diff --git a/src/ast.rs b/src/ast.rs index fdcd1f0..aa1d021 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -108,18 +108,27 @@ pub struct BinaryOp { #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum BinaryOpKind { - Add, - Sub, - Mult, - Div, + // Logical + And, + Or, + + // Equality Eq, NotEq, + + // Comparison Greater, GreaterEq, Less, LessEq, - And, - Or, + + // Term + Add, + Sub, + + // Factor + Mult, + Div, } impl BinaryOp { diff --git a/src/parser.rs b/src/parser.rs index 5f6461a..4ac040b 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -102,7 +102,7 @@ impl Parser { BangEq => NotEq }); - parse_binary_expr!(comparison, primary, [Greater, GreaterEq, Less, LessEq]); + parse_binary_expr!(comparison, term, [Greater, GreaterEq, Less, LessEq]); parse_binary_expr!(term, factor, { Minus => Sub, @@ -281,21 +281,47 @@ mod tests { parse(tokens).unwrap_err() } + fn assert_binary_expr_op(input_map: &[(&'static str, BinaryOpKind)]) { + for (input, expected_op) in input_map { + let e = parse_to_expr(&format!("1 {input} 2")); + let (left, parsed_op, right) = e.unwrap_binary(); + assert_eq!(parsed_op.kind, *expected_op); + assert_eq!(left.unwrap_literal().unwrap_number(), 1.0); + assert_eq!(right.unwrap_literal().unwrap_number(), 2.0); + } + } + #[test] fn parses_equality_expr() { + use BinaryOpKind::*; + start_test_tracing(); + assert_binary_expr_op(&[("==", Eq), ("!=", NotEq)]); + } + + #[test] + fn parses_comparison_expr() { + use BinaryOpKind::*; start_test_tracing(); + assert_binary_expr_op(&[ + (">", Greater), + (">=", GreaterEq), + ("<", Less), + ("<=", LessEq), + ]); + } - let e = parse_to_expr("1 == 2"); - let (left, op, right) = e.unwrap_binary(); - assert_eq!(left.unwrap_literal().unwrap_number(), 1.0); - assert_eq!(right.unwrap_literal().unwrap_number(), 2.0); - assert_eq!(op.kind, BinaryOpKind::Eq); - - let e = parse_to_expr("1 != 2"); - let (left, op, right) = e.unwrap_binary(); - assert_eq!(left.unwrap_literal().unwrap_number(), 1.0); - assert_eq!(right.unwrap_literal().unwrap_number(), 2.0); - assert_eq!(op.kind, BinaryOpKind::NotEq); + #[test] + fn parses_term_expr() { + use BinaryOpKind::*; + start_test_tracing(); + assert_binary_expr_op(&[("+", Add), ("-", Sub)]); + } + + #[test] + fn parses_factor_expr() { + use BinaryOpKind::*; + start_test_tracing(); + assert_binary_expr_op(&[("*", Mult), ("/", Div)]); } #[test]