mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* compile.c: support multiple splat (e.g, [a, *b, *c, e, *f]).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12225 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
a379112975
commit
9d89855052
3 changed files with 65 additions and 54 deletions
|
@ -1,3 +1,7 @@
|
||||||
|
Fri Apr 27 01:51:50 2007 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
|
* compile.c: support multiple splat (e.g, [a, *b, *c, e, *f]).
|
||||||
|
|
||||||
Fri Apr 27 00:03:48 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Fri Apr 27 00:03:48 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* bignum.c (rb_big_pow): truncate all zero BDIGITs. [ruby-dev:30733]
|
* bignum.c (rb_big_pow): truncate all zero BDIGITs. [ruby-dev:30733]
|
||||||
|
|
109
compile.c
109
compile.c
|
@ -1760,6 +1760,11 @@ compile_array(rb_iseq_t *iseq,
|
||||||
DECL_ANCHOR(anchor);
|
DECL_ANCHOR(anchor);
|
||||||
|
|
||||||
while (node) {
|
while (node) {
|
||||||
|
if (nd_type(node) != NODE_ARRAY) {
|
||||||
|
rb_bug("compile_array: This node is not NODE_ARRAY, but %s",
|
||||||
|
ruby_node_name(nd_type(node)));
|
||||||
|
}
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
if (opt_p && nd_type(node->nd_head) != NODE_LIT) {
|
if (opt_p && nd_type(node->nd_head) != NODE_LIT) {
|
||||||
opt_p = Qfalse;
|
opt_p = Qfalse;
|
||||||
|
@ -1945,38 +1950,11 @@ compile_massign(rb_iseq_t *iseq, LINK_ANCHOR *ret,
|
||||||
INT2FIX(lhs_splat));
|
INT2FIX(lhs_splat));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_ARGSCAT:{
|
case NODE_ARGSCAT:
|
||||||
NODE *ary = rhsn->nd_head;
|
COMPILE(ret, "rhs to argscat", rhsn);
|
||||||
int idx = 0;
|
ADD_INSN2(ret, nd_line(rhsn), expandarray,
|
||||||
|
INT2FIX(llen), INT2FIX(lhs_splat));
|
||||||
while (ary) {
|
break;
|
||||||
if (idx < llen || lhs_splat) {
|
|
||||||
COMPILE(ret, "rhs aggscat each head",
|
|
||||||
ary->nd_head);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
COMPILE_POPED(ret,
|
|
||||||
"rhs aggscat each head (popped)",
|
|
||||||
ary->nd_head);
|
|
||||||
}
|
|
||||||
ary = ary->nd_next;
|
|
||||||
idx++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (llen > idx) {
|
|
||||||
COMPILE(ret, "rhs to ary (argscat/splat)",
|
|
||||||
rhsn->nd_body);
|
|
||||||
ADD_INSN2(ret, nd_line(rhsn), expandarray,
|
|
||||||
INT2FIX(llen - idx), INT2FIX(lhs_splat));
|
|
||||||
}
|
|
||||||
else if (lhs_splat) {
|
|
||||||
COMPILE(ret, "rhs to ary (argscat/splat)",
|
|
||||||
rhsn->nd_body);
|
|
||||||
ADD_INSN2(ret, nd_line(rhsn), expandarray,
|
|
||||||
INT2FIX(llen - idx), INT2FIX(lhs_splat));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
COMPILE(ret, "rhs to ary (splat/default)", rhsn);
|
COMPILE(ret, "rhs to ary (splat/default)", rhsn);
|
||||||
ADD_INSN2(ret, nd_line(rhsn), expandarray, INT2FIX(llen),
|
ADD_INSN2(ret, nd_line(rhsn), expandarray, INT2FIX(llen),
|
||||||
|
@ -2364,9 +2342,10 @@ setup_arg(rb_iseq_t *iseq, LINK_ANCHOR *args, NODE *node, VALUE *flag)
|
||||||
{
|
{
|
||||||
VALUE argc = INT2FIX(0);
|
VALUE argc = INT2FIX(0);
|
||||||
NODE *argn = node->nd_args;
|
NODE *argn = node->nd_args;
|
||||||
|
int nsplat = 0;
|
||||||
DECL_ANCHOR(arg_block);
|
DECL_ANCHOR(arg_block);
|
||||||
DECL_ANCHOR(args_push);
|
DECL_ANCHOR(args_splat);
|
||||||
|
|
||||||
if (argn && nd_type(argn) == NODE_BLOCK_PASS) {
|
if (argn && nd_type(argn) == NODE_BLOCK_PASS) {
|
||||||
COMPILE(arg_block, "block", argn->nd_body);
|
COMPILE(arg_block, "block", argn->nd_body);
|
||||||
*flag |= VM_CALL_ARGS_BLOCKARG_BIT;
|
*flag |= VM_CALL_ARGS_BLOCKARG_BIT;
|
||||||
|
@ -2382,31 +2361,57 @@ setup_arg(rb_iseq_t *iseq, LINK_ANCHOR *args, NODE *node, VALUE *flag)
|
||||||
*flag |= VM_CALL_ARGS_SPLAT_BIT;
|
*flag |= VM_CALL_ARGS_SPLAT_BIT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NODE_ARGSCAT: {
|
case NODE_ARGSCAT:
|
||||||
argc = INT2FIX(compile_array(iseq, args, argn->nd_head, Qfalse) + 1);
|
case NODE_ARGSPUSH: {
|
||||||
POP_ELEMENT(args);
|
int next_is_array = (nd_type(argn->nd_head) == NODE_ARRAY);
|
||||||
COMPILE(args, "args (cat: splat)", argn->nd_body);
|
DECL_ANCHOR(tmp);
|
||||||
|
|
||||||
|
COMPILE(tmp, "args (cat: splat)", argn->nd_body);
|
||||||
|
if (next_is_array && nsplat == 0) {
|
||||||
|
/* none */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (nd_type(argn) == NODE_ARGSCAT) {
|
||||||
|
ADD_INSN1(tmp, nd_line(argn), splatarray, Qfalse);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ADD_INSN1(tmp, nd_line(argn), newarray, INT2FIX(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
INSERT_LIST(args_splat, tmp);
|
||||||
|
nsplat++;
|
||||||
*flag |= VM_CALL_ARGS_SPLAT_BIT;
|
*flag |= VM_CALL_ARGS_SPLAT_BIT;
|
||||||
|
|
||||||
|
if (next_is_array) {
|
||||||
|
argc = INT2FIX(compile_array(iseq, args, argn->nd_head, Qfalse) + 1);
|
||||||
|
POP_ELEMENT(args);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
argn = argn->nd_head;
|
||||||
|
goto setup_argn;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NODE_ARGSPUSH: {
|
case NODE_ARRAY: {
|
||||||
DECL_ANCHOR(args_push_e);
|
|
||||||
COMPILE(args_push_e, "argspush (cdr)", argn->nd_body);
|
|
||||||
ADD_INSN(args_push_e, nd_line(node), concatarray);
|
|
||||||
INSERT_LIST(args_push, args_push_e);
|
|
||||||
argn = argn->nd_head;
|
|
||||||
goto setup_argn;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
argc = INT2FIX(compile_array(iseq, args, argn, Qfalse));
|
argc = INT2FIX(compile_array(iseq, args, argn, Qfalse));
|
||||||
POP_ELEMENT(args);
|
POP_ELEMENT(args);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
default: {
|
||||||
|
rb_bug("setup_arg: unknown node: %s\n", ruby_node_name(nd_type(node)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!LIST_SIZE_ZERO(args_push)) {
|
if (nsplat > 1) {
|
||||||
ADD_SEQ(args, args_push);
|
int i;
|
||||||
|
for (i=1; i<nsplat; i++) {
|
||||||
|
ADD_INSN(args_splat, nd_line(args), concatarray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!LIST_SIZE_ZERO(args_splat)) {
|
||||||
|
ADD_SEQ(args, args_splat);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*flag & VM_CALL_ARGS_BLOCKARG_BIT) {
|
if (*flag & VM_CALL_ARGS_BLOCKARG_BIT) {
|
||||||
|
@ -3892,8 +3897,10 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NODE_ARGSPUSH:{
|
case NODE_ARGSPUSH:{
|
||||||
/* OK */
|
COMPILE(ret, "arsgpush head", node->nd_head);
|
||||||
COMPILE_ERROR(("BUG: unknown node: NODE_ARGSPUSH"));
|
COMPILE(ret, "argspush body", node->nd_body);
|
||||||
|
ADD_INSN1(ret, nd_line(node), newarray, INT2FIX(1));
|
||||||
|
ADD_INSN(ret, nd_line(node), concatarray);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NODE_SPLAT:{
|
case NODE_SPLAT:{
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#define RUBY_VERSION "1.9.0"
|
#define RUBY_VERSION "1.9.0"
|
||||||
#define RUBY_RELEASE_DATE "2007-04-26"
|
#define RUBY_RELEASE_DATE "2007-04-27"
|
||||||
#define RUBY_VERSION_CODE 190
|
#define RUBY_VERSION_CODE 190
|
||||||
#define RUBY_RELEASE_CODE 20070426
|
#define RUBY_RELEASE_CODE 20070427
|
||||||
#define RUBY_PATCHLEVEL 0
|
#define RUBY_PATCHLEVEL 0
|
||||||
|
|
||||||
#define RUBY_VERSION_MAJOR 1
|
#define RUBY_VERSION_MAJOR 1
|
||||||
|
@ -9,7 +9,7 @@
|
||||||
#define RUBY_VERSION_TEENY 0
|
#define RUBY_VERSION_TEENY 0
|
||||||
#define RUBY_RELEASE_YEAR 2007
|
#define RUBY_RELEASE_YEAR 2007
|
||||||
#define RUBY_RELEASE_MONTH 4
|
#define RUBY_RELEASE_MONTH 4
|
||||||
#define RUBY_RELEASE_DAY 26
|
#define RUBY_RELEASE_DAY 27
|
||||||
|
|
||||||
RUBY_EXTERN const char ruby_version[];
|
RUBY_EXTERN const char ruby_version[];
|
||||||
RUBY_EXTERN const char ruby_release_date[];
|
RUBY_EXTERN const char ruby_release_date[];
|
||||||
|
|
Loading…
Reference in a new issue