seqlua

annotate 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
rev   line source
jbe@0 1 seqlua: Extended sequences and iterators in Lua
jbe@0 2 ===============================================
jbe@0 3
jbe@0 4 This is an experimental package to extend Lua in the following manner:
jbe@0 5
jbe@25 6 * allow ``ipairs(seq)`` to accept tables as well as functions,
jbe@25 7 * add a new function ``string.concat(separator, seq)`` to concat either table
jbe@25 8 entries or function return values,
jbe@23 9 * provide auxiliary C functions and macros to simplify iterating over both
jbe@0 10 tables and iterator functions with the same statement.
jbe@0 11
jbe@25 12 In other words:
jbe@25 13 When calling ``ipairs(seq)`` or ``string.concat(separator, seq)``,
jbe@25 14 then ``seq`` may either be a (table) sequence or a (function) iterator.
jbe@25 15 Auxiliary C functions and macros are provided to simplify extending your own
jbe@25 16 C functions in the same manner.
jbe@25 17
jbe@0 18 This library completely ignores the ``__ipairs`` metamethod (as it is
jbe@18 19 deprecated since Lua 5.3.0-alpha). It respects, however, any ``__index`` and
jbe@18 20 ``__call`` metamethods (this may cause unexpected behavior when passing
jbe@18 21 callable tables to ``ipairs``). The ``__call`` metamethod takes precedence over
jbe@18 22 an existing ``__index`` metamethod.
jbe@0 23
jbe@0 24
jbe@0 25
jbe@0 26 Lua part of the library
jbe@0 27 -----------------------
jbe@0 28
jbe@25 29 The modified ``ipairs(seq)`` function and the new ``string.concat`` function
jbe@25 30 work as demonstrated in the following examples:
jbe@0 31
jbe@0 32 require "seqlua"
jbe@0 33
jbe@0 34 t = {"a", "b", "c"}
jbe@0 35
jbe@0 36 for i, v in ipairs(t) do
jbe@0 37 print(i, v)
jbe@0 38 end
jbe@0 39 -- prints:
jbe@0 40 -- 1 a
jbe@0 41 -- 2 b
jbe@0 42 -- 3 c
jbe@0 43
jbe@25 44 print(string.concat(",", t))
jbe@25 45 -- prints: a,b,c
jbe@25 46
jbe@19 47 function alphabet()
jbe@0 48 local letter = nil
jbe@0 49 return function()
jbe@0 50 if letter == nil then
jbe@19 51 letter = "a"
jbe@19 52 elseif letter == "z" then
jbe@0 53 return nil
jbe@0 54 else
jbe@0 55 letter = string.char(string.byte(letter) + 1)
jbe@0 56 end
jbe@0 57 return letter
jbe@0 58 end
jbe@0 59 end
jbe@0 60
jbe@23 61 for i, v in ipairs(alphabet()) do
jbe@0 62 print(i, v)
jbe@0 63 end
jbe@0 64 -- prints:
jbe@0 65 -- 1 a
jbe@0 66 -- 2 b
jbe@0 67 -- 3 c
jbe@0 68 -- ...
jbe@0 69 -- 25 y
jbe@0 70 -- 26 z
jbe@0 71
jbe@25 72 print(string.concat(",", alphabet()))
jbe@25 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
jbe@25 74
jbe@23 75 function filter(f, seq)
jbe@23 76 return coroutine.wrap(function()
jbe@23 77 for i, v in ipairs(seq) do f(v) end
jbe@23 78 end)
jbe@0 79 end
jbe@19 80
jbe@23 81 function filterfunc(v)
jbe@23 82 local type_v = type(v)
jbe@23 83 if type_v == "string" then
jbe@23 84 coroutine.yield(v)
jbe@23 85 elseif type_v == "number" then
jbe@23 86 for i = 1, v do
jbe@23 87 coroutine.yield(true)
jbe@23 88 end
jbe@0 89 end
jbe@0 90 end
jbe@0 91
jbe@23 92 for v in filter(filterfunc, {"a", "b", 3, "c"}) do
jbe@0 93 print(v)
jbe@0 94 end
jbe@0 95 -- prints:
jbe@23 96 -- a
jbe@23 97 -- b
jbe@23 98 -- true
jbe@23 99 -- true
jbe@23 100 -- true
jbe@23 101 -- c
jbe@0 102
jbe@25 103 print((","):concat(filter(filterfunc, {"a", "b", 3, "c"})))
jbe@25 104 -- prints: a,b,true,true,true,c
jbe@25 105
jbe@0 106
jbe@0 107 C part of the library
jbe@0 108 ---------------------
jbe@0 109
jbe@0 110 In ``seqlualib.h``, the following macro is defined:
jbe@0 111
jbe@0 112 #define seqlua_iterloop(L, iter, idx) \
jbe@0 113 for ( \
jbe@0 114 seqlua_iterinit((L), (iter), (idx)); \
jbe@0 115 seqlua_iternext(iter); \
jbe@25 116 )
jbe@25 117
jbe@25 118 and
jbe@25 119
jbe@25 120 #define seqlua_iterloopauto(L, iter, idx) \
jbe@25 121 for ( \
jbe@25 122 seqlua_iterinit((L), (iter), (idx)); \
jbe@25 123 seqlua_iternext(iter); \
jbe@0 124 lua_pop((L), 1) \
jbe@0 125 )
jbe@0 126
jbe@23 127 This macro allows iteration over either tables or iterator functions as the
jbe@23 128 following example function demonstrates:
jbe@0 129
jbe@0 130 int printcsv(lua_State *L) {
jbe@0 131 seqlua_Iterator iter;
jbe@0 132 seqlua_iterloop(L, &iter, 1) {
jbe@0 133 if (seqlua_itercount(&iter) > 1) fputs(",", stdout);
jbe@0 134 fputs(luaL_tolstring(L, -1, NULL), stdout);
jbe@25 135 // two values need to be popped (the value pushed by
jbe@25 136 // seqlua_iternext and the value pushed by luaL_tolstring)
jbe@25 137 lua_pop(L, 2);
jbe@0 138 }
jbe@0 139 fputs("\n", stdout);
jbe@0 140 return 0;
jbe@0 141 }
jbe@0 142
jbe@11 143 printcsv{"a", "b", "c"}
jbe@11 144 -- prints: a,b,c
jbe@11 145
jbe@11 146 printcsv(assert(io.open("testfile")):lines())
jbe@11 147 -- prints: line1,line2,... of "testfile"
jbe@0 148
jbe@0 149

Impressum / About Us