On Fri, Aug 03, 2007 at 09:51:53PM -0500, Patrick R. Michaud wrote: > > Currently, the only way to get a distinct binding for each "$i" in > > PIR is to factor the loop body out into a separate lexical sub. This is > > far from ideal, not least because it is not transparent to the HLL user. > > Factoring the loop body out into a separate lexical sub is _exactly_ > how Chip described to me that the above needed to be done.
Just for completeness, attached is a PIR version that I think is slightly more faithful to the original test-closures.pl program. It appears to work: $ ./parrot test-closures-3.pir Called sub 1 out of 3. Called sub 2 out of 3. Called sub 3 out of 3. $ Pm
## Return n closures, each with lexical references to "I" and "N'. .sub make_closures_loop .param pmc n .lex "$n", n .lex "@result", $P0 $P0 = new 'ResizablePMCArray' $I0 = 1 $I1 = n next: if $I0 > $I1 goto done 'internal_loop_body'($I0) inc $I0 goto next done: .return ($P0) .end .sub 'internal_loop_body' :outer('make_closures_loop') .param pmc topic .lex '$_', topic $P0 = clone topic .lex '$i', $P0 .const .Sub $P1 = 'internal_sub' newclosure $P2, $P1 find_lex $P3, '@result' push $P3, $P2 .return ($P3) .end .sub 'internal_sub' :outer('internal_loop_body') find_lex $P0, '$i' find_lex $P1, '$n' print "Called sub " print $P0 print " out of " print $P1 print ".\n" .end ## Make three closures and call them in turn. .sub test_closures :main .local pmc closures $I1 = 3 closures = make_closures_loop($I1) $I0 = 0 next: if $I0 >= $I1 goto done $P52 = closures[$I0] $P52() inc $I0 goto next done: .end