From f9f27d6f5a00898f7d3faaee921ab8d13e13b85a Mon Sep 17 00:00:00 2001 From: ISSOtm Date: Thu, 9 Apr 2020 10:42:24 +0200 Subject: [PATCH] Clean up symbol system Get rid of Hungarian notation Improve encapsulation (the rest of the world should not touch PC directly) --- include/asm/asm.h | 1 - include/asm/fstack.h | 4 +- include/asm/lexer.h | 2 +- include/asm/symbol.h | 96 +++-- src/asm/asmy.y | 7 +- src/asm/fstack.c | 46 +-- src/asm/globlex.c | 4 +- src/asm/lexer.c | 2 +- src/asm/output.c | 32 +- src/asm/rpn.c | 37 +- src/asm/section.c | 21 +- src/asm/symbol.c | 488 +++++++++++------------ test/asm/macro-@.err | 3 +- test/asm/reference-undefined-sym.asm | 2 +- test/asm/reference-undefined-sym.err | 3 - test/asm/reference-undefined-sym.out.bin | 0 test/asm/symbol-override.err | 2 +- 17 files changed, 356 insertions(+), 394 deletions(-) create mode 100644 test/asm/reference-undefined-sym.out.bin diff --git a/include/asm/asm.h b/include/asm/asm.h index 867e3345..36ba06f5 100644 --- a/include/asm/asm.h +++ b/include/asm/asm.h @@ -34,7 +34,6 @@ extern uint32_t unionStart[MAXUNIONS]; extern uint32_t unionSize[MAXUNIONS]; extern char tzCurrentFileName[_MAX_PATH + 1]; extern struct Section *pCurrentSection; -extern struct sSymbol *pPCSymbol; extern bool oDontExpandStrings; size_t symvaluetostring(char *dest, size_t maxLength, char *sym, diff --git a/include/asm/fstack.h b/include/asm/fstack.h index ace621d5..23807399 100644 --- a/include/asm/fstack.h +++ b/include/asm/fstack.h @@ -25,7 +25,7 @@ struct MacroArgs; struct sContext { YY_BUFFER_STATE FlexHandle; - struct sSymbol *pMacro; + struct Symbol const *pMacro; struct sContext *pNext; char tzFileName[_MAX_PATH + 1]; struct MacroArgs *macroArgs; @@ -48,7 +48,7 @@ void fstk_Dump(void); void fstk_DumpToStr(char *buf, size_t len); void fstk_DumpStringExpansions(void); void fstk_AddIncludePath(char *s); -bool fstk_RunMacro(char *s, struct MacroArgs *args); +void fstk_RunMacro(char *s, struct MacroArgs *args); void fstk_RunRept(uint32_t count, int32_t nReptLineNo); FILE *fstk_FindFile(char const *fname, char **incPathUsed); int32_t fstk_GetLine(void); diff --git a/include/asm/lexer.h b/include/asm/lexer.h index c4e845b5..7d095e53 100644 --- a/include/asm/lexer.h +++ b/include/asm/lexer.h @@ -56,7 +56,7 @@ void setup_lexer(void); void yy_set_state(enum eLexerState i); YY_BUFFER_STATE yy_create_buffer(FILE *f); -YY_BUFFER_STATE yy_scan_bytes(char *mem, uint32_t size); +YY_BUFFER_STATE yy_scan_bytes(char const *mem, uint32_t size); void yy_delete_buffer(YY_BUFFER_STATE buf); void yy_switch_to_buffer(YY_BUFFER_STATE buf); uint32_t lex_FloatAlloc(const struct sLexFloat *tok); diff --git a/include/asm/symbol.h b/include/asm/symbol.h index 2720d073..e1a420ef 100644 --- a/include/asm/symbol.h +++ b/include/asm/symbol.h @@ -29,53 +29,70 @@ enum SymbolType { SYM_REF // Forward reference to a label }; -struct sSymbol { - char tzName[MAXSYMLEN + 1]; +struct Symbol { + char name[MAXSYMLEN + 1]; enum SymbolType type; bool isExported; /* Whether the symbol is to be exported */ bool isBuiltin; /* Whether the symbol is a built-in */ - struct sSymbol *pScope; - struct Section *pSection; - int32_t nValue; - uint32_t ulMacroSize; - char *pMacro; - int32_t (*Callback)(struct sSymbol const *self); - char tzFileName[_MAX_PATH + 1]; /* File where the symbol was defined. */ - uint32_t nFileLine; /* Line where the symbol was defined. */ + struct Symbol const *scope; + struct Section *section; + char fileName[_MAX_PATH + 1]; /* File where the symbol was defined. */ + uint32_t fileLine; /* Line where the symbol was defined. */ + + union { + struct { /* If sym_IsNumeric */ + int32_t value; + int32_t (*callback)(void); + }; + struct { /* For SYM_MACRO */ + uint32_t macroSize; + char *macro; + }; + }; uint32_t ID; /* ID of the symbol in the object file (-1 if none) */ - struct sSymbol *next; /* Next object to output in the object file */ + struct Symbol *next; /* Next object to output in the object file */ }; -static inline bool sym_IsDefined(struct sSymbol const *sym) +bool sym_IsPC(struct Symbol const *sym); + +static inline bool sym_IsDefined(struct Symbol const *sym) { return sym->type != SYM_REF; } -static inline bool sym_IsConstant(struct sSymbol const *sym) +static inline struct Section *sym_GetSection(struct Symbol const *sym) { - return sym->type == SYM_EQU || sym->type == SYM_SET - || (sym->type == SYM_LABEL && sym->pSection - && sym->pSection->nOrg != -1); + return sym_IsPC(sym) ? sect_GetSymbolSection() : sym->section; } -static inline bool sym_IsNumeric(struct sSymbol const *sym) +static inline bool sym_IsConstant(struct Symbol const *sym) +{ + if (sym->type == SYM_LABEL) { + struct Section const *sect = sym_GetSection(sym); + + return sect && sect->nOrg != -1; + } + return sym->type == SYM_EQU || sym->type == SYM_SET; +} + +static inline bool sym_IsNumeric(struct Symbol const *sym) { return sym->type == SYM_LABEL || sym->type == SYM_EQU || sym->type == SYM_SET; } -static inline bool sym_IsLabel(struct sSymbol const *sym) +static inline bool sym_IsLabel(struct Symbol const *sym) { return sym->type == SYM_LABEL || sym->type == SYM_REF; } -static inline bool sym_IsLocal(struct sSymbol const *sym) +static inline bool sym_IsLocal(struct Symbol const *sym) { - return sym_IsLabel(sym) && strchr(sym->tzName, '.'); + return sym_IsLabel(sym) && strchr(sym->name, '.'); } -static inline bool sym_IsExported(struct sSymbol const *sym) +static inline bool sym_IsExported(struct Symbol const *sym) { return sym->isExported; } @@ -83,33 +100,32 @@ static inline bool sym_IsExported(struct sSymbol const *sym) /* * Get a string equate's value */ -static inline char *sym_GetStringValue(struct sSymbol const *sym) +static inline char const *sym_GetStringValue(struct Symbol const *sym) { - return sym->pMacro; + return sym->macro; } -void sym_ForEach(void (*func)(struct sSymbol *, void *), void *arg); +void sym_ForEach(void (*func)(struct Symbol *, void *), void *arg); -int32_t sym_GetValue(struct sSymbol const *sym); +int32_t sym_GetValue(struct Symbol const *sym); void sym_SetExportAll(bool set); -struct sSymbol *sym_AddLocalReloc(char const *tzSym); -struct sSymbol *sym_AddReloc(char const *tzSym); -void sym_Export(char const *tzSym); -struct sSymbol *sym_FindMacro(char const *s); -struct sSymbol *sym_AddEqu(char const *tzSym, int32_t value); -struct sSymbol *sym_AddSet(char const *tzSym, int32_t value); -void sym_Init(void); +struct Symbol *sym_AddLocalReloc(char const *symName); +struct Symbol *sym_AddReloc(char const *symName); +void sym_Export(char const *symName); +struct Symbol *sym_AddEqu(char const *symName, int32_t value); +struct Symbol *sym_AddSet(char const *symName, int32_t value); +uint32_t sym_GetPCValue(void); uint32_t sym_GetConstantValue(char const *s); -struct sSymbol *sym_FindSymbol(char const *tzName); -char *sym_GetStringValue(struct sSymbol const *sym); -struct sSymbol *sym_AddMacro(char const *tzSym, int32_t nDefLineNo); -struct sSymbol *sym_Ref(char const *tzSym); -struct sSymbol *sym_AddString(char const *tzSym, char const *tzValue); +struct Symbol *sym_FindSymbol(char const *symName); +struct Symbol *sym_AddMacro(char const *symName, int32_t defLineNo); +struct Symbol *sym_Ref(char const *symName); +struct Symbol *sym_AddString(char const *symName, char const *value); uint32_t sym_GetDefinedValue(char const *s); -void sym_Purge(char const *tzName); +void sym_Purge(char const *symName); +void sym_Init(void); /* Functions to save and restore the current symbol scope. */ -struct sSymbol *sym_GetCurrentSymbolScope(void); -void sym_SetCurrentSymbolScope(struct sSymbol *pNewScope); +struct Symbol *sym_GetCurrentSymbolScope(void); +void sym_SetCurrentSymbolScope(struct Symbol *newScope); #endif /* RGBDS_SYMBOL_H */ diff --git a/src/asm/asmy.y b/src/asm/asmy.y index 0d8db329..b7df86cc 100644 --- a/src/asm/asmy.y +++ b/src/asm/asmy.y @@ -43,7 +43,7 @@ size_t symvaluetostring(char *dest, size_t maxLength, char *symName, const char *mode) { size_t length; - struct sSymbol *sym = sym_FindSymbol(symName); + struct Symbol *sym = sym_FindSymbol(symName); if (sym && sym->type == SYM_EQUS) { char const *src = sym_GetStringValue(sym); @@ -710,8 +710,7 @@ macro : T_ID { yy_set_state(LEX_STATE_MACROARGS); } macroargs { yy_set_state(LEX_STATE_NORMAL); - if (!fstk_RunMacro($1, $3)) - fatalerror("Macro '%s' not defined", $1); + fstk_RunMacro($1, $3); } ; @@ -1334,7 +1333,7 @@ relocexpr_no_str : scoped_id { rpn_Symbol(&$$, $1); } | T_OP_DEF { oDontExpandStrings = true; } '(' scoped_id ')' { - struct sSymbol const *sym = sym_FindSymbol($4); + struct Symbol const *sym = sym_FindSymbol($4); rpn_Number(&$$, !!sym); diff --git a/src/asm/fstack.c b/src/asm/fstack.c index 67e68dc6..e00ebf99 100644 --- a/src/asm/fstack.c +++ b/src/asm/fstack.c @@ -34,7 +34,7 @@ static struct sContext *pFileStack; static unsigned int nFileStackDepth; unsigned int nMaxRecursionDepth; -static struct sSymbol *pCurrentMacro; +static struct Symbol const *pCurrentMacro; static YY_BUFFER_STATE CurrentFlexHandle; static FILE *pCurrentFile; static uint32_t nCurrentStatus; @@ -449,52 +449,38 @@ void fstk_RunInclude(char *tzFileName) /* * Set up a macro for parsing */ -bool fstk_RunMacro(char *s, struct MacroArgs *args) +void fstk_RunMacro(char *s, struct MacroArgs *args) { - struct sSymbol *sym = sym_FindMacro(s); + struct Symbol const *sym = sym_FindSymbol(s); int nPrintedChars; - if (sym == NULL || sym->pMacro == NULL) - return false; + if (sym == NULL) { + yyerror("Macro \"%s\" not defined", s); + return; + } + if (sym->type != SYM_MACRO) { + yyerror("\"%s\" is not a macro", s); + return; + } pushcontext(); macro_SetUniqueID(nMacroCount++); /* Minus 1 because there is a newline at the beginning of the buffer */ - nLineNo = sym->nFileLine - 1; + nLineNo = sym->fileLine - 1; macro_UseNewArgs(args); nCurrentStatus = STAT_isMacro; nPrintedChars = snprintf(tzCurrentFileName, _MAX_PATH + 1, - "%s::%s", sym->tzFileName, s); + "%s::%s", sym->fileName, s); if (nPrintedChars > _MAX_PATH) { popcontext(); fatalerror("File name + macro name is too large to fit into buffer"); } pCurrentMacro = sym; - CurrentFlexHandle = yy_scan_bytes(pCurrentMacro->pMacro, - strlen(pCurrentMacro->pMacro)); + /* TODO: why is `strlen` being used when there's a macro size field? */ + CurrentFlexHandle = yy_scan_bytes(pCurrentMacro->macro, + strlen(pCurrentMacro->macro)); yy_switch_to_buffer(CurrentFlexHandle); - - return true; -} - -/* - * Set up a stringequate for parsing - */ -void fstk_RunString(char *s) -{ - const struct sSymbol *pSym = sym_FindSymbol(s); - - if (pSym != NULL) { - pushcontext(); - nCurrentStatus = STAT_isMacroArg; - strcpy(tzCurrentFileName, s); - CurrentFlexHandle = - yy_scan_bytes(pSym->pMacro, strlen(pSym->pMacro)); - yy_switch_to_buffer(CurrentFlexHandle); - } else { - yyerror("No such string symbol '%s'", s); - } } /* diff --git a/src/asm/globlex.c b/src/asm/globlex.c index 467e8f68..dc56ddf1 100644 --- a/src/asm/globlex.c +++ b/src/asm/globlex.c @@ -277,10 +277,10 @@ uint32_t ParseSymbol(char *src, uint32_t size) /* If the symbol is an EQUS, expand it */ if (!oDontExpandStrings) { - struct sSymbol const *sym = sym_FindSymbol(dest); + struct Symbol const *sym = sym_FindSymbol(dest); if (sym && sym->type == SYM_EQUS) { - char *s; + char const *s; lex_BeginStringExpansion(dest); diff --git a/src/asm/lexer.c b/src/asm/lexer.c index 7b72da75..27a9a1cf 100644 --- a/src/asm/lexer.c +++ b/src/asm/lexer.c @@ -190,7 +190,7 @@ static void yy_buffer_append_newlines(YY_BUFFER_STATE buf, size_t capacity) } } -YY_BUFFER_STATE yy_scan_bytes(char *mem, uint32_t size) +YY_BUFFER_STATE yy_scan_bytes(char const *mem, uint32_t size) { YY_BUFFER_STATE pBuffer = malloc(sizeof(struct yy_buffer_state)); diff --git a/src/asm/output.c b/src/asm/output.c index 3f7feb50..fc1b906e 100644 --- a/src/asm/output.c +++ b/src/asm/output.c @@ -55,8 +55,8 @@ char *tzObjectname; struct Section *pSectionList, *pCurrentSection; /* Linked list of symbols to put in the object file */ -static struct sSymbol *objectSymbols = NULL; -static struct sSymbol **objectSymbolsTail = &objectSymbols; +static struct Symbol *objectSymbols = NULL; +static struct Symbol **objectSymbolsTail = &objectSymbols; static uint32_t nbSymbols = 0; /* Length of the above list */ static struct Assertion *assertions = NULL; @@ -196,17 +196,17 @@ static void writesection(struct Section const *pSect, FILE *f) /* * Write a symbol to a file */ -static void writesymbol(struct sSymbol const *pSym, FILE *f) +static void writesymbol(struct Symbol const *sym, FILE *f) { - fputstring(pSym->tzName, f); - if (!sym_IsDefined(pSym)) { + fputstring(sym->name, f); + if (!sym_IsDefined(sym)) { fputc(SYMTYPE_IMPORT, f); } else { - fputc(pSym->isExported ? SYMTYPE_EXPORT : SYMTYPE_LOCAL, f); - fputstring(pSym->tzFileName, f); - fputlong(pSym->nFileLine, f); - fputlong(getSectIDIfAny(pSym->pSection), f); - fputlong(pSym->nValue, f); + fputc(sym->isExported ? SYMTYPE_EXPORT : SYMTYPE_LOCAL, f); + fputstring(sym->fileName, f); + fputlong(sym->fileLine, f); + fputlong(getSectIDIfAny(sym_GetSection(sym)), f); + fputlong(sym->value, f); } } @@ -214,7 +214,7 @@ static void writesymbol(struct sSymbol const *pSym, FILE *f) * Returns a symbol's ID within the object file * If the symbol does not have one, one is assigned by registering the symbol */ -static uint32_t getSymbolID(struct sSymbol *sym) +static uint32_t getSymbolID(struct Symbol *sym) { if (sym->ID == -1) { sym->ID = nbSymbols++; @@ -247,7 +247,7 @@ static void writerpn(uint8_t *rpnexpr, uint32_t *rpnptr, uint8_t *rpn, { for (unsigned int i = -1; (tzSym[++i] = popbyte()); ) ; - struct sSymbol *sym = sym_FindSymbol(tzSym); + struct Symbol *sym = sym_FindSymbol(tzSym); uint32_t value; if (sym_IsConstant(sym)) { @@ -267,7 +267,7 @@ static void writerpn(uint8_t *rpnexpr, uint32_t *rpnptr, uint8_t *rpn, { for (unsigned int i = -1; (tzSym[++i] = popbyte()); ) ; - struct sSymbol *sym = sym_FindSymbol(tzSym); + struct Symbol *sym = sym_FindSymbol(tzSym); uint32_t value = getSymbolID(sym); writebyte(RPN_BANK_SYM); @@ -367,10 +367,10 @@ static void writeassert(struct Assertion *assert, FILE *f) fputstring(assert->message, f); } -static void registerExportedSymbol(struct sSymbol *symbol, void *arg) +static void registerExportedSymbol(struct Symbol *symbol, void *arg) { (void)arg; - if (symbol->isExported && symbol->ID == -1) { + if (sym_IsExported(symbol) && symbol->ID == -1) { *objectSymbolsTail = symbol; objectSymbolsTail = &symbol->next; nbSymbols++; @@ -396,7 +396,7 @@ void out_WriteObject(void) fputlong(nbSymbols, f); fputlong(countsections(), f); - for (struct sSymbol const *sym = objectSymbols; sym; sym = sym->next) + for (struct Symbol const *sym = objectSymbols; sym; sym = sym->next) writesymbol(sym, f); for (struct Section *sect = pSectionList; sect; sect = sect->pNext) diff --git a/src/asm/rpn.c b/src/asm/rpn.c index 3388cd1a..31094e17 100644 --- a/src/asm/rpn.c +++ b/src/asm/rpn.c @@ -104,9 +104,9 @@ void rpn_Number(struct Expression *expr, uint32_t i) void rpn_Symbol(struct Expression *expr, char *tzSym) { - struct sSymbol *sym = sym_FindSymbol(tzSym); + struct Symbol *sym = sym_FindSymbol(tzSym); - if (sym == pPCSymbol && !pPCSymbol->pSection) { + if (sym_IsPC(sym) && !sect_GetSymbolSection()) { yyerror("PC has no value outside a section"); rpn_Number(expr, 0); } else if (!sym || !sym_IsConstant(sym)) { @@ -114,9 +114,9 @@ void rpn_Symbol(struct Expression *expr, char *tzSym) expr->isSymbol = true; sym_Ref(tzSym); - makeUnknown(expr, strcmp(tzSym, "@") - ? "'%s' is not constant at assembly time" - : "PC is not constant at assembly time", + makeUnknown(expr, sym_IsPC(sym) + ? "PC is not constant at assembly time" + : "'%s' is not constant at assembly time", tzSym); expr->nRPNPatchSize += 5; /* 1-byte opcode + 4-byte symbol ID */ @@ -126,7 +126,7 @@ void rpn_Symbol(struct Expression *expr, char *tzSym) memcpy(ptr, tzSym, nameLen); /* RGBLINK assumes PC is at the byte being computed... */ - if (sym == pPCSymbol && nPCOffset) { + if (sym_IsPC(sym) && nPCOffset) { struct Expression pc = *expr, offset; rpn_Number(&offset, nPCOffset); @@ -157,10 +157,10 @@ void rpn_BankSelf(struct Expression *expr) void rpn_BankSymbol(struct Expression *expr, char const *tzSym) { - struct sSymbol const *sym = sym_FindSymbol(tzSym); + struct Symbol const *sym = sym_FindSymbol(tzSym); /* The @ symbol is treated differently. */ - if (sym == pPCSymbol) { + if (sym_IsPC(sym)) { rpn_BankSelf(expr); return; } @@ -170,12 +170,13 @@ void rpn_BankSymbol(struct Expression *expr, char const *tzSym) yyerror("BANK argument must be a label"); } else { sym_Ref(tzSym); - /* If the symbol didn't exist, `sym_Ref` created it */ - struct sSymbol *pSymbol = sym_FindSymbol(tzSym); + if (!sym) + /* If the symbol didn't exist, `sym_Ref` created it */ + sym = sym_FindSymbol(tzSym); - if (pSymbol->pSection && pSymbol->pSection->nBank != -1) { + if (sym_GetSection(sym) && sym_GetSection(sym)->nBank != -1) { /* Symbol's section is known and bank is fixed */ - expr->nVal = pSymbol->pSection->nBank; + expr->nVal = sym_GetSection(sym)->nBank; } else { makeUnknown(expr, "\"%s\"'s bank is not known", tzSym); expr->nRPNPatchSize += 5; /* opcode + 4-byte sect ID */ @@ -293,7 +294,7 @@ static int32_t shift(int32_t shiftee, int32_t amount) } } -static struct sSymbol const *symbolOf(struct Expression const *expr) +static struct Symbol const *symbolOf(struct Expression const *expr) { if (!rpn_isSymbol(expr)) return NULL; @@ -304,14 +305,14 @@ static bool isDiffConstant(struct Expression const *src1, struct Expression const *src2) { /* Check if both expressions only refer to a single symbol */ - struct sSymbol const *symbol1 = symbolOf(src1); - struct sSymbol const *symbol2 = symbolOf(src2); + struct Symbol const *symbol1 = symbolOf(src1); + struct Symbol const *symbol2 = symbolOf(src2); if (!symbol1 || !symbol2 || symbol1->type != SYM_LABEL || symbol2->type != SYM_LABEL) return false; - return symbol1->pSection == symbol2->pSection; + return sym_GetSection(symbol1) == sym_GetSection(symbol2); } void rpn_BinaryOp(enum RPNCommand op, struct Expression *expr, @@ -424,8 +425,8 @@ void rpn_BinaryOp(enum RPNCommand op, struct Expression *expr, } } else if (op == RPN_SUB && isDiffConstant(src1, src2)) { - struct sSymbol const *symbol1 = symbolOf(src1); - struct sSymbol const *symbol2 = symbolOf(src2); + struct Symbol const *symbol1 = symbolOf(src1); + struct Symbol const *symbol2 = symbolOf(src2); expr->nVal = sym_GetValue(symbol1) - sym_GetValue(symbol2); expr->isKnown = true; diff --git a/src/asm/section.c b/src/asm/section.c index 17626a02..dd3d2b61 100644 --- a/src/asm/section.c +++ b/src/asm/section.c @@ -15,7 +15,7 @@ struct SectionStackEntry { struct Section *pSection; - struct sSymbol *pScope; /* Section's symbol scope */ + struct Symbol *pScope; /* Section's symbol scope */ uint32_t offset; struct SectionStackEntry *pNext; }; @@ -288,13 +288,11 @@ static struct Section *getSection(char const *pzName, enum SectionType type, /* * Set the current section */ -static void setSection(struct Section *pSect) +static void changeSection(void) { if (nUnionDepth > 0) fatalerror("Cannot change the section within a UNION"); - pPCSymbol->pSection = pSect; - sym_SetCurrentSymbolScope(NULL); } @@ -309,7 +307,7 @@ void out_NewSection(char const *pzName, uint32_t type, uint32_t org, struct Section *pSect = getSection(pzName, type, org, attribs, isUnion); - setSection(pSect); + changeSection(); curOffset = isUnion ? 0 : pSect->size; pCurrentSection = pSect; } @@ -329,7 +327,7 @@ void out_SetLoadSection(char const *name, uint32_t type, uint32_t org, loadOffset = curOffset; curOffset = 0; /* curOffset -= loadOffset; */ - setSection(pSect); + changeSection(); currentLoadSection = pSect; } @@ -339,7 +337,7 @@ void out_EndLoadSection(void) yyerror("Found `ENDL` outside of a `LOAD` block"); currentLoadSection = NULL; - setSection(pCurrentSection); + changeSection(); curOffset += loadOffset; loadOffset = 0; } @@ -359,9 +357,9 @@ void sect_AlignPC(uint8_t alignment, uint16_t offset) struct Section *sect = sect_GetSymbolSection(); if (sect->nOrg != -1) { - if ((sym_GetValue(pPCSymbol) - offset) % (1 << alignment)) + if ((sym_GetPCValue() - offset) % (1 << alignment)) yyerror("Section's fixed address fails required alignment (PC = $%04x)", - sym_GetValue(pPCSymbol)); + sym_GetPCValue()); } else if (sect->nAlign != 0) { if ((((sect->alignOfs + curOffset) % (1 << sect->nAlign)) - offset) % (1 << alignment)) { @@ -553,7 +551,7 @@ void out_PCRelByte(struct Expression *expr) writebyte(0); } else { /* Target is relative to the byte *after* the operand */ - uint16_t address = sym_GetValue(pPCSymbol) + 1; + uint16_t address = sym_GetPCValue() + 1; /* The offset wraps (jump from ROM to HRAM, for loopexample) */ int16_t offset = expr->nVal - address; @@ -698,6 +696,7 @@ void out_PushSection(void) pSect->offset = curOffset; pSect->pNext = pSectionStack; pSectionStack = pSect; + /* TODO: maybe set current section to NULL? */ } void out_PopSection(void) @@ -711,7 +710,7 @@ void out_PopSection(void) struct SectionStackEntry *pSect; pSect = pSectionStack; - setSection(pSect->pSection); + changeSection(); pCurrentSection = pSect->pSection; sym_SetCurrentSymbolScope(pSect->pScope); curOffset = pSect->offset; diff --git a/src/asm/symbol.c b/src/asm/symbol.c index 3dd8bb3e..646c3dfc 100644 --- a/src/asm/symbol.c +++ b/src/asm/symbol.c @@ -35,112 +35,111 @@ HashMap symbols; -static struct sSymbol *pScope; /* Current section symbol scope */ -struct sSymbol *pPCSymbol; -static struct sSymbol *p_NARGSymbol; -static struct sSymbol *p__LINE__Symbol; -static char SavedTIME[256]; -static char SavedDATE[256]; -static char SavedTIMESTAMP_ISO8601_LOCAL[256]; -static char SavedTIMESTAMP_ISO8601_UTC[256]; -static char SavedDAY[3]; -static char SavedMONTH[3]; -static char SavedYEAR[20]; -static char SavedHOUR[3]; -static char SavedMINUTE[3]; -static char SavedSECOND[3]; +static struct Symbol *symbolScope; /* Current section symbol scope */ +static struct Symbol *PCSymbol; +static char savedTIME[256]; +static char savedDATE[256]; +static char savedTIMESTAMP_ISO8601_LOCAL[256]; +static char savedTIMESTAMP_ISO8601_UTC[256]; +static char savedDAY[3]; +static char savedMONTH[3]; +static char savedYEAR[20]; +static char savedHOUR[3]; +static char savedMINUTE[3]; +static char savedSECOND[3]; static bool exportall; +bool sym_IsPC(struct Symbol const *sym) +{ + return sym == PCSymbol; +} + struct ForEachArgs { - void (*func)(struct sSymbol *symbol, void *arg); + void (*func)(struct Symbol *symbol, void *arg); void *arg; }; static void forEachWrapper(void *_symbol, void *_argWrapper) { struct ForEachArgs *argWrapper = _argWrapper; - struct sSymbol *symbol = _symbol; + struct Symbol *symbol = _symbol; argWrapper->func(symbol, argWrapper->arg); } -void sym_ForEach(void (*func)(struct sSymbol *, void *), void *arg) +void sym_ForEach(void (*func)(struct Symbol *, void *), void *arg) { struct ForEachArgs argWrapper = { .func = func, .arg = arg }; hash_ForEach(symbols, forEachWrapper, &argWrapper); } -static int32_t Callback_NARG(struct sSymbol const *self) +static int32_t Callback_NARG(void) { - (void)self; return macro_NbArgs(); } -static int32_t Callback__LINE__(struct sSymbol const *self) +static int32_t Callback__LINE__(void) { - (void)self; return nLineNo; } -static int32_t CallbackPC(struct sSymbol const *self) +static int32_t CallbackPC(void) { - return self->pSection ? self->pSection->nOrg + curOffset : 0; + struct Section const *section = sect_GetSymbolSection(); + + return section ? section->nOrg + curOffset : 0; } /* - * Get the nValue field of a symbol + * Get the value field of a symbol */ -int32_t sym_GetValue(struct sSymbol const *sym) +int32_t sym_GetValue(struct Symbol const *sym) { - if (sym->Callback) - return sym->Callback(sym); + if (sym_IsNumeric(sym) && sym->callback) + return sym->callback(); if (sym->type == SYM_LABEL) - return sym->nValue + sym->pSection->nOrg; + /* TODO: do not use section's org directly */ + return sym->value + sym_GetSection(sym)->nOrg; - return sym->nValue; + return sym->value; } /* * Update a symbol's definition filename and line */ -static void updateSymbolFilename(struct sSymbol *nsym) +static void updateSymbolFilename(struct Symbol *sym) { - if (snprintf(nsym->tzFileName, _MAX_PATH + 1, "%s", - tzCurrentFileName) > _MAX_PATH) { + if (snprintf(sym->fileName, _MAX_PATH + 1, "%s", + tzCurrentFileName) > _MAX_PATH) fatalerror("%s: File name is too long: '%s'", __func__, tzCurrentFileName); - } - nsym->nFileLine = fstk_GetLine(); + sym->fileLine = fstk_GetLine(); } /* * Create a new symbol by name */ -static struct sSymbol *createsymbol(char const *s) +static struct Symbol *createsymbol(char const *s) { - struct sSymbol *symbol = malloc(sizeof(*symbol)); + struct Symbol *symbol = malloc(sizeof(*symbol)); if (!symbol) fatalerror("Failed to create symbol: %s", strerror(errno)); - if (snprintf(symbol->tzName, MAXSYMLEN + 1, "%s", s) > MAXSYMLEN) + if (snprintf(symbol->name, MAXSYMLEN + 1, "%s", s) > MAXSYMLEN) warning(WARNING_LONG_STR, "Symbol name is too long: '%s'", s); - hash_AddElement(symbols, symbol->tzName, symbol); - symbol->isExported = false; symbol->isBuiltin = false; - symbol->pScope = NULL; - symbol->pSection = NULL; - symbol->nValue = 0; /* TODO: is this necessary? */ - symbol->pMacro = NULL; - symbol->Callback = NULL; - + symbol->scope = NULL; + symbol->section = NULL; + updateSymbolFilename(symbol); symbol->ID = -1; symbol->next = NULL; - updateSymbolFilename(symbol); + + hash_AddElement(symbols, symbol->name, symbol); return symbol; } @@ -149,20 +148,20 @@ static struct sSymbol *createsymbol(char const *s) * the name with the parent symbol's name. */ static void fullSymbolName(char *output, size_t outputSize, - char const *localName, const struct sSymbol *scope) + char const *localName, const struct Symbol *scope) { - const struct sSymbol *parent = scope->pScope ? scope->pScope : scope; - int n = snprintf(output, outputSize, "%s%s", parent->tzName, localName); + const struct Symbol *parent = scope->scope ? scope->scope : scope; + int n = snprintf(output, outputSize, "%s%s", parent->name, localName); if (n >= (int)outputSize) - fatalerror("Symbol name is too long: '%s%s'", - parent->tzName, localName); + fatalerror("Symbol name is too long: '%s%s'", parent->name, + localName); } /* * Find a symbol by name and scope */ -static struct sSymbol *findsymbol(char const *s, struct sSymbol const *scope) +static struct Symbol *findsymbol(char const *s, struct Symbol const *scope) { char fullname[MAXSYMLEN + 1]; @@ -183,19 +182,12 @@ static struct sSymbol *findsymbol(char const *s, struct sSymbol const *scope) /* * Find a symbol by name, with automatically determined scope */ -struct sSymbol *sym_FindSymbol(char const *tzName) +struct Symbol *sym_FindSymbol(char const *symName) { - struct sSymbol *pscope; - - if (*tzName == '.') - pscope = pScope; - else - pscope = NULL; - - return findsymbol(tzName, pscope); + return findsymbol(symName, symName[0] == '.' ? symbolScope : NULL); } -static inline bool isReferenced(struct sSymbol const *sym) +static inline bool isReferenced(struct Symbol const *sym) { return sym->ID != -1; } @@ -203,48 +195,54 @@ static inline bool isReferenced(struct sSymbol const *sym) /* * Purge a symbol */ -void sym_Purge(char const *tzName) +void sym_Purge(char const *symName) { - struct sSymbol *scope = tzName[0] == '.' ? pScope : NULL; - struct sSymbol *symbol = findsymbol(tzName, scope); + struct Symbol *scope = symName[0] == '.' ? symbolScope : NULL; + struct Symbol *symbol = findsymbol(symName, scope); if (!symbol) { - yyerror("'%s' not defined", tzName); + yyerror("'%s' not defined", symName); } else if (symbol->isBuiltin) { - yyerror("Built-in symbol '%s' cannot be purged", tzName); + yyerror("Built-in symbol '%s' cannot be purged", symName); } else if (isReferenced(symbol)) { yyerror("Symbol \"%s\" is referenced and thus cannot be purged", - tzName); + symName); } else { - hash_RemoveElement(symbols, tzName); - free(symbol->pMacro); + hash_RemoveElement(symbols, symName); + if (symbol->type == SYM_MACRO) + free(symbol->macro); free(symbol); } } +uint32_t sym_GetPCValue(void) +{ + struct Section const *sect = sect_GetSymbolSection(); + + if (!sect) + yyerror("PC has no value outside a section"); + else if (sect->nOrg == -1) + yyerror("Expected constant PC but section is not fixed"); + else + return CallbackPC(); + return 0; +} + /* * Return a constant symbols value */ uint32_t sym_GetConstantValue(char const *s) { - struct sSymbol const *psym = sym_FindSymbol(s); + struct Symbol const *sym = sym_FindSymbol(s); - if (psym == pPCSymbol) { - if (!pCurrentSection) - yyerror("PC has no value outside a section"); - else if (pCurrentSection->nOrg == -1) - yyerror("Expected constant PC but section is not fixed"); - else - return sym_GetValue(psym); - - } else if (psym != NULL) { - if (sym_IsConstant(psym)) - return sym_GetValue(psym); - - yyerror("\"%s\" does not have a constant value", s); - } else { + if (sym == NULL) yyerror("'%s' not defined", s); - } + else if (sym == PCSymbol) + return sym_GetPCValue(); + else if (!sym_IsConstant(sym)) + yyerror("\"%s\" does not have a constant value", s); + else + return sym_GetValue(sym); return 0; } @@ -254,38 +252,26 @@ uint32_t sym_GetConstantValue(char const *s) */ uint32_t sym_GetDefinedValue(char const *s) { - struct sSymbol const *psym = sym_FindSymbol(s); + struct Symbol const *sym = sym_FindSymbol(s); - if (psym != NULL) { - if (sym_IsDefined(psym)) { - if (!sym_IsNumeric(psym)) - yyerror("'%s' is a macro or string symbol", s); - - return sym_GetValue(psym); - } - } - - yyerror("'%s' not defined", s); + if (sym == NULL || !sym_IsDefined(sym)) + yyerror("'%s' not defined", s); + else if (!sym_IsNumeric(sym)) + yyerror("'%s' is a macro or string symbol", s); + else + return sym_GetValue(sym); return 0; } -struct sSymbol *sym_GetCurrentSymbolScope(void) +struct Symbol *sym_GetCurrentSymbolScope(void) { - return pScope; + return symbolScope; } -void sym_SetCurrentSymbolScope(struct sSymbol *pNewScope) +void sym_SetCurrentSymbolScope(struct Symbol *newScope) { - pScope = pNewScope; -} - -/* - * Find a macro by name - */ -struct sSymbol *sym_FindMacro(char const *s) -{ - return findsymbol(s, NULL); + symbolScope = newScope; } /* @@ -293,15 +279,15 @@ struct sSymbol *sym_FindMacro(char const *s) * hasn't already been defined or referenced in a context that would * require that it be relocatable */ -static struct sSymbol *createNonrelocSymbol(char const *symbolName) +static struct Symbol *createNonrelocSymbol(char const *symbolName) { - struct sSymbol *symbol = findsymbol(symbolName, NULL); + struct Symbol *symbol = findsymbol(symbolName, NULL); if (!symbol) symbol = createsymbol(symbolName); else if (sym_IsDefined(symbol)) yyerror("'%s' already defined at %s(%u)", symbolName, - symbol->tzFileName, symbol->nFileLine); + symbol->fileName, symbol->fileLine); return symbol; } @@ -309,16 +295,15 @@ static struct sSymbol *createNonrelocSymbol(char const *symbolName) /* * Add an equated symbol */ -struct sSymbol *sym_AddEqu(char const *tzSym, int32_t value) +struct Symbol *sym_AddEqu(char const *symName, int32_t value) { - struct sSymbol *nsym = createNonrelocSymbol(tzSym); + struct Symbol *sym = createNonrelocSymbol(symName); - nsym->nValue = value; - nsym->type = SYM_EQU; - nsym->pScope = NULL; - updateSymbolFilename(nsym); + sym->type = SYM_EQU; + sym->callback = NULL; + sym->value = value; - return nsym; + return sym; } /* @@ -333,190 +318,175 @@ struct sSymbol *sym_AddEqu(char const *tzSym, int32_t value) * of the string are enough: sym_AddString("M_PI", "3.1415"). This is the same * as ``` M_PI EQUS "3.1415" ``` */ -struct sSymbol *sym_AddString(char const *tzSym, char const *tzValue) +struct Symbol *sym_AddString(char const *symName, char const *value) { - struct sSymbol *nsym = createNonrelocSymbol(tzSym); + struct Symbol *sym = createNonrelocSymbol(symName); + size_t len = strlen(value); + char *string = malloc(len + 1); - nsym->pMacro = malloc(strlen(tzValue) + 1); - - if (nsym->pMacro != NULL) - strcpy(nsym->pMacro, tzValue); - else + if (string == NULL) fatalerror("No memory for string equate"); + strcpy(string, value); - nsym->type = SYM_EQUS; - nsym->ulMacroSize = strlen(tzValue); - nsym->pScope = NULL; + sym->type = SYM_EQUS; + /* TODO: use other fields */ + sym->macroSize = len; + sym->macro = string; - return nsym; + return sym; } /* * Alter a SET symbols value */ -struct sSymbol *sym_AddSet(char const *tzSym, int32_t value) +struct Symbol *sym_AddSet(char const *symName, int32_t value) { - struct sSymbol *nsym = findsymbol(tzSym, NULL); + struct Symbol *sym = findsymbol(symName, NULL); - if (nsym != NULL) { - if (sym_IsDefined(nsym)) { - if (nsym->type == SYM_LABEL) - yyerror("'%s' already defined as non-constant at %s(%u)", - tzSym, - nsym->tzFileName, - nsym->nFileLine); - else if (nsym->type != SYM_SET) - yyerror("'%s' already defined as constant at %s(%u)", - tzSym, - nsym->tzFileName, - nsym->nFileLine); - } else if (nsym->type == SYM_REF) { - yyerror("'%s' already referenced at %s(%u)", - tzSym, - nsym->tzFileName, - nsym->nFileLine); - } - } else { - nsym = createsymbol(tzSym); - } + if (sym == NULL) + sym = createsymbol(symName); + else if (sym_IsDefined(sym) && sym->type != SYM_SET) + yyerror("'%s' already defined as %s at %s(%u)", symName, + sym->type == SYM_LABEL ? "label" : "constant", + sym->fileName, sym->fileLine); + else + /* TODO: can the scope be incorrect when talking over refs? */ + updateSymbolFilename(sym); - nsym->nValue = value; - nsym->type = SYM_SET; - nsym->pScope = NULL; - updateSymbolFilename(nsym); + sym->type = SYM_SET; + sym->callback = NULL; + sym->value = value; - return nsym; + return sym; } /* * Add a local (.name) relocatable symbol */ -struct sSymbol *sym_AddLocalReloc(char const *tzSym) +struct Symbol *sym_AddLocalReloc(char const *symName) { - if (pScope) { - char fullname[MAXSYMLEN + 1]; - - fullSymbolName(fullname, sizeof(fullname), tzSym, pScope); - return sym_AddReloc(fullname); + if (!symbolScope) { + yyerror("Local label '%s' in main scope", symName); + return NULL; } - yyerror("Local label '%s' in main scope", tzSym); - return NULL; + char fullname[MAXSYMLEN + 1]; + + fullSymbolName(fullname, sizeof(fullname), symName, symbolScope); + return sym_AddReloc(fullname); } /* * Add a relocatable symbol */ -struct sSymbol *sym_AddReloc(char const *tzSym) +struct Symbol *sym_AddReloc(char const *symName) { - struct sSymbol *scope = NULL; - struct sSymbol *nsym; - char *localPtr = strchr(tzSym, '.'); + struct Symbol const *scope = NULL; + char *localPtr = strchr(symName, '.'); if (localPtr != NULL) { - if (!pScope) { + if (!symbolScope) { yyerror("Local label in main scope"); return NULL; } - struct sSymbol *parent = pScope->pScope ? - pScope->pScope : pScope; - uint32_t parentLen = localPtr - tzSym; + scope = symbolScope->scope ? symbolScope->scope : symbolScope; + uint32_t parentLen = localPtr - symName; if (strchr(localPtr + 1, '.') != NULL) fatalerror("'%s' is a nonsensical reference to a nested local symbol", - tzSym); - else if (strlen(parent->tzName) != parentLen - || strncmp(tzSym, parent->tzName, parentLen) != 0) + symName); + else if (strlen(scope->name) != parentLen + || strncmp(symName, scope->name, parentLen) != 0) yyerror("Not currently in the scope of '%.*s'", - parentLen, tzSym); - - scope = parent; + parentLen, symName); } - nsym = findsymbol(tzSym, scope); + struct Symbol *sym = findsymbol(symName, scope); - if (!nsym) - nsym = createsymbol(tzSym); - else if (sym_IsDefined(nsym)) - yyerror("'%s' already defined in %s(%d)", tzSym, - nsym->tzFileName, nsym->nFileLine); + if (!sym) + sym = createsymbol(symName); + else if (sym_IsDefined(sym)) + yyerror("'%s' already defined in %s(%d)", symName, + sym->fileName, sym->fileLine); /* If the symbol already exists as a ref, just "take over" it */ - nsym->nValue = curOffset; - nsym->type = SYM_LABEL; + sym->type = SYM_LABEL; + sym->callback = NULL; + sym->value = curOffset; if (exportall) - nsym->isExported = true; + sym->isExported = true; - nsym->pScope = scope; - nsym->pSection = sect_GetSymbolSection(); + sym->scope = scope; + sym->section = sect_GetSymbolSection(); /* Labels need to be assigned a section, except PC */ - if (!pCurrentSection && strcmp(tzSym, "@")) + if (!sym->section && strcmp(symName, "@")) yyerror("Label \"%s\" created outside of a SECTION", - tzSym); + symName); - updateSymbolFilename(nsym); + updateSymbolFilename(sym); - pScope = findsymbol(tzSym, scope); - return pScope; + /* Set the symbol as the new scope */ + /* TODO: don't do this for local labels */ + symbolScope = findsymbol(symName, scope); + return symbolScope; } /* * Export a symbol */ -void sym_Export(char const *tzSym) +void sym_Export(char const *symName) { - struct sSymbol *nsym = sym_FindSymbol(tzSym); + struct Symbol *sym = sym_FindSymbol(symName); /* If the symbol doesn't exist, create a ref that can be purged */ - if (!nsym) - nsym = sym_Ref(tzSym); - nsym->isExported = true; + if (!sym) + sym = sym_Ref(symName); + sym->isExported = true; } /* * Add a macro definition */ -struct sSymbol *sym_AddMacro(char const *tzSym, int32_t nDefLineNo) +struct Symbol *sym_AddMacro(char const *symName, int32_t defLineNo) { - struct sSymbol *nsym = createNonrelocSymbol(tzSym); + struct Symbol *sym = createNonrelocSymbol(symName); - nsym->type = SYM_MACRO; - nsym->pScope = NULL; - nsym->ulMacroSize = ulNewMacroSize; - nsym->pMacro = tzNewMacro; - updateSymbolFilename(nsym); + sym->type = SYM_MACRO; + sym->macroSize = ulNewMacroSize; + sym->macro = tzNewMacro; + updateSymbolFilename(sym); /* * The symbol is created at the line after the `endm`, * override this with the actual definition line */ - nsym->nFileLine = nDefLineNo; + sym->fileLine = defLineNo; - return nsym; + return sym; } /* * Flag that a symbol is referenced in an RPN expression * and create it if it doesn't exist yet */ -struct sSymbol *sym_Ref(char const *tzSym) +struct Symbol *sym_Ref(char const *symName) { - struct sSymbol *nsym = sym_FindSymbol(tzSym); + struct Symbol *nsym = sym_FindSymbol(symName); if (nsym == NULL) { char fullname[MAXSYMLEN + 1]; - if (*tzSym == '.') { - if (!pScope) + if (*symName == '.') { + if (!symbolScope) fatalerror("Local label reference '%s' in main scope", - tzSym); - fullSymbolName(fullname, sizeof(fullname), tzSym, - pScope); - tzSym = fullname; + symName); + fullSymbolName(fullname, sizeof(fullname), symName, + symbolScope); + symName = fullname; } - nsym = createsymbol(tzSym); + nsym = createsymbol(symName); nsym->type = SYM_REF; } @@ -547,22 +517,21 @@ static inline char const *removeLeadingZeros(char const *ptr) */ void sym_Init(void) { - pPCSymbol = sym_AddReloc("@"); - pPCSymbol->Callback = CallbackPC; - pPCSymbol->isBuiltin = true; - p_NARGSymbol = sym_AddEqu("_NARG", 0); - p_NARGSymbol->Callback = Callback_NARG; - p_NARGSymbol->isBuiltin = true; - p__LINE__Symbol = sym_AddEqu("__LINE__", 0); - p__LINE__Symbol->Callback = Callback__LINE__; - p__LINE__Symbol->isBuiltin = true; - struct sSymbol *_RSSymbol = sym_AddSet("_RS", 0); + struct Symbol *_NARGSymbol = sym_AddEqu("_NARG", 0); + struct Symbol *__LINE__Symbol = sym_AddEqu("__LINE__", 0); - _RSSymbol->isBuiltin = true; + PCSymbol = sym_AddReloc("@"), + PCSymbol->isBuiltin = true; + PCSymbol->callback = CallbackPC; + _NARGSymbol->isBuiltin = true; + _NARGSymbol->callback = Callback_NARG; + __LINE__Symbol->isBuiltin = true; + __LINE__Symbol->callback = Callback__LINE__; + sym_AddSet("_RS", 0)->isBuiltin = true; - sym_AddEqu("__RGBDS_MAJOR__", PACKAGE_VERSION_MAJOR); - sym_AddEqu("__RGBDS_MINOR__", PACKAGE_VERSION_MINOR); - sym_AddEqu("__RGBDS_PATCH__", PACKAGE_VERSION_PATCH); + sym_AddEqu("__RGBDS_MAJOR__", PACKAGE_VERSION_MAJOR)->isBuiltin = true; + sym_AddEqu("__RGBDS_MINOR__", PACKAGE_VERSION_MINOR)->isBuiltin = true; + sym_AddEqu("__RGBDS_PATCH__", PACKAGE_VERSION_PATCH)->isBuiltin = true; time_t now = time(NULL); @@ -575,43 +544,38 @@ void sym_Init(void) const struct tm *time_utc = gmtime(&now); const struct tm *time_local = localtime(&now); - strftime(SavedTIME, sizeof(SavedTIME), "\"%H:%M:%S\"", - time_local); - strftime(SavedDATE, sizeof(SavedDATE), "\"%d %B %Y\"", - time_local); - strftime(SavedTIMESTAMP_ISO8601_LOCAL, - sizeof(SavedTIMESTAMP_ISO8601_LOCAL), "\"%Y-%m-%dT%H-%M-%S%z\"", + strftime(savedTIME, sizeof(savedTIME), "\"%H:%M:%S\"", time_local); + strftime(savedDATE, sizeof(savedDATE), "\"%d %B %Y\"", time_local); + strftime(savedTIMESTAMP_ISO8601_LOCAL, + sizeof(savedTIMESTAMP_ISO8601_LOCAL), "\"%Y-%m-%dT%H-%M-%S%z\"", time_local); - strftime(SavedTIMESTAMP_ISO8601_UTC, - sizeof(SavedTIMESTAMP_ISO8601_UTC), "\"%Y-%m-%dT%H-%M-%SZ\"", + strftime(savedTIMESTAMP_ISO8601_UTC, + sizeof(savedTIMESTAMP_ISO8601_UTC), "\"%Y-%m-%dT%H-%M-%SZ\"", time_utc); - strftime(SavedYEAR, sizeof(SavedYEAR), "%Y", time_utc); - strftime(SavedMONTH, sizeof(SavedMONTH), "%m", time_utc); - strftime(SavedDAY, sizeof(SavedDAY), "%d", time_utc); - strftime(SavedHOUR, sizeof(SavedHOUR), "%H", time_utc); - strftime(SavedMINUTE, sizeof(SavedMINUTE), "%M", time_utc); - strftime(SavedSECOND, sizeof(SavedSECOND), "%S", time_utc); + strftime(savedYEAR, sizeof(savedYEAR), "%Y", time_utc); + strftime(savedMONTH, sizeof(savedMONTH), "%m", time_utc); + strftime(savedDAY, sizeof(savedDAY), "%d", time_utc); + strftime(savedHOUR, sizeof(savedHOUR), "%H", time_utc); + strftime(savedMINUTE, sizeof(savedMINUTE), "%M", time_utc); + strftime(savedSECOND, sizeof(savedSECOND), "%S", time_utc); -#define addString(name, val) do { \ - struct sSymbol *symbol = sym_AddString(name, val); \ - symbol->isBuiltin = true; \ -} while (0) - addString("__TIME__", SavedTIME); - addString("__DATE__", SavedDATE); - addString("__ISO_8601_LOCAL__", SavedTIMESTAMP_ISO8601_LOCAL); - addString("__ISO_8601_UTC__", SavedTIMESTAMP_ISO8601_UTC); +#define addString(name, val) sym_AddString(name, val)->isBuiltin = true + addString("__TIME__", savedTIME); + addString("__DATE__", savedDATE); + addString("__ISO_8601_LOCAL__", savedTIMESTAMP_ISO8601_LOCAL); + addString("__ISO_8601_UTC__", savedTIMESTAMP_ISO8601_UTC); /* This cannot start with zeros */ - addString("__UTC_YEAR__", SavedYEAR); - addString("__UTC_MONTH__", removeLeadingZeros(SavedMONTH)); - addString("__UTC_DAY__", removeLeadingZeros(SavedDAY)); - addString("__UTC_HOUR__", removeLeadingZeros(SavedHOUR)); - addString("__UTC_MINUTE__", removeLeadingZeros(SavedMINUTE)); - addString("__UTC_SECOND__", removeLeadingZeros(SavedSECOND)); + addString("__UTC_YEAR__", savedYEAR); + addString("__UTC_MONTH__", removeLeadingZeros(savedMONTH)); + addString("__UTC_DAY__", removeLeadingZeros(savedDAY)); + addString("__UTC_HOUR__", removeLeadingZeros(savedHOUR)); + addString("__UTC_MINUTE__", removeLeadingZeros(savedMINUTE)); + addString("__UTC_SECOND__", removeLeadingZeros(savedSECOND)); #undef addString - pScope = NULL; + symbolScope = NULL; math_DefinePI(); } diff --git a/test/asm/macro-@.err b/test/asm/macro-@.err index 1284eecb..09a94705 100644 --- a/test/asm/macro-@.err +++ b/test/asm/macro-@.err @@ -1,4 +1,5 @@ ERROR: macro-@.asm(1): Label "foo" created outside of a SECTION ERROR: macro-@.asm(1): - Macro '@' not defined + "@" is not a macro +error: Assembly aborted (2 errors)! diff --git a/test/asm/reference-undefined-sym.asm b/test/asm/reference-undefined-sym.asm index 68c83f1e..e12c2274 100644 --- a/test/asm/reference-undefined-sym.asm +++ b/test/asm/reference-undefined-sym.asm @@ -1,4 +1,4 @@ -SECTION "sec", ROM0 +SECTION "sec", ROM0[0] db X X = 2 diff --git a/test/asm/reference-undefined-sym.err b/test/asm/reference-undefined-sym.err index e55ee236..e69de29b 100644 --- a/test/asm/reference-undefined-sym.err +++ b/test/asm/reference-undefined-sym.err @@ -1,3 +0,0 @@ -ERROR: reference-undefined-sym.asm(4): - 'X' already referenced at reference-undefined-sym.asm(2) -error: Assembly aborted (1 errors)! diff --git a/test/asm/reference-undefined-sym.out.bin b/test/asm/reference-undefined-sym.out.bin new file mode 100644 index 00000000..e69de29b diff --git a/test/asm/symbol-override.err b/test/asm/symbol-override.err index 352ec342..9dce916d 100644 --- a/test/asm/symbol-override.err +++ b/test/asm/symbol-override.err @@ -3,5 +3,5 @@ ERROR: symbol-override.asm(6): ERROR: symbol-override.asm(10): 'X' already defined as constant at symbol-override.asm(9) ERROR: symbol-override.asm(14): - 'Y' already defined as non-constant at symbol-override.asm(13) + 'Y' already defined as label at symbol-override.asm(13) error: Assembly aborted (3 errors)!