Exemple #1
0
static mrb_value
exc_equal(mrb_state *mrb, mrb_value exc)
{
  mrb_value obj;
  mrb_value mesg;
  mrb_bool equal_p;
  mrb_sym id_mesg = mrb_intern2(mrb, "mesg", 4);

  mrb_get_args(mrb, "o", &obj);
  if (mrb_obj_equal(mrb, exc, obj)) {
    equal_p = 1;
  }
  else {
    if (mrb_obj_class(mrb, exc) != mrb_obj_class(mrb, obj)) {
      if (mrb_respond_to(mrb, obj, mrb_intern2(mrb, "message", 7))) {
        mesg = mrb_funcall(mrb, obj, "message", 0);
      }
      else
        return mrb_false_value();
    }
    else {
      mesg = mrb_attr_get(mrb, obj, id_mesg);
    }

    equal_p = mrb_equal(mrb, mrb_attr_get(mrb, exc, id_mesg), mesg);
  }

  return mrb_bool_value(equal_p);
}
Exemple #2
0
static mrb_value
mrb_ary_equal(mrb_state *mrb, mrb_value ary1)
{
  mrb_value ary2;

  mrb_get_args(mrb, "o", &ary2);
  if (mrb_obj_equal(mrb, ary1,ary2)) return mrb_true_value();
  if (mrb_type(ary2) != MRB_TT_ARRAY) {
    if (!mrb_respond_to(mrb, ary2, mrb_intern(mrb, "to_ary"))) {
        return mrb_false_value();
    }
    if (mrb_equal(mrb, ary2, ary1)){
      return mrb_true_value();
    }
    else {
      return mrb_false_value();
    }
  }
  if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return mrb_false_value();
  else {
    int i;

    for (i=0; i<RARRAY_LEN(ary1); i++) {
      if (!mrb_equal(mrb, ary_elt(ary1, i), ary_elt(ary2, i)))
        return mrb_false_value();
    }
    return mrb_true_value();
  }
}
Exemple #3
0
MRB_API mrb_value
mrb_ary_splat(mrb_state *mrb, mrb_value v)
{
  mrb_value a, recv_class;

  if (mrb_array_p(v)) {
    return v;
  }

  if (!mrb_respond_to(mrb, v, mrb_intern_lit(mrb, "to_a"))) {
    return mrb_ary_new_from_values(mrb, 1, &v);
  }

  a = mrb_funcall(mrb, v, "to_a", 0);
  if (mrb_array_p(a)) {
    return a;
  }
  else 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();
  }
}
Exemple #4
0
/*
 *  call-seq:
 *     obj.method_missing(symbol [, *args] )   -> result
 *
 *  Invoked by Ruby when <i>obj</i> is sent a message it cannot handle.
 *  <i>symbol</i> is the symbol for the method called, and <i>args</i>
 *  are any arguments that were passed to it. By default, the interpreter
 *  raises an error when this method is called. However, it is possible
 *  to override the method to provide more dynamic behavior.
 *  If it is decided that a particular method should not be handled, then
 *  <i>super</i> should be called, so that ancestors can pick up the
 *  missing method.
 *  The example below creates
 *  a class <code>Roman</code>, which responds to methods with names
 *  consisting of roman numerals, returning the corresponding integer
 *  values.
 *
 *     class Roman
 *       def romanToInt(str)
 *         # ...
 *       end
 *       def method_missing(methId)
 *         str = methId.id2name
 *         romanToInt(str)
 *       end
 *     end
 *
 *     r = Roman.new
 *     r.iv      #=> 4
 *     r.xxiii   #=> 23
 *     r.mm      #=> 2000
 */
static mrb_value
mrb_bob_missing(mrb_state *mrb, mrb_value mod)
{
  mrb_value name, *a;
  int alen;
  mrb_value inspect;

  mrb_get_args(mrb, "o*", &name, &a, &alen);
  if (!mrb_symbol_p(name)) {
    mrb_raise(mrb, E_TYPE_ERROR, "name should be a symbol");
  }

  if (mrb_respond_to(mrb,mod,mrb_intern2(mrb,"inspect",7))){
    inspect = mrb_funcall(mrb, mod, "inspect", 0);
    if (RSTRING_LEN(inspect) > 64) {
      inspect = mrb_any_to_s(mrb, mod);
    }
  }
  else {
    inspect = mrb_any_to_s(mrb, mod);
  }

  mrb_raisef(mrb, E_NOMETHOD_ERROR, "undefined method '%S' for %S",
             mrb_sym2str(mrb, mrb_symbol(name)), inspect);
  /* not reached */
  return mrb_nil_value();
}
Exemple #5
0
static mrb_value
exc_equal(mrb_state *mrb, mrb_value exc)
{
  mrb_value obj;
  mrb_value mesg;
  mrb_sym id_mesg = mrb_intern(mrb, "mesg");

  mrb_get_args(mrb, "o", &obj);
  if (mrb_obj_equal(mrb, exc, obj)) return mrb_true_value();

  if (mrb_obj_class(mrb, exc) != mrb_obj_class(mrb, obj)) {
    if ( mrb_respond_to(mrb, obj, mrb_intern(mrb, "message")) ) {
      mesg = mrb_funcall(mrb, obj, "message", 0);
    }
    else
      return mrb_false_value();
  }
  else {
    mesg = mrb_attr_get(mrb, obj, id_mesg);
  }

  if (!mrb_equal(mrb, mrb_attr_get(mrb, exc, id_mesg), mesg))
    return mrb_false_value();
  return mrb_true_value();
}
Exemple #6
0
static mrb_value
mrb_ary_equal(mrb_state *mrb, mrb_value ary1)
{
  mrb_value ary2;
  mrb_int i;

  mrb_get_args(mrb, "o", &ary2);
  if (mrb_obj_equal(mrb, ary1, ary2)) return mrb_true_value();
  if (mrb_special_const_p(ary2)) return mrb_false_value();
  if (!mrb_array_p(ary2)) {
    if (!mrb_respond_to(mrb, ary2, mrb_intern2(mrb, "to_ary", 6))) {
      return mrb_false_value();
    }
    else {
      return mrb_bool_value(mrb_equal(mrb, ary2, ary1));
    }
  }
  if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return mrb_false_value();
  for (i=0; i<RARRAY_LEN(ary1); i++) {
    if (!mrb_equal(mrb, ary_elt(ary1, i), ary_elt(ary2, i))) {
      return mrb_false_value();
    }
  }
  return mrb_true_value();
}
Exemple #7
0
mrb_value
make_exception(mrb_state *mrb, int argc, mrb_value *argv, int isstr)
{
  mrb_value mesg;
  int n;

  mesg = mrb_nil_value();
  switch (argc) {
    case 0:
    break;
    case 1:
      if (mrb_nil_p(argv[0]))
        break;
      if (isstr) {
        mesg = mrb_check_string_type(mrb, argv[0]);
        if (!mrb_nil_p(mesg)) {
          mesg = mrb_exc_new3(mrb, E_RUNTIME_ERROR, mesg);
          break;
        }
      }
      n = 0;
      goto exception_call;

    case 2:
    case 3:
      n = 1;
exception_call:
      //if (argv[0] == sysstack_error) return argv[0];

      //CONST_ID(mrb, exception, "exception");
      //mesg = mrb_check_funcall(mrb, argv[0], exception, n, argv+1);
      //if (mrb_nil_p(mesg)) {
      //  /* undef */
      //  mrb_raise(mrb, E_TYPE_ERROR, "exception class/object expected");
      //}
      if (mrb_respond_to(mrb, argv[0], mrb_intern(mrb, "exception"))) {
        mesg = mrb_funcall_argv(mrb, argv[0], "exception", n, argv+1);
      }
      else {
        /* undef */
        mrb_raise(mrb, E_TYPE_ERROR, "exception class/object expected");
      }

      break;
    default:
      mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%d for 0..3)", argc);
      break;
  }
  if (argc > 0) {
    if (!mrb_obj_is_kind_of(mrb, mesg, mrb->eException_class))
      mrb_raise(mrb, E_TYPE_ERROR, "exception object expected");
    if (argc > 2)
        set_backtrace(mrb, mesg, argv[2]);
  }

  return mesg;
}
Exemple #8
0
/*
 * Class:     org_jamruby_mruby_RClass
 * Method:    n_respondTo
 * Signature: (JLorg/jamruby/mruby/Value;J)Z
 */
JNIEXPORT jboolean JNICALL Java_org_jamruby_mruby_RClass_n_1respondTo
  (JNIEnv *env, jclass, jlong mrb, jobject obj, jlong mid)
{
	mrb_value obj_val;
	if (!create_mrb_value(getEnv(), obj, obj_val)) {
		return JNI_FALSE;
	}
	int const &ret = mrb_respond_to(to_ptr<mrb_state>(mrb), obj_val, static_cast<mrb_sym>(mid));
	return (0 != ret) ? JNI_TRUE : JNI_FALSE;
}
Exemple #9
0
static mrb_value
make_exception(mrb_state *mrb, int argc, const mrb_value *argv, mrb_bool isstr)
{
  mrb_value mesg;
  int n;

  mesg = mrb_nil_value();
  switch (argc) {
    case 0:
    break;
    case 1:
      if (mrb_nil_p(argv[0]))
        break;
      if (isstr) {
        mesg = mrb_check_string_type(mrb, argv[0]);
        if (!mrb_nil_p(mesg)) {
          mesg = mrb_exc_new_str(mrb, E_RUNTIME_ERROR, mesg);
          break;
        }
      }
      n = 0;
      goto exception_call;

    case 2:
    case 3:
      n = 1;
exception_call:
      {
        mrb_sym exc = mrb_intern_lit(mrb, "exception");
        if (mrb_respond_to(mrb, argv[0], exc)) {
          mesg = mrb_funcall_argv(mrb, argv[0], exc, n, argv+1);
        }
        else {
          /* undef */
          mrb_raise(mrb, E_TYPE_ERROR, "exception class/object expected");
        }
      }

      break;
    default:
      mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%S for 0..3)", mrb_fixnum_value(argc));
      break;
  }
  if (argc > 0) {
    if (!mrb_obj_is_kind_of(mrb, mesg, mrb->eException_class))
      mrb_raise(mrb, mrb->eException_class, "exception object expected");
    if (argc > 2)
      set_backtrace(mrb, mesg, argv[2]);
  }

  return mesg;
}
Exemple #10
0
MRB_API mrb_value
mrb_ary_splat(mrb_state *mrb, mrb_value v)
{
  if (mrb_array_p(v)) {
    return v;
  }
  if (mrb_respond_to(mrb, v, mrb_intern_lit(mrb, "to_a"))) {
    return mrb_funcall(mrb, v, "to_a", 0);
  }
  else {
    return mrb_ary_new_from_values(mrb, 1, &v);
  }
}
Exemple #11
0
static void close_body_obj(h2o_mruby_generator_t *generator)
{
    h2o_mruby_chunked_t *chunked = generator->chunked;
    mrb_state *mrb = generator->ctx->shared->mrb;

    if (!mrb_nil_p(chunked->body_obj)) {
        /* call close and throw away error */
        if (mrb_respond_to(mrb, chunked->body_obj, generator->ctx->shared->symbols.sym_close))
            mrb_funcall_argv(mrb, chunked->body_obj, generator->ctx->shared->symbols.sym_close, 0, NULL);
        mrb->exc = NULL;
        mrb_gc_unregister(mrb, chunked->body_obj);
        chunked->body_obj = mrb_nil_value();
    }
}
Exemple #12
0
static mrb_value
convert_type(mrb_state *mrb, mrb_value val, const char *tname, const char *method, mrb_bool raise)
{
  mrb_sym m = 0;

  m = mrb_intern_cstr(mrb, method);
  if (!mrb_respond_to(mrb, val, m)) {
    if (raise) {
      mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S into %S", inspect_type(mrb, val), mrb_str_new_cstr(mrb, tname));
    }
    return mrb_nil_value();
  }
  return mrb_funcall_argv(mrb, val, m, 0, 0);
}
Exemple #13
0
static mrb_value
hash_equal(mrb_state *mrb, mrb_value hash1, mrb_value hash2, mrb_bool eql)
{
  khash_t(ht) *h1, *h2;
  mrb_bool eq;

  if (mrb_obj_equal(mrb, hash1, hash2)) return mrb_true_value();
  if (!mrb_hash_p(hash2)) {
      if (!mrb_respond_to(mrb, hash2, mrb_intern_lit(mrb, "to_hash"))) {
          return mrb_false_value();
      }
      else {
        if (eql) {
          eq = mrb_eql(mrb, hash2, hash1);
        }
        else {
          eq = mrb_equal(mrb, hash2, hash1);
        }
        return mrb_bool_value(eq);
      }
  }
  h1 = RHASH_TBL(hash1);
  h2 = RHASH_TBL(hash2);
  if (!h1) {
    return mrb_bool_value(!h2);
  }
  if (!h2) return mrb_false_value();
  if (kh_size(h1) != kh_size(h2)) return mrb_false_value();
  else {
    khiter_t k1, k2;
    mrb_value key;

    for (k1 = kh_begin(h1); k1 != kh_end(h1); k1++) {
      if (!kh_exist(h1, k1)) continue;
      key = kh_key(h1,k1);
      k2 = kh_get(ht, mrb, h2, key);
      if (k2 != kh_end(h2)) {
        if (eql)
          eq = mrb_eql(mrb, kh_value(h1,k1), kh_value(h2,k2));
        else
          eq = mrb_equal(mrb, kh_value(h1,k1), kh_value(h2,k2));
        if (eq) {
          continue; /* next key */
        }
      }
      return mrb_false_value();
    }
  }
  return mrb_true_value();
}
static mrb_value
cfunc_call(mrb_state *mrb, mrb_value self)
{
    int margc;
    mrb_value mresult_type, mname, *margs;
    mrb_get_args(mrb, "oo*", &mresult_type, &mname, &margs, &margc);
        
    void *dlh = dlopen(NULL, RTLD_LAZY);
    void *fp = dlsym(dlh, RSTRING_PTR(mname));
    
    ffi_type **args = malloc(sizeof(ffi_type*) * margc);
    void **values = malloc(sizeof(void*) * margc);
    mrb_sym to_pointer = mrb_intern(mrb, "to_pointer");

    for(int i = 0; i < margc; ++i) {
        if(!mrb_respond_to(mrb, margs[i], to_pointer)) {
            // Todo: should free some malloc-ed pointers
            mrb_raise(mrb, E_TYPE_ERROR, "ignore argument type");
        }
        args[i] = mrb_value_to_mrb_ffi_type(mrb, margs[i])->ffi_type_value;
        values[i] = mobi_pointer_ptr(mrb_funcall(mrb, margs[i], "to_pointer", 0));
    }
    
    ffi_type *result_type = rclass_to_mrb_ffi_type(mrb, mrb_class_ptr(mresult_type))->ffi_type_value;
    if (result_type == NULL) {
        mrb_raise(mrb, E_ARGUMENT_ERROR, "ignore return type");
    }
    
    mrb_value mresult = mrb_nil_value();
    ffi_cif cif;
    if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, margc, result_type, args) == FFI_OK) {
        void *result = result_type->size ? malloc(result_type->size) : NULL;
        ffi_call(&cif, fp, result, values);
        
        if(result) {
            mrb_value result_ptr = cfunc_pointer_new_with_pointer(mrb, result, 1);
            mresult = mrb_funcall(mrb, mresult_type, "refer", 1, result_ptr);
        }
    }
    else {
        // todo
        mrb_raise(mrb, E_NAME_ERROR, "can't find C function");
    }

cfunc_call_exit:
    free(values);
    free(args);
    return mresult;
}
Exemple #15
0
static mrb_value
hash_equal(mrb_state *mrb, mrb_value hash1, mrb_value hash2, int eql)
{
  if (mrb_obj_equal(mrb, hash1, hash2)) return mrb_true_value();
  if (mrb_type(hash2) != MRB_TT_HASH) {
      if (!mrb_respond_to(mrb, hash2, mrb_intern(mrb, "to_hash"))) {
          return mrb_false_value();
      }
      if (eql)
          return mrb_fixnum_value(mrb_eql(mrb, hash2, hash1));
      else
          return mrb_fixnum_value(mrb_equal(mrb, hash2, hash1));
  }
  if (RHASH_SIZE(hash1) != RHASH_SIZE(hash2)) return mrb_false_value();
  if (!RHASH(hash1)->ht || !RHASH(hash2)->ht) return mrb_true_value();

  return mrb_exec_recursive_paired(mrb, recursive_eql, hash1, hash2, (void*)0);
}
Exemple #16
0
MRB_API mrb_value
mrb_ary_splat(mrb_state *mrb, mrb_value v)
{
  mrb_value a;

  if (mrb_array_p(v)) {
    return v;
  }

  if (!mrb_respond_to(mrb, v, mrb_intern_lit(mrb, "to_a"))) {
    return mrb_ary_new_from_values(mrb, 1, &v);
  }

  a = mrb_funcall(mrb, v, "to_a", 0);
  if (mrb_nil_p(a)) {
    return mrb_ary_new_from_values(mrb, 1, &v);
  }
  mrb_ensure_array_type(mrb, a);
  return a;
}
Exemple #17
0
static mrb_value
hash_equal(mrb_state *mrb, mrb_value hash1, mrb_value hash2, int eql)
{
  khash_t(ht) *h1, *h2;

  if (mrb_obj_equal(mrb, hash1, hash2)) return mrb_true_value();
  if (mrb_type(hash2) != MRB_TT_HASH) {
      if (!mrb_respond_to(mrb, hash2, mrb_intern(mrb, "to_hash"))) {
          return mrb_false_value();
      }
      if (eql)
          return mrb_fixnum_value(mrb_eql(mrb, hash2, hash1));
      else
          return mrb_fixnum_value(mrb_equal(mrb, hash2, hash1));
  }
  h1 = RHASH_TBL(hash1);
  h2 = RHASH_TBL(hash2);
  if (!h2) {
    if (!h2)  return mrb_true_value();
    return mrb_false_value();
  }
  if (!h2) return mrb_false_value();
  if (kh_size(h1) != kh_size(h2)) return mrb_false_value();
  else {
    khiter_t k1, k2;
    mrb_value key;

    for (k1 = kh_begin(h1); k1 != kh_end(h1); k1++) {
      if (!kh_exist(h1, k1)) continue;
      key = kh_key(h1,k1);
      k2 = kh_get(ht, h2, key);
      if (k2 != kh_end(h2)) {
	if (mrb_equal(mrb, kh_value(h1,k1), kh_value(h2,k2))) {
	  continue; /* next key */
	}
      }
      return mrb_false_value();
    }
  }
  return mrb_true_value();
}
Exemple #18
0
mrb_value
convert_type(mrb_state *mrb, mrb_value val, const char *tname, const char *method, int raise)
{
  mrb_sym m = 0;

  m = mrb_intern(mrb, method);
  if (!mrb_respond_to(mrb, val, m)) {
    if (raise) {
      mrb_raise(mrb, E_TYPE_ERROR, "can't convert %s into %s",
         mrb_nil_p(val) ? "nil" :
         (mrb_type(val) == MRB_TT_TRUE) ? "true" :
         (mrb_type(val) == MRB_TT_FALSE) ? "false" :
         mrb_obj_classname(mrb, val),
         tname);
      return mrb_nil_value();
    }
    else {
      return mrb_nil_value();
    }
  }
  return mrb_funcall(mrb, val, method, 0);
}
Exemple #19
0
static mrb_value
mrb_ary_equal(mrb_state *mrb, mrb_value ary1)
{
  mrb_value ary2;
  mrb_bool equal_p;

  mrb_get_args(mrb, "o", &ary2);
  if (mrb_obj_equal(mrb, ary1, ary2)) {
    equal_p = 1;
  }
  else if (mrb_special_const_p(ary2)) {
    equal_p = 0;
  }
  else if (!mrb_array_p(ary2)) {
    if (!mrb_respond_to(mrb, ary2, mrb_intern2(mrb, "to_ary", 6))) {
        equal_p = 0;
    }
    else {
      equal_p = mrb_equal(mrb, ary2, ary1);
    }
  }
  else if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) {
    equal_p = 0;
  }
  else {
    mrb_int i;

    equal_p = 1;
    for (i=0; i<RARRAY_LEN(ary1); i++) {
      if (!mrb_equal(mrb, ary_elt(ary1, i), ary_elt(ary2, i))) {
        equal_p = 0;
        break;
      }
    }
  }

  return mrb_bool_value(equal_p);
}
Exemple #20
0
static mrb_value
const_get(mrb_state *mrb, struct RClass *base, mrb_sym sym)
{
    struct RClass *c = base;
    mrb_value v;
    iv_tbl *t;
    mrb_bool retry = 0;
    mrb_sym cm;

L_RETRY:
    while (c) {
        if (c->iv) {
            t = c->iv;
            if (iv_get(mrb, t, sym, &v))
                return v;
        }
        c = c->super;
    }
    if (!retry && base && base->tt == MRB_TT_MODULE) {
        c = mrb->object_class;
        retry = 1;
        goto L_RETRY;
    }
    c = base;
    cm = mrb_intern2(mrb, "const_missing", 13);
    while (c) {
        if (mrb_respond_to(mrb, mrb_obj_value(c), cm)) {
            mrb_value name = mrb_symbol_value(sym);
            return mrb_funcall_argv(mrb, mrb_obj_value(c), cm, 1, &name);
        }
        c = c->super;
    }
    mrb_raisef(mrb, E_NAME_ERROR, "uninitialized constant %s",
               mrb_sym2name(mrb, sym));
    /* not reached */
    return mrb_nil_value();
}
Exemple #21
0
int main()
{
  mrb_state *mrb = mrb_open();
  init_TestClass(mrb);

  char code[] = "$t = Test.new; res = $t.run; p res";
  printf("Executing Ruby code from C!\n");

  auto c = mrbc_context_new(mrb);
  auto p = mrb_parse_string(mrb, code, c);
  auto n = mrb_generate_code(mrb, p);

  // mrb_run(mrb, n, mrb_top_self(mrb));
  unsigned stack_keep = 0;
  auto result = mrb_vm_run(mrb,
                n,
                mrb_top_self(mrb),
                stack_keep);

  if (mrb->exc) // have exception
  {
    mrb_p(mrb, mrb_obj_value(mrb->exc));
    mrb->exc = 0;
  }
  else
  {
    if (!mrb_respond_to(mrb, result, mrb_intern_lit(mrb, "inspect")))
      result = mrb_any_to_s(mrb, result);
    
    mrb_p(mrb, result);
  }

  mrbc_context_free(mrb, c);
  mrb_close(mrb);

  return 0;
}
Exemple #22
0
static void
mrb_search_method_owner(mrb_state *mrb, struct RClass *c, mrb_value obj, mrb_sym name, struct RClass **owner, struct RProc **proc, mrb_bool unbound)
{
  mrb_value ret;
  const char *s;

  *owner = c;
  *proc = method_search_vm(mrb, owner, name);
  if (!*proc) {
    if (unbound) {
      goto name_error;
    }
    if (!mrb_respond_to(mrb, obj, mrb_intern_lit(mrb, "respond_to_missing?"))) {
      goto name_error;
    }
    ret = mrb_funcall(mrb, obj, "respond_to_missing?", 2, mrb_symbol_value(name), mrb_true_value());
    if (!mrb_test(ret)) {
      goto name_error;
    }
    *owner = c;
  }

  while ((*owner)->tt == MRB_TT_ICLASS)
    *owner = (*owner)->c;

  return;

name_error:
  s = mrb_class_name(mrb, c);
  mrb_raisef(
    mrb, E_NAME_ERROR,
    "undefined method `%S' for class `%S'",
    mrb_sym2str(mrb, name),
    mrb_str_new_static(mrb, s, strlen(s))
  );
}
Exemple #23
0
int
main(void)
{
  char ruby_code[1024] = { 0 };
  char last_code_line[1024] = { 0 };
#ifndef ENABLE_READLINE
  int last_char;
  int char_index;
#endif
  mrbc_context *cxt;
  struct mrb_parser_state *parser;
  mrb_state *mrb;
  mrb_value result;
  int n;
  int code_block_open = FALSE;
  int ai;

  print_hint();

  /* new interpreter instance */
  mrb = mrb_open();
  if (mrb == NULL) {
    fprintf(stderr, "Invalid mrb interpreter, exiting mirb");
    return EXIT_FAILURE;
  }

  cxt = mrbc_context_new(mrb);
  cxt->capture_errors = 1;

  ai = mrb_gc_arena_save(mrb);
  while (TRUE) {
#ifndef ENABLE_READLINE
    print_cmdline(code_block_open);

    char_index = 0;
    while ((last_char = getchar()) != '\n') {
      if (last_char == EOF) break;
      last_code_line[char_index++] = last_char;
    }
    if (last_char == EOF) {
      printf("\n");
      break;
    }

    last_code_line[char_index] = '\0';
#else
    char* line = readline(code_block_open ? "* " : "> ");
    if(line == NULL) {
      printf("\n");
      break;
    }
    strncat(last_code_line, line, sizeof(last_code_line)-1);
    add_history(line);
    free(line);
#endif

    if ((strcmp(last_code_line, "quit") == 0) || (strcmp(last_code_line, "exit") == 0)) {
      if (!code_block_open) {
        break;
      }
      else{
        /* count the quit/exit commands as strings if in a quote block */
        strcat(ruby_code, "\n");
        strcat(ruby_code, last_code_line);
      }
    }
    else {
      if (code_block_open) {
        strcat(ruby_code, "\n");
        strcat(ruby_code, last_code_line);
      }
      else {
        strcpy(ruby_code, last_code_line);
      }
    }

    /* parse code */
    parser = mrb_parser_new(mrb);
    parser->s = ruby_code;
    parser->send = ruby_code + strlen(ruby_code);
    parser->lineno = 1;
    mrb_parser_parse(parser, cxt);
    code_block_open = is_code_block_open(parser);

    if (code_block_open) {
      /* no evaluation of code */
    }
    else {
      if (0 < parser->nerr) {
        /* syntax error */
        printf("line %d: %s\n", parser->error_buffer[0].lineno, parser->error_buffer[0].message);
      }
      else {
        /* generate bytecode */
        n = mrb_generate_code(mrb, parser);

        /* evaluate the bytecode */
        result = mrb_run(mrb,
            /* pass a proc for evaulation */
            mrb_proc_new(mrb, mrb->irep[n]),
            mrb_top_self(mrb));
        /* did an exception occur? */
        if (mrb->exc) {
          p(mrb, mrb_obj_value(mrb->exc));
          mrb->exc = 0;
        }
        else {
          /* no */
          printf(" => ");
          if (!mrb_respond_to(mrb,result,mrb_intern(mrb,"inspect"))){
            result = mrb_any_to_s(mrb,result);
          }
          p(mrb, result);
        }
      }
      ruby_code[0] = '\0';
      last_code_line[0] = '\0';
      mrb_parser_free(parser);
      mrb_gc_arena_restore(mrb, ai);
    }
  }
  mrbc_context_free(mrb, cxt);
  mrb_close(mrb);

  return 0;
}
Exemple #24
0
int
main(int argc, char **argv)
{
  char ruby_code[1024] = { 0 };
  char last_code_line[1024] = { 0 };
#ifndef ENABLE_READLINE
  int last_char;
  int char_index;
#else
  char *home = NULL;
#endif
  mrbc_context *cxt;
  struct mrb_parser_state *parser;
  mrb_state *mrb;
  mrb_value result;
  struct _args args;
  int n;
  mrb_bool code_block_open = FALSE;
  mrb_value MIRB_BIN;
  int ai;
  unsigned int stack_keep = 0;

  /* new interpreter instance */
  mrb = mrb_open();
  if (mrb == NULL) {
    fputs("Invalid mrb interpreter, exiting mirb\n", stderr);
    return EXIT_FAILURE;
  }
  mrb_define_global_const(mrb, "ARGV", mrb_ary_new_capa(mrb, 0));

  n = parse_args(mrb, argc, argv, &args);
  if (n == EXIT_FAILURE) {
    cleanup(mrb, &args);
    usage(argv[0]);
    return n;
  }

  print_hint();

  cxt = mrbc_context_new(mrb);
  cxt->capture_errors = 1;
  cxt->lineno = 1;
  mrbc_filename(mrb, cxt, "(mirb)");
  if (args.verbose) cxt->dump_result = 1;

  MIRB_BIN= mrb_str_new(mrb, argv[0], strlen(argv[0]));
  mrb_define_global_const(mrb, "MIRB_BIN", MIRB_BIN);

#ifdef ENABLE_REQUIRE
  mrb_value LOAD_PATH = mrb_gv_get(mrb, mrb_intern(mrb, "$:"));

  if (mrb_str_cmp(mrb, MIRB_BIN, mrb_str_new2(mrb, "mirb")) != 0) {
    int len = strrchr(RSTRING_PTR(MIRB_BIN), '/') - RSTRING_PTR(MIRB_BIN);
    mrb_value extdir = mrb_str_substr(mrb, mrb_str_dup(mrb, MIRB_BIN), 0, len);
    mrb_str_cat2(mrb, extdir, "/../ext");

    if (mrb_obj_eq(mrb, mrb_file_exist(mrb, extdir), mrb_true_value())) {
      mrb_ary_push(mrb, LOAD_PATH, extdir);
    }
  }
#endif /* ENABLE_REQUIRE */


  ai = mrb_gc_arena_save(mrb);

#ifdef ENABLE_READLINE
  MIRB_USING_HISTORY();
  home = getenv("HOME");
#ifdef _WIN32
  if (!home)
    home = getenv("USERPROFILE");
#endif
  if (home) {
    strcpy(history_path, home);
    strcat(history_path, "/");
    strcat(history_path, history_file_name);
    MIRB_READ_HISTORY(history_path);
  }
#endif


  while (TRUE) {
#ifndef ENABLE_READLINE
    print_cmdline(code_block_open);

    char_index = 0;
    while ((last_char = getchar()) != '\n') {
      if (last_char == EOF) break;
      last_code_line[char_index++] = last_char;
    }
    if (last_char == EOF) {
      fputs("\n", stdout);
      break;
    }

    last_code_line[char_index] = '\0';
#else
    char* line = MIRB_READLINE(code_block_open ? "* " : "> ");
    if (line == NULL) {
      printf("\n");
      break;
    }
    strncpy(last_code_line, line, sizeof(last_code_line)-1);
    MIRB_ADD_HISTORY(line);
    free(line);
#endif

    if (code_block_open) {
        strcat(ruby_code, "\n");
        strcat(ruby_code, last_code_line);
    }
    else {
      if ((strcmp(last_code_line, "quit") == 0) || (strcmp(last_code_line, "exit") == 0)) {
        break;
      }
      strcpy(ruby_code, last_code_line);
    }

    /* parse code */
    parser = mrb_parser_new(mrb);
    parser->s = ruby_code;
    parser->send = ruby_code + strlen(ruby_code);
    parser->lineno = cxt->lineno;
    mrb_parser_parse(parser, cxt);
    code_block_open = is_code_block_open(parser);

    if (code_block_open) {
      /* no evaluation of code */
    }
    else {
      if (0 < parser->nerr) {
        /* syntax error */
        printf("line %d: %s\n", parser->error_buffer[0].lineno, parser->error_buffer[0].message);
      }
      else {
        /* generate bytecode */
        struct RProc *proc = mrb_generate_code(mrb, parser);

        if (args.verbose) {
          mrb_codedump_all(mrb, proc);
        }
        /* pass a proc for evaulation */
        /* evaluate the bytecode */
        result = mrb_context_run(mrb,
            proc,
            mrb_top_self(mrb),
            stack_keep);
        stack_keep = proc->body.irep->nlocals;
        /* did an exception occur? */
        if (mrb->exc) {
          p(mrb, mrb_obj_value(mrb->exc), 0);
          mrb->exc = 0;
        }
        else {
          /* no */
          if (!mrb_respond_to(mrb, result, mrb_intern_lit(mrb, "inspect"))){
            result = mrb_any_to_s(mrb,result);
          }
          p(mrb, result, 1);
        }
      }
      ruby_code[0] = '\0';
      last_code_line[0] = '\0';
      mrb_gc_arena_restore(mrb, ai);
    }
    mrb_parser_free(parser);
    cxt->lineno++;
  }
  mrbc_context_free(mrb, cxt);
  mrb_close(mrb);

#ifdef ENABLE_READLINE
  MIRB_WRITE_HISTORY(history_path);
#endif

  return 0;
}
Exemple #25
0
static mrb_value
mrb_sdl2_misc_bytebuffer_initialize(mrb_state *mrb, mrb_value self)
{
  mrb_value arg;
  mrb_get_args(mrb, "o", &arg);

  mrb_sdl2_misc_buffer_data_t *data =
    (mrb_sdl2_misc_buffer_data_t*)DATA_PTR(self);

  if (NULL == data) {
    data = (mrb_sdl2_misc_buffer_data_t*)mrb_malloc(mrb, sizeof(mrb_sdl2_misc_buffer_data_t));
    if (NULL == data) {
      mrb_raise(mrb, E_RUNTIME_ERROR, "insufficient memory.");
    }
    data->buffer = NULL;
    data->size   = 0;
  }

  enum mrb_vtype const arg_type = mrb_type(arg);
  switch (arg_type) {
  case MRB_TT_FIXNUM:
    data->size = (size_t)mrb_fixnum(arg);
    break;
  case MRB_TT_FLOAT:
    data->size = (size_t)mrb_float(arg);
    break;
  case MRB_TT_STRING:
    data->size = (size_t)mrb_float(mrb_funcall(mrb, arg, "to_f", 0));
    break;
  case MRB_TT_ARRAY:
    {
      mrb_int const n = mrb_ary_len(mrb, arg);
      if (0 == n) {
        mrb_raise(mrb, E_ARGUMENT_ERROR, "cannot accept empty array.");
      }
      data->size = n * sizeof(uint8_t);
    }
    break;
  default:
    if (mrb_respond_to(mrb, arg, mrb_intern(mrb, "to_f", 4))) {
      data->size = (size_t)mrb_float(mrb_funcall(mrb, arg, "to_f", 0));
    } else if (mrb_respond_to(mrb, arg, mrb_intern(mrb, "to_i", 4))) {
      data->size = (size_t)mrb_fixnum(mrb_funcall(mrb, arg, "to_i", 0));
    } else {
      mrb_raise(mrb, E_TYPE_ERROR, "expected Fixnum/Float/String/Array or comvertible type");
    }
    break;
  }

  data->buffer = mrb_malloc(mrb, data->size);
  if (NULL == data->buffer) {
    mrb_free(mrb, data);
    mrb_raise(mrb, E_RUNTIME_ERROR, "insufficient memory.");
  }

  size_t i = 0;
  for (i = 0; i < data->size/sizeof(uint8_t); ++i) {
    ((uint8_t*)data->buffer)[i] = 0;
  }

  if (arg_type == MRB_TT_ARRAY) {
    mrb_int const n = mrb_ary_len(mrb, arg);
    mrb_int i;
    for (i = 0; i < n; ++i) {
      mrb_value const item = mrb_ary_ref(mrb, arg, i);
      switch (mrb_type(item)) {
      case MRB_TT_FIXNUM:
        ((uint8_t*)data->buffer)[i] = (uint8_t)(mrb_fixnum(item) & 0xffu);
        break;
      case MRB_TT_FLOAT:
        ((uint8_t*)data->buffer)[i] = (uint8_t)((uint32_t)mrb_float(item) & 0xffu);
        break;
      case MRB_TT_STRING:
        ((uint8_t*)data->buffer)[i] = (uint8_t)((uint32_t)mrb_float(mrb_funcall(mrb, item, "to_f", 0)) & 0xffu);
        break;
      default:
        if (mrb_respond_to(mrb, item, mrb_intern(mrb, "to_f", 4))) {
          ((uint8_t*)data->buffer)[i] = (uint8_t)((uint32_t)mrb_float(mrb_funcall(mrb, item, "to_f", 0)) & 0xffu);
        } else if (mrb_respond_to(mrb, item, mrb_intern(mrb, "to_i", 4))) {
          ((uint8_t*)data->buffer)[i] = (uint8_t)(mrb_fixnum(mrb_funcall(mrb, item, "to_i", 0)) & 0xffu);
        } else {
          mrb_free(mrb, data->buffer);
          mrb_free(mrb, data);
          mrb_raise(mrb, E_TYPE_ERROR, "expected Fixnum/Float/String or convertible type");
        }
        break;
      }
    }
  }

  DATA_PTR(self) = data;
  DATA_TYPE(self) = &mrb_sdl2_misc_buffer_data_type;

  return self;
}
Exemple #26
0
static inline mrb_bool
basic_obj_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym id, int pub)
{
  return mrb_respond_to(mrb, obj, id);
}
Exemple #27
0
static mrb_value
cfunc_call(mrb_state *mrb, mrb_value self)
{
    int margc;
    mrb_value mresult_type, mname, *margs;
    void **values = NULL;
    ffi_type **args = NULL;

    mrb_get_args(mrb, "oo*", &mresult_type, &mname, &margs, &margc);

    void *fp = NULL;
    if(mrb_string_p(mname) || mrb_symbol_p(mname)) {
        void *dlh = dlopen(NULL, RTLD_LAZY);
        fp = dlsym(dlh, mrb_string_value_ptr(mrb, mname));
        dlclose(dlh);
    }
    else {
        fp = cfunc_pointer_ptr(mname);
    }

    if(fp == NULL) {
        mrb_raisef(mrb, E_NAME_ERROR, "can't find C function %s", mrb_string_value_ptr(mrb, mname));
        goto cfunc_call_exit;
    }

    args = malloc(sizeof(ffi_type*) * margc);
    values = malloc(sizeof(void*) * margc);
    mrb_sym sym_to_ffi_value = mrb_intern(mrb, "to_ffi_value");

    mrb_value nil_ary[1];
    nil_ary[0] = mrb_nil_value();
    for(int i = 0; i < margc; ++i) {
        if(mrb_respond_to(mrb, margs[i], sym_to_ffi_value)) {
            args[i] = mrb_value_to_mrb_ffi_type(mrb, margs[i])->ffi_type_value;
            values[i] = cfunc_pointer_ptr(mrb_funcall_argv(mrb, margs[i], sym_to_ffi_value, 1, nil_ary));
        }
        else {
            cfunc_mrb_raise_without_jump(mrb, E_TYPE_ERROR, "ignore argument type %s", mrb_obj_classname(mrb, margs[i]));
            goto cfunc_call_exit;
        }
    }

    ffi_type *result_type = rclass_to_mrb_ffi_type(mrb, mrb_class_ptr(mresult_type))->ffi_type_value;
    if (result_type == NULL) {
        cfunc_mrb_raise_without_jump(mrb, E_ARGUMENT_ERROR, "ignore return type %s", mrb_class_name(mrb, mrb_class_ptr(mresult_type)));
        goto cfunc_call_exit;
    }

    mrb_value mresult = mrb_nil_value();
    ffi_cif cif;
    if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, margc, result_type, args) == FFI_OK) {
        void *result;
        if(result_type->size > sizeof(long)) {
            result = malloc(result_type->size);
        }
        else if(result_type->size) {
            result = malloc(sizeof(long));
        }
        else {
            result = NULL;
        }
        ffi_call(&cif, fp, result, values);

        if(result) {
            mrb_value result_ptr = cfunc_pointer_new_with_pointer(mrb, result, true);
            mresult = mrb_funcall(mrb, mresult_type, "refer", 1, result_ptr);
        }
    }
    else {
        mrb_raisef(mrb, E_NAME_ERROR, "Can't find C function %s", mname);
        goto cfunc_call_exit;
    }

cfunc_call_exit:
    free(values);
    free(args);
    return mresult;
}
Exemple #28
0
void loop() {
  if (Serial.available() > 0) {
    char_index = 0;
    while (true) {
      if (Serial.available() > 0) {
        incommingByte = Serial.read();
        if (incommingByte == 13) {
          // New Line
          last_code_line[char_index] = '\0';
          break;
        } else {
          last_code_line[char_index++] = incommingByte;
          Serial.write(incommingByte);
        }
      }
    }
    Serial.println("");
    Serial.flush();

    is_exit = false;
    if ((strcmp(last_code_line, "quit") == 0) || (strcmp(last_code_line, "exit") == 0)) {
      // Exit Interactive Mode
      if (!code_block_open) {
        is_exit = true;
      } else {
        /* count the quit/exit commands as strings if in a quote block */
        strcat(ruby_code, "\n");
        strcat(ruby_code, last_code_line);
        is_exit = false;
      }
    } else {
      if (code_block_open) {
        strcat(ruby_code, "\n");
        strcat(ruby_code, last_code_line);
        is_exit = false;
      } else {
        strcpy(ruby_code, last_code_line);
        is_exit = false;
      }
    }

    if (!is_exit) {
      // Not Exit or Quit!

      /* parse code */
      parser = mrb_parser_new(mrb);
      parser->s = ruby_code;
      parser->send = ruby_code + strlen(ruby_code);
      parser->lineno = 1;
      mrb_parser_parse(parser, cxt);
      code_block_open = is_code_block_open(parser);

      if (code_block_open) {
        /* no evaluation of code */
      }
      else {
        if (0 < parser->nerr) {
          /* syntax error */
          Serial.write("Syntax Error: ");
          Serial.println(parser->error_buffer[0].message);
        }
        else {
          /* generate bytecode */
          n = mrb_generate_code(mrb, parser);

          /* evaluate the bytecode */
          result = mrb_run(mrb,
              /* pass a proc for evaulation */
              mrb_proc_new(mrb, mrb->irep[n]),
              mrb_top_self(mrb));

          /* did an exception occur? */
          if (mrb->exc) {
            /* yes */
            p(mrb, mrb_obj_value(mrb->exc), 0);
            mrb->exc = 0;
          }
          else {
            /* no */
            if (!mrb_respond_to(mrb,result,mrb_intern(mrb, "inspect"))){
              result = mrb_any_to_s(mrb,result);
            }
            p(mrb, result, 1);
          }
        }
        ruby_code[0] = '\0';
        last_code_line[0] = '\0';
        mrb_gc_arena_restore(mrb, ai);
      }
      mrb_parser_free(parser);
    } else {
      // User Enter 'exit' or 'quit'
      Serial.println("quit IAS");
      ruby_code[0] = '\0';
      last_code_line[0] = '\0';
      mrb_parser_free(parser);
      mrbc_context_free(mrb, cxt);
      mrb_close(mrb);
      mrb_setup_arduino();
    }
    print_cmdline(code_block_open);
  }
}
Exemple #29
0
static inline int
basic_obj_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym id, int pub)
{
  return mrb_respond_to(mrb, obj, id);
  //return TRUE;
}
Exemple #30
0
int
main(int argc, char **argv)
{
  char ruby_code[1024] = { 0 };
  char last_code_line[1024] = { 0 };
#ifndef ENABLE_READLINE
  int last_char;
  int char_index;
#else
  char *home = NULL;
#endif
  mrbc_context *cxt;
  struct mrb_parser_state *parser;
  mrb_state *mrb;
  mrb_value result;
  struct _args args;
  int n;
  mrb_bool code_block_open = FALSE;
  int ai;
  mrb_bool first_command = TRUE;
  unsigned int nregs;

  /* new interpreter instance */
  mrb = mrb_open();
  if (mrb == NULL) {
    fputs("Invalid mrb interpreter, exiting mirb\n", stderr);
    return EXIT_FAILURE;
  }
  mrb_define_global_const(mrb, "ARGV", mrb_ary_new_capa(mrb, 0));

  n = parse_args(mrb, argc, argv, &args);
  if (n == EXIT_FAILURE) {
    cleanup(mrb, &args);
    usage(argv[0]);
    return n;
  }

  print_hint();

  cxt = mrbc_context_new(mrb);
  cxt->capture_errors = 1;
  cxt->lineno = 1;
  mrbc_filename(mrb, cxt, "(mirb)");
  if (args.verbose) cxt->dump_result = 1;

  ai = mrb_gc_arena_save(mrb);

#ifdef ENABLE_READLINE
  using_history();
  home = getenv("HOME");
#ifdef _WIN32
  if (!home)
    home = getenv("USERPROFILE");
#endif
  if (home) {
    strcpy(history_path, home);
    strcat(history_path, "/");
    strcat(history_path, history_file_name);
    read_history(history_path);
  }
#endif


  while (TRUE) {
#ifndef ENABLE_READLINE
    print_cmdline(code_block_open);

    char_index = 0;
    while ((last_char = getchar()) != '\n') {
      if (last_char == EOF) break;
      last_code_line[char_index++] = last_char;
    }
    if (last_char == EOF) {
      fputs("\n", stdout);
      break;
    }

    last_code_line[char_index] = '\0';
#else
    char* line = readline(code_block_open ? "* " : "> ");
    if (line == NULL) {
      printf("\n");
      break;
    }
    strncpy(last_code_line, line, sizeof(last_code_line)-1);
    add_history(line);
    free(line);
#endif

    if ((strcmp(last_code_line, "quit") == 0) || (strcmp(last_code_line, "exit") == 0)) {
      if (!code_block_open) {
        break;
      }
      else{
        /* count the quit/exit commands as strings if in a quote block */
        strcat(ruby_code, "\n");
        strcat(ruby_code, last_code_line);
      }
    }
    else {
      if (code_block_open) {
        strcat(ruby_code, "\n");
        strcat(ruby_code, last_code_line);
      }
      else {
        strcpy(ruby_code, last_code_line);
      }
    }

    /* parse code */
    parser = mrb_parser_new(mrb);
    parser->s = ruby_code;
    parser->send = ruby_code + strlen(ruby_code);
    parser->lineno = cxt->lineno;
    mrb_parser_parse(parser, cxt);
    code_block_open = is_code_block_open(parser);

    if (code_block_open) {
      /* no evaluation of code */
    }
    else {
      if (0 < parser->nerr) {
        /* syntax error */
        printf("line %d: %s\n", parser->error_buffer[0].lineno, parser->error_buffer[0].message);
      }
      else {
        /* generate bytecode */
        struct RProc *proc = mrb_generate_code(mrb, parser);

        if (args.verbose) {
          mrb_codedump_all(mrb, proc);
        }
        /* pass a proc for evaulation */
        nregs = first_command ? 0: proc->body.irep->nregs;
        /* evaluate the bytecode */
        result = mrb_context_run(mrb,
            proc,
            mrb_top_self(mrb),
            nregs);
        /* did an exception occur? */
        if (mrb->exc) {
          p(mrb, mrb_obj_value(mrb->exc), 0);
          mrb->exc = 0;
        }
        else {
          /* no */
          if (!mrb_respond_to(mrb, result, mrb_intern_lit(mrb, "inspect"))){
            result = mrb_any_to_s(mrb,result);
          }
          p(mrb, result, 1);
        }
      }
      ruby_code[0] = '\0';
      last_code_line[0] = '\0';
      mrb_gc_arena_restore(mrb, ai);
    }
    mrb_parser_free(parser);
    cxt->lineno++;
    first_command = FALSE;
  }
  mrbc_context_free(mrb, cxt);
  mrb_close(mrb);

#ifdef ENABLE_READLINE
  write_history(history_path);
#endif

  return 0;
}