ref: 4f842a1248be75cc9ca0c23e7a4e1b00e59cc6a5
parent: cc4d455b8a827e03ea73554a6058a7888bf9e736
author: ISSOtm <eldredhabert0@gmail.com>
date: Fri Nov 20 20:06:17 EST 2020
Create specialized symbol finder functions The old "find symbol with auto scope" function is now three: - One finds the exact name passed to it, skipping any checks This is useful e.g. if such checks were already performed. - One checks that the name is not scoped, and calls the first. This is useful for names that cannot be scoped, such as checking for EQUS. Doing this instead of the third should improve performance somehwat, since this specific case is hit by the lexer each time an identifier is read. - The last one checks if the name should be expanded (`.loc` → `Glob.loc`), and that the local part is not scoped. This is essentially the old function.
--- a/include/asm/rpn.h
+++ b/include/asm/rpn.h
@@ -46,7 +46,7 @@
return expr->isSymbol;
}
-void rpn_Symbol(struct Expression *expr, char *tzSym);
+void rpn_Symbol(struct Expression *expr, char const *tzSym);
void rpn_Number(struct Expression *expr, uint32_t i);
void rpn_LOGNOT(struct Expression *expr, const struct Expression *src);
struct Symbol const *rpn_SymbolOf(struct Expression const *expr);
--- a/include/asm/symbol.h
+++ b/include/asm/symbol.h
@@ -121,7 +121,19 @@
uint32_t sym_GetPCValue(void);
uint32_t sym_GetConstantSymValue(struct Symbol const *sym);
uint32_t sym_GetConstantValue(char const *s);
-struct Symbol *sym_FindSymbol(char const *symName);
+/*
+ * Find a symbol by exact name, bypassing expansion checks
+ */
+struct Symbol *sym_FindExactSymbol(char const *name);
+/*
+ * Find a symbol by exact name; may not be scoped, produces an error if it is
+ */
+struct Symbol *sym_FindUnscopedSymbol(char const *name);
+/*
+ * Find a symbol, possibly scoped, by name
+ */
+struct Symbol *sym_FindScopedSymbol(char const *name);
+struct Symbol const *sym_GetPC(void);
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_AddString(char const *symName, char const *value);
--- a/src/asm/fstack.c
+++ b/src/asm/fstack.c
@@ -317,7 +317,7 @@
{
dbgPrint("Running macro \"%s\"\n", macroName);
- struct Symbol *macro = sym_FindSymbol(macroName);
+ struct Symbol *macro = sym_FindExactSymbol(macroName);
if (!macro) {
error("Macro \"%s\" not defined\n", macroName);
--- a/src/asm/lexer.c
+++ b/src/asm/lexer.c
@@ -1311,7 +1311,7 @@
}
symName[i] = '\0';
- struct Symbol const *sym = sym_FindSymbol(symName);
+ struct Symbol const *sym = sym_FindScopedSymbol(symName);
if (!sym) {
error("Interpolated symbol \"%s\" does not exist\n", symName);
@@ -1691,9 +1691,10 @@
if (tokenType != T_ID && tokenType != T_LOCAL_ID)
return tokenType;
- if (lexerState->expandStrings) {
+ /* Local symbols cannot be string expansions */
+ if (tokenType == T_ID && lexerState->expandStrings) {
/* Attempt string expansion */
- struct Symbol const *sym = sym_FindSymbol(yylval.tzSym);
+ struct Symbol const *sym = sym_FindExactSymbol(yylval.tzSym);
if (sym && sym->type == SYM_EQUS) {
char const *s = sym_GetStringValue(sym);
--- a/src/asm/output.c
+++ b/src/asm/output.c
@@ -296,6 +296,11 @@
uint8_t rpndata = popbyte();
switch (rpndata) {
+ struct Symbol *sym;
+ uint32_t value;
+ uint8_t b;
+ size_t i;
+
case RPN_CONST:
writebyte(RPN_CONST);
writebyte(popbyte());
@@ -303,13 +308,15 @@
writebyte(popbyte());
writebyte(popbyte());
break;
+
case RPN_SYM:
- {
- for (unsigned int i = -1; (tzSym[++i] = popbyte()); )
- ;
- struct Symbol *sym = sym_FindSymbol(tzSym);
- uint32_t value;
+ i = 0;
+ do {
+ tzSym[i] = popbyte();
+ } while (tzSym[i++]);
+ // The symbol name is always written expanded
+ sym = sym_FindExactSymbol(tzSym);
if (sym_IsConstant(sym)) {
writebyte(RPN_CONST);
value = sym_GetConstantValue(tzSym);
@@ -317,19 +324,23 @@
writebyte(RPN_SYM);
value = getSymbolID(sym);
}
+
writebyte(value & 0xFF);
writebyte(value >> 8);
writebyte(value >> 16);
writebyte(value >> 24);
break;
- }
+
case RPN_BANK_SYM:
- {
- for (unsigned int i = -1; (tzSym[++i] = popbyte()); )
- ;
- struct Symbol *sym = sym_FindSymbol(tzSym);
- uint32_t value = getSymbolID(sym);
+ i = 0;
+ do {
+ tzSym[i] = popbyte();
+ } while (tzSym[i++]);
+ // The symbol name is always written expanded
+ sym = sym_FindExactSymbol(tzSym);
+ value = getSymbolID(sym);
+
writebyte(RPN_BANK_SYM);
writebyte(value & 0xFF);
writebyte(value >> 8);
@@ -336,11 +347,8 @@
writebyte(value >> 16);
writebyte(value >> 24);
break;
- }
- case RPN_BANK_SECT:
- {
- uint8_t b;
+ case RPN_BANK_SECT:
writebyte(RPN_BANK_SECT);
do {
b = popbyte();
@@ -347,7 +355,7 @@
writebyte(b);
} while (b != 0);
break;
- }
+
default:
writebyte(rpndata);
break;
--- a/src/asm/parser.y
+++ b/src/asm/parser.y
@@ -932,7 +932,7 @@
| T_OP_DEF {
lexer_ToggleStringExpansion(false);
} '(' scoped_id ')' {
- struct Symbol const *sym = sym_FindSymbol($4);
+ struct Symbol const *sym = sym_FindScopedSymbol($4);
rpn_Number(&$$, !!sym);
--- a/src/asm/rpn.c
+++ b/src/asm/rpn.c
@@ -104,9 +104,9 @@
expr->nVal = i;
}
-void rpn_Symbol(struct Expression *expr, char *tzSym)
+void rpn_Symbol(struct Expression *expr, char const *tzSym)
{
- struct Symbol *sym = sym_FindSymbol(tzSym);
+ struct Symbol *sym = sym_FindScopedSymbol(tzSym);
if (sym_IsPC(sym) && !sect_GetSymbolSection()) {
error("PC has no value outside a section\n");
@@ -115,15 +115,15 @@
rpn_Init(expr);
expr->isSymbol = true;
- sym_Ref(tzSym);
makeUnknown(expr, sym_IsPC(sym) ? "PC is not constant at assembly time"
: "'%s' is not constant at assembly time", tzSym);
+ sym = sym_Ref(tzSym);
expr->nRPNPatchSize += 5; /* 1-byte opcode + 4-byte symbol ID */
- size_t nameLen = strlen(tzSym) + 1; /* Don't forget NUL! */
+ size_t nameLen = strlen(sym->name) + 1; /* Don't forget NUL! */
uint8_t *ptr = reserveSpace(expr, nameLen + 1);
*ptr++ = RPN_SYM;
- memcpy(ptr, tzSym, nameLen);
+ memcpy(ptr, sym->name, nameLen);
/* RGBLINK assumes PC is at the byte being computed... */
if (sym_IsPC(sym) && nPCOffset) {
@@ -157,7 +157,7 @@
void rpn_BankSymbol(struct Expression *expr, char const *tzSym)
{
- struct Symbol const *sym = sym_FindSymbol(tzSym);
+ struct Symbol const *sym = sym_FindScopedSymbol(tzSym);
/* The @ symbol is treated differently. */
if (sym_IsPC(sym)) {
@@ -169,10 +169,8 @@
if (sym && !sym_IsLabel(sym)) {
error("BANK argument must be a label\n");
} else {
- sym_Ref(tzSym);
- if (!sym)
- /* If the symbol didn't exist, `sym_Ref` created it */
- sym = sym_FindSymbol(tzSym);
+ sym = sym_Ref(tzSym);
+ assert(sym); // If the symbol didn't exist, it should have been created
if (sym_GetSection(sym) && sym_GetSection(sym)->bank != -1) {
/* Symbol's section is known and bank is fixed */
@@ -181,10 +179,10 @@
makeUnknown(expr, "\"%s\"'s bank is not known", tzSym);
expr->nRPNPatchSize += 5; /* opcode + 4-byte sect ID */
- size_t nameLen = strlen(tzSym) + 1; /* Room for NUL! */
+ size_t nameLen = strlen(sym->name) + 1; /* Room for NUL! */
uint8_t *ptr = reserveSpace(expr, nameLen + 1);
*ptr++ = RPN_BANK_SYM;
- memcpy(ptr, tzSym, nameLen);
+ memcpy(ptr, sym->name, nameLen);
}
}
}
@@ -298,7 +296,7 @@
{
if (!rpn_isSymbol(expr))
return NULL;
- return sym_FindSymbol((char *)expr->tRPN + 1);
+ return sym_FindScopedSymbol((char *)expr->tRPN + 1);
}
bool rpn_IsDiffConstant(struct Expression const *src, struct Symbol const *sym)
--- a/src/asm/section.c
+++ b/src/asm/section.c
@@ -620,7 +620,7 @@
{
checkcodesection();
reserveSpace(1);
- struct Symbol const *pc = sym_FindSymbol("@");
+ struct Symbol const *pc = sym_GetPC();
if (!rpn_IsDiffConstant(expr, pc)) {
createPatch(PATCHTYPE_JR, expr);
--- a/src/asm/symbol.c
+++ b/src/asm/symbol.c
@@ -222,32 +222,42 @@
fatalerror("Symbol name is too long: '%s%s'\n", scopeName, localName);
}
-/*
- * Find a symbol by name and scope
- */
-static struct Symbol *findsymbol(char const *s, char const *scope)
+struct Symbol *sym_FindExactSymbol(char const *name)
{
- char fullname[MAXSYMLEN + 1];
+ return hash_GetElement(symbols, name);
+}
- if (s[0] == '.' && scope) {
- fullSymbolName(fullname, sizeof(fullname), s, scope);
- s = fullname;
+struct Symbol *sym_FindUnscopedSymbol(char const *name)
+{
+ if (strchr(name, '.')) {
+ error("Expected non-scoped symbol name, not \"%s\"\n", name);
+ return NULL;
}
+ return sym_FindExactSymbol(name);
+}
- char const *separator = strchr(s, '.');
+struct Symbol *sym_FindScopedSymbol(char const *name)
+{
+ char const *dotPtr = strchr(name, '.');
- if (separator && strchr(separator + 1, '.'))
- fatalerror("'%s' is a nonsensical reference to a nested local symbol\n", s);
+ if (dotPtr) {
+ if (strchr(dotPtr + 1, '.'))
+ fatalerror("'%s' is a nonsensical reference to a nested local symbol\n",
+ name);
+ /* If auto-scoped local label, expand the name */
+ if (dotPtr == name) { /* Meaning, the name begins with the dot */
+ char fullname[MAXSYMLEN + 1];
- return hash_GetElement(symbols, s);
+ fullSymbolName(fullname, sizeof(fullname), name, labelScope);
+ return sym_FindExactSymbol(fullname);
+ }
+ }
+ return sym_FindExactSymbol(name);
}
-/*
- * Find a symbol by name, with automatically determined scope
- */
-struct Symbol *sym_FindSymbol(char const *symName)
+struct Symbol const *sym_GetPC(void)
{
- return findsymbol(symName, symName[0] == '.' ? labelScope : NULL);
+ return PCSymbol;
}
static inline bool isReferenced(struct Symbol const *sym)
@@ -260,7 +270,7 @@
*/
void sym_Purge(char const *symName)
{
- struct Symbol *symbol = sym_FindSymbol(symName);
+ struct Symbol *symbol = sym_FindScopedSymbol(symName);
if (!symbol) {
error("'%s' not defined\n", symName);
@@ -312,7 +322,7 @@
*/
uint32_t sym_GetConstantValue(char const *s)
{
- struct Symbol const *sym = sym_FindSymbol(s);
+ struct Symbol const *sym = sym_FindScopedSymbol(s);
if (sym == NULL)
error("'%s' not defined\n", s);
@@ -339,11 +349,11 @@
*/
static struct Symbol *createNonrelocSymbol(char const *symbolName)
{
- struct Symbol *symbol = findsymbol(symbolName, NULL);
+ struct Symbol *symbol = sym_FindExactSymbol(symbolName);
- if (!symbol)
+ if (!symbol) {
symbol = createsymbol(symbolName);
- else if (sym_IsDefined(symbol)) {
+ } else if (sym_IsDefined(symbol)) {
error("'%s' already defined at ", symbolName);
dumpFilename(symbol);
putc('\n', stderr);
@@ -400,7 +410,7 @@
*/
struct Symbol *sym_AddSet(char const *symName, int32_t value)
{
- struct Symbol *sym = findsymbol(symName, NULL);
+ struct Symbol *sym = sym_FindExactSymbol(symName);
if (sym == NULL) {
sym = createsymbol(symName);
@@ -411,7 +421,6 @@
putc('\n', stderr);
return sym;
} else {
- /* TODO: can the scope be incorrect when taking over refs? */
updateSymbolFilename(sym);
}
@@ -429,7 +438,7 @@
static struct Symbol *addLabel(char const *name)
{
assert(name[0] != '.'); /* The symbol name must have been expanded prior */
- struct Symbol *sym = findsymbol(name, NULL); /* Due to this, don't look for expansions */
+ struct Symbol *sym = sym_FindExactSymbol(name);
if (!sym) {
sym = createsymbol(name);
@@ -511,7 +520,7 @@
*/
void sym_Export(char const *symName)
{
- struct Symbol *sym = sym_FindSymbol(symName);
+ struct Symbol *sym = sym_FindScopedSymbol(symName);
/* If the symbol doesn't exist, create a ref that can be purged */
if (!sym)
@@ -545,7 +554,7 @@
*/
struct Symbol *sym_Ref(char const *symName)
{
- struct Symbol *nsym = sym_FindSymbol(symName);
+ struct Symbol *nsym = sym_FindScopedSymbol(symName);
if (nsym == NULL) {
char fullname[MAXSYMLEN + 1];