fix: plus evaluated before minus
This commit is contained in:
parent
b7c3972949
commit
5f25c92404
2 changed files with 22 additions and 4 deletions
|
|
@ -112,24 +112,6 @@ fn collapse_toplevel(nodes: &mut Vec<Node>, mut end: usize) {
|
||||||
end -= 1;
|
end -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
while let Some(operator) = nodes[start..end]
|
|
||||||
.iter()
|
|
||||||
.position(|n| *n == Node::Operator(Operator::Plus))
|
|
||||||
{
|
|
||||||
let lhs = match nodes.remove(start + operator - 1) {
|
|
||||||
Node::Number(n) => n,
|
|
||||||
n => panic!("operator has an invalid operand: {n:?}"),
|
|
||||||
};
|
|
||||||
end -= 1;
|
|
||||||
match &mut nodes[start..end][operator] {
|
|
||||||
Node::Number(n) => n.add_from(lhs),
|
|
||||||
n => panic!("operator has an invalid operand: {n:?}"),
|
|
||||||
};
|
|
||||||
|
|
||||||
nodes.remove(start + operator - 1);
|
|
||||||
end -= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
while let Some(operator) = nodes[start..end]
|
while let Some(operator) = nodes[start..end]
|
||||||
.iter()
|
.iter()
|
||||||
.position(|n| *n == Node::Operator(Operator::Minus))
|
.position(|n| *n == Node::Operator(Operator::Minus))
|
||||||
|
|
@ -148,6 +130,24 @@ fn collapse_toplevel(nodes: &mut Vec<Node>, mut end: usize) {
|
||||||
end -= 1;
|
end -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while let Some(operator) = nodes[start..end]
|
||||||
|
.iter()
|
||||||
|
.position(|n| *n == Node::Operator(Operator::Plus))
|
||||||
|
{
|
||||||
|
let lhs = match nodes.remove(start + operator - 1) {
|
||||||
|
Node::Number(n) => n,
|
||||||
|
n => panic!("operator has an invalid operand: {n:?}"),
|
||||||
|
};
|
||||||
|
end -= 1;
|
||||||
|
match &mut nodes[start..end][operator] {
|
||||||
|
Node::Number(n) => n.add_from(lhs),
|
||||||
|
n => panic!("operator has an invalid operand: {n:?}"),
|
||||||
|
};
|
||||||
|
|
||||||
|
nodes.remove(start + operator - 1);
|
||||||
|
end -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
if nodes.len() > 1 {
|
if nodes.len() > 1 {
|
||||||
nodes.remove(end);
|
nodes.remove(end);
|
||||||
nodes.remove(start);
|
nodes.remove(start);
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,24 @@ use rug::Float;
|
||||||
|
|
||||||
use crate::nodes::{Function, Node, Nodes, Operator, PREC};
|
use crate::nodes::{Function, Node, Nodes, Operator, PREC};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn plus_minus_order() {
|
||||||
|
assert_eq!(
|
||||||
|
Nodes::from_str("1 - 4 - 5").unwrap().evaluate().to_f64(),
|
||||||
|
-8.
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
Nodes::from_str("1 - 4 + 5").unwrap().evaluate().to_f64(),
|
||||||
|
2.
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
Nodes::from_str("1 + 4 - 5").unwrap().evaluate().to_f64(),
|
||||||
|
0.
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn e_edge_case() {
|
fn e_edge_case() {
|
||||||
assert_eq!(Nodes::from_str("1e-1").unwrap().evaluate().to_f64(), 0.1)
|
assert_eq!(Nodes::from_str("1e-1").unwrap().evaluate().to_f64(), 0.1)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue