Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
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);
    }
  }
}
Пример #4
0
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 */
}