• wanli's avatar
    update · ba10055a
    wanli authored
    ba10055a
symtab.c 3.33 KB
/* 
 * symtab.c - Symbol Table package routines.
 *	      ( Descriptions in file symtab.h .)
 * 
 * Author:	Russ Fish
 * 		Computer Science Dept.
 * 		University of Utah
 * Date:	3 September 1981
 */

#include "misc.h"
#include "symtab.h"

/*****************************************************************
 * TAG( new_symbol )
 */
id *				/* Constructor. */
new_symbol( sym_name, table )
string sym_name;
hash_table * table;
{
    id  * ret,  * * slot;

    /* Allocate id node and link into symbol table at hashed location. */
    ret = NEW_1( id );
    slot = hash( sym_name, table );
    ADD( ret, *slot );

    ret->var_name = sym_name;	/* Link to name string from id. */
    ret->var_value = NULL;	/* No value cell or fn ptr yet. */

    return( ret );
}

/*****************************************************************
 * TAG( find_symbol )
 */
id *				/* Locator, NULL if not found. */
find_symbol( sym_name, table )
string sym_name;
hash_table * table;
{
    register id * sym;			/* Symbol list traversal ptr. */

    /* Search list to which symbol hashes. */
    TRACE( sym, *hash( sym_name, table ) )
    {
	/* Break out of search loop when matching name is found. */
	if ( strcmp( sym_name, sym->var_name ) == 0 ) break;
    }				/* sym is NULL if trace loop exits. */

    return( sym );
}

/*****************************************************************
 *  TAG( new_hash_table )
 */
hash_table *			/* Constructor. */
new_hash_table( n_entries )
int n_entries;
{
    hash_table * ret;
    id ** ent;			/* Entries of table are bases of id lists. */
    int i;

    ret = NEW( hash_table, sizeof( hash_table ) + n_entries * sizeof( id * ) );

    ret->hash_size = n_entries;		/* Remember the size, for hash comp. */

    for ( i = 0, ent = & ret->hash_id[0];	/* Clear the entries. */
	  i < n_entries;
	  i++ )
	      *ent++ = NULL;	/* Empty list pointers. */

    return( ret );
}

/*****************************************************************
 *  TAG( hash )
 */
id * *	   /* Hashing algorithm, returns ptr to base of an id list in table. */
hash( sym_name, table )
string sym_name;
hash_table * table;
{
    register char * c;
    register int i, n, hash_val;

    /* Hash is the total of the character codes, modulo number of entries. */
    for ( i = 0, n = strlen( sym_name ), c = (char *)sym_name, hash_val = 0;
	  i < n;
	  i++ )
	      hash_val += *c++;

    return( & table->hash_id[ hash_val % table->hash_size ] );
}

/*****************************************************************
 * TAG( ld_table )
 * 
 * Links a vector of already initialiazed id's into a hash table.
 * NULL var_name terminates the vector.
 */
ld_table( id_vec, table )
id id_vec[];
hash_table * table;
{
    id * sym;			/* Vector traversal ptr. */
    id  * * slot;

    for ( sym = & id_vec[0]; sym->var_name != NULL; sym++ )
    {
	/* Link id node into symbol table at hashed location. */
        slot = hash( sym->var_name, table );
	ADD( sym, *slot );
    }
}

/*****************************************************************
 * TAG( fr_hash_table )
 * 
 * Dispose of a hash table.
 */
fr_hash_table( table )
hash_table * table;
{
    id ** ent;			/* Entries of table are bases of id lists. */
    id * ids;
    int i;

    for ( i = 0, ent = & table->hash_id[0];	/* Clear the entries. */
	  i < table->hash_size;
	  i++, ent++ )
	if ( ids = *ent )
	    FREE_LIST( ids );

    FREE( table );
}