diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 1998-01-16 12:13:05 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 1998-01-16 12:13:05 +0000 |
commit | 3db12e8b236ac8f88db8eb4690d10e4a3b8dbcd4 (patch) | |
tree | b3c086e437cab449f90ba637710daed0ddfec4c4 /range.c | |
parent | 392296c12de9d7f9be03a8205250ba0844cb9d38 (diff) | |
download | ruby-3db12e8b236ac8f88db8eb4690d10e4a3b8dbcd4.tar.gz |
Initial revisionv1_0_r2
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'range.c')
-rw-r--r-- | range.c | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/range.c b/range.c new file mode 100644 index 0000000000..b7406a1e7a --- /dev/null +++ b/range.c @@ -0,0 +1,211 @@ +/************************************************ + + range.c - + + $Author$ + $Date$ + created at: Thu Aug 19 17:46:47 JST 1993 + + Copyright (C) 1993-1996 Yukihiro Matsumoto + +************************************************/ + +#include "ruby.h" + +VALUE mComparable; +static VALUE cRange; +extern VALUE cNumeric; + +static ID upto; + +static VALUE +range_s_new(class, first, last) + VALUE class, first, last; +{ + VALUE obj; + + 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, "first", first); + rb_iv_set(obj, "last", last); + + return obj; +} + +VALUE +range_new(first, last) + VALUE first, last; +{ + return range_s_new(cRange, first, last); +} + +static VALUE +range_eqq(rng, obj) + VALUE rng, obj; +{ + VALUE first, last; + + first = rb_iv_get(rng, "first"); + last = rb_iv_get(rng, "last"); + + if (FIXNUM_P(first) && FIXNUM_P(obj) && FIXNUM_P(last)) { + if (FIX2INT(first) <= FIX2INT(obj) && FIX2INT(obj) <= FIX2INT(last)) { + return TRUE; + } + return FALSE; + } + else { + if (RTEST(rb_funcall(first, rb_intern("<="), 1, obj)) && + RTEST(rb_funcall(last, rb_intern(">="), 1, obj))) { + return TRUE; + } + return FALSE; + } +} + +struct upto_data { + VALUE first; + VALUE last; +}; + +static VALUE +range_upto(data) + struct upto_data *data; +{ + return rb_funcall(data->first, upto, 1, data->last); +} + +static VALUE +range_each(obj) + VALUE obj; +{ + VALUE b, e; + + 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 { + struct upto_data data; + + data.first = b; + data.last = e; + + rb_iterate(range_upto, &data, rb_yield, 0); + } + + return Qnil; +} + +static VALUE +range_first(obj) + VALUE obj; +{ + VALUE b; + + b = rb_iv_get(obj, "first"); + return b; +} + +static VALUE +range_last(obj) + VALUE obj; +{ + VALUE e; + + e = rb_iv_get(obj, "last"); + return e; +} + +VALUE +range_beg_end(range, begp, endp) + VALUE range; + int *begp, *endp; +{ + VALUE first, last; + + if (!obj_is_kind_of(range, cRange)) return FALSE; + + 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 +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_eqq, 1); + rb_define_method(cRange, "each", range_each, 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"); +} |