diff --git a/src/eval.rs b/src/eval.rs index 3c1dd043db..6fa450cf9c 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -259,6 +259,34 @@ fn eval_operator(left_expr: &Evaluated, op: Operator, right_expr: &Evaluated) -> // Equals (_, Equals, _) => eq(left_expr, right_expr), + // LessThan + (Int(left_num), LessThan, Int(right_num)) => bool_variant(left_num < right_num), + (Frac(left_num), LessThan, Frac(right_num)) => bool_variant(left_num < right_num), + (Int(_), LessThan, Frac(_)) => EvalError(TypeMismatch("tried check Frac < Int. Explicitly convert them to the same type first!".to_string())), + (Frac(_), LessThan, Int(_)) => EvalError(TypeMismatch("tried check Int < Frac. Explicitly convert them to the same type first!".to_string())), + (_, LessThan, _) => EvalError(TypeMismatch("tried to check if one non-number < another non-number".to_string())), + + // LessThanOrEq + (Int(left_num), LessThanOrEq, Int(right_num)) => bool_variant(left_num <= right_num), + (Frac(left_num), LessThanOrEq, Frac(right_num)) => bool_variant(left_num <= right_num), + (Int(_), LessThanOrEq, Frac(_)) => EvalError(TypeMismatch("tried check Frac <= Int. Explicitly convert them to the same type first!".to_string())), + (Frac(_), LessThanOrEq, Int(_)) => EvalError(TypeMismatch("tried check Int <= Frac. Explicitly convert them to the same type first!".to_string())), + (_, LessThanOrEq, _) => EvalError(TypeMismatch("tried to check if one non-number <= another non-number".to_string())), + + // GreaterThan + (Int(left_num), GreaterThan, Int(right_num)) => bool_variant(left_num > right_num), + (Frac(left_num), GreaterThan, Frac(right_num)) => bool_variant(left_num > right_num), + (Int(_), GreaterThan, Frac(_)) => EvalError(TypeMismatch("tried check Frac > Int. Explicitly convert them to the same type first!".to_string())), + (Frac(_), GreaterThan, Int(_)) => EvalError(TypeMismatch("tried check Int > Frac. Explicitly convert them to the same type first!".to_string())), + (_, GreaterThan, _) => EvalError(TypeMismatch("tried to check if one non-number > another non-number".to_string())), + + // GreaterThanOrEq + (Int(left_num), GreaterThanOrEq, Int(right_num)) => bool_variant(left_num >= right_num), + (Frac(left_num), GreaterThanOrEq, Frac(right_num)) => bool_variant(left_num >= right_num), + (Int(_), GreaterThanOrEq, Frac(_)) => EvalError(TypeMismatch("tried check Frac >= Int. Explicitly convert them to the same type first!".to_string())), + (Frac(_), GreaterThanOrEq, Int(_)) => EvalError(TypeMismatch("tried check Int >= Frac. Explicitly convert them to the same type first!".to_string())), + (_, GreaterThanOrEq, _) => EvalError(TypeMismatch("tried to check if one non-number >= another non-number".to_string())), + // Plus (Int(left_num), Plus, Int(right_num)) => Int(left_num + right_num), (Frac(left_num), Plus, Frac(right_num)) => Frac(left_num + right_num), diff --git a/src/expr.rs b/src/expr.rs index c8240a698f..5639c8e3d4 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -44,5 +44,6 @@ pub enum Pattern { #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] pub enum Operator { - Plus, Minus, Star, Slash, DoubleSlash, Equals, + Plus, Minus, Star, Slash, DoubleSlash, + Equals, LessThan, GreaterThan, LessThanOrEq, GreaterThanOrEq } diff --git a/src/parse.rs b/src/parse.rs index c586506ddb..789d471c88 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -339,11 +339,15 @@ where I: Stream, I::Error: ParseError { choice(( - string("==").map(|_| Operator::Equals), + attempt(string("==")).map(|_| Operator::Equals), + attempt(string("<=")).map(|_| Operator::LessThanOrEq), + attempt(string(">=")).map(|_| Operator::GreaterThanOrEq), char('+').map(|_| Operator::Plus), char('-').map(|_| Operator::Minus), char('*').map(|_| Operator::Star), char('/').map(|_| Operator::Slash), + char('<').map(|_| Operator::LessThan), + char('>').map(|_| Operator::GreaterThan), )) } diff --git a/tests/test_parse.rs b/tests/test_parse.rs index 62d1321dd6..4143904f12 100644 --- a/tests/test_parse.rs +++ b/tests/test_parse.rs @@ -288,6 +288,42 @@ mod test_parse { ); } + #[test] + fn comparison_operators() { + assert_eq!( + parse_standalone("x >= 0"), + Ok((Operator( + Box::new(Var("x".to_string())), + GreaterThanOrEq, + Box::new(Int(0)) + ), "")) + ); + assert_eq!( + parse_standalone("x > 0"), + Ok((Operator( + Box::new(Var("x".to_string())), + GreaterThan, + Box::new(Int(0)) + ), "")) + ); + assert_eq!( + parse_standalone("x <= 0"), + Ok((Operator( + Box::new(Var("x".to_string())), + LessThanOrEq, + Box::new(Int(0)) + ), "")) + ); + assert_eq!( + parse_standalone("x < 0"), + Ok((Operator( + Box::new(Var("x".to_string())), + LessThan, + Box::new(Int(0)) + ), "")) + ); + } + #[test] fn single_operator() {