Skip to content

Instantly share code, notes, and snippets.

@masak
Created September 5, 2012 09:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save masak/3634046 to your computer and use it in GitHub Desktop.
Save masak/3634046 to your computer and use it in GitHub Desktop.
It's all about context
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).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment