diff options
Diffstat (limited to 'src/range.c')
| -rw-r--r-- | src/range.c | 144 |
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"); } |
