## This version doesn't work; the recursive call from coro_enumerate_tree ## winds up yielding. -- rgr, 7-Oct-06. ## build a complete N-ary tree of the specified depth, with the leaves being ## consecutive integer PMCs from start. .sub make_nary_tree .param int start .param int node_width .param int depth .local pmc result if depth goto deeper result = new .Undef result = start inc start goto done deeper: result = new .FixedPMCArray result = node_width dec depth .local int i i = 0 next: if i >= node_width goto done ($P0, start) = make_nary_tree(start, node_width, depth) result[i] = $P0 inc i goto next done: .return (result, start) .end ## non-coroutine traversal, for debugging. .sub enumerate_tree .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" done: .return () recur: .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($P1, depth) inc i goto again .end ## recursive coroutine to enumerate tree elements, each of which is yielded in ## turn. .sub coro_enumerate_tree .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" .yield (tree_node) .return () recur: .local int size, i i = 0 size = tree_node again: if i >= size goto done print "[coro recur: depth " print depth print ' elt ' print i print "]\n" $P1 = tree_node[i] ## [NB: this recursive call isn't to the clone. but it's not clear ## whether that would help. -- rgr, 7-Oct-06.] coro_enumerate_tree($P1) inc i goto again done: .return () .end .sub main :main ## make a data structure for traversal. .local pmc binary_3 binary_3 = make_nary_tree(1, 2, 3) ## enable this to show that make_nary_tree works. ## enumerate_tree(binary_3) ## list its contents via coroutine. .local pmc coro1 coro1 = global 'coro_enumerate_tree' ## [cloning makes it fail later. -- rgr, 7-Oct-06.] ## coro1 = clone coro1 loop: ($P0 :optional, $I0 :opt_flag) = coro1(binary_3) unless $I0 goto done if null $P0 goto oops print $P0 print "\n" goto loop oops: ## we should never get here; the coroutine returns either no values, or ## one value that must be an integer PMC. print "oops.\n" done: .end