diff options
Diffstat (limited to 'fallback.c')
-rw-r--r-- | fallback.c | 130 |
1 files changed, 114 insertions, 16 deletions
@@ -3,7 +3,7 @@ | |||
3 | ** TecCGraf - PUC-Rio | 3 | ** TecCGraf - PUC-Rio |
4 | */ | 4 | */ |
5 | 5 | ||
6 | char *rcs_fallback="$Id: fallback.c,v 1.24 1996/04/22 18:00:37 roberto Exp roberto $"; | 6 | char *rcs_fallback="$Id: fallback.c,v 1.25 1996/04/25 14:10:00 roberto Exp roberto $"; |
7 | 7 | ||
8 | #include <stdio.h> | 8 | #include <stdio.h> |
9 | #include <string.h> | 9 | #include <string.h> |
@@ -13,6 +13,8 @@ char *rcs_fallback="$Id: fallback.c,v 1.24 1996/04/22 18:00:37 roberto Exp rober | |||
13 | #include "opcode.h" | 13 | #include "opcode.h" |
14 | #include "lua.h" | 14 | #include "lua.h" |
15 | #include "table.h" | 15 | #include "table.h" |
16 | #include "tree.h" | ||
17 | #include "hash.h" | ||
16 | 18 | ||
17 | 19 | ||
18 | static void errorFB (void); | 20 | static void errorFB (void); |
@@ -29,8 +31,6 @@ static void funcFB (void); | |||
29 | ** Warning: This list must be in the same order as the #define's | 31 | ** Warning: This list must be in the same order as the #define's |
30 | */ | 32 | */ |
31 | struct FB luaI_fallBacks[] = { | 33 | struct FB luaI_fallBacks[] = { |
32 | {"error", {LUA_T_CFUNCTION, {errorFB}}, 1, 0}, | ||
33 | {"index", {LUA_T_CFUNCTION, {indexFB}}, 2, 1}, | ||
34 | {"gettable", {LUA_T_CFUNCTION, {gettableFB}}, 2, 1}, | 34 | {"gettable", {LUA_T_CFUNCTION, {gettableFB}}, 2, 1}, |
35 | {"arith", {LUA_T_CFUNCTION, {arithFB}}, 3, 1}, | 35 | {"arith", {LUA_T_CFUNCTION, {arithFB}}, 3, 1}, |
36 | {"order", {LUA_T_CFUNCTION, {orderFB}}, 3, 1}, | 36 | {"order", {LUA_T_CFUNCTION, {orderFB}}, 3, 1}, |
@@ -39,12 +39,26 @@ struct FB luaI_fallBacks[] = { | |||
39 | {"gc", {LUA_T_CFUNCTION, {GDFB}}, 1, 0}, | 39 | {"gc", {LUA_T_CFUNCTION, {GDFB}}, 1, 0}, |
40 | {"function", {LUA_T_CFUNCTION, {funcFB}}, -1, -1}, | 40 | {"function", {LUA_T_CFUNCTION, {funcFB}}, -1, -1}, |
41 | /* no fixed number of params or results */ | 41 | /* no fixed number of params or results */ |
42 | {"getglobal", {LUA_T_CFUNCTION, {indexFB}}, 1, 1} | 42 | {"getglobal", {LUA_T_CFUNCTION, {indexFB}}, 1, 1}, |
43 | /* same default behavior of index FB */ | 43 | /* same default behavior of index FB */ |
44 | {"index", {LUA_T_CFUNCTION, {indexFB}}, 2, 1}, | ||
45 | {"error", {LUA_T_CFUNCTION, {errorFB}}, 1, 0} | ||
44 | }; | 46 | }; |
45 | 47 | ||
46 | #define N_FB (sizeof(luaI_fallBacks)/sizeof(struct FB)) | 48 | #define N_FB (sizeof(luaI_fallBacks)/sizeof(struct FB)) |
47 | 49 | ||
50 | static int luaI_findevent (char *name) | ||
51 | { | ||
52 | int i; | ||
53 | for (i=0; i<N_FB; i++) | ||
54 | if (strcmp(luaI_fallBacks[i].kind, name) == 0) | ||
55 | return i; | ||
56 | /* name not found */ | ||
57 | lua_error("invalid event name"); | ||
58 | return 0; /* to avoid warnings */ | ||
59 | } | ||
60 | |||
61 | |||
48 | void luaI_setfallback (void) | 62 | void luaI_setfallback (void) |
49 | { | 63 | { |
50 | int i; | 64 | int i; |
@@ -52,17 +66,9 @@ void luaI_setfallback (void) | |||
52 | lua_Object func = lua_getparam(2); | 66 | lua_Object func = lua_getparam(2); |
53 | if (name == NULL || !lua_isfunction(func)) | 67 | if (name == NULL || !lua_isfunction(func)) |
54 | lua_error("incorrect argument to function `setfallback'"); | 68 | lua_error("incorrect argument to function `setfallback'"); |
55 | for (i=0; i<N_FB; i++) | 69 | i = luaI_findevent(name); |
56 | { | 70 | luaI_pushobject(&luaI_fallBacks[i].function); |
57 | if (strcmp(luaI_fallBacks[i].kind, name) == 0) | 71 | luaI_fallBacks[i].function = *luaI_Address(func); |
58 | { | ||
59 | luaI_pushobject(&luaI_fallBacks[i].function); | ||
60 | luaI_fallBacks[i].function = *luaI_Address(func); | ||
61 | return; | ||
62 | } | ||
63 | } | ||
64 | /* name not found */ | ||
65 | lua_error("incorrect argument to function `setfallback'"); | ||
66 | } | 72 | } |
67 | 73 | ||
68 | 74 | ||
@@ -112,7 +118,7 @@ static void funcFB (void) | |||
112 | } | 118 | } |
113 | 119 | ||
114 | 120 | ||
115 | /* | 121 | /* ------------------------------------------- |
116 | ** Reference routines | 122 | ** Reference routines |
117 | */ | 123 | */ |
118 | 124 | ||
@@ -189,3 +195,95 @@ char *luaI_travfallbacks (int (*fn)(Object *)) | |||
189 | return luaI_fallBacks[i].kind; | 195 | return luaI_fallBacks[i].kind; |
190 | return NULL; | 196 | return NULL; |
191 | } | 197 | } |
198 | |||
199 | |||
200 | /* ------------------------------------------- | ||
201 | * Internal Methods | ||
202 | */ | ||
203 | #define BASE_TAG 1000 | ||
204 | |||
205 | static struct IM { | ||
206 | lua_Type tp; | ||
207 | Object int_method[FB_N]; | ||
208 | } *luaI_IMtable = NULL; | ||
209 | static int IMtable_size = 0; | ||
210 | static int last_tag = BASE_TAG-1; | ||
211 | |||
212 | int lua_newtag (char *t) | ||
213 | { | ||
214 | int i; | ||
215 | ++last_tag; | ||
216 | if ((last_tag-BASE_TAG) >= IMtable_size) | ||
217 | IMtable_size = growvector(&luaI_IMtable, IMtable_size, | ||
218 | struct IM, memEM, MAX_INT); | ||
219 | if (strcmp(t, "table") == 0) | ||
220 | luaI_IMtable[last_tag-BASE_TAG].tp = LUA_T_ARRAY; | ||
221 | else if (strcmp(t, "userdata") == 0) | ||
222 | luaI_IMtable[last_tag-BASE_TAG].tp = LUA_T_USERDATA; | ||
223 | else | ||
224 | lua_error("invalid type for new tag"); | ||
225 | for (i=0; i<FB_N; i++) | ||
226 | luaI_IMtable[last_tag-BASE_TAG].int_method[i].tag = LUA_T_NIL; | ||
227 | return last_tag; | ||
228 | } | ||
229 | |||
230 | static int validtag (int tag) | ||
231 | { | ||
232 | return (BASE_TAG <= tag && tag <= last_tag); | ||
233 | } | ||
234 | |||
235 | static void checktag (int tag) | ||
236 | { | ||
237 | if (!validtag(tag)) | ||
238 | lua_error("invalid tag"); | ||
239 | } | ||
240 | |||
241 | void luaI_settag (int tag, Object *o) | ||
242 | { | ||
243 | checktag(tag); | ||
244 | if (tag(o) != luaI_IMtable[tag-BASE_TAG].tp) | ||
245 | lua_error("Tag is not compatible with this type"); | ||
246 | if (o->tag == LUA_T_ARRAY) | ||
247 | o->value.a->htag = tag; | ||
248 | else /* must be userdata */ | ||
249 | o->value.ts->tag = tag; | ||
250 | } | ||
251 | |||
252 | int luaI_tag (Object *o) | ||
253 | { | ||
254 | lua_Type t = tag(o); | ||
255 | if (t == LUA_T_USERDATA) | ||
256 | return o->value.ts->tag; | ||
257 | else if (t == LUA_T_ARRAY) | ||
258 | return o->value.a->htag; | ||
259 | else return t; | ||
260 | } | ||
261 | |||
262 | Object *luaI_getim (int tag, int event) | ||
263 | { | ||
264 | if (tag == 0) | ||
265 | return &luaI_fallBacks[event].function; | ||
266 | else if (validtag(tag)) { | ||
267 | Object *func = &luaI_IMtable[tag-BASE_TAG].int_method[event]; | ||
268 | if (func->tag == LUA_T_NIL) | ||
269 | return NULL; | ||
270 | else | ||
271 | return func; | ||
272 | } | ||
273 | else return NULL; | ||
274 | } | ||
275 | |||
276 | void luaI_setintmethod (void) | ||
277 | { | ||
278 | lua_Object tag = lua_getparam(1); | ||
279 | lua_Object event = lua_getparam(2); | ||
280 | lua_Object func = lua_getparam(3); | ||
281 | if (!(lua_isnumber(tag) && lua_isstring(event) && lua_isfunction(func))) | ||
282 | lua_error("incorrect arguments to function `setintmethod'"); | ||
283 | else { | ||
284 | int i = luaI_findevent(lua_getstring(event)); | ||
285 | int t = lua_getnumber(tag); | ||
286 | checktag(t); | ||
287 | luaI_IMtable[t-BASE_TAG].int_method[i] = *luaI_Address(func); | ||
288 | } | ||
289 | } | ||