2 ** $Id: lapi.c,v 1.47 1999/06/22 20:37:23 roberto Exp $
4 ** See Copyright Notice in lua.h
27 char lua_ident
[] = "$Lua: " LUA_VERSION
" " LUA_COPYRIGHT
" $\n"
28 "$Authors: " LUA_AUTHORS
" $";
32 TObject
*luaA_Address (lua_Object o
) {
33 return (o
!= LUA_NOOBJECT
) ? Address(o
) : NULL
;
37 static lua_Type
normalized_type (TObject
*o
)
53 static void set_normalized (TObject
*d
, TObject
*s
)
56 d
->ttype
= normalized_type(s
);
60 static TObject
*luaA_protovalue (TObject
*o
)
62 return (normalized_type(o
) == LUA_T_CLOSURE
) ? protovalue(o
) : o
;
66 void luaA_packresults (void)
68 luaV_pack(L
->Cstack
.lua2C
, L
->Cstack
.num
, L
->stack
.top
);
73 int luaA_passresults (void) {
74 L
->Cstack
.base
= L
->Cstack
.lua2C
; /* position of first result */
79 static void checkCparams (int nParams
)
81 if (L
->stack
.top
-L
->stack
.stack
< L
->Cstack
.base
+nParams
)
82 lua_error("API error - wrong number of arguments in C2lua stack");
86 static lua_Object
put_luaObject (TObject
*o
) {
87 luaD_openstack((L
->stack
.top
-L
->stack
.stack
)-L
->Cstack
.base
);
88 L
->stack
.stack
[L
->Cstack
.base
++] = *o
;
89 return L
->Cstack
.base
; /* this is +1 real position (see Ref) */
93 static lua_Object
put_luaObjectonTop (void) {
94 luaD_openstack((L
->stack
.top
-L
->stack
.stack
)-L
->Cstack
.base
);
95 L
->stack
.stack
[L
->Cstack
.base
++] = *(--L
->stack
.top
);
96 return L
->Cstack
.base
; /* this is +1 real position (see Ref) */
100 static void top2LC (int n
) {
101 /* Put the 'n' elements on the top as the Lua2C contents */
102 L
->Cstack
.base
= (L
->stack
.top
-L
->stack
.stack
); /* new base */
103 L
->Cstack
.lua2C
= L
->Cstack
.base
-n
; /* position of the new results */
104 L
->Cstack
.num
= n
; /* number of results */
108 lua_Object
lua_pop (void) {
110 return put_luaObjectonTop();
115 ** Get a parameter, returning the object handle or LUA_NOOBJECT on error.
116 ** 'number' must be 1 to get the first parameter.
118 lua_Object
lua_lua2C (int number
)
120 if (number
<= 0 || number
> L
->Cstack
.num
) return LUA_NOOBJECT
;
121 /* Ref(L->stack.stack+(L->Cstack.lua2C+number-1)) ==
122 L->stack.stack+(L->Cstack.lua2C+number-1)-L->stack.stack+1 == */
123 return L
->Cstack
.lua2C
+number
;
127 int lua_callfunction (lua_Object function
)
129 if (function
== LUA_NOOBJECT
)
132 luaD_openstack((L
->stack
.top
-L
->stack
.stack
)-L
->Cstack
.base
);
133 set_normalized(L
->stack
.stack
+L
->Cstack
.base
, Address(function
));
134 return luaD_protectedrun();
139 lua_Object
lua_gettagmethod (int tag
, char *event
)
141 return put_luaObject(luaT_gettagmethod(tag
, event
));
145 lua_Object
lua_settagmethod (int tag
, char *event
)
148 luaT_settagmethod(tag
, event
, L
->stack
.top
-1);
149 return put_luaObjectonTop();
153 lua_Object
lua_seterrormethod (void) {
156 temp
= lua_getglobal("_ERRORMESSAGE");
157 lua_setglobal("_ERRORMESSAGE");
162 lua_Object
lua_gettable (void)
166 return put_luaObjectonTop();
170 lua_Object
lua_rawgettable (void) {
172 if (ttype(L
->stack
.top
-2) != LUA_T_ARRAY
)
173 lua_error("indexed expression not a table in rawgettable");
174 *(L
->stack
.top
-2) = *luaH_get(avalue(L
->stack
.top
-2), L
->stack
.top
-1);
176 return put_luaObjectonTop();
180 void lua_settable (void) {
182 luaV_settable(L
->stack
.top
-3);
183 L
->stack
.top
-= 2; /* pop table and index */
187 void lua_rawsettable (void) {
189 luaV_rawsettable(L
->stack
.top
-3);
193 lua_Object
lua_createtable (void)
197 avalue(&o
) = luaH_new(0);
198 ttype(&o
) = LUA_T_ARRAY
;
199 return put_luaObject(&o
);
203 lua_Object
lua_getglobal (char *name
)
205 luaD_checkstack(2); /* may need that to call T.M. */
206 luaV_getglobal(luaS_new(name
));
207 return put_luaObjectonTop();
211 lua_Object
lua_rawgetglobal (char *name
)
213 TaggedString
*ts
= luaS_new(name
);
214 return put_luaObject(&ts
->u
.s
.globalval
);
218 void lua_setglobal (char *name
)
221 luaD_checkstack(2); /* may need that to call T.M. */
222 luaV_setglobal(luaS_new(name
));
226 void lua_rawsetglobal (char *name
)
228 TaggedString
*ts
= luaS_new(name
);
230 luaS_rawsetglobal(ts
, --L
->stack
.top
);
235 int lua_isnil (lua_Object o
)
237 return (o
!= LUA_NOOBJECT
) && (ttype(Address(o
)) == LUA_T_NIL
);
240 int lua_istable (lua_Object o
)
242 return (o
!= LUA_NOOBJECT
) && (ttype(Address(o
)) == LUA_T_ARRAY
);
245 int lua_isuserdata (lua_Object o
)
247 return (o
!= LUA_NOOBJECT
) && (ttype(Address(o
)) == LUA_T_USERDATA
);
250 int lua_iscfunction (lua_Object o
)
252 return (lua_tag(o
) == LUA_T_CPROTO
);
255 int lua_isnumber (lua_Object o
)
257 return (o
!= LUA_NOOBJECT
) && (tonumber(Address(o
)) == 0);
260 int lua_isstring (lua_Object o
)
263 return (t
== LUA_T_STRING
) || (t
== LUA_T_NUMBER
);
266 int lua_isfunction (lua_Object o
)
269 return (t
== LUA_T_PROTO
) || (t
== LUA_T_CPROTO
);
273 double lua_getnumber (lua_Object object
)
275 if (object
== LUA_NOOBJECT
) return 0.0;
276 if (tonumber(Address(object
))) return 0.0;
277 else return (nvalue(Address(object
)));
280 char *lua_getstring (lua_Object object
)
282 luaC_checkGC(); /* "tostring" may create a new string */
283 if (object
== LUA_NOOBJECT
|| tostring(Address(object
)))
285 else return (svalue(Address(object
)));
288 long lua_strlen (lua_Object object
)
290 luaC_checkGC(); /* "tostring" may create a new string */
291 if (object
== LUA_NOOBJECT
|| tostring(Address(object
)))
293 else return (tsvalue(Address(object
))->u
.s
.len
);
296 void *lua_getuserdata (lua_Object object
)
298 if (object
== LUA_NOOBJECT
|| ttype(Address(object
)) != LUA_T_USERDATA
)
300 else return tsvalue(Address(object
))->u
.d
.v
;
303 lua_CFunction
lua_getcfunction (lua_Object object
)
305 if (!lua_iscfunction(object
))
307 else return fvalue(luaA_protovalue(Address(object
)));
311 void lua_pushnil (void)
313 ttype(L
->stack
.top
) = LUA_T_NIL
;
317 void lua_pushnumber (double n
)
319 ttype(L
->stack
.top
) = LUA_T_NUMBER
;
320 nvalue(L
->stack
.top
) = n
;
324 void lua_pushlstring (char *s
, long len
)
326 tsvalue(L
->stack
.top
) = luaS_newlstr(s
, len
);
327 ttype(L
->stack
.top
) = LUA_T_STRING
;
332 void lua_pushstring (char *s
)
337 lua_pushlstring(s
, strlen(s
));
340 void lua_pushcclosure (lua_CFunction fn
, int n
)
343 lua_error("API error - attempt to push a NULL Cfunction");
345 ttype(L
->stack
.top
) = LUA_T_CPROTO
;
346 fvalue(L
->stack
.top
) = fn
;
352 void lua_pushusertag (void *u
, int tag
)
354 if (tag
< 0 && tag
!= LUA_ANYTAG
)
355 luaT_realtag(tag
); /* error if tag is not valid */
356 tsvalue(L
->stack
.top
) = luaS_createudata(u
, tag
);
357 ttype(L
->stack
.top
) = LUA_T_USERDATA
;
362 void luaA_pushobject (TObject
*o
)
368 void lua_pushobject (lua_Object o
) {
369 if (o
== LUA_NOOBJECT
)
370 lua_error("API error - attempt to push a NOOBJECT");
371 set_normalized(L
->stack
.top
, Address(o
));
376 int lua_tag (lua_Object lo
)
378 if (lo
== LUA_NOOBJECT
)
381 TObject
*o
= Address(lo
);
383 switch (t
= ttype(o
)) {
385 return o
->value
.ts
->u
.d
.tag
;
387 return o
->value
.a
->htag
;
392 case LUA_T_CLOSURE
: case LUA_T_CLMARK
:
393 return o
->value
.cl
->consts
[0].ttype
;
396 LUA_INTERNALERROR("invalid type");
405 void lua_settag (int tag
)
409 switch (ttype(L
->stack
.top
-1)) {
411 (L
->stack
.top
-1)->value
.a
->htag
= tag
;
414 (L
->stack
.top
-1)->value
.ts
->u
.d
.tag
= tag
;
417 luaL_verror("cannot change the tag of a %.20s",
418 luaO_typename(L
->stack
.top
-1));
424 TaggedString
*luaA_nextvar (TaggedString
*g
) {
426 g
= (TaggedString
*)L
->rootglobal
.next
; /* first variable */
428 /* check whether name is in global var list */
429 luaL_arg_check((GCnode
*)g
!= g
->head
.next
, 1, "variable name expected");
430 g
= (TaggedString
*)g
->head
.next
; /* get next */
432 while (g
&& g
->u
.s
.globalval
.ttype
== LUA_T_NIL
) /* skip globals with nil */
433 g
= (TaggedString
*)g
->head
.next
;
435 ttype(L
->stack
.top
) = LUA_T_STRING
; tsvalue(L
->stack
.top
) = g
;
437 luaA_pushobject(&g
->u
.s
.globalval
);
443 char *lua_nextvar (char *varname
) {
444 TaggedString
*g
= (varname
== NULL
) ? NULL
: luaS_new(varname
);
457 int luaA_next (Hash
*t
, int i
) {
458 int tsize
= nhash(t
);
459 for (; i
<tsize
; i
++) {
460 Node
*n
= node(t
, i
);
461 if (ttype(val(n
)) != LUA_T_NIL
) {
462 luaA_pushobject(ref(n
));
463 luaA_pushobject(val(n
));
464 return i
+1; /* index to be used next time */
467 return 0; /* no more elements */
471 int lua_next (lua_Object o
, int i
) {
472 TObject
*t
= Address(o
);
473 if (ttype(t
) != LUA_T_ARRAY
)
474 lua_error("API error - object is not a table in `lua_next'");
475 i
= luaA_next(avalue(t
), i
);
476 top2LC((i
==0) ? 0 : 2);
483 ** {======================================================
484 ** To manipulate some state information
485 ** =======================================================
488 lua_State
*lua_setstate (lua_State
*st
) {
489 lua_State
*old
= lua_state
;
494 lua_LHFunction
lua_setlinehook (lua_LHFunction func
) {
495 lua_LHFunction old
= L
->linehook
;
500 lua_CHFunction
lua_setcallhook (lua_CHFunction func
) {
501 lua_CHFunction old
= L
->callhook
;
506 int lua_setdebug (int debug
) {
512 /* }====================================================== */
516 ** {======================================================
518 ** =======================================================
522 lua_Function
lua_stackedfunction (int level
)
525 for (i
= (L
->stack
.top
-1)-L
->stack
.stack
; i
>=0; i
--) {
526 int t
= L
->stack
.stack
[i
].ttype
;
527 if (t
== LUA_T_CLMARK
|| t
== LUA_T_PMARK
|| t
== LUA_T_CMARK
)
529 return Ref(L
->stack
.stack
+i
);
535 int lua_nups (lua_Function func
) {
536 TObject
*o
= luaA_Address(func
);
537 return (!o
|| normalized_type(o
) != LUA_T_CLOSURE
) ? 0 : o
->value
.cl
->nelems
;
541 int lua_currentline (lua_Function func
)
543 TObject
*f
= Address(func
);
544 return (f
+1 < L
->stack
.top
&& (f
+1)->ttype
== LUA_T_LINE
) ?
549 lua_Object
lua_getlocal (lua_Function func
, int local_number
, char **name
) {
550 /* check whether func is a Lua function */
551 if (lua_tag(func
) != LUA_T_PROTO
)
554 TObject
*f
= Address(func
);
555 TProtoFunc
*fp
= luaA_protovalue(f
)->value
.tf
;
556 *name
= luaF_getlocalname(fp
, local_number
, lua_currentline(func
));
558 /* if "*name", there must be a LUA_T_LINE */
559 /* therefore, f+2 points to function base */
560 return put_luaObject((f
+2)+(local_number
-1));
568 int lua_setlocal (lua_Function func
, int local_number
)
570 /* check whether func is a Lua function */
571 if (lua_tag(func
) != LUA_T_PROTO
)
574 TObject
*f
= Address(func
);
575 TProtoFunc
*fp
= luaA_protovalue(f
)->value
.tf
;
576 char *name
= luaF_getlocalname(fp
, local_number
, lua_currentline(func
));
580 /* if "name", there must be a LUA_T_LINE */
581 /* therefore, f+2 points to function base */
582 *((f
+2)+(local_number
-1)) = *L
->stack
.top
;
591 void lua_funcinfo (lua_Object func
, char **source
, int *linedefined
) {
592 if (!lua_isfunction(func
))
593 lua_error("API error - `funcinfo' called with a non-function value");
595 TObject
*f
= luaA_protovalue(Address(func
));
596 if (normalized_type(f
) == LUA_T_PROTO
) {
597 *source
= tfvalue(f
)->source
->str
;
598 *linedefined
= tfvalue(f
)->lineDefined
;
608 static int checkfunc (TObject
*o
)
610 return luaO_equalObj(o
, L
->stack
.top
);
614 char *lua_getobjname (lua_Object o
, char **name
)
615 { /* try to find a name for given function */
616 set_normalized(L
->stack
.top
, Address(o
)); /* to be accessed by "checkfunc" */
617 if ((*name
= luaS_travsymbol(checkfunc
)) != NULL
)
619 else if ((*name
= luaT_travtagmethods(checkfunc
)) != NULL
)
624 /* }====================================================== */
628 ** {======================================================
630 ** =======================================================
635 #define MAX_C_BLOCKS 1000 /* arbitrary limit */
639 void lua_beginblock (void) {
640 luaM_growvector(L
->Cblocks
, L
->numCblocks
, 1, struct C_Lua_Stack
,
641 "too many nested blocks", MAX_C_BLOCKS
);
642 L
->Cblocks
[L
->numCblocks
] = L
->Cstack
;
646 void lua_endblock (void) {
648 L
->Cstack
= L
->Cblocks
[L
->numCblocks
];
649 luaD_adjusttop(L
->Cstack
.base
);
654 int lua_ref (int lock
) {
657 ref
= luaC_ref(L
->stack
.top
-1, lock
);
664 lua_Object
lua_getref (int ref
) {
665 TObject
*o
= luaC_getref(ref
);
666 return (o
? put_luaObject(o
) : LUA_NOOBJECT
);
669 /* }====================================================== */
675 ** API: set a function as a fallback
678 static void do_unprotectedrun (lua_CFunction f
, int nParams
, int nResults
) {
679 luaD_openstack(nParams
);
680 (L
->stack
.top
-nParams
)->ttype
= LUA_T_CPROTO
;
681 (L
->stack
.top
-nParams
)->value
.f
= f
;
682 luaD_calln(nParams
, nResults
);
686 lua_Object
lua_setfallback (char *name
, lua_CFunction fallback
) {
687 lua_pushstring(name
);
688 lua_pushcfunction(fallback
);
689 do_unprotectedrun(luaT_setfallback
, 2, 1);
690 return put_luaObjectonTop();