Allow REDEF for EQU constants

Fixes #853
This commit is contained in:
Rangi
2021-04-25 21:06:19 -04:00
committed by Eldred Habert
parent ee67f1039c
commit 8e4ba8d2e4
15 changed files with 99 additions and 6 deletions

View File

@@ -120,6 +120,7 @@ struct Symbol *sym_AddAnonLabel(void);
void sym_WriteAnonLabelName(char buf[MIN_NB_ELMS(MAXSYMLEN + 1)], uint32_t ofs, bool neg);
void sym_Export(char const *symName);
struct Symbol *sym_AddEqu(char const *symName, int32_t value);
struct Symbol *sym_RedefEqu(char const *symName, int32_t value);
struct Symbol *sym_AddSet(char const *symName, int32_t value);
uint32_t sym_GetPCValue(void);
uint32_t sym_GetConstantSymValue(struct Symbol const *sym);

View File

@@ -851,6 +851,7 @@ directive : endc
| warn
| assert
| def_equ
| redef_equ
| def_set
| def_rb
| def_rw
@@ -1118,6 +1119,11 @@ def_equ : def_id T_POP_EQU const {
}
;
redef_equ : redef_id T_POP_EQU const {
sym_RedefEqu($1, $3);
}
;
def_set : def_id set_or_equal const {
sym_AddSet($1, $3);
}

View File

@@ -967,6 +967,26 @@ def SCREEN_HEIGHT equ 144
Note that colons
.Ql \&:
following the name are not allowed.
.Pp
If you
.Em really
need to, the
.Ic REDEF
keyword will define or redefine a constant symbol.
This can be used, for example, to update a constant using a macro, without making it mutable in general.
.Bd -literal -offset indent
def NUM_ITEMS equ 0
MACRO add_item
redef NUM_ITEMS equ NUM_ITEMS + 1
def ITEM_{02x:NUM_ITEMS} equ \1
ENDM
add_item 1
add_item 4
add_item 9
add_item 16
assert NUM_ITEMS == 4
assert ITEM_04 == 16
.Ed
.Ss Mutable constants
.Ic SET ,
or its synonym

View File

@@ -397,6 +397,30 @@ struct Symbol *sym_AddEqu(char const *symName, int32_t value)
return sym;
}
struct Symbol *sym_RedefEqu(char const *symName, int32_t value)
{
struct Symbol *sym = sym_FindExactSymbol(symName);
if (!sym)
return sym_AddEqu(symName, value);
if (sym_IsDefined(sym) && sym->type != SYM_EQU) {
error("'%s' already defined as non-EQU at ", symName);
dumpFilename(sym);
putc('\n', stderr);
return NULL;
} else if (sym->isBuiltin) {
error("Built-in symbol '%s' cannot be redefined\n", symName);
return NULL;
}
updateSymbolFilename(sym);
sym->type = SYM_EQU;
sym->value = value;
return sym;
}
/*
* Add a string equated symbol.
*

View File

@@ -26,4 +26,5 @@ def constant equ 6*7 ; fails
redef string equs "there"
println "{string}"
redef constant equ 6*9 ; syntax error
redef constant equ 6*9
println constant

View File

@@ -1,5 +1,3 @@
ERROR: def.asm(23):
'constant' already defined at def.asm(10)
ERROR: def.asm(29):
syntax error, unexpected EQU, expecting SET or = or EQUS
error: Assembly aborted (2 errors)!
error: Assembly aborted (1 error)!

View File

@@ -7,3 +7,4 @@ here
$0 $1 $5 $9
$2A
there
$36

23
test/asm/redef-equ.asm Normal file
View File

@@ -0,0 +1,23 @@
DEF n EQU 0
REDEF n EQU 1
; prints "$1"
PRINTLN n
list: MACRO
LIST_NAME EQUS "\1"
DEF LENGTH_{LIST_NAME} EQU 0
ENDM
item: MACRO
REDEF LENGTH_{LIST_NAME} EQU LENGTH_{LIST_NAME} + 1
DEF {LIST_NAME}_{d:LENGTH_{LIST_NAME}} EQU \1
ENDM
list SQUARES
item 1
item 4
item 9
println LENGTH_SQUARES, SQUARES_1, SQUARES_2, SQUARES_3
N EQUS "X"
REDEF N EQU 42

3
test/asm/redef-equ.err Normal file
View File

@@ -0,0 +1,3 @@
ERROR: redef-equ.asm(23):
'N' already defined as non-EQU at redef-equ.asm(22)
error: Assembly aborted (1 error)!

2
test/asm/redef-equ.out Normal file
View File

@@ -0,0 +1,2 @@
$1
$3$1$4$9

View File

@@ -0,0 +1,5 @@
SECTION "sec", ROM0[0]
db s1, s2
def s1 equs "1"
redef s2 equs "2"

View File

@@ -0,0 +1,5 @@
ERROR: reference-undefined-equs.asm(4):
's1' already referenced at reference-undefined-equs.asm(2)
ERROR: reference-undefined-equs.asm(5):
's2' already referenced at reference-undefined-equs.asm(2)
error: Assembly aborted (2 errors)!

View File

View File

@@ -1,4 +1,7 @@
SECTION "sec", ROM0[0]
db X
db x1, x2, y1, y2
X = 2
def x1 = 1
redef x2 = 2
def y1 equ 3
redef y2 equ 4

View File

@@ -0,0 +1 @@