diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1997-03-19 16:41:10 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1997-03-19 16:41:10 -0300 |
commit | 1444d28476af70bc51c4fdba71deb669f41c77a3 (patch) | |
tree | 6d19c5653702ea341f6650f3e917ed77456f757f | |
parent | 2de803c250de373186afbbea0a5978f54c52850c (diff) | |
download | lua-1444d28476af70bc51c4fdba71deb669f41c77a3.tar.gz lua-1444d28476af70bc51c4fdba71deb669f41c77a3.tar.bz2 lua-1444d28476af70bc51c4fdba71deb669f41c77a3.zip |
first full implementation of internal methods
-rw-r--r-- | fallback.c | 369 | ||||
-rw-r--r-- | fallback.h | 37 | ||||
-rw-r--r-- | hash.c | 9 | ||||
-rw-r--r-- | hash.h | 3 | ||||
-rw-r--r-- | inout.c | 4 | ||||
-rw-r--r-- | lua.h | 20 | ||||
-rw-r--r-- | opcode.c | 161 | ||||
-rw-r--r-- | opcode.h | 22 | ||||
-rw-r--r-- | table.c | 4 | ||||
-rw-r--r-- | tree.c | 23 | ||||
-rw-r--r-- | tree.h | 3 |
11 files changed, 404 insertions, 251 deletions
@@ -3,11 +3,12 @@ | |||
3 | ** TecCGraf - PUC-Rio | 3 | ** TecCGraf - PUC-Rio |
4 | */ | 4 | */ |
5 | 5 | ||
6 | char *rcs_fallback="$Id: fallback.c,v 1.26 1997/02/26 17:38:41 roberto Unstable roberto $"; | 6 | char *rcs_fallback="$Id: fallback.c,v 1.27 1997/03/11 18:44:28 roberto Exp roberto $"; |
7 | 7 | ||
8 | #include <stdio.h> | 8 | #include <stdio.h> |
9 | #include <string.h> | 9 | #include <string.h> |
10 | 10 | ||
11 | #include "auxlib.h" | ||
11 | #include "mem.h" | 12 | #include "mem.h" |
12 | #include "fallback.h" | 13 | #include "fallback.h" |
13 | #include "opcode.h" | 14 | #include "opcode.h" |
@@ -17,105 +18,6 @@ char *rcs_fallback="$Id: fallback.c,v 1.26 1997/02/26 17:38:41 roberto Unstable | |||
17 | #include "hash.h" | 18 | #include "hash.h" |
18 | 19 | ||
19 | 20 | ||
20 | static void errorFB (void); | ||
21 | static void indexFB (void); | ||
22 | static void gettableFB (void); | ||
23 | static void arithFB (void); | ||
24 | static void concatFB (void); | ||
25 | static void orderFB (void); | ||
26 | static void GDFB (void); | ||
27 | static void funcFB (void); | ||
28 | |||
29 | |||
30 | /* | ||
31 | ** Warning: This list must be in the same order as the #define's | ||
32 | */ | ||
33 | struct FB luaI_fallBacks[] = { | ||
34 | {"gettable", {LUA_T_CFUNCTION, {gettableFB}}, 2, 1}, | ||
35 | {"arith", {LUA_T_CFUNCTION, {arithFB}}, 3, 1}, | ||
36 | {"order", {LUA_T_CFUNCTION, {orderFB}}, 3, 1}, | ||
37 | {"concat", {LUA_T_CFUNCTION, {concatFB}}, 2, 1}, | ||
38 | {"settable", {LUA_T_CFUNCTION, {gettableFB}}, 3, 0}, | ||
39 | {"gc", {LUA_T_CFUNCTION, {GDFB}}, 1, 0}, | ||
40 | {"function", {LUA_T_CFUNCTION, {funcFB}}, -1, -1}, | ||
41 | /* no fixed number of params or results */ | ||
42 | {"getglobal", {LUA_T_CFUNCTION, {indexFB}}, 1, 1}, | ||
43 | /* same default behavior of index FB */ | ||
44 | {"index", {LUA_T_CFUNCTION, {indexFB}}, 2, 1}, | ||
45 | {"error", {LUA_T_CFUNCTION, {errorFB}}, 1, 0} | ||
46 | }; | ||
47 | |||
48 | #define N_FB (sizeof(luaI_fallBacks)/sizeof(struct FB)) | ||
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 | |||
62 | void luaI_setfallback (void) | ||
63 | { | ||
64 | int i; | ||
65 | char *name = lua_getstring(lua_getparam(1)); | ||
66 | lua_Object func = lua_getparam(2); | ||
67 | if (name == NULL || !lua_isfunction(func)) | ||
68 | lua_error("incorrect argument to function `setfallback'"); | ||
69 | i = luaI_findevent(name); | ||
70 | luaI_pushobject(&luaI_fallBacks[i].function); | ||
71 | luaI_fallBacks[i].function = *luaI_Address(func); | ||
72 | } | ||
73 | |||
74 | |||
75 | static void errorFB (void) | ||
76 | { | ||
77 | lua_Object o = lua_getparam(1); | ||
78 | if (lua_isstring(o)) | ||
79 | fprintf (stderr, "lua: %s\n", lua_getstring(o)); | ||
80 | else | ||
81 | fprintf(stderr, "lua: unknown error\n"); | ||
82 | } | ||
83 | |||
84 | |||
85 | static void indexFB (void) | ||
86 | { | ||
87 | lua_pushnil(); | ||
88 | } | ||
89 | |||
90 | |||
91 | static void gettableFB (void) | ||
92 | { | ||
93 | lua_error("indexed expression not a table"); | ||
94 | } | ||
95 | |||
96 | |||
97 | static void arithFB (void) | ||
98 | { | ||
99 | lua_error("unexpected type at conversion to number"); | ||
100 | } | ||
101 | |||
102 | static void concatFB (void) | ||
103 | { | ||
104 | lua_error("unexpected type at conversion to string"); | ||
105 | } | ||
106 | |||
107 | |||
108 | static void orderFB (void) | ||
109 | { | ||
110 | lua_error("unexpected type at comparison"); | ||
111 | } | ||
112 | |||
113 | static void GDFB (void) { } | ||
114 | |||
115 | static void funcFB (void) | ||
116 | { | ||
117 | lua_error("call expression not a function"); | ||
118 | } | ||
119 | 21 | ||
120 | 22 | ||
121 | /* ------------------------------------------- | 23 | /* ------------------------------------------- |
@@ -187,50 +89,127 @@ void luaI_invalidaterefs (void) | |||
187 | refArray[i].status = COLLECTED; | 89 | refArray[i].status = COLLECTED; |
188 | } | 90 | } |
189 | 91 | ||
190 | char *luaI_travfallbacks (int (*fn)(Object *)) | 92 | |
93 | /* ------------------------------------------- | ||
94 | * Internal Methods | ||
95 | */ | ||
96 | |||
97 | char *eventname[] = { | ||
98 | "gettable", /* IM_GETTABLE */ | ||
99 | "arith", /* IM_ARITH */ | ||
100 | "order", /* IM_ORDER */ | ||
101 | "concat", /* IM_CONCAT */ | ||
102 | "settable", /* IM_SETTABLE */ | ||
103 | "gc", /* IM_GC */ | ||
104 | "function", /* IM_FUNCTION */ | ||
105 | "index", /* IM_INDEX */ | ||
106 | NULL | ||
107 | }; | ||
108 | |||
109 | |||
110 | char *geventname[] = { | ||
111 | "error", /* GIM_ERROR */ | ||
112 | "getglobal", /* GIM_GETGLOBAL */ | ||
113 | "setglobal", /* GIM_SETGLOBAL */ | ||
114 | NULL | ||
115 | }; | ||
116 | |||
117 | static int luaI_findevent (char *name, char *list[]) | ||
191 | { | 118 | { |
192 | int i; | 119 | int i; |
193 | for (i=0; i<N_FB; i++) | 120 | for (i=0; list[i]; i++) |
194 | if (fn(&luaI_fallBacks[i].function)) | 121 | if (strcmp(list[i], name) == 0) |
195 | return luaI_fallBacks[i].kind; | 122 | return i; |
196 | return NULL; | 123 | /* name not found */ |
124 | return -1; | ||
197 | } | 125 | } |
198 | 126 | ||
127 | static int luaI_checkevent (char *name, char *list[]) | ||
128 | { | ||
129 | int e = luaI_findevent(name, list); | ||
130 | if (e < 0) | ||
131 | lua_error("invalid event name"); | ||
132 | return e; | ||
133 | } | ||
199 | 134 | ||
200 | /* ------------------------------------------- | ||
201 | * Internal Methods | ||
202 | */ | ||
203 | #define BASE_TAG 1000 | ||
204 | 135 | ||
205 | static struct IM { | 136 | static struct IM { |
206 | lua_Type tp; | 137 | lua_Type tp; |
207 | Object int_method[FB_N]; | 138 | Object int_method[IM_N]; |
208 | } *luaI_IMtable = NULL; | 139 | } *luaI_IMtable = NULL; |
140 | |||
209 | static int IMtable_size = 0; | 141 | static int IMtable_size = 0; |
210 | static int last_tag = BASE_TAG-1; | 142 | static int last_tag = LUA_T_NIL; |
143 | |||
144 | static struct { | ||
145 | lua_Type t; | ||
146 | int event; | ||
147 | } exceptions[] = { /* list of events that cannot be modified */ | ||
148 | {LUA_T_NUMBER, IM_ARITH}, | ||
149 | {LUA_T_NUMBER, IM_ORDER}, | ||
150 | {LUA_T_NUMBER, IM_GC}, | ||
151 | {LUA_T_STRING, IM_ARITH}, | ||
152 | {LUA_T_STRING, IM_ORDER}, | ||
153 | {LUA_T_STRING, IM_CONCAT}, | ||
154 | {LUA_T_STRING, IM_GC}, | ||
155 | {LUA_T_ARRAY, IM_GETTABLE}, | ||
156 | {LUA_T_ARRAY, IM_SETTABLE}, | ||
157 | {LUA_T_FUNCTION, IM_FUNCTION}, | ||
158 | {LUA_T_FUNCTION, IM_GC}, | ||
159 | {LUA_T_CFUNCTION, IM_FUNCTION}, | ||
160 | {LUA_T_CFUNCTION, IM_GC}, | ||
161 | {LUA_T_NIL, 0} /* flag end of list */ | ||
162 | }; | ||
211 | 163 | ||
212 | int lua_newtag (char *t) | 164 | |
165 | static int validevent (int t, int event) | ||
166 | { | ||
167 | int i; | ||
168 | if (t == LUA_T_NIL) /* cannot modify any event for nil */ | ||
169 | return 0; | ||
170 | for (i=0; exceptions[i].t != LUA_T_NIL; i++) | ||
171 | if (exceptions[i].t == t && exceptions[i].event == event) | ||
172 | return 0; | ||
173 | return 1; | ||
174 | } | ||
175 | |||
176 | static void init_entry (int tag) | ||
213 | { | 177 | { |
214 | int i; | 178 | int i; |
215 | ++last_tag; | 179 | for (i=0; i<IM_N; i++) |
216 | if ((last_tag-BASE_TAG) >= IMtable_size) | 180 | luaI_IMtable[-tag].int_method[i].ttype = LUA_T_NIL; |
181 | } | ||
182 | |||
183 | void luaI_initfallbacks (void) | ||
184 | { | ||
185 | int i; | ||
186 | IMtable_size = NUM_TYPES+10; | ||
187 | luaI_IMtable = newvector(IMtable_size, struct IM); | ||
188 | for (i=LUA_T_NIL; i<=LUA_T_USERDATA; i++) { | ||
189 | luaI_IMtable[-i].tp = (lua_Type)i; | ||
190 | init_entry(i); | ||
191 | } | ||
192 | } | ||
193 | |||
194 | int lua_newtag (char *t) | ||
195 | { | ||
196 | --last_tag; | ||
197 | if ((-last_tag) >= IMtable_size) | ||
217 | IMtable_size = growvector(&luaI_IMtable, IMtable_size, | 198 | IMtable_size = growvector(&luaI_IMtable, IMtable_size, |
218 | struct IM, memEM, MAX_INT); | 199 | struct IM, memEM, MAX_INT); |
219 | if (strcmp(t, "table") == 0) | 200 | if (strcmp(t, "table") == 0) |
220 | luaI_IMtable[last_tag-BASE_TAG].tp = LUA_T_ARRAY; | 201 | luaI_IMtable[-last_tag].tp = LUA_T_ARRAY; |
221 | else if (strcmp(t, "userdata") == 0) | 202 | else if (strcmp(t, "userdata") == 0) |
222 | luaI_IMtable[last_tag-BASE_TAG].tp = LUA_T_USERDATA; | 203 | luaI_IMtable[-last_tag].tp = LUA_T_USERDATA; |
223 | else | 204 | else |
224 | lua_error("invalid type for new tag"); | 205 | lua_error("invalid type for new tag"); |
225 | for (i=0; i<FB_N; i++) | 206 | init_entry(last_tag); |
226 | luaI_IMtable[last_tag-BASE_TAG].int_method[i].ttype = LUA_T_NIL; | ||
227 | return last_tag; | 207 | return last_tag; |
228 | } | 208 | } |
229 | 209 | ||
230 | static int validtag (int tag) | 210 | |
231 | { | 211 | #define validtag(tag) (last_tag <= (tag) && (tag) <= 0) |
232 | return (BASE_TAG <= tag && tag <= last_tag); | 212 | |
233 | } | ||
234 | 213 | ||
235 | static void checktag (int tag) | 214 | static void checktag (int tag) |
236 | { | 215 | { |
@@ -238,10 +217,18 @@ static void checktag (int tag) | |||
238 | lua_error("invalid tag"); | 217 | lua_error("invalid tag"); |
239 | } | 218 | } |
240 | 219 | ||
220 | lua_Type luaI_typetag (int tag) | ||
221 | { | ||
222 | if (tag >= 0) return LUA_T_USERDATA; | ||
223 | else { | ||
224 | checktag(tag); | ||
225 | return luaI_IMtable[-tag].tp; | ||
226 | } | ||
227 | } | ||
228 | |||
241 | void luaI_settag (int tag, Object *o) | 229 | void luaI_settag (int tag, Object *o) |
242 | { | 230 | { |
243 | checktag(tag); | 231 | if (ttype(o) != luaI_typetag(tag)) |
244 | if (ttype(o) != luaI_IMtable[tag-BASE_TAG].tp) | ||
245 | lua_error("Tag is not compatible with this type"); | 232 | lua_error("Tag is not compatible with this type"); |
246 | if (o->ttype == LUA_T_ARRAY) | 233 | if (o->ttype == LUA_T_ARRAY) |
247 | o->value.a->htag = tag; | 234 | o->value.a->htag = tag; |
@@ -261,29 +248,123 @@ int luaI_tag (Object *o) | |||
261 | 248 | ||
262 | Object *luaI_getim (int tag, int event) | 249 | Object *luaI_getim (int tag, int event) |
263 | { | 250 | { |
264 | if (tag == 0) | 251 | if (tag > LUA_T_USERDATA) |
265 | return &luaI_fallBacks[event].function; | 252 | tag = LUA_T_USERDATA; /* default for non-registered tags */ |
266 | else if (validtag(tag)) { | 253 | return &luaI_IMtable[-tag].int_method[event]; |
267 | Object *func = &luaI_IMtable[tag-BASE_TAG].int_method[event]; | 254 | } |
268 | if (func->ttype == LUA_T_NIL) | 255 | |
269 | return NULL; | 256 | Object *luaI_getimbyObj (Object *o, int event) |
270 | else | 257 | { |
271 | return func; | 258 | return luaI_getim(luaI_tag(o), event); |
272 | } | ||
273 | else return NULL; | ||
274 | } | 259 | } |
275 | 260 | ||
276 | void luaI_setintmethod (void) | 261 | void luaI_setintmethod (void) |
277 | { | 262 | { |
278 | lua_Object tag = lua_getparam(1); | 263 | int t = (int)luaL_check_number(1, "setintmethod"); |
279 | lua_Object event = lua_getparam(2); | 264 | int e = luaI_checkevent(luaL_check_string(2, "setintmethod"), eventname); |
280 | lua_Object func = lua_getparam(3); | 265 | lua_Object func = lua_getparam(3); |
281 | if (!(lua_isnumber(tag) && lua_isstring(event) && lua_isfunction(func))) | 266 | if (!validevent(t, e)) |
282 | lua_error("incorrect arguments to function `setintmethod'"); | 267 | lua_error("cannot change this internal method"); |
283 | else { | 268 | luaL_arg_check(lua_isnil(func) || lua_isfunction(func), "setintmethod", |
284 | int i = luaI_findevent(lua_getstring(event)); | 269 | 3, "function expected"); |
285 | int t = lua_getnumber(tag); | 270 | checktag(t); |
286 | checktag(t); | 271 | luaI_IMtable[-t].int_method[e] = *luaI_Address(func); |
287 | luaI_IMtable[t-BASE_TAG].int_method[i] = *luaI_Address(func); | 272 | } |
273 | |||
274 | static Object gmethod[GIM_N] = { | ||
275 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}} | ||
276 | }; | ||
277 | |||
278 | Object *luaI_getgim (int event) | ||
279 | { | ||
280 | return &gmethod[event]; | ||
281 | } | ||
282 | |||
283 | void luaI_setglobalmethod (void) | ||
284 | { | ||
285 | int e = luaI_checkevent(luaL_check_string(1, "setintmethod"), geventname); | ||
286 | lua_Object func = lua_getparam(2); | ||
287 | luaL_arg_check(lua_isnil(func) || lua_isfunction(func), "setintmethod", | ||
288 | 2, "function expected"); | ||
289 | gmethod[e] = *luaI_Address(func); | ||
290 | } | ||
291 | |||
292 | char *luaI_travfallbacks (int (*fn)(Object *)) | ||
293 | { /* ?????????? | ||
294 | int i; | ||
295 | for (i=0; i<N_FB; i++) | ||
296 | if (fn(&luaI_fallBacks[i].function)) | ||
297 | return luaI_fallBacks[i].kind; */ | ||
298 | return NULL; | ||
299 | } | ||
300 | |||
301 | |||
302 | /* | ||
303 | * =================================================================== | ||
304 | * compatibility with old fallback system | ||
305 | */ | ||
306 | |||
307 | |||
308 | static void errorFB (void) | ||
309 | { | ||
310 | lua_Object o = lua_getparam(1); | ||
311 | if (lua_isstring(o)) | ||
312 | fprintf (stderr, "lua: %s\n", lua_getstring(o)); | ||
313 | else | ||
314 | fprintf(stderr, "lua: unknown error\n"); | ||
315 | } | ||
316 | |||
317 | |||
318 | static void nilFB (void) { } | ||
319 | |||
320 | |||
321 | static void typeFB (void) | ||
322 | { | ||
323 | lua_error("unexpected type"); | ||
324 | } | ||
325 | |||
326 | |||
327 | void luaI_setfallback (void) | ||
328 | { | ||
329 | int e; | ||
330 | char *name = luaL_check_string(1, "setfallback"); | ||
331 | lua_Object func = lua_getparam(2); | ||
332 | luaL_arg_check(lua_isfunction(func), "setfallback", 2, "function expected"); | ||
333 | e = luaI_findevent(name, geventname); | ||
334 | if (e >= 0) { /* global event */ | ||
335 | switch (e) { | ||
336 | case GIM_ERROR: | ||
337 | gmethod[e] = *luaI_Address(func); | ||
338 | lua_pushcfunction(errorFB); | ||
339 | break; | ||
340 | case GIM_GETGLOBAL: /* goes through */ | ||
341 | case GIM_SETGLOBAL: | ||
342 | gmethod[e] = *luaI_Address(func); | ||
343 | lua_pushcfunction(nilFB); | ||
344 | break; | ||
345 | default: lua_error("internal error"); | ||
346 | } | ||
347 | } | ||
348 | else { /* tagged name? */ | ||
349 | int t; | ||
350 | Object oldfunc; | ||
351 | e = luaI_checkevent(name, eventname); | ||
352 | oldfunc = luaI_IMtable[LUA_T_USERDATA].int_method[e]; | ||
353 | for (t=LUA_T_NIL; t<=LUA_T_USERDATA; t++) | ||
354 | if (validevent(t, e)) | ||
355 | luaI_IMtable[-t].int_method[e] = *luaI_Address(func); | ||
356 | if (oldfunc.ttype != LUA_T_NIL) | ||
357 | luaI_pushobject(&oldfunc); | ||
358 | else { | ||
359 | switch (e) { | ||
360 | case IM_GC: case IM_INDEX: | ||
361 | lua_pushcfunction(nilFB); | ||
362 | break; | ||
363 | default: | ||
364 | lua_pushcfunction(typeFB); | ||
365 | break; | ||
366 | } | ||
367 | } | ||
288 | } | 368 | } |
289 | } | 369 | } |
370 | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: fallback.h,v 1.13 1996/04/25 14:10:00 roberto Exp roberto $ | 2 | ** $Id: fallback.h,v 1.14 1997/02/26 17:38:41 roberto Unstable roberto $ |
3 | */ | 3 | */ |
4 | 4 | ||
5 | #ifndef fallback_h | 5 | #ifndef fallback_h |
@@ -8,24 +8,20 @@ | |||
8 | #include "lua.h" | 8 | #include "lua.h" |
9 | #include "opcode.h" | 9 | #include "opcode.h" |
10 | 10 | ||
11 | extern struct FB { | 11 | #define IM_GETTABLE 0 |
12 | char *kind; | 12 | #define IM_ARITH 1 |
13 | Object function; | 13 | #define IM_ORDER 2 |
14 | int nParams; | 14 | #define IM_CONCAT 3 |
15 | int nResults; | 15 | #define IM_SETTABLE 4 |
16 | } luaI_fallBacks[]; | 16 | #define IM_GC 5 |
17 | #define IM_FUNCTION 6 | ||
18 | #define IM_INDEX 7 | ||
19 | #define IM_N 8 | ||
17 | 20 | ||
18 | #define FB_GETTABLE 0 | 21 | #define GIM_ERROR 0 |
19 | #define FB_ARITH 1 | 22 | #define GIM_GETGLOBAL 1 |
20 | #define FB_ORDER 2 | 23 | #define GIM_SETGLOBAL 2 |
21 | #define FB_CONCAT 3 | 24 | #define GIM_N 3 |
22 | #define FB_SETTABLE 4 | ||
23 | #define FB_GC 5 | ||
24 | #define FB_FUNCTION 6 | ||
25 | #define FB_GETGLOBAL 7 | ||
26 | #define FB_INDEX 8 | ||
27 | #define FB_ERROR 9 | ||
28 | #define FB_N 10 | ||
29 | 25 | ||
30 | void luaI_setfallback (void); | 26 | void luaI_setfallback (void); |
31 | int luaI_ref (Object *object, int lock); | 27 | int luaI_ref (Object *object, int lock); |
@@ -35,9 +31,14 @@ void luaI_invalidaterefs (void); | |||
35 | char *luaI_travfallbacks (int (*fn)(Object *)); | 31 | char *luaI_travfallbacks (int (*fn)(Object *)); |
36 | 32 | ||
37 | void luaI_settag (int tag, Object *o); | 33 | void luaI_settag (int tag, Object *o); |
34 | lua_Type luaI_typetag (int tag); | ||
38 | Object *luaI_getim (int tag, int event); | 35 | Object *luaI_getim (int tag, int event); |
36 | Object *luaI_getgim (int event); | ||
37 | Object *luaI_getimbyObj (Object *o, int event); | ||
39 | int luaI_tag (Object *o); | 38 | int luaI_tag (Object *o); |
40 | void luaI_setintmethod (void); | 39 | void luaI_setintmethod (void); |
40 | void luaI_setglobalmethod (void); | ||
41 | void luaI_initfallbacks (void); | ||
41 | 42 | ||
42 | #endif | 43 | #endif |
43 | 44 | ||
@@ -3,7 +3,7 @@ | |||
3 | ** hash manager for lua | 3 | ** hash manager for lua |
4 | */ | 4 | */ |
5 | 5 | ||
6 | char *rcs_hash="$Id: hash.c,v 2.34 1997/02/26 17:38:41 roberto Unstable roberto $"; | 6 | char *rcs_hash="$Id: hash.c,v 2.35 1997/03/11 18:44:28 roberto Exp roberto $"; |
7 | 7 | ||
8 | 8 | ||
9 | #include "mem.h" | 9 | #include "mem.h" |
@@ -159,7 +159,7 @@ void lua_hashmark (Hash *h) | |||
159 | } | 159 | } |
160 | 160 | ||
161 | 161 | ||
162 | static void call_fallbacks (void) | 162 | void luaI_hashcallIM (void) |
163 | { | 163 | { |
164 | Hash *curr_array; | 164 | Hash *curr_array; |
165 | Object t; | 165 | Object t; |
@@ -168,10 +168,10 @@ static void call_fallbacks (void) | |||
168 | if (markarray(curr_array) != 1) | 168 | if (markarray(curr_array) != 1) |
169 | { | 169 | { |
170 | avalue(&t) = curr_array; | 170 | avalue(&t) = curr_array; |
171 | luaI_gcFB(&t); | 171 | luaI_gcIM(&t); |
172 | } | 172 | } |
173 | ttype(&t) = LUA_T_NIL; | 173 | ttype(&t) = LUA_T_NIL; |
174 | luaI_gcFB(&t); /* end of list */ | 174 | luaI_gcIM(&t); /* end of list */ |
175 | } | 175 | } |
176 | 176 | ||
177 | 177 | ||
@@ -183,7 +183,6 @@ Long lua_hashcollector (void) | |||
183 | { | 183 | { |
184 | Hash *curr_array = listhead, *prev = NULL; | 184 | Hash *curr_array = listhead, *prev = NULL; |
185 | Long counter = 0; | 185 | Long counter = 0; |
186 | call_fallbacks(); | ||
187 | while (curr_array != NULL) | 186 | while (curr_array != NULL) |
188 | { | 187 | { |
189 | Hash *next = curr_array->next; | 188 | Hash *next = curr_array->next; |
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | ** hash.h | 2 | ** hash.h |
3 | ** hash manager for lua | 3 | ** hash manager for lua |
4 | ** $Id: hash.h,v 2.12 1996/05/06 14:30:27 roberto Exp roberto $ | 4 | ** $Id: hash.h,v 2.13 1997/02/26 17:38:41 roberto Unstable roberto $ |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #ifndef hash_h | 7 | #ifndef hash_h |
@@ -30,6 +30,7 @@ int luaI_redimension (int nhash); | |||
30 | Hash *lua_createarray (int nhash); | 30 | Hash *lua_createarray (int nhash); |
31 | void lua_hashmark (Hash *h); | 31 | void lua_hashmark (Hash *h); |
32 | Long lua_hashcollector (void); | 32 | Long lua_hashcollector (void); |
33 | void luaI_hashcallIM (void); | ||
33 | Object *lua_hashget (Hash *t, Object *ref); | 34 | Object *lua_hashget (Hash *t, Object *ref); |
34 | Object *lua_hashdefine (Hash *t, Object *ref); | 35 | Object *lua_hashdefine (Hash *t, Object *ref); |
35 | void lua_next (void); | 36 | void lua_next (void); |
@@ -5,11 +5,12 @@ | |||
5 | ** Also provides some predefined lua functions. | 5 | ** Also provides some predefined lua functions. |
6 | */ | 6 | */ |
7 | 7 | ||
8 | char *rcs_inout="$Id: inout.c,v 2.45 1997/03/11 18:44:28 roberto Exp roberto $"; | 8 | char *rcs_inout="$Id: inout.c,v 2.46 1997/03/17 17:01:10 roberto Exp roberto $"; |
9 | 9 | ||
10 | #include <stdio.h> | 10 | #include <stdio.h> |
11 | #include <string.h> | 11 | #include <string.h> |
12 | 12 | ||
13 | #include "auxlib.h" | ||
13 | #include "lex.h" | 14 | #include "lex.h" |
14 | #include "opcode.h" | 15 | #include "opcode.h" |
15 | #include "inout.h" | 16 | #include "inout.h" |
@@ -322,6 +323,7 @@ static struct { | |||
322 | {"print", luaI_print}, | 323 | {"print", luaI_print}, |
323 | {"setfallback", luaI_setfallback}, | 324 | {"setfallback", luaI_setfallback}, |
324 | {"setintmethod", luaI_setintmethod}, | 325 | {"setintmethod", luaI_setintmethod}, |
326 | {"setglobalmethod", luaI_setglobalmethod}, | ||
325 | {"setglobal", luaI_setglobal}, | 327 | {"setglobal", luaI_setglobal}, |
326 | {"tonumber", lua_obj2number}, | 328 | {"tonumber", lua_obj2number}, |
327 | {"tostring", luaI_tostring}, | 329 | {"tostring", luaI_tostring}, |
@@ -2,7 +2,7 @@ | |||
2 | ** LUA - Linguagem para Usuarios de Aplicacao | 2 | ** LUA - Linguagem para Usuarios de Aplicacao |
3 | ** Grupo de Tecnologia em Computacao Grafica | 3 | ** Grupo de Tecnologia em Computacao Grafica |
4 | ** TeCGraf - PUC-Rio | 4 | ** TeCGraf - PUC-Rio |
5 | ** $Id: lua.h,v 3.35 1997/02/26 17:38:41 roberto Unstable roberto $ | 5 | ** $Id: lua.h,v 3.36 1997/03/17 17:01:10 roberto Exp roberto $ |
6 | */ | 6 | */ |
7 | 7 | ||
8 | 8 | ||
@@ -21,6 +21,7 @@ typedef unsigned int lua_Object; | |||
21 | 21 | ||
22 | lua_Object lua_setfallback (char *event, lua_CFunction fallback); | 22 | lua_Object lua_setfallback (char *event, lua_CFunction fallback); |
23 | void lua_setintmethod (int tag, char *event, lua_CFunction method); | 23 | void lua_setintmethod (int tag, char *event, lua_CFunction method); |
24 | void lua_setglobalmethod (char *event, lua_CFunction method); | ||
24 | 25 | ||
25 | int lua_newtag (char *t); | 26 | int lua_newtag (char *t); |
26 | void lua_settag (int tag); /* In: object */ | 27 | void lua_settag (int tag); /* In: object */ |
@@ -36,8 +37,9 @@ int lua_call (char *funcname); | |||
36 | void lua_beginblock (void); | 37 | void lua_beginblock (void); |
37 | void lua_endblock (void); | 38 | void lua_endblock (void); |
38 | 39 | ||
39 | lua_Object lua_getparam (int number); | 40 | lua_Object lua_lua2C (int number); |
40 | #define lua_getresult(_) lua_getparam(_) | 41 | #define lua_getparam(_) lua_lua2C(_) |
42 | #define lua_getresult(_) lua_lua2C(_) | ||
41 | 43 | ||
42 | int lua_isnil (lua_Object object); | 44 | int lua_isnil (lua_Object object); |
43 | int lua_istable (lua_Object object); | 45 | int lua_istable (lua_Object object); |
@@ -62,7 +64,9 @@ void lua_pushusertag (void *u, int tag); | |||
62 | void lua_pushobject (lua_Object object); | 64 | void lua_pushobject (lua_Object object); |
63 | 65 | ||
64 | lua_Object lua_getglobal (char *name); | 66 | lua_Object lua_getglobal (char *name); |
67 | lua_Object lua_basicgetglobal (char *name); | ||
65 | void lua_storeglobal (char *name); /* In: value */ | 68 | void lua_storeglobal (char *name); /* In: value */ |
69 | void lua_basicstoreglobal (char *name); /* In: value */ | ||
66 | 70 | ||
67 | void lua_storesubscript (void); /* In: table, index, value */ | 71 | void lua_storesubscript (void); /* In: table, index, value */ |
68 | void lua_basicstoreindex (void); /* In: table, index, value */ | 72 | void lua_basicstoreindex (void); /* In: table, index, value */ |
@@ -91,16 +95,6 @@ lua_Object lua_createtable (void); | |||
91 | 95 | ||
92 | 96 | ||
93 | /* =============================================================== */ | 97 | /* =============================================================== */ |
94 | /* Auxiliar functions for libraries */ | ||
95 | |||
96 | void luaL_arg_check(int cond, char *funcname, int numarg, char *extramsg); | ||
97 | char *luaL_check_string (int numArg, char *funcname); | ||
98 | char *luaL_opt_string (int numArg, char *def, char *funcname); | ||
99 | double luaL_check_number (int numArg, char *funcname); | ||
100 | double luaL_opt_number (int numArg, double def, char *funcname); | ||
101 | |||
102 | |||
103 | /* =============================================================== */ | ||
104 | /* for compatibility with old versions. Avoid using these macros */ | 98 | /* for compatibility with old versions. Avoid using these macros */ |
105 | 99 | ||
106 | #define lua_type(o) (lua_tag(o)) | 100 | #define lua_type(o) (lua_tag(o)) |
@@ -3,7 +3,7 @@ | |||
3 | ** TecCGraf - PUC-Rio | 3 | ** TecCGraf - PUC-Rio |
4 | */ | 4 | */ |
5 | 5 | ||
6 | char *rcs_opcode="$Id: opcode.c,v 3.83 1997/03/06 17:30:55 roberto Exp roberto $"; | 6 | char *rcs_opcode="$Id: opcode.c,v 3.84 1997/03/11 18:44:28 roberto Exp roberto $"; |
7 | 7 | ||
8 | #include <setjmp.h> | 8 | #include <setjmp.h> |
9 | #include <stdio.h> | 9 | #include <stdio.h> |
@@ -268,15 +268,6 @@ static void callIM (Object *f, int nParams, int nResults) | |||
268 | do_call((top-stack)-nParams, nResults); | 268 | do_call((top-stack)-nParams, nResults); |
269 | } | 269 | } |
270 | 270 | ||
271 | /* | ||
272 | ** Call the specified fallback, putting it on the stack below its arguments | ||
273 | */ | ||
274 | static void callFB (int fb) | ||
275 | { | ||
276 | callIM(&luaI_fallBacks[fb].function, luaI_fallBacks[fb].nParams, | ||
277 | luaI_fallBacks[fb].nResults); | ||
278 | } | ||
279 | |||
280 | 271 | ||
281 | /* | 272 | /* |
282 | ** Call a function (C or Lua). The parameters must be on the stack, | 273 | ** Call a function (C or Lua). The parameters must be on the stack, |
@@ -289,21 +280,21 @@ static void do_call (StkId base, int nResults) | |||
289 | StkId firstResult; | 280 | StkId firstResult; |
290 | Object *func = stack+base-1; | 281 | Object *func = stack+base-1; |
291 | int i; | 282 | int i; |
292 | if (ttype(func) == LUA_T_CFUNCTION) | 283 | if (ttype(func) == LUA_T_CFUNCTION) { |
293 | { | ||
294 | ttype(func) = LUA_T_CMARK; | 284 | ttype(func) = LUA_T_CMARK; |
295 | firstResult = callC(fvalue(func), base); | 285 | firstResult = callC(fvalue(func), base); |
296 | } | 286 | } |
297 | else if (ttype(func) == LUA_T_FUNCTION) | 287 | else if (ttype(func) == LUA_T_FUNCTION) { |
298 | { | ||
299 | ttype(func) = LUA_T_MARK; | 288 | ttype(func) = LUA_T_MARK; |
300 | firstResult = lua_execute(func->value.tf->code, base); | 289 | firstResult = lua_execute(func->value.tf->code, base); |
301 | } | 290 | } |
302 | else | 291 | else { /* func is not a function */ |
303 | { /* func is not a function */ | 292 | /* Check the fallback for invalid functions */ |
304 | /* Call the fallback for invalid functions */ | 293 | Object *im = luaI_getimbyObj(func, IM_FUNCTION); |
294 | if (ttype(im) == LUA_T_NIL) | ||
295 | lua_error("call expression not a function"); | ||
305 | open_stack((top-stack)-(base-1)); | 296 | open_stack((top-stack)-(base-1)); |
306 | stack[base-1] = luaI_fallBacks[FB_FUNCTION].function; | 297 | stack[base-1] = *im; |
307 | do_call(base, nResults); | 298 | do_call(base, nResults); |
308 | return; | 299 | return; |
309 | } | 300 | } |
@@ -326,15 +317,14 @@ static void do_call (StkId base, int nResults) | |||
326 | static void pushsubscript (void) | 317 | static void pushsubscript (void) |
327 | { | 318 | { |
328 | int tg = luaI_tag(top-2); | 319 | int tg = luaI_tag(top-2); |
329 | Object *im = luaI_getim(tg, FB_GETTABLE); | 320 | Object *im = luaI_getim(tg, IM_GETTABLE); |
330 | if (ttype(top-2) == LUA_T_ARRAY && im == NULL) { | 321 | if (ttype(top-2) == LUA_T_ARRAY && ttype(im) == LUA_T_NIL) { |
331 | Object *h = lua_hashget(avalue(top-2), top-1); | 322 | Object *h = lua_hashget(avalue(top-2), top-1); |
332 | if (h != NULL && ttype(h) != LUA_T_NIL) { | 323 | if (h != NULL && ttype(h) != LUA_T_NIL) { |
333 | --top; | 324 | --top; |
334 | *(top-1) = *h; | 325 | *(top-1) = *h; |
335 | } | 326 | } |
336 | else if (tg == LUA_T_ARRAY && | 327 | else if (ttype(im=luaI_getim(tg, IM_INDEX)) != LUA_T_NIL) |
337 | (im=luaI_getim(0, FB_INDEX)) != NULL) | ||
338 | callIM(im, 2, 1); | 328 | callIM(im, 2, 1); |
339 | else { | 329 | else { |
340 | --top; | 330 | --top; |
@@ -376,14 +366,14 @@ lua_Object lua_basicindex (void) | |||
376 | */ | 366 | */ |
377 | static void storesubscript (Object *t, int mode) | 367 | static void storesubscript (Object *t, int mode) |
378 | { | 368 | { |
379 | Object *im = (mode == 0) ? NULL : luaI_getim(luaI_tag(t), FB_SETTABLE); | 369 | Object *im = (mode == 0) ? NULL : luaI_getimbyObj(t, IM_SETTABLE); |
380 | if (ttype(t) == LUA_T_ARRAY && im == NULL) { | 370 | if (ttype(t) == LUA_T_ARRAY && (im == NULL || ttype(im) == LUA_T_NIL)) { |
381 | Object *h = lua_hashdefine(avalue(t), t+1); | 371 | Object *h = lua_hashdefine(avalue(t), t+1); |
382 | *h = *(top-1); | 372 | *h = *(top-1); |
383 | top -= (mode == 2) ? 1 : 3; | 373 | top -= (mode == 2) ? 1 : 3; |
384 | } | 374 | } |
385 | else { /* object is not a table, and/or has a specific "settable" method */ | 375 | else { /* object is not a table, and/or has a specific "settable" method */ |
386 | if (im) { | 376 | if (im && ttype(im) != LUA_T_NIL) { |
387 | if (mode == 2) { | 377 | if (mode == 2) { |
388 | lua_checkstack(top+2); | 378 | lua_checkstack(top+2); |
389 | *(top+1) = *(top-1); | 379 | *(top+1) = *(top-1); |
@@ -403,11 +393,13 @@ static void getglobal (Word n) | |||
403 | { | 393 | { |
404 | *top = lua_table[n].object; | 394 | *top = lua_table[n].object; |
405 | incr_top; | 395 | incr_top; |
406 | if (ttype(top-1) == LUA_T_NIL) | 396 | if (ttype(top-1) == LUA_T_NIL) { /* check i.m. */ |
407 | { /* must call getglobal fallback */ | 397 | Object *im = luaI_getgim(GIM_GETGLOBAL); |
408 | ttype(top-1) = LUA_T_STRING; | 398 | if (ttype(im) != LUA_T_NIL) { |
409 | tsvalue(top-1) = lua_table[n].varname; | 399 | ttype(top-1) = LUA_T_STRING; |
410 | callFB(FB_GETGLOBAL); | 400 | tsvalue(top-1) = lua_table[n].varname; |
401 | callIM(im, 1, 1); | ||
402 | } | ||
411 | } | 403 | } |
412 | } | 404 | } |
413 | 405 | ||
@@ -428,8 +420,13 @@ void lua_travstack (int (*fn)(Object *)) | |||
428 | 420 | ||
429 | static void lua_message (char *s) | 421 | static void lua_message (char *s) |
430 | { | 422 | { |
431 | lua_pushstring(s); | 423 | Object *im = luaI_getgim(GIM_ERROR); |
432 | callFB(FB_ERROR); | 424 | if (ttype(im) == LUA_T_NIL) |
425 | fprintf(stderr, "lua: %s\n", s); | ||
426 | else { | ||
427 | lua_pushstring(s); | ||
428 | callIM(im, 1, 0); | ||
429 | } | ||
433 | } | 430 | } |
434 | 431 | ||
435 | /* | 432 | /* |
@@ -659,10 +656,20 @@ void lua_setintmethod (int tag, char *event, lua_CFunction method) | |||
659 | { | 656 | { |
660 | lua_pushnumber(tag); | 657 | lua_pushnumber(tag); |
661 | lua_pushstring(event); | 658 | lua_pushstring(event); |
662 | lua_pushcfunction (method); | 659 | if (method) |
660 | lua_pushcfunction (method); | ||
661 | else | ||
662 | lua_pushnil(); | ||
663 | do_unprotectedrun(luaI_setintmethod, 3, 0); | 663 | do_unprotectedrun(luaI_setintmethod, 3, 0); |
664 | } | 664 | } |
665 | 665 | ||
666 | void lua_setglobalmethod (char *event, lua_CFunction method) | ||
667 | { | ||
668 | lua_pushstring(event); | ||
669 | lua_pushcfunction (method); | ||
670 | do_unprotectedrun(luaI_setglobalmethod, 3, 0); | ||
671 | } | ||
672 | |||
666 | 673 | ||
667 | /* | 674 | /* |
668 | ** API: receives on the stack the table and the index. | 675 | ** API: receives on the stack the table and the index. |
@@ -741,7 +748,7 @@ lua_Object lua_createtable (void) | |||
741 | ** Get a parameter, returning the object handle or LUA_NOOBJECT on error. | 748 | ** Get a parameter, returning the object handle or LUA_NOOBJECT on error. |
742 | ** 'number' must be 1 to get the first parameter. | 749 | ** 'number' must be 1 to get the first parameter. |
743 | */ | 750 | */ |
744 | lua_Object lua_getparam (int number) | 751 | lua_Object lua_lua2C (int number) |
745 | { | 752 | { |
746 | if (number <= 0 || number > CLS_current.num) return LUA_NOOBJECT; | 753 | if (number <= 0 || number > CLS_current.num) return LUA_NOOBJECT; |
747 | /* Ref(stack+(CLS_current.base-CLS_current.num+number-1)) == | 754 | /* Ref(stack+(CLS_current.base-CLS_current.num+number-1)) == |
@@ -874,6 +881,17 @@ lua_Object lua_getglobal (char *name) | |||
874 | return Ref(top-1); | 881 | return Ref(top-1); |
875 | } | 882 | } |
876 | 883 | ||
884 | |||
885 | lua_Object lua_basicgetglobal (char *name) | ||
886 | { | ||
887 | adjustC(0); | ||
888 | *top = lua_table[luaI_findsymbolbyname(name)].object; | ||
889 | incr_top; | ||
890 | CLS_current.base++; /* incorporate object in the stack */ | ||
891 | return Ref(top-1); | ||
892 | } | ||
893 | |||
894 | |||
877 | /* | 895 | /* |
878 | ** Store top of the stack at a global variable array field. | 896 | ** Store top of the stack at a global variable array field. |
879 | */ | 897 | */ |
@@ -944,7 +962,7 @@ void lua_pushbinarydata (void *buff, int size, int tag) | |||
944 | */ | 962 | */ |
945 | void lua_pushusertag (void *u, int tag) | 963 | void lua_pushusertag (void *u, int tag) |
946 | { | 964 | { |
947 | if (tag < LUA_T_USERDATA) | 965 | if (luaI_typetag(tag) != LUA_T_USERDATA) |
948 | lua_error("invalid tag in `lua_pushusertag'"); | 966 | lua_error("invalid tag in `lua_pushusertag'"); |
949 | lua_pushbinarydata(&u, sizeof(void *), tag); | 967 | lua_pushbinarydata(&u, sizeof(void *), tag); |
950 | } | 968 | } |
@@ -977,18 +995,47 @@ int lua_tag (lua_Object o) | |||
977 | } | 995 | } |
978 | 996 | ||
979 | 997 | ||
980 | void luaI_gcFB (Object *o) | 998 | void luaI_gcIM (Object *o) |
981 | { | 999 | { |
982 | *top = *o; | 1000 | Object *im = luaI_getimbyObj(o, IM_GC); |
983 | incr_top; | 1001 | if (ttype(im) != LUA_T_NIL) { |
984 | callFB(FB_GC); | 1002 | *top = *o; |
1003 | incr_top; | ||
1004 | callIM(im, 1, 0); | ||
1005 | } | ||
985 | } | 1006 | } |
986 | 1007 | ||
987 | 1008 | ||
988 | static void call_arith (char *op) | 1009 | static void call_arith (char *op) |
989 | { | 1010 | { |
1011 | Object *im = luaI_getimbyObj(top-2, IM_ARITH); /* try first operand */ | ||
1012 | if (ttype(im) == LUA_T_NIL) { | ||
1013 | im = luaI_getimbyObj(top-1, IM_ARITH); /* try second operand */ | ||
1014 | if (ttype(im) == LUA_T_NIL) { | ||
1015 | im = luaI_getim(0, IM_ARITH); /* try a 'global' i.m. */ | ||
1016 | if (ttype(im) == LUA_T_NIL) | ||
1017 | lua_error("unexpected type at conversion to number"); | ||
1018 | } | ||
1019 | } | ||
990 | lua_pushstring(op); | 1020 | lua_pushstring(op); |
991 | callFB(FB_ARITH); | 1021 | callIM(im, 3, 1); |
1022 | } | ||
1023 | |||
1024 | static void concim (Object *o) | ||
1025 | { | ||
1026 | Object *im = luaI_getimbyObj(o, IM_CONCAT); | ||
1027 | if (ttype(im) == LUA_T_NIL) | ||
1028 | lua_error("unexpected type at conversion to string"); | ||
1029 | callIM(im, 2, 1); | ||
1030 | } | ||
1031 | |||
1032 | static void ordim (Object *o, char *op) | ||
1033 | { | ||
1034 | Object *im = luaI_getimbyObj(o, IM_ORDER); | ||
1035 | if (ttype(im) == LUA_T_NIL) | ||
1036 | lua_error("unexpected type at comparison"); | ||
1037 | lua_pushstring(op); | ||
1038 | callIM(im, 3, 1); | ||
992 | } | 1039 | } |
993 | 1040 | ||
994 | static void comparison (lua_Type ttype_less, lua_Type ttype_equal, | 1041 | static void comparison (lua_Type ttype_less, lua_Type ttype_equal, |
@@ -999,10 +1046,12 @@ static void comparison (lua_Type ttype_less, lua_Type ttype_equal, | |||
999 | int result; | 1046 | int result; |
1000 | if (ttype(l) == LUA_T_NUMBER && ttype(r) == LUA_T_NUMBER) | 1047 | if (ttype(l) == LUA_T_NUMBER && ttype(r) == LUA_T_NUMBER) |
1001 | result = (nvalue(l) < nvalue(r)) ? -1 : (nvalue(l) == nvalue(r)) ? 0 : 1; | 1048 | result = (nvalue(l) < nvalue(r)) ? -1 : (nvalue(l) == nvalue(r)) ? 0 : 1; |
1002 | else if (tostring(l) || tostring(r)) | 1049 | else if (tostring(l)) { |
1003 | { | 1050 | ordim(l, op); |
1004 | lua_pushstring(op); | 1051 | return; |
1005 | callFB(FB_ORDER); | 1052 | } |
1053 | else if (tostring(r)) { | ||
1054 | ordim(r, op); | ||
1006 | return; | 1055 | return; |
1007 | } | 1056 | } |
1008 | else | 1057 | else |
@@ -1318,17 +1367,17 @@ static StkId lua_execute (Byte *pc, StkId base) | |||
1318 | call_arith("pow"); | 1367 | call_arith("pow"); |
1319 | break; | 1368 | break; |
1320 | 1369 | ||
1321 | case CONCOP: | 1370 | case CONCOP: { |
1322 | { | 1371 | Object *l = top-2; |
1323 | Object *l = top-2; | 1372 | Object *r = top-1; |
1324 | Object *r = top-1; | 1373 | if (tostring(l)) /* first argument is not a string */ |
1325 | if (tostring(r) || tostring(l)) | 1374 | concim(l); |
1326 | callFB(FB_CONCAT); | 1375 | else if (tostring(r)) /* second argument is not a string */ |
1327 | else | 1376 | concim(r); |
1328 | { | 1377 | else { |
1329 | tsvalue(l) = lua_createstring (lua_strconc(svalue(l),svalue(r))); | 1378 | tsvalue(l) = lua_createstring(lua_strconc(svalue(l),svalue(r))); |
1330 | --top; | 1379 | --top; |
1331 | } | 1380 | } |
1332 | } | 1381 | } |
1333 | break; | 1382 | break; |
1334 | 1383 | ||
@@ -1356,7 +1405,7 @@ static StkId lua_execute (Byte *pc, StkId base) | |||
1356 | } | 1405 | } |
1357 | break; | 1406 | break; |
1358 | 1407 | ||
1359 | case ONFJMP: | 1408 | case ONFJMP: |
1360 | { | 1409 | { |
1361 | Word w; | 1410 | Word w; |
1362 | get_word(w,pc); | 1411 | get_word(w,pc); |
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | ** TeCGraf - PUC-Rio | 2 | ** TeCGraf - PUC-Rio |
3 | ** $Id: opcode.h,v 3.27 1997/03/06 17:30:55 roberto Exp roberto $ | 3 | ** $Id: opcode.h,v 3.28 1997/03/11 18:44:28 roberto Exp roberto $ |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #ifndef opcode_h | 6 | #ifndef opcode_h |
@@ -16,18 +16,20 @@ | |||
16 | 16 | ||
17 | typedef enum | 17 | typedef enum |
18 | { | 18 | { |
19 | LUA_T_NIL = -1, | 19 | LUA_T_NIL = -9, |
20 | LUA_T_NUMBER = -2, | 20 | LUA_T_NUMBER = -8, |
21 | LUA_T_STRING = -3, | 21 | LUA_T_STRING = -7, |
22 | LUA_T_ARRAY = -4, /* array==table */ | 22 | LUA_T_ARRAY = -6, /* array==table */ |
23 | LUA_T_FUNCTION = -5, | 23 | LUA_T_FUNCTION = -5, |
24 | LUA_T_CFUNCTION= -6, | 24 | LUA_T_CFUNCTION= -4, |
25 | LUA_T_MARK = -7, | 25 | LUA_T_MARK = -3, |
26 | LUA_T_CMARK = -8, | 26 | LUA_T_CMARK = -2, |
27 | LUA_T_LINE = -9, | 27 | LUA_T_LINE = -1, |
28 | LUA_T_USERDATA = 0 | 28 | LUA_T_USERDATA = 0 |
29 | } lua_Type; | 29 | } lua_Type; |
30 | 30 | ||
31 | #define NUM_TYPES 10 | ||
32 | |||
31 | 33 | ||
32 | typedef enum { | 34 | typedef enum { |
33 | /* name parm before after side effect | 35 | /* name parm before after side effect |
@@ -156,7 +158,7 @@ void luaI_codedebugline (int line); /* from "lua.stx" module */ | |||
156 | void lua_travstack (int (*fn)(Object *)); | 158 | void lua_travstack (int (*fn)(Object *)); |
157 | Object *luaI_Address (lua_Object o); | 159 | Object *luaI_Address (lua_Object o); |
158 | void luaI_pushobject (Object *o); | 160 | void luaI_pushobject (Object *o); |
159 | void luaI_gcFB (Object *o); | 161 | void luaI_gcIM (Object *o); |
160 | int luaI_dorun (TFunc *tf); | 162 | int luaI_dorun (TFunc *tf); |
161 | 163 | ||
162 | #endif | 164 | #endif |
@@ -3,7 +3,7 @@ | |||
3 | ** Module to control static tables | 3 | ** Module to control static tables |
4 | */ | 4 | */ |
5 | 5 | ||
6 | char *rcs_table="$Id: table.c,v 2.59 1997/02/26 17:38:41 roberto Unstable roberto $"; | 6 | char *rcs_table="$Id: table.c,v 2.60 1997/03/11 18:44:28 roberto Exp roberto $"; |
7 | 7 | ||
8 | #include "mem.h" | 8 | #include "mem.h" |
9 | #include "opcode.h" | 9 | #include "opcode.h" |
@@ -168,6 +168,8 @@ Long luaI_collectgarbage (void) | |||
168 | lua_travsymbol(lua_markobject); /* mark symbol table objects */ | 168 | lua_travsymbol(lua_markobject); /* mark symbol table objects */ |
169 | luaI_travlock(lua_markobject); /* mark locked objects */ | 169 | luaI_travlock(lua_markobject); /* mark locked objects */ |
170 | luaI_travfallbacks(lua_markobject); /* mark fallbacks */ | 170 | luaI_travfallbacks(lua_markobject); /* mark fallbacks */ |
171 | luaI_hashcallIM(); | ||
172 | luaI_strcallIM(); | ||
171 | luaI_invalidaterefs(); | 173 | luaI_invalidaterefs(); |
172 | recovered += lua_strcollector(); | 174 | recovered += lua_strcollector(); |
173 | recovered += lua_hashcollector(); | 175 | recovered += lua_hashcollector(); |
@@ -3,7 +3,7 @@ | |||
3 | ** TecCGraf - PUC-Rio | 3 | ** TecCGraf - PUC-Rio |
4 | */ | 4 | */ |
5 | 5 | ||
6 | char *rcs_tree="$Id: tree.c,v 1.20 1996/03/14 15:56:26 roberto Exp roberto $"; | 6 | char *rcs_tree="$Id: tree.c,v 1.21 1997/02/11 11:35:05 roberto Exp roberto $"; |
7 | 7 | ||
8 | 8 | ||
9 | #include <string.h> | 9 | #include <string.h> |
@@ -14,6 +14,7 @@ char *rcs_tree="$Id: tree.c,v 1.20 1996/03/14 15:56:26 roberto Exp roberto $"; | |||
14 | #include "lex.h" | 14 | #include "lex.h" |
15 | #include "hash.h" | 15 | #include "hash.h" |
16 | #include "table.h" | 16 | #include "table.h" |
17 | #include "fallback.h" | ||
17 | 18 | ||
18 | 19 | ||
19 | #define NUM_HASHS 64 | 20 | #define NUM_HASHS 64 |
@@ -45,6 +46,7 @@ static void initialize (void) | |||
45 | luaI_addReserved(); | 46 | luaI_addReserved(); |
46 | luaI_initsymbol(); | 47 | luaI_initsymbol(); |
47 | luaI_initconstant(); | 48 | luaI_initconstant(); |
49 | luaI_initfallbacks(); | ||
48 | } | 50 | } |
49 | 51 | ||
50 | 52 | ||
@@ -120,6 +122,25 @@ TaggedString *lua_createstring (char *str) | |||
120 | } | 122 | } |
121 | 123 | ||
122 | 124 | ||
125 | void luaI_strcallIM (void) | ||
126 | { | ||
127 | int i; | ||
128 | Object o; | ||
129 | ttype(&o) = LUA_T_USERDATA; | ||
130 | for (i=0; i<NUM_HASHS; i++) { | ||
131 | stringtable *tb = &string_root[i]; | ||
132 | int j; | ||
133 | for (j=0; j<tb->size; j++) { | ||
134 | TaggedString *t = tb->hash[j]; | ||
135 | if (t != NULL && t->tag != LUA_T_STRING && t->marked == 0) { | ||
136 | tsvalue(&o) = t; | ||
137 | luaI_gcIM(&o); | ||
138 | } | ||
139 | } | ||
140 | } | ||
141 | } | ||
142 | |||
143 | |||
123 | /* | 144 | /* |
124 | ** Garbage collection function. | 145 | ** Garbage collection function. |
125 | ** This function traverse the string list freeing unindexed strings | 146 | ** This function traverse the string list freeing unindexed strings |
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | ** tree.h | 2 | ** tree.h |
3 | ** TecCGraf - PUC-Rio | 3 | ** TecCGraf - PUC-Rio |
4 | ** $Id: tree.h,v 1.14 1996/02/26 17:07:49 roberto Exp roberto $ | 4 | ** $Id: tree.h,v 1.15 1997/02/11 11:35:05 roberto Exp roberto $ |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #ifndef tree_h | 7 | #ifndef tree_h |
@@ -27,5 +27,6 @@ typedef struct TaggedString | |||
27 | TaggedString *lua_createstring (char *str); | 27 | TaggedString *lua_createstring (char *str); |
28 | TaggedString *luaI_createuserdata (char *buff, long size, int tag); | 28 | TaggedString *luaI_createuserdata (char *buff, long size, int tag); |
29 | Long lua_strcollector (void); | 29 | Long lua_strcollector (void); |
30 | void luaI_strcallIM (void); | ||
30 | 31 | ||
31 | #endif | 32 | #endif |