public
Created

It's all about context

  • Download Gist
macros-d2-musings.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
Let's take this bit of code as our example:
 
macro twice($code) { # parse # runtime
quasi {
{{{$code}}}; # (3)
{{{$code}}}; # (3)
} # (1) # (4)
}
my $counter = 0;
twice $counter++; # (2)(6) # (5)
say $counter;
 
Here are the data flows during parsing:
 
(1) quasi gets parsed
resulting in some QAST that will generate
a Perl6::AST at runtime for that quasi.
that code runs during (3) and (4).
 
(2) call to &twice gets parsed
we package the argument `$counter++` as
a Perl6::AST and send it off as an
argument in the macro call.
 
(3) unquotes evaluate
so the QAST generated at (1) runs now,
running the two {{{}}} blocks in order
and expecting Perl6::AST objects out
of them. which we get, since $code is
a Perl6::AST. all the Perl6::AST objects
from all the {{{}}} blocks are gutted,
and their contents are incorporated into
the big QAST tree for the whole quasi.
 
(4) quasi object is built
it's just a Perl6::AST.
 
(5) macro returns
it is expected that the return value be
a Perl6::AST, but that's fine, because
that's what the quasi block evaluated to.
 
(6) macro result gets inserted into mainline
the Perl6::AST coming from the macro is
gutted, its QAST cargo is inserted into
the mainline, and there is peace on earth
and good will to men.
 
Now, there are *two* transfers of context that must happen for all of this
to work. Only the second currently works, which is why we are seeing bogus
results:
 
(a) The context at (2) must be saved and applied at (3).
 
(b) The context at (4) must be saved and applied at (6).

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.