summaryrefslogtreecommitdiffhomepage
path: root/src/array.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/array.c')
-rw-r--r--src/array.c128
1 files changed, 60 insertions, 68 deletions
diff --git a/src/array.c b/src/array.c
index 2152e292d..8cf813743 100644
--- a/src/array.c
+++ b/src/array.c
@@ -120,9 +120,7 @@ ary_fill_with_nil(mrb_value *ptr, mrb_int size)
static void
ary_modify_check(mrb_state *mrb, struct RArray *a)
{
- if (MRB_FROZEN_P(a)) {
- mrb_raise(mrb, E_FROZEN_ERROR, "can't modify frozen array");
- }
+ mrb_check_frozen(mrb, a);
}
static void
@@ -231,7 +229,7 @@ ary_expand_capa(mrb_state *mrb, struct RArray *a, mrb_int len)
static void
ary_shrink_capa(mrb_state *mrb, struct RArray *a)
{
-
+
mrb_int capa;
if (ARY_EMBED_P(a)) return;
@@ -853,14 +851,14 @@ static mrb_value
mrb_ary_aget(mrb_state *mrb, mrb_value self)
{
struct RArray *a = mrb_ary_ptr(self);
- mrb_int i, len, alen = ARY_LEN(a);
+ mrb_int i, len, alen;
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, alen, TRUE) == 1) {
+ if (mrb_range_beg_len(mrb, index, &i, &len, ARY_LEN(a), TRUE) == MRB_RANGE_OK) {
return ary_subseq(mrb, a, i, len);
}
else {
@@ -874,6 +872,7 @@ mrb_ary_aget(mrb_state *mrb, mrb_value self)
}
i = aget_index(mrb, index);
+ alen = ARY_LEN(a);
if (i < 0) i += alen;
if (i < 0 || alen < i) return mrb_nil_value();
if (len < 0) return mrb_nil_value();
@@ -928,13 +927,13 @@ mrb_ary_aset(mrb_state *mrb, mrb_value 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 */
+ case MRB_RANGE_TYPE_MISMATCH:
mrb_ary_set(mrb, self, aget_index(mrb, v1), v2);
break;
- case 1: /* range */
+ case MRB_RANGE_OK:
mrb_ary_splice(mrb, self, i, len, v2);
break;
- case 2: /* out of range */
+ case MRB_RANGE_OUT:
mrb_raisef(mrb, E_RANGE_ERROR, "%S out of range", v1);
break;
}
@@ -953,9 +952,10 @@ mrb_ary_delete_at(mrb_state *mrb, mrb_value self)
mrb_int index;
mrb_value val;
mrb_value *ptr;
- mrb_int len, alen = ARY_LEN(a);
+ mrb_int len, alen;
mrb_get_args(mrb, "i", &index);
+ alen = ARY_LEN(a);
if (index < 0) index += alen;
if (index < 0 || alen <= index) return mrb_nil_value();
@@ -980,16 +980,17 @@ static mrb_value
mrb_ary_first(mrb_state *mrb, mrb_value self)
{
struct RArray *a = mrb_ary_ptr(self);
- mrb_int size, alen = ARY_LEN(a);
+ mrb_int size, alen;
if (mrb_get_argc(mrb) == 0) {
- return (alen > 0)? ARY_PTR(a)[0]: mrb_nil_value();
+ return (ARY_LEN(a) > 0)? ARY_PTR(a)[0]: mrb_nil_value();
}
mrb_get_args(mrb, "|i", &size);
if (size < 0) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "negative array size");
}
+ alen = ARY_LEN(a);
if (size > alen) size = alen;
if (ARY_SHARED_P(a)) {
return ary_subseq(mrb, a, 0, size);
@@ -1001,10 +1002,13 @@ static mrb_value
mrb_ary_last(mrb_state *mrb, mrb_value self)
{
struct RArray *a = mrb_ary_ptr(self);
- mrb_int size, alen = ARY_LEN(a);
+ mrb_int n, size, alen;
- if (mrb_get_args(mrb, "|i", &size) == 0)
- return (alen > 0)? ARY_PTR(a)[alen - 1]: mrb_nil_value();
+ n = mrb_get_args(mrb, "|i", &size);
+ alen = ARY_LEN(a);
+ if (n == 0) {
+ return (alen > 0) ? ARY_PTR(a)[alen - 1]: mrb_nil_value();
+ }
if (size < 0) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "negative array size");
@@ -1052,7 +1056,7 @@ mrb_ary_rindex_m(mrb_state *mrb, mrb_value self)
MRB_API mrb_value
mrb_ary_splat(mrb_state *mrb, mrb_value v)
{
- mrb_value a, recv_class;
+ mrb_value a;
if (mrb_array_p(v)) {
return v;
@@ -1063,22 +1067,11 @@ mrb_ary_splat(mrb_state *mrb, mrb_value v)
}
a = mrb_funcall(mrb, v, "to_a", 0);
- if (mrb_array_p(a)) {
- return a;
- }
- else if (mrb_nil_p(a)) {
+ if (mrb_nil_p(a)) {
return mrb_ary_new_from_values(mrb, 1, &v);
}
- else {
- recv_class = mrb_obj_value(mrb_obj_class(mrb, v));
- mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S to Array (%S#to_a gives %S)",
- recv_class,
- recv_class,
- mrb_obj_value(mrb_obj_class(mrb, a))
- );
- /* not reached */
- return mrb_undef_value();
- }
+ mrb_ensure_array_type(mrb, a);
+ return a;
}
static mrb_value
@@ -1108,6 +1101,13 @@ mrb_ary_clear(mrb_state *mrb, mrb_value self)
}
static mrb_value
+mrb_ary_clear_m(mrb_state *mrb, mrb_value self)
+{
+ mrb_get_args(mrb, "");
+ return mrb_ary_clear(mrb, self);
+}
+
+static mrb_value
mrb_ary_empty_p(mrb_state *mrb, mrb_value self)
{
struct RArray *a = mrb_ary_ptr(self);
@@ -1116,12 +1116,6 @@ mrb_ary_empty_p(mrb_state *mrb, mrb_value self)
}
MRB_API mrb_value
-mrb_check_array_type(mrb_state *mrb, mrb_value ary)
-{
- return mrb_check_convert_type(mrb, ary, MRB_TT_ARRAY, "Array", "to_ary");
-}
-
-MRB_API mrb_value
mrb_ary_entry(mrb_value ary, mrb_int offset)
{
if (offset < 0) {
@@ -1174,7 +1168,7 @@ join_ary(mrb_state *mrb, mrb_value ary, mrb_value sep, mrb_value list)
val = tmp;
goto str_join;
}
- tmp = mrb_check_convert_type(mrb, val, MRB_TT_ARRAY, "Array", "to_ary");
+ tmp = mrb_check_array_type(mrb, val);
if (!mrb_nil_p(tmp)) {
val = tmp;
goto ary_join;
@@ -1268,41 +1262,39 @@ mrb_init_array(mrb_state *mrb)
{
struct RClass *a;
- mrb->array_class = a = mrb_define_class(mrb, "Array", mrb->object_class); /* 15.2.12 */
+ mrb->array_class = a = mrb_define_class(mrb, "Array", mrb->object_class); /* 15.2.12 */
MRB_SET_INSTANCE_TT(a, MRB_TT_ARRAY);
- mrb_define_class_method(mrb, a, "[]", mrb_ary_s_create, MRB_ARGS_ANY()); /* 15.2.12.4.1 */
-
- mrb_define_method(mrb, a, "+", mrb_ary_plus, MRB_ARGS_REQ(1)); /* 15.2.12.5.1 */
- mrb_define_method(mrb, a, "*", mrb_ary_times, MRB_ARGS_REQ(1)); /* 15.2.12.5.2 */
- mrb_define_method(mrb, a, "<<", mrb_ary_push_m, MRB_ARGS_REQ(1)); /* 15.2.12.5.3 */
- mrb_define_method(mrb, a, "[]", mrb_ary_aget, MRB_ARGS_ANY()); /* 15.2.12.5.4 */
- mrb_define_method(mrb, a, "[]=", mrb_ary_aset, MRB_ARGS_ANY()); /* 15.2.12.5.5 */
- mrb_define_method(mrb, a, "clear", mrb_ary_clear, MRB_ARGS_NONE()); /* 15.2.12.5.6 */
- mrb_define_method(mrb, a, "concat", mrb_ary_concat_m, MRB_ARGS_REQ(1)); /* 15.2.12.5.8 */
- mrb_define_method(mrb, a, "delete_at", mrb_ary_delete_at, MRB_ARGS_REQ(1)); /* 15.2.12.5.9 */
- mrb_define_method(mrb, a, "empty?", mrb_ary_empty_p, MRB_ARGS_NONE()); /* 15.2.12.5.12 */
- mrb_define_method(mrb, a, "first", mrb_ary_first, MRB_ARGS_OPT(1)); /* 15.2.12.5.13 */
- mrb_define_method(mrb, a, "index", mrb_ary_index_m, MRB_ARGS_REQ(1)); /* 15.2.12.5.14 */
- mrb_define_method(mrb, a, "initialize_copy", mrb_ary_replace_m, MRB_ARGS_REQ(1)); /* 15.2.12.5.16 */
- mrb_define_method(mrb, a, "join", mrb_ary_join_m, MRB_ARGS_ANY()); /* 15.2.12.5.17 */
- mrb_define_method(mrb, a, "last", mrb_ary_last, MRB_ARGS_ANY()); /* 15.2.12.5.18 */
- mrb_define_method(mrb, a, "length", mrb_ary_size, MRB_ARGS_NONE()); /* 15.2.12.5.19 */
- mrb_define_method(mrb, a, "pop", mrb_ary_pop, MRB_ARGS_NONE()); /* 15.2.12.5.21 */
- mrb_define_method(mrb, a, "push", mrb_ary_push_m, MRB_ARGS_ANY()); /* 15.2.12.5.22 */
- mrb_define_method(mrb, a, "append", mrb_ary_push_m, MRB_ARGS_ANY());
- mrb_define_method(mrb, a, "replace", mrb_ary_replace_m, MRB_ARGS_REQ(1)); /* 15.2.12.5.23 */
- mrb_define_method(mrb, a, "reverse", mrb_ary_reverse, MRB_ARGS_NONE()); /* 15.2.12.5.24 */
- mrb_define_method(mrb, a, "reverse!", mrb_ary_reverse_bang, MRB_ARGS_NONE()); /* 15.2.12.5.25 */
- mrb_define_method(mrb, a, "rindex", mrb_ary_rindex_m, MRB_ARGS_REQ(1)); /* 15.2.12.5.26 */
- mrb_define_method(mrb, a, "shift", mrb_ary_shift, MRB_ARGS_NONE()); /* 15.2.12.5.27 */
- mrb_define_method(mrb, a, "size", mrb_ary_size, MRB_ARGS_NONE()); /* 15.2.12.5.28 */
- mrb_define_method(mrb, a, "slice", mrb_ary_aget, MRB_ARGS_ANY()); /* 15.2.12.5.29 */
- mrb_define_method(mrb, a, "unshift", mrb_ary_unshift_m, MRB_ARGS_ANY()); /* 15.2.12.5.30 */
- mrb_define_method(mrb, a, "prepend", mrb_ary_unshift_m, MRB_ARGS_ANY());
+ mrb_define_class_method(mrb, a, "[]", mrb_ary_s_create, MRB_ARGS_ANY()); /* 15.2.12.4.1 */
+
+ mrb_define_method(mrb, a, "+", mrb_ary_plus, MRB_ARGS_REQ(1)); /* 15.2.12.5.1 */
+ mrb_define_method(mrb, a, "*", mrb_ary_times, MRB_ARGS_REQ(1)); /* 15.2.12.5.2 */
+ mrb_define_method(mrb, a, "<<", mrb_ary_push_m, MRB_ARGS_REQ(1)); /* 15.2.12.5.3 */
+ mrb_define_method(mrb, a, "[]", mrb_ary_aget, MRB_ARGS_ARG(1,1)); /* 15.2.12.5.4 */
+ mrb_define_method(mrb, a, "[]=", mrb_ary_aset, MRB_ARGS_ARG(2,1)); /* 15.2.12.5.5 */
+ mrb_define_method(mrb, a, "clear", mrb_ary_clear_m, MRB_ARGS_NONE()); /* 15.2.12.5.6 */
+ mrb_define_method(mrb, a, "concat", mrb_ary_concat_m, MRB_ARGS_REQ(1)); /* 15.2.12.5.8 */
+ mrb_define_method(mrb, a, "delete_at", mrb_ary_delete_at, MRB_ARGS_REQ(1)); /* 15.2.12.5.9 */
+ mrb_define_method(mrb, a, "empty?", mrb_ary_empty_p, MRB_ARGS_NONE()); /* 15.2.12.5.12 */
+ mrb_define_method(mrb, a, "first", mrb_ary_first, MRB_ARGS_OPT(1)); /* 15.2.12.5.13 */
+ mrb_define_method(mrb, a, "index", mrb_ary_index_m, MRB_ARGS_REQ(1)); /* 15.2.12.5.14 */
+ mrb_define_method(mrb, a, "initialize_copy", mrb_ary_replace_m, MRB_ARGS_REQ(1)); /* 15.2.12.5.16 */
+ mrb_define_method(mrb, a, "join", mrb_ary_join_m, MRB_ARGS_OPT(1)); /* 15.2.12.5.17 */
+ mrb_define_method(mrb, a, "last", mrb_ary_last, MRB_ARGS_OPT(1)); /* 15.2.12.5.18 */
+ mrb_define_method(mrb, a, "length", mrb_ary_size, MRB_ARGS_NONE()); /* 15.2.12.5.19 */
+ mrb_define_method(mrb, a, "pop", mrb_ary_pop, MRB_ARGS_NONE()); /* 15.2.12.5.21 */
+ mrb_define_method(mrb, a, "push", mrb_ary_push_m, MRB_ARGS_ANY()); /* 15.2.12.5.22 */
+ mrb_define_method(mrb, a, "replace", mrb_ary_replace_m, MRB_ARGS_REQ(1)); /* 15.2.12.5.23 */
+ mrb_define_method(mrb, a, "reverse", mrb_ary_reverse, MRB_ARGS_NONE()); /* 15.2.12.5.24 */
+ mrb_define_method(mrb, a, "reverse!", mrb_ary_reverse_bang, MRB_ARGS_NONE()); /* 15.2.12.5.25 */
+ mrb_define_method(mrb, a, "rindex", mrb_ary_rindex_m, MRB_ARGS_REQ(1)); /* 15.2.12.5.26 */
+ mrb_define_method(mrb, a, "shift", mrb_ary_shift, MRB_ARGS_NONE()); /* 15.2.12.5.27 */
+ mrb_define_method(mrb, a, "size", mrb_ary_size, MRB_ARGS_NONE()); /* 15.2.12.5.28 */
+ mrb_define_method(mrb, a, "slice", mrb_ary_aget, MRB_ARGS_ARG(1,1)); /* 15.2.12.5.29 */
+ mrb_define_method(mrb, a, "unshift", mrb_ary_unshift_m, MRB_ARGS_ANY()); /* 15.2.12.5.30 */
mrb_define_method(mrb, a, "__ary_eq", mrb_ary_eq, MRB_ARGS_REQ(1));
mrb_define_method(mrb, a, "__ary_cmp", mrb_ary_cmp, MRB_ARGS_REQ(1));
- mrb_define_method(mrb, a, "__ary_index", mrb_ary_index_m, MRB_ARGS_REQ(1)); /* kept for mruby-array-ext */
+ mrb_define_method(mrb, a, "__ary_index", mrb_ary_index_m, MRB_ARGS_REQ(1)); /* kept for mruby-array-ext */
mrb_define_method(mrb, a, "__svalue", mrb_ary_svalue, MRB_ARGS_NONE());
}