/*
* symtab.C
*/
#include <iostream.h>
#include <string.h>
#include "symtab.h"
extern bool debugFlag;
PSymtabCls ScopeCls::vista = 0; // define static member
SymtabEntryCls :: SymtabEntryCls(char *Name) {
if (debugFlag) cout << "SymtabEntryCls()" << endl;
name = Name;
}
int SymtabEntryCls :: emit() {
cout << "SymtabEntryCls::emit() BASE CLASS!!!!" << endl;
return 0;
}
SymbolCls::SymbolCls(char *name, PDataTypeCls dataType, PAddressCls addr)
{
this->name = name;
data_type = dataType;
address = addr;
}
PDataTypeCls SymbolCls::getDataType()
{
return data_type;
}
PAddressCls SymbolCls::getAddress()
{
return address;
}
/* end-attributes */
/* begin-symtab */
/* ******************************************************************** */
/*
* SymtabCls
*/
/* ******************************************************************** */
SymtabCls :: SymtabCls() {
if (debugFlag) cout << "SymtabCls::()"<< endl;
tablesize = 17; //Must be a prime for good performance
hashtable = new int[tablesize];
next_location = 1; // sacrifice 0th spot - hashtable empty:NIL
symtab = new PSymtabEntryCls[tablesize]; // Note "P" !!!!
PSymtabEntryCls tmp = new SymtabEntryCls(" ");
for (int i=0; i<tablesize; i++) {
hashtable[i] = 0;
symtab[i] = tmp;
}
}
int SymtabCls :: hash(char *s) {
if (debugFlag) cout << "SymtabCls :: hashing for " << s ;
char* ss = s;
unsigned int h = 0, g;
for (; *ss != '\0'; ss++) {
h = (h << 4) + *ss;
if (g = h & 0xf0000000) {
h ^= g >> 24; // fold top 4 bits onto ------X-
h ^= g; // clear top 4 bits
}
}
return h % tablesize ;
}
int SymtabCls :: insert(PSymtabEntryCls info) {
if (debugFlag) cout << "SymtabCls::insert()" << endl;
//Return 0 if insert successful; else location in symtab.
//Look for open slot in the hashtable....
int Try, hash_try; //`try' can be a reserved word
char *Name = info -> name;
if (debugFlag) cout<<"preparing to enter"<<Name<<"\n";
Try = hash(Name);
if (debugFlag) cout << "preparing to go into hash table at " << Try << endl;
while (hash_try = hashtable[Try]) { //something's in hashtable
//Check to see if it's the same thing we want to insert...
if (!strcmp((symtab[hash_try] -> name), Name)) {
return hash_try; //it's already there!
} else if (++Try >= tablesize) {
//resolve collision by looking for open spot ...
Try = 0; //wrap around
}
//Mature (growing) tables can be at most 2/3 full,
}
// So an open spot MUST be found
hashtable[Try] = next_location;
if (debugFlag) cout << "entered current loc'n in table " << Try << endl;
symtab[next_location++] = info; //Since they're both pointers
return 0; // success!
}
PSymtabEntryCls SymtabCls :: lookup(char *Name) {
if (debugFlag) cout << "SymtabCls :: lookup for " << Name ;
int cur_table_size = tablesize;
int Try, orig_try, hash_try;
orig_try = Try = hash(Name);
hash_try = hashtable[Try];
while (hash_try) {
if (!strcmp(symtab[hash_try] -> name, Name)) {
return symtab[hash_try];
}
if (++Try >= cur_table_size) Try = 0; // wrap around
if (Try == orig_try) {
return symtab[0];
} else {
hash_try = hashtable[Try];
}
}
return 0; //Failure!
}
|