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 static int seqlua_ipairsaux_raw(lua_State *L) {
|
jbe@0
|
6 lua_Integer i;
|
jbe@0
|
7 luaL_checktype(L, 1, LUA_TTABLE);
|
jbe@0
|
8 i = luaL_checkinteger(L, 2) + 1;
|
jbe@0
|
9 lua_pushinteger(L, i);
|
jbe@0
|
10 lua_rawgeti(L, 1, i); // TODO: Lua 5.3 returns type
|
jbe@0
|
11 return lua_isnil(L, -1) ? 1 : 2;
|
jbe@0
|
12 }
|
jbe@0
|
13
|
jbe@0
|
14 static int seqlua_ipairsaux_meta(lua_State *L) {
|
jbe@0
|
15 lua_Integer i;
|
jbe@0
|
16 i = luaL_checkinteger(L, 2) + 1;
|
jbe@0
|
17 lua_pushinteger(L, i);
|
jbe@0
|
18 lua_pushinteger(L, i);
|
jbe@0
|
19 lua_gettable(L, 1); // TODO: Lua 5.3 returns type
|
jbe@0
|
20 return lua_isnil(L, -1) ? 1 : 2;
|
jbe@0
|
21 }
|
jbe@0
|
22
|
jbe@0
|
23 static int seqlua_ipairsaux_func(lua_State *L) {
|
jbe@0
|
24 luaL_checktype(L, 1, LUA_TFUNCTION);
|
jbe@0
|
25 lua_pushinteger(L, luaL_checkinteger(L, 2) + 1);
|
jbe@0
|
26 lua_insert(L, 1);
|
jbe@0
|
27 lua_settop(L, 2);
|
jbe@0
|
28 lua_call(L, 0, LUA_MULTRET);
|
jbe@0
|
29 if (lua_isnoneornil(L, 2)) {
|
jbe@0
|
30 lua_settop(L, 0);
|
jbe@0
|
31 lua_pushnil(L);
|
jbe@0
|
32 return 1;
|
jbe@0
|
33 } else {
|
jbe@0
|
34 return lua_gettop(L);
|
jbe@0
|
35 }
|
jbe@0
|
36 }
|
jbe@0
|
37
|
jbe@0
|
38 static int seqlua_ipairsaux_funcclosure(lua_State *L) {
|
jbe@0
|
39 lua_Integer i = lua_tointeger(L, lua_upvalueindex(4)) + 1;
|
jbe@0
|
40 lua_settop(L, 0);
|
jbe@0
|
41 lua_pushinteger(L, i);
|
jbe@0
|
42 lua_replace(L, lua_upvalueindex(4));
|
jbe@0
|
43 lua_pushinteger(L, i);
|
jbe@0
|
44 lua_pushvalue(L, lua_upvalueindex(1));
|
jbe@0
|
45 lua_pushvalue(L, lua_upvalueindex(2));
|
jbe@0
|
46 lua_pushvalue(L, lua_upvalueindex(3));
|
jbe@0
|
47 lua_call(L, 2, LUA_MULTRET);
|
jbe@0
|
48 if (lua_isnoneornil(L, 2)) {
|
jbe@0
|
49 lua_settop(L, 0);
|
jbe@0
|
50 lua_pushnil(L);
|
jbe@0
|
51 return 1;
|
jbe@0
|
52 } else {
|
jbe@0
|
53 lua_pushvalue(L, 2);
|
jbe@0
|
54 lua_replace(L, lua_upvalueindex(3));
|
jbe@0
|
55 return lua_gettop(L);
|
jbe@0
|
56 }
|
jbe@0
|
57 }
|
jbe@0
|
58
|
jbe@0
|
59 static int seqlua_ipairs(lua_State *L) {
|
jbe@0
|
60 if (luaL_getmetafield(L, 1, "__call")) {
|
jbe@0
|
61 if (lua_type(L, -1) != LUA_TFUNCTION) luaL_error(L, "__call is not a function");
|
jbe@0
|
62 lua_replace(L, 1);
|
jbe@0
|
63 }
|
jbe@0
|
64 if (lua_type(L, 1) == LUA_TFUNCTION) {
|
jbe@0
|
65 if (!lua_isnoneornil(L, 2) || !lua_isnoneornil(L, 3)) {
|
jbe@0
|
66 lua_settop(L, 3);
|
jbe@0
|
67 lua_pushinteger(L, 0);
|
jbe@0
|
68 lua_pushcclosure(L, seqlua_ipairsaux_funcclosure, 4);
|
jbe@0
|
69 return 1;
|
jbe@0
|
70 }
|
jbe@0
|
71 lua_pushcfunction(L, seqlua_ipairsaux_func);
|
jbe@0
|
72 } else if (luaL_getmetafield(L, 1, "__index")) {
|
jbe@0
|
73 lua_pushcfunction(L, seqlua_ipairsaux_meta);
|
jbe@0
|
74 } else {
|
jbe@0
|
75 luaL_checktype(L, 1, LUA_TTABLE);
|
jbe@0
|
76 lua_pushcfunction(L, seqlua_ipairsaux_raw);
|
jbe@0
|
77 }
|
jbe@0
|
78 lua_pushvalue(L, 1);
|
jbe@0
|
79 lua_pushinteger(L, 0);
|
jbe@0
|
80 return 3;
|
jbe@0
|
81 }
|
jbe@0
|
82
|
jbe@0
|
83 static int seqlua_iteratoraux(lua_State *L) {
|
jbe@0
|
84 lua_settop(L, 0);
|
jbe@0
|
85 lua_pushvalue(L, lua_upvalueindex(1));
|
jbe@0
|
86 lua_pushvalue(L, lua_upvalueindex(2));
|
jbe@0
|
87 lua_pushvalue(L, lua_upvalueindex(3));
|
jbe@0
|
88 lua_call(L, 2, LUA_MULTRET);
|
jbe@0
|
89 if (lua_isnoneornil(L, 1)) {
|
jbe@0
|
90 lua_settop(L, 1);
|
jbe@0
|
91 return 1;
|
jbe@0
|
92 }
|
jbe@0
|
93 lua_pushvalue(L, 1);
|
jbe@0
|
94 lua_replace(L, lua_upvalueindex(3));
|
jbe@0
|
95 return lua_gettop(L);
|
jbe@0
|
96 }
|
jbe@0
|
97
|
jbe@0
|
98 static int seqlua_iterator(lua_State *L) {
|
jbe@0
|
99 if (luaL_getmetafield(L, 1, "__call")) {
|
jbe@0
|
100 if (lua_type(L, -1) != LUA_TFUNCTION) luaL_error(L, "__call is not a function");
|
jbe@0
|
101 lua_replace(L, 1);
|
jbe@0
|
102 }
|
jbe@0
|
103 if (lua_type(L, 1) == LUA_TFUNCTION) {
|
jbe@0
|
104 if (lua_isnoneornil(L, 2) && lua_isnoneornil(L, 3)) {
|
jbe@0
|
105 lua_settop(L, 1);
|
jbe@0
|
106 } else {
|
jbe@0
|
107 lua_settop(L, 3);
|
jbe@0
|
108 lua_pushcclosure(L, seqlua_iteratoraux, 3);
|
jbe@0
|
109 }
|
jbe@0
|
110 } else {
|
jbe@0
|
111 seqlua_iterclosure(L, 1);
|
jbe@0
|
112 lua_settop(L, 1);
|
jbe@0
|
113 }
|
jbe@0
|
114 return 1;
|
jbe@0
|
115 }
|
jbe@0
|
116
|
jbe@0
|
117 int luaopen_seqlua(lua_State *L) {
|
jbe@0
|
118 lua_pushcfunction(L, seqlua_ipairs);
|
jbe@0
|
119 lua_setglobal(L, "ipairs");
|
jbe@0
|
120 lua_pushcfunction(L, seqlua_iterator);
|
jbe@0
|
121 lua_setglobal(L, "iterator");
|
jbe@0
|
122 return 1;
|
jbe@0
|
123 }
|