static mrb_value make_struct(mrb_state *mrb, mrb_value name, mrb_value members, struct RClass * klass) { mrb_value nstr, *ptr_members; mrb_sym id; long i, len; struct RClass *c; //OBJ_FREEZE(members); if (mrb_nil_p(name)) { c = mrb_class_new(mrb, klass); //mrb_make_metaclass(nstr, RBASIC(klass)->c); //mrb_class_inherited(klass, nstr); } else { /* old style: should we warn? */ name = mrb_str_to_str(mrb, name); id = mrb_to_id(mrb, name); if (!mrb_is_const_id(id)) { //mrb_name_error(id, "identifier %s needs to be constant", StringValuePtr(name)); mrb_name_error(mrb, id, "identifier %s needs to be constant", mrb_string_value_ptr(mrb, name)); } if (mrb_const_defined_at(mrb, klass, id)) { //mrb_warn("redefining constant Struct::%s", StringValuePtr(name)); mrb_warn("redefining constant Struct::%s", mrb_string_value_ptr(mrb, name)); //?rb_mod_remove_const(klass, mrb_sym2name(mrb, id)); } c = mrb_define_class_under(mrb, klass, RSTRING_PTR(name), klass); } MRB_SET_INSTANCE_TT(c, MRB_TT_STRUCT); nstr = mrb_obj_value(c); mrb_iv_set(mrb, nstr, mrb_intern(mrb, "__members__"), members); mrb_define_class_method(mrb, c, "new", mrb_class_new_instance_m, ARGS_ANY()); mrb_define_class_method(mrb, c, "[]", mrb_class_new_instance_m, ARGS_ANY()); mrb_define_class_method(mrb, c, "members", mrb_struct_s_members_m, ARGS_NONE()); //RSTRUCT(nstr)->basic.c->super = c->c; ptr_members = RARRAY_PTR(members); len = RARRAY_LEN(members); for (i=0; i< len; i++) { mrb_sym id = SYM2ID(ptr_members[i]); if (mrb_is_local_id(id) || mrb_is_const_id(id)) { if (i < N_REF_FUNC) { mrb_define_method_id(mrb, c, id, (mrb_func_t)ref_func[i], 0); } else { mrb_define_method_id(mrb, c, id, mrb_struct_ref, 0); } mrb_define_method_id(mrb, c, mrb_id_attrset(id), (mrb_func_t)mrb_struct_set, 1); } } return nstr; }
static mrb_value make_struct(mrb_state *mrb, mrb_value name, mrb_value members, struct RClass * klass) { mrb_value nstr, *ptr_members; mrb_sym id; mrb_int i, len; struct RClass *c; int ai; if (mrb_nil_p(name)) { c = mrb_class_new(mrb, klass); } else { /* old style: should we warn? */ name = mrb_str_to_str(mrb, name); id = mrb_obj_to_sym(mrb, name); if (!mrb_is_const_id(id)) { mrb_name_error(mrb, id, "identifier %S needs to be constant", name); } if (mrb_const_defined_at(mrb, klass, id)) { mrb_warn(mrb, "redefining constant Struct::%S", name); /* ?rb_mod_remove_const(klass, mrb_sym2name(mrb, id)); */ } c = mrb_define_class_under(mrb, klass, RSTRING_PTR(name), klass); } MRB_SET_INSTANCE_TT(c, MRB_TT_ARRAY); nstr = mrb_obj_value(c); mrb_iv_set(mrb, nstr, mrb_intern_lit(mrb, "__members__"), members); mrb_define_class_method(mrb, c, "new", mrb_instance_new, MRB_ARGS_ANY()); mrb_define_class_method(mrb, c, "[]", mrb_instance_new, MRB_ARGS_ANY()); mrb_define_class_method(mrb, c, "members", mrb_struct_s_members_m, MRB_ARGS_NONE()); /* RSTRUCT(nstr)->basic.c->super = c->c; */ ptr_members = RARRAY_PTR(members); len = RARRAY_LEN(members); ai = mrb_gc_arena_save(mrb); for (i=0; i< len; i++) { mrb_sym id = mrb_symbol(ptr_members[i]); if (mrb_is_local_id(id) || mrb_is_const_id(id)) { if (i < N_REF_FUNC) { mrb_define_method_id(mrb, c, id, ref_func[i], MRB_ARGS_NONE()); } else { mrb_define_method_id(mrb, c, id, mrb_struct_ref, MRB_ARGS_NONE()); } mrb_define_method_id(mrb, c, mrb_id_attrset(mrb, id), mrb_struct_set_m, MRB_ARGS_REQ(1)); mrb_gc_arena_restore(mrb, ai); } } return nstr; }
static void make_struct_define_accessors(mrb_state *mrb, mrb_value members, struct RClass *c) { const mrb_value *ptr_members = RARRAY_PTR(members); mrb_int i; mrb_int len = RARRAY_LEN(members); int ai = mrb_gc_arena_save(mrb); for (i=0; i<len; i++) { mrb_sym id = mrb_symbol(ptr_members[i]); const char *name = mrb_sym2name_len(mrb, id, NULL); if (is_local_id(mrb, name) || is_const_id(mrb, name)) { mrb_define_method_id(mrb, c, id, mrb_struct_ref, MRB_ARGS_NONE()); mrb_define_method_id(mrb, c, mrb_id_attrset(mrb, id), mrb_struct_set_m, MRB_ARGS_REQ(1)); mrb_gc_arena_restore(mrb, ai); } } }
void mrb_define_singleton_method(mrb_state *mrb, struct RObject *o, const char *name, mrb_func_t func, int aspec) { prepare_singleton_class(mrb, (struct RBasic*)o); mrb_define_method_id(mrb, o->c, mrb_intern(mrb, name), func, aspec); }
void mrb_define_method(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, int aspec) { mrb_define_method_id(mrb, c, mrb_intern(mrb, name), func, aspec); }
void mrb_define_singleton_method(mrb_state *mrb, struct RObject *o, const char *name, mrb_func_t func, int aspec) { mrb_define_method_id(mrb, mrb_singleton_class_ptr(mrb, o->c), mrb_intern(mrb, name), func, aspec); }