summaryrefslogtreecommitdiff
path: root/compile.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-04-28 21:12:05 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-04-28 21:12:05 +0000
commit3380974143d3fdf1721d9e28d6b2d42036f03bd2 (patch)
tree86a60ee982dbdc8f2c68900a43327765b648822e /compile.c
parent82fa2995b5ca47d3383cce82ba5c75da4f09da5a (diff)
* parse.y (assoc, parser_yylex): add syntax to splat keyword hash.
[ruby-core:44591][Feature #6353] * compile.c (compile_array_): generate keyword splat insns. * vm.c (m_core_hash_merge_kwd): merge keyword hash into intermediate hash. leftward argument is prior currently. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@35489 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'compile.c')
-rw-r--r--compile.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/compile.c b/compile.c
index 74982db138..b5a215c8df 100644
--- a/compile.c
+++ b/compile.c
@@ -2296,21 +2296,28 @@ compile_array_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE* node_root,
while (node) {
NODE *start_node = node, *end_node;
+ NODE *kw = 0;
const int max = 0x100;
DECL_ANCHOR(anchor);
INIT_ANCHOR(anchor);
- for (i=0; i<max && node; i++, len++) {
+ for (i=0; i<max && node; i++, len++, node = node->nd_next) {
if (CPDEBUG > 0 && nd_type(node) != NODE_ARRAY) {
rb_bug("compile_array: This node is not NODE_ARRAY, but %s", ruby_node_name(nd_type(node)));
}
+ if (type == COMPILE_ARRAY_TYPE_HASH && !node->nd_head) {
+ opt_p = 0;
+ kw = node->nd_next;
+ node = kw->nd_next;
+ kw = kw->nd_head;
+ break;
+ }
if (opt_p && nd_type(node->nd_head) != NODE_LIT) {
opt_p = 0;
}
COMPILE_(anchor, "array element", node->nd_head, poped);
- node = node->nd_next;
}
if (opt_p && type != COMPILE_ARRAY_TYPE_ARGS) {
@@ -2378,12 +2385,18 @@ compile_array_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE* node_root,
ADD_INSN1(anchor, line, newhash, INT2FIX(i));
APPEND_LIST(ret, anchor);
}
- else {
+ else if (i > 0) {
ADD_INSN1(ret, line, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
ADD_INSN(ret, line, swap);
APPEND_LIST(ret, anchor);
ADD_SEND(ret, line, ID2SYM(id_core_hash_merge_ptr), INT2FIX(i + 1));
}
+ if (kw) {
+ ADD_INSN1(ret, line, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
+ ADD_INSN(ret, line, swap);
+ COMPILE(ret, "keyword splat", kw);
+ ADD_SEND(ret, line, ID2SYM(id_core_hash_merge_kwd), INT2FIX(2));
+ }
break;
case COMPILE_ARRAY_TYPE_ARGS:
APPEND_LIST(ret, anchor);