static mrb_value mrb_ary_aset(mrb_state *mrb, mrb_value self) { mrb_value v1, v2, v3; mrb_int i, len; if (mrb_get_args(mrb, "oo|o", &v1, &v2, &v3) == 2) { switch (mrb_type(v1)) { /* a[n..m] = v */ case MRB_TT_RANGE: if (mrb_range_beg_len(mrb, v1, &i, &len, RARRAY_LEN(self))) { mrb_ary_splice(mrb, self, i, len, v2); } break; /* a[n] = v */ case MRB_TT_FIXNUM: mrb_ary_set(mrb, self, mrb_fixnum(v1), v2); break; default: mrb_ary_set(mrb, self, aget_index(mrb, v1), v2); break; } return v2; } /* a[n,m] = v */ mrb_ary_splice(mrb, self, aget_index(mrb, v1), aget_index(mrb, v2), v3); return v3; }
static mrb_value mrb_ary_aget(mrb_state *mrb, mrb_value self) { struct RArray *a = mrb_ary_ptr(self); mrb_int i, len; mrb_value index; if (mrb_get_args(mrb, "o|i", &index, &len) == 1) { switch (mrb_type(index)) { /* a[n..m] */ case MRB_TT_RANGE: if (mrb_range_beg_len(mrb, index, &i, &len, a->len)) { return ary_subseq(mrb, a, i, len); } else { return mrb_nil_value(); } case MRB_TT_FIXNUM: return mrb_ary_ref(mrb, self, mrb_fixnum(index)); default: return mrb_ary_ref(mrb, self, aget_index(mrb, index)); } } i = aget_index(mrb, index); if (i < 0) i += a->len; if (i < 0 || a->len < i) return mrb_nil_value(); if (len < 0) return mrb_nil_value(); if (a->len == i) return mrb_ary_new(mrb); if (len > a->len - i) len = a->len - i; return ary_subseq(mrb, a, i, len); }
static mrb_value mrb_ary_aset(mrb_state *mrb, mrb_value self) { mrb_value v1, v2, v3; mrb_int i, len; mrb_ary_modify(mrb, mrb_ary_ptr(self)); if (mrb_get_args(mrb, "oo|o", &v1, &v2, &v3) == 2) { /* a[n..m] = v */ switch (mrb_range_beg_len(mrb, v1, &i, &len, RARRAY_LEN(self), FALSE)) { case 0: /* not range */ mrb_ary_set(mrb, self, aget_index(mrb, v1), v2); break; case 1: /* range */ mrb_ary_splice(mrb, self, i, len, v2); break; case 2: /* out of range */ mrb_raisef(mrb, E_RANGE_ERROR, "%S out of range", v1); break; } return v2; } /* a[n,m] = v */ mrb_ary_splice(mrb, self, aget_index(mrb, v1), aget_index(mrb, v2), v3); return v3; }
static mrb_value mrb_str_byteslice(mrb_state *mrb, mrb_value str) { mrb_value a1; mrb_int len; int argc; argc = mrb_get_args(mrb, "o|i", &a1, &len); if (argc == 2) { return mrb_str_substr(mrb, str, mrb_fixnum(a1), len); } switch (mrb_type(a1)) { case MRB_TT_RANGE: { mrb_int beg; len = RSTRING_LEN(str); if (mrb_range_beg_len(mrb, a1, &beg, &len, len)) { return mrb_str_substr(mrb, str, beg, len); } return mrb_nil_value(); } case MRB_TT_FLOAT: a1 = mrb_fixnum_value((mrb_int)mrb_float(a1)); /* fall through */ case MRB_TT_FIXNUM: return mrb_str_substr(mrb, str, mrb_fixnum(a1), 1); default: mrb_raise(mrb, E_TYPE_ERROR, "wrong type of argument"); } /* not reached */ return mrb_nil_value(); }
static mrb_value mrb_f_caller(mrb_state *mrb, mrb_value self) { mrb_value bt, v, length; mrb_int bt_len, argc, lev, n; bt = mrb_get_backtrace(mrb); bt_len = RARRAY_LEN(bt); argc = mrb_get_args(mrb, "|oo", &v, &length); switch (argc) { case 0: lev = 1; n = bt_len - lev; break; case 1: if (mrb_type(v) == MRB_TT_RANGE) { mrb_int beg, len; if (mrb_range_beg_len(mrb, v, &beg, &len, bt_len, TRUE) == 1) { lev = beg; n = len; } else { return mrb_nil_value(); } } else { v = mrb_to_int(mrb, v); lev = mrb_fixnum(v); if (lev < 0) { mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative level (%S)", v); } n = bt_len - lev; } break; case 2: lev = mrb_fixnum(mrb_to_int(mrb, v)); n = mrb_fixnum(mrb_to_int(mrb, length)); if (lev < 0) { mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative level (%S)", v); } if (n < 0) { mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative size (%S)", length); } break; default: lev = n = 0; break; } if (n == 0) { return mrb_ary_new(mrb); } return mrb_funcall(mrb, bt, "[]", 2, mrb_fixnum_value(lev), mrb_fixnum_value(n)); }
static mrb_value mrb_str_aref(mrb_state *mrb, mrb_value str, mrb_value indx) { mrb_int idx; regexp_check(mrb, indx); switch (mrb_type(indx)) { case MRB_TT_FIXNUM: idx = mrb_fixnum(indx); num_index: str = str_substr(mrb, str, idx, 1); if (!mrb_nil_p(str) && RSTRING_LEN(str) == 0) return mrb_nil_value(); return str; case MRB_TT_STRING: if (str_index(mrb, str, indx, 0) != -1) return mrb_str_dup(mrb, indx); return mrb_nil_value(); case MRB_TT_RANGE: /* check if indx is Range */ { mrb_int beg, len; mrb_value tmp; len = RSTRING_LEN_UTF8(str); if (mrb_range_beg_len(mrb, indx, &beg, &len, len)) { tmp = str_subseq(mrb, str, beg, len); return tmp; } else { return mrb_nil_value(); } } default: idx = mrb_fixnum(indx); goto num_index; } return mrb_nil_value(); /* not reached */ }