Skip to content

fix(format): keep the parentheses an expression's reading depends on; release 0.1.1 - #1

Merged
superWorldSavior merged 2 commits into
mainfrom
fix/format-parentheses
Oct 25, 2026
Merged

superWorldSavior merged 2 commits into
mainfrom
fix/format-parentheses

Conversation

@superWorldSavior

Copy link
Copy Markdown
Owner

Summary

  • The bug. exprToString only parenthesised an operand that binds more loosely than its parent.
  • The fix. Operands are now parenthesised by side and operator:
    • the right operand of - or / at the same level: a - (b - c), a / (b * c);
    • a comparison inside a comparison;
    • a negation on the right: a - (-b);
    • a unary minus over a compound or negated operand: -(a + b), -(-a).
  • Unchanged. Parentheses that change nothing are still left out: a - b - c, a * b * c, a + b - c, (a + b) * 2, t ≥ -10 and t ≤ 80.

Test plan

  • New tests/format_test.ts (the first tests for format.ts). Three of its four tests failed before the fix. The fourth pins the cases that must stay free of parentheses.
  • deno task test (35 passed, z3 included), deno task check, deno lint, and deno fmt --check on the changed files.
    • Nine files on main are already unformatted; this PR leaves them alone.

Not done here

  • No version bump and no JSR publication.
  • mcp-syson will pick the fix up once a version is published and its deno.json moves off jsr:@casys/constraint-solver@0.1.0.

🤖 Generated with Claude Code

superWorldSavior and others added 2 commits October 25, 2026 11:53
exprToString parenthesised an operand only when it bound more loosely
than its parent, so a right operand at the same level as `-` or `/`
lost its parentheses: `thrust / (totalMass * 9.81) >= 2` rendered as
`thrust / totalMass * 9.81 ≥ 2`, which denotes another expression than
the one evaluated. The same held for `a - (b - c)`, comparisons nested
in comparisons, and a unary minus over a compound or negated operand
(`-(a + b)` rendered as `-a + b`).

Operands are now parenthesised by side and operator; parentheses that
change nothing are still left out. First tests for format.ts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review follow-up on the parentheses fix:
- a negation right of an operator is grouped only under `-`
  (`t ≥ -10`, not `t ≥ (-10)`); a negative literal there too (`a - (-5)`);
- a negative under a unary minus is grouped (`-(-5)`, formerly `--5`);
- a quantity right of `*` or `/` is grouped, since mathjs reads
  `5 / 2 kg` as `(5 / 2) kg`;
- an operator outside the precedence table groups its compound operands.

A 4.77M-tree round-trip fuzz finds no rendering that reads as another
expression. Version 0.1.1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@superWorldSavior superWorldSavior changed the title fix(format): keep the parentheses an expression's reading depends on fix(format): keep the parentheses an expression's reading depends on; release 0.1.1 Oct 25, 2026
@superWorldSavior
superWorldSavior merged commit 3f75bdb into main Oct 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant