diff --git a/ChangeLog b/ChangeLog index 348826991a..c1c74ec2c0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +Fri Jan 5 12:03:07 2007 Koichi Sasada + + * 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 * thread_pthread.ci (native_sleep): fix tv_nsec overflow. diff --git a/compile.c b/compile.c index 025e655457..131eb7f8e6 100644 --- a/compile.c +++ b/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; ilocal_tbl) { + /* copy from old local tbl and delete it */ + for (i=1; ilocal_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; diff --git a/sample/test.rb b/sample/test.rb index 0968fa5015..cf2e3a2493 100644 --- a/sample/test.rb +++ b/sample/test.rb @@ -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 diff --git a/test/ruby/test_lambda.rb b/test/ruby/test_lambda.rb index 5687722c31..b4f0dac658 100644 --- a/test/ruby/test_lambda.rb +++ b/test/ruby/test_lambda.rb @@ -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