lua

A copy of the Lua development repository
Log | Files | Refs | README

commit 9a21e81907e49b79ec44677660acf9e35ad308bb
parent f0b3cd1d6f35ba34091450d5e3057269114a17b6
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date:   Thu, 31 Aug 2000 18:01:21 -0300

more builtin functions using official API

Diffstat:
Mlapi.c | 48+++++++++++++++++++++++++++++++++++++++++++-----
Mlbuiltin.c | 159++++++++++++++++++++++++++++++++++---------------------------------------------
Mlua.h | 4+++-
3 files changed, 115 insertions(+), 96 deletions(-)

diff --git a/lapi.c b/lapi.c @@ -1,5 +1,5 @@ /* -** $Id: lapi.c,v 1.91 2000/08/31 14:08:27 roberto Exp roberto $ +** $Id: lapi.c,v 1.92 2000/08/31 20:23:40 roberto Exp roberto $ ** Lua API ** See Copyright Notice in lua.h */ @@ -167,6 +167,23 @@ void *lua_touserdata (lua_State *L, int index) { access(L, index, (ttype(o) == TAG_USERDATA), NULL, tsvalue(o)->u.d.value); } +const void *lua_topointer (lua_State *L, int index) { + const TObject *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; + case TAG_TABLE: + return hvalue(o); + case TAG_CCLOSURE: case TAG_LCLOSURE: + return clvalue(o); + default: return NULL; + } +} + /* @@ -236,7 +253,7 @@ void lua_gettable (lua_State *L) { void lua_rawget (lua_State *L) { - LUA_ASSERT(ttype(L->top-2) == TAG_TABLE, "not a table"); + 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--; } @@ -295,7 +312,7 @@ void lua_settable (lua_State *L) { void lua_rawset (lua_State *L) { - LUA_ASSERT(ttype(L->top-3) == TAG_TABLE, "not a table"); + 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; } @@ -303,7 +320,7 @@ void lua_rawset (lua_State *L) { void lua_setglobals (lua_State *L) { TObject *newtable = --L->top; - LUA_ASSERT(ttype(newtable) == TAG_TABLE, "not a table"); + LUA_ASSERT(ttype(newtable) == TAG_TABLE, "table expected"); L->gt = hvalue(newtable); } @@ -375,7 +392,7 @@ void lua_unref (lua_State *L, int ref) { int lua_next (lua_State *L) { const TObject *t = Index(L, -2); Node *n; - LUA_ASSERT(ttype(t) == TAG_TABLE, "object is not a table in `lua_next'"); + LUA_ASSERT(ttype(t) == TAG_TABLE, "table expected"); n = luaH_next(L, hvalue(t), Index(L, -1)); if (n) { *(L->top-1) = *key(n); @@ -389,3 +406,24 @@ int lua_next (lua_State *L) { } } + +int lua_getn (lua_State *L, int index) { + Hash *h = hvalue(Index(L, index)); + const TObject *value = luaH_getstr(h, luaS_new(L, "n")); /* value = h.n */ + if (ttype(value) == TAG_NUMBER) + return (int)nvalue(value); + else { + Number max = 0; + int i = h->size; + Node *n = h->node; + while (i--) { + if (ttype(key(n)) == TAG_NUMBER && + ttype(val(n)) != TAG_NIL && + nvalue(key(n)) > max) + max = nvalue(key(n)); + n++; + } + return (int)max; + } +} + diff --git a/lbuiltin.c b/lbuiltin.c @@ -1,5 +1,5 @@ /* -** $Id: lbuiltin.c,v 1.126 2000/08/31 16:52:06 roberto Exp roberto $ +** $Id: lbuiltin.c,v 1.127 2000/08/31 20:23:40 roberto Exp roberto $ ** Built-in functions ** See Copyright Notice in lua.h */ @@ -270,71 +270,15 @@ int luaB_dofile (lua_State *L) { return passresults(L, lua_dofile(L, fname), oldtop); } -/* }====================================================== */ - - -/* -** {====================================================== -** Functions that could use only the official API but -** do not, for efficiency. -** ======================================================= -*/ - -#include "lapi.h" -#include "ldo.h" -#include "lmem.h" -#include "lobject.h" -#include "lstate.h" -#include "lstring.h" -#include "ltable.h" -#include "ltm.h" -#include "lvm.h" - - -/* -** {====================================================== -** Auxiliary functions -** ======================================================= -*/ - -static Number getsize (const Hash *h) { - Number max = 0; - int i = h->size; - Node *n = h->node; - while (i--) { - if (ttype(key(n)) == TAG_NUMBER && - ttype(val(n)) != TAG_NIL && - nvalue(key(n)) > max) - max = nvalue(key(n)); - n++; - } - return max; -} - - -static Number getnarg (lua_State *L, const Hash *a) { - const TObject *value = luaH_getstr(a, luaS_new(L, "n")); /* value = a.n */ - return (ttype(value) == TAG_NUMBER) ? nvalue(value) : getsize(a); -} - - -static Hash *gettable (lua_State *L, int arg) { - luaL_checktype(L, arg, "table"); - return hvalue(luaA_index(L, arg)); -} - -/* }====================================================== */ - - - int luaB_call (lua_State *L) { int oldtop; - const Hash *arg = gettable(L, 2); const char *options = luaL_opt_string(L, 3, ""); int err = 0; /* index of old error method */ - int n = (int)getnarg(L, arg); int i, status; + int n; + luaL_checktype(L, 2, "table"); + n = lua_getn(L, 2); if (!lua_isnull(L, 4)) { /* set new error method */ lua_getglobal(L, LUA_ERRORMESSAGE); err = lua_gettop(L); /* get index */ @@ -345,9 +289,12 @@ int luaB_call (lua_State *L) { /* push function */ lua_pushobject(L, 1); /* push arg[1...n] */ - luaD_checkstack(L, n); - for (i=0; i<n; i++) - *(L->top++) = *luaH_getnum(arg, i+1); + luaL_checkstack(L, n, "too many arguments"); + for (i=0; i<n; i++) { + lua_pushobject(L, 2); + lua_pushnumber(L, i+1); + lua_rawget(L); + } status = lua_call(L, n, LUA_MULTRET); if (err != 0) { /* restore old error method */ lua_pushobject(L, err); @@ -360,44 +307,35 @@ int luaB_call (lua_State *L) { lua_error(L, NULL); /* propagate error without additional messages */ return 1; } - else { /* no errors */ - if (strchr(options, 'p')) { /* pack results? */ - luaV_pack(L, luaA_index(L, oldtop+1)); - return 1; /* only table is returned */ - } - else - return lua_gettop(L) - oldtop; /* results are already on the stack */ - } + if (strchr(options, 'p')) /* pack results? */ + lua_error(L, "deprecated option `p' in `call'"); + return lua_gettop(L) - oldtop; /* results are already on the stack */ } - int luaB_tostring (lua_State *L) { char buff[64]; - const TObject *o; - luaL_checktype(L, 1, "any"); - o = luaA_index(L, 1); - switch (ttype(o)) { - case TAG_NUMBER: + switch (lua_type(L, 1)[2]) { + case 'm': /* nuMber */ lua_pushstring(L, lua_tostring(L, 1)); return 1; - case TAG_STRING: + case 'r': /* stRing */ lua_pushobject(L, 1); return 1; - case TAG_TABLE: - sprintf(buff, "table: %p", hvalue(o)); + case 'b': /* taBle */ + sprintf(buff, "table: %p", lua_topointer(L, 1)); break; - case TAG_LCLOSURE: case TAG_CCLOSURE: - sprintf(buff, "function: %p", clvalue(o)); + case 'n': /* fuNction */ + sprintf(buff, "function: %p", lua_topointer(L, 1)); break; - case TAG_USERDATA: + case 'e': /* usErdata */ sprintf(buff, "userdata(%d): %p", lua_tag(L, 1), lua_touserdata(L, 1)); break; - case TAG_NIL: + case 'l': /* niL */ lua_pushstring(L, "nil"); return 1; default: - LUA_INTERNALERROR("invalid type"); + luaL_argerror(L, 1, "value expected"); } lua_pushstring(L, buff); return 1; @@ -406,6 +344,46 @@ int luaB_tostring (lua_State *L) { /* }====================================================== */ +/* +** {====================================================== +** Functions that could use only the official API but +** do not, for efficiency. +** ======================================================= +*/ + +#include "lapi.h" +#include "ldo.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lvm.h" + + +/* +** {====================================================== +** Auxiliary functions +** ======================================================= +*/ + + +static Hash *gettable (lua_State *L, int arg) { + luaL_checktype(L, arg, "table"); + return hvalue(luaA_index(L, arg)); +} + +/* }====================================================== */ + + + + + + +/* }====================================================== */ + + /* ** {====================================================== @@ -426,7 +404,8 @@ int luaB_assert (lua_State *L) { int luaB_getn (lua_State *L) { - lua_pushnumber(L, getnarg(L, gettable(L, 1))); + luaL_checktype(L, 1, "table"); + lua_pushnumber(L, lua_getn(L, 1)); return 1; } @@ -440,7 +419,7 @@ static void t_move (lua_State *L, Hash *t, int from, int to) { int luaB_tinsert (lua_State *L) { Hash *a = gettable(L, 1); - int n = (int)getnarg(L, a); + int n = lua_getn(L, 1); int v = lua_gettop(L); /* last argument: to be inserted */ int pos; if (v == 2) /* called with only 2 arguments */ @@ -457,7 +436,7 @@ int luaB_tinsert (lua_State *L) { int luaB_tremove (lua_State *L) { Hash *a = gettable(L, 1); - int n = (int)getnarg(L, a); + int n = lua_getn(L, 1); int pos = luaL_opt_int(L, 2, n); if (n <= 0) return 0; /* table is "empty" */ luaA_pushobject(L, luaH_getnum(a, pos)); /* result = a[pos] */ @@ -471,7 +450,7 @@ int luaB_tremove (lua_State *L) { static int luaB_foreachi (lua_State *L) { const Hash *t = gettable(L, 1); - int n = (int)getnarg(L, t); + int n = lua_getn(L, 1); int i; luaL_checktype(L, 2, "function"); for (i=1; i<=n; i++) { @@ -584,7 +563,7 @@ static void auxsort (lua_State *L, Hash *a, int l, int u, const TObject *f) { int luaB_sort (lua_State *L) { Hash *a = gettable(L, 1); - int n = (int)getnarg(L, a); + int n = lua_getn(L, 1); const TObject *func = NULL; if (!lua_isnull(L, 2)) { /* is there a 2nd argument? */ luaL_checktype(L, 2, "function"); diff --git a/lua.h b/lua.h @@ -1,5 +1,5 @@ /* -** $Id: lua.h,v 1.63 2000/08/31 14:08:27 roberto Exp roberto $ +** $Id: lua.h,v 1.64 2000/08/31 20:23:40 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 @@ -83,6 +83,7 @@ const char *lua_tostring (lua_State *L, int index); size_t lua_strlen (lua_State *L, int index); lua_CFunction lua_tocfunction (lua_State *L, int index); void *lua_touserdata (lua_State *L, int index); +const void *lua_topointer (lua_State *L, int index); /* @@ -145,6 +146,7 @@ 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);