Skip to content

Commit b81241b

Browse files
committed
port C3 linearization from nqp
1 parent e1eaa4c commit b81241b

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

lib/Perl6/TypeGraph.pm

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,55 @@ class Perl6::TypeGraph {
55
has @.super;
66
has @.roles;
77
has $.packagetype is rw = 'class';
8+
9+
has @.mro;
10+
method mro(Type:D:) {
11+
return @!mro if @!mro;
12+
if @.super == 1 {
13+
@!mro = @.super[0].mro;
14+
} elsif @.super > 1 {
15+
my @merge_list = @.super.map: *.mro.item;
16+
@!mro = self.c3_merge(@merge_list);
17+
}
18+
@!mro.unshift: self;
19+
}
20+
21+
method c3_merge(@merge_list) {
22+
my @result;
23+
my $accepted;
24+
my $something_accepted = 0;
25+
my $cand_count = 0;
26+
for @merge_list -> @cand_list {
27+
next unless @cand_list;
28+
my $rejected = 0;
29+
my $cand_class = @cand_list[0];
30+
$cand_count++;
31+
for @merge_list {
32+
next if $_ === @cand_list;
33+
for 1..+$_ -> $cur_pos {
34+
if $_[$cur_pos] === $cand_class {
35+
$rejected = 1;
36+
last;
37+
}
38+
}
39+
}
40+
unless $rejected {
41+
$accepted = $cand_class;
42+
$something_accepted = 1;
43+
last;
44+
}
45+
}
46+
return () unless $cand_count;
47+
unless $something_accepted {
48+
die("Could not build C3 linearization for {self}: ambiguous hierarchy");
49+
}
50+
for @merge_list.keys -> $i {
51+
@merge_list[$i] = [@merge_list[$i].grep: { $_ ne $accepted }] ;
52+
}
53+
@result = self.c3_merge(@merge_list);
54+
@result.unshift: $accepted;
55+
@result;
56+
}
857
}
958
my grammar Decl {
1059
token ident { <.alpha> \w* }

t/typegraph.t

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,6 @@ ok $t.types<Array>.super.any eq 'List',
1010
'Array has List as a superclass';
1111
ok $t.types<List>.roles.any eq 'Positional',
1212
'List does positional';
13+
is $t.types<Str>.mro, 'Str Cool Any Mu', 'Str mro';
14+
is $t.types<Match>.mro, 'Match Capture Cool Any Mu', 'Match mro';
1315
done;

0 commit comments

Comments
 (0)