Parrot::Coroutine - A pure PIR implementation of coroutines
.sub onload :load load_bytecode 'Parrot/Coroutine.pbc' .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 .local pmc coro .const 'Sub' coro_sub = "enumerate_tree" coro = new ['Parrot'; 'Coroutine'], 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
This object class provides an implementation of coroutines that is written in pure PIR using continuations.
This method is normally called via the
.local pmc coro .const 'Sub' coro_sub = "enumerate_tree" coro_class = get_class ['Parrot'; 'Coroutine'] coro = coro_class.'new'('initial_sub' => coro_sub)
Given a sub, it initializes a new
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
If the coroutine subsequently yields, the values passed to the
yield method are returned as the values from
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.
Within the coroutine,
yield returns arbitrary values back to the caller, making it look like the values came from the last
The next time the caller decides to resume the coroutine, the arguments passed to
resume are returned as the values from
Please report any others you find to
http://en.wikipedia.org/wiki/Coroutine -- coroutines defined.
t/library/coroutine.t -- "same fringe" test case.
src/pmc/coroutine.pmc -- the
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.
Copyright (C) 2006-2008, Parrot Foundation. This program is free software. It is subject to the same license as The Parrot Interpreter.