prism 0.18.0 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/CHANGELOG.md +31 -1
 - data/README.md +2 -1
 - data/config.yml +188 -55
 - data/docs/building.md +9 -2
 - data/docs/configuration.md +10 -9
 - data/docs/encoding.md +24 -56
 - data/docs/local_variable_depth.md +229 -0
 - data/docs/ruby_api.md +2 -0
 - data/docs/serialization.md +18 -13
 - data/ext/prism/api_node.c +337 -195
 - data/ext/prism/extconf.rb +13 -7
 - data/ext/prism/extension.c +96 -32
 - data/ext/prism/extension.h +1 -1
 - data/include/prism/ast.h +340 -137
 - data/include/prism/defines.h +17 -0
 - data/include/prism/diagnostic.h +11 -5
 - data/include/prism/encoding.h +248 -0
 - data/include/prism/options.h +2 -2
 - data/include/prism/parser.h +62 -42
 - data/include/prism/regexp.h +2 -2
 - data/include/prism/util/pm_buffer.h +9 -1
 - data/include/prism/util/pm_memchr.h +2 -2
 - data/include/prism/util/pm_strpbrk.h +3 -3
 - data/include/prism/version.h +2 -2
 - data/include/prism.h +13 -15
 - data/lib/prism/compiler.rb +12 -0
 - data/lib/prism/debug.rb +9 -4
 - data/lib/prism/desugar_compiler.rb +3 -3
 - data/lib/prism/dispatcher.rb +56 -0
 - data/lib/prism/dot_visitor.rb +476 -198
 - data/lib/prism/dsl.rb +66 -46
 - data/lib/prism/ffi.rb +16 -3
 - data/lib/prism/lex_compat.rb +19 -9
 - data/lib/prism/mutation_compiler.rb +20 -0
 - data/lib/prism/node.rb +1173 -450
 - data/lib/prism/node_ext.rb +41 -16
 - data/lib/prism/parse_result.rb +12 -15
 - data/lib/prism/ripper_compat.rb +49 -34
 - data/lib/prism/serialize.rb +242 -212
 - data/lib/prism/visitor.rb +12 -0
 - data/lib/prism.rb +20 -4
 - data/prism.gemspec +4 -10
 - data/rbi/prism.rbi +605 -230
 - data/rbi/prism_static.rbi +3 -0
 - data/sig/prism.rbs +379 -124
 - data/sig/prism_static.rbs +1 -0
 - data/src/diagnostic.c +228 -222
 - data/src/encoding.c +5137 -0
 - data/src/node.c +66 -0
 - data/src/options.c +21 -2
 - data/src/prettyprint.c +806 -406
 - data/src/prism.c +1092 -700
 - data/src/regexp.c +3 -3
 - data/src/serialize.c +227 -157
 - data/src/util/pm_buffer.c +10 -1
 - data/src/util/pm_memchr.c +1 -1
 - data/src/util/pm_strpbrk.c +4 -4
 - metadata +5 -11
 - data/include/prism/enc/pm_encoding.h +0 -227
 - data/src/enc/pm_big5.c +0 -116
 - data/src/enc/pm_cp51932.c +0 -57
 - data/src/enc/pm_euc_jp.c +0 -69
 - data/src/enc/pm_gbk.c +0 -65
 - data/src/enc/pm_shift_jis.c +0 -57
 - data/src/enc/pm_tables.c +0 -2073
 - data/src/enc/pm_unicode.c +0 -2369
 - data/src/enc/pm_windows_31j.c +0 -57
 
    
        data/src/prism.c
    CHANGED
    
    | 
         @@ -40,6 +40,7 @@ debug_context(pm_context_t context) { 
     | 
|
| 
       40 
40 
     | 
    
         
             
                    case PM_CONTEXT_DEF_PARAMS: return "DEF_PARAMS";
         
     | 
| 
       41 
41 
     | 
    
         
             
                    case PM_CONTEXT_DEFAULT_PARAMS: return "DEFAULT_PARAMS";
         
     | 
| 
       42 
42 
     | 
    
         
             
                    case PM_CONTEXT_ENSURE: return "ENSURE";
         
     | 
| 
      
 43 
     | 
    
         
            +
                    case PM_CONTEXT_ENSURE_DEF: return "ENSURE_DEF";
         
     | 
| 
       43 
44 
     | 
    
         
             
                    case PM_CONTEXT_ELSE: return "ELSE";
         
     | 
| 
       44 
45 
     | 
    
         
             
                    case PM_CONTEXT_ELSIF: return "ELSIF";
         
     | 
| 
       45 
46 
     | 
    
         
             
                    case PM_CONTEXT_EMBEXPR: return "EMBEXPR";
         
     | 
| 
         @@ -56,6 +57,8 @@ debug_context(pm_context_t context) { 
     | 
|
| 
       56 
57 
     | 
    
         
             
                    case PM_CONTEXT_PREEXE: return "PREEXE";
         
     | 
| 
       57 
58 
     | 
    
         
             
                    case PM_CONTEXT_RESCUE: return "RESCUE";
         
     | 
| 
       58 
59 
     | 
    
         
             
                    case PM_CONTEXT_RESCUE_ELSE: return "RESCUE_ELSE";
         
     | 
| 
      
 60 
     | 
    
         
            +
                    case PM_CONTEXT_RESCUE_ELSE_DEF: return "RESCUE_ELSE_DEF";
         
     | 
| 
      
 61 
     | 
    
         
            +
                    case PM_CONTEXT_RESCUE_DEF: return "RESCUE_DEF";
         
     | 
| 
       59 
62 
     | 
    
         
             
                    case PM_CONTEXT_SCLASS: return "SCLASS";
         
     | 
| 
       60 
63 
     | 
    
         
             
                    case PM_CONTEXT_UNLESS: return "UNLESS";
         
     | 
| 
       61 
64 
     | 
    
         
             
                    case PM_CONTEXT_UNTIL: return "UNTIL";
         
     | 
| 
         @@ -272,6 +275,7 @@ lex_mode_push_list(pm_parser_t *parser, bool interpolation, uint8_t delimiter) { 
     | 
|
| 
       272 
275 
     | 
    
         
             
                    breakpoints[index++] = incrementor;
         
     | 
| 
       273 
276 
     | 
    
         
             
                }
         
     | 
| 
       274 
277 
     | 
    
         | 
| 
      
 278 
     | 
    
         
            +
                parser->explicit_encoding = NULL;
         
     | 
| 
       275 
279 
     | 
    
         
             
                return lex_mode_push(parser, lex_mode);
         
     | 
| 
       276 
280 
     | 
    
         
             
            }
         
     | 
| 
       277 
281 
     | 
    
         | 
| 
         @@ -353,6 +357,7 @@ lex_mode_push_string(pm_parser_t *parser, bool interpolation, bool label_allowed 
     | 
|
| 
       353 
357 
     | 
    
         
             
                    breakpoints[index++] = incrementor;
         
     | 
| 
       354 
358 
     | 
    
         
             
                }
         
     | 
| 
       355 
359 
     | 
    
         | 
| 
      
 360 
     | 
    
         
            +
                parser->explicit_encoding = NULL;
         
     | 
| 
       356 
361 
     | 
    
         
             
                return lex_mode_push(parser, lex_mode);
         
     | 
| 
       357 
362 
     | 
    
         
             
            }
         
     | 
| 
       358 
363 
     | 
    
         | 
| 
         @@ -536,7 +541,7 @@ pm_parser_err_token(pm_parser_t *parser, const pm_token_t *token, pm_diagnostic_ 
     | 
|
| 
       536 
541 
     | 
    
         
             
             * Append an error to the list of errors on the parser using the location of the
         
     | 
| 
       537 
542 
     | 
    
         
             
             * given token and a format string.
         
     | 
| 
       538 
543 
     | 
    
         
             
             */
         
     | 
| 
       539 
     | 
    
         
            -
            #define PM_PARSER_ERR_TOKEN_FORMAT(parser, token, diag_id, ...) pm_diagnostic_list_append_format(&parser->error_list, token 
     | 
| 
      
 544 
     | 
    
         
            +
            #define PM_PARSER_ERR_TOKEN_FORMAT(parser, token, diag_id, ...) pm_diagnostic_list_append_format(&parser->error_list, (token).start, (token).end, diag_id, __VA_ARGS__)
         
     | 
| 
       540 
545 
     | 
    
         | 
| 
       541 
546 
     | 
    
         
             
            /**
         
     | 
| 
       542 
547 
     | 
    
         
             
             * Append a warning to the list of warnings on the parser.
         
     | 
| 
         @@ -776,8 +781,7 @@ pm_conditional_predicate(pm_node_t *node) { 
     | 
|
| 
       776 
781 
     | 
    
         
             
             * parentheses. In these cases we set the token to the "not provided" type. For
         
     | 
| 
       777 
782 
     | 
    
         
             
             * example:
         
     | 
| 
       778 
783 
     | 
    
         
             
             *
         
     | 
| 
       779 
     | 
    
         
            -
             *     pm_token_t token;
         
     | 
| 
       780 
     | 
    
         
            -
             *     not_provided(&token, parser->previous.end);
         
     | 
| 
      
 784 
     | 
    
         
            +
             *     pm_token_t token = not_provided(parser);
         
     | 
| 
       781 
785 
     | 
    
         
             
             */
         
     | 
| 
       782 
786 
     | 
    
         
             
            static inline pm_token_t
         
     | 
| 
       783 
787 
     | 
    
         
             
            not_provided(pm_parser_t *parser) {
         
     | 
| 
         @@ -860,6 +864,27 @@ pm_arguments_validate_block(pm_parser_t *parser, pm_arguments_t *arguments, pm_b 
     | 
|
| 
       860 
864 
     | 
    
         
             
                pm_parser_err_node(parser, (pm_node_t *) block, PM_ERR_ARGUMENT_UNEXPECTED_BLOCK);
         
     | 
| 
       861 
865 
     | 
    
         
             
            }
         
     | 
| 
       862 
866 
     | 
    
         | 
| 
      
 867 
     | 
    
         
            +
            /******************************************************************************/
         
     | 
| 
      
 868 
     | 
    
         
            +
            /* Node flag handling functions                                               */
         
     | 
| 
      
 869 
     | 
    
         
            +
            /******************************************************************************/
         
     | 
| 
      
 870 
     | 
    
         
            +
             
     | 
| 
      
 871 
     | 
    
         
            +
            /**
         
     | 
| 
      
 872 
     | 
    
         
            +
             * Set the given flag on the given node.
         
     | 
| 
      
 873 
     | 
    
         
            +
             */
         
     | 
| 
      
 874 
     | 
    
         
            +
            static inline void
         
     | 
| 
      
 875 
     | 
    
         
            +
            pm_node_flag_set(pm_node_t *node, pm_node_flags_t flag) {
         
     | 
| 
      
 876 
     | 
    
         
            +
                node->flags |= flag;
         
     | 
| 
      
 877 
     | 
    
         
            +
            }
         
     | 
| 
      
 878 
     | 
    
         
            +
             
     | 
| 
      
 879 
     | 
    
         
            +
            /**
         
     | 
| 
      
 880 
     | 
    
         
            +
             * Remove the given flag from the given node.
         
     | 
| 
      
 881 
     | 
    
         
            +
             */
         
     | 
| 
      
 882 
     | 
    
         
            +
            static inline void
         
     | 
| 
      
 883 
     | 
    
         
            +
            pm_node_flag_unset(pm_node_t *node, pm_node_flags_t flag) {
         
     | 
| 
      
 884 
     | 
    
         
            +
                node->flags &= (pm_node_flags_t) ~flag;
         
     | 
| 
      
 885 
     | 
    
         
            +
            }
         
     | 
| 
      
 886 
     | 
    
         
            +
             
     | 
| 
      
 887 
     | 
    
         
            +
             
     | 
| 
       863 
888 
     | 
    
         
             
            /******************************************************************************/
         
     | 
| 
       864 
889 
     | 
    
         
             
            /* Node creation functions                                                    */
         
     | 
| 
       865 
890 
     | 
    
         
             
            /******************************************************************************/
         
     | 
| 
         @@ -1148,8 +1173,12 @@ pm_array_node_elements_append(pm_array_node_t *node, pm_node_t *element) { 
     | 
|
| 
       1148 
1173 
     | 
    
         | 
| 
       1149 
1174 
     | 
    
         
             
                // If the element is not a static literal, then the array is not a static
         
     | 
| 
       1150 
1175 
     | 
    
         
             
                // literal. Turn that flag off.
         
     | 
| 
       1151 
     | 
    
         
            -
                if (PM_NODE_TYPE_P(element, PM_ARRAY_NODE) || PM_NODE_TYPE_P(element, PM_HASH_NODE) || PM_NODE_TYPE_P(element, PM_RANGE_NODE) || (element 
     | 
| 
       1152 
     | 
    
         
            -
                     
     | 
| 
      
 1176 
     | 
    
         
            +
                if (PM_NODE_TYPE_P(element, PM_ARRAY_NODE) || PM_NODE_TYPE_P(element, PM_HASH_NODE) || PM_NODE_TYPE_P(element, PM_RANGE_NODE) || !PM_NODE_FLAG_P(element, PM_NODE_FLAG_STATIC_LITERAL)) {
         
     | 
| 
      
 1177 
     | 
    
         
            +
                    pm_node_flag_unset((pm_node_t *)node, PM_NODE_FLAG_STATIC_LITERAL);
         
     | 
| 
      
 1178 
     | 
    
         
            +
                }
         
     | 
| 
      
 1179 
     | 
    
         
            +
             
     | 
| 
      
 1180 
     | 
    
         
            +
                if (PM_NODE_TYPE_P(element, PM_SPLAT_NODE)) {
         
     | 
| 
      
 1181 
     | 
    
         
            +
                    pm_node_flag_set((pm_node_t *)node, PM_ARRAY_NODE_FLAGS_CONTAINS_SPLAT);
         
     | 
| 
       1153 
1182 
     | 
    
         
             
                }
         
     | 
| 
       1154 
1183 
     | 
    
         
             
            }
         
     | 
| 
       1155 
1184 
     | 
    
         | 
| 
         @@ -1193,7 +1222,7 @@ pm_array_pattern_node_node_list_create(pm_parser_t *parser, pm_node_list_t *node 
     | 
|
| 
       1193 
1222 
     | 
    
         
             
                for (size_t index = 0; index < nodes->size; index++) {
         
     | 
| 
       1194 
1223 
     | 
    
         
             
                    pm_node_t *child = nodes->nodes[index];
         
     | 
| 
       1195 
1224 
     | 
    
         | 
| 
       1196 
     | 
    
         
            -
                    if (!found_rest && PM_NODE_TYPE_P(child, PM_SPLAT_NODE)) {
         
     | 
| 
      
 1225 
     | 
    
         
            +
                    if (!found_rest && (PM_NODE_TYPE_P(child, PM_SPLAT_NODE) || PM_NODE_TYPE_P(child, PM_IMPLICIT_REST_NODE))) {
         
     | 
| 
       1197 
1226 
     | 
    
         
             
                        node->rest = child;
         
     | 
| 
       1198 
1227 
     | 
    
         
             
                        found_rest = true;
         
     | 
| 
       1199 
1228 
     | 
    
         
             
                    } else if (found_rest) {
         
     | 
| 
         @@ -1461,7 +1490,7 @@ pm_block_argument_node_create(pm_parser_t *parser, const pm_token_t *operator, p 
     | 
|
| 
       1461 
1490 
     | 
    
         
             
             * Allocate and initialize a new BlockNode node.
         
     | 
| 
       1462 
1491 
     | 
    
         
             
             */
         
     | 
| 
       1463 
1492 
     | 
    
         
             
            static pm_block_node_t *
         
     | 
| 
       1464 
     | 
    
         
            -
            pm_block_node_create(pm_parser_t *parser, pm_constant_id_list_t *locals, const pm_token_t *opening,  
     | 
| 
      
 1493 
     | 
    
         
            +
            pm_block_node_create(pm_parser_t *parser, pm_constant_id_list_t *locals, uint32_t locals_body_index, const pm_token_t *opening, pm_node_t *parameters, pm_node_t *body, const pm_token_t *closing) {
         
     | 
| 
       1465 
1494 
     | 
    
         
             
                pm_block_node_t *node = PM_ALLOC_NODE(parser, pm_block_node_t);
         
     | 
| 
       1466 
1495 
     | 
    
         | 
| 
       1467 
1496 
     | 
    
         
             
                *node = (pm_block_node_t) {
         
     | 
| 
         @@ -1470,6 +1499,7 @@ pm_block_node_create(pm_parser_t *parser, pm_constant_id_list_t *locals, const p 
     | 
|
| 
       1470 
1499 
     | 
    
         
             
                        .location = { .start = opening->start, .end = closing->end },
         
     | 
| 
       1471 
1500 
     | 
    
         
             
                    },
         
     | 
| 
       1472 
1501 
     | 
    
         
             
                    .locals = *locals,
         
     | 
| 
      
 1502 
     | 
    
         
            +
                    .locals_body_index = locals_body_index,
         
     | 
| 
       1473 
1503 
     | 
    
         
             
                    .parameters = parameters,
         
     | 
| 
       1474 
1504 
     | 
    
         
             
                    .body = body,
         
     | 
| 
       1475 
1505 
     | 
    
         
             
                    .opening_loc = PM_LOCATION_TOKEN_VALUE(opening),
         
     | 
| 
         @@ -1711,7 +1741,7 @@ pm_call_node_call_create(pm_parser_t *parser, pm_node_t *receiver, pm_token_t *o 
     | 
|
| 
       1711 
1741 
     | 
    
         
             
                node->block = arguments->block;
         
     | 
| 
       1712 
1742 
     | 
    
         | 
| 
       1713 
1743 
     | 
    
         
             
                if (operator->type == PM_TOKEN_AMPERSAND_DOT) {
         
     | 
| 
       1714 
     | 
    
         
            -
                    node 
     | 
| 
      
 1744 
     | 
    
         
            +
                    pm_node_flag_set((pm_node_t *)node, PM_CALL_NODE_FLAGS_SAFE_NAVIGATION);
         
     | 
| 
       1715 
1745 
     | 
    
         
             
                }
         
     | 
| 
       1716 
1746 
     | 
    
         | 
| 
       1717 
1747 
     | 
    
         
             
                node->name = pm_parser_constant_id_token(parser, message);
         
     | 
| 
         @@ -1785,7 +1815,7 @@ pm_call_node_shorthand_create(pm_parser_t *parser, pm_node_t *receiver, pm_token 
     | 
|
| 
       1785 
1815 
     | 
    
         
             
                node->block = arguments->block;
         
     | 
| 
       1786 
1816 
     | 
    
         | 
| 
       1787 
1817 
     | 
    
         
             
                if (operator->type == PM_TOKEN_AMPERSAND_DOT) {
         
     | 
| 
       1788 
     | 
    
         
            -
                    node 
     | 
| 
      
 1818 
     | 
    
         
            +
                    pm_node_flag_set((pm_node_t *)node, PM_CALL_NODE_FLAGS_SAFE_NAVIGATION);
         
     | 
| 
       1789 
1819 
     | 
    
         
             
                }
         
     | 
| 
       1790 
1820 
     | 
    
         | 
| 
       1791 
1821 
     | 
    
         
             
                node->name = pm_parser_constant_id_constant(parser, "call", 4);
         
     | 
| 
         @@ -1832,12 +1862,12 @@ pm_call_node_variable_call_create(pm_parser_t *parser, pm_token_t *message) { 
     | 
|
| 
       1832 
1862 
     | 
    
         
             
             */
         
     | 
| 
       1833 
1863 
     | 
    
         
             
            static inline bool
         
     | 
| 
       1834 
1864 
     | 
    
         
             
            pm_call_node_variable_call_p(pm_call_node_t *node) {
         
     | 
| 
       1835 
     | 
    
         
            -
                return node 
     | 
| 
      
 1865 
     | 
    
         
            +
                return PM_NODE_FLAG_P(node, PM_CALL_NODE_FLAGS_VARIABLE_CALL);
         
     | 
| 
       1836 
1866 
     | 
    
         
             
            }
         
     | 
| 
       1837 
1867 
     | 
    
         | 
| 
       1838 
1868 
     | 
    
         
             
            /**
         
     | 
| 
       1839 
     | 
    
         
            -
             * Returns whether or not this call is to the [] method in the index form (as
         
     | 
| 
       1840 
     | 
    
         
            -
             * opposed to `foo.[]`).
         
     | 
| 
      
 1869 
     | 
    
         
            +
             * Returns whether or not this call is to the [] method in the index form without a block (as
         
     | 
| 
      
 1870 
     | 
    
         
            +
             * opposed to `foo.[]` and `foo[] { }`).
         
     | 
| 
       1841 
1871 
     | 
    
         
             
             */
         
     | 
| 
       1842 
1872 
     | 
    
         
             
            static inline bool
         
     | 
| 
       1843 
1873 
     | 
    
         
             
            pm_call_node_index_p(pm_call_node_t *node) {
         
     | 
| 
         @@ -1845,7 +1875,8 @@ pm_call_node_index_p(pm_call_node_t *node) { 
     | 
|
| 
       1845 
1875 
     | 
    
         
             
                    (node->call_operator_loc.start == NULL) &&
         
     | 
| 
       1846 
1876 
     | 
    
         
             
                    (node->message_loc.start != NULL) &&
         
     | 
| 
       1847 
1877 
     | 
    
         
             
                    (node->message_loc.start[0] == '[') &&
         
     | 
| 
       1848 
     | 
    
         
            -
                    (node->message_loc.end[-1] == ']')
         
     | 
| 
      
 1878 
     | 
    
         
            +
                    (node->message_loc.end[-1] == ']') &&
         
     | 
| 
      
 1879 
     | 
    
         
            +
                    (node->block == NULL || PM_NODE_TYPE_P(node->block, PM_BLOCK_ARGUMENT_NODE))
         
     | 
| 
       1849 
1880 
     | 
    
         
             
                );
         
     | 
| 
       1850 
1881 
     | 
    
         
             
            }
         
     | 
| 
       1851 
1882 
     | 
    
         | 
| 
         @@ -2101,6 +2132,63 @@ pm_index_or_write_node_create(pm_parser_t *parser, pm_call_node_t *target, const 
     | 
|
| 
       2101 
2132 
     | 
    
         
             
                return node;
         
     | 
| 
       2102 
2133 
     | 
    
         
             
            }
         
     | 
| 
       2103 
2134 
     | 
    
         | 
| 
      
 2135 
     | 
    
         
            +
            /**
         
     | 
| 
      
 2136 
     | 
    
         
            +
             * Allocate and initialize a new CallTargetNode node from an existing call
         
     | 
| 
      
 2137 
     | 
    
         
            +
             * node.
         
     | 
| 
      
 2138 
     | 
    
         
            +
             */
         
     | 
| 
      
 2139 
     | 
    
         
            +
            static pm_call_target_node_t *
         
     | 
| 
      
 2140 
     | 
    
         
            +
            pm_call_target_node_create(pm_parser_t *parser, pm_call_node_t *target) {
         
     | 
| 
      
 2141 
     | 
    
         
            +
                pm_call_target_node_t *node = PM_ALLOC_NODE(parser, pm_call_target_node_t);
         
     | 
| 
      
 2142 
     | 
    
         
            +
             
     | 
| 
      
 2143 
     | 
    
         
            +
                *node = (pm_call_target_node_t) {
         
     | 
| 
      
 2144 
     | 
    
         
            +
                    {
         
     | 
| 
      
 2145 
     | 
    
         
            +
                        .type = PM_CALL_TARGET_NODE,
         
     | 
| 
      
 2146 
     | 
    
         
            +
                        .flags = target->base.flags,
         
     | 
| 
      
 2147 
     | 
    
         
            +
                        .location = target->base.location
         
     | 
| 
      
 2148 
     | 
    
         
            +
                    },
         
     | 
| 
      
 2149 
     | 
    
         
            +
                    .receiver = target->receiver,
         
     | 
| 
      
 2150 
     | 
    
         
            +
                    .call_operator_loc = target->call_operator_loc,
         
     | 
| 
      
 2151 
     | 
    
         
            +
                    .name = target->name,
         
     | 
| 
      
 2152 
     | 
    
         
            +
                    .message_loc = target->message_loc
         
     | 
| 
      
 2153 
     | 
    
         
            +
                };
         
     | 
| 
      
 2154 
     | 
    
         
            +
             
     | 
| 
      
 2155 
     | 
    
         
            +
                // Here we're going to free the target, since it is no longer necessary.
         
     | 
| 
      
 2156 
     | 
    
         
            +
                // However, we don't want to call `pm_node_destroy` because we want to keep
         
     | 
| 
      
 2157 
     | 
    
         
            +
                // around all of its children since we just reused them.
         
     | 
| 
      
 2158 
     | 
    
         
            +
                free(target);
         
     | 
| 
      
 2159 
     | 
    
         
            +
             
     | 
| 
      
 2160 
     | 
    
         
            +
                return node;
         
     | 
| 
      
 2161 
     | 
    
         
            +
            }
         
     | 
| 
      
 2162 
     | 
    
         
            +
             
     | 
| 
      
 2163 
     | 
    
         
            +
            /**
         
     | 
| 
      
 2164 
     | 
    
         
            +
             * Allocate and initialize a new IndexTargetNode node from an existing call
         
     | 
| 
      
 2165 
     | 
    
         
            +
             * node.
         
     | 
| 
      
 2166 
     | 
    
         
            +
             */
         
     | 
| 
      
 2167 
     | 
    
         
            +
            static pm_index_target_node_t *
         
     | 
| 
      
 2168 
     | 
    
         
            +
            pm_index_target_node_create(pm_parser_t *parser, pm_call_node_t *target) {
         
     | 
| 
      
 2169 
     | 
    
         
            +
                pm_index_target_node_t *node = PM_ALLOC_NODE(parser, pm_index_target_node_t);
         
     | 
| 
      
 2170 
     | 
    
         
            +
             
     | 
| 
      
 2171 
     | 
    
         
            +
                *node = (pm_index_target_node_t) {
         
     | 
| 
      
 2172 
     | 
    
         
            +
                    {
         
     | 
| 
      
 2173 
     | 
    
         
            +
                        .type = PM_INDEX_TARGET_NODE,
         
     | 
| 
      
 2174 
     | 
    
         
            +
                        .flags = target->base.flags,
         
     | 
| 
      
 2175 
     | 
    
         
            +
                        .location = target->base.location
         
     | 
| 
      
 2176 
     | 
    
         
            +
                    },
         
     | 
| 
      
 2177 
     | 
    
         
            +
                    .receiver = target->receiver,
         
     | 
| 
      
 2178 
     | 
    
         
            +
                    .opening_loc = target->opening_loc,
         
     | 
| 
      
 2179 
     | 
    
         
            +
                    .arguments = target->arguments,
         
     | 
| 
      
 2180 
     | 
    
         
            +
                    .closing_loc = target->closing_loc,
         
     | 
| 
      
 2181 
     | 
    
         
            +
                    .block = target->block
         
     | 
| 
      
 2182 
     | 
    
         
            +
                };
         
     | 
| 
      
 2183 
     | 
    
         
            +
             
     | 
| 
      
 2184 
     | 
    
         
            +
                // Here we're going to free the target, since it is no longer necessary.
         
     | 
| 
      
 2185 
     | 
    
         
            +
                // However, we don't want to call `pm_node_destroy` because we want to keep
         
     | 
| 
      
 2186 
     | 
    
         
            +
                // around all of its children since we just reused them.
         
     | 
| 
      
 2187 
     | 
    
         
            +
                free(target);
         
     | 
| 
      
 2188 
     | 
    
         
            +
             
     | 
| 
      
 2189 
     | 
    
         
            +
                return node;
         
     | 
| 
      
 2190 
     | 
    
         
            +
            }
         
     | 
| 
      
 2191 
     | 
    
         
            +
             
     | 
| 
       2104 
2192 
     | 
    
         
             
            /**
         
     | 
| 
       2105 
2193 
     | 
    
         
             
             * Allocate and initialize a new CapturePatternNode node.
         
     | 
| 
       2106 
2194 
     | 
    
         
             
             */
         
     | 
| 
         @@ -2452,6 +2540,8 @@ pm_constant_path_or_write_node_create(pm_parser_t *parser, pm_constant_path_node 
     | 
|
| 
       2452 
2540 
     | 
    
         
             
             */
         
     | 
| 
       2453 
2541 
     | 
    
         
             
            static pm_constant_path_node_t *
         
     | 
| 
       2454 
2542 
     | 
    
         
             
            pm_constant_path_node_create(pm_parser_t *parser, pm_node_t *parent, const pm_token_t *delimiter, pm_node_t *child) {
         
     | 
| 
      
 2543 
     | 
    
         
            +
                pm_assert_value_expression(parser, parent);
         
     | 
| 
      
 2544 
     | 
    
         
            +
             
     | 
| 
       2455 
2545 
     | 
    
         
             
                pm_constant_path_node_t *node = PM_ALLOC_NODE(parser, pm_constant_path_node_t);
         
     | 
| 
       2456 
2546 
     | 
    
         | 
| 
       2457 
2547 
     | 
    
         
             
                *node = (pm_constant_path_node_t) {
         
     | 
| 
         @@ -2622,6 +2712,7 @@ pm_def_node_create( 
     | 
|
| 
       2622 
2712 
     | 
    
         
             
                pm_parameters_node_t *parameters,
         
     | 
| 
       2623 
2713 
     | 
    
         
             
                pm_node_t *body,
         
     | 
| 
       2624 
2714 
     | 
    
         
             
                pm_constant_id_list_t *locals,
         
     | 
| 
      
 2715 
     | 
    
         
            +
                uint32_t locals_body_index,
         
     | 
| 
       2625 
2716 
     | 
    
         
             
                const pm_token_t *def_keyword,
         
     | 
| 
       2626 
2717 
     | 
    
         
             
                const pm_token_t *operator,
         
     | 
| 
       2627 
2718 
     | 
    
         
             
                const pm_token_t *lparen,
         
     | 
| 
         @@ -2649,6 +2740,7 @@ pm_def_node_create( 
     | 
|
| 
       2649 
2740 
     | 
    
         
             
                    .parameters = parameters,
         
     | 
| 
       2650 
2741 
     | 
    
         
             
                    .body = body,
         
     | 
| 
       2651 
2742 
     | 
    
         
             
                    .locals = *locals,
         
     | 
| 
      
 2743 
     | 
    
         
            +
                    .locals_body_index = locals_body_index,
         
     | 
| 
       2652 
2744 
     | 
    
         
             
                    .def_keyword_loc = PM_LOCATION_TOKEN_VALUE(def_keyword),
         
     | 
| 
       2653 
2745 
     | 
    
         
             
                    .operator_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(operator),
         
     | 
| 
       2654 
2746 
     | 
    
         
             
                    .lparen_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(lparen),
         
     | 
| 
         @@ -3256,10 +3348,16 @@ static inline void 
     | 
|
| 
       3256 
3348 
     | 
    
         
             
            pm_hash_node_elements_append(pm_hash_node_t *hash, pm_node_t *element) {
         
     | 
| 
       3257 
3349 
     | 
    
         
             
                pm_node_list_append(&hash->elements, element);
         
     | 
| 
       3258 
3350 
     | 
    
         | 
| 
       3259 
     | 
    
         
            -
                 
     | 
| 
       3260 
     | 
    
         
            -
                 
     | 
| 
       3261 
     | 
    
         
            -
             
     | 
| 
       3262 
     | 
    
         
            -
                     
     | 
| 
      
 3351 
     | 
    
         
            +
                bool static_literal = PM_NODE_TYPE_P(element, PM_ASSOC_NODE);
         
     | 
| 
      
 3352 
     | 
    
         
            +
                if (static_literal) {
         
     | 
| 
      
 3353 
     | 
    
         
            +
                    pm_assoc_node_t *assoc = (pm_assoc_node_t *) element;
         
     | 
| 
      
 3354 
     | 
    
         
            +
                    static_literal = !PM_NODE_TYPE_P(assoc->key, PM_ARRAY_NODE) && !PM_NODE_TYPE_P(assoc->key, PM_HASH_NODE) && !PM_NODE_TYPE_P(assoc->key, PM_RANGE_NODE);
         
     | 
| 
      
 3355 
     | 
    
         
            +
                    static_literal = static_literal && PM_NODE_FLAG_P(assoc->key, PM_NODE_FLAG_STATIC_LITERAL);
         
     | 
| 
      
 3356 
     | 
    
         
            +
                    static_literal = static_literal && PM_NODE_FLAG_P(assoc, PM_NODE_FLAG_STATIC_LITERAL);
         
     | 
| 
      
 3357 
     | 
    
         
            +
                }
         
     | 
| 
      
 3358 
     | 
    
         
            +
             
     | 
| 
      
 3359 
     | 
    
         
            +
                if (!static_literal) {
         
     | 
| 
      
 3360 
     | 
    
         
            +
                    pm_node_flag_unset((pm_node_t *)hash, PM_NODE_FLAG_STATIC_LITERAL);
         
     | 
| 
       3263 
3361 
     | 
    
         
             
                }
         
     | 
| 
       3264 
3362 
     | 
    
         
             
            }
         
     | 
| 
       3265 
3363 
     | 
    
         | 
| 
         @@ -3416,6 +3514,25 @@ pm_implicit_node_create(pm_parser_t *parser, pm_node_t *value) { 
     | 
|
| 
       3416 
3514 
     | 
    
         
             
                return node;
         
     | 
| 
       3417 
3515 
     | 
    
         
             
            }
         
     | 
| 
       3418 
3516 
     | 
    
         | 
| 
      
 3517 
     | 
    
         
            +
            /**
         
     | 
| 
      
 3518 
     | 
    
         
            +
             * Allocate and initialize a new ImplicitRestNode node.
         
     | 
| 
      
 3519 
     | 
    
         
            +
             */
         
     | 
| 
      
 3520 
     | 
    
         
            +
            static pm_implicit_rest_node_t *
         
     | 
| 
      
 3521 
     | 
    
         
            +
            pm_implicit_rest_node_create(pm_parser_t *parser, const pm_token_t *token) {
         
     | 
| 
      
 3522 
     | 
    
         
            +
                assert(token->type == PM_TOKEN_COMMA);
         
     | 
| 
      
 3523 
     | 
    
         
            +
             
     | 
| 
      
 3524 
     | 
    
         
            +
                pm_implicit_rest_node_t *node = PM_ALLOC_NODE(parser, pm_implicit_rest_node_t);
         
     | 
| 
      
 3525 
     | 
    
         
            +
             
     | 
| 
      
 3526 
     | 
    
         
            +
                *node = (pm_implicit_rest_node_t) {
         
     | 
| 
      
 3527 
     | 
    
         
            +
                    {
         
     | 
| 
      
 3528 
     | 
    
         
            +
                        .type = PM_IMPLICIT_REST_NODE,
         
     | 
| 
      
 3529 
     | 
    
         
            +
                        .location = PM_LOCATION_TOKEN_VALUE(token)
         
     | 
| 
      
 3530 
     | 
    
         
            +
                    }
         
     | 
| 
      
 3531 
     | 
    
         
            +
                };
         
     | 
| 
      
 3532 
     | 
    
         
            +
             
     | 
| 
      
 3533 
     | 
    
         
            +
                return node;
         
     | 
| 
      
 3534 
     | 
    
         
            +
            }
         
     | 
| 
      
 3535 
     | 
    
         
            +
             
     | 
| 
       3419 
3536 
     | 
    
         
             
            /**
         
     | 
| 
       3420 
3537 
     | 
    
         
             
             * Allocate and initialize a new IntegerNode node.
         
     | 
| 
       3421 
3538 
     | 
    
         
             
             */
         
     | 
| 
         @@ -3697,7 +3814,7 @@ static inline void 
     | 
|
| 
       3697 
3814 
     | 
    
         
             
            pm_interpolated_regular_expression_node_closing_set(pm_interpolated_regular_expression_node_t *node, const pm_token_t *closing) {
         
     | 
| 
       3698 
3815 
     | 
    
         
             
                node->closing_loc = PM_LOCATION_TOKEN_VALUE(closing);
         
     | 
| 
       3699 
3816 
     | 
    
         
             
                node->base.location.end = closing->end;
         
     | 
| 
       3700 
     | 
    
         
            -
                node 
     | 
| 
      
 3817 
     | 
    
         
            +
                pm_node_flag_set((pm_node_t *)node, pm_regular_expression_flags_create(closing));
         
     | 
| 
       3701 
3818 
     | 
    
         
             
            }
         
     | 
| 
       3702 
3819 
     | 
    
         | 
| 
       3703 
3820 
     | 
    
         
             
            /**
         
     | 
| 
         @@ -3831,7 +3948,8 @@ pm_keyword_hash_node_create(pm_parser_t *parser) { 
     | 
|
| 
       3831 
3948 
     | 
    
         
             
                *node = (pm_keyword_hash_node_t) {
         
     | 
| 
       3832 
3949 
     | 
    
         
             
                    .base = {
         
     | 
| 
       3833 
3950 
     | 
    
         
             
                        .type = PM_KEYWORD_HASH_NODE,
         
     | 
| 
       3834 
     | 
    
         
            -
                        .location = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE
         
     | 
| 
      
 3951 
     | 
    
         
            +
                        .location = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE,
         
     | 
| 
      
 3952 
     | 
    
         
            +
                        .flags = PM_KEYWORD_HASH_NODE_FLAGS_SYMBOL_KEYS
         
     | 
| 
       3835 
3953 
     | 
    
         
             
                    },
         
     | 
| 
       3836 
3954 
     | 
    
         
             
                    .elements = { 0 }
         
     | 
| 
       3837 
3955 
     | 
    
         
             
                };
         
     | 
| 
         @@ -3844,6 +3962,13 @@ pm_keyword_hash_node_create(pm_parser_t *parser) { 
     | 
|
| 
       3844 
3962 
     | 
    
         
             
             */
         
     | 
| 
       3845 
3963 
     | 
    
         
             
            static void
         
     | 
| 
       3846 
3964 
     | 
    
         
             
            pm_keyword_hash_node_elements_append(pm_keyword_hash_node_t *hash, pm_node_t *element) {
         
     | 
| 
      
 3965 
     | 
    
         
            +
                // If the element being added is not an AssocNode or does not have a symbol key, then
         
     | 
| 
      
 3966 
     | 
    
         
            +
                // we want to turn the STATIC_KEYS flag off.
         
     | 
| 
      
 3967 
     | 
    
         
            +
                // TODO: Rename the flag to SYMBOL_KEYS instead.
         
     | 
| 
      
 3968 
     | 
    
         
            +
                if (!PM_NODE_TYPE_P(element, PM_ASSOC_NODE) || !PM_NODE_TYPE_P(((pm_assoc_node_t *) element)->key, PM_SYMBOL_NODE)) {
         
     | 
| 
      
 3969 
     | 
    
         
            +
                    pm_node_flag_unset((pm_node_t *)hash, PM_KEYWORD_HASH_NODE_FLAGS_SYMBOL_KEYS);
         
     | 
| 
      
 3970 
     | 
    
         
            +
                }
         
     | 
| 
      
 3971 
     | 
    
         
            +
             
     | 
| 
       3847 
3972 
     | 
    
         
             
                pm_node_list_append(&hash->elements, element);
         
     | 
| 
       3848 
3973 
     | 
    
         
             
                if (hash->base.location.start == NULL) {
         
     | 
| 
       3849 
3974 
     | 
    
         
             
                    hash->base.location.start = element->location.start;
         
     | 
| 
         @@ -3926,10 +4051,11 @@ static pm_lambda_node_t * 
     | 
|
| 
       3926 
4051 
     | 
    
         
             
            pm_lambda_node_create(
         
     | 
| 
       3927 
4052 
     | 
    
         
             
                pm_parser_t *parser,
         
     | 
| 
       3928 
4053 
     | 
    
         
             
                pm_constant_id_list_t *locals,
         
     | 
| 
      
 4054 
     | 
    
         
            +
                uint32_t locals_body_index,
         
     | 
| 
       3929 
4055 
     | 
    
         
             
                const pm_token_t *operator,
         
     | 
| 
       3930 
4056 
     | 
    
         
             
                const pm_token_t *opening,
         
     | 
| 
       3931 
4057 
     | 
    
         
             
                const pm_token_t *closing,
         
     | 
| 
       3932 
     | 
    
         
            -
                 
     | 
| 
      
 4058 
     | 
    
         
            +
                pm_node_t *parameters,
         
     | 
| 
       3933 
4059 
     | 
    
         
             
                pm_node_t *body
         
     | 
| 
       3934 
4060 
     | 
    
         
             
            ) {
         
     | 
| 
       3935 
4061 
     | 
    
         
             
                pm_lambda_node_t *node = PM_ALLOC_NODE(parser, pm_lambda_node_t);
         
     | 
| 
         @@ -3943,6 +4069,7 @@ pm_lambda_node_create( 
     | 
|
| 
       3943 
4069 
     | 
    
         
             
                        },
         
     | 
| 
       3944 
4070 
     | 
    
         
             
                    },
         
     | 
| 
       3945 
4071 
     | 
    
         
             
                    .locals = *locals,
         
     | 
| 
      
 4072 
     | 
    
         
            +
                    .locals_body_index = locals_body_index,
         
     | 
| 
       3946 
4073 
     | 
    
         
             
                    .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
         
     | 
| 
       3947 
4074 
     | 
    
         
             
                    .opening_loc = PM_LOCATION_TOKEN_VALUE(opening),
         
     | 
| 
       3948 
4075 
     | 
    
         
             
                    .closing_loc = PM_LOCATION_TOKEN_VALUE(closing),
         
     | 
| 
         @@ -4038,6 +4165,12 @@ pm_local_variable_or_write_node_create(pm_parser_t *parser, pm_node_t *target, c 
     | 
|
| 
       4038 
4165 
     | 
    
         
             
             */
         
     | 
| 
       4039 
4166 
     | 
    
         
             
            static pm_local_variable_read_node_t *
         
     | 
| 
       4040 
4167 
     | 
    
         
             
            pm_local_variable_read_node_create(pm_parser_t *parser, const pm_token_t *name, uint32_t depth) {
         
     | 
| 
      
 4168 
     | 
    
         
            +
                pm_constant_id_t name_id = pm_parser_constant_id_token(parser, name);
         
     | 
| 
      
 4169 
     | 
    
         
            +
             
     | 
| 
      
 4170 
     | 
    
         
            +
                if (parser->current_param_name == name_id) {
         
     | 
| 
      
 4171 
     | 
    
         
            +
                    pm_parser_err_token(parser, name, PM_ERR_PARAMETER_CIRCULAR);
         
     | 
| 
      
 4172 
     | 
    
         
            +
                }
         
     | 
| 
      
 4173 
     | 
    
         
            +
             
     | 
| 
       4041 
4174 
     | 
    
         
             
                pm_local_variable_read_node_t *node = PM_ALLOC_NODE(parser, pm_local_variable_read_node_t);
         
     | 
| 
       4042 
4175 
     | 
    
         | 
| 
       4043 
4176 
     | 
    
         
             
                *node = (pm_local_variable_read_node_t) {
         
     | 
| 
         @@ -4045,7 +4178,7 @@ pm_local_variable_read_node_create(pm_parser_t *parser, const pm_token_t *name, 
     | 
|
| 
       4045 
4178 
     | 
    
         
             
                        .type = PM_LOCAL_VARIABLE_READ_NODE,
         
     | 
| 
       4046 
4179 
     | 
    
         
             
                        .location = PM_LOCATION_TOKEN_VALUE(name)
         
     | 
| 
       4047 
4180 
     | 
    
         
             
                    },
         
     | 
| 
       4048 
     | 
    
         
            -
                    .name =  
     | 
| 
      
 4181 
     | 
    
         
            +
                    .name = name_id,
         
     | 
| 
       4049 
4182 
     | 
    
         
             
                    .depth = depth
         
     | 
| 
       4050 
4183 
     | 
    
         
             
                };
         
     | 
| 
       4051 
4184 
     | 
    
         | 
| 
         @@ -4132,6 +4265,21 @@ pm_local_variable_target_node_create(pm_parser_t *parser, const pm_token_t *name 
     | 
|
| 
       4132 
4265 
     | 
    
         
             
                );
         
     | 
| 
       4133 
4266 
     | 
    
         
             
            }
         
     | 
| 
       4134 
4267 
     | 
    
         | 
| 
      
 4268 
     | 
    
         
            +
            /**
         
     | 
| 
      
 4269 
     | 
    
         
            +
             * Allocate and initialize a new LocalVariableTargetNode node with the given depth.
         
     | 
| 
      
 4270 
     | 
    
         
            +
             */
         
     | 
| 
      
 4271 
     | 
    
         
            +
            static pm_local_variable_target_node_t *
         
     | 
| 
      
 4272 
     | 
    
         
            +
            pm_local_variable_target_node_create_depth(pm_parser_t *parser, const pm_token_t *name, uint32_t depth) {
         
     | 
| 
      
 4273 
     | 
    
         
            +
                pm_refute_numbered_parameter(parser, name->start, name->end);
         
     | 
| 
      
 4274 
     | 
    
         
            +
             
     | 
| 
      
 4275 
     | 
    
         
            +
                return pm_local_variable_target_node_create_values(
         
     | 
| 
      
 4276 
     | 
    
         
            +
                    parser,
         
     | 
| 
      
 4277 
     | 
    
         
            +
                    &(pm_location_t) { .start = name->start, .end = name->end },
         
     | 
| 
      
 4278 
     | 
    
         
            +
                    pm_parser_constant_id_token(parser, name),
         
     | 
| 
      
 4279 
     | 
    
         
            +
                    depth
         
     | 
| 
      
 4280 
     | 
    
         
            +
                );
         
     | 
| 
      
 4281 
     | 
    
         
            +
            }
         
     | 
| 
      
 4282 
     | 
    
         
            +
             
     | 
| 
       4135 
4283 
     | 
    
         
             
            /**
         
     | 
| 
       4136 
4284 
     | 
    
         
             
             * Allocate and initialize a new MatchPredicateNode node.
         
     | 
| 
       4137 
4285 
     | 
    
         
             
             */
         
     | 
| 
         @@ -4254,7 +4402,7 @@ pm_multi_target_node_create(pm_parser_t *parser) { 
     | 
|
| 
       4254 
4402 
     | 
    
         
             
             */
         
     | 
| 
       4255 
4403 
     | 
    
         
             
            static void
         
     | 
| 
       4256 
4404 
     | 
    
         
             
            pm_multi_target_node_targets_append(pm_parser_t *parser, pm_multi_target_node_t *node, pm_node_t *target) {
         
     | 
| 
       4257 
     | 
    
         
            -
                if (PM_NODE_TYPE_P(target, PM_SPLAT_NODE)) {
         
     | 
| 
      
 4405 
     | 
    
         
            +
                if (PM_NODE_TYPE_P(target, PM_SPLAT_NODE) || PM_NODE_TYPE_P(target, PM_IMPLICIT_REST_NODE)) {
         
     | 
| 
       4258 
4406 
     | 
    
         
             
                    if (node->rest == NULL) {
         
     | 
| 
       4259 
4407 
     | 
    
         
             
                        node->rest = target;
         
     | 
| 
       4260 
4408 
     | 
    
         
             
                    } else {
         
     | 
| 
         @@ -4390,7 +4538,25 @@ pm_no_keywords_parameter_node_create(pm_parser_t *parser, const pm_token_t *oper 
     | 
|
| 
       4390 
4538 
     | 
    
         
             
            }
         
     | 
| 
       4391 
4539 
     | 
    
         | 
| 
       4392 
4540 
     | 
    
         
             
            /**
         
     | 
| 
       4393 
     | 
    
         
            -
             * Allocate a new  
     | 
| 
      
 4541 
     | 
    
         
            +
             * Allocate and initialize a new NumberedParametersNode node.
         
     | 
| 
      
 4542 
     | 
    
         
            +
             */
         
     | 
| 
      
 4543 
     | 
    
         
            +
            static pm_numbered_parameters_node_t *
         
     | 
| 
      
 4544 
     | 
    
         
            +
            pm_numbered_parameters_node_create(pm_parser_t *parser, const pm_location_t *location, uint8_t maximum) {
         
     | 
| 
      
 4545 
     | 
    
         
            +
                pm_numbered_parameters_node_t *node = PM_ALLOC_NODE(parser, pm_numbered_parameters_node_t);
         
     | 
| 
      
 4546 
     | 
    
         
            +
             
     | 
| 
      
 4547 
     | 
    
         
            +
                *node = (pm_numbered_parameters_node_t) {
         
     | 
| 
      
 4548 
     | 
    
         
            +
                    {
         
     | 
| 
      
 4549 
     | 
    
         
            +
                        .type = PM_NUMBERED_PARAMETERS_NODE,
         
     | 
| 
      
 4550 
     | 
    
         
            +
                        .location = *location
         
     | 
| 
      
 4551 
     | 
    
         
            +
                    },
         
     | 
| 
      
 4552 
     | 
    
         
            +
                    .maximum = maximum
         
     | 
| 
      
 4553 
     | 
    
         
            +
                };
         
     | 
| 
      
 4554 
     | 
    
         
            +
             
     | 
| 
      
 4555 
     | 
    
         
            +
                return node;
         
     | 
| 
      
 4556 
     | 
    
         
            +
            }
         
     | 
| 
      
 4557 
     | 
    
         
            +
             
     | 
| 
      
 4558 
     | 
    
         
            +
            /**
         
     | 
| 
      
 4559 
     | 
    
         
            +
             * Allocate and initialize a new NthReferenceReadNode node.
         
     | 
| 
       4394 
4560 
     | 
    
         
             
             */
         
     | 
| 
       4395 
4561 
     | 
    
         
             
            static pm_numbered_reference_read_node_t *
         
     | 
| 
       4396 
4562 
     | 
    
         
             
            pm_numbered_reference_read_node_create(pm_parser_t *parser, const pm_token_t *name) {
         
     | 
| 
         @@ -4530,9 +4696,8 @@ pm_parameters_node_posts_append(pm_parameters_node_t *params, pm_node_t *param) 
     | 
|
| 
       4530 
4696 
     | 
    
         
             
             * Set the rest parameter on a ParametersNode node.
         
     | 
| 
       4531 
4697 
     | 
    
         
             
             */
         
     | 
| 
       4532 
4698 
     | 
    
         
             
            static void
         
     | 
| 
       4533 
     | 
    
         
            -
            pm_parameters_node_rest_set(pm_parameters_node_t *params,  
     | 
| 
       4534 
     | 
    
         
            -
                 
     | 
| 
       4535 
     | 
    
         
            -
                pm_parameters_node_location_set(params, (pm_node_t *) param);
         
     | 
| 
      
 4699 
     | 
    
         
            +
            pm_parameters_node_rest_set(pm_parameters_node_t *params, pm_node_t *param) {
         
     | 
| 
      
 4700 
     | 
    
         
            +
                pm_parameters_node_location_set(params, param);
         
     | 
| 
       4536 
4701 
     | 
    
         
             
                params->rest = param;
         
     | 
| 
       4537 
4702 
     | 
    
         
             
            }
         
     | 
| 
       4538 
4703 
     | 
    
         | 
| 
         @@ -5124,7 +5289,7 @@ pm_statements_node_body_append(pm_statements_node_t *node, pm_node_t *statement) 
     | 
|
| 
       5124 
5289 
     | 
    
         
             
                pm_node_list_append(&node->body, statement);
         
     | 
| 
       5125 
5290 
     | 
    
         | 
| 
       5126 
5291 
     | 
    
         
             
                // Every statement gets marked as a place where a newline can occur.
         
     | 
| 
       5127 
     | 
    
         
            -
                statement 
     | 
| 
      
 5292 
     | 
    
         
            +
                pm_node_flag_set(statement, PM_NODE_FLAG_NEWLINE);
         
     | 
| 
       5128 
5293 
     | 
    
         
             
            }
         
     | 
| 
       5129 
5294 
     | 
    
         | 
| 
       5130 
5295 
     | 
    
         
             
            /**
         
     | 
| 
         @@ -5643,6 +5808,7 @@ pm_xstring_node_create_unescaped(pm_parser_t *parser, const pm_token_t *opening, 
     | 
|
| 
       5643 
5808 
     | 
    
         
             
                *node = (pm_x_string_node_t) {
         
     | 
| 
       5644 
5809 
     | 
    
         
             
                    {
         
     | 
| 
       5645 
5810 
     | 
    
         
             
                        .type = PM_X_STRING_NODE,
         
     | 
| 
      
 5811 
     | 
    
         
            +
                        .flags = PM_STRING_FLAGS_FROZEN,
         
     | 
| 
       5646 
5812 
     | 
    
         
             
                        .location = {
         
     | 
| 
       5647 
5813 
     | 
    
         
             
                            .start = opening->start,
         
     | 
| 
       5648 
5814 
     | 
    
         
             
                            .end = closing->end
         
     | 
| 
         @@ -5718,8 +5884,7 @@ pm_parser_scope_push(pm_parser_t *parser, bool closed) { 
     | 
|
| 
       5718 
5884 
     | 
    
         
             
                    .previous = parser->current_scope,
         
     | 
| 
       5719 
5885 
     | 
    
         
             
                    .closed = closed,
         
     | 
| 
       5720 
5886 
     | 
    
         
             
                    .explicit_params = false,
         
     | 
| 
       5721 
     | 
    
         
            -
                    . 
     | 
| 
       5722 
     | 
    
         
            -
                    .transparent = false
         
     | 
| 
      
 5887 
     | 
    
         
            +
                    .numbered_parameters = 0,
         
     | 
| 
       5723 
5888 
     | 
    
         
             
                };
         
     | 
| 
       5724 
5889 
     | 
    
         | 
| 
       5725 
5890 
     | 
    
         
             
                pm_constant_id_list_init(&scope->locals);
         
     | 
| 
         @@ -5728,27 +5893,6 @@ pm_parser_scope_push(pm_parser_t *parser, bool closed) { 
     | 
|
| 
       5728 
5893 
     | 
    
         
             
                return true;
         
     | 
| 
       5729 
5894 
     | 
    
         
             
            }
         
     | 
| 
       5730 
5895 
     | 
    
         | 
| 
       5731 
     | 
    
         
            -
            /**
         
     | 
| 
       5732 
     | 
    
         
            -
             * Allocate and initialize a new scope. Push it onto the scope stack.
         
     | 
| 
       5733 
     | 
    
         
            -
             */
         
     | 
| 
       5734 
     | 
    
         
            -
            static bool
         
     | 
| 
       5735 
     | 
    
         
            -
            pm_parser_scope_push_transparent(pm_parser_t *parser) {
         
     | 
| 
       5736 
     | 
    
         
            -
                pm_scope_t *scope = (pm_scope_t *) malloc(sizeof(pm_scope_t));
         
     | 
| 
       5737 
     | 
    
         
            -
                if (scope == NULL) return false;
         
     | 
| 
       5738 
     | 
    
         
            -
             
     | 
| 
       5739 
     | 
    
         
            -
                *scope = (pm_scope_t) {
         
     | 
| 
       5740 
     | 
    
         
            -
                    .previous = parser->current_scope,
         
     | 
| 
       5741 
     | 
    
         
            -
                    .closed = false,
         
     | 
| 
       5742 
     | 
    
         
            -
                    .explicit_params = false,
         
     | 
| 
       5743 
     | 
    
         
            -
                    .numbered_params = false,
         
     | 
| 
       5744 
     | 
    
         
            -
                    .transparent = true
         
     | 
| 
       5745 
     | 
    
         
            -
                };
         
     | 
| 
       5746 
     | 
    
         
            -
             
     | 
| 
       5747 
     | 
    
         
            -
                parser->current_scope = scope;
         
     | 
| 
       5748 
     | 
    
         
            -
             
     | 
| 
       5749 
     | 
    
         
            -
                return true;
         
     | 
| 
       5750 
     | 
    
         
            -
            }
         
     | 
| 
       5751 
     | 
    
         
            -
             
     | 
| 
       5752 
5896 
     | 
    
         
             
            /**
         
     | 
| 
       5753 
5897 
     | 
    
         
             
             * Check if any of the currently visible scopes contain a local variable
         
     | 
| 
       5754 
5898 
     | 
    
         
             
             * described by the given constant id.
         
     | 
| 
         @@ -5759,7 +5903,7 @@ pm_parser_local_depth_constant_id(pm_parser_t *parser, pm_constant_id_t constant 
     | 
|
| 
       5759 
5903 
     | 
    
         
             
                int depth = 0;
         
     | 
| 
       5760 
5904 
     | 
    
         | 
| 
       5761 
5905 
     | 
    
         
             
                while (scope != NULL) {
         
     | 
| 
       5762 
     | 
    
         
            -
                    if ( 
     | 
| 
      
 5906 
     | 
    
         
            +
                    if (pm_constant_id_list_includes(&scope->locals, constant_id)) return depth;
         
     | 
| 
       5763 
5907 
     | 
    
         
             
                    if (scope->closed) break;
         
     | 
| 
       5764 
5908 
     | 
    
         | 
| 
       5765 
5909 
     | 
    
         
             
                    scope = scope->previous;
         
     | 
| 
         @@ -5784,15 +5928,19 @@ pm_parser_local_depth(pm_parser_t *parser, pm_token_t *token) { 
     | 
|
| 
       5784 
5928 
     | 
    
         
             
             */
         
     | 
| 
       5785 
5929 
     | 
    
         
             
            static inline void
         
     | 
| 
       5786 
5930 
     | 
    
         
             
            pm_parser_local_add(pm_parser_t *parser, pm_constant_id_t constant_id) {
         
     | 
| 
       5787 
     | 
    
         
            -
                 
     | 
| 
       5788 
     | 
    
         
            -
             
     | 
| 
       5789 
     | 
    
         
            -
             
     | 
| 
       5790 
     | 
    
         
            -
                assert(scope != NULL);
         
     | 
| 
       5791 
     | 
    
         
            -
                if (!pm_constant_id_list_includes(&scope->locals, constant_id)) {
         
     | 
| 
       5792 
     | 
    
         
            -
                    pm_constant_id_list_append(&scope->locals, constant_id);
         
     | 
| 
      
 5931 
     | 
    
         
            +
                if (!pm_constant_id_list_includes(&parser->current_scope->locals, constant_id)) {
         
     | 
| 
      
 5932 
     | 
    
         
            +
                    pm_constant_id_list_append(&parser->current_scope->locals, constant_id);
         
     | 
| 
       5793 
5933 
     | 
    
         
             
                }
         
     | 
| 
       5794 
5934 
     | 
    
         
             
            }
         
     | 
| 
       5795 
5935 
     | 
    
         | 
| 
      
 5936 
     | 
    
         
            +
            /**
         
     | 
| 
      
 5937 
     | 
    
         
            +
             * Set the numbered_parameters value of the current scope.
         
     | 
| 
      
 5938 
     | 
    
         
            +
             */
         
     | 
| 
      
 5939 
     | 
    
         
            +
            static inline void
         
     | 
| 
      
 5940 
     | 
    
         
            +
            pm_parser_numbered_parameters_set(pm_parser_t *parser, uint8_t numbered_parameters) {
         
     | 
| 
      
 5941 
     | 
    
         
            +
                parser->current_scope->numbered_parameters = numbered_parameters;
         
     | 
| 
      
 5942 
     | 
    
         
            +
            }
         
     | 
| 
      
 5943 
     | 
    
         
            +
             
     | 
| 
       5796 
5944 
     | 
    
         
             
            /**
         
     | 
| 
       5797 
5945 
     | 
    
         
             
             * Add a local variable from a location to the current scope.
         
     | 
| 
       5798 
5946 
     | 
    
         
             
             */
         
     | 
| 
         @@ -5869,12 +6017,12 @@ static inline size_t 
     | 
|
| 
       5869 
6017 
     | 
    
         
             
            char_is_identifier_start(pm_parser_t *parser, const uint8_t *b) {
         
     | 
| 
       5870 
6018 
     | 
    
         
             
                if (parser->encoding_changed) {
         
     | 
| 
       5871 
6019 
     | 
    
         
             
                    size_t width;
         
     | 
| 
       5872 
     | 
    
         
            -
                    if ((width = parser->encoding 
     | 
| 
      
 6020 
     | 
    
         
            +
                    if ((width = parser->encoding->alpha_char(b, parser->end - b)) != 0) {
         
     | 
| 
       5873 
6021 
     | 
    
         
             
                        return width;
         
     | 
| 
       5874 
6022 
     | 
    
         
             
                    } else if (*b == '_') {
         
     | 
| 
       5875 
6023 
     | 
    
         
             
                        return 1;
         
     | 
| 
       5876 
6024 
     | 
    
         
             
                    } else if (*b >= 0x80) {
         
     | 
| 
       5877 
     | 
    
         
            -
                        return parser->encoding 
     | 
| 
      
 6025 
     | 
    
         
            +
                        return parser->encoding->char_width(b, parser->end - b);
         
     | 
| 
       5878 
6026 
     | 
    
         
             
                    } else {
         
     | 
| 
       5879 
6027 
     | 
    
         
             
                        return 0;
         
     | 
| 
       5880 
6028 
     | 
    
         
             
                    }
         
     | 
| 
         @@ -5885,6 +6033,19 @@ char_is_identifier_start(pm_parser_t *parser, const uint8_t *b) { 
     | 
|
| 
       5885 
6033 
     | 
    
         
             
                }
         
     | 
| 
       5886 
6034 
     | 
    
         
             
            }
         
     | 
| 
       5887 
6035 
     | 
    
         | 
| 
      
 6036 
     | 
    
         
            +
            /**
         
     | 
| 
      
 6037 
     | 
    
         
            +
             * Similar to char_is_identifier but this function assumes that the encoding
         
     | 
| 
      
 6038 
     | 
    
         
            +
             * has not been changed.
         
     | 
| 
      
 6039 
     | 
    
         
            +
             */
         
     | 
| 
      
 6040 
     | 
    
         
            +
            static inline size_t
         
     | 
| 
      
 6041 
     | 
    
         
            +
            char_is_identifier_utf8(const uint8_t *b, const uint8_t *end) {
         
     | 
| 
      
 6042 
     | 
    
         
            +
                if (*b < 0x80) {
         
     | 
| 
      
 6043 
     | 
    
         
            +
                    return (*b == '_') || (pm_encoding_unicode_table[*b] & PRISM_ENCODING_ALPHANUMERIC_BIT ? 1 : 0);
         
     | 
| 
      
 6044 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 6045 
     | 
    
         
            +
                    return (size_t) (pm_encoding_utf_8_alnum_char(b, end - b) || 1u);
         
     | 
| 
      
 6046 
     | 
    
         
            +
                }
         
     | 
| 
      
 6047 
     | 
    
         
            +
            }
         
     | 
| 
      
 6048 
     | 
    
         
            +
             
     | 
| 
       5888 
6049 
     | 
    
         
             
            /**
         
     | 
| 
       5889 
6050 
     | 
    
         
             
             * Like the above, this function is also used extremely frequently to lex all of
         
     | 
| 
       5890 
6051 
     | 
    
         
             
             * the identifiers in a source file once the first character has been found. So
         
     | 
| 
         @@ -5894,20 +6055,17 @@ static inline size_t 
     | 
|
| 
       5894 
6055 
     | 
    
         
             
            char_is_identifier(pm_parser_t *parser, const uint8_t *b) {
         
     | 
| 
       5895 
6056 
     | 
    
         
             
                if (parser->encoding_changed) {
         
     | 
| 
       5896 
6057 
     | 
    
         
             
                    size_t width;
         
     | 
| 
       5897 
     | 
    
         
            -
                    if ((width = parser->encoding 
     | 
| 
      
 6058 
     | 
    
         
            +
                    if ((width = parser->encoding->alnum_char(b, parser->end - b)) != 0) {
         
     | 
| 
       5898 
6059 
     | 
    
         
             
                        return width;
         
     | 
| 
       5899 
6060 
     | 
    
         
             
                    } else if (*b == '_') {
         
     | 
| 
       5900 
6061 
     | 
    
         
             
                        return 1;
         
     | 
| 
       5901 
6062 
     | 
    
         
             
                    } else if (*b >= 0x80) {
         
     | 
| 
       5902 
     | 
    
         
            -
                        return parser->encoding 
     | 
| 
      
 6063 
     | 
    
         
            +
                        return parser->encoding->char_width(b, parser->end - b);
         
     | 
| 
       5903 
6064 
     | 
    
         
             
                    } else {
         
     | 
| 
       5904 
6065 
     | 
    
         
             
                        return 0;
         
     | 
| 
       5905 
6066 
     | 
    
         
             
                    }
         
     | 
| 
       5906 
     | 
    
         
            -
                } else if (*b < 0x80) {
         
     | 
| 
       5907 
     | 
    
         
            -
                    return (pm_encoding_unicode_table[*b] & PRISM_ENCODING_ALPHANUMERIC_BIT ? 1 : 0) || (*b == '_');
         
     | 
| 
       5908 
     | 
    
         
            -
                } else {
         
     | 
| 
       5909 
     | 
    
         
            -
                    return (size_t) (pm_encoding_utf_8_alnum_char(b, parser->end - b) || 1u);
         
     | 
| 
       5910 
6067 
     | 
    
         
             
                }
         
     | 
| 
      
 6068 
     | 
    
         
            +
                return char_is_identifier_utf8(b, parser->end);
         
     | 
| 
       5911 
6069 
     | 
    
         
             
            }
         
     | 
| 
       5912 
6070 
     | 
    
         | 
| 
       5913 
6071 
     | 
    
         
             
            // Here we're defining a perfect hash for the characters that are allowed in
         
     | 
| 
         @@ -6082,195 +6240,18 @@ next_newline(const uint8_t *cursor, ptrdiff_t length) { 
     | 
|
| 
       6082 
6240 
     | 
    
         
             
             */
         
     | 
| 
       6083 
6241 
     | 
    
         
             
            static bool
         
     | 
| 
       6084 
6242 
     | 
    
         
             
            parser_lex_magic_comment_encoding_value(pm_parser_t *parser, const uint8_t *start, const uint8_t *end) {
         
     | 
| 
       6085 
     | 
    
         
            -
                 
     | 
| 
       6086 
     | 
    
         
            -
             
     | 
| 
       6087 
     | 
    
         
            -
                // First, we're going to call out to a user-defined callback if one was
         
     | 
| 
       6088 
     | 
    
         
            -
                // provided. If they return an encoding struct that we can use, then we'll
         
     | 
| 
       6089 
     | 
    
         
            -
                // use that here.
         
     | 
| 
       6090 
     | 
    
         
            -
                if (parser->encoding_decode_callback != NULL) {
         
     | 
| 
       6091 
     | 
    
         
            -
                    pm_encoding_t *encoding = parser->encoding_decode_callback(parser, start, width);
         
     | 
| 
      
 6243 
     | 
    
         
            +
                const pm_encoding_t *encoding = pm_encoding_find(start, end);
         
     | 
| 
       6092 
6244 
     | 
    
         | 
| 
       6093 
     | 
    
         
            -
             
     | 
| 
       6094 
     | 
    
         
            -
             
     | 
| 
       6095 
     | 
    
         
            -
                         
     | 
| 
       6096 
     | 
    
         
            -
                    }
         
     | 
| 
       6097 
     | 
    
         
            -
                }
         
     | 
| 
       6098 
     | 
    
         
            -
             
     | 
| 
       6099 
     | 
    
         
            -
                // Next, we're going to check for UTF-8. This is the most common encoding.
         
     | 
| 
       6100 
     | 
    
         
            -
                // utf-8 can contain extra information at the end about the platform it is
         
     | 
| 
       6101 
     | 
    
         
            -
                // encoded on, such as utf-8-mac or utf-8-unix. We'll ignore those suffixes.
         
     | 
| 
       6102 
     | 
    
         
            -
                if ((start + 5 <= end) && (pm_strncasecmp(start, (const uint8_t *) "utf-8", 5) == 0)) {
         
     | 
| 
       6103 
     | 
    
         
            -
                    // We need to explicitly handle utf-8-hfs, as that one needs to switch
         
     | 
| 
       6104 
     | 
    
         
            -
                    // over to being utf8-mac.
         
     | 
| 
       6105 
     | 
    
         
            -
                    if (width == 9 && (pm_strncasecmp(start + 5, (const uint8_t *) "-hfs", 4) == 0)) {
         
     | 
| 
       6106 
     | 
    
         
            -
                        parser->encoding = pm_encoding_utf8_mac;
         
     | 
| 
      
 6245 
     | 
    
         
            +
                if (encoding != NULL) {
         
     | 
| 
      
 6246 
     | 
    
         
            +
                    if (encoding != PM_ENCODING_UTF_8_ENTRY) {
         
     | 
| 
      
 6247 
     | 
    
         
            +
                        parser->encoding = encoding;
         
     | 
| 
       6107 
6248 
     | 
    
         
             
                        parser->encoding_changed = true;
         
     | 
| 
       6108 
6249 
     | 
    
         
             
                        if (parser->encoding_changed_callback != NULL) parser->encoding_changed_callback(parser);
         
     | 
| 
       6109 
     | 
    
         
            -
                        return true;
         
     | 
| 
       6110 
6250 
     | 
    
         
             
                    }
         
     | 
| 
       6111 
6251 
     | 
    
         | 
| 
       6112 
     | 
    
         
            -
                    // We don't need to do anything here because the default encoding is
         
     | 
| 
       6113 
     | 
    
         
            -
                    // already UTF-8. We'll just return.
         
     | 
| 
       6114 
6252 
     | 
    
         
             
                    return true;
         
     | 
| 
       6115 
6253 
     | 
    
         
             
                }
         
     | 
| 
       6116 
6254 
     | 
    
         | 
| 
       6117 
     | 
    
         
            -
                // Next, we're going to loop through each of the encodings that we handle
         
     | 
| 
       6118 
     | 
    
         
            -
                // explicitly. If we found one that we understand, we'll use that value.
         
     | 
| 
       6119 
     | 
    
         
            -
            #define ENCODING1(value, prebuilt) \
         
     | 
| 
       6120 
     | 
    
         
            -
                if (width == sizeof(value) - 1 && start + width <= end && pm_strncasecmp(start, (const uint8_t *) value, width) == 0) { \
         
     | 
| 
       6121 
     | 
    
         
            -
                    parser->encoding = prebuilt; \
         
     | 
| 
       6122 
     | 
    
         
            -
                    parser->encoding_changed = true; \
         
     | 
| 
       6123 
     | 
    
         
            -
                    if (parser->encoding_changed_callback != NULL) parser->encoding_changed_callback(parser); \
         
     | 
| 
       6124 
     | 
    
         
            -
                    return true; \
         
     | 
| 
       6125 
     | 
    
         
            -
                }
         
     | 
| 
       6126 
     | 
    
         
            -
             
     | 
| 
       6127 
     | 
    
         
            -
                // A convenience macros for comparing two aliases for the same encoding.
         
     | 
| 
       6128 
     | 
    
         
            -
            #define ENCODING2(value1, value2, prebuilt) ENCODING1(value1, prebuilt) ENCODING1(value2, prebuilt)
         
     | 
| 
       6129 
     | 
    
         
            -
             
     | 
| 
       6130 
     | 
    
         
            -
                if (width >= 3) {
         
     | 
| 
       6131 
     | 
    
         
            -
                    switch (*start) {
         
     | 
| 
       6132 
     | 
    
         
            -
                        case 'A': case 'a':
         
     | 
| 
       6133 
     | 
    
         
            -
                            ENCODING1("ASCII", pm_encoding_ascii);
         
     | 
| 
       6134 
     | 
    
         
            -
                            ENCODING1("ASCII-8BIT", pm_encoding_ascii_8bit);
         
     | 
| 
       6135 
     | 
    
         
            -
                            ENCODING1("ANSI_X3.4-1968", pm_encoding_ascii);
         
     | 
| 
       6136 
     | 
    
         
            -
                            break;
         
     | 
| 
       6137 
     | 
    
         
            -
                        case 'B': case 'b':
         
     | 
| 
       6138 
     | 
    
         
            -
                            ENCODING1("BINARY", pm_encoding_ascii_8bit);
         
     | 
| 
       6139 
     | 
    
         
            -
                            ENCODING1("Big5", pm_encoding_big5);
         
     | 
| 
       6140 
     | 
    
         
            -
                            ENCODING1("Big5-HKSCS", pm_encoding_big5_hkscs);
         
     | 
| 
       6141 
     | 
    
         
            -
                            ENCODING1("Big5-UAO", pm_encoding_big5_uao);
         
     | 
| 
       6142 
     | 
    
         
            -
                            break;
         
     | 
| 
       6143 
     | 
    
         
            -
                        case 'C': case 'c':
         
     | 
| 
       6144 
     | 
    
         
            -
                            ENCODING1("CP437", pm_encoding_ibm437);
         
     | 
| 
       6145 
     | 
    
         
            -
                            ENCODING1("CP720", pm_encoding_ibm720);
         
     | 
| 
       6146 
     | 
    
         
            -
                            ENCODING1("CP737", pm_encoding_ibm737);
         
     | 
| 
       6147 
     | 
    
         
            -
                            ENCODING1("CP775", pm_encoding_ibm775);
         
     | 
| 
       6148 
     | 
    
         
            -
                            ENCODING1("CP850", pm_encoding_cp850);
         
     | 
| 
       6149 
     | 
    
         
            -
                            ENCODING1("CP852", pm_encoding_cp852);
         
     | 
| 
       6150 
     | 
    
         
            -
                            ENCODING1("CP855", pm_encoding_cp855);
         
     | 
| 
       6151 
     | 
    
         
            -
                            ENCODING1("CP857", pm_encoding_ibm857);
         
     | 
| 
       6152 
     | 
    
         
            -
                            ENCODING1("CP860", pm_encoding_ibm860);
         
     | 
| 
       6153 
     | 
    
         
            -
                            ENCODING1("CP861", pm_encoding_ibm861);
         
     | 
| 
       6154 
     | 
    
         
            -
                            ENCODING1("CP862", pm_encoding_ibm862);
         
     | 
| 
       6155 
     | 
    
         
            -
                            ENCODING1("CP864", pm_encoding_ibm864);
         
     | 
| 
       6156 
     | 
    
         
            -
                            ENCODING1("CP865", pm_encoding_ibm865);
         
     | 
| 
       6157 
     | 
    
         
            -
                            ENCODING1("CP866", pm_encoding_ibm866);
         
     | 
| 
       6158 
     | 
    
         
            -
                            ENCODING1("CP869", pm_encoding_ibm869);
         
     | 
| 
       6159 
     | 
    
         
            -
                            ENCODING1("CP874", pm_encoding_windows_874);
         
     | 
| 
       6160 
     | 
    
         
            -
                            ENCODING1("CP878", pm_encoding_koi8_r);
         
     | 
| 
       6161 
     | 
    
         
            -
                            ENCODING1("CP863", pm_encoding_ibm863);
         
     | 
| 
       6162 
     | 
    
         
            -
                            ENCODING2("CP932", "csWindows31J", pm_encoding_windows_31j);
         
     | 
| 
       6163 
     | 
    
         
            -
                            ENCODING1("CP936", pm_encoding_gbk);
         
     | 
| 
       6164 
     | 
    
         
            -
                            ENCODING1("CP1250", pm_encoding_windows_1250);
         
     | 
| 
       6165 
     | 
    
         
            -
                            ENCODING1("CP1251", pm_encoding_windows_1251);
         
     | 
| 
       6166 
     | 
    
         
            -
                            ENCODING1("CP1252", pm_encoding_windows_1252);
         
     | 
| 
       6167 
     | 
    
         
            -
                            ENCODING1("CP1253", pm_encoding_windows_1253);
         
     | 
| 
       6168 
     | 
    
         
            -
                            ENCODING1("CP1254", pm_encoding_windows_1254);
         
     | 
| 
       6169 
     | 
    
         
            -
                            ENCODING1("CP1255", pm_encoding_windows_1255);
         
     | 
| 
       6170 
     | 
    
         
            -
                            ENCODING1("CP1256", pm_encoding_windows_1256);
         
     | 
| 
       6171 
     | 
    
         
            -
                            ENCODING1("CP1257", pm_encoding_windows_1257);
         
     | 
| 
       6172 
     | 
    
         
            -
                            ENCODING1("CP1258", pm_encoding_windows_1258);
         
     | 
| 
       6173 
     | 
    
         
            -
                            ENCODING1("CP51932", pm_encoding_cp51932);
         
     | 
| 
       6174 
     | 
    
         
            -
                            ENCODING1("CP65001", pm_encoding_utf_8);
         
     | 
| 
       6175 
     | 
    
         
            -
                            break;
         
     | 
| 
       6176 
     | 
    
         
            -
                        case 'E': case 'e':
         
     | 
| 
       6177 
     | 
    
         
            -
                            ENCODING2("EUC-JP", "eucJP", pm_encoding_euc_jp);
         
     | 
| 
       6178 
     | 
    
         
            -
                            ENCODING1("external", pm_encoding_utf_8);
         
     | 
| 
       6179 
     | 
    
         
            -
                            break;
         
     | 
| 
       6180 
     | 
    
         
            -
                        case 'F': case 'f':
         
     | 
| 
       6181 
     | 
    
         
            -
                            ENCODING1("filesystem", pm_encoding_utf_8);
         
     | 
| 
       6182 
     | 
    
         
            -
                            break;
         
     | 
| 
       6183 
     | 
    
         
            -
                        case 'G': case 'g':
         
     | 
| 
       6184 
     | 
    
         
            -
                            ENCODING1("GB1988", pm_encoding_gb1988);
         
     | 
| 
       6185 
     | 
    
         
            -
                            ENCODING1("GBK", pm_encoding_gbk);
         
     | 
| 
       6186 
     | 
    
         
            -
                            break;
         
     | 
| 
       6187 
     | 
    
         
            -
                        case 'I': case 'i':
         
     | 
| 
       6188 
     | 
    
         
            -
                            ENCODING1("IBM437", pm_encoding_ibm437);
         
     | 
| 
       6189 
     | 
    
         
            -
                            ENCODING1("IBM720", pm_encoding_ibm720);
         
     | 
| 
       6190 
     | 
    
         
            -
                            ENCODING1("IBM737", pm_encoding_ibm737);
         
     | 
| 
       6191 
     | 
    
         
            -
                            ENCODING1("IBM775", pm_encoding_ibm775);
         
     | 
| 
       6192 
     | 
    
         
            -
                            ENCODING1("IBM850", pm_encoding_cp850);
         
     | 
| 
       6193 
     | 
    
         
            -
                            ENCODING1("IBM852", pm_encoding_ibm852);
         
     | 
| 
       6194 
     | 
    
         
            -
                            ENCODING1("IBM855", pm_encoding_ibm855);
         
     | 
| 
       6195 
     | 
    
         
            -
                            ENCODING1("IBM857", pm_encoding_ibm857);
         
     | 
| 
       6196 
     | 
    
         
            -
                            ENCODING1("IBM860", pm_encoding_ibm860);
         
     | 
| 
       6197 
     | 
    
         
            -
                            ENCODING1("IBM861", pm_encoding_ibm861);
         
     | 
| 
       6198 
     | 
    
         
            -
                            ENCODING1("IBM862", pm_encoding_ibm862);
         
     | 
| 
       6199 
     | 
    
         
            -
                            ENCODING1("IBM863", pm_encoding_ibm863);
         
     | 
| 
       6200 
     | 
    
         
            -
                            ENCODING1("IBM864", pm_encoding_ibm864);
         
     | 
| 
       6201 
     | 
    
         
            -
                            ENCODING1("IBM865", pm_encoding_ibm865);
         
     | 
| 
       6202 
     | 
    
         
            -
                            ENCODING1("IBM866", pm_encoding_ibm866);
         
     | 
| 
       6203 
     | 
    
         
            -
                            ENCODING1("IBM869", pm_encoding_ibm869);
         
     | 
| 
       6204 
     | 
    
         
            -
                            ENCODING2("ISO-8859-1", "ISO8859-1", pm_encoding_iso_8859_1);
         
     | 
| 
       6205 
     | 
    
         
            -
                            ENCODING2("ISO-8859-2", "ISO8859-2", pm_encoding_iso_8859_2);
         
     | 
| 
       6206 
     | 
    
         
            -
                            ENCODING2("ISO-8859-3", "ISO8859-3", pm_encoding_iso_8859_3);
         
     | 
| 
       6207 
     | 
    
         
            -
                            ENCODING2("ISO-8859-4", "ISO8859-4", pm_encoding_iso_8859_4);
         
     | 
| 
       6208 
     | 
    
         
            -
                            ENCODING2("ISO-8859-5", "ISO8859-5", pm_encoding_iso_8859_5);
         
     | 
| 
       6209 
     | 
    
         
            -
                            ENCODING2("ISO-8859-6", "ISO8859-6", pm_encoding_iso_8859_6);
         
     | 
| 
       6210 
     | 
    
         
            -
                            ENCODING2("ISO-8859-7", "ISO8859-7", pm_encoding_iso_8859_7);
         
     | 
| 
       6211 
     | 
    
         
            -
                            ENCODING2("ISO-8859-8", "ISO8859-8", pm_encoding_iso_8859_8);
         
     | 
| 
       6212 
     | 
    
         
            -
                            ENCODING2("ISO-8859-9", "ISO8859-9", pm_encoding_iso_8859_9);
         
     | 
| 
       6213 
     | 
    
         
            -
                            ENCODING2("ISO-8859-10", "ISO8859-10", pm_encoding_iso_8859_10);
         
     | 
| 
       6214 
     | 
    
         
            -
                            ENCODING2("ISO-8859-11", "ISO8859-11", pm_encoding_iso_8859_11);
         
     | 
| 
       6215 
     | 
    
         
            -
                            ENCODING2("ISO-8859-13", "ISO8859-13", pm_encoding_iso_8859_13);
         
     | 
| 
       6216 
     | 
    
         
            -
                            ENCODING2("ISO-8859-14", "ISO8859-14", pm_encoding_iso_8859_14);
         
     | 
| 
       6217 
     | 
    
         
            -
                            ENCODING2("ISO-8859-15", "ISO8859-15", pm_encoding_iso_8859_15);
         
     | 
| 
       6218 
     | 
    
         
            -
                            ENCODING2("ISO-8859-16", "ISO8859-16", pm_encoding_iso_8859_16);
         
     | 
| 
       6219 
     | 
    
         
            -
                            break;
         
     | 
| 
       6220 
     | 
    
         
            -
                        case 'K': case 'k':
         
     | 
| 
       6221 
     | 
    
         
            -
                            ENCODING1("KOI8-R", pm_encoding_koi8_r);
         
     | 
| 
       6222 
     | 
    
         
            -
                            break;
         
     | 
| 
       6223 
     | 
    
         
            -
                        case 'L': case 'l':
         
     | 
| 
       6224 
     | 
    
         
            -
                            ENCODING1("locale", pm_encoding_utf_8);
         
     | 
| 
       6225 
     | 
    
         
            -
                            break;
         
     | 
| 
       6226 
     | 
    
         
            -
                        case 'M': case 'm':
         
     | 
| 
       6227 
     | 
    
         
            -
                            ENCODING1("macCentEuro", pm_encoding_mac_cent_euro);
         
     | 
| 
       6228 
     | 
    
         
            -
                            ENCODING1("macCroatian", pm_encoding_mac_croatian);
         
     | 
| 
       6229 
     | 
    
         
            -
                            ENCODING1("macCyrillic", pm_encoding_mac_cyrillic);
         
     | 
| 
       6230 
     | 
    
         
            -
                            ENCODING1("macGreek", pm_encoding_mac_greek);
         
     | 
| 
       6231 
     | 
    
         
            -
                            ENCODING1("macIceland", pm_encoding_mac_iceland);
         
     | 
| 
       6232 
     | 
    
         
            -
                            ENCODING1("macRoman", pm_encoding_mac_roman);
         
     | 
| 
       6233 
     | 
    
         
            -
                            ENCODING1("macRomania", pm_encoding_mac_romania);
         
     | 
| 
       6234 
     | 
    
         
            -
                            ENCODING1("macThai", pm_encoding_mac_thai);
         
     | 
| 
       6235 
     | 
    
         
            -
                            ENCODING1("macTurkish", pm_encoding_mac_turkish);
         
     | 
| 
       6236 
     | 
    
         
            -
                            ENCODING1("macUkraine", pm_encoding_mac_ukraine);
         
     | 
| 
       6237 
     | 
    
         
            -
                            break;
         
     | 
| 
       6238 
     | 
    
         
            -
                        case 'P': case 'p':
         
     | 
| 
       6239 
     | 
    
         
            -
                            ENCODING1("PCK", pm_encoding_windows_31j);
         
     | 
| 
       6240 
     | 
    
         
            -
                            break;
         
     | 
| 
       6241 
     | 
    
         
            -
                        case 'S': case 's':
         
     | 
| 
       6242 
     | 
    
         
            -
                            ENCODING1("Shift_JIS", pm_encoding_shift_jis);
         
     | 
| 
       6243 
     | 
    
         
            -
                            ENCODING1("SJIS", pm_encoding_windows_31j);
         
     | 
| 
       6244 
     | 
    
         
            -
                            break;
         
     | 
| 
       6245 
     | 
    
         
            -
                        case 'T': case 't':
         
     | 
| 
       6246 
     | 
    
         
            -
                            ENCODING1("TIS-620", pm_encoding_tis_620);
         
     | 
| 
       6247 
     | 
    
         
            -
                            break;
         
     | 
| 
       6248 
     | 
    
         
            -
                        case 'U': case 'u':
         
     | 
| 
       6249 
     | 
    
         
            -
                            ENCODING1("US-ASCII", pm_encoding_ascii);
         
     | 
| 
       6250 
     | 
    
         
            -
                            ENCODING2("UTF8-MAC", "UTF-8-HFS", pm_encoding_utf8_mac);
         
     | 
| 
       6251 
     | 
    
         
            -
                            break;
         
     | 
| 
       6252 
     | 
    
         
            -
                        case 'W': case 'w':
         
     | 
| 
       6253 
     | 
    
         
            -
                            ENCODING1("Windows-31J", pm_encoding_windows_31j);
         
     | 
| 
       6254 
     | 
    
         
            -
                            ENCODING1("Windows-874", pm_encoding_windows_874);
         
     | 
| 
       6255 
     | 
    
         
            -
                            ENCODING1("Windows-1250", pm_encoding_windows_1250);
         
     | 
| 
       6256 
     | 
    
         
            -
                            ENCODING1("Windows-1251", pm_encoding_windows_1251);
         
     | 
| 
       6257 
     | 
    
         
            -
                            ENCODING1("Windows-1252", pm_encoding_windows_1252);
         
     | 
| 
       6258 
     | 
    
         
            -
                            ENCODING1("Windows-1253", pm_encoding_windows_1253);
         
     | 
| 
       6259 
     | 
    
         
            -
                            ENCODING1("Windows-1254", pm_encoding_windows_1254);
         
     | 
| 
       6260 
     | 
    
         
            -
                            ENCODING1("Windows-1255", pm_encoding_windows_1255);
         
     | 
| 
       6261 
     | 
    
         
            -
                            ENCODING1("Windows-1256", pm_encoding_windows_1256);
         
     | 
| 
       6262 
     | 
    
         
            -
                            ENCODING1("Windows-1257", pm_encoding_windows_1257);
         
     | 
| 
       6263 
     | 
    
         
            -
                            ENCODING1("Windows-1258", pm_encoding_windows_1258);
         
     | 
| 
       6264 
     | 
    
         
            -
                            break;
         
     | 
| 
       6265 
     | 
    
         
            -
                        case '6':
         
     | 
| 
       6266 
     | 
    
         
            -
                            ENCODING1("646", pm_encoding_ascii);
         
     | 
| 
       6267 
     | 
    
         
            -
                            break;
         
     | 
| 
       6268 
     | 
    
         
            -
                    }
         
     | 
| 
       6269 
     | 
    
         
            -
                }
         
     | 
| 
       6270 
     | 
    
         
            -
             
     | 
| 
       6271 
     | 
    
         
            -
            #undef ENCODING2
         
     | 
| 
       6272 
     | 
    
         
            -
            #undef ENCODING1
         
     | 
| 
       6273 
     | 
    
         
            -
             
     | 
| 
       6274 
6255 
     | 
    
         
             
                return false;
         
     | 
| 
       6275 
6256 
     | 
    
         
             
            }
         
     | 
| 
       6276 
6257 
     | 
    
         | 
| 
         @@ -6319,7 +6300,7 @@ parser_lex_magic_comment_encoding(pm_parser_t *parser) { 
     | 
|
| 
       6319 
6300 
     | 
    
         
             
                }
         
     | 
| 
       6320 
6301 
     | 
    
         | 
| 
       6321 
6302 
     | 
    
         
             
                const uint8_t *value_start = cursor;
         
     | 
| 
       6322 
     | 
    
         
            -
                while ((*cursor == '-' || *cursor == '_' || parser->encoding 
     | 
| 
      
 6303 
     | 
    
         
            +
                while ((*cursor == '-' || *cursor == '_' || parser->encoding->alnum_char(cursor, 1)) && ++cursor < end);
         
     | 
| 
       6323 
6304 
     | 
    
         | 
| 
       6324 
6305 
     | 
    
         
             
                if (!parser_lex_magic_comment_encoding_value(parser, value_start, cursor)) {
         
     | 
| 
       6325 
6306 
     | 
    
         
             
                    // If we were unable to parse the encoding value, then we've got an
         
     | 
| 
         @@ -6353,7 +6334,7 @@ pm_char_is_magic_comment_key_delimiter(const uint8_t b) { 
     | 
|
| 
       6353 
6334 
     | 
    
         
             
             */
         
     | 
| 
       6354 
6335 
     | 
    
         
             
            static inline const uint8_t *
         
     | 
| 
       6355 
6336 
     | 
    
         
             
            parser_lex_magic_comment_emacs_marker(pm_parser_t *parser, const uint8_t *cursor, const uint8_t *end) {
         
     | 
| 
       6356 
     | 
    
         
            -
                while ((cursor + 3 <= end) && (cursor = pm_memchr(cursor, '-', (size_t) (end - cursor), parser->encoding_changed,  
     | 
| 
      
 6337 
     | 
    
         
            +
                while ((cursor + 3 <= end) && (cursor = pm_memchr(cursor, '-', (size_t) (end - cursor), parser->encoding_changed, parser->encoding)) != NULL) {
         
     | 
| 
       6357 
6338 
     | 
    
         
             
                    if (cursor + 3 <= end && cursor[1] == '*' && cursor[2] == '-') {
         
     | 
| 
       6358 
6339 
     | 
    
         
             
                        return cursor;
         
     | 
| 
       6359 
6340 
     | 
    
         
             
                    }
         
     | 
| 
         @@ -6443,7 +6424,7 @@ parser_lex_magic_comment(pm_parser_t *parser, bool semantic_token_seen) { 
     | 
|
| 
       6443 
6424 
     | 
    
         
             
                    // underscores. We only need to do this if there _is_ a dash in the key.
         
     | 
| 
       6444 
6425 
     | 
    
         
             
                    pm_string_t key;
         
     | 
| 
       6445 
6426 
     | 
    
         
             
                    const size_t key_length = (size_t) (key_end - key_start);
         
     | 
| 
       6446 
     | 
    
         
            -
                    const uint8_t *dash = pm_memchr(key_start, '-', (size_t) key_length, parser->encoding_changed,  
     | 
| 
      
 6427 
     | 
    
         
            +
                    const uint8_t *dash = pm_memchr(key_start, '-', (size_t) key_length, parser->encoding_changed, parser->encoding);
         
     | 
| 
       6447 
6428 
     | 
    
         | 
| 
       6448 
6429 
     | 
    
         
             
                    if (dash == NULL) {
         
     | 
| 
       6449 
6430 
     | 
    
         
             
                        pm_string_shared_init(&key, key_start, key_end);
         
     | 
| 
         @@ -6455,7 +6436,7 @@ parser_lex_magic_comment(pm_parser_t *parser, bool semantic_token_seen) { 
     | 
|
| 
       6455 
6436 
     | 
    
         
             
                        memcpy(buffer, key_start, width);
         
     | 
| 
       6456 
6437 
     | 
    
         
             
                        buffer[dash - key_start] = '_';
         
     | 
| 
       6457 
6438 
     | 
    
         | 
| 
       6458 
     | 
    
         
            -
                        while ((dash = pm_memchr(dash + 1, '-', (size_t) (key_end - dash - 1), parser->encoding_changed,  
     | 
| 
      
 6439 
     | 
    
         
            +
                        while ((dash = pm_memchr(dash + 1, '-', (size_t) (key_end - dash - 1), parser->encoding_changed, parser->encoding)) != NULL) {
         
     | 
| 
       6459 
6440 
     | 
    
         
             
                            buffer[dash - key_start] = '_';
         
     | 
| 
       6460 
6441 
     | 
    
         
             
                        }
         
     | 
| 
       6461 
6442 
     | 
    
         | 
| 
         @@ -6530,6 +6511,7 @@ context_terminator(pm_context_t context, pm_token_t *token) { 
     | 
|
| 
       6530 
6511 
     | 
    
         
             
                    case PM_CONTEXT_ELSE:
         
     | 
| 
       6531 
6512 
     | 
    
         
             
                    case PM_CONTEXT_FOR:
         
     | 
| 
       6532 
6513 
     | 
    
         
             
                    case PM_CONTEXT_ENSURE:
         
     | 
| 
      
 6514 
     | 
    
         
            +
                    case PM_CONTEXT_ENSURE_DEF:
         
     | 
| 
       6533 
6515 
     | 
    
         
             
                        return token->type == PM_TOKEN_KEYWORD_END;
         
     | 
| 
       6534 
6516 
     | 
    
         
             
                    case PM_CONTEXT_FOR_INDEX:
         
     | 
| 
       6535 
6517 
     | 
    
         
             
                        return token->type == PM_TOKEN_KEYWORD_IN;
         
     | 
| 
         @@ -6550,8 +6532,10 @@ context_terminator(pm_context_t context, pm_token_t *token) { 
     | 
|
| 
       6550 
6532 
     | 
    
         
             
                        return token->type == PM_TOKEN_PARENTHESIS_RIGHT;
         
     | 
| 
       6551 
6533 
     | 
    
         
             
                    case PM_CONTEXT_BEGIN:
         
     | 
| 
       6552 
6534 
     | 
    
         
             
                    case PM_CONTEXT_RESCUE:
         
     | 
| 
      
 6535 
     | 
    
         
            +
                    case PM_CONTEXT_RESCUE_DEF:
         
     | 
| 
       6553 
6536 
     | 
    
         
             
                        return token->type == PM_TOKEN_KEYWORD_ENSURE || token->type == PM_TOKEN_KEYWORD_RESCUE || token->type == PM_TOKEN_KEYWORD_ELSE || token->type == PM_TOKEN_KEYWORD_END;
         
     | 
| 
       6554 
6537 
     | 
    
         
             
                    case PM_CONTEXT_RESCUE_ELSE:
         
     | 
| 
      
 6538 
     | 
    
         
            +
                    case PM_CONTEXT_RESCUE_ELSE_DEF:
         
     | 
| 
       6555 
6539 
     | 
    
         
             
                        return token->type == PM_TOKEN_KEYWORD_ENSURE || token->type == PM_TOKEN_KEYWORD_END;
         
     | 
| 
       6556 
6540 
     | 
    
         
             
                    case PM_CONTEXT_LAMBDA_BRACES:
         
     | 
| 
       6557 
6541 
     | 
    
         
             
                        return token->type == PM_TOKEN_BRACE_RIGHT;
         
     | 
| 
         @@ -6617,6 +6601,10 @@ context_def_p(pm_parser_t *parser) { 
     | 
|
| 
       6617 
6601 
     | 
    
         
             
                while (context_node != NULL) {
         
     | 
| 
       6618 
6602 
     | 
    
         
             
                    switch (context_node->context) {
         
     | 
| 
       6619 
6603 
     | 
    
         
             
                        case PM_CONTEXT_DEF:
         
     | 
| 
      
 6604 
     | 
    
         
            +
                        case PM_CONTEXT_DEF_PARAMS:
         
     | 
| 
      
 6605 
     | 
    
         
            +
                        case PM_CONTEXT_ENSURE_DEF:
         
     | 
| 
      
 6606 
     | 
    
         
            +
                        case PM_CONTEXT_RESCUE_DEF:
         
     | 
| 
      
 6607 
     | 
    
         
            +
                        case PM_CONTEXT_RESCUE_ELSE_DEF:
         
     | 
| 
       6620 
6608 
     | 
    
         
             
                            return true;
         
     | 
| 
       6621 
6609 
     | 
    
         
             
                        case PM_CONTEXT_CLASS:
         
     | 
| 
       6622 
6610 
     | 
    
         
             
                        case PM_CONTEXT_MODULE:
         
     | 
| 
         @@ -6979,9 +6967,16 @@ lex_identifier(pm_parser_t *parser, bool previous_command_start) { 
     | 
|
| 
       6979 
6967 
     | 
    
         
             
                const uint8_t *end = parser->end;
         
     | 
| 
       6980 
6968 
     | 
    
         
             
                const uint8_t *current_start = parser->current.start;
         
     | 
| 
       6981 
6969 
     | 
    
         
             
                const uint8_t *current_end = parser->current.end;
         
     | 
| 
      
 6970 
     | 
    
         
            +
                bool encoding_changed = parser->encoding_changed;
         
     | 
| 
       6982 
6971 
     | 
    
         | 
| 
       6983 
     | 
    
         
            -
                 
     | 
| 
       6984 
     | 
    
         
            -
                    current_end  
     | 
| 
      
 6972 
     | 
    
         
            +
                if (encoding_changed) {
         
     | 
| 
      
 6973 
     | 
    
         
            +
                    while (current_end < end && (width = char_is_identifier(parser, current_end)) > 0) {
         
     | 
| 
      
 6974 
     | 
    
         
            +
                        current_end += width;
         
     | 
| 
      
 6975 
     | 
    
         
            +
                    }
         
     | 
| 
      
 6976 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 6977 
     | 
    
         
            +
                    while (current_end < end && (width = char_is_identifier_utf8(current_end, end)) > 0) {
         
     | 
| 
      
 6978 
     | 
    
         
            +
                        current_end += width;
         
     | 
| 
      
 6979 
     | 
    
         
            +
                    }
         
     | 
| 
       6985 
6980 
     | 
    
         
             
                }
         
     | 
| 
       6986 
6981 
     | 
    
         
             
                parser->current.end = current_end;
         
     | 
| 
       6987 
6982 
     | 
    
         | 
| 
         @@ -7099,8 +7094,8 @@ lex_identifier(pm_parser_t *parser, bool previous_command_start) { 
     | 
|
| 
       7099 
7094 
     | 
    
         
             
                    }
         
     | 
| 
       7100 
7095 
     | 
    
         
             
                }
         
     | 
| 
       7101 
7096 
     | 
    
         | 
| 
       7102 
     | 
    
         
            -
                if ( 
     | 
| 
       7103 
     | 
    
         
            -
                    return parser->encoding 
     | 
| 
      
 7097 
     | 
    
         
            +
                if (encoding_changed) {
         
     | 
| 
      
 7098 
     | 
    
         
            +
                    return parser->encoding->isupper_char(current_start, end - current_start) ? PM_TOKEN_CONSTANT : PM_TOKEN_IDENTIFIER;
         
     | 
| 
       7104 
7099 
     | 
    
         
             
                }
         
     | 
| 
       7105 
7100 
     | 
    
         
             
                return pm_encoding_utf_8_isupper_char(current_start, end - current_start) ? PM_TOKEN_CONSTANT : PM_TOKEN_IDENTIFIER;
         
     | 
| 
       7106 
7101 
     | 
    
         
             
            }
         
     | 
| 
         @@ -7314,7 +7309,18 @@ escape_byte(uint8_t value, const uint8_t flags) { 
     | 
|
| 
       7314 
7309 
     | 
    
         
             
             * Write a unicode codepoint to the given buffer.
         
     | 
| 
       7315 
7310 
     | 
    
         
             
             */
         
     | 
| 
       7316 
7311 
     | 
    
         
             
            static inline void
         
     | 
| 
       7317 
     | 
    
         
            -
            escape_write_unicode(pm_parser_t *parser, pm_buffer_t *buffer, const uint8_t *start, const uint8_t *end, uint32_t value) {
         
     | 
| 
      
 7312 
     | 
    
         
            +
            escape_write_unicode(pm_parser_t *parser, pm_buffer_t *buffer, const uint8_t flags, const uint8_t *start, const uint8_t *end, uint32_t value) {
         
     | 
| 
      
 7313 
     | 
    
         
            +
                // \u escape sequences in string-like structures implicitly change the
         
     | 
| 
      
 7314 
     | 
    
         
            +
                // encoding to UTF-8 if they are >= 0x80 or if they are used in a character
         
     | 
| 
      
 7315 
     | 
    
         
            +
                // literal.
         
     | 
| 
      
 7316 
     | 
    
         
            +
                if (value >= 0x80 || flags & PM_ESCAPE_FLAG_SINGLE) {
         
     | 
| 
      
 7317 
     | 
    
         
            +
                    if (parser->explicit_encoding != NULL && parser->explicit_encoding != PM_ENCODING_UTF_8_ENTRY) {
         
     | 
| 
      
 7318 
     | 
    
         
            +
                        PM_PARSER_ERR_FORMAT(parser, start, end, PM_ERR_MIXED_ENCODING, parser->explicit_encoding->name);
         
     | 
| 
      
 7319 
     | 
    
         
            +
                    }
         
     | 
| 
      
 7320 
     | 
    
         
            +
             
     | 
| 
      
 7321 
     | 
    
         
            +
                    parser->explicit_encoding = PM_ENCODING_UTF_8_ENTRY;
         
     | 
| 
      
 7322 
     | 
    
         
            +
                }
         
     | 
| 
      
 7323 
     | 
    
         
            +
             
     | 
| 
       7318 
7324 
     | 
    
         
             
                if (value <= 0x7F) { // 0xxxxxxx
         
     | 
| 
       7319 
7325 
     | 
    
         
             
                    pm_buffer_append_byte(buffer, (uint8_t) value);
         
     | 
| 
       7320 
7326 
     | 
    
         
             
                } else if (value <= 0x7FF) { // 110xxxxx 10xxxxxx
         
     | 
| 
         @@ -7337,6 +7343,23 @@ escape_write_unicode(pm_parser_t *parser, pm_buffer_t *buffer, const uint8_t *st 
     | 
|
| 
       7337 
7343 
     | 
    
         
             
                }
         
     | 
| 
       7338 
7344 
     | 
    
         
             
            }
         
     | 
| 
       7339 
7345 
     | 
    
         | 
| 
      
 7346 
     | 
    
         
            +
            /**
         
     | 
| 
      
 7347 
     | 
    
         
            +
             * When you're writing a byte to the unescape buffer, if the byte is non-ASCII
         
     | 
| 
      
 7348 
     | 
    
         
            +
             * (i.e., the top bit is set) then it locks in the encoding.
         
     | 
| 
      
 7349 
     | 
    
         
            +
             */
         
     | 
| 
      
 7350 
     | 
    
         
            +
            static inline void
         
     | 
| 
      
 7351 
     | 
    
         
            +
            escape_write_byte_encoded(pm_parser_t *parser, pm_buffer_t *buffer, uint8_t byte) {
         
     | 
| 
      
 7352 
     | 
    
         
            +
                if (byte >= 0x80) {
         
     | 
| 
      
 7353 
     | 
    
         
            +
                    if (parser->explicit_encoding != NULL && parser->explicit_encoding == PM_ENCODING_UTF_8_ENTRY && parser->encoding != PM_ENCODING_UTF_8_ENTRY) {
         
     | 
| 
      
 7354 
     | 
    
         
            +
                        PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_MIXED_ENCODING, parser->encoding->name);
         
     | 
| 
      
 7355 
     | 
    
         
            +
                    }
         
     | 
| 
      
 7356 
     | 
    
         
            +
             
     | 
| 
      
 7357 
     | 
    
         
            +
                    parser->explicit_encoding = parser->encoding;
         
     | 
| 
      
 7358 
     | 
    
         
            +
                }
         
     | 
| 
      
 7359 
     | 
    
         
            +
             
     | 
| 
      
 7360 
     | 
    
         
            +
                pm_buffer_append_byte(buffer, byte);
         
     | 
| 
      
 7361 
     | 
    
         
            +
            }
         
     | 
| 
      
 7362 
     | 
    
         
            +
             
     | 
| 
       7340 
7363 
     | 
    
         
             
            /**
         
     | 
| 
       7341 
7364 
     | 
    
         
             
             * The regular expression engine doesn't support the same escape sequences as
         
     | 
| 
       7342 
7365 
     | 
    
         
             
             * Ruby does. So first we have to read the escape sequence, and then we have to
         
     | 
| 
         @@ -7353,7 +7376,7 @@ escape_write_unicode(pm_parser_t *parser, pm_buffer_t *buffer, const uint8_t *st 
     | 
|
| 
       7353 
7376 
     | 
    
         
             
             * source so that the regular expression engine will perform its own unescaping.
         
     | 
| 
       7354 
7377 
     | 
    
         
             
             */
         
     | 
| 
       7355 
7378 
     | 
    
         
             
            static inline void
         
     | 
| 
       7356 
     | 
    
         
            -
            escape_write_byte(pm_buffer_t *buffer, uint8_t flags, uint8_t byte) {
         
     | 
| 
      
 7379 
     | 
    
         
            +
            escape_write_byte(pm_parser_t *parser, pm_buffer_t *buffer, uint8_t flags, uint8_t byte) {
         
     | 
| 
       7357 
7380 
     | 
    
         
             
                if (flags & PM_ESCAPE_FLAG_REGEXP) {
         
     | 
| 
       7358 
7381 
     | 
    
         
             
                    pm_buffer_append_bytes(buffer, (const uint8_t *) "\\x", 2);
         
     | 
| 
       7359 
7382 
     | 
    
         | 
| 
         @@ -7372,7 +7395,7 @@ escape_write_byte(pm_buffer_t *buffer, uint8_t flags, uint8_t byte) { 
     | 
|
| 
       7372 
7395 
     | 
    
         
             
                        pm_buffer_append_byte(buffer, (uint8_t) (byte2 + '0'));
         
     | 
| 
       7373 
7396 
     | 
    
         
             
                    }
         
     | 
| 
       7374 
7397 
     | 
    
         
             
                } else {
         
     | 
| 
       7375 
     | 
    
         
            -
                     
     | 
| 
      
 7398 
     | 
    
         
            +
                    escape_write_byte_encoded(parser, buffer, byte);
         
     | 
| 
       7376 
7399 
     | 
    
         
             
                }
         
     | 
| 
       7377 
7400 
     | 
    
         
             
            }
         
     | 
| 
       7378 
7401 
     | 
    
         | 
| 
         @@ -7384,57 +7407,57 @@ escape_read(pm_parser_t *parser, pm_buffer_t *buffer, uint8_t flags) { 
     | 
|
| 
       7384 
7407 
     | 
    
         
             
                switch (peek(parser)) {
         
     | 
| 
       7385 
7408 
     | 
    
         
             
                    case '\\': {
         
     | 
| 
       7386 
7409 
     | 
    
         
             
                        parser->current.end++;
         
     | 
| 
       7387 
     | 
    
         
            -
                         
     | 
| 
      
 7410 
     | 
    
         
            +
                        escape_write_byte_encoded(parser, buffer, escape_byte('\\', flags));
         
     | 
| 
       7388 
7411 
     | 
    
         
             
                        return;
         
     | 
| 
       7389 
7412 
     | 
    
         
             
                    }
         
     | 
| 
       7390 
7413 
     | 
    
         
             
                    case '\'': {
         
     | 
| 
       7391 
7414 
     | 
    
         
             
                        parser->current.end++;
         
     | 
| 
       7392 
     | 
    
         
            -
                         
     | 
| 
      
 7415 
     | 
    
         
            +
                        escape_write_byte_encoded(parser, buffer, escape_byte('\'', flags));
         
     | 
| 
       7393 
7416 
     | 
    
         
             
                        return;
         
     | 
| 
       7394 
7417 
     | 
    
         
             
                    }
         
     | 
| 
       7395 
7418 
     | 
    
         
             
                    case 'a': {
         
     | 
| 
       7396 
7419 
     | 
    
         
             
                        parser->current.end++;
         
     | 
| 
       7397 
     | 
    
         
            -
                         
     | 
| 
      
 7420 
     | 
    
         
            +
                        escape_write_byte_encoded(parser, buffer, escape_byte('\a', flags));
         
     | 
| 
       7398 
7421 
     | 
    
         
             
                        return;
         
     | 
| 
       7399 
7422 
     | 
    
         
             
                    }
         
     | 
| 
       7400 
7423 
     | 
    
         
             
                    case 'b': {
         
     | 
| 
       7401 
7424 
     | 
    
         
             
                        parser->current.end++;
         
     | 
| 
       7402 
     | 
    
         
            -
                         
     | 
| 
      
 7425 
     | 
    
         
            +
                        escape_write_byte_encoded(parser, buffer, escape_byte('\b', flags));
         
     | 
| 
       7403 
7426 
     | 
    
         
             
                        return;
         
     | 
| 
       7404 
7427 
     | 
    
         
             
                    }
         
     | 
| 
       7405 
7428 
     | 
    
         
             
                    case 'e': {
         
     | 
| 
       7406 
7429 
     | 
    
         
             
                        parser->current.end++;
         
     | 
| 
       7407 
     | 
    
         
            -
                         
     | 
| 
      
 7430 
     | 
    
         
            +
                        escape_write_byte_encoded(parser, buffer, escape_byte('\033', flags));
         
     | 
| 
       7408 
7431 
     | 
    
         
             
                        return;
         
     | 
| 
       7409 
7432 
     | 
    
         
             
                    }
         
     | 
| 
       7410 
7433 
     | 
    
         
             
                    case 'f': {
         
     | 
| 
       7411 
7434 
     | 
    
         
             
                        parser->current.end++;
         
     | 
| 
       7412 
     | 
    
         
            -
                         
     | 
| 
      
 7435 
     | 
    
         
            +
                        escape_write_byte_encoded(parser, buffer, escape_byte('\f', flags));
         
     | 
| 
       7413 
7436 
     | 
    
         
             
                        return;
         
     | 
| 
       7414 
7437 
     | 
    
         
             
                    }
         
     | 
| 
       7415 
7438 
     | 
    
         
             
                    case 'n': {
         
     | 
| 
       7416 
7439 
     | 
    
         
             
                        parser->current.end++;
         
     | 
| 
       7417 
     | 
    
         
            -
                         
     | 
| 
      
 7440 
     | 
    
         
            +
                        escape_write_byte_encoded(parser, buffer, escape_byte('\n', flags));
         
     | 
| 
       7418 
7441 
     | 
    
         
             
                        return;
         
     | 
| 
       7419 
7442 
     | 
    
         
             
                    }
         
     | 
| 
       7420 
7443 
     | 
    
         
             
                    case 'r': {
         
     | 
| 
       7421 
7444 
     | 
    
         
             
                        parser->current.end++;
         
     | 
| 
       7422 
     | 
    
         
            -
                         
     | 
| 
      
 7445 
     | 
    
         
            +
                        escape_write_byte_encoded(parser, buffer, escape_byte('\r', flags));
         
     | 
| 
       7423 
7446 
     | 
    
         
             
                        return;
         
     | 
| 
       7424 
7447 
     | 
    
         
             
                    }
         
     | 
| 
       7425 
7448 
     | 
    
         
             
                    case 's': {
         
     | 
| 
       7426 
7449 
     | 
    
         
             
                        parser->current.end++;
         
     | 
| 
       7427 
     | 
    
         
            -
                         
     | 
| 
      
 7450 
     | 
    
         
            +
                        escape_write_byte_encoded(parser, buffer, escape_byte(' ', flags));
         
     | 
| 
       7428 
7451 
     | 
    
         
             
                        return;
         
     | 
| 
       7429 
7452 
     | 
    
         
             
                    }
         
     | 
| 
       7430 
7453 
     | 
    
         
             
                    case 't': {
         
     | 
| 
       7431 
7454 
     | 
    
         
             
                        parser->current.end++;
         
     | 
| 
       7432 
     | 
    
         
            -
                         
     | 
| 
      
 7455 
     | 
    
         
            +
                        escape_write_byte_encoded(parser, buffer, escape_byte('\t', flags));
         
     | 
| 
       7433 
7456 
     | 
    
         
             
                        return;
         
     | 
| 
       7434 
7457 
     | 
    
         
             
                    }
         
     | 
| 
       7435 
7458 
     | 
    
         
             
                    case 'v': {
         
     | 
| 
       7436 
7459 
     | 
    
         
             
                        parser->current.end++;
         
     | 
| 
       7437 
     | 
    
         
            -
                         
     | 
| 
      
 7460 
     | 
    
         
            +
                        escape_write_byte_encoded(parser, buffer, escape_byte('\v', flags));
         
     | 
| 
       7438 
7461 
     | 
    
         
             
                        return;
         
     | 
| 
       7439 
7462 
     | 
    
         
             
                    }
         
     | 
| 
       7440 
7463 
     | 
    
         
             
                    case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': {
         
     | 
| 
         @@ -7451,7 +7474,7 @@ escape_read(pm_parser_t *parser, pm_buffer_t *buffer, uint8_t flags) { 
     | 
|
| 
       7451 
7474 
     | 
    
         
             
                            }
         
     | 
| 
       7452 
7475 
     | 
    
         
             
                        }
         
     | 
| 
       7453 
7476 
     | 
    
         | 
| 
       7454 
     | 
    
         
            -
                         
     | 
| 
      
 7477 
     | 
    
         
            +
                        escape_write_byte_encoded(parser, buffer, value);
         
     | 
| 
       7455 
7478 
     | 
    
         
             
                        return;
         
     | 
| 
       7456 
7479 
     | 
    
         
             
                    }
         
     | 
| 
       7457 
7480 
     | 
    
         
             
                    case 'x': {
         
     | 
| 
         @@ -7473,7 +7496,7 @@ escape_read(pm_parser_t *parser, pm_buffer_t *buffer, uint8_t flags) { 
     | 
|
| 
       7473 
7496 
     | 
    
         
             
                            if (flags & PM_ESCAPE_FLAG_REGEXP) {
         
     | 
| 
       7474 
7497 
     | 
    
         
             
                                pm_buffer_append_bytes(buffer, start, (size_t) (parser->current.end - start));
         
     | 
| 
       7475 
7498 
     | 
    
         
             
                            } else {
         
     | 
| 
       7476 
     | 
    
         
            -
                                 
     | 
| 
      
 7499 
     | 
    
         
            +
                                escape_write_byte_encoded(parser, buffer, value);
         
     | 
| 
       7477 
7500 
     | 
    
         
             
                            }
         
     | 
| 
       7478 
7501 
     | 
    
         
             
                        } else {
         
     | 
| 
       7479 
7502 
     | 
    
         
             
                            pm_parser_err_current(parser, PM_ERR_ESCAPE_INVALID_HEXADECIMAL);
         
     | 
| 
         @@ -7497,7 +7520,7 @@ escape_read(pm_parser_t *parser, pm_buffer_t *buffer, uint8_t flags) { 
     | 
|
| 
       7497 
7520 
     | 
    
         
             
                            if (flags & PM_ESCAPE_FLAG_REGEXP) {
         
     | 
| 
       7498 
7521 
     | 
    
         
             
                                pm_buffer_append_bytes(buffer, start, (size_t) (parser->current.end + 4 - start));
         
     | 
| 
       7499 
7522 
     | 
    
         
             
                            } else {
         
     | 
| 
       7500 
     | 
    
         
            -
                                escape_write_unicode(parser, buffer, start, parser->current.end + 4, value);
         
     | 
| 
      
 7523 
     | 
    
         
            +
                                escape_write_unicode(parser, buffer, flags, start, parser->current.end + 4, value);
         
     | 
| 
       7501 
7524 
     | 
    
         
             
                            }
         
     | 
| 
       7502 
7525 
     | 
    
         | 
| 
       7503 
7526 
     | 
    
         
             
                            parser->current.end += 4;
         
     | 
| 
         @@ -7531,13 +7554,14 @@ escape_read(pm_parser_t *parser, pm_buffer_t *buffer, uint8_t flags) { 
     | 
|
| 
       7531 
7554 
     | 
    
         | 
| 
       7532 
7555 
     | 
    
         
             
                                if (!(flags & PM_ESCAPE_FLAG_REGEXP)) {
         
     | 
| 
       7533 
7556 
     | 
    
         
             
                                    uint32_t value = escape_unicode(unicode_start, hexadecimal_length);
         
     | 
| 
       7534 
     | 
    
         
            -
                                    escape_write_unicode(parser, buffer, unicode_start, parser->current.end, value);
         
     | 
| 
      
 7557 
     | 
    
         
            +
                                    escape_write_unicode(parser, buffer, flags, unicode_start, parser->current.end, value);
         
     | 
| 
       7535 
7558 
     | 
    
         
             
                                }
         
     | 
| 
       7536 
7559 
     | 
    
         | 
| 
       7537 
7560 
     | 
    
         
             
                                parser->current.end += pm_strspn_whitespace(parser->current.end, parser->end - parser->current.end);
         
     | 
| 
       7538 
7561 
     | 
    
         
             
                            }
         
     | 
| 
       7539 
7562 
     | 
    
         | 
| 
       7540 
     | 
    
         
            -
                            // ?\u{nnnn} character literal should contain only one codepoint 
     | 
| 
      
 7563 
     | 
    
         
            +
                            // ?\u{nnnn} character literal should contain only one codepoint
         
     | 
| 
      
 7564 
     | 
    
         
            +
                            // and cannot be like ?\u{nnnn mmmm}.
         
     | 
| 
       7541 
7565 
     | 
    
         
             
                            if (flags & PM_ESCAPE_FLAG_SINGLE && codepoints_count > 1) {
         
     | 
| 
       7542 
7566 
     | 
    
         
             
                                pm_parser_err(parser, extra_codepoints_start, parser->current.end - 1, PM_ERR_ESCAPE_INVALID_UNICODE_LITERAL);
         
     | 
| 
       7543 
7567 
     | 
    
         
             
                            }
         
     | 
| 
         @@ -7568,7 +7592,7 @@ escape_read(pm_parser_t *parser, pm_buffer_t *buffer, uint8_t flags) { 
     | 
|
| 
       7568 
7592 
     | 
    
         
             
                        switch (peeked) {
         
     | 
| 
       7569 
7593 
     | 
    
         
             
                            case '?': {
         
     | 
| 
       7570 
7594 
     | 
    
         
             
                                parser->current.end++;
         
     | 
| 
       7571 
     | 
    
         
            -
                                escape_write_byte(buffer, flags, escape_byte(0x7f, flags));
         
     | 
| 
      
 7595 
     | 
    
         
            +
                                escape_write_byte(parser, buffer, flags, escape_byte(0x7f, flags));
         
     | 
| 
       7572 
7596 
     | 
    
         
             
                                return;
         
     | 
| 
       7573 
7597 
     | 
    
         
             
                            }
         
     | 
| 
       7574 
7598 
     | 
    
         
             
                            case '\\':
         
     | 
| 
         @@ -7586,7 +7610,7 @@ escape_read(pm_parser_t *parser, pm_buffer_t *buffer, uint8_t flags) { 
     | 
|
| 
       7586 
7610 
     | 
    
         
             
                                }
         
     | 
| 
       7587 
7611 
     | 
    
         | 
| 
       7588 
7612 
     | 
    
         
             
                                parser->current.end++;
         
     | 
| 
       7589 
     | 
    
         
            -
                                escape_write_byte(buffer, flags, escape_byte(peeked, flags | PM_ESCAPE_FLAG_CONTROL));
         
     | 
| 
      
 7613 
     | 
    
         
            +
                                escape_write_byte(parser, buffer, flags, escape_byte(peeked, flags | PM_ESCAPE_FLAG_CONTROL));
         
     | 
| 
       7590 
7614 
     | 
    
         
             
                                return;
         
     | 
| 
       7591 
7615 
     | 
    
         
             
                            }
         
     | 
| 
       7592 
7616 
     | 
    
         
             
                        }
         
     | 
| 
         @@ -7608,7 +7632,7 @@ escape_read(pm_parser_t *parser, pm_buffer_t *buffer, uint8_t flags) { 
     | 
|
| 
       7608 
7632 
     | 
    
         
             
                        switch (peeked) {
         
     | 
| 
       7609 
7633 
     | 
    
         
             
                            case '?': {
         
     | 
| 
       7610 
7634 
     | 
    
         
             
                                parser->current.end++;
         
     | 
| 
       7611 
     | 
    
         
            -
                                escape_write_byte(buffer, flags, escape_byte(0x7f, flags));
         
     | 
| 
      
 7635 
     | 
    
         
            +
                                escape_write_byte(parser, buffer, flags, escape_byte(0x7f, flags));
         
     | 
| 
       7612 
7636 
     | 
    
         
             
                                return;
         
     | 
| 
       7613 
7637 
     | 
    
         
             
                            }
         
     | 
| 
       7614 
7638 
     | 
    
         
             
                            case '\\':
         
     | 
| 
         @@ -7626,7 +7650,7 @@ escape_read(pm_parser_t *parser, pm_buffer_t *buffer, uint8_t flags) { 
     | 
|
| 
       7626 
7650 
     | 
    
         
             
                                }
         
     | 
| 
       7627 
7651 
     | 
    
         | 
| 
       7628 
7652 
     | 
    
         
             
                                parser->current.end++;
         
     | 
| 
       7629 
     | 
    
         
            -
                                escape_write_byte(buffer, flags, escape_byte(peeked, flags | PM_ESCAPE_FLAG_CONTROL));
         
     | 
| 
      
 7653 
     | 
    
         
            +
                                escape_write_byte(parser, buffer, flags, escape_byte(peeked, flags | PM_ESCAPE_FLAG_CONTROL));
         
     | 
| 
       7630 
7654 
     | 
    
         
             
                                return;
         
     | 
| 
       7631 
7655 
     | 
    
         
             
                            }
         
     | 
| 
       7632 
7656 
     | 
    
         
             
                        }
         
     | 
| 
         @@ -7661,20 +7685,20 @@ escape_read(pm_parser_t *parser, pm_buffer_t *buffer, uint8_t flags) { 
     | 
|
| 
       7661 
7685 
     | 
    
         
             
                        }
         
     | 
| 
       7662 
7686 
     | 
    
         | 
| 
       7663 
7687 
     | 
    
         
             
                        parser->current.end++;
         
     | 
| 
       7664 
     | 
    
         
            -
                        escape_write_byte(buffer, flags, escape_byte(peeked, flags | PM_ESCAPE_FLAG_META));
         
     | 
| 
      
 7688 
     | 
    
         
            +
                        escape_write_byte(parser, buffer, flags, escape_byte(peeked, flags | PM_ESCAPE_FLAG_META));
         
     | 
| 
       7665 
7689 
     | 
    
         
             
                        return;
         
     | 
| 
       7666 
7690 
     | 
    
         
             
                    }
         
     | 
| 
       7667 
7691 
     | 
    
         
             
                    case '\r': {
         
     | 
| 
       7668 
7692 
     | 
    
         
             
                        if (peek_offset(parser, 1) == '\n') {
         
     | 
| 
       7669 
7693 
     | 
    
         
             
                            parser->current.end += 2;
         
     | 
| 
       7670 
     | 
    
         
            -
                             
     | 
| 
      
 7694 
     | 
    
         
            +
                            escape_write_byte_encoded(parser, buffer, escape_byte('\n', flags));
         
     | 
| 
       7671 
7695 
     | 
    
         
             
                            return;
         
     | 
| 
       7672 
7696 
     | 
    
         
             
                        }
         
     | 
| 
       7673 
7697 
     | 
    
         
             
                    }
         
     | 
| 
       7674 
7698 
     | 
    
         
             
                    /* fallthrough */
         
     | 
| 
       7675 
7699 
     | 
    
         
             
                    default: {
         
     | 
| 
       7676 
7700 
     | 
    
         
             
                        if (parser->current.end < parser->end) {
         
     | 
| 
       7677 
     | 
    
         
            -
                             
     | 
| 
      
 7701 
     | 
    
         
            +
                            escape_write_byte_encoded(parser, buffer, *parser->current.end++);
         
     | 
| 
       7678 
7702 
     | 
    
         
             
                        }
         
     | 
| 
       7679 
7703 
     | 
    
         
             
                        return;
         
     | 
| 
       7680 
7704 
     | 
    
         
             
                    }
         
     | 
| 
         @@ -7737,13 +7761,12 @@ lex_question_mark(pm_parser_t *parser) { 
     | 
|
| 
       7737 
7761 
     | 
    
         | 
| 
       7738 
7762 
     | 
    
         
             
                    return PM_TOKEN_CHARACTER_LITERAL;
         
     | 
| 
       7739 
7763 
     | 
    
         
             
                } else {
         
     | 
| 
       7740 
     | 
    
         
            -
                    size_t encoding_width = parser->encoding 
     | 
| 
      
 7764 
     | 
    
         
            +
                    size_t encoding_width = parser->encoding->char_width(parser->current.end, parser->end - parser->current.end);
         
     | 
| 
       7741 
7765 
     | 
    
         | 
| 
       7742 
     | 
    
         
            -
                    // Ternary operators can have a ? immediately followed by an identifier 
     | 
| 
       7743 
     | 
    
         
            -
                    // an underscore. We check for this case
         
     | 
| 
      
 7766 
     | 
    
         
            +
                    // Ternary operators can have a ? immediately followed by an identifier
         
     | 
| 
      
 7767 
     | 
    
         
            +
                    // which starts with an underscore. We check for this case here.
         
     | 
| 
       7744 
7768 
     | 
    
         
             
                    if (
         
     | 
| 
       7745 
     | 
    
         
            -
                        !(parser->encoding 
     | 
| 
       7746 
     | 
    
         
            -
                          peek(parser) == '_') ||
         
     | 
| 
      
 7769 
     | 
    
         
            +
                        !(parser->encoding->alnum_char(parser->current.end, parser->end - parser->current.end) || peek(parser) == '_') ||
         
     | 
| 
       7747 
7770 
     | 
    
         
             
                        (
         
     | 
| 
       7748 
7771 
     | 
    
         
             
                            (parser->current.end + encoding_width >= parser->end) ||
         
     | 
| 
       7749 
7772 
     | 
    
         
             
                            !char_is_identifier(parser, parser->current.end + encoding_width)
         
     | 
| 
         @@ -7809,8 +7832,7 @@ parser_comment(pm_parser_t *parser, pm_comment_type_t type) { 
     | 
|
| 
       7809 
7832 
     | 
    
         | 
| 
       7810 
7833 
     | 
    
         
             
                *comment = (pm_comment_t) {
         
     | 
| 
       7811 
7834 
     | 
    
         
             
                    .type = type,
         
     | 
| 
       7812 
     | 
    
         
            -
                    . 
     | 
| 
       7813 
     | 
    
         
            -
                    .end = parser->current.end
         
     | 
| 
      
 7835 
     | 
    
         
            +
                    .location = { parser->current.start, parser->current.end }
         
     | 
| 
       7814 
7836 
     | 
    
         
             
                };
         
     | 
| 
       7815 
7837 
     | 
    
         | 
| 
       7816 
7838 
     | 
    
         
             
                return comment;
         
     | 
| 
         @@ -7861,7 +7883,7 @@ lex_embdoc(pm_parser_t *parser) { 
     | 
|
| 
       7861 
7883 
     | 
    
         
             
                        parser->current.type = PM_TOKEN_EMBDOC_END;
         
     | 
| 
       7862 
7884 
     | 
    
         
             
                        parser_lex_callback(parser);
         
     | 
| 
       7863 
7885 
     | 
    
         | 
| 
       7864 
     | 
    
         
            -
                        comment->end = parser->current.end;
         
     | 
| 
      
 7886 
     | 
    
         
            +
                        comment->location.end = parser->current.end;
         
     | 
| 
       7865 
7887 
     | 
    
         
             
                        pm_list_append(&parser->comment_list, (pm_list_node_t *) comment);
         
     | 
| 
       7866 
7888 
     | 
    
         | 
| 
       7867 
7889 
     | 
    
         
             
                        return PM_TOKEN_EMBDOC_END;
         
     | 
| 
         @@ -7884,7 +7906,7 @@ lex_embdoc(pm_parser_t *parser) { 
     | 
|
| 
       7884 
7906 
     | 
    
         | 
| 
       7885 
7907 
     | 
    
         
             
                pm_parser_err_current(parser, PM_ERR_EMBDOC_TERM);
         
     | 
| 
       7886 
7908 
     | 
    
         | 
| 
       7887 
     | 
    
         
            -
                comment->end = parser->current.end;
         
     | 
| 
      
 7909 
     | 
    
         
            +
                comment->location.end = parser->current.end;
         
     | 
| 
       7888 
7910 
     | 
    
         
             
                pm_list_append(&parser->comment_list, (pm_list_node_t *) comment);
         
     | 
| 
       7889 
7911 
     | 
    
         | 
| 
       7890 
7912 
     | 
    
         
             
                return PM_TOKEN_EOF;
         
     | 
| 
         @@ -8592,6 +8614,7 @@ parser_lex(pm_parser_t *parser) { 
     | 
|
| 
       8592 
8614 
     | 
    
         
             
                                                // TODO: handle unterminated heredoc
         
     | 
| 
       8593 
8615 
     | 
    
         
             
                                            }
         
     | 
| 
       8594 
8616 
     | 
    
         | 
| 
      
 8617 
     | 
    
         
            +
                                            parser->explicit_encoding = NULL;
         
     | 
| 
       8595 
8618 
     | 
    
         
             
                                            lex_mode_push(parser, (pm_lex_mode_t) {
         
     | 
| 
       8596 
8619 
     | 
    
         
             
                                                .mode = PM_LEX_HEREDOC,
         
     | 
| 
       8597 
8620 
     | 
    
         
             
                                                .as.heredoc = {
         
     | 
| 
         @@ -8998,7 +9021,7 @@ parser_lex(pm_parser_t *parser) { 
     | 
|
| 
       8998 
9021 
     | 
    
         
             
                                    (lex_state_p(parser, PM_LEX_STATE_FITEM) && (peek(parser) == 's')) ||
         
     | 
| 
       8999 
9022 
     | 
    
         
             
                                    lex_state_spcarg_p(parser, space_seen)
         
     | 
| 
       9000 
9023 
     | 
    
         
             
                                ) {
         
     | 
| 
       9001 
     | 
    
         
            -
                                    if (!parser->encoding 
     | 
| 
      
 9024 
     | 
    
         
            +
                                    if (!parser->encoding->alnum_char(parser->current.end, parser->end - parser->current.end)) {
         
     | 
| 
       9002 
9025 
     | 
    
         
             
                                        if (*parser->current.end >= 0x80) {
         
     | 
| 
       9003 
9026 
     | 
    
         
             
                                            pm_parser_err_current(parser, PM_ERR_INVALID_PERCENT);
         
     | 
| 
       9004 
9027 
     | 
    
         
             
                                        }
         
     | 
| 
         @@ -9021,7 +9044,7 @@ parser_lex(pm_parser_t *parser) { 
     | 
|
| 
       9021 
9044 
     | 
    
         
             
                                    // Delimiters for %-literals cannot be alphanumeric. We
         
     | 
| 
       9022 
9045 
     | 
    
         
             
                                    // validate that here.
         
     | 
| 
       9023 
9046 
     | 
    
         
             
                                    uint8_t delimiter = peek_offset(parser, 1);
         
     | 
| 
       9024 
     | 
    
         
            -
                                    if (delimiter >= 0x80 || parser->encoding 
     | 
| 
      
 9047 
     | 
    
         
            +
                                    if (delimiter >= 0x80 || parser->encoding->alnum_char(&delimiter, 1)) {
         
     | 
| 
       9025 
9048 
     | 
    
         
             
                                        pm_parser_err_current(parser, PM_ERR_INVALID_PERCENT);
         
     | 
| 
       9026 
9049 
     | 
    
         
             
                                        goto lex_next_token;
         
     | 
| 
       9027 
9050 
     | 
    
         
             
                                    }
         
     | 
| 
         @@ -9207,8 +9230,8 @@ parser_lex(pm_parser_t *parser) { 
     | 
|
| 
       9207 
9230 
     | 
    
         
             
                                    parser->current.type = PM_TOKEN___END__;
         
     | 
| 
       9208 
9231 
     | 
    
         
             
                                    parser_lex_callback(parser);
         
     | 
| 
       9209 
9232 
     | 
    
         | 
| 
       9210 
     | 
    
         
            -
                                     
     | 
| 
       9211 
     | 
    
         
            -
                                     
     | 
| 
      
 9233 
     | 
    
         
            +
                                    parser->data_loc.start = parser->current.start;
         
     | 
| 
      
 9234 
     | 
    
         
            +
                                    parser->data_loc.end = parser->current.end;
         
     | 
| 
       9212 
9235 
     | 
    
         | 
| 
       9213 
9236 
     | 
    
         
             
                                    LEX(PM_TOKEN_EOF);
         
     | 
| 
       9214 
9237 
     | 
    
         
             
                                }
         
     | 
| 
         @@ -9437,7 +9460,9 @@ parser_lex(pm_parser_t *parser) { 
     | 
|
| 
       9437 
9460 
     | 
    
         | 
| 
       9438 
9461 
     | 
    
         
             
                        // If we were unable to find a breakpoint, then this token hits the
         
     | 
| 
       9439 
9462 
     | 
    
         
             
                        // end of the file.
         
     | 
| 
       9440 
     | 
    
         
            -
                         
     | 
| 
      
 9463 
     | 
    
         
            +
                        parser->current.end = parser->end;
         
     | 
| 
      
 9464 
     | 
    
         
            +
                        pm_token_buffer_flush(parser, &token_buffer);
         
     | 
| 
      
 9465 
     | 
    
         
            +
                        LEX(PM_TOKEN_STRING_CONTENT);
         
     | 
| 
       9441 
9466 
     | 
    
         
             
                    }
         
     | 
| 
       9442 
9467 
     | 
    
         
             
                    case PM_LEX_REGEXP: {
         
     | 
| 
       9443 
9468 
     | 
    
         
             
                        // First, we'll set to start of this token to be the current end.
         
     | 
| 
         @@ -9545,7 +9570,9 @@ parser_lex(pm_parser_t *parser) { 
     | 
|
| 
       9545 
9570 
     | 
    
         
             
                                    case '\r':
         
     | 
| 
       9546 
9571 
     | 
    
         
             
                                        parser->current.end++;
         
     | 
| 
       9547 
9572 
     | 
    
         
             
                                        if (peek(parser) != '\n') {
         
     | 
| 
       9548 
     | 
    
         
            -
                                             
     | 
| 
      
 9573 
     | 
    
         
            +
                                            if (lex_mode->as.regexp.terminator != '\r') {
         
     | 
| 
      
 9574 
     | 
    
         
            +
                                                pm_token_buffer_push(&token_buffer, '\\');
         
     | 
| 
      
 9575 
     | 
    
         
            +
                                            }
         
     | 
| 
       9549 
9576 
     | 
    
         
             
                                            pm_token_buffer_push(&token_buffer, '\r');
         
     | 
| 
       9550 
9577 
     | 
    
         
             
                                            break;
         
     | 
| 
       9551 
9578 
     | 
    
         
             
                                        }
         
     | 
| 
         @@ -9573,7 +9600,20 @@ parser_lex(pm_parser_t *parser) { 
     | 
|
| 
       9573 
9600 
     | 
    
         
             
                                        escape_read(parser, &token_buffer.buffer, PM_ESCAPE_FLAG_REGEXP);
         
     | 
| 
       9574 
9601 
     | 
    
         
             
                                        break;
         
     | 
| 
       9575 
9602 
     | 
    
         
             
                                    default:
         
     | 
| 
       9576 
     | 
    
         
            -
                                        if (lex_mode->as.regexp.terminator ==  
     | 
| 
      
 9603 
     | 
    
         
            +
                                        if (lex_mode->as.regexp.terminator == peeked) {
         
     | 
| 
      
 9604 
     | 
    
         
            +
                                            // Some characters when they are used as the
         
     | 
| 
      
 9605 
     | 
    
         
            +
                                            // terminator also receive an escape. They are
         
     | 
| 
      
 9606 
     | 
    
         
            +
                                            // enumerated here.
         
     | 
| 
      
 9607 
     | 
    
         
            +
                                            switch (peeked) {
         
     | 
| 
      
 9608 
     | 
    
         
            +
                                                case '$': case ')': case '*': case '+':
         
     | 
| 
      
 9609 
     | 
    
         
            +
                                                case '.': case '>': case '?': case ']':
         
     | 
| 
      
 9610 
     | 
    
         
            +
                                                case '^': case '|': case '}':
         
     | 
| 
      
 9611 
     | 
    
         
            +
                                                    pm_token_buffer_push(&token_buffer, '\\');
         
     | 
| 
      
 9612 
     | 
    
         
            +
                                                    break;
         
     | 
| 
      
 9613 
     | 
    
         
            +
                                                default:
         
     | 
| 
      
 9614 
     | 
    
         
            +
                                                    break;
         
     | 
| 
      
 9615 
     | 
    
         
            +
                                            }
         
     | 
| 
      
 9616 
     | 
    
         
            +
             
     | 
| 
       9577 
9617 
     | 
    
         
             
                                            pm_token_buffer_push(&token_buffer, peeked);
         
     | 
| 
       9578 
9618 
     | 
    
         
             
                                            parser->current.end++;
         
     | 
| 
       9579 
9619 
     | 
    
         
             
                                            break;
         
     | 
| 
         @@ -9626,7 +9666,9 @@ parser_lex(pm_parser_t *parser) { 
     | 
|
| 
       9626 
9666 
     | 
    
         | 
| 
       9627 
9667 
     | 
    
         
             
                        // If we were unable to find a breakpoint, then this token hits the
         
     | 
| 
       9628 
9668 
     | 
    
         
             
                        // end of the file.
         
     | 
| 
       9629 
     | 
    
         
            -
                         
     | 
| 
      
 9669 
     | 
    
         
            +
                        parser->current.end = parser->end;
         
     | 
| 
      
 9670 
     | 
    
         
            +
                        pm_token_buffer_flush(parser, &token_buffer);
         
     | 
| 
      
 9671 
     | 
    
         
            +
                        LEX(PM_TOKEN_STRING_CONTENT);
         
     | 
| 
       9630 
9672 
     | 
    
         
             
                    }
         
     | 
| 
       9631 
9673 
     | 
    
         
             
                    case PM_LEX_STRING: {
         
     | 
| 
       9632 
9674 
     | 
    
         
             
                        // First, we'll set to start of this token to be the current end.
         
     | 
| 
         @@ -9830,8 +9872,10 @@ parser_lex(pm_parser_t *parser) { 
     | 
|
| 
       9830 
9872 
     | 
    
         
             
                        }
         
     | 
| 
       9831 
9873 
     | 
    
         | 
| 
       9832 
9874 
     | 
    
         
             
                        // If we've hit the end of the string, then this is an unterminated
         
     | 
| 
       9833 
     | 
    
         
            -
                        // string. In that case we'll return  
     | 
| 
       9834 
     | 
    
         
            -
                         
     | 
| 
      
 9875 
     | 
    
         
            +
                        // string. In that case we'll return a string content token.
         
     | 
| 
      
 9876 
     | 
    
         
            +
                        parser->current.end = parser->end;
         
     | 
| 
      
 9877 
     | 
    
         
            +
                        pm_token_buffer_flush(parser, &token_buffer);
         
     | 
| 
      
 9878 
     | 
    
         
            +
                        LEX(PM_TOKEN_STRING_CONTENT);
         
     | 
| 
       9835 
9879 
     | 
    
         
             
                    }
         
     | 
| 
       9836 
9880 
     | 
    
         
             
                    case PM_LEX_HEREDOC: {
         
     | 
| 
       9837 
9881 
     | 
    
         
             
                        // First, we'll set to start of this token.
         
     | 
| 
         @@ -9860,24 +9904,42 @@ parser_lex(pm_parser_t *parser) { 
     | 
|
| 
       9860 
9904 
     | 
    
         
             
                        // terminator, then we need to return the ending of the heredoc.
         
     | 
| 
       9861 
9905 
     | 
    
         
             
                        if (current_token_starts_line(parser)) {
         
     | 
| 
       9862 
9906 
     | 
    
         
             
                            const uint8_t *start = parser->current.start;
         
     | 
| 
       9863 
     | 
    
         
            -
                             
     | 
| 
      
 9907 
     | 
    
         
            +
                            if (start + ident_length <= parser->end) {
         
     | 
| 
      
 9908 
     | 
    
         
            +
                                const uint8_t *newline = next_newline(start, parser->end - start);
         
     | 
| 
      
 9909 
     | 
    
         
            +
                                const uint8_t *ident_end = newline;
         
     | 
| 
      
 9910 
     | 
    
         
            +
                                const uint8_t *terminator_end = newline;
         
     | 
| 
      
 9911 
     | 
    
         
            +
             
     | 
| 
      
 9912 
     | 
    
         
            +
                                if (newline == NULL) {
         
     | 
| 
      
 9913 
     | 
    
         
            +
                                    terminator_end = parser->end;
         
     | 
| 
      
 9914 
     | 
    
         
            +
                                    ident_end = parser->end;
         
     | 
| 
      
 9915 
     | 
    
         
            +
                                } else {
         
     | 
| 
      
 9916 
     | 
    
         
            +
                                    terminator_end++;
         
     | 
| 
      
 9917 
     | 
    
         
            +
                                    if (newline[-1] == '\r') {
         
     | 
| 
      
 9918 
     | 
    
         
            +
                                        ident_end--; // Remove \r
         
     | 
| 
      
 9919 
     | 
    
         
            +
                                    }
         
     | 
| 
      
 9920 
     | 
    
         
            +
                                }
         
     | 
| 
       9864 
9921 
     | 
    
         | 
| 
       9865 
     | 
    
         
            -
             
     | 
| 
       9866 
     | 
    
         
            -
                                 
     | 
| 
       9867 
     | 
    
         
            -
                                bool at_end = false;
         
     | 
| 
      
 9922 
     | 
    
         
            +
                                const uint8_t *terminator_start = ident_end - ident_length;
         
     | 
| 
      
 9923 
     | 
    
         
            +
                                const uint8_t *cursor = start;
         
     | 
| 
       9868 
9924 
     | 
    
         | 
| 
       9869 
     | 
    
         
            -
                                 
     | 
| 
       9870 
     | 
    
         
            -
             
     | 
| 
       9871 
     | 
    
         
            -
                                     
     | 
| 
       9872 
     | 
    
         
            -
             
     | 
| 
       9873 
     | 
    
         
            -
             
     | 
| 
       9874 
     | 
    
         
            -
             
     | 
| 
       9875 
     | 
    
         
            -
                                     
     | 
| 
       9876 
     | 
    
         
            -
                                } else {
         
     | 
| 
       9877 
     | 
    
         
            -
                                    matched = false;
         
     | 
| 
      
 9925 
     | 
    
         
            +
                                if (
         
     | 
| 
      
 9926 
     | 
    
         
            +
                                    lex_mode->as.heredoc.indent == PM_HEREDOC_INDENT_DASH ||
         
     | 
| 
      
 9927 
     | 
    
         
            +
                                    lex_mode->as.heredoc.indent == PM_HEREDOC_INDENT_TILDE
         
     | 
| 
      
 9928 
     | 
    
         
            +
                                ) {
         
     | 
| 
      
 9929 
     | 
    
         
            +
                                    while (cursor < terminator_start && pm_char_is_inline_whitespace(*cursor)) {
         
     | 
| 
      
 9930 
     | 
    
         
            +
                                        cursor++;
         
     | 
| 
      
 9931 
     | 
    
         
            +
                                    }
         
     | 
| 
       9878 
9932 
     | 
    
         
             
                                }
         
     | 
| 
       9879 
9933 
     | 
    
         | 
| 
       9880 
     | 
    
         
            -
                                if ( 
     | 
| 
      
 9934 
     | 
    
         
            +
                                if (
         
     | 
| 
      
 9935 
     | 
    
         
            +
                                    (cursor == terminator_start) &&
         
     | 
| 
      
 9936 
     | 
    
         
            +
                                    (memcmp(terminator_start, ident_start, ident_length) == 0)
         
     | 
| 
      
 9937 
     | 
    
         
            +
                                ) {
         
     | 
| 
      
 9938 
     | 
    
         
            +
                                    if (newline != NULL) {
         
     | 
| 
      
 9939 
     | 
    
         
            +
                                        pm_newline_list_append(&parser->newline_list, newline);
         
     | 
| 
      
 9940 
     | 
    
         
            +
                                    }
         
     | 
| 
      
 9941 
     | 
    
         
            +
             
     | 
| 
      
 9942 
     | 
    
         
            +
                                    parser->current.end = terminator_end;
         
     | 
| 
       9881 
9943 
     | 
    
         
             
                                    if (*lex_mode->as.heredoc.next_start == '\\') {
         
     | 
| 
       9882 
9944 
     | 
    
         
             
                                        parser->next_start = NULL;
         
     | 
| 
       9883 
9945 
     | 
    
         
             
                                    } else {
         
     | 
| 
         @@ -9885,15 +9947,12 @@ parser_lex(pm_parser_t *parser) { 
     | 
|
| 
       9885 
9947 
     | 
    
         
             
                                        parser->heredoc_end = parser->current.end;
         
     | 
| 
       9886 
9948 
     | 
    
         
             
                                    }
         
     | 
| 
       9887 
9949 
     | 
    
         | 
| 
       9888 
     | 
    
         
            -
                                    parser 
     | 
| 
       9889 
     | 
    
         
            -
                                    lex_mode_pop(parser);
         
     | 
| 
       9890 
     | 
    
         
            -
                                    if (!at_end) {
         
     | 
| 
       9891 
     | 
    
         
            -
                                        lex_state_set(parser, PM_LEX_STATE_END);
         
     | 
| 
       9892 
     | 
    
         
            -
                                    }
         
     | 
| 
      
 9950 
     | 
    
         
            +
                                    lex_state_set(parser, PM_LEX_STATE_END);
         
     | 
| 
       9893 
9951 
     | 
    
         
             
                                    LEX(PM_TOKEN_HEREDOC_END);
         
     | 
| 
       9894 
9952 
     | 
    
         
             
                                }
         
     | 
| 
       9895 
9953 
     | 
    
         
             
                            }
         
     | 
| 
       9896 
9954 
     | 
    
         | 
| 
      
 9955 
     | 
    
         
            +
                            size_t whitespace = pm_heredoc_strspn_inline_whitespace(parser, &start, lex_mode->as.heredoc.indent);
         
     | 
| 
       9897 
9956 
     | 
    
         
             
                            if (
         
     | 
| 
       9898 
9957 
     | 
    
         
             
                                lex_mode->as.heredoc.indent == PM_HEREDOC_INDENT_TILDE &&
         
     | 
| 
       9899 
9958 
     | 
    
         
             
                                (lex_mode->as.heredoc.common_whitespace > whitespace) &&
         
     | 
| 
         @@ -9937,23 +9996,35 @@ parser_lex(pm_parser_t *parser) { 
     | 
|
| 
       9937 
9996 
     | 
    
         
             
                                    // If we have a - or ~ heredoc, then we can match after
         
     | 
| 
       9938 
9997 
     | 
    
         
             
                                    // some leading whitespace.
         
     | 
| 
       9939 
9998 
     | 
    
         
             
                                    const uint8_t *start = breakpoint + 1;
         
     | 
| 
       9940 
     | 
    
         
            -
                                    size_t whitespace = pm_heredoc_strspn_inline_whitespace(parser, &start, lex_mode->as.heredoc.indent);
         
     | 
| 
       9941 
9999 
     | 
    
         | 
| 
       9942 
     | 
    
         
            -
                                     
     | 
| 
       9943 
     | 
    
         
            -
             
     | 
| 
       9944 
     | 
    
         
            -
             
     | 
| 
       9945 
     | 
    
         
            -
             
     | 
| 
       9946 
     | 
    
         
            -
             
     | 
| 
       9947 
     | 
    
         
            -
             
     | 
| 
       9948 
     | 
    
         
            -
             
     | 
| 
       9949 
     | 
    
         
            -
                                         
     | 
| 
       9950 
     | 
    
         
            -
             
     | 
| 
       9951 
     | 
    
         
            -
             
     | 
| 
       9952 
     | 
    
         
            -
             
     | 
| 
       9953 
     | 
    
         
            -
                                        //  
     | 
| 
      
 10000 
     | 
    
         
            +
                                    if (!was_escaped_newline && (start + ident_length <= parser->end)) {
         
     | 
| 
      
 10001 
     | 
    
         
            +
                                        // We want to match the terminator starting from the end of the line in case
         
     | 
| 
      
 10002 
     | 
    
         
            +
                                        // there is whitespace in the ident such as <<-'   DOC' or <<~'   DOC'.
         
     | 
| 
      
 10003 
     | 
    
         
            +
                                        const uint8_t *newline = next_newline(start, parser->end - start);
         
     | 
| 
      
 10004 
     | 
    
         
            +
             
     | 
| 
      
 10005 
     | 
    
         
            +
                                        if (newline == NULL) {
         
     | 
| 
      
 10006 
     | 
    
         
            +
                                            newline = parser->end;
         
     | 
| 
      
 10007 
     | 
    
         
            +
                                        } else if (newline[-1] == '\r') {
         
     | 
| 
      
 10008 
     | 
    
         
            +
                                            newline--; // Remove \r
         
     | 
| 
      
 10009 
     | 
    
         
            +
                                        }
         
     | 
| 
      
 10010 
     | 
    
         
            +
             
     | 
| 
      
 10011 
     | 
    
         
            +
                                        // Start of a possible terminator.
         
     | 
| 
      
 10012 
     | 
    
         
            +
                                        const uint8_t *terminator_start = newline - ident_length;
         
     | 
| 
      
 10013 
     | 
    
         
            +
             
     | 
| 
      
 10014 
     | 
    
         
            +
                                        // Cursor to check for the leading whitespace. We skip the
         
     | 
| 
      
 10015 
     | 
    
         
            +
                                        // leading whitespace if we have a - or ~ heredoc.
         
     | 
| 
      
 10016 
     | 
    
         
            +
                                        const uint8_t *cursor = start;
         
     | 
| 
      
 10017 
     | 
    
         
            +
             
     | 
| 
      
 10018 
     | 
    
         
            +
                                        if (lex_mode->as.heredoc.indent == PM_HEREDOC_INDENT_DASH ||
         
     | 
| 
      
 10019 
     | 
    
         
            +
                                            lex_mode->as.heredoc.indent == PM_HEREDOC_INDENT_TILDE) {
         
     | 
| 
      
 10020 
     | 
    
         
            +
                                            while (cursor < terminator_start && pm_char_is_inline_whitespace(*cursor)) {
         
     | 
| 
      
 10021 
     | 
    
         
            +
                                                cursor++;
         
     | 
| 
      
 10022 
     | 
    
         
            +
                                            }
         
     | 
| 
      
 10023 
     | 
    
         
            +
                                        }
         
     | 
| 
      
 10024 
     | 
    
         
            +
             
     | 
| 
       9954 
10025 
     | 
    
         
             
                                        if (
         
     | 
| 
       9955 
     | 
    
         
            -
                                             
     | 
| 
       9956 
     | 
    
         
            -
                                             
     | 
| 
      
 10026 
     | 
    
         
            +
                                            cursor == terminator_start &&
         
     | 
| 
      
 10027 
     | 
    
         
            +
                                            (memcmp(terminator_start, ident_start, ident_length) == 0)
         
     | 
| 
       9957 
10028 
     | 
    
         
             
                                        ) {
         
     | 
| 
       9958 
10029 
     | 
    
         
             
                                            parser->current.end = breakpoint + 1;
         
     | 
| 
       9959 
10030 
     | 
    
         
             
                                            pm_token_buffer_flush(parser, &token_buffer);
         
     | 
| 
         @@ -9961,6 +10032,14 @@ parser_lex(pm_parser_t *parser) { 
     | 
|
| 
       9961 
10032 
     | 
    
         
             
                                        }
         
     | 
| 
       9962 
10033 
     | 
    
         
             
                                    }
         
     | 
| 
       9963 
10034 
     | 
    
         | 
| 
      
 10035 
     | 
    
         
            +
                                    size_t whitespace = pm_heredoc_strspn_inline_whitespace(parser, &start, lex_mode->as.heredoc.indent);
         
     | 
| 
      
 10036 
     | 
    
         
            +
             
     | 
| 
      
 10037 
     | 
    
         
            +
                                    // If we have hit a newline that is followed by a valid
         
     | 
| 
      
 10038 
     | 
    
         
            +
                                    // terminator, then we need to return the content of the
         
     | 
| 
      
 10039 
     | 
    
         
            +
                                    // heredoc here as string content. Then, the next time a
         
     | 
| 
      
 10040 
     | 
    
         
            +
                                    // token is lexed, it will match again and return the
         
     | 
| 
      
 10041 
     | 
    
         
            +
                                    // end of the heredoc.
         
     | 
| 
      
 10042 
     | 
    
         
            +
             
     | 
| 
       9964 
10043 
     | 
    
         
             
                                    if (lex_mode->as.heredoc.indent == PM_HEREDOC_INDENT_TILDE) {
         
     | 
| 
       9965 
10044 
     | 
    
         
             
                                        if ((lex_mode->as.heredoc.common_whitespace > whitespace) && peek_at(parser, start) != '\n') {
         
     | 
| 
       9966 
10045 
     | 
    
         
             
                                            lex_mode->as.heredoc.common_whitespace = whitespace;
         
     | 
| 
         @@ -10078,8 +10157,10 @@ parser_lex(pm_parser_t *parser) { 
     | 
|
| 
       10078 
10157 
     | 
    
         
             
                        }
         
     | 
| 
       10079 
10158 
     | 
    
         | 
| 
       10080 
10159 
     | 
    
         
             
                        // If we've hit the end of the string, then this is an unterminated
         
     | 
| 
       10081 
     | 
    
         
            -
                        // heredoc. In that case we'll return  
     | 
| 
       10082 
     | 
    
         
            -
                         
     | 
| 
      
 10160 
     | 
    
         
            +
                        // heredoc. In that case we'll return a string content token.
         
     | 
| 
      
 10161 
     | 
    
         
            +
                        parser->current.end = parser->end;
         
     | 
| 
      
 10162 
     | 
    
         
            +
                        pm_token_buffer_flush(parser, &token_buffer);
         
     | 
| 
      
 10163 
     | 
    
         
            +
                        LEX(PM_TOKEN_STRING_CONTENT);
         
     | 
| 
       10083 
10164 
     | 
    
         
             
                    }
         
     | 
| 
       10084 
10165 
     | 
    
         
             
                }
         
     | 
| 
       10085 
10166 
     | 
    
         | 
| 
         @@ -10101,32 +10182,33 @@ parser_lex(pm_parser_t *parser) { 
     | 
|
| 
       10101 
10182 
     | 
    
         
             
             * specify their associativity by adding or subtracting one.
         
     | 
| 
       10102 
10183 
     | 
    
         
             
             */
         
     | 
| 
       10103 
10184 
     | 
    
         
             
            typedef enum {
         
     | 
| 
       10104 
     | 
    
         
            -
                PM_BINDING_POWER_UNSET = 
     | 
| 
       10105 
     | 
    
         
            -
                PM_BINDING_POWER_STATEMENT = 
     | 
| 
       10106 
     | 
    
         
            -
                PM_BINDING_POWER_MODIFIER = 
     | 
| 
       10107 
     | 
    
         
            -
                PM_BINDING_POWER_MODIFIER_RESCUE = 
     | 
| 
       10108 
     | 
    
         
            -
                PM_BINDING_POWER_COMPOSITION = 
     | 
| 
       10109 
     | 
    
         
            -
                PM_BINDING_POWER_NOT = 
     | 
| 
       10110 
     | 
    
         
            -
                PM_BINDING_POWER_MATCH = 
     | 
| 
       10111 
     | 
    
         
            -
                PM_BINDING_POWER_DEFINED = 
     | 
| 
       10112 
     | 
    
         
            -
                 
     | 
| 
       10113 
     | 
    
         
            -
                 
     | 
| 
       10114 
     | 
    
         
            -
                 
     | 
| 
       10115 
     | 
    
         
            -
                 
     | 
| 
       10116 
     | 
    
         
            -
                 
     | 
| 
       10117 
     | 
    
         
            -
                 
     | 
| 
       10118 
     | 
    
         
            -
                 
     | 
| 
       10119 
     | 
    
         
            -
                 
     | 
| 
       10120 
     | 
    
         
            -
                 
     | 
| 
       10121 
     | 
    
         
            -
                 
     | 
| 
       10122 
     | 
    
         
            -
                 
     | 
| 
       10123 
     | 
    
         
            -
                 
     | 
| 
       10124 
     | 
    
         
            -
                 
     | 
| 
       10125 
     | 
    
         
            -
                 
     | 
| 
       10126 
     | 
    
         
            -
                 
     | 
| 
       10127 
     | 
    
         
            -
                 
     | 
| 
       10128 
     | 
    
         
            -
                 
     | 
| 
       10129 
     | 
    
         
            -
                 
     | 
| 
      
 10185 
     | 
    
         
            +
                PM_BINDING_POWER_UNSET =             0, // used to indicate this token cannot be used as an infix operator
         
     | 
| 
      
 10186 
     | 
    
         
            +
                PM_BINDING_POWER_STATEMENT =         2,
         
     | 
| 
      
 10187 
     | 
    
         
            +
                PM_BINDING_POWER_MODIFIER =          4, // if unless until while
         
     | 
| 
      
 10188 
     | 
    
         
            +
                PM_BINDING_POWER_MODIFIER_RESCUE =   6, // rescue
         
     | 
| 
      
 10189 
     | 
    
         
            +
                PM_BINDING_POWER_COMPOSITION =       8, // and or
         
     | 
| 
      
 10190 
     | 
    
         
            +
                PM_BINDING_POWER_NOT =              10, // not
         
     | 
| 
      
 10191 
     | 
    
         
            +
                PM_BINDING_POWER_MATCH =            12, // => in
         
     | 
| 
      
 10192 
     | 
    
         
            +
                PM_BINDING_POWER_DEFINED =          14, // defined?
         
     | 
| 
      
 10193 
     | 
    
         
            +
                PM_BINDING_POWER_MULTI_ASSIGNMENT = 16, // =
         
     | 
| 
      
 10194 
     | 
    
         
            +
                PM_BINDING_POWER_ASSIGNMENT =       18, // = += -= *= /= %= &= |= ^= &&= ||= <<= >>= **=
         
     | 
| 
      
 10195 
     | 
    
         
            +
                PM_BINDING_POWER_TERNARY =          20, // ?:
         
     | 
| 
      
 10196 
     | 
    
         
            +
                PM_BINDING_POWER_RANGE =            22, // .. ...
         
     | 
| 
      
 10197 
     | 
    
         
            +
                PM_BINDING_POWER_LOGICAL_OR =       24, // ||
         
     | 
| 
      
 10198 
     | 
    
         
            +
                PM_BINDING_POWER_LOGICAL_AND =      26, // &&
         
     | 
| 
      
 10199 
     | 
    
         
            +
                PM_BINDING_POWER_EQUALITY =         28, // <=> == === != =~ !~
         
     | 
| 
      
 10200 
     | 
    
         
            +
                PM_BINDING_POWER_COMPARISON =       30, // > >= < <=
         
     | 
| 
      
 10201 
     | 
    
         
            +
                PM_BINDING_POWER_BITWISE_OR =       32, // | ^
         
     | 
| 
      
 10202 
     | 
    
         
            +
                PM_BINDING_POWER_BITWISE_AND =      34, // &
         
     | 
| 
      
 10203 
     | 
    
         
            +
                PM_BINDING_POWER_SHIFT =            36, // << >>
         
     | 
| 
      
 10204 
     | 
    
         
            +
                PM_BINDING_POWER_TERM =             38, // + -
         
     | 
| 
      
 10205 
     | 
    
         
            +
                PM_BINDING_POWER_FACTOR =           40, // * / %
         
     | 
| 
      
 10206 
     | 
    
         
            +
                PM_BINDING_POWER_UMINUS =           42, // -@
         
     | 
| 
      
 10207 
     | 
    
         
            +
                PM_BINDING_POWER_EXPONENT =         44, // **
         
     | 
| 
      
 10208 
     | 
    
         
            +
                PM_BINDING_POWER_UNARY =            46, // ! ~ +@
         
     | 
| 
      
 10209 
     | 
    
         
            +
                PM_BINDING_POWER_INDEX =            48, // [] []=
         
     | 
| 
      
 10210 
     | 
    
         
            +
                PM_BINDING_POWER_CALL =             50, // :: .
         
     | 
| 
      
 10211 
     | 
    
         
            +
                PM_BINDING_POWER_MAX =              52
         
     | 
| 
       10130 
10212 
     | 
    
         
             
            } pm_binding_power_t;
         
     | 
| 
       10131 
10213 
     | 
    
         | 
| 
       10132 
10214 
     | 
    
         
             
            /**
         
     | 
| 
         @@ -10153,7 +10235,7 @@ typedef struct { 
     | 
|
| 
       10153 
10235 
     | 
    
         
             
            #define BINDING_POWER_ASSIGNMENT { PM_BINDING_POWER_UNARY, PM_BINDING_POWER_ASSIGNMENT, true, false }
         
     | 
| 
       10154 
10236 
     | 
    
         
             
            #define LEFT_ASSOCIATIVE(precedence) { precedence, precedence + 1, true, false }
         
     | 
| 
       10155 
10237 
     | 
    
         
             
            #define RIGHT_ASSOCIATIVE(precedence) { precedence, precedence, true, false }
         
     | 
| 
       10156 
     | 
    
         
            -
            #define NON_ASSOCIATIVE(precedence) { precedence 
     | 
| 
      
 10238 
     | 
    
         
            +
            #define NON_ASSOCIATIVE(precedence) { precedence, precedence + 1, true, true }
         
     | 
| 
       10157 
10239 
     | 
    
         
             
            #define RIGHT_ASSOCIATIVE_UNARY(precedence) { precedence, precedence, false, false }
         
     | 
| 
       10158 
10240 
     | 
    
         | 
| 
       10159 
10241 
     | 
    
         
             
            pm_binding_powers_t pm_binding_powers[PM_TOKEN_MAXIMUM] = {
         
     | 
| 
         @@ -10196,6 +10278,8 @@ pm_binding_powers_t pm_binding_powers[PM_TOKEN_MAXIMUM] = { 
     | 
|
| 
       10196 
10278 
     | 
    
         
             
                // .. ...
         
     | 
| 
       10197 
10279 
     | 
    
         
             
                [PM_TOKEN_DOT_DOT] = NON_ASSOCIATIVE(PM_BINDING_POWER_RANGE),
         
     | 
| 
       10198 
10280 
     | 
    
         
             
                [PM_TOKEN_DOT_DOT_DOT] = NON_ASSOCIATIVE(PM_BINDING_POWER_RANGE),
         
     | 
| 
      
 10281 
     | 
    
         
            +
                [PM_TOKEN_UDOT_DOT] = RIGHT_ASSOCIATIVE_UNARY(PM_BINDING_POWER_LOGICAL_OR),
         
     | 
| 
      
 10282 
     | 
    
         
            +
                [PM_TOKEN_UDOT_DOT_DOT] = RIGHT_ASSOCIATIVE_UNARY(PM_BINDING_POWER_LOGICAL_OR),
         
     | 
| 
       10199 
10283 
     | 
    
         | 
| 
       10200 
10284 
     | 
    
         
             
                // ||
         
     | 
| 
       10201 
10285 
     | 
    
         
             
                [PM_TOKEN_PIPE_PIPE] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_LOGICAL_OR),
         
     | 
| 
         @@ -10204,12 +10288,12 @@ pm_binding_powers_t pm_binding_powers[PM_TOKEN_MAXIMUM] = { 
     | 
|
| 
       10204 
10288 
     | 
    
         
             
                [PM_TOKEN_AMPERSAND_AMPERSAND] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_LOGICAL_AND),
         
     | 
| 
       10205 
10289 
     | 
    
         | 
| 
       10206 
10290 
     | 
    
         
             
                // != !~ == === =~ <=>
         
     | 
| 
       10207 
     | 
    
         
            -
                [PM_TOKEN_BANG_EQUAL] =  
     | 
| 
       10208 
     | 
    
         
            -
                [PM_TOKEN_BANG_TILDE] =  
     | 
| 
       10209 
     | 
    
         
            -
                [PM_TOKEN_EQUAL_EQUAL] =  
     | 
| 
       10210 
     | 
    
         
            -
                [PM_TOKEN_EQUAL_EQUAL_EQUAL] =  
     | 
| 
       10211 
     | 
    
         
            -
                [PM_TOKEN_EQUAL_TILDE] =  
     | 
| 
       10212 
     | 
    
         
            -
                [PM_TOKEN_LESS_EQUAL_GREATER] =  
     | 
| 
      
 10291 
     | 
    
         
            +
                [PM_TOKEN_BANG_EQUAL] = NON_ASSOCIATIVE(PM_BINDING_POWER_EQUALITY),
         
     | 
| 
      
 10292 
     | 
    
         
            +
                [PM_TOKEN_BANG_TILDE] = NON_ASSOCIATIVE(PM_BINDING_POWER_EQUALITY),
         
     | 
| 
      
 10293 
     | 
    
         
            +
                [PM_TOKEN_EQUAL_EQUAL] = NON_ASSOCIATIVE(PM_BINDING_POWER_EQUALITY),
         
     | 
| 
      
 10294 
     | 
    
         
            +
                [PM_TOKEN_EQUAL_EQUAL_EQUAL] = NON_ASSOCIATIVE(PM_BINDING_POWER_EQUALITY),
         
     | 
| 
      
 10295 
     | 
    
         
            +
                [PM_TOKEN_EQUAL_TILDE] = NON_ASSOCIATIVE(PM_BINDING_POWER_EQUALITY),
         
     | 
| 
      
 10296 
     | 
    
         
            +
                [PM_TOKEN_LESS_EQUAL_GREATER] = NON_ASSOCIATIVE(PM_BINDING_POWER_EQUALITY),
         
     | 
| 
       10213 
10297 
     | 
    
         | 
| 
       10214 
10298 
     | 
    
         
             
                // > >= < <=
         
     | 
| 
       10215 
10299 
     | 
    
         
             
                [PM_TOKEN_GREATER] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_COMPARISON),
         
     | 
| 
         @@ -10289,6 +10373,14 @@ match3(const pm_parser_t *parser, pm_token_type_t type1, pm_token_type_t type2, 
     | 
|
| 
       10289 
10373 
     | 
    
         
             
                return match1(parser, type1) || match1(parser, type2) || match1(parser, type3);
         
     | 
| 
       10290 
10374 
     | 
    
         
             
            }
         
     | 
| 
       10291 
10375 
     | 
    
         | 
| 
      
 10376 
     | 
    
         
            +
            /**
         
     | 
| 
      
 10377 
     | 
    
         
            +
             * Returns true if the current token is any of the four given types.
         
     | 
| 
      
 10378 
     | 
    
         
            +
             */
         
     | 
| 
      
 10379 
     | 
    
         
            +
            static inline bool
         
     | 
| 
      
 10380 
     | 
    
         
            +
            match4(const pm_parser_t *parser, pm_token_type_t type1, pm_token_type_t type2, pm_token_type_t type3, pm_token_type_t type4) {
         
     | 
| 
      
 10381 
     | 
    
         
            +
                return match1(parser, type1) || match1(parser, type2) || match1(parser, type3) || match1(parser, type4);
         
     | 
| 
      
 10382 
     | 
    
         
            +
            }
         
     | 
| 
      
 10383 
     | 
    
         
            +
             
     | 
| 
       10292 
10384 
     | 
    
         
             
            /**
         
     | 
| 
       10293 
10385 
     | 
    
         
             
             * Returns true if the current token is any of the five given types.
         
     | 
| 
       10294 
10386 
     | 
    
         
             
             */
         
     | 
| 
         @@ -10414,14 +10506,14 @@ expect3(pm_parser_t *parser, pm_token_type_t type1, pm_token_type_t type2, pm_to 
     | 
|
| 
       10414 
10506 
     | 
    
         
             
            }
         
     | 
| 
       10415 
10507 
     | 
    
         | 
| 
       10416 
10508 
     | 
    
         
             
            static pm_node_t *
         
     | 
| 
       10417 
     | 
    
         
            -
            parse_expression(pm_parser_t *parser, pm_binding_power_t binding_power, pm_diagnostic_id_t diag_id);
         
     | 
| 
      
 10509 
     | 
    
         
            +
            parse_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool accepts_command_call, pm_diagnostic_id_t diag_id);
         
     | 
| 
       10418 
10510 
     | 
    
         | 
| 
       10419 
10511 
     | 
    
         
             
            /**
         
     | 
| 
       10420 
10512 
     | 
    
         
             
             * This is a wrapper of parse_expression, which also checks whether the resulting node is value expression.
         
     | 
| 
       10421 
10513 
     | 
    
         
             
             */
         
     | 
| 
       10422 
10514 
     | 
    
         
             
            static pm_node_t *
         
     | 
| 
       10423 
     | 
    
         
            -
            parse_value_expression(pm_parser_t *parser, pm_binding_power_t binding_power, pm_diagnostic_id_t diag_id) {
         
     | 
| 
       10424 
     | 
    
         
            -
                pm_node_t *node = parse_expression(parser, binding_power, diag_id);
         
     | 
| 
      
 10515 
     | 
    
         
            +
            parse_value_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool accepts_command_call, pm_diagnostic_id_t diag_id) {
         
     | 
| 
      
 10516 
     | 
    
         
            +
                pm_node_t *node = parse_expression(parser, binding_power, accepts_command_call, diag_id);
         
     | 
| 
       10425 
10517 
     | 
    
         
             
                pm_assert_value_expression(parser, node);
         
     | 
| 
       10426 
10518 
     | 
    
         
             
                return node;
         
     | 
| 
       10427 
10519 
     | 
    
         
             
            }
         
     | 
| 
         @@ -10506,14 +10598,14 @@ token_begins_expression_p(pm_token_type_t type) { 
     | 
|
| 
       10506 
10598 
     | 
    
         
             
             * prefixed by the * operator.
         
     | 
| 
       10507 
10599 
     | 
    
         
             
             */
         
     | 
| 
       10508 
10600 
     | 
    
         
             
            static pm_node_t *
         
     | 
| 
       10509 
     | 
    
         
            -
            parse_starred_expression(pm_parser_t *parser, pm_binding_power_t binding_power, pm_diagnostic_id_t diag_id) {
         
     | 
| 
      
 10601 
     | 
    
         
            +
            parse_starred_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool accepts_command_call, pm_diagnostic_id_t diag_id) {
         
     | 
| 
       10510 
10602 
     | 
    
         
             
                if (accept1(parser, PM_TOKEN_USTAR)) {
         
     | 
| 
       10511 
10603 
     | 
    
         
             
                    pm_token_t operator = parser->previous;
         
     | 
| 
       10512 
     | 
    
         
            -
                    pm_node_t *expression = parse_value_expression(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_STAR);
         
     | 
| 
      
 10604 
     | 
    
         
            +
                    pm_node_t *expression = parse_value_expression(parser, binding_power, false, PM_ERR_EXPECT_EXPRESSION_AFTER_STAR);
         
     | 
| 
       10513 
10605 
     | 
    
         
             
                    return (pm_node_t *) pm_splat_node_create(parser, &operator, expression);
         
     | 
| 
       10514 
10606 
     | 
    
         
             
                }
         
     | 
| 
       10515 
10607 
     | 
    
         | 
| 
       10516 
     | 
    
         
            -
                return parse_value_expression(parser, binding_power, diag_id);
         
     | 
| 
      
 10608 
     | 
    
         
            +
                return parse_value_expression(parser, binding_power, accepts_command_call, diag_id);
         
     | 
| 
       10517 
10609 
     | 
    
         
             
            }
         
     | 
| 
       10518 
10610 
     | 
    
         | 
| 
       10519 
10611 
     | 
    
         
             
            /**
         
     | 
| 
         @@ -10621,7 +10713,6 @@ parse_target(pm_parser_t *parser, pm_node_t *target) { 
     | 
|
| 
       10621 
10713 
     | 
    
         
             
                                pm_node_destroy(parser, target);
         
     | 
| 
       10622 
10714 
     | 
    
         | 
| 
       10623 
10715 
     | 
    
         
             
                                uint32_t depth = 0;
         
     | 
| 
       10624 
     | 
    
         
            -
                                for (pm_scope_t *scope = parser->current_scope; scope && scope->transparent; depth++, scope = scope->previous);
         
     | 
| 
       10625 
10716 
     | 
    
         
             
                                const pm_token_t name = { .type = PM_TOKEN_IDENTIFIER, .start = message.start, .end = message.end };
         
     | 
| 
       10626 
10717 
     | 
    
         
             
                                target = (pm_node_t *) pm_local_variable_read_node_create(parser, &name, depth);
         
     | 
| 
       10627 
10718 
     | 
    
         | 
| 
         @@ -10632,25 +10723,17 @@ parse_target(pm_parser_t *parser, pm_node_t *target) { 
     | 
|
| 
       10632 
10723 
     | 
    
         
             
                                return target;
         
     | 
| 
       10633 
10724 
     | 
    
         
             
                            }
         
     | 
| 
       10634 
10725 
     | 
    
         | 
| 
       10635 
     | 
    
         
            -
                            if (*call->message_loc.start == '_' || parser->encoding 
     | 
| 
      
 10726 
     | 
    
         
            +
                            if (*call->message_loc.start == '_' || parser->encoding->alnum_char(call->message_loc.start, call->message_loc.end - call->message_loc.start)) {
         
     | 
| 
       10636 
10727 
     | 
    
         
             
                                parse_write_name(parser, &call->name);
         
     | 
| 
       10637 
     | 
    
         
            -
                                return (pm_node_t *) call;
         
     | 
| 
      
 10728 
     | 
    
         
            +
                                return (pm_node_t *) pm_call_target_node_create(parser, call);
         
     | 
| 
       10638 
10729 
     | 
    
         
             
                            }
         
     | 
| 
       10639 
10730 
     | 
    
         
             
                        }
         
     | 
| 
       10640 
10731 
     | 
    
         | 
| 
       10641 
10732 
     | 
    
         
             
                        // If there is no call operator and the message is "[]" then this is
         
     | 
| 
       10642 
10733 
     | 
    
         
             
                        // an aref expression, and we can transform it into an aset
         
     | 
| 
       10643 
10734 
     | 
    
         
             
                        // expression.
         
     | 
| 
       10644 
     | 
    
         
            -
                        if (
         
     | 
| 
       10645 
     | 
    
         
            -
                            ( 
     | 
| 
       10646 
     | 
    
         
            -
                            (call->message_loc.start != NULL) &&
         
     | 
| 
       10647 
     | 
    
         
            -
                            (call->message_loc.start[0] == '[') &&
         
     | 
| 
       10648 
     | 
    
         
            -
                            (call->message_loc.end[-1] == ']') &&
         
     | 
| 
       10649 
     | 
    
         
            -
                            (call->block == NULL)
         
     | 
| 
       10650 
     | 
    
         
            -
                        ) {
         
     | 
| 
       10651 
     | 
    
         
            -
                            // Replace the name with "[]=".
         
     | 
| 
       10652 
     | 
    
         
            -
                            call->name = pm_parser_constant_id_constant(parser, "[]=", 3);
         
     | 
| 
       10653 
     | 
    
         
            -
                            return target;
         
     | 
| 
      
 10735 
     | 
    
         
            +
                        if (pm_call_node_index_p(call)) {
         
     | 
| 
      
 10736 
     | 
    
         
            +
                            return (pm_node_t *) pm_index_target_node_create(parser, call);
         
     | 
| 
       10654 
10737 
     | 
    
         
             
                        }
         
     | 
| 
       10655 
10738 
     | 
    
         
             
                    }
         
     | 
| 
       10656 
10739 
     | 
    
         
             
                    /* fallthrough */
         
     | 
| 
         @@ -10690,6 +10773,7 @@ static pm_node_t * 
     | 
|
| 
       10690 
10773 
     | 
    
         
             
            parse_write(pm_parser_t *parser, pm_node_t *target, pm_token_t *operator, pm_node_t *value) {
         
     | 
| 
       10691 
10774 
     | 
    
         
             
                switch (PM_NODE_TYPE(target)) {
         
     | 
| 
       10692 
10775 
     | 
    
         
             
                    case PM_MISSING_NODE:
         
     | 
| 
      
 10776 
     | 
    
         
            +
                        pm_node_destroy(parser, value);
         
     | 
| 
       10693 
10777 
     | 
    
         
             
                        return target;
         
     | 
| 
       10694 
10778 
     | 
    
         
             
                    case PM_CLASS_VARIABLE_READ_NODE: {
         
     | 
| 
       10695 
10779 
     | 
    
         
             
                        pm_class_variable_write_node_t *node = pm_class_variable_write_node_create(parser, (pm_class_variable_read_node_t *) target, operator, value);
         
     | 
| 
         @@ -10700,6 +10784,9 @@ parse_write(pm_parser_t *parser, pm_node_t *target, pm_token_t *operator, pm_nod 
     | 
|
| 
       10700 
10784 
     | 
    
         
             
                        return (pm_node_t *) pm_constant_path_write_node_create(parser, (pm_constant_path_node_t *) target, operator, value);
         
     | 
| 
       10701 
10785 
     | 
    
         
             
                    case PM_CONSTANT_READ_NODE: {
         
     | 
| 
       10702 
10786 
     | 
    
         
             
                        pm_constant_write_node_t *node = pm_constant_write_node_create(parser, (pm_constant_read_node_t *) target, operator, value);
         
     | 
| 
      
 10787 
     | 
    
         
            +
                        if (context_def_p(parser)) {
         
     | 
| 
      
 10788 
     | 
    
         
            +
                            pm_parser_err_node(parser, (pm_node_t *) node, PM_ERR_WRITE_TARGET_IN_METHOD);
         
     | 
| 
      
 10789 
     | 
    
         
            +
                        }
         
     | 
| 
       10703 
10790 
     | 
    
         
             
                        pm_node_destroy(parser, target);
         
     | 
| 
       10704 
10791 
     | 
    
         
             
                        return (pm_node_t *) node;
         
     | 
| 
       10705 
10792 
     | 
    
         
             
                    }
         
     | 
| 
         @@ -10779,7 +10866,7 @@ parse_write(pm_parser_t *parser, pm_node_t *target, pm_token_t *operator, pm_nod 
     | 
|
| 
       10779 
10866 
     | 
    
         
             
                                return target;
         
     | 
| 
       10780 
10867 
     | 
    
         
             
                            }
         
     | 
| 
       10781 
10868 
     | 
    
         | 
| 
       10782 
     | 
    
         
            -
                            if (*call->message_loc.start == '_' || parser->encoding 
     | 
| 
      
 10869 
     | 
    
         
            +
                            if (*call->message_loc.start == '_' || parser->encoding->alnum_char(call->message_loc.start, call->message_loc.end - call->message_loc.start)) {
         
     | 
| 
       10783 
10870 
     | 
    
         
             
                                // When we get here, we have a method call, because it was
         
     | 
| 
       10784 
10871 
     | 
    
         
             
                                // previously marked as a method call but now we have an =. This
         
     | 
| 
       10785 
10872 
     | 
    
         
             
                                // looks like:
         
     | 
| 
         @@ -10797,6 +10884,7 @@ parse_write(pm_parser_t *parser, pm_node_t *target, pm_token_t *operator, pm_nod 
     | 
|
| 
       10797 
10884 
     | 
    
         
             
                                call->base.location.end = arguments->base.location.end;
         
     | 
| 
       10798 
10885 
     | 
    
         | 
| 
       10799 
10886 
     | 
    
         
             
                                parse_write_name(parser, &call->name);
         
     | 
| 
      
 10887 
     | 
    
         
            +
                                pm_node_flag_set((pm_node_t *) call, PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE);
         
     | 
| 
       10800 
10888 
     | 
    
         
             
                                return (pm_node_t *) call;
         
     | 
| 
       10801 
10889 
     | 
    
         
             
                            }
         
     | 
| 
       10802 
10890 
     | 
    
         
             
                        }
         
     | 
| 
         @@ -10804,13 +10892,7 @@ parse_write(pm_parser_t *parser, pm_node_t *target, pm_token_t *operator, pm_nod 
     | 
|
| 
       10804 
10892 
     | 
    
         
             
                        // If there is no call operator and the message is "[]" then this is
         
     | 
| 
       10805 
10893 
     | 
    
         
             
                        // an aref expression, and we can transform it into an aset
         
     | 
| 
       10806 
10894 
     | 
    
         
             
                        // expression.
         
     | 
| 
       10807 
     | 
    
         
            -
                        if (
         
     | 
| 
       10808 
     | 
    
         
            -
                            (call->call_operator_loc.start == NULL) &&
         
     | 
| 
       10809 
     | 
    
         
            -
                            (call->message_loc.start != NULL) &&
         
     | 
| 
       10810 
     | 
    
         
            -
                            (call->message_loc.start[0] == '[') &&
         
     | 
| 
       10811 
     | 
    
         
            -
                            (call->message_loc.end[-1] == ']') &&
         
     | 
| 
       10812 
     | 
    
         
            -
                            (call->block == NULL)
         
     | 
| 
       10813 
     | 
    
         
            -
                        ) {
         
     | 
| 
      
 10895 
     | 
    
         
            +
                        if (pm_call_node_index_p(call)) {
         
     | 
| 
       10814 
10896 
     | 
    
         
             
                            if (call->arguments == NULL) {
         
     | 
| 
       10815 
10897 
     | 
    
         
             
                                call->arguments = pm_arguments_node_create(parser);
         
     | 
| 
       10816 
10898 
     | 
    
         
             
                            }
         
     | 
| 
         @@ -10820,6 +10902,7 @@ parse_write(pm_parser_t *parser, pm_node_t *target, pm_token_t *operator, pm_nod 
     | 
|
| 
       10820 
10902 
     | 
    
         | 
| 
       10821 
10903 
     | 
    
         
             
                            // Replace the name with "[]=".
         
     | 
| 
       10822 
10904 
     | 
    
         
             
                            call->name = pm_parser_constant_id_constant(parser, "[]=", 3);
         
     | 
| 
      
 10905 
     | 
    
         
            +
                            pm_node_flag_set((pm_node_t *) call, PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE);
         
     | 
| 
       10823 
10906 
     | 
    
         
             
                            return target;
         
     | 
| 
       10824 
10907 
     | 
    
         
             
                        }
         
     | 
| 
       10825 
10908 
     | 
    
         | 
| 
         @@ -10852,7 +10935,7 @@ parse_write(pm_parser_t *parser, pm_node_t *target, pm_token_t *operator, pm_nod 
     | 
|
| 
       10852 
10935 
     | 
    
         
             
             */
         
     | 
| 
       10853 
10936 
     | 
    
         
             
            static pm_node_t *
         
     | 
| 
       10854 
10937 
     | 
    
         
             
            parse_targets(pm_parser_t *parser, pm_node_t *first_target, pm_binding_power_t binding_power) {
         
     | 
| 
       10855 
     | 
    
         
            -
                bool  
     | 
| 
      
 10938 
     | 
    
         
            +
                bool has_rest = PM_NODE_TYPE_P(first_target, PM_SPLAT_NODE);
         
     | 
| 
       10856 
10939 
     | 
    
         | 
| 
       10857 
10940 
     | 
    
         
             
                pm_multi_target_node_t *result = pm_multi_target_node_create(parser);
         
     | 
| 
       10858 
10941 
     | 
    
         
             
                pm_multi_target_node_targets_append(parser, result, parse_target(parser, first_target));
         
     | 
| 
         @@ -10862,7 +10945,7 @@ parse_targets(pm_parser_t *parser, pm_node_t *first_target, pm_binding_power_t b 
     | 
|
| 
       10862 
10945 
     | 
    
         
             
                        // Here we have a splat operator. It can have a name or be
         
     | 
| 
       10863 
10946 
     | 
    
         
             
                        // anonymous. It can be the final target or be in the middle if
         
     | 
| 
       10864 
10947 
     | 
    
         
             
                        // there haven't been any others yet.
         
     | 
| 
       10865 
     | 
    
         
            -
                        if ( 
     | 
| 
      
 10948 
     | 
    
         
            +
                        if (has_rest) {
         
     | 
| 
       10866 
10949 
     | 
    
         
             
                            pm_parser_err_previous(parser, PM_ERR_MULTI_ASSIGN_MULTI_SPLATS);
         
     | 
| 
       10867 
10950 
     | 
    
         
             
                        }
         
     | 
| 
       10868 
10951 
     | 
    
         | 
| 
         @@ -10870,24 +10953,23 @@ parse_targets(pm_parser_t *parser, pm_node_t *first_target, pm_binding_power_t b 
     | 
|
| 
       10870 
10953 
     | 
    
         
             
                        pm_node_t *name = NULL;
         
     | 
| 
       10871 
10954 
     | 
    
         | 
| 
       10872 
10955 
     | 
    
         
             
                        if (token_begins_expression_p(parser->current.type)) {
         
     | 
| 
       10873 
     | 
    
         
            -
                            name = parse_expression(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_STAR);
         
     | 
| 
      
 10956 
     | 
    
         
            +
                            name = parse_expression(parser, binding_power, false, PM_ERR_EXPECT_EXPRESSION_AFTER_STAR);
         
     | 
| 
       10874 
10957 
     | 
    
         
             
                            name = parse_target(parser, name);
         
     | 
| 
       10875 
10958 
     | 
    
         
             
                        }
         
     | 
| 
       10876 
10959 
     | 
    
         | 
| 
       10877 
10960 
     | 
    
         
             
                        pm_node_t *splat = (pm_node_t *) pm_splat_node_create(parser, &star_operator, name);
         
     | 
| 
       10878 
10961 
     | 
    
         
             
                        pm_multi_target_node_targets_append(parser, result, splat);
         
     | 
| 
       10879 
     | 
    
         
            -
                         
     | 
| 
      
 10962 
     | 
    
         
            +
                        has_rest = true;
         
     | 
| 
       10880 
10963 
     | 
    
         
             
                    } else if (token_begins_expression_p(parser->current.type)) {
         
     | 
| 
       10881 
     | 
    
         
            -
                        pm_node_t *target = parse_expression(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_COMMA);
         
     | 
| 
      
 10964 
     | 
    
         
            +
                        pm_node_t *target = parse_expression(parser, binding_power, false, PM_ERR_EXPECT_EXPRESSION_AFTER_COMMA);
         
     | 
| 
       10882 
10965 
     | 
    
         
             
                        target = parse_target(parser, target);
         
     | 
| 
       10883 
10966 
     | 
    
         | 
| 
       10884 
10967 
     | 
    
         
             
                        pm_multi_target_node_targets_append(parser, result, target);
         
     | 
| 
       10885 
10968 
     | 
    
         
             
                    } else if (!match1(parser, PM_TOKEN_EOF)) {
         
     | 
| 
       10886 
10969 
     | 
    
         
             
                        // If we get here, then we have a trailing , in a multi target node.
         
     | 
| 
       10887 
     | 
    
         
            -
                        // We  
     | 
| 
       10888 
     | 
    
         
            -
                         
     | 
| 
       10889 
     | 
    
         
            -
                         
     | 
| 
       10890 
     | 
    
         
            -
                        pm_multi_target_node_targets_append(parser, result, splat);
         
     | 
| 
      
 10970 
     | 
    
         
            +
                        // We'll set the implicit rest flag to indicate this.
         
     | 
| 
      
 10971 
     | 
    
         
            +
                        pm_node_t *rest = (pm_node_t *) pm_implicit_rest_node_create(parser, &parser->previous);
         
     | 
| 
      
 10972 
     | 
    
         
            +
                        pm_multi_target_node_targets_append(parser, result, rest);
         
     | 
| 
       10891 
10973 
     | 
    
         
             
                        break;
         
     | 
| 
       10892 
10974 
     | 
    
         
             
                    }
         
     | 
| 
       10893 
10975 
     | 
    
         
             
                }
         
     | 
| 
         @@ -10930,7 +11012,7 @@ parse_statements(pm_parser_t *parser, pm_context_t context) { 
     | 
|
| 
       10930 
11012 
     | 
    
         
             
                context_push(parser, context);
         
     | 
| 
       10931 
11013 
     | 
    
         | 
| 
       10932 
11014 
     | 
    
         
             
                while (true) {
         
     | 
| 
       10933 
     | 
    
         
            -
                    pm_node_t *node = parse_expression(parser, PM_BINDING_POWER_STATEMENT, PM_ERR_CANNOT_PARSE_EXPRESSION);
         
     | 
| 
      
 11015 
     | 
    
         
            +
                    pm_node_t *node = parse_expression(parser, PM_BINDING_POWER_STATEMENT, true, PM_ERR_CANNOT_PARSE_EXPRESSION);
         
     | 
| 
       10934 
11016 
     | 
    
         
             
                    pm_statements_node_body_append(statements, node);
         
     | 
| 
       10935 
11017 
     | 
    
         | 
| 
       10936 
11018 
     | 
    
         
             
                    // If we're recovering from a syntax error, then we need to stop parsing the
         
     | 
| 
         @@ -10984,7 +11066,7 @@ parse_statements(pm_parser_t *parser, pm_context_t context) { 
     | 
|
| 
       10984 
11066 
     | 
    
         
             
            }
         
     | 
| 
       10985 
11067 
     | 
    
         | 
| 
       10986 
11068 
     | 
    
         
             
            /**
         
     | 
| 
       10987 
     | 
    
         
            -
             * Parse all of the elements of a hash.  
     | 
| 
      
 11069 
     | 
    
         
            +
             * Parse all of the elements of a hash. returns true if a double splat was found.
         
     | 
| 
       10988 
11070 
     | 
    
         
             
             */
         
     | 
| 
       10989 
11071 
     | 
    
         
             
            static bool
         
     | 
| 
       10990 
11072 
     | 
    
         
             
            parse_assocs(pm_parser_t *parser, pm_node_t *node) {
         
     | 
| 
         @@ -11001,7 +11083,7 @@ parse_assocs(pm_parser_t *parser, pm_node_t *node) { 
     | 
|
| 
       11001 
11083 
     | 
    
         
             
                            pm_node_t *value = NULL;
         
     | 
| 
       11002 
11084 
     | 
    
         | 
| 
       11003 
11085 
     | 
    
         
             
                            if (token_begins_expression_p(parser->current.type)) {
         
     | 
| 
       11004 
     | 
    
         
            -
                                value = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH);
         
     | 
| 
      
 11086 
     | 
    
         
            +
                                value = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH);
         
     | 
| 
       11005 
11087 
     | 
    
         
             
                            } else if (pm_parser_local_depth(parser, &operator) == -1) {
         
     | 
| 
       11006 
11088 
     | 
    
         
             
                                pm_parser_err_token(parser, &operator, PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH);
         
     | 
| 
       11007 
11089 
     | 
    
         
             
                            }
         
     | 
| 
         @@ -11019,9 +11101,9 @@ parse_assocs(pm_parser_t *parser, pm_node_t *node) { 
     | 
|
| 
       11019 
11101 
     | 
    
         
             
                            pm_node_t *value = NULL;
         
     | 
| 
       11020 
11102 
     | 
    
         | 
| 
       11021 
11103 
     | 
    
         
             
                            if (token_begins_expression_p(parser->current.type)) {
         
     | 
| 
       11022 
     | 
    
         
            -
                                value = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_HASH_EXPRESSION_AFTER_LABEL);
         
     | 
| 
      
 11104 
     | 
    
         
            +
                                value = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_HASH_EXPRESSION_AFTER_LABEL);
         
     | 
| 
       11023 
11105 
     | 
    
         
             
                            } else {
         
     | 
| 
       11024 
     | 
    
         
            -
                                if (parser->encoding 
     | 
| 
      
 11106 
     | 
    
         
            +
                                if (parser->encoding->isupper_char(label.start, (label.end - 1) - label.start)) {
         
     | 
| 
       11025 
11107 
     | 
    
         
             
                                    pm_token_t constant = { .type = PM_TOKEN_CONSTANT, .start = label.start, .end = label.end - 1 };
         
     | 
| 
       11026 
11108 
     | 
    
         
             
                                    value = (pm_node_t *) pm_constant_read_node_create(parser, &constant);
         
     | 
| 
       11027 
11109 
     | 
    
         
             
                                } else {
         
     | 
| 
         @@ -11043,7 +11125,7 @@ parse_assocs(pm_parser_t *parser, pm_node_t *node) { 
     | 
|
| 
       11043 
11125 
     | 
    
         
             
                            break;
         
     | 
| 
       11044 
11126 
     | 
    
         
             
                        }
         
     | 
| 
       11045 
11127 
     | 
    
         
             
                        default: {
         
     | 
| 
       11046 
     | 
    
         
            -
                            pm_node_t *key = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_HASH_KEY);
         
     | 
| 
      
 11128 
     | 
    
         
            +
                            pm_node_t *key = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_HASH_KEY);
         
     | 
| 
       11047 
11129 
     | 
    
         
             
                            pm_token_t operator;
         
     | 
| 
       11048 
11130 
     | 
    
         | 
| 
       11049 
11131 
     | 
    
         
             
                            if (pm_symbol_node_label_p(key)) {
         
     | 
| 
         @@ -11053,7 +11135,7 @@ parse_assocs(pm_parser_t *parser, pm_node_t *node) { 
     | 
|
| 
       11053 
11135 
     | 
    
         
             
                                operator = parser->previous;
         
     | 
| 
       11054 
11136 
     | 
    
         
             
                            }
         
     | 
| 
       11055 
11137 
     | 
    
         | 
| 
       11056 
     | 
    
         
            -
                            pm_node_t *value = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_HASH_VALUE);
         
     | 
| 
      
 11138 
     | 
    
         
            +
                            pm_node_t *value = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_HASH_VALUE);
         
     | 
| 
       11057 
11139 
     | 
    
         
             
                            element = (pm_node_t *) pm_assoc_node_create(parser, key, &operator, value);
         
     | 
| 
       11058 
11140 
     | 
    
         
             
                            break;
         
     | 
| 
       11059 
11141 
     | 
    
         
             
                        }
         
     | 
| 
         @@ -11136,15 +11218,11 @@ parse_arguments(pm_parser_t *parser, pm_arguments_t *arguments, bool accepts_for 
     | 
|
| 
       11136 
11218 
     | 
    
         
             
                            pm_keyword_hash_node_t *hash = pm_keyword_hash_node_create(parser);
         
     | 
| 
       11137 
11219 
     | 
    
         
             
                            argument = (pm_node_t *) hash;
         
     | 
| 
       11138 
11220 
     | 
    
         | 
| 
       11139 
     | 
    
         
            -
                            bool contains_keyword_splat =  
     | 
| 
       11140 
     | 
    
         
            -
                            if (!match7(parser, terminator, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON, PM_TOKEN_EOF, PM_TOKEN_BRACE_RIGHT, PM_TOKEN_KEYWORD_DO, PM_TOKEN_PARENTHESIS_RIGHT)) {
         
     | 
| 
       11141 
     | 
    
         
            -
                                contains_keyword_splat = parse_assocs(parser, (pm_node_t *) hash);
         
     | 
| 
       11142 
     | 
    
         
            -
                            }
         
     | 
| 
       11143 
     | 
    
         
            -
             
     | 
| 
      
 11221 
     | 
    
         
            +
                            bool contains_keyword_splat = parse_assocs(parser, (pm_node_t *) hash);
         
     | 
| 
       11144 
11222 
     | 
    
         
             
                            parsed_bare_hash = true;
         
     | 
| 
       11145 
11223 
     | 
    
         
             
                            parse_arguments_append(parser, arguments, argument);
         
     | 
| 
       11146 
11224 
     | 
    
         
             
                            if (contains_keyword_splat) {
         
     | 
| 
       11147 
     | 
    
         
            -
                                arguments->arguments 
     | 
| 
      
 11225 
     | 
    
         
            +
                                pm_node_flag_set((pm_node_t *)arguments->arguments, PM_ARGUMENTS_NODE_FLAGS_CONTAINS_KEYWORD_SPLAT);
         
     | 
| 
       11148 
11226 
     | 
    
         
             
                            }
         
     | 
| 
       11149 
11227 
     | 
    
         
             
                            break;
         
     | 
| 
       11150 
11228 
     | 
    
         
             
                        }
         
     | 
| 
         @@ -11154,9 +11232,15 @@ parse_arguments(pm_parser_t *parser, pm_arguments_t *arguments, bool accepts_for 
     | 
|
| 
       11154 
11232 
     | 
    
         
             
                            pm_node_t *expression = NULL;
         
     | 
| 
       11155 
11233 
     | 
    
         | 
| 
       11156 
11234 
     | 
    
         
             
                            if (token_begins_expression_p(parser->current.type)) {
         
     | 
| 
       11157 
     | 
    
         
            -
                                expression = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_EXPECT_ARGUMENT);
         
     | 
| 
       11158 
     | 
    
         
            -
                            } else  
     | 
| 
       11159 
     | 
    
         
            -
                                 
     | 
| 
      
 11235 
     | 
    
         
            +
                                expression = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_EXPECT_ARGUMENT);
         
     | 
| 
      
 11236 
     | 
    
         
            +
                            } else {
         
     | 
| 
      
 11237 
     | 
    
         
            +
                                if (pm_parser_local_depth(parser, &operator) == -1) {
         
     | 
| 
      
 11238 
     | 
    
         
            +
                                    // A block forwarding in a method having `...` parameter (e.g. `def foo(...); bar(&); end`) is available.
         
     | 
| 
      
 11239 
     | 
    
         
            +
                                    pm_constant_id_t ellipsis_id = pm_parser_constant_id_constant(parser, "...", 3);
         
     | 
| 
      
 11240 
     | 
    
         
            +
                                    if (pm_parser_local_depth_constant_id(parser, ellipsis_id) == -1) {
         
     | 
| 
      
 11241 
     | 
    
         
            +
                                        pm_parser_err_token(parser, &operator, PM_ERR_ARGUMENT_NO_FORWARDING_AMP);
         
     | 
| 
      
 11242 
     | 
    
         
            +
                                    }
         
     | 
| 
      
 11243 
     | 
    
         
            +
                                }
         
     | 
| 
       11160 
11244 
     | 
    
         
             
                            }
         
     | 
| 
       11161 
11245 
     | 
    
         | 
| 
       11162 
11246 
     | 
    
         
             
                            argument = (pm_node_t *) pm_block_argument_node_create(parser, &operator, expression);
         
     | 
| 
         @@ -11173,14 +11257,14 @@ parse_arguments(pm_parser_t *parser, pm_arguments_t *arguments, bool accepts_for 
     | 
|
| 
       11173 
11257 
     | 
    
         
             
                            parser_lex(parser);
         
     | 
| 
       11174 
11258 
     | 
    
         
             
                            pm_token_t operator = parser->previous;
         
     | 
| 
       11175 
11259 
     | 
    
         | 
| 
       11176 
     | 
    
         
            -
                            if ( 
     | 
| 
      
 11260 
     | 
    
         
            +
                            if (match4(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_TOKEN_COMMA, PM_TOKEN_SEMICOLON, PM_TOKEN_BRACKET_RIGHT)) {
         
     | 
| 
       11177 
11261 
     | 
    
         
             
                                if (pm_parser_local_depth(parser, &parser->previous) == -1) {
         
     | 
| 
       11178 
11262 
     | 
    
         
             
                                    pm_parser_err_token(parser, &operator, PM_ERR_ARGUMENT_NO_FORWARDING_STAR);
         
     | 
| 
       11179 
11263 
     | 
    
         
             
                                }
         
     | 
| 
       11180 
11264 
     | 
    
         | 
| 
       11181 
11265 
     | 
    
         
             
                                argument = (pm_node_t *) pm_splat_node_create(parser, &operator, NULL);
         
     | 
| 
       11182 
11266 
     | 
    
         
             
                            } else {
         
     | 
| 
       11183 
     | 
    
         
            -
                                pm_node_t *expression = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT);
         
     | 
| 
      
 11267 
     | 
    
         
            +
                                pm_node_t *expression = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT);
         
     | 
| 
       11184 
11268 
     | 
    
         | 
| 
       11185 
11269 
     | 
    
         
             
                                if (parsed_bare_hash) {
         
     | 
| 
       11186 
11270 
     | 
    
         
             
                                    pm_parser_err(parser, operator.start, expression->location.end, PM_ERR_ARGUMENT_SPLAT_AFTER_ASSOC_SPLAT);
         
     | 
| 
         @@ -11200,7 +11284,7 @@ parse_arguments(pm_parser_t *parser, pm_arguments_t *arguments, bool accepts_for 
     | 
|
| 
       11200 
11284 
     | 
    
         
             
                                    // If the token begins an expression then this ... was not actually
         
     | 
| 
       11201 
11285 
     | 
    
         
             
                                    // argument forwarding but was instead a range.
         
     | 
| 
       11202 
11286 
     | 
    
         
             
                                    pm_token_t operator = parser->previous;
         
     | 
| 
       11203 
     | 
    
         
            -
                                    pm_node_t *right = parse_expression(parser, PM_BINDING_POWER_RANGE, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
         
     | 
| 
      
 11287 
     | 
    
         
            +
                                    pm_node_t *right = parse_expression(parser, PM_BINDING_POWER_RANGE, false, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
         
     | 
| 
       11204 
11288 
     | 
    
         
             
                                    argument = (pm_node_t *) pm_range_node_create(parser, NULL, &operator, right);
         
     | 
| 
       11205 
11289 
     | 
    
         
             
                                } else {
         
     | 
| 
       11206 
11290 
     | 
    
         
             
                                    if (pm_parser_local_depth(parser, &parser->previous) == -1) {
         
     | 
| 
         @@ -11220,7 +11304,7 @@ parse_arguments(pm_parser_t *parser, pm_arguments_t *arguments, bool accepts_for 
     | 
|
| 
       11220 
11304 
     | 
    
         
             
                        /* fallthrough */
         
     | 
| 
       11221 
11305 
     | 
    
         
             
                        default: {
         
     | 
| 
       11222 
11306 
     | 
    
         
             
                            if (argument == NULL) {
         
     | 
| 
       11223 
     | 
    
         
            -
                                argument = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_EXPECT_ARGUMENT);
         
     | 
| 
      
 11307 
     | 
    
         
            +
                                argument = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, !parsed_first_argument, PM_ERR_EXPECT_ARGUMENT);
         
     | 
| 
       11224 
11308 
     | 
    
         
             
                            }
         
     | 
| 
       11225 
11309 
     | 
    
         | 
| 
       11226 
11310 
     | 
    
         
             
                            bool contains_keyword_splat = false;
         
     | 
| 
         @@ -11239,7 +11323,7 @@ parse_arguments(pm_parser_t *parser, pm_arguments_t *arguments, bool accepts_for 
     | 
|
| 
       11239 
11323 
     | 
    
         
             
                                pm_keyword_hash_node_t *bare_hash = pm_keyword_hash_node_create(parser);
         
     | 
| 
       11240 
11324 
     | 
    
         | 
| 
       11241 
11325 
     | 
    
         
             
                                // Finish parsing the one we are part way through
         
     | 
| 
       11242 
     | 
    
         
            -
                                pm_node_t *value = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_HASH_VALUE);
         
     | 
| 
      
 11326 
     | 
    
         
            +
                                pm_node_t *value = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_HASH_VALUE);
         
     | 
| 
       11243 
11327 
     | 
    
         | 
| 
       11244 
11328 
     | 
    
         
             
                                argument = (pm_node_t *) pm_assoc_node_create(parser, argument, &operator, value);
         
     | 
| 
       11245 
11329 
     | 
    
         
             
                                pm_keyword_hash_node_elements_append(bare_hash, argument);
         
     | 
| 
         @@ -11258,7 +11342,7 @@ parse_arguments(pm_parser_t *parser, pm_arguments_t *arguments, bool accepts_for 
     | 
|
| 
       11258 
11342 
     | 
    
         | 
| 
       11259 
11343 
     | 
    
         
             
                            parse_arguments_append(parser, arguments, argument);
         
     | 
| 
       11260 
11344 
     | 
    
         
             
                            if (contains_keyword_splat) {
         
     | 
| 
       11261 
     | 
    
         
            -
                                arguments->arguments 
     | 
| 
      
 11345 
     | 
    
         
            +
                                pm_node_flag_set((pm_node_t *)arguments->arguments, PM_ARGUMENTS_NODE_FLAGS_CONTAINS_KEYWORD_SPLAT);
         
     | 
| 
       11262 
11346 
     | 
    
         
             
                            }
         
     | 
| 
       11263 
11347 
     | 
    
         
             
                            break;
         
     | 
| 
       11264 
11348 
     | 
    
         
             
                        }
         
     | 
| 
         @@ -11310,11 +11394,14 @@ parse_required_destructured_parameter(pm_parser_t *parser) { 
     | 
|
| 
       11310 
11394 
     | 
    
         
             
                do {
         
     | 
| 
       11311 
11395 
     | 
    
         
             
                    pm_node_t *param;
         
     | 
| 
       11312 
11396 
     | 
    
         | 
| 
       11313 
     | 
    
         
            -
                    // If we get here then we have a trailing comma 
     | 
| 
       11314 
     | 
    
         
            -
                    //  
     | 
| 
      
 11397 
     | 
    
         
            +
                    // If we get here then we have a trailing comma, which isn't allowed in
         
     | 
| 
      
 11398 
     | 
    
         
            +
                    // the grammar. In other places, multi targets _do_ allow trailing
         
     | 
| 
      
 11399 
     | 
    
         
            +
                    // commas, so here we'll assume this is a mistake of the user not
         
     | 
| 
      
 11400 
     | 
    
         
            +
                    // knowing it's not allowed here.
         
     | 
| 
       11315 
11401 
     | 
    
         
             
                    if (node->lefts.size > 0 && match1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) {
         
     | 
| 
       11316 
     | 
    
         
            -
                        param = (pm_node_t *)  
     | 
| 
      
 11402 
     | 
    
         
            +
                        param = (pm_node_t *) pm_implicit_rest_node_create(parser, &parser->previous);
         
     | 
| 
       11317 
11403 
     | 
    
         
             
                        pm_multi_target_node_targets_append(parser, node, param);
         
     | 
| 
      
 11404 
     | 
    
         
            +
                        pm_parser_err_current(parser, PM_ERR_PARAMETER_WILD_LOOSE_COMMA);
         
     | 
| 
       11318 
11405 
     | 
    
         
             
                        break;
         
     | 
| 
       11319 
11406 
     | 
    
         
             
                    }
         
     | 
| 
       11320 
11407 
     | 
    
         | 
| 
         @@ -11545,10 +11632,14 @@ parse_parameters( 
     | 
|
| 
       11545 
11632 
     | 
    
         
             
                            if (accept1(parser, PM_TOKEN_EQUAL)) {
         
     | 
| 
       11546 
11633 
     | 
    
         
             
                                pm_token_t operator = parser->previous;
         
     | 
| 
       11547 
11634 
     | 
    
         
             
                                context_push(parser, PM_CONTEXT_DEFAULT_PARAMS);
         
     | 
| 
       11548 
     | 
    
         
            -
                                 
     | 
| 
      
 11635 
     | 
    
         
            +
                                pm_constant_id_t old_param_name = parser->current_param_name;
         
     | 
| 
      
 11636 
     | 
    
         
            +
                                parser->current_param_name = pm_parser_constant_id_token(parser, &name);
         
     | 
| 
      
 11637 
     | 
    
         
            +
                                pm_node_t *value = parse_value_expression(parser, binding_power, false, PM_ERR_PARAMETER_NO_DEFAULT);
         
     | 
| 
       11549 
11638 
     | 
    
         | 
| 
       11550 
11639 
     | 
    
         
             
                                pm_optional_parameter_node_t *param = pm_optional_parameter_node_create(parser, &name, &operator, value);
         
     | 
| 
       11551 
11640 
     | 
    
         
             
                                pm_parameters_node_optionals_append(params, param);
         
     | 
| 
      
 11641 
     | 
    
         
            +
             
     | 
| 
      
 11642 
     | 
    
         
            +
                                parser->current_param_name = old_param_name;
         
     | 
| 
       11552 
11643 
     | 
    
         
             
                                context_pop(parser);
         
     | 
| 
       11553 
11644 
     | 
    
         | 
| 
       11554 
11645 
     | 
    
         
             
                                // If parsing the value of the parameter resulted in error recovery,
         
     | 
| 
         @@ -11604,7 +11695,10 @@ parse_parameters( 
     | 
|
| 
       11604 
11695 
     | 
    
         | 
| 
       11605 
11696 
     | 
    
         
             
                                    if (token_begins_expression_p(parser->current.type)) {
         
     | 
| 
       11606 
11697 
     | 
    
         
             
                                        context_push(parser, PM_CONTEXT_DEFAULT_PARAMS);
         
     | 
| 
       11607 
     | 
    
         
            -
                                         
     | 
| 
      
 11698 
     | 
    
         
            +
                                        pm_constant_id_t old_param_name = parser->current_param_name;
         
     | 
| 
      
 11699 
     | 
    
         
            +
                                        parser->current_param_name = pm_parser_constant_id_token(parser, &local);
         
     | 
| 
      
 11700 
     | 
    
         
            +
                                        pm_node_t *value = parse_value_expression(parser, binding_power, false, PM_ERR_PARAMETER_NO_DEFAULT_KW);
         
     | 
| 
      
 11701 
     | 
    
         
            +
                                        parser->current_param_name = old_param_name;
         
     | 
| 
       11608 
11702 
     | 
    
         
             
                                        context_pop(parser);
         
     | 
| 
       11609 
11703 
     | 
    
         
             
                                        param = (pm_node_t *) pm_optional_keyword_parameter_node_create(parser, &name, value);
         
     | 
| 
       11610 
11704 
     | 
    
         
             
                                    }
         
     | 
| 
         @@ -11647,12 +11741,12 @@ parse_parameters( 
     | 
|
| 
       11647 
11741 
     | 
    
         
             
                                }
         
     | 
| 
       11648 
11742 
     | 
    
         
             
                            }
         
     | 
| 
       11649 
11743 
     | 
    
         | 
| 
       11650 
     | 
    
         
            -
                             
     | 
| 
      
 11744 
     | 
    
         
            +
                            pm_node_t *param = (pm_node_t *) pm_rest_parameter_node_create(parser, &operator, &name);
         
     | 
| 
       11651 
11745 
     | 
    
         
             
                            if (params->rest == NULL) {
         
     | 
| 
       11652 
11746 
     | 
    
         
             
                                pm_parameters_node_rest_set(params, param);
         
     | 
| 
       11653 
11747 
     | 
    
         
             
                            } else {
         
     | 
| 
       11654 
     | 
    
         
            -
                                pm_parser_err_node(parser,  
     | 
| 
       11655 
     | 
    
         
            -
                                pm_parameters_node_posts_append(params,  
     | 
| 
      
 11748 
     | 
    
         
            +
                                pm_parser_err_node(parser, param, PM_ERR_PARAMETER_SPLAT_MULTI);
         
     | 
| 
      
 11749 
     | 
    
         
            +
                                pm_parameters_node_posts_append(params, param);
         
     | 
| 
       11656 
11750 
     | 
    
         
             
                            }
         
     | 
| 
       11657 
11751 
     | 
    
         | 
| 
       11658 
11752 
     | 
    
         
             
                            break;
         
     | 
| 
         @@ -11697,11 +11791,9 @@ parse_parameters( 
     | 
|
| 
       11697 
11791 
     | 
    
         
             
                        default:
         
     | 
| 
       11698 
11792 
     | 
    
         
             
                            if (parser->previous.type == PM_TOKEN_COMMA) {
         
     | 
| 
       11699 
11793 
     | 
    
         
             
                                if (allows_trailing_comma) {
         
     | 
| 
       11700 
     | 
    
         
            -
                                    // If we get here, then we have a trailing comma in a 
     | 
| 
       11701 
     | 
    
         
            -
                                    // parameter list. 
     | 
| 
       11702 
     | 
    
         
            -
                                     
     | 
| 
       11703 
     | 
    
         
            -
                                    pm_token_t name = not_provided(parser);
         
     | 
| 
       11704 
     | 
    
         
            -
                                    pm_rest_parameter_node_t *param = pm_rest_parameter_node_create(parser, &parser->previous, &name);
         
     | 
| 
      
 11794 
     | 
    
         
            +
                                    // If we get here, then we have a trailing comma in a
         
     | 
| 
      
 11795 
     | 
    
         
            +
                                    // block parameter list.
         
     | 
| 
      
 11796 
     | 
    
         
            +
                                    pm_node_t *param = (pm_node_t *) pm_implicit_rest_node_create(parser, &parser->previous);
         
     | 
| 
       11705 
11797 
     | 
    
         | 
| 
       11706 
11798 
     | 
    
         
             
                                    if (params->rest == NULL) {
         
     | 
| 
       11707 
11799 
     | 
    
         
             
                                        pm_parameters_node_rest_set(params, param);
         
     | 
| 
         @@ -11739,7 +11831,7 @@ parse_parameters( 
     | 
|
| 
       11739 
11831 
     | 
    
         
             
             * nodes pointing to each other from the top.
         
     | 
| 
       11740 
11832 
     | 
    
         
             
             */
         
     | 
| 
       11741 
11833 
     | 
    
         
             
            static inline void
         
     | 
| 
       11742 
     | 
    
         
            -
            parse_rescues(pm_parser_t *parser, pm_begin_node_t *parent_node) {
         
     | 
| 
      
 11834 
     | 
    
         
            +
            parse_rescues(pm_parser_t *parser, pm_begin_node_t *parent_node, bool def_p) {
         
     | 
| 
       11743 
11835 
     | 
    
         
             
                pm_rescue_node_t *current = NULL;
         
     | 
| 
       11744 
11836 
     | 
    
         | 
| 
       11745 
11837 
     | 
    
         
             
                while (accept1(parser, PM_TOKEN_KEYWORD_RESCUE)) {
         
     | 
| 
         @@ -11753,7 +11845,7 @@ parse_rescues(pm_parser_t *parser, pm_begin_node_t *parent_node) { 
     | 
|
| 
       11753 
11845 
     | 
    
         
             
                            parser_lex(parser);
         
     | 
| 
       11754 
11846 
     | 
    
         
             
                            pm_rescue_node_operator_set(rescue, &parser->previous);
         
     | 
| 
       11755 
11847 
     | 
    
         | 
| 
       11756 
     | 
    
         
            -
                            pm_node_t *reference = parse_expression(parser, PM_BINDING_POWER_INDEX, PM_ERR_RESCUE_VARIABLE);
         
     | 
| 
      
 11848 
     | 
    
         
            +
                            pm_node_t *reference = parse_expression(parser, PM_BINDING_POWER_INDEX, false, PM_ERR_RESCUE_VARIABLE);
         
     | 
| 
       11757 
11849 
     | 
    
         
             
                            reference = parse_target(parser, reference);
         
     | 
| 
       11758 
11850 
     | 
    
         | 
| 
       11759 
11851 
     | 
    
         
             
                            pm_rescue_node_reference_set(rescue, reference);
         
     | 
| 
         @@ -11771,7 +11863,7 @@ parse_rescues(pm_parser_t *parser, pm_begin_node_t *parent_node) { 
     | 
|
| 
       11771 
11863 
     | 
    
         
             
                                // we'll attempt to parse it here and any others delimited by commas.
         
     | 
| 
       11772 
11864 
     | 
    
         | 
| 
       11773 
11865 
     | 
    
         
             
                                do {
         
     | 
| 
       11774 
     | 
    
         
            -
                                    pm_node_t *expression = parse_starred_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_RESCUE_EXPRESSION);
         
     | 
| 
      
 11866 
     | 
    
         
            +
                                    pm_node_t *expression = parse_starred_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_RESCUE_EXPRESSION);
         
     | 
| 
       11775 
11867 
     | 
    
         
             
                                    pm_rescue_node_exceptions_append(rescue, expression);
         
     | 
| 
       11776 
11868 
     | 
    
         | 
| 
       11777 
11869 
     | 
    
         
             
                                    // If we hit a newline, then this is the end of the rescue expression. We
         
     | 
| 
         @@ -11783,7 +11875,7 @@ parse_rescues(pm_parser_t *parser, pm_begin_node_t *parent_node) { 
     | 
|
| 
       11783 
11875 
     | 
    
         
             
                                    if (accept1(parser, PM_TOKEN_EQUAL_GREATER)) {
         
     | 
| 
       11784 
11876 
     | 
    
         
             
                                        pm_rescue_node_operator_set(rescue, &parser->previous);
         
     | 
| 
       11785 
11877 
     | 
    
         | 
| 
       11786 
     | 
    
         
            -
                                        pm_node_t *reference = parse_expression(parser, PM_BINDING_POWER_INDEX, PM_ERR_RESCUE_VARIABLE);
         
     | 
| 
      
 11878 
     | 
    
         
            +
                                        pm_node_t *reference = parse_expression(parser, PM_BINDING_POWER_INDEX, false, PM_ERR_RESCUE_VARIABLE);
         
     | 
| 
       11787 
11879 
     | 
    
         
             
                                        reference = parse_target(parser, reference);
         
     | 
| 
       11788 
11880 
     | 
    
         | 
| 
       11789 
11881 
     | 
    
         
             
                                        pm_rescue_node_reference_set(rescue, reference);
         
     | 
| 
         @@ -11802,7 +11894,7 @@ parse_rescues(pm_parser_t *parser, pm_begin_node_t *parent_node) { 
     | 
|
| 
       11802 
11894 
     | 
    
         | 
| 
       11803 
11895 
     | 
    
         
             
                    if (!match3(parser, PM_TOKEN_KEYWORD_ELSE, PM_TOKEN_KEYWORD_ENSURE, PM_TOKEN_KEYWORD_END)) {
         
     | 
| 
       11804 
11896 
     | 
    
         
             
                        pm_accepts_block_stack_push(parser, true);
         
     | 
| 
       11805 
     | 
    
         
            -
                        pm_statements_node_t *statements = parse_statements(parser, PM_CONTEXT_RESCUE);
         
     | 
| 
      
 11897 
     | 
    
         
            +
                        pm_statements_node_t *statements = parse_statements(parser, def_p ? PM_CONTEXT_RESCUE_DEF : PM_CONTEXT_RESCUE);
         
     | 
| 
       11806 
11898 
     | 
    
         
             
                        if (statements) {
         
     | 
| 
       11807 
11899 
     | 
    
         
             
                            pm_rescue_node_statements_set(rescue, statements);
         
     | 
| 
       11808 
11900 
     | 
    
         
             
                        }
         
     | 
| 
         @@ -11838,7 +11930,7 @@ parse_rescues(pm_parser_t *parser, pm_begin_node_t *parent_node) { 
     | 
|
| 
       11838 
11930 
     | 
    
         
             
                    pm_statements_node_t *else_statements = NULL;
         
     | 
| 
       11839 
11931 
     | 
    
         
             
                    if (!match2(parser, PM_TOKEN_KEYWORD_END, PM_TOKEN_KEYWORD_ENSURE)) {
         
     | 
| 
       11840 
11932 
     | 
    
         
             
                        pm_accepts_block_stack_push(parser, true);
         
     | 
| 
       11841 
     | 
    
         
            -
                        else_statements = parse_statements(parser, PM_CONTEXT_RESCUE_ELSE);
         
     | 
| 
      
 11933 
     | 
    
         
            +
                        else_statements = parse_statements(parser, def_p ? PM_CONTEXT_RESCUE_ELSE_DEF : PM_CONTEXT_RESCUE_ELSE);
         
     | 
| 
       11842 
11934 
     | 
    
         
             
                        pm_accepts_block_stack_pop(parser);
         
     | 
| 
       11843 
11935 
     | 
    
         
             
                        accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON);
         
     | 
| 
       11844 
11936 
     | 
    
         
             
                    }
         
     | 
| 
         @@ -11854,7 +11946,7 @@ parse_rescues(pm_parser_t *parser, pm_begin_node_t *parent_node) { 
     | 
|
| 
       11854 
11946 
     | 
    
         
             
                    pm_statements_node_t *ensure_statements = NULL;
         
     | 
| 
       11855 
11947 
     | 
    
         
             
                    if (!match1(parser, PM_TOKEN_KEYWORD_END)) {
         
     | 
| 
       11856 
11948 
     | 
    
         
             
                        pm_accepts_block_stack_push(parser, true);
         
     | 
| 
       11857 
     | 
    
         
            -
                        ensure_statements = parse_statements(parser, PM_CONTEXT_ENSURE);
         
     | 
| 
      
 11949 
     | 
    
         
            +
                        ensure_statements = parse_statements(parser, def_p ? PM_CONTEXT_ENSURE_DEF : PM_CONTEXT_ENSURE);
         
     | 
| 
       11858 
11950 
     | 
    
         
             
                        pm_accepts_block_stack_pop(parser);
         
     | 
| 
       11859 
11951 
     | 
    
         
             
                        accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON);
         
     | 
| 
       11860 
11952 
     | 
    
         
             
                    }
         
     | 
| 
         @@ -11872,10 +11964,10 @@ parse_rescues(pm_parser_t *parser, pm_begin_node_t *parent_node) { 
     | 
|
| 
       11872 
11964 
     | 
    
         
             
            }
         
     | 
| 
       11873 
11965 
     | 
    
         | 
| 
       11874 
11966 
     | 
    
         
             
            static inline pm_begin_node_t *
         
     | 
| 
       11875 
     | 
    
         
            -
            parse_rescues_as_begin(pm_parser_t *parser, pm_statements_node_t *statements) {
         
     | 
| 
      
 11967 
     | 
    
         
            +
            parse_rescues_as_begin(pm_parser_t *parser, pm_statements_node_t *statements, bool def_p) {
         
     | 
| 
       11876 
11968 
     | 
    
         
             
                pm_token_t no_begin_token = not_provided(parser);
         
     | 
| 
       11877 
11969 
     | 
    
         
             
                pm_begin_node_t *begin_node = pm_begin_node_create(parser, &no_begin_token, statements);
         
     | 
| 
       11878 
     | 
    
         
            -
                parse_rescues(parser, begin_node);
         
     | 
| 
      
 11970 
     | 
    
         
            +
                parse_rescues(parser, begin_node, def_p);
         
     | 
| 
       11879 
11971 
     | 
    
         | 
| 
       11880 
11972 
     | 
    
         
             
                // All nodes within a begin node are optional, so we look
         
     | 
| 
       11881 
11973 
     | 
    
         
             
                // for the earliest possible node that we can use to set
         
     | 
| 
         @@ -11941,24 +12033,30 @@ parse_block(pm_parser_t *parser) { 
     | 
|
| 
       11941 
12033 
     | 
    
         | 
| 
       11942 
12034 
     | 
    
         
             
                pm_accepts_block_stack_push(parser, true);
         
     | 
| 
       11943 
12035 
     | 
    
         
             
                pm_parser_scope_push(parser, false);
         
     | 
| 
       11944 
     | 
    
         
            -
                pm_block_parameters_node_t * 
     | 
| 
      
 12036 
     | 
    
         
            +
                pm_block_parameters_node_t *block_parameters = NULL;
         
     | 
| 
       11945 
12037 
     | 
    
         | 
| 
       11946 
12038 
     | 
    
         
             
                if (accept1(parser, PM_TOKEN_PIPE)) {
         
     | 
| 
       11947 
12039 
     | 
    
         
             
                    parser->current_scope->explicit_params = true;
         
     | 
| 
       11948 
12040 
     | 
    
         
             
                    pm_token_t block_parameters_opening = parser->previous;
         
     | 
| 
       11949 
12041 
     | 
    
         | 
| 
       11950 
12042 
     | 
    
         
             
                    if (match1(parser, PM_TOKEN_PIPE)) {
         
     | 
| 
       11951 
     | 
    
         
            -
                         
     | 
| 
      
 12043 
     | 
    
         
            +
                        block_parameters = pm_block_parameters_node_create(parser, NULL, &block_parameters_opening);
         
     | 
| 
       11952 
12044 
     | 
    
         
             
                        parser->command_start = true;
         
     | 
| 
       11953 
12045 
     | 
    
         
             
                        parser_lex(parser);
         
     | 
| 
       11954 
12046 
     | 
    
         
             
                    } else {
         
     | 
| 
       11955 
     | 
    
         
            -
                         
     | 
| 
      
 12047 
     | 
    
         
            +
                        block_parameters = parse_block_parameters(parser, true, &block_parameters_opening, false);
         
     | 
| 
       11956 
12048 
     | 
    
         
             
                        accept1(parser, PM_TOKEN_NEWLINE);
         
     | 
| 
       11957 
12049 
     | 
    
         
             
                        parser->command_start = true;
         
     | 
| 
       11958 
12050 
     | 
    
         
             
                        expect1(parser, PM_TOKEN_PIPE, PM_ERR_BLOCK_PARAM_PIPE_TERM);
         
     | 
| 
       11959 
12051 
     | 
    
         
             
                    }
         
     | 
| 
       11960 
12052 
     | 
    
         | 
| 
       11961 
     | 
    
         
            -
                    pm_block_parameters_node_closing_set( 
     | 
| 
      
 12053 
     | 
    
         
            +
                    pm_block_parameters_node_closing_set(block_parameters, &parser->previous);
         
     | 
| 
      
 12054 
     | 
    
         
            +
                }
         
     | 
| 
      
 12055 
     | 
    
         
            +
             
     | 
| 
      
 12056 
     | 
    
         
            +
                uint32_t locals_body_index = 0;
         
     | 
| 
      
 12057 
     | 
    
         
            +
             
     | 
| 
      
 12058 
     | 
    
         
            +
                if (block_parameters) {
         
     | 
| 
      
 12059 
     | 
    
         
            +
                    locals_body_index = (uint32_t) parser->current_scope->locals.size;
         
     | 
| 
       11962 
12060 
     | 
    
         
             
                }
         
     | 
| 
       11963 
12061 
     | 
    
         | 
| 
       11964 
12062 
     | 
    
         
             
                accept1(parser, PM_TOKEN_NEWLINE);
         
     | 
| 
         @@ -11980,17 +12078,25 @@ parse_block(pm_parser_t *parser) { 
     | 
|
| 
       11980 
12078 
     | 
    
         | 
| 
       11981 
12079 
     | 
    
         
             
                        if (match2(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) {
         
     | 
| 
       11982 
12080 
     | 
    
         
             
                            assert(statements == NULL || PM_NODE_TYPE_P(statements, PM_STATEMENTS_NODE));
         
     | 
| 
       11983 
     | 
    
         
            -
                            statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements);
         
     | 
| 
      
 12081 
     | 
    
         
            +
                            statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements, false);
         
     | 
| 
       11984 
12082 
     | 
    
         
             
                        }
         
     | 
| 
       11985 
12083 
     | 
    
         
             
                    }
         
     | 
| 
       11986 
12084 
     | 
    
         | 
| 
       11987 
12085 
     | 
    
         
             
                    expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_BLOCK_TERM_END);
         
     | 
| 
       11988 
12086 
     | 
    
         
             
                }
         
     | 
| 
       11989 
12087 
     | 
    
         | 
| 
      
 12088 
     | 
    
         
            +
                pm_node_t *parameters = (pm_node_t *) block_parameters;
         
     | 
| 
      
 12089 
     | 
    
         
            +
                uint8_t maximum = parser->current_scope->numbered_parameters;
         
     | 
| 
      
 12090 
     | 
    
         
            +
             
     | 
| 
      
 12091 
     | 
    
         
            +
                if (parameters == NULL && (maximum > 0)) {
         
     | 
| 
      
 12092 
     | 
    
         
            +
                    parameters = (pm_node_t *) pm_numbered_parameters_node_create(parser, &(pm_location_t) { .start = opening.start, .end = parser->previous.end }, maximum);
         
     | 
| 
      
 12093 
     | 
    
         
            +
                    locals_body_index = maximum;
         
     | 
| 
      
 12094 
     | 
    
         
            +
                }
         
     | 
| 
      
 12095 
     | 
    
         
            +
             
     | 
| 
       11990 
12096 
     | 
    
         
             
                pm_constant_id_list_t locals = parser->current_scope->locals;
         
     | 
| 
       11991 
12097 
     | 
    
         
             
                pm_parser_scope_pop(parser);
         
     | 
| 
       11992 
12098 
     | 
    
         
             
                pm_accepts_block_stack_pop(parser);
         
     | 
| 
       11993 
     | 
    
         
            -
                return pm_block_node_create(parser, &locals, &opening, parameters, statements, &parser->previous);
         
     | 
| 
      
 12099 
     | 
    
         
            +
                return pm_block_node_create(parser, &locals, locals_body_index, &opening, parameters, statements, &parser->previous);
         
     | 
| 
       11994 
12100 
     | 
    
         
             
            }
         
     | 
| 
       11995 
12101 
     | 
    
         | 
| 
       11996 
12102 
     | 
    
         
             
            /**
         
     | 
| 
         @@ -11999,7 +12105,7 @@ parse_block(pm_parser_t *parser) { 
     | 
|
| 
       11999 
12105 
     | 
    
         
             
             * arguments, or blocks).
         
     | 
| 
       12000 
12106 
     | 
    
         
             
             */
         
     | 
| 
       12001 
12107 
     | 
    
         
             
            static bool
         
     | 
| 
       12002 
     | 
    
         
            -
            parse_arguments_list(pm_parser_t *parser, pm_arguments_t *arguments, bool accepts_block) {
         
     | 
| 
      
 12108 
     | 
    
         
            +
            parse_arguments_list(pm_parser_t *parser, pm_arguments_t *arguments, bool accepts_block, bool accepts_command_call) {
         
     | 
| 
       12003 
12109 
     | 
    
         
             
                bool found = false;
         
     | 
| 
       12004 
12110 
     | 
    
         | 
| 
       12005 
12111 
     | 
    
         
             
                if (accept1(parser, PM_TOKEN_PARENTHESIS_LEFT)) {
         
     | 
| 
         @@ -12016,7 +12122,7 @@ parse_arguments_list(pm_parser_t *parser, pm_arguments_t *arguments, bool accept 
     | 
|
| 
       12016 
12122 
     | 
    
         | 
| 
       12017 
12123 
     | 
    
         
             
                        arguments->closing_loc = PM_LOCATION_TOKEN_VALUE(&parser->previous);
         
     | 
| 
       12018 
12124 
     | 
    
         
             
                    }
         
     | 
| 
       12019 
     | 
    
         
            -
                } else if ((token_begins_expression_p(parser->current.type) || match3(parser, PM_TOKEN_USTAR, PM_TOKEN_USTAR_STAR, PM_TOKEN_UAMPERSAND)) && !match1(parser, PM_TOKEN_BRACE_LEFT)) {
         
     | 
| 
      
 12125 
     | 
    
         
            +
                } else if (accepts_command_call && (token_begins_expression_p(parser->current.type) || match3(parser, PM_TOKEN_USTAR, PM_TOKEN_USTAR_STAR, PM_TOKEN_UAMPERSAND)) && !match1(parser, PM_TOKEN_BRACE_LEFT)) {
         
     | 
| 
       12020 
12126 
     | 
    
         
             
                    found |= true;
         
     | 
| 
       12021 
12127 
     | 
    
         
             
                    pm_accepts_block_stack_push(parser, false);
         
     | 
| 
       12022 
12128 
     | 
    
         | 
| 
         @@ -12071,7 +12177,7 @@ static inline pm_node_t * 
     | 
|
| 
       12071 
12177 
     | 
    
         
             
            parse_predicate(pm_parser_t *parser, pm_binding_power_t binding_power, pm_context_t context, pm_token_t *then_keyword) {
         
     | 
| 
       12072 
12178 
     | 
    
         
             
                context_push(parser, PM_CONTEXT_PREDICATE);
         
     | 
| 
       12073 
12179 
     | 
    
         
             
                pm_diagnostic_id_t error_id = context == PM_CONTEXT_IF ? PM_ERR_CONDITIONAL_IF_PREDICATE : PM_ERR_CONDITIONAL_UNLESS_PREDICATE;
         
     | 
| 
       12074 
     | 
    
         
            -
                pm_node_t *predicate = parse_value_expression(parser, binding_power, error_id);
         
     | 
| 
      
 12180 
     | 
    
         
            +
                pm_node_t *predicate = parse_value_expression(parser, binding_power, true, error_id);
         
     | 
| 
       12075 
12181 
     | 
    
         | 
| 
       12076 
12182 
     | 
    
         
             
                // Predicates are closed by a term, a "then", or a term and then a "then".
         
     | 
| 
       12077 
12183 
     | 
    
         
             
                bool predicate_closed = accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON);
         
     | 
| 
         @@ -12266,6 +12372,26 @@ parse_conditional(pm_parser_t *parser, pm_context_t context) { 
     | 
|
| 
       12266 
12372 
     | 
    
         
             
                case PM_INSTANCE_VARIABLE_READ_NODE: case PM_MULTI_TARGET_NODE: case PM_BACK_REFERENCE_READ_NODE: \
         
     | 
| 
       12267 
12373 
     | 
    
         
             
                case PM_NUMBERED_REFERENCE_READ_NODE
         
     | 
| 
       12268 
12374 
     | 
    
         | 
| 
      
 12375 
     | 
    
         
            +
            // Assert here that the flags are the same so that we can safely switch the type
         
     | 
| 
      
 12376 
     | 
    
         
            +
            // of the node without having to move the flags.
         
     | 
| 
      
 12377 
     | 
    
         
            +
            PM_STATIC_ASSERT(__LINE__, ((int) PM_STRING_FLAGS_FORCED_UTF8_ENCODING) == ((int) PM_ENCODING_FLAGS_FORCED_UTF8_ENCODING), "Expected the flags to match.");
         
     | 
| 
      
 12378 
     | 
    
         
            +
             
     | 
| 
      
 12379 
     | 
    
         
            +
            /**
         
     | 
| 
      
 12380 
     | 
    
         
            +
             * If the encoding was explicitly set through the lexing process, then we need
         
     | 
| 
      
 12381 
     | 
    
         
            +
             * to potentially mark the string's flags to indicate how to encode it.
         
     | 
| 
      
 12382 
     | 
    
         
            +
             */
         
     | 
| 
      
 12383 
     | 
    
         
            +
            static inline pm_node_flags_t
         
     | 
| 
      
 12384 
     | 
    
         
            +
            parse_unescaped_encoding(const pm_parser_t *parser) {
         
     | 
| 
      
 12385 
     | 
    
         
            +
                if (parser->explicit_encoding != NULL) {
         
     | 
| 
      
 12386 
     | 
    
         
            +
                    if (parser->explicit_encoding == PM_ENCODING_UTF_8_ENTRY) {
         
     | 
| 
      
 12387 
     | 
    
         
            +
                        return PM_STRING_FLAGS_FORCED_UTF8_ENCODING;
         
     | 
| 
      
 12388 
     | 
    
         
            +
                    } else if (parser->encoding == PM_ENCODING_US_ASCII_ENTRY) {
         
     | 
| 
      
 12389 
     | 
    
         
            +
                        return PM_STRING_FLAGS_FORCED_BINARY_ENCODING;
         
     | 
| 
      
 12390 
     | 
    
         
            +
                    }
         
     | 
| 
      
 12391 
     | 
    
         
            +
                }
         
     | 
| 
      
 12392 
     | 
    
         
            +
                return 0;
         
     | 
| 
      
 12393 
     | 
    
         
            +
            }
         
     | 
| 
      
 12394 
     | 
    
         
            +
             
     | 
| 
       12269 
12395 
     | 
    
         
             
            /**
         
     | 
| 
       12270 
12396 
     | 
    
         
             
             * Parse a node that is part of a string. If the subsequent tokens cannot be
         
     | 
| 
       12271 
12397 
     | 
    
         
             
             * parsed as a string part, then NULL is returned.
         
     | 
| 
         @@ -12282,7 +12408,9 @@ parse_string_part(pm_parser_t *parser) { 
     | 
|
| 
       12282 
12408 
     | 
    
         
             
                    case PM_TOKEN_STRING_CONTENT: {
         
     | 
| 
       12283 
12409 
     | 
    
         
             
                        pm_token_t opening = not_provided(parser);
         
     | 
| 
       12284 
12410 
     | 
    
         
             
                        pm_token_t closing = not_provided(parser);
         
     | 
| 
      
 12411 
     | 
    
         
            +
             
     | 
| 
       12285 
12412 
     | 
    
         
             
                        pm_node_t *node = (pm_node_t *) pm_string_node_create_current_string(parser, &opening, &parser->current, &closing);
         
     | 
| 
      
 12413 
     | 
    
         
            +
                        pm_node_flag_set(node, parse_unescaped_encoding(parser));
         
     | 
| 
       12286 
12414 
     | 
    
         | 
| 
       12287 
12415 
     | 
    
         
             
                        parser_lex(parser);
         
     | 
| 
       12288 
12416 
     | 
    
         
             
                        return node;
         
     | 
| 
         @@ -12451,7 +12579,11 @@ parse_symbol(pm_parser_t *parser, pm_lex_mode_t *lex_mode, pm_lex_state_t next_s 
     | 
|
| 
       12451 
12579 
     | 
    
         
             
                    }
         
     | 
| 
       12452 
12580 
     | 
    
         | 
| 
       12453 
12581 
     | 
    
         
             
                    if (next_state != PM_LEX_STATE_NONE) lex_state_set(parser, next_state);
         
     | 
| 
       12454 
     | 
    
         
            -
                     
     | 
| 
      
 12582 
     | 
    
         
            +
                    if (match1(parser, PM_TOKEN_EOF)) {
         
     | 
| 
      
 12583 
     | 
    
         
            +
                        pm_parser_err_token(parser, &opening, PM_ERR_SYMBOL_TERM_INTERPOLATED);
         
     | 
| 
      
 12584 
     | 
    
         
            +
                    } else {
         
     | 
| 
      
 12585 
     | 
    
         
            +
                        expect1(parser, PM_TOKEN_STRING_END, PM_ERR_SYMBOL_TERM_INTERPOLATED);
         
     | 
| 
      
 12586 
     | 
    
         
            +
                    }
         
     | 
| 
       12455 
12587 
     | 
    
         | 
| 
       12456 
12588 
     | 
    
         
             
                    return (pm_node_t *) pm_interpolated_symbol_node_create(parser, &opening, &node_list, &parser->previous);
         
     | 
| 
       12457 
12589 
     | 
    
         
             
                }
         
     | 
| 
         @@ -12463,6 +12595,34 @@ parse_symbol(pm_parser_t *parser, pm_lex_mode_t *lex_mode, pm_lex_state_t next_s 
     | 
|
| 
       12463 
12595 
     | 
    
         
             
                    content = parser->current;
         
     | 
| 
       12464 
12596 
     | 
    
         
             
                    unescaped = parser->current_string;
         
     | 
| 
       12465 
12597 
     | 
    
         
             
                    parser_lex(parser);
         
     | 
| 
      
 12598 
     | 
    
         
            +
             
     | 
| 
      
 12599 
     | 
    
         
            +
                    // If we have two string contents in a row, then the content of this
         
     | 
| 
      
 12600 
     | 
    
         
            +
                    // symbol is split because of heredoc contents. This looks like:
         
     | 
| 
      
 12601 
     | 
    
         
            +
                    //
         
     | 
| 
      
 12602 
     | 
    
         
            +
                    // <<A; :'a
         
     | 
| 
      
 12603 
     | 
    
         
            +
                    // A
         
     | 
| 
      
 12604 
     | 
    
         
            +
                    // b'
         
     | 
| 
      
 12605 
     | 
    
         
            +
                    //
         
     | 
| 
      
 12606 
     | 
    
         
            +
                    // In this case, the best way we have to represent this is as an
         
     | 
| 
      
 12607 
     | 
    
         
            +
                    // interpolated string node, so that's what we'll do here.
         
     | 
| 
      
 12608 
     | 
    
         
            +
                    if (match1(parser, PM_TOKEN_STRING_CONTENT)) {
         
     | 
| 
      
 12609 
     | 
    
         
            +
                        pm_node_list_t parts = { 0 };
         
     | 
| 
      
 12610 
     | 
    
         
            +
                        pm_token_t bounds = not_provided(parser);
         
     | 
| 
      
 12611 
     | 
    
         
            +
             
     | 
| 
      
 12612 
     | 
    
         
            +
                        pm_node_t *part = (pm_node_t *) pm_string_node_create_unescaped(parser, &bounds, &content, &bounds, &unescaped);
         
     | 
| 
      
 12613 
     | 
    
         
            +
                        pm_node_list_append(&parts, part);
         
     | 
| 
      
 12614 
     | 
    
         
            +
             
     | 
| 
      
 12615 
     | 
    
         
            +
                        part = (pm_node_t *) pm_string_node_create_unescaped(parser, &bounds, &parser->current, &bounds, &parser->current_string);
         
     | 
| 
      
 12616 
     | 
    
         
            +
                        pm_node_list_append(&parts, part);
         
     | 
| 
      
 12617 
     | 
    
         
            +
             
     | 
| 
      
 12618 
     | 
    
         
            +
                        if (next_state != PM_LEX_STATE_NONE) {
         
     | 
| 
      
 12619 
     | 
    
         
            +
                            lex_state_set(parser, next_state);
         
     | 
| 
      
 12620 
     | 
    
         
            +
                        }
         
     | 
| 
      
 12621 
     | 
    
         
            +
             
     | 
| 
      
 12622 
     | 
    
         
            +
                        parser_lex(parser);
         
     | 
| 
      
 12623 
     | 
    
         
            +
                        expect1(parser, PM_TOKEN_STRING_END, PM_ERR_SYMBOL_TERM_DYNAMIC);
         
     | 
| 
      
 12624 
     | 
    
         
            +
                        return (pm_node_t *) pm_interpolated_symbol_node_create(parser, &opening, &parts, &parser->previous);
         
     | 
| 
      
 12625 
     | 
    
         
            +
                    }
         
     | 
| 
       12466 
12626 
     | 
    
         
             
                } else {
         
     | 
| 
       12467 
12627 
     | 
    
         
             
                    content = (pm_token_t) { .type = PM_TOKEN_STRING_CONTENT, .start = parser->previous.end, .end = parser->previous.end };
         
     | 
| 
       12468 
12628 
     | 
    
         
             
                    pm_string_shared_init(&unescaped, content.start, content.end);
         
     | 
| 
         @@ -12472,7 +12632,11 @@ parse_symbol(pm_parser_t *parser, pm_lex_mode_t *lex_mode, pm_lex_state_t next_s 
     | 
|
| 
       12472 
12632 
     | 
    
         
             
                    lex_state_set(parser, next_state);
         
     | 
| 
       12473 
12633 
     | 
    
         
             
                }
         
     | 
| 
       12474 
12634 
     | 
    
         | 
| 
       12475 
     | 
    
         
            -
                 
     | 
| 
      
 12635 
     | 
    
         
            +
                if (match1(parser, PM_TOKEN_EOF)) {
         
     | 
| 
      
 12636 
     | 
    
         
            +
                    pm_parser_err_token(parser, &opening, PM_ERR_SYMBOL_TERM_DYNAMIC);
         
     | 
| 
      
 12637 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 12638 
     | 
    
         
            +
                    expect1(parser, PM_TOKEN_STRING_END, PM_ERR_SYMBOL_TERM_DYNAMIC);
         
     | 
| 
      
 12639 
     | 
    
         
            +
                }
         
     | 
| 
       12476 
12640 
     | 
    
         
             
                return (pm_node_t *) pm_symbol_node_create_unescaped(parser, &opening, &content, &parser->previous, &unescaped);
         
     | 
| 
       12477 
12641 
     | 
    
         
             
            }
         
     | 
| 
       12478 
12642 
     | 
    
         | 
| 
         @@ -12561,9 +12725,9 @@ parse_alias_argument(pm_parser_t *parser, bool first) { 
     | 
|
| 
       12561 
12725 
     | 
    
         
             
             * numbered parameters.
         
     | 
| 
       12562 
12726 
     | 
    
         
             
             */
         
     | 
| 
       12563 
12727 
     | 
    
         
             
            static bool
         
     | 
| 
       12564 
     | 
    
         
            -
             
     | 
| 
      
 12728 
     | 
    
         
            +
            outer_scope_using_numbered_parameters_p(pm_parser_t *parser) {
         
     | 
| 
       12565 
12729 
     | 
    
         
             
                for (pm_scope_t *scope = parser->current_scope->previous; scope != NULL && !scope->closed; scope = scope->previous) {
         
     | 
| 
       12566 
     | 
    
         
            -
                    if (scope-> 
     | 
| 
      
 12730 
     | 
    
         
            +
                    if (scope->numbered_parameters) return true;
         
     | 
| 
       12567 
12731 
     | 
    
         
             
                }
         
     | 
| 
       12568 
12732 
     | 
    
         | 
| 
       12569 
12733 
     | 
    
         
             
                return false;
         
     | 
| 
         @@ -12583,25 +12747,32 @@ parse_variable_call(pm_parser_t *parser) { 
     | 
|
| 
       12583 
12747 
     | 
    
         
             
                    }
         
     | 
| 
       12584 
12748 
     | 
    
         | 
| 
       12585 
12749 
     | 
    
         
             
                    if (!parser->current_scope->closed && pm_token_is_numbered_parameter(parser->previous.start, parser->previous.end)) {
         
     | 
| 
       12586 
     | 
    
         
            -
                        // Indicate that this scope is using numbered params so that child
         
     | 
| 
       12587 
     | 
    
         
            -
                        // scopes cannot.
         
     | 
| 
       12588 
     | 
    
         
            -
                        parser->current_scope->numbered_params = true;
         
     | 
| 
       12589 
     | 
    
         
            -
             
     | 
| 
       12590 
12750 
     | 
    
         
             
                        // Now that we know we have a numbered parameter, we need to check
         
     | 
| 
       12591 
12751 
     | 
    
         
             
                        // if it's allowed in this context. If it is, then we will create a
         
     | 
| 
       12592 
12752 
     | 
    
         
             
                        // local variable read. If it's not, then we'll create a normal call
         
     | 
| 
       12593 
12753 
     | 
    
         
             
                        // node but add an error.
         
     | 
| 
       12594 
12754 
     | 
    
         
             
                        if (parser->current_scope->explicit_params) {
         
     | 
| 
       12595 
12755 
     | 
    
         
             
                            pm_parser_err_previous(parser, PM_ERR_NUMBERED_PARAMETER_NOT_ALLOWED);
         
     | 
| 
       12596 
     | 
    
         
            -
                        } else if ( 
     | 
| 
      
 12756 
     | 
    
         
            +
                        } else if (outer_scope_using_numbered_parameters_p(parser)) {
         
     | 
| 
       12597 
12757 
     | 
    
         
             
                            pm_parser_err_previous(parser, PM_ERR_NUMBERED_PARAMETER_OUTER_SCOPE);
         
     | 
| 
       12598 
12758 
     | 
    
         
             
                        } else {
         
     | 
| 
      
 12759 
     | 
    
         
            +
                            // Indicate that this scope is using numbered params so that child
         
     | 
| 
      
 12760 
     | 
    
         
            +
                            // scopes cannot.
         
     | 
| 
      
 12761 
     | 
    
         
            +
                            uint8_t number = parser->previous.start[1];
         
     | 
| 
      
 12762 
     | 
    
         
            +
             
     | 
| 
      
 12763 
     | 
    
         
            +
                            // We subtract the value for the character '0' to get the actual
         
     | 
| 
      
 12764 
     | 
    
         
            +
                            // integer value of the number (only _1 through _9 are valid)
         
     | 
| 
      
 12765 
     | 
    
         
            +
                            uint8_t numbered_parameters = (uint8_t) (number - '0');
         
     | 
| 
      
 12766 
     | 
    
         
            +
                            if (numbered_parameters > parser->current_scope->numbered_parameters) {
         
     | 
| 
      
 12767 
     | 
    
         
            +
                                parser->current_scope->numbered_parameters = numbered_parameters;
         
     | 
| 
      
 12768 
     | 
    
         
            +
                                pm_parser_numbered_parameters_set(parser, numbered_parameters);
         
     | 
| 
      
 12769 
     | 
    
         
            +
                            }
         
     | 
| 
      
 12770 
     | 
    
         
            +
             
     | 
| 
       12599 
12771 
     | 
    
         
             
                            // When you use a numbered parameter, it implies the existence
         
     | 
| 
       12600 
12772 
     | 
    
         
             
                            // of all of the locals that exist before it. For example,
         
     | 
| 
       12601 
12773 
     | 
    
         
             
                            // referencing _2 means that _1 must exist. Therefore here we
         
     | 
| 
       12602 
12774 
     | 
    
         
             
                            // loop through all of the possibilities and add them into the
         
     | 
| 
       12603 
12775 
     | 
    
         
             
                            // constant pool.
         
     | 
| 
       12604 
     | 
    
         
            -
                            uint8_t number = parser->previous.start[1];
         
     | 
| 
       12605 
12776 
     | 
    
         
             
                            uint8_t current = '1';
         
     | 
| 
       12606 
12777 
     | 
    
         
             
                            uint8_t *value;
         
     | 
| 
       12607 
12778 
     | 
    
         | 
| 
         @@ -12624,7 +12795,7 @@ parse_variable_call(pm_parser_t *parser) { 
     | 
|
| 
       12624 
12795 
     | 
    
         
             
                }
         
     | 
| 
       12625 
12796 
     | 
    
         | 
| 
       12626 
12797 
     | 
    
         
             
                pm_call_node_t *node = pm_call_node_variable_call_create(parser, &parser->previous);
         
     | 
| 
       12627 
     | 
    
         
            -
                node 
     | 
| 
      
 12798 
     | 
    
         
            +
                pm_node_flag_set((pm_node_t *)node, flags);
         
     | 
| 
       12628 
12799 
     | 
    
         | 
| 
       12629 
12800 
     | 
    
         
             
                return (pm_node_t *) node;
         
     | 
| 
       12630 
12801 
     | 
    
         
             
            }
         
     | 
| 
         @@ -12803,7 +12974,7 @@ parse_pattern_constant_path(pm_parser_t *parser, pm_node_t *node) { 
     | 
|
| 
       12803 
12974 
     | 
    
         
             
                    case PM_ARRAY_PATTERN_NODE: {
         
     | 
| 
       12804 
12975 
     | 
    
         
             
                        pm_array_pattern_node_t *pattern_node = (pm_array_pattern_node_t *) inner;
         
     | 
| 
       12805 
12976 
     | 
    
         | 
| 
       12806 
     | 
    
         
            -
                        if (pattern_node->constant == NULL) {
         
     | 
| 
      
 12977 
     | 
    
         
            +
                        if (pattern_node->constant == NULL && pattern_node->opening_loc.start == NULL) {
         
     | 
| 
       12807 
12978 
     | 
    
         
             
                            pattern_node->base.location.start = node->location.start;
         
     | 
| 
       12808 
12979 
     | 
    
         
             
                            pattern_node->base.location.end = closing.end;
         
     | 
| 
       12809 
12980 
     | 
    
         | 
| 
         @@ -12819,7 +12990,7 @@ parse_pattern_constant_path(pm_parser_t *parser, pm_node_t *node) { 
     | 
|
| 
       12819 
12990 
     | 
    
         
             
                    case PM_FIND_PATTERN_NODE: {
         
     | 
| 
       12820 
12991 
     | 
    
         
             
                        pm_find_pattern_node_t *pattern_node = (pm_find_pattern_node_t *) inner;
         
     | 
| 
       12821 
12992 
     | 
    
         | 
| 
       12822 
     | 
    
         
            -
                        if (pattern_node->constant == NULL) {
         
     | 
| 
      
 12993 
     | 
    
         
            +
                        if (pattern_node->constant == NULL && pattern_node->opening_loc.start == NULL) {
         
     | 
| 
       12823 
12994 
     | 
    
         
             
                            pattern_node->base.location.start = node->location.start;
         
     | 
| 
       12824 
12995 
     | 
    
         
             
                            pattern_node->base.location.end = closing.end;
         
     | 
| 
       12825 
12996 
     | 
    
         | 
| 
         @@ -12835,7 +13006,7 @@ parse_pattern_constant_path(pm_parser_t *parser, pm_node_t *node) { 
     | 
|
| 
       12835 
13006 
     | 
    
         
             
                    case PM_HASH_PATTERN_NODE: {
         
     | 
| 
       12836 
13007 
     | 
    
         
             
                        pm_hash_pattern_node_t *pattern_node = (pm_hash_pattern_node_t *) inner;
         
     | 
| 
       12837 
13008 
     | 
    
         | 
| 
       12838 
     | 
    
         
            -
                        if (pattern_node->constant == NULL) {
         
     | 
| 
      
 13009 
     | 
    
         
            +
                        if (pattern_node->constant == NULL && pattern_node->opening_loc.start == NULL) {
         
     | 
| 
       12839 
13010 
     | 
    
         
             
                            pattern_node->base.location.start = node->location.start;
         
     | 
| 
       12840 
13011 
     | 
    
         
             
                            pattern_node->base.location.end = closing.end;
         
     | 
| 
       12841 
13012 
     | 
    
         | 
| 
         @@ -12951,10 +13122,15 @@ parse_pattern_hash(pm_parser_t *parser, pm_node_t *first_assoc) { 
     | 
|
| 
       12951 
13122 
     | 
    
         
             
                        break;
         
     | 
| 
       12952 
13123 
     | 
    
         
             
                    }
         
     | 
| 
       12953 
13124 
     | 
    
         | 
| 
       12954 
     | 
    
         
            -
                    pm_node_t *assoc;
         
     | 
| 
       12955 
     | 
    
         
            -
             
     | 
| 
       12956 
13125 
     | 
    
         
             
                    if (match1(parser, PM_TOKEN_USTAR_STAR)) {
         
     | 
| 
       12957 
     | 
    
         
            -
                        assoc = parse_pattern_keyword_rest(parser);
         
     | 
| 
      
 13126 
     | 
    
         
            +
                        pm_node_t *assoc = parse_pattern_keyword_rest(parser);
         
     | 
| 
      
 13127 
     | 
    
         
            +
             
     | 
| 
      
 13128 
     | 
    
         
            +
                        if (rest == NULL) {
         
     | 
| 
      
 13129 
     | 
    
         
            +
                            rest = assoc;
         
     | 
| 
      
 13130 
     | 
    
         
            +
                        } else {
         
     | 
| 
      
 13131 
     | 
    
         
            +
                            pm_parser_err_node(parser, assoc, PM_ERR_PATTERN_EXPRESSION_AFTER_REST);
         
     | 
| 
      
 13132 
     | 
    
         
            +
                            pm_node_list_append(&assocs, assoc);
         
     | 
| 
      
 13133 
     | 
    
         
            +
                        }
         
     | 
| 
       12958 
13134 
     | 
    
         
             
                    } else {
         
     | 
| 
       12959 
13135 
     | 
    
         
             
                        expect1(parser, PM_TOKEN_LABEL, PM_ERR_PATTERN_LABEL_AFTER_COMMA);
         
     | 
| 
       12960 
13136 
     | 
    
         
             
                        pm_node_t *key = (pm_node_t *) pm_symbol_node_label_create(parser, &parser->previous);
         
     | 
| 
         @@ -12968,10 +13144,14 @@ parse_pattern_hash(pm_parser_t *parser, pm_node_t *first_assoc) { 
     | 
|
| 
       12968 
13144 
     | 
    
         
             
                        }
         
     | 
| 
       12969 
13145 
     | 
    
         | 
| 
       12970 
13146 
     | 
    
         
             
                        pm_token_t operator = not_provided(parser);
         
     | 
| 
       12971 
     | 
    
         
            -
                        assoc = (pm_node_t *) pm_assoc_node_create(parser, key, &operator, value);
         
     | 
| 
       12972 
     | 
    
         
            -
             
     | 
| 
      
 13147 
     | 
    
         
            +
                        pm_node_t *assoc = (pm_node_t *) pm_assoc_node_create(parser, key, &operator, value);
         
     | 
| 
      
 13148 
     | 
    
         
            +
             
     | 
| 
      
 13149 
     | 
    
         
            +
                        if (rest != NULL) {
         
     | 
| 
      
 13150 
     | 
    
         
            +
                            pm_parser_err_node(parser, assoc, PM_ERR_PATTERN_EXPRESSION_AFTER_REST);
         
     | 
| 
      
 13151 
     | 
    
         
            +
                        }
         
     | 
| 
       12973 
13152 
     | 
    
         | 
| 
       12974 
     | 
    
         
            -
             
     | 
| 
      
 13153 
     | 
    
         
            +
                        pm_node_list_append(&assocs, assoc);
         
     | 
| 
      
 13154 
     | 
    
         
            +
                    }
         
     | 
| 
       12975 
13155 
     | 
    
         
             
                }
         
     | 
| 
       12976 
13156 
     | 
    
         | 
| 
       12977 
13157 
     | 
    
         
             
                pm_hash_pattern_node_t *node = pm_hash_pattern_node_node_list_create(parser, &assocs, rest);
         
     | 
| 
         @@ -12989,8 +13169,13 @@ parse_pattern_primitive(pm_parser_t *parser, pm_diagnostic_id_t diag_id) { 
     | 
|
| 
       12989 
13169 
     | 
    
         
             
                    case PM_TOKEN_IDENTIFIER:
         
     | 
| 
       12990 
13170 
     | 
    
         
             
                    case PM_TOKEN_METHOD_NAME: {
         
     | 
| 
       12991 
13171 
     | 
    
         
             
                        parser_lex(parser);
         
     | 
| 
       12992 
     | 
    
         
            -
                         
     | 
| 
       12993 
     | 
    
         
            -
                         
     | 
| 
      
 13172 
     | 
    
         
            +
                        pm_token_t name = parser->previous;
         
     | 
| 
      
 13173 
     | 
    
         
            +
                        int depth = pm_parser_local_depth(parser, &name);
         
     | 
| 
      
 13174 
     | 
    
         
            +
                        if (depth < 0) {
         
     | 
| 
      
 13175 
     | 
    
         
            +
                            depth = 0;
         
     | 
| 
      
 13176 
     | 
    
         
            +
                            pm_parser_local_add_token(parser, &name);
         
     | 
| 
      
 13177 
     | 
    
         
            +
                        }
         
     | 
| 
      
 13178 
     | 
    
         
            +
                        return (pm_node_t *) pm_local_variable_target_node_create_depth(parser, &name, (uint32_t) depth);
         
     | 
| 
       12994 
13179 
     | 
    
         
             
                    }
         
     | 
| 
       12995 
13180 
     | 
    
         
             
                    case PM_TOKEN_BRACKET_LEFT_ARRAY: {
         
     | 
| 
       12996 
13181 
     | 
    
         
             
                        pm_token_t opening = parser->current;
         
     | 
| 
         @@ -13077,7 +13262,7 @@ parse_pattern_primitive(pm_parser_t *parser, pm_diagnostic_id_t diag_id) { 
     | 
|
| 
       13077 
13262 
     | 
    
         
             
                                    first_assoc = parse_pattern_keyword_rest(parser);
         
     | 
| 
       13078 
13263 
     | 
    
         
             
                                    break;
         
     | 
| 
       13079 
13264 
     | 
    
         
             
                                case PM_TOKEN_STRING_BEGIN: {
         
     | 
| 
       13080 
     | 
    
         
            -
                                    pm_node_t *key = parse_expression(parser, PM_BINDING_POWER_MAX, PM_ERR_PATTERN_HASH_KEY);
         
     | 
| 
      
 13265 
     | 
    
         
            +
                                    pm_node_t *key = parse_expression(parser, PM_BINDING_POWER_MAX, false, PM_ERR_PATTERN_HASH_KEY);
         
     | 
| 
       13081 
13266 
     | 
    
         
             
                                    pm_token_t operator = not_provided(parser);
         
     | 
| 
       13082 
13267 
     | 
    
         | 
| 
       13083 
13268 
     | 
    
         
             
                                    if (!pm_symbol_node_label_p(key)) {
         
     | 
| 
         @@ -13124,7 +13309,7 @@ parse_pattern_primitive(pm_parser_t *parser, pm_diagnostic_id_t diag_id) { 
     | 
|
| 
       13124 
13309 
     | 
    
         
             
                        // expression as the right side of the range.
         
     | 
| 
       13125 
13310 
     | 
    
         
             
                        switch (parser->current.type) {
         
     | 
| 
       13126 
13311 
     | 
    
         
             
                            case PM_CASE_PRIMITIVE: {
         
     | 
| 
       13127 
     | 
    
         
            -
                                pm_node_t *right = parse_expression(parser, PM_BINDING_POWER_MAX, PM_ERR_PATTERN_EXPRESSION_AFTER_RANGE);
         
     | 
| 
      
 13312 
     | 
    
         
            +
                                pm_node_t *right = parse_expression(parser, PM_BINDING_POWER_MAX, false, PM_ERR_PATTERN_EXPRESSION_AFTER_RANGE);
         
     | 
| 
       13128 
13313 
     | 
    
         
             
                                return (pm_node_t *) pm_range_node_create(parser, NULL, &operator, right);
         
     | 
| 
       13129 
13314 
     | 
    
         
             
                            }
         
     | 
| 
       13130 
13315 
     | 
    
         
             
                            default: {
         
     | 
| 
         @@ -13135,7 +13320,7 @@ parse_pattern_primitive(pm_parser_t *parser, pm_diagnostic_id_t diag_id) { 
     | 
|
| 
       13135 
13320 
     | 
    
         
             
                        }
         
     | 
| 
       13136 
13321 
     | 
    
         
             
                    }
         
     | 
| 
       13137 
13322 
     | 
    
         
             
                    case PM_CASE_PRIMITIVE: {
         
     | 
| 
       13138 
     | 
    
         
            -
                        pm_node_t *node = parse_expression(parser, PM_BINDING_POWER_MAX, diag_id);
         
     | 
| 
      
 13323 
     | 
    
         
            +
                        pm_node_t *node = parse_expression(parser, PM_BINDING_POWER_MAX, false, diag_id);
         
     | 
| 
       13139 
13324 
     | 
    
         | 
| 
       13140 
13325 
     | 
    
         
             
                        // Now that we have a primitive, we need to check if it's part of a range.
         
     | 
| 
       13141 
13326 
     | 
    
         
             
                        if (accept2(parser, PM_TOKEN_DOT_DOT, PM_TOKEN_DOT_DOT_DOT)) {
         
     | 
| 
         @@ -13146,7 +13331,7 @@ parse_pattern_primitive(pm_parser_t *parser, pm_diagnostic_id_t diag_id) { 
     | 
|
| 
       13146 
13331 
     | 
    
         
             
                            // node. Otherwise, we'll create an endless range.
         
     | 
| 
       13147 
13332 
     | 
    
         
             
                            switch (parser->current.type) {
         
     | 
| 
       13148 
13333 
     | 
    
         
             
                                case PM_CASE_PRIMITIVE: {
         
     | 
| 
       13149 
     | 
    
         
            -
                                    pm_node_t *right = parse_expression(parser, PM_BINDING_POWER_MAX, PM_ERR_PATTERN_EXPRESSION_AFTER_RANGE);
         
     | 
| 
      
 13334 
     | 
    
         
            +
                                    pm_node_t *right = parse_expression(parser, PM_BINDING_POWER_MAX, false, PM_ERR_PATTERN_EXPRESSION_AFTER_RANGE);
         
     | 
| 
       13150 
13335 
     | 
    
         
             
                                    return (pm_node_t *) pm_range_node_create(parser, node, &operator, right);
         
     | 
| 
       13151 
13336 
     | 
    
         
             
                                }
         
     | 
| 
       13152 
13337 
     | 
    
         
             
                                default:
         
     | 
| 
         @@ -13206,7 +13391,7 @@ parse_pattern_primitive(pm_parser_t *parser, pm_diagnostic_id_t diag_id) { 
     | 
|
| 
       13206 
13391 
     | 
    
         
             
                                pm_token_t lparen = parser->current;
         
     | 
| 
       13207 
13392 
     | 
    
         
             
                                parser_lex(parser);
         
     | 
| 
       13208 
13393 
     | 
    
         | 
| 
       13209 
     | 
    
         
            -
                                pm_node_t *expression = parse_value_expression(parser, PM_BINDING_POWER_STATEMENT, PM_ERR_PATTERN_EXPRESSION_AFTER_PIN);
         
     | 
| 
      
 13394 
     | 
    
         
            +
                                pm_node_t *expression = parse_value_expression(parser, PM_BINDING_POWER_STATEMENT, true, PM_ERR_PATTERN_EXPRESSION_AFTER_PIN);
         
     | 
| 
       13210 
13395 
     | 
    
         
             
                                parser->pattern_matching_newlines = previous_pattern_matching_newlines;
         
     | 
| 
       13211 
13396 
     | 
    
         | 
| 
       13212 
13397 
     | 
    
         
             
                                accept1(parser, PM_TOKEN_NEWLINE);
         
     | 
| 
         @@ -13307,9 +13492,13 @@ parse_pattern_primitives(pm_parser_t *parser, pm_diagnostic_id_t diag_id) { 
     | 
|
| 
       13307 
13492 
     | 
    
         | 
| 
       13308 
13493 
     | 
    
         
             
                    expect1(parser, PM_TOKEN_IDENTIFIER, PM_ERR_PATTERN_IDENT_AFTER_HROCKET);
         
     | 
| 
       13309 
13494 
     | 
    
         
             
                    pm_token_t identifier = parser->previous;
         
     | 
| 
       13310 
     | 
    
         
            -
                     
     | 
| 
      
 13495 
     | 
    
         
            +
                    int depth = pm_parser_local_depth(parser, &identifier);
         
     | 
| 
      
 13496 
     | 
    
         
            +
                    if (depth < 0) {
         
     | 
| 
      
 13497 
     | 
    
         
            +
                        depth = 0;
         
     | 
| 
      
 13498 
     | 
    
         
            +
                        pm_parser_local_add_token(parser, &identifier);
         
     | 
| 
      
 13499 
     | 
    
         
            +
                    }
         
     | 
| 
       13311 
13500 
     | 
    
         | 
| 
       13312 
     | 
    
         
            -
                    pm_node_t *target = (pm_node_t *)  
     | 
| 
      
 13501 
     | 
    
         
            +
                    pm_node_t *target = (pm_node_t *) pm_local_variable_target_node_create_depth(parser, &identifier, (uint32_t) depth);
         
     | 
| 
       13313 
13502 
     | 
    
         
             
                    node = (pm_node_t *) pm_capture_pattern_node_create(parser, node, target, &operator);
         
     | 
| 
       13314 
13503 
     | 
    
         
             
                }
         
     | 
| 
       13315 
13504 
     | 
    
         | 
| 
         @@ -13370,6 +13559,8 @@ parse_pattern(pm_parser_t *parser, bool top_pattern, pm_diagnostic_id_t diag_id) 
     | 
|
| 
       13370 
13559 
     | 
    
         
             
                    while (accept1(parser, PM_TOKEN_COMMA)) {
         
     | 
| 
       13371 
13560 
     | 
    
         
             
                        // Break early here in case we have a trailing comma.
         
     | 
| 
       13372 
13561 
     | 
    
         
             
                        if (match5(parser, PM_TOKEN_KEYWORD_THEN, PM_TOKEN_BRACE_RIGHT, PM_TOKEN_BRACKET_RIGHT, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON)) {
         
     | 
| 
      
 13562 
     | 
    
         
            +
                            node = (pm_node_t *) pm_implicit_rest_node_create(parser, &parser->previous);
         
     | 
| 
      
 13563 
     | 
    
         
            +
                            pm_node_list_append(&nodes, node);
         
     | 
| 
       13373 
13564 
     | 
    
         
             
                            break;
         
     | 
| 
       13374 
13565 
     | 
    
         
             
                        }
         
     | 
| 
       13375 
13566 
     | 
    
         | 
| 
         @@ -13460,13 +13651,15 @@ parse_strings(pm_parser_t *parser, pm_node_t *current) { 
     | 
|
| 
       13460 
13651 
     | 
    
         | 
| 
       13461 
13652 
     | 
    
         
             
                    // Here we have found a string literal. We'll parse it and add it to
         
     | 
| 
       13462 
13653 
     | 
    
         
             
                    // the list of strings.
         
     | 
| 
       13463 
     | 
    
         
            -
                     
     | 
| 
       13464 
     | 
    
         
            -
                     
     | 
| 
      
 13654 
     | 
    
         
            +
                    const pm_lex_mode_t *lex_mode = parser->lex_modes.current;
         
     | 
| 
      
 13655 
     | 
    
         
            +
                    assert(lex_mode->mode == PM_LEX_STRING);
         
     | 
| 
      
 13656 
     | 
    
         
            +
                    bool lex_interpolation = lex_mode->as.string.interpolation;
         
     | 
| 
       13465 
13657 
     | 
    
         | 
| 
       13466 
13658 
     | 
    
         
             
                    pm_token_t opening = parser->current;
         
     | 
| 
       13467 
13659 
     | 
    
         
             
                    parser_lex(parser);
         
     | 
| 
       13468 
13660 
     | 
    
         | 
| 
       13469 
     | 
    
         
            -
                    if ( 
     | 
| 
      
 13661 
     | 
    
         
            +
                    if (match2(parser, PM_TOKEN_STRING_END, PM_TOKEN_EOF)) {
         
     | 
| 
      
 13662 
     | 
    
         
            +
                        expect1(parser, PM_TOKEN_STRING_END, PM_ERR_STRING_LITERAL_TERM);
         
     | 
| 
       13470 
13663 
     | 
    
         
             
                        // If we get here, then we have an end immediately after a
         
     | 
| 
       13471 
13664 
     | 
    
         
             
                        // start. In that case we'll create an empty content token and
         
     | 
| 
       13472 
13665 
     | 
    
         
             
                        // return an uninterpolated string.
         
     | 
| 
         @@ -13489,15 +13682,16 @@ parse_strings(pm_parser_t *parser, pm_node_t *current) { 
     | 
|
| 
       13489 
13682 
     | 
    
         
             
                        // If we don't accept interpolation then we expect the string to
         
     | 
| 
       13490 
13683 
     | 
    
         
             
                        // start with a single string content node.
         
     | 
| 
       13491 
13684 
     | 
    
         
             
                        pm_string_t unescaped;
         
     | 
| 
      
 13685 
     | 
    
         
            +
                        pm_token_t content;
         
     | 
| 
       13492 
13686 
     | 
    
         
             
                        if (match1(parser, PM_TOKEN_EOF)) {
         
     | 
| 
       13493 
13687 
     | 
    
         
             
                            unescaped = PM_STRING_EMPTY;
         
     | 
| 
      
 13688 
     | 
    
         
            +
                            content = not_provided(parser);
         
     | 
| 
       13494 
13689 
     | 
    
         
             
                        } else {
         
     | 
| 
       13495 
13690 
     | 
    
         
             
                            unescaped = parser->current_string;
         
     | 
| 
      
 13691 
     | 
    
         
            +
                            expect1(parser, PM_TOKEN_STRING_CONTENT, PM_ERR_EXPECT_STRING_CONTENT);
         
     | 
| 
      
 13692 
     | 
    
         
            +
                            content = parser->previous;
         
     | 
| 
       13496 
13693 
     | 
    
         
             
                        }
         
     | 
| 
       13497 
13694 
     | 
    
         | 
| 
       13498 
     | 
    
         
            -
                        expect1(parser, PM_TOKEN_STRING_CONTENT, PM_ERR_EXPECT_STRING_CONTENT);
         
     | 
| 
       13499 
     | 
    
         
            -
                        pm_token_t content = parser->previous;
         
     | 
| 
       13500 
     | 
    
         
            -
             
     | 
| 
       13501 
13695 
     | 
    
         
             
                        // It is unfortunately possible to have multiple string content
         
     | 
| 
       13502 
13696 
     | 
    
         
             
                        // nodes in a row in the case that there's heredoc content in
         
     | 
| 
       13503 
13697 
     | 
    
         
             
                        // the middle of the string, like this cursed example:
         
     | 
| 
         @@ -13526,6 +13720,9 @@ parse_strings(pm_parser_t *parser, pm_node_t *current) { 
     | 
|
| 
       13526 
13720 
     | 
    
         
             
                            node = (pm_node_t *) pm_interpolated_string_node_create(parser, &opening, &parts, &parser->previous);
         
     | 
| 
       13527 
13721 
     | 
    
         
             
                        } else if (accept1(parser, PM_TOKEN_LABEL_END) && !state_is_arg_labeled) {
         
     | 
| 
       13528 
13722 
     | 
    
         
             
                            node = (pm_node_t *) pm_symbol_node_create_unescaped(parser, &opening, &content, &parser->previous, &unescaped);
         
     | 
| 
      
 13723 
     | 
    
         
            +
                        } else if (match1(parser, PM_TOKEN_EOF)) {
         
     | 
| 
      
 13724 
     | 
    
         
            +
                            pm_parser_err_token(parser, &opening, PM_ERR_STRING_LITERAL_TERM);
         
     | 
| 
      
 13725 
     | 
    
         
            +
                            node = (pm_node_t *) pm_string_node_create_unescaped(parser, &opening, &content, &parser->current, &unescaped);
         
     | 
| 
       13529 
13726 
     | 
    
         
             
                        } else {
         
     | 
| 
       13530 
13727 
     | 
    
         
             
                            expect1(parser, PM_TOKEN_STRING_END, PM_ERR_STRING_LITERAL_TERM);
         
     | 
| 
       13531 
13728 
     | 
    
         
             
                            node = (pm_node_t *) pm_string_node_create_unescaped(parser, &opening, &content, &parser->previous, &unescaped);
         
     | 
| 
         @@ -13539,9 +13736,10 @@ parse_strings(pm_parser_t *parser, pm_node_t *current) { 
     | 
|
| 
       13539 
13736 
     | 
    
         
             
                        pm_string_t unescaped = parser->current_string;
         
     | 
| 
       13540 
13737 
     | 
    
         
             
                        parser_lex(parser);
         
     | 
| 
       13541 
13738 
     | 
    
         | 
| 
       13542 
     | 
    
         
            -
                        if ( 
     | 
| 
      
 13739 
     | 
    
         
            +
                        if (match2(parser, PM_TOKEN_STRING_END, PM_TOKEN_EOF)) {
         
     | 
| 
       13543 
13740 
     | 
    
         
             
                            node = (pm_node_t *) pm_string_node_create_unescaped(parser, &opening, &content, &parser->current, &unescaped);
         
     | 
| 
       13544 
     | 
    
         
            -
                             
     | 
| 
      
 13741 
     | 
    
         
            +
                            pm_node_flag_set(node, parse_unescaped_encoding(parser));
         
     | 
| 
      
 13742 
     | 
    
         
            +
                            expect1(parser, PM_TOKEN_STRING_END, PM_ERR_STRING_LITERAL_TERM);
         
     | 
| 
       13545 
13743 
     | 
    
         
             
                        } else if (accept1(parser, PM_TOKEN_LABEL_END)) {
         
     | 
| 
       13546 
13744 
     | 
    
         
             
                            node = (pm_node_t *) pm_symbol_node_create_unescaped(parser, &opening, &content, &parser->previous, &unescaped);
         
     | 
| 
       13547 
13745 
     | 
    
         
             
                        } else {
         
     | 
| 
         @@ -13552,6 +13750,7 @@ parse_strings(pm_parser_t *parser, pm_node_t *current) { 
     | 
|
| 
       13552 
13750 
     | 
    
         
             
                            pm_token_t string_closing = not_provided(parser);
         
     | 
| 
       13553 
13751 
     | 
    
         | 
| 
       13554 
13752 
     | 
    
         
             
                            pm_node_t *part = (pm_node_t *) pm_string_node_create_unescaped(parser, &string_opening, &parser->previous, &string_closing, &unescaped);
         
     | 
| 
      
 13753 
     | 
    
         
            +
                            pm_node_flag_set(part, parse_unescaped_encoding(parser));
         
     | 
| 
       13555 
13754 
     | 
    
         
             
                            pm_node_list_append(&parts, part);
         
     | 
| 
       13556 
13755 
     | 
    
         | 
| 
       13557 
13756 
     | 
    
         
             
                            while (!match3(parser, PM_TOKEN_STRING_END, PM_TOKEN_LABEL_END, PM_TOKEN_EOF)) {
         
     | 
| 
         @@ -13562,6 +13761,9 @@ parse_strings(pm_parser_t *parser, pm_node_t *current) { 
     | 
|
| 
       13562 
13761 
     | 
    
         | 
| 
       13563 
13762 
     | 
    
         
             
                            if (accept1(parser, PM_TOKEN_LABEL_END) && !state_is_arg_labeled) {
         
     | 
| 
       13564 
13763 
     | 
    
         
             
                                node = (pm_node_t *) pm_interpolated_symbol_node_create(parser, &opening, &parts, &parser->previous);
         
     | 
| 
      
 13764 
     | 
    
         
            +
                            } else if (match1(parser, PM_TOKEN_EOF)) {
         
     | 
| 
      
 13765 
     | 
    
         
            +
                                pm_parser_err_token(parser, &opening, PM_ERR_STRING_INTERPOLATED_TERM);
         
     | 
| 
      
 13766 
     | 
    
         
            +
                                node = (pm_node_t *) pm_interpolated_string_node_create(parser, &opening, &parts, &parser->current);
         
     | 
| 
       13565 
13767 
     | 
    
         
             
                            } else {
         
     | 
| 
       13566 
13768 
     | 
    
         
             
                                expect1(parser, PM_TOKEN_STRING_END, PM_ERR_STRING_INTERPOLATED_TERM);
         
     | 
| 
       13567 
13769 
     | 
    
         
             
                                node = (pm_node_t *) pm_interpolated_string_node_create(parser, &opening, &parts, &parser->previous);
         
     | 
| 
         @@ -13582,6 +13784,9 @@ parse_strings(pm_parser_t *parser, pm_node_t *current) { 
     | 
|
| 
       13582 
13784 
     | 
    
         | 
| 
       13583 
13785 
     | 
    
         
             
                        if (accept1(parser, PM_TOKEN_LABEL_END)) {
         
     | 
| 
       13584 
13786 
     | 
    
         
             
                            node = (pm_node_t *) pm_interpolated_symbol_node_create(parser, &opening, &parts, &parser->previous);
         
     | 
| 
      
 13787 
     | 
    
         
            +
                        } else if (match1(parser, PM_TOKEN_EOF)) {
         
     | 
| 
      
 13788 
     | 
    
         
            +
                            pm_parser_err_token(parser, &opening, PM_ERR_STRING_INTERPOLATED_TERM);
         
     | 
| 
      
 13789 
     | 
    
         
            +
                            node = (pm_node_t *) pm_interpolated_string_node_create(parser, &opening, &parts, &parser->current);
         
     | 
| 
       13585 
13790 
     | 
    
         
             
                        } else {
         
     | 
| 
       13586 
13791 
     | 
    
         
             
                            expect1(parser, PM_TOKEN_STRING_END, PM_ERR_STRING_INTERPOLATED_TERM);
         
     | 
| 
       13587 
13792 
     | 
    
         
             
                            node = (pm_node_t *) pm_interpolated_string_node_create(parser, &opening, &parts, &parser->previous);
         
     | 
| 
         @@ -13629,7 +13834,7 @@ parse_strings(pm_parser_t *parser, pm_node_t *current) { 
     | 
|
| 
       13629 
13834 
     | 
    
         
             
             * Parse an expression that begins with the previous node that we just lexed.
         
     | 
| 
       13630 
13835 
     | 
    
         
             
             */
         
     | 
| 
       13631 
13836 
     | 
    
         
             
            static inline pm_node_t *
         
     | 
| 
       13632 
     | 
    
         
            -
            parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) {
         
     | 
| 
      
 13837 
     | 
    
         
            +
            parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, bool accepts_command_call) {
         
     | 
| 
       13633 
13838 
     | 
    
         
             
                switch (parser->current.type) {
         
     | 
| 
       13634 
13839 
     | 
    
         
             
                    case PM_TOKEN_BRACKET_LEFT_ARRAY: {
         
     | 
| 
       13635 
13840 
     | 
    
         
             
                        parser_lex(parser);
         
     | 
| 
         @@ -13665,7 +13870,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       13665 
13870 
     | 
    
         
             
                                        pm_parser_err_token(parser, &operator, PM_ERR_ARGUMENT_NO_FORWARDING_STAR);
         
     | 
| 
       13666 
13871 
     | 
    
         
             
                                    }
         
     | 
| 
       13667 
13872 
     | 
    
         
             
                                } else {
         
     | 
| 
       13668 
     | 
    
         
            -
                                    expression =  
     | 
| 
      
 13873 
     | 
    
         
            +
                                    expression = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_ARRAY_EXPRESSION_AFTER_STAR);
         
     | 
| 
       13669 
13874 
     | 
    
         
             
                                }
         
     | 
| 
       13670 
13875 
     | 
    
         | 
| 
       13671 
13876 
     | 
    
         
             
                                element = (pm_node_t *) pm_splat_node_create(parser, &operator, expression);
         
     | 
| 
         @@ -13683,7 +13888,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       13683 
13888 
     | 
    
         | 
| 
       13684 
13889 
     | 
    
         
             
                                parsed_bare_hash = true;
         
     | 
| 
       13685 
13890 
     | 
    
         
             
                            } else {
         
     | 
| 
       13686 
     | 
    
         
            -
                                element =  
     | 
| 
      
 13891 
     | 
    
         
            +
                                element = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_ARRAY_EXPRESSION);
         
     | 
| 
       13687 
13892 
     | 
    
         | 
| 
       13688 
13893 
     | 
    
         
             
                                if (pm_symbol_node_label_p(element) || accept1(parser, PM_TOKEN_EQUAL_GREATER)) {
         
     | 
| 
       13689 
13894 
     | 
    
         
             
                                    if (parsed_bare_hash) {
         
     | 
| 
         @@ -13699,7 +13904,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       13699 
13904 
     | 
    
         
             
                                        operator = not_provided(parser);
         
     | 
| 
       13700 
13905 
     | 
    
         
             
                                    }
         
     | 
| 
       13701 
13906 
     | 
    
         | 
| 
       13702 
     | 
    
         
            -
                                    pm_node_t *value =  
     | 
| 
      
 13907 
     | 
    
         
            +
                                    pm_node_t *value = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_HASH_VALUE);
         
     | 
| 
       13703 
13908 
     | 
    
         
             
                                    pm_node_t *assoc = (pm_node_t *) pm_assoc_node_create(parser, element, &operator, value);
         
     | 
| 
       13704 
13909 
     | 
    
         
             
                                    pm_keyword_hash_node_elements_append(hash, assoc);
         
     | 
| 
       13705 
13910 
     | 
    
         | 
| 
         @@ -13740,7 +13945,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       13740 
13945 
     | 
    
         
             
                        // of statements within the parentheses.
         
     | 
| 
       13741 
13946 
     | 
    
         
             
                        pm_accepts_block_stack_push(parser, true);
         
     | 
| 
       13742 
13947 
     | 
    
         
             
                        context_push(parser, PM_CONTEXT_PARENS);
         
     | 
| 
       13743 
     | 
    
         
            -
                        pm_node_t *statement = parse_expression(parser, PM_BINDING_POWER_STATEMENT, PM_ERR_CANNOT_PARSE_EXPRESSION);
         
     | 
| 
      
 13948 
     | 
    
         
            +
                        pm_node_t *statement = parse_expression(parser, PM_BINDING_POWER_STATEMENT, true, PM_ERR_CANNOT_PARSE_EXPRESSION);
         
     | 
| 
       13744 
13949 
     | 
    
         
             
                        context_pop(parser);
         
     | 
| 
       13745 
13950 
     | 
    
         | 
| 
       13746 
13951 
     | 
    
         
             
                        // Determine if this statement is followed by a terminator. In the
         
     | 
| 
         @@ -13816,7 +14021,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       13816 
14021 
     | 
    
         | 
| 
       13817 
14022 
     | 
    
         
             
                        // Parse each statement within the parentheses.
         
     | 
| 
       13818 
14023 
     | 
    
         
             
                        while (true) {
         
     | 
| 
       13819 
     | 
    
         
            -
                            pm_node_t *node = parse_expression(parser, PM_BINDING_POWER_STATEMENT, PM_ERR_CANNOT_PARSE_EXPRESSION);
         
     | 
| 
      
 14024 
     | 
    
         
            +
                            pm_node_t *node = parse_expression(parser, PM_BINDING_POWER_STATEMENT, true, PM_ERR_CANNOT_PARSE_EXPRESSION);
         
     | 
| 
       13820 
14025 
     | 
    
         
             
                            pm_statements_node_body_append(statements, node);
         
     | 
| 
       13821 
14026 
     | 
    
         | 
| 
       13822 
14027 
     | 
    
         
             
                            // If we're recovering from a syntax error, then we need to stop
         
     | 
| 
         @@ -13879,6 +14084,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       13879 
14084 
     | 
    
         | 
| 
       13880 
14085 
     | 
    
         
             
                        pm_token_t closing = not_provided(parser);
         
     | 
| 
       13881 
14086 
     | 
    
         
             
                        pm_node_t *node = (pm_node_t *) pm_string_node_create_current_string(parser, &opening, &content, &closing);
         
     | 
| 
      
 14087 
     | 
    
         
            +
                        pm_node_flag_set(node, parse_unescaped_encoding(parser));
         
     | 
| 
       13882 
14088 
     | 
    
         | 
| 
       13883 
14089 
     | 
    
         
             
                        // Characters can be followed by strings in which case they are
         
     | 
| 
       13884 
14090 
     | 
    
         
             
                        // automatically concatenated.
         
     | 
| 
         @@ -13906,11 +14112,11 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       13906 
14112 
     | 
    
         
             
                        // fact a method call, not a constant read.
         
     | 
| 
       13907 
14113 
     | 
    
         
             
                        if (
         
     | 
| 
       13908 
14114 
     | 
    
         
             
                            match1(parser, PM_TOKEN_PARENTHESIS_LEFT) ||
         
     | 
| 
       13909 
     | 
    
         
            -
                            ( 
     | 
| 
      
 14115 
     | 
    
         
            +
                            (accepts_command_call && (token_begins_expression_p(parser->current.type) || match3(parser, PM_TOKEN_UAMPERSAND, PM_TOKEN_USTAR, PM_TOKEN_USTAR_STAR))) ||
         
     | 
| 
       13910 
14116 
     | 
    
         
             
                            (pm_accepts_block_stack_p(parser) && match2(parser, PM_TOKEN_KEYWORD_DO, PM_TOKEN_BRACE_LEFT))
         
     | 
| 
       13911 
14117 
     | 
    
         
             
                        ) {
         
     | 
| 
       13912 
14118 
     | 
    
         
             
                            pm_arguments_t arguments = { 0 };
         
     | 
| 
       13913 
     | 
    
         
            -
                            parse_arguments_list(parser, &arguments, true);
         
     | 
| 
      
 14119 
     | 
    
         
            +
                            parse_arguments_list(parser, &arguments, true, accepts_command_call);
         
     | 
| 
       13914 
14120 
     | 
    
         
             
                            return (pm_node_t *) pm_call_node_fcall_create(parser, &constant, &arguments);
         
     | 
| 
       13915 
14121 
     | 
    
         
             
                        }
         
     | 
| 
       13916 
14122 
     | 
    
         | 
| 
         @@ -13944,7 +14150,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       13944 
14150 
     | 
    
         
             
                        pm_token_t operator = parser->current;
         
     | 
| 
       13945 
14151 
     | 
    
         
             
                        parser_lex(parser);
         
     | 
| 
       13946 
14152 
     | 
    
         | 
| 
       13947 
     | 
    
         
            -
                        pm_node_t *right = parse_expression(parser,  
     | 
| 
      
 14153 
     | 
    
         
            +
                        pm_node_t *right = parse_expression(parser, pm_binding_powers[operator.type].left, false, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
         
     | 
| 
       13948 
14154 
     | 
    
         
             
                        return (pm_node_t *) pm_range_node_create(parser, NULL, &operator, right);
         
     | 
| 
       13949 
14155 
     | 
    
         
             
                    }
         
     | 
| 
       13950 
14156 
     | 
    
         
             
                    case PM_TOKEN_FLOAT:
         
     | 
| 
         @@ -14003,10 +14209,10 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14003 
14209 
     | 
    
         
             
                            pm_call_node_t *call = (pm_call_node_t *) node;
         
     | 
| 
       14004 
14210 
     | 
    
         
             
                            pm_arguments_t arguments = { 0 };
         
     | 
| 
       14005 
14211 
     | 
    
         | 
| 
       14006 
     | 
    
         
            -
                            if (parse_arguments_list(parser, &arguments, true)) {
         
     | 
| 
      
 14212 
     | 
    
         
            +
                            if (parse_arguments_list(parser, &arguments, true, accepts_command_call)) {
         
     | 
| 
       14007 
14213 
     | 
    
         
             
                                // Since we found arguments, we need to turn off the
         
     | 
| 
       14008 
14214 
     | 
    
         
             
                                // variable call bit in the flags.
         
     | 
| 
       14009 
     | 
    
         
            -
                                 
     | 
| 
      
 14215 
     | 
    
         
            +
                                pm_node_flag_unset((pm_node_t *)call, PM_CALL_NODE_FLAGS_VARIABLE_CALL);
         
     | 
| 
       14010 
14216 
     | 
    
         | 
| 
       14011 
14217 
     | 
    
         
             
                                call->opening_loc = arguments.opening_loc;
         
     | 
| 
       14012 
14218 
     | 
    
         
             
                                call->arguments = arguments.arguments;
         
     | 
| 
         @@ -14030,11 +14236,11 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14030 
14236 
     | 
    
         
             
                            // can still be a method call if it is followed by arguments or
         
     | 
| 
       14031 
14237 
     | 
    
         
             
                            // a block, so we need to check for that here.
         
     | 
| 
       14032 
14238 
     | 
    
         
             
                            if (
         
     | 
| 
       14033 
     | 
    
         
            -
                                ( 
     | 
| 
      
 14239 
     | 
    
         
            +
                                (accepts_command_call && (token_begins_expression_p(parser->current.type) || match3(parser, PM_TOKEN_UAMPERSAND, PM_TOKEN_USTAR, PM_TOKEN_USTAR_STAR))) ||
         
     | 
| 
       14034 
14240 
     | 
    
         
             
                                (pm_accepts_block_stack_p(parser) && match2(parser, PM_TOKEN_KEYWORD_DO, PM_TOKEN_BRACE_LEFT))
         
     | 
| 
       14035 
14241 
     | 
    
         
             
                            ) {
         
     | 
| 
       14036 
14242 
     | 
    
         
             
                                pm_arguments_t arguments = { 0 };
         
     | 
| 
       14037 
     | 
    
         
            -
                                parse_arguments_list(parser, &arguments, true);
         
     | 
| 
      
 14243 
     | 
    
         
            +
                                parse_arguments_list(parser, &arguments, true, accepts_command_call);
         
     | 
| 
       14038 
14244 
     | 
    
         | 
| 
       14039 
14245 
     | 
    
         
             
                                pm_call_node_t *fcall = pm_call_node_fcall_create(parser, &identifier, &arguments);
         
     | 
| 
       14040 
14246 
     | 
    
         
             
                                pm_node_destroy(parser, node);
         
     | 
| 
         @@ -14065,7 +14271,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14065 
14271 
     | 
    
         
             
                        if (match2(parser, PM_TOKEN_HEREDOC_END, PM_TOKEN_EOF)) {
         
     | 
| 
       14066 
14272 
     | 
    
         
             
                            // If we get here, then we have an empty heredoc. We'll create
         
     | 
| 
       14067 
14273 
     | 
    
         
             
                            // an empty content token and return an empty string node.
         
     | 
| 
       14068 
     | 
    
         
            -
                             
     | 
| 
      
 14274 
     | 
    
         
            +
                            lex_mode_pop(parser);
         
     | 
| 
       14069 
14275 
     | 
    
         
             
                            expect1(parser, PM_TOKEN_HEREDOC_END, PM_ERR_HEREDOC_TERM);
         
     | 
| 
       14070 
14276 
     | 
    
         
             
                            pm_token_t content = parse_strings_empty_content(parser->previous.start);
         
     | 
| 
       14071 
14277 
     | 
    
         | 
| 
         @@ -14086,6 +14292,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14086 
14292 
     | 
    
         
             
                            // content and we're at the end of the heredoc, so we can return
         
     | 
| 
       14087 
14293 
     | 
    
         
             
                            // just a string node with the heredoc opening and closing as
         
     | 
| 
       14088 
14294 
     | 
    
         
             
                            // its opening and closing.
         
     | 
| 
      
 14295 
     | 
    
         
            +
                            pm_node_flag_set(part, parse_unescaped_encoding(parser));
         
     | 
| 
       14089 
14296 
     | 
    
         
             
                            pm_string_node_t *cast = (pm_string_node_t *) part;
         
     | 
| 
       14090 
14297 
     | 
    
         | 
| 
       14091 
14298 
     | 
    
         
             
                            cast->opening_loc = PM_LOCATION_TOKEN_VALUE(&opening);
         
     | 
| 
         @@ -14097,13 +14304,13 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14097 
14304 
     | 
    
         
             
                                cast->base.type = PM_X_STRING_NODE;
         
     | 
| 
       14098 
14305 
     | 
    
         
             
                            }
         
     | 
| 
       14099 
14306 
     | 
    
         | 
| 
       14100 
     | 
    
         
            -
                            size_t common_whitespace =  
     | 
| 
      
 14307 
     | 
    
         
            +
                            size_t common_whitespace = lex_mode->as.heredoc.common_whitespace;
         
     | 
| 
       14101 
14308 
     | 
    
         
             
                            if (indent == PM_HEREDOC_INDENT_TILDE && (common_whitespace != (size_t) -1) && (common_whitespace != 0)) {
         
     | 
| 
       14102 
14309 
     | 
    
         
             
                                parse_heredoc_dedent_string(&cast->unescaped, common_whitespace);
         
     | 
| 
       14103 
14310 
     | 
    
         
             
                            }
         
     | 
| 
       14104 
14311 
     | 
    
         | 
| 
       14105 
14312 
     | 
    
         
             
                            node = (pm_node_t *) cast;
         
     | 
| 
       14106 
     | 
    
         
            -
                             
     | 
| 
      
 14313 
     | 
    
         
            +
                            lex_mode_pop(parser);
         
     | 
| 
       14107 
14314 
     | 
    
         
             
                            expect1(parser, PM_TOKEN_HEREDOC_END, PM_ERR_HEREDOC_TERM);
         
     | 
| 
       14108 
14315 
     | 
    
         
             
                        } else {
         
     | 
| 
       14109 
14316 
     | 
    
         
             
                            // If we get here, then we have multiple parts in the heredoc,
         
     | 
| 
         @@ -14118,13 +14325,15 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14118 
14325 
     | 
    
         
             
                                }
         
     | 
| 
       14119 
14326 
     | 
    
         
             
                            }
         
     | 
| 
       14120 
14327 
     | 
    
         | 
| 
      
 14328 
     | 
    
         
            +
                            size_t common_whitespace = lex_mode->as.heredoc.common_whitespace;
         
     | 
| 
      
 14329 
     | 
    
         
            +
             
     | 
| 
       14121 
14330 
     | 
    
         
             
                            // Now that we have all of the parts, create the correct type of
         
     | 
| 
       14122 
14331 
     | 
    
         
             
                            // interpolated node.
         
     | 
| 
       14123 
14332 
     | 
    
         
             
                            if (quote == PM_HEREDOC_QUOTE_BACKTICK) {
         
     | 
| 
       14124 
14333 
     | 
    
         
             
                                pm_interpolated_x_string_node_t *cast = pm_interpolated_xstring_node_create(parser, &opening, &opening);
         
     | 
| 
       14125 
14334 
     | 
    
         
             
                                cast->parts = parts;
         
     | 
| 
       14126 
14335 
     | 
    
         | 
| 
       14127 
     | 
    
         
            -
                                 
     | 
| 
      
 14336 
     | 
    
         
            +
                                lex_mode_pop(parser);
         
     | 
| 
       14128 
14337 
     | 
    
         
             
                                expect1(parser, PM_TOKEN_HEREDOC_END, PM_ERR_HEREDOC_TERM);
         
     | 
| 
       14129 
14338 
     | 
    
         | 
| 
       14130 
14339 
     | 
    
         
             
                                pm_interpolated_xstring_node_closing_set(cast, &parser->previous);
         
     | 
| 
         @@ -14133,7 +14342,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14133 
14342 
     | 
    
         
             
                            } else {
         
     | 
| 
       14134 
14343 
     | 
    
         
             
                                pm_interpolated_string_node_t *cast = pm_interpolated_string_node_create(parser, &opening, &parts, &opening);
         
     | 
| 
       14135 
14344 
     | 
    
         | 
| 
       14136 
     | 
    
         
            -
                                 
     | 
| 
      
 14345 
     | 
    
         
            +
                                lex_mode_pop(parser);
         
     | 
| 
       14137 
14346 
     | 
    
         
             
                                expect1(parser, PM_TOKEN_HEREDOC_END, PM_ERR_HEREDOC_TERM);
         
     | 
| 
       14138 
14347 
     | 
    
         | 
| 
       14139 
14348 
     | 
    
         
             
                                pm_interpolated_string_node_closing_set(cast, &parser->previous);
         
     | 
| 
         @@ -14143,7 +14352,6 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14143 
14352 
     | 
    
         | 
| 
       14144 
14353 
     | 
    
         
             
                            // If this is a heredoc that is indented with a ~, then we need
         
     | 
| 
       14145 
14354 
     | 
    
         
             
                            // to dedent each line by the common leading whitespace.
         
     | 
| 
       14146 
     | 
    
         
            -
                            size_t common_whitespace = parser->current_string_common_whitespace;
         
     | 
| 
       14147 
14355 
     | 
    
         
             
                            if (indent == PM_HEREDOC_INDENT_TILDE && (common_whitespace != (size_t) -1) && (common_whitespace != 0)) {
         
     | 
| 
       14148 
14356 
     | 
    
         
             
                                pm_node_list_t *nodes;
         
     | 
| 
       14149 
14357 
     | 
    
         
             
                                if (quote == PM_HEREDOC_QUOTE_BACKTICK) {
         
     | 
| 
         @@ -14202,6 +14410,10 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14202 
14410 
     | 
    
         
             
                        parser_lex(parser);
         
     | 
| 
       14203 
14411 
     | 
    
         
             
                        return (pm_node_t *) pm_source_line_node_create(parser, &parser->previous);
         
     | 
| 
       14204 
14412 
     | 
    
         
             
                    case PM_TOKEN_KEYWORD_ALIAS: {
         
     | 
| 
      
 14413 
     | 
    
         
            +
                        if (binding_power != PM_BINDING_POWER_STATEMENT) {
         
     | 
| 
      
 14414 
     | 
    
         
            +
                            pm_parser_err_current(parser, PM_ERR_STATEMENT_ALIAS);
         
     | 
| 
      
 14415 
     | 
    
         
            +
                        }
         
     | 
| 
      
 14416 
     | 
    
         
            +
             
     | 
| 
       14205 
14417 
     | 
    
         
             
                        parser_lex(parser);
         
     | 
| 
       14206 
14418 
     | 
    
         
             
                        pm_token_t keyword = parser->previous;
         
     | 
| 
       14207 
14419 
     | 
    
         | 
| 
         @@ -14246,7 +14458,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14246 
14458 
     | 
    
         
             
                         } else if (!token_begins_expression_p(parser->current.type)) {
         
     | 
| 
       14247 
14459 
     | 
    
         
             
                            predicate = NULL;
         
     | 
| 
       14248 
14460 
     | 
    
         
             
                        } else {
         
     | 
| 
       14249 
     | 
    
         
            -
                            predicate = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, PM_ERR_CASE_EXPRESSION_AFTER_CASE);
         
     | 
| 
      
 14461 
     | 
    
         
            +
                            predicate = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, true, PM_ERR_CASE_EXPRESSION_AFTER_CASE);
         
     | 
| 
       14250 
14462 
     | 
    
         
             
                            while (accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON));
         
     | 
| 
       14251 
14463 
     | 
    
         
             
                        }
         
     | 
| 
       14252 
14464 
     | 
    
         | 
| 
         @@ -14273,14 +14485,14 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14273 
14485 
     | 
    
         
             
                                do {
         
     | 
| 
       14274 
14486 
     | 
    
         
             
                                    if (accept1(parser, PM_TOKEN_USTAR)) {
         
     | 
| 
       14275 
14487 
     | 
    
         
             
                                        pm_token_t operator = parser->previous;
         
     | 
| 
       14276 
     | 
    
         
            -
                                        pm_node_t *expression = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_EXPECT_EXPRESSION_AFTER_STAR);
         
     | 
| 
      
 14488 
     | 
    
         
            +
                                        pm_node_t *expression = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_EXPECT_EXPRESSION_AFTER_STAR);
         
     | 
| 
       14277 
14489 
     | 
    
         | 
| 
       14278 
14490 
     | 
    
         
             
                                        pm_splat_node_t *splat_node = pm_splat_node_create(parser, &operator, expression);
         
     | 
| 
       14279 
14491 
     | 
    
         
             
                                        pm_when_node_conditions_append(when_node, (pm_node_t *) splat_node);
         
     | 
| 
       14280 
14492 
     | 
    
         | 
| 
       14281 
14493 
     | 
    
         
             
                                        if (PM_NODE_TYPE_P(expression, PM_MISSING_NODE)) break;
         
     | 
| 
       14282 
14494 
     | 
    
         
             
                                    } else {
         
     | 
| 
       14283 
     | 
    
         
            -
                                        pm_node_t *condition = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_CASE_EXPRESSION_AFTER_WHEN);
         
     | 
| 
      
 14495 
     | 
    
         
            +
                                        pm_node_t *condition = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_CASE_EXPRESSION_AFTER_WHEN);
         
     | 
| 
       14284 
14496 
     | 
    
         
             
                                        pm_when_node_conditions_append(when_node, condition);
         
     | 
| 
       14285 
14497 
     | 
    
         | 
| 
       14286 
14498 
     | 
    
         
             
                                        if (PM_NODE_TYPE_P(condition, PM_MISSING_NODE)) break;
         
     | 
| 
         @@ -14337,11 +14549,11 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14337 
14549 
     | 
    
         
             
                                // for guard clauses in the form of `if` or `unless` statements.
         
     | 
| 
       14338 
14550 
     | 
    
         
             
                                if (accept1(parser, PM_TOKEN_KEYWORD_IF_MODIFIER)) {
         
     | 
| 
       14339 
14551 
     | 
    
         
             
                                    pm_token_t keyword = parser->previous;
         
     | 
| 
       14340 
     | 
    
         
            -
                                    pm_node_t *predicate = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_CONDITIONAL_IF_PREDICATE);
         
     | 
| 
      
 14552 
     | 
    
         
            +
                                    pm_node_t *predicate = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, true, PM_ERR_CONDITIONAL_IF_PREDICATE);
         
     | 
| 
       14341 
14553 
     | 
    
         
             
                                    pattern = (pm_node_t *) pm_if_node_modifier_create(parser, pattern, &keyword, predicate);
         
     | 
| 
       14342 
14554 
     | 
    
         
             
                                } else if (accept1(parser, PM_TOKEN_KEYWORD_UNLESS_MODIFIER)) {
         
     | 
| 
       14343 
14555 
     | 
    
         
             
                                    pm_token_t keyword = parser->previous;
         
     | 
| 
       14344 
     | 
    
         
            -
                                    pm_node_t *predicate = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_CONDITIONAL_UNLESS_PREDICATE);
         
     | 
| 
      
 14556 
     | 
    
         
            +
                                    pm_node_t *predicate = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, true, PM_ERR_CONDITIONAL_UNLESS_PREDICATE);
         
     | 
| 
       14345 
14557 
     | 
    
         
             
                                    pattern = (pm_node_t *) pm_unless_node_modifier_create(parser, pattern, &keyword, predicate);
         
     | 
| 
       14346 
14558 
     | 
    
         
             
                                }
         
     | 
| 
       14347 
14559 
     | 
    
         | 
| 
         @@ -14426,7 +14638,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14426 
14638 
     | 
    
         
             
                        }
         
     | 
| 
       14427 
14639 
     | 
    
         | 
| 
       14428 
14640 
     | 
    
         
             
                        pm_begin_node_t *begin_node = pm_begin_node_create(parser, &begin_keyword, begin_statements);
         
     | 
| 
       14429 
     | 
    
         
            -
                        parse_rescues(parser, begin_node);
         
     | 
| 
      
 14641 
     | 
    
         
            +
                        parse_rescues(parser, begin_node, false);
         
     | 
| 
       14430 
14642 
     | 
    
         | 
| 
       14431 
14643 
     | 
    
         
             
                        expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_BEGIN_TERM);
         
     | 
| 
       14432 
14644 
     | 
    
         
             
                        begin_node->base.location.end = parser->previous.end;
         
     | 
| 
         @@ -14439,6 +14651,10 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14439 
14651 
     | 
    
         
             
                        return (pm_node_t *) begin_node;
         
     | 
| 
       14440 
14652 
     | 
    
         
             
                    }
         
     | 
| 
       14441 
14653 
     | 
    
         
             
                    case PM_TOKEN_KEYWORD_BEGIN_UPCASE: {
         
     | 
| 
      
 14654 
     | 
    
         
            +
                        if (binding_power != PM_BINDING_POWER_STATEMENT) {
         
     | 
| 
      
 14655 
     | 
    
         
            +
                            pm_parser_err_current(parser, PM_ERR_STATEMENT_PREEXE_BEGIN);
         
     | 
| 
      
 14656 
     | 
    
         
            +
                        }
         
     | 
| 
      
 14657 
     | 
    
         
            +
             
     | 
| 
       14442 
14658 
     | 
    
         
             
                        parser_lex(parser);
         
     | 
| 
       14443 
14659 
     | 
    
         
             
                        pm_token_t keyword = parser->previous;
         
     | 
| 
       14444 
14660 
     | 
    
         | 
| 
         @@ -14496,7 +14712,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14496 
14712 
     | 
    
         | 
| 
       14497 
14713 
     | 
    
         
             
                        pm_token_t keyword = parser->previous;
         
     | 
| 
       14498 
14714 
     | 
    
         
             
                        pm_arguments_t arguments = { 0 };
         
     | 
| 
       14499 
     | 
    
         
            -
                        parse_arguments_list(parser, &arguments, true);
         
     | 
| 
      
 14715 
     | 
    
         
            +
                        parse_arguments_list(parser, &arguments, true, accepts_command_call);
         
     | 
| 
       14500 
14716 
     | 
    
         | 
| 
       14501 
14717 
     | 
    
         
             
                        if (
         
     | 
| 
       14502 
14718 
     | 
    
         
             
                            arguments.opening_loc.start == NULL &&
         
     | 
| 
         @@ -14513,7 +14729,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14513 
14729 
     | 
    
         | 
| 
       14514 
14730 
     | 
    
         
             
                        pm_token_t keyword = parser->previous;
         
     | 
| 
       14515 
14731 
     | 
    
         
             
                        pm_arguments_t arguments = { 0 };
         
     | 
| 
       14516 
     | 
    
         
            -
                        parse_arguments_list(parser, &arguments, false);
         
     | 
| 
      
 14732 
     | 
    
         
            +
                        parse_arguments_list(parser, &arguments, false, accepts_command_call);
         
     | 
| 
       14517 
14733 
     | 
    
         | 
| 
       14518 
14734 
     | 
    
         
             
                        return (pm_node_t *) pm_yield_node_create(parser, &keyword, &arguments.opening_loc, arguments.arguments, &arguments.closing_loc);
         
     | 
| 
       14519 
14735 
     | 
    
         
             
                    }
         
     | 
| 
         @@ -14524,8 +14740,10 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14524 
14740 
     | 
    
         | 
| 
       14525 
14741 
     | 
    
         
             
                        if (accept1(parser, PM_TOKEN_LESS_LESS)) {
         
     | 
| 
       14526 
14742 
     | 
    
         
             
                            pm_token_t operator = parser->previous;
         
     | 
| 
       14527 
     | 
    
         
            -
                            pm_node_t *expression =  
     | 
| 
      
 14743 
     | 
    
         
            +
                            pm_node_t *expression = parse_value_expression(parser, PM_BINDING_POWER_NOT, true, PM_ERR_EXPECT_EXPRESSION_AFTER_LESS_LESS);
         
     | 
| 
       14528 
14744 
     | 
    
         | 
| 
      
 14745 
     | 
    
         
            +
                            pm_constant_id_t old_param_name = parser->current_param_name;
         
     | 
| 
      
 14746 
     | 
    
         
            +
                            parser->current_param_name = 0;
         
     | 
| 
       14529 
14747 
     | 
    
         
             
                            pm_parser_scope_push(parser, true);
         
     | 
| 
       14530 
14748 
     | 
    
         
             
                            accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON);
         
     | 
| 
       14531 
14749 
     | 
    
         | 
| 
         @@ -14538,18 +14756,19 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14538 
14756 
     | 
    
         | 
| 
       14539 
14757 
     | 
    
         
             
                            if (match2(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) {
         
     | 
| 
       14540 
14758 
     | 
    
         
             
                                assert(statements == NULL || PM_NODE_TYPE_P(statements, PM_STATEMENTS_NODE));
         
     | 
| 
       14541 
     | 
    
         
            -
                                statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements);
         
     | 
| 
      
 14759 
     | 
    
         
            +
                                statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements, false);
         
     | 
| 
       14542 
14760 
     | 
    
         
             
                            }
         
     | 
| 
       14543 
14761 
     | 
    
         | 
| 
       14544 
14762 
     | 
    
         
             
                            expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CLASS_TERM);
         
     | 
| 
       14545 
14763 
     | 
    
         | 
| 
       14546 
14764 
     | 
    
         
             
                            pm_constant_id_list_t locals = parser->current_scope->locals;
         
     | 
| 
       14547 
14765 
     | 
    
         
             
                            pm_parser_scope_pop(parser);
         
     | 
| 
      
 14766 
     | 
    
         
            +
                            parser->current_param_name = old_param_name;
         
     | 
| 
       14548 
14767 
     | 
    
         
             
                            pm_do_loop_stack_pop(parser);
         
     | 
| 
       14549 
14768 
     | 
    
         
             
                            return (pm_node_t *) pm_singleton_class_node_create(parser, &locals, &class_keyword, &operator, expression, statements, &parser->previous);
         
     | 
| 
       14550 
14769 
     | 
    
         
             
                        }
         
     | 
| 
       14551 
14770 
     | 
    
         | 
| 
       14552 
     | 
    
         
            -
                        pm_node_t *constant_path = parse_expression(parser, PM_BINDING_POWER_INDEX, PM_ERR_CLASS_NAME);
         
     | 
| 
      
 14771 
     | 
    
         
            +
                        pm_node_t *constant_path = parse_expression(parser, PM_BINDING_POWER_INDEX, false, PM_ERR_CLASS_NAME);
         
     | 
| 
       14553 
14772 
     | 
    
         
             
                        pm_token_t name = parser->previous;
         
     | 
| 
       14554 
14773 
     | 
    
         
             
                        if (name.type != PM_TOKEN_CONSTANT) {
         
     | 
| 
       14555 
14774 
     | 
    
         
             
                            pm_parser_err_token(parser, &name, PM_ERR_CLASS_NAME);
         
     | 
| 
         @@ -14565,12 +14784,14 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14565 
14784 
     | 
    
         
             
                            parser->command_start = true;
         
     | 
| 
       14566 
14785 
     | 
    
         
             
                            parser_lex(parser);
         
     | 
| 
       14567 
14786 
     | 
    
         | 
| 
       14568 
     | 
    
         
            -
                            superclass = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, PM_ERR_CLASS_SUPERCLASS);
         
     | 
| 
      
 14787 
     | 
    
         
            +
                            superclass = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, true, PM_ERR_CLASS_SUPERCLASS);
         
     | 
| 
       14569 
14788 
     | 
    
         
             
                        } else {
         
     | 
| 
       14570 
14789 
     | 
    
         
             
                            inheritance_operator = not_provided(parser);
         
     | 
| 
       14571 
14790 
     | 
    
         
             
                            superclass = NULL;
         
     | 
| 
       14572 
14791 
     | 
    
         
             
                        }
         
     | 
| 
       14573 
14792 
     | 
    
         | 
| 
      
 14793 
     | 
    
         
            +
                        pm_constant_id_t old_param_name = parser->current_param_name;
         
     | 
| 
      
 14794 
     | 
    
         
            +
                        parser->current_param_name = 0;
         
     | 
| 
       14574 
14795 
     | 
    
         
             
                        pm_parser_scope_push(parser, true);
         
     | 
| 
       14575 
14796 
     | 
    
         
             
                        if (inheritance_operator.type != PM_TOKEN_NOT_PROVIDED) {
         
     | 
| 
       14576 
14797 
     | 
    
         
             
                            expect2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON, PM_ERR_CLASS_UNEXPECTED_END);
         
     | 
| 
         @@ -14587,7 +14808,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14587 
14808 
     | 
    
         | 
| 
       14588 
14809 
     | 
    
         
             
                        if (match2(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) {
         
     | 
| 
       14589 
14810 
     | 
    
         
             
                            assert(statements == NULL || PM_NODE_TYPE_P(statements, PM_STATEMENTS_NODE));
         
     | 
| 
       14590 
     | 
    
         
            -
                            statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements);
         
     | 
| 
      
 14811 
     | 
    
         
            +
                            statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements, false);
         
     | 
| 
       14591 
14812 
     | 
    
         
             
                        }
         
     | 
| 
       14592 
14813 
     | 
    
         | 
| 
       14593 
14814 
     | 
    
         
             
                        expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CLASS_TERM);
         
     | 
| 
         @@ -14598,6 +14819,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14598 
14819 
     | 
    
         | 
| 
       14599 
14820 
     | 
    
         
             
                        pm_constant_id_list_t locals = parser->current_scope->locals;
         
     | 
| 
       14600 
14821 
     | 
    
         
             
                        pm_parser_scope_pop(parser);
         
     | 
| 
      
 14822 
     | 
    
         
            +
                        parser->current_param_name = old_param_name;
         
     | 
| 
       14601 
14823 
     | 
    
         
             
                        pm_do_loop_stack_pop(parser);
         
     | 
| 
       14602 
14824 
     | 
    
         | 
| 
       14603 
14825 
     | 
    
         
             
                        if (!PM_NODE_TYPE_P(constant_path, PM_CONSTANT_PATH_NODE) && !(PM_NODE_TYPE_P(constant_path, PM_CONSTANT_READ_NODE))) {
         
     | 
| 
         @@ -14613,12 +14835,16 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14613 
14835 
     | 
    
         
             
                        pm_token_t operator = not_provided(parser);
         
     | 
| 
       14614 
14836 
     | 
    
         
             
                        pm_token_t name = (pm_token_t) { .type = PM_TOKEN_MISSING, .start = def_keyword.end, .end = def_keyword.end };
         
     | 
| 
       14615 
14837 
     | 
    
         | 
| 
      
 14838 
     | 
    
         
            +
                        // This context is necessary for lexing `...` in a bare params correctly.
         
     | 
| 
      
 14839 
     | 
    
         
            +
                        // It must be pushed before lexing the first param, so it is here.
         
     | 
| 
       14616 
14840 
     | 
    
         
             
                        context_push(parser, PM_CONTEXT_DEF_PARAMS);
         
     | 
| 
       14617 
14841 
     | 
    
         
             
                        parser_lex(parser);
         
     | 
| 
      
 14842 
     | 
    
         
            +
                        pm_constant_id_t old_param_name = parser->current_param_name;
         
     | 
| 
       14618 
14843 
     | 
    
         | 
| 
       14619 
14844 
     | 
    
         
             
                        switch (parser->current.type) {
         
     | 
| 
       14620 
14845 
     | 
    
         
             
                            case PM_CASE_OPERATOR:
         
     | 
| 
       14621 
14846 
     | 
    
         
             
                                pm_parser_scope_push(parser, true);
         
     | 
| 
      
 14847 
     | 
    
         
            +
                                parser->current_param_name = 0;
         
     | 
| 
       14622 
14848 
     | 
    
         
             
                                lex_state_set(parser, PM_LEX_STATE_ENDFN);
         
     | 
| 
       14623 
14849 
     | 
    
         
             
                                parser_lex(parser);
         
     | 
| 
       14624 
14850 
     | 
    
         
             
                                name = parser->previous;
         
     | 
| 
         @@ -14630,6 +14856,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14630 
14856 
     | 
    
         
             
                                    receiver = parse_variable_call(parser);
         
     | 
| 
       14631 
14857 
     | 
    
         | 
| 
       14632 
14858 
     | 
    
         
             
                                    pm_parser_scope_push(parser, true);
         
     | 
| 
      
 14859 
     | 
    
         
            +
                                    parser->current_param_name = 0;
         
     | 
| 
       14633 
14860 
     | 
    
         
             
                                    lex_state_set(parser, PM_LEX_STATE_FNAME);
         
     | 
| 
       14634 
14861 
     | 
    
         
             
                                    parser_lex(parser);
         
     | 
| 
       14635 
14862 
     | 
    
         | 
| 
         @@ -14638,6 +14865,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14638 
14865 
     | 
    
         
             
                                } else {
         
     | 
| 
       14639 
14866 
     | 
    
         
             
                                    pm_refute_numbered_parameter(parser, parser->previous.start, parser->previous.end);
         
     | 
| 
       14640 
14867 
     | 
    
         
             
                                    pm_parser_scope_push(parser, true);
         
     | 
| 
      
 14868 
     | 
    
         
            +
                                    parser->current_param_name = 0;
         
     | 
| 
       14641 
14869 
     | 
    
         
             
                                    name = parser->previous;
         
     | 
| 
       14642 
14870 
     | 
    
         
             
                                }
         
     | 
| 
       14643 
14871 
     | 
    
         | 
| 
         @@ -14655,6 +14883,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14655 
14883 
     | 
    
         
             
                            case PM_TOKEN_KEYWORD___LINE__:
         
     | 
| 
       14656 
14884 
     | 
    
         
             
                            case PM_TOKEN_KEYWORD___ENCODING__: {
         
     | 
| 
       14657 
14885 
     | 
    
         
             
                                pm_parser_scope_push(parser, true);
         
     | 
| 
      
 14886 
     | 
    
         
            +
                                parser->current_param_name = 0;
         
     | 
| 
       14658 
14887 
     | 
    
         
             
                                parser_lex(parser);
         
     | 
| 
       14659 
14888 
     | 
    
         
             
                                pm_token_t identifier = parser->previous;
         
     | 
| 
       14660 
14889 
     | 
    
         | 
| 
         @@ -14708,9 +14937,14 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14708 
14937 
     | 
    
         
             
                                break;
         
     | 
| 
       14709 
14938 
     | 
    
         
             
                            }
         
     | 
| 
       14710 
14939 
     | 
    
         
             
                            case PM_TOKEN_PARENTHESIS_LEFT: {
         
     | 
| 
      
 14940 
     | 
    
         
            +
                                // The current context is `PM_CONTEXT_DEF_PARAMS`, however the inner expression
         
     | 
| 
      
 14941 
     | 
    
         
            +
                                // of this parenthesis should not be processed under this context.
         
     | 
| 
      
 14942 
     | 
    
         
            +
                                // Thus, the context is popped here.
         
     | 
| 
      
 14943 
     | 
    
         
            +
                                context_pop(parser);
         
     | 
| 
       14711 
14944 
     | 
    
         
             
                                parser_lex(parser);
         
     | 
| 
      
 14945 
     | 
    
         
            +
             
     | 
| 
       14712 
14946 
     | 
    
         
             
                                pm_token_t lparen = parser->previous;
         
     | 
| 
       14713 
     | 
    
         
            -
                                pm_node_t *expression = parse_value_expression(parser, PM_BINDING_POWER_STATEMENT, PM_ERR_DEF_RECEIVER);
         
     | 
| 
      
 14947 
     | 
    
         
            +
                                pm_node_t *expression = parse_value_expression(parser, PM_BINDING_POWER_STATEMENT, true, PM_ERR_DEF_RECEIVER);
         
     | 
| 
       14714 
14948 
     | 
    
         | 
| 
       14715 
14949 
     | 
    
         
             
                                expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_EXPECT_RPAREN);
         
     | 
| 
       14716 
14950 
     | 
    
         
             
                                pm_token_t rparen = parser->previous;
         
     | 
| 
         @@ -14722,11 +14956,16 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14722 
14956 
     | 
    
         
             
                                receiver = (pm_node_t *) pm_parentheses_node_create(parser, &lparen, expression, &rparen);
         
     | 
| 
       14723 
14957 
     | 
    
         | 
| 
       14724 
14958 
     | 
    
         
             
                                pm_parser_scope_push(parser, true);
         
     | 
| 
      
 14959 
     | 
    
         
            +
                                parser->current_param_name = 0;
         
     | 
| 
      
 14960 
     | 
    
         
            +
             
     | 
| 
      
 14961 
     | 
    
         
            +
                                // To push `PM_CONTEXT_DEF_PARAMS` again is for the same reason as described the above.
         
     | 
| 
      
 14962 
     | 
    
         
            +
                                context_push(parser, PM_CONTEXT_DEF_PARAMS);
         
     | 
| 
       14725 
14963 
     | 
    
         
             
                                name = parse_method_definition_name(parser);
         
     | 
| 
       14726 
14964 
     | 
    
         
             
                                break;
         
     | 
| 
       14727 
14965 
     | 
    
         
             
                            }
         
     | 
| 
       14728 
14966 
     | 
    
         
             
                            default:
         
     | 
| 
       14729 
14967 
     | 
    
         
             
                                pm_parser_scope_push(parser, true);
         
     | 
| 
      
 14968 
     | 
    
         
            +
                                parser->current_param_name = 0;
         
     | 
| 
       14730 
14969 
     | 
    
         
             
                                name = parse_method_definition_name(parser);
         
     | 
| 
       14731 
14970 
     | 
    
         
             
                                break;
         
     | 
| 
       14732 
14971 
     | 
    
         
             
                        }
         
     | 
| 
         @@ -14779,6 +15018,8 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14779 
15018 
     | 
    
         
             
                            }
         
     | 
| 
       14780 
15019 
     | 
    
         
             
                        }
         
     | 
| 
       14781 
15020 
     | 
    
         | 
| 
      
 15021 
     | 
    
         
            +
                        uint32_t locals_body_index = (uint32_t) parser->current_scope->locals.size;
         
     | 
| 
      
 15022 
     | 
    
         
            +
             
     | 
| 
       14782 
15023 
     | 
    
         
             
                        context_pop(parser);
         
     | 
| 
       14783 
15024 
     | 
    
         
             
                        pm_node_t *statements = NULL;
         
     | 
| 
       14784 
15025 
     | 
    
         
             
                        pm_token_t equal;
         
     | 
| 
         @@ -14794,11 +15035,11 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14794 
15035 
     | 
    
         
             
                            pm_do_loop_stack_push(parser, false);
         
     | 
| 
       14795 
15036 
     | 
    
         
             
                            statements = (pm_node_t *) pm_statements_node_create(parser);
         
     | 
| 
       14796 
15037 
     | 
    
         | 
| 
       14797 
     | 
    
         
            -
                            pm_node_t *statement = parse_expression(parser, PM_BINDING_POWER_DEFINED + 1, PM_ERR_DEF_ENDLESS);
         
     | 
| 
      
 15038 
     | 
    
         
            +
                            pm_node_t *statement = parse_expression(parser, PM_BINDING_POWER_DEFINED + 1, binding_power < PM_BINDING_POWER_COMPOSITION, PM_ERR_DEF_ENDLESS);
         
     | 
| 
       14798 
15039 
     | 
    
         | 
| 
       14799 
15040 
     | 
    
         
             
                            if (accept1(parser, PM_TOKEN_KEYWORD_RESCUE_MODIFIER)) {
         
     | 
| 
       14800 
15041 
     | 
    
         
             
                                pm_token_t rescue_keyword = parser->previous;
         
     | 
| 
       14801 
     | 
    
         
            -
                                pm_node_t *value = parse_expression(parser, binding_power, PM_ERR_RESCUE_MODIFIER_VALUE);
         
     | 
| 
      
 15042 
     | 
    
         
            +
                                pm_node_t *value = parse_expression(parser, binding_power, false, PM_ERR_RESCUE_MODIFIER_VALUE);
         
     | 
| 
       14802 
15043 
     | 
    
         
             
                                pm_rescue_modifier_node_t *rescue_node = pm_rescue_modifier_node_create(parser, statement, &rescue_keyword, value);
         
     | 
| 
       14803 
15044 
     | 
    
         
             
                                statement = (pm_node_t *)rescue_node;
         
     | 
| 
       14804 
15045 
     | 
    
         
             
                            }
         
     | 
| 
         @@ -14829,7 +15070,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14829 
15070 
     | 
    
         | 
| 
       14830 
15071 
     | 
    
         
             
                            if (match2(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) {
         
     | 
| 
       14831 
15072 
     | 
    
         
             
                                assert(statements == NULL || PM_NODE_TYPE_P(statements, PM_STATEMENTS_NODE));
         
     | 
| 
       14832 
     | 
    
         
            -
                                statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements);
         
     | 
| 
      
 15073 
     | 
    
         
            +
                                statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements, true);
         
     | 
| 
       14833 
15074 
     | 
    
         
             
                            }
         
     | 
| 
       14834 
15075 
     | 
    
         | 
| 
       14835 
15076 
     | 
    
         
             
                            pm_accepts_block_stack_pop(parser);
         
     | 
| 
         @@ -14839,6 +15080,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14839 
15080 
     | 
    
         
             
                        }
         
     | 
| 
       14840 
15081 
     | 
    
         | 
| 
       14841 
15082 
     | 
    
         
             
                        pm_constant_id_list_t locals = parser->current_scope->locals;
         
     | 
| 
      
 15083 
     | 
    
         
            +
                        parser->current_param_name = old_param_name;
         
     | 
| 
       14842 
15084 
     | 
    
         
             
                        pm_parser_scope_pop(parser);
         
     | 
| 
       14843 
15085 
     | 
    
         | 
| 
       14844 
15086 
     | 
    
         
             
                        return (pm_node_t *) pm_def_node_create(
         
     | 
| 
         @@ -14848,6 +15090,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14848 
15090 
     | 
    
         
             
                            params,
         
     | 
| 
       14849 
15091 
     | 
    
         
             
                            statements,
         
     | 
| 
       14850 
15092 
     | 
    
         
             
                            &locals,
         
     | 
| 
      
 15093 
     | 
    
         
            +
                            locals_body_index,
         
     | 
| 
       14851 
15094 
     | 
    
         
             
                            &def_keyword,
         
     | 
| 
       14852 
15095 
     | 
    
         
             
                            &operator,
         
     | 
| 
       14853 
15096 
     | 
    
         
             
                            &lparen,
         
     | 
| 
         @@ -14866,18 +15109,19 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14866 
15109 
     | 
    
         | 
| 
       14867 
15110 
     | 
    
         
             
                        if (accept1(parser, PM_TOKEN_PARENTHESIS_LEFT)) {
         
     | 
| 
       14868 
15111 
     | 
    
         
             
                            lparen = parser->previous;
         
     | 
| 
       14869 
     | 
    
         
            -
                            expression = parse_expression(parser, PM_BINDING_POWER_COMPOSITION, PM_ERR_DEFINED_EXPRESSION);
         
     | 
| 
      
 15112 
     | 
    
         
            +
                            expression = parse_expression(parser, PM_BINDING_POWER_COMPOSITION, true, PM_ERR_DEFINED_EXPRESSION);
         
     | 
| 
       14870 
15113 
     | 
    
         | 
| 
       14871 
15114 
     | 
    
         
             
                            if (parser->recovering) {
         
     | 
| 
       14872 
15115 
     | 
    
         
             
                                rparen = not_provided(parser);
         
     | 
| 
       14873 
15116 
     | 
    
         
             
                            } else {
         
     | 
| 
      
 15117 
     | 
    
         
            +
                                accept1(parser, PM_TOKEN_NEWLINE);
         
     | 
| 
       14874 
15118 
     | 
    
         
             
                                expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_EXPECT_RPAREN);
         
     | 
| 
       14875 
15119 
     | 
    
         
             
                                rparen = parser->previous;
         
     | 
| 
       14876 
15120 
     | 
    
         
             
                            }
         
     | 
| 
       14877 
15121 
     | 
    
         
             
                        } else {
         
     | 
| 
       14878 
15122 
     | 
    
         
             
                            lparen = not_provided(parser);
         
     | 
| 
       14879 
15123 
     | 
    
         
             
                            rparen = not_provided(parser);
         
     | 
| 
       14880 
     | 
    
         
            -
                            expression = parse_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_DEFINED_EXPRESSION);
         
     | 
| 
      
 15124 
     | 
    
         
            +
                            expression = parse_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_DEFINED_EXPRESSION);
         
     | 
| 
       14881 
15125 
     | 
    
         
             
                        }
         
     | 
| 
       14882 
15126 
     | 
    
         | 
| 
       14883 
15127 
     | 
    
         
             
                        return (pm_node_t *) pm_defined_node_create(
         
     | 
| 
         @@ -14889,6 +15133,10 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14889 
15133 
     | 
    
         
             
                        );
         
     | 
| 
       14890 
15134 
     | 
    
         
             
                    }
         
     | 
| 
       14891 
15135 
     | 
    
         
             
                    case PM_TOKEN_KEYWORD_END_UPCASE: {
         
     | 
| 
      
 15136 
     | 
    
         
            +
                        if (binding_power != PM_BINDING_POWER_STATEMENT) {
         
     | 
| 
      
 15137 
     | 
    
         
            +
                            pm_parser_err_current(parser, PM_ERR_STATEMENT_POSTEXE_END);
         
     | 
| 
      
 15138 
     | 
    
         
            +
                        }
         
     | 
| 
      
 15139 
     | 
    
         
            +
             
     | 
| 
       14892 
15140 
     | 
    
         
             
                        parser_lex(parser);
         
     | 
| 
       14893 
15141 
     | 
    
         
             
                        pm_token_t keyword = parser->previous;
         
     | 
| 
       14894 
15142 
     | 
    
         | 
| 
         @@ -14911,7 +15159,6 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14911 
15159 
     | 
    
         
             
                        pm_token_t for_keyword = parser->previous;
         
     | 
| 
       14912 
15160 
     | 
    
         
             
                        pm_node_t *index;
         
     | 
| 
       14913 
15161 
     | 
    
         | 
| 
       14914 
     | 
    
         
            -
                        pm_parser_scope_push_transparent(parser);
         
     | 
| 
       14915 
15162 
     | 
    
         
             
                        context_push(parser, PM_CONTEXT_FOR_INDEX);
         
     | 
| 
       14916 
15163 
     | 
    
         | 
| 
       14917 
15164 
     | 
    
         
             
                        // First, parse out the first index expression.
         
     | 
| 
         @@ -14920,12 +15167,12 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14920 
15167 
     | 
    
         
             
                            pm_node_t *name = NULL;
         
     | 
| 
       14921 
15168 
     | 
    
         | 
| 
       14922 
15169 
     | 
    
         
             
                            if (token_begins_expression_p(parser->current.type)) {
         
     | 
| 
       14923 
     | 
    
         
            -
                                name = parse_expression(parser, PM_BINDING_POWER_INDEX, PM_ERR_EXPECT_EXPRESSION_AFTER_STAR);
         
     | 
| 
      
 15170 
     | 
    
         
            +
                                name = parse_expression(parser, PM_BINDING_POWER_INDEX, false, PM_ERR_EXPECT_EXPRESSION_AFTER_STAR);
         
     | 
| 
       14924 
15171 
     | 
    
         
             
                            }
         
     | 
| 
       14925 
15172 
     | 
    
         | 
| 
       14926 
15173 
     | 
    
         
             
                            index = (pm_node_t *) pm_splat_node_create(parser, &star_operator, name);
         
     | 
| 
       14927 
15174 
     | 
    
         
             
                        } else if (token_begins_expression_p(parser->current.type)) {
         
     | 
| 
       14928 
     | 
    
         
            -
                            index = parse_expression(parser, PM_BINDING_POWER_INDEX, PM_ERR_EXPECT_EXPRESSION_AFTER_COMMA);
         
     | 
| 
      
 15175 
     | 
    
         
            +
                            index = parse_expression(parser, PM_BINDING_POWER_INDEX, false, PM_ERR_EXPECT_EXPRESSION_AFTER_COMMA);
         
     | 
| 
       14929 
15176 
     | 
    
         
             
                        } else {
         
     | 
| 
       14930 
15177 
     | 
    
         
             
                            pm_parser_err_token(parser, &for_keyword, PM_ERR_FOR_INDEX);
         
     | 
| 
       14931 
15178 
     | 
    
         
             
                            index = (pm_node_t *) pm_missing_node_create(parser, for_keyword.start, for_keyword.end);
         
     | 
| 
         @@ -14939,13 +15186,12 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14939 
15186 
     | 
    
         
             
                        }
         
     | 
| 
       14940 
15187 
     | 
    
         | 
| 
       14941 
15188 
     | 
    
         
             
                        context_pop(parser);
         
     | 
| 
       14942 
     | 
    
         
            -
                        pm_parser_scope_pop(parser);
         
     | 
| 
       14943 
15189 
     | 
    
         
             
                        pm_do_loop_stack_push(parser, true);
         
     | 
| 
       14944 
15190 
     | 
    
         | 
| 
       14945 
15191 
     | 
    
         
             
                        expect1(parser, PM_TOKEN_KEYWORD_IN, PM_ERR_FOR_IN);
         
     | 
| 
       14946 
15192 
     | 
    
         
             
                        pm_token_t in_keyword = parser->previous;
         
     | 
| 
       14947 
15193 
     | 
    
         | 
| 
       14948 
     | 
    
         
            -
                        pm_node_t *collection = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, PM_ERR_FOR_COLLECTION);
         
     | 
| 
      
 15194 
     | 
    
         
            +
                        pm_node_t *collection = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, true, PM_ERR_FOR_COLLECTION);
         
     | 
| 
       14949 
15195 
     | 
    
         
             
                        pm_do_loop_stack_pop(parser);
         
     | 
| 
       14950 
15196 
     | 
    
         | 
| 
       14951 
15197 
     | 
    
         
             
                        pm_token_t do_keyword;
         
     | 
| 
         @@ -14959,10 +15205,8 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14959 
15205 
     | 
    
         
             
                        pm_statements_node_t *statements = NULL;
         
     | 
| 
       14960 
15206 
     | 
    
         | 
| 
       14961 
15207 
     | 
    
         
             
                        if (!accept1(parser, PM_TOKEN_KEYWORD_END)) {
         
     | 
| 
       14962 
     | 
    
         
            -
                            pm_parser_scope_push_transparent(parser);
         
     | 
| 
       14963 
15208 
     | 
    
         
             
                            statements = parse_statements(parser, PM_CONTEXT_FOR);
         
     | 
| 
       14964 
15209 
     | 
    
         
             
                            expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_FOR_TERM);
         
     | 
| 
       14965 
     | 
    
         
            -
                            pm_parser_scope_pop(parser);
         
     | 
| 
       14966 
15210 
     | 
    
         
             
                        }
         
     | 
| 
       14967 
15211 
     | 
    
         | 
| 
       14968 
15212 
     | 
    
         
             
                        return (pm_node_t *) pm_for_node_create(parser, index, collection, statements, &for_keyword, &in_keyword, &do_keyword, &parser->previous);
         
     | 
| 
         @@ -14971,6 +15215,10 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       14971 
15215 
     | 
    
         
             
                        parser_lex(parser);
         
     | 
| 
       14972 
15216 
     | 
    
         
             
                        return parse_conditional(parser, PM_CONTEXT_IF);
         
     | 
| 
       14973 
15217 
     | 
    
         
             
                    case PM_TOKEN_KEYWORD_UNDEF: {
         
     | 
| 
      
 15218 
     | 
    
         
            +
                        if (binding_power != PM_BINDING_POWER_STATEMENT) {
         
     | 
| 
      
 15219 
     | 
    
         
            +
                            pm_parser_err_current(parser, PM_ERR_STATEMENT_UNDEF);
         
     | 
| 
      
 15220 
     | 
    
         
            +
                        }
         
     | 
| 
      
 15221 
     | 
    
         
            +
             
     | 
| 
       14974 
15222 
     | 
    
         
             
                        parser_lex(parser);
         
     | 
| 
       14975 
15223 
     | 
    
         
             
                        pm_undef_node_t *undef = pm_undef_node_create(parser, &parser->previous);
         
     | 
| 
       14976 
15224 
     | 
    
         
             
                        pm_node_t *name = parse_undef_argument(parser);
         
     | 
| 
         @@ -15011,7 +15259,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       15011 
15259 
     | 
    
         
             
                            if (accept1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) {
         
     | 
| 
       15012 
15260 
     | 
    
         
             
                                arguments.closing_loc = PM_LOCATION_TOKEN_VALUE(&parser->previous);
         
     | 
| 
       15013 
15261 
     | 
    
         
             
                            } else {
         
     | 
| 
       15014 
     | 
    
         
            -
                                receiver = parse_expression(parser, PM_BINDING_POWER_COMPOSITION, PM_ERR_NOT_EXPRESSION);
         
     | 
| 
      
 15262 
     | 
    
         
            +
                                receiver = parse_expression(parser, PM_BINDING_POWER_COMPOSITION, true, PM_ERR_NOT_EXPRESSION);
         
     | 
| 
       15015 
15263 
     | 
    
         
             
                                pm_conditional_predicate(receiver);
         
     | 
| 
       15016 
15264 
     | 
    
         | 
| 
       15017 
15265 
     | 
    
         
             
                                if (!parser->recovering) {
         
     | 
| 
         @@ -15021,7 +15269,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       15021 
15269 
     | 
    
         
             
                                }
         
     | 
| 
       15022 
15270 
     | 
    
         
             
                            }
         
     | 
| 
       15023 
15271 
     | 
    
         
             
                        } else {
         
     | 
| 
       15024 
     | 
    
         
            -
                            receiver = parse_expression(parser,  
     | 
| 
      
 15272 
     | 
    
         
            +
                            receiver = parse_expression(parser, PM_BINDING_POWER_NOT, true, PM_ERR_NOT_EXPRESSION);
         
     | 
| 
       15025 
15273 
     | 
    
         
             
                            pm_conditional_predicate(receiver);
         
     | 
| 
       15026 
15274 
     | 
    
         
             
                        }
         
     | 
| 
       15027 
15275 
     | 
    
         | 
| 
         @@ -15034,7 +15282,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       15034 
15282 
     | 
    
         
             
                        parser_lex(parser);
         
     | 
| 
       15035 
15283 
     | 
    
         | 
| 
       15036 
15284 
     | 
    
         
             
                        pm_token_t module_keyword = parser->previous;
         
     | 
| 
       15037 
     | 
    
         
            -
                        pm_node_t *constant_path = parse_expression(parser, PM_BINDING_POWER_INDEX, PM_ERR_MODULE_NAME);
         
     | 
| 
      
 15285 
     | 
    
         
            +
                        pm_node_t *constant_path = parse_expression(parser, PM_BINDING_POWER_INDEX, false, PM_ERR_MODULE_NAME);
         
     | 
| 
       15038 
15286 
     | 
    
         
             
                        pm_token_t name;
         
     | 
| 
       15039 
15287 
     | 
    
         | 
| 
       15040 
15288 
     | 
    
         
             
                        // If we can recover from a syntax error that occurred while parsing
         
     | 
| 
         @@ -15061,6 +15309,8 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       15061 
15309 
     | 
    
         
             
                            pm_parser_err_token(parser, &name, PM_ERR_MODULE_NAME);
         
     | 
| 
       15062 
15310 
     | 
    
         
             
                        }
         
     | 
| 
       15063 
15311 
     | 
    
         | 
| 
      
 15312 
     | 
    
         
            +
                        pm_constant_id_t old_param_name = parser->current_param_name;
         
     | 
| 
      
 15313 
     | 
    
         
            +
                        parser->current_param_name = 0;
         
     | 
| 
       15064 
15314 
     | 
    
         
             
                        pm_parser_scope_push(parser, true);
         
     | 
| 
       15065 
15315 
     | 
    
         
             
                        accept2(parser, PM_TOKEN_SEMICOLON, PM_TOKEN_NEWLINE);
         
     | 
| 
       15066 
15316 
     | 
    
         
             
                        pm_node_t *statements = NULL;
         
     | 
| 
         @@ -15073,11 +15323,12 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       15073 
15323 
     | 
    
         | 
| 
       15074 
15324 
     | 
    
         
             
                        if (match2(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) {
         
     | 
| 
       15075 
15325 
     | 
    
         
             
                            assert(statements == NULL || PM_NODE_TYPE_P(statements, PM_STATEMENTS_NODE));
         
     | 
| 
       15076 
     | 
    
         
            -
                            statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements);
         
     | 
| 
      
 15326 
     | 
    
         
            +
                            statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements, false);
         
     | 
| 
       15077 
15327 
     | 
    
         
             
                        }
         
     | 
| 
       15078 
15328 
     | 
    
         | 
| 
       15079 
15329 
     | 
    
         
             
                        pm_constant_id_list_t locals = parser->current_scope->locals;
         
     | 
| 
       15080 
15330 
     | 
    
         
             
                        pm_parser_scope_pop(parser);
         
     | 
| 
      
 15331 
     | 
    
         
            +
                        parser->current_param_name = old_param_name;
         
     | 
| 
       15081 
15332 
     | 
    
         | 
| 
       15082 
15333 
     | 
    
         
             
                        expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_MODULE_TERM);
         
     | 
| 
       15083 
15334 
     | 
    
         | 
| 
         @@ -15107,7 +15358,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       15107 
15358 
     | 
    
         
             
                        parser_lex(parser);
         
     | 
| 
       15108 
15359 
     | 
    
         
             
                        pm_token_t keyword = parser->previous;
         
     | 
| 
       15109 
15360 
     | 
    
         | 
| 
       15110 
     | 
    
         
            -
                        pm_node_t *predicate = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, PM_ERR_CONDITIONAL_UNTIL_PREDICATE);
         
     | 
| 
      
 15361 
     | 
    
         
            +
                        pm_node_t *predicate = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, true, PM_ERR_CONDITIONAL_UNTIL_PREDICATE);
         
     | 
| 
       15111 
15362 
     | 
    
         
             
                        pm_do_loop_stack_pop(parser);
         
     | 
| 
       15112 
15363 
     | 
    
         | 
| 
       15113 
15364 
     | 
    
         
             
                        expect3(parser, PM_TOKEN_KEYWORD_DO_LOOP, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON, PM_ERR_CONDITIONAL_UNTIL_PREDICATE);
         
     | 
| 
         @@ -15128,7 +15379,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       15128 
15379 
     | 
    
         
             
                        parser_lex(parser);
         
     | 
| 
       15129 
15380 
     | 
    
         
             
                        pm_token_t keyword = parser->previous;
         
     | 
| 
       15130 
15381 
     | 
    
         | 
| 
       15131 
     | 
    
         
            -
                        pm_node_t *predicate = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, PM_ERR_CONDITIONAL_WHILE_PREDICATE);
         
     | 
| 
      
 15382 
     | 
    
         
            +
                        pm_node_t *predicate = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, true, PM_ERR_CONDITIONAL_WHILE_PREDICATE);
         
     | 
| 
       15132 
15383 
     | 
    
         
             
                        pm_do_loop_stack_pop(parser);
         
     | 
| 
       15133 
15384 
     | 
    
         | 
| 
       15134 
15385 
     | 
    
         
             
                        expect3(parser, PM_TOKEN_KEYWORD_DO_LOOP, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON, PM_ERR_CONDITIONAL_WHILE_PREDICATE);
         
     | 
| 
         @@ -15146,7 +15397,8 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       15146 
15397 
     | 
    
         
             
                    }
         
     | 
| 
       15147 
15398 
     | 
    
         
             
                    case PM_TOKEN_PERCENT_LOWER_I: {
         
     | 
| 
       15148 
15399 
     | 
    
         
             
                        parser_lex(parser);
         
     | 
| 
       15149 
     | 
    
         
            -
                         
     | 
| 
      
 15400 
     | 
    
         
            +
                        pm_token_t opening = parser->previous;
         
     | 
| 
      
 15401 
     | 
    
         
            +
                        pm_array_node_t *array = pm_array_node_create(parser, &opening);
         
     | 
| 
       15150 
15402 
     | 
    
         | 
| 
       15151 
15403 
     | 
    
         
             
                        while (!match2(parser, PM_TOKEN_STRING_END, PM_TOKEN_EOF)) {
         
     | 
| 
       15152 
15404 
     | 
    
         
             
                            accept1(parser, PM_TOKEN_WORDS_SEP);
         
     | 
| 
         @@ -15161,14 +15413,21 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       15161 
15413 
     | 
    
         
             
                            expect1(parser, PM_TOKEN_STRING_CONTENT, PM_ERR_LIST_I_LOWER_ELEMENT);
         
     | 
| 
       15162 
15414 
     | 
    
         
             
                        }
         
     | 
| 
       15163 
15415 
     | 
    
         | 
| 
       15164 
     | 
    
         
            -
                         
     | 
| 
       15165 
     | 
    
         
            -
                         
     | 
| 
      
 15416 
     | 
    
         
            +
                        pm_token_t closing = parser->current;
         
     | 
| 
      
 15417 
     | 
    
         
            +
                        if (match1(parser, PM_TOKEN_EOF)) {
         
     | 
| 
      
 15418 
     | 
    
         
            +
                            pm_parser_err_token(parser, &opening, PM_ERR_LIST_I_LOWER_TERM);
         
     | 
| 
      
 15419 
     | 
    
         
            +
                            closing = (pm_token_t) { .type = PM_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end };
         
     | 
| 
      
 15420 
     | 
    
         
            +
                        } else {
         
     | 
| 
      
 15421 
     | 
    
         
            +
                            expect1(parser, PM_TOKEN_STRING_END, PM_ERR_LIST_I_LOWER_TERM);
         
     | 
| 
      
 15422 
     | 
    
         
            +
                        }
         
     | 
| 
      
 15423 
     | 
    
         
            +
                        pm_array_node_close_set(array, &closing);
         
     | 
| 
       15166 
15424 
     | 
    
         | 
| 
       15167 
15425 
     | 
    
         
             
                        return (pm_node_t *) array;
         
     | 
| 
       15168 
15426 
     | 
    
         
             
                    }
         
     | 
| 
       15169 
15427 
     | 
    
         
             
                    case PM_TOKEN_PERCENT_UPPER_I: {
         
     | 
| 
       15170 
15428 
     | 
    
         
             
                        parser_lex(parser);
         
     | 
| 
       15171 
     | 
    
         
            -
                         
     | 
| 
      
 15429 
     | 
    
         
            +
                        pm_token_t opening = parser->previous;
         
     | 
| 
      
 15430 
     | 
    
         
            +
                        pm_array_node_t *array = pm_array_node_create(parser, &opening);
         
     | 
| 
       15172 
15431 
     | 
    
         | 
| 
       15173 
15432 
     | 
    
         
             
                        // This is the current node that we are parsing that will be added to the
         
     | 
| 
       15174 
15433 
     | 
    
         
             
                        // list of elements.
         
     | 
| 
         @@ -15308,14 +15567,21 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       15308 
15567 
     | 
    
         
             
                            pm_array_node_elements_append(array, current);
         
     | 
| 
       15309 
15568 
     | 
    
         
             
                        }
         
     | 
| 
       15310 
15569 
     | 
    
         | 
| 
       15311 
     | 
    
         
            -
                         
     | 
| 
       15312 
     | 
    
         
            -
                         
     | 
| 
      
 15570 
     | 
    
         
            +
                        pm_token_t closing = parser->current;
         
     | 
| 
      
 15571 
     | 
    
         
            +
                        if (match1(parser, PM_TOKEN_EOF)) {
         
     | 
| 
      
 15572 
     | 
    
         
            +
                            pm_parser_err_token(parser, &opening, PM_ERR_LIST_I_UPPER_TERM);
         
     | 
| 
      
 15573 
     | 
    
         
            +
                            closing = (pm_token_t) { .type = PM_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end };
         
     | 
| 
      
 15574 
     | 
    
         
            +
                        } else {
         
     | 
| 
      
 15575 
     | 
    
         
            +
                            expect1(parser, PM_TOKEN_STRING_END, PM_ERR_LIST_I_UPPER_TERM);
         
     | 
| 
      
 15576 
     | 
    
         
            +
                        }
         
     | 
| 
      
 15577 
     | 
    
         
            +
                        pm_array_node_close_set(array, &closing);
         
     | 
| 
       15313 
15578 
     | 
    
         | 
| 
       15314 
15579 
     | 
    
         
             
                        return (pm_node_t *) array;
         
     | 
| 
       15315 
15580 
     | 
    
         
             
                    }
         
     | 
| 
       15316 
15581 
     | 
    
         
             
                    case PM_TOKEN_PERCENT_LOWER_W: {
         
     | 
| 
       15317 
15582 
     | 
    
         
             
                        parser_lex(parser);
         
     | 
| 
       15318 
     | 
    
         
            -
                         
     | 
| 
      
 15583 
     | 
    
         
            +
                        pm_token_t opening = parser->previous;
         
     | 
| 
      
 15584 
     | 
    
         
            +
                        pm_array_node_t *array = pm_array_node_create(parser, &opening);
         
     | 
| 
       15319 
15585 
     | 
    
         | 
| 
       15320 
15586 
     | 
    
         
             
                        // skip all leading whitespaces
         
     | 
| 
       15321 
15587 
     | 
    
         
             
                        accept1(parser, PM_TOKEN_WORDS_SEP);
         
     | 
| 
         @@ -15335,28 +15601,40 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       15335 
15601 
     | 
    
         
             
                            expect1(parser, PM_TOKEN_STRING_CONTENT, PM_ERR_LIST_W_LOWER_ELEMENT);
         
     | 
| 
       15336 
15602 
     | 
    
         
             
                        }
         
     | 
| 
       15337 
15603 
     | 
    
         | 
| 
       15338 
     | 
    
         
            -
                         
     | 
| 
       15339 
     | 
    
         
            -
                         
     | 
| 
      
 15604 
     | 
    
         
            +
                        pm_token_t closing = parser->current;
         
     | 
| 
      
 15605 
     | 
    
         
            +
                        if (match1(parser, PM_TOKEN_EOF)) {
         
     | 
| 
      
 15606 
     | 
    
         
            +
                            pm_parser_err_token(parser, &opening, PM_ERR_LIST_W_LOWER_TERM);
         
     | 
| 
      
 15607 
     | 
    
         
            +
                            closing = (pm_token_t) { .type = PM_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end };
         
     | 
| 
      
 15608 
     | 
    
         
            +
                        } else {
         
     | 
| 
      
 15609 
     | 
    
         
            +
                            expect1(parser, PM_TOKEN_STRING_END, PM_ERR_LIST_W_LOWER_TERM);
         
     | 
| 
      
 15610 
     | 
    
         
            +
                        }
         
     | 
| 
       15340 
15611 
     | 
    
         | 
| 
      
 15612 
     | 
    
         
            +
                        pm_array_node_close_set(array, &closing);
         
     | 
| 
       15341 
15613 
     | 
    
         
             
                        return (pm_node_t *) array;
         
     | 
| 
       15342 
15614 
     | 
    
         
             
                    }
         
     | 
| 
       15343 
15615 
     | 
    
         
             
                    case PM_TOKEN_PERCENT_UPPER_W: {
         
     | 
| 
       15344 
15616 
     | 
    
         
             
                        parser_lex(parser);
         
     | 
| 
       15345 
     | 
    
         
            -
                         
     | 
| 
      
 15617 
     | 
    
         
            +
                        pm_token_t opening = parser->previous;
         
     | 
| 
      
 15618 
     | 
    
         
            +
                        pm_array_node_t *array = pm_array_node_create(parser, &opening);
         
     | 
| 
       15346 
15619 
     | 
    
         | 
| 
       15347 
     | 
    
         
            -
                        // This is the current node that we are parsing that will be added 
     | 
| 
       15348 
     | 
    
         
            -
                        // list of elements.
         
     | 
| 
      
 15620 
     | 
    
         
            +
                        // This is the current node that we are parsing that will be added
         
     | 
| 
      
 15621 
     | 
    
         
            +
                        // to the list of elements.
         
     | 
| 
       15349 
15622 
     | 
    
         
             
                        pm_node_t *current = NULL;
         
     | 
| 
       15350 
15623 
     | 
    
         | 
| 
       15351 
15624 
     | 
    
         
             
                        while (!match2(parser, PM_TOKEN_STRING_END, PM_TOKEN_EOF)) {
         
     | 
| 
       15352 
15625 
     | 
    
         
             
                            switch (parser->current.type) {
         
     | 
| 
       15353 
15626 
     | 
    
         
             
                                case PM_TOKEN_WORDS_SEP: {
         
     | 
| 
      
 15627 
     | 
    
         
            +
                                    // Reset the explicit encoding if we hit a separator
         
     | 
| 
      
 15628 
     | 
    
         
            +
                                    // since each element can have its own encoding.
         
     | 
| 
      
 15629 
     | 
    
         
            +
                                    parser->explicit_encoding = NULL;
         
     | 
| 
      
 15630 
     | 
    
         
            +
             
     | 
| 
       15354 
15631 
     | 
    
         
             
                                    if (current == NULL) {
         
     | 
| 
       15355 
     | 
    
         
            -
                                        // If we hit a separator before we have any content, 
     | 
| 
       15356 
     | 
    
         
            -
                                        // need to do anything.
         
     | 
| 
      
 15632 
     | 
    
         
            +
                                        // If we hit a separator before we have any content,
         
     | 
| 
      
 15633 
     | 
    
         
            +
                                        // then we don't need to do anything.
         
     | 
| 
       15357 
15634 
     | 
    
         
             
                                    } else {
         
     | 
| 
       15358 
     | 
    
         
            -
                                        // If we hit a separator after we've hit content, 
     | 
| 
       15359 
     | 
    
         
            -
                                        // append that content to the list 
     | 
| 
      
 15635 
     | 
    
         
            +
                                        // If we hit a separator after we've hit content,
         
     | 
| 
      
 15636 
     | 
    
         
            +
                                        // then we need to append that content to the list
         
     | 
| 
      
 15637 
     | 
    
         
            +
                                        // and reset the current node.
         
     | 
| 
       15360 
15638 
     | 
    
         
             
                                        pm_array_node_elements_append(array, current);
         
     | 
| 
       15361 
15639 
     | 
    
         
             
                                        current = NULL;
         
     | 
| 
       15362 
15640 
     | 
    
         
             
                                    }
         
     | 
| 
         @@ -15369,22 +15647,25 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       15369 
15647 
     | 
    
         
             
                                    pm_token_t closing = not_provided(parser);
         
     | 
| 
       15370 
15648 
     | 
    
         | 
| 
       15371 
15649 
     | 
    
         
             
                                    pm_node_t *string = (pm_node_t *) pm_string_node_create_current_string(parser, &opening, &parser->current, &closing);
         
     | 
| 
      
 15650 
     | 
    
         
            +
                                    pm_node_flag_set(string, parse_unescaped_encoding(parser));
         
     | 
| 
       15372 
15651 
     | 
    
         
             
                                    parser_lex(parser);
         
     | 
| 
       15373 
15652 
     | 
    
         | 
| 
       15374 
15653 
     | 
    
         
             
                                    if (current == NULL) {
         
     | 
| 
       15375 
     | 
    
         
            -
                                        // If we hit content and the current node is NULL, 
     | 
| 
       15376 
     | 
    
         
            -
                                        // the first string content we've seen. 
     | 
| 
       15377 
     | 
    
         
            -
                                        // to create a new string 
     | 
| 
      
 15654 
     | 
    
         
            +
                                        // If we hit content and the current node is NULL,
         
     | 
| 
      
 15655 
     | 
    
         
            +
                                        // then this is the first string content we've seen.
         
     | 
| 
      
 15656 
     | 
    
         
            +
                                        // In that case we're going to create a new string
         
     | 
| 
      
 15657 
     | 
    
         
            +
                                        // node and set that to the current.
         
     | 
| 
       15378 
15658 
     | 
    
         
             
                                        current = string;
         
     | 
| 
       15379 
15659 
     | 
    
         
             
                                    } else if (PM_NODE_TYPE_P(current, PM_INTERPOLATED_STRING_NODE)) {
         
     | 
| 
       15380 
     | 
    
         
            -
                                        // If we hit string content and the current node is 
     | 
| 
       15381 
     | 
    
         
            -
                                        // interpolated string, then we need to append 
     | 
| 
       15382 
     | 
    
         
            -
                                        // to the list of child nodes.
         
     | 
| 
      
 15660 
     | 
    
         
            +
                                        // If we hit string content and the current node is
         
     | 
| 
      
 15661 
     | 
    
         
            +
                                        // an interpolated string, then we need to append
         
     | 
| 
      
 15662 
     | 
    
         
            +
                                        // the string content to the list of child nodes.
         
     | 
| 
       15383 
15663 
     | 
    
         
             
                                        pm_interpolated_string_node_append((pm_interpolated_string_node_t *) current, string);
         
     | 
| 
       15384 
15664 
     | 
    
         
             
                                    } else if (PM_NODE_TYPE_P(current, PM_STRING_NODE)) {
         
     | 
| 
       15385 
     | 
    
         
            -
                                        // If we hit string content and the current node is 
     | 
| 
       15386 
     | 
    
         
            -
                                        // then we need to convert the 
     | 
| 
       15387 
     | 
    
         
            -
                                        //  
     | 
| 
      
 15665 
     | 
    
         
            +
                                        // If we hit string content and the current node is
         
     | 
| 
      
 15666 
     | 
    
         
            +
                                        // a string node, then we need to convert the
         
     | 
| 
      
 15667 
     | 
    
         
            +
                                        // current node into an interpolated string and add
         
     | 
| 
      
 15668 
     | 
    
         
            +
                                        // the string content to the list of child nodes.
         
     | 
| 
       15388 
15669 
     | 
    
         
             
                                        pm_interpolated_string_node_t *interpolated = pm_interpolated_string_node_create(parser, &opening, NULL, &closing);
         
     | 
| 
       15389 
15670 
     | 
    
         
             
                                        pm_interpolated_string_node_append(interpolated, current);
         
     | 
| 
       15390 
15671 
     | 
    
         
             
                                        pm_interpolated_string_node_append(interpolated, string);
         
     | 
| 
         @@ -15397,24 +15678,27 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       15397 
15678 
     | 
    
         
             
                                }
         
     | 
| 
       15398 
15679 
     | 
    
         
             
                                case PM_TOKEN_EMBVAR: {
         
     | 
| 
       15399 
15680 
     | 
    
         
             
                                    if (current == NULL) {
         
     | 
| 
       15400 
     | 
    
         
            -
                                        // If we hit an embedded variable and the current 
     | 
| 
       15401 
     | 
    
         
            -
                                        // then this is the start of a new 
     | 
| 
       15402 
     | 
    
         
            -
                                        // node to a new 
     | 
| 
      
 15681 
     | 
    
         
            +
                                        // If we hit an embedded variable and the current
         
     | 
| 
      
 15682 
     | 
    
         
            +
                                        // node is NULL, then this is the start of a new
         
     | 
| 
      
 15683 
     | 
    
         
            +
                                        // string. We'll set the current node to a new
         
     | 
| 
      
 15684 
     | 
    
         
            +
                                        // interpolated string.
         
     | 
| 
       15403 
15685 
     | 
    
         
             
                                        pm_token_t opening = not_provided(parser);
         
     | 
| 
       15404 
15686 
     | 
    
         
             
                                        pm_token_t closing = not_provided(parser);
         
     | 
| 
       15405 
15687 
     | 
    
         
             
                                        current = (pm_node_t *) pm_interpolated_string_node_create(parser, &opening, NULL, &closing);
         
     | 
| 
       15406 
15688 
     | 
    
         
             
                                    } else if (PM_NODE_TYPE_P(current, PM_STRING_NODE)) {
         
     | 
| 
       15407 
     | 
    
         
            -
                                        // If we hit an embedded variable and the current 
     | 
| 
       15408 
     | 
    
         
            -
                                        // node, then we'll convert the 
     | 
| 
       15409 
     | 
    
         
            -
                                        //  
     | 
| 
      
 15689 
     | 
    
         
            +
                                        // If we hit an embedded variable and the current
         
     | 
| 
      
 15690 
     | 
    
         
            +
                                        // node is a string node, then we'll convert the
         
     | 
| 
      
 15691 
     | 
    
         
            +
                                        // current into an interpolated string and add the
         
     | 
| 
      
 15692 
     | 
    
         
            +
                                        // string node to the list of parts.
         
     | 
| 
       15410 
15693 
     | 
    
         
             
                                        pm_token_t opening = not_provided(parser);
         
     | 
| 
       15411 
15694 
     | 
    
         
             
                                        pm_token_t closing = not_provided(parser);
         
     | 
| 
       15412 
15695 
     | 
    
         
             
                                        pm_interpolated_string_node_t *interpolated = pm_interpolated_string_node_create(parser, &opening, NULL, &closing);
         
     | 
| 
       15413 
15696 
     | 
    
         
             
                                        pm_interpolated_string_node_append(interpolated, current);
         
     | 
| 
       15414 
15697 
     | 
    
         
             
                                        current = (pm_node_t *) interpolated;
         
     | 
| 
       15415 
15698 
     | 
    
         
             
                                    } else {
         
     | 
| 
       15416 
     | 
    
         
            -
                                        // If we hit an embedded variable and the current 
     | 
| 
       15417 
     | 
    
         
            -
                                        // interpolated string, then we'll just 
     | 
| 
      
 15699 
     | 
    
         
            +
                                        // If we hit an embedded variable and the current
         
     | 
| 
      
 15700 
     | 
    
         
            +
                                        // node is an interpolated string, then we'll just
         
     | 
| 
      
 15701 
     | 
    
         
            +
                                        // add the embedded variable.
         
     | 
| 
       15418 
15702 
     | 
    
         
             
                                    }
         
     | 
| 
       15419 
15703 
     | 
    
         | 
| 
       15420 
15704 
     | 
    
         
             
                                    pm_node_t *part = parse_string_part(parser);
         
     | 
| 
         @@ -15423,25 +15707,27 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       15423 
15707 
     | 
    
         
             
                                }
         
     | 
| 
       15424 
15708 
     | 
    
         
             
                                case PM_TOKEN_EMBEXPR_BEGIN: {
         
     | 
| 
       15425 
15709 
     | 
    
         
             
                                    if (current == NULL) {
         
     | 
| 
       15426 
     | 
    
         
            -
                                        // If we hit an embedded expression and the current 
     | 
| 
       15427 
     | 
    
         
            -
                                        // then this is the start of a new 
     | 
| 
       15428 
     | 
    
         
            -
                                        // node to a new 
     | 
| 
      
 15710 
     | 
    
         
            +
                                        // If we hit an embedded expression and the current
         
     | 
| 
      
 15711 
     | 
    
         
            +
                                        // node is NULL, then this is the start of a new
         
     | 
| 
      
 15712 
     | 
    
         
            +
                                        // string. We'll set the current node to a new
         
     | 
| 
      
 15713 
     | 
    
         
            +
                                        // interpolated string.
         
     | 
| 
       15429 
15714 
     | 
    
         
             
                                        pm_token_t opening = not_provided(parser);
         
     | 
| 
       15430 
15715 
     | 
    
         
             
                                        pm_token_t closing = not_provided(parser);
         
     | 
| 
       15431 
15716 
     | 
    
         
             
                                        current = (pm_node_t *) pm_interpolated_string_node_create(parser, &opening, NULL, &closing);
         
     | 
| 
       15432 
15717 
     | 
    
         
             
                                    } else if (PM_NODE_TYPE_P(current, PM_STRING_NODE)) {
         
     | 
| 
       15433 
     | 
    
         
            -
                                        // If we hit an embedded expression and the current 
     | 
| 
       15434 
     | 
    
         
            -
                                        // string node, then we'll convert the 
     | 
| 
       15435 
     | 
    
         
            -
                                        // interpolated string and add the 
     | 
| 
       15436 
     | 
    
         
            -
                                        // parts.
         
     | 
| 
      
 15718 
     | 
    
         
            +
                                        // If we hit an embedded expression and the current
         
     | 
| 
      
 15719 
     | 
    
         
            +
                                        // node is a string node, then we'll convert the
         
     | 
| 
      
 15720 
     | 
    
         
            +
                                        // current into an interpolated string and add the
         
     | 
| 
      
 15721 
     | 
    
         
            +
                                        // string node to the list of parts.
         
     | 
| 
       15437 
15722 
     | 
    
         
             
                                        pm_token_t opening = not_provided(parser);
         
     | 
| 
       15438 
15723 
     | 
    
         
             
                                        pm_token_t closing = not_provided(parser);
         
     | 
| 
       15439 
15724 
     | 
    
         
             
                                        pm_interpolated_string_node_t *interpolated = pm_interpolated_string_node_create(parser, &opening, NULL, &closing);
         
     | 
| 
       15440 
15725 
     | 
    
         
             
                                        pm_interpolated_string_node_append(interpolated, current);
         
     | 
| 
       15441 
15726 
     | 
    
         
             
                                        current = (pm_node_t *) interpolated;
         
     | 
| 
       15442 
15727 
     | 
    
         
             
                                    } else if (PM_NODE_TYPE_P(current, PM_INTERPOLATED_STRING_NODE)) {
         
     | 
| 
       15443 
     | 
    
         
            -
                                        // If we hit an embedded expression and the current 
     | 
| 
       15444 
     | 
    
         
            -
                                        // interpolated string, then we'll just 
     | 
| 
      
 15728 
     | 
    
         
            +
                                        // If we hit an embedded expression and the current
         
     | 
| 
      
 15729 
     | 
    
         
            +
                                        // node is an interpolated string, then we'll just
         
     | 
| 
      
 15730 
     | 
    
         
            +
                                        // continue on.
         
     | 
| 
       15445 
15731 
     | 
    
         
             
                                    } else {
         
     | 
| 
       15446 
15732 
     | 
    
         
             
                                        assert(false && "unreachable");
         
     | 
| 
       15447 
15733 
     | 
    
         
             
                                    }
         
     | 
| 
         @@ -15462,9 +15748,15 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       15462 
15748 
     | 
    
         
             
                            pm_array_node_elements_append(array, current);
         
     | 
| 
       15463 
15749 
     | 
    
         
             
                        }
         
     | 
| 
       15464 
15750 
     | 
    
         | 
| 
       15465 
     | 
    
         
            -
                         
     | 
| 
       15466 
     | 
    
         
            -
                         
     | 
| 
      
 15751 
     | 
    
         
            +
                        pm_token_t closing = parser->current;
         
     | 
| 
      
 15752 
     | 
    
         
            +
                        if (match1(parser, PM_TOKEN_EOF)) {
         
     | 
| 
      
 15753 
     | 
    
         
            +
                            pm_parser_err_token(parser, &opening, PM_ERR_LIST_W_UPPER_TERM);
         
     | 
| 
      
 15754 
     | 
    
         
            +
                            closing = (pm_token_t) { .type = PM_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end };
         
     | 
| 
      
 15755 
     | 
    
         
            +
                        } else {
         
     | 
| 
      
 15756 
     | 
    
         
            +
                            expect1(parser, PM_TOKEN_STRING_END, PM_ERR_LIST_W_UPPER_TERM);
         
     | 
| 
      
 15757 
     | 
    
         
            +
                        }
         
     | 
| 
       15467 
15758 
     | 
    
         | 
| 
      
 15759 
     | 
    
         
            +
                        pm_array_node_close_set(array, &closing);
         
     | 
| 
       15468 
15760 
     | 
    
         
             
                        return (pm_node_t *) array;
         
     | 
| 
       15469 
15761 
     | 
    
         
             
                    }
         
     | 
| 
       15470 
15762 
     | 
    
         
             
                    case PM_TOKEN_REGEXP_BEGIN: {
         
     | 
| 
         @@ -15527,8 +15819,14 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       15527 
15819 
     | 
    
         
             
                            }
         
     | 
| 
       15528 
15820 
     | 
    
         
             
                        }
         
     | 
| 
       15529 
15821 
     | 
    
         | 
| 
       15530 
     | 
    
         
            -
                         
     | 
| 
       15531 
     | 
    
         
            -
                         
     | 
| 
      
 15822 
     | 
    
         
            +
                        pm_token_t closing = parser->current;
         
     | 
| 
      
 15823 
     | 
    
         
            +
                        if (match1(parser, PM_TOKEN_EOF)) {
         
     | 
| 
      
 15824 
     | 
    
         
            +
                            pm_parser_err_token(parser, &opening, PM_ERR_REGEXP_TERM);
         
     | 
| 
      
 15825 
     | 
    
         
            +
                            closing = (pm_token_t) { .type = PM_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end };
         
     | 
| 
      
 15826 
     | 
    
         
            +
                        } else {
         
     | 
| 
      
 15827 
     | 
    
         
            +
                            expect1(parser, PM_TOKEN_REGEXP_END, PM_ERR_REGEXP_TERM);
         
     | 
| 
      
 15828 
     | 
    
         
            +
                        }
         
     | 
| 
      
 15829 
     | 
    
         
            +
                        pm_interpolated_regular_expression_node_closing_set(node, &closing);
         
     | 
| 
       15532 
15830 
     | 
    
         | 
| 
       15533 
15831 
     | 
    
         
             
                        return (pm_node_t *) node;
         
     | 
| 
       15534 
15832 
     | 
    
         
             
                    }
         
     | 
| 
         @@ -15566,8 +15864,11 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       15566 
15864 
     | 
    
         
             
                            pm_token_t content = parser->current;
         
     | 
| 
       15567 
15865 
     | 
    
         
             
                            parser_lex(parser);
         
     | 
| 
       15568 
15866 
     | 
    
         | 
| 
       15569 
     | 
    
         
            -
                            if ( 
     | 
| 
       15570 
     | 
    
         
            -
                                 
     | 
| 
      
 15867 
     | 
    
         
            +
                            if (match1(parser, PM_TOKEN_STRING_END)) {
         
     | 
| 
      
 15868 
     | 
    
         
            +
                                pm_node_t *node = (pm_node_t *) pm_xstring_node_create_unescaped(parser, &opening, &content, &parser->current, &unescaped);
         
     | 
| 
      
 15869 
     | 
    
         
            +
                                pm_node_flag_set(node, parse_unescaped_encoding(parser));
         
     | 
| 
      
 15870 
     | 
    
         
            +
                                parser_lex(parser);
         
     | 
| 
      
 15871 
     | 
    
         
            +
                                return node;
         
     | 
| 
       15571 
15872 
     | 
    
         
             
                            }
         
     | 
| 
       15572 
15873 
     | 
    
         | 
| 
       15573 
15874 
     | 
    
         
             
                            // If we get here, then we have interpolation so we'll need to
         
     | 
| 
         @@ -15576,7 +15877,9 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       15576 
15877 
     | 
    
         | 
| 
       15577 
15878 
     | 
    
         
             
                            pm_token_t opening = not_provided(parser);
         
     | 
| 
       15578 
15879 
     | 
    
         
             
                            pm_token_t closing = not_provided(parser);
         
     | 
| 
      
 15880 
     | 
    
         
            +
             
     | 
| 
       15579 
15881 
     | 
    
         
             
                            pm_node_t *part = (pm_node_t *) pm_string_node_create_unescaped(parser, &opening, &parser->previous, &closing, &unescaped);
         
     | 
| 
      
 15882 
     | 
    
         
            +
                            pm_node_flag_set(part, parse_unescaped_encoding(parser));
         
     | 
| 
       15580 
15883 
     | 
    
         | 
| 
       15581 
15884 
     | 
    
         
             
                            pm_interpolated_xstring_node_append(node, part);
         
     | 
| 
       15582 
15885 
     | 
    
         
             
                        } else {
         
     | 
| 
         @@ -15593,8 +15896,15 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       15593 
15896 
     | 
    
         
             
                            }
         
     | 
| 
       15594 
15897 
     | 
    
         
             
                        }
         
     | 
| 
       15595 
15898 
     | 
    
         | 
| 
       15596 
     | 
    
         
            -
                         
     | 
| 
       15597 
     | 
    
         
            -
                         
     | 
| 
      
 15899 
     | 
    
         
            +
                        pm_token_t closing = parser->current;
         
     | 
| 
      
 15900 
     | 
    
         
            +
                        if (match1(parser, PM_TOKEN_EOF)) {
         
     | 
| 
      
 15901 
     | 
    
         
            +
                            pm_parser_err_token(parser, &opening, PM_ERR_XSTRING_TERM);
         
     | 
| 
      
 15902 
     | 
    
         
            +
                            closing = (pm_token_t) { .type = PM_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end };
         
     | 
| 
      
 15903 
     | 
    
         
            +
                        } else {
         
     | 
| 
      
 15904 
     | 
    
         
            +
                            expect1(parser, PM_TOKEN_STRING_END, PM_ERR_XSTRING_TERM);
         
     | 
| 
      
 15905 
     | 
    
         
            +
                        }
         
     | 
| 
      
 15906 
     | 
    
         
            +
                        pm_interpolated_xstring_node_closing_set(node, &closing);
         
     | 
| 
      
 15907 
     | 
    
         
            +
             
     | 
| 
       15598 
15908 
     | 
    
         
             
                        return (pm_node_t *) node;
         
     | 
| 
       15599 
15909 
     | 
    
         
             
                    }
         
     | 
| 
       15600 
15910 
     | 
    
         
             
                    case PM_TOKEN_USTAR: {
         
     | 
| 
         @@ -15611,7 +15921,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       15611 
15921 
     | 
    
         
             
                        pm_node_t *name = NULL;
         
     | 
| 
       15612 
15922 
     | 
    
         | 
| 
       15613 
15923 
     | 
    
         
             
                        if (token_begins_expression_p(parser->current.type)) {
         
     | 
| 
       15614 
     | 
    
         
            -
                            name = parse_expression(parser, PM_BINDING_POWER_INDEX, PM_ERR_EXPECT_EXPRESSION_AFTER_STAR);
         
     | 
| 
      
 15924 
     | 
    
         
            +
                            name = parse_expression(parser, PM_BINDING_POWER_INDEX, false, PM_ERR_EXPECT_EXPRESSION_AFTER_STAR);
         
     | 
| 
       15615 
15925 
     | 
    
         
             
                        }
         
     | 
| 
       15616 
15926 
     | 
    
         | 
| 
       15617 
15927 
     | 
    
         
             
                        pm_node_t *splat = (pm_node_t *) pm_splat_node_create(parser, &operator, name);
         
     | 
| 
         @@ -15626,7 +15936,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       15626 
15936 
     | 
    
         
             
                        parser_lex(parser);
         
     | 
| 
       15627 
15937 
     | 
    
         | 
| 
       15628 
15938 
     | 
    
         
             
                        pm_token_t operator = parser->previous;
         
     | 
| 
       15629 
     | 
    
         
            -
                        pm_node_t *receiver = parse_expression(parser, pm_binding_powers[parser->previous.type].right, PM_ERR_UNARY_RECEIVER_BANG);
         
     | 
| 
      
 15939 
     | 
    
         
            +
                        pm_node_t *receiver = parse_expression(parser, pm_binding_powers[parser->previous.type].right, binding_power < PM_BINDING_POWER_MATCH, PM_ERR_UNARY_RECEIVER_BANG);
         
     | 
| 
       15630 
15940 
     | 
    
         
             
                        pm_call_node_t *node = pm_call_node_unary_create(parser, &operator, receiver, "!");
         
     | 
| 
       15631 
15941 
     | 
    
         | 
| 
       15632 
15942 
     | 
    
         
             
                        pm_conditional_predicate(receiver);
         
     | 
| 
         @@ -15636,7 +15946,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       15636 
15946 
     | 
    
         
             
                        parser_lex(parser);
         
     | 
| 
       15637 
15947 
     | 
    
         | 
| 
       15638 
15948 
     | 
    
         
             
                        pm_token_t operator = parser->previous;
         
     | 
| 
       15639 
     | 
    
         
            -
                        pm_node_t *receiver = parse_expression(parser, pm_binding_powers[parser->previous.type].right, PM_ERR_UNARY_RECEIVER_TILDE);
         
     | 
| 
      
 15949 
     | 
    
         
            +
                        pm_node_t *receiver = parse_expression(parser, pm_binding_powers[parser->previous.type].right, false, PM_ERR_UNARY_RECEIVER_TILDE);
         
     | 
| 
       15640 
15950 
     | 
    
         
             
                        pm_call_node_t *node = pm_call_node_unary_create(parser, &operator, receiver, "~");
         
     | 
| 
       15641 
15951 
     | 
    
         | 
| 
       15642 
15952 
     | 
    
         
             
                        return (pm_node_t *) node;
         
     | 
| 
         @@ -15645,7 +15955,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       15645 
15955 
     | 
    
         
             
                        parser_lex(parser);
         
     | 
| 
       15646 
15956 
     | 
    
         | 
| 
       15647 
15957 
     | 
    
         
             
                        pm_token_t operator = parser->previous;
         
     | 
| 
       15648 
     | 
    
         
            -
                        pm_node_t *receiver = parse_expression(parser, pm_binding_powers[parser->previous.type].right, PM_ERR_UNARY_RECEIVER_MINUS);
         
     | 
| 
      
 15958 
     | 
    
         
            +
                        pm_node_t *receiver = parse_expression(parser, pm_binding_powers[parser->previous.type].right, false, PM_ERR_UNARY_RECEIVER_MINUS);
         
     | 
| 
       15649 
15959 
     | 
    
         
             
                        pm_call_node_t *node = pm_call_node_unary_create(parser, &operator, receiver, "-@");
         
     | 
| 
       15650 
15960 
     | 
    
         | 
| 
       15651 
15961 
     | 
    
         
             
                        return (pm_node_t *) node;
         
     | 
| 
         @@ -15654,11 +15964,11 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       15654 
15964 
     | 
    
         
             
                        parser_lex(parser);
         
     | 
| 
       15655 
15965 
     | 
    
         | 
| 
       15656 
15966 
     | 
    
         
             
                        pm_token_t operator = parser->previous;
         
     | 
| 
       15657 
     | 
    
         
            -
                        pm_node_t *node = parse_expression(parser, pm_binding_powers[parser->previous.type].right, PM_ERR_UNARY_RECEIVER_MINUS);
         
     | 
| 
      
 15967 
     | 
    
         
            +
                        pm_node_t *node = parse_expression(parser, pm_binding_powers[parser->previous.type].right, false, PM_ERR_UNARY_RECEIVER_MINUS);
         
     | 
| 
       15658 
15968 
     | 
    
         | 
| 
       15659 
15969 
     | 
    
         
             
                        if (accept1(parser, PM_TOKEN_STAR_STAR)) {
         
     | 
| 
       15660 
15970 
     | 
    
         
             
                            pm_token_t exponent_operator = parser->previous;
         
     | 
| 
       15661 
     | 
    
         
            -
                            pm_node_t *exponent = parse_expression(parser, pm_binding_powers[exponent_operator.type].right, PM_ERR_EXPECT_ARGUMENT);
         
     | 
| 
      
 15971 
     | 
    
         
            +
                            pm_node_t *exponent = parse_expression(parser, pm_binding_powers[exponent_operator.type].right, false, PM_ERR_EXPECT_ARGUMENT);
         
     | 
| 
       15662 
15972 
     | 
    
         
             
                            node = (pm_node_t *) pm_call_node_binary_create(parser, node, &exponent_operator, exponent);
         
     | 
| 
       15663 
15973 
     | 
    
         
             
                            node = (pm_node_t *) pm_call_node_unary_create(parser, &operator, node, "-@");
         
     | 
| 
       15664 
15974 
     | 
    
         
             
                        } else {
         
     | 
| 
         @@ -15686,7 +15996,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       15686 
15996 
     | 
    
         | 
| 
       15687 
15997 
     | 
    
         
             
                        pm_token_t operator = parser->previous;
         
     | 
| 
       15688 
15998 
     | 
    
         
             
                        pm_parser_scope_push(parser, false);
         
     | 
| 
       15689 
     | 
    
         
            -
                        pm_block_parameters_node_t * 
     | 
| 
      
 15999 
     | 
    
         
            +
                        pm_block_parameters_node_t *block_parameters;
         
     | 
| 
       15690 
16000 
     | 
    
         | 
| 
       15691 
16001 
     | 
    
         
             
                        switch (parser->current.type) {
         
     | 
| 
       15692 
16002 
     | 
    
         
             
                            case PM_TOKEN_PARENTHESIS_LEFT: {
         
     | 
| 
         @@ -15695,31 +16005,37 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       15695 
16005 
     | 
    
         
             
                                parser_lex(parser);
         
     | 
| 
       15696 
16006 
     | 
    
         | 
| 
       15697 
16007 
     | 
    
         
             
                                if (match1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) {
         
     | 
| 
       15698 
     | 
    
         
            -
                                     
     | 
| 
      
 16008 
     | 
    
         
            +
                                    block_parameters = pm_block_parameters_node_create(parser, NULL, &opening);
         
     | 
| 
       15699 
16009 
     | 
    
         
             
                                } else {
         
     | 
| 
       15700 
     | 
    
         
            -
                                     
     | 
| 
      
 16010 
     | 
    
         
            +
                                    block_parameters = parse_block_parameters(parser, false, &opening, true);
         
     | 
| 
       15701 
16011 
     | 
    
         
             
                                }
         
     | 
| 
       15702 
16012 
     | 
    
         | 
| 
       15703 
16013 
     | 
    
         
             
                                accept1(parser, PM_TOKEN_NEWLINE);
         
     | 
| 
       15704 
16014 
     | 
    
         
             
                                expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_EXPECT_RPAREN);
         
     | 
| 
       15705 
16015 
     | 
    
         | 
| 
       15706 
     | 
    
         
            -
                                pm_block_parameters_node_closing_set( 
     | 
| 
      
 16016 
     | 
    
         
            +
                                pm_block_parameters_node_closing_set(block_parameters, &parser->previous);
         
     | 
| 
       15707 
16017 
     | 
    
         
             
                                break;
         
     | 
| 
       15708 
16018 
     | 
    
         
             
                            }
         
     | 
| 
       15709 
16019 
     | 
    
         
             
                            case PM_CASE_PARAMETER: {
         
     | 
| 
       15710 
16020 
     | 
    
         
             
                                parser->current_scope->explicit_params = true;
         
     | 
| 
       15711 
16021 
     | 
    
         
             
                                pm_accepts_block_stack_push(parser, false);
         
     | 
| 
       15712 
16022 
     | 
    
         
             
                                pm_token_t opening = not_provided(parser);
         
     | 
| 
       15713 
     | 
    
         
            -
                                 
     | 
| 
      
 16023 
     | 
    
         
            +
                                block_parameters = parse_block_parameters(parser, false, &opening, true);
         
     | 
| 
       15714 
16024 
     | 
    
         
             
                                pm_accepts_block_stack_pop(parser);
         
     | 
| 
       15715 
16025 
     | 
    
         
             
                                break;
         
     | 
| 
       15716 
16026 
     | 
    
         
             
                            }
         
     | 
| 
       15717 
16027 
     | 
    
         
             
                            default: {
         
     | 
| 
       15718 
     | 
    
         
            -
                                 
     | 
| 
      
 16028 
     | 
    
         
            +
                                block_parameters = NULL;
         
     | 
| 
       15719 
16029 
     | 
    
         
             
                                break;
         
     | 
| 
       15720 
16030 
     | 
    
         
             
                            }
         
     | 
| 
       15721 
16031 
     | 
    
         
             
                        }
         
     | 
| 
       15722 
16032 
     | 
    
         | 
| 
      
 16033 
     | 
    
         
            +
                        uint32_t locals_body_index = 0;
         
     | 
| 
      
 16034 
     | 
    
         
            +
             
     | 
| 
      
 16035 
     | 
    
         
            +
                        if (block_parameters) {
         
     | 
| 
      
 16036 
     | 
    
         
            +
                            locals_body_index = (uint32_t) parser->current_scope->locals.size;
         
     | 
| 
      
 16037 
     | 
    
         
            +
                        }
         
     | 
| 
      
 16038 
     | 
    
         
            +
             
     | 
| 
       15723 
16039 
     | 
    
         
             
                        pm_token_t opening;
         
     | 
| 
       15724 
16040 
     | 
    
         
             
                        pm_node_t *body = NULL;
         
     | 
| 
       15725 
16041 
     | 
    
         
             
                        parser->lambda_enclosure_nesting = previous_lambda_enclosure_nesting;
         
     | 
| 
         @@ -15743,22 +16059,30 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       15743 
16059 
     | 
    
         | 
| 
       15744 
16060 
     | 
    
         
             
                            if (match2(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) {
         
     | 
| 
       15745 
16061 
     | 
    
         
             
                                assert(body == NULL || PM_NODE_TYPE_P(body, PM_STATEMENTS_NODE));
         
     | 
| 
       15746 
     | 
    
         
            -
                                body = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) body);
         
     | 
| 
      
 16062 
     | 
    
         
            +
                                body = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) body, false);
         
     | 
| 
       15747 
16063 
     | 
    
         
             
                            }
         
     | 
| 
       15748 
16064 
     | 
    
         | 
| 
       15749 
16065 
     | 
    
         
             
                            expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_LAMBDA_TERM_END);
         
     | 
| 
       15750 
16066 
     | 
    
         
             
                        }
         
     | 
| 
       15751 
16067 
     | 
    
         | 
| 
      
 16068 
     | 
    
         
            +
                        pm_node_t *parameters = (pm_node_t *) block_parameters;
         
     | 
| 
      
 16069 
     | 
    
         
            +
                        uint8_t maximum = parser->current_scope->numbered_parameters;
         
     | 
| 
      
 16070 
     | 
    
         
            +
             
     | 
| 
      
 16071 
     | 
    
         
            +
                        if (parameters == NULL && (maximum > 0)) {
         
     | 
| 
      
 16072 
     | 
    
         
            +
                            parameters = (pm_node_t *) pm_numbered_parameters_node_create(parser, &(pm_location_t) { .start = operator.start, .end = parser->previous.end }, maximum);
         
     | 
| 
      
 16073 
     | 
    
         
            +
                            locals_body_index = maximum;
         
     | 
| 
      
 16074 
     | 
    
         
            +
                        }
         
     | 
| 
      
 16075 
     | 
    
         
            +
             
     | 
| 
       15752 
16076 
     | 
    
         
             
                        pm_constant_id_list_t locals = parser->current_scope->locals;
         
     | 
| 
       15753 
16077 
     | 
    
         
             
                        pm_parser_scope_pop(parser);
         
     | 
| 
       15754 
16078 
     | 
    
         
             
                        pm_accepts_block_stack_pop(parser);
         
     | 
| 
       15755 
     | 
    
         
            -
                        return (pm_node_t *) pm_lambda_node_create(parser, &locals, &operator, &opening, &parser->previous,  
     | 
| 
      
 16079 
     | 
    
         
            +
                        return (pm_node_t *) pm_lambda_node_create(parser, &locals, locals_body_index, &operator, &opening, &parser->previous, parameters, body);
         
     | 
| 
       15756 
16080 
     | 
    
         
             
                    }
         
     | 
| 
       15757 
16081 
     | 
    
         
             
                    case PM_TOKEN_UPLUS: {
         
     | 
| 
       15758 
16082 
     | 
    
         
             
                        parser_lex(parser);
         
     | 
| 
       15759 
16083 
     | 
    
         | 
| 
       15760 
16084 
     | 
    
         
             
                        pm_token_t operator = parser->previous;
         
     | 
| 
       15761 
     | 
    
         
            -
                        pm_node_t *receiver = parse_expression(parser, pm_binding_powers[parser->previous.type].right, PM_ERR_UNARY_RECEIVER_PLUS);
         
     | 
| 
      
 16085 
     | 
    
         
            +
                        pm_node_t *receiver = parse_expression(parser, pm_binding_powers[parser->previous.type].right, false, PM_ERR_UNARY_RECEIVER_PLUS);
         
     | 
| 
       15762 
16086 
     | 
    
         
             
                        pm_call_node_t *node = pm_call_node_unary_create(parser, &operator, receiver, "+@");
         
     | 
| 
       15763 
16087 
     | 
    
         | 
| 
       15764 
16088 
     | 
    
         
             
                        return (pm_node_t *) node;
         
     | 
| 
         @@ -15781,14 +16105,14 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) { 
     | 
|
| 
       15781 
16105 
     | 
    
         
             
            }
         
     | 
| 
       15782 
16106 
     | 
    
         | 
| 
       15783 
16107 
     | 
    
         
             
            static inline pm_node_t *
         
     | 
| 
       15784 
     | 
    
         
            -
            parse_assignment_value(pm_parser_t *parser, pm_binding_power_t binding_power, pm_diagnostic_id_t diag_id) {
         
     | 
| 
       15785 
     | 
    
         
            -
                pm_node_t *value = parse_value_expression(parser, binding_power, diag_id);
         
     | 
| 
      
 16108 
     | 
    
         
            +
            parse_assignment_value(pm_parser_t *parser, pm_binding_power_t previous_binding_power, pm_binding_power_t binding_power, bool accepts_command_call, pm_diagnostic_id_t diag_id) {
         
     | 
| 
      
 16109 
     | 
    
         
            +
                pm_node_t *value = parse_value_expression(parser, binding_power, previous_binding_power == PM_BINDING_POWER_ASSIGNMENT ? accepts_command_call : previous_binding_power < PM_BINDING_POWER_MATCH, diag_id);
         
     | 
| 
       15786 
16110 
     | 
    
         | 
| 
       15787 
16111 
     | 
    
         
             
                // Contradicting binding powers, the right-hand-side value of rthe assignment allows the `rescue` modifier.
         
     | 
| 
       15788 
16112 
     | 
    
         
             
                if (match1(parser, PM_TOKEN_KEYWORD_RESCUE_MODIFIER)) {
         
     | 
| 
       15789 
16113 
     | 
    
         
             
                    pm_token_t rescue = parser->current;
         
     | 
| 
       15790 
16114 
     | 
    
         
             
                    parser_lex(parser);
         
     | 
| 
       15791 
     | 
    
         
            -
                    pm_node_t *right = parse_expression(parser, binding_power, PM_ERR_RESCUE_MODIFIER_VALUE);
         
     | 
| 
      
 16115 
     | 
    
         
            +
                    pm_node_t *right = parse_expression(parser, binding_power, false, PM_ERR_RESCUE_MODIFIER_VALUE);
         
     | 
| 
       15792 
16116 
     | 
    
         | 
| 
       15793 
16117 
     | 
    
         
             
                    return (pm_node_t *) pm_rescue_modifier_node_create(parser, value, &rescue, right);
         
     | 
| 
       15794 
16118 
     | 
    
         
             
                }
         
     | 
| 
         @@ -15798,8 +16122,8 @@ parse_assignment_value(pm_parser_t *parser, pm_binding_power_t binding_power, pm 
     | 
|
| 
       15798 
16122 
     | 
    
         | 
| 
       15799 
16123 
     | 
    
         | 
| 
       15800 
16124 
     | 
    
         
             
            static inline pm_node_t *
         
     | 
| 
       15801 
     | 
    
         
            -
            parse_assignment_values(pm_parser_t *parser, pm_binding_power_t previous_binding_power, pm_binding_power_t binding_power, pm_diagnostic_id_t diag_id) {
         
     | 
| 
       15802 
     | 
    
         
            -
                pm_node_t *value = parse_starred_expression(parser, binding_power, diag_id);
         
     | 
| 
      
 16125 
     | 
    
         
            +
            parse_assignment_values(pm_parser_t *parser, pm_binding_power_t previous_binding_power, pm_binding_power_t binding_power, bool accepts_command_call, pm_diagnostic_id_t diag_id) {
         
     | 
| 
      
 16126 
     | 
    
         
            +
                pm_node_t *value = parse_starred_expression(parser, binding_power, previous_binding_power == PM_BINDING_POWER_ASSIGNMENT ? accepts_command_call : previous_binding_power < PM_BINDING_POWER_MATCH, diag_id);
         
     | 
| 
       15803 
16127 
     | 
    
         | 
| 
       15804 
16128 
     | 
    
         
             
                bool is_single_value = true;
         
     | 
| 
       15805 
16129 
     | 
    
         
             
                if (previous_binding_power == PM_BINDING_POWER_STATEMENT && (PM_NODE_TYPE_P(value, PM_SPLAT_NODE) || match1(parser, PM_TOKEN_COMMA))) {
         
     | 
| 
         @@ -15811,7 +16135,7 @@ parse_assignment_values(pm_parser_t *parser, pm_binding_power_t previous_binding 
     | 
|
| 
       15811 
16135 
     | 
    
         
             
                    value = (pm_node_t *) array;
         
     | 
| 
       15812 
16136 
     | 
    
         | 
| 
       15813 
16137 
     | 
    
         
             
                    while (accept1(parser, PM_TOKEN_COMMA)) {
         
     | 
| 
       15814 
     | 
    
         
            -
                        pm_node_t *element = parse_starred_expression(parser, binding_power, PM_ERR_ARRAY_ELEMENT);
         
     | 
| 
      
 16138 
     | 
    
         
            +
                        pm_node_t *element = parse_starred_expression(parser, binding_power, false, PM_ERR_ARRAY_ELEMENT);
         
     | 
| 
       15815 
16139 
     | 
    
         
             
                        pm_array_node_elements_append(array, element);
         
     | 
| 
       15816 
16140 
     | 
    
         
             
                        if (PM_NODE_TYPE_P(element, PM_MISSING_NODE)) break;
         
     | 
| 
       15817 
16141 
     | 
    
         
             
                    }
         
     | 
| 
         @@ -15821,7 +16145,7 @@ parse_assignment_values(pm_parser_t *parser, pm_binding_power_t previous_binding 
     | 
|
| 
       15821 
16145 
     | 
    
         
             
                if (is_single_value && match1(parser, PM_TOKEN_KEYWORD_RESCUE_MODIFIER)) {
         
     | 
| 
       15822 
16146 
     | 
    
         
             
                    pm_token_t rescue = parser->current;
         
     | 
| 
       15823 
16147 
     | 
    
         
             
                    parser_lex(parser);
         
     | 
| 
       15824 
     | 
    
         
            -
                    pm_node_t *right = parse_expression(parser, binding_power, PM_ERR_RESCUE_MODIFIER_VALUE);
         
     | 
| 
      
 16148 
     | 
    
         
            +
                    pm_node_t *right = parse_expression(parser, binding_power, false, PM_ERR_RESCUE_MODIFIER_VALUE);
         
     | 
| 
       15825 
16149 
     | 
    
         | 
| 
       15826 
16150 
     | 
    
         
             
                    return (pm_node_t *) pm_rescue_modifier_node_create(parser, value, &rescue, right);
         
     | 
| 
       15827 
16151 
     | 
    
         
             
                }
         
     | 
| 
         @@ -15879,7 +16203,7 @@ parse_regular_expression_named_captures(pm_parser_t *parser, const pm_string_t * 
     | 
|
| 
       15879 
16203 
     | 
    
         
             
                pm_string_list_t named_captures = { 0 };
         
     | 
| 
       15880 
16204 
     | 
    
         
             
                pm_node_t *result;
         
     | 
| 
       15881 
16205 
     | 
    
         | 
| 
       15882 
     | 
    
         
            -
                if (pm_regexp_named_capture_group_names(pm_string_source(content), pm_string_length(content), &named_captures, parser->encoding_changed,  
     | 
| 
      
 16206 
     | 
    
         
            +
                if (pm_regexp_named_capture_group_names(pm_string_source(content), pm_string_length(content), &named_captures, parser->encoding_changed, parser->encoding) && (named_captures.length > 0)) {
         
     | 
| 
       15883 
16207 
     | 
    
         
             
                    // Since we should not create a MatchWriteNode when all capture names
         
     | 
| 
       15884 
16208 
     | 
    
         
             
                    // are invalid, creating a MatchWriteNode is delayed here.
         
     | 
| 
       15885 
16209 
     | 
    
         
             
                    pm_match_write_node_t *match = NULL;
         
     | 
| 
         @@ -15913,6 +16237,8 @@ parse_regular_expression_named_captures(pm_parser_t *parser, const pm_string_t * 
     | 
|
| 
       15913 
16237 
     | 
    
         
             
                            if (memory == NULL) abort();
         
     | 
| 
       15914 
16238 
     | 
    
         | 
| 
       15915 
16239 
     | 
    
         
             
                            memcpy(memory, source, length);
         
     | 
| 
      
 16240 
     | 
    
         
            +
                            // This silences clang analyzer warning about leak of memory pointed by `memory`.
         
     | 
| 
      
 16241 
     | 
    
         
            +
                            // NOLINTNEXTLINE(clang-analyzer-*)
         
     | 
| 
       15916 
16242 
     | 
    
         
             
                            name = pm_parser_constant_id_owned(parser, (const uint8_t *) memory, length);
         
     | 
| 
       15917 
16243 
     | 
    
         | 
| 
       15918 
16244 
     | 
    
         
             
                            if (pm_token_is_numbered_parameter(source, source + length)) {
         
     | 
| 
         @@ -15960,7 +16286,7 @@ parse_regular_expression_named_captures(pm_parser_t *parser, const pm_string_t * 
     | 
|
| 
       15960 
16286 
     | 
    
         
             
            }
         
     | 
| 
       15961 
16287 
     | 
    
         | 
| 
       15962 
16288 
     | 
    
         
             
            static inline pm_node_t *
         
     | 
| 
       15963 
     | 
    
         
            -
            parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t previous_binding_power, pm_binding_power_t binding_power) {
         
     | 
| 
      
 16289 
     | 
    
         
            +
            parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t previous_binding_power, pm_binding_power_t binding_power, bool accepts_command_call) {
         
     | 
| 
       15964 
16290 
     | 
    
         
             
                pm_token_t token = parser->current;
         
     | 
| 
       15965 
16291 
     | 
    
         | 
| 
       15966 
16292 
     | 
    
         
             
                switch (token.type) {
         
     | 
| 
         @@ -15979,7 +16305,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       15979 
16305 
     | 
    
         
             
                            /* fallthrough */
         
     | 
| 
       15980 
16306 
     | 
    
         
             
                            case PM_CASE_WRITABLE: {
         
     | 
| 
       15981 
16307 
     | 
    
         
             
                                parser_lex(parser);
         
     | 
| 
       15982 
     | 
    
         
            -
                                pm_node_t *value = parse_assignment_values(parser, previous_binding_power, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_EQUAL);
         
     | 
| 
      
 16308 
     | 
    
         
            +
                                pm_node_t *value = parse_assignment_values(parser, previous_binding_power, PM_NODE_TYPE_P(node, PM_MULTI_TARGET_NODE) ? PM_BINDING_POWER_MULTI_ASSIGNMENT + 1 : binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_EQUAL);
         
     | 
| 
       15983 
16309 
     | 
    
         
             
                                return parse_write(parser, node, &token, value);
         
     | 
| 
       15984 
16310 
     | 
    
         
             
                            }
         
     | 
| 
       15985 
16311 
     | 
    
         
             
                            case PM_SPLAT_NODE: {
         
     | 
| 
         @@ -15987,7 +16313,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       15987 
16313 
     | 
    
         
             
                                pm_multi_target_node_targets_append(parser, multi_target, node);
         
     | 
| 
       15988 
16314 
     | 
    
         | 
| 
       15989 
16315 
     | 
    
         
             
                                parser_lex(parser);
         
     | 
| 
       15990 
     | 
    
         
            -
                                pm_node_t *value = parse_assignment_values(parser, previous_binding_power,  
     | 
| 
      
 16316 
     | 
    
         
            +
                                pm_node_t *value = parse_assignment_values(parser, previous_binding_power, PM_BINDING_POWER_MULTI_ASSIGNMENT + 1, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_EQUAL);
         
     | 
| 
       15991 
16317 
     | 
    
         
             
                                return parse_write(parser, (pm_node_t *) multi_target, &token, value);
         
     | 
| 
       15992 
16318 
     | 
    
         
             
                            }
         
     | 
| 
       15993 
16319 
     | 
    
         
             
                            default:
         
     | 
| 
         @@ -16009,7 +16335,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16009 
16335 
     | 
    
         
             
                            case PM_GLOBAL_VARIABLE_READ_NODE: {
         
     | 
| 
       16010 
16336 
     | 
    
         
             
                                parser_lex(parser);
         
     | 
| 
       16011 
16337 
     | 
    
         | 
| 
       16012 
     | 
    
         
            -
                                pm_node_t *value = parse_assignment_value(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
         
     | 
| 
      
 16338 
     | 
    
         
            +
                                pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
         
     | 
| 
       16013 
16339 
     | 
    
         
             
                                pm_node_t *result = (pm_node_t *) pm_global_variable_and_write_node_create(parser, node, &token, value);
         
     | 
| 
       16014 
16340 
     | 
    
         | 
| 
       16015 
16341 
     | 
    
         
             
                                pm_node_destroy(parser, node);
         
     | 
| 
         @@ -16018,7 +16344,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16018 
16344 
     | 
    
         
             
                            case PM_CLASS_VARIABLE_READ_NODE: {
         
     | 
| 
       16019 
16345 
     | 
    
         
             
                                parser_lex(parser);
         
     | 
| 
       16020 
16346 
     | 
    
         | 
| 
       16021 
     | 
    
         
            -
                                pm_node_t *value = parse_assignment_value(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
         
     | 
| 
      
 16347 
     | 
    
         
            +
                                pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
         
     | 
| 
       16022 
16348 
     | 
    
         
             
                                pm_node_t *result = (pm_node_t *) pm_class_variable_and_write_node_create(parser, (pm_class_variable_read_node_t *) node, &token, value);
         
     | 
| 
       16023 
16349 
     | 
    
         | 
| 
       16024 
16350 
     | 
    
         
             
                                pm_node_destroy(parser, node);
         
     | 
| 
         @@ -16027,13 +16353,13 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16027 
16353 
     | 
    
         
             
                            case PM_CONSTANT_PATH_NODE: {
         
     | 
| 
       16028 
16354 
     | 
    
         
             
                                parser_lex(parser);
         
     | 
| 
       16029 
16355 
     | 
    
         | 
| 
       16030 
     | 
    
         
            -
                                pm_node_t *value = parse_assignment_value(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
         
     | 
| 
      
 16356 
     | 
    
         
            +
                                pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
         
     | 
| 
       16031 
16357 
     | 
    
         
             
                                return (pm_node_t *) pm_constant_path_and_write_node_create(parser, (pm_constant_path_node_t *) node, &token, value);
         
     | 
| 
       16032 
16358 
     | 
    
         
             
                            }
         
     | 
| 
       16033 
16359 
     | 
    
         
             
                            case PM_CONSTANT_READ_NODE: {
         
     | 
| 
       16034 
16360 
     | 
    
         
             
                                parser_lex(parser);
         
     | 
| 
       16035 
16361 
     | 
    
         | 
| 
       16036 
     | 
    
         
            -
                                pm_node_t *value = parse_assignment_value(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
         
     | 
| 
      
 16362 
     | 
    
         
            +
                                pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
         
     | 
| 
       16037 
16363 
     | 
    
         
             
                                pm_node_t *result = (pm_node_t *) pm_constant_and_write_node_create(parser, (pm_constant_read_node_t *) node, &token, value);
         
     | 
| 
       16038 
16364 
     | 
    
         | 
| 
       16039 
16365 
     | 
    
         
             
                                pm_node_destroy(parser, node);
         
     | 
| 
         @@ -16042,7 +16368,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16042 
16368 
     | 
    
         
             
                            case PM_INSTANCE_VARIABLE_READ_NODE: {
         
     | 
| 
       16043 
16369 
     | 
    
         
             
                                parser_lex(parser);
         
     | 
| 
       16044 
16370 
     | 
    
         | 
| 
       16045 
     | 
    
         
            -
                                pm_node_t *value = parse_assignment_value(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
         
     | 
| 
      
 16371 
     | 
    
         
            +
                                pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
         
     | 
| 
       16046 
16372 
     | 
    
         
             
                                pm_node_t *result = (pm_node_t *) pm_instance_variable_and_write_node_create(parser, (pm_instance_variable_read_node_t *) node, &token, value);
         
     | 
| 
       16047 
16373 
     | 
    
         | 
| 
       16048 
16374 
     | 
    
         
             
                                pm_node_destroy(parser, node);
         
     | 
| 
         @@ -16052,7 +16378,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16052 
16378 
     | 
    
         
             
                                pm_local_variable_read_node_t *cast = (pm_local_variable_read_node_t *) node;
         
     | 
| 
       16053 
16379 
     | 
    
         
             
                                parser_lex(parser);
         
     | 
| 
       16054 
16380 
     | 
    
         | 
| 
       16055 
     | 
    
         
            -
                                pm_node_t *value = parse_assignment_value(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
         
     | 
| 
      
 16381 
     | 
    
         
            +
                                pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
         
     | 
| 
       16056 
16382 
     | 
    
         
             
                                pm_node_t *result = (pm_node_t *) pm_local_variable_and_write_node_create(parser, node, &token, value, cast->name, cast->depth);
         
     | 
| 
       16057 
16383 
     | 
    
         | 
| 
       16058 
16384 
     | 
    
         
             
                                pm_node_destroy(parser, node);
         
     | 
| 
         @@ -16070,7 +16396,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16070 
16396 
     | 
    
         
             
                                    pm_refute_numbered_parameter(parser, message_loc->start, message_loc->end);
         
     | 
| 
       16071 
16397 
     | 
    
         | 
| 
       16072 
16398 
     | 
    
         
             
                                    pm_constant_id_t constant_id = pm_parser_local_add_location(parser, message_loc->start, message_loc->end);
         
     | 
| 
       16073 
     | 
    
         
            -
                                    pm_node_t *value = parse_assignment_value(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
         
     | 
| 
      
 16399 
     | 
    
         
            +
                                    pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
         
     | 
| 
       16074 
16400 
     | 
    
         
             
                                    pm_node_t *result = (pm_node_t *) pm_local_variable_and_write_node_create(parser, (pm_node_t *) cast, &token, value, constant_id, 0);
         
     | 
| 
       16075 
16401 
     | 
    
         | 
| 
       16076 
16402 
     | 
    
         
             
                                    pm_node_destroy(parser, (pm_node_t *) cast);
         
     | 
| 
         @@ -16081,7 +16407,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16081 
16407 
     | 
    
         
             
                                // this is an aref expression, and we can transform it into
         
     | 
| 
       16082 
16408 
     | 
    
         
             
                                // an aset expression.
         
     | 
| 
       16083 
16409 
     | 
    
         
             
                                if (pm_call_node_index_p(cast)) {
         
     | 
| 
       16084 
     | 
    
         
            -
                                    pm_node_t *value = parse_assignment_value(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
         
     | 
| 
      
 16410 
     | 
    
         
            +
                                    pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
         
     | 
| 
       16085 
16411 
     | 
    
         
             
                                    return (pm_node_t *) pm_index_and_write_node_create(parser, cast, &token, value);
         
     | 
| 
       16086 
16412 
     | 
    
         
             
                                }
         
     | 
| 
       16087 
16413 
     | 
    
         | 
| 
         @@ -16093,7 +16419,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16093 
16419 
     | 
    
         
             
                                }
         
     | 
| 
       16094 
16420 
     | 
    
         | 
| 
       16095 
16421 
     | 
    
         
             
                                parse_call_operator_write(parser, cast, &token);
         
     | 
| 
       16096 
     | 
    
         
            -
                                pm_node_t *value = parse_assignment_value(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
         
     | 
| 
      
 16422 
     | 
    
         
            +
                                pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
         
     | 
| 
       16097 
16423 
     | 
    
         
             
                                return (pm_node_t *) pm_call_and_write_node_create(parser, cast, &token, value);
         
     | 
| 
       16098 
16424 
     | 
    
         
             
                            }
         
     | 
| 
       16099 
16425 
     | 
    
         
             
                            case PM_MULTI_WRITE_NODE: {
         
     | 
| 
         @@ -16120,7 +16446,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16120 
16446 
     | 
    
         
             
                            case PM_GLOBAL_VARIABLE_READ_NODE: {
         
     | 
| 
       16121 
16447 
     | 
    
         
             
                                parser_lex(parser);
         
     | 
| 
       16122 
16448 
     | 
    
         | 
| 
       16123 
     | 
    
         
            -
                                pm_node_t *value = parse_assignment_value(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
         
     | 
| 
      
 16449 
     | 
    
         
            +
                                pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
         
     | 
| 
       16124 
16450 
     | 
    
         
             
                                pm_node_t *result = (pm_node_t *) pm_global_variable_or_write_node_create(parser, node, &token, value);
         
     | 
| 
       16125 
16451 
     | 
    
         | 
| 
       16126 
16452 
     | 
    
         
             
                                pm_node_destroy(parser, node);
         
     | 
| 
         @@ -16129,7 +16455,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16129 
16455 
     | 
    
         
             
                            case PM_CLASS_VARIABLE_READ_NODE: {
         
     | 
| 
       16130 
16456 
     | 
    
         
             
                                parser_lex(parser);
         
     | 
| 
       16131 
16457 
     | 
    
         | 
| 
       16132 
     | 
    
         
            -
                                pm_node_t *value = parse_assignment_value(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
         
     | 
| 
      
 16458 
     | 
    
         
            +
                                pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
         
     | 
| 
       16133 
16459 
     | 
    
         
             
                                pm_node_t *result = (pm_node_t *) pm_class_variable_or_write_node_create(parser, (pm_class_variable_read_node_t *) node, &token, value);
         
     | 
| 
       16134 
16460 
     | 
    
         | 
| 
       16135 
16461 
     | 
    
         
             
                                pm_node_destroy(parser, node);
         
     | 
| 
         @@ -16138,13 +16464,13 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16138 
16464 
     | 
    
         
             
                            case PM_CONSTANT_PATH_NODE: {
         
     | 
| 
       16139 
16465 
     | 
    
         
             
                                parser_lex(parser);
         
     | 
| 
       16140 
16466 
     | 
    
         | 
| 
       16141 
     | 
    
         
            -
                                pm_node_t *value = parse_assignment_value(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
         
     | 
| 
      
 16467 
     | 
    
         
            +
                                pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
         
     | 
| 
       16142 
16468 
     | 
    
         
             
                                return (pm_node_t *) pm_constant_path_or_write_node_create(parser, (pm_constant_path_node_t *) node, &token, value);
         
     | 
| 
       16143 
16469 
     | 
    
         
             
                            }
         
     | 
| 
       16144 
16470 
     | 
    
         
             
                            case PM_CONSTANT_READ_NODE: {
         
     | 
| 
       16145 
16471 
     | 
    
         
             
                                parser_lex(parser);
         
     | 
| 
       16146 
16472 
     | 
    
         | 
| 
       16147 
     | 
    
         
            -
                                pm_node_t *value = parse_assignment_value(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
         
     | 
| 
      
 16473 
     | 
    
         
            +
                                pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
         
     | 
| 
       16148 
16474 
     | 
    
         
             
                                pm_node_t *result = (pm_node_t *) pm_constant_or_write_node_create(parser, (pm_constant_read_node_t *) node, &token, value);
         
     | 
| 
       16149 
16475 
     | 
    
         | 
| 
       16150 
16476 
     | 
    
         
             
                                pm_node_destroy(parser, node);
         
     | 
| 
         @@ -16153,7 +16479,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16153 
16479 
     | 
    
         
             
                            case PM_INSTANCE_VARIABLE_READ_NODE: {
         
     | 
| 
       16154 
16480 
     | 
    
         
             
                                parser_lex(parser);
         
     | 
| 
       16155 
16481 
     | 
    
         | 
| 
       16156 
     | 
    
         
            -
                                pm_node_t *value = parse_assignment_value(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
         
     | 
| 
      
 16482 
     | 
    
         
            +
                                pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
         
     | 
| 
       16157 
16483 
     | 
    
         
             
                                pm_node_t *result = (pm_node_t *) pm_instance_variable_or_write_node_create(parser, (pm_instance_variable_read_node_t *) node, &token, value);
         
     | 
| 
       16158 
16484 
     | 
    
         | 
| 
       16159 
16485 
     | 
    
         
             
                                pm_node_destroy(parser, node);
         
     | 
| 
         @@ -16163,7 +16489,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16163 
16489 
     | 
    
         
             
                                pm_local_variable_read_node_t *cast = (pm_local_variable_read_node_t *) node;
         
     | 
| 
       16164 
16490 
     | 
    
         
             
                                parser_lex(parser);
         
     | 
| 
       16165 
16491 
     | 
    
         | 
| 
       16166 
     | 
    
         
            -
                                pm_node_t *value = parse_assignment_value(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
         
     | 
| 
      
 16492 
     | 
    
         
            +
                                pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
         
     | 
| 
       16167 
16493 
     | 
    
         
             
                                pm_node_t *result = (pm_node_t *) pm_local_variable_or_write_node_create(parser, node, &token, value, cast->name, cast->depth);
         
     | 
| 
       16168 
16494 
     | 
    
         | 
| 
       16169 
16495 
     | 
    
         
             
                                pm_node_destroy(parser, node);
         
     | 
| 
         @@ -16181,7 +16507,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16181 
16507 
     | 
    
         
             
                                    pm_refute_numbered_parameter(parser, message_loc->start, message_loc->end);
         
     | 
| 
       16182 
16508 
     | 
    
         | 
| 
       16183 
16509 
     | 
    
         
             
                                    pm_constant_id_t constant_id = pm_parser_local_add_location(parser, message_loc->start, message_loc->end);
         
     | 
| 
       16184 
     | 
    
         
            -
                                    pm_node_t *value = parse_assignment_value(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
         
     | 
| 
      
 16510 
     | 
    
         
            +
                                    pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
         
     | 
| 
       16185 
16511 
     | 
    
         
             
                                    pm_node_t *result = (pm_node_t *) pm_local_variable_or_write_node_create(parser, (pm_node_t *) cast, &token, value, constant_id, 0);
         
     | 
| 
       16186 
16512 
     | 
    
         | 
| 
       16187 
16513 
     | 
    
         
             
                                    pm_node_destroy(parser, (pm_node_t *) cast);
         
     | 
| 
         @@ -16192,7 +16518,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16192 
16518 
     | 
    
         
             
                                // this is an aref expression, and we can transform it into
         
     | 
| 
       16193 
16519 
     | 
    
         
             
                                // an aset expression.
         
     | 
| 
       16194 
16520 
     | 
    
         
             
                                if (pm_call_node_index_p(cast)) {
         
     | 
| 
       16195 
     | 
    
         
            -
                                    pm_node_t *value = parse_assignment_value(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
         
     | 
| 
      
 16521 
     | 
    
         
            +
                                    pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
         
     | 
| 
       16196 
16522 
     | 
    
         
             
                                    return (pm_node_t *) pm_index_or_write_node_create(parser, cast, &token, value);
         
     | 
| 
       16197 
16523 
     | 
    
         
             
                                }
         
     | 
| 
       16198 
16524 
     | 
    
         | 
| 
         @@ -16204,7 +16530,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16204 
16530 
     | 
    
         
             
                                }
         
     | 
| 
       16205 
16531 
     | 
    
         | 
| 
       16206 
16532 
     | 
    
         
             
                                parse_call_operator_write(parser, cast, &token);
         
     | 
| 
       16207 
     | 
    
         
            -
                                pm_node_t *value = parse_assignment_value(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
         
     | 
| 
      
 16533 
     | 
    
         
            +
                                pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
         
     | 
| 
       16208 
16534 
     | 
    
         
             
                                return (pm_node_t *) pm_call_or_write_node_create(parser, cast, &token, value);
         
     | 
| 
       16209 
16535 
     | 
    
         
             
                            }
         
     | 
| 
       16210 
16536 
     | 
    
         
             
                            case PM_MULTI_WRITE_NODE: {
         
     | 
| 
         @@ -16241,7 +16567,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16241 
16567 
     | 
    
         
             
                            case PM_GLOBAL_VARIABLE_READ_NODE: {
         
     | 
| 
       16242 
16568 
     | 
    
         
             
                                parser_lex(parser);
         
     | 
| 
       16243 
16569 
     | 
    
         | 
| 
       16244 
     | 
    
         
            -
                                pm_node_t *value = parse_assignment_value(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
         
     | 
| 
      
 16570 
     | 
    
         
            +
                                pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
         
     | 
| 
       16245 
16571 
     | 
    
         
             
                                pm_node_t *result = (pm_node_t *) pm_global_variable_operator_write_node_create(parser, node, &token, value);
         
     | 
| 
       16246 
16572 
     | 
    
         | 
| 
       16247 
16573 
     | 
    
         
             
                                pm_node_destroy(parser, node);
         
     | 
| 
         @@ -16250,7 +16576,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16250 
16576 
     | 
    
         
             
                            case PM_CLASS_VARIABLE_READ_NODE: {
         
     | 
| 
       16251 
16577 
     | 
    
         
             
                                parser_lex(parser);
         
     | 
| 
       16252 
16578 
     | 
    
         | 
| 
       16253 
     | 
    
         
            -
                                pm_node_t *value = parse_assignment_value(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
         
     | 
| 
      
 16579 
     | 
    
         
            +
                                pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
         
     | 
| 
       16254 
16580 
     | 
    
         
             
                                pm_node_t *result = (pm_node_t *) pm_class_variable_operator_write_node_create(parser, (pm_class_variable_read_node_t *) node, &token, value);
         
     | 
| 
       16255 
16581 
     | 
    
         | 
| 
       16256 
16582 
     | 
    
         
             
                                pm_node_destroy(parser, node);
         
     | 
| 
         @@ -16259,13 +16585,13 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16259 
16585 
     | 
    
         
             
                            case PM_CONSTANT_PATH_NODE: {
         
     | 
| 
       16260 
16586 
     | 
    
         
             
                                parser_lex(parser);
         
     | 
| 
       16261 
16587 
     | 
    
         | 
| 
       16262 
     | 
    
         
            -
                                pm_node_t *value = parse_assignment_value(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
         
     | 
| 
      
 16588 
     | 
    
         
            +
                                pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
         
     | 
| 
       16263 
16589 
     | 
    
         
             
                                return (pm_node_t *) pm_constant_path_operator_write_node_create(parser, (pm_constant_path_node_t *) node, &token, value);
         
     | 
| 
       16264 
16590 
     | 
    
         
             
                            }
         
     | 
| 
       16265 
16591 
     | 
    
         
             
                            case PM_CONSTANT_READ_NODE: {
         
     | 
| 
       16266 
16592 
     | 
    
         
             
                                parser_lex(parser);
         
     | 
| 
       16267 
16593 
     | 
    
         | 
| 
       16268 
     | 
    
         
            -
                                pm_node_t *value = parse_assignment_value(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
         
     | 
| 
      
 16594 
     | 
    
         
            +
                                pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
         
     | 
| 
       16269 
16595 
     | 
    
         
             
                                pm_node_t *result = (pm_node_t *) pm_constant_operator_write_node_create(parser, (pm_constant_read_node_t *) node, &token, value);
         
     | 
| 
       16270 
16596 
     | 
    
         | 
| 
       16271 
16597 
     | 
    
         
             
                                pm_node_destroy(parser, node);
         
     | 
| 
         @@ -16274,7 +16600,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16274 
16600 
     | 
    
         
             
                            case PM_INSTANCE_VARIABLE_READ_NODE: {
         
     | 
| 
       16275 
16601 
     | 
    
         
             
                                parser_lex(parser);
         
     | 
| 
       16276 
16602 
     | 
    
         | 
| 
       16277 
     | 
    
         
            -
                                pm_node_t *value = parse_assignment_value(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
         
     | 
| 
      
 16603 
     | 
    
         
            +
                                pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
         
     | 
| 
       16278 
16604 
     | 
    
         
             
                                pm_node_t *result = (pm_node_t *) pm_instance_variable_operator_write_node_create(parser, (pm_instance_variable_read_node_t *) node, &token, value);
         
     | 
| 
       16279 
16605 
     | 
    
         | 
| 
       16280 
16606 
     | 
    
         
             
                                pm_node_destroy(parser, node);
         
     | 
| 
         @@ -16284,7 +16610,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16284 
16610 
     | 
    
         
             
                                pm_local_variable_read_node_t *cast = (pm_local_variable_read_node_t *) node;
         
     | 
| 
       16285 
16611 
     | 
    
         
             
                                parser_lex(parser);
         
     | 
| 
       16286 
16612 
     | 
    
         | 
| 
       16287 
     | 
    
         
            -
                                pm_node_t *value = parse_assignment_value(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
         
     | 
| 
      
 16613 
     | 
    
         
            +
                                pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
         
     | 
| 
       16288 
16614 
     | 
    
         
             
                                pm_node_t *result = (pm_node_t *) pm_local_variable_operator_write_node_create(parser, node, &token, value, cast->name, cast->depth);
         
     | 
| 
       16289 
16615 
     | 
    
         | 
| 
       16290 
16616 
     | 
    
         
             
                                pm_node_destroy(parser, node);
         
     | 
| 
         @@ -16302,7 +16628,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16302 
16628 
     | 
    
         
             
                                    pm_refute_numbered_parameter(parser, message_loc->start, message_loc->end);
         
     | 
| 
       16303 
16629 
     | 
    
         | 
| 
       16304 
16630 
     | 
    
         
             
                                    pm_constant_id_t constant_id = pm_parser_local_add_location(parser, message_loc->start, message_loc->end);
         
     | 
| 
       16305 
     | 
    
         
            -
                                    pm_node_t *value = parse_assignment_value(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
         
     | 
| 
      
 16631 
     | 
    
         
            +
                                    pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
         
     | 
| 
       16306 
16632 
     | 
    
         
             
                                    pm_node_t *result = (pm_node_t *) pm_local_variable_operator_write_node_create(parser, (pm_node_t *) cast, &token, value, constant_id, 0);
         
     | 
| 
       16307 
16633 
     | 
    
         | 
| 
       16308 
16634 
     | 
    
         
             
                                    pm_node_destroy(parser, (pm_node_t *) cast);
         
     | 
| 
         @@ -16313,7 +16639,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16313 
16639 
     | 
    
         
             
                                // this is an aref expression, and we can transform it into
         
     | 
| 
       16314 
16640 
     | 
    
         
             
                                // an aset expression.
         
     | 
| 
       16315 
16641 
     | 
    
         
             
                                if (pm_call_node_index_p(cast)) {
         
     | 
| 
       16316 
     | 
    
         
            -
                                    pm_node_t *value = parse_assignment_value(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
         
     | 
| 
      
 16642 
     | 
    
         
            +
                                    pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
         
     | 
| 
       16317 
16643 
     | 
    
         
             
                                    return (pm_node_t *) pm_index_operator_write_node_create(parser, cast, &token, value);
         
     | 
| 
       16318 
16644 
     | 
    
         
             
                                }
         
     | 
| 
       16319 
16645 
     | 
    
         | 
| 
         @@ -16325,7 +16651,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16325 
16651 
     | 
    
         
             
                                }
         
     | 
| 
       16326 
16652 
     | 
    
         | 
| 
       16327 
16653 
     | 
    
         
             
                                parse_call_operator_write(parser, cast, &token);
         
     | 
| 
       16328 
     | 
    
         
            -
                                pm_node_t *value = parse_assignment_value(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
         
     | 
| 
      
 16654 
     | 
    
         
            +
                                pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
         
     | 
| 
       16329 
16655 
     | 
    
         
             
                                return (pm_node_t *) pm_call_operator_write_node_create(parser, cast, &token, value);
         
     | 
| 
       16330 
16656 
     | 
    
         
             
                            }
         
     | 
| 
       16331 
16657 
     | 
    
         
             
                            case PM_MULTI_WRITE_NODE: {
         
     | 
| 
         @@ -16347,14 +16673,14 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16347 
16673 
     | 
    
         
             
                    case PM_TOKEN_KEYWORD_AND: {
         
     | 
| 
       16348 
16674 
     | 
    
         
             
                        parser_lex(parser);
         
     | 
| 
       16349 
16675 
     | 
    
         | 
| 
       16350 
     | 
    
         
            -
                        pm_node_t *right = parse_expression(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
         
     | 
| 
      
 16676 
     | 
    
         
            +
                        pm_node_t *right = parse_expression(parser, binding_power, parser->previous.type == PM_TOKEN_KEYWORD_AND, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
         
     | 
| 
       16351 
16677 
     | 
    
         
             
                        return (pm_node_t *) pm_and_node_create(parser, node, &token, right);
         
     | 
| 
       16352 
16678 
     | 
    
         
             
                    }
         
     | 
| 
       16353 
16679 
     | 
    
         
             
                    case PM_TOKEN_KEYWORD_OR:
         
     | 
| 
       16354 
16680 
     | 
    
         
             
                    case PM_TOKEN_PIPE_PIPE: {
         
     | 
| 
       16355 
16681 
     | 
    
         
             
                        parser_lex(parser);
         
     | 
| 
       16356 
16682 
     | 
    
         | 
| 
       16357 
     | 
    
         
            -
                        pm_node_t *right = parse_expression(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
         
     | 
| 
      
 16683 
     | 
    
         
            +
                        pm_node_t *right = parse_expression(parser, binding_power, parser->previous.type == PM_TOKEN_KEYWORD_OR, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
         
     | 
| 
       16358 
16684 
     | 
    
         
             
                        return (pm_node_t *) pm_or_node_create(parser, node, &token, right);
         
     | 
| 
       16359 
16685 
     | 
    
         
             
                    }
         
     | 
| 
       16360 
16686 
     | 
    
         
             
                    case PM_TOKEN_EQUAL_TILDE: {
         
     | 
| 
         @@ -16366,7 +16692,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16366 
16692 
     | 
    
         
             
                        //
         
     | 
| 
       16367 
16693 
     | 
    
         
             
                        // In this case, `foo` should be a method call and not a local yet.
         
     | 
| 
       16368 
16694 
     | 
    
         
             
                        parser_lex(parser);
         
     | 
| 
       16369 
     | 
    
         
            -
                        pm_node_t *argument = parse_expression(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
         
     | 
| 
      
 16695 
     | 
    
         
            +
                        pm_node_t *argument = parse_expression(parser, binding_power, false, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
         
     | 
| 
       16370 
16696 
     | 
    
         | 
| 
       16371 
16697 
     | 
    
         
             
                        // By default, we're going to create a call node and then return it.
         
     | 
| 
       16372 
16698 
     | 
    
         
             
                        pm_call_node_t *call = pm_call_node_binary_create(parser, node, &token, argument);
         
     | 
| 
         @@ -16451,7 +16777,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16451 
16777 
     | 
    
         
             
                    case PM_TOKEN_STAR_STAR: {
         
     | 
| 
       16452 
16778 
     | 
    
         
             
                        parser_lex(parser);
         
     | 
| 
       16453 
16779 
     | 
    
         | 
| 
       16454 
     | 
    
         
            -
                        pm_node_t *argument = parse_expression(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
         
     | 
| 
      
 16780 
     | 
    
         
            +
                        pm_node_t *argument = parse_expression(parser, binding_power, false, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
         
     | 
| 
       16455 
16781 
     | 
    
         
             
                        return (pm_node_t *) pm_call_node_binary_create(parser, node, &token, argument);
         
     | 
| 
       16456 
16782 
     | 
    
         
             
                    }
         
     | 
| 
       16457 
16783 
     | 
    
         
             
                    case PM_TOKEN_AMPERSAND_DOT:
         
     | 
| 
         @@ -16462,7 +16788,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16462 
16788 
     | 
    
         | 
| 
       16463 
16789 
     | 
    
         
             
                        // This if statement handles the foo.() syntax.
         
     | 
| 
       16464 
16790 
     | 
    
         
             
                        if (match1(parser, PM_TOKEN_PARENTHESIS_LEFT)) {
         
     | 
| 
       16465 
     | 
    
         
            -
                            parse_arguments_list(parser, &arguments, true);
         
     | 
| 
      
 16791 
     | 
    
         
            +
                            parse_arguments_list(parser, &arguments, true, false);
         
     | 
| 
       16466 
16792 
     | 
    
         
             
                            return (pm_node_t *) pm_call_node_shorthand_create(parser, node, &operator, &arguments);
         
     | 
| 
       16467 
16793 
     | 
    
         
             
                        }
         
     | 
| 
       16468 
16794 
     | 
    
         | 
| 
         @@ -16484,7 +16810,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16484 
16810 
     | 
    
         
             
                            }
         
     | 
| 
       16485 
16811 
     | 
    
         
             
                        }
         
     | 
| 
       16486 
16812 
     | 
    
         | 
| 
       16487 
     | 
    
         
            -
                        parse_arguments_list(parser, &arguments, true);
         
     | 
| 
      
 16813 
     | 
    
         
            +
                        parse_arguments_list(parser, &arguments, true, accepts_command_call);
         
     | 
| 
       16488 
16814 
     | 
    
         
             
                        pm_call_node_t *call = pm_call_node_call_create(parser, node, &operator, &message, &arguments);
         
     | 
| 
       16489 
16815 
     | 
    
         | 
| 
       16490 
16816 
     | 
    
         
             
                        if (
         
     | 
| 
         @@ -16504,7 +16830,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16504 
16830 
     | 
    
         | 
| 
       16505 
16831 
     | 
    
         
             
                        pm_node_t *right = NULL;
         
     | 
| 
       16506 
16832 
     | 
    
         
             
                        if (token_begins_expression_p(parser->current.type)) {
         
     | 
| 
       16507 
     | 
    
         
            -
                            right = parse_expression(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
         
     | 
| 
      
 16833 
     | 
    
         
            +
                            right = parse_expression(parser, binding_power, false, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
         
     | 
| 
       16508 
16834 
     | 
    
         
             
                        }
         
     | 
| 
       16509 
16835 
     | 
    
         | 
| 
       16510 
16836 
     | 
    
         
             
                        return (pm_node_t *) pm_range_node_create(parser, node, &token, right);
         
     | 
| 
         @@ -16513,14 +16839,14 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16513 
16839 
     | 
    
         
             
                        pm_token_t keyword = parser->current;
         
     | 
| 
       16514 
16840 
     | 
    
         
             
                        parser_lex(parser);
         
     | 
| 
       16515 
16841 
     | 
    
         | 
| 
       16516 
     | 
    
         
            -
                        pm_node_t *predicate = parse_value_expression(parser, binding_power, PM_ERR_CONDITIONAL_IF_PREDICATE);
         
     | 
| 
      
 16842 
     | 
    
         
            +
                        pm_node_t *predicate = parse_value_expression(parser, binding_power, true, PM_ERR_CONDITIONAL_IF_PREDICATE);
         
     | 
| 
       16517 
16843 
     | 
    
         
             
                        return (pm_node_t *) pm_if_node_modifier_create(parser, node, &keyword, predicate);
         
     | 
| 
       16518 
16844 
     | 
    
         
             
                    }
         
     | 
| 
       16519 
16845 
     | 
    
         
             
                    case PM_TOKEN_KEYWORD_UNLESS_MODIFIER: {
         
     | 
| 
       16520 
16846 
     | 
    
         
             
                        pm_token_t keyword = parser->current;
         
     | 
| 
       16521 
16847 
     | 
    
         
             
                        parser_lex(parser);
         
     | 
| 
       16522 
16848 
     | 
    
         | 
| 
       16523 
     | 
    
         
            -
                        pm_node_t *predicate = parse_value_expression(parser, binding_power, PM_ERR_CONDITIONAL_UNLESS_PREDICATE);
         
     | 
| 
      
 16849 
     | 
    
         
            +
                        pm_node_t *predicate = parse_value_expression(parser, binding_power, true, PM_ERR_CONDITIONAL_UNLESS_PREDICATE);
         
     | 
| 
       16524 
16850 
     | 
    
         
             
                        return (pm_node_t *) pm_unless_node_modifier_create(parser, node, &keyword, predicate);
         
     | 
| 
       16525 
16851 
     | 
    
         
             
                    }
         
     | 
| 
       16526 
16852 
     | 
    
         
             
                    case PM_TOKEN_KEYWORD_UNTIL_MODIFIER: {
         
     | 
| 
         @@ -16528,7 +16854,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16528 
16854 
     | 
    
         
             
                        pm_statements_node_t *statements = pm_statements_node_create(parser);
         
     | 
| 
       16529 
16855 
     | 
    
         
             
                        pm_statements_node_body_append(statements, node);
         
     | 
| 
       16530 
16856 
     | 
    
         | 
| 
       16531 
     | 
    
         
            -
                        pm_node_t *predicate = parse_value_expression(parser, binding_power, PM_ERR_CONDITIONAL_UNTIL_PREDICATE);
         
     | 
| 
      
 16857 
     | 
    
         
            +
                        pm_node_t *predicate = parse_value_expression(parser, binding_power, true, PM_ERR_CONDITIONAL_UNTIL_PREDICATE);
         
     | 
| 
       16532 
16858 
     | 
    
         
             
                        return (pm_node_t *) pm_until_node_modifier_create(parser, &token, predicate, statements, PM_NODE_TYPE_P(node, PM_BEGIN_NODE) ? PM_LOOP_FLAGS_BEGIN_MODIFIER : 0);
         
     | 
| 
       16533 
16859 
     | 
    
         
             
                    }
         
     | 
| 
       16534 
16860 
     | 
    
         
             
                    case PM_TOKEN_KEYWORD_WHILE_MODIFIER: {
         
     | 
| 
         @@ -16536,13 +16862,13 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16536 
16862 
     | 
    
         
             
                        pm_statements_node_t *statements = pm_statements_node_create(parser);
         
     | 
| 
       16537 
16863 
     | 
    
         
             
                        pm_statements_node_body_append(statements, node);
         
     | 
| 
       16538 
16864 
     | 
    
         | 
| 
       16539 
     | 
    
         
            -
                        pm_node_t *predicate = parse_value_expression(parser, binding_power, PM_ERR_CONDITIONAL_WHILE_PREDICATE);
         
     | 
| 
      
 16865 
     | 
    
         
            +
                        pm_node_t *predicate = parse_value_expression(parser, binding_power, true, PM_ERR_CONDITIONAL_WHILE_PREDICATE);
         
     | 
| 
       16540 
16866 
     | 
    
         
             
                        return (pm_node_t *) pm_while_node_modifier_create(parser, &token, predicate, statements, PM_NODE_TYPE_P(node, PM_BEGIN_NODE) ? PM_LOOP_FLAGS_BEGIN_MODIFIER : 0);
         
     | 
| 
       16541 
16867 
     | 
    
         
             
                    }
         
     | 
| 
       16542 
16868 
     | 
    
         
             
                    case PM_TOKEN_QUESTION_MARK: {
         
     | 
| 
       16543 
16869 
     | 
    
         
             
                        pm_token_t qmark = parser->current;
         
     | 
| 
       16544 
16870 
     | 
    
         
             
                        parser_lex(parser);
         
     | 
| 
       16545 
     | 
    
         
            -
                        pm_node_t *true_expression = parse_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_TERNARY_EXPRESSION_TRUE);
         
     | 
| 
      
 16871 
     | 
    
         
            +
                        pm_node_t *true_expression = parse_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_TERNARY_EXPRESSION_TRUE);
         
     | 
| 
       16546 
16872 
     | 
    
         | 
| 
       16547 
16873 
     | 
    
         
             
                        if (parser->recovering) {
         
     | 
| 
       16548 
16874 
     | 
    
         
             
                            // If parsing the true expression of this ternary resulted in a syntax
         
     | 
| 
         @@ -16561,7 +16887,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16561 
16887 
     | 
    
         
             
                        expect1(parser, PM_TOKEN_COLON, PM_ERR_TERNARY_COLON);
         
     | 
| 
       16562 
16888 
     | 
    
         | 
| 
       16563 
16889 
     | 
    
         
             
                        pm_token_t colon = parser->previous;
         
     | 
| 
       16564 
     | 
    
         
            -
                        pm_node_t *false_expression = parse_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_TERNARY_EXPRESSION_FALSE);
         
     | 
| 
      
 16890 
     | 
    
         
            +
                        pm_node_t *false_expression = parse_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_TERNARY_EXPRESSION_FALSE);
         
     | 
| 
       16565 
16891 
     | 
    
         | 
| 
       16566 
16892 
     | 
    
         
             
                        return (pm_node_t *) pm_if_node_ternary_create(parser, node, &qmark, true_expression, &colon, false_expression);
         
     | 
| 
       16567 
16893 
     | 
    
         
             
                    }
         
     | 
| 
         @@ -16587,7 +16913,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16587 
16913 
     | 
    
         
             
                                    pm_token_t message = parser->previous;
         
     | 
| 
       16588 
16914 
     | 
    
         
             
                                    pm_arguments_t arguments = { 0 };
         
     | 
| 
       16589 
16915 
     | 
    
         | 
| 
       16590 
     | 
    
         
            -
                                    parse_arguments_list(parser, &arguments, true);
         
     | 
| 
      
 16916 
     | 
    
         
            +
                                    parse_arguments_list(parser, &arguments, true, accepts_command_call);
         
     | 
| 
       16591 
16917 
     | 
    
         
             
                                    path = (pm_node_t *) pm_call_node_call_create(parser, node, &delimiter, &message, &arguments);
         
     | 
| 
       16592 
16918 
     | 
    
         
             
                                } else {
         
     | 
| 
       16593 
16919 
     | 
    
         
             
                                    // Otherwise, this is a constant path. That would look like Foo::Bar.
         
     | 
| 
         @@ -16612,7 +16938,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16612 
16938 
     | 
    
         
             
                                // If we have an identifier following a '::' operator, then it is for
         
     | 
| 
       16613 
16939 
     | 
    
         
             
                                // sure a method call.
         
     | 
| 
       16614 
16940 
     | 
    
         
             
                                pm_arguments_t arguments = { 0 };
         
     | 
| 
       16615 
     | 
    
         
            -
                                parse_arguments_list(parser, &arguments, true);
         
     | 
| 
      
 16941 
     | 
    
         
            +
                                parse_arguments_list(parser, &arguments, true, accepts_command_call);
         
     | 
| 
       16616 
16942 
     | 
    
         
             
                                pm_call_node_t *call = pm_call_node_call_create(parser, node, &delimiter, &message, &arguments);
         
     | 
| 
       16617 
16943 
     | 
    
         | 
| 
       16618 
16944 
     | 
    
         
             
                                // If this is followed by a comma then it is a multiple assignment.
         
     | 
| 
         @@ -16626,7 +16952,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16626 
16952 
     | 
    
         
             
                                // If we have a parenthesis following a '::' operator, then it is the
         
     | 
| 
       16627 
16953 
     | 
    
         
             
                                // method call shorthand. That would look like Foo::(bar).
         
     | 
| 
       16628 
16954 
     | 
    
         
             
                                pm_arguments_t arguments = { 0 };
         
     | 
| 
       16629 
     | 
    
         
            -
                                parse_arguments_list(parser, &arguments, true);
         
     | 
| 
      
 16955 
     | 
    
         
            +
                                parse_arguments_list(parser, &arguments, true, false);
         
     | 
| 
       16630 
16956 
     | 
    
         | 
| 
       16631 
16957 
     | 
    
         
             
                                return (pm_node_t *) pm_call_node_shorthand_create(parser, node, &delimiter, &arguments);
         
     | 
| 
       16632 
16958 
     | 
    
         
             
                            }
         
     | 
| 
         @@ -16640,7 +16966,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16640 
16966 
     | 
    
         
             
                    case PM_TOKEN_KEYWORD_RESCUE_MODIFIER: {
         
     | 
| 
       16641 
16967 
     | 
    
         
             
                        parser_lex(parser);
         
     | 
| 
       16642 
16968 
     | 
    
         
             
                        accept1(parser, PM_TOKEN_NEWLINE);
         
     | 
| 
       16643 
     | 
    
         
            -
                        pm_node_t *value = parse_expression(parser, binding_power, PM_ERR_RESCUE_MODIFIER_VALUE);
         
     | 
| 
      
 16969 
     | 
    
         
            +
                        pm_node_t *value = parse_expression(parser, binding_power, true, PM_ERR_RESCUE_MODIFIER_VALUE);
         
     | 
| 
       16644 
16970 
     | 
    
         | 
| 
       16645 
16971 
     | 
    
         
             
                        return (pm_node_t *) pm_rescue_modifier_node_create(parser, node, &token, value);
         
     | 
| 
       16646 
16972 
     | 
    
         
             
                    }
         
     | 
| 
         @@ -16736,16 +17062,39 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t 
     | 
|
| 
       16736 
17062 
     | 
    
         
             
             * determine if they need to perform additional cleanup.
         
     | 
| 
       16737 
17063 
     | 
    
         
             
             */
         
     | 
| 
       16738 
17064 
     | 
    
         
             
            static pm_node_t *
         
     | 
| 
       16739 
     | 
    
         
            -
            parse_expression(pm_parser_t *parser, pm_binding_power_t binding_power, pm_diagnostic_id_t diag_id) {
         
     | 
| 
      
 17065 
     | 
    
         
            +
            parse_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool accepts_command_call, pm_diagnostic_id_t diag_id) {
         
     | 
| 
       16740 
17066 
     | 
    
         
             
                pm_token_t recovery = parser->previous;
         
     | 
| 
       16741 
     | 
    
         
            -
                pm_node_t *node = parse_expression_prefix(parser, binding_power);
         
     | 
| 
      
 17067 
     | 
    
         
            +
                pm_node_t *node = parse_expression_prefix(parser, binding_power, accepts_command_call);
         
     | 
| 
       16742 
17068 
     | 
    
         | 
| 
       16743 
     | 
    
         
            -
                 
     | 
| 
       16744 
     | 
    
         
            -
             
     | 
| 
       16745 
     | 
    
         
            -
             
     | 
| 
       16746 
     | 
    
         
            -
             
     | 
| 
       16747 
     | 
    
         
            -
             
     | 
| 
       16748 
     | 
    
         
            -
             
     | 
| 
      
 17069 
     | 
    
         
            +
                switch (PM_NODE_TYPE(node)) {
         
     | 
| 
      
 17070 
     | 
    
         
            +
                    case PM_MISSING_NODE:
         
     | 
| 
      
 17071 
     | 
    
         
            +
                        // If we found a syntax error, then the type of node returned by
         
     | 
| 
      
 17072 
     | 
    
         
            +
                        // parse_expression_prefix is going to be a missing node. In that
         
     | 
| 
      
 17073 
     | 
    
         
            +
                        // case we need to add the error message to the parser's error list.
         
     | 
| 
      
 17074 
     | 
    
         
            +
                        pm_parser_err(parser, recovery.end, recovery.end, diag_id);
         
     | 
| 
      
 17075 
     | 
    
         
            +
                        return node;
         
     | 
| 
      
 17076 
     | 
    
         
            +
                    case PM_PRE_EXECUTION_NODE:
         
     | 
| 
      
 17077 
     | 
    
         
            +
                    case PM_POST_EXECUTION_NODE:
         
     | 
| 
      
 17078 
     | 
    
         
            +
                    case PM_ALIAS_GLOBAL_VARIABLE_NODE:
         
     | 
| 
      
 17079 
     | 
    
         
            +
                    case PM_ALIAS_METHOD_NODE:
         
     | 
| 
      
 17080 
     | 
    
         
            +
                    case PM_UNDEF_NODE:
         
     | 
| 
      
 17081 
     | 
    
         
            +
                        // These expressions are statements, and cannot be followed by
         
     | 
| 
      
 17082 
     | 
    
         
            +
                        // operators (except modifiers).
         
     | 
| 
      
 17083 
     | 
    
         
            +
                        if (pm_binding_powers[parser->current.type].left > PM_BINDING_POWER_MODIFIER_RESCUE) {
         
     | 
| 
      
 17084 
     | 
    
         
            +
                            return node;
         
     | 
| 
      
 17085 
     | 
    
         
            +
                        }
         
     | 
| 
      
 17086 
     | 
    
         
            +
                        break;
         
     | 
| 
      
 17087 
     | 
    
         
            +
                    case PM_RANGE_NODE:
         
     | 
| 
      
 17088 
     | 
    
         
            +
                        // Range operators are non-associative, so that it does not
         
     | 
| 
      
 17089 
     | 
    
         
            +
                        // associate with other range operators (i.e. `..1..` should be
         
     | 
| 
      
 17090 
     | 
    
         
            +
                        // rejected.) For this reason, we check such a case for unary ranges
         
     | 
| 
      
 17091 
     | 
    
         
            +
                        // here, and if so, it returns the node immediately,
         
     | 
| 
      
 17092 
     | 
    
         
            +
                        if ((((pm_range_node_t *) node)->left == NULL) && pm_binding_powers[parser->current.type].left >= PM_BINDING_POWER_RANGE) {
         
     | 
| 
      
 17093 
     | 
    
         
            +
                            return node;
         
     | 
| 
      
 17094 
     | 
    
         
            +
                        }
         
     | 
| 
      
 17095 
     | 
    
         
            +
                        break;
         
     | 
| 
      
 17096 
     | 
    
         
            +
                    default:
         
     | 
| 
      
 17097 
     | 
    
         
            +
                        break;
         
     | 
| 
       16749 
17098 
     | 
    
         
             
                }
         
     | 
| 
       16750 
17099 
     | 
    
         | 
| 
       16751 
17100 
     | 
    
         
             
                // Otherwise we'll look and see if the next token can be parsed as an infix
         
     | 
| 
         @@ -16756,12 +17105,68 @@ parse_expression(pm_parser_t *parser, pm_binding_power_t binding_power, pm_diagn 
     | 
|
| 
       16756 
17105 
     | 
    
         
             
                    binding_power <= current_binding_powers.left &&
         
     | 
| 
       16757 
17106 
     | 
    
         
             
                    current_binding_powers.binary
         
     | 
| 
       16758 
17107 
     | 
    
         
             
                 ) {
         
     | 
| 
       16759 
     | 
    
         
            -
                    node = parse_expression_infix(parser, node, binding_power, current_binding_powers.right);
         
     | 
| 
       16760 
     | 
    
         
            -
                    if (
         
     | 
| 
       16761 
     | 
    
         
            -
                         
     | 
| 
       16762 
     | 
    
         
            -
                         
     | 
| 
       16763 
     | 
    
         
            -
             
     | 
| 
       16764 
     | 
    
         
            -
             
     | 
| 
      
 17108 
     | 
    
         
            +
                    node = parse_expression_infix(parser, node, binding_power, current_binding_powers.right, accepts_command_call);
         
     | 
| 
      
 17109 
     | 
    
         
            +
                    if (current_binding_powers.nonassoc) {
         
     | 
| 
      
 17110 
     | 
    
         
            +
                        bool endless_range_p = PM_NODE_TYPE_P(node, PM_RANGE_NODE) && ((pm_range_node_t *) node)->right == NULL;
         
     | 
| 
      
 17111 
     | 
    
         
            +
                        pm_binding_power_t left = endless_range_p ? PM_BINDING_POWER_TERM : current_binding_powers.left;
         
     | 
| 
      
 17112 
     | 
    
         
            +
                        if (
         
     | 
| 
      
 17113 
     | 
    
         
            +
                            left <= pm_binding_powers[parser->current.type].left ||
         
     | 
| 
      
 17114 
     | 
    
         
            +
                            // Exceptionally to operator precedences, '1.. & 2' is rejected.
         
     | 
| 
      
 17115 
     | 
    
         
            +
                            // '1.. || 2' is also an exception, but it is handled by the lexer.
         
     | 
| 
      
 17116 
     | 
    
         
            +
                            // (Here, parser->current is PM_TOKEN_PIPE, not PM_TOKEN_PIPE_PIPE).
         
     | 
| 
      
 17117 
     | 
    
         
            +
                            (endless_range_p && match1(parser, PM_TOKEN_AMPERSAND))
         
     | 
| 
      
 17118 
     | 
    
         
            +
                        ) {
         
     | 
| 
      
 17119 
     | 
    
         
            +
                            break;
         
     | 
| 
      
 17120 
     | 
    
         
            +
                        }
         
     | 
| 
      
 17121 
     | 
    
         
            +
                    }
         
     | 
| 
      
 17122 
     | 
    
         
            +
                    if (accepts_command_call) {
         
     | 
| 
      
 17123 
     | 
    
         
            +
                        // A command-style method call is only accepted on method chains.
         
     | 
| 
      
 17124 
     | 
    
         
            +
                        // Thus, we check whether the parsed node can continue method chains.
         
     | 
| 
      
 17125 
     | 
    
         
            +
                        // The method chain can continue if the parsed node is one of the following five kinds:
         
     | 
| 
      
 17126 
     | 
    
         
            +
                        // (1) index access: foo[1]
         
     | 
| 
      
 17127 
     | 
    
         
            +
                        // (2) attribute access: foo.bar
         
     | 
| 
      
 17128 
     | 
    
         
            +
                        // (3) method call with parenthesis: foo.bar(1)
         
     | 
| 
      
 17129 
     | 
    
         
            +
                        // (4) method call with a block: foo.bar do end
         
     | 
| 
      
 17130 
     | 
    
         
            +
                        // (5) constant path: foo::Bar
         
     | 
| 
      
 17131 
     | 
    
         
            +
                        switch (node->type) {
         
     | 
| 
      
 17132 
     | 
    
         
            +
                            case PM_CALL_NODE: {
         
     | 
| 
      
 17133 
     | 
    
         
            +
                                pm_call_node_t *cast = (pm_call_node_t *)node;
         
     | 
| 
      
 17134 
     | 
    
         
            +
                                if (
         
     | 
| 
      
 17135 
     | 
    
         
            +
                                    // (1) foo[1]
         
     | 
| 
      
 17136 
     | 
    
         
            +
                                    !(
         
     | 
| 
      
 17137 
     | 
    
         
            +
                                        cast->call_operator_loc.start == NULL &&
         
     | 
| 
      
 17138 
     | 
    
         
            +
                                        cast->message_loc.start != NULL &&
         
     | 
| 
      
 17139 
     | 
    
         
            +
                                        cast->message_loc.start[0] == '[' &&
         
     | 
| 
      
 17140 
     | 
    
         
            +
                                        cast->message_loc.end[-1] == ']'
         
     | 
| 
      
 17141 
     | 
    
         
            +
                                    ) &&
         
     | 
| 
      
 17142 
     | 
    
         
            +
                                    // (2) foo.bar
         
     | 
| 
      
 17143 
     | 
    
         
            +
                                    !(
         
     | 
| 
      
 17144 
     | 
    
         
            +
                                        cast->call_operator_loc.start != NULL &&
         
     | 
| 
      
 17145 
     | 
    
         
            +
                                        cast->arguments == NULL &&
         
     | 
| 
      
 17146 
     | 
    
         
            +
                                        cast->block == NULL &&
         
     | 
| 
      
 17147 
     | 
    
         
            +
                                        cast->opening_loc.start == NULL
         
     | 
| 
      
 17148 
     | 
    
         
            +
                                    ) &&
         
     | 
| 
      
 17149 
     | 
    
         
            +
                                    // (3) foo.bar(1)
         
     | 
| 
      
 17150 
     | 
    
         
            +
                                    !(
         
     | 
| 
      
 17151 
     | 
    
         
            +
                                        cast->call_operator_loc.start != NULL &&
         
     | 
| 
      
 17152 
     | 
    
         
            +
                                        cast->opening_loc.start != NULL
         
     | 
| 
      
 17153 
     | 
    
         
            +
                                    ) &&
         
     | 
| 
      
 17154 
     | 
    
         
            +
                                    // (4) foo.bar do end
         
     | 
| 
      
 17155 
     | 
    
         
            +
                                    !(
         
     | 
| 
      
 17156 
     | 
    
         
            +
                                        cast->block != NULL && PM_NODE_TYPE_P(cast->block, PM_BLOCK_NODE)
         
     | 
| 
      
 17157 
     | 
    
         
            +
                                    )
         
     | 
| 
      
 17158 
     | 
    
         
            +
                                 ) {
         
     | 
| 
      
 17159 
     | 
    
         
            +
                                    accepts_command_call = false;
         
     | 
| 
      
 17160 
     | 
    
         
            +
                                }
         
     | 
| 
      
 17161 
     | 
    
         
            +
                                break;
         
     | 
| 
      
 17162 
     | 
    
         
            +
                            }
         
     | 
| 
      
 17163 
     | 
    
         
            +
                            // (5) foo::Bar
         
     | 
| 
      
 17164 
     | 
    
         
            +
                            case PM_CONSTANT_PATH_NODE:
         
     | 
| 
      
 17165 
     | 
    
         
            +
                                break;
         
     | 
| 
      
 17166 
     | 
    
         
            +
                            default:
         
     | 
| 
      
 17167 
     | 
    
         
            +
                                accepts_command_call = false;
         
     | 
| 
      
 17168 
     | 
    
         
            +
                                break;
         
     | 
| 
      
 17169 
     | 
    
         
            +
                        }
         
     | 
| 
       16765 
17170 
     | 
    
         
             
                    }
         
     | 
| 
       16766 
17171 
     | 
    
         
             
                }
         
     | 
| 
       16767 
17172 
     | 
    
         | 
| 
         @@ -16825,9 +17230,8 @@ pm_parser_init(pm_parser_t *parser, const uint8_t *source, size_t size, const pm 
     | 
|
| 
       16825 
17230 
     | 
    
         
             
                    .error_list = { 0 },
         
     | 
| 
       16826 
17231 
     | 
    
         
             
                    .current_scope = NULL,
         
     | 
| 
       16827 
17232 
     | 
    
         
             
                    .current_context = NULL,
         
     | 
| 
       16828 
     | 
    
         
            -
                    .encoding =  
     | 
| 
      
 17233 
     | 
    
         
            +
                    .encoding = PM_ENCODING_UTF_8_ENTRY,
         
     | 
| 
       16829 
17234 
     | 
    
         
             
                    .encoding_changed_callback = NULL,
         
     | 
| 
       16830 
     | 
    
         
            -
                    .encoding_decode_callback = NULL,
         
     | 
| 
       16831 
17235 
     | 
    
         
             
                    .encoding_comment_start = source,
         
     | 
| 
       16832 
17236 
     | 
    
         
             
                    .lex_callback = NULL,
         
     | 
| 
       16833 
17237 
     | 
    
         
             
                    .filepath_string = { 0 },
         
     | 
| 
         @@ -16836,11 +17240,13 @@ pm_parser_init(pm_parser_t *parser, const uint8_t *source, size_t size, const pm 
     | 
|
| 
       16836 
17240 
     | 
    
         
             
                    .integer_base = 0,
         
     | 
| 
       16837 
17241 
     | 
    
         
             
                    .current_string = PM_STRING_EMPTY,
         
     | 
| 
       16838 
17242 
     | 
    
         
             
                    .start_line = 1,
         
     | 
| 
      
 17243 
     | 
    
         
            +
                    .explicit_encoding = NULL,
         
     | 
| 
       16839 
17244 
     | 
    
         
             
                    .command_start = true,
         
     | 
| 
       16840 
17245 
     | 
    
         
             
                    .recovering = false,
         
     | 
| 
       16841 
17246 
     | 
    
         
             
                    .encoding_changed = false,
         
     | 
| 
       16842 
17247 
     | 
    
         
             
                    .pattern_matching_newlines = false,
         
     | 
| 
       16843 
17248 
     | 
    
         
             
                    .in_keyword_arg = false,
         
     | 
| 
      
 17249 
     | 
    
         
            +
                    .current_param_name = 0,
         
     | 
| 
       16844 
17250 
     | 
    
         
             
                    .semantic_token_seen = false,
         
     | 
| 
       16845 
17251 
     | 
    
         
             
                    .frozen_string_literal = false,
         
     | 
| 
       16846 
17252 
     | 
    
         
             
                    .suppress_warnings = false
         
     | 
| 
         @@ -16875,9 +17281,7 @@ pm_parser_init(pm_parser_t *parser, const uint8_t *source, size_t size, const pm 
     | 
|
| 
       16875 
17281 
     | 
    
         
             
                    parser->filepath_string = options->filepath;
         
     | 
| 
       16876 
17282 
     | 
    
         | 
| 
       16877 
17283 
     | 
    
         
             
                    // line option
         
     | 
| 
       16878 
     | 
    
         
            -
                     
     | 
| 
       16879 
     | 
    
         
            -
                        parser->start_line = options->line;
         
     | 
| 
       16880 
     | 
    
         
            -
                    }
         
     | 
| 
      
 17284 
     | 
    
         
            +
                    parser->start_line = options->line;
         
     | 
| 
       16881 
17285 
     | 
    
         | 
| 
       16882 
17286 
     | 
    
         
             
                    // encoding option
         
     | 
| 
       16883 
17287 
     | 
    
         
             
                    size_t encoding_length = pm_string_length(&options->encoding);
         
     | 
| 
         @@ -16943,18 +17347,6 @@ pm_parser_register_encoding_changed_callback(pm_parser_t *parser, pm_encoding_ch 
     | 
|
| 
       16943 
17347 
     | 
    
         
             
                parser->encoding_changed_callback = callback;
         
     | 
| 
       16944 
17348 
     | 
    
         
             
            }
         
     | 
| 
       16945 
17349 
     | 
    
         | 
| 
       16946 
     | 
    
         
            -
            /**
         
     | 
| 
       16947 
     | 
    
         
            -
             * Register a callback that will be called when prism encounters a magic comment
         
     | 
| 
       16948 
     | 
    
         
            -
             * with an encoding referenced that it doesn't understand. The callback should
         
     | 
| 
       16949 
     | 
    
         
            -
             * return NULL if it also doesn't understand the encoding or it should return a
         
     | 
| 
       16950 
     | 
    
         
            -
             * pointer to a pm_encoding_t struct that contains the functions necessary to
         
     | 
| 
       16951 
     | 
    
         
            -
             * parse identifiers.
         
     | 
| 
       16952 
     | 
    
         
            -
             */
         
     | 
| 
       16953 
     | 
    
         
            -
            PRISM_EXPORTED_FUNCTION void
         
     | 
| 
       16954 
     | 
    
         
            -
            pm_parser_register_encoding_decode_callback(pm_parser_t *parser, pm_encoding_decode_callback_t callback) {
         
     | 
| 
       16955 
     | 
    
         
            -
                parser->encoding_decode_callback = callback;
         
     | 
| 
       16956 
     | 
    
         
            -
            }
         
     | 
| 
       16957 
     | 
    
         
            -
             
     | 
| 
       16958 
17350 
     | 
    
         
             
            /**
         
     | 
| 
       16959 
17351 
     | 
    
         
             
             * Free all of the memory associated with the comment list.
         
     | 
| 
       16960 
17352 
     | 
    
         
             
             */
         
     | 
| 
         @@ -17046,7 +17438,7 @@ pm_serialize(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) { 
     | 
|
| 
       17046 
17438 
     | 
    
         
             
            PRISM_EXPORTED_FUNCTION void
         
     | 
| 
       17047 
17439 
     | 
    
         
             
            pm_serialize_parse(pm_buffer_t *buffer, const uint8_t *source, size_t size, const char *data) {
         
     | 
| 
       17048 
17440 
     | 
    
         
             
                pm_options_t options = { 0 };
         
     | 
| 
       17049 
     | 
    
         
            -
                 
     | 
| 
      
 17441 
     | 
    
         
            +
                pm_options_read(&options, data);
         
     | 
| 
       17050 
17442 
     | 
    
         | 
| 
       17051 
17443 
     | 
    
         
             
                pm_parser_t parser;
         
     | 
| 
       17052 
17444 
     | 
    
         
             
                pm_parser_init(&parser, source, size, &options);
         
     | 
| 
         @@ -17068,15 +17460,15 @@ pm_serialize_parse(pm_buffer_t *buffer, const uint8_t *source, size_t size, cons 
     | 
|
| 
       17068 
17460 
     | 
    
         
             
            PRISM_EXPORTED_FUNCTION void
         
     | 
| 
       17069 
17461 
     | 
    
         
             
            pm_serialize_parse_comments(pm_buffer_t *buffer, const uint8_t *source, size_t size, const char *data) {
         
     | 
| 
       17070 
17462 
     | 
    
         
             
                pm_options_t options = { 0 };
         
     | 
| 
       17071 
     | 
    
         
            -
                 
     | 
| 
      
 17463 
     | 
    
         
            +
                pm_options_read(&options, data);
         
     | 
| 
       17072 
17464 
     | 
    
         | 
| 
       17073 
17465 
     | 
    
         
             
                pm_parser_t parser;
         
     | 
| 
       17074 
17466 
     | 
    
         
             
                pm_parser_init(&parser, source, size, &options);
         
     | 
| 
       17075 
17467 
     | 
    
         | 
| 
       17076 
17468 
     | 
    
         
             
                pm_node_t *node = pm_parse(&parser);
         
     | 
| 
       17077 
17469 
     | 
    
         
             
                pm_serialize_header(buffer);
         
     | 
| 
       17078 
     | 
    
         
            -
                pm_serialize_encoding( 
     | 
| 
       17079 
     | 
    
         
            -
                 
     | 
| 
      
 17470 
     | 
    
         
            +
                pm_serialize_encoding(parser.encoding, buffer);
         
     | 
| 
      
 17471 
     | 
    
         
            +
                pm_buffer_append_varsint(buffer, parser.start_line);
         
     | 
| 
       17080 
17472 
     | 
    
         
             
                pm_serialize_comment_list(&parser, &parser.comment_list, buffer);
         
     | 
| 
       17081 
17473 
     | 
    
         | 
| 
       17082 
17474 
     | 
    
         
             
                pm_node_destroy(&parser, node);
         
     |