WIP: multi-pass setup
authorLukas Krickl <lukas@krickl.dev>
Wed, 29 Nov 2023 13:05:25 +0000 (14:05 +0100)
committerLukas Krickl <lukas@krickl.dev>
Wed, 29 Nov 2023 13:05:25 +0000 (14:05 +0100)
include/ulas.h
src/test.c
src/ulas.c

index 806fde6b031bb14cad779882feba6289461272f5..ad09376ada1b660df4ac68dca23eb06959945537 100644 (file)
@@ -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
index 546c3b9317485874a4e889bb89d3e9f392a025cc..d5e2bd987141e7c15428e3bc8f0a25931412ba26 100644 (file)
@@ -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");                                  \
index 977e7584c541df64c3d34a8ef5cf38475c84ff61..62cf6529aef35f527da87787243d1322727e5810 100644 (file)
@@ -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: