seqlua

annotate seqlualib.c @ 7:2cb22d01fdd0

Reverted last commit and added TODO for first argument to __call
author jbe
date Wed Aug 20 01:59:55 2014 +0200 (2014-08-20)
parents 7b05ca6ef925
children 144f0bddee2b
rev   line source
jbe@0 1 #include <lua.h>
jbe@0 2 #include <lauxlib.h>
jbe@0 3 #include "seqlualib.h"
jbe@0 4
jbe@0 5 #define SEQLUA_ITERTYPE_FUNC 1
jbe@0 6 #define SEQLUA_ITERTYPE_META 2
jbe@0 7 #define SEQLUA_ITERTYPE_RAW 3
jbe@0 8
jbe@0 9 void seqlua_iterinit(lua_State *L, seqlua_Iterator *iter, int idx) {
jbe@0 10 luaL_checkany(L, idx); // provides better error message
jbe@0 11 iter->L = L;
jbe@0 12 if (luaL_getmetafield(L, idx, "__call")) {
jbe@0 13 if (lua_type(L, -1) != LUA_TFUNCTION) luaL_error(L, "__call is not a function");
jbe@0 14 iter->itertype = SEQLUA_ITERTYPE_FUNC;
jbe@0 15 } else if (lua_type(L, idx) == LUA_TFUNCTION) {
jbe@7 16 lua_pushvalue(L, idx);
jbe@0 17 iter->itertype = SEQLUA_ITERTYPE_FUNC;
jbe@0 18 } else {
jbe@0 19 if (luaL_getmetafield(L, idx, "__index")) {
jbe@0 20 lua_pop(L, 1);
jbe@0 21 iter->itertype = SEQLUA_ITERTYPE_META;
jbe@0 22 } else {
jbe@0 23 luaL_checktype(L, idx, LUA_TTABLE);
jbe@0 24 iter->itertype = SEQLUA_ITERTYPE_RAW;
jbe@0 25 }
jbe@7 26 lua_pushvalue(L, idx);
jbe@0 27 }
jbe@0 28 iter->i = 0;
jbe@0 29 }
jbe@0 30
jbe@0 31 int seqlua_iternext(seqlua_Iterator *iter) {
jbe@0 32 lua_State *L = iter->L;
jbe@0 33 lua_Integer i = ++iter->i;
jbe@0 34 switch (iter->itertype) {
jbe@0 35 case SEQLUA_ITERTYPE_FUNC:
jbe@0 36 lua_pushvalue(L, -1);
jbe@0 37 lua_call(L, 0, 1);
jbe@0 38 break;
jbe@0 39 case SEQLUA_ITERTYPE_META:
jbe@0 40 lua_pushinteger(L, i);
jbe@0 41 lua_gettable(L, -2);
jbe@0 42 break;
jbe@0 43 case SEQLUA_ITERTYPE_RAW:
jbe@0 44 lua_rawgeti(L, -1, i);
jbe@0 45 }
jbe@0 46 if (lua_isnil(L, -1)) {
jbe@7 47 lua_pop(L, 2);
jbe@0 48 return 0;
jbe@0 49 }
jbe@0 50 return 1;
jbe@0 51 }
jbe@0 52
jbe@0 53 static int seqlua_iterclosureaux_raw(lua_State *L) {
jbe@0 54 lua_Integer i = lua_tointeger(L, lua_upvalueindex(2)) + 1;
jbe@0 55 lua_rawgeti(L, lua_upvalueindex(1), i);
jbe@0 56 if (lua_isnil(L, -1)) return 1;
jbe@0 57 lua_pushinteger(L, i);
jbe@0 58 lua_replace(L, lua_upvalueindex(2));
jbe@0 59 return 1;
jbe@0 60 }
jbe@0 61
jbe@0 62 static int seqlua_iterclosureaux_meta(lua_State *L) {
jbe@0 63 lua_Integer i = lua_tointeger(L, lua_upvalueindex(2)) + 1;
jbe@0 64 lua_pushinteger(L, i);
jbe@0 65 lua_gettable(L, lua_upvalueindex(1));
jbe@0 66 if (lua_isnil(L, -1)) return 1;
jbe@0 67 lua_pushinteger(L, i);
jbe@0 68 lua_replace(L, lua_upvalueindex(2));
jbe@0 69 return 1;
jbe@0 70 }
jbe@0 71
jbe@0 72 void seqlua_iterclosure(lua_State *L, int idx) {
jbe@0 73 if (lua_type(L, idx) == LUA_TFUNCTION) {
jbe@0 74 // do nothing
jbe@0 75 } else if (luaL_getmetafield(L, idx, "__call")) {
jbe@0 76 if (lua_type(L, -1) != LUA_TFUNCTION) luaL_error(L, "__call is not a function");
jbe@0 77 lua_replace(L, idx);
jbe@0 78 } else if (luaL_getmetafield(L, idx, "__index")) {
jbe@0 79 lua_pop(L, 1);
jbe@0 80 lua_pushvalue(L, idx);
jbe@0 81 lua_pushinteger(L, 0);
jbe@0 82 lua_pushcclosure(L, seqlua_iterclosureaux_raw, 2);
jbe@0 83 lua_replace(L, idx);
jbe@0 84 } else {
jbe@0 85 luaL_checktype(L, idx, LUA_TTABLE);
jbe@0 86 lua_pushvalue(L, idx);
jbe@0 87 lua_pushinteger(L, 0);
jbe@0 88 lua_pushcclosure(L, seqlua_iterclosureaux_meta, 2);
jbe@0 89 lua_replace(L, idx);
jbe@0 90 }
jbe@0 91 }
jbe@0 92

Impressum / About Us