summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/mruby.h2
-rw-r--r--mrblib/class.rb24
-rw-r--r--mrblib/kernel.rb28
-rw-r--r--mrblib/print.rb4
-rw-r--r--src/class.c16
-rw-r--r--src/error.c8
-rw-r--r--src/gc.c2
-rw-r--r--src/kernel.c25
-rw-r--r--src/proc.c63
-rw-r--r--src/re.c2
-rw-r--r--src/string.c2
-rw-r--r--src/vm.c6
12 files changed, 120 insertions, 62 deletions
diff --git a/include/mruby.h b/include/mruby.h
index ef742cef4..aadd56e94 100644
--- a/include/mruby.h
+++ b/include/mruby.h
@@ -279,7 +279,6 @@ typedef struct mrb_state {
struct RClass *eException_class;
struct RClass *eStandardError_class;
- struct RClass *eRuntimeError_class;
void *ud; /* auxiliary data */
} mrb_state;
@@ -430,6 +429,7 @@ void rb_raise(struct RClass *c, const char *fmt, ...);
void mrb_warn(const char *fmt, ...);
void mrb_bug(const char *fmt, ...);
+#define E_RUNTIME_ERROR (mrb_class_obj_get(mrb, "RuntimeError"))
#define E_TYPE_ERROR (mrb_class_obj_get(mrb, "TypeError"))
#define E_ARGUMENT_ERROR (mrb_class_obj_get(mrb, "ArgumentError"))
#define E_INDEX_ERROR (mrb_class_obj_get(mrb, "IndexError"))
diff --git a/mrblib/class.rb b/mrblib/class.rb
new file mode 100644
index 000000000..9c3ef91fd
--- /dev/null
+++ b/mrblib/class.rb
@@ -0,0 +1,24 @@
+class Module
+ # 15.2.2.4.13
+ def attr_reader(*names)
+ names.each{|name|
+ define_method(name){self.instance_variable_get(name)}
+ }
+ end
+ # 15.2.2.4.14
+ def attr_writer(*names)
+ names.each{|name|
+ aset = (name.to_s+"=").intern
+ define_method(aset){|v|self.instance_variable_set(name,v)}
+ }
+ end
+ # 15.2.2.4.12
+ def attr_accessor(*names)
+ attr_reader(*names)
+ attr_writer(*names)
+ end
+ # 15.2.2.4.11
+ def attr(name)
+ attr_reader(name)
+ end
+end
diff --git a/mrblib/kernel.rb b/mrblib/kernel.rb
index c263ec403..ad3bc72f7 100644
--- a/mrblib/kernel.rb
+++ b/mrblib/kernel.rb
@@ -3,17 +3,6 @@
#
# ISO 15.3.1
module Kernel
-
- ##
- # Takes the given block, create a lambda
- # out of it and +call+ it.
- #
- # ISO 15.3.1.2.6
- def self.lambda(&block)
- ### *** TODO *** ###
- block # dummy
- end
-
##
# Calls the given block repetitively.
#
@@ -29,29 +18,12 @@ module Kernel
raise NotImplementedError.new("eval not implemented")
end
- ##
- # Alias for +send+.
- #
- # ISO 15.3.1.3.4
- #def __send__(symbol, *args, &block)
- ### *** TODO *** ###
- #end
-
# 15.3.1.3.12
def eval(s)
Kernel.eval(s)
end
##
- # Alias for +Kernel.lambda+.
- #
- # ISO 15.3.1.3.27
- def lambda(&block)
- ### *** TODO *** ###
- block # dummy
- end
-
- ##
# Alias for +Kernel.loop+.
#
# ISO 15.3.1.3.29
diff --git a/mrblib/print.rb b/mrblib/print.rb
index 0d33c66d2..452ba53a9 100644
--- a/mrblib/print.rb
+++ b/mrblib/print.rb
@@ -47,4 +47,8 @@ module Kernel
end
args[0]
end
+
+ def printf(*args)
+ __printstr__(sprintf(*args))
+ end
end
diff --git a/src/class.c b/src/class.c
index 434ecb037..72fef70aa 100644
--- a/src/class.c
+++ b/src/class.c
@@ -1206,6 +1206,21 @@ mrb_mod_undef(mrb_state *mrb, mrb_value mod)
return mrb_nil_value();
}
+static mrb_value
+mod_define_method(mrb_state *mrb, mrb_value self)
+{
+ struct RClass *c = mrb_class_ptr(self);
+ mrb_sym mid;
+ mrb_value blk;
+
+ mrb_get_args(mrb, "n&", &mid, &blk);
+ if (mrb_nil_p(blk)) {
+ /* raise */
+ }
+ mrb_define_method_raw(mrb, c, mid, mrb_proc_ptr(blk));
+ return blk;
+}
+
static mrb_sym
mrb_sym_value(mrb_state *mrb, mrb_value val)
{
@@ -1310,6 +1325,7 @@ mrb_init_class(mrb_state *mrb)
mrb_define_method(mrb, mod, "const_defined?", mrb_mod_const_defined, ARGS_REQ(1)); /* 15.2.2.4.20 */
mrb_define_method(mrb, mod, "const_get", mrb_mod_const_get, ARGS_REQ(1)); /* 15.2.2.4.21 */
mrb_define_method(mrb, mod, "const_set", mrb_mod_const_set, ARGS_REQ(2)); /* 15.2.2.4.23 */
+ mrb_define_method(mrb, mod, "define_method", mod_define_method, ARGS_REQ(1));
mrb_define_method(mrb, mod, "===", mrb_mod_eqq, ARGS_REQ(1));
}
diff --git a/src/error.c b/src/error.c
index b2d9a8c8d..1183d8643 100644
--- a/src/error.c
+++ b/src/error.c
@@ -301,7 +301,7 @@ make_exception(mrb_state *mrb, int argc, mrb_value *argv, int isstr)
if (isstr) {
mesg = mrb_check_string_type(mrb, argv[0]);
if (!mrb_nil_p(mesg)) {
- mesg = mrb_exc_new3(mrb, mrb->eRuntimeError_class, mesg);
+ mesg = mrb_exc_new3(mrb, E_RUNTIME_ERROR, mesg);
break;
}
}
@@ -352,7 +352,7 @@ mrb_make_exception(mrb_state *mrb, int argc, mrb_value *argv)
void
mrb_sys_fail(mrb_state *mrb, const char *mesg)
{
- mrb_raise(mrb, mrb->eRuntimeError_class, "%s", mesg);
+ mrb_raise(mrb, E_RUNTIME_ERROR, "%s", mesg);
}
void
@@ -369,6 +369,6 @@ mrb_init_exception(mrb_state *mrb)
mrb_define_method(mrb, e, "message", exc_message, ARGS_NONE());
mrb_define_method(mrb, e, "inspect", exc_inspect, ARGS_NONE());
- mrb->eStandardError_class = mrb_define_class(mrb, "StandardError", mrb->eException_class); /* 15.2.23 */
- mrb->eRuntimeError_class = mrb_define_class(mrb, "RuntimeError", mrb->eStandardError_class); /* 15.2.28 */
+ mrb->eStandardError_class = mrb_define_class(mrb, "StandardError", mrb->eException_class); /* 15.2.23 */
+ mrb_define_class(mrb, "RuntimeError", mrb->eStandardError_class); /* 15.2.28 */
}
diff --git a/src/gc.c b/src/gc.c
index c07c9b13b..a7537a015 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -277,7 +277,7 @@ gc_protect(mrb_state *mrb, struct RBasic *p)
if (mrb->arena_idx > MRB_ARENA_SIZE) {
/* arena overflow error */
mrb->arena_idx = MRB_ARENA_SIZE - 4; /* force room in arena */
- mrb_raise(mrb, mrb->eRuntimeError_class, "arena overflow error");
+ mrb_raise(mrb, E_RUNTIME_ERROR, "arena overflow error");
}
mrb->arena[mrb->arena_idx++] = p;
}
diff --git a/src/kernel.c b/src/kernel.c
index 75c588a81..a9f4792d7 100644
--- a/src/kernel.c
+++ b/src/kernel.c
@@ -570,7 +570,7 @@ mrb_obj_instance_eval(mrb_state *mrb, mrb_value self)
mrb_value a, b;
if (mrb_get_args(mrb, "|S&", &a, &b) == 1) {
- mrb_raise(mrb, mrb->eRuntimeError_class, "instance_eval with string not implemented");
+ mrb_raise(mrb, E_RUNTIME_ERROR, "instance_eval with string not implemented");
}
return mrb_yield_with_self(mrb, b, 0, 0, self);
}
@@ -791,22 +791,6 @@ mrb_obj_is_kind_of_m(mrb_state *mrb, mrb_value self)
}
}
-/* 15.3.1.2.6 */
-/* 15.3.1.3.27 */
-/*
- * call-seq:
- * lambda { |...| block } -> a_proc
- *
- * Equivalent to <code>Proc.new</code>, except the resulting Proc objects
- * check the number of parameters passed when called.
- */
-mrb_value
-proc_lambda(mrb_state *mrb, mrb_value self)
-{
- //return mrb_block_lambda();
- return mrb_nil_value(); /* dummy */
-}
-
static void
method_entry_loop(mrb_state *mrb, struct RClass* klass, mrb_value ary)
{
@@ -1032,13 +1016,13 @@ mrb_f_raise(mrb_state *mrb, mrb_value self)
argc = mrb_get_args(mrb, "|oo", &a[0], &a[1]);
switch (argc) {
case 0:
- mrb_raise(mrb, mrb->eRuntimeError_class, "");
+ mrb_raise(mrb, E_RUNTIME_ERROR, "");
break;
case 1:
a[1] = mrb_check_string_type(mrb, a[0]);
if (!mrb_nil_p(a[1])) {
argc = 2;
- a[0] = mrb_obj_value(mrb->eRuntimeError_class);
+ a[0] = mrb_obj_value(E_RUNTIME_ERROR);
}
/* fall through */
default:
@@ -1202,7 +1186,6 @@ mrb_init_kernel(mrb_state *mrb)
mrb_define_class_method(mrb, krn, "block_given?", mrb_f_block_given_p_m, ARGS_NONE()); /* 15.3.1.2.2 */
mrb_define_class_method(mrb, krn, "global_variables", mrb_f_global_variables, ARGS_NONE()); /* 15.3.1.2.4 */
mrb_define_class_method(mrb, krn, "iterator?", mrb_f_block_given_p_m, ARGS_NONE()); /* 15.3.1.2.5 */
- mrb_define_class_method(mrb, krn, "lambda", proc_lambda, ARGS_NONE()); /* 15.3.1.2.6 */
; /* 15.3.1.2.11 */
mrb_define_class_method(mrb, krn, "raise", mrb_f_raise, ARGS_ANY()); /* 15.3.1.2.12 */
@@ -1233,7 +1216,6 @@ mrb_init_kernel(mrb_state *mrb)
mrb_define_method(mrb, krn, "is_a?", mrb_obj_is_kind_of_m, ARGS_REQ(1)); /* 15.3.1.3.24 */
mrb_define_method(mrb, krn, "iterator?", mrb_f_block_given_p_m, ARGS_NONE()); /* 15.3.1.3.25 */
mrb_define_method(mrb, krn, "kind_of?", mrb_obj_is_kind_of_m, ARGS_REQ(1)); /* 15.3.1.3.26 */
- mrb_define_method(mrb, krn, "lambda", proc_lambda, ARGS_NONE()); /* 15.3.1.3.27 */
mrb_define_method(mrb, krn, "methods", mrb_obj_methods_m, ARGS_ANY()); /* 15.3.1.3.31 */
mrb_define_method(mrb, krn, "nil?", mrb_false, ARGS_NONE()); /* 15.3.1.3.32 */
mrb_define_method(mrb, krn, "object_id", mrb_obj_id_m, ARGS_NONE()); /* 15.3.1.3.33 */
@@ -1244,6 +1226,7 @@ mrb_init_kernel(mrb_state *mrb)
mrb_define_method(mrb, krn, "remove_instance_variable", mrb_obj_remove_instance_variable,ARGS_REQ(1)); /* 15.3.1.3.41 */
mrb_define_method(mrb, krn, "respond_to?", obj_respond_to, ARGS_ANY()); /* 15.3.1.3.43 */
mrb_define_method(mrb, krn, "send", mrb_f_send, ARGS_ANY()); /* 15.3.1.3.44 */
+ mrb_define_method(mrb, krn, "__send__", mrb_f_send, ARGS_ANY()); /* 15.3.1.3.4 */
mrb_define_method(mrb, krn, "singleton_methods", mrb_obj_singleton_methods_m, ARGS_ANY()); /* 15.3.1.3.45 */
mrb_define_method(mrb, krn, "to_s", mrb_any_to_s, ARGS_NONE()); /* 15.3.1.3.46 */
diff --git a/src/proc.c b/src/proc.c
index 21c462493..98f753ac6 100644
--- a/src/proc.c
+++ b/src/proc.c
@@ -56,20 +56,41 @@ mrb_proc_new_cfunc(mrb_state *mrb, mrb_func_t func)
return p;
}
+static inline void
+proc_copy(struct RProc *a, struct RProc *b)
+{
+ a->flags = b->flags;
+ a->body = b->body;
+ a->target_class = b->target_class;
+ a->env = b->env;
+}
+
static mrb_value
mrb_proc_initialize(mrb_state *mrb, mrb_value self)
{
mrb_value blk;
mrb_get_args(mrb, "&", &blk);
- if (!mrb_nil_p(blk)) {
- *mrb_proc_ptr(self) = *mrb_proc_ptr(blk);
- }
- else {
+ if (mrb_nil_p(blk)) {
/* Calling Proc.new without a block is not implemented yet */
mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Proc object without a block");
}
+ else {
+ proc_copy(mrb_proc_ptr(self), mrb_proc_ptr(blk));
+ }
+ return self;
+}
+static mrb_value
+mrb_proc_init_copy(mrb_state *mrb, mrb_value self)
+{
+ mrb_value proc;
+
+ mrb_get_args(mrb, "o", &proc);
+ if (mrb_type(proc) != MRB_TT_PROC) {
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "not a proc");
+ }
+ proc_copy(mrb_proc_ptr(self), mrb_proc_ptr(proc));
return self;
}
@@ -91,6 +112,35 @@ mrb_proc_iseq(mrb_state *mrb, struct RProc *p)
return p->body.irep->iseq;
}
+/* 15.3.1.2.6 */
+/* 15.3.1.3.27 */
+/*
+ * call-seq:
+ * lambda { |...| block } -> a_proc
+ *
+ * Equivalent to <code>Proc.new</code>, except the resulting Proc objects
+ * check the number of parameters passed when called.
+ */
+static mrb_value
+proc_lambda(mrb_state *mrb, mrb_value self)
+{
+ mrb_value blk;
+ struct RProc *p;
+
+ mrb_get_args(mrb, "&", &blk);
+ if (mrb_nil_p(blk)) {
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Proc object without a block");
+ }
+ p = mrb_proc_ptr(blk);
+ if (!MRB_PROC_STRICT_P(p)) {
+ struct RProc *p2 = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, p->c);
+ proc_copy(p2, p);
+ p2->flags |= MRB_PROC_STRICT;
+ return mrb_obj_value(p2);
+ }
+ return self;
+}
+
void
mrb_init_proc(mrb_state *mrb)
{
@@ -108,10 +158,15 @@ mrb_init_proc(mrb_state *mrb)
call_irep->ilen = 1;
mrb->proc_class = mrb_define_class(mrb, "Proc", mrb->object_class);
+ MRB_SET_INSTANCE_TT(mrb->proc_class, MRB_TT_PROC);
mrb_define_method(mrb, mrb->proc_class, "initialize", mrb_proc_initialize, ARGS_NONE());
+ mrb_define_method(mrb, mrb->proc_class, "initialize_copy", mrb_proc_init_copy, ARGS_REQ(1));
m = mrb_proc_new(mrb, call_irep);
mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern(mrb, "call"), m);
mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern(mrb, "[]"), m);
+
+ mrb_define_class_method(mrb, mrb->kernel_module, "lambda", proc_lambda, ARGS_NONE()); /* 15.3.1.2.6 */
+ mrb_define_method(mrb, mrb->kernel_module, "lambda", proc_lambda, ARGS_NONE()); /* 15.3.1.3.27 */
}
diff --git a/src/re.c b/src/re.c
index 70e7c59b6..b821d2e71 100644
--- a/src/re.c
+++ b/src/re.c
@@ -2143,7 +2143,7 @@ mrb_reg_regsub(mrb_state *mrb, mrb_value str, mrb_value src, struct re_registers
break;
}
else {
- mrb_raise(mrb, mrb->eRuntimeError_class, "invalid group name reference format");
+ mrb_raise(mrb, E_RUNTIME_ERROR, "invalid group name reference format");
}
}
diff --git a/src/string.c b/src/string.c
index 6392b504c..585edf8a3 100644
--- a/src/string.c
+++ b/src/string.c
@@ -100,7 +100,7 @@ str_mod_check(mrb_state *mrb, mrb_value str, char *p, mrb_int len)
struct RString *s = mrb_str_ptr(str);
if (s->ptr != p || s->len != len) {
- mrb_raise(mrb, mrb->eRuntimeError_class, "string modified");
+ mrb_raise(mrb, E_RUNTIME_ERROR, "string modified");
}
}
diff --git a/src/vm.c b/src/vm.c
index 826cdafef..f3e5a497a 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -788,6 +788,10 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
/* setup environment for calling method */
proc = m;
irep = m->body.irep;
+ if (!irep) {
+ mrb->stack[0] = mrb_nil_value();
+ goto L_RETURN;
+ }
pool = irep->pool;
syms = irep->syms;
ci->nregs = irep->nregs;
@@ -1600,7 +1604,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
CASE(OP_ERR) {
/* Bx raise RuntimeError with message Lit(Bx) */
mrb_value msg = pool[GETARG_Bx(i)];
- mrb_value exc = mrb_exc_new3(mrb, mrb->eRuntimeError_class, msg);
+ mrb_value exc = mrb_exc_new3(mrb, E_RUNTIME_ERROR, msg);
mrb->exc = (struct RObject*)mrb_object(exc);
goto L_RAISE;