Skip to content

Commit 8836ac8

Browse files
committed
feat(interpreter): support string and boolean equality comparisons
- Refactor and in to explicitly handle and boolean values. - Previously, these operations delegated to , which restricted comparisons to numeric types only. - This change enables logic like to execute correctly, fixing failures in tests like Beecrowd 1049. - Update to clarify that equality operators supportfeat(interpreter): support string and boolean equality comparisons - Refactor and in to explicitly handle and boolean values. - Previously, these operations delegated to , which restricted comparisons to numeric types only. - This change enables logic like to execute correctly, fixing failures in tests. - Update to clarify that equality operators support
1 parent 210e40d commit 8836ac8

File tree

2 files changed

+92
-21
lines changed

2 files changed

+92
-21
lines changed

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,12 @@ counter = counter + 1;
7373
| Category | Operators |
7474
|--------------|----------------------------------------|
7575
| Arithmetic | `+`, `-`, `*`, `/` |
76-
| Comparison | `==`, `!=`, `<`, `>`, `<=`, `>=` |
76+
| Equality | `==`, `!=` |
77+
| Ordering | `<`, `>`, `<=`, `>=` |
7778
| Logical | `and`, `or`, `not` |
7879

80+
> **Note:** Equality operators support numbers, strings, and booleans. Ordering operators are currently limited to numbers.
81+
7982
---
8083

8184
## Type System

src/interpreter/expression_eval.rs

Lines changed: 88 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -258,39 +258,107 @@ fn eval_eq(
258258
rhs: Expression,
259259
env: &Environment<Expression>,
260260
) -> Result<ExpressionResult, String> {
261-
eval_binary_rel_op(
262-
lhs,
263-
rhs,
264-
env,
265-
|a, b| {
266-
if a == b {
261+
let v1 = match eval(lhs, env)? {
262+
ExpressionResult::Value(expr) => expr,
263+
ExpressionResult::Propagate(expr) => return Ok(ExpressionResult::Propagate(expr)),
264+
};
265+
let v2 = match eval(rhs, env)? {
266+
ExpressionResult::Value(expr) => expr,
267+
ExpressionResult::Propagate(expr) => return Ok(ExpressionResult::Propagate(expr)),
268+
};
269+
270+
match (v1, v2) {
271+
(Expression::CInt(v1), Expression::CInt(v2)) => Ok(ExpressionResult::Value(if v1 == v2 {
272+
Expression::CTrue
273+
} else {
274+
Expression::CFalse
275+
})),
276+
(Expression::CInt(v1), Expression::CReal(v2)) => Ok(ExpressionResult::Value(
277+
if (v1 as f64) == v2 {
267278
Expression::CTrue
268279
} else {
269280
Expression::CFalse
270-
}
271-
},
272-
"equality '(==)' is only defined for numbers (integers and real).",
273-
)
281+
},
282+
)),
283+
(Expression::CReal(v1), Expression::CInt(v2)) => Ok(ExpressionResult::Value(
284+
if v1 == (v2 as f64) {
285+
Expression::CTrue
286+
} else {
287+
Expression::CFalse
288+
},
289+
)),
290+
(Expression::CReal(v1), Expression::CReal(v2)) => Ok(ExpressionResult::Value(if v1 == v2 {
291+
Expression::CTrue
292+
} else {
293+
Expression::CFalse
294+
})),
295+
(Expression::CString(v1), Expression::CString(v2)) => {
296+
Ok(ExpressionResult::Value(if v1 == v2 {
297+
Expression::CTrue
298+
} else {
299+
Expression::CFalse
300+
}))
301+
}
302+
(Expression::CTrue, Expression::CTrue) => Ok(ExpressionResult::Value(Expression::CTrue)),
303+
(Expression::CFalse, Expression::CFalse) => Ok(ExpressionResult::Value(Expression::CTrue)),
304+
(Expression::CTrue, Expression::CFalse) => Ok(ExpressionResult::Value(Expression::CFalse)),
305+
(Expression::CFalse, Expression::CTrue) => Ok(ExpressionResult::Value(Expression::CFalse)),
306+
_ => Err("equality '(==)' is only defined for numbers, strings and booleans.".to_string()),
307+
}
274308
}
275309

276310
fn eval_neq(
277311
lhs: Expression,
278312
rhs: Expression,
279313
env: &Environment<Expression>,
280314
) -> Result<ExpressionResult, String> {
281-
eval_binary_rel_op(
282-
lhs,
283-
rhs,
284-
env,
285-
|a, b| {
286-
if a != b {
315+
let v1 = match eval(lhs, env)? {
316+
ExpressionResult::Value(expr) => expr,
317+
ExpressionResult::Propagate(expr) => return Ok(ExpressionResult::Propagate(expr)),
318+
};
319+
let v2 = match eval(rhs, env)? {
320+
ExpressionResult::Value(expr) => expr,
321+
ExpressionResult::Propagate(expr) => return Ok(ExpressionResult::Propagate(expr)),
322+
};
323+
324+
match (v1, v2) {
325+
(Expression::CInt(v1), Expression::CInt(v2)) => Ok(ExpressionResult::Value(if v1 != v2 {
326+
Expression::CTrue
327+
} else {
328+
Expression::CFalse
329+
})),
330+
(Expression::CInt(v1), Expression::CReal(v2)) => Ok(ExpressionResult::Value(
331+
if (v1 as f64) != v2 {
287332
Expression::CTrue
288333
} else {
289334
Expression::CFalse
290-
}
291-
},
292-
"inequality '(!=)' is only defined for numbers (integers and real).",
293-
)
335+
},
336+
)),
337+
(Expression::CReal(v1), Expression::CInt(v2)) => Ok(ExpressionResult::Value(
338+
if v1 != (v2 as f64) {
339+
Expression::CTrue
340+
} else {
341+
Expression::CFalse
342+
},
343+
)),
344+
(Expression::CReal(v1), Expression::CReal(v2)) => Ok(ExpressionResult::Value(if v1 != v2 {
345+
Expression::CTrue
346+
} else {
347+
Expression::CFalse
348+
})),
349+
(Expression::CString(v1), Expression::CString(v2)) => {
350+
Ok(ExpressionResult::Value(if v1 != v2 {
351+
Expression::CTrue
352+
} else {
353+
Expression::CFalse
354+
}))
355+
}
356+
(Expression::CTrue, Expression::CTrue) => Ok(ExpressionResult::Value(Expression::CFalse)),
357+
(Expression::CFalse, Expression::CFalse) => Ok(ExpressionResult::Value(Expression::CFalse)),
358+
(Expression::CTrue, Expression::CFalse) => Ok(ExpressionResult::Value(Expression::CTrue)),
359+
(Expression::CFalse, Expression::CTrue) => Ok(ExpressionResult::Value(Expression::CTrue)),
360+
_ => Err("inequality '(!=)' is only defined for numbers, strings and booleans.".to_string()),
361+
}
294362
}
295363

296364
fn eval_gt(

0 commit comments

Comments
 (0)