[macruby-changes] [999] MacRuby/branches/experimental

source_changes at macosforge.org source_changes at macosforge.org
Thu Mar 19 17:21:06 PDT 2009


Revision: 999
          http://trac.macosforge.org/projects/ruby/changeset/999
Author:   vincent.isambart at gmail.com
Date:     2009-03-19 17:21:06 -0700 (Thu, 19 Mar 2009)
Log Message:
-----------
added support for opt args and rest for blocks in the VM
however, I realised the MacRuby parser does not support opt args in blocks
(Ruby 1.9 does)

Modified Paths:
--------------
    MacRuby/branches/experimental/roxor.cpp
    MacRuby/branches/experimental/test_roxor.rb

Property Changed:
----------------
    MacRuby/branches/experimental/test_roxor.rb

Modified: MacRuby/branches/experimental/roxor.cpp
===================================================================
--- MacRuby/branches/experimental/roxor.cpp	2009-03-19 23:09:50 UTC (rev 998)
+++ MacRuby/branches/experimental/roxor.cpp	2009-03-20 00:21:06 UTC (rev 999)
@@ -5020,26 +5020,50 @@
 	return Qnil;
     }
     node_arity arity = rb_vm_node_arity(b->node);
-    if (arity.real != argc || b->dvars_size > 0) {
-	VALUE *new_argv = (VALUE *)alloca(sizeof(VALUE) * (arity.real + b->dvars_size));
-	for (int i = 0; i < b->dvars_size; i++) {
-	    new_argv[i] = (VALUE)b->dvars[i];
-	}
-	if (argc == 1 && TYPE(argv[0]) == T_ARRAY && arity.real > 1) {
+    int dvars_size = b->dvars_size;
+
+    if (dvars_size > 0 || argc < arity.min || argc > arity.max) {
+	VALUE *new_argv;
+	if (argc == 1 && TYPE(argv[0]) == T_ARRAY && (arity.max == -1 || arity.max > 1)) {
 	    // Expand the array
 	    long ary_len = RARRAY_LEN(argv[0]);
-	    for (int i = 0; i < arity.real; i++) {
-		new_argv[b->dvars_size + i] = i < ary_len ? RARRAY_AT(argv[0], i) : Qnil;
+	    new_argv = (VALUE *)alloca(sizeof(VALUE) * ary_len);
+	    for (int i = 0; i < ary_len; i++) {
+		new_argv[i] = RARRAY_AT(argv[0], i);
 	    }
+	    argv = new_argv;
+	    argc = ary_len;
+	    if (dvars_size == 0 && argc >= arity.min && (argc <= arity.max || arity.max == -1)) {
+		return __rb_vm_rcall(b->self, b->node, b->imp, arity, argc, argv);
+	    }
 	}
+	int new_argc;
+	if (argc <= arity.min) {
+	    new_argc = dvars_size + arity.min;
+	}
+	else if (argc > arity.max && arity.max != -1) {
+	    new_argc = dvars_size + arity.max;
+	}
 	else {
-	    for (int i = 0; i < arity.real; i++) {
-		new_argv[b->dvars_size + i] = i < argc ? argv[i] : Qnil;
+	    new_argc = dvars_size + argc;
+	}
+	new_argv = (VALUE *)alloca(sizeof(VALUE) * new_argc);
+	for (int i = 0; i < dvars_size; i++) {
+	    new_argv[i] = (VALUE)b->dvars[i];
+	}
+	for (int i = 0; i < new_argc - dvars_size; i++) {
+	    new_argv[dvars_size + i] = i < argc ? argv[i] : Qnil;
+	}
+	argc = new_argc;
+	argv = new_argv;
+	if (dvars_size > 0) {
+	    arity.min += dvars_size;
+	    if (arity.max != -1) {
+		arity.max += dvars_size;
 	    }
+	    arity.real += dvars_size;
+	    arity.left_req += dvars_size;
 	}
-	argc = b->dvars_size + arity.real;
-	argv = new_argv;
-	arity.real = argc;
     }
 #if ROXOR_DEBUG
     printf("yield block %p argc %d arity %d dvars %d\n", b, argc, arity.real, b->dvars_size);

Modified: MacRuby/branches/experimental/test_roxor.rb
===================================================================
--- MacRuby/branches/experimental/test_roxor.rb	2009-03-19 23:09:50 UTC (rev 998)
+++ MacRuby/branches/experimental/test_roxor.rb	2009-03-20 00:21:06 UTC (rev 999)
@@ -1,3 +1,4 @@
+#!/usr/bin/ruby
 # Preliminary test suite for the MacRuby VM.
 # Aimed at testing critical features of the VM.
 #
@@ -7,7 +8,7 @@
 $test_only = []
 test_commands = []
 ARGV.each do |arg|
-  if md = /--ruby=(([^"'].*)|(".+")|('.*'))/.match(arg)
+  if md = /--ruby=(.*)/.match(arg)
     test_commands << md[1]
   else
     $test_only << arg
@@ -732,6 +733,13 @@
     func
     func
   }
+  
+  assert "[1, 2]", %{
+    def f
+      yield 1, 2
+    end
+    f {|*args| p args}
+  }
 
 end
 
@@ -765,6 +773,44 @@
       p :ok if x == 1 and y == 2 and z == nil
     end
   }
+  assert ":ok", %q{
+    def foo; yield(1, 2); end
+    foo do |x| 
+      p :ok if x == 1
+    end
+  }
+  assert ":ok", %q{
+    def foo; yield(1, 2); end
+    foo do |x, y = :y, z|
+      p :ok if x == 1 and y == :y and z == 2
+    end
+  }
+  assert ":ok", %q{
+    def foo; yield(1); end
+    foo do |x, y = :y, z|
+      p :ok if x == 1 and y == :y and z == nil
+    end
+  }
+  assert ":ok", %q{
+    def foo; yield(1, 2, 3, 4); end
+    foo do |x, y = :y, *rest, z|
+      p :ok if x == 1 and y == 2 and rest == [3] and z == 4
+    end
+  }
+  assert ":ok", %q{
+    def foo; yield([1, 2]); end
+    foo do |x, y = :y, z|
+      p :ok if x == 1 and y == :y and z == 2
+    end
+  }
+  assert "[1, 2]", %q{
+    def foo; yield(1, 2); end
+    foo { |*rest| p rest }
+  }
+  assert "[1, 2]", %q{
+    def foo; yield([1, 2]); end
+    foo { |*rest| p rest }
+  }
 
   assert ":ok", "def foo; p :ok if block_given?;     end; foo {}"
   assert ":ok", "def foo; p :ok unless block_given?; end; foo"


Property changes on: MacRuby/branches/experimental/test_roxor.rb
___________________________________________________________________
Added: svn:executable
   + *
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090319/1b06db1b/attachment.html>


More information about the macruby-changes mailing list