Skip to content

Commit

Permalink
Migrate to use of parse time
Browse files Browse the repository at this point in the history
So that we no longer rely on the feature to do begin time before a node.
  • Loading branch information
jnthn committed Jun 4, 2023
1 parent 8b13ff1 commit 8ed4a96
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 37 deletions.
22 changes: 3 additions & 19 deletions src/Raku/ast/begintime.rakumod
Expand Up @@ -18,25 +18,9 @@ class RakuAST::BeginTime

# Ensure the begin-time effects are performed.
method ensure-begin-performed(RakuAST::Resolver $resolver, RakuAST::IMPL::QASTContext $context, int :$phase) {
if nqp::can(self, 'PERFORM-BEGIN-BEFORE-CHILDREN') || nqp::can(self, 'PERFORM-BEGIN-AFTER-CHILDREN') {
if $phase == 0 && self.is-begin-performed-before-children || $phase == 1 {
unless $!begin-performed +& 1 {
self.PERFORM-BEGIN-BEFORE-CHILDREN($resolver, $context);
nqp::bindattr_i(self, RakuAST::BeginTime, '$!begin-performed', $!begin-performed +| 1);
}
}
if $phase == 0 && self.is-begin-performed-after-children || $phase == 2 {
unless $!begin-performed +& 2 {
self.PERFORM-BEGIN-AFTER-CHILDREN($resolver, $context);
nqp::bindattr_i(self, RakuAST::BeginTime, '$!begin-performed', $!begin-performed +| 2);
}
}
}
else {
unless $!begin-performed {
self.PERFORM-BEGIN($resolver, $context);
nqp::bindattr_i(self, RakuAST::BeginTime, '$!begin-performed', 3);
}
unless $!begin-performed {
self.PERFORM-BEGIN($resolver, $context);
nqp::bindattr_i(self, RakuAST::BeginTime, '$!begin-performed', 3);
}
Nil
}
Expand Down
15 changes: 5 additions & 10 deletions src/Raku/ast/code.rakumod
Expand Up @@ -1323,6 +1323,7 @@ class RakuAST::Routine
is RakuAST::AttachTarget
is RakuAST::PlaceholderParameterOwner
is RakuAST::ImplicitLookups
is RakuAST::ParseTime
is RakuAST::BeginTime
is RakuAST::TraitTarget
is RakuAST::ScopePhaser
Expand Down Expand Up @@ -1405,10 +1406,7 @@ class RakuAST::Routine
$routine
}

method is-begin-performed-before-children() { True }
method is-begin-performed-after-children() { True }

method PERFORM-BEGIN-BEFORE-CHILDREN(RakuAST::Resolver $resolver, RakuAST::IMPL::QASTContext $context) {
method PERFORM-PARSE(RakuAST::Resolver $resolver, RakuAST::IMPL::QASTContext $context) {
my $placeholder-signature := self.placeholder-signature;
if $placeholder-signature {
$placeholder-signature.IMPL-ENSURE-IMPLICITS;
Expand All @@ -1418,7 +1416,7 @@ class RakuAST::Routine
}
}

method PERFORM-BEGIN-AFTER-CHILDREN(RakuAST::Resolver $resolver, RakuAST::IMPL::QASTContext $context) {
method PERFORM-BEGIN(RakuAST::Resolver $resolver, RakuAST::IMPL::QASTContext $context) {
# Make sure that our placeholder signature has resolutions performed.
my $placeholder-signature := self.placeholder-signature;
if $placeholder-signature {
Expand Down Expand Up @@ -1769,10 +1767,7 @@ class RakuAST::Methodish
nqp::bindattr(self, RakuAST::Code, '$!resolver', $resolver.clone);
}

method is-begin-performed-before-children() { True }
method is-begin-performed-after-children() { True }

method PERFORM-BEGIN-BEFORE-CHILDREN(RakuAST::Resolver $resolver, RakuAST::IMPL::QASTContext $context) {
method PERFORM-PARSE(RakuAST::Resolver $resolver, RakuAST::IMPL::QASTContext $context) {
my $placeholder-signature := self.placeholder-signature;
if $placeholder-signature {
$placeholder-signature.set-is-on-method(True);
Expand All @@ -1797,7 +1792,7 @@ class RakuAST::Methodish
}
}

method PERFORM-BEGIN-AFTER-CHILDREN(RakuAST::Resolver $resolver, RakuAST::IMPL::QASTContext $context) {
method PERFORM-BEGIN(RakuAST::Resolver $resolver, RakuAST::IMPL::QASTContext $context) {
if nqp::getattr(self, RakuAST::Routine, '$!package') {
nqp::getattr(self, RakuAST::Routine, '$!package').ATTACH-METHOD(self);
}
Expand Down
7 changes: 2 additions & 5 deletions src/Raku/ast/package.rakumod
Expand Up @@ -5,7 +5,7 @@ class RakuAST::Package
is RakuAST::IMPL::ImmediateBlockUser
is RakuAST::Declaration
is RakuAST::AttachTarget
is RakuAST::BeginTime
is RakuAST::ParseTime
is RakuAST::TraitTarget
is RakuAST::ImplicitBlockSemanticsProvider
is RakuAST::LexicalScope
Expand Down Expand Up @@ -170,17 +170,14 @@ class RakuAST::Package
Nil
}

# We install the name before parsing the class body.
method is-begin-performed-before-children() { True }

method IMPL-GENERATE-LEXICAL-DECLARATION(RakuAST::Name $name, Mu $type-object) {
RakuAST::Declaration::LexicalPackage.new:
:lexical-name($name),
:compile-time-value($type-object),
:package(self);
}

method PERFORM-BEGIN(RakuAST::Resolver $resolver, RakuAST::IMPL::QASTContext $context) {
method PERFORM-PARSE(RakuAST::Resolver $resolver, RakuAST::IMPL::QASTContext $context) {
# Note that this early return is actually not effective as the begin handler will
# already be run when the parser enters the package and we only know that it's a
# stub when we are done parsing the body.
Expand Down
39 changes: 39 additions & 0 deletions src/Raku/ast/parsetime.rakumod
Expand Up @@ -21,4 +21,43 @@ class RakuAST::ParseTime
nqp::bindattr_i(self, RakuAST::ParseTime, '$!parse-performed', 1);
}
}

# Called when a BEGIN-time construct needs to evaluate code. Tries to
# interpret simple things to avoid the cost of compilation.
method IMPL-BEGIN-TIME-EVALUATE(RakuAST::Node $code, RakuAST::Resolver $resolver, RakuAST::IMPL::QASTContext $context) {
$code.IMPL-CHECK($resolver, $context, False);
if $code.IMPL-CAN-INTERPRET {
$code.IMPL-INTERPRET(RakuAST::IMPL::InterpContext.new)
}
elsif nqp::istype($code, RakuAST::Code) {
$code.meta-object;
}
elsif nqp::istype($code, RakuAST::Expression) {
my $thunk := RakuAST::ExpressionThunk.new;
$code.wrap-with-thunk($thunk);
$thunk.IMPL-STUB-CODE($resolver, $context);
$thunk.IMPL-QAST-BLOCK($context, :expression($code));
$thunk.meta-object()()
}
else {
nqp::die('BEGIN time evaluation only supported for simple constructs so far')
}
}

# Called when a BEGIN-time construct wants to evaluate a resolved code
# with a set of arguments.
method IMPL-BEGIN-TIME-CALL(RakuAST::Node $callee, RakuAST::ArgList $args,
RakuAST::Resolver $resolver, RakuAST::IMPL::QASTContext $context) {
if $callee.is-resolved && nqp::istype($callee.resolution, RakuAST::CompileTimeValue) &&
$args.IMPL-CAN-INTERPRET {
my $resolved := $callee.resolution.compile-time-value;
my @args := $args.IMPL-INTERPRET(RakuAST::IMPL::InterpContext.new);
my @pos := @args[0];
my %named := @args[1];
return $resolved(|@pos, |%named);
}
else {
nqp::die('BEGIN time calls only supported for simple constructs so far')
}
}
}
4 changes: 1 addition & 3 deletions src/Raku/ast/type.rakumod
Expand Up @@ -673,9 +673,7 @@ class RakuAST::Type::Subset
:scope(self.scope);
}

method is-begin-performed-after-children() { True }

method PERFORM-BEGIN-AFTER-CHILDREN(RakuAST::Resolver $resolver, RakuAST::IMPL::QASTContext $context) {
method PERFORM-BEGIN(RakuAST::Resolver $resolver, RakuAST::IMPL::QASTContext $context) {
self.apply-traits($resolver, $context, self);

my $block := $!block;
Expand Down

0 comments on commit 8ed4a96

Please sign in to comment.