Skip to content

Commit

Permalink
RakuAST: make "no strict" work in the Raku grammar
Browse files Browse the repository at this point in the history
- Remove class RakuAST::Var::Lexical::Auto
- Add class RakuAST::VarDeclaration::Auto
  This is for all intents and purposes, the same as the
  RakuAST::VarDeclaration::Simple class, but it deparses and rakufies
  as a RakuAST::Var::Lexical.
- Adapt actions to use add a RakuAST::VarDeclaration::Auto if
  "no strict" is active, and the variable in question does not resolve
  yet.

nine++ for pointers.  Sadly, this is now a grammar only functionality
that can **not** be represented in a RakuAST tree.  But I guess we
can live with that, definitely for now.
  • Loading branch information
lizmat committed Mar 26, 2023
1 parent b504224 commit 238931a
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 48 deletions.
13 changes: 10 additions & 3 deletions src/Raku/Actions.nqp
Expand Up @@ -1355,9 +1355,16 @@ class Raku::Actions is HLL::Actions does Raku::CommonActions {
}
elsif $twigil eq '' {
if !$longname || $longname<name>.ast.is-identifier {
self.attach: $/, $*LANG.pragma("strict")
?? self.r('Var', 'Lexical').new($name)
!! self.r('Var', 'Lexical', 'Auto').new($name)
if $*LANG.pragma("strict") || $*R.resolve-lexical($name) {
self.attach: $/, self.r('Var', 'Lexical').new($name);
}
else {
my $decl := self.r('VarDeclaration','Auto').new(
scope => "our", name => $name
);
$*R.declare-lexical($decl);
self.attach: $/, $decl;
}
}
else { # package variable
self.attach: $/, self.r('Var', 'Package').new(
Expand Down
45 changes: 0 additions & 45 deletions src/Raku/ast/variable-access.rakumod
Expand Up @@ -55,51 +55,6 @@ class RakuAST::Var::Lexical
}
}

# A lexical variable that possibly needs to be auto-declared (aka
# "no strict" active)
class RakuAST::Var::Lexical::Auto
is RakuAST::Var::Lexical
{
has Mu $!package;

method new(str $name) {
my $obj := nqp::create(self);
nqp::bindattr_s($obj, RakuAST::Var::Lexical, '$!name', $name);
nqp::bindattr($obj,RakuAST::Var::Lexical::Auto,'$!package',nqp::null);
$obj
}

method resolve-with(RakuAST::Resolver $resolver) {
my $resolved := $resolver.resolve-lexical(self.name);
unless $resolved {
nqp::bindattr(self, RakuAST::Var::Lexical::Auto, '$!package',
$resolver.current-package);
$resolved := RakuAST::VarDeclaration::Simple.new(
scope => "our", name => self.name
);
$resolver.declare-lexical($resolved);
}
self.set-resolution($resolved);
Nil
}

method IMPL-EXPR-QAST(RakuAST::IMPL::QASTContext $context) {
my $qast := self.resolution.IMPL-LOOKUP-QAST($context);
nqp::isnull($!package)
?? $qast
!! QAST::Stmts.new(
QAST::Op.new(:op('bind'),
QAST::Var.new(:scope('lexical'),:decl('var'),:name(self.name)),
QAST::Op.new(:op('callmethod'),:name('VIVIFY-KEY'),
QAST::Op.new(:op('who'),QAST::WVal.new(:value($!package))),
QAST::SVal.new(:value(self.name))
)
),
$qast
)
}
}

# A lexical variable lookup, but assumed to resolve to a compile time
# value.
class RakuAST::Var::Lexical::Constant
Expand Down
5 changes: 5 additions & 0 deletions src/Raku/ast/variable-declaration.rakumod
Expand Up @@ -925,6 +925,11 @@ class RakuAST::VarDeclaration::Simple
method needs-sink-call() { False }
}

# Subclass to mark that the declaration was automatically generated.
# Used in correctly raku-fying and deparsing
class RakuAST::VarDeclaration::Auto
is RakuAST::VarDeclaration::Simple { }

class RakuAST::VarDeclaration::Signature
is RakuAST::Declaration
is RakuAST::ImplicitLookups
Expand Down
4 changes: 4 additions & 0 deletions src/core.c/RakuAST/Deparse.pm6
Expand Up @@ -1984,6 +1984,10 @@ class RakuAST::Deparse {
!! "$scope $sigil"
}

multi method deparse(RakuAST::VarDeclaration::Auto:D $ast --> Str:D) {
self.deparse(RakuAST::Var::Lexical.new($ast.name))
}

multi method deparse(RakuAST::VarDeclaration::Constant:D $ast --> Str:D) {
my str @parts;

Expand Down
4 changes: 4 additions & 0 deletions src/core.c/RakuAST/Raku.pm6
Expand Up @@ -1054,6 +1054,10 @@ augment class RakuAST::Node {
self!nameds: <scope sigil type initializer>
}

multi method raku(RakuAST::VarDeclaration::Auto:D: --> Str:D) {
RakuAST::Var::Lexical.new(self.name).raku
}

multi method raku(RakuAST::VarDeclaration::Constant:D: --> Str:D) {
self!nameds: <scope type name traits initializer>
}
Expand Down

0 comments on commit 238931a

Please sign in to comment.