diff --git a/src/core/Any-str.pm b/src/core/Any-str.pm index a9406f87b24..fe88534f711 100644 --- a/src/core/Any-str.pm +++ b/src/core/Any-str.pm @@ -1,4 +1,8 @@ augment class Any { + method ACCEPTS($topic) { + self === $topic + } + our Int multi method bytes() is export { pir::box__PI(pir::bytelength__IS(self)) } diff --git a/src/core/EnumMap.pm b/src/core/EnumMap.pm index 7b7ffb28851..30c6bf8b599 100644 --- a/src/core/EnumMap.pm +++ b/src/core/EnumMap.pm @@ -21,7 +21,12 @@ class EnumMap does Associative { } multi method ACCEPTS(Regex $topic) { - any(@.keys) ~~ $topic; + for @.keys -> $k { + if $topic.ACCEPTS($k) { + return True; + } + } + False } multi method ACCEPTS(%topic) { diff --git a/src/core/Parcel.pm b/src/core/Parcel.pm index 1a755a526d4..803883ff348 100644 --- a/src/core/Parcel.pm +++ b/src/core/Parcel.pm @@ -8,7 +8,7 @@ augment class Parcel { if self.elems == 0 { $x.notdef || ($x.does(::Positional) && $x == 0) } else { - die "Don't know how to smart-match against a Parcel that doesn't happen to be empty"; + self.Seq.ACCEPTS($x) } } } diff --git a/src/core/Seq.pm b/src/core/Seq.pm index ac39d164706..e7eb226f594 100644 --- a/src/core/Seq.pm +++ b/src/core/Seq.pm @@ -1,4 +1,49 @@ augment class Seq { + multi method ACCEPTS(@topic) { + my $self_it = self.iterator(); + my $topic_it = @topic.iterator(); + loop { + my $cur_self_elem = $self_it.get; + if $cur_self_elem ~~ EMPTY { last } + if $cur_self_elem ~~ Whatever { + # If we just have * left, we're done. Otherwise, we have a + # "target" to look for. + loop { + $cur_self_elem = $self_it.get; + if $cur_self_elem ~~ EMPTY { return True } + unless $cur_self_elem ~~ Whatever { + last; + } + } + + # Need to find our target in the topic, if possible. + loop { + my $cur_topic_elem = $topic_it.get; + if $cur_topic_elem ~~ EMPTY { + # Ran out before finding what we wanted. + return False; + } + elsif $cur_topic_elem === $cur_self_elem { + last; + } + } + } + else { + my $cur_topic_elem = $topic_it.get; + if $cur_topic_elem ~~ EMPTY || $cur_topic_elem !=== $cur_self_elem { + return False; + } + } + } + + # If we've nothing left to match, we're successful. + $topic_it.get ~~ EMPTY + } + + multi method ACCEPTS($topic) { + self.ACCEPTS(@($topic)) + } + method elems() { pir::set__IP(self!fill); } method Str() {