From b3e0a7e8d372d9b7107de01572b22d7e11aff5b7 Mon Sep 17 00:00:00 2001 From: Harrison Booth Date: Mon, 19 Oct 2026 16:06:47 -0500 Subject: [PATCH] Formulas: count the leftmost operand of a chain at the same depth The left end of a flat operator chain is not nesting, so (((...1)))+1 is accepted whenever (((...1))) is, in Spanish entry and display. Co-Authored-By: Claude Sonnet 5.5 --- crates/formula/src/input.rs | 2 +- crates/formula/src/tests.rs | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/crates/formula/src/input.rs b/crates/formula/src/input.rs index 7c0fe8b53..38a87cd11 100644 --- a/crates/formula/src/input.rs +++ b/crates/formula/src/input.rs @@ -194,7 +194,7 @@ fn normalize(expr: &mut Expr, known_name: &impl Fn(&str) -> bool, bindings: &mut normalize(right, known_name, bindings, depth + 1, display)?; node = left; } - normalize(node, known_name, bindings, depth + 1, display)?; + normalize(node, known_name, bindings, depth, display)?; } Expr::Array(rows) if display => { for row in rows { diff --git a/crates/formula/src/tests.rs b/crates/formula/src/tests.rs index 185ffdb23..4177fd055 100644 --- a/crates/formula/src/tests.rs +++ b/crates/formula/src/tests.rs @@ -435,3 +435,21 @@ fn longest_flat_chains_clone_compare_walk_and_adjust_without_deep_recursion() { .expect("spawn"); handle.join().expect("long chains must not overflow the stack"); } + +#[test] +fn spanish_input_counts_left_operand_of_a_chain_at_the_same_depth() { + // The leftmost operand of a flat chain is not nested, so `(((…1)))+1` is accepted whenever + // `(((…1)))` is, in both the pre-check and `normalize`. + let wrap = |n: usize| { + let mut e = Expr::Number(1.0); + for _ in 0..n { + e = Expr::Paren(Box::new(e)); + } + e + }; + let es = |e: &Expr| crate::print_input(e, FormulaLocale::Es, |_| false); + let deepest = (0..400).take_while(|&n| es(&wrap(n)).is_ok()).last().expect("depth 0 is accepted"); + assert!(deepest > 1 && deepest < 400); + let chain = Expr::Binary(BinOp::Add, Box::new(wrap(deepest)), Box::new(Expr::Number(1.0))); + assert!(es(&chain).is_ok()); +}