mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-22 11:12:07 +00:00
Use only one pass
This commit is contained in:
333
src/asm/symbol.c
333
src/asm/symbol.c
@@ -358,50 +358,6 @@ uint32_t sym_GetConstantValue(char *s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
@@ -549,26 +505,24 @@ struct sSymbol *sym_FindMacro(char *s)
|
||||
*/
|
||||
void sym_AddEqu(char *tzSym, int32_t value)
|
||||
{
|
||||
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) {
|
||||
nsym->nValue = value;
|
||||
nsym->nType |= SYMF_EQU | SYMF_DEFINED | SYMF_CONST;
|
||||
nsym->pScope = NULL;
|
||||
updateSymbolFilename(nsym);
|
||||
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 = value;
|
||||
nsym->nType |= SYMF_EQU | SYMF_DEFINED | SYMF_CONST;
|
||||
nsym->pScope = NULL;
|
||||
updateSymbolFilename(nsym);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -669,59 +623,55 @@ void sym_AddLocalReloc(char *tzSym)
|
||||
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);
|
||||
|
||||
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 (exportall)
|
||||
nsym->nType |= SYMF_EXPORT;
|
||||
|
||||
nsym->pScope = scope;
|
||||
nsym->pSection = pCurrentSection;
|
||||
|
||||
updateSymbolFilename(nsym);
|
||||
}
|
||||
scope = parent;
|
||||
}
|
||||
|
||||
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 (exportall)
|
||||
nsym->nType |= SYMF_EXPORT;
|
||||
|
||||
nsym->pScope = scope;
|
||||
nsym->pSection = pCurrentSection;
|
||||
|
||||
updateSymbolFilename(nsym);
|
||||
}
|
||||
|
||||
pScope = findsymbol(tzSym, scope);
|
||||
}
|
||||
|
||||
@@ -734,10 +684,6 @@ void sym_AddReloc(char *tzSym)
|
||||
*/
|
||||
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,46 +727,13 @@ int32_t sym_IsRelocDiffDefined(char *tzSym1, char *tzSym2)
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Globalize a symbol (export if defined, import if not)
|
||||
*/
|
||||
void sym_Global(char *tzSym)
|
||||
{
|
||||
if (nPass == 2) {
|
||||
/* only globalize symbols in pass 2 */
|
||||
struct sSymbol *nsym = sym_FindSymbol(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_EXPORT;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -828,30 +741,50 @@ void sym_Global(char *tzSym)
|
||||
*/
|
||||
void sym_AddMacro(char *tzSym)
|
||||
{
|
||||
if ((nPass == 1) || ((nPass == 2) && (sym_isDefined(tzSym) == 0))) {
|
||||
/* only add macros in pass 1 */
|
||||
struct sSymbol *nsym;
|
||||
struct sSymbol *nsym;
|
||||
|
||||
nsym = findsymbol(tzSym, NULL);
|
||||
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 in %s(%d)",
|
||||
tzSym, nsym->tzFileName,
|
||||
nsym->nFileLine);
|
||||
}
|
||||
} else {
|
||||
nsym = createsymbol(tzSym);
|
||||
}
|
||||
|
||||
if (nsym) {
|
||||
nsym->nValue = nPC;
|
||||
nsym->nType |= SYMF_MACRO | SYMF_DEFINED;
|
||||
nsym->pScope = NULL;
|
||||
nsym->ulMacroSize = ulNewMacroSize;
|
||||
nsym->pMacro = tzNewMacro;
|
||||
updateSymbolFilename(nsym);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a symbol that is being referenced ahead of its definition
|
||||
*/
|
||||
void sym_AddForwardRef(char *tzSym)
|
||||
{
|
||||
if (sym_FindSymbol(tzSym) == NULL) {
|
||||
char fullname[MAXSYMLEN + 1];
|
||||
int isLocal = 0;
|
||||
|
||||
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);
|
||||
}
|
||||
struct sSymbol *nsym = createsymbol(tzSym);
|
||||
|
||||
if (nsym && isLocal)
|
||||
nsym->nType |= SYMF_LOCAL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -863,66 +796,6 @@ 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();
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the symboltable
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user