/*
** $Id: ltm.c,v 1.48 2000/09/11 19:45:27 roberto Exp roberto $
** Tag methods
** See Copyright Notice in lua.h
*/


#include <stdio.h>
#include <string.h>

#include "lua.h"

#include "ldo.h"
#include "lmem.h"
#include "lobject.h"
#include "lstate.h"
#include "ltm.h"


const char *const luaT_eventname[] = {  /* ORDER IM */
  "gettable", "settable", "index", "getglobal", "setglobal", "add", "sub",
  "mul", "div", "pow", "unm", "lt", "concat", "gc", "function",
  "le", "gt", "ge",  /* deprecated options!! */
  NULL
};


static int findevent (const char *name) {
  int i;
  for (i=0; luaT_eventname[i]; i++)
    if (strcmp(luaT_eventname[i], name) == 0)
      return i;
  return -1;  /* name not found */
}


static int luaI_checkevent (lua_State *L, const char *name, int t) {
  int e = findevent(name);
  if (e >= IM_N)
    luaO_verror(L, "event `%.50s' is deprecated", name);
  if (e == IM_GC && t == TAG_TABLE)
    luaO_verror(L, "event `gc' for tables is deprecated");
  if (e < 0)
    luaO_verror(L, "`%.50s' is not a valid event name", name);
  return e;
}



/* events in TAG_NIL are all allowed, since this is used as a
*  'placeholder' for "default" fallbacks
*/
/* ORDER LUA_T, ORDER IM */
static const char luaT_validevents[NUM_TAGS][IM_N] = {
  {1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1},  /* TAG_USERDATA */
  {1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1},  /* TAG_NUMBER */
  {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},  /* TAG_STRING */
  {0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1},  /* TAG_TABLE */
  {1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0},  /* TAG_LCLOSURE */
  {1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0},  /* TAG_CCLOSURE */
  {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}   /* TAG_NIL */
};

int luaT_validevent (int t, int e) {  /* ORDER LUA_T */
  return (t > TAG_NIL) ?  1 : luaT_validevents[t][e];
}


static void init_entry (lua_State *L, int tag) {
  int i;
  for (i=0; i<IM_N; i++)
    ttype(luaT_getim(L, tag, i)) = TAG_NIL;
  L->IMtable[tag].collected = NULL;
}


void luaT_init (lua_State *L) {
  int t;
  luaM_growvector(L, L->IMtable, 0, NUM_TAGS, struct IM, "", MAX_INT);
  L->last_tag = NUM_TAGS-1;
  for (t=0; t<=L->last_tag; t++)
    init_entry(L, t);
}


int lua_newtag (lua_State *L) {
  luaM_growvector(L, L->IMtable, L->last_tag, 1, struct IM,
                  "tag table overflow", MAX_INT);
  L->last_tag++;
  init_entry(L, L->last_tag);
  return L->last_tag;
}


static void checktag (lua_State *L, int tag) {
  if (!(0 <= tag && tag <= L->last_tag))
    luaO_verror(L, "%d is not a valid tag", tag);
}

void luaT_realtag (lua_State *L, int tag) {
  if (!(NUM_TAGS <= tag && tag <= L->last_tag))
    luaO_verror(L, "tag %d was not created by `newtag'", tag);
}


int lua_copytagmethods (lua_State *L, int tagto, int tagfrom) {
  int e;
  checktag(L, tagto);
  checktag(L, tagfrom);
  for (e=0; e<IM_N; e++) {
    if (luaT_validevent(tagto, e))
      *luaT_getim(L, tagto, e) = *luaT_getim(L, tagfrom, e);
  }
  return tagto;
}


int luaT_effectivetag (lua_State *L, const TObject *o) {
  lua_Type t = ttype(o);
  switch (t) {
    case TAG_USERDATA: {
      int tag = tsvalue(o)->u.d.tag;
      return (tag > L->last_tag) ? TAG_USERDATA : tag;  /* deprecated test */
    }
    case TAG_TABLE: return hvalue(o)->htag;
    default: return t;
  }
}


void lua_gettagmethod (lua_State *L, int t, const char *event) {
  int e;
  e = luaI_checkevent(L, event, t);
  checktag(L, t);
  if (luaT_validevent(t, e))
    *L->top = *luaT_getim(L, t,e);
  else
    ttype(L->top) = TAG_NIL;
  incr_top;
}


void lua_settagmethod (lua_State *L, int t, const char *event) {
  TObject temp;
  int e;
  LUA_ASSERT(lua_isnil(L, -1) || lua_isfunction(L, -1),
             "function or nil expected");
  e = luaI_checkevent(L, event, t);
  checktag(L, t);
  if (!luaT_validevent(t, e))
    luaO_verror(L, "cannot change `%.20s' tag method for type `%.20s'%.20s",
                luaT_eventname[e], luaO_typenames[t],
                (t == TAG_TABLE || t == TAG_USERDATA) ? " with default tag"
                                                          : "");
  temp = *(L->top - 1);
  *(L->top - 1) = *luaT_getim(L, t,e);
  *luaT_getim(L, t, e) = temp;
}

