prism 2.0.0.rc2-x86_64-linux-gnu → 2.0.0-x86_64-linux-gnu
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 +9 -2
- data/docs/serialization.md +19 -6
- data/ext/prism/api_node.c +80 -80
- data/ext/prism/extension.c +34 -67
- data/ext/prism/extension.h +1 -1
- data/include/prism/arena.h +8 -0
- data/include/prism/arena.hpp +42 -0
- data/include/prism/ast.h +11 -1
- data/include/prism/ast.hpp +641 -0
- data/include/prism/buffer.h +8 -0
- data/include/prism/buffer.hpp +55 -0
- data/include/prism/comments.h +17 -0
- data/include/prism/compiler/branch.h +26 -0
- data/include/prism/compiler/cplusplus.hpp +16 -0
- data/include/prism/compiler/exceptions.hpp +17 -0
- data/include/prism/compiler/format.h +2 -0
- data/include/prism/compiler/lifetimebound.hpp +25 -0
- data/include/prism/constant_pool.h +25 -0
- data/include/prism/diagnostic.h +18 -0
- data/include/prism/errors_format.h +8 -0
- data/include/prism/internal/node.h +8 -4
- data/include/prism/internal/stringy.h +1 -6
- data/include/prism/json.h +8 -0
- data/include/prism/line_offset_list.h +8 -0
- data/include/prism/magic_comments.h +18 -0
- data/include/prism/node.h +55 -10
- data/include/prism/node.hpp +272 -0
- data/include/prism/node_type.hpp +38 -0
- data/include/prism/options.h +10 -1
- data/include/prism/options.hpp +43 -0
- data/include/prism/parser.h +72 -64
- data/include/prism/parser.hpp +274 -0
- data/include/prism/prettyprint.h +8 -0
- data/include/prism/serialize.h +8 -0
- data/include/prism/source.h +8 -0
- data/include/prism/stream.h +8 -0
- data/include/prism/string_query.h +8 -0
- data/include/prism/stringy.h +16 -27
- data/include/prism/stringy.hpp +31 -0
- data/include/prism/version.h +9 -1
- data/include/prism.h +0 -8
- data/include/prism.hpp +24 -0
- data/lib/prism/3.3/prism.so +0 -0
- data/lib/prism/3.4/prism.so +0 -0
- data/lib/prism/4.0/prism.so +0 -0
- data/lib/prism/serialize.rb +2549 -3281
- data/prism.gemspec +14 -1
- data/rbi/generated/prism/node.rbi +736 -0
- data/rbi/generated/prism/serialize.rbi +6 -5
- data/sig/generated/prism/node.rbs +736 -0
- data/sig/generated/prism/serialize.rbs +7 -5
- data/src/comments.c +2 -2
- data/src/diagnostic.c +8 -0
- data/src/node.c +216 -368
- data/src/options.c +7 -13
- data/src/parser.c +52 -48
- data/src/prism.c +175 -194
- data/src/regexp.c +0 -1
- data/src/serialize.c +2300 -1950
- data/src/source.c +8 -2
- data/src/stringy.c +3 -33
- metadata +14 -1
data/src/prism.c
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#include "prism/compiler/accel.h"
|
|
2
|
+
#include "prism/compiler/branch.h"
|
|
2
3
|
#include "prism/compiler/fallthrough.h"
|
|
3
4
|
#include "prism/compiler/unused.h"
|
|
4
5
|
|
|
@@ -68,24 +69,6 @@
|
|
|
68
69
|
# define PM_STATIC_ASSERT(line, condition, message) typedef char PM_CONCATENATE(static_assert_, line)[(condition) ? 1 : -1]
|
|
69
70
|
#endif
|
|
70
71
|
|
|
71
|
-
/**
|
|
72
|
-
* Support PRISM_LIKELY and PRISM_UNLIKELY to help the compiler optimize its
|
|
73
|
-
* branch predication.
|
|
74
|
-
*/
|
|
75
|
-
#if defined(__GNUC__) || defined(__clang__)
|
|
76
|
-
/** The compiler should predicate that this branch will be taken. */
|
|
77
|
-
#define PRISM_LIKELY(x) __builtin_expect(!!(x), 1)
|
|
78
|
-
|
|
79
|
-
/** The compiler should predicate that this branch will not be taken. */
|
|
80
|
-
#define PRISM_UNLIKELY(x) __builtin_expect(!!(x), 0)
|
|
81
|
-
#else
|
|
82
|
-
/** Void because this platform does not support branch prediction hints. */
|
|
83
|
-
#define PRISM_LIKELY(x) (x)
|
|
84
|
-
|
|
85
|
-
/** Void because this platform does not support branch prediction hints. */
|
|
86
|
-
#define PRISM_UNLIKELY(x) (x)
|
|
87
|
-
#endif
|
|
88
|
-
|
|
89
72
|
/**
|
|
90
73
|
* The prism version and the serialization format.
|
|
91
74
|
*/
|
|
@@ -2452,7 +2435,7 @@ pm_arguments_node_arguments_append(pm_arena_t *arena, pm_arguments_node_t *node,
|
|
|
2452
2435
|
PM_NODE_LENGTH_SET_NODE(node, argument);
|
|
2453
2436
|
}
|
|
2454
2437
|
|
|
2455
|
-
|
|
2438
|
+
pm_node_list_append_inline(arena, &node->arguments, argument);
|
|
2456
2439
|
|
|
2457
2440
|
if (PM_NODE_TYPE_P(argument, PM_SPLAT_NODE)) {
|
|
2458
2441
|
if (PM_NODE_FLAG_P(node, PM_ARGUMENTS_NODE_FLAGS_CONTAINS_SPLAT)) {
|
|
@@ -2500,7 +2483,7 @@ pm_array_node_elements_append(pm_arena_t *arena, pm_array_node_t *node, pm_node_
|
|
|
2500
2483
|
PM_NODE_START_SET_NODE(node, element);
|
|
2501
2484
|
}
|
|
2502
2485
|
|
|
2503
|
-
|
|
2486
|
+
pm_node_list_append_inline(arena, &node->elements, element);
|
|
2504
2487
|
PM_NODE_LENGTH_SET_NODE(node, element);
|
|
2505
2488
|
|
|
2506
2489
|
// If the element is not a static literal, then the array is not a static
|
|
@@ -2553,9 +2536,9 @@ pm_array_pattern_node_node_list_create(pm_parser_t *parser, pm_node_list_t *node
|
|
|
2553
2536
|
node->rest = child;
|
|
2554
2537
|
found_rest = true;
|
|
2555
2538
|
} else if (found_rest) {
|
|
2556
|
-
|
|
2539
|
+
pm_node_list_append_inline(parser->arena, &node->posts, child);
|
|
2557
2540
|
} else {
|
|
2558
|
-
|
|
2541
|
+
pm_node_list_append_inline(parser->arena, &node->requireds, child);
|
|
2559
2542
|
}
|
|
2560
2543
|
}
|
|
2561
2544
|
|
|
@@ -2623,7 +2606,7 @@ pm_array_pattern_node_empty_create(pm_parser_t *parser, const pm_token_t *openin
|
|
|
2623
2606
|
|
|
2624
2607
|
static PRISM_INLINE void
|
|
2625
2608
|
pm_array_pattern_node_requireds_append(pm_arena_t *arena, pm_array_pattern_node_t *node, pm_node_t *inner) {
|
|
2626
|
-
|
|
2609
|
+
pm_node_list_append_inline(arena, &node->requireds, inner);
|
|
2627
2610
|
}
|
|
2628
2611
|
|
|
2629
2612
|
/**
|
|
@@ -2887,7 +2870,7 @@ pm_block_local_variable_node_create(pm_parser_t *parser, const pm_token_t *name)
|
|
|
2887
2870
|
*/
|
|
2888
2871
|
static void
|
|
2889
2872
|
pm_block_parameters_node_append_local(pm_arena_t *arena, pm_block_parameters_node_t *node, const pm_block_local_variable_node_t *local) {
|
|
2890
|
-
|
|
2873
|
+
pm_node_list_append_inline(arena, &node->locals, UP(local));
|
|
2891
2874
|
|
|
2892
2875
|
if (PM_NODE_LENGTH(node) == 0) {
|
|
2893
2876
|
PM_NODE_START_SET_NODE(node, local);
|
|
@@ -3540,7 +3523,7 @@ static void
|
|
|
3540
3523
|
pm_case_node_condition_append(pm_arena_t *arena, pm_case_node_t *node, pm_node_t *condition) {
|
|
3541
3524
|
assert(PM_NODE_TYPE_P(condition, PM_WHEN_NODE));
|
|
3542
3525
|
|
|
3543
|
-
|
|
3526
|
+
pm_node_list_append_inline(arena, &node->conditions, condition);
|
|
3544
3527
|
PM_NODE_LENGTH_SET_NODE(node, condition);
|
|
3545
3528
|
}
|
|
3546
3529
|
|
|
@@ -3587,7 +3570,7 @@ static void
|
|
|
3587
3570
|
pm_case_match_node_condition_append(pm_arena_t *arena, pm_case_match_node_t *node, pm_node_t *condition) {
|
|
3588
3571
|
assert(PM_NODE_TYPE_P(condition, PM_IN_NODE));
|
|
3589
3572
|
|
|
3590
|
-
|
|
3573
|
+
pm_node_list_append_inline(arena, &node->conditions, condition);
|
|
3591
3574
|
PM_NODE_LENGTH_SET_NODE(node, condition);
|
|
3592
3575
|
}
|
|
3593
3576
|
|
|
@@ -4127,7 +4110,7 @@ pm_find_pattern_node_create(pm_parser_t *parser, pm_node_list_t *nodes) {
|
|
|
4127
4110
|
// much more efficient, as we could instead resize the node list to only point
|
|
4128
4111
|
// to 1...-1.
|
|
4129
4112
|
for (size_t index = 1; index < nodes->size - 1; index++) {
|
|
4130
|
-
|
|
4113
|
+
pm_node_list_append_inline(parser->arena, &node->requireds, nodes->nodes[index]);
|
|
4131
4114
|
}
|
|
4132
4115
|
|
|
4133
4116
|
return node;
|
|
@@ -4624,7 +4607,7 @@ pm_hash_node_create(pm_parser_t *parser, const pm_token_t *opening) {
|
|
|
4624
4607
|
*/
|
|
4625
4608
|
static PRISM_INLINE void
|
|
4626
4609
|
pm_hash_node_elements_append(pm_arena_t *arena, pm_hash_node_t *hash, pm_node_t *element) {
|
|
4627
|
-
|
|
4610
|
+
pm_node_list_append_inline(arena, &hash->elements, element);
|
|
4628
4611
|
|
|
4629
4612
|
bool static_literal = PM_NODE_TYPE_P(element, PM_ASSOC_NODE);
|
|
4630
4613
|
if (static_literal) {
|
|
@@ -5049,7 +5032,7 @@ pm_interpolated_node_append(pm_arena_t *arena, pm_node_t *node, pm_node_list_t *
|
|
|
5049
5032
|
break;
|
|
5050
5033
|
}
|
|
5051
5034
|
|
|
5052
|
-
|
|
5035
|
+
pm_node_list_append_inline(arena, parts, part);
|
|
5053
5036
|
}
|
|
5054
5037
|
|
|
5055
5038
|
/**
|
|
@@ -5191,7 +5174,7 @@ pm_interpolated_string_node_append(pm_parser_t *parser, pm_interpolated_string_n
|
|
|
5191
5174
|
// These will only happen in error cases. But we want to handle it
|
|
5192
5175
|
// here so that we don't fail the assertion.
|
|
5193
5176
|
CLEAR_FLAGS(node);
|
|
5194
|
-
|
|
5177
|
+
pm_node_list_append_inline(arena, &node->parts, UP(pm_error_recovery_node_create_unexpected(parser, part)));
|
|
5195
5178
|
return;
|
|
5196
5179
|
case PM_ERROR_RECOVERY_NODE:
|
|
5197
5180
|
CLEAR_FLAGS(node);
|
|
@@ -5201,7 +5184,7 @@ pm_interpolated_string_node_append(pm_parser_t *parser, pm_interpolated_string_n
|
|
|
5201
5184
|
break;
|
|
5202
5185
|
}
|
|
5203
5186
|
|
|
5204
|
-
|
|
5187
|
+
pm_node_list_append_inline(arena, &node->parts, part);
|
|
5205
5188
|
|
|
5206
5189
|
#undef CLEAR_FLAGS
|
|
5207
5190
|
#undef MUTABLE_FLAGS
|
|
@@ -5381,7 +5364,7 @@ pm_keyword_hash_node_elements_append(pm_arena_t *arena, pm_keyword_hash_node_t *
|
|
|
5381
5364
|
pm_node_flag_unset(UP(hash), PM_KEYWORD_HASH_NODE_FLAGS_SYMBOL_KEYS);
|
|
5382
5365
|
}
|
|
5383
5366
|
|
|
5384
|
-
|
|
5367
|
+
pm_node_list_append_inline(arena, &hash->elements, element);
|
|
5385
5368
|
if (PM_NODE_LENGTH(hash) == 0) {
|
|
5386
5369
|
PM_NODE_START_SET_NODE(hash, element);
|
|
5387
5370
|
}
|
|
@@ -5729,19 +5712,19 @@ pm_multi_target_node_targets_append(pm_parser_t *parser, pm_multi_target_node_t
|
|
|
5729
5712
|
node->rest = target;
|
|
5730
5713
|
} else {
|
|
5731
5714
|
pm_parser_err_node(parser, target, PM_ERR_MULTI_ASSIGN_MULTI_SPLATS);
|
|
5732
|
-
|
|
5715
|
+
pm_node_list_append_inline(parser->arena, &node->rights, target);
|
|
5733
5716
|
}
|
|
5734
5717
|
} else if (PM_NODE_TYPE_P(target, PM_IMPLICIT_REST_NODE)) {
|
|
5735
5718
|
if (node->rest == NULL) {
|
|
5736
5719
|
node->rest = target;
|
|
5737
5720
|
} else {
|
|
5738
5721
|
PM_PARSER_ERR_TOKEN_FORMAT_CONTENT(parser, &parser->current, PM_ERR_MULTI_ASSIGN_UNEXPECTED_REST);
|
|
5739
|
-
|
|
5722
|
+
pm_node_list_append_inline(parser->arena, &node->rights, target);
|
|
5740
5723
|
}
|
|
5741
5724
|
} else if (node->rest == NULL) {
|
|
5742
|
-
|
|
5725
|
+
pm_node_list_append_inline(parser->arena, &node->lefts, target);
|
|
5743
5726
|
} else {
|
|
5744
|
-
|
|
5727
|
+
pm_node_list_append_inline(parser->arena, &node->rights, target);
|
|
5745
5728
|
}
|
|
5746
5729
|
|
|
5747
5730
|
if (PM_NODE_LENGTH(node) == 0 || (PM_NODE_START(node) > PM_NODE_START(target))) {
|
|
@@ -6016,7 +5999,7 @@ pm_parameters_node_location_set(pm_parameters_node_t *params, pm_node_t *param)
|
|
|
6016
5999
|
static void
|
|
6017
6000
|
pm_parameters_node_requireds_append(pm_arena_t *arena, pm_parameters_node_t *params, pm_node_t *param) {
|
|
6018
6001
|
pm_parameters_node_location_set(params, param);
|
|
6019
|
-
|
|
6002
|
+
pm_node_list_append_inline(arena, ¶ms->requireds, param);
|
|
6020
6003
|
}
|
|
6021
6004
|
|
|
6022
6005
|
/**
|
|
@@ -6025,7 +6008,7 @@ pm_parameters_node_requireds_append(pm_arena_t *arena, pm_parameters_node_t *par
|
|
|
6025
6008
|
static void
|
|
6026
6009
|
pm_parameters_node_optionals_append(pm_arena_t *arena, pm_parameters_node_t *params, pm_optional_parameter_node_t *param) {
|
|
6027
6010
|
pm_parameters_node_location_set(params, UP(param));
|
|
6028
|
-
|
|
6011
|
+
pm_node_list_append_inline(arena, ¶ms->optionals, UP(param));
|
|
6029
6012
|
}
|
|
6030
6013
|
|
|
6031
6014
|
/**
|
|
@@ -6034,7 +6017,7 @@ pm_parameters_node_optionals_append(pm_arena_t *arena, pm_parameters_node_t *par
|
|
|
6034
6017
|
static void
|
|
6035
6018
|
pm_parameters_node_posts_append(pm_arena_t *arena, pm_parameters_node_t *params, pm_node_t *param) {
|
|
6036
6019
|
pm_parameters_node_location_set(params, param);
|
|
6037
|
-
|
|
6020
|
+
pm_node_list_append_inline(arena, ¶ms->posts, param);
|
|
6038
6021
|
}
|
|
6039
6022
|
|
|
6040
6023
|
/**
|
|
@@ -6052,7 +6035,7 @@ pm_parameters_node_rest_set(pm_parameters_node_t *params, pm_node_t *param) {
|
|
|
6052
6035
|
static void
|
|
6053
6036
|
pm_parameters_node_keywords_append(pm_arena_t *arena, pm_parameters_node_t *params, pm_node_t *param) {
|
|
6054
6037
|
pm_parameters_node_location_set(params, param);
|
|
6055
|
-
|
|
6038
|
+
pm_node_list_append_inline(arena, ¶ms->keywords, param);
|
|
6056
6039
|
}
|
|
6057
6040
|
|
|
6058
6041
|
/**
|
|
@@ -6340,7 +6323,7 @@ pm_rescue_node_subsequent_set(pm_rescue_node_t *node, pm_rescue_node_t *subseque
|
|
|
6340
6323
|
*/
|
|
6341
6324
|
static void
|
|
6342
6325
|
pm_rescue_node_exceptions_append(pm_arena_t *arena, pm_rescue_node_t *node, pm_node_t *exception) {
|
|
6343
|
-
|
|
6326
|
+
pm_node_list_append_inline(arena, &node->exceptions, exception);
|
|
6344
6327
|
PM_NODE_LENGTH_SET_NODE(node, exception);
|
|
6345
6328
|
}
|
|
6346
6329
|
|
|
@@ -6573,7 +6556,7 @@ pm_statements_node_body_append(pm_parser_t *parser, pm_statements_node_t *node,
|
|
|
6573
6556
|
}
|
|
6574
6557
|
}
|
|
6575
6558
|
|
|
6576
|
-
|
|
6559
|
+
pm_node_list_append_inline(parser->arena, &node->body, statement);
|
|
6577
6560
|
if (newline) pm_node_flag_set(statement, PM_NODE_FLAG_NEWLINE);
|
|
6578
6561
|
}
|
|
6579
6562
|
|
|
@@ -6820,7 +6803,7 @@ pm_symbol_node_synthesized_create(pm_parser_t *parser, const char *content) {
|
|
|
6820
6803
|
((pm_string_t) { 0 })
|
|
6821
6804
|
);
|
|
6822
6805
|
|
|
6823
|
-
|
|
6806
|
+
pm_string_init(&node->unescaped, (const uint8_t *) content, strlen(content));
|
|
6824
6807
|
return node;
|
|
6825
6808
|
}
|
|
6826
6809
|
|
|
@@ -6963,7 +6946,7 @@ pm_undef_node_create(pm_parser_t *parser, const pm_token_t *token) {
|
|
|
6963
6946
|
static void
|
|
6964
6947
|
pm_undef_node_append(pm_arena_t *arena, pm_undef_node_t *node, pm_node_t *name) {
|
|
6965
6948
|
PM_NODE_LENGTH_SET_NODE(node, name);
|
|
6966
|
-
|
|
6949
|
+
pm_node_list_append_inline(arena, &node->names, name);
|
|
6967
6950
|
}
|
|
6968
6951
|
|
|
6969
6952
|
/**
|
|
@@ -7105,7 +7088,7 @@ pm_when_node_create(pm_parser_t *parser, const pm_token_t *keyword) {
|
|
|
7105
7088
|
static void
|
|
7106
7089
|
pm_when_node_conditions_append(pm_arena_t *arena, pm_when_node_t *node, pm_node_t *condition) {
|
|
7107
7090
|
PM_NODE_LENGTH_SET_NODE(node, condition);
|
|
7108
|
-
|
|
7091
|
+
pm_node_list_append_inline(arena, &node->conditions, condition);
|
|
7109
7092
|
}
|
|
7110
7093
|
|
|
7111
7094
|
/**
|
|
@@ -7692,6 +7675,27 @@ parser_lex_magic_comment_emacs_marker(pm_parser_t *parser, const uint8_t *cursor
|
|
|
7692
7675
|
return NULL;
|
|
7693
7676
|
}
|
|
7694
7677
|
|
|
7678
|
+
/**
|
|
7679
|
+
* Returns true if the given magic comment key matches the given name, which is
|
|
7680
|
+
* written in lowercase with underscores and is the same length as the key.
|
|
7681
|
+
* Keys match case-insensitively, and a dash in the key matches an underscore in
|
|
7682
|
+
* the name. Every byte of a name is ASCII, so a byte of a multibyte character
|
|
7683
|
+
* in the key never matches one.
|
|
7684
|
+
*/
|
|
7685
|
+
static bool
|
|
7686
|
+
parser_magic_comment_key_p(const uint8_t *key, size_t key_length, const char *name) {
|
|
7687
|
+
assert(name[key_length] == '\0');
|
|
7688
|
+
|
|
7689
|
+
for (size_t index = 0; index < key_length; index++) {
|
|
7690
|
+
uint8_t byte = key[index];
|
|
7691
|
+
if (byte == '-') byte = '_';
|
|
7692
|
+
if ('A' <= byte && byte <= 'Z') byte |= 0x20;
|
|
7693
|
+
if (byte != (uint8_t) name[index]) return false;
|
|
7694
|
+
}
|
|
7695
|
+
|
|
7696
|
+
return true;
|
|
7697
|
+
}
|
|
7698
|
+
|
|
7695
7699
|
/**
|
|
7696
7700
|
* Parse the current token on the parser to see if it's a magic comment and
|
|
7697
7701
|
* potentially perform some action based on that. A regular expression that this
|
|
@@ -7783,73 +7787,34 @@ parser_lex_magic_comment(pm_parser_t *parser, bool semantic_token_seen) {
|
|
|
7783
7787
|
if (cursor != end) return false;
|
|
7784
7788
|
}
|
|
7785
7789
|
|
|
7786
|
-
|
|
7787
|
-
|
|
7788
|
-
pm_string_t key;
|
|
7790
|
+
/* Finally, we can start checking the key against the list of known
|
|
7791
|
+
* magic comment keys, and potentially change state based on that. */
|
|
7789
7792
|
const size_t key_length = (size_t) (key_end - key_start);
|
|
7790
|
-
const uint8_t *dash = pm_memchr(key_start, '-', key_length, parser->encoding_changed, parser->encoding);
|
|
7791
|
-
|
|
7792
|
-
if (dash == NULL) {
|
|
7793
|
-
pm_string_shared_init(&key, key_start, key_end);
|
|
7794
|
-
} else {
|
|
7795
|
-
uint8_t *buffer = xmalloc(key_length);
|
|
7796
|
-
if (buffer == NULL) break;
|
|
7797
|
-
|
|
7798
|
-
memcpy(buffer, key_start, key_length);
|
|
7799
|
-
buffer[dash - key_start] = '_';
|
|
7800
|
-
|
|
7801
|
-
while ((dash = pm_memchr(dash + 1, '-', (size_t) (key_end - dash - 1), parser->encoding_changed, parser->encoding)) != NULL) {
|
|
7802
|
-
buffer[dash - key_start] = '_';
|
|
7803
|
-
}
|
|
7804
|
-
|
|
7805
|
-
pm_string_owned_init(&key, buffer, key_length);
|
|
7806
|
-
}
|
|
7807
|
-
|
|
7808
|
-
// Finally, we can start checking the key against the list of known
|
|
7809
|
-
// magic comment keys, and potentially change state based on that.
|
|
7810
|
-
const uint8_t *key_source = pm_string_source(&key);
|
|
7811
7793
|
uint32_t value_length = (uint32_t) (value_end - value_start);
|
|
7812
7794
|
|
|
7813
|
-
|
|
7814
|
-
|
|
7815
|
-
|
|
7816
|
-
|
|
7817
|
-
|
|
7818
|
-
(
|
|
7819
|
-
|
|
7820
|
-
|
|
7821
|
-
|
|
7822
|
-
}
|
|
7823
|
-
|
|
7824
|
-
if (key_length == 11) {
|
|
7825
|
-
if (pm_strncasecmp(key_source, (const uint8_t *) "warn_indent", 11) == 0) {
|
|
7826
|
-
switch (parser_lex_magic_comment_boolean_value(value_start, value_length)) {
|
|
7827
|
-
case PM_MAGIC_COMMENT_BOOLEAN_VALUE_INVALID:
|
|
7828
|
-
PM_PARSER_WARN_TOKEN_FORMAT(
|
|
7829
|
-
parser,
|
|
7830
|
-
&parser->current,
|
|
7831
|
-
PM_WARN_INVALID_MAGIC_COMMENT_VALUE,
|
|
7832
|
-
(int) key_length,
|
|
7833
|
-
(const char *) key_source,
|
|
7834
|
-
(int) value_length,
|
|
7835
|
-
(const char *) value_start
|
|
7836
|
-
);
|
|
7837
|
-
break;
|
|
7838
|
-
case PM_MAGIC_COMMENT_BOOLEAN_VALUE_FALSE:
|
|
7839
|
-
parser->warn_mismatched_indentation = false;
|
|
7840
|
-
break;
|
|
7841
|
-
case PM_MAGIC_COMMENT_BOOLEAN_VALUE_TRUE:
|
|
7842
|
-
parser->warn_mismatched_indentation = true;
|
|
7843
|
-
break;
|
|
7795
|
+
switch (key_length) {
|
|
7796
|
+
case 6:
|
|
7797
|
+
/* We only want to attempt to compare against encoding comments
|
|
7798
|
+
* if it is the first line in the file (or the second in the
|
|
7799
|
+
* case of a shebang). */
|
|
7800
|
+
if (parser->current.start == parser->encoding_comment_start && !parser->encoding_locked) {
|
|
7801
|
+
if (parser_magic_comment_key_p(key_start, key_length, "coding")) {
|
|
7802
|
+
result = parser_lex_magic_comment_encoding_value(parser, value_start, value_end);
|
|
7803
|
+
}
|
|
7844
7804
|
}
|
|
7845
|
-
|
|
7846
|
-
|
|
7847
|
-
|
|
7848
|
-
|
|
7849
|
-
|
|
7850
|
-
if (
|
|
7851
|
-
|
|
7852
|
-
|
|
7805
|
+
break;
|
|
7806
|
+
case 8:
|
|
7807
|
+
/* We only want to attempt to compare against encoding comments
|
|
7808
|
+
* if it is the first line in the file (or the second in the
|
|
7809
|
+
* case of a shebang). */
|
|
7810
|
+
if (parser->current.start == parser->encoding_comment_start && !parser->encoding_locked) {
|
|
7811
|
+
if (parser_magic_comment_key_p(key_start, key_length, "encoding")) {
|
|
7812
|
+
result = parser_lex_magic_comment_encoding_value(parser, value_start, value_end);
|
|
7813
|
+
}
|
|
7814
|
+
}
|
|
7815
|
+
break;
|
|
7816
|
+
case 11:
|
|
7817
|
+
if (parser_magic_comment_key_p(key_start, key_length, "warn_indent")) {
|
|
7853
7818
|
switch (parser_lex_magic_comment_boolean_value(value_start, value_length)) {
|
|
7854
7819
|
case PM_MAGIC_COMMENT_BOOLEAN_VALUE_INVALID:
|
|
7855
7820
|
PM_PARSER_WARN_TOKEN_FORMAT(
|
|
@@ -7857,53 +7822,79 @@ parser_lex_magic_comment(pm_parser_t *parser, bool semantic_token_seen) {
|
|
|
7857
7822
|
&parser->current,
|
|
7858
7823
|
PM_WARN_INVALID_MAGIC_COMMENT_VALUE,
|
|
7859
7824
|
(int) key_length,
|
|
7860
|
-
|
|
7825
|
+
"warn_indent",
|
|
7861
7826
|
(int) value_length,
|
|
7862
7827
|
(const char *) value_start
|
|
7863
7828
|
);
|
|
7864
7829
|
break;
|
|
7865
7830
|
case PM_MAGIC_COMMENT_BOOLEAN_VALUE_FALSE:
|
|
7866
|
-
parser->
|
|
7831
|
+
parser->warn_mismatched_indentation = false;
|
|
7867
7832
|
break;
|
|
7868
7833
|
case PM_MAGIC_COMMENT_BOOLEAN_VALUE_TRUE:
|
|
7869
|
-
parser->
|
|
7834
|
+
parser->warn_mismatched_indentation = true;
|
|
7870
7835
|
break;
|
|
7871
7836
|
}
|
|
7872
7837
|
}
|
|
7873
|
-
|
|
7874
|
-
|
|
7875
|
-
|
|
7876
|
-
|
|
7877
|
-
|
|
7878
|
-
|
|
7879
|
-
|
|
7880
|
-
|
|
7881
|
-
|
|
7882
|
-
|
|
7883
|
-
|
|
7884
|
-
|
|
7885
|
-
|
|
7886
|
-
|
|
7887
|
-
|
|
7888
|
-
|
|
7889
|
-
|
|
7890
|
-
|
|
7891
|
-
|
|
7892
|
-
|
|
7893
|
-
|
|
7894
|
-
|
|
7895
|
-
|
|
7896
|
-
|
|
7897
|
-
|
|
7898
|
-
|
|
7838
|
+
break;
|
|
7839
|
+
case 21:
|
|
7840
|
+
if (parser_magic_comment_key_p(key_start, key_length, "frozen_string_literal")) {
|
|
7841
|
+
/* We only want to handle frozen string literal comments if
|
|
7842
|
+
* it is before any semantic tokens have been seen. */
|
|
7843
|
+
if (semantic_token_seen) {
|
|
7844
|
+
pm_parser_warn_token(parser, &parser->current, PM_WARN_IGNORED_FROZEN_STRING_LITERAL);
|
|
7845
|
+
} else {
|
|
7846
|
+
switch (parser_lex_magic_comment_boolean_value(value_start, value_length)) {
|
|
7847
|
+
case PM_MAGIC_COMMENT_BOOLEAN_VALUE_INVALID:
|
|
7848
|
+
PM_PARSER_WARN_TOKEN_FORMAT(
|
|
7849
|
+
parser,
|
|
7850
|
+
&parser->current,
|
|
7851
|
+
PM_WARN_INVALID_MAGIC_COMMENT_VALUE,
|
|
7852
|
+
(int) key_length,
|
|
7853
|
+
"frozen_string_literal",
|
|
7854
|
+
(int) value_length,
|
|
7855
|
+
(const char *) value_start
|
|
7856
|
+
);
|
|
7857
|
+
break;
|
|
7858
|
+
case PM_MAGIC_COMMENT_BOOLEAN_VALUE_FALSE:
|
|
7859
|
+
parser->frozen_string_literal = PM_OPTIONS_FROZEN_STRING_LITERAL_DISABLED;
|
|
7860
|
+
break;
|
|
7861
|
+
case PM_MAGIC_COMMENT_BOOLEAN_VALUE_TRUE:
|
|
7862
|
+
parser->frozen_string_literal = PM_OPTIONS_FROZEN_STRING_LITERAL_ENABLED;
|
|
7863
|
+
break;
|
|
7864
|
+
}
|
|
7865
|
+
}
|
|
7899
7866
|
}
|
|
7900
|
-
|
|
7867
|
+
break;
|
|
7868
|
+
case 24:
|
|
7869
|
+
if (parser_magic_comment_key_p(key_start, key_length, "shareable_constant_value")) {
|
|
7870
|
+
const uint8_t *cursor = parser->current.start;
|
|
7871
|
+
while ((cursor > parser->start) && ((cursor[-1] == ' ') || (cursor[-1] == '\t'))) cursor--;
|
|
7872
|
+
|
|
7873
|
+
if (!((cursor == parser->start) || (cursor[-1] == '\n'))) {
|
|
7874
|
+
pm_parser_warn_token(parser, &parser->current, PM_WARN_SHAREABLE_CONSTANT_VALUE_LINE);
|
|
7875
|
+
} else if (value_length == 4 && pm_strncasecmp(value_start, (const uint8_t *) "none", 4) == 0) {
|
|
7876
|
+
pm_parser_scope_shareable_constant_set(parser, PM_SCOPE_SHAREABLE_CONSTANT_NONE);
|
|
7877
|
+
} else if (value_length == 7 && pm_strncasecmp(value_start, (const uint8_t *) "literal", 7) == 0) {
|
|
7878
|
+
pm_parser_scope_shareable_constant_set(parser, PM_SCOPE_SHAREABLE_CONSTANT_LITERAL);
|
|
7879
|
+
} else if (value_length == 23 && pm_strncasecmp(value_start, (const uint8_t *) "experimental_everything", 23) == 0) {
|
|
7880
|
+
pm_parser_scope_shareable_constant_set(parser, PM_SCOPE_SHAREABLE_CONSTANT_EXPERIMENTAL_EVERYTHING);
|
|
7881
|
+
} else if (value_length == 17 && pm_strncasecmp(value_start, (const uint8_t *) "experimental_copy", 17) == 0) {
|
|
7882
|
+
pm_parser_scope_shareable_constant_set(parser, PM_SCOPE_SHAREABLE_CONSTANT_EXPERIMENTAL_COPY);
|
|
7883
|
+
} else {
|
|
7884
|
+
PM_PARSER_WARN_TOKEN_FORMAT(
|
|
7885
|
+
parser,
|
|
7886
|
+
&parser->current,
|
|
7887
|
+
PM_WARN_INVALID_MAGIC_COMMENT_VALUE,
|
|
7888
|
+
(int) key_length,
|
|
7889
|
+
"shareable_constant_value",
|
|
7890
|
+
(int) value_length,
|
|
7891
|
+
(const char *) value_start
|
|
7892
|
+
);
|
|
7893
|
+
}
|
|
7894
|
+
}
|
|
7895
|
+
break;
|
|
7901
7896
|
}
|
|
7902
7897
|
|
|
7903
|
-
// When we're done, we want to free the string in case we had to
|
|
7904
|
-
// allocate memory for it.
|
|
7905
|
-
pm_string_cleanup(&key);
|
|
7906
|
-
|
|
7907
7898
|
// Allocate a new magic comment node to append to the parser's list.
|
|
7908
7899
|
pm_magic_comment_t *magic_comment = (pm_magic_comment_t *) pm_arena_alloc(&parser->metadata_arena, sizeof(pm_magic_comment_t), PRISM_ALIGNOF(pm_magic_comment_t));
|
|
7909
7900
|
magic_comment->node.next = NULL;
|
|
@@ -9650,7 +9641,7 @@ lex_question_mark(pm_parser_t *parser) {
|
|
|
9650
9641
|
|
|
9651
9642
|
// Copy buffer data into the arena and free the heap buffer.
|
|
9652
9643
|
void *arena_data = pm_arena_memdup(parser->arena, buffer.value, buffer.length, PRISM_ALIGNOF(uint8_t));
|
|
9653
|
-
|
|
9644
|
+
pm_string_init(&parser->current_string, (const uint8_t *) arena_data, buffer.length);
|
|
9654
9645
|
pm_buffer_cleanup(&buffer);
|
|
9655
9646
|
|
|
9656
9647
|
return PM_TOKEN_CHARACTER_LITERAL;
|
|
@@ -9974,7 +9965,7 @@ pm_token_buffer_copy(pm_parser_t *parser, pm_token_buffer_t *token_buffer) {
|
|
|
9974
9965
|
// Copy buffer data into the arena and free the heap buffer.
|
|
9975
9966
|
size_t len = pm_buffer_length(&token_buffer->buffer);
|
|
9976
9967
|
void *arena_data = pm_arena_memdup(parser->arena, pm_buffer_value(&token_buffer->buffer), len, PRISM_ALIGNOF(uint8_t));
|
|
9977
|
-
|
|
9968
|
+
pm_string_init(&parser->current_string, (const uint8_t *) arena_data, len);
|
|
9978
9969
|
pm_buffer_cleanup(&token_buffer->buffer);
|
|
9979
9970
|
}
|
|
9980
9971
|
|
|
@@ -13187,7 +13178,7 @@ parse_starred_expression(pm_parser_t *parser, pm_binding_power_t binding_power,
|
|
|
13187
13178
|
return parse_value_expression(parser, binding_power, flags, diag_id, depth);
|
|
13188
13179
|
}
|
|
13189
13180
|
|
|
13190
|
-
static
|
|
13181
|
+
static pm_visit_result_t
|
|
13191
13182
|
pm_node_unreference_each(const pm_node_t *node, void *data) {
|
|
13192
13183
|
switch (PM_NODE_TYPE(node)) {
|
|
13193
13184
|
/* When we are about to destroy a set of nodes that could potentially
|
|
@@ -13213,15 +13204,15 @@ pm_node_unreference_each(const pm_node_t *node, void *data) {
|
|
|
13213
13204
|
}
|
|
13214
13205
|
parser->current_block_exits->size--;
|
|
13215
13206
|
|
|
13216
|
-
/* Note
|
|
13207
|
+
/* Note descending here because these nodes could have
|
|
13217
13208
|
* arguments that are themselves block exits. */
|
|
13218
|
-
return
|
|
13209
|
+
return PM_VISIT_DESCEND;
|
|
13219
13210
|
}
|
|
13220
13211
|
|
|
13221
13212
|
index++;
|
|
13222
13213
|
}
|
|
13223
13214
|
|
|
13224
|
-
return
|
|
13215
|
+
return PM_VISIT_DESCEND;
|
|
13225
13216
|
}
|
|
13226
13217
|
/* When an implicit local variable is written to or targeted, it becomes
|
|
13227
13218
|
* a regular, named local variable. This branch removes it from the list
|
|
@@ -13245,10 +13236,10 @@ pm_node_unreference_each(const pm_node_t *node, void *data) {
|
|
|
13245
13236
|
}
|
|
13246
13237
|
}
|
|
13247
13238
|
|
|
13248
|
-
return
|
|
13239
|
+
return PM_VISIT_SKIP;
|
|
13249
13240
|
}
|
|
13250
13241
|
default:
|
|
13251
|
-
return
|
|
13242
|
+
return PM_VISIT_DESCEND;
|
|
13252
13243
|
}
|
|
13253
13244
|
}
|
|
13254
13245
|
|
|
@@ -15990,7 +15981,7 @@ ensure_valid_jump(pm_parser_t *parser, pm_node_t *node) {
|
|
|
15990
15981
|
// block exit to the list of exits for the expression, and
|
|
15991
15982
|
// the node parsing will handle validating it instead.
|
|
15992
15983
|
assert(parser->current_block_exits != NULL);
|
|
15993
|
-
|
|
15984
|
+
pm_node_list_append_inline(parser->arena, parser->current_block_exits, node);
|
|
15994
15985
|
return;
|
|
15995
15986
|
case PM_CONTEXT_BEGIN_ELSE:
|
|
15996
15987
|
case PM_CONTEXT_BEGIN_ENSURE:
|
|
@@ -16728,12 +16719,12 @@ parse_variable(pm_parser_t *parser) {
|
|
|
16728
16719
|
}
|
|
16729
16720
|
|
|
16730
16721
|
pm_node_t *node = UP(pm_local_variable_read_node_create_constant_id(parser, &parser->previous, name_id, 0, false));
|
|
16731
|
-
|
|
16722
|
+
pm_node_list_append_inline(parser->arena, ¤t_scope->implicit_parameters, node);
|
|
16732
16723
|
|
|
16733
16724
|
return node;
|
|
16734
16725
|
} else if ((parser->version >= PM_OPTIONS_VERSION_CRUBY_3_4) && pm_token_is_it(parser->previous.start, parser->previous.end)) {
|
|
16735
16726
|
pm_node_t *node = UP(pm_it_local_variable_read_node_create(parser, &parser->previous));
|
|
16736
|
-
|
|
16727
|
+
pm_node_list_append_inline(parser->arena, ¤t_scope->implicit_parameters, node);
|
|
16737
16728
|
|
|
16738
16729
|
return node;
|
|
16739
16730
|
}
|
|
@@ -16790,18 +16781,13 @@ parse_method_definition_name(pm_parser_t *parser) {
|
|
|
16790
16781
|
|
|
16791
16782
|
static void
|
|
16792
16783
|
parse_heredoc_dedent_string(pm_arena_t *arena, pm_string_t *string, size_t common_whitespace) {
|
|
16793
|
-
// Make a writable copy
|
|
16794
|
-
// We keep a mutable pointer to the arena memory so we can
|
|
16795
|
-
// below without casting away const from the string's
|
|
16796
|
-
|
|
16797
|
-
|
|
16798
|
-
|
|
16799
|
-
|
|
16800
|
-
writable = (uint8_t *) pm_arena_memdup(arena, pm_string_source(string), length, PRISM_ALIGNOF(uint8_t));
|
|
16801
|
-
pm_string_constant_init(string, (const char *) writable, length);
|
|
16802
|
-
} else {
|
|
16803
|
-
writable = (uint8_t *) string->source;
|
|
16804
|
-
}
|
|
16784
|
+
// Make a writable copy of the string in the arena, since strings only view
|
|
16785
|
+
// their bytes. We keep a mutable pointer to the arena memory so we can
|
|
16786
|
+
// memmove into it below without casting away const from the string's
|
|
16787
|
+
// source field.
|
|
16788
|
+
size_t length = pm_string_length(string);
|
|
16789
|
+
uint8_t *writable = (uint8_t *) pm_arena_memdup(arena, pm_string_source(string), length, PRISM_ALIGNOF(uint8_t));
|
|
16790
|
+
pm_string_init(string, writable, length);
|
|
16805
16791
|
|
|
16806
16792
|
// Now get the bounds of the existing string. We'll use this as a
|
|
16807
16793
|
// destination to move bytes into. We'll also use it for bounds checking
|
|
@@ -16966,11 +16952,11 @@ parse_strings(pm_parser_t *parser, pm_node_t *current, bool accepts_label, uint1
|
|
|
16966
16952
|
if (match1(parser, PM_TOKEN_STRING_CONTENT)) {
|
|
16967
16953
|
pm_node_list_t parts = { 0 };
|
|
16968
16954
|
pm_node_t *part = UP(pm_string_node_create_unescaped(parser, NULL, &content, NULL, &unescaped));
|
|
16969
|
-
|
|
16955
|
+
pm_node_list_append_inline(parser->arena, &parts, part);
|
|
16970
16956
|
|
|
16971
16957
|
do {
|
|
16972
16958
|
part = UP(pm_string_node_create_current_string(parser, NULL, &parser->current, NULL));
|
|
16973
|
-
|
|
16959
|
+
pm_node_list_append_inline(parser->arena, &parts, part);
|
|
16974
16960
|
parser_lex(parser);
|
|
16975
16961
|
} while (match1(parser, PM_TOKEN_STRING_CONTENT));
|
|
16976
16962
|
|
|
@@ -17025,11 +17011,11 @@ parse_strings(pm_parser_t *parser, pm_node_t *current, bool accepts_label, uint1
|
|
|
17025
17011
|
pm_node_list_t parts = { 0 };
|
|
17026
17012
|
pm_node_t *part = UP(pm_string_node_create_unescaped(parser, NULL, &parser->previous, NULL, &unescaped));
|
|
17027
17013
|
pm_node_flag_set(part, parse_unescaped_encoding(parser, explicit_encoding));
|
|
17028
|
-
|
|
17014
|
+
pm_node_list_append_inline(parser->arena, &parts, part);
|
|
17029
17015
|
|
|
17030
17016
|
while (!match3(parser, PM_TOKEN_STRING_END, PM_TOKEN_LABEL_END, PM_TOKEN_EOF)) {
|
|
17031
17017
|
if ((part = parse_string_part(parser, (uint16_t) (depth + 1))) != NULL) {
|
|
17032
|
-
|
|
17018
|
+
pm_node_list_append_inline(parser->arena, &parts, part);
|
|
17033
17019
|
}
|
|
17034
17020
|
}
|
|
17035
17021
|
|
|
@@ -17053,7 +17039,7 @@ parse_strings(pm_parser_t *parser, pm_node_t *current, bool accepts_label, uint1
|
|
|
17053
17039
|
|
|
17054
17040
|
while (!match3(parser, PM_TOKEN_STRING_END, PM_TOKEN_LABEL_END, PM_TOKEN_EOF)) {
|
|
17055
17041
|
if ((part = parse_string_part(parser, (uint16_t) (depth + 1))) != NULL) {
|
|
17056
|
-
|
|
17042
|
+
pm_node_list_append_inline(parser->arena, &parts, part);
|
|
17057
17043
|
}
|
|
17058
17044
|
}
|
|
17059
17045
|
|
|
@@ -17439,7 +17425,7 @@ parse_pattern_hash(pm_parser_t *parser, pm_constant_id_set_t *captures, pm_node_
|
|
|
17439
17425
|
}
|
|
17440
17426
|
|
|
17441
17427
|
pm_node_t *assoc = UP(pm_assoc_node_create(parser, first_node, NULL, value));
|
|
17442
|
-
|
|
17428
|
+
pm_node_list_append_inline(parser->arena, &assocs, assoc);
|
|
17443
17429
|
break;
|
|
17444
17430
|
}
|
|
17445
17431
|
}
|
|
@@ -17454,7 +17440,7 @@ parse_pattern_hash(pm_parser_t *parser, pm_constant_id_set_t *captures, pm_node_
|
|
|
17454
17440
|
pm_node_t *value = UP(pm_error_recovery_node_create(parser, PM_NODE_START(first_node), PM_NODE_LENGTH(first_node)));
|
|
17455
17441
|
pm_node_t *assoc = UP(pm_assoc_node_create(parser, first_node, NULL, value));
|
|
17456
17442
|
|
|
17457
|
-
|
|
17443
|
+
pm_node_list_append_inline(parser->arena, &assocs, assoc);
|
|
17458
17444
|
break;
|
|
17459
17445
|
}
|
|
17460
17446
|
}
|
|
@@ -17482,7 +17468,7 @@ parse_pattern_hash(pm_parser_t *parser, pm_constant_id_set_t *captures, pm_node_
|
|
|
17482
17468
|
rest = assoc;
|
|
17483
17469
|
} else {
|
|
17484
17470
|
pm_parser_err_node(parser, assoc, PM_ERR_PATTERN_EXPRESSION_AFTER_REST);
|
|
17485
|
-
|
|
17471
|
+
pm_node_list_append_inline(parser->arena, &assocs, assoc);
|
|
17486
17472
|
}
|
|
17487
17473
|
} else {
|
|
17488
17474
|
pm_node_t *key;
|
|
@@ -17528,7 +17514,7 @@ parse_pattern_hash(pm_parser_t *parser, pm_constant_id_set_t *captures, pm_node_
|
|
|
17528
17514
|
pm_parser_err_node(parser, assoc, PM_ERR_PATTERN_EXPRESSION_AFTER_REST);
|
|
17529
17515
|
}
|
|
17530
17516
|
|
|
17531
|
-
|
|
17517
|
+
pm_node_list_append_inline(parser->arena, &assocs, assoc);
|
|
17532
17518
|
}
|
|
17533
17519
|
}
|
|
17534
17520
|
|
|
@@ -17808,7 +17794,7 @@ parse_pattern_primitive(pm_parser_t *parser, pm_constant_id_set_t *captures, pm_
|
|
|
17808
17794
|
* are not captures of this pattern. A nested alternation is not visited
|
|
17809
17795
|
* either: its operands were already checked when it was parsed.
|
|
17810
17796
|
*/
|
|
17811
|
-
static
|
|
17797
|
+
static pm_visit_result_t
|
|
17812
17798
|
parse_pattern_alternation_error_each(const pm_node_t *node, void *data) {
|
|
17813
17799
|
pm_parser_t *parser = (pm_parser_t *) data;
|
|
17814
17800
|
|
|
@@ -17819,7 +17805,7 @@ parse_pattern_alternation_error_each(const pm_node_t *node, void *data) {
|
|
|
17819
17805
|
if (peek_at(parser, parser->start + PM_NODE_START(node)) != '_') {
|
|
17820
17806
|
pm_parser_err(parser, PM_NODE_START(node), PM_NODE_LENGTH(node), PM_ERR_PATTERN_CAPTURE_IN_ALTERNATIVE);
|
|
17821
17807
|
}
|
|
17822
|
-
return
|
|
17808
|
+
return PM_VISIT_SKIP;
|
|
17823
17809
|
case PM_ARRAY_PATTERN_NODE:
|
|
17824
17810
|
case PM_ASSOC_NODE:
|
|
17825
17811
|
case PM_ASSOC_SPLAT_NODE:
|
|
@@ -17829,9 +17815,9 @@ parse_pattern_alternation_error_each(const pm_node_t *node, void *data) {
|
|
|
17829
17815
|
case PM_IMPLICIT_NODE:
|
|
17830
17816
|
case PM_PARENTHESES_NODE:
|
|
17831
17817
|
case PM_SPLAT_NODE:
|
|
17832
|
-
return
|
|
17818
|
+
return PM_VISIT_DESCEND;
|
|
17833
17819
|
default:
|
|
17834
|
-
return
|
|
17820
|
+
return PM_VISIT_SKIP;
|
|
17835
17821
|
}
|
|
17836
17822
|
}
|
|
17837
17823
|
|
|
@@ -18027,7 +18013,7 @@ parse_pattern(pm_parser_t *parser, pm_constant_id_set_t *captures, uint8_t flags
|
|
|
18027
18013
|
// or a find pattern. We need to parse all of the patterns, put them
|
|
18028
18014
|
// into a big list, and then determine which type of node we have.
|
|
18029
18015
|
pm_node_list_t nodes = { 0 };
|
|
18030
|
-
|
|
18016
|
+
pm_node_list_append_inline(parser->arena, &nodes, node);
|
|
18031
18017
|
|
|
18032
18018
|
// Gather up all of the patterns into the list.
|
|
18033
18019
|
while (accept1(parser, PM_TOKEN_COMMA)) {
|
|
@@ -18046,7 +18032,7 @@ parse_pattern(pm_parser_t *parser, pm_constant_id_set_t *captures, uint8_t flags
|
|
|
18046
18032
|
}
|
|
18047
18033
|
|
|
18048
18034
|
node = UP(pm_implicit_rest_node_create(parser, &parser->previous));
|
|
18049
|
-
|
|
18035
|
+
pm_node_list_append_inline(parser->arena, &nodes, node);
|
|
18050
18036
|
trailing_rest = true;
|
|
18051
18037
|
break;
|
|
18052
18038
|
}
|
|
@@ -18066,7 +18052,7 @@ parse_pattern(pm_parser_t *parser, pm_constant_id_set_t *captures, uint8_t flags
|
|
|
18066
18052
|
node = parse_pattern_primitives(parser, captures, NULL, PM_ERR_PATTERN_EXPRESSION_AFTER_COMMA, (uint16_t) (depth + 1));
|
|
18067
18053
|
}
|
|
18068
18054
|
|
|
18069
|
-
|
|
18055
|
+
pm_node_list_append_inline(parser->arena, &nodes, node);
|
|
18070
18056
|
}
|
|
18071
18057
|
|
|
18072
18058
|
// If the first pattern and the last pattern are rest patterns, then we
|
|
@@ -19572,11 +19558,11 @@ parse_heredoc(pm_parser_t *parser, uint16_t depth) {
|
|
|
19572
19558
|
// so we'll need to create an interpolated string node to hold
|
|
19573
19559
|
// them all.
|
|
19574
19560
|
pm_node_list_t parts = { 0 };
|
|
19575
|
-
|
|
19561
|
+
pm_node_list_append_inline(parser->arena, &parts, part);
|
|
19576
19562
|
|
|
19577
19563
|
while (!match2(parser, PM_TOKEN_HEREDOC_END, PM_TOKEN_EOF)) {
|
|
19578
19564
|
if ((part = parse_string_part(parser, (uint16_t) (depth + 1))) != NULL) {
|
|
19579
|
-
|
|
19565
|
+
pm_node_list_append_inline(parser->arena, &parts, part);
|
|
19580
19566
|
}
|
|
19581
19567
|
}
|
|
19582
19568
|
|
|
@@ -21845,7 +21831,7 @@ parse_regular_expression_named_capture(pm_parser_t *parser, const pm_string_t *c
|
|
|
21845
21831
|
pm_token_t token = { .type = 0, .start = start, .end = end };
|
|
21846
21832
|
pm_location_t token_loc = TOK2LOC(parser, &token);
|
|
21847
21833
|
pm_node_t *target = UP(pm_local_variable_target_node_create(parser, &token_loc, name, depth == -1 ? 0 : (uint32_t) depth));
|
|
21848
|
-
|
|
21834
|
+
pm_node_list_append_inline(parser->arena, &name_data->match->targets, target);
|
|
21849
21835
|
}
|
|
21850
21836
|
|
|
21851
21837
|
pm_buffer_cleanup(&unescaped);
|
|
@@ -22014,9 +22000,7 @@ parse_match(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t binding_pow
|
|
|
22014
22000
|
}
|
|
22015
22001
|
|
|
22016
22002
|
if (!interpolated && total_length > 0) {
|
|
22017
|
-
|
|
22018
|
-
if (!memory) abort();
|
|
22019
|
-
|
|
22003
|
+
uint8_t *memory = (uint8_t *) pm_arena_alloc(&parser->metadata_arena, total_length, PRISM_ALIGNOF(uint8_t));
|
|
22020
22004
|
uint8_t *cursor = memory;
|
|
22021
22005
|
PM_NODE_LIST_FOREACH(parts, index, part) {
|
|
22022
22006
|
pm_string_t *unescaped = &((pm_string_node_t *) part)->unescaped;
|
|
@@ -22026,11 +22010,9 @@ parse_match(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t binding_pow
|
|
|
22026
22010
|
cursor += length;
|
|
22027
22011
|
}
|
|
22028
22012
|
|
|
22029
|
-
pm_string_t
|
|
22030
|
-
|
|
22031
|
-
|
|
22032
|
-
result = parse_interpolated_regular_expression_named_captures(parser, &owned, call, PM_NODE_FLAG_P(node, PM_REGULAR_EXPRESSION_FLAGS_EXTENDED));
|
|
22033
|
-
pm_string_cleanup(&owned);
|
|
22013
|
+
pm_string_t content;
|
|
22014
|
+
pm_string_init(&content, memory, total_length);
|
|
22015
|
+
result = parse_interpolated_regular_expression_named_captures(parser, &content, call, PM_NODE_FLAG_P(node, PM_REGULAR_EXPRESSION_FLAGS_EXTENDED));
|
|
22034
22016
|
}
|
|
22035
22017
|
} else if (PM_NODE_TYPE_P(node, PM_REGULAR_EXPRESSION_NODE)) {
|
|
22036
22018
|
/* If we have a regular expression node, then we can parse the named
|
|
@@ -22040,7 +22022,7 @@ parse_match(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t binding_pow
|
|
|
22040
22022
|
.call = call,
|
|
22041
22023
|
.match = NULL,
|
|
22042
22024
|
.names = { 0 },
|
|
22043
|
-
.shared = regexp->unescaped
|
|
22025
|
+
.shared = pm_string_source(®exp->unescaped) == parser->start + regexp->content_loc.start,
|
|
22044
22026
|
};
|
|
22045
22027
|
|
|
22046
22028
|
pm_node_flag_set(UP(regexp), pm_regexp_parse(parser, regexp, parse_regular_expression_named_capture, &name_data));
|
|
@@ -23566,7 +23548,6 @@ pm_parser_new(pm_arena_t *arena, const uint8_t *source, size_t size, const pm_op
|
|
|
23566
23548
|
*/
|
|
23567
23549
|
void
|
|
23568
23550
|
pm_parser_cleanup(pm_parser_t *parser) {
|
|
23569
|
-
pm_string_cleanup(&parser->filepath);
|
|
23570
23551
|
pm_arena_cleanup(&parser->metadata_arena);
|
|
23571
23552
|
|
|
23572
23553
|
while (parser->lex_modes.index >= PM_LEX_STACK_SIZE) {
|