Browse Source

first full implementation of internal methods

Roberto Ierusalimschy 28 years ago
parent
commit
1444d28476
11 changed files with 404 additions and 251 deletions
  1. 225 144
      fallback.c
  2. 19 18
      fallback.h
  3. 4 5
      hash.c
  4. 2 1
      hash.h
  5. 3 1
      inout.c
  6. 7 13
      lua.h
  7. 105 56
      opcode.c
  8. 12 10
      opcode.h
  9. 3 1
      table.c
  10. 22 1
      tree.c
  11. 2 1
      tree.h

+ 225 - 144
fallback.c

@@ -3,11 +3,12 @@
 ** TecCGraf - PUC-Rio
 ** TecCGraf - PUC-Rio
 */
 */
  
  
-char *rcs_fallback="$Id: fallback.c,v 1.26 1997/02/26 17:38:41 roberto Unstable roberto $";
+char *rcs_fallback="$Id: fallback.c,v 1.27 1997/03/11 18:44:28 roberto Exp roberto $";
 
 
 #include <stdio.h>
 #include <stdio.h>
 #include <string.h>
 #include <string.h>
  
  
+#include "auxlib.h"
 #include "mem.h"
 #include "mem.h"
 #include "fallback.h"
 #include "fallback.h"
 #include "opcode.h"
 #include "opcode.h"
@@ -17,105 +18,6 @@ char *rcs_fallback="$Id: fallback.c,v 1.26 1997/02/26 17:38:41 roberto Unstable
 #include "hash.h"
 #include "hash.h"
 
 
 
 
-static void errorFB (void);
-static void indexFB (void);
-static void gettableFB (void);
-static void arithFB (void);
-static void concatFB (void);
-static void orderFB (void);
-static void GDFB (void);
-static void funcFB (void);
-
-
-/*
-** Warning: This list must be in the same order as the #define's
-*/
-struct FB  luaI_fallBacks[] = {
-{"gettable", {LUA_T_CFUNCTION, {gettableFB}}, 2, 1},
-{"arith", {LUA_T_CFUNCTION, {arithFB}}, 3, 1},
-{"order", {LUA_T_CFUNCTION, {orderFB}}, 3, 1},
-{"concat", {LUA_T_CFUNCTION, {concatFB}}, 2, 1},
-{"settable", {LUA_T_CFUNCTION, {gettableFB}}, 3, 0},
-{"gc", {LUA_T_CFUNCTION, {GDFB}}, 1, 0},
-{"function", {LUA_T_CFUNCTION, {funcFB}}, -1, -1},
-                                /* no fixed number of params or results */
-{"getglobal", {LUA_T_CFUNCTION, {indexFB}}, 1, 1},
-                                /* same default behavior of index FB */
-{"index", {LUA_T_CFUNCTION, {indexFB}}, 2, 1},
-{"error", {LUA_T_CFUNCTION, {errorFB}}, 1, 0}
-};
-
-#define N_FB  (sizeof(luaI_fallBacks)/sizeof(struct FB))
-
-static int luaI_findevent (char *name)
-{
-  int i;
-  for (i=0; i<N_FB; i++)
-    if (strcmp(luaI_fallBacks[i].kind, name) == 0)
-      return i;
-  /* name not found */
-  lua_error("invalid event name");
-  return 0;  /* to avoid warnings */
-}
-
-
-void luaI_setfallback (void)
-{
-  int i;
-  char *name = lua_getstring(lua_getparam(1));
-  lua_Object func = lua_getparam(2);
-  if (name == NULL || !lua_isfunction(func))
-    lua_error("incorrect argument to function `setfallback'");
-  i = luaI_findevent(name);
-  luaI_pushobject(&luaI_fallBacks[i].function);
-  luaI_fallBacks[i].function = *luaI_Address(func);
-}
-
-
-static void errorFB (void)
-{
-  lua_Object o = lua_getparam(1);
-  if (lua_isstring(o))
-    fprintf (stderr, "lua: %s\n", lua_getstring(o));
-  else
-    fprintf(stderr, "lua: unknown error\n");
-}
- 
-
-static void indexFB (void)
-{
-  lua_pushnil();
-}
- 
-
-static void gettableFB (void)
-{
-  lua_error("indexed expression not a table");
-}
- 
-
-static void arithFB (void)
-{
-  lua_error("unexpected type at conversion to number");
-}
-
-static void concatFB (void)
-{
-  lua_error("unexpected type at conversion to string");
-}
-
-
-static void orderFB (void)
-{
-  lua_error("unexpected type at comparison");
-}
-
-static void GDFB (void) { }
-
-static void funcFB (void)
-{
-  lua_error("call expression not a function");
-}
 
 
 
 
 /* -------------------------------------------
 /* -------------------------------------------
@@ -187,50 +89,127 @@ void luaI_invalidaterefs (void)
       refArray[i].status = COLLECTED;
       refArray[i].status = COLLECTED;
 }
 }
 
 
-char *luaI_travfallbacks (int (*fn)(Object *))
+
+/* -------------------------------------------
+* Internal Methods 
+*/
+
+char *eventname[] = {
+  "gettable",  /* IM_GETTABLE */
+  "arith",  /* IM_ARITH */
+  "order",  /* IM_ORDER */
+  "concat",  /* IM_CONCAT */
+  "settable",  /* IM_SETTABLE */
+  "gc",  /* IM_GC */
+  "function",  /* IM_FUNCTION */
+  "index",  /* IM_INDEX */
+  NULL
+};
+
+
+char *geventname[] = {
+  "error",  /* GIM_ERROR */
+  "getglobal",  /* GIM_GETGLOBAL */
+  "setglobal",  /* GIM_SETGLOBAL */
+  NULL
+};
+
+static int luaI_findevent (char *name, char *list[])
 {
 {
   int i;
   int i;
-  for (i=0; i<N_FB; i++)
-    if (fn(&luaI_fallBacks[i].function))
-      return luaI_fallBacks[i].kind;
-  return NULL;
+  for (i=0; list[i]; i++)
+    if (strcmp(list[i], name) == 0)
+      return i;
+  /* name not found */
+  return -1;
 }
 }
 
 
+static int luaI_checkevent (char *name, char *list[])
+{
+  int e = luaI_findevent(name, list);
+  if (e < 0)
+    lua_error("invalid event name");
+  return e;
+}
 
 
-/* -------------------------------------------
-* Internal Methods 
-*/
-#define BASE_TAG 1000
 
 
 static struct IM {
 static struct IM {
   lua_Type tp;
   lua_Type tp;
-  Object int_method[FB_N];
- } *luaI_IMtable = NULL;
+  Object int_method[IM_N];
+} *luaI_IMtable = NULL;
+
 static int IMtable_size = 0;
 static int IMtable_size = 0;
-static int last_tag = BASE_TAG-1;
+static int last_tag = LUA_T_NIL;
+
+static struct {
+  lua_Type t;
+  int event;
+} exceptions[] = {  /* list of events that cannot be modified */
+    {LUA_T_NUMBER, IM_ARITH},
+    {LUA_T_NUMBER, IM_ORDER},
+    {LUA_T_NUMBER, IM_GC},
+    {LUA_T_STRING, IM_ARITH},
+    {LUA_T_STRING, IM_ORDER},
+    {LUA_T_STRING, IM_CONCAT},
+    {LUA_T_STRING, IM_GC},
+    {LUA_T_ARRAY, IM_GETTABLE},
+    {LUA_T_ARRAY, IM_SETTABLE},
+    {LUA_T_FUNCTION, IM_FUNCTION},
+    {LUA_T_FUNCTION, IM_GC},
+    {LUA_T_CFUNCTION, IM_FUNCTION},
+    {LUA_T_CFUNCTION, IM_GC},
+    {LUA_T_NIL, 0}  /* flag end of list */
+};
 
 
-int lua_newtag (char *t)
+
+static int validevent (int t, int event)
+{
+  int i;
+  if (t == LUA_T_NIL)  /* cannot modify any event for nil */
+    return 0;
+  for (i=0; exceptions[i].t != LUA_T_NIL; i++)
+    if (exceptions[i].t == t && exceptions[i].event == event)
+      return 0;
+  return 1;
+}
+
+static void init_entry (int tag)
 {
 {
   int i;
   int i;
-  ++last_tag;
-  if ((last_tag-BASE_TAG) >= IMtable_size)
+  for (i=0; i<IM_N; i++)
+    luaI_IMtable[-tag].int_method[i].ttype = LUA_T_NIL;
+}
+
+void luaI_initfallbacks (void)
+{
+  int i;
+  IMtable_size = NUM_TYPES+10;
+  luaI_IMtable = newvector(IMtable_size, struct IM);
+  for (i=LUA_T_NIL; i<=LUA_T_USERDATA; i++) {
+    luaI_IMtable[-i].tp = (lua_Type)i;
+    init_entry(i);
+  }
+}
+
+int lua_newtag (char *t)
+{
+  --last_tag;
+  if ((-last_tag) >= IMtable_size)
     IMtable_size = growvector(&luaI_IMtable, IMtable_size,
     IMtable_size = growvector(&luaI_IMtable, IMtable_size,
                               struct IM, memEM, MAX_INT);
                               struct IM, memEM, MAX_INT);
   if (strcmp(t, "table") == 0)
   if (strcmp(t, "table") == 0)
-    luaI_IMtable[last_tag-BASE_TAG].tp = LUA_T_ARRAY;
+    luaI_IMtable[-last_tag].tp = LUA_T_ARRAY;
   else if (strcmp(t, "userdata") == 0)
   else if (strcmp(t, "userdata") == 0)
-    luaI_IMtable[last_tag-BASE_TAG].tp = LUA_T_USERDATA;
+    luaI_IMtable[-last_tag].tp = LUA_T_USERDATA;
   else
   else
     lua_error("invalid type for new tag");
     lua_error("invalid type for new tag");
-  for (i=0; i<FB_N; i++)
-    luaI_IMtable[last_tag-BASE_TAG].int_method[i].ttype = LUA_T_NIL;
+  init_entry(last_tag);
   return last_tag;
   return last_tag;
 }
 }
 
 
-static int validtag (int tag)
-{
-  return (BASE_TAG <= tag && tag <= last_tag);
-}
+
+#define validtag(tag)  (last_tag <= (tag) && (tag) <= 0)
+
 
 
 static void checktag (int tag)
 static void checktag (int tag)
 {
 {
@@ -238,10 +217,18 @@ static void checktag (int tag)
     lua_error("invalid tag");
     lua_error("invalid tag");
 }
 }
 
 
+lua_Type luaI_typetag (int tag)
+{
+  if (tag >= 0) return LUA_T_USERDATA;
+  else {
+    checktag(tag);
+    return luaI_IMtable[-tag].tp;
+  }
+}
+
 void luaI_settag (int tag, Object *o)
 void luaI_settag (int tag, Object *o)
 {
 {
-  checktag(tag);
-  if (ttype(o) != luaI_IMtable[tag-BASE_TAG].tp)
+  if (ttype(o) != luaI_typetag(tag))
     lua_error("Tag is not compatible with this type");
     lua_error("Tag is not compatible with this type");
   if (o->ttype == LUA_T_ARRAY)
   if (o->ttype == LUA_T_ARRAY)
     o->value.a->htag = tag;
     o->value.a->htag = tag;
@@ -261,29 +248,123 @@ int luaI_tag (Object *o)
 
 
 Object *luaI_getim (int tag, int event)
 Object *luaI_getim (int tag, int event)
 {
 {
-  if (tag == 0)
-    return &luaI_fallBacks[event].function;
-  else if (validtag(tag)) {
-    Object *func = &luaI_IMtable[tag-BASE_TAG].int_method[event];
-    if (func->ttype == LUA_T_NIL)
-      return NULL;
-    else
-      return func;
-  }
-  else return NULL;
+  if (tag > LUA_T_USERDATA)
+    tag = LUA_T_USERDATA;  /* default for non-registered tags */
+  return &luaI_IMtable[-tag].int_method[event];
+}
+
+Object *luaI_getimbyObj (Object *o, int event)
+{
+  return luaI_getim(luaI_tag(o), event);
 }
 }
 
 
 void luaI_setintmethod (void)
 void luaI_setintmethod (void)
 {
 {
-  lua_Object tag = lua_getparam(1);
-  lua_Object event = lua_getparam(2);
+  int t = (int)luaL_check_number(1, "setintmethod");
+  int e = luaI_checkevent(luaL_check_string(2, "setintmethod"), eventname);
   lua_Object func = lua_getparam(3);
   lua_Object func = lua_getparam(3);
-  if (!(lua_isnumber(tag) && lua_isstring(event) && lua_isfunction(func)))
-    lua_error("incorrect arguments to function `setintmethod'");
-  else {
-    int i = luaI_findevent(lua_getstring(event));
-    int t = lua_getnumber(tag);
-    checktag(t);
-    luaI_IMtable[t-BASE_TAG].int_method[i] = *luaI_Address(func);
+  if (!validevent(t, e))
+    lua_error("cannot change this internal method");
+  luaL_arg_check(lua_isnil(func) || lua_isfunction(func), "setintmethod",
+                 3, "function expected");
+  checktag(t);
+  luaI_IMtable[-t].int_method[e] = *luaI_Address(func);
+}
+
+static Object gmethod[GIM_N] = {
+  {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}
+};
+
+Object *luaI_getgim (int event)
+{
+  return &gmethod[event];
+}
+
+void luaI_setglobalmethod (void)
+{
+  int e = luaI_checkevent(luaL_check_string(1, "setintmethod"), geventname);
+  lua_Object func = lua_getparam(2);
+  luaL_arg_check(lua_isnil(func) || lua_isfunction(func), "setintmethod",
+                 2, "function expected");
+  gmethod[e] = *luaI_Address(func);
+}
+
+char *luaI_travfallbacks (int (*fn)(Object *))
+{ /* ??????????
+  int i;
+  for (i=0; i<N_FB; i++)
+    if (fn(&luaI_fallBacks[i].function))
+      return luaI_fallBacks[i].kind; */
+  return NULL;
+}
+
+
+/*
+* ===================================================================
+* compatibility with old fallback system
+*/
+
+
+static void errorFB (void)
+{
+  lua_Object o = lua_getparam(1);
+  if (lua_isstring(o))
+    fprintf (stderr, "lua: %s\n", lua_getstring(o));
+  else
+    fprintf(stderr, "lua: unknown error\n");
+}
+ 
+
+static void nilFB (void) { }
+ 
+
+static void typeFB (void)
+{
+  lua_error("unexpected type");
+}
+
+
+void luaI_setfallback (void)
+{
+  int e;
+  char *name = luaL_check_string(1, "setfallback");
+  lua_Object func = lua_getparam(2);
+  luaL_arg_check(lua_isfunction(func), "setfallback", 2, "function expected");
+  e = luaI_findevent(name, geventname);
+  if (e >= 0) {  /* global event */
+    switch (e) {
+      case GIM_ERROR:
+        gmethod[e] = *luaI_Address(func);
+        lua_pushcfunction(errorFB);
+        break;
+      case GIM_GETGLOBAL:  /* goes through */
+      case GIM_SETGLOBAL:
+        gmethod[e] = *luaI_Address(func);
+        lua_pushcfunction(nilFB);
+        break;
+      default: lua_error("internal error");
+    }
+  }
+  else {  /* tagged name? */
+    int t;
+    Object oldfunc;
+    e = luaI_checkevent(name, eventname);
+    oldfunc = luaI_IMtable[LUA_T_USERDATA].int_method[e];
+    for (t=LUA_T_NIL; t<=LUA_T_USERDATA; t++)
+      if (validevent(t, e))
+        luaI_IMtable[-t].int_method[e] = *luaI_Address(func);
+    if (oldfunc.ttype != LUA_T_NIL)
+      luaI_pushobject(&oldfunc);
+    else {
+      switch (e) {
+       case IM_GC:  case IM_INDEX:
+         lua_pushcfunction(nilFB);
+         break;
+       default:
+         lua_pushcfunction(typeFB);
+         break;
+      }
+    }
   }
   }
 }
 }
+ 

+ 19 - 18
fallback.h

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: fallback.h,v 1.13 1996/04/25 14:10:00 roberto Exp roberto $
+** $Id: fallback.h,v 1.14 1997/02/26 17:38:41 roberto Unstable roberto $
 */
 */
  
  
 #ifndef fallback_h
 #ifndef fallback_h
@@ -8,24 +8,20 @@
 #include "lua.h"
 #include "lua.h"
 #include "opcode.h"
 #include "opcode.h"
 
 
-extern struct FB {
-  char *kind;
-  Object function;
-  int nParams;
-  int nResults;
-} luaI_fallBacks[];
+#define IM_GETTABLE  0
+#define IM_ARITH  1
+#define IM_ORDER  2
+#define IM_CONCAT  3
+#define IM_SETTABLE  4
+#define IM_GC 5
+#define IM_FUNCTION 6
+#define IM_INDEX  7
+#define IM_N 8
 
 
-#define FB_GETTABLE  0
-#define FB_ARITH  1
-#define FB_ORDER  2
-#define FB_CONCAT  3
-#define FB_SETTABLE  4
-#define FB_GC 5
-#define FB_FUNCTION 6
-#define FB_GETGLOBAL 7
-#define FB_INDEX  8
-#define FB_ERROR  9
-#define FB_N 10
+#define GIM_ERROR 0
+#define GIM_GETGLOBAL 1
+#define GIM_SETGLOBAL 2
+#define GIM_N 3
 
 
 void luaI_setfallback (void);
 void luaI_setfallback (void);
 int luaI_ref (Object *object, int lock);
 int luaI_ref (Object *object, int lock);
@@ -35,9 +31,14 @@ void luaI_invalidaterefs (void);
 char *luaI_travfallbacks (int (*fn)(Object *));
 char *luaI_travfallbacks (int (*fn)(Object *));
 
 
 void luaI_settag (int tag, Object *o);
 void luaI_settag (int tag, Object *o);
+lua_Type luaI_typetag (int tag);
 Object *luaI_getim (int tag, int event);
 Object *luaI_getim (int tag, int event);
+Object *luaI_getgim (int event);
+Object *luaI_getimbyObj (Object *o, int event);
 int luaI_tag (Object *o);
 int luaI_tag (Object *o);
 void luaI_setintmethod (void);
 void luaI_setintmethod (void);
+void luaI_setglobalmethod (void);
+void luaI_initfallbacks (void);
 
 
 #endif
 #endif
 
 

+ 4 - 5
hash.c

@@ -3,7 +3,7 @@
 ** hash manager for lua
 ** hash manager for lua
 */
 */
 
 
-char *rcs_hash="$Id: hash.c,v 2.34 1997/02/26 17:38:41 roberto Unstable roberto $";
+char *rcs_hash="$Id: hash.c,v 2.35 1997/03/11 18:44:28 roberto Exp roberto $";
 
 
 
 
 #include "mem.h"
 #include "mem.h"
@@ -159,7 +159,7 @@ void lua_hashmark (Hash *h)
 }
 }
 
 
 
 
-static void call_fallbacks (void)
+void luaI_hashcallIM (void)
 {
 {
   Hash *curr_array;
   Hash *curr_array;
   Object t;
   Object t;
@@ -168,10 +168,10 @@ static void call_fallbacks (void)
     if (markarray(curr_array) != 1)
     if (markarray(curr_array) != 1)
     {
     {
       avalue(&t) = curr_array;
       avalue(&t) = curr_array;
-      luaI_gcFB(&t);
+      luaI_gcIM(&t);
     }
     }
   ttype(&t) = LUA_T_NIL;
   ttype(&t) = LUA_T_NIL;
-  luaI_gcFB(&t);  /* end of list */
+  luaI_gcIM(&t);  /* end of list */
 }
 }
 
 
  
  
@@ -183,7 +183,6 @@ Long lua_hashcollector (void)
 {
 {
  Hash *curr_array = listhead, *prev = NULL;
  Hash *curr_array = listhead, *prev = NULL;
  Long counter = 0;
  Long counter = 0;
- call_fallbacks();
  while (curr_array != NULL)
  while (curr_array != NULL)
  {
  {
   Hash *next = curr_array->next;
   Hash *next = curr_array->next;

+ 2 - 1
hash.h

@@ -1,7 +1,7 @@
 /*
 /*
 ** hash.h
 ** hash.h
 ** hash manager for lua
 ** hash manager for lua
-** $Id: hash.h,v 2.12 1996/05/06 14:30:27 roberto Exp roberto $
+** $Id: hash.h,v 2.13 1997/02/26 17:38:41 roberto Unstable roberto $
 */
 */
 
 
 #ifndef hash_h
 #ifndef hash_h
@@ -30,6 +30,7 @@ int      luaI_redimension (int nhash);
 Hash    *lua_createarray (int nhash);
 Hash    *lua_createarray (int nhash);
 void     lua_hashmark (Hash *h);
 void     lua_hashmark (Hash *h);
 Long     lua_hashcollector (void);
 Long     lua_hashcollector (void);
+void	 luaI_hashcallIM (void);
 Object  *lua_hashget (Hash *t, Object *ref);
 Object  *lua_hashget (Hash *t, Object *ref);
 Object 	*lua_hashdefine (Hash *t, Object *ref);
 Object 	*lua_hashdefine (Hash *t, Object *ref);
 void     lua_next (void);
 void     lua_next (void);

+ 3 - 1
inout.c

@@ -5,11 +5,12 @@
 ** Also provides some predefined lua functions.
 ** Also provides some predefined lua functions.
 */
 */
 
 
-char *rcs_inout="$Id: inout.c,v 2.45 1997/03/11 18:44:28 roberto Exp roberto $";
+char *rcs_inout="$Id: inout.c,v 2.46 1997/03/17 17:01:10 roberto Exp roberto $";
 
 
 #include <stdio.h>
 #include <stdio.h>
 #include <string.h>
 #include <string.h>
 
 
+#include "auxlib.h"
 #include "lex.h"
 #include "lex.h"
 #include "opcode.h"
 #include "opcode.h"
 #include "inout.h"
 #include "inout.h"
@@ -322,6 +323,7 @@ static struct {
   {"print", luaI_print},
   {"print", luaI_print},
   {"setfallback", luaI_setfallback},
   {"setfallback", luaI_setfallback},
   {"setintmethod", luaI_setintmethod},
   {"setintmethod", luaI_setintmethod},
+  {"setglobalmethod", luaI_setglobalmethod},
   {"setglobal", luaI_setglobal},
   {"setglobal", luaI_setglobal},
   {"tonumber", lua_obj2number},
   {"tonumber", lua_obj2number},
   {"tostring", luaI_tostring},
   {"tostring", luaI_tostring},

+ 7 - 13
lua.h

@@ -2,7 +2,7 @@
 ** LUA - Linguagem para Usuarios de Aplicacao
 ** LUA - Linguagem para Usuarios de Aplicacao
 ** Grupo de Tecnologia em Computacao Grafica
 ** Grupo de Tecnologia em Computacao Grafica
 ** TeCGraf - PUC-Rio
 ** TeCGraf - PUC-Rio
-** $Id: lua.h,v 3.35 1997/02/26 17:38:41 roberto Unstable roberto $
+** $Id: lua.h,v 3.36 1997/03/17 17:01:10 roberto Exp roberto $
 */
 */
 
 
 
 
@@ -21,6 +21,7 @@ typedef unsigned int lua_Object;
 
 
 lua_Object     lua_setfallback		(char *event, lua_CFunction fallback);
 lua_Object     lua_setfallback		(char *event, lua_CFunction fallback);
 void           lua_setintmethod	(int tag, char *event, lua_CFunction method);
 void           lua_setintmethod	(int tag, char *event, lua_CFunction method);
+void           lua_setglobalmethod (char *event, lua_CFunction method);
 
 
 int            lua_newtag		(char *t);
 int            lua_newtag		(char *t);
 void           lua_settag		(int tag); /* In: object */
 void           lua_settag		(int tag); /* In: object */
@@ -36,8 +37,9 @@ int	       lua_call			(char *funcname);
 void	       lua_beginblock		(void);
 void	       lua_beginblock		(void);
 void	       lua_endblock		(void);
 void	       lua_endblock		(void);
 
 
-lua_Object     lua_getparam 		(int number);
-#define	       lua_getresult(_)		lua_getparam(_)
+lua_Object     lua_lua2C 		(int number);
+#define	       lua_getparam(_)		lua_lua2C(_)
+#define	       lua_getresult(_)		lua_lua2C(_)
 
 
 int            lua_isnil                (lua_Object object);
 int            lua_isnil                (lua_Object object);
 int            lua_istable              (lua_Object object);
 int            lua_istable              (lua_Object object);
@@ -62,7 +64,9 @@ void           lua_pushusertag     	(void *u, int tag);
 void           lua_pushobject       	(lua_Object object);
 void           lua_pushobject       	(lua_Object object);
 
 
 lua_Object     lua_getglobal 		(char *name);
 lua_Object     lua_getglobal 		(char *name);
+lua_Object     lua_basicgetglobal	(char *name);
 void           lua_storeglobal		(char *name); /* In: value */
 void           lua_storeglobal		(char *name); /* In: value */
+void           lua_basicstoreglobal	(char *name); /* In: value */
 
 
 void           lua_storesubscript	(void); /* In: table, index, value */
 void           lua_storesubscript	(void); /* In: table, index, value */
 void           lua_basicstoreindex	(void); /* In: table, index, value */
 void           lua_basicstoreindex	(void); /* In: table, index, value */
@@ -90,16 +94,6 @@ lua_Object     lua_createtable		(void);
 #define lua_pushuserdata(u)     lua_pushusertag(u, 0)
 #define lua_pushuserdata(u)     lua_pushusertag(u, 0)
 
 
 
 
-/* =============================================================== */
-/* Auxiliar functions for libraries */
-
-void luaL_arg_check(int cond, char *funcname, int numarg, char *extramsg);
-char *luaL_check_string (int numArg, char *funcname);
-char *luaL_opt_string (int numArg, char *def, char *funcname);
-double luaL_check_number (int numArg, char *funcname);
-double luaL_opt_number (int numArg, double def, char *funcname);
-
-
 /* =============================================================== */
 /* =============================================================== */
 /* for compatibility with old versions. Avoid using these macros */
 /* for compatibility with old versions. Avoid using these macros */
 
 

+ 105 - 56
opcode.c

@@ -3,7 +3,7 @@
 ** TecCGraf - PUC-Rio
 ** TecCGraf - PUC-Rio
 */
 */
 
 
-char *rcs_opcode="$Id: opcode.c,v 3.83 1997/03/06 17:30:55 roberto Exp roberto $";
+char *rcs_opcode="$Id: opcode.c,v 3.84 1997/03/11 18:44:28 roberto Exp roberto $";
 
 
 #include <setjmp.h>
 #include <setjmp.h>
 #include <stdio.h>
 #include <stdio.h>
@@ -268,15 +268,6 @@ static void callIM (Object *f, int nParams, int nResults)
   do_call((top-stack)-nParams, nResults);
   do_call((top-stack)-nParams, nResults);
 }
 }
 
 
-/*
-** Call the specified fallback, putting it on the stack below its arguments
-*/
-static void callFB (int fb)
-{
-  callIM(&luaI_fallBacks[fb].function, luaI_fallBacks[fb].nParams,
-         luaI_fallBacks[fb].nResults);
-}
-
 
 
 /*
 /*
 ** Call a function (C or Lua). The parameters must be on the stack,
 ** Call a function (C or Lua). The parameters must be on the stack,
@@ -289,21 +280,21 @@ static void do_call (StkId base, int nResults)
   StkId firstResult;
   StkId firstResult;
   Object *func = stack+base-1;
   Object *func = stack+base-1;
   int i;
   int i;
-  if (ttype(func) == LUA_T_CFUNCTION)
-  {
+  if (ttype(func) == LUA_T_CFUNCTION) {
     ttype(func) = LUA_T_CMARK;
     ttype(func) = LUA_T_CMARK;
     firstResult = callC(fvalue(func), base);
     firstResult = callC(fvalue(func), base);
   }
   }
-  else if (ttype(func) == LUA_T_FUNCTION)
-  {
+  else if (ttype(func) == LUA_T_FUNCTION) {
     ttype(func) = LUA_T_MARK;
     ttype(func) = LUA_T_MARK;
     firstResult = lua_execute(func->value.tf->code, base);
     firstResult = lua_execute(func->value.tf->code, base);
   }
   }
-  else
-  { /* func is not a function */
-    /* Call the fallback for invalid functions */
+  else { /* func is not a function */
+    /* Check the fallback for invalid functions */
+    Object *im = luaI_getimbyObj(func, IM_FUNCTION);
+    if (ttype(im) == LUA_T_NIL)
+      lua_error("call expression not a function");
     open_stack((top-stack)-(base-1));
     open_stack((top-stack)-(base-1));
-    stack[base-1] = luaI_fallBacks[FB_FUNCTION].function;
+    stack[base-1] = *im;
     do_call(base, nResults);
     do_call(base, nResults);
     return;
     return;
   }
   }
@@ -326,15 +317,14 @@ static void do_call (StkId base, int nResults)
 static void pushsubscript (void)
 static void pushsubscript (void)
 {
 {
   int tg = luaI_tag(top-2);
   int tg = luaI_tag(top-2);
-  Object *im = luaI_getim(tg, FB_GETTABLE);
-  if (ttype(top-2) == LUA_T_ARRAY && im == NULL) {
+  Object *im = luaI_getim(tg, IM_GETTABLE);
+  if (ttype(top-2) == LUA_T_ARRAY && ttype(im) == LUA_T_NIL) {
       Object *h = lua_hashget(avalue(top-2), top-1);
       Object *h = lua_hashget(avalue(top-2), top-1);
       if (h != NULL && ttype(h) != LUA_T_NIL) {
       if (h != NULL && ttype(h) != LUA_T_NIL) {
         --top;
         --top;
         *(top-1) = *h;
         *(top-1) = *h;
       }
       }
-      else if (tg == LUA_T_ARRAY &&
-              (im=luaI_getim(0, FB_INDEX)) != NULL)
+      else if (ttype(im=luaI_getim(tg, IM_INDEX)) != LUA_T_NIL)
         callIM(im, 2, 1);
         callIM(im, 2, 1);
       else {
       else {
         --top;
         --top;
@@ -376,14 +366,14 @@ lua_Object lua_basicindex (void)
 */
 */
 static void storesubscript (Object *t, int mode)
 static void storesubscript (Object *t, int mode)
 {
 {
-  Object *im = (mode == 0) ? NULL : luaI_getim(luaI_tag(t), FB_SETTABLE);
-  if (ttype(t) == LUA_T_ARRAY && im == NULL) {
+  Object *im = (mode == 0) ? NULL : luaI_getimbyObj(t, IM_SETTABLE);
+  if (ttype(t) == LUA_T_ARRAY && (im == NULL || ttype(im) == LUA_T_NIL)) {
     Object *h = lua_hashdefine(avalue(t), t+1);
     Object *h = lua_hashdefine(avalue(t), t+1);
     *h = *(top-1);
     *h = *(top-1);
     top -= (mode == 2) ? 1 : 3;
     top -= (mode == 2) ? 1 : 3;
   }
   }
   else {  /* object is not a table, and/or has a specific "settable" method */
   else {  /* object is not a table, and/or has a specific "settable" method */
-    if (im) {
+    if (im && ttype(im) != LUA_T_NIL) {
       if (mode == 2) {
       if (mode == 2) {
         lua_checkstack(top+2);
         lua_checkstack(top+2);
         *(top+1) = *(top-1);
         *(top+1) = *(top-1);
@@ -403,11 +393,13 @@ static void getglobal (Word n)
 {
 {
   *top = lua_table[n].object;
   *top = lua_table[n].object;
   incr_top;
   incr_top;
-  if (ttype(top-1) == LUA_T_NIL)
-  { /* must call getglobal fallback */
-    ttype(top-1) = LUA_T_STRING;
-    tsvalue(top-1) = lua_table[n].varname;
-    callFB(FB_GETGLOBAL);
+  if (ttype(top-1) == LUA_T_NIL) {  /* check i.m. */
+    Object *im = luaI_getgim(GIM_GETGLOBAL);
+    if (ttype(im) != LUA_T_NIL) {
+      ttype(top-1) = LUA_T_STRING;
+      tsvalue(top-1) = lua_table[n].varname;
+      callIM(im, 1, 1);
+    }
   }
   }
 }
 }
 
 
@@ -428,8 +420,13 @@ void lua_travstack (int (*fn)(Object *))
 
 
 static void lua_message (char *s)
 static void lua_message (char *s)
 {
 {
-  lua_pushstring(s);
-  callFB(FB_ERROR);
+  Object *im = luaI_getgim(GIM_ERROR);
+  if (ttype(im) == LUA_T_NIL)
+    fprintf(stderr, "lua: %s\n", s);
+  else {
+    lua_pushstring(s);
+    callIM(im, 1, 0);
+  }
 }
 }
 
 
 /*
 /*
@@ -659,10 +656,20 @@ void lua_setintmethod (int tag, char *event, lua_CFunction method)
 {
 {
   lua_pushnumber(tag);
   lua_pushnumber(tag);
   lua_pushstring(event);
   lua_pushstring(event);
-  lua_pushcfunction (method);
+  if (method)
+    lua_pushcfunction (method);
+  else
+    lua_pushnil();
   do_unprotectedrun(luaI_setintmethod, 3, 0);
   do_unprotectedrun(luaI_setintmethod, 3, 0);
 }
 }
 
 
+void lua_setglobalmethod (char *event, lua_CFunction method)
+{
+  lua_pushstring(event);
+  lua_pushcfunction (method);
+  do_unprotectedrun(luaI_setglobalmethod, 3, 0);
+}
+
 
 
 /* 
 /* 
 ** API: receives on the stack the table and the index.
 ** API: receives on the stack the table and the index.
@@ -741,7 +748,7 @@ lua_Object lua_createtable (void)
 ** Get a parameter, returning the object handle or LUA_NOOBJECT on error.
 ** Get a parameter, returning the object handle or LUA_NOOBJECT on error.
 ** 'number' must be 1 to get the first parameter.
 ** 'number' must be 1 to get the first parameter.
 */
 */
-lua_Object lua_getparam (int number)
+lua_Object lua_lua2C (int number)
 {
 {
  if (number <= 0 || number > CLS_current.num) return LUA_NOOBJECT;
  if (number <= 0 || number > CLS_current.num) return LUA_NOOBJECT;
  /* Ref(stack+(CLS_current.base-CLS_current.num+number-1)) ==
  /* Ref(stack+(CLS_current.base-CLS_current.num+number-1)) ==
@@ -874,6 +881,17 @@ lua_Object lua_getglobal (char *name)
  return Ref(top-1);
  return Ref(top-1);
 }
 }
 
 
+
+lua_Object lua_basicgetglobal (char *name)
+{
+  adjustC(0);
+  *top = lua_table[luaI_findsymbolbyname(name)].object;
+  incr_top;
+  CLS_current.base++;  /* incorporate object in the stack */
+  return Ref(top-1);
+}
+
+
 /*
 /*
 ** Store top of the stack at a global variable array field.
 ** Store top of the stack at a global variable array field.
 */
 */
@@ -944,7 +962,7 @@ void lua_pushbinarydata (void *buff, int size, int tag)
 */
 */
 void lua_pushusertag (void *u, int tag)
 void lua_pushusertag (void *u, int tag)
 {
 {
-  if (tag < LUA_T_USERDATA) 
+  if (luaI_typetag(tag) != LUA_T_USERDATA)
     lua_error("invalid tag in `lua_pushusertag'");
     lua_error("invalid tag in `lua_pushusertag'");
   lua_pushbinarydata(&u, sizeof(void *), tag);
   lua_pushbinarydata(&u, sizeof(void *), tag);
 }
 }
@@ -977,18 +995,47 @@ int lua_tag (lua_Object o)
 }
 }
 
 
 
 
-void luaI_gcFB (Object *o)
+void luaI_gcIM (Object *o)
 {
 {
-  *top = *o;
-  incr_top;
-  callFB(FB_GC);
+  Object *im = luaI_getimbyObj(o, IM_GC);
+  if (ttype(im) != LUA_T_NIL) {
+    *top = *o;
+    incr_top;
+    callIM(im, 1, 0);
+  }
 }
 }
 
 
 
 
 static void call_arith (char *op)
 static void call_arith (char *op)
 {
 {
+  Object *im = luaI_getimbyObj(top-2, IM_ARITH);  /* try first operand */
+  if (ttype(im) == LUA_T_NIL) {
+    im = luaI_getimbyObj(top-1, IM_ARITH);  /* try second operand */
+    if (ttype(im) == LUA_T_NIL) {
+      im = luaI_getim(0, IM_ARITH);  /* try a 'global' i.m. */
+      if (ttype(im) == LUA_T_NIL)
+        lua_error("unexpected type at conversion to number");
+    }
+  }
   lua_pushstring(op);
   lua_pushstring(op);
-  callFB(FB_ARITH);
+  callIM(im, 3, 1);
+}
+
+static void concim (Object *o)
+{
+  Object *im = luaI_getimbyObj(o, IM_CONCAT);
+  if (ttype(im) == LUA_T_NIL)
+    lua_error("unexpected type at conversion to string");
+  callIM(im, 2, 1);
+}
+
+static void ordim (Object *o, char *op)
+{
+  Object *im = luaI_getimbyObj(o, IM_ORDER);
+  if (ttype(im) == LUA_T_NIL)
+    lua_error("unexpected type at comparison");
+  lua_pushstring(op);
+  callIM(im, 3, 1);
 }
 }
 
 
 static void comparison (lua_Type ttype_less, lua_Type ttype_equal, 
 static void comparison (lua_Type ttype_less, lua_Type ttype_equal, 
@@ -999,10 +1046,12 @@ static void comparison (lua_Type ttype_less, lua_Type ttype_equal,
   int result;
   int result;
   if (ttype(l) == LUA_T_NUMBER && ttype(r) == LUA_T_NUMBER)
   if (ttype(l) == LUA_T_NUMBER && ttype(r) == LUA_T_NUMBER)
     result = (nvalue(l) < nvalue(r)) ? -1 : (nvalue(l) == nvalue(r)) ? 0 : 1;
     result = (nvalue(l) < nvalue(r)) ? -1 : (nvalue(l) == nvalue(r)) ? 0 : 1;
-  else if (tostring(l) || tostring(r))
-  {
-    lua_pushstring(op);
-    callFB(FB_ORDER);
+  else if (tostring(l)) {
+    ordim(l, op);
+    return;
+  }
+  else if (tostring(r)) {
+    ordim(r, op);
     return;
     return;
   }
   }
   else
   else
@@ -1318,17 +1367,17 @@ static StkId lua_execute (Byte *pc, StkId base)
     call_arith("pow");
     call_arith("pow");
     break;
     break;
 
 
-   case CONCOP:
-   {
-    Object *l = top-2;
-    Object *r = top-1;
-    if (tostring(r) || tostring(l))
-      callFB(FB_CONCAT);
-    else
-    {
-      tsvalue(l) = lua_createstring (lua_strconc(svalue(l),svalue(r)));
-      --top;
-    }
+   case CONCOP: {
+     Object *l = top-2;
+     Object *r = top-1;
+     if (tostring(l))  /* first argument is not a string */
+       concim(l);
+     else if (tostring(r))  /* second argument is not a string */
+       concim(r);
+     else {
+       tsvalue(l) = lua_createstring(lua_strconc(svalue(l),svalue(r)));
+       --top;
+     }
    }
    }
    break;
    break;
 
 
@@ -1356,7 +1405,7 @@ static StkId lua_execute (Byte *pc, StkId base)
    }
    }
    break;
    break;
 
 
-   case ONFJMP:	
+   case ONFJMP:
    {
    {
     Word w;
     Word w;
     get_word(w,pc);
     get_word(w,pc);

+ 12 - 10
opcode.h

@@ -1,6 +1,6 @@
 /*
 /*
 ** TeCGraf - PUC-Rio
 ** TeCGraf - PUC-Rio
-** $Id: opcode.h,v 3.27 1997/03/06 17:30:55 roberto Exp roberto $
+** $Id: opcode.h,v 3.28 1997/03/11 18:44:28 roberto Exp roberto $
 */
 */
 
 
 #ifndef opcode_h
 #ifndef opcode_h
@@ -16,18 +16,20 @@
 
 
 typedef enum
 typedef enum
 {
 {
- LUA_T_NIL      = -1,
- LUA_T_NUMBER   = -2,
- LUA_T_STRING   = -3,
- LUA_T_ARRAY    = -4,  /* array==table */
+ LUA_T_NIL      = -9,
+ LUA_T_NUMBER   = -8,
+ LUA_T_STRING   = -7,
+ LUA_T_ARRAY    = -6,  /* array==table */
  LUA_T_FUNCTION = -5,
  LUA_T_FUNCTION = -5,
- LUA_T_CFUNCTION= -6,
- LUA_T_MARK     = -7,
- LUA_T_CMARK    = -8,
- LUA_T_LINE     = -9,
+ LUA_T_CFUNCTION= -4,
+ LUA_T_MARK     = -3,
+ LUA_T_CMARK    = -2,
+ LUA_T_LINE     = -1,
  LUA_T_USERDATA = 0
  LUA_T_USERDATA = 0
 } lua_Type;
 } lua_Type;
 
 
+#define NUM_TYPES 10
+
 
 
 typedef enum {
 typedef enum {
 /* name          parm    before          after           side effect
 /* name          parm    before          after           side effect
@@ -156,7 +158,7 @@ void	luaI_codedebugline (int line);  /* from "lua.stx" module */
 void    lua_travstack (int (*fn)(Object *));
 void    lua_travstack (int (*fn)(Object *));
 Object *luaI_Address (lua_Object o);
 Object *luaI_Address (lua_Object o);
 void	luaI_pushobject (Object *o);
 void	luaI_pushobject (Object *o);
-void    luaI_gcFB       (Object *o);
+void    luaI_gcIM       (Object *o);
 int     luaI_dorun (TFunc *tf);
 int     luaI_dorun (TFunc *tf);
 
 
 #endif
 #endif

+ 3 - 1
table.c

@@ -3,7 +3,7 @@
 ** Module to control static tables
 ** Module to control static tables
 */
 */
 
 
-char *rcs_table="$Id: table.c,v 2.59 1997/02/26 17:38:41 roberto Unstable roberto $";
+char *rcs_table="$Id: table.c,v 2.60 1997/03/11 18:44:28 roberto Exp roberto $";
 
 
 #include "mem.h"
 #include "mem.h"
 #include "opcode.h"
 #include "opcode.h"
@@ -168,6 +168,8 @@ Long luaI_collectgarbage (void)
   lua_travsymbol(lua_markobject); /* mark symbol table objects */
   lua_travsymbol(lua_markobject); /* mark symbol table objects */
   luaI_travlock(lua_markobject); /* mark locked objects */
   luaI_travlock(lua_markobject); /* mark locked objects */
   luaI_travfallbacks(lua_markobject);  /* mark fallbacks */
   luaI_travfallbacks(lua_markobject);  /* mark fallbacks */
+  luaI_hashcallIM();
+  luaI_strcallIM();
   luaI_invalidaterefs();
   luaI_invalidaterefs();
   recovered += lua_strcollector();
   recovered += lua_strcollector();
   recovered += lua_hashcollector();
   recovered += lua_hashcollector();

+ 22 - 1
tree.c

@@ -3,7 +3,7 @@
 ** TecCGraf - PUC-Rio
 ** TecCGraf - PUC-Rio
 */
 */
  
  
-char *rcs_tree="$Id: tree.c,v 1.20 1996/03/14 15:56:26 roberto Exp roberto $";
+char *rcs_tree="$Id: tree.c,v 1.21 1997/02/11 11:35:05 roberto Exp roberto $";
 
 
 
 
 #include <string.h>
 #include <string.h>
@@ -14,6 +14,7 @@ char *rcs_tree="$Id: tree.c,v 1.20 1996/03/14 15:56:26 roberto Exp roberto $";
 #include "lex.h"
 #include "lex.h"
 #include "hash.h"
 #include "hash.h"
 #include "table.h"
 #include "table.h"
+#include "fallback.h"
 
 
 
 
 #define NUM_HASHS  64
 #define NUM_HASHS  64
@@ -45,6 +46,7 @@ static void initialize (void)
   luaI_addReserved();
   luaI_addReserved();
   luaI_initsymbol();
   luaI_initsymbol();
   luaI_initconstant();
   luaI_initconstant();
+  luaI_initfallbacks();
 }
 }
 
 
 
 
@@ -120,6 +122,25 @@ TaggedString *lua_createstring (char *str)
 }
 }
 
 
 
 
+void luaI_strcallIM (void)
+{
+  int i;
+  Object o;
+  ttype(&o) = LUA_T_USERDATA;
+  for (i=0; i<NUM_HASHS; i++) {
+    stringtable *tb = &string_root[i];
+    int j;
+    for (j=0; j<tb->size; j++) {
+      TaggedString *t = tb->hash[j];
+      if (t != NULL && t->tag != LUA_T_STRING && t->marked == 0) {
+        tsvalue(&o) = t;
+        luaI_gcIM(&o);
+      }
+    }
+  }
+}
+
+
 /*
 /*
 ** Garbage collection function.
 ** Garbage collection function.
 ** This function traverse the string list freeing unindexed strings
 ** This function traverse the string list freeing unindexed strings

+ 2 - 1
tree.h

@@ -1,7 +1,7 @@
 /*
 /*
 ** tree.h
 ** tree.h
 ** TecCGraf - PUC-Rio
 ** TecCGraf - PUC-Rio
-** $Id: tree.h,v 1.14 1996/02/26 17:07:49 roberto Exp roberto $
+** $Id: tree.h,v 1.15 1997/02/11 11:35:05 roberto Exp roberto $
 */
 */
 
 
 #ifndef tree_h
 #ifndef tree_h
@@ -27,5 +27,6 @@ typedef struct TaggedString
 TaggedString *lua_createstring (char *str);
 TaggedString *lua_createstring (char *str);
 TaggedString *luaI_createuserdata (char *buff, long size, int tag);
 TaggedString *luaI_createuserdata (char *buff, long size, int tag);
 Long lua_strcollector (void);
 Long lua_strcollector (void);
+void luaI_strcallIM (void);
 
 
 #endif
 #endif