Handle logical comparisons
parent
6aa29e25f4
commit
b00d635820
12
src/eval.rs
12
src/eval.rs
|
@ -105,9 +105,21 @@ impl ExprVisitor<Result<EvaluatedValue, ScriptError>> for InterpreterRunner<'_>
|
||||||
right: &Expr,
|
right: &Expr,
|
||||||
) -> Result<EvaluatedValue, ScriptError> {
|
) -> Result<EvaluatedValue, ScriptError> {
|
||||||
let left_operand = self.visit_expr(left)?;
|
let left_operand = self.visit_expr(left)?;
|
||||||
|
// These operators must be handled first to allow for short circuiting
|
||||||
|
match operator.kind() {
|
||||||
|
TokenKind::Or if left_operand.is_truthy() => return Ok(left_operand),
|
||||||
|
TokenKind::And if !left_operand.is_truthy() => return Ok(left_operand),
|
||||||
|
_ => {
|
||||||
|
// fall through, evaluate right operand before continuing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let right_operand = self.visit_expr(right)?;
|
let right_operand = self.visit_expr(right)?;
|
||||||
|
|
||||||
match operator.kind() {
|
match operator.kind() {
|
||||||
|
// 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_addition((left_operand, right_operand), operator),
|
||||||
|
|
||||||
TokenKind::Minus => evaluate_binary_arithmetic(
|
TokenKind::Minus => evaluate_binary_arithmetic(
|
||||||
|
|
10
src/parse.rs
10
src/parse.rs
|
@ -272,7 +272,7 @@ fn parse_expression<I: Iterator<Item = Token>>(iter: &mut Peekable<I>) -> Result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_assignment<I: Iterator<Item = Token>>(iter: &mut Peekable<I>) -> Result<Expr, ParseError> {
|
fn parse_assignment<I: Iterator<Item = Token>>(iter: &mut Peekable<I>) -> Result<Expr, ParseError> {
|
||||||
let expr = parse_equality(iter)?;
|
let expr = parse_or(iter)?;
|
||||||
match (match_token_kind!(iter, TokenKind::Equal), expr) {
|
match (match_token_kind!(iter, TokenKind::Equal), expr) {
|
||||||
(Err(_), expr) => Ok(expr),
|
(Err(_), expr) => Ok(expr),
|
||||||
|
|
||||||
|
@ -292,6 +292,14 @@ fn parse_assignment<I: Iterator<Item = Token>>(iter: &mut Peekable<I>) -> Result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_or<I: Iterator<Item = Token>>(iter: &mut Peekable<I>) -> Result<Expr, ParseError> {
|
||||||
|
parse_binary(iter, &[TokenKind::Or], parse_and)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_and<I: Iterator<Item = Token>>(iter: &mut Peekable<I>) -> Result<Expr, ParseError> {
|
||||||
|
parse_binary(iter, &[TokenKind::And], parse_equality)
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_equality<I: Iterator<Item = Token>>(iter: &mut Peekable<I>) -> Result<Expr, ParseError> {
|
fn parse_equality<I: Iterator<Item = Token>>(iter: &mut Peekable<I>) -> Result<Expr, ParseError> {
|
||||||
parse_binary(
|
parse_binary(
|
||||||
iter,
|
iter,
|
||||||
|
|
Loading…
Reference in New Issue