* compile.c (iseq_compile_each, set_block_local_tbl) :

support NODE_LAMBDA (partly).
* sample/test.rb : restore test of NODE_LAMBDA
* test/ruby/test_lambda.rb : ditto



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11477 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
ko1 2007-01-05 03:43:12 +00:00
Родитель f189294d04
Коммит c5bd0c8e3b
4 изменённых файлов: 97 добавлений и 52 удалений

Просмотреть файл

@ -1,3 +1,12 @@
Fri Jan 5 12:03:07 2007 Koichi Sasada <ko1@atdot.net>
* compile.c (iseq_compile_each, set_block_local_tbl) :
support NODE_LAMBDA (partly).
* sample/test.rb : restore test of NODE_LAMBDA
* test/ruby/test_lambda.rb : ditto
Fri Jan 5 12:31:23 2007 GOTOU Yuuzou <gotoyuzo@notwork.org>
* thread_pthread.ci (native_sleep): fix tv_nsec overflow.

109
compile.c
Просмотреть файл

@ -964,48 +964,74 @@ set_block_local_tbl(yarv_iseq_t *iseq, NODE * node, LINK_ANCHOR *anchor)
else if (node->nd_var) {
NODE *nargs = node->nd_var;
switch (nd_type(nargs)) {
case NODE_MASGN:{
NODE *massign = nargs;
int i = 0;
if (nargs->nd_head != 0) {
NODE *lhsn = massign->nd_head;
case NODE_MASGN:{
NODE *massign = nargs;
int i = 0;
if (nargs->nd_head != 0) {
NODE *lhsn = massign->nd_head;
while (lhsn) {
if (nd_type(lhsn->nd_head) != NODE_DASGN_CURR) {
/* idx-th param, current level */
set_block_initializer(iseq, lhsn->nd_head,
anchor, iseq->local_size - i);
}
i++;
lhsn = lhsn->nd_next;
}
}
while (lhsn) {
if (nd_type(lhsn->nd_head) != NODE_DASGN_CURR) {
/* idx-th param, current level */
set_block_initializer(iseq, lhsn->nd_head,
anchor, iseq->local_size - i);
}
i++;
lhsn = lhsn->nd_next;
}
}
/* check rest */
if (massign->nd_args != 0 && (long)massign->nd_args != -1) {
iseq->argc++;
iseq->arg_rest = i + 1;
/* check rest */
if (massign->nd_args != 0 && (long)massign->nd_args != -1) {
iseq->argc++;
iseq->arg_rest = i + 1;
if (nd_type(massign->nd_args) != NODE_DASGN_CURR) {
set_block_initializer(iseq, massign->nd_args,
anchor, iseq->local_size - i);
}
}
else if (i == 1) {
iseq->arg_rest = -1;
}
break;
}
if (nd_type(massign->nd_args) != NODE_DASGN_CURR) {
set_block_initializer(iseq, massign->nd_args,
anchor, iseq->local_size - i);
}
}
else if (i == 1) {
iseq->arg_rest = -1;
}
break;
}
case NODE_DASGN_CURR:
case NODE_DASGN_CURR:
break;
/* for 1.x compatibility */
default:{
/* first param, current level */
set_block_initializer(iseq, nargs, anchor, iseq->local_size);
break;
}
case NODE_ARGS:{
/* make parameters */
VALUE a = nargs->nd_frml;
int i;
int argc = a ? RARRAY_LEN(a) : 0;
int local_size = argc + iseq->local_size - 1;
ID *local_tbl = local_size > 0 ? ALLOC_N(ID, local_size) : 0;
for (i=0; i<argc; i++) {
ID id = SYM2ID(RARRAY_PTR(a)[i]);
debugi("NODE_ARGS param", id);
local_tbl[i] = id;
}
if (iseq->local_tbl) {
/* copy from old local tbl and delete it */
for (i=1; i<iseq->local_size; i++) {
local_tbl[argc + i - 1] = iseq->local_tbl[i];
}
ruby_xfree(iseq->local_tbl);
}
iseq->local_tbl = local_tbl;
iseq->local_size = local_size;
iseq->argc = argc;
break;
}
default:{
/* for 1.x compatibility */
/* first param, current level */
set_block_initializer(iseq, nargs, anchor, iseq->local_size);
break;
}
}
}
@ -4480,6 +4506,17 @@ iseq_compile_each(yarv_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
COMPILE_(ret, "body", node->nd_body, poped);
break;
}
case NODE_LAMBDA:{
VALUE block = NEW_CHILD_ISEQVAL(node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK);
VALUE argc = INT2FIX(0);
ADD_INSN (ret, nd_line(node), putself);
ADD_SEND_R(ret, nd_line(node), ID2SYM(idLambda), argc,
block, INT2FIX(VM_CALL_FCALL_BIT));
if (poped) {
ADD_INSN(ret, nd_line(node), pop);
}
break;
}
default:
COMPILE_ERROR(("BUG: unknown node (default): %s", node_name(type)));
return Qnil;

Просмотреть файл

@ -1101,8 +1101,7 @@ def proc_return1
end
test_ok(proc_return1() == 43)
def proc_return2
#! ->{return 42}.call+1
lambda{return 42}.call+1
->{return 42}.call+1
end
test_ok(proc_return2() == 43)
def proc_return3

Просмотреть файл

@ -1,14 +1,6 @@
require 'test/unit'
class TestLambdaParameters < Test::Unit::TestCase
def test_not_supported
flunk("YARV doesn't support NODE_LAMBDA")
end
end
__END__
class TestLambdaParametersBackup
def test_call_simple
assert_equal(1, ->(a){ a }.call(1))
assert_equal([1,2], ->(a,b){ [a,b] }.call(1,2))
@ -18,6 +10,20 @@ class TestLambdaParametersBackup
assert_raises(ArgumentError) { ->(a,b){ }.call(1,2,3) }
end
def test_lambda_as_iterator
a = 0
2.times(&->(_){ a += 1 })
assert_equal(a, 2)
end
def test_message
flunk("YARV doesn't support some argument types for Proc object created by '->' syntax")
end
end
__END__
class TestLambdaParameters
def test_call_rest_args
assert_equal([1,2], ->(*a){ a }.call(1,2))
assert_equal([1,2,[]], ->(a,b,*c){ [a,b,c] }.call(1,2))
@ -52,10 +58,4 @@ class TestLambdaParametersBackup
def foo
assert_equal(nil, ->(&b){ b }.call)
end
def test_lambda_as_iterator
a = 0
2.times(&->(_){ a += 1 })
assert_equal(a, 2)
end
end