Added .def and .set
authorLukas Krickl <lukas@krickl.dev>
Mon, 4 Dec 2023 14:22:51 +0000 (15:22 +0100)
committerLukas Krickl <lukas@krickl.dev>
Mon, 4 Dec 2023 14:22:51 +0000 (15:22 +0100)
include/ulas.h
src/ulas.c
tests/t0.bin
tests/t0.s

index c078a04d9e46a5df6413963176c1ba4704129852..7364b3942954e4f87b8260286255b35fefca11e0 100644 (file)
@@ -41,6 +41,7 @@
 #define ULAS_ASMSTR_FILL ".fill"
 #define ULAS_ASMSTR_PAD ".pad"
 #define ULAS_ASMSTR_INCBIN ".incbin"
+#define ULAS_ASMSTR_DEF ".def"
 
 // configurable tokens
 #define ULAS_TOK_COMMENT ';'
@@ -327,7 +328,7 @@ enum ulas_asmdir {
   ULAS_ASMDIR_NONE = 0,
   // .org <address>
   ULAS_ASMDIR_ORG,
-  // .set name = <expr>
+  // .set <type> name = <expr>
   ULAS_ASMDIR_SET,
   // .byte <expr>, <expr>, <expr>, ...
   ULAS_ASMDIR_BYTE,
@@ -339,6 +340,8 @@ enum ulas_asmdir {
   ULAS_ASMDIR_PAD,
   // .incbin <filename>
   ULAS_ASMDIR_INCBIN,
+  // .def name = value
+  ULAS_ASMDIR_DEF,
 };
 
 // amount of registers
index 9f2aaa21175f6436b02da0838299b2b164c44f85..5eef3c29f3e4a1ebb2a4d8eeb8aa6177ec1c4484 100644 (file)
@@ -2039,21 +2039,8 @@ int ulas_asmdirbyte(FILE *dst, const char *line, unsigned long n) {
   return 0;
 }
 
-int ulas_asmdirset(const char **line, unsigned long n) {
-  // .set <str,int> = name expr
+int ulas_asmdirset(const char **line, unsigned long n, enum ulas_type t) {
   char name[ULAS_SYMNAMEMAX];
-
-  ulas_tok(&ulas.tok, line, n);
-  enum ulas_type t = ULAS_INT;
-  if (strncmp(ulas.tok.buf, "int", ulas.tok.maxlen) == 0) {
-    t = ULAS_INT;
-  } else if (strncmp(ulas.tok.buf, "char", ulas.tok.maxlen) == 0) {
-    t = ULAS_STR;
-  } else {
-    ULASERR("Type (str,int) expected. Got '%s'\n", ulas.tok.buf);
-    return -1;
-  }
-
   ulas_tok(&ulas.tok, line, n);
   if (!ulas_isname(ulas.tok.buf, ulas.tok.maxlen)) {
     ULASERR("Unexpected token '%s'\n", ulas.tok.buf);
@@ -2094,6 +2081,46 @@ fail:
   return rc;
 }
 
+int ulas_asmdirset_lookup(const char **line, unsigned long n) {
+  if (ulas.pass != ULAS_PASS_FINAL) {
+    *line += strlen(*line);
+    return 0;
+  }
+  const char *start = *line;
+  ulas_tok(&ulas.tok, line, n);
+
+  int rc = 0;
+  struct ulas_sym *found = ulas_symbolresolve(ulas.tok.buf, -1, &rc);
+
+  if (rc == -1 || !found) {
+    ULASERR("Unable to set symbol '%s'\n", ulas.tok.buf);
+    return -1;
+  }
+
+  enum ulas_type t = found->tok.type;
+
+  *line = start;
+
+  return ulas_asmdirset(line, n, t);
+}
+
+int ulas_asmdirdef(const char **line, unsigned long n) {
+  // .set <str,int> = name expr
+
+  ulas_tok(&ulas.tok, line, n);
+  enum ulas_type t = ULAS_INT;
+  if (strncmp(ulas.tok.buf, "int", ulas.tok.maxlen) == 0) {
+    t = ULAS_INT;
+  } else if (strncmp(ulas.tok.buf, "char", ulas.tok.maxlen) == 0) {
+    t = ULAS_STR;
+  } else {
+    ULASERR("Type (str,int) expected. Got '%s'\n", ulas.tok.buf);
+    return -1;
+  }
+
+  return ulas_asmdirset(line, n, t);
+}
+
 int ulas_asmline(FILE *dst, FILE *src, const char *line, unsigned long n) {
   // this buffer is written both to dst and to verbose output
   char outbuf[ULAS_OUTBUFMAX];
@@ -2114,11 +2141,12 @@ int ulas_asmline(FILE *dst, FILE *src, const char *line, unsigned long n) {
 
   if (ulas.tok.buf[0] == ULAS_TOK_ASMDIR_BEGIN) {
     const char *dirstrs[] = {
-        ULAS_ASMSTR_ORG,  ULAS_ASMSTR_SET, ULAS_ASMSTR_BYTE,   ULAS_ASMSTR_STR,
-        ULAS_ASMSTR_FILL, ULAS_ASMSTR_PAD, ULAS_ASMSTR_INCBIN, NULL};
+        ULAS_ASMSTR_ORG,    ULAS_ASMSTR_SET,  ULAS_ASMSTR_BYTE,
+        ULAS_ASMSTR_STR,    ULAS_ASMSTR_FILL, ULAS_ASMSTR_PAD,
+        ULAS_ASMSTR_INCBIN, ULAS_ASMSTR_DEF,  NULL};
     enum ulas_asmdir dirs[] = {
-        ULAS_ASMDIR_ORG,  ULAS_ASMDIR_SET, ULAS_ASMDIR_BYTE,  ULAS_ASMDIR_STR,
-        ULAS_ASMDIR_FILL, ULAS_ASMDIR_PAD, ULAS_ASMDIR_INCBIN};
+        ULAS_ASMDIR_ORG,  ULAS_ASMDIR_SET, ULAS_ASMDIR_BYTE,   ULAS_ASMDIR_STR,
+        ULAS_ASMDIR_FILL, ULAS_ASMDIR_PAD, ULAS_ASMDIR_INCBIN, ULAS_ASMDIR_DEF};
 
     enum ulas_asmdir dir = ULAS_ASMDIR_NONE;
 
@@ -2140,9 +2168,12 @@ int ulas_asmline(FILE *dst, FILE *src, const char *line, unsigned long n) {
     case ULAS_ASMDIR_ORG:
       ulas.address = ulas_intexpr(&line, strnlen(start, n), &rc);
       break;
-    case ULAS_ASMDIR_SET:
+    case ULAS_ASMDIR_DEF:
       // only do this in the final pass
-      rc = ulas_asmdirset(&line, n);
+      rc = ulas_asmdirdef(&line, n);
+      break;
+    case ULAS_ASMDIR_SET:
+      rc = ulas_asmdirset_lookup(&line, n);
       break;
     case ULAS_ASMDIR_BYTE:
     case ULAS_ASMDIR_STR:
index 739357a260773e6b2129410b5613072d852fe917..29abba46eeac06c8b0823cd607569cb75d53ae96 100644 (file)
Binary files a/tests/t0.bin and b/tests/t0.bin differ
index 5de1ad5a669b7ced129956804ed212ff274d3c68..b64a432de30079da56abbc861780020a86bcdae9 100644 (file)
@@ -81,5 +81,7 @@ l2:
   ld bc, $
   jr z, $ - l2
 
-.set int s1 = 1 + 2
+.def int s1 = 1 + 2
+  ld a, s1
+.set s1 = 4
   ld a, s1