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
--
⑨