jbe@0: #include jbe@0: #include jbe@0: #include "seqlualib.h" jbe@0: jbe@15: #define SEQLUA_ITERTYPE_FUNC 1 jbe@15: #define SEQLUA_ITERTYPE_META 2 jbe@15: #define SEQLUA_ITERTYPE_RAW 3 jbe@0: jbe@0: void seqlua_iterinit(lua_State *L, seqlua_Iterator *iter, int idx) { jbe@0: luaL_checkany(L, idx); // provides better error message jbe@0: iter->L = L; jbe@15: iter->idx = idx; jbe@23: if ( jbe@23: lua_type(L, idx) == LUA_TFUNCTION || jbe@23: (luaL_getmetafield(L, idx, "__call") && (lua_pop(L, 1), 1)) jbe@23: ) { jbe@0: iter->itertype = SEQLUA_ITERTYPE_FUNC; jbe@23: } else if (luaL_getmetafield(L, idx, "__index") && (lua_pop(L, 1), 1)) { jbe@15: iter->itertype = SEQLUA_ITERTYPE_META; jbe@0: } else { jbe@15: luaL_checktype(L, idx, LUA_TTABLE); jbe@15: iter->itertype = SEQLUA_ITERTYPE_RAW; jbe@0: } jbe@0: iter->i = 0; jbe@0: } jbe@0: jbe@0: int seqlua_iternext(seqlua_Iterator *iter) { jbe@0: lua_State *L = iter->L; jbe@0: lua_Integer i = ++iter->i; jbe@0: switch (iter->itertype) { jbe@0: case SEQLUA_ITERTYPE_FUNC: jbe@8: lua_pushvalue(L, iter->idx); jbe@0: lua_call(L, 0, 1); jbe@0: break; jbe@0: case SEQLUA_ITERTYPE_META: jbe@0: lua_pushinteger(L, i); jbe@8: lua_gettable(L, iter->idx); jbe@0: break; jbe@0: case SEQLUA_ITERTYPE_RAW: jbe@8: lua_rawgeti(L, iter->idx, i); jbe@8: break; jbe@0: } jbe@0: if (lua_isnil(L, -1)) { jbe@15: lua_pop(L, 1); jbe@0: return 0; jbe@0: } jbe@0: return 1; jbe@0: } jbe@0: