mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-24 00:44:23 +00:00
261 lines
7.0 KiB
C
261 lines
7.0 KiB
C
/*
|
|
Copyright 1982
|
|
Alcyon Corporation
|
|
8716 Production Ave.
|
|
San Diego, Ca. 92121
|
|
*/
|
|
|
|
/**
|
|
* symbol table entry allocation and lookup routines
|
|
**/
|
|
|
|
#include "parser.h"
|
|
|
|
#define STEL HSIZE/2
|
|
|
|
struct symbol *symtab[HSIZE]; /*hash table*/
|
|
struct symbol *symbols; /*pointer to next avail symbol buf*/
|
|
|
|
/* syminit - initialize the symbol table, install reswords*/
|
|
/* Goes thru the resword table and installs them into the symbol*/
|
|
/* table.*/
|
|
syminit() /* returns - none*/
|
|
{
|
|
register struct resword *rp;
|
|
|
|
for( rp = &reswords[0]; rp->r_name != 0; rp++ )
|
|
install(rp->r_name,SRESWORD|SDEFINED,rp->r_value);
|
|
}
|
|
|
|
/**
|
|
* install - install a symbol in the symbol table
|
|
* Allocates a symbol entry, copies info into it and links it
|
|
* into the hash table chain.
|
|
**/
|
|
char *
|
|
install(sym,attrib,offset) /* returns pointer to symbol struct*/
|
|
char *sym; /* symbol to install*/
|
|
int attrib; /* attribues of symbol*/
|
|
int offset; /* symbol offset (resword value)*/
|
|
{
|
|
register struct symbol *sp;
|
|
register short i;
|
|
|
|
while( (sp=symbols) <= 0 ) {
|
|
if( (sp = (struct symbol *)sbrk(SYMSIZE)) == -1 )
|
|
ferror("symbol table overflow");
|
|
for( i = SYMSIZE/(sizeof *symbols); --i >= 0; ) {
|
|
if (sp <= 0)
|
|
ferror("bad symbol table");
|
|
sp->s_next = symbols;
|
|
symbols = sp++;
|
|
}
|
|
}
|
|
symbols = sp->s_next;
|
|
sp->s_attrib = attrib;
|
|
sp->s_sc = sp->s_type = sp->s_dp = sp->s_ssp = 0;
|
|
sp->s_offset = offset;
|
|
if (in_struct) {
|
|
sp->s_par = struc_parent[in_struct];
|
|
hold_sib = struc_sib[in_struct];
|
|
sp->s_scope = (infunc) ? FUNC_SCOPE : GLOB_SCOPE; /* [vlh] 4.2 */
|
|
|
|
#ifdef DEBUG
|
|
if (symdebug)
|
|
printf(" struct element parent is %.8s\n", sp->s_par->s_symbol);
|
|
#endif
|
|
if (struc_sib[in_struct]) {
|
|
struc_sib[in_struct]->s_sib = sp;
|
|
#ifdef DEBUG
|
|
if (symdebug)
|
|
printf(" sparent sib is %.8s\n",struc_sib[in_struct]->s_symbol);
|
|
#endif
|
|
}
|
|
else {
|
|
struc_parent[in_struct]->s_child = sp;
|
|
#ifdef DEBUG
|
|
if (symdebug)
|
|
printf(" child of %.8s\n",struc_parent[in_struct]->s_symbol);
|
|
#endif
|
|
}
|
|
struc_sib[in_struct] = sp;
|
|
sp->s_child = sp->s_sib = 0;
|
|
}
|
|
else {
|
|
sp->s_sib = sp->s_child = sp->s_par = 0;
|
|
sp->s_scope = scope_level; /* [vlh] 4.2 */
|
|
}
|
|
symcopy(sym,sp->s_symbol); /*copy symbol to symbol struct*/
|
|
i = symhash(sym,in_struct|smember); /*link into chain list*/
|
|
sp->s_next = symtab[i];
|
|
symtab[i] = sp;
|
|
return((char *)sp);
|
|
}
|
|
|
|
/* lookup - looks up a symbol in symbol table*/
|
|
/* Hashes symbol, then goes thru chain, if not found, then*/
|
|
/* installs the symbol.*/
|
|
char *
|
|
lookup(sym,force) /* returns pointer to symbol buffer*/
|
|
char *sym; /* pointer to symbol*/
|
|
int force; /* [vlh] 4.2 force entry in symbol table */
|
|
{
|
|
register struct symbol *sp, *hold;
|
|
register char *p;
|
|
short exact, prev_level; /* same name, diff type or offset */
|
|
|
|
p = sym; prev_level = 0;
|
|
for( sp = symtab[symhash(p,0)]; sp != 0; sp = sp->s_next )
|
|
if((sp->s_attrib&(SRESWORD|STYPEDEF)) && symequal(p,sp->s_symbol))
|
|
return(sp);
|
|
if (!(smember|in_struct)) { /*[vlh]*/
|
|
hold = 0;
|
|
for( sp=symtab[symhash(p,0)]; sp!=0; sp=sp->s_next )
|
|
if(symequal(p,sp->s_symbol))
|
|
if (scope_level == sp->s_scope) /* [vlh] 4.2 added scope... */
|
|
return(sp); /* perfect scope match */
|
|
else
|
|
if (prev_level <= sp->s_scope) { /* only closer scope */
|
|
hold = sp;
|
|
prev_level = sp->s_scope;
|
|
}
|
|
if (!force && hold) /* [vlh] 4.2 added scope... */
|
|
return(hold);
|
|
}
|
|
else { /* doing a declaration or an expression */
|
|
hold = 0; exact = 0;
|
|
for( sp=symtab[symhash(p,in_struct|smember)]; sp!=0; sp=sp->s_next ) {
|
|
if( symequal(p,sp->s_symbol) ) {
|
|
if (symsame(sp,hold,&exact))
|
|
return(sp);
|
|
else if (!hold && !exact)
|
|
hold = sp;
|
|
}
|
|
}
|
|
if (hold && (instmt || in_struct==0 || smember!=0)) /*4.1*/
|
|
return(hold);
|
|
}
|
|
#ifdef DEBUG
|
|
if (symdebug) printf("installing [%.8s] %d\n",p,indecl);
|
|
#endif
|
|
return(install(p,0,0));
|
|
}
|
|
|
|
/* freesyms - frees all local symbols at end of function declaration*/
|
|
/* Searches thru symbol table, deleting all symbols marked as locals*/
|
|
freesyms(level) /* returns - none*/
|
|
int level; /* [vlh] 4.2 scope levels... */
|
|
{
|
|
register short i;
|
|
register struct symbol *sp, *tp, *nextp, **htp;
|
|
|
|
for( htp = &symtab[0], i = HSIZE; --i >= 0; htp++ )
|
|
for( tp = 0, sp = *htp; sp != 0; sp = nextp ) {
|
|
nextp = sp->s_next;
|
|
if (level == FUNC_SCOPE)
|
|
if( !(sp->s_attrib&SDEFINED) ) {
|
|
error("undefined label: %.8s",sp->s_symbol);
|
|
sp->s_attrib |= SDEFINED;
|
|
}
|
|
if (sp->s_attrib & (SGLOBAL|SRESWORD) )
|
|
tp = sp;
|
|
else if ( !(sp->s_attrib & SGLOBAL) && sp->s_scope < level)
|
|
tp = sp;
|
|
else {
|
|
#ifdef DEBUG
|
|
if (symdebug)
|
|
printf("freeing %s, level %d\n",sp->s_symbol,level);
|
|
#endif
|
|
if( tp )
|
|
tp->s_next = sp->s_next;
|
|
else
|
|
*htp = sp->s_next;
|
|
sp->s_next = symbols;
|
|
symbols = sp;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* chksyms - checks symbol table for undefined symbols, etc.*/
|
|
/* Goes thru the symbol table checking for undeclared forward*/
|
|
/* referenced structures, and outputs local symbols for debugger.*/
|
|
chksyms(ok) /* returns - none*/
|
|
int ok;
|
|
{
|
|
register struct symbol **htp, *sp;
|
|
register short i, sc;
|
|
|
|
for( htp = &symtab[0], i = HSIZE; --i >= 0; htp++ )
|
|
for( sp = *htp; sp != 0; sp = sp->s_next ) {
|
|
sc = sp->s_sc;
|
|
if(sc!=0 && sp->s_ssp>=0 && (BTYPE(sp->s_type))==FRSTRUCT) {
|
|
sp->s_ssp = frstab[sp->s_ssp]->s_ssp; /* 3.4 ssp>0 */
|
|
sp->s_type = (sp->s_type&~TYPE) | STRUCT;
|
|
sp->s_par = frstab[sp->s_ssp]->s_par;
|
|
}
|
|
if( sc == PDECLIST ) {
|
|
error("not in parameter list: %.8s",sp->s_symbol);
|
|
sp->s_sc = AUTO;
|
|
if (ok)
|
|
outlocal(sp->s_type,sc,sp->s_symbol,sp->s_offset);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* symhash - compute hash value for symbol*/
|
|
/* Sums the symbols characters and takes that modulus the hash table*/
|
|
/* size.*/
|
|
symhash(sym,stel) /* returns hash value for symbol*/
|
|
char *sym; /* pointer to symbol*/
|
|
int stel; /* structure element flag*/
|
|
{
|
|
register char *p;
|
|
register short hashval, i;
|
|
|
|
hashval = (stel ? STEL : 0 );
|
|
for( p = sym, i = SSIZE; *p != '\0' && i > 0; i-- )
|
|
hashval += *p++;
|
|
return( hashval % HSIZE );
|
|
}
|
|
|
|
/* symequal - check for symbol equality*/
|
|
/* Does comparison between two symbols.*/
|
|
symequal(sym1,sym2) /* returns 1 if equal, 0 otherwise*/
|
|
char *sym1; /* pointer to first symbol*/
|
|
char *sym2; /* pointer to second symbol*/
|
|
{
|
|
register char *p, *q;
|
|
register short i;
|
|
|
|
for( p = sym1, q = sym2, i = SSIZE; *p == *q++; )
|
|
if( *p++ == '\0' || --i == 0 )
|
|
return(1);
|
|
return(0);
|
|
}
|
|
|
|
/* symsame - symbol member same as declared */
|
|
symsame(sp,hold,exact) /* [vlh] */
|
|
struct symbol *sp, *hold;
|
|
short *exact;
|
|
{
|
|
if (struc_parent[in_struct]==sp->s_par) /* all structures have parents */
|
|
return(1);
|
|
if (hold)
|
|
if (sp->s_type != hold->s_type || sp->s_offset != hold->s_offset)
|
|
*exact = 1;
|
|
return(0);
|
|
}
|
|
|
|
/* symcopy - symbol copy*/
|
|
/* Copies one symbol to another.*/
|
|
symcopy(sym1,sym2) /* returns - none*/
|
|
char *sym1; /* pointer to symbol to copy*/
|
|
char *sym2; /* pointer to area to copy to*/
|
|
{
|
|
register char *p, *q;
|
|
register short i;
|
|
|
|
for( p = sym1, q = sym2, i = SSIZE; --i >= 0; )
|
|
*q++ = ( *p ? *p++ : '\0');
|
|
}
|