Permalink
Browse files

proper type check when creating a range; #345

  • Loading branch information...
1 parent becb7e9 commit 0d99856b57f172948c4e579c8f96cc19aa3d8568 @matz matz committed Jul 7, 2012
Showing with 27 additions and 33 deletions.
  1. +26 −32 src/range.c
  2. +1 −1 test/t/bs_block.rb
View
@@ -21,13 +21,38 @@
#define RANGE_CLASS (mrb_class_obj_get(mrb, "Range"))
+static void
+range_check(mrb_state *mrb, mrb_value a, mrb_value b)
+{
+ mrb_value ans;
+
+ switch (mrb_type(a)) {
+ case MRB_TT_FIXNUM:
+ case MRB_TT_FLOAT:
+ switch (mrb_type(b)) {
+ case MRB_TT_FIXNUM:
+ case MRB_TT_FLOAT:
+ return;
+ }
+ }
+
+ mrb_p(mrb, a);
+ mrb_p(mrb, b);
+ 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)
{
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));
+ range_check(mrb, beg, end);
r->edges->beg = beg;
r->edges->end = end;
r->excl = excl;
@@ -82,39 +107,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;
- 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;
@@ -166,7 +164,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();
@@ -199,20 +196,17 @@ r_le(mrb_state *mrb, mrb_value a, mrb_value b)
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_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 */
View
@@ -62,7 +62,7 @@ def each(&block)
assert('BS Block 7') do
ans = []
for m in 1..3
- for n in 1..3
+ for n in 2..4
a = [m, n]
ans << a
end

0 comments on commit 0d99856

Please sign in to comment.