seqlua

view seqlua.c @ 15:a95fbd16473f

Removed unnecessary creation of closures for callable values (through __call)
author jbe
date Wed Aug 20 06:33:18 2014 +0200 (2014-08-20)
parents 03ed3361f332
children 040a0ca089c1
line source
1 #include <lua.h>
2 #include <lauxlib.h>
4 static int seqlua_ipairsaux_raw(lua_State *L) {
5 lua_Integer i;
6 luaL_checktype(L, 1, LUA_TTABLE);
7 i = luaL_checkinteger(L, 2) + 1;
8 lua_pushinteger(L, i);
9 lua_rawgeti(L, 1, i); // TODO: Lua 5.3 returns type
10 return lua_isnil(L, -1) ? 1 : 2;
11 }
13 static int seqlua_ipairsaux_meta(lua_State *L) {
14 lua_Integer i;
15 i = luaL_checkinteger(L, 2) + 1;
16 lua_pushinteger(L, i);
17 lua_pushinteger(L, i);
18 lua_gettable(L, 1); // TODO: Lua 5.3 returns type
19 return lua_isnil(L, -1) ? 1 : 2;
20 }
22 static int seqlua_ipairsaux_func(lua_State *L) {
23 //luaL_checktype(L, 1, LUA_TFUNCTION);
24 lua_pushinteger(L, luaL_checkinteger(L, 2) + 1);
25 lua_insert(L, 1);
26 lua_settop(L, 2);
27 lua_call(L, 0, LUA_MULTRET);
28 if (lua_isnoneornil(L, 2)) {
29 lua_settop(L, 0);
30 lua_pushnil(L);
31 return 1;
32 } else {
33 return lua_gettop(L);
34 }
35 }
37 static int seqlua_ipairsaux_triplet(lua_State *L) {
38 lua_Integer i = lua_tointeger(L, lua_upvalueindex(4)) + 1;
39 lua_settop(L, 0);
40 lua_pushinteger(L, i);
41 lua_replace(L, lua_upvalueindex(4));
42 lua_pushinteger(L, i);
43 lua_pushvalue(L, lua_upvalueindex(1));
44 lua_pushvalue(L, lua_upvalueindex(2));
45 lua_pushvalue(L, lua_upvalueindex(3));
46 lua_call(L, 2, LUA_MULTRET);
47 if (lua_isnoneornil(L, 2)) {
48 lua_settop(L, 0);
49 lua_pushnil(L);
50 return 1;
51 } else {
52 lua_pushvalue(L, 2);
53 lua_replace(L, lua_upvalueindex(3));
54 return lua_gettop(L);
55 }
56 }
58 static int seqlua_ipairs(lua_State *L) {
59 luaL_checkany(L, 1); // provides better error message
60 if (lua_type(L, 1) == LUA_TFUNCTION) {
61 seqlua_ipairs_function:
62 if (!lua_isnoneornil(L, 2) || !lua_isnoneornil(L, 3)) {
63 lua_settop(L, 3);
64 lua_pushinteger(L, 0);
65 lua_pushcclosure(L, seqlua_ipairsaux_triplet, 4);
66 return 1;
67 }
68 lua_pushcfunction(L, seqlua_ipairsaux_func);
69 } else if (luaL_getmetafield(L, 1, "__call")) {
70 lua_pop(L, 1);
71 goto seqlua_ipairs_function;
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_raw(lua_State *L) {
84 lua_Integer i = lua_tointeger(L, lua_upvalueindex(2)) + 1;
85 lua_rawgeti(L, lua_upvalueindex(1), i);
86 if (lua_isnil(L, -1)) return 1;
87 lua_pushinteger(L, i);
88 lua_replace(L, lua_upvalueindex(2));
89 return 1;
90 }
92 static int seqlua_iteratoraux_meta(lua_State *L) {
93 lua_Integer i = lua_tointeger(L, lua_upvalueindex(2)) + 1;
94 lua_pushinteger(L, i);
95 lua_gettable(L, lua_upvalueindex(1));
96 if (lua_isnil(L, -1)) return 1;
97 lua_pushinteger(L, i);
98 lua_replace(L, lua_upvalueindex(2));
99 return 1;
100 }
102 static int seqlua_iteratoraux_triplet(lua_State *L) {
103 lua_settop(L, 0);
104 lua_pushvalue(L, lua_upvalueindex(1));
105 lua_pushvalue(L, lua_upvalueindex(2));
106 lua_pushvalue(L, lua_upvalueindex(3));
107 lua_call(L, 2, LUA_MULTRET);
108 if (lua_isnoneornil(L, 1)) {
109 lua_settop(L, 1);
110 return 1;
111 }
112 lua_pushvalue(L, 1);
113 lua_replace(L, lua_upvalueindex(3));
114 return lua_gettop(L);
115 }
117 int seqlua_iterator(lua_State *L) {
118 luaL_checkany(L, 1); // provides better error message
119 lua_settop(L, 3);
120 if (lua_type(L, 1) == LUA_TFUNCTION) {
121 seqlua_iterator_function:
122 if (lua_isnil(L, 2) && lua_isnil(L, 3)) {
123 lua_settop(L, 1);
124 } else {
125 lua_pushcclosure(L, seqlua_iteratoraux_triplet, 3);
126 }
127 } else if (luaL_getmetafield(L, 1, "__call")) {
128 lua_pop(L, 1);
129 goto seqlua_iterator_function;
130 } else if (luaL_getmetafield(L, 1, "__index")) {
131 lua_pushvalue(L, 1);
132 lua_pushinteger(L, 0);
133 lua_pushcclosure(L, seqlua_iteratoraux_raw, 2);
134 } else {
135 luaL_checktype(L, 1, LUA_TTABLE);
136 lua_pushvalue(L, 1);
137 lua_pushinteger(L, 0);
138 lua_pushcclosure(L, seqlua_iteratoraux_meta, 2);
139 }
140 return 1;
141 }
143 int luaopen_seqlua(lua_State *L) {
144 lua_pushcfunction(L, seqlua_ipairs);
145 lua_setglobal(L, "ipairs");
146 lua_pushcfunction(L, seqlua_iterator);
147 lua_setglobal(L, "iterator");
148 return 1;
149 }

Impressum / About Us