|
|
@ -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); |
|
|
|
} |
|
|
|
|
|
|
|