Merge pull request #628 from MarekSpodBiedry:issue-527
This commit is contained in:
commit
3794892f28
|
|
@ -224,10 +224,20 @@ fn write_expr(s: &mut String, e: &Expr, r1c1: Option<CellRef>) {
|
|||
}
|
||||
},
|
||||
},
|
||||
Expr::Binary(op, a, b) => {
|
||||
write_expr(s, a, r1c1);
|
||||
s.push_str(op.symbol());
|
||||
write_expr(s, b, r1c1);
|
||||
Expr::Binary(..) => {
|
||||
// Walk the left spine iteratively: a flat chain such as `1+1+1+...` parses into a
|
||||
// tree one level deeper per operator, and recursing on it could exhaust the stack.
|
||||
let mut rest: Vec<(&BinOp, &Expr)> = Vec::new();
|
||||
let mut first = e;
|
||||
while let Expr::Binary(op, a, b) = first {
|
||||
rest.push((op, b));
|
||||
first = a;
|
||||
}
|
||||
write_expr(s, first, r1c1);
|
||||
for (op, right) in rest.into_iter().rev() {
|
||||
s.push_str(op.symbol());
|
||||
write_expr(s, right, r1c1);
|
||||
}
|
||||
}
|
||||
Expr::Call(name, args) => {
|
||||
s.push_str(name);
|
||||
|
|
|
|||
|
|
@ -301,3 +301,25 @@ fn trim_references_adjust() {
|
|||
let refs: Vec<String> = parse("SUM(Sheet2!A1:.B5)").unwrap().references().iter().map(|r| printer::reference_a1(r)).collect();
|
||||
assert_eq!(refs, ["Sheet2!A1:B5"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn prints_long_flat_chain_without_deep_recursion() {
|
||||
// Small stack: a recursive printer overflows long before 20000 levels.
|
||||
let handle = std::thread::Builder::new()
|
||||
.stack_size(256 * 1024)
|
||||
.spawn(|| {
|
||||
let mut e = Expr::Number(1.0);
|
||||
for _ in 0..20000 {
|
||||
e = Expr::Binary(BinOp::Add, Box::new(e), Box::new(Expr::Number(1.0)));
|
||||
}
|
||||
let text = print(&e);
|
||||
let r1c1 = print_r1c1(&e, gridcraft_core::CellRef { row: 0, col: 0 });
|
||||
// Dropping the deep tree recurses; leak it so only the printer is under test.
|
||||
std::mem::forget(e);
|
||||
(text, r1c1)
|
||||
})
|
||||
.expect("spawn");
|
||||
let (text, r1c1) = handle.join().expect("printer must not overflow the stack");
|
||||
assert_eq!(text, vec!["1"; 20001].join("+"));
|
||||
assert_eq!(r1c1, text);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue