diff options
author | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-01-05 03:43:12 +0000 |
---|---|---|
committer | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-01-05 03:43:12 +0000 |
commit | c5bd0c8e3bf602e082cfd8f95bc28b06aeea2694 (patch) | |
tree | ce1445fe22ddf1412a7e89f9664f107fa65560b5 /compile.c | |
parent | f189294d04ba8c05a03964c622327369c0773829 (diff) | |
download | ruby-c5bd0c8e3bf602e082cfd8f95bc28b06aeea2694.tar.gz |
* 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
Diffstat (limited to 'compile.c')
-rw-r--r-- | compile.c | 111 |
1 files changed, 74 insertions, 37 deletions
@@ -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; - - 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; - } - } + 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; + } + } - /* 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; |