summaryrefslogtreecommitdiff
path: root/compile.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-03-12 13:20:50 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-03-12 13:20:50 +0000
commit34a95669dad8843e3e9a4af683682ab2f50856dd (patch)
tree165cd3bd3ed70a911853f55055bce1a86632a686 /compile.c
parent976a3041ef38711b84c6a35db25f189d31903e38 (diff)
required keyword arguments
* compile.c (iseq_set_arguments, iseq_compile_each): support required keyword arguments. [ruby-core:51454] [Feature #7701] * iseq.c (rb_iseq_parameters): ditto. * parse.y (f_kw, f_block_kw): ditto. this syntax is still experimental, the notation may change. * vm_core.h (rb_iseq_struct): ditto. * vm_insnhelper.c (vm_callee_setup_keyword_arg): ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@39735 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'compile.c')
-rw-r--r--compile.c29
1 files changed, 23 insertions, 6 deletions
diff --git a/compile.c b/compile.c
index f9ed3c0..9360f5b 100644
--- a/compile.c
+++ b/compile.c
@@ -1183,19 +1183,31 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *optargs, NODE *node_args)
if (args->kw_args) {
NODE *node = args->kw_args;
VALUE keywords = rb_ary_tmp_new(1);
- int i = 0, j;
+ VALUE required = 0;
+ int i = 0, j, r = 0;
iseq->arg_keyword = get_dyna_var_idx_at_raw(iseq, args->kw_rest_arg->nd_vid);
COMPILE(optargs, "kwarg", args->kw_rest_arg);
while (node) {
- rb_ary_push(keywords, INT2FIX(node->nd_body->nd_vid));
+ VALUE list = keywords;
+ if (node->nd_body->nd_value == (NODE *)-1) {
+ ++r;
+ if (!required) required = rb_ary_tmp_new(1);
+ list = required;
+ }
+ rb_ary_push(list, INT2FIX(node->nd_body->nd_vid));
COMPILE_POPED(optargs, "kwarg", node); /* nd_type(node) == NODE_KW_ARG */
node = node->nd_next;
i += 1;
}
iseq->arg_keyword_check = (args->kw_rest_arg->nd_vid & ID_SCOPE_MASK) == ID_JUNK;
iseq->arg_keywords = i;
+ iseq->arg_keyword_required = r;
iseq->arg_keyword_table = ALLOC_N(ID, i);
+ if (r) {
+ rb_ary_concat(required, keywords);
+ keywords = required;
+ }
for (j = 0; j < i; j++) {
iseq->arg_keyword_table[j] = FIX2INT(RARRAY_PTR(keywords)[j]);
}
@@ -5200,7 +5212,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
}
case NODE_KW_ARG:{
LABEL *default_label = NEW_LABEL(line);
- LABEL *end_label = NEW_LABEL(line);
+ LABEL *end_label = 0;
int idx, lv, ls;
ID id = node->nd_body->nd_vid;
@@ -5224,10 +5236,15 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
default:
rb_bug("iseq_compile_each (NODE_KW_ARG): unknown node: %s", ruby_node_name(nd_type(node->nd_body)));
}
- ADD_INSNL(ret, line, jump, end_label);
+ if (node->nd_body->nd_value != (NODE *)-1) {
+ end_label = NEW_LABEL(nd_line(node));
+ ADD_INSNL(ret, nd_line(node), jump, end_label);
+ }
ADD_LABEL(ret, default_label);
- COMPILE_POPED(ret, "keyword default argument", node->nd_body);
- ADD_LABEL(ret, end_label);
+ if (node->nd_body->nd_value != (NODE *)-1) {
+ COMPILE_POPED(ret, "keyword default argument", node->nd_body);
+ ADD_LABEL(ret, end_label);
+ }
break;
}
case NODE_DSYM:{