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