Skip to content

Commit

Permalink
Re-work implicit lookups
Browse files Browse the repository at this point in the history
They are now treated as if they are like children of a node that get
their parse time and begin time ahead of the parse time of their owner.
  • Loading branch information
jnthn committed Jun 5, 2023
1 parent e69dbef commit f7501f0
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 19 deletions.
5 changes: 0 additions & 5 deletions src/Raku/Actions.nqp
Expand Up @@ -23,12 +23,7 @@ role Raku::CommonActions {
# object.
method attach($/, $node, :$as-key-origin) {
$node.to-begin-time($*R, $*CU.context);
if nqp::istype($node, self.r('ImplicitLookups')) {
$node.resolve-implicit-lookups-with($*R);
}

self.SET-NODE-ORIGIN($/, $node, :$as-key-origin);

make $node;
}

Expand Down
19 changes: 14 additions & 5 deletions src/Raku/ast/base.rakumod
Expand Up @@ -77,6 +77,9 @@ class RakuAST::Node {

# Bring the node up to parse time. Returns the node itself.
method to-parse-time(RakuAST::Resolver $resolver, RakuAST::IMPL::QASTContext $context) {
if nqp::istype(self, RakuAST::ImplicitLookups) {
self.implicit-lookups-to-begin-time($resolver, $context);
}
if nqp::istype(self, RakuAST::ParseTime) {
self.ensure-parse-performed($resolver, $context);
}
Expand All @@ -85,6 +88,9 @@ class RakuAST::Node {

# Bring the node up to begin time. Returns the node itself.
method to-begin-time(RakuAST::Resolver $resolver, RakuAST::IMPL::QASTContext $context) {
if nqp::istype(self, RakuAST::ImplicitLookups) {
self.implicit-lookups-to-begin-time($resolver, $context);
}
if nqp::istype(self, RakuAST::ParseTime) {
self.ensure-parse-performed($resolver, $context);
}
Expand All @@ -98,6 +104,12 @@ class RakuAST::Node {
# the compiler, this is done while parsing takes place. For a synthetic AST, however, it needs
# to be performed.
method IMPL-BEGIN(RakuAST::Resolver $resolver, RakuAST::IMPL::QASTContext $context) {
# Ensure implicit lookups are driven to their begin state ahead of the node's parse
# time (in that sense, they are a bit like implicit children of the node).
if nqp::istype(self, RakuAST::ImplicitLookups) {
self.implicit-lookups-to-begin-time($resolver, $context);
}

# Ensure parse time was performed already before visiting children, when it is a
# lexical scope that we are entering.
my int $is-scope := nqp::istype(self, RakuAST::LexicalScope);
Expand All @@ -107,13 +119,10 @@ class RakuAST::Node {
$is-parse-time := 0;
}

# TODO Cleanup legacy phase actions
# TODO Move all resolve-with into parse time or begin time
if nqp::istype(self, RakuAST::Lookup) && !self.is-resolved {
self.resolve-with($resolver);
}
if nqp::istype(self, RakuAST::ImplicitLookups) {
self.resolve-implicit-lookups-with($resolver);
}

# Visit children.
my int $is-package := nqp::istype(self, RakuAST::Package);
Expand All @@ -139,12 +148,12 @@ class RakuAST::Node {
# parse time has already completely happened.
method IMPL-CHECK(RakuAST::Resolver $resolver, RakuAST::IMPL::QASTContext $context, Bool $resolve-only) {
# Apply implicit block semantics.
my int $is-scope := nqp::istype(self, RakuAST::LexicalScope);
if nqp::istype(self, RakuAST::ImplicitBlockSemanticsProvider) {
self.apply-implicit-block-semantics();
}

# Visit children and do their CHECK time.
my int $is-scope := nqp::istype(self, RakuAST::LexicalScope);
my int $is-package := nqp::istype(self, RakuAST::Package);
$resolver.push-scope(self) if $is-scope;
$resolver.push-package(self) if $is-package;
Expand Down
5 changes: 0 additions & 5 deletions src/Raku/ast/code.rakumod
Expand Up @@ -1250,11 +1250,6 @@ class RakuAST::PointyBlock
}

method PERFORM-BEGIN(RakuAST::Resolver $resolver, RakuAST::IMPL::QASTContext $context) {
# Cannot rely on IMPL-CHECK getting run before this, as that would
# also run our children's BEGIN handlers which would screw up our
# block-or-hash detection
self.resolve-implicit-lookups-with($resolver);

# Make sure that our placeholder signature has resolutions performed,
# and that we don't produce a topic parameter.
if $!signature {
Expand Down
12 changes: 8 additions & 4 deletions src/Raku/ast/scoping.rakumod
Expand Up @@ -692,7 +692,9 @@ class RakuAST::UndeclaredSymbolDescription::Routine
# of symbols as part of their compilation. For example, a positional regex
# access depends on `&postcircumfix:<[ ]>` and `$/`, while an `unless`
# statement depends on `Empty` (as that's what it evaluates to in the case
# there the condition is not matched).
# there the condition is not matched). Implicit lookups are not children of
# the node, but they will receive their parse/begin time prior to the node's
# parse time.
class RakuAST::ImplicitLookups
is RakuAST::Node
{
Expand All @@ -715,10 +717,12 @@ class RakuAST::ImplicitLookups
!! self.IMPL-WRAP-LIST([])
}

# Resolve the implicit lookups if needed.
method resolve-implicit-lookups-with(RakuAST::Resolver $resolver) {
# Drive the implicit lookups to their begin time.
method implicit-lookups-to-begin-time(RakuAST::Resolver $resolver, RakuAST::IMPL::QASTContext $context) {
for self.IMPL-UNWRAP-LIST(self.get-implicit-lookups()) {
unless $_.is-resolved {
$_.to-begin-time($resolver, $context);
# TODO Eliminate when resolve-with is gone
if nqp::can($_, 'resolve-with') {
$_.resolve-with($resolver);
}
}
Expand Down

0 comments on commit f7501f0

Please sign in to comment.