Added unnamed labels
authorLukas Krickl <lukas@krickl.dev>
Wed, 28 Feb 2024 09:45:23 +0000 (10:45 +0100)
committerLukas Krickl <lukas@krickl.dev>
Wed, 28 Feb 2024 09:45:23 +0000 (10:45 +0100)
Unnamed labels can be declared using just a :.
Unnamed labels ignore redefinition rules and
just get added to the symbol list regardless.
They currently only serve as markers, however in the future they can be
reached using + and - symbols to jump to the next or previous label
respectively.

src/ulas.c
src/ulas.h
tests/t0.bin
tests/t0.s
tests/t0_dasm.s

index a5783c80efc27d9e7204001d2a7f6067262e4f85..917858ccbbb2548767408681aa74455c420995ff 100644 (file)
@@ -265,7 +265,7 @@ int ulas_isname(const char *tok, unsigned long n) {
 }
 
 int ulas_islabelname(const char *tok, unsigned long n) {
-  return tok[n - 1] == ':' && ulas_isname(tok, n - 1);
+  return tok[n - 1] == ':' && (ulas_isname(tok, n - 1) || n == 1);
 }
 
 struct ulas_sym *ulas_symbolresolve(const char *name, int scope, int *rc) {
@@ -311,7 +311,7 @@ int ulas_symbolset(const char *cname, int scope, struct ulas_tok tok,
     ulas.scope++;
   }
 
-  if (!existing) {
+  if (!existing || (name[0] == '\0' && len == 1)) {
     // def new symbol
     struct ulas_sym new_sym = {strndup(name, len), tok, scope, ulas.pass,
                                constant};
@@ -340,7 +340,11 @@ int ulas_symbolout(FILE *dst, struct ulas_sym *s) {
   }
 
   int rc = 0;
-  fprintf(dst, "%s = ", s->name);
+  if (!s->name || s->name[0] == '\0') {
+    fprintf(dst, "<unnamed> = ");
+  } else {
+    fprintf(dst, "%s = ", s->name);
+  }
   switch (s->tok.type) {
   case ULAS_INT:
     fprintf(dst, "0x%x", ulas_valint(&s->tok, &rc));
@@ -1470,7 +1474,8 @@ int ulas_parsecmp(int *i);
 int ulas_parseun(int *i) {
   struct ulas_tok *t = ulas_tokbufget(&ulas.toks, *i);
 
-  if (t && (t->type == '!' || t->type == '-' || t->type == '~' || t->type == '+')) {
+  if (t &&
+      (t->type == '!' || t->type == '-' || t->type == '~' || t->type == '+')) {
     int op = *i;
     *i += 1;
     int right = ulas_parseun(i);
@@ -2336,7 +2341,9 @@ int ulas_asmline(FILE *dst, FILE *src, const char *line, unsigned long n) {
   if (ulas_islabelname(ulas.tok.buf, strlen(ulas.tok.buf))) {
     instr_start = line;
     struct ulas_tok label_tok = {ULAS_INT, {(int)ulas.address}};
-    ulas_symbolset(ulas.tok.buf, -1, label_tok, 1);
+    if (ulas_symbolset(ulas.tok.buf, -1, label_tok, 1) == -1) {
+      return -1;
+    }
     ulas_tok(&ulas.tok, &line, n);
     // is next token empty?
     if (ulas_istokend(&ulas.tok)) {
index fe29e7f09f5bd80d820d991f7110a2777f1307c4..8c58880d709473687d5282e56c0aa0aa1566f901 100644 (file)
@@ -248,7 +248,6 @@ struct ulas_preproc {
   struct ulas_str macrobuf;
 };
 
-
 struct ulas {
   struct ulas_preproc pp;
   char *filename;
@@ -427,7 +426,6 @@ enum ulas_asmdir {
   ULAS_ASMDIR_REP,
 };
 
-
 #define ULAS_INSTRTOKMAX 16
 #define ULAS_INSTRDATMAX 16
 
index 371ef142ee4dd29c40eb82131274098a23b74568..4f18f9a43542ebf2402d537bcb4dba529ac78012 100644 (file)
Binary files a/tests/t0.bin and b/tests/t0.bin differ
index fe5ffc8c1776059b6bbf5648f52de8bc84b2852e..18f76f82336a7bdc6c3b2c74268663f6ad54e994 100644 (file)
@@ -155,3 +155,8 @@ nextlevel $2
 #endmacro 
 
 toplevel 5, 6
+
+:
+:
+  halt
+
index a83a590e40fa120e1e5e0297f2325a0bbe531cac..0ea1f10b768afca26142a3893220a6183d607203 100644 (file)
   dec b
   inc b
 .db 0x6
+.db 0x76