ref: 8e4ba8d2e436a985c77e08212b65dd31157dea3f
parent: ee67f1039cf8a690263dbf485b0c1720341b67d0
author: Rangi <[email protected]>
date: Sun Apr 25 17:06:19 EDT 2021
Allow REDEF for EQU constants Fixes #853
--- a/include/asm/symbol.h
+++ b/include/asm/symbol.h
@@ -120,6 +120,7 @@
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);
--- a/src/asm/parser.y
+++ b/src/asm/parser.y
@@ -851,6 +851,7 @@
| warn
| assert
| def_equ
+ | redef_equ
| def_set
| def_rb
| def_rw
@@ -1115,6 +1116,11 @@
def_equ : def_id T_POP_EQU const {
sym_AddEqu($1, $3);
+ }
+;
+
+redef_equ : redef_id T_POP_EQU const {
+ sym_RedefEqu($1, $3);
}
;
--- a/src/asm/rgbasm.5
+++ b/src/asm/rgbasm.5
@@ -967,6 +967,26 @@
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
--- a/src/asm/symbol.c
+++ b/src/asm/symbol.c
@@ -397,6 +397,30 @@
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.
*
--- a/test/asm/def.asm
+++ b/test/asm/def.asm
@@ -26,4 +26,5 @@
redef string equs "there"
println "{string}"
-redef constant equ 6*9 ; syntax error
+redef constant equ 6*9
+ println constant
--- a/test/asm/def.err
+++ b/test/asm/def.err
@@ -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)!
--- a/test/asm/def.out
+++ b/test/asm/def.out
@@ -7,3 +7,4 @@
$0 $1 $5 $9
$2A
there
+$36
--- /dev/null
+++ b/test/asm/redef-equ.asm
@@ -1,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
--- /dev/null
+++ b/test/asm/redef-equ.err
@@ -1,0 +1,3 @@
+ERROR: redef-equ.asm(23):
+ 'N' already defined as non-EQU at redef-equ.asm(22)
+error: Assembly aborted (1 error)!
--- /dev/null
+++ b/test/asm/redef-equ.out
@@ -1,0 +1,2 @@
+$1
+$3$1$4$9
--- /dev/null
+++ b/test/asm/reference-undefined-equs.asm
@@ -1,0 +1,5 @@
+SECTION "sec", ROM0[0]
+ db s1, s2
+
+def s1 equs "1"
+redef s2 equs "2"
--- /dev/null
+++ b/test/asm/reference-undefined-equs.err
@@ -1,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)!
--- a/test/asm/reference-undefined-sym.asm
+++ b/test/asm/reference-undefined-sym.asm
@@ -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
--- a/test/asm/reference-undefined-sym.out.bin
+++ b/test/asm/reference-undefined-sym.out.bin
@@ -1,0 +1,1 @@
+
\ No newline at end of file