Index: parse.y =================================================================== --- parse.y (revision 32466) +++ parse.y (working copy) @@ -426,6 +426,8 @@ #define get_value(val) ripper_get_value(val) static VALUE assignable_gen(struct parser_params*,VALUE); #define assignable(lhs,node) assignable_gen(parser, (lhs)) +static int id_is_var_gen(struct parser_params *parser, ID id); +#define id_is_var(id) id_is_var_gen(parser, (id)) #endif /* !RIPPER */ static ID formal_argument_gen(struct parser_params*, ID); @@ -699,7 +701,7 @@ %type lambda f_larglist lambda_body %type brace_block cmd_brace_block do_block lhs none fitem %type mlhs mlhs_head mlhs_basic mlhs_item mlhs_node mlhs_post mlhs_inner -%type fsym variable sym symbol operation operation2 operation3 +%type fsym keyword_variable user_variable sym symbol operation operation2 operation3 %type cname fname op f_rest_arg f_block_arg opt_f_block_arg f_norm_arg f_bad_arg /*%%%*/ /*% @@ -1601,10 +1603,14 @@ } ; -mlhs_node : variable +mlhs_node : user_variable { $$ = assignable($1, 0); } + | keyword_variable + { + $$ = assignable($1, 0); + } | primary_value '[' opt_call_args rbracket { /*%%%*/ @@ -1671,7 +1677,7 @@ } ; -lhs : variable +lhs : user_variable { $$ = assignable($1, 0); /*%%%*/ @@ -1680,6 +1686,15 @@ $$ = dispatch1(var_field, $$); %*/ } + | keyword_variable + { + $$ = assignable($1, 0); + /*%%%*/ + if (!$$) $$ = NEW_BEGIN(0); + /*% + $$ = dispatch1(var_field, $$); + %*/ + } | primary_value '[' opt_call_args rbracket { /*%%%*/ @@ -4257,31 +4272,45 @@ } ; -variable : tIDENTIFIER - | tIVAR - | tGVAR - | tCONSTANT - | tCVAR - | keyword_nil {ifndef_ripper($$ = keyword_nil);} - | keyword_self {ifndef_ripper($$ = keyword_self);} - | keyword_true {ifndef_ripper($$ = keyword_true);} - | keyword_false {ifndef_ripper($$ = keyword_false);} - | keyword__FILE__ {ifndef_ripper($$ = keyword__FILE__);} - | keyword__LINE__ {ifndef_ripper($$ = keyword__LINE__);} - | keyword__ENCODING__ {ifndef_ripper($$ = keyword__ENCODING__);} - ; +keyword_variable : keyword_nil {ifndef_ripper($$ = keyword_nil);} + | keyword_self {ifndef_ripper($$ = keyword_self);} + | keyword_true {ifndef_ripper($$ = keyword_true);} + | keyword_false {ifndef_ripper($$ = keyword_false);} + | keyword__FILE__ {ifndef_ripper($$ = keyword__FILE__);} + | keyword__LINE__ {ifndef_ripper($$ = keyword__LINE__);} + | keyword__ENCODING__ {ifndef_ripper($$ = keyword__ENCODING__);} + ; -var_ref : variable +user_variable : tIDENTIFIER + | tIVAR + | tGVAR + | tCONSTANT + | tCVAR + ; + +var_ref : user_variable { /*%%%*/ if (!($$ = gettable($1))) $$ = NEW_BEGIN(0); /*% - $$ = dispatch1(var_ref, $1); + if (id_is_var(get_id($1))) { + $$ = dispatch1(var_ref, $1); + } else { + $$ = dispatch1(vcall, $1); + } %*/ } + | keyword_variable + { + /*%%%*/ + if (!($$ = gettable($1))) $$ = NEW_BEGIN(0); + /*% + $$ = dispatch1(var_ref, $1); + %*/ + } ; -var_lhs : variable +var_lhs : user_variable { $$ = assignable($1, 0); /*%%%*/ @@ -4289,6 +4318,14 @@ $$ = dispatch1(var_field, $$); %*/ } + | keyword_variable + { + $$ = assignable($1, 0); + /*%%%*/ + /*% + $$ = dispatch1(var_field, $$); + %*/ + } ; backref : tNTH_REF @@ -7894,7 +7931,25 @@ return t; } -#ifndef RIPPER +#ifdef RIPPER + +static int +id_is_var_gen(struct parser_params *parser, ID id) +{ + if (is_global_id(id) || is_instance_id(id) || is_const_id(id) || is_class_id(id)) { + return 1; + } + else if (is_local_id(id)) { + if (dyna_in_block() && dvar_defined(id)) return 1; + if (local_id(id)) return 1; + /* method call without arguments */ + return 0; + } + compile_error(PARSER_ARG "identifier %s is not valid to get", rb_id2name(id)); + return 0; +} + +#else /* !RIPPER */ static NODE* node_newnode(struct parser_params *parser, enum node_type type, VALUE a0, VALUE a1, VALUE a2) {