shithub: rgbds

Download patch

ref: c06985a7ad2e91105b50ad07bcb93a29f502ab3b
parent: c50280419287ca259da4620be591f8e1e67285dc
author: Eldred Habert <[email protected]>
date: Tue May 4 22:04:19 EDT 2021

Fix incorrect lexing of "$ff00+c" (#882)

Fixes #881 by moving the task from the lexer to the parser.
This both alleviates the need for backtracking in the lexer,
removing what is (was) arguably a hack, and causes tokenization
boundaries to be properly respected, fixing the issue mentioned above.

Co-authored-by: Rangi <[email protected]>

--- a/src/asm/lexer.c
+++ b/src/asm/lexer.c
@@ -355,7 +355,6 @@
 	uint32_t lineNo;
 	uint32_t colNo;
 	int lastToken;
-	int nextToken;
 
 	struct IfStack *ifStack;
 
@@ -379,7 +378,6 @@
 	state->mode = LEXER_NORMAL;
 	state->atLineStart = true; /* yylex() will init colNo due to this */
 	state->lastToken = T_EOF;
-	state->nextToken = 0;
 
 	state->ifStack = NULL;
 
@@ -1795,13 +1793,6 @@
 	dbgPrint("Lexing in normal mode, line=%" PRIu32 ", col=%" PRIu32 "\n",
 		 lexer_GetLineNo(), lexer_GetColNo());
 
-	if (lexerState->nextToken) {
-		int token = lexerState->nextToken;
-
-		lexerState->nextToken = 0;
-		return token;
-	}
-
 	for (;;) {
 		int c = nextChar();
 		char secondChar;
@@ -1919,23 +1910,6 @@
 
 		case '$':
 			yylval.constValue = readHexNumber();
-			/* Attempt to match `$ff00+c` */
-			if (yylval.constValue == 0xff00) {
-				/* Whitespace is ignored anyways */
-				while (isWhitespace(c = peek()))
-					shiftChar();
-				if (c == '+') {
-					shiftChar();
-					while (isWhitespace(c = peek()))
-						shiftChar();
-					if (c == 'c' || c == 'C') {
-						shiftChar();
-						return T_MODE_HW_C;
-					}
-					/* Retroactively lex the plus after the $ff00 */
-					lexerState->nextToken = T_OP_ADD;
-				}
-			}
 			return T_NUMBER;
 
 		case '0': /* Decimal number */
--- a/src/asm/parser.y
+++ b/src/asm/parser.y
@@ -646,7 +646,6 @@
 %token	T_TOKEN_D "d" T_TOKEN_E "e"
 %token	T_TOKEN_H "h" T_TOKEN_L "l"
 %token	T_MODE_AF "af" T_MODE_BC "bc" T_MODE_DE "de" T_MODE_SP "sp"
-%token	T_MODE_HW_C "$ff00+c"
 %token	T_MODE_HL "hl" T_MODE_HL_DEC "hld/hl-" T_MODE_HL_INC "hli/hl+"
 %token	T_CC_NZ "nz" T_CC_Z "z" T_CC_NC "nc" // There is no T_CC_C, only T_TOKEN_C
 
@@ -1861,7 +1860,10 @@
 ;
 
 c_ind		: T_LBRACK T_MODE_C T_RBRACK
-		| T_LBRACK T_MODE_HW_C T_RBRACK
+		| T_LBRACK relocexpr T_OP_ADD T_MODE_C T_RBRACK {
+			if (!rpn_isKnown(&$2) || $2.val != 0xff00)
+				error("Expected constant expression equal to $FF00 for \"$ff00+c\"\n");
+		}
 ;
 
 z80_ld		: z80_ld_mem
--- /dev/null
+++ b/test/asm/ff00+c-bad.asm
@@ -1,0 +1,9 @@
+
+SECTION "ff00+c or not to ff00+c", ROMX
+
+	ld a, [$ff00 + c]
+	ld [65280 + c], a
+
+	; Not ok
+	ld a, [$ff01 + c]
+	ld [xyz + c], a
--- /dev/null
+++ b/test/asm/ff00+c-bad.err
@@ -1,0 +1,5 @@
+ERROR: ff00+c-bad.asm(8):
+    Expected constant expression equal to $FF00 for "$ff00+c"
+ERROR: ff00+c-bad.asm(9):
+    Expected constant expression equal to $FF00 for "$ff00+c"
+error: Assembly aborted (2 errors)!
--- /dev/null
+++ b/test/asm/ff00+c-label.asm
@@ -1,0 +1,11 @@
+CONSTANT equ 42
+PRINTLN $ff00 + CONSTANT
+
+SECTION "Overreading much?", ROM0[0]
+
+	jp $ff00 + CONSTANT
+	jp $ff00 + carryOnPlease
+	jp $ff00+CONSTANT
+	jp $ff00+carryOnPlease
+
+carryOnPlease:
--- /dev/null
+++ b/test/asm/ff00+c-label.out
@@ -1,0 +1,1 @@
+$FF2A
--- /dev/null
+++ b/test/asm/ff00+c-label.out.bin
@@ -1,0 +1,1 @@
+�*����*��
\ No newline at end of file
--- /dev/null
+++ b/test/asm/ff00+c.asm
@@ -1,0 +1,5 @@
+SECTION "test", ROM0[0]
+	ld [ $ff00 + c ], a
+	; 257 spaces exceeds both LEXER_BUF_SIZE (42) and uint8_t limit (255)
+	ld [ $ff00 +                                                                                                                                                                                                                                                                 c ], a
+	ld [ $ff00                                                                                                                                                                                                                                                                 + c ], a
--- /dev/null
+++ b/test/asm/ff00+c.out.bin
@@ -1,0 +1,1 @@
+�
\ No newline at end of file
--- a/test/asm/ff00-plus-c.asm
+++ /dev/null
@@ -1,5 +1,0 @@
-SECTION "test", ROM0[0]
-	ld [ $ff00 + c ], a
-	; 257 spaces exceeds both LEXER_BUF_SIZE (42) and uint8_t limit (255)
-	ld [ $ff00 +                                                                                                                                                                                                                                                                 c ], a
-	ld [ $ff00                                                                                                                                                                                                                                                                 + c ], a
--- a/test/asm/ff00-plus-c.out.bin
+++ /dev/null
@@ -1,1 +1,0 @@
-�
\ No newline at end of file