Remove "EOF-newline" lexer hack

In preparation for an upcoming change
Makes for nicer error messages, complaining about EOF instead of newlines
The hack had to be kept for the lexer raw mode to avoid a bug;
see the relevant code comment for more info.
This commit is contained in:
ISSOtm
2021-02-11 12:48:37 +01:00
parent 76446e6d00
commit b3c0db218d
19 changed files with 160 additions and 131 deletions

View File

@@ -36,9 +36,6 @@
#include "linkdefs.h"
#include "platform.h" // strncasecmp, strdup
int32_t nPCOffset; /* Read by rpn_Symbol */
static uint32_t nListCountEmpty;
static bool executeElseBlock; /* If this is set, ELIFs cannot be executed anymore */
static struct CaptureBody captureBody; /* Captures a REPT/FOR or MACRO */
@@ -406,6 +403,7 @@ enum {
int32_t step;
} forArgs;
struct StrFmtArgList strfmtArgs;
bool hasEmpty; // Whether `db`, `dw`, `dl` argument lists contain any empty entries
}
%type <sVal> relocexpr
@@ -420,6 +418,9 @@ enum {
%type <sVal> reloc_16bit
%type <sVal> reloc_16bit_no_str
%type <nConstValue> sectiontype
%type <hasEmpty> constlist_8bit constlist_8bit_entry
%type <hasEmpty> constlist_16bit constlist_16bit_entry
%type <hasEmpty> constlist_32bit constlist_32bit_entry
%type <tzString> string
%type <tzString> strcat_args
@@ -584,21 +585,21 @@ enum {
%%
asmfile : lines;
asmfile : lines last_line
;
/* Note: The lexer adds T_NEWLINE at the end of the input */
lines : %empty
| lines {
nListCountEmpty = 0;
nPCOffset = 0;
} line
| lines line
;
line : label T_NEWLINE
| label cpu_command T_NEWLINE
| label macro T_NEWLINE
| label directive T_NEWLINE
| assignment_directive T_NEWLINE
last_line : label
| label cpu_command
| label macro
| label directive
| assignment_directive
;
line : last_line T_NEWLINE
| line_directive /* Directives that manage newlines themselves */
| error T_NEWLINE { /* Continue parsing the next line on a syntax error */
fstk_StopRept();
@@ -951,7 +952,7 @@ ds : T_POP_DS uconst { out_Skip($2, true); }
/* Authorize empty entries if there is only one */
db : T_POP_DB constlist_8bit_entry T_COMMA constlist_8bit {
if (nListCountEmpty > 0)
if ($2 || $4)
warning(WARNING_EMPTY_ENTRY,
"Empty entry in list of 8-bit elements (treated as padding).\n");
}
@@ -959,7 +960,7 @@ db : T_POP_DB constlist_8bit_entry T_COMMA constlist_8bit {
;
dw : T_POP_DW constlist_16bit_entry T_COMMA constlist_16bit {
if (nListCountEmpty > 0)
if ($2 || $4)
warning(WARNING_EMPTY_ENTRY,
"Empty entry in list of 16-bit elements (treated as padding).\n");
}
@@ -967,7 +968,7 @@ dw : T_POP_DW constlist_16bit_entry T_COMMA constlist_16bit {
;
dl : T_POP_DL constlist_32bit_entry T_COMMA constlist_32bit {
if (nListCountEmpty > 0)
if ($2 || $4)
warning(WARNING_EMPTY_ENTRY,
"Empty entry in list of 32-bit elements (treated as padding).\n");
}
@@ -1110,56 +1111,74 @@ const_3bit : const {
;
constlist_8bit : constlist_8bit_entry
| constlist_8bit T_COMMA constlist_8bit_entry
| constlist_8bit T_COMMA constlist_8bit_entry {
$$ = $1 || $3;
}
;
constlist_8bit_entry : %empty {
out_Skip(1, false);
nListCountEmpty++;
$$ = true;
}
| reloc_8bit_no_str {
out_RelByte(&$1, false);
$$ = false;
}
| reloc_8bit_no_str { out_RelByte(&$1); }
| string {
uint8_t *output = malloc(strlen($1)); /* Cannot be larger than that */
int32_t length = charmap_Convert($1, output);
out_AbsByteGroup(output, length);
free(output);
$$ = false;
}
;
constlist_16bit : constlist_16bit_entry
| constlist_16bit T_COMMA constlist_16bit_entry
| constlist_16bit T_COMMA constlist_16bit_entry {
$$ = $1 || $3;
}
;
constlist_16bit_entry : %empty {
out_Skip(2, false);
nListCountEmpty++;
$$ = true;
}
| reloc_16bit_no_str {
out_RelWord(&$1, false);
$$ = false;
}
| reloc_16bit_no_str { out_RelWord(&$1); }
| string {
uint8_t *output = malloc(strlen($1)); /* Cannot be larger than that */
int32_t length = charmap_Convert($1, output);
out_AbsWordGroup(output, length);
free(output);
$$ = false;
}
;
constlist_32bit : constlist_32bit_entry
| constlist_32bit T_COMMA constlist_32bit_entry
| constlist_32bit T_COMMA constlist_32bit_entry {
$$ = $1 || $3;
}
;
constlist_32bit_entry : %empty {
out_Skip(4, false);
nListCountEmpty++;
$$ = true;
}
| relocexpr_no_str {
out_RelLong(&$1, false);
$$ = false;
}
| relocexpr_no_str { out_RelLong(&$1); }
| string {
uint8_t *output = malloc(strlen($1)); /* Cannot be larger than that */
int32_t length = charmap_Convert($1, output);
out_AbsLongGroup(output, length);
free(output);
$$ = false;
}
;
@@ -1500,31 +1519,31 @@ sectattrs : %empty {
;
cpu_command : { nPCOffset = 1; } z80_adc
| { nPCOffset = 1; } z80_add
| { nPCOffset = 1; } z80_and
| { nPCOffset = 1; } z80_bit
| { nPCOffset = 1; } z80_call
cpu_command : z80_adc
| z80_add
| z80_and
| z80_bit
| z80_call
| z80_ccf
| { nPCOffset = 1; } z80_cp
| z80_cp
| z80_cpl
| z80_daa
| { nPCOffset = 1; } z80_dec
| z80_dec
| z80_di
| z80_ei
| z80_halt
| z80_inc
| { nPCOffset = 1; } z80_jp
| { nPCOffset = 1; } z80_jr
| { nPCOffset = 1; } z80_ld
| z80_jp
| z80_jr
| z80_ld
| z80_ldd
| z80_ldi
| { nPCOffset = 1; } z80_ldio
| z80_ldio
| z80_nop
| { nPCOffset = 1; } z80_or
| z80_or
| z80_pop
| z80_push
| { nPCOffset = 1; } z80_res
| z80_res
| z80_ret
| z80_reti
| z80_rl
@@ -1536,41 +1555,41 @@ cpu_command : { nPCOffset = 1; } z80_adc
| z80_rrc
| z80_rrca
| /*{ nPCOffset = 0; }*/ z80_rst
| { nPCOffset = 1; } z80_sbc
| z80_sbc
| z80_scf
| { nPCOffset = 1; } z80_set
| z80_set
| z80_sla
| z80_sra
| z80_srl
| { nPCOffset = 1; } z80_stop
| { nPCOffset = 1; } z80_sub
| z80_stop
| z80_sub
| z80_swap
| { nPCOffset = 1; } z80_xor
| z80_xor
;
z80_adc : T_Z80_ADC op_a_n {
out_AbsByte(0xCE);
out_RelByte(&$2);
out_RelByte(&$2, true);
}
| T_Z80_ADC op_a_r { out_AbsByte(0x88 | $2); }
;
z80_add : T_Z80_ADD op_a_n {
out_AbsByte(0xC6);
out_RelByte(&$2);
out_RelByte(&$2, true);
}
| T_Z80_ADD op_a_r { out_AbsByte(0x80 | $2); }
| T_Z80_ADD op_hl_ss { out_AbsByte(0x09 | ($2 << 4)); }
| T_Z80_ADD T_MODE_SP T_COMMA reloc_8bit {
out_AbsByte(0xE8);
out_RelByte(&$4);
out_RelByte(&$4, true);
}
;
z80_and : T_Z80_AND op_a_n {
out_AbsByte(0xE6);
out_RelByte(&$2);
out_RelByte(&$2, true);
}
| T_Z80_AND op_a_r { out_AbsByte(0xA0 | $2); }
;
@@ -1583,11 +1602,11 @@ z80_bit : T_Z80_BIT const_3bit T_COMMA reg_r {
z80_call : T_Z80_CALL reloc_16bit {
out_AbsByte(0xCD);
out_RelWord(&$2);
out_RelWord(&$2, true);
}
| T_Z80_CALL ccode T_COMMA reloc_16bit {
out_AbsByte(0xC4 | ($2 << 3));
out_RelWord(&$4);
out_RelWord(&$4, true);
}
;
@@ -1596,7 +1615,7 @@ z80_ccf : T_Z80_CCF { out_AbsByte(0x3F); }
z80_cp : T_Z80_CP op_a_n {
out_AbsByte(0xFE);
out_RelByte(&$2);
out_RelByte(&$2, true);
}
| T_Z80_CP op_a_r { out_AbsByte(0xB8 | $2); }
;
@@ -1630,11 +1649,11 @@ z80_inc : T_Z80_INC reg_r { out_AbsByte(0x04 | ($2 << 3)); }
z80_jp : T_Z80_JP reloc_16bit {
out_AbsByte(0xC3);
out_RelWord(&$2);
out_RelWord(&$2, true);
}
| T_Z80_JP ccode T_COMMA reloc_16bit {
out_AbsByte(0xC2 | ($2 << 3));
out_RelWord(&$4);
out_RelWord(&$4, true);
}
| T_Z80_JP T_MODE_HL {
out_AbsByte(0xE9);
@@ -1643,11 +1662,11 @@ z80_jp : T_Z80_JP reloc_16bit {
z80_jr : T_Z80_JR reloc_16bit {
out_AbsByte(0x18);
out_PCRelByte(&$2);
out_PCRelByte(&$2, true);
}
| T_Z80_JR ccode T_COMMA reloc_16bit {
out_AbsByte(0x20 | ($2 << 3));
out_PCRelByte(&$4);
out_PCRelByte(&$4, true);
}
;
@@ -1671,13 +1690,13 @@ z80_ldio : T_Z80_LDH T_MODE_A T_COMMA op_mem_ind {
rpn_CheckHRAM(&$4, &$4);
out_AbsByte(0xF0);
out_RelByte(&$4);
out_RelByte(&$4, true);
}
| T_Z80_LDH op_mem_ind T_COMMA T_MODE_A {
rpn_CheckHRAM(&$2, &$2);
out_AbsByte(0xE0);
out_RelByte(&$2);
out_RelByte(&$2, true);
}
| T_Z80_LDH T_MODE_A T_COMMA c_ind {
out_AbsByte(0xF2);
@@ -1703,24 +1722,24 @@ z80_ld : z80_ld_mem
z80_ld_hl : T_Z80_LD T_MODE_HL T_COMMA T_MODE_SP reloc_8bit {
out_AbsByte(0xF8);
out_RelByte(&$5);
out_RelByte(&$5, true);
}
| T_Z80_LD T_MODE_HL T_COMMA reloc_16bit {
out_AbsByte(0x01 | (REG_HL << 4));
out_RelWord(&$4);
out_RelWord(&$4, true);
}
;
z80_ld_sp : T_Z80_LD T_MODE_SP T_COMMA T_MODE_HL { out_AbsByte(0xF9); }
| T_Z80_LD T_MODE_SP T_COMMA reloc_16bit {
out_AbsByte(0x01 | (REG_SP << 4));
out_RelWord(&$4);
out_RelWord(&$4, true);
}
;
z80_ld_mem : T_Z80_LD op_mem_ind T_COMMA T_MODE_SP {
out_AbsByte(0x08);
out_RelWord(&$2);
out_RelWord(&$2, true);
}
| T_Z80_LD op_mem_ind T_COMMA T_MODE_A {
if (optimizeloads && rpn_isKnown(&$2)
@@ -1730,7 +1749,7 @@ z80_ld_mem : T_Z80_LD op_mem_ind T_COMMA T_MODE_SP {
rpn_Free(&$2);
} else {
out_AbsByte(0xEA);
out_RelWord(&$2);
out_RelWord(&$2, true);
}
}
;
@@ -1747,7 +1766,7 @@ z80_ld_rr : T_Z80_LD reg_rr T_COMMA T_MODE_A {
z80_ld_r : T_Z80_LD reg_r T_COMMA reloc_8bit {
out_AbsByte(0x06 | ($2 << 3));
out_RelByte(&$4);
out_RelByte(&$4, true);
}
| T_Z80_LD reg_r T_COMMA reg_r {
if (($2 == REG_HL_IND) && ($4 == REG_HL_IND))
@@ -1778,7 +1797,7 @@ z80_ld_a : T_Z80_LD reg_r T_COMMA c_ind {
rpn_Free(&$4);
} else {
out_AbsByte(0xFA);
out_RelWord(&$4);
out_RelWord(&$4, true);
}
} else {
error("Destination operand must be A\n");
@@ -1789,11 +1808,11 @@ z80_ld_a : T_Z80_LD reg_r T_COMMA c_ind {
z80_ld_ss : T_Z80_LD T_MODE_BC T_COMMA reloc_16bit {
out_AbsByte(0x01 | (REG_BC << 4));
out_RelWord(&$4);
out_RelWord(&$4, true);
}
| T_Z80_LD T_MODE_DE T_COMMA reloc_16bit {
out_AbsByte(0x01 | (REG_DE << 4));
out_RelWord(&$4);
out_RelWord(&$4, true);
}
/*
* HL is taken care of in z80_ld_hl
@@ -1806,7 +1825,7 @@ z80_nop : T_Z80_NOP { out_AbsByte(0x00); }
z80_or : T_Z80_OR op_a_n {
out_AbsByte(0xF6);
out_RelByte(&$2);
out_RelByte(&$2, true);
}
| T_Z80_OR op_a_r { out_AbsByte(0xB0 | $2); }
;
@@ -1870,7 +1889,10 @@ z80_rrca : T_Z80_RRCA { out_AbsByte(0x0F); }
z80_rst : T_Z80_RST reloc_8bit {
rpn_CheckRST(&$2, &$2);
if (!rpn_isKnown(&$2))
out_RelByte(&$2);
// This could be considered as an "operand", but the purpose of the
// "operand" flag is to signal to RGBLINK to correct PC,
// which we don't want here.
out_RelByte(&$2, false);
else
out_AbsByte(0xC7 | $2.nVal);
rpn_Free(&$2);
@@ -1879,7 +1901,7 @@ z80_rst : T_Z80_RST reloc_8bit {
z80_sbc : T_Z80_SBC op_a_n {
out_AbsByte(0xDE);
out_RelByte(&$2);
out_RelByte(&$2, true);
}
| T_Z80_SBC op_a_r { out_AbsByte(0x98 | $2); }
;
@@ -1917,13 +1939,13 @@ z80_stop : T_Z80_STOP {
}
| T_Z80_STOP reloc_8bit {
out_AbsByte(0x10);
out_RelByte(&$2);
out_RelByte(&$2, true);
}
;
z80_sub : T_Z80_SUB op_a_n {
out_AbsByte(0xD6);
out_RelByte(&$2);
out_RelByte(&$2, true);
}
| T_Z80_SUB op_a_r { out_AbsByte(0x90 | $2);
}
@@ -1937,7 +1959,7 @@ z80_swap : T_Z80_SWAP reg_r {
z80_xor : T_Z80_XOR op_a_n {
out_AbsByte(0xEE);
out_RelByte(&$2);
out_RelByte(&$2, true);
}
| T_Z80_XOR op_a_r { out_AbsByte(0xA8 | $2); }
;