mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Merge branch 'work_for_merge' of https://github.com/zubycz/mruby into zubycz-work_for_merge
This commit is contained in:
@@ -2190,10 +2190,18 @@ arg : lhs '=' arg_rhs
|
||||
{
|
||||
$$ = new_dot2(p, $1, $3);
|
||||
}
|
||||
| arg tDOT2
|
||||
{
|
||||
$$ = new_dot2(p, $1, new_nil(p));
|
||||
}
|
||||
| arg tDOT3 arg
|
||||
{
|
||||
$$ = new_dot3(p, $1, $3);
|
||||
}
|
||||
| arg tDOT3
|
||||
{
|
||||
$$ = new_dot3(p, $1, new_nil(p));
|
||||
}
|
||||
| arg '+' arg
|
||||
{
|
||||
$$ = call_bin_op(p, $1, "+", $3);
|
||||
|
||||
+1406
-1390
File diff suppressed because it is too large
Load Diff
@@ -27,10 +27,12 @@ class Range
|
||||
end
|
||||
|
||||
def max(&block)
|
||||
val = self.first
|
||||
last = self.last
|
||||
val = self.begin
|
||||
last = self.end
|
||||
return super if block
|
||||
|
||||
raise RangeError, "cannot get the maximum of endless range" if last.nil?
|
||||
|
||||
# fast path for numerics
|
||||
if val.kind_of?(Numeric) && last.kind_of?(Numeric)
|
||||
raise TypeError if exclude_end? && !last.kind_of?(Integer)
|
||||
@@ -47,9 +49,13 @@ class Range
|
||||
end
|
||||
|
||||
def min(&block)
|
||||
val = self.first
|
||||
last = self.last
|
||||
return super if block
|
||||
val = self.begin
|
||||
last = self.end
|
||||
if block
|
||||
raise RangeError, "cannot get the minimum of endless range with custom comparison method" if last.nil?
|
||||
return super
|
||||
end
|
||||
return val if last.nil?
|
||||
|
||||
# fast path for numerics
|
||||
if val.kind_of?(Numeric) && last.kind_of?(Numeric)
|
||||
|
||||
@@ -42,6 +42,9 @@ range_cover(mrb_state *mrb, mrb_value range)
|
||||
end = RANGE_END(r);
|
||||
|
||||
if (r_le(mrb, beg, val)) {
|
||||
if (mrb_nil_p(end)) {
|
||||
return mrb_true_value();
|
||||
}
|
||||
if (RANGE_EXCL(r)) {
|
||||
if (r_lt(mrb, val, end))
|
||||
return mrb_true_value();
|
||||
@@ -76,6 +79,11 @@ range_last(mrb_state *mrb, mrb_value range)
|
||||
{
|
||||
mrb_value num;
|
||||
mrb_value array;
|
||||
struct RRange *r = mrb_range_ptr(mrb, range);
|
||||
|
||||
if (mrb_nil_p(RANGE_END(r))) {
|
||||
mrb_raise(mrb, E_RANGE_ERROR, "cannot get the last element of endless range");
|
||||
}
|
||||
|
||||
if (mrb_get_args(mrb, "|o", &num) == 0) {
|
||||
return mrb_range_end(mrb, range);
|
||||
@@ -108,6 +116,10 @@ range_size(mrb_state *mrb, mrb_value range)
|
||||
|
||||
beg = RANGE_BEG(r);
|
||||
end = RANGE_END(r);
|
||||
if ((mrb_fixnum_p(beg) || mrb_float_p(beg)) && mrb_nil_p(end)) {
|
||||
return mrb_float_value(mrb, INFINITY);
|
||||
}
|
||||
|
||||
excl = RANGE_EXCL(r);
|
||||
if (mrb_integer_p(beg)) {
|
||||
beg_f = (mrb_float)mrb_integer(beg);
|
||||
@@ -159,6 +171,10 @@ range_size(mrb_state *mrb, mrb_value range)
|
||||
|
||||
beg = RANGE_BEG(r);
|
||||
end = RANGE_END(r);
|
||||
if (mrb_fixnum_p(beg) && mrb_nil_p(end)) {
|
||||
return mrb_nil_value();
|
||||
}
|
||||
|
||||
excl = RANGE_EXCL(r) ? 0 : 1;
|
||||
|
||||
if (mrb_integer_p(beg) && mrb_integer_p(end)) {
|
||||
|
||||
@@ -5,11 +5,16 @@ assert('Range#cover?') do
|
||||
assert_true ("a".."z").cover?("c")
|
||||
assert_true !("a".."z").cover?("5")
|
||||
assert_true ("a".."z").cover?("cc")
|
||||
assert_true ("a"..).cover?("c")
|
||||
assert_false ("a"..).cover?("5")
|
||||
assert_true ("a"..).cover?("cc")
|
||||
end
|
||||
|
||||
assert('Range#first') do
|
||||
assert_equal 10, (10..20).first
|
||||
assert_equal [10, 11, 12], (10..20).first(3)
|
||||
assert_equal 10, (10..).first
|
||||
assert_equal [10, 11, 12], (10..).first(3)
|
||||
|
||||
skip unless Object.const_defined?(:Float)
|
||||
assert_equal [0, 1, 2], (0..Float::INFINITY).first(3)
|
||||
@@ -18,6 +23,8 @@ end
|
||||
assert('Range#last') do
|
||||
assert_equal 20, (10..20).last
|
||||
assert_equal 20, (10...20).last
|
||||
assert_raise(RangeError) { (10..).last }
|
||||
assert_raise(RangeError) { (10...).last }
|
||||
assert_equal [18, 19, 20], (10..20).last(3)
|
||||
assert_equal [17, 18, 19], (10...20).last(3)
|
||||
end
|
||||
@@ -26,6 +33,9 @@ assert('Range#size') do
|
||||
assert_equal 42, (1..42).size
|
||||
assert_equal 41, (1...42).size
|
||||
assert_nil ('a'..'z').size
|
||||
assert_nil ('a'..).size
|
||||
|
||||
assert_nil (1..).size unless Object.const_defined?(:Float)
|
||||
|
||||
skip unless Object.const_defined?(:Float)
|
||||
assert_equal 6, (1...6.3).size
|
||||
@@ -33,6 +43,10 @@ assert('Range#size') do
|
||||
assert_equal 5, (1.1...6).size
|
||||
assert_equal 15, (1.0..15.9).size
|
||||
assert_equal Float::INFINITY, (0..Float::INFINITY).size
|
||||
|
||||
assert_equal Float::INFINITY, (1..).size
|
||||
assert_equal Float::INFINITY, (1...).size
|
||||
assert_equal Float::INFINITY, (1.0..).size
|
||||
end
|
||||
|
||||
assert('Range#max') do
|
||||
@@ -50,6 +64,10 @@ assert('Range#max') do
|
||||
# returns the endpoint when the endpoint equals the start point and the range is inclusive
|
||||
assert_equal 5, (5..5).max
|
||||
|
||||
# raises RangeError when called on an endless range
|
||||
assert_raise(RangeError) { (10..).max }
|
||||
assert_raise(RangeError) { (10...).max }
|
||||
|
||||
skip unless Object.const_defined?(:Float)
|
||||
|
||||
# returns the maximum value in the Float range when called with no arguments
|
||||
@@ -94,6 +112,7 @@ assert('Range#min') do
|
||||
# returns the minimum value in the range when called with no arguments
|
||||
assert_equal 1, (1..10).min
|
||||
assert_equal 1, (1...10).min
|
||||
assert_equal 1, (1..).min
|
||||
|
||||
# returns nil when the start point is greater than the endpoint
|
||||
assert_equal nil, (100..10).min
|
||||
@@ -108,12 +127,16 @@ assert('Range#min') do
|
||||
|
||||
# returns the minimum value in the Float range when called with no arguments
|
||||
assert_equal 303.20, (303.20..908.1111).min
|
||||
assert_equal 1, (1.0..).min
|
||||
|
||||
# returns nil when the start point is greater than the endpoint in a Float range
|
||||
assert_equal nil, (3003.20..908.1111).min
|
||||
end
|
||||
|
||||
assert('Range#min given a block') do
|
||||
# raise when called with a block in endless range
|
||||
assert_raise(RangeError) { (1..).min{} }
|
||||
|
||||
# passes each pair of values in the range to the block
|
||||
acc = []
|
||||
(1..10).min do |a, b|
|
||||
|
||||
@@ -443,4 +443,27 @@ class String
|
||||
end
|
||||
self
|
||||
end
|
||||
|
||||
def __upto_endless(&block)
|
||||
return to_enum(:__upto_endless) unless block
|
||||
|
||||
len = self.length
|
||||
# both edges are all digits
|
||||
bi = self.to_i(10)
|
||||
if bi > 0 or bi == "0"*len
|
||||
while true
|
||||
s = bi.to_s
|
||||
s = s.rjust(len, "0") if s.length < len
|
||||
yield s
|
||||
bi += 1
|
||||
end
|
||||
return self
|
||||
end
|
||||
bs = self
|
||||
while true
|
||||
yield bs
|
||||
bs = bs.succ
|
||||
end
|
||||
self
|
||||
end
|
||||
end
|
||||
|
||||
+24
-2
@@ -12,8 +12,25 @@ class Range
|
||||
def each(&block)
|
||||
return to_enum :each unless block
|
||||
|
||||
val = self.first
|
||||
last = self.last
|
||||
val = self.begin
|
||||
last = self.end
|
||||
|
||||
if val.kind_of?(Fixnum) && last.nil?
|
||||
i = val
|
||||
while true
|
||||
block.call(i)
|
||||
i += 1
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
if val.kind_of?(String) && last.nil?
|
||||
if val.respond_to? :__upto_endless
|
||||
return val.__upto_endless(&block)
|
||||
else
|
||||
str_each = true
|
||||
end
|
||||
end
|
||||
|
||||
if val.kind_of?(Integer) && last.kind_of?(Integer) # fixnums are special
|
||||
lim = last
|
||||
@@ -56,6 +73,11 @@ class Range
|
||||
h += 1 if self.exclude_end?
|
||||
h
|
||||
end
|
||||
|
||||
def to_a
|
||||
raise RangeError, "cannot convert endless range to an array" if self.last.nil?
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
|
||||
+18
-10
@@ -32,6 +32,8 @@ r_check(mrb_state *mrb, mrb_value a, mrb_value b)
|
||||
return;
|
||||
}
|
||||
|
||||
if (mrb_nil_p(b)) return;
|
||||
|
||||
n = mrb_cmp(mrb, a, b);
|
||||
if (n == -2) { /* can not be compared */
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "bad value for range");
|
||||
@@ -212,15 +214,19 @@ range_include(mrb_state *mrb, mrb_value range)
|
||||
mrb_value val = mrb_get_arg1(mrb);
|
||||
struct RRange *r = mrb_range_ptr(mrb, range);
|
||||
mrb_value beg, end;
|
||||
mrb_bool include_p;
|
||||
|
||||
beg = RANGE_BEG(r);
|
||||
end = RANGE_END(r);
|
||||
include_p = r_le(mrb, beg, val) && /* beg <= val */
|
||||
(RANGE_EXCL(r) ? r_gt(mrb, end, val) /* end > val */
|
||||
: r_ge(mrb, end, val)); /* end >= val */
|
||||
|
||||
return mrb_bool_value(include_p);
|
||||
if (r_le(mrb, beg, val)) { /* beg <= val */
|
||||
if (mrb_nil_p(end)) {
|
||||
return mrb_true_value();
|
||||
}
|
||||
if (RANGE_EXCL(r) ? r_gt(mrb, end, val) /* end > val */
|
||||
: r_ge(mrb, end, val)) { /* end >= val */
|
||||
return mrb_true_value();
|
||||
}
|
||||
}
|
||||
return mrb_false_value();
|
||||
}
|
||||
|
||||
/* 15.2.14.4.12(x) */
|
||||
@@ -261,10 +267,10 @@ range_inspect(mrb_state *mrb, mrb_value range)
|
||||
struct RRange *r = mrb_range_ptr(mrb, range);
|
||||
|
||||
str = mrb_inspect(mrb, RANGE_BEG(r));
|
||||
str2 = mrb_inspect(mrb, RANGE_END(r));
|
||||
if (!mrb_nil_p(RANGE_END(r))) str2 = mrb_inspect(mrb, RANGE_END(r));
|
||||
str = mrb_str_dup(mrb, str);
|
||||
mrb_str_cat(mrb, str, "...", RANGE_EXCL(r) ? 3 : 2);
|
||||
mrb_str_cat_str(mrb, str, str2);
|
||||
if (!mrb_nil_p(RANGE_END(r))) mrb_str_cat_str(mrb, str, str2);
|
||||
|
||||
return str;
|
||||
}
|
||||
@@ -381,13 +387,15 @@ MRB_API enum mrb_range_beg_len
|
||||
mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc)
|
||||
{
|
||||
mrb_int beg, end;
|
||||
mrb_bool excl;
|
||||
struct RRange *r;
|
||||
|
||||
if (!mrb_range_p(range)) return MRB_RANGE_TYPE_MISMATCH;
|
||||
r = mrb_range_ptr(mrb, range);
|
||||
|
||||
beg = mrb_int(mrb, RANGE_BEG(r));
|
||||
end = mrb_int(mrb, RANGE_END(r));
|
||||
end = mrb_nil_p(RANGE_END(r)) ? -1 : mrb_int(mrb, RANGE_END(r));
|
||||
excl = mrb_nil_p(RANGE_END(r)) ? 0 : RANGE_EXCL(r);
|
||||
|
||||
if (beg < 0) {
|
||||
beg += len;
|
||||
@@ -400,7 +408,7 @@ mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp,
|
||||
}
|
||||
|
||||
if (end < 0) end += len;
|
||||
if (!RANGE_EXCL(r) && (!trunc || end < len)) end++; /* include end point */
|
||||
if (!excl && (!trunc || end < len)) end++; /* include end point */
|
||||
len = end - beg;
|
||||
if (len < 0) len = 0;
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@ assert('Array#[]', '15.2.12.5.4') do
|
||||
a = [ "a", "b", "c", "d", "e" ]
|
||||
assert_equal(["b", "c"], a[1,2])
|
||||
assert_equal(["b", "c", "d"], a[1..-2])
|
||||
assert_equal(["b", "c", "d", "e"], a[1..])
|
||||
skip unless Object.const_defined?(:Float)
|
||||
assert_equal("b", a[1.1])
|
||||
end
|
||||
@@ -92,6 +93,10 @@ assert('Array#[]=', '15.2.12.5.5') do
|
||||
a[2...4] = 6
|
||||
assert_equal([1,2,6,5], a)
|
||||
|
||||
a = [1,2,3,4,5]
|
||||
a[2...] = 6
|
||||
assert_equal([1,2,6], a)
|
||||
|
||||
# passing self (#3274)
|
||||
a = [1,2,3]
|
||||
a[1,0] = a
|
||||
|
||||
+67
-1
@@ -8,19 +8,30 @@ end
|
||||
assert('Range#==', '15.2.14.4.1') do
|
||||
assert_true (1..10) == (1..10)
|
||||
assert_false (1..10) == (1..100)
|
||||
assert_false (1..10) == (1..)
|
||||
|
||||
assert_true (1..) == (1..nil)
|
||||
assert_true (1..) == (1..)
|
||||
assert_false (1..) == (1...)
|
||||
|
||||
skip unless Object.const_defined?(:Float)
|
||||
assert_true (1..10) == Range.new(1.0, 10.0)
|
||||
|
||||
end
|
||||
|
||||
assert('Range#===', '15.2.14.4.2') do
|
||||
a = (1..10)
|
||||
b = (1..)
|
||||
|
||||
assert_true a === 5
|
||||
assert_false a === 20
|
||||
assert_true b === 20
|
||||
assert_false b === 0
|
||||
end
|
||||
|
||||
assert('Range#begin', '15.2.14.4.3') do
|
||||
assert_equal 1, (1..10).begin
|
||||
assert_equal 1, (1..).begin
|
||||
end
|
||||
|
||||
assert('Range#each', '15.2.14.4.4') do
|
||||
@@ -28,27 +39,38 @@ assert('Range#each', '15.2.14.4.4') do
|
||||
b = 0
|
||||
a.each {|i| b += i}
|
||||
assert_equal 6, b
|
||||
c = []
|
||||
(1..).each { |i| c << i; break if c.size == 10 }
|
||||
assert_equal [1, 2, 3, 4, 5, 6, 7, 8 ,9, 10], c
|
||||
end
|
||||
|
||||
assert('Range#end', '15.2.14.4.5') do
|
||||
assert_equal 10, (1..10).end
|
||||
assert_nil (1..).end
|
||||
end
|
||||
|
||||
assert('Range#exclude_end?', '15.2.14.4.6') do
|
||||
assert_true (1...10).exclude_end?
|
||||
assert_false (1..10).exclude_end?
|
||||
assert_true (1...).exclude_end?
|
||||
assert_false (1..).exclude_end?
|
||||
end
|
||||
|
||||
assert('Range#first', '15.2.14.4.7') do
|
||||
assert_equal 1, (1..10).first
|
||||
assert_equal 1, (1..).first
|
||||
end
|
||||
|
||||
assert('Range#include?', '15.2.14.4.8') do
|
||||
assert_true (1..10).include?(10)
|
||||
assert_false (1..10).include?(11)
|
||||
assert_true (1..).include?(10)
|
||||
assert_false (1..).include?(0)
|
||||
|
||||
assert_true (1...10).include?(9)
|
||||
assert_false (1...10).include?(10)
|
||||
assert_true (1...).include?(10)
|
||||
assert_false (1...).include?(0)
|
||||
end
|
||||
|
||||
assert('Range#initialize', '15.2.14.4.9') do
|
||||
@@ -61,17 +83,29 @@ assert('Range#initialize', '15.2.14.4.9') do
|
||||
assert_false b.exclude_end?
|
||||
|
||||
assert_raise(NameError) { (0..1).__send__(:initialize, 1, 3) }
|
||||
|
||||
c = Range.new(1, nil, true)
|
||||
d = Range.new(1, nil, false)
|
||||
|
||||
assert_equal (1...nil), c
|
||||
assert_true c.exclude_end?
|
||||
assert_equal (1..nil), d
|
||||
assert_false d.exclude_end?
|
||||
end
|
||||
|
||||
assert('Range#last', '15.2.14.4.10') do
|
||||
assert_equal 10, (1..10).last
|
||||
assert_nil (1..).last
|
||||
end
|
||||
|
||||
assert('Range#member?', '15.2.14.4.11') do
|
||||
a = (1..10)
|
||||
b = (1..)
|
||||
|
||||
assert_true a.member?(5)
|
||||
assert_false a.member?(20)
|
||||
assert_true b.member?(20)
|
||||
assert_false b.member?(0)
|
||||
end
|
||||
|
||||
assert('Range#to_s', '15.2.14.4.12') do
|
||||
@@ -79,6 +113,10 @@ assert('Range#to_s', '15.2.14.4.12') do
|
||||
assert_equal "0...1", (0...1).to_s
|
||||
assert_equal "a..b", ("a".."b").to_s
|
||||
assert_equal "a...b", ("a"..."b").to_s
|
||||
assert_equal "0..", (0..).to_s
|
||||
assert_equal "0...", (0...).to_s
|
||||
assert_equal "a..", ("a"..).to_s
|
||||
assert_equal "a...", ("a"...).to_s
|
||||
end
|
||||
|
||||
assert('Range#inspect', '15.2.14.4.13') do
|
||||
@@ -86,19 +124,36 @@ assert('Range#inspect', '15.2.14.4.13') do
|
||||
assert_equal "0...1", (0...1).inspect
|
||||
assert_equal "\"a\"..\"b\"", ("a".."b").inspect
|
||||
assert_equal "\"a\"...\"b\"", ("a"..."b").inspect
|
||||
assert_equal "0..", (0..).inspect
|
||||
assert_equal "0...", (0...).inspect
|
||||
assert_equal "\"a\"..", ("a"..).inspect
|
||||
assert_equal "\"a\"...", ("a"...).inspect
|
||||
end
|
||||
|
||||
assert('Range#eql?', '15.2.14.4.14') do
|
||||
assert_true (1..10).eql? (1..10)
|
||||
assert_false (1..10).eql? (1..100)
|
||||
assert_false (1..10).eql? (Range.new(1.0, 10.0))
|
||||
assert_false (1..10).eql? "1..10"
|
||||
assert_true (1..).eql? (1..)
|
||||
assert_false (1..).eql? (2..)
|
||||
assert_false (1..).eql? "1.."
|
||||
skip unless Object.const_defined?(:Float)
|
||||
assert_false (1..10).eql? (Range.new(1.0, 10.0))
|
||||
assert_false (1..).eql? (Range.new(1.0, nil))
|
||||
end
|
||||
|
||||
assert('Range#initialize_copy', '15.2.14.4.15') do
|
||||
assert_raise(NameError) { (0..1).__send__(:initialize_copy, 1..3) }
|
||||
end
|
||||
|
||||
assert('Range#hash', '15.3.1.3.15') do
|
||||
assert_kind_of(Integer, (1..10).hash)
|
||||
assert_equal (1..10).hash, (1..10).hash
|
||||
assert_not_equal (1..10).hash, (1...10).hash
|
||||
assert_equal (1..).hash, (1..).hash
|
||||
assert_not_equal (1..).hash, (1...).hash
|
||||
end
|
||||
|
||||
assert('Range#dup') do
|
||||
r = (1..3).dup
|
||||
assert_equal 1, r.begin
|
||||
@@ -109,4 +164,15 @@ assert('Range#dup') do
|
||||
assert_equal "a", r.begin
|
||||
assert_equal "z", r.end
|
||||
assert_true r.exclude_end?
|
||||
|
||||
r = (1..).dup
|
||||
assert_equal 1, r.begin
|
||||
assert_nil r.end
|
||||
assert_false r.exclude_end?
|
||||
end
|
||||
|
||||
assert('Range#to_a') do
|
||||
assert_equal([1, 2, 3, 4, 5], (1..5).to_a)
|
||||
assert_equal([1, 2, 3, 4], (1...5).to_a)
|
||||
assert_raise(RangeError) { (1..).to_a }
|
||||
end
|
||||
|
||||
@@ -90,6 +90,7 @@ assert('String#[] with Range') do
|
||||
h1 = 'abc'[3..4]
|
||||
i1 = 'abc'[4..5]
|
||||
j1 = 'abcdefghijklmnopqrstuvwxyz'[1..3]
|
||||
k1 = 'abcdefghijklmnopqrstuvwxyz'[-3..]
|
||||
a2 = 'abc'[1...0]
|
||||
b2 = 'abc'[1...1]
|
||||
c2 = 'abc'[1...2]
|
||||
@@ -100,6 +101,7 @@ assert('String#[] with Range') do
|
||||
h2 = 'abc'[3...4]
|
||||
i2 = 'abc'[4...5]
|
||||
j2 = 'abcdefghijklmnopqrstuvwxyz'[1...3]
|
||||
k2 = 'abcdefghijklmnopqrstuvwxyz'[-3...]
|
||||
|
||||
assert_equal '', a1
|
||||
assert_equal 'b', b1
|
||||
@@ -111,6 +113,7 @@ assert('String#[] with Range') do
|
||||
assert_equal '', h1
|
||||
assert_nil i2
|
||||
assert_equal 'bcd', j1
|
||||
assert_equal 'xyz', k1
|
||||
assert_equal '', a2
|
||||
assert_equal '', b2
|
||||
assert_equal 'b', c2
|
||||
@@ -121,6 +124,7 @@ assert('String#[] with Range') do
|
||||
assert_equal '', h2
|
||||
assert_nil i2
|
||||
assert_equal 'bc', j2
|
||||
assert_equal 'xyz', k2
|
||||
end
|
||||
|
||||
assert('String#[]=') do
|
||||
|
||||
Reference in New Issue
Block a user