Project

General

Profile

0004-rough-implementation-of-keyword-arguments.patch

mame (Yusuke Endoh), 10/18/2011 01:21 AM

View differences:

compile.c
1093 1093
	    iseq->arg_post_len = args->post_args_num;
1094 1094
	}
1095 1095

  
1096
	if (args->kw_args) {
1097
	    rb_notimplement();
1098
	}
1099 1096
	if (args->opt_args) {
1100 1097
	    NODE *node = args->opt_args;
1101 1098
	    LABEL *label;
......
1129 1126
	    iseq->arg_opts = 0;
1130 1127
	}
1131 1128

  
1129
	if (args->kw_args) {
1130
	    NODE *node = args->kw_args;
1131
	    VALUE keywords = rb_ary_tmp_new(1);
1132
	    int i = 0, j;
1133
	    while (node) {
1134
		rb_ary_push(keywords, INT2FIX(node->nd_body->nd_head->nd_vid));
1135
		COMPILE_POPED(optargs, "kwarg", node->nd_body);
1136
		node = node->nd_next;
1137
		i += 1;
1138
	    }
1139
	    iseq->arg_keywords = i;
1140
	    iseq->arg_keyword_table = ALLOC_N(ID, i);
1141
	    iseq->arg_keyword_vars = ALLOC_N(int, i);
1142
	    for (j = 0; j < i; j++) {
1143
		ID id = FIX2INT(RARRAY_PTR(keywords)[j]);
1144
		iseq->arg_keyword_table[j] = id;
1145
		iseq->arg_keyword_vars[j] = get_dyna_var_idx_at_raw(iseq, id);
1146
	    }
1147
	    rb_ary_clear(keywords);
1148
	}
1149
	else {
1150
	    iseq->arg_keywords = 0;
1151
	}
1152

  
1132 1153
	if (args->pre_init) { /* m_init */
1133 1154
	    COMPILE_POPED(optargs, "init arguments (m)", args->pre_init);
1134 1155
	}
......
1153 1174
	}
1154 1175

  
1155 1176
	if (iseq->arg_opts != 0 || iseq->arg_post_len != 0 ||
1156
	    iseq->arg_rest != -1 || iseq->arg_block != -1) {
1177
	    iseq->arg_rest != -1 || iseq->arg_block != -1 ||
1178
	    iseq->arg_keywords != 0) {
1157 1179
	    iseq->arg_simple = 0;
1158 1180

  
1159 1181
	    /* set arg_size: size of arguments */
node.c
823 823
	F_NODE(nd_next, "next");
824 824
	break;
825 825

  
826
      case NODE_KW_ARG:
827
	ANN("keyword arguments");
828
	ANN("format: def method_name([nd_body=some], [nd_next..])");
829
	ANN("example: def foo(a:1, b:2); end");
830
	F_NODE(nd_body, "body");
831
	LAST_NODE;
832
	F_NODE(nd_next, "next");
833
	break;
834

  
826 835
      case NODE_POSTARG:
827 836
	ANN("post arguments");
828 837
	ANN("format: *[nd_1st], [nd_2nd..] = ..");
......
849 858
	F_ID(nd_ainfo->rest_arg, "rest argument");
850 859
	F_ID(nd_ainfo->block_arg, "block argument");
851 860
	F_NODE(nd_ainfo->opt_args, "optional arguments");
861
	LAST_NODE;
862
	F_NODE(nd_ainfo->kw_args, "keyword arguments");
852 863
	break;
853 864

  
854 865
      case NODE_SCOPE:
parse.y
4821 4821

  
4822 4822
f_kw		: tLABEL arg_value
4823 4823
		    {
4824
			NODE *lasgn;
4824 4825
			arg_var(formal_argument(get_id($1)));
4825
			$$ = assignable($1, $2);
4826
			lasgn = assignable($1, $2);
4827
			$$ = NEW_OP_ASGN_OR(gettable(lasgn->nd_vid), lasgn);
4826 4828
		    /*%%%*/
4827 4829
			$$ = NEW_KW_ARG(0, $$);
4828 4830
		    /*%
......
4833 4835

  
4834 4836
f_block_kw	: tLABEL primary_value
4835 4837
		    {
4838
			NODE *lasgn;
4836 4839
			arg_var(formal_argument(get_id($1)));
4837
			$$ = assignable($1, $2);
4840
			lasgn = assignable($1, $2);
4841
			$$ = NEW_OP_ASGN_OR(gettable(lasgn->nd_vid), lasgn);
4838 4842
		    /*%%%*/
4839 4843
			$$ = NEW_KW_ARG(0, $$);
4840 4844
		    /*%
vm_core.h
220 220
    int arg_post_start;
221 221
    int arg_size;
222 222
    VALUE *arg_opt_table;
223
    int arg_keywords;
224
    ID *arg_keyword_table;
225
    int *arg_keyword_vars;
223 226

  
224 227
    size_t stack_max; /* for stack overflow check */
225 228

  
vm_insnhelper.c
156 156

  
157 157
    th->mark_stack_len = argc + iseq->arg_size;
158 158

  
159
    if (iseq->arg_keywords && argc > 0 && TYPE(argv[argc-1]) == T_HASH) {
160
	VALUE hash = argv[argc-1];
161
	int i;
162
	argc--;
163
	for (i = 0; i < iseq->arg_keywords; i++) {
164
	    VALUE val = rb_hash_aref(hash, ID2SYM(iseq->arg_keyword_table[i]));
165
	    orig_argv[iseq->arg_keyword_vars[i]] = val;
166
	}
167
    }
168

  
159 169
    /* mandatory */
160 170
    if (argc < (m + iseq->arg_post_len)) { /* check with post arg */
161 171
	argument_error(iseq, argc, m + iseq->arg_post_len);
......
475 485
		      iseq->local_size, iseq->arg_size);
476 486

  
477 487
	/* clear local variables */
478
	for (i = 0; i < iseq->local_size - iseq->arg_size; i++) {
488
	sp += iseq->arg_keywords;
489
	for (i = iseq->arg_keywords; i < iseq->local_size - iseq->arg_size; i++) {
479 490
	    *sp++ = Qnil;
480 491
	}
481 492

  
......
498 509
	sp -= rsp - p_rsp;
499 510

  
500 511
	/* clear local variables */
501
	for (i = 0; i < iseq->local_size - iseq->arg_size; i++) {
512
	sp += iseq->arg_keywords;
513
	for (i = iseq->arg_keywords; i < iseq->local_size - iseq->arg_size; i++) {
502 514
	    *sp++ = Qnil;
503 515
	}
504 516

  
505
-