diff --git a/core/src/ast.rs b/core/src/ast.rs index 0a625c19..bb108f8a 100644 --- a/core/src/ast.rs +++ b/core/src/ast.rs @@ -489,7 +489,14 @@ pub(crate) fn evaluate( } Expr::Bop(bop, a, b) => eval!(*a)?.handle_two_nums( eval!(*b)?, - |a, b| a.bop(bop, b, attrs, context, int), + |a, b| { + // println!("====== .bop() '{}'", bop); + // println!("\t{:?}", a); + // println!("\t{:?}", b); + // println!("\tattr {:?}", attrs); + // println!("\t context {:?}", context); + a.bop(bop, b, attrs, context, int) + }, |a| |f| Expr::Bop(bop, f, Box::new(Expr::Literal(Value::Num(Box::new(a))))), |a| |f| Expr::Bop(bop, Box::new(Expr::Literal(Value::Num(Box::new(a)))), f), scope, diff --git a/core/src/eval.rs b/core/src/eval.rs index 3d9a40f9..db4818a1 100644 --- a/core/src/eval.rs +++ b/core/src/eval.rs @@ -11,6 +11,7 @@ pub(crate) fn evaluate_to_value( context: &mut crate::Context, int: &I, ) -> FResult { + println!("evaluate_to_value"); let lex = lexer::lex(input, context, int); let mut tokens = vec![]; let mut missing_open_parens: i32 = 0; @@ -24,7 +25,9 @@ pub(crate) fn evaluate_to_value( for _ in 0..missing_open_parens { tokens.insert(0, lexer::Token::Symbol(lexer::Symbol::OpenParens)); } + println!("\t{:?}", tokens); let parsed = parser::parse_tokens(&tokens)?; + println!("parsed: {:#?}", parsed); let result = ast::evaluate(parsed, scope, attrs, context, int)?; Ok(result) } @@ -80,6 +83,7 @@ pub(crate) fn evaluate_to_spans( ) -> FResult<(Vec, bool, Attrs)> { let (attrs, input) = parse_attrs(input); let value = evaluate_to_value(input, scope, attrs, context, int)?; + println!("{} {:#?}", value.type_name(), value); context.variables.insert("_".to_string(), value.clone()); context.variables.insert("ans".to_string(), value.clone()); Ok(( diff --git a/core/src/num/unit.rs b/core/src/num/unit.rs index 40dfa2a3..d5c16207 100644 --- a/core/src/num/unit.rs +++ b/core/src/num/unit.rs @@ -278,6 +278,9 @@ impl Value { } pub(crate) fn div(self, rhs: Self, int: &I) -> FResult { + println!("====== div"); + println!("\t{:?}", self); + println!("\t{:?}", rhs); let mut components = self.unit.components.clone(); for rhs_component in rhs.unit.components { components.push(UnitExponent::new( diff --git a/core/src/parser.rs b/core/src/parser.rs index 94f26d0d..7371252b 100644 --- a/core/src/parser.rs +++ b/core/src/parser.rs @@ -207,7 +207,12 @@ fn parse_apply_cont<'a>(input: &'a [Token], lhs: &Expr) -> ParseResult<'a> { (_, Expr::Literal(Value::Num(_))) => { Expr::ApplyFunctionCall(Box::new(lhs.clone()), Box::new(rhs)) } - (Expr::Literal(Value::Num(_)) | Expr::ApplyMul(_, _), _) => { + (Expr::ApplyMul(_, _), _) => { + println!("\t-> ApplyMul *"); + Expr::ApplyMul(Box::new(lhs.clone()), Box::new(rhs)) + } + (Expr::Literal(Value::Num(_)), _) => { + println!("\t-> ApplyMul implicit, rhs {:?}", rhs); Expr::ApplyMul(Box::new(lhs.clone()), Box::new(rhs)) } _ => Expr::Apply(Box::new(lhs.clone()), Box::new(rhs)), @@ -268,13 +273,15 @@ fn parse_mixed_fraction<'a>(input: &'a [Token], lhs: &Expr) -> ParseResult<'a> { fn parse_multiplication_cont(input: &[Token]) -> ParseResult<'_> { let ((), input) = parse_fixed_symbol(input, Symbol::Mul)?; + println!("\t\tparse_multiplication_cont2 {:?}", input.to_vec()); let (b, input) = parse_power(input, true)?; + println!("\t\tparse_multiplication_cont3 {:?}", input.to_vec()); Ok((b, input)) } fn parse_division_cont(input: &[Token]) -> ParseResult<'_> { let ((), input) = parse_fixed_symbol(input, Symbol::Div)?; - let (b, input) = parse_power(input, true)?; + let (b, input) = parse_implicit_multiplication(input)?; Ok((b, input)) } @@ -301,29 +308,51 @@ fn parse_modulo2_cont(input: &[Token]) -> ParseResult<'_> { }) { return Err(ParseError::UnexpectedInput); } - let (b, input) = parse_power(input, true)?; + let (b, input) = parse_implicit_multiplication(input)?; Ok((b, input)) } +fn parse_implicit_multiplication(input: &[Token]) -> ParseResult<'_> { + let (mut res, mut input) = parse_power(input, true)?; + println!("parse_implicit_multiplication {:?}", input.to_vec()); + loop { + if let Ok((new_res, remaining)) = parse_apply_cont(input, &res) { + println!("\tparse_apply_cont {:?}", remaining.to_vec()); + res = new_res; + input = remaining; + } else { + break; + } + } + Ok((res, input)) +} + fn parse_multiplicative(input: &[Token]) -> ParseResult<'_> { let (mut res, mut input) = parse_power(input, true)?; + println!("parse_multiplicative {:?}", input.to_vec()); loop { if let Ok((term, remaining)) = parse_multiplication_cont(input) { + println!("\tparse_multiplication_cont {:?}", remaining.to_vec()); res = Expr::Bop(Bop::Mul, Box::new(res.clone()), Box::new(term)); input = remaining; } else if let Ok((term, remaining)) = parse_division_cont(input) { + println!("\tparse_division_cont {:?}", remaining.to_vec()); res = Expr::Bop(Bop::Div, Box::new(res.clone()), Box::new(term)); input = remaining; } else if let Ok((term, remaining)) = parse_modulo_cont(input) { + println!("\tparse_modulo_cont {:?}", remaining.to_vec()); res = Expr::Bop(Bop::Mod, Box::new(res.clone()), Box::new(term)); input = remaining; } else if let Ok((term, remaining)) = parse_modulo2_cont(input) { + println!("\tparse_modulo2_cont {:?}", remaining.to_vec()); res = Expr::Bop(Bop::Mod, Box::new(res.clone()), Box::new(term)); input = remaining; } else if let Ok((new_res, remaining)) = parse_mixed_fraction(input, &res) { + println!("\tparse_mixed_fraction {:?}", remaining.to_vec()); res = new_res; input = remaining; } else if let Ok((new_res, remaining)) = parse_apply_cont(input, &res) { + println!("\tparse_apply_cont {:?}", remaining.to_vec()); res = new_res; input = remaining; } else { diff --git a/core/tests/integration_tests.rs b/core/tests/integration_tests.rs index 936be9a6..a663d42b 100644 --- a/core/tests/integration_tests.rs +++ b/core/tests/integration_tests.rs @@ -795,6 +795,15 @@ fn order_of_operations_17() { test_eval("-3 -1/2", "-3.5"); } +#[test] +fn order_of_operations_18() { + test_eval("1/2/4", "0.125"); +} +#[test] +fn order_of_operations_19() { + test_eval("19 % 7 % 3", "2"); +} + #[test] fn yobibyte() { test_eval("1 YiB to bytes", "1208925819614629174706176 bytes"); @@ -6078,3 +6087,33 @@ fn european_formatting() { "approx. 0,9320390859" ); } + +#[test] +fn implitic_mul_priority_1() { + test_eval("10m/2s", "2 m / s"); +} + +#[test] +fn implitic_mul_priority_2() { + test_eval("10m/2s * 5 s", "25 m"); +} + +#[test] +fn implitic_mul_priority_3() { + test_eval("sin pi/2", "0") +} + +#[test] +fn implitic_mul_priority_4() { + test_eval("1 3/8 inches", "1.375 inches") +} + +#[test] +fn implitic_mul_priority_5() { + test_eval("-sin (pi/2)", "-1") +} + +#[test] +fn implitic_mul_priority_6() { + test_eval("-sin (pi/2)", "-1") +}