From 7118506a2a51a3261087d69a57a1c3f185175829 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 11 Oct 2020 21:37:15 -0700 Subject: Accept `**` operator as exponentiation (#39) * Accept `**` operator as exponentiation * Add test of exponentiation --- src/lex/mod.rs | 8 +++++++- src/main.rs | 5 +++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/lex/mod.rs b/src/lex/mod.rs index b21bafb..3222c12 100644 --- a/src/lex/mod.rs +++ b/src/lex/mod.rs @@ -129,7 +129,8 @@ pub fn lexer(input: &str, prev_ans: Option) -> Result, CalcError let mut result: Vec = vec![]; let mut last_char_is_op = true; - for letter in input.chars() { + let mut chars = input.chars().peekable(); + while let Some(mut letter) = chars.next() { match letter { '0'..='9' | '.' => { if !char_vec.is_empty() { @@ -209,6 +210,11 @@ pub fn lexer(input: &str, prev_ans: Option) -> Result, CalcError } '/' | '*' | '%' | '^' | '!' => { drain_stack(&mut num_vec, &mut char_vec, &mut result); + if letter == '*' && chars.peek() == Some(&'*') { + // Accept `**` operator as meaning `^` (exponentation). + let _ = chars.next(); + letter = '^'; + } let operator_token: Token = OPERATORS.get(&letter).unwrap().clone(); result.push(operator_token); last_char_is_op = true; diff --git a/src/main.rs b/src/main.rs index 2a2cf9d..bc22ce2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -227,6 +227,11 @@ mod tests { assert_eq!(32., evaled); } #[test] + fn exponentiation() { + let evaled = eval_math_expression("2 ** 2 ** 3", None).unwrap(); + assert_eq!(256., evaled); // 2^(2^3), not (2^2)^3 + } + #[test] fn floating_ops() { let evaled = eval_math_expression("1.2816 + 1 + 1.2816/1.2", Some(0f64)).unwrap(); assert_eq!(3.3496, evaled); -- cgit v1.2.3