shithub: rgbds

Download patch

ref: 9923fa3eee8924d1fd49117bcbd9339e17a1a241
parent: 750e93be3de46f50220ce4920f064380ec9b704f
author: Rangi <[email protected]>
date: Sat Apr 17 09:14:40 EDT 2021

Fix expansions that start from the end of another expansion (#839)

Do not free an expansion until its offset is *past* its size.
This means potentially freeing a nested stack of expansions
all at once.

Fixes #696

--- a/src/asm/lexer.c
+++ b/src/asm/lexer.c
@@ -736,7 +736,11 @@
 static int peekInternal(uint8_t distance)
 {
 	for (struct Expansion *exp = lexerState->expansions; exp; exp = exp->parent) {
-		assert(exp->offset < exp->size);
+		/*
+		 * An expansion that has reached its end will have `exp->offset` == `exp->size`,
+		 * and `peekInternal` will continue with its parent
+		 */
+		assert(exp->offset <= exp->size);
 		if (distance < exp->size - exp->offset)
 			return exp->contents.unowned[exp->offset + distance];
 		distance -= exp->size - exp->offset;
@@ -870,16 +874,21 @@
 
 	lexerState->macroArgScanDistance--;
 
+restart:
 	if (lexerState->expansions) {
 		/* Advance within the current expansion */
-		assert(lexerState->expansions->offset < lexerState->expansions->size);
+		assert(lexerState->expansions->offset <= lexerState->expansions->size);
 		lexerState->expansions->offset++;
-		if (lexerState->expansions->offset == lexerState->expansions->size) {
-			/* When an expansion is done, free it and move up to its parent */
+		if (lexerState->expansions->offset > lexerState->expansions->size) {
+			/*
+			 * When advancing would go past an expansion's end, free it,
+			 * move up to its parent, and try again to advance
+			 */
 			struct Expansion *exp = lexerState->expansions;
 
 			lexerState->expansions = lexerState->expansions->parent;
 			freeExpansion(exp);
+			goto restart;
 		}
 	} else {
 		/* Advance within the file contents */
--- a/test/asm/equs-newline.err
+++ b/test/asm/equs-newline.err
@@ -3,5 +3,6 @@
 while expanding symbol "ACT"
 warning: equs-newline.asm(3): [-Wuser]
     Second
+while expanding symbol "ACT"
 warning: equs-newline.asm(4): [-Wuser]
     Third
--- a/test/asm/equs-recursion.asm
+++ b/test/asm/equs-recursion.asm
@@ -1,6 +1,2 @@
-recurse EQUS "recurse "
+recurse EQUS "recurse"
 recurse
-
-; FIXME: also handle the following:
-; recurse EQUS "recurse"
-; recurse
--- a/test/asm/interpolation-recursion.asm
+++ b/test/asm/interpolation-recursion.asm
@@ -1,6 +1,2 @@
-recurse EQUS "\{recurse\} "
+recurse EQUS "\{recurse\}"
 {recurse}
-
-; FIXME: also handle the following:
-; recurse EQUS "\{recurse\}"
-; {recurse}
--- a/test/asm/interpolation-recursion.err
+++ b/test/asm/interpolation-recursion.err
@@ -1,67 +1,67 @@
 FATAL: interpolation-recursion.asm(2):
     Recursion limit (64) exceeded
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
-while expanding symbol "{recurse} "
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
+while expanding symbol "{recurse}"
--- a/test/asm/rst.asm
+++ b/test/asm/rst.asm
@@ -16,12 +16,8 @@
 
 
 defRST: MACRO
-; FIXME: This is required, otherwise the lexer does not paste the two tokens
-ADDR equs "$\1"
-SECTION "rst\1", ROM0[ADDR]
-
-rst\1:
-	PURGE ADDR
+	SECTION "rst\1", ROM0[$\1]
+	rst\1:
 ENDM
 	defRST 00
 	defRST 08
--- a/test/asm/test.sh
+++ b/test/asm/test.sh
@@ -62,6 +62,7 @@
 	cat > quote\"file.err <<EOF
 warning: quote"file.asm(1): [-Wuser]
     quote"file.asm
+while expanding symbol "__FILE__"
 EOF
 fi
 
--- a/test/asm/unique-id.err
+++ b/test/asm/unique-id.err
@@ -1,19 +1,27 @@
 warning: unique-id.asm(12) -> unique-id.asm::m(4): [-Wuser]
     _u1
+while expanding symbol "warn_unique"
 warning: unique-id.asm(12) -> unique-id.asm::m(5) -> unique-id.asm::m::REPT~1(6): [-Wuser]
     _u2
+while expanding symbol "warn_unique"
 warning: unique-id.asm(12) -> unique-id.asm::m(5) -> unique-id.asm::m::REPT~2(6): [-Wuser]
     _u3
+while expanding symbol "warn_unique"
 warning: unique-id.asm(12) -> unique-id.asm::m(8): [-Wuser]
     _u1
+while expanding symbol "warn_unique"
 warning: unique-id.asm(14) -> unique-id.asm::m(4): [-Wuser]
     _u4
+while expanding symbol "warn_unique"
 warning: unique-id.asm(14) -> unique-id.asm::m(5) -> unique-id.asm::m::REPT~1(6): [-Wuser]
     _u5
+while expanding symbol "warn_unique"
 warning: unique-id.asm(14) -> unique-id.asm::m(5) -> unique-id.asm::m::REPT~2(6): [-Wuser]
     _u6
+while expanding symbol "warn_unique"
 warning: unique-id.asm(14) -> unique-id.asm::m(8): [-Wuser]
     _u4
+while expanding symbol "warn_unique"
 FATAL: unique-id.asm(15):
     Macro argument '\@' not defined
 while expanding symbol "warn_unique"
--- a/test/link/rst.asm
+++ b/test/link/rst.asm
@@ -14,12 +14,8 @@
 
 
 defRST: MACRO
-; FIXME: This is required, otherwise the lexer does not paste the two tokens
-ADDR equs "$\1"
-SECTION "rst\1", ROM0[ADDR]
-
-rst\1:
-	PURGE ADDR
+	SECTION "rst\1", ROM0[$\1]
+	rst\1:
 ENDM
 	defRST 00
 	defRST 08