diff --git a/src/token/mod.rs b/src/token/mod.rs index b15ab08..62a806a 100644 --- a/src/token/mod.rs +++ b/src/token/mod.rs @@ -355,7 +355,25 @@ fn partial_tokens_to_tokens(mut tokens: &[PartialToken]) -> EvalexprResult() { Some(Token::Boolean(boolean)) } else { - Some(Token::Identifier(literal.to_string())) + // If there are two tokens following this one, check if the next one is + // a plus or a minus. If so, then attempt to parse all three tokens as a + // scientific notation number of the form `e{+,-}`, + // for example [Literal("10e"), Minus, Literal("3")] => "1e-3".parse(). + match (second, third) { + (Some(s), Some(t)) + if s == PartialToken::Minus || s == PartialToken::Plus => + { + if let Ok(number) = + format!("{}{}{}", literal, s, t).parse::() + { + cutoff = 3; + Some(Token::Float(number)) + } else { + Some(Token::Identifier(literal.to_string())) + } + } + _ => Some(Token::Identifier(literal.to_string())), + } } }, PartialToken::Whitespace => { diff --git a/tests/integration.rs b/tests/integration.rs index 705c1ce..fba3d23 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -17,6 +17,11 @@ fn test_unary_examples() { assert_eq!(eval("-3"), Ok(Value::Int(-3))); assert_eq!(eval("-3.6"), Ok(Value::Float(-3.6))); assert_eq!(eval("----3"), Ok(Value::Int(3))); + assert_eq!(eval("1e0"), Ok(Value::Float(1.0))); + assert_eq!(eval("1e-0"), Ok(Value::Float(1.0))); + assert_eq!(eval("10e3"), Ok(Value::Float(10000.0))); + assert_eq!(eval("10e+3"), Ok(Value::Float(10000.0))); + assert_eq!(eval("10e-3"), Ok(Value::Float(0.01))); } #[test] @@ -41,6 +46,8 @@ fn test_binary_examples() { assert_eq!(eval("3+-1"), Ok(Value::Int(2))); assert_eq!(eval("-3-5"), Ok(Value::Int(-8))); assert_eq!(eval("-5--3"), Ok(Value::Int(-2))); + assert_eq!(eval("5e2--3"), Ok(Value::Float(503.0))); + assert_eq!(eval("-5e-2--3"), Ok(Value::Float(2.95))); } #[test]