static mrb_value mrb_struct_set(mrb_state *mrb, mrb_value obj, mrb_value val) { const char *name; int i, len; mrb_sym mid; mrb_value members, slot, *ptr, *ptr_members; /* get base id */ name = mrb_sym2name_len(mrb, mrb->ci->mid, &len); mid = mrb_intern2(mrb, name, len-1); /* omit last "=" */ members = mrb_struct_members(mrb, obj); ptr_members = RARRAY_PTR(members); len = RARRAY_LEN(members); mrb_struct_modify(obj); ptr = RSTRUCT_PTR(obj); for (i=0; i<len; i++) { slot = ptr_members[i]; if (SYM2ID(slot) == mid) { return ptr[i] = val; } } mrb_name_error(mrb, mid, "`%s' is not a struct member", mrb_sym2name(mrb, mid)); return mrb_nil_value(); /* not reached */ }
static mrb_value mrb_struct_set(mrb_state *mrb, mrb_value obj, mrb_value val) { const char *name; size_t i, len; mrb_int slen; mrb_sym mid; mrb_value members, slot, *ptr, *ptr_members; /* get base id */ name = mrb_sym2name_len(mrb, mrb->c->ci->mid, &slen); mid = mrb_intern(mrb, name, slen-1); /* omit last "=" */ members = mrb_struct_members(mrb, obj); ptr_members = RARRAY_PTR(members); len = RARRAY_LEN(members); ptr = RSTRUCT_PTR(obj); for (i=0; i<len; i++) { slot = ptr_members[i]; if (mrb_symbol(slot) == mid) { return ptr[i] = val; } } mrb_raisef(mrb, E_INDEX_ERROR, "`%S' is not a struct member", mrb_sym2str(mrb, mid)); return mrb_nil_value(); /* not reached */ }
static mrb_value mrb_struct_aset_sym(mrb_state *mrb, mrb_value s, mrb_sym id, mrb_value val) { mrb_value members, *ptr; const mrb_value *ptr_members; mrb_int i, len; members = mrb_struct_members(mrb, s); len = RARRAY_LEN(members); if (RSTRUCT_LEN(s) != len) { mrb_raisef(mrb, E_TYPE_ERROR, "struct size differs (%S required %S given)", mrb_fixnum_value(len), mrb_fixnum_value(RSTRUCT_LEN(s))); } ptr = RSTRUCT_PTR(s); ptr_members = RARRAY_PTR(members); for (i=0; i<len; i++) { if (mrb_symbol(ptr_members[i]) == id) { ptr[i] = val; return val; } } mrb_raisef(mrb, E_INDEX_ERROR, "no member '%S' in struct", mrb_sym2str(mrb, id)); return val; /* not reach */ }
static mrb_value inspect_struct(mrb_state *mrb, mrb_value s, int recur) { const char *cn = mrb_class_name(mrb, mrb_obj_class(mrb, s)); mrb_value members, str = mrb_str_new_lit(mrb, "#<struct "); mrb_value *ptr, *ptr_members; mrb_int i, len; if (cn) { mrb_str_append(mrb, str, mrb_str_new_cstr(mrb, cn)); } if (recur) { return mrb_str_cat_lit(mrb, str, ":...>"); } members = mrb_struct_members(mrb, s); ptr_members = RARRAY_PTR(members); ptr = RSTRUCT_PTR(s); len = RSTRUCT_LEN(s); for (i=0; i<len; i++) { mrb_value slot; mrb_sym id; if (i > 0) { mrb_str_cat_lit(mrb, str, ", "); } else if (cn) { mrb_str_cat_lit(mrb, str, " "); } slot = ptr_members[i]; id = mrb_symbol(slot); if (mrb_is_local_id(id) || mrb_is_const_id(id)) { const char *name; mrb_int len; name = mrb_sym2name_len(mrb, id, &len); mrb_str_append(mrb, str, mrb_str_new(mrb, name, len)); } else { mrb_str_append(mrb, str, mrb_inspect(mrb, slot)); } mrb_str_cat_lit(mrb, str, "="); mrb_str_append(mrb, str, mrb_inspect(mrb, ptr[i])); } mrb_str_cat_lit(mrb, str, ">"); return str; }
static mrb_value mrb_struct_aref_id(mrb_state *mrb, mrb_value s, mrb_sym id) { mrb_value *ptr, members, *ptr_members; mrb_int i, len; ptr = RSTRUCT_PTR(s); members = mrb_struct_members(mrb, s); ptr_members = RARRAY_PTR(members); len = RARRAY_LEN(members); for (i=0; i<len; i++) { if (mrb_symbol(ptr_members[i]) == id) { return ptr[i]; } } mrb_raisef(mrb, E_INDEX_ERROR, "no member '%S' in struct", mrb_sym2str(mrb, id)); return mrb_nil_value(); /* not reached */ }
static mrb_value mrb_struct_aref_id(mrb_state *mrb, mrb_value s, mrb_sym id) { mrb_value *ptr, members, *ptr_members; long i, len; ptr = RSTRUCT_PTR(s); members = mrb_struct_members(mrb, s); ptr_members = RARRAY_PTR(members); len = RARRAY_LEN(members); for (i=0; i<len; i++) { if (SYM2ID(ptr_members[i]) == id) { return ptr[i]; } } mrb_name_error(mrb, id, "no member '%s' in struct", mrb_sym2name(mrb, id)); return mrb_nil_value(); /* not reached */ }
mrb_value mrb_struct_getmember(mrb_state *mrb, mrb_value obj, mrb_sym id) { mrb_value members, slot, *ptr, *ptr_members; mrb_int i, len; ptr = RSTRUCT_PTR(obj); members = mrb_struct_members(mrb, obj); ptr_members = RARRAY_PTR(members); slot = mrb_symbol_value(id); len = RARRAY_LEN(members); for (i=0; i<len; i++) { if (mrb_obj_equal(mrb, ptr_members[i], slot)) { return ptr[i]; } } mrb_raisef(mrb, E_INDEX_ERROR, "`%S' is not a struct member", mrb_sym2str(mrb, id)); return mrb_nil_value(); /* not reached */ }
mrb_value mrb_struct_getmember(mrb_state *mrb, mrb_value obj, mrb_sym id) { mrb_value members, slot, *ptr, *ptr_members; long i, len; ptr = RSTRUCT_PTR(obj); members = mrb_struct_members(mrb, obj); ptr_members = RARRAY_PTR(members); slot = mrb_symbol_value(id); len = RARRAY_LEN(members); for (i=0; i<len; i++) { if (mrb_obj_equal(mrb, ptr_members[i], slot)) { return ptr[i]; } } mrb_name_error(mrb, id, "%s is not struct member", mrb_sym2name(mrb, id)); return mrb_nil_value(); /* not reached */ }
static mrb_value mrb_struct_set(mrb_state *mrb, mrb_value obj, mrb_value val) { mrb_value members, slot, *ptr, *ptr_members; long i, len; members = mrb_struct_members(mrb, obj); ptr_members = RARRAY_PTR(members); len = RARRAY_LEN(members); mrb_struct_modify(obj); ptr = RSTRUCT_PTR(obj); for (i=0; i<len; i++) { slot = ptr_members[i]; if (mrb_id_attrset(SYM2ID(slot)) == 0/*rb_frame_this_func(mrb)*/) { return ptr[i] = val; } } mrb_name_error(mrb, 0/*rb_frame_this_func(mrb)*/, "`%s' is not a struct member", mrb_sym2name(mrb, 0/*rb_frame_this_func(mrb)*/)); return mrb_nil_value(); /* not reached */ }
static mrb_value mrb_struct_aset_id(mrb_state *mrb, mrb_value s, mrb_sym id, mrb_value val) { mrb_value members, *ptr, *ptr_members; long i, len; members = mrb_struct_members(mrb, s); len = RARRAY_LEN(members); mrb_struct_modify(s); if (RSTRUCT_LEN(s) != len) { mrb_raise(mrb, E_TYPE_ERROR, "struct size differs (%ld required %ld given)", len, RSTRUCT_LEN(s)); } ptr = RSTRUCT_PTR(s); ptr_members = RARRAY_PTR(members); for (i=0; i<len; i++) { if (SYM2ID(ptr_members[i]) == id) { ptr[i] = val; return val; } } mrb_name_error(mrb, id, "no member '%s' in struct", mrb_sym2name(mrb, id)); return val; /* not reach */ }
static mrb_value mrb_struct_aset_id(mrb_state *mrb, mrb_value s, mrb_sym id, mrb_value val) { mrb_value members, *ptr, *ptr_members; mrb_int i, len; members = mrb_struct_members(mrb, s); len = RARRAY_LEN(members); if (RSTRUCT_LEN(s) != len) { mrb_raisef(mrb, E_TYPE_ERROR, "struct size differs (%" PRIdMRB_INT " required %" PRIdMRB_INT " given)", len, RSTRUCT_LEN(s)); } ptr = RSTRUCT_PTR(s); ptr_members = RARRAY_PTR(members); for (i=0; i<len; i++) { if (mrb_symbol(ptr_members[i]) == id) { ptr[i] = val; return val; } } mrb_raisef(mrb, E_NAME_ERROR, "no member '%s' in struct", mrb_sym2name(mrb, id)); return val; /* not reach */ }