summaryrefslogtreecommitdiff
path: root/compile.c
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2007-01-05 03:43:12 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2007-01-05 03:43:12 +0000
commitc5bd0c8e3bf602e082cfd8f95bc28b06aeea2694 (patch)
treece1445fe22ddf1412a7e89f9664f107fa65560b5 /compile.c
parentf189294d04ba8c05a03964c622327369c0773829 (diff)
* 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.c111
1 files changed, 74 insertions, 37 deletions
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;
-
- 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;