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@15
|
5 #define SEQLUA_ITERTYPE_FUNC 1
|
jbe@15
|
6 #define SEQLUA_ITERTYPE_META 2
|
jbe@15
|
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@15
|
12 iter->idx = idx;
|
jbe@23
|
13 if (
|
jbe@23
|
14 lua_type(L, idx) == LUA_TFUNCTION ||
|
jbe@23
|
15 (luaL_getmetafield(L, idx, "__call") && (lua_pop(L, 1), 1))
|
jbe@23
|
16 ) {
|
jbe@0
|
17 iter->itertype = SEQLUA_ITERTYPE_FUNC;
|
jbe@23
|
18 } else if (luaL_getmetafield(L, idx, "__index") && (lua_pop(L, 1), 1)) {
|
jbe@15
|
19 iter->itertype = SEQLUA_ITERTYPE_META;
|
jbe@0
|
20 } else {
|
jbe@15
|
21 luaL_checktype(L, idx, LUA_TTABLE);
|
jbe@15
|
22 iter->itertype = SEQLUA_ITERTYPE_RAW;
|
jbe@0
|
23 }
|
jbe@0
|
24 iter->i = 0;
|
jbe@0
|
25 }
|
jbe@0
|
26
|
jbe@0
|
27 int seqlua_iternext(seqlua_Iterator *iter) {
|
jbe@0
|
28 lua_State *L = iter->L;
|
jbe@0
|
29 lua_Integer i = ++iter->i;
|
jbe@0
|
30 switch (iter->itertype) {
|
jbe@0
|
31 case SEQLUA_ITERTYPE_FUNC:
|
jbe@8
|
32 lua_pushvalue(L, iter->idx);
|
jbe@0
|
33 lua_call(L, 0, 1);
|
jbe@0
|
34 break;
|
jbe@0
|
35 case SEQLUA_ITERTYPE_META:
|
jbe@0
|
36 lua_pushinteger(L, i);
|
jbe@8
|
37 lua_gettable(L, iter->idx);
|
jbe@0
|
38 break;
|
jbe@0
|
39 case SEQLUA_ITERTYPE_RAW:
|
jbe@8
|
40 lua_rawgeti(L, iter->idx, i);
|
jbe@8
|
41 break;
|
jbe@0
|
42 }
|
jbe@0
|
43 if (lua_isnil(L, -1)) {
|
jbe@15
|
44 lua_pop(L, 1);
|
jbe@0
|
45 return 0;
|
jbe@0
|
46 }
|
jbe@0
|
47 return 1;
|
jbe@0
|
48 }
|
jbe@0
|
49
|