Feature #4146 ยป symbol_lambda.diff
w/parse.y | ||
---|---|---|
#define arg_append(h,t) arg_append_gen(parser,h,t)
|
||
static NODE *arg_concat_gen(struct parser_params*,NODE*,NODE*);
|
||
#define arg_concat(h,t) arg_concat_gen(parser,h,t)
|
||
static NODE *arg_prepend_gen(struct parser_params*,NODE*,NODE*);
|
||
#define arg_prepend(h,t) arg_prepend_gen(parser,h,t)
|
||
static NODE *literal_concat_gen(struct parser_params*,NODE*,NODE*);
|
||
#define literal_concat(h,t) literal_concat_gen(parser,h,t)
|
||
static int literal_concat0(struct parser_params *, VALUE, VALUE);
|
||
... | ... | |
static ID *local_tbl_gen(struct parser_params*);
|
||
#define local_tbl() local_tbl_gen(parser)
|
||
static NODE *symbol_lambda_gen(struct parser_params *, ID, NODE *);
|
||
#define symbol_lambda(mid, args) symbol_lambda_gen(parser, mid, args)
|
||
static void fixup_nodes(NODE **);
|
||
extern int rb_dvar_defined(ID);
|
||
... | ... | |
keyword__FILE__
|
||
keyword__ENCODING__
|
||
%token <id> tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL
|
||
%token <id> tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL tAREFBEG
|
||
%token <node> tINTEGER tFLOAT tSTRING_CONTENT tCHAR
|
||
%token <node> tNTH_REF tBACK_REF
|
||
%token <num> tREGEXP_END
|
||
... | ... | |
%type <node> assoc_list assocs assoc undef_list backref string_dvar for_var
|
||
%type <node> block_param opt_block_param block_param_def f_opt
|
||
%type <node> bv_decls opt_bv_decl bvar
|
||
%type <node> lambda f_larglist lambda_body
|
||
%type <node> lambda f_larglist lambda_body sym_lambda
|
||
%type <node> brace_block cmd_brace_block do_block lhs none fitem
|
||
%type <node> mlhs mlhs_head mlhs_basic mlhs_item mlhs_node mlhs_post mlhs_inner
|
||
%type <id> fsym variable sym symbol operation operation2 operation3
|
||
... | ... | |
| tUMINUS { ifndef_ripper($$ = tUMINUS); }
|
||
| tAREF { ifndef_ripper($$ = tAREF); }
|
||
| tASET { ifndef_ripper($$ = tASET); }
|
||
| tAREFBEG { ifndef_ripper($$ = tAREFBEG); }
|
||
| '`' { ifndef_ripper($$ = '`'); }
|
||
;
|
||
... | ... | |
;
|
||
primary : literal
|
||
| sym_lambda
|
||
| strings
|
||
| xstring
|
||
| regexp
|
||
... | ... | |
}
|
||
;
|
||
sym_lambda : literal paren_args
|
||
{
|
||
/*%%%*/
|
||
if (nd_type($1) == NODE_LIT ? SYMBOL_P($1->nd_lit) :
|
||
nd_type($1) == NODE_DSYM) {
|
||
ID mid = id__send__;
|
||
if (nd_type($1) == NODE_LIT) {
|
||
mid = SYM2ID($1->nd_lit);
|
||
}
|
||
else {
|
||
$2 = arg_prepend(NEW_LIST($1), $2);
|
||
}
|
||
$$ = symbol_lambda(mid, $2);
|
||
fixpos($$, $1);
|
||
}
|
||
else {
|
||
compile_error(PARSER_ARG "non-symbol lambda");
|
||
}
|
||
/*%
|
||
$$ = dispatch2(lambda, $1, $2);
|
||
%*/
|
||
}
|
||
| /*:'['*/ tAREFBEG { $<num>$ = ruby_sourceline; } aref_args ']'
|
||
{
|
||
/*%%%*/
|
||
$$ = symbol_lambda(tAREF, $3);
|
||
nd_set_line($$, $<num>2);
|
||
/*%
|
||
$$ = dispatch2(lambda, ripper_id2sym(tAREF), $3);
|
||
%*/
|
||
}
|
||
;
|
||
do_block : keyword_do_block
|
||
{
|
||
$<vars>1 = dyna_push();
|
||
... | ... | |
case '"':
|
||
lex_strterm = NEW_STRTERM(str_dsym, c, 0);
|
||
break;
|
||
case '[':
|
||
if (!peek(']')) {
|
||
lex_state = EXPR_BEG;
|
||
return tAREFBEG;
|
||
}
|
||
default:
|
||
pushback(c);
|
||
break;
|
||
... | ... | |
}
|
||
static NODE *
|
||
arg_prepend_gen(struct parser_params *parser, NODE *node1, NODE *node2)
|
||
{
|
||
const char *ruby_node_name(int);
|
||
if (!node1) return node2;
|
||
if (!node2) return node1;
|
||
switch (nd_type(node2)) {
|
||
case NODE_ARRAY:
|
||
return list_concat(node1, node2);
|
||
case NODE_BLOCK_PASS:
|
||
node2->nd_head = arg_prepend(node1, node2->nd_head);
|
||
return node2;
|
||
case NODE_SPLAT:
|
||
node2->nd_body = node2->nd_head;
|
||
node2->nd_head = node1;
|
||
nd_set_type(node2, NODE_ARGSCAT);
|
||
return node2;
|
||
case NODE_ARGSCAT:
|
||
node2->nd_head = arg_prepend(node1, node2->nd_head);
|
||
return node2;
|
||
case NODE_ARGSPUSH:
|
||
node2->nd_head = arg_prepend(node1, node2->nd_head);
|
||
return node2;
|
||
default:
|
||
compile_error(PARSER_ARG "unhandled node %s", ruby_node_name(nd_type(node2)));
|
||
return 0;
|
||
}
|
||
}
|
||
static NODE *
|
||
symbol_lambda_gen(struct parser_params *parser, ID mid, NODE *args)
|
||
{
|
||
const struct vtable *vars = dyna_push();
|
||
ID tid = internal_id();
|
||
NODE *lambda = NEW_LAMBDA(0);
|
||
arg_var(tid);
|
||
lambda->nd_body = NEW_SCOPE(new_args(NEW_ARGS_AUX(tid, 1), 0, 0, 0, 0),
|
||
NEW_CALL(NEW_DVAR(tid), mid, args));
|
||
dyna_pop(vars);
|
||
return lambda;
|
||
}
|
||
static NODE *
|
||
splat_array(NODE* node)
|
||
{
|
||
if (nd_type(node) == NODE_SPLAT) node = node->nd_head;
|
w/test/ruby/test_symbol.rb | ||
---|---|---|
ary_ids = ary.collect{|x| x.object_id }
|
||
assert_equal ary_ids, ary.collect(&:object_id)
|
||
end
|
||
assert_equal [2, 4, 6], (1..3).map(&:*(2))
|
||
assert_equal %w(b e h), %w[abc def ghi].map(&:[1])
|
||
end
|
||
def test_call
|