Implement FOREACH (#658)

This acts like `REPT` with a variable automatically
incremented across a range of values

Fixes #432
This commit is contained in:
Rangi
2020-12-29 15:30:42 -05:00
committed by GitHub
parent 3690546795
commit 6874f694e5
8 changed files with 239 additions and 14 deletions

View File

@@ -205,6 +205,11 @@ static inline void failAssertMsg(enum AssertionType type, char const *msg)
struct SectionSpec sectSpec;
struct MacroArgs *macroArg;
enum AssertionType assertType;
struct {
int32_t start;
int32_t stop;
int32_t step;
} foreachArgs;
}
%type <sVal> relocexpr
@@ -296,7 +301,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
%token T_POP_INCBIN T_POP_REPT T_POP_FOREACH
%token T_POP_CHARMAP
%token T_POP_NEWCHARMAP
%token T_POP_SETCHARMAP
@@ -321,6 +326,8 @@ static inline void failAssertMsg(enum AssertionType type, char const *msg)
%type <sectMod> sectmod
%type <macroArg> macroargs
%type <foreachArgs> foreach_args
%token T_Z80_ADC T_Z80_ADD T_Z80_AND
%token T_Z80_BIT
%token T_Z80_CALL T_Z80_CCF T_Z80_CP T_Z80_CPL
@@ -522,6 +529,7 @@ simple_pseudoop : include
| popc
| load
| rept
| foreach
| shift
| fail
| warn
@@ -645,6 +653,31 @@ rept : T_POP_REPT uconst {
}
;
foreach : T_POP_FOREACH T_ID T_COMMA foreach_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);
}
foreach_args : const {
$$.start = 0;
$$.stop = $1;
$$.step = 1;
}
| const T_COMMA const {
$$.start = $1;
$$.stop = $3;
$$.step = 1;
}
| const T_COMMA const T_COMMA const {
$$.start = $1;
$$.stop = $3;
$$.step = $5;
}
;
macrodef : T_LABEL T_COLON T_POP_MACRO {
int32_t nDefinitionLineNo = lexer_GetLineNo();
char *body;