Skip to content

Commit 11045e5

Browse files
committed
[refactoring] Rename and reorganize expression evaluation functions
- Rename all eval function calls to use consistent 'eval_' prefix: * add → eval_add, sub → eval_sub, mul → eval_mul, div → eval_div * and → eval_and, or → eval_or, not → eval_not * eq → eval_eq, neq → eval_neq, gt → eval_gt, lt → eval_lt * gte → eval_gte, lte → eval_lte * lookup → eval_lookup, call → eval_call - Reorganize function definitions to match eval() function call order - Move helper functions (eval_binary_arith_op, eval_binary_boolean_op, eval_binary_rel_op) before their usage - Group functions by operation type: arithmetic, boolean, relational - Maintain all existing functionality and test coverage - Improve code organization and naming consistency
1 parent b57cc53 commit 11045e5

1 file changed

Lines changed: 145 additions & 128 deletions

File tree

src/interpreter/expression_eval.rs

Lines changed: 145 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -5,92 +5,35 @@ type ErrorMessage = (String, Option<Expression>);
55

66
pub 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
9437
fn 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
378395
fn eval_unwrap_expression(
379396
exp: Expression,

0 commit comments

Comments
 (0)