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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user