/*********************************************************************
 * Author: B. Alex Bridges                                           *
 * Login ID: brid0129                                                *
 * Class: CPSC-431, Winter 2000                                      *
 * Project: Laboratory Exercise 3                                    *
 * Description: This program is a lexical analyzer, the parser       *
 *              portion of a syntax analyzer, and a semantic analyzer*
 *              for the lanaguage Micro Modula-2.                    *
 * Contents: Setup and control of Symbol_Table object.               *
 *********************************************************************/
/* IMPORTS */
import java.io.*;


class Symbol_Table
{
  /* CONSTANTS */
  final static boolean b_debug = false; // CONTROLS EXTRA DEBUG OUTPUT
  final static int int_table = 100;     // SIZE OF SYMBOL TABLE

  /* GLOBAL VARIABLES */ 
  public static Token[] Token_entries  // SYMBOL TABLE'S TOKEN ENTRIES
   = new Token[int_table];
  public static int int_available = 0; // SYMBOL TABLE'S INDEX FOR NEXT ENTRY

  //public Symbol_Table()
  //{
  //  Token_entries = new Token[int_table];
  //  int_available = 0;
  //} // constructor Symbol_Table
  
  /*************************************************************************
   * Method: insert                                                        *
   * Purpose: Inserts the given token into the symbol table.               *
   * Input: --PARAMATERS--                                                 *
   *        => 'Token_given' = The given token which is to be inserted.    *
   * Output: --RETURNS--                                                   *
   *         => 0 or greater = The array index of the inserted token.      *
   *         => -1           = Insertion failed due to table being full.   *
   *************************************************************************/
  public static int insert(Token Token_given)
  {
    /* LOCAL VARIABLES */
    int int_index; // RESULTING INDEX
    
    /* CHECK IF ENTRY ALREADY EXISTS */
    int_index = lookup(Token_given.str_actual);
    
    if( int_index >= 0 )
    {
      if(b_debug)
        System.out.println("=> The Token['"+Token_given.str_actual+
                           "','"+Token_given.str_name+
                           "'] already exists in the symbol table at '"+
                           int_index+"'.");

      return(int_index);
    } // if  
    else
    {
      /* CHECK IF TABLE IS FULL */
      if(int_available >= int_table)
      {
        System.out.println("\nERROR: The table limit of '"+int_table+
                           "' has been reached.\n");
        
        return(-1);
      } // if
      else
      {
        Token_entries[int_available++] = Token_given;

        if(b_debug)
          System.out.println("=> The Token['"+Token_given.str_actual+
                             "','"+Token_given.str_name+
                             "'] was inserted into the symbol table at '"+
                             String.valueOf(int_available-1)+"'.");
        
        return(int_available-1);                     
      } // else
    } // else
  } // method insert

  /*************************************************************************
   * Method: retrieve                                                      *
   * Purpose: Retrieves the type of the token in the symbol table.         *
   * Input: --PARAMATERS--                                                 *
   *        => 'str_id'   = The id of the token which is to be retrieved.  *
   * Output: --RETURNS--                                                   *
   *        => If available,the type of the token which is to be retrieved.*
   *************************************************************************/
  public static String retrieve(String str_id)
  {
    /* LOCAL VARIABLES */
    int int_index; // RESULTING INDEX
    
    /* CHECK IF ENTRY ALREADY EXISTS */
    int_index = lookup(str_id);
    
    if( int_index < 0 )
    {
      System.out.println("\n ERROR: The Token['"+str_id+
                         "'] could not be found in the symbol table "+
                         "and therefore could not be retrieved.\n");
      
      return(null);
    } // if  
    else
    {
      if(b_debug)
        System.out.println("=> The type information of the Token['"+str_id+
                           "']' at '"+int_index+"' in the symbol table "+
                           "is '"+Token_entries[int_index].str_attribute+
                           "'");


      return(Token_entries[int_index].str_attribute);
    } // else
  } // method update

  /*************************************************************************
   * Method: update                                                        *
   * Purpose: Updates the type of the token in the symbol table.           *
   * Input: --PARAMATERS--                                                 *
   *        => 'str_id'   = The id of the token which is to be updated.    *
   *        => 'str_type' = The type for the token which is to be updated. *
   * Output: --RETURNS--                                                   *
   *         => 0 or greater = The array index of the updated token.       *
   *         => -1           = Update failed due to no matching token.     *
   *************************************************************************/
  public static int update(String str_id, String str_type)
  {
    /* LOCAL VARIABLES */
    int int_index; // RESULTING INDEX
    
    /* CHECK IF ENTRY ALREADY EXISTS */
    int_index = lookup(str_id);
    
    if( int_index < 0 )
    {
      System.out.println("\n ERROR: The Token['"+str_id+
                         "'] could not be found in the symbol table "+
                         "and therefore could not be updated.\n");
    } // if  
    else
    {
      if(b_debug)
        System.out.println("=> The type of the Token['"+str_id+"']' at '"+
                           int_index+"' in the symbol table "+                          "changed from '"+
                           Token_entries[int_index].str_attribute+
                           "' to '"+str_type+"'.");


      Token_entries[int_index].str_attribute = str_type;
    } // else

    return(int_index);
  } // method update

  /*************************************************************************
   * Method: lookup                                                        *
   * Purpose: Looks up the given lexeme string in the symbol table.        *
   * Input: --PARAMATERS--                                                 *
   *        => 'str_given' = The given string which is to be looked up.    *
   * Output: --RETURNS--                                                   *
   *         => 0 or greater = The array index of the matching token.      *
   *         => -1           = No matching token was found.                *
   *************************************************************************/
  private static int lookup(String str_given)
  {
    /* LOCAL VARIABLES */
    // NONE
    
    /* LOOK FOR MATCHING TOKEN */
    for(int i = int_available-1; i >= 0; i--)
      if( Token_entries[i].str_actual.equals(str_given) )
        return(i);

    /* NO MATCH FOUND */
    return(-1);    
  } // method lookup
} // class Symbol_Table

