Project

General

Profile

Feature #4146 ยป symbol_lambda.diff

nobu (Nobuyoshi Nakada), 12/10/2010 08:02 PM

View differences:

w/parse.y
356 356
#define arg_append(h,t) arg_append_gen(parser,h,t)
357 357
static NODE *arg_concat_gen(struct parser_params*,NODE*,NODE*);
358 358
#define arg_concat(h,t) arg_concat_gen(parser,h,t)
359
static NODE *arg_prepend_gen(struct parser_params*,NODE*,NODE*);
360
#define arg_prepend(h,t) arg_prepend_gen(parser,h,t)
359 361
static NODE *literal_concat_gen(struct parser_params*,NODE*,NODE*);
360 362
#define literal_concat(h,t) literal_concat_gen(parser,h,t)
361 363
static int literal_concat0(struct parser_params *, VALUE, VALUE);
......
401 403
static ID  *local_tbl_gen(struct parser_params*);
402 404
#define local_tbl() local_tbl_gen(parser)
403 405

  
406
static NODE *symbol_lambda_gen(struct parser_params *, ID, NODE *);
407
#define symbol_lambda(mid, args) symbol_lambda_gen(parser, mid, args)
408

  
404 409
static void fixup_nodes(NODE **);
405 410

  
406 411
extern int rb_dvar_defined(ID);
......
676 681
	keyword__FILE__
677 682
	keyword__ENCODING__
678 683

  
679
%token <id>   tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL
684
%token <id>   tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL tAREFBEG
680 685
%token <node> tINTEGER tFLOAT tSTRING_CONTENT tCHAR
681 686
%token <node> tNTH_REF tBACK_REF
682 687
%token <num>  tREGEXP_END
......
698 703
%type <node> assoc_list assocs assoc undef_list backref string_dvar for_var
699 704
%type <node> block_param opt_block_param block_param_def f_opt
700 705
%type <node> bv_decls opt_bv_decl bvar
701
%type <node> lambda f_larglist lambda_body
706
%type <node> lambda f_larglist lambda_body sym_lambda
702 707
%type <node> brace_block cmd_brace_block do_block lhs none fitem
703 708
%type <node> mlhs mlhs_head mlhs_basic mlhs_item mlhs_node mlhs_post mlhs_inner
704 709
%type <id>   fsym variable sym symbol operation operation2 operation3
......
1859 1864
		| tUMINUS	{ ifndef_ripper($$ = tUMINUS); }
1860 1865
		| tAREF		{ ifndef_ripper($$ = tAREF); }
1861 1866
		| tASET		{ ifndef_ripper($$ = tASET); }
1867
		| tAREFBEG	{ ifndef_ripper($$ = tAREFBEG); }
1862 1868
		| '`'		{ ifndef_ripper($$ = '`'); }
1863 1869
		;
1864 1870

  
......
2576 2582
		;
2577 2583

  
2578 2584
primary		: literal
2585
		| sym_lambda
2579 2586
		| strings
2580 2587
		| xstring
2581 2588
		| regexp
......
3528 3535
		    }
3529 3536
		;
3530 3537

  
3538
sym_lambda	: literal paren_args
3539
		    {
3540
		    /*%%%*/
3541
			if (nd_type($1) == NODE_LIT ? SYMBOL_P($1->nd_lit) :
3542
			    nd_type($1) == NODE_DSYM) {
3543
			    ID mid = id__send__;
3544
			    if (nd_type($1) == NODE_LIT) {
3545
				mid = SYM2ID($1->nd_lit);
3546
			    }
3547
			    else {
3548
				$2 = arg_prepend(NEW_LIST($1), $2);
3549
			    }
3550
			    $$ = symbol_lambda(mid, $2);
3551
			    fixpos($$, $1);
3552
			}
3553
			else {
3554
			    compile_error(PARSER_ARG "non-symbol lambda");
3555
			}
3556
		    /*%
3557
			$$ = dispatch2(lambda, $1, $2);
3558
		    %*/
3559
		    }
3560
		| /*:'['*/ tAREFBEG { $<num>$ = ruby_sourceline; } aref_args ']'
3561
		    {
3562
		    /*%%%*/
3563
			$$ = symbol_lambda(tAREF, $3);
3564
			nd_set_line($$, $<num>2);
3565
		    /*%
3566
			$$ = dispatch2(lambda, ripper_id2sym(tAREF), $3);
3567
		    %*/
3568
		    }
3569
		;
3570

  
3531 3571
do_block	: keyword_do_block
3532 3572
		    {
3533 3573
			$<vars>1 = dyna_push();
......
7304 7344
	  case '"':
7305 7345
	    lex_strterm = NEW_STRTERM(str_dsym, c, 0);
7306 7346
	    break;
7347
	  case '[':
7348
	    if (!peek(']')) {
7349
		lex_state = EXPR_BEG;
7350
		return tAREFBEG;
7351
	    }
7307 7352
	  default:
7308 7353
	    pushback(c);
7309 7354
	    break;
......
8387 8432
}
8388 8433

  
8389 8434
static NODE *
8435
arg_prepend_gen(struct parser_params *parser, NODE *node1, NODE *node2)
8436
{
8437
    const char *ruby_node_name(int);
8438

  
8439
    if (!node1) return node2;
8440
    if (!node2) return node1;
8441
    switch (nd_type(node2)) {
8442
      case NODE_ARRAY:
8443
	return list_concat(node1, node2);
8444
      case NODE_BLOCK_PASS:
8445
	node2->nd_head = arg_prepend(node1, node2->nd_head);
8446
	return node2;
8447
      case NODE_SPLAT:
8448
	node2->nd_body = node2->nd_head;
8449
	node2->nd_head = node1;
8450
	nd_set_type(node2, NODE_ARGSCAT);
8451
	return node2;
8452
      case NODE_ARGSCAT:
8453
	node2->nd_head = arg_prepend(node1, node2->nd_head);
8454
	return node2;
8455
      case NODE_ARGSPUSH:
8456
	node2->nd_head = arg_prepend(node1, node2->nd_head);
8457
	return node2;
8458
      default:
8459
	compile_error(PARSER_ARG "unhandled node %s", ruby_node_name(nd_type(node2)));
8460
	return 0;
8461
    }
8462
}
8463

  
8464
static NODE *
8465
symbol_lambda_gen(struct parser_params *parser, ID mid, NODE *args)
8466
{
8467
    const struct vtable *vars = dyna_push();
8468
    ID tid = internal_id();
8469
    NODE *lambda = NEW_LAMBDA(0);
8470
    arg_var(tid);
8471
    lambda->nd_body = NEW_SCOPE(new_args(NEW_ARGS_AUX(tid, 1), 0, 0, 0, 0),
8472
				NEW_CALL(NEW_DVAR(tid), mid, args));
8473
    dyna_pop(vars);
8474
    return lambda;
8475
}
8476

  
8477
static NODE *
8390 8478
splat_array(NODE* node)
8391 8479
{
8392 8480
    if (nd_type(node) == NODE_SPLAT) node = node->nd_head;
w/test/ruby/test_symbol.rb
88 88
      ary_ids = ary.collect{|x| x.object_id }
89 89
      assert_equal ary_ids, ary.collect(&:object_id)
90 90
    end
91

  
92
    assert_equal [2, 4, 6], (1..3).map(&:*(2))
93
    assert_equal %w(b e h), %w[abc def ghi].map(&:[1])
91 94
  end
92 95

  
93 96
  def test_call