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