[#30722] JSON ライブラリの取り込み — "NARUSE, Yui" <naruse@...>

naruseです。

20 messages 2007/04/21

[ruby-dev:30735] ObjectC style keyword argument

From: Nobuyoshi Nakada <nobu@...>
Date: 2007-04-26 14:22:56 UTC
List: ruby-dev #30735
なかだです。

おととい電車の中で大体できちゃったのでなんとなく(謎)。

  class ObjC
    def copy:from: p [copy, from] end
  end
  ObjC.new.copy: "x", from: "y" #=> ["x", "y"]

という感じでメソッド定義も可能になりました。


Index: parse.y
===================================================================
--- parse.y	(revision 12223)
+++ parse.y	(working copy)
@@ -529,4 +529,6 @@ static void ripper_compile_error(struct 
 #endif
 
+ID rb_alist_id(VALUE);
+
 %}
 
@@ -613,4 +615,5 @@ static void ripper_compile_error(struct 
 %type <node> f_arglist f_args f_arg f_arg_item f_optarg f_marg f_marg_head f_margs
 %type <node> assoc_list assocs assoc undef_list backref string_dvar for_var
+%type <node> assoc_call assoc_arg
 %type <node> block_param opt_block_param block_param_def f_opt
 %type <node> bv_decls opt_bv_decl bvar
@@ -620,4 +623,5 @@ static void ripper_compile_error(struct 
 %type <id>   fsym variable sym symbol operation operation2 operation3
 %type <id>   cname fname op f_rest_arg f_block_arg opt_f_block_arg f_norm_arg
+%type <val>  label_args label_arg
 /*%%%*/
 /*%
@@ -1040,4 +1044,17 @@ stmt		: keyword_alias fitem {lex_state =
 		    %*/
 		    }
+		| primary_value '.' assoc_call
+		    {
+		    /*%%%*/
+			ID associd = rb_alist_id($3->nd_lit);
+			$3->nd_next->nd_alen = $3->nd_alen - 1;
+			$$ = NEW_CALL($1, associd, $3->nd_next);
+			fixpos($$, $1);
+		    /*%
+			$$ = dispatch3(call, $1, ripper_id2sym('.'),
+				       ID2SYM(rb_alist_id(rb_ary_shift($3))));
+		        $$ = method_arg($$, $3);
+		    %*/
+		    }
 		| primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call
 		    {
@@ -2830,4 +2847,82 @@ primary		: literal
 		    %*/
 		    }
+		| keyword_def label_args
+		    {
+			$<id>$ = cur_mid;
+			cur_mid = rb_alist_id($2);
+			in_def++;
+		    /*%%%*/
+			local_push(0);
+		    /*%
+		    %*/
+		    }
+		    {
+		    /*%%%*/
+			VALUE names = $2;
+			long i;
+			for (i = 0; i < RARRAY_LEN(names); ++i) {
+			    ID id = SYM2ID(RARRAY_PTR(names)[i]);
+			    shadowing_lvar(id);
+			    arg_var(id);
+			}
+			$<node>$ = new_args(NEW_ARGS_AUX(0, i), 0, 0, 0, 0);
+		    /*%
+			$$ = dispatch5(params, $2, Qnil, Qnil, Qnil, Qnil);
+		    %*/
+		    }
+		  bodystmt
+		  keyword_end
+		    {
+		    /*%%%*/
+			NODE *body = remove_begin($5);
+			reduce_nodes(&body);
+			$$ = NEW_DEFN(cur_mid, $<node>4, body, NOEX_PRIVATE);
+		        fixpos($$, $<node>4);
+		        local_pop();
+			in_def--;
+			cur_mid = $<id>3;
+		    /*%
+			$$ = dispatch3(def, cur_mid, $<val>4, $5);
+			in_def--;
+			cur_mid = $<id>3;
+		    %*/
+		    }
+		| keyword_def singleton dot_or_colon {lex_state = EXPR_FNAME;} label_args
+		    {
+			in_single++;
+		    /*%%%*/
+			local_push(0);
+		    /*%
+		    %*/
+		    }
+		    {
+		    /*%%%*/
+			VALUE names = $5;
+			long i;
+			for (i = 0; i < RARRAY_LEN(names); ++i) {
+			    ID id = SYM2ID(RARRAY_PTR(names)[i]);
+			    shadowing_lvar(id);
+			    arg_var(id);
+			}
+			$<node>$ = new_args(NEW_ARGS_AUX(0, i), 0, 0, 0, 0);
+		    /*%
+			$$ = dispatch5(params, $5, Qnil, Qnil, Qnil, Qnil);
+		    %*/
+		    }
+		  bodystmt
+		  keyword_end
+		    {
+		    /*%%%*/
+			NODE *body = remove_begin($8);
+			reduce_nodes(&body);
+			$$ = NEW_DEFS($2, rb_alist_id($5), $<node>7, body);
+		        fixpos($$, $2);
+		        local_pop();
+			in_single--;
+		    /*%
+			$$ = dispatch5(defs, $2, $3, ID2SYM(rb_alist_id($5)), $<val>7, $8);
+			in_single--;
+		    %*/
+		    }
 		| keyword_break
 		    {
@@ -4329,4 +4424,48 @@ assoc		: arg_value tASSOC arg_value
 		;
 
+assoc_call	: assoc_arg
+		| assoc_call ',' assoc_arg
+		    {
+		    /*%%%*/
+			rb_ary_concat($1->nd_lit, $3->nd_lit);
+			$$ = list_concat($1, $3->nd_next);
+		    /*%
+			rb_ary_push(rb_ary_entry($1, 0), rb_ary_entry($3, 0));
+			rb_ary_push($1, rb_ary_entry($3, 1));
+		    %*/
+		    }
+
+assoc_arg	: tLABEL arg_value
+		    {
+		    /*%%%*/
+			$$ = list_append(NEW_LIST(rb_ary_new3(1, ID2SYM($1))), $2);
+		    /*%
+		    	$$ = rb_assoc_new(rb_ary_new3(1, $1), $2);
+		    %*/
+		    }
+		;
+
+label_args	: label_arg
+		    {
+			$$ = rb_ary_new3(1, $1);
+		    }
+		| label_args label_arg
+		    {
+			rb_ary_push($1, $2);
+			$$ = $1;
+		    }
+		;
+label_arg	: tLABEL
+		    {
+                    /*%%%*/
+			if (!is_local_id($1))
+			    yyerror("formal argument must be local variable");
+			$$ = ID2SYM($1);
+                    /*%
+		        $$ = dispatch1(label_arg, ID2SYM($1));
+                    %*/
+		    }
+		;
+
 operation	: tIDENTIFIER
 		| tCONSTANT
@@ -6795,4 +6934,6 @@ parser_yylex(struct parser_params *parse
 	    if ((lex_state == EXPR_BEG && !cmd_state) ||
 		lex_state == EXPR_ARG ||
+		lex_state == EXPR_DOT ||
+		lex_state == EXPR_FNAME ||
 		lex_state == EXPR_CMDARG) {
 		if (peek(':') && !(lex_p + 1 < lex_pend && lex_p[1] == ':')) {
@@ -8501,4 +8642,11 @@ rb_id2name(ID id)
 }
 
+ID
+rb_alist_id(VALUE names)
+{
+    VALUE name = rb_str_cat(rb_ary_join(names, rb_str_new2(":")), ":", 1);
+    return rb_intern2(RSTRING_PTR(name), RSTRING_LEN(name));
+}
+
 static int
 symbols_i(VALUE sym, ID value, VALUE ary)


-- 
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
    中田 伸悦

In This Thread

Prev Next