diff --git a/src/asm/fstack.c b/src/asm/fstack.c index 5ce5aa37..aadac116 100644 --- a/src/asm/fstack.c +++ b/src/asm/fstack.c @@ -285,6 +285,9 @@ static void newContext(struct FileStackNode *fileInfo) ++contextDepth; fstk_NewRecursionDepth(maxRecursionDepth); // Only checks if the max depth was exceeded + // Save the current `\@` value, to be restored when this context ends + contextStack->uniqueID = macro_GetUniqueID(); + struct Context *context = malloc(sizeof(*context)); if (!context) diff --git a/src/asm/macro.c b/src/asm/macro.c index 30fd9ed2..655d3d03 100644 --- a/src/asm/macro.c +++ b/src/asm/macro.c @@ -6,7 +6,6 @@ * SPDX-License-Identifier: MIT */ -#include #include #include #include @@ -145,17 +144,19 @@ uint32_t macro_GetUniqueID(void) char const *macro_GetUniqueIDStr(void) { + // Generate a new unique ID on the first use of `\@` + if (uniqueID == 0) + macro_SetUniqueID(++maxUniqueID); + return uniqueIDPtr; } void macro_SetUniqueID(uint32_t id) { uniqueID = id; - if (id == 0) { + if (id == 0 || id == (uint32_t)-1) { uniqueIDPtr = NULL; } else { - if (uniqueID > maxUniqueID) - maxUniqueID = uniqueID; // The buffer is guaranteed to be the correct size // This is a valid label fragment, but not a valid numeric sprintf(uniqueIDBuf, "_u%" PRIu32, id); @@ -165,13 +166,15 @@ void macro_SetUniqueID(uint32_t id) uint32_t macro_UseNewUniqueID(void) { - macro_SetUniqueID(++maxUniqueID); + // A new ID will be generated on the first use of `\@` + macro_SetUniqueID(0); return uniqueID; } uint32_t macro_UndefUniqueID(void) { - macro_SetUniqueID(0); + // No ID will be generated; use of `\@` is an error + macro_SetUniqueID((uint32_t)-1); return uniqueID; } diff --git a/test/asm/unique-id-values.asm b/test/asm/unique-id-values.asm new file mode 100644 index 00000000..12a30c32 --- /dev/null +++ b/test/asm/unique-id-values.asm @@ -0,0 +1,22 @@ +MACRO m + println " m: \@" + for q, \# + if q % 2 == 0 + println " q = {d:q}: \@" + else + println " q = {d:q}" + endc + endr + println " (m: still \@)" +ENDM + +for p, 10 + if p % 3 == 0 + println "p = {d:p}: \@" + m 3 + m 3, 6 + println " (p: still \@)" + else + println "p = {d:p}" + endc +endr diff --git a/test/asm/unique-id-values.err b/test/asm/unique-id-values.err new file mode 100644 index 00000000..e69de29b diff --git a/test/asm/unique-id-values.out b/test/asm/unique-id-values.out new file mode 100644 index 00000000..29d3e768 --- /dev/null +++ b/test/asm/unique-id-values.out @@ -0,0 +1,54 @@ +p = 0: _u1 + m: _u2 + q = 0: _u3 + q = 1 + q = 2: _u4 + (m: still _u2) + m: _u5 + q = 3 + q = 4: _u6 + q = 5 + (m: still _u5) + (p: still _u1) +p = 1 +p = 2 +p = 3: _u7 + m: _u8 + q = 0: _u9 + q = 1 + q = 2: _u10 + (m: still _u8) + m: _u11 + q = 3 + q = 4: _u12 + q = 5 + (m: still _u11) + (p: still _u7) +p = 4 +p = 5 +p = 6: _u13 + m: _u14 + q = 0: _u15 + q = 1 + q = 2: _u16 + (m: still _u14) + m: _u17 + q = 3 + q = 4: _u18 + q = 5 + (m: still _u17) + (p: still _u13) +p = 7 +p = 8 +p = 9: _u19 + m: _u20 + q = 0: _u21 + q = 1 + q = 2: _u22 + (m: still _u20) + m: _u23 + q = 3 + q = 4: _u24 + q = 5 + (m: still _u23) + (p: still _u19)