aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--parse.y20
-rw-r--r--test/ruby/test_iseq.rb2
-rw-r--r--test/ruby/test_pattern_matching.rb7
3 files changed, 26 insertions, 3 deletions
diff --git a/parse.y b/parse.y
index 14568d98c3..33fa0e7944 100644
--- a/parse.y
+++ b/parse.y
@@ -1127,7 +1127,7 @@ static void token_info_warn(struct parser_params *p, const char *token, token_in
%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
@@ -1537,7 +1537,23 @@ expr : command_call
{
$$ = call_uni_op(p, method_cond(p, $2, &@2), '!', &@1, &@$);
}
- | arg
+ | arg keyword_in
+ {
+ SET_LEX_STATE(EXPR_BEG|EXPR_LABEL);
+ p->command_start = FALSE;
+ $<num>$ = p->in_kwarg;
+ p->in_kwarg = 1;
+ }
+ p_top_expr_body
+ {
+ p->in_kwarg = !!$<num>2;
+ /*%%%*/
+ $$ = NEW_CASE3($1, NEW_IN($4, NEW_TRUE(&@4), NEW_FALSE(&@4), &@4), &@$);
+ rb_warn0L(nd_line($$), "Pattern matching is experimental, and the behavior may change in future versions of Ruby!");
+ /*% %*/
+ /*% ripper: case!($1, in!($4, Qnil, Qnil)) %*/
+ }
+ | arg %prec tLBRACE_ARG
;
expr_value : expr
diff --git a/test/ruby/test_iseq.rb b/test/ruby/test_iseq.rb
index 1a1abc627b..2aa6966785 100644
--- a/test/ruby/test_iseq.rb
+++ b/test/ruby/test_iseq.rb
@@ -434,7 +434,7 @@ class TestISeq < Test::Unit::TestCase
end
def test_to_binary_pattern_matching
- code = "case foo in []; end"
+ code = "case foo; in []; end"
iseq = compile(code)
assert_include(iseq.disasm, "TypeError")
assert_include(iseq.disasm, "NoMatchingPatternError")
diff --git a/test/ruby/test_pattern_matching.rb b/test/ruby/test_pattern_matching.rb
index 1f209b0081..cb87529ccf 100644
--- a/test/ruby/test_pattern_matching.rb
+++ b/test/ruby/test_pattern_matching.rb
@@ -1180,6 +1180,13 @@ END
end
end
end
+
+ ################################################################
+
+ def test_modifier_in
+ assert_equal true, (1 in a)
+ assert_equal 1, a
+ end
end
END_of_GUARD
$VERBOSE = verbose