@@ -5,92 +5,35 @@ type ErrorMessage = (String, Option<Expression>);
55
66pub fn eval ( exp : Expression , env : & Environment < Expression > ) -> Result < Expression , ErrorMessage > {
77 match exp {
8- Expression :: Add ( lhs, rhs) => add ( * lhs, * rhs, env) ,
9- Expression :: Sub ( lhs, rhs) => sub ( * lhs, * rhs, env) ,
10- Expression :: Mul ( lhs, rhs) => mul ( * lhs, * rhs, env) ,
11- Expression :: Div ( lhs, rhs) => div ( * lhs, * rhs, env) ,
12- Expression :: And ( lhs, rhs) => and ( * lhs, * rhs, env) ,
13- Expression :: Or ( lhs, rhs) => or ( * lhs, * rhs, env) ,
14- Expression :: Not ( lhs) => not ( * lhs, env) ,
15- Expression :: EQ ( lhs, rhs) => eq ( * lhs, * rhs, env) ,
16- Expression :: NEQ ( lhs, rhs) => neq ( * lhs, * rhs, env) ,
17- Expression :: GT ( lhs, rhs) => gt ( * lhs, * rhs, env) ,
18- Expression :: LT ( lhs, rhs) => lt ( * lhs, * rhs, env) ,
19- Expression :: GTE ( lhs, rhs) => gte ( * lhs, * rhs, env) ,
20- Expression :: LTE ( lhs, rhs) => lte ( * lhs, * rhs, env) ,
21- Expression :: Var ( name) => lookup ( name, env) ,
8+ Expression :: Add ( lhs, rhs) => eval_add ( * lhs, * rhs, env) ,
9+ Expression :: Sub ( lhs, rhs) => eval_sub ( * lhs, * rhs, env) ,
10+ Expression :: Mul ( lhs, rhs) => eval_mul ( * lhs, * rhs, env) ,
11+ Expression :: Div ( lhs, rhs) => eval_div ( * lhs, * rhs, env) ,
12+ Expression :: And ( lhs, rhs) => eval_and ( * lhs, * rhs, env) ,
13+ Expression :: Or ( lhs, rhs) => eval_or ( * lhs, * rhs, env) ,
14+ Expression :: Not ( lhs) => eval_not ( * lhs, env) ,
15+ Expression :: EQ ( lhs, rhs) => eval_eq ( * lhs, * rhs, env) ,
16+ Expression :: NEQ ( lhs, rhs) => eval_neq ( * lhs, * rhs, env) ,
17+ Expression :: GT ( lhs, rhs) => eval_gt ( * lhs, * rhs, env) ,
18+ Expression :: LT ( lhs, rhs) => eval_lt ( * lhs, * rhs, env) ,
19+ Expression :: GTE ( lhs, rhs) => eval_gte ( * lhs, * rhs, env) ,
20+ Expression :: LTE ( lhs, rhs) => eval_lte ( * lhs, * rhs, env) ,
21+ Expression :: Var ( name) => eval_lookup ( name, env) ,
2222 Expression :: COk ( e) => eval_ok ( * e, env) ,
2323 Expression :: CErr ( e) => eval_err ( * e, env) ,
2424 Expression :: CJust ( e) => eval_just ( * e, env) ,
2525 Expression :: Unwrap ( e) => eval_unwrap_expression ( * e, env) ,
2626 Expression :: Propagate ( e) => eval_propagate_expression ( * e, env) ,
2727 Expression :: IsError ( e) => eval_iserror_expression ( * e, env) ,
2828 Expression :: IsNothing ( e) => eval_isnothing_expression ( * e, env) ,
29- Expression :: FuncCall ( name, args) => call ( name, args, env) ,
29+ Expression :: FuncCall ( name, args) => eval_call ( name, args, env) ,
3030 Expression :: ListValue ( values) => eval_list_value ( values, env) ,
3131 _ if is_constant ( exp. clone ( ) ) => Ok ( exp) ,
3232 _ => Err ( ( String :: from ( "Not implemented yet." ) , None ) ) ,
3333 }
3434}
3535
36- pub fn lookup ( name : String , env : & Environment < Expression > ) -> Result < Expression , ErrorMessage > {
37- match env. lookup ( & name) {
38- Some ( ( _, value) ) => Ok ( value. clone ( ) ) ,
39- None => Err ( ( format ! ( "Variable '{}' not found" , name) , None ) ) ,
40- }
41- }
42-
43- pub fn call (
44- name : Name ,
45- args : Vec < Expression > ,
46- env : & Environment < Expression > ,
47- ) -> Result < Expression , ErrorMessage > {
48- match env. lookup_function ( & name) {
49- Some ( func) => {
50- let mut new_env = Environment :: new ( ) ;
51-
52- // Copy global functions
53- for ( name, ( _, value) ) in env. get_all_variables ( ) {
54- if let Expression :: FuncCall ( _, _) = value {
55- new_env. map_variable ( name. clone ( ) , false , value. clone ( ) ) ;
56- }
57- }
58-
59- // Bind arguments
60- for ( i, formal_arg) in func. params . iter ( ) . enumerate ( ) {
61- if i >= args. len ( ) {
62- return Err ( (
63- format ! (
64- "[Runtime Error on '{}()'] missing argument '{}'." ,
65- name, formal_arg. argument_name
66- ) ,
67- None ,
68- ) ) ;
69- }
70- let arg_value = eval ( args[ i] . clone ( ) , env) ?;
71- new_env. map_variable ( formal_arg. argument_name . clone ( ) , false , arg_value) ;
72- }
73-
74- if args. len ( ) > func. params . len ( ) {
75- return Err ( (
76- format ! ( "[Runtime Error on '{}()'] too many arguments." , name) ,
77- None ,
78- ) ) ;
79- }
80-
81- // Execute function
82- match super :: statement_execute:: execute ( * func. body . as_ref ( ) . unwrap ( ) . clone ( ) , & new_env)
83- {
84- Ok ( _) => Err ( ( "Function did not return a value" . to_string ( ) , None ) ) ,
85- Err ( ( _, Some ( value) ) ) => Ok ( value) ,
86- Err ( e) => Err ( e) ,
87- }
88- }
89- _ => Err ( ( format ! ( "Function {} not found" , name) , None ) ) ,
90- }
91- }
92-
93- // Arithmetic Operations
36+ // Helper function for arithmetic operations
9437fn eval_binary_arith_op < F > (
9538 lhs : Expression ,
9639 rhs : Expression ,
@@ -115,7 +58,54 @@ where
11558 }
11659}
11760
118- fn add (
61+ // Helper function for boolean operations
62+ fn eval_binary_boolean_op < F > (
63+ lhs : Expression ,
64+ rhs : Expression ,
65+ env : & Environment < Expression > ,
66+ op : F ,
67+ error_msg : & str ,
68+ ) -> Result < Expression , ErrorMessage >
69+ where
70+ F : Fn ( bool , bool ) -> Expression ,
71+ {
72+ let v1 = eval ( lhs, env) ?;
73+ let v2 = eval ( rhs, env) ?;
74+
75+ match ( v1, v2) {
76+ ( Expression :: CTrue , Expression :: CTrue ) => Ok ( op ( true , true ) ) ,
77+ ( Expression :: CTrue , Expression :: CFalse ) => Ok ( op ( true , false ) ) ,
78+ ( Expression :: CFalse , Expression :: CTrue ) => Ok ( op ( false , true ) ) ,
79+ ( Expression :: CFalse , Expression :: CFalse ) => Ok ( op ( false , false ) ) ,
80+ _ => Err ( ( error_msg. to_string ( ) , None ) ) ,
81+ }
82+ }
83+
84+ // Helper function for relational operations
85+ fn eval_binary_rel_op < F > (
86+ lhs : Expression ,
87+ rhs : Expression ,
88+ env : & Environment < Expression > ,
89+ op : F ,
90+ error_msg : & str ,
91+ ) -> Result < Expression , ErrorMessage >
92+ where
93+ F : Fn ( f64 , f64 ) -> Expression ,
94+ {
95+ let v1 = eval ( lhs, env) ?;
96+ let v2 = eval ( rhs, env) ?;
97+
98+ match ( v1, v2) {
99+ ( Expression :: CInt ( v1) , Expression :: CInt ( v2) ) => Ok ( op ( v1 as f64 , v2 as f64 ) ) ,
100+ ( Expression :: CInt ( v1) , Expression :: CReal ( v2) ) => Ok ( op ( v1 as f64 , v2) ) ,
101+ ( Expression :: CReal ( v1) , Expression :: CInt ( v2) ) => Ok ( op ( v1, v2 as f64 ) ) ,
102+ ( Expression :: CReal ( v1) , Expression :: CReal ( v2) ) => Ok ( op ( v1, v2) ) ,
103+ _ => Err ( ( error_msg. to_string ( ) , None ) ) ,
104+ }
105+ }
106+
107+ // Arithmetic Operations
108+ fn eval_add (
119109 lhs : Expression ,
120110 rhs : Expression ,
121111 env : & Environment < Expression > ,
@@ -128,7 +118,8 @@ fn add(
128118 "addition '(+)' is only defined for numbers (integers and real)." ,
129119 )
130120}
131- fn sub (
121+
122+ fn eval_sub (
132123 lhs : Expression ,
133124 rhs : Expression ,
134125 env : & Environment < Expression > ,
@@ -141,7 +132,8 @@ fn sub(
141132 "subtraction '(-)' is only defined for numbers (integers and real)." ,
142133 )
143134}
144- fn mul (
135+
136+ fn eval_mul (
145137 lhs : Expression ,
146138 rhs : Expression ,
147139 env : & Environment < Expression > ,
@@ -154,7 +146,8 @@ fn mul(
154146 "multiplication '(*)' is only defined for numbers (integers and real)." ,
155147 )
156148}
157- fn div (
149+
150+ fn eval_div (
158151 lhs : Expression ,
159152 rhs : Expression ,
160153 env : & Environment < Expression > ,
@@ -169,28 +162,7 @@ fn div(
169162}
170163
171164// Boolean Operations
172- fn eval_binary_boolean_op < F > (
173- lhs : Expression ,
174- rhs : Expression ,
175- env : & Environment < Expression > ,
176- op : F ,
177- error_msg : & str ,
178- ) -> Result < Expression , ErrorMessage >
179- where
180- F : Fn ( bool , bool ) -> Expression ,
181- {
182- let v1 = eval ( lhs, env) ?;
183- let v2 = eval ( rhs, env) ?;
184-
185- match ( v1, v2) {
186- ( Expression :: CTrue , Expression :: CTrue ) => Ok ( op ( true , true ) ) ,
187- ( Expression :: CTrue , Expression :: CFalse ) => Ok ( op ( true , false ) ) ,
188- ( Expression :: CFalse , Expression :: CTrue ) => Ok ( op ( false , true ) ) ,
189- ( Expression :: CFalse , Expression :: CFalse ) => Ok ( op ( false , false ) ) ,
190- _ => Err ( ( error_msg. to_string ( ) , None ) ) ,
191- }
192- }
193- fn and (
165+ fn eval_and (
194166 lhs : Expression ,
195167 rhs : Expression ,
196168 env : & Environment < Expression > ,
@@ -209,7 +181,8 @@ fn and(
209181 "'and' is only defined for booleans." ,
210182 )
211183}
212- fn or (
184+
185+ fn eval_or (
213186 lhs : Expression ,
214187 rhs : Expression ,
215188 env : & Environment < Expression > ,
@@ -228,7 +201,8 @@ fn or(
228201 "'or' is only defined for booleans." ,
229202 )
230203}
231- fn not ( lhs : Expression , env : & Environment < Expression > ) -> Result < Expression , ErrorMessage > {
204+
205+ fn eval_not ( lhs : Expression , env : & Environment < Expression > ) -> Result < Expression , ErrorMessage > {
232206 let v = eval ( lhs, env) ?;
233207 match v {
234208 Expression :: CTrue => Ok ( Expression :: CFalse ) ,
@@ -238,28 +212,7 @@ fn not(lhs: Expression, env: &Environment<Expression>) -> Result<Expression, Err
238212}
239213
240214// Relational Operations
241- fn eval_binary_rel_op < F > (
242- lhs : Expression ,
243- rhs : Expression ,
244- env : & Environment < Expression > ,
245- op : F ,
246- error_msg : & str ,
247- ) -> Result < Expression , ErrorMessage >
248- where
249- F : Fn ( f64 , f64 ) -> Expression ,
250- {
251- let v1 = eval ( lhs, env) ?;
252- let v2 = eval ( rhs, env) ?;
253-
254- match ( v1, v2) {
255- ( Expression :: CInt ( v1) , Expression :: CInt ( v2) ) => Ok ( op ( v1 as f64 , v2 as f64 ) ) ,
256- ( Expression :: CInt ( v1) , Expression :: CReal ( v2) ) => Ok ( op ( v1 as f64 , v2) ) ,
257- ( Expression :: CReal ( v1) , Expression :: CInt ( v2) ) => Ok ( op ( v1, v2 as f64 ) ) ,
258- ( Expression :: CReal ( v1) , Expression :: CReal ( v2) ) => Ok ( op ( v1, v2) ) ,
259- _ => Err ( ( error_msg. to_string ( ) , None ) ) ,
260- }
261- }
262- fn eq (
215+ fn eval_eq (
263216 lhs : Expression ,
264217 rhs : Expression ,
265218 env : & Environment < Expression > ,
@@ -278,7 +231,8 @@ fn eq(
278231 "(==) is only defined for numbers (integers and real)." ,
279232 )
280233}
281- fn neq (
234+
235+ fn eval_neq (
282236 lhs : Expression ,
283237 rhs : Expression ,
284238 env : & Environment < Expression > ,
@@ -297,7 +251,8 @@ fn neq(
297251 "(!=) is only defined for numbers (integers and real)." ,
298252 )
299253}
300- fn gt (
254+
255+ fn eval_gt (
301256 lhs : Expression ,
302257 rhs : Expression ,
303258 env : & Environment < Expression > ,
@@ -316,7 +271,8 @@ fn gt(
316271 "(>) is only defined for numbers (integers and real)." ,
317272 )
318273}
319- fn lt (
274+
275+ fn eval_lt (
320276 lhs : Expression ,
321277 rhs : Expression ,
322278 env : & Environment < Expression > ,
@@ -335,7 +291,8 @@ fn lt(
335291 "(<) is only defined for numbers (integers and real)." ,
336292 )
337293}
338- fn gte (
294+
295+ fn eval_gte (
339296 lhs : Expression ,
340297 rhs : Expression ,
341298 env : & Environment < Expression > ,
@@ -354,7 +311,8 @@ fn gte(
354311 "(>=) is only defined for numbers (integers and real)." ,
355312 )
356313}
357- fn lte (
314+
315+ fn eval_lte (
358316 lhs : Expression ,
359317 rhs : Expression ,
360318 env : & Environment < Expression > ,
@@ -374,6 +332,65 @@ fn lte(
374332 )
375333}
376334
335+ // Variable lookup
336+ pub fn eval_lookup ( name : String , env : & Environment < Expression > ) -> Result < Expression , ErrorMessage > {
337+ match env. lookup ( & name) {
338+ Some ( ( _, value) ) => Ok ( value. clone ( ) ) ,
339+ None => Err ( ( format ! ( "Variable '{}' not found" , name) , None ) ) ,
340+ }
341+ }
342+
343+ // Function call
344+ pub fn eval_call (
345+ name : Name ,
346+ args : Vec < Expression > ,
347+ env : & Environment < Expression > ,
348+ ) -> Result < Expression , ErrorMessage > {
349+ match env. lookup_function ( & name) {
350+ Some ( func) => {
351+ let mut new_env = Environment :: new ( ) ;
352+
353+ // Copy global functions
354+ for ( name, ( _, value) ) in env. get_all_variables ( ) {
355+ if let Expression :: FuncCall ( _, _) = value {
356+ new_env. map_variable ( name. clone ( ) , false , value. clone ( ) ) ;
357+ }
358+ }
359+
360+ // Bind arguments
361+ for ( i, formal_arg) in func. params . iter ( ) . enumerate ( ) {
362+ if i >= args. len ( ) {
363+ return Err ( (
364+ format ! (
365+ "[Runtime Error on '{}()'] missing argument '{}'." ,
366+ name, formal_arg. argument_name
367+ ) ,
368+ None ,
369+ ) ) ;
370+ }
371+ let arg_value = eval ( args[ i] . clone ( ) , env) ?;
372+ new_env. map_variable ( formal_arg. argument_name . clone ( ) , false , arg_value) ;
373+ }
374+
375+ if args. len ( ) > func. params . len ( ) {
376+ return Err ( (
377+ format ! ( "[Runtime Error on '{}()'] too many arguments." , name) ,
378+ None ,
379+ ) ) ;
380+ }
381+
382+ // Execute function
383+ match super :: statement_execute:: execute ( * func. body . as_ref ( ) . unwrap ( ) . clone ( ) , & new_env)
384+ {
385+ Ok ( _) => Err ( ( "Function did not return a value" . to_string ( ) , None ) ) ,
386+ Err ( ( _, Some ( value) ) ) => Ok ( value) ,
387+ Err ( e) => Err ( e) ,
388+ }
389+ }
390+ _ => Err ( ( format ! ( "Function {} not found" , name) , None ) ) ,
391+ }
392+ }
393+
377394// Other helpers
378395fn eval_unwrap_expression (
379396 exp : Expression ,
0 commit comments