-
-
Save niner/0422e5ca8a00c70582e88273717f787b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/Raku/Grammar.nqp b/src/Raku/Grammar.nqp | |
index cfafe42d9..596f961d3 100644 | |
--- a/src/Raku/Grammar.nqp | |
+++ b/src/Raku/Grammar.nqp | |
@@ -1625,6 +1625,7 @@ grammar Raku::Grammar is HLL::Grammar does Raku::Common { | |
token scope_declarator:sym<HAS> { <sym> <scoped('HAS')> } | |
token scope_declarator:sym<anon> { <sym> <scoped('anon')> } | |
token scope_declarator:sym<state> { <sym> <scoped('state')> } | |
+ token scope_declarator:sym<unit> { <sym> <scoped('unit')> } | |
token scoped($*SCOPE) { | |
<.end_keyword> | |
diff --git a/src/Raku/ast/scoping.rakumod b/src/Raku/ast/scoping.rakumod | |
index 34760b2a0..9603dea07 100644 | |
--- a/src/Raku/ast/scoping.rakumod | |
+++ b/src/Raku/ast/scoping.rakumod | |
@@ -469,7 +469,7 @@ class RakuAST::Lookup is RakuAST::Node { | |
method resolution() { | |
nqp::isconcrete($!resolution) | |
?? $!resolution | |
- !! nqp::die('This element has not been resolved. Type: ' ~ self.HOW.name(self)) | |
+ !! nqp::die('This element ' ~ self ~ ' has not been resolved. Type: ' ~ self.HOW.name(self)) | |
} | |
method set-resolution(RakuAST::Declaration $resolution) { | |
diff --git a/src/Raku/ast/signature.rakumod b/src/Raku/ast/signature.rakumod | |
index 849fffa7c..fc8838ae4 100644 | |
--- a/src/Raku/ast/signature.rakumod | |
+++ b/src/Raku/ast/signature.rakumod | |
@@ -149,12 +149,13 @@ class RakuAST::Parameter is RakuAST::Meta is RakuAST::Attaching | |
has Mu $!names; | |
has Bool $.invocant; | |
has Bool $!optional; | |
+ has Bool $!hllize; | |
has RakuAST::Parameter::Slurpy $.slurpy; | |
has RakuAST::Expression $.default; | |
has RakuAST::Node $!owner; | |
method new(RakuAST::Type :$type, RakuAST::ParameterTarget :$target, | |
- List :$names, Bool :$invocant, Bool :$optional, | |
+ List :$names, Bool :$invocant, Bool :$optional, Bool :$hllize, | |
RakuAST::Parameter::Slurpy :$slurpy, List :$traits, | |
RakuAST::Expression :$default) { | |
my $obj := nqp::create(self); | |
@@ -165,6 +166,7 @@ class RakuAST::Parameter is RakuAST::Meta is RakuAST::Attaching | |
nqp::bindattr($obj, RakuAST::Parameter, '$!optional', nqp::defined($optional) | |
?? ($optional ?? True !! False) | |
!! Bool); | |
+ nqp::bindattr($obj, RakuAST::Parameter, '$!hllize', nqp::defined($hllize) ?? ($hllize ?? True !! False) !! True); | |
nqp::bindattr($obj, RakuAST::Parameter, '$!slurpy', | |
nqp::istype($slurpy, RakuAST::Parameter::Slurpy) | |
?? $slurpy | |
@@ -278,9 +280,10 @@ class RakuAST::Parameter is RakuAST::Meta is RakuAST::Attaching | |
elsif $sigil eq '%' { $sigil-type := 'Associative' } | |
elsif $sigil eq '&' { $sigil-type := 'Callable' } | |
else { $sigil-type := '' } | |
- self.IMPL-WRAP-LIST($sigil-type | |
+ my @lookups := $sigil-type | |
?? [RakuAST::Type::Setting.new(RakuAST::Name.from-identifier($sigil-type))] | |
- !! []) | |
+ !! []; | |
+ self.IMPL-WRAP-LIST(@lookups) | |
} | |
method PRODUCE-META-OBJECT() { | |
@@ -331,7 +334,7 @@ class RakuAST::Parameter is RakuAST::Meta is RakuAST::Attaching | |
method IMPL-NOMINAL-TYPE() { | |
my str $sigil := $!target.sigil; | |
- if $sigil eq '@' || $sigil eq '%' || $sigil eq '&' { | |
+ if $!hllize && ($sigil eq '@' || $sigil eq '%' || $sigil eq '&') { | |
my @lookups := self.IMPL-UNWRAP-LIST(self.get-implicit-lookups()); | |
my $sigil-type := @lookups[0].resolution.compile-time-value; | |
$!type | |
@@ -398,15 +401,15 @@ class RakuAST::Parameter is RakuAST::Meta is RakuAST::Attaching | |
if $!names { | |
$param-qast.named(nqp::elems($!names) == 1 ?? $!names[0] !! $!names); | |
} | |
- elsif !($!slurpy =:= RakuAST::Parameter::Slurpy) { | |
+ if !($!slurpy =:= RakuAST::Parameter::Slurpy) { | |
$!slurpy.IMPL-TRANSFORM-PARAM-QAST($context, $param-qast, $temp-qast-var, | |
- $!target.sigil, @prepend); | |
+ $!target.sigil, @prepend, $!hllize); | |
$was-slurpy := 1; | |
} | |
# HLLize before type checking unless it was a slurpy (in which | |
# case we know full well what we produced). | |
- unless $was-slurpy { | |
+ if !$was-slurpy && $!hllize { | |
$param-qast.push(QAST::Op.new( | |
:op('bind'), | |
$temp-qast-var, | |
@@ -606,7 +609,7 @@ class RakuAST::Parameter::Slurpy { | |
} | |
method IMPL-TRANSFORM-PARAM-QAST(RakuAST::IMPL::QASTContext $context, | |
- Mu $param-qast, Mu $temp-qast, str $sigil, @prepend) { | |
+ Mu $param-qast, Mu $temp-qast, str $sigil, @prepend, $hllize) { | |
# Not slurply, so nothing to do | |
$param-qast | |
} | |
@@ -636,7 +639,7 @@ class RakuAST::Parameter::Slurpy::Flattened is RakuAST::Parameter::Slurpy { | |
} | |
method IMPL-TRANSFORM-PARAM-QAST(RakuAST::IMPL::QASTContext $context, | |
- Mu $param-qast, Mu $temp-qast, str $sigil, @prepend) { | |
+ Mu $param-qast, Mu $temp-qast, str $sigil, @prepend, $hllize) { | |
if $sigil eq '@' { | |
self.IMPL-QAST-LISTY-SLURP($param-qast, $temp-qast, Array, 'from-slurpy-flat'); | |
} | |
@@ -656,7 +659,7 @@ class RakuAST::Parameter::Slurpy::Flattened is RakuAST::Parameter::Slurpy { | |
QAST::SVal.new( :value('$!storage') ), | |
$temp-qast | |
) | |
- )); | |
+ )) if $hllize; | |
} | |
else { | |
nqp::die("Parameter * quantifier not applicable to sigil '$sigil'"); | |
@@ -672,7 +675,7 @@ class RakuAST::Parameter::Slurpy::Unflattened is RakuAST::Parameter::Slurpy { | |
} | |
method IMPL-TRANSFORM-PARAM-QAST(RakuAST::IMPL::QASTContext $context, | |
- Mu $param-qast, Mu $temp-qast, str $sigil, @prepend) { | |
+ Mu $param-qast, Mu $temp-qast, str $sigil, @prepend, $hllize) { | |
if $sigil eq '@' { | |
self.IMPL-QAST-LISTY-SLURP($param-qast, $temp-qast, Array, 'from-slurpy'); | |
} | |
@@ -690,7 +693,7 @@ class RakuAST::Parameter::Slurpy::SingleArgument is RakuAST::Parameter::Slurpy { | |
} | |
method IMPL-TRANSFORM-PARAM-QAST(RakuAST::IMPL::QASTContext $context, | |
- Mu $param-qast, Mu $temp-qast, str $sigil, @prepend) { | |
+ Mu $param-qast, Mu $temp-qast, str $sigil, @prepend, $hllize) { | |
if $sigil eq '@' || $sigil eq '' { | |
self.IMPL-QAST-LISTY-SLURP($param-qast, $temp-qast, Array, 'from-slurpy-onearg'); | |
} | |
@@ -708,7 +711,7 @@ class RakuAST::Parameter::Slurpy::Capture is RakuAST::Parameter::Slurpy { | |
} | |
method IMPL-TRANSFORM-PARAM-QAST(RakuAST::IMPL::QASTContext $context, | |
- Mu $param-qast, Mu $temp-qast, str $sigil, @prepend) { | |
+ Mu $param-qast, Mu $temp-qast, str $sigil, @prepend, $hllize) { | |
# Sneak in a slurpy hash parameter too. | |
$param-qast.slurpy(1); | |
my $hash-param-name := $temp-qast.name ~ '_hash'; | |
diff --git a/src/Raku/ast/statements.rakumod b/src/Raku/ast/statements.rakumod | |
index 7440ff597..0d72d2205 100644 | |
--- a/src/Raku/ast/statements.rakumod | |
+++ b/src/Raku/ast/statements.rakumod | |
@@ -1123,6 +1123,15 @@ class RakuAST::Statement::Use is RakuAST::Statement is RakuAST::BeginTime | |
} | |
True | |
} | |
+ elsif $name eq 'MONKEY-SEE-NO-EVAL' { | |
+ True | |
+ } | |
+ elsif $name eq 'MONKEY-GUTS' { | |
+ True | |
+ } | |
+ elsif $name eq 'nqp' { | |
+ True | |
+ } | |
else { | |
False | |
} | |
diff --git a/src/core.c/Compiler.pm6 b/src/core.c/Compiler.pm6 | |
index 77fd3c1bf..8a1b67160 100644 | |
--- a/src/core.c/Compiler.pm6 | |
+++ b/src/core.c/Compiler.pm6 | |
@@ -31,6 +31,14 @@ class Compiler does Systemic { | |
multi method id(Compiler:U:) { nqp::ifnull(nqp::atkey($compiler,'id'),$id) } | |
multi method id(Compiler:D:) { $!id } | |
+ method compile(|a) { | |
+ nqp::getcomp("Raku").compile(|a) | |
+ } | |
+ | |
+ method qast(|a) { | |
+ nqp::getcomp("Raku").qast(|a) | |
+ } | |
+ | |
method verbose-config(:$say) { | |
my $compiler := nqp::getcomp("Raku"); | |
my $backend := $compiler.backend; | |
diff --git a/src/vm/moar/dispatchers.nqp b/src/vm/moar/dispatchers.nqp | |
index e0037af5f..abf8b66c4 100644 | |
--- a/src/vm/moar/dispatchers.nqp | |
+++ b/src/vm/moar/dispatchers.nqp | |
@@ -1561,6 +1561,24 @@ sub simple-args-proto($callee, $capture) { | |
return nqp::capturehasnameds($capture) ?? $accepts-any-named !! 1; | |
} | |
+class DispatchASTNode { | |
+ has @!args; | |
+ method push($arg) { | |
+ nqp::push(@!args, $arg); | |
+ } | |
+ method IMPL-TO-QAST(RakuAST::IMPL::QASTContext $context) { | |
+ QAST::Op.new: | |
+ :op('dispatch'), | |
+ QAST::SVal.new( :value('boot-resume') ), | |
+ QAST::IVal.new( :value(nqp::const::DISP_DECONT) ), | |
+ |@!args; | |
+ } | |
+ method IMPL-CHECK($resolver, $resolve-only) { | |
+ } | |
+ method visit-children($visitor) { | |
+ } | |
+} | |
+ | |
# We we invoke a multi with an argument that is a Proxy (or some other non-Scalar | |
# container), we need to read the value(s) from the Proxy argument(s) and then go | |
# on with the dispatch. The ProxyReaderFactory produces code objects that do | |
@@ -1596,27 +1614,12 @@ class ProxyReaderFactory { | |
} | |
method !produce-reader($num-args, $has-nameds, $indices) { | |
- # Create a block taking each positional arg required, adding an | |
- # slurpy named if needed. | |
- my $block := QAST::Block.new(:is_thunk); | |
+# # Produce a dispatch op with the required arguments decontainerized. | |
+ my $dispatch := DispatchASTNode.new; | |
my int $i := 0; | |
- while $i < $num-args { | |
- $block.push(QAST::Var.new( :name("a$i"), :decl<param>, :scope<local> )); | |
- $i++; | |
- } | |
- if $has-nameds { | |
- $block.push(QAST::Var.new( :name<n>, :decl<param>, :scope<local>, :named, :slurpy )); | |
- } | |
- | |
- # Produce a dispatch op with the required arguments decontainerized. | |
- my $dispatch := QAST::Op.new: | |
- :op('dispatch'), | |
- QAST::SVal.new( :value('boot-resume') ), | |
- QAST::IVal.new( :value(nqp::const::DISP_DECONT) ); | |
- $i := 0; | |
my $decont-index := 0; | |
while $i < $num-args { | |
- my $var := QAST::Var.new( :name("a$i"), :scope<local> ); | |
+ my $var := QAST::Var.new( :name("a$i"), :scope<lexical> ); | |
if nqp::atpos_i($indices, $decont-index) == $i { | |
$dispatch.push(QAST::Op.new( :op<decont>, $var )); | |
$decont-index++; | |
@@ -1627,19 +1630,78 @@ class ProxyReaderFactory { | |
$i++; | |
} | |
if $has-nameds { | |
- $dispatch.push(QAST::Var.new( :name<n>, :scope<local>, :named, :flat )); | |
+ $dispatch.push(QAST::Var.new( :name<%n>, :scope<lexical>, :named, :flat )); | |
} | |
- $block.push($dispatch); | |
+ | |
+ # Create a block taking each positional arg required, adding an | |
+ # slurpy named if needed. | |
+ my @parameters; | |
+ $i := 0; | |
+ while $i < $num-args { | |
+ nqp::push(@parameters, | |
+ RakuAST::Parameter.new( | |
+ target => RakuAST::ParameterTarget::Var.new("a$i"), | |
+ hllize => 0, | |
+ ), | |
+ ); | |
+ $i++; | |
+ } | |
+ if $has-nameds { | |
+ nqp::push(@parameters, | |
+ RakuAST::Parameter.new( | |
+ target => RakuAST::ParameterTarget::Var.new('%n'), | |
+ names => ['%n'], | |
+ optional => 0, | |
+ hllize => 0, | |
+ slurpy => RakuAST::Parameter::Slurpy::Flattened, | |
+ ), | |
+ ); | |
+ } | |
+ | |
+ my $block := RakuAST::PointyBlock.new( | |
+ signature => RakuAST::Signature.new( | |
+ parameters => @parameters, | |
+ ), | |
+ body => RakuAST::Blockoid.new( | |
+ RakuAST::StatementList.new( | |
+ RakuAST::Statement::Expression.new( | |
+ expression => $dispatch, | |
+ ), | |
+ ), | |
+ ), | |
+ ); | |
+ my $compunit := RakuAST::CompUnit.new( | |
+ :!eval, | |
+ :comp-unit-name('proxy-reader'), | |
+ :statement-list(RakuAST::StatementList.new( | |
+ RakuAST::Statement::Expression.new( | |
+ expression => $block, | |
+ ), | |
+ )) | |
+ ); | |
+ | |
+ my $ctx := nqp::ctxcaller(nqp::ctx()); | |
+ my $core-rev-sym := 'CORE-SETTING-REV'; | |
+ while nqp::isnull(nqp::getlexrel($ctx, $core-rev-sym)) { | |
+ $ctx := nqp::ctxcaller($ctx); | |
+ } | |
+ my $resolver := RakuAST::Resolver::EVAL.new( | |
+ :context($ctx), | |
+ :global(GLOBAL), | |
+ ); | |
+ nqp::gethllsym('nqp', 'note')('checking...'); | |
+ $compunit.check($resolver); | |
# Compile and return it. | |
- nqp::getcomp('Raku').compile($block, :from<optimize>) | |
+ my $res := nqp::getcomp('Raku').compile($compunit, :from<ast>)(); | |
+ nqp::getattr($res, Code, '$!do') | |
} | |
} | |
my $PROXY-READERS := ProxyReaderFactory.new; | |
nqp::bindhllsym('Raku', 'PROXY-READERS', $PROXY-READERS); | |
# The core of multi dispatch. Once we are here, either there was a simple | |
-# proto that we don't need to inovke, or we already did invoke the proto. | |
+# proto that we don't need to invoke, or we already did invoke the proto. | |
# | |
# Multiple dispatch is relatively complex in the most general case. However, | |
# the most common case by far consists of: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment