From ea3bb29ec39d5e8fc0530f4ff94e2351aba160f5 Mon Sep 17 00:00:00 2001 From: phobos2077 Date: Thu, 26 Feb 2026 23:03:54 +0100 Subject: [PATCH] Array Expressions: emit temp_array calls with special flags to signify begin/end of a sub-expression --- parse.c | 4 ++-- parseext.c | 60 +++++++++++++++++++++++++++++++++++------------------- parseext.h | 4 ++-- 3 files changed, 43 insertions(+), 25 deletions(-) diff --git a/parse.c b/parse.c index bd046d9..a1888e7 100644 --- a/parse.c +++ b/parse.c @@ -1126,10 +1126,10 @@ static void factor(Procedure *p, NodeList *nodes) { } break; case '[': - parseArrayConstant(p, nodes); + parseArrayExpression(p, nodes); break; case '{': - parseAssocArrayConstant(p, nodes); + parseAssocArrayExpression(p, nodes); break; default: parseLibExpression(p, nodes, i); diff --git a/parseext.c b/parseext.c index c6162c8..aa26c6c 100644 --- a/parseext.c +++ b/parseext.c @@ -10,6 +10,11 @@ extern int loopNesting; extern Program *currentProgram; +static int arrayExpressionNesting = 0; + +#define ARRAYFLAG_EXPR_PUSH (32) // is created as part of array sub-expression +#define ARRAYFLAG_EXPR_POP (64) // is used to indicate end of array sub-expression, not used in actual array + // vars, constants, etc. void emitNodeExpr(Procedure *p, NodeList *n, LexData *data) { emitOp(p, n, T_START_EXPRESSION); @@ -413,14 +418,25 @@ void parseSwitch(Procedure *p, NodeList *n) { if(expectToken(T_END)==-1) parseError("Expected end"); } -void parseAssocArrayConstant(Procedure *p, NodeList *n) { - emitOp(p, n, T_TS_TEMP_ARRAY); +static void emitIntConstIntExpr(Procedure *p, NodeList *n, int i) { emitOp(p, n, T_START_EXPRESSION); - emitInt(p, n, -1); - emitOp(p, n, T_END_EXPRESSION); - emitOp(p, n, T_START_EXPRESSION); - emitInt(p, n, 0); + emitInt(p, n, i); emitOp(p, n, T_END_EXPRESSION); +} + +static void emitSubExpressionTerminator(Procedure *p, NodeList *n) { + // Special temp_array call that will not actually create any array, but pop the internal expression stack for nested expressions to work properly + emitOp(p, n, T_TS_TEMP_ARRAY); + emitIntConstIntExpr(p, n, 0); + emitIntConstIntExpr(p, n, ARRAYFLAG_EXPR_POP); + emitOp(p, n, '+'); +} + +void parseAssocArrayExpression(Procedure *p, NodeList *n) { + arrayExpressionNesting++; + emitOp(p, n, T_TS_TEMP_ARRAY); + emitIntConstIntExpr(p, n, -1); + emitIntConstIntExpr(p, n, arrayExpressionNesting > 1 ? ARRAYFLAG_EXPR_PUSH : 0); if (lex() != '}') { ungetToken(); emitOp(p, n, T_TS_STACK_ARRAY); @@ -440,31 +456,30 @@ void parseAssocArrayConstant(Procedure *p, NodeList *n) { parseError("Mismatched '{}'"); } } - return; + if (arrayExpressionNesting > 1) { + emitSubExpressionTerminator(p, n); + } + arrayExpressionNesting--; } -void parseArrayConstant(Procedure *p, NodeList *n) { +void parseArrayExpression(Procedure *p, NodeList *n) { int i; + arrayExpressionNesting++; + emitOp(p, n, T_TS_TEMP_ARRAY); - for (i=0; i<2; i++) { - emitOp(p, n, T_START_EXPRESSION); - emitInt(p, n, 0); - emitOp(p, n, T_END_EXPRESSION); - } + emitIntConstIntExpr(p, n, 0); // size + emitIntConstIntExpr(p, n, arrayExpressionNesting > 1 ? ARRAYFLAG_EXPR_PUSH : 0); + if (lex() != ']') { ungetToken(); emitOp(p, n, T_TS_STACK_ARRAY); - emitOp(p, n, T_START_EXPRESSION); - emitInt(p, n, 0); - emitOp(p, n, T_END_EXPRESSION); + emitIntConstIntExpr(p, n, 0); // first index parseExpression(p, n); emitOp(p, n, '+'); - i=1; + i = 1; while (lex() == ',') { emitOp(p, n, T_TS_STACK_ARRAY); - emitOp(p, n, T_START_EXPRESSION); - emitInt(p, n, i); - emitOp(p, n, T_END_EXPRESSION); + emitIntConstIntExpr(p, n, i); // index parseExpression(p, n); emitOp(p, n, '+'); i++; @@ -474,5 +489,8 @@ void parseArrayConstant(Procedure *p, NodeList *n) { parseError("Mismatched '[]'"); } } - return; + if (arrayExpressionNesting > 1) { + emitSubExpressionTerminator(p, n); + } + arrayExpressionNesting--; } \ No newline at end of file diff --git a/parseext.h b/parseext.h index be4adfc..fde426e 100644 --- a/parseext.h +++ b/parseext.h @@ -13,7 +13,7 @@ void parseArrayAssignment(Procedure *p, NodeList *nodes, LexData symb); void parseFor(Procedure *p, NodeList *n); void parseForEach(Procedure *p, NodeList *n); void parseSwitch(Procedure *p, NodeList *n); -void parseAssocArrayConstant(Procedure *p, NodeList *n); -void parseArrayConstant(Procedure *p, NodeList *n); +void parseAssocArrayExpression(Procedure *p, NodeList *n); +void parseArrayExpression(Procedure *p, NodeList *n); #endif