From c01317e08dd94002f497f9a3ec65760ae3e1cddc Mon Sep 17 00:00:00 2001 From: Rangi <35663410+Rangi42@users.noreply.github.com> Date: Wed, 31 Aug 2022 17:45:21 -0400 Subject: [PATCH] Only increment the unique `\@` ID when it is first used per context (#1030) This avoids changes to generated `\@` labels just by adding or removing macros or loops which do not actually use `\@`. Fixes #1019 --- src/asm/fstack.c | 3 ++ src/asm/macro.c | 15 ++++++---- test/asm/unique-id-values.asm | 22 ++++++++++++++ test/asm/unique-id-values.err | 0 test/asm/unique-id-values.out | 54 +++++++++++++++++++++++++++++++++++ 5 files changed, 88 insertions(+), 6 deletions(-) create mode 100644 test/asm/unique-id-values.asm create mode 100644 test/asm/unique-id-values.err create mode 100644 test/asm/unique-id-values.out 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)