aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1997-02-26 14:38:41 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1997-02-26 14:38:41 -0300
commit131d66efd2dc26b05bcb2bdaf67f5175f3eda1aa (patch)
treee912e35e04883c24e89917ee3d94b8fa574f6294
parentbbf1b3060a1aa4e5ec3235a560d3d054457e957d (diff)
downloadlua-131d66efd2dc26b05bcb2bdaf67f5175f3eda1aa.tar.gz
lua-131d66efd2dc26b05bcb2bdaf67f5175f3eda1aa.tar.bz2
lua-131d66efd2dc26b05bcb2bdaf67f5175f3eda1aa.zip
first step in implementing internal methods.
-rw-r--r--fallback.c130
-rw-r--r--fallback.h28
-rw-r--r--hash.c5
-rw-r--r--hash.h19
-rw-r--r--inout.c205
-rw-r--r--inout.h14
-rw-r--r--lua.h30
-rw-r--r--opcode.c196
-rw-r--r--table.c41
-rw-r--r--table.h3
10 files changed, 438 insertions, 233 deletions
diff --git a/fallback.c b/fallback.c
index 9523318c..3100ec31 100644
--- a/fallback.c
+++ b/fallback.c
@@ -3,7 +3,7 @@
3** TecCGraf - PUC-Rio 3** TecCGraf - PUC-Rio
4*/ 4*/
5 5
6char *rcs_fallback="$Id: fallback.c,v 1.24 1996/04/22 18:00:37 roberto Exp roberto $"; 6char *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
18static void errorFB (void); 20static 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*/
31struct FB luaI_fallBacks[] = { 33struct 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
50static 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
48void luaI_setfallback (void) 62void 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
205static struct IM {
206 lua_Type tp;
207 Object int_method[FB_N];
208 } *luaI_IMtable = NULL;
209static int IMtable_size = 0;
210static int last_tag = BASE_TAG-1;
211
212int 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
230static int validtag (int tag)
231{
232 return (BASE_TAG <= tag && tag <= last_tag);
233}
234
235static void checktag (int tag)
236{
237 if (!validtag(tag))
238 lua_error("invalid tag");
239}
240
241void 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
252int 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
262Object *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
276void 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}
diff --git a/fallback.h b/fallback.h
index 2bcc4f5d..cb0d2220 100644
--- a/fallback.h
+++ b/fallback.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: fallback.h,v 1.12 1996/04/22 18:00:37 roberto Exp roberto $ 2** $Id: fallback.h,v 1.13 1996/04/25 14:10:00 roberto Exp roberto $
3*/ 3*/
4 4
5#ifndef fallback_h 5#ifndef fallback_h
@@ -15,16 +15,17 @@ extern struct FB {
15 int nResults; 15 int nResults;
16} luaI_fallBacks[]; 16} luaI_fallBacks[];
17 17
18#define FB_ERROR 0 18#define FB_GETTABLE 0
19#define FB_INDEX 1 19#define FB_ARITH 1
20#define FB_GETTABLE 2 20#define FB_ORDER 2
21#define FB_ARITH 3 21#define FB_CONCAT 3
22#define FB_ORDER 4 22#define FB_SETTABLE 4
23#define FB_CONCAT 5 23#define FB_GC 5
24#define FB_SETTABLE 6 24#define FB_FUNCTION 6
25#define FB_GC 7 25#define FB_GETGLOBAL 7
26#define FB_FUNCTION 8 26#define FB_INDEX 8
27#define FB_GETGLOBAL 9 27#define FB_ERROR 9
28#define FB_N 10
28 29
29void luaI_setfallback (void); 30void luaI_setfallback (void);
30int luaI_ref (Object *object, int lock); 31int luaI_ref (Object *object, int lock);
@@ -33,5 +34,10 @@ void luaI_travlock (int (*fn)(Object *));
33void luaI_invalidaterefs (void); 34void luaI_invalidaterefs (void);
34char *luaI_travfallbacks (int (*fn)(Object *)); 35char *luaI_travfallbacks (int (*fn)(Object *));
35 36
37void luaI_settag (int tag, Object *o);
38Object *luaI_getim (int tag, int event);
39int luaI_tag (Object *o);
40void luaI_setintmethod (void);
41
36#endif 42#endif
37 43
diff --git a/hash.c b/hash.c
index 8565d4f2..3ed5065d 100644
--- a/hash.c
+++ b/hash.c
@@ -3,7 +3,7 @@
3** hash manager for lua 3** hash manager for lua
4*/ 4*/
5 5
6char *rcs_hash="$Id: hash.c,v 2.32 1996/11/18 13:48:44 roberto Exp roberto $"; 6char *rcs_hash="$Id: hash.c,v 2.33 1997/02/11 11:35:05 roberto Exp roberto $";
7 7
8 8
9#include "mem.h" 9#include "mem.h"
@@ -24,6 +24,8 @@ char *rcs_hash="$Id: hash.c,v 2.32 1996/11/18 13:48:44 roberto Exp roberto $";
24 24
25#define REHASH_LIMIT 0.70 /* avoid more than this % full */ 25#define REHASH_LIMIT 0.70 /* avoid more than this % full */
26 26
27#define TagDefault LUA_T_ARRAY;
28
27 29
28static Hash *listhead = NULL; 30static Hash *listhead = NULL;
29 31
@@ -121,6 +123,7 @@ static Hash *hashcreate (int nhash)
121 nhash(t) = nhash; 123 nhash(t) = nhash;
122 nuse(t) = 0; 124 nuse(t) = 0;
123 markarray(t) = 0; 125 markarray(t) = 0;
126 t->htag = TagDefault;
124 return t; 127 return t;
125} 128}
126 129
diff --git a/hash.h b/hash.h
index d0e26f90..f64de254 100644
--- a/hash.h
+++ b/hash.h
@@ -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.11 1996/03/08 12:04:04 roberto Exp roberto $ 4** $Id: hash.h,v 2.12 1996/05/06 14:30:27 roberto Exp roberto $
5*/ 5*/
6 6
7#ifndef hash_h 7#ifndef hash_h
@@ -10,19 +10,18 @@
10#include "types.h" 10#include "types.h"
11#include "opcode.h" 11#include "opcode.h"
12 12
13typedef struct node 13typedef struct node {
14{
15 Object ref; 14 Object ref;
16 Object val; 15 Object val;
17} Node; 16} Node;
18 17
19typedef struct Hash 18typedef struct Hash {
20{ 19 struct Hash *next;
21 struct Hash *next; 20 Node *node;
22 Node *node; 21 int nhash;
23 int nhash; 22 int nuse;
24 int nuse; 23 int htag;
25 char mark; 24 char mark;
26} Hash; 25} Hash;
27 26
28 27
diff --git a/inout.c b/inout.c
index 0f79b9c7..7ccd1a58 100644
--- a/inout.c
+++ b/inout.c
@@ -5,7 +5,7 @@
5** Also provides some predefined lua functions. 5** Also provides some predefined lua functions.
6*/ 6*/
7 7
8char *rcs_inout="$Id: inout.c,v 2.42 1996/09/24 21:46:44 roberto Exp roberto $"; 8char *rcs_inout="$Id: inout.c,v 2.43 1996/09/25 12:57:22 roberto Exp roberto $";
9 9
10#include <stdio.h> 10#include <stdio.h>
11#include <string.h> 11#include <string.h>
@@ -16,7 +16,9 @@ char *rcs_inout="$Id: inout.c,v 2.42 1996/09/24 21:46:44 roberto Exp roberto $";
16#include "table.h" 16#include "table.h"
17#include "tree.h" 17#include "tree.h"
18#include "lua.h" 18#include "lua.h"
19#include "hash.h"
19#include "mem.h" 20#include "mem.h"
21#include "fallback.h"
20 22
21 23
22/* Exported variables */ 24/* Exported variables */
@@ -109,6 +111,21 @@ static void check_arg (int cond, char *func)
109 } 111 }
110} 112}
111 113
114static char *check_string (int numArg, char *funcname)
115{
116 lua_Object o = lua_getparam(numArg);
117 check_arg(lua_isstring(o), funcname);
118 return lua_getstring(o);
119}
120
121static int check_number (int numArg, char *funcname)
122{
123 lua_Object o = lua_getparam(numArg);
124 check_arg(lua_isnumber(o), funcname);
125 return (int)lua_getnumber(o);
126}
127
128
112 129
113static int passresults (void) 130static int passresults (void)
114{ 131{
@@ -122,10 +139,9 @@ static int passresults (void)
122/* 139/*
123** Internal function: do a string 140** Internal function: do a string
124*/ 141*/
125void lua_internaldostring (void) 142static void lua_internaldostring (void)
126{ 143{
127 lua_Object obj = lua_getparam (1); 144 if (lua_dostring(check_string(1, "dostring")) == 0)
128 if (lua_isstring(obj) && lua_dostring(lua_getstring(obj)) == 0)
129 if (passresults() == 0) 145 if (passresults() == 0)
130 lua_pushuserdata(NULL); /* at least one result to signal no errors */ 146 lua_pushuserdata(NULL); /* at least one result to signal no errors */
131} 147}
@@ -133,7 +149,7 @@ void lua_internaldostring (void)
133/* 149/*
134** Internal function: do a file 150** Internal function: do a file
135*/ 151*/
136void lua_internaldofile (void) 152static void lua_internaldofile (void)
137{ 153{
138 lua_Object obj = lua_getparam (1); 154 lua_Object obj = lua_getparam (1);
139 char *fname = NULL; 155 char *fname = NULL;
@@ -150,36 +166,24 @@ void lua_internaldofile (void)
150 166
151static char *tostring (lua_Object obj) 167static char *tostring (lua_Object obj)
152{ 168{
153 char *buff = luaI_buffer(20);
154 if (lua_isstring(obj)) /* get strings and numbers */ 169 if (lua_isstring(obj)) /* get strings and numbers */
155 return lua_getstring(obj); 170 return lua_getstring(obj);
156 else switch(lua_type(obj)) 171 else if (lua_istable(obj))
157 { 172 return "<table>";
158 case LUA_T_FUNCTION: 173 else if (lua_isfunction(obj))
159 sprintf(buff, "function: %p", (luaI_Address(obj))->value.tf); 174 return "<function>";
160 break; 175 else if (lua_isnil(obj))
161 case LUA_T_CFUNCTION: 176 return "nil";
162 sprintf(buff, "cfunction: %p", lua_getcfunction(obj)); 177 else /* if (lua_isuserdata(obj)) */
163 break; 178 return "<userdata>";
164 case LUA_T_ARRAY:
165 sprintf(buff, "table: %p", avalue(luaI_Address(obj)));
166 break;
167 case LUA_T_NIL:
168 sprintf(buff, "nil");
169 break;
170 default:
171 sprintf(buff, "userdata: %p", lua_getuserdata(obj));
172 break;
173 }
174 return buff;
175} 179}
176 180
177void luaI_tostring (void) 181static void luaI_tostring (void)
178{ 182{
179 lua_pushstring(tostring(lua_getparam(1))); 183 lua_pushstring(tostring(lua_getparam(1)));
180} 184}
181 185
182void luaI_print (void) 186static void luaI_print (void)
183{ 187{
184 int i = 1; 188 int i = 1;
185 lua_Object obj; 189 lua_Object obj;
@@ -190,42 +194,35 @@ void luaI_print (void)
190/* 194/*
191** Internal function: return an object type. 195** Internal function: return an object type.
192*/ 196*/
193void luaI_type (void) 197static void luaI_type (void)
194{ 198{
195 lua_Object o = lua_getparam(1); 199 lua_Object o = lua_getparam(1);
196 int t; 200 int t = lua_tag(o);
197 if (o == LUA_NOOBJECT) 201 char *s;
202 if (t == LUA_T_NUMBER)
203 s = "number";
204 else if (lua_isstring(o))
205 s = "string";
206 else if (lua_istable(o))
207 s = "table";
208 else if (lua_isnil(o))
209 s = "nil";
210 else if (lua_isfunction(o))
211 s = "function";
212 else if (lua_isuserdata(o))
213 s = "userdata";
214 else {
198 lua_error("no parameter to function 'type'"); 215 lua_error("no parameter to function 'type'");
199 t = lua_type(o); 216 return; /* to avoid warnings */
200 switch (t)
201 {
202 case LUA_T_NIL :
203 lua_pushliteral("nil");
204 break;
205 case LUA_T_NUMBER :
206 lua_pushliteral("number");
207 break;
208 case LUA_T_STRING :
209 lua_pushliteral("string");
210 break;
211 case LUA_T_ARRAY :
212 lua_pushliteral("table");
213 break;
214 case LUA_T_FUNCTION :
215 case LUA_T_CFUNCTION :
216 lua_pushliteral("function");
217 break;
218 default :
219 lua_pushliteral("userdata");
220 break;
221 } 217 }
218 lua_pushliteral(s);
222 lua_pushnumber(t); 219 lua_pushnumber(t);
223} 220}
224 221
225/* 222/*
226** Internal function: convert an object to a number 223** Internal function: convert an object to a number
227*/ 224*/
228void lua_obj2number (void) 225static void lua_obj2number (void)
229{ 226{
230 lua_Object o = lua_getparam(1); 227 lua_Object o = lua_getparam(1);
231 if (lua_isnumber(o)) 228 if (lua_isnumber(o))
@@ -233,39 +230,36 @@ void lua_obj2number (void)
233} 230}
234 231
235 232
236void luaI_error (void) 233static void luaI_error (void)
237{ 234{
238 char *s = lua_getstring(lua_getparam(1)); 235 char *s = lua_getstring(lua_getparam(1));
239 if (s == NULL) s = "(no message)"; 236 if (s == NULL) s = "(no message)";
240 lua_error(s); 237 lua_error(s);
241} 238}
242 239
243void luaI_assert (void) 240static void luaI_assert (void)
244{ 241{
245 lua_Object p = lua_getparam(1); 242 lua_Object p = lua_getparam(1);
246 if (p == LUA_NOOBJECT || lua_isnil(p)) 243 if (p == LUA_NOOBJECT || lua_isnil(p))
247 lua_error("assertion failed!"); 244 lua_error("assertion failed!");
248} 245}
249 246
250void luaI_setglobal (void) 247static void luaI_setglobal (void)
251{ 248{
252 lua_Object name = lua_getparam(1);
253 lua_Object value = lua_getparam(2); 249 lua_Object value = lua_getparam(2);
254 check_arg(lua_isstring(name), "setglobal"); 250 check_arg(value != LUA_NOOBJECT, "setglobal");
255 lua_pushobject(value); 251 lua_pushobject(value);
256 lua_storeglobal(lua_getstring(name)); 252 lua_storeglobal(check_string(1, "setglobal"));
257 lua_pushobject(value); /* return given value */ 253 lua_pushobject(value); /* return given value */
258} 254}
259 255
260void luaI_getglobal (void) 256static void luaI_getglobal (void)
261{ 257{
262 lua_Object name = lua_getparam(1); 258 lua_pushobject(lua_getglobal(check_string(1, "getglobal")));
263 check_arg(lua_isstring(name), "getglobal");
264 lua_pushobject(lua_getglobal(lua_getstring(name)));
265} 259}
266 260
267#define MAXPARAMS 256 261#define MAXPARAMS 256
268void luaI_call (void) 262static void luaI_call (void)
269{ 263{
270 lua_Object f = lua_getparam(1); 264 lua_Object f = lua_getparam(1);
271 lua_Object arg = lua_getparam(2); 265 lua_Object arg = lua_getparam(2);
@@ -298,3 +292,86 @@ void luaI_call (void)
298 else 292 else
299 passresults(); 293 passresults();
300} 294}
295
296static void luaIl_settag (void)
297{
298 lua_Object o = lua_getparam(1);
299 check_arg(o != LUA_NOOBJECT, "settag");
300 lua_pushobject(o);
301 lua_settag(check_number(2, "settag"));
302}
303
304static void luaIl_newtag (void)
305{
306 lua_pushnumber(lua_newtag(check_string(1, "newtag")));
307}
308
309static void basicindex (void)
310{
311 lua_Object t = lua_getparam(1);
312 lua_Object i = lua_getparam(2);
313 check_arg(t != LUA_NOOBJECT && i != LUA_NOOBJECT, "basicindex");
314 lua_pushobject(t);
315 lua_pushobject(i);
316 lua_pushobject(lua_basicindex());
317}
318
319static void basicstoreindex (void)
320{
321 lua_Object t = lua_getparam(1);
322 lua_Object i = lua_getparam(2);
323 lua_Object v = lua_getparam(3);
324 check_arg(t != LUA_NOOBJECT && i != LUA_NOOBJECT && v != LUA_NOOBJECT,
325 "basicindex");
326 lua_pushobject(t);
327 lua_pushobject(i);
328 lua_pushobject(v);
329 lua_basicstoreindex();
330}
331
332
333
334/*
335** Internal functions
336*/
337static struct {
338 char *name;
339 lua_CFunction func;
340} int_funcs[] = {
341 {"assert", luaI_assert},
342 {"call", luaI_call},
343 {"basicindex", basicindex},
344 {"basicstoreindex", basicstoreindex},
345 {"settag", luaIl_settag},
346 {"dofile", lua_internaldofile},
347 {"dostring", lua_internaldostring},
348 {"error", luaI_error},
349 {"getglobal", luaI_getglobal},
350 {"next", lua_next},
351 {"nextvar", luaI_nextvar},
352 {"newtag", luaIl_newtag},
353 {"print", luaI_print},
354 {"setfallback", luaI_setfallback},
355 {"setintmethod", luaI_setintmethod},
356 {"setglobal", luaI_setglobal},
357 {"tonumber", lua_obj2number},
358 {"tostring", luaI_tostring},
359 {"type", luaI_type}
360};
361
362#define INTFUNCSIZE (sizeof(int_funcs)/sizeof(int_funcs[0]))
363
364
365void luaI_predefine (void)
366{
367 int i;
368 Word n;
369 for (i=0; i<INTFUNCSIZE; i++) {
370 n = luaI_findsymbolbyname(int_funcs[i].name);
371 s_tag(n) = LUA_T_CFUNCTION; s_fvalue(n) = int_funcs[i].func;
372 }
373 n = luaI_findsymbolbyname("_VERSION_");
374 s_tag(n) = LUA_T_STRING; s_tsvalue(n) = lua_createstring(LUA_VERSION);
375}
376
377
diff --git a/inout.h b/inout.h
index ee359089..1e544143 100644
--- a/inout.h
+++ b/inout.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: inout.h,v 1.15 1996/03/15 18:21:58 roberto Exp roberto $ 2** $Id: inout.h,v 1.16 1996/05/28 21:07:32 roberto Exp roberto $
3*/ 3*/
4 4
5 5
@@ -19,16 +19,6 @@ void lua_closefile (void);
19void lua_openstring (char *s); 19void lua_openstring (char *s);
20void lua_closestring (void); 20void lua_closestring (void);
21 21
22void lua_internaldofile (void); 22void luaI_predefine (void);
23void lua_internaldostring (void);
24void luaI_tostring (void);
25void luaI_print (void);
26void luaI_type (void);
27void lua_obj2number (void);
28void luaI_error (void);
29void luaI_assert (void);
30void luaI_setglobal (void);
31void luaI_getglobal (void);
32void luaI_call (void);
33 23
34#endif 24#endif
diff --git a/lua.h b/lua.h
index e656134e..623465e1 100644
--- a/lua.h
+++ b/lua.h
@@ -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.33 1997/02/11 11:40:01 roberto Exp roberto $ 5** $Id: lua.h,v 3.34 1997/02/20 15:51:14 roberto Exp roberto $
6*/ 6*/
7 7
8 8
@@ -19,13 +19,19 @@
19typedef void (*lua_CFunction) (void); 19typedef void (*lua_CFunction) (void);
20typedef unsigned int lua_Object; 20typedef unsigned int lua_Object;
21 21
22lua_Object lua_setfallback (char *name, lua_CFunction fallback); 22lua_Object lua_setfallback (char *event, lua_CFunction fallback);
23void lua_setintmethod (int tag, char *event, lua_CFunction method);
24
25int lua_newtag (char *t);
26void lua_settag (int tag); /* In: object */
23 27
24void lua_error (char *s); 28void lua_error (char *s);
25int lua_dofile (char *filename); 29int lua_dofile (char *filename); /* Out: returns */
26int lua_dostring (char *string); 30int lua_dostring (char *string); /* Out: returns */
27int lua_callfunction (lua_Object function); 31int lua_callfunction (lua_Object f);
32 /* In: parameters; Out: returns */
28int lua_call (char *funcname); 33int lua_call (char *funcname);
34 /* In: parameters; Out: returns */
29 35
30void lua_beginblock (void); 36void lua_beginblock (void);
31void lua_endblock (void); 37void lua_endblock (void);
@@ -56,15 +62,17 @@ void lua_pushusertag (void *u, int tag);
56void lua_pushobject (lua_Object object); 62void lua_pushobject (lua_Object object);
57 63
58lua_Object lua_getglobal (char *name); 64lua_Object lua_getglobal (char *name);
59void lua_storeglobal (char *name); 65void lua_storeglobal (char *name); /* In: value */
60 66
61void lua_storesubscript (void); 67void lua_storesubscript (void); /* In: table, index, value */
62lua_Object lua_getsubscript (void); 68void lua_basicstoreindex (void); /* In: table, index, value */
69lua_Object lua_getsubscript (void); /* In: table, index */
70lua_Object lua_basicindex (void); /* In: table, index */
63 71
64int lua_type (lua_Object object); 72int lua_tag (lua_Object object);
65 73
66 74
67int lua_ref (int lock); 75int lua_ref (int lock); /* In: value */
68lua_Object lua_getref (int ref); 76lua_Object lua_getref (int ref);
69void lua_pushref (int ref); 77void lua_pushref (int ref);
70void lua_unref (int ref); 78void lua_unref (int ref);
@@ -84,6 +92,8 @@ lua_Object lua_createtable (void);
84 92
85/* for compatibility with old versions. Avoid using these macros */ 93/* for compatibility with old versions. Avoid using these macros */
86 94
95#define lua_type(o) (lua_tag(o))
96
87#define lua_getuserdata(o) (*(void **)lua_getbinarydata(o)) 97#define lua_getuserdata(o) (*(void **)lua_getbinarydata(o))
88 98
89#define lua_lockobject(o) lua_refobject(o,1) 99#define lua_lockobject(o) lua_refobject(o,1)
diff --git a/opcode.c b/opcode.c
index c089dccb..919b2059 100644
--- a/opcode.c
+++ b/opcode.c
@@ -3,7 +3,7 @@
3** TecCGraf - PUC-Rio 3** TecCGraf - PUC-Rio
4*/ 4*/
5 5
6char *rcs_opcode="$Id: opcode.c,v 3.80 1997/02/11 11:35:05 roberto Exp roberto $"; 6char *rcs_opcode="$Id: opcode.c,v 3.81 1997/02/20 15:51:14 roberto Exp roberto $";
7 7
8#include <setjmp.h> 8#include <setjmp.h>
9#include <stdio.h> 9#include <stdio.h>
@@ -261,15 +261,20 @@ static StkId callC (lua_CFunction func, StkId base)
261 return firstResult; 261 return firstResult;
262} 262}
263 263
264static void callIM (Object *f, int nParams, int nResults)
265{
266 open_stack(nParams);
267 *(top-nParams-1) = *f;
268 do_call((top-stack)-nParams, nResults);
269}
270
264/* 271/*
265** Call the specified fallback, putting it on the stack below its arguments 272** Call the specified fallback, putting it on the stack below its arguments
266*/ 273*/
267static void callFB (int fb) 274static void callFB (int fb)
268{ 275{
269 int nParams = luaI_fallBacks[fb].nParams; 276 callIM(&luaI_fallBacks[fb].function, luaI_fallBacks[fb].nParams,
270 open_stack(nParams); 277 luaI_fallBacks[fb].nResults);
271 *(top-nParams-1) = luaI_fallBacks[fb].function;
272 do_call((top-stack)-nParams, luaI_fallBacks[fb].nResults);
273} 278}
274 279
275 280
@@ -320,35 +325,77 @@ static void do_call (StkId base, int nResults)
320*/ 325*/
321static void pushsubscript (void) 326static void pushsubscript (void)
322{ 327{
328 int tg = luaI_tag(top-2);
329 Object *im = luaI_getim(tg, FB_GETTABLE);
330 if (tag(top-2) == LUA_T_ARRAY && im == NULL) {
331 Object *h = lua_hashget(avalue(top-2), top-1);
332 if (h != NULL && tag(h) != LUA_T_NIL) {
333 --top;
334 *(top-1) = *h;
335 }
336 else if (tg == LUA_T_ARRAY &&
337 (im=luaI_getim(0, FB_INDEX)) != NULL)
338 callIM(im, 2, 1);
339 else {
340 --top;
341 tag(top-1) = LUA_T_NIL;
342 }
343 }
344 else { /* object is not a table, and/or has a specific "gettable" method */
345 if (im)
346 callIM(im, 2, 1);
347 else
348 lua_error("indexed expression not a table");
349 }
350}
351
352
353lua_Object lua_basicindex (void)
354{
355 adjustC(2);
323 if (tag(top-2) != LUA_T_ARRAY) 356 if (tag(top-2) != LUA_T_ARRAY)
324 callFB(FB_GETTABLE); 357 lua_error("indexed expression not a table in basic indexing");
325 else 358 else {
326 {
327 Object *h = lua_hashget(avalue(top-2), top-1); 359 Object *h = lua_hashget(avalue(top-2), top-1);
328 if (h == NULL || tag(h) == LUA_T_NIL) 360 --top;
329 callFB(FB_INDEX); 361 if (h != NULL)
330 else
331 {
332 --top;
333 *(top-1) = *h; 362 *(top-1) = *h;
334 } 363 else
364 tag(top-1) = LUA_T_NIL;
335 } 365 }
366 CLS_current.base++; /* incorporate object in the stack */
367 return (Ref(top-1));
336} 368}
337 369
338 370
339/* 371/*
340** Function to store indexed based on values at the top 372** Function to store indexed based on values at the top
373** mode = 0: basic store (without internal methods)
374** mode = 1: normal store (with internal methods)
375** mode = 2: "deep stack" store (with internal methods)
341*/ 376*/
342static void storesubscript (void) 377static void storesubscript (Object *t, int mode)
343{ 378{
344 if (tag(top-3) != LUA_T_ARRAY) 379 Object *im = (mode == 0) ? NULL : luaI_getim(luaI_tag(t), FB_SETTABLE);
345 callFB(FB_SETTABLE); 380 if (tag(t) == LUA_T_ARRAY && im == NULL) {
346 else 381 Object *h = lua_hashdefine(avalue(t), t+1);
347 { 382 *h = *(top-1);
348 Object *h = lua_hashdefine (avalue(top-3), top-2); 383 top -= (mode == 2) ? 1 : 3;
349 *h = *(top-1); 384 }
350 top -= 3; 385 else { /* object is not a table, and/or has a specific "settable" method */
351 } 386 if (im) {
387 if (mode == 2) {
388 lua_checkstack(top+2);
389 *(top+1) = *(top-1);
390 *(top) = *(t+1);
391 *(top-1) = *t;
392 top += 2;
393 }
394 callIM(im, 3, 0);
395 }
396 else
397 lua_error("indexed expression not a table");
398 }
352} 399}
353 400
354 401
@@ -450,6 +497,26 @@ int lua_setlocal (lua_Function func, int local_number)
450 return 0; 497 return 0;
451} 498}
452 499
500/*
501** Call the function at CLS_current.base, and incorporate results on
502** the Lua2C structure.
503*/
504static void do_callinc (int nResults)
505{
506 do_call(CLS_current.base+1, nResults);
507 CLS_current.num = (top-stack) - CLS_current.base; /* number of results */
508 CLS_current.base += CLS_current.num; /* incorporate results on the stack */
509}
510
511static void do_unprotectedrun (lua_CFunction f, int nParams, int nResults)
512{
513 adjustC(nParams);
514 open_stack((top-stack)-CLS_current.base);
515 stack[CLS_current.base].tag = LUA_T_CFUNCTION;
516 stack[CLS_current.base].value.f = f;
517 do_callinc(nResults);
518}
519
453 520
454/* 521/*
455** Execute a protected call. Assumes that function is at CLS_current.base and 522** Execute a protected call. Assumes that function is at CLS_current.base and
@@ -462,15 +529,11 @@ static int do_protectedrun (int nResults)
462 struct C_Lua_Stack oldCLS = CLS_current; 529 struct C_Lua_Stack oldCLS = CLS_current;
463 jmp_buf *oldErr = errorJmp; 530 jmp_buf *oldErr = errorJmp;
464 errorJmp = &myErrorJmp; 531 errorJmp = &myErrorJmp;
465 if (setjmp(myErrorJmp) == 0) 532 if (setjmp(myErrorJmp) == 0) {
466 { 533 do_callinc(nResults);
467 do_call(CLS_current.base+1, nResults);
468 CLS_current.num = (top-stack) - CLS_current.base; /* number of results */
469 CLS_current.base += CLS_current.num; /* incorporate results on the stack */
470 status = 0; 534 status = 0;
471 } 535 }
472 else 536 else { /* an error occurred: restore CLS_current and top */
473 { /* an error occurred: restore CLS_current and top */
474 CLS_current = oldCLS; 537 CLS_current = oldCLS;
475 top = stack+CLS_current.base; 538 top = stack+CLS_current.base;
476 status = 1; 539 status = 1;
@@ -586,15 +649,18 @@ int lua_dostring (char *str)
586*/ 649*/
587lua_Object lua_setfallback (char *name, lua_CFunction fallback) 650lua_Object lua_setfallback (char *name, lua_CFunction fallback)
588{ 651{
589 adjustC(1); /* one slot for the pseudo-function */
590 stack[CLS_current.base].tag = LUA_T_CFUNCTION;
591 stack[CLS_current.base].value.f = luaI_setfallback;
592 lua_pushstring(name); 652 lua_pushstring(name);
593 lua_pushcfunction(fallback); 653 lua_pushcfunction(fallback);
594 if (do_protectedrun(1) == 0) 654 do_unprotectedrun(luaI_setfallback, 2, 1);
595 return (Ref(top-1)); 655 return (Ref(top-1));
596 else 656}
597 return LUA_NOOBJECT; 657
658void lua_setintmethod (int tag, char *event, lua_CFunction method)
659{
660 lua_pushnumber(tag);
661 lua_pushstring(event);
662 lua_pushcfunction (method);
663 do_unprotectedrun(luaI_setintmethod, 3, 0);
598} 664}
599 665
600 666
@@ -637,13 +703,25 @@ void lua_endblock (void)
637 adjustC(0); 703 adjustC(0);
638} 704}
639 705
706void lua_settag (int tag)
707{
708 adjustC(1);
709 luaI_settag(tag, --top);
710}
711
640/* 712/*
641** API: receives on the stack the table, the index, and the new value. 713** API: receives on the stack the table, the index, and the new value.
642*/ 714*/
643void lua_storesubscript (void) 715void lua_storesubscript (void)
644{ 716{
645 adjustC(3); 717 adjustC(3);
646 storesubscript(); 718 storesubscript(top-3, 1);
719}
720
721void lua_basicstoreindex (void)
722{
723 adjustC(3);
724 storesubscript(top-3, 0);
647} 725}
648 726
649/* 727/*
@@ -688,7 +766,7 @@ int lua_isuserdata (lua_Object o)
688 766
689int lua_iscfunction (lua_Object o) 767int lua_iscfunction (lua_Object o)
690{ 768{
691 int t = lua_type(o); 769 int t = lua_tag(o);
692 return (t == LUA_T_CMARK) || (t == LUA_T_CFUNCTION); 770 return (t == LUA_T_CMARK) || (t == LUA_T_CFUNCTION);
693} 771}
694 772
@@ -699,13 +777,13 @@ int lua_isnumber (lua_Object o)
699 777
700int lua_isstring (lua_Object o) 778int lua_isstring (lua_Object o)
701{ 779{
702 int t = lua_type(o); 780 int t = lua_tag(o);
703 return (t == LUA_T_STRING) || (t == LUA_T_NUMBER); 781 return (t == LUA_T_STRING) || (t == LUA_T_NUMBER);
704} 782}
705 783
706int lua_isfunction (lua_Object o) 784int lua_isfunction (lua_Object o)
707{ 785{
708 int t = lua_type(o); 786 int t = lua_tag(o);
709 return (t == LUA_T_FUNCTION) || (t == LUA_T_CFUNCTION) || 787 return (t == LUA_T_FUNCTION) || (t == LUA_T_CFUNCTION) ||
710 (t == LUA_T_MARK) || (t == LUA_T_CMARK); 788 (t == LUA_T_MARK) || (t == LUA_T_CMARK);
711} 789}
@@ -893,16 +971,9 @@ void lua_pushobject (lua_Object o)
893 incr_top; 971 incr_top;
894} 972}
895 973
896int lua_type (lua_Object o) 974int lua_tag (lua_Object o)
897{ 975{
898 if (o == LUA_NOOBJECT) 976 return (o == LUA_NOOBJECT) ? LUA_T_NIL : luaI_tag(Address(o));
899 return LUA_T_NIL;
900 else {
901 lua_Type t = tag(Address(o));
902 if (t == LUA_T_USERDATA)
903 return (Address(o))->value.ts->tag;
904 else return t;
905 }
906} 977}
907 978
908 979
@@ -1085,29 +1156,14 @@ static StkId lua_execute (Byte *pc, StkId base)
1085 break; 1156 break;
1086 1157
1087 case STOREINDEXED0: 1158 case STOREINDEXED0:
1088 storesubscript(); 1159 storesubscript(top-3, 1);
1089 break; 1160 break;
1090 1161
1091 case STOREINDEXED: 1162 case STOREINDEXED: {
1092 { 1163 int n = *pc++;
1093 int n = *pc++; 1164 storesubscript(top-3-n, 2);
1094 if (tag(top-3-n) != LUA_T_ARRAY) 1165 break;
1095 {
1096 lua_checkstack(top+2);
1097 *(top+1) = *(top-1);
1098 *(top) = *(top-2-n);
1099 *(top-1) = *(top-3-n);
1100 top += 2;
1101 callFB(FB_SETTABLE);
1102 }
1103 else
1104 {
1105 Object *h = lua_hashdefine (avalue(top-3-n), top-2-n);
1106 *h = *(top-1);
1107 top--;
1108 }
1109 } 1166 }
1110 break;
1111 1167
1112 case STORELIST0: 1168 case STORELIST0:
1113 case STORELIST: 1169 case STORELIST:
diff --git a/table.c b/table.c
index 8af20ccc..5fc85f3d 100644
--- a/table.c
+++ b/table.c
@@ -3,7 +3,7 @@
3** Module to control static tables 3** Module to control static tables
4*/ 4*/
5 5
6char *rcs_table="$Id: table.c,v 2.57 1996/07/12 20:00:26 roberto Exp roberto $"; 6char *rcs_table="$Id: table.c,v 2.58 1996/11/01 12:47:45 roberto Exp roberto $";
7 7
8#include "mem.h" 8#include "mem.h"
9#include "opcode.h" 9#include "opcode.h"
@@ -29,47 +29,12 @@ static Long lua_maxconstant = 0;
29 29
30#define GARBAGE_BLOCK 50 30#define GARBAGE_BLOCK 50
31 31
32static void lua_nextvar (void);
33
34/*
35** Internal functions
36*/
37static struct {
38 char *name;
39 lua_CFunction func;
40} int_funcs[] = {
41 {"assert", luaI_assert},
42 {"call", luaI_call},
43 {"dofile", lua_internaldofile},
44 {"dostring", lua_internaldostring},
45 {"error", luaI_error},
46 {"getglobal", luaI_getglobal},
47 {"next", lua_next},
48 {"nextvar", lua_nextvar},
49 {"print", luaI_print},
50 {"setfallback", luaI_setfallback},
51 {"setglobal", luaI_setglobal},
52 {"tonumber", lua_obj2number},
53 {"tostring", luaI_tostring},
54 {"type", luaI_type}
55};
56
57#define INTFUNCSIZE (sizeof(int_funcs)/sizeof(int_funcs[0]))
58
59 32
60void luaI_initsymbol (void) 33void luaI_initsymbol (void)
61{ 34{
62 int i;
63 Word n;
64 lua_maxsymbol = BUFFER_BLOCK; 35 lua_maxsymbol = BUFFER_BLOCK;
65 lua_table = newvector(lua_maxsymbol, Symbol); 36 lua_table = newvector(lua_maxsymbol, Symbol);
66 for (i=0; i<INTFUNCSIZE; i++) 37 luaI_predefine();
67 {
68 n = luaI_findsymbolbyname(int_funcs[i].name);
69 s_tag(n) = LUA_T_CFUNCTION; s_fvalue(n) = int_funcs[i].func;
70 }
71 n = luaI_findsymbolbyname("_VERSION_");
72 s_tag(n) = LUA_T_STRING; s_tsvalue(n) = lua_createstring(LUA_VERSION);
73} 38}
74 39
75 40
@@ -225,7 +190,7 @@ void lua_pack (void)
225/* 190/*
226** Internal function: return next global variable 191** Internal function: return next global variable
227*/ 192*/
228static void lua_nextvar (void) 193void luaI_nextvar (void)
229{ 194{
230 Word next; 195 Word next;
231 lua_Object o = lua_getparam(1); 196 lua_Object o = lua_getparam(1);
diff --git a/table.h b/table.h
index bfe1a6be..42d44c07 100644
--- a/table.h
+++ b/table.h
@@ -1,7 +1,7 @@
1/* 1/*
2** Module to control static tables 2** Module to control static tables
3** TeCGraf - PUC-Rio 3** TeCGraf - PUC-Rio
4** $Id: table.h,v 2.20 1996/03/14 15:57:19 roberto Exp roberto $ 4** $Id: table.h,v 2.21 1996/04/22 18:00:37 roberto Exp roberto $
5*/ 5*/
6 6
7#ifndef table_h 7#ifndef table_h
@@ -28,6 +28,7 @@ Word luaI_findsymbolbyname (char *name);
28Word luaI_findsymbol (TaggedString *t); 28Word luaI_findsymbol (TaggedString *t);
29Word luaI_findconstant (TaggedString *t); 29Word luaI_findconstant (TaggedString *t);
30Word luaI_findconstantbyname (char *name); 30Word luaI_findconstantbyname (char *name);
31void luaI_nextvar (void);
31TaggedString *luaI_createfixedstring (char *str); 32TaggedString *luaI_createfixedstring (char *str);
32int lua_markobject (Object *o); 33int lua_markobject (Object *o);
33int luaI_ismarked (Object *o); 34int luaI_ismarked (Object *o);