ref: d2bd9a23684507dbb413028770c9121e01500bb0
parent: b2c1f6122eb5ed5a9070c8cf0450f0cf826f6edd
parent: b909a5063aca9b29abe15e65eb137de0904100cc
author: Antonio Niño Díaz <antonio_nd@outlook.com>
date: Fri May 31 08:10:17 EDT 2019
Merge pull request #337 from dbrotz/one-pass Use only one pass
--- a/include/asm/asm.h
+++ b/include/asm/asm.h
@@ -28,7 +28,6 @@
extern int32_t nLineNo;
extern uint32_t nTotalLines;
extern uint32_t nPC;
-extern uint32_t nPass;
extern uint32_t nIFDepth;
extern bool skipElif;
extern uint32_t nUnionDepth;
--- a/include/asm/rpn.h
+++ b/include/asm/rpn.h
@@ -18,11 +18,9 @@
uint32_t nRPNLength;
uint32_t nRPNOut;
uint32_t isReloc;
- uint32_t isPCRel;
};
uint32_t rpn_isReloc(const struct Expression *expr);
-uint32_t rpn_isPCRelative(const struct Expression *expr);
void rpn_Symbol(struct Expression *expr, char *tzSym);
void rpn_Number(struct Expression *expr, uint32_t i);
void rpn_LOGNOT(struct Expression *expr, const struct Expression *src);
--- a/include/asm/symbol.h
+++ b/include/asm/symbol.h
@@ -38,8 +38,8 @@
#define SYMF_SET 0x004
/* Symbol should be exported */
#define SYMF_EXPORT 0x008
-/* Symbol is imported, it's value is unknown */
-#define SYMF_IMPORT 0x010
+/* Symbol referenced in RPN expression */
+#define SYMF_REF 0x010
/* Symbol is a local symbol */
#define SYMF_LOCAL 0x020
/* Symbol has been defined, not only referenced */
@@ -53,8 +53,6 @@
uint32_t calchash(char *s);
void sym_SetExportAll(uint8_t set);
-void sym_PrepPass1(void);
-void sym_PrepPass2(void);
void sym_AddLocalReloc(char *tzSym);
void sym_AddReloc(char *tzSym);
void sym_Export(char *tzSym);
@@ -72,7 +70,6 @@
uint32_t sym_GetConstantValue(char *s);
uint32_t sym_isConstant(char *s);
struct sSymbol *sym_FindSymbol(char *tzName);
-void sym_Global(char *tzSym);
char *sym_FindMacroArg(int32_t i);
char *sym_GetStringValue(char *tzSym);
void sym_UseCurrentMacroArgs(void);
@@ -79,9 +76,9 @@
void sym_SetMacroArgID(uint32_t nMacroCount);
uint32_t sym_isString(char *tzSym);
void sym_AddMacro(char *tzSym);
+void sym_Ref(char *tzSym);
void sym_ShiftCurrentMacroArgs(void);
void sym_AddString(char *tzSym, char *tzValue);
-uint32_t sym_GetValue(char *s);
uint32_t sym_GetDefinedValue(char *s);
uint32_t sym_isDefined(char *tzName);
void sym_Purge(char *tzName);
--- a/src/asm/asmy.y
+++ b/src/asm/asmy.y
@@ -799,7 +799,7 @@
;
db : T_POP_DB constlist_8bit_entry comma constlist_8bit {
- if ((nPass == 1) && (nListCountEmpty > 0)) {
+ if (nListCountEmpty > 0) {
warning("Empty entry in list of 8-bit elements (treated as 0).");
}
}
@@ -807,7 +807,7 @@
;
dw : T_POP_DW constlist_16bit_entry comma constlist_16bit {
- if ((nPass == 1) && (nListCountEmpty > 0)) {
+ if (nListCountEmpty > 0) {
warning("Empty entry in list of 16-bit elements (treated as 0).");
}
}
@@ -815,7 +815,7 @@
;
dl : T_POP_DL constlist_32bit_entry comma constlist_32bit {
- if ((nPass == 1) && (nListCountEmpty > 0)) {
+ if (nListCountEmpty > 0) {
warning("Empty entry in list of 32-bit elements (treated as 0).");
}
}
@@ -852,8 +852,7 @@
* This is done automatically if the label isn't found
* in the list of defined symbols.
*/
- if (nPass == 1)
- warning("IMPORT is a deprecated keyword with no effect: %s", $1);
+ warning("IMPORT is a deprecated keyword with no effect: %s", $1);
}
;
@@ -879,7 +878,7 @@
global_list_entry : T_ID
{
- sym_Global($1);
+ sym_Export($1);
}
;
@@ -929,29 +928,25 @@
printt : T_POP_PRINTT string
{
- if (nPass == 1)
- printf("%s", $2);
+ printf("%s", $2);
}
;
printv : T_POP_PRINTV const
{
- if (nPass == 1)
- printf("$%X", constexpr_GetConstantValue(&$2));
+ printf("$%X", constexpr_GetConstantValue(&$2));
}
;
printi : T_POP_PRINTI const
{
- if (nPass == 1)
- printf("%d", constexpr_GetConstantValue(&$2));
+ printf("%d", constexpr_GetConstantValue(&$2));
}
;
printf : T_POP_PRINTF const
{
- if (nPass == 1)
- math_Print(constexpr_GetConstantValue(&$2));
+ math_Print(constexpr_GetConstantValue(&$2));
}
;
@@ -1126,7 +1121,6 @@
struct Expression sTemp, sOffset;
rpn_Symbol(&sTemp, $1);
- sTemp.nVal = sym_GetValue($1);
rpn_Number(&sOffset, nPCOffset);
@@ -1133,13 +1127,11 @@
rpn_SUB(&$$, &sTemp, &sOffset);
} else {
rpn_Symbol(&$$, $1);
- $$.nVal = sym_GetValue($1);
}
}
| T_NUMBER
{
rpn_Number(&$$, $1);
- $$.nVal = $1;
}
| string
{
@@ -1149,7 +1141,6 @@
free(s);
rpn_Number(&$$, r);
- $$.nVal = r;
}
| T_OP_LOGICNOT relocconst %prec NEG { rpn_LOGNOT(&$$, &$2); }
| relocconst T_OP_LOGICOR relocconst { rpn_LOGOR(&$$, &$1, &$3); }
@@ -1179,12 +1170,10 @@
{
/* '@' is also a T_ID, it is handled here. */
rpn_BankSymbol(&$$, $3);
- $$.nVal = 0;
}
| T_OP_BANK '(' string ')'
{
rpn_BankSection(&$$, $3);
- $$.nVal = 0;
}
| T_OP_DEF {
oDontExpandStrings = true;
@@ -1637,8 +1626,7 @@
| T_Z80_JP T_MODE_HL_IND
{
out_AbsByte(0xE9);
- if (nPass == 1)
- warning("'JP [HL]' is obsolete, use 'JP HL' instead.");
+ warning("'JP [HL]' is obsolete, use 'JP HL' instead.");
}
| T_Z80_JP T_MODE_HL
{
@@ -1665,8 +1653,7 @@
| T_Z80_LDI T_MODE_A comma T_MODE_HL
{
out_AbsByte(0x0A | (2 << 4));
- if (nPass == 1)
- warning("'LDI A,HL' is obsolete, use 'LDI A,[HL]' or 'LD A,[HL+] instead.");
+ warning("'LDI A,HL' is obsolete, use 'LDI A,[HL]' or 'LD A,[HL+] instead.");
}
| T_Z80_LDI T_MODE_A comma T_MODE_HL_IND
{
@@ -1681,8 +1668,7 @@
| T_Z80_LDD T_MODE_A comma T_MODE_HL
{
out_AbsByte(0x0A | (3 << 4));
- if (nPass == 1)
- warning("'LDD A,HL' is obsolete, use 'LDD A,[HL]' or 'LD A,[HL-] instead.");
+ warning("'LDD A,HL' is obsolete, use 'LDD A,[HL]' or 'LD A,[HL-] instead.");
}
| T_Z80_LDD T_MODE_A comma T_MODE_HL_IND
{
--- a/src/asm/charmap.c
+++ b/src/asm/charmap.c
@@ -62,9 +62,6 @@
charmap = &globalCharmap;
}
- if (nPass == 2)
- return charmap->count;
-
if (charmap->count > MAXCHARMAPS || strlen(input) > CHARMAPLENGTH)
return -1;
--- a/src/asm/main.c
+++ b/src/asm/main.c
@@ -37,7 +37,7 @@
clock_t nStartClock, nEndClock;
int32_t nLineNo;
-uint32_t nTotalLines, nPass, nPC, nIFDepth, nUnionDepth, nErrors;
+uint32_t nTotalLines, nPC, nIFDepth, nUnionDepth, nErrors;
bool skipElif;
uint32_t unionStart[128], unionSize[128];
@@ -432,21 +432,17 @@
skipElif = true;
nUnionDepth = 0;
nPC = 0;
- nPass = 1;
nErrors = 0;
- sym_PrepPass1();
+ sym_Init();
sym_SetExportAll(CurrentOptions.exportall);
fstk_Init(tzMainfile);
opt_ParseDefines();
- if (CurrentOptions.verbose)
- printf("Pass 1...\n");
-
yy_set_state(LEX_STATE_NORMAL);
opt_SetCurrentOptions(&DefaultOptions);
if (yyparse() != 0 || nErrors != 0)
- errx(1, "Assembly aborted in pass 1 (%ld errors)!", nErrors);
+ errx(1, "Assembly aborted (%ld errors)!", nErrors);
if (nIFDepth != 0)
errx(1, "Unterminated IF construct (%ld levels)!", nIFDepth);
@@ -455,27 +451,6 @@
errx(1, "Unterminated UNION construct (%ld levels)!",
nUnionDepth);
}
-
- nTotalLines = 0;
- nLineNo = 1;
- nIFDepth = 0;
- skipElif = true;
- nUnionDepth = 0;
- nPC = 0;
- nPass = 2;
- nErrors = 0;
- sym_PrepPass2();
- out_PrepPass2();
- fstk_Init(tzMainfile);
- yy_set_state(LEX_STATE_NORMAL);
- opt_SetCurrentOptions(&DefaultOptions);
- opt_ParseDefines();
-
- if (CurrentOptions.verbose)
- printf("Pass 2...\n");
-
- if (yyparse() != 0 || nErrors != 0)
- errx(1, "Assembly aborted in pass 2 (%ld errors)!", nErrors);
double timespent;
--- a/src/asm/output.c
+++ b/src/asm/output.c
@@ -259,37 +259,46 @@
*/
static void writesymbol(struct sSymbol *pSym, FILE *f)
{
- char symname[MAXSYMLEN * 2 + 1];
uint32_t type;
uint32_t offset;
int32_t sectid;
- if (pSym->nType & SYMF_IMPORT) {
- /* Symbol should be imported */
- strcpy(symname, pSym->tzName);
- offset = 0;
- sectid = -1;
+ if (!(pSym->nType & SYMF_DEFINED)) {
+ if (pSym->nType & SYMF_LOCAL) {
+ char *name = pSym->tzName;
+ char *localPtr = strchr(name, '.');
+
+ if (localPtr)
+ name = localPtr;
+ errx(1, "%s(%u) : '%s' not defined",
+ pSym->tzFileName, pSym->nFileLine, name);
+ }
type = SYM_IMPORT;
+ } else if (pSym->nType & SYMF_EXPORT) {
+ type = SYM_EXPORT;
} else {
- strcpy(symname, pSym->tzName);
+ type = SYM_LOCAL;
+ }
- if (pSym->nType & SYMF_EXPORT) {
- /* Symbol should be exported */
- type = SYM_EXPORT;
- offset = pSym->nValue;
- if (pSym->nType & SYMF_CONST)
- sectid = -1;
- else
- sectid = getsectid(pSym->pSection);
- } else {
- /* Symbol is local to this file */
- type = SYM_LOCAL;
- offset = pSym->nValue;
+ switch (type) {
+ case SYM_LOCAL:
+ offset = pSym->nValue;
+ sectid = getsectid(pSym->pSection);
+ break;
+ case SYM_IMPORT:
+ offset = 0;
+ sectid = -1;
+ break;
+ case SYM_EXPORT:
+ offset = pSym->nValue;
+ if (pSym->nType & SYMF_CONST)
+ sectid = -1;
+ else
sectid = getsectid(pSym->pSection);
- }
+ break;
}
- fputstring(symname, f);
+ fputstring(pSym->tzName, f);
fputc(type, f);
if (type != SYM_IMPORT) {
@@ -563,22 +572,6 @@
}
/*
- * Prepare for pass #2
- */
-void out_PrepPass2(void)
-{
- struct Section *pSect;
-
- pSect = pSectionList;
- while (pSect) {
- pSect->nPC = 0;
- pSect = pSect->pNext;
- }
- pCurrentSection = NULL;
- pSectionStack = NULL;
-}
-
-/*
* Set the objectfilename
*/
void out_SetFileName(char *s)
@@ -586,10 +579,6 @@
tzObjectname = s;
if (CurrentOptions.verbose)
printf("Output filename %s\n", s);
-
- pSectionList = NULL;
- pCurrentSection = NULL;
- pPatchSymbols = NULL;
}
/*
@@ -636,7 +625,6 @@
pSect->pNext = NULL;
pSect->pPatches = NULL;
pSect->charmap = NULL;
- pPatchSymbols = NULL;
/* It is only needed to allocate memory for ROM sections. */
if (secttype == SECT_ROM0 || secttype == SECT_ROMX) {
@@ -705,9 +693,7 @@
{
checksectionoverflow(1);
b &= 0xFF;
- if (nPass == 2)
- pCurrentSection->tData[nPC] = b;
-
+ pCurrentSection->tData[nPC] = b;
pCurrentSection->nPC += 1;
nPC += 1;
pPCSymbol->nValue += 1;
@@ -772,10 +758,8 @@
checkcodesection();
checksectionoverflow(1);
if (rpn_isReloc(expr)) {
- if (nPass == 2) {
- pCurrentSection->tData[nPC] = 0;
- createpatch(PATCH_BYTE, expr);
- }
+ pCurrentSection->tData[nPC] = 0;
+ createpatch(PATCH_BYTE, expr);
pCurrentSection->nPC += 1;
nPC += 1;
pPCSymbol->nValue += 1;
@@ -793,10 +777,8 @@
checkcodesection();
checksectionoverflow(2);
b &= 0xFFFF;
- if (nPass == 2) {
- pCurrentSection->tData[nPC] = b & 0xFF;
- pCurrentSection->tData[nPC + 1] = b >> 8;
- }
+ pCurrentSection->tData[nPC] = b & 0xFF;
+ pCurrentSection->tData[nPC + 1] = b >> 8;
pCurrentSection->nPC += 2;
nPC += 2;
pPCSymbol->nValue += 2;
@@ -808,17 +790,12 @@
*/
void out_RelWord(struct Expression *expr)
{
- uint32_t b;
-
checkcodesection();
checksectionoverflow(2);
- b = expr->nVal & 0xFFFF;
if (rpn_isReloc(expr)) {
- if (nPass == 2) {
- pCurrentSection->tData[nPC] = b & 0xFF;
- pCurrentSection->tData[nPC + 1] = b >> 8;
- createpatch(PATCH_WORD_L, expr);
- }
+ pCurrentSection->tData[nPC] = 0;
+ pCurrentSection->tData[nPC + 1] = 0;
+ createpatch(PATCH_WORD_L, expr);
pCurrentSection->nPC += 2;
nPC += 2;
pPCSymbol->nValue += 2;
@@ -835,12 +812,10 @@
{
checkcodesection();
checksectionoverflow(sizeof(int32_t));
- if (nPass == 2) {
- pCurrentSection->tData[nPC] = b & 0xFF;
- pCurrentSection->tData[nPC + 1] = b >> 8;
- pCurrentSection->tData[nPC + 2] = b >> 16;
- pCurrentSection->tData[nPC + 3] = b >> 24;
- }
+ pCurrentSection->tData[nPC] = b & 0xFF;
+ pCurrentSection->tData[nPC + 1] = b >> 8;
+ pCurrentSection->tData[nPC + 2] = b >> 16;
+ pCurrentSection->tData[nPC + 3] = b >> 24;
pCurrentSection->nPC += 4;
nPC += 4;
pPCSymbol->nValue += 4;
@@ -852,19 +827,14 @@
*/
void out_RelLong(struct Expression *expr)
{
- int32_t b;
-
checkcodesection();
checksectionoverflow(4);
- b = expr->nVal;
if (rpn_isReloc(expr)) {
- if (nPass == 2) {
- pCurrentSection->tData[nPC] = b & 0xFF;
- pCurrentSection->tData[nPC + 1] = b >> 8;
- pCurrentSection->tData[nPC + 2] = b >> 16;
- pCurrentSection->tData[nPC + 3] = b >> 24;
- createpatch(PATCH_LONG_L, expr);
- }
+ pCurrentSection->tData[nPC] = 0;
+ pCurrentSection->tData[nPC + 1] = 0;
+ pCurrentSection->tData[nPC + 2] = 0;
+ pCurrentSection->tData[nPC + 3] = 0;
+ createpatch(PATCH_LONG_L, expr);
pCurrentSection->nPC += 4;
nPC += 4;
pPCSymbol->nValue += 4;
@@ -884,10 +854,8 @@
checksectionoverflow(1);
/* Always let the linker calculate the offset. */
- if (nPass == 2) {
- pCurrentSection->tData[nPC] = 0;
- createpatch(PATCH_BYTE_JR, expr);
- }
+ pCurrentSection->tData[nPC] = 0;
+ createpatch(PATCH_BYTE_JR, expr);
pCurrentSection->nPC += 1;
nPC += 1;
pPCSymbol->nValue += 1;
@@ -915,13 +883,12 @@
checkcodesection();
checksectionoverflow(fsize);
- if (nPass == 2) {
- int32_t dest = nPC;
- int32_t todo = fsize;
+ int32_t dest = nPC;
+ int32_t todo = fsize;
- while (todo--)
- pCurrentSection->tData[dest++] = fgetc(f);
- }
+ while (todo--)
+ pCurrentSection->tData[dest++] = fgetc(f);
+
pCurrentSection->nPC += fsize;
nPC += fsize;
pPCSymbol->nValue += fsize;
@@ -958,13 +925,12 @@
checkcodesection();
checksectionoverflow(length);
- if (nPass == 2) {
- int32_t dest = nPC;
- int32_t todo = length;
+ int32_t dest = nPC;
+ int32_t todo = length;
- while (todo--)
- pCurrentSection->tData[dest++] = fgetc(f);
- }
+ while (todo--)
+ pCurrentSection->tData[dest++] = fgetc(f);
+
pCurrentSection->nPC += length;
nPC += length;
pPCSymbol->nValue += length;
--- a/src/asm/rpn.c
+++ b/src/asm/rpn.c
@@ -55,7 +55,6 @@
expr->nRPNLength = len;
expr->isReloc = src1->isReloc || src2->isReloc;
- expr->isPCRel = src1->isPCRel || src2->isPCRel;
}
#define joinexpr() mergetwoexpressions(expr, src1, src2)
@@ -91,7 +90,6 @@
expr->nRPNLength = 0;
expr->nRPNOut = 0;
expr->isReloc = 0;
- expr->isPCRel = 0;
}
/*
@@ -123,14 +121,6 @@
}
/*
- * Determine if the current expression can be pc-relative
- */
-uint32_t rpn_isPCRelative(const struct Expression *expr)
-{
- return expr->isPCRel;
-}
-
-/*
* Add symbols, constants and operators to expression
*/
void rpn_Number(struct Expression *expr, uint32_t i)
@@ -147,15 +137,8 @@
void rpn_Symbol(struct Expression *expr, char *tzSym)
{
if (!sym_isConstant(tzSym)) {
- const struct sSymbol *psym;
-
rpn_Init(expr);
-
- psym = sym_FindSymbol(tzSym);
-
- if (psym == NULL || psym->pSection == pCurrentSection
- || psym->pSection == NULL)
- expr->isPCRel = 1;
+ sym_Ref(tzSym);
expr->isReloc = 1;
pushbyte(expr, RPN_SYM);
while (*tzSym)
@@ -189,13 +172,7 @@
if (!sym_isConstant(tzSym)) {
rpn_Init(expr);
-
- /*
- * Check that the symbol exists by evaluating and discarding the
- * value.
- */
- sym_GetValue(tzSym);
-
+ sym_Ref(tzSym);
expr->isReloc = 1;
pushbyte(expr, RPN_BANK_SYM);
while (*tzSym)
--- a/src/asm/symbol.c
+++ b/src/asm/symbol.c
@@ -154,12 +154,15 @@
* Creates the full name of a local symbol in a given scope, by prepending
* the name with the parent symbol's name.
*/
-static size_t fullSymbolName(char *output, size_t outputSize, char *localName,
- const struct sSymbol *scope)
+static void fullSymbolName(char *output, size_t outputSize, char *localName,
+ const struct sSymbol *scope)
{
const struct sSymbol *parent = scope->pScope ? scope->pScope : scope;
+ int n = snprintf(output, outputSize, "%s%s", parent->tzName, localName);
- return snprintf(output, outputSize, "%s%s", parent->tzName, localName);
+ if (n >= (int)outputSize)
+ fatalerror("Symbol name is too long: '%s%s'",
+ parent->tzName, localName);
}
/*
@@ -207,7 +210,7 @@
}
/*
- * Find a symbol by name and scope
+ * Find a symbol by name, with automatically determined scope
*/
struct sSymbol *sym_FindSymbol(char *tzName)
{
@@ -256,15 +259,8 @@
*/
uint32_t sym_isConstDefined(char *tzName)
{
- struct sSymbol *psym, *pscope;
+ struct sSymbol *psym = sym_FindSymbol(tzName);
- if (*tzName == '.')
- pscope = pScope;
- else
- pscope = NULL;
-
- psym = findsymbol(tzName, pscope);
-
if (psym && (psym->nType & SYMF_DEFINED)) {
uint32_t mask = SYMF_EQU | SYMF_SET | SYMF_MACRO | SYMF_STRING;
@@ -280,19 +276,9 @@
uint32_t sym_isDefined(char *tzName)
{
- struct sSymbol *psym, *pscope;
+ struct sSymbol *psym = sym_FindSymbol(tzName);
- if (*tzName == '.')
- pscope = pScope;
- else
- pscope = NULL;
-
- psym = findsymbol(tzName, pscope);
-
- if (psym && (psym->nType & SYMF_DEFINED))
- return 1;
- else
- return 0;
+ return (psym && (psym->nType & SYMF_DEFINED));
}
/*
@@ -300,21 +286,9 @@
*/
uint32_t sym_isConstant(char *s)
{
- struct sSymbol *psym, *pscope;
+ struct sSymbol *psym = sym_FindSymbol(s);
- if (*s == '.')
- pscope = pScope;
- else
- pscope = NULL;
-
- psym = findsymbol(s, pscope);
-
- if (psym != NULL) {
- if (psym->nType & SYMF_CONST)
- return 1;
- }
-
- return 0;
+ return (psym && (psym->nType & SYMF_CONST));
}
/*
@@ -327,7 +301,7 @@
if (pSym != NULL)
return pSym->pMacro;
- yyerror("Stringsymbol '%s' not defined", tzSym);
+ yyerror("String symbol '%s' not defined", tzSym);
return NULL;
}
@@ -337,15 +311,8 @@
*/
uint32_t sym_GetConstantValue(char *s)
{
- struct sSymbol *psym, *pscope;
+ struct sSymbol *psym = sym_FindSymbol(s);
- if (*s == '.')
- pscope = pScope;
- else
- pscope = NULL;
-
- psym = findsymbol(s, pscope);
-
if (psym != NULL) {
if (psym->nType & SYMF_CONST)
return getvaluefield(psym);
@@ -359,63 +326,12 @@
}
/*
- * Return a symbols value... "estimated" if not defined yet
- */
-uint32_t sym_GetValue(char *s)
-{
- struct sSymbol *psym, *pscope;
-
- if (*s == '.')
- pscope = pScope;
- else
- pscope = NULL;
-
- psym = findsymbol(s, pscope);
-
- if (psym != NULL) {
- if (psym->nType & SYMF_DEFINED) {
- if (psym->nType & (SYMF_MACRO | SYMF_STRING))
- yyerror("'%s' is a macro or string symbol", s);
-
- return getvaluefield(psym);
- }
-
- if (nPass == 2) {
- /*
- * Assume undefined symbols are imported from
- * somwehere else
- */
- psym->nType |= SYMF_IMPORT;
- }
-
- /* 0x80 seems like a good default value... */
- return 0x80;
- }
-
- if (nPass == 1) {
- createsymbol(s);
- return 0x80;
- }
-
- yyerror("'%s' not defined", s);
-
- return 0;
-}
-
-/*
* Return a defined symbols value... aborts if not defined yet
*/
uint32_t sym_GetDefinedValue(char *s)
{
- struct sSymbol *psym, *pscope;
+ struct sSymbol *psym = sym_FindSymbol(s);
- if (*s == '.')
- pscope = pScope;
- else
- pscope = NULL;
-
- psym = findsymbol(s, pscope);
-
if (psym != NULL) {
if ((psym->nType & SYMF_DEFINED)) {
if (psym->nType & (SYMF_MACRO | SYMF_STRING))
@@ -545,30 +461,43 @@
}
/*
- * Add an equated symbol
+ * Create a symbol that will be non-relocatable and ensure that it
+ * hasn't already been defined or referenced in a context that would
+ * require that it be relocatable
*/
-void sym_AddEqu(char *tzSym, int32_t value)
+static struct sSymbol *createNonrelocSymbol(char *tzSym)
{
- if ((nPass == 1) || ((nPass == 2) && (sym_isDefined(tzSym) == 0))) {
- /* only add equated symbols in pass 1 */
- struct sSymbol *nsym = findsymbol(tzSym, NULL);
+ struct sSymbol *nsym = findsymbol(tzSym, NULL);
- if (nsym != NULL) {
- if (nsym->nType & SYMF_DEFINED) {
- yyerror("'%s' already defined in %s(%d)", tzSym,
- nsym->tzFileName, nsym->nFileLine);
- }
- } else {
- nsym = createsymbol(tzSym);
+ if (nsym != NULL) {
+ if (nsym->nType & SYMF_DEFINED) {
+ yyerror("'%s' already defined at %s(%u)",
+ tzSym, nsym->tzFileName, nsym->nFileLine);
+ } else if (nsym->nType & SYMF_REF) {
+ yyerror("'%s' already referenced at %s(%u)",
+ tzSym, nsym->tzFileName, nsym->nFileLine);
}
+ } else {
+ nsym = createsymbol(tzSym);
+ }
- if (nsym) {
- nsym->nValue = value;
- nsym->nType |= SYMF_EQU | SYMF_DEFINED | SYMF_CONST;
- nsym->pScope = NULL;
- updateSymbolFilename(nsym);
- }
+ return nsym;
+}
+
+/*
+ * Add an equated symbol
+ */
+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);
}
+
}
/*
@@ -585,17 +514,8 @@
*/
void sym_AddString(char *tzSym, char *tzValue)
{
- struct sSymbol *nsym = findsymbol(tzSym, NULL);
+ struct sSymbol *nsym = createNonrelocSymbol(tzSym);
- if (nsym != NULL) {
- if (nsym->nType & SYMF_DEFINED) {
- yyerror("'%s' already defined in %s(%d)",
- tzSym, nsym->tzFileName, nsym->nFileLine);
- }
- } else {
- nsym = createsymbol(tzSym);
- }
-
if (nsym) {
nsym->pMacro = malloc(strlen(tzValue) + 1);
@@ -602,7 +522,7 @@
if (nsym->pMacro != NULL)
strcpy(nsym->pMacro, tzValue);
else
- fatalerror("No memory for stringequate");
+ fatalerror("No memory for string equate");
nsym->nType |= SYMF_STRING | SYMF_DEFINED;
nsym->ulMacroSize = strlen(tzValue);
@@ -617,11 +537,7 @@
{
const struct sSymbol *pSym = findsymbol(tzSym, NULL);
- if (pSym != NULL) {
- if (pSym->nType & SYMF_STRING)
- return 1;
- }
- return 0;
+ return (pSym && (pSym->nType & SYMF_STRING));
}
/*
@@ -631,8 +547,20 @@
{
struct sSymbol *nsym = findsymbol(tzSym, NULL);
- if (nsym == NULL) {
- /* Symbol hasn been found, create */
+ if (nsym != NULL) {
+ if (nsym->nType & SYMF_DEFINED) {
+ if (!(nsym->nType & SYMF_CONST))
+ yyerror("'%s' already defined as non-constant at %s(%u)",
+ tzSym,
+ nsym->tzFileName,
+ nsym->nFileLine);
+ } else if (nsym->nType & SYMF_REF) {
+ yyerror("'%s' already referenced at %s(%u)",
+ tzSym,
+ nsym->tzFileName,
+ nsym->nFileLine);
+ }
+ } else {
nsym = createsymbol(tzSym);
}
@@ -650,9 +578,6 @@
void sym_AddLocalReloc(char *tzSym)
{
if (pScope) {
- if (strlen(tzSym) + strlen(pScope->tzName) > MAXSYMLEN)
- fatalerror("Symbol too long");
-
char fullname[MAXSYMLEN + 1];
fullSymbolName(fullname, sizeof(fullname), tzSym, pScope);
@@ -669,59 +594,55 @@
void sym_AddReloc(char *tzSym)
{
struct sSymbol *scope = NULL;
+ struct sSymbol *nsym;
+ char *localPtr = strchr(tzSym, '.');
- if ((nPass == 1)
- || ((nPass == 2) && (sym_isDefined(tzSym) == 0))) {
- /* only add reloc symbols in pass 1 */
- struct sSymbol *nsym;
- char *localPtr = strchr(tzSym, '.');
+ if (localPtr != NULL) {
+ if (!pScope)
+ fatalerror("Local label in main scope");
- if (localPtr != NULL) {
- if (!pScope)
- fatalerror("Local label in main scope");
+ struct sSymbol *parent = pScope->pScope ?
+ pScope->pScope : pScope;
+ uint32_t parentLen = localPtr - tzSym;
- struct sSymbol *parent = pScope->pScope ?
- pScope->pScope : pScope;
- uint32_t parentLen = localPtr - tzSym;
-
- 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) {
- yyerror("Not currently in the scope of '%.*s'",
- parentLen, tzSym);
- }
-
- scope = parent;
+ 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) {
+ yyerror("Not currently in the scope of '%.*s'",
+ parentLen, tzSym);
}
- nsym = findsymbol(tzSym, scope);
+ scope = parent;
+ }
- if (nsym != NULL) {
- if (nsym->nType & SYMF_DEFINED) {
- yyerror("'%s' already defined in %s(%d)", tzSym,
- nsym->tzFileName, nsym->nFileLine);
- }
- } else {
- nsym = createsymbol(tzSym);
+ nsym = findsymbol(tzSym, scope);
+
+ if (nsym != NULL) {
+ if (nsym->nType & SYMF_DEFINED) {
+ yyerror("'%s' already defined in %s(%d)", tzSym,
+ nsym->tzFileName, nsym->nFileLine);
}
+ } else {
+ nsym = createsymbol(tzSym);
+ }
- if (nsym) {
- nsym->nValue = nPC;
- nsym->nType |= SYMF_RELOC | SYMF_DEFINED;
- if (localPtr)
- nsym->nType |= SYMF_LOCAL;
+ if (nsym) {
+ nsym->nValue = nPC;
+ nsym->nType |= SYMF_RELOC | SYMF_DEFINED;
+ if (localPtr)
+ nsym->nType |= SYMF_LOCAL;
- if (exportall)
- nsym->nType |= SYMF_EXPORT;
+ if (exportall)
+ nsym->nType |= SYMF_EXPORT;
- nsym->pScope = scope;
- nsym->pSection = pCurrentSection;
+ nsym->pScope = scope;
+ nsym->pSection = pCurrentSection;
- updateSymbolFilename(nsym);
- }
+ updateSymbolFilename(nsym);
}
+
pScope = findsymbol(tzSym, scope);
}
@@ -734,10 +655,6 @@
*/
int32_t sym_IsRelocDiffDefined(char *tzSym1, char *tzSym2)
{
- /* Do nothing the first pass. */
- if (nPass != 2)
- return 1;
-
const struct sSymbol *nsym1 = sym_FindSymbol(tzSym1);
const struct sSymbol *nsym2 = sym_FindSymbol(tzSym2);
@@ -781,146 +698,66 @@
*/
void sym_Export(char *tzSym)
{
- if (nPass == 1) {
- /* only export symbols in pass 1 */
- struct sSymbol *nsym = sym_FindSymbol(tzSym);
+ struct sSymbol *nsym = sym_FindSymbol(tzSym);
- if (nsym == NULL)
- nsym = createsymbol(tzSym);
+ if (nsym == NULL)
+ nsym = createsymbol(tzSym);
- if (nsym)
- nsym->nType |= SYMF_EXPORT;
- } else {
- const struct sSymbol *nsym = sym_FindSymbol(tzSym);
-
- if (nsym != NULL) {
- if (nsym->nType & SYMF_DEFINED)
- return;
- }
- yyerror("'%s' not defined", tzSym);
- }
+ if (nsym)
+ nsym->nType |= SYMF_EXPORT;
}
/*
- * Globalize a symbol (export if defined, import if not)
+ * Add a macro definition
*/
-void sym_Global(char *tzSym)
+void sym_AddMacro(char *tzSym)
{
- if (nPass == 2) {
- /* only globalize symbols in pass 2 */
- struct sSymbol *nsym = sym_FindSymbol(tzSym);
+ struct sSymbol *nsym = createNonrelocSymbol(tzSym);
- if ((nsym == NULL) || ((nsym->nType & SYMF_DEFINED) == 0)) {
- if (nsym == NULL)
- nsym = createsymbol(tzSym);
-
- if (nsym)
- nsym->nType |= SYMF_IMPORT;
- } else {
- if (nsym)
- nsym->nType |= SYMF_EXPORT;
- }
+ if (nsym) {
+ nsym->nType |= SYMF_MACRO | SYMF_DEFINED;
+ nsym->pScope = NULL;
+ nsym->ulMacroSize = ulNewMacroSize;
+ nsym->pMacro = tzNewMacro;
+ updateSymbolFilename(nsym);
}
}
/*
- * Add a macro definition
+ * Flag that a symbol is referenced in an RPN expression
+ * and create it if it doesn't exist yet
*/
-void sym_AddMacro(char *tzSym)
+void sym_Ref(char *tzSym)
{
- if ((nPass == 1) || ((nPass == 2) && (sym_isDefined(tzSym) == 0))) {
- /* only add macros in pass 1 */
- struct sSymbol *nsym;
+ struct sSymbol *nsym = sym_FindSymbol(tzSym);
- nsym = findsymbol(tzSym, NULL);
+ if (nsym == NULL) {
+ char fullname[MAXSYMLEN + 1];
+ int isLocal = 0;
- if (nsym != NULL) {
- if (nsym->nType & SYMF_DEFINED) {
- yyerror("'%s' already defined in %s(%d)",
- tzSym, nsym->tzFileName,
- nsym->nFileLine);
- }
- } else {
- nsym = createsymbol(tzSym);
+ if (*tzSym == '.') {
+ fullSymbolName(fullname, sizeof(fullname), tzSym,
+ pScope);
+ tzSym = fullname;
+ isLocal = 1;
}
- if (nsym) {
- nsym->nValue = nPC;
- nsym->nType |= SYMF_MACRO | SYMF_DEFINED;
- nsym->pScope = NULL;
- nsym->ulMacroSize = ulNewMacroSize;
- nsym->pMacro = tzNewMacro;
- updateSymbolFilename(nsym);
- }
+ nsym = createsymbol(tzSym);
+
+ if (nsym && isLocal)
+ nsym->nType |= SYMF_LOCAL;
}
+
+ if (nsym)
+ nsym->nType |= SYMF_REF;
}
/*
- * Set whether to export all relocable symbols by default
+ * Set whether to export all relocatable symbols by default
*/
void sym_SetExportAll(uint8_t set)
{
exportall = set;
-}
-
-/*
- * Prepare for pass #1
- */
-void sym_PrepPass1(void)
-{
- sym_Init();
-}
-
-/*
- * Prepare for pass #2
- */
-void sym_PrepPass2(void)
-{
- int32_t i;
-
- for (i = 0; i < HASHSIZE; i += 1) {
- struct sSymbol **ppSym = &(tHashedSymbols[i]);
-
- while (*ppSym) {
- uint32_t mask = SYMF_SET | SYMF_STRING | SYMF_EQU;
-
- if ((*ppSym)->nType & mask) {
- struct sSymbol *pTemp;
-
- pTemp = (*ppSym)->pNext;
- free(*ppSym);
- *ppSym = pTemp;
- } else {
- ppSym = &((*ppSym)->pNext);
- }
- }
- }
- pScope = NULL;
- pPCSymbol->nValue = 0;
-
- sym_AddString("__TIME__", SavedTIME);
- sym_AddString("__DATE__", SavedDATE);
- sym_AddString("__ISO_8601_LOCAL__", SavedTIMESTAMP_ISO8601_LOCAL);
- sym_AddString("__ISO_8601_UTC__", SavedTIMESTAMP_ISO8601_UTC);
- sym_AddString("__UTC_DAY__", SavedDAY);
- sym_AddString("__UTC_MONTH__", SavedMONTH);
- sym_AddString("__UTC_YEAR__", SavedYEAR);
- sym_AddString("__UTC_HOUR__", SavedHOUR);
- sym_AddString("__UTC_MINUTE__", SavedMINUTE);
- sym_AddString("__UTC_SECOND__", SavedSECOND);
- sym_AddEqu("__RGBDS_MAJOR__", PACKAGE_VERSION_MAJOR);
- sym_AddEqu("__RGBDS_MINOR__", PACKAGE_VERSION_MINOR);
- sym_AddEqu("__RGBDS_PATCH__", PACKAGE_VERSION_PATCH);
- sym_AddSet("_RS", 0);
-
- sym_AddEqu("_NARG", 0);
- p_NARGSymbol = findsymbol("_NARG", NULL);
- p_NARGSymbol->Callback = Callback_NARG;
- sym_AddEqu("__LINE__", 0);
- p__LINE__Symbol = findsymbol("__LINE__", NULL);
- p__LINE__Symbol->Callback = Callback__LINE__;
-
- math_DefinePI();
}
/*
--- a/test/asm/label-redefinition.out
+++ b/test/asm/label-redefinition.out
@@ -1,3 +1,3 @@
ERROR: label-redefinition.asm(7):
'Sym' already defined in m(6)
-error: Assembly aborted in pass 1 (1 errors)!
+error: Assembly aborted (1 errors)!
--- a/test/asm/local-wrong-parent.out
+++ b/test/asm/local-wrong-parent.out
@@ -1,3 +1,3 @@
ERROR: local-wrong-parent.asm(5):
Not currently in the scope of 'WrongParent'
-error: Assembly aborted in pass 1 (1 errors)!
+error: Assembly aborted (1 errors)!
--- /dev/null
+++ b/test/asm/reference-undefined-sym.asm
@@ -1,0 +1,4 @@
+SECTION "sec", ROM0
+ db X
+
+X = 2
--- /dev/null
+++ b/test/asm/reference-undefined-sym.out
@@ -1,0 +1,3 @@
+ERROR: reference-undefined-sym.asm(4):
+ 'X' already referenced at reference-undefined-sym.asm(2)
+error: Assembly aborted (1 errors)!
--- a/test/asm/undefined-dot.out
+++ b/test/asm/undefined-dot.out
@@ -1,3 +1,1 @@
-ERROR: undefined-dot.asm(3):
- '.' not defined
-error: Assembly aborted in pass 2 (1 errors)!
+error: undefined-dot.asm(3) : '.' not defined