seqlua

view README @ 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 2ef6eb7d17d2
children 431fa6946a61
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 ``__call``
16 metamethods (this may cause unexpected behavior when passing callable tables
17 to ``ipairs``).
21 Lua part of the library
22 -----------------------
24 The new ``ipairs(...)`` function works as follows:
26 require "seqlua"
28 t = {"a", "b", "c"}
30 for i, v in ipairs(t) do
31 print(i, v)
32 end
33 -- prints:
34 -- 1 a
35 -- 2 b
36 -- 3 c
38 function alphabet(from, to)
39 local letter = nil
40 return function()
41 if letter == nil then
42 letter = from
43 elseif letter == to then
44 return nil
45 else
46 letter = string.char(string.byte(letter) + 1)
47 end
48 return letter
49 end
50 end
52 f = alphabet("a", "z")
54 for i, v in ipairs(f) do
55 print(i, v)
56 end
57 -- prints:
58 -- 1 a
59 -- 2 b
60 -- 3 c
61 -- ...
62 -- 25 y
63 -- 26 z
65 c = setmetatable(
66 { iter = alphabet("a", "f") },
67 { __call = function(t) return t.iter() end }
68 )
70 for i, v in ipairs(c) do
71 print(i, v)
72 end
73 -- prints:
74 -- 1 a
75 -- 2 b
76 -- 3 c
77 -- 4 d
78 -- 5 e
79 -- 6 f
81 g = coroutine.wrap(function()
82 coroutine.yield("Alice")
83 coroutine.yield("Bob")
84 for i = 1, 3 do
85 coroutine.yield("Person #" .. tostring(i))
86 end
87 end)
89 for i, v in ipairs(g) do
90 print(i, v)
91 end
92 -- prints:
93 -- 1 Alice
94 -- 2 Bob
95 -- 3 Person #1
96 -- 4 Person #2
97 -- 5 Person #3
99 set = {apple = true, banana = true}
100 for i, k, v in ipairs(pairs(set)) do
101 print(i, k, v)
102 end
103 -- prints:
104 -- 1 banana true
105 -- 2 apple true
106 -- (order of "apple" and "banana" may vary)
108 The function ``iterator(...)`` may be used to convert any table, any function,
109 or any iterator triplet into a single function (possibly creating a closure):
111 require "seqlua"
113 function filter_strings(...)
114 nextvalue = iterator(...)
115 return function()
116 local value
117 repeat
118 value = nextvalue()
119 until value == nil or type(value) == "string"
120 return value
121 end
122 end
124 for i, v in ipairs(filter_strings{"Hello", true, "World"}) do
125 print(i, v)
126 end
127 -- prints:
128 -- 1 Hello
129 -- 2 World
131 tbl = {apple = true, banana = true, [1] = "array entry"}
132 for v in filter_strings(pairs(tbl)) do
133 print(v)
134 end
135 -- prints:
136 -- banana
137 -- apple
138 -- (order may vary)
142 C part of the library
143 ---------------------
145 In ``seqlualib.h``, the following macro is defined:
147 #define seqlua_iterloop(L, iter, idx) \
148 for ( \
149 seqlua_iterinit((L), (iter), (idx)); \
150 seqlua_iternext(iter); \
151 lua_pop((L), 1) \
152 )
154 This macro allows iteration over either tables or iterator functions (but not
155 iterator triplets) as the following example function demonstrates:
157 int printcsv(lua_State *L) {
158 seqlua_Iterator iter;
159 seqlua_iterloop(L, &iter, 1) {
160 if (seqlua_itercount(&iter) > 1) fputs(",", stdout);
161 fputs(luaL_tolstring(L, -1, NULL), stdout);
162 lua_pop(L, 1); // pops value that luaL_tolstring pushed onto stack
163 }
164 fputs("\n", stdout);
165 return 0;
166 }
168 printcsv{"a", "b", "c"}
169 -- prints: a,b,c
171 printcsv(assert(io.open("testfile")):lines())
172 -- prints: line1,line2,... of "testfile"
174 Additionally, ``seqlualib`` includes a function ``seqlua_iterclosure(L, idx)``,
175 which converts a table at a given stack index into a function closure (stored
176 on the same stack index) that iterates over the elements of the table. If the
177 value at the given stack index is already a function (or if it is callable
178 through a ``__call`` metamethod), then ``seqlua_iterclosure(L, idx)`` leaves
179 the value at ``idx`` unchanged.

Impressum / About Us