Permalink
Browse files

ISO conforming lambda

  • Loading branch information...
1 parent e9231bc commit b11d4647e91bdcd6dfaecfaccdc4c350b1bc413f @matz matz committed Jun 20, 2012
Showing with 33 additions and 38 deletions.
  1. +0 −20 mrblib/kernel.rb
  2. +0 −18 src/kernel.c
  3. +33 −0 src/proc.c
View
@@ -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.
#
@@ -43,15 +32,6 @@ def 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
View
@@ -794,22 +794,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)
{
@@ -1205,7 +1189,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 */
@@ -1236,7 +1219,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 */
View
@@ -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 */
}

0 comments on commit b11d464

Please sign in to comment.