'ipairs' respects metamethods
This commit is contained in:
46
lbaselib.c
46
lbaselib.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lbaselib.c,v 1.291 2014/07/16 13:56:59 roberto Exp roberto $
|
** $Id: lbaselib.c,v 1.292 2014/07/17 13:53:37 roberto Exp roberto $
|
||||||
** Basic library
|
** Basic library
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -244,17 +244,53 @@ static int luaB_pairs (lua_State *L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int ipairsaux (lua_State *L) {
|
/*
|
||||||
int i = luaL_checkint(L, 2);
|
** Traversal function for 'ipairs' for raw tables
|
||||||
|
*/
|
||||||
|
static int ipairsaux_raw (lua_State *L) {
|
||||||
|
int i = luaL_checkint(L, 2) + 1;
|
||||||
luaL_checktype(L, 1, LUA_TTABLE);
|
luaL_checktype(L, 1, LUA_TTABLE);
|
||||||
i++; /* next value */
|
|
||||||
lua_pushinteger(L, i);
|
lua_pushinteger(L, i);
|
||||||
return (lua_rawgeti(L, 1, i) == LUA_TNIL) ? 1 : 2;
|
return (lua_rawgeti(L, 1, i) == LUA_TNIL) ? 1 : 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Traversal function for 'ipairs' for tables with metamethods
|
||||||
|
*/
|
||||||
|
static int ipairsaux (lua_State *L) {
|
||||||
|
int i = luaL_checkint(L, 2) + 1;
|
||||||
|
if (i > luaL_len(L, 1)) { /* larger than length? */
|
||||||
|
lua_pushnil(L); /* end traversal */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lua_pushinteger(L, i);
|
||||||
|
lua_pushinteger(L, i); /* key for indexing table */
|
||||||
|
lua_gettable(L, 1);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** This function will use either 'ipairsaux' or 'ipairsaux_raw' to
|
||||||
|
** traverse a table, depending on whether the table has metamethods
|
||||||
|
** that can affect the traversal.
|
||||||
|
*/
|
||||||
static int luaB_ipairs (lua_State *L) {
|
static int luaB_ipairs (lua_State *L) {
|
||||||
return pairsmeta(L, "__ipairs", 1, ipairsaux);
|
lua_CFunction iter =
|
||||||
|
(luaL_getmetafield(L, 1, "__len") ||
|
||||||
|
luaL_getmetafield(L, 1, "__index"))
|
||||||
|
? ipairsaux : ipairsaux_raw;
|
||||||
|
#if defined(LUA_COMPAT_IPAIRS)
|
||||||
|
return pairsmeta(L, "__ipairs", 1, iter);
|
||||||
|
#else
|
||||||
|
lua_pushcfunction(L, iter); /* iteration function */
|
||||||
|
lua_pushvalue(L, 1); /* state */
|
||||||
|
lua_pushinteger(L, 0); /* initial value */
|
||||||
|
return 3;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
3
ltests.h
3
ltests.h
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ltests.h,v 2.37 2014/07/23 17:16:50 roberto Exp roberto $
|
** $Id: ltests.h,v 2.38 2014/07/24 14:00:16 roberto Exp roberto $
|
||||||
** Internal Header for Debugging of the Lua Implementation
|
** Internal Header for Debugging of the Lua Implementation
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
/* test Lua with no compatibility code */
|
/* test Lua with no compatibility code */
|
||||||
#undef LUA_COMPAT_MATHLIB
|
#undef LUA_COMPAT_MATHLIB
|
||||||
|
#undef LUA_COMPAT_IPAIRS
|
||||||
#undef LUA_COMPAT_BITLIB
|
#undef LUA_COMPAT_BITLIB
|
||||||
#undef LUA_COMPAT_APIUNSIGNED
|
#undef LUA_COMPAT_APIUNSIGNED
|
||||||
#undef LUA_COMPAT_FLOATSTRING
|
#undef LUA_COMPAT_FLOATSTRING
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: luaconf.h,v 1.210 2014/07/17 13:53:37 roberto Exp roberto $
|
** $Id: luaconf.h,v 1.211 2014/07/24 14:00:16 roberto Exp roberto $
|
||||||
** Configuration file for Lua
|
** Configuration file for Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -304,6 +304,11 @@
|
|||||||
*/
|
*/
|
||||||
#define LUA_COMPAT_BITLIB
|
#define LUA_COMPAT_BITLIB
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ LUA_COMPAT_IPAIRS controls the effectivness of the __ipairs metamethod.
|
||||||
|
*/
|
||||||
|
#define LUA_COMPAT_IPAIRS
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ LUA_COMPAT_APIUNSIGNED controls the presence of macros for
|
@@ LUA_COMPAT_APIUNSIGNED controls the presence of macros for
|
||||||
** manipulating unsigned integers (lua_pushunsigned, lua_tounsigned, etc.)
|
** manipulating unsigned integers (lua_pushunsigned, lua_tounsigned, etc.)
|
||||||
|
|||||||
Reference in New Issue
Block a user