summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--prism/parser.h1
-rw-r--r--prism/prism.c17
-rw-r--r--test/prism/fixtures/variables.txt1
-rw-r--r--test/prism/snapshots/variables.txt110
4 files changed, 85 insertions, 44 deletions
diff --git a/prism/parser.h b/prism/parser.h
index f77d8818aa..c701e595a9 100644
--- a/prism/parser.h
+++ b/prism/parser.h
@@ -212,6 +212,7 @@ typedef enum {
PM_CONTEXT_EMBEXPR, // an interpolated expression
PM_CONTEXT_ENSURE, // an ensure statement
PM_CONTEXT_FOR, // a for loop
+ PM_CONTEXT_FOR_INDEX, // a for loop's index
PM_CONTEXT_IF, // an if statement
PM_CONTEXT_LAMBDA_BRACES, // a lambda expression with braces
PM_CONTEXT_LAMBDA_DO_END, // a lambda expression with do..end
diff --git a/prism/prism.c b/prism/prism.c
index 6b9c20a4bd..5cb18a7b30 100644
--- a/prism/prism.c
+++ b/prism/prism.c
@@ -40,6 +40,7 @@ debug_context(pm_context_t context) {
case PM_CONTEXT_BLOCK_BRACES: return "BLOCK_BRACES";
case PM_CONTEXT_BLOCK_KEYWORDS: return "BLOCK_KEYWORDS";
case PM_CONTEXT_FOR: return "FOR";
+ case PM_CONTEXT_FOR_INDEX: return "FOR_INDEX";
case PM_CONTEXT_IF: return "IF";
case PM_CONTEXT_MAIN: return "MAIN";
case PM_CONTEXT_MODULE: return "MODULE";
@@ -5602,6 +5603,8 @@ context_terminator(pm_context_t context, pm_token_t *token) {
case PM_CONTEXT_FOR:
case PM_CONTEXT_ENSURE:
return token->type == PM_TOKEN_KEYWORD_END;
+ case PM_CONTEXT_FOR_INDEX:
+ return token->type == PM_TOKEN_KEYWORD_IN;
case PM_CONTEXT_CASE_WHEN:
return token->type == PM_TOKEN_KEYWORD_WHEN || token->type == PM_TOKEN_KEYWORD_END || token->type == PM_TOKEN_KEYWORD_ELSE;
case PM_CONTEXT_CASE_IN:
@@ -9585,7 +9588,7 @@ parse_target(pm_parser_t *parser, pm_node_t *target) {
}
}
-// Parse a write targets and validate that it is in a valid position for
+// Parse a write target and validate that it is in a valid position for
// assignment.
static pm_node_t *
parse_target_validate(pm_parser_t *parser, pm_node_t *target) {
@@ -12544,10 +12547,13 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) {
multi_target->base.location.end = rparen_loc.end;
if (match1(parser, PM_TOKEN_COMMA)) {
- return parse_targets_validate(parser, (pm_node_t *) multi_target, PM_BINDING_POWER_INDEX);
- } else {
- return parse_target_validate(parser, (pm_node_t *) multi_target);
+ if (binding_power == PM_BINDING_POWER_STATEMENT) {
+ return parse_targets_validate(parser, (pm_node_t *) multi_target, PM_BINDING_POWER_INDEX);
+ }
+ return (pm_node_t *) multi_target;
}
+
+ return parse_target_validate(parser, (pm_node_t *) multi_target);
}
// If we have a single statement and are ending on a right parenthesis
@@ -13634,7 +13640,9 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) {
parser_lex(parser);
pm_token_t for_keyword = parser->previous;
pm_node_t *index;
+
pm_parser_scope_push_transparent(parser);
+ context_push(parser, PM_CONTEXT_FOR_INDEX);
// First, parse out the first index expression.
if (accept1(parser, PM_TOKEN_USTAR)) {
@@ -13660,6 +13668,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) {
index = parse_target(parser, index);
}
+ context_pop(parser);
pm_parser_scope_pop(parser);
pm_do_loop_stack_push(parser, true);
diff --git a/test/prism/fixtures/variables.txt b/test/prism/fixtures/variables.txt
index 276dc3b3f1..1545c30c80 100644
--- a/test/prism/fixtures/variables.txt
+++ b/test/prism/fixtures/variables.txt
@@ -44,3 +44,4 @@ Foo = 1, 2
(a; b; c)
+a, (b, c), d = []
diff --git a/test/prism/snapshots/variables.txt b/test/prism/snapshots/variables.txt
index f0293522be..4a5507e313 100644
--- a/test/prism/snapshots/variables.txt
+++ b/test/prism/snapshots/variables.txt
@@ -1,8 +1,8 @@
-@ ProgramNode (location: (1,0)-(45,9))
-├── locals: [:abc, :foo, :bar, :baz]
+@ ProgramNode (location: (1,0)-(47,17))
+├── locals: [:abc, :foo, :bar, :baz, :a, :b, :c, :d]
└── statements:
- @ StatementsNode (location: (1,0)-(45,9))
- └── body: (length: 24)
+ @ StatementsNode (location: (1,0)-(47,17))
+ └── body: (length: 25)
├── @ ClassVariableReadNode (location: (1,0)-(1,5))
│ └── name: :@@abc
├── @ ClassVariableWriteNode (location: (3,0)-(3,9))
@@ -300,39 +300,69 @@
│ │ ├── opening_loc: ∅
│ │ └── closing_loc: ∅
│ └── operator_loc: (43,4)-(43,5) = "="
- └── @ ParenthesesNode (location: (45,0)-(45,9))
- ├── body:
- │ @ StatementsNode (location: (45,1)-(45,8))
- │ └── body: (length: 3)
- │ ├── @ CallNode (location: (45,1)-(45,2))
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── message_loc: (45,1)-(45,2) = "a"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ ├── block: ∅
- │ │ ├── flags: variable_call
- │ │ └── name: :a
- │ ├── @ CallNode (location: (45,4)-(45,5))
- │ │ ├── receiver: ∅
- │ │ ├── call_operator_loc: ∅
- │ │ ├── message_loc: (45,4)-(45,5) = "b"
- │ │ ├── opening_loc: ∅
- │ │ ├── arguments: ∅
- │ │ ├── closing_loc: ∅
- │ │ ├── block: ∅
- │ │ ├── flags: variable_call
- │ │ └── name: :b
- │ └── @ CallNode (location: (45,7)-(45,8))
- │ ├── receiver: ∅
- │ ├── call_operator_loc: ∅
- │ ├── message_loc: (45,7)-(45,8) = "c"
- │ ├── opening_loc: ∅
- │ ├── arguments: ∅
- │ ├── closing_loc: ∅
- │ ├── block: ∅
- │ ├── flags: variable_call
- │ └── name: :c
- ├── opening_loc: (45,0)-(45,1) = "("
- └── closing_loc: (45,8)-(45,9) = ")"
+ ├── @ ParenthesesNode (location: (45,0)-(45,9))
+ │ ├── body:
+ │ │ @ StatementsNode (location: (45,1)-(45,8))
+ │ │ └── body: (length: 3)
+ │ │ ├── @ CallNode (location: (45,1)-(45,2))
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── message_loc: (45,1)-(45,2) = "a"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ ├── block: ∅
+ │ │ │ ├── flags: variable_call
+ │ │ │ └── name: :a
+ │ │ ├── @ CallNode (location: (45,4)-(45,5))
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── message_loc: (45,4)-(45,5) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ ├── block: ∅
+ │ │ │ ├── flags: variable_call
+ │ │ │ └── name: :b
+ │ │ └── @ CallNode (location: (45,7)-(45,8))
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── message_loc: (45,7)-(45,8) = "c"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ ├── block: ∅
+ │ │ ├── flags: variable_call
+ │ │ └── name: :c
+ │ ├── opening_loc: (45,0)-(45,1) = "("
+ │ └── closing_loc: (45,8)-(45,9) = ")"
+ └── @ MultiWriteNode (location: (47,0)-(47,17))
+ ├── requireds: (length: 3)
+ │ ├── @ LocalVariableTargetNode (location: (47,0)-(47,1))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ ├── @ MultiTargetNode (location: (47,3)-(47,9))
+ │ │ ├── requireds: (length: 2)
+ │ │ │ ├── @ LocalVariableTargetNode (location: (47,4)-(47,5))
+ │ │ │ │ ├── name: :b
+ │ │ │ │ └── depth: 0
+ │ │ │ └── @ LocalVariableTargetNode (location: (47,7)-(47,8))
+ │ │ │ ├── name: :c
+ │ │ │ └── depth: 0
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── lparen_loc: (47,3)-(47,4) = "("
+ │ │ └── rparen_loc: (47,8)-(47,9) = ")"
+ │ └── @ LocalVariableTargetNode (location: (47,11)-(47,12))
+ │ ├── name: :d
+ │ └── depth: 0
+ ├── rest: ∅
+ ├── posts: (length: 0)
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── operator_loc: (47,13)-(47,14) = "="
+ └── value:
+ @ ArrayNode (location: (47,15)-(47,17))
+ ├── elements: (length: 0)
+ ├── opening_loc: (47,15)-(47,16) = "["
+ └── closing_loc: (47,16)-(47,17) = "]"