diff --git a/snapshots/for.txt b/snapshots/for.txt index 5558209826..3c8d724d62 100644 --- a/snapshots/for.txt +++ b/snapshots/for.txt @@ -1,10 +1,10 @@ -@ ProgramNode (location: (1,0)-(19,22)) +@ ProgramNode (location: (1,0)-(21,25)) ├── flags: ∅ -├── locals: [:i, :j, :k] +├── locals: [:i, :j, :k, :x, :b] └── statements: - @ StatementsNode (location: (1,0)-(19,22)) + @ StatementsNode (location: (1,0)-(21,25)) ├── flags: ∅ - └── body: (length: 6) + └── body: (length: 7) ├── @ ForNode (location: (1,0)-(3,3)) │ ├── flags: newline │ ├── index: @@ -186,34 +186,83 @@ │ ├── in_keyword_loc: (15,6)-(15,8) = "in" │ ├── do_keyword_loc: (15,15)-(15,17) = "do" │ └── end_keyword_loc: (17,0)-(17,3) = "end" - └── @ ForNode (location: (19,0)-(19,22)) + ├── @ ForNode (location: (19,0)-(19,22)) + │ ├── flags: newline + │ ├── index: + │ │ @ LocalVariableTargetNode (location: (19,4)-(19,5)) + │ │ ├── flags: ∅ + │ │ ├── name: :i + │ │ └── depth: 0 + │ ├── collection: + │ │ @ RangeNode (location: (19,9)-(19,14)) + │ │ ├── flags: static_literal + │ │ ├── left: + │ │ │ @ IntegerNode (location: (19,9)-(19,10)) + │ │ │ ├── flags: static_literal, decimal + │ │ │ └── value: 1 + │ │ ├── right: + │ │ │ @ IntegerNode (location: (19,12)-(19,14)) + │ │ │ ├── flags: static_literal, decimal + │ │ │ └── value: 10 + │ │ └── operator_loc: (19,10)-(19,12) = ".." + │ ├── statements: + │ │ @ StatementsNode (location: (19,16)-(19,17)) + │ │ ├── flags: ∅ + │ │ └── body: (length: 1) + │ │ └── @ LocalVariableReadNode (location: (19,16)-(19,17)) + │ │ ├── flags: newline + │ │ ├── name: :i + │ │ └── depth: 0 + │ ├── for_keyword_loc: (19,0)-(19,3) = "for" + │ ├── in_keyword_loc: (19,6)-(19,8) = "in" + │ ├── do_keyword_loc: ∅ + │ └── end_keyword_loc: (19,19)-(19,22) = "end" + └── @ ForNode (location: (21,0)-(21,25)) ├── flags: newline ├── index: - │ @ LocalVariableTargetNode (location: (19,4)-(19,5)) + │ @ LocalVariableTargetNode (location: (21,4)-(21,5)) │ ├── flags: ∅ - │ ├── name: :i + │ ├── name: :x │ └── depth: 0 ├── collection: - │ @ RangeNode (location: (19,9)-(19,14)) - │ ├── flags: static_literal - │ ├── left: - │ │ @ IntegerNode (location: (19,9)-(19,10)) - │ │ ├── flags: static_literal, decimal - │ │ └── value: 1 - │ ├── right: - │ │ @ IntegerNode (location: (19,12)-(19,14)) - │ │ ├── flags: static_literal, decimal - │ │ └── value: 10 - │ └── operator_loc: (19,10)-(19,12) = ".." + │ @ MatchPredicateNode (location: (21,9)-(21,16)) + │ ├── flags: ∅ + │ ├── value: + │ │ @ CallNode (location: (21,9)-(21,10)) + │ │ ├── flags: variable_call, ignore_visibility + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── name: :a + │ │ ├── message_loc: (21,9)-(21,10) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── equal_loc: ∅ + │ │ └── block: ∅ + │ ├── pattern: + │ │ @ ArrayPatternNode (location: (21,14)-(21,16)) + │ │ ├── flags: ∅ + │ │ ├── constant: ∅ + │ │ ├── requireds: (length: 1) + │ │ │ └── @ LocalVariableTargetNode (location: (21,14)-(21,15)) + │ │ │ ├── flags: ∅ + │ │ │ ├── name: :b + │ │ │ └── depth: 0 + │ │ ├── rest: + │ │ │ @ ImplicitRestNode (location: (21,15)-(21,16)) + │ │ │ └── flags: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── opening_loc: ∅ + │ │ └── closing_loc: ∅ + │ └── operator_loc: (21,11)-(21,13) = "in" ├── statements: - │ @ StatementsNode (location: (19,16)-(19,17)) + │ @ StatementsNode (location: (21,20)-(21,21)) │ ├── flags: ∅ │ └── body: (length: 1) - │ └── @ LocalVariableReadNode (location: (19,16)-(19,17)) - │ ├── flags: newline - │ ├── name: :i - │ └── depth: 0 - ├── for_keyword_loc: (19,0)-(19,3) = "for" - ├── in_keyword_loc: (19,6)-(19,8) = "in" - ├── do_keyword_loc: ∅ - └── end_keyword_loc: (19,19)-(19,22) = "end" + │ └── @ IntegerNode (location: (21,20)-(21,21)) + │ ├── flags: newline, static_literal, decimal + │ └── value: 1 + ├── for_keyword_loc: (21,0)-(21,3) = "for" + ├── in_keyword_loc: (21,6)-(21,8) = "in" + ├── do_keyword_loc: (21,17)-(21,19) = "do" + └── end_keyword_loc: (21,22)-(21,25) = "end" diff --git a/snapshots/until.txt b/snapshots/until.txt index 55b3beafa8..aa0c9935c6 100644 --- a/snapshots/until.txt +++ b/snapshots/until.txt @@ -1,10 +1,10 @@ -@ ProgramNode (location: (1,0)-(13,20)) +@ ProgramNode (location: (1,0)-(15,22)) ├── flags: ∅ -├── locals: [:baz] +├── locals: [:baz, :b] └── statements: - @ StatementsNode (location: (1,0)-(13,20)) + @ StatementsNode (location: (1,0)-(15,22)) ├── flags: ∅ - └── body: (length: 7) + └── body: (length: 8) ├── @ UntilNode (location: (1,0)-(1,18)) │ ├── flags: newline │ ├── keyword_loc: (1,0)-(1,5) = "until" @@ -172,44 +172,87 @@ │ ├── closing_loc: ∅ │ ├── equal_loc: ∅ │ └── block: ∅ - └── @ WhileNode (location: (13,0)-(13,20)) + ├── @ WhileNode (location: (13,0)-(13,20)) + │ ├── flags: newline + │ ├── keyword_loc: (13,4)-(13,9) = "while" + │ ├── do_keyword_loc: ∅ + │ ├── closing_loc: ∅ + │ ├── predicate: + │ │ @ MatchPredicateNode (location: (13,10)-(13,20)) + │ │ ├── flags: ∅ + │ │ ├── value: + │ │ │ @ CallNode (location: (13,10)-(13,13)) + │ │ │ ├── flags: variable_call, ignore_visibility + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── name: :bar + │ │ │ ├── message_loc: (13,10)-(13,13) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── equal_loc: ∅ + │ │ │ └── block: ∅ + │ │ ├── pattern: + │ │ │ @ LocalVariableTargetNode (location: (13,17)-(13,20)) + │ │ │ ├── flags: ∅ + │ │ │ ├── name: :baz + │ │ │ └── depth: 0 + │ │ └── operator_loc: (13,14)-(13,16) = "in" + │ └── statements: + │ @ StatementsNode (location: (13,0)-(13,3)) + │ ├── flags: ∅ + │ └── body: (length: 1) + │ └── @ CallNode (location: (13,0)-(13,3)) + │ ├── flags: newline, variable_call, ignore_visibility + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── name: :foo + │ ├── message_loc: (13,0)-(13,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── equal_loc: ∅ + │ └── block: ∅ + └── @ UntilNode (location: (15,0)-(15,22)) ├── flags: newline - ├── keyword_loc: (13,4)-(13,9) = "while" - ├── do_keyword_loc: ∅ - ├── closing_loc: ∅ + ├── keyword_loc: (15,0)-(15,5) = "until" + ├── do_keyword_loc: (15,14)-(15,16) = "do" + ├── closing_loc: (15,19)-(15,22) = "end" ├── predicate: - │ @ MatchPredicateNode (location: (13,10)-(13,20)) + │ @ MatchPredicateNode (location: (15,6)-(15,13)) │ ├── flags: ∅ │ ├── value: - │ │ @ CallNode (location: (13,10)-(13,13)) + │ │ @ CallNode (location: (15,6)-(15,7)) │ │ ├── flags: variable_call, ignore_visibility │ │ ├── receiver: ∅ │ │ ├── call_operator_loc: ∅ - │ │ ├── name: :bar - │ │ ├── message_loc: (13,10)-(13,13) = "bar" + │ │ ├── name: :a + │ │ ├── message_loc: (15,6)-(15,7) = "a" │ │ ├── opening_loc: ∅ │ │ ├── arguments: ∅ │ │ ├── closing_loc: ∅ │ │ ├── equal_loc: ∅ │ │ └── block: ∅ │ ├── pattern: - │ │ @ LocalVariableTargetNode (location: (13,17)-(13,20)) + │ │ @ ArrayPatternNode (location: (15,11)-(15,13)) │ │ ├── flags: ∅ - │ │ ├── name: :baz - │ │ └── depth: 0 - │ └── operator_loc: (13,14)-(13,16) = "in" + │ │ ├── constant: ∅ + │ │ ├── requireds: (length: 1) + │ │ │ └── @ LocalVariableTargetNode (location: (15,11)-(15,12)) + │ │ │ ├── flags: ∅ + │ │ │ ├── name: :b + │ │ │ └── depth: 0 + │ │ ├── rest: + │ │ │ @ ImplicitRestNode (location: (15,12)-(15,13)) + │ │ │ └── flags: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── opening_loc: ∅ + │ │ └── closing_loc: ∅ + │ └── operator_loc: (15,8)-(15,10) = "in" └── statements: - @ StatementsNode (location: (13,0)-(13,3)) + @ StatementsNode (location: (15,17)-(15,18)) ├── flags: ∅ └── body: (length: 1) - └── @ CallNode (location: (13,0)-(13,3)) - ├── flags: newline, variable_call, ignore_visibility - ├── receiver: ∅ - ├── call_operator_loc: ∅ - ├── name: :foo - ├── message_loc: (13,0)-(13,3) = "foo" - ├── opening_loc: ∅ - ├── arguments: ∅ - ├── closing_loc: ∅ - ├── equal_loc: ∅ - └── block: ∅ + └── @ IntegerNode (location: (15,17)-(15,18)) + ├── flags: newline, static_literal, decimal + └── value: 1 diff --git a/snapshots/while.txt b/snapshots/while.txt index 67d45e4d66..2db815bc2d 100644 --- a/snapshots/while.txt +++ b/snapshots/while.txt @@ -1,10 +1,10 @@ -@ ProgramNode (location: (1,0)-(23,20)) +@ ProgramNode (location: (1,0)-(25,22)) ├── flags: ∅ -├── locals: [:baz] +├── locals: [:baz, :b] └── statements: - @ StatementsNode (location: (1,0)-(23,20)) + @ StatementsNode (location: (1,0)-(25,22)) ├── flags: ∅ - └── body: (length: 12) + └── body: (length: 13) ├── @ WhileNode (location: (1,0)-(1,18)) │ ├── flags: newline │ ├── keyword_loc: (1,0)-(1,5) = "while" @@ -513,44 +513,87 @@ │ │ ├── equal_loc: (21,14)-(21,15) = "=" │ │ └── end_keyword_loc: ∅ │ └── statements: ∅ - └── @ WhileNode (location: (23,0)-(23,20)) + ├── @ WhileNode (location: (23,0)-(23,20)) + │ ├── flags: newline + │ ├── keyword_loc: (23,4)-(23,9) = "while" + │ ├── do_keyword_loc: ∅ + │ ├── closing_loc: ∅ + │ ├── predicate: + │ │ @ MatchPredicateNode (location: (23,10)-(23,20)) + │ │ ├── flags: ∅ + │ │ ├── value: + │ │ │ @ CallNode (location: (23,10)-(23,13)) + │ │ │ ├── flags: variable_call, ignore_visibility + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── name: :bar + │ │ │ ├── message_loc: (23,10)-(23,13) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── equal_loc: ∅ + │ │ │ └── block: ∅ + │ │ ├── pattern: + │ │ │ @ LocalVariableTargetNode (location: (23,17)-(23,20)) + │ │ │ ├── flags: ∅ + │ │ │ ├── name: :baz + │ │ │ └── depth: 0 + │ │ └── operator_loc: (23,14)-(23,16) = "in" + │ └── statements: + │ @ StatementsNode (location: (23,0)-(23,3)) + │ ├── flags: ∅ + │ └── body: (length: 1) + │ └── @ CallNode (location: (23,0)-(23,3)) + │ ├── flags: newline, variable_call, ignore_visibility + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── name: :foo + │ ├── message_loc: (23,0)-(23,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── equal_loc: ∅ + │ └── block: ∅ + └── @ WhileNode (location: (25,0)-(25,22)) ├── flags: newline - ├── keyword_loc: (23,4)-(23,9) = "while" - ├── do_keyword_loc: ∅ - ├── closing_loc: ∅ + ├── keyword_loc: (25,0)-(25,5) = "while" + ├── do_keyword_loc: (25,14)-(25,16) = "do" + ├── closing_loc: (25,19)-(25,22) = "end" ├── predicate: - │ @ MatchPredicateNode (location: (23,10)-(23,20)) + │ @ MatchPredicateNode (location: (25,6)-(25,13)) │ ├── flags: ∅ │ ├── value: - │ │ @ CallNode (location: (23,10)-(23,13)) + │ │ @ CallNode (location: (25,6)-(25,7)) │ │ ├── flags: variable_call, ignore_visibility │ │ ├── receiver: ∅ │ │ ├── call_operator_loc: ∅ - │ │ ├── name: :bar - │ │ ├── message_loc: (23,10)-(23,13) = "bar" + │ │ ├── name: :a + │ │ ├── message_loc: (25,6)-(25,7) = "a" │ │ ├── opening_loc: ∅ │ │ ├── arguments: ∅ │ │ ├── closing_loc: ∅ │ │ ├── equal_loc: ∅ │ │ └── block: ∅ │ ├── pattern: - │ │ @ LocalVariableTargetNode (location: (23,17)-(23,20)) + │ │ @ ArrayPatternNode (location: (25,11)-(25,13)) │ │ ├── flags: ∅ - │ │ ├── name: :baz - │ │ └── depth: 0 - │ └── operator_loc: (23,14)-(23,16) = "in" + │ │ ├── constant: ∅ + │ │ ├── requireds: (length: 1) + │ │ │ └── @ LocalVariableTargetNode (location: (25,11)-(25,12)) + │ │ │ ├── flags: ∅ + │ │ │ ├── name: :b + │ │ │ └── depth: 0 + │ │ ├── rest: + │ │ │ @ ImplicitRestNode (location: (25,12)-(25,13)) + │ │ │ └── flags: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── opening_loc: ∅ + │ │ └── closing_loc: ∅ + │ └── operator_loc: (25,8)-(25,10) = "in" └── statements: - @ StatementsNode (location: (23,0)-(23,3)) + @ StatementsNode (location: (25,17)-(25,18)) ├── flags: ∅ └── body: (length: 1) - └── @ CallNode (location: (23,0)-(23,3)) - ├── flags: newline, variable_call, ignore_visibility - ├── receiver: ∅ - ├── call_operator_loc: ∅ - ├── name: :foo - ├── message_loc: (23,0)-(23,3) = "foo" - ├── opening_loc: ∅ - ├── arguments: ∅ - ├── closing_loc: ∅ - ├── equal_loc: ∅ - └── block: ∅ + └── @ IntegerNode (location: (25,17)-(25,18)) + ├── flags: newline, static_literal, decimal + └── value: 1 diff --git a/src/prism.c b/src/prism.c index d997c63d16..ddbfea18b0 100644 --- a/src/prism.c +++ b/src/prism.c @@ -17598,7 +17598,7 @@ parse_pattern(pm_parser_t *parser, pm_constant_id_list_t *captures, uint8_t flag // when `pattern_matching_newlines` is set, so this does not affect // patterns nested in brackets or parentheses. if ( - match7(parser, PM_TOKEN_KEYWORD_THEN, PM_TOKEN_BRACE_RIGHT, PM_TOKEN_BRACKET_RIGHT, PM_TOKEN_PARENTHESIS_RIGHT, PM_TOKEN_SEMICOLON, PM_TOKEN_KEYWORD_AND, PM_TOKEN_KEYWORD_OR) || + match8(parser, PM_TOKEN_KEYWORD_THEN, PM_TOKEN_KEYWORD_DO_LOOP, PM_TOKEN_BRACE_RIGHT, PM_TOKEN_BRACKET_RIGHT, PM_TOKEN_PARENTHESIS_RIGHT, PM_TOKEN_SEMICOLON, PM_TOKEN_KEYWORD_AND, PM_TOKEN_KEYWORD_OR) || match2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_EOF) ) { // A trailing comma forms an implicit rest pattern (`[a,]` is diff --git a/test/prism/fixtures/for.txt b/test/prism/fixtures/for.txt index b6eb2cb24f..714027ba00 100644 --- a/test/prism/fixtures/for.txt +++ b/test/prism/fixtures/for.txt @@ -17,3 +17,5 @@ i end for i in 1..10; i; end + +for x in a in b, do 1 end diff --git a/test/prism/fixtures/until.txt b/test/prism/fixtures/until.txt index 652fc8c5a7..ee8534d6bb 100644 --- a/test/prism/fixtures/until.txt +++ b/test/prism/fixtures/until.txt @@ -11,3 +11,5 @@ return until true foo :a, :b until bar? foo while bar in baz + +until a in b, do 1 end diff --git a/test/prism/fixtures/while.txt b/test/prism/fixtures/while.txt index b776f755ee..4bc61a6a14 100644 --- a/test/prism/fixtures/while.txt +++ b/test/prism/fixtures/while.txt @@ -21,3 +21,5 @@ tap { while class << self; a = tap do end; end; break; end } while def foo = bar do end; end foo while bar in baz + +while a in b, do 1 end