diff --git a/src/lex.rs b/src/lex.rs index 64d767a..50a45e3 100644 --- a/src/lex.rs +++ b/src/lex.rs @@ -2,6 +2,7 @@ * Refer to LICENCE for more information. * */ +use num::pow; use once_cell::sync::Lazy; use std::collections::HashMap; @@ -237,10 +238,32 @@ pub fn lexer(input: &str, prev_ans: Option) -> Result, CalcError } 'a'..='z' | 'A'..='Z' => { let parse_num = num_vec.parse::().ok(); + if let Some(x) = parse_num { + num_vec.clear(); + + // Check for exponential notation + if letter == 'e' { + while let Some(next) = chars.peek() { + if !matches!(*next, '0'..='9') { + break; + } + + num_vec.push(*next); + chars.next(); + } + + if num_vec.len() > 0 { + if let Some(exp) = num_vec.parse::().ok() { + result.push(Token::Num(x * pow(10 as f64, exp) as f64)); + num_vec.clear(); + continue; + } + } + } + result.push(Token::Num(x)); result.push(OPERATORS.get(&'*').unwrap().clone()); - num_vec.clear(); } char_vec.push(letter); last_char_is_op = false; diff --git a/src/main.rs b/src/main.rs index 667d064..b8702fa 100644 --- a/src/main.rs +++ b/src/main.rs @@ -283,6 +283,16 @@ mod tests { assert_eq!(evaled, Ok(20.0855369232)); } #[test] + fn eval_exponential_notation() { + let evaled = eval("1e5", None); + assert_eq!(evaled, Ok(100000.0)); + } + #[test] + fn eval_exponential_notation_decimal() { + let evaled = eval("2.5e5", None); + assert_eq!(evaled, Ok(250000.0)); + } + #[test] fn eval_e_times_n() { let evaled = eval("e0", None); assert_eq!(evaled, Ok(0.));