mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
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 <remy.oukaour+rangi42@gmail.com>
This commit is contained in:
@@ -355,7 +355,6 @@ struct LexerState {
|
||||
uint32_t lineNo;
|
||||
uint32_t colNo;
|
||||
int lastToken;
|
||||
int nextToken;
|
||||
|
||||
struct IfStack *ifStack;
|
||||
|
||||
@@ -379,7 +378,6 @@ 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;
|
||||
|
||||
@@ -1795,13 +1793,6 @@ 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;
|
||||
@@ -1919,23 +1910,6 @@ static int yylex_NORMAL(void)
|
||||
|
||||
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 */
|
||||
|
||||
@@ -646,7 +646,6 @@ enum {
|
||||
%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 @@ z80_ldio : T_Z80_LDH T_MODE_A T_COMMA op_mem_ind {
|
||||
;
|
||||
|
||||
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
|
||||
|
||||
9
test/asm/ff00+c-bad.asm
Normal file
9
test/asm/ff00+c-bad.asm
Normal file
@@ -0,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
|
||||
5
test/asm/ff00+c-bad.err
Normal file
5
test/asm/ff00+c-bad.err
Normal file
@@ -0,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)!
|
||||
11
test/asm/ff00+c-label.asm
Normal file
11
test/asm/ff00+c-label.asm
Normal file
@@ -0,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:
|
||||
1
test/asm/ff00+c-label.out
Normal file
1
test/asm/ff00+c-label.out
Normal file
@@ -0,0 +1 @@
|
||||
$FF2A
|
||||
1
test/asm/ff00+c-label.out.bin
Normal file
1
test/asm/ff00+c-label.out.bin
Normal file
@@ -0,0 +1 @@
|
||||
<EFBFBD>*<2A><><0C><>*<2A><><0C>
|
||||
0
test/asm/ff00+c.err
Normal file
0
test/asm/ff00+c.err
Normal file
0
test/asm/ff00+c.out
Normal file
0
test/asm/ff00+c.out
Normal file
Reference in New Issue
Block a user