Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Draft of fixing some routines not doing Callable role
Was working out OK, until hitting this issue:
Any.^lookup('EXISTS-KEY').^compose;
say Iterator.^lookup('EXISTS-KEY') ~~ Callable; # False

So not only we need to recompose methods, but also need to
go through kids and recompose them...
  • Loading branch information
zoffixznet committed Mar 7, 2018
1 parent 5feb6bb commit 3506395
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 70 deletions.
4 changes: 0 additions & 4 deletions src/core/Any-iterable-methods.pm6
Expand Up @@ -1955,10 +1955,6 @@ multi sub infix:<min>(Num:D \a, Num:D \b) { nqp::if(nqp::islt_i(nqp::cmp_n(a, b)
multi sub infix:<min>(num \a, num \b) { nqp::if(nqp::islt_i(nqp::cmp_n(a, b), 0), a, b) }
multi sub infix:<min>(+args is raw) { args.min }

proto sub min(|) is pure {*}
multi sub min(+args, :&by!) { args.min(&by) }
multi sub min(+args) { args.min }

proto sub infix:<max>(|) is pure {*}
multi sub infix:<max>(Mu:D \a, Mu:U) { a }
multi sub infix:<max>(Mu:U, Mu:D \b) { b }
Expand Down
70 changes: 5 additions & 65 deletions src/core/Mu.pm6
Expand Up @@ -55,7 +55,7 @@ my class Mu { # declared in BOOTSTRAP
}

proto method split(|) {*}
proto method splice(|) is nodal {*}
proto method splice(|) is nodal {*} # TRAITED in traited-routines.pm6

method emit {
emit self;
Expand Down Expand Up @@ -871,8 +871,10 @@ Perhaps it can be found at https://docs.perl6.org/type/$name"
nqp::can($nodality, 'nodal')),
nqp::if(
c,
HYPER( sub (\obj) is nodal { obj."$meth-name"(|c) }, SELF ),
HYPER( sub (\obj) is nodal { obj."$meth-name"() }, SELF )),
HYPER( sub (\obj) is nodal { # IGNORE for traited-routines.pm6 test
obj."$meth-name"(|c) }, SELF ),
HYPER( sub (\obj) is nodal { # IGNORE for traited-routines.pm6 test
obj."$meth-name"() }, SELF )),
nqp::if(
c,
HYPER( -> \obj { obj."$meth-name"(|c) }, SELF ),
Expand Down Expand Up @@ -947,10 +949,6 @@ Perhaps it can be found at https://docs.perl6.org/type/$name"
}
}


proto sub defined(Mu) is pure {*}
multi sub defined(Mu \x) { x.defined }

proto sub infix:<~~>(Mu \topic, Mu \matcher) {*}
multi sub infix:<~~>(Mu \topic, Mu \matcher) {
matcher.ACCEPTS(topic).Bool;
Expand All @@ -961,64 +959,6 @@ multi sub infix:<!~~>(Mu \topic, Mu \matcher) {
matcher.ACCEPTS(topic).not;
}

proto sub infix:<=:=>(Mu $?, Mu $?) is pure {*}
multi sub infix:<=:=>($?) { Bool::True }
multi sub infix:<=:=>(Mu \a, Mu \b) {
nqp::p6bool(nqp::eqaddr(a, b));
}

proto sub infix:<eqv>(Any $?, Any $?) is pure {*}
multi sub infix:<eqv>($?) { Bool::True }

# Last ditch snapshot semantics. We shouldn't come here too often, so
# please do not change this to be faster but wronger. (Instead, add
# specialized multis for datatypes that can be tested piecemeal.)
multi sub infix:<eqv>(Any:U \a, Any:U \b) {
nqp::p6bool(nqp::eqaddr(nqp::decont(a),nqp::decont(b)))
}
multi sub infix:<eqv>(Any:D \a, Any:U \b) { False }
multi sub infix:<eqv>(Any:U \a, Any:D \b) { False }
multi sub infix:<eqv>(Any:D \a, Any:D \b) {
nqp::p6bool(
nqp::eqaddr(a,b)
|| (nqp::eqaddr(a.WHAT,b.WHAT) && nqp::iseq_s(a.perl,b.perl))
)
}

multi sub infix:<eqv>(Iterable:D \a, Iterable:D \b) {
nqp::p6bool(
nqp::unless(
nqp::eqaddr(nqp::decont(a),nqp::decont(b)),
nqp::if( # not same object
nqp::eqaddr(a.WHAT,b.WHAT),
nqp::if( # same type
a.is-lazy,
nqp::if( # a lazy
b.is-lazy,
die(X::Cannot::Lazy.new: :action<eqv>) # a && b lazy
),
nqp::if( # a NOT lazy
b.is-lazy,
0, # b lazy
nqp::if( # a && b NOT lazy
nqp::iseq_i((my int $elems = a.elems),b.elems),
nqp::stmts( # same # elems
(my int $i = -1),
nqp::while(
nqp::islt_i(($i = nqp::add_i($i,1)),$elems) # not exhausted
&& a.AT-POS($i) eqv b.AT-POS($i), # still same
nqp::null
),
nqp::iseq_i($i,$elems) # exhausted = success!
)
)
)
)
)
)
)
}

sub DUMP(|args (*@args, :$indent-step = 4, :%ctx?)) {
my Mu $capture := nqp::usecapture();
my Mu $topic := nqp::captureposarg($capture, 0);
Expand Down
89 changes: 89 additions & 0 deletions src/core/traited-routines.pm6
@@ -0,0 +1,89 @@

# In core, we can't use traits that mixin roles into routines before
# Callable and all the types that use that role have already been composed.
# This file is to keep such routines, if otherwise they'd go to some earlier
# place in the setting. Issue: https://github.com/rakudo/rakudo/issues/1566

{ # "If the method won't come to the Muhammad, Muhammad will… use a hack."
# We poke into types, looking for routines we marked with traits earlier
# and recompose them so that `Callable` role becomes visible correctly.
my @recompose = Mu => <splice>, Any => <EXISTS-KEY>;
for @recompose {
my \T := .key;
T.^lookup($_).^compose for .values;
}
}

# From Mu.pm6
proto sub defined(Mu) is pure {*}
multi sub defined(Mu \x) { x.defined }

proto sub infix:<=:=>(Mu $?, Mu $?) is pure {*}
multi sub infix:<=:=>($?) { Bool::True }
multi sub infix:<=:=>(Mu \a, Mu \b) {
nqp::p6bool(nqp::eqaddr(a, b));
}
proto sub infix:<eqv>(Any $?, Any $?) is pure {*}
multi sub infix:<eqv>($?) { Bool::True }
# Last ditch snapshot semantics. We shouldn't come here too often, so
# please do not change this to be faster but wronger. (Instead, add
# specialized multis for datatypes that can be tested piecemeal.)
multi sub infix:<eqv>(Any:U \a, Any:U \b) {
nqp::p6bool(nqp::eqaddr(nqp::decont(a),nqp::decont(b)))
}
multi sub infix:<eqv>(Any:D \a, Any:U \b) { False }
multi sub infix:<eqv>(Any:U \a, Any:D \b) { False }
multi sub infix:<eqv>(Any:D \a, Any:D \b) {
nqp::p6bool(
nqp::eqaddr(a,b)
|| (nqp::eqaddr(a.WHAT,b.WHAT) && nqp::iseq_s(a.perl,b.perl))
)
}

multi sub infix:<eqv>(Iterable:D \a, Iterable:D \b) {
nqp::p6bool(
nqp::unless(
nqp::eqaddr(nqp::decont(a),nqp::decont(b)),
nqp::if( # not same object
nqp::eqaddr(a.WHAT,b.WHAT),
nqp::if( # same type
a.is-lazy,
nqp::if( # a lazy
b.is-lazy,
die(X::Cannot::Lazy.new: :action<eqv>) # a && b lazy
),
nqp::if( # a NOT lazy
b.is-lazy,
0, # b lazy
nqp::if( # a && b NOT lazy
nqp::iseq_i((my int $elems = a.elems),b.elems),
nqp::stmts( # same # elems
(my int $i = -1),
nqp::while(
nqp::islt_i(($i = nqp::add_i($i,1)),$elems) # not exhausted
&& a.AT-POS($i) eqv b.AT-POS($i), # still same
nqp::null
),
nqp::iseq_i($i,$elems) # exhausted = success!
)
)
)
)
)
)
)
}


# From Stringy.pm6


# From Any.pm6



# From Any-iterable-methods.pm6

proto sub min(|) is pure {*}
multi sub min(+args, :&by!) { args.min(&by) }
multi sub min(+args) { args.min }
40 changes: 40 additions & 0 deletions t/02-rakudo/00-misc.t
@@ -0,0 +1,40 @@
use Test;
plan 1;

# https://github.com/rakudo/rakudo/issues/1566
subtest 'role-applying traits on SETTING routines are late enough (R#1566)' => {
# To fix failures in this test, move all routines that have role-applying
# traits on them into src/core/traited-routines.pm6 or any place later
# in the setting

plan 2;
for <tools/build/moar_core_sources tools/build/jvm_core_sources> -> $list {
subtest "$list source list" => {
plan +my @sources = $list.IO.lines.grep: {
# file all source files before and including all the code files
state $code-files = SetHash.new: <
src/core/Code.pm6
src/core/Routine.pm6
src/core/Block.pm6
src/core/Submethod.pm6
src/core/Method.pm6
>;
LEAVE $code-files{$_}--;
$code-files
}

for @sources -> $file {
my @seen;
for $file.IO.lines.kv -> $n, $line {
next unless $line.contains:
any «'is pure' 'is nodal' 'is default' 'is hidden-from-USAGE'»;
next if .contains: «'# IGNORE' '# TRAITED'».any
& 'traited-routines.pm6';
push @seen, "$file:{$n+1}: $line";
}
cmp-ok +@seen, '==', 0, "not seen any traits in $file"
or diag @seen.join: "\n";
}
}
}
}
1 change: 1 addition & 0 deletions tools/build/jvm_core_sources
Expand Up @@ -32,6 +32,7 @@ src/core/Sub.pm6
src/core/Macro.pm6
src/core/Method.pm6
src/core/Submethod.pm6
src/core/traited-routines.pm6
src/core/Junction.pm6
src/core/Cool.pm6
src/core/Enumeration.pm6
Expand Down
3 changes: 2 additions & 1 deletion tools/build/moar_core_sources
Expand Up @@ -7,7 +7,6 @@ src/core/natives.pm6
src/core/stubs.pm6
src/core/control.pm6
src/core/Mu.pm6
src/core/Stringy.pm6
src/core/Any.pm6
src/core/Attribute.pm6
src/core/Iterator.pm6
Expand All @@ -32,6 +31,8 @@ src/core/Sub.pm6
src/core/Macro.pm6
src/core/Method.pm6
src/core/Submethod.pm6
src/core/Stringy.pm6
src/core/traited-routines.pm6
src/core/Junction.pm6
src/core/Cool.pm6
src/core/Enumeration.pm6
Expand Down

0 comments on commit 3506395

Please sign in to comment.