Merge pull request #484 from nihilist-narwhal:fix-long-operator-chains
This commit is contained in:
commit
96897b709c
|
|
@ -465,9 +465,22 @@ impl<'h> Evaluator<'h> {
|
|||
}
|
||||
}
|
||||
_ => {
|
||||
let x = self.value(a);
|
||||
let y = self.value(b);
|
||||
Ev::V(binary_values(op, &x, &y))
|
||||
// A long chain such as A1+A2+…+A500 nests to the left: fold it in a loop instead
|
||||
// of one level of recursion per operator (past the depth limit it was #CALC!).
|
||||
let mut rest = vec![(op, b)];
|
||||
let mut left = a;
|
||||
while let Expr::Binary(o, l, r) = left
|
||||
&& !matches!(o, BinOp::Range | BinOp::Union | BinOp::Intersect)
|
||||
{
|
||||
rest.push((*o, r.as_ref()));
|
||||
left = l.as_ref();
|
||||
}
|
||||
let mut acc = self.value(left);
|
||||
while let Some((o, r)) = rest.pop() {
|
||||
let y = self.value(r);
|
||||
acc = binary_values(o, &acc, &y);
|
||||
}
|
||||
Ev::V(acc)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -596,6 +596,17 @@ fn text_function() {
|
|||
assert_eq!(t.get("A1"), Value::from("1,234.50"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn long_operator_chains() {
|
||||
let mut t = T::new();
|
||||
t.set("A1", "1");
|
||||
// 1,000 additions: a formula of 3,000 characters, well within Excel's 8,192.
|
||||
t.set("B1", &format!("={}", vec!["A1"; 1000].join("+")));
|
||||
assert_eq!(t.num("B1"), 1000.0);
|
||||
t.set("B2", &format!("=5{}", "+1-1".repeat(600)));
|
||||
assert_eq!(t.num("B2"), 5.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn subtotal_skips_hidden() {
|
||||
let mut t = T::new();
|
||||
|
|
|
|||
Loading…
Reference in New Issue