-
-
Save niner/05f73c3288e450b7712e723288c8d0f6 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/Perl6/Optimizer.nqp b/src/Perl6/Optimizer.nqp | |
index b19ba877a..874980cde 100644 | |
--- a/src/Perl6/Optimizer.nqp | |
+++ b/src/Perl6/Optimizer.nqp | |
@@ -45,6 +45,7 @@ my class Symbols { | |
has $!Seq; | |
has $!AST; | |
has $!LoweredAwayLexical; | |
+ has $!Positional; | |
# Top routine, for faking it when optimizing post-inline. | |
has $!fake_top_routine; | |
@@ -83,6 +84,7 @@ my class Symbols { | |
$!Seq := self.find_in_setting('Seq'); | |
$!AST := self.find_in_setting('AST'); | |
$!LoweredAwayLexical := self.find_symbol(['Rakudo', 'Internals', 'LoweredAwayLexical']); | |
+ $!Positional := self.find_in_setting('Positional'); | |
nqp::pop(@!block_stack); | |
} | |
@@ -136,6 +138,7 @@ my class Symbols { | |
method Seq() { $!Seq } | |
method AST() { $!AST } | |
method LoweredAwayLexical() { $!LoweredAwayLexical } | |
+ method Positional() { $!Positional } | |
# The following function is a nearly 1:1 copy of World.find_symbol. | |
# Finds a symbol that has a known value at compile time from the | |
@@ -3095,7 +3098,7 @@ class Perl6::Optimizer { | |
} | |
method optimize_array_variable_initialization($op) { | |
- my $Positional := $!symbols.find_in_setting('Positional'); | |
+ my $Positional := $!symbols.Positional; | |
if $op[0].returns =:= $Positional { | |
# Turns the @var.STORE(infix:<,>(...)) into: | |
# nqp::getattr( | |
@@ -3352,6 +3355,55 @@ class Perl6::Optimizer { | |
:protoguilt($ct_result_proto == -1) | |
) unless $*NO-COMPILE-TIME-THROWAGE; | |
} | |
+ else { | |
+ # Can't directly chose a multi candidate, but maybe still simplify refs | |
+ note(" checking for simplify refs") if $!debug; | |
+ my $call := $op; | |
+ my @args := $call.list; | |
+ my int $i := $call.name eq '' ?? 1 !! 0; | |
+ my int $n := nqp::elems(@args); | |
+ my int $p := 0; | |
+ #my @candidates := nqp::getattr(nqp::decont($obj), $!symbols.Routine, '@!dispatchees'); | |
+ my @candidates := $obj.possible_candidates(@types, @flags); | |
+ note(" found " ~ nqp::elems(@candidates) ~ " candidates") if $!debug; | |
+ while $i < $n { | |
+ my $arg := @args[$i]; | |
+ unless $arg.named || $arg.flat { | |
+ if nqp::istype($arg, QAST::Var) { | |
+ my str $scope := $arg.scope; | |
+ my int $lref := $scope eq 'lexicalref'; | |
+ my int $aref := $scope eq 'attributeref'; | |
+ if $lref || $aref { | |
+ my $lower := 1; | |
+ for @candidates -> $cand { | |
+ my $sig := $cand.signature; | |
+ #my $ct_result_cand := nqp::p6trialbind($sig, @types, @flags); | |
+ #next if $ct_result_cand == -1; | |
+ if nqp::iseq_n($sig.arity, $sig.count) { | |
+ my $param := nqp::getattr($sig, $!symbols.Signature, '@!params')[$p]; | |
+ if nqp::can($param, 'rw') && $param.rw { | |
+ note("not lowering $i because rw") if $!debug; | |
+ $lower := 0; | |
+ last; | |
+ } | |
+ } | |
+ else { | |
+ note("not lowering $i because arity " ~ $sig.arity ~ " != " ~ $sig.count) if $!debug; | |
+ $lower := 0; | |
+ last; | |
+ } | |
+ } | |
+ if $lower { | |
+ note("Lowering arg $i") if $!debug; | |
+ $arg.scope($lref ?? 'lexical' !! 'attribute'); | |
+ } | |
+ } | |
+ } | |
+ $p++; | |
+ } | |
+ $i++; | |
+ } | |
+ } | |
} | |
if $op.op eq 'chain' { $!chain_depth := $!chain_depth - 1 } | |
} | |
@@ -3477,6 +3529,45 @@ class Perl6::Optimizer { | |
} | |
} | |
+ elsif nqp::istype($var,QAST::Call) && $var.name eq '&postcircumfix:<[ ]>' { | |
+ if nqp::istype($var[0],QAST::Var) { | |
+ my $returns := $var[0].returns; | |
+ if nqp::istype($returns, $!symbols.Positional) && nqp::can($returns.HOW, 'role_arguments') { | |
+ my $slot_type := $returns.HOW.role_arguments($returns)[0]; | |
+ if ($primspec := nqp::objprimspec($slot_type)) { | |
+ if $primspec == 1 { | |
+ my $tmp := QAST::Node.unique: 'array_inc_'; | |
+ return QAST::Stmts.new: | |
+ QAST::Op.new(:op<bind>, | |
+ QAST::Var.new(:name($tmp), :scope<local>, :decl<var>, :returns($slot_type)), | |
+ QAST::Op.new(:op('atpos_i'), $var[0], $var[1]), | |
+ ), | |
+ QAST::Op.new(:op<bindpos_i>, $var[0], $var[1], | |
+ QAST::Op.new: :op('add_i'), | |
+ QAST::Var.new(:name($tmp), :scope<local>, :returns($slot_type)), | |
+ QAST::IVal.new: :value(1) | |
+ ), | |
+ QAST::Var.new(:name($tmp), :scope<local>, :returns($slot_type)); | |
+ } | |
+ elsif $primspec == 10 { | |
+ my $tmp := QAST::Node.unique: 'array_inc_'; | |
+ return QAST::Stmts.new: | |
+ QAST::Op.new(:op<bind>, | |
+ QAST::Var.new(:name($tmp), :scope<local>, :decl<var>, :returns($slot_type)), | |
+ QAST::Op.new(:op('atpos_u'), $var[0], $var[1]), | |
+ ), | |
+ QAST::Op.new(:op<bindpos_u>, $var[0], $var[1], | |
+ QAST::Op.new: :op('add_i'), | |
+ QAST::Var.new(:name($tmp), :scope<local>, :returns($slot_type)), | |
+ QAST::IVal.new: :value(1) | |
+ ), | |
+ QAST::Var.new(:name($tmp), :scope<local>, :returns($slot_type)); | |
+ } | |
+ } | |
+ } | |
+ } | |
+ } | |
+ | |
# XXX TODO: my tests show the opt below makes things 25% slower. | |
# Even without the temp var business, and unoptimized version: | |
# my $i = 1; my $z; { for ^10000_000 { $z = 1 + ++$i }; say now - ENTER now } | |
@@ -4457,6 +4548,7 @@ class Perl6::Optimizer { | |
# if we find them check if the expectation is for an non-rw argument. | |
method simplify_refs($call, $sig) { | |
if nqp::iseq_n($sig.arity, $sig.count) { | |
+ my @params := nqp::getattr($sig, $!symbols.Signature, '@!params'); | |
my @args := $call.list; | |
my int $i := $call.name eq '' ?? 1 !! 0; | |
my int $n := nqp::elems(@args); | |
@@ -4469,7 +4561,7 @@ class Perl6::Optimizer { | |
my int $lref := $scope eq 'lexicalref'; | |
my int $aref := $scope eq 'attributeref'; | |
if $lref || $aref { | |
- my $param := nqp::getattr($sig, $!symbols.Signature, '@!params')[$p]; | |
+ my $param := @params[$p]; | |
if nqp::can($param, 'rw') { | |
unless $param.rw { | |
$arg.scope($lref ?? 'lexical' !! 'attribute'); | |
diff --git a/src/Perl6/bootstrap.c/BOOTSTRAP.nqp b/src/Perl6/bootstrap.c/BOOTSTRAP.nqp | |
index 226e401ee..5e226ab99 100644 | |
--- a/src/Perl6/bootstrap.c/BOOTSTRAP.nqp | |
+++ b/src/Perl6/bootstrap.c/BOOTSTRAP.nqp | |
@@ -1098,11 +1098,17 @@ my class Binder { | |
nqp::getattr($param, Parameter, '@!post_constraints')) { | |
next | |
} | |
+ if $flags +& $SIG_ELEM_IS_CAPTURE | |
+ && nqp::isnull( | |
+ nqp::getattr($param, Parameter, '@!post_constraints')) { | |
+ return $TRIAL_BIND_OK; | |
+ } | |
if $flags +& nqp::bitneg_i( | |
$SIG_ELEM_MULTI_INVOCANT +| $SIG_ELEM_IS_RAW +| | |
$SIG_ELEM_IS_COPY +| $SIG_ELEM_ARRAY_SIGIL +| | |
$SIG_ELEM_HASH_SIGIL +| $SIG_ELEM_NATIVE_VALUE +| | |
- $SIG_ELEM_IS_OPTIONAL) || $flags +& $SIG_ELEM_IS_RW { | |
+ $SIG_ELEM_IS_OPTIONAL +| $SIG_ELEM_DEFINED_ONLY +| $SIG_ELEM_UNDEFINED_ONLY) || $flags +& $SIG_ELEM_IS_RW { | |
+ note(" bad flags") if $*DEBUG; | |
return $TRIAL_BIND_NOT_SURE; | |
} | |
unless nqp::isnull(nqp::getattr($param, Parameter, '@!named_names')) { | |
@@ -3434,6 +3440,181 @@ BEGIN { | |
# Otherwise, dunno...we'll have to find out at runtime. | |
return [$MD_CT_NOT_SURE, NQPMu]; | |
})); | |
+ Routine.HOW.add_method(Routine, 'possible_candidates', nqp::getstaticcode(sub ($self, @args, @flags) { | |
+ # Compile time dispatch result. | |
+ my $MD_CT_NOT_SURE := 0; # Needs a runtime dispatch. | |
+ my $MD_CT_DECIDED := 1; # Worked it out; see result. | |
+ my $MD_CT_NO_WAY := -1; # Proved it'd never manage to dispatch. | |
+ | |
+ # Other constants we need. | |
+ my int $DEFCON_DEFINED := 1; | |
+ my int $DEFCON_UNDEFINED := 2; | |
+ my int $DEFCON_MASK := $DEFCON_DEFINED +| $DEFCON_UNDEFINED; | |
+ my int $TYPE_NATIVE_INT := 4; | |
+ my int $TYPE_NATIVE_NUM := 8; | |
+ my int $TYPE_NATIVE_STR := 16; | |
+ my int $TYPE_NATIVE_UINT := 32; | |
+ my int $TYPE_NATIVE_MASK := $TYPE_NATIVE_INT +| $TYPE_NATIVE_UINT +| $TYPE_NATIVE_NUM +| $TYPE_NATIVE_STR; | |
+ my int $BIND_VAL_OBJ := 0; | |
+ my int $BIND_VAL_INT := 1; | |
+ my int $BIND_VAL_UINT := 10; | |
+ my int $BIND_VAL_NUM := 2; | |
+ my int $BIND_VAL_STR := 3; | |
+ my int $ARG_IS_LITERAL := 32; | |
+ | |
+ # Count arguments. | |
+ my int $num_args := nqp::elems(@args); | |
+ | |
+ # Get list and number of candidates, triggering a sort if there are none. | |
+ my $dcself := nqp::decont($self); | |
+ my @candidates := nqp::getattr($dcself, Routine, '@!dispatch_order'); | |
+ if nqp::isnull(@candidates) { | |
+ nqp::scwbdisable(); | |
+ @candidates := $dcself.'!sort_dispatchees_internal'(); | |
+ nqp::bindattr($dcself, Routine, '@!dispatch_order', @candidates); | |
+ nqp::scwbenable(); | |
+ } | |
+ | |
+ # Look through the candidates. If we see anything that needs a bind | |
+ # check or a definedness check, we can't decide it at compile time, | |
+ # so bail out immediately. | |
+ my int $all_native := 1; | |
+ my int $cur_idx := 0; | |
+ my int $seen_all := 0; | |
+ my int $arity_possible := 0; | |
+ my int $type_possible := 0; | |
+ my int $used_defcon; | |
+ my int $type_mismatch; | |
+ my int $type_check_count; | |
+ my int $type_match_possible; | |
+ my int $i; | |
+ my $cur_candidate; | |
+ my @possible; | |
+ my ¬e := nqp::gethllsym('nqp', 'note'); | |
+ while 1 { | |
+ $cur_candidate := nqp::atpos(@candidates, $cur_idx); | |
+ $used_defcon := 0; | |
+ | |
+ # Did we reach the end of a tied group? If so, note we can only | |
+ # consider the narrowest group, *unless* they are all natively | |
+ # typed candidates in which case we can look a bit further. | |
+ # We also exit if we found something. | |
+ unless nqp::isconcrete($cur_candidate) { | |
+ ++$cur_idx; | |
+ if nqp::isconcrete(nqp::atpos(@candidates, $cur_idx)) | |
+ && $all_native { | |
+ next; | |
+ } | |
+ else { | |
+ $seen_all := !nqp::isconcrete(nqp::atpos(@candidates, $cur_idx)); | |
+ last; | |
+ } | |
+ } | |
+ note("candidate $cur_idx file " ~ $cur_candidate<sub>.file ~ ":" ~ $cur_candidate<sub>.line) if $*DEBUG; | |
+ | |
+ # Check if it's admissible by arity. | |
+ if $num_args < nqp::atkey($cur_candidate, 'min_arity') | |
+ || $num_args > nqp::atkey($cur_candidate, 'max_arity') { | |
+ ++$cur_idx; | |
+ note(" wrong arity") if $*DEBUG; | |
+ next; | |
+ } | |
+ | |
+ # If we got this far, something at least matched on arity. | |
+ $arity_possible := 1; | |
+ | |
+ # Check if it's admissible by type. | |
+ $type_check_count := nqp::atkey($cur_candidate, 'num_types') > $num_args | |
+ ?? $num_args | |
+ !! nqp::atkey($cur_candidate, 'num_types'); | |
+ $type_mismatch := 0; | |
+ $type_match_possible := 1; | |
+ $i := -1; | |
+ while ++$i < $type_check_count { | |
+ my int $type_flags := nqp::atpos_i(nqp::atkey($cur_candidate, 'type_flags'), $i); | |
+ my int $got_prim := nqp::atpos(@flags, $i) +& 0xF; | |
+ if $type_flags +& $TYPE_NATIVE_MASK { | |
+ # Looking for a natively typed value. Did we get one? | |
+ if $got_prim == $BIND_VAL_OBJ { | |
+ # Object; won't do. | |
+ note(" arg $i got obj for native") if $*DEBUG; | |
+ $type_mismatch := 1; | |
+ $type_match_possible := 0; | |
+ last; | |
+ } | |
+ | |
+ # Yes, but does it have the right type? Also look at rw-ness for literals. | |
+ my int $literal := nqp::atpos(@flags, $i) +& $ARG_IS_LITERAL; | |
+ if (($type_flags +& $TYPE_NATIVE_INT) && $got_prim != $BIND_VAL_INT) | |
+ || (($type_flags +& $TYPE_NATIVE_UINT) && $got_prim != $BIND_VAL_UINT) | |
+ || (($type_flags +& $TYPE_NATIVE_NUM) && $got_prim != $BIND_VAL_NUM) | |
+ || (($type_flags +& $TYPE_NATIVE_STR) && $got_prim != $BIND_VAL_STR) | |
+ || ($literal && nqp::atpos_i(nqp::atkey($cur_candidate, 'rwness'), $i)) { | |
+ # Mismatch. | |
+ note(" arg $i wrong native") if $*DEBUG; | |
+ $type_mismatch := 1; | |
+ $type_match_possible := 0; | |
+ last; | |
+ } | |
+ } | |
+ else { | |
+ my $type_obj := nqp::atpos(nqp::atkey($cur_candidate, 'types'), $i); | |
+ | |
+ # Work out parameter. | |
+ my $param := | |
+ $got_prim == $BIND_VAL_OBJ ?? nqp::atpos(@args, $i) !! | |
+ $got_prim == $BIND_VAL_INT ?? Int !! | |
+ $got_prim == $BIND_VAL_UINT ?? Int !! | |
+ $got_prim == $BIND_VAL_NUM ?? Num !! | |
+ Str; | |
+ | |
+ # If we're here, it's a non-native. | |
+ $all_native := 0; | |
+ | |
+ # A literal won't work with rw parameter. | |
+ my int $literal := nqp::atpos(@flags, $i) +& $ARG_IS_LITERAL; | |
+ if $literal && nqp::atpos_i(nqp::atkey($cur_candidate, 'rwness'), $i) { | |
+ note(" arg $i wrong rwness") if $*DEBUG; | |
+ $type_mismatch := 1; | |
+ $type_match_possible := 0; | |
+ last; | |
+ } | |
+ } | |
+ } | |
+ if $type_match_possible { | |
+ note(" type possible") if $*DEBUG; | |
+ $type_possible := 1; | |
+ } | |
+ if $type_mismatch { | |
+ note(" type mismatch") if $*DEBUG; | |
+ ++$cur_idx; | |
+ next; | |
+ } | |
+ if ($used_defcon) { | |
+ note(" used defcon") if $*DEBUG; | |
+ nqp::push(@possible, nqp::atkey($cur_candidate, 'sub')); | |
+ ++$cur_idx; | |
+ next; | |
+ } | |
+ | |
+ # If it's possible but needs a bind check, we're not going to be | |
+ # able to decide it. | |
+ if nqp::existskey($cur_candidate, 'bind_check') { | |
+ note(" used bind_check") if $*DEBUG; | |
+ nqp::push(@possible, nqp::atkey($cur_candidate, 'sub')); | |
+ ++$cur_idx; | |
+ next; | |
+ } | |
+ | |
+ # If we get here, it's the result. Well, unless we already had one, | |
+ # in which case we're in bother 'cus we don't know how to disambiguate | |
+ # at compile time. | |
+ note(" adding") if $*DEBUG; | |
+ nqp::push(@possible, nqp::atkey($cur_candidate, 'sub')); | |
+ ++$cur_idx; | |
+ } | |
+ return @possible; | |
+ })); | |
Routine.HOW.add_method(Routine, 'set_flag', nqp::getstaticcode(sub ($self, $bit) { | |
my $dcself := nqp::decont($self); | |
nqp::bindattr_i($dcself, Routine, '$!flags', | |
diff --git a/src/core.c/Int.pm6 b/src/core.c/Int.pm6 | |
index 89b6c793f..2f389d479 100644 | |
--- a/src/core.c/Int.pm6 | |
+++ b/src/core.c/Int.pm6 | |
@@ -313,14 +313,20 @@ multi sub abs(int $a --> int) { | |
multi sub infix:<+>(Int:D $a, Int:D $b --> Int:D) { nqp::add_I($a,$b,Int) } | |
multi sub infix:<+>(int $a, int $b --> int) { nqp::add_i($a,$b) } | |
+multi sub infix:<+>(int $a, uint $b --> int) { nqp::add_i($a,$b) } | |
+multi sub infix:<+>(uint $a, int $b --> int) { nqp::add_i($a,$b) } | |
multi sub infix:<+>(uint $a, uint $b --> uint) { nqp::add_i($a,$b) } | |
multi sub infix:<->(Int:D $a, Int:D $b --> Int:D) { nqp::sub_I($a,$b,Int) } | |
multi sub infix:<->(int $a, int $b --> int) { nqp::sub_i($a,$b) } | |
+multi sub infix:<->(int $a, uint $b --> int) { nqp::sub_i($a,$b) } | |
+multi sub infix:<->(uint $a, int $b --> int) { nqp::sub_i($a,$b) } | |
multi sub infix:<->(uint $a, uint $b --> uint) { nqp::sub_i($a,$b) } | |
multi sub infix:<*>(Int:D $a, Int:D $b --> Int:D) { nqp::mul_I($a,$b,Int) } | |
multi sub infix:<*>(int $a, int $b --> int) { nqp::mul_i($a,$b) } | |
+multi sub infix:<*>(int $a, uint $b --> int) { nqp::mul_i($a,$b) } | |
+multi sub infix:<*>(uint $a, int $b --> int) { nqp::mul_i($a,$b) } | |
multi sub infix:<*>(uint $a, uint $b --> uint) { nqp::mul_i($a,$b) } | |
multi sub infix:<eqv>(Int:D $a, Int:D $b --> Bool:D) { | |
@@ -443,6 +449,9 @@ multi sub infix:«<=»(Int:D $a, Int:D $b --> Bool:D) { | |
multi sub infix:«<=»(int $a, int $b --> Bool:D) { | |
nqp::hllbool(nqp::isle_i($a,$b)) | |
} | |
+multi sub infix:«<=»(uint $a, uint $b --> Bool:D) { | |
+ nqp::hllbool(nqp::isle_i($a,$b)) | |
+} | |
multi sub infix:«>»(Int:D $a, Int:D $b --> Bool:D) { | |
nqp::hllbool(nqp::isgt_I($a,$b)) | |
diff --git a/src/core.c/native_array.pm6 b/src/core.c/native_array.pm6 | |
index 387cb798d..d59250459 100644 | |
--- a/src/core.c/native_array.pm6 | |
+++ b/src/core.c/native_array.pm6 | |
@@ -4883,9 +4883,15 @@ multi sub postcircumfix:<[ ]>(array:D \SELF, Range:D \range ) is raw { | |
} | |
#- start of postcircumfix candidates of strarray ------------------------------- | |
-#- Generated on 2022-02-03T19:03:07+01:00 by tools/build/makeNATIVE_CANDIDATES.raku | |
+#- Generated on 2022-02-06T14:35:26+01:00 by tools/build/makeNATIVE_CANDIDATES.raku | |
#- PLEASE DON'T CHANGE ANYTHING BELOW THIS LINE | |
+multi sub postcircumfix:<[ ]>( | |
+ array::strarray:D \SELF, uint $pos | |
+) is raw { | |
+ nqp::atposref_s(nqp::decont(SELF),$pos) | |
+} | |
+ | |
multi sub postcircumfix:<[ ]>( | |
array::strarray:D \SELF, Int:D $pos | |
) is raw { | |
@@ -5135,9 +5141,15 @@ multi sub infix:<cmp>(array::strarray:D \a, array::strarray:D \b) { | |
#- end of postcircumfix candidates of strarray --------------------------------- | |
#- start of postcircumfix candidates of numarray ------------------------------- | |
-#- Generated on 2022-02-03T19:03:07+01:00 by tools/build/makeNATIVE_CANDIDATES.raku | |
+#- Generated on 2022-02-06T14:35:26+01:00 by tools/build/makeNATIVE_CANDIDATES.raku | |
#- PLEASE DON'T CHANGE ANYTHING BELOW THIS LINE | |
+multi sub postcircumfix:<[ ]>( | |
+ array::numarray:D \SELF, uint $pos | |
+) is raw { | |
+ nqp::atposref_n(nqp::decont(SELF),$pos) | |
+} | |
+ | |
multi sub postcircumfix:<[ ]>( | |
array::numarray:D \SELF, Int:D $pos | |
) is raw { | |
@@ -5387,9 +5399,15 @@ multi sub infix:<cmp>(array::numarray:D \a, array::numarray:D \b) { | |
#- end of postcircumfix candidates of numarray --------------------------------- | |
#- start of postcircumfix candidates of intarray ------------------------------- | |
-#- Generated on 2022-02-03T19:03:07+01:00 by tools/build/makeNATIVE_CANDIDATES.raku | |
+#- Generated on 2022-02-06T14:35:26+01:00 by tools/build/makeNATIVE_CANDIDATES.raku | |
#- PLEASE DON'T CHANGE ANYTHING BELOW THIS LINE | |
+multi sub postcircumfix:<[ ]>( | |
+ array::intarray:D \SELF, uint $pos | |
+) is raw { | |
+ nqp::atposref_i(nqp::decont(SELF),$pos) | |
+} | |
+ | |
multi sub postcircumfix:<[ ]>( | |
array::intarray:D \SELF, Int:D $pos | |
) is raw { | |
@@ -5639,9 +5657,15 @@ multi sub infix:<cmp>(array::intarray:D \a, array::intarray:D \b) { | |
#- end of postcircumfix candidates of intarray --------------------------------- | |
#- start of postcircumfix candidates of uintarray ------------------------------- | |
-#- Generated on 2022-02-03T19:03:07+01:00 by tools/build/makeNATIVE_CANDIDATES.raku | |
+#- Generated on 2022-02-06T14:35:26+01:00 by tools/build/makeNATIVE_CANDIDATES.raku | |
#- PLEASE DON'T CHANGE ANYTHING BELOW THIS LINE | |
+multi sub postcircumfix:<[ ]>( | |
+ array::uintarray:D \SELF, uint $pos | |
+) is raw { | |
+ nqp::atposref_u(nqp::decont(SELF),$pos) | |
+} | |
+ | |
multi sub postcircumfix:<[ ]>( | |
array::uintarray:D \SELF, Int:D $pos | |
) is raw { | |
diff --git a/tools/build/makeNATIVE_CANDIDATES.raku b/tools/build/makeNATIVE_CANDIDATES.raku | |
index f11361e58..0d2d5db9c 100755 | |
--- a/tools/build/makeNATIVE_CANDIDATES.raku | |
+++ b/tools/build/makeNATIVE_CANDIDATES.raku | |
@@ -53,6 +53,12 @@ while @lines { | |
# spurt the candidates | |
say Q:to/SOURCE/.subst(/ '#' (\w+) '#' /, -> $/ { %mapper{$0} }, :g).chomp; | |
+multi sub postcircumfix:<[ ]>( | |
+ array::#type#array:D \SELF, uint $pos | |
+) is raw { | |
+ nqp::atposref_#postfix#(nqp::decont(SELF),$pos) | |
+} | |
+ | |
multi sub postcircumfix:<[ ]>( | |
array::#type#array:D \SELF, Int:D $pos | |
) is raw { |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment