seqlua

annotate README @ 6:7b05ca6ef925

Allow seqlua_iterinit to modify the value on stack instead of storing an extra element on stack
author jbe
date Wed Aug 20 01:52:35 2014 +0200 (2014-08-20)
parents e29e2d7b73a5
children 2cb22d01fdd0
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@0 6 * allow ipairs(...) to accept tables as well as functions or iterator triplets,
jbe@0 7 * provide a function iterator(...) that returns single functions unmodified,
jbe@0 8 but converts
jbe@0 9 * iterator triplets into closures, and
jbe@0 10 * tables into a function closure that iterates over the elements,
jbe@0 11 * provide the auxiliary C functions and macros to simplify iterating over both
jbe@0 12 tables and iterator functions with the same statement.
jbe@0 13
jbe@0 14 This library completely ignores the ``__ipairs`` metamethod (as it is
jbe@0 15 deprecated since Lua 5.3.0-alpha). It respects, however, any ``__call``
jbe@0 16 metamethods (this may cause unexpected behavior when passing callable tables
jbe@0 17 to ``ipairs``).
jbe@0 18
jbe@0 19
jbe@0 20
jbe@0 21 Lua part of the library
jbe@0 22 -----------------------
jbe@0 23
jbe@0 24 The new ``ipairs(...)`` function works as follows:
jbe@0 25
jbe@0 26 require "seqlua"
jbe@0 27
jbe@0 28 t = {"a", "b", "c"}
jbe@0 29
jbe@0 30 for i, v in ipairs(t) do
jbe@0 31 print(i, v)
jbe@0 32 end
jbe@0 33 -- prints:
jbe@0 34 -- 1 a
jbe@0 35 -- 2 b
jbe@0 36 -- 3 c
jbe@0 37
jbe@0 38 function alphabet()
jbe@0 39 local letter = nil
jbe@0 40 return function()
jbe@0 41 if letter == nil then
jbe@0 42 letter = "a"
jbe@0 43 elseif letter == "z" then
jbe@0 44 return nil
jbe@0 45 else
jbe@0 46 letter = string.char(string.byte(letter) + 1)
jbe@0 47 end
jbe@0 48 return letter
jbe@0 49 end
jbe@0 50 end
jbe@0 51
jbe@0 52 f = alphabet()
jbe@0 53
jbe@0 54 for i, v in ipairs(f) do
jbe@0 55 print(i, v)
jbe@0 56 end
jbe@0 57 -- prints:
jbe@0 58 -- 1 a
jbe@0 59 -- 2 b
jbe@0 60 -- 3 c
jbe@0 61 -- ...
jbe@0 62 -- 25 y
jbe@0 63 -- 26 z
jbe@0 64
jbe@0 65 set = {apple = true, banana = true}
jbe@0 66 for i, k, v in ipairs(pairs(set)) do
jbe@0 67 print(i, k, v)
jbe@0 68 end
jbe@0 69 -- prints:
jbe@0 70 -- 1 banana true
jbe@0 71 -- 2 apple true
jbe@0 72 -- (order of "apple" and "banana" may vary)
jbe@0 73
jbe@0 74 The function ``iterator(...)`` may be used to convert any table, any function,
jbe@0 75 or any iterator triplet into a single function (possibly creating a closure):
jbe@0 76
jbe@2 77 require "seqlua"
jbe@2 78
jbe@0 79 function filter_strings(...)
jbe@0 80 nextvalue = iterator(...)
jbe@0 81 return function()
jbe@0 82 local value
jbe@0 83 repeat
jbe@0 84 value = nextvalue()
jbe@0 85 until value == nil or type(value) == "string"
jbe@0 86 return value
jbe@0 87 end
jbe@0 88 end
jbe@0 89
jbe@0 90 for i, v in ipairs(filter_strings{"Hello", true, "World"}) do
jbe@0 91 print(i, v)
jbe@0 92 end
jbe@0 93 -- prints:
jbe@0 94 -- 1 Hello
jbe@0 95 -- 2 World
jbe@0 96
jbe@0 97 tbl = {apple = true, banana = true, [1] = "array entry"}
jbe@0 98 for v in filter_strings(pairs(tbl)) do
jbe@0 99 print(v)
jbe@0 100 end
jbe@0 101 -- prints:
jbe@0 102 -- banana
jbe@0 103 -- apple
jbe@0 104 -- (order may vary)
jbe@0 105
jbe@0 106
jbe@0 107
jbe@0 108 C part of the library
jbe@0 109 ---------------------
jbe@0 110
jbe@0 111 In ``seqlualib.h``, the following macro is defined:
jbe@0 112
jbe@0 113 #define seqlua_iterloop(L, iter, idx) \
jbe@0 114 for ( \
jbe@0 115 seqlua_iterinit((L), (iter), (idx)); \
jbe@0 116 seqlua_iternext(iter); \
jbe@0 117 lua_pop((L), 1) \
jbe@0 118 )
jbe@0 119
jbe@0 120 This macro allows iteration over either tables or iterator functions (but not
jbe@0 121 iterator triplets) as the following example function demonstrates:
jbe@0 122
jbe@0 123 int printcsv(lua_State *L) {
jbe@0 124 seqlua_Iterator iter;
jbe@0 125 seqlua_iterloop(L, &iter, 1) {
jbe@0 126 if (seqlua_itercount(&iter) > 1) fputs(",", stdout);
jbe@0 127 fputs(luaL_tolstring(L, -1, NULL), stdout);
jbe@1 128 lua_pop(L, 1); // pops value that luaL_tolstring pushed onto stack
jbe@0 129 }
jbe@0 130 fputs("\n", stdout);
jbe@0 131 return 0;
jbe@0 132 }
jbe@0 133
jbe@0 134 printcsv{"a", "b", "c"} -- prints: a,b,c
jbe@0 135
jbe@6 136 NOTE: If the index passed to ``seqlua_iterinit`` points to a value that has a
jbe@6 137 ``__call`` metamethod, then the value at the stack position will be replaced by
jbe@6 138 that metamethod.
jbe@3 139
jbe@0 140 Additionally, ``seqlualib`` includes a function ``seqlua_iterclosure(L, idx)``,
jbe@0 141 which converts a table at a given stack index into a function closure (stored
jbe@0 142 on the same stack index) that iterates over the elements of the table. If the
jbe@0 143 value at the given stack index is already a function, it leaves the value
jbe@4 144 unchanged. If the value is convertible to a function using ``__call,`` then the
jbe@5 145 value is replaced by its ``__call`` metamethod.
jbe@0 146
jbe@0 147

Impressum / About Us