From c06985a7ad2e91105b50ad07bcb93a29f502ab3b Mon Sep 17 00:00:00 2001 From: Eldred Habert Date: Wed, 5 May 2021 02:04:19 +0200 Subject: [PATCH] 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 --- src/asm/lexer.c | 26 ------------------- src/asm/parser.y | 6 +++-- test/asm/ff00+c-bad.asm | 9 +++++++ test/asm/ff00+c-bad.err | 5 ++++ test/asm/{ff00-plus-c.err => ff00+c-bad.out} | 0 test/asm/ff00+c-label.asm | 11 ++++++++ .../asm/{ff00-plus-c.out => ff00+c-label.err} | 0 test/asm/ff00+c-label.out | 1 + test/asm/ff00+c-label.out.bin | 1 + test/asm/{ff00-plus-c.asm => ff00+c.asm} | 0 test/asm/ff00+c.err | 0 test/asm/ff00+c.out | 0 .../{ff00-plus-c.out.bin => ff00+c.out.bin} | 0 13 files changed, 31 insertions(+), 28 deletions(-) create mode 100644 test/asm/ff00+c-bad.asm create mode 100644 test/asm/ff00+c-bad.err rename test/asm/{ff00-plus-c.err => ff00+c-bad.out} (100%) create mode 100644 test/asm/ff00+c-label.asm rename test/asm/{ff00-plus-c.out => ff00+c-label.err} (100%) create mode 100644 test/asm/ff00+c-label.out create mode 100644 test/asm/ff00+c-label.out.bin rename test/asm/{ff00-plus-c.asm => ff00+c.asm} (100%) create mode 100644 test/asm/ff00+c.err create mode 100644 test/asm/ff00+c.out rename test/asm/{ff00-plus-c.out.bin => ff00+c.out.bin} (100%) diff --git a/src/asm/lexer.c b/src/asm/lexer.c index ca25e42e8..3a7425ab9 100644 --- a/src/asm/lexer.c +++ b/src/asm/lexer.c @@ -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 */ diff --git a/src/asm/parser.y b/src/asm/parser.y index 630cbd4f2..48afd9d47 100644 --- a/src/asm/parser.y +++ b/src/asm/parser.y @@ -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 diff --git a/test/asm/ff00+c-bad.asm b/test/asm/ff00+c-bad.asm new file mode 100644 index 000000000..19a01a53e --- /dev/null +++ b/test/asm/ff00+c-bad.asm @@ -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 diff --git a/test/asm/ff00+c-bad.err b/test/asm/ff00+c-bad.err new file mode 100644 index 000000000..3589cd451 --- /dev/null +++ b/test/asm/ff00+c-bad.err @@ -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)! diff --git a/test/asm/ff00-plus-c.err b/test/asm/ff00+c-bad.out similarity index 100% rename from test/asm/ff00-plus-c.err rename to test/asm/ff00+c-bad.out diff --git a/test/asm/ff00+c-label.asm b/test/asm/ff00+c-label.asm new file mode 100644 index 000000000..61370a33a --- /dev/null +++ b/test/asm/ff00+c-label.asm @@ -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: diff --git a/test/asm/ff00-plus-c.out b/test/asm/ff00+c-label.err similarity index 100% rename from test/asm/ff00-plus-c.out rename to test/asm/ff00+c-label.err diff --git a/test/asm/ff00+c-label.out b/test/asm/ff00+c-label.out new file mode 100644 index 000000000..36f7700b0 --- /dev/null +++ b/test/asm/ff00+c-label.out @@ -0,0 +1 @@ +$FF2A diff --git a/test/asm/ff00+c-label.out.bin b/test/asm/ff00+c-label.out.bin new file mode 100644 index 000000000..d7d82955e --- /dev/null +++ b/test/asm/ff00+c-label.out.bin @@ -0,0 +1 @@ +Ã*ÿÃ ÿÃ*ÿÃ ÿ \ No newline at end of file diff --git a/test/asm/ff00-plus-c.asm b/test/asm/ff00+c.asm similarity index 100% rename from test/asm/ff00-plus-c.asm rename to test/asm/ff00+c.asm diff --git a/test/asm/ff00+c.err b/test/asm/ff00+c.err new file mode 100644 index 000000000..e69de29bb diff --git a/test/asm/ff00+c.out b/test/asm/ff00+c.out new file mode 100644 index 000000000..e69de29bb diff --git a/test/asm/ff00-plus-c.out.bin b/test/asm/ff00+c.out.bin similarity index 100% rename from test/asm/ff00-plus-c.out.bin rename to test/asm/ff00+c.out.bin