From 5d60470508aad81eac145ab4e004fbf150130267 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy <roberto@inf.puc-rio.br> Date: Thu, 20 Mar 1997 16:20:43 -0300 Subject: i.m. "arith" and "order" splited for different operations --- fallback.c | 167 ++++++++++++++++++++++++++++++------------------------------- 1 file changed, 83 insertions(+), 84 deletions(-) (limited to 'fallback.c') diff --git a/fallback.c b/fallback.c index 385a1495..0516919c 100644 --- a/fallback.c +++ b/fallback.c @@ -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); } -- cgit v1.2.3-55-g6feb