mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-23 08:24:18 +00:00
Upload
Digital Research
This commit is contained in:
304
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/orgc068/symt.c
Normal file
304
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/orgc068/symt.c
Normal file
@@ -0,0 +1,304 @@
|
||||
/*
|
||||
Copyright 1982
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
|
||||
@(#)symt.c 1.8 12/30/83
|
||||
*/
|
||||
|
||||
/**
|
||||
* symbol table entry allocation and lookup routines
|
||||
**/
|
||||
|
||||
#include "parser.h"
|
||||
|
||||
#define STEL HSIZE/2
|
||||
|
||||
#ifndef SYM_TO_DSK
|
||||
struct symbol *symtab[HSIZE]; /*hash table*/
|
||||
struct symbol *symbols; /*pointer to next avail symbol buf*/
|
||||
#endif
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
#ifdef SYM_TO_DSK
|
||||
install("",0,0); /* null entry at zero */
|
||||
#endif
|
||||
for( rp = &reswords[0]; rp->r_name != 0; rp++ )
|
||||
install(rp->r_name,SRESWORD|SDEFINED,rp->r_value);
|
||||
}
|
||||
|
||||
#ifndef SYM_TO_DSK
|
||||
/**
|
||||
* 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, is;
|
||||
|
||||
#ifndef DECC
|
||||
while( (sp=symbols) <= 0 ) {
|
||||
#else
|
||||
/**
|
||||
* Peculiar bug on the vax required changing <= to ==. DEC
|
||||
* people are checking into why the relational <, >, <=, >=
|
||||
* don't work properly when a global pointer to a structure
|
||||
* is compared with 0.
|
||||
**/
|
||||
while( (sp=symbols) == 0 ) {
|
||||
#endif
|
||||
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++;
|
||||
}
|
||||
}
|
||||
is = in_struct;
|
||||
symbols = sp->s_next;
|
||||
sp->s_attrib = attrib;
|
||||
sp->s_offset = offset;
|
||||
sp->s_sc = sp->s_type = sp->s_dp = sp->s_ssp = 0;
|
||||
sp->s_sib = sp->s_child = sp->s_par = 0;
|
||||
if (is) {
|
||||
sp->s_par = struc_parent[is];
|
||||
hold_sib = struc_sib[is];
|
||||
sp->s_scope = (infunc) ? FUNC_SCOPE : GLOB_SCOPE; /* [vlh] 4.2 */
|
||||
if (struc_sib[is])
|
||||
struc_sib[is]->s_sib = sp;
|
||||
else
|
||||
struc_parent[is]->s_child = sp;
|
||||
struc_sib[is] = sp;
|
||||
}
|
||||
else
|
||||
sp->s_scope = scope_level; /* [vlh] 4.2 */
|
||||
|
||||
symcopy(sym,sp->s_symbol); /*copy symbol to symbol struct*/
|
||||
i = symhash(sym,is|smember); /*link into chain list*/
|
||||
sp->s_next = symtab[i];
|
||||
symtab[i] = sp;
|
||||
#ifdef DEBUG
|
||||
if (symdebug && attrib != (SRESWORD|SDEFINED)) {
|
||||
printf(" scope %d\n",sp->s_scope);
|
||||
/*
|
||||
if(sp->s_par) printf(" struct element parent [%.8s] %d %ld\n",
|
||||
sp->s_par->s_symbol,is,sp->s_par);
|
||||
else printf(" NO parent\n");
|
||||
if(struc_sib[is]) printf(" struct sib [%.8s]\n",
|
||||
struc_sib[is]->s_symbol);
|
||||
else printf(" struct sib NULL\n");
|
||||
if(struc_parent[is]) {
|
||||
printf(" struct par [%.8s] ",struc_parent[is]->s_symbol);
|
||||
if(struc_parent[is]->s_child) printf("child [%.8s]\n",
|
||||
struc_parent[is]->s_child->s_symbol);
|
||||
else printf("no child\n");
|
||||
}
|
||||
else printf(" struct parent NULL\n");
|
||||
*/
|
||||
}
|
||||
#endif
|
||||
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);
|
||||
hold = 0;
|
||||
if (!(smember|in_struct)) { /*[vlh]*/
|
||||
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 (!force && prev_level <= sp->s_scope) {
|
||||
hold = sp;
|
||||
prev_level = sp->s_scope;
|
||||
}
|
||||
}
|
||||
if ( hold ) /* [vlh] 4.2 added scope... */
|
||||
return(hold);
|
||||
}
|
||||
else { /* doing a declaration or an expression */
|
||||
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_par = frstab[sp->s_ssp]->s_par;
|
||||
#ifdef DEBUG
|
||||
if(symdebug) printf("[%s] <= par [%s]\n",sp->s_symbol,sp->s_par->s_symbol);
|
||||
#endif
|
||||
sp->s_ssp = frstab[sp->s_ssp]->s_ssp; /* 3.4 ssp>0 */
|
||||
sp->s_type = (sp->s_type&~TYPE) | STRUCT; /* 4.2+ moved */
|
||||
}
|
||||
if( sc == PDECLIST || sc == PDECREG ) {
|
||||
error("not in parameter list: %.8s",sp->s_symbol);
|
||||
sp->s_sc = (sc == PDECLIST) ? AUTO : REGISTER;
|
||||
if (ok)
|
||||
outlocal(sp->s_type,sp->s_sc,sp->s_symbol,sp->s_offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* symhash - compute hash value for symbol
|
||||
* Sums the symbols characters and takes that modulus the hash table
|
||||
* size.
|
||||
* [vlh] 4.3, symhash must be on minimum number of chars which is a max
|
||||
* eg. Maximum number for external variable is SSIZE-1...
|
||||
**/
|
||||
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-1; *p != '\0' && i > 0; i-- )
|
||||
hashval += *p++;
|
||||
return( hashval % HSIZE );
|
||||
}
|
||||
|
||||
/**
|
||||
* symequal - check for symbol equality
|
||||
* Does comparison between two symbols.
|
||||
* [vlh] 4.3, global (external symbols) match at SSIZE-1!!!
|
||||
**/
|
||||
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;
|
||||
|
||||
i = (scope_level == GLOB_SCOPE && !smember && !in_struct) ? SSIZE-1 : SSIZE;
|
||||
for( p = sym1, q = sym2; *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');
|
||||
}
|
Reference in New Issue
Block a user