summaryrefslogtreecommitdiff
path: root/parse.y
diff options
context:
space:
mode:
Diffstat (limited to 'parse.y')
-rw-r--r--parse.y70
1 files changed, 63 insertions, 7 deletions
diff --git a/parse.y b/parse.y
index ffa649b7af..aca2b6ac3e 100644
--- a/parse.y
+++ b/parse.y
@@ -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