Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge branch 'lucasbuchala-range-excludes' into nom
Conflicts:
	src/core/Range.pm
  • Loading branch information
moritz committed Jan 1, 2015
2 parents f53153d + 49fab66 commit 1f3bb95
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 50 deletions.
16 changes: 8 additions & 8 deletions src/core/Any.pm
Expand Up @@ -334,36 +334,36 @@ my class Any { # declared in BOOTSTRAP

my $min;
my $max;
my $excludes_min = Bool::False;
my $excludes_max = Bool::False;
my $excludes-min = Bool::False;
my $excludes-max = Bool::False;

for @.list {
.defined or next;

if .isa(Range) {
if !$min.defined || $cmp($_.min, $min) < 0 {
$min = $_;
$excludes_min = $_.excludes_min;
$excludes-min = $_.excludes-min;
}
if !$max.defined || $cmp($_.max, $max) > 0 {
$max = $_;
$excludes_max = $_.excludes_max;
$excludes-max = $_.excludes-max;
}
} else {
if !$min.defined || $cmp($_, $min) < 0 {
$min = $_;
$excludes_min = Bool::False;
$excludes-min = Bool::False;
}
if !$max.defined || $cmp($_, $max) > 0 {
$max = $_;
$excludes_max = Bool::False;
$excludes-max = Bool::False;
}
}
}
Range.new($min // Inf,
$max // -Inf,
:excludes_min($excludes_min),
:excludes_max($excludes_max));
:excludes-min($excludes-min),
:excludes-max($excludes-max));
}

proto method at_pos(|) {*}
Expand Down
2 changes: 1 addition & 1 deletion src/core/List.pm
Expand Up @@ -415,7 +415,7 @@ my class List does Positional { # declared in BOOTSTRAP
return self if $elems < 2;

# Range is currently optimized for fast Parcel construction.
my $index := Range.new(0, $elems, :excludes_max).reify(*);
my $index := Range.new(0, $elems, :excludes-max).reify(*);
my Mu $index_rpa := nqp::getattr($index, Parcel, '$!storage');

# if $by.arity < 2, then we apply the block to the elements
Expand Down
85 changes: 44 additions & 41 deletions src/core/Range.pm
Expand Up @@ -3,51 +3,51 @@ my class X::Range::InvalidArg { ... }
my class Range is Iterable is Cool does Positional {
has $.min;
has $.max;
has $.excludes_min;
has $.excludes_max;
has $.excludes-min;
has $.excludes-max;

proto method new(|) { * }
# The order of "method new" declarations matters here, to ensure
# appropriate candidate tiebreaking when mixed type arguments
# are present (e.g., Range,Whatever or Real,Range).
multi method new(Range $min, $max, :$excludes_min, :$excludes_max) {
multi method new(Range $min, $max, :$excludes-min, :$excludes-max) {
X::Range::InvalidArg.new(:got($min)).throw;
}
multi method new($min, Range $max, :$excludes_min, :$excludes_max) {
multi method new($min, Range $max, :$excludes-min, :$excludes-max) {
X::Range::InvalidArg.new(:got($max)).throw;
}
multi method new(Whatever $min, Whatever $max, :$excludes_min, :$excludes_max) {
nqp::create(self).BUILD(-Inf, Inf, $excludes_min, $excludes_max)
multi method new(Whatever $min, Whatever $max, :$excludes-min, :$excludes-max) {
nqp::create(self).BUILD(-Inf, Inf, $excludes-min, $excludes-max)
}
multi method new(Whatever $min, $max, :$excludes_min, :$excludes_max) {
nqp::create(self).BUILD(-Inf, $max, $excludes_min, $excludes_max)
multi method new(Whatever $min, $max, :$excludes-min, :$excludes-max) {
nqp::create(self).BUILD(-Inf, $max, $excludes-min, $excludes-max)
}
multi method new($min, Whatever $max, :$excludes_min, :$excludes_max) {
nqp::create(self).BUILD($min, Inf, $excludes_min, $excludes_max)
multi method new($min, Whatever $max, :$excludes-min, :$excludes-max) {
nqp::create(self).BUILD($min, Inf, $excludes-min, $excludes-max)
}
multi method new(Real $min, $max, :$excludes_min, :$excludes_max) {
nqp::create(self).BUILD($min, $max.Real, $excludes_min, $excludes_max)
multi method new(Real $min, $max, :$excludes-min, :$excludes-max) {
nqp::create(self).BUILD($min, $max.Real, $excludes-min, $excludes-max)
}
multi method new($min is copy, $max, :$excludes_min, :$excludes_max) {
multi method new($min is copy, $max, :$excludes-min, :$excludes-max) {
$min = +$min
if nqp::istype($min,List) || nqp::istype($min,Match) || nqp::istype($min,Parcel);
nqp::create(self).BUILD($min, $max, $excludes_min, $excludes_max)
nqp::create(self).BUILD($min, $max, $excludes-min, $excludes-max)
}

submethod BUILD($min, $max, $excludes_min, $excludes_max) {
submethod BUILD($min, $max, $excludes-min, $excludes-max) {
$!min = $min;
$!max = $max;
$!excludes_min = $excludes_min.Bool;
$!excludes_max = $excludes_max.Bool;
$!excludes-min = $excludes-min.Bool;
$!excludes-max = $excludes-max.Bool;
self;
}

multi method WHICH (Range:D:) {
self.^name
~ "|$!min"
~ ("^" if $!excludes_min)
~ ("^" if $!excludes-min)
~ '..'
~ ("^" if $!excludes_max)
~ ("^" if $!excludes-max)
~ $!max;
}

Expand All @@ -59,27 +59,27 @@ my class Range is Iterable is Cool does Positional {
method bounds() { ($!min, $!max) }

multi method ACCEPTS(Range:D: Mu \topic) {
(topic cmp $!min) > -(!$!excludes_min)
and (topic cmp $!max) < +(!$!excludes_max)
(topic cmp $!min) > -(!$!excludes-min)
and (topic cmp $!max) < +(!$!excludes-max)
}

multi method ACCEPTS(Range:D: Range \topic) {
(topic.min > $!min
|| topic.min == $!min
&& !(!topic.excludes_min && $!excludes_min))
&& !(!topic.excludes-min && $!excludes-min))
&&
(topic.max < $!max
|| topic.max == $!max
&& !(!topic.excludes_max && $!excludes_max))
&& !(!topic.excludes-max && $!excludes-max))
}

method reify($n = 10) {
my $value = $!excludes_min ?? $!min.succ !! $!min;
my $value = $!excludes-min ?? $!min.succ !! $!min;
# Iterating a Str range delegates to iterating a sequence.
if Str.ACCEPTS($value) {
return $value after $!max
?? ()
!! SEQUENCE($value, $!max, :exclude_end($!excludes_max)).iterator.reify($n)
!! SEQUENCE($value, $!max, :exclude_end($!excludes-max)).iterator.reify($n)
}
my $count;
if nqp::istype($n, Whatever) {
Expand All @@ -90,7 +90,7 @@ my class Range is Iterable is Cool does Positional {
fail "request for infinite elements from range"
if $count == Inf && self.infinite;
}
my $cmpstop = $!excludes_max ?? 0 !! 1;
my $cmpstop = $!excludes-max ?? 0 !! 1;
my $realmax = nqp::istype($!min, Numeric) && !nqp::istype($!max, Callable) && !nqp::istype($!max, Whatever)
?? $!max.Numeric
!! $!max;
Expand Down Expand Up @@ -129,7 +129,7 @@ my class Range is Iterable is Cool does Positional {
if ($value cmp $!max) < $cmpstop {
nqp::push($rpa,
($value.succ cmp $!max < $cmpstop)
?? nqp::create(self).BUILD($value, $!max, 0, $!excludes_max)
?? nqp::create(self).BUILD($value, $!max, 0, $!excludes-max)
!! $value);
}
nqp::p6parcel($rpa, nqp::null());
Expand All @@ -139,9 +139,9 @@ my class Range is Iterable is Cool does Positional {

multi method perl(Range:D:) {
$.min.perl
~ ('^' if $.excludes_min)
~ ('^' if $.excludes-min)
~ '..'
~ ('^' if $.excludes_max)
~ ('^' if $.excludes-max)
~ $.max.perl
}

Expand All @@ -151,8 +151,8 @@ my class Range is Iterable is Cool does Positional {
}
multi method roll(Range:D:) {
return self.list.roll unless nqp::istype($!min, Int) && nqp::istype($!max, Int);
my Int:D $least = $!excludes_min ?? $!min + 1 !! $!min;
my Int:D $elems = 1 + ($!excludes_max ?? $!max - 1 !! $!max) - $least;
my Int:D $least = $!excludes-min ?? $!min + 1 !! $!min;
my Int:D $elems = 1 + ($!excludes-max ?? $!max - 1 !! $!max) - $least;
$elems ?? ($least + nqp::rand_I(nqp::decont($elems), Int)) !! Any;
}
multi method roll(Cool $num as Int) {
Expand All @@ -170,8 +170,8 @@ my class Range is Iterable is Cool does Positional {
multi method pick(Cool $n as Int) {
return self.list.pick($n) unless nqp::istype($!min, Int) && nqp::istype($!max, Int);
return self.roll if $n == 1;
my Int:D $least = $!excludes_min ?? $!min + 1 !! $!min;
my Int:D $elems = 1 + ($!excludes_max ?? $!max - 1 !! $!max) - $least;
my Int:D $least = $!excludes-min ?? $!min + 1 !! $!min;
my Int:D $elems = 1 + ($!excludes-max ?? $!max - 1 !! $!max) - $least;
return self.list.pick($n) unless $elems > 3 * $n;
my %seen;
my int $i_n = nqp::unbox_i($n);
Expand All @@ -188,37 +188,40 @@ my class Range is Iterable is Cool does Positional {
multi method Numeric (Range:D:) {
nextsame unless nqp::istype($.max,Numeric) && nqp::istype($.min,Numeric);

my $diff := $.max - $.min - $.excludes_min;
my $diff := $.max - $.min - $.excludes-min;

# empty range
return 0 if $diff < 0;

my $floor := $diff.floor;
return $floor + 1 - ($floor == $diff ?? $.excludes_max !! 0);
return $floor + 1 - ($floor == $diff ?? $.excludes-max !! 0);
}

method excludes_min() { DEPRECATED('excludes-min', |<2014.12 2015.12>); $!excludes-min }
method excludes_max() { DEPRECATED('excludes-max', |<2014.12 2015.12>); $!excludes-max }
}

sub infix:<..>($min, $max) {
Range.new($min, $max)
}
sub infix:<^..>($min, $max) {
Range.new($min, $max, :excludes_min)
Range.new($min, $max, :excludes-min)
}
sub infix:<..^>($min, $max) {
Range.new($min, $max, :excludes_max)
Range.new($min, $max, :excludes-max)
}
sub infix:<^..^>($min, $max) is pure {
Range.new($min, $max, :excludes_min, :excludes_max)
Range.new($min, $max, :excludes-min, :excludes-max)
}
sub prefix:<^>($max) {
Range.new(0, $max.Numeric, :excludes_max)
Range.new(0, $max.Numeric, :excludes-max)
}

multi sub infix:<eqv>(Range:D \a, Range:D \b) {
a.min eqv b.min
&& a.max eqv b.max
&& a.excludes_min eqv b.excludes_min
&& a.excludes_max eqv b.excludes_max
&& a.excludes-min eqv b.excludes-min
&& a.excludes-max eqv b.excludes-max
}

# vim: ft=perl6 expandtab sw=4

0 comments on commit 1f3bb95

Please sign in to comment.