@@ -17274,6 +17274,9 @@ parse_pattern_primitive(pm_parser_t *parser, pm_constant_id_list_t *captures, pm
17274
17274
case PM_CASE_PRIMITIVE: {
17275
17275
pm_node_t *node = parse_expression(parser, PM_BINDING_POWER_MAX, false, true, diag_id, (uint16_t) (depth + 1));
17276
17276
17277
+ // If we found a label, we need to immediately return to the caller.
17278
+ if (pm_symbol_node_label_p(node)) return node;
17279
+
17277
17280
// Now that we have a primitive, we need to check if it's part of a range.
17278
17281
if (accept2(parser, PM_TOKEN_DOT_DOT, PM_TOKEN_DOT_DOT_DOT)) {
17279
17282
pm_token_t operator = parser->previous;
@@ -17391,10 +17394,10 @@ parse_pattern_primitive(pm_parser_t *parser, pm_constant_id_list_t *captures, pm
17391
17394
* assignment.
17392
17395
*/
17393
17396
static pm_node_t *
17394
- parse_pattern_primitives(pm_parser_t *parser, pm_constant_id_list_t *captures, pm_diagnostic_id_t diag_id, uint16_t depth) {
17395
- pm_node_t *node = NULL ;
17397
+ parse_pattern_primitives(pm_parser_t *parser, pm_constant_id_list_t *captures, pm_node_t *first_node, pm_diagnostic_id_t diag_id, uint16_t depth) {
17398
+ pm_node_t *node = first_node ;
17396
17399
17397
- do {
17400
+ while ((node == NULL) || accept1(parser, PM_TOKEN_PIPE)) {
17398
17401
pm_token_t operator = parser->previous;
17399
17402
17400
17403
switch (parser->current.type) {
@@ -17447,7 +17450,7 @@ parse_pattern_primitives(pm_parser_t *parser, pm_constant_id_list_t *captures, p
17447
17450
break;
17448
17451
}
17449
17452
}
17450
- } while (accept1(parser, PM_TOKEN_PIPE));
17453
+ }
17451
17454
17452
17455
// If we have an =>, then we are assigning this pattern to a variable.
17453
17456
// In this case we should create an assignment node.
@@ -17508,6 +17511,24 @@ parse_pattern(pm_parser_t *parser, pm_constant_id_list_t *captures, uint8_t flag
17508
17511
17509
17512
return node;
17510
17513
}
17514
+ case PM_TOKEN_STRING_BEGIN: {
17515
+ // We need special handling for string beginnings because they could
17516
+ // be dynamic symbols leading to hash patterns.
17517
+ node = parse_pattern_primitive(parser, captures, diag_id, (uint16_t) (depth + 1));
17518
+
17519
+ if (pm_symbol_node_label_p(node)) {
17520
+ node = (pm_node_t *) parse_pattern_hash(parser, captures, node, (uint16_t) (depth + 1));
17521
+
17522
+ if (!(flags & PM_PARSE_PATTERN_TOP)) {
17523
+ pm_parser_err_node(parser, node, PM_ERR_PATTERN_HASH_IMPLICIT);
17524
+ }
17525
+
17526
+ return node;
17527
+ }
17528
+
17529
+ node = parse_pattern_primitives(parser, captures, node, diag_id, (uint16_t) (depth + 1));
17530
+ break;
17531
+ }
17511
17532
case PM_TOKEN_USTAR: {
17512
17533
if (flags & (PM_PARSE_PATTERN_TOP | PM_PARSE_PATTERN_MULTI)) {
17513
17534
parser_lex(parser);
@@ -17518,7 +17539,7 @@ parse_pattern(pm_parser_t *parser, pm_constant_id_list_t *captures, uint8_t flag
17518
17539
}
17519
17540
/* fallthrough */
17520
17541
default:
17521
- node = parse_pattern_primitives(parser, captures, diag_id, (uint16_t) (depth + 1));
17542
+ node = parse_pattern_primitives(parser, captures, NULL, diag_id, (uint16_t) (depth + 1));
17522
17543
break;
17523
17544
}
17524
17545
@@ -17556,7 +17577,7 @@ parse_pattern(pm_parser_t *parser, pm_constant_id_list_t *captures, uint8_t flag
17556
17577
17557
17578
trailing_rest = true;
17558
17579
} else {
17559
- node = parse_pattern_primitives(parser, captures, PM_ERR_PATTERN_EXPRESSION_AFTER_COMMA, (uint16_t) (depth + 1));
17580
+ node = parse_pattern_primitives(parser, captures, NULL, PM_ERR_PATTERN_EXPRESSION_AFTER_COMMA, (uint16_t) (depth + 1));
17560
17581
}
17561
17582
17562
17583
pm_node_list_append(&nodes, node);
0 commit comments