summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--mrblib/kernel.rb8
-rw-r--r--src/class.c149
-rw-r--r--src/kernel.c67
-rw-r--r--test/t/kernel.rb9
4 files changed, 114 insertions, 119 deletions
diff --git a/mrblib/kernel.rb b/mrblib/kernel.rb
index e769741b7..f5099c561 100644
--- a/mrblib/kernel.rb
+++ b/mrblib/kernel.rb
@@ -33,10 +33,10 @@ module Kernel
#end
# 15.3.1.3.18
- def instance_eval(string=nil, &block)
- ### *** TODO *** ###
- raise "Not implemented yet"
- end
+ #def instance_eval(string=nil, &block)
+ # ### *** TODO *** ###
+ # raise "Not implemented yet"
+ #end
##
# Alias for +Kernel.lambda+.
diff --git a/src/class.c b/src/class.c
index b49ce00f8..914785120 100644
--- a/src/class.c
+++ b/src/class.c
@@ -396,8 +396,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
case '|': case '*': case '&':
break;
default:
- if (argc <= i) {
- if (opt) continue;
+ if (argc <= i && !opt) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments");
}
}
@@ -408,8 +407,10 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
mrb_value *p;
p = va_arg(ap, mrb_value*);
- *p = *sp;
- i++; sp++;
+ if (i < argc) {
+ *p = *sp++;
+ i++;
+ }
}
break;
case 'S':
@@ -417,8 +418,10 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
mrb_value *p;
p = va_arg(ap, mrb_value*);
- *p = to_str(mrb, *sp);
- i++; sp++;
+ if (i < argc) {
+ *p = to_str(mrb, *sp++);
+ i++;
+ }
}
break;
case 'A':
@@ -426,8 +429,10 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
mrb_value *p;
p = va_arg(ap, mrb_value*);
- *p = to_ary(mrb, *sp);
- i++; sp++;
+ if (i < argc) {
+ *p = to_ary(mrb, *sp++);
+ i++;
+ }
}
break;
case 'H':
@@ -435,8 +440,10 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
mrb_value *p;
p = va_arg(ap, mrb_value*);
- *p = to_hash(mrb, *sp);
- i++; sp++;
+ if (i < argc) {
+ *p = to_hash(mrb, *sp++);
+ i++;
+ }
}
break;
case 's':
@@ -446,13 +453,15 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
char **ps = 0;
int *pl = 0;
- ss = to_str(mrb, *sp);
- s = mrb_str_ptr(ss);
ps = va_arg(ap, char**);
- *ps = s->ptr;
pl = va_arg(ap, int*);
- *pl = s->len;
- i++; sp++;
+ if (i < argc) {
+ ss = to_str(mrb, *sp++);
+ s = mrb_str_ptr(ss);
+ *ps = s->ptr;
+ *pl = s->len;
+ i++;
+ }
}
break;
case 'z':
@@ -461,14 +470,16 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
struct RString *s;
char **ps;
- ss = to_str(mrb, *sp);
- s = mrb_str_ptr(ss);
- if (strlen(s->ptr) != s->len) {
- mrb_raise(mrb, E_ARGUMENT_ERROR, "String contains NUL");
- }
ps = va_arg(ap, char**);
- *ps = s->ptr;
- i++; sp++;
+ if (i < argc) {
+ ss = to_str(mrb, *sp++);
+ s = mrb_str_ptr(ss);
+ if (strlen(s->ptr) != s->len) {
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "String contains NUL");
+ }
+ *ps = s->ptr;
+ i++;
+ }
}
break;
case 'a':
@@ -478,13 +489,15 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
mrb_value **pb;
int *pl;
- aa = to_ary(mrb, *sp);
- a = mrb_ary_ptr(aa);
pb = va_arg(ap, mrb_value**);
- *pb = a->ptr;
pl = va_arg(ap, int*);
- *pl = a->len;
- i++; sp++;
+ if (i < argc) {
+ aa = to_ary(mrb, *sp++);
+ a = mrb_ary_ptr(aa);
+ *pb = a->ptr;
+ *pl = a->len;
+ i++;
+ }
}
break;
case 'f':
@@ -492,26 +505,29 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
mrb_float *p;
p = va_arg(ap, mrb_float*);
- switch (sp->tt) {
- case MRB_TT_FLOAT:
- *p = mrb_float(*sp);
- break;
- case MRB_TT_FIXNUM:
- *p = (mrb_float)mrb_fixnum(*sp);
- break;
- case MRB_TT_FALSE:
- *p = 0.0;
- break;
- default:
- {
- mrb_value tmp;
-
- tmp = mrb_convert_type(mrb, *sp, MRB_TT_FLOAT, "Float", "to_f");
- *p = mrb_float(tmp);
+ if (i < argc) {
+ switch (sp->tt) {
+ case MRB_TT_FLOAT:
+ *p = mrb_float(*sp);
+ break;
+ case MRB_TT_FIXNUM:
+ *p = (mrb_float)mrb_fixnum(*sp);
+ break;
+ case MRB_TT_FALSE:
+ *p = 0.0;
+ break;
+ default:
+ {
+ mrb_value tmp;
+
+ tmp = mrb_convert_type(mrb, *sp, MRB_TT_FLOAT, "Float", "to_f");
+ *p = mrb_float(tmp);
+ }
+ break;
}
- break;
- }
- i++; sp++;
+ sp++;
+ i++;
+ }
}
break;
case 'i':
@@ -519,26 +535,29 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
mrb_int *p;
p = va_arg(ap, mrb_int*);
- switch (sp->tt) {
- case MRB_TT_FIXNUM:
- *p = mrb_fixnum(*sp);
- break;
- case MRB_TT_FLOAT:
- *p = (mrb_int)mrb_float(*sp);
- break;
- case MRB_TT_FALSE:
- *p = 0;
- break;
- default:
- {
- mrb_value tmp;
-
- tmp = mrb_convert_type(mrb, *sp, MRB_TT_FIXNUM, "Integer", "to_int");
- *p = mrb_fixnum(tmp);
+ if (i < argc) {
+ switch (sp->tt) {
+ case MRB_TT_FIXNUM:
+ *p = mrb_fixnum(*sp);
+ break;
+ case MRB_TT_FLOAT:
+ *p = (mrb_int)mrb_float(*sp);
+ break;
+ case MRB_TT_FALSE:
+ *p = 0;
+ break;
+ default:
+ {
+ mrb_value tmp;
+
+ tmp = mrb_convert_type(mrb, *sp, MRB_TT_FIXNUM, "Integer", "to_int");
+ *p = mrb_fixnum(tmp);
+ }
+ break;
}
- break;
- }
- i++; sp++;
+ sp++;
+ i++;
+ }
}
break;
diff --git a/src/kernel.c b/src/kernel.c
index bc8e0059b..30c1c8a67 100644
--- a/src/kernel.c
+++ b/src/kernel.c
@@ -269,12 +269,6 @@ mrb_f_send(mrb_state *mrb, mrb_value self)
return mrb_funcall_with_block(mrb,self, mrb_string_value_ptr(mrb, name), argc, argv, block);
}
-static mrb_value
-mrb_f_block_given_p(void)
-{
- return mrb_false_value(); /* dummy */
-}
-
/* 15.3.1.2.2 */
/* 15.3.1.2.5 */
/* 15.3.1.3.6 */
@@ -302,7 +296,18 @@ mrb_f_block_given_p(void)
static mrb_value
mrb_f_block_given_p_m(mrb_state *mrb, mrb_value self)
{
- return mrb_f_block_given_p();
+ mrb_callinfo *ci = mrb->ci;
+ mrb_value *bp, *p;
+
+ p = mrb->stbase + ci->stackidx;
+ bp = mrb->stbase + ci->stackidx + 1;
+ ci--;
+ if (ci <= mrb->cibase) return mrb_false_value();
+ if (ci->argc > 0) {
+ bp += ci->argc;
+ }
+ if (mrb_nil_p(*bp)) return mrb_false_value();
+ return mrb_true_value();
}
/* 15.3.1.3.7 */
@@ -466,40 +471,6 @@ mrb_obj_dup(mrb_state *mrb, mrb_value obj)
return dup;
}
-/* 15.3.1.2.3 */
-/* 15.3.1.3.12 */
-/*
- * call-seq:
- * eval(string [, binding [, filename [,lineno]]]) -> obj
- *
- * Evaluates the Ruby expression(s) in <em>string</em>. If
- * <em>binding</em> is given, which must be a <code>Binding</code>
- * object, the evaluation is performed in its context. If the
- * optional <em>filename</em> and <em>lineno</em> parameters are
- * present, they will be used when reporting syntax errors.
- *
- * def getBinding(str)
- * return binding
- * end
- * str = "hello"
- * eval "str + ' Fred'" #=> "hello Fred"
- * eval "str + ' Fred'", getBinding("bye") #=> "bye Fred"
- */
-mrb_value
-mrb_f_eval(int argc, mrb_value *argv, mrb_value self)
-{
- return mrb_false_value(); /* dummy */
-}
-mrb_value
-mrb_f_eval_m(mrb_state *mrb, mrb_value self)
-{
- mrb_value *argv;
- int argc;
-
- mrb_get_args(mrb, "*", &argv, &argc);
- return mrb_f_eval(argc, argv, self);
-}
-
static mrb_value
mrb_obj_extend(mrb_state *mrb, int argc, mrb_value *argv, mrb_value obj)
{
@@ -591,12 +562,10 @@ mrb_obj_init_copy(mrb_state *mrb, mrb_value self)
/* 15.3.1.3.18 */
/*
* call-seq:
- * obj.instance_eval(string [, filename [, lineno]] ) -> obj
* obj.instance_eval {| | block } -> obj
*
- * Evaluates a string containing Ruby source code, or the given block,
- * within the context of the receiver (_obj_). In order to set the
- * context, the variable +self+ is set to _obj_ while
+ * Evaluates the given block,within the context of the receiver (_obj_).
+ * In order to set the context, the variable +self+ is set to _obj_ while
* the code is executing, giving the code access to _obj_'s
* instance variables. In the version of <code>instance_eval</code>
* that takes a +String+, the optional second and third
@@ -614,9 +583,11 @@ mrb_obj_init_copy(mrb_state *mrb, mrb_value self)
mrb_value
mrb_obj_instance_eval(mrb_state *mrb, mrb_value self)
{
- mrb_value b;
+ mrb_value a, b;
- mrb_get_args(mrb, "&", &b);
+ if (mrb_get_args(mrb, "|S&", &a, &b) == 1) {
+ mrb_raise(mrb, mrb->eRuntimeError_class, "instance_eval with string not implemented");
+ }
return mrb_yield_with_self(mrb, b, 0, 0, self);
}
@@ -1370,7 +1341,6 @@ mrb_init_kernel(mrb_state *mrb)
krn = mrb->kernel_module = mrb_define_module(mrb, "Kernel");
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, "eval", mrb_f_eval_m, ARGS_ANY()); /* 15.3.1.2.3 */
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 */
@@ -1393,7 +1363,6 @@ mrb_init_kernel(mrb_state *mrb)
mrb_define_method(mrb, krn, "dup", mrb_obj_dup, ARGS_NONE()); /* 15.3.1.3.9 */
mrb_define_method(mrb, krn, "eql?", mrb_obj_equal_m, ARGS_REQ(1)); /* 15.3.1.3.10 */
mrb_define_method(mrb, krn, "equal?", mrb_obj_equal_m, ARGS_REQ(1)); /* 15.3.1.3.11 */
- mrb_define_method(mrb, krn, "eval", mrb_f_eval_m, ARGS_ANY()); /* 15.3.1.3.12 */
mrb_define_method(mrb, krn, "extend", mrb_obj_extend_m, ARGS_ANY()); /* 15.3.1.3.13 */
mrb_define_method(mrb, krn, "global_variables", mrb_f_global_variables, ARGS_NONE()); /* 15.3.1.3.14 */
mrb_define_method(mrb, krn, "hash", mrb_obj_hash, ARGS_NONE()); /* 15.3.1.3.15 */
diff --git a/test/t/kernel.rb b/test/t/kernel.rb
index 847f1baeb..5e25d6516 100644
--- a/test/t/kernel.rb
+++ b/test/t/kernel.rb
@@ -6,7 +6,14 @@ assert('Kernel', '15.3.1') do
end
assert('Kernel.block_given?', '15.3.1.2.2') do
- Kernel.block_given? == false
+ def bg_try(&b)
+ if block_given?
+ yield
+ else
+ "no block"
+ end
+ end
+ (Kernel.block_given? == false) && (bg_try == "no block") && ((bg_try { "block" }) == "block") && ((bg_try do "block" end) == "block")
end
assert('Kernel.global_variables', '15.3.1.2.4') do