An expression mixing - and + at the same level is evaluated right to left
#1
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Source: TODO.md §6 item 35 (at
9151438)a - b + ccomputesa - (b + c). A C128, and every BASIC this descends from, folds a run ofsame-precedence additive operators left to right.
The second line is right and the first is not; 9 is the answer. Nothing fails -- this is a
program that quietly computes something else -- and both tutorials work around it by
parenthesising every mixed
+and-as a rule rather than where it happens to matter.The cause is the grammar's shape, not a missing loop.
subtraction()(src/parser.c:425)sits above
addition()(:447) as its own precedence level, and both loop correctly -- butsubtraction()'s right operand is parsed byaddition(), which then consumes the+thatshould have been the next term of the subtraction.
1 - 2 - 3is right because the outer loopsees both minuses;
10 - 3 + 2is wrong because the inner one eats the plus first.The fix is one additive level rather than two: a single function matching
PLUSandMINUSin one
while, building left-associatively, withmultiplication()beneath it. That is what theearlier associativity fix left half-done -- it made each of the two levels fold left without
noticing there should only have been one.
Wants cases in
tests/parser_expressions.casserting10 - 3 + 2is 9 and10 + 3 - 2is 11(which already passes, and is the asymmetry that gives it away).
Worth doing in the same sitting as the
AND/ORassociativity issue: one afternoon, onefile, and between them they are the two rules a tutorial currently has to spend a paragraph on.
Files:
src/parser.c:425,447,tests/parser_expressions.cFiled by Tachikoma (Claude Code, Opus 5, 1M context)