132 lines
3.4 KiB
C
132 lines
3.4 KiB
C
#include <out.h>
|
|
#include <system.h>
|
|
#include "hash.h"
|
|
#include "header.h"
|
|
#include "back.h"
|
|
|
|
/* Findsym() manages the symbol table. It can be called in three ways.
|
|
* 1) findsym( "string", DEFINITION) : look if string is present in the
|
|
* symol table. If not create a new entry: set index into the
|
|
* string_area. Return the index to the entry. Symbol_def() will
|
|
* the fields.
|
|
* 2) findsym( "string", REFERENCE) : If string is present but never used
|
|
* (see 3)) make this name extern visible and set on_valu on -1.
|
|
* We use the on_valu field to distinguish between external visible
|
|
* names that are defined here and those that are defined in another file.
|
|
* If the string is not present create a new entry and make the name extern
|
|
* visible and set on_valu on -1.
|
|
* If the name is present do nothing special.
|
|
* 3) findsym( "string", STORE_STRING) : this call is made to save a
|
|
* copy action. The first time a name is encountered we store it
|
|
* immediately in the symbol table. If the name is not present we
|
|
* create a new entry and set the on_valu field on -2. In this
|
|
* way we can tell later that the name is not used yet. The index
|
|
* is stored in the global varaible 'index_symbol_table' because it is
|
|
* very likely that the same string is in the next call to findsym.
|
|
* (After introducing a new name one does something with this name)
|
|
*/
|
|
|
|
int string_lengte = 0,
|
|
index_symbol_table = -1;
|
|
|
|
struct Hashitem *Hashitems ;
|
|
|
|
/* MAXHASH must be a power of two ... */
|
|
#define MAXHASH 512
|
|
static int Hashtab[ MAXHASH];
|
|
static int Hash();
|
|
|
|
|
|
int find_sym( sym, isdef)
|
|
char *sym;
|
|
int isdef;
|
|
{
|
|
register struct outname *s;
|
|
register struct Hashitem *ip;
|
|
register int h;
|
|
|
|
if ( index_symbol_table != -1 ) {
|
|
s = symbol_table + index_symbol_table;
|
|
if ( sym == s->on_foff + string_area) {
|
|
if ( (s->on_valu == -2) && ( isdef == REFERENCE)) {
|
|
s->on_type = S_EXT;
|
|
s->on_valu = -1;
|
|
}
|
|
return( index_symbol_table);
|
|
}
|
|
}
|
|
|
|
h = Hash(sym);
|
|
for ( ip = Hashtab[h] + Hashitems ; ip != Hashitems;
|
|
ip = (ip->hs_next) + Hashitems) {
|
|
register char *p = sym, *q;
|
|
|
|
s = symbol_table + ip->hs_nami;
|
|
q = string_area + s->on_foff;
|
|
while (*p == *q++) if (*p++ == '\0') {
|
|
if ( (s->on_valu == -2) && (isdef == REFERENCE)) {
|
|
s->on_type = S_EXT;
|
|
s->on_valu = -1;
|
|
}
|
|
return ip->hs_nami;
|
|
}
|
|
}
|
|
|
|
if ( nname >= size_symbol)
|
|
mem_symbol_hash();
|
|
|
|
s = symbol_table + nname;
|
|
ip = Hashitems + nname + 1; /* skip the first entry */
|
|
|
|
if (isdef == REFERENCE) {
|
|
s->on_type = S_EXT;
|
|
s->on_valu = -1;
|
|
}
|
|
if (isdef == STORE_STRING) {
|
|
s->on_type = S_UND;
|
|
s->on_valu = -2;
|
|
}
|
|
|
|
ip->hs_nami = nname;
|
|
ip->hs_next = Hashtab[h];
|
|
Hashtab[h] = ip - Hashitems;
|
|
|
|
if ( sym == string)
|
|
string += string_lengte;
|
|
else { /* zie C_fil, C_lin, C_lni */
|
|
register char *p;
|
|
|
|
string_lengte = 0;
|
|
for( p=sym; *p != '\0' ; p++) {
|
|
string_lengte++;
|
|
}
|
|
while ( (string + string_lengte - string_area) >= size_string) {
|
|
mem_string();
|
|
}
|
|
for( p=sym; *p != '\0' ; p++) {
|
|
*string++ = *p;
|
|
}
|
|
}
|
|
if ( (string - string_area) >= size_string) {
|
|
mem_string();
|
|
}
|
|
*string++ = '\0';
|
|
s->on_foff = string - (string_lengte + 1) - string_area;
|
|
|
|
return nname++;
|
|
}
|
|
|
|
|
|
static int Hash(sym)
|
|
char *sym;
|
|
{
|
|
register unsigned h;
|
|
register char *s = sym;
|
|
|
|
h = 0;
|
|
while (*s) {
|
|
h = (h << 2) + *s++;
|
|
}
|
|
return (h & (MAXHASH - 1));
|
|
}
|