/* Copyright (c) 1993 by The Johns Hopkins University */


/*

  SYMTAB.C:  Translates symbol values for a given feature to a
  	     specific integer for indexing into distance tables.

*/


#include <stdlib.h>
#include <string.h>
#include "config.h"
#include "pebls.h"


node *classtab[HASH_SIZE];
node *symtab[FEATURES_MAX][HASH_SIZE];
extern config_type CONFIG;



/* ------------------------------------------------------------ */
/* HASH:  Simple Hashing function used to determine storage     */
/*  location of symbolic names.					*/
/* INPUTS:  symbol = The symbol name being searched for/stored  */

int hash(char symbol[])
{
    return (symbol[0] % HASH_SIZE);
}



/* ------------------------------------------------------------ */
/* INITIALIZE_CLASSTAB:  Initialize the CLASS symbol table	*/

void initialize_classtab(void)
{
    int hs;
    for (hs=0; hs<HASH_SIZE; hs++)
	classtab[hs] = NULL;
}





/* ------------------------------------------------------------ */
/* CLASSTAB_LOOKUP: Look up a symbol in the table of class 	*/
/*   symbols.							*/
/* INPUTS:  class_name = name of class symbol			*/
 
int classtab_lookup(char class_name[])
{
    int hashval;
    node *current;


    hashval = hash(class_name);
    if ((current = classtab[hashval]) == NULL)
	error(UNDECLARED_CLASS_ERR, class_name);
    
    while (strcmp(current->symbol,class_name) != 0)
    {
	current = current->next;
	if (current == NULL) error(UNDECLARED_CLASS_ERR, class_name);
    }

    return (current->value);
}



/* ------------------------------------------------------------ */
/* CLASSTAB_INSERT:  Insert a new class symbol into the table   */
/* INPUTS:  class_name = symbolic name				*/
/*          value      = index value identified with symbol     */

void classtab_insert(char class_name[], int value)
{
    int hashval;
    node *newnode;

    hashval = hash(class_name);
    newnode = (node *) malloc (sizeof(node));

    strcpy(newnode->symbol, class_name);
    newnode->value = value;
    newnode->next = classtab[hashval];
    classtab[hashval] = newnode;
}




/* ------------------------------------------------------------ */
/* INITIALIZE_SYMTAB:  Initialize the symbol table		*/

void initialize_symtab(void)
{
    int f, hs;
    for (f=0; f<FEATURES_MAX; f++)
	for (hs=0; hs<HASH_SIZE; hs++)
	    symtab[f][hs] = NULL;
}




/* ------------------------------------------------------------ */
/* SYMTAB_LOOKUP:  Look up a value in the symbol table.		*/
/* INPUTS:  feature = feature index associated with symbol	*/
/*  	    symbol  = symbolic value				*/
/* OUTPUT:  index associated with 'symbol' 			*/

int symtab_lookup(int feature, char symbol[])
{
    int hashval;
    int feature_index;
    node *current;
    if (CONFIG.common_values == TRUE) feature_index = 0;
    else feature_index = feature;
    hashval = hash(symbol);

    if ((current = symtab[feature_index][hashval]) == NULL)
	error(UNDECLARED_VALUE_ERR, symbol);


    while (strcmp(current->symbol,symbol) != 0)
    {
	current = current->next;
	if (current == NULL) error(UNDECLARED_VALUE_ERR, symbol);    
    }

    return (current->value);
}



/* ------------------------------------------------------------ */
/* SYMTAB_INSERT:  Insert a new symbol into the table		*/
/* INPUTS:  feature_index = index into list of features		*/
/*          symbol = symbolic value				*/
/*	    value =  index to be associated with symbol		*/

void symtab_insert(int feature_index, char symbol[], int value)
{
    int hashval;
    node *newnode;

    hashval = hash(symbol);
    newnode = (node *) malloc (sizeof(node));

    strcpy(newnode->symbol, symbol);
    newnode->value = value;
    newnode->next = symtab[feature_index][hashval];
    symtab[feature_index][hashval] = newnode;
}


