www.pudn.com > HEC-win32.zip > hashtbl.cpp


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
+                                                                   + 
+ hashtbl.cpp - the hash table                                      + 
+                                                                   + 
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ 
 
/* 
	The hash table is the gateway to the entire process of creating 
	a symbol table and resolving indentifiers during assembly 
 
	During Pass1 ( directives populate Proc and GlobVar arrays ) 
	------------ 
	 
	1) encounter a identifier declaration 
	2) take hash and query hash table 
		2a) if exists ( query proc returns non-NULL )  
			print error, redefinition 
		2b) if does not exist ( query proc returns NULL ) 
			add entry to string table 
			add entry to symbol table 
			add entry to hash table 
 
	During Pass2 ( gen. bytecode ) 
	------------ 
	 
	1) encounter a identifier in an instruction 
	2) take hash and query hash table 
		2a) if exists ( query proc returns non-NULL )  
			generate bytecode 
		2b) if does not exist ( query proc returns NULL ) 
			print error, referencing non-existent identifier 
*/ 
 
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
+ macros                                                            + 
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ 
 
/*hash table type*/ 
 
#define GLOBAL_VAR	0	 
#define PROC		1 
#define PROC_RET	2 
#define PROC_ARG	3 
#define PROC_LOC	4 
#define PROC_LBL	5 
 
char *SymTypeStr[]={"GLOBAL_VAR", 
                    "PROC", 
                    "PROC_RET","PROC_ARG","PROC_LOC","PROC_LBL"}; 
 
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
+ declaration                                                       + 
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ 
 
struct HashTbl 
{ 
	U1 empty;		/*indicates if entry is used or not*/ 
    U8 text;		/*index to strTbl*/ 
	U1 type;		/*GLOBAL_VAR -> PROC_LBL*/ 
	U4 index;		/*index to globVar, proc arrays in symbTbl*/ 
	U4 subIndex;	/*subindex for PROC_RET, ... , PROC_LBL*/ 
    struct HashTbl *left; 
    struct HashTbl *right; 
}; 
 
#define PRIME 547 
//#define PRIME 5 
 
class HashTable 
{ 
	StringTable *strTbl; 
 
	int hashpjw(unsigned char *s); 
 
	/*collision resolution BST routines*/ 
	struct HashTbl* findNode(struct HashTbl* link, char *val); 
	void insertNode(struct HashTbl** link, char *val, U8 text, U1 type, U4 ind, U4 subInd, U4 line); 
	void printTree(struct HashTbl* link, int level); 
 
	void deleteAllNodes(struct HashTbl** link); 
 
	public: 
	struct HashTbl hashTbl[PRIME]; 
 
	HashTable(StringTable *st); 
	~HashTable(); 
 
	/*hash table routine calls corresponding BST rotuine*/ 
	struct HashTbl* queryHashTbl(char *str); 
	void addHashTblEntry(char *val, U8 text, U1 type, U4 ind, U4 subInd, U4 line ); 
	void printHashTbl(); 
 
	void test(); 
}; 
 
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
+ definitions                                                        + 
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ 
 
HashTable::HashTable(StringTable *st) 
{ 
	int i; 
	for(i=0;i> 24); 
			h = h ^ g; 
		} 
	} 
 
	return h % PRIME; 
 
}/*end hashpjw*/ 
 
/*-----------------------------------------------------------------*/ 
 
struct HashTbl* HashTable::findNode(struct HashTbl* link, char *val) 
{ 
    if(link==NULL) 
    {  
        return(NULL);  
    } 
    else if(strcmp(val,(char*)&((*strTbl).text[(*link).text]))==0) 
    {  
        return(link);  
    } 
    else if(strcmp(val,(char*)&((*strTbl).text[(*link).text]))>0 ) 
    {  
        return(findNode((*link).right,val));  
    } 
    else 
    { 
        return(findNode((*link).left,val)); 
    } 
 
}/*end findNode*/ 
 
/*-----------------------------------------------------------------*/ 
 
void HashTable::insertNode(struct HashTbl** link,  
						   char *val,  
						   U8 text,  
						   U1 type,  
						   U4 ind,  
						   U4 subInd, 
						   U4 line) 
{ 
    if( (*link) == NULL ) 
    { 
        (*link) = (struct HashTbl*)malloc(sizeof(struct HashTbl)); 
		(*(*link)).empty	= FALSE; 
		(*(*link)).text		= text; 
		(*(*link)).type     = type; 
		(*(*link)).index    = ind; 
		(*(*link)).subIndex = subInd; 
        (*(*link)).left		= NULL; 
        (*(*link)).right	= NULL; 
    } 
    else if( strcmp(val,(char*)&((*strTbl).text[(*(*link)).text])) == 0 ) 
    { 
		ERROR2("re-defined identifier %s on line %lu\n",val,line); 
        return; 
    } 
	else if( strcmp(val,(char*)&((*strTbl).text[(*(*link)).text])) < 0 ) 
    { 
        insertNode( &((*(*link)).left) , val, text, type, ind, subInd, line); 
    } 
    else 
    { 
        insertNode( &((*(*link)).right) ,val, text, type, ind, subInd, line); 
    } 
    return; 
 
}/*end insertNode*/ 
 
/*-----------------------------------------------------------------*/ 
 
void HashTable::deleteAllNodes(struct HashTbl** link) 
{ 
	if(*link==NULL){ return; } 
	 
	deleteAllNodes(&(*(*link)).left); 
	deleteAllNodes(&(*(*link)).right); 
 
	//printf("freeing node %s\n",&((*strTbl).text[(*(*link)).text])); 
	free(*link); 
	*link=NULL; 
 
	return; 
 
}/*end deleteAllNodes*/ 
 
/*-----------------------------------------------------------------*/ 
 
/* 
print tree by giving root to node and zero as args 
*/ 
 
void HashTable::printTree(struct HashTbl* link, int level) 
{ 
    int i; 
    if(link==NULL) 
    { 
        return; 
    } 
    printTree((*link).right,level+1); 
    for(i=0;i