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);

Impressum / About Us