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:
Rangi
2021-04-28 12:11:26 -04:00
parent d37aa93a7d
commit ee67f1039c
2 changed files with 51 additions and 48 deletions

View File

@@ -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 :

View File

@@ -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) {
if (sym->type != SYM_EQUS) {
if (sym_IsDefined(sym))
error("'%s' already defined as non-EQUS at ", symName); 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;
} }
/* /*