seqlua
diff seqlua.c @ 30:367fc70acc15
Respect the __ipairs and __len metamethods
| author | jbe |
|---|---|
| date | Sat Aug 23 23:13:17 2014 +0200 (2014-08-23) |
| parents | 44880bcfc323 |
| children | 3ff7cec8d3ce |
line diff
1.1 --- a/seqlua.c Fri Aug 22 12:27:25 2014 +0200 1.2 +++ b/seqlua.c Sat Aug 23 23:13:17 2014 +0200 1.3 @@ -2,28 +2,18 @@ 1.4 #include <lauxlib.h> 1.5 #include "seqlualib.h" 1.6 1.7 -static int seqlua_ipairsaux_raw(lua_State *L) { 1.8 - lua_Integer i; 1.9 - luaL_checktype(L, 1, LUA_TTABLE); 1.10 - i = luaL_checkinteger(L, 2) + 1; 1.11 - lua_pushinteger(L, i); 1.12 - lua_rawgeti(L, 1, i); // TODO: Lua 5.3 returns type 1.13 - return lua_isnil(L, -1) ? 1 : 2; 1.14 -} 1.15 - 1.16 -static int seqlua_ipairsaux_meta(lua_State *L) { 1.17 - lua_Integer i; 1.18 - i = luaL_checkinteger(L, 2) + 1; 1.19 +static int seqlua_ipairsaux_index(lua_State *L) { 1.20 + lua_Integer i = luaL_checkinteger(L, 2) + 1; 1.21 lua_pushinteger(L, i); 1.22 lua_pushinteger(L, i); 1.23 lua_gettable(L, 1); // TODO: Lua 5.3 returns type 1.24 - return lua_isnil(L, -1) ? 1 : 2; 1.25 + return lua_isnil(L, -1) && i > luaL_len(L, 1) ? 1 : 2; 1.26 } 1.27 1.28 -static int seqlua_ipairsaux_func(lua_State *L) { 1.29 +static int seqlua_ipairsaux_call(lua_State *L) { 1.30 lua_pushinteger(L, luaL_checkinteger(L, 2) + 1); 1.31 - lua_insert(L, 1); 1.32 - lua_settop(L, 2); 1.33 + lua_insert(L, 1); // integer on stack index 1 1.34 + lua_settop(L, 2); // function on stack index 2 1.35 lua_call(L, 0, LUA_MULTRET); 1.36 if (lua_isnoneornil(L, 2)) { 1.37 lua_settop(L, 0); 1.38 @@ -35,20 +25,22 @@ 1.39 } 1.40 1.41 static int seqlua_ipairs(lua_State *L) { 1.42 - luaL_checkany(L, 1); // provides better error message 1.43 - if ( 1.44 - lua_type(L, 1) == LUA_TFUNCTION || 1.45 - (luaL_getmetafield(L, 1, "__call") && (lua_pop(L, 1), 1)) 1.46 - ) { 1.47 - lua_pushcfunction(L, seqlua_ipairsaux_func); 1.48 - } else if (luaL_getmetafield(L, 1, "__index")) { 1.49 - lua_pushcfunction(L, seqlua_ipairsaux_meta); 1.50 + if (luaL_getmetafield(L, 1, "__ipairs")) { 1.51 + lua_pushvalue(L, 1); 1.52 + lua_call(L, 1, 3); 1.53 } else { 1.54 - luaL_checktype(L, 1, LUA_TTABLE); 1.55 - lua_pushcfunction(L, seqlua_ipairsaux_raw); 1.56 + int t = lua_type(L, 1); 1.57 + if (t == LUA_TFUNCTION) { 1.58 + lua_pushcfunction(L, seqlua_ipairsaux_call); 1.59 + } else { 1.60 + if (t != LUA_TTABLE && !luaL_getmetafield(L, 1, "__index")) { 1.61 + luaL_checktype(L, 1, LUA_TTABLE); 1.62 + } 1.63 + lua_pushcfunction(L, seqlua_ipairsaux_index); 1.64 + } 1.65 + lua_pushvalue(L, 1); 1.66 + lua_pushinteger(L, 0); 1.67 } 1.68 - lua_pushvalue(L, 1); 1.69 - lua_pushinteger(L, 0); 1.70 return 3; 1.71 } 1.72