aboutsummaryrefslogtreecommitdiff
path: root/lbaselib.c
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 /lbaselib.c
parent57d842414670769fff8ad045693dcbf1018c59c1 (diff)
downloadlua-f9037ae8c1ccb614e38cb56054927aef6203cfd9.tar.gz
lua-f9037ae8c1ccb614e38cb56054927aef6203cfd9.tar.bz2
lua-f9037ae8c1ccb614e38cb56054927aef6203cfd9.zip
'ipairs' respects metamethods
Diffstat (limited to 'lbaselib.c')
-rw-r--r--lbaselib.c46
1 files changed, 41 insertions, 5 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