seqlua
view README @ 31:4fc9090ada1d
Mention 3 extra elements on stack in README; Changed order of two instructions in seqlualib.c
| author | jbe | 
|---|---|
| date | Sat Aug 23 23:35:10 2014 +0200 (2014-08-23) | 
| parents | 367fc70acc15 | 
| children | 3ff7cec8d3ce | 
 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 (i.e function
     7   iterators),
     8 * add a new function ``string.concat(separator, seq)`` to concat either table
     9   entries or function return values,
    10 * provide auxiliary C functions and macros to simplify iterating over both
    11   tables and iterator functions with the same statement.
    13 In all cases, existing ``__index``, ``__len``, or ``__ipairs`` metamethods are
    14 respected. The ``__ipairs`` metamethod takes precedence.
    17 Lua part of the library
    18 -----------------------
    20 The modified ``ipairs(seq)`` and the new ``string.concat(sep, seq)`` functions
    21 accept either a table or a function as ``seq``. This is demonstrated in the
    22 following examples:
    24     require "seqlua"
    26     t = {"a", "b", "c"}
    28     for i, v in ipairs(t) do
    29       print(i, v)
    30     end
    31     -- prints:
    32     --  1   a
    33     --  2   b
    34     --  3   c
    36     print(string.concat(",", t))
    37     -- prints: a,b,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     for i, v in ipairs(alphabet()) do
    54       print(i, v)
    55     end
    56     -- prints:
    57     --  1   a
    58     --  2   b
    59     --  3   c
    60     --  ...
    61     --  25  y
    62     --  26  z
    64     print(string.concat(",", alphabet()))
    65     -- 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
    67     function filter(f)
    68       return function(seq)
    69         return coroutine.wrap(function()
    70           for i, v in ipairs(seq) do f(v) end
    71         end)
    72       end
    73     end
    75     alpha_beta_x = filter(function(v)
    76       if v == "a" then
    77         coroutine.yield("alpha")
    78       elseif v == "b" then
    79         coroutine.yield("beta")
    80       elseif type(v) == "number" then
    81         for i = 1, v do
    82           coroutine.yield("X")
    83         end
    84       end
    85     end)
    87     print((","):concat(alpha_beta_x{"a", 3, "b", "c", "d"}))
    88     -- prints: alpha,X,X,X,beta
    90     print((","):concat(alpha_beta_x(alphabet())))
    91     -- prints: alpha,beta
    94 C part of the library
    95 ---------------------
    97 In ``seqlualib.h``, the following macro is defined:
    99     #define seqlua_iterloop(L, iter, idx) \
   100       for ( \
   101         seqlua_iterinit((L), (iter), (idx)); \
   102         seqlua_iternext(iter); \
   103       )
   105 and
   107     #define seqlua_iterloopauto(L, iter, idx) \
   108       for ( \
   109         seqlua_iterinit((L), (iter), (idx)); \
   110         seqlua_iternext(iter); \
   111         lua_pop((L), 1) \
   112       )
   114 This macro allows iteration over either tables or iterator functions as the
   115 following example function demonstrates:
   117     int printcsv(lua_State *L) {
   118       seqlua_Iterator iter;
   119       seqlua_iterloop(L, &iter, 1) {
   120         if (seqlua_itercount(&iter) > 1) fputs(",", stdout);
   121         fputs(luaL_tolstring(L, -1, NULL), stdout);
   122         // two values need to be popped (the value pushed by
   123         // seqlua_iternext and the value pushed by luaL_tolstring)
   124         lua_pop(L, 2);
   125       }
   126       fputs("\n", stdout);
   127       return 0;
   128     }
   130     printcsv{"a", "b", "c"}
   131     -- prints: a,b,c
   133     printcsv(assert(io.open("testfile")):lines())
   134     -- prints: line1,line2,... of "testfile"
   136 NOTE: During iteration using ``seqlua_iterloop``, ``seqlua_iterloopauto``, or
   137 ``seqlua_iterinit``, three extra elements are stored on the stack (additionally
   138 to the value). These extra elements are removed automatically when the loop ends
   139 (i.e. when ``seqlua_iternext`` returns zero). The value pushed onto the stack
   140 for every iteration step has to be removed manually from the stack, unless
   141 ``seqlua_iterloopauto`` is used.
