2 Copyright (c) 2006 Maurizio Monge <maurizio.monge@kdemail.net>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This file has been contributed by Rici Lake under the Lua license:
11 Copyright (c) 2006 Rici Lake
13 Permission is hereby granted, free of charge, to any person obtaining a copy
14 of this software and associated documentation files (the "Software"), to
15 deal in the Software without restriction, including without limitation the
16 rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
17 sell copies of the Software, and to permit persons to whom the Software is
18 furnished to do so, subject to the following conditions:
20 The above copyright notice and this permission notice shall be included in
21 all copies or substantial portions of the Software.
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
35 #include "luaapi/lfunclib.h"
37 /* "Constructors" (or collectors, if you prefer). Take an iterator
41 /* foreach just applies the self-function to each iteration tuple
42 * in turn. The return the result is the last return value
45 * func:foreach(<iter>) ==>
48 * for val... in <iter> do
49 * rv... = func(val...)
55 static int f_foreach (lua_State
*L
) {
58 int callbase
= lua_gettop(L
);
62 lua_call(L
, 2, LUA_MULTRET
);
63 if (lua_isnoneornil(L
, callbase
+ 1)) {
64 lua_settop(L
, callbase
);
67 lua_pushvalue(L
, callbase
+ 1);
68 lua_replace(L
, 4); /* ctl = newctl */
75 for (; callbase
> 5; --callbase
)
76 lua_remove(L
, callbase
);
78 lua_call(L
, lua_gettop(L
) - 5, LUA_MULTRET
);
82 /* first calls the self-function on each iteration tuple in turn,
83 * and returns the first true (not non-null) return of the self-function.
85 func:first(<iter>) ==>
86 for val... in <iter> do
87 local rv... = func(val...)
88 if (rv...) then return rv... end
92 1: self_func 2: iter_func 3: base 4: control
93 5: copy_self 6: returned control
96 static int f_first (lua_State
*L
) {
103 lua_call(L
, 2, LUA_MULTRET
);
104 if (lua_isnoneornil(L
, 6)) return 0;
107 lua_call(L
, lua_gettop(L
) - 5, LUA_MULTRET
);
108 if (lua_toboolean(L
, 5)) return lua_gettop(L
) - 5;
113 func:fold1(init, <iter>)
114 for val... in <iter> do
115 init = func(init, val...)
119 func:fold2(init, <iter>)
120 for val, rest... in <iter> do
121 init = func(init, rest...)
126 1: self_func 2: init val 3: iter_func 4: base 5: control
127 6: copy self 7: copy init 8: returned control
131 static int f_fold1 (lua_State
*L
) {
139 lua_call(L
, 2, LUA_MULTRET
);
140 if (lua_isnoneornil(L
, 8)) { lua_settop(L
, 7); return 1; }
143 lua_call(L
, lua_gettop(L
) - 6, 1);
149 static int f_fold2 (lua_State
*L
) {
157 lua_call(L
, 2, LUA_MULTRET
);
158 if (lua_isnoneornil(L
, 8)) { lua_settop(L
, 7); return 1; }
162 lua_call(L
, lua_gettop(L
) - 6, 1);
168 /* func:reduce{1,2}(default, <iter>) is like
169 * func:fold{1,2}(init, <iter>) except that the initial
170 * value is taken from the first iteration of the loop.
171 * If the loop fails to produce even one value, the default
172 * argument is returned. Otherwise, default is not used.
175 static int f_reduce1 (lua_State
*L
) {
181 if (lua_isnil(L
, -1)) { lua_settop(L
, 2); return 1; }
182 lua_pushvalue(L
, -1);
188 static int f_reduce2 (lua_State
*L
) {
194 if (lua_isnil(L
, -2)) { lua_settop(L
, 2); return 1; }
200 /* These ones could easily be implemented in terms of fold, but
201 * the direct implementation uses fewer temporary objects.
202 * Unlike the other stuff in this module, these are not
203 * function methods; they're just functions in the collect
208 * .keys => an array of the keys (or control variable, anyway)
209 * .vals => an array of the second iterator return
210 * .pairs => an table of (first) = (second)
211 * .keyset => a set of (first) = true
212 * .valset => a set of (second) = true
215 static int c_advance_aux (lua_State
*L
, int iter
, int nr
, int cb
) {
216 lua_settop(L
, cb
- 1);
217 lua_pushvalue(L
, iter
);
218 lua_pushvalue(L
, iter
+1);
219 lua_pushvalue(L
, iter
+2);
221 if (lua_isnoneornil(L
, cb
)) return 0;
222 lua_pushvalue(L
, cb
);
223 lua_replace(L
, iter
+2);
227 static int c_keys (lua_State
*L
) {
231 while (c_advance_aux(L
, 2, 1, 5))
232 lua_rawseti(L
, 1, ++index
);
237 static int c_vals (lua_State
*L
) {
241 while (c_advance_aux(L
, 2, 2, 5))
242 lua_rawseti(L
, 1, ++index
);
247 static int c_pairs (lua_State
*L
) {
250 while (c_advance_aux(L
, 2, 2, 5))
256 static int c_keyset (lua_State
*L
) {
259 while (c_advance_aux(L
, 2, 1, 5)) {
260 lua_pushboolean(L
, 1);
267 static int c_valset (lua_State
*L
) {
270 while (c_advance_aux(L
, 2, 2, 5)) {
271 lua_pushboolean(L
, 1);
279 /* func:dropping(i) -> function
280 * The returned function drops its ith argument (default 1) and
281 * returns the application of func to the remaining arguments.
282 * This is useful for removing keys from iterators in some of
283 * these iterator methods
286 static int f_dropping_aux (lua_State
*L
) {
287 int i
= lua_tointeger(L
, lua_upvalueindex(2));
288 int top
= lua_gettop(L
);
289 lua_pushvalue(L
, lua_upvalueindex(1));
291 if (i
<= top
) { lua_remove(L
, i
+ 1); --top
; }
292 lua_call(L
, top
, LUA_MULTRET
);
293 return lua_gettop(L
);
296 static int f_dropping (lua_State
*L
) {
299 if (lua_isnil(L
, 2)) {
300 lua_pushinteger(L
, 1);
304 luaL_checknumber(L
, 2);
306 lua_pushcclosure(L
, f_dropping_aux
, 2);
311 static int aux_nups (lua_State
*L
) {
313 lua_getstack(L
, 0, &ar
);
314 lua_getinfo(L
, "u", &ar
);
319 static int aux_insertupvalues (lua_State
*L
, int where
) {
321 int nups
= aux_nups(L
);
322 luaL_checkstack(L
, nups
, "insert upvalues");
324 for (i
= 1; i
<= nups
; ++i
, ++where
) {
325 lua_pushvalue(L
, lua_upvalueindex(i
));
326 lua_insert(L
, where
);
329 else if (where
< 0) {
331 for (i
= 1; i
<= nups
; ++i
) {
332 lua_pushvalue(L
, lua_upvalueindex(i
));
333 lua_insert(L
, where
);
337 for (i
= 1; i
<= nups
; ++i
)
338 lua_pushvalue(L
, lua_upvalueindex(i
));
343 /* func:partial(...) -> function
344 * The returned function is the original function with the given
345 * arguments "filled in" from the left.
348 static int f_partial_aux (lua_State
*L
) {
349 aux_insertupvalues(L
, 1);
350 lua_call(L
, lua_gettop(L
) - 1, LUA_MULTRET
);
351 return lua_gettop(L
);
354 static int f_partial (lua_State
*L
) {
355 int top
= lua_gettop(L
);
356 if (top
>= LUAI_MAXUPVALUES
) {
357 luaL_error(L
, "too many arguments, maximum is %d", LUAI_MAXUPVALUES
);
359 if (lua_tocfunction(L
, 1) == f_partial_aux
) {
361 /* We should find out how many there are, really. */
362 luaL_checkstack(L
, LUAI_MAXUPVALUES
, "partial combination");
363 for (; lua_getupvalue(L
, 1, i
); ++i
) {
364 lua_insert(L
, i
+ 1);
368 lua_pushcclosure(L
, f_partial_aux
, top
);
374 static int f_reorder_aux (lua_State
*L
) {
375 const char *format
= lua_tostring(L
, lua_upvalueindex(1));
376 int nups
= lua_tointeger(L
, lua_upvalueindex(2));
377 int top
= lua_gettop(L
);
378 lua_pushvalue(L
, lua_upvalueindex(3)); /* The function */
382 int base
= *format
++ - '0';
384 for (ch
= *format
; '0' <= ch
&& ch
<= '9'; ch
= *++format
)
385 base
= base
* 10 + ch
- '0';
387 while (*++format
== '.');
389 luaL_checkstack(L
, nups
- base
, "");
390 for (; base
<= nups
; ++base
)
391 lua_pushvalue(L
, lua_upvalueindex(base
+ 3));
394 else if (base
<= nups
)
395 lua_pushvalue(L
, lua_upvalueindex(base
));
401 /* duplicate above, but with top */
404 int func
= lua_gettop(L
);
406 /* get count or ... */
407 lua_call(L
, lua_gettop(L
) - func
, nups
);
414 return lua_gettop(L
) - top
;
422 /* Functions which take iterators and return iterators */
424 /* for vals... in f:map(<iter>) do <block> end
426 * for temp... in <iter> do
427 * local vals... = f(temp...)
432 static int f_map_aux (lua_State
*L
) {
434 lua_pushvalue(L
, lua_upvalueindex(1));
435 lua_pushvalue(L
, lua_upvalueindex(2));
436 lua_pushvalue(L
, lua_upvalueindex(3));
437 lua_pushvalue(L
, lua_upvalueindex(4));
438 lua_call(L
, 2, LUA_MULTRET
);
439 if (lua_isnoneornil(L
, 2)) return 0;
441 lua_replace(L
, lua_upvalueindex(4));
442 lua_call(L
, lua_gettop(L
) - 1, LUA_MULTRET
);
443 return lua_gettop(L
);
446 static int f_map (lua_State
*L
) {
448 lua_pushcclosure(L
, f_map_aux
, 4);
452 /* Possibly more useful.
453 * for k, vals... in f:mapvals(<iter>) do <block> end
455 * for k, temp... in <iter> do
456 * local vals... = f(temp...)
461 static int f_mapvals_aux (lua_State
*L
) {
462 lua_pushvalue(L
, lua_upvalueindex(2));
464 lua_call(L
, lua_gettop(L
) - 1, LUA_MULTRET
);
465 if (lua_isnoneornil(L
, 1)) return 0;
466 lua_pushvalue(L
, lua_upvalueindex(1));
468 lua_call(L
, lua_gettop(L
) - 2, LUA_MULTRET
);
469 return lua_gettop(L
);
472 /* Factor this out */
473 static int f_mapvals (lua_State
*L
) {
477 lua_pushcclosure(L
, f_mapvals_aux
, 2);
483 /* for vals... in f:filter(<iter>) do <block> end
485 * for vals... in <iter> do
492 static int f_filter_aux (lua_State
*L
) {
498 lua_pushvalue(L
, lua_upvalueindex(2));
499 lua_replace(L
, 2); /* Obj IterFunc Obj Ctl */
500 lua_call(L
, 2, LUA_MULTRET
);
502 if (top
== 1 || lua_isnil(L
, 2)) return 0;
503 luaL_checkstack(L
, top
, "filtered iterator returned too many results");
504 lua_pushvalue(L
, lua_upvalueindex(1));
505 for (i
= 2; i
<= top
; ++i
) lua_pushvalue(L
, i
);
506 lua_call(L
, top
- 1, 1);
507 } while (!lua_toboolean(L
, -1));
512 static int f_filter (lua_State
*L
) {
516 lua_pushcclosure(L
, f_filter_aux
, 2);
523 * pcall, coroutine.wrap -> both are appropriate function methods
524 * possibly some introspection stuff
525 * something like the new python with modifier: i.e. safely do a call
526 * with a prelude and postlude.
529 static const luaL_reg func_funcs
[] = {
530 { "first", f_first
},
531 { "foreach", f_foreach
},
532 { "fold1", f_fold1
},
533 { "fold2", f_fold2
},
534 { "reduce1", f_reduce1
},
535 { "reduce2", f_reduce2
},
536 { "dropping", f_dropping
},
537 { "partial", f_partial
},
539 { "mapvals", f_mapvals
},
540 { "filter", f_filter
},
544 static const luaL_reg collect_funcs
[] = {
547 { "pairs", c_pairs
},
548 { "keyset", c_keyset
},
549 { "valset", c_valset
},
553 int luaopen_func (lua_State
*L
) {
554 luaL_register(L
, LUA_FUNCLIBNAME
, func_funcs
);
555 lua_pushcfunction(L
, luaopen_func
); /* A function */
556 if (!lua_getmetatable(L
, -1)) {
557 lua_createtable(L
, 0, 0);
558 lua_pushvalue(L
, -3);
559 lua_setfield(L
, -2, "__index");
560 lua_setmetatable(L
, -2);
567 int luaopen_collect (lua_State
*L
) {
568 luaL_register(L
, LUA_COLLECTLIBNAME
, collect_funcs
);