mirror of
https://github.com/lua/lua
synced 2025-03-30 09:32:52 +03:00
new "primitive" getn
This commit is contained in:
parent
6bfef60e77
commit
9ffae705ee
24
lapi.c
24
lapi.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lapi.c,v 2.30 2005/03/08 20:10:05 roberto Exp roberto $
|
||||
** $Id: lapi.c,v 2.31 2005/03/09 16:28:07 roberto Exp roberto $
|
||||
** Lua API
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -350,16 +350,18 @@ LUA_API const char *lua_tostring (lua_State *L, int idx) {
|
||||
|
||||
LUA_API size_t lua_objsize (lua_State *L, int idx) {
|
||||
StkId o = index2adr(L, idx);
|
||||
if (ttisstring(o))
|
||||
return tsvalue(o)->len;
|
||||
else if (ttisuserdata(o))
|
||||
return uvalue(o)->len;
|
||||
else {
|
||||
size_t l;
|
||||
lua_lock(L); /* `luaV_tostring' may create a new string */
|
||||
l = (luaV_tostring(L, o) ? tsvalue(o)->len : 0);
|
||||
lua_unlock(L);
|
||||
return l;
|
||||
switch (ttype(o)) {
|
||||
case LUA_TSTRING: return tsvalue(o)->len;
|
||||
case LUA_TUSERDATA: return uvalue(o)->len;
|
||||
case LUA_TTABLE: return luaH_getn(hvalue(o));
|
||||
case LUA_TNUMBER: {
|
||||
size_t l;
|
||||
lua_lock(L); /* `luaV_tostring' may create a new string */
|
||||
l = (luaV_tostring(L, o) ? tsvalue(o)->len : 0);
|
||||
lua_unlock(L);
|
||||
return l;
|
||||
}
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
49
lauxlib.c
49
lauxlib.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lauxlib.c,v 1.128 2005/02/10 17:12:02 roberto Exp roberto $
|
||||
** $Id: lauxlib.c,v 1.129 2005/02/23 17:30:22 roberto Exp roberto $
|
||||
** Auxiliary functions for building Lua libraries
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -25,12 +25,7 @@
|
||||
#include "lauxlib.h"
|
||||
|
||||
|
||||
/* number of prereserved references (for internal use) */
|
||||
#define RESERVED_REFS 2
|
||||
|
||||
/* reserved references */
|
||||
#define FREELIST_REF 1 /* free list of references */
|
||||
#define ARRAYSIZE_REF 2 /* array sizes */
|
||||
#define FREELIST_REF 0 /* free list of references */
|
||||
|
||||
|
||||
/* convert a stack index to positive */
|
||||
@ -275,6 +270,8 @@ LUALIB_API void luaL_openlib (lua_State *L, const char *libname,
|
||||
** =======================================================
|
||||
*/
|
||||
|
||||
#ifndef luaL_getn
|
||||
|
||||
static int checkint (lua_State *L, int topop) {
|
||||
int n = (lua_type(L, -1) == LUA_TNUMBER) ? lua_tointeger(L, -1) : -1;
|
||||
lua_pop(L, topop);
|
||||
@ -283,7 +280,7 @@ static int checkint (lua_State *L, int topop) {
|
||||
|
||||
|
||||
static void getsizes (lua_State *L) {
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, ARRAYSIZE_REF);
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, "LUA_SIZES");
|
||||
if (lua_isnil(L, -1)) { /* no `size' table? */
|
||||
lua_pop(L, 1); /* remove nil */
|
||||
lua_newtable(L); /* create it */
|
||||
@ -292,7 +289,7 @@ static void getsizes (lua_State *L) {
|
||||
lua_pushliteral(L, "kv");
|
||||
lua_setfield(L, -2, "__mode"); /* metatable(N).__mode = "kv" */
|
||||
lua_pushvalue(L, -1);
|
||||
lua_rawseti(L, LUA_REGISTRYINDEX, ARRAYSIZE_REF); /* store in register */
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, "LUA_SIZES"); /* store in register */
|
||||
}
|
||||
}
|
||||
|
||||
@ -307,31 +304,6 @@ LUALIB_API void luaL_setn (lua_State *L, int t, int n) {
|
||||
}
|
||||
|
||||
|
||||
/* find an `n' such that t[n] ~= nil and t[n+1] == nil */
|
||||
static int countn (lua_State *L, int t) {
|
||||
int i = LUA_FIRSTINDEX - 1;
|
||||
int j = 2;
|
||||
/* find `i' such that i <= n < i*2 (= j) */
|
||||
for (;;) {
|
||||
lua_rawgeti(L, t, j);
|
||||
if (lua_isnil(L, -1)) break;
|
||||
lua_pop(L, 1);
|
||||
i = j;
|
||||
j = i*2;
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
/* i <= n < j; do a binary search */
|
||||
while (i < j-1) {
|
||||
int m = (i+j)/2;
|
||||
lua_rawgeti(L, t, m);
|
||||
if (lua_isnil(L, -1)) j = m;
|
||||
else i = m;
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
return i - LUA_FIRSTINDEX + 1;
|
||||
}
|
||||
|
||||
|
||||
LUALIB_API int luaL_getn (lua_State *L, int t) {
|
||||
int n;
|
||||
t = abs_index(L, t);
|
||||
@ -341,9 +313,11 @@ LUALIB_API int luaL_getn (lua_State *L, int t) {
|
||||
if ((n = checkint(L, 2)) >= 0) return n;
|
||||
lua_getfield(L, t, "n"); /* else try t.n */
|
||||
if ((n = checkint(L, 1)) >= 0) return n;
|
||||
return countn(L, t);
|
||||
return lua_objsize(L, t);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* }====================================================== */
|
||||
|
||||
|
||||
@ -562,11 +536,8 @@ LUALIB_API int luaL_ref (lua_State *L, int t) {
|
||||
lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */
|
||||
}
|
||||
else { /* no free elements */
|
||||
ref = luaL_getn(L, t);
|
||||
if (ref < RESERVED_REFS)
|
||||
ref = RESERVED_REFS; /* skip reserved references */
|
||||
ref = lua_objsize(L, t);
|
||||
ref++; /* create new reference */
|
||||
luaL_setn(L, t, ref);
|
||||
}
|
||||
lua_rawseti(L, t, ref);
|
||||
return ref;
|
||||
|
10
lbaselib.c
10
lbaselib.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lbaselib.c,v 1.169 2005/02/28 17:24:41 roberto Exp roberto $
|
||||
** $Id: lbaselib.c,v 1.170 2005/03/11 15:51:08 roberto Exp roberto $
|
||||
** Basic library
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -332,6 +332,13 @@ static int luaB_assert (lua_State *L) {
|
||||
}
|
||||
|
||||
|
||||
static int luaB_getn (lua_State *L) {
|
||||
luaL_checktype(L, 1, LUA_TTABLE);
|
||||
lua_pushinteger(L, lua_objsize(L, 1));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int luaB_unpack (lua_State *L) {
|
||||
int i = luaL_optint(L, 2, LUA_FIRSTINDEX);
|
||||
int e = luaL_optint(L, 3, -1);
|
||||
@ -448,6 +455,7 @@ static const luaL_reg base_funcs[] = {
|
||||
{"tostring", luaB_tostring},
|
||||
{"type", luaB_type},
|
||||
{"assert", luaB_assert},
|
||||
{"getn", luaB_getn},
|
||||
{"unpack", luaB_unpack},
|
||||
{"select", luaB_select},
|
||||
{"rawequal", luaB_rawequal},
|
||||
|
50
ltable.c
50
ltable.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ltable.c,v 2.17 2005/03/08 20:10:05 roberto Exp roberto $
|
||||
** $Id: ltable.c,v 2.18 2005/03/09 16:28:07 roberto Exp roberto $
|
||||
** Lua tables (hash)
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -524,3 +524,51 @@ TValue *luaH_setstr (lua_State *L, Table *t, TString *key) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int unbound_search (Table *t, unsigned int j) {
|
||||
unsigned int i = j; /* i is zero or a present index */
|
||||
j = j+1;
|
||||
/* find `i' and `j' such that i is present and j is not */
|
||||
while (!ttisnil(luaH_getnum(t, j))) {
|
||||
i = j;
|
||||
j = i*2;
|
||||
if (j > cast(unsigned int, MAX_INT)) { /* overflow? */
|
||||
/* table was built with bad purposes: resort to linear search */
|
||||
i = 1;
|
||||
while (!ttisnil(luaH_getnum(t, i))) i++;
|
||||
return i - 1;
|
||||
}
|
||||
}
|
||||
/* now do a binary search between them */
|
||||
while (i < j-1) {
|
||||
unsigned int m = (i+j)/2;
|
||||
if (ttisnil(luaH_getnum(t, m))) j = m;
|
||||
else i = m;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Try to find a boundary in table `t'. A `boundary' is an integer index
|
||||
** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil).
|
||||
*/
|
||||
int luaH_getn (Table *t) {
|
||||
unsigned int j = t->sizearray;
|
||||
if (j > 0 && ttisnil(&t->array[j - 1])) {
|
||||
/* there is a boundary in the array part: (binary) search for it */
|
||||
unsigned int i = 1;
|
||||
if (ttisnil(&t->array[1 - 1])) return 0;
|
||||
while (i < j - 1) {
|
||||
unsigned int m = (i+j)/2;
|
||||
if (ttisnil(&t->array[m - 1])) j = m;
|
||||
else i = m;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
/* else must find a boundary in hash part */
|
||||
else if (t->node == &luaH_dummynode) /* hash part is empty? */
|
||||
return j; /* that is easy... */
|
||||
else return unbound_search(t, j);
|
||||
}
|
||||
|
||||
|
3
ltable.h
3
ltable.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ltable.h,v 2.4 2005/01/04 15:55:12 roberto Exp roberto $
|
||||
** $Id: ltable.h,v 2.5 2005/01/05 18:20:51 roberto Exp roberto $
|
||||
** Lua tables (hash)
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -30,6 +30,7 @@ Table *luaH_new (lua_State *L, int narray, int lnhash);
|
||||
void luaH_resizearray (lua_State *L, Table *t, int nasize);
|
||||
void luaH_free (lua_State *L, Table *t);
|
||||
int luaH_next (lua_State *L, Table *t, StkId key);
|
||||
int luaH_getn (Table *t);
|
||||
|
||||
/* exported only for debugging */
|
||||
Node *luaH_mainposition (const Table *t, const TValue *key);
|
||||
|
21
ltablib.c
21
ltablib.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ltablib.c,v 1.26 2004/06/15 13:37:21 roberto Exp roberto $
|
||||
** $Id: ltablib.c,v 1.27 2004/12/07 18:28:47 roberto Exp roberto $
|
||||
** Library for Table Manipulation
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -62,29 +62,32 @@ static int getn (lua_State *L) {
|
||||
|
||||
static int setn (lua_State *L) {
|
||||
luaL_checktype(L, 1, LUA_TTABLE);
|
||||
#ifndef luaL_setn
|
||||
luaL_setn(L, 1, luaL_checkint(L, 2));
|
||||
#else
|
||||
luaL_error(L, "`setn' is obsolete");
|
||||
#endif
|
||||
lua_pushvalue(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int tinsert (lua_State *L) {
|
||||
int v = lua_gettop(L); /* number of arguments */
|
||||
int e = aux_getn(L, 1) + LUA_FIRSTINDEX; /* first empty element */
|
||||
int pos; /* where to insert new element */
|
||||
if (v == 2) /* called with only 2 arguments */
|
||||
if (lua_isnone(L, 3)) /* called with only 2 arguments */
|
||||
pos = e; /* insert new element at the end */
|
||||
else {
|
||||
int i;
|
||||
pos = luaL_checkint(L, 2); /* 2nd argument is the position */
|
||||
if (pos > e) e = pos; /* `grow' array if necessary */
|
||||
v = 3; /* function may be called with more than 3 args */
|
||||
lua_settop(L, 3); /* function may be called with more than 3 args */
|
||||
for (i = e; i > pos; i--) { /* move up elements */
|
||||
lua_rawgeti(L, 1, i-1);
|
||||
lua_rawseti(L, 1, i); /* t[i] = t[i-1] */
|
||||
}
|
||||
}
|
||||
luaL_setn(L, 1, e - LUA_FIRSTINDEX + 1); /* new size */
|
||||
while (--e >= pos) { /* move up elements */
|
||||
lua_rawgeti(L, 1, e);
|
||||
lua_rawseti(L, 1, e+1); /* t[e+1] = t[e] */
|
||||
}
|
||||
lua_pushvalue(L, v);
|
||||
lua_rawseti(L, 1, pos); /* t[pos] = v */
|
||||
return 0;
|
||||
}
|
||||
|
10
ltests.c
10
ltests.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ltests.c,v 2.19 2005/01/19 15:54:26 roberto Exp roberto $
|
||||
** $Id: ltests.c,v 2.20 2005/02/18 12:40:02 roberto Exp roberto $
|
||||
** Internal Module for Debugging of the Lua Implementation
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -456,11 +456,11 @@ static int listlocals (lua_State *L) {
|
||||
|
||||
static int get_limits (lua_State *L) {
|
||||
lua_createtable(L, 0, 5);
|
||||
setnameval(L, "BITS_INT", LUA_BITSINT);
|
||||
setnameval(L, "BITS_INT", LUAI_BITSINT);
|
||||
setnameval(L, "LFPF", LFIELDS_PER_FLUSH);
|
||||
setnameval(L, "MAXVARS", MAXVARS);
|
||||
setnameval(L, "MAXVARS", LUAI_MAXVARS);
|
||||
setnameval(L, "MAXSTACK", MAXSTACK);
|
||||
setnameval(L, "MAXUPVALUES", MAXUPVALUES);
|
||||
setnameval(L, "MAXUPVALUES", LUAI_MAXUPVALUES);
|
||||
setnameval(L, "NUM_OPCODES", NUM_OPCODES);
|
||||
return 1;
|
||||
}
|
||||
@ -970,12 +970,14 @@ static int testC (lua_State *L) {
|
||||
int i = getindex;
|
||||
lua_pushinteger(L1, luaL_getn(L1, i));
|
||||
}
|
||||
#ifndef luaL_setn
|
||||
else if EQ("setn") {
|
||||
int i = getindex;
|
||||
int n = cast(int, lua_tonumber(L1, -1));
|
||||
luaL_setn(L1, i, n);
|
||||
lua_pop(L1, 1);
|
||||
}
|
||||
#endif
|
||||
else if EQ("throw") {
|
||||
#ifdef __cplusplus
|
||||
static struct X { int x; } x;
|
||||
|
Loading…
x
Reference in New Issue
Block a user