aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lbuiltin.c573
1 files changed, 312 insertions, 261 deletions
diff --git a/lbuiltin.c b/lbuiltin.c
index d72a320d..574e5fae 100644
--- a/lbuiltin.c
+++ b/lbuiltin.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lbuiltin.c,v 1.38 1998/12/15 15:21:09 roberto Exp $ 2** $Id: lbuiltin.c,v 1.38 1998/12/15 15:21:09 roberto Exp roberto $
3** Built-in functions 3** Built-in functions
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -27,6 +27,13 @@
27 27
28 28
29 29
30/*
31** =======================================================
32** Auxliliar functions
33** =======================================================
34*/
35
36
30static void pushstring (TaggedString *s) { 37static void pushstring (TaggedString *s) {
31 TObject o; 38 TObject o;
32 o.ttype = LUA_T_STRING; 39 o.ttype = LUA_T_STRING;
@@ -35,22 +42,23 @@ static void pushstring (TaggedString *s) {
35} 42}
36 43
37 44
38static int getsize (TObject *t) { 45static real getsize (TObject *t) {
39 int max = 0; 46 real max = 0;
40 int i; 47 int i;
41 Hash *h = avalue(t); 48 Hash *h = avalue(t);
42 LUA_ASSERT(ttype(t) == LUA_T_ARRAY, "table expected"); 49 LUA_ASSERT(ttype(t) == LUA_T_ARRAY, "table expected");
43 for (i = 0; i<nhash(h); i++) { 50 for (i = 0; i<nhash(h); i++) {
44 Node *n = h->node+i; 51 Node *n = h->node+i;
45 if (ttype(ref(n)) == LUA_T_NUMBER && ttype(val(n)) != LUA_T_NIL && 52 if (ttype(ref(n)) == LUA_T_NUMBER &&
46 (int)nvalue(ref(n)) > max) 53 ttype(val(n)) != LUA_T_NIL &&
54 nvalue(ref(n)) > max)
47 max = nvalue(ref(n)); 55 max = nvalue(ref(n));
48 } 56 }
49 return max; 57 return max;
50} 58}
51 59
52 60
53static int getnarg (lua_Object table) { 61static real getnarg (lua_Object table) {
54 lua_Object temp; 62 lua_Object temp;
55 /* temp = table.n */ 63 /* temp = table.n */
56 lua_pushobject(table); lua_pushstring("n"); temp = lua_rawgettable(); 64 lua_pushobject(table); lua_pushstring("n"); temp = lua_rawgettable();
@@ -64,201 +72,66 @@ static void luaB_getn (void) {
64} 72}
65 73
66 74
67static void luaB_nextvar (void) {
68 TObject *o = luaA_Address(luaL_nonnullarg(1));
69 TaggedString *g;
70 if (ttype(o) == LUA_T_NIL)
71 g = (TaggedString *)L->rootglobal.next; /* first variable */
72 else {
73 luaL_arg_check(ttype(o) == LUA_T_STRING, 1, "variable name expected");
74 g = tsvalue(o); /* find given variable name */
75 /* check whether name is in global var list */
76 luaL_arg_check((GCnode *)g != g->head.next, 1, "variable name expected");
77 g = (TaggedString *)g->head.next; /* get next */
78 }
79 while (g && g->u.s.globalval.ttype == LUA_T_NIL) /* skip globals with nil */
80 g = (TaggedString *)g->head.next;
81 if (g) {
82 pushstring(g);
83 luaA_pushobject(&g->u.s.globalval);
84 }
85 else lua_pushnil(); /* no more globals */
86}
87
88
89static void luaB_foreachvar (void) {
90 TObject f = *luaA_Address(luaL_functionarg(1));
91 GCnode *g;
92 StkId name = L->Cstack.base++; /* place to keep var name (to avoid GC) */
93 luaD_checkstack(4); /* for var name, f, s, and globalvar */
94 ttype(L->stack.stack+name) = LUA_T_NIL;
95 L->stack.top++; /* top == base */
96 for (g = L->rootglobal.next; g; g = g->next) {
97 TaggedString *s = (TaggedString *)g;
98 if (s->u.s.globalval.ttype != LUA_T_NIL) {
99 ttype(L->stack.stack+name) = LUA_T_STRING;
100 tsvalue(L->stack.stack+name) = s; /* keep s on stack to avoid GC */
101 *(L->stack.top++) = f;
102 pushstring(s);
103 *(L->stack.top++) = s->u.s.globalval;
104 luaD_calln(2, 1);
105 if (ttype(L->stack.top-1) != LUA_T_NIL)
106 return;
107 L->stack.top--;
108 }
109 }
110}
111
112
113static void luaB_next (void) {
114 Node *n = luaH_next(luaA_Address(luaL_tablearg(1)),
115 luaA_Address(luaL_nonnullarg(2)));
116 if (n) {
117 luaA_pushobject(&n->ref);
118 luaA_pushobject(&n->val);
119 }
120 else lua_pushnil();
121}
122
123
124static void luaB_foreach (void) {
125 TObject t = *luaA_Address(luaL_tablearg(1));
126 TObject f = *luaA_Address(luaL_functionarg(2));
127 int i;
128 luaD_checkstack(3); /* for f, ref, and val */
129 for (i=0; i<avalue(&t)->nhash; i++) {
130 Node *nd = &(avalue(&t)->node[i]);
131 if (ttype(ref(nd)) != LUA_T_NIL && ttype(val(nd)) != LUA_T_NIL) {
132 *(L->stack.top++) = f;
133 *(L->stack.top++) = *ref(nd);
134 *(L->stack.top++) = *val(nd);
135 luaD_calln(2, 1);
136 if (ttype(L->stack.top-1) != LUA_T_NIL)
137 return;
138 L->stack.top--;
139 }
140 }
141}
142
143
144static void luaB_foreachi (void) {
145 lua_Object ot = luaL_tablearg(1);
146 Hash *t = avalue(luaA_Address(ot));
147 TObject f = *luaA_Address(luaL_functionarg(2));
148 int i;
149 int n = getnarg(ot);
150 luaD_checkstack(3); /* for f, ref, and val */
151 for (i=1; i<=n; i++) {
152 *(L->stack.top++) = f;
153 ttype(L->stack.top) = LUA_T_NUMBER;
154 nvalue(L->stack.top++) = i;
155 *(L->stack.top++) = *luaH_getint(t, i);
156 luaD_calln(2, 1);
157 if (ttype(L->stack.top-1) != LUA_T_NIL)
158 return;
159 L->stack.top--;
160 }
161}
162
163 75
164static void luaB_dostring (void) { 76/*
165 long l; 77** =======================================================
166 char *s = luaL_check_lstr(1, &l); 78** Functions that use only the official API
167 if (*s == ID_CHUNK) 79** =======================================================
168 lua_error("`dostring' cannot run pre-compiled code"); 80*/
169 if (lua_dobuffer(s, l, luaL_opt_string(2, NULL)) == 0)
170 if (luaA_passresults() == 0)
171 lua_pushuserdata(NULL); /* at least one result to signal no errors */
172}
173 81
174 82
175static void luaB_dofile (void) { 83/*
176 char *fname = luaL_opt_string(1, NULL); 84** If your system does not support "stderr", remove this function and
177 if (lua_dofile(fname) == 0) 85** define your own "_ALERT" function. You *must* have an _ALERT function
178 if (luaA_passresults() == 0) 86** defined for Lua to work properly.
179 lua_pushuserdata(NULL); /* at least one result to signal no errors */ 87*/
88static void luaB_alert (void) {
89 fputs(luaL_check_string(1), stderr);
180} 90}
181 91
182 92
183static void luaB_tostring (void) { 93/*
184 lua_Object obj = lua_getparam(1); 94** Standard implementation of _ERRORMESSAGE.
185 TObject *o = luaA_Address(obj); 95** The library "iolib" redefines _ERRORMESSAGE for better error information.
186 char buff[32]; 96*/
187 switch (ttype(o)) { 97static void error_message (void) {
188 case LUA_T_NUMBER: 98 char buff[600];
189 lua_pushstring(lua_getstring(obj)); 99 sprintf(buff, "lua error: %.500s\n", luaL_check_string(1));
190 return;
191 case LUA_T_STRING:
192 lua_pushobject(obj);
193 return;
194 case LUA_T_ARRAY: {
195 sprintf(buff, "table: %p", (void *)o->value.a);
196 break;
197 }
198 case LUA_T_CLOSURE: {
199 sprintf(buff, "function: %p", (void *)o->value.cl);
200 break;
201 }
202 case LUA_T_PROTO: {
203 sprintf(buff, "function: %p", (void *)o->value.tf);
204 break;
205 }
206 case LUA_T_CPROTO: {
207 sprintf(buff, "function: %p", (void *)o->value.f);
208 break;
209 }
210 case LUA_T_USERDATA: {
211 sprintf(buff, "userdata: %p", o->value.ts->u.d.v);
212 break;
213 }
214 case LUA_T_NIL:
215 lua_pushstring("nil");
216 return;
217 default:
218 LUA_INTERNALERROR("invalid type");
219 }
220 lua_pushstring(buff); 100 lua_pushstring(buff);
101 lua_call("_ALERT");
221} 102}
222 103
223 104
105/*
106** If your system does not support "stdout", just remove this function.
107** If you need, you can define your own "print" function, following this
108** model but changing "fputs" to put the strings at a proper place
109** (a console window or a log file, for instance).
110*/
111#define MAXPRINT 40
224static void luaB_print (void) { 112static void luaB_print (void) {
225 TaggedString *ts = luaS_new("tostring"); 113 lua_Object args[MAXPRINT];
226 lua_Object obj; 114 lua_Object obj;
227 int i = 1; 115 int n = 0;
228 while ((obj = lua_getparam(i++)) != LUA_NOOBJECT) { 116 int i;
229 luaA_pushobject(&ts->u.s.globalval); 117 while ((obj = lua_getparam(n+1)) != LUA_NOOBJECT) {
230 lua_pushobject(obj); 118 luaL_arg_check(n < MAXPRINT, n+1, "too many arguments");
231 luaD_calln(1, 1); 119 args[n++] = obj;
232 if (ttype(L->stack.top-1) != LUA_T_STRING) 120 }
121 for (i=0; i<n; i++) {
122 lua_pushobject(args[i]);
123 if (lua_call("tostring"))
124 lua_error("error in `tostring' called by `print'");
125 obj = lua_getresult(1);
126 if (!lua_isstring(obj))
233 lua_error("`tostring' must return a string to `print'"); 127 lua_error("`tostring' must return a string to `print'");
234 if (i>2) fputs("\t", stdout); 128 if (i>0) fputs("\t", stdout);
235 fputs(svalue(L->stack.top-1), stdout); 129 fputs(lua_getstring(obj), stdout);
236 L->stack.top--;
237 } 130 }
238 fputs("\n", stdout); 131 fputs("\n", stdout);
239} 132}
240 133
241 134
242static void luaB_message (void) {
243 fputs(luaL_check_string(1), stderr);
244}
245
246
247static void error_message (void) {
248 char buff[200];
249 sprintf(buff, "lua error: %.180s\n", luaL_check_string(1));
250 lua_pushstring(buff);
251 lua_call("_ALERT");
252}
253
254
255static void luaB_type (void) {
256 lua_Object o = luaL_nonnullarg(1);
257 lua_pushstring(luaO_typename(luaA_Address(o)));
258 lua_pushnumber(lua_tag(o));
259}
260
261
262static void luaB_tonumber (void) { 135static void luaB_tonumber (void) {
263 int base = luaL_opt_number(2, 10); 136 int base = luaL_opt_number(2, 10);
264 if (base == 10) { /* standard conversion */ 137 if (base == 10) { /* standard conversion */
@@ -282,14 +155,6 @@ static void luaB_error (void) {
282 lua_error(lua_getstring(lua_getparam(1))); 155 lua_error(lua_getstring(lua_getparam(1)));
283} 156}
284 157
285
286static void luaB_assert (void) {
287 lua_Object p = lua_getparam(1);
288 if (p == LUA_NOOBJECT || lua_isnil(p))
289 luaL_verror("assertion failed! %.100s", luaL_opt_string(2, ""));
290}
291
292
293static void luaB_setglobal (void) { 158static void luaB_setglobal (void) {
294 char *n = luaL_check_string(1); 159 char *n = luaL_check_string(1);
295 lua_Object value = luaL_nonnullarg(2); 160 lua_Object value = luaL_nonnullarg(2);
@@ -318,44 +183,6 @@ static void luaB_luatag (void) {
318 lua_pushnumber(lua_tag(lua_getparam(1))); 183 lua_pushnumber(lua_tag(lua_getparam(1)));
319} 184}
320 185
321
322static void luaB_call (void) {
323 lua_Object f = luaL_nonnullarg(1);
324 lua_Object arg = luaL_tablearg(2);
325 char *options = luaL_opt_string(3, "");
326 lua_Object err = lua_getparam(4);
327 int narg = getnarg(arg);
328 int i, status;
329 if (err != LUA_NOOBJECT) { /* set new error method */
330 lua_pushobject(err);
331 err = lua_seterrormethod();
332 }
333 /* push arg[1...n] */
334 luaD_checkstack(narg);
335 for (i=0; i<narg; i++)
336 *(L->stack.top++) = *luaH_getint(avalue(luaA_Address(arg)), i+1);
337 status = lua_callfunction(f);
338 if (err != LUA_NOOBJECT) { /* restore old error method */
339 lua_pushobject(err);
340 lua_seterrormethod();
341 }
342 if (status != 0) { /* error in call? */
343 if (strchr(options, 'x')) {
344 lua_pushnil();
345 return; /* return nil to signal the error */
346 }
347 else
348 lua_error(NULL);
349 }
350 else { /* no errors */
351 if (strchr(options, 'p'))
352 luaA_packresults();
353 else
354 luaA_passresults();
355 }
356}
357
358
359static void luaB_settag (void) { 186static void luaB_settag (void) {
360 lua_Object o = luaL_tablearg(1); 187 lua_Object o = luaL_tablearg(1);
361 lua_pushobject(o); 188 lua_pushobject(o);
@@ -363,25 +190,21 @@ static void luaB_settag (void) {
363 lua_pushobject(o); /* returns first argument */ 190 lua_pushobject(o); /* returns first argument */
364} 191}
365 192
366
367static void luaB_newtag (void) { 193static void luaB_newtag (void) {
368 lua_pushnumber(lua_newtag()); 194 lua_pushnumber(lua_newtag());
369} 195}
370 196
371
372static void luaB_copytagmethods (void) { 197static void luaB_copytagmethods (void) {
373 lua_pushnumber(lua_copytagmethods(luaL_check_number(1), 198 lua_pushnumber(lua_copytagmethods(luaL_check_number(1),
374 luaL_check_number(2))); 199 luaL_check_number(2)));
375} 200}
376 201
377
378static void luaB_rawgettable (void) { 202static void luaB_rawgettable (void) {
379 lua_pushobject(luaL_nonnullarg(1)); 203 lua_pushobject(luaL_nonnullarg(1));
380 lua_pushobject(luaL_nonnullarg(2)); 204 lua_pushobject(luaL_nonnullarg(2));
381 lua_pushobject(lua_rawgettable()); 205 lua_pushobject(lua_rawgettable());
382} 206}
383 207
384
385static void luaB_rawsettable (void) { 208static void luaB_rawsettable (void) {
386 lua_pushobject(luaL_nonnullarg(1)); 209 lua_pushobject(luaL_nonnullarg(1));
387 lua_pushobject(luaL_nonnullarg(2)); 210 lua_pushobject(luaL_nonnullarg(2));
@@ -389,7 +212,6 @@ static void luaB_rawsettable (void) {
389 lua_rawsettable(); 212 lua_rawsettable();
390} 213}
391 214
392
393static void luaB_settagmethod (void) { 215static void luaB_settagmethod (void) {
394 lua_Object nf = luaL_nonnullarg(3); 216 lua_Object nf = luaL_nonnullarg(3);
395 lua_pushobject(nf); 217 lua_pushobject(nf);
@@ -397,26 +219,171 @@ static void luaB_settagmethod (void) {
397 luaL_check_string(2))); 219 luaL_check_string(2)));
398} 220}
399 221
400
401static void luaB_gettagmethod (void) { 222static void luaB_gettagmethod (void) {
402 lua_pushobject(lua_gettagmethod((int)luaL_check_number(1), 223 lua_pushobject(lua_gettagmethod((int)luaL_check_number(1),
403 luaL_check_string(2))); 224 luaL_check_string(2)));
404} 225}
405 226
406
407static void luaB_seterrormethod (void) { 227static void luaB_seterrormethod (void) {
408 lua_Object nf = luaL_functionarg(1); 228 lua_Object nf = luaL_functionarg(1);
409 lua_pushobject(nf); 229 lua_pushobject(nf);
410 lua_pushobject(lua_seterrormethod()); 230 lua_pushobject(lua_seterrormethod());
411} 231}
412 232
413
414static void luaB_collectgarbage (void) { 233static void luaB_collectgarbage (void) {
415 lua_pushnumber(lua_collectgarbage(luaL_opt_number(1, 0))); 234 lua_pushnumber(lua_collectgarbage(luaL_opt_number(1, 0)));
416} 235}
417 236
418 237
419 238
239/*
240** =======================================================
241** Functions that could use only the official API but
242** do not, for efficiency.
243** =======================================================
244*/
245
246static void luaB_dostring (void) {
247 long l;
248 char *s = luaL_check_lstr(1, &l);
249 if (*s == ID_CHUNK)
250 lua_error("`dostring' cannot run pre-compiled code");
251 if (lua_dobuffer(s, l, luaL_opt_string(2, NULL)) == 0)
252 if (luaA_passresults() == 0)
253 lua_pushuserdata(NULL); /* at least one result to signal no errors */
254}
255
256
257static void luaB_dofile (void) {
258 char *fname = luaL_opt_string(1, NULL);
259 if (lua_dofile(fname) == 0)
260 if (luaA_passresults() == 0)
261 lua_pushuserdata(NULL); /* at least one result to signal no errors */
262}
263
264
265static void luaB_call (void) {
266 lua_Object f = luaL_nonnullarg(1);
267 lua_Object arg = luaL_tablearg(2);
268 char *options = luaL_opt_string(3, "");
269 lua_Object err = lua_getparam(4);
270 int narg = (int)getnarg(arg);
271 int i, status;
272 if (err != LUA_NOOBJECT) { /* set new error method */
273 lua_pushobject(err);
274 err = lua_seterrormethod();
275 }
276 /* push arg[1...n] */
277 luaD_checkstack(narg);
278 for (i=0; i<narg; i++)
279 *(L->stack.top++) = *luaH_getint(avalue(luaA_Address(arg)), i+1);
280 status = lua_callfunction(f);
281 if (err != LUA_NOOBJECT) { /* restore old error method */
282 lua_pushobject(err);
283 lua_seterrormethod();
284 }
285 if (status != 0) { /* error in call? */
286 if (strchr(options, 'x')) {
287 lua_pushnil();
288 return; /* return nil to signal the error */
289 }
290 else
291 lua_error(NULL);
292 }
293 else { /* no errors */
294 if (strchr(options, 'p'))
295 luaA_packresults();
296 else
297 luaA_passresults();
298 }
299}
300
301
302
303/*
304** =======================================================
305** "Extra" functions
306** (These functions can be written in Lua, so you can
307** delete them if you need a tiny Lua implementation.)
308** =======================================================
309*/
310
311static void luaB_assert (void) {
312 lua_Object p = lua_getparam(1);
313 if (p == LUA_NOOBJECT || lua_isnil(p))
314 luaL_verror("assertion failed! %.100s", luaL_opt_string(2, ""));
315}
316
317
318static void luaB_foreachi (void) {
319 lua_Object ot = luaL_tablearg(1);
320 Hash *t = avalue(luaA_Address(ot));
321 TObject f = *luaA_Address(luaL_functionarg(2));
322 int i;
323 int n = (int)getnarg(ot);
324 luaD_checkstack(3); /* for f, ref, and val */
325 for (i=1; i<=n; i++) {
326 *(L->stack.top++) = f;
327 ttype(L->stack.top) = LUA_T_NUMBER;
328 nvalue(L->stack.top++) = i;
329 *(L->stack.top++) = *luaH_getint(t, i);
330 luaD_calln(2, 1);
331 if (ttype(L->stack.top-1) != LUA_T_NIL)
332 return;
333 L->stack.top--;
334 }
335}
336
337
338static void luaB_foreach (void) {
339 TObject t = *luaA_Address(luaL_tablearg(1));
340 TObject f = *luaA_Address(luaL_functionarg(2));
341 int i;
342 luaD_checkstack(3); /* for f, ref, and val */
343 for (i=0; i<avalue(&t)->nhash; i++) {
344 Node *nd = &(avalue(&t)->node[i]);
345 if (ttype(ref(nd)) != LUA_T_NIL && ttype(val(nd)) != LUA_T_NIL) {
346 *(L->stack.top++) = f;
347 *(L->stack.top++) = *ref(nd);
348 *(L->stack.top++) = *val(nd);
349 luaD_calln(2, 1);
350 if (ttype(L->stack.top-1) != LUA_T_NIL)
351 return;
352 L->stack.top--;
353 }
354 }
355}
356
357
358static void luaB_foreachvar (void) {
359 TObject f = *luaA_Address(luaL_functionarg(1));
360 GCnode *g;
361 StkId name = L->Cstack.base++; /* place to keep var name (to avoid GC) */
362 luaD_checkstack(4); /* for var name, f, s, and globalvar */
363 ttype(L->stack.stack+name) = LUA_T_NIL;
364 L->stack.top++; /* top == base */
365 for (g = L->rootglobal.next; g; g = g->next) {
366 TaggedString *s = (TaggedString *)g;
367 if (s->u.s.globalval.ttype != LUA_T_NIL) {
368 ttype(L->stack.stack+name) = LUA_T_STRING;
369 tsvalue(L->stack.stack+name) = s; /* keep s on stack to avoid GC */
370 *(L->stack.top++) = f;
371 pushstring(s);
372 *(L->stack.top++) = s->u.s.globalval;
373 luaD_calln(2, 1);
374 if (ttype(L->stack.top-1) != LUA_T_NIL)
375 return;
376 L->stack.top--;
377 }
378 }
379}
380
381
382
383/*
384** Quicksort algorithm from "Programming Pearls", pg. 112
385*/
386
420static void swap (Hash *a, int i, int j) { 387static void swap (Hash *a, int i, int j) {
421 /* notice: must use two temporary vars, because luaH_setint may cause a 388 /* notice: must use two temporary vars, because luaH_setint may cause a
422 rehash and change the addresses of values in the array */ 389 rehash and change the addresses of values in the array */
@@ -442,9 +409,6 @@ static int sort_comp (TObject *f, TObject *a, TObject *b) {
442 return ttype(--(L->stack.top)) != LUA_T_NIL; 409 return ttype(--(L->stack.top)) != LUA_T_NIL;
443} 410}
444 411
445/*
446** quicksort algorithm from "Programming Pearls", pg. 112
447*/
448static void auxsort (Hash *a, int l, int u, TObject *f) { 412static void auxsort (Hash *a, int l, int u, TObject *f) {
449 init: 413 init:
450 if (u <= l) return; /* 0 or 1 element */ 414 if (u <= l) return; /* 0 or 1 element */
@@ -466,7 +430,7 @@ static void auxsort (Hash *a, int l, int u, TObject *f) {
466 } 430 }
467 } 431 }
468 L->stack.top--; /* remove pivot from stack */ 432 L->stack.top--; /* remove pivot from stack */
469 swap(a, l, m); 433 swap(a, l, m); /* swap pivot with a[m] */
470 /* a[l..m-1] < a[m] <= a[m+1..u] */ 434 /* a[l..m-1] < a[m] <= a[m+1..u] */
471 if (m-l < u-m) { /* check which "half" is bigger */ 435 if (m-l < u-m) { /* check which "half" is bigger */
472 auxsort(a, l, m-1, f); /* call recursively the smaller one */ 436 auxsort(a, l, m-1, f); /* call recursively the smaller one */
@@ -481,7 +445,7 @@ static void auxsort (Hash *a, int l, int u, TObject *f) {
481 445
482static void luaB_sort (void) { 446static void luaB_sort (void) {
483 lua_Object t = luaL_tablearg(1); 447 lua_Object t = luaL_tablearg(1);
484 int n = getnarg(t); 448 int n = (int)getnarg(t);
485 Hash *a = avalue(luaA_Address(t)); 449 Hash *a = avalue(luaA_Address(t));
486 lua_Object func = lua_getparam(2); 450 lua_Object func = lua_getparam(2);
487 TObject *f = luaA_Address(func); 451 TObject *f = luaA_Address(func);
@@ -491,12 +455,100 @@ static void luaB_sort (void) {
491} 455}
492 456
493 457
458
494/* 459/*
495** ======================================================= 460** =======================================================
496** some DEBUG functions 461** Internal Functions.
462** These functions need access to internal structures
463** to be implemented.
497** ======================================================= 464** =======================================================
498*/ 465*/
466
467
468static void luaB_nextvar (void) {
469 TObject *o = luaA_Address(luaL_nonnullarg(1));
470 TaggedString *g;
471 if (ttype(o) == LUA_T_NIL)
472 g = (TaggedString *)L->rootglobal.next; /* first variable */
473 else {
474 luaL_arg_check(ttype(o) == LUA_T_STRING, 1, "variable name expected");
475 g = tsvalue(o); /* find given variable name */
476 /* check whether name is in global var list */
477 luaL_arg_check((GCnode *)g != g->head.next, 1, "variable name expected");
478 g = (TaggedString *)g->head.next; /* get next */
479 }
480 while (g && g->u.s.globalval.ttype == LUA_T_NIL) /* skip globals with nil */
481 g = (TaggedString *)g->head.next;
482 if (g) {
483 pushstring(g);
484 luaA_pushobject(&g->u.s.globalval);
485 }
486 else lua_pushnil(); /* no more globals */
487}
488
489
490static void luaB_next (void) {
491 Node *n = luaH_next(luaA_Address(luaL_tablearg(1)),
492 luaA_Address(luaL_nonnullarg(2)));
493 if (n) {
494 luaA_pushobject(&n->ref);
495 luaA_pushobject(&n->val);
496 }
497 else lua_pushnil();
498}
499
500
501static void luaB_tostring (void) {
502 lua_Object obj = lua_getparam(1);
503 TObject *o = luaA_Address(obj);
504 char buff[64];
505 switch (ttype(o)) {
506 case LUA_T_NUMBER:
507 lua_pushstring(lua_getstring(obj));
508 return;
509 case LUA_T_STRING:
510 lua_pushobject(obj);
511 return;
512 case LUA_T_ARRAY:
513 sprintf(buff, "table: %p", (void *)o->value.a);
514 break;
515 case LUA_T_CLOSURE:
516 sprintf(buff, "function: %p", (void *)o->value.cl);
517 break;
518 case LUA_T_PROTO:
519 sprintf(buff, "function: %p", (void *)o->value.tf);
520 break;
521 case LUA_T_CPROTO:
522 sprintf(buff, "function: %p", (void *)o->value.f);
523 break;
524 case LUA_T_USERDATA:
525 sprintf(buff, "userdata: %p", o->value.ts->u.d.v);
526 break;
527 case LUA_T_NIL:
528 lua_pushstring("nil");
529 return;
530 default:
531 LUA_INTERNALERROR("invalid type");
532 }
533 lua_pushstring(buff);
534}
535
536
537static void luaB_type (void) {
538 lua_Object o = luaL_nonnullarg(1);
539 lua_pushstring(luaO_typename(luaA_Address(o)));
540 lua_pushnumber(lua_tag(o));
541}
542
543
544
545
499#ifdef DEBUG 546#ifdef DEBUG
547/*
548** =======================================================
549** some DEBUG functions
550** =======================================================
551*/
500 552
501static void mem_query (void) { 553static void mem_query (void) {
502 lua_pushnumber(totalmem); 554 lua_pushnumber(totalmem);
@@ -567,10 +619,8 @@ static void testC (void) {
567#endif 619#endif
568 620
569 621
570/* 622
571** Internal functions 623static struct luaL_reg builtin_funcs[] = {
572*/
573static struct luaL_reg int_funcs[] = {
574#ifdef LUA_COMPAT2_5 624#ifdef LUA_COMPAT2_5
575 {"setfallback", luaT_setfallback}, 625 {"setfallback", luaT_setfallback},
576#endif 626#endif
@@ -579,19 +629,17 @@ static struct luaL_reg int_funcs[] = {
579 {"totalmem", mem_query}, 629 {"totalmem", mem_query},
580 {"count", countlist}, 630 {"count", countlist},
581#endif 631#endif
582 {"assert", luaB_assert}, 632 {"_ALERT", luaB_alert},
633 {"_ERRORMESSAGE", error_message},
583 {"call", luaB_call}, 634 {"call", luaB_call},
584 {"collectgarbage", luaB_collectgarbage}, 635 {"collectgarbage", luaB_collectgarbage},
585 {"dofile", luaB_dofile},
586 {"copytagmethods", luaB_copytagmethods}, 636 {"copytagmethods", luaB_copytagmethods},
637 {"dofile", luaB_dofile},
587 {"dostring", luaB_dostring}, 638 {"dostring", luaB_dostring},
588 {"error", luaB_error}, 639 {"error", luaB_error},
589 {"_ERRORMESSAGE", error_message},
590 {"foreach", luaB_foreach},
591 {"foreachi", luaB_foreachi},
592 {"foreachvar", luaB_foreachvar},
593 {"getn", luaB_getn},
594 {"getglobal", luaB_getglobal}, 640 {"getglobal", luaB_getglobal},
641 {"getn", luaB_getn},
642 {"gettagmethod", luaB_gettagmethod},
595 {"newtag", luaB_newtag}, 643 {"newtag", luaB_newtag},
596 {"next", luaB_next}, 644 {"next", luaB_next},
597 {"nextvar", luaB_nextvar}, 645 {"nextvar", luaB_nextvar},
@@ -602,26 +650,29 @@ static struct luaL_reg int_funcs[] = {
602 {"rawsettable", luaB_rawsettable}, 650 {"rawsettable", luaB_rawsettable},
603 {"seterrormethod", luaB_seterrormethod}, 651 {"seterrormethod", luaB_seterrormethod},
604 {"setglobal", luaB_setglobal}, 652 {"setglobal", luaB_setglobal},
605 {"settagmethod", luaB_settagmethod},
606 {"gettagmethod", luaB_gettagmethod},
607 {"settag", luaB_settag}, 653 {"settag", luaB_settag},
608 {"sort", luaB_sort}, 654 {"settagmethod", luaB_settagmethod},
655 {"tag", luaB_luatag},
609 {"tonumber", luaB_tonumber}, 656 {"tonumber", luaB_tonumber},
610 {"tostring", luaB_tostring}, 657 {"tostring", luaB_tostring},
611 {"tag", luaB_luatag},
612 {"type", luaB_type}, 658 {"type", luaB_type},
613 {"_ALERT", luaB_message} 659/* "Extra" functions */
660 {"assert", luaB_assert},
661 {"foreach", luaB_foreach},
662 {"foreachi", luaB_foreachi},
663 {"foreachvar", luaB_foreachvar},
664 {"sort", luaB_sort}
614}; 665};
615 666
616 667
617#define INTFUNCSIZE (sizeof(int_funcs)/sizeof(int_funcs[0])) 668#define INTFUNCSIZE (sizeof(builtin_funcs)/sizeof(builtin_funcs[0]))
618 669
619 670
620void luaB_predefine (void) { 671void luaB_predefine (void) {
621 /* pre-register mem error messages, to avoid loop when error arises */ 672 /* pre-register mem error messages, to avoid loop when error arises */
622 luaS_newfixedstring(tableEM); 673 luaS_newfixedstring(tableEM);
623 luaS_newfixedstring(memEM); 674 luaS_newfixedstring(memEM);
624 luaL_openlib(int_funcs, (sizeof(int_funcs)/sizeof(int_funcs[0]))); 675 luaL_openlib(builtin_funcs, (sizeof(builtin_funcs)/sizeof(builtin_funcs[0])));
625 lua_pushstring(LUA_VERSION); 676 lua_pushstring(LUA_VERSION);
626 lua_setglobal("_VERSION"); 677 lua_setglobal("_VERSION");
627} 678}