diff --git a/include/asm/fstack.h b/include/asm/fstack.h index cef562ff..8a029eb1 100644 --- a/include/asm/fstack.h +++ b/include/asm/fstack.h @@ -73,7 +73,7 @@ bool yywrap(void); void fstk_RunInclude(char const *path); void fstk_RunMacro(char const *macroName, struct MacroArgs *args); void fstk_RunRept(uint32_t count, int32_t nReptLineNo, char *body, size_t size); -void fstk_RunForeach(char const *symName, int32_t start, int32_t stop, int32_t step, +void fstk_RunFor(char const *symName, int32_t start, int32_t stop, int32_t step, int32_t reptLineNo, char *body, size_t size); void fstk_Init(char const *mainPath, size_t maxRecursionDepth); diff --git a/src/asm/fstack.c b/src/asm/fstack.c index 5d5f1512..6e0fcac2 100644 --- a/src/asm/fstack.c +++ b/src/asm/fstack.c @@ -34,9 +34,9 @@ struct Context { uint32_t uniqueID; struct MacroArgs *macroArgs; /* Macro args are *saved* here */ uint32_t nbReptIters; - int32_t foreachValue; - int32_t foreachStep; - char *foreachName; + int32_t forValue; + int32_t forStep; + char *forName; }; static struct Context *contextStack; @@ -220,14 +220,14 @@ bool yywrap(void) } fileInfo->iters[0]++; - /* If this is a FOREACH, update the symbol value */ - if (contextStack->foreachName) { - contextStack->foreachValue += contextStack->foreachStep; - struct Symbol *sym = sym_AddSet(contextStack->foreachName, - contextStack->foreachValue); + /* If this is a FOR, update the symbol value */ + if (contextStack->forName) { + contextStack->forValue += contextStack->forStep; + struct Symbol *sym = sym_AddSet(contextStack->forName, + contextStack->forValue); if (sym->type != SYM_SET) - fatalerror("Failed to update FOREACH symbol value\n"); + fatalerror("Failed to update FOR symbol value\n"); } /* If this wasn't the last iteration, wrap instead of popping */ if (fileInfo->iters[0] <= contextStack->nbReptIters) { @@ -254,8 +254,8 @@ bool yywrap(void) /* Free the file stack node */ if (!context->fileInfo->referenced) free(context->fileInfo); - /* Free the FOREACH symbol name */ - free(context->foreachName); + /* Free the FOR symbol name */ + free(context->forName); /* Free the entry and make its parent the current entry */ free(context); @@ -281,7 +281,7 @@ static void newContext(struct FileStackNode *fileInfo) fileInfo->referenced = false; fileInfo->lineNo = lexer_GetLineNo(); context->fileInfo = fileInfo; - context->foreachName = NULL; + context->forName = NULL; /* * Link new entry to its parent so it's reachable later * ERRORS SHOULD NOT OCCUR AFTER THIS!! @@ -443,13 +443,13 @@ void fstk_RunRept(uint32_t count, int32_t reptLineNo, char *body, size_t size) return; contextStack->nbReptIters = count; - contextStack->foreachName = NULL; + contextStack->forName = NULL; } -void fstk_RunForeach(char const *symName, int32_t start, int32_t stop, int32_t step, +void fstk_RunFor(char const *symName, int32_t start, int32_t stop, int32_t step, int32_t reptLineNo, char *body, size_t size) { - dbgPrint("Running FOREACH(\"%s\", %" PRId32 ", %" PRId32 ", %" PRId32 ")\n", + dbgPrint("Running FOR(\"%s\", %" PRId32 ", %" PRId32 ", %" PRId32 ")\n", symName, start, stop, step); struct Symbol *sym = sym_AddSet(symName, start); @@ -464,7 +464,7 @@ void fstk_RunForeach(char const *symName, int32_t start, int32_t stop, int32_t s else if (step < 0 && stop < start) count = (start - stop - 1) / -step + 1; else if (step == 0) - error("FOREACH cannot have a step value of 0\n"); + error("FOR cannot have a step value of 0\n"); if (count == 0) return; @@ -472,11 +472,11 @@ void fstk_RunForeach(char const *symName, int32_t start, int32_t stop, int32_t s return; contextStack->nbReptIters = count; - contextStack->foreachValue = start; - contextStack->foreachStep = step; - contextStack->foreachName = strdup(symName); - if (!contextStack->foreachName) - fatalerror("Not enough memory for FOREACH name: %s\n", strerror(errno)); + contextStack->forValue = start; + contextStack->forStep = step; + contextStack->forName = strdup(symName); + if (!contextStack->forName) + fatalerror("Not enough memory for FOR symbol name: %s\n", strerror(errno)); } void fstk_Init(char const *mainPath, size_t maxRecursionDepth) @@ -508,9 +508,9 @@ void fstk_Init(char const *mainPath, size_t maxRecursionDepth) context->uniqueID = 0; macro_SetUniqueID(0); context->nbReptIters = 0; - context->foreachValue = 0; - context->foreachStep = 0; - context->foreachName = NULL; + context->forValue = 0; + context->forStep = 0; + context->forName = NULL; /* Now that it's set up properly, register the context */ contextStack = context; diff --git a/src/asm/lexer.c b/src/asm/lexer.c index e846fd07..7edaee7a 100644 --- a/src/asm/lexer.c +++ b/src/asm/lexer.c @@ -240,7 +240,7 @@ static struct KeywordMapping { {"SHIFT", T_POP_SHIFT}, {"REPT", T_POP_REPT}, - {"FOREACH", T_POP_FOREACH}, + {"FOR", T_POP_FOR}, {"ENDR", T_POP_ENDR}, {"LOAD", T_POP_LOAD}, @@ -462,7 +462,7 @@ struct LexerState *lexer_OpenFileView(char *buf, size_t size, uint32_t lineNo) void lexer_RestartRept(uint32_t lineNo) { - dbgPrint("Restarting REPT/FOREACH\n"); + dbgPrint("Restarting REPT/FOR\n"); lexerState->offset = 0; initState(lexerState); lexerState->lineNo = lineNo; @@ -2123,11 +2123,11 @@ void lexer_CaptureRept(char **capture, size_t *size) do { /* Discard initial whitespace */ c = nextChar(); } while (isWhitespace(c)); - /* Now, try to match `REPT`, `FOREACH` or `ENDR` as a **whole** identifier */ + /* Now, try to match `REPT`, `FOR` or `ENDR` as a **whole** identifier */ if (startsIdentifier(c)) { switch (readIdentifier(c)) { case T_POP_REPT: - case T_POP_FOREACH: + case T_POP_FOR: level++; /* Ignore the rest of that line */ break; @@ -2156,7 +2156,7 @@ void lexer_CaptureRept(char **capture, size_t *size) /* Just consume characters until EOL or EOF */ for (;;) { if (c == EOF) { - error("Unterminated REPT/FOREACH block\n"); + error("Unterminated REPT/FOR block\n"); lexerState->capturing = false; goto finish; } else if (c == '\n' || c == '\r') { diff --git a/src/asm/parser.y b/src/asm/parser.y index ab39178a..d62524fe 100644 --- a/src/asm/parser.y +++ b/src/asm/parser.y @@ -310,7 +310,7 @@ static inline void failAssertMsg(enum AssertionType type, char const *msg) int32_t start; int32_t stop; int32_t step; - } foreachArgs; + } forArgs; struct StrFmtArgList strfmtArgs; } @@ -406,7 +406,7 @@ static inline void failAssertMsg(enum AssertionType type, char const *msg) %token T_POP_ENDM %token T_POP_RSRESET T_POP_RSSET %token T_POP_UNION T_POP_NEXTU T_POP_ENDU -%token T_POP_INCBIN T_POP_REPT T_POP_FOREACH +%token T_POP_INCBIN T_POP_REPT T_POP_FOR %token T_POP_CHARMAP %token T_POP_NEWCHARMAP %token T_POP_SETCHARMAP @@ -431,7 +431,7 @@ static inline void failAssertMsg(enum AssertionType type, char const *msg) %type sectmod %type macroargs -%type foreach_args +%type for_args %token T_Z80_ADC T_Z80_ADD T_Z80_AND %token T_Z80_BIT @@ -634,7 +634,7 @@ simple_pseudoop : include | popc | load | rept - | foreach + | for | shift | fail | warn @@ -758,15 +758,15 @@ rept : T_POP_REPT uconst { } ; -foreach : T_POP_FOREACH T_ID T_COMMA foreach_args { +for : T_POP_FOR T_ID T_COMMA for_args { uint32_t nDefinitionLineNo = lexer_GetLineNo(); char *body; size_t size; lexer_CaptureRept(&body, &size); - fstk_RunForeach($2, $4.start, $4.stop, $4.step, nDefinitionLineNo, body, size); + fstk_RunFor($2, $4.start, $4.stop, $4.step, nDefinitionLineNo, body, size); } -foreach_args : const { +for_args : const { $$.start = 0; $$.stop = $1; $$.step = 1; diff --git a/src/asm/rgbasm.5 b/src/asm/rgbasm.5 index ca1b947d..2ebebf3b 100644 --- a/src/asm/rgbasm.5 +++ b/src/asm/rgbasm.5 @@ -1533,18 +1533,18 @@ As in macros, you can also use the escape sequence blocks can be nested. .Pp A common pattern is to repeat a block for each value in some range. -.Ic FOREACH +.Ic FOR is simpler than .Ic REPT for that purpose. Everything between -.Ic FOREACH +.Ic FOR and the matching .Ic ENDR will be repeated for each value of a given symbol. For example, this code will produce a table of squared values from 0 to 255: .Bd -literal -offset indent -FOREACH N, 256 +FOR N, 256 dw N * N ENDR .Ed @@ -1564,24 +1564,24 @@ N = 256 .Ed .Pp You can customize the range of -.Ic FOREACH +.Ic FOR values: -.Bl -column "FOREACH V, start, stop, step" +.Bl -column "FOR V, start, stop, step" .It Sy Code Ta Sy Range -.It Ic FOREACH Ar V , stop Ta Ar V No increments from 0 to Ar stop No -.It Ic FOREACH Ar V , start , stop Ta Ar V No increments from Ar start No to Ar stop No -.It Ic FOREACH Ar V , start , stop , step Ta Ar V No goes from Ar start No to Ar stop No by Ar step No +.It Ic FOR Ar V , stop Ta Ar V No increments from 0 to Ar stop No +.It Ic FOR Ar V , start , stop Ta Ar V No increments from Ar start No to Ar stop No +.It Ic FOR Ar V , start , stop , step Ta Ar V No goes from Ar start No to Ar stop No by Ar step No .El .Pp The -.Ic FOREACH +.Ic FOR value will be updated by .Ar step until it reaches or exceeds .Ar stop. For example: .Bd -literal -offset indent -FOREACH V, 4, 25, 5 +FOR V, 4, 25, 5 PRINTT "{d:V} " ENDR PRINTT "done {d:V}\n" @@ -1596,7 +1596,7 @@ Just like with blocks, you can use the escape sequence .Ic \[rs]@ inside of -.Ic FOREACH +.Ic FOR blocks, and they can be nested. .Ss Aborting the assembly process .Ic FAIL diff --git a/test/asm/foreach.asm b/test/asm/for.asm similarity index 73% rename from test/asm/foreach.asm rename to test/asm/for.asm index d4028b1e..e51b4d0d 100644 --- a/test/asm/foreach.asm +++ b/test/asm/for.asm @@ -1,44 +1,44 @@ -foreach n, 10 +for n, 10 printt "{d:n} " endr printt "-> {d:n}\n" -foreach v, 0 +for v, 0 printt "unreached" endr -foreach v, 2, 1 +for v, 2, 1 printt "unreached" endr -foreach v, 1, 2, 0 +for v, 1, 2, 0 printt "unreached" endr -foreach x, 1, 5+1 +for x, 1, 5+1 printt "{d:x} " endr printt "-> {d:x}\n" -foreach v, 10, -1, -1 +for v, 10, -1, -1 printt "{d:v} " v = 42 endr printt "-> {d:v}\n" -foreach q, 5, 21, 5 +for q, 5, 21, 5 printt "{d:q} " purge q endr printt "-> {d:q}\n" s EQUS "x" -foreach s, 3, 30, 3 +for s, 3, 30, 3 printt "{d:x} " endr printt "-> {d:x}\n" -foreach v, 10 +for v, 10 printt "{d:v}\n" if v == 3 purge v diff --git a/test/asm/for.err b/test/asm/for.err new file mode 100644 index 00000000..4a48d9d5 --- /dev/null +++ b/test/asm/for.err @@ -0,0 +1,6 @@ +ERROR: for.asm(16): + FOR cannot have a step value of 0 +ERROR: for.asm(41) -> for.asm::REPT~5(47): + 'v' already defined as constant at for.asm(41) -> for.asm::REPT~4(45) +FATAL: for.asm(41) -> for.asm::REPT~5(47): + Failed to update FOR symbol value diff --git a/test/asm/foreach.out b/test/asm/for.out similarity index 100% rename from test/asm/foreach.out rename to test/asm/for.out diff --git a/test/asm/foreach.err b/test/asm/foreach.err deleted file mode 100644 index 5f27ecda..00000000 --- a/test/asm/foreach.err +++ /dev/null @@ -1,6 +0,0 @@ -ERROR: foreach.asm(16): - FOREACH cannot have a step value of 0 -ERROR: foreach.asm(41) -> foreach.asm::REPT~5(47): - 'v' already defined as constant at foreach.asm(41) -> foreach.asm::REPT~4(45) -FATAL: foreach.asm(41) -> foreach.asm::REPT~5(47): - Failed to update FOREACH symbol value