Skip to content

Commit

Permalink
Fix incorrect lexing of "$ff00+c" (gbdev#882)
Browse files Browse the repository at this point in the history
Fixes gbdev#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>
  • Loading branch information
ISSOtm and Rangi42 authored May 5, 2021
1 parent c502804 commit c06985a
Show file tree
Hide file tree
Showing 13 changed files with 31 additions and 28 deletions.
26 changes: 0 additions & 26 deletions src/asm/lexer.c
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,6 @@ struct LexerState {
uint32_t lineNo;
uint32_t colNo;
int lastToken;
int nextToken;

struct IfStack *ifStack;

Expand All @@ -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;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 */
Expand Down
6 changes: 4 additions & 2 deletions src/asm/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down
9 changes: 9 additions & 0 deletions test/asm/ff00+c-bad.asm
Original file line number Diff line number Diff line change
@@ -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 changes: 5 additions & 0 deletions test/asm/ff00+c-bad.err
Original file line number Diff line number Diff line change
@@ -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)!
File renamed without changes.
11 changes: 11 additions & 0 deletions test/asm/ff00+c-label.asm
Original file line number Diff line number Diff line change
@@ -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:
File renamed without changes.
1 change: 1 addition & 0 deletions test/asm/ff00+c-label.out
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
$FF2A
1 change: 1 addition & 0 deletions test/asm/ff00+c-label.out.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
�*�� ��*�� �
File renamed without changes.
Empty file added test/asm/ff00+c.err
Empty file.
Empty file added test/asm/ff00+c.out
Empty file.
File renamed without changes.

0 comments on commit c06985a

Please sign in to comment.