mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-21 10:42:07 +00:00
Fix REDEF EQUS behavior
Redefining an EQUS constant will now update its filename, like redefining a SET/= constant. Attempting to redefine as EQUS a non-EQUS constant will print an appropriate error message. This also standardizes on `sym` versus `symbol` as a variable name (which pairs with `symName`).
This commit is contained in:
@@ -958,7 +958,7 @@ is used to define numerical constant symbols.
|
|||||||
Unlike
|
Unlike
|
||||||
.Ic SET
|
.Ic SET
|
||||||
below, constants defined this way cannot be redefined.
|
below, constants defined this way cannot be redefined.
|
||||||
They can, for example, be used for things such as bit definitions of hardware registers.
|
These constants can be used for unchanging values such as properties of the hardware.
|
||||||
.Bd -literal -offset indent
|
.Bd -literal -offset indent
|
||||||
def SCREEN_WIDTH equ 160 ;\ In pixels
|
def SCREEN_WIDTH equ 160 ;\ In pixels
|
||||||
def SCREEN_HEIGHT equ 144
|
def SCREEN_HEIGHT equ 144
|
||||||
@@ -1075,7 +1075,7 @@ For example:
|
|||||||
DEF s EQUS "Hello, "
|
DEF s EQUS "Hello, "
|
||||||
REDEF s EQUS "{s}world!"
|
REDEF s EQUS "{s}world!"
|
||||||
; prints "Hello, world!"
|
; prints "Hello, world!"
|
||||||
PRINTT "{s}\n"
|
PRINTLN "{s}\n"
|
||||||
.Ed
|
.Ed
|
||||||
.Pp
|
.Pp
|
||||||
.Sy Important note :
|
.Sy Important note :
|
||||||
|
|||||||
@@ -51,16 +51,16 @@ bool sym_IsPC(struct Symbol const *sym)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct ForEachArgs {
|
struct ForEachArgs {
|
||||||
void (*func)(struct Symbol *symbol, void *arg);
|
void (*func)(struct Symbol *sym, void *arg);
|
||||||
void *arg;
|
void *arg;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void forEachWrapper(void *_symbol, void *_argWrapper)
|
static void forEachWrapper(void *_sym, void *_argWrapper)
|
||||||
{
|
{
|
||||||
struct ForEachArgs *argWrapper = _argWrapper;
|
struct ForEachArgs *argWrapper = _argWrapper;
|
||||||
struct Symbol *symbol = _symbol;
|
struct Symbol *sym = _sym;
|
||||||
|
|
||||||
argWrapper->func(symbol, argWrapper->arg);
|
argWrapper->func(sym, argWrapper->arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sym_ForEach(void (*func)(struct Symbol *, void *), void *arg)
|
void sym_ForEach(void (*func)(struct Symbol *, void *), void *arg)
|
||||||
@@ -181,24 +181,24 @@ static void updateSymbolFilename(struct Symbol *sym)
|
|||||||
*/
|
*/
|
||||||
static struct Symbol *createsymbol(char const *symName)
|
static struct Symbol *createsymbol(char const *symName)
|
||||||
{
|
{
|
||||||
struct Symbol *symbol = malloc(sizeof(*symbol));
|
struct Symbol *sym = malloc(sizeof(*sym));
|
||||||
|
|
||||||
if (!symbol)
|
if (!sym)
|
||||||
fatalerror("Failed to create symbol '%s': %s\n", symName, strerror(errno));
|
fatalerror("Failed to create symbol '%s': %s\n", symName, strerror(errno));
|
||||||
|
|
||||||
if (snprintf(symbol->name, MAXSYMLEN + 1, "%s", symName) > MAXSYMLEN)
|
if (snprintf(sym->name, MAXSYMLEN + 1, "%s", symName) > MAXSYMLEN)
|
||||||
warning(WARNING_LONG_STR, "Symbol name is too long: '%s'\n", symName);
|
warning(WARNING_LONG_STR, "Symbol name is too long: '%s'\n", symName);
|
||||||
|
|
||||||
symbol->isExported = false;
|
sym->isExported = false;
|
||||||
symbol->isBuiltin = false;
|
sym->isBuiltin = false;
|
||||||
symbol->hasCallback = false;
|
sym->hasCallback = false;
|
||||||
symbol->section = NULL;
|
sym->section = NULL;
|
||||||
setSymbolFilename(symbol);
|
setSymbolFilename(sym);
|
||||||
symbol->ID = -1;
|
sym->ID = -1;
|
||||||
symbol->next = NULL;
|
sym->next = NULL;
|
||||||
|
|
||||||
hash_AddElement(symbols, symbol->name, symbol);
|
hash_AddElement(symbols, sym->name, sym);
|
||||||
return symbol;
|
return sym;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -220,7 +220,7 @@ static void assignStringSymbol(struct Symbol *sym, char const *value)
|
|||||||
{
|
{
|
||||||
char *string = strdup(value);
|
char *string = strdup(value);
|
||||||
|
|
||||||
if (string == NULL)
|
if (!string)
|
||||||
fatalerror("No memory for string equate: %s\n", strerror(errno));
|
fatalerror("No memory for string equate: %s\n", strerror(errno));
|
||||||
|
|
||||||
sym->type = SYM_EQUS;
|
sym->type = SYM_EQUS;
|
||||||
@@ -276,27 +276,26 @@ static bool isReferenced(struct Symbol const *sym)
|
|||||||
*/
|
*/
|
||||||
void sym_Purge(char const *symName)
|
void sym_Purge(char const *symName)
|
||||||
{
|
{
|
||||||
struct Symbol *symbol = sym_FindScopedSymbol(symName);
|
struct Symbol *sym = sym_FindScopedSymbol(symName);
|
||||||
|
|
||||||
if (!symbol) {
|
if (!sym) {
|
||||||
error("'%s' not defined\n", symName);
|
error("'%s' not defined\n", symName);
|
||||||
} else if (symbol->isBuiltin) {
|
} else if (sym->isBuiltin) {
|
||||||
error("Built-in symbol '%s' cannot be purged\n", symName);
|
error("Built-in symbol '%s' cannot be purged\n", symName);
|
||||||
} else if (isReferenced(symbol)) {
|
} else if (isReferenced(sym)) {
|
||||||
error("Symbol \"%s\" is referenced and thus cannot be purged\n", symName);
|
error("Symbol \"%s\" is referenced and thus cannot be purged\n", symName);
|
||||||
} else {
|
} else {
|
||||||
/* Do not keep a reference to the label's name after purging it */
|
/* Do not keep a reference to the label's name after purging it */
|
||||||
if (symbol->name == labelScope)
|
if (sym->name == labelScope)
|
||||||
sym_SetCurrentSymbolScope(NULL);
|
sym_SetCurrentSymbolScope(NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FIXME: this leaks symbol->macro for SYM_EQUS and SYM_MACRO, but this can't
|
* FIXME: this leaks sym->macro for SYM_EQUS and SYM_MACRO, but this can't
|
||||||
* free(symbol->macro) because the expansion may be purging itself.
|
* free(sym->macro) because the expansion may be purging itself.
|
||||||
*/
|
*/
|
||||||
|
hash_RemoveElement(symbols, sym->name);
|
||||||
hash_RemoveElement(symbols, symbol->name);
|
|
||||||
/* TODO: ideally, also unref the file stack nodes */
|
/* TODO: ideally, also unref the file stack nodes */
|
||||||
free(symbol);
|
free(sym);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,7 +334,7 @@ uint32_t sym_GetConstantValue(char const *symName)
|
|||||||
{
|
{
|
||||||
struct Symbol const *sym = sym_FindScopedSymbol(symName);
|
struct Symbol const *sym = sym_FindScopedSymbol(symName);
|
||||||
|
|
||||||
if (sym == NULL)
|
if (!sym)
|
||||||
error("'%s' not defined\n", symName);
|
error("'%s' not defined\n", symName);
|
||||||
else
|
else
|
||||||
return sym_GetConstantSymValue(sym);
|
return sym_GetConstantSymValue(sym);
|
||||||
@@ -362,24 +361,24 @@ void sym_SetCurrentSymbolScope(char const *newScope)
|
|||||||
*/
|
*/
|
||||||
static struct Symbol *createNonrelocSymbol(char const *symName, bool numeric)
|
static struct Symbol *createNonrelocSymbol(char const *symName, bool numeric)
|
||||||
{
|
{
|
||||||
struct Symbol *symbol = sym_FindExactSymbol(symName);
|
struct Symbol *sym = sym_FindExactSymbol(symName);
|
||||||
|
|
||||||
if (!symbol) {
|
if (!sym) {
|
||||||
symbol = createsymbol(symName);
|
sym = createsymbol(symName);
|
||||||
} else if (sym_IsDefined(symbol)) {
|
} else if (sym_IsDefined(sym)) {
|
||||||
error("'%s' already defined at ", symName);
|
error("'%s' already defined at ", symName);
|
||||||
dumpFilename(symbol);
|
dumpFilename(sym);
|
||||||
putc('\n', stderr);
|
putc('\n', stderr);
|
||||||
return NULL; // Don't allow overriding the symbol, that'd be bad!
|
return NULL; // Don't allow overriding the symbol, that'd be bad!
|
||||||
} else if (!numeric) {
|
} else if (!numeric) {
|
||||||
// The symbol has already been referenced, but it's not allowed
|
// The symbol has already been referenced, but it's not allowed
|
||||||
error("'%s' already referenced at ", symName);
|
error("'%s' already referenced at ", symName);
|
||||||
dumpFilename(symbol);
|
dumpFilename(sym);
|
||||||
putc('\n', stderr);
|
putc('\n', stderr);
|
||||||
return NULL; // Don't allow overriding the symbol, that'd be bad!
|
return NULL; // Don't allow overriding the symbol, that'd be bad!
|
||||||
}
|
}
|
||||||
|
|
||||||
return symbol;
|
return sym;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -425,10 +424,14 @@ struct Symbol *sym_RedefString(char const *symName, char const *value)
|
|||||||
{
|
{
|
||||||
struct Symbol *sym = sym_FindExactSymbol(symName);
|
struct Symbol *sym = sym_FindExactSymbol(symName);
|
||||||
|
|
||||||
if (!sym) {
|
if (!sym)
|
||||||
sym = createsymbol(symName);
|
return sym_AddString(symName, value);
|
||||||
} else if (sym->type != SYM_EQUS) {
|
|
||||||
error("'%s' already defined as non-EQUS at ", symName);
|
if (sym->type != SYM_EQUS) {
|
||||||
|
if (sym_IsDefined(sym))
|
||||||
|
error("'%s' already defined as non-EQUS at ", symName);
|
||||||
|
else
|
||||||
|
error("'%s' already referenced at ", symName);
|
||||||
dumpFilename(sym);
|
dumpFilename(sym);
|
||||||
putc('\n', stderr);
|
putc('\n', stderr);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -437,11 +440,11 @@ struct Symbol *sym_RedefString(char const *symName, char const *value)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateSymbolFilename(sym);
|
||||||
/*
|
/*
|
||||||
* FIXME: this leaks the previous sym->macro value, but this can't
|
* FIXME: this leaks the previous sym->macro value, but this can't
|
||||||
* free(sym->macro) because the expansion may be redefining itself.
|
* free(sym->macro) because the expansion may be redefining itself.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
assignStringSymbol(sym, value);
|
assignStringSymbol(sym, value);
|
||||||
|
|
||||||
return sym;
|
return sym;
|
||||||
@@ -454,7 +457,7 @@ struct Symbol *sym_AddSet(char const *symName, int32_t value)
|
|||||||
{
|
{
|
||||||
struct Symbol *sym = sym_FindExactSymbol(symName);
|
struct Symbol *sym = sym_FindExactSymbol(symName);
|
||||||
|
|
||||||
if (sym == NULL) {
|
if (!sym) {
|
||||||
sym = createsymbol(symName);
|
sym = createsymbol(symName);
|
||||||
} else if (sym_IsDefined(sym) && sym->type != SYM_SET) {
|
} else if (sym_IsDefined(sym) && sym->type != SYM_SET) {
|
||||||
error("'%s' already defined as %s at ",
|
error("'%s' already defined as %s at ",
|
||||||
@@ -650,9 +653,9 @@ struct Symbol *sym_AddMacro(char const *symName, int32_t defLineNo, char *body,
|
|||||||
*/
|
*/
|
||||||
struct Symbol *sym_Ref(char const *symName)
|
struct Symbol *sym_Ref(char const *symName)
|
||||||
{
|
{
|
||||||
struct Symbol *nsym = sym_FindScopedSymbol(symName);
|
struct Symbol *sym = sym_FindScopedSymbol(symName);
|
||||||
|
|
||||||
if (nsym == NULL) {
|
if (!sym) {
|
||||||
char fullname[MAXSYMLEN + 1];
|
char fullname[MAXSYMLEN + 1];
|
||||||
|
|
||||||
if (symName[0] == '.') {
|
if (symName[0] == '.') {
|
||||||
@@ -662,11 +665,11 @@ struct Symbol *sym_Ref(char const *symName)
|
|||||||
symName = fullname;
|
symName = fullname;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsym = createsymbol(symName);
|
sym = createsymbol(symName);
|
||||||
nsym->type = SYM_REF;
|
sym->type = SYM_REF;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nsym;
|
return sym;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Reference in New Issue
Block a user