// ********************************************
// *                                          *
// *  SymbolTable.h                           *
// *                                          *
// *  Interface for an SymbolTable class      *
// *                                          *
// *  Author: Mariusz Zaczek                  *
// *    Date: 4/6/99                          *
// *   Class: Tu 11-1 Chad Peiper             *
// *                                          *
// ********************************************

#ifndef  _SYMBOLTABLE_H
#define  _SYMBOLTABLE_H

#include "array.h"
#include "hashbase.h"
#include "singlist.h"
#include "stack.h"
#include "string.h"
#include "StringHash.h"

// Name: Variable
//
// This struct will serve as the value holder of variables to be
//  declared during the program. It also keeps track of the level
//  at which the variable is nested.
//
struct Variable
{
  int value;            // value of Variable
  int nest_depth;       // nest depth of Variable

  // operator==
  //   - operator to compare if two Variables are equivalent
  friend int operator==(const Variable& left, const Variable& right);  

  // operator<<
  //   - required output operator...outputs Variable name and value
  friend ostream & operator<<(ostream & Out, Variable& outputVariable);

};


// Name: SymbolTable
//
// This class is used as an interpreter via a hash table. This
//  class stores Stacks of Variables in the table and allows the
//  user to define new Variables, store values to these Variables,
//  and read them. In addition, it allows for nesting within the
//  program itself, thus making for a more robust interpreter.
//
class SymbolTable
{
 private:
   StringHash<Stack<Variable>* >* MyTable;  // Hash Table to store 
					    // stacks of Variables
   int current_depth;			    // integer variable keeping
                                            // track of current nest level
   Stack<String> *NameStk;                  // Stack containing names of 
                                            // of elements stored

 public:

   // SymbolTable
   // 	- default constructor
   //	- initializes current_depth, the MyTable hash table
   //     & the NameStk Stack
   SymbolTable();


   // ~SymbolTable
   // 	- destructor
   // 	- deletes dynamically allocated memory
   ~SymbolTable();


   // Declare
   //	- parameters : VarName - a String representing the name
   //                   of the variable.
   //   - creates a new Variable with the name, VarName, in the
   //     current procedure.
   void Declare(String VarName);


   // Write
   //	- parameters : VarName - a String representing the name 
   //                   of the variable.
   //                  VarValue - an in represening the value 
   //                   of the variable
   //   - Assigns the value of VarValue to the Variable of name
   //     VarName
   void Write(String VarName, int VarValue);


   // Read
   //   - parameters : VarName - a String representing the name
   //                   of the variable
   //   - read the value of the variable having name, VarName, 
   //     and returns.
   int Read(String VarName);


   // CallProcedure
   //   - parameters : none
   //   - increases the nesting level of the program
   void CallProcedure(); 


   // ExitProcedure
   //   - parameters : none
   //   - decreases the nesting level of the procedure and removes any
   //     variable declared or stored in the previous nesting level.
   void ExitProcedure();

};

#endif
