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::{
|
use crate::{
|
||||||
ast::{Expr, ExprVisitor, LiteralValue, Stmt, StmtVisitor},
|
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.
|
// Finish the short circuit; if we get to this point the result will always be right.
|
||||||
TokenKind::Or | TokenKind::And => Ok(right_operand),
|
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(
|
TokenKind::Minus => evaluate_binary_arithmetic(
|
||||||
(left_operand, right_operand),
|
(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),
|
|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),
|
(left_operand, right_operand),
|
||||||
operator,
|
operator,
|
||||||
|left_value, right_value| EvaluatedValue::Boolean(left_value == right_value),
|
|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),
|
(left_operand, right_operand),
|
||||||
operator,
|
operator,
|
||||||
|left_value, right_value| EvaluatedValue::Boolean(left_value != right_value),
|
|left_value, right_value| EvaluatedValue::Boolean(left_value != right_value),
|
||||||
|
|left_value, right_value| EvaluatedValue::Boolean(left_value != right_value),
|
||||||
),
|
),
|
||||||
|
|
||||||
_ => unreachable!(
|
_ => 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),
|
(left, right): (EvaluatedValue, EvaluatedValue),
|
||||||
operator: &Token,
|
operator: &Token,
|
||||||
|
make_number_output: F,
|
||||||
|
make_string_output: G,
|
||||||
) -> Result<EvaluatedValue, ScriptError> {
|
) -> Result<EvaluatedValue, ScriptError> {
|
||||||
match (left, right) {
|
match (left, right) {
|
||||||
(EvaluatedValue::Number(left_value), EvaluatedValue::Number(right_value)) => {
|
(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)) => {
|
(EvaluatedValue::String(left_value), EvaluatedValue::String(right_value)) => {
|
||||||
let concatted = left_value.to_string() + right_value.as_ref();
|
Ok(make_string_output(left_value, right_value))
|
||||||
Ok(EvaluatedValue::String(concatted.into()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: we could improve this error (and others) to include the types
|
// TODO: we could improve this error (and others) to include the types
|
||||||
|
|
Loading…
Reference in New Issue