seqlua
diff README @ 0:47f9b323d68c
Initial commit
author | jbe |
---|---|
date | Wed Aug 20 00:39:10 2014 +0200 (2014-08-20) |
parents | |
children | 158dfce546c0 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/README Wed Aug 20 00:39:10 2014 +0200 1.3 @@ -0,0 +1,141 @@ 1.4 +seqlua: Extended sequences and iterators in Lua 1.5 +=============================================== 1.6 + 1.7 +This is an experimental package to extend Lua in the following manner: 1.8 + 1.9 +* allow ipairs(...) to accept tables as well as functions or iterator triplets, 1.10 +* provide a function iterator(...) that returns single functions unmodified, 1.11 + but converts 1.12 + * iterator triplets into closures, and 1.13 + * tables into a function closure that iterates over the elements, 1.14 +* provide the auxiliary C functions and macros to simplify iterating over both 1.15 + tables and iterator functions with the same statement. 1.16 + 1.17 +This library completely ignores the ``__ipairs`` metamethod (as it is 1.18 +deprecated since Lua 5.3.0-alpha). It respects, however, any ``__call`` 1.19 +metamethods (this may cause unexpected behavior when passing callable tables 1.20 +to ``ipairs``). 1.21 + 1.22 + 1.23 + 1.24 +Lua part of the library 1.25 +----------------------- 1.26 + 1.27 +The new ``ipairs(...)`` function works as follows: 1.28 + 1.29 + require "seqlua" 1.30 + 1.31 + t = {"a", "b", "c"} 1.32 + 1.33 + for i, v in ipairs(t) do 1.34 + print(i, v) 1.35 + end 1.36 + -- prints: 1.37 + -- 1 a 1.38 + -- 2 b 1.39 + -- 3 c 1.40 + 1.41 + function alphabet() 1.42 + local letter = nil 1.43 + return function() 1.44 + if letter == nil then 1.45 + letter = "a" 1.46 + elseif letter == "z" then 1.47 + return nil 1.48 + else 1.49 + letter = string.char(string.byte(letter) + 1) 1.50 + end 1.51 + return letter 1.52 + end 1.53 + end 1.54 + 1.55 + f = alphabet() 1.56 + 1.57 + for i, v in ipairs(f) do 1.58 + print(i, v) 1.59 + end 1.60 + -- prints: 1.61 + -- 1 a 1.62 + -- 2 b 1.63 + -- 3 c 1.64 + -- ... 1.65 + -- 25 y 1.66 + -- 26 z 1.67 + 1.68 + set = {apple = true, banana = true} 1.69 + for i, k, v in ipairs(pairs(set)) do 1.70 + print(i, k, v) 1.71 + end 1.72 + -- prints: 1.73 + -- 1 banana true 1.74 + -- 2 apple true 1.75 + -- (order of "apple" and "banana" may vary) 1.76 + 1.77 +The function ``iterator(...)`` may be used to convert any table, any function, 1.78 +or any iterator triplet into a single function (possibly creating a closure): 1.79 + 1.80 + function filter_strings(...) 1.81 + nextvalue = iterator(...) 1.82 + return function() 1.83 + local value 1.84 + repeat 1.85 + value = nextvalue() 1.86 + until value == nil or type(value) == "string" 1.87 + return value 1.88 + end 1.89 + end 1.90 + 1.91 + for i, v in ipairs(filter_strings{"Hello", true, "World"}) do 1.92 + print(i, v) 1.93 + end 1.94 + -- prints: 1.95 + -- 1 Hello 1.96 + -- 2 World 1.97 + 1.98 + tbl = {apple = true, banana = true, [1] = "array entry"} 1.99 + for v in filter_strings(pairs(tbl)) do 1.100 + print(v) 1.101 + end 1.102 + -- prints: 1.103 + -- banana 1.104 + -- apple 1.105 + -- (order may vary) 1.106 + 1.107 + 1.108 + 1.109 +C part of the library 1.110 +--------------------- 1.111 + 1.112 +In ``seqlualib.h``, the following macro is defined: 1.113 + 1.114 + #define seqlua_iterloop(L, iter, idx) \ 1.115 + for ( \ 1.116 + seqlua_iterinit((L), (iter), (idx)); \ 1.117 + seqlua_iternext(iter); \ 1.118 + lua_pop((L), 1) \ 1.119 + ) 1.120 + 1.121 +This macro allows iteration over either tables or iterator functions (but not 1.122 +iterator triplets) as the following example function demonstrates: 1.123 + 1.124 + int printcsv(lua_State *L) { 1.125 + seqlua_Iterator iter; 1.126 + seqlua_iterloop(L, &iter, 1) { 1.127 + if (seqlua_itercount(&iter) > 1) fputs(",", stdout); 1.128 + fputs(luaL_tolstring(L, -1, NULL), stdout); 1.129 + lua_pop(L, 1); 1.130 + } 1.131 + fputs("\n", stdout); 1.132 + return 0; 1.133 + } 1.134 + 1.135 + printcsv{"a", "b", "c"} -- prints: a,b,c 1.136 + 1.137 +Additionally, ``seqlualib`` includes a function ``seqlua_iterclosure(L, idx)``, 1.138 +which converts a table at a given stack index into a function closure (stored 1.139 +on the same stack index) that iterates over the elements of the table. If the 1.140 +value at the given stack index is already a function, it leaves the value 1.141 +unchanged. If the value is convertible to a function using ``__ipairs,`` then 1.142 +the function is replaced by its ``__ipairs`` metamethod. 1.143 + 1.144 +