2 ** $Id: lbuiltin.c,v 1.32 1998/06/29 18:24:06 roberto Exp $
4 ** See Copyright Notice in lua.h
29 static void pushstring (TaggedString
*s
)
32 o
.ttype
= LUA_T_STRING
;
38 static void nextvar (void)
40 TObject
*o
= luaA_Address(luaL_nonnullarg(1));
42 if (ttype(o
) == LUA_T_NIL
)
43 g
= (TaggedString
*)L
->rootglobal
.next
;
45 luaL_arg_check(ttype(o
) == LUA_T_STRING
, 1, "variable name expected");
47 /* check whether name is in global var list */
48 luaL_arg_check((GCnode
*)g
!= g
->head
.next
, 1, "variable name expected");
49 g
= (TaggedString
*)g
->head
.next
;
51 while (g
&& g
->u
.s
.globalval
.ttype
== LUA_T_NIL
) /* skip globals with nil */
52 g
= (TaggedString
*)g
->head
.next
;
55 luaA_pushobject(&g
->u
.s
.globalval
);
61 static void foreachvar (void)
63 TObject f
= *luaA_Address(luaL_functionarg(1));
65 StkId name
= L
->Cstack
.base
++; /* place to keep var name (to avoid GC) */
66 ttype(L
->stack
.stack
+name
) = LUA_T_NIL
;
68 for (g
= L
->rootglobal
.next
; g
; g
= g
->next
) {
69 TaggedString
*s
= (TaggedString
*)g
;
70 if (s
->u
.s
.globalval
.ttype
!= LUA_T_NIL
) {
71 ttype(L
->stack
.stack
+name
) = LUA_T_STRING
;
72 tsvalue(L
->stack
.stack
+name
) = s
; /* keep s on stack to avoid GC */
75 luaA_pushobject(&s
->u
.s
.globalval
);
76 luaD_call((L
->stack
.top
-L
->stack
.stack
)-2, 1);
77 if (ttype(L
->stack
.top
-1) != LUA_T_NIL
)
85 static void next (void)
87 lua_Object o
= luaL_tablearg(1);
88 lua_Object r
= luaL_nonnullarg(2);
89 Node
*n
= luaH_next(luaA_Address(o
), luaA_Address(r
));
91 luaA_pushobject(&n
->ref
);
92 luaA_pushobject(&n
->val
);
98 static void foreach (void)
100 TObject t
= *luaA_Address(luaL_tablearg(1));
101 TObject f
= *luaA_Address(luaL_functionarg(2));
103 for (i
=0; i
<avalue(&t
)->nhash
; i
++) {
104 Node
*nd
= &(avalue(&t
)->node
[i
]);
105 if (ttype(ref(nd
)) != LUA_T_NIL
&& ttype(val(nd
)) != LUA_T_NIL
) {
107 luaA_pushobject(ref(nd
));
108 luaA_pushobject(val(nd
));
109 luaD_call((L
->stack
.top
-L
->stack
.stack
)-2, 1);
110 if (ttype(L
->stack
.top
-1) != LUA_T_NIL
)
118 static void internaldostring (void)
121 char *s
= luaL_check_lstr(1, &l
);
123 lua_error("`dostring' cannot run pre-compiled code");
124 if (lua_dobuffer(s
, l
, luaL_opt_string(2, NULL
)) == 0)
125 if (luaA_passresults() == 0)
126 lua_pushuserdata(NULL
); /* at least one result to signal no errors */
130 static void internaldofile (void)
132 char *fname
= luaL_opt_string(1, NULL
);
133 if (lua_dofile(fname
) == 0)
134 if (luaA_passresults() == 0)
135 lua_pushuserdata(NULL
); /* at least one result to signal no errors */
139 static void to_string (void) {
140 lua_Object obj
= lua_getparam(1);
141 char *buff
= luaL_openspace(30);
142 TObject
*o
= luaA_Address(obj
);
145 lua_pushstring(lua_getstring(obj
));
151 sprintf(buff
, "table: %p", (void *)o
->value
.a
);
154 case LUA_T_CLOSURE
: {
155 sprintf(buff
, "function: %p", (void *)o
->value
.cl
);
159 sprintf(buff
, "function: %p", (void *)o
->value
.tf
);
163 sprintf(buff
, "function: %p", (void *)o
->value
.f
);
166 case LUA_T_USERDATA
: {
167 sprintf(buff
, "userdata: %p", o
->value
.ts
->u
.d
.v
);
171 lua_pushstring("nil");
174 LUA_INTERNALERROR("invalid type");
176 lua_pushstring(buff
);
180 static void luaI_print (void) {
181 TaggedString
*ts
= luaS_new("tostring");
184 while ((obj
= lua_getparam(i
++)) != LUA_NOOBJECT
) {
185 luaA_pushobject(&ts
->u
.s
.globalval
);
187 luaD_call((L
->stack
.top
-L
->stack
.stack
)-1, 1);
188 if (ttype(L
->stack
.top
-1) != LUA_T_STRING
)
189 lua_error("`tostring' must return a string to `print'");
190 printf("%s\t", svalue(L
->stack
.top
-1));
197 static void luaI_type (void)
199 lua_Object o
= luaL_nonnullarg(1);
200 lua_pushstring(luaO_typenames
[-ttype(luaA_Address(o
))]);
201 lua_pushnumber(lua_tag(o
));
205 static void tonumber (void)
207 int base
= luaL_opt_number(2, 10);
208 if (base
== 10) { /* standard conversion */
209 lua_Object o
= lua_getparam(1);
211 lua_pushnumber(lua_getnumber(o
));
214 char *s
= luaL_check_string(1);
216 luaL_arg_check(0 <= base
&& base
<= 36, 2, "base out of range");
217 n
= strtol(s
, &s
, base
);
218 while (isspace(*s
)) s
++; /* skip trailing spaces */
219 if (*s
) lua_pushnil(); /* invalid format: return nil */
220 else lua_pushnumber(n
);
225 static void luaI_error (void)
227 lua_error(lua_getstring(lua_getparam(1)));
231 static void luaI_assert (void)
233 lua_Object p
= lua_getparam(1);
234 if (p
== LUA_NOOBJECT
|| lua_isnil(p
))
235 luaL_verror("assertion failed! %.100s", luaL_opt_string(2, ""));
239 static void setglobal (void)
241 char *n
= luaL_check_string(1);
242 lua_Object value
= luaL_nonnullarg(2);
243 lua_pushobject(value
);
245 lua_pushobject(value
); /* return given value */
248 static void rawsetglobal (void)
250 char *n
= luaL_check_string(1);
251 lua_Object value
= luaL_nonnullarg(2);
252 lua_pushobject(value
);
254 lua_pushobject(value
); /* return given value */
257 static void getglobal (void)
259 lua_pushobject(lua_getglobal(luaL_check_string(1)));
262 static void rawgetglobal (void)
264 lua_pushobject(lua_rawgetglobal(luaL_check_string(1)));
267 static void luatag (void)
269 lua_pushnumber(lua_tag(lua_getparam(1)));
273 static int getnarg (lua_Object table
)
277 lua_pushobject(table
); lua_pushstring("n"); temp
= lua_rawgettable();
278 return (lua_isnumber(temp
) ? lua_getnumber(temp
) : MAX_INT
);
281 static void luaI_call (void)
283 lua_Object f
= luaL_nonnullarg(1);
284 lua_Object arg
= luaL_tablearg(2);
285 char *options
= luaL_opt_string(3, "");
286 lua_Object err
= lua_getparam(4);
287 int narg
= getnarg(arg
);
289 if (err
!= LUA_NOOBJECT
) { /* set new error method */
291 err
= lua_seterrormethod();
293 /* push arg[1...n] */
294 for (i
=0; i
<narg
; i
++) {
296 /* temp = arg[i+1] */
297 lua_pushobject(arg
); lua_pushnumber(i
+1); temp
= lua_rawgettable();
298 if (narg
== MAX_INT
&& lua_isnil(temp
))
300 lua_pushobject(temp
);
302 status
= lua_callfunction(f
);
303 if (err
!= LUA_NOOBJECT
) { /* restore old error method */
305 lua_seterrormethod();
307 if (status
!= 0) { /* error in call? */
308 if (strchr(options
, 'x')) {
310 return; /* return nil to signal the error */
315 else { /* no errors */
316 if (strchr(options
, 'p'))
324 static void settag (void)
326 lua_Object o
= luaL_tablearg(1);
328 lua_settag(luaL_check_number(2));
329 lua_pushobject(o
); /* returns first argument */
333 static void newtag (void)
335 lua_pushnumber(lua_newtag());
339 static void copytagmethods (void)
341 lua_pushnumber(lua_copytagmethods(luaL_check_number(1),
342 luaL_check_number(2)));
346 static void rawgettable (void)
348 lua_pushobject(luaL_nonnullarg(1));
349 lua_pushobject(luaL_nonnullarg(2));
350 lua_pushobject(lua_rawgettable());
354 static void rawsettable (void)
356 lua_pushobject(luaL_nonnullarg(1));
357 lua_pushobject(luaL_nonnullarg(2));
358 lua_pushobject(luaL_nonnullarg(3));
363 static void settagmethod (void)
365 lua_Object nf
= luaL_nonnullarg(3);
367 lua_pushobject(lua_settagmethod((int)luaL_check_number(1),
368 luaL_check_string(2)));
372 static void gettagmethod (void)
374 lua_pushobject(lua_gettagmethod((int)luaL_check_number(1),
375 luaL_check_string(2)));
379 static void seterrormethod (void)
381 lua_Object nf
= luaL_functionarg(1);
383 lua_pushobject(lua_seterrormethod());
387 static void luaI_collectgarbage (void)
389 lua_pushnumber(lua_collectgarbage(luaL_opt_number(1, 0)));
394 ** =======================================================
395 ** some DEBUG functions
396 ** =======================================================
400 static void mem_query (void)
402 lua_pushnumber(totalmem
);
403 lua_pushnumber(numblocks
);
407 static void countlist (void)
409 char *s
= luaL_check_string(1);
410 GCnode
*l
= (s
[0]=='t') ? L
->roottable
.next
: (s
[0]=='c') ? L
->rootcl
.next
:
411 (s
[0]=='p') ? L
->rootproto
.next
: L
->rootglobal
.next
;
421 static void testC (void)
423 #define getnum(s) ((*s++) - '0')
424 #define getname(s) (nome[0] = *s++, nome)
426 static int locks
[10];
429 char *s
= luaL_check_string(1);
433 case '0': case '1': case '2': case '3': case '4':
434 case '5': case '6': case '7': case '8': case '9':
435 lua_pushnumber(*(s
-1) - '0');
438 case 'c': reg
[getnum(s
)] = lua_createtable(); break;
439 case 'C': { lua_CFunction f
= lua_getcfunction(lua_getglobal(getname(s
)));
440 lua_pushcclosure(f
, getnum(s
));
443 case 'P': reg
[getnum(s
)] = lua_pop(); break;
444 case 'g': { int n
=getnum(s
); reg
[n
]=lua_getglobal(getname(s
)); break; }
445 case 'G': { int n
= getnum(s
);
446 reg
[n
] = lua_rawgetglobal(getname(s
));
449 case 'l': locks
[getnum(s
)] = lua_ref(1); break;
450 case 'L': locks
[getnum(s
)] = lua_ref(0); break;
451 case 'r': { int n
=getnum(s
); reg
[n
]=lua_getref(locks
[getnum(s
)]); break; }
452 case 'u': lua_unref(locks
[getnum(s
)]); break;
453 case 'p': { int n
= getnum(s
); reg
[n
] = lua_getparam(getnum(s
)); break; }
454 case '=': lua_setglobal(getname(s
)); break;
455 case 's': lua_pushstring(getname(s
)); break;
456 case 'o': lua_pushobject(reg
[getnum(s
)]); break;
457 case 'f': (lua_call
)(getname(s
)); break;
458 case 'i': reg
[getnum(s
)] = lua_gettable(); break;
459 case 'I': reg
[getnum(s
)] = lua_rawgettable(); break;
460 case 't': lua_settable(); break;
461 case 'T': lua_rawsettable(); break;
462 default: luaL_verror("unknown command in `testC': %c", *(s
-1));
465 if (*s
++ != ' ') lua_error("missing ` ' between commands in `testC'");
473 ** Internal functions
475 static struct luaL_reg int_funcs
[] = {
477 {"setfallback", luaT_setfallback
},
481 {"totalmem", mem_query
},
482 {"count", countlist
},
484 {"assert", luaI_assert
},
486 {"collectgarbage", luaI_collectgarbage
},
487 {"dofile", internaldofile
},
488 {"copytagmethods", copytagmethods
},
489 {"dostring", internaldostring
},
490 {"error", luaI_error
},
491 {"foreach", foreach
},
492 {"foreachvar", foreachvar
},
493 {"getglobal", getglobal
},
496 {"nextvar", nextvar
},
497 {"print", luaI_print
},
498 {"rawgetglobal", rawgetglobal
},
499 {"rawgettable", rawgettable
},
500 {"rawsetglobal", rawsetglobal
},
501 {"rawsettable", rawsettable
},
502 {"seterrormethod", seterrormethod
},
503 {"setglobal", setglobal
},
504 {"settagmethod", settagmethod
},
505 {"gettagmethod", gettagmethod
},
507 {"tonumber", tonumber
},
508 {"tostring", to_string
},
514 #define INTFUNCSIZE (sizeof(int_funcs)/sizeof(int_funcs[0]))
517 void luaB_predefine (void)
519 /* pre-register mem error messages, to avoid loop when error arises */
520 luaS_newfixedstring(tableEM
);
521 luaS_newfixedstring(memEM
);
522 luaL_openlib(int_funcs
, (sizeof(int_funcs
)/sizeof(int_funcs
[0])));
523 lua_pushstring(LUA_VERSION
);
524 lua_setglobal("_VERSION");