shithub: rgbds

Download patch

ref: 260d372acd761f6310339a91f1cb1a7ce25e1805
parent: 4e1b0ce7930fc7201a42ca17669e81d088d0c5b2
author: Rangi <remy.oukaour+rangi42@gmail.com>
date: Tue Mar 23 09:54:23 EDT 2021

Lex `$ff00+c` without needing large `peek` lookahead

This also allows arbitrary amounts of whitespace in `$ff00 + c`,
instead of needing to fit in the 42-byte LEXER_BUF_SIZE

--- a/src/asm/lexer.c
+++ b/src/asm/lexer.c
@@ -350,6 +350,7 @@
 	uint32_t lineNo;
 	uint32_t colNo;
 	int lastToken;
+	int nextToken;
 
 	struct IfStack *ifStack;
 
@@ -374,6 +375,7 @@
 	state->mode = LEXER_NORMAL;
 	state->atLineStart = true; /* yylex() will init colNo due to this */
 	state->lastToken = T_EOF;
+	state->nextToken = 0;
 
 	state->ifStack = NULL;
 
@@ -1778,6 +1780,14 @@
 {
 	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;
@@ -1902,17 +1912,15 @@
 				while (isWhitespace(c = peek(0)))
 					shiftChars(1);
 				if (c == '+') {
-					/* FIXME: not great due to large lookahead */
-					uint8_t distance = 1;
-
-					do {
-						c = peek(distance++);
-					} while (isWhitespace(c));
-
+					shiftChars(1);
+					while (isWhitespace(c = peek(0)))
+						shiftChars(1);
 					if (c == 'c' || c == 'C') {
-						shiftChars(distance);
+						shiftChars(1);
 						return T_MODE_HW_C;
 					}
+					/* Retroactively lex the plus after the $ff00 */
+					lexerState->nextToken = T_OP_ADD;
 				}
 			}
 			return T_NUMBER;
--- /dev/null
+++ b/test/asm/ff00-plus-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-plus-c.out.bin
@@ -1,0 +1,1 @@
+�
\ No newline at end of file