Allow eq eq comparison between strings
parent
465039cf43
commit
32266d07f6
30
src/eval.rs
30
src/eval.rs
|
@ -1,4 +1,7 @@
|
|||
use std::fmt::{self, Display, Formatter};
|
||||
use std::{
|
||||
fmt::{self, Display, Formatter},
|
||||
rc::Rc,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
ast::{Expr, ExprVisitor, LiteralValue, Stmt, StmtVisitor},
|
||||
|
@ -120,7 +123,12 @@ impl ExprVisitor<Result<EvaluatedValue, ScriptError>> for InterpreterRunner<'_>
|
|||
// Finish the short circuit; if we get to this point the result will always be right.
|
||||
TokenKind::Or | TokenKind::And => Ok(right_operand),
|
||||
|
||||
TokenKind::Plus => evaluate_addition((left_operand, right_operand), operator),
|
||||
TokenKind::Plus => evaluate_arithmetic_or_string_operation(
|
||||
(left_operand, right_operand),
|
||||
operator,
|
||||
|left, right| EvaluatedValue::Number(left + right),
|
||||
|left, right| EvaluatedValue::String((left.to_string() + right.as_ref()).into()),
|
||||
),
|
||||
|
||||
TokenKind::Minus => evaluate_binary_arithmetic(
|
||||
(left_operand, right_operand),
|
||||
|
@ -164,16 +172,18 @@ impl ExprVisitor<Result<EvaluatedValue, ScriptError>> for InterpreterRunner<'_>
|
|||
|left_value, right_value| EvaluatedValue::Boolean(left_value <= right_value),
|
||||
),
|
||||
|
||||
TokenKind::EqualEqual => evaluate_binary_arithmetic(
|
||||
TokenKind::EqualEqual => evaluate_arithmetic_or_string_operation(
|
||||
(left_operand, right_operand),
|
||||
operator,
|
||||
|left_value, right_value| EvaluatedValue::Boolean(left_value == right_value),
|
||||
|left_value, right_value| EvaluatedValue::Boolean(left_value == right_value),
|
||||
),
|
||||
|
||||
TokenKind::BangEqual => evaluate_binary_arithmetic(
|
||||
TokenKind::BangEqual => evaluate_arithmetic_or_string_operation(
|
||||
(left_operand, right_operand),
|
||||
operator,
|
||||
|left_value, right_value| EvaluatedValue::Boolean(left_value != right_value),
|
||||
|left_value, right_value| EvaluatedValue::Boolean(left_value != right_value),
|
||||
),
|
||||
|
||||
_ => unreachable!(
|
||||
|
@ -287,18 +297,22 @@ fn convert_arithmetic_operands(
|
|||
}
|
||||
}
|
||||
|
||||
fn evaluate_addition(
|
||||
fn evaluate_arithmetic_or_string_operation<
|
||||
F: FnOnce(f64, f64) -> EvaluatedValue,
|
||||
G: FnOnce(Rc<str>, Rc<str>) -> EvaluatedValue,
|
||||
>(
|
||||
(left, right): (EvaluatedValue, EvaluatedValue),
|
||||
operator: &Token,
|
||||
make_number_output: F,
|
||||
make_string_output: G,
|
||||
) -> Result<EvaluatedValue, ScriptError> {
|
||||
match (left, right) {
|
||||
(EvaluatedValue::Number(left_value), EvaluatedValue::Number(right_value)) => {
|
||||
Ok(EvaluatedValue::Number(left_value + right_value))
|
||||
Ok(make_number_output(left_value, right_value))
|
||||
}
|
||||
|
||||
(EvaluatedValue::String(left_value), EvaluatedValue::String(right_value)) => {
|
||||
let concatted = left_value.to_string() + right_value.as_ref();
|
||||
Ok(EvaluatedValue::String(concatted.into()))
|
||||
Ok(make_string_output(left_value, right_value))
|
||||
}
|
||||
|
||||
// TODO: we could improve this error (and others) to include the types
|
||||
|
|
Loading…
Reference in New Issue