From d8dc5499542eed1476d525a7249126701934f257 Mon Sep 17 00:00:00 2001 From: electria Date: Sun, 4 Oct 2026 16:04:25 -0700 Subject: [PATCH] feat: add "e" as a constant this is not great, because due to lacking whitespace-awareness `e sin(1)` evaluates as `esin(1)` which does not exist. --- src/nodes/parse.rs | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/nodes/parse.rs b/src/nodes/parse.rs index 07f6d4c..68e6fcc 100644 --- a/src/nodes/parse.rs +++ b/src/nodes/parse.rs @@ -13,6 +13,7 @@ impl Node { "pi" => Self::Number(Float::with_val(PREC, f64::consts::PI)), // Planck's constant, in J*s (joule-seconds) "h" => Self::Number(Float::with_val(PREC, 6.62607015e-34)), + "e" => Self::Number(Float::with_val(PREC, f64::consts::E)), _ => Self::Function(s.parse()?), }) } @@ -70,10 +71,14 @@ impl FromStr for Nodes { fn from_str(s: &str) -> Result { /// A superset of `char::is_numeric` /// that includes other characters parseable into numbers, - /// such as `.` (for decimal) and `e` for scientific notation. + /// now only `.` (for decimals) + /// + /// since including `e` makes it not parsable as a constant, + /// this function effectively only checks if the character can *start* a number + /// (since a number cannot start with `e`) fn is_number_char(c: char) -> bool { match c { - '.' | 'e' => true, + '.' => true, c => c.is_numeric(), } } @@ -114,8 +119,10 @@ impl FromStr for Nodes { } ParsingState::ReadingNumber(start_index) => { if !is_number_char(c) - // don't stop reading number on a special case, eg "1e-1" - && !(filtered_string.chars().nth(i - 1) == Some('e') && c == '-') + && !(c == 'e' && filtered_string.chars().nth(i + 1).is_some_and(char::is_numeric)) + // don't stop reading number on special case eg "1e-1" + && !(c == 'e' && filtered_string.chars().nth(i + 1).is_some_and(|c| c == '-')) + && !(c == '-' && filtered_string.chars().nth(i - 1).is_some_and(|c| c == 'e')) { nodes.push(Node::Number( Float::parse(&filtered_string[start_index..i]) @@ -203,3 +210,16 @@ fn test() { ], ) } +#[test] +fn test_e() { + assert_eq!( + Nodes::from_str("5e * 5").unwrap().as_ref(), + &[ + Node::Number(Float::with_val(PREC, 5)), + Node::Operator(Operator::Mult), + Node::Number(Float::with_val(PREC, f64::consts::E)), + Node::Operator(Operator::Mult), + Node::Number(Float::with_val(PREC, 5)) + ], + ) +}