seqlua

annotate README @ 23:29792283522f

Removed iterator(...) function; ipairs doesn't accept iterator triplets anymore
author jbe
date Thu Aug 21 20:01:52 2014 +0200 (2014-08-21)
parents 50c6388d4963
children 44880bcfc323
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@23 6 * allow ipairs(...) to accept tables as well as functions
jbe@23 7 * provide auxiliary C functions and macros to simplify iterating over both
jbe@0 8 tables and iterator functions with the same statement.
jbe@0 9
jbe@0 10 This library completely ignores the ``__ipairs`` metamethod (as it is
jbe@18 11 deprecated since Lua 5.3.0-alpha). It respects, however, any ``__index`` and
jbe@18 12 ``__call`` metamethods (this may cause unexpected behavior when passing
jbe@18 13 callable tables to ``ipairs``). The ``__call`` metamethod takes precedence over
jbe@18 14 an existing ``__index`` metamethod.
jbe@0 15
jbe@0 16
jbe@0 17
jbe@0 18 Lua part of the library
jbe@0 19 -----------------------
jbe@0 20
jbe@0 21 The new ``ipairs(...)`` function works as follows:
jbe@0 22
jbe@0 23 require "seqlua"
jbe@0 24
jbe@0 25 t = {"a", "b", "c"}
jbe@0 26
jbe@0 27 for i, v in ipairs(t) do
jbe@0 28 print(i, v)
jbe@0 29 end
jbe@0 30 -- prints:
jbe@0 31 -- 1 a
jbe@0 32 -- 2 b
jbe@0 33 -- 3 c
jbe@0 34
jbe@19 35 function alphabet()
jbe@0 36 local letter = nil
jbe@0 37 return function()
jbe@0 38 if letter == nil then
jbe@19 39 letter = "a"
jbe@19 40 elseif letter == "z" then
jbe@0 41 return nil
jbe@0 42 else
jbe@0 43 letter = string.char(string.byte(letter) + 1)
jbe@0 44 end
jbe@0 45 return letter
jbe@0 46 end
jbe@0 47 end
jbe@0 48
jbe@23 49 for i, v in ipairs(alphabet()) do
jbe@0 50 print(i, v)
jbe@0 51 end
jbe@0 52 -- prints:
jbe@0 53 -- 1 a
jbe@0 54 -- 2 b
jbe@0 55 -- 3 c
jbe@0 56 -- ...
jbe@0 57 -- 25 y
jbe@0 58 -- 26 z
jbe@0 59
jbe@23 60 function filter(f, seq)
jbe@23 61 return coroutine.wrap(function()
jbe@23 62 for i, v in ipairs(seq) do f(v) end
jbe@23 63 end)
jbe@0 64 end
jbe@19 65
jbe@23 66 function filterfunc(v)
jbe@23 67 local type_v = type(v)
jbe@23 68 if type_v == "string" then
jbe@23 69 coroutine.yield(v)
jbe@23 70 elseif type_v == "number" then
jbe@23 71 for i = 1, v do
jbe@23 72 coroutine.yield(true)
jbe@23 73 end
jbe@0 74 end
jbe@0 75 end
jbe@0 76
jbe@23 77 for v in filter(filterfunc, {"a", "b", 3, "c"}) do
jbe@0 78 print(v)
jbe@0 79 end
jbe@0 80 -- prints:
jbe@23 81 -- a
jbe@23 82 -- b
jbe@23 83 -- true
jbe@23 84 -- true
jbe@23 85 -- true
jbe@23 86 -- c
jbe@0 87
jbe@0 88
jbe@0 89 C part of the library
jbe@0 90 ---------------------
jbe@0 91
jbe@0 92 In ``seqlualib.h``, the following macro is defined:
jbe@0 93
jbe@0 94 #define seqlua_iterloop(L, iter, idx) \
jbe@0 95 for ( \
jbe@0 96 seqlua_iterinit((L), (iter), (idx)); \
jbe@0 97 seqlua_iternext(iter); \
jbe@0 98 lua_pop((L), 1) \
jbe@0 99 )
jbe@0 100
jbe@23 101 This macro allows iteration over either tables or iterator functions as the
jbe@23 102 following example function demonstrates:
jbe@0 103
jbe@0 104 int printcsv(lua_State *L) {
jbe@0 105 seqlua_Iterator iter;
jbe@0 106 seqlua_iterloop(L, &iter, 1) {
jbe@0 107 if (seqlua_itercount(&iter) > 1) fputs(",", stdout);
jbe@0 108 fputs(luaL_tolstring(L, -1, NULL), stdout);
jbe@1 109 lua_pop(L, 1); // pops value that luaL_tolstring pushed onto stack
jbe@0 110 }
jbe@0 111 fputs("\n", stdout);
jbe@0 112 return 0;
jbe@0 113 }
jbe@0 114
jbe@11 115 printcsv{"a", "b", "c"}
jbe@11 116 -- prints: a,b,c
jbe@11 117
jbe@11 118 printcsv(assert(io.open("testfile")):lines())
jbe@11 119 -- prints: line1,line2,... of "testfile"
jbe@0 120
jbe@0 121

Impressum / About Us