ref: e895832b2b89cf341ef84ee43e70aaa41f002fed
dir: /src/ASM/SYMBOL.C/
/*
* RGBAsm - SYMBOL.C - Symboltable and macroargs stuff
*
* INCLUDES
*
*/
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "asm.h"
#include "symbol.h"
#include "main.h"
#include "mymath.h"
#include "output.h"
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* VARIABLES
*
*/
struct sSymbol *tHashedSymbols[HASHSIZE];
struct sSymbol *pScope = NULL;
struct sSymbol *pPCSymbol = NULL;
struct sSymbol *p_NARGSymbol = NULL;
struct sSymbol *p__LINE__Symbol = NULL;
char *currentmacroargs[MAXMACROARGS + 1];
char *newmacroargs[MAXMACROARGS + 1];
char SavedTIME[256];
char SavedDATE[256];
SLONG Callback_NARG (struct sSymbol *sym)
{
ULONG i = 0;
sym = sym;
while (currentmacroargs[i] && i < MAXMACROARGS)
i += 1;
return (i);
}
SLONG Callback__LINE__ (struct sSymbol *sym)
{
sym=sym;
return (nLineNo);
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Get the nValue field of a symbol
*
*/
SLONG getvaluefield (struct sSymbol *sym)
{
if (sym->Callback)
{
return (sym->Callback (sym));
}
else
return (sym->nValue);
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Calculate the hash value for a string
*
*/
ULONG calchash (char *s)
{
ULONG hash = 0;
while (*s != 0)
hash += (*s++);
return (hash % HASHSIZE);
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Create a new symbol by name
*
*/
struct sSymbol *createsymbol (char *s)
{
struct sSymbol **ppsym;
ULONG hash;
hash = calchash (s);
ppsym = &(tHashedSymbols[hash]);
while ((*ppsym) != NULL)
ppsym = &((*ppsym)->pNext);
if( ((*ppsym)=(struct sSymbol *)malloc(sizeof (struct sSymbol)))!=NULL )
{
strcpy ((*ppsym)->tzName, s);
(*ppsym)->nValue = 0;
(*ppsym)->nType = 0;
(*ppsym)->pScope = NULL;
(*ppsym)->pNext = NULL;
(*ppsym)->pMacro = NULL;
(*ppsym)->pSection = NULL;
(*ppsym)->Callback = NULL;
return (*ppsym);
}
else
{
fatalerror ("No memory for symbol");
return (NULL);
}
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Find a symbol by name and scope
*
*/
struct sSymbol *findsymbol (char *s, struct sSymbol *scope)
{
struct sSymbol **ppsym;
SLONG hash;
hash = calchash (s);
ppsym = &(tHashedSymbols[hash]);
while ((*ppsym) != NULL)
{
if( (strcmp (s, (*ppsym)->tzName) == 0)
&& ((*ppsym)->pScope == scope) )
{
return (*ppsym);
}
else
ppsym = &((*ppsym)->pNext);
}
return (NULL);
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Find the pointer to a symbol by name and scope
*
*/
struct sSymbol **findpsymbol (char *s, struct sSymbol *scope)
{
struct sSymbol **ppsym;
SLONG hash;
hash = calchash (s);
ppsym = &(tHashedSymbols[hash]);
while ((*ppsym) != NULL)
{
if( (strcmp (s, (*ppsym)->tzName) == 0)
&& ((*ppsym)->pScope == scope) )
{
return (ppsym);
}
else
ppsym = &((*ppsym)->pNext);
}
return (NULL);
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Find a symbol by name and scope
*
*/
struct sSymbol *sym_FindSymbol (char *tzName)
{
struct sSymbol *pscope;
if (*tzName == '.')
pscope = pScope;
else
pscope = NULL;
return (findsymbol (tzName, pscope));
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Purge a symbol
*
*/
void sym_Purge( char *tzName )
{
struct sSymbol **ppSym;
struct sSymbol *pscope;
if (*tzName == '.')
pscope = pScope;
else
pscope = NULL;
ppSym=findpsymbol( tzName, pscope );
if( ppSym )
{
struct sSymbol *pSym;
pSym=*ppSym;
*ppSym=pSym->pNext;
if( pSym->pMacro )
free( pSym->pMacro );
free( pSym );
}
else
{
sprintf( temptext, "'%s' not defined", tzName );
yyerror( temptext );
}
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Determine if a symbol has been defined
*
*/
ULONG sym_isConstDefined (char *tzName)
{
struct sSymbol *psym,
*pscope;
if (*tzName == '.')
pscope = pScope;
else
pscope = NULL;
psym = findsymbol (tzName, pscope);
if( psym
&& (psym->nType & SYMF_DEFINED) )
{
if( psym->nType & (SYMF_EQU|SYMF_SET|SYMF_MACRO|SYMF_STRING) )
{
return (1);
}
else
{
sprintf( temptext, "'%s' is not allowed as argument to the DEF function", tzName );
fatalerror( temptext );
}
}
return (0);
}
ULONG sym_isDefined (char *tzName)
{
struct sSymbol *psym,
*pscope;
if (*tzName == '.')
pscope = pScope;
else
pscope = NULL;
psym = findsymbol (tzName, pscope);
if (psym && (psym->nType & SYMF_DEFINED))
return (1);
else
return (0);
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Determine if the symbol is a constant
*
*/
ULONG sym_isConstant (char *s)
{
struct sSymbol *psym,
*pscope;
if (*s == '.')
pscope = pScope;
else
pscope = NULL;
if( (psym=findsymbol(s,pscope))!=NULL )
{
if (psym->nType & SYMF_CONST)
return (1);
}
return (0);
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Get a string equate's value
*
*/
char *sym_GetStringValue (char *tzSym)
{
struct sSymbol *pSym;
if( (pSym=sym_FindSymbol(tzSym))!=NULL )
return (pSym->pMacro);
else
{
sprintf (temptext, "Stringsymbol '%s' not defined", tzSym);
yyerror (temptext);
}
return (NULL);
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Return a constant symbols value
*
*/
ULONG sym_GetConstantValue (char *s)
{
struct sSymbol *psym,
*pscope;
if (*s == '.')
pscope = pScope;
else
pscope = NULL;
if( (psym=findsymbol(s,pscope))!=NULL )
{
if (psym->nType & SYMF_CONST)
return (getvaluefield (psym));
else
{
fatalerror ("Expression must have a constant value");
}
}
else
{
sprintf (temptext, "'%s' not defined", s);
yyerror (temptext);
}
return (0);
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Return a symbols value... "estimated" if not defined yet
*
*/
ULONG sym_GetValue (char *s)
{
struct sSymbol *psym,
*pscope;
if (*s == '.')
pscope = pScope;
else
pscope = NULL;
if( (psym=findsymbol(s,pscope))!=NULL )
{
if( psym->nType & SYMF_DEFINED )
{
if( psym->nType & (SYMF_MACRO|SYMF_STRING) )
{
sprintf (temptext, "'%s' is a macro or string symbol", s);
yyerror (temptext);
}
return (getvaluefield (psym));
}
else
{
if ((nPass == 1) || (psym->nType & SYMF_IMPORT))
{
/* 0x80 seems like a good default value... */
return (0x80);
}
else
{
sprintf (temptext, "'%s' not defined", s);
yyerror (temptext);
}
}
}
else
{
if (nPass == 1)
{
createsymbol (s);
return (0x80);
}
else
{
sprintf (temptext, "'%s' not defined", s);
yyerror (temptext);
}
}
return (0);
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Return a defined symbols value... aborts if not defined yet
*
*/
ULONG sym_GetDefinedValue (char *s)
{
struct sSymbol *psym,
*pscope;
if (*s == '.')
pscope = pScope;
else
pscope = NULL;
if( (psym=findsymbol(s,pscope))!=NULL )
{
if( (psym->nType & SYMF_DEFINED) )
{
if( psym->nType & (SYMF_MACRO|SYMF_STRING) )
{
sprintf (temptext, "'%s' is a macro or string symbol", s);
yyerror (temptext);
}
return (getvaluefield (psym));
}
else
{
sprintf (temptext, "'%s' not defined", s);
yyerror (temptext);
}
}
else
{
sprintf (temptext, "'%s' not defined", s);
yyerror (temptext);
}
return (0);
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Macro argument stuff
*
*/
void sym_ShiftCurrentMacroArgs (void)
{
SLONG i;
free (currentmacroargs[0]);
for (i = 0; i < MAXMACROARGS - 1; i += 1)
{
currentmacroargs[i] = currentmacroargs[i + 1];
}
currentmacroargs[MAXMACROARGS - 1] = NULL;
}
char *sym_FindMacroArg (SLONG i)
{
if (i == -1)
i = MAXMACROARGS + 1;
return (currentmacroargs[i - 1]);
}
void sym_UseNewMacroArgs (void)
{
SLONG i;
for (i = 0; i <= MAXMACROARGS; i += 1)
{
currentmacroargs[i] = newmacroargs[i];
newmacroargs[i] = NULL;
}
}
void sym_SaveCurrentMacroArgs (char *save[])
{
SLONG i;
for (i = 0; i <= MAXMACROARGS; i += 1)
save[i] = currentmacroargs[i];
}
void sym_RestoreCurrentMacroArgs (char *save[])
{
SLONG i;
for (i = 0; i <= MAXMACROARGS; i += 1)
currentmacroargs[i] = save[i];
}
void sym_FreeCurrentMacroArgs (void)
{
SLONG i;
for (i = 0; i <= MAXMACROARGS; i += 1)
{
free (currentmacroargs[i]);
currentmacroargs[i] = NULL;
}
}
void sym_AddNewMacroArg (char *s)
{
SLONG i = 0;
while (i < MAXMACROARGS && newmacroargs[i] != NULL)
i += 1;
if (i < MAXMACROARGS)
{
if (s)
newmacroargs[i] = strdup (s);
else
newmacroargs[i] = NULL;
}
else
yyerror ("A maximum of 9 arguments allowed");
}
void sym_SetMacroArgID (ULONG nMacroCount)
{
char s[256];
sprintf(s, "_%ld", nMacroCount);
newmacroargs[MAXMACROARGS] = strdup (s);
}
void sym_UseCurrentMacroArgs (void)
{
SLONG i;
for (i = 1; i <= MAXMACROARGS; i += 1)
sym_AddNewMacroArg (sym_FindMacroArg (i));
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Find a macro by name
*
*/
struct sSymbol *sym_FindMacro (char *s)
{
return (findsymbol (s, NULL));
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Add an equated symbol
*
*/
void sym_AddEqu (char *tzSym, SLONG value)
{
if( (nPass==1)
|| ((nPass==2)&&(sym_isDefined(tzSym)==0)) )
{
/* only add equated symbols in pass 1 */
struct sSymbol *nsym;
if( (nsym=findsymbol(tzSym,NULL))!=NULL )
{
if (nsym->nType & SYMF_DEFINED)
{
sprintf (temptext, "'%s' already defined", tzSym);
yyerror (temptext);
}
}
else
nsym = createsymbol (tzSym);
if (nsym)
{
nsym->nValue = value;
nsym->nType |= SYMF_EQU | SYMF_DEFINED | SYMF_CONST;
nsym->pScope = NULL;
}
}
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Add a string equated symbol
*
*/
void sym_AddString (char *tzSym, char *tzValue)
{
struct sSymbol *nsym;
if( (nsym=findsymbol(tzSym,NULL))!=NULL )
{
if (nsym->nType & SYMF_DEFINED)
{
sprintf (temptext, "'%s' already defined", tzSym);
yyerror (temptext);
}
}
else
nsym = createsymbol (tzSym);
if (nsym)
{
if( (nsym->pMacro=(char *)malloc(strlen(tzValue)+1))!=NULL )
strcpy (nsym->pMacro, tzValue);
else
fatalerror ("No memory for stringequate");
nsym->nType |= SYMF_STRING | SYMF_DEFINED;
nsym->ulMacroSize = strlen( tzValue );
nsym->pScope = NULL;
}
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* check if symbol is a string equated symbol
*
*/
ULONG sym_isString (char *tzSym)
{
struct sSymbol *pSym;
if( (pSym=findsymbol(tzSym,NULL))!=NULL )
{
if (pSym->nType & SYMF_STRING)
return (1);
}
return (0);
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Alter a SET symbols value
*
*/
void sym_AddSet (char *tzSym, SLONG value)
{
struct sSymbol *nsym;
if( (nsym=findsymbol(tzSym,NULL))!=NULL )
{
}
else
nsym = createsymbol (tzSym);
if (nsym)
{
nsym->nValue = value;
nsym->nType |= SYMF_SET | SYMF_DEFINED | SYMF_CONST;
nsym->pScope = NULL;
}
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Add a local (.name) relocatable symbol
*
*/
void sym_AddLocalReloc (char *tzSym)
{
if( (nPass==1)
|| ((nPass==2)&&(sym_isDefined(tzSym)==0)) )
{
/* only add local reloc symbols in pass 1 */
struct sSymbol *nsym;
if (pScope)
{
if( (nsym=findsymbol(tzSym,pScope))!=NULL )
{
if (nsym->nType & SYMF_DEFINED)
{
sprintf (temptext, "'%s' already defined", tzSym);
yyerror (temptext);
}
}
else
nsym = createsymbol (tzSym);
if (nsym)
{
nsym->nValue = nPC;
nsym->nType |= SYMF_RELOC | SYMF_LOCAL | SYMF_DEFINED;
nsym->pScope = pScope;
nsym->pSection = pCurrentSection;
}
}
else
fatalerror ("Local label in main scope");
}
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Add a relocatable symbol
*
*/
void sym_AddReloc (char *tzSym)
{
if( (nPass==1)
|| ((nPass==2)&&(sym_isDefined(tzSym)==0)) )
{
/* only add reloc symbols in pass 1 */
struct sSymbol *nsym;
if( (nsym=findsymbol(tzSym,NULL))!=NULL )
{
if (nsym->nType & SYMF_DEFINED)
{
sprintf (temptext, "'%s' already defined", tzSym);
yyerror (temptext);
}
}
else
nsym = createsymbol (tzSym);
if (nsym)
{
nsym->nValue = nPC;
nsym->nType |= SYMF_RELOC | SYMF_DEFINED;
nsym->pScope = NULL;
nsym->pSection = pCurrentSection;
}
}
pScope = findsymbol (tzSym, NULL);
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Export a symbol
*
*/
void sym_Export (char *tzSym)
{
if (nPass == 1)
{
/* only export symbols in pass 1 */
struct sSymbol *nsym;
if ((nsym = findsymbol (tzSym, 0)) == NULL)
nsym = createsymbol (tzSym);
if (nsym)
nsym->nType |= SYMF_EXPORT;
}
else
{
struct sSymbol *nsym;
if( (nsym=findsymbol(tzSym,0))!=NULL )
{
if (nsym->nType & SYMF_DEFINED)
return;
}
sprintf (temptext, "'%s' not defined", tzSym);
yyerror (temptext);
}
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Import a symbol
*
*/
void sym_Import (char *tzSym)
{
if (nPass == 1)
{
/* only import symbols in pass 1 */
struct sSymbol *nsym;
if (findsymbol (tzSym, NULL))
{
sprintf (temptext, "'%s' already defined", tzSym);
yyerror (temptext);
}
if( (nsym=createsymbol(tzSym))!=NULL )
nsym->nType |= SYMF_IMPORT;
}
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* 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;
nsym = findsymbol (tzSym, 0);
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;
}
}
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Add a macro definition
*
*/
void sym_AddMacro (char *tzSym)
{
if( (nPass==1)
|| ((nPass==2)&&(sym_isDefined(tzSym)==0)) )
{
/* only add macros in pass 1 */
struct sSymbol *nsym;
if( (nsym=findsymbol(tzSym,NULL))!=NULL )
{
if (nsym->nType & SYMF_DEFINED)
{
sprintf (temptext, "'%s' already defined", tzSym);
yyerror (temptext);
}
}
else
nsym = createsymbol (tzSym);
if (nsym)
{
nsym->nValue = nPC;
nsym->nType |= SYMF_MACRO | SYMF_DEFINED;
nsym->pScope = NULL;
nsym->ulMacroSize = ulNewMacroSize;
nsym->pMacro = tzNewMacro;
}
}
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Prepare for pass #1
*
*/
void sym_PrepPass1 (void)
{
sym_Init ();
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Prepare for pass #2
*
*/
void sym_PrepPass2 (void)
{
SLONG i;
for (i = 0; i < HASHSIZE; i += 1)
{
struct sSymbol **ppSym = &(tHashedSymbols[i]);
while (*ppSym)
{
if ((*ppSym)->nType & (SYMF_SET | SYMF_STRING | SYMF_EQU))
{
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_AddSet( "_RS", 0 );
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* Initialise the symboltable
*
*/
void sym_Init (void)
{
SLONG i;
time_t tod;
for (i = 0; i < MAXMACROARGS; i += 1)
{
currentmacroargs[i] = NULL;
newmacroargs[i] = NULL;
}
for (i = 0; i < HASHSIZE; i += 1)
tHashedSymbols[i] = NULL;
sym_AddReloc ("@");
pPCSymbol = findsymbol ("@", NULL);
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__;
sym_AddEqu( "__ASM__", (SLONG) (atof (ASM_VERSION) * 65536));
sym_AddSet( "_RS", 0 );
if( time(&tod)!=-1 )
{
struct tm *tptr;
tptr=localtime( &tod );
strftime( SavedTIME, sizeof(SavedTIME), "%H:%M:%S", tptr );
strftime( SavedDATE, sizeof(SavedDATE), "%d %B %Y", tptr );
sym_AddString ("__TIME__", SavedTIME);
sym_AddString ("__DATE__", SavedDATE);
}
pScope = NULL;
math_DefinePI ();
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* DEBUG: Print the symbol table
*
*/
void sym_PrintSymbolTable (void)
{
ULONG i;
for (i = 0; i < HASHSIZE; i += 1)
{
struct sSymbol *sym = tHashedSymbols[i];
if (sym != NULL)
printf ("\nHashTable #%ld:\n", i);
while (sym != NULL)
{
if (sym->nType & SYMF_LOCAL)
printf ("LOCAL : '%s%s' - %08lX\n", sym->pScope->tzName, sym->tzName, getvaluefield (sym));
else if (sym->nType & (SYMF_MACRO | SYMF_STRING))
{
ULONG i = 0;
printf ("MACRO : '%s'\n\"", sym->tzName);
while (i < sym->ulMacroSize)
{
if (sym->pMacro[i] == '\n')
{
printf ("\n");
i += 1;
}
else
printf ("%c", sym->pMacro[i++]);
}
printf ("\"\n");
}
else if (sym->nType & SYMF_EXPORT)
printf ("EXPORT: '%s' - %08lX\n", sym->tzName, getvaluefield (sym));
else if (sym->nType & SYMF_IMPORT)
printf ("IMPORT: '%s'\n", sym->tzName);
else if (sym->nType & SYMF_EQU)
printf ("EQU : '%s' - %08lX\n", sym->tzName, getvaluefield (sym));
else if (sym->nType & SYMF_SET)
printf ("SET : '%s' - %08lX\n", sym->tzName, getvaluefield (sym));
else
printf ("SYMBOL: '%s' - %08lX\n", sym->tzName, getvaluefield (sym));
sym = sym->pNext;
}
}
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
* DEBUG: Dump the macroargs
*
*/
void sym_DumpMacroArgs (void)
{
ULONG i;
for (i = 0; i < MAXMACROARGS; i += 1)
printf ("CurrentArg%ld: %s\n", i + 1, currentmacroargs[i]);
}