mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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:
parent
f189294d04
commit
c5bd0c8e3b
4 changed files with 97 additions and 52 deletions
|
@ -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
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
|
||||
|
|
Loading…
Reference in a new issue