/*****************************************************
 * PROJECT:       BBB interpreter
 * ORGANIZATION:  Microfluffy Corp.
 * LANGUAGE:      any ANSI C++ complaint
 * FILE:          symtab.cpp
 * DESCRIPTION:   This file implements the symbol table
 * VERSION:       1.0
 *****************************************************/

#include <string.h>
#include "bbb.h"

/*data types that the symbol table needs*/
/* record that contains the value of a string variable */
typedef struct {
  char name[MAX_VAR+1];
  char value[MAX_STRVARLEN+1];
} strvarrec;

/* record that contains the value of an integer variable */
typedef struct {
  char name[MAX_VAR+1];
  int value;
} intvarrec;


/* variables that actually contain the symbols */

/* these contain the actual variable values */
strvarrec StrTable[MAX_STRVAR];
intvarrec IntTable[MAX_INTVAR];

/* these mark which entries in the table have been used */
int StrIdx;
int IntIdx;


/* initialization */
void InitSymtab()
{
  StrIdx = 0;         /*set table sizes to zero*/
  IntIdx = 0;
}

/* figure out if <name> is referring to a string variable */
boolean IsStrVar(char* name)
{
  return (name[strlen(name)-1] == '$');
}


/* integer variable lookup */
int GetIntVal(char* name)
{
  int i;
  /* search through the integer table for the variable */
  /* named <name>, and if it is found, put it's value */
  /* in <value> and return.*/
  for (i = 0; i < IntIdx; i++) {
    if (strcmp(name, IntTable[i].name) == 0) {
      return IntTable[i].value;
    }
  }
  /* if the variable isn't there, then add it */
  i = 0;
  SetIntVal(name, i);

  return 0;
}  

/* string variable lookup */
void GetStrVal(char *name, char* value)
{
  int i;

  /* search through the string table for the variable */
  /* named <name>, and if it is found, put it's value */
  /* in <value> and return */
  for (i = 0; i < StrIdx; i++) {
    if (strcmp(name, StrTable[i].name) == 0)  {
      strcpy(value, StrTable[i].value);
      return;
    }
  }

  /* if the variable isn't there, then add it */
  strcpy(value, "");
  SetStrVal(name, value);
} 

/* set the value of an integer variable */
void SetIntVal(char *name, int value)
{
  int i;

  /* try to lookup the variable <name>, and set it's value */
  for (i = 0; i < IntIdx; i++) {
    if (strcmp(name, IntTable[i].name) == 0) {
      IntTable[i].value = value;
      return;
    }
  }

  /* don't allow the add if the table is full or if the */
  /* variable name is too long */
  if (IntIdx == MAX_INTVAR)
    PrintError(e_nomem, 0);
  if (strlen(name) > MAX_VAR)
    PrintError(e_varlen, 0);

  /* increment the table size and record the variable */
  strcpy(IntTable[IntIdx].name, name);
  IntTable[IntIdx].value = value;
  IntIdx++;
}  

/* set the value of a string variable */
void SetStrVal(char *name, char *value) {
  int i;

  /* try to lookup the variable <name>, and set it's value */
  for (i = 0; i < StrIdx; i++) {
    if (strcmp(name, StrTable[i].name) == 0) {
      strcpy(StrTable[i].value, value);
      return;
    }
  }

  /* don't allow the add if the table is full or if the */
  /* variable name is too long */
  if (StrIdx == MAX_STRVAR)
    PrintError(e_nomem, 0);
  if (strlen(name) > MAX_VAR)
    PrintError(e_varlen, 0);
    
  /* increment the table size and record the variable */
  strcpy(StrTable[StrIdx].name, name);
  strcpy(StrTable[StrIdx].value, value);
  StrIdx++;
}  


