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
>
>