| home | contents | previous | next page | send comment | send link | add bookmark |

SYM_TABL.CPP

symbol table

/*-------------------------------------------------------------------*
     Symbol Table functions

     File:     sym_tabl.cpp

     Module:   symbol table

     by:  Stephen R. Schmitt
 *-------------------------------------------------------------------*/

#include <stdlib.h>
#include <string.h>
#include "tpl_data.h"

/*
 *   Global variables
 */
int Scope;
SYMTAB_NODE_PTR Symbol_table[NESTING_LEVELS];
TYPE_STRUCT_PTR Integer_typep, Real_typep,
		Boolean_typep, Char_typep,
		String_typep,  Null_typep;

/*-------------------------------------------------------------------*
			 Code Section
 *-------------------------------------------------------------------*/

/*
 *   "init_symtab" initializes the symbol table with predefined
 *   identifiers, types, and routines
 *
 *   returns:  nothing
 */
void init_symtab()
{
    Scope = 0;                                      // declaration scope
    Symbol_table[0] = NULL;                         // symbol table

    // initialize pre-defined types
    Integer_typep           = alloc_type_struct();
    Integer_typep->form     = SCALER_FORM;
    Integer_typep->size     = 1;
    Integer_typep->type_idp = NULL;

    Real_typep           = alloc_type_struct();
    Real_typep->form     = SCALER_FORM;
    Real_typep->size     = 1;
    Real_typep->type_idp = NULL;

    Boolean_typep           = alloc_type_struct();
    Boolean_typep->form     = ENUM_FORM;
    Boolean_typep->size     = 1;
    Boolean_typep->type_idp = NULL;

    Char_typep           = alloc_type_struct();
    Char_typep->form     = SCALER_FORM;
    Char_typep->size     = 1;
    Char_typep->type_idp = NULL;

    String_typep = alloc_type_struct();
    String_typep = make_string_type_ptr(MAX_STRING_LENGTH);

    Null_typep           = alloc_type_struct();
    Null_typep->form     = NO_FORM;
    Null_typep->size     = 0;
    Null_typep->type_idp = NULL;
}

/*
 *   "lookup" searches for an identifier in the symbol table.
 *   A pointer is returned if the identifier is found; NULL if not.
 *
 *   returns:  a pointer to the symbol table entry or NULL
 */
SYMTAB_NODE_PTR lookup(char *name,                  // of identifier
	               SYMTAB_NODE_PTR idp)         // of symbol table
{
    while (idp != NULL)                             // another branch?
    {
        int cmp = strcmp(name, idp->name);
        if (cmp == 0)
            return idp;                             // found match

        if (cmp < 0)
            idp = idp->left;
        else
            idp = idp->right;
    }

    return NULL;                                    // name not found
}

/*
 *   "search_symbol_tables" searches all the symbol tables in the
 *   symbol table display for an identifier.  A pointer is returned
 *   if the identifier is found; NULL if not.
 *
 *   returns:  a pointer to the symbol table entry or NULL
 */
SYMTAB_NODE_PTR search_symbol_tables(char *name)    // of identifier
{
    SYMTAB_NODE_PTR idp;

    for (int i = Scope; i >= 0; i--)
    {
        idp = lookup(name, Symbol_table[i]);
        if (idp != NULL)
            return idp;                             // found name
    }

    return NULL;                                    // name not found
}

/*
 *   "insert" puts a new identifier into the symbol table.
 *   A pointer is returned to the new entry.
 *
 *   WARNING:  Before using this function, "lookup" or
 *	       "search_symbol_tables" must return NULL.
 *
 *   returns:  a pointer to the symbol table entry
 */
SYMTAB_NODE_PTR insert(char *name,                  // of identifier
	               SYMTAB_NODE_PTR *idpp)       // of symbol table
{
    int cmp;
    SYMTAB_NODE_PTR new_idp, idp;

    // create a new node for the identifier
    new_idp = new SYMTAB_NODE;
    if (new_idp == NULL)
        runtime_error(M_OUT, M_OF, M_MEMORY, M_0);

    // initialize
    new_idp->left = NULL;
    new_idp->right = NULL;
    new_idp->next = NULL;
    new_idp->name = new char[strlen(name) + 1];
    strcpy(new_idp->name, name);
    new_idp->typep = NULL;
    new_idp->definition = UNDEFINED;
    new_idp->initialized = false;

    idp = *idpp;                                    // initial node pointer

    // now search for insertion point
    while (idp != NULL)
    {
        cmp = strcmp(name, idp->name);

        if (cmp < 0)
            idpp = &(idp->left);
        else
            idpp = &(idp->right);

        idp = *idpp;
    }

    *idpp = new_idp;                                // pointer to new_idp
    return new_idp;
}

/*
 *   "incr_scope" enters a deeper declaration scope level and pushes 
 *   its symbol table onto the display stack.
 *
 *   returns:  nothing
 */
void incr_scope()
{
    Scope++;                                        // increment level
    Symbol_table[Scope] = NULL;
}

/*
 *   "decr_scope" exits the current declaration scope and pops the
 *   current symbol table off of the display stack.
 *
 *   returns:  nothing
 */
void decr_scope()
{
    Scope--;                                        // decrement level
}

/*
 *   "assign_type_compatible" returns true iff a value of type tp2
 *   can be assigned to a variable of type tp1
 *
 *   returns:  true or false
 */
bool assign_type_compatible(TYPE_STRUCT_PTR tp1,    // destination
                            TYPE_STRUCT_PTR tp2)    // source
{
    bool result;

    if (tp1 == tp2)
    {
        if ((tp1 == Integer_typep    )||
            (tp1 == Real_typep       )||
            (tp1 == Char_typep       )||
            (tp1 == Boolean_typep    )||
            (tp1->form == ENUM_FORM  )||
            (tp1->form == STRING_FORM))
            result = true;
        else
            result = false;
    }
    else if ((tp1 == Real_typep)&&(tp2 == Integer_typep))
        result = true;
    else if ((tp1->form == STRING_FORM)&&
             (tp2->form == STRING_FORM))
        result = true;
    else
        result = false;

    return result;
}

/*
 *   "make_string_type_ptr" creates a string type structure and
 *   returns a pointer to it
 *
 *   returns:  a pointer to a type structure
 */
TYPE_STRUCT_PTR make_string_type_ptr(int length)    // of string
{
    TYPE_STRUCT_PTR tp;

    tp = alloc_type_struct();
    tp->form = STRING_FORM;
    tp->size = 1;                                   // one storage element
    tp->array.elmt_typep  = Char_typep;
    tp->array.max_index   = length - 1;             // zero based array
    tp->array.val_index   = 1;

    return tp;
}

/*
 *   "alloc_type_struct" creates a type structure and returns a
 *   pointer to it
 *
 *   returns:  a pointer to a type structure
 */
TYPE_STRUCT_PTR alloc_type_struct()
{
    TYPE_STRUCT_PTR tp = new TYPE_STRUCT;

    if (tp == NULL)
        runtime_error(M_OUT, M_OF, M_MEMORY, M_0);

    return tp;
}

| home | contents | previous | next page | send comment | send link | add bookmark |

Copyright © 2004, Stephen R. Schmitt