From 759a63b6a3355b85e1e52b78810d66fd9ee7b838 Mon Sep 17 00:00:00 2001 From: matz Date: Wed, 27 Jul 2005 07:27:19 +0000 Subject: * 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 --- parse.y | 185 +++++++++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 132 insertions(+), 53 deletions(-) (limited to 'parse.y') 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 args when_args call_args call_args2 open_args paren_args opt_paren_args %type command_args aref_args opt_block_arg block_arg var_ref var_lhs %type mrhs superclass block_call block_command -%type f_arglist f_args f_optarg f_opt f_block_arg opt_f_block_arg +%type f_arglist f_args f_rest_arg f_optarg f_opt f_block_arg opt_f_block_arg %type assoc_list assocs assoc undef_list backref string_dvar %type for_var block_var opt_block_var block_var_def block_param -%type opt_bv_decl bv_decls bv_decl +%type opt_bv_decl bv_decls bv_decl lambda f_larglist lambda_body %type brace_block cmd_brace_block do_block lhs none fitem %type mlhs mlhs_head mlhs_basic mlhs_entry mlhs_item mlhs_node %type fsym variable sym symbol operation operation2 operation3 -%type cname fname op f_rest_arg -%type f_norm_arg f_arg +%type cname fname op f_norm_arg +%type f_arg /*%%%*/ /*% %type 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 - { - /*%%%*/ - $$ = dyna_push(); - $1 = ruby_sourceline; - /*% - %*/ - } - block_var_def {$$ = ruby_dyna_vars;} - compstmt - '}' - { - /*%%%*/ - $3->nd_body = block_append($3->nd_body, - dyna_init($5, $4)); - $$ = $3; - nd_set_type($3, NODE_LAMBDA); - nd_set_line($$, $1); - dyna_pop($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 : { + /*%%%*/ + $$ = dyna_push(); + /*% + %*/ + } + f_larglist + { + lex_state = EXPR_END; + $$ = ruby_dyna_vars; + } + lambda_body + { + /*%%%*/ + $$ = NEW_LAMBDA($2, $4); + dyna_pop($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; -- cgit v1.2.3