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

@@ -308,15 +308,17 @@ static akerr_ErrorContext *evaluate_identifier(akbasic_Runtime *obj, akbasic_AST
int subscriptcount = 0;
/*
* A .right hanging off an identifier is an array subscript only when it is
* an ARRAY_SUBSCRIPT argument list; anything else belongs to the enclosing
* expression and must not be followed.
* An identifier's subscript list hangs off .expr, deliberately clear of
* .right -- which is where an argument list chains its arguments, and where
* INPUT's parse handler would otherwise collide with it. Checked for the
* ARRAY_SUBSCRIPT operator anyway, because .expr means something else on the
* leaf types that use it for grouping.
*/
texpr = expr->right;
texpr = expr->expr;
if ( texpr != NULL &&
texpr->leaftype == AKBASIC_LEAF_ARGUMENTLIST &&
texpr->operator_ == AKBASIC_TOK_ARRAY_SUBSCRIPT ) {
for ( texpr = texpr->right; texpr != NULL; texpr = texpr->right ) {
for ( texpr = texpr->right; texpr != NULL; texpr = texpr->next ) {
FAIL_ZERO_RETURN(errctx, (subscriptcount < AKBASIC_MAX_ARRAY_DEPTH),
AKBASIC_ERR_BOUNDS,
"More than %d array subscripts", AKBASIC_MAX_ARRAY_DEPTH);
@@ -611,8 +613,8 @@ akerr_ErrorContext *akbasic_runtime_user_function(akbasic_Runtime *obj, akbasic_
obj->environment = fndef->environment;
PASS(errctx, akbasic_environment_assign(fndef->environment, argptr, argvalue, &unused));
obj->environment = callerenv;
leafptr = leafptr->right;
argptr = argptr->right;
leafptr = leafptr->next;
argptr = argptr->next;
}
obj->environment = fndef->environment;