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)),
|
"pi" => Self::Number(Float::with_val(PREC, f64::consts::PI)),
|
||||||
// Planck's constant, in J*s (joule-seconds)
|
// Planck's constant, in J*s (joule-seconds)
|
||||||
"h" => Self::Number(Float::with_val(PREC, 6.62607015e-34)),
|
"h" => Self::Number(Float::with_val(PREC, 6.62607015e-34)),
|
||||||
|
"e" => Self::Number(Float::with_val(PREC, f64::consts::E)),
|
||||||
_ => Self::Function(s.parse()?),
|
_ => Self::Function(s.parse()?),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -70,10 +71,14 @@ impl FromStr for Nodes {
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
/// A superset of `char::is_numeric`
|
/// A superset of `char::is_numeric`
|
||||||
/// that includes other characters parseable into numbers,
|
/// 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 {
|
fn is_number_char(c: char) -> bool {
|
||||||
match c {
|
match c {
|
||||||
'.' | 'e' => true,
|
'.' => true,
|
||||||
c => c.is_numeric(),
|
c => c.is_numeric(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -114,8 +119,10 @@ impl FromStr for Nodes {
|
||||||
}
|
}
|
||||||
ParsingState::ReadingNumber(start_index) => {
|
ParsingState::ReadingNumber(start_index) => {
|
||||||
if !is_number_char(c)
|
if !is_number_char(c)
|
||||||
// don't stop reading number on a special case, eg "1e-1"
|
&& !(c == 'e' && filtered_string.chars().nth(i + 1).is_some_and(char::is_numeric))
|
||||||
&& !(filtered_string.chars().nth(i - 1) == Some('e') && c == '-')
|
// 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(
|
nodes.push(Node::Number(
|
||||||
Float::parse(&filtered_string[start_index..i])
|
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