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.
This commit is contained in:
parent
ba33a71501
commit
d8dc549954
1 changed files with 24 additions and 4 deletions
|
|
@ -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<Self, Self::Err> {
|
||||
/// 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))
|
||||
],
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue