diff --git a/snapshots/case_in_in.txt b/snapshots/case_in_in.txt new file mode 100644 index 0000000000..0fcedb0e89 --- /dev/null +++ b/snapshots/case_in_in.txt @@ -0,0 +1,81 @@ +@ ProgramNode (location: (1,0)-(4,3)) +├── flags: ∅ +├── locals: [:event] +└── statements: + @ StatementsNode (location: (1,0)-(4,3)) + ├── flags: ∅ + └── body: (length: 1) + └── @ CaseMatchNode (location: (1,0)-(4,3)) + ├── flags: newline + ├── predicate: + │ @ CallNode (location: (1,5)-(1,9)) + │ ├── flags: variable_call, ignore_visibility + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── name: :args + │ ├── message_loc: (1,5)-(1,9) = "args" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── equal_loc: ∅ + │ └── block: ∅ + ├── conditions: (length: 1) + │ └── @ InNode (location: (2,0)-(3,25)) + │ ├── flags: ∅ + │ ├── pattern: + │ │ @ ArrayPatternNode (location: (2,3)-(2,10)) + │ │ ├── flags: ∅ + │ │ ├── constant: ∅ + │ │ ├── requireds: (length: 1) + │ │ │ └── @ LocalVariableTargetNode (location: (2,4)-(2,9)) + │ │ │ ├── flags: ∅ + │ │ │ ├── name: :event + │ │ │ └── depth: 0 + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── opening_loc: (2,3)-(2,4) = "[" + │ │ └── closing_loc: (2,9)-(2,10) = "]" + │ ├── statements: + │ │ @ StatementsNode (location: (3,2)-(3,25)) + │ │ ├── flags: ∅ + │ │ └── body: (length: 1) + │ │ └── @ MatchPredicateNode (location: (3,2)-(3,25)) + │ │ ├── flags: newline + │ │ ├── value: + │ │ │ @ CallNode (location: (3,2)-(3,15)) + │ │ │ ├── flags: ∅ + │ │ │ ├── receiver: + │ │ │ │ @ CallNode (location: (3,2)-(3,9)) + │ │ │ │ ├── flags: variable_call, ignore_visibility + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── name: :context + │ │ │ │ ├── message_loc: (3,2)-(3,9) = "context" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── equal_loc: ∅ + │ │ │ │ └── block: ∅ + │ │ │ ├── call_operator_loc: (3,9)-(3,10) = "." + │ │ │ ├── name: :event + │ │ │ ├── message_loc: (3,10)-(3,15) = "event" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── equal_loc: ∅ + │ │ │ └── block: ∅ + │ │ ├── pattern: + │ │ │ @ PinnedVariableNode (location: (3,19)-(3,25)) + │ │ │ ├── flags: ∅ + │ │ │ ├── variable: + │ │ │ │ @ LocalVariableReadNode (location: (3,20)-(3,25)) + │ │ │ │ ├── flags: ∅ + │ │ │ │ ├── name: :event + │ │ │ │ └── depth: 0 + │ │ │ └── operator_loc: (3,19)-(3,20) = "^" + │ │ └── operator_loc: (3,16)-(3,18) = "in" + │ ├── in_loc: (2,0)-(2,2) = "in" + │ └── then_loc: ∅ + ├── else_clause: ∅ + ├── case_keyword_loc: (1,0)-(1,4) = "case" + └── end_keyword_loc: (4,0)-(4,3) = "end" diff --git a/src/prism.c b/src/prism.c index 3b61472cbc..2eb09675ad 100644 --- a/src/prism.c +++ b/src/prism.c @@ -21674,12 +21674,6 @@ parse_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool acc ) { node = parse_expression_infix(parser, node, binding_power, current_binding_powers.right, accepts_command_call, (uint16_t) (depth + 1)); - if (context_terminator(parser->current_context->context, &parser->current)) { - // If this token terminates the current context, then we need to - // stop parsing the expression, as it has become a statement. - return node; - } - switch (PM_NODE_TYPE(node)) { case PM_MULTI_WRITE_NODE: // Multi-write nodes are statements, and cannot be followed by @@ -21792,6 +21786,17 @@ parse_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool acc break; } } + + if (context_terminator(parser->current_context->context, &parser->current)) { + pm_binding_powers_t next_binding_powers = pm_binding_powers[parser->current.type]; + if ( + !next_binding_powers.binary || + binding_power > next_binding_powers.left || + (PM_NODE_TYPE_P(node, PM_CALL_NODE) && pm_call_node_command_p((pm_call_node_t *) node)) + ) { + return node; + } + } } return node; diff --git a/test/prism/fixtures/case_in_in.txt b/test/prism/fixtures/case_in_in.txt new file mode 100644 index 0000000000..a5f9e4ec41 --- /dev/null +++ b/test/prism/fixtures/case_in_in.txt @@ -0,0 +1,4 @@ +case args +in [event] + context.event in ^event +end