seqlua
changeset 32:3ff7cec8d3ce
Do not respect __len metamethods
author | jbe |
---|---|
date | Sun Aug 24 00:00:43 2014 +0200 (2014-08-24) |
parents | 4fc9090ada1d |
children | 25cdfe854335 |
files | README seqlua.c seqlualib.c seqlualib.h |
line diff
1.1 --- a/README Sat Aug 23 23:35:10 2014 +0200 1.2 +++ b/README Sun Aug 24 00:00:43 2014 +0200 1.3 @@ -5,13 +5,16 @@ 1.4 1.5 * allow ``ipairs(seq)`` to accept tables as well as functions (i.e function 1.6 iterators), 1.7 -* add a new function ``string.concat(separator, seq)`` to concat either table 1.8 - entries or function return values, 1.9 +* add a new function ``string.concat(separator, seq)`` to concat either 1.10 + table entries or function return values, 1.11 * provide auxiliary C functions and macros to simplify iterating over both 1.12 tables and iterator functions with the same statement. 1.13 1.14 -In all cases, existing ``__index``, ``__len``, or ``__ipairs`` metamethods are 1.15 -respected. The ``__ipairs`` metamethod takes precedence. 1.16 +Existing ``__ipairs`` or ``__index`` (but not ``__len``) metamethods 1.17 +are respected by the C and Lua functions as well as C macros. The 1.18 +``__ipairs`` metamethod takes precedence over ``__index``, while the 1.19 +``__len`` metamethod is never used. 1.20 + 1.21 1.22 1.23 Lua part of the library
2.1 --- a/seqlua.c Sat Aug 23 23:35:10 2014 +0200 2.2 +++ b/seqlua.c Sun Aug 24 00:00:43 2014 +0200 2.3 @@ -2,12 +2,21 @@ 2.4 #include <lauxlib.h> 2.5 #include "seqlualib.h" 2.6 2.7 +static int seqlua_ipairsaux_raw(lua_State *L) { 2.8 + lua_Integer i; 2.9 + luaL_checktype(L, 1, LUA_TTABLE); 2.10 + i = luaL_checkinteger(L, 2) + 1; 2.11 + lua_pushinteger(L, i); 2.12 + lua_rawgeti(L, 1, i); // TODO: Lua 5.3 returns type 2.13 + return lua_isnil(L, -1) ? 1 : 2; 2.14 +} 2.15 + 2.16 static int seqlua_ipairsaux_index(lua_State *L) { 2.17 lua_Integer i = luaL_checkinteger(L, 2) + 1; 2.18 lua_pushinteger(L, i); 2.19 lua_pushinteger(L, i); 2.20 lua_gettable(L, 1); // TODO: Lua 5.3 returns type 2.21 - return lua_isnil(L, -1) && i > luaL_len(L, 1) ? 1 : 2; 2.22 + return lua_isnil(L, -1) ? 1 : 2; 2.23 } 2.24 2.25 static int seqlua_ipairsaux_call(lua_State *L) { 2.26 @@ -32,10 +41,10 @@ 2.27 int t = lua_type(L, 1); 2.28 if (t == LUA_TFUNCTION) { 2.29 lua_pushcfunction(L, seqlua_ipairsaux_call); 2.30 + } else if (luaL_getmetafield(L, 1, "__index")) { 2.31 + lua_pushcfunction(L, seqlua_ipairsaux_index); 2.32 } else { 2.33 - if (t != LUA_TTABLE && !luaL_getmetafield(L, 1, "__index")) { 2.34 - luaL_checktype(L, 1, LUA_TTABLE); 2.35 - } 2.36 + luaL_checktype(L, 1, LUA_TTABLE); 2.37 lua_pushcfunction(L, seqlua_ipairsaux_index); 2.38 } 2.39 lua_pushvalue(L, 1);
3.1 --- a/seqlualib.c Sat Aug 23 23:35:10 2014 +0200 3.2 +++ b/seqlualib.c Sun Aug 24 00:00:43 2014 +0200 3.3 @@ -15,12 +15,8 @@ 3.4 } else { 3.5 if (lua_type(L, idx) == LUA_TFUNCTION) { 3.6 iter->itertype = SEQLUA_ITERTYPE_CALL; 3.7 - } else if ( 3.8 - luaL_getmetafield(L, idx, "__index") || 3.9 - luaL_getmetafield(L, idx, "__len") 3.10 - ) { 3.11 + } else if (luaL_getmetafield(L, idx, "__index")) { 3.12 lua_pop(L, 1); 3.13 - iter->len = luaL_len(L, idx); 3.14 iter->itertype = SEQLUA_ITERTYPE_INDEX; 3.15 } else { 3.16 luaL_checktype(L, idx, LUA_TTABLE); 3.17 @@ -56,13 +52,9 @@ 3.18 lua_call(L, 0, 1); 3.19 break; 3.20 case SEQLUA_ITERTYPE_INDEX: 3.21 - if (i > iter->len) { 3.22 - lua_pop(L, 3); 3.23 - return 0; 3.24 - } 3.25 lua_pushinteger(L, i); 3.26 lua_gettable(L, iter->idx); 3.27 - return 1; 3.28 + break; 3.29 case SEQLUA_ITERTYPE_RAW: 3.30 lua_rawgeti(L, iter->idx, i); 3.31 break;
4.1 --- a/seqlualib.h Sat Aug 23 23:35:10 2014 +0200 4.2 +++ b/seqlualib.h Sun Aug 24 00:00:43 2014 +0200 4.3 @@ -6,7 +6,6 @@ 4.4 int idx; 4.5 int itertype; 4.6 lua_Integer i; 4.7 - lua_Integer len; 4.8 } seqlua_Iterator; 4.9 4.10 extern void seqlua_iterinit(lua_State *L, seqlua_Iterator *iter, int idx);