seqlua
diff seqlua.c @ 0:47f9b323d68c
Initial commit
author | jbe |
---|---|
date | Wed Aug 20 00:39:10 2014 +0200 (2014-08-20) |
parents | |
children | 144f0bddee2b |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/seqlua.c Wed Aug 20 00:39:10 2014 +0200 1.3 @@ -0,0 +1,123 @@ 1.4 +#include <lua.h> 1.5 +#include <lauxlib.h> 1.6 +#include "seqlualib.h" 1.7 + 1.8 +static int seqlua_ipairsaux_raw(lua_State *L) { 1.9 + lua_Integer i; 1.10 + luaL_checktype(L, 1, LUA_TTABLE); 1.11 + i = luaL_checkinteger(L, 2) + 1; 1.12 + lua_pushinteger(L, i); 1.13 + lua_rawgeti(L, 1, i); // TODO: Lua 5.3 returns type 1.14 + return lua_isnil(L, -1) ? 1 : 2; 1.15 +} 1.16 + 1.17 +static int seqlua_ipairsaux_meta(lua_State *L) { 1.18 + lua_Integer i; 1.19 + i = luaL_checkinteger(L, 2) + 1; 1.20 + lua_pushinteger(L, i); 1.21 + lua_pushinteger(L, i); 1.22 + lua_gettable(L, 1); // TODO: Lua 5.3 returns type 1.23 + return lua_isnil(L, -1) ? 1 : 2; 1.24 +} 1.25 + 1.26 +static int seqlua_ipairsaux_func(lua_State *L) { 1.27 + luaL_checktype(L, 1, LUA_TFUNCTION); 1.28 + lua_pushinteger(L, luaL_checkinteger(L, 2) + 1); 1.29 + lua_insert(L, 1); 1.30 + lua_settop(L, 2); 1.31 + lua_call(L, 0, LUA_MULTRET); 1.32 + if (lua_isnoneornil(L, 2)) { 1.33 + lua_settop(L, 0); 1.34 + lua_pushnil(L); 1.35 + return 1; 1.36 + } else { 1.37 + return lua_gettop(L); 1.38 + } 1.39 +} 1.40 + 1.41 +static int seqlua_ipairsaux_funcclosure(lua_State *L) { 1.42 + lua_Integer i = lua_tointeger(L, lua_upvalueindex(4)) + 1; 1.43 + lua_settop(L, 0); 1.44 + lua_pushinteger(L, i); 1.45 + lua_replace(L, lua_upvalueindex(4)); 1.46 + lua_pushinteger(L, i); 1.47 + lua_pushvalue(L, lua_upvalueindex(1)); 1.48 + lua_pushvalue(L, lua_upvalueindex(2)); 1.49 + lua_pushvalue(L, lua_upvalueindex(3)); 1.50 + lua_call(L, 2, LUA_MULTRET); 1.51 + if (lua_isnoneornil(L, 2)) { 1.52 + lua_settop(L, 0); 1.53 + lua_pushnil(L); 1.54 + return 1; 1.55 + } else { 1.56 + lua_pushvalue(L, 2); 1.57 + lua_replace(L, lua_upvalueindex(3)); 1.58 + return lua_gettop(L); 1.59 + } 1.60 +} 1.61 + 1.62 +static int seqlua_ipairs(lua_State *L) { 1.63 + if (luaL_getmetafield(L, 1, "__call")) { 1.64 + if (lua_type(L, -1) != LUA_TFUNCTION) luaL_error(L, "__call is not a function"); 1.65 + lua_replace(L, 1); 1.66 + } 1.67 + if (lua_type(L, 1) == LUA_TFUNCTION) { 1.68 + if (!lua_isnoneornil(L, 2) || !lua_isnoneornil(L, 3)) { 1.69 + lua_settop(L, 3); 1.70 + lua_pushinteger(L, 0); 1.71 + lua_pushcclosure(L, seqlua_ipairsaux_funcclosure, 4); 1.72 + return 1; 1.73 + } 1.74 + lua_pushcfunction(L, seqlua_ipairsaux_func); 1.75 + } else if (luaL_getmetafield(L, 1, "__index")) { 1.76 + lua_pushcfunction(L, seqlua_ipairsaux_meta); 1.77 + } else { 1.78 + luaL_checktype(L, 1, LUA_TTABLE); 1.79 + lua_pushcfunction(L, seqlua_ipairsaux_raw); 1.80 + } 1.81 + lua_pushvalue(L, 1); 1.82 + lua_pushinteger(L, 0); 1.83 + return 3; 1.84 +} 1.85 + 1.86 +static int seqlua_iteratoraux(lua_State *L) { 1.87 + lua_settop(L, 0); 1.88 + lua_pushvalue(L, lua_upvalueindex(1)); 1.89 + lua_pushvalue(L, lua_upvalueindex(2)); 1.90 + lua_pushvalue(L, lua_upvalueindex(3)); 1.91 + lua_call(L, 2, LUA_MULTRET); 1.92 + if (lua_isnoneornil(L, 1)) { 1.93 + lua_settop(L, 1); 1.94 + return 1; 1.95 + } 1.96 + lua_pushvalue(L, 1); 1.97 + lua_replace(L, lua_upvalueindex(3)); 1.98 + return lua_gettop(L); 1.99 +} 1.100 + 1.101 +static int seqlua_iterator(lua_State *L) { 1.102 + if (luaL_getmetafield(L, 1, "__call")) { 1.103 + if (lua_type(L, -1) != LUA_TFUNCTION) luaL_error(L, "__call is not a function"); 1.104 + lua_replace(L, 1); 1.105 + } 1.106 + if (lua_type(L, 1) == LUA_TFUNCTION) { 1.107 + if (lua_isnoneornil(L, 2) && lua_isnoneornil(L, 3)) { 1.108 + lua_settop(L, 1); 1.109 + } else { 1.110 + lua_settop(L, 3); 1.111 + lua_pushcclosure(L, seqlua_iteratoraux, 3); 1.112 + } 1.113 + } else { 1.114 + seqlua_iterclosure(L, 1); 1.115 + lua_settop(L, 1); 1.116 + } 1.117 + return 1; 1.118 +} 1.119 + 1.120 +int luaopen_seqlua(lua_State *L) { 1.121 + lua_pushcfunction(L, seqlua_ipairs); 1.122 + lua_setglobal(L, "ipairs"); 1.123 + lua_pushcfunction(L, seqlua_iterator); 1.124 + lua_setglobal(L, "iterator"); 1.125 + return 1; 1.126 +}