seqlua

view README @ 25:44880bcfc323

Macro seqlua_iterloop doesn't automatically pop the value anymore (use seqlua_iterloopauto instead); New function string.concat(sep, seq) introduced
author jbe
date Thu Aug 21 21:32:01 2014 +0200 (2014-08-21)
parents 29792283522f
children 8ff86106e2fe
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(seq)`` to accept tables as well as functions,
7 * add a new function ``string.concat(separator, seq)`` to concat either table
8 entries or function return values,
9 * provide auxiliary C functions and macros to simplify iterating over both
10 tables and iterator functions with the same statement.
12 In other words:
13 When calling ``ipairs(seq)`` or ``string.concat(separator, seq)``,
14 then ``seq`` may either be a (table) sequence or a (function) iterator.
15 Auxiliary C functions and macros are provided to simplify extending your own
16 C functions in the same manner.
18 This library completely ignores the ``__ipairs`` metamethod (as it is
19 deprecated since Lua 5.3.0-alpha). It respects, however, any ``__index`` and
20 ``__call`` metamethods (this may cause unexpected behavior when passing
21 callable tables to ``ipairs``). The ``__call`` metamethod takes precedence over
22 an existing ``__index`` metamethod.
26 Lua part of the library
27 -----------------------
29 The modified ``ipairs(seq)`` function and the new ``string.concat`` function
30 work as demonstrated in the following examples:
32 require "seqlua"
34 t = {"a", "b", "c"}
36 for i, v in ipairs(t) do
37 print(i, v)
38 end
39 -- prints:
40 -- 1 a
41 -- 2 b
42 -- 3 c
44 print(string.concat(",", t))
45 -- prints: a,b,c
47 function alphabet()
48 local letter = nil
49 return function()
50 if letter == nil then
51 letter = "a"
52 elseif letter == "z" then
53 return nil
54 else
55 letter = string.char(string.byte(letter) + 1)
56 end
57 return letter
58 end
59 end
61 for i, v in ipairs(alphabet()) do
62 print(i, v)
63 end
64 -- prints:
65 -- 1 a
66 -- 2 b
67 -- 3 c
68 -- ...
69 -- 25 y
70 -- 26 z
72 print(string.concat(",", alphabet()))
73 -- prints: a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z
75 function filter(f, seq)
76 return coroutine.wrap(function()
77 for i, v in ipairs(seq) do f(v) end
78 end)
79 end
81 function filterfunc(v)
82 local type_v = type(v)
83 if type_v == "string" then
84 coroutine.yield(v)
85 elseif type_v == "number" then
86 for i = 1, v do
87 coroutine.yield(true)
88 end
89 end
90 end
92 for v in filter(filterfunc, {"a", "b", 3, "c"}) do
93 print(v)
94 end
95 -- prints:
96 -- a
97 -- b
98 -- true
99 -- true
100 -- true
101 -- c
103 print((","):concat(filter(filterfunc, {"a", "b", 3, "c"})))
104 -- prints: a,b,true,true,true,c
107 C part of the library
108 ---------------------
110 In ``seqlualib.h``, the following macro is defined:
112 #define seqlua_iterloop(L, iter, idx) \
113 for ( \
114 seqlua_iterinit((L), (iter), (idx)); \
115 seqlua_iternext(iter); \
116 )
118 and
120 #define seqlua_iterloopauto(L, iter, idx) \
121 for ( \
122 seqlua_iterinit((L), (iter), (idx)); \
123 seqlua_iternext(iter); \
124 lua_pop((L), 1) \
125 )
127 This macro allows iteration over either tables or iterator functions as the
128 following example function demonstrates:
130 int printcsv(lua_State *L) {
131 seqlua_Iterator iter;
132 seqlua_iterloop(L, &iter, 1) {
133 if (seqlua_itercount(&iter) > 1) fputs(",", stdout);
134 fputs(luaL_tolstring(L, -1, NULL), stdout);
135 // two values need to be popped (the value pushed by
136 // seqlua_iternext and the value pushed by luaL_tolstring)
137 lua_pop(L, 2);
138 }
139 fputs("\n", stdout);
140 return 0;
141 }
143 printcsv{"a", "b", "c"}
144 -- prints: a,b,c
146 printcsv(assert(io.open("testfile")):lines())
147 -- prints: line1,line2,... of "testfile"

Impressum / About Us