diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2011-07-10 13:38:17 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2011-07-10 13:38:17 +0000 |
commit | 577c03c7130e5776e0958d870e1aaf545d59e40e (patch) | |
tree | 9d8774fcf7fd764b527b3c2fb1079a2e4b1fd28b /parse.y | |
parent | ce698d4c0d4eb9c48650466b7f1566c869eb2e01 (diff) | |
download | ruby-577c03c7130e5776e0958d870e1aaf545d59e40e.tar.gz |
* parse.y (var_ref): distinguish vcall from local variable
references. based on a patch by Michael Edgar michael.j.edgar
AT dartmouth.edu. Bug #5002
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32498 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'parse.y')
-rw-r--r-- | parse.y | 70 |
1 files changed, 63 insertions, 7 deletions
@@ -426,6 +426,8 @@ static VALUE ripper_get_value(VALUE); #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 @@ static void token_info_pop(struct parser_params*, const char *token); %type <node> 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_item mlhs_node mlhs_post mlhs_inner -%type <id> fsym variable sym symbol operation operation2 operation3 +%type <id> fsym keyword_variable user_variable sym symbol operation operation2 operation3 %type <id> cname fname op f_rest_arg f_block_arg opt_f_block_arg f_norm_arg f_bad_arg /*%%%*/ /*% @@ -1601,10 +1603,14 @@ mlhs_post : mlhs_item } ; -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 @@ mlhs_node : variable } ; -lhs : variable +lhs : user_variable { $$ = assignable($1, 0); /*%%%*/ @@ -1680,6 +1686,15 @@ lhs : variable $$ = dispatch1(var_field, $$); %*/ } + | keyword_variable + { + $$ = assignable($1, 0); + /*%%%*/ + if (!$$) $$ = NEW_BEGIN(0); + /*% + $$ = dispatch1(var_field, $$); + %*/ + } | primary_value '[' opt_call_args rbracket { /*%%%*/ @@ -4257,12 +4272,14 @@ numeric : tINTEGER } ; -variable : tIDENTIFIER +user_variable : tIDENTIFIER | tIVAR | tGVAR | tCONSTANT | tCVAR - | keyword_nil {ifndef_ripper($$ = keyword_nil);} + ; + +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);} @@ -4271,7 +4288,20 @@ variable : tIDENTIFIER | keyword__ENCODING__ {ifndef_ripper($$ = keyword__ENCODING__);} ; -var_ref : variable +var_ref : user_variable + { + /*%%%*/ + if (!($$ = gettable($1))) $$ = NEW_BEGIN(0); + /*% + if (id_is_var(get_id($1))) { + $$ = dispatch1(var_ref, $1); + } + else { + $$ = dispatch1(vcall, $1); + } + %*/ + } + | keyword_variable { /*%%%*/ if (!($$ = gettable($1))) $$ = NEW_BEGIN(0); @@ -4281,7 +4311,7 @@ var_ref : variable } ; -var_lhs : variable +var_lhs : user_variable { $$ = assignable($1, 0); /*%%%*/ @@ -4289,6 +4319,14 @@ var_lhs : variable $$ = dispatch1(var_field, $$); %*/ } + | keyword_variable + { + $$ = assignable($1, 0); + /*%%%*/ + /*% + $$ = dispatch1(var_field, $$); + %*/ + } ; backref : tNTH_REF @@ -8242,6 +8280,24 @@ gettable_gen(struct parser_params *parser, ID id) compile_error(PARSER_ARG "identifier %s is not valid to get", rb_id2name(id)); return 0; } +#else /* !RIPPER */ +static int +id_is_var_gen(struct parser_params *parser, ID id) +{ + if (is_notop_id(id)) { + switch (id & ID_SCOPE_MASK) { + case ID_GLOBAL: case ID_INSTANCE: case ID_CONST: case ID_CLASS: + return 1; + case ID_LOCAL: + 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; +} #endif /* !RIPPER */ #ifdef RIPPER |