summaryrefslogtreecommitdiffhomepage
path: root/src/range.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/range.c')
-rw-r--r--src/range.c144
1 files changed, 52 insertions, 92 deletions
diff --git a/src/range.c b/src/range.c
index c1fb580b5..db17c7d40 100644
--- a/src/range.c
+++ b/src/range.c
@@ -7,30 +7,35 @@
#include "mruby.h"
#include "mruby/class.h"
#include "mruby/range.h"
-#include "mruby/variable.h"
-#include "error.h"
-#include "mruby/numeric.h"
#include "mruby/string.h"
-
-#include <stdio.h>
#include <string.h>
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
#ifndef OTHER
#define OTHER 2
#endif
#define RANGE_CLASS (mrb_class_obj_get(mrb, "Range"))
-mrb_value mrb_exec_recursive_paired(mrb_state *mrb, mrb_value (*func) (mrb_state *, mrb_value, mrb_value, int),
- mrb_value obj, mrb_value paired_obj, void* arg);
+static void
+range_check(mrb_state *mrb, mrb_value a, mrb_value b)
+{
+ mrb_value ans;
+ int ta;
+ int tb;
+
+ ta = mrb_type(a);
+ tb = mrb_type(b);
+ if ((ta == MRB_TT_FIXNUM || ta == MRB_TT_FLOAT) &&
+ (tb == MRB_TT_FIXNUM || tb == MRB_TT_FLOAT)) {
+ return;
+ }
+
+ ans = mrb_funcall(mrb, a, "<=>", 1, b);
+ if (mrb_nil_p(ans)) {
+ /* can not be compared */
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "bad value for range");
+ }
+}
mrb_value
mrb_range_new(mrb_state *mrb, mrb_value beg, mrb_value end, int excl)
@@ -38,7 +43,8 @@ mrb_range_new(mrb_state *mrb, mrb_value beg, mrb_value end, int excl)
struct RRange *r;
r = (struct RRange*)mrb_obj_alloc(mrb, MRB_TT_RANGE, RANGE_CLASS);
- r->edges = mrb_malloc(mrb, sizeof(struct mrb_range_edges));
+ r->edges = (struct mrb_range_edges *)mrb_malloc(mrb, sizeof(struct mrb_range_edges));
+ range_check(mrb, beg, end);
r->edges->beg = beg;
r->edges->end = end;
r->excl = excl;
@@ -93,41 +99,12 @@ mrb_range_excl(mrb_state *mrb, mrb_value range)
return r->excl ? mrb_true_value() : mrb_false_value();
}
-/*
- * call-seq:
- * beg end
- * args[0] <= args[1] => true
- * args[0] > args[1] => false
- */
-static int
-range_check(mrb_state *mrb, mrb_value *args)
-{
- mrb_value ans = mrb_funcall(mrb, args[0], "<=>", 1, args[1]);
- /* beg end
- ans :args[0] < args[1] => -1
- args[0] = args[1] => 0
- args[0] > args[1] => +1 */
- if (mrb_nil_p(ans)) return FALSE;
- //if (mrb_obj_equal(mrb, ans, mrb_fixnum_value(1))) return FALSE;
- if (mrb_fixnum(ans) == 1) return FALSE;
- return TRUE;
-}
-
static void
range_init(mrb_state *mrb, mrb_value range, mrb_value beg, mrb_value end, mrb_int exclude_end)
{
- mrb_value args[2];
struct RRange *r = mrb_range_ptr(range);
- if ((mrb_type(beg) != MRB_TT_FIXNUM) || (mrb_type(end) != MRB_TT_FIXNUM)) {
- args[0] = beg;
- args[1] = end;
- /* eroor.c v = mrb_rescue(range_check, (mrb_value)args, range_failed, 0);
- if (mrb_nil_p(v)) range_failed(); */
- if (!range_check(mrb, args)) {
- printf("range_failed()\n");
- }
- }
+ range_check(mrb, beg, end);
r->excl = exclude_end;
r->edges->beg = beg;
r->edges->end = end;
@@ -179,7 +156,6 @@ mrb_range_eq(mrb_state *mrb, mrb_value range)
if (mrb_obj_equal(mrb, range, obj)) return mrb_true_value();
/* same class? */
- // if (!rb_obj_is_instance_of(obj, rb_obj_class(range)))
if (!mrb_obj_is_instance_of(mrb, obj, mrb_obj_class(mrb, range)))
return mrb_false_value();
@@ -198,55 +174,41 @@ mrb_range_eq(mrb_state *mrb, mrb_value range)
static int
r_le(mrb_state *mrb, mrb_value a, mrb_value b)
{
- //int c;
mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */
/* output :a < b => -1, a = b => 0, a > b => +1 */
- if (mrb_nil_p(r)) return FALSE;
+ if (mrb_type(r) == MRB_TT_FIXNUM) {
+ int c = mrb_fixnum(r);
+ if (c == 0 || c == -1) return TRUE;
+ }
- /* mrb_value -> int */
- //c = mrb_cmpint(mrb, r, a, b);
- //if (c == 0) return TRUE;
- //if (c < 0) return TRUE;
- //return FALSE;
- if (mrb_obj_equal(mrb, r, mrb_fixnum_value(0))) return TRUE;
- if (mrb_obj_equal(mrb, r, mrb_fixnum_value(-1))) return TRUE;
return FALSE;
}
static int
r_gt(mrb_state *mrb, mrb_value a, mrb_value b)
{
- //int c;
mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b);
/* output :a < b => -1, a = b => 0, a > b => +1 */
- if (mrb_nil_p(r)) return FALSE;
+ if (mrb_type(r) == MRB_TT_FIXNUM) {
+ if (mrb_fixnum(r) == 1) return TRUE;
+ }
- /* mrb_value -> int */
- //c = mrb_cmpint(mrb, r);
- //if (c > 0) return TRUE;
- //return FALSE;
- if (mrb_obj_equal(mrb, r, mrb_fixnum_value(1))) return TRUE;
return FALSE;
}
static int
r_ge(mrb_state *mrb, mrb_value a, mrb_value b)
{
- //int c;
mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */
/* output :a < b => -1, a = b => 0, a > b => +1 */
- if (mrb_nil_p(r)) return FALSE;
+ if (mrb_type(r) == MRB_TT_FIXNUM) {
+ int c = mrb_fixnum(r);
+ if (c == 0 || c == 1) return TRUE;
+ }
- /* mrb_value -> int */
- //c = mrb_cmpint(mrb, r);
- //if (c == 0) return TRUE;
- //if (c > 0) return TRUE;
- //return FALSE;
- if (mrb_obj_equal(mrb, r, mrb_fixnum_value(0))) return TRUE;
- if (mrb_obj_equal(mrb, r, mrb_fixnum_value(1))) return TRUE;
return FALSE;
}
@@ -370,7 +332,12 @@ inspect_range(mrb_state *mrb, mrb_value range, mrb_value dummy, int recur)
struct RRange *r = mrb_range_ptr(range);
if (recur) {
- return mrb_str_new2(mrb, r->excl ? "(... ... ...)" : "(... .. ...)");
+ static const char s[2][14] = { "(... ... ...)", "(... .. ...)" };
+ static const int n[] = { 13, 12 };
+ int idx;
+
+ idx = (r->excl) ? 0 : 1;
+ return mrb_str_new(mrb, s[idx], n[idx]);
}
str = mrb_inspect(mrb, r->edges->beg);
str2 = mrb_inspect(mrb, r->edges->end);
@@ -397,23 +364,6 @@ range_inspect(mrb_state *mrb, mrb_value range)
return inspect_range(mrb, range, range, 0);
}
-static mrb_value
-recursive_eql(mrb_state *mrb, mrb_value range, mrb_value obj, int recur)
-{
- struct RRange *r = mrb_range_ptr(range);
- struct RRange *o = mrb_range_ptr(obj);
-
- if (recur) return mrb_true_value(); /* Subtle! */
- if (!mrb_eql(mrb, r->edges->beg, o->edges->beg))
- return mrb_false_value();
- if (!mrb_eql(mrb, r->edges->end, o->edges->end))
- return mrb_false_value();
-
- if (r->excl != o->excl)
- return mrb_false_value();
- return mrb_true_value();
-}
-
/* 15.2.14.4.14(x) */
/*
* call-seq:
@@ -433,13 +383,24 @@ static mrb_value
range_eql(mrb_state *mrb, mrb_value range)
{
mrb_value obj;
+ struct RRange *r, *o;
mrb_get_args(mrb, "o", &obj);
if (mrb_obj_equal(mrb, range, obj))
return mrb_true_value();
if (!mrb_obj_is_kind_of(mrb, obj, RANGE_CLASS))
return mrb_false_value();
- return mrb_exec_recursive_paired(mrb, recursive_eql, range, obj, &obj);
+
+ r = mrb_range_ptr(range);
+ if (obj.tt != MRB_TT_RANGE) return mrb_false_value();
+ o = mrb_range_ptr(obj);
+ if (!mrb_eql(mrb, r->edges->beg, o->edges->beg))
+ return mrb_false_value();
+ if (!mrb_eql(mrb, r->edges->end, o->edges->end))
+ return mrb_false_value();
+ if (r->excl != o->excl)
+ return mrb_false_value();
+ return mrb_true_value();
}
/* 15.2.14.4.15(x) */
@@ -451,7 +412,6 @@ range_initialize_copy(mrb_state *mrb, mrb_value copy)
mrb_get_args(mrb, "o", &src);
if (mrb_obj_equal(mrb, copy, src)) return copy;
- //mrb_check_frozen(copy);
if (!mrb_obj_is_instance_of(mrb, src, mrb_obj_class(mrb, copy))) {
mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class");
}