mirror of
https://github.com/lua/lua.git
synced 2026-07-29 01:19:06 +00:00
Compare commits
153 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e64dbc390a | ||
|
|
a0fd8d1787 | ||
|
|
d9d04a9274 | ||
|
|
b4ad600b93 | ||
|
|
cb7f027380 | ||
|
|
0bbd96bd5f | ||
|
|
4eb67aa710 | ||
|
|
0133610315 | ||
|
|
de04533dc0 | ||
|
|
7c9aee64c2 | ||
|
|
e0ff4e5d22 | ||
|
|
bf7f85d609 | ||
|
|
a775a2d81a | ||
|
|
e9aa98d594 | ||
|
|
3e9c6a8a24 | ||
|
|
1f4e2ba7b2 | ||
|
|
d6ff06751a | ||
|
|
7a11c7f8e4 | ||
|
|
c454dc7bdd | ||
|
|
82ad0d5770 | ||
|
|
256d1bea08 | ||
|
|
f2d35bdc78 | ||
|
|
2679461637 | ||
|
|
0870a2d1d8 | ||
|
|
78edc241e9 | ||
|
|
e907c711c0 | ||
|
|
5a8bb00df4 | ||
|
|
677188de8a | ||
|
|
6233d21c9d | ||
|
|
ab8ea5c38a | ||
|
|
ae9fd122fa | ||
|
|
da18ec5d54 | ||
|
|
038848eccd | ||
|
|
b678e465a1 | ||
|
|
72d675aba7 | ||
|
|
ba57f7d946 | ||
|
|
e63b542c9b | ||
|
|
6a853fcb8b | ||
|
|
31bea2190b | ||
|
|
4b954e9b2e | ||
|
|
055823c04d | ||
|
|
26d1e21c89 | ||
|
|
24a2c08145 | ||
|
|
9d7bae0b6a | ||
|
|
082aded149 | ||
|
|
aa9c75c06e | ||
|
|
f04c83e075 | ||
|
|
c364e9f97e | ||
|
|
e3a02e6a9c | ||
|
|
d5feffdb60 | ||
|
|
bb5627f3a4 | ||
|
|
21107d7c2c | ||
|
|
b5cd7d426f | ||
|
|
bf6d2ccf92 | ||
|
|
b82ff713e3 | ||
|
|
77113ee02f | ||
|
|
ad6c7b0dd4 | ||
|
|
8b2d97d187 | ||
|
|
fb1cf6ab2d | ||
|
|
19ca2087de | ||
|
|
7bdbd833b5 | ||
|
|
b22baf386d | ||
|
|
8fdd06ba3c | ||
|
|
028ec00ab9 | ||
|
|
1dcf1c9cbd | ||
|
|
76179a1014 | ||
|
|
bdfab46c22 | ||
|
|
5687949560 | ||
|
|
19de5b2205 | ||
|
|
cbc58af260 | ||
|
|
80001ab0eb | ||
|
|
ae29ab9858 | ||
|
|
27407fc1f5 | ||
|
|
1a17da2ff9 | ||
|
|
50248e440a | ||
|
|
0f0079f394 | ||
|
|
68267ed878 | ||
|
|
fd25d4ad85 | ||
|
|
2431534f10 | ||
|
|
fd7d0774e5 | ||
|
|
57ffc3f009 | ||
|
|
4a13f513f8 | ||
|
|
13ad46b67d | ||
|
|
1b45e967b4 | ||
|
|
933bead92e | ||
|
|
3314f49ec4 | ||
|
|
bc930aa5ff | ||
|
|
67b44c9493 | ||
|
|
758a381644 | ||
|
|
eec31aaca5 | ||
|
|
595738f6fe | ||
|
|
b5eb4f3126 | ||
|
|
3fecf187ff | ||
|
|
54840fb256 | ||
|
|
e87fddf1ad | ||
|
|
dea400bc1d | ||
|
|
fb663f768d | ||
|
|
e03767b3eb | ||
|
|
8396027516 | ||
|
|
e24f7fd2d2 | ||
|
|
8081f39dab | ||
|
|
3cc4ca821e | ||
|
|
01772cefa5 | ||
|
|
dc90d4bce3 | ||
|
|
f5bc671030 | ||
|
|
d7294c6de8 | ||
|
|
63a752f961 | ||
|
|
03d38b66fd | ||
|
|
b9c9ccfbb4 | ||
|
|
b94110a68f | ||
|
|
8278468041 | ||
|
|
4fbb2531b3 | ||
|
|
59f8e6fb77 | ||
|
|
05d89b5c05 | ||
|
|
fe5c41fb8a | ||
|
|
9a45543841 | ||
|
|
766e67ef3b | ||
|
|
4c94d8cc2c | ||
|
|
d2de2d5eda | ||
|
|
96a7695275 | ||
|
|
63166c0ca0 | ||
|
|
a881abfd1e | ||
|
|
d3ac7075a2 | ||
|
|
0c9080c7a9 | ||
|
|
b8fcb7b151 | ||
|
|
5d6de9075d | ||
|
|
21cff3015a | ||
|
|
5ca2709ba0 | ||
|
|
bb1cb7b9f1 | ||
|
|
c64f36ab2b | ||
|
|
e4830ddce3 | ||
|
|
758e330d6e | ||
|
|
8e3bd752bb | ||
|
|
a84bca67fc | ||
|
|
4ccfb2f9bc | ||
|
|
ce9609296c | ||
|
|
b1450721be | ||
|
|
b04294d3d8 | ||
|
|
22c2704842 | ||
|
|
ee22af5ced | ||
|
|
cc117253c8 | ||
|
|
8e226e6a09 | ||
|
|
1d420c2c11 | ||
|
|
5378331f2d | ||
|
|
894a264671 | ||
|
|
e1a127245d | ||
|
|
afb5ef72e1 | ||
|
|
1d8edd347d | ||
|
|
41d9ea948c | ||
|
|
ee912e5a7f | ||
|
|
ad446a0eb0 | ||
|
|
176cb39feb | ||
|
|
64ad009fb2 |
36
bugs
36
bugs
@@ -31,7 +31,7 @@ Tue Jan 27 17:12:36 EDT 1998
|
|||||||
|
|
||||||
** lstring.c / ltable.c
|
** lstring.c / ltable.c
|
||||||
Wed Jan 28 14:48:12 EDT 1998
|
Wed Jan 28 14:48:12 EDT 1998
|
||||||
>> tables can become full of "emptys" slots, and keep growing without limits.
|
>> tables can become full of "empty" slots, and keep growing without limits.
|
||||||
|
|
||||||
** lstrlib.c
|
** lstrlib.c
|
||||||
Mon Mar 9 15:26:09 EST 1998
|
Mon Mar 9 15:26:09 EST 1998
|
||||||
@@ -41,3 +41,37 @@ Mon Mar 9 15:26:09 EST 1998
|
|||||||
Mon May 18 19:20:00 EST 1998
|
Mon May 18 19:20:00 EST 1998
|
||||||
>> arguments for "format" 'x', 'X', 'o' and 'u' must be unsigned int.
|
>> arguments for "format" 'x', 'X', 'o' and 'u' must be unsigned int.
|
||||||
|
|
||||||
|
|
||||||
|
--- Version 3.1
|
||||||
|
|
||||||
|
** liolib.c / lauxlib.c
|
||||||
|
Mon Sep 7 15:57:02 EST 1998
|
||||||
|
>> function "luaL_argerror" prints wrong argument number (from a user's point
|
||||||
|
of view) when functions have upvalues.
|
||||||
|
|
||||||
|
** lstrlib.c
|
||||||
|
Tue Nov 10 17:29:36 EDT 1998
|
||||||
|
>> gsub/strfind do not check whether captures are properly finished.
|
||||||
|
|
||||||
|
** lbuiltin.c
|
||||||
|
Fri Dec 18 11:22:55 EDT 1998
|
||||||
|
>> "tonumber" goes crazy with negative numbers in other bases (not 10),
|
||||||
|
because "strtol" returns long, not unsigned long.
|
||||||
|
|
||||||
|
** lstrlib.c
|
||||||
|
Mon Jan 4 10:41:40 EDT 1999
|
||||||
|
>> "format" does not check size of format item (such as "%00000...00000d").
|
||||||
|
|
||||||
|
** lapi.c
|
||||||
|
Wed Feb 3 14:40:21 EDT 1999
|
||||||
|
>> getlocal cannot return the local itself, since lua_isstring and
|
||||||
|
lua_isnumber can modify it.
|
||||||
|
|
||||||
|
** lstrlib.c
|
||||||
|
Thu Feb 4 17:08:50 EDT 1999
|
||||||
|
>> format "%s" may break limit of "sprintf" on some machines.
|
||||||
|
|
||||||
|
|
||||||
|
** lzio.c
|
||||||
|
Thu Mar 4 11:49:37 EST 1999
|
||||||
|
>> file stream cannot call fread after EOF.
|
||||||
|
|||||||
213
lapi.c
213
lapi.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lapi.c,v 1.24 1998/03/09 21:49:52 roberto Exp roberto $
|
** $Id: lapi.c,v 1.41 1999/03/04 21:17:26 roberto Exp roberto $
|
||||||
** Lua API
|
** Lua API
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -25,17 +25,16 @@
|
|||||||
|
|
||||||
|
|
||||||
char lua_ident[] = "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n"
|
char lua_ident[] = "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n"
|
||||||
"$Autores: " LUA_AUTHORS " $";
|
"$Authors: " LUA_AUTHORS " $";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
TObject *luaA_Address (lua_Object o)
|
TObject *luaA_Address (lua_Object o) {
|
||||||
{
|
return (o != LUA_NOOBJECT) ? Address(o) : NULL;
|
||||||
return Address(o);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int normalized_type (TObject *o)
|
static lua_Type normalized_type (TObject *o)
|
||||||
{
|
{
|
||||||
int t = ttype(o);
|
int t = ttype(o);
|
||||||
switch (t) {
|
switch (t) {
|
||||||
@@ -71,12 +70,8 @@ void luaA_packresults (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int luaA_passresults (void)
|
int luaA_passresults (void) {
|
||||||
{
|
L->Cstack.base = L->Cstack.lua2C; /* position of first result */
|
||||||
luaD_checkstack(L->Cstack.num);
|
|
||||||
memcpy(L->stack.top, L->Cstack.lua2C+L->stack.stack,
|
|
||||||
L->Cstack.num*sizeof(TObject));
|
|
||||||
L->stack.top += L->Cstack.num;
|
|
||||||
return L->Cstack.num;
|
return L->Cstack.num;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,24 +83,29 @@ static void checkCparams (int nParams)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static lua_Object put_luaObject (TObject *o)
|
static lua_Object put_luaObject (TObject *o) {
|
||||||
{
|
|
||||||
luaD_openstack((L->stack.top-L->stack.stack)-L->Cstack.base);
|
luaD_openstack((L->stack.top-L->stack.stack)-L->Cstack.base);
|
||||||
L->stack.stack[L->Cstack.base++] = *o;
|
L->stack.stack[L->Cstack.base++] = *o;
|
||||||
return L->Cstack.base; /* this is +1 real position (see Ref) */
|
return L->Cstack.base; /* this is +1 real position (see Ref) */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static lua_Object put_luaObjectonTop (void)
|
static lua_Object put_luaObjectonTop (void) {
|
||||||
{
|
|
||||||
luaD_openstack((L->stack.top-L->stack.stack)-L->Cstack.base);
|
luaD_openstack((L->stack.top-L->stack.stack)-L->Cstack.base);
|
||||||
L->stack.stack[L->Cstack.base++] = *(--L->stack.top);
|
L->stack.stack[L->Cstack.base++] = *(--L->stack.top);
|
||||||
return L->Cstack.base; /* this is +1 real position (see Ref) */
|
return L->Cstack.base; /* this is +1 real position (see Ref) */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
lua_Object lua_pop (void)
|
static void top2LC (int n) {
|
||||||
{
|
/* Put the 'n' elements on the top as the Lua2C contents */
|
||||||
|
L->Cstack.base = (L->stack.top-L->stack.stack); /* 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 (void) {
|
||||||
checkCparams(1);
|
checkCparams(1);
|
||||||
return put_luaObjectonTop();
|
return put_luaObjectonTop();
|
||||||
}
|
}
|
||||||
@@ -150,12 +150,12 @@ lua_Object lua_settagmethod (int tag, char *event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
lua_Object lua_seterrormethod (void)
|
lua_Object lua_seterrormethod (void) {
|
||||||
{
|
lua_Object temp;
|
||||||
TObject temp = L->errorim;
|
|
||||||
checkCparams(1);
|
checkCparams(1);
|
||||||
L->errorim = *(--L->stack.top);
|
temp = lua_getglobal("_ERRORMESSAGE");
|
||||||
return put_luaObject(&temp);
|
lua_setglobal("_ERRORMESSAGE");
|
||||||
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -173,28 +173,23 @@ lua_Object lua_rawgettable (void)
|
|||||||
if (ttype(L->stack.top-2) != LUA_T_ARRAY)
|
if (ttype(L->stack.top-2) != LUA_T_ARRAY)
|
||||||
lua_error("indexed expression not a table in rawgettable");
|
lua_error("indexed expression not a table in rawgettable");
|
||||||
else {
|
else {
|
||||||
TObject *h = luaH_get(avalue(L->stack.top-2), L->stack.top-1);
|
*(L->stack.top-2) = *luaH_get(avalue(L->stack.top-2), L->stack.top-1);
|
||||||
--L->stack.top;
|
--L->stack.top;
|
||||||
if (h != NULL)
|
|
||||||
*(L->stack.top-1) = *h;
|
|
||||||
else
|
|
||||||
ttype(L->stack.top-1) = LUA_T_NIL;
|
|
||||||
}
|
}
|
||||||
return put_luaObjectonTop();
|
return put_luaObjectonTop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void lua_settable (void)
|
void lua_settable (void) {
|
||||||
{
|
|
||||||
checkCparams(3);
|
checkCparams(3);
|
||||||
luaV_settable(L->stack.top-3, 1);
|
luaV_settable(L->stack.top-3);
|
||||||
|
L->stack.top -= 2; /* pop table and index */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void lua_rawsettable (void)
|
void lua_rawsettable (void) {
|
||||||
{
|
|
||||||
checkCparams(3);
|
checkCparams(3);
|
||||||
luaV_settable(L->stack.top-3, 0);
|
luaV_rawsettable(L->stack.top-3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -426,22 +421,108 @@ void lua_settag (int tag)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
luaL_verror("cannot change the tag of a %.20s",
|
luaL_verror("cannot change the tag of a %.20s",
|
||||||
luaO_typenames[-ttype((L->stack.top-1))]);
|
luaO_typename(L->stack.top-1));
|
||||||
}
|
}
|
||||||
L->stack.top--;
|
L->stack.top--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TaggedString *luaA_nextvar (TaggedString *g) {
|
||||||
|
if (g == NULL)
|
||||||
|
g = (TaggedString *)L->rootglobal.next; /* first variable */
|
||||||
|
else {
|
||||||
|
/* check whether name is in global var list */
|
||||||
|
luaL_arg_check((GCnode *)g != g->head.next, 1, "variable name expected");
|
||||||
|
g = (TaggedString *)g->head.next; /* get next */
|
||||||
|
}
|
||||||
|
while (g && g->u.s.globalval.ttype == LUA_T_NIL) /* skip globals with nil */
|
||||||
|
g = (TaggedString *)g->head.next;
|
||||||
|
if (g) {
|
||||||
|
ttype(L->stack.top) = LUA_T_STRING; tsvalue(L->stack.top) = g;
|
||||||
|
incr_top;
|
||||||
|
luaA_pushobject(&g->u.s.globalval);
|
||||||
|
}
|
||||||
|
return g;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *lua_nextvar (char *varname) {
|
||||||
|
TaggedString *g = (varname == NULL) ? NULL : luaS_new(varname);
|
||||||
|
g = luaA_nextvar(g);
|
||||||
|
if (g) {
|
||||||
|
top2LC(2);
|
||||||
|
return g->str;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
top2LC(0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int luaA_next (Hash *t, int i) {
|
||||||
|
int tsize = nhash(t);
|
||||||
|
for (; i<tsize; i++) {
|
||||||
|
Node *n = node(t, i);
|
||||||
|
if (ttype(val(n)) != LUA_T_NIL) {
|
||||||
|
luaA_pushobject(ref(n));
|
||||||
|
luaA_pushobject(val(n));
|
||||||
|
return i+1; /* index to be used next time */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0; /* no more elements */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int lua_next (lua_Object o, int i) {
|
||||||
|
TObject *t = Address(o);
|
||||||
|
if (ttype(t) != LUA_T_ARRAY)
|
||||||
|
lua_error("API error - object is not a table in `lua_next'");
|
||||||
|
i = luaA_next(avalue(t), i);
|
||||||
|
top2LC((i==0) ? 0 : 2);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** =======================================================
|
** {======================================================
|
||||||
** Debug interface
|
** To manipulate some state information
|
||||||
** =======================================================
|
** =======================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
lua_State *lua_setstate (lua_State *st) {
|
||||||
|
lua_State *old = lua_state;
|
||||||
|
lua_state = st;
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
/* Hooks */
|
lua_LHFunction lua_setlinehook (lua_LHFunction func) {
|
||||||
lua_CHFunction lua_callhook = NULL;
|
lua_LHFunction old = L->linehook;
|
||||||
lua_LHFunction lua_linehook = NULL;
|
L->linehook = func;
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_CHFunction lua_setcallhook (lua_CHFunction func) {
|
||||||
|
lua_CHFunction old = L->callhook;
|
||||||
|
L->callhook = func;
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua_setdebug (int debug) {
|
||||||
|
int old = L->debug;
|
||||||
|
L->debug = debug;
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* }====================================================== */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** {======================================================
|
||||||
|
** Debug interface
|
||||||
|
** =======================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
lua_Function lua_stackedfunction (int level)
|
lua_Function lua_stackedfunction (int level)
|
||||||
@@ -457,6 +538,12 @@ lua_Function lua_stackedfunction (int level)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int lua_nups (lua_Function func) {
|
||||||
|
TObject *o = luaA_Address(func);
|
||||||
|
return (!o || normalized_type(o) != LUA_T_CLOSURE) ? 0 : o->value.cl->nelems;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int lua_currentline (lua_Function func)
|
int lua_currentline (lua_Function func)
|
||||||
{
|
{
|
||||||
TObject *f = Address(func);
|
TObject *f = Address(func);
|
||||||
@@ -465,8 +552,7 @@ int lua_currentline (lua_Function func)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
lua_Object lua_getlocal (lua_Function func, int local_number, char **name)
|
lua_Object lua_getlocal (lua_Function func, int local_number, char **name) {
|
||||||
{
|
|
||||||
/* check whether func is a Lua function */
|
/* check whether func is a Lua function */
|
||||||
if (lua_tag(func) != LUA_T_PROTO)
|
if (lua_tag(func) != LUA_T_PROTO)
|
||||||
return LUA_NOOBJECT;
|
return LUA_NOOBJECT;
|
||||||
@@ -477,7 +563,7 @@ lua_Object lua_getlocal (lua_Function func, int local_number, char **name)
|
|||||||
if (*name) {
|
if (*name) {
|
||||||
/* if "*name", there must be a LUA_T_LINE */
|
/* if "*name", there must be a LUA_T_LINE */
|
||||||
/* therefore, f+2 points to function base */
|
/* therefore, f+2 points to function base */
|
||||||
return Ref((f+2)+(local_number-1));
|
return put_luaObject((f+2)+(local_number-1));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return LUA_NOOBJECT;
|
return LUA_NOOBJECT;
|
||||||
@@ -508,18 +594,17 @@ int lua_setlocal (lua_Function func, int local_number)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void lua_funcinfo (lua_Object func, char **filename, int *linedefined)
|
void lua_funcinfo (lua_Object func, char **source, int *linedefined) {
|
||||||
{
|
|
||||||
if (!lua_isfunction(func))
|
if (!lua_isfunction(func))
|
||||||
lua_error("API - `funcinfo' called with a non-function value");
|
lua_error("API - `funcinfo' called with a non-function value");
|
||||||
else {
|
else {
|
||||||
TObject *f = luaA_protovalue(Address(func));
|
TObject *f = luaA_protovalue(Address(func));
|
||||||
if (normalized_type(f) == LUA_T_PROTO) {
|
if (normalized_type(f) == LUA_T_PROTO) {
|
||||||
*filename = tfvalue(f)->fileName->str;
|
*source = tfvalue(f)->source->str;
|
||||||
*linedefined = tfvalue(f)->lineDefined;
|
*linedefined = tfvalue(f)->lineDefined;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
*filename = "(C)";
|
*source = "(C)";
|
||||||
*linedefined = -1;
|
*linedefined = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -534,16 +619,19 @@ static int checkfunc (TObject *o)
|
|||||||
|
|
||||||
char *lua_getobjname (lua_Object o, char **name)
|
char *lua_getobjname (lua_Object o, char **name)
|
||||||
{ /* try to find a name for given function */
|
{ /* try to find a name for given function */
|
||||||
set_normalized(L->stack.top, Address(o)); /* to be accessed by "checkfunc */
|
set_normalized(L->stack.top, Address(o)); /* to be accessed by "checkfunc" */
|
||||||
if ((*name = luaT_travtagmethods(checkfunc)) != NULL)
|
if ((*name = luaS_travsymbol(checkfunc)) != NULL)
|
||||||
return "tag-method";
|
|
||||||
else if ((*name = luaS_travsymbol(checkfunc)) != NULL)
|
|
||||||
return "global";
|
return "global";
|
||||||
|
else if ((*name = luaT_travtagmethods(checkfunc)) != NULL)
|
||||||
|
return "tag-method";
|
||||||
else return "";
|
else return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* }====================================================== */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** =======================================================
|
** {======================================================
|
||||||
** BLOCK mechanism
|
** BLOCK mechanism
|
||||||
** =======================================================
|
** =======================================================
|
||||||
*/
|
*/
|
||||||
@@ -583,26 +671,7 @@ lua_Object lua_getref (int ref)
|
|||||||
return (o ? put_luaObject(o) : LUA_NOOBJECT);
|
return (o ? put_luaObject(o) : LUA_NOOBJECT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* }====================================================== */
|
||||||
/*
|
|
||||||
** =======================================================
|
|
||||||
** Derived functions
|
|
||||||
** =======================================================
|
|
||||||
*/
|
|
||||||
int (lua_call) (char *name) { return lua_call(name); }
|
|
||||||
|
|
||||||
void (lua_pushref) (int ref) { lua_pushref(ref); }
|
|
||||||
|
|
||||||
int (lua_refobject) (lua_Object o, int l) { return lua_refobject(o, l); }
|
|
||||||
|
|
||||||
void (lua_register) (char *n, lua_CFunction f) { lua_register(n, f); }
|
|
||||||
|
|
||||||
void (lua_pushuserdata) (void *u) { lua_pushuserdata(u); }
|
|
||||||
|
|
||||||
void (lua_pushcfunction) (lua_CFunction f) { lua_pushcfunction(f); }
|
|
||||||
|
|
||||||
int (lua_clonetag) (int t) { return lua_clonetag(t); }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
4
lapi.h
4
lapi.h
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lapi.h,v 1.1 1997/09/16 19:25:59 roberto Exp roberto $
|
** $Id: lapi.h,v 1.3 1999/02/22 19:13:12 roberto Exp roberto $
|
||||||
** Auxiliary functions from Lua API
|
** Auxiliary functions from Lua API
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -16,5 +16,7 @@ TObject *luaA_Address (lua_Object o);
|
|||||||
void luaA_pushobject (TObject *o);
|
void luaA_pushobject (TObject *o);
|
||||||
void luaA_packresults (void);
|
void luaA_packresults (void);
|
||||||
int luaA_passresults (void);
|
int luaA_passresults (void);
|
||||||
|
TaggedString *luaA_nextvar (TaggedString *g);
|
||||||
|
int luaA_next (Hash *t, int i);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
36
lauxlib.c
36
lauxlib.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lauxlib.c,v 1.11 1998/06/18 16:57:03 roberto Exp roberto $
|
** $Id: lauxlib.c,v 1.16 1999/03/10 14:19:41 roberto Exp roberto $
|
||||||
** Auxiliary functions for building Lua libraries
|
** Auxiliary functions for building Lua libraries
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -10,9 +10,10 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
/* Please Notice: This file uses only the official API of Lua
|
/* Please Notice: This file uses only the official API of Lua
|
||||||
** Any function declared here could be written as an application
|
** Any function declared here could be written as an application function.
|
||||||
** function. With care, these functions can be used by other libraries.
|
** With care, these functions can be used by other libraries.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "lauxlib.h"
|
#include "lauxlib.h"
|
||||||
#include "lua.h"
|
#include "lua.h"
|
||||||
#include "luadebug.h"
|
#include "luadebug.h"
|
||||||
@@ -27,12 +28,13 @@ int luaL_findstring (char *name, char *list[]) {
|
|||||||
return -1; /* name not found */
|
return -1; /* name not found */
|
||||||
}
|
}
|
||||||
|
|
||||||
void luaL_argerror (int numarg, char *extramsg)
|
void luaL_argerror (int numarg, char *extramsg) {
|
||||||
{
|
lua_Function f = lua_stackedfunction(0);
|
||||||
char *funcname;
|
char *funcname;
|
||||||
lua_getobjname(lua_stackedfunction(0), &funcname);
|
lua_getobjname(f, &funcname);
|
||||||
|
numarg -= lua_nups(f);
|
||||||
if (funcname == NULL)
|
if (funcname == NULL)
|
||||||
funcname = "???";
|
funcname = "?";
|
||||||
if (extramsg == NULL)
|
if (extramsg == NULL)
|
||||||
luaL_verror("bad argument #%d to function `%.50s'", numarg, funcname);
|
luaL_verror("bad argument #%d to function `%.50s'", numarg, funcname);
|
||||||
else
|
else
|
||||||
@@ -109,3 +111,23 @@ void luaL_verror (char *fmt, ...)
|
|||||||
lua_error(buff);
|
lua_error(buff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void luaL_chunkid (char *out, char *source, int len) {
|
||||||
|
len -= 13; /* 13 = strlen("string ''...\0") */
|
||||||
|
if (*source == '@')
|
||||||
|
sprintf(out, "file `%.*s'", len, source+1);
|
||||||
|
else if (*source == '(')
|
||||||
|
strcpy(out, "(C code)");
|
||||||
|
else {
|
||||||
|
char *b = strchr(source , '\n'); /* stop string at first new line */
|
||||||
|
int lim = (b && (b-source)<len) ? b-source : len;
|
||||||
|
sprintf(out, "string `%.*s'", lim, source);
|
||||||
|
strcpy(out+lim+(13-5), "...'"); /* 5 = strlen("...'\0") */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void luaL_filesource (char *out, char *filename, int len) {
|
||||||
|
if (filename == NULL) filename = "(stdin)";
|
||||||
|
sprintf(out, "@%.*s", len-2, filename); /* -2 for '@' and '\0' */
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lauxlib.h,v 1.8 1998/06/18 16:57:03 roberto Exp roberto $
|
** $Id: lauxlib.h,v 1.11 1999/03/04 21:17:26 roberto Exp roberto $
|
||||||
** Auxiliary functions for building Lua libraries
|
** Auxiliary functions for building Lua libraries
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -28,7 +28,11 @@ char *luaL_check_lstr (int numArg, long *len);
|
|||||||
#define luaL_opt_string(n, d) (luaL_opt_lstr((n), (d), NULL))
|
#define luaL_opt_string(n, d) (luaL_opt_lstr((n), (d), NULL))
|
||||||
char *luaL_opt_lstr (int numArg, char *def, long *len);
|
char *luaL_opt_lstr (int numArg, char *def, long *len);
|
||||||
double luaL_check_number (int numArg);
|
double luaL_check_number (int numArg);
|
||||||
|
#define luaL_check_int(n) ((int)luaL_check_number(n))
|
||||||
|
#define luaL_check_long(n) ((long)luaL_check_number(n))
|
||||||
double luaL_opt_number (int numArg, double def);
|
double luaL_opt_number (int numArg, double def);
|
||||||
|
#define luaL_opt_int(n,d) ((int)luaL_opt_number(n,d))
|
||||||
|
#define luaL_opt_long(n,d) ((long)luaL_opt_number(n,d))
|
||||||
lua_Object luaL_functionarg (int arg);
|
lua_Object luaL_functionarg (int arg);
|
||||||
lua_Object luaL_tablearg (int arg);
|
lua_Object luaL_tablearg (int arg);
|
||||||
lua_Object luaL_nonnullarg (int numArg);
|
lua_Object luaL_nonnullarg (int numArg);
|
||||||
@@ -42,6 +46,8 @@ int luaL_newbuffer (int size);
|
|||||||
void luaL_oldbuffer (int old);
|
void luaL_oldbuffer (int old);
|
||||||
char *luaL_buffer (void);
|
char *luaL_buffer (void);
|
||||||
int luaL_findstring (char *name, char *list[]);
|
int luaL_findstring (char *name, char *list[]);
|
||||||
|
void luaL_chunkid (char *out, char *source, int len);
|
||||||
|
void luaL_filesource (char *out, char *filename, int len);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
60
lbuffer.c
60
lbuffer.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lbuffer.c,v 1.3 1998/06/02 20:37:04 roberto Exp roberto $
|
** $Id: lbuffer.c,v 1.8 1999/02/25 19:20:40 roberto Exp roberto $
|
||||||
** Auxiliary functions for building Lua libraries
|
** Auxiliary functions for building Lua libraries
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -16,70 +16,60 @@
|
|||||||
** Auxiliary buffer
|
** Auxiliary buffer
|
||||||
-------------------------------------------------------*/
|
-------------------------------------------------------*/
|
||||||
|
|
||||||
#define BUFF_STEP 32
|
|
||||||
|
#define EXTRABUFF 32
|
||||||
|
|
||||||
|
|
||||||
#define openspace(size) if (L->Mbuffnext+(size) > L->Mbuffsize) Openspace(size)
|
#define openspace(size) if (L->Mbuffnext+(size) > L->Mbuffsize) Openspace(size)
|
||||||
|
|
||||||
static void Openspace (int size)
|
static void Openspace (int size) {
|
||||||
{
|
|
||||||
lua_State *l = L; /* to optimize */
|
lua_State *l = L; /* to optimize */
|
||||||
int base = l->Mbuffbase-l->Mbuffer;
|
size += EXTRABUFF;
|
||||||
l->Mbuffsize *= 2;
|
l->Mbuffsize = l->Mbuffnext+size;
|
||||||
if (l->Mbuffnext+size > l->Mbuffsize) /* still not big enough? */
|
luaM_growvector(l->Mbuffer, l->Mbuffnext, size, char, arrEM, MAX_INT);
|
||||||
l->Mbuffsize = l->Mbuffnext+size;
|
|
||||||
l->Mbuffer = luaM_realloc(l->Mbuffer, l->Mbuffsize);
|
|
||||||
l->Mbuffbase = l->Mbuffer+base;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char *luaL_openspace (int size)
|
char *luaL_openspace (int size) {
|
||||||
{
|
|
||||||
openspace(size);
|
openspace(size);
|
||||||
return L->Mbuffer+L->Mbuffnext;
|
return L->Mbuffer+L->Mbuffnext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void luaL_addchar (int c)
|
void luaL_addchar (int c) {
|
||||||
{
|
openspace(1);
|
||||||
openspace(BUFF_STEP);
|
L->Mbuffer[L->Mbuffnext++] = (char)c;
|
||||||
L->Mbuffer[L->Mbuffnext++] = c;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void luaL_resetbuffer (void)
|
void luaL_resetbuffer (void) {
|
||||||
{
|
L->Mbuffnext = L->Mbuffbase;
|
||||||
L->Mbuffnext = L->Mbuffbase-L->Mbuffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void luaL_addsize (int n)
|
void luaL_addsize (int n) {
|
||||||
{
|
|
||||||
L->Mbuffnext += n;
|
L->Mbuffnext += n;
|
||||||
}
|
}
|
||||||
|
|
||||||
int luaL_getsize (void)
|
int luaL_getsize (void) {
|
||||||
{
|
return L->Mbuffnext-L->Mbuffbase;
|
||||||
return L->Mbuffnext-(L->Mbuffbase-L->Mbuffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int luaL_newbuffer (int size)
|
int luaL_newbuffer (int size) {
|
||||||
{
|
int old = L->Mbuffbase;
|
||||||
int old = L->Mbuffbase-L->Mbuffer;
|
|
||||||
openspace(size);
|
openspace(size);
|
||||||
L->Mbuffbase = L->Mbuffer+L->Mbuffnext;
|
L->Mbuffbase = L->Mbuffnext;
|
||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void luaL_oldbuffer (int old)
|
void luaL_oldbuffer (int old) {
|
||||||
{
|
L->Mbuffnext = L->Mbuffbase;
|
||||||
L->Mbuffnext = L->Mbuffbase-L->Mbuffer;
|
L->Mbuffbase = old;
|
||||||
L->Mbuffbase = L->Mbuffer+old;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char *luaL_buffer (void)
|
char *luaL_buffer (void) {
|
||||||
{
|
return L->Mbuffer+L->Mbuffbase;
|
||||||
return L->Mbuffbase;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
814
lbuiltin.c
814
lbuiltin.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lbuiltin.c,v 1.31 1998/06/19 18:47:06 roberto Exp roberto $
|
** $Id: lbuiltin.c,v 1.55 1999/03/01 20:22:16 roberto Exp roberto $
|
||||||
** Built-in functions
|
** Built-in functions
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -23,11 +23,18 @@
|
|||||||
#include "ltm.h"
|
#include "ltm.h"
|
||||||
#include "lua.h"
|
#include "lua.h"
|
||||||
#include "lundump.h"
|
#include "lundump.h"
|
||||||
|
#include "lvm.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void pushstring (TaggedString *s)
|
/*
|
||||||
{
|
** {======================================================
|
||||||
|
** Auxiliary functions
|
||||||
|
** =======================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
static void pushtagstring (TaggedString *s) {
|
||||||
TObject o;
|
TObject o;
|
||||||
o.ttype = LUA_T_STRING;
|
o.ttype = LUA_T_STRING;
|
||||||
o.value.ts = s;
|
o.value.ts = s;
|
||||||
@@ -35,209 +42,123 @@ static void pushstring (TaggedString *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void nextvar (void)
|
static real getsize (Hash *h) {
|
||||||
{
|
real max = 0;
|
||||||
TObject *o = luaA_Address(luaL_nonnullarg(1));
|
|
||||||
TaggedString *g;
|
|
||||||
if (ttype(o) == LUA_T_NIL)
|
|
||||||
g = (TaggedString *)L->rootglobal.next;
|
|
||||||
else {
|
|
||||||
luaL_arg_check(ttype(o) == LUA_T_STRING, 1, "variable name expected");
|
|
||||||
g = tsvalue(o);
|
|
||||||
/* check whether name is in global var list */
|
|
||||||
luaL_arg_check((GCnode *)g != g->head.next, 1, "variable name expected");
|
|
||||||
g = (TaggedString *)g->head.next;
|
|
||||||
}
|
|
||||||
while (g && g->u.s.globalval.ttype == LUA_T_NIL) /* skip globals with nil */
|
|
||||||
g = (TaggedString *)g->head.next;
|
|
||||||
if (g) {
|
|
||||||
pushstring(g);
|
|
||||||
luaA_pushobject(&g->u.s.globalval);
|
|
||||||
}
|
|
||||||
else lua_pushnil();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void foreachvar (void)
|
|
||||||
{
|
|
||||||
TObject f = *luaA_Address(luaL_functionarg(1));
|
|
||||||
GCnode *g;
|
|
||||||
StkId name = L->Cstack.base++; /* place to keep var name (to avoid GC) */
|
|
||||||
ttype(L->stack.stack+name) = LUA_T_NIL;
|
|
||||||
L->stack.top++;
|
|
||||||
for (g = L->rootglobal.next; g; g = g->next) {
|
|
||||||
TaggedString *s = (TaggedString *)g;
|
|
||||||
if (s->u.s.globalval.ttype != LUA_T_NIL) {
|
|
||||||
ttype(L->stack.stack+name) = LUA_T_STRING;
|
|
||||||
tsvalue(L->stack.stack+name) = s; /* keep s on stack to avoid GC */
|
|
||||||
luaA_pushobject(&f);
|
|
||||||
pushstring(s);
|
|
||||||
luaA_pushobject(&s->u.s.globalval);
|
|
||||||
luaD_call((L->stack.top-L->stack.stack)-2, 1);
|
|
||||||
if (ttype(L->stack.top-1) != LUA_T_NIL)
|
|
||||||
return;
|
|
||||||
L->stack.top--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void next (void)
|
|
||||||
{
|
|
||||||
lua_Object o = luaL_tablearg(1);
|
|
||||||
lua_Object r = luaL_nonnullarg(2);
|
|
||||||
Node *n = luaH_next(luaA_Address(o), luaA_Address(r));
|
|
||||||
if (n) {
|
|
||||||
luaA_pushobject(&n->ref);
|
|
||||||
luaA_pushobject(&n->val);
|
|
||||||
}
|
|
||||||
else lua_pushnil();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void foreach (void)
|
|
||||||
{
|
|
||||||
TObject t = *luaA_Address(luaL_tablearg(1));
|
|
||||||
TObject f = *luaA_Address(luaL_functionarg(2));
|
|
||||||
int i;
|
int i;
|
||||||
for (i=0; i<avalue(&t)->nhash; i++) {
|
for (i = 0; i<nhash(h); i++) {
|
||||||
Node *nd = &(avalue(&t)->node[i]);
|
Node *n = h->node+i;
|
||||||
if (ttype(ref(nd)) != LUA_T_NIL && ttype(val(nd)) != LUA_T_NIL) {
|
if (ttype(ref(n)) == LUA_T_NUMBER &&
|
||||||
luaA_pushobject(&f);
|
ttype(val(n)) != LUA_T_NIL &&
|
||||||
luaA_pushobject(ref(nd));
|
nvalue(ref(n)) > max)
|
||||||
luaA_pushobject(val(nd));
|
max = nvalue(ref(n));
|
||||||
luaD_call((L->stack.top-L->stack.stack)-2, 1);
|
}
|
||||||
if (ttype(L->stack.top-1) != LUA_T_NIL)
|
return max;
|
||||||
return;
|
}
|
||||||
L->stack.top--;
|
|
||||||
}
|
|
||||||
|
static real getnarg (Hash *a) {
|
||||||
|
TObject index;
|
||||||
|
TObject *value;
|
||||||
|
/* value = table.n */
|
||||||
|
ttype(&index) = LUA_T_STRING;
|
||||||
|
tsvalue(&index) = luaS_new("n");
|
||||||
|
value = luaH_get(a, &index);
|
||||||
|
return (ttype(value) == LUA_T_NUMBER) ? nvalue(value) : getsize(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static Hash *gethash (int arg) {
|
||||||
|
return avalue(luaA_Address(luaL_tablearg(arg)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* }====================================================== */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** {======================================================
|
||||||
|
** Functions that use only the official API
|
||||||
|
** =======================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** If your system does not support "stderr", redefine this function, or
|
||||||
|
** redefine _ERRORMESSAGE so that it won't need _ALERT.
|
||||||
|
*/
|
||||||
|
static void luaB_alert (void) {
|
||||||
|
fputs(luaL_check_string(1), stderr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Standard implementation of _ERRORMESSAGE.
|
||||||
|
** The library "iolib" redefines _ERRORMESSAGE for better error information.
|
||||||
|
*/
|
||||||
|
static void error_message (void) {
|
||||||
|
lua_Object al = lua_rawgetglobal("_ALERT");
|
||||||
|
if (lua_isfunction(al)) { /* avoid error loop if _ALERT is not defined */
|
||||||
|
char buff[600];
|
||||||
|
sprintf(buff, "lua error: %.500s\n", luaL_check_string(1));
|
||||||
|
lua_pushstring(buff);
|
||||||
|
lua_callfunction(al);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void internaldostring (void)
|
/*
|
||||||
{
|
** If your system does not support "stdout", just remove this function.
|
||||||
long l;
|
** If you need, you can define your own "print" function, following this
|
||||||
char *s = luaL_check_lstr(1, &l);
|
** model but changing "fputs" to put the strings at a proper place
|
||||||
if (*s == ID_CHUNK)
|
** (a console window or a log file, for instance).
|
||||||
lua_error("`dostring' cannot run pre-compiled code");
|
*/
|
||||||
if (lua_dobuffer(s, l, luaL_opt_string(2, NULL)) == 0)
|
#define MAXPRINT 40
|
||||||
if (luaA_passresults() == 0)
|
static void luaB_print (void) {
|
||||||
lua_pushuserdata(NULL); /* at least one result to signal no errors */
|
lua_Object args[MAXPRINT];
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void internaldofile (void)
|
|
||||||
{
|
|
||||||
char *fname = luaL_opt_string(1, NULL);
|
|
||||||
if (lua_dofile(fname) == 0)
|
|
||||||
if (luaA_passresults() == 0)
|
|
||||||
lua_pushuserdata(NULL); /* at least one result to signal no errors */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void to_string (void) {
|
|
||||||
lua_Object obj = lua_getparam(1);
|
|
||||||
char *buff = luaL_openspace(30);
|
|
||||||
TObject *o = luaA_Address(obj);
|
|
||||||
switch (ttype(o)) {
|
|
||||||
case LUA_T_NUMBER:
|
|
||||||
lua_pushstring(lua_getstring(obj));
|
|
||||||
return;
|
|
||||||
case LUA_T_STRING:
|
|
||||||
lua_pushobject(obj);
|
|
||||||
return;
|
|
||||||
case LUA_T_ARRAY: {
|
|
||||||
sprintf(buff, "table: %p", (void *)o->value.a);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LUA_T_CLOSURE: {
|
|
||||||
sprintf(buff, "function: %p", (void *)o->value.cl);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LUA_T_PROTO: {
|
|
||||||
sprintf(buff, "function: %p", (void *)o->value.tf);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LUA_T_CPROTO: {
|
|
||||||
sprintf(buff, "function: %p", (void *)o->value.f);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LUA_T_USERDATA: {
|
|
||||||
sprintf(buff, "userdata: %p", o->value.ts->u.d.v);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LUA_T_NIL:
|
|
||||||
lua_pushstring("nil");
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
LUA_INTERNALERROR("invalid type");
|
|
||||||
}
|
|
||||||
lua_pushstring(buff);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void luaI_print (void) {
|
|
||||||
TaggedString *ts = luaS_new("tostring");
|
|
||||||
lua_Object obj;
|
lua_Object obj;
|
||||||
int i = 1;
|
int n = 0;
|
||||||
while ((obj = lua_getparam(i++)) != LUA_NOOBJECT) {
|
int i;
|
||||||
luaA_pushobject(&ts->u.s.globalval);
|
while ((obj = lua_getparam(n+1)) != LUA_NOOBJECT) {
|
||||||
lua_pushobject(obj);
|
luaL_arg_check(n < MAXPRINT, n+1, "too many arguments");
|
||||||
luaD_call((L->stack.top-L->stack.stack)-1, 1);
|
args[n++] = obj;
|
||||||
if (ttype(L->stack.top-1) != LUA_T_STRING)
|
|
||||||
lua_error("`tostring' must return a string to `print'");
|
|
||||||
printf("%s\t", svalue(L->stack.top-1));
|
|
||||||
L->stack.top--;
|
|
||||||
}
|
}
|
||||||
printf("\n");
|
for (i=0; i<n; i++) {
|
||||||
|
lua_pushobject(args[i]);
|
||||||
|
if (lua_call("tostring"))
|
||||||
|
lua_error("error in `tostring' called by `print'");
|
||||||
|
obj = lua_getresult(1);
|
||||||
|
if (!lua_isstring(obj))
|
||||||
|
lua_error("`tostring' must return a string to `print'");
|
||||||
|
if (i>0) fputs("\t", stdout);
|
||||||
|
fputs(lua_getstring(obj), stdout);
|
||||||
|
}
|
||||||
|
fputs("\n", stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void luaI_type (void)
|
static void luaB_tonumber (void) {
|
||||||
{
|
int base = luaL_opt_int(2, 10);
|
||||||
lua_Object o = luaL_nonnullarg(1);
|
|
||||||
lua_pushstring(luaO_typenames[-ttype(luaA_Address(o))]);
|
|
||||||
lua_pushnumber(lua_tag(o));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void tonumber (void)
|
|
||||||
{
|
|
||||||
int base = luaL_opt_number(2, 10);
|
|
||||||
if (base == 10) { /* standard conversion */
|
if (base == 10) { /* standard conversion */
|
||||||
lua_Object o = lua_getparam(1);
|
lua_Object o = lua_getparam(1);
|
||||||
if (lua_isnumber(o))
|
if (lua_isnumber(o)) lua_pushnumber(lua_getnumber(o));
|
||||||
lua_pushnumber(lua_getnumber(o));
|
else lua_pushnil(); /* not a number */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
char *s = luaL_check_string(1);
|
char *s = luaL_check_string(1);
|
||||||
unsigned long n;
|
long n;
|
||||||
luaL_arg_check(0 <= base && base <= 36, 2, "base out of range");
|
luaL_arg_check(0 <= base && base <= 36, 2, "base out of range");
|
||||||
n = strtol(s, &s, base);
|
n = strtol(s, &s, base);
|
||||||
while (isspace(*s)) s++; /* skip trailing spaces */
|
while (isspace((unsigned char)*s)) s++; /* skip trailing spaces */
|
||||||
if (*s) lua_pushnil(); /* invalid format: return nil */
|
if (*s) lua_pushnil(); /* invalid format: return nil */
|
||||||
else lua_pushnumber(n);
|
else lua_pushnumber(n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void luaI_error (void)
|
static void luaB_error (void) {
|
||||||
{
|
|
||||||
lua_error(lua_getstring(lua_getparam(1)));
|
lua_error(lua_getstring(lua_getparam(1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void luaB_setglobal (void) {
|
||||||
static void luaI_assert (void)
|
|
||||||
{
|
|
||||||
lua_Object p = lua_getparam(1);
|
|
||||||
if (p == LUA_NOOBJECT || lua_isnil(p))
|
|
||||||
luaL_verror("assertion failed! %.100s", luaL_opt_string(2, ""));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void setglobal (void)
|
|
||||||
{
|
|
||||||
char *n = luaL_check_string(1);
|
char *n = luaL_check_string(1);
|
||||||
lua_Object value = luaL_nonnullarg(2);
|
lua_Object value = luaL_nonnullarg(2);
|
||||||
lua_pushobject(value);
|
lua_pushobject(value);
|
||||||
@@ -245,8 +166,7 @@ static void setglobal (void)
|
|||||||
lua_pushobject(value); /* return given value */
|
lua_pushobject(value); /* return given value */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rawsetglobal (void)
|
static void luaB_rawsetglobal (void) {
|
||||||
{
|
|
||||||
char *n = luaL_check_string(1);
|
char *n = luaL_check_string(1);
|
||||||
lua_Object value = luaL_nonnullarg(2);
|
lua_Object value = luaL_nonnullarg(2);
|
||||||
lua_pushobject(value);
|
lua_pushobject(value);
|
||||||
@@ -254,51 +174,111 @@ static void rawsetglobal (void)
|
|||||||
lua_pushobject(value); /* return given value */
|
lua_pushobject(value); /* return given value */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void getglobal (void)
|
static void luaB_getglobal (void) {
|
||||||
{
|
|
||||||
lua_pushobject(lua_getglobal(luaL_check_string(1)));
|
lua_pushobject(lua_getglobal(luaL_check_string(1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rawgetglobal (void)
|
static void luaB_rawgetglobal (void) {
|
||||||
{
|
|
||||||
lua_pushobject(lua_rawgetglobal(luaL_check_string(1)));
|
lua_pushobject(lua_rawgetglobal(luaL_check_string(1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void luatag (void)
|
static void luaB_luatag (void) {
|
||||||
{
|
|
||||||
lua_pushnumber(lua_tag(lua_getparam(1)));
|
lua_pushnumber(lua_tag(lua_getparam(1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void luaB_settag (void) {
|
||||||
static int getnarg (lua_Object table)
|
lua_Object o = luaL_tablearg(1);
|
||||||
{
|
lua_pushobject(o);
|
||||||
lua_Object temp;
|
lua_settag(luaL_check_int(2));
|
||||||
/* temp = table.n */
|
lua_pushobject(o); /* return first argument */
|
||||||
lua_pushobject(table); lua_pushstring("n"); temp = lua_rawgettable();
|
|
||||||
return (lua_isnumber(temp) ? lua_getnumber(temp) : MAX_INT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void luaI_call (void)
|
static void luaB_newtag (void) {
|
||||||
{
|
lua_pushnumber(lua_newtag());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void luaB_copytagmethods (void) {
|
||||||
|
lua_pushnumber(lua_copytagmethods(luaL_check_int(1),
|
||||||
|
luaL_check_int(2)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void luaB_rawgettable (void) {
|
||||||
|
lua_pushobject(luaL_nonnullarg(1));
|
||||||
|
lua_pushobject(luaL_nonnullarg(2));
|
||||||
|
lua_pushobject(lua_rawgettable());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void luaB_rawsettable (void) {
|
||||||
|
lua_pushobject(luaL_nonnullarg(1));
|
||||||
|
lua_pushobject(luaL_nonnullarg(2));
|
||||||
|
lua_pushobject(luaL_nonnullarg(3));
|
||||||
|
lua_rawsettable();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void luaB_settagmethod (void) {
|
||||||
|
lua_Object nf = luaL_nonnullarg(3);
|
||||||
|
lua_pushobject(nf);
|
||||||
|
lua_pushobject(lua_settagmethod(luaL_check_int(1), luaL_check_string(2)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void luaB_gettagmethod (void) {
|
||||||
|
lua_pushobject(lua_gettagmethod(luaL_check_int(1), luaL_check_string(2)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void luaB_seterrormethod (void) {
|
||||||
|
lua_Object nf = luaL_functionarg(1);
|
||||||
|
lua_pushobject(nf);
|
||||||
|
lua_pushobject(lua_seterrormethod());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void luaB_collectgarbage (void) {
|
||||||
|
lua_pushnumber(lua_collectgarbage(luaL_opt_int(1, 0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* }====================================================== */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** {======================================================
|
||||||
|
** Functions that could use only the official API but
|
||||||
|
** do not, for efficiency.
|
||||||
|
** =======================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void luaB_dostring (void) {
|
||||||
|
long l;
|
||||||
|
char *s = luaL_check_lstr(1, &l);
|
||||||
|
if (*s == ID_CHUNK)
|
||||||
|
lua_error("`dostring' cannot run pre-compiled code");
|
||||||
|
if (lua_dobuffer(s, l, luaL_opt_string(2, s)) == 0)
|
||||||
|
if (luaA_passresults() == 0)
|
||||||
|
lua_pushuserdata(NULL); /* at least one result to signal no errors */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void luaB_dofile (void) {
|
||||||
|
char *fname = luaL_opt_string(1, NULL);
|
||||||
|
if (lua_dofile(fname) == 0)
|
||||||
|
if (luaA_passresults() == 0)
|
||||||
|
lua_pushuserdata(NULL); /* at least one result to signal no errors */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void luaB_call (void) {
|
||||||
lua_Object f = luaL_nonnullarg(1);
|
lua_Object f = luaL_nonnullarg(1);
|
||||||
lua_Object arg = luaL_tablearg(2);
|
Hash *arg = gethash(2);
|
||||||
char *options = luaL_opt_string(3, "");
|
char *options = luaL_opt_string(3, "");
|
||||||
lua_Object err = lua_getparam(4);
|
lua_Object err = lua_getparam(4);
|
||||||
int narg = getnarg(arg);
|
int narg = (int)getnarg(arg);
|
||||||
int i, status;
|
int i, status;
|
||||||
if (err != LUA_NOOBJECT) { /* set new error method */
|
if (err != LUA_NOOBJECT) { /* set new error method */
|
||||||
lua_pushobject(err);
|
lua_pushobject(err);
|
||||||
err = lua_seterrormethod();
|
err = lua_seterrormethod();
|
||||||
}
|
}
|
||||||
/* push arg[1...n] */
|
/* push arg[1...n] */
|
||||||
for (i=0; i<narg; i++) {
|
luaD_checkstack(narg);
|
||||||
lua_Object temp;
|
for (i=0; i<narg; i++)
|
||||||
/* temp = arg[i+1] */
|
*(L->stack.top++) = *luaH_getint(arg, i+1);
|
||||||
lua_pushobject(arg); lua_pushnumber(i+1); temp = lua_rawgettable();
|
|
||||||
if (narg == MAX_INT && lua_isnil(temp))
|
|
||||||
break;
|
|
||||||
lua_pushobject(temp);
|
|
||||||
}
|
|
||||||
status = lua_callfunction(f);
|
status = lua_callfunction(f);
|
||||||
if (err != LUA_NOOBJECT) { /* restore old error method */
|
if (err != LUA_NOOBJECT) { /* restore old error method */
|
||||||
lua_pushobject(err);
|
lua_pushobject(err);
|
||||||
@@ -312,7 +292,7 @@ static void luaI_call (void)
|
|||||||
else
|
else
|
||||||
lua_error(NULL);
|
lua_error(NULL);
|
||||||
}
|
}
|
||||||
else { /* no errors */
|
else { /* no errors */
|
||||||
if (strchr(options, 'p'))
|
if (strchr(options, 'p'))
|
||||||
luaA_packresults();
|
luaA_packresults();
|
||||||
else
|
else
|
||||||
@@ -321,91 +301,299 @@ static void luaI_call (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void settag (void)
|
static void luaB_nextvar (void) {
|
||||||
{
|
TObject *o = luaA_Address(luaL_nonnullarg(1));
|
||||||
lua_Object o = luaL_tablearg(1);
|
TaggedString *g;
|
||||||
lua_pushobject(o);
|
if (ttype(o) == LUA_T_NIL)
|
||||||
lua_settag(luaL_check_number(2));
|
g = NULL;
|
||||||
lua_pushobject(o); /* returns first argument */
|
else {
|
||||||
|
luaL_arg_check(ttype(o) == LUA_T_STRING, 1, "variable name expected");
|
||||||
|
g = tsvalue(o);
|
||||||
|
}
|
||||||
|
if (!luaA_nextvar(g))
|
||||||
|
lua_pushnil();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void newtag (void)
|
static void luaB_next (void) {
|
||||||
{
|
Hash *a = gethash(1);
|
||||||
lua_pushnumber(lua_newtag());
|
TObject *k = luaA_Address(luaL_nonnullarg(2));
|
||||||
|
int i = (ttype(k) == LUA_T_NIL) ? 0 : luaH_pos(a, k)+1;
|
||||||
|
if (luaA_next(a, i) == 0)
|
||||||
|
lua_pushnil();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void copytagmethods (void)
|
static void luaB_tostring (void) {
|
||||||
{
|
lua_Object obj = lua_getparam(1);
|
||||||
lua_pushnumber(lua_copytagmethods(luaL_check_number(1),
|
TObject *o = luaA_Address(obj);
|
||||||
luaL_check_number(2)));
|
char buff[64];
|
||||||
|
switch (ttype(o)) {
|
||||||
|
case LUA_T_NUMBER:
|
||||||
|
lua_pushstring(lua_getstring(obj));
|
||||||
|
return;
|
||||||
|
case LUA_T_STRING:
|
||||||
|
lua_pushobject(obj);
|
||||||
|
return;
|
||||||
|
case LUA_T_ARRAY:
|
||||||
|
sprintf(buff, "table: %p", (void *)o->value.a);
|
||||||
|
break;
|
||||||
|
case LUA_T_CLOSURE:
|
||||||
|
sprintf(buff, "function: %p", (void *)o->value.cl);
|
||||||
|
break;
|
||||||
|
case LUA_T_PROTO:
|
||||||
|
sprintf(buff, "function: %p", (void *)o->value.tf);
|
||||||
|
break;
|
||||||
|
case LUA_T_CPROTO:
|
||||||
|
sprintf(buff, "function: %p", (void *)o->value.f);
|
||||||
|
break;
|
||||||
|
case LUA_T_USERDATA:
|
||||||
|
sprintf(buff, "userdata: %p", o->value.ts->u.d.v);
|
||||||
|
break;
|
||||||
|
case LUA_T_NIL:
|
||||||
|
lua_pushstring("nil");
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
LUA_INTERNALERROR("invalid type");
|
||||||
|
}
|
||||||
|
lua_pushstring(buff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void rawgettable (void)
|
static void luaB_type (void) {
|
||||||
{
|
lua_Object o = luaL_nonnullarg(1);
|
||||||
lua_pushobject(luaL_nonnullarg(1));
|
lua_pushstring(luaO_typename(luaA_Address(o)));
|
||||||
lua_pushobject(luaL_nonnullarg(2));
|
lua_pushnumber(lua_tag(o));
|
||||||
lua_pushobject(lua_rawgettable());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* }====================================================== */
|
||||||
|
|
||||||
static void rawsettable (void)
|
|
||||||
{
|
|
||||||
lua_pushobject(luaL_nonnullarg(1));
|
|
||||||
lua_pushobject(luaL_nonnullarg(2));
|
|
||||||
lua_pushobject(luaL_nonnullarg(3));
|
|
||||||
lua_rawsettable();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void settagmethod (void)
|
|
||||||
{
|
|
||||||
lua_Object nf = luaL_nonnullarg(3);
|
|
||||||
lua_pushobject(nf);
|
|
||||||
lua_pushobject(lua_settagmethod((int)luaL_check_number(1),
|
|
||||||
luaL_check_string(2)));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void gettagmethod (void)
|
|
||||||
{
|
|
||||||
lua_pushobject(lua_gettagmethod((int)luaL_check_number(1),
|
|
||||||
luaL_check_string(2)));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void seterrormethod (void)
|
|
||||||
{
|
|
||||||
lua_Object nf = luaL_functionarg(1);
|
|
||||||
lua_pushobject(nf);
|
|
||||||
lua_pushobject(lua_seterrormethod());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void luaI_collectgarbage (void)
|
|
||||||
{
|
|
||||||
lua_pushnumber(lua_collectgarbage(luaL_opt_number(1, 0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
** {======================================================
|
||||||
|
** "Extra" functions
|
||||||
|
** These functions can be written in Lua, so you can
|
||||||
|
** delete them if you need a tiny Lua implementation.
|
||||||
|
** If you delete them, remove their entries in array
|
||||||
|
** "builtin_funcs".
|
||||||
** =======================================================
|
** =======================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void luaB_assert (void) {
|
||||||
|
lua_Object p = lua_getparam(1);
|
||||||
|
if (p == LUA_NOOBJECT || lua_isnil(p))
|
||||||
|
luaL_verror("assertion failed! %.100s", luaL_opt_string(2, ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void luaB_foreachi (void) {
|
||||||
|
Hash *t = gethash(1);
|
||||||
|
TObject *f = luaA_Address(luaL_functionarg(2));
|
||||||
|
int i;
|
||||||
|
int n = (int)getnarg(t);
|
||||||
|
luaD_checkstack(3); /* for f, ref, and val */
|
||||||
|
for (i=1; i<=n; i++) {
|
||||||
|
*(L->stack.top++) = *f;
|
||||||
|
ttype(L->stack.top) = LUA_T_NUMBER; nvalue(L->stack.top++) = i;
|
||||||
|
*(L->stack.top++) = *luaH_getint(t, i);
|
||||||
|
luaD_calln(2, 1);
|
||||||
|
if (ttype(L->stack.top-1) != LUA_T_NIL)
|
||||||
|
return;
|
||||||
|
L->stack.top--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void luaB_foreach (void) {
|
||||||
|
Hash *a = gethash(1);
|
||||||
|
TObject *f = luaA_Address(luaL_functionarg(2));
|
||||||
|
int i;
|
||||||
|
luaD_checkstack(3); /* for f, ref, and val */
|
||||||
|
for (i=0; i<a->nhash; i++) {
|
||||||
|
Node *nd = &(a->node[i]);
|
||||||
|
if (ttype(val(nd)) != LUA_T_NIL) {
|
||||||
|
*(L->stack.top++) = *f;
|
||||||
|
*(L->stack.top++) = *ref(nd);
|
||||||
|
*(L->stack.top++) = *val(nd);
|
||||||
|
luaD_calln(2, 1);
|
||||||
|
if (ttype(L->stack.top-1) != LUA_T_NIL)
|
||||||
|
return;
|
||||||
|
L->stack.top--; /* remove result */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void luaB_foreachvar (void) {
|
||||||
|
TObject *f = luaA_Address(luaL_functionarg(1));
|
||||||
|
GCnode *g;
|
||||||
|
luaD_checkstack(4); /* for extra var name, f, var name, and globalval */
|
||||||
|
for (g = L->rootglobal.next; g; g = g->next) {
|
||||||
|
TaggedString *s = (TaggedString *)g;
|
||||||
|
if (s->u.s.globalval.ttype != LUA_T_NIL) {
|
||||||
|
pushtagstring(s); /* keep (extra) s on stack to avoid GC */
|
||||||
|
*(L->stack.top++) = *f;
|
||||||
|
pushtagstring(s);
|
||||||
|
*(L->stack.top++) = s->u.s.globalval;
|
||||||
|
luaD_calln(2, 1);
|
||||||
|
if (ttype(L->stack.top-1) != LUA_T_NIL) {
|
||||||
|
L->stack.top--;
|
||||||
|
*(L->stack.top-1) = *L->stack.top; /* remove extra s */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
L->stack.top-=2; /* remove result and extra s */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void luaB_getn (void) {
|
||||||
|
lua_pushnumber(getnarg(gethash(1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void luaB_tinsert (void) {
|
||||||
|
Hash *a = gethash(1);
|
||||||
|
lua_Object v = lua_getparam(3);
|
||||||
|
int n = (int)getnarg(a);
|
||||||
|
int pos;
|
||||||
|
if (v != LUA_NOOBJECT)
|
||||||
|
pos = luaL_check_int(2);
|
||||||
|
else { /* called with only 2 arguments */
|
||||||
|
v = luaL_nonnullarg(2);
|
||||||
|
pos = n+1;
|
||||||
|
}
|
||||||
|
luaV_setn(a, n+1); /* increment field "n" */
|
||||||
|
for ( ;n>=pos; n--)
|
||||||
|
luaH_move(a, n, n+1);
|
||||||
|
luaH_setint(a, pos, luaA_Address(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void luaB_tremove (void) {
|
||||||
|
Hash *a = gethash(1);
|
||||||
|
int n = (int)getnarg(a);
|
||||||
|
int pos = luaL_opt_int(2, n);
|
||||||
|
if (n <= 0) return; /* table is "empty" */
|
||||||
|
luaA_pushobject(luaH_getint(a, pos)); /* push result */
|
||||||
|
luaV_setn(a, n-1); /* decrement field "n" */
|
||||||
|
for ( ;pos<n; pos++)
|
||||||
|
luaH_move(a, pos+1, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* {
|
||||||
|
** Quicksort
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void swap (Hash *a, int i, int j) {
|
||||||
|
TObject temp;
|
||||||
|
temp = *luaH_getint(a, i);
|
||||||
|
luaH_move(a, j, i);
|
||||||
|
luaH_setint(a, j, &temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sort_comp (TObject *f, TObject *a, TObject *b) {
|
||||||
|
/* notice: the caller (auxsort) must check stack space */
|
||||||
|
if (f) {
|
||||||
|
*(L->stack.top) = *f;
|
||||||
|
*(L->stack.top+1) = *a;
|
||||||
|
*(L->stack.top+2) = *b;
|
||||||
|
L->stack.top += 3;
|
||||||
|
luaD_calln(2, 1);
|
||||||
|
}
|
||||||
|
else { /* a < b? */
|
||||||
|
*(L->stack.top) = *a;
|
||||||
|
*(L->stack.top+1) = *b;
|
||||||
|
L->stack.top += 2;
|
||||||
|
luaV_comparison(LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT);
|
||||||
|
}
|
||||||
|
return ttype(--(L->stack.top)) != LUA_T_NIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void auxsort (Hash *a, int l, int u, TObject *f) {
|
||||||
|
while (l < u) { /* for tail recursion */
|
||||||
|
TObject *P;
|
||||||
|
int i, j;
|
||||||
|
/* sort elements a[l], a[(l+u)/2] and a[u] */
|
||||||
|
if (sort_comp(f, luaH_getint(a, u), luaH_getint(a, l))) /* a[l]>a[u]? */
|
||||||
|
swap(a, l, u);
|
||||||
|
if (u-l == 1) break; /* only 2 elements */
|
||||||
|
i = (l+u)/2;
|
||||||
|
P = luaH_getint(a, i);
|
||||||
|
if (sort_comp(f, P, luaH_getint(a, l))) /* a[l]>a[i]? */
|
||||||
|
swap(a, l, i);
|
||||||
|
else if (sort_comp(f, luaH_getint(a, u), P)) /* a[i]>a[u]? */
|
||||||
|
swap(a, i, u);
|
||||||
|
if (u-l == 2) break; /* only 3 elements */
|
||||||
|
P = L->stack.top++;
|
||||||
|
*P = *luaH_getint(a, i); /* save pivot on stack (for GC) */
|
||||||
|
swap(a, i, u-1); /* put median element as pivot (a[u-1]) */
|
||||||
|
/* a[l] <= P == a[u-1] <= a[u], only needs to sort from l+1 to u-2 */
|
||||||
|
i = l; j = u-1;
|
||||||
|
for (;;) {
|
||||||
|
/* invariant: a[l..i] <= P <= a[j..u] */
|
||||||
|
while (sort_comp(f, luaH_getint(a, ++i), P)) /* stop when a[i] >= P */
|
||||||
|
if (i>u) lua_error("invalid order function for sorting");
|
||||||
|
while (sort_comp(f, P, luaH_getint(a, --j))) /* stop when a[j] <= P */
|
||||||
|
if (j<l) lua_error("invalid order function for sorting");
|
||||||
|
if (j<i) break;
|
||||||
|
swap(a, i, j);
|
||||||
|
}
|
||||||
|
swap(a, u-1, i); /* swap pivot (a[u-1]) with a[i] */
|
||||||
|
L->stack.top--; /* remove pivot from stack */
|
||||||
|
/* a[l..i-1] <= a[i] == P <= a[i+1..u] */
|
||||||
|
/* adjust so that smaller "half" is in [j..i] and larger one in [l..u] */
|
||||||
|
if (i-l < u-i) {
|
||||||
|
j=l; i=i-1; l=i+2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
j=i+1; i=u; u=j-2;
|
||||||
|
}
|
||||||
|
auxsort(a, j, i, f); /* call recursively the smaller one */
|
||||||
|
} /* repeat the routine for the larger one */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void luaB_sort (void) {
|
||||||
|
lua_Object t = lua_getparam(1);
|
||||||
|
Hash *a = gethash(1);
|
||||||
|
int n = (int)getnarg(a);
|
||||||
|
lua_Object func = lua_getparam(2);
|
||||||
|
TObject *f = luaA_Address(func);
|
||||||
|
luaL_arg_check(!f || lua_isfunction(func), 2, "function expected");
|
||||||
|
luaD_checkstack(4); /* for Pivot, f, a, b (sort_comp) */
|
||||||
|
auxsort(a, 1, n, f);
|
||||||
|
lua_pushobject(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* }}===================================================== */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** ====================================================== */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
/*
|
||||||
|
** {======================================================
|
||||||
** some DEBUG functions
|
** some DEBUG functions
|
||||||
** =======================================================
|
** =======================================================
|
||||||
*/
|
*/
|
||||||
#ifdef DEBUG
|
|
||||||
|
|
||||||
static void mem_query (void)
|
static void mem_query (void) {
|
||||||
{
|
|
||||||
lua_pushnumber(totalmem);
|
lua_pushnumber(totalmem);
|
||||||
lua_pushnumber(numblocks);
|
lua_pushnumber(numblocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void countlist (void)
|
static void query_strings (void) {
|
||||||
{
|
lua_pushnumber(L->string_root[luaL_check_int(1)].nuse);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void countlist (void) {
|
||||||
char *s = luaL_check_string(1);
|
char *s = luaL_check_string(1);
|
||||||
GCnode *l = (s[0]=='t') ? L->roottable.next : (s[0]=='c') ? L->rootcl.next :
|
GCnode *l = (s[0]=='t') ? L->roottable.next : (s[0]=='c') ? L->rootcl.next :
|
||||||
(s[0]=='p') ? L->rootproto.next : L->rootglobal.next;
|
(s[0]=='p') ? L->rootproto.next : L->rootglobal.next;
|
||||||
@@ -418,8 +606,7 @@ static void countlist (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void testC (void)
|
static void testC (void) {
|
||||||
{
|
|
||||||
#define getnum(s) ((*s++) - '0')
|
#define getnum(s) ((*s++) - '0')
|
||||||
#define getname(s) (nome[0] = *s++, nome)
|
#define getname(s) (nome[0] = *s++, nome)
|
||||||
|
|
||||||
@@ -428,7 +615,7 @@ static void testC (void)
|
|||||||
char nome[2];
|
char nome[2];
|
||||||
char *s = luaL_check_string(1);
|
char *s = luaL_check_string(1);
|
||||||
nome[1] = 0;
|
nome[1] = 0;
|
||||||
while (1) {
|
for (;;) {
|
||||||
switch (*s++) {
|
switch (*s++) {
|
||||||
case '0': case '1': case '2': case '3': case '4':
|
case '0': case '1': case '2': case '3': case '4':
|
||||||
case '5': case '6': case '7': case '8': case '9':
|
case '5': case '6': case '7': case '8': case '9':
|
||||||
@@ -454,11 +641,17 @@ static void testC (void)
|
|||||||
case '=': lua_setglobal(getname(s)); break;
|
case '=': lua_setglobal(getname(s)); break;
|
||||||
case 's': lua_pushstring(getname(s)); break;
|
case 's': lua_pushstring(getname(s)); break;
|
||||||
case 'o': lua_pushobject(reg[getnum(s)]); break;
|
case 'o': lua_pushobject(reg[getnum(s)]); break;
|
||||||
case 'f': (lua_call)(getname(s)); break;
|
case 'f': lua_call(getname(s)); break;
|
||||||
case 'i': reg[getnum(s)] = lua_gettable(); break;
|
case 'i': reg[getnum(s)] = lua_gettable(); break;
|
||||||
case 'I': reg[getnum(s)] = lua_rawgettable(); break;
|
case 'I': reg[getnum(s)] = lua_rawgettable(); break;
|
||||||
case 't': lua_settable(); break;
|
case 't': lua_settable(); break;
|
||||||
case 'T': lua_rawsettable(); break;
|
case 'T': lua_rawsettable(); break;
|
||||||
|
case 'N' : lua_pushstring(lua_nextvar(lua_getstring(reg[getnum(s)])));
|
||||||
|
break;
|
||||||
|
case 'n' : { int n=getnum(s);
|
||||||
|
n=lua_next(reg[n], (int)lua_getnumber(reg[getnum(s)]));
|
||||||
|
lua_pushnumber(n); break;
|
||||||
|
}
|
||||||
default: luaL_verror("unknown command in `testC': %c", *(s-1));
|
default: luaL_verror("unknown command in `testC': %c", *(s-1));
|
||||||
}
|
}
|
||||||
if (*s == 0) return;
|
if (*s == 0) return;
|
||||||
@@ -466,13 +659,12 @@ static void testC (void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* }====================================================== */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Internal functions
|
static struct luaL_reg builtin_funcs[] = {
|
||||||
*/
|
|
||||||
static struct luaL_reg int_funcs[] = {
|
|
||||||
#ifdef LUA_COMPAT2_5
|
#ifdef LUA_COMPAT2_5
|
||||||
{"setfallback", luaT_setfallback},
|
{"setfallback", luaT_setfallback},
|
||||||
#endif
|
#endif
|
||||||
@@ -480,46 +672,54 @@ static struct luaL_reg int_funcs[] = {
|
|||||||
{"testC", testC},
|
{"testC", testC},
|
||||||
{"totalmem", mem_query},
|
{"totalmem", mem_query},
|
||||||
{"count", countlist},
|
{"count", countlist},
|
||||||
|
{"querystr", query_strings},
|
||||||
#endif
|
#endif
|
||||||
{"assert", luaI_assert},
|
{"_ALERT", luaB_alert},
|
||||||
{"call", luaI_call},
|
{"_ERRORMESSAGE", error_message},
|
||||||
{"collectgarbage", luaI_collectgarbage},
|
{"call", luaB_call},
|
||||||
{"dofile", internaldofile},
|
{"collectgarbage", luaB_collectgarbage},
|
||||||
{"copytagmethods", copytagmethods},
|
{"copytagmethods", luaB_copytagmethods},
|
||||||
{"dostring", internaldostring},
|
{"dofile", luaB_dofile},
|
||||||
{"error", luaI_error},
|
{"dostring", luaB_dostring},
|
||||||
{"foreach", foreach},
|
{"error", luaB_error},
|
||||||
{"foreachvar", foreachvar},
|
{"getglobal", luaB_getglobal},
|
||||||
{"getglobal", getglobal},
|
{"gettagmethod", luaB_gettagmethod},
|
||||||
{"newtag", newtag},
|
{"newtag", luaB_newtag},
|
||||||
{"next", next},
|
{"next", luaB_next},
|
||||||
{"nextvar", nextvar},
|
{"nextvar", luaB_nextvar},
|
||||||
{"print", luaI_print},
|
{"print", luaB_print},
|
||||||
{"rawgetglobal", rawgetglobal},
|
{"rawgetglobal", luaB_rawgetglobal},
|
||||||
{"rawgettable", rawgettable},
|
{"rawgettable", luaB_rawgettable},
|
||||||
{"rawsetglobal", rawsetglobal},
|
{"rawsetglobal", luaB_rawsetglobal},
|
||||||
{"rawsettable", rawsettable},
|
{"rawsettable", luaB_rawsettable},
|
||||||
{"seterrormethod", seterrormethod},
|
{"seterrormethod", luaB_seterrormethod},
|
||||||
{"setglobal", setglobal},
|
{"setglobal", luaB_setglobal},
|
||||||
{"settagmethod", settagmethod},
|
{"settag", luaB_settag},
|
||||||
{"gettagmethod", gettagmethod},
|
{"settagmethod", luaB_settagmethod},
|
||||||
{"settag", settag},
|
{"tag", luaB_luatag},
|
||||||
{"tonumber", tonumber},
|
{"tonumber", luaB_tonumber},
|
||||||
{"tostring", to_string},
|
{"tostring", luaB_tostring},
|
||||||
{"tag", luatag},
|
{"type", luaB_type},
|
||||||
{"type", luaI_type}
|
/* "Extra" functions */
|
||||||
|
{"assert", luaB_assert},
|
||||||
|
{"foreach", luaB_foreach},
|
||||||
|
{"foreachi", luaB_foreachi},
|
||||||
|
{"foreachvar", luaB_foreachvar},
|
||||||
|
{"getn", luaB_getn},
|
||||||
|
{"sort", luaB_sort},
|
||||||
|
{"tinsert", luaB_tinsert},
|
||||||
|
{"tremove", luaB_tremove}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#define INTFUNCSIZE (sizeof(int_funcs)/sizeof(int_funcs[0]))
|
#define INTFUNCSIZE (sizeof(builtin_funcs)/sizeof(builtin_funcs[0]))
|
||||||
|
|
||||||
|
|
||||||
void luaB_predefine (void)
|
void luaB_predefine (void) {
|
||||||
{
|
|
||||||
/* pre-register mem error messages, to avoid loop when error arises */
|
/* pre-register mem error messages, to avoid loop when error arises */
|
||||||
luaS_newfixedstring(tableEM);
|
luaS_newfixedstring(tableEM);
|
||||||
luaS_newfixedstring(memEM);
|
luaS_newfixedstring(memEM);
|
||||||
luaL_openlib(int_funcs, (sizeof(int_funcs)/sizeof(int_funcs[0])));
|
luaL_openlib(builtin_funcs, (sizeof(builtin_funcs)/sizeof(builtin_funcs[0])));
|
||||||
lua_pushstring(LUA_VERSION);
|
lua_pushstring(LUA_VERSION);
|
||||||
lua_setglobal("_VERSION");
|
lua_setglobal("_VERSION");
|
||||||
}
|
}
|
||||||
|
|||||||
217
ldblib.c
Normal file
217
ldblib.c
Normal file
@@ -0,0 +1,217 @@
|
|||||||
|
/*
|
||||||
|
** $Id: ldblib.c,v 1.4 1999/02/04 17:47:59 roberto Exp roberto $
|
||||||
|
** Interface from Lua to its debug API
|
||||||
|
** See Copyright Notice in lua.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "lauxlib.h"
|
||||||
|
#include "lua.h"
|
||||||
|
#include "luadebug.h"
|
||||||
|
#include "lualib.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void settabss (lua_Object t, char *i, char *v) {
|
||||||
|
lua_pushobject(t);
|
||||||
|
lua_pushstring(i);
|
||||||
|
lua_pushstring(v);
|
||||||
|
lua_settable();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void settabsi (lua_Object t, char *i, int v) {
|
||||||
|
lua_pushobject(t);
|
||||||
|
lua_pushstring(i);
|
||||||
|
lua_pushnumber(v);
|
||||||
|
lua_settable();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static lua_Object getfuncinfo (lua_Object func) {
|
||||||
|
lua_Object result = lua_createtable();
|
||||||
|
char *str;
|
||||||
|
int line;
|
||||||
|
lua_funcinfo(func, &str, &line);
|
||||||
|
if (line == -1) /* C function? */
|
||||||
|
settabss(result, "kind", "C");
|
||||||
|
else if (line == 0) { /* "main"? */
|
||||||
|
settabss(result, "kind", "chunk");
|
||||||
|
settabss(result, "source", str);
|
||||||
|
}
|
||||||
|
else { /* Lua function */
|
||||||
|
settabss(result, "kind", "Lua");
|
||||||
|
settabsi(result, "def_line", line);
|
||||||
|
settabss(result, "source", str);
|
||||||
|
}
|
||||||
|
if (line != 0) { /* is it not a "main"? */
|
||||||
|
char *kind = lua_getobjname(func, &str);
|
||||||
|
if (*kind) {
|
||||||
|
settabss(result, "name", str);
|
||||||
|
settabss(result, "where", kind);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void getstack (void) {
|
||||||
|
lua_Object func = lua_stackedfunction(luaL_check_int(1));
|
||||||
|
if (func == LUA_NOOBJECT) /* level out of range? */
|
||||||
|
return;
|
||||||
|
else {
|
||||||
|
lua_Object result = getfuncinfo(func);
|
||||||
|
int currline = lua_currentline(func);
|
||||||
|
if (currline > 0)
|
||||||
|
settabsi(result, "current", currline);
|
||||||
|
lua_pushobject(result);
|
||||||
|
lua_pushstring("func");
|
||||||
|
lua_pushobject(func);
|
||||||
|
lua_settable(); /* result.func = func */
|
||||||
|
lua_pushobject(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void funcinfo (void) {
|
||||||
|
lua_pushobject(getfuncinfo(luaL_functionarg(1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int findlocal (lua_Object func, int arg) {
|
||||||
|
lua_Object v = lua_getparam(arg);
|
||||||
|
if (lua_isnumber(v))
|
||||||
|
return (int)lua_getnumber(v);
|
||||||
|
else {
|
||||||
|
char *name = luaL_check_string(arg);
|
||||||
|
int i = 0;
|
||||||
|
int result = -1;
|
||||||
|
char *vname;
|
||||||
|
while (lua_getlocal(func, ++i, &vname) != LUA_NOOBJECT) {
|
||||||
|
if (strcmp(name, vname) == 0)
|
||||||
|
result = i; /* keep looping to get the last var with this name */
|
||||||
|
}
|
||||||
|
if (result == -1)
|
||||||
|
luaL_verror("no local variable `%.50s' at given level", name);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void getlocal (void) {
|
||||||
|
lua_Object func = lua_stackedfunction(luaL_check_int(1));
|
||||||
|
lua_Object val;
|
||||||
|
char *name;
|
||||||
|
if (func == LUA_NOOBJECT) /* level out of range? */
|
||||||
|
return; /* return nil */
|
||||||
|
else if (lua_getparam(2) != LUA_NOOBJECT) { /* 2nd argument? */
|
||||||
|
if ((val = lua_getlocal(func, findlocal(func, 2), &name)) != LUA_NOOBJECT) {
|
||||||
|
lua_pushobject(val);
|
||||||
|
lua_pushstring(name);
|
||||||
|
}
|
||||||
|
/* else return nil */
|
||||||
|
}
|
||||||
|
else { /* collect all locals in a table */
|
||||||
|
lua_Object result = lua_createtable();
|
||||||
|
int i;
|
||||||
|
for (i=1; ;i++) {
|
||||||
|
if ((val = lua_getlocal(func, i, &name)) == LUA_NOOBJECT)
|
||||||
|
break;
|
||||||
|
lua_pushobject(result);
|
||||||
|
lua_pushstring(name);
|
||||||
|
lua_pushobject(val);
|
||||||
|
lua_settable(); /* result[name] = value */
|
||||||
|
}
|
||||||
|
lua_pushobject(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void setlocal (void) {
|
||||||
|
lua_Object func = lua_stackedfunction(luaL_check_int(1));
|
||||||
|
int numvar;
|
||||||
|
luaL_arg_check(func != LUA_NOOBJECT, 1, "level out of range");
|
||||||
|
numvar = findlocal(func, 2);
|
||||||
|
lua_pushobject(luaL_nonnullarg(3));
|
||||||
|
if (!lua_setlocal(func, numvar))
|
||||||
|
lua_error("no such local variable");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int linehook = -1; /* Lua reference to line hook function */
|
||||||
|
static int callhook = -1; /* Lua reference to call hook function */
|
||||||
|
|
||||||
|
|
||||||
|
static void dohook (int ref) {
|
||||||
|
lua_LHFunction oldlinehook = lua_setlinehook(NULL);
|
||||||
|
lua_CHFunction oldcallhook = lua_setcallhook(NULL);
|
||||||
|
lua_callfunction(lua_getref(ref));
|
||||||
|
lua_setlinehook(oldlinehook);
|
||||||
|
lua_setcallhook(oldcallhook);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void linef (int line) {
|
||||||
|
lua_pushnumber(line);
|
||||||
|
dohook(linehook);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void callf (lua_Function func, char *file, int line) {
|
||||||
|
if (func != LUA_NOOBJECT) {
|
||||||
|
lua_pushobject(func);
|
||||||
|
lua_pushstring(file);
|
||||||
|
lua_pushnumber(line);
|
||||||
|
}
|
||||||
|
dohook(callhook);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void setcallhook (void) {
|
||||||
|
lua_Object f = lua_getparam(1);
|
||||||
|
lua_unref(callhook);
|
||||||
|
if (f == LUA_NOOBJECT) {
|
||||||
|
callhook = -1;
|
||||||
|
lua_setcallhook(NULL);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lua_pushobject(f);
|
||||||
|
callhook = lua_ref(1);
|
||||||
|
lua_setcallhook(callf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void setlinehook (void) {
|
||||||
|
lua_Object f = lua_getparam(1);
|
||||||
|
lua_unref(linehook);
|
||||||
|
if (f == LUA_NOOBJECT) {
|
||||||
|
linehook = -1;
|
||||||
|
lua_setlinehook(NULL);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lua_pushobject(f);
|
||||||
|
linehook = lua_ref(1);
|
||||||
|
lua_setlinehook(linef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct luaL_reg dblib[] = {
|
||||||
|
{"funcinfo", funcinfo},
|
||||||
|
{"getlocal", getlocal},
|
||||||
|
{"getstack", getstack},
|
||||||
|
{"setcallhook", setcallhook},
|
||||||
|
{"setlinehook", setlinehook},
|
||||||
|
{"setlocal", setlocal}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void lua_dblibopen (void) {
|
||||||
|
luaL_openlib(dblib, (sizeof(dblib)/sizeof(dblib[0])));
|
||||||
|
}
|
||||||
|
|
||||||
138
ldo.c
138
ldo.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ldo.c,v 1.26 1998/06/15 21:34:14 roberto Exp roberto $
|
** $Id: ldo.c,v 1.40 1999/03/10 14:23:07 roberto Exp roberto $
|
||||||
** Stack and Call structure of Lua
|
** Stack and Call structure of Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "lauxlib.h"
|
||||||
#include "ldo.h"
|
#include "ldo.h"
|
||||||
#include "lfunc.h"
|
#include "lfunc.h"
|
||||||
#include "lgc.h"
|
#include "lgc.h"
|
||||||
@@ -17,6 +18,7 @@
|
|||||||
#include "lobject.h"
|
#include "lobject.h"
|
||||||
#include "lparser.h"
|
#include "lparser.h"
|
||||||
#include "lstate.h"
|
#include "lstate.h"
|
||||||
|
#include "lstring.h"
|
||||||
#include "ltm.h"
|
#include "ltm.h"
|
||||||
#include "lua.h"
|
#include "lua.h"
|
||||||
#include "luadebug.h"
|
#include "luadebug.h"
|
||||||
@@ -32,37 +34,22 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Error messages
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void stderrorim (void)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "lua error: %s\n", lua_getstring(lua_getparam(1)));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define STACK_UNIT 128
|
#define STACK_UNIT 128
|
||||||
|
|
||||||
|
|
||||||
void luaD_init (void)
|
void luaD_init (void) {
|
||||||
{
|
|
||||||
L->stack.stack = luaM_newvector(STACK_UNIT, TObject);
|
L->stack.stack = luaM_newvector(STACK_UNIT, TObject);
|
||||||
L->stack.top = L->stack.stack;
|
L->stack.top = L->stack.stack;
|
||||||
L->stack.last = L->stack.stack+(STACK_UNIT-1);
|
L->stack.last = L->stack.stack+(STACK_UNIT-1);
|
||||||
ttype(&L->errorim) = LUA_T_CPROTO;
|
|
||||||
fvalue(&L->errorim) = stderrorim;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void luaD_checkstack (int n)
|
void luaD_checkstack (int n) {
|
||||||
{
|
|
||||||
struct Stack *S = &L->stack;
|
struct Stack *S = &L->stack;
|
||||||
if (S->last-S->top <= n) {
|
if (S->last-S->top <= n) {
|
||||||
StkId top = S->top-S->stack;
|
StkId top = S->top-S->stack;
|
||||||
int stacksize = (S->last-S->stack)+1+STACK_UNIT+n;
|
int stacksize = (S->last-S->stack)+STACK_UNIT+n;
|
||||||
S->stack = luaM_reallocvector(S->stack, stacksize, TObject);
|
luaM_reallocvector(S->stack, stacksize, TObject);
|
||||||
S->last = S->stack+(stacksize-1);
|
S->last = S->stack+(stacksize-1);
|
||||||
S->top = S->stack + top;
|
S->top = S->stack + top;
|
||||||
if (stacksize >= STACK_LIMIT) { /* stack overflow? */
|
if (stacksize >= STACK_LIMIT) { /* stack overflow? */
|
||||||
@@ -78,8 +65,7 @@ void luaD_checkstack (int n)
|
|||||||
/*
|
/*
|
||||||
** Adjust stack. Set top to the given value, pushing NILs if needed.
|
** Adjust stack. Set top to the given value, pushing NILs if needed.
|
||||||
*/
|
*/
|
||||||
void luaD_adjusttop (StkId newtop)
|
void luaD_adjusttop (StkId newtop) {
|
||||||
{
|
|
||||||
int diff = newtop-(L->stack.top-L->stack.stack);
|
int diff = newtop-(L->stack.top-L->stack.stack);
|
||||||
if (diff <= 0)
|
if (diff <= 0)
|
||||||
L->stack.top += diff;
|
L->stack.top += diff;
|
||||||
@@ -107,7 +93,7 @@ void luaD_lineHook (int line)
|
|||||||
struct C_Lua_Stack oldCLS = L->Cstack;
|
struct C_Lua_Stack oldCLS = L->Cstack;
|
||||||
StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->stack.top-L->stack.stack;
|
StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->stack.top-L->stack.stack;
|
||||||
L->Cstack.num = 0;
|
L->Cstack.num = 0;
|
||||||
(*lua_linehook)(line);
|
(*L->linehook)(line);
|
||||||
L->stack.top = L->stack.stack+old_top;
|
L->stack.top = L->stack.stack+old_top;
|
||||||
L->Cstack = oldCLS;
|
L->Cstack = oldCLS;
|
||||||
}
|
}
|
||||||
@@ -119,13 +105,13 @@ void luaD_callHook (StkId base, TProtoFunc *tf, int isreturn)
|
|||||||
StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->stack.top-L->stack.stack;
|
StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->stack.top-L->stack.stack;
|
||||||
L->Cstack.num = 0;
|
L->Cstack.num = 0;
|
||||||
if (isreturn)
|
if (isreturn)
|
||||||
(*lua_callhook)(LUA_NOOBJECT, "(return)", 0);
|
(*L->callhook)(LUA_NOOBJECT, "(return)", 0);
|
||||||
else {
|
else {
|
||||||
TObject *f = L->stack.stack+base-1;
|
TObject *f = L->stack.stack+base-1;
|
||||||
if (tf)
|
if (tf)
|
||||||
(*lua_callhook)(Ref(f), tf->fileName->str, tf->lineDefined);
|
(*L->callhook)(Ref(f), tf->source->str, tf->lineDefined);
|
||||||
else
|
else
|
||||||
(*lua_callhook)(Ref(f), "(C)", -1);
|
(*L->callhook)(Ref(f), "(C)", -1);
|
||||||
}
|
}
|
||||||
L->stack.top = L->stack.stack+old_top;
|
L->stack.top = L->stack.stack+old_top;
|
||||||
L->Cstack = oldCLS;
|
L->Cstack = oldCLS;
|
||||||
@@ -146,10 +132,10 @@ static StkId callC (lua_CFunction f, StkId base)
|
|||||||
CS->num = numarg;
|
CS->num = numarg;
|
||||||
CS->lua2C = base;
|
CS->lua2C = base;
|
||||||
CS->base = base+numarg; /* == top-stack */
|
CS->base = base+numarg; /* == top-stack */
|
||||||
if (lua_callhook)
|
if (L->callhook)
|
||||||
luaD_callHook(base, NULL, 0);
|
luaD_callHook(base, NULL, 0);
|
||||||
(*f)(); /* do the actual call */
|
(*f)(); /* do the actual call */
|
||||||
if (lua_callhook) /* func may have changed lua_callhook */
|
if (L->callhook) /* func may have changed callhook */
|
||||||
luaD_callHook(base, NULL, 1);
|
luaD_callHook(base, NULL, 1);
|
||||||
firstResult = CS->base;
|
firstResult = CS->base;
|
||||||
*CS = oldCLS;
|
*CS = oldCLS;
|
||||||
@@ -172,11 +158,10 @@ static StkId callCclosure (struct Closure *cl, lua_CFunction f, StkId base)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void luaD_callTM (TObject *f, int nParams, int nResults)
|
void luaD_callTM (TObject *f, int nParams, int nResults) {
|
||||||
{
|
|
||||||
luaD_openstack(nParams);
|
luaD_openstack(nParams);
|
||||||
*(L->stack.top-nParams-1) = *f;
|
*(L->stack.top-nParams-1) = *f;
|
||||||
luaD_call((L->stack.top-L->stack.stack)-nParams, nResults);
|
luaD_calln(nParams, nResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -230,6 +215,10 @@ void luaD_call (StkId base, int nResults)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void luaD_calln (int nArgs, int nResults) {
|
||||||
|
luaD_call((L->stack.top-L->stack.stack)-nArgs, nResults);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Traverse all objects on L->stack.stack
|
** Traverse all objects on L->stack.stack
|
||||||
@@ -243,25 +232,26 @@ void luaD_travstack (int (*fn)(TObject *))
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void message (char *s)
|
static void message (char *s) {
|
||||||
{
|
TObject *em = &(luaS_new("_ERRORMESSAGE")->u.s.globalval);
|
||||||
TObject im = L->errorim;
|
if (ttype(em) == LUA_T_PROTO || ttype(em) == LUA_T_CPROTO ||
|
||||||
if (ttype(&im) != LUA_T_NIL) {
|
ttype(em) == LUA_T_CLOSURE) {
|
||||||
|
*L->stack.top = *em;
|
||||||
|
incr_top;
|
||||||
lua_pushstring(s);
|
lua_pushstring(s);
|
||||||
luaD_callTM(&im, 1, 0);
|
luaD_calln(1, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Reports an error, and jumps up to the available recover label
|
** Reports an error, and jumps up to the available recover label
|
||||||
*/
|
*/
|
||||||
void lua_error (char *s)
|
void lua_error (char *s) {
|
||||||
{
|
|
||||||
if (s) message(s);
|
if (s) message(s);
|
||||||
if (L->errorJmp)
|
if (L->errorJmp)
|
||||||
longjmp(*((jmp_buf *)L->errorJmp), 1);
|
longjmp(*((jmp_buf *)L->errorJmp), 1);
|
||||||
else {
|
else {
|
||||||
fprintf (stderr, "lua: exit(1). Unable to recover\n");
|
message("exit(1). Unable to recover.\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -274,9 +264,9 @@ static void do_callinc (int nResults)
|
|||||||
{
|
{
|
||||||
StkId base = L->Cstack.base;
|
StkId base = L->Cstack.base;
|
||||||
luaD_call(base+1, nResults);
|
luaD_call(base+1, nResults);
|
||||||
L->Cstack.lua2C = base; /* position of the luaM_new results */
|
L->Cstack.lua2C = base; /* position of the new results */
|
||||||
L->Cstack.num = (L->stack.top-L->stack.stack) - base; /* number of results */
|
L->Cstack.num = (L->stack.top-L->stack.stack) - base; /* number of results */
|
||||||
L->Cstack.base = base + L->Cstack.num; /* incorporate results on L->stack.stack */
|
L->Cstack.base = base + L->Cstack.num; /* incorporate results on stack */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -284,18 +274,17 @@ static void do_callinc (int nResults)
|
|||||||
** Execute a protected call. Assumes that function is at L->Cstack.base and
|
** Execute a protected call. Assumes that function is at L->Cstack.base and
|
||||||
** parameters are on top of it. Leave nResults on the stack.
|
** parameters are on top of it. Leave nResults on the stack.
|
||||||
*/
|
*/
|
||||||
int luaD_protectedrun (int nResults)
|
int luaD_protectedrun (int nResults) {
|
||||||
{
|
|
||||||
jmp_buf myErrorJmp;
|
|
||||||
int status;
|
|
||||||
volatile struct C_Lua_Stack oldCLS = L->Cstack;
|
volatile struct C_Lua_Stack oldCLS = L->Cstack;
|
||||||
|
jmp_buf myErrorJmp;
|
||||||
|
volatile int status;
|
||||||
jmp_buf *volatile oldErr = L->errorJmp;
|
jmp_buf *volatile oldErr = L->errorJmp;
|
||||||
L->errorJmp = &myErrorJmp;
|
L->errorJmp = &myErrorJmp;
|
||||||
if (setjmp(myErrorJmp) == 0) {
|
if (setjmp(myErrorJmp) == 0) {
|
||||||
do_callinc(nResults);
|
do_callinc(nResults);
|
||||||
status = 0;
|
status = 0;
|
||||||
}
|
}
|
||||||
else { /* an error occurred: restore L->Cstack and L->stack.top */
|
else { /* an error occurred: restore L->Cstack and L->stack.top */
|
||||||
L->Cstack = oldCLS;
|
L->Cstack = oldCLS;
|
||||||
L->stack.top = L->stack.stack+L->Cstack.base;
|
L->stack.top = L->stack.stack+L->Cstack.base;
|
||||||
status = 1;
|
status = 1;
|
||||||
@@ -308,18 +297,20 @@ int luaD_protectedrun (int nResults)
|
|||||||
/*
|
/*
|
||||||
** returns 0 = chunk loaded; 1 = error; 2 = no more chunks to load
|
** returns 0 = chunk loaded; 1 = error; 2 = no more chunks to load
|
||||||
*/
|
*/
|
||||||
static int protectedparser (ZIO *z, int bin)
|
static int protectedparser (ZIO *z, int bin) {
|
||||||
{
|
volatile struct C_Lua_Stack oldCLS = L->Cstack;
|
||||||
|
jmp_buf myErrorJmp;
|
||||||
volatile int status;
|
volatile int status;
|
||||||
TProtoFunc *volatile tf;
|
TProtoFunc *volatile tf;
|
||||||
jmp_buf myErrorJmp;
|
|
||||||
jmp_buf *volatile oldErr = L->errorJmp;
|
jmp_buf *volatile oldErr = L->errorJmp;
|
||||||
L->errorJmp = &myErrorJmp;
|
L->errorJmp = &myErrorJmp;
|
||||||
if (setjmp(myErrorJmp) == 0) {
|
if (setjmp(myErrorJmp) == 0) {
|
||||||
tf = bin ? luaU_undump1(z) : luaY_parser(z);
|
tf = bin ? luaU_undump1(z) : luaY_parser(z);
|
||||||
status = 0;
|
status = 0;
|
||||||
}
|
}
|
||||||
else {
|
else { /* an error occurred: restore L->Cstack and L->stack.top */
|
||||||
|
L->Cstack = oldCLS;
|
||||||
|
L->stack.top = L->stack.stack+L->Cstack.base;
|
||||||
tf = NULL;
|
tf = NULL;
|
||||||
status = 1;
|
status = 1;
|
||||||
}
|
}
|
||||||
@@ -334,9 +325,9 @@ static int protectedparser (ZIO *z, int bin)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int do_main (ZIO *z, int bin)
|
static int do_main (ZIO *z, int bin) {
|
||||||
{
|
|
||||||
int status;
|
int status;
|
||||||
|
int debug = L->debug; /* save debug status */
|
||||||
do {
|
do {
|
||||||
long old_blocks = (luaC_checkGC(), L->nblocks);
|
long old_blocks = (luaC_checkGC(), L->nblocks);
|
||||||
status = protectedparser(z, bin);
|
status = protectedparser(z, bin);
|
||||||
@@ -349,6 +340,7 @@ static int do_main (ZIO *z, int bin)
|
|||||||
L->GCthreshold -= newelems2;
|
L->GCthreshold -= newelems2;
|
||||||
}
|
}
|
||||||
} while (bin && status == 0);
|
} while (bin && status == 0);
|
||||||
|
L->debug = debug; /* restore debug status */
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -364,23 +356,24 @@ void luaD_gcIM (TObject *o)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int lua_dofile (char *filename)
|
#define MAXFILENAME 260 /* maximum part of a file name kept */
|
||||||
{
|
|
||||||
|
int lua_dofile (char *filename) {
|
||||||
ZIO z;
|
ZIO z;
|
||||||
int status;
|
int status;
|
||||||
int c;
|
int c;
|
||||||
int bin;
|
int bin;
|
||||||
|
char source[MAXFILENAME];
|
||||||
FILE *f = (filename == NULL) ? stdin : fopen(filename, "r");
|
FILE *f = (filename == NULL) ? stdin : fopen(filename, "r");
|
||||||
if (f == NULL)
|
if (f == NULL)
|
||||||
return 2;
|
return 2;
|
||||||
if (filename == NULL)
|
|
||||||
filename = "(stdin)";
|
|
||||||
c = fgetc(f);
|
c = fgetc(f);
|
||||||
ungetc(c, f);
|
ungetc(c, f);
|
||||||
bin = (c == ID_CHUNK);
|
bin = (c == ID_CHUNK);
|
||||||
if (bin)
|
if (bin)
|
||||||
f = freopen(filename, "rb", f); /* set binary mode */
|
f = freopen(filename, "rb", f); /* set binary mode */
|
||||||
luaZ_Fopen(&z, f, filename);
|
luaL_filesource(source, filename, sizeof(source));
|
||||||
|
luaZ_Fopen(&z, f, source);
|
||||||
status = do_main(&z, bin);
|
status = do_main(&z, bin);
|
||||||
if (f != stdin)
|
if (f != stdin)
|
||||||
fclose(f);
|
fclose(f);
|
||||||
@@ -388,40 +381,15 @@ int lua_dofile (char *filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define SIZE_PREF 20 /* size of string prefix to appear in error messages */
|
|
||||||
#define SSIZE_PREF "20"
|
|
||||||
|
|
||||||
|
|
||||||
static void build_name (char *str, char *name) {
|
|
||||||
if (str == NULL || *str == ID_CHUNK)
|
|
||||||
strcpy(name, "(buffer)");
|
|
||||||
else {
|
|
||||||
char *temp;
|
|
||||||
sprintf(name, "(dostring) >> \"%." SSIZE_PREF "s\"", str);
|
|
||||||
temp = strchr(name, '\n');
|
|
||||||
if (temp) { /* end string after first line */
|
|
||||||
*temp = '"';
|
|
||||||
*(temp+1) = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int lua_dostring (char *str) {
|
int lua_dostring (char *str) {
|
||||||
return lua_dobuffer(str, strlen(str), NULL);
|
return lua_dobuffer(str, strlen(str), str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int lua_dobuffer (char *buff, int size, char *name) {
|
int lua_dobuffer (char *buff, int size, char *name) {
|
||||||
char newname[SIZE_PREF+25];
|
|
||||||
ZIO z;
|
ZIO z;
|
||||||
int status;
|
if (!name) name = "?";
|
||||||
if (name==NULL) {
|
|
||||||
build_name(buff, newname);
|
|
||||||
name = newname;
|
|
||||||
}
|
|
||||||
luaZ_mopen(&z, buff, size, name);
|
luaZ_mopen(&z, buff, size, name);
|
||||||
status = do_main(&z, buff[0]==ID_CHUNK);
|
return do_main(&z, buff[0]==ID_CHUNK);
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
3
ldo.h
3
ldo.h
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ldo.h,v 1.3 1997/11/19 17:29:23 roberto Exp roberto $
|
** $Id: ldo.h,v 1.4 1997/12/15 16:17:20 roberto Exp roberto $
|
||||||
** Stack and Call structure of Lua
|
** Stack and Call structure of Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -36,6 +36,7 @@ void luaD_openstack (int nelems);
|
|||||||
void luaD_lineHook (int line);
|
void luaD_lineHook (int line);
|
||||||
void luaD_callHook (StkId base, TProtoFunc *tf, int isreturn);
|
void luaD_callHook (StkId base, TProtoFunc *tf, int isreturn);
|
||||||
void luaD_call (StkId base, int nResults);
|
void luaD_call (StkId base, int nResults);
|
||||||
|
void luaD_calln (int nArgs, int nResults);
|
||||||
void luaD_callTM (TObject *f, int nParams, int nResults);
|
void luaD_callTM (TObject *f, int nParams, int nResults);
|
||||||
int luaD_protectedrun (int nResults);
|
int luaD_protectedrun (int nResults);
|
||||||
void luaD_gcIM (TObject *o);
|
void luaD_gcIM (TObject *o);
|
||||||
|
|||||||
4
lfunc.c
4
lfunc.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lfunc.c,v 1.8 1997/12/15 16:17:20 roberto Exp roberto $
|
** $Id: lfunc.c,v 1.9 1998/06/19 16:14:09 roberto Exp roberto $
|
||||||
** Auxiliary functions to manipulate prototypes and closures
|
** Auxiliary functions to manipulate prototypes and closures
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -31,7 +31,7 @@ TProtoFunc *luaF_newproto (void)
|
|||||||
TProtoFunc *f = luaM_new(TProtoFunc);
|
TProtoFunc *f = luaM_new(TProtoFunc);
|
||||||
f->code = NULL;
|
f->code = NULL;
|
||||||
f->lineDefined = 0;
|
f->lineDefined = 0;
|
||||||
f->fileName = NULL;
|
f->source = NULL;
|
||||||
f->consts = NULL;
|
f->consts = NULL;
|
||||||
f->nconsts = 0;
|
f->nconsts = 0;
|
||||||
f->locvars = NULL;
|
f->locvars = NULL;
|
||||||
|
|||||||
31
lgc.c
31
lgc.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lgc.c,v 1.17 1998/03/06 16:54:42 roberto Exp roberto $
|
** $Id: lgc.c,v 1.22 1999/02/26 15:48:55 roberto Exp roberto $
|
||||||
** Garbage Collector
|
** Garbage Collector
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -29,23 +29,18 @@ static int markobject (TObject *o);
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
int luaC_ref (TObject *o, int lock)
|
int luaC_ref (TObject *o, int lock) {
|
||||||
{
|
|
||||||
int ref;
|
int ref;
|
||||||
if (ttype(o) == LUA_T_NIL)
|
if (ttype(o) == LUA_T_NIL)
|
||||||
ref = -1; /* special ref for nil */
|
ref = -1; /* special ref for nil */
|
||||||
else {
|
else {
|
||||||
for (ref=0; ref<L->refSize; ref++)
|
for (ref=0; ref<L->refSize; ref++)
|
||||||
if (L->refArray[ref].status == FREE)
|
if (L->refArray[ref].status == FREE)
|
||||||
goto found;
|
break;
|
||||||
/* no more empty spaces */ {
|
if (ref == L->refSize) { /* no more empty spaces? */
|
||||||
int oldSize = L->refSize;
|
luaM_growvector(L->refArray, L->refSize, 1, struct ref, refEM, MAX_INT);
|
||||||
L->refSize = luaM_growvector(&L->refArray, L->refSize, struct ref,
|
L->refSize++;
|
||||||
refEM, MAX_INT);
|
}
|
||||||
for (ref=oldSize; ref<L->refSize; ref++)
|
|
||||||
L->refArray[ref].status = FREE;
|
|
||||||
ref = oldSize;
|
|
||||||
} found:
|
|
||||||
L->refArray[ref].o = *o;
|
L->refArray[ref].o = *o;
|
||||||
L->refArray[ref].status = lock ? LOCK : HOLD;
|
L->refArray[ref].status = lock ? LOCK : HOLD;
|
||||||
}
|
}
|
||||||
@@ -163,21 +158,13 @@ static void strmark (TaggedString *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void protomark (TProtoFunc *f)
|
static void protomark (TProtoFunc *f) {
|
||||||
{
|
|
||||||
if (!f->head.marked) {
|
if (!f->head.marked) {
|
||||||
LocVar *v = f->locvars;
|
|
||||||
int i;
|
int i;
|
||||||
f->head.marked = 1;
|
f->head.marked = 1;
|
||||||
if (f->fileName)
|
strmark(f->source);
|
||||||
strmark(f->fileName);
|
|
||||||
for (i=0; i<f->nconsts; i++)
|
for (i=0; i<f->nconsts; i++)
|
||||||
markobject(&f->consts[i]);
|
markobject(&f->consts[i]);
|
||||||
if (v) {
|
|
||||||
for (; v->line != -1; v++)
|
|
||||||
if (v->varname)
|
|
||||||
strmark(v->varname);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
17
linit.c
Normal file
17
linit.c
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
** $Id: linit.c,v 1.1 1999/01/08 16:47:44 roberto Exp $
|
||||||
|
** Initialization of libraries for lua.c
|
||||||
|
** See Copyright Notice in lua.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lua.h"
|
||||||
|
#include "lualib.h"
|
||||||
|
|
||||||
|
|
||||||
|
void lua_userinit (void) {
|
||||||
|
lua_iolibopen();
|
||||||
|
lua_strlibopen();
|
||||||
|
lua_mathlibopen();
|
||||||
|
lua_dblibopen();
|
||||||
|
}
|
||||||
|
|
||||||
538
liolib.c
538
liolib.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: liolib.c,v 1.20 1998/06/05 22:17:44 roberto Exp roberto $
|
** $Id: liolib.c,v 1.37 1999/04/05 19:47:05 roberto Exp roberto $
|
||||||
** Standard I/O (and system) library
|
** Standard I/O (and system) library
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
#ifndef OLD_ANSI
|
#ifndef OLD_ANSI
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#else
|
#else
|
||||||
|
/* no support for locale and for strerror: fake them */
|
||||||
#define setlocale(a,b) 0
|
#define setlocale(a,b) 0
|
||||||
#define LC_ALL 0
|
#define LC_ALL 0
|
||||||
#define LC_COLLATE 0
|
#define LC_COLLATE 0
|
||||||
@@ -31,10 +32,12 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define CLOSEDTAG 2
|
#define IOTAG 1
|
||||||
#define IOTAG 1
|
|
||||||
|
#define FIRSTARG 2 /* 1st is upvalue */
|
||||||
|
|
||||||
|
#define CLOSEDTAG(tag) ((tag)-1) /* assume that CLOSEDTAG = iotag-1 */
|
||||||
|
|
||||||
#define FIRSTARG 3 /* 1st and 2nd are upvalues */
|
|
||||||
|
|
||||||
#define FINPUT "_INPUT"
|
#define FINPUT "_INPUT"
|
||||||
#define FOUTPUT "_OUTPUT"
|
#define FOUTPUT "_OUTPUT"
|
||||||
@@ -43,95 +46,131 @@
|
|||||||
#ifdef POPEN
|
#ifdef POPEN
|
||||||
FILE *popen();
|
FILE *popen();
|
||||||
int pclose();
|
int pclose();
|
||||||
|
#define CLOSEFILE(f) {if (pclose(f) == -1) fclose(f);}
|
||||||
#else
|
#else
|
||||||
|
/* no support for popen */
|
||||||
#define popen(x,y) NULL /* that is, popen always fails */
|
#define popen(x,y) NULL /* that is, popen always fails */
|
||||||
#define pclose(x) (-1)
|
#define CLOSEFILE(f) {fclose(f);}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static int gettag (int i)
|
|
||||||
{
|
|
||||||
return lua_getnumber(lua_getparam(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
static void pushresult (int i) {
|
||||||
static void pushresult (int i)
|
|
||||||
{
|
|
||||||
if (i)
|
if (i)
|
||||||
lua_pushuserdata(NULL);
|
lua_pushuserdata(NULL);
|
||||||
else {
|
else {
|
||||||
lua_pushnil();
|
lua_pushnil();
|
||||||
lua_pushstring(strerror(errno));
|
lua_pushstring(strerror(errno));
|
||||||
|
lua_pushnumber(errno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int ishandler (lua_Object f)
|
/*
|
||||||
{
|
** {======================================================
|
||||||
|
** FILE Operations
|
||||||
|
** =======================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int gettag (void) {
|
||||||
|
return (int)lua_getnumber(lua_getparam(IOTAG));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int ishandle (lua_Object f) {
|
||||||
if (lua_isuserdata(f)) {
|
if (lua_isuserdata(f)) {
|
||||||
if (lua_tag(f) == gettag(CLOSEDTAG))
|
int tag = gettag();
|
||||||
|
if (lua_tag(f) == CLOSEDTAG(tag))
|
||||||
lua_error("cannot access a closed file");
|
lua_error("cannot access a closed file");
|
||||||
return lua_tag(f) == gettag(IOTAG);
|
return lua_tag(f) == tag;
|
||||||
}
|
}
|
||||||
else return 0;
|
else return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FILE *getfile (char *name)
|
|
||||||
{
|
static FILE *getfilebyname (char *name) {
|
||||||
lua_Object f = lua_getglobal(name);
|
lua_Object f = lua_getglobal(name);
|
||||||
if (!ishandler(f))
|
if (!ishandle(f))
|
||||||
luaL_verror("global variable `%.50s' is not a file handle", name);
|
luaL_verror("global variable `%.50s' is not a file handle", name);
|
||||||
return lua_getuserdata(f);
|
return lua_getuserdata(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static FILE *getfileparam (char *name, int *arg)
|
static FILE *getfile (int arg) {
|
||||||
{
|
lua_Object f = lua_getparam(arg);
|
||||||
lua_Object f = lua_getparam(*arg);
|
return (ishandle(f)) ? lua_getuserdata(f) : NULL;
|
||||||
if (ishandler(f)) {
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static FILE *getnonullfile (int arg) {
|
||||||
|
FILE *f = getfile(arg);
|
||||||
|
luaL_arg_check(f, arg, "invalid file handle");
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static FILE *getfileparam (char *name, int *arg) {
|
||||||
|
FILE *f = getfile(*arg);
|
||||||
|
if (f) {
|
||||||
(*arg)++;
|
(*arg)++;
|
||||||
return lua_getuserdata(f);
|
return f;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return getfile(name);
|
return getfilebyname(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void closefile (char *name)
|
static void closefile (FILE *f) {
|
||||||
{
|
if (f != stdin && f != stdout) {
|
||||||
FILE *f = getfile(name);
|
int tag = gettag();
|
||||||
if (f == stdin || f == stdout) return;
|
CLOSEFILE(f);
|
||||||
if (pclose(f) == -1)
|
lua_pushusertag(f, tag);
|
||||||
fclose(f);
|
lua_settag(CLOSEDTAG(tag));
|
||||||
lua_pushobject(lua_getglobal(name));
|
}
|
||||||
lua_settag(gettag(CLOSEDTAG));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void setfile (FILE *f, char *name, int tag)
|
static void io_close (void) {
|
||||||
{
|
closefile(getnonullfile(FIRSTARG));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void gc_close (void) {
|
||||||
|
FILE *f = getnonullfile(FIRSTARG);
|
||||||
|
if (f != stdin && f != stdout && f != stderr) {
|
||||||
|
CLOSEFILE(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void io_open (void) {
|
||||||
|
FILE *f = fopen(luaL_check_string(FIRSTARG), luaL_check_string(FIRSTARG+1));
|
||||||
|
if (f) lua_pushusertag(f, gettag());
|
||||||
|
else pushresult(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void setfile (FILE *f, char *name, int tag) {
|
||||||
lua_pushusertag(f, tag);
|
lua_pushusertag(f, tag);
|
||||||
lua_setglobal(name);
|
lua_setglobal(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void setreturn (FILE *f, char *name)
|
static void setreturn (FILE *f, char *name) {
|
||||||
{
|
int tag = gettag();
|
||||||
int tag = gettag(IOTAG);
|
|
||||||
setfile(f, name, tag);
|
setfile(f, name, tag);
|
||||||
lua_pushusertag(f, tag);
|
lua_pushusertag(f, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void io_readfrom (void)
|
static void io_readfrom (void) {
|
||||||
{
|
|
||||||
FILE *current;
|
FILE *current;
|
||||||
lua_Object f = lua_getparam(FIRSTARG);
|
lua_Object f = lua_getparam(FIRSTARG);
|
||||||
if (f == LUA_NOOBJECT) {
|
if (f == LUA_NOOBJECT) {
|
||||||
closefile(FINPUT);
|
closefile(getfilebyname(FINPUT));
|
||||||
current = stdin;
|
current = stdin;
|
||||||
}
|
}
|
||||||
else if (lua_tag(f) == gettag(IOTAG))
|
else if (lua_tag(f) == gettag()) /* deprecated option */
|
||||||
current = lua_getuserdata(f);
|
current = lua_getuserdata(f);
|
||||||
else {
|
else {
|
||||||
char *s = luaL_check_string(FIRSTARG);
|
char *s = luaL_check_string(FIRSTARG);
|
||||||
@@ -145,19 +184,18 @@ static void io_readfrom (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void io_writeto (void)
|
static void io_writeto (void) {
|
||||||
{
|
|
||||||
FILE *current;
|
FILE *current;
|
||||||
lua_Object f = lua_getparam(FIRSTARG);
|
lua_Object f = lua_getparam(FIRSTARG);
|
||||||
if (f == LUA_NOOBJECT) {
|
if (f == LUA_NOOBJECT) {
|
||||||
closefile(FOUTPUT);
|
closefile(getfilebyname(FOUTPUT));
|
||||||
current = stdout;
|
current = stdout;
|
||||||
}
|
}
|
||||||
else if (lua_tag(f) == gettag(IOTAG))
|
else if (lua_tag(f) == gettag()) /* deprecated option */
|
||||||
current = lua_getuserdata(f);
|
current = lua_getuserdata(f);
|
||||||
else {
|
else {
|
||||||
char *s = luaL_check_string(FIRSTARG);
|
char *s = luaL_check_string(FIRSTARG);
|
||||||
current = (*s == '|') ? popen(s+1,"w") : fopen(s,"w");
|
current = (*s == '|') ? popen(s+1,"w") : fopen(s, "w");
|
||||||
if (current == NULL) {
|
if (current == NULL) {
|
||||||
pushresult(0);
|
pushresult(0);
|
||||||
return;
|
return;
|
||||||
@@ -167,10 +205,8 @@ static void io_writeto (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void io_appendto (void)
|
static void io_appendto (void) {
|
||||||
{
|
FILE *fp = fopen(luaL_check_string(FIRSTARG), "a");
|
||||||
char *s = luaL_check_string(FIRSTARG);
|
|
||||||
FILE *fp = fopen (s, "a");
|
|
||||||
if (fp != NULL)
|
if (fp != NULL)
|
||||||
setreturn(fp, FOUTPUT);
|
setreturn(fp, FOUTPUT);
|
||||||
else
|
else
|
||||||
@@ -178,127 +214,208 @@ static void io_appendto (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** {======================================================
|
||||||
|
** READ
|
||||||
|
** =======================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** We cannot lookahead without need, because this can lock stdin.
|
||||||
|
** This flag signals when we need to read a next char.
|
||||||
|
*/
|
||||||
#define NEED_OTHER (EOF-1) /* just some flag different from EOF */
|
#define NEED_OTHER (EOF-1) /* just some flag different from EOF */
|
||||||
|
|
||||||
|
|
||||||
static void read_until (FILE *f, int lim) {
|
static int read_pattern (FILE *f, char *p) {
|
||||||
int l = 0;
|
int inskip = 0; /* {skip} level */
|
||||||
int c;
|
int c = NEED_OTHER;
|
||||||
for (c = getc(f); c != EOF && c != lim; c = getc(f)) {
|
while (*p != '\0') {
|
||||||
luaL_addchar(c);
|
switch (*p) {
|
||||||
l++;
|
case '{':
|
||||||
}
|
inskip++;
|
||||||
if (l > 0 || c == lim) /* read anything? */
|
p++;
|
||||||
lua_pushlstring(luaL_buffer(), l);
|
continue;
|
||||||
}
|
case '}':
|
||||||
|
if (!inskip) lua_error("unbalanced braces in read pattern");
|
||||||
static void io_read (void) {
|
inskip--;
|
||||||
int arg = FIRSTARG;
|
p++;
|
||||||
FILE *f = getfileparam(FINPUT, &arg);
|
continue;
|
||||||
char *p = luaL_opt_string(arg, NULL);
|
default: {
|
||||||
luaL_resetbuffer();
|
char *ep; /* get what is next */
|
||||||
if (p == NULL) /* default: read a line */
|
int m; /* match result */
|
||||||
read_until(f, '\n');
|
if (c == NEED_OTHER) c = getc(f);
|
||||||
else if (p[0] == '.' && p[1] == '*' && p[2] == 0) /* p = ".*" */
|
if (c != EOF)
|
||||||
read_until(f, EOF);
|
m = luaI_singlematch(c, p, &ep);
|
||||||
else {
|
else {
|
||||||
int l = 0; /* number of chars read in buffer */
|
luaI_singlematch(0, p, &ep); /* to set "ep" */
|
||||||
int inskip = 0; /* to control {skips} */
|
m = 0; /* EOF matches no pattern */
|
||||||
int c = NEED_OTHER;
|
}
|
||||||
while (*p) {
|
if (m) {
|
||||||
switch (*p) {
|
if (!inskip) luaL_addchar(c);
|
||||||
case '{':
|
c = NEED_OTHER;
|
||||||
inskip++;
|
}
|
||||||
p++;
|
switch (*ep) {
|
||||||
continue;
|
case '*': /* repetition */
|
||||||
case '}':
|
if (!m) p = ep+1; /* else stay in (repeat) the same item */
|
||||||
if (inskip == 0)
|
continue;
|
||||||
lua_error("unbalanced braces in read pattern");
|
case '?': /* optional */
|
||||||
inskip--;
|
p = ep+1; /* continues reading the pattern */
|
||||||
p++;
|
continue;
|
||||||
continue;
|
default:
|
||||||
default: {
|
if (!m) goto break_while; /* pattern fails? */
|
||||||
char *ep; /* get what is next */
|
p = ep; /* else continues reading the pattern */
|
||||||
int m; /* match result */
|
|
||||||
if (c == NEED_OTHER) c = getc(f);
|
|
||||||
if (c == EOF) {
|
|
||||||
luaI_singlematch(0, p, &ep); /* to set "ep" */
|
|
||||||
m = 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
m = luaI_singlematch(c, p, &ep);
|
|
||||||
if (m) {
|
|
||||||
if (inskip == 0) {
|
|
||||||
luaL_addchar(c);
|
|
||||||
l++;
|
|
||||||
}
|
|
||||||
c = NEED_OTHER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
switch (*ep) {
|
|
||||||
case '*': /* repetition */
|
|
||||||
if (!m) p = ep+1; /* else stay in (repeat) the same item */
|
|
||||||
continue;
|
|
||||||
case '?': /* optional */
|
|
||||||
p = ep+1; /* continues reading the pattern */
|
|
||||||
continue;
|
|
||||||
default:
|
|
||||||
if (m) p = ep; /* continues reading the pattern */
|
|
||||||
else
|
|
||||||
goto break_while; /* pattern fails */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} break_while:
|
}
|
||||||
if (c >= 0) /* not EOF nor NEED_OTHER? */
|
} break_while:
|
||||||
ungetc(c, f);
|
if (c != NEED_OTHER) ungetc(c, f);
|
||||||
if (l > 0 || *p == 0) /* read something or did not fail? */
|
return (*p == '\0');
|
||||||
lua_pushlstring(luaL_buffer(), l);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void io_write (void)
|
static int read_number (FILE *f) {
|
||||||
{
|
double d;
|
||||||
|
if (fscanf(f, "%lf", &d) == 1) {
|
||||||
|
lua_pushnumber(d);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else return 0; /* read fails */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define HUNK_LINE 1024
|
||||||
|
#define HUNK_FILE BUFSIZ
|
||||||
|
|
||||||
|
static int read_line (FILE *f) {
|
||||||
|
/* equivalent to: return read_pattern(f, "[^\n]*{\n}"); */
|
||||||
|
int n;
|
||||||
|
char *b;
|
||||||
|
do {
|
||||||
|
b = luaL_openspace(HUNK_LINE);
|
||||||
|
if (!fgets(b, HUNK_LINE, f)) return 0; /* read fails */
|
||||||
|
n = strlen(b);
|
||||||
|
luaL_addsize(n);
|
||||||
|
} while (b[n-1] != '\n');
|
||||||
|
luaL_addsize(-1); /* remove '\n' */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void read_file (FILE *f) {
|
||||||
|
/* equivalent to: return read_pattern(f, ".*"); */
|
||||||
|
int n;
|
||||||
|
do {
|
||||||
|
char *b = luaL_openspace(HUNK_FILE);
|
||||||
|
n = fread(b, sizeof(char), HUNK_FILE, f);
|
||||||
|
luaL_addsize(n);
|
||||||
|
} while (n==HUNK_FILE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void io_read (void) {
|
||||||
|
static char *options[] = {"*n", "*l", "*a", ".*", "*w", NULL};
|
||||||
|
int arg = FIRSTARG;
|
||||||
|
FILE *f = getfileparam(FINPUT, &arg);
|
||||||
|
char *p = luaL_opt_string(arg++, "*l");
|
||||||
|
do { /* repeat for each part */
|
||||||
|
long l;
|
||||||
|
int success;
|
||||||
|
luaL_resetbuffer();
|
||||||
|
switch (luaL_findstring(p, options)) {
|
||||||
|
case 0: /* number */
|
||||||
|
if (!read_number(f)) return; /* read fails */
|
||||||
|
continue; /* number is already pushed; avoid the "pushstring" */
|
||||||
|
case 1: /* line */
|
||||||
|
success = read_line(f);
|
||||||
|
break;
|
||||||
|
case 2: case 3: /* file */
|
||||||
|
read_file(f);
|
||||||
|
success = 1; /* always success */
|
||||||
|
break;
|
||||||
|
case 4: /* word */
|
||||||
|
success = read_pattern(f, "{%s*}%S%S*");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
success = read_pattern(f, p);
|
||||||
|
}
|
||||||
|
l = luaL_getsize();
|
||||||
|
if (!success && l==0) return; /* read fails */
|
||||||
|
lua_pushlstring(luaL_buffer(), l);
|
||||||
|
} while ((p = luaL_opt_string(arg++, NULL)) != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* }====================================================== */
|
||||||
|
|
||||||
|
|
||||||
|
static void io_write (void) {
|
||||||
int arg = FIRSTARG;
|
int arg = FIRSTARG;
|
||||||
FILE *f = getfileparam(FOUTPUT, &arg);
|
FILE *f = getfileparam(FOUTPUT, &arg);
|
||||||
int status = 1;
|
int status = 1;
|
||||||
char *s;
|
char *s;
|
||||||
long l;
|
long l;
|
||||||
while ((s = luaL_opt_lstr(arg++, NULL, &l)) != NULL)
|
while ((s = luaL_opt_lstr(arg++, NULL, &l)) != NULL)
|
||||||
status = status && (fwrite(s, 1, l, f) == l);
|
status = status && ((long)fwrite(s, 1, l, f) == l);
|
||||||
pushresult(status);
|
pushresult(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void io_execute (void)
|
static void io_seek (void) {
|
||||||
{
|
static int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
|
||||||
|
static char *modenames[] = {"set", "cur", "end", NULL};
|
||||||
|
FILE *f = getnonullfile(FIRSTARG);
|
||||||
|
int op = luaL_findstring(luaL_opt_string(FIRSTARG+1, "cur"), modenames);
|
||||||
|
long offset = luaL_opt_long(FIRSTARG+2, 0);
|
||||||
|
luaL_arg_check(op != -1, FIRSTARG+1, "invalid mode");
|
||||||
|
op = fseek(f, offset, mode[op]);
|
||||||
|
if (op)
|
||||||
|
pushresult(0); /* error */
|
||||||
|
else
|
||||||
|
lua_pushnumber(ftell(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void io_flush (void) {
|
||||||
|
FILE *f = getfile(FIRSTARG);
|
||||||
|
luaL_arg_check(f || lua_getparam(FIRSTARG) == LUA_NOOBJECT, FIRSTARG,
|
||||||
|
"invalid file handle");
|
||||||
|
pushresult(fflush(f) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* }====================================================== */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** {======================================================
|
||||||
|
** Other O.S. Operations
|
||||||
|
** =======================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void io_execute (void) {
|
||||||
lua_pushnumber(system(luaL_check_string(1)));
|
lua_pushnumber(system(luaL_check_string(1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void io_remove (void)
|
static void io_remove (void) {
|
||||||
{
|
|
||||||
pushresult(remove(luaL_check_string(1)) == 0);
|
pushresult(remove(luaL_check_string(1)) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void io_rename (void)
|
static void io_rename (void) {
|
||||||
{
|
|
||||||
pushresult(rename(luaL_check_string(1),
|
pushresult(rename(luaL_check_string(1),
|
||||||
luaL_check_string(2)) == 0);
|
luaL_check_string(2)) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void io_tmpname (void)
|
static void io_tmpname (void) {
|
||||||
{
|
|
||||||
lua_pushstring(tmpnam(NULL));
|
lua_pushstring(tmpnam(NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void io_getenv (void)
|
static void io_getenv (void) {
|
||||||
{
|
|
||||||
lua_pushstring(getenv(luaL_check_string(1))); /* if NULL push nil */
|
lua_pushstring(getenv(luaL_check_string(1))); /* if NULL push nil */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,12 +425,11 @@ static void io_clock (void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void io_date (void)
|
static void io_date (void) {
|
||||||
{
|
char b[256];
|
||||||
time_t t;
|
|
||||||
struct tm *tm;
|
|
||||||
char *s = luaL_opt_string(1, "%c");
|
char *s = luaL_opt_string(1, "%c");
|
||||||
char b[BUFSIZ];
|
struct tm *tm;
|
||||||
|
time_t t;
|
||||||
time(&t); tm = localtime(&t);
|
time(&t); tm = localtime(&t);
|
||||||
if (strftime(b,sizeof(b),s,tm))
|
if (strftime(b,sizeof(b),s,tm))
|
||||||
lua_pushstring(b);
|
lua_pushstring(b);
|
||||||
@@ -322,8 +438,7 @@ static void io_date (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void setloc (void)
|
static void setloc (void) {
|
||||||
{
|
|
||||||
static int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC,
|
static int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC,
|
||||||
LC_TIME};
|
LC_TIME};
|
||||||
static char *catnames[] = {"all", "collate", "ctype", "monetary",
|
static char *catnames[] = {"all", "collate", "ctype", "monetary",
|
||||||
@@ -334,115 +449,140 @@ static void setloc (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void io_exit (void)
|
static void io_exit (void) {
|
||||||
{
|
|
||||||
lua_Object o = lua_getparam(1);
|
lua_Object o = lua_getparam(1);
|
||||||
exit(lua_isnumber(o) ? (int)lua_getnumber(o) : 1);
|
exit(lua_isnumber(o) ? (int)lua_getnumber(o) : 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* }====================================================== */
|
||||||
|
|
||||||
static void io_debug (void)
|
|
||||||
{
|
|
||||||
while (1) {
|
static void io_debug (void) {
|
||||||
|
for (;;) {
|
||||||
char buffer[250];
|
char buffer[250];
|
||||||
fprintf(stderr, "lua_debug> ");
|
fprintf(stderr, "lua_debug> ");
|
||||||
if (fgets(buffer, sizeof(buffer), stdin) == 0) return;
|
if (fgets(buffer, sizeof(buffer), stdin) == 0 ||
|
||||||
if (strcmp(buffer, "cont\n") == 0) return;
|
strcmp(buffer, "cont\n") == 0)
|
||||||
|
return;
|
||||||
lua_dostring(buffer);
|
lua_dostring(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void lua_printstack (FILE *f)
|
|
||||||
{
|
#define MESSAGESIZE 150
|
||||||
|
#define MAXMESSAGE (MESSAGESIZE*10)
|
||||||
|
|
||||||
|
|
||||||
|
#define MAXSRC 40
|
||||||
|
|
||||||
|
|
||||||
|
static void errorfb (void) {
|
||||||
|
char buff[MAXMESSAGE];
|
||||||
int level = 1; /* skip level 0 (it's this function) */
|
int level = 1; /* skip level 0 (it's this function) */
|
||||||
lua_Object func;
|
lua_Object func;
|
||||||
|
sprintf(buff, "lua error: %.200s\n", lua_getstring(lua_getparam(1)));
|
||||||
while ((func = lua_stackedfunction(level++)) != LUA_NOOBJECT) {
|
while ((func = lua_stackedfunction(level++)) != LUA_NOOBJECT) {
|
||||||
char *name;
|
char *name;
|
||||||
int currentline;
|
int currentline;
|
||||||
char *filename;
|
char *chunkname;
|
||||||
|
char buffchunk[MAXSRC];
|
||||||
int linedefined;
|
int linedefined;
|
||||||
lua_funcinfo(func, &filename, &linedefined);
|
lua_funcinfo(func, &chunkname, &linedefined);
|
||||||
fprintf(f, (level==2) ? "Active Stack:\n\t" : "\t");
|
luaL_chunkid(buffchunk, chunkname, sizeof(buffchunk));
|
||||||
|
if (level == 2) strcat(buff, "Active Stack:\n");
|
||||||
|
strcat(buff, "\t");
|
||||||
|
if (strlen(buff) > MAXMESSAGE-MESSAGESIZE) {
|
||||||
|
strcat(buff, "...\n");
|
||||||
|
break; /* buffer is full */
|
||||||
|
}
|
||||||
switch (*lua_getobjname(func, &name)) {
|
switch (*lua_getobjname(func, &name)) {
|
||||||
case 'g':
|
case 'g':
|
||||||
fprintf(f, "function %s", name);
|
sprintf(buff+strlen(buff), "function `%.50s'", name);
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
fprintf(f, "`%s' tag method", name);
|
sprintf(buff+strlen(buff), "`%.50s' tag method", name);
|
||||||
break;
|
break;
|
||||||
default: {
|
default: {
|
||||||
if (linedefined == 0)
|
if (linedefined == 0)
|
||||||
fprintf(f, "main of %s", filename);
|
sprintf(buff+strlen(buff), "main of %.50s", buffchunk);
|
||||||
else if (linedefined < 0)
|
else if (linedefined < 0)
|
||||||
fprintf(f, "%s", filename);
|
sprintf(buff+strlen(buff), "%.50s", buffchunk);
|
||||||
else
|
else
|
||||||
fprintf(f, "function (%s:%d)", filename, linedefined);
|
sprintf(buff+strlen(buff), "function <%d:%.50s>",
|
||||||
filename = NULL;
|
linedefined, buffchunk);
|
||||||
|
chunkname = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((currentline = lua_currentline(func)) > 0)
|
if ((currentline = lua_currentline(func)) > 0)
|
||||||
fprintf(f, " at line %d", currentline);
|
sprintf(buff+strlen(buff), " at line %d", currentline);
|
||||||
if (filename)
|
if (chunkname)
|
||||||
fprintf(f, " [in file %s]", filename);
|
sprintf(buff+strlen(buff), " [%.50s]", buffchunk);
|
||||||
fprintf(f, "\n");
|
strcat(buff, "\n");
|
||||||
|
}
|
||||||
|
func = lua_rawgetglobal("_ALERT");
|
||||||
|
if (lua_isfunction(func)) { /* avoid error loop if _ALERT is not defined */
|
||||||
|
lua_pushstring(buff);
|
||||||
|
lua_callfunction(func);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void errorfb (void)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "lua: %s\n", lua_getstring(lua_getparam(1)));
|
|
||||||
lua_printstack(stderr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static struct luaL_reg iolib[] = {
|
static struct luaL_reg iolib[] = {
|
||||||
{"setlocale", setloc},
|
{"_ERRORMESSAGE", errorfb},
|
||||||
{"execute", io_execute},
|
{"clock", io_clock},
|
||||||
{"remove", io_remove},
|
{"date", io_date},
|
||||||
{"rename", io_rename},
|
{"debug", io_debug},
|
||||||
{"tmpname", io_tmpname},
|
{"execute", io_execute},
|
||||||
{"getenv", io_getenv},
|
{"exit", io_exit},
|
||||||
{"date", io_date},
|
{"getenv", io_getenv},
|
||||||
{"clock", io_clock},
|
{"remove", io_remove},
|
||||||
{"exit", io_exit},
|
{"rename", io_rename},
|
||||||
{"debug", io_debug},
|
{"setlocale", setloc},
|
||||||
{"print_stack", errorfb}
|
{"tmpname", io_tmpname}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static struct luaL_reg iolibtag[] = {
|
static struct luaL_reg iolibtag[] = {
|
||||||
{"readfrom", io_readfrom},
|
{"appendto", io_appendto},
|
||||||
{"writeto", io_writeto},
|
{"closefile", io_close},
|
||||||
{"appendto", io_appendto},
|
{"flush", io_flush},
|
||||||
{"read", io_read},
|
{"openfile", io_open},
|
||||||
{"write", io_write}
|
{"read", io_read},
|
||||||
|
{"readfrom", io_readfrom},
|
||||||
|
{"seek", io_seek},
|
||||||
|
{"write", io_write},
|
||||||
|
{"writeto", io_writeto}
|
||||||
};
|
};
|
||||||
|
|
||||||
static void openwithtags (void)
|
|
||||||
{
|
static void openwithtags (void) {
|
||||||
int iotag = lua_newtag();
|
|
||||||
int closedtag = lua_newtag();
|
|
||||||
int i;
|
int i;
|
||||||
|
int iotag = lua_newtag();
|
||||||
|
lua_newtag(); /* alloc CLOSEDTAG: assume that CLOSEDTAG = iotag-1 */
|
||||||
for (i=0; i<sizeof(iolibtag)/sizeof(iolibtag[0]); i++) {
|
for (i=0; i<sizeof(iolibtag)/sizeof(iolibtag[0]); i++) {
|
||||||
/* put both tags as upvalues for these functions */
|
/* put iotag as upvalue for these functions */
|
||||||
lua_pushnumber(iotag);
|
lua_pushnumber(iotag);
|
||||||
lua_pushnumber(closedtag);
|
lua_pushcclosure(iolibtag[i].func, 1);
|
||||||
lua_pushcclosure(iolibtag[i].func, 2);
|
|
||||||
lua_setglobal(iolibtag[i].name);
|
lua_setglobal(iolibtag[i].name);
|
||||||
}
|
}
|
||||||
|
/* predefined file handles */
|
||||||
setfile(stdin, FINPUT, iotag);
|
setfile(stdin, FINPUT, iotag);
|
||||||
setfile(stdout, FOUTPUT, iotag);
|
setfile(stdout, FOUTPUT, iotag);
|
||||||
setfile(stdin, "_STDIN", iotag);
|
setfile(stdin, "_STDIN", iotag);
|
||||||
setfile(stdout, "_STDOUT", iotag);
|
setfile(stdout, "_STDOUT", iotag);
|
||||||
setfile(stderr, "_STDERR", iotag);
|
setfile(stderr, "_STDERR", iotag);
|
||||||
|
/* close file when collected */
|
||||||
|
lua_pushnumber(iotag);
|
||||||
|
lua_pushcclosure(gc_close, 1);
|
||||||
|
lua_settagmethod(iotag, "gc");
|
||||||
}
|
}
|
||||||
|
|
||||||
void lua_iolibopen (void)
|
void lua_iolibopen (void) {
|
||||||
{
|
/* register lib functions */
|
||||||
luaL_openlib(iolib, (sizeof(iolib)/sizeof(iolib[0])));
|
luaL_openlib(iolib, (sizeof(iolib)/sizeof(iolib[0])));
|
||||||
openwithtags();
|
openwithtags();
|
||||||
lua_pushcfunction(errorfb);
|
|
||||||
lua_seterrormethod();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
109
llex.c
109
llex.c
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: llex.c,v 1.22 1998/06/19 18:47:06 roberto Exp roberto $
|
** $Id: llex.c,v 1.33 1999/03/11 18:59:19 roberto Exp roberto $
|
||||||
** Lexical Analizer
|
** Lexical Analyzer
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -20,9 +20,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int lua_debug=0;
|
|
||||||
|
|
||||||
|
|
||||||
#define next(LS) (LS->current = zgetc(LS->lex_z))
|
#define next(LS) (LS->current = zgetc(LS->lex_z))
|
||||||
|
|
||||||
|
|
||||||
@@ -35,8 +32,7 @@ char *reserved [] = {"and", "do", "else", "elseif", "end", "function",
|
|||||||
"until", "while"};
|
"until", "while"};
|
||||||
|
|
||||||
|
|
||||||
void luaX_init (void)
|
void luaX_init (void) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
for (i=0; i<(sizeof(reserved)/sizeof(reserved[0])); i++) {
|
for (i=0; i<(sizeof(reserved)/sizeof(reserved[0])); i++) {
|
||||||
TaggedString *ts = luaS_new(reserved[i]);
|
TaggedString *ts = luaS_new(reserved[i]);
|
||||||
@@ -45,24 +41,28 @@ void luaX_init (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define MAXSRC 40
|
||||||
|
|
||||||
void luaX_syntaxerror (LexState *ls, char *s, char *token) {
|
void luaX_syntaxerror (LexState *ls, char *s, char *token) {
|
||||||
if (token[0] == 0)
|
char buff[MAXSRC];
|
||||||
|
luaL_chunkid(buff, zname(ls->lex_z), sizeof(buff));
|
||||||
|
if (token[0] == '\0')
|
||||||
token = "<eof>";
|
token = "<eof>";
|
||||||
luaL_verror("%.100s;\n last token read: `%.50s' at line %d in chunk `%.50s'",
|
luaL_verror("%.100s;\n last token read: `%.50s' at line %d in %.50s",
|
||||||
s, token, ls->linenumber, zname(ls->lex_z));
|
s, token, ls->linenumber, buff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void luaX_error (LexState *ls, char *s) {
|
void luaX_error (LexState *ls, char *s) {
|
||||||
save(0);
|
save('\0');
|
||||||
luaX_syntaxerror(ls, s, luaL_buffer());
|
luaX_syntaxerror(ls, s, luaL_buffer());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void luaX_token2str (LexState *ls, int token, char *s) {
|
void luaX_token2str (int token, char *s) {
|
||||||
if (token < 255) {
|
if (token < 255) {
|
||||||
s[0] = token;
|
s[0] = (char)token;
|
||||||
s[1] = 0;
|
s[1] = '\0';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
strcpy(s, reserved[token-FIRST_RESERVED]);
|
strcpy(s, reserved[token-FIRST_RESERVED]);
|
||||||
@@ -71,7 +71,7 @@ void luaX_token2str (LexState *ls, int token, char *s) {
|
|||||||
|
|
||||||
static void luaX_invalidchar (LexState *ls, int c) {
|
static void luaX_invalidchar (LexState *ls, int c) {
|
||||||
char buff[10];
|
char buff[10];
|
||||||
sprintf(buff, "0x%X", c);
|
sprintf(buff, "0x%02X", c);
|
||||||
luaX_syntaxerror(ls, "invalid control char", buff);
|
luaX_syntaxerror(ls, "invalid control char", buff);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,7 +138,7 @@ static void readname (LexState *LS, char *buff)
|
|||||||
buff[PRAGMASIZE] = 0;
|
buff[PRAGMASIZE] = 0;
|
||||||
luaX_syntaxerror(LS, "pragma too long", buff);
|
luaX_syntaxerror(LS, "pragma too long", buff);
|
||||||
}
|
}
|
||||||
buff[i++] = LS->current;
|
buff[i++] = (char)LS->current;
|
||||||
next(LS);
|
next(LS);
|
||||||
}
|
}
|
||||||
buff[i] = 0;
|
buff[i] = 0;
|
||||||
@@ -174,10 +174,10 @@ static void inclinenumber (LexState *LS)
|
|||||||
readname(LS, buff);
|
readname(LS, buff);
|
||||||
switch (luaL_findstring(buff, pragmas)) {
|
switch (luaL_findstring(buff, pragmas)) {
|
||||||
case 0: /* debug */
|
case 0: /* debug */
|
||||||
if (!skip) lua_debug = 1;
|
if (!skip) L->debug = 1;
|
||||||
break;
|
break;
|
||||||
case 1: /* nodebug */
|
case 1: /* nodebug */
|
||||||
if (!skip) lua_debug = 0;
|
if (!skip) L->debug = 0;
|
||||||
break;
|
break;
|
||||||
case 2: /* endinput */
|
case 2: /* endinput */
|
||||||
if (!skip) {
|
if (!skip) {
|
||||||
@@ -221,6 +221,7 @@ static void inclinenumber (LexState *LS)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** =======================================================
|
** =======================================================
|
||||||
** LEXICAL ANALIZER
|
** LEXICAL ANALIZER
|
||||||
@@ -229,12 +230,9 @@ static void inclinenumber (LexState *LS)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int read_long_string (LexState *LS) {
|
||||||
|
|
||||||
static int read_long_string (LexState *LS)
|
|
||||||
{
|
|
||||||
int cont = 0;
|
int cont = 0;
|
||||||
while (1) {
|
for (;;) {
|
||||||
switch (LS->current) {
|
switch (LS->current) {
|
||||||
case EOZ:
|
case EOZ:
|
||||||
luaX_error(LS, "unfinished long string");
|
luaX_error(LS, "unfinished long string");
|
||||||
@@ -262,17 +260,16 @@ static int read_long_string (LexState *LS)
|
|||||||
save_and_next(LS);
|
save_and_next(LS);
|
||||||
}
|
}
|
||||||
} endloop:
|
} endloop:
|
||||||
save_and_next(LS); /* pass the second ']' */
|
save_and_next(LS); /* skip the second ']' */
|
||||||
LS->seminfo.ts = luaS_newlstr(L->Mbuffbase+2,
|
LS->seminfo.ts = luaS_newlstr(L->Mbuffer+(L->Mbuffbase+2),
|
||||||
L->Mbuffnext-(L->Mbuffbase-L->Mbuffer)-4);
|
L->Mbuffnext-L->Mbuffbase-4);
|
||||||
return STRING;
|
return STRING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int luaX_lex (LexState *LS) {
|
int luaX_lex (LexState *LS) {
|
||||||
double a;
|
|
||||||
luaL_resetbuffer();
|
luaL_resetbuffer();
|
||||||
while (1) {
|
for (;;) {
|
||||||
switch (LS->current) {
|
switch (LS->current) {
|
||||||
|
|
||||||
case ' ': case '\t': case '\r': /* CR: to avoid problems with DOS */
|
case ' ': case '\t': case '\r': /* CR: to avoid problems with DOS */
|
||||||
@@ -347,7 +344,7 @@ int luaX_lex (LexState *LS) {
|
|||||||
c = 10*c + (LS->current-'0');
|
c = 10*c + (LS->current-'0');
|
||||||
next(LS);
|
next(LS);
|
||||||
} while (++i<3 && isdigit(LS->current));
|
} while (++i<3 && isdigit(LS->current));
|
||||||
if (c >= 256)
|
if (c != (unsigned char)c)
|
||||||
luaX_error(LS, "escape sequence too large");
|
luaX_error(LS, "escape sequence too large");
|
||||||
save(c);
|
save(c);
|
||||||
}
|
}
|
||||||
@@ -364,8 +361,8 @@ int luaX_lex (LexState *LS) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
save_and_next(LS); /* skip delimiter */
|
save_and_next(LS); /* skip delimiter */
|
||||||
LS->seminfo.ts = luaS_newlstr(L->Mbuffbase+1,
|
LS->seminfo.ts = luaS_newlstr(L->Mbuffer+(L->Mbuffbase+1),
|
||||||
L->Mbuffnext-(L->Mbuffbase-L->Mbuffer)-2);
|
L->Mbuffnext-L->Mbuffbase-2);
|
||||||
return STRING;
|
return STRING;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -382,15 +379,11 @@ int luaX_lex (LexState *LS) {
|
|||||||
else return CONC; /* .. */
|
else return CONC; /* .. */
|
||||||
}
|
}
|
||||||
else if (!isdigit(LS->current)) return '.';
|
else if (!isdigit(LS->current)) return '.';
|
||||||
/* LS->current is a digit: goes through to number */
|
goto fraction; /* LS->current is a digit: goes through to number */
|
||||||
a=0.0;
|
|
||||||
goto fraction;
|
|
||||||
|
|
||||||
case '0': case '1': case '2': case '3': case '4':
|
case '0': case '1': case '2': case '3': case '4':
|
||||||
case '5': case '6': case '7': case '8': case '9':
|
case '5': case '6': case '7': case '8': case '9':
|
||||||
a=0.0;
|
|
||||||
do {
|
do {
|
||||||
a = 10.0*a + (LS->current-'0');
|
|
||||||
save_and_next(LS);
|
save_and_next(LS);
|
||||||
} while (isdigit(LS->current));
|
} while (isdigit(LS->current));
|
||||||
if (LS->current == '.') {
|
if (LS->current == '.') {
|
||||||
@@ -402,35 +395,19 @@ int luaX_lex (LexState *LS) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fraction:
|
fraction:
|
||||||
{ double da=0.1;
|
while (isdigit(LS->current))
|
||||||
while (isdigit(LS->current))
|
save_and_next(LS);
|
||||||
{
|
if (toupper(LS->current) == 'E') {
|
||||||
a += (LS->current-'0')*da;
|
save_and_next(LS); /* read 'E' */
|
||||||
da /= 10.0;
|
save_and_next(LS); /* read '+', '-' or first digit */
|
||||||
|
while (isdigit(LS->current))
|
||||||
save_and_next(LS);
|
save_and_next(LS);
|
||||||
}
|
|
||||||
if (toupper(LS->current) == 'E') {
|
|
||||||
int e = 0;
|
|
||||||
int neg;
|
|
||||||
double ea;
|
|
||||||
save_and_next(LS);
|
|
||||||
neg = (LS->current=='-');
|
|
||||||
if (LS->current == '+' || LS->current == '-') save_and_next(LS);
|
|
||||||
if (!isdigit(LS->current))
|
|
||||||
luaX_error(LS, "invalid numeral format");
|
|
||||||
do {
|
|
||||||
e = 10*e + (LS->current-'0');
|
|
||||||
save_and_next(LS);
|
|
||||||
} while (isdigit(LS->current));
|
|
||||||
for (ea=neg?0.1:10.0; e>0; e>>=1)
|
|
||||||
{
|
|
||||||
if (e & 1) a *= ea;
|
|
||||||
ea *= ea;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LS->seminfo.r = a;
|
|
||||||
return NUMBER;
|
|
||||||
}
|
}
|
||||||
|
save('\0');
|
||||||
|
LS->seminfo.r = luaO_str2d(L->Mbuffer+L->Mbuffbase);
|
||||||
|
if (LS->seminfo.r < 0)
|
||||||
|
luaX_error(LS, "invalid numeric format");
|
||||||
|
return NUMBER;
|
||||||
|
|
||||||
case EOZ:
|
case EOZ:
|
||||||
if (LS->iflevel > 0)
|
if (LS->iflevel > 0)
|
||||||
@@ -450,9 +427,9 @@ int luaX_lex (LexState *LS) {
|
|||||||
do {
|
do {
|
||||||
save_and_next(LS);
|
save_and_next(LS);
|
||||||
} while (isalnum(LS->current) || LS->current == '_');
|
} while (isalnum(LS->current) || LS->current == '_');
|
||||||
save(0);
|
save('\0');
|
||||||
ts = luaS_new(L->Mbuffbase);
|
ts = luaS_new(L->Mbuffer+L->Mbuffbase);
|
||||||
if (ts->head.marked >= 'A')
|
if (ts->head.marked >= FIRST_RESERVED)
|
||||||
return ts->head.marked; /* reserved word */
|
return ts->head.marked; /* reserved word */
|
||||||
LS->seminfo.ts = ts;
|
LS->seminfo.ts = ts;
|
||||||
return NAME;
|
return NAME;
|
||||||
|
|||||||
8
llex.h
8
llex.h
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: llex.h,v 1.8 1998/05/27 13:03:40 roberto Exp roberto $
|
** $Id: llex.h,v 1.10 1998/07/24 18:02:38 roberto Exp roberto $
|
||||||
** Lexical Analizer
|
** Lexical Analyzer
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ enum RESERVED {
|
|||||||
/* "ifstate" keeps the state of each nested $if the lexical is dealing with. */
|
/* "ifstate" keeps the state of each nested $if the lexical is dealing with. */
|
||||||
|
|
||||||
struct ifState {
|
struct ifState {
|
||||||
int elsepart; /* true if its in the $else part */
|
int elsepart; /* true if it's in the $else part */
|
||||||
int condition; /* true if $if condition is true */
|
int condition; /* true if $if condition is true */
|
||||||
int skip; /* true if part must be skipped */
|
int skip; /* true if part must be skipped */
|
||||||
};
|
};
|
||||||
@@ -56,7 +56,7 @@ void luaX_setinput (LexState *LS, ZIO *z);
|
|||||||
int luaX_lex (LexState *LS);
|
int luaX_lex (LexState *LS);
|
||||||
void luaX_syntaxerror (LexState *ls, char *s, char *token);
|
void luaX_syntaxerror (LexState *ls, char *s, char *token);
|
||||||
void luaX_error (LexState *ls, char *s);
|
void luaX_error (LexState *ls, char *s);
|
||||||
void luaX_token2str (LexState *ls, int token, char *s);
|
void luaX_token2str (int token, char *s);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
123
lmathlib.c
123
lmathlib.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lmathlib.c,v 1.9 1998/05/27 19:09:39 roberto Exp roberto $
|
** $Id: lmathlib.c,v 1.15 1999/01/04 12:41:12 roberto Exp roberto $
|
||||||
** Lua standard mathematical library
|
** Lua standard mathematical library
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -12,107 +12,95 @@
|
|||||||
#include "lua.h"
|
#include "lua.h"
|
||||||
#include "lualib.h"
|
#include "lualib.h"
|
||||||
|
|
||||||
#ifdef M_PI
|
|
||||||
#define PI M_PI
|
#define PI (3.14159265358979323846)
|
||||||
|
#define RADIANS_PER_DEGREE (PI/180.0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** If you want Lua to operate in radians (instead of degrees),
|
||||||
|
** define RADIANS
|
||||||
|
*/
|
||||||
|
#ifdef RADIANS
|
||||||
|
#define FROMRAD(a) (a)
|
||||||
|
#define TORAD(a) (a)
|
||||||
#else
|
#else
|
||||||
#define PI ((double)3.14159265358979323846)
|
#define FROMRAD(a) ((a)/RADIANS_PER_DEGREE)
|
||||||
|
#define TORAD(a) ((a)*RADIANS_PER_DEGREE)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define FROMRAD(a) ((a)*(180.0/PI))
|
static void math_abs (void) {
|
||||||
#define TORAD(a) ((a)*(PI/180.0))
|
lua_pushnumber(fabs(luaL_check_number(1)));
|
||||||
|
|
||||||
|
|
||||||
static void math_abs (void)
|
|
||||||
{
|
|
||||||
double d = luaL_check_number(1);
|
|
||||||
if (d < 0) d = -d;
|
|
||||||
lua_pushnumber(d);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void math_sin (void)
|
static void math_sin (void) {
|
||||||
{
|
|
||||||
lua_pushnumber(sin(TORAD(luaL_check_number(1))));
|
lua_pushnumber(sin(TORAD(luaL_check_number(1))));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void math_cos (void)
|
static void math_cos (void) {
|
||||||
{
|
|
||||||
lua_pushnumber(cos(TORAD(luaL_check_number(1))));
|
lua_pushnumber(cos(TORAD(luaL_check_number(1))));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void math_tan (void)
|
static void math_tan (void) {
|
||||||
{
|
|
||||||
lua_pushnumber(tan(TORAD(luaL_check_number(1))));
|
lua_pushnumber(tan(TORAD(luaL_check_number(1))));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void math_asin (void)
|
static void math_asin (void) {
|
||||||
{
|
|
||||||
lua_pushnumber(FROMRAD(asin(luaL_check_number(1))));
|
lua_pushnumber(FROMRAD(asin(luaL_check_number(1))));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void math_acos (void)
|
static void math_acos (void) {
|
||||||
{
|
|
||||||
lua_pushnumber(FROMRAD(acos(luaL_check_number(1))));
|
lua_pushnumber(FROMRAD(acos(luaL_check_number(1))));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void math_atan (void)
|
static void math_atan (void) {
|
||||||
{
|
|
||||||
lua_pushnumber(FROMRAD(atan(luaL_check_number(1))));
|
lua_pushnumber(FROMRAD(atan(luaL_check_number(1))));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void math_atan2 (void)
|
static void math_atan2 (void) {
|
||||||
{
|
|
||||||
lua_pushnumber(FROMRAD(atan2(luaL_check_number(1), luaL_check_number(2))));
|
lua_pushnumber(FROMRAD(atan2(luaL_check_number(1), luaL_check_number(2))));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void math_ceil (void)
|
static void math_ceil (void) {
|
||||||
{
|
|
||||||
lua_pushnumber(ceil(luaL_check_number(1)));
|
lua_pushnumber(ceil(luaL_check_number(1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void math_floor (void)
|
static void math_floor (void) {
|
||||||
{
|
|
||||||
lua_pushnumber(floor(luaL_check_number(1)));
|
lua_pushnumber(floor(luaL_check_number(1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void math_mod (void)
|
static void math_mod (void) {
|
||||||
{
|
|
||||||
lua_pushnumber(fmod(luaL_check_number(1), luaL_check_number(2)));
|
lua_pushnumber(fmod(luaL_check_number(1), luaL_check_number(2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void math_sqrt (void)
|
static void math_sqrt (void) {
|
||||||
{
|
|
||||||
lua_pushnumber(sqrt(luaL_check_number(1)));
|
lua_pushnumber(sqrt(luaL_check_number(1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void math_pow (void)
|
static void math_pow (void) {
|
||||||
{
|
|
||||||
lua_pushnumber(pow(luaL_check_number(1), luaL_check_number(2)));
|
lua_pushnumber(pow(luaL_check_number(1), luaL_check_number(2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void math_log (void)
|
static void math_log (void) {
|
||||||
{
|
|
||||||
lua_pushnumber(log(luaL_check_number(1)));
|
lua_pushnumber(log(luaL_check_number(1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void math_log10 (void)
|
static void math_log10 (void) {
|
||||||
{
|
|
||||||
lua_pushnumber(log10(luaL_check_number(1)));
|
lua_pushnumber(log10(luaL_check_number(1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void math_exp (void)
|
static void math_exp (void) {
|
||||||
{
|
|
||||||
lua_pushnumber(exp(luaL_check_number(1)));
|
lua_pushnumber(exp(luaL_check_number(1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void math_deg (void)
|
static void math_deg (void) {
|
||||||
{
|
lua_pushnumber(luaL_check_number(1)/RADIANS_PER_DEGREE);
|
||||||
lua_pushnumber(luaL_check_number(1)*(180.0/PI));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void math_rad (void)
|
static void math_rad (void) {
|
||||||
{
|
lua_pushnumber(luaL_check_number(1)*RADIANS_PER_DEGREE);
|
||||||
lua_pushnumber(luaL_check_number(1)*(PI/180.0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void math_frexp (void) {
|
static void math_frexp (void) {
|
||||||
@@ -122,13 +110,12 @@ static void math_frexp (void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void math_ldexp (void) {
|
static void math_ldexp (void) {
|
||||||
lua_pushnumber(ldexp(luaL_check_number(1), luaL_check_number(2)));
|
lua_pushnumber(ldexp(luaL_check_number(1), luaL_check_int(2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void math_min (void)
|
static void math_min (void) {
|
||||||
{
|
|
||||||
int i = 1;
|
int i = 1;
|
||||||
double dmin = luaL_check_number(i);
|
double dmin = luaL_check_number(i);
|
||||||
while (lua_getparam(++i) != LUA_NOOBJECT) {
|
while (lua_getparam(++i) != LUA_NOOBJECT) {
|
||||||
@@ -140,8 +127,7 @@ static void math_min (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void math_max (void)
|
static void math_max (void) {
|
||||||
{
|
|
||||||
int i = 1;
|
int i = 1;
|
||||||
double dmax = luaL_check_number(i);
|
double dmax = luaL_check_number(i);
|
||||||
while (lua_getparam(++i) != LUA_NOOBJECT) {
|
while (lua_getparam(++i) != LUA_NOOBJECT) {
|
||||||
@@ -153,22 +139,27 @@ static void math_max (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void math_random (void)
|
static void math_random (void) {
|
||||||
{
|
/* the '%' avoids the (rare) case of r==1, and is needed also because on
|
||||||
/* the '%' is needed because on some systems (SunOS!) "rand()" may */
|
some systems (SunOS!) "rand()" may return a value bigger than RAND_MAX */
|
||||||
/* return a value bigger than RAND_MAX... */
|
|
||||||
double r = (double)(rand()%RAND_MAX) / (double)RAND_MAX;
|
double r = (double)(rand()%RAND_MAX) / (double)RAND_MAX;
|
||||||
double l = luaL_opt_number(1, 0);
|
int l = luaL_opt_int(1, 0);
|
||||||
if (l == 0)
|
if (l == 0)
|
||||||
lua_pushnumber(r);
|
lua_pushnumber(r);
|
||||||
else
|
else {
|
||||||
lua_pushnumber((int)(r*l)+1);
|
int u = luaL_opt_int(2, 0);
|
||||||
|
if (u == 0) {
|
||||||
|
u = l;
|
||||||
|
l = 1;
|
||||||
|
}
|
||||||
|
luaL_arg_check(l<=u, 1, "interval is empty");
|
||||||
|
lua_pushnumber((int)(r*(u-l+1))+l);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void math_randomseed (void)
|
static void math_randomseed (void) {
|
||||||
{
|
srand(luaL_check_int(1));
|
||||||
srand(luaL_check_number(1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -201,10 +192,8 @@ static struct luaL_reg mathlib[] = {
|
|||||||
/*
|
/*
|
||||||
** Open math library
|
** Open math library
|
||||||
*/
|
*/
|
||||||
void lua_mathlibopen (void)
|
void lua_mathlibopen (void) {
|
||||||
{
|
|
||||||
luaL_openlib(mathlib, (sizeof(mathlib)/sizeof(mathlib[0])));
|
luaL_openlib(mathlib, (sizeof(mathlib)/sizeof(mathlib[0])));
|
||||||
lua_pushstring("deg"); lua_setglobal("_TRIGMODE");
|
|
||||||
lua_pushcfunction(math_pow);
|
lua_pushcfunction(math_pow);
|
||||||
lua_pushnumber(0); /* to get its tag */
|
lua_pushnumber(0); /* to get its tag */
|
||||||
lua_settagmethod(lua_tag(lua_pop()), "pow");
|
lua_settagmethod(lua_tag(lua_pop()), "pow");
|
||||||
|
|||||||
90
lmem.c
90
lmem.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lmem.c,v 1.6 1998/06/19 16:14:09 roberto Exp roberto $
|
** $Id: lmem.c,v 1.13 1999/02/26 15:50:10 roberto Exp roberto $
|
||||||
** Interface to Memory Manager
|
** Interface to Memory Manager
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -12,41 +12,59 @@
|
|||||||
#include "lua.h"
|
#include "lua.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** real ANSI systems do not need these tests;
|
||||||
|
** but some systems (Sun OS) are not that ANSI...
|
||||||
|
*/
|
||||||
|
#ifdef OLD_ANSI
|
||||||
|
#define realloc(b,s) ((b) == NULL ? malloc(s) : (realloc)(b, s))
|
||||||
|
#define free(b) if (b) (free)(b)
|
||||||
|
#endif
|
||||||
|
|
||||||
int luaM_growaux (void **block, unsigned long nelems, int size,
|
|
||||||
char *errormsg, unsigned long limit)
|
#define MINSIZE 16 /* minimum size for "growing" vectors */
|
||||||
{
|
|
||||||
if (nelems >= limit)
|
|
||||||
lua_error(errormsg);
|
|
||||||
nelems = (nelems == 0) ? 32 : nelems*2;
|
|
||||||
if (nelems > limit)
|
|
||||||
nelems = limit;
|
|
||||||
*block = luaM_realloc(*block, nelems*size);
|
|
||||||
return (int)nelems;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef DEBUG
|
#ifndef DEBUG
|
||||||
|
|
||||||
|
|
||||||
|
static unsigned long power2 (unsigned long n) {
|
||||||
|
unsigned long p = MINSIZE;
|
||||||
|
while (p<=n) p<<=1;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void *luaM_growaux (void *block, unsigned long nelems, int inc, int size,
|
||||||
|
char *errormsg, unsigned long limit) {
|
||||||
|
unsigned long newn = nelems+inc;
|
||||||
|
if ((newn ^ nelems) <= nelems || /* still the same power of 2 limit? */
|
||||||
|
(nelems > 0 && newn < MINSIZE)) /* or block already is MINSIZE? */
|
||||||
|
return block; /* do not need to reallocate */
|
||||||
|
else { /* it crossed a power of 2 boundary; grow to next power */
|
||||||
|
if (newn >= limit)
|
||||||
|
lua_error(errormsg);
|
||||||
|
newn = power2(newn);
|
||||||
|
if (newn > limit)
|
||||||
|
newn = limit;
|
||||||
|
return luaM_realloc(block, newn*size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** generic allocation routine.
|
** generic allocation routine.
|
||||||
** real ANSI systems do not need some of these tests,
|
|
||||||
** since realloc(NULL, s)==malloc(s) and realloc(b, 0)==free(b).
|
|
||||||
** But some systems (e.g. Sun OS) are not that ANSI...
|
|
||||||
*/
|
*/
|
||||||
void *luaM_realloc (void *block, unsigned long size)
|
void *luaM_realloc (void *block, unsigned long size) {
|
||||||
{
|
|
||||||
size_t s = (size_t)size;
|
size_t s = (size_t)size;
|
||||||
if (s != size)
|
if (s != size)
|
||||||
lua_error("Allocation Error: Block too big");
|
lua_error("memory allocation error: block too big");
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
if (block) {
|
free(block); /* block may be NULL, that is OK for free */
|
||||||
free(block);
|
|
||||||
}
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
block = block ? realloc(block, s) : malloc(s);
|
block = realloc(block, s);
|
||||||
if (block == NULL)
|
if (block == NULL)
|
||||||
lua_error(memEM);
|
lua_error(memEM);
|
||||||
return block;
|
return block;
|
||||||
@@ -60,6 +78,15 @@ void *luaM_realloc (void *block, unsigned long size)
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
void *luaM_growaux (void *block, unsigned long nelems, int inc, int size,
|
||||||
|
char *errormsg, unsigned long limit) {
|
||||||
|
unsigned long newn = nelems+inc;
|
||||||
|
if (newn >= limit)
|
||||||
|
lua_error(errormsg);
|
||||||
|
return luaM_realloc(block, newn*size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#define HEADER (sizeof(double))
|
#define HEADER (sizeof(double))
|
||||||
|
|
||||||
#define MARK 55
|
#define MARK 55
|
||||||
@@ -68,8 +95,7 @@ unsigned long numblocks = 0;
|
|||||||
unsigned long totalmem = 0;
|
unsigned long totalmem = 0;
|
||||||
|
|
||||||
|
|
||||||
static void *checkblock (void *block)
|
static void *checkblock (void *block) {
|
||||||
{
|
|
||||||
unsigned long *b = (unsigned long *)((char *)block - HEADER);
|
unsigned long *b = (unsigned long *)((char *)block - HEADER);
|
||||||
unsigned long size = *b;
|
unsigned long size = *b;
|
||||||
LUA_ASSERT(*(((char *)b)+size+HEADER) == MARK,
|
LUA_ASSERT(*(((char *)b)+size+HEADER) == MARK,
|
||||||
@@ -80,26 +106,22 @@ static void *checkblock (void *block)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void *luaM_realloc (void *block, unsigned long size)
|
void *luaM_realloc (void *block, unsigned long size) {
|
||||||
{
|
|
||||||
unsigned long realsize = HEADER+size+1;
|
unsigned long realsize = HEADER+size+1;
|
||||||
if (realsize != (size_t)realsize)
|
if (realsize != (size_t)realsize)
|
||||||
lua_error("Allocation Error: Block too big");
|
lua_error("memory allocation error: block too big");
|
||||||
if (size == 0) { /* ANSI dosen't need this, but some machines... */
|
if (size == 0) {
|
||||||
if (block) {
|
if (block) {
|
||||||
unsigned long *b = (unsigned long *)((char *)block - HEADER);
|
unsigned long *b = (unsigned long *)((char *)block - HEADER);
|
||||||
memset(block, -1, *b); /* erase block */
|
memset(block, -1, *b); /* erase block */
|
||||||
block = checkblock(block);
|
block = checkblock(block);
|
||||||
free(block);
|
|
||||||
}
|
}
|
||||||
|
free(block);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (block) {
|
if (block)
|
||||||
block = checkblock(block);
|
block = checkblock(block);
|
||||||
block = (unsigned long *)realloc(block, realsize);
|
block = (unsigned long *)realloc(block, realsize);
|
||||||
}
|
|
||||||
else
|
|
||||||
block = (unsigned long *)malloc(realsize);
|
|
||||||
if (block == NULL)
|
if (block == NULL)
|
||||||
lua_error(memEM);
|
lua_error(memEM);
|
||||||
totalmem += size;
|
totalmem += size;
|
||||||
|
|||||||
16
lmem.h
16
lmem.h
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lmem.h,v 1.4 1997/12/01 20:30:44 roberto Exp roberto $
|
** $Id: lmem.h,v 1.7 1999/02/25 15:16:26 roberto Exp roberto $
|
||||||
** Interface to Memory Manager
|
** Interface to Memory Manager
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -8,10 +8,7 @@
|
|||||||
#define lmem_h
|
#define lmem_h
|
||||||
|
|
||||||
|
|
||||||
#ifndef NULL
|
#include <stdlib.h>
|
||||||
#define NULL 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* memory error messages */
|
/* memory error messages */
|
||||||
#define codeEM "code size overflow"
|
#define codeEM "code size overflow"
|
||||||
@@ -19,18 +16,19 @@
|
|||||||
#define refEM "reference table overflow"
|
#define refEM "reference table overflow"
|
||||||
#define tableEM "table overflow"
|
#define tableEM "table overflow"
|
||||||
#define memEM "not enough memory"
|
#define memEM "not enough memory"
|
||||||
|
#define arrEM "internal array bigger than `int' limit"
|
||||||
|
|
||||||
void *luaM_realloc (void *oldblock, unsigned long size);
|
void *luaM_realloc (void *oldblock, unsigned long size);
|
||||||
int luaM_growaux (void **block, unsigned long nelems, int size,
|
void *luaM_growaux (void *block, unsigned long nelems, int inc, int size,
|
||||||
char *errormsg, unsigned long limit);
|
char *errormsg, unsigned long limit);
|
||||||
|
|
||||||
#define luaM_free(b) luaM_realloc((b), 0)
|
#define luaM_free(b) luaM_realloc((b), 0)
|
||||||
#define luaM_malloc(t) luaM_realloc(NULL, (t))
|
#define luaM_malloc(t) luaM_realloc(NULL, (t))
|
||||||
#define luaM_new(t) ((t *)luaM_malloc(sizeof(t)))
|
#define luaM_new(t) ((t *)luaM_malloc(sizeof(t)))
|
||||||
#define luaM_newvector(n,t) ((t *)luaM_malloc((n)*sizeof(t)))
|
#define luaM_newvector(n,t) ((t *)luaM_malloc((n)*sizeof(t)))
|
||||||
#define luaM_growvector(old,n,t,e,l) \
|
#define luaM_growvector(v,nelems,inc,t,e,l) \
|
||||||
(luaM_growaux((void**)old,n,sizeof(t),e,l))
|
((v)=(t *)luaM_growaux(v,nelems,inc,sizeof(t),e,l))
|
||||||
#define luaM_reallocvector(v,n,t) ((t *)luaM_realloc(v,(n)*sizeof(t)))
|
#define luaM_reallocvector(v,n,t) ((v)=(t *)luaM_realloc(v,(n)*sizeof(t)))
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|||||||
76
lobject.c
76
lobject.c
@@ -1,9 +1,10 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lobject.c,v 1.12 1998/06/18 16:57:03 roberto Exp roberto $
|
** $Id: lobject.c,v 1.18 1999/02/26 15:48:30 roberto Exp roberto $
|
||||||
** Some generic functions over Lua objects
|
** Some generic functions over Lua objects
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "lobject.h"
|
#include "lobject.h"
|
||||||
@@ -34,14 +35,12 @@ int luaO_redimension (int oldsize)
|
|||||||
if (dimensions[i] > oldsize)
|
if (dimensions[i] > oldsize)
|
||||||
return dimensions[i];
|
return dimensions[i];
|
||||||
}
|
}
|
||||||
lua_error("table overflow");
|
lua_error("tableEM");
|
||||||
return 0; /* to avoid warnings */
|
return 0; /* to avoid warnings */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int luaO_equalObj (TObject *t1, TObject *t2)
|
int luaO_equalval (TObject *t1, TObject *t2) {
|
||||||
{
|
|
||||||
if (ttype(t1) != ttype(t2)) return 0;
|
|
||||||
switch (ttype(t1)) {
|
switch (ttype(t1)) {
|
||||||
case LUA_T_NIL: return 1;
|
case LUA_T_NIL: return 1;
|
||||||
case LUA_T_NUMBER: return nvalue(t1) == nvalue(t2);
|
case LUA_T_NUMBER: return nvalue(t1) == nvalue(t2);
|
||||||
@@ -64,20 +63,67 @@ void luaO_insertlist (GCnode *root, GCnode *node)
|
|||||||
node->marked = 0;
|
node->marked = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef OLD_ANSI
|
#ifdef OLD_ANSI
|
||||||
void luaO_memup (void *dest, void *src, int size)
|
void luaO_memup (void *dest, void *src, int size) {
|
||||||
{
|
while (size--)
|
||||||
char *d = dest;
|
((char *)dest)[size]=((char *)src)[size];
|
||||||
char *s = src;
|
|
||||||
while (size--) d[size]=s[size];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void luaO_memdown (void *dest, void *src, int size)
|
void luaO_memdown (void *dest, void *src, int size) {
|
||||||
{
|
|
||||||
char *d = dest;
|
|
||||||
char *s = src;
|
|
||||||
int i;
|
int i;
|
||||||
for (i=0; i<size; i++) d[i]=s[i];
|
for (i=0; i<size; i++)
|
||||||
|
((char *)dest)[i]=((char *)src)[i];
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static double expten (unsigned int e) {
|
||||||
|
double exp = 10.0;
|
||||||
|
double res = 1.0;
|
||||||
|
for (; e; e>>=1) {
|
||||||
|
if (e & 1) res *= exp;
|
||||||
|
exp *= exp;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double luaO_str2d (char *s) { /* LUA_NUMBER */
|
||||||
|
double a = 0.0;
|
||||||
|
int point = 0;
|
||||||
|
while (isdigit((unsigned char)*s)) {
|
||||||
|
a = 10.0*a + (*(s++)-'0');
|
||||||
|
}
|
||||||
|
if (*s == '.') {
|
||||||
|
s++;
|
||||||
|
while (isdigit((unsigned char)*s)) {
|
||||||
|
a = 10.0*a + (*(s++)-'0');
|
||||||
|
point++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (toupper((unsigned char)*s) == 'E') {
|
||||||
|
int e = 0;
|
||||||
|
int sig = 1;
|
||||||
|
s++;
|
||||||
|
if (*s == '-') {
|
||||||
|
s++;
|
||||||
|
sig = -1;
|
||||||
|
}
|
||||||
|
else if (*s == '+') s++;
|
||||||
|
if (!isdigit((unsigned char)*s)) return -1; /* no digit in the exponent? */
|
||||||
|
do {
|
||||||
|
e = 10*e + (*(s++)-'0');
|
||||||
|
} while (isdigit((unsigned char)*s));
|
||||||
|
point -= sig*e;
|
||||||
|
}
|
||||||
|
while (isspace((unsigned char)*s)) s++;
|
||||||
|
if (*s != '\0') return -1; /* invalid trailing characters? */
|
||||||
|
if (point > 0)
|
||||||
|
a /= expten(point);
|
||||||
|
else if (point < 0)
|
||||||
|
a *= expten(-point);
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
24
lobject.h
24
lobject.h
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lobject.h,v 1.20 1998/06/11 18:21:37 roberto Exp roberto $
|
** $Id: lobject.h,v 1.27 1999/03/04 21:17:26 roberto Exp roberto $
|
||||||
** Type definitions for Lua objects
|
** Type definitions for Lua objects
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -32,10 +32,6 @@
|
|||||||
#define LUA_NUM_TYPE double
|
#define LUA_NUM_TYPE double
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
** format to convert number to strings
|
|
||||||
*/
|
|
||||||
#define NUMBER_FMT "%g"
|
|
||||||
|
|
||||||
typedef LUA_NUM_TYPE real;
|
typedef LUA_NUM_TYPE real;
|
||||||
|
|
||||||
@@ -45,13 +41,6 @@ typedef unsigned char Byte; /* unsigned 8 bits */
|
|||||||
|
|
||||||
#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */
|
#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */
|
||||||
|
|
||||||
/* maximum value of a word of 2 bytes (-2 for safety); must fit in an "int" */
|
|
||||||
#if MAX_INT < 65534
|
|
||||||
#define MAX_WORD MAX_INT
|
|
||||||
#else
|
|
||||||
#define MAX_WORD 65534
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef unsigned int IntPoint; /* unsigned with same size as a pointer (for hashing) */
|
typedef unsigned int IntPoint; /* unsigned with same size as a pointer (for hashing) */
|
||||||
|
|
||||||
|
|
||||||
@@ -75,7 +64,6 @@ typedef enum {
|
|||||||
LUA_T_LINE = -11
|
LUA_T_LINE = -11
|
||||||
} lua_Type;
|
} lua_Type;
|
||||||
|
|
||||||
#define NUM_TYPES 11
|
|
||||||
#define NUM_TAGS 7
|
#define NUM_TAGS 7
|
||||||
|
|
||||||
|
|
||||||
@@ -139,7 +127,7 @@ typedef struct TProtoFunc {
|
|||||||
int nconsts;
|
int nconsts;
|
||||||
Byte *code; /* ends with opcode ENDCODE */
|
Byte *code; /* ends with opcode ENDCODE */
|
||||||
int lineDefined;
|
int lineDefined;
|
||||||
TaggedString *fileName;
|
TaggedString *source;
|
||||||
struct LocVar *locvars; /* ends with line = -1 */
|
struct LocVar *locvars; /* ends with line = -1 */
|
||||||
} TProtoFunc;
|
} TProtoFunc;
|
||||||
|
|
||||||
@@ -192,11 +180,17 @@ typedef struct Hash {
|
|||||||
|
|
||||||
extern char *luaO_typenames[];
|
extern char *luaO_typenames[];
|
||||||
|
|
||||||
|
#define luaO_typename(o) luaO_typenames[-ttype(o)]
|
||||||
|
|
||||||
|
|
||||||
extern TObject luaO_nilobject;
|
extern TObject luaO_nilobject;
|
||||||
|
|
||||||
int luaO_equalObj (TObject *t1, TObject *t2);
|
#define luaO_equalObj(t1,t2) ((ttype(t1) != ttype(t2)) ? 0 \
|
||||||
|
: luaO_equalval(t1,t2))
|
||||||
|
int luaO_equalval (TObject *t1, TObject *t2);
|
||||||
int luaO_redimension (int oldsize);
|
int luaO_redimension (int oldsize);
|
||||||
void luaO_insertlist (GCnode *root, GCnode *node);
|
void luaO_insertlist (GCnode *root, GCnode *node);
|
||||||
|
double luaO_str2d (char *s);
|
||||||
|
|
||||||
#ifdef OLD_ANSI
|
#ifdef OLD_ANSI
|
||||||
void luaO_memup (void *dest, void *src, int size);
|
void luaO_memup (void *dest, void *src, int size);
|
||||||
|
|||||||
221
lopcodes.h
221
lopcodes.h
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lopcodes.h,v 1.17 1998/03/25 18:52:29 roberto Exp roberto $
|
** $Id: lopcodes.h,v 1.31 1999/03/05 21:16:07 roberto Exp roberto $
|
||||||
** Opcodes for Lua virtual machine
|
** Opcodes for Lua virtual machine
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -10,172 +10,129 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
** NOTICE: variants of the same opcode must be consecutive: First, those
|
** NOTICE: variants of the same opcode must be consecutive: First, those
|
||||||
** with byte parameter, then with built-in parameters, and last with
|
** with word parameter, then with byte parameter.
|
||||||
** word parameter.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
/* name parm before after side effect
|
/* name parm before after side effect
|
||||||
-----------------------------------------------------------------------------*/
|
-----------------------------------------------------------------------------*/
|
||||||
ENDCODE,/* - - - */
|
ENDCODE,/* - - (return) */
|
||||||
|
RETCODE,/* b - (return) */
|
||||||
|
|
||||||
PUSHNIL,/* b - nil_0...nil_b */
|
CALL,/* b c v_c...v_1 f r_b...r_1 f(v1,...,v_c) */
|
||||||
PUSHNIL0,/* - - nil */
|
|
||||||
|
|
||||||
PUSHNUMBER,/* b - (float)b */
|
TAILCALL,/* b c v_c...v_1 f (return) f(v1,...,v_c) */
|
||||||
PUSHNUMBER0,/* - - 0.0 */
|
|
||||||
PUSHNUMBER1,/* - - 1.0 */
|
|
||||||
PUSHNUMBER2,/* - - 2.0 */
|
|
||||||
PUSHNUMBERW,/* w - (float)w */
|
|
||||||
|
|
||||||
PUSHCONSTANT,/* b - CNST[b] */
|
PUSHNIL,/* b - nil_0...nil_b */
|
||||||
PUSHCONSTANT0,/*- - CNST[0] */
|
POP,/* b a_b...a_1 - */
|
||||||
PUSHCONSTANT1,/*- - CNST[1] */
|
|
||||||
PUSHCONSTANT2,/*- - CNST[2] */
|
|
||||||
PUSHCONSTANT3,/*- - CNST[3] */
|
|
||||||
PUSHCONSTANT4,/*- - CNST[4] */
|
|
||||||
PUSHCONSTANT5,/*- - CNST[5] */
|
|
||||||
PUSHCONSTANT6,/*- - CNST[6] */
|
|
||||||
PUSHCONSTANT7,/*- - CNST[7] */
|
|
||||||
PUSHCONSTANTW,/*w - CNST[w] */
|
|
||||||
|
|
||||||
PUSHUPVALUE,/* b - Closure[b] */
|
PUSHNUMBERW,/* w - (float)w */
|
||||||
PUSHUPVALUE0,/* - - Closure[0] */
|
PUSHNUMBER,/* b - (float)b */
|
||||||
PUSHUPVALUE1,/* - - Closure[1] */
|
|
||||||
|
|
||||||
PUSHLOCAL,/* b - LOC[b] */
|
PUSHNUMBERNEGW,/* w - (float)-w */
|
||||||
PUSHLOCAL0,/* - - LOC[0] */
|
PUSHNUMBERNEG,/* b - (float)-b */
|
||||||
PUSHLOCAL1,/* - - LOC[1] */
|
|
||||||
PUSHLOCAL2,/* - - LOC[2] */
|
|
||||||
PUSHLOCAL3,/* - - LOC[3] */
|
|
||||||
PUSHLOCAL4,/* - - LOC[4] */
|
|
||||||
PUSHLOCAL5,/* - - LOC[5] */
|
|
||||||
PUSHLOCAL6,/* - - LOC[6] */
|
|
||||||
PUSHLOCAL7,/* - - LOC[7] */
|
|
||||||
|
|
||||||
GETGLOBAL,/* b - VAR[CNST[b]] */
|
PUSHCONSTANTW,/*w - CNST[w] */
|
||||||
GETGLOBAL0,/* - - VAR[CNST[0]] */
|
PUSHCONSTANT,/* b - CNST[b] */
|
||||||
GETGLOBAL1,/* - - VAR[CNST[1]] */
|
|
||||||
GETGLOBAL2,/* - - VAR[CNST[2]] */
|
|
||||||
GETGLOBAL3,/* - - VAR[CNST[3]] */
|
|
||||||
GETGLOBAL4,/* - - VAR[CNST[4]] */
|
|
||||||
GETGLOBAL5,/* - - VAR[CNST[5]] */
|
|
||||||
GETGLOBAL6,/* - - VAR[CNST[6]] */
|
|
||||||
GETGLOBAL7,/* - - VAR[CNST[7]] */
|
|
||||||
GETGLOBALW,/* w - VAR[CNST[w]] */
|
|
||||||
|
|
||||||
GETTABLE,/* - i t t[i] */
|
PUSHUPVALUE,/* b - Closure[b] */
|
||||||
|
|
||||||
GETDOTTED,/* b t t[CNST[b]] */
|
PUSHLOCAL,/* b - LOC[b] */
|
||||||
GETDOTTED0,/* - t t[CNST[0]] */
|
|
||||||
GETDOTTED1,/* - t t[CNST[1]] */
|
|
||||||
GETDOTTED2,/* - t t[CNST[2]] */
|
|
||||||
GETDOTTED3,/* - t t[CNST[3]] */
|
|
||||||
GETDOTTED4,/* - t t[CNST[4]] */
|
|
||||||
GETDOTTED5,/* - t t[CNST[5]] */
|
|
||||||
GETDOTTED6,/* - t t[CNST[6]] */
|
|
||||||
GETDOTTED7,/* - t t[CNST[7]] */
|
|
||||||
GETDOTTEDW,/* w t t[CNST[w]] */
|
|
||||||
|
|
||||||
PUSHSELF,/* b t t t[CNST[b]] */
|
GETGLOBALW,/* w - VAR[CNST[w]] */
|
||||||
PUSHSELF0,/* - t t t[CNST[0]] */
|
GETGLOBAL,/* b - VAR[CNST[b]] */
|
||||||
PUSHSELF1,/* - t t t[CNST[1]] */
|
|
||||||
PUSHSELF2,/* - t t t[CNST[2]] */
|
|
||||||
PUSHSELF3,/* - t t t[CNST[3]] */
|
|
||||||
PUSHSELF4,/* - t t t[CNST[4]] */
|
|
||||||
PUSHSELF5,/* - t t t[CNST[5]] */
|
|
||||||
PUSHSELF6,/* - t t t[CNST[6]] */
|
|
||||||
PUSHSELF7,/* - t t t[CNST[7]] */
|
|
||||||
PUSHSELFW,/* w t t t[CNST[w]] */
|
|
||||||
|
|
||||||
CREATEARRAY,/* b - newarray(size = b) */
|
GETTABLE,/* - i t t[i] */
|
||||||
CREATEARRAY0,/* - - newarray(size = 0) */
|
|
||||||
CREATEARRAY1,/* - - newarray(size = 1) */
|
|
||||||
CREATEARRAYW,/* w - newarray(size = w) */
|
|
||||||
|
|
||||||
SETLOCAL,/* b x - LOC[b]=x */
|
GETDOTTEDW,/* w t t[CNST[w]] */
|
||||||
SETLOCAL0,/* - x - LOC[0]=x */
|
GETDOTTED,/* b t t[CNST[b]] */
|
||||||
SETLOCAL1,/* - x - LOC[1]=x */
|
|
||||||
SETLOCAL2,/* - x - LOC[2]=x */
|
|
||||||
SETLOCAL3,/* - x - LOC[3]=x */
|
|
||||||
SETLOCAL4,/* - x - LOC[4]=x */
|
|
||||||
SETLOCAL5,/* - x - LOC[5]=x */
|
|
||||||
SETLOCAL6,/* - x - LOC[6]=x */
|
|
||||||
SETLOCAL7,/* - x - LOC[7]=x */
|
|
||||||
|
|
||||||
SETGLOBAL,/* b x - VAR[CNST[b]]=x */
|
PUSHSELFW,/* w t t t[CNST[w]] */
|
||||||
SETGLOBAL0,/* - x - VAR[CNST[0]]=x */
|
PUSHSELF,/* b t t t[CNST[b]] */
|
||||||
SETGLOBAL1,/* - x - VAR[CNST[1]]=x */
|
|
||||||
SETGLOBAL2,/* - x - VAR[CNST[2]]=x */
|
|
||||||
SETGLOBAL3,/* - x - VAR[CNST[3]]=x */
|
|
||||||
SETGLOBAL4,/* - x - VAR[CNST[4]]=x */
|
|
||||||
SETGLOBAL5,/* - x - VAR[CNST[5]]=x */
|
|
||||||
SETGLOBAL6,/* - x - VAR[CNST[6]]=x */
|
|
||||||
SETGLOBAL7,/* - x - VAR[CNST[7]]=x */
|
|
||||||
SETGLOBALW,/* w x - VAR[CNST[w]]=x */
|
|
||||||
|
|
||||||
SETTABLE0,/* - v i t - t[i]=v */
|
CREATEARRAYW,/* w - newarray(size = w) */
|
||||||
|
CREATEARRAY,/* b - newarray(size = b) */
|
||||||
|
|
||||||
SETTABLE,/* b v a_b...a_1 i t a_b...a_1 i t t[i]=v */
|
SETLOCAL,/* b x - LOC[b]=x */
|
||||||
|
|
||||||
SETLIST,/* b c v_c...v_1 t - t[i+b*FPF]=v_i */
|
SETGLOBALW,/* w x - VAR[CNST[w]]=x */
|
||||||
SETLIST0,/* b v_b...v_1 t - t[i]=v_i */
|
SETGLOBAL,/* b x - VAR[CNST[b]]=x */
|
||||||
SETLISTW,/* w c v_c...v_1 t - t[i+w*FPF]=v_i */
|
|
||||||
|
|
||||||
SETMAP,/* b v_b k_b ...v_0 k_0 t t t[k_i]=v_i */
|
SETTABLEPOP,/* - v i t - t[i]=v */
|
||||||
SETMAP0,/* - v_0 k_0 t t t[k_0]=v_0 */
|
|
||||||
|
|
||||||
EQOP,/* - y x (x==y)? 1 : nil */
|
SETTABLE,/* b v a_b...a_1 i t a_b...a_1 i t t[i]=v */
|
||||||
NEQOP,/* - y x (x~=y)? 1 : nil */
|
|
||||||
LTOP,/* - y x (x<y)? 1 : nil */
|
|
||||||
LEOP,/* - y x (x<y)? 1 : nil */
|
|
||||||
GTOP,/* - y x (x>y)? 1 : nil */
|
|
||||||
GEOP,/* - y x (x>=y)? 1 : nil */
|
|
||||||
ADDOP,/* - y x x+y */
|
|
||||||
SUBOP,/* - y x x-y */
|
|
||||||
MULTOP,/* - y x x*y */
|
|
||||||
DIVOP,/* - y x x/y */
|
|
||||||
POWOP,/* - y x x^y */
|
|
||||||
CONCOP,/* - y x x..y */
|
|
||||||
MINUSOP,/* - x -x */
|
|
||||||
NOTOP,/* - x (x==nil)? 1 : nil */
|
|
||||||
|
|
||||||
ONTJMP,/* b x (x!=nil)? x : - (x!=nil)? PC+=b */
|
SETLISTW,/* w c v_c...v_1 t t t[i+w*FPF]=v_i */
|
||||||
ONTJMPW,/* w x (x!=nil)? x : - (x!=nil)? PC+=w */
|
SETLIST,/* b c v_c...v_1 t t t[i+b*FPF]=v_i */
|
||||||
ONFJMP,/* b x (x==nil)? x : - (x==nil)? PC+=b */
|
|
||||||
ONFJMPW,/* w x (x==nil)? x : - (x==nil)? PC+=w */
|
|
||||||
JMP,/* b - - PC+=b */
|
|
||||||
JMPW,/* w - - PC+=w */
|
|
||||||
IFFJMP,/* b x - (x==nil)? PC+=b */
|
|
||||||
IFFJMPW,/* w x - (x==nil)? PC+=w */
|
|
||||||
IFTUPJMP,/* b x - (x!=nil)? PC-=b */
|
|
||||||
IFTUPJMPW,/* w x - (x!=nil)? PC-=w */
|
|
||||||
IFFUPJMP,/* b x - (x==nil)? PC-=b */
|
|
||||||
IFFUPJMPW,/* w x - (x==nil)? PC-=w */
|
|
||||||
|
|
||||||
CLOSURE,/* b c v_c...v_1 closure(CNST[b], v_c...v_1) */
|
SETMAP,/* b v_b k_b ...v_0 k_0 t t t[k_i]=v_i */
|
||||||
CLOSUREW,/* w c v_b...v_1 closure(CNST[w], v_c...v_1) */
|
|
||||||
|
|
||||||
CALLFUNC,/* b c v_c...v_1 f r_b...r_1 f(v1,...,v_c) */
|
NEQOP,/* - y x (x~=y)? 1 : nil */
|
||||||
CALLFUNC0,/* b v_b...v_1 f - f(v1,...,v_b) */
|
EQOP,/* - y x (x==y)? 1 : nil */
|
||||||
CALLFUNC1,/* b v_b...v_1 f r_1 f(v1,...,v_b) */
|
LTOP,/* - y x (x<y)? 1 : nil */
|
||||||
|
LEOP,/* - y x (x<y)? 1 : nil */
|
||||||
|
GTOP,/* - y x (x>y)? 1 : nil */
|
||||||
|
GEOP,/* - y x (x>=y)? 1 : nil */
|
||||||
|
ADDOP,/* - y x x+y */
|
||||||
|
SUBOP,/* - y x x-y */
|
||||||
|
MULTOP,/* - y x x*y */
|
||||||
|
DIVOP,/* - y x x/y */
|
||||||
|
POWOP,/* - y x x^y */
|
||||||
|
CONCOP,/* - y x x..y */
|
||||||
|
MINUSOP,/* - x -x */
|
||||||
|
NOTOP,/* - x (x==nil)? 1 : nil */
|
||||||
|
|
||||||
RETCODE,/* b - - */
|
ONTJMPW,/* w x (x!=nil)? x : - (x!=nil)? PC+=w */
|
||||||
|
ONTJMP,/* b x (x!=nil)? x : - (x!=nil)? PC+=b */
|
||||||
|
ONFJMPW,/* w x (x==nil)? x : - (x==nil)? PC+=w */
|
||||||
|
ONFJMP,/* b x (x==nil)? x : - (x==nil)? PC+=b */
|
||||||
|
JMPW,/* w - - PC+=w */
|
||||||
|
JMP,/* b - - PC+=b */
|
||||||
|
IFFJMPW,/* w x - (x==nil)? PC+=w */
|
||||||
|
IFFJMP,/* b x - (x==nil)? PC+=b */
|
||||||
|
IFTUPJMPW,/* w x - (x!=nil)? PC-=w */
|
||||||
|
IFTUPJMP,/* b x - (x!=nil)? PC-=b */
|
||||||
|
IFFUPJMPW,/* w x - (x==nil)? PC-=w */
|
||||||
|
IFFUPJMP,/* b x - (x==nil)? PC-=b */
|
||||||
|
|
||||||
SETLINE,/* b - - LINE=b */
|
CLOSUREW,/* w c v_c...v_1 closure(CNST[w], v_c...v_1) */
|
||||||
SETLINEW,/* w - - LINE=w */
|
CLOSURE,/* b c v_c...v_1 closure(CNST[b], v_c...v_1) */
|
||||||
|
|
||||||
POP,/* b - - TOP-=(b+1) */
|
SETLINEW,/* w - - LINE=w */
|
||||||
POP0,/* - - - TOP-=1 */
|
SETLINE,/* b - - LINE=b */
|
||||||
POP1/* - - - TOP-=2 */
|
|
||||||
|
LONGARGW,/* w (add w*(1<<16) to arg of next instruction) */
|
||||||
|
LONGARG,/* b (add b*(1<<16) to arg of next instruction) */
|
||||||
|
|
||||||
|
CHECKSTACK /* b (assert #temporaries == b; only for internal debuging!) */
|
||||||
|
|
||||||
} OpCode;
|
} OpCode;
|
||||||
|
|
||||||
|
|
||||||
#define RFIELDS_PER_FLUSH 32 /* records (SETMAP) */
|
#define RFIELDS_PER_FLUSH 32 /* records (SETMAP) */
|
||||||
#define LFIELDS_PER_FLUSH 64 /* lists (SETLIST) */
|
#define LFIELDS_PER_FLUSH 64 /* FPF - lists (SETLIST) */
|
||||||
|
|
||||||
#define ZEROVARARG 64
|
#define ZEROVARARG 64
|
||||||
|
|
||||||
|
|
||||||
|
/* maximum value of an arg of 3 bytes; must fit in an "int" */
|
||||||
|
#if MAX_INT < (1<<24)
|
||||||
|
#define MAX_ARG MAX_INT
|
||||||
|
#else
|
||||||
|
#define MAX_ARG ((1<<24)-1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* maximum value of a word of 2 bytes; cannot be bigger than MAX_ARG */
|
||||||
|
#if MAX_ARG < (1<<16)
|
||||||
|
#define MAX_WORD MAX_ARG
|
||||||
|
#else
|
||||||
|
#define MAX_WORD ((1<<16)-1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* maximum value of a byte */
|
||||||
|
#define MAX_BYTE ((1<<8)-1)
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lparser.h,v 1.1 1997/09/16 19:25:59 roberto Exp roberto $
|
** $Id: lparser.h,v 1.2 1997/12/22 20:57:18 roberto Exp roberto $
|
||||||
** Syntax analizer and code generator
|
** LL(1) Parser and code generator for Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
22
lstate.c
22
lstate.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lstate.c,v 1.5 1997/12/17 20:48:58 roberto Exp roberto $
|
** $Id: lstate.c,v 1.9 1999/02/25 15:17:01 roberto Exp roberto $
|
||||||
** Global State
|
** Global State
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -24,11 +24,18 @@ void lua_open (void)
|
|||||||
{
|
{
|
||||||
if (lua_state) return;
|
if (lua_state) return;
|
||||||
lua_state = luaM_new(lua_State);
|
lua_state = luaM_new(lua_State);
|
||||||
L->numCblocks = 0;
|
|
||||||
L->Cstack.base = 0;
|
L->Cstack.base = 0;
|
||||||
L->Cstack.lua2C = 0;
|
L->Cstack.lua2C = 0;
|
||||||
L->Cstack.num = 0;
|
L->Cstack.num = 0;
|
||||||
L->errorJmp = NULL;
|
L->errorJmp = NULL;
|
||||||
|
L->Mbuffer = NULL;
|
||||||
|
L->Mbuffbase = 0;
|
||||||
|
L->Mbuffsize = 0;
|
||||||
|
L->Mbuffnext = 0;
|
||||||
|
L->numCblocks = 0;
|
||||||
|
L->debug = 0;
|
||||||
|
L->callhook = NULL;
|
||||||
|
L->linehook = NULL;
|
||||||
L->rootproto.next = NULL;
|
L->rootproto.next = NULL;
|
||||||
L->rootproto.marked = 0;
|
L->rootproto.marked = 0;
|
||||||
L->rootcl.next = NULL;
|
L->rootcl.next = NULL;
|
||||||
@@ -37,12 +44,9 @@ void lua_open (void)
|
|||||||
L->rootglobal.marked = 0;
|
L->rootglobal.marked = 0;
|
||||||
L->roottable.next = NULL;
|
L->roottable.next = NULL;
|
||||||
L->roottable.marked = 0;
|
L->roottable.marked = 0;
|
||||||
|
L->IMtable = NULL;
|
||||||
L->refArray = NULL;
|
L->refArray = NULL;
|
||||||
L->refSize = 0;
|
L->refSize = 0;
|
||||||
L->Mbuffsize = 0;
|
|
||||||
L->Mbuffnext = 0;
|
|
||||||
L->Mbuffbase = NULL;
|
|
||||||
L->Mbuffer = NULL;
|
|
||||||
L->GCthreshold = GARBAGE_BLOCK;
|
L->GCthreshold = GARBAGE_BLOCK;
|
||||||
L->nblocks = 0;
|
L->nblocks = 0;
|
||||||
luaD_init();
|
luaD_init();
|
||||||
@@ -78,9 +82,3 @@ void lua_close (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
lua_State *lua_setstate (lua_State *st) {
|
|
||||||
lua_State *old = lua_state;
|
|
||||||
lua_state = st;
|
|
||||||
return old;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
14
lstate.h
14
lstate.h
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lstate.h,v 1.10 1998/06/19 16:14:09 roberto Exp roberto $
|
** $Id: lstate.h,v 1.15 1999/02/25 15:17:01 roberto Exp roberto $
|
||||||
** Global State
|
** Global State
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include "lobject.h"
|
#include "lobject.h"
|
||||||
#include "lua.h"
|
#include "lua.h"
|
||||||
|
#include "luadebug.h"
|
||||||
|
|
||||||
|
|
||||||
#define MAX_C_BLOCKS 10
|
#define MAX_C_BLOCKS 10
|
||||||
@@ -55,20 +56,21 @@ struct lua_State {
|
|||||||
struct C_Lua_Stack Cstack; /* C2lua struct */
|
struct C_Lua_Stack Cstack; /* C2lua struct */
|
||||||
jmp_buf *errorJmp; /* current error recover point */
|
jmp_buf *errorJmp; /* current error recover point */
|
||||||
char *Mbuffer; /* global buffer */
|
char *Mbuffer; /* global buffer */
|
||||||
char *Mbuffbase; /* current first position of Mbuffer */
|
int Mbuffbase; /* current first position of Mbuffer */
|
||||||
int Mbuffsize; /* size of Mbuffer */
|
int Mbuffsize; /* size of Mbuffer */
|
||||||
int Mbuffnext; /* next position to fill in Mbuffer */
|
int Mbuffnext; /* next position to fill in Mbuffer */
|
||||||
struct C_Lua_Stack Cblocks[MAX_C_BLOCKS];
|
struct C_Lua_Stack Cblocks[MAX_C_BLOCKS];
|
||||||
int numCblocks; /* number of nested Cblocks */
|
int numCblocks; /* number of nested Cblocks */
|
||||||
|
int debug;
|
||||||
|
lua_CHFunction callhook;
|
||||||
|
lua_LHFunction linehook;
|
||||||
/* global state */
|
/* global state */
|
||||||
TObject errorim; /* error tag method */
|
|
||||||
GCnode rootproto; /* list of all prototypes */
|
GCnode rootproto; /* list of all prototypes */
|
||||||
GCnode rootcl; /* list of all closures */
|
GCnode rootcl; /* list of all closures */
|
||||||
GCnode roottable; /* list of all tables */
|
GCnode roottable; /* list of all tables */
|
||||||
GCnode rootglobal; /* list of strings with global values */
|
GCnode rootglobal; /* list of strings with global values */
|
||||||
stringtable *string_root; /* array of hash tables for strings and udata */
|
stringtable *string_root; /* array of hash tables for strings and udata */
|
||||||
struct IM *IMtable; /* table for tag methods */
|
struct IM *IMtable; /* table for tag methods */
|
||||||
int IMtable_size; /* size of IMtable */
|
|
||||||
int last_tag; /* last used tag in IMtable */
|
int last_tag; /* last used tag in IMtable */
|
||||||
struct ref *refArray; /* locked objects */
|
struct ref *refArray; /* locked objects */
|
||||||
int refSize; /* size of refArray */
|
int refSize; /* size of refArray */
|
||||||
@@ -77,10 +79,8 @@ struct lua_State {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
extern lua_State *lua_state;
|
|
||||||
|
|
||||||
|
|
||||||
#define L lua_state
|
#define L lua_state
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
139
lstring.c
139
lstring.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lstring.c,v 1.12 1998/03/06 16:54:42 roberto Exp roberto $
|
** $Id: lstring.c,v 1.18 1999/02/08 16:28:48 roberto Exp roberto $
|
||||||
** String table (keeps all strings handled by Lua)
|
** String table (keeps all strings handled by Lua)
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -14,7 +14,9 @@
|
|||||||
#include "lua.h"
|
#include "lua.h"
|
||||||
|
|
||||||
|
|
||||||
#define NUM_HASHS 61
|
#define NUM_HASHSTR 31
|
||||||
|
#define NUM_HASHUDATA 31
|
||||||
|
#define NUM_HASHS (NUM_HASHSTR+NUM_HASHUDATA)
|
||||||
|
|
||||||
|
|
||||||
#define gcsizestring(l) (1+(l/64)) /* "weight" for a string with length 'l' */
|
#define gcsizestring(l) (1+(l/64)) /* "weight" for a string with length 'l' */
|
||||||
@@ -25,8 +27,7 @@ static TaggedString EMPTY = {{NULL, 2}, 0L, 0,
|
|||||||
{{{LUA_T_NIL, {NULL}}, 0L}}, {0}};
|
{{{LUA_T_NIL, {NULL}}, 0L}}, {0}};
|
||||||
|
|
||||||
|
|
||||||
void luaS_init (void)
|
void luaS_init (void) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
L->string_root = luaM_newvector(NUM_HASHS, stringtable);
|
L->string_root = luaM_newvector(NUM_HASHS, stringtable);
|
||||||
for (i=0; i<NUM_HASHS; i++) {
|
for (i=0; i<NUM_HASHS; i++) {
|
||||||
@@ -37,16 +38,14 @@ void luaS_init (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static unsigned long hash_s (char *s, long l)
|
static unsigned long hash_s (char *s, long l) {
|
||||||
{
|
unsigned long h = 0; /* seed */
|
||||||
unsigned long h = 0;
|
|
||||||
while (l--)
|
while (l--)
|
||||||
h = ((h<<5)-h)^(unsigned char)*(s++);
|
h = h ^ ((h<<5)+(h>>2)+(unsigned char)*(s++));
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int newsize (stringtable *tb)
|
static int newsize (stringtable *tb) {
|
||||||
{
|
|
||||||
int size = tb->size;
|
int size = tb->size;
|
||||||
int realuse = 0;
|
int realuse = 0;
|
||||||
int i;
|
int i;
|
||||||
@@ -54,16 +53,11 @@ static int newsize (stringtable *tb)
|
|||||||
for (i=0; i<size; i++)
|
for (i=0; i<size; i++)
|
||||||
if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY)
|
if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY)
|
||||||
realuse++;
|
realuse++;
|
||||||
if (2*(realuse+1) <= size) /* +1 is the new element */
|
return luaO_redimension((realuse+1)*2); /* +1 is the new element */
|
||||||
return size; /* don't need to grow, just rehash to clear EMPTYs */
|
|
||||||
else
|
|
||||||
return luaO_redimension(size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void grow (stringtable *tb)
|
static void grow (stringtable *tb) {
|
||||||
{
|
|
||||||
|
|
||||||
int ns = newsize(tb);
|
int ns = newsize(tb);
|
||||||
TaggedString **newhash = luaM_newvector(ns, TaggedString *);
|
TaggedString **newhash = luaM_newvector(ns, TaggedString *);
|
||||||
int i;
|
int i;
|
||||||
@@ -73,10 +67,13 @@ static void grow (stringtable *tb)
|
|||||||
tb->nuse = 0;
|
tb->nuse = 0;
|
||||||
for (i=0; i<tb->size; i++) {
|
for (i=0; i<tb->size; i++) {
|
||||||
if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY) {
|
if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY) {
|
||||||
int h = tb->hash[i]->hash%ns;
|
unsigned long h = tb->hash[i]->hash;
|
||||||
while (newhash[h])
|
int h1 = h%ns;
|
||||||
h = (h+1)%ns;
|
while (newhash[h1]) {
|
||||||
newhash[h] = tb->hash[i];
|
h1 += (h&(ns-2)) + 1; /* double hashing */
|
||||||
|
if (h1 >= ns) h1 -= ns;
|
||||||
|
}
|
||||||
|
newhash[h1] = tb->hash[i];
|
||||||
tb->nuse++;
|
tb->nuse++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -86,8 +83,7 @@ static void grow (stringtable *tb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static TaggedString *newone_s (char *str, long l, unsigned long h)
|
static TaggedString *newone_s (char *str, long l, unsigned long h) {
|
||||||
{
|
|
||||||
TaggedString *ts = (TaggedString *)luaM_malloc(sizeof(TaggedString)+l);
|
TaggedString *ts = (TaggedString *)luaM_malloc(sizeof(TaggedString)+l);
|
||||||
memcpy(ts->str, str, l);
|
memcpy(ts->str, str, l);
|
||||||
ts->str[l] = 0; /* ending 0 */
|
ts->str[l] = 0; /* ending 0 */
|
||||||
@@ -101,8 +97,7 @@ static TaggedString *newone_s (char *str, long l, unsigned long h)
|
|||||||
return ts;
|
return ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
static TaggedString *newone_u (char *buff, int tag, unsigned long h)
|
static TaggedString *newone_u (char *buff, int tag, unsigned long h) {
|
||||||
{
|
|
||||||
TaggedString *ts = luaM_new(TaggedString);
|
TaggedString *ts = luaM_new(TaggedString);
|
||||||
ts->u.d.v = buff;
|
ts->u.d.v = buff;
|
||||||
ts->u.d.tag = (tag == LUA_ANYTAG) ? 0 : tag;
|
ts->u.d.tag = (tag == LUA_ANYTAG) ? 0 : tag;
|
||||||
@@ -114,82 +109,79 @@ static TaggedString *newone_u (char *buff, int tag, unsigned long h)
|
|||||||
return ts;
|
return ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
static TaggedString *insert_s (char *str, long l, stringtable *tb)
|
static TaggedString *insert_s (char *str, long l, stringtable *tb) {
|
||||||
{
|
|
||||||
TaggedString *ts;
|
TaggedString *ts;
|
||||||
unsigned long h = hash_s(str, l);
|
unsigned long h = hash_s(str, l);
|
||||||
int size = tb->size;
|
int size = tb->size;
|
||||||
int i;
|
|
||||||
int j = -1;
|
int j = -1;
|
||||||
|
int h1;
|
||||||
if ((long)tb->nuse*3 >= (long)size*2) {
|
if ((long)tb->nuse*3 >= (long)size*2) {
|
||||||
grow(tb);
|
grow(tb);
|
||||||
size = tb->size;
|
size = tb->size;
|
||||||
}
|
}
|
||||||
for (i = h%size; (ts = tb->hash[i]) != NULL; ) {
|
h1 = h%size;
|
||||||
|
while ((ts = tb->hash[h1]) != NULL) {
|
||||||
if (ts == &EMPTY)
|
if (ts == &EMPTY)
|
||||||
j = i;
|
j = h1;
|
||||||
else if (ts->constindex >= 0 &&
|
else if (ts->u.s.len == l && (memcmp(str, ts->str, l) == 0))
|
||||||
ts->u.s.len == l &&
|
|
||||||
(memcmp(str, ts->str, l) == 0))
|
|
||||||
return ts;
|
return ts;
|
||||||
if (++i == size) i=0;
|
h1 += (h&(size-2)) + 1; /* double hashing */
|
||||||
|
if (h1 >= size) h1 -= size;
|
||||||
}
|
}
|
||||||
/* not found */
|
/* not found */
|
||||||
if (j != -1) /* is there an EMPTY space? */
|
if (j != -1) /* is there an EMPTY space? */
|
||||||
i = j;
|
h1 = j;
|
||||||
else
|
else
|
||||||
tb->nuse++;
|
tb->nuse++;
|
||||||
ts = tb->hash[i] = newone_s(str, l, h);
|
ts = tb->hash[h1] = newone_s(str, l, h);
|
||||||
return ts;
|
return ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
static TaggedString *insert_u (void *buff, int tag, stringtable *tb)
|
|
||||||
{
|
static TaggedString *insert_u (void *buff, int tag, stringtable *tb) {
|
||||||
TaggedString *ts;
|
TaggedString *ts;
|
||||||
unsigned long h = (unsigned long)buff;
|
unsigned long h = (unsigned long)buff;
|
||||||
int size = tb->size;
|
int size = tb->size;
|
||||||
int i;
|
|
||||||
int j = -1;
|
int j = -1;
|
||||||
|
int h1;
|
||||||
if ((long)tb->nuse*3 >= (long)size*2) {
|
if ((long)tb->nuse*3 >= (long)size*2) {
|
||||||
grow(tb);
|
grow(tb);
|
||||||
size = tb->size;
|
size = tb->size;
|
||||||
}
|
}
|
||||||
for (i = h%size; (ts = tb->hash[i]) != NULL; ) {
|
h1 = h%size;
|
||||||
|
while ((ts = tb->hash[h1]) != NULL) {
|
||||||
if (ts == &EMPTY)
|
if (ts == &EMPTY)
|
||||||
j = i;
|
j = h1;
|
||||||
else if (ts->constindex < 0 && /* is a udata? */
|
else if ((tag == ts->u.d.tag || tag == LUA_ANYTAG) && buff == ts->u.d.v)
|
||||||
(tag == ts->u.d.tag || tag == LUA_ANYTAG) &&
|
|
||||||
buff == ts->u.d.v)
|
|
||||||
return ts;
|
return ts;
|
||||||
if (++i == size) i=0;
|
h1 += (h&(size-2)) + 1; /* double hashing */
|
||||||
|
if (h1 >= size) h1 -= size;
|
||||||
}
|
}
|
||||||
/* not found */
|
/* not found */
|
||||||
if (j != -1) /* is there an EMPTY space? */
|
if (j != -1) /* is there an EMPTY space? */
|
||||||
i = j;
|
h1 = j;
|
||||||
else
|
else
|
||||||
tb->nuse++;
|
tb->nuse++;
|
||||||
ts = tb->hash[i] = newone_u(buff, tag, h);
|
ts = tb->hash[h1] = newone_u(buff, tag, h);
|
||||||
return ts;
|
return ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
TaggedString *luaS_createudata (void *udata, int tag)
|
|
||||||
{
|
TaggedString *luaS_createudata (void *udata, int tag) {
|
||||||
return insert_u(udata, tag, &L->string_root[(unsigned)udata%NUM_HASHS]);
|
int t = ((unsigned)udata%NUM_HASHUDATA)+NUM_HASHSTR;
|
||||||
|
return insert_u(udata, tag, &L->string_root[t]);
|
||||||
}
|
}
|
||||||
|
|
||||||
TaggedString *luaS_newlstr (char *str, long l)
|
TaggedString *luaS_newlstr (char *str, long l) {
|
||||||
{
|
int t = (l==0) ? 0 : ((int)((unsigned char)str[0]*l))%NUM_HASHSTR;
|
||||||
int i = (l==0)?0:(unsigned char)str[0];
|
return insert_s(str, l, &L->string_root[t]);
|
||||||
return insert_s(str, l, &L->string_root[i%NUM_HASHS]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TaggedString *luaS_new (char *str)
|
TaggedString *luaS_new (char *str) {
|
||||||
{
|
|
||||||
return luaS_newlstr(str, strlen(str));
|
return luaS_newlstr(str, strlen(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
TaggedString *luaS_newfixedstring (char *str)
|
TaggedString *luaS_newfixedstring (char *str) {
|
||||||
{
|
|
||||||
TaggedString *ts = luaS_new(str);
|
TaggedString *ts = luaS_new(str);
|
||||||
if (ts->head.marked == 0)
|
if (ts->head.marked == 0)
|
||||||
ts->head.marked = 2; /* avoid GC */
|
ts->head.marked = 2; /* avoid GC */
|
||||||
@@ -197,8 +189,7 @@ TaggedString *luaS_newfixedstring (char *str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void luaS_free (TaggedString *l)
|
void luaS_free (TaggedString *l) {
|
||||||
{
|
|
||||||
while (l) {
|
while (l) {
|
||||||
TaggedString *next = (TaggedString *)l->head.next;
|
TaggedString *next = (TaggedString *)l->head.next;
|
||||||
L->nblocks -= (l->constindex == -1) ? 1 : gcsizestring(l->u.s.len);
|
L->nblocks -= (l->constindex == -1) ? 1 : gcsizestring(l->u.s.len);
|
||||||
@@ -212,8 +203,7 @@ void luaS_free (TaggedString *l)
|
|||||||
** Garbage collection functions.
|
** Garbage collection functions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void remove_from_list (GCnode *l)
|
static void remove_from_list (GCnode *l) {
|
||||||
{
|
|
||||||
while (l) {
|
while (l) {
|
||||||
GCnode *next = l->next;
|
GCnode *next = l->next;
|
||||||
while (next && !next->marked)
|
while (next && !next->marked)
|
||||||
@@ -223,8 +213,7 @@ static void remove_from_list (GCnode *l)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TaggedString *luaS_collector (void)
|
TaggedString *luaS_collector (void) {
|
||||||
{
|
|
||||||
TaggedString *frees = NULL;
|
TaggedString *frees = NULL;
|
||||||
int i;
|
int i;
|
||||||
remove_from_list(&(L->rootglobal));
|
remove_from_list(&(L->rootglobal));
|
||||||
@@ -247,18 +236,18 @@ TaggedString *luaS_collector (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TaggedString *luaS_collectudata (void)
|
TaggedString *luaS_collectudata (void) {
|
||||||
{
|
|
||||||
TaggedString *frees = NULL;
|
TaggedString *frees = NULL;
|
||||||
int i;
|
int i;
|
||||||
L->rootglobal.next = NULL; /* empty list of globals */
|
L->rootglobal.next = NULL; /* empty list of globals */
|
||||||
for (i=0; i<NUM_HASHS; i++) {
|
for (i=NUM_HASHSTR; i<NUM_HASHS; i++) {
|
||||||
stringtable *tb = &L->string_root[i];
|
stringtable *tb = &L->string_root[i];
|
||||||
int j;
|
int j;
|
||||||
for (j=0; j<tb->size; j++) {
|
for (j=0; j<tb->size; j++) {
|
||||||
TaggedString *t = tb->hash[j];
|
TaggedString *t = tb->hash[j];
|
||||||
if (t == NULL || t == &EMPTY || t->constindex != -1)
|
if (t == NULL || t == &EMPTY)
|
||||||
continue; /* get only user data */
|
continue;
|
||||||
|
LUA_ASSERT(t->constindex == -1, "must be userdata");
|
||||||
t->head.next = (GCnode *)frees;
|
t->head.next = (GCnode *)frees;
|
||||||
frees = t;
|
frees = t;
|
||||||
tb->hash[j] = &EMPTY;
|
tb->hash[j] = &EMPTY;
|
||||||
@@ -268,8 +257,7 @@ TaggedString *luaS_collectudata (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void luaS_freeall (void)
|
void luaS_freeall (void) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
for (i=0; i<NUM_HASHS; i++) {
|
for (i=0; i<NUM_HASHS; i++) {
|
||||||
stringtable *tb = &L->string_root[i];
|
stringtable *tb = &L->string_root[i];
|
||||||
@@ -285,8 +273,7 @@ void luaS_freeall (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void luaS_rawsetglobal (TaggedString *ts, TObject *newval)
|
void luaS_rawsetglobal (TaggedString *ts, TObject *newval) {
|
||||||
{
|
|
||||||
ts->u.s.globalval = *newval;
|
ts->u.s.globalval = *newval;
|
||||||
if (ts->head.next == (GCnode *)ts) { /* is not in list? */
|
if (ts->head.next == (GCnode *)ts) { /* is not in list? */
|
||||||
ts->head.next = L->rootglobal.next;
|
ts->head.next = L->rootglobal.next;
|
||||||
@@ -295,8 +282,7 @@ void luaS_rawsetglobal (TaggedString *ts, TObject *newval)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char *luaS_travsymbol (int (*fn)(TObject *))
|
char *luaS_travsymbol (int (*fn)(TObject *)) {
|
||||||
{
|
|
||||||
TaggedString *g;
|
TaggedString *g;
|
||||||
for (g=(TaggedString *)L->rootglobal.next; g; g=(TaggedString *)g->head.next)
|
for (g=(TaggedString *)L->rootglobal.next; g; g=(TaggedString *)g->head.next)
|
||||||
if (fn(&g->u.s.globalval))
|
if (fn(&g->u.s.globalval))
|
||||||
@@ -305,8 +291,7 @@ char *luaS_travsymbol (int (*fn)(TObject *))
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int luaS_globaldefined (char *name)
|
int luaS_globaldefined (char *name) {
|
||||||
{
|
|
||||||
TaggedString *ts = luaS_new(name);
|
TaggedString *ts = luaS_new(name);
|
||||||
return ts->u.s.globalval.ttype != LUA_T_NIL;
|
return ts->u.s.globalval.ttype != LUA_T_NIL;
|
||||||
}
|
}
|
||||||
|
|||||||
172
lstrlib.c
172
lstrlib.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lstrlib.c,v 1.17 1998/06/29 18:24:06 roberto Exp roberto $
|
** $Id: lstrlib.c,v 1.27 1999/02/25 19:13:56 roberto Exp roberto $
|
||||||
** Standard library for strings and pattern-matching
|
** Standard library for strings and pattern-matching
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -32,33 +32,31 @@ static void str_len (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void closeandpush (void)
|
static void closeandpush (void) {
|
||||||
{
|
|
||||||
lua_pushlstring(luaL_buffer(), luaL_getsize());
|
lua_pushlstring(luaL_buffer(), luaL_getsize());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static long posrelat (long pos, long len)
|
static long posrelat (long pos, long len) {
|
||||||
{
|
|
||||||
/* relative string position: negative means back from end */
|
/* relative string position: negative means back from end */
|
||||||
return (pos>=0) ? pos : len+pos+1;
|
return (pos>=0) ? pos : len+pos+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void str_sub (void)
|
static void str_sub (void) {
|
||||||
{
|
|
||||||
long l;
|
long l;
|
||||||
char *s = luaL_check_lstr(1, &l);
|
char *s = luaL_check_lstr(1, &l);
|
||||||
long start = posrelat(luaL_check_number(2), l);
|
long start = posrelat(luaL_check_long(2), l);
|
||||||
long end = posrelat(luaL_opt_number(3, -1), l);
|
long end = posrelat(luaL_opt_long(3, -1), l);
|
||||||
if (1 <= start && start <= end && end <= l)
|
if (start < 1) start = 1;
|
||||||
|
if (end > l) end = l;
|
||||||
|
if (start <= end)
|
||||||
lua_pushlstring(s+start-1, end-start+1);
|
lua_pushlstring(s+start-1, end-start+1);
|
||||||
else lua_pushstring("");
|
else lua_pushstring("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void str_lower (void)
|
static void str_lower (void) {
|
||||||
{
|
|
||||||
long l;
|
long l;
|
||||||
int i;
|
int i;
|
||||||
char *s = luaL_check_lstr(1, &l);
|
char *s = luaL_check_lstr(1, &l);
|
||||||
@@ -69,8 +67,7 @@ static void str_lower (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void str_upper (void)
|
static void str_upper (void) {
|
||||||
{
|
|
||||||
long l;
|
long l;
|
||||||
int i;
|
int i;
|
||||||
char *s = luaL_check_lstr(1, &l);
|
char *s = luaL_check_lstr(1, &l);
|
||||||
@@ -84,7 +81,7 @@ static void str_rep (void)
|
|||||||
{
|
{
|
||||||
long l;
|
long l;
|
||||||
char *s = luaL_check_lstr(1, &l);
|
char *s = luaL_check_lstr(1, &l);
|
||||||
int n = (int)luaL_check_number(2);
|
int n = luaL_check_int(2);
|
||||||
luaL_resetbuffer();
|
luaL_resetbuffer();
|
||||||
while (n-- > 0)
|
while (n-- > 0)
|
||||||
addnchar(s, l);
|
addnchar(s, l);
|
||||||
@@ -92,29 +89,30 @@ static void str_rep (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void str_byte (void)
|
static void str_byte (void) {
|
||||||
{
|
|
||||||
long l;
|
long l;
|
||||||
char *s = luaL_check_lstr(1, &l);
|
char *s = luaL_check_lstr(1, &l);
|
||||||
long pos = posrelat(luaL_opt_number(2, 1), l);
|
long pos = posrelat(luaL_opt_long(2, 1), l);
|
||||||
luaL_arg_check(0<pos && pos<=l, 2, "out of range");
|
luaL_arg_check(0<pos && pos<=l, 2, "out of range");
|
||||||
lua_pushnumber((unsigned char)s[pos-1]);
|
lua_pushnumber((unsigned char)s[pos-1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void str_char (void) {
|
static void str_char (void) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
luaL_resetbuffer();
|
luaL_resetbuffer();
|
||||||
while (lua_getparam(++i) != LUA_NOOBJECT) {
|
while (lua_getparam(++i) != LUA_NOOBJECT) {
|
||||||
double c = luaL_check_number(i);
|
double c = luaL_check_number(i);
|
||||||
luaL_arg_check((unsigned char)c == c, i, "invalid value");
|
luaL_arg_check((unsigned char)c == c, i, "invalid value");
|
||||||
luaL_addchar((int)c);
|
luaL_addchar((unsigned char)c);
|
||||||
}
|
}
|
||||||
closeandpush();
|
closeandpush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** =======================================================
|
** {======================================================
|
||||||
** PATTERN MATCHING
|
** PATTERN MATCHING
|
||||||
** =======================================================
|
** =======================================================
|
||||||
*/
|
*/
|
||||||
@@ -122,8 +120,8 @@ static void str_char (void) {
|
|||||||
#define MAX_CAPT 9
|
#define MAX_CAPT 9
|
||||||
|
|
||||||
struct Capture {
|
struct Capture {
|
||||||
int level; /* total number of captures (finished or unfinished) */
|
|
||||||
char *src_end; /* end ('\0') of source string */
|
char *src_end; /* end ('\0') of source string */
|
||||||
|
int level; /* total number of captures (finished or unfinished) */
|
||||||
struct {
|
struct {
|
||||||
char *init;
|
char *init;
|
||||||
int len; /* -1 signals unfinished capture */
|
int len; /* -1 signals unfinished capture */
|
||||||
@@ -135,16 +133,17 @@ struct Capture {
|
|||||||
#define SPECIALS "^$*?.([%-"
|
#define SPECIALS "^$*?.([%-"
|
||||||
|
|
||||||
|
|
||||||
static void push_captures (struct Capture *cap)
|
static void push_captures (struct Capture *cap) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
for (i=0; i<cap->level; i++)
|
for (i=0; i<cap->level; i++) {
|
||||||
lua_pushlstring(cap->capture[i].init, cap->capture[i].len);
|
int l = cap->capture[i].len;
|
||||||
|
if (l == -1) lua_error("unfinished capture");
|
||||||
|
lua_pushlstring(cap->capture[i].init, l);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int check_cap (int l, struct Capture *cap)
|
static int check_cap (int l, struct Capture *cap) {
|
||||||
{
|
|
||||||
l -= '1';
|
l -= '1';
|
||||||
if (!(0 <= l && l < cap->level && cap->capture[l].len != -1))
|
if (!(0 <= l && l < cap->level && cap->capture[l].len != -1))
|
||||||
lua_error("invalid capture index");
|
lua_error("invalid capture index");
|
||||||
@@ -152,8 +151,7 @@ static int check_cap (int l, struct Capture *cap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int capture_to_close (struct Capture *cap)
|
static int capture_to_close (struct Capture *cap) {
|
||||||
{
|
|
||||||
int level = cap->level;
|
int level = cap->level;
|
||||||
for (level--; level>=0; level--)
|
for (level--; level>=0; level--)
|
||||||
if (cap->capture[level].len == -1) return level;
|
if (cap->capture[level].len == -1) return level;
|
||||||
@@ -162,14 +160,12 @@ static int capture_to_close (struct Capture *cap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static char *bracket_end (char *p)
|
static char *bracket_end (char *p) {
|
||||||
{
|
|
||||||
return (*p == 0) ? NULL : strchr((*p=='^') ? p+2 : p+1, ']');
|
return (*p == 0) ? NULL : strchr((*p=='^') ? p+2 : p+1, ']');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int matchclass (int c, int cl)
|
static int matchclass (int c, int cl) {
|
||||||
{
|
|
||||||
int res;
|
int res;
|
||||||
switch (tolower(cl)) {
|
switch (tolower(cl)) {
|
||||||
case 'a' : res = isalpha(c); break;
|
case 'a' : res = isalpha(c); break;
|
||||||
@@ -180,15 +176,15 @@ static int matchclass (int c, int cl)
|
|||||||
case 's' : res = isspace(c); break;
|
case 's' : res = isspace(c); break;
|
||||||
case 'u' : res = isupper(c); break;
|
case 'u' : res = isupper(c); break;
|
||||||
case 'w' : res = isalnum(c); break;
|
case 'w' : res = isalnum(c); break;
|
||||||
|
case 'x' : res = isxdigit(c); break;
|
||||||
case 'z' : res = (c == '\0'); break;
|
case 'z' : res = (c == '\0'); break;
|
||||||
default: return (cl == c);
|
default: return (cl == c);
|
||||||
}
|
}
|
||||||
return (islower((unsigned char)cl) ? res : !res);
|
return (islower(cl) ? res : !res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int luaI_singlematch (int c, char *p, char **ep)
|
int luaI_singlematch (int c, char *p, char **ep) {
|
||||||
{
|
|
||||||
switch (*p) {
|
switch (*p) {
|
||||||
case '.': /* matches any char */
|
case '.': /* matches any char */
|
||||||
*ep = p+1;
|
*ep = p+1;
|
||||||
@@ -213,7 +209,7 @@ int luaI_singlematch (int c, char *p, char **ep)
|
|||||||
}
|
}
|
||||||
else if ((*(p+1) == '-') && (p+2 < end)) {
|
else if ((*(p+1) == '-') && (p+2 < end)) {
|
||||||
p+=2;
|
p+=2;
|
||||||
if ((unsigned char)*(p-2) <= c && c <= (unsigned char)*p)
|
if ((int)(unsigned char)*(p-2) <= c && c <= (int)(unsigned char)*p)
|
||||||
return sig;
|
return sig;
|
||||||
}
|
}
|
||||||
else if ((unsigned char)*p == c) return sig;
|
else if ((unsigned char)*p == c) return sig;
|
||||||
@@ -227,8 +223,7 @@ int luaI_singlematch (int c, char *p, char **ep)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static char *matchbalance (char *s, int b, int e, struct Capture *cap)
|
static char *matchbalance (char *s, int b, int e, struct Capture *cap) {
|
||||||
{
|
|
||||||
if (*s != b) return NULL;
|
if (*s != b) return NULL;
|
||||||
else {
|
else {
|
||||||
int cont = 1;
|
int cont = 1;
|
||||||
@@ -243,8 +238,7 @@ static char *matchbalance (char *s, int b, int e, struct Capture *cap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static char *matchitem (char *s, char *p, struct Capture *cap, char **ep)
|
static char *matchitem (char *s, char *p, struct Capture *cap, char **ep) {
|
||||||
{
|
|
||||||
if (*p == ESC) {
|
if (*p == ESC) {
|
||||||
p++;
|
p++;
|
||||||
if (isdigit((unsigned char)*p)) { /* capture */
|
if (isdigit((unsigned char)*p)) { /* capture */
|
||||||
@@ -264,14 +258,13 @@ static char *matchitem (char *s, char *p, struct Capture *cap, char **ep)
|
|||||||
}
|
}
|
||||||
else p--; /* and go through */
|
else p--; /* and go through */
|
||||||
}
|
}
|
||||||
/* "luaI_singlematch" sets "ep" (so must be called even when *s == 0) */
|
/* "luaI_singlematch" sets "ep" (so must be called even at the end of "s" */
|
||||||
return (luaI_singlematch((unsigned char)*s, p, ep) && s<cap->src_end) ?
|
return (luaI_singlematch((unsigned char)*s, p, ep) && s<cap->src_end) ?
|
||||||
s+1 : NULL;
|
s+1 : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static char *match (char *s, char *p, struct Capture *cap)
|
static char *match (char *s, char *p, struct Capture *cap) {
|
||||||
{
|
|
||||||
init: /* using goto's to optimize tail recursion */
|
init: /* using goto's to optimize tail recursion */
|
||||||
switch (*p) {
|
switch (*p) {
|
||||||
case '(': { /* start capture */
|
case '(': { /* start capture */
|
||||||
@@ -297,7 +290,7 @@ static char *match (char *s, char *p, struct Capture *cap)
|
|||||||
return s;
|
return s;
|
||||||
/* else go through */
|
/* else go through */
|
||||||
default: { /* it is a pattern item */
|
default: { /* it is a pattern item */
|
||||||
char *ep; /* get what is next */
|
char *ep; /* will point to what is next */
|
||||||
char *s1 = matchitem(s, p, cap, &ep);
|
char *s1 = matchitem(s, p, cap, &ep);
|
||||||
switch (*ep) {
|
switch (*ep) {
|
||||||
case '*': { /* repetition */
|
case '*': { /* repetition */
|
||||||
@@ -332,12 +325,11 @@ static char *match (char *s, char *p, struct Capture *cap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void str_find (void)
|
static void str_find (void) {
|
||||||
{
|
|
||||||
long l;
|
long l;
|
||||||
char *s = luaL_check_lstr(1, &l);
|
char *s = luaL_check_lstr(1, &l);
|
||||||
char *p = luaL_check_string(2);
|
char *p = luaL_check_string(2);
|
||||||
long init = posrelat(luaL_opt_number(3, 1), l) - 1;
|
long init = posrelat(luaL_opt_long(3, 1), l) - 1;
|
||||||
struct Capture cap;
|
struct Capture cap;
|
||||||
luaL_arg_check(0 <= init && init <= l, 3, "out of range");
|
luaL_arg_check(0 <= init && init <= l, 3, "out of range");
|
||||||
if (lua_getparam(4) != LUA_NOOBJECT ||
|
if (lua_getparam(4) != LUA_NOOBJECT ||
|
||||||
@@ -368,8 +360,7 @@ static void str_find (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void add_s (lua_Object newp, struct Capture *cap)
|
static void add_s (lua_Object newp, struct Capture *cap) {
|
||||||
{
|
|
||||||
if (lua_isstring(newp)) {
|
if (lua_isstring(newp)) {
|
||||||
char *news = lua_getstring(newp);
|
char *news = lua_getstring(newp);
|
||||||
int l = lua_strlen(newp);
|
int l = lua_strlen(newp);
|
||||||
@@ -411,13 +402,12 @@ static void add_s (lua_Object newp, struct Capture *cap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void str_gsub (void)
|
static void str_gsub (void) {
|
||||||
{
|
|
||||||
long srcl;
|
long srcl;
|
||||||
char *src = luaL_check_lstr(1, &srcl);
|
char *src = luaL_check_lstr(1, &srcl);
|
||||||
char *p = luaL_check_string(2);
|
char *p = luaL_check_string(2);
|
||||||
lua_Object newp = lua_getparam(3);
|
lua_Object newp = lua_getparam(3);
|
||||||
int max_s = (int)luaL_opt_number(4, srcl+1);
|
int max_s = luaL_opt_int(4, srcl+1);
|
||||||
int anchor = (*p == '^') ? (p++, 1) : 0;
|
int anchor = (*p == '^') ? (p++, 1) : 0;
|
||||||
int n = 0;
|
int n = 0;
|
||||||
struct Capture cap;
|
struct Capture cap;
|
||||||
@@ -445,26 +435,33 @@ static void str_gsub (void)
|
|||||||
lua_pushnumber(n); /* number of substitutions */
|
lua_pushnumber(n); /* number of substitutions */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* }====================================================== */
|
||||||
|
|
||||||
static void luaI_addquoted (char *s)
|
|
||||||
{
|
static void luaI_addquoted (int arg) {
|
||||||
|
long l;
|
||||||
|
char *s = luaL_check_lstr(arg, &l);
|
||||||
luaL_addchar('"');
|
luaL_addchar('"');
|
||||||
for (; *s; s++) {
|
while (l--) {
|
||||||
if (strchr("\"\\\n", *s))
|
switch (*s) {
|
||||||
luaL_addchar('\\');
|
case '"': case '\\': case '\n':
|
||||||
luaL_addchar(*s);
|
luaL_addchar('\\');
|
||||||
|
luaL_addchar(*s);
|
||||||
|
break;
|
||||||
|
case '\0': addnchar("\\000", 4); break;
|
||||||
|
default: luaL_addchar(*s);
|
||||||
|
}
|
||||||
|
s++;
|
||||||
}
|
}
|
||||||
luaL_addchar('"');
|
luaL_addchar('"');
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAX_FORMAT 200
|
/* maximum size of each format specification (such as '%-099.99d') */
|
||||||
|
#define MAX_FORMAT 20
|
||||||
|
|
||||||
static void str_format (void)
|
static void str_format (void) {
|
||||||
{
|
|
||||||
int arg = 1;
|
int arg = 1;
|
||||||
char *strfrmt = luaL_check_string(arg);
|
char *strfrmt = luaL_check_string(arg);
|
||||||
struct Capture cap;
|
|
||||||
cap.src_end = strfrmt+strlen(strfrmt)+1;
|
|
||||||
luaL_resetbuffer();
|
luaL_resetbuffer();
|
||||||
while (*strfrmt) {
|
while (*strfrmt) {
|
||||||
if (*strfrmt != '%')
|
if (*strfrmt != '%')
|
||||||
@@ -472,34 +469,28 @@ static void str_format (void)
|
|||||||
else if (*++strfrmt == '%')
|
else if (*++strfrmt == '%')
|
||||||
luaL_addchar(*strfrmt++); /* %% */
|
luaL_addchar(*strfrmt++); /* %% */
|
||||||
else { /* format item */
|
else { /* format item */
|
||||||
char form[MAX_FORMAT]; /* store the format ('%...') */
|
struct Capture cap;
|
||||||
char *buff;
|
char form[MAX_FORMAT]; /* to store the format ('%...') */
|
||||||
|
char *buff; /* to store the formatted item */
|
||||||
char *initf = strfrmt;
|
char *initf = strfrmt;
|
||||||
form[0] = '%';
|
form[0] = '%';
|
||||||
cap.level = 0;
|
if (isdigit((unsigned char)*initf) && *(initf+1) == '$') {
|
||||||
if (isdigit((unsigned char)initf[0]) && initf[1] == '$') {
|
arg = *initf - '0';
|
||||||
arg = initf[0] - '0';
|
|
||||||
initf += 2; /* skip the 'n$' */
|
initf += 2; /* skip the 'n$' */
|
||||||
}
|
}
|
||||||
arg++;
|
arg++;
|
||||||
|
cap.src_end = strfrmt+strlen(strfrmt)+1;
|
||||||
|
cap.level = 0;
|
||||||
strfrmt = match(initf, "[-+ #0]*(%d*)%.?(%d*)", &cap);
|
strfrmt = match(initf, "[-+ #0]*(%d*)%.?(%d*)", &cap);
|
||||||
if (cap.capture[0].len > 2 || cap.capture[1].len > 2) /* < 100? */
|
if (cap.capture[0].len > 2 || cap.capture[1].len > 2 || /* < 100? */
|
||||||
|
strfrmt-initf > MAX_FORMAT-2)
|
||||||
lua_error("invalid format (width or precision too long)");
|
lua_error("invalid format (width or precision too long)");
|
||||||
strncpy(form+1, initf, strfrmt-initf+1); /* +1 to include conversion */
|
strncpy(form+1, initf, strfrmt-initf+1); /* +1 to include conversion */
|
||||||
form[strfrmt-initf+2] = 0;
|
form[strfrmt-initf+2] = 0;
|
||||||
buff = luaL_openspace(1000); /* to store the formatted value */
|
buff = luaL_openspace(512); /* 512 > soid luaI_addquot99.99f', -1e308) */
|
||||||
switch (*strfrmt++) {
|
switch (*strfrmt++) {
|
||||||
case 'q':
|
|
||||||
luaI_addquoted(luaL_check_string(arg));
|
|
||||||
continue;
|
|
||||||
case 's': {
|
|
||||||
char *s = luaL_check_string(arg);
|
|
||||||
buff = luaL_openspace(strlen(s));
|
|
||||||
sprintf(buff, form, s);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'c': case 'd': case 'i':
|
case 'c': case 'd': case 'i':
|
||||||
sprintf(buff, form, (int)luaL_check_number(arg));
|
sprintf(buff, form, luaL_check_int(arg));
|
||||||
break;
|
break;
|
||||||
case 'o': case 'u': case 'x': case 'X':
|
case 'o': case 'u': case 'x': case 'X':
|
||||||
sprintf(buff, form, (unsigned int)luaL_check_number(arg));
|
sprintf(buff, form, (unsigned int)luaL_check_number(arg));
|
||||||
@@ -507,6 +498,23 @@ static void str_format (void)
|
|||||||
case 'e': case 'E': case 'f': case 'g': case 'G':
|
case 'e': case 'E': case 'f': case 'g': case 'G':
|
||||||
sprintf(buff, form, luaL_check_number(arg));
|
sprintf(buff, form, luaL_check_number(arg));
|
||||||
break;
|
break;
|
||||||
|
case 'q':
|
||||||
|
luaI_addquoted(arg);
|
||||||
|
continue; /* skip the "addsize" at the end */
|
||||||
|
case 's': {
|
||||||
|
long l;
|
||||||
|
char *s = luaL_check_lstr(arg, &l);
|
||||||
|
if (cap.capture[1].len == 0 && l >= 100) {
|
||||||
|
/* no precision and string is too big to be formatted;
|
||||||
|
keep original string */
|
||||||
|
addnchar(s, l);
|
||||||
|
continue; /* skip the "addsize" at the end */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sprintf(buff, form, s);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
default: /* also treat cases 'pnLlh' */
|
default: /* also treat cases 'pnLlh' */
|
||||||
lua_error("invalid option in `format'");
|
lua_error("invalid option in `format'");
|
||||||
}
|
}
|
||||||
@@ -524,7 +532,7 @@ static struct luaL_reg strlib[] = {
|
|||||||
{"strupper", str_upper},
|
{"strupper", str_upper},
|
||||||
{"strchar", str_char},
|
{"strchar", str_char},
|
||||||
{"strrep", str_rep},
|
{"strrep", str_rep},
|
||||||
{"ascii", str_byte}, /* for compatibility */
|
{"ascii", str_byte}, /* for compatibility with 3.0 and earlier */
|
||||||
{"strbyte", str_byte},
|
{"strbyte", str_byte},
|
||||||
{"format", str_format},
|
{"format", str_format},
|
||||||
{"strfind", str_find},
|
{"strfind", str_find},
|
||||||
|
|||||||
182
ltable.c
182
ltable.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ltable.c,v 1.11 1998/01/13 18:06:27 roberto Exp roberto $
|
** $Id: ltable.c,v 1.20 1999/01/25 17:41:19 roberto Exp roberto $
|
||||||
** Lua tables (hash)
|
** Lua tables (hash)
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -20,14 +20,11 @@
|
|||||||
#define nodevector(t) ((t)->node)
|
#define nodevector(t) ((t)->node)
|
||||||
|
|
||||||
|
|
||||||
#define REHASH_LIMIT 0.70 /* avoid more than this % full */
|
|
||||||
|
|
||||||
#define TagDefault LUA_T_ARRAY;
|
#define TagDefault LUA_T_ARRAY;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static long int hashindex (TObject *ref)
|
static long int hashindex (TObject *ref) {
|
||||||
{
|
|
||||||
long int h;
|
long int h;
|
||||||
switch (ttype(ref)) {
|
switch (ttype(ref)) {
|
||||||
case LUA_T_NUMBER:
|
case LUA_T_NUMBER:
|
||||||
@@ -56,61 +53,45 @@ static long int hashindex (TObject *ref)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int present (Hash *t, TObject *key)
|
Node *luaH_present (Hash *t, TObject *key) {
|
||||||
{
|
|
||||||
int tsize = nhash(t);
|
int tsize = nhash(t);
|
||||||
long int h = hashindex(key);
|
long int h = hashindex(key);
|
||||||
int h1 = h%tsize;
|
int h1 = h%tsize;
|
||||||
TObject *rf = ref(node(t, h1));
|
Node *n = node(t, h1);
|
||||||
if (ttype(rf) != LUA_T_NIL && !luaO_equalObj(key, rf)) {
|
/* keep looking until an entry with "ref" equal to key or nil */
|
||||||
int h2 = h%(tsize-2) + 1;
|
while ((ttype(ref(n)) == ttype(key)) ? !luaO_equalval(key, ref(n))
|
||||||
do {
|
: ttype(ref(n)) != LUA_T_NIL) {
|
||||||
h1 += h2;
|
h1 += (h&(tsize-2)) + 1; /* double hashing */
|
||||||
if (h1 >= tsize) h1 -= tsize;
|
if (h1 >= tsize) h1 -= tsize;
|
||||||
rf = ref(node(t, h1));
|
n = node(t, h1);
|
||||||
} while (ttype(rf) != LUA_T_NIL && !luaO_equalObj(key, rf));
|
|
||||||
}
|
}
|
||||||
return h1;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
void luaH_free (Hash *frees) {
|
||||||
** Alloc a vector node
|
|
||||||
*/
|
|
||||||
static Node *hashnodecreate (int nhash)
|
|
||||||
{
|
|
||||||
Node *v = luaM_newvector(nhash, Node);
|
|
||||||
int i;
|
|
||||||
for (i=0; i<nhash; i++)
|
|
||||||
ttype(ref(&v[i])) = LUA_T_NIL;
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Delete a hash
|
|
||||||
*/
|
|
||||||
static void hashdelete (Hash *t)
|
|
||||||
{
|
|
||||||
luaM_free(nodevector(t));
|
|
||||||
luaM_free(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void luaH_free (Hash *frees)
|
|
||||||
{
|
|
||||||
while (frees) {
|
while (frees) {
|
||||||
Hash *next = (Hash *)frees->head.next;
|
Hash *next = (Hash *)frees->head.next;
|
||||||
L->nblocks -= gcsize(frees->nhash);
|
L->nblocks -= gcsize(frees->nhash);
|
||||||
hashdelete(frees);
|
luaM_free(nodevector(frees));
|
||||||
|
luaM_free(frees);
|
||||||
frees = next;
|
frees = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Hash *luaH_new (int nhash)
|
static Node *hashnodecreate (int nhash) {
|
||||||
{
|
Node *v = luaM_newvector(nhash, Node);
|
||||||
|
int i;
|
||||||
|
for (i=0; i<nhash; i++)
|
||||||
|
ttype(ref(&v[i])) = ttype(val(&v[i])) = LUA_T_NIL;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Hash *luaH_new (int nhash) {
|
||||||
Hash *t = luaM_new(Hash);
|
Hash *t = luaM_new(Hash);
|
||||||
nhash = luaO_redimension((int)((float)nhash/REHASH_LIMIT));
|
nhash = luaO_redimension(nhash*3/2);
|
||||||
nodevector(t) = hashnodecreate(nhash);
|
nodevector(t) = hashnodecreate(nhash);
|
||||||
nhash(t) = nhash;
|
nhash(t) = nhash;
|
||||||
nuse(t) = 0;
|
nuse(t) = 0;
|
||||||
@@ -121,96 +102,75 @@ Hash *luaH_new (int nhash)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int newsize (Hash *t)
|
static int newsize (Hash *t) {
|
||||||
{
|
|
||||||
Node *v = t->node;
|
Node *v = t->node;
|
||||||
int size = nhash(t);
|
int size = nhash(t);
|
||||||
int realuse = 0;
|
int realuse = 0;
|
||||||
int i;
|
int i;
|
||||||
for (i=0; i<size; i++) {
|
for (i=0; i<size; i++) {
|
||||||
if (ttype(ref(v+i)) != LUA_T_NIL && ttype(val(v+i)) != LUA_T_NIL)
|
if (ttype(val(v+i)) != LUA_T_NIL)
|
||||||
realuse++;
|
realuse++;
|
||||||
}
|
}
|
||||||
if (2*(realuse+1) <= size) /* +1 is the new element */
|
return luaO_redimension((realuse+1)*2); /* +1 is the new element */
|
||||||
return size; /* don't need to grow, just rehash */
|
|
||||||
else
|
|
||||||
return luaO_redimension(size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rehash (Hash *t)
|
|
||||||
{
|
static void rehash (Hash *t) {
|
||||||
int nold = nhash(t);
|
int nold = nhash(t);
|
||||||
Node *vold = nodevector(t);
|
Node *vold = nodevector(t);
|
||||||
int nnew = newsize(t);
|
int nnew = newsize(t);
|
||||||
int i;
|
int i;
|
||||||
nodevector(t) = hashnodecreate(nnew);
|
nodevector(t) = hashnodecreate(nnew);
|
||||||
nhash(t) = nnew;
|
nhash(t) = nnew;
|
||||||
|
nuse(t) = 0;
|
||||||
for (i=0; i<nold; i++) {
|
for (i=0; i<nold; i++) {
|
||||||
Node *n = vold+i;
|
Node *n = vold+i;
|
||||||
if (ttype(ref(n)) != LUA_T_NIL && ttype(val(n)) != LUA_T_NIL)
|
if (ttype(val(n)) != LUA_T_NIL) {
|
||||||
*node(t, present(t, ref(n))) = *n; /* copy old node to luaM_new hash */
|
*luaH_present(t, ref(n)) = *n; /* copy old node to new hash */
|
||||||
|
nuse(t)++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
L->nblocks += gcsize(nnew)-gcsize(nold);
|
L->nblocks += gcsize(nnew)-gcsize(nold);
|
||||||
luaM_free(vold);
|
luaM_free(vold);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
** If the hash node is present, return its pointer, otherwise return
|
|
||||||
** null.
|
|
||||||
*/
|
|
||||||
TObject *luaH_get (Hash *t, TObject *ref)
|
|
||||||
{
|
|
||||||
int h = present(t, ref);
|
|
||||||
if (ttype(ref(node(t, h))) != LUA_T_NIL) return val(node(t, h));
|
|
||||||
else return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
void luaH_set (Hash *t, TObject *ref, TObject *val) {
|
||||||
/*
|
Node *n = luaH_present(t, ref);
|
||||||
** If the hash node is present, return its pointer, otherwise create a luaM_new
|
if (ttype(ref(n)) != LUA_T_NIL)
|
||||||
** node for the given reference and also return its pointer.
|
*val(n) = *val;
|
||||||
*/
|
|
||||||
TObject *luaH_set (Hash *t, TObject *ref)
|
|
||||||
{
|
|
||||||
Node *n = node(t, present(t, ref));
|
|
||||||
if (ttype(ref(n)) == LUA_T_NIL) {
|
|
||||||
nuse(t)++;
|
|
||||||
if ((float)nuse(t) > (float)nhash(t)*REHASH_LIMIT) {
|
|
||||||
rehash(t);
|
|
||||||
n = node(t, present(t, ref));
|
|
||||||
}
|
|
||||||
*ref(n) = *ref;
|
|
||||||
ttype(val(n)) = LUA_T_NIL;
|
|
||||||
}
|
|
||||||
return (val(n));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static Node *hashnext (Hash *t, int i)
|
|
||||||
{
|
|
||||||
Node *n;
|
|
||||||
int tsize = nhash(t);
|
|
||||||
if (i >= tsize)
|
|
||||||
return NULL;
|
|
||||||
n = node(t, i);
|
|
||||||
while (ttype(ref(n)) == LUA_T_NIL || ttype(val(n)) == LUA_T_NIL) {
|
|
||||||
if (++i >= tsize)
|
|
||||||
return NULL;
|
|
||||||
n = node(t, i);
|
|
||||||
}
|
|
||||||
return node(t, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
Node *luaH_next (TObject *o, TObject *r)
|
|
||||||
{
|
|
||||||
Hash *t = avalue(o);
|
|
||||||
if (ttype(r) == LUA_T_NIL)
|
|
||||||
return hashnext(t, 0);
|
|
||||||
else {
|
else {
|
||||||
int i = present(t, r);
|
TObject buff = *val; /* rehash may invalidate this address */
|
||||||
Node *n = node(t, i);
|
if ((long)nuse(t)*3L > (long)nhash(t)*2L) {
|
||||||
luaL_arg_check(ttype(ref(n))!=LUA_T_NIL && ttype(val(n))!=LUA_T_NIL,
|
rehash(t);
|
||||||
2, "key not found");
|
n = luaH_present(t, ref);
|
||||||
return hashnext(t, i+1);
|
}
|
||||||
|
nuse(t)++;
|
||||||
|
*ref(n) = *ref;
|
||||||
|
*val(n) = buff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int luaH_pos (Hash *t, TObject *r) {
|
||||||
|
Node *n = luaH_present(t, r);
|
||||||
|
luaL_arg_check(ttype(val(n)) != LUA_T_NIL, 2, "key not found");
|
||||||
|
return n-(t->node);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void luaH_setint (Hash *t, int ref, TObject *val) {
|
||||||
|
TObject index;
|
||||||
|
ttype(&index) = LUA_T_NUMBER;
|
||||||
|
nvalue(&index) = ref;
|
||||||
|
luaH_set(t, &index, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TObject *luaH_getint (Hash *t, int ref) {
|
||||||
|
TObject index;
|
||||||
|
ttype(&index) = LUA_T_NUMBER;
|
||||||
|
nvalue(&index) = ref;
|
||||||
|
return luaH_get(t, &index);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
14
ltable.h
14
ltable.h
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ltable.h,v 1.4 1997/11/19 17:29:23 roberto Exp roberto $
|
** $Id: ltable.h,v 1.10 1999/01/25 17:40:10 roberto Exp roberto $
|
||||||
** Lua tables (hash)
|
** Lua tables (hash)
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -15,10 +15,16 @@
|
|||||||
#define val(n) (&(n)->val)
|
#define val(n) (&(n)->val)
|
||||||
#define nhash(t) ((t)->nhash)
|
#define nhash(t) ((t)->nhash)
|
||||||
|
|
||||||
|
#define luaH_get(t,ref) (val(luaH_present((t), (ref))))
|
||||||
|
#define luaH_move(t,from,to) (luaH_setint(t, to, luaH_getint(t, from)))
|
||||||
|
|
||||||
Hash *luaH_new (int nhash);
|
Hash *luaH_new (int nhash);
|
||||||
void luaH_free (Hash *frees);
|
void luaH_free (Hash *frees);
|
||||||
TObject *luaH_get (Hash *t, TObject *ref);
|
Node *luaH_present (Hash *t, TObject *key);
|
||||||
TObject *luaH_set (Hash *t, TObject *ref);
|
void luaH_set (Hash *t, TObject *ref, TObject *val);
|
||||||
Node *luaH_next (TObject *o, TObject *r);
|
int luaH_pos (Hash *t, TObject *r);
|
||||||
|
void luaH_setint (Hash *t, int ref, TObject *val);
|
||||||
|
TObject *luaH_getint (Hash *t, int ref);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
88
ltm.c
88
ltm.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ltm.c,v 1.15 1998/03/11 13:59:50 roberto Exp roberto $
|
** $Id: ltm.c,v 1.23 1999/02/25 19:13:56 roberto Exp roberto $
|
||||||
** Tag methods
|
** Tag methods
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -22,8 +22,7 @@ char *luaT_eventname[] = { /* ORDER IM */
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static int luaI_checkevent (char *name, char *list[])
|
static int luaI_checkevent (char *name, char *list[]) {
|
||||||
{
|
|
||||||
int e = luaL_findstring(name, list);
|
int e = luaL_findstring(name, list);
|
||||||
if (e < 0)
|
if (e < 0)
|
||||||
luaL_verror("`%.50s' is not a valid event name", name);
|
luaL_verror("`%.50s' is not a valid event name", name);
|
||||||
@@ -35,7 +34,7 @@ static int luaI_checkevent (char *name, char *list[])
|
|||||||
/* events in LUA_T_NIL are all allowed, since this is used as a
|
/* events in LUA_T_NIL are all allowed, since this is used as a
|
||||||
* 'placeholder' for "default" fallbacks
|
* 'placeholder' for "default" fallbacks
|
||||||
*/
|
*/
|
||||||
static char validevents[NUM_TAGS][IM_N] = { /* ORDER LUA_T, ORDER IM */
|
static char luaT_validevents[NUM_TAGS][IM_N] = { /* ORDER LUA_T, ORDER IM */
|
||||||
{1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, /* LUA_T_USERDATA */
|
{1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, /* LUA_T_USERDATA */
|
||||||
{1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_T_NUMBER */
|
{1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_T_NUMBER */
|
||||||
{1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_T_STRING */
|
{1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_T_STRING */
|
||||||
@@ -45,71 +44,59 @@ static char validevents[NUM_TAGS][IM_N] = { /* ORDER LUA_T, ORDER IM */
|
|||||||
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} /* LUA_T_NIL */
|
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} /* LUA_T_NIL */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int luaT_validevent (int t, int e) { /* ORDER LUA_T */
|
||||||
static int validevent (int t, int e)
|
return (t < LUA_T_NIL) ? 1 : luaT_validevents[-t][e];
|
||||||
{ /* ORDER LUA_T */
|
|
||||||
return (t < LUA_T_NIL) ? 1 : validevents[-t][e];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void init_entry (int tag)
|
static void init_entry (int tag) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
for (i=0; i<IM_N; i++)
|
for (i=0; i<IM_N; i++)
|
||||||
ttype(luaT_getim(tag, i)) = LUA_T_NIL;
|
ttype(luaT_getim(tag, i)) = LUA_T_NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void luaT_init (void)
|
void luaT_init (void) {
|
||||||
{
|
|
||||||
int t;
|
int t;
|
||||||
L->IMtable_size = NUM_TAGS*2;
|
|
||||||
L->last_tag = -(NUM_TAGS-1);
|
L->last_tag = -(NUM_TAGS-1);
|
||||||
L->IMtable = luaM_newvector(L->IMtable_size, struct IM);
|
luaM_growvector(L->IMtable, 0, NUM_TAGS, struct IM, arrEM, MAX_INT);
|
||||||
for (t=L->last_tag; t<=0; t++)
|
for (t=L->last_tag; t<=0; t++)
|
||||||
init_entry(t);
|
init_entry(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int lua_newtag (void)
|
int lua_newtag (void) {
|
||||||
{
|
|
||||||
--L->last_tag;
|
--L->last_tag;
|
||||||
if ((-L->last_tag) >= L->IMtable_size)
|
luaM_growvector(L->IMtable, -(L->last_tag), 1, struct IM, arrEM, MAX_INT);
|
||||||
L->IMtable_size = luaM_growvector(&L->IMtable, L->IMtable_size,
|
|
||||||
struct IM, memEM, MAX_INT);
|
|
||||||
init_entry(L->last_tag);
|
init_entry(L->last_tag);
|
||||||
return L->last_tag;
|
return L->last_tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void checktag (int tag)
|
static void checktag (int tag) {
|
||||||
{
|
|
||||||
if (!(L->last_tag <= tag && tag <= 0))
|
if (!(L->last_tag <= tag && tag <= 0))
|
||||||
luaL_verror("%d is not a valid tag", tag);
|
luaL_verror("%d is not a valid tag", tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
void luaT_realtag (int tag)
|
void luaT_realtag (int tag) {
|
||||||
{
|
|
||||||
if (!(L->last_tag <= tag && tag < LUA_T_NIL))
|
if (!(L->last_tag <= tag && tag < LUA_T_NIL))
|
||||||
luaL_verror("tag %d is not result of `newtag'", tag);
|
luaL_verror("tag %d was not created by `newtag'", tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int lua_copytagmethods (int tagto, int tagfrom)
|
int lua_copytagmethods (int tagto, int tagfrom) {
|
||||||
{
|
|
||||||
int e;
|
int e;
|
||||||
checktag(tagto);
|
checktag(tagto);
|
||||||
checktag(tagfrom);
|
checktag(tagfrom);
|
||||||
for (e=0; e<IM_N; e++) {
|
for (e=0; e<IM_N; e++) {
|
||||||
if (validevent(tagto, e))
|
if (luaT_validevent(tagto, e))
|
||||||
*luaT_getim(tagto, e) = *luaT_getim(tagfrom, e);
|
*luaT_getim(tagto, e) = *luaT_getim(tagfrom, e);
|
||||||
}
|
}
|
||||||
return tagto;
|
return tagto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int luaT_efectivetag (TObject *o)
|
int luaT_effectivetag (TObject *o) {
|
||||||
{
|
|
||||||
int t;
|
int t;
|
||||||
switch (t = ttype(o)) {
|
switch (t = ttype(o)) {
|
||||||
case LUA_T_ARRAY:
|
case LUA_T_ARRAY:
|
||||||
@@ -131,36 +118,33 @@ int luaT_efectivetag (TObject *o)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TObject *luaT_gettagmethod (int t, char *event)
|
TObject *luaT_gettagmethod (int t, char *event) {
|
||||||
{
|
|
||||||
int e = luaI_checkevent(event, luaT_eventname);
|
int e = luaI_checkevent(event, luaT_eventname);
|
||||||
checktag(t);
|
checktag(t);
|
||||||
if (validevent(t, e))
|
if (luaT_validevent(t, e))
|
||||||
return luaT_getim(t,e);
|
return luaT_getim(t,e);
|
||||||
else
|
else
|
||||||
return &luaO_nilobject;
|
return &luaO_nilobject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void luaT_settagmethod (int t, char *event, TObject *func)
|
void luaT_settagmethod (int t, char *event, TObject *func) {
|
||||||
{
|
|
||||||
TObject temp = *func;
|
TObject temp = *func;
|
||||||
int e = luaI_checkevent(event, luaT_eventname);
|
int e = luaI_checkevent(event, luaT_eventname);
|
||||||
checktag(t);
|
checktag(t);
|
||||||
if (!validevent(t, e))
|
if (!luaT_validevent(t, e))
|
||||||
luaL_verror("settagmethod: cannot change tag method `%.20s' for tag %d",
|
luaL_verror("cannot change tag method `%.20s' for type `%.20s'%.20s",
|
||||||
luaT_eventname[e], t);
|
luaT_eventname[e], luaO_typenames[-t],
|
||||||
|
(t == LUA_T_ARRAY || t == LUA_T_USERDATA) ? " with default tag"
|
||||||
|
: "");
|
||||||
*func = *luaT_getim(t,e);
|
*func = *luaT_getim(t,e);
|
||||||
*luaT_getim(t, e) = temp;
|
*luaT_getim(t, e) = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char *luaT_travtagmethods (int (*fn)(TObject *))
|
char *luaT_travtagmethods (int (*fn)(TObject *)) { /* ORDER IM */
|
||||||
{
|
|
||||||
int e;
|
int e;
|
||||||
if (fn(&L->errorim))
|
for (e=IM_GETTABLE; e<=IM_FUNCTION; e++) {
|
||||||
return "error";
|
|
||||||
for (e=IM_GETTABLE; e<=IM_FUNCTION; e++) { /* ORDER IM */
|
|
||||||
int t;
|
int t;
|
||||||
for (t=0; t>=L->last_tag; t--)
|
for (t=0; t>=L->last_tag; t--)
|
||||||
if (fn(luaT_getim(t,e)))
|
if (fn(luaT_getim(t,e)))
|
||||||
@@ -177,6 +161,7 @@ char *luaT_travtagmethods (int (*fn)(TObject *))
|
|||||||
#ifdef LUA_COMPAT2_5
|
#ifdef LUA_COMPAT2_5
|
||||||
|
|
||||||
#include "lapi.h"
|
#include "lapi.h"
|
||||||
|
#include "lstring.h"
|
||||||
|
|
||||||
static void errorFB (void)
|
static void errorFB (void)
|
||||||
{
|
{
|
||||||
@@ -191,23 +176,20 @@ static void errorFB (void)
|
|||||||
static void nilFB (void) { }
|
static void nilFB (void) { }
|
||||||
|
|
||||||
|
|
||||||
static void typeFB (void)
|
static void typeFB (void) {
|
||||||
{
|
|
||||||
lua_error("unexpected type");
|
lua_error("unexpected type");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void fillvalids (IMS e, TObject *func)
|
static void fillvalids (IMS e, TObject *func) {
|
||||||
{
|
|
||||||
int t;
|
int t;
|
||||||
for (t=LUA_T_NIL; t<=LUA_T_USERDATA; t++)
|
for (t=LUA_T_NIL; t<=LUA_T_USERDATA; t++)
|
||||||
if (validevent(t, e))
|
if (luaT_validevent(t, e))
|
||||||
*luaT_getim(t, e) = *func;
|
*luaT_getim(t, e) = *func;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void luaT_setfallback (void)
|
void luaT_setfallback (void) {
|
||||||
{
|
|
||||||
static char *oldnames [] = {"error", "getglobal", "arith", "order", NULL};
|
static char *oldnames [] = {"error", "getglobal", "arith", "order", NULL};
|
||||||
TObject oldfunc;
|
TObject oldfunc;
|
||||||
lua_CFunction replace;
|
lua_CFunction replace;
|
||||||
@@ -215,11 +197,13 @@ void luaT_setfallback (void)
|
|||||||
lua_Object func = lua_getparam(2);
|
lua_Object func = lua_getparam(2);
|
||||||
luaL_arg_check(lua_isfunction(func), 2, "function expected");
|
luaL_arg_check(lua_isfunction(func), 2, "function expected");
|
||||||
switch (luaL_findstring(name, oldnames)) {
|
switch (luaL_findstring(name, oldnames)) {
|
||||||
case 0: /* old error fallback */
|
case 0: { /* old error fallback */
|
||||||
oldfunc = L->errorim;
|
TObject *em = &(luaS_new("_ERRORMESSAGE")->u.s.globalval);
|
||||||
L->errorim = *luaA_Address(func);
|
oldfunc = *em;
|
||||||
|
*em = *luaA_Address(func);
|
||||||
replace = errorFB;
|
replace = errorFB;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 1: /* old getglobal fallback */
|
case 1: /* old getglobal fallback */
|
||||||
oldfunc = *luaT_getim(LUA_T_NIL, IM_GETGLOBAL);
|
oldfunc = *luaT_getim(LUA_T_NIL, IM_GETGLOBAL);
|
||||||
*luaT_getim(LUA_T_NIL, IM_GETGLOBAL) = *luaA_Address(func);
|
*luaT_getim(LUA_T_NIL, IM_GETGLOBAL) = *luaA_Address(func);
|
||||||
|
|||||||
6
ltm.h
6
ltm.h
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ltm.h,v 1.3 1997/11/19 17:29:23 roberto Exp roberto $
|
** $Id: ltm.h,v 1.4 1997/11/26 18:53:45 roberto Exp roberto $
|
||||||
** Tag methods
|
** Tag methods
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -45,14 +45,14 @@ struct IM {
|
|||||||
|
|
||||||
|
|
||||||
#define luaT_getim(tag,event) (&L->IMtable[-(tag)].int_method[event])
|
#define luaT_getim(tag,event) (&L->IMtable[-(tag)].int_method[event])
|
||||||
#define luaT_getimbyObj(o,e) (luaT_getim(luaT_efectivetag(o),(e)))
|
#define luaT_getimbyObj(o,e) (luaT_getim(luaT_effectivetag(o),(e)))
|
||||||
|
|
||||||
extern char *luaT_eventname[];
|
extern char *luaT_eventname[];
|
||||||
|
|
||||||
|
|
||||||
void luaT_init (void);
|
void luaT_init (void);
|
||||||
void luaT_realtag (int tag);
|
void luaT_realtag (int tag);
|
||||||
int luaT_efectivetag (TObject *o);
|
int luaT_effectivetag (TObject *o);
|
||||||
void luaT_settagmethod (int t, char *event, TObject *func);
|
void luaT_settagmethod (int t, char *event, TObject *func);
|
||||||
TObject *luaT_gettagmethod (int t, char *event);
|
TObject *luaT_gettagmethod (int t, char *event);
|
||||||
char *luaT_travtagmethods (int (*fn)(TObject *));
|
char *luaT_travtagmethods (int (*fn)(TObject *));
|
||||||
|
|||||||
57
lua.c
57
lua.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lua.c,v 1.13 1998/01/19 19:49:49 roberto Exp roberto $
|
** $Id: lua.c,v 1.18 1999/01/26 11:50:58 roberto Exp roberto $
|
||||||
** Lua stand-alone interpreter
|
** Lua stand-alone interpreter
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -32,27 +32,31 @@ typedef void (*handler)(int); /* type for signal actions */
|
|||||||
|
|
||||||
static void laction (int i);
|
static void laction (int i);
|
||||||
|
|
||||||
static handler lreset (void)
|
|
||||||
{
|
static lua_LHFunction old_linehook = NULL;
|
||||||
lua_linehook = NULL;
|
static lua_CHFunction old_callhook = NULL;
|
||||||
lua_callhook = NULL;
|
|
||||||
|
|
||||||
|
static handler lreset (void) {
|
||||||
return signal(SIGINT, laction);
|
return signal(SIGINT, laction);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lstop (void)
|
|
||||||
{
|
static void lstop (void) {
|
||||||
|
lua_setlinehook(old_linehook);
|
||||||
|
lua_setcallhook(old_callhook);
|
||||||
lreset();
|
lreset();
|
||||||
lua_error("interrupted!");
|
lua_error("interrupted!");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void laction (int i)
|
|
||||||
{
|
static void laction (int i) {
|
||||||
lua_linehook = (lua_LHFunction)lstop;
|
old_linehook = lua_setlinehook((lua_LHFunction)lstop);
|
||||||
lua_callhook = (lua_CHFunction)lstop;
|
old_callhook = lua_setcallhook((lua_CHFunction)lstop);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ldo (int (*f)(char *), char *name)
|
|
||||||
{
|
static int ldo (int (*f)(char *), char *name) {
|
||||||
int res;
|
int res;
|
||||||
handler h = lreset();
|
handler h = lreset();
|
||||||
res = f(name); /* dostring | dofile */
|
res = f(name); /* dostring | dofile */
|
||||||
@@ -61,8 +65,7 @@ static int ldo (int (*f)(char *), char *name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void print_message (void)
|
static void print_message (void) {
|
||||||
{
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Lua: command line options:\n"
|
"Lua: command line options:\n"
|
||||||
" -v print version information\n"
|
" -v print version information\n"
|
||||||
@@ -76,8 +79,7 @@ static void print_message (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void assign (char *arg)
|
static void assign (char *arg) {
|
||||||
{
|
|
||||||
if (strlen(arg) >= 500)
|
if (strlen(arg) >= 500)
|
||||||
fprintf(stderr, "lua: shell argument too long");
|
fprintf(stderr, "lua: shell argument too long");
|
||||||
else {
|
else {
|
||||||
@@ -90,13 +92,11 @@ static void assign (char *arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define BUF_SIZE 512
|
|
||||||
|
|
||||||
static void manual_input (int prompt)
|
static void manual_input (int prompt) {
|
||||||
{
|
|
||||||
int cont = 1;
|
int cont = 1;
|
||||||
while (cont) {
|
while (cont) {
|
||||||
char buffer[BUF_SIZE];
|
char buffer[BUFSIZ];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
lua_beginblock();
|
lua_beginblock();
|
||||||
if (prompt)
|
if (prompt)
|
||||||
@@ -112,13 +112,13 @@ static void manual_input (int prompt)
|
|||||||
buffer[i-1] = '\n';
|
buffer[i-1] = '\n';
|
||||||
else break;
|
else break;
|
||||||
}
|
}
|
||||||
else if (i >= BUF_SIZE-1) {
|
else if (i >= BUFSIZ-1) {
|
||||||
fprintf(stderr, "lua: argument line too long\n");
|
fprintf(stderr, "lua: argument line too long\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else buffer[i++] = c;
|
else buffer[i++] = (char)c;
|
||||||
}
|
}
|
||||||
buffer[i] = 0;
|
buffer[i] = '\0';
|
||||||
ldo(lua_dostring, buffer);
|
ldo(lua_dostring, buffer);
|
||||||
lua_endblock();
|
lua_endblock();
|
||||||
}
|
}
|
||||||
@@ -129,11 +129,10 @@ static void manual_input (int prompt)
|
|||||||
int main (int argc, char *argv[])
|
int main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
setlocale(LC_ALL, "");
|
lua_open();
|
||||||
lua_iolibopen();
|
|
||||||
lua_strlibopen();
|
|
||||||
lua_mathlibopen();
|
|
||||||
lua_pushstring("> "); lua_setglobal("_PROMPT");
|
lua_pushstring("> "); lua_setglobal("_PROMPT");
|
||||||
|
setlocale(LC_ALL, "");
|
||||||
|
lua_userinit();
|
||||||
if (argc < 2) { /* no arguments? */
|
if (argc < 2) { /* no arguments? */
|
||||||
if (isatty(0)) {
|
if (isatty(0)) {
|
||||||
printf("%s %s\n", LUA_VERSION, LUA_COPYRIGHT);
|
printf("%s %s\n", LUA_VERSION, LUA_COPYRIGHT);
|
||||||
@@ -155,7 +154,7 @@ int main (int argc, char *argv[])
|
|||||||
manual_input(0);
|
manual_input(0);
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
lua_debug = 1;
|
lua_setdebug(1);
|
||||||
break;
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
printf("%s %s\n(written by %s)\n\n",
|
printf("%s %s\n(written by %s)\n\n",
|
||||||
|
|||||||
29
lua.h
29
lua.h
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lua.h,v 1.22 1998/06/15 21:34:14 roberto Exp roberto $
|
** $Id: lua.h,v 1.30 1999/02/25 19:13:56 roberto Exp roberto $
|
||||||
** Lua - An Extensible Extension Language
|
** Lua - An Extensible Extension Language
|
||||||
** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil
|
** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil
|
||||||
** e-mail: lua@tecgraf.puc-rio.br
|
** e-mail: lua@tecgraf.puc-rio.br
|
||||||
@@ -11,8 +11,8 @@
|
|||||||
#ifndef lua_h
|
#ifndef lua_h
|
||||||
#define lua_h
|
#define lua_h
|
||||||
|
|
||||||
#define LUA_VERSION "Lua 3.1"
|
#define LUA_VERSION "Lua 3.2 (beta)"
|
||||||
#define LUA_COPYRIGHT "Copyright (C) 1994-1998 TeCGraf, PUC-Rio"
|
#define LUA_COPYRIGHT "Copyright (C) 1994-1999 TeCGraf, PUC-Rio"
|
||||||
#define LUA_AUTHORS "W. Celes, R. Ierusalimschy & L. H. de Figueiredo"
|
#define LUA_AUTHORS "W. Celes, R. Ierusalimschy & L. H. de Figueiredo"
|
||||||
|
|
||||||
|
|
||||||
@@ -20,19 +20,18 @@
|
|||||||
|
|
||||||
#define LUA_ANYTAG (-1)
|
#define LUA_ANYTAG (-1)
|
||||||
|
|
||||||
typedef void (*lua_CFunction) (void);
|
|
||||||
typedef unsigned int lua_Object;
|
|
||||||
|
|
||||||
typedef struct lua_State lua_State;
|
typedef struct lua_State lua_State;
|
||||||
extern lua_State *lua_state;
|
extern lua_State *lua_state;
|
||||||
|
|
||||||
|
typedef void (*lua_CFunction) (void);
|
||||||
|
typedef unsigned int lua_Object;
|
||||||
|
|
||||||
void lua_open (void);
|
void lua_open (void);
|
||||||
void lua_close (void);
|
void lua_close (void);
|
||||||
lua_State *lua_setstate (lua_State *st);
|
lua_State *lua_setstate (lua_State *st);
|
||||||
|
|
||||||
lua_Object lua_settagmethod (int tag, char *event); /* In: new method */
|
lua_Object lua_settagmethod (int tag, char *event); /* In: new method */
|
||||||
lua_Object lua_gettagmethod (int tag, char *event);
|
lua_Object lua_gettagmethod (int tag, char *event);
|
||||||
lua_Object lua_seterrormethod (void); /* In: new method */
|
|
||||||
|
|
||||||
int lua_newtag (void);
|
int lua_newtag (void);
|
||||||
int lua_copytagmethods (int tagto, int tagfrom);
|
int lua_copytagmethods (int tagto, int tagfrom);
|
||||||
@@ -90,6 +89,9 @@ lua_Object lua_rawgettable (void); /* In: table, index */
|
|||||||
|
|
||||||
int lua_tag (lua_Object object);
|
int lua_tag (lua_Object object);
|
||||||
|
|
||||||
|
char *lua_nextvar (char *varname); /* Out: value */
|
||||||
|
int lua_next (lua_Object o, int i);
|
||||||
|
/* Out: ref, value */
|
||||||
|
|
||||||
int lua_ref (int lock); /* In: value */
|
int lua_ref (int lock); /* In: value */
|
||||||
lua_Object lua_getref (int ref);
|
lua_Object lua_getref (int ref);
|
||||||
@@ -101,29 +103,23 @@ long lua_collectgarbage (long limit);
|
|||||||
|
|
||||||
|
|
||||||
/* =============================================================== */
|
/* =============================================================== */
|
||||||
/* some useful macros/derived functions */
|
/* some useful macros/functions */
|
||||||
|
|
||||||
int (lua_call) (char *name);
|
|
||||||
#define lua_call(name) lua_callfunction(lua_getglobal(name))
|
#define lua_call(name) lua_callfunction(lua_getglobal(name))
|
||||||
|
|
||||||
void (lua_pushref) (int ref);
|
|
||||||
#define lua_pushref(ref) lua_pushobject(lua_getref(ref))
|
#define lua_pushref(ref) lua_pushobject(lua_getref(ref))
|
||||||
|
|
||||||
int (lua_refobject) (lua_Object o, int l);
|
|
||||||
#define lua_refobject(o,l) (lua_pushobject(o), lua_ref(l))
|
#define lua_refobject(o,l) (lua_pushobject(o), lua_ref(l))
|
||||||
|
|
||||||
void (lua_register) (char *n, lua_CFunction f);
|
|
||||||
#define lua_register(n,f) (lua_pushcfunction(f), lua_setglobal(n))
|
#define lua_register(n,f) (lua_pushcfunction(f), lua_setglobal(n))
|
||||||
|
|
||||||
void (lua_pushuserdata) (void *u);
|
|
||||||
#define lua_pushuserdata(u) lua_pushusertag(u, 0)
|
#define lua_pushuserdata(u) lua_pushusertag(u, 0)
|
||||||
|
|
||||||
void (lua_pushcfunction) (lua_CFunction f);
|
|
||||||
#define lua_pushcfunction(f) lua_pushcclosure(f, 0)
|
#define lua_pushcfunction(f) lua_pushcclosure(f, 0)
|
||||||
|
|
||||||
int (lua_clonetag) (int t);
|
|
||||||
#define lua_clonetag(t) lua_copytagmethods(lua_newtag(), (t))
|
#define lua_clonetag(t) lua_copytagmethods(lua_newtag(), (t))
|
||||||
|
|
||||||
|
lua_Object lua_seterrormethod (void); /* In: new method */
|
||||||
|
|
||||||
/* ==========================================================================
|
/* ==========================================================================
|
||||||
** for compatibility with old versions. Avoid using these macros/functions
|
** for compatibility with old versions. Avoid using these macros/functions
|
||||||
@@ -162,7 +158,7 @@ lua_Object lua_setfallback (char *event, lua_CFunction fallback);
|
|||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Copyright (c) 1994-1998 TeCGraf, PUC-Rio. All rights reserved.
|
* Copyright (c) 1994-1999 TeCGraf, PUC-Rio. All rights reserved.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, without written agreement and without license
|
* Permission is hereby granted, without written agreement and without license
|
||||||
* or royalty fees, to use, copy, modify, and distribute this software and its
|
* or royalty fees, to use, copy, modify, and distribute this software and its
|
||||||
@@ -192,5 +188,6 @@ lua_Object lua_setfallback (char *event, lua_CFunction fallback);
|
|||||||
* The Lua language and this implementation have been entirely designed and
|
* The Lua language and this implementation have been entirely designed and
|
||||||
* written by Waldemar Celes Filho, Roberto Ierusalimschy and
|
* written by Waldemar Celes Filho, Roberto Ierusalimschy and
|
||||||
* Luiz Henrique de Figueiredo at TeCGraf, PUC-Rio.
|
* Luiz Henrique de Figueiredo at TeCGraf, PUC-Rio.
|
||||||
|
*
|
||||||
* This implementation contains no third-party code.
|
* This implementation contains no third-party code.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|||||||
11
luadebug.h
11
luadebug.h
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: luadebug.h,v 1.1 1997/09/16 19:25:59 roberto Exp roberto $
|
** $Id: luadebug.h,v 1.5 1999/02/04 17:47:59 roberto Exp roberto $
|
||||||
** Debugging API
|
** Debugging API
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -17,17 +17,18 @@ typedef void (*lua_LHFunction) (int line);
|
|||||||
typedef void (*lua_CHFunction) (lua_Function func, char *file, int line);
|
typedef void (*lua_CHFunction) (lua_Function func, char *file, int line);
|
||||||
|
|
||||||
lua_Function lua_stackedfunction (int level);
|
lua_Function lua_stackedfunction (int level);
|
||||||
void lua_funcinfo (lua_Object func, char **filename, int *linedefined);
|
void lua_funcinfo (lua_Object func, char **source, int *linedefined);
|
||||||
int lua_currentline (lua_Function func);
|
int lua_currentline (lua_Function func);
|
||||||
char *lua_getobjname (lua_Object o, char **name);
|
char *lua_getobjname (lua_Object o, char **name);
|
||||||
|
|
||||||
lua_Object lua_getlocal (lua_Function func, int local_number, char **name);
|
lua_Object lua_getlocal (lua_Function func, int local_number, char **name);
|
||||||
int lua_setlocal (lua_Function func, int local_number);
|
int lua_setlocal (lua_Function func, int local_number);
|
||||||
|
|
||||||
|
int lua_nups (lua_Function func);
|
||||||
|
|
||||||
extern lua_LHFunction lua_linehook;
|
lua_LHFunction lua_setlinehook (lua_LHFunction func);
|
||||||
extern lua_CHFunction lua_callhook;
|
lua_CHFunction lua_setcallhook (lua_CHFunction func);
|
||||||
extern int lua_debug;
|
int lua_setdebug (int debug);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
5
lualib.h
5
lualib.h
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lualib.h,v 1.3 1997/12/17 20:48:58 roberto Exp roberto $
|
** $Id: lualib.h,v 1.4 1998/06/19 16:14:09 roberto Exp roberto $
|
||||||
** Lua standard libraries
|
** Lua standard libraries
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -10,12 +10,13 @@
|
|||||||
|
|
||||||
#include "lua.h"
|
#include "lua.h"
|
||||||
|
|
||||||
|
|
||||||
void lua_iolibopen (void);
|
void lua_iolibopen (void);
|
||||||
void lua_strlibopen (void);
|
void lua_strlibopen (void);
|
||||||
void lua_mathlibopen (void);
|
void lua_mathlibopen (void);
|
||||||
|
void lua_dblibopen (void);
|
||||||
|
|
||||||
|
|
||||||
|
void lua_userinit (void);
|
||||||
|
|
||||||
|
|
||||||
/* To keep compatibility with old versions */
|
/* To keep compatibility with old versions */
|
||||||
|
|||||||
170
lundump.c
170
lundump.c
@@ -1,105 +1,93 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lundump.c,v 1.10 1998/06/25 15:50:09 lhf Exp $
|
** $Id: lundump.c,v 1.18 1999/04/09 03:10:40 lhf Exp lhf $
|
||||||
** load bytecodes from files
|
** load bytecodes from files
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
#include "lauxlib.h"
|
#include "lauxlib.h"
|
||||||
#include "lfunc.h"
|
#include "lfunc.h"
|
||||||
#include "lmem.h"
|
#include "lmem.h"
|
||||||
|
#include "lopcodes.h"
|
||||||
#include "lstring.h"
|
#include "lstring.h"
|
||||||
#include "lundump.h"
|
#include "lundump.h"
|
||||||
|
|
||||||
#define LoadBlock(b,size,Z) ezread(Z,b,size)
|
#define LoadBlock(b,size,Z) ezread(Z,b,size)
|
||||||
#define LoadNative(t,Z) LoadBlock(&t,sizeof(t),Z)
|
|
||||||
|
|
||||||
#if ID_NUMBER==ID_NATIVE
|
#if LUAC_NATIVE
|
||||||
#define doLoadNumber(f,Z) LoadNative(f,Z)
|
#define doLoadNumber(x,Z) LoadBlock(&x,sizeof(x),Z)
|
||||||
#else
|
#else
|
||||||
#define doLoadNumber(f,Z) f=LoadNumber(Z)
|
#define doLoadNumber(x,Z) x=LoadNumber(Z)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void unexpectedEOZ(ZIO* Z)
|
static void unexpectedEOZ (ZIO* Z)
|
||||||
{
|
{
|
||||||
luaL_verror("unexpected end of file in %s",zname(Z));
|
luaL_verror("unexpected end of file in %s",zname(Z));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ezgetc(ZIO* Z)
|
static int ezgetc (ZIO* Z)
|
||||||
{
|
{
|
||||||
int c=zgetc(Z);
|
int c=zgetc(Z);
|
||||||
if (c==EOZ) unexpectedEOZ(Z);
|
if (c==EOZ) unexpectedEOZ(Z);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ezread(ZIO* Z, void* b, int n)
|
static void ezread (ZIO* Z, void* b, int n)
|
||||||
{
|
{
|
||||||
int r=zread(Z,b,n);
|
int r=zread(Z,b,n);
|
||||||
if (r!=0) unexpectedEOZ(Z);
|
if (r!=0) unexpectedEOZ(Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int LoadWord(ZIO* Z)
|
static unsigned int LoadWord (ZIO* Z)
|
||||||
{
|
{
|
||||||
unsigned int hi=ezgetc(Z);
|
unsigned int hi=ezgetc(Z);
|
||||||
unsigned int lo=ezgetc(Z);
|
unsigned int lo=ezgetc(Z);
|
||||||
return (hi<<8)|lo;
|
return (hi<<8)|lo;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned long LoadLong(ZIO* Z)
|
static unsigned long LoadLong (ZIO* Z)
|
||||||
{
|
{
|
||||||
unsigned long hi=LoadWord(Z);
|
unsigned long hi=LoadWord(Z);
|
||||||
unsigned long lo=LoadWord(Z);
|
unsigned long lo=LoadWord(Z);
|
||||||
return (hi<<16)|lo;
|
return (hi<<16)|lo;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ID_NUMBER==ID_REAL4
|
static real LoadNumber (ZIO* Z)
|
||||||
/* LUA_NUMBER */
|
{
|
||||||
/* assumes sizeof(long)==4 and sizeof(float)==4 (IEEE) */
|
char b[256];
|
||||||
static float LoadFloat(ZIO* Z)
|
int size=ezgetc(Z);
|
||||||
|
LoadBlock(b,size,Z);
|
||||||
|
b[size]=0;
|
||||||
|
if (b[0]=='-')
|
||||||
|
return -luaO_str2d(b+1);
|
||||||
|
else
|
||||||
|
return luaO_str2d(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int LoadInt (ZIO* Z, char* message)
|
||||||
{
|
{
|
||||||
unsigned long l=LoadLong(Z);
|
unsigned long l=LoadLong(Z);
|
||||||
float f=*(float*)&l;
|
unsigned int i=l;
|
||||||
return f;
|
if (i!=l) luaL_verror(message,l,zname(Z));
|
||||||
|
return i;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if ID_NUMBER==ID_REAL8
|
#define PAD 5 /* two word operands plus opcode */
|
||||||
/* LUA_NUMBER */
|
|
||||||
/* assumes sizeof(long)==4 and sizeof(double)==8 (IEEE) */
|
|
||||||
static double LoadDouble(ZIO* Z)
|
|
||||||
{
|
|
||||||
unsigned long l[2];
|
|
||||||
double f;
|
|
||||||
int x=1;
|
|
||||||
if (*(char*)&x==1) /* little-endian */
|
|
||||||
{
|
|
||||||
l[1]=LoadLong(Z);
|
|
||||||
l[0]=LoadLong(Z);
|
|
||||||
}
|
|
||||||
else /* big-endian */
|
|
||||||
{
|
|
||||||
l[0]=LoadLong(Z);
|
|
||||||
l[1]=LoadLong(Z);
|
|
||||||
}
|
|
||||||
f=*(double*)l;
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static Byte* LoadCode(ZIO* Z)
|
static Byte* LoadCode (ZIO* Z)
|
||||||
{
|
{
|
||||||
unsigned long size=LoadLong(Z);
|
int size=LoadInt(Z,"code too long (%ld bytes) in %s");
|
||||||
unsigned int s=size;
|
Byte* b=luaM_malloc(size+PAD);
|
||||||
void* b;
|
|
||||||
if (s!=size) luaL_verror("code too long (%ld bytes) in %s",size,zname(Z));
|
|
||||||
b=luaM_malloc(size);
|
|
||||||
LoadBlock(b,size,Z);
|
LoadBlock(b,size,Z);
|
||||||
|
if (b[size-1]!=ENDCODE) luaL_verror("bad code in %s",zname(Z));
|
||||||
|
memset(b+size,ENDCODE,PAD); /* pad code for safety */
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
static TaggedString* LoadTString(ZIO* Z)
|
static TaggedString* LoadTString (ZIO* Z)
|
||||||
{
|
{
|
||||||
int size=LoadWord(Z);
|
long size=LoadLong(Z);
|
||||||
if (size==0)
|
if (size==0)
|
||||||
return NULL;
|
return NULL;
|
||||||
else
|
else
|
||||||
@@ -110,65 +98,65 @@ static TaggedString* LoadTString(ZIO* Z)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void LoadLocals(TProtoFunc* tf, ZIO* Z)
|
static void LoadLocals (TProtoFunc* tf, ZIO* Z)
|
||||||
{
|
{
|
||||||
int i,n=LoadWord(Z);
|
int i,n=LoadInt(Z,"too many locals (%ld) in %s");
|
||||||
if (n==0) return;
|
if (n==0) return;
|
||||||
tf->locvars=luaM_newvector(n+1,LocVar);
|
tf->locvars=luaM_newvector(n+1,LocVar);
|
||||||
for (i=0; i<n; i++)
|
for (i=0; i<n; i++)
|
||||||
{
|
{
|
||||||
tf->locvars[i].line=LoadWord(Z);
|
tf->locvars[i].line=LoadInt(Z,"too many lines (%ld) in %s");
|
||||||
tf->locvars[i].varname=LoadTString(Z);
|
tf->locvars[i].varname=LoadTString(Z);
|
||||||
}
|
}
|
||||||
tf->locvars[i].line=-1; /* flag end of vector */
|
tf->locvars[i].line=-1; /* flag end of vector */
|
||||||
tf->locvars[i].varname=NULL;
|
tf->locvars[i].varname=NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static TProtoFunc* LoadFunction(ZIO* Z);
|
static TProtoFunc* LoadFunction (ZIO* Z);
|
||||||
|
|
||||||
static void LoadConstants(TProtoFunc* tf, ZIO* Z)
|
static void LoadConstants (TProtoFunc* tf, ZIO* Z)
|
||||||
{
|
{
|
||||||
int i,n=LoadWord(Z);
|
int i,n=LoadInt(Z,"too many constants (%ld) in %s");
|
||||||
tf->nconsts=n;
|
tf->nconsts=n;
|
||||||
if (n==0) return;
|
if (n==0) return;
|
||||||
tf->consts=luaM_newvector(n,TObject);
|
tf->consts=luaM_newvector(n,TObject);
|
||||||
for (i=0; i<n; i++)
|
for (i=0; i<n; i++)
|
||||||
{
|
{
|
||||||
TObject* o=tf->consts+i;
|
TObject* o=tf->consts+i;
|
||||||
int c=ezgetc(Z);
|
ttype(o)=-ezgetc(Z); /* ttype(o) is negative - ORDER LUA_T */
|
||||||
switch (c)
|
switch (ttype(o))
|
||||||
{
|
{
|
||||||
case ID_NUM:
|
case LUA_T_NUMBER:
|
||||||
ttype(o)=LUA_T_NUMBER;
|
|
||||||
doLoadNumber(nvalue(o),Z);
|
doLoadNumber(nvalue(o),Z);
|
||||||
break;
|
break;
|
||||||
case ID_STR:
|
case LUA_T_STRING:
|
||||||
ttype(o)=LUA_T_STRING;
|
|
||||||
tsvalue(o)=LoadTString(Z);
|
tsvalue(o)=LoadTString(Z);
|
||||||
break;
|
break;
|
||||||
case ID_FUN:
|
case LUA_T_PROTO:
|
||||||
ttype(o)=LUA_T_PROTO;
|
|
||||||
tfvalue(o)=LoadFunction(Z);
|
tfvalue(o)=LoadFunction(Z);
|
||||||
break;
|
break;
|
||||||
default:
|
case LUA_T_NIL:
|
||||||
luaL_verror("bad constant #%d in %s: type=%d ('%c')",i,zname(Z),c,c);
|
break;
|
||||||
|
default: /* cannot happen */
|
||||||
|
luaU_badconstant("load",i,o,tf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static TProtoFunc* LoadFunction(ZIO* Z)
|
static TProtoFunc* LoadFunction (ZIO* Z)
|
||||||
{
|
{
|
||||||
TProtoFunc* tf=luaF_newproto();
|
TProtoFunc* tf=luaF_newproto();
|
||||||
tf->lineDefined=LoadWord(Z);
|
tf->lineDefined=LoadInt(Z,"lineDefined too large (%ld) in %s");
|
||||||
tf->fileName=LoadTString(Z);
|
tf->source=LoadTString(Z);
|
||||||
|
if (tf->source==NULL) tf->source=luaS_new(zname(Z));
|
||||||
tf->code=LoadCode(Z);
|
tf->code=LoadCode(Z);
|
||||||
LoadLocals(tf,Z);
|
LoadLocals(tf,Z);
|
||||||
LoadConstants(tf,Z);
|
LoadConstants(tf,Z);
|
||||||
return tf;
|
return tf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void LoadSignature(ZIO* Z)
|
static void LoadSignature (ZIO* Z)
|
||||||
{
|
{
|
||||||
char* s=SIGNATURE;
|
char* s=SIGNATURE;
|
||||||
while (*s!=0 && ezgetc(Z)==*s)
|
while (*s!=0 && ezgetc(Z)==*s)
|
||||||
@@ -176,10 +164,9 @@ static void LoadSignature(ZIO* Z)
|
|||||||
if (*s!=0) luaL_verror("bad signature in %s",zname(Z));
|
if (*s!=0) luaL_verror("bad signature in %s",zname(Z));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void LoadHeader(ZIO* Z)
|
static void LoadHeader (ZIO* Z)
|
||||||
{
|
{
|
||||||
int version,id,sizeofR;
|
int version,sizeofR;
|
||||||
real f=-TEST_NUMBER,tf=TEST_NUMBER;
|
|
||||||
LoadSignature(Z);
|
LoadSignature(Z);
|
||||||
version=ezgetc(Z);
|
version=ezgetc(Z);
|
||||||
if (version>VERSION)
|
if (version>VERSION)
|
||||||
@@ -190,22 +177,33 @@ static void LoadHeader(ZIO* Z)
|
|||||||
luaL_verror(
|
luaL_verror(
|
||||||
"%s too old: version=0x%02x; expected at least 0x%02x",
|
"%s too old: version=0x%02x; expected at least 0x%02x",
|
||||||
zname(Z),version,VERSION0);
|
zname(Z),version,VERSION0);
|
||||||
id=ezgetc(Z); /* test number representation */
|
sizeofR=ezgetc(Z); /* test number representation */
|
||||||
sizeofR=ezgetc(Z);
|
#if LUAC_NATIVE
|
||||||
if (id!=ID_NUMBER || sizeofR!=sizeof(real))
|
if (sizeofR==0)
|
||||||
|
luaL_verror("cannot read numbers in %s: "
|
||||||
|
"support for decimal format not enabled",
|
||||||
|
zname(Z));
|
||||||
|
if (sizeofR!=sizeof(real))
|
||||||
|
luaL_verror("unknown number size in %s: read %d; expected %d",
|
||||||
|
zname(Z),sizeofR,sizeof(real));
|
||||||
|
else
|
||||||
{
|
{
|
||||||
luaL_verror("unknown number signature in %s: "
|
real f=-TEST_NUMBER,tf=TEST_NUMBER;
|
||||||
"read 0x%02x%02x; expected 0x%02x%02x",
|
|
||||||
zname(Z),id,sizeofR,ID_NUMBER,sizeof(real));
|
|
||||||
}
|
|
||||||
doLoadNumber(f,Z);
|
doLoadNumber(f,Z);
|
||||||
if (f!=tf)
|
if (f!=tf)
|
||||||
luaL_verror("unknown number representation in %s: "
|
luaL_verror("unknown number representation in %s: "
|
||||||
"read " NUMBER_FMT "; expected " NUMBER_FMT "", /* LUA_NUMBER */
|
"read " NUMBER_FMT "; expected " NUMBER_FMT,
|
||||||
zname(Z),(double)f,(double)tf);
|
zname(Z),f,tf);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (sizeofR!=0)
|
||||||
|
luaL_verror("cannot read numbers in %s: "
|
||||||
|
"support for native format not enabled",
|
||||||
|
zname(Z));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static TProtoFunc* LoadChunk(ZIO* Z)
|
static TProtoFunc* LoadChunk (ZIO* Z)
|
||||||
{
|
{
|
||||||
LoadHeader(Z);
|
LoadHeader(Z);
|
||||||
return LoadFunction(Z);
|
return LoadFunction(Z);
|
||||||
@@ -215,7 +213,7 @@ static TProtoFunc* LoadChunk(ZIO* Z)
|
|||||||
** load one chunk from a file or buffer
|
** load one chunk from a file or buffer
|
||||||
** return main if ok and NULL at EOF
|
** return main if ok and NULL at EOF
|
||||||
*/
|
*/
|
||||||
TProtoFunc* luaU_undump1(ZIO* Z)
|
TProtoFunc* luaU_undump1 (ZIO* Z)
|
||||||
{
|
{
|
||||||
int c=zgetc(Z);
|
int c=zgetc(Z);
|
||||||
if (c==ID_CHUNK)
|
if (c==ID_CHUNK)
|
||||||
@@ -224,3 +222,13 @@ TProtoFunc* luaU_undump1(ZIO* Z)
|
|||||||
luaL_verror("%s is not a Lua binary file",zname(Z));
|
luaL_verror("%s is not a Lua binary file",zname(Z));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* handle constants that cannot happen
|
||||||
|
*/
|
||||||
|
void luaU_badconstant (char* s, int i, TObject* o, TProtoFunc* tf)
|
||||||
|
{
|
||||||
|
int t=ttype(o);
|
||||||
|
char* name= (t>0 || t<LUA_T_LINE) ? "?" : luaO_typenames[-t];
|
||||||
|
luaL_verror("cannot %s constant #%d: type=%d [%s]" IN,s,i,t,name,INLOC);
|
||||||
|
}
|
||||||
|
|||||||
87
lundump.h
87
lundump.h
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lundump.h,v 1.7 1998/06/25 15:50:09 lhf Exp $
|
** $Id: lundump.h,v 1.13 1999/03/29 16:16:18 lhf Exp lhf $
|
||||||
** load pre-compiled Lua chunks
|
** load pre-compiled Lua chunks
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -10,72 +10,39 @@
|
|||||||
#include "lobject.h"
|
#include "lobject.h"
|
||||||
#include "lzio.h"
|
#include "lzio.h"
|
||||||
|
|
||||||
TProtoFunc* luaU_undump1(ZIO* Z); /* load one chunk */
|
TProtoFunc* luaU_undump1 (ZIO* Z); /* load one chunk */
|
||||||
|
void luaU_badconstant (char* s, int i, TObject* o, TProtoFunc* tf);
|
||||||
|
/* handle cases that cannot happen */
|
||||||
|
|
||||||
#define SIGNATURE "Lua"
|
/* definitions for headers of binary files */
|
||||||
#define VERSION 0x31 /* last format change was in 3.1 */
|
#define VERSION 0x32 /* last format change was in 3.2 */
|
||||||
#define VERSION0 0x31 /* last major change was in 3.1 */
|
#define VERSION0 0x32 /* last major change was in 3.2 */
|
||||||
|
#define ID_CHUNK 27 /* binary files start with ESC... */
|
||||||
|
#define SIGNATURE "Lua" /* ...followed by this signature */
|
||||||
|
|
||||||
#define IsMain(f) (f->lineDefined==0)
|
/* formats for error messages */
|
||||||
|
#define SOURCE "<%s:%d>"
|
||||||
|
#define IN " in %p " SOURCE
|
||||||
|
#define INLOC tf,tf->source->str,tf->lineDefined
|
||||||
|
|
||||||
#define ID_CHUNK 27 /* ESC */
|
/* format for numbers in listings and error messages */
|
||||||
#define ID_NUM 'N'
|
#ifndef NUMBER_FMT
|
||||||
#define ID_STR 'S'
|
#define NUMBER_FMT "%.16g" /* LUA_NUMBER */
|
||||||
#define ID_FUN 'F'
|
#endif
|
||||||
|
|
||||||
/* number representation */
|
|
||||||
#define ID_INT4 'l' /* 4-byte integers */
|
|
||||||
#define ID_REAL4 'f' /* 4-byte reals */
|
|
||||||
#define ID_REAL8 'd' /* 8-byte reals */
|
|
||||||
#define ID_NATIVE '?' /* whatever your machine uses */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* use a multiple of PI for testing number representation.
|
|
||||||
* multiplying by 1E8 gives notrivial integer values.
|
|
||||||
*/
|
|
||||||
#define TEST_NUMBER 3.14159265358979323846E8
|
|
||||||
|
|
||||||
/* LUA_NUMBER
|
/* LUA_NUMBER
|
||||||
* choose one below for the number representation in precompiled chunks.
|
* by default, numbers are stored in precompiled chunks as decimal strings.
|
||||||
* the default is ID_REAL8 because the default for LUA_NUM_TYPE is double.
|
* this is completely portable and fast enough for most applications.
|
||||||
* if your machine does not use IEEE 754, use ID_NATIVE.
|
* if you want to use this default, do nothing.
|
||||||
* the next version will support conversion to/from IEEE 754.
|
* if you want additional speed at the expense of portability, move the line
|
||||||
*
|
* below out of this comment.
|
||||||
* if you change LUA_NUM_TYPE, make sure you set ID_NUMBER accordingly,
|
#define LUAC_NATIVE
|
||||||
* specially if sizeof(long)!=4.
|
|
||||||
* for types other than the ones listed below, you'll have to write your own
|
|
||||||
* dump and undump routines.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef ID_NUMBER
|
#ifdef LUAC_NATIVE
|
||||||
#define ID_NUMBER ID_NATIVE
|
/* a multiple of PI for testing number representation */
|
||||||
#endif
|
/* multiplying by 1E8 gives non-trivial integer values */
|
||||||
|
#define TEST_NUMBER 3.14159265358979323846E8
|
||||||
#if 0
|
|
||||||
#define ID_NUMBER ID_INT4
|
|
||||||
#define ID_NUMBER ID_REAL4
|
|
||||||
#define ID_NUMBER ID_REAL8
|
|
||||||
#define ID_NUMBER ID_NATIVE
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ID_NUMBER==ID_REAL4
|
|
||||||
#define DumpNumber DumpFloat
|
|
||||||
#define LoadNumber LoadFloat
|
|
||||||
#define SIZEOF_NUMBER 4
|
|
||||||
#elif ID_NUMBER==ID_REAL8
|
|
||||||
#define DumpNumber DumpDouble
|
|
||||||
#define LoadNumber LoadDouble
|
|
||||||
#define SIZEOF_NUMBER 8
|
|
||||||
#elif ID_NUMBER==ID_INT4
|
|
||||||
#define DumpNumber DumpLong
|
|
||||||
#define LoadNumber LoadLong
|
|
||||||
#define SIZEOF_NUMBER 4
|
|
||||||
#elif ID_NUMBER==ID_NATIVE
|
|
||||||
#define DumpNumber DumpNative
|
|
||||||
#define LoadNumber LoadNative
|
|
||||||
#define SIZEOF_NUMBER sizeof(real)
|
|
||||||
#else
|
|
||||||
#error bad ID_NUMBER
|
|
||||||
#endif
|
|
||||||
|
|||||||
599
lvm.c
599
lvm.c
@@ -1,11 +1,14 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lvm.c,v 1.29 1998/05/31 22:18:24 roberto Exp roberto $
|
** $Id: lvm.c,v 1.54 1999/03/10 14:09:45 roberto Exp roberto $
|
||||||
** Lua virtual machine
|
** Lua virtual machine
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <limits.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "lauxlib.h"
|
#include "lauxlib.h"
|
||||||
@@ -13,6 +16,7 @@
|
|||||||
#include "lfunc.h"
|
#include "lfunc.h"
|
||||||
#include "lgc.h"
|
#include "lgc.h"
|
||||||
#include "lmem.h"
|
#include "lmem.h"
|
||||||
|
#include "lobject.h"
|
||||||
#include "lopcodes.h"
|
#include "lopcodes.h"
|
||||||
#include "lstate.h"
|
#include "lstate.h"
|
||||||
#include "lstring.h"
|
#include "lstring.h"
|
||||||
@@ -27,9 +31,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define skip_word(pc) (pc+=2)
|
#define highbyte(x) ((x)<<8)
|
||||||
#define get_word(pc) ((*(pc)<<8)+(*((pc)+1)))
|
|
||||||
#define next_word(pc) (pc+=2, get_word(pc-2))
|
|
||||||
|
|
||||||
|
|
||||||
/* Extra stack size to run a function: LUA_T_LINE(1), TM calls(2), ... */
|
/* Extra stack size to run a function: LUA_T_LINE(1), TM calls(2), ... */
|
||||||
@@ -37,45 +39,47 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static TaggedString *strconc (TaggedString *l, TaggedString *r)
|
static TaggedString *strconc (TaggedString *l, TaggedString *r) {
|
||||||
{
|
long nl = l->u.s.len;
|
||||||
size_t nl = l->u.s.len;
|
long nr = r->u.s.len;
|
||||||
size_t nr = r->u.s.len;
|
char *buffer = luaL_openspace(nl+nr);
|
||||||
char *buffer = luaL_openspace(nl+nr+1);
|
|
||||||
memcpy(buffer, l->str, nl);
|
memcpy(buffer, l->str, nl);
|
||||||
memcpy(buffer+nl, r->str, nr);
|
memcpy(buffer+nl, r->str, nr);
|
||||||
return luaS_newlstr(buffer, nl+nr);
|
return luaS_newlstr(buffer, nl+nr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int luaV_tonumber (TObject *obj)
|
int luaV_tonumber (TObject *obj) { /* LUA_NUMBER */
|
||||||
{ /* LUA_NUMBER */
|
|
||||||
double t;
|
|
||||||
char c;
|
|
||||||
if (ttype(obj) != LUA_T_STRING)
|
if (ttype(obj) != LUA_T_STRING)
|
||||||
return 1;
|
return 1;
|
||||||
else if (sscanf(svalue(obj), "%lf %c",&t, &c) == 1) {
|
else {
|
||||||
nvalue(obj) = (real)t;
|
double t;
|
||||||
|
char *e = svalue(obj);
|
||||||
|
int sig = 1;
|
||||||
|
while (isspace((unsigned char)*e)) e++;
|
||||||
|
if (*e == '-') {
|
||||||
|
e++;
|
||||||
|
sig = -1;
|
||||||
|
}
|
||||||
|
else if (*e == '+') e++;
|
||||||
|
/* no digit before or after decimal point? */
|
||||||
|
if (!isdigit((unsigned char)*e) && !isdigit((unsigned char)*(e+1)))
|
||||||
|
return 2;
|
||||||
|
t = luaO_str2d(e);
|
||||||
|
if (t<0) return 2;
|
||||||
|
nvalue(obj) = (real)t*sig;
|
||||||
ttype(obj) = LUA_T_NUMBER;
|
ttype(obj) = LUA_T_NUMBER;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
return 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int luaV_tostring (TObject *obj)
|
int luaV_tostring (TObject *obj) { /* LUA_NUMBER */
|
||||||
{ /* LUA_NUMBER */
|
|
||||||
if (ttype(obj) != LUA_T_NUMBER)
|
if (ttype(obj) != LUA_T_NUMBER)
|
||||||
return 1;
|
return 1;
|
||||||
else {
|
else {
|
||||||
char s[60];
|
char s[32]; /* 16 digits, signal, point and \0 (+ some extra...) */
|
||||||
real f = nvalue(obj);
|
sprintf(s, "%.16g", (double)nvalue(obj));
|
||||||
int i;
|
|
||||||
if ((real)(-MAX_INT) <= f && f <= (real)MAX_INT && (real)(i=(int)f) == f)
|
|
||||||
sprintf (s, "%d", i);
|
|
||||||
else
|
|
||||||
sprintf (s, NUMBER_FMT, nvalue(obj));
|
|
||||||
tsvalue(obj) = luaS_new(s);
|
tsvalue(obj) = luaS_new(s);
|
||||||
ttype(obj) = LUA_T_STRING;
|
ttype(obj) = LUA_T_STRING;
|
||||||
return 0;
|
return 0;
|
||||||
@@ -83,8 +87,15 @@ int luaV_tostring (TObject *obj)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void luaV_closure (int nelems)
|
void luaV_setn (Hash *t, int val) {
|
||||||
{
|
TObject index, value;
|
||||||
|
ttype(&index) = LUA_T_STRING; tsvalue(&index) = luaS_new("n");
|
||||||
|
ttype(&value) = LUA_T_NUMBER; nvalue(&value) = val;
|
||||||
|
luaH_set(t, &index, &value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void luaV_closure (int nelems) {
|
||||||
if (nelems > 0) {
|
if (nelems > 0) {
|
||||||
struct Stack *S = &L->stack;
|
struct Stack *S = &L->stack;
|
||||||
Closure *c = luaF_newclosure(nelems);
|
Closure *c = luaF_newclosure(nelems);
|
||||||
@@ -101,94 +112,104 @@ void luaV_closure (int nelems)
|
|||||||
** Function to index a table.
|
** Function to index a table.
|
||||||
** Receives the table at top-2 and the index at top-1.
|
** Receives the table at top-2 and the index at top-1.
|
||||||
*/
|
*/
|
||||||
void luaV_gettable (void)
|
void luaV_gettable (void) {
|
||||||
{
|
TObject *table = L->stack.top-2;
|
||||||
struct Stack *S = &L->stack;
|
|
||||||
TObject *im;
|
TObject *im;
|
||||||
if (ttype(S->top-2) != LUA_T_ARRAY) /* not a table, get "gettable" method */
|
if (ttype(table) != LUA_T_ARRAY) { /* not a table, get gettable method */
|
||||||
im = luaT_getimbyObj(S->top-2, IM_GETTABLE);
|
im = luaT_getimbyObj(table, IM_GETTABLE);
|
||||||
|
if (ttype(im) == LUA_T_NIL)
|
||||||
|
lua_error("indexed expression not a table");
|
||||||
|
}
|
||||||
else { /* object is a table... */
|
else { /* object is a table... */
|
||||||
int tg = (S->top-2)->value.a->htag;
|
int tg = table->value.a->htag;
|
||||||
im = luaT_getim(tg, IM_GETTABLE);
|
im = luaT_getim(tg, IM_GETTABLE);
|
||||||
if (ttype(im) == LUA_T_NIL) { /* and does not have a "gettable" method */
|
if (ttype(im) == LUA_T_NIL) { /* and does not have a "gettable" method */
|
||||||
TObject *h = luaH_get(avalue(S->top-2), S->top-1);
|
TObject *h = luaH_get(avalue(table), table+1);
|
||||||
if (h != NULL && ttype(h) != LUA_T_NIL) {
|
if (ttype(h) == LUA_T_NIL &&
|
||||||
--S->top;
|
(ttype(im=luaT_getim(tg, IM_INDEX)) != LUA_T_NIL)) {
|
||||||
*(S->top-1) = *h;
|
/* result is nil and there is an "index" tag method */
|
||||||
|
luaD_callTM(im, 2, 1); /* calls it */
|
||||||
}
|
}
|
||||||
else if (ttype(im=luaT_getim(tg, IM_INDEX)) != LUA_T_NIL)
|
|
||||||
luaD_callTM(im, 2, 1);
|
|
||||||
else {
|
else {
|
||||||
--S->top;
|
L->stack.top--;
|
||||||
ttype(S->top-1) = LUA_T_NIL;
|
*table = *h; /* "push" result into table position */
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* else it has a "gettable" method, go through to next command */
|
/* else it has a "gettable" method, go through to next command */
|
||||||
}
|
}
|
||||||
/* object is not a table, or it has a "gettable" method */
|
/* object is not a table, or it has a "gettable" method */
|
||||||
if (ttype(im) != LUA_T_NIL)
|
luaD_callTM(im, 2, 1);
|
||||||
luaD_callTM(im, 2, 1);
|
|
||||||
else
|
|
||||||
lua_error("indexed expression not a table");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Function to store indexed based on values at the stack.top
|
** Receives table at *t, index at *(t+1) and value at top.
|
||||||
** mode = 0: raw store (without tag methods)
|
|
||||||
** mode = 1: normal store (with tag methods)
|
|
||||||
** mode = 2: "deep L->stack.stack" store (with tag methods)
|
|
||||||
*/
|
*/
|
||||||
void luaV_settable (TObject *t, int mode)
|
void luaV_settable (TObject *t) {
|
||||||
{
|
|
||||||
struct Stack *S = &L->stack;
|
struct Stack *S = &L->stack;
|
||||||
TObject *im = (mode == 0) ? NULL : luaT_getimbyObj(t, IM_SETTABLE);
|
TObject *im;
|
||||||
if (ttype(t) == LUA_T_ARRAY && (im == NULL || ttype(im) == LUA_T_NIL)) {
|
if (ttype(t) != LUA_T_ARRAY) { /* not a table, get "settable" method */
|
||||||
TObject *h = luaH_set(avalue(t), t+1);
|
im = luaT_getimbyObj(t, IM_SETTABLE);
|
||||||
*h = *(S->top-1);
|
if (ttype(im) == LUA_T_NIL)
|
||||||
S->top -= (mode == 2) ? 1 : 3;
|
|
||||||
}
|
|
||||||
else { /* object is not a table, and/or has a specific "settable" method */
|
|
||||||
if (im && ttype(im) != LUA_T_NIL) {
|
|
||||||
if (mode == 2) {
|
|
||||||
*(S->top+1) = *(L->stack.top-1);
|
|
||||||
*(S->top) = *(t+1);
|
|
||||||
*(S->top-1) = *t;
|
|
||||||
S->top += 2; /* WARNING: caller must assure stack space */
|
|
||||||
}
|
|
||||||
luaD_callTM(im, 3, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
lua_error("indexed expression not a table");
|
lua_error("indexed expression not a table");
|
||||||
}
|
}
|
||||||
|
else { /* object is a table... */
|
||||||
|
im = luaT_getim(avalue(t)->htag, IM_SETTABLE);
|
||||||
|
if (ttype(im) == LUA_T_NIL) { /* and does not have a "settable" method */
|
||||||
|
luaH_set(avalue(t), t+1, S->top-1);
|
||||||
|
S->top--; /* pop value */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* else it has a "settable" method, go through to next command */
|
||||||
|
}
|
||||||
|
/* object is not a table, or it has a "settable" method */
|
||||||
|
/* prepare arguments and call the tag method */
|
||||||
|
*(S->top+1) = *(L->stack.top-1);
|
||||||
|
*(S->top) = *(t+1);
|
||||||
|
*(S->top-1) = *t;
|
||||||
|
S->top += 2; /* WARNING: caller must assure stack space */
|
||||||
|
luaD_callTM(im, 3, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void luaV_getglobal (TaggedString *ts)
|
void luaV_rawsettable (TObject *t) {
|
||||||
{
|
if (ttype(t) != LUA_T_ARRAY)
|
||||||
/* WARNING: caller must assure stack space */
|
lua_error("indexed expression not a table");
|
||||||
TObject *value = &ts->u.s.globalval;
|
|
||||||
TObject *im = luaT_getimbyObj(value, IM_GETGLOBAL);
|
|
||||||
if (ttype(im) == LUA_T_NIL) { /* default behavior */
|
|
||||||
*L->stack.top++ = *value;
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
struct Stack *S = &L->stack;
|
struct Stack *S = &L->stack;
|
||||||
ttype(S->top) = LUA_T_STRING;
|
luaH_set(avalue(t), t+1, S->top-1);
|
||||||
tsvalue(S->top) = ts;
|
S->top -= 3;
|
||||||
S->top++;
|
|
||||||
*S->top++ = *value;
|
|
||||||
luaD_callTM(im, 2, 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void luaV_setglobal (TaggedString *ts)
|
void luaV_getglobal (TaggedString *ts) {
|
||||||
{
|
/* WARNING: caller must assure stack space */
|
||||||
|
/* only userdata, tables and nil can have getglobal tag methods */
|
||||||
|
static char valid_getglobals[] = {1, 0, 0, 1, 0, 0, 1, 0}; /* ORDER LUA_T */
|
||||||
|
TObject *value = &ts->u.s.globalval;
|
||||||
|
if (valid_getglobals[-ttype(value)]) {
|
||||||
|
TObject *im = luaT_getimbyObj(value, IM_GETGLOBAL);
|
||||||
|
if (ttype(im) != LUA_T_NIL) { /* is there a tag method? */
|
||||||
|
struct Stack *S = &L->stack;
|
||||||
|
ttype(S->top) = LUA_T_STRING;
|
||||||
|
tsvalue(S->top) = ts;
|
||||||
|
S->top++;
|
||||||
|
*S->top++ = *value;
|
||||||
|
luaD_callTM(im, 2, 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* else no tag method: go through to default behavior */
|
||||||
|
}
|
||||||
|
*L->stack.top++ = *value; /* default behavior */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void luaV_setglobal (TaggedString *ts) {
|
||||||
TObject *oldvalue = &ts->u.s.globalval;
|
TObject *oldvalue = &ts->u.s.globalval;
|
||||||
TObject *im = luaT_getimbyObj(oldvalue, IM_SETGLOBAL);
|
TObject *im = luaT_getimbyObj(oldvalue, IM_SETGLOBAL);
|
||||||
if (ttype(im) == LUA_T_NIL) /* default behavior */
|
if (ttype(im) == LUA_T_NIL) /* is there a tag method? */
|
||||||
luaS_rawsetglobal(ts, --L->stack.top);
|
luaS_rawsetglobal(ts, --L->stack.top);
|
||||||
else {
|
else {
|
||||||
/* WARNING: caller must assure stack space */
|
/* WARNING: caller must assure stack space */
|
||||||
@@ -225,7 +246,7 @@ static void call_arith (IMS event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int strcomp (char *l, long ll, char *r, long lr)
|
static int luaV_strcomp (char *l, long ll, char *r, long lr)
|
||||||
{
|
{
|
||||||
for (;;) {
|
for (;;) {
|
||||||
long temp = strcoll(l, r);
|
long temp = strcoll(l, r);
|
||||||
@@ -242,18 +263,17 @@ static int strcomp (char *l, long ll, char *r, long lr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void comparison (lua_Type ttype_less, lua_Type ttype_equal,
|
void luaV_comparison (lua_Type ttype_less, lua_Type ttype_equal,
|
||||||
lua_Type ttype_great, IMS op)
|
lua_Type ttype_great, IMS op) {
|
||||||
{
|
|
||||||
struct Stack *S = &L->stack;
|
struct Stack *S = &L->stack;
|
||||||
TObject *l = S->top-2;
|
TObject *l = S->top-2;
|
||||||
TObject *r = S->top-1;
|
TObject *r = S->top-1;
|
||||||
int result;
|
real result;
|
||||||
if (ttype(l) == LUA_T_NUMBER && ttype(r) == LUA_T_NUMBER)
|
if (ttype(l) == LUA_T_NUMBER && ttype(r) == LUA_T_NUMBER)
|
||||||
result = (nvalue(l) < nvalue(r)) ? -1 : (nvalue(l) == nvalue(r)) ? 0 : 1;
|
result = nvalue(l)-nvalue(r);
|
||||||
else if (ttype(l) == LUA_T_STRING && ttype(r) == LUA_T_STRING)
|
else if (ttype(l) == LUA_T_STRING && ttype(r) == LUA_T_STRING)
|
||||||
result = strcomp(svalue(l), tsvalue(l)->u.s.len,
|
result = luaV_strcomp(svalue(l), tsvalue(l)->u.s.len,
|
||||||
svalue(r), tsvalue(r)->u.s.len);
|
svalue(r), tsvalue(r)->u.s.len);
|
||||||
else {
|
else {
|
||||||
call_binTM(op, "unexpected type in comparison");
|
call_binTM(op, "unexpected type in comparison");
|
||||||
return;
|
return;
|
||||||
@@ -265,27 +285,16 @@ static void comparison (lua_Type ttype_less, lua_Type ttype_equal,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void luaV_pack (StkId firstel, int nvararg, TObject *tab)
|
void luaV_pack (StkId firstel, int nvararg, TObject *tab) {
|
||||||
{
|
|
||||||
TObject *firstelem = L->stack.stack+firstel;
|
TObject *firstelem = L->stack.stack+firstel;
|
||||||
int i;
|
int i;
|
||||||
|
Hash *htab;
|
||||||
if (nvararg < 0) nvararg = 0;
|
if (nvararg < 0) nvararg = 0;
|
||||||
avalue(tab) = luaH_new(nvararg+1); /* +1 for field 'n' */
|
htab = avalue(tab) = luaH_new(nvararg+1); /* +1 for field 'n' */
|
||||||
ttype(tab) = LUA_T_ARRAY;
|
ttype(tab) = LUA_T_ARRAY;
|
||||||
for (i=0; i<nvararg; i++) {
|
for (i=0; i<nvararg; i++)
|
||||||
TObject index;
|
luaH_setint(htab, i+1, firstelem+i);
|
||||||
ttype(&index) = LUA_T_NUMBER;
|
luaV_setn(htab, nvararg); /* store counter in field "n" */
|
||||||
nvalue(&index) = i+1;
|
|
||||||
*(luaH_set(avalue(tab), &index)) = *(firstelem+i);
|
|
||||||
}
|
|
||||||
/* store counter in field "n" */ {
|
|
||||||
TObject index, extra;
|
|
||||||
ttype(&index) = LUA_T_STRING;
|
|
||||||
tsvalue(&index) = luaS_new("n");
|
|
||||||
ttype(&extra) = LUA_T_NUMBER;
|
|
||||||
nvalue(&extra) = nvararg;
|
|
||||||
*(luaH_set(avalue(tab), &index)) = extra;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -305,12 +314,11 @@ static void adjust_varargs (StkId first_extra_arg)
|
|||||||
** [stack+base,top). Returns n such that the the results are between
|
** [stack+base,top). Returns n such that the the results are between
|
||||||
** [stack+n,top).
|
** [stack+n,top).
|
||||||
*/
|
*/
|
||||||
StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base)
|
StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) {
|
||||||
{
|
|
||||||
struct Stack *S = &L->stack; /* to optimize */
|
struct Stack *S = &L->stack; /* to optimize */
|
||||||
Byte *pc = tf->code;
|
register Byte *pc = tf->code;
|
||||||
TObject *consts = tf->consts;
|
TObject *consts = tf->consts;
|
||||||
if (lua_callhook)
|
if (L->callhook)
|
||||||
luaD_callHook(base, tf, 0);
|
luaD_callHook(base, tf, 0);
|
||||||
luaD_checkstack((*pc++)+EXTRA_STACK);
|
luaD_checkstack((*pc++)+EXTRA_STACK);
|
||||||
if (*pc < ZEROVARARG)
|
if (*pc < ZEROVARARG)
|
||||||
@@ -319,86 +327,82 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base)
|
|||||||
luaC_checkGC();
|
luaC_checkGC();
|
||||||
adjust_varargs(base+(*pc++)-ZEROVARARG);
|
adjust_varargs(base+(*pc++)-ZEROVARARG);
|
||||||
}
|
}
|
||||||
while (1) {
|
for (;;) {
|
||||||
int aux;
|
register int aux = 0;
|
||||||
switch ((OpCode)(aux = *pc++)) {
|
switchentry:
|
||||||
|
switch ((OpCode)*pc++) {
|
||||||
|
|
||||||
case PUSHNIL0:
|
case ENDCODE:
|
||||||
ttype(S->top++) = LUA_T_NIL;
|
S->top = S->stack + base;
|
||||||
|
goto ret;
|
||||||
|
|
||||||
|
case RETCODE:
|
||||||
|
base += *pc++;
|
||||||
|
goto ret;
|
||||||
|
|
||||||
|
case CALL: aux = *pc++;
|
||||||
|
luaD_call((S->top-S->stack)-(*pc++), aux);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PUSHNIL:
|
case TAILCALL: aux = *pc++;
|
||||||
aux = *pc++;
|
luaD_call((S->top-S->stack)-(*pc++), MULT_RET);
|
||||||
|
base += aux;
|
||||||
|
goto ret;
|
||||||
|
|
||||||
|
case PUSHNIL: aux = *pc++;
|
||||||
do {
|
do {
|
||||||
ttype(S->top++) = LUA_T_NIL;
|
ttype(S->top++) = LUA_T_NIL;
|
||||||
} while (aux--);
|
} while (aux--);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PUSHNUMBER:
|
case POP: aux = *pc++;
|
||||||
aux = *pc++; goto pushnumber;
|
S->top -= aux;
|
||||||
|
break;
|
||||||
|
|
||||||
case PUSHNUMBERW:
|
case PUSHNUMBERW: aux += highbyte(*pc++);
|
||||||
aux = next_word(pc); goto pushnumber;
|
case PUSHNUMBER: aux += *pc++;
|
||||||
|
|
||||||
case PUSHNUMBER0: case PUSHNUMBER1: case PUSHNUMBER2:
|
|
||||||
aux -= PUSHNUMBER0;
|
|
||||||
pushnumber:
|
|
||||||
ttype(S->top) = LUA_T_NUMBER;
|
ttype(S->top) = LUA_T_NUMBER;
|
||||||
nvalue(S->top) = aux;
|
nvalue(S->top) = aux;
|
||||||
S->top++;
|
S->top++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PUSHLOCAL:
|
case PUSHNUMBERNEGW: aux += highbyte(*pc++);
|
||||||
aux = *pc++; goto pushlocal;
|
case PUSHNUMBERNEG: aux += *pc++;
|
||||||
|
ttype(S->top) = LUA_T_NUMBER;
|
||||||
|
nvalue(S->top) = -aux;
|
||||||
|
S->top++;
|
||||||
|
break;
|
||||||
|
|
||||||
case PUSHLOCAL0: case PUSHLOCAL1: case PUSHLOCAL2: case PUSHLOCAL3:
|
case PUSHCONSTANTW: aux += highbyte(*pc++);
|
||||||
case PUSHLOCAL4: case PUSHLOCAL5: case PUSHLOCAL6: case PUSHLOCAL7:
|
case PUSHCONSTANT: aux += *pc++;
|
||||||
aux -= PUSHLOCAL0;
|
*S->top++ = consts[aux];
|
||||||
pushlocal:
|
break;
|
||||||
|
|
||||||
|
case PUSHUPVALUE: aux = *pc++;
|
||||||
|
*S->top++ = cl->consts[aux+1];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PUSHLOCAL: aux = *pc++;
|
||||||
*S->top++ = *((S->stack+base) + aux);
|
*S->top++ = *((S->stack+base) + aux);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GETGLOBALW:
|
case GETGLOBALW: aux += highbyte(*pc++);
|
||||||
aux = next_word(pc); goto getglobal;
|
case GETGLOBAL: aux += *pc++;
|
||||||
|
|
||||||
case GETGLOBAL:
|
|
||||||
aux = *pc++; goto getglobal;
|
|
||||||
|
|
||||||
case GETGLOBAL0: case GETGLOBAL1: case GETGLOBAL2: case GETGLOBAL3:
|
|
||||||
case GETGLOBAL4: case GETGLOBAL5: case GETGLOBAL6: case GETGLOBAL7:
|
|
||||||
aux -= GETGLOBAL0;
|
|
||||||
getglobal:
|
|
||||||
luaV_getglobal(tsvalue(&consts[aux]));
|
luaV_getglobal(tsvalue(&consts[aux]));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GETTABLE:
|
case GETTABLE:
|
||||||
luaV_gettable();
|
luaV_gettable();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GETDOTTEDW:
|
case GETDOTTEDW: aux += highbyte(*pc++);
|
||||||
aux = next_word(pc); goto getdotted;
|
case GETDOTTED: aux += *pc++;
|
||||||
|
|
||||||
case GETDOTTED:
|
|
||||||
aux = *pc++; goto getdotted;
|
|
||||||
|
|
||||||
case GETDOTTED0: case GETDOTTED1: case GETDOTTED2: case GETDOTTED3:
|
|
||||||
case GETDOTTED4: case GETDOTTED5: case GETDOTTED6: case GETDOTTED7:
|
|
||||||
aux -= GETDOTTED0;
|
|
||||||
getdotted:
|
|
||||||
*S->top++ = consts[aux];
|
*S->top++ = consts[aux];
|
||||||
luaV_gettable();
|
luaV_gettable();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PUSHSELFW:
|
case PUSHSELFW: aux += highbyte(*pc++);
|
||||||
aux = next_word(pc); goto pushself;
|
case PUSHSELF: aux += *pc++; {
|
||||||
|
|
||||||
case PUSHSELF:
|
|
||||||
aux = *pc++; goto pushself;
|
|
||||||
|
|
||||||
case PUSHSELF0: case PUSHSELF1: case PUSHSELF2: case PUSHSELF3:
|
|
||||||
case PUSHSELF4: case PUSHSELF5: case PUSHSELF6: case PUSHSELF7:
|
|
||||||
aux -= PUSHSELF0;
|
|
||||||
pushself: {
|
|
||||||
TObject receiver = *(S->top-1);
|
TObject receiver = *(S->top-1);
|
||||||
*S->top++ = consts[aux];
|
*S->top++ = consts[aux];
|
||||||
luaV_gettable();
|
luaV_gettable();
|
||||||
@@ -406,141 +410,75 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case PUSHCONSTANTW:
|
case CREATEARRAYW: aux += highbyte(*pc++);
|
||||||
aux = next_word(pc); goto pushconstant;
|
case CREATEARRAY: aux += *pc++;
|
||||||
|
|
||||||
case PUSHCONSTANT:
|
|
||||||
aux = *pc++; goto pushconstant;
|
|
||||||
|
|
||||||
case PUSHCONSTANT0: case PUSHCONSTANT1: case PUSHCONSTANT2:
|
|
||||||
case PUSHCONSTANT3: case PUSHCONSTANT4: case PUSHCONSTANT5:
|
|
||||||
case PUSHCONSTANT6: case PUSHCONSTANT7:
|
|
||||||
aux -= PUSHCONSTANT0;
|
|
||||||
pushconstant:
|
|
||||||
*S->top++ = consts[aux];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PUSHUPVALUE:
|
|
||||||
aux = *pc++; goto pushupvalue;
|
|
||||||
|
|
||||||
case PUSHUPVALUE0: case PUSHUPVALUE1:
|
|
||||||
aux -= PUSHUPVALUE0;
|
|
||||||
pushupvalue:
|
|
||||||
*S->top++ = cl->consts[aux+1];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SETLOCAL:
|
|
||||||
aux = *pc++; goto setlocal;
|
|
||||||
|
|
||||||
case SETLOCAL0: case SETLOCAL1: case SETLOCAL2: case SETLOCAL3:
|
|
||||||
case SETLOCAL4: case SETLOCAL5: case SETLOCAL6: case SETLOCAL7:
|
|
||||||
aux -= SETLOCAL0;
|
|
||||||
setlocal:
|
|
||||||
*((S->stack+base) + aux) = *(--S->top);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SETGLOBALW:
|
|
||||||
aux = next_word(pc); goto setglobal;
|
|
||||||
|
|
||||||
case SETGLOBAL:
|
|
||||||
aux = *pc++; goto setglobal;
|
|
||||||
|
|
||||||
case SETGLOBAL0: case SETGLOBAL1: case SETGLOBAL2: case SETGLOBAL3:
|
|
||||||
case SETGLOBAL4: case SETGLOBAL5: case SETGLOBAL6: case SETGLOBAL7:
|
|
||||||
aux -= SETGLOBAL0;
|
|
||||||
setglobal:
|
|
||||||
luaV_setglobal(tsvalue(&consts[aux]));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SETTABLE0:
|
|
||||||
luaV_settable(S->top-3, 1);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SETTABLE:
|
|
||||||
luaV_settable(S->top-3-(*pc++), 2);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SETLISTW:
|
|
||||||
aux = next_word(pc); aux *= LFIELDS_PER_FLUSH; goto setlist;
|
|
||||||
|
|
||||||
case SETLIST:
|
|
||||||
aux = *(pc++) * LFIELDS_PER_FLUSH; goto setlist;
|
|
||||||
|
|
||||||
case SETLIST0:
|
|
||||||
aux = 0;
|
|
||||||
setlist: {
|
|
||||||
int n = *(pc++);
|
|
||||||
TObject *arr = S->top-n-1;
|
|
||||||
for (; n; n--) {
|
|
||||||
ttype(S->top) = LUA_T_NUMBER;
|
|
||||||
nvalue(S->top) = n+aux;
|
|
||||||
*(luaH_set(avalue(arr), S->top)) = *(S->top-1);
|
|
||||||
S->top--;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SETMAP0:
|
|
||||||
aux = 0; goto setmap;
|
|
||||||
|
|
||||||
case SETMAP:
|
|
||||||
aux = *pc++;
|
|
||||||
setmap: {
|
|
||||||
TObject *arr = S->top-(2*aux)-3;
|
|
||||||
do {
|
|
||||||
*(luaH_set(avalue(arr), S->top-2)) = *(S->top-1);
|
|
||||||
S->top-=2;
|
|
||||||
} while (aux--);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case POP:
|
|
||||||
aux = *pc++; goto pop;
|
|
||||||
|
|
||||||
case POP0: case POP1:
|
|
||||||
aux -= POP0;
|
|
||||||
pop:
|
|
||||||
S->top -= (aux+1);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CREATEARRAYW:
|
|
||||||
aux = next_word(pc); goto createarray;
|
|
||||||
|
|
||||||
case CREATEARRAY0: case CREATEARRAY1:
|
|
||||||
aux -= CREATEARRAY0; goto createarray;
|
|
||||||
|
|
||||||
case CREATEARRAY:
|
|
||||||
aux = *pc++;
|
|
||||||
createarray:
|
|
||||||
luaC_checkGC();
|
luaC_checkGC();
|
||||||
avalue(S->top) = luaH_new(aux);
|
avalue(S->top) = luaH_new(aux);
|
||||||
ttype(S->top) = LUA_T_ARRAY;
|
ttype(S->top) = LUA_T_ARRAY;
|
||||||
S->top++;
|
S->top++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EQOP: case NEQOP: {
|
case SETLOCAL: aux = *pc++;
|
||||||
|
*((S->stack+base) + aux) = *(--S->top);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SETGLOBALW: aux += highbyte(*pc++);
|
||||||
|
case SETGLOBAL: aux += *pc++;
|
||||||
|
luaV_setglobal(tsvalue(&consts[aux]));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SETTABLEPOP:
|
||||||
|
luaV_settable(S->top-3);
|
||||||
|
S->top -= 2; /* pop table and index */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SETTABLE:
|
||||||
|
luaV_settable(S->top-3-(*pc++));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SETLISTW: aux += highbyte(*pc++);
|
||||||
|
case SETLIST: aux += *pc++; {
|
||||||
|
int n = *(pc++);
|
||||||
|
TObject *arr = S->top-n-1;
|
||||||
|
aux *= LFIELDS_PER_FLUSH;
|
||||||
|
for (; n; n--)
|
||||||
|
luaH_setint(avalue(arr), n+aux, --S->top);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SETMAP: aux = *pc++; {
|
||||||
|
TObject *arr = S->top-(2*aux)-3;
|
||||||
|
do {
|
||||||
|
luaH_set(avalue(arr), S->top-2, S->top-1);
|
||||||
|
S->top-=2;
|
||||||
|
} while (aux--);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case NEQOP: aux = 1;
|
||||||
|
case EQOP: {
|
||||||
int res = luaO_equalObj(S->top-2, S->top-1);
|
int res = luaO_equalObj(S->top-2, S->top-1);
|
||||||
|
if (aux) res = !res;
|
||||||
S->top--;
|
S->top--;
|
||||||
if (aux == NEQOP) res = !res;
|
|
||||||
ttype(S->top-1) = res ? LUA_T_NUMBER : LUA_T_NIL;
|
ttype(S->top-1) = res ? LUA_T_NUMBER : LUA_T_NIL;
|
||||||
nvalue(S->top-1) = 1;
|
nvalue(S->top-1) = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case LTOP:
|
case LTOP:
|
||||||
comparison(LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT);
|
luaV_comparison(LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LEOP:
|
case LEOP:
|
||||||
comparison(LUA_T_NUMBER, LUA_T_NUMBER, LUA_T_NIL, IM_LE);
|
luaV_comparison(LUA_T_NUMBER, LUA_T_NUMBER, LUA_T_NIL, IM_LE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GTOP:
|
case GTOP:
|
||||||
comparison(LUA_T_NIL, LUA_T_NIL, LUA_T_NUMBER, IM_GT);
|
luaV_comparison(LUA_T_NIL, LUA_T_NIL, LUA_T_NUMBER, IM_GT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GEOP:
|
case GEOP:
|
||||||
comparison(LUA_T_NIL, LUA_T_NUMBER, LUA_T_NUMBER, IM_GE);
|
luaV_comparison(LUA_T_NIL, LUA_T_NUMBER, LUA_T_NUMBER, IM_GE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ADDOP: {
|
case ADDOP: {
|
||||||
@@ -624,98 +562,47 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base)
|
|||||||
nvalue(S->top-1) = 1;
|
nvalue(S->top-1) = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ONTJMPW:
|
case ONTJMPW: aux += highbyte(*pc++);
|
||||||
aux = next_word(pc); goto ontjmp;
|
case ONTJMP: aux += *pc++;
|
||||||
|
|
||||||
case ONTJMP:
|
|
||||||
aux = *pc++;
|
|
||||||
ontjmp:
|
|
||||||
if (ttype(S->top-1) != LUA_T_NIL) pc += aux;
|
if (ttype(S->top-1) != LUA_T_NIL) pc += aux;
|
||||||
else S->top--;
|
else S->top--;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ONFJMPW:
|
case ONFJMPW: aux += highbyte(*pc++);
|
||||||
aux = next_word(pc); goto onfjmp;
|
case ONFJMP: aux += *pc++;
|
||||||
|
|
||||||
case ONFJMP:
|
|
||||||
aux = *pc++;
|
|
||||||
onfjmp:
|
|
||||||
if (ttype(S->top-1) == LUA_T_NIL) pc += aux;
|
if (ttype(S->top-1) == LUA_T_NIL) pc += aux;
|
||||||
else S->top--;
|
else S->top--;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JMPW:
|
case JMPW: aux += highbyte(*pc++);
|
||||||
aux = next_word(pc); goto jmp;
|
case JMP: aux += *pc++;
|
||||||
|
|
||||||
case JMP:
|
|
||||||
aux = *pc++;
|
|
||||||
jmp:
|
|
||||||
pc += aux;
|
pc += aux;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IFFJMPW:
|
case IFFJMPW: aux += highbyte(*pc++);
|
||||||
aux = next_word(pc); goto iffjmp;
|
case IFFJMP: aux += *pc++;
|
||||||
|
|
||||||
case IFFJMP:
|
|
||||||
aux = *pc++;
|
|
||||||
iffjmp:
|
|
||||||
if (ttype(--S->top) == LUA_T_NIL) pc += aux;
|
if (ttype(--S->top) == LUA_T_NIL) pc += aux;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IFTUPJMPW:
|
case IFTUPJMPW: aux += highbyte(*pc++);
|
||||||
aux = next_word(pc); goto iftupjmp;
|
case IFTUPJMP: aux += *pc++;
|
||||||
|
|
||||||
case IFTUPJMP:
|
|
||||||
aux = *pc++;
|
|
||||||
iftupjmp:
|
|
||||||
if (ttype(--S->top) != LUA_T_NIL) pc -= aux;
|
if (ttype(--S->top) != LUA_T_NIL) pc -= aux;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IFFUPJMPW:
|
case IFFUPJMPW: aux += highbyte(*pc++);
|
||||||
aux = next_word(pc); goto iffupjmp;
|
case IFFUPJMP: aux += *pc++;
|
||||||
|
|
||||||
case IFFUPJMP:
|
|
||||||
aux = *pc++;
|
|
||||||
iffupjmp:
|
|
||||||
if (ttype(--S->top) == LUA_T_NIL) pc -= aux;
|
if (ttype(--S->top) == LUA_T_NIL) pc -= aux;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CLOSUREW:
|
case CLOSUREW: aux += highbyte(*pc++);
|
||||||
aux = next_word(pc); goto closure;
|
case CLOSURE: aux += *pc++;
|
||||||
|
|
||||||
case CLOSURE:
|
|
||||||
aux = *pc++;
|
|
||||||
closure:
|
|
||||||
*S->top++ = consts[aux];
|
*S->top++ = consts[aux];
|
||||||
luaV_closure(*pc++);
|
luaV_closure(*pc++);
|
||||||
luaC_checkGC();
|
luaC_checkGC();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CALLFUNC:
|
case SETLINEW: aux += highbyte(*pc++);
|
||||||
aux = *pc++; goto callfunc;
|
case SETLINE: aux += *pc++;
|
||||||
|
|
||||||
case CALLFUNC0: case CALLFUNC1:
|
|
||||||
aux -= CALLFUNC0;
|
|
||||||
callfunc: {
|
|
||||||
StkId newBase = (S->top-S->stack)-(*pc++);
|
|
||||||
luaD_call(newBase, aux);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case ENDCODE:
|
|
||||||
S->top = S->stack + base;
|
|
||||||
/* goes through */
|
|
||||||
case RETCODE:
|
|
||||||
if (lua_callhook)
|
|
||||||
luaD_callHook(base, NULL, 1);
|
|
||||||
return (base + ((aux==RETCODE) ? *pc : 0));
|
|
||||||
|
|
||||||
case SETLINEW:
|
|
||||||
aux = next_word(pc); goto setline;
|
|
||||||
|
|
||||||
case SETLINE:
|
|
||||||
aux = *pc++;
|
|
||||||
setline:
|
|
||||||
if ((S->stack+base-1)->ttype != LUA_T_LINE) {
|
if ((S->stack+base-1)->ttype != LUA_T_LINE) {
|
||||||
/* open space for LINE value */
|
/* open space for LINE value */
|
||||||
luaD_openstack((S->top-S->stack)-base);
|
luaD_openstack((S->top-S->stack)-base);
|
||||||
@@ -723,15 +610,23 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base)
|
|||||||
(S->stack+base-1)->ttype = LUA_T_LINE;
|
(S->stack+base-1)->ttype = LUA_T_LINE;
|
||||||
}
|
}
|
||||||
(S->stack+base-1)->value.i = aux;
|
(S->stack+base-1)->value.i = aux;
|
||||||
if (lua_linehook)
|
if (L->linehook)
|
||||||
luaD_lineHook(aux);
|
luaD_lineHook(aux);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef DEBUG
|
case LONGARGW: aux += highbyte(*pc++);
|
||||||
default:
|
case LONGARG: aux += *pc++;
|
||||||
LUA_INTERNALERROR("opcode doesn't match");
|
aux = highbyte(highbyte(aux));
|
||||||
#endif
|
goto switchentry; /* do not reset "aux" */
|
||||||
|
|
||||||
|
case CHECKSTACK: aux = *pc++;
|
||||||
|
LUA_ASSERT((S->top-S->stack)-base == aux, "wrong stack size");
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
} ret:
|
||||||
|
if (L->callhook)
|
||||||
|
luaD_callHook(0, NULL, 1);
|
||||||
|
return base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
9
lvm.h
9
lvm.h
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lvm.h,v 1.3 1997/10/16 10:59:34 roberto Exp roberto $
|
** $Id: lvm.h,v 1.7 1998/12/30 17:26:49 roberto Exp roberto $
|
||||||
** Lua virtual machine
|
** Lua virtual machine
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include "ldo.h"
|
#include "ldo.h"
|
||||||
#include "lobject.h"
|
#include "lobject.h"
|
||||||
|
#include "ltm.h"
|
||||||
|
|
||||||
|
|
||||||
#define tonumber(o) ((ttype(o) != LUA_T_NUMBER) && (luaV_tonumber(o) != 0))
|
#define tonumber(o) ((ttype(o) != LUA_T_NUMBER) && (luaV_tonumber(o) != 0))
|
||||||
@@ -19,11 +20,15 @@
|
|||||||
void luaV_pack (StkId firstel, int nvararg, TObject *tab);
|
void luaV_pack (StkId firstel, int nvararg, TObject *tab);
|
||||||
int luaV_tonumber (TObject *obj);
|
int luaV_tonumber (TObject *obj);
|
||||||
int luaV_tostring (TObject *obj);
|
int luaV_tostring (TObject *obj);
|
||||||
|
void luaV_setn (Hash *t, int val);
|
||||||
void luaV_gettable (void);
|
void luaV_gettable (void);
|
||||||
void luaV_settable (TObject *t, int mode);
|
void luaV_settable (TObject *t);
|
||||||
|
void luaV_rawsettable (TObject *t);
|
||||||
void luaV_getglobal (TaggedString *ts);
|
void luaV_getglobal (TaggedString *ts);
|
||||||
void luaV_setglobal (TaggedString *ts);
|
void luaV_setglobal (TaggedString *ts);
|
||||||
StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base);
|
StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base);
|
||||||
void luaV_closure (int nelems);
|
void luaV_closure (int nelems);
|
||||||
|
void luaV_comparison (lua_Type ttype_less, lua_Type ttype_equal,
|
||||||
|
lua_Type ttype_great, IMS op);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
22
lzio.c
22
lzio.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lzio.c,v 1.2 1997/11/21 19:00:46 roberto Exp roberto $
|
** $Id: lzio.c,v 1.6 1999/03/04 14:49:18 roberto Exp roberto $
|
||||||
** a generic input stream interface
|
** a generic input stream interface
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -15,11 +15,11 @@
|
|||||||
|
|
||||||
/* ----------------------------------------------------- memory buffers --- */
|
/* ----------------------------------------------------- memory buffers --- */
|
||||||
|
|
||||||
static int zmfilbuf (ZIO* z)
|
static int zmfilbuf (ZIO* z) {
|
||||||
{
|
|
||||||
return EOZ;
|
return EOZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ZIO* zmopen (ZIO* z, char* b, int size, char *name)
|
ZIO* zmopen (ZIO* z, char* b, int size, char *name)
|
||||||
{
|
{
|
||||||
if (b==NULL) return NULL;
|
if (b==NULL) return NULL;
|
||||||
@@ -41,9 +41,10 @@ ZIO* zsopen (ZIO* z, char* s, char *name)
|
|||||||
|
|
||||||
/* -------------------------------------------------------------- FILEs --- */
|
/* -------------------------------------------------------------- FILEs --- */
|
||||||
|
|
||||||
static int zffilbuf (ZIO* z)
|
static int zffilbuf (ZIO* z) {
|
||||||
{
|
int n;
|
||||||
int n=fread(z->buffer,1,ZBSIZE,z->u);
|
if (feof((FILE *)z->u)) return EOZ;
|
||||||
|
n=fread(z->buffer,1,ZBSIZE,z->u);
|
||||||
if (n==0) return EOZ;
|
if (n==0) return EOZ;
|
||||||
z->n=n-1;
|
z->n=n-1;
|
||||||
z->p=z->buffer;
|
z->p=z->buffer;
|
||||||
@@ -64,16 +65,15 @@ ZIO* zFopen (ZIO* z, FILE* f, char *name)
|
|||||||
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------- read --- */
|
/* --------------------------------------------------------------- read --- */
|
||||||
int zread (ZIO *z, void *b, int n)
|
int zread (ZIO *z, void *b, int n) {
|
||||||
{
|
|
||||||
while (n) {
|
while (n) {
|
||||||
int m;
|
int m;
|
||||||
if (z->n == 0) {
|
if (z->n == 0) {
|
||||||
if (z->filbuf(z) == EOZ)
|
if (z->filbuf(z) == EOZ)
|
||||||
return n; /* retorna quantos faltaram ler */
|
return n; /* return number of missing bytes */
|
||||||
zungetc(z); /* poe o resultado de filbuf no buffer */
|
zungetc(z); /* put result from 'filbuf' in the buffer */
|
||||||
}
|
}
|
||||||
m = (n <= z->n) ? n : z->n; /* minimo de n e z->n */
|
m = (n <= z->n) ? n : z->n; /* min. between n and z->n */
|
||||||
memcpy(b, z->p, m);
|
memcpy(b, z->p, m);
|
||||||
z->n -= m;
|
z->n -= m;
|
||||||
z->p += m;
|
z->p += m;
|
||||||
|
|||||||
72
makefile
72
makefile
@@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
## $Id: makefile,v 1.12 1998/05/27 13:03:40 roberto Exp roberto $
|
## $Id: makefile,v 1.18 1999/02/23 15:01:29 roberto Exp roberto $
|
||||||
## Makefile
|
## Makefile
|
||||||
## See Copyright Notice in lua.h
|
## See Copyright Notice in lua.h
|
||||||
#
|
#
|
||||||
@@ -12,13 +12,15 @@
|
|||||||
# define (undefine) _POSIX_SOURCE if your system is (not) POSIX compliant
|
# define (undefine) _POSIX_SOURCE if your system is (not) POSIX compliant
|
||||||
#
|
#
|
||||||
# define (undefine) OLD_ANSI if your system does NOT have some new ANSI
|
# define (undefine) OLD_ANSI if your system does NOT have some new ANSI
|
||||||
# facilities (e.g. strerror, locale.h, memmove). Although they are ANSI,
|
# facilities (e.g. strerror, locale.h, memmove). SunOS does not comply;
|
||||||
# SunOS does not comply; so, add "-DOLD_ANSI" on SunOS
|
# so, add "-DOLD_ANSI" on SunOS
|
||||||
#
|
#
|
||||||
# define LUA_COMPAT2_5 if yous system does need to be compatible with
|
# define LUA_COMPAT2_5 if yous system does need to be compatible with
|
||||||
# version 2.5 (or older)
|
# version 2.5 (or older)
|
||||||
#
|
#
|
||||||
# define LUA_NUM_TYPE if you need numbers to be different from double
|
# define LUA_NUM_TYPE if you need numbers to be different from double
|
||||||
|
# (for instance, -DLUA_NUM_TYPE=float)
|
||||||
|
#
|
||||||
|
|
||||||
CONFIG = -DPOPEN -D_POSIX_SOURCE
|
CONFIG = -DPOPEN -D_POSIX_SOURCE
|
||||||
#CONFIG = -DLUA_COMPAT2_5 -DOLD_ANSI -DDEBUG
|
#CONFIG = -DLUA_COMPAT2_5 -DOLD_ANSI -DDEBUG
|
||||||
@@ -30,6 +32,10 @@ CWARNS = -Wall -Wmissing-prototypes -Wshadow -pedantic -Wpointer-arith -Wcast-al
|
|||||||
CFLAGS = $(CONFIG) $(CWARNS) -ansi -O2
|
CFLAGS = $(CONFIG) $(CWARNS) -ansi -O2
|
||||||
|
|
||||||
|
|
||||||
|
# To make early versions
|
||||||
|
CO_OPTIONS =
|
||||||
|
|
||||||
|
|
||||||
AR = ar
|
AR = ar
|
||||||
ARFLAGS = rvl
|
ARFLAGS = rvl
|
||||||
|
|
||||||
@@ -58,7 +64,9 @@ LUAOBJS = \
|
|||||||
LIBOBJS = \
|
LIBOBJS = \
|
||||||
liolib.o \
|
liolib.o \
|
||||||
lmathlib.o \
|
lmathlib.o \
|
||||||
lstrlib.o
|
lstrlib.o \
|
||||||
|
ldblib.o \
|
||||||
|
linit.o
|
||||||
|
|
||||||
|
|
||||||
lua : lua.o liblua.a liblualib.a
|
lua : lua.o liblua.a liblualib.a
|
||||||
@@ -80,45 +88,53 @@ clear :
|
|||||||
rcsclean
|
rcsclean
|
||||||
rm -f *.o
|
rm -f *.o
|
||||||
rm -f
|
rm -f
|
||||||
co lua.h lualib.h luadebug.h
|
co $(CO_OPTIONS) lua.h lualib.h luadebug.h
|
||||||
|
|
||||||
|
|
||||||
%.h : RCS/%.h,v
|
%.h : RCS/%.h,v
|
||||||
co $@
|
co $(CO_OPTIONS) $@
|
||||||
|
|
||||||
%.c : RCS/%.c,v
|
%.c : RCS/%.c,v
|
||||||
co $@
|
co $(CO_OPTIONS) $@
|
||||||
|
|
||||||
|
|
||||||
lapi.o: lapi.c lapi.h lua.h lobject.h lauxlib.h ldo.h lstate.h lfunc.h \
|
lapi.o: lapi.c lapi.h lua.h lobject.h lauxlib.h ldo.h lstate.h \
|
||||||
lgc.h lmem.h lstring.h ltable.h ltm.h luadebug.h lvm.h
|
luadebug.h lfunc.h lgc.h lmem.h lstring.h ltable.h ltm.h lvm.h
|
||||||
lauxlib.o: lauxlib.c lauxlib.h lua.h luadebug.h
|
lauxlib.o: lauxlib.c lauxlib.h lua.h luadebug.h
|
||||||
lbuffer.o: lbuffer.c lauxlib.h lua.h lmem.h lstate.h lobject.h
|
lbuffer.o: lbuffer.c lauxlib.h lua.h lmem.h lstate.h lobject.h \
|
||||||
|
luadebug.h
|
||||||
lbuiltin.o: lbuiltin.c lapi.h lua.h lobject.h lauxlib.h lbuiltin.h \
|
lbuiltin.o: lbuiltin.c lapi.h lua.h lobject.h lauxlib.h lbuiltin.h \
|
||||||
ldo.h lstate.h lfunc.h lmem.h lstring.h ltable.h ltm.h lundump.h \
|
ldo.h lstate.h luadebug.h lfunc.h lmem.h lstring.h ltable.h ltm.h \
|
||||||
lzio.h
|
lundump.h lzio.h lvm.h
|
||||||
ldo.o: ldo.c ldo.h lobject.h lua.h lstate.h lfunc.h lgc.h lmem.h \
|
ldblib.o: ldblib.c lauxlib.h lua.h luadebug.h lualib.h
|
||||||
lparser.h lzio.h ltm.h luadebug.h lundump.h lvm.h
|
ldo.o: ldo.c ldo.h lobject.h lua.h lstate.h luadebug.h lfunc.h lgc.h \
|
||||||
lfunc.o: lfunc.c lfunc.h lobject.h lua.h lmem.h lstate.h
|
lmem.h lparser.h lzio.h lstring.h ltm.h lundump.h lvm.h
|
||||||
lgc.o: lgc.c ldo.h lobject.h lua.h lstate.h lfunc.h lgc.h lmem.h \
|
lfunc.o: lfunc.c lfunc.h lobject.h lua.h lmem.h lstate.h luadebug.h
|
||||||
lstring.h ltable.h ltm.h
|
lgc.o: lgc.c ldo.h lobject.h lua.h lstate.h luadebug.h lfunc.h lgc.h \
|
||||||
|
lmem.h lstring.h ltable.h ltm.h
|
||||||
|
linit.o: linit.c lua.h lualib.h
|
||||||
liolib.o: liolib.c lauxlib.h lua.h luadebug.h lualib.h
|
liolib.o: liolib.c lauxlib.h lua.h luadebug.h lualib.h
|
||||||
llex.o: llex.c lauxlib.h lua.h llex.h lobject.h lzio.h lmem.h \
|
llex.o: llex.c lauxlib.h lua.h llex.h lobject.h lzio.h lmem.h \
|
||||||
lparser.h lstate.h lstring.h luadebug.h
|
lparser.h lstate.h luadebug.h lstring.h
|
||||||
lmathlib.o: lmathlib.c lauxlib.h lua.h lualib.h
|
lmathlib.o: lmathlib.c lauxlib.h lua.h lualib.h
|
||||||
lmem.o: lmem.c lmem.h lstate.h lobject.h lua.h
|
lmem.o: lmem.c lmem.h lstate.h lobject.h lua.h luadebug.h
|
||||||
lobject.o: lobject.c lobject.h lua.h
|
lobject.o: lobject.c lobject.h lua.h
|
||||||
lparser.o: lparser.c lauxlib.h lua.h ldo.h lobject.h lstate.h lfunc.h \
|
lparser.o: lparser.c lauxlib.h lua.h ldo.h lobject.h lstate.h \
|
||||||
llex.h lzio.h lmem.h lopcodes.h lparser.h lstring.h luadebug.h
|
luadebug.h lfunc.h llex.h lzio.h lmem.h lopcodes.h lparser.h \
|
||||||
lstate.o: lstate.c lbuiltin.h ldo.h lobject.h lua.h lstate.h lfunc.h \
|
lstring.h
|
||||||
lgc.h llex.h lzio.h lmem.h lstring.h ltable.h ltm.h
|
lstate.o: lstate.c lbuiltin.h ldo.h lobject.h lua.h lstate.h \
|
||||||
lstring.o: lstring.c lmem.h lobject.h lua.h lstate.h lstring.h
|
luadebug.h lfunc.h lgc.h llex.h lzio.h lmem.h lstring.h ltable.h \
|
||||||
|
ltm.h
|
||||||
|
lstring.o: lstring.c lmem.h lobject.h lua.h lstate.h luadebug.h \
|
||||||
|
lstring.h
|
||||||
lstrlib.o: lstrlib.c lauxlib.h lua.h lualib.h
|
lstrlib.o: lstrlib.c lauxlib.h lua.h lualib.h
|
||||||
ltable.o: ltable.c lauxlib.h lua.h lmem.h lobject.h lstate.h ltable.h
|
ltable.o: ltable.c lauxlib.h lua.h lmem.h lobject.h lstate.h \
|
||||||
ltm.o: ltm.c lauxlib.h lua.h lmem.h lobject.h lstate.h ltm.h
|
luadebug.h ltable.h
|
||||||
|
ltm.o: ltm.c lauxlib.h lua.h lmem.h lobject.h lstate.h luadebug.h \
|
||||||
|
ltm.h
|
||||||
lua.o: lua.c lua.h luadebug.h lualib.h
|
lua.o: lua.c lua.h luadebug.h lualib.h
|
||||||
lundump.o: lundump.c lauxlib.h lua.h lfunc.h lobject.h lmem.h \
|
lundump.o: lundump.c lauxlib.h lua.h lfunc.h lobject.h lmem.h \
|
||||||
lstring.h lundump.h lzio.h
|
lstring.h lundump.h lzio.h
|
||||||
lvm.o: lvm.c lauxlib.h lua.h ldo.h lobject.h lstate.h lfunc.h lgc.h \
|
lvm.o: lvm.c lauxlib.h lua.h ldo.h lobject.h lstate.h luadebug.h \
|
||||||
lmem.h lopcodes.h lstring.h ltable.h ltm.h luadebug.h lvm.h
|
lfunc.h lgc.h lmem.h lopcodes.h lstring.h ltable.h ltm.h lvm.h
|
||||||
lzio.o: lzio.c lzio.h
|
lzio.o: lzio.c lzio.h
|
||||||
|
|||||||
885
manual.tex
885
manual.tex
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user