From: Lukas Krickl Date: Wed, 29 Nov 2023 13:05:25 +0000 (+0100) Subject: WIP: multi-pass setup X-Git-Url: https://git.krickl.dev/?a=commitdiff_plain;h=20a21e4c160c380eeef1fdd7f83fcbba522c4391;p=ulas%2F.git WIP: multi-pass setup --- diff --git a/include/ulas.h b/include/ulas.h index 806fde6..ad09376 100644 --- a/include/ulas.h +++ b/include/ulas.h @@ -152,7 +152,7 @@ struct ulas_exprbuf { * Symbols */ -enum ulas_syms { ULAS_SYM_LABEL, ULAS_SYM_DEF }; +enum ulas_syms { ULAS_SYM_LABEL, ULAS_SYM_SET }; struct ulas_sym { char *name; @@ -174,12 +174,14 @@ struct ulas_symbuf { */ enum ulas_pass { - ULAS_PASS_FINAL = 0, - ULAS_PASS_RESOLVE = 1, + ULAS_PASS_END = 0, + ULAS_PASS_FINAL = 1, + ULAS_PASS_RESOLVE = 2, }; struct ulas { char *filename; + char *initial_filename; unsigned long line; // count how many passes we have completed so far diff --git a/src/test.c b/src/test.c index 546c3b9..d5e2bd9 100644 --- a/src/test.c +++ b/src/test.c @@ -79,6 +79,7 @@ void test_strbuf(void) { #define assert_preproc(expect_dst, expect_ret, input) \ { \ + ulas.pass = ULAS_PASS_RESOLVE; \ char dstbuf[ULAS_LINEMAX]; \ memset(dstbuf, 0, ULAS_LINEMAX); \ FILE *src = fmemopen((input), strlen((input)), "re"); \ @@ -308,6 +309,7 @@ void test_asminstr(void) { printf("[source: %s; expect: %s]\n", in_path, expect_path); \ ulaslstout = stdout; \ struct ulas_config cfg = ulas_cfg_from_env(); \ + cfg.verbose = 1; \ char dstbuf[ULAS_FULLEN]; \ char expect[ULAS_FULLEN]; \ FILE *expectf = fopen(expect_path, "re"); \ diff --git a/src/ulas.c b/src/ulas.c index 977e758..62cf652 100644 --- a/src/ulas.c +++ b/src/ulas.c @@ -34,14 +34,22 @@ void ulas_init(struct ulas_config cfg) { if (cfg.argc) { ulas.filename = cfg.argv[0]; + ulas.initial_filename = cfg.argv[0]; } + ulas.pass = ULAS_PASS_FINAL; ulas.toks = ulas_tokbuf(); ulas.exprs = ulas_exprbuf(); ulas.syms = ulas_symbuf(); } -void ulas_nextpass(void) { ulas.scope = 0; } +void ulas_nextpass(void) { + ulas.scope = 0; + ulas.line = 0; + ulas.icntr = 0; + ulas.address = 0; + ulas.filename = ulas.initial_filename; +} void ulas_free(void) { ulas_strfree(&ulas.tok); @@ -111,9 +119,20 @@ int ulas_main(struct ulas_config cfg) { preprocdst = tmpfile(); } - if (ulas_preproc(preprocdst, ulasin) == -1) { - rc = -1; - goto cleanup; + ulas.pass = ULAS_PASS_RESOLVE; + while (ulas.pass > 0) { + ulas_nextpass(); + + if (ulascfg.verbose) { + fprintf(ulaserr, "[Pass %d]\n", ulas.pass); + } + + if (ulas_preproc(preprocdst, ulasin) == -1) { + rc = -1; + goto cleanup; + } + + ulas.pass -= 1; } if (cfg.preproc_only) { @@ -908,9 +927,7 @@ int ulas_preproc(FILE *dst, FILE *src) { // init struct ulas_preproc pp = ulas_preprocinit(); - ulas_nextpass(); - - long prevseek = 0; + long prevseek = ftell(asmsrc); // preproc while ((rc = ulas_preprocnext(&pp, dst, src, buf, ULAS_LINEMAX)) > 0) { if (ulascfg.preproc_only) { @@ -1890,7 +1907,8 @@ int ulas_asminstr(char *dst, unsigned long max, const char **line, } void ulas_asmlst(const char *line, const char *outbuf, unsigned long n) { - if (ulaslstout) { + // only write to dst on final pass + if (ulaslstout && ulas.pass == ULAS_PASS_FINAL) { fprintf(ulaslstout, "%08X", ulas.address); // always pad at least n bytes @@ -1911,7 +1929,10 @@ void ulas_asmlst(const char *line, const char *outbuf, unsigned long n) { } void ulas_asmout(FILE *dst, const char *outbuf, unsigned long n) { - fwrite(outbuf, 1, n, dst); + // only write to dst on final pass + if (ulas.pass == ULAS_PASS_FINAL) { + fwrite(outbuf, 1, n, dst); + } } int ulas_asmline(FILE *dst, FILE *src, const char *line, unsigned long n) { @@ -1996,11 +2017,9 @@ int ulas_asmline(FILE *dst, FILE *src, const char *line, unsigned long n) { } } - // only write to dst on final pass - if (ulas.pass == ULAS_PASS_FINAL) { - ulas_asmout(dst, outbuf, towrite); - ulas_asmlst(start, outbuf, towrite); - } + ulas_asmout(dst, outbuf, towrite); + ulas_asmlst(start, outbuf, towrite); + ulas.address += towrite; fail: