summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2014-07-24 16:33:29 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2014-07-24 16:33:29 -0300
commitf9037ae8c1ccb614e38cb56054927aef6203cfd9 (patch)
tree658f5d707b03c1b04258165db15544f5cbd52775
parent57d842414670769fff8ad045693dcbf1018c59c1 (diff)
downloadlua-f9037ae8c1ccb614e38cb56054927aef6203cfd9.tar.gz
lua-f9037ae8c1ccb614e38cb56054927aef6203cfd9.tar.bz2
lua-f9037ae8c1ccb614e38cb56054927aef6203cfd9.zip
'ipairs' respects metamethods
-rw-r--r--lbaselib.c46
-rw-r--r--ltests.h3
-rw-r--r--luaconf.h7
3 files changed, 49 insertions, 7 deletions
diff --git a/lbaselib.c b/lbaselib.c
index 47d6793a..ffb21804 100644
--- a/lbaselib.c
+++ b/lbaselib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lbaselib.c,v 1.291 2014/07/16 13:56:59 roberto Exp roberto $ 2** $Id: lbaselib.c,v 1.292 2014/07/17 13:53:37 roberto Exp roberto $
3** Basic library 3** Basic library
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -244,17 +244,53 @@ static int luaB_pairs (lua_State *L) {
244} 244}
245 245
246 246
247static int ipairsaux (lua_State *L) { 247/*
248 int i = luaL_checkint(L, 2); 248** Traversal function for 'ipairs' for raw tables
249*/
250static int ipairsaux_raw (lua_State *L) {
251 int i = luaL_checkint(L, 2) + 1;
249 luaL_checktype(L, 1, LUA_TTABLE); 252 luaL_checktype(L, 1, LUA_TTABLE);
250 i++; /* next value */
251 lua_pushinteger(L, i); 253 lua_pushinteger(L, i);
252 return (lua_rawgeti(L, 1, i) == LUA_TNIL) ? 1 : 2; 254 return (lua_rawgeti(L, 1, i) == LUA_TNIL) ? 1 : 2;
253} 255}
254 256
255 257
258/*
259** Traversal function for 'ipairs' for tables with metamethods
260*/
261static int ipairsaux (lua_State *L) {
262 int i = luaL_checkint(L, 2) + 1;
263 if (i > luaL_len(L, 1)) { /* larger than length? */
264 lua_pushnil(L); /* end traversal */
265 return 1;
266 }
267 else {
268 lua_pushinteger(L, i);
269 lua_pushinteger(L, i); /* key for indexing table */
270 lua_gettable(L, 1);
271 return 2;
272 }
273}
274
275
276/*
277** This function will use either 'ipairsaux' or 'ipairsaux_raw' to
278** traverse a table, depending on whether the table has metamethods
279** that can affect the traversal.
280*/
256static int luaB_ipairs (lua_State *L) { 281static int luaB_ipairs (lua_State *L) {
257 return pairsmeta(L, "__ipairs", 1, ipairsaux); 282 lua_CFunction iter =
283 (luaL_getmetafield(L, 1, "__len") ||
284 luaL_getmetafield(L, 1, "__index"))
285 ? ipairsaux : ipairsaux_raw;
286#if defined(LUA_COMPAT_IPAIRS)
287 return pairsmeta(L, "__ipairs", 1, iter);
288#else
289 lua_pushcfunction(L, iter); /* iteration function */
290 lua_pushvalue(L, 1); /* state */
291 lua_pushinteger(L, 0); /* initial value */
292 return 3;
293#endif
258} 294}
259 295
260 296
diff --git a/ltests.h b/ltests.h
index 805f46ed..56b0d352 100644
--- a/ltests.h
+++ b/ltests.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltests.h,v 2.37 2014/07/23 17:16:50 roberto Exp roberto $ 2** $Id: ltests.h,v 2.38 2014/07/24 14:00:16 roberto Exp roberto $
3** Internal Header for Debugging of the Lua Implementation 3** Internal Header for Debugging of the Lua Implementation
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -12,6 +12,7 @@
12 12
13/* test Lua with no compatibility code */ 13/* test Lua with no compatibility code */
14#undef LUA_COMPAT_MATHLIB 14#undef LUA_COMPAT_MATHLIB
15#undef LUA_COMPAT_IPAIRS
15#undef LUA_COMPAT_BITLIB 16#undef LUA_COMPAT_BITLIB
16#undef LUA_COMPAT_APIUNSIGNED 17#undef LUA_COMPAT_APIUNSIGNED
17#undef LUA_COMPAT_FLOATSTRING 18#undef LUA_COMPAT_FLOATSTRING
diff --git a/luaconf.h b/luaconf.h
index 6edc0e4e..07e98a5d 100644
--- a/luaconf.h
+++ b/luaconf.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: luaconf.h,v 1.210 2014/07/17 13:53:37 roberto Exp roberto $ 2** $Id: luaconf.h,v 1.211 2014/07/24 14:00:16 roberto Exp roberto $
3** Configuration file for Lua 3** Configuration file for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -305,6 +305,11 @@
305#define LUA_COMPAT_BITLIB 305#define LUA_COMPAT_BITLIB
306 306
307/* 307/*
308@@ LUA_COMPAT_IPAIRS controls the effectivness of the __ipairs metamethod.
309*/
310#define LUA_COMPAT_IPAIRS
311
312/*
308@@ LUA_COMPAT_APIUNSIGNED controls the presence of macros for 313@@ LUA_COMPAT_APIUNSIGNED controls the presence of macros for
309** manipulating unsigned integers (lua_pushunsigned, lua_tounsigned, etc.) 314** manipulating unsigned integers (lua_pushunsigned, lua_tounsigned, etc.)
310*/ 315*/