diff options
| -rw-r--r-- | include/mruby/numeric.h | 2 | ||||
| -rw-r--r-- | mrbgems/mruby-eval/src/eval.c | 31 | ||||
| -rw-r--r-- | mrbgems/mruby-eval/test/eval.rb | 8 | ||||
| -rw-r--r-- | src/numeric.c | 7 |
4 files changed, 44 insertions, 4 deletions
diff --git a/include/mruby/numeric.h b/include/mruby/numeric.h index 52e335ade..e09a797ed 100644 --- a/include/mruby/numeric.h +++ b/include/mruby/numeric.h @@ -166,7 +166,7 @@ MRB_API mrb_float mrb_as_float(mrb_state *mrb, mrb_value x); /* internal functions */ mrb_float mrb_div_float(mrb_float x, mrb_float y); -mrb_value mrb_float_to_str(mrb_state *mrb, mrb_value x); +mrb_value mrb_float_to_str(mrb_state *mrb, mrb_value x, const char *fmt); int mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, char sign); /* obsolete functions; will be removed */ diff --git a/mrbgems/mruby-eval/src/eval.c b/mrbgems/mruby-eval/src/eval.c index 508f5ffcb..dc0017e1c 100644 --- a/mrbgems/mruby-eval/src/eval.c +++ b/mrbgems/mruby-eval/src/eval.c @@ -11,6 +11,7 @@ struct REnv *mrb_env_new(mrb_state *mrb, struct mrb_context *c, mrb_callinfo *ci, int nstacks, mrb_value *stack, struct RClass *tc); mrb_value mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p, mrb_func_t posthook); mrb_value mrb_obj_instance_eval(mrb_state *mrb, mrb_value self); +mrb_value mrb_mod_module_eval(mrb_state*, mrb_value); void mrb_codedump_all(mrb_state*, struct RProc*); void mrb_proc_merge_lvar(mrb_state *mrb, mrb_irep *irep, struct REnv *env, int num, const mrb_sym *lv, const mrb_value *stack); @@ -221,11 +222,41 @@ f_instance_eval(mrb_state *mrb, mrb_value self) } } +static mrb_value +f_class_eval(mrb_state *mrb, mrb_value self) +{ + mrb_value b; + mrb_int argc; const mrb_value *argv; + + mrb_get_args(mrb, "*!&", &argv, &argc, &b); + + if (mrb_nil_p(b)) { + const char *s; + mrb_int len; + const char *file = NULL; + mrb_int line = 1; + struct RProc *proc; + + mrb_get_args(mrb, "s|zi", &s, &len, &file, &line); + proc = create_proc_from_string(mrb, s, len, mrb_nil_value(), file, line); + MRB_PROC_SET_TARGET_CLASS(proc, mrb_class_ptr(self)); + mrb_assert(!MRB_PROC_CFUNC_P(proc)); + mrb_vm_ci_target_class_set(mrb->c->ci, mrb_class_ptr(self)); + return exec_irep(mrb, self, proc, NULL); + } + else { + mrb_get_args(mrb, "&", &b); + return mrb_mod_module_eval(mrb, self); + } +} + void mrb_mruby_eval_gem_init(mrb_state* mrb) { mrb_define_module_function(mrb, mrb->kernel_module, "eval", f_eval, MRB_ARGS_ARG(1, 3)); mrb_define_method_id(mrb, mrb_class_get_id(mrb, MRB_SYM(BasicObject)), MRB_SYM(instance_eval), f_instance_eval, MRB_ARGS_OPT(3)|MRB_ARGS_BLOCK()); + mrb_define_method_id(mrb, mrb_class_get_id(mrb, MRB_SYM(Module)), MRB_SYM(module_eval), f_class_eval, MRB_ARGS_OPT(3)|MRB_ARGS_BLOCK()); + mrb_define_method_id(mrb, mrb_class_get_id(mrb, MRB_SYM(Module)), MRB_SYM(class_eval), f_class_eval, MRB_ARGS_OPT(3)|MRB_ARGS_BLOCK()); } void diff --git a/mrbgems/mruby-eval/test/eval.rb b/mrbgems/mruby-eval/test/eval.rb index e95171223..524b0b959 100644 --- a/mrbgems/mruby-eval/test/eval.rb +++ b/mrbgems/mruby-eval/test/eval.rb @@ -151,3 +151,11 @@ assert('Access numbered parameter from eval') do hoge.fuga(3) { _1 + eval("_1") } } end + +assert('Module#class_eval with string') do + c = Class.new + c.class_eval "def foo() 42; end" + cc = c.new + assert_true cc.respond_to?(:foo) + assert_equal 42, c.new.foo +end diff --git a/src/numeric.c b/src/numeric.c index a38301caa..b377ce0e6 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -277,8 +277,9 @@ flo_div(mrb_state *mrb, mrb_value x) return mrb_float_value(mrb, a); } -MRB_API mrb_value -mrb_float_to_str(mrb_state *mrb, mrb_value flo) +/* the argument `fmt` is no longer used; you can pass `NULL` */ +mrb_value +mrb_float_to_str(mrb_state *mrb, mrb_value flo, const char *fmt) { char buf[25]; #ifdef MRB_USE_FLOAT32 @@ -330,7 +331,7 @@ flo_to_s(mrb_state *mrb, mrb_value flt) str = mrb_str_new_lit(mrb, "NaN"); } else { - str = mrb_float_to_str(mrb, flt); + str = mrb_float_to_str(mrb, flt, NULL); } RSTR_SET_ASCII_FLAG(mrb_str_ptr(str)); |
