seqlua

view seqlualib.c @ 57:da4b9d6a5b7e

Fixed bug due to problem combining luaL_buffinit with seqlua_iterinit
author jbe
date Tue Jan 05 04:26:49 2016 +0100 (2016-01-05)
parents 92ce3958aca7
children
line source
1 #include <lua.h>
2 #include <lauxlib.h>
3 #include "seqlualib.h"
4 #include <string.h>
6 #define SEQLUA_ITERTYPE_IPAIRS 1
7 #define SEQLUA_ITERTYPE_CALL 2
8 #define SEQLUA_ITERTYPE_INDEX 3
9 #define SEQLUA_ITERTYPE_RAW 4
11 // TODO: allow combining luaL_buffinit with seqlua_iterinit somehow
13 void seqlua_iterinit(lua_State *L, seqlua_Iterator *iter, int idx) {
14 if (luaL_getmetafield(L, idx, "__ipairs")) {
15 lua_pushvalue(L, idx);
16 lua_call(L, 1, 3);
17 if (lua_type(L, -3) == LUA_TSTRING) {
18 const char *method = lua_tostring(L, -3);
19 if (!strcmp(method, "raw")) {
20 iter->itertype = SEQLUA_ITERTYPE_RAW;
21 } else if (!strcmp(method, "index")) {
22 iter->itertype = SEQLUA_ITERTYPE_INDEX;
23 } else if (!strcmp(method, "call")) {
24 iter->itertype = SEQLUA_ITERTYPE_CALL;
25 } else {
26 luaL_error(L, "Unexpected string returned by __ipairs metamethod");
27 }
28 iter->idx = lua_gettop(L) - 1;
29 } else {
30 iter->itertype = SEQLUA_ITERTYPE_IPAIRS;
31 }
32 } else {
33 if (lua_type(L, idx) == LUA_TFUNCTION) {
34 iter->itertype = SEQLUA_ITERTYPE_CALL;
35 } else if (luaL_getmetafield(L, idx, "__index")) {
36 lua_pop(L, 1);
37 iter->itertype = SEQLUA_ITERTYPE_INDEX;
38 } else {
39 luaL_checktype(L, idx, LUA_TTABLE);
40 iter->itertype = SEQLUA_ITERTYPE_RAW;
41 }
42 // always occupy 3 stack indicies
43 lua_pushnil(L);
44 lua_pushnil(L);
45 lua_pushnil(L);
46 iter->idx = idx;
47 }
48 iter->L = L;
49 iter->i = 0;
50 }
52 int seqlua_iternext(seqlua_Iterator *iter) {
53 lua_State *L = iter->L;
54 lua_Integer i = ++iter->i;
55 switch (iter->itertype) {
56 case SEQLUA_ITERTYPE_IPAIRS:
57 lua_pushvalue(L, -3);
58 lua_pushvalue(L, -3);
59 lua_pushvalue(L, -3);
60 lua_call(L, 2, 2);
61 if (lua_isnil(L, -2)) {
62 lua_pop(L, 5);
63 return 0;
64 }
65 lua_remove(L, -3);
66 return 1;
67 case SEQLUA_ITERTYPE_CALL:
68 lua_pushvalue(L, iter->idx);
69 lua_call(L, 0, 1);
70 break;
71 case SEQLUA_ITERTYPE_INDEX:
72 lua_pushinteger(L, i);
73 lua_gettable(L, iter->idx);
74 break;
75 case SEQLUA_ITERTYPE_RAW:
76 lua_rawgeti(L, iter->idx, i);
77 break;
78 }
79 if (lua_isnil(L, -1)) {
80 lua_pop(L, 4);
81 return 0;
82 }
83 return 1;
84 }

Impressum / About Us