Feature #5454 » 0004-rough-implementation-of-keyword-arguments.patch
compile.c | ||
---|---|---|
iseq->arg_post_len = args->post_args_num;
|
||
}
|
||
if (args->kw_args) {
|
||
rb_notimplement();
|
||
}
|
||
if (args->opt_args) {
|
||
NODE *node = args->opt_args;
|
||
LABEL *label;
|
||
... | ... | |
iseq->arg_opts = 0;
|
||
}
|
||
if (args->kw_args) {
|
||
NODE *node = args->kw_args;
|
||
VALUE keywords = rb_ary_tmp_new(1);
|
||
int i = 0, j;
|
||
while (node) {
|
||
rb_ary_push(keywords, INT2FIX(node->nd_body->nd_head->nd_vid));
|
||
COMPILE_POPED(optargs, "kwarg", node->nd_body);
|
||
node = node->nd_next;
|
||
i += 1;
|
||
}
|
||
iseq->arg_keywords = i;
|
||
iseq->arg_keyword_table = ALLOC_N(ID, i);
|
||
iseq->arg_keyword_vars = ALLOC_N(int, i);
|
||
for (j = 0; j < i; j++) {
|
||
ID id = FIX2INT(RARRAY_PTR(keywords)[j]);
|
||
iseq->arg_keyword_table[j] = id;
|
||
iseq->arg_keyword_vars[j] = get_dyna_var_idx_at_raw(iseq, id);
|
||
}
|
||
rb_ary_clear(keywords);
|
||
}
|
||
else {
|
||
iseq->arg_keywords = 0;
|
||
}
|
||
if (args->pre_init) { /* m_init */
|
||
COMPILE_POPED(optargs, "init arguments (m)", args->pre_init);
|
||
}
|
||
... | ... | |
}
|
||
if (iseq->arg_opts != 0 || iseq->arg_post_len != 0 ||
|
||
iseq->arg_rest != -1 || iseq->arg_block != -1) {
|
||
iseq->arg_rest != -1 || iseq->arg_block != -1 ||
|
||
iseq->arg_keywords != 0) {
|
||
iseq->arg_simple = 0;
|
||
/* set arg_size: size of arguments */
|
node.c | ||
---|---|---|
F_NODE(nd_next, "next");
|
||
break;
|
||
case NODE_KW_ARG:
|
||
ANN("keyword arguments");
|
||
ANN("format: def method_name([nd_body=some], [nd_next..])");
|
||
ANN("example: def foo(a:1, b:2); end");
|
||
F_NODE(nd_body, "body");
|
||
LAST_NODE;
|
||
F_NODE(nd_next, "next");
|
||
break;
|
||
case NODE_POSTARG:
|
||
ANN("post arguments");
|
||
ANN("format: *[nd_1st], [nd_2nd..] = ..");
|
||
... | ... | |
F_ID(nd_ainfo->rest_arg, "rest argument");
|
||
F_ID(nd_ainfo->block_arg, "block argument");
|
||
F_NODE(nd_ainfo->opt_args, "optional arguments");
|
||
LAST_NODE;
|
||
F_NODE(nd_ainfo->kw_args, "keyword arguments");
|
||
break;
|
||
case NODE_SCOPE:
|
parse.y | ||
---|---|---|
f_kw : tLABEL arg_value
|
||
{
|
||
NODE *lasgn;
|
||
arg_var(formal_argument(get_id($1)));
|
||
$$ = assignable($1, $2);
|
||
lasgn = assignable($1, $2);
|
||
$$ = NEW_OP_ASGN_OR(gettable(lasgn->nd_vid), lasgn);
|
||
/*%%%*/
|
||
$$ = NEW_KW_ARG(0, $$);
|
||
/*%
|
||
... | ... | |
f_block_kw : tLABEL primary_value
|
||
{
|
||
NODE *lasgn;
|
||
arg_var(formal_argument(get_id($1)));
|
||
$$ = assignable($1, $2);
|
||
lasgn = assignable($1, $2);
|
||
$$ = NEW_OP_ASGN_OR(gettable(lasgn->nd_vid), lasgn);
|
||
/*%%%*/
|
||
$$ = NEW_KW_ARG(0, $$);
|
||
/*%
|
vm_core.h | ||
---|---|---|
int arg_post_start;
|
||
int arg_size;
|
||
VALUE *arg_opt_table;
|
||
int arg_keywords;
|
||
ID *arg_keyword_table;
|
||
int *arg_keyword_vars;
|
||
size_t stack_max; /* for stack overflow check */
|
||
vm_insnhelper.c | ||
---|---|---|
th->mark_stack_len = argc + iseq->arg_size;
|
||
if (iseq->arg_keywords && argc > 0 && TYPE(argv[argc-1]) == T_HASH) {
|
||
VALUE hash = argv[argc-1];
|
||
int i;
|
||
argc--;
|
||
for (i = 0; i < iseq->arg_keywords; i++) {
|
||
VALUE val = rb_hash_aref(hash, ID2SYM(iseq->arg_keyword_table[i]));
|
||
orig_argv[iseq->arg_keyword_vars[i]] = val;
|
||
}
|
||
}
|
||
/* mandatory */
|
||
if (argc < (m + iseq->arg_post_len)) { /* check with post arg */
|
||
argument_error(iseq, argc, m + iseq->arg_post_len);
|
||
... | ... | |
iseq->local_size, iseq->arg_size);
|
||
/* clear local variables */
|
||
for (i = 0; i < iseq->local_size - iseq->arg_size; i++) {
|
||
sp += iseq->arg_keywords;
|
||
for (i = iseq->arg_keywords; i < iseq->local_size - iseq->arg_size; i++) {
|
||
*sp++ = Qnil;
|
||
}
|
||
... | ... | |
sp -= rsp - p_rsp;
|
||
/* clear local variables */
|
||
for (i = 0; i < iseq->local_size - iseq->arg_size; i++) {
|
||
sp += iseq->arg_keywords;
|
||
for (i = iseq->arg_keywords; i < iseq->local_size - iseq->arg_size; i++) {
|
||
*sp++ = Qnil;
|
||
}
|
||