jbe@0: #include jbe@0: #include jbe@25: #include "seqlualib.h" jbe@8: jbe@0: static int seqlua_ipairsaux_raw(lua_State *L) { jbe@0: lua_Integer i; jbe@0: luaL_checktype(L, 1, LUA_TTABLE); jbe@0: i = luaL_checkinteger(L, 2) + 1; jbe@0: lua_pushinteger(L, i); jbe@0: lua_rawgeti(L, 1, i); // TODO: Lua 5.3 returns type jbe@0: return lua_isnil(L, -1) ? 1 : 2; jbe@0: } jbe@0: jbe@0: static int seqlua_ipairsaux_meta(lua_State *L) { jbe@0: lua_Integer i; jbe@0: i = luaL_checkinteger(L, 2) + 1; jbe@0: lua_pushinteger(L, i); jbe@0: lua_pushinteger(L, i); jbe@0: lua_gettable(L, 1); // TODO: Lua 5.3 returns type jbe@0: return lua_isnil(L, -1) ? 1 : 2; jbe@0: } jbe@0: jbe@0: static int seqlua_ipairsaux_func(lua_State *L) { jbe@0: lua_pushinteger(L, luaL_checkinteger(L, 2) + 1); jbe@0: lua_insert(L, 1); jbe@0: lua_settop(L, 2); jbe@0: lua_call(L, 0, LUA_MULTRET); jbe@0: if (lua_isnoneornil(L, 2)) { jbe@0: lua_settop(L, 0); jbe@0: lua_pushnil(L); jbe@0: return 1; jbe@0: } else { jbe@0: return lua_gettop(L); jbe@0: } jbe@0: } jbe@0: jbe@0: static int seqlua_ipairs(lua_State *L) { jbe@8: luaL_checkany(L, 1); // provides better error message jbe@23: if ( jbe@23: lua_type(L, 1) == LUA_TFUNCTION || jbe@23: (luaL_getmetafield(L, 1, "__call") && (lua_pop(L, 1), 1)) jbe@23: ) { jbe@0: lua_pushcfunction(L, seqlua_ipairsaux_func); jbe@0: } else if (luaL_getmetafield(L, 1, "__index")) { jbe@0: lua_pushcfunction(L, seqlua_ipairsaux_meta); jbe@0: } else { jbe@0: luaL_checktype(L, 1, LUA_TTABLE); jbe@0: lua_pushcfunction(L, seqlua_ipairsaux_raw); jbe@0: } jbe@0: lua_pushvalue(L, 1); jbe@0: lua_pushinteger(L, 0); jbe@0: return 3; jbe@0: } jbe@0: jbe@25: static int seqlua_concat(lua_State *L) { jbe@25: const char *sep; jbe@25: size_t seplen; jbe@25: luaL_Buffer buf; jbe@25: seqlua_Iterator iter; jbe@25: sep = luaL_checklstring(L, 1, &seplen); jbe@25: luaL_checkany(L, 2); jbe@25: lua_settop(L, 3); jbe@25: luaL_buffinit(L, &buf); jbe@25: seqlua_iterloop(L, &iter, 2) { jbe@25: lua_replace(L, 3); jbe@25: if (seqlua_itercount(&iter) > 1) luaL_addlstring(&buf, sep, seplen); jbe@25: luaL_tolstring(L, 3, NULL); jbe@25: luaL_addvalue(&buf); jbe@25: } jbe@25: luaL_pushresult(&buf); jbe@25: return 1; jbe@25: } jbe@25: jbe@0: int luaopen_seqlua(lua_State *L) { jbe@0: lua_pushcfunction(L, seqlua_ipairs); jbe@0: lua_setglobal(L, "ipairs"); jbe@25: lua_getglobal(L, "string"); jbe@25: lua_pushcfunction(L, seqlua_concat); jbe@25: lua_setfield(L, -2, "concat"); jbe@25: return 0; jbe@0: }