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