Give argument lists their own link, not each argument's .right

An identifier's subscript list, a unary's operand and a binary's right-hand
side all lived in the same field the argument chain used, so ABS(-9),
MOD(A#, B# + 12) and any array reference in a parameter list were counted as
extra arguments and refused. Subscript lists move to .expr and arguments now
chain through a dedicated .next.

This is the third time the same collision was fixed; the first two moved it
along rather than removing it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-31 11:58:15 -04:00
parent 5b7b7d2ed9
commit f4007d80d4
14 changed files with 133 additions and 55 deletions

View File

@@ -106,6 +106,26 @@ typedef struct akbasic_ASTLeaf
struct akbasic_ASTLeaf *left;
struct akbasic_ASTLeaf *right;
struct akbasic_ASTLeaf *expr;
/**
* The next argument or subscript in a list, and nothing else.
*
* **This field exists because reusing `.right` for it was a bug.** The
* reference chains an argument list through each argument's `.right`
* (`basicparser.go`'s argumentList), which is also where a unary leaf keeps
* its operand, where a binary leaf keeps its right-hand side, and where an
* identifier used to keep its subscript list. The three meanings were
* indistinguishable, and every one of them produced a wrong answer:
*
* ABS(-9) counted as two arguments, refused
* MOD(A#, B# + 12) counted as three, refused
* MOD(-7, 3) the second argument overwrote the first's operand
*
* -- TODO.md section 6 item 13, and the "array references in parameter
* lists" item in section 4, which turned out to be the same defect twice.
* An argument list's *head* is still the list leaf's `.right`; only the
* sibling chain moved here.
*/
struct akbasic_ASTLeaf *next;
} akbasic_ASTLeaf;
/**