Ignore:
Timestamp:
Jul 9, 2020, 8:51:43 AM (4 years ago)
Author:
coas-nagasima
Message:

mrubyを2.1.1に更新

Location:
EcnlProtoTool/trunk/mruby-2.1.1
Files:
1 edited
1 moved

Legend:

Unmodified
Added
Removed
  • EcnlProtoTool/trunk/mruby-2.1.1/src/range.c

    r331 r439  
    1111#include <mruby/array.h>
    1212
    13 #define RANGE_CLASS (mrb_class_get(mrb, "Range"))
    14 
    15 MRB_API struct RRange*
    16 mrb_range_ptr(mrb_state *mrb, mrb_value v)
    17 {
    18   struct RRange *r = (struct RRange*)mrb_ptr(v);
    19 
    20   if (r->edges == NULL) {
    21     mrb_raise(mrb, E_ARGUMENT_ERROR, "uninitialized range");
    22   }
    23   return r;
    24 }
     13#define RANGE_INITIALIZED_MASK 1
     14#define RANGE_INITIALIZED(p) ((p)->flags |= RANGE_INITIALIZED_MASK)
     15#define RANGE_INITIALIZED_P(p) ((p)->flags & RANGE_INITIALIZED_MASK)
    2516
    2617static void
    27 range_check(mrb_state *mrb, mrb_value a, mrb_value b)
    28 {
    29   mrb_value ans;
     18r_check(mrb_state *mrb, mrb_value a, mrb_value b)
     19{
    3020  enum mrb_vtype ta;
    3121  enum mrb_vtype tb;
     22  mrb_int n;
    3223
    3324  ta = mrb_type(a);
    3425  tb = mrb_type(b);
     26#ifdef MRB_WITHOUT_FLOAT
     27  if (ta == MRB_TT_FIXNUM && tb == MRB_TT_FIXNUM ) {
     28#else
    3529  if ((ta == MRB_TT_FIXNUM || ta == MRB_TT_FLOAT) &&
    3630      (tb == MRB_TT_FIXNUM || tb == MRB_TT_FLOAT)) {
     31#endif
    3732    return;
    3833  }
    3934
    40   ans =  mrb_funcall(mrb, a, "<=>", 1, b);
    41   if (mrb_nil_p(ans)) {
    42     /* can not be compared */
     35  n = mrb_cmp(mrb, a, b);
     36  if (n == -2) {                /* can not be compared */
    4337    mrb_raise(mrb, E_ARGUMENT_ERROR, "bad value for range");
    4438  }
    4539}
    4640
    47 MRB_API mrb_value
    48 mrb_range_new(mrb_state *mrb, mrb_value beg, mrb_value end, mrb_bool excl)
    49 {
    50   struct RRange *r;
    51 
    52   range_check(mrb, beg, end);
    53   r = (struct RRange*)mrb_obj_alloc(mrb, MRB_TT_RANGE, RANGE_CLASS);
     41static mrb_bool
     42r_le(mrb_state *mrb, mrb_value a, mrb_value b)
     43{
     44  mrb_int n = mrb_cmp(mrb, a, b);
     45
     46  if (n == 0 || n == -1) return TRUE;
     47  return FALSE;
     48}
     49
     50static mrb_bool
     51r_gt(mrb_state *mrb, mrb_value a, mrb_value b)
     52{
     53  return mrb_cmp(mrb, a, b) == 1;
     54}
     55
     56static mrb_bool
     57r_ge(mrb_state *mrb, mrb_value a, mrb_value b)
     58{
     59  mrb_int n = mrb_cmp(mrb, a, b);
     60
     61  if (n == 0 || n == 1) return TRUE;
     62  return FALSE;
     63}
     64
     65static void
     66range_ptr_alloc_edges(mrb_state *mrb, struct RRange *r)
     67{
     68#ifndef MRB_RANGE_EMBED
    5469  r->edges = (mrb_range_edges *)mrb_malloc(mrb, sizeof(mrb_range_edges));
    55   r->edges->beg = beg;
    56   r->edges->end = end;
    57   r->excl = excl;
    58   return mrb_range_value(r);
     70#endif
     71}
     72
     73static struct RRange *
     74range_ptr_init(mrb_state *mrb, struct RRange *r, mrb_value beg, mrb_value end, mrb_bool excl)
     75{
     76  r_check(mrb, beg, end);
     77
     78  if (r) {
     79    if (RANGE_INITIALIZED_P(r)) {
     80      /* Ranges are immutable, so that they should be initialized only once. */
     81      mrb_name_error(mrb, mrb_intern_lit(mrb, "initialize"), "'initialize' called twice");
     82    }
     83    else {
     84      range_ptr_alloc_edges(mrb, r);
     85    }
     86  }
     87  else {
     88    r = (struct RRange*)mrb_obj_alloc(mrb, MRB_TT_RANGE, mrb->range_class);
     89    range_ptr_alloc_edges(mrb, r);
     90  }
     91
     92  RANGE_BEG(r) = beg;
     93  RANGE_END(r) = end;
     94  RANGE_EXCL(r) = excl;
     95  RANGE_INITIALIZED(r);
     96
     97  return r;
     98}
     99
     100static void
     101range_ptr_replace(mrb_state *mrb, struct RRange *r, mrb_value beg, mrb_value end, mrb_bool excl)
     102{
     103  range_ptr_init(mrb, r, beg, end, excl);
     104  mrb_write_barrier(mrb, (struct RBasic*)r);
    59105}
    60106
     
    66112 *  Returns the first object in <i>rng</i>.
    67113 */
    68 mrb_value
    69 mrb_range_beg(mrb_state *mrb, mrb_value range)
    70 {
    71   struct RRange *r = mrb_range_ptr(mrb, range);
    72 
    73   return r->edges->beg;
     114static mrb_value
     115range_beg(mrb_state *mrb, mrb_value range)
     116{
     117  return mrb_range_beg(mrb, range);
    74118}
    75119
     
    84128 *     (1...10).end   #=> 10
    85129 */
    86 
    87 mrb_value
    88 mrb_range_end(mrb_state *mrb, mrb_value range)
    89 {
    90   struct RRange *r = mrb_range_ptr(mrb, range);
    91 
    92   return r->edges->end;
     130static mrb_value
     131range_end(mrb_state *mrb, mrb_value range)
     132{
     133  return mrb_range_end(mrb, range);
    93134}
    94135
     
    99140 *  Returns <code>true</code> if <i>range</i> excludes its end value.
    100141 */
    101 mrb_value
    102 mrb_range_excl(mrb_state *mrb, mrb_value range)
    103 {
    104   struct RRange *r = mrb_range_ptr(mrb, range);
    105 
    106   return mrb_bool_value(r->excl);
    107 }
    108 
    109 static void
    110 range_init(mrb_state *mrb, mrb_value range, mrb_value beg, mrb_value end, mrb_bool exclude_end)
    111 {
    112   struct RRange *r = mrb_range_raw_ptr(range);
    113 
    114   range_check(mrb, beg, end);
    115   r->excl = exclude_end;
    116   if (!r->edges) {
    117     r->edges = (mrb_range_edges *)mrb_malloc(mrb, sizeof(mrb_range_edges));
    118   }
    119   r->edges->beg = beg;
    120   r->edges->end = end;
    121 }
     142static mrb_value
     143range_excl(mrb_state *mrb, mrb_value range)
     144{
     145  return mrb_bool_value(mrb_range_excl_p(mrb, range));
     146}
     147
    122148/*
    123149 *  call-seq:
     
    128154 *  the end object; otherwise, it will be excluded.
    129155 */
    130 
    131 mrb_value
    132 mrb_range_initialize(mrb_state *mrb, mrb_value range)
     156static mrb_value
     157range_initialize(mrb_state *mrb, mrb_value range)
    133158{
    134159  mrb_value beg, end;
    135   mrb_bool exclusive;
    136   int n;
    137 
    138   n = mrb_get_args(mrb, "oo|b", &beg, &end, &exclusive);
    139   if (n != 3) {
    140     exclusive = FALSE;
    141   }
    142   /* Ranges are immutable, so that they should be initialized only once. */
    143   if (mrb_range_raw_ptr(range)->edges) {
    144     mrb_name_error(mrb, mrb_intern_lit(mrb, "initialize"), "`initialize' called twice");
    145   }
    146   range_init(mrb, range, beg, end, exclusive);
     160  mrb_bool exclusive = FALSE;
     161
     162  mrb_get_args(mrb, "oo|b", &beg, &end, &exclusive);
     163  range_ptr_replace(mrb, mrb_range_raw_ptr(range), beg, end, exclusive);
    147164  return range;
    148165}
     166
    149167/*
    150168 *  call-seq:
     
    159177 *    (0..2) == Range.new(0,2)    #=> true
    160178 *    (0..2) == (0...2)           #=> false
    161  *
    162  */
    163 
    164 mrb_value
    165 mrb_range_eq(mrb_state *mrb, mrb_value range)
     179 */
     180static mrb_value
     181range_eq(mrb_state *mrb, mrb_value range)
    166182{
    167183  struct RRange *rr;
    168184  struct RRange *ro;
    169   mrb_value obj, v1, v2;
     185  mrb_value obj;
     186  mrb_bool v1, v2;
    170187
    171188  mrb_get_args(mrb, "o", &obj);
     
    178195  rr = mrb_range_ptr(mrb, range);
    179196  ro = mrb_range_ptr(mrb, obj);
    180   v1 = mrb_funcall(mrb, rr->edges->beg, "==", 1, ro->edges->beg);
    181   v2 = mrb_funcall(mrb, rr->edges->end, "==", 1, ro->edges->end);
    182   if (!mrb_bool(v1) || !mrb_bool(v2) || rr->excl != ro->excl) {
     197  v1 = mrb_equal(mrb, RANGE_BEG(rr), RANGE_BEG(ro));
     198  v2 = mrb_equal(mrb, RANGE_END(rr), RANGE_END(ro));
     199  if (!v1 || !v2 || RANGE_EXCL(rr) != RANGE_EXCL(ro)) {
    183200    return mrb_false_value();
    184201  }
    185202  return mrb_true_value();
    186 }
    187 
    188 static mrb_bool
    189 r_le(mrb_state *mrb, mrb_value a, mrb_value b)
    190 {
    191   mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */
    192   /* output :a < b => -1, a = b =>  0, a > b => +1 */
    193 
    194   if (mrb_fixnum_p(r)) {
    195     mrb_int c = mrb_fixnum(r);
    196     if (c == 0 || c == -1) return TRUE;
    197   }
    198 
    199   return FALSE;
    200 }
    201 
    202 static mrb_bool
    203 r_gt(mrb_state *mrb, mrb_value a, mrb_value b)
    204 {
    205   mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b);
    206   /* output :a < b => -1, a = b =>  0, a > b => +1 */
    207 
    208   return mrb_fixnum_p(r) && mrb_fixnum(r) == 1;
    209 }
    210 
    211 static mrb_bool
    212 r_ge(mrb_state *mrb, mrb_value a, mrb_value b)
    213 {
    214   mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */
    215   /* output :a < b => -1, a = b =>  0, a > b => +1 */
    216 
    217   if (mrb_fixnum_p(r)) {
    218     mrb_int c = mrb_fixnum(r);
    219     if (c == 0 || c == 1) return TRUE;
    220   }
    221 
    222   return FALSE;
    223203}
    224204
     
    228208 *     range.member?(val)  =>  true or false
    229209 *     range.include?(val) =>  true or false
    230  *
    231  */
    232 mrb_value
    233 mrb_range_include(mrb_state *mrb, mrb_value range)
     210 */
     211static mrb_value
     212range_include(mrb_state *mrb, mrb_value range)
    234213{
    235214  mrb_value val;
     
    240219  mrb_get_args(mrb, "o", &val);
    241220
    242   beg = r->edges->beg;
    243   end = r->edges->end;
    244   include_p = r_le(mrb, beg, val) &&           /* beg <= val */
    245               (r->excl ? r_gt(mrb, end, val)   /* end >  val */
    246                        : r_ge(mrb, end, val)); /* end >= val */
     221  beg = RANGE_BEG(r);
     222  end = RANGE_END(r);
     223  include_p = r_le(mrb, beg, val) &&                 /* beg <= val */
     224              (RANGE_EXCL(r) ? r_gt(mrb, end, val)   /* end >  val */
     225                             : r_ge(mrb, end, val)); /* end >= val */
    247226
    248227  return mrb_bool_value(include_p);
    249 }
    250 
    251 MRB_API mrb_int
    252 mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc)
    253 {
    254   mrb_int beg, end;
    255   struct RRange *r;
    256 
    257   if (mrb_type(range) != MRB_TT_RANGE) return 0;
    258   r = mrb_range_ptr(mrb, range);
    259 
    260   beg = mrb_int(mrb, r->edges->beg);
    261   end = mrb_int(mrb, r->edges->end);
    262 
    263   if (beg < 0) {
    264     beg += len;
    265     if (beg < 0) return 2;
    266   }
    267 
    268   if (trunc) {
    269     if (beg > len) return 2;
    270     if (end > len) end = len;
    271   }
    272 
    273   if (end < 0) end += len;
    274   if (!r->excl && (!trunc || end < len))
    275     end++;                      /* include end point */
    276   len = end - beg;
    277   if (len < 0) len = 0;
    278 
    279   *begp = beg;
    280   *lenp = len;
    281   return 1;
    282228}
    283229
     
    289235 * Convert this range object to a printable form.
    290236 */
    291 
    292237static mrb_value
    293238range_to_s(mrb_state *mrb, mrb_value range)
     
    296241  struct RRange *r = mrb_range_ptr(mrb, range);
    297242
    298   str  = mrb_obj_as_string(mrb, r->edges->beg);
    299   str2 = mrb_obj_as_string(mrb, r->edges->end);
     243  str  = mrb_obj_as_string(mrb, RANGE_BEG(r));
     244  str2 = mrb_obj_as_string(mrb, RANGE_END(r));
    300245  str  = mrb_str_dup(mrb, str);
    301   mrb_str_cat(mrb, str, "...", r->excl ? 3 : 2);
     246  mrb_str_cat(mrb, str, "...", RANGE_EXCL(r) ? 3 : 2);
    302247  mrb_str_cat_str(mrb, str, str2);
    303248
     
    314259 * objects).
    315260 */
    316 
    317261static mrb_value
    318262range_inspect(mrb_state *mrb, mrb_value range)
     
    321265  struct RRange *r = mrb_range_ptr(mrb, range);
    322266
    323   str  = mrb_inspect(mrb, r->edges->beg);
    324   str2 = mrb_inspect(mrb, r->edges->end);
     267  str  = mrb_inspect(mrb, RANGE_BEG(r));
     268  str2 = mrb_inspect(mrb, RANGE_END(r));
    325269  str  = mrb_str_dup(mrb, str);
    326   mrb_str_cat(mrb, str, "...", r->excl ? 3 : 2);
     270  mrb_str_cat(mrb, str, "...", RANGE_EXCL(r) ? 3 : 2);
    327271  mrb_str_cat_str(mrb, str, str2);
    328272
     
    342286 *    (0..2).eql?(Range.new(0,2))  #=> true
    343287 *    (0..2).eql?(0...2)           #=> false
    344  *
    345  */
    346 
     288 */
    347289static mrb_value
    348290range_eql(mrb_state *mrb, mrb_value range)
     
    354296
    355297  if (mrb_obj_equal(mrb, range, obj)) return mrb_true_value();
    356   if (!mrb_obj_is_kind_of(mrb, obj, RANGE_CLASS)) {
    357     return mrb_false_value();
    358   }
    359   if (mrb_type(obj) != MRB_TT_RANGE) return mrb_false_value();
     298  if (!mrb_obj_is_kind_of(mrb, obj, mrb->range_class)) return mrb_false_value();
     299  if (!mrb_range_p(obj)) return mrb_false_value();
    360300
    361301  r = mrb_range_ptr(mrb, range);
    362302  o = mrb_range_ptr(mrb, obj);
    363   if (!mrb_eql(mrb, r->edges->beg, o->edges->beg) ||
    364       !mrb_eql(mrb, r->edges->end, o->edges->end) ||
    365       (r->excl != o->excl)) {
     303  if (!mrb_eql(mrb, RANGE_BEG(r), RANGE_BEG(o)) ||
     304      !mrb_eql(mrb, RANGE_END(r), RANGE_END(o)) ||
     305      (RANGE_EXCL(r) != RANGE_EXCL(o))) {
    366306    return mrb_false_value();
    367307  }
     
    384324
    385325  r = mrb_range_ptr(mrb, src);
    386   range_init(mrb, copy, r->edges->beg, r->edges->end, r->excl);
     326  range_ptr_replace(mrb, mrb_range_raw_ptr(copy), RANGE_BEG(r), RANGE_END(r), RANGE_EXCL(r));
    387327
    388328  return copy;
     
    400340      mrb_ary_push(mrb, result, func(mrb, obj, mrb_fixnum(argv[i])));
    401341    }
    402     else if (mrb_range_beg_len(mrb, argv[i], &beg, &len, olen, FALSE) == 1) {
     342    else if (mrb_range_beg_len(mrb, argv[i], &beg, &len, olen, FALSE) == MRB_RANGE_OK) {
    403343      mrb_int const end = olen < beg + len ? olen : beg + len;
    404344      for (j = beg; j < end; ++j) {
     
    411351    }
    412352    else {
    413       mrb_raisef(mrb, E_TYPE_ERROR, "invalid values selector: %S", argv[i]);
     353      mrb_raisef(mrb, E_TYPE_ERROR, "invalid values selector: %v", argv[i]);
    414354    }
    415355  }
    416356
    417357  return result;
     358}
     359
     360void
     361mrb_gc_mark_range(mrb_state *mrb, struct RRange *r)
     362{
     363  if (RANGE_INITIALIZED_P(r)) {
     364    mrb_gc_mark_value(mrb, RANGE_BEG(r));
     365    mrb_gc_mark_value(mrb, RANGE_END(r));
     366  }
     367}
     368
     369MRB_API struct RRange*
     370mrb_range_ptr(mrb_state *mrb, mrb_value range)
     371{
     372  struct RRange *r = mrb_range_raw_ptr(range);
     373
     374  /* check for if #initialize_copy was removed [#3320] */
     375  if (!RANGE_INITIALIZED_P(r)) {
     376    mrb_raise(mrb, E_ARGUMENT_ERROR, "uninitialized range");
     377  }
     378  return r;
     379}
     380
     381MRB_API mrb_value
     382mrb_range_new(mrb_state *mrb, mrb_value beg, mrb_value end, mrb_bool excl)
     383{
     384  struct RRange *r = range_ptr_init(mrb, NULL, beg, end, excl);
     385  return mrb_range_value(r);
     386}
     387
     388MRB_API enum mrb_range_beg_len
     389mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc)
     390{
     391  mrb_int beg, end;
     392  struct RRange *r;
     393
     394  if (!mrb_range_p(range)) return MRB_RANGE_TYPE_MISMATCH;
     395  r = mrb_range_ptr(mrb, range);
     396
     397  beg = mrb_int(mrb, RANGE_BEG(r));
     398  end = mrb_int(mrb, RANGE_END(r));
     399
     400  if (beg < 0) {
     401    beg += len;
     402    if (beg < 0) return MRB_RANGE_OUT;
     403  }
     404
     405  if (trunc) {
     406    if (beg > len) return MRB_RANGE_OUT;
     407    if (end > len) end = len;
     408  }
     409
     410  if (end < 0) end += len;
     411  if (!RANGE_EXCL(r) && (!trunc || end < len)) end++;  /* include end point */
     412  len = end - beg;
     413  if (len < 0) len = 0;
     414
     415  *begp = beg;
     416  *lenp = len;
     417  return MRB_RANGE_OK;
    418418}
    419419
     
    424424
    425425  r = mrb_define_class(mrb, "Range", mrb->object_class);                                /* 15.2.14 */
     426  mrb->range_class = r;
    426427  MRB_SET_INSTANCE_TT(r, MRB_TT_RANGE);
    427428
    428   mrb_define_method(mrb, r, "begin",           mrb_range_beg,         MRB_ARGS_NONE()); /* 15.2.14.4.3  */
    429   mrb_define_method(mrb, r, "end",             mrb_range_end,         MRB_ARGS_NONE()); /* 15.2.14.4.5  */
    430   mrb_define_method(mrb, r, "==",              mrb_range_eq,          MRB_ARGS_REQ(1)); /* 15.2.14.4.1  */
    431   mrb_define_method(mrb, r, "===",             mrb_range_include,     MRB_ARGS_REQ(1)); /* 15.2.14.4.2  */
    432   mrb_define_method(mrb, r, "exclude_end?",    mrb_range_excl,        MRB_ARGS_NONE()); /* 15.2.14.4.6  */
    433   mrb_define_method(mrb, r, "first",           mrb_range_beg,         MRB_ARGS_NONE()); /* 15.2.14.4.7  */
    434   mrb_define_method(mrb, r, "include?",        mrb_range_include,     MRB_ARGS_REQ(1)); /* 15.2.14.4.8  */
    435   mrb_define_method(mrb, r, "initialize",      mrb_range_initialize,  MRB_ARGS_ANY());  /* 15.2.14.4.9  */
    436   mrb_define_method(mrb, r, "last",            mrb_range_end,         MRB_ARGS_NONE()); /* 15.2.14.4.10 */
    437   mrb_define_method(mrb, r, "member?",         mrb_range_include,     MRB_ARGS_REQ(1)); /* 15.2.14.4.11 */
    438 
     429  mrb_define_method(mrb, r, "begin",           range_beg,             MRB_ARGS_NONE()); /* 15.2.14.4.3  */
     430  mrb_define_method(mrb, r, "end",             range_end,             MRB_ARGS_NONE()); /* 15.2.14.4.5  */
     431  mrb_define_method(mrb, r, "==",              range_eq,              MRB_ARGS_REQ(1)); /* 15.2.14.4.1  */
     432  mrb_define_method(mrb, r, "===",             range_include,         MRB_ARGS_REQ(1)); /* 15.2.14.4.2  */
     433  mrb_define_method(mrb, r, "exclude_end?",    range_excl,            MRB_ARGS_NONE()); /* 15.2.14.4.6  */
     434  mrb_define_method(mrb, r, "first",           range_beg,             MRB_ARGS_NONE()); /* 15.2.14.4.7  */
     435  mrb_define_method(mrb, r, "include?",        range_include,         MRB_ARGS_REQ(1)); /* 15.2.14.4.8  */
     436  mrb_define_method(mrb, r, "initialize",      range_initialize,      MRB_ARGS_ANY());  /* 15.2.14.4.9  */
     437  mrb_define_method(mrb, r, "last",            range_end,             MRB_ARGS_NONE()); /* 15.2.14.4.10 */
     438  mrb_define_method(mrb, r, "member?",         range_include,         MRB_ARGS_REQ(1)); /* 15.2.14.4.11 */
    439439  mrb_define_method(mrb, r, "to_s",            range_to_s,            MRB_ARGS_NONE()); /* 15.2.14.4.12(x) */
    440440  mrb_define_method(mrb, r, "inspect",         range_inspect,         MRB_ARGS_NONE()); /* 15.2.14.4.13(x) */
Note: See TracChangeset for help on using the changeset viewer.