seqlua
view README @ 21:eb40d8ea7b9a
Undo previous commit (doesn't work more than once)
| author | jbe | 
|---|---|
| date | Wed Aug 20 12:57:53 2014 +0200 (2014-08-20) | 
| parents | 2fad7f50076b | 
| children | 50c6388d4963 | 
 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 ``__index`` and
    16 ``__call`` metamethods (this may cause unexpected behavior when passing
    17 callable tables to ``ipairs``). The ``__call`` metamethod takes precedence over
    18 an existing ``__index`` metamethod.
    22 Lua part of the library
    23 -----------------------
    25 The new ``ipairs(...)`` function works as follows:
    27     require "seqlua"
    29     t = {"a", "b", "c"}
    31     for i, v in ipairs(t) do
    32       print(i, v)
    33     end
    34     -- prints:
    35     --  1   a
    36     --  2   b
    37     --  3   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     f = alphabet("a", "z")
    55     for i, v in ipairs(f) do
    56       print(i, v)
    57     end
    58     -- prints:
    59     --  1   a
    60     --  2   b
    61     --  3   c
    62     --  ...
    63     --  25  y
    64     --  26  z
    66     set = {apple = true, banana = true}
    67     for i, k, v in ipairs(pairs(set)) do
    68       print(i, k, v)
    69     end
    70     -- prints:
    71     --  1   banana  true
    72     --  2   apple   true
    73     -- (order of "apple" and "banana" may vary)
    75 More examples for invoking the ``ipairs(...)`` function can be found in the
    76 file ``seqlua_ipairs_example.lua``.
    78 The function ``iterator(...)`` may be used to convert any table, any function,
    79 or any iterator triplet into a single function (possibly creating a closure):
    81     require "seqlua"
    83     function filter_strings(...)
    84       nextvalue = iterator(...)
    85       return function()
    86         local value
    87         repeat
    88           value = nextvalue()
    89         until value == nil or type(value) == "string"
    90         return value
    91       end
    92     end
    94     for i, v in ipairs(filter_strings{"Hello", true, "World"}) do
    95       print(i, v)
    96     end
    97     -- prints:
    98     --  1   Hello
    99     --  2   World
   101     tbl = {apple = true, banana = true, [1] = "array entry"}
   102     for v in filter_strings(pairs(tbl)) do
   103       print(v)
   104     end
   105     -- prints:
   106     --   banana
   107     --   apple
   108     -- (order may vary)
   112 C part of the library
   113 ---------------------
   115 In ``seqlualib.h``, the following macro is defined:
   117     #define seqlua_iterloop(L, iter, idx) \
   118       for ( \
   119         seqlua_iterinit((L), (iter), (idx)); \
   120         seqlua_iternext(iter); \
   121         lua_pop((L), 1) \
   122       )
   124 This macro allows iteration over either tables or iterator functions (but not
   125 iterator triplets) as the following example function demonstrates:
   127     int printcsv(lua_State *L) {
   128       seqlua_Iterator iter;
   129       seqlua_iterloop(L, &iter, 1) {
   130         if (seqlua_itercount(&iter) > 1) fputs(",", stdout);
   131         fputs(luaL_tolstring(L, -1, NULL), stdout);
   132         lua_pop(L, 1);  // pops value that luaL_tolstring pushed onto stack
   133       }
   134       fputs("\n", stdout);
   135       return 0;
   136     }
   138     printcsv{"a", "b", "c"}
   139     -- prints: a,b,c
   141     printcsv(assert(io.open("testfile")):lines())
   142     -- prints: line1,line2,... of "testfile"
   144 Additionally, ``seqlualib`` includes a function ``seqlua_iterclosure(L, idx)``,
   145 which converts a table at a given stack index into a function closure (stored
   146 on the same stack index) that iterates over the elements of the table. If the
   147 value at the given stack index is already a function (or if it is callable
   148 through a ``__call`` metamethod), then ``seqlua_iterclosure(L, idx)`` leaves
   149 the value at ``idx`` unchanged.
