summaryrefslogtreecommitdiff
path: root/parse.y
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2005-07-27 07:27:19 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2005-07-27 07:27:19 +0000
commit759a63b6a3355b85e1e52b78810d66fd9ee7b838 (patch)
treeec585ba5c983af89ff164ef8204bde6ae9b0add5 /parse.y
parent2ea2d95e8196b61a43915870fb2e1eefc3fc2554 (diff)
* parse.y (lambda): Perl6 style -> lambda expression. [NEW]
[VERY EXPERIMENTAL] * gc.c (id2ref): must not assign pointers to long int. use LONG_LONG instead if SIZEOF_LONG < SIZEOF_VOIDP. [ruby-talk:149645] * ruby.h: use LONG_LONG to simplify the change. [ruby-talk:149645] * dir.c (dir_each): rewinddir(3) before iteration. [ruby-talk:149628] * eval.c (rb_f_throw): replace all '0x%lx' by '%p'. [ruby-talk:149553] * missing/vsnprintf.c (BSD_vfprintf): '%p' need to handle 64bit size pointer. [ruby-talk:149553] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@8847 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'parse.y')
-rw-r--r--parse.y185
1 files changed, 132 insertions, 53 deletions
diff --git a/parse.y b/parse.y
index 3ac72387b0..4c28192b25 100644
--- a/parse.y
+++ b/parse.y
@@ -505,15 +505,15 @@ static void ripper_compile_error _((struct parser_params*, const char *fmt, ...)
%type <node> args when_args call_args call_args2 open_args paren_args opt_paren_args
%type <node> command_args aref_args opt_block_arg block_arg var_ref var_lhs
%type <node> mrhs superclass block_call block_command
-%type <node> f_arglist f_args f_optarg f_opt f_block_arg opt_f_block_arg
+%type <node> f_arglist f_args f_rest_arg f_optarg f_opt f_block_arg opt_f_block_arg
%type <node> assoc_list assocs assoc undef_list backref string_dvar
%type <node> for_var block_var opt_block_var block_var_def block_param
-%type <node> opt_bv_decl bv_decls bv_decl
+%type <node> opt_bv_decl bv_decls bv_decl lambda f_larglist lambda_body
%type <node> brace_block cmd_brace_block do_block lhs none fitem
%type <node> mlhs mlhs_head mlhs_basic mlhs_entry mlhs_item mlhs_node
%type <id> fsym variable sym symbol operation operation2 operation3
-%type <id> cname fname op f_rest_arg
-%type <num> f_norm_arg f_arg
+%type <id> cname fname op f_norm_arg
+%type <val> f_arg
/*%%%*/
/*%
%type <val> program reswords then do dot_or_colon
@@ -544,6 +544,8 @@ static void ripper_compile_error _((struct parser_params*, const char *fmt, ...)
%token tLBRACE_ARG /* { */
%token tSTAR /* * */
%token tAMPER /* & */
+%token tLAMBDA /* -> */
+%token tLAMBDA_ARG /* -> */
%token tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tWORDS_BEG tQWORDS_BEG
%token tSTRING_DBEG tSTRING_DVAR tSTRING_END
@@ -1033,11 +1035,6 @@ expr : command_call
$$ = dispatch2(unary, ID2SYM('!'), $2);
%*/
}
- | do_block
- {
- $$ = $1;
- nd_set_type($$, NODE_LAMBDA);
- }
| arg
;
@@ -2531,29 +2528,6 @@ primary : literal
$$ = dispatch1(hash, escape_Qundef($2));
%*/
}
- | tLBRACE
- {
- /*%%%*/
- $<vars>$ = dyna_push();
- $<num>1 = ruby_sourceline;
- /*%
- %*/
- }
- block_var_def {$<vars>$ = ruby_dyna_vars;}
- compstmt
- '}'
- {
- /*%%%*/
- $3->nd_body = block_append($3->nd_body,
- dyna_init($5, $<vars>4));
- $$ = $3;
- nd_set_type($3, NODE_LAMBDA);
- nd_set_line($$, $<num>1);
- dyna_pop($<vars>2);
- /*%
- $$ = dispatch2(brace_block, escape_Qundef($3), $5);
- %*/
- }
| kRETURN
{
/*%%%*/
@@ -2619,6 +2593,11 @@ primary : literal
$$ = dispatch2(iter_block, $1, $2);
%*/
}
+ | tLAMBDA
+ lambda
+ {
+ $$ = $2;
+ }
| kIF expr_value then
compstmt
if_tail
@@ -3185,6 +3164,84 @@ bv_decl : tIDENTIFIER
}
;
+lambda : {
+ /*%%%*/
+ $<vars>$ = dyna_push();
+ /*%
+ %*/
+ }
+ f_larglist
+ {
+ lex_state = EXPR_END;
+ $<vars>$ = ruby_dyna_vars;
+ }
+ lambda_body
+ {
+ /*%%%*/
+ $$ = NEW_LAMBDA($2, $4);
+ dyna_pop($<vars>1);
+ /*%
+ $$ = dispatch2(lambda, $2, $4);
+ %*/
+ }
+ ;
+
+f_larglist : '(' f_args rparen
+ {
+ /*%%%*/
+ $$ = $2;
+ /*%
+ $$ = dispatch1(paren, $2);
+ %*/
+ }
+ | f_arg opt_terms
+ {
+ /*%%%*/
+ $$ = NEW_ARGS($1, 0, 0);
+ /*%
+ $$ = dispatch4(params, $1, Qnil, Qnil, Qnil);
+ %*/
+ }
+ | f_arg ',' f_rest_arg opt_terms
+ {
+ /*%%%*/
+ $$ = NEW_ARGS($1, 0, $3);
+ /*%
+ $$ = dispatch4(params, $1, Qnil, $3, Qnil);
+ %*/
+ }
+ | f_rest_arg opt_terms
+ {
+ /*%%%*/
+ $$ = NEW_ARGS(0, 0, $1);
+ /*%
+ $$ = dispatch4(params, Qnil, Qnil, $1, Qnil);
+ %*/
+ }
+ | /* none */
+ {
+ /*%%%*/
+ $$ = NEW_ARGS(0, 0, 0);
+ /*%
+ $$ = dispatch4(params, Qnil, Qnil, Qnil, Qnil);
+ %*/
+ }
+ ;
+
+lambda_body : '{'
+ compstmt
+ '}'
+ {
+ $$ = $2;
+ }
+ | kDO
+ compstmt
+ kEND
+ {
+ $$ = $2;
+ }
+ ;
+
do_block : kDO_BLOCK
{
/*%%%*/
@@ -3375,6 +3432,17 @@ brace_block : '{'
$$ = dispatch2(do_block, escape_Qundef($3), $5);
%*/
}
+ | tLAMBDA_ARG
+ lambda
+ {
+ /*%%%*/
+ $$ = $2;
+ nd_set_type($$, NODE_ITER);
+ /*%
+ $$ = $2;
+ $$ = dispatch1(do_block, $2);
+ %*/
+ }
;
case_body : kWHEN when_args then
@@ -3922,7 +3990,7 @@ f_args : f_arg ',' f_optarg ',' f_rest_arg opt_f_block_arg
| f_arg ',' f_optarg opt_f_block_arg
{
/*%%%*/
- $$ = block_append(NEW_ARGS($1, $3, -1), $4);
+ $$ = block_append(NEW_ARGS($1, $3, 0), $4);
/*%
$$ = dispatch4(params, $1, $3, Qnil, escape_Qundef($4));
%*/
@@ -3938,7 +4006,7 @@ f_args : f_arg ',' f_optarg ',' f_rest_arg opt_f_block_arg
| f_arg opt_f_block_arg
{
/*%%%*/
- $$ = block_append(NEW_ARGS($1, 0, -1), $2);
+ $$ = block_append(NEW_ARGS($1, 0, 0), $2);
/*%
$$ = dispatch4(params, $1, Qnil, Qnil, escape_Qundef($2));
%*/
@@ -3954,7 +4022,7 @@ f_args : f_arg ',' f_optarg ',' f_rest_arg opt_f_block_arg
| f_optarg opt_f_block_arg
{
/*%%%*/
- $$ = block_append(NEW_ARGS(0, $1, -1), $2);
+ $$ = block_append(NEW_ARGS(0, $1, 0), $2);
/*%
$$ = dispatch4(params, Qnil, $1, Qnil, escape_Qundef($2));
%*/
@@ -3970,7 +4038,7 @@ f_args : f_arg ',' f_optarg ',' f_rest_arg opt_f_block_arg
| f_block_arg
{
/*%%%*/
- $$ = block_append(NEW_ARGS(0, 0, -1), $1);
+ $$ = block_append(NEW_ARGS(0, 0, 0), $1);
/*%
$$ = dispatch4(params, Qnil, Qnil, Qnil, $1);
%*/
@@ -3978,7 +4046,7 @@ f_args : f_arg ',' f_optarg ',' f_rest_arg opt_f_block_arg
| /* none */
{
/*%%%*/
- $$ = NEW_ARGS(0, 0, -1);
+ $$ = NEW_ARGS(0, 0, 0);
/*%
$$ = dispatch4(params, Qnil, Qnil, Qnil, Qnil);
%*/
@@ -4024,8 +4092,13 @@ f_norm_arg : tCONSTANT
yyerror("formal argument must be local variable");
else if (local_id($1))
yyerror("duplicate argument name");
- local_cnt($1);
- $$ = 1;
+ if (dyna_in_block()) {
+ dyna_var($1);
+ }
+ else {
+ local_cnt($1);
+ }
+ $$ = $1;
/*%
$$ = $1;
%*/
@@ -4033,18 +4106,11 @@ f_norm_arg : tCONSTANT
;
f_arg : f_norm_arg
- /*%c%*/
- /*%c
- { $$ = rb_ary_new3(1, $1); }
- %*/
+ { $$ = rb_ary_new3(1, ID2SYM($1)); }
| f_arg ',' f_norm_arg
{
- /*%%%*/
- $$ += 1;
- /*%
$$ = $1;
- rb_ary_push($$, $3);
- %*/
+ rb_ary_push($$, ID2SYM($3));
}
;
@@ -4092,7 +4158,7 @@ f_rest_arg : restarg_mark tIDENTIFIER
yyerror("rest argument must be local variable");
else if (local_id($2))
yyerror("duplicate rest argument name");
- $$ = local_cnt($2);
+ $$ = assignable($2, 0);
/*%
$$ = dispatch1(restparam, $2);
%*/
@@ -4100,7 +4166,7 @@ f_rest_arg : restarg_mark tIDENTIFIER
| restarg_mark
{
/*%%%*/
- $$ = local_append((ID)0);
+ $$ = (NODE*)Qnil;
/*%
$$ = dispatch1(restparam, Qnil);
%*/
@@ -6000,6 +6066,19 @@ parser_yylex(parser)
lex_state = EXPR_BEG;
return tOP_ASGN;
}
+ if (c == '>') {
+ enum lex_state_e state = lex_state;
+ lex_state = EXPR_ARG;
+ switch (state) {
+ case EXPR_CMDARG:
+ case EXPR_ENDARG:
+ case EXPR_ARG:
+ case EXPR_END:
+ return tLAMBDA_ARG;
+ default:
+ return tLAMBDA;
+ }
+ }
if (IS_BEG() ||
(IS_ARG() && space_seen && !ISSPACE(c))) {
if (IS_ARG()) arg_ambiguous();
@@ -8692,7 +8771,7 @@ ripper_validate_object(self, x)
if (FIXNUM_P(x)) return x;
if (SYMBOL_P(x)) return x;
if (!rb_is_pointer_to_heap(x))
- rb_raise(rb_eArgError, "invalid pointer: 0x%x", x);
+ rb_raise(rb_eArgError, "invalid pointer: %p", x);
switch (TYPE(x)) {
case T_STRING:
case T_OBJECT:
@@ -8701,9 +8780,9 @@ ripper_validate_object(self, x)
case T_FLOAT:
return x;
case T_NODE:
- rb_raise(rb_eArgError, "NODE given: 0x%x", x);
+ rb_raise(rb_eArgError, "NODE given: %p", x);
default:
- rb_raise(rb_eArgError, "wrong type of ruby object: 0x%x (%s)",
+ rb_raise(rb_eArgError, "wrong type of ruby object: %p (%s)",
x, rb_obj_classname(x));
}
return x;