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:
M | lapi.c | | | 48 | +++++++++++++++++++++++++++++++++++++++++++----- |
M | lbuiltin.c | | | 159 | ++++++++++++++++++++++++++++++++++--------------------------------------------- |
M | lua.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);