Skip to content

Commit

Permalink
RakuAST: fix parsing of indirect lookups
Browse files Browse the repository at this point in the history
True ?? ::("Int") !! 1 failed to parse because we were treating ::(...)
as a call instead of a plain name. This untangles indirect lookups and
calls.
  • Loading branch information
niner committed Feb 13, 2023
1 parent 2b6b401 commit cbe8d97
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 6 deletions.
6 changes: 3 additions & 3 deletions src/Raku/Actions.nqp
Expand Up @@ -1182,9 +1182,9 @@ class Raku::Actions is HLL::Actions does Raku::CommonActions {
}

method term:sym<name>($/) {
my $name := $<longname>.ast;
if $<args> {
my $args := $<args>.ast;
my $name := $<longname>.ast;
if $args.invocant {
# Indirect method call syntax, e.g. new Int: 1
self.attach: $/, self.r('ApplyPostfix').new:
Expand All @@ -1197,14 +1197,14 @@ class Raku::Actions is HLL::Actions does Raku::CommonActions {
}
else {
if $*is-type {
my $type := self.r('Type', 'Simple').new($<longname>.ast);
my $type := self.r('Type', 'Simple').new($name);
if $<arglist> {
$type := self.r('Type', 'Parameterized').new($type, $<arglist>.ast);
}
self.attach: $/, $type;
}
else {
self.attach: $/, self.r('Term', 'Name').new($<longname>.ast);
self.attach: $/, self.r('Term', 'Name').new($name);
}
}
}
Expand Down
22 changes: 20 additions & 2 deletions src/Raku/Grammar.nqp
Expand Up @@ -1734,12 +1734,25 @@ grammar Raku::Grammar is HLL::Grammar does Raku::Common {
:my $*is-type;
<longname>
[
|| <?{ $*R.is-name-known($<longname>.ast) }>
{ $*is-type := $*R.is-name-type($<longname>.ast) }
|| <?{ nqp::eqat($<longname>.Str, '::', 0) || $*R.is-name-known($<longname>.ast) }>
{ $*is-type := $*R.is-name-type($<longname>.ast) }
[
<?[[]> <?{ $*is-type }>
:dba('type parameter') '[' ~ ']' <arglist>
]?
<.unsp>?
[
<?[{]> <?{ $*is-type }>
<whence=.postcircumfix> <.NYI('Autovivifying object closures')>
]?
<.unsp>?
[
<?[(]> <?{ $*is-type }>
'(' <.ws> [
|| <accept=.maybe_typename> <!{ nqp::isconcrete($<accept>.ast) }>
|| $<accept_any>=<?>
] <.ws> ')'
]?
|| [ \\ <?before '('> ]? <args(1)>
{
if !$<args><invocant> {
Expand Down Expand Up @@ -2571,6 +2584,11 @@ grammar Raku::Grammar is HLL::Grammar does Raku::Common {
[<.ws> 'of' <.ws> <typename> ]?
}
method maybe_typename() {
return self.typename();
CATCH { return self.'!cursor_start_cur'() }
}
##
## Signatures
##
Expand Down
35 changes: 34 additions & 1 deletion src/Raku/ast/term.rakumod
Expand Up @@ -6,24 +6,57 @@ class RakuAST::Term::Name
is RakuAST::Lookup
{
has RakuAST::Name $.name;
has Mu $!package;

method new(RakuAST::Name $name) {
my $obj := nqp::create(self);
nqp::bindattr($obj, RakuAST::Term::Name, '$!name', $name);
$obj
}

method attach(RakuAST::Resolver $resolver) {
my $package := $resolver.find-attach-target('package');
nqp::bindattr(self, RakuAST::Term::Name, '$!package', $package);
}

method resolve-with(RakuAST::Resolver $resolver) {
my $resolved := $resolver.resolve-name($!name);
if $resolved {
self.set-resolution($resolved);
}
elsif $!name.is-package-lookup {
my $name := $!name.base-name;
if $name.canonicalize {
$resolved := $resolver.resolve-name($name);
if $resolved {
my $v := $resolved.compile-time-value;
self.set-resolution($resolved);
}
}
}
Nil
}

method IMPL-EXPR-QAST(RakuAST::IMPL::QASTContext $context) {
# TODO indirects, trailing ::, etc.
self.resolution.IMPL-LOOKUP-QAST($context)
if $!name.is-package-lookup {
return self.is-resolved
?? $!name.IMPL-QAST-PACKAGE-LOOKUP(
$context,
QAST::WVal.new(:value($!package)),
:lexical(self.resolution)
)
!! $!name.IMPL-QAST-PACKAGE-LOOKUP(
$context,
QAST::WVal.new(:value($!package))
);
}
elsif $!name.is-indirect-lookup {
return $!name.IMPL-QAST-INDIRECT-LOOKUP($context);
}
else {
self.resolution.IMPL-LOOKUP-QAST($context)
}
}

method visit-children(Code $visitor) {
Expand Down

0 comments on commit cbe8d97

Please sign in to comment.