ref: c01317e08dd94002f497f9a3ec65760ae3e1cddc
parent: a52a00a9ca7753ef41814b55878b510e8dc80b7b
author: Rangi <35663410+Rangi42@users.noreply.github.com>
date: Wed Aug 31 13:45:21 EDT 2022
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
--- a/src/asm/fstack.c
+++ b/src/asm/fstack.c
@@ -285,6 +285,9 @@
++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)
--- a/src/asm/macro.c
+++ b/src/asm/macro.c
@@ -6,7 +6,6 @@
* SPDX-License-Identifier: MIT
*/
-#include <assert.h>
#include <errno.h>
#include <inttypes.h>
#include <stdbool.h>
@@ -145,6 +144,10 @@
char const *macro_GetUniqueIDStr(void)
{
+ // Generate a new unique ID on the first use of `\@`
+ if (uniqueID == 0)
+ macro_SetUniqueID(++maxUniqueID);
+
return uniqueIDPtr;
}
@@ -151,11 +154,9 @@
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 @@
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;
}
--- /dev/null
+++ b/test/asm/unique-id-values.asm
@@ -1,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
--- /dev/null
+++ b/test/asm/unique-id-values.out
@@ -1,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)