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:
Rangi
2021-03-23 13:54:23 -04:00
committed by Eldred Habert
parent 4e1b0ce793
commit 260d372acd
5 changed files with 22 additions and 8 deletions

View File

@@ -350,6 +350,7 @@ struct LexerState {
uint32_t lineNo;
uint32_t colNo;
int lastToken;
int nextToken;
struct IfStack *ifStack;
@@ -374,6 +375,7 @@ static void initState(struct LexerState *state)
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 @@ static int yylex_NORMAL(void)
{
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 @@ static int yylex_NORMAL(void)
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;