mirror of
https://github.com/lua/lua.git
synced 2024-11-23 18:23:43 +08:00
first version for new API
This commit is contained in:
parent
f1fd9b5c2c
commit
9fdf73bc9a
504
lapi.c
504
lapi.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lapi.c,v 1.86 2000/08/09 19:16:57 roberto Exp roberto $
|
||||
** $Id: lapi.c,v 1.87 2000/08/14 19:10:14 roberto Exp roberto $
|
||||
** Lua API
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -16,7 +16,6 @@
|
||||
#include "lgc.h"
|
||||
#include "lmem.h"
|
||||
#include "lobject.h"
|
||||
#include "lref.h"
|
||||
#include "lstate.h"
|
||||
#include "lstring.h"
|
||||
#include "ltable.h"
|
||||
@ -29,246 +28,148 @@ const char lua_ident[] = "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n"
|
||||
|
||||
|
||||
|
||||
void luaA_checkCargs (lua_State *L, int nargs) {
|
||||
if (nargs > L->top-L->Cstack.base)
|
||||
luaL_verror(L, "Lua API error - "
|
||||
"expected at least %d arguments in C2lua stack", nargs);
|
||||
#define Index(L,i) ((i) >= 0 ? (L->Cbase+((i)-1)) : (L->top+(i)))
|
||||
|
||||
#define api_incr_top(L) (++L->top)
|
||||
|
||||
|
||||
|
||||
|
||||
TObject *luaA_index (lua_State *L, int index) {
|
||||
return Index(L, index);
|
||||
}
|
||||
|
||||
|
||||
lua_Object luaA_putluaObject (lua_State *L, const TObject *o) {
|
||||
luaD_openstack(L, L->Cstack.base);
|
||||
*L->Cstack.base++ = *o;
|
||||
return L->Cstack.base-1;
|
||||
}
|
||||
|
||||
|
||||
static void top2LC (lua_State *L, int n) {
|
||||
/* Put the `n' elements on the top as the Lua2C contents */
|
||||
L->Cstack.base = L->top; /* new base */
|
||||
L->Cstack.lua2C = L->Cstack.base-n; /* position of the new results */
|
||||
L->Cstack.num = n; /* number of results */
|
||||
}
|
||||
|
||||
|
||||
lua_Object lua_pop (lua_State *L) {
|
||||
luaA_checkCargs(L, 1);
|
||||
if (L->Cstack.base != L->top-1) {
|
||||
luaD_openstack(L, L->Cstack.base);
|
||||
*L->Cstack.base = *(--L->top);
|
||||
}
|
||||
return L->Cstack.base++;
|
||||
}
|
||||
|
||||
|
||||
void lua_pushglobals (lua_State *L) {
|
||||
hvalue(L->top) = L->gt;
|
||||
ttype(L->top) = TAG_TABLE;
|
||||
void luaA_pushobject (lua_State *L, const TObject *o) {
|
||||
*L->top = *o;
|
||||
incr_top;
|
||||
}
|
||||
|
||||
|
||||
void lua_setglobals (lua_State *L, lua_Object newtable) {
|
||||
if (lua_type(L, newtable)[0] != 't') /* type == "table"? */
|
||||
lua_error(L, "Lua API error - invalid value for global table");
|
||||
L->gt = hvalue(newtable);
|
||||
|
||||
/*
|
||||
** basic stack manipulation
|
||||
*/
|
||||
|
||||
|
||||
int lua_gettop (lua_State *L) {
|
||||
return (L->top - L->Cbase);
|
||||
}
|
||||
|
||||
|
||||
void lua_settop (lua_State *L, int index) {
|
||||
if (index >= 0)
|
||||
luaD_adjusttop(L, L->Cbase, index);
|
||||
else
|
||||
L->top += index; /* index is negative */
|
||||
}
|
||||
|
||||
|
||||
void lua_pushobject (lua_State *L, int index) {
|
||||
*L->top = *Index(L, index);
|
||||
api_incr_top(L);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** Get a parameter, returning the object handle or LUA_NOOBJECT on error.
|
||||
** `number' must be 1 to get the first parameter.
|
||||
** access functions (stack -> C)
|
||||
*/
|
||||
lua_Object lua_lua2C (lua_State *L, int number) {
|
||||
if (number <= 0 || number > L->Cstack.num) return LUA_NOOBJECT;
|
||||
return L->Cstack.lua2C+number-1;
|
||||
|
||||
|
||||
#define btest(L,i,value,default) { \
|
||||
StkId o; \
|
||||
if ((i) >= 0) { \
|
||||
o = L->Cbase+((i)-1); \
|
||||
if (o >= L->top) return (default); \
|
||||
} \
|
||||
else o = L->top+(i); \
|
||||
return (value); }
|
||||
|
||||
|
||||
#define access(L,i,test,default,value) { \
|
||||
StkId o; \
|
||||
if ((i) >= 0) { \
|
||||
o = L->Cbase+((i)-1); \
|
||||
if (o >= L->top) return (default); \
|
||||
} \
|
||||
else o = L->top+(i); \
|
||||
return ((test) ? (value) : (default)); }
|
||||
|
||||
|
||||
const char *lua_type (lua_State *L, int index) {
|
||||
btest(L, index, luaO_typename(o), "NO VALUE");
|
||||
}
|
||||
|
||||
int lua_iscfunction (lua_State *L, int index) {
|
||||
btest(L, index, (ttype(o) == TAG_CCLOSURE), 0);
|
||||
}
|
||||
|
||||
int lua_isnumber (lua_State *L, int index) {
|
||||
btest(L, index, (tonumber(Index(L, index)) == 0), 0);
|
||||
}
|
||||
|
||||
int lua_tag (lua_State *L, int index) {
|
||||
btest(L, index,
|
||||
((ttype(o) == TAG_USERDATA) ? tsvalue(o)->u.d.tag : luaT_effectivetag(L, o)),
|
||||
-1);
|
||||
}
|
||||
|
||||
int lua_equal(lua_State *L, int index1, int index2) {
|
||||
return luaO_equalObj(Index(L, index1), Index(L, index2));
|
||||
}
|
||||
|
||||
|
||||
int lua_callfunction (lua_State *L, lua_Object function) {
|
||||
if (function == LUA_NOOBJECT)
|
||||
return 1;
|
||||
else {
|
||||
luaD_openstack(L, L->Cstack.base);
|
||||
*L->Cstack.base = *function;
|
||||
return luaD_protectedrun(L);
|
||||
}
|
||||
|
||||
double lua_tonumber (lua_State *L, int index) {
|
||||
access(L, index, (tonumber(o) == 0), 0.0, nvalue(o));
|
||||
}
|
||||
|
||||
|
||||
lua_Object lua_gettagmethod (lua_State *L, int tag, const char *event) {
|
||||
return luaA_putluaObject(L, luaT_gettagmethod(L, tag, event));
|
||||
}
|
||||
|
||||
|
||||
lua_Object lua_settagmethod (lua_State *L, int tag, const char *event) {
|
||||
TObject *method;
|
||||
luaA_checkCargs(L, 1);
|
||||
method = L->top-1;
|
||||
if ((ttype(method) != TAG_NIL) && (*lua_type(L, method) != 'f'))
|
||||
lua_error(L, "Lua API error - tag method must be a function or nil");
|
||||
luaT_settagmethod(L, tag, event, method);
|
||||
return lua_pop(L);
|
||||
}
|
||||
|
||||
|
||||
lua_Object lua_gettable (lua_State *L) {
|
||||
luaA_checkCargs(L, 2);
|
||||
luaV_gettable(L, L->top--);
|
||||
return lua_pop(L);
|
||||
}
|
||||
|
||||
|
||||
lua_Object lua_rawget (lua_State *L) {
|
||||
lua_Object res;
|
||||
luaA_checkCargs(L, 2);
|
||||
if (ttype(L->top-2) != TAG_TABLE)
|
||||
lua_error(L, "indexed expression not a table");
|
||||
res = luaA_putluaObject(L, luaH_get(L, hvalue(L->top-2), L->top-1));
|
||||
L->top -= 2;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
void lua_settable (lua_State *L) {
|
||||
StkId top;
|
||||
luaA_checkCargs(L, 3);
|
||||
top = L->top;
|
||||
luaV_settable(L, top-3, top);
|
||||
L->top = top-3; /* pop table, index, and value */
|
||||
}
|
||||
|
||||
|
||||
void lua_rawset (lua_State *L) {
|
||||
luaA_checkCargs(L, 3);
|
||||
if (ttype(L->top-3) != TAG_TABLE)
|
||||
lua_error(L, "indexed expression not a table");
|
||||
*luaH_set(L, hvalue(L->top-3), L->top-2) = *(L->top-1);
|
||||
L->top -= 3;
|
||||
}
|
||||
|
||||
|
||||
lua_Object lua_createtable (lua_State *L) {
|
||||
TObject o;
|
||||
luaC_checkGC(L);
|
||||
hvalue(&o) = luaH_new(L, 0);
|
||||
ttype(&o) = TAG_TABLE;
|
||||
return luaA_putluaObject(L, &o);
|
||||
}
|
||||
|
||||
|
||||
lua_Object lua_getglobal (lua_State *L, const char *name) {
|
||||
luaV_getglobal(L, luaS_new(L, name), L->top++);
|
||||
return lua_pop(L);
|
||||
}
|
||||
|
||||
|
||||
void lua_setglobal (lua_State *L, const char *name) {
|
||||
luaA_checkCargs(L, 1);
|
||||
luaV_setglobal(L, luaS_new(L, name), L->top--);
|
||||
}
|
||||
|
||||
|
||||
const char *lua_type (lua_State *L, lua_Object o) {
|
||||
UNUSED(L);
|
||||
return (o == LUA_NOOBJECT) ? "NOOBJECT" : luaO_typename(o);
|
||||
}
|
||||
|
||||
int lua_isnil (lua_State *L, lua_Object o) {
|
||||
UNUSED(L);
|
||||
return (o != LUA_NOOBJECT) && (ttype(o) == TAG_NIL);
|
||||
}
|
||||
|
||||
int lua_istable (lua_State *L, lua_Object o) {
|
||||
UNUSED(L);
|
||||
return (o != LUA_NOOBJECT) && (ttype(o) == TAG_TABLE);
|
||||
}
|
||||
|
||||
int lua_isuserdata (lua_State *L, lua_Object o) {
|
||||
UNUSED(L);
|
||||
return (o != LUA_NOOBJECT) && (ttype(o) == TAG_USERDATA);
|
||||
}
|
||||
|
||||
int lua_iscfunction (lua_State *L, lua_Object o) {
|
||||
UNUSED(L);
|
||||
return (o != LUA_NOOBJECT) && (ttype(o) == TAG_CCLOSURE);
|
||||
}
|
||||
|
||||
int lua_isnumber (lua_State *L, lua_Object o) {
|
||||
UNUSED(L);
|
||||
return (o != LUA_NOOBJECT) && (tonumber(o) == 0);
|
||||
}
|
||||
|
||||
int lua_isstring (lua_State *L, lua_Object o) {
|
||||
UNUSED(L);
|
||||
return (o != LUA_NOOBJECT && (ttype(o) == TAG_STRING ||
|
||||
ttype(o) == TAG_NUMBER));
|
||||
}
|
||||
|
||||
int lua_isfunction (lua_State *L, lua_Object o) {
|
||||
return *lua_type(L, o) == 'f';
|
||||
}
|
||||
|
||||
int lua_equal(lua_State *L, lua_Object o1, lua_Object o2) {
|
||||
UNUSED(L);
|
||||
if (o1 == LUA_NOOBJECT || o2 == LUA_NOOBJECT)
|
||||
return (o1 == o2);
|
||||
else return luaO_equalObj(o1, o2);
|
||||
}
|
||||
|
||||
|
||||
double lua_getnumber (lua_State *L, lua_Object obj) {
|
||||
UNUSED(L);
|
||||
if (obj == LUA_NOOBJECT || tonumber(obj))
|
||||
return 0.0;
|
||||
else return (nvalue(obj));
|
||||
}
|
||||
|
||||
const char *lua_getstring (lua_State *L, lua_Object obj) {
|
||||
const char *lua_tostring (lua_State *L, int index) {
|
||||
luaC_checkGC(L); /* `tostring' may create a new string */
|
||||
if (obj == LUA_NOOBJECT || tostring(L, obj))
|
||||
return NULL;
|
||||
else return (svalue(obj));
|
||||
access(L, index, (tostring(L, o) == 0), NULL, svalue(o));
|
||||
}
|
||||
|
||||
size_t lua_strlen (lua_State *L, lua_Object obj) {
|
||||
if (obj == LUA_NOOBJECT || tostring(L, obj))
|
||||
return 0L;
|
||||
else return (tsvalue(obj)->u.s.len);
|
||||
size_t lua_strlen (lua_State *L, int index) {
|
||||
access(L, index, (tostring(L, o) == 0), 0, tsvalue(o)->u.s.len);
|
||||
}
|
||||
|
||||
void *lua_getuserdata (lua_State *L, lua_Object obj) {
|
||||
UNUSED(L);
|
||||
if (obj == LUA_NOOBJECT || ttype(obj) != TAG_USERDATA)
|
||||
return NULL;
|
||||
else return tsvalue(obj)->u.d.value;
|
||||
lua_CFunction lua_tocfunction (lua_State *L, int index) {
|
||||
access(L, index, (ttype(o) == TAG_CCLOSURE), NULL, clvalue(o)->f.c);
|
||||
}
|
||||
|
||||
lua_CFunction lua_getcfunction (lua_State *L, lua_Object obj) {
|
||||
if (!lua_iscfunction(L, obj))
|
||||
return NULL;
|
||||
else return clvalue(obj)->f.c;
|
||||
void *lua_touserdata (lua_State *L, int index) {
|
||||
access(L, index, (ttype(o) == TAG_USERDATA), NULL, tsvalue(o)->u.d.value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** push functions (C -> stack)
|
||||
*/
|
||||
|
||||
|
||||
void lua_pushnil (lua_State *L) {
|
||||
ttype(L->top) = TAG_NIL;
|
||||
incr_top;
|
||||
api_incr_top(L);
|
||||
}
|
||||
|
||||
|
||||
void lua_pushnumber (lua_State *L, double n) {
|
||||
ttype(L->top) = TAG_NUMBER;
|
||||
nvalue(L->top) = n;
|
||||
incr_top;
|
||||
api_incr_top(L);
|
||||
}
|
||||
|
||||
|
||||
void lua_pushlstring (lua_State *L, const char *s, size_t len) {
|
||||
luaC_checkGC(L);
|
||||
tsvalue(L->top) = luaS_newlstr(L, s, len);
|
||||
ttype(L->top) = TAG_STRING;
|
||||
incr_top;
|
||||
luaC_checkGC(L);
|
||||
api_incr_top(L);
|
||||
}
|
||||
|
||||
|
||||
void lua_pushstring (lua_State *L, const char *s) {
|
||||
if (s == NULL)
|
||||
lua_pushnil(L);
|
||||
@ -276,48 +177,154 @@ void lua_pushstring (lua_State *L, const char *s) {
|
||||
lua_pushlstring(L, s, strlen(s));
|
||||
}
|
||||
|
||||
|
||||
void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
|
||||
if (fn == NULL)
|
||||
lua_error(L, "Lua API error - attempt to push a NULL Cfunction");
|
||||
luaA_checkCargs(L, n);
|
||||
luaV_Cclosure(L, fn, n);
|
||||
luaC_checkGC(L);
|
||||
luaV_Cclosure(L, fn, n);
|
||||
}
|
||||
|
||||
|
||||
void lua_pushusertag (lua_State *L, void *u, int tag) { /* ORDER LUA_T */
|
||||
luaC_checkGC(L);
|
||||
if (tag != LUA_ANYTAG && tag != TAG_USERDATA && tag < NUM_TAGS)
|
||||
luaL_verror(L, "invalid tag for a userdata (%d)", tag);
|
||||
tsvalue(L->top) = luaS_createudata(L, u, tag);
|
||||
ttype(L->top) = TAG_USERDATA;
|
||||
incr_top;
|
||||
luaC_checkGC(L);
|
||||
}
|
||||
|
||||
void luaA_pushobject (lua_State *L, const TObject *o) {
|
||||
*L->top = *o;
|
||||
incr_top;
|
||||
}
|
||||
|
||||
void lua_pushobject (lua_State *L, lua_Object o) {
|
||||
if (o == LUA_NOOBJECT)
|
||||
lua_error(L, "Lua API error - attempt to push a NOOBJECT");
|
||||
*L->top = *o;
|
||||
incr_top;
|
||||
api_incr_top(L);
|
||||
}
|
||||
|
||||
|
||||
int lua_tag (lua_State *L, lua_Object o) {
|
||||
if (o == LUA_NOOBJECT)
|
||||
return TAG_NIL;
|
||||
else if (ttype(o) == TAG_USERDATA) /* to allow `old' tags (deprecated) */
|
||||
return tsvalue(o)->u.d.tag;
|
||||
|
||||
/*
|
||||
** get functions (Lua -> stack)
|
||||
*/
|
||||
|
||||
|
||||
void lua_getglobal (lua_State *L, const char *name) {
|
||||
luaV_getglobal(L, luaS_new(L, name), L->top++);
|
||||
}
|
||||
|
||||
|
||||
void lua_gettable (lua_State *L) {
|
||||
luaV_gettable(L, L->top--);
|
||||
}
|
||||
|
||||
|
||||
void lua_rawget (lua_State *L) {
|
||||
if (ttype(L->top - 2) != TAG_TABLE)
|
||||
lua_error(L, "indexed expression not a table");
|
||||
*(L->top - 2) = *luaH_get(L, hvalue(L->top - 2), L->top - 1);
|
||||
L->top--;
|
||||
}
|
||||
|
||||
|
||||
void lua_getglobals (lua_State *L) {
|
||||
hvalue(L->top) = L->gt;
|
||||
ttype(L->top) = TAG_TABLE;
|
||||
api_incr_top(L);
|
||||
}
|
||||
|
||||
|
||||
void lua_gettagmethod (lua_State *L, int tag, const char *event) {
|
||||
*L->top = *luaT_gettagmethod(L, tag, event);
|
||||
api_incr_top(L);
|
||||
}
|
||||
|
||||
|
||||
int lua_getref (lua_State *L, int ref) {
|
||||
if (ref == LUA_REFNIL)
|
||||
ttype(L->top) = TAG_NIL;
|
||||
else if (0 <= ref && ref < L->refSize &&
|
||||
(L->refArray[ref].st == LOCK || L->refArray[ref].st == HOLD))
|
||||
*L->top = L->refArray[ref].o;
|
||||
else
|
||||
return luaT_effectivetag(L, o);
|
||||
return 0;
|
||||
api_incr_top(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void lua_newtable (lua_State *L) {
|
||||
luaC_checkGC(L);
|
||||
hvalue(L->top) = luaH_new(L, 0);
|
||||
ttype(L->top) = TAG_TABLE;
|
||||
api_incr_top(L);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** set functions (stack -> Lua)
|
||||
*/
|
||||
|
||||
|
||||
void lua_setglobal (lua_State *L, const char *name) {
|
||||
luaV_setglobal(L, luaS_new(L, name), L->top--);
|
||||
}
|
||||
|
||||
|
||||
void lua_settable (lua_State *L) {
|
||||
StkId top = L->top;
|
||||
luaV_settable(L, top-3, top);
|
||||
L->top = top-3; /* pop table, index, and value */
|
||||
}
|
||||
|
||||
|
||||
void lua_rawset (lua_State *L) {
|
||||
if (ttype(L->top-3) != TAG_TABLE)
|
||||
lua_error(L, "indexed expression not a table");
|
||||
*luaH_set(L, hvalue(L->top-3), L->top-2) = *(L->top-1);
|
||||
L->top -= 3;
|
||||
}
|
||||
|
||||
|
||||
void lua_setglobals (lua_State *L) {
|
||||
TObject *newtable = --L->top;
|
||||
if (ttype(newtable) != TAG_TABLE)
|
||||
lua_error(L, "Lua API error - invalid value for global table");
|
||||
L->gt = hvalue(newtable);
|
||||
}
|
||||
|
||||
|
||||
void lua_settagmethod (lua_State *L, int tag, const char *event) {
|
||||
TObject *method = L->top - 1;
|
||||
if (ttype(method) != TAG_NIL &&
|
||||
ttype(method) != TAG_CCLOSURE &&
|
||||
ttype(method) != TAG_LCLOSURE)
|
||||
lua_error(L, "Lua API error - tag method must be a function or nil");
|
||||
luaT_settagmethod(L, tag, event, method);
|
||||
}
|
||||
|
||||
|
||||
int lua_ref (lua_State *L, int lock) {
|
||||
int ref;
|
||||
if (ttype(L->top-1) == TAG_NIL)
|
||||
ref = LUA_REFNIL;
|
||||
else {
|
||||
if (L->refFree != NONEXT) { /* is there a free place? */
|
||||
ref = L->refFree;
|
||||
L->refFree = L->refArray[ref].st;
|
||||
}
|
||||
else { /* no more free places */
|
||||
luaM_growvector(L, L->refArray, L->refSize, 1, struct Ref,
|
||||
"reference table overflow", MAX_INT);
|
||||
ref = L->refSize++;
|
||||
}
|
||||
L->refArray[ref].o = *(L->top-1);
|
||||
L->refArray[ref].st = lock ? LOCK : HOLD;
|
||||
}
|
||||
L->top--;
|
||||
return ref;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** miscelaneous functions
|
||||
*/
|
||||
|
||||
|
||||
void lua_settag (lua_State *L, int tag) {
|
||||
luaA_checkCargs(L, 1);
|
||||
luaT_realtag(L, tag);
|
||||
switch (ttype(L->top-1)) {
|
||||
case TAG_TABLE:
|
||||
@ -334,6 +341,17 @@ void lua_settag (lua_State *L, int tag) {
|
||||
}
|
||||
|
||||
|
||||
void lua_unref (lua_State *L, int ref) {
|
||||
if (ref >= 0) {
|
||||
if (ref >= L->refSize || L->refArray[ref].st >= 0)
|
||||
lua_error(L, "Lua API error - "
|
||||
"invalid argument for function `lua_unref'");
|
||||
L->refArray[ref].st = L->refFree;
|
||||
L->refFree = ref;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int luaA_next (lua_State *L, const Hash *t, int i) {
|
||||
int tsize = t->size;
|
||||
for (; i<tsize; i++) {
|
||||
@ -348,38 +366,10 @@ int luaA_next (lua_State *L, const Hash *t, int i) {
|
||||
}
|
||||
|
||||
|
||||
int lua_next (lua_State *L, lua_Object t, int i) {
|
||||
int lua_next (lua_State *L, int index, int i) {
|
||||
const TObject *t = Index(L, index);
|
||||
if (ttype(t) != TAG_TABLE)
|
||||
lua_error(L, "Lua API error - object is not a table in `lua_next'");
|
||||
i = luaA_next(L, hvalue(t), i);
|
||||
top2LC(L, (i==0) ? 0 : 2);
|
||||
return i;
|
||||
return luaA_next(L, hvalue(t), i);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if LUA_DEPRECATETFUNCS
|
||||
|
||||
/*
|
||||
** obsolete functions
|
||||
*/
|
||||
|
||||
lua_Object lua_rawgetglobal (lua_State *L, const char *name) {
|
||||
lua_pushglobals(L);
|
||||
lua_pushstring(L, name);
|
||||
return lua_rawget(L);
|
||||
}
|
||||
|
||||
|
||||
void lua_rawsetglobal (lua_State *L, const char *name) {
|
||||
lua_Object value;
|
||||
lua_beginblock(L);
|
||||
value = lua_pop(L);
|
||||
lua_pushglobals(L);
|
||||
lua_pushstring(L, name);
|
||||
lua_pushobject(L, value);
|
||||
lua_rawset(L);
|
||||
lua_endblock(L);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
5
lapi.h
5
lapi.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lapi.h,v 1.17 2000/05/08 19:32:53 roberto Exp roberto $
|
||||
** $Id: lapi.h,v 1.18 2000/05/08 20:49:05 roberto Exp roberto $
|
||||
** Auxiliary functions from Lua API
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -11,9 +11,8 @@
|
||||
#include "lobject.h"
|
||||
|
||||
|
||||
void luaA_checkCargs (lua_State *L, int nargs);
|
||||
TObject *luaA_index (lua_State *L, int index);
|
||||
void luaA_pushobject (lua_State *L, const TObject *o);
|
||||
int luaA_next (lua_State *L, const Hash *t, int i);
|
||||
lua_Object luaA_putluaObject (lua_State *L, const TObject *o);
|
||||
|
||||
#endif
|
||||
|
68
lauxlib.c
68
lauxlib.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lauxlib.c,v 1.29 2000/06/12 13:52:05 roberto Exp roberto $
|
||||
** $Id: lauxlib.c,v 1.30 2000/08/09 19:16:57 roberto Exp roberto $
|
||||
** Auxiliary functions for building Lua libraries
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -41,72 +41,61 @@ void luaL_argerror (lua_State *L, int narg, const char *extramsg) {
|
||||
}
|
||||
|
||||
|
||||
static void type_error (lua_State *L, int narg, const char *type_name,
|
||||
lua_Object o) {
|
||||
static void type_error (lua_State *L, int narg, const char *type_name) {
|
||||
char buff[100];
|
||||
const char *otype = (o == LUA_NOOBJECT) ? "no value" : lua_type(L, o);
|
||||
sprintf(buff, "%.10s expected, got %.10s", type_name, otype);
|
||||
const char *rt = lua_type(L, narg);
|
||||
if (*rt == 'N') rt = "no value";
|
||||
sprintf(buff, "%.10s expected, got %.10s", type_name, rt);
|
||||
luaL_argerror(L, narg, buff);
|
||||
}
|
||||
|
||||
|
||||
static const char *checkstr (lua_State *L, lua_Object o, int narg,
|
||||
size_t *len) {
|
||||
const char *s = lua_getstring(L, o);
|
||||
if (!s) type_error(L, narg, "string", o);
|
||||
if (len) *len = lua_strlen(L, o);
|
||||
/*
|
||||
** use the 3rd letter of type names for testing:
|
||||
** nuMber, niL, stRing, fuNction, usErdata, taBle, anY
|
||||
*/
|
||||
void luaL_checktype(lua_State *L, int narg, const char *tname) {
|
||||
const char *rt = lua_type(L, narg);
|
||||
if (!(*rt != 'N' && (tname[2] == 'y' || tname[2] == rt[2])))
|
||||
type_error(L, narg, tname);
|
||||
}
|
||||
|
||||
|
||||
static const char *checkstr (lua_State *L, int narg, size_t *len) {
|
||||
const char *s = lua_tostring(L, narg);
|
||||
if (!s) type_error(L, narg, "string");
|
||||
if (len) *len = lua_strlen(L, narg);
|
||||
return s;
|
||||
}
|
||||
|
||||
const char *luaL_check_lstr (lua_State *L, int narg, size_t *len) {
|
||||
return checkstr(L, lua_getparam(L, narg), narg, len);
|
||||
return checkstr(L, narg, len);
|
||||
}
|
||||
|
||||
const char *luaL_opt_lstr (lua_State *L, int narg, const char *def,
|
||||
size_t *len) {
|
||||
lua_Object o = lua_getparam(L, narg);
|
||||
if (o == LUA_NOOBJECT) {
|
||||
if (lua_isnull(L, narg)) {
|
||||
if (len) *len = def ? strlen(def) : 0;
|
||||
return def;
|
||||
}
|
||||
else return checkstr(L, o, narg, len);
|
||||
else return checkstr(L, narg, len);
|
||||
}
|
||||
|
||||
double luaL_check_number (lua_State *L, int narg) {
|
||||
lua_Object o = lua_getparam(L, narg);
|
||||
if (!lua_isnumber(L, o)) type_error(L, narg, "number", o);
|
||||
return lua_getnumber(L, o);
|
||||
if (!lua_isnumber(L, narg)) type_error(L, narg, "number");
|
||||
return lua_tonumber(L, narg);
|
||||
}
|
||||
|
||||
|
||||
double luaL_opt_number (lua_State *L, int narg, double def) {
|
||||
lua_Object o = lua_getparam(L, narg);
|
||||
if (o == LUA_NOOBJECT) return def;
|
||||
if (lua_isnull(L, narg)) return def;
|
||||
else {
|
||||
if (!lua_isnumber(L, o)) type_error(L, narg, "number", o);
|
||||
return lua_getnumber(L, o);
|
||||
if (!lua_isnumber(L, narg)) type_error(L, narg, "number");
|
||||
return lua_tonumber(L, narg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
lua_Object luaL_tablearg (lua_State *L, int narg) {
|
||||
lua_Object o = lua_getparam(L, narg);
|
||||
if (!lua_istable(L, o)) type_error(L, narg, "table", o);
|
||||
return o;
|
||||
}
|
||||
|
||||
lua_Object luaL_functionarg (lua_State *L, int narg) {
|
||||
lua_Object o = lua_getparam(L, narg);
|
||||
if (!lua_isfunction(L, o)) type_error(L, narg, "function", o);
|
||||
return o;
|
||||
}
|
||||
|
||||
lua_Object luaL_nonnullarg (lua_State *L, int narg) {
|
||||
lua_Object o = lua_getparam(L, narg);
|
||||
luaL_arg_check(L, o != LUA_NOOBJECT, narg, "value expected");
|
||||
return o;
|
||||
}
|
||||
|
||||
void luaL_openlib (lua_State *L, const struct luaL_reg *l, int n) {
|
||||
int i;
|
||||
for (i=0; i<n; i++)
|
||||
@ -150,3 +139,4 @@ void luaL_filesource (char *out, const char *filename, int len) {
|
||||
if (filename == NULL) filename = "(stdin)";
|
||||
sprintf(out, "@%.*s", len-2, filename); /* -2 for '@' and '\0' */
|
||||
}
|
||||
|
||||
|
12
lauxlib.h
12
lauxlib.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lauxlib.h,v 1.18 2000/05/24 13:54:49 roberto Exp roberto $
|
||||
** $Id: lauxlib.h,v 1.19 2000/08/09 19:16:57 roberto Exp roberto $
|
||||
** Auxiliary functions for building Lua libraries
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -27,14 +27,15 @@ const char *luaL_opt_lstr (lua_State *L, int numArg, const char *def,
|
||||
size_t *len);
|
||||
double luaL_check_number (lua_State *L, int numArg);
|
||||
double luaL_opt_number (lua_State *L, int numArg, double def);
|
||||
lua_Object luaL_functionarg (lua_State *L, int arg);
|
||||
lua_Object luaL_tablearg (lua_State *L, int arg);
|
||||
lua_Object luaL_nonnullarg (lua_State *L, int numArg);
|
||||
|
||||
void luaL_checktype(lua_State *L, int narg, const char *tname);
|
||||
|
||||
void luaL_verror (lua_State *L, const char *fmt, ...);
|
||||
int luaL_findstring (const char *name, const char *const list[]);
|
||||
void luaL_chunkid (char *out, const char *source, int len);
|
||||
void luaL_filesource (char *out, const char *filename, int len);
|
||||
|
||||
|
||||
char *luaL_openspace (lua_State *L, size_t size);
|
||||
void luaL_resetbuffer (lua_State *L);
|
||||
void luaL_addchar (lua_State *L, int c);
|
||||
@ -91,9 +92,6 @@ char *luaL_buffer (lua_State *L);
|
||||
(luaL_opt_lstr)(lua_state,numArg,def,len)
|
||||
#define luaL_check_number(numArg) (luaL_check_number)(lua_state,numArg)
|
||||
#define luaL_opt_number(numArg,def) (luaL_opt_number)(lua_state,numArg,def)
|
||||
#define luaL_functionarg(arg) (luaL_functionarg)(lua_state,arg)
|
||||
#define luaL_tablearg(arg) (luaL_tablearg)(lua_state,arg)
|
||||
#define luaL_nonnullarg(numArg) (luaL_nonnullarg)(lua_state,numArg)
|
||||
#define luaL_openspace(size) (luaL_openspace)(lua_state,size)
|
||||
#define luaL_resetbuffer() (luaL_resetbuffer)(lua_state)
|
||||
#define luaL_addchar(c) (luaL_addchar)(lua_state,c)
|
||||
|
333
lbuiltin.c
333
lbuiltin.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lbuiltin.c,v 1.120 2000/08/14 19:10:14 roberto Exp roberto $
|
||||
** $Id: lbuiltin.c,v 1.121 2000/08/15 18:28:48 roberto Exp roberto $
|
||||
** Built-in functions
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -50,7 +50,6 @@ void luaB_opentests (lua_State *L);
|
||||
** =======================================================
|
||||
*/
|
||||
|
||||
|
||||
static Number getsize (const Hash *h) {
|
||||
Number max = 0;
|
||||
int i = h->size;
|
||||
@ -73,7 +72,8 @@ static Number getnarg (lua_State *L, const Hash *a) {
|
||||
|
||||
|
||||
static Hash *gettable (lua_State *L, int arg) {
|
||||
return hvalue(luaL_tablearg(L, arg));
|
||||
luaL_checktype(L, arg, "table");
|
||||
return hvalue(luaA_index(L, arg));
|
||||
}
|
||||
|
||||
/* }====================================================== */
|
||||
@ -90,8 +90,9 @@ static Hash *gettable (lua_State *L, int arg) {
|
||||
** If your system does not support `stderr', redefine this function, or
|
||||
** redefine _ERRORMESSAGE so that it won't need _ALERT.
|
||||
*/
|
||||
void luaB__ALERT (lua_State *L) {
|
||||
int luaB__ALERT (lua_State *L) {
|
||||
fputs(luaL_check_string(L, 1), stderr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -99,18 +100,19 @@ void luaB__ALERT (lua_State *L) {
|
||||
** Standard implementation of _ERRORMESSAGE.
|
||||
** The library `liolib' redefines _ERRORMESSAGE for better error information.
|
||||
*/
|
||||
void luaB__ERRORMESSAGE (lua_State *L) {
|
||||
lua_Object al;
|
||||
lua_pushglobals(L);
|
||||
int luaB__ERRORMESSAGE (lua_State *L) {
|
||||
lua_getglobals(L);
|
||||
lua_pushstring(L, LUA_ALERT);
|
||||
al = lua_rawget(L);
|
||||
if (lua_isfunction(L, al)) { /* avoid error loop if _ALERT is not defined */
|
||||
lua_rawget(L);
|
||||
if (lua_isfunction(L, -1)) { /* avoid error loop if _ALERT is not defined */
|
||||
const char *s = luaL_check_string(L, 1);
|
||||
char *buff = luaL_openspace(L, strlen(s)+sizeof("error: \n"));
|
||||
strcpy(buff, "error: "); strcat(buff, s); strcat(buff, "\n");
|
||||
lua_pushobject(L, -1); /* function to be called */
|
||||
lua_pushstring(L, buff);
|
||||
lua_callfunction(L, al);
|
||||
lua_call(L, 1, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -120,36 +122,35 @@ void luaB__ERRORMESSAGE (lua_State *L) {
|
||||
** model but changing `fputs' to put the strings at a proper place
|
||||
** (a console window or a log file, for instance).
|
||||
*/
|
||||
void luaB_print (lua_State *L) {
|
||||
lua_Object args[MAXPRINT];
|
||||
lua_Object obj;
|
||||
int n = 0;
|
||||
int luaB_print (lua_State *L) {
|
||||
int n = lua_gettop(L); /* number of arguments */
|
||||
int i;
|
||||
while ((obj = lua_getparam(L, n+1)) != LUA_NOOBJECT) {
|
||||
luaL_arg_check(L, n < MAXPRINT, n+1, "too many arguments");
|
||||
args[n++] = obj;
|
||||
}
|
||||
for (i=0; i<n; i++) {
|
||||
lua_pushobject(L, args[i]);
|
||||
if (lua_call(L, "tostring"))
|
||||
lua_getglobal(L, "tostring");
|
||||
for (i=1; i<=n; i++) {
|
||||
const char *s;
|
||||
lua_pushobject(L, -1); /* function to be called */
|
||||
lua_pushobject(L, i);
|
||||
if (lua_call(L, 1, 1) != 0)
|
||||
lua_error(L, "error in `tostring' called by `print'");
|
||||
obj = lua_getresult(L, 1);
|
||||
if (!lua_isstring(L, obj))
|
||||
s = lua_tostring(L, -1); /* get result */
|
||||
if (s == NULL)
|
||||
lua_error(L, "`tostring' must return a string to `print'");
|
||||
if (i>0) fputs("\t", stdout);
|
||||
fputs(lua_getstring(L, obj), stdout);
|
||||
if (i>1) fputs("\t", stdout);
|
||||
fputs(s, stdout);
|
||||
lua_settop(L, -1); /* pop result */
|
||||
}
|
||||
fputs("\n", stdout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void luaB_tonumber (lua_State *L) {
|
||||
int luaB_tonumber (lua_State *L) {
|
||||
int base = luaL_opt_int(L, 2, 10);
|
||||
if (base == 10) { /* standard conversion */
|
||||
lua_Object o = luaL_nonnullarg(L, 1);
|
||||
if (lua_isnumber(L, o)) {
|
||||
lua_pushnumber(L, lua_getnumber(L, o));
|
||||
return;
|
||||
luaL_checktype(L, 1, "any");
|
||||
if (lua_isnumber(L, 1)) {
|
||||
lua_pushnumber(L, lua_tonumber(L, 1));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -162,94 +163,108 @@ void luaB_tonumber (lua_State *L) {
|
||||
while (isspace((unsigned char)*s2)) s2++; /* skip trailing spaces */
|
||||
if (*s2 == '\0') { /* no invalid trailing characters? */
|
||||
lua_pushnumber(L, n);
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
lua_pushnil(L); /* else not a number */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void luaB_error (lua_State *L) {
|
||||
int luaB_error (lua_State *L) {
|
||||
lua_error(L, luaL_opt_string(L, 1, NULL));
|
||||
return 0; /* to avoid errors */
|
||||
}
|
||||
|
||||
void luaB_setglobal (lua_State *L) {
|
||||
const char *name = luaL_check_string(L, 1);
|
||||
lua_Object value = luaL_nonnullarg(L, 2);
|
||||
lua_pushobject(L, value);
|
||||
lua_setglobal(L, name);
|
||||
int luaB_setglobal (lua_State *L) {
|
||||
luaL_checktype(L, 2, "any");
|
||||
lua_setglobal(L, luaL_check_string(L, 1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void luaB_getglobal (lua_State *L) {
|
||||
lua_pushobject(L, lua_getglobal(L, luaL_check_string(L, 1)));
|
||||
int luaB_getglobal (lua_State *L) {
|
||||
lua_getglobal(L, luaL_check_string(L, 1));
|
||||
return 1;
|
||||
}
|
||||
|
||||
void luaB_tag (lua_State *L) {
|
||||
lua_pushnumber(L, lua_tag(L, luaL_nonnullarg(L, 1)));
|
||||
int luaB_tag (lua_State *L) {
|
||||
luaL_checktype(L, 1, "any");
|
||||
lua_pushnumber(L, lua_tag(L, 1));
|
||||
return 1;
|
||||
}
|
||||
|
||||
void luaB_settag (lua_State *L) {
|
||||
lua_Object o = luaL_tablearg(L, 1);
|
||||
lua_pushobject(L, o);
|
||||
int luaB_settag (lua_State *L) {
|
||||
luaL_checktype(L, 1, "table");
|
||||
lua_pushobject(L, 1); /* push table */
|
||||
lua_settag(L, luaL_check_int(L, 2));
|
||||
lua_pushobject(L, o); /* return first argument */
|
||||
lua_pushobject(L, 1); /* return first argument */
|
||||
return 1;
|
||||
}
|
||||
|
||||
void luaB_newtag (lua_State *L) {
|
||||
int luaB_newtag (lua_State *L) {
|
||||
lua_pushnumber(L, lua_newtag(L));
|
||||
return 1;
|
||||
}
|
||||
|
||||
void luaB_copytagmethods (lua_State *L) {
|
||||
int luaB_copytagmethods (lua_State *L) {
|
||||
lua_pushnumber(L, lua_copytagmethods(L, luaL_check_int(L, 1),
|
||||
luaL_check_int(L, 2)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
void luaB_globals (lua_State *L) {
|
||||
lua_pushglobals(L);
|
||||
if (lua_getparam(L, 1) != LUA_NOOBJECT)
|
||||
lua_setglobals(L, luaL_tablearg(L, 1));
|
||||
int luaB_globals (lua_State *L) {
|
||||
lua_getglobals(L); /* value to be returned */
|
||||
if (!lua_isnull(L, 1)) {
|
||||
luaL_checktype(L, 1, "table");
|
||||
lua_pushobject(L, 1); /* new table of globals */
|
||||
lua_setglobals(L);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void luaB_rawget (lua_State *L) {
|
||||
lua_pushobject(L, luaL_nonnullarg(L, 1));
|
||||
lua_pushobject(L, luaL_nonnullarg(L, 2));
|
||||
lua_pushobject(L, lua_rawget(L));
|
||||
int luaB_rawget (lua_State *L) {
|
||||
luaL_checktype(L, 1, "table");
|
||||
luaL_checktype(L, 2, "any");
|
||||
lua_rawget(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void luaB_rawset (lua_State *L) {
|
||||
lua_pushobject(L, luaL_nonnullarg(L, 1));
|
||||
lua_pushobject(L, luaL_nonnullarg(L, 2));
|
||||
lua_pushobject(L, luaL_nonnullarg(L, 3));
|
||||
int luaB_rawset (lua_State *L) {
|
||||
luaL_checktype(L, 1, "table");
|
||||
luaL_checktype(L, 2, "any");
|
||||
luaL_checktype(L, 3, "any");
|
||||
lua_rawset(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void luaB_settagmethod (lua_State *L) {
|
||||
int tag = luaL_check_int(L, 1);
|
||||
int luaB_settagmethod (lua_State *L) {
|
||||
int tag = (int)luaL_check_int(L, 1);
|
||||
const char *event = luaL_check_string(L, 2);
|
||||
lua_Object nf = luaL_nonnullarg(L, 3);
|
||||
luaL_arg_check(L, lua_isnil(L, nf) || lua_isfunction(L, nf), 3,
|
||||
luaL_arg_check(L, lua_isfunction(L, 3) || lua_isnil(L, 3), 3,
|
||||
"function or nil expected");
|
||||
if (strcmp(event, "gc") == 0 && tag != TAG_NIL)
|
||||
lua_error(L, "deprecated use: cannot set the `gc' tag method from Lua");
|
||||
lua_pushobject(L, nf);
|
||||
lua_pushobject(L, lua_settagmethod(L, tag, event));
|
||||
lua_settagmethod(L, tag, event);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void luaB_gettagmethod (lua_State *L) {
|
||||
lua_pushobject(L, lua_gettagmethod(L, luaL_check_int(L, 1),
|
||||
luaL_check_string(L, 2)));
|
||||
int luaB_gettagmethod (lua_State *L) {
|
||||
lua_gettagmethod(L, luaL_check_int(L, 1), luaL_check_string(L, 2));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void luaB_collectgarbage (lua_State *L) {
|
||||
int luaB_collectgarbage (lua_State *L) {
|
||||
lua_pushnumber(L, lua_collectgarbage(L, luaL_opt_int(L, 1, 0)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void luaB_type (lua_State *L) {
|
||||
lua_Object o = luaL_nonnullarg(L, 1);
|
||||
lua_pushstring(L, lua_type(L, o));
|
||||
int luaB_type (lua_State *L) {
|
||||
luaL_checktype(L, 1, "any");
|
||||
lua_pushstring(L, lua_type(L, 1));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* }====================================================== */
|
||||
@ -263,99 +278,115 @@ void luaB_type (lua_State *L) {
|
||||
*/
|
||||
|
||||
|
||||
static void passresults (lua_State *L) {
|
||||
L->Cstack.base = L->Cstack.lua2C; /* position of first result */
|
||||
if (L->Cstack.num == 0)
|
||||
static int passresults (lua_State *L, int status, int oldtop) {
|
||||
if (status == 0) {
|
||||
int nresults = lua_gettop(L) - oldtop;
|
||||
if (nresults > 0)
|
||||
return nresults; /* results are already on the stack */
|
||||
else {
|
||||
lua_pushuserdata(L, NULL); /* at least one result to signal no errors */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else { /* error */
|
||||
lua_pushnil(L);
|
||||
lua_pushnumber(L, status); /* error code */
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
void luaB_dostring (lua_State *L) {
|
||||
int luaB_dostring (lua_State *L) {
|
||||
int oldtop = lua_gettop(L);
|
||||
size_t l;
|
||||
const char *s = luaL_check_lstr(L, 1, &l);
|
||||
if (*s == ID_CHUNK)
|
||||
lua_error(L, "`dostring' cannot run pre-compiled code");
|
||||
if (lua_dobuffer(L, s, l, luaL_opt_string(L, 2, s)) == 0)
|
||||
passresults(L);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
return passresults(L, lua_dobuffer(L, s, l, luaL_opt_string(L, 2, s)), oldtop);
|
||||
}
|
||||
|
||||
|
||||
void luaB_dofile (lua_State *L) {
|
||||
int luaB_dofile (lua_State *L) {
|
||||
int oldtop = lua_gettop(L);
|
||||
const char *fname = luaL_opt_string(L, 1, NULL);
|
||||
if (lua_dofile(L, fname) == 0)
|
||||
passresults(L);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
return passresults(L, lua_dofile(L, fname), oldtop);
|
||||
}
|
||||
|
||||
|
||||
void luaB_call (lua_State *L) {
|
||||
lua_Object f = luaL_nonnullarg(L, 1);
|
||||
int luaB_call (lua_State *L) {
|
||||
int oldtop;
|
||||
const Hash *arg = gettable(L, 2);
|
||||
const char *options = luaL_opt_string(L, 3, "");
|
||||
lua_Object err = lua_getparam(L, 4);
|
||||
int narg = (int)getnarg(L, arg);
|
||||
int err = 0; /* index of old error method */
|
||||
int n = (int)getnarg(L, arg);
|
||||
int i, status;
|
||||
if (err != LUA_NOOBJECT) { /* set new error method */
|
||||
lua_Object oldem = lua_getglobal(L, LUA_ERRORMESSAGE);
|
||||
lua_pushobject(L, err);
|
||||
if (!lua_isnull(L, 4)) { /* set new error method */
|
||||
lua_getglobal(L, LUA_ERRORMESSAGE);
|
||||
err = lua_gettop(L); /* get index */
|
||||
lua_pushobject(L, 4);
|
||||
lua_setglobal(L, LUA_ERRORMESSAGE);
|
||||
err = oldem;
|
||||
}
|
||||
oldtop = lua_gettop(L); /* top before function-call preparation */
|
||||
/* push function */
|
||||
lua_pushobject(L, 1);
|
||||
/* push arg[1...n] */
|
||||
luaD_checkstack(L, narg);
|
||||
for (i=0; i<narg; i++)
|
||||
luaD_checkstack(L, n);
|
||||
for (i=0; i<n; i++)
|
||||
*(L->top++) = *luaH_getnum(arg, i+1);
|
||||
status = lua_callfunction(L, f);
|
||||
if (err != LUA_NOOBJECT) { /* restore old error method */
|
||||
status = lua_call(L, n, LUA_MULTRET);
|
||||
n = lua_gettop(L) - oldtop; /* number of results */
|
||||
if (err != 0) { /* restore old error method */
|
||||
lua_pushobject(L, err);
|
||||
lua_setglobal(L, LUA_ERRORMESSAGE);
|
||||
}
|
||||
if (status != 0) { /* error in call? */
|
||||
if (strchr(options, 'x')) {
|
||||
lua_pushnil(L);
|
||||
return; /* return nil to signal the error */
|
||||
}
|
||||
if (strchr(options, 'x'))
|
||||
lua_pushnil(L); /* return nil to signal the error */
|
||||
else
|
||||
lua_error(L, NULL); /* propagate error without additional messages */
|
||||
return 1;
|
||||
}
|
||||
else { /* no errors */
|
||||
if (strchr(options, 'p')) { /* pack results? */
|
||||
luaV_pack(L, L->Cstack.lua2C, L->Cstack.num, L->top);
|
||||
luaV_pack(L, luaA_index(L, oldtop+1), n, L->top);
|
||||
incr_top;
|
||||
return 1; /* only table is returned */
|
||||
}
|
||||
else
|
||||
L->Cstack.base = L->Cstack.lua2C; /* position of first result */
|
||||
return n; /* results are already on the stack */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void luaB_next (lua_State *L) {
|
||||
int luaB_next (lua_State *L) {
|
||||
const Hash *a = gettable(L, 1);
|
||||
lua_Object k = lua_getparam(L, 2);
|
||||
int i; /* `luaA_next' gets first element after `i' */
|
||||
if (k == LUA_NOOBJECT || ttype(k) == TAG_NIL)
|
||||
if (lua_isnull(L, 2) || lua_isnil(L, 2)) /* no index or nil index? */
|
||||
i = 0; /* get first */
|
||||
else {
|
||||
i = luaH_pos(L, a, k)+1;
|
||||
i = luaH_pos(L, a, luaA_index(L, 2))+1;
|
||||
luaL_arg_check(L, i != 0, 2, "key not found");
|
||||
}
|
||||
if (luaA_next(L, a, i) == 0)
|
||||
if (luaA_next(L, a, i) != 0)
|
||||
return 2; /* `luaA_next' left them on the stack */
|
||||
else {
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void luaB_tostring (lua_State *L) {
|
||||
lua_Object o = luaL_nonnullarg(L, 1);
|
||||
int luaB_tostring (lua_State *L) {
|
||||
char buff[64];
|
||||
const TObject *o;
|
||||
luaL_checktype(L, 1, "any");
|
||||
o = luaA_index(L, 1);
|
||||
switch (ttype(o)) {
|
||||
case TAG_NUMBER:
|
||||
lua_pushstring(L, lua_getstring(L, o));
|
||||
return;
|
||||
lua_pushstring(L, lua_tostring(L, 1));
|
||||
return 1;
|
||||
case TAG_STRING:
|
||||
lua_pushobject(L, o);
|
||||
return;
|
||||
lua_pushobject(L, 1);
|
||||
return 1;
|
||||
case TAG_TABLE:
|
||||
sprintf(buff, "table: %p", hvalue(o));
|
||||
break;
|
||||
@ -368,11 +399,12 @@ void luaB_tostring (lua_State *L) {
|
||||
break;
|
||||
case TAG_NIL:
|
||||
lua_pushstring(L, "nil");
|
||||
return;
|
||||
return 1;
|
||||
default:
|
||||
LUA_INTERNALERROR("invalid type");
|
||||
}
|
||||
lua_pushstring(L, buff);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* }====================================================== */
|
||||
@ -389,15 +421,17 @@ void luaB_tostring (lua_State *L) {
|
||||
** =======================================================
|
||||
*/
|
||||
|
||||
void luaB_assert (lua_State *L) {
|
||||
lua_Object p = luaL_nonnullarg(L, 1);
|
||||
if (lua_isnil(L, p))
|
||||
int luaB_assert (lua_State *L) {
|
||||
luaL_checktype(L, 1, "any");
|
||||
if (lua_isnil(L, 1))
|
||||
luaL_verror(L, "assertion failed! %.90s", luaL_opt_string(L, 2, ""));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void luaB_getn (lua_State *L) {
|
||||
int luaB_getn (lua_State *L) {
|
||||
lua_pushnumber(L, getnarg(L, gettable(L, 1)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@ -408,72 +442,72 @@ static void t_move (lua_State *L, Hash *t, int from, int to) {
|
||||
}
|
||||
|
||||
|
||||
void luaB_tinsert (lua_State *L) {
|
||||
int luaB_tinsert (lua_State *L) {
|
||||
Hash *a = gettable(L, 1);
|
||||
lua_Object v = lua_getparam(L, 3);
|
||||
int n = (int)getnarg(L, a);
|
||||
int v = lua_gettop(L); /* last argument: to be inserted */
|
||||
int pos;
|
||||
if (v != LUA_NOOBJECT)
|
||||
pos = luaL_check_int(L, 2);
|
||||
else { /* called with only 2 arguments */
|
||||
v = luaL_nonnullarg(L, 2);
|
||||
if (v == 2) /* called with only 2 arguments */
|
||||
pos = n+1;
|
||||
}
|
||||
else
|
||||
pos = luaL_check_int(L, 2); /* 2nd argument is the position */
|
||||
luaH_setstrnum(L, a, luaS_new(L, "n"), n+1); /* a.n = n+1 */
|
||||
for (; n>=pos; n--)
|
||||
t_move(L, a, n, n+1); /* a[n+1] = a[n] */
|
||||
*luaH_setint(L, a, pos) = *v; /* a[pos] = v */
|
||||
*luaH_setint(L, a, pos) = *luaA_index(L, v); /* a[pos] = v */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void luaB_tremove (lua_State *L) {
|
||||
int luaB_tremove (lua_State *L) {
|
||||
Hash *a = gettable(L, 1);
|
||||
int n = (int)getnarg(L, a);
|
||||
int pos = luaL_opt_int(L, 2, n);
|
||||
if (n <= 0) return; /* table is "empty" */
|
||||
if (n <= 0) return 0; /* table is "empty" */
|
||||
luaA_pushobject(L, luaH_getnum(a, pos)); /* result = a[pos] */
|
||||
for ( ;pos<n; pos++)
|
||||
t_move(L, a, pos+1, pos); /* a[pos] = a[pos+1] */
|
||||
luaH_setstrnum(L, a, luaS_new(L, "n"), n-1); /* a.n = n-1 */
|
||||
ttype(luaH_setint(L, a, n)) = TAG_NIL; /* a[n] = nil */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void luaB_foreachi (lua_State *L) {
|
||||
static int luaB_foreachi (lua_State *L) {
|
||||
const Hash *t = gettable(L, 1);
|
||||
int n = (int)getnarg(L, t);
|
||||
int i;
|
||||
lua_Object f = luaL_functionarg(L, 2);
|
||||
luaD_checkstack(L, 3); /* for f, key, and val */
|
||||
luaL_checktype(L, 2, "function");
|
||||
for (i=1; i<=n; i++) {
|
||||
*(L->top++) = *f;
|
||||
lua_pushobject(L, 2);
|
||||
ttype(L->top) = TAG_NUMBER; nvalue(L->top++) = i;
|
||||
*(L->top++) = *luaH_getnum(t, i);
|
||||
luaD_call(L, L->top-3, 1);
|
||||
if (ttype(L->top-1) != TAG_NIL)
|
||||
return;
|
||||
return 1;
|
||||
L->top--; /* remove nil result */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void luaB_foreach (lua_State *L) {
|
||||
static int luaB_foreach (lua_State *L) {
|
||||
const Hash *a = gettable(L, 1);
|
||||
lua_Object f = luaL_functionarg(L, 2);
|
||||
int i;
|
||||
luaD_checkstack(L, 3); /* for f, key, and val */
|
||||
luaL_checktype(L, 2, "function");
|
||||
for (i=0; i<a->size; i++) {
|
||||
const Node *nd = &(a->node[i]);
|
||||
if (ttype(val(nd)) != TAG_NIL) {
|
||||
*(L->top++) = *f;
|
||||
lua_pushobject(L, 2);
|
||||
*(L->top++) = *key(nd);
|
||||
*(L->top++) = *val(nd);
|
||||
luaD_call(L, L->top-3, 1);
|
||||
if (ttype(L->top-1) != TAG_NIL)
|
||||
return;
|
||||
return 1;
|
||||
L->top--; /* remove result */
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -492,10 +526,10 @@ static void swap (lua_State *L, Hash *a, int i, int j) {
|
||||
*luaH_setint(L, a, j) = temp;
|
||||
}
|
||||
|
||||
static int sort_comp (lua_State *L, lua_Object f, const TObject *a,
|
||||
static int sort_comp (lua_State *L, const TObject *f, const TObject *a,
|
||||
const TObject *b) {
|
||||
/* WARNING: the caller (auxsort) must ensure stack space */
|
||||
if (f != LUA_NOOBJECT) {
|
||||
if (f != NULL) {
|
||||
*(L->top) = *f;
|
||||
*(L->top+1) = *a;
|
||||
*(L->top+2) = *b;
|
||||
@ -508,7 +542,7 @@ static int sort_comp (lua_State *L, lua_Object f, const TObject *a,
|
||||
return luaV_lessthan(L, a, b, L->top);
|
||||
}
|
||||
|
||||
static void auxsort (lua_State *L, Hash *a, int l, int u, lua_Object f) {
|
||||
static void auxsort (lua_State *L, Hash *a, int l, int u, const TObject *f) {
|
||||
StkId P = L->top++; /* temporary place for pivot */
|
||||
ttype(P) = TAG_NIL;
|
||||
while (l < u) { /* for tail recursion */
|
||||
@ -552,14 +586,16 @@ static void auxsort (lua_State *L, Hash *a, int l, int u, lua_Object f) {
|
||||
L->top--; /* remove pivot from stack */
|
||||
}
|
||||
|
||||
void luaB_sort (lua_State *L) {
|
||||
int luaB_sort (lua_State *L) {
|
||||
Hash *a = gettable(L, 1);
|
||||
int n = (int)getnarg(L, a);
|
||||
lua_Object func = lua_getparam(L, 2);
|
||||
luaL_arg_check(L, func == LUA_NOOBJECT || lua_isfunction(L, func), 2,
|
||||
"function expected");
|
||||
luaD_checkstack(L, 4); /* for pivot, f, a, b (sort_comp) */
|
||||
const TObject *func = NULL;
|
||||
if (!lua_isnull(L, 2)) { /* is there a 2nd argument? */
|
||||
luaL_checktype(L, 2, "function");
|
||||
func = luaA_index(L, 2);
|
||||
}
|
||||
auxsort(L, a, 1, n, func);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }====================================================== */
|
||||
@ -615,8 +651,9 @@ static void deprecated_funcs (lua_State *L) {
|
||||
/*
|
||||
** gives an explicit error in any attempt to call a deprecated function
|
||||
*/
|
||||
static void deprecated_func (lua_State *L) {
|
||||
static int deprecated_func (lua_State *L) {
|
||||
luaL_verror(L, "function `%.20s' is deprecated", luaL_check_string(L, 1));
|
||||
return 0; /* to avoid warnings */
|
||||
}
|
||||
|
||||
|
||||
|
58
lbuiltin.h
58
lbuiltin.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lbuiltin.h,v 1.8 2000/05/08 19:32:53 roberto Exp roberto $
|
||||
** $Id: lbuiltin.h,v 1.9 2000/05/26 19:17:57 roberto Exp roberto $
|
||||
** Built-in functions
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -9,34 +9,34 @@
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
void luaB__ALERT (lua_State *L);
|
||||
void luaB__ERRORMESSAGE (lua_State *L);
|
||||
void luaB_assert (lua_State *L);
|
||||
void luaB_call (lua_State *L);
|
||||
void luaB_collectgarbage (lua_State *L);
|
||||
void luaB_copytagmethods (lua_State *L);
|
||||
void luaB_dofile (lua_State *L);
|
||||
void luaB_dostring (lua_State *L);
|
||||
void luaB_error (lua_State *L);
|
||||
void luaB_getglobal (lua_State *L);
|
||||
void luaB_getn (lua_State *L);
|
||||
void luaB_gettagmethod (lua_State *L);
|
||||
void luaB_globals (lua_State *L);
|
||||
void luaB_newtag (lua_State *L);
|
||||
void luaB_next (lua_State *L);
|
||||
void luaB_print (lua_State *L);
|
||||
void luaB_rawget (lua_State *L);
|
||||
void luaB_rawset (lua_State *L);
|
||||
void luaB_setglobal (lua_State *L);
|
||||
void luaB_settag (lua_State *L);
|
||||
void luaB_settagmethod (lua_State *L);
|
||||
void luaB_sort (lua_State *L);
|
||||
void luaB_tag (lua_State *L);
|
||||
void luaB_tinsert (lua_State *L);
|
||||
void luaB_tonumber (lua_State *L);
|
||||
void luaB_tostring (lua_State *L);
|
||||
void luaB_tremove (lua_State *L);
|
||||
void luaB_type (lua_State *L);
|
||||
int luaB__ALERT (lua_State *L);
|
||||
int luaB__ERRORMESSAGE (lua_State *L);
|
||||
int luaB_assert (lua_State *L);
|
||||
int luaB_call (lua_State *L);
|
||||
int luaB_collectgarbage (lua_State *L);
|
||||
int luaB_copytagmethods (lua_State *L);
|
||||
int luaB_dofile (lua_State *L);
|
||||
int luaB_dostring (lua_State *L);
|
||||
int luaB_error (lua_State *L);
|
||||
int luaB_getglobal (lua_State *L);
|
||||
int luaB_getn (lua_State *L);
|
||||
int luaB_gettagmethod (lua_State *L);
|
||||
int luaB_globals (lua_State *L);
|
||||
int luaB_newtag (lua_State *L);
|
||||
int luaB_next (lua_State *L);
|
||||
int luaB_print (lua_State *L);
|
||||
int luaB_rawget (lua_State *L);
|
||||
int luaB_rawset (lua_State *L);
|
||||
int luaB_setglobal (lua_State *L);
|
||||
int luaB_settag (lua_State *L);
|
||||
int luaB_settagmethod (lua_State *L);
|
||||
int luaB_sort (lua_State *L);
|
||||
int luaB_tag (lua_State *L);
|
||||
int luaB_tinsert (lua_State *L);
|
||||
int luaB_tonumber (lua_State *L);
|
||||
int luaB_tostring (lua_State *L);
|
||||
int luaB_tremove (lua_State *L);
|
||||
int luaB_type (lua_State *L);
|
||||
|
||||
void luaB_predefine (lua_State *L);
|
||||
|
||||
|
104
ldblib.c
104
ldblib.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ldblib.c,v 1.17 2000/06/12 13:52:05 roberto Exp roberto $
|
||||
** $Id: ldblib.c,v 1.18 2000/08/09 19:16:57 roberto Exp roberto $
|
||||
** Interface from Lua to its debug API
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -17,102 +17,96 @@
|
||||
|
||||
|
||||
|
||||
static void settabss (lua_State *L, lua_Object t, const char *i, const char *v) {
|
||||
lua_pushobject(L, t);
|
||||
static void settabss (lua_State *L, const char *i, const char *v) {
|
||||
lua_pushobject(L, -1);
|
||||
lua_pushstring(L, i);
|
||||
lua_pushstring(L, v);
|
||||
lua_settable(L);
|
||||
}
|
||||
|
||||
|
||||
static void settabsi (lua_State *L, lua_Object t, const char *i, int v) {
|
||||
lua_pushobject(L, t);
|
||||
static void settabsi (lua_State *L, const char *i, int v) {
|
||||
lua_pushobject(L, -1);
|
||||
lua_pushstring(L, i);
|
||||
lua_pushnumber(L, v);
|
||||
lua_settable(L);
|
||||
}
|
||||
|
||||
|
||||
static void settabso (lua_State *L, lua_Object t, const char *i, lua_Object v) {
|
||||
lua_pushobject(L, t);
|
||||
lua_pushstring(L, i);
|
||||
lua_pushobject(L, v);
|
||||
lua_settable(L);
|
||||
}
|
||||
|
||||
|
||||
static void getinfo (lua_State *L) {
|
||||
static int getinfo (lua_State *L) {
|
||||
lua_Debug ar;
|
||||
lua_Object res;
|
||||
lua_Object func = lua_getparam(L, 1);
|
||||
const char *options = luaL_opt_string(L, 2, "flnSu");
|
||||
char buff[20];
|
||||
if (lua_isnumber(L, func)) {
|
||||
if (!lua_getstack(L, (int)lua_getnumber(L, func), &ar)) {
|
||||
if (lua_isnumber(L, 1)) {
|
||||
if (!lua_getstack(L, (int)lua_tonumber(L, 1), &ar)) {
|
||||
lua_pushnil(L); /* level out of range */
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if (lua_isfunction(L, func)) {
|
||||
ar.func = func;
|
||||
else if (lua_isfunction(L, 1)) {
|
||||
lua_pushobject(L, 1);
|
||||
sprintf(buff, ">%.10s", options);
|
||||
options = buff;
|
||||
}
|
||||
else
|
||||
luaL_argerror(L, 1, "function or level expected");
|
||||
res = lua_createtable(L);
|
||||
if (!lua_getinfo(L, options, &ar))
|
||||
luaL_argerror(L, 2, "invalid option");
|
||||
lua_newtable(L);
|
||||
for (; *options; options++) {
|
||||
switch (*options) {
|
||||
case 'S':
|
||||
settabss(L, res, "source", ar.source);
|
||||
settabsi(L, res, "linedefined", ar.linedefined);
|
||||
settabss(L, res, "what", ar.what);
|
||||
settabss(L, "source", ar.source);
|
||||
settabsi(L, "linedefined", ar.linedefined);
|
||||
settabss(L, "what", ar.what);
|
||||
break;
|
||||
case 'l':
|
||||
settabsi(L, res, "currentline", ar.currentline);
|
||||
settabsi(L, "currentline", ar.currentline);
|
||||
break;
|
||||
case 'u':
|
||||
settabsi(L, res, "nups", ar.nups);
|
||||
settabsi(L, "nups", ar.nups);
|
||||
break;
|
||||
case 'n':
|
||||
settabss(L, res, "name", ar.name);
|
||||
settabss(L, res, "namewhat", ar.namewhat);
|
||||
settabss(L, "name", ar.name);
|
||||
settabss(L, "namewhat", ar.namewhat);
|
||||
break;
|
||||
case 'f':
|
||||
settabso(L, res, "func", ar.func);
|
||||
lua_pushobject(L, -1);
|
||||
lua_pushstring(L, "func");
|
||||
lua_pushobject(L, -4);
|
||||
lua_settable(L);
|
||||
break;
|
||||
}
|
||||
}
|
||||
lua_pushobject(L, res);
|
||||
return 1; /* return table */
|
||||
}
|
||||
|
||||
|
||||
static void getlocal (lua_State *L) {
|
||||
static int getlocal (lua_State *L) {
|
||||
lua_Debug ar;
|
||||
lua_Localvar lvar;
|
||||
const char *name;
|
||||
if (!lua_getstack(L, luaL_check_int(L, 1), &ar)) /* level out of range? */
|
||||
luaL_argerror(L, 1, "level out of range");
|
||||
lvar.index = luaL_check_int(L, 2);
|
||||
if (lua_getlocal(L, &ar, &lvar)) {
|
||||
lua_pushstring(L, lvar.name);
|
||||
lua_pushobject(L, lvar.value);
|
||||
name = lua_getlocal(L, &ar, luaL_check_int(L, 2));
|
||||
if (name) {
|
||||
lua_pushstring(L, name);
|
||||
lua_pushobject(L, -2);
|
||||
return 2;
|
||||
}
|
||||
else {
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
else lua_pushnil(L);
|
||||
}
|
||||
|
||||
|
||||
static void setlocal (lua_State *L) {
|
||||
static int setlocal (lua_State *L) {
|
||||
lua_Debug ar;
|
||||
lua_Localvar lvar;
|
||||
if (!lua_getstack(L, luaL_check_int(L, 1), &ar)) /* level out of range? */
|
||||
luaL_argerror(L, 1, "level out of range");
|
||||
lvar.index = luaL_check_int(L, 2);
|
||||
lvar.value = luaL_nonnullarg(L, 3);
|
||||
if (lua_setlocal(L, &ar, &lvar))
|
||||
lua_pushstring(L, lvar.name);
|
||||
else lua_pushnil(L);
|
||||
luaL_checktype(L, 3, "any");
|
||||
lua_pushstring(L, lua_setlocal(L, &ar, luaL_check_int(L, 2)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@ -128,47 +122,47 @@ static int callhook = LUA_NOREF; /* Lua reference to call hook function */
|
||||
|
||||
static void linef (lua_State *L, lua_Debug *ar) {
|
||||
if (linehook != LUA_NOREF) {
|
||||
lua_getref(L, linehook);
|
||||
lua_pushnumber(L, ar->currentline);
|
||||
lua_callfunction(L, lua_getref(L, linehook));
|
||||
lua_call(L, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void callf (lua_State *L, lua_Debug *ar) {
|
||||
if (callhook != LUA_NOREF) {
|
||||
lua_getref(L, callhook);
|
||||
lua_pushstring(L, ar->event);
|
||||
lua_callfunction(L, lua_getref(L, callhook));
|
||||
lua_call(L, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void setcallhook (lua_State *L) {
|
||||
lua_Object f = lua_getparam(L, 1);
|
||||
static int setcallhook (lua_State *L) {
|
||||
lua_unref(L, callhook);
|
||||
if (f == LUA_NOOBJECT) {
|
||||
if (lua_isnull(L, 1)) {
|
||||
callhook = LUA_NOREF;
|
||||
lua_setcallhook(L, NULL);
|
||||
}
|
||||
else {
|
||||
lua_pushobject(L, f);
|
||||
callhook = lua_ref(L, 1);
|
||||
lua_setcallhook(L, callf);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void setlinehook (lua_State *L) {
|
||||
lua_Object f = lua_getparam(L, 1);
|
||||
static int setlinehook (lua_State *L) {
|
||||
lua_unref(L, linehook);
|
||||
if (f == LUA_NOOBJECT) {
|
||||
if (lua_isnull(L, 1)) {
|
||||
linehook = LUA_NOREF;
|
||||
lua_setlinehook(L, NULL);
|
||||
}
|
||||
else {
|
||||
lua_pushobject(L, f);
|
||||
linehook = lua_ref(L, 1);
|
||||
lua_setlinehook(L, linef);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
40
ldebug.c
40
ldebug.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ldebug.c,v 1.35 2000/08/14 17:59:20 roberto Exp roberto $
|
||||
** $Id: ldebug.c,v 1.36 2000/08/15 18:28:48 roberto Exp roberto $
|
||||
** Debug Interface
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -144,26 +144,28 @@ static Proto *getluaproto (StkId f) {
|
||||
}
|
||||
|
||||
|
||||
int lua_getlocal (lua_State *L, const lua_Debug *ar, lua_Localvar *v) {
|
||||
const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int localnum) {
|
||||
const char *name;
|
||||
StkId f = ar->_func;
|
||||
Proto *fp = getluaproto(f);
|
||||
if (!fp) return 0; /* `f' is not a Lua function? */
|
||||
v->name = luaF_getlocalname(fp, v->index, lua_currentpc(f));
|
||||
if (!v->name) return 0;
|
||||
v->value = luaA_putluaObject(L, (f+1)+(v->index-1));
|
||||
return 1;
|
||||
if (!fp) return NULL; /* `f' is not a Lua function? */
|
||||
name = luaF_getlocalname(fp, localnum, lua_currentpc(f));
|
||||
if (!name) return NULL;
|
||||
luaA_pushobject(L, (f+1)+(localnum-1)); /* push value */
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
int lua_setlocal (lua_State *L, const lua_Debug *ar, lua_Localvar *v) {
|
||||
const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int localnum) {
|
||||
const char *name;
|
||||
StkId f = ar->_func;
|
||||
Proto *fp = getluaproto(f);
|
||||
UNUSED(L);
|
||||
if (!fp) return 0; /* `f' is not a Lua function? */
|
||||
v->name = luaF_getlocalname(fp, v->index, lua_currentpc(f));
|
||||
if (!v->name || v->name[0] == '*') return 0; /* `*' starts private locals */
|
||||
*((f+1)+(v->index-1)) = *v->value;
|
||||
return 1;
|
||||
if (!fp) return NULL; /* `f' is not a Lua function? */
|
||||
name = luaF_getlocalname(fp, localnum, lua_currentpc(f));
|
||||
if (!name || name[0] == '*') return NULL; /* `*' starts private locals */
|
||||
*((f+1)+(localnum-1)) = *(--L->top);
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
@ -236,7 +238,7 @@ int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
|
||||
func = ar->_func;
|
||||
else {
|
||||
what++; /* skip the '>' */
|
||||
func = ar->func;
|
||||
func = L->top - 1;
|
||||
}
|
||||
for (; *what; what++) {
|
||||
switch (*what) {
|
||||
@ -260,13 +262,13 @@ int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
|
||||
}
|
||||
case 'f': {
|
||||
setnormalized(L->top, func);
|
||||
incr_top;
|
||||
ar->func = lua_pop(L);
|
||||
incr_top; /* push function */
|
||||
break;
|
||||
}
|
||||
default: return 0; /* invalid option */
|
||||
}
|
||||
}
|
||||
if (!isactive) L->top--; /* pop function */
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -420,7 +422,7 @@ static const char *getfuncname (lua_State *L, StkId f, const char **name) {
|
||||
void luaG_typeerror (lua_State *L, StkId o, const char *op) {
|
||||
const char *name;
|
||||
const char *kind = getobjname(L, o, &name);
|
||||
const char *t = lua_type(L, o);
|
||||
const char *t = luaO_typename(o);
|
||||
if (kind)
|
||||
luaL_verror(L, "attempt to %.30s %.20s `%.40s' (a %.10s value)",
|
||||
op, kind, name, t);
|
||||
@ -437,8 +439,8 @@ void luaG_binerror (lua_State *L, StkId p1, lua_Type t, const char *op) {
|
||||
|
||||
|
||||
void luaG_ordererror (lua_State *L, StkId top) {
|
||||
const char *t1 = lua_type(L, top-2);
|
||||
const char *t2 = lua_type(L, top-1);
|
||||
const char *t1 = luaO_typename(top-2);
|
||||
const char *t2 = luaO_typename(top-1);
|
||||
if (t1[2] == t2[2])
|
||||
luaL_verror(L, "attempt to compare two %.10s values", t1);
|
||||
else
|
||||
|
87
ldo.c
87
ldo.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ldo.c,v 1.84 2000/08/09 19:16:57 roberto Exp roberto $
|
||||
** $Id: ldo.c,v 1.85 2000/08/10 19:50:47 roberto Exp roberto $
|
||||
** Stack and Call structure of Lua
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -41,8 +41,7 @@ void luaD_init (lua_State *L, int stacksize) {
|
||||
L->stack = luaM_newvector(L, stacksize+EXTRA_STACK, TObject);
|
||||
L->stack_last = L->stack+(stacksize-1);
|
||||
L->stacksize = stacksize;
|
||||
L->Cstack.base = L->Cstack.lua2C = L->top = L->stack;
|
||||
L->Cstack.num = 0;
|
||||
L->Cbase = L->top = L->stack;
|
||||
}
|
||||
|
||||
|
||||
@ -68,8 +67,8 @@ void luaD_checkstack (lua_State *L, int n) {
|
||||
|
||||
|
||||
static void restore_stack_limit (lua_State *L) {
|
||||
if (L->top-L->stack < L->stacksize-1)
|
||||
L->stack_last = L->stack+(L->stacksize-1);
|
||||
if (L->top - L->stack < L->stacksize - 1)
|
||||
L->stack_last = L->stack + (L->stacksize-1);
|
||||
}
|
||||
|
||||
|
||||
@ -103,9 +102,8 @@ void luaD_openstack (lua_State *L, StkId pos) {
|
||||
void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook) {
|
||||
if (L->allowhooks) {
|
||||
lua_Debug ar;
|
||||
struct C_Lua_Stack oldCLS = L->Cstack;
|
||||
StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->top;
|
||||
L->Cstack.num = 0;
|
||||
StkId old_Cbase = L->Cbase;
|
||||
StkId old_top = L->Cbase = L->top;
|
||||
ar._func = func;
|
||||
ar.event = "line";
|
||||
ar.currentline = line;
|
||||
@ -113,7 +111,7 @@ void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook) {
|
||||
(*linehook)(L, &ar);
|
||||
L->allowhooks = 1;
|
||||
L->top = old_top;
|
||||
L->Cstack = oldCLS;
|
||||
L->Cbase = old_Cbase;
|
||||
}
|
||||
}
|
||||
|
||||
@ -122,42 +120,36 @@ static void luaD_callHook (lua_State *L, StkId func, lua_Hook callhook,
|
||||
const char *event) {
|
||||
if (L->allowhooks) {
|
||||
lua_Debug ar;
|
||||
struct C_Lua_Stack oldCLS = L->Cstack;
|
||||
StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->top;
|
||||
L->Cstack.num = 0;
|
||||
StkId old_Cbase = L->Cbase;
|
||||
StkId old_top = L->Cbase = L->top;
|
||||
ar._func = func;
|
||||
ar.event = event;
|
||||
L->allowhooks = 0; /* cannot call hooks inside a hook */
|
||||
callhook(L, &ar);
|
||||
L->allowhooks = 1;
|
||||
L->top = old_top;
|
||||
L->Cstack = oldCLS;
|
||||
L->Cbase = old_Cbase;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static StkId callCclosure (lua_State *L, const struct Closure *cl, StkId base) {
|
||||
int nup = cl->nupvalues; /* number of upvalues */
|
||||
int numarg = L->top-base;
|
||||
struct C_Lua_Stack oldCLS = L->Cstack;
|
||||
StkId firstResult;
|
||||
StkId old_Cbase = L->Cbase;
|
||||
int nres; /* number of results */
|
||||
if (nup > 0) {
|
||||
int n = numarg;
|
||||
int n = L->top - base; /* number of arguments */
|
||||
luaD_checkstack(L, nup);
|
||||
/* open space for upvalues as extra arguments */
|
||||
while (n--) *(base+nup+n) = *(base+n);
|
||||
L->top += nup;
|
||||
numarg += nup;
|
||||
/* copy upvalues into stack */
|
||||
while (nup--) *(base+nup) = cl->upvalue[nup];
|
||||
}
|
||||
L->Cstack.num = numarg;
|
||||
L->Cstack.lua2C = base;
|
||||
L->Cstack.base = L->top;
|
||||
(*cl->f.c)(L); /* do the actual call */
|
||||
firstResult = L->Cstack.base;
|
||||
L->Cstack = oldCLS;
|
||||
return firstResult;
|
||||
L->Cbase = base; /* new base for C function */
|
||||
nres = (*cl->f.c)(L); /* do the actual call */
|
||||
L->Cbase = old_Cbase; /* restore old C base */
|
||||
return L->top - nres; /* return index of first result */
|
||||
}
|
||||
|
||||
|
||||
@ -257,42 +249,36 @@ void lua_error (lua_State *L, const char *s) {
|
||||
|
||||
|
||||
static void chain_longjmp (lua_State *L, struct lua_longjmp *lj) {
|
||||
lj->base = L->Cstack.base;
|
||||
lj->numCblocks = L->numCblocks;
|
||||
lj->status = 0;
|
||||
lj->base = L->Cbase;
|
||||
lj->previous = L->errorJmp;
|
||||
L->errorJmp = lj;
|
||||
}
|
||||
|
||||
|
||||
static void restore_longjmp (lua_State *L, struct lua_longjmp *lj) {
|
||||
L->Cstack.num = 0; /* no results */
|
||||
L->top = L->Cstack.base = L->Cstack.lua2C = lj->base;
|
||||
L->numCblocks = lj->numCblocks;
|
||||
static int restore_longjmp (lua_State *L, struct lua_longjmp *lj) {
|
||||
L->Cbase = lj->base;
|
||||
L->errorJmp = lj->previous;
|
||||
return lj->status;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Execute a protected call. Assumes that function is at Cstack.base and
|
||||
** parameters are on top of it.
|
||||
** Execute a protected call.
|
||||
*/
|
||||
int luaD_protectedrun (lua_State *L) {
|
||||
int lua_call (lua_State *L, int nargs, int nresults) {
|
||||
StkId func = L->top - (nargs+1); /* function to be called */
|
||||
struct lua_longjmp myErrorJmp;
|
||||
chain_longjmp(L, &myErrorJmp);
|
||||
if (nresults == LUA_MULTRET) nresults = MULT_RET; /* internal code */
|
||||
if (setjmp(myErrorJmp.b) == 0) {
|
||||
StkId base = L->Cstack.base;
|
||||
luaD_call(L, base, MULT_RET);
|
||||
L->Cstack.lua2C = base; /* position of the new results */
|
||||
L->Cstack.num = L->top - base;
|
||||
L->Cstack.base = base + L->Cstack.num; /* incorporate results on stack */
|
||||
L->errorJmp = myErrorJmp.previous;
|
||||
return 0;
|
||||
luaD_call(L, func, nresults);
|
||||
}
|
||||
else { /* an error occurred: restore the stack */
|
||||
restore_longjmp(L, &myErrorJmp);
|
||||
else { /* an error occurred: restore the state */
|
||||
L->top = func; /* remove garbage from the stack */
|
||||
restore_stack_limit(L);
|
||||
return myErrorJmp.status;
|
||||
}
|
||||
return restore_longjmp(L, &myErrorJmp);
|
||||
}
|
||||
|
||||
|
||||
@ -302,20 +288,17 @@ int luaD_protectedrun (lua_State *L) {
|
||||
static int protectedparser (lua_State *L, ZIO *z, int bin) {
|
||||
struct lua_longjmp myErrorJmp;
|
||||
chain_longjmp(L, &myErrorJmp);
|
||||
L->top = L->Cstack.base; /* clear C2Lua */
|
||||
if (setjmp(myErrorJmp.b) == 0) {
|
||||
Proto *tf = bin ? luaU_undump1(L, z) : luaY_parser(L, z);
|
||||
L->errorJmp = myErrorJmp.previous;
|
||||
if (tf == NULL) return -1; /* `natural' end */
|
||||
if (tf == NULL)
|
||||
myErrorJmp.status = -1; /* `natural' end */
|
||||
luaV_Lclosure(L, tf, 0);
|
||||
return 0;
|
||||
}
|
||||
else { /* an error occurred */
|
||||
restore_longjmp(L, &myErrorJmp);
|
||||
else { /* an error occurred: correct error code */
|
||||
if (myErrorJmp.status == LUA_ERRRUN)
|
||||
myErrorJmp.status = LUA_ERRSYNTAX;
|
||||
return myErrorJmp.status; /* error code */
|
||||
}
|
||||
return restore_longjmp(L, &myErrorJmp); /* error code */
|
||||
}
|
||||
|
||||
|
||||
@ -331,7 +314,7 @@ static int do_main (lua_State *L, ZIO *z, int bin) {
|
||||
else {
|
||||
unsigned long newelems2 = 2*(L->nblocks-old_blocks);
|
||||
L->GCthreshold += newelems2;
|
||||
status = luaD_protectedrun(L);
|
||||
status = lua_call(L, 0, LUA_MULTRET);
|
||||
L->GCthreshold -= newelems2;
|
||||
}
|
||||
} while (bin && status == 0);
|
||||
|
3
ldo.h
3
ldo.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ldo.h,v 1.21 2000/06/28 20:21:06 roberto Exp roberto $
|
||||
** $Id: ldo.h,v 1.22 2000/08/07 18:39:16 roberto Exp roberto $
|
||||
** Stack and Call structure of Lua
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -26,7 +26,6 @@ void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook);
|
||||
void luaD_call (lua_State *L, StkId func, int nResults);
|
||||
void luaD_callTM (lua_State *L, const TObject *f, int nParams, int nResults);
|
||||
void luaD_breakrun (lua_State *L, int errcode);
|
||||
int luaD_protectedrun (lua_State *L);
|
||||
void luaD_checkstack (lua_State *L, int n);
|
||||
|
||||
|
||||
|
42
lgc.c
42
lgc.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lgc.c,v 1.62 2000/08/09 19:16:57 roberto Exp roberto $
|
||||
** $Id: lgc.c,v 1.63 2000/08/22 17:44:17 roberto Exp roberto $
|
||||
** Garbage Collector
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -11,7 +11,6 @@
|
||||
#include "lgc.h"
|
||||
#include "lmem.h"
|
||||
#include "lobject.h"
|
||||
#include "lref.h"
|
||||
#include "lstate.h"
|
||||
#include "lstring.h"
|
||||
#include "ltable.h"
|
||||
@ -145,6 +144,43 @@ static void markall (lua_State *L) {
|
||||
}
|
||||
|
||||
|
||||
static int hasmark (const TObject *o) {
|
||||
/* valid only for locked objects */
|
||||
switch (o->ttype) {
|
||||
case TAG_STRING: case TAG_USERDATA:
|
||||
return tsvalue(o)->marked;
|
||||
case TAG_TABLE:
|
||||
return ismarked(hvalue(o));
|
||||
case TAG_LCLOSURE: case TAG_CCLOSURE:
|
||||
return ismarked(clvalue(o)->mark);
|
||||
default: /* number */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* macro for internal debugging; check if a link of free refs is valid */
|
||||
#define VALIDLINK(L, st,n) (NONEXT <= (st) && (st) < (n))
|
||||
|
||||
static void invalidaterefs (lua_State *L) {
|
||||
int n = L->refSize;
|
||||
int i;
|
||||
for (i=0; i<n; i++) {
|
||||
struct Ref *r = &L->refArray[i];
|
||||
if (r->st == HOLD && !hasmark(&r->o))
|
||||
r->st = COLLECTED;
|
||||
LUA_ASSERT((r->st == LOCK && hasmark(&r->o)) ||
|
||||
(r->st == HOLD && hasmark(&r->o)) ||
|
||||
r->st == COLLECTED ||
|
||||
r->st == NONEXT ||
|
||||
(r->st < n && VALIDLINK(L, L->refArray[r->st].st, n)),
|
||||
"inconsistent ref table");
|
||||
}
|
||||
LUA_ASSERT(VALIDLINK(L, L->refFree, n), "inconsistent ref table");
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void collectproto (lua_State *L) {
|
||||
Proto **p = &L->rootproto;
|
||||
Proto *next;
|
||||
@ -300,7 +336,7 @@ void luaC_collect (lua_State *L, int all) {
|
||||
long lua_collectgarbage (lua_State *L, long limit) {
|
||||
unsigned long recovered = L->nblocks; /* to subtract `nblocks' after gc */
|
||||
markall(L);
|
||||
luaR_invalidaterefs(L);
|
||||
invalidaterefs(L);
|
||||
luaC_collect(L, 0);
|
||||
recovered = recovered - L->nblocks;
|
||||
L->GCthreshold = (limit == 0) ? 2*L->nblocks : L->nblocks+limit;
|
||||
|
196
liolib.c
196
liolib.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: liolib.c,v 1.70 2000/08/14 19:10:14 roberto Exp roberto $
|
||||
** $Id: liolib.c,v 1.71 2000/08/22 17:47:17 roberto Exp roberto $
|
||||
** Standard I/O (and system) library
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -61,13 +61,16 @@ typedef struct IOCtrl {
|
||||
static const char *const filenames[] = {"_INPUT", "_OUTPUT"};
|
||||
|
||||
|
||||
static void pushresult (lua_State *L, int i) {
|
||||
if (i)
|
||||
static int pushresult (lua_State *L, int i) {
|
||||
if (i) {
|
||||
lua_pushuserdata(L, NULL);
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, strerror(errno));
|
||||
lua_pushnumber(L, errno);
|
||||
return 3;;
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,8 +82,8 @@ static void pushresult (lua_State *L, int i) {
|
||||
*/
|
||||
|
||||
|
||||
static FILE *gethandle (lua_State *L, IOCtrl *ctrl, lua_Object f) {
|
||||
void *p = lua_getuserdata(L, f);
|
||||
static FILE *gethandle (lua_State *L, IOCtrl *ctrl, int f) {
|
||||
void *p = lua_touserdata(L, f);
|
||||
if (p != NULL) { /* is `f' a userdata ? */
|
||||
int ftag = lua_tag(L, f);
|
||||
if (ftag == ctrl->iotag) /* does it have the correct tag? */
|
||||
@ -94,7 +97,7 @@ static FILE *gethandle (lua_State *L, IOCtrl *ctrl, lua_Object f) {
|
||||
|
||||
|
||||
static FILE *getnonullfile (lua_State *L, IOCtrl *ctrl, int arg) {
|
||||
FILE *f = gethandle(L, ctrl, lua_getparam(L, arg));
|
||||
FILE *f = gethandle(L, ctrl, arg);
|
||||
luaL_arg_check(L, f, arg, "invalid file handle");
|
||||
return f;
|
||||
}
|
||||
@ -102,9 +105,11 @@ static FILE *getnonullfile (lua_State *L, IOCtrl *ctrl, int arg) {
|
||||
|
||||
static FILE *getfilebyref (lua_State *L, IOCtrl *ctrl, int inout) {
|
||||
FILE *f;
|
||||
lua_pushglobals(L);
|
||||
lua_pushref(L, ctrl->ref[inout]);
|
||||
f = gethandle(L, ctrl, lua_rawget(L));
|
||||
lua_getglobals(L);
|
||||
lua_getref(L, ctrl->ref[inout]);
|
||||
lua_rawget(L);
|
||||
f = gethandle(L, ctrl, -1);
|
||||
lua_settop(L, -1); /* remove global */
|
||||
if (f == NULL)
|
||||
luaL_verror(L, "global variable `%.10s' is not a file handle",
|
||||
filenames[inout]);
|
||||
@ -122,12 +127,13 @@ static void setfilebyname (lua_State *L, IOCtrl *ctrl, FILE *f,
|
||||
#define setfile(L,ctrl,f,inout) (setfilebyname(L,ctrl,f,filenames[inout]))
|
||||
|
||||
|
||||
static void setreturn (lua_State *L, IOCtrl *ctrl, FILE *f, int inout) {
|
||||
static int setreturn (lua_State *L, IOCtrl *ctrl, FILE *f, int inout) {
|
||||
if (f == NULL)
|
||||
pushresult(L, 0);
|
||||
return pushresult(L, 0);
|
||||
else {
|
||||
setfile(L, ctrl, f, inout);
|
||||
lua_pushusertag(L, f, ctrl->iotag);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -143,15 +149,15 @@ static int closefile (lua_State *L, IOCtrl *ctrl, FILE *f) {
|
||||
}
|
||||
|
||||
|
||||
static void io_close (lua_State *L) {
|
||||
IOCtrl *ctrl = (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 1));
|
||||
pushresult(L, closefile(L, ctrl, getnonullfile(L, ctrl, 2)));
|
||||
static int io_close (lua_State *L) {
|
||||
IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1);
|
||||
return pushresult(L, closefile(L, ctrl, getnonullfile(L, ctrl, 2)));
|
||||
}
|
||||
|
||||
|
||||
static void file_collect (lua_State *L) {
|
||||
IOCtrl *ctrl = (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 1));
|
||||
if (ctrl == (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 2))) {
|
||||
static int file_collect (lua_State *L) {
|
||||
IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1);
|
||||
if (ctrl == (IOCtrl *)lua_touserdata(L, 2)) {
|
||||
/* collectig `ctrl' itself */
|
||||
lua_unref(L, ctrl->ref[INFILE]);
|
||||
lua_unref(L, ctrl->ref[OUTFILE]);
|
||||
@ -162,50 +168,54 @@ static void file_collect (lua_State *L) {
|
||||
if (f != stdin && f != stdout && f != stderr)
|
||||
CLOSEFILE(L, f);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void io_open (lua_State *L) {
|
||||
IOCtrl *ctrl = (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 1));
|
||||
static int io_open (lua_State *L) {
|
||||
IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1);
|
||||
FILE *f = fopen(luaL_check_string(L, 2), luaL_check_string(L, 3));
|
||||
if (f) lua_pushusertag(L, f, ctrl->iotag);
|
||||
else pushresult(L, 0);
|
||||
if (f) {
|
||||
lua_pushusertag(L, f, ctrl->iotag);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return pushresult(L, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void io_fromto (lua_State *L, int inout, const char *mode) {
|
||||
IOCtrl *ctrl = (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 1));
|
||||
lua_Object f = lua_getparam(L, 2);
|
||||
static int io_fromto (lua_State *L, int inout, const char *mode) {
|
||||
IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1);
|
||||
FILE *current;
|
||||
if (f == LUA_NOOBJECT) {
|
||||
if (lua_isnull(L, 2)) {
|
||||
closefile(L, ctrl, getfilebyref(L, ctrl, inout));
|
||||
current = (inout == 0) ? stdin : stdout;
|
||||
}
|
||||
else if (lua_tag(L, f) == ctrl->iotag) /* deprecated option */
|
||||
current = (FILE *)lua_getuserdata(L, f);
|
||||
else if (lua_tag(L, 2) == ctrl->iotag) /* deprecated option */
|
||||
current = (FILE *)lua_touserdata(L, 2);
|
||||
else {
|
||||
const char *s = luaL_check_string(L, 2);
|
||||
current = (*s == '|') ? popen(s+1, mode) : fopen(s, mode);
|
||||
}
|
||||
setreturn(L, ctrl, current, inout);
|
||||
return setreturn(L, ctrl, current, inout);
|
||||
}
|
||||
|
||||
|
||||
static void io_readfrom (lua_State *L) {
|
||||
io_fromto(L, INFILE, "r");
|
||||
static int io_readfrom (lua_State *L) {
|
||||
return io_fromto(L, INFILE, "r");
|
||||
}
|
||||
|
||||
|
||||
static void io_writeto (lua_State *L) {
|
||||
io_fromto(L, OUTFILE, "w");
|
||||
static int io_writeto (lua_State *L) {
|
||||
return io_fromto(L, OUTFILE, "w");
|
||||
}
|
||||
|
||||
|
||||
static void io_appendto (lua_State *L) {
|
||||
IOCtrl *ctrl = (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 1));
|
||||
static int io_appendto (lua_State *L) {
|
||||
IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1);
|
||||
FILE *current = fopen(luaL_check_string(L, 2), "a");
|
||||
setreturn(L, ctrl, current, OUTFILE);
|
||||
return setreturn(L, ctrl, current, OUTFILE);
|
||||
}
|
||||
|
||||
|
||||
@ -342,28 +352,29 @@ static int read_chars (lua_State *L, FILE *f, size_t n) {
|
||||
}
|
||||
|
||||
|
||||
static void io_read (lua_State *L) {
|
||||
IOCtrl *ctrl = (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 1));
|
||||
int arg = 2;
|
||||
lua_Object op;
|
||||
FILE *f = gethandle(L, ctrl, lua_getparam(L, arg));
|
||||
if (f) arg++;
|
||||
static int io_read (lua_State *L) {
|
||||
IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1);
|
||||
int lastarg = lua_gettop(L);
|
||||
int firstarg = 2;
|
||||
FILE *f = gethandle(L, ctrl, firstarg);
|
||||
int n = 0;
|
||||
if (f) firstarg++;
|
||||
else f = getfilebyref(L, ctrl, INFILE); /* get _INPUT */
|
||||
op = lua_getparam(L, arg);
|
||||
do { /* repeat for each part */
|
||||
size_t l;
|
||||
int success;
|
||||
luaL_resetbuffer(L);
|
||||
if (lua_isnumber(L, op))
|
||||
success = read_chars(L, f, (size_t)lua_getnumber(L, op));
|
||||
if (lua_isnumber(L, firstarg+n))
|
||||
success = read_chars(L, f, (size_t)lua_tonumber(L, firstarg+n));
|
||||
else {
|
||||
const char *p = luaL_opt_string(L, arg, "*l");
|
||||
const char *p = luaL_opt_string(L, firstarg+n, "*l");
|
||||
if (p[0] != '*')
|
||||
success = read_pattern(L, f, p); /* deprecated! */
|
||||
else {
|
||||
switch (p[1]) {
|
||||
case 'n': /* number */
|
||||
if (!read_number(L, f)) return; /* read fails */
|
||||
if (!read_number(L, f)) return n; /* read fails */
|
||||
n++;
|
||||
continue; /* number is already pushed; avoid the "pushstring" */
|
||||
case 'l': /* line */
|
||||
success = read_line(L, f);
|
||||
@ -377,66 +388,69 @@ static void io_read (lua_State *L) {
|
||||
success = 0; /* must read something to succeed */
|
||||
break;
|
||||
default:
|
||||
luaL_argerror(L, arg, "invalid format");
|
||||
luaL_argerror(L, firstarg+n, "invalid format");
|
||||
success = 0; /* to avoid warnings */
|
||||
}
|
||||
}
|
||||
}
|
||||
l = luaL_getsize(L);
|
||||
if (!success && l==0) return; /* read fails */
|
||||
if (!success && l==0) return n; /* read fails */
|
||||
lua_pushlstring(L, luaL_buffer(L), l);
|
||||
} while ((op = lua_getparam(L, ++arg)) != LUA_NOOBJECT);
|
||||
n++;
|
||||
} while (firstarg+n <= lastarg);
|
||||
return n;
|
||||
}
|
||||
|
||||
/* }====================================================== */
|
||||
|
||||
|
||||
static void io_write (lua_State *L) {
|
||||
IOCtrl *ctrl = (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 1));
|
||||
static int io_write (lua_State *L) {
|
||||
int lastarg = lua_gettop(L);
|
||||
IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1);
|
||||
int arg = 2;
|
||||
int status = 1;
|
||||
lua_Object o;
|
||||
FILE *f = gethandle(L, ctrl, lua_getparam(L, arg));
|
||||
FILE *f = gethandle(L, ctrl, arg);
|
||||
if (f) arg++;
|
||||
else f = getfilebyref(L, ctrl, OUTFILE); /* get _OUTPUT */
|
||||
while ((o = lua_getparam(L, arg)) != LUA_NOOBJECT) {
|
||||
if (lua_type(L, o)[2] == 'm') { /* nuMber? */ /* LUA_NUMBER */
|
||||
for (; arg <= lastarg; arg++) {
|
||||
if (lua_type(L, arg)[2] == 'm') { /* nuMber? */ /* LUA_NUMBER */
|
||||
/* optimization: could be done exactly as for strings */
|
||||
status = status && fprintf(f, "%.16g", lua_getnumber(L, o)) > 0;
|
||||
status = status && fprintf(f, "%.16g", lua_tonumber(L, arg)) > 0;
|
||||
}
|
||||
else {
|
||||
size_t l;
|
||||
const char *s = luaL_check_lstr(L, arg, &l);
|
||||
status = status && (fwrite(s, sizeof(char), l, f) == l);
|
||||
}
|
||||
arg++;
|
||||
}
|
||||
pushresult(L, status);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void io_seek (lua_State *L) {
|
||||
static int io_seek (lua_State *L) {
|
||||
static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
|
||||
static const char *const modenames[] = {"set", "cur", "end", NULL};
|
||||
IOCtrl *ctrl = (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 1));
|
||||
IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1);
|
||||
FILE *f = getnonullfile(L, ctrl, 2);
|
||||
int op = luaL_findstring(luaL_opt_string(L, 3, "cur"), modenames);
|
||||
long offset = luaL_opt_long(L, 4, 0);
|
||||
luaL_arg_check(L, op != -1, 3, "invalid mode");
|
||||
op = fseek(f, offset, mode[op]);
|
||||
if (op)
|
||||
pushresult(L, 0); /* error */
|
||||
else
|
||||
return pushresult(L, 0); /* error */
|
||||
else {
|
||||
lua_pushnumber(L, ftell(f));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void io_flush (lua_State *L) {
|
||||
IOCtrl *ctrl = (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 1));
|
||||
lua_Object of = lua_getparam(L, 2);
|
||||
FILE *f = gethandle(L, ctrl, of);
|
||||
luaL_arg_check(L, f || of == LUA_NOOBJECT, 2, "invalid file handle");
|
||||
pushresult(L, fflush(f) == 0);
|
||||
static int io_flush (lua_State *L) {
|
||||
IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1);
|
||||
FILE *f = gethandle(L, ctrl, 2);
|
||||
luaL_arg_check(L, f || lua_isnull(L, 2), 2, "invalid file handle");
|
||||
return pushresult(L, fflush(f) == 0);
|
||||
}
|
||||
|
||||
/* }====================================================== */
|
||||
@ -448,39 +462,43 @@ static void io_flush (lua_State *L) {
|
||||
** =======================================================
|
||||
*/
|
||||
|
||||
static void io_execute (lua_State *L) {
|
||||
static int io_execute (lua_State *L) {
|
||||
lua_pushnumber(L, system(luaL_check_string(L, 1)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void io_remove (lua_State *L) {
|
||||
pushresult(L, remove(luaL_check_string(L, 1)) == 0);
|
||||
static int io_remove (lua_State *L) {
|
||||
return pushresult(L, remove(luaL_check_string(L, 1)) == 0);
|
||||
}
|
||||
|
||||
|
||||
static void io_rename (lua_State *L) {
|
||||
pushresult(L, rename(luaL_check_string(L, 1),
|
||||
static int io_rename (lua_State *L) {
|
||||
return pushresult(L, rename(luaL_check_string(L, 1),
|
||||
luaL_check_string(L, 2)) == 0);
|
||||
}
|
||||
|
||||
|
||||
static void io_tmpname (lua_State *L) {
|
||||
static int io_tmpname (lua_State *L) {
|
||||
lua_pushstring(L, tmpnam(NULL));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void io_getenv (lua_State *L) {
|
||||
static int io_getenv (lua_State *L) {
|
||||
lua_pushstring(L, getenv(luaL_check_string(L, 1))); /* if NULL push nil */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void io_clock (lua_State *L) {
|
||||
static int io_clock (lua_State *L) {
|
||||
lua_pushnumber(L, ((double)clock())/CLOCKS_PER_SEC);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void io_date (lua_State *L) {
|
||||
static int io_date (lua_State *L) {
|
||||
char b[256];
|
||||
const char *s = luaL_opt_string(L, 1, "%c");
|
||||
struct tm *stm;
|
||||
@ -490,10 +508,11 @@ static void io_date (lua_State *L) {
|
||||
lua_pushstring(L, b);
|
||||
else
|
||||
lua_error(L, "invalid `date' format");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void setloc (lua_State *L) {
|
||||
static int setloc (lua_State *L) {
|
||||
static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY,
|
||||
LC_NUMERIC, LC_TIME};
|
||||
static const char *const catnames[] = {"all", "collate", "ctype", "monetary",
|
||||
@ -501,25 +520,28 @@ static void setloc (lua_State *L) {
|
||||
int op = luaL_findstring(luaL_opt_string(L, 2, "all"), catnames);
|
||||
luaL_arg_check(L, op != -1, 2, "invalid option");
|
||||
lua_pushstring(L, setlocale(cat[op], luaL_check_string(L, 1)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void io_exit (lua_State *L) {
|
||||
static int io_exit (lua_State *L) {
|
||||
exit(luaL_opt_int(L, 1, EXIT_SUCCESS));
|
||||
return 0; /* to avoid warnings */
|
||||
}
|
||||
|
||||
/* }====================================================== */
|
||||
|
||||
|
||||
|
||||
static void io_debug (lua_State *L) {
|
||||
static int io_debug (lua_State *L) {
|
||||
for (;;) {
|
||||
char buffer[250];
|
||||
fprintf(stderr, "lua_debug> ");
|
||||
if (fgets(buffer, sizeof(buffer), stdin) == 0 ||
|
||||
strcmp(buffer, "cont\n") == 0)
|
||||
return;
|
||||
return 0;
|
||||
lua_dostring(L, buffer);
|
||||
lua_settop(L, 0); /* remove eventual returns */
|
||||
}
|
||||
}
|
||||
|
||||
@ -529,12 +551,11 @@ static void io_debug (lua_State *L) {
|
||||
#define MAXMESSAGE (MESSAGESIZE*10)
|
||||
|
||||
|
||||
static void errorfb (lua_State *L) {
|
||||
static int errorfb (lua_State *L) {
|
||||
char buff[MAXMESSAGE];
|
||||
int level = 1; /* skip level 0 (it's this function) */
|
||||
lua_Debug ar;
|
||||
lua_Object alertfunc;
|
||||
sprintf(buff, "error: %.200s\n", lua_getstring(L, lua_getparam(L, 1)));
|
||||
sprintf(buff, "error: %.200s\n", lua_tostring(L, 1));
|
||||
while (lua_getstack(L, level++, &ar)) {
|
||||
char buffchunk[60];
|
||||
lua_getinfo(L, "Snl", &ar);
|
||||
@ -572,13 +593,14 @@ static void errorfb (lua_State *L) {
|
||||
sprintf(buff+strlen(buff), " [%.70s]", buffchunk);
|
||||
strcat(buff, "\n");
|
||||
}
|
||||
lua_pushglobals(L);
|
||||
lua_getglobals(L);
|
||||
lua_pushstring(L, LUA_ALERT);
|
||||
alertfunc = lua_rawget(L);
|
||||
if (lua_isfunction(L, alertfunc)) { /* avoid loop if _ALERT is not defined */
|
||||
lua_rawget(L);
|
||||
if (lua_isfunction(L, -1)) { /* avoid loop if _ALERT is not defined */
|
||||
lua_pushstring(L, buff);
|
||||
lua_callfunction(L, alertfunc);
|
||||
lua_call(L, 1, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: llimits.h,v 1.11 2000/06/28 17:03:32 roberto Exp roberto $
|
||||
** $Id: llimits.h,v 1.12 2000/08/15 18:28:48 roberto Exp roberto $
|
||||
** Limits, basic types, and some other "installation-dependent" definitions
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -197,12 +197,6 @@ typedef unsigned long Instruction;
|
||||
#define RFIELDS_PER_FLUSH (LFIELDS_PER_FLUSH/2)
|
||||
|
||||
|
||||
/* maximum number of values printed in one call to `print' */
|
||||
#ifndef MAXPRINT
|
||||
#define MAXPRINT 40 /* arbitrary limit */
|
||||
#endif
|
||||
|
||||
|
||||
/* maximum lookback to find a real constant (for code generation) */
|
||||
#ifndef LOOKBACKNUMS
|
||||
#define LOOKBACKNUMS 20 /* arbitrary constant */
|
||||
|
118
lmathlib.c
118
lmathlib.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lmathlib.c,v 1.25 2000/06/12 13:52:05 roberto Exp roberto $
|
||||
** $Id: lmathlib.c,v 1.26 2000/08/09 19:16:57 roberto Exp roberto $
|
||||
** Standard mathematical library
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -33,138 +33,169 @@
|
||||
#endif
|
||||
|
||||
|
||||
static void math_abs (lua_State *L) {
|
||||
static int math_abs (lua_State *L) {
|
||||
lua_pushnumber(L, fabs(luaL_check_number(L, 1)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void math_sin (lua_State *L) {
|
||||
static int math_sin (lua_State *L) {
|
||||
lua_pushnumber(L, sin(TORAD(luaL_check_number(L, 1))));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void math_cos (lua_State *L) {
|
||||
static int math_cos (lua_State *L) {
|
||||
lua_pushnumber(L, cos(TORAD(luaL_check_number(L, 1))));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void math_tan (lua_State *L) {
|
||||
static int math_tan (lua_State *L) {
|
||||
lua_pushnumber(L, tan(TORAD(luaL_check_number(L, 1))));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void math_asin (lua_State *L) {
|
||||
static int math_asin (lua_State *L) {
|
||||
lua_pushnumber(L, FROMRAD(asin(luaL_check_number(L, 1))));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void math_acos (lua_State *L) {
|
||||
static int math_acos (lua_State *L) {
|
||||
lua_pushnumber(L, FROMRAD(acos(luaL_check_number(L, 1))));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void math_atan (lua_State *L) {
|
||||
static int math_atan (lua_State *L) {
|
||||
lua_pushnumber(L, FROMRAD(atan(luaL_check_number(L, 1))));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void math_atan2 (lua_State *L) {
|
||||
static int math_atan2 (lua_State *L) {
|
||||
lua_pushnumber(L, FROMRAD(atan2(luaL_check_number(L, 1), luaL_check_number(L, 2))));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void math_ceil (lua_State *L) {
|
||||
static int math_ceil (lua_State *L) {
|
||||
lua_pushnumber(L, ceil(luaL_check_number(L, 1)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void math_floor (lua_State *L) {
|
||||
static int math_floor (lua_State *L) {
|
||||
lua_pushnumber(L, floor(luaL_check_number(L, 1)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void math_mod (lua_State *L) {
|
||||
static int math_mod (lua_State *L) {
|
||||
lua_pushnumber(L, fmod(luaL_check_number(L, 1), luaL_check_number(L, 2)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void math_sqrt (lua_State *L) {
|
||||
static int math_sqrt (lua_State *L) {
|
||||
lua_pushnumber(L, sqrt(luaL_check_number(L, 1)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void math_pow (lua_State *L) {
|
||||
static int math_pow (lua_State *L) {
|
||||
lua_pushnumber(L, pow(luaL_check_number(L, 1), luaL_check_number(L, 2)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void math_log (lua_State *L) {
|
||||
static int math_log (lua_State *L) {
|
||||
lua_pushnumber(L, log(luaL_check_number(L, 1)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void math_log10 (lua_State *L) {
|
||||
static int math_log10 (lua_State *L) {
|
||||
lua_pushnumber(L, log10(luaL_check_number(L, 1)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void math_exp (lua_State *L) {
|
||||
static int math_exp (lua_State *L) {
|
||||
lua_pushnumber(L, exp(luaL_check_number(L, 1)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void math_deg (lua_State *L) {
|
||||
static int math_deg (lua_State *L) {
|
||||
lua_pushnumber(L, luaL_check_number(L, 1)/RADIANS_PER_DEGREE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void math_rad (lua_State *L) {
|
||||
static int math_rad (lua_State *L) {
|
||||
lua_pushnumber(L, luaL_check_number(L, 1)*RADIANS_PER_DEGREE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void math_frexp (lua_State *L) {
|
||||
static int math_frexp (lua_State *L) {
|
||||
int e;
|
||||
lua_pushnumber(L, frexp(luaL_check_number(L, 1), &e));
|
||||
lua_pushnumber(L, e);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static void math_ldexp (lua_State *L) {
|
||||
static int math_ldexp (lua_State *L) {
|
||||
lua_pushnumber(L, ldexp(luaL_check_number(L, 1), luaL_check_int(L, 2)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void math_min (lua_State *L) {
|
||||
int i = 1;
|
||||
double dmin = luaL_check_number(L, i);
|
||||
while (lua_getparam(L, ++i) != LUA_NOOBJECT) {
|
||||
static int math_min (lua_State *L) {
|
||||
int n = lua_gettop(L); /* number of arguments */
|
||||
double dmin = luaL_check_number(L, 1);
|
||||
int i;
|
||||
for (i=2; i<=n; i++) {
|
||||
double d = luaL_check_number(L, i);
|
||||
if (d < dmin)
|
||||
dmin = d;
|
||||
}
|
||||
lua_pushnumber(L, dmin);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void math_max (lua_State *L) {
|
||||
int i = 1;
|
||||
double dmax = luaL_check_number(L, i);
|
||||
while (lua_getparam(L, ++i) != LUA_NOOBJECT) {
|
||||
static int math_max (lua_State *L) {
|
||||
int n = lua_gettop(L); /* number of arguments */
|
||||
double dmax = luaL_check_number(L, 1);
|
||||
int i;
|
||||
for (i=2; i<=n; i++) {
|
||||
double d = luaL_check_number(L, i);
|
||||
if (d > dmax)
|
||||
dmax = d;
|
||||
}
|
||||
lua_pushnumber(L, dmax);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void math_random (lua_State *L) {
|
||||
static int math_random (lua_State *L) {
|
||||
/* the '%' avoids the (rare) case of r==1, and is needed also because on
|
||||
some systems (SunOS!) "rand()" may return a value larger than RAND_MAX */
|
||||
double r = (double)(rand()%RAND_MAX) / (double)RAND_MAX;
|
||||
if (lua_getparam(L, 1) == LUA_NOOBJECT) /* no arguments? */
|
||||
switch (lua_gettop(L)) { /* check number of arguments */
|
||||
case 0: { /* no arguments */
|
||||
lua_pushnumber(L, r); /* Number between 0 and 1 */
|
||||
else {
|
||||
int l, u; /* lower & upper limits */
|
||||
if (lua_getparam(L, 2) == LUA_NOOBJECT) { /* only one argument? */
|
||||
l = 1;
|
||||
u = luaL_check_int(L, 1);
|
||||
break;
|
||||
}
|
||||
else { /* two arguments */
|
||||
l = luaL_check_int(L, 1);
|
||||
u = luaL_check_int(L, 2);
|
||||
case 1: { /* only upper limit */
|
||||
int u = luaL_check_int(L, 1);
|
||||
luaL_arg_check(L, 1<=u, 1, "interval is empty");
|
||||
lua_pushnumber(L, (int)(r*u)+1); /* integer between 1 and `u' */
|
||||
break;
|
||||
}
|
||||
luaL_arg_check(L, l<=u, 1, "interval is empty");
|
||||
case 2: { /* lower and upper limits */
|
||||
int l = luaL_check_int(L, 1);
|
||||
int u = luaL_check_int(L, 2);
|
||||
luaL_arg_check(L, l<=u, 2, "interval is empty");
|
||||
lua_pushnumber(L, (int)(r*(u-l+1))+l); /* integer between `l' and `u' */
|
||||
break;
|
||||
}
|
||||
default: lua_error(L, "wrong number of arguments");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void math_randomseed (lua_State *L) {
|
||||
static int math_randomseed (lua_State *L) {
|
||||
srand(luaL_check_int(L, 1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -199,9 +230,10 @@ static const struct luaL_reg mathlib[] = {
|
||||
*/
|
||||
void lua_mathlibopen (lua_State *L) {
|
||||
luaL_openl(L, mathlib);
|
||||
lua_pushcfunction(L, math_pow);
|
||||
lua_pushnumber(L, 0); /* to get its tag */
|
||||
lua_settagmethod(L, lua_tag(L, lua_pop(L)), "pow");
|
||||
lua_pushcfunction(L, math_pow);
|
||||
lua_settagmethod(L, lua_tag(L, -2), "pow");
|
||||
lua_settop(L, -1); /* remove number */
|
||||
lua_pushnumber(L, PI); lua_setglobal(L, "PI");
|
||||
}
|
||||
|
||||
|
118
lref.c
118
lref.c
@ -1,118 +0,0 @@
|
||||
/*
|
||||
** $Id: lref.c,v 1.17 2000/08/09 19:16:57 roberto Exp roberto $
|
||||
** reference mechanism
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#include "lapi.h"
|
||||
#include "ldo.h"
|
||||
#include "lmem.h"
|
||||
#include "lref.h"
|
||||
#include "lstate.h"
|
||||
|
||||
|
||||
int lua_ref (lua_State *L, int lock) {
|
||||
int ref;
|
||||
luaA_checkCargs(L, 1);
|
||||
if (ttype(L->top-1) == TAG_NIL)
|
||||
ref = LUA_REFNIL;
|
||||
else {
|
||||
if (L->refFree != NONEXT) { /* is there a free place? */
|
||||
ref = L->refFree;
|
||||
L->refFree = L->refArray[ref].st;
|
||||
}
|
||||
else { /* no more free places */
|
||||
luaM_growvector(L, L->refArray, L->refSize, 1, struct Ref,
|
||||
"reference table overflow", MAX_INT);
|
||||
ref = L->refSize++;
|
||||
}
|
||||
L->refArray[ref].o = *(L->top-1);
|
||||
L->refArray[ref].st = lock ? LOCK : HOLD;
|
||||
}
|
||||
L->top--;
|
||||
return ref;
|
||||
}
|
||||
|
||||
|
||||
void lua_unref (lua_State *L, int ref) {
|
||||
if (ref >= 0) {
|
||||
if (ref >= L->refSize || L->refArray[ref].st >= 0)
|
||||
lua_error(L, "Lua API error - "
|
||||
"invalid argument for function `lua_unref'");
|
||||
L->refArray[ref].st = L->refFree;
|
||||
L->refFree = ref;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int lua_pushref (lua_State *L, int ref) {
|
||||
if (ref == LUA_REFNIL)
|
||||
ttype(L->top) = TAG_NIL;
|
||||
else if (0 <= ref && ref < L->refSize &&
|
||||
(L->refArray[ref].st == LOCK || L->refArray[ref].st == HOLD))
|
||||
*L->top = L->refArray[ref].o;
|
||||
else
|
||||
return 0;
|
||||
incr_top;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void lua_beginblock (lua_State *L) {
|
||||
luaM_growvector(L, L->Cblocks, L->numCblocks, 1, struct C_Lua_Stack,
|
||||
"too many nested blocks", L->stacksize);
|
||||
L->Cblocks[L->numCblocks] = L->Cstack;
|
||||
L->numCblocks++;
|
||||
}
|
||||
|
||||
|
||||
void lua_endblock (lua_State *L) {
|
||||
if (L->numCblocks <= 0)
|
||||
lua_error(L, "Lua API error - no block to end");
|
||||
--L->numCblocks;
|
||||
L->Cstack = L->Cblocks[L->numCblocks];
|
||||
L->top = L->Cstack.base;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int hasmark (const TObject *o) {
|
||||
/* valid only for locked objects */
|
||||
switch (o->ttype) {
|
||||
case TAG_STRING: case TAG_USERDATA:
|
||||
return tsvalue(o)->marked;
|
||||
case TAG_TABLE:
|
||||
return ismarked(hvalue(o));
|
||||
case TAG_LCLOSURE: case TAG_CCLOSURE:
|
||||
return ismarked(clvalue(o)->mark);
|
||||
default: /* number */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* for internal debugging only; check if a link of free refs is valid */
|
||||
#define VALIDLINK(L, st,n) (NONEXT <= (st) && (st) < (n))
|
||||
|
||||
void luaR_invalidaterefs (lua_State *L) {
|
||||
int n = L->refSize;
|
||||
int i;
|
||||
for (i=0; i<n; i++) {
|
||||
struct Ref *r = &L->refArray[i];
|
||||
if (r->st == HOLD && !hasmark(&r->o))
|
||||
r->st = COLLECTED;
|
||||
LUA_ASSERT((r->st == LOCK && hasmark(&r->o)) ||
|
||||
r->st == COLLECTED ||
|
||||
r->st == NONEXT ||
|
||||
(r->st < n && VALIDLINK(L, L->refArray[r->st].st, n)),
|
||||
"inconsistent ref table");
|
||||
}
|
||||
LUA_ASSERT(VALIDLINK(L, L->refFree, n), "inconsistent ref table");
|
||||
}
|
||||
|
27
lref.h
27
lref.h
@ -1,27 +0,0 @@
|
||||
/*
|
||||
** $Id: lref.h,v 1.5 1999/12/27 17:33:22 roberto Exp roberto $
|
||||
** reference mechanism
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
#ifndef lref_h
|
||||
#define lref_h
|
||||
|
||||
#include "lobject.h"
|
||||
|
||||
|
||||
#define NONEXT -1 /* to end the free list */
|
||||
#define HOLD -2
|
||||
#define COLLECTED -3
|
||||
#define LOCK -4
|
||||
|
||||
|
||||
struct Ref {
|
||||
TObject o;
|
||||
int st; /* can be LOCK, HOLD, COLLECTED, or next (for free list) */
|
||||
};
|
||||
|
||||
|
||||
void luaR_invalidaterefs (lua_State *L);
|
||||
|
||||
#endif
|
8
lstate.c
8
lstate.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lstate.c,v 1.32 2000/08/09 19:16:57 roberto Exp roberto $
|
||||
** $Id: lstate.c,v 1.33 2000/08/14 17:46:07 roberto Exp roberto $
|
||||
** Global State
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -9,13 +9,11 @@
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#include "lauxlib.h"
|
||||
#include "lbuiltin.h"
|
||||
#include "ldo.h"
|
||||
#include "lgc.h"
|
||||
#include "llex.h"
|
||||
#include "lmem.h"
|
||||
#include "lref.h"
|
||||
#include "lstate.h"
|
||||
#include "lstring.h"
|
||||
#include "ltable.h"
|
||||
@ -35,8 +33,6 @@ lua_State *lua_newstate (int stacksize, int put_builtin) {
|
||||
L->Mbuffbase = 0;
|
||||
L->Mbuffsize = 0;
|
||||
L->Mbuffnext = 0;
|
||||
L->Cblocks = NULL;
|
||||
L->numCblocks = 0;
|
||||
L->rootproto = NULL;
|
||||
L->rootcl = NULL;
|
||||
L->roottable = NULL;
|
||||
@ -84,8 +80,6 @@ void lua_close (lua_State *L) {
|
||||
luaM_free(L, L->IMtable);
|
||||
luaM_free(L, L->refArray);
|
||||
luaM_free(L, L->Mbuffer);
|
||||
luaM_free(L, L->Cblocks);
|
||||
LUA_ASSERT(L->numCblocks == 0, "Cblocks still open");
|
||||
LUA_ASSERT(L->nblocks == 0, "wrong count for nblocks");
|
||||
luaM_free(L, L);
|
||||
LUA_ASSERT(L != lua_state || memdebug_numblocks == 0, "memory leak!");
|
||||
|
35
lstate.h
35
lstate.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lstate.h,v 1.35 2000/08/07 18:39:16 roberto Exp roberto $
|
||||
** $Id: lstate.h,v 1.36 2000/08/08 20:42:07 roberto Exp roberto $
|
||||
** Global State
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -18,6 +18,21 @@
|
||||
typedef TObject *StkId; /* index to stack elements */
|
||||
|
||||
|
||||
/*
|
||||
** marks for Reference array
|
||||
*/
|
||||
#define NONEXT -1 /* to end the free list */
|
||||
#define HOLD -2
|
||||
#define COLLECTED -3
|
||||
#define LOCK -4
|
||||
|
||||
|
||||
struct Ref {
|
||||
TObject o;
|
||||
int st; /* can be LOCK, HOLD, COLLECTED, or next (for free list) */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
** chain list of long jumps
|
||||
*/
|
||||
@ -26,20 +41,6 @@ struct lua_longjmp {
|
||||
struct lua_longjmp *previous;
|
||||
volatile int status; /* error code */
|
||||
StkId base;
|
||||
int numCblocks;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
** stack layout for C point of view:
|
||||
** [lua2C, lua2C+num) - `array' lua2C
|
||||
** [lua2C+num, base) - space for extra lua_Objects (limbo)
|
||||
** [base, L->top) - `stack' C2Lua
|
||||
*/
|
||||
struct C_Lua_Stack {
|
||||
StkId base;
|
||||
StkId lua2C;
|
||||
int num;
|
||||
};
|
||||
|
||||
|
||||
@ -57,14 +58,12 @@ struct lua_State {
|
||||
StkId stack; /* stack base */
|
||||
StkId stack_last; /* last free slot in the stack */
|
||||
int stacksize;
|
||||
struct C_Lua_Stack Cstack; /* C2lua struct */
|
||||
StkId Cbase; /* base for current C function */
|
||||
struct lua_longjmp *errorJmp; /* current error recover point */
|
||||
char *Mbuffer; /* global buffer */
|
||||
size_t Mbuffbase; /* current first position of Mbuffer */
|
||||
size_t Mbuffsize; /* size of Mbuffer */
|
||||
size_t Mbuffnext; /* next position to fill in Mbuffer */
|
||||
struct C_Lua_Stack *Cblocks;
|
||||
int numCblocks; /* number of nested Cblocks */
|
||||
/* global state */
|
||||
Proto *rootproto; /* list of all prototypes */
|
||||
Closure *rootcl; /* list of all closures */
|
||||
|
104
lstrlib.c
104
lstrlib.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lstrlib.c,v 1.45 2000/06/12 14:37:18 roberto Exp roberto $
|
||||
** $Id: lstrlib.c,v 1.46 2000/08/09 19:16:57 roberto Exp roberto $
|
||||
** Standard library for string operations and pattern-matching
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -25,10 +25,11 @@ static void addnchar (lua_State *L, const char *s, size_t n) {
|
||||
}
|
||||
|
||||
|
||||
static void str_len (lua_State *L) {
|
||||
static int str_len (lua_State *L) {
|
||||
size_t l;
|
||||
luaL_check_lstr(L, 1, &l);
|
||||
lua_pushnumber(L, l);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@ -43,7 +44,7 @@ static long posrelat (long pos, size_t len) {
|
||||
}
|
||||
|
||||
|
||||
static void str_sub (lua_State *L) {
|
||||
static int str_sub (lua_State *L) {
|
||||
size_t l;
|
||||
const char *s = luaL_check_lstr(L, 1, &l);
|
||||
long start = posrelat(luaL_check_long(L, 2), l);
|
||||
@ -53,10 +54,11 @@ static void str_sub (lua_State *L) {
|
||||
if (start <= end)
|
||||
lua_pushlstring(L, s+start-1, end-start+1);
|
||||
else lua_pushstring(L, "");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void str_lower (lua_State *L) {
|
||||
static int str_lower (lua_State *L) {
|
||||
size_t l;
|
||||
size_t i;
|
||||
const char *s = luaL_check_lstr(L, 1, &l);
|
||||
@ -64,10 +66,11 @@ static void str_lower (lua_State *L) {
|
||||
for (i=0; i<l; i++)
|
||||
luaL_addchar(L, tolower((unsigned char)(s[i])));
|
||||
closeandpush(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void str_upper (lua_State *L) {
|
||||
static int str_upper (lua_State *L) {
|
||||
size_t l;
|
||||
size_t i;
|
||||
const char *s = luaL_check_lstr(L, 1, &l);
|
||||
@ -75,9 +78,10 @@ static void str_upper (lua_State *L) {
|
||||
for (i=0; i<l; i++)
|
||||
luaL_addchar(L, toupper((unsigned char)(s[i])));
|
||||
closeandpush(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void str_rep (lua_State *L) {
|
||||
static int str_rep (lua_State *L) {
|
||||
size_t l;
|
||||
const char *s = luaL_check_lstr(L, 1, &l);
|
||||
int n = luaL_check_int(L, 2);
|
||||
@ -85,27 +89,31 @@ static void str_rep (lua_State *L) {
|
||||
while (n-- > 0)
|
||||
addnchar(L, s, l);
|
||||
closeandpush(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void str_byte (lua_State *L) {
|
||||
static int str_byte (lua_State *L) {
|
||||
size_t l;
|
||||
const char *s = luaL_check_lstr(L, 1, &l);
|
||||
long pos = posrelat(luaL_opt_long(L, 2, 1), l);
|
||||
luaL_arg_check(L, 0<pos && (size_t)pos<=l, 2, "out of range");
|
||||
lua_pushnumber(L, (unsigned char)s[pos-1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void str_char (lua_State *L) {
|
||||
int i = 0;
|
||||
static int str_char (lua_State *L) {
|
||||
int n = lua_gettop(L); /* number of arguments */
|
||||
int i;
|
||||
luaL_resetbuffer(L);
|
||||
while (lua_getparam(L, ++i) != LUA_NOOBJECT) {
|
||||
for (i=1; i<=n; i++) {
|
||||
int c = luaL_check_int(L, i);
|
||||
luaL_arg_check(L, (unsigned char)c == c, i, "invalid value");
|
||||
luaL_addchar(L, (unsigned char)c);
|
||||
}
|
||||
closeandpush(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@ -135,16 +143,6 @@ struct Capture {
|
||||
#define SPECIALS "^$*+?.([%-"
|
||||
|
||||
|
||||
static void push_captures (lua_State *L, struct Capture *cap) {
|
||||
int i;
|
||||
for (i=0; i<cap->level; i++) {
|
||||
int l = cap->capture[i].len;
|
||||
if (l == -1) lua_error(L, "unfinished capture");
|
||||
lua_pushlstring(L, cap->capture[i].init, l);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int check_capture (lua_State *L, int l, struct Capture *cap) {
|
||||
l -= '1';
|
||||
if (!(0 <= l && l < cap->level && cap->capture[l].len != -1))
|
||||
@ -400,20 +398,31 @@ static const char *lmemfind (const char *s1, size_t l1,
|
||||
}
|
||||
|
||||
|
||||
static void str_find (lua_State *L) {
|
||||
static int push_captures (lua_State *L, struct Capture *cap) {
|
||||
int i;
|
||||
for (i=0; i<cap->level; i++) {
|
||||
int l = cap->capture[i].len;
|
||||
if (l == -1) lua_error(L, "unfinished capture");
|
||||
lua_pushlstring(L, cap->capture[i].init, l);
|
||||
}
|
||||
return cap->level; /* number of strings pushed */
|
||||
}
|
||||
|
||||
|
||||
static int str_find (lua_State *L) {
|
||||
size_t l1, l2;
|
||||
const char *s = luaL_check_lstr(L, 1, &l1);
|
||||
const char *p = luaL_check_lstr(L, 2, &l2);
|
||||
long init = posrelat(luaL_opt_long(L, 3, 1), l1) - 1;
|
||||
struct Capture cap;
|
||||
luaL_arg_check(L, 0 <= init && (size_t)init <= l1, 3, "out of range");
|
||||
if (lua_getparam(L, 4) != LUA_NOOBJECT ||
|
||||
strpbrk(p, SPECIALS) == NULL) { /* no special characters? */
|
||||
if (lua_gettop(L) > 3 || /* extra argument? */
|
||||
strpbrk(p, SPECIALS) == NULL) { /* or no special characters? */
|
||||
const char *s2 = lmemfind(s+init, l1-init, p, l2);
|
||||
if (s2) {
|
||||
lua_pushnumber(L, s2-s+1);
|
||||
lua_pushnumber(L, s2-s+l2);
|
||||
return;
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -426,19 +435,19 @@ static void str_find (lua_State *L) {
|
||||
if ((res=match(L, s1, p, &cap)) != NULL) {
|
||||
lua_pushnumber(L, s1-s+1); /* start */
|
||||
lua_pushnumber(L, res-s); /* end */
|
||||
push_captures(L, &cap);
|
||||
return;
|
||||
return push_captures(L, &cap) + 2;
|
||||
}
|
||||
} while (s1++<cap.src_end && !anchor);
|
||||
}
|
||||
lua_pushnil(L); /* not found */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void add_s (lua_State *L, lua_Object newp, struct Capture *cap) {
|
||||
if (lua_isstring(L, newp)) {
|
||||
const char *news = lua_getstring(L, newp);
|
||||
size_t l = lua_strlen(L, newp);
|
||||
static void add_s (lua_State *L, struct Capture *cap) {
|
||||
if (lua_isstring(L, 3)) {
|
||||
const char *news = lua_tostring(L, 3);
|
||||
size_t l = lua_strlen(L, 3);
|
||||
size_t i;
|
||||
for (i=0; i<l; i++) {
|
||||
if (news[i] != ESC)
|
||||
@ -455,39 +464,38 @@ static void add_s (lua_State *L, lua_Object newp, struct Capture *cap) {
|
||||
}
|
||||
}
|
||||
else { /* is a function */
|
||||
lua_Object res;
|
||||
int status;
|
||||
size_t oldbuff;
|
||||
lua_beginblock(L);
|
||||
push_captures(L, cap);
|
||||
int n;
|
||||
const char *s;
|
||||
lua_pushobject(L, 3);
|
||||
n = push_captures(L, cap);
|
||||
/* function may use buffer, so save it and create a new one */
|
||||
oldbuff = luaL_newbuffer(L, 0);
|
||||
status = lua_callfunction(L, newp);
|
||||
status = lua_call(L, n, 1);
|
||||
/* restore old buffer */
|
||||
luaL_oldbuffer(L, oldbuff);
|
||||
if (status != 0) {
|
||||
lua_endblock(L);
|
||||
if (status != 0)
|
||||
lua_error(L, NULL);
|
||||
}
|
||||
res = lua_getresult(L, 1);
|
||||
if (lua_isstring(L, res))
|
||||
addnchar(L, lua_getstring(L, res), lua_strlen(L, res));
|
||||
lua_endblock(L);
|
||||
s = lua_tostring(L, -1);
|
||||
if (s)
|
||||
addnchar(L, lua_tostring(L, -1), lua_strlen(L, -1));
|
||||
lua_settop(L, -1); /* pop function result */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void str_gsub (lua_State *L) {
|
||||
static int str_gsub (lua_State *L) {
|
||||
size_t srcl;
|
||||
const char *src = luaL_check_lstr(L, 1, &srcl);
|
||||
const char *p = luaL_check_string(L, 2);
|
||||
lua_Object newp = lua_getparam(L, 3);
|
||||
int max_s = luaL_opt_int(L, 4, srcl+1);
|
||||
int anchor = (*p == '^') ? (p++, 1) : 0;
|
||||
int n = 0;
|
||||
struct Capture cap;
|
||||
luaL_arg_check(L, lua_isstring(L, newp) || lua_isfunction(L, newp), 3,
|
||||
"string or function expected");
|
||||
luaL_arg_check(L,
|
||||
lua_gettop(L) >= 3 && (lua_isstring(L, 3) || lua_isfunction(L, 3)),
|
||||
3, "string or function expected");
|
||||
luaL_resetbuffer(L);
|
||||
cap.src_end = src+srcl;
|
||||
while (n < max_s) {
|
||||
@ -496,7 +504,7 @@ static void str_gsub (lua_State *L) {
|
||||
e = match(L, src, p, &cap);
|
||||
if (e) {
|
||||
n++;
|
||||
add_s(L, newp, &cap);
|
||||
add_s(L, &cap);
|
||||
}
|
||||
if (e && e>src) /* non empty match? */
|
||||
src = e; /* skip it */
|
||||
@ -508,6 +516,7 @@ static void str_gsub (lua_State *L) {
|
||||
addnchar(L, src, cap.src_end-src);
|
||||
closeandpush(L);
|
||||
lua_pushnumber(L, n); /* number of substitutions */
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* }====================================================== */
|
||||
@ -534,7 +543,7 @@ static void luaI_addquoted (lua_State *L, int arg) {
|
||||
/* maximum size of each format specification (such as '%-099.99d') */
|
||||
#define MAX_FORMAT 20 /* arbitrary limit */
|
||||
|
||||
static void str_format (lua_State *L) {
|
||||
static int str_format (lua_State *L) {
|
||||
int arg = 1;
|
||||
const char *strfrmt = luaL_check_string(L, arg);
|
||||
luaL_resetbuffer(L);
|
||||
@ -597,6 +606,7 @@ static void str_format (lua_State *L) {
|
||||
}
|
||||
}
|
||||
closeandpush(L); /* push the result */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
423
ltests.c
423
ltests.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ltests.c,v 1.33 2000/08/09 19:16:57 roberto Exp roberto $
|
||||
** $Id: ltests.c,v 1.34 2000/08/15 20:14:27 roberto Exp roberto $
|
||||
** Internal Module for Debugging of the Lua Implementation
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -10,7 +10,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define LUA_SINGLESTATE
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
@ -38,11 +37,11 @@ void luaB_opentests (lua_State *L);
|
||||
|
||||
|
||||
|
||||
static void setnameval (lua_Object t, const char *name, int val) {
|
||||
lua_pushobject(t);
|
||||
lua_pushstring(name);
|
||||
lua_pushnumber(val);
|
||||
lua_settable();
|
||||
static void setnameval (lua_State *L, const char *name, int val) {
|
||||
lua_pushobject(L, -1);
|
||||
lua_pushstring(L, name);
|
||||
lua_pushnumber(L, val);
|
||||
lua_settable(L);
|
||||
}
|
||||
|
||||
|
||||
@ -65,7 +64,7 @@ static const char *const instrname[NUM_OPCODES] = {
|
||||
};
|
||||
|
||||
|
||||
static int pushop (Proto *p, int pc) {
|
||||
static int pushop (lua_State *L, Proto *p, int pc) {
|
||||
char buff[100];
|
||||
Instruction i = p->code[pc];
|
||||
OpCode o = GET_OPCODE(i);
|
||||
@ -85,146 +84,161 @@ static int pushop (Proto *p, int pc) {
|
||||
sprintf(buff+8, "%-12s%4d %4d", name, GETARG_A(i), GETARG_B(i));
|
||||
break;
|
||||
}
|
||||
lua_pushstring(buff);
|
||||
lua_pushstring(L, buff);
|
||||
return (o != OP_END);
|
||||
}
|
||||
|
||||
|
||||
static void listcode (void) {
|
||||
lua_Object o = luaL_nonnullarg(1);
|
||||
lua_Object t = lua_createtable();
|
||||
static int listcode (lua_State *L) {
|
||||
int pc;
|
||||
Proto *p;
|
||||
int res;
|
||||
luaL_arg_check(ttype(o) == TAG_LCLOSURE, 1, "Lua function expected");
|
||||
p = clvalue(o)->f.l;
|
||||
setnameval(t, "maxstack", p->maxstacksize);
|
||||
setnameval(t, "numparams", p->numparams);
|
||||
luaL_arg_check(L, lua_tag(L, 1) == TAG_LCLOSURE, 1, "Lua function expected");
|
||||
p = clvalue(luaA_index(L, 1))->f.l;
|
||||
lua_newtable(L);
|
||||
setnameval(L, "maxstack", p->maxstacksize);
|
||||
setnameval(L, "numparams", p->numparams);
|
||||
pc = 0;
|
||||
do {
|
||||
lua_pushobject(t);
|
||||
lua_pushnumber(pc+1);
|
||||
res = pushop(p, pc++);
|
||||
lua_settable();
|
||||
lua_pushobject(L, -1);
|
||||
lua_pushnumber(L, pc+1);
|
||||
res = pushop(L, p, pc++);
|
||||
lua_settable(L);
|
||||
} while (res);
|
||||
lua_pushobject(t);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void liststrings (void) {
|
||||
lua_Object o = luaL_nonnullarg(1);
|
||||
lua_Object t = lua_createtable();
|
||||
static int liststrings (lua_State *L) {
|
||||
Proto *p;
|
||||
int i;
|
||||
luaL_arg_check(ttype(o) == TAG_LCLOSURE, 1, "Lua function expected");
|
||||
p = clvalue(o)->f.l;
|
||||
luaL_arg_check(L, lua_tag(L, 1) == TAG_LCLOSURE, 1, "Lua function expected");
|
||||
p = clvalue(luaA_index(L, 1))->f.l;
|
||||
lua_newtable(L);
|
||||
for (i=0; i<p->nkstr; i++) {
|
||||
lua_pushobject(t);
|
||||
lua_pushnumber(i+1);
|
||||
lua_pushstring(p->kstr[i]->str);
|
||||
lua_settable();
|
||||
lua_pushobject(L, -1);
|
||||
lua_pushnumber(L, i+1);
|
||||
lua_pushstring(L, p->kstr[i]->str);
|
||||
lua_settable(L);
|
||||
}
|
||||
lua_pushobject(t);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void listlocals (void) {
|
||||
lua_Object o = luaL_nonnullarg(1);
|
||||
static int listlocals (lua_State *L) {
|
||||
Proto *p;
|
||||
int pc = luaL_check_int(2) - 1;
|
||||
int i = 1;
|
||||
int pc = luaL_check_int(L, 2) - 1;
|
||||
int i = 0;
|
||||
const char *name;
|
||||
luaL_arg_check(ttype(o) == TAG_LCLOSURE, 1, "Lua function expected");
|
||||
p = clvalue(o)->f.l;
|
||||
while ((name = luaF_getlocalname(p, i++, pc)) != NULL)
|
||||
lua_pushstring(name);
|
||||
luaL_arg_check(L, lua_tag(L, 1) == TAG_LCLOSURE, 1, "Lua function expected");
|
||||
p = clvalue(luaA_index(L, 1))->f.l;
|
||||
while ((name = luaF_getlocalname(p, ++i, pc)) != NULL)
|
||||
lua_pushstring(L, name);
|
||||
return i-1;
|
||||
}
|
||||
|
||||
/* }====================================================== */
|
||||
|
||||
|
||||
|
||||
static void get_limits (void) {
|
||||
lua_Object t = lua_createtable();
|
||||
setnameval(t, "BITS_INT", BITS_INT);
|
||||
setnameval(t, "LFPF", LFIELDS_PER_FLUSH);
|
||||
setnameval(t, "MAXARG_A", MAXARG_A);
|
||||
setnameval(t, "MAXARG_B", MAXARG_B);
|
||||
setnameval(t, "MAXARG_S", MAXARG_S);
|
||||
setnameval(t, "MAXARG_U", MAXARG_U);
|
||||
setnameval(t, "MAXLOCALS", MAXLOCALS);
|
||||
setnameval(t, "MAXPARAMS", MAXPARAMS);
|
||||
setnameval(t, "MAXSTACK", MAXSTACK);
|
||||
setnameval(t, "MAXUPVALUES", MAXUPVALUES);
|
||||
setnameval(t, "MAXVARSLH", MAXVARSLH);
|
||||
setnameval(t, "RFPF", RFIELDS_PER_FLUSH);
|
||||
setnameval(t, "SIZE_A", SIZE_A);
|
||||
setnameval(t, "SIZE_B", SIZE_B);
|
||||
setnameval(t, "SIZE_OP", SIZE_OP);
|
||||
setnameval(t, "SIZE_U", SIZE_U);
|
||||
lua_pushobject(t);
|
||||
static int get_limits (lua_State *L) {
|
||||
lua_newtable(L);
|
||||
setnameval(L, "BITS_INT", BITS_INT);
|
||||
setnameval(L, "LFPF", LFIELDS_PER_FLUSH);
|
||||
setnameval(L, "MAXARG_A", MAXARG_A);
|
||||
setnameval(L, "MAXARG_B", MAXARG_B);
|
||||
setnameval(L, "MAXARG_S", MAXARG_S);
|
||||
setnameval(L, "MAXARG_U", MAXARG_U);
|
||||
setnameval(L, "MAXLOCALS", MAXLOCALS);
|
||||
setnameval(L, "MAXPARAMS", MAXPARAMS);
|
||||
setnameval(L, "MAXSTACK", MAXSTACK);
|
||||
setnameval(L, "MAXUPVALUES", MAXUPVALUES);
|
||||
setnameval(L, "MAXVARSLH", MAXVARSLH);
|
||||
setnameval(L, "RFPF", RFIELDS_PER_FLUSH);
|
||||
setnameval(L, "SIZE_A", SIZE_A);
|
||||
setnameval(L, "SIZE_B", SIZE_B);
|
||||
setnameval(L, "SIZE_OP", SIZE_OP);
|
||||
setnameval(L, "SIZE_U", SIZE_U);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void mem_query (void) {
|
||||
lua_Object arg = lua_getparam(1);
|
||||
if (arg == LUA_NOOBJECT) {
|
||||
lua_pushnumber(memdebug_total);
|
||||
lua_pushnumber(memdebug_numblocks);
|
||||
lua_pushnumber(memdebug_maxmem);
|
||||
}
|
||||
else
|
||||
memdebug_memlimit = luaL_check_int(1);
|
||||
}
|
||||
|
||||
|
||||
static void hash_query (void) {
|
||||
lua_Object o = luaL_nonnullarg(1);
|
||||
if (lua_getparam(2) == LUA_NOOBJECT) {
|
||||
luaL_arg_check(ttype(o) == TAG_STRING, 1, "string expected");
|
||||
lua_pushnumber(tsvalue(o)->u.s.hash);
|
||||
static int mem_query (lua_State *L) {
|
||||
if (lua_isnull(L, 1)) {
|
||||
lua_pushnumber(L, memdebug_total);
|
||||
lua_pushnumber(L, memdebug_numblocks);
|
||||
lua_pushnumber(L, memdebug_maxmem);
|
||||
return 3;
|
||||
}
|
||||
else {
|
||||
const Hash *t = hvalue(luaL_tablearg(2));
|
||||
lua_pushnumber(luaH_mainposition(t, o) - t->node);
|
||||
memdebug_memlimit = luaL_check_int(L, 1);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void table_query (void) {
|
||||
const Hash *t = hvalue(luaL_tablearg(1));
|
||||
int i = luaL_opt_int(2, -1);
|
||||
static int hash_query (lua_State *L) {
|
||||
if (lua_isnull(L, 2)) {
|
||||
luaL_arg_check(L, lua_tag(L, 1) == TAG_STRING, 1, "string expected");
|
||||
lua_pushnumber(L, tsvalue(luaA_index(L, 1))->u.s.hash);
|
||||
}
|
||||
else {
|
||||
Hash *t;
|
||||
luaL_checktype(L, 2, "table");
|
||||
t = hvalue(luaA_index(L, 2));
|
||||
lua_pushnumber(L, luaH_mainposition(t, luaA_index(L, 1)) - t->node);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int table_query (lua_State *L) {
|
||||
const Hash *t;
|
||||
int i = luaL_opt_int(L, 2, -1);
|
||||
luaL_checktype(L, 1, "table");
|
||||
t = hvalue(luaA_index(L, 1));
|
||||
if (i == -1) {
|
||||
lua_pushnumber(t->size);
|
||||
lua_pushnumber(t->firstfree - t->node);
|
||||
lua_pushnumber(L, t->size);
|
||||
lua_pushnumber(L, t->firstfree - t->node);
|
||||
return 2;
|
||||
}
|
||||
else if (i < t->size) {
|
||||
luaA_pushobject(lua_state, &t->node[i].key);
|
||||
luaA_pushobject(lua_state, &t->node[i].val);
|
||||
if (t->node[i].next)
|
||||
lua_pushnumber(t->node[i].next - t->node);
|
||||
luaA_pushobject(L, &t->node[i].key);
|
||||
luaA_pushobject(L, &t->node[i].val);
|
||||
if (t->node[i].next) {
|
||||
lua_pushnumber(L, t->node[i].next - t->node);
|
||||
return 3;
|
||||
}
|
||||
else
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void string_query (void) {
|
||||
lua_State *L = lua_state;
|
||||
stringtable *tb = (*luaL_check_string(1) == 's') ? &L->strt : &L->udt;
|
||||
int s = luaL_opt_int(2, 0) - 1;
|
||||
static int string_query (lua_State *L) {
|
||||
stringtable *tb = (*luaL_check_string(L, 1) == 's') ? &L->strt : &L->udt;
|
||||
int s = luaL_opt_int(L, 2, 0) - 1;
|
||||
if (s==-1) {
|
||||
lua_pushnumber(tb->nuse);
|
||||
lua_pushnumber(tb->size);
|
||||
lua_pushnumber(L ,tb->nuse);
|
||||
lua_pushnumber(L ,tb->size);
|
||||
return 2;
|
||||
}
|
||||
else if (s < tb->size) {
|
||||
TString *ts;
|
||||
int n = 0;
|
||||
for (ts = tb->hash[s]; ts; ts = ts->nexthash) {
|
||||
ttype(L->top) = TAG_STRING;
|
||||
tsvalue(L->top) = ts;
|
||||
incr_top;
|
||||
n++;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** {======================================================
|
||||
** function to test the API with C. It interprets a kind of "assembler"
|
||||
@ -238,21 +252,33 @@ static void skip (const char **pc) {
|
||||
while (**pc != '\0' && strchr(delimits, **pc)) (*pc)++;
|
||||
}
|
||||
|
||||
static int getnum (const char **pc) {
|
||||
static int getnum (const char **pc, int *reg) {
|
||||
int res = 0;
|
||||
int sig = 1;
|
||||
int ref = 0;
|
||||
skip(pc);
|
||||
if (**pc == 'r') {
|
||||
ref = 1;
|
||||
(*pc)++;
|
||||
}
|
||||
else if (**pc == '-') {
|
||||
sig = -1;
|
||||
(*pc)++;
|
||||
}
|
||||
while (isdigit(**pc)) res = res*10 + (*(*pc)++) - '0';
|
||||
return res;
|
||||
if (!ref)
|
||||
return sig*res;
|
||||
else
|
||||
return reg[res];
|
||||
}
|
||||
|
||||
static int getreg (const char **pc) {
|
||||
skip(pc);
|
||||
if (*(*pc)++ != 'r') lua_error("`testC' expecting a register");
|
||||
return getnum(pc);
|
||||
(*pc)++; /* skip the `r' */
|
||||
return getnum(pc, NULL);
|
||||
}
|
||||
|
||||
static const char *getname (const char **pc) {
|
||||
static char buff[30];
|
||||
static const char *getname (char *buff, const char **pc) {
|
||||
int i = 0;
|
||||
skip(pc);
|
||||
while (**pc != '\0' && !strchr(delimits, **pc))
|
||||
@ -264,159 +290,148 @@ static const char *getname (const char **pc) {
|
||||
|
||||
#define EQ(s1) (strcmp(s1, inst) == 0)
|
||||
|
||||
#define getnum ((getnum)(&pc, reg))
|
||||
#define getreg ((getreg)(&pc))
|
||||
#define getname ((getname)(buff, &pc))
|
||||
|
||||
static void testC (void) {
|
||||
lua_Object reg[10];
|
||||
const char *pc = luaL_check_string(1);
|
||||
|
||||
static int testC (lua_State *L) {
|
||||
char buff[30];
|
||||
int reg[10];
|
||||
const char *pc = luaL_check_string(L, 1);
|
||||
for (;;) {
|
||||
const char *inst = getname(&pc);
|
||||
if EQ("") return;
|
||||
else if EQ("pushnum") {
|
||||
lua_pushnumber(getnum(&pc));
|
||||
const char *inst = getname;
|
||||
if EQ("") return 0;
|
||||
else if EQ("return") {
|
||||
return getnum;
|
||||
}
|
||||
else if EQ("createtable") {
|
||||
reg[getreg(&pc)] = lua_createtable();
|
||||
else if EQ("retall") {
|
||||
return lua_gettop(L) - 1;
|
||||
}
|
||||
else if EQ("gettop") {
|
||||
reg[getreg] = lua_gettop(L);
|
||||
}
|
||||
else if EQ("settop") {
|
||||
lua_settop(L, getnum);
|
||||
}
|
||||
else if EQ("setreg") {
|
||||
int n = getreg;
|
||||
reg[n] = lua_tonumber(L, getnum);
|
||||
}
|
||||
else if EQ("pushnum") {
|
||||
lua_pushnumber(L, getnum);
|
||||
}
|
||||
else if EQ("newtable") {
|
||||
lua_newtable(L);
|
||||
}
|
||||
else if EQ("closure") {
|
||||
lua_CFunction f = lua_getcfunction(lua_getglobal(getname(&pc)));
|
||||
lua_pushcclosure(f, getnum(&pc));
|
||||
lua_CFunction f;
|
||||
lua_getglobal(L, getname);
|
||||
f = lua_tocfunction(L, -1);
|
||||
lua_settop(L, -1);
|
||||
lua_pushcclosure(L, f, getnum);
|
||||
}
|
||||
else if EQ("pop") {
|
||||
reg[getreg(&pc)] = lua_pop();
|
||||
else if EQ("pushobject") {
|
||||
lua_pushobject(L, getnum);
|
||||
}
|
||||
else if EQ("getglobal") {
|
||||
int n = getreg(&pc);
|
||||
reg[n] = lua_getglobal(getname(&pc));
|
||||
lua_getglobal(L, getname);
|
||||
}
|
||||
else if EQ("ref") {
|
||||
lua_pushnumber(lua_ref(0));
|
||||
reg[getreg(&pc)] = lua_pop();
|
||||
reg[getreg] = lua_ref(L, 0);
|
||||
}
|
||||
else if EQ("reflock") {
|
||||
lua_pushnumber(lua_ref(1));
|
||||
reg[getreg(&pc)] = lua_pop();
|
||||
reg[getreg] = lua_ref(L, 1);
|
||||
}
|
||||
else if EQ("getref") {
|
||||
int n = getreg(&pc);
|
||||
reg[n] = lua_getref((int)lua_getnumber(reg[getreg(&pc)]));
|
||||
int n = getreg;
|
||||
reg[n] = lua_getref(L, getnum);
|
||||
}
|
||||
else if EQ("unref") {
|
||||
lua_unref((int)lua_getnumber(reg[getreg(&pc)]));
|
||||
}
|
||||
else if EQ("getparam") {
|
||||
int n = getreg(&pc);
|
||||
reg[n] = lua_getparam(getnum(&pc)+1); /* skips the command itself */
|
||||
}
|
||||
else if EQ("getresult") {
|
||||
int n = getreg(&pc);
|
||||
reg[n] = lua_getparam(getnum(&pc));
|
||||
lua_unref(L, getnum);
|
||||
}
|
||||
else if EQ("setglobal") {
|
||||
lua_setglobal(getname(&pc));
|
||||
}
|
||||
else if EQ("pushglobals") {
|
||||
lua_pushglobals();
|
||||
lua_setglobal(L, getname);
|
||||
}
|
||||
else if EQ("pushstring") {
|
||||
lua_pushstring(getname(&pc));
|
||||
}
|
||||
else if EQ("pushreg") {
|
||||
lua_pushobject(reg[getreg(&pc)]);
|
||||
lua_pushstring(L, getname);
|
||||
}
|
||||
else if EQ("call") {
|
||||
if (lua_call(getname(&pc))) lua_error(NULL);
|
||||
int narg = getnum;
|
||||
int nres = getnum;
|
||||
if (lua_call(L, narg, nres)) lua_error(L, NULL);
|
||||
}
|
||||
else if EQ("gettable") {
|
||||
reg[getreg(&pc)] = lua_gettable();
|
||||
lua_gettable(L);
|
||||
}
|
||||
else if EQ("rawget") {
|
||||
reg[getreg(&pc)] = lua_rawget();
|
||||
lua_rawget(L);
|
||||
}
|
||||
else if EQ("settable") {
|
||||
lua_settable();
|
||||
lua_settable(L);
|
||||
}
|
||||
else if EQ("rawset") {
|
||||
lua_rawset();
|
||||
lua_rawset(L);
|
||||
}
|
||||
else if EQ("tag") {
|
||||
lua_pushnumber(lua_tag(reg[getreg(&pc)]));
|
||||
int n = getreg;
|
||||
reg[n] = lua_tag(L, getnum);
|
||||
}
|
||||
else if EQ("type") {
|
||||
lua_pushstring(lua_type(reg[getreg(&pc)]));
|
||||
}
|
||||
else if EQ("next") {
|
||||
int n = getreg(&pc);
|
||||
n = lua_next(reg[n], (int)lua_getnumber(reg[getreg(&pc)]));
|
||||
lua_pushnumber(n);
|
||||
lua_pushstring(L, lua_type(L, getnum));
|
||||
}
|
||||
else if EQ("equal") {
|
||||
int n1 = getreg(&pc);
|
||||
int n2 = getreg(&pc);
|
||||
lua_pushnumber(lua_equal(reg[n1], reg[n2]));
|
||||
int n1 = getreg;
|
||||
int n2 = getnum;
|
||||
int n3 = getnum;
|
||||
reg[n1] = lua_equal(L, n2, n3);
|
||||
}
|
||||
else if EQ("pushusertag") {
|
||||
int val = getreg(&pc);
|
||||
int tag = getreg(&pc);
|
||||
lua_pushusertag((void *)(int)lua_getnumber(reg[val]),
|
||||
(int)lua_getnumber(reg[tag]));
|
||||
int val = getnum;
|
||||
int tag = getnum;
|
||||
lua_pushusertag(L, (void *)val, tag);
|
||||
}
|
||||
else if EQ("udataval") {
|
||||
int n = getreg(&pc);
|
||||
lua_pushnumber((int)lua_getuserdata(reg[getreg(&pc)]));
|
||||
reg[n] = lua_pop();
|
||||
int n = getreg;
|
||||
reg[n] = (int)lua_touserdata(L, getnum);
|
||||
}
|
||||
else if EQ("settagmethod") {
|
||||
int n = getreg(&pc);
|
||||
lua_settagmethod((int)lua_getnumber(reg[n]), getname(&pc));
|
||||
}
|
||||
else if EQ("beginblock") {
|
||||
lua_beginblock();
|
||||
}
|
||||
else if EQ("endblock") {
|
||||
lua_endblock();
|
||||
int n = getnum;
|
||||
lua_settagmethod(L, n, getname);
|
||||
}
|
||||
else if EQ("newstate") {
|
||||
int stacksize = getnum(&pc);
|
||||
lua_State *L1 = lua_newstate(stacksize, getnum(&pc));
|
||||
int stacksize = getnum;
|
||||
lua_State *L1 = lua_newstate(stacksize, getnum);
|
||||
if (L1)
|
||||
lua_pushuserdata(L1);
|
||||
lua_pushuserdata(L, L1);
|
||||
else
|
||||
lua_pushnil();
|
||||
lua_pushnil(L);
|
||||
}
|
||||
else if EQ("closestate") {
|
||||
(lua_close)((lua_State *)lua_getuserdata(reg[getreg(&pc)]));
|
||||
(lua_close)((lua_State *)lua_touserdata(L, getnum));
|
||||
}
|
||||
else if EQ("doremote") {
|
||||
lua_Object ol1 = reg[getreg(&pc)];
|
||||
lua_Object str = reg[getreg(&pc)];
|
||||
int ol1 = getnum;
|
||||
int str = getnum;
|
||||
lua_State *L1;
|
||||
lua_Object temp;
|
||||
int status;
|
||||
if (!lua_isuserdata(ol1) || !lua_isstring(str))
|
||||
lua_error("bad arguments for `doremote'");
|
||||
L1 = (lua_State *)lua_getuserdata(ol1);
|
||||
status = (lua_dostring)(L1, lua_getstring(str));
|
||||
if (!lua_isuserdata(L, ol1) || !lua_isstring(L, str))
|
||||
lua_error(L, "bad arguments for `doremote'");
|
||||
L1 = (lua_State *)lua_touserdata(L, ol1);
|
||||
status = lua_dostring(L1, lua_tostring(L, str));
|
||||
if (status != 0) {
|
||||
lua_pushnil();
|
||||
lua_pushnumber(status);
|
||||
lua_pushnil(L);
|
||||
lua_pushnumber(L, status);
|
||||
}
|
||||
else {
|
||||
int i = 1;
|
||||
while ((temp = (lua_getresult)(L1, i++)) != LUA_NOOBJECT)
|
||||
lua_pushstring((lua_getstring)(L1, temp));
|
||||
int i = 0;
|
||||
while (!lua_isnull(L, ++i))
|
||||
lua_pushstring(L, lua_tostring(L1, i));
|
||||
}
|
||||
}
|
||||
#if LUA_DEPRECATETFUNCS
|
||||
else if EQ("rawsetglobal") {
|
||||
lua_rawsetglobal(getname(&pc));
|
||||
}
|
||||
else if EQ("rawgetglobal") {
|
||||
int n = getreg(&pc);
|
||||
reg[n] = lua_rawgetglobal(getname(&pc));
|
||||
}
|
||||
#endif
|
||||
else luaL_verror(lua_state, "unknown command in `testC': %.20s", inst);
|
||||
else luaL_verror(L, "unknown instruction %.30s", buff);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }====================================================== */
|
||||
@ -424,22 +439,20 @@ static void testC (void) {
|
||||
|
||||
|
||||
static const struct luaL_reg tests_funcs[] = {
|
||||
{"hash", (lua_CFunction)hash_query},
|
||||
{"limits", (lua_CFunction)get_limits},
|
||||
{"listcode", (lua_CFunction)listcode},
|
||||
{"liststrings", (lua_CFunction)liststrings},
|
||||
{"listlocals", (lua_CFunction)listlocals},
|
||||
{"querystr", (lua_CFunction)string_query},
|
||||
{"querytab", (lua_CFunction)table_query},
|
||||
{"testC", (lua_CFunction)testC},
|
||||
{"totalmem", (lua_CFunction)mem_query}
|
||||
{"hash", hash_query},
|
||||
{"limits", get_limits},
|
||||
{"listcode", listcode},
|
||||
{"liststrings", liststrings},
|
||||
{"listlocals", listlocals},
|
||||
{"querystr", string_query},
|
||||
{"querytab", table_query},
|
||||
{"testC", testC},
|
||||
{"totalmem", mem_query}
|
||||
};
|
||||
|
||||
|
||||
void luaB_opentests (lua_State *L) {
|
||||
if (lua_state != NULL) return; /* do not open tests for auxiliar states */
|
||||
lua_state = L;
|
||||
luaL_openl(tests_funcs);
|
||||
luaL_openl(L, tests_funcs);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
74
lua.c
74
lua.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lua.c,v 1.44 2000/08/09 19:16:57 roberto Exp roberto $
|
||||
** $Id: lua.c,v 1.45 2000/08/14 17:45:59 roberto Exp roberto $
|
||||
** Lua stand-alone interpreter
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -10,14 +10,14 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define LUA_SINGLESTATE
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#include "luadebug.h"
|
||||
#include "lualib.h"
|
||||
|
||||
|
||||
lua_State *lua_state = NULL;
|
||||
#define L lua_state
|
||||
|
||||
|
||||
#ifndef PROMPT
|
||||
@ -54,10 +54,10 @@ extern void USERINIT (void);
|
||||
#else
|
||||
#define USERINIT userinit
|
||||
static void userinit (void) {
|
||||
lua_iolibopen();
|
||||
lua_strlibopen();
|
||||
lua_mathlibopen();
|
||||
lua_dblibopen();
|
||||
lua_iolibopen(L);
|
||||
lua_strlibopen(L);
|
||||
lua_mathlibopen(L);
|
||||
lua_dblibopen(L);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -68,10 +68,10 @@ static handler lreset (void) {
|
||||
|
||||
|
||||
static void lstop (void) {
|
||||
lua_setlinehook(lua_state, old_linehook);
|
||||
lua_setcallhook(lua_state, old_callhook);
|
||||
lua_setlinehook(L, old_linehook);
|
||||
lua_setcallhook(L, old_callhook);
|
||||
lreset();
|
||||
lua_error("interrupted!");
|
||||
lua_error(L, "interrupted!");
|
||||
}
|
||||
|
||||
|
||||
@ -79,15 +79,15 @@ static void laction (int i) {
|
||||
(void)i; /* to avoid warnings */
|
||||
signal(SIGINT, SIG_DFL); /* if another SIGINT happens before lstop,
|
||||
terminate process (default action) */
|
||||
old_linehook = lua_setlinehook(lua_state, (lua_Hook)lstop);
|
||||
old_callhook = lua_setcallhook(lua_state, (lua_Hook)lstop);
|
||||
old_linehook = lua_setlinehook(L, (lua_Hook)lstop);
|
||||
old_callhook = lua_setcallhook(L, (lua_Hook)lstop);
|
||||
}
|
||||
|
||||
|
||||
static int ldo (int (*f)(lua_State *L, const char *), const char *name) {
|
||||
static int ldo (int (*f)(lua_State *l, const char *), const char *name) {
|
||||
int res;
|
||||
handler h = lreset();
|
||||
res = f(lua_state, name); /* dostring | dofile */
|
||||
res = f(L, name); /* dostring | dofile */
|
||||
signal(SIGINT, h); /* restore old action */
|
||||
if (res == LUA_ERRMEM) {
|
||||
/* Lua gives no message in such case, so lua.c provides one */
|
||||
@ -122,29 +122,29 @@ static void print_version (void) {
|
||||
static void assign (char *arg) {
|
||||
char *eq = strchr(arg, '=');
|
||||
*eq = '\0'; /* spilt `arg' in two strings (name & value) */
|
||||
lua_pushstring(eq+1);
|
||||
lua_setglobal(arg);
|
||||
lua_pushstring(L, eq+1);
|
||||
lua_setglobal(L, arg);
|
||||
}
|
||||
|
||||
|
||||
static lua_Object getargs (char *argv[]) {
|
||||
lua_Object args = lua_createtable();
|
||||
static void getargs (char *argv[]) {
|
||||
int i;
|
||||
lua_newtable(L);
|
||||
for (i=0; argv[i]; i++) {
|
||||
/* arg[i] = argv[i] */
|
||||
lua_pushobject(args); lua_pushnumber(i);
|
||||
lua_pushstring(argv[i]); lua_settable();
|
||||
lua_pushobject(L, -1); lua_pushnumber(L, i);
|
||||
lua_pushstring(L, argv[i]); lua_settable(L);
|
||||
}
|
||||
/* arg.n = maximum index in table `arg' */
|
||||
lua_pushobject(args); lua_pushstring("n");
|
||||
lua_pushnumber(i-1); lua_settable();
|
||||
return args;
|
||||
lua_pushobject(L, -1); lua_pushstring(L, "n");
|
||||
lua_pushnumber(L, i-1); lua_settable(L);
|
||||
}
|
||||
|
||||
|
||||
static void l_getargs (void) {
|
||||
char **argv = (char **)lua_getuserdata(lua_getparam(1));
|
||||
lua_pushobject(getargs(argv));
|
||||
static int l_getargs (lua_State *l) {
|
||||
char **argv = (char **)lua_touserdata(l, 1);
|
||||
getargs(argv);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@ -173,9 +173,11 @@ static void manual_input (int version, int prompt) {
|
||||
while (cont) {
|
||||
char buffer[MAXINPUT];
|
||||
int i = 0;
|
||||
lua_beginblock();
|
||||
if (prompt) {
|
||||
const char *s = lua_getstring(lua_getglobal("_PROMPT"));
|
||||
const char *s;
|
||||
lua_getglobal(L, "_PROMPT");
|
||||
s = lua_tostring(L, -1);
|
||||
lua_settop(L, -1); /* remove global */
|
||||
if (!s) s = PROMPT;
|
||||
fputs(s, stdout);
|
||||
}
|
||||
@ -198,7 +200,7 @@ static void manual_input (int version, int prompt) {
|
||||
}
|
||||
buffer[i] = '\0';
|
||||
ldo(lua_dostring, buffer);
|
||||
lua_endblock();
|
||||
lua_settop(L, 0); /* remove eventual results */
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
@ -262,8 +264,8 @@ static int handle_argv (char *argv[], struct Options *opt) {
|
||||
print_message();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
lua_pushobject(getargs(argv+i)); /* collect remaining arguments */
|
||||
lua_setglobal("arg");
|
||||
getargs(argv+i); /* collect remaining arguments */
|
||||
lua_setglobal(L, "arg");
|
||||
return file_input(argv[i]); /* stop scanning arguments */
|
||||
}
|
||||
case 's': {
|
||||
@ -296,9 +298,9 @@ static void getstacksize (int argc, char *argv[], struct Options *opt) {
|
||||
|
||||
|
||||
static void register_getargs (char *argv[]) {
|
||||
lua_pushuserdata(argv);
|
||||
lua_pushcclosure(l_getargs, 1);
|
||||
lua_setglobal("getargs");
|
||||
lua_pushuserdata(L, argv);
|
||||
lua_pushcclosure(L, l_getargs, 1);
|
||||
lua_setglobal(L, "getargs");
|
||||
}
|
||||
|
||||
|
||||
@ -307,12 +309,12 @@ int main (int argc, char *argv[]) {
|
||||
int status;
|
||||
opt.toclose = 0;
|
||||
getstacksize(argc, argv, &opt); /* handle option `-s' */
|
||||
lua_state = lua_newstate(opt.stacksize, 1); /* create state */
|
||||
L = lua_newstate(opt.stacksize, 1); /* create state */
|
||||
USERINIT(); /* open libraries */
|
||||
register_getargs(argv); /* create `getargs' function */
|
||||
status = handle_argv(argv+1, &opt);
|
||||
if (opt.toclose)
|
||||
lua_close();
|
||||
lua_close(L);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
259
lua.h
259
lua.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lua.h,v 1.58 2000/08/14 19:10:14 roberto Exp roberto $
|
||||
** $Id: lua.h,v 1.59 2000/08/17 13:18:01 roberto Exp roberto $
|
||||
** Lua - An Extensible Extension Language
|
||||
** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil
|
||||
** e-mail: lua@tecgraf.puc-rio.br
|
||||
@ -30,8 +30,10 @@
|
||||
|
||||
#define LUA_ANYTAG (-1)
|
||||
|
||||
#define LUA_MULTRET (-1)
|
||||
|
||||
/* error code for lua_do* */
|
||||
|
||||
/* error codes for lua_do* */
|
||||
#define LUA_ERRFILE 2
|
||||
#define LUA_ERRSYNTAX 3
|
||||
#define LUA_ERRRUN 1
|
||||
@ -40,95 +42,103 @@
|
||||
|
||||
typedef struct lua_State lua_State;
|
||||
|
||||
typedef void (*lua_CFunction) (lua_State *L);
|
||||
|
||||
typedef struct lua_TObject *lua_Object;
|
||||
|
||||
#define LUA_NOOBJECT ((lua_Object)0)
|
||||
typedef int (*lua_CFunction) (lua_State *L);
|
||||
|
||||
|
||||
/*
|
||||
** state manipulation
|
||||
*/
|
||||
lua_State *lua_newstate (int stacksize, int builtin);
|
||||
void lua_close (lua_State *L);
|
||||
|
||||
lua_Object lua_settagmethod (lua_State *L, int tag, const char *event);
|
||||
/* In: new method */
|
||||
lua_Object lua_gettagmethod (lua_State *L, int tag, const char *event);
|
||||
|
||||
int lua_newtag (lua_State *L);
|
||||
int lua_copytagmethods (lua_State *L, int tagto, int tagfrom);
|
||||
void lua_settag (lua_State *L, int tag); /* In: object */
|
||||
|
||||
void lua_error (lua_State *L, const char *s);
|
||||
int lua_dofile (lua_State *L, const char *filename);
|
||||
/* Out: returns */
|
||||
int lua_dostring (lua_State *L, const char *str);
|
||||
/* Out: returns */
|
||||
int lua_dobuffer (lua_State *L, const char *buff, size_t size,
|
||||
const char *name); /* Out: returns */
|
||||
int lua_callfunction (lua_State *L, lua_Object f);
|
||||
/* In: arguments; Out: returns */
|
||||
|
||||
void lua_beginblock (lua_State *L);
|
||||
void lua_endblock (lua_State *L);
|
||||
|
||||
void lua_pushglobals (lua_State *L);
|
||||
void lua_setglobals (lua_State *L, lua_Object newtable);
|
||||
|
||||
lua_Object lua_lua2C (lua_State *L, int number);
|
||||
#define lua_getparam lua_lua2C
|
||||
#define lua_getresult lua_lua2C
|
||||
|
||||
const char *lua_type (lua_State *L, lua_Object obj);
|
||||
|
||||
int lua_isnil (lua_State *L, lua_Object obj);
|
||||
int lua_istable (lua_State *L, lua_Object obj);
|
||||
int lua_isuserdata (lua_State *L, lua_Object obj);
|
||||
int lua_iscfunction (lua_State *L, lua_Object obj);
|
||||
int lua_isnumber (lua_State *L, lua_Object obj);
|
||||
int lua_isstring (lua_State *L, lua_Object obj);
|
||||
int lua_isfunction (lua_State *L, lua_Object obj);
|
||||
|
||||
int lua_equal (lua_State *L, lua_Object o1, lua_Object o2);
|
||||
|
||||
double lua_getnumber (lua_State *L, lua_Object obj);
|
||||
const char *lua_getstring (lua_State *L, lua_Object obj);
|
||||
size_t lua_strlen (lua_State *L, lua_Object obj);
|
||||
lua_CFunction lua_getcfunction (lua_State *L, lua_Object obj);
|
||||
void *lua_getuserdata (lua_State *L, lua_Object obj);
|
||||
/*
|
||||
** basic stack manipulation
|
||||
*/
|
||||
int lua_gettop (lua_State *L);
|
||||
void lua_settop (lua_State *L, int index);
|
||||
void lua_pushobject (lua_State *L, int index);
|
||||
|
||||
|
||||
/*
|
||||
** access functions (stack -> C)
|
||||
*/
|
||||
|
||||
const char *lua_type (lua_State *L, int index);
|
||||
int lua_isnumber (lua_State *L, int index);
|
||||
int lua_iscfunction (lua_State *L, int index);
|
||||
int lua_tag (lua_State *L, int index);
|
||||
|
||||
int lua_equal (lua_State *L, int index1, int index2);
|
||||
|
||||
double lua_tonumber (lua_State *L, int index);
|
||||
const char *lua_tostring (lua_State *L, int index);
|
||||
size_t lua_strlen (lua_State *L, int index);
|
||||
lua_CFunction lua_tocfunction (lua_State *L, int index);
|
||||
void *lua_touserdata (lua_State *L, int index);
|
||||
|
||||
|
||||
/*
|
||||
** push functions (C -> stack)
|
||||
*/
|
||||
void lua_pushnil (lua_State *L);
|
||||
void lua_pushnumber (lua_State *L, double n);
|
||||
void lua_pushlstring (lua_State *L, const char *s, size_t len);
|
||||
void lua_pushstring (lua_State *L, const char *s);
|
||||
void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);
|
||||
void lua_pushusertag (lua_State *L, void *u, int tag);
|
||||
void lua_pushobject (lua_State *L, lua_Object obj);
|
||||
|
||||
lua_Object lua_pop (lua_State *L);
|
||||
|
||||
lua_Object lua_getglobal (lua_State *L, const char *name);
|
||||
void lua_setglobal (lua_State *L, const char *name); /* In: value */
|
||||
/*
|
||||
** get functions (Lua -> stack)
|
||||
*/
|
||||
void lua_getglobal (lua_State *L, const char *name);
|
||||
void lua_gettable (lua_State *L);
|
||||
void lua_rawget (lua_State *L);
|
||||
void lua_getglobals (lua_State *L);
|
||||
void lua_gettagmethod (lua_State *L, int tag, const char *event);
|
||||
|
||||
void lua_settable (lua_State *L); /* In: table, index, value */
|
||||
lua_Object lua_gettable (lua_State *L); /* In: table, index */
|
||||
int lua_getref (lua_State *L, int ref);
|
||||
|
||||
void lua_rawset (lua_State *L); /* In: table, index, value */
|
||||
lua_Object lua_rawget (lua_State *L); /* In: table, index */
|
||||
void lua_newtable (lua_State *L);
|
||||
|
||||
int lua_tag (lua_State *L, lua_Object obj);
|
||||
|
||||
int lua_next (lua_State *L, lua_Object o, int i);
|
||||
/* Out: index, value */
|
||||
/*
|
||||
** set functions (stack -> Lua)
|
||||
*/
|
||||
void lua_setglobal (lua_State *L, const char *name);
|
||||
void lua_settable (lua_State *L);
|
||||
void lua_rawset (lua_State *L);
|
||||
void lua_setglobals (lua_State *L);
|
||||
void lua_settagmethod (lua_State *L, int tag, const char *event);
|
||||
int lua_ref (lua_State *L, int lock);
|
||||
|
||||
|
||||
/*
|
||||
** "do" functions (run Lua code)
|
||||
*/
|
||||
int lua_call (lua_State *L, int nargs, int nresults);
|
||||
int lua_dofile (lua_State *L, const char *filename);
|
||||
int lua_dostring (lua_State *L, const char *str);
|
||||
int lua_dobuffer (lua_State *L, const char *buff, size_t size,
|
||||
const char *name);
|
||||
|
||||
|
||||
/*
|
||||
** miscelaneous functions
|
||||
*/
|
||||
int lua_newtag (lua_State *L);
|
||||
int lua_copytagmethods (lua_State *L, int tagto, int tagfrom);
|
||||
void lua_settag (lua_State *L, int tag);
|
||||
|
||||
void lua_error (lua_State *L, const char *s);
|
||||
|
||||
int lua_ref (lua_State *L, int lock); /* In: value */
|
||||
int lua_pushref (lua_State *L, int ref); /* Out: value */
|
||||
void lua_unref (lua_State *L, int ref);
|
||||
|
||||
lua_Object lua_createtable (lua_State *L);
|
||||
|
||||
long lua_collectgarbage (lua_State *L, long limit);
|
||||
|
||||
int lua_next (lua_State *L, int index, int i);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
@ -137,122 +147,17 @@ long lua_collectgarbage (lua_State *L, long limit);
|
||||
** ===============================================================
|
||||
*/
|
||||
|
||||
#ifndef LUA_SINGLESTATE
|
||||
|
||||
#define lua_call(L,name) lua_callfunction(L, lua_getglobal(L, name))
|
||||
#define lua_getref(L, ref) (lua_pushref(L, ref) ? lua_pop(L) : LUA_NOOBJECT)
|
||||
#define lua_refobject(L,o,l) (lua_pushobject(L, o), lua_ref(L, l))
|
||||
#define lua_register(L,n,f) (lua_pushcfunction(L, f), lua_setglobal(L, n))
|
||||
#define lua_pushuserdata(L,u) lua_pushusertag(L, u, 0)
|
||||
#define lua_pushcfunction(L,f) lua_pushcclosure(L, f, 0)
|
||||
#define lua_clonetag(L,t) lua_copytagmethods(L, lua_newtag(L), (t))
|
||||
|
||||
#else
|
||||
|
||||
#define lua_call(name) lua_callfunction(lua_getglobal(name))
|
||||
#define lua_getref(ref) (lua_pushref(ref) ? lua_pop() : LUA_NOOBJECT)
|
||||
#define lua_refobject(o,l) (lua_pushobject(o), lua_ref(l))
|
||||
#define lua_register(n,f) (lua_pushcfunction(f), lua_setglobal(n))
|
||||
#define lua_pushuserdata(u) lua_pushusertag(u, 0)
|
||||
#define lua_pushcfunction(f) lua_pushcclosure(f, 0)
|
||||
#define lua_clonetag(t) lua_copytagmethods(lua_newtag(), (t))
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef LUA_SINGLESTATE
|
||||
/*
|
||||
** {==============================================================
|
||||
** Macros for single-state use
|
||||
** ===============================================================
|
||||
*/
|
||||
|
||||
extern lua_State *lua_state;
|
||||
|
||||
#define lua_open() ((void)(lua_state?0:(lua_state=lua_newstate(0, 1))))
|
||||
|
||||
#define lua_close() (lua_close)(lua_state)
|
||||
#define lua_settagmethod(tag,event) (lua_settagmethod)(lua_state, tag,event)
|
||||
#define lua_gettagmethod(tag,event) (lua_gettagmethod)(lua_state, tag,event)
|
||||
#define lua_newtag() (lua_newtag)(lua_state)
|
||||
#define lua_copytagmethods(tagto,tagfrom) \
|
||||
(lua_copytagmethods)(lua_state, tagto,tagfrom)
|
||||
#define lua_settag(tag) (lua_settag)(lua_state, tag)
|
||||
#define lua_error(s) (lua_error)(lua_state, s)
|
||||
#define lua_dofile(filename) (lua_dofile)(lua_state, filename)
|
||||
#define lua_dostring(str) (lua_dostring)(lua_state, str)
|
||||
#define lua_dobuffer(b,s,n) (lua_dobuffer)(lua_state, b,s,n)
|
||||
#define lua_callfunction(f) (lua_callfunction)(lua_state, f)
|
||||
#define lua_beginblock() (lua_beginblock)(lua_state)
|
||||
#define lua_endblock() (lua_endblock)(lua_state)
|
||||
#define lua_pushglobals() (lua_pushglobals)(lua_state)
|
||||
#define lua_setglobals(t) (lua_setglobals)(lua_state, t)
|
||||
#define lua_lua2C(number) (lua_lua2C)(lua_state, number)
|
||||
#define lua_type(obj) (lua_type)(lua_state, obj)
|
||||
#define lua_isnil(obj) (lua_isnil)(lua_state, obj)
|
||||
#define lua_istable(obj) (lua_istable)(lua_state, obj)
|
||||
#define lua_isuserdata(obj) (lua_isuserdata)(lua_state, obj)
|
||||
#define lua_iscfunction(obj) (lua_iscfunction)(lua_state, obj)
|
||||
#define lua_isnumber(obj) (lua_isnumber)(lua_state, obj)
|
||||
#define lua_isstring(obj) (lua_isstring)(lua_state, obj)
|
||||
#define lua_isfunction(obj) (lua_isfunction)(lua_state, obj)
|
||||
#define lua_equal(o1,o2) (lua_equal)(lua_state, o1,o2)
|
||||
#define lua_getnumber(obj) (lua_getnumber)(lua_state, obj)
|
||||
#define lua_getstring(obj) (lua_getstring)(lua_state, obj)
|
||||
#define lua_strlen(obj) (lua_strlen)(lua_state, obj)
|
||||
#define lua_getcfunction(obj) (lua_getcfunction)(lua_state, obj)
|
||||
#define lua_getuserdata(obj) (lua_getuserdata)(lua_state, obj)
|
||||
#define lua_pushnil() (lua_pushnil)(lua_state)
|
||||
#define lua_pushnumber(n) (lua_pushnumber)(lua_state, n)
|
||||
#define lua_pushlstring(s,len) (lua_pushlstring)(lua_state, s,len)
|
||||
#define lua_pushstring(s) (lua_pushstring)(lua_state, s)
|
||||
#define lua_pushusertag(u,tag) (lua_pushusertag)(lua_state, u,tag)
|
||||
#define lua_pushobject(obj) (lua_pushobject)(lua_state, obj)
|
||||
#define lua_pop() (lua_pop)(lua_state)
|
||||
#define lua_getglobal(name) (lua_getglobal)(lua_state, name)
|
||||
#define lua_setglobal(name) (lua_setglobal)(lua_state, name)
|
||||
#define lua_settable() (lua_settable)(lua_state)
|
||||
#define lua_gettable() (lua_gettable)(lua_state)
|
||||
#define lua_rawset() (lua_rawset)(lua_state)
|
||||
#define lua_rawget() (lua_rawget)(lua_state)
|
||||
#define lua_tag(obj) (lua_tag)(lua_state, obj)
|
||||
#define lua_next(o,i) (lua_next)(lua_state, o,i)
|
||||
#define lua_ref(lock) (lua_ref)(lua_state, lock)
|
||||
#define lua_pushref(ref) (lua_pushref)(lua_state, ref)
|
||||
#define lua_unref(ref) (lua_unref)(lua_state, ref)
|
||||
#define lua_createtable() (lua_createtable)(lua_state)
|
||||
#define lua_collectgarbage(limit) (lua_collectgarbage)(lua_state, limit)
|
||||
/*
|
||||
** the following typecast is a little dirty, but we know of no other
|
||||
** way to keep compatibility with old definition of `lua_CFunction'
|
||||
*/
|
||||
#define lua_pushcclosure(fn,n) \
|
||||
(lua_pushcclosure)(lua_state, (lua_CFunction)(fn), n)
|
||||
|
||||
|
||||
/*
|
||||
** }==============================================================
|
||||
*/
|
||||
#endif
|
||||
|
||||
/*
|
||||
** compatibility with 3.2
|
||||
** these functions are only available when Lua is compiled with
|
||||
** the option LUA_DEPRECATETFUNCS
|
||||
*/
|
||||
|
||||
#define lua_rawsettable lua_rawset
|
||||
#define lua_rawgettable lua_rawget
|
||||
|
||||
lua_Object lua_rawgetglobal (lua_State *L, const char *name);
|
||||
void lua_rawsetglobal (lua_State *L, const char *name);/* In: value */
|
||||
|
||||
#ifdef LUA_SINGLESTATE
|
||||
#define lua_rawgetglobal(name) (lua_rawgetglobal(lua_state, name))
|
||||
#define lua_rawsetglobal(name) (lua_rawsetglobal(lua_state, name))
|
||||
#endif
|
||||
|
||||
#define lua_isfunction(L,n) (*lua_type(L,n) == 'f')
|
||||
#define lua_isstring(L,n) (lua_tostring(L,n))
|
||||
#define lua_istable(L,n) (*lua_type(L,n) == 't')
|
||||
#define lua_isuserdata(L,n) (*lua_type(L,n) == 'u')
|
||||
#define lua_isnil(L,n) (lua_type(L,n)[2] == 'l')
|
||||
#define lua_isnull(L,n) (*lua_type(L,n) == 'N')
|
||||
|
||||
#endif
|
||||
|
||||
|
16
luadebug.h
16
luadebug.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: luadebug.h,v 1.11 2000/08/08 20:42:07 roberto Exp roberto $
|
||||
** $Id: luadebug.h,v 1.12 2000/08/11 16:17:28 roberto Exp roberto $
|
||||
** Debugging API
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -19,8 +19,8 @@ typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
|
||||
|
||||
int lua_getstack (lua_State *L, int level, lua_Debug *ar);
|
||||
int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
|
||||
int lua_getlocal (lua_State *L, const lua_Debug *ar, lua_Localvar *v);
|
||||
int lua_setlocal (lua_State *L, const lua_Debug *ar, lua_Localvar *v);
|
||||
const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int localnum);
|
||||
const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int localnum);
|
||||
|
||||
lua_Hook lua_setcallhook (lua_State *L, lua_Hook func);
|
||||
lua_Hook lua_setlinehook (lua_State *L, lua_Hook func);
|
||||
@ -36,16 +36,8 @@ struct lua_Debug {
|
||||
const char *name; /* (n) */
|
||||
const char *namewhat; /* (n) `global', `tag method', `local', `field' */
|
||||
int nups; /* (u) number of upvalues */
|
||||
lua_Object func; /* (f) function being executed */
|
||||
/* private part */
|
||||
lua_Object _func; /* active function */
|
||||
};
|
||||
|
||||
|
||||
struct lua_Localvar {
|
||||
int index;
|
||||
const char *name;
|
||||
lua_Object value;
|
||||
struct lua_TObject *_func; /* active function */
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user