Skip to content

Commit

Permalink
RakuAST: implement support for INIT phasers
Browse files Browse the repository at this point in the history
Instead of an !INIT_VALUES hash in the comp unit like the old compiler
frontend, the RakuAST frontend simply creates a Scalar container for
each init value and uses this for storing and accessing the value.
  • Loading branch information
niner committed Jan 22, 2023
1 parent a99da6c commit 75b4f5b
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/Raku/Actions.nqp
Expand Up @@ -492,6 +492,10 @@ class Raku::Actions is HLL::Actions does Raku::CommonActions {
self.attach: $/, $ast;
}

method statement_prefix:sym<INIT>($/) {
self.attach: $/, self.r('StatementPrefix', 'Phaser', 'Init').new($<blorst>.ast);
}

method statement_prefix:sym<END>($/) {
self.attach: $/, self.r('StatementPrefix', 'Phaser', 'End').new($<blorst>.ast);
}
Expand Down
1 change: 1 addition & 0 deletions src/Raku/Grammar.nqp
Expand Up @@ -899,6 +899,7 @@ grammar Raku::Grammar is HLL::Grammar does Raku::Common {
proto token statement_prefix { <...> }
token statement_prefix:sym<BEGIN> { <sym><.kok> <blorst> }
token statement_prefix:sym<INIT> { <sym><.kok> <blorst> }
token statement_prefix:sym<END> { <sym><.kok> <blorst> }
token statement_prefix:sym<LEAVE> { <sym><.kok> <blorst> }
Expand Down
27 changes: 27 additions & 0 deletions src/Raku/ast/compunit.rakumod
Expand Up @@ -15,6 +15,7 @@ class RakuAST::CompUnit
has int $!is-sunk;
has int $!is-eval;
has Mu $!global-package-how;
has Mu $!init-phasers;
has Mu $!end-phasers;
has Mu $!singleton-whatever;
has Mu $!singleton-hyper-whatever;
Expand All @@ -40,6 +41,7 @@ class RakuAST::CompUnit
$global-package-how =:= NQPMu ?? Perl6::Metamodel::PackageHOW !! $global-package-how);
nqp::bindattr($obj, RakuAST::CompUnit, '$!export-package',
$export-package =:= NQPMu ?? Mu !! $export-package);
nqp::bindattr($obj, RakuAST::CompUnit, '$!init-phasers', []);
nqp::bindattr($obj, RakuAST::CompUnit, '$!end-phasers', []);
nqp::bindattr_i($obj, RakuAST::CompUnit, '$!precompilation-mode', $precompilation-mode ?? 1 !! 0);
nqp::bindattr($obj, RakuAST::CompUnit, '$!herestub-queue', []);
Expand Down Expand Up @@ -110,11 +112,17 @@ class RakuAST::CompUnit
}

method clear-attachments() {
nqp::setelems($!init-phasers, 0);
nqp::setelems($!end-phasers, 0);
self.clear-handler-attachments();
Nil
}

method add-init-phaser(RakuAST::StatementPrefix::Phaser::Init $phaser) {
nqp::push($!init-phasers, $phaser);
Nil
}

method add-end-phaser(RakuAST::StatementPrefix::Phaser::End $phaser) {
nqp::push($!end-phasers, $phaser);
Nil
Expand Down Expand Up @@ -285,12 +293,31 @@ class RakuAST::CompUnit
QAST::Stmts.new(
QAST::Var.new( :name('__args__'), :scope('local'), :decl('param'), :slurpy(1) ),
self.IMPL-QAST-DECLS($context),
self.IMPL-QAST-INIT-PHASERS($context),
self.IMPL-QAST-END-PHASERS($context),
self.IMPL-QAST-CTXSAVE($context),
self.IMPL-WRAP-SCOPE-HANDLER-QAST($context, $!statement-list.IMPL-TO-QAST($context)),
)
}

method IMPL-QAST-INIT-PHASERS(RakuAST::IMPL::QASTContext $context) {
my $init-setup := QAST::Stmts.new;
for $!init-phasers {
my $container := $_.container;
$context.ensure-sc($container);
$init-setup.push(
QAST::Op.new(
:op<bindattr>,
QAST::WVal.new( :value($container) ),
QAST::WVal.new( :value(Scalar) ),
QAST::SVal.new( :value('$!value') ),
$_.IMPL-CALLISH-QAST($context)
)
);
}
$init-setup
}

method IMPL-QAST-END-PHASERS(RakuAST::IMPL::QASTContext $context) {
my $end-setup := QAST::Stmts.new;
for $!end-phasers {
Expand Down
32 changes: 32 additions & 0 deletions src/Raku/ast/statementprefixes.rakumod
Expand Up @@ -371,6 +371,38 @@ class RakuAST::StatementPrefix::Phaser::Begin
}
}

# The INIT phaser.
class RakuAST::StatementPrefix::Phaser::Init
is RakuAST::StatementPrefix::Phaser
is RakuAST::StatementPrefix::Thunky
is RakuAST::Attaching
{
has Scalar $.container;

method new(RakuAST::Blorst $blorst) {
my $obj := nqp::create(self);
unless self.allowed-on-for-statement {
if nqp::istype($blorst, RakuAST::Statement::For) {
nqp::die('Do not use this statement prefix on a RakuAST::Statement::For; ' ~
'instead, set the mode on that node');
}
}
nqp::bindattr($obj, RakuAST::StatementPrefix, '$!blorst', $blorst);
nqp::bindattr($obj, RakuAST::StatementPrefix::Phaser::Init, '$!container', nqp::create(Scalar));
$obj
}

method attach(RakuAST::Resolver $resolver) {
$resolver.find-attach-target('compunit').add-init-phaser(self);
}

method IMPL-EXPR-QAST(RakuAST::IMPL::QASTContext $context) {
my $container := $!container;
$context.ensure-sc($container);
QAST::WVal.new( :value($container) )
}
}

# The FIRST phaser.
class RakuAST::StatementPrefix::Phaser::First
is RakuAST::StatementPrefix::Phaser::Sinky
Expand Down

0 comments on commit 75b4f5b

Please sign in to comment.