summaryrefslogtreecommitdiff
path: root/parse.y
diff options
context:
space:
mode:
authorKazuki Tsujimoto <kazuki@callcc.net>2020-12-13 11:50:14 +0900
committerKazuki Tsujimoto <kazuki@callcc.net>2020-12-13 11:51:49 +0900
commit88f3ce12d32ffbef983b0950743c20253ea2d0c6 (patch)
tree8ff07aa837af75a4e389ef30d139fb391be63e0f /parse.y
parenta8cf526ae99c9e0823cd8c7c5ac96e43061fafa6 (diff)
Reintroduce `expr in pat` [Feature #17371]
Diffstat (limited to 'parse.y')
-rw-r--r--parse.y29
1 files changed, 24 insertions, 5 deletions
diff --git a/parse.y b/parse.y
index bc33c6a23f..ff413d8b1b 100644
--- a/parse.y
+++ b/parse.y
@@ -502,7 +502,7 @@ static NODE *new_find_pattern(struct parser_params *p, NODE *constant, NODE *fnd
static NODE *new_find_pattern_tail(struct parser_params *p, ID pre_rest_arg, NODE *args, ID post_rest_arg, const YYLTYPE *loc);
static NODE *new_hash_pattern(struct parser_params *p, NODE *constant, NODE *hshptn, const YYLTYPE *loc);
static NODE *new_hash_pattern_tail(struct parser_params *p, NODE *kw_args, ID kw_rest_arg, const YYLTYPE *loc);
-static void warn_one_line_pattern_matching(struct parser_params *p, NODE *node, NODE *pattern);
+static void warn_one_line_pattern_matching(struct parser_params *p, NODE *node, NODE *pattern, bool right_assign);
static NODE *new_kw_arg(struct parser_params *p, NODE *k, const YYLTYPE *loc);
static NODE *args_with_numbered(struct parser_params*,NODE*,int);
@@ -1243,7 +1243,7 @@ static int looking_at_eol_p(struct parser_params *p);
%nonassoc tLOWEST
%nonassoc tLBRACE_ARG
-%nonassoc modifier_if modifier_unless modifier_while modifier_until
+%nonassoc modifier_if modifier_unless modifier_while modifier_until keyword_in
%left keyword_or keyword_and
%right keyword_not
%nonassoc keyword_defined
@@ -1662,7 +1662,26 @@ expr : command_call
p->ctxt.in_kwarg = $<ctxt>3.in_kwarg;
/*%%%*/
$$ = NEW_CASE3($1, NEW_IN($5, 0, 0, &@5), &@$);
- warn_one_line_pattern_matching(p, $$, $5);
+ warn_one_line_pattern_matching(p, $$, $5, true);
+ /*% %*/
+ /*% ripper: case!($1, in!($5, Qnil, Qnil)) %*/
+ }
+ | arg keyword_in
+ {
+ value_expr($1);
+ SET_LEX_STATE(EXPR_BEG|EXPR_LABEL);
+ p->command_start = FALSE;
+ $<ctxt>$ = p->ctxt;
+ p->ctxt.in_kwarg = 1;
+ }
+ {$<tbl>$ = push_pvtbl(p);}
+ p_expr
+ {pop_pvtbl(p, $<tbl>4);}
+ {
+ p->ctxt.in_kwarg = $<ctxt>3.in_kwarg;
+ /*%%%*/
+ $$ = NEW_CASE3($1, NEW_IN($5, NEW_TRUE(&@5), NEW_FALSE(&@5), &@5), &@$);
+ warn_one_line_pattern_matching(p, $$, $5, false);
/*% %*/
/*% ripper: case!($1, in!($5, Qnil, Qnil)) %*/
}
@@ -11689,13 +11708,13 @@ new_hash_pattern_tail(struct parser_params *p, NODE *kw_args, ID kw_rest_arg, co
}
static void
-warn_one_line_pattern_matching(struct parser_params *p, NODE *node, NODE *pattern)
+warn_one_line_pattern_matching(struct parser_params *p, NODE *node, NODE *pattern, bool right_assign)
{
enum node_type type;
type = nd_type(pattern);
if (rb_warning_category_enabled_p(RB_WARN_CATEGORY_EXPERIMENTAL) &&
- !(type == NODE_LASGN || type == NODE_DASGN || type == NODE_DASGN_CURR))
+ !(right_assign && (type == NODE_LASGN || type == NODE_DASGN || type == NODE_DASGN_CURR)))
rb_warn0L(nd_line(node), "One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!");
}