commit 41ed3c47719b29dd02dc9fcf07f79dc6f2c4381d
parent 635b7c707d146ab56127260601b6fb84c0c140f3
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Mon, 27 Jan 2003 11:45:54 -0200
getn/setn in C moved to lauxlib
Diffstat:
M | lauxlib.c | | | 85 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- |
M | lauxlib.h | | | 5 | ++++- |
M | ltablib.c | | | 65 | +++++++---------------------------------------------------------- |
3 files changed, 94 insertions(+), 61 deletions(-)
diff --git a/lauxlib.c b/lauxlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lauxlib.c,v 1.91 2002/12/04 17:38:31 roberto Exp roberto $
+** $Id: lauxlib.c,v 1.92 2003/01/23 11:34:18 roberto Exp roberto $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@@ -23,6 +23,13 @@
#include "lauxlib.h"
+/* number of prereserved references (for internal use) */
+#define RESERVED_REFS 1
+
+/* reserved reference for array sizes */
+#define ARRAYSIZE_REF 1
+
+
/*
** {======================================================
** Error-report functions
@@ -197,6 +204,78 @@ LUALIB_API void luaL_openlib (lua_State *L, const char *libname,
/*
** {======================================================
+** getn-setn: size for arrays
+** =======================================================
+*/
+
+static int checkint (lua_State *L, int topop) {
+ int n = (int)lua_tonumber(L, -1);
+ if (n == 0 && !lua_isnumber(L, -1)) n = -1;
+ lua_pop(L, topop);
+ return n;
+}
+
+
+static void getsizes (lua_State *L) {
+ lua_rawgeti(L, LUA_REGISTRYINDEX, ARRAYSIZE_REF);
+ if (lua_isnil(L, -1)) { /* no `size' table? */
+ lua_newtable(L); /* create it */
+ lua_pushvalue(L, -1); /* `size' will be its own metatable */
+ lua_setmetatable(L, -2);
+ lua_pushliteral(L, "__mode");
+ lua_pushliteral(L, "k");
+ lua_rawset(L, -3); /* metatable(N).__mode = "k" */
+ lua_pushvalue(L, -1);
+ lua_rawseti(L, LUA_REGISTRYINDEX, ARRAYSIZE_REF); /* store in register */
+ }
+}
+
+
+void luaL_setn (lua_State *L, int t, int n) {
+ lua_pushliteral(L, "n");
+ lua_rawget(L, t);
+ if (checkint(L, 1) >= 0) { /* is there a numeric field `n'? */
+ lua_pushliteral(L, "n"); /* use it */
+ lua_pushnumber(L, n);
+ lua_rawset(L, t);
+ }
+ else { /* use `sizes' */
+ getsizes(L);
+ lua_pushvalue(L, t);
+ lua_pushnumber(L, n);
+ lua_rawset(L, -3); /* sizes[t] = n */
+ lua_pop(L, 1); /* remove `sizes' */
+ }
+}
+
+
+int luaL_getn (lua_State *L, int t) {
+ int n;
+ lua_pushliteral(L, "n"); /* try t.n */
+ lua_rawget(L, t);
+ if ((n = checkint(L, 1)) >= 0) return n;
+ getsizes(L); /* else try sizes[t] */
+ lua_pushvalue(L, t);
+ lua_rawget(L, -2);
+ if ((n = checkint(L, 2)) >= 0) return n;
+ else { /* must count elements */
+ for (n = 1; ; n++) {
+ lua_rawgeti(L, t, n);
+ if (lua_isnil(L, -1)) break;
+ lua_pop(L, 1);
+ }
+ lua_pop(L, 1);
+ luaL_setn(L, t, n - 1);
+ return n - 1;
+ }
+}
+
+/* }====================================================== */
+
+
+
+/*
+** {======================================================
** Generic Buffer manipulation
** =======================================================
*/
@@ -308,8 +387,10 @@ LUALIB_API int luaL_ref (lua_State *L, int t) {
lua_pushliteral(L, "n");
lua_pushvalue(L, -1);
lua_rawget(L, t); /* get t.n */
- ref = (int)lua_tonumber(L, -1) + 1; /* ref = t.n + 1 */
+ ref = (int)lua_tonumber(L, -1); /* ref = t.n */
lua_pop(L, 1); /* pop t.n */
+ if (ref == 0) ref = RESERVED_REFS; /* skip reserved references */
+ ref++; /* create new reference */
lua_pushnumber(L, ref);
lua_rawset(L, t); /* t.n = t.n + 1 */
}
diff --git a/lauxlib.h b/lauxlib.h
@@ -1,5 +1,5 @@
/*
-** $Id: lauxlib.h,v 1.55 2002/11/14 15:41:38 roberto Exp roberto $
+** $Id: lauxlib.h,v 1.56 2003/01/17 15:28:09 roberto Exp roberto $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@@ -51,6 +51,9 @@ LUALIB_API int luaL_findstring (const char *st, const char *const lst[]);
LUALIB_API int luaL_ref (lua_State *L, int t);
LUALIB_API void luaL_unref (lua_State *L, int t, int ref);
+LUALIB_API int luaL_getn (lua_State *L, int t);
+LUALIB_API void luaL_setn (lua_State *L, int t, int n);
+
LUALIB_API int luaL_loadfile (lua_State *L, const char *filename);
LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t sz,
const char *name);
diff --git a/ltablib.c b/ltablib.c
@@ -1,5 +1,5 @@
/*
-** $Id: ltablib.c,v 1.17 2002/12/04 17:38:31 roberto Exp roberto $
+** $Id: ltablib.c,v 1.18 2002/12/20 10:26:33 roberto Exp roberto $
** Library for Table Manipulation
** See Copyright Notice in lua.h
*/
@@ -15,52 +15,7 @@
#include "lualib.h"
-
-static int checkint (lua_State *L) {
- int n = (int)lua_tonumber(L, -1);
- if (n == 0 && !lua_isnumber(L, -1)) n = -1;
- lua_pop(L, 1);
- return n;
-}
-
-
-static void aux_setn (lua_State *L, int t, int n) {
- lua_pushliteral(L, "n");
- lua_rawget(L, t);
- if (checkint(L) >= 0) {
- lua_pushliteral(L, "n"); /* use it */
- lua_pushnumber(L, n);
- lua_rawset(L, t);
- }
- else { /* use N */
- lua_pushvalue(L, t);
- lua_pushnumber(L, n);
- lua_rawset(L, lua_upvalueindex(1)); /* N[t] = n */
- }
-}
-
-
-static int aux_getn (lua_State *L, int t) {
- int n;
- luaL_checktype(L, t, LUA_TTABLE);
- lua_pushliteral(L, "n"); /* try t.n */
- lua_rawget(L, t);
- if ((n = checkint(L)) >= 0) return n;
- lua_pushvalue(L, t); /* try N[t] */
- lua_rawget(L, lua_upvalueindex(1));
- if ((n = checkint(L)) >= 0) return n;
- else { /* must count elements */
- n = 0;
- for (;;) {
- lua_rawgeti(L, t, ++n);
- if (lua_isnil(L, -1)) break;
- lua_pop(L, 1);
- }
- lua_pop(L, 1);
- aux_setn(L, t, n - 1);
- return n - 1;
- }
-}
+#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n))
static int luaB_foreachi (lua_State *L) {
@@ -106,7 +61,7 @@ static int luaB_getn (lua_State *L) {
static int luaB_setn (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
- aux_setn(L, 1, luaL_checkint(L, 2));
+ luaL_setn(L, 1, luaL_checkint(L, 2));
return 0;
}
@@ -122,7 +77,7 @@ static int luaB_tinsert (lua_State *L) {
if (pos > n) n = pos; /* `grow' array if necessary */
v = 3; /* function may be called with more than 3 args */
}
- aux_setn(L, 1, n); /* new size */
+ luaL_setn(L, 1, n); /* new size */
while (--n >= pos) { /* move up elements */
lua_rawgeti(L, 1, n);
lua_rawseti(L, 1, n+1); /* t[n+1] = t[n] */
@@ -137,7 +92,7 @@ static int luaB_tremove (lua_State *L) {
int n = aux_getn(L, 1);
int pos = luaL_optint(L, 2, n);
if (n <= 0) return 0; /* table is `empty' */
- aux_setn(L, 1, n-1); /* t.n = n-1 */
+ luaL_setn(L, 1, n-1); /* t.n = n-1 */
lua_rawgeti(L, 1, pos); /* result = t[pos] */
for ( ;pos<n; pos++) {
lua_rawgeti(L, 1, pos+1);
@@ -156,7 +111,7 @@ static int str_concat (lua_State *L) {
int i = luaL_optint(L, 3, 1);
int n = luaL_optint(L, 4, 0);
luaL_checktype(L, 1, LUA_TTABLE);
- if (n == 0) n = aux_getn(L, 1);
+ if (n == 0) n = luaL_getn(L, 1);
luaL_buffinit(L, &b);
for (; i <= n; i++) {
lua_rawgeti(L, 1, i);
@@ -289,13 +244,7 @@ static const luaL_reg tab_funcs[] = {
LUALIB_API int lua_tablibopen (lua_State *L) {
- lua_newtable(L); /* create N (table to store num. elements in tables) */
- lua_pushvalue(L, -1); /* `N' will be its own metatable */
- lua_setmetatable(L, -2);
- lua_pushliteral(L, "__mode");
- lua_pushliteral(L, "k");
- lua_rawset(L, -3); /* metatable(N).__mode = "k" */
- luaL_openlib(L, LUA_TABLIBNAME, tab_funcs, 1);
+ luaL_openlib(L, LUA_TABLIBNAME, tab_funcs, 0);
return 1;
}