mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +00:00
Only define @ and _NARG when they have values (#1073)
Fixes #1069 Co-authored-by: Eldred Habert <eldredhabert0@gmail.com>
This commit is contained in:
@@ -127,6 +127,8 @@ struct Symbol *sym_FindExactSymbol(char const *symName);
|
|||||||
struct Symbol *sym_FindUnscopedSymbol(char const *symName);
|
struct Symbol *sym_FindUnscopedSymbol(char const *symName);
|
||||||
// Find a symbol, possibly scoped, by name
|
// Find a symbol, possibly scoped, by name
|
||||||
struct Symbol *sym_FindScopedSymbol(char const *symName);
|
struct Symbol *sym_FindScopedSymbol(char const *symName);
|
||||||
|
// Find a scoped symbol by name; do not return `@` or `_NARG` when they have no value
|
||||||
|
struct Symbol *sym_FindScopedValidSymbol(char const *symName);
|
||||||
struct Symbol const *sym_GetPC(void);
|
struct Symbol const *sym_GetPC(void);
|
||||||
struct Symbol *sym_AddMacro(char const *symName, int32_t defLineNo, char *body, size_t size);
|
struct Symbol *sym_AddMacro(char const *symName, int32_t defLineNo, char *body, size_t size);
|
||||||
struct Symbol *sym_Ref(char const *symName);
|
struct Symbol *sym_Ref(char const *symName);
|
||||||
|
|||||||
@@ -733,7 +733,7 @@ static uint32_t readBracketedMacroArgNum(void)
|
|||||||
}
|
}
|
||||||
symName[i] = '\0';
|
symName[i] = '\0';
|
||||||
|
|
||||||
struct Symbol const *sym = sym_FindScopedSymbol(symName);
|
struct Symbol const *sym = sym_FindScopedValidSymbol(symName);
|
||||||
|
|
||||||
if (!sym) {
|
if (!sym) {
|
||||||
error("Bracketed symbol \"%s\" does not exist\n", symName);
|
error("Bracketed symbol \"%s\" does not exist\n", symName);
|
||||||
@@ -1400,7 +1400,7 @@ static char const *readInterpolation(size_t depth)
|
|||||||
|
|
||||||
static char buf[MAXSTRLEN + 1];
|
static char buf[MAXSTRLEN + 1];
|
||||||
|
|
||||||
struct Symbol const *sym = sym_FindScopedSymbol(symName);
|
struct Symbol const *sym = sym_FindScopedValidSymbol(symName);
|
||||||
|
|
||||||
if (!sym) {
|
if (!sym) {
|
||||||
error("Interpolated symbol \"%s\" does not exist\n", symName);
|
error("Interpolated symbol \"%s\" does not exist\n", symName);
|
||||||
|
|||||||
@@ -1462,9 +1462,7 @@ relocexpr_no_str : scoped_anon_id { rpn_Symbol(&$$, $1); }
|
|||||||
| T_OP_DEF {
|
| T_OP_DEF {
|
||||||
lexer_ToggleStringExpansion(false);
|
lexer_ToggleStringExpansion(false);
|
||||||
} T_LPAREN scoped_anon_id T_RPAREN {
|
} T_LPAREN scoped_anon_id T_RPAREN {
|
||||||
struct Symbol const *sym = sym_FindScopedSymbol($4);
|
rpn_Number(&$$, sym_FindScopedValidSymbol($4) != NULL);
|
||||||
|
|
||||||
rpn_Number(&$$, !!sym);
|
|
||||||
|
|
||||||
lexer_ToggleStringExpansion(true);
|
lexer_ToggleStringExpansion(true);
|
||||||
}
|
}
|
||||||
@@ -1590,7 +1588,7 @@ string : T_STRING
|
|||||||
freeStrFmtArgList(&$3);
|
freeStrFmtArgList(&$3);
|
||||||
}
|
}
|
||||||
| T_POP_SECTION T_LPAREN scoped_anon_id T_RPAREN {
|
| T_POP_SECTION T_LPAREN scoped_anon_id T_RPAREN {
|
||||||
struct Symbol *sym = sym_FindScopedSymbol($3);
|
struct Symbol *sym = sym_FindScopedValidSymbol($3);
|
||||||
|
|
||||||
if (!sym)
|
if (!sym)
|
||||||
fatalerror("Unknown symbol \"%s\"\n", $3);
|
fatalerror("Unknown symbol \"%s\"\n", $3);
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ HashMap symbols;
|
|||||||
|
|
||||||
static const char *labelScope; // Current section's label scope
|
static const char *labelScope; // Current section's label scope
|
||||||
static struct Symbol *PCSymbol;
|
static struct Symbol *PCSymbol;
|
||||||
|
static struct Symbol *_NARGSymbol;
|
||||||
static char savedTIME[256];
|
static char savedTIME[256];
|
||||||
static char savedDATE[256];
|
static char savedDATE[256];
|
||||||
static char savedTIMESTAMP_ISO8601_LOCAL[256];
|
static char savedTIMESTAMP_ISO8601_LOCAL[256];
|
||||||
@@ -250,6 +251,21 @@ struct Symbol *sym_FindScopedSymbol(char const *symName)
|
|||||||
return sym_FindExactSymbol(symName);
|
return sym_FindExactSymbol(symName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Symbol *sym_FindScopedValidSymbol(char const *symName)
|
||||||
|
{
|
||||||
|
struct Symbol *sym = sym_FindScopedSymbol(symName);
|
||||||
|
|
||||||
|
// `@` has no value outside a section
|
||||||
|
if (sym == PCSymbol && !sect_GetSymbolSection()) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// `_NARG` has no value outside a macro
|
||||||
|
if (sym == _NARGSymbol && !macro_GetCurrentArgs()) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return sym;
|
||||||
|
}
|
||||||
|
|
||||||
struct Symbol const *sym_GetPC(void)
|
struct Symbol const *sym_GetPC(void)
|
||||||
{
|
{
|
||||||
return PCSymbol;
|
return PCSymbol;
|
||||||
@@ -263,7 +279,7 @@ static bool isReferenced(struct Symbol const *sym)
|
|||||||
// Purge a symbol
|
// Purge a symbol
|
||||||
void sym_Purge(char const *symName)
|
void sym_Purge(char const *symName)
|
||||||
{
|
{
|
||||||
struct Symbol *sym = sym_FindScopedSymbol(symName);
|
struct Symbol *sym = sym_FindScopedValidSymbol(symName);
|
||||||
|
|
||||||
if (!sym) {
|
if (!sym) {
|
||||||
error("'%s' not defined\n", symName);
|
error("'%s' not defined\n", symName);
|
||||||
@@ -682,7 +698,7 @@ static struct Symbol *createBuiltinSymbol(char const *symName)
|
|||||||
void sym_Init(time_t now)
|
void sym_Init(time_t now)
|
||||||
{
|
{
|
||||||
PCSymbol = createBuiltinSymbol("@");
|
PCSymbol = createBuiltinSymbol("@");
|
||||||
struct Symbol *_NARGSymbol = createBuiltinSymbol("_NARG");
|
_NARGSymbol = createBuiltinSymbol("_NARG");
|
||||||
// __LINE__ is deprecated
|
// __LINE__ is deprecated
|
||||||
struct Symbol *__LINE__Symbol = createBuiltinSymbol("__LINE__");
|
struct Symbol *__LINE__Symbol = createBuiltinSymbol("__LINE__");
|
||||||
// __FILE__ is deprecated
|
// __FILE__ is deprecated
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
if "{@}"
|
|
||||||
endc
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
error: if@-no-sect.asm(1):
|
|
||||||
PC has no value outside a section
|
|
||||||
warning: if@-no-sect.asm(1): [-Wnumeric-string]
|
|
||||||
Treating 2-character string as a number
|
|
||||||
error: Assembly aborted (1 error)!
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
PRINTLN "{_NARG}"
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
error: narg-nosect.asm(1):
|
|
||||||
_NARG does not make sense outside of a macro
|
|
||||||
error: Assembly aborted (1 error)!
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
$0
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
IF DEF(@)
|
|
||||||
PRINTLN "defined"
|
|
||||||
ELSE
|
|
||||||
PRINTLN "not defined"
|
|
||||||
ENDC
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
defined
|
|
||||||
21
test/asm/undefined-builtins.asm
Normal file
21
test/asm/undefined-builtins.asm
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
; not inside a section
|
||||||
|
assert !DEF(@)
|
||||||
|
println @
|
||||||
|
println "{@}?"
|
||||||
|
|
||||||
|
; not inside a macro
|
||||||
|
assert !DEF(_NARG)
|
||||||
|
println _NARG
|
||||||
|
println "{_NARG}?"
|
||||||
|
|
||||||
|
SECTION "s", ROM0[$42]
|
||||||
|
assert DEF(@)
|
||||||
|
println @
|
||||||
|
println "{@}!"
|
||||||
|
|
||||||
|
MACRO m
|
||||||
|
assert DEF(_NARG)
|
||||||
|
println _NARG
|
||||||
|
println "{_NARG}!"
|
||||||
|
ENDM
|
||||||
|
m 1, 2, 3
|
||||||
9
test/asm/undefined-builtins.err
Normal file
9
test/asm/undefined-builtins.err
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
error: undefined-builtins.asm(3):
|
||||||
|
PC has no value outside a section
|
||||||
|
error: undefined-builtins.asm(4):
|
||||||
|
Interpolated symbol "@" does not exist
|
||||||
|
error: undefined-builtins.asm(8):
|
||||||
|
_NARG does not make sense outside of a macro
|
||||||
|
error: undefined-builtins.asm(9):
|
||||||
|
Interpolated symbol "_NARG" does not exist
|
||||||
|
error: Assembly aborted (4 errors)!
|
||||||
8
test/asm/undefined-builtins.out
Normal file
8
test/asm/undefined-builtins.out
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
$0
|
||||||
|
?
|
||||||
|
$0
|
||||||
|
?
|
||||||
|
$42
|
||||||
|
$42!
|
||||||
|
$3
|
||||||
|
$3!
|
||||||
Reference in New Issue
Block a user