diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1997-02-26 14:38:41 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1997-02-26 14:38:41 -0300 |
| commit | 131d66efd2dc26b05bcb2bdaf67f5175f3eda1aa (patch) | |
| tree | e912e35e04883c24e89917ee3d94b8fa574f6294 /fallback.c | |
| parent | bbf1b3060a1aa4e5ec3235a560d3d054457e957d (diff) | |
| download | lua-131d66efd2dc26b05bcb2bdaf67f5175f3eda1aa.tar.gz lua-131d66efd2dc26b05bcb2bdaf67f5175f3eda1aa.tar.bz2 lua-131d66efd2dc26b05bcb2bdaf67f5175f3eda1aa.zip | |
first step in implementing internal methods.
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 | } | ||
