seqlua
view README @ 27:18292ffaf2ac
Modified examples for filter function in README
| author | jbe | 
|---|---|
| date | Fri Aug 22 12:20:58 2014 +0200 (2014-08-22) | 
| parents | 8ff86106e2fe | 
| children | 3287510a35e3 | 
 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)
    76       return function(seq)
    77         return coroutine.wrap(function()
    78           for i, v in ipairs(seq) do f(v) end
    79         end)
    80       end
    81     end
    83     number_to_trues = filter(function(v)
    84       local type_v = type(v)
    85       if type_v == "string" then
    86         coroutine.yield(v)
    87       elseif type_v == "number" then
    88         for i = 1, v do
    89           coroutine.yield(true)
    90         end
    91       end
    92     end)
    94     print((","):concat(number_to_trues{"a", "b", 3, "c"}))
    95     -- prints: a,b,true,true,true,c
    97     print((","):concat(number_to_trues(alphabet())))
    98     -- 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
   101 C part of the library
   102 ---------------------
   104 In ``seqlualib.h``, the following macro is defined:
   106     #define seqlua_iterloop(L, iter, idx) \
   107       for ( \
   108         seqlua_iterinit((L), (iter), (idx)); \
   109         seqlua_iternext(iter); \
   110       )
   112 and
   114     #define seqlua_iterloopauto(L, iter, idx) \
   115       for ( \
   116         seqlua_iterinit((L), (iter), (idx)); \
   117         seqlua_iternext(iter); \
   118         lua_pop((L), 1) \
   119       )
   121 This macro allows iteration over either tables or iterator functions as the
   122 following example function demonstrates:
   124     int printcsv(lua_State *L) {
   125       seqlua_Iterator iter;
   126       seqlua_iterloop(L, &iter, 1) {
   127         if (seqlua_itercount(&iter) > 1) fputs(",", stdout);
   128         fputs(luaL_tolstring(L, -1, NULL), stdout);
   129         // two values need to be popped (the value pushed by
   130         // seqlua_iternext and the value pushed by luaL_tolstring)
   131         lua_pop(L, 2);
   132       }
   133       fputs("\n", stdout);
   134       return 0;
   135     }
   137     printcsv{"a", "b", "c"}
   138     -- prints: a,b,c
   140     printcsv(assert(io.open("testfile")):lines())
   141     -- prints: line1,line2,... of "testfile"
