Project

General

Profile

Feature #10481 ยป rescue-conditions.diff

javawizard (Alex Boyd), 11/20/2014 12:30 PM

View differences:

compile.c
3838 3838
	ADD_CATCH_ENTRY(CATCH_TYPE_RETRY, lend, lcont, 0, lstart);
3839 3839
	break;
3840 3840
      }
3841
      case NODE_RESCOND:
3841 3842
      case NODE_RESBODY:{
3842 3843
	NODE *resq = node;
3843
	NODE *narg;
3844
	LABEL *label_miss, *label_hit;
3844
	NODE *narg, *cond;
3845
	LABEL *label_miss, *label_hit, *label_pass;
3845 3846

  
3846 3847
	while (resq) {
3847 3848
	    label_miss = NEW_LABEL(line);
3848 3849
	    label_hit = NEW_LABEL(line);
3849 3850

  
3851
	    if (nd_type(resq) == NODE_RESCOND) {
3852
	        label_pass = NEW_LABEL(line);
3853
	        cond = resq->nd_cond;
3854
	        resq = resq->nd_resq;
3855
	    }
3856
	    else {
3857
	        cond = 0;
3858
	    }
3859

  
3850 3860
	    narg = resq->nd_args;
3851 3861
	    if (narg) {
3852 3862
		switch (nd_type(narg)) {
......
3880 3890
	    }
3881 3891
	    ADD_INSNL(ret, line, jump, label_miss);
3882 3892
	    ADD_LABEL(ret, label_hit);
3893

  
3894
	    if (cond) {
3895
	        switch (nd_type(cond)) {
3896
	          case NODE_RESCOND_IF:
3897
	            compile_branch_condition(iseq, ret, cond->nd_cond, label_pass, label_miss);
3898
	            break;
3899
	          case NODE_RESCOND_UNLESS:
3900
	            compile_branch_condition(iseq, ret, cond->nd_cond, label_miss, label_pass);
3901
	            break;
3902
	          default:
3903
	            rb_bug("NODE_RESCOND: unknown node (%s)",
3904
	               ruby_node_name(nd_type(cond)));
3905
	        }
3906
	        ADD_LABEL(ret, label_pass);
3907
	    }
3908

  
3883 3909
	    COMPILE(ret, "resbody body", resq->nd_body);
3884 3910
	    if (iseq->compile_data->option->tailcall_optimization) {
3885 3911
		ADD_INSN(ret, line, nop);
ext/objspace/objspace.c
319 319
		COUNT_NODE(NODE_BEGIN);
320 320
		COUNT_NODE(NODE_RESCUE);
321 321
		COUNT_NODE(NODE_RESBODY);
322
		COUNT_NODE(NODE_RESCOND);
323
		COUNT_NODE(NODE_RESCOND_IF);
324
		COUNT_NODE(NODE_RESCOND_UNLESS);
322 325
		COUNT_NODE(NODE_ENSURE);
323 326
		COUNT_NODE(NODE_AND);
324 327
		COUNT_NODE(NODE_OR);
gc.c
3751 3751
	  case NODE_ALIAS:
3752 3752
	  case NODE_VALIAS:
3753 3753
	  case NODE_ARGSCAT:
3754
	  case NODE_RESCOND:
3754 3755
	    gc_mark(objspace, (VALUE)obj->as.node.u1.node);
3755 3756
	    /* fall through */
3756 3757
	  case NODE_GASGN:	/* 2 */
......
3781 3782
	  case NODE_COLON2:
3782 3783
	  case NODE_SPLAT:
3783 3784
	  case NODE_TO_ARY:
3785
	  case NODE_RESCOND_IF:
3786
	  case NODE_RESCOND_UNLESS:
3784 3787
	    ptr = (VALUE)obj->as.node.u1.node;
3785 3788
	    goto again;
3786 3789

  
node.c
234 234
	F_NODE(nd_head, "next rescue clause");
235 235
	break;
236 236

  
237
      case NODE_RESCOND:
238
	ANN("conditional rescue");
239
	ANN("format: (rescue) [nd_body] (if or unless) [nd_cond]");
240
	F_NODE(nd_cond, "rescue condition");
241
	LAST_NODE;
242
	F_NODE(nd_resq, "rescue clause");
243
	break;
244

  
245
      case NODE_RESCOND_IF:
246
	ANN("conditional rescue if modifier");
247
	ANN("format: if [nd_cond]");
248
	LAST_NODE;
249
	F_NODE(nd_cond, "condition");
250
	break;
251

  
252
      case NODE_RESCOND_UNLESS:
253
	ANN("conditional rescue unless modifier");
254
	ANN("format: unless [nd_cond]");
255
	LAST_NODE;
256
	F_NODE(nd_cond, "condition");
257
	break;
258

  
237 259
      case NODE_ENSURE:
238 260
	ANN("ensure clause");
239 261
	ANN("format: begin; [nd_head]; ensure; [nd_ensr]; end");
node.h
54 54
#define NODE_RESCUE      NODE_RESCUE
55 55
    NODE_RESBODY,
56 56
#define NODE_RESBODY     NODE_RESBODY
57
    NODE_RESCOND,
58
#define NODE_RESCOND     NODE_RESCOND
59
    NODE_RESCOND_IF,
60
#define NODE_RESCOND_IF     NODE_RESCOND_IF
61
    NODE_RESCOND_UNLESS,
62
#define NODE_RESCOND_UNLESS     NODE_RESCOND_UNLESS
57 63
    NODE_ENSURE,
58 64
#define NODE_ENSURE      NODE_ENSURE
59 65
    NODE_AND,
......
385 391
#define NEW_BEGIN(b) NEW_NODE(NODE_BEGIN,0,b,0)
386 392
#define NEW_RESCUE(b,res,e) NEW_NODE(NODE_RESCUE,b,res,e)
387 393
#define NEW_RESBODY(a,ex,n) NEW_NODE(NODE_RESBODY,n,ex,a)
394
#define NEW_RESCOND(c,b) NEW_NODE(NODE_RESCOND,c,b,0)
395
#define NEW_RESCOND_IF(c) NEW_NODE(NODE_RESCOND_IF,c,0,0)
396
#define NEW_RESCOND_UNLESS(c) NEW_NODE(NODE_RESCOND_UNLESS,c,0,0)
388 397
#define NEW_ENSURE(b,en) NEW_NODE(NODE_ENSURE,b,0,en)
389 398
#define NEW_RETURN(s) NEW_NODE(NODE_RETURN,s,0,0)
390 399
#define NEW_YIELD(a) NEW_NODE(NODE_YIELD,a,0,0)
parse.y
771 771
%type <node> top_compstmt top_stmts top_stmt
772 772
%type <node> bodystmt compstmt stmts stmt_or_begin stmt expr arg primary command command_call method_call
773 773
%type <node> expr_value arg_value primary_value fcall
774
%type <node> if_tail opt_else case_body cases opt_rescue exc_list exc_var opt_ensure
774
%type <node> if_tail opt_else case_body cases opt_rescue exc_cond exc_list exc_var opt_ensure
775 775
%type <node> args call_args opt_call_args
776 776
%type <node> paren_args opt_paren_args args_tail opt_args_tail block_args_tail opt_block_args_tail
777 777
%type <node> command_args aref_args opt_block_arg block_arg var_ref var_lhs
......
3745 3745
		| case_body
3746 3746
		;
3747 3747

  
3748
opt_rescue	: keyword_rescue exc_list exc_var then
3748
opt_rescue	: keyword_rescue exc_list exc_var exc_cond then
3749 3749
		  compstmt
3750 3750
		  opt_rescue
3751 3751
		    {
3752 3752
		    /*%%%*/
3753 3753
			if ($3) {
3754 3754
			    $3 = node_assign($3, NEW_ERRINFO());
3755
			    $5 = block_append($3, $5);
3755
			    if ($4) {
3756
			      $4->nd_cond = block_append($3, $4->nd_cond);
3757
			    }
3758
			    else {
3759
			      $6 = block_append($3, $6);
3760
			    }
3761
			}
3762
			$$ = NEW_RESBODY($2, $6, $7);
3763
			if ($4) {
3764
			    $$ = NEW_RESCOND($4, $$);
3756 3765
			}
3757
			$$ = NEW_RESBODY($2, $5, $6);
3758
			fixpos($$, $2?$2:$5);
3766
			fixpos($$, $2?$2:$6);
3759 3767
		    /*%
3760
			$$ = dispatch4(rescue,
3768
			$$ = dispatch5(rescue,
3761 3769
				       escape_Qundef($2),
3762 3770
				       escape_Qundef($3),
3763
				       escape_Qundef($5),
3764
				       escape_Qundef($6));
3771
				       escape_Qundef($4),
3772
				       escape_Qundef($6),
3773
				       escape_Qundef($7));
3774
		    %*/
3775
		    }
3776
		| none
3777
		;
3778

  
3779
exc_cond	: modifier_if expr_value
3780
		    {
3781
		    /*%%%*/
3782
			$$ = NEW_RESCOND_IF(cond($2));
3783
		    /*%
3784
			$$ = dispatch1(rescond_if, $2);
3785
		    %*/
3786
		    }
3787
		| modifier_unless expr_value
3788
		    {
3789
		    /*%%%*/
3790
			$$ = NEW_RESCOND_UNLESS(cond($2));
3791
		    /*%
3792
			$$ = dispatch1(rescond_unless, $2);
3765 3793
		    %*/
3766 3794
		    }
3767 3795
		| none