mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Initial revision
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
392296c12d
commit
3db12e8b23
225 changed files with 75935 additions and 0 deletions
211
range.c
Normal file
211
range.c
Normal file
|
@ -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");
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue