seqlua
view README @ 19:2fad7f50076b
Added coroutine based filter(func, ...) example to new file seqlua_ipairs_example.lua
author | jbe |
---|---|
date | Wed Aug 20 12:23:31 2014 +0200 (2014-08-20) |
parents | 431fa6946a61 |
children | 50c6388d4963 |
line source
1 seqlua: Extended sequences and iterators in Lua
2 ===============================================
4 This is an experimental package to extend Lua in the following manner:
6 * allow ipairs(...) to accept tables as well as functions or iterator triplets,
7 * provide a function iterator(...) that returns single functions unmodified,
8 but converts
9 * iterator triplets into closures, and
10 * tables into a function closure that iterates over the elements,
11 * provide the auxiliary C functions and macros to simplify iterating over both
12 tables and iterator functions with the same statement.
14 This library completely ignores the ``__ipairs`` metamethod (as it is
15 deprecated since Lua 5.3.0-alpha). It respects, however, any ``__index`` and
16 ``__call`` metamethods (this may cause unexpected behavior when passing
17 callable tables to ``ipairs``). The ``__call`` metamethod takes precedence over
18 an existing ``__index`` metamethod.
22 Lua part of the library
23 -----------------------
25 The new ``ipairs(...)`` function works as follows:
27 require "seqlua"
29 t = {"a", "b", "c"}
31 for i, v in ipairs(t) do
32 print(i, v)
33 end
34 -- prints:
35 -- 1 a
36 -- 2 b
37 -- 3 c
39 function alphabet()
40 local letter = nil
41 return function()
42 if letter == nil then
43 letter = "a"
44 elseif letter == "z" then
45 return nil
46 else
47 letter = string.char(string.byte(letter) + 1)
48 end
49 return letter
50 end
51 end
53 f = alphabet("a", "z")
55 for i, v in ipairs(f) do
56 print(i, v)
57 end
58 -- prints:
59 -- 1 a
60 -- 2 b
61 -- 3 c
62 -- ...
63 -- 25 y
64 -- 26 z
66 set = {apple = true, banana = true}
67 for i, k, v in ipairs(pairs(set)) do
68 print(i, k, v)
69 end
70 -- prints:
71 -- 1 banana true
72 -- 2 apple true
73 -- (order of "apple" and "banana" may vary)
75 More examples for invoking the ``ipairs(...)`` function can be found in the
76 file ``seqlua_ipairs_example.lua``.
78 The function ``iterator(...)`` may be used to convert any table, any function,
79 or any iterator triplet into a single function (possibly creating a closure):
81 require "seqlua"
83 function filter_strings(...)
84 nextvalue = iterator(...)
85 return function()
86 local value
87 repeat
88 value = nextvalue()
89 until value == nil or type(value) == "string"
90 return value
91 end
92 end
94 for i, v in ipairs(filter_strings{"Hello", true, "World"}) do
95 print(i, v)
96 end
97 -- prints:
98 -- 1 Hello
99 -- 2 World
101 tbl = {apple = true, banana = true, [1] = "array entry"}
102 for v in filter_strings(pairs(tbl)) do
103 print(v)
104 end
105 -- prints:
106 -- banana
107 -- apple
108 -- (order may vary)
112 C part of the library
113 ---------------------
115 In ``seqlualib.h``, the following macro is defined:
117 #define seqlua_iterloop(L, iter, idx) \
118 for ( \
119 seqlua_iterinit((L), (iter), (idx)); \
120 seqlua_iternext(iter); \
121 lua_pop((L), 1) \
122 )
124 This macro allows iteration over either tables or iterator functions (but not
125 iterator triplets) as the following example function demonstrates:
127 int printcsv(lua_State *L) {
128 seqlua_Iterator iter;
129 seqlua_iterloop(L, &iter, 1) {
130 if (seqlua_itercount(&iter) > 1) fputs(",", stdout);
131 fputs(luaL_tolstring(L, -1, NULL), stdout);
132 lua_pop(L, 1); // pops value that luaL_tolstring pushed onto stack
133 }
134 fputs("\n", stdout);
135 return 0;
136 }
138 printcsv{"a", "b", "c"}
139 -- prints: a,b,c
141 printcsv(assert(io.open("testfile")):lines())
142 -- prints: line1,line2,... of "testfile"
144 Additionally, ``seqlualib`` includes a function ``seqlua_iterclosure(L, idx)``,
145 which converts a table at a given stack index into a function closure (stored
146 on the same stack index) that iterates over the elements of the table. If the
147 value at the given stack index is already a function (or if it is callable
148 through a ``__call`` metamethod), then ``seqlua_iterclosure(L, idx)`` leaves
149 the value at ``idx`` unchanged.