WIP: multi-pass symbol resolver
authorLukas Krickl <lukas@krickl.dev>
Tue, 28 Nov 2023 04:35:43 +0000 (05:35 +0100)
committerLukas Krickl <lukas@krickl.dev>
Tue, 28 Nov 2023 04:35:43 +0000 (05:35 +0100)
include/ulas.h
src/ulas.c

index 35773e25f798680bbf7422274a13bf750d85d591..d26dab27a3a54148355cdee92727a59ed43910ce 100644 (file)
@@ -154,8 +154,6 @@ struct ulas_exprbuf {
 
 enum ulas_syms { ULAS_SYM_FORWARD, ULAS_SYM_DECL };
 
-enum ulas_symres { ULAS_EGLOBALUNRESOLVE = 1, ULAS_ELOCALUNRESOLVE = 2 };
-
 struct ulas_sym {
   char *name;
   struct ulas_tok tok;
@@ -173,10 +171,18 @@ struct ulas_symbuf {
  * Assembly context
  */
 
+enum ulas_pass {
+  ULAS_PASS_FINAL = 0,
+  ULAS_PASS_RESOLVE = 1,
+};
+
 struct ulas {
   char *filename;
   unsigned long line;
 
+  // count how many passes we have completed so far
+  int pass;
+
   // holds the current token
   struct ulas_str tok;
 
@@ -384,8 +390,7 @@ char *ulas_strndup(const char *src, unsigned long n);
 // returns -1 if any flagged symbol was not found
 // if flagged symbols remain unresolved (e.g. global or locals) rc is set to the
 // respective flag value
-struct ulas_tok *ulas_symbolresolve(const char *name, enum ulas_symres flags,
-                                    int *rc);
+struct ulas_tok *ulas_symbolresolve(const char *name, int *rc);
 
 // tokenisze according to pre-defined rules
 // returns the amount of bytes of line that were
@@ -463,9 +468,9 @@ char *ulas_preprocexpand(struct ulas_preproc *pp, const char *raw_line,
 
 // convert literal to its int value
 // retunrs -1 on error, 0 on success and 1 if there is an unresolved symbol
-int ulas_valint(struct ulas_tok *lit, enum ulas_symres flags, int *rc);
+int ulas_valint(struct ulas_tok *lit, int *rc);
 // convert literal to its char value
-char *ulas_valstr(struct ulas_tok *lit, enum ulas_symres flags, int *rc);
+char *ulas_valstr(struct ulas_tok *lit, int *rc);
 
 struct ulas_tokbuf ulas_tokbuf(void);
 
index 33a874b64d64bda909e16a015cca79d6e4643c02..b764ffc3e95e85c4e2896ba352727964cde4c84d 100644 (file)
@@ -163,8 +163,7 @@ int ulas_isname(const char *tok, unsigned long n) {
   return 1;
 }
 
-struct ulas_tok *ulas_symbolresolve(const char *name, enum ulas_symres flags,
-                                    int *rc) {
+struct ulas_tok *ulas_symbolresolve(const char *name, int *rc) {
   // TODO: implement
   return NULL;
 }
@@ -934,14 +933,14 @@ fail:
  * Literals, tokens and expressions
  */
 
-int ulas_valint(struct ulas_tok *lit, enum ulas_symres flags, int *rc) {
+int ulas_valint(struct ulas_tok *lit, int *rc) {
   if (lit->type == ULAS_SYMBOL) {
-    struct ulas_tok *stok = ulas_symbolresolve(lit->val.strv, flags, rc);
+    struct ulas_tok *stok = ulas_symbolresolve(lit->val.strv, rc);
     // bail if symbol is not resolvable
     if (*rc > 0) {
       return 0;
     }
-    return ulas_valint(stok, flags, rc);
+    return ulas_valint(stok, rc);
   }
 
   if (!lit || lit->type != ULAS_INT) {
@@ -953,7 +952,7 @@ int ulas_valint(struct ulas_tok *lit, enum ulas_symres flags, int *rc) {
   return lit->val.intv;
 }
 
-char *ulas_valstr(struct ulas_tok *lit, enum ulas_symres flags, int *rc) {
+char *ulas_valstr(struct ulas_tok *lit, int *rc) {
   if (!lit || lit->type != ULAS_STR) {
     ULASERR("Expected str\n");
     *rc = -1;
@@ -1387,7 +1386,7 @@ int ulas_intexpreval(int i, int *rc) {
   }
   case ULAS_EXPPRIM: {
     struct ulas_tok *t = ulas_tokbufget(&ulas.toks, (int)e->val.prim.tok);
-    return ulas_valint(t, 0, rc);
+    return ulas_valint(t, rc);
   }
   }
 
@@ -1978,12 +1977,6 @@ int ulas_asmline(FILE *dst, FILE *src, const char *line, unsigned long n) {
       goto fail;
     }
     towrite += nextwrite;
-
-    // TODO:
-    // place marker when a label was unresolved
-    // write down byte location in dst as well as the byte offset in lstout so
-    // we can fix them later labels can only be unresolved when they are the
-    // only node in an expression!
   }
 
   // check for trailing
@@ -1995,8 +1988,11 @@ int ulas_asmline(FILE *dst, FILE *src, const char *line, unsigned long n) {
     }
   }
 
-  ulas_asmout(dst, outbuf, towrite);
-  ulas_asmlst(start, outbuf, towrite);
+  // only write to dst on final pass
+  if (ulas.pass == ULAS_PASS_FINAL) {
+    ulas_asmout(dst, outbuf, towrite);
+    ulas_asmlst(start, outbuf, towrite);
+  }
   ulas.address += towrite;
 
 fail: