summaryrefslogtreecommitdiff
path: root/range.c
diff options
context:
space:
mode:
Diffstat (limited to 'range.c')
-rw-r--r--range.c153
1 files changed, 92 insertions, 61 deletions
diff --git a/range.c b/range.c
index 147c28a..b7d2f3b 100644
--- a/range.c
+++ b/range.c
@@ -6,7 +6,7 @@
$Date: 1994/12/06 09:30:12 $
created at: Thu Aug 19 17:46:47 JST 1993
- Copyright (C) 1993-1995 Yukihiro Matsumoto
+ Copyright (C) 1993-1996 Yukihiro Matsumoto
************************************************/
@@ -14,55 +14,58 @@
VALUE mComparable;
static VALUE cRange;
+extern VALUE cNumeric;
static ID upto;
static VALUE
-range_s_new(class, start, end)
- VALUE class, start, end;
+range_s_new(class, first, last)
+ VALUE class, first, last;
{
VALUE obj;
- if (!(FIXNUM_P(start) && FIXNUM_P(end))
- && (TYPE(start) != TYPE(end)
- || CLASS_OF(start) != CLASS_OF(end)
- || !rb_responds_to(start, upto))) {
- Fail("bad value for range");
+ if (!(FIXNUM_P(first) && FIXNUM_P(last))
+ && (TYPE(first) != TYPE(last)
+ || CLASS_OF(first) != CLASS_OF(last)
+ || !rb_respond_to(first, upto))
+ && !(obj_is_kind_of(first, cNumeric)
+ && obj_is_kind_of(last, cNumeric))) {
+ ArgError("bad value for range");
}
obj = obj_alloc(class);
- rb_iv_set(obj, "start", start);
- rb_iv_set(obj, "end", end);
+ rb_iv_set(obj, "first", first);
+ rb_iv_set(obj, "last", last);
return obj;
}
VALUE
-range_new(start, end)
- VALUE start, end;
+range_new(first, last)
+ VALUE first, last;
{
- return range_s_new(cRange, start, end);
+ return range_s_new(cRange, first, last);
}
static VALUE
range_match(rng, obj)
VALUE rng, obj;
{
- VALUE beg, end;
+ VALUE first, last;
- beg = rb_iv_get(rng, "start");
- end = rb_iv_get(rng, "end");
+ first = rb_iv_get(rng, "first");
+ last = rb_iv_get(rng, "last");
- if (FIXNUM_P(beg) && FIXNUM_P(obj)) {
- if (FIX2INT(beg) <= FIX2INT(obj) && FIX2INT(obj) <= FIX2INT(end)) {
+ if (FIXNUM_P(first) && FIXNUM_P(obj)) {
+ if (FIX2INT(first) <= FIX2INT(obj) && FIX2INT(obj) <= FIX2INT(last)) {
return TRUE;
}
return FALSE;
}
else {
- if (rb_funcall(beg, rb_intern("<="), 1, obj) &&
- rb_funcall(end, rb_intern(">="), 1, obj)) {
+ if (rb_funcall(first, rb_intern("<="), 1, obj) &&
+ rb_funcall(last, rb_intern(">="), 1, obj)) {
return TRUE;
}
return FALSE;
@@ -70,23 +73,15 @@ range_match(rng, obj)
}
struct upto_data {
- VALUE beg;
- VALUE end;
+ VALUE first;
+ VALUE last;
};
static VALUE
range_upto(data)
struct upto_data *data;
{
- return rb_funcall(data->beg, upto, 1, data->end);
-}
-
-static VALUE
-range_upto_yield(v)
- VALUE v;
-{
- rb_yield(v);
- return Qnil;
+ return rb_funcall(data->first, upto, 1, data->last);
}
static VALUE
@@ -95,73 +90,105 @@ range_each(obj)
{
VALUE b, e;
- b = rb_iv_get(obj, "start");
- e = rb_iv_get(obj, "end");
+ b = rb_iv_get(obj, "first");
+ e = rb_iv_get(obj, "last");
if (FIXNUM_P(b)) { /* fixnum is a special case(for performance) */
num_upto(b, e);
}
- else if (TYPE(b) == T_STRING) {
- str_upto(b, e);
- }
else {
struct upto_data data;
- data.beg = b;
- data.end = e;
+ data.first = b;
+ data.last = e;
- rb_iterate(range_upto, &data, range_upto_yield, Qnil);
+ rb_iterate(range_upto, &data, rb_yield, 0);
}
return Qnil;
}
static VALUE
-range_start(obj)
+range_first(obj)
VALUE obj;
{
VALUE b;
- b = rb_iv_get(obj, "start");
+ b = rb_iv_get(obj, "first");
return b;
}
static VALUE
-range_end(obj)
+range_last(obj)
VALUE obj;
{
VALUE e;
- e = rb_iv_get(obj, "end");
+ e = rb_iv_get(obj, "last");
return e;
}
-static VALUE
-range_to_s(obj)
- VALUE obj;
-{
- VALUE args[4];
-
- args[0] = str_new2("%d..%d");
- args[1] = rb_iv_get(obj, "start");
- args[2] = rb_iv_get(obj, "end");
- return f_sprintf(3, args);
-}
-
VALUE
range_beg_end(range, begp, endp)
VALUE range;
int *begp, *endp;
{
- int beg, end;
+ VALUE first, last;
if (!obj_is_kind_of(range, cRange)) return FALSE;
- beg = rb_iv_get(range, "start"); *begp = NUM2INT(beg);
- end = rb_iv_get(range, "end"); *endp = NUM2INT(end);
+ first = rb_iv_get(range, "first"); *begp = NUM2INT(first);
+ last = rb_iv_get(range, "last"); *endp = NUM2INT(last);
return TRUE;
}
+static VALUE
+range_to_s(range)
+ VALUE range;
+{
+ VALUE str, str2;
+
+ str = obj_as_string(rb_iv_get(range, "first"));
+ str2 = obj_as_string(rb_iv_get(range, "last"));
+ str_cat(str, "..", 2);
+ str_cat(str, RSTRING(str2)->ptr, RSTRING(str2)->len);
+
+ return str;
+}
+
+static VALUE
+range_inspect(range)
+ VALUE range;
+{
+ VALUE str, str2;
+
+ str = rb_inspect(rb_iv_get(range, "first"));
+ str2 = rb_inspect(rb_iv_get(range, "last"));
+ str_cat(str, "..", 2);
+ str_cat(str, RSTRING(str2)->ptr, RSTRING(str2)->len);
+
+ return str;
+}
+
+static VALUE
+range_length(rng)
+ VALUE rng;
+{
+ VALUE first, last;
+ VALUE size;
+
+ first = rb_iv_get(rng, "first");
+ last = rb_iv_get(rng, "last");
+
+ if (!obj_is_kind_of(first, cNumeric)) {
+ return enum_length(rng);
+ }
+ size = rb_funcall(last, '-', 1, first);
+ size = rb_funcall(size, '+', 1, INT2FIX(1));
+
+ return size;
+}
+
extern VALUE mEnumerable;
void
@@ -170,11 +197,15 @@ Init_Range()
cRange = rb_define_class("Range", cObject);
rb_include_module(cRange, mEnumerable);
rb_define_singleton_method(cRange, "new", range_s_new, 2);
- rb_define_method(cRange, "=~", range_match, 1);
+ rb_define_method(cRange, "===", range_match, 1);
rb_define_method(cRange, "each", range_each, 0);
- rb_define_method(cRange, "start", range_start, 0);
- rb_define_method(cRange, "end", range_end, 0);
+ rb_define_method(cRange, "first", range_first, 0);
+ rb_define_method(cRange, "last", range_last, 0);
rb_define_method(cRange, "to_s", range_to_s, 0);
+ rb_define_method(cRange, "inspect", range_inspect, 0);
+
+ rb_define_method(cRange, "length", range_length, 0);
+ rb_define_method(cRange, "size", range_length, 0);
upto = rb_intern("upto");
}