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

Reply via email to