/*
** table.c
** Module to control static tables
*/

char *rcs_table="$Id: table.c,v 2.1 1994/04/20 22:07:57 celes Exp celes $";

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

#include "mm.h"

#include "opcode.h"
#include "tree.h"
#include "hash.h"
#include "inout.h"
#include "table.h"
#include "lua.h"

#define streq(s1,s2)	(s1[0]==s2[0]&&strcmp(s1+1,s2+1)==0)

#define BUFFER_BLOCK 256

Symbol *lua_table;
static Word lua_ntable = 0;
static Word lua_maxsymbol = 0;

char **lua_constant;
static Word lua_nconstant = 0;
static Word lua_maxconstant = 0;



#define MAXFILE 	20
char  		       *lua_file[MAXFILE];
int      		lua_nfile;

/* Variables to controll garbage collection */
#define GARBAGE_BLOCK 256
Word lua_block=GARBAGE_BLOCK; /* when garbage collector will be called */
Word lua_nentity;   /* counter of new entities (strings and arrays) */


/*
** Initialise symbol table with internal functions
*/
static void lua_initsymbol (void)
{
 int n;
 lua_maxsymbol = BUFFER_BLOCK;
 lua_table = (Symbol *) calloc(lua_maxsymbol, sizeof(Symbol));
 if (lua_table == NULL)
 {
  lua_error ("symbol table: not enough memory");
  return;
 }
 n = lua_findsymbol("type"); 
 s_tag(n) = T_CFUNCTION; s_fvalue(n) = lua_type;
 n = lua_findsymbol("tonumber");
 s_tag(n) = T_CFUNCTION; s_fvalue(n) = lua_obj2number;
 n = lua_findsymbol("next");
 s_tag(n) = T_CFUNCTION; s_fvalue(n) = lua_next;
 n = lua_findsymbol("nextvar");
 s_tag(n) = T_CFUNCTION; s_fvalue(n) = lua_nextvar;
 n = lua_findsymbol("print");
 s_tag(n) = T_CFUNCTION; s_fvalue(n) = lua_print;
 n = lua_findsymbol("dofile");
 s_tag(n) = T_CFUNCTION; s_fvalue(n) = lua_internaldofile;
 n = lua_findsymbol("dostring");
 s_tag(n) = T_CFUNCTION; s_fvalue(n) = lua_internaldostring;
}


/*
** Initialise constant table with pre-defined constants
*/
void lua_initconstant (void)
{
 lua_maxconstant = BUFFER_BLOCK;
 lua_constant = (char **) calloc(lua_maxconstant, sizeof(char *));
 if (lua_constant == NULL)
 {
  lua_error ("constant table: not enough memory");
  return;
 }
 lua_findconstant("mark");
 lua_findconstant("nil");
 lua_findconstant("number");
 lua_findconstant("string");
 lua_findconstant("table");
 lua_findconstant("function");
 lua_findconstant("cfunction");
 lua_findconstant("userdata");
}

/*
** Given a name, search it at symbol table and return its index. If not
** found, allocate it.
** On error, return -1.
*/
int lua_findsymbol (char *s)
{
 char *n; 
 if (lua_table == NULL)
  lua_initsymbol(); 
 n = lua_varcreate(s);
 if (n == NULL)
 {
  lua_error ("create symbol: not enough memory");
  return -1;
 }
 if (indexstring(n) == UNMARKED_STRING)
 {
  if (lua_ntable == lua_maxsymbol)
  {
   lua_maxsymbol *= 2;
   if (lua_maxsymbol > MAX_WORD)
   {
    lua_error("symbol table overflow");
    return -1;
   }
   lua_table = (Symbol *)realloc(lua_table, lua_maxsymbol*sizeof(Symbol));
   if (lua_table == NULL)
   {
    lua_error ("symbol table: not enough memory");
    return -1;
   }
  }
  indexstring(n) = lua_ntable;
  s_tag(lua_ntable) = T_NIL;
  lua_ntable++;
 }
 return indexstring(n);
}


/*
** Given a name, search it at constant table and return its index. If not
** found, allocate it.
** On error, return -1.
*/
int lua_findconstant (char *s)
{
 char *n;
 if (lua_constant == NULL)
  lua_initconstant();
 n = lua_constcreate(s);
 if (n == NULL)
 {
  lua_error ("create constant: not enough memory");
  return -1;
 }
 if (indexstring(n) == UNMARKED_STRING)
 {
  if (lua_nconstant == lua_maxconstant)
  {
   lua_maxconstant *= 2;
   if (lua_maxconstant > MAX_WORD)
   {
    lua_error("constant table overflow");
    return -1;
   }
   lua_constant = (char**)realloc(lua_constant,lua_maxconstant*sizeof(char*));
   if (lua_constant == NULL)
   {
    lua_error ("constant table: not enough memory");
    return -1;
   }
  }
  indexstring(n) = lua_nconstant;
  lua_constant[lua_nconstant] = n;
  lua_nconstant++;
 }
 return indexstring(n);
}


/*
** Traverse symbol table objects
*/
void lua_travsymbol (void (*fn)(Object *))
{
 int i;
 for (i=0; i<lua_ntable; i++)
  fn(&s_object(i));
}


/*
** Mark an object if it is a string or a unmarked array.
*/
void lua_markobject (Object *o)
{
 if (tag(o) == T_STRING && indexstring(svalue(o)) == UNMARKED_STRING)
  indexstring(svalue(o)) = MARKED_STRING;
 else if (tag(o) == T_ARRAY)
  lua_hashmark (avalue(o));
}


/*
** Garbage collection. 
** Delete all unused strings and arrays.
*/
void lua_pack (void)
{
 /* mark stack strings */
 lua_travstack(lua_markobject);
 
 /* mark symbol table strings */
 lua_travsymbol(lua_markobject);

 lua_strcollector();
 lua_hashcollector();

 lua_nentity = 0;      /* reset counter */
} 


/*
** If the string isn't allocated, allocate a new string at string tree.
*/
char *lua_createstring (char *s)
{
 if (s == NULL) return NULL;
 
 if (lua_nentity == lua_block)
  lua_pack ();
 lua_nentity++;
 return lua_strcreate(s);
}


/*
** Add a file name at file table, checking overflow. This function also set
** the external variable "lua_filename" with the function filename set.
** Return 0 on success or 1 on error.
*/
int lua_addfile (char *fn)
{
 if (lua_nfile >= MAXFILE-1)
 {
  lua_error ("too many files");
  return 1;
 }
 if ((lua_file[lua_nfile++] = strdup (fn)) == NULL)
 {
  lua_error ("not enough memory");
  return 1;
 }
 return 0;
}

/*
** Delete a file from file stack
*/
int lua_delfile (void)
{
 lua_nfile--; 
 return 1;
}

/*
** Return the last file name set.
*/
char *lua_filename (void)
{
 return lua_file[lua_nfile-1];
}

/*
** Internal function: return next global variable
*/
void lua_nextvar (void)
{
 char *varname, *next;
 Object *o = lua_getparam (1);
 if (o == NULL)
 { lua_error ("too few arguments to function `nextvar'"); return; }
 if (lua_getparam (2) != NULL)
 { lua_error ("too many arguments to function `nextvar'"); return; }
 if (tag(o) == T_NIL)
 {
  varname = 0;
 }
 else if (tag(o) != T_STRING) 
 { 
  lua_error ("incorrect argument to function `nextvar'"); 
  return;
 }
 else
 {
  varname = svalue(o);
 }
 next = lua_varnext(varname);
 if (next == NULL)
 {
  lua_pushnil();
  lua_pushnil();
 }
 else
 {
  Object name;
  tag(&name) = T_STRING;
  svalue(&name) = next;
  if (lua_pushobject (&name)) return;
  if (lua_pushobject (&s_object(indexstring(next)))) return;
 }
}
