diff --git a/include/asm/output.h b/include/asm/output.h index 46fffb3b..f888f6bd 100644 --- a/include/asm/output.h +++ b/include/asm/output.h @@ -40,7 +40,6 @@ void out_AbsByteGroup(char *s, int32_t length); void out_RelByte(struct Expression *expr); void out_RelWord(struct Expression *expr); void out_PCRelByte(struct Expression *expr); -void out_CheckErrors(void); void out_WriteObject(void); void out_Skip(int32_t skip); void out_BinaryFile(char *s); diff --git a/include/asm/symbol.h b/include/asm/symbol.h index 65aa6ef6..cd470f5d 100644 --- a/include/asm/symbol.h +++ b/include/asm/symbol.h @@ -9,20 +9,33 @@ #ifndef RGBDS_SYMBOL_H #define RGBDS_SYMBOL_H +#include #include +#include #include "types.h" #define HASHSIZE (1 << 16) #define MAXSYMLEN 256 +enum SymbolType { + SYM_LABEL, + SYM_EQU, + SYM_SET, + SYM_MACRO, + SYM_EQUS, + SYM_REF // Forward reference to a label +}; + struct sSymbol { char tzName[MAXSYMLEN + 1]; - int32_t nValue; - uint32_t nType; + enum SymbolType type; + bool isConstant; /* Whether the symbol's value is currently known */ + bool isExported; /* Whether the symbol is to be exported */ struct sSymbol *pScope; struct sSymbol *pNext; struct Section *pSection; + int32_t nValue; uint32_t ulMacroSize; char *pMacro; int32_t (*Callback)(struct sSymbol *self); @@ -30,26 +43,49 @@ struct sSymbol { uint32_t nFileLine; /* Line where the symbol was defined. */ }; -/* Symbol will be relocated during linking, it's absolute value is unknown */ +static inline bool sym_IsDefined(struct sSymbol const *sym) +{ + return sym->type != SYM_REF; +} +static inline bool sym_IsConstant(struct sSymbol const *sym) +{ + return sym->isConstant; +} +static inline bool sym_IsNumeric(struct sSymbol const *sym) +{ + return sym->type == SYM_LABEL || sym->type == SYM_EQU + || sym->type == SYM_SET; +} +static inline bool sym_IsLocal(struct sSymbol const *sym) +{ + return (sym->type == SYM_LABEL || sym->type == SYM_REF) + && strchr(sym->tzName, '.'); +} +static inline bool sym_IsExported(struct sSymbol const *sym) +{ + return sym->isExported; +} +/* Symbol will be relocated during linking, it's absolute value is unknown #define SYMF_RELOC 0x001 -/* Symbol is defined using EQU, will not be changed during linking */ +Symbol is defined using EQU, will not be changed during linking #define SYMF_EQU 0x002 -/* Symbol is (re)defined using SET, will not be changed during linking */ +Symbol is (re)defined using SET, will not be changed during linking #define SYMF_SET 0x004 -/* Symbol should be exported */ +Symbol should be exported #define SYMF_EXPORT 0x008 -/* Symbol referenced in RPN expression */ +Symbol referenced in RPN expression #define SYMF_REF 0x010 -/* Symbol is a local symbol */ +Symbol is a local symbol #define SYMF_LOCAL 0x020 -/* Symbol has been defined, not only referenced */ +Symbol has been defined, not only referenced #define SYMF_DEFINED 0x040 -/* Symbol is a macro */ +Symbol is a macro #define SYMF_MACRO 0x080 -/* Symbol is a stringsymbol */ +Symbol is a stringsymbol #define SYMF_STRING 0x100 -/* Symbol has a constant value, will not be changed during linking */ +Symbol has a constant value, will not be changed during linking #define SYMF_CONST 0x200 +*/ uint32_t sym_CalcHash(const char *s); void sym_SetExportAll(uint8_t set); @@ -67,22 +103,18 @@ void sym_AddEqu(char *tzSym, int32_t value); void sym_AddSet(char *tzSym, int32_t value); void sym_Init(void); uint32_t sym_GetConstantValue(char *s); -uint32_t sym_isConstant(char *s); struct sSymbol *sym_FindSymbol(char *tzName); char *sym_FindMacroArg(int32_t i); -char *sym_GetStringValue(char *tzSym); +char *sym_GetStringValue(struct sSymbol const *sym); void sym_UseCurrentMacroArgs(void); void sym_SetMacroArgID(uint32_t nMacroCount); -uint32_t sym_isString(char *tzSym); void sym_AddMacro(char *tzSym, int32_t nDefLineNo); void sym_Ref(char *tzSym); void sym_ShiftCurrentMacroArgs(void); void sym_AddString(char *tzSym, char *tzValue); uint32_t sym_GetDefinedValue(char *s); -uint32_t sym_isDefined(char *tzName); void sym_Purge(char *tzName); -uint32_t sym_isConstDefined(char *tzName); -int32_t sym_IsRelocDiffDefined(char *tzSym1, char *tzSym2); +bool sym_IsRelocDiffDefined(char *tzSym1, char *tzSym2); /* Functions to save and restore the current symbol scope. */ struct sSymbol *sym_GetCurrentSymbolScope(void); diff --git a/include/link/symbol.h b/include/link/symbol.h index 3733cdf6..14210f7e 100644 --- a/include/link/symbol.h +++ b/include/link/symbol.h @@ -19,7 +19,7 @@ struct Symbol { /* Info contained in the object files */ char *name; - enum SymbolType type; + enum ExportLevel type; char const *objFileName; char *fileName; int32_t lineNo; diff --git a/include/linkdefs.h b/include/linkdefs.h index 74665805..e154791e 100644 --- a/include/linkdefs.h +++ b/include/linkdefs.h @@ -59,7 +59,7 @@ enum SectionType { SECTTYPE_INVALID }; -enum SymbolType { +enum ExportLevel { SYMTYPE_LOCAL, SYMTYPE_IMPORT, SYMTYPE_EXPORT diff --git a/src/asm/asmy.y b/src/asm/asmy.y index 22d27da6..fe36cdf3 100644 --- a/src/asm/asmy.y +++ b/src/asm/asmy.y @@ -78,13 +78,14 @@ static void bankrangecheck(char *name, uint32_t secttype, int32_t org, out_NewAbsSection(name, secttype, org, bank); } -size_t symvaluetostring(char *dest, size_t maxLength, char *sym, +size_t symvaluetostring(char *dest, size_t maxLength, char *symName, const char *mode) { size_t length; + struct sSymbol *sym = sym_FindSymbol(symName); - if (sym_isString(sym)) { - char *src = sym_GetStringValue(sym); + if (sym && sym->type == SYM_EQUS) { + char const *src = sym_GetStringValue(sym); size_t i; if (mode) @@ -100,7 +101,7 @@ size_t symvaluetostring(char *dest, size_t maxLength, char *sym, length = i; } else { - uint32_t value = sym_GetConstantValue(sym); + uint32_t value = sym_GetConstantValue(symName); int32_t fullLength; /* Special cheat for binary */ @@ -1307,7 +1308,11 @@ relocconst : T_ID oDontExpandStrings = true; } '(' T_ID ')' { - rpn_Number(&$$, sym_isConstDefined($4)); + struct sSymbol const *sym = sym_FindSymbol($4); + if (sym && !(sym_IsDefined(sym) && sym->type != SYM_LABEL)) + yyerror("Label \"%s\" is not a valid argument to DEF", + $4); + rpn_Number(&$$, !!sym); oDontExpandStrings = false; } | T_OP_ROUND '(' const ')' @@ -1447,7 +1452,11 @@ const : T_ID { constexpr_Symbol(&$$, $1); } oDontExpandStrings = true; } '(' T_ID ')' { - constexpr_Number(&$$, sym_isConstDefined($4)); + struct sSymbol const *sym = sym_FindSymbol($4); + if (sym && !(sym_IsDefined(sym) && sym->type != SYM_LABEL)) + yyerror("Label \"%s\" is not a valid argument to DEF", + $4); + constexpr_Number(&$$, !!sym); oDontExpandStrings = false; } | T_OP_STRCMP '(' string comma string ')' diff --git a/src/asm/constexpr.c b/src/asm/constexpr.c index 093d8bb6..5a60c621 100644 --- a/src/asm/constexpr.c +++ b/src/asm/constexpr.c @@ -24,15 +24,13 @@ void constexpr_Symbol(struct ConstExpression *expr, char *tzSym) { - if (!sym_isConstant(tzSym)) { - struct sSymbol *pSym = sym_FindSymbol(tzSym); + struct sSymbol *sym = sym_FindSymbol(tzSym); - if (pSym != NULL) { - expr->u.pSym = pSym; - expr->isSym = 1; - } else { - fatalerror("'%s' not defined", tzSym); - } + if (!sym) { + fatalerror("'%s' not defined", tzSym); + } else if (!sym_IsConstant(sym)) { + expr->u.pSym = sym; + expr->isSym = 1; } else { constexpr_Number(expr, sym_GetConstantValue(tzSym)); } @@ -41,23 +39,21 @@ void constexpr_Symbol(struct ConstExpression *expr, char *tzSym) void constexpr_BankSymbol(struct ConstExpression *expr, char *tzSym) { constexpr_Number(expr, 0); + struct sSymbol *sym = sym_FindSymbol(tzSym); - if (sym_FindSymbol(tzSym) == pPCSymbol) { + if (!sym) { + yyerror("BANK argument doesn't exist"); + } else if (sym == pPCSymbol) { if (pCurrentSection->nBank == -1) - yyerror("%s's bank is not known yet", tzSym); + yyerror("Current bank is not known yet"); else constexpr_Number(expr, pCurrentSection->nBank); - } else if (sym_isConstant(tzSym)) { - yyerror("BANK argument must be a relocatable identifier"); + } else if (sym->type != SYM_LABEL) { + yyerror("BANK argument must be a label"); + } else if (sym->pSection->nBank == -1) { + yyerror("BANK argument's bank is not known yet'"); } else { - struct sSymbol *pSymbol = sym_FindSymbol(tzSym); - - if (!pSymbol) - yyerror("BANK argument doesn't exist"); - else if (!pSymbol->pSection || pSymbol->pSection->nBank == -1) - yyerror("BANK argument must be a relocatable identifier"); - else - constexpr_Number(expr, pSymbol->pSection->nBank); + constexpr_Number(expr, sym->pSection->nBank); } } diff --git a/src/asm/globlex.c b/src/asm/globlex.c index 0d6e0198..978126a4 100644 --- a/src/asm/globlex.c +++ b/src/asm/globlex.c @@ -277,20 +277,24 @@ uint32_t ParseSymbol(char *src, uint32_t size) yyunputstr(rest); /* If the symbol is an EQUS, expand it */ - if (!oDontExpandStrings && sym_isString(dest)) { - char *s; + if (!oDontExpandStrings) { + struct sSymbol const *sym = sym_FindSymbol(dest); - lex_BeginStringExpansion(dest); + if (sym && sym->type == SYM_EQUS) { + char *s; - /* Feed the symbol's contents into the buffer */ - yyunputstr(s = sym_GetStringValue(dest)); + lex_BeginStringExpansion(dest); - /* Lines inserted this way shall not increase nLineNo */ - while (*s) { - if (*s++ == '\n') - nLineNo--; + /* Feed the symbol's contents into the buffer */ + yyunputstr(s = sym_GetStringValue(sym)); + + /* Lines inserted this way shall not increase nLineNo */ + while (*s) { + if (*s++ == '\n') + nLineNo--; + } + return 0; } - return 0; } strcpy(yylval.tzSym, dest); diff --git a/src/asm/main.c b/src/asm/main.c index 669e389a..f74b8277 100644 --- a/src/asm/main.c +++ b/src/asm/main.c @@ -471,7 +471,6 @@ int main(int argc, char *argv[]) (int)(60 / timespent * nTotalLines)); } - out_CheckErrors(); /* If no path specified, don't write file */ if (tzObjectname != NULL) out_WriteObject(); diff --git a/src/asm/output.c b/src/asm/output.c index ca82446f..1a019682 100644 --- a/src/asm/output.c +++ b/src/asm/output.c @@ -45,7 +45,7 @@ struct Patch { struct PatchSymbol { uint32_t ID; - struct sSymbol *pSymbol; + struct sSymbol const *pSymbol; struct PatchSymbol *pNext; struct PatchSymbol *pBucketNext; /* next symbol in hash table bucket */ }; @@ -186,7 +186,7 @@ static void fputlong(uint32_t i, FILE *f) /* * Write a NULL-terminated string to a file */ -static void fputstring(char *s, FILE *f) +static void fputstring(char const *s, FILE *f) { while (*s) fputc(*s++, f); @@ -259,15 +259,15 @@ static void writesection(struct Section *pSect, FILE *f) /* * Write a symbol to a file */ -static void writesymbol(struct sSymbol *pSym, FILE *f) +static void writesymbol(struct sSymbol const *pSym, FILE *f) { uint32_t type; uint32_t offset; int32_t sectid; - if (!(pSym->nType & SYMF_DEFINED)) + if (!sym_IsDefined(pSym)) type = SYMTYPE_IMPORT; - else if (pSym->nType & SYMF_EXPORT) + else if (pSym->isExported) type = SYMTYPE_EXPORT; else type = SYMTYPE_LOCAL; @@ -283,7 +283,7 @@ static void writesymbol(struct sSymbol *pSym, FILE *f) break; case SYMTYPE_EXPORT: offset = pSym->nValue; - if (pSym->nType & SYMF_CONST) + if (pSym->type != SYM_LABEL) sectid = -1; else sectid = getsectid(pSym->pSection); @@ -307,7 +307,7 @@ static void writesymbol(struct sSymbol *pSym, FILE *f) */ static uint32_t nextID; -static uint32_t addsymbol(struct sSymbol *pSym) +static uint32_t addsymbol(struct sSymbol const *pSym) { struct PatchSymbol *pPSym, **ppPSym; uint32_t hash; @@ -350,7 +350,7 @@ static void addexports(void) pSym = tHashedSymbols[i]; while (pSym) { - if (pSym->nType & SYMF_EXPORT) + if (pSym->isExported) addsymbol(pSym); pSym = pSym->pNext; } @@ -409,11 +409,16 @@ void createpatch(uint32_t type, struct Expression *expr) rpnexpr[rpnptr++] = rpn_PopByte(expr); break; case RPN_SYM: + { symptr = 0; while ((tzSym[symptr++] = rpn_PopByte(expr)) != 0) ; - if (sym_isConstant(tzSym)) { + struct sSymbol const *sym = sym_FindSymbol(tzSym); + + if (!sym) { + break; // TODO: wtf? + } else if (sym_IsConstant(sym)) { uint32_t value; value = sym_GetConstantValue(tzSym); @@ -423,11 +428,6 @@ void createpatch(uint32_t type, struct Expression *expr) rpnexpr[rpnptr++] = value >> 16; rpnexpr[rpnptr++] = value >> 24; } else { - struct sSymbol *sym = sym_FindSymbol(tzSym); - - if (sym == NULL) - break; - symptr = addsymbol(sym); rpnexpr[rpnptr++] = RPN_SYM; rpnexpr[rpnptr++] = symptr & 0xFF; @@ -436,6 +436,7 @@ void createpatch(uint32_t type, struct Expression *expr) rpnexpr[rpnptr++] = symptr >> 24; } break; + } case RPN_BANK_SYM: { struct sSymbol *sym; @@ -526,34 +527,6 @@ static void checksectionoverflow(uint32_t delta_size) } } -/* - * Check for errors that could happen while writing an object file - * This is important as out_WriteObject is skipped entirely when `-o` is omitted - * Therefore, errors such as memory allocations still should be handled in - * out_WriteObject and not here - */ -void out_CheckErrors(void) -{ - /* Local symbols cannot be imported from elsewhere */ - struct PatchSymbol *pSym = pPatchSymbols; - - while (pSym) { - struct sSymbol *pSymbol = pSym->pSymbol; - - if (!(pSymbol->nType & SYMF_DEFINED) - && pSymbol->nType & SYMF_LOCAL) { - char *name = pSymbol->tzName; - char *localPtr = strchr(name, '.'); - - if (localPtr) - name = localPtr; - errx(1, "%s(%u) : '%s' not defined", - pSymbol->tzFileName, pSymbol->nFileLine, name); - } - pSym = pSym->pNext; - } -} - /* * Write an objectfile */ @@ -690,6 +663,7 @@ void out_SetCurrentSection(struct Section *pSect) pPCSymbol->nValue = nPC; pPCSymbol->pSection = pCurrentSection; + pPCSymbol->isConstant = pSect && pSect->nOrg != -1; } /* diff --git a/src/asm/rpn.c b/src/asm/rpn.c index 0d45829a..8abd10bd 100644 --- a/src/asm/rpn.c +++ b/src/asm/rpn.c @@ -143,7 +143,9 @@ void rpn_Number(struct Expression *expr, uint32_t i) void rpn_Symbol(struct Expression *expr, char *tzSym) { - if (!sym_isConstant(tzSym)) { + struct sSymbol *sym = sym_FindSymbol(tzSym); + + if (!sym || !sym_IsConstant(sym)) { rpn_Init(expr); sym_Ref(tzSym); expr->isReloc = 1; @@ -176,13 +178,15 @@ void rpn_BankSelf(struct Expression *expr) void rpn_BankSymbol(struct Expression *expr, char *tzSym) { + struct sSymbol const *sym = sym_FindSymbol(tzSym); + /* The @ symbol is treated differently. */ - if (sym_FindSymbol(tzSym) == pPCSymbol) { + if (sym == pPCSymbol) { rpn_BankSelf(expr); return; } - if (sym_isConstant(tzSym)) { + if (sym && sym_IsConstant(sym)) { yyerror("BANK argument must be a relocatable identifier"); } else { rpn_Init(expr); diff --git a/src/asm/symbol.c b/src/asm/symbol.c index abe227d1..5b8d5160 100644 --- a/src/asm/symbol.c +++ b/src/asm/symbol.c @@ -88,6 +88,9 @@ static int32_t getvaluefield(struct sSymbol *sym) if (sym->Callback) return sym->Callback(sym); + if (sym->type == SYM_LABEL) + return sym->nValue + sym->pSection->nOrg; + return sym->nValue; } @@ -136,12 +139,13 @@ struct sSymbol *createsymbol(char *s) if (snprintf((*ppsym)->tzName, MAXSYMLEN + 1, "%s", s) > MAXSYMLEN) warning(WARNING_LONG_STR, "Symbol name is too long: '%s'", s); - (*ppsym)->nValue = 0; - (*ppsym)->nType = 0; + (*ppsym)->isConstant = false; + (*ppsym)->isExported = false; (*ppsym)->pScope = NULL; (*ppsym)->pNext = NULL; - (*ppsym)->pMacro = NULL; (*ppsym)->pSection = NULL; + (*ppsym)->nValue = 0; + (*ppsym)->pMacro = NULL; (*ppsym)->Callback = NULL; updateSymbolFilename(*ppsym); return *ppsym; @@ -251,58 +255,15 @@ void sym_Purge(char *tzName) } } -/* - * Determine if a symbol has been defined - */ -uint32_t sym_isConstDefined(char *tzName) -{ - struct sSymbol *psym = sym_FindSymbol(tzName); - - if (psym && (psym->nType & SYMF_DEFINED)) { - uint32_t mask = SYMF_EQU | SYMF_SET | SYMF_MACRO | SYMF_STRING; - - if (psym->nType & mask) - return 1; - - fatalerror("'%s' is not allowed as argument to the DEF function", - tzName); - } - - return 0; -} - -uint32_t sym_isDefined(char *tzName) -{ - struct sSymbol *psym = sym_FindSymbol(tzName); - - return (psym && (psym->nType & SYMF_DEFINED)); -} - -/* - * Determine if the symbol is a constant - */ -uint32_t sym_isConstant(char *s) -{ - struct sSymbol *psym = sym_FindSymbol(s); - - /* The @ symbol is handled differently */ - if (psym == pPCSymbol) - return pCurrentSection->nOrg != -1; - - return (psym && (psym->nType & SYMF_CONST)); -} - /* * Get a string equate's value */ -char *sym_GetStringValue(char *tzSym) +char *sym_GetStringValue(struct sSymbol const *sym) { - const struct sSymbol *pSym = sym_FindSymbol(tzSym); + if (sym != NULL) + return sym->pMacro; - if (pSym != NULL) - return pSym->pMacro; - - yyerror("String symbol '%s' not defined", tzSym); + yyerror("String symbol '%s' not defined", sym->tzName); return NULL; } @@ -318,10 +279,10 @@ uint32_t sym_GetConstantValue(char *s) if (pCurrentSection->nOrg == -1) yyerror("Expected constant PC but section is not fixed"); else - return pPCSymbol->nValue; + return getvaluefield(psym); } else if (psym != NULL) { - if (psym->nType & SYMF_CONST) + if (sym_IsConstant(psym)) return getvaluefield(psym); fatalerror("Expression must have a constant value"); @@ -340,8 +301,8 @@ uint32_t sym_GetDefinedValue(char *s) struct sSymbol *psym = sym_FindSymbol(s); if (psym != NULL) { - if ((psym->nType & SYMF_DEFINED)) { - if (psym->nType & (SYMF_MACRO | SYMF_STRING)) + if (sym_IsDefined(psym)) { + if (!sym_IsNumeric(psym)) yyerror("'%s' is a macro or string symbol", s); return getvaluefield(psym); @@ -472,10 +433,10 @@ static struct sSymbol *createNonrelocSymbol(char *tzSym) struct sSymbol *nsym = findsymbol(tzSym, NULL); if (nsym != NULL) { - if (nsym->nType & SYMF_DEFINED) { + if (sym_IsDefined(nsym)) { yyerror("'%s' already defined at %s(%u)", tzSym, nsym->tzFileName, nsym->nFileLine); - } else if (nsym->nType & SYMF_REF) { + } else { yyerror("'%s' referenced as label at %s(%u)", tzSym, nsym->tzFileName, nsym->nFileLine); } @@ -493,12 +454,11 @@ void sym_AddEqu(char *tzSym, int32_t value) { struct sSymbol *nsym = createNonrelocSymbol(tzSym); - if (nsym) { - nsym->nValue = value; - nsym->nType |= SYMF_EQU | SYMF_DEFINED | SYMF_CONST; - nsym->pScope = NULL; - updateSymbolFilename(nsym); - } + nsym->nValue = value; + nsym->type = SYM_EQU; + nsym->isConstant = true; + nsym->pScope = NULL; + updateSymbolFilename(nsym); } /* @@ -517,28 +477,16 @@ void sym_AddString(char *tzSym, char *tzValue) { struct sSymbol *nsym = createNonrelocSymbol(tzSym); - if (nsym) { - nsym->pMacro = malloc(strlen(tzValue) + 1); + nsym->pMacro = malloc(strlen(tzValue) + 1); - if (nsym->pMacro != NULL) - strcpy(nsym->pMacro, tzValue); - else - fatalerror("No memory for string equate"); + if (nsym->pMacro != NULL) + strcpy(nsym->pMacro, tzValue); + else + fatalerror("No memory for string equate"); - nsym->nType |= SYMF_STRING | SYMF_DEFINED; - nsym->ulMacroSize = strlen(tzValue); - nsym->pScope = NULL; - } -} - -/* - * check if symbol is a string equated symbol - */ -uint32_t sym_isString(char *tzSym) -{ - const struct sSymbol *pSym = findsymbol(tzSym, NULL); - - return (pSym && (pSym->nType & SYMF_STRING)); + nsym->type = SYM_EQUS; + nsym->ulMacroSize = strlen(tzValue); + nsym->pScope = NULL; } /* @@ -549,18 +497,18 @@ void sym_AddSet(char *tzSym, int32_t value) struct sSymbol *nsym = findsymbol(tzSym, NULL); if (nsym != NULL) { - if (nsym->nType & SYMF_DEFINED) { - if (!(nsym->nType & SYMF_CONST)) + 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->nType & SYMF_SET)) + else if (nsym->type != SYM_SET) yyerror("'%s' already defined as constant at %s(%u)", tzSym, nsym->tzFileName, nsym->nFileLine); - } else if (nsym->nType & SYMF_REF) { + } else if (nsym->type == SYM_REF) { yyerror("'%s' already referenced at %s(%u)", tzSym, nsym->tzFileName, @@ -570,12 +518,11 @@ void sym_AddSet(char *tzSym, int32_t value) nsym = createsymbol(tzSym); } - if (nsym) { - nsym->nValue = value; - nsym->nType |= SYMF_SET | SYMF_DEFINED | SYMF_CONST; - nsym->pScope = NULL; - updateSymbolFilename(nsym); - } + nsym->nValue = value; + nsym->type = SYM_SET; + nsym->isConstant = true; + nsym->pScope = NULL; + updateSymbolFilename(nsym); } /* @@ -626,7 +573,7 @@ void sym_AddReloc(char *tzSym) nsym = findsymbol(tzSym, scope); if (nsym != NULL) { - if (nsym->nType & SYMF_DEFINED) { + if (sym_IsDefined(nsym)) { yyerror("'%s' already defined in %s(%d)", tzSym, nsym->tzFileName, nsym->nFileLine); } @@ -634,24 +581,21 @@ void sym_AddReloc(char *tzSym) nsym = createsymbol(tzSym); } - if (nsym) { - nsym->nValue = nPC; - nsym->nType |= SYMF_RELOC | SYMF_DEFINED; - if (localPtr) - nsym->nType |= SYMF_LOCAL; + nsym->nValue = nPC; + nsym->type = SYM_LABEL; + nsym->isConstant = pCurrentSection && pCurrentSection->nOrg != -1; - if (exportall) - nsym->nType |= SYMF_EXPORT; + if (exportall) + nsym->isExported = true; - nsym->pScope = scope; - nsym->pSection = pCurrentSection; - /* Labels need to be assigned a section, except PC */ - if (!pCurrentSection && strcmp(tzSym, "@")) - yyerror("Label \"%s\" created outside of a SECTION", - tzSym); + nsym->pScope = scope; + nsym->pSection = pCurrentSection; + /* Labels need to be assigned a section, except PC */ + if (!pCurrentSection && strcmp(tzSym, "@")) + yyerror("Label \"%s\" created outside of a SECTION", + tzSym); - updateSymbolFilename(nsym); - } + updateSymbolFilename(nsym); pScope = findsymbol(tzSym, scope); } @@ -663,7 +607,7 @@ void sym_AddReloc(char *tzSym) * * It returns 1 if the difference is defined, 0 if not. */ -int32_t sym_IsRelocDiffDefined(char *tzSym1, char *tzSym2) +bool sym_IsRelocDiffDefined(char *tzSym1, char *tzSym2) { const struct sSymbol *nsym1 = sym_FindSymbol(tzSym1); const struct sSymbol *nsym2 = sym_FindSymbol(tzSym2); @@ -675,25 +619,25 @@ int32_t sym_IsRelocDiffDefined(char *tzSym1, char *tzSym2) if (nsym2 == NULL) fatalerror("Symbol \"%s\" isn't defined.", tzSym2); - int32_t s1reloc = (nsym1->nType & SYMF_RELOC) != 0; - int32_t s2reloc = (nsym2->nType & SYMF_RELOC) != 0; + int32_t s1const = sym_IsConstant(nsym1); + int32_t s2const = sym_IsConstant(nsym2); /* Both are non-relocatable */ - if (!s1reloc && !s2reloc) - return 1; + if (s1const && s2const) + return true; /* One of them is relocatable, the other one is not. */ - if (s1reloc ^ s2reloc) - return 0; + if (s1const ^ s2const) + return false; /* * Both of them are relocatable. Make sure they are defined (internal * coherency with sym_AddReloc and sym_AddLocalReloc). */ - if (!(nsym1->nType & SYMF_DEFINED)) + if (!sym_IsDefined(nsym1)) fatalerror("Relocatable symbol \"%s\" isn't defined.", tzSym1); - if (!(nsym2->nType & SYMF_DEFINED)) + if (!sym_IsDefined(nsym2)) fatalerror("Relocatable symbol \"%s\" isn't defined.", tzSym2); /* @@ -708,13 +652,10 @@ int32_t sym_IsRelocDiffDefined(char *tzSym1, char *tzSym2) */ void sym_Export(char *tzSym) { + sym_Ref(tzSym); struct sSymbol *nsym = sym_FindSymbol(tzSym); - if (nsym == NULL) - nsym = createsymbol(tzSym); - - if (nsym) - nsym->nType |= SYMF_EXPORT; + nsym->isExported = true; } /* @@ -724,18 +665,16 @@ void sym_AddMacro(char *tzSym, int32_t nDefLineNo) { struct sSymbol *nsym = createNonrelocSymbol(tzSym); - if (nsym) { - nsym->nType |= SYMF_MACRO | SYMF_DEFINED; - nsym->pScope = NULL; - nsym->ulMacroSize = ulNewMacroSize; - nsym->pMacro = tzNewMacro; - updateSymbolFilename(nsym); - /* - * The symbol is created at the line after the `endm`, - * override this with the actual definition line - */ - nsym->nFileLine = nDefLineNo; - } + nsym->type = SYM_MACRO; + nsym->pScope = NULL; + nsym->ulMacroSize = ulNewMacroSize; + nsym->pMacro = tzNewMacro; + updateSymbolFilename(nsym); + /* + * The symbol is created at the line after the `endm`, + * override this with the actual definition line + */ + nsym->nFileLine = nDefLineNo; } /* @@ -748,7 +687,6 @@ void sym_Ref(char *tzSym) if (nsym == NULL) { char fullname[MAXSYMLEN + 1]; - int isLocal = 0; if (*tzSym == '.') { if (!pScope) @@ -757,17 +695,11 @@ void sym_Ref(char *tzSym) fullSymbolName(fullname, sizeof(fullname), tzSym, pScope); tzSym = fullname; - isLocal = 1; } nsym = createsymbol(tzSym); - - if (nsym && isLocal) - nsym->nType |= SYMF_LOCAL; + nsym->type = SYM_REF; } - - if (nsym) - nsym->nType |= SYMF_REF; } /* diff --git a/test/asm/label-diff.asm b/test/asm/label-diff.asm index 01938568..c331d6e0 100644 --- a/test/asm/label-diff.asm +++ b/test/asm/label-diff.asm @@ -27,7 +27,7 @@ POPS ; Ensure we are in neither section ; TODO: uncomment all that can be, there is seriously room for improvement here ; Diffing two constants should work -; But it doesn't yet print_diff Constant, Constant2 + print_diff Constant, Constant2 ; Diffing two labels in the same SECTION as well print_diff Known2, Known ; Diffing a constant and a "floating" label cannot work @@ -40,7 +40,7 @@ POPS ; Ensure we are in neither section ; Now let's fiddle with PC SECTION "fixed PC", ROM0[420] ; Diffing a constant and PC should work -; But it doesn't yet print_diff Constant, @ + print_diff Constant, @ ; Diffing a floating label and PC cannot work ; ...And that causes a fatal error print_diff Known, @ ; Diffinf a ref and PC cannot work @@ -49,7 +49,7 @@ SECTION "fixed PC", ROM0[420] print_diff @, @ ; Diffing PC and a label from here should work LocalFixed: -; But it doesn't yet print_diff LocalFixed, @ + print_diff LocalFixed, @ SECTION "Floating PC", ROM0 ; Diffing a constant and PC cannot work diff --git a/test/asm/label-diff.out b/test/asm/label-diff.out index 54b4570b..67533371 100644 --- a/test/asm/label-diff.out +++ b/test/asm/label-diff.out @@ -1,5 +1,11 @@ +$FFFFFFE5 +$1B $4 $FFFFFFFC +$FFFFFE86 +$17A +$0 +$0 $0 $0 $0 diff --git a/test/asm/pc-bank.err b/test/asm/pc-bank.err index cb5d4b31..e81e10cf 100644 --- a/test/asm/pc-bank.err +++ b/test/asm/pc-bank.err @@ -1,5 +1,5 @@ ERROR: pc-bank.asm(2): Source address $2a00 not in $FF00 to $FFFF ERROR: pc-bank.asm(11): - @'s bank is not known yet + Current bank is not known yet error: Assembly aborted (2 errors)! diff --git a/test/asm/pc-def.err b/test/asm/pc-def.err index c0288fa1..9b09e440 100644 --- a/test/asm/pc-def.err +++ b/test/asm/pc-def.err @@ -1,2 +1,3 @@ ERROR: pc-def.asm(1): - '@' is not allowed as argument to the DEF function + Label "@" is not a valid argument to DEF +error: Assembly aborted (1 errors)! diff --git a/test/asm/pc-def.out b/test/asm/pc-def.out index e69de29b..59dbac95 100644 --- a/test/asm/pc-def.out +++ b/test/asm/pc-def.out @@ -0,0 +1 @@ +defined diff --git a/test/asm/undefined-dot.err b/test/asm/undefined-dot.err index 511659b7..e69de29b 100644 --- a/test/asm/undefined-dot.err +++ b/test/asm/undefined-dot.err @@ -1 +0,0 @@ -error: undefined-dot.asm(3) : '.' not defined