scope: Reworked begin and endscope to use icounter
authorLukas Krickl <lukas@krickl.dev>
Wed, 19 Mar 2025 21:40:54 +0000 (22:40 +0100)
committerLukas Krickl <lukas@krickl.dev>
Wed, 19 Mar 2025 21:40:54 +0000 (22:40 +0100)
TODO.md
man/ulas.5
src/ulas.c
src/ulas.h

diff --git a/TODO.md b/TODO.md
index dc8ec80f0fb4f9eb2e40252925827977bb9f701d..228c74425a536c6ee29e13019d7b46c6bde594a5 100644 (file)
--- a/TODO.md
+++ b/TODO.md
@@ -7,4 +7,4 @@
 - Add failing tests for most failure cases
 - Assert `.section` in full test
 - Add `.bank.` directive allowing users to set the current bank number (ulas.bank) which can be used for symbol files.
-- Add scoped labels in macros
+- Allow nested begin and end scope calls
index f37da733070c859c5b9e66255c9a79bc6149600c..30b093f7621900f639e952ef7cab412f72460b9a 100644 (file)
@@ -155,7 +155,8 @@ The special value $ will evaluate to the current address.
 
 .SH beginscope 
   \.beginscope
-  Starts a new scope
+  Starts a new scope.
+  .beginscope should not be nested!
 
 .SH endscope
   \.endscope
index 36b077c840ebf90aa119d9d1b03d3d55255cb682..9c265094c990624e820d7119eaecb528947adb40 100644 (file)
@@ -2620,10 +2620,18 @@ int ulas_asmline(FILE *dst, FILE *src, const char *line, unsigned long n) {
       rc = ulas_asmdirbank(dst, src, &line, n, &rc);
       break;
     case ULAS_ASMDIR_BEGIN_SCOPE:
-      ulas.scope++;
+      if (ulas.prev_scope != 0) {
+        ULASPANIC("nested .beginscope detected\n");
+      }
+      ulas.prev_scope = ulas.scope;
+      ulas.scope = -1 - ulas_icntr();
       break;
     case ULAS_ASMDIR_END_SCOPE:
-      ulas.scope--;
+      if (ulas.prev_scope == 0) {
+        ULASPANIC("calling .endscope without starting a scope\n");
+      }
+      ulas.scope = ulas.prev_scope;
+      ulas.prev_scope = 0;
       break;
     case ULAS_ASMDIR_PAD:
       // TODO: pad is the same as .fill n, $ - n
index 5d301c48c4322f73abe029b2e4c3c74d28a5c598..4fcb0fb794b6e388a5c6ca9a0e6a97f5df2a9f05 100644 (file)
@@ -310,6 +310,9 @@ struct ulas {
   // current scope index
   // each global-label increments the scope
   int scope;
+  // temporary storage for .beginscope 
+  // and .endscope
+  int prev_scope;
 
   // internal counter
   // used whenever a new unique number might be needed