summaryrefslogtreecommitdiffhomepage
path: root/src/proc.c
diff options
context:
space:
mode:
authorYukihiro Matsumoto <[email protected]>2012-06-20 15:41:22 +0900
committerYukihiro Matsumoto <[email protected]>2012-06-20 15:41:22 +0900
commitb11d4647e91bdcd6dfaecfaccdc4c350b1bc413f (patch)
treec1955f7b36ca4083ad50952021db71b12a712dfa /src/proc.c
parente9231bca7a5fafa67e0a15aa657e727e46a1363a (diff)
downloadmruby-b11d4647e91bdcd6dfaecfaccdc4c350b1bc413f.tar.gz
mruby-b11d4647e91bdcd6dfaecfaccdc4c350b1bc413f.zip
ISO conforming lambda
Diffstat (limited to 'src/proc.c')
-rw-r--r--src/proc.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/src/proc.c b/src/proc.c
index c64bb88ac..98f753ac6 100644
--- a/src/proc.c
+++ b/src/proc.c
@@ -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 */
}