seqlua

view seqlualib.c @ 31:4fc9090ada1d

Mention 3 extra elements on stack in README; Changed order of two instructions in seqlualib.c
author jbe
date Sat Aug 23 23:35:10 2014 +0200 (2014-08-23)
parents 367fc70acc15
children 3ff7cec8d3ce
line source
1 #include <lua.h>
2 #include <lauxlib.h>
3 #include "seqlualib.h"
5 #define SEQLUA_ITERTYPE_IPAIRS 1
6 #define SEQLUA_ITERTYPE_CALL 2
7 #define SEQLUA_ITERTYPE_INDEX 3
8 #define SEQLUA_ITERTYPE_RAW 4
10 void seqlua_iterinit(lua_State *L, seqlua_Iterator *iter, int idx) {
11 if (luaL_getmetafield(L, idx, "__ipairs")) {
12 lua_pushvalue(L, idx);
13 lua_call(L, 1, 3);
14 iter->itertype = SEQLUA_ITERTYPE_IPAIRS;
15 } else {
16 if (lua_type(L, idx) == LUA_TFUNCTION) {
17 iter->itertype = SEQLUA_ITERTYPE_CALL;
18 } else if (
19 luaL_getmetafield(L, idx, "__index") ||
20 luaL_getmetafield(L, idx, "__len")
21 ) {
22 lua_pop(L, 1);
23 iter->len = luaL_len(L, idx);
24 iter->itertype = SEQLUA_ITERTYPE_INDEX;
25 } else {
26 luaL_checktype(L, idx, LUA_TTABLE);
27 iter->itertype = SEQLUA_ITERTYPE_RAW;
28 }
29 // always occupy 3 stack indicies
30 lua_pushnil(L);
31 lua_pushnil(L);
32 lua_pushnil(L);
33 iter->idx = idx;
34 }
35 iter->L = L;
36 iter->i = 0;
37 }
39 int seqlua_iternext(seqlua_Iterator *iter) {
40 lua_State *L = iter->L;
41 lua_Integer i = ++iter->i;
42 switch (iter->itertype) {
43 case SEQLUA_ITERTYPE_IPAIRS:
44 lua_pushvalue(L, -3);
45 lua_pushvalue(L, -3);
46 lua_pushvalue(L, -3);
47 lua_call(L, 2, 2);
48 if (lua_isnil(L, -2)) {
49 lua_pop(L, 5);
50 return 0;
51 }
52 lua_remove(L, -3);
53 return 1;
54 case SEQLUA_ITERTYPE_CALL:
55 lua_pushvalue(L, iter->idx);
56 lua_call(L, 0, 1);
57 break;
58 case SEQLUA_ITERTYPE_INDEX:
59 if (i > iter->len) {
60 lua_pop(L, 3);
61 return 0;
62 }
63 lua_pushinteger(L, i);
64 lua_gettable(L, iter->idx);
65 return 1;
66 case SEQLUA_ITERTYPE_RAW:
67 lua_rawgeti(L, iter->idx, i);
68 break;
69 }
70 if (lua_isnil(L, -1)) {
71 lua_pop(L, 4);
72 return 0;
73 }
74 return 1;
75 }

Impressum / About Us