2008/9/24 Patrick R. Michaud <[EMAIL PROTECTED]>:
> On Wed, Sep 24, 2008 at 12:09:37PM +0200, François Perrad wrote:
>> Currently, the bigger issue in Lua on Parrot is lexical or upvalue in
>> Lua jargon (the reason for Lua on Parrot is not really Lua).
>> The following Lua code doesn't give the expected result (from
>> languages/lua/t/closure.t) :
>>     a = {}
>>     local x = 20
>>     for i=1,10 do
>>         local y = 0
>>         a[i] = function () y=y+1; return x+y end
>>     end
>>
>>     print(a[1]())
>>     print(a[1]())
>>     print(a[2]())
>>
>>     --[[
>>     The loop creates ten closures (that is, ten instances of
>>     the anonymous function). Each of these closures uses
>>     a different y variable, while all of them share the same x.
>>     ]]
>>
>>
>> With the current Parrot, I never found a way to do it.
>>
>> So, I'll be happy if this revisiting handles this issue.
>
>
> Here's how I would expect this to look in PIR under the
> new scheme (I'm not familiar with Lua, but I'm assuming 'local'
> in Lua means 'lexical', and that the loop variable is lexical):
>
Details are here http://www.lua.org/manual/5.1/manual.html#2.6
"Visibility Rules",
where comes from the code sample.

> .sub 'main'
>    ##  set outer context of forbody_block
>    .const .Sub forbody = 'forbody_block'
>    capture_lex forbody
>
>    ##  a = {}
>    .local pmc a
>    a = new 'ResizablePMCArray'
>    store_global 'a', a
>
>    ##  local x = 20
>    .local pmc x
>    x = new 'Integer'
>    x = 20
>    .lex 'x', x
>
>    ##  for i = 1,10 do
>    .local pmc i
>    i = new 'Integer'
>    .lex 'i', i
>  for_loop:
>    if i > 10 goto for_done
>    forbody()
>    inc i
>    goto for_loop
>  for_done:
>
>    ##  print(a[1]())
>    $P0 = a[1]
>    $P1 = $P0()
>    say $P1
>
>    ## ...
> .end
>
>
> .sub 'forbody_block' :outer('main')
>    ##  set outer context of lambda_block
>    .const .Sub lambda = 'lambda_block'
>    capture_lex lambda
>
>    ##  local y = 0
>    .local pmc y
>    y = new 'Integer'
>    y = 0
>    .lex 'y', y
>
>    ##  a[i] = function () y = y+1; return x+y; end
>    .local pmc a,i
>    a = get_global 'a'
>    i = find_lex 'i'
>    $P0 = clone lambda           ## this creates the closure
>    a[i] = $P0
> .end
>
>
> .sub 'lambda_block' :outer('forbody_block')
>    ##  y = y + 1;
>    .local pmc y
>    y = find_lex 'y'
>    n_add $P0, y, 1
>    copy y, $P0
>
>    ##  return x+y;
>    .local pmc x
>    x = find_lex 'x'
>    n_add $P1, x,y
>    .return ($P1)
> .end
>
Looks fine.
Thanks.

François.

>
>
> Pm
>
>

Reply via email to