// Converts Go value to mruby value. func (m *MRuby) mrubyValue(i interface{}) C.mrb_value { v := reflect.ValueOf(i) switch v.Kind() { case reflect.Invalid: return C.mrb_nil_value() // mrb_undef_value() explodes case reflect.Bool: b := v.Bool() if b { return C.mrb_true_value() } else { return C.mrb_false_value() } case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return C.mrb_fixnum_value(C.mrb_int(v.Int())) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: return C.mrb_fixnum_value(C.mrb_int(v.Uint())) case reflect.Float32, reflect.Float64: return C.mrb_float_value((*C.struct_mrb_state)(m.state), C.mrb_float(v.Float())) case reflect.String: cs := C.CString(v.String()) defer C.free(unsafe.Pointer(cs)) if v.Type() == symbolT { return C.mrb_check_intern_cstr(m.state, cs) } else { return C.mrb_str_new_cstr(m.state, cs) } case reflect.Array, reflect.Slice: l := v.Len() res := C.mrb_ary_new_capa(m.state, C.mrb_int(l)) for i := 0; i < l; i++ { C.mrb_ary_set(m.state, res, C.mrb_int(i), m.mrubyValue(v.Index(i).Interface())) } return res case reflect.Map: l := v.Len() res := C.mrb_hash_new_capa(m.state, C.int(l)) for _, key := range v.MapKeys() { val := v.MapIndex(key) C.mrb_hash_set(m.state, res, m.mrubyValue(key.Interface()), m.mrubyValue(val.Interface())) } return res } panic(fmt.Errorf("gomruby bug: failed to convert Go value %#v (%T) to mruby value", i, i)) }
func (m *MRuby) Eval(code string, args ...interface{}) interface{} { c := C.CString(code) defer C.free(unsafe.Pointer(c)) x := C.mrbc_context_new(m.mrb) defer C.mrbc_context_free(m.mrb, x) p := C.mrb_parse_string(m.mrb, c, x) n := C.mrb_generate_code(m.mrb, p) C.mrb_pool_close((*C.mrb_pool)(p.pool)) a := C.CString("ARGV") defer C.free(unsafe.Pointer(a)) ARGV := C.mrb_ary_new(m.mrb) for i := 0; i < len(args); i++ { C.mrb_ary_push(m.mrb, ARGV, go2mruby(m.mrb, args[i])) } C.mrb_define_global_const(m.mrb, a, ARGV) return mruby2go(m.mrb, C.mrb_run(m.mrb, n, C.mrb_top_self(m.mrb))) return C.mrb_nil_value() }
func (m *MRuby) Eval(code string, args ...interface{}) interface{} { c := C.CString(code) defer C.free(unsafe.Pointer(c)) p := C.mrb_parse_string(m.mrb, c) n := C.mrb_generate_code(m.mrb, p.tree) C.mrb_pool_close((*C.mrb_pool)(p.pool)) a := C.CString("ARGV") defer C.free(unsafe.Pointer(a)) if n >= 0 { ARGV := C.mrb_ary_new(m.mrb) for i := 0; i < len(args); i++ { C.mrb_ary_push(m.mrb, ARGV, go2mruby(m.mrb, args[i])) } C.mrb_define_global_const(m.mrb, a, ARGV) return mruby2go(m.mrb, C.mrb_run( m.mrb, C.mrb_proc_new(m.mrb, (*C.mrb_irep)(C._get_irep(m.mrb, n))), C.mrb_top_self(m.mrb))) } return C.mrb_nil_value() }
func go2mruby(mrb *C.mrb_state, o interface{}) C.mrb_value { v := reflect.ValueOf(o) switch v.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return C.mrb_fixnum_value(C.mrb_int(v.Int())) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: return C.mrb_fixnum_value(C.mrb_int(v.Uint())) case reflect.Float32, reflect.Float64: return C.mrb_float_value((C.mrb_float)(v.Float())) case reflect.Complex64, reflect.Complex128: return C.mrb_float_value((C.mrb_float)(v.Float())) case reflect.String: ptr := C.CString(v.String()) return C.mrb_str_new(mrb, ptr, C.strlen(ptr)) case reflect.Bool: if v.Bool() { return C.mrb_true_value() } return C.mrb_false_value() case reflect.Array, reflect.Slice: ary := C.mrb_ary_new(mrb) for i := 0; i < v.Len(); i++ { C.mrb_ary_push(mrb, ary, go2mruby(mrb, v.Index(i).Interface())) } return ary case reflect.Map: hash := C.mrb_hash_new(mrb, 32) for _, key := range v.MapKeys() { val := v.MapIndex(key) C.mrb_hash_set(mrb, hash, go2mruby(mrb, key.String()), go2mruby(mrb, val.Interface())) } return hash case reflect.Interface: return go2mruby(mrb, v.Elem().Interface()) } return C.mrb_nil_value() }
// NilValue returns "nil" func (m *Mrb) NilValue() *MrbValue { return newValue(m.state, C.mrb_nil_value()) }