From: Lukas Krickl Date: Fri, 11 Jul 2025 04:53:24 +0000 (+0200) Subject: BUG: Fixed macro expansion bug that consumed new lines in nested macros X-Git-Url: https://git.krickl.dev/?a=commitdiff_plain;h=57fea9be9f1299c769582a948a0b8d8cf061d005;p=ulas%2F.git BUG: Fixed macro expansion bug that consumed new lines in nested macros This was fixed by simply appending new lines to the start of the expansion list when a nested macro is used. This is not an ideal fix. The root cause of the macro going missing surely is in another place, however this is a decent enough solution for now. If the root cause of new lines being dropped in this case this commit should be reverted. --- diff --git a/BUGS.md b/BUGS.md index 23564d6..5eb8751 100644 --- a/BUGS.md +++ b/BUGS.md @@ -1,22 +1,5 @@ # Known Bugs -## Nested macros break if a macro expansion is used - -e.g. - -``` -#macro macro1 - nop - other_macro -#endmacro - -#macro other_macro - nop -#endmacro -``` - -This seems to be caused by the new line after the initial line (ld a, $1) being eaten. This likely happens during `pp_proc` that is applied to the already expanded macro. - ## .scc ' ' does not work `.scc ' ' = 100` results in an error. The expected result is for it to re-map the space character. diff --git a/src/test.c b/src/test.c index 6ee4b61..0fa1c23 100644 --- a/src/test.c +++ b/src/test.c @@ -126,7 +126,7 @@ void test_preproc(void) { "#macro mtest\ntest macro with no args\n#endmacro\nmtest"); assert_preproc("", -1, "#macro test\n not terminated\n"); assert_preproc( - "content macro t1\nt1\nafter\ncontent n1\n", 0, + "\ncontent macro t1\nt1\nafter\ncontent n1\n", 0, "#macro test\nmnested macro $1\n$1\n#macro " "mnested\ncontent $1\n#endmacro\nafter\nmnested n1\n#endmacro\ntest t1"); diff --git a/src/ulas.c b/src/ulas.c index 40e6aca..127456a 100644 --- a/src/ulas.c +++ b/src/ulas.c @@ -848,6 +848,8 @@ void ulas_trimend(char c, char *buf, unsigned long n) { } } +char *ulas_preprocexpand2(struct ulas_preproc *pp, const char *raw_line, + unsigned long *n, int recursive); void ulas_preprocexpand_rec(struct ulas_preproc *pp) { // expand macro result again to allow // defines to appear in the macro @@ -859,12 +861,17 @@ void ulas_preprocexpand_rec(struct ulas_preproc *pp) { ULASERR("Max macro recursion depth reached\n"); return; } - ulas_preprocexpand(pp, pp->line2.buf, &n); + ulas_preprocexpand2(pp, pp->line2.buf, &n, 1); pp->exp_depth--; } char *ulas_preprocexpand(struct ulas_preproc *pp, const char *raw_line, unsigned long *n) { + return ulas_preprocexpand2(pp, raw_line, n, 0); +} + +char *ulas_preprocexpand2(struct ulas_preproc *pp, const char *raw_line, + unsigned long *n, int recursive) { const char *praw_line = raw_line; memset(pp->line.buf, 0, pp->line.maxlen); @@ -968,6 +975,17 @@ char *ulas_preprocexpand(struct ulas_preproc *pp, const char *raw_line, const char *tocat = NULL; unsigned long tocatlen = 0; + // always start an expanded macro with a new line + // to ensure expansion are separated if we are in a recursive call + // this fixes new lines in recursive macros being consumed + if (recursive) { + int len = strnlen(pp->line.buf, pp->line.maxlen) + 1; + ulas_strensr(&pp->line, + len + 1); + strncat(pp->line.buf, "\n", len); + } + + // now tokenize the macro's value and look for $0-$9 // and replace those instances // eveyrthing else will just be copied as is diff --git a/tests/t0.bin b/tests/t0.bin index d41e184..782f7d1 100644 Binary files a/tests/t0.bin and b/tests/t0.bin differ diff --git a/tests/t0.s b/tests/t0.s index 04c14b8..fe556b6 100644 --- a/tests/t0.s +++ b/tests/t0.s @@ -212,3 +212,13 @@ test_scoped: defarg2 DEFARG * arg_p, arg_p +#macro nopnest1 + nop + nopnest2 +#endmacro + +#macro nopnest2 + nop +#endmacro + +nopnest1 diff --git a/tests/t0_dasm.s b/tests/t0_dasm.s index 4191bb5..47f15d2 100644 --- a/tests/t0_dasm.s +++ b/tests/t0_dasm.s @@ -134,4 +134,6 @@ nop inc bc ld [bc], a -.db 0x2 + ld [bc], a + nop +.db 0x0