From ee67f1039cf8a690263dbf485b0c1720341b67d0 Mon Sep 17 00:00:00 2001 From: Rangi Date: Wed, 28 Apr 2021 12:11:26 -0400 Subject: [PATCH] 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`). --- src/asm/rgbasm.5 | 4 +- src/asm/symbol.c | 95 +++++++++++++++++++++++++----------------------- 2 files changed, 51 insertions(+), 48 deletions(-) diff --git a/src/asm/rgbasm.5 b/src/asm/rgbasm.5 index 8c57f385..08620606 100644 --- a/src/asm/rgbasm.5 +++ b/src/asm/rgbasm.5 @@ -958,7 +958,7 @@ is used to define numerical constant symbols. Unlike .Ic SET 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 def SCREEN_WIDTH equ 160 ;\ In pixels def SCREEN_HEIGHT equ 144 @@ -1075,7 +1075,7 @@ For example: DEF s EQUS "Hello, " REDEF s EQUS "{s}world!" ; prints "Hello, world!" -PRINTT "{s}\n" +PRINTLN "{s}\n" .Ed .Pp .Sy Important note : diff --git a/src/asm/symbol.c b/src/asm/symbol.c index 55f5e30c..3982e472 100644 --- a/src/asm/symbol.c +++ b/src/asm/symbol.c @@ -51,16 +51,16 @@ bool sym_IsPC(struct Symbol const *sym) } struct ForEachArgs { - void (*func)(struct Symbol *symbol, void *arg); + void (*func)(struct Symbol *sym, void *arg); void *arg; }; -static void forEachWrapper(void *_symbol, void *_argWrapper) +static void forEachWrapper(void *_sym, void *_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) @@ -181,24 +181,24 @@ static void updateSymbolFilename(struct Symbol *sym) */ 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)); - 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); - symbol->isExported = false; - symbol->isBuiltin = false; - symbol->hasCallback = false; - symbol->section = NULL; - setSymbolFilename(symbol); - symbol->ID = -1; - symbol->next = NULL; + sym->isExported = false; + sym->isBuiltin = false; + sym->hasCallback = false; + sym->section = NULL; + setSymbolFilename(sym); + sym->ID = -1; + sym->next = NULL; - hash_AddElement(symbols, symbol->name, symbol); - return symbol; + hash_AddElement(symbols, sym->name, sym); + return sym; } /* @@ -220,7 +220,7 @@ static void assignStringSymbol(struct Symbol *sym, char const *value) { char *string = strdup(value); - if (string == NULL) + if (!string) fatalerror("No memory for string equate: %s\n", strerror(errno)); sym->type = SYM_EQUS; @@ -276,27 +276,26 @@ static bool isReferenced(struct Symbol const *sym) */ 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); - } else if (symbol->isBuiltin) { + } else if (sym->isBuiltin) { 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); } else { /* Do not keep a reference to the label's name after purging it */ - if (symbol->name == labelScope) + if (sym->name == labelScope) sym_SetCurrentSymbolScope(NULL); /* - * FIXME: this leaks symbol->macro for SYM_EQUS and SYM_MACRO, but this can't - * free(symbol->macro) because the expansion may be purging itself. + * FIXME: this leaks sym->macro for SYM_EQUS and SYM_MACRO, but this can't + * free(sym->macro) because the expansion may be purging itself. */ - - hash_RemoveElement(symbols, symbol->name); + hash_RemoveElement(symbols, sym->name); /* 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); - if (sym == NULL) + if (!sym) error("'%s' not defined\n", symName); else return sym_GetConstantSymValue(sym); @@ -362,24 +361,24 @@ void sym_SetCurrentSymbolScope(char const *newScope) */ static struct Symbol *createNonrelocSymbol(char const *symName, bool numeric) { - struct Symbol *symbol = sym_FindExactSymbol(symName); + struct Symbol *sym = sym_FindExactSymbol(symName); - if (!symbol) { - symbol = createsymbol(symName); - } else if (sym_IsDefined(symbol)) { + if (!sym) { + sym = createsymbol(symName); + } else if (sym_IsDefined(sym)) { error("'%s' already defined at ", symName); - dumpFilename(symbol); + dumpFilename(sym); putc('\n', stderr); return NULL; // Don't allow overriding the symbol, that'd be bad! } else if (!numeric) { // The symbol has already been referenced, but it's not allowed error("'%s' already referenced at ", symName); - dumpFilename(symbol); + dumpFilename(sym); putc('\n', stderr); 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); - if (!sym) { - sym = createsymbol(symName); - } else if (sym->type != SYM_EQUS) { - error("'%s' already defined as non-EQUS at ", symName); + if (!sym) + return sym_AddString(symName, value); + + 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); putc('\n', stderr); return NULL; @@ -437,11 +440,11 @@ struct Symbol *sym_RedefString(char const *symName, char const *value) return NULL; } + updateSymbolFilename(sym); /* * FIXME: this leaks the previous sym->macro value, but this can't * free(sym->macro) because the expansion may be redefining itself. */ - assignStringSymbol(sym, value); return sym; @@ -454,7 +457,7 @@ struct Symbol *sym_AddSet(char const *symName, int32_t value) { struct Symbol *sym = sym_FindExactSymbol(symName); - if (sym == NULL) { + if (!sym) { sym = createsymbol(symName); } else if (sym_IsDefined(sym) && sym->type != SYM_SET) { 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 *nsym = sym_FindScopedSymbol(symName); + struct Symbol *sym = sym_FindScopedSymbol(symName); - if (nsym == NULL) { + if (!sym) { char fullname[MAXSYMLEN + 1]; if (symName[0] == '.') { @@ -662,11 +665,11 @@ struct Symbol *sym_Ref(char const *symName) symName = fullname; } - nsym = createsymbol(symName); - nsym->type = SYM_REF; + sym = createsymbol(symName); + sym->type = SYM_REF; } - return nsym; + return sym; } /*