mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
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
This commit is contained in:
@@ -350,6 +350,7 @@ struct LexerState {
|
|||||||
uint32_t lineNo;
|
uint32_t lineNo;
|
||||||
uint32_t colNo;
|
uint32_t colNo;
|
||||||
int lastToken;
|
int lastToken;
|
||||||
|
int nextToken;
|
||||||
|
|
||||||
struct IfStack *ifStack;
|
struct IfStack *ifStack;
|
||||||
|
|
||||||
@@ -374,6 +375,7 @@ static void initState(struct LexerState *state)
|
|||||||
state->mode = LEXER_NORMAL;
|
state->mode = LEXER_NORMAL;
|
||||||
state->atLineStart = true; /* yylex() will init colNo due to this */
|
state->atLineStart = true; /* yylex() will init colNo due to this */
|
||||||
state->lastToken = T_EOF;
|
state->lastToken = T_EOF;
|
||||||
|
state->nextToken = 0;
|
||||||
|
|
||||||
state->ifStack = NULL;
|
state->ifStack = NULL;
|
||||||
|
|
||||||
@@ -1778,6 +1780,14 @@ static int yylex_NORMAL(void)
|
|||||||
{
|
{
|
||||||
dbgPrint("Lexing in normal mode, line=%" PRIu32 ", col=%" PRIu32 "\n",
|
dbgPrint("Lexing in normal mode, line=%" PRIu32 ", col=%" PRIu32 "\n",
|
||||||
lexer_GetLineNo(), lexer_GetColNo());
|
lexer_GetLineNo(), lexer_GetColNo());
|
||||||
|
|
||||||
|
if (lexerState->nextToken) {
|
||||||
|
int token = lexerState->nextToken;
|
||||||
|
|
||||||
|
lexerState->nextToken = 0;
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int c = nextChar();
|
int c = nextChar();
|
||||||
char secondChar;
|
char secondChar;
|
||||||
@@ -1902,17 +1912,15 @@ static int yylex_NORMAL(void)
|
|||||||
while (isWhitespace(c = peek(0)))
|
while (isWhitespace(c = peek(0)))
|
||||||
shiftChars(1);
|
shiftChars(1);
|
||||||
if (c == '+') {
|
if (c == '+') {
|
||||||
/* FIXME: not great due to large lookahead */
|
shiftChars(1);
|
||||||
uint8_t distance = 1;
|
while (isWhitespace(c = peek(0)))
|
||||||
|
shiftChars(1);
|
||||||
do {
|
|
||||||
c = peek(distance++);
|
|
||||||
} while (isWhitespace(c));
|
|
||||||
|
|
||||||
if (c == 'c' || c == 'C') {
|
if (c == 'c' || c == 'C') {
|
||||||
shiftChars(distance);
|
shiftChars(1);
|
||||||
return T_MODE_HW_C;
|
return T_MODE_HW_C;
|
||||||
}
|
}
|
||||||
|
/* Retroactively lex the plus after the $ff00 */
|
||||||
|
lexerState->nextToken = T_OP_ADD;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return T_NUMBER;
|
return T_NUMBER;
|
||||||
|
|||||||
5
test/asm/ff00-plus-c.asm
Normal file
5
test/asm/ff00-plus-c.asm
Normal file
@@ -0,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
|
||||||
0
test/asm/ff00-plus-c.err
Normal file
0
test/asm/ff00-plus-c.err
Normal file
0
test/asm/ff00-plus-c.out
Normal file
0
test/asm/ff00-plus-c.out
Normal file
1
test/asm/ff00-plus-c.out.bin
Normal file
1
test/asm/ff00-plus-c.out.bin
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<EFBFBD><EFBFBD><EFBFBD>
|
||||||
Reference in New Issue
Block a user