diff --git a/lapi.c b/lapi.c index fb22b3df..4a80796a 100644 --- a/lapi.c +++ b/lapi.c @@ -1,5 +1,5 @@ /* -** $Id: lapi.c,v 1.92 2000/08/31 20:23:40 roberto Exp roberto $ +** $Id: lapi.c,v 1.93 2000/08/31 21:01:43 roberto Exp roberto $ ** Lua API ** See Copyright Notice in lua.h */ @@ -69,25 +69,24 @@ void lua_settop (lua_State *L, int index) { } -void lua_move (lua_State *L, int index) { - TObject *p = Index(L, index); - TObject temp = *p; +void lua_remove (lua_State *L, int index) { + StkId p = Index(L, index); while (++p < L->top) *(p-1) = *p; - *(L->top-1) = temp; + L->top--; } void lua_insert (lua_State *L, int index) { TObject temp = *(L->top-1); - TObject *p = Index(L, index); - TObject *q; + StkId p = Index(L, index); + StkId q; for (q = L->top-1; q>p; q--) *q = *(q-1); *p = temp; } -void lua_pushobject (lua_State *L, int index) { +void lua_pushvalue (lua_State *L, int index) { *L->top = *Index(L, index); api_incr_top(L); } @@ -133,17 +132,24 @@ int lua_isnumber (lua_State *L, int index) { int lua_tag (lua_State *L, int index) { btest(L, index, - ((ttype(o) == TAG_USERDATA) ? tsvalue(o)->u.d.tag : luaT_effectivetag(L, o)), - -1); + ((ttype(o) == TAG_USERDATA) ? tsvalue(o)->u.d.tag : + luaT_effectivetag(L, o)), -1); } -int lua_equal(lua_State *L, int index1, int index2) { +int lua_equal (lua_State *L, int index1, int index2) { StkId o1 = Index(L, index1); StkId o2 = Index(L, index2); if (o1 >= L->top || o2 >= L->top) return 0; /* index out-of-range */ else return luaO_equalObj(o1, o2); } +int lua_lessthan (lua_State *L, int index1, int index2) { + StkId o1 = Index(L, index1); + StkId o2 = Index(L, index2); + if (o1 >= L->top || o2 >= L->top) return 0; /* index out-of-range */ + else return luaV_lessthan(L, o1, o2, L->top); +} + double lua_tonumber (lua_State *L, int index) { @@ -168,14 +174,13 @@ void *lua_touserdata (lua_State *L, int index) { } const void *lua_topointer (lua_State *L, int index) { - const TObject *o = Index(L, index); + StkId o = Index(L, index); switch (ttype(o)) { case TAG_NUMBER: case TAG_NIL: return NULL; case TAG_STRING: - return tsvalue(o)->str; case TAG_USERDATA: - return tsvalue(o)->u.d.value; + return tsvalue(o); case TAG_TABLE: return hvalue(o); case TAG_CCLOSURE: case TAG_LCLOSURE: @@ -243,19 +248,32 @@ void lua_pushusertag (lua_State *L, void *u, int tag) { /* ORDER LUA_T */ void lua_getglobal (lua_State *L, const char *name) { - luaV_getglobal(L, luaS_new(L, name), L->top++); + StkId top = L->top; + *top = *luaV_getglobal(L, luaS_new(L, name)); + L->top = top+1; } -void lua_gettable (lua_State *L) { - luaV_gettable(L, L->top--); +void lua_gettable (lua_State *L, int tableindex) { + StkId t = Index(L, tableindex); + StkId top = L->top; + *(top-1) = *luaV_gettable(L, t); + L->top = top; /* tag method may change top */ } -void lua_rawget (lua_State *L) { - LUA_ASSERT(ttype(L->top-2) == TAG_TABLE, "table expected"); - *(L->top - 2) = *luaH_get(L, hvalue(L->top - 2), L->top - 1); - L->top--; +void lua_rawget (lua_State *L, int tableindex) { + StkId t = Index(L, tableindex); + LUA_ASSERT(ttype(t) == TAG_TABLE, "table expected"); + *(L->top - 1) = *luaH_get(L, hvalue(t), L->top - 1); +} + + +void lua_rawgeti (lua_State *L, int index, int n) { + StkId o = Index(L, index); + LUA_ASSERT(ttype(o) == TAG_TABLE, "table expected"); + *L->top = *luaH_getnum(hvalue(o), n); + api_incr_top(L); } @@ -266,12 +284,6 @@ void lua_getglobals (lua_State *L) { } -void lua_gettagmethod (lua_State *L, int tag, const char *event) { - *L->top = *luaT_gettagmethod(L, tag, event); - api_incr_top(L); -} - - int lua_getref (lua_State *L, int ref) { if (ref == LUA_REFNIL) ttype(L->top) = TAG_NIL; @@ -300,41 +312,43 @@ void lua_newtable (lua_State *L) { void lua_setglobal (lua_State *L, const char *name) { - luaV_setglobal(L, luaS_new(L, name), L->top--); -} - - -void lua_settable (lua_State *L) { StkId top = L->top; - luaV_settable(L, top-3, top); - L->top = top-3; /* pop table, index, and value */ + luaV_setglobal(L, luaS_new(L, name)); + L->top = top-1; /* remove element from the top */ } -void lua_rawset (lua_State *L) { - LUA_ASSERT(ttype(L->top-3) == TAG_TABLE, "table expected"); - *luaH_set(L, hvalue(L->top-3), L->top-2) = *(L->top-1); - L->top -= 3; +void lua_settable (lua_State *L, int tableindex) { + StkId t = Index(L, tableindex); + StkId top = L->top; + luaV_settable(L, t, top-2); + L->top = top-2; /* pop index and value */ +} + + +void lua_rawset (lua_State *L, int tableindex) { + StkId t = Index(L, tableindex); + LUA_ASSERT(ttype(t) == TAG_TABLE, "table expected"); + *luaH_set(L, hvalue(t), L->top-2) = *(L->top-1); + L->top -= 2; +} + + +void lua_rawseti (lua_State *L, int index, int n) { + StkId o = Index(L, index); + LUA_ASSERT(ttype(o) == TAG_TABLE, "table expected"); + *luaH_setint(L, hvalue(o), n) = *(L->top-1); + L->top--; } void lua_setglobals (lua_State *L) { - TObject *newtable = --L->top; + StkId newtable = --L->top; LUA_ASSERT(ttype(newtable) == TAG_TABLE, "table expected"); L->gt = hvalue(newtable); } -void lua_settagmethod (lua_State *L, int tag, const char *event) { - TObject *method = L->top - 1; - if (ttype(method) != TAG_NIL && - ttype(method) != TAG_CCLOSURE && - ttype(method) != TAG_LCLOSURE) - lua_error(L, "Lua API error - tag method must be a function or nil"); - luaT_settagmethod(L, tag, event, method); -} - - int lua_ref (lua_State *L, int lock) { int ref; if (ttype(L->top-1) == TAG_NIL) @@ -362,7 +376,6 @@ int lua_ref (lua_State *L, int lock) { ** miscellaneous functions */ - void lua_settag (lua_State *L, int tag) { luaT_realtag(L, tag); switch (ttype(L->top-1)) { @@ -389,8 +402,8 @@ void lua_unref (lua_State *L, int ref) { } -int lua_next (lua_State *L) { - const TObject *t = Index(L, -2); +int lua_next (lua_State *L, int tableindex) { + StkId t = Index(L, tableindex); Node *n; LUA_ASSERT(ttype(t) == TAG_TABLE, "table expected"); n = luaH_next(L, hvalue(t), Index(L, -1)); @@ -401,7 +414,7 @@ int lua_next (lua_State *L) { return 1; } else { /* no more elements */ - L->top -= 2; /* remove key and table */ + L->top -= 1; /* remove key */ return 0; } } @@ -427,3 +440,10 @@ int lua_getn (lua_State *L, int index) { } } + +void lua_concat (lua_State *L, int n) { + StkId top = L->top; + luaV_strconc(L, n, top); + L->top = top-(n-1); +} + diff --git a/ldblib.c b/ldblib.c index 17edcda5..2d8c555f 100644 --- a/ldblib.c +++ b/ldblib.c @@ -1,5 +1,5 @@ /* -** $Id: ldblib.c,v 1.18 2000/08/09 19:16:57 roberto Exp roberto $ +** $Id: ldblib.c,v 1.19 2000/08/28 17:57:04 roberto Exp roberto $ ** Interface from Lua to its debug API ** See Copyright Notice in lua.h */ @@ -18,18 +18,16 @@ static void settabss (lua_State *L, const char *i, const char *v) { - lua_pushobject(L, -1); lua_pushstring(L, i); lua_pushstring(L, v); - lua_settable(L); + lua_settable(L, -3); } static void settabsi (lua_State *L, const char *i, int v) { - lua_pushobject(L, -1); lua_pushstring(L, i); lua_pushnumber(L, v); - lua_settable(L); + lua_settable(L, -3); } @@ -44,7 +42,7 @@ static int getinfo (lua_State *L) { } } else if (lua_isfunction(L, 1)) { - lua_pushobject(L, 1); + lua_pushvalue(L, 1); sprintf(buff, ">%.10s", options); options = buff; } @@ -71,10 +69,9 @@ static int getinfo (lua_State *L) { settabss(L, "namewhat", ar.namewhat); break; case 'f': - lua_pushobject(L, -1); lua_pushstring(L, "func"); - lua_pushobject(L, -4); - lua_settable(L); + lua_pushvalue(L, -3); + lua_settable(L, -3); break; } } @@ -90,7 +87,7 @@ static int getlocal (lua_State *L) { name = lua_getlocal(L, &ar, luaL_check_int(L, 2)); if (name) { lua_pushstring(L, name); - lua_pushobject(L, -2); + lua_pushvalue(L, -2); return 2; } else { diff --git a/liolib.c b/liolib.c index 46d619c1..885db9bd 100644 --- a/liolib.c +++ b/liolib.c @@ -1,5 +1,5 @@ /* -** $Id: liolib.c,v 1.75 2000/08/31 13:30:10 roberto Exp roberto $ +** $Id: liolib.c,v 1.76 2000/08/31 20:23:40 roberto Exp roberto $ ** Standard I/O (and system) library ** See Copyright Notice in lua.h */ @@ -107,7 +107,7 @@ static FILE *getfilebyref (lua_State *L, IOCtrl *ctrl, int inout) { FILE *f; lua_getglobals(L); lua_getref(L, ctrl->ref[inout]); - lua_rawget(L); + lua_rawget(L, -2); f = gethandle(L, ctrl, -1); if (f == NULL) luaL_verror(L, "global variable `%.10s' is not a file handle", @@ -564,58 +564,77 @@ static int io_debug (lua_State *L) { } - -#define MESSAGESIZE 150 -#define MAXMESSAGE (MESSAGESIZE*10) - +#define LEVELS1 12 /* size of the first part of the stack */ +#define LEVELS2 10 /* size of the second part of the stack */ static int errorfb (lua_State *L) { - char buff[MAXMESSAGE]; int level = 1; /* skip level 0 (it's this function) */ + int firstpart = 1; /* still before eventual `...' */ lua_Debug ar; - sprintf(buff, "error: %.200s\n", lua_tostring(L, 1)); + lua_settop(L, 1); + luaL_checktype(L, 1, "string"); + lua_pushstring(L, "error: "); + lua_insert(L, 1); + lua_pushstring(L, "\nstack traceback:\n"); + lua_concat(L, 3); while (lua_getstack(L, level++, &ar)) { + char buff[120]; /* enough to fit following `sprintf's */ char buffchunk[60]; + int toconcat = 1; /* number of strings in the stack to concat */ + if (level > LEVELS1 && firstpart) { + /* no more than `LEVELS2' more levels? */ + if (!lua_getstack(L, level+LEVELS2, &ar)) + level--; /* keep going */ + else { + lua_pushstring(L, " ...\n"); /* too many levels */ + lua_concat(L, 2); + while (lua_getstack(L, level+LEVELS2, &ar)) /* get last levels */ + level++; + } + firstpart = 0; + continue; + } + sprintf(buff, "%4d: ", level-1); + lua_pushstring(L, buff); toconcat++; lua_getinfo(L, "Snl", &ar); luaL_chunkid(buffchunk, ar.source, sizeof(buffchunk)); - if (level == 2) strcat(buff, "stack traceback:\n"); - strcat(buff, " "); - if (strlen(buff) > MAXMESSAGE-MESSAGESIZE) { - strcat(buff, "...\n"); - break; /* buffer is full */ - } switch (*ar.namewhat) { case 'g': case 'l': /* global, local */ - sprintf(buff+strlen(buff), "function `%.50s'", ar.name); + sprintf(buff, "function `%.50s'", ar.name); break; case 'f': /* field */ - sprintf(buff+strlen(buff), "method `%.50s'", ar.name); + sprintf(buff, "method `%.50s'", ar.name); break; case 't': /* tag method */ - sprintf(buff+strlen(buff), "`%.50s' tag method", ar.name); + sprintf(buff, "`%.50s' tag method", ar.name); break; default: { if (*ar.what == 'm') /* main? */ - sprintf(buff+strlen(buff), "main of %.70s", buffchunk); + sprintf(buff, "main of %.70s", buffchunk); else if (*ar.what == 'C') /* C function? */ - sprintf(buff+strlen(buff), "%.70s", buffchunk); + sprintf(buff, "%.70s", buffchunk); else - sprintf(buff+strlen(buff), "function <%d:%.70s>", - ar.linedefined, buffchunk); + sprintf(buff, "function <%d:%.70s>", ar.linedefined, buffchunk); ar.source = NULL; } } - if (ar.currentline > 0) - sprintf(buff+strlen(buff), " at line %d", ar.currentline); - if (ar.source) - sprintf(buff+strlen(buff), " [%.70s]", buffchunk); - strcat(buff, "\n"); + lua_pushstring(L, buff); toconcat++; + if (ar.currentline > 0) { + sprintf(buff, " at line %d", ar.currentline); + lua_pushstring(L, buff); toconcat++; + } + if (ar.source) { + sprintf(buff, " [%.70s]", buffchunk); + lua_pushstring(L, buff); toconcat++; + } + lua_pushstring(L, "\n"); toconcat++; + lua_concat(L, toconcat); } lua_getglobals(L); lua_pushstring(L, LUA_ALERT); - lua_rawget(L); + lua_rawget(L, -2); if (lua_isfunction(L, -1)) { /* avoid loop if _ALERT is not defined */ - lua_pushstring(L, buff); + lua_pushvalue(L, -3); /* error message */ lua_call(L, 1, 0); } return 0; diff --git a/lstate.c b/lstate.c index 7e264565..f5d5b67c 100644 --- a/lstate.c +++ b/lstate.c @@ -1,5 +1,5 @@ /* -** $Id: lstate.c,v 1.34 2000/08/28 17:57:04 roberto Exp roberto $ +** $Id: lstate.c,v 1.35 2000/08/31 13:30:39 roberto Exp roberto $ ** Global State ** See Copyright Notice in lua.h */ @@ -9,7 +9,6 @@ #include "lua.h" -#include "lbuiltin.h" #include "ldo.h" #include "lgc.h" #include "llex.h" @@ -20,7 +19,13 @@ #include "ltm.h" -lua_State *lua_newstate (int stacksize, int put_builtin) { +#ifdef DEBUG +extern lua_State *lua_state; +void luaB_opentests (lua_State *L); +#endif + + +lua_State *lua_newstate (int stacksize) { struct lua_longjmp myErrorJmp; lua_State *L = luaM_new(NULL, lua_State); if (L == NULL) return NULL; /* memory allocation error */ @@ -54,8 +59,9 @@ lua_State *lua_newstate (int stacksize, int put_builtin) { luaS_init(L); luaX_init(L); luaT_init(L); - if (put_builtin) - luaB_predefine(L); +#ifdef DEBUG + luaB_opentests(L); +#endif L->GCthreshold = L->nblocks*4; L->errorJmp = NULL; return L; @@ -67,10 +73,6 @@ lua_State *lua_newstate (int stacksize, int put_builtin) { } -#ifdef DEBUG -extern lua_State *lua_state; -#endif - void lua_close (lua_State *L) { luaC_collect(L, 1); /* collect all elements */ LUA_ASSERT(L->rootproto == NULL, "list should be empty"); @@ -83,6 +85,7 @@ void lua_close (lua_State *L) { luaM_free(L, L->Mbuffer); LUA_ASSERT(L->nblocks == 0, "wrong count for nblocks"); luaM_free(L, L); + LUA_ASSERT(L->Cbase == L->stack, "stack not empty"); LUA_ASSERT(L != lua_state || memdebug_numblocks == 0, "memory leak!"); LUA_ASSERT(L != lua_state || memdebug_total == 0,"memory leak!"); } diff --git a/lstrlib.c b/lstrlib.c index 827a59ff..6cdd87da 100644 --- a/lstrlib.c +++ b/lstrlib.c @@ -1,5 +1,5 @@ /* -** $Id: lstrlib.c,v 1.49 2000/08/31 13:30:22 roberto Exp roberto $ +** $Id: lstrlib.c,v 1.50 2000/08/31 20:23:40 roberto Exp roberto $ ** Standard library for string operations and pattern-matching ** See Copyright Notice in lua.h */ @@ -469,7 +469,7 @@ static void add_s (lua_State *L, struct Capture *cap) { size_t oldbuff; int n; const char *s; - lua_pushobject(L, 3); + lua_pushvalue(L, 3); n = push_captures(L, cap); /* function may use buffer, so save it and create a new one */ oldbuff = luaL_newbuffer(L, 0); diff --git a/ltests.c b/ltests.c index 79b6d970..92c543d6 100644 --- a/ltests.c +++ b/ltests.c @@ -1,5 +1,5 @@ /* -** $Id: ltests.c,v 1.38 2000/08/31 13:29:47 roberto Exp roberto $ +** $Id: ltests.c,v 1.39 2000/08/31 20:23:40 roberto Exp roberto $ ** Internal Module for Debugging of the Lua Implementation ** See Copyright Notice in lua.h */ @@ -38,10 +38,9 @@ void luaB_opentests (lua_State *L); static void setnameval (lua_State *L, const char *name, int val) { - lua_pushobject(L, -1); lua_pushstring(L, name); lua_pushnumber(L, val); - lua_settable(L); + lua_settable(L, -3); } @@ -100,10 +99,9 @@ static int listcode (lua_State *L) { setnameval(L, "numparams", p->numparams); pc = 0; do { - lua_pushobject(L, -1); lua_pushnumber(L, pc+1); res = pushop(L, p, pc++); - lua_settable(L); + lua_settable(L, -3); } while (res); return 1; } @@ -116,10 +114,9 @@ static int liststrings (lua_State *L) { p = clvalue(luaA_index(L, 1))->f.l; lua_newtable(L); for (i=0; inkstr; i++) { - lua_pushobject(L, -1); lua_pushnumber(L, i+1); lua_pushstring(L, p->kstr[i]->str); - lua_settable(L); + lua_settable(L, -3); } return 1; } @@ -241,7 +238,7 @@ static int string_query (lua_State *L) { static int tref (lua_State *L) { luaL_checktype(L, 1, "any"); - lua_pushobject(L, 1); + lua_pushvalue(L, 1); lua_pushnumber(L, lua_ref(L, luaL_opt_int(L, 2, 1))); return 1; } @@ -270,7 +267,7 @@ static int udataval (lua_State *L) { } static int newstate (lua_State *L) { - lua_State *L1 = lua_newstate(luaL_check_int(L, 1), luaL_check_int(L, 2)); + lua_State *L1 = lua_newstate(luaL_check_int(L, 1)); if (L1) lua_pushuserdata(L, L1); else @@ -390,17 +387,20 @@ static int testC (lua_State *L) { else if EQ("pushnum") { lua_pushnumber(L, getnum); } - else if EQ("pushobject") { - lua_pushobject(L, getnum); + else if EQ("pushvalue") { + lua_pushvalue(L, getnum); } - else if EQ("move") { - lua_move(L, getnum); + else if EQ("remove") { + lua_remove(L, getnum); } else if EQ("insert") { lua_insert(L, getnum); } else if EQ("next") { - lua_next(L); + lua_next(L, -2); + } + else if EQ("concat") { + lua_concat(L, getnum); } else if EQ("call") { int narg = getnum; @@ -445,7 +445,7 @@ static const struct luaL_reg tests_funcs[] = { void luaB_opentests (lua_State *L) { lua_newtable(L); lua_getglobals(L); - lua_pushobject(L, -2); + lua_pushvalue(L, -2); lua_setglobals(L); luaL_openl(L, tests_funcs); /* open functions inside new table */ lua_setglobals(L); /* restore old table of globals */ diff --git a/ltm.c b/ltm.c index 1cb7647f..3d59b9a0 100644 --- a/ltm.c +++ b/ltm.c @@ -1,5 +1,5 @@ /* -** $Id: ltm.c,v 1.45 2000/08/07 20:21:34 roberto Exp roberto $ +** $Id: ltm.c,v 1.46 2000/08/09 19:16:57 roberto Exp roberto $ ** Tag methods ** See Copyright Notice in lua.h */ @@ -119,20 +119,23 @@ int luaT_effectivetag (lua_State *L, const TObject *o) { } -const TObject *luaT_gettagmethod (lua_State *L, int t, const char *event) { +void lua_gettagmethod (lua_State *L, int t, const char *event) { int e; e = luaI_checkevent(L, event, t); checktag(L, t); if (luaT_validevent(t, e)) - return luaT_getim(L, t,e); + *L->top = *luaT_getim(L, t,e); else - return &luaO_nilobject; + ttype(L->top) = TAG_NIL; + L->top++; } -void luaT_settagmethod (lua_State *L, int t, const char *event, TObject *func) { +void lua_settagmethod (lua_State *L, int t, const char *event) { TObject temp; int e; + LUA_ASSERT(lua_isnil(L, -1) || lua_isfunction(L, -1), + "function or nil expected"); e = luaI_checkevent(L, event, t); checktag(L, t); if (!luaT_validevent(t, e)) @@ -140,8 +143,8 @@ void luaT_settagmethod (lua_State *L, int t, const char *event, TObject *func) { luaT_eventname[e], luaO_typenames[t], (t == TAG_TABLE || t == TAG_USERDATA) ? " with default tag" : ""); - temp = *func; - *func = *luaT_getim(L, t,e); + temp = *(L->top - 1); + *(L->top - 1) = *luaT_getim(L, t,e); *luaT_getim(L, t, e) = temp; } diff --git a/ltm.h b/ltm.h index 2a4510a0..2d15b3ef 100644 --- a/ltm.h +++ b/ltm.h @@ -1,5 +1,5 @@ /* -** $Id: ltm.h,v 1.13 2000/05/30 18:54:49 roberto Exp roberto $ +** $Id: ltm.h,v 1.14 2000/08/07 20:21:34 roberto Exp roberto $ ** Tag methods ** See Copyright Notice in lua.h */ @@ -50,8 +50,6 @@ extern const char *const luaT_eventname[]; void luaT_init (lua_State *L); void luaT_realtag (lua_State *L, int tag); int luaT_effectivetag (lua_State *L, const TObject *o); -void luaT_settagmethod (lua_State *L, int t, const char *event, TObject *func); -const TObject *luaT_gettagmethod (lua_State *L, int t, const char *event); int luaT_validevent (int t, int e); /* used by compatibility module */ diff --git a/lua.c b/lua.c index 577ada06..05da8bfb 100644 --- a/lua.c +++ b/lua.c @@ -1,5 +1,5 @@ /* -** $Id: lua.c,v 1.48 2000/08/31 14:28:17 roberto Exp roberto $ +** $Id: lua.c,v 1.49 2000/08/31 20:23:40 roberto Exp roberto $ ** Lua stand-alone interpreter ** See Copyright Notice in lua.h */ @@ -54,6 +54,7 @@ extern void USERINIT (void); #else #define USERINIT userinit static void userinit (void) { + lua_baselibopen(L); lua_iolibopen(L); lua_strlibopen(L); lua_mathlibopen(L); @@ -103,7 +104,7 @@ static void print_message (void) { fprintf(stderr, "usage: lua [options]. Available options are:\n" " - execute stdin as a file\n" - " -c close lua when exiting\n" + " -c close Lua when exiting\n" " -e stat execute string `stat'\n" " -f name execute file `name' with remaining arguments in table `arg'\n" " -i enter interactive mode with prompt\n" @@ -134,12 +135,14 @@ static void getargs (char *argv[]) { lua_newtable(L); for (i=0; argv[i]; i++) { /* arg[i] = argv[i] */ - lua_pushobject(L, -1); lua_pushnumber(L, i); - lua_pushstring(L, argv[i]); lua_settable(L); + lua_pushnumber(L, i); + lua_pushstring(L, argv[i]); + lua_settable(L, -3); } /* arg.n = maximum index in table `arg' */ - lua_pushobject(L, -1); lua_pushstring(L, "n"); - lua_pushnumber(L, i-1); lua_settable(L); + lua_pushstring(L, "n"); + lua_pushnumber(L, i-1); + lua_settable(L, -3); } @@ -311,7 +314,7 @@ int main (int argc, char *argv[]) { int status; opt.toclose = 0; getstacksize(argc, argv, &opt); /* handle option `-s' */ - L = lua_newstate(opt.stacksize, 1); /* create state */ + L = lua_newstate(opt.stacksize); /* create state */ USERINIT(); /* open libraries */ register_getargs(argv); /* create `getargs' function */ status = handle_argv(argv+1, &opt); diff --git a/lua.h b/lua.h index e81030d3..2b51deab 100644 --- a/lua.h +++ b/lua.h @@ -1,5 +1,5 @@ /* -** $Id: lua.h,v 1.64 2000/08/31 20:23:40 roberto Exp roberto $ +** $Id: lua.h,v 1.65 2000/08/31 21:01:43 roberto Exp roberto $ ** Lua - An Extensible Extension Language ** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil ** e-mail: lua@tecgraf.puc-rio.br @@ -52,7 +52,7 @@ typedef int (*lua_CFunction) (lua_State *L); /* ** state manipulation */ -lua_State *lua_newstate (int stacksize, int builtin); +lua_State *lua_newstate (int stacksize); void lua_close (lua_State *L); @@ -61,8 +61,8 @@ void lua_close (lua_State *L); */ int lua_gettop (lua_State *L); void lua_settop (lua_State *L, int index); -void lua_pushobject (lua_State *L, int index); -void lua_move (lua_State *L, int index); +void lua_pushvalue (lua_State *L, int index); +void lua_remove (lua_State *L, int index); void lua_insert (lua_State *L, int index); int lua_stackspace (lua_State *L); @@ -77,6 +77,7 @@ int lua_iscfunction (lua_State *L, int index); int lua_tag (lua_State *L, int index); int lua_equal (lua_State *L, int index1, int index2); +int lua_lessthan (lua_State *L, int index1, int index2); double lua_tonumber (lua_State *L, int index); const char *lua_tostring (lua_State *L, int index); @@ -101,8 +102,9 @@ void lua_pushusertag (lua_State *L, void *u, int tag); ** get functions (Lua -> stack) */ void lua_getglobal (lua_State *L, const char *name); -void lua_gettable (lua_State *L); -void lua_rawget (lua_State *L); +void lua_gettable (lua_State *L, int tableindex); +void lua_rawget (lua_State *L, int tableindex); +void lua_rawgeti (lua_State *L, int tableindex, int n); void lua_getglobals (lua_State *L); void lua_gettagmethod (lua_State *L, int tag, const char *event); @@ -115,8 +117,9 @@ void lua_newtable (lua_State *L); ** set functions (stack -> Lua) */ void lua_setglobal (lua_State *L, const char *name); -void lua_settable (lua_State *L); -void lua_rawset (lua_State *L); +void lua_settable (lua_State *L, int tableindex); +void lua_rawset (lua_State *L, int tableindex); +void lua_rawseti (lua_State *L, int tableindex, int n); void lua_setglobals (lua_State *L); void lua_settagmethod (lua_State *L, int tag, const char *event); int lua_ref (lua_State *L, int lock); @@ -145,9 +148,10 @@ void lua_unref (lua_State *L, int ref); long lua_collectgarbage (lua_State *L, long limit); -int lua_next (lua_State *L); -int lua_getn (lua_State *L, int index); +int lua_next (lua_State *L, int tableindex); +int lua_getn (lua_State *L, int tableindex); +void lua_concat (lua_State *L, int n); /* diff --git a/lualib.h b/lualib.h index 0a0fbe24..463951ab 100644 --- a/lualib.h +++ b/lualib.h @@ -1,5 +1,5 @@ /* -** $Id: lualib.h,v 1.9 2000/06/16 17:22:43 roberto Exp roberto $ +** $Id: lualib.h,v 1.10 2000/08/09 19:16:57 roberto Exp roberto $ ** Lua standard libraries ** See Copyright Notice in lua.h */ @@ -10,6 +10,7 @@ #include "lua.h" +void lua_baselibopen (lua_State *L); void lua_iolibopen (lua_State *L); void lua_strlibopen (lua_State *L); void lua_mathlibopen (lua_State *L); @@ -17,26 +18,6 @@ void lua_dblibopen (lua_State *L); -/* -** =============================================================== -** Macros (and functions) for single-state use -** =============================================================== -*/ - -#ifdef LUA_SINGLESTATE - -#define lua_iolibopen() (lua_iolibopen)(lua_state) -#define lua_strlibopen() (lua_strlibopen)(lua_state) -#define lua_mathlibopen() (lua_mathlibopen)(lua_state) -#define lua_dblibopen() (lua_dblibopen)(lua_state) - -/* this function should be used only in single-state mode */ -void lua_userinit (void); - -#endif - - - /* Auxiliary functions (private) */ const char *luaI_classend (lua_State *L, const char *p); diff --git a/lvm.c b/lvm.c index a2aa456e..a8e81dd5 100644 --- a/lvm.c +++ b/lvm.c @@ -1,5 +1,5 @@ /* -** $Id: lvm.c,v 1.132 2000/08/31 14:08:27 roberto Exp roberto $ +** $Id: lvm.c,v 1.133 2000/08/31 21:02:55 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -112,10 +112,10 @@ void luaV_Lclosure (lua_State *L, Proto *l, int nelems) { /* ** Function to index a table. -** Receives the table at top-2 and the index at top-1. +** Receives the table at `t' and the key at top. */ -void luaV_gettable (lua_State *L, StkId top) { - StkId t = top-2; +const TObject *luaV_gettable (lua_State *L, StkId t) { + const TObject *im; int tg; if (ttype(t) == TAG_TABLE && /* `t' is a table? */ ((tg = hvalue(t)->htag) == TAG_TABLE || /* with default tag? */ @@ -123,46 +123,49 @@ void luaV_gettable (lua_State *L, StkId top) { /* do a primitive get */ const TObject *h = luaH_get(L, hvalue(t), t+1); /* result is no nil or there is no `index' tag method? */ - const TObject *im; if (ttype(h) != TAG_NIL || (ttype(im=luaT_getim(L, tg, IM_INDEX)) == TAG_NIL)) - *t = *h; /* put result into table position */ - else { /* call `index' tag method */ - L->top = top; - luaD_callTM(L, im, 2, 1); - } + return h; /* return result */ + /* else call `index' tag method */ } else { /* try a 'gettable' TM */ - const TObject *im = luaT_getimbyObj(L, t, IM_GETTABLE); - L->top = top; - if (ttype(im) != TAG_NIL) /* call `gettable' tag method */ - luaD_callTM(L, im, 2, 1); - else /* no tag method */ - luaG_typeerror(L, t, "index"); + im = luaT_getimbyObj(L, t, IM_GETTABLE); + } + if (ttype(im) != TAG_NIL) { /* is there a tag method? */ + luaD_checkstack(L, 2); + *(L->top+1) = *(L->top-1); /* key */ + *L->top = *t; /* table */ + *(L->top-1) = *im; /* tag method */ + L->top += 2; + luaD_call(L, L->top - 3, 1); + return L->top - 1; /* call result */ + } + else { /* no tag method */ + luaG_typeerror(L, t, "index"); + return NULL; /* to avoid warnings */ } } /* -** Receives table at *t, index at *(t+1) and value at `top'. +** Receives table at `t', key at `key' and value at top. */ -void luaV_settable (lua_State *L, StkId t, StkId top) { +void luaV_settable (lua_State *L, StkId t, StkId key) { int tg; if (ttype(t) == TAG_TABLE && /* `t' is a table? */ ((tg = hvalue(t)->htag) == TAG_TABLE || /* with default tag? */ ttype(luaT_getim(L, tg, IM_SETTABLE)) == TAG_NIL)) /* or no TM? */ - *luaH_set(L, hvalue(t), t+1) = *(top-1); /* do a primitive set */ + *luaH_set(L, hvalue(t), key) = *(L->top-1); /* do a primitive set */ else { /* try a `settable' tag method */ const TObject *im = luaT_getimbyObj(L, t, IM_SETTABLE); - L->top = top; if (ttype(im) != TAG_NIL) { luaD_checkstack(L, 3); - *(top+2) = *(top-1); - *(top+1) = *(t+1); - *(top) = *t; - *(top-1) = *im; - L->top = top+3; - luaD_call(L, top-1, 0); /* call `settable' tag method */ + *(L->top+2) = *(L->top-1); + *(L->top+1) = *key; + *(L->top) = *t; + *(L->top-1) = *im; + L->top += 3; + luaD_call(L, L->top - 4, 0); /* call `settable' tag method */ } else /* no tag method... */ luaG_typeerror(L, t, "index"); @@ -170,49 +173,48 @@ void luaV_settable (lua_State *L, StkId t, StkId top) { } -void luaV_getglobal (lua_State *L, TString *s, StkId top) { +const TObject *luaV_getglobal (lua_State *L, TString *s) { const TObject *value = luaH_getstr(L->gt, s); TObject *im = luaT_getimbyObj(L, value, IM_GETGLOBAL); if (ttype(im) == TAG_NIL) /* is there a tag method? */ - *top = *value; /* default behavior */ + return value; /* default behavior */ else { /* tag method */ - L->top = top; luaD_checkstack(L, 3); - *top = *im; - ttype(top+1) = TAG_STRING; - tsvalue(top+1) = s; /* global name */ - *(top+2) = *value; - L->top = top+3; - luaD_call(L, top, 1); + *L->top = *im; + ttype(L->top+1) = TAG_STRING; + tsvalue(L->top+1) = s; /* global name */ + *(L->top+2) = *value; + L->top += 3; + luaD_call(L, L->top - 3, 1); + return L->top - 1; } } -void luaV_setglobal (lua_State *L, TString *s, StkId top) { +void luaV_setglobal (lua_State *L, TString *s) { const TObject *oldvalue = luaH_getstr(L->gt, s); const TObject *im = luaT_getimbyObj(L, oldvalue, IM_SETGLOBAL); if (ttype(im) == TAG_NIL) { /* is there a tag method? */ if (oldvalue != &luaO_nilobject) { /* cast to remove `const' is OK, because `oldvalue' != luaO_nilobject */ - *(TObject *)oldvalue = *(top-1); + *(TObject *)oldvalue = *(L->top - 1); } else { TObject key; ttype(&key) = TAG_STRING; tsvalue(&key) = s; - *luaH_set(L, L->gt, &key) = *(top-1); + *luaH_set(L, L->gt, &key) = *(L->top - 1); } } else { - L->top = top; luaD_checkstack(L, 3); - *(top+2) = *(top-1); /* new value */ - *(top+1) = *oldvalue; - ttype(top) = TAG_STRING; - tsvalue(top) = s; - *(top-1) = *im; - L->top = top+3; - luaD_call(L, top-1, 0); + *(L->top+2) = *(L->top-1); /* new value */ + *(L->top+1) = *oldvalue; + ttype(L->top) = TAG_STRING; + tsvalue(L->top) = s; + *(L->top-1) = *im; + L->top += 3; + luaD_call(L, L->top - 4, 0); } } @@ -280,7 +282,7 @@ int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r, StkId top) } -static void strconc (lua_State *L, int total, StkId top) { +void luaV_strconc (lua_State *L, int total, StkId top) { do { int n = 2; /* number of elements handled in this pass (at least 2) */ if (tostring(L, top-2) || tostring(L, top-1)) { @@ -425,26 +427,28 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { break; } case OP_GETGLOBAL: { - luaV_getglobal(L, kstr[GETARG_U(i)], top); + L->top = top; + *top = *luaV_getglobal(L, kstr[GETARG_U(i)]); top++; break; } case OP_GETTABLE: { - luaV_gettable(L, top); + L->top = top; top--; + *(top-1) = *luaV_gettable(L, top-1); break; } case OP_GETDOTTED: { ttype(top) = TAG_STRING; - tsvalue(top++) = kstr[GETARG_U(i)]; - luaV_gettable(L, top); - top--; + tsvalue(top) = kstr[GETARG_U(i)]; + L->top = top+1; + *(top-1) = *luaV_gettable(L, top-1); break; } case OP_GETINDEXED: { - *top++ = *(base+GETARG_U(i)); - luaV_gettable(L, top); - top--; + *top = *(base+GETARG_U(i)); + L->top = top+1; + *(top-1) = *luaV_gettable(L, top-1); break; } case OP_PUSHSELF: { @@ -452,7 +456,8 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { receiver = *(top-1); ttype(top) = TAG_STRING; tsvalue(top++) = kstr[GETARG_U(i)]; - luaV_gettable(L, top); + L->top = top; + *(top-2) = *luaV_gettable(L, top-2); *(top-1) = receiver; break; } @@ -469,12 +474,15 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { break; } case OP_SETGLOBAL: { - luaV_setglobal(L, kstr[GETARG_U(i)], top); + L->top = top; + luaV_setglobal(L, kstr[GETARG_U(i)]); top--; break; } case OP_SETTABLE: { - luaV_settable(L, top-GETARG_A(i), top); + StkId t = top-GETARG_A(i); + L->top = top; + luaV_settable(L, t, t+1); top -= GETARG_B(i); /* pop values */ break; } @@ -548,7 +556,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { } case OP_CONCAT: { int n = GETARG_U(i); - strconc(L, n, top); + luaV_strconc(L, n, top); top -= n-1; L->top = top; luaC_checkGC(L); diff --git a/lvm.h b/lvm.h index 5783c209..e74eaf30 100644 --- a/lvm.h +++ b/lvm.h @@ -1,5 +1,5 @@ /* -** $Id: lvm.h,v 1.24 2000/08/29 14:41:56 roberto Exp roberto $ +** $Id: lvm.h,v 1.25 2000/08/31 21:02:55 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -19,13 +19,14 @@ int luaV_tonumber (TObject *obj); int luaV_tostring (lua_State *L, TObject *obj); -void luaV_gettable (lua_State *L, StkId top); -void luaV_settable (lua_State *L, StkId t, StkId top); -void luaV_getglobal (lua_State *L, TString *s, StkId top); -void luaV_setglobal (lua_State *L, TString *s, StkId top); +const TObject *luaV_gettable (lua_State *L, StkId t); +void luaV_settable (lua_State *L, StkId t, StkId key); +const TObject *luaV_getglobal (lua_State *L, TString *s); +void luaV_setglobal (lua_State *L, TString *s); StkId luaV_execute (lua_State *L, const Closure *cl, StkId base); void luaV_Cclosure (lua_State *L, lua_CFunction c, int nelems); void luaV_Lclosure (lua_State *L, Proto *l, int nelems); int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r, StkId top); +void luaV_strconc (lua_State *L, int total, StkId top); #endif