On Wed, Feb 13, 2008 at 11:26:36AM +0100, Klaas-Jan Stol wrote:
> this is very interesting. I think we should store this example somewhere
> in proper documentation format, maybe in docs/compiler_faq.pod
FWIW, the information about using getinterp to get at a caller's
lexpad is already in pdd20, so perhaps we can just add the information
about the 'outer' example there as well.
Pm
> On Feb 12, 2008 8:50 PM, Andrew Parker <[EMAIL PROTECTED]> wrote:
>
> So that works in this situation because the outer lexpad that I want
> is the same as the caller's lexpad. Thanks for the tip :) After
> poking around a bit at what "getinterp" does I found some good reading.
>
> * docs/ops/core.pod - getinterp returns the ParrotInterpreter
> * src/pmc/parrotinterpreter.pmc - the list of PMC keys is very
> interesting
>
> Now to kick it up a notch! From that I learned that the getinterp and
> then lexpad works in this case since the wanted lexical pad is the
> caller's. This doesn't work when the wanted lexical pad is the
> lexically enclosing scope (not the caller). Here is an example:
>
> # equivalent to:
> #
> # sub f {
> # my $x = 1;
> # return sub { my $x = $x + 1; return $x; };
> # }
> # print f()->(), "\n"
> #
> .namespace
> .sub "main"
> get_global $P18, "outer"
> $P17 = $P18()
> $P16 = $P17()
> print $P16
> print "\n"
> .end
>
> .sub "outer" :outer("main")
> new $P12, "Integer"
> assign $P12, 1
> .lex "x", $P12
> get_global $P18, "inner"
> newclosure $P18, $P18
> .return ($P18)
> .end
>
> .sub "inner" :outer("outer")
> $P0 = getinterp
> $P1 = $P0['outer'; 'lexpad']
> $P14 = $P1['x']
> n_add $P15, $P14, 1
> .lex "x", $P15
> .return ($P15)
> .end
>
> There is also the 'outer' lexpad which is the actuall enclosing one.
> So it looks like my complaint that there was something lacking was
> wrong. It is more that I didn't look enough and parrot has so much
> that it was hard to find :P
>
> Thanks for the patience and the help.
> Andrew Parker
> On Feb 12, 2008, at 8:00 PM, Patrick R. Michaud wrote:
>
> > On Mon, Feb 11, 2008 at 10:27:27PM +0100, Andrew Parker wrote:
> >> .namespace
> >> .sub "outer"
> >> new $P12, "Integer"
> >> assign $P12, 1
> >> .lex "x", $P12
> >> get_global $P18, "inner"
> >> newclosure $P18, $P18
> >> $P17 = $P18()
> >> print $P17
> >> print "\n"
> >> .end
> >>
> >> .sub "inner" :outer("outer")
> >> find_lex $P14, "x"
> >> n_add $P15, $P14, 1
> >> .lex "x", $P15
> >> .return ($P15)
> >> .end
> >
> > A PIR subroutine can get at its caller's lexpad by doing:
> >
> > $P0 = getinterp
> > $P1 = $P0['lexpad'; 1]
> >
> > So, in the 'inner' sub above, it can get to outer's 'x' lexical
> > by doing:
> >
> > $P0 = getinterp
> > $P1 = $P0['lexpad'; 1]
> > $P2 = $P1['x']
> >
> > Pm