TITLE ^

Parrot::Coroutine - A pure PIR implementation of coroutines

VERSION ^

 $Id:$

SYNOPSIS ^

        .sub __onload :load
                load_bytecode 'Parrot/Coroutine.pir'
        .end

        ## Recursive coroutine to enumerate tree elements.  Each element that is
        ## not a FixedPMCArray is yielded in turn.
        .sub enumerate_tree
                .param pmc coro
                .param pmc tree_node
                .param int depth :optional
                .param int depth_p :opt_flag

                if depth_p goto have_depth
                depth = 0
        have_depth:
                inc depth

                $I0 = isa tree_node, 'FixedPMCArray'
                if $I0 goto recur
                print "[leaf "
                print tree_node
                print "]\n"
                coro.'yield'(tree_node)
                .return ()

        recur:
                ## Loop through array elements, recurring on each.
                .local int size, i
                i = 0
                size = tree_node
        again:
                if i >= size goto done
                print "[recur: depth "
                print depth
                print ' elt '
                print i
                print "]\n"
                $P1 = tree_node[i]
                enumerate_tree(coro, $P1, depth)
                inc i
                goto again
        done:
                .return ()
        .end

        .sub print_tree
                .param pmc tree

                .local int coro_class, idx
                coro_class = find_type 'Parrot::Coroutine'
                .local pmc coro
                .const .Sub coro_sub = "enumerate_tree"
                coro = new coro_class, coro_sub
                ($P0 :optional, $I0 :opt_flag) = coro.'resume'(coro, tree)
                idx = 0

        loop:
                unless $I0 goto done
                print 'print_tree:  '
                print idx
                print ' => '
                print $P0
                print "\n"
                ($P0 :optional, $I0 :opt_flag) = coro.'resume'()
                goto loop
        done:
        .end

DESCRIPTION ^

This object class provides an implementation of coroutines that is written in pure PIR using continuations.

METHODS ^

__init(sub)

This method is normally called via the new op:

        .local int coro_class
        coro_class = find_type 'Parrot::Coroutine'
        .local pmc coro
        .const .Sub coro_sub = "enumerate_tree"
        coro = new coro_class, coro_sub

Given a sub, it initializes a new Parrot::Coroutine object.

coro.resume(args...)

Invoke the coroutine. The first time this is called on a new coroutine, the initial sub is invoked with the passed arguments. The second and subsequent times, the args are delivered as the result of the previous yield operation.

If the coroutine subsequently yields, the values passed to the yield method are returned as the values from resume.

If the coroutine returns normally (i.e. from the original sub), then those values are passed returned from the resume method, and the coroutine is marked as dead, in which case it is an error to attempt to resume it again.

coro.yield(args...)

Within the coroutine, yield returns arbitrary values back to the caller, making it look like the values came from the last resume call.

The next time the caller decides to resume the coroutine, the arguments passed to resume are returned as the values from yield.

BUGS ^

  1. We should really keep more state details. The only legal state transitions should be 'new' to 'resumed' to 'yielded' to 'resumed' to 'yielded' ..., except that one might at any time transition to 'dead', which is (not surprisingly) the terminal state.

Please report any others you find to <parrot-porters@perl.org>.

SEE ALSO ^

http://en.wikipedia.org/wiki/Coroutine -- coroutines defined.

t/library/coroutine.t -- "same fringe" test case.

src/pmc/coroutine.pmc -- the pmclass implementation.

http://www.lua.org/manual/5.1/manual.html#2.11 -- definition of the coroutine API for the Lua programming language, upon which the Parrot::Coroutine API is based.

http://gd.tuwien.ac.at/languages/scheme/tutorial-dsitaram/t-y-scheme-Z-H-14.html -- Scheme tutorial chapter that introduces call/cc and uses it to solve "same fringe" via coroutines.

AUTHOR ^

Bob Rogers <rogers-perl6@rgrjr.dyndns.org>

COPYRIGHT ^

Copyright (C) 2006, The Perl Foundation. This program is free software. It is subject to the same license as The Parrot Interpreter.

" vim: ts=8 expandtab


parrot