seqlua

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

Impressum / About Us