From f0b3cd1d6f35ba34091450d5e3057269114a17b6 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Thu, 31 Aug 2000 17:23:40 -0300 Subject: [PATCH] new API functions `pop', `insert', and `move' --- lapi.c | 38 +++++++++++++++++++++++++------------- lbuiltin.c | 8 ++++---- liolib.c | 18 +++++++++--------- lmathlib.c | 4 ++-- lstrlib.c | 4 ++-- ltests.c | 13 +++++++++++-- lua.c | 6 ++++-- lua.h | 6 +++++- 8 files changed, 62 insertions(+), 35 deletions(-) diff --git a/lapi.c b/lapi.c index 75159082..5364c040 100644 --- a/lapi.c +++ b/lapi.c @@ -1,5 +1,5 @@ /* -** $Id: lapi.c,v 1.90 2000/08/29 20:43:28 roberto Exp roberto $ +** $Id: lapi.c,v 1.91 2000/08/31 14:08:27 roberto Exp roberto $ ** Lua API ** See Copyright Notice in lua.h */ @@ -65,7 +65,25 @@ void lua_settop (lua_State *L, int index) { if (index >= 0) luaD_adjusttop(L, L->Cbase, index); else - L->top += index; /* index is negative */ + L->top = L->top+index+1; /* index is negative */ +} + + +void lua_move (lua_State *L, int index) { + TObject *p = Index(L, index); + TObject temp = *p; + while (++p < L->top) *(p-1) = *p; + *(L->top-1) = temp; +} + + +void lua_insert (lua_State *L, int index) { + TObject temp = *(L->top-1); + TObject *p = Index(L, index); + TObject *q; + for (q = L->top-1; q>p; q--) + *q = *(q-1); + *p = temp; } @@ -218,8 +236,7 @@ void lua_gettable (lua_State *L) { void lua_rawget (lua_State *L) { - if (ttype(L->top - 2) != TAG_TABLE) - lua_error(L, "indexed expression not a table"); + LUA_ASSERT(ttype(L->top-2) == TAG_TABLE, "not a table"); *(L->top - 2) = *luaH_get(L, hvalue(L->top - 2), L->top - 1); L->top--; } @@ -278,8 +295,7 @@ void lua_settable (lua_State *L) { void lua_rawset (lua_State *L) { - if (ttype(L->top-3) != TAG_TABLE) - lua_error(L, "indexed expression not a table"); + LUA_ASSERT(ttype(L->top-3) == TAG_TABLE, "not a table"); *luaH_set(L, hvalue(L->top-3), L->top-2) = *(L->top-1); L->top -= 3; } @@ -287,8 +303,7 @@ void lua_rawset (lua_State *L) { void lua_setglobals (lua_State *L) { TObject *newtable = --L->top; - if (ttype(newtable) != TAG_TABLE) - lua_error(L, "Lua API error - invalid value for global table"); + LUA_ASSERT(ttype(newtable) == TAG_TABLE, "not a table"); L->gt = hvalue(newtable); } @@ -350,9 +365,7 @@ void lua_settag (lua_State *L, int tag) { void lua_unref (lua_State *L, int ref) { if (ref >= 0) { - if (ref >= L->refSize || L->refArray[ref].st >= 0) - lua_error(L, "Lua API error - " - "invalid argument for function `lua_unref'"); + LUA_ASSERT(ref < L->refSize && L->refArray[ref].st < 0, "invalid ref"); L->refArray[ref].st = L->refFree; L->refFree = ref; } @@ -362,8 +375,7 @@ void lua_unref (lua_State *L, int ref) { int lua_next (lua_State *L) { const TObject *t = Index(L, -2); Node *n; - if (ttype(t) != TAG_TABLE) - lua_error(L, "Lua API error - object is not a table in `lua_next'"); + LUA_ASSERT(ttype(t) == TAG_TABLE, "object is not a table in `lua_next'"); n = luaH_next(L, hvalue(t), Index(L, -1)); if (n) { *(L->top-1) = *key(n); diff --git a/lbuiltin.c b/lbuiltin.c index f4368f56..348214e4 100644 --- a/lbuiltin.c +++ b/lbuiltin.c @@ -1,5 +1,5 @@ /* -** $Id: lbuiltin.c,v 1.125 2000/08/31 14:08:27 roberto Exp roberto $ +** $Id: lbuiltin.c,v 1.126 2000/08/31 16:52:06 roberto Exp roberto $ ** Built-in functions ** See Copyright Notice in lua.h */ @@ -92,7 +92,7 @@ int luaB_print (lua_State *L) { lua_error(L, "`tostring' must return a string to `print'"); if (i>1) fputs("\t", stdout); fputs(s, stdout); - lua_settop(L, -1); /* pop result */ + lua_pop(L, 1); /* pop result */ } fputs("\n", stdout); return 0; @@ -201,7 +201,7 @@ int luaB_settagmethod (lua_State *L) { lua_pushnil(L); /* to get its tag */ if (strcmp(event, "gc") == 0 && tag != lua_tag(L, -1)) lua_error(L, "deprecated use: cannot set the `gc' tag method from Lua"); - lua_settop(L, -1); /* remove the nil */ + lua_pop(L, 1); /* remove the nil */ lua_settagmethod(L, tag, event); return 1; } @@ -501,7 +501,7 @@ static int luaB_foreach (lua_State *L) { if (lua_call(L, 2, 1) != 0) lua_error(L, NULL); if (!lua_isnil(L, -1)) return 1; - lua_settop(L, -2); /* remove value and result */ + lua_pop(L, 2); /* remove value and result */ } } diff --git a/liolib.c b/liolib.c index 33a15a81..46d619c1 100644 --- a/liolib.c +++ b/liolib.c @@ -1,5 +1,5 @@ /* -** $Id: liolib.c,v 1.74 2000/08/29 20:43:28 roberto Exp roberto $ +** $Id: liolib.c,v 1.75 2000/08/31 13:30:10 roberto Exp roberto $ ** Standard I/O (and system) library ** See Copyright Notice in lua.h */ @@ -150,14 +150,14 @@ static int closefile (lua_State *L, IOCtrl *ctrl, FILE *f) { static int io_close (lua_State *L) { IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1); - lua_settop(L, -1); /* remove upvalue */ + lua_pop(L, 1); /* remove upvalue */ return pushresult(L, closefile(L, ctrl, getnonullfile(L, ctrl, 1))); } static int file_collect (lua_State *L) { IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1); - lua_settop(L, -1); /* remove upvalue */ + lua_pop(L, 1); /* remove upvalue */ if (ctrl == (IOCtrl *)lua_touserdata(L, 1)) { /* collecting `ctrl' itself */ lua_unref(L, ctrl->ref[INFILE]); @@ -176,7 +176,7 @@ static int file_collect (lua_State *L) { static int io_open (lua_State *L) { IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1); FILE *f; - lua_settop(L, -1); /* remove upvalue */ + lua_pop(L, 1); /* remove upvalue */ f = fopen(luaL_check_string(L, 1), luaL_check_string(L, 2)); if (f) { lua_pushusertag(L, f, ctrl->iotag); @@ -191,7 +191,7 @@ static int io_open (lua_State *L) { static int io_fromto (lua_State *L, int inout, const char *mode) { IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1); FILE *current; - lua_settop(L, -1); /* remove upvalue */ + lua_pop(L, 1); /* remove upvalue */ if (lua_isnull(L, 1)) { closefile(L, ctrl, getfilebyref(L, ctrl, inout)); current = (inout == 0) ? stdin : stdout; @@ -219,7 +219,7 @@ static int io_writeto (lua_State *L) { static int io_appendto (lua_State *L) { IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1); FILE *current; - lua_settop(L, -1); /* remove upvalue */ + lua_pop(L, 1); /* remove upvalue */ current = fopen(luaL_check_string(L, 1), "a"); return setreturn(L, ctrl, current, OUTFILE); } @@ -366,7 +366,7 @@ static int io_read (lua_State *L) { int n; if (f) firstarg++; else f = getfilebyref(L, ctrl, INFILE); /* get _INPUT */ - lua_settop(L, -1); + lua_pop(L, 1); if (firstarg > lastarg) { /* no arguments? */ lua_settop(L, 0); /* erase upvalue and other eventual garbage */ firstarg = lastarg = 1; /* correct indices */ @@ -447,7 +447,7 @@ static int io_seek (lua_State *L) { FILE *f; int op; long offset; - lua_settop(L, -1); /* remove upvalue */ + lua_pop(L, 1); /* remove upvalue */ f = getnonullfile(L, ctrl, 1); op = luaL_findstring(luaL_opt_string(L, 2, "cur"), modenames); offset = luaL_opt_long(L, 3, 0); @@ -465,7 +465,7 @@ static int io_seek (lua_State *L) { static int io_flush (lua_State *L) { IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1); FILE *f; - lua_settop(L, -1); /* remove upvalue */ + lua_pop(L, 1); /* remove upvalue */ f = gethandle(L, ctrl, 1); luaL_arg_check(L, f || lua_isnull(L, 1), 1, "invalid file handle"); return pushresult(L, fflush(f) == 0); diff --git a/lmathlib.c b/lmathlib.c index d6957e76..ca14ee8c 100644 --- a/lmathlib.c +++ b/lmathlib.c @@ -1,5 +1,5 @@ /* -** $Id: lmathlib.c,v 1.26 2000/08/09 19:16:57 roberto Exp roberto $ +** $Id: lmathlib.c,v 1.27 2000/08/28 17:57:04 roberto Exp roberto $ ** Standard mathematical library ** See Copyright Notice in lua.h */ @@ -233,7 +233,7 @@ void lua_mathlibopen (lua_State *L) { lua_pushnumber(L, 0); /* to get its tag */ lua_pushcfunction(L, math_pow); lua_settagmethod(L, lua_tag(L, -2), "pow"); - lua_settop(L, -1); /* remove number */ + lua_pop(L, 1); /* remove number */ lua_pushnumber(L, PI); lua_setglobal(L, "PI"); } diff --git a/lstrlib.c b/lstrlib.c index 86cb90ed..827a59ff 100644 --- a/lstrlib.c +++ b/lstrlib.c @@ -1,5 +1,5 @@ /* -** $Id: lstrlib.c,v 1.48 2000/08/29 20:43:28 roberto Exp roberto $ +** $Id: lstrlib.c,v 1.49 2000/08/31 13:30:22 roberto Exp roberto $ ** Standard library for string operations and pattern-matching ** See Copyright Notice in lua.h */ @@ -481,7 +481,7 @@ static void add_s (lua_State *L, struct Capture *cap) { s = lua_tostring(L, -1); if (s) addnchar(L, lua_tostring(L, -1), lua_strlen(L, -1)); - lua_settop(L, -1); /* pop function result */ + lua_pop(L, 1); /* pop function result */ } } diff --git a/ltests.c b/ltests.c index 45b1f1c0..79b6d970 100644 --- a/ltests.c +++ b/ltests.c @@ -1,5 +1,5 @@ /* -** $Id: ltests.c,v 1.37 2000/08/29 19:05:11 roberto Exp roberto $ +** $Id: ltests.c,v 1.38 2000/08/31 13:29:47 roberto Exp roberto $ ** Internal Module for Debugging of the Lua Implementation ** See Copyright Notice in lua.h */ @@ -341,7 +341,7 @@ static int getnum (lua_State *L, const char **pc) { skip(pc); if (**pc == '.') { res = (int)lua_tonumber(L, -1); - lua_settop(L, -1); + lua_pop(L, 1); (*pc)++; return res; } @@ -384,12 +384,21 @@ static int testC (lua_State *L) { else if EQ("settop") { lua_settop(L, getnum); } + else if EQ("pop") { + lua_pop(L, getnum); + } else if EQ("pushnum") { lua_pushnumber(L, getnum); } else if EQ("pushobject") { lua_pushobject(L, getnum); } + else if EQ("move") { + lua_move(L, getnum); + } + else if EQ("insert") { + lua_insert(L, getnum); + } else if EQ("next") { lua_next(L); } diff --git a/lua.c b/lua.c index 8fd014d1..577ada06 100644 --- a/lua.c +++ b/lua.c @@ -1,5 +1,5 @@ /* -** $Id: lua.c,v 1.47 2000/08/29 14:33:31 roberto Exp roberto $ +** $Id: lua.c,v 1.48 2000/08/31 14:28:17 roberto Exp roberto $ ** Lua stand-alone interpreter ** See Copyright Notice in lua.h */ @@ -87,7 +87,9 @@ static void laction (int i) { static int ldo (int (*f)(lua_State *l, const char *), const char *name) { int res; handler h = lreset(); + int top = lua_gettop(L); res = f(L, name); /* dostring | dofile */ + lua_settop(L, top); /* remove eventual results */ signal(SIGINT, h); /* restore old action */ if (res == LUA_ERRMEM) { /* Lua gives no message in such case, so lua.c provides one */ @@ -177,9 +179,9 @@ static void manual_input (int version, int prompt) { const char *s; lua_getglobal(L, "_PROMPT"); s = lua_tostring(L, -1); - lua_settop(L, -1); /* remove global */ if (!s) s = PROMPT; fputs(s, stdout); + lua_pop(L, 1); /* remove global */ } for(;;) { int c = getchar(); diff --git a/lua.h b/lua.h index 0ad37ad6..a5862ba5 100644 --- a/lua.h +++ b/lua.h @@ -1,5 +1,5 @@ /* -** $Id: lua.h,v 1.62 2000/08/29 20:43:28 roberto Exp roberto $ +** $Id: lua.h,v 1.63 2000/08/31 14:08:27 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 @@ -62,6 +62,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_insert (lua_State *L, int index); int lua_stackspace (lua_State *L); @@ -152,6 +154,8 @@ int lua_next (lua_State *L); ** =============================================================== */ +#define lua_pop(L,n) lua_settop(L, -(n)-1) + #define lua_register(L,n,f) (lua_pushcfunction(L, f), lua_setglobal(L, n)) #define lua_pushuserdata(L,u) lua_pushusertag(L, u, 0) #define lua_pushcfunction(L,f) lua_pushcclosure(L, f, 0)