[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