[ create a new paste ] login | about

Link: http://codepad.org/eQP2e87S    [ raw code | output | fork ]

Lua, pasted on Mar 24:
pack = function (...) return { n = select('#', ...), ... } end

-- used to retrieve args from a continuation
local dummy = function (...) return ... end

local continuation_pack =
    function (...)
        local args = table.pack(...)

        return function (f) return f(unpack(args)) end
    end

local continuation_thread =
    function (...)
        local c =
            coroutine.create(
                function (...)
                    -- args have been added
                    local f = coroutine.yield()

                    while true do
                        f = coroutine.yield(f(...))
                    end
                end
            )

        -- "init" the vararg
        coroutine.resume(c, ...)

        return function (f) return select(2, coroutine.resume(c, f)) end
    end

-- recursive; forward-declare
local reverser_impl_thread = nil
reverser_impl_thread =
    function (iter, self, ...)
        local args = continuation_thread(iter(self, ...))

        -- iteration is over?
        if args(dummy) == nil then return end

        reverser_impl_thread(iter, self, args(dummy))
        coroutine.yield(args(dummy))
    end

local reverser_impl_pack = nil
reverser_impl_pack =
    function (iter, self, ...)
        local args = pack(iter(self, ...))

        -- iteration is over?
        if args[1] == nil then return end

        reverser_impl_pack(iter, self, unpack(args))
        coroutine.yield(unpack(args))
    end

local reverser_pack =
    function (...)
        local args = pack(...)

        return coroutine.wrap(function () return reverser_impl_pack(unpack(args)) end)
    end

local reverser_thread =
    function (...)
        local args = continuation_thread(...)

        return coroutine.wrap(function () return reverser_impl_thread(args(dummy)) end)
    end

print('reverser (thread):')
for m    in reverser_thread(string.gmatch('cat', '.')) do print(m)    end
for i, v in reverser_thread(ipairs({ 'a', 'b', 'c' })) do print(i, v) end

print(('-'):rep(30))

print('reverser (pack): ')
for m    in reverser_pack(string.gmatch('cat', '.')) do print(m)    end
for i, v in reverser_pack(ipairs({ 'a', 'b', 'c' })) do print(i, v) end


Output:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
reverser (thread):
t
a
c
3	c
2	b
1	a
------------------------------
reverser (pack): 
t
a
c
3	c
2	b
1	a


Create a new paste based on this one


Comments: