ISO conforming lambda

This commit is contained in:
Yukihiro Matsumoto
2012-06-20 15:41:22 +09:00
parent e9231bca7a
commit b11d4647e9
3 changed files with 33 additions and 38 deletions
+33
View File
@@ -59,6 +59,7 @@ mrb_proc_new_cfunc(mrb_state *mrb, mrb_func_t func)
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;
@@ -111,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)
{
@@ -136,4 +166,7 @@ mrb_init_proc(mrb_state *mrb)
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 */
}