Пример #1
0
mrb_value
mrb_range_eq(mrb_state *mrb, mrb_value range)
{
  struct RRange *rr;
  struct RRange *ro;
  mrb_value obj;

  mrb_get_args(mrb, "o", &obj);

  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();

  rr = mrb_range_ptr(range);
  ro = mrb_range_ptr(obj);
  if (!mrb_obj_equal(mrb, rr->edges->beg, ro->edges->beg))
    return mrb_false_value();
  if (!mrb_obj_equal(mrb, rr->edges->end, ro->edges->end))
    return mrb_false_value();
  if (rr->excl != ro->excl)
    return mrb_false_value();

  return mrb_true_value();
}
Пример #2
0
/* 15.2.14.4.15(x) */
mrb_value
range_initialize_copy(mrb_state *mrb, mrb_value copy)
{
  mrb_value src;
  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");
    }
    memcpy(mrb_range_ptr(copy), mrb_range_ptr(src), sizeof(struct RRange));

    return copy;
}
Пример #3
0
Файл: range.c Проект: jjue/mruby
/* 15.2.14.4.15(x) */
mrb_value
range_initialize_copy(mrb_state *mrb, mrb_value copy)
{
  mrb_value src;

  mrb_get_args(mrb, "o", &src);

  if (mrb_obj_equal(mrb, copy, src)) return copy;
  if (!mrb_obj_is_instance_of(mrb, src, mrb_obj_class(mrb, copy))) {
    mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class");
  }
  *mrb_range_ptr(copy) = *mrb_range_ptr(src);

  return copy;
}
Пример #4
0
/*
 *  call-seq:
 *     range.exclude_end?    => true or false
 *
 *  Returns <code>true</code> if <i>range</i> excludes its end value.
 */
mrb_value
mrb_range_excl(mrb_state *mrb, mrb_value range)
{
  struct RRange *r = mrb_range_ptr(range);

  return mrb_bool_value(r->excl);
}
Пример #5
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();
}
Пример #6
0
MRB_API mrb_bool
range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc)
{
  mrb_int beg, end, b, e;
  struct RRange *r = mrb_range_ptr(range);

  if (mrb_type(range) != MRB_TT_RANGE) return FALSE;

  beg = b = mrb_int(mrb, r->edges->beg);
  end = e = mrb_int(mrb, r->edges->end);

  if (beg < 0) {
    beg += len;
    if (beg < 0) return FALSE;
  }

  if (trunc) {
    if (beg > len) return FALSE;
    if (end > len) end = len;
  }

  if (end < 0) end += len;
  if (!r->excl && (!trunc || end < len))
    end++;                      /* include end point */
  len = end - beg;
  if (len < 0) len = 0;

  *begp = beg;
  *lenp = len;
  return TRUE;
}
Пример #7
0
/*
 *  call-seq:
 *     rng.cover?(obj)  ->  true or false
 *
 *  Returns <code>true</code> if +obj+ is between the begin and end of
 *  the range.
 *
 *  This tests <code>begin <= obj <= end</code> when #exclude_end? is +false+
 *  and <code>begin <= obj < end</code> when #exclude_end? is +true+.
 *
 *     ("a".."z").cover?("c")    #=> true
 *     ("a".."z").cover?("5")    #=> false
 *     ("a".."z").cover?("cc")   #=> true
 */
static mrb_value
mrb_range_cover(mrb_state *mrb, mrb_value range)
{
  mrb_value val;
  struct RRange *r = mrb_range_ptr(mrb, range);
  mrb_value beg, end;

  mrb_get_args(mrb, "o", &val);

  beg = r->edges->beg;
  end = r->edges->end;

  if (r_le(mrb, beg, val)) {
    if (r->excl) {
      if (r_lt(mrb, val, end))
        return mrb_true_value();
    }
    else {
      if (r_le(mrb, val, end))
        return mrb_true_value();
    }
  }

  return mrb_false_value();
}
Пример #8
0
mrb_int
mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_int err)
{
  mrb_int beg, end, b, e;
  struct RRange *r = mrb_range_ptr(range);

  if (mrb_type(range) != MRB_TT_RANGE) return FALSE;

  beg = b = mrb_fixnum(r->edges->beg);
  end = e = mrb_fixnum(r->edges->end);

  if (beg < 0) {
    beg += len;
    if (beg < 0) goto out_of_range;
  }
  if (err == 0 || err == 2) {
    if (beg > len) goto out_of_range;
    if (end > len) end = len;
  }
  if (end < 0) end += len;
  if (!r->excl) end++;  /* include end point */
  len = end - beg;
  if (len < 0) len = 0;

  *begp = beg;
  *lenp = len;
  return TRUE;

out_of_range:
  if (err) {
    mrb_raise(mrb, E_RANGE_ERROR, "%ld..%s%ld out of range",
      b, r->excl? "." : "", e);
  }
  return OTHER;
}
Пример #9
0
mrb_value
mrb_range_end(mrb_state *mrb, mrb_value range)
{
  struct RRange *r = mrb_range_ptr(range);

  return r->edges->end;
}
Пример #10
0
mrb_int
mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len)
{
  mrb_int beg, end, b, e;
  struct RRange *r = mrb_range_ptr(range);

  if (mrb_type(range) != MRB_TT_RANGE) {
    mrb_raise(mrb, E_TYPE_ERROR, "expected Range.");
  }

  beg = b = mrb_fixnum(r->edges->beg);
  end = e = mrb_fixnum(r->edges->end);

  if (beg < 0) {
    beg += len;
    if (beg < 0) return FALSE;
  }

  if (beg > len) return FALSE;
  if (end > len) end = len;

  if (end < 0) end += len;
  if (!r->excl && end < len) end++;  /* include end point */
  len = end - beg;
  if (len < 0) len = 0;

  *begp = beg;
  *lenp = len;
  return TRUE;
}
Пример #11
0
/*
 *  call-seq:
 *     range.exclude_end?    => true or false
 *
 *  Returns <code>true</code> if <i>range</i> excludes its end value.
 */
mrb_value
mrb_range_excl(mrb_state *mrb, mrb_value range)
{
  struct RRange *r = mrb_range_ptr(range);

  return r->excl ? mrb_true_value() : mrb_false_value();
}
Пример #12
0
Файл: range.c Проект: jjue/mruby
static void
range_init(mrb_state *mrb, mrb_value range, mrb_value beg, mrb_value end, mrb_int exclude_end)
{
  struct RRange *r = mrb_range_ptr(range);

  range_check(mrb, beg, end);
  r->excl = exclude_end;
  r->edges->beg = beg;
  r->edges->end = end;
}
Пример #13
0
static mrb_value
mrb_range_size(mrb_state *mrb, mrb_value range)
{
  struct RRange *r = mrb_range_ptr(mrb, range);
  mrb_value beg, end;
  mrb_float beg_f, end_f;
  mrb_bool num_p = TRUE;
  mrb_bool excl;

  beg = r->edges->beg;
  end = r->edges->end;
  excl = r->excl;
  if (mrb_fixnum_p(beg)) {
    beg_f = (mrb_float)mrb_fixnum(beg);
  }
  else if (mrb_float_p(beg)) {
    beg_f = mrb_float(beg);
  }
  else {
    num_p = FALSE;
  }
  if (mrb_fixnum_p(end)) {
    end_f = (mrb_float)mrb_fixnum(end);
  }
  else if (mrb_float_p(end)) {
    end_f = mrb_float(end);
  }
  else {
    num_p = FALSE;
  }
  if (num_p) {
    mrb_float n = end_f - beg_f;
    mrb_float err = (fabs(beg_f) + fabs(end_f) + fabs(end_f-beg_f)) * MRB_FLOAT_EPSILON;

    if (err>0.5) err=0.5;
    if (excl) {
      if (n<=0) return mrb_fixnum_value(0);
      if (n<1)
        n = 0;
      else
        n = floor(n - err);
    }
    else {
      if (n<0) return mrb_fixnum_value(0);
      n = floor(n + err);
    }
    if (isinf(n+1))
      return mrb_float_value(mrb, INFINITY);
    return mrb_fixnum_value(n+1);
  }
  return mrb_nil_value();
}
Пример #14
0
static void
range_init(mrb_state *mrb, mrb_value range, mrb_value beg, mrb_value end, mrb_bool exclude_end)
{
  struct RRange *r = mrb_range_ptr(range);

  range_check(mrb, beg, end);
  r->excl = exclude_end;
  if (!r->edges) {
    r->edges = (mrb_range_edges *)mrb_malloc(mrb, sizeof(mrb_range_edges));
  }
  r->edges->beg = beg;
  r->edges->end = end;
}
Пример #15
0
mrb_value
mrb_range_eq(mrb_state *mrb, mrb_value range)
{
  struct RRange *rr;
  struct RRange *ro;
  mrb_value obj;

  mrb_get_args(mrb, "o", &obj);

  if (mrb_obj_equal(mrb, range, obj)) return mrb_true_value();
  if (!mrb_obj_is_instance_of(mrb, obj, mrb_obj_class(mrb, range))) { /* same class? */
    return mrb_false_value();
  }

  rr = mrb_range_ptr(range);
  ro = mrb_range_ptr(obj);
  if (!mrb_bool(mrb_funcall(mrb, rr->edges->beg, "==", 1, ro->edges->beg)) ||
      !mrb_bool(mrb_funcall(mrb, rr->edges->end, "==", 1, ro->edges->end)) ||
      rr->excl != ro->excl) {
    return mrb_false_value();
  }
  return mrb_true_value();
}
Пример #16
0
/*
 *  call-seq:
 *     rng.last    -> obj
 *     rng.last(n) -> an_array
 *
 *  Returns the last object in the range,
 *  or an array of the last +n+ elements.
 *
 *  Note that with no arguments +last+ will return the object that defines
 *  the end of the range even if #exclude_end? is +true+.
 *
 *    (10..20).last      #=> 20
 *    (10...20).last     #=> 20
 *    (10..20).last(3)   #=> [18, 19, 20]
 *    (10...20).last(3)  #=> [17, 18, 19]
 */
static mrb_value
mrb_range_last(mrb_state *mrb, mrb_value range)
{
  mrb_value num;
  mrb_value array;
  struct RRange *r = mrb_range_ptr(mrb, range);

  if (mrb_get_args(mrb, "|o", &num) == 0) {
    return r->edges->end;
  }

  array = mrb_funcall(mrb, range, "to_a", 0);
  return mrb_funcall(mrb, array, "last", 1, mrb_to_int(mrb, num));
}
Пример #17
0
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();
  }
  if (mrb_type(obj) != MRB_TT_RANGE) return mrb_false_value();

  r = mrb_range_ptr(range);
  o = mrb_range_ptr(obj);
  if (!mrb_eql(mrb, r->edges->beg, o->edges->beg) ||
      !mrb_eql(mrb, r->edges->end, o->edges->end) ||
      (r->excl != o->excl)) {
    return mrb_false_value();
  }
  return mrb_true_value();
}
Пример #18
0
static mrb_value
range_to_s(mrb_state *mrb, mrb_value range)
{
  mrb_value str, str2;
  struct RRange *r = mrb_range_ptr(range);

  str  = mrb_obj_as_string(mrb, r->edges->beg);
  str2 = mrb_obj_as_string(mrb, r->edges->end);
  str  = mrb_str_dup(mrb, str);
  mrb_str_cat(mrb, str, "...", r->excl ? 3 : 2);
  mrb_str_append(mrb, str, str2);

  return str;
}
Пример #19
0
static mrb_value
inspect_range(mrb_state *mrb, mrb_value range, mrb_value dummy, int recur)
{
  mrb_value str, str2;
  struct RRange *r = mrb_range_ptr(range);

  if (recur) {
    return mrb_str_new2(mrb, r->excl ? "(... ... ...)" : "(... .. ...)");
  }
  str  = mrb_inspect(mrb, r->edges->beg);
  str2 = mrb_inspect(mrb, r->edges->end);
  str  = mrb_str_dup(mrb, str);
  mrb_str_cat(mrb, str, "...", r->excl ? 3 : 2);
  mrb_str_append(mrb, str, str2);

  return str;
}
Пример #20
0
/*
 *  call-seq:
 *     range === obj       =>  true or false
 *     range.member?(val)  =>  true or false
 *     range.include?(val) =>  true or false
 *
 */
mrb_value
mrb_range_include(mrb_state *mrb, mrb_value range)
{
  mrb_value val;
  struct RRange *r = mrb_range_ptr(range);
  mrb_value beg, end;
  mrb_bool include_p;

  mrb_get_args(mrb, "o", &val);

  beg = r->edges->beg;
  end = r->edges->end;
  include_p = r_le(mrb, beg, val) && /* beg <= val */
              ((r->excl && r_gt(mrb, end, val)) || /* end >  val */
              (r_ge(mrb, end, val))); /* end >= val */

  return mrb_bool_value(include_p);
}
Пример #21
0
/* 15.2.14.4.15(x) */
static mrb_value
range_initialize_copy(mrb_state *mrb, mrb_value copy)
{
  mrb_value src;
  struct RRange *r;

  mrb_get_args(mrb, "o", &src);

  if (mrb_obj_equal(mrb, copy, src)) return copy;
  if (!mrb_obj_is_instance_of(mrb, src, mrb_obj_class(mrb, copy))) {
    mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class");
  }

  r = mrb_range_ptr(src);
  range_init(mrb, copy, r->edges->beg, r->edges->end, r->excl);

  return copy;
}
Пример #22
0
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");
    }
  }
  r->excl = exclude_end;
  r->edges->beg = beg;
  r->edges->end = end;
}
Пример #23
0
Файл: range.c Проект: jjue/mruby
static mrb_value
inspect_range(mrb_state *mrb, mrb_value range, mrb_value dummy, int recur)
{
  mrb_value str, str2;
  struct RRange *r = mrb_range_ptr(range);

  if (recur) {
    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);
  str  = mrb_str_dup(mrb, str);
  mrb_str_cat(mrb, str, "...", r->excl ? 3 : 2);
  mrb_str_append(mrb, str, str2);

  return str;
}
Пример #24
0
/*
 *  call-seq:
 *     range === obj       =>  true or false
 *     range.member?(val)  =>  true or false
 *     range.include?(val) =>  true or false
 *
 */
mrb_value
mrb_range_include(mrb_state *mrb, mrb_value range)
{
  mrb_value val;
  struct RRange *r = mrb_range_ptr(range);
  mrb_value beg, end;

  mrb_get_args(mrb, "o", &val);

  beg = r->edges->beg;
  end = r->edges->end;
  if (r_le(mrb, beg, val)) {
    /* beg <= val */
    if (r->excl) {
      if (r_gt(mrb, end, val)) return mrb_true_value(); /* end >  val */
    }
    else {
      if (r_ge(mrb, end, val)) return mrb_true_value(); /* end >= val */
    }
  }
  return mrb_false_value();
}
Пример #25
0
static mrb_bool
is_safe_migratable_simple_value(mrb_state *mrb, mrb_value v, mrb_state *mrb2)
{
  switch (mrb_type(v)) {
  case MRB_TT_OBJECT:
  case MRB_TT_EXCEPTION:
    {
      struct RObject *o = mrb_obj_ptr(v);
      mrb_value path = mrb_class_path(mrb, o->c);

      if (mrb_nil_p(path) || !mrb_class_defined(mrb2, RSTRING_PTR(path))) {
        return FALSE;
      }
    }
    break;
  case MRB_TT_FALSE:
  case MRB_TT_TRUE:
  case MRB_TT_FIXNUM:
  case MRB_TT_SYMBOL:
  case MRB_TT_FLOAT:
  case MRB_TT_STRING:
    break;
  case MRB_TT_RANGE:
    {
      struct RRange *r = mrb_range_ptr(v);
      if (!is_safe_migratable_simple_value(mrb, r->edges->beg, mrb2) ||
          !is_safe_migratable_simple_value(mrb, r->edges->end, mrb2)) {
        return FALSE;
      }
    }
    break;
  case MRB_TT_ARRAY:
    {
      struct RArray *a0;
      int i;
      a0 = mrb_ary_ptr(v);
      for (i=0; i<a0->len; i++) {
        if (!is_safe_migratable_simple_value(mrb, a0->ptr[i], mrb2)) {
          return FALSE;
        }
      }
    }
    break;
  case MRB_TT_HASH:
    {
      mrb_value ka;
      int i, l;
      ka = mrb_hash_keys(mrb, v);
      l = RARRAY_LEN(ka);
      for (i = 0; i < l; i++) {
        mrb_value k = mrb_ary_entry(ka, i);
        if (!is_safe_migratable_simple_value(mrb, k, mrb2) ||
            !is_safe_migratable_simple_value(mrb, mrb_hash_get(mrb, v, k), mrb2)) {
          return FALSE;
        }
      }
    }
    break;
  case MRB_TT_DATA:
    if (!is_safe_migratable_datatype(DATA_TYPE(v)))
      return FALSE;
    break;
  default:
    return FALSE;
    break;
  }
  return TRUE;
}
Пример #26
0
// based on https://gist.github.com/3066997
static mrb_value
migrate_simple_value(mrb_state *mrb, mrb_value v, mrb_state *mrb2) {
  mrb_value nv;

  switch (mrb_type(v)) {
  case MRB_TT_OBJECT:
  case MRB_TT_EXCEPTION:
    {
      struct RObject *o = mrb_obj_ptr(v);
      mrb_value path = mrb_class_path(mrb, o->c);
      struct RClass *c;

      if (mrb_nil_p(path)) {
        mrb_raise(mrb, E_TYPE_ERROR, "cannot migrate class");
      }
      c = mrb_class_get(mrb2, RSTRING_PTR(path));
      nv = mrb_obj_value(mrb_obj_alloc(mrb2, mrb_type(v), c));
    }
    migrate_simple_iv(mrb, v, mrb2, nv);
    break;
  case MRB_TT_FALSE:
  case MRB_TT_TRUE:
  case MRB_TT_FIXNUM:
    nv = v;
    break;
  case MRB_TT_SYMBOL:
    nv = mrb_symbol_value(migrate_sym(mrb, mrb_symbol(v), mrb2));
    break;
  case MRB_TT_FLOAT:
    nv = mrb_float_value(mrb2, mrb_float(v));
    break;
  case MRB_TT_STRING:
    nv = mrb_str_new(mrb2, RSTRING_PTR(v), RSTRING_LEN(v));
    break;
  case MRB_TT_RANGE:
    {
      struct RRange *r = mrb_range_ptr(v);
      nv = mrb_range_new(mrb2,
                         migrate_simple_value(mrb, r->edges->beg, mrb2),
                         migrate_simple_value(mrb, r->edges->end, mrb2),
                         r->excl);
    }
    break;
  case MRB_TT_ARRAY:
    {
      struct RArray *a0, *a1;
      int i;

      a0 = mrb_ary_ptr(v);
      nv = mrb_ary_new_capa(mrb2, a0->len);
      a1 = mrb_ary_ptr(nv);
      for (i=0; i<a0->len; i++) {
        int ai = mrb_gc_arena_save(mrb2);
        a1->ptr[i] = migrate_simple_value(mrb, a0->ptr[i], mrb2);
        a1->len++;
        mrb_gc_arena_restore(mrb2, ai);
      }
    }
    break;
  case MRB_TT_HASH:
    {
      mrb_value ka;
      int i, l;

      nv = mrb_hash_new(mrb2);
      ka = mrb_hash_keys(mrb, v);
      l = RARRAY_LEN(ka);
      for (i = 0; i < l; i++) {
        int ai = mrb_gc_arena_save(mrb2);
        mrb_value k = migrate_simple_value(mrb, mrb_ary_entry(ka, i), mrb2);
        mrb_value o = migrate_simple_value(mrb, mrb_hash_get(mrb, v, k), mrb2);
        mrb_hash_set(mrb2, nv, k, o);
        mrb_gc_arena_restore(mrb2, ai);
      }
    }
    migrate_simple_iv(mrb, v, mrb2, nv);
    break;
  case MRB_TT_DATA:
    if (!is_safe_migratable_datatype(DATA_TYPE(v)))
      mrb_raise(mrb, E_TYPE_ERROR, "cannot migrate object");
    nv = v;
    DATA_PTR(nv) = DATA_PTR(v);
    DATA_TYPE(nv) = DATA_TYPE(v);
    migrate_simple_iv(mrb, v, mrb2, nv);
    break;
  default:
    mrb_raise(mrb, E_TYPE_ERROR, "cannot migrate object");
    break;
  }
  return nv;
}