diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-03-12 13:20:50 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-03-12 13:20:50 +0000 |
commit | 34a95669dad8843e3e9a4af683682ab2f50856dd (patch) | |
tree | 165cd3bd3ed70a911853f55055bce1a86632a686 /compile.c | |
parent | 976a3041ef38711b84c6a35db25f189d31903e38 (diff) | |
download | ruby-34a95669dad8843e3e9a4af683682ab2f50856dd.tar.gz |
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.c | 29 |
1 files changed, 23 insertions, 6 deletions
@@ -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:{ |