seqlua

view seqlua.c @ 0:47f9b323d68c

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

Impressum / About Us