Moved asm step.
authorLukas Krickl <lukas@krickl.dev>
Tue, 14 Nov 2023 10:41:36 +0000 (11:41 +0100)
committerLukas Krickl <lukas@krickl.dev>
Tue, 14 Nov 2023 10:41:36 +0000 (11:41 +0100)
The asm step is now executed directly after each line is processed.
This makes it easier to track file locations for error reporting.

include/ulas.h
src/test.c
src/ulas.c

index beccd40176cd25ec2541c0c50570385e4e220e97..a3d51353dabf7e69feb397a01db74ed70a3d9433 100644 (file)
 #define ULAS_PPSTR_ENDMACRO "#endmacro"
 #define ULAS_PPSTR_UNDEF "#undefine"
 
+#define ULAS_ASMSTR_ORG ".org"
+#define ULAS_ASMSTR_SET ".set"
+#define ULAS_ASMSTR_BYTE ".db"
+#define ULAS_ASMSTR_STR ".str"
+#define ULAS_ASMSTR_FILL ".fill"
+#define ULAS_ASMSTR_PAD ".pad"
+#define ULAS_ASMSTR_INCBIN ".incbin"
+
 // configurable tokens
 #define ULAS_TOK_COMMENT ';'
 // start of as directives such as .org
@@ -237,6 +245,7 @@ struct ulas_expr {
  * asm
  */
 enum ulas_asmdir {
+  ULAS_ASMDIR_NONE = 0,
   // .org <address>
   ULAS_ASMDIR_ORG,
   // .set name = <expr>
index 51c973157e26b4cc43a077f8bc51ef5876a60fd0..f419c75e3bab981e1d707d310652f6fc8109a10f 100644 (file)
@@ -90,6 +90,7 @@ void test_strbuf(void) {
   }
 
 void test_preproc(void) {
+  ulascfg.preproc_only = 1;
   TESTBEGIN("preproc");
 
   // no directive
@@ -139,6 +140,7 @@ void test_preproc(void) {
                  "#ifndef test\nifndeftest defined!\n");
 
   TESTEND("preproc");
+  ulascfg.preproc_only = 0;
 }
 
 int main(int arc, char **argv) {
index 433a044799433dd3a22b1e43b557d31c125789d6..cea0eb745f113b2b4938f0a6afd59d9f97c25e59 100644 (file)
@@ -78,9 +78,6 @@ int ulas_main(struct ulas_config cfg) {
     goto cleanup;
   }
 
-  fseek(preprocdst, 0, SEEK_SET);
-  rc = ulas_asm(ulasout, preprocdst);
-
 cleanup:
   if (!cfg.preproc_only) {
     fclose(preprocdst);
@@ -679,6 +676,7 @@ void ulas_preprocfree(struct ulas_preproc *pp) {
 }
 
 int ulas_preproc(FILE *dst, FILE *src) {
+  FILE *asmsrc = dst;
   char buf[ULAS_LINEMAX];
   memset(buf, 0, ULAS_LINEMAX);
   int rc = 0;
@@ -686,10 +684,24 @@ int ulas_preproc(FILE *dst, FILE *src) {
   // init
   struct ulas_preproc pp = ulas_preprocinit();
 
+  long prevseek = 0;
   // preproc
   while ((rc = ulas_preprocnext(&pp, dst, src, buf, ULAS_LINEMAX)) > 0) {
+    if (ulascfg.preproc_only) {
+      continue;
+    }
+
+    // after each preproc line we assembly it by reading it back
+    // from the temporary buffer
+    fseek(asmsrc, prevseek, SEEK_SET);
+    if (ulas_asm(ulasout, asmsrc) == -1) {
+      rc = -1;
+      goto fail;
+    }
+    prevseek = ftell(asmsrc);
   }
 
+fail:
   // cleanup
   ulas_preprocfree(&pp);
 
@@ -710,20 +722,39 @@ int ulas_asmline(FILE *dst, FILE *src, const char *line, size_t n) {
   ulas_tok(&ulas.tok, &line, n);
 
   if (ulas.tok.buf[0] == ULAS_TOK_ASMDIR_BEGIN) {
-    // is directive!
-    puts("Directive");
+    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};
+    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};
+
+    enum ulas_asmdir dir = ULAS_ASMDIR_NONE;
+
+    for (long i = 0; dirstrs[i]; i++) {
+      if (strncmp(ulas.tok.buf, dirstrs[i], n) == 0) {
+        dir = dirs[i];
+        break;
+      }
+    }
+
+    if (!dir) {
+      ULASERR("Unexpected directive\n");
+      rc = -1;
+      goto fail;
+    }
+
   } else {
     // is regular line in form of [label:] instruction ; comment
   }
 
+fail:
   return rc;
 }
 
 int ulas_asmnext(FILE *dst, FILE *src, char *buf, int n) {
   int rc = 1;
   if (fgets(buf, n, src) != NULL) {
-    ulas.line++;
-
     size_t buflen = strlen(buf);
     if (ulas_asmline(dst, src, buf, buflen) == -1) {
       rc = -1;
@@ -739,15 +770,9 @@ int ulas_asm(FILE *dst, FILE *src) {
   memset(buf, 0, ULAS_LINEMAX);
   int rc = 0;
 
-  // init
-  struct ulas_preproc pp = ulas_preprocinit();
-
   // preproc
   while ((rc = ulas_asmnext(dst, src, buf, ULAS_LINEMAX)) > 0) {
   }
 
-  // cleanup
-  ulas_preprocfree(&pp);
-
   return rc;
 }