i.m. "arith" and "order" splited for different operations

This commit is contained in:
Roberto Ierusalimschy
1997-03-20 16:20:43 -03:00
parent 88d7ffb0d0
commit 5d60470508
4 changed files with 150 additions and 121 deletions

View File

@@ -3,7 +3,7 @@
** TecCGraf - PUC-Rio
*/
char *rcs_fallback="$Id: fallback.c,v 1.28 1997/03/19 19:41:10 roberto Exp roberto $";
char *rcs_fallback="$Id: fallback.c,v 1.29 1997/03/19 21:12:34 roberto Exp roberto $";
#include <stdio.h>
#include <string.h>
@@ -18,6 +18,19 @@ char *rcs_fallback="$Id: fallback.c,v 1.28 1997/03/19 19:41:10 roberto Exp rober
#include "hash.h"
static char *typenames[] = { /* ORDER LUA_T */
"userdata", "line", "cmark", "mark", "function",
"function", "table", "string", "number", "nil",
NULL
};
void luaI_type (void)
{
lua_Object o = lua_getparam(1);
lua_pushstring(typenames[-ttype(luaI_Address(o))]);
lua_pushnumber(lua_tag(o));
}
/* -------------------------------------------
@@ -94,27 +107,19 @@ void luaI_invalidaterefs (void)
* 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 */
char *luaI_eventname[] = { /* ORDER IM */
"gettable", "settable", "index", "add", "sub", "mul", "div",
"pow", "unm", "lt", "le", "gt", "ge", "concat", "gc", "function",
NULL
};
char *geventname[] = {
"error", /* GIM_ERROR */
"getglobal", /* GIM_GETGLOBAL */
"setglobal", /* GIM_SETGLOBAL */
static char *geventname[] = { /* ORDER GIM */
"error", "getglobal", "setglobal",
NULL
};
static int luaI_findevent (char *name, char *list[])
static int findstring (char *name, char *list[])
{
int i;
for (i=0; list[i]; i++)
@@ -126,7 +131,7 @@ static int luaI_findevent (char *name, char *list[])
static int luaI_checkevent (char *name, char *list[])
{
int e = luaI_findevent(name, list);
int e = findstring(name, list);
if (e < 0)
lua_error("invalid event name");
return e;
@@ -141,38 +146,25 @@ static struct IM {
static int IMtable_size = 0;
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 */
static char validevents[NUM_TYPES][IM_N] = { /* ORDER LUA_T, ORDER IM */
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* LUA_T_USERDATA */
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* LUA_T_LINE */
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* LUA_T_CMARK */
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* LUA_T_MARK */
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, /* LUA_T_CFUNCTION */
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, /* LUA_T_FUNCTION */
{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* LUA_T_ARRAY */
{1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_T_STRING */
{1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1}, /* LUA_T_NUMBER */
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0} /* LUA_T_NIL */
};
static int validevent (int t, int event)
static int validevent (lua_Type t, int e)
{
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;
return (t < LUA_T_NIL) ? 1 : validevents[-t][e];
}
static void init_entry (int tag)
{
int i;
@@ -193,14 +185,14 @@ void luaI_initfallbacks (void)
int lua_newtag (char *t)
{
int tp;
--last_tag;
if ((-last_tag) >= IMtable_size)
IMtable_size = growvector(&luaI_IMtable, IMtable_size,
struct IM, memEM, MAX_INT);
if (strcmp(t, "table") == 0)
luaI_IMtable[-last_tag].tp = LUA_T_ARRAY;
else if (strcmp(t, "userdata") == 0)
luaI_IMtable[-last_tag].tp = LUA_T_USERDATA;
tp = -findstring(t, typenames);
if (tp == LUA_T_ARRAY || tp == LUA_T_USERDATA)
luaI_IMtable[-last_tag].tp = tp;
else
lua_error("invalid type for new tag");
init_entry(last_tag);
@@ -246,14 +238,14 @@ int luaI_tag (Object *o)
else return t;
}
Object *luaI_getim (int tag, int event)
Object *luaI_getim (int tag, IMS event)
{
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)
Object *luaI_getimbyObj (Object *o, IMS event)
{
return luaI_getim(luaI_tag(o), event);
}
@@ -261,13 +253,13 @@ Object *luaI_getimbyObj (Object *o, int event)
void luaI_setintmethod (void)
{
int t = (int)luaL_check_number(1, "setintmethod");
int e = luaI_checkevent(luaL_check_string(2, "setintmethod"), eventname);
int e = luaI_checkevent(luaL_check_string(2, "setintmethod"), luaI_eventname);
lua_Object func = lua_getparam(3);
checktag(t);
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_pushobject(&luaI_IMtable[-t].int_method[e]);
luaI_IMtable[-t].int_method[e] = *luaI_Address(func);
}
@@ -276,7 +268,7 @@ static Object gmethod[GIM_N] = {
{LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}
};
Object *luaI_getgim (int event)
Object *luaI_getgim (IMGS event)
{
return &gmethod[event];
}
@@ -326,47 +318,54 @@ static void typeFB (void)
}
static void fillvalids (IMS e, Object *func)
{
int t;
for (t=LUA_T_NIL; t<=LUA_T_USERDATA; t++)
if (validevent(t, e))
luaI_IMtable[-t].int_method[e] = *func;
}
void luaI_setfallback (void)
{
int e;
Object oldfunc;
lua_CFunction replace;
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);
e = findstring(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");
}
oldfunc = gmethod[e];
gmethod[e] = *luaI_Address(func);
replace = (e == GIM_ERROR) ? errorFB : nilFB;
}
else { /* tagged name? */
int t;
Object oldfunc;
e = luaI_checkevent(name, eventname);
else if ((e = findstring(name, luaI_eventname)) >= 0) {
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;
}
}
fillvalids(e, luaI_Address(func));
replace = (e == IM_GC || e == IM_INDEX) ? nilFB : typeFB;
}
else if (strcmp(name, "arith") == 0) { /* old arith fallback */
int i;
oldfunc = luaI_IMtable[LUA_T_USERDATA].int_method[IM_ADD];
for (i=IM_ADD; i<=IM_UNM; i++) /* ORDER IM */
fillvalids(i, luaI_Address(func));
replace = typeFB;
}
else if (strcmp(name, "order") == 0) { /* old order fallback */
int i;
oldfunc = luaI_IMtable[LUA_T_USERDATA].int_method[IM_LT];
for (i=IM_LT; i<=IM_GE; i++) /* ORDER IM */
fillvalids(i, luaI_Address(func));
replace = typeFB;
}
else {
lua_error("invalid fallback name");
replace = NULL; /* to avoid warnings */
}
if (oldfunc.ttype != LUA_T_NIL)
luaI_pushobject(&oldfunc);
else
lua_pushcfunction(replace);
}