Skip to content

Commit

Permalink
Allow REDEF for EQU constants
Browse files Browse the repository at this point in the history
Fixes gbdev#853
  • Loading branch information
Rangi42 authored and ISSOtm committed Apr 29, 2021
1 parent ee67f10 commit 8e4ba8d
Show file tree
Hide file tree
Showing 15 changed files with 99 additions and 6 deletions.
1 change: 1 addition & 0 deletions include/asm/symbol.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
6 changes: 6 additions & 0 deletions src/asm/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -851,6 +851,7 @@ directive : endc
| warn
| assert
| def_equ
| redef_equ
| def_set
| def_rb
| def_rw
Expand Down Expand Up @@ -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);
}
Expand Down
20 changes: 20 additions & 0 deletions src/asm/rgbasm.5
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
24 changes: 24 additions & 0 deletions src/asm/symbol.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down
3 changes: 2 additions & 1 deletion test/asm/def.asm
Original file line number Diff line number Diff line change
Expand Up @@ -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
4 changes: 1 addition & 3 deletions test/asm/def.err
Original file line number Diff line number Diff line change
@@ -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)!
1 change: 1 addition & 0 deletions test/asm/def.out
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ here
$0 $1 $5 $9
$2A
there
$36
23 changes: 23 additions & 0 deletions test/asm/redef-equ.asm
Original file line number Diff line number Diff line change
@@ -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 changes: 3 additions & 0 deletions test/asm/redef-equ.err
Original file line number Diff line number Diff line change
@@ -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 changes: 2 additions & 0 deletions test/asm/redef-equ.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
$1
$3$1$4$9
5 changes: 5 additions & 0 deletions test/asm/reference-undefined-equs.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
SECTION "sec", ROM0[0]
db s1, s2

def s1 equs "1"
redef s2 equs "2"
5 changes: 5 additions & 0 deletions test/asm/reference-undefined-equs.err
Original file line number Diff line number Diff line change
@@ -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)!
Empty file.
7 changes: 5 additions & 2 deletions test/asm/reference-undefined-sym.asm
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions test/asm/reference-undefined-sym.out.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@


0 comments on commit 8e4ba8d

Please sign in to comment.