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

@@ -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.
*