diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 6c3222f..3083be6 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -286,6 +286,7 @@ macro_rules! make_selector { #[derive(PartialEq, Clone)] pub struct SelectorList { pub head: Box, + // TODO This should now work more like a binary operator. Perhaps move into the precendence parser code? pub tail: Option>, } @@ -579,10 +580,6 @@ impl MacroDef { stack.push(&bexpr.left); stack.push(&bexpr.right); } - &Expression::Compare(ref cexpr) => { - stack.push(&cexpr.left); - stack.push(&cexpr.right); - } &Expression::Grouped(ref expr) => { stack.push(expr); } @@ -644,26 +641,14 @@ pub enum BinaryExprType { Sub, Mul, Div, -} - -/// CompareType signals the type of a comparison for a binary expression. -#[derive(Debug, PartialEq, Clone)] -pub enum CompareType { + // Comparison Equal, GT, LT, NotEqual, GTEqual, LTEqual, -} - -/// ComparisonDef Represents a comparison between two expressions. -#[derive(Debug, PartialEq, Clone)] -pub struct ComparisonDef { - pub kind: CompareType, - pub left: Box, - pub right: Box, - pub pos: Position, + // TODO DOT Selector operator } /// Represents an expression with a left and a right side. @@ -759,7 +744,6 @@ pub enum Expression { // Binary expressions Binary(BinaryOpDef), - Compare(ComparisonDef), // Complex Expressions Copy(CopyDef), @@ -779,7 +763,6 @@ impl Expression { match self { &Expression::Simple(ref v) => v.pos(), &Expression::Binary(ref def) => &def.pos, - &Expression::Compare(ref def) => &def.pos, &Expression::Copy(ref def) => &def.pos, &Expression::Grouped(ref expr) => expr.pos(), &Expression::Format(ref def) => &def.pos, @@ -801,9 +784,6 @@ impl fmt::Display for Expression { &Expression::Binary(_) => { write!(w, "")?; } - &Expression::Compare(_) => { - write!(w, "")?; - } &Expression::ListOp(_) => { write!(w, "")?; } diff --git a/src/build/mod.rs b/src/build/mod.rs index c0cc049..c18cd8f 100644 --- a/src/build/mod.rs +++ b/src/build/mod.rs @@ -866,20 +866,12 @@ impl<'a> FileBuilder<'a> { &BinaryExprType::Sub => self.subtract_vals(&def.pos, left, right), &BinaryExprType::Mul => self.multiply_vals(&def.pos, left, right), &BinaryExprType::Div => self.divide_vals(&def.pos, left, right), - } - } - - fn eval_compare(&mut self, def: &ComparisonDef, scope: &Scope) -> Result, Box> { - let kind = &def.kind; - let left = self.eval_expr(&def.left, scope)?; - let right = self.eval_expr(&def.right, scope)?; - match kind { - &CompareType::Equal => self.do_deep_equal(&def.pos, left, right), - &CompareType::GT => self.do_gt(&def.pos, left, right), - &CompareType::LT => self.do_lt(&def.pos, left, right), - &CompareType::GTEqual => self.do_gtequal(&def.pos, left, right), - &CompareType::LTEqual => self.do_ltequal(&def.pos, left, right), - &CompareType::NotEqual => self.do_not_deep_equal(&def.pos, left, right), + &BinaryExprType::Equal => self.do_deep_equal(&def.pos, left, right), + &BinaryExprType::GT => self.do_gt(&def.pos, left, right), + &BinaryExprType::LT => self.do_lt(&def.pos, left, right), + &BinaryExprType::GTEqual => self.do_gtequal(&def.pos, left, right), + &BinaryExprType::LTEqual => self.do_ltequal(&def.pos, left, right), + &BinaryExprType::NotEqual => self.do_not_deep_equal(&def.pos, left, right), } } @@ -1247,7 +1239,6 @@ impl<'a> FileBuilder<'a> { match expr { &Expression::Simple(ref val) => self.eval_value(val, scope), &Expression::Binary(ref def) => self.eval_binary(def, scope), - &Expression::Compare(ref def) => self.eval_compare(def, scope), &Expression::Copy(ref def) => self.eval_copy(def, scope), &Expression::Grouped(ref expr) => self.eval_expr(expr, scope), &Expression::Format(ref def) => self.eval_format(def, scope), diff --git a/src/parse/mod.rs b/src/parse/mod.rs index f666744..d0b0662 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -277,6 +277,8 @@ make_fn!( make_fn!( value, Value>, either!( + // TODO This should move to op_expression instead of a value now. + // We probably still need a bareword parser though? trace_parse!(selector_value), trace_parse!(compound_value), trace_parse!(boolean_value), @@ -426,6 +428,7 @@ make_fn!( copy_expression, Expression>, do_each!( pos => pos, + // TODO This should become just a bareword symbol now selector => trace_parse!(selector_list), _ => punct!("{"), fields => optional!(trace_parse!(field_list)), @@ -635,6 +638,7 @@ make_fn!( fn call_expression(input: SliceIter) -> Result, Expression> { let parsed = do_each!(input.clone(), + // TODO This should become just a bareword symbol now callee_name => trace_parse!(selector_value), _ => punct!("("), args => optional!(separated!(punct!(","), trace_parse!(expression))), @@ -723,6 +727,7 @@ make_fn!( do_each!(_ => word!("map"), (ListOpType::Map)), do_each!(_ => word!("filter"), (ListOpType::Filter)) ), + // TODO This should become just a bareword symbol now macroname => trace_parse!(selector_value), list => trace_parse!(non_op_expression), (tuple_to_list_op(&input, optype, macroname, list).unwrap()) diff --git a/src/parse/precedence.rs b/src/parse/precedence.rs index 58eb025..236b545 100644 --- a/src/parse/precedence.rs +++ b/src/parse/precedence.rs @@ -24,8 +24,7 @@ use crate::ast::*; #[derive(Debug, PartialEq, Clone)] pub enum Element { Expr(Expression), - MathOp(BinaryExprType), - CompareOp(CompareType), + Op(BinaryExprType), } make_fn!( @@ -33,16 +32,16 @@ make_fn!( either!( do_each!( _ => punct!("+"), - (Element::MathOp(BinaryExprType::Add))), + (Element::Op(BinaryExprType::Add))), do_each!( _ => punct!("-"), - (Element::MathOp(BinaryExprType::Sub))), + (Element::Op(BinaryExprType::Sub))), do_each!( _ => punct!("*"), - (Element::MathOp(BinaryExprType::Mul))), + (Element::Op(BinaryExprType::Mul))), do_each!( _ => punct!("/"), - (Element::MathOp(BinaryExprType::Div))) + (Element::Op(BinaryExprType::Div))) ) ); @@ -76,7 +75,7 @@ fn parse_sum_operator(i: SliceIter) -> Result, Binar )); } let el = i_.next(); - if let Some(&Element::MathOp(ref op)) = el { + if let Some(&Element::Op(ref op)) = el { match op { &BinaryExprType::Add => { return Result::Complete(i_.clone(), op.clone()); @@ -121,7 +120,7 @@ fn parse_product_operator(i: SliceIter) -> Result, B )); } let el = i_.next(); - if let Some(&Element::MathOp(ref op)) = el { + if let Some(&Element::Op(ref op)) = el { match op { &BinaryExprType::Mul => { return Result::Complete(i_.clone(), op.clone()); @@ -201,34 +200,19 @@ make_fn!( ) ); -// TODO(jwall): Change comparison operators to use the do_binary_expr! with precedence? -fn tuple_to_compare_expression( - kind: CompareType, - left: Expression, - right: Expression, -) -> Expression { - let pos = left.pos().clone(); - Expression::Compare(ComparisonDef { - kind: kind, - left: Box::new(left), - right: Box::new(right), - pos: pos, - }) -} - make_fn!( compare_op_type, Element>, either!( - do_each!(_ => punct!("=="), (Element::CompareOp(CompareType::Equal))), - do_each!(_ => punct!("!="), (Element::CompareOp(CompareType::NotEqual))), - do_each!(_ => punct!("<="), (Element::CompareOp(CompareType::LTEqual))), - do_each!(_ => punct!(">="), (Element::CompareOp(CompareType::GTEqual))), - do_each!(_ => punct!("<"), (Element::CompareOp(CompareType::LT))), - do_each!(_ => punct!(">"), (Element::CompareOp(CompareType::GT))) + do_each!(_ => punct!("=="), (Element::Op(BinaryExprType::Equal))), + do_each!(_ => punct!("!="), (Element::Op(BinaryExprType::NotEqual))), + do_each!(_ => punct!("<="), (Element::Op(BinaryExprType::LTEqual))), + do_each!(_ => punct!(">="), (Element::Op(BinaryExprType::GTEqual))), + do_each!(_ => punct!("<"), (Element::Op(BinaryExprType::LT))), + do_each!(_ => punct!(">"), (Element::Op(BinaryExprType::GT))) ) ); -fn parse_compare_operator(i: SliceIter) -> Result, CompareType> { +fn parse_compare_operator(i: SliceIter) -> Result, BinaryExprType> { let mut i_ = i.clone(); if eoi(i_.clone()).is_complete() { return Result::Fail(Error::new( @@ -237,8 +221,20 @@ fn parse_compare_operator(i: SliceIter) -> Result, C )); } let el = i_.next(); - if let Some(&Element::CompareOp(ref op)) = el { - return Result::Complete(i_.clone(), op.clone()); + if let Some(&Element::Op(ref op)) = el { + match op { + &BinaryExprType::GT + | &BinaryExprType::GTEqual + | &BinaryExprType::LT + | &BinaryExprType::LTEqual + | &BinaryExprType::NotEqual + | &BinaryExprType::Equal => { + return Result::Complete(i_.clone(), op.clone()); + } + _other => { + // noop + } + }; } return Result::Fail(Error::new( format!( @@ -249,13 +245,19 @@ fn parse_compare_operator(i: SliceIter) -> Result, C )); } +make_fn!( + binary_expression, Expression>, + either!(compare_expression, math_expression, parse_expression) +); + make_fn!( compare_expression, Expression>, - do_each!( - left => either!(trace_parse!(math_expression), trace_parse!(parse_expression)), - typ => parse_compare_operator, - right => either!(trace_parse!(math_expression), trace_parse!(parse_expression)), - (tuple_to_compare_expression(typ, left, right)) + do_binary_expr!( + parse_compare_operator, + either!( + trace_parse!(math_expression), + trace_parse!(parse_expression) + ) ) ); @@ -340,11 +342,7 @@ pub fn op_expression<'a>(i: SliceIter<'a, Token>) -> Result, Ex Result::Incomplete(i) => Result::Incomplete(i), Result::Complete(rest, oplist) => { let i_ = SliceIter::new(&oplist); - let parse_result = either!( - i_.clone(), - trace_parse!(compare_expression), - trace_parse!(math_expression) - ); + let parse_result = binary_expression(i_); match parse_result { Result::Fail(_e) => { diff --git a/src/parse/test.rs b/src/parse/test.rs index 8ceb8d1..dbbed3e 100644 --- a/src/parse/test.rs +++ b/src/parse/test.rs @@ -619,8 +619,8 @@ fn test_expression_parse() { ); assert_parse!( expression("1 > 1"), - Expression::Compare(ComparisonDef { - kind: CompareType::GT, + Expression::Binary(BinaryOpDef { + kind: BinaryExprType::GT, left: Box::new(Expression::Simple(Value::Int(value_node!( 1, Position::new(1, 1, 0) @@ -634,8 +634,8 @@ fn test_expression_parse() { ); assert_parse!( expression("1 < 1"), - Expression::Compare(ComparisonDef { - kind: CompareType::LT, + Expression::Binary(BinaryOpDef { + kind: BinaryExprType::LT, left: Box::new(Expression::Simple(Value::Int(value_node!( 1, Position::new(1, 1, 0) @@ -649,8 +649,8 @@ fn test_expression_parse() { ); assert_parse!( expression("1 <= 1"), - Expression::Compare(ComparisonDef { - kind: CompareType::LTEqual, + Expression::Binary(BinaryOpDef { + kind: BinaryExprType::LTEqual, left: Box::new(Expression::Simple(Value::Int(value_node!( 1, Position::new(1, 1, 0) @@ -664,8 +664,8 @@ fn test_expression_parse() { ); assert_parse!( expression("1 >= 1"), - Expression::Compare(ComparisonDef { - kind: CompareType::GTEqual, + Expression::Binary(BinaryOpDef { + kind: BinaryExprType::GTEqual, left: Box::new(Expression::Simple(Value::Int(value_node!( 1, Position::new(1, 1, 0)