prism 1.0.0 → 1.1.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 +26 -1
- data/README.md +1 -0
- data/config.yml +257 -20
- data/docs/parsing_rules.md +4 -1
- data/ext/prism/extension.c +63 -26
- data/ext/prism/extension.h +1 -1
- data/include/prism/ast.h +559 -327
- data/include/prism/defines.h +27 -0
- data/include/prism/diagnostic.h +5 -1
- data/include/prism/options.h +39 -2
- data/include/prism/parser.h +7 -0
- data/include/prism/util/pm_string.h +27 -4
- data/include/prism/version.h +2 -2
- data/lib/prism/dot_visitor.rb +2 -0
- data/lib/prism/dsl.rb +10 -8
- data/lib/prism/ffi.rb +37 -3
- data/lib/prism/inspect_visitor.rb +1 -1
- data/lib/prism/lex_compat.rb +1 -1
- data/lib/prism/node.rb +132 -89
- data/lib/prism/parse_result.rb +1 -1
- data/lib/prism/reflection.rb +1 -1
- data/lib/prism/serialize.rb +6 -2
- data/lib/prism/translation/parser/lexer.rb +25 -3
- data/lib/prism/translation/ruby_parser.rb +7 -1
- data/prism.gemspec +1 -2
- data/rbi/prism/dsl.rbi +32 -32
- data/rbi/prism/node.rbi +69 -59
- data/rbi/prism.rbi +34 -34
- data/sig/prism/dsl.rbs +24 -24
- data/sig/prism/node.rbs +113 -105
- data/sig/prism.rbs +90 -72
- data/src/diagnostic.c +15 -7
- data/src/node.c +10 -0
- data/src/options.c +58 -27
- data/src/prettyprint.c +10 -0
- data/src/prism.c +588 -385
- data/src/util/pm_string.c +123 -65
- metadata +2 -3
- data/lib/prism/translation/parser/rubocop.rb +0 -73
data/src/prism.c
CHANGED
@@ -168,6 +168,7 @@ lex_mode_push_regexp(pm_parser_t *parser, uint8_t incrementor, uint8_t terminato
|
|
168
168
|
breakpoints[index++] = incrementor;
|
169
169
|
}
|
170
170
|
|
171
|
+
parser->explicit_encoding = NULL;
|
171
172
|
return lex_mode_push(parser, lex_mode);
|
172
173
|
}
|
173
174
|
|
@@ -277,11 +278,6 @@ lex_state_beg_p(pm_parser_t *parser) {
|
|
277
278
|
return lex_state_p(parser, PM_LEX_STATE_BEG_ANY) || ((parser->lex_state & (PM_LEX_STATE_ARG | PM_LEX_STATE_LABELED)) == (PM_LEX_STATE_ARG | PM_LEX_STATE_LABELED));
|
278
279
|
}
|
279
280
|
|
280
|
-
static inline bool
|
281
|
-
lex_state_arg_labeled_p(pm_parser_t *parser) {
|
282
|
-
return (parser->lex_state & (PM_LEX_STATE_ARG | PM_LEX_STATE_LABELED)) == (PM_LEX_STATE_ARG | PM_LEX_STATE_LABELED);
|
283
|
-
}
|
284
|
-
|
285
281
|
static inline bool
|
286
282
|
lex_state_arg_p(pm_parser_t *parser) {
|
287
283
|
return lex_state_p(parser, PM_LEX_STATE_ARG_ANY);
|
@@ -1038,7 +1034,7 @@ pm_parser_optional_constant_id_token(pm_parser_t *parser, const pm_token_t *toke
|
|
1038
1034
|
*/
|
1039
1035
|
static pm_node_t *
|
1040
1036
|
pm_check_value_expression(pm_parser_t *parser, pm_node_t *node) {
|
1041
|
-
pm_node_t*
|
1037
|
+
pm_node_t *void_node = NULL;
|
1042
1038
|
|
1043
1039
|
while (node != NULL) {
|
1044
1040
|
switch (PM_NODE_TYPE(node)) {
|
@@ -1054,24 +1050,43 @@ pm_check_value_expression(pm_parser_t *parser, pm_node_t *node) {
|
|
1054
1050
|
case PM_BEGIN_NODE: {
|
1055
1051
|
pm_begin_node_t *cast = (pm_begin_node_t *) node;
|
1056
1052
|
|
1057
|
-
if (cast->
|
1058
|
-
node = (pm_node_t *) cast->ensure_clause;
|
1059
|
-
}
|
1060
|
-
else {
|
1053
|
+
if (cast->ensure_clause != NULL) {
|
1061
1054
|
if (cast->rescue_clause != NULL) {
|
1062
|
-
|
1063
|
-
|
1064
|
-
|
1065
|
-
|
1066
|
-
|
1055
|
+
pm_node_t *vn = pm_check_value_expression(parser, (pm_node_t *) cast->rescue_clause);
|
1056
|
+
if (vn != NULL) return vn;
|
1057
|
+
}
|
1058
|
+
|
1059
|
+
if (cast->statements != NULL) {
|
1060
|
+
pm_node_t *vn = pm_check_value_expression(parser, (pm_node_t *) cast->statements);
|
1061
|
+
if (vn != NULL) return vn;
|
1062
|
+
}
|
1063
|
+
|
1064
|
+
node = (pm_node_t *) cast->ensure_clause;
|
1065
|
+
} else if (cast->rescue_clause != NULL) {
|
1066
|
+
if (cast->statements == NULL) return NULL;
|
1067
|
+
|
1068
|
+
pm_node_t *vn = pm_check_value_expression(parser, (pm_node_t *) cast->statements);
|
1069
|
+
if (vn == NULL) return NULL;
|
1070
|
+
if (void_node == NULL) void_node = vn;
|
1071
|
+
|
1072
|
+
for (pm_rescue_node_t *rescue_clause = cast->rescue_clause; rescue_clause != NULL; rescue_clause = rescue_clause->subsequent) {
|
1073
|
+
pm_node_t *vn = pm_check_value_expression(parser, (pm_node_t *) rescue_clause->statements);
|
1074
|
+
if (vn == NULL) {
|
1075
|
+
void_node = NULL;
|
1076
|
+
break;
|
1067
1077
|
}
|
1068
|
-
|
1069
|
-
|
1078
|
+
if (void_node == NULL) {
|
1079
|
+
void_node = vn;
|
1070
1080
|
}
|
1071
1081
|
}
|
1072
|
-
|
1073
|
-
|
1082
|
+
|
1083
|
+
if (cast->else_clause != NULL) {
|
1084
|
+
node = (pm_node_t *) cast->else_clause;
|
1085
|
+
} else {
|
1086
|
+
return void_node;
|
1074
1087
|
}
|
1088
|
+
} else {
|
1089
|
+
node = (pm_node_t *) cast->statements;
|
1075
1090
|
}
|
1076
1091
|
|
1077
1092
|
break;
|
@@ -2065,7 +2080,11 @@ pm_arguments_node_arguments_append(pm_arguments_node_t *node, pm_node_t *argumen
|
|
2065
2080
|
pm_node_list_append(&node->arguments, argument);
|
2066
2081
|
|
2067
2082
|
if (PM_NODE_TYPE_P(argument, PM_SPLAT_NODE)) {
|
2068
|
-
|
2083
|
+
if (PM_NODE_FLAG_P(node, PM_ARGUMENTS_NODE_FLAGS_CONTAINS_SPLAT)) {
|
2084
|
+
pm_node_flag_set((pm_node_t *) node, PM_ARGUMENTS_NODE_FLAGS_CONTAINS_MULTIPLE_SPLATS);
|
2085
|
+
} else {
|
2086
|
+
pm_node_flag_set((pm_node_t *) node, PM_ARGUMENTS_NODE_FLAGS_CONTAINS_SPLAT);
|
2087
|
+
}
|
2069
2088
|
}
|
2070
2089
|
}
|
2071
2090
|
|
@@ -2985,6 +3004,7 @@ pm_index_and_write_node_create(pm_parser_t *parser, pm_call_node_t *target, cons
|
|
2985
3004
|
|
2986
3005
|
pm_index_arguments_check(parser, target->arguments, target->block);
|
2987
3006
|
|
3007
|
+
assert(!target->block || PM_NODE_TYPE_P(target->block, PM_BLOCK_ARGUMENT_NODE));
|
2988
3008
|
*node = (pm_index_and_write_node_t) {
|
2989
3009
|
{
|
2990
3010
|
.type = PM_INDEX_AND_WRITE_NODE,
|
@@ -3000,7 +3020,7 @@ pm_index_and_write_node_create(pm_parser_t *parser, pm_call_node_t *target, cons
|
|
3000
3020
|
.opening_loc = target->opening_loc,
|
3001
3021
|
.arguments = target->arguments,
|
3002
3022
|
.closing_loc = target->closing_loc,
|
3003
|
-
.block = target->block,
|
3023
|
+
.block = (pm_block_argument_node_t *) target->block,
|
3004
3024
|
.operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
|
3005
3025
|
.value = value
|
3006
3026
|
};
|
@@ -3060,6 +3080,7 @@ pm_index_operator_write_node_create(pm_parser_t *parser, pm_call_node_t *target,
|
|
3060
3080
|
|
3061
3081
|
pm_index_arguments_check(parser, target->arguments, target->block);
|
3062
3082
|
|
3083
|
+
assert(!target->block || PM_NODE_TYPE_P(target->block, PM_BLOCK_ARGUMENT_NODE));
|
3063
3084
|
*node = (pm_index_operator_write_node_t) {
|
3064
3085
|
{
|
3065
3086
|
.type = PM_INDEX_OPERATOR_WRITE_NODE,
|
@@ -3075,7 +3096,7 @@ pm_index_operator_write_node_create(pm_parser_t *parser, pm_call_node_t *target,
|
|
3075
3096
|
.opening_loc = target->opening_loc,
|
3076
3097
|
.arguments = target->arguments,
|
3077
3098
|
.closing_loc = target->closing_loc,
|
3078
|
-
.block = target->block,
|
3099
|
+
.block = (pm_block_argument_node_t *) target->block,
|
3079
3100
|
.binary_operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1),
|
3080
3101
|
.binary_operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
|
3081
3102
|
.value = value
|
@@ -3137,6 +3158,7 @@ pm_index_or_write_node_create(pm_parser_t *parser, pm_call_node_t *target, const
|
|
3137
3158
|
|
3138
3159
|
pm_index_arguments_check(parser, target->arguments, target->block);
|
3139
3160
|
|
3161
|
+
assert(!target->block || PM_NODE_TYPE_P(target->block, PM_BLOCK_ARGUMENT_NODE));
|
3140
3162
|
*node = (pm_index_or_write_node_t) {
|
3141
3163
|
{
|
3142
3164
|
.type = PM_INDEX_OR_WRITE_NODE,
|
@@ -3152,7 +3174,7 @@ pm_index_or_write_node_create(pm_parser_t *parser, pm_call_node_t *target, const
|
|
3152
3174
|
.opening_loc = target->opening_loc,
|
3153
3175
|
.arguments = target->arguments,
|
3154
3176
|
.closing_loc = target->closing_loc,
|
3155
|
-
.block = target->block,
|
3177
|
+
.block = (pm_block_argument_node_t *) target->block,
|
3156
3178
|
.operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
|
3157
3179
|
.value = value
|
3158
3180
|
};
|
@@ -3205,6 +3227,7 @@ pm_index_target_node_create(pm_parser_t *parser, pm_call_node_t *target) {
|
|
3205
3227
|
|
3206
3228
|
pm_index_arguments_check(parser, target->arguments, target->block);
|
3207
3229
|
|
3230
|
+
assert(!target->block || PM_NODE_TYPE_P(target->block, PM_BLOCK_ARGUMENT_NODE));
|
3208
3231
|
*node = (pm_index_target_node_t) {
|
3209
3232
|
{
|
3210
3233
|
.type = PM_INDEX_TARGET_NODE,
|
@@ -3216,7 +3239,7 @@ pm_index_target_node_create(pm_parser_t *parser, pm_call_node_t *target) {
|
|
3216
3239
|
.opening_loc = target->opening_loc,
|
3217
3240
|
.arguments = target->arguments,
|
3218
3241
|
.closing_loc = target->closing_loc,
|
3219
|
-
.block = target->block
|
3242
|
+
.block = (pm_block_argument_node_t *) target->block,
|
3220
3243
|
};
|
3221
3244
|
|
3222
3245
|
// Here we're going to free the target, since it is no longer necessary.
|
@@ -3231,7 +3254,7 @@ pm_index_target_node_create(pm_parser_t *parser, pm_call_node_t *target) {
|
|
3231
3254
|
* Allocate and initialize a new CapturePatternNode node.
|
3232
3255
|
*/
|
3233
3256
|
static pm_capture_pattern_node_t *
|
3234
|
-
pm_capture_pattern_node_create(pm_parser_t *parser, pm_node_t *value,
|
3257
|
+
pm_capture_pattern_node_create(pm_parser_t *parser, pm_node_t *value, pm_local_variable_target_node_t *target, const pm_token_t *operator) {
|
3235
3258
|
pm_capture_pattern_node_t *node = PM_NODE_ALLOC(parser, pm_capture_pattern_node_t);
|
3236
3259
|
|
3237
3260
|
*node = (pm_capture_pattern_node_t) {
|
@@ -3240,7 +3263,7 @@ pm_capture_pattern_node_create(pm_parser_t *parser, pm_node_t *value, pm_node_t
|
|
3240
3263
|
.node_id = PM_NODE_IDENTIFY(parser),
|
3241
3264
|
.location = {
|
3242
3265
|
.start = value->location.start,
|
3243
|
-
.end = target->location.end
|
3266
|
+
.end = target->base.location.end
|
3244
3267
|
},
|
3245
3268
|
},
|
3246
3269
|
.value = value,
|
@@ -4032,14 +4055,25 @@ pm_find_pattern_node_create(pm_parser_t *parser, pm_node_list_t *nodes) {
|
|
4032
4055
|
pm_find_pattern_node_t *node = PM_NODE_ALLOC(parser, pm_find_pattern_node_t);
|
4033
4056
|
|
4034
4057
|
pm_node_t *left = nodes->nodes[0];
|
4058
|
+
assert(PM_NODE_TYPE_P(left, PM_SPLAT_NODE));
|
4059
|
+
pm_splat_node_t *left_splat_node = (pm_splat_node_t *) left;
|
4060
|
+
|
4035
4061
|
pm_node_t *right;
|
4036
4062
|
|
4037
4063
|
if (nodes->size == 1) {
|
4038
4064
|
right = (pm_node_t *) pm_missing_node_create(parser, left->location.end, left->location.end);
|
4039
4065
|
} else {
|
4040
4066
|
right = nodes->nodes[nodes->size - 1];
|
4067
|
+
assert(PM_NODE_TYPE_P(right, PM_SPLAT_NODE));
|
4041
4068
|
}
|
4042
4069
|
|
4070
|
+
#if PRISM_SERIALIZE_ONLY_SEMANTICS_FIELDS
|
4071
|
+
// FindPatternNode#right is typed as SplatNode in this case, so replace the potential MissingNode with a SplatNode.
|
4072
|
+
// The resulting AST will anyway be ignored, but this file still needs to compile.
|
4073
|
+
pm_splat_node_t *right_splat_node = PM_NODE_TYPE_P(right, PM_SPLAT_NODE) ? (pm_splat_node_t *) right : left_splat_node;
|
4074
|
+
#else
|
4075
|
+
pm_node_t *right_splat_node = right;
|
4076
|
+
#endif
|
4043
4077
|
*node = (pm_find_pattern_node_t) {
|
4044
4078
|
{
|
4045
4079
|
.type = PM_FIND_PATTERN_NODE,
|
@@ -4050,8 +4084,8 @@ pm_find_pattern_node_create(pm_parser_t *parser, pm_node_list_t *nodes) {
|
|
4050
4084
|
},
|
4051
4085
|
},
|
4052
4086
|
.constant = NULL,
|
4053
|
-
.left =
|
4054
|
-
.right =
|
4087
|
+
.left = left_splat_node,
|
4088
|
+
.right = right_splat_node,
|
4055
4089
|
.requireds = { 0 },
|
4056
4090
|
.opening_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE,
|
4057
4091
|
.closing_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE
|
@@ -6147,14 +6181,14 @@ pm_numbered_reference_read_node_number(pm_parser_t *parser, const pm_token_t *to
|
|
6147
6181
|
errno = 0;
|
6148
6182
|
unsigned long value = strtoul(digits, &endptr, 10);
|
6149
6183
|
|
6150
|
-
if ((digits == endptr) || (*endptr != '\0')
|
6184
|
+
if ((digits == endptr) || (*endptr != '\0')) {
|
6151
6185
|
pm_parser_err(parser, start, end, PM_ERR_INVALID_NUMBER_DECIMAL);
|
6152
6186
|
value = 0;
|
6153
6187
|
}
|
6154
6188
|
|
6155
6189
|
xfree(digits);
|
6156
6190
|
|
6157
|
-
if (value > NTH_REF_MAX) {
|
6191
|
+
if ((errno == ERANGE) || (value > NTH_REF_MAX)) {
|
6158
6192
|
PM_PARSER_WARN_FORMAT(parser, start, end, PM_WARN_INVALID_NUMBERED_REFERENCE, (int) (length + 1), (const char *) token->start);
|
6159
6193
|
value = 0;
|
6160
6194
|
}
|
@@ -11273,7 +11307,16 @@ parser_lex(pm_parser_t *parser) {
|
|
11273
11307
|
|
11274
11308
|
pm_token_type_t type = PM_TOKEN_AMPERSAND;
|
11275
11309
|
if (lex_state_spcarg_p(parser, space_seen)) {
|
11276
|
-
|
11310
|
+
if ((peek(parser) != ':') || (peek_offset(parser, 1) == '\0')) {
|
11311
|
+
pm_parser_warn_token(parser, &parser->current, PM_WARN_AMBIGUOUS_PREFIX_AMPERSAND);
|
11312
|
+
} else {
|
11313
|
+
const uint8_t delim = peek_offset(parser, 1);
|
11314
|
+
|
11315
|
+
if ((delim != '\'') && (delim != '"') && !char_is_identifier(parser, parser->current.end + 1)) {
|
11316
|
+
pm_parser_warn_token(parser, &parser->current, PM_WARN_AMBIGUOUS_PREFIX_AMPERSAND);
|
11317
|
+
}
|
11318
|
+
}
|
11319
|
+
|
11277
11320
|
type = PM_TOKEN_UAMPERSAND;
|
11278
11321
|
} else if (lex_state_beg_p(parser)) {
|
11279
11322
|
type = PM_TOKEN_UAMPERSAND;
|
@@ -11409,10 +11452,7 @@ parser_lex(pm_parser_t *parser) {
|
|
11409
11452
|
if (match(parser, '.')) {
|
11410
11453
|
if (match(parser, '.')) {
|
11411
11454
|
// If we're _not_ inside a range within default parameters
|
11412
|
-
if (
|
11413
|
-
!context_p(parser, PM_CONTEXT_DEFAULT_PARAMS) &&
|
11414
|
-
context_p(parser, PM_CONTEXT_DEF_PARAMS)
|
11415
|
-
) {
|
11455
|
+
if (!context_p(parser, PM_CONTEXT_DEFAULT_PARAMS) && context_p(parser, PM_CONTEXT_DEF_PARAMS)) {
|
11416
11456
|
if (lex_state_p(parser, PM_LEX_STATE_END)) {
|
11417
11457
|
lex_state_set(parser, PM_LEX_STATE_BEG);
|
11418
11458
|
} else {
|
@@ -13138,15 +13178,15 @@ expect1_heredoc_term(pm_parser_t *parser, pm_lex_mode_t *lex_mode) {
|
|
13138
13178
|
}
|
13139
13179
|
|
13140
13180
|
static pm_node_t *
|
13141
|
-
parse_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool accepts_command_call, pm_diagnostic_id_t diag_id);
|
13181
|
+
parse_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool accepts_command_call, bool accepts_label, pm_diagnostic_id_t diag_id, uint16_t depth);
|
13142
13182
|
|
13143
13183
|
/**
|
13144
13184
|
* This is a wrapper of parse_expression, which also checks whether the
|
13145
13185
|
* resulting node is a value expression.
|
13146
13186
|
*/
|
13147
13187
|
static pm_node_t *
|
13148
|
-
parse_value_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool accepts_command_call, pm_diagnostic_id_t diag_id) {
|
13149
|
-
pm_node_t *node = parse_expression(parser, binding_power, accepts_command_call, diag_id);
|
13188
|
+
parse_value_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool accepts_command_call, bool accepts_label, pm_diagnostic_id_t diag_id, uint16_t depth) {
|
13189
|
+
pm_node_t *node = parse_expression(parser, binding_power, accepts_command_call, accepts_label, diag_id, depth);
|
13150
13190
|
pm_assert_value_expression(parser, node);
|
13151
13191
|
return node;
|
13152
13192
|
}
|
@@ -13230,14 +13270,14 @@ token_begins_expression_p(pm_token_type_t type) {
|
|
13230
13270
|
* prefixed by the * operator.
|
13231
13271
|
*/
|
13232
13272
|
static pm_node_t *
|
13233
|
-
parse_starred_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool accepts_command_call, pm_diagnostic_id_t diag_id) {
|
13273
|
+
parse_starred_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool accepts_command_call, pm_diagnostic_id_t diag_id, uint16_t depth) {
|
13234
13274
|
if (accept1(parser, PM_TOKEN_USTAR)) {
|
13235
13275
|
pm_token_t operator = parser->previous;
|
13236
|
-
pm_node_t *expression = parse_value_expression(parser, binding_power, false, PM_ERR_EXPECT_EXPRESSION_AFTER_STAR);
|
13276
|
+
pm_node_t *expression = parse_value_expression(parser, binding_power, false, false, PM_ERR_EXPECT_EXPRESSION_AFTER_STAR, (uint16_t) (depth + 1));
|
13237
13277
|
return (pm_node_t *) pm_splat_node_create(parser, &operator, expression);
|
13238
13278
|
}
|
13239
13279
|
|
13240
|
-
return parse_value_expression(parser, binding_power, accepts_command_call, diag_id);
|
13280
|
+
return parse_value_expression(parser, binding_power, accepts_command_call, false, diag_id, depth);
|
13241
13281
|
}
|
13242
13282
|
|
13243
13283
|
/**
|
@@ -13731,7 +13771,7 @@ parse_unwriteable_write(pm_parser_t *parser, pm_node_t *target, const pm_token_t
|
|
13731
13771
|
* target node or a multi-target node.
|
13732
13772
|
*/
|
13733
13773
|
static pm_node_t *
|
13734
|
-
parse_targets(pm_parser_t *parser, pm_node_t *first_target, pm_binding_power_t binding_power) {
|
13774
|
+
parse_targets(pm_parser_t *parser, pm_node_t *first_target, pm_binding_power_t binding_power, uint16_t depth) {
|
13735
13775
|
bool has_rest = PM_NODE_TYPE_P(first_target, PM_SPLAT_NODE);
|
13736
13776
|
|
13737
13777
|
pm_multi_target_node_t *result = pm_multi_target_node_create(parser);
|
@@ -13750,7 +13790,7 @@ parse_targets(pm_parser_t *parser, pm_node_t *first_target, pm_binding_power_t b
|
|
13750
13790
|
pm_node_t *name = NULL;
|
13751
13791
|
|
13752
13792
|
if (token_begins_expression_p(parser->current.type)) {
|
13753
|
-
name = parse_expression(parser, binding_power, false, PM_ERR_EXPECT_EXPRESSION_AFTER_STAR);
|
13793
|
+
name = parse_expression(parser, binding_power, false, false, PM_ERR_EXPECT_EXPRESSION_AFTER_STAR, (uint16_t) (depth + 1));
|
13754
13794
|
name = parse_target(parser, name, true, true);
|
13755
13795
|
}
|
13756
13796
|
|
@@ -13758,7 +13798,7 @@ parse_targets(pm_parser_t *parser, pm_node_t *first_target, pm_binding_power_t b
|
|
13758
13798
|
pm_multi_target_node_targets_append(parser, result, splat);
|
13759
13799
|
has_rest = true;
|
13760
13800
|
} else if (token_begins_expression_p(parser->current.type)) {
|
13761
|
-
pm_node_t *target = parse_expression(parser, binding_power, false, PM_ERR_EXPECT_EXPRESSION_AFTER_COMMA);
|
13801
|
+
pm_node_t *target = parse_expression(parser, binding_power, false, false, PM_ERR_EXPECT_EXPRESSION_AFTER_COMMA, (uint16_t) (depth + 1));
|
13762
13802
|
target = parse_target(parser, target, true, false);
|
13763
13803
|
|
13764
13804
|
pm_multi_target_node_targets_append(parser, result, target);
|
@@ -13779,8 +13819,8 @@ parse_targets(pm_parser_t *parser, pm_node_t *first_target, pm_binding_power_t b
|
|
13779
13819
|
* assignment.
|
13780
13820
|
*/
|
13781
13821
|
static pm_node_t *
|
13782
|
-
parse_targets_validate(pm_parser_t *parser, pm_node_t *first_target, pm_binding_power_t binding_power) {
|
13783
|
-
pm_node_t *result = parse_targets(parser, first_target, binding_power);
|
13822
|
+
parse_targets_validate(pm_parser_t *parser, pm_node_t *first_target, pm_binding_power_t binding_power, uint16_t depth) {
|
13823
|
+
pm_node_t *result = parse_targets(parser, first_target, binding_power, depth);
|
13784
13824
|
accept1(parser, PM_TOKEN_NEWLINE);
|
13785
13825
|
|
13786
13826
|
// Ensure that we have either an = or a ) after the targets.
|
@@ -13795,7 +13835,7 @@ parse_targets_validate(pm_parser_t *parser, pm_node_t *first_target, pm_binding_
|
|
13795
13835
|
* Parse a list of statements separated by newlines or semicolons.
|
13796
13836
|
*/
|
13797
13837
|
static pm_statements_node_t *
|
13798
|
-
parse_statements(pm_parser_t *parser, pm_context_t context) {
|
13838
|
+
parse_statements(pm_parser_t *parser, pm_context_t context, uint16_t depth) {
|
13799
13839
|
// First, skip past any optional terminators that might be at the beginning
|
13800
13840
|
// of the statements.
|
13801
13841
|
while (accept2(parser, PM_TOKEN_SEMICOLON, PM_TOKEN_NEWLINE));
|
@@ -13810,7 +13850,7 @@ parse_statements(pm_parser_t *parser, pm_context_t context) {
|
|
13810
13850
|
context_push(parser, context);
|
13811
13851
|
|
13812
13852
|
while (true) {
|
13813
|
-
pm_node_t *node = parse_expression(parser, PM_BINDING_POWER_STATEMENT, true, PM_ERR_CANNOT_PARSE_EXPRESSION);
|
13853
|
+
pm_node_t *node = parse_expression(parser, PM_BINDING_POWER_STATEMENT, true, false, PM_ERR_CANNOT_PARSE_EXPRESSION, (uint16_t) (depth + 1));
|
13814
13854
|
pm_statements_node_body_append(parser, statements, node, true);
|
13815
13855
|
|
13816
13856
|
// If we're recovering from a syntax error, then we need to stop parsing
|
@@ -13930,7 +13970,7 @@ pm_when_clause_static_literals_add(pm_parser_t *parser, pm_static_literals_t *li
|
|
13930
13970
|
* Parse all of the elements of a hash. Return true if a double splat was found.
|
13931
13971
|
*/
|
13932
13972
|
static bool
|
13933
|
-
parse_assocs(pm_parser_t *parser, pm_static_literals_t *literals, pm_node_t *node) {
|
13973
|
+
parse_assocs(pm_parser_t *parser, pm_static_literals_t *literals, pm_node_t *node, uint16_t depth) {
|
13934
13974
|
assert(PM_NODE_TYPE_P(node, PM_HASH_NODE) || PM_NODE_TYPE_P(node, PM_KEYWORD_HASH_NODE));
|
13935
13975
|
bool contains_keyword_splat = false;
|
13936
13976
|
|
@@ -13949,9 +13989,9 @@ parse_assocs(pm_parser_t *parser, pm_static_literals_t *literals, pm_node_t *nod
|
|
13949
13989
|
// inner hash to share the static literals with the outer
|
13950
13990
|
// hash.
|
13951
13991
|
parser->current_hash_keys = literals;
|
13952
|
-
value = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH);
|
13992
|
+
value = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, false, PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH, (uint16_t) (depth + 1));
|
13953
13993
|
} else if (token_begins_expression_p(parser->current.type)) {
|
13954
|
-
value = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH);
|
13994
|
+
value = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, false, PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH, (uint16_t) (depth + 1));
|
13955
13995
|
} else {
|
13956
13996
|
pm_parser_scope_forwarding_keywords_check(parser, &operator);
|
13957
13997
|
}
|
@@ -13971,7 +14011,7 @@ parse_assocs(pm_parser_t *parser, pm_static_literals_t *literals, pm_node_t *nod
|
|
13971
14011
|
pm_node_t *value = NULL;
|
13972
14012
|
|
13973
14013
|
if (token_begins_expression_p(parser->current.type)) {
|
13974
|
-
value = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_HASH_EXPRESSION_AFTER_LABEL);
|
14014
|
+
value = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, false, PM_ERR_HASH_EXPRESSION_AFTER_LABEL, (uint16_t) (depth + 1));
|
13975
14015
|
} else {
|
13976
14016
|
if (parser->encoding->isupper_char(label.start, (label.end - 1) - label.start)) {
|
13977
14017
|
pm_token_t constant = { .type = PM_TOKEN_CONSTANT, .start = label.start, .end = label.end - 1 };
|
@@ -14001,7 +14041,7 @@ parse_assocs(pm_parser_t *parser, pm_static_literals_t *literals, pm_node_t *nod
|
|
14001
14041
|
break;
|
14002
14042
|
}
|
14003
14043
|
default: {
|
14004
|
-
pm_node_t *key = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_HASH_KEY);
|
14044
|
+
pm_node_t *key = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, true, PM_ERR_HASH_KEY, (uint16_t) (depth + 1));
|
14005
14045
|
|
14006
14046
|
// Hash keys that are strings are automatically frozen. We will
|
14007
14047
|
// mark that here.
|
@@ -14019,7 +14059,7 @@ parse_assocs(pm_parser_t *parser, pm_static_literals_t *literals, pm_node_t *nod
|
|
14019
14059
|
operator = parser->previous;
|
14020
14060
|
}
|
14021
14061
|
|
14022
|
-
pm_node_t *value = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_HASH_VALUE);
|
14062
|
+
pm_node_t *value = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, false, PM_ERR_HASH_VALUE, (uint16_t) (depth + 1));
|
14023
14063
|
element = (pm_node_t *) pm_assoc_node_create(parser, key, &operator, value);
|
14024
14064
|
break;
|
14025
14065
|
}
|
@@ -14065,7 +14105,7 @@ parse_arguments_append(pm_parser_t *parser, pm_arguments_t *arguments, pm_node_t
|
|
14065
14105
|
* Parse a list of arguments.
|
14066
14106
|
*/
|
14067
14107
|
static void
|
14068
|
-
parse_arguments(pm_parser_t *parser, pm_arguments_t *arguments, bool accepts_forwarding, pm_token_type_t terminator) {
|
14108
|
+
parse_arguments(pm_parser_t *parser, pm_arguments_t *arguments, bool accepts_forwarding, pm_token_type_t terminator, uint16_t depth) {
|
14069
14109
|
pm_binding_power_t binding_power = pm_binding_powers[parser->current.type].left;
|
14070
14110
|
|
14071
14111
|
// First we need to check if the next token is one that could be the start of
|
@@ -14084,9 +14124,6 @@ parse_arguments(pm_parser_t *parser, pm_arguments_t *arguments, bool accepts_for
|
|
14084
14124
|
bool parsed_forwarding_arguments = false;
|
14085
14125
|
|
14086
14126
|
while (!match1(parser, PM_TOKEN_EOF)) {
|
14087
|
-
if (parsed_block_argument) {
|
14088
|
-
pm_parser_err_current(parser, PM_ERR_ARGUMENT_AFTER_BLOCK);
|
14089
|
-
}
|
14090
14127
|
if (parsed_forwarding_arguments) {
|
14091
14128
|
pm_parser_err_current(parser, PM_ERR_ARGUMENT_AFTER_FORWARDING_ELLIPSES);
|
14092
14129
|
}
|
@@ -14104,7 +14141,7 @@ parse_arguments(pm_parser_t *parser, pm_arguments_t *arguments, bool accepts_for
|
|
14104
14141
|
argument = (pm_node_t *) hash;
|
14105
14142
|
|
14106
14143
|
pm_static_literals_t hash_keys = { 0 };
|
14107
|
-
bool contains_keyword_splat = parse_assocs(parser, &hash_keys, (pm_node_t *) hash);
|
14144
|
+
bool contains_keyword_splat = parse_assocs(parser, &hash_keys, (pm_node_t *) hash, (uint16_t) (depth + 1));
|
14108
14145
|
|
14109
14146
|
parse_arguments_append(parser, arguments, argument);
|
14110
14147
|
|
@@ -14123,7 +14160,7 @@ parse_arguments(pm_parser_t *parser, pm_arguments_t *arguments, bool accepts_for
|
|
14123
14160
|
pm_node_t *expression = NULL;
|
14124
14161
|
|
14125
14162
|
if (token_begins_expression_p(parser->current.type)) {
|
14126
|
-
expression = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_EXPECT_ARGUMENT);
|
14163
|
+
expression = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, false, PM_ERR_EXPECT_ARGUMENT, (uint16_t) (depth + 1));
|
14127
14164
|
} else {
|
14128
14165
|
pm_parser_scope_forwarding_block_check(parser, &operator);
|
14129
14166
|
}
|
@@ -14135,6 +14172,10 @@ parse_arguments(pm_parser_t *parser, pm_arguments_t *arguments, bool accepts_for
|
|
14135
14172
|
arguments->block = argument;
|
14136
14173
|
}
|
14137
14174
|
|
14175
|
+
if (match1(parser, PM_TOKEN_COMMA)) {
|
14176
|
+
pm_parser_err_current(parser, PM_ERR_ARGUMENT_AFTER_BLOCK);
|
14177
|
+
}
|
14178
|
+
|
14138
14179
|
parsed_block_argument = true;
|
14139
14180
|
break;
|
14140
14181
|
}
|
@@ -14146,7 +14187,7 @@ parse_arguments(pm_parser_t *parser, pm_arguments_t *arguments, bool accepts_for
|
|
14146
14187
|
pm_parser_scope_forwarding_positionals_check(parser, &operator);
|
14147
14188
|
argument = (pm_node_t *) pm_splat_node_create(parser, &operator, NULL);
|
14148
14189
|
} else {
|
14149
|
-
pm_node_t *expression = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT);
|
14190
|
+
pm_node_t *expression = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, false, PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT, (uint16_t) (depth + 1));
|
14150
14191
|
|
14151
14192
|
if (parsed_bare_hash) {
|
14152
14193
|
pm_parser_err(parser, operator.start, expression->location.end, PM_ERR_ARGUMENT_SPLAT_AFTER_ASSOC_SPLAT);
|
@@ -14163,10 +14204,20 @@ parse_arguments(pm_parser_t *parser, pm_arguments_t *arguments, bool accepts_for
|
|
14163
14204
|
parser_lex(parser);
|
14164
14205
|
|
14165
14206
|
if (token_begins_expression_p(parser->current.type)) {
|
14166
|
-
// If the token begins an expression then this ... was
|
14167
|
-
// argument forwarding but was instead a
|
14207
|
+
// If the token begins an expression then this ... was
|
14208
|
+
// not actually argument forwarding but was instead a
|
14209
|
+
// range.
|
14168
14210
|
pm_token_t operator = parser->previous;
|
14169
|
-
pm_node_t *right = parse_expression(parser, PM_BINDING_POWER_RANGE, false, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
|
14211
|
+
pm_node_t *right = parse_expression(parser, PM_BINDING_POWER_RANGE, false, false, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1));
|
14212
|
+
|
14213
|
+
// If we parse a range, we need to validate that we
|
14214
|
+
// didn't accidentally violate the nonassoc rules of the
|
14215
|
+
// ... operator.
|
14216
|
+
if (PM_NODE_TYPE_P(right, PM_RANGE_NODE)) {
|
14217
|
+
pm_range_node_t *range = (pm_range_node_t *) right;
|
14218
|
+
pm_parser_err(parser, range->operator_loc.start, range->operator_loc.end, PM_ERR_UNEXPECTED_RANGE_OPERATOR);
|
14219
|
+
}
|
14220
|
+
|
14170
14221
|
argument = (pm_node_t *) pm_range_node_create(parser, NULL, &operator, right);
|
14171
14222
|
} else {
|
14172
14223
|
pm_parser_scope_forwarding_all_check(parser, &parser->previous);
|
@@ -14176,6 +14227,7 @@ parse_arguments(pm_parser_t *parser, pm_arguments_t *arguments, bool accepts_for
|
|
14176
14227
|
|
14177
14228
|
argument = (pm_node_t *) pm_forwarding_arguments_node_create(parser, &parser->previous);
|
14178
14229
|
parse_arguments_append(parser, arguments, argument);
|
14230
|
+
pm_node_flag_set((pm_node_t *) arguments->arguments, PM_ARGUMENTS_NODE_FLAGS_CONTAINS_FORWARDING);
|
14179
14231
|
arguments->has_forwarding = true;
|
14180
14232
|
parsed_forwarding_arguments = true;
|
14181
14233
|
break;
|
@@ -14185,7 +14237,7 @@ parse_arguments(pm_parser_t *parser, pm_arguments_t *arguments, bool accepts_for
|
|
14185
14237
|
/* fallthrough */
|
14186
14238
|
default: {
|
14187
14239
|
if (argument == NULL) {
|
14188
|
-
argument = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, !parsed_first_argument, PM_ERR_EXPECT_ARGUMENT);
|
14240
|
+
argument = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, !parsed_first_argument, true, PM_ERR_EXPECT_ARGUMENT, (uint16_t) (depth + 1));
|
14189
14241
|
}
|
14190
14242
|
|
14191
14243
|
bool contains_keywords = false;
|
@@ -14211,7 +14263,7 @@ parse_arguments(pm_parser_t *parser, pm_arguments_t *arguments, bool accepts_for
|
|
14211
14263
|
pm_hash_key_static_literals_add(parser, &hash_keys, argument);
|
14212
14264
|
|
14213
14265
|
// Finish parsing the one we are part way through.
|
14214
|
-
pm_node_t *value = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_HASH_VALUE);
|
14266
|
+
pm_node_t *value = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, false, PM_ERR_HASH_VALUE, (uint16_t) (depth + 1));
|
14215
14267
|
argument = (pm_node_t *) pm_assoc_node_create(parser, argument, &operator, value);
|
14216
14268
|
|
14217
14269
|
pm_keyword_hash_node_elements_append(bare_hash, argument);
|
@@ -14222,14 +14274,11 @@ parse_arguments(pm_parser_t *parser, pm_arguments_t *arguments, bool accepts_for
|
|
14222
14274
|
token_begins_expression_p(parser->current.type) ||
|
14223
14275
|
match2(parser, PM_TOKEN_USTAR_STAR, PM_TOKEN_LABEL)
|
14224
14276
|
)) {
|
14225
|
-
contains_keyword_splat = parse_assocs(parser, &hash_keys, (pm_node_t *) bare_hash);
|
14277
|
+
contains_keyword_splat = parse_assocs(parser, &hash_keys, (pm_node_t *) bare_hash, (uint16_t) (depth + 1));
|
14226
14278
|
}
|
14227
14279
|
|
14228
14280
|
pm_static_literals_free(&hash_keys);
|
14229
14281
|
parsed_bare_hash = true;
|
14230
|
-
} else if (accept1(parser, PM_TOKEN_KEYWORD_IN)) {
|
14231
|
-
// TODO: Could we solve this with binding powers instead?
|
14232
|
-
pm_parser_err_current(parser, PM_ERR_ARGUMENT_IN);
|
14233
14282
|
}
|
14234
14283
|
|
14235
14284
|
parse_arguments_append(parser, arguments, argument);
|
@@ -14417,7 +14466,9 @@ parse_parameters(
|
|
14417
14466
|
pm_binding_power_t binding_power,
|
14418
14467
|
bool uses_parentheses,
|
14419
14468
|
bool allows_trailing_comma,
|
14420
|
-
bool allows_forwarding_parameters
|
14469
|
+
bool allows_forwarding_parameters,
|
14470
|
+
bool accepts_blocks_in_defaults,
|
14471
|
+
uint16_t depth
|
14421
14472
|
) {
|
14422
14473
|
pm_parameters_node_t *params = pm_parameters_node_create(parser);
|
14423
14474
|
bool looping = true;
|
@@ -14528,18 +14579,22 @@ parse_parameters(
|
|
14528
14579
|
bool repeated = pm_parser_parameter_name_check(parser, &name);
|
14529
14580
|
pm_parser_local_add_token(parser, &name, 1);
|
14530
14581
|
|
14531
|
-
if (
|
14532
|
-
pm_token_t operator = parser->
|
14582
|
+
if (match1(parser, PM_TOKEN_EQUAL)) {
|
14583
|
+
pm_token_t operator = parser->current;
|
14533
14584
|
context_push(parser, PM_CONTEXT_DEFAULT_PARAMS);
|
14585
|
+
parser_lex(parser);
|
14534
14586
|
|
14535
14587
|
pm_constant_id_t name_id = pm_parser_constant_id_token(parser, &name);
|
14536
14588
|
uint32_t reads = parser->version == PM_OPTIONS_VERSION_CRUBY_3_3 ? pm_locals_reads(&parser->current_scope->locals, name_id) : 0;
|
14537
14589
|
|
14538
|
-
|
14590
|
+
if (accepts_blocks_in_defaults) pm_accepts_block_stack_push(parser, true);
|
14591
|
+
pm_node_t *value = parse_value_expression(parser, binding_power, false, false, PM_ERR_PARAMETER_NO_DEFAULT, (uint16_t) (depth + 1));
|
14592
|
+
if (accepts_blocks_in_defaults) pm_accepts_block_stack_pop(parser);
|
14593
|
+
|
14539
14594
|
pm_optional_parameter_node_t *param = pm_optional_parameter_node_create(parser, &name, &operator, value);
|
14540
14595
|
|
14541
14596
|
if (repeated) {
|
14542
|
-
pm_node_flag_set_repeated_parameter((pm_node_t *)param);
|
14597
|
+
pm_node_flag_set_repeated_parameter((pm_node_t *) param);
|
14543
14598
|
}
|
14544
14599
|
pm_parameters_node_optionals_append(params, param);
|
14545
14600
|
|
@@ -14578,6 +14633,8 @@ parse_parameters(
|
|
14578
14633
|
case PM_TOKEN_LABEL: {
|
14579
14634
|
if (!uses_parentheses) parser->in_keyword_arg = true;
|
14580
14635
|
update_parameter_state(parser, &parser->current, &order);
|
14636
|
+
|
14637
|
+
context_push(parser, PM_CONTEXT_DEFAULT_PARAMS);
|
14581
14638
|
parser_lex(parser);
|
14582
14639
|
|
14583
14640
|
pm_token_t name = parser->previous;
|
@@ -14597,15 +14654,20 @@ parse_parameters(
|
|
14597
14654
|
case PM_TOKEN_COMMA:
|
14598
14655
|
case PM_TOKEN_PARENTHESIS_RIGHT:
|
14599
14656
|
case PM_TOKEN_PIPE: {
|
14657
|
+
context_pop(parser);
|
14658
|
+
|
14600
14659
|
pm_node_t *param = (pm_node_t *) pm_required_keyword_parameter_node_create(parser, &name);
|
14601
14660
|
if (repeated) {
|
14602
14661
|
pm_node_flag_set_repeated_parameter(param);
|
14603
14662
|
}
|
14663
|
+
|
14604
14664
|
pm_parameters_node_keywords_append(params, param);
|
14605
14665
|
break;
|
14606
14666
|
}
|
14607
14667
|
case PM_TOKEN_SEMICOLON:
|
14608
14668
|
case PM_TOKEN_NEWLINE: {
|
14669
|
+
context_pop(parser);
|
14670
|
+
|
14609
14671
|
if (uses_parentheses) {
|
14610
14672
|
looping = false;
|
14611
14673
|
break;
|
@@ -14615,6 +14677,7 @@ parse_parameters(
|
|
14615
14677
|
if (repeated) {
|
14616
14678
|
pm_node_flag_set_repeated_parameter(param);
|
14617
14679
|
}
|
14680
|
+
|
14618
14681
|
pm_parameters_node_keywords_append(params, param);
|
14619
14682
|
break;
|
14620
14683
|
}
|
@@ -14622,17 +14685,17 @@ parse_parameters(
|
|
14622
14685
|
pm_node_t *param;
|
14623
14686
|
|
14624
14687
|
if (token_begins_expression_p(parser->current.type)) {
|
14625
|
-
context_push(parser, PM_CONTEXT_DEFAULT_PARAMS);
|
14626
|
-
|
14627
14688
|
pm_constant_id_t name_id = pm_parser_constant_id_token(parser, &local);
|
14628
14689
|
uint32_t reads = parser->version == PM_OPTIONS_VERSION_CRUBY_3_3 ? pm_locals_reads(&parser->current_scope->locals, name_id) : 0;
|
14629
|
-
|
14690
|
+
|
14691
|
+
if (accepts_blocks_in_defaults) pm_accepts_block_stack_push(parser, true);
|
14692
|
+
pm_node_t *value = parse_value_expression(parser, binding_power, false, false, PM_ERR_PARAMETER_NO_DEFAULT_KW, (uint16_t) (depth + 1));
|
14693
|
+
if (accepts_blocks_in_defaults) pm_accepts_block_stack_pop(parser);
|
14630
14694
|
|
14631
14695
|
if (parser->version == PM_OPTIONS_VERSION_CRUBY_3_3 && (pm_locals_reads(&parser->current_scope->locals, name_id) != reads)) {
|
14632
14696
|
PM_PARSER_ERR_TOKEN_FORMAT_CONTENT(parser, local, PM_ERR_PARAMETER_CIRCULAR);
|
14633
14697
|
}
|
14634
14698
|
|
14635
|
-
context_pop(parser);
|
14636
14699
|
param = (pm_node_t *) pm_optional_keyword_parameter_node_create(parser, &name, value);
|
14637
14700
|
}
|
14638
14701
|
else {
|
@@ -14642,6 +14705,8 @@ parse_parameters(
|
|
14642
14705
|
if (repeated) {
|
14643
14706
|
pm_node_flag_set_repeated_parameter(param);
|
14644
14707
|
}
|
14708
|
+
|
14709
|
+
context_pop(parser);
|
14645
14710
|
pm_parameters_node_keywords_append(params, param);
|
14646
14711
|
|
14647
14712
|
// If parsing the value of the parameter resulted in error recovery,
|
@@ -14734,7 +14799,7 @@ parse_parameters(
|
|
14734
14799
|
}
|
14735
14800
|
default:
|
14736
14801
|
if (parser->previous.type == PM_TOKEN_COMMA) {
|
14737
|
-
if (allows_trailing_comma) {
|
14802
|
+
if (allows_trailing_comma && order >= PM_PARAMETERS_ORDER_NAMED) {
|
14738
14803
|
// If we get here, then we have a trailing comma in a
|
14739
14804
|
// block parameter list.
|
14740
14805
|
pm_node_t *param = (pm_node_t *) pm_implicit_rest_node_create(parser, &parser->previous);
|
@@ -14831,7 +14896,7 @@ token_column(const pm_parser_t *parser, size_t newline_index, const pm_token_t *
|
|
14831
14896
|
* function warns if the indentation of the two tokens does not match.
|
14832
14897
|
*/
|
14833
14898
|
static void
|
14834
|
-
parser_warn_indentation_mismatch(pm_parser_t *parser, size_t opening_newline_index, const pm_token_t *opening_token, bool if_after_else) {
|
14899
|
+
parser_warn_indentation_mismatch(pm_parser_t *parser, size_t opening_newline_index, const pm_token_t *opening_token, bool if_after_else, bool allow_indent) {
|
14835
14900
|
// If these warnings are disabled (unlikely), then we can just return.
|
14836
14901
|
if (!parser->warn_mismatched_indentation) return;
|
14837
14902
|
|
@@ -14853,6 +14918,10 @@ parser_warn_indentation_mismatch(pm_parser_t *parser, size_t opening_newline_ind
|
|
14853
14918
|
int64_t closing_column = token_column(parser, closing_newline_index, closing_token, true);
|
14854
14919
|
if ((closing_column == -1) || (opening_column == closing_column)) return;
|
14855
14920
|
|
14921
|
+
// If the closing column is greater than the opening column and we are
|
14922
|
+
// allowing indentation, then we do not warn.
|
14923
|
+
if (allow_indent && (closing_column > opening_column)) return;
|
14924
|
+
|
14856
14925
|
// Otherwise, add a warning.
|
14857
14926
|
PM_PARSER_WARN_FORMAT(
|
14858
14927
|
parser,
|
@@ -14882,11 +14951,11 @@ typedef enum {
|
|
14882
14951
|
* nodes pointing to each other from the top.
|
14883
14952
|
*/
|
14884
14953
|
static inline void
|
14885
|
-
parse_rescues(pm_parser_t *parser, size_t opening_newline_index, const pm_token_t *opening, pm_begin_node_t *parent_node, pm_rescues_type_t type) {
|
14954
|
+
parse_rescues(pm_parser_t *parser, size_t opening_newline_index, const pm_token_t *opening, pm_begin_node_t *parent_node, pm_rescues_type_t type, uint16_t depth) {
|
14886
14955
|
pm_rescue_node_t *current = NULL;
|
14887
14956
|
|
14888
14957
|
while (match1(parser, PM_TOKEN_KEYWORD_RESCUE)) {
|
14889
|
-
if (opening != NULL) parser_warn_indentation_mismatch(parser, opening_newline_index, opening, false);
|
14958
|
+
if (opening != NULL) parser_warn_indentation_mismatch(parser, opening_newline_index, opening, false, false);
|
14890
14959
|
parser_lex(parser);
|
14891
14960
|
|
14892
14961
|
pm_rescue_node_t *rescue = pm_rescue_node_create(parser, &parser->previous);
|
@@ -14899,7 +14968,7 @@ parse_rescues(pm_parser_t *parser, size_t opening_newline_index, const pm_token_
|
|
14899
14968
|
parser_lex(parser);
|
14900
14969
|
pm_rescue_node_operator_set(rescue, &parser->previous);
|
14901
14970
|
|
14902
|
-
pm_node_t *reference = parse_expression(parser, PM_BINDING_POWER_INDEX, false, PM_ERR_RESCUE_VARIABLE);
|
14971
|
+
pm_node_t *reference = parse_expression(parser, PM_BINDING_POWER_INDEX, false, false, PM_ERR_RESCUE_VARIABLE, (uint16_t) (depth + 1));
|
14903
14972
|
reference = parse_target(parser, reference, false, false);
|
14904
14973
|
|
14905
14974
|
pm_rescue_node_reference_set(rescue, reference);
|
@@ -14917,7 +14986,7 @@ parse_rescues(pm_parser_t *parser, size_t opening_newline_index, const pm_token_
|
|
14917
14986
|
// we'll attempt to parse it here and any others delimited by commas.
|
14918
14987
|
|
14919
14988
|
do {
|
14920
|
-
pm_node_t *expression = parse_starred_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_RESCUE_EXPRESSION);
|
14989
|
+
pm_node_t *expression = parse_starred_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_RESCUE_EXPRESSION, (uint16_t) (depth + 1));
|
14921
14990
|
pm_rescue_node_exceptions_append(rescue, expression);
|
14922
14991
|
|
14923
14992
|
// If we hit a newline, then this is the end of the rescue expression. We
|
@@ -14929,7 +14998,7 @@ parse_rescues(pm_parser_t *parser, size_t opening_newline_index, const pm_token_
|
|
14929
14998
|
if (accept1(parser, PM_TOKEN_EQUAL_GREATER)) {
|
14930
14999
|
pm_rescue_node_operator_set(rescue, &parser->previous);
|
14931
15000
|
|
14932
|
-
pm_node_t *reference = parse_expression(parser, PM_BINDING_POWER_INDEX, false, PM_ERR_RESCUE_VARIABLE);
|
15001
|
+
pm_node_t *reference = parse_expression(parser, PM_BINDING_POWER_INDEX, false, false, PM_ERR_RESCUE_VARIABLE, (uint16_t) (depth + 1));
|
14933
15002
|
reference = parse_target(parser, reference, false, false);
|
14934
15003
|
|
14935
15004
|
pm_rescue_node_reference_set(rescue, reference);
|
@@ -14961,7 +15030,7 @@ parse_rescues(pm_parser_t *parser, size_t opening_newline_index, const pm_token_
|
|
14961
15030
|
default: assert(false && "unreachable"); context = PM_CONTEXT_BEGIN_RESCUE; break;
|
14962
15031
|
}
|
14963
15032
|
|
14964
|
-
pm_statements_node_t *statements = parse_statements(parser, context);
|
15033
|
+
pm_statements_node_t *statements = parse_statements(parser, context, (uint16_t) (depth + 1));
|
14965
15034
|
if (statements != NULL) pm_rescue_node_statements_set(rescue, statements);
|
14966
15035
|
|
14967
15036
|
pm_accepts_block_stack_pop(parser);
|
@@ -14992,7 +15061,7 @@ parse_rescues(pm_parser_t *parser, size_t opening_newline_index, const pm_token_
|
|
14992
15061
|
|
14993
15062
|
pm_token_t else_keyword;
|
14994
15063
|
if (match1(parser, PM_TOKEN_KEYWORD_ELSE)) {
|
14995
|
-
if (opening != NULL) parser_warn_indentation_mismatch(parser, opening_newline_index, opening, false);
|
15064
|
+
if (opening != NULL) parser_warn_indentation_mismatch(parser, opening_newline_index, opening, false, false);
|
14996
15065
|
opening_newline_index = token_newline_index(parser);
|
14997
15066
|
|
14998
15067
|
else_keyword = parser->current;
|
@@ -15017,7 +15086,7 @@ parse_rescues(pm_parser_t *parser, size_t opening_newline_index, const pm_token_
|
|
15017
15086
|
default: assert(false && "unreachable"); context = PM_CONTEXT_BEGIN_RESCUE; break;
|
15018
15087
|
}
|
15019
15088
|
|
15020
|
-
else_statements = parse_statements(parser, context);
|
15089
|
+
else_statements = parse_statements(parser, context, (uint16_t) (depth + 1));
|
15021
15090
|
pm_accepts_block_stack_pop(parser);
|
15022
15091
|
|
15023
15092
|
accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON);
|
@@ -15032,7 +15101,7 @@ parse_rescues(pm_parser_t *parser, size_t opening_newline_index, const pm_token_
|
|
15032
15101
|
}
|
15033
15102
|
|
15034
15103
|
if (match1(parser, PM_TOKEN_KEYWORD_ENSURE)) {
|
15035
|
-
if (opening != NULL) parser_warn_indentation_mismatch(parser, opening_newline_index, opening, false);
|
15104
|
+
if (opening != NULL) parser_warn_indentation_mismatch(parser, opening_newline_index, opening, false, false);
|
15036
15105
|
pm_token_t ensure_keyword = parser->current;
|
15037
15106
|
|
15038
15107
|
parser_lex(parser);
|
@@ -15054,7 +15123,7 @@ parse_rescues(pm_parser_t *parser, size_t opening_newline_index, const pm_token_
|
|
15054
15123
|
default: assert(false && "unreachable"); context = PM_CONTEXT_BEGIN_RESCUE; break;
|
15055
15124
|
}
|
15056
15125
|
|
15057
|
-
ensure_statements = parse_statements(parser, context);
|
15126
|
+
ensure_statements = parse_statements(parser, context, (uint16_t) (depth + 1));
|
15058
15127
|
pm_accepts_block_stack_pop(parser);
|
15059
15128
|
|
15060
15129
|
accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON);
|
@@ -15065,7 +15134,7 @@ parse_rescues(pm_parser_t *parser, size_t opening_newline_index, const pm_token_
|
|
15065
15134
|
}
|
15066
15135
|
|
15067
15136
|
if (match1(parser, PM_TOKEN_KEYWORD_END)) {
|
15068
|
-
if (opening != NULL) parser_warn_indentation_mismatch(parser, opening_newline_index, opening, false);
|
15137
|
+
if (opening != NULL) parser_warn_indentation_mismatch(parser, opening_newline_index, opening, false, false);
|
15069
15138
|
pm_begin_node_end_keyword_set(parent_node, &parser->current);
|
15070
15139
|
} else {
|
15071
15140
|
pm_token_t end_keyword = (pm_token_t) { .type = PM_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end };
|
@@ -15078,11 +15147,11 @@ parse_rescues(pm_parser_t *parser, size_t opening_newline_index, const pm_token_
|
|
15078
15147
|
* class, module, def, etc.).
|
15079
15148
|
*/
|
15080
15149
|
static pm_begin_node_t *
|
15081
|
-
parse_rescues_implicit_begin(pm_parser_t *parser, size_t opening_newline_index, const pm_token_t *opening, const uint8_t *start, pm_statements_node_t *statements, pm_rescues_type_t type) {
|
15150
|
+
parse_rescues_implicit_begin(pm_parser_t *parser, size_t opening_newline_index, const pm_token_t *opening, const uint8_t *start, pm_statements_node_t *statements, pm_rescues_type_t type, uint16_t depth) {
|
15082
15151
|
pm_token_t begin_keyword = not_provided(parser);
|
15083
15152
|
pm_begin_node_t *node = pm_begin_node_create(parser, &begin_keyword, statements);
|
15084
15153
|
|
15085
|
-
parse_rescues(parser, opening_newline_index, opening, node, type);
|
15154
|
+
parse_rescues(parser, opening_newline_index, opening, node, type, (uint16_t) (depth + 1));
|
15086
15155
|
node->base.location.start = start;
|
15087
15156
|
|
15088
15157
|
return node;
|
@@ -15096,7 +15165,9 @@ parse_block_parameters(
|
|
15096
15165
|
pm_parser_t *parser,
|
15097
15166
|
bool allows_trailing_comma,
|
15098
15167
|
const pm_token_t *opening,
|
15099
|
-
bool is_lambda_literal
|
15168
|
+
bool is_lambda_literal,
|
15169
|
+
bool accepts_blocks_in_defaults,
|
15170
|
+
uint16_t depth
|
15100
15171
|
) {
|
15101
15172
|
pm_parameters_node_t *parameters = NULL;
|
15102
15173
|
if (!match1(parser, PM_TOKEN_SEMICOLON)) {
|
@@ -15105,7 +15176,9 @@ parse_block_parameters(
|
|
15105
15176
|
is_lambda_literal ? PM_BINDING_POWER_DEFINED : PM_BINDING_POWER_INDEX,
|
15106
15177
|
false,
|
15107
15178
|
allows_trailing_comma,
|
15108
|
-
false
|
15179
|
+
false,
|
15180
|
+
accepts_blocks_in_defaults,
|
15181
|
+
(uint16_t) (depth + 1)
|
15109
15182
|
);
|
15110
15183
|
}
|
15111
15184
|
|
@@ -15259,7 +15332,7 @@ parse_blocklike_parameters(pm_parser_t *parser, pm_node_t *parameters, const pm_
|
|
15259
15332
|
* Parse a block.
|
15260
15333
|
*/
|
15261
15334
|
static pm_block_node_t *
|
15262
|
-
parse_block(pm_parser_t *parser) {
|
15335
|
+
parse_block(pm_parser_t *parser, uint16_t depth) {
|
15263
15336
|
pm_token_t opening = parser->previous;
|
15264
15337
|
accept1(parser, PM_TOKEN_NEWLINE);
|
15265
15338
|
|
@@ -15275,7 +15348,7 @@ parse_block(pm_parser_t *parser) {
|
|
15275
15348
|
parser->command_start = true;
|
15276
15349
|
parser_lex(parser);
|
15277
15350
|
} else {
|
15278
|
-
block_parameters = parse_block_parameters(parser, true, &block_parameters_opening, false);
|
15351
|
+
block_parameters = parse_block_parameters(parser, true, &block_parameters_opening, false, true, (uint16_t) (depth + 1));
|
15279
15352
|
accept1(parser, PM_TOKEN_NEWLINE);
|
15280
15353
|
parser->command_start = true;
|
15281
15354
|
expect1(parser, PM_TOKEN_PIPE, PM_ERR_BLOCK_PARAM_PIPE_TERM);
|
@@ -15289,7 +15362,7 @@ parse_block(pm_parser_t *parser) {
|
|
15289
15362
|
|
15290
15363
|
if (opening.type == PM_TOKEN_BRACE_LEFT) {
|
15291
15364
|
if (!match1(parser, PM_TOKEN_BRACE_RIGHT)) {
|
15292
|
-
statements = (pm_node_t *) parse_statements(parser, PM_CONTEXT_BLOCK_BRACES);
|
15365
|
+
statements = (pm_node_t *) parse_statements(parser, PM_CONTEXT_BLOCK_BRACES, (uint16_t) (depth + 1));
|
15293
15366
|
}
|
15294
15367
|
|
15295
15368
|
expect1(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_BLOCK_TERM_BRACE);
|
@@ -15297,13 +15370,13 @@ parse_block(pm_parser_t *parser) {
|
|
15297
15370
|
if (!match1(parser, PM_TOKEN_KEYWORD_END)) {
|
15298
15371
|
if (!match3(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ELSE, PM_TOKEN_KEYWORD_ENSURE)) {
|
15299
15372
|
pm_accepts_block_stack_push(parser, true);
|
15300
|
-
statements = (pm_node_t *) parse_statements(parser, PM_CONTEXT_BLOCK_KEYWORDS);
|
15373
|
+
statements = (pm_node_t *) parse_statements(parser, PM_CONTEXT_BLOCK_KEYWORDS, (uint16_t) (depth + 1));
|
15301
15374
|
pm_accepts_block_stack_pop(parser);
|
15302
15375
|
}
|
15303
15376
|
|
15304
15377
|
if (match2(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) {
|
15305
15378
|
assert(statements == NULL || PM_NODE_TYPE_P(statements, PM_STATEMENTS_NODE));
|
15306
|
-
statements = (pm_node_t *) parse_rescues_implicit_begin(parser, 0, NULL, opening.start, (pm_statements_node_t *) statements, PM_RESCUES_BLOCK);
|
15379
|
+
statements = (pm_node_t *) parse_rescues_implicit_begin(parser, 0, NULL, opening.start, (pm_statements_node_t *) statements, PM_RESCUES_BLOCK, (uint16_t) (depth + 1));
|
15307
15380
|
}
|
15308
15381
|
}
|
15309
15382
|
|
@@ -15326,7 +15399,7 @@ parse_block(pm_parser_t *parser) {
|
|
15326
15399
|
* arguments, or blocks).
|
15327
15400
|
*/
|
15328
15401
|
static bool
|
15329
|
-
parse_arguments_list(pm_parser_t *parser, pm_arguments_t *arguments, bool accepts_block, bool accepts_command_call) {
|
15402
|
+
parse_arguments_list(pm_parser_t *parser, pm_arguments_t *arguments, bool accepts_block, bool accepts_command_call, uint16_t depth) {
|
15330
15403
|
bool found = false;
|
15331
15404
|
|
15332
15405
|
if (accept1(parser, PM_TOKEN_PARENTHESIS_LEFT)) {
|
@@ -15337,7 +15410,7 @@ parse_arguments_list(pm_parser_t *parser, pm_arguments_t *arguments, bool accept
|
|
15337
15410
|
arguments->closing_loc = PM_LOCATION_TOKEN_VALUE(&parser->previous);
|
15338
15411
|
} else {
|
15339
15412
|
pm_accepts_block_stack_push(parser, true);
|
15340
|
-
parse_arguments(parser, arguments, accepts_block, PM_TOKEN_PARENTHESIS_RIGHT);
|
15413
|
+
parse_arguments(parser, arguments, accepts_block, PM_TOKEN_PARENTHESIS_RIGHT, (uint16_t) (depth + 1));
|
15341
15414
|
|
15342
15415
|
if (!accept1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) {
|
15343
15416
|
PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_ARGUMENT_TERM_PAREN, pm_token_type_human(parser->current.type));
|
@@ -15355,13 +15428,13 @@ parse_arguments_list(pm_parser_t *parser, pm_arguments_t *arguments, bool accept
|
|
15355
15428
|
// If we get here, then the subsequent token cannot be used as an infix
|
15356
15429
|
// operator. In this case we assume the subsequent token is part of an
|
15357
15430
|
// argument to this method call.
|
15358
|
-
parse_arguments(parser, arguments, accepts_block, PM_TOKEN_EOF);
|
15431
|
+
parse_arguments(parser, arguments, accepts_block, PM_TOKEN_EOF, (uint16_t) (depth + 1));
|
15359
15432
|
|
15360
15433
|
// If we have done with the arguments and still not consumed the comma,
|
15361
15434
|
// then we have a trailing comma where we need to check whether it is
|
15362
15435
|
// allowed or not.
|
15363
15436
|
if (parser->previous.type == PM_TOKEN_COMMA && !match1(parser, PM_TOKEN_SEMICOLON)) {
|
15364
|
-
|
15437
|
+
PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->previous, PM_ERR_EXPECT_ARGUMENT, pm_token_type_human(parser->current.type));
|
15365
15438
|
}
|
15366
15439
|
|
15367
15440
|
pm_accepts_block_stack_pop(parser);
|
@@ -15375,11 +15448,11 @@ parse_arguments_list(pm_parser_t *parser, pm_arguments_t *arguments, bool accept
|
|
15375
15448
|
|
15376
15449
|
if (accept1(parser, PM_TOKEN_BRACE_LEFT)) {
|
15377
15450
|
found |= true;
|
15378
|
-
block = parse_block(parser);
|
15451
|
+
block = parse_block(parser, (uint16_t) (depth + 1));
|
15379
15452
|
pm_arguments_validate_block(parser, arguments, block);
|
15380
15453
|
} else if (pm_accepts_block_stack_p(parser) && accept1(parser, PM_TOKEN_KEYWORD_DO)) {
|
15381
15454
|
found |= true;
|
15382
|
-
block = parse_block(parser);
|
15455
|
+
block = parse_block(parser, (uint16_t) (depth + 1));
|
15383
15456
|
}
|
15384
15457
|
|
15385
15458
|
if (block != NULL) {
|
@@ -15418,7 +15491,6 @@ parse_return(pm_parser_t *parser, pm_node_t *node) {
|
|
15418
15491
|
case PM_CONTEXT_CASE_IN:
|
15419
15492
|
case PM_CONTEXT_CASE_WHEN:
|
15420
15493
|
case PM_CONTEXT_DEFAULT_PARAMS:
|
15421
|
-
case PM_CONTEXT_DEF_PARAMS:
|
15422
15494
|
case PM_CONTEXT_DEFINED:
|
15423
15495
|
case PM_CONTEXT_ELSE:
|
15424
15496
|
case PM_CONTEXT_ELSIF:
|
@@ -15464,6 +15536,7 @@ parse_return(pm_parser_t *parser, pm_node_t *node) {
|
|
15464
15536
|
case PM_CONTEXT_BLOCK_RESCUE:
|
15465
15537
|
case PM_CONTEXT_DEF_ELSE:
|
15466
15538
|
case PM_CONTEXT_DEF_ENSURE:
|
15539
|
+
case PM_CONTEXT_DEF_PARAMS:
|
15467
15540
|
case PM_CONTEXT_DEF_RESCUE:
|
15468
15541
|
case PM_CONTEXT_DEF:
|
15469
15542
|
case PM_CONTEXT_LAMBDA_BRACES:
|
@@ -15634,10 +15707,10 @@ pop_block_exits(pm_parser_t *parser, pm_node_list_t *previous_block_exits) {
|
|
15634
15707
|
}
|
15635
15708
|
|
15636
15709
|
static inline pm_node_t *
|
15637
|
-
parse_predicate(pm_parser_t *parser, pm_binding_power_t binding_power, pm_context_t context, pm_token_t *then_keyword) {
|
15710
|
+
parse_predicate(pm_parser_t *parser, pm_binding_power_t binding_power, pm_context_t context, pm_token_t *then_keyword, uint16_t depth) {
|
15638
15711
|
context_push(parser, PM_CONTEXT_PREDICATE);
|
15639
15712
|
pm_diagnostic_id_t error_id = context == PM_CONTEXT_IF ? PM_ERR_CONDITIONAL_IF_PREDICATE : PM_ERR_CONDITIONAL_UNLESS_PREDICATE;
|
15640
|
-
pm_node_t *predicate = parse_value_expression(parser, binding_power, true, error_id);
|
15713
|
+
pm_node_t *predicate = parse_value_expression(parser, binding_power, true, false, error_id, (uint16_t) (depth + 1));
|
15641
15714
|
|
15642
15715
|
// Predicates are closed by a term, a "then", or a term and then a "then".
|
15643
15716
|
bool predicate_closed = accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON);
|
@@ -15656,19 +15729,19 @@ parse_predicate(pm_parser_t *parser, pm_binding_power_t binding_power, pm_contex
|
|
15656
15729
|
}
|
15657
15730
|
|
15658
15731
|
static inline pm_node_t *
|
15659
|
-
parse_conditional(pm_parser_t *parser, pm_context_t context, size_t opening_newline_index, bool if_after_else) {
|
15732
|
+
parse_conditional(pm_parser_t *parser, pm_context_t context, size_t opening_newline_index, bool if_after_else, uint16_t depth) {
|
15660
15733
|
pm_node_list_t current_block_exits = { 0 };
|
15661
15734
|
pm_node_list_t *previous_block_exits = push_block_exits(parser, ¤t_block_exits);
|
15662
15735
|
|
15663
15736
|
pm_token_t keyword = parser->previous;
|
15664
15737
|
pm_token_t then_keyword = not_provided(parser);
|
15665
15738
|
|
15666
|
-
pm_node_t *predicate = parse_predicate(parser, PM_BINDING_POWER_MODIFIER, context, &then_keyword);
|
15739
|
+
pm_node_t *predicate = parse_predicate(parser, PM_BINDING_POWER_MODIFIER, context, &then_keyword, (uint16_t) (depth + 1));
|
15667
15740
|
pm_statements_node_t *statements = NULL;
|
15668
15741
|
|
15669
15742
|
if (!match3(parser, PM_TOKEN_KEYWORD_ELSIF, PM_TOKEN_KEYWORD_ELSE, PM_TOKEN_KEYWORD_END)) {
|
15670
15743
|
pm_accepts_block_stack_push(parser, true);
|
15671
|
-
statements = parse_statements(parser, context);
|
15744
|
+
statements = parse_statements(parser, context, (uint16_t) (depth + 1));
|
15672
15745
|
pm_accepts_block_stack_pop(parser);
|
15673
15746
|
accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON);
|
15674
15747
|
}
|
@@ -15698,14 +15771,14 @@ parse_conditional(pm_parser_t *parser, pm_context_t context, size_t opening_newl
|
|
15698
15771
|
PM_PARSER_WARN_TOKEN_FORMAT_CONTENT(parser, parser->current, PM_WARN_KEYWORD_EOL);
|
15699
15772
|
}
|
15700
15773
|
|
15701
|
-
parser_warn_indentation_mismatch(parser, opening_newline_index, &keyword, false);
|
15774
|
+
parser_warn_indentation_mismatch(parser, opening_newline_index, &keyword, false, false);
|
15702
15775
|
pm_token_t elsif_keyword = parser->current;
|
15703
15776
|
parser_lex(parser);
|
15704
15777
|
|
15705
|
-
pm_node_t *predicate = parse_predicate(parser, PM_BINDING_POWER_MODIFIER, PM_CONTEXT_ELSIF, &then_keyword);
|
15778
|
+
pm_node_t *predicate = parse_predicate(parser, PM_BINDING_POWER_MODIFIER, PM_CONTEXT_ELSIF, &then_keyword, (uint16_t) (depth + 1));
|
15706
15779
|
pm_accepts_block_stack_push(parser, true);
|
15707
15780
|
|
15708
|
-
pm_statements_node_t *statements = parse_statements(parser, PM_CONTEXT_ELSIF);
|
15781
|
+
pm_statements_node_t *statements = parse_statements(parser, PM_CONTEXT_ELSIF, (uint16_t) (depth + 1));
|
15709
15782
|
pm_accepts_block_stack_pop(parser);
|
15710
15783
|
accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON);
|
15711
15784
|
|
@@ -15716,18 +15789,18 @@ parse_conditional(pm_parser_t *parser, pm_context_t context, size_t opening_newl
|
|
15716
15789
|
}
|
15717
15790
|
|
15718
15791
|
if (match1(parser, PM_TOKEN_KEYWORD_ELSE)) {
|
15719
|
-
parser_warn_indentation_mismatch(parser, opening_newline_index, &keyword, false);
|
15792
|
+
parser_warn_indentation_mismatch(parser, opening_newline_index, &keyword, false, false);
|
15720
15793
|
opening_newline_index = token_newline_index(parser);
|
15721
15794
|
|
15722
15795
|
parser_lex(parser);
|
15723
15796
|
pm_token_t else_keyword = parser->previous;
|
15724
15797
|
|
15725
15798
|
pm_accepts_block_stack_push(parser, true);
|
15726
|
-
pm_statements_node_t *else_statements = parse_statements(parser, PM_CONTEXT_ELSE);
|
15799
|
+
pm_statements_node_t *else_statements = parse_statements(parser, PM_CONTEXT_ELSE, (uint16_t) (depth + 1));
|
15727
15800
|
pm_accepts_block_stack_pop(parser);
|
15728
15801
|
|
15729
15802
|
accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON);
|
15730
|
-
parser_warn_indentation_mismatch(parser, opening_newline_index, &else_keyword, false);
|
15803
|
+
parser_warn_indentation_mismatch(parser, opening_newline_index, &else_keyword, false, false);
|
15731
15804
|
expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CONDITIONAL_TERM_ELSE);
|
15732
15805
|
|
15733
15806
|
pm_else_node_t *else_node = pm_else_node_create(parser, &else_keyword, else_statements, &parser->previous);
|
@@ -15744,7 +15817,7 @@ parse_conditional(pm_parser_t *parser, pm_context_t context, size_t opening_newl
|
|
15744
15817
|
break;
|
15745
15818
|
}
|
15746
15819
|
} else {
|
15747
|
-
parser_warn_indentation_mismatch(parser, opening_newline_index, &keyword, if_after_else);
|
15820
|
+
parser_warn_indentation_mismatch(parser, opening_newline_index, &keyword, if_after_else, false);
|
15748
15821
|
expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CONDITIONAL_TERM);
|
15749
15822
|
}
|
15750
15823
|
|
@@ -15880,7 +15953,7 @@ parse_unescaped_encoding(const pm_parser_t *parser) {
|
|
15880
15953
|
* parsed as a string part, then NULL is returned.
|
15881
15954
|
*/
|
15882
15955
|
static pm_node_t *
|
15883
|
-
parse_string_part(pm_parser_t *parser) {
|
15956
|
+
parse_string_part(pm_parser_t *parser, uint16_t depth) {
|
15884
15957
|
switch (parser->current.type) {
|
15885
15958
|
// Here the lexer has returned to us plain string content. In this case
|
15886
15959
|
// we'll create a string node that has no opening or closing and return that
|
@@ -15921,7 +15994,7 @@ parse_string_part(pm_parser_t *parser) {
|
|
15921
15994
|
|
15922
15995
|
if (!match1(parser, PM_TOKEN_EMBEXPR_END)) {
|
15923
15996
|
pm_accepts_block_stack_push(parser, true);
|
15924
|
-
statements = parse_statements(parser, PM_CONTEXT_EMBEXPR);
|
15997
|
+
statements = parse_statements(parser, PM_CONTEXT_EMBEXPR, (uint16_t) (depth + 1));
|
15925
15998
|
pm_accepts_block_stack_pop(parser);
|
15926
15999
|
}
|
15927
16000
|
|
@@ -16046,7 +16119,7 @@ parse_operator_symbol(pm_parser_t *parser, const pm_token_t *opening, pm_lex_sta
|
|
16046
16119
|
* symbols.
|
16047
16120
|
*/
|
16048
16121
|
static pm_node_t *
|
16049
|
-
parse_symbol(pm_parser_t *parser, pm_lex_mode_t *lex_mode, pm_lex_state_t next_state) {
|
16122
|
+
parse_symbol(pm_parser_t *parser, pm_lex_mode_t *lex_mode, pm_lex_state_t next_state, uint16_t depth) {
|
16050
16123
|
const pm_token_t opening = parser->previous;
|
16051
16124
|
|
16052
16125
|
if (lex_mode->mode != PM_LEX_STRING) {
|
@@ -16092,7 +16165,7 @@ parse_symbol(pm_parser_t *parser, pm_lex_mode_t *lex_mode, pm_lex_state_t next_s
|
|
16092
16165
|
}
|
16093
16166
|
|
16094
16167
|
// Now we can parse the first part of the symbol.
|
16095
|
-
pm_node_t *part = parse_string_part(parser);
|
16168
|
+
pm_node_t *part = parse_string_part(parser, (uint16_t) (depth + 1));
|
16096
16169
|
|
16097
16170
|
// If we got a string part, then it's possible that we could transform
|
16098
16171
|
// what looks like an interpolated symbol into a regular symbol.
|
@@ -16107,7 +16180,7 @@ parse_symbol(pm_parser_t *parser, pm_lex_mode_t *lex_mode, pm_lex_state_t next_s
|
|
16107
16180
|
if (part) pm_interpolated_symbol_node_append(symbol, part);
|
16108
16181
|
|
16109
16182
|
while (!match2(parser, PM_TOKEN_STRING_END, PM_TOKEN_EOF)) {
|
16110
|
-
if ((part = parse_string_part(parser)) != NULL) {
|
16183
|
+
if ((part = parse_string_part(parser, (uint16_t) (depth + 1))) != NULL) {
|
16111
16184
|
pm_interpolated_symbol_node_append(symbol, part);
|
16112
16185
|
}
|
16113
16186
|
}
|
@@ -16183,7 +16256,7 @@ parse_symbol(pm_parser_t *parser, pm_lex_mode_t *lex_mode, pm_lex_state_t next_s
|
|
16183
16256
|
* constant, or an interpolated symbol.
|
16184
16257
|
*/
|
16185
16258
|
static inline pm_node_t *
|
16186
|
-
parse_undef_argument(pm_parser_t *parser) {
|
16259
|
+
parse_undef_argument(pm_parser_t *parser, uint16_t depth) {
|
16187
16260
|
switch (parser->current.type) {
|
16188
16261
|
case PM_CASE_OPERATOR: {
|
16189
16262
|
const pm_token_t opening = not_provided(parser);
|
@@ -16208,7 +16281,7 @@ parse_undef_argument(pm_parser_t *parser) {
|
|
16208
16281
|
pm_lex_mode_t lex_mode = *parser->lex_modes.current;
|
16209
16282
|
parser_lex(parser);
|
16210
16283
|
|
16211
|
-
return parse_symbol(parser, &lex_mode, PM_LEX_STATE_NONE);
|
16284
|
+
return parse_symbol(parser, &lex_mode, PM_LEX_STATE_NONE, (uint16_t) (depth + 1));
|
16212
16285
|
}
|
16213
16286
|
default:
|
16214
16287
|
pm_parser_err_current(parser, PM_ERR_UNDEF_ARGUMENT);
|
@@ -16223,7 +16296,7 @@ parse_undef_argument(pm_parser_t *parser) {
|
|
16223
16296
|
* between the first and second arguments.
|
16224
16297
|
*/
|
16225
16298
|
static inline pm_node_t *
|
16226
|
-
parse_alias_argument(pm_parser_t *parser, bool first) {
|
16299
|
+
parse_alias_argument(pm_parser_t *parser, bool first, uint16_t depth) {
|
16227
16300
|
switch (parser->current.type) {
|
16228
16301
|
case PM_CASE_OPERATOR: {
|
16229
16302
|
const pm_token_t opening = not_provided(parser);
|
@@ -16249,7 +16322,7 @@ parse_alias_argument(pm_parser_t *parser, bool first) {
|
|
16249
16322
|
pm_lex_mode_t lex_mode = *parser->lex_modes.current;
|
16250
16323
|
parser_lex(parser);
|
16251
16324
|
|
16252
|
-
return parse_symbol(parser, &lex_mode, first ? PM_LEX_STATE_FNAME | PM_LEX_STATE_FITEM : PM_LEX_STATE_NONE);
|
16325
|
+
return parse_symbol(parser, &lex_mode, first ? PM_LEX_STATE_FNAME | PM_LEX_STATE_FITEM : PM_LEX_STATE_NONE, (uint16_t) (depth + 1));
|
16253
16326
|
}
|
16254
16327
|
case PM_TOKEN_BACK_REFERENCE:
|
16255
16328
|
parser_lex(parser);
|
@@ -16449,11 +16522,9 @@ parse_strings_empty_content(const uint8_t *location) {
|
|
16449
16522
|
* Parse a set of strings that could be concatenated together.
|
16450
16523
|
*/
|
16451
16524
|
static inline pm_node_t *
|
16452
|
-
parse_strings(pm_parser_t *parser, pm_node_t *current) {
|
16525
|
+
parse_strings(pm_parser_t *parser, pm_node_t *current, bool accepts_label, uint16_t depth) {
|
16453
16526
|
assert(parser->current.type == PM_TOKEN_STRING_BEGIN);
|
16454
|
-
|
16455
16527
|
bool concating = false;
|
16456
|
-
bool state_is_arg_labeled = lex_state_arg_labeled_p(parser);
|
16457
16528
|
|
16458
16529
|
while (match1(parser, PM_TOKEN_STRING_BEGIN)) {
|
16459
16530
|
pm_node_t *node = NULL;
|
@@ -16463,6 +16534,7 @@ parse_strings(pm_parser_t *parser, pm_node_t *current) {
|
|
16463
16534
|
const pm_lex_mode_t *lex_mode = parser->lex_modes.current;
|
16464
16535
|
assert(lex_mode->mode == PM_LEX_STRING);
|
16465
16536
|
bool lex_interpolation = lex_mode->as.string.interpolation;
|
16537
|
+
bool label_allowed = lex_mode->as.string.label_allowed && accepts_label;
|
16466
16538
|
|
16467
16539
|
pm_token_t opening = parser->current;
|
16468
16540
|
parser_lex(parser);
|
@@ -16486,6 +16558,8 @@ parse_strings(pm_parser_t *parser, pm_node_t *current) {
|
|
16486
16558
|
|
16487
16559
|
pm_string_shared_init(&symbol->unescaped, content.start, content.end);
|
16488
16560
|
node = (pm_node_t *) symbol;
|
16561
|
+
|
16562
|
+
if (!label_allowed) pm_parser_err_node(parser, node, PM_ERR_UNEXPECTED_LABEL);
|
16489
16563
|
} else if (!lex_interpolation) {
|
16490
16564
|
// If we don't accept interpolation then we expect the string to
|
16491
16565
|
// start with a single string content node.
|
@@ -16529,8 +16603,9 @@ parse_strings(pm_parser_t *parser, pm_node_t *current) {
|
|
16529
16603
|
node = (pm_node_t *) pm_interpolated_string_node_create(parser, &opening, &parts, &parser->previous);
|
16530
16604
|
|
16531
16605
|
pm_node_list_free(&parts);
|
16532
|
-
} else if (accept1(parser, PM_TOKEN_LABEL_END)
|
16606
|
+
} else if (accept1(parser, PM_TOKEN_LABEL_END)) {
|
16533
16607
|
node = (pm_node_t *) pm_symbol_node_create_unescaped(parser, &opening, &content, &parser->previous, &unescaped, parse_symbol_encoding(parser, &content, &unescaped, true));
|
16608
|
+
if (!label_allowed) pm_parser_err_node(parser, node, PM_ERR_UNEXPECTED_LABEL);
|
16534
16609
|
} else if (match1(parser, PM_TOKEN_EOF)) {
|
16535
16610
|
pm_parser_err_token(parser, &opening, PM_ERR_STRING_LITERAL_EOF);
|
16536
16611
|
node = (pm_node_t *) pm_string_node_create_unescaped(parser, &opening, &content, &parser->current, &unescaped);
|
@@ -16569,6 +16644,7 @@ parse_strings(pm_parser_t *parser, pm_node_t *current) {
|
|
16569
16644
|
}
|
16570
16645
|
} else if (accept1(parser, PM_TOKEN_LABEL_END)) {
|
16571
16646
|
node = (pm_node_t *) pm_symbol_node_create_unescaped(parser, &opening, &content, &parser->previous, &unescaped, parse_symbol_encoding(parser, &content, &unescaped, true));
|
16647
|
+
if (!label_allowed) pm_parser_err_node(parser, node, PM_ERR_UNEXPECTED_LABEL);
|
16572
16648
|
} else {
|
16573
16649
|
// If we get here, then we have interpolation so we'll need
|
16574
16650
|
// to create a string or symbol node with interpolation.
|
@@ -16581,13 +16657,14 @@ parse_strings(pm_parser_t *parser, pm_node_t *current) {
|
|
16581
16657
|
pm_node_list_append(&parts, part);
|
16582
16658
|
|
16583
16659
|
while (!match3(parser, PM_TOKEN_STRING_END, PM_TOKEN_LABEL_END, PM_TOKEN_EOF)) {
|
16584
|
-
if ((part = parse_string_part(parser)) != NULL) {
|
16660
|
+
if ((part = parse_string_part(parser, (uint16_t) (depth + 1))) != NULL) {
|
16585
16661
|
pm_node_list_append(&parts, part);
|
16586
16662
|
}
|
16587
16663
|
}
|
16588
16664
|
|
16589
|
-
if (accept1(parser, PM_TOKEN_LABEL_END)
|
16665
|
+
if (accept1(parser, PM_TOKEN_LABEL_END)) {
|
16590
16666
|
node = (pm_node_t *) pm_interpolated_symbol_node_create(parser, &opening, &parts, &parser->previous);
|
16667
|
+
if (!label_allowed) pm_parser_err_node(parser, node, PM_ERR_UNEXPECTED_LABEL);
|
16591
16668
|
} else if (match1(parser, PM_TOKEN_EOF)) {
|
16592
16669
|
pm_parser_err_token(parser, &opening, PM_ERR_STRING_INTERPOLATED_TERM);
|
16593
16670
|
node = (pm_node_t *) pm_interpolated_string_node_create(parser, &opening, &parts, &parser->current);
|
@@ -16606,13 +16683,14 @@ parse_strings(pm_parser_t *parser, pm_node_t *current) {
|
|
16606
16683
|
pm_node_t *part;
|
16607
16684
|
|
16608
16685
|
while (!match3(parser, PM_TOKEN_STRING_END, PM_TOKEN_LABEL_END, PM_TOKEN_EOF)) {
|
16609
|
-
if ((part = parse_string_part(parser)) != NULL) {
|
16686
|
+
if ((part = parse_string_part(parser, (uint16_t) (depth + 1))) != NULL) {
|
16610
16687
|
pm_node_list_append(&parts, part);
|
16611
16688
|
}
|
16612
16689
|
}
|
16613
16690
|
|
16614
16691
|
if (accept1(parser, PM_TOKEN_LABEL_END)) {
|
16615
16692
|
node = (pm_node_t *) pm_interpolated_symbol_node_create(parser, &opening, &parts, &parser->previous);
|
16693
|
+
if (!label_allowed) pm_parser_err_node(parser, node, PM_ERR_UNEXPECTED_LABEL);
|
16616
16694
|
} else if (match1(parser, PM_TOKEN_EOF)) {
|
16617
16695
|
pm_parser_err_token(parser, &opening, PM_ERR_STRING_INTERPOLATED_TERM);
|
16618
16696
|
node = (pm_node_t *) pm_interpolated_string_node_create(parser, &opening, &parts, &parser->current);
|
@@ -16666,7 +16744,7 @@ parse_strings(pm_parser_t *parser, pm_node_t *current) {
|
|
16666
16744
|
#define PM_PARSE_PATTERN_MULTI 2
|
16667
16745
|
|
16668
16746
|
static pm_node_t *
|
16669
|
-
parse_pattern(pm_parser_t *parser, pm_constant_id_list_t *captures, uint8_t flags, pm_diagnostic_id_t diag_id);
|
16747
|
+
parse_pattern(pm_parser_t *parser, pm_constant_id_list_t *captures, uint8_t flags, pm_diagnostic_id_t diag_id, uint16_t depth);
|
16670
16748
|
|
16671
16749
|
/**
|
16672
16750
|
* Add the newly created local to the list of captures for this pattern matching
|
@@ -16689,7 +16767,7 @@ parse_pattern_capture(pm_parser_t *parser, pm_constant_id_list_t *captures, pm_c
|
|
16689
16767
|
* Accept any number of constants joined by :: delimiters.
|
16690
16768
|
*/
|
16691
16769
|
static pm_node_t *
|
16692
|
-
parse_pattern_constant_path(pm_parser_t *parser, pm_constant_id_list_t *captures, pm_node_t *node) {
|
16770
|
+
parse_pattern_constant_path(pm_parser_t *parser, pm_constant_id_list_t *captures, pm_node_t *node, uint16_t depth) {
|
16693
16771
|
// Now, if there are any :: operators that follow, parse them as constant
|
16694
16772
|
// path nodes.
|
16695
16773
|
while (accept1(parser, PM_TOKEN_COLON_COLON)) {
|
@@ -16714,7 +16792,7 @@ parse_pattern_constant_path(pm_parser_t *parser, pm_constant_id_list_t *captures
|
|
16714
16792
|
accept1(parser, PM_TOKEN_NEWLINE);
|
16715
16793
|
|
16716
16794
|
if (!accept1(parser, PM_TOKEN_BRACKET_RIGHT)) {
|
16717
|
-
inner = parse_pattern(parser, captures, PM_PARSE_PATTERN_TOP | PM_PARSE_PATTERN_MULTI, PM_ERR_PATTERN_EXPRESSION_AFTER_BRACKET);
|
16795
|
+
inner = parse_pattern(parser, captures, PM_PARSE_PATTERN_TOP | PM_PARSE_PATTERN_MULTI, PM_ERR_PATTERN_EXPRESSION_AFTER_BRACKET, (uint16_t) (depth + 1));
|
16718
16796
|
accept1(parser, PM_TOKEN_NEWLINE);
|
16719
16797
|
expect1(parser, PM_TOKEN_BRACKET_RIGHT, PM_ERR_PATTERN_TERM_BRACKET);
|
16720
16798
|
}
|
@@ -16726,7 +16804,7 @@ parse_pattern_constant_path(pm_parser_t *parser, pm_constant_id_list_t *captures
|
|
16726
16804
|
accept1(parser, PM_TOKEN_NEWLINE);
|
16727
16805
|
|
16728
16806
|
if (!accept1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) {
|
16729
|
-
inner = parse_pattern(parser, captures, PM_PARSE_PATTERN_TOP | PM_PARSE_PATTERN_MULTI, PM_ERR_PATTERN_EXPRESSION_AFTER_PAREN);
|
16807
|
+
inner = parse_pattern(parser, captures, PM_PARSE_PATTERN_TOP | PM_PARSE_PATTERN_MULTI, PM_ERR_PATTERN_EXPRESSION_AFTER_PAREN, (uint16_t) (depth + 1));
|
16730
16808
|
accept1(parser, PM_TOKEN_NEWLINE);
|
16731
16809
|
expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_PATTERN_TERM_PAREN);
|
16732
16810
|
}
|
@@ -16952,7 +17030,7 @@ parse_pattern_hash_key(pm_parser_t *parser, pm_static_literals_t *keys, pm_node_
|
|
16952
17030
|
* Parse a hash pattern.
|
16953
17031
|
*/
|
16954
17032
|
static pm_hash_pattern_node_t *
|
16955
|
-
parse_pattern_hash(pm_parser_t *parser, pm_constant_id_list_t *captures, pm_node_t *first_node) {
|
17033
|
+
parse_pattern_hash(pm_parser_t *parser, pm_constant_id_list_t *captures, pm_node_t *first_node, uint16_t depth) {
|
16956
17034
|
pm_node_list_t assocs = { 0 };
|
16957
17035
|
pm_static_literals_t keys = { 0 };
|
16958
17036
|
pm_node_t *rest = NULL;
|
@@ -16974,7 +17052,7 @@ parse_pattern_hash(pm_parser_t *parser, pm_constant_id_list_t *captures, pm_node
|
|
16974
17052
|
} else {
|
16975
17053
|
// Here we have a value for the first assoc in the list, so
|
16976
17054
|
// we will parse it now.
|
16977
|
-
value = parse_pattern(parser, captures, PM_PARSE_PATTERN_SINGLE, PM_ERR_PATTERN_EXPRESSION_AFTER_KEY);
|
17055
|
+
value = parse_pattern(parser, captures, PM_PARSE_PATTERN_SINGLE, PM_ERR_PATTERN_EXPRESSION_AFTER_KEY, (uint16_t) (depth + 1));
|
16978
17056
|
}
|
16979
17057
|
|
16980
17058
|
pm_token_t operator = not_provided(parser);
|
@@ -17021,7 +17099,7 @@ parse_pattern_hash(pm_parser_t *parser, pm_constant_id_list_t *captures, pm_node
|
|
17021
17099
|
pm_node_t *key;
|
17022
17100
|
|
17023
17101
|
if (match1(parser, PM_TOKEN_STRING_BEGIN)) {
|
17024
|
-
key = parse_strings(parser, NULL);
|
17102
|
+
key = parse_strings(parser, NULL, true, (uint16_t) (depth + 1));
|
17025
17103
|
|
17026
17104
|
if (PM_NODE_TYPE_P(key, PM_INTERPOLATED_SYMBOL_NODE)) {
|
17027
17105
|
pm_parser_err_node(parser, key, PM_ERR_PATTERN_HASH_KEY_INTERPOLATED);
|
@@ -17039,7 +17117,7 @@ parse_pattern_hash(pm_parser_t *parser, pm_constant_id_list_t *captures, pm_node
|
|
17039
17117
|
if (match7(parser, PM_TOKEN_COMMA, PM_TOKEN_KEYWORD_THEN, PM_TOKEN_BRACE_RIGHT, PM_TOKEN_BRACKET_RIGHT, PM_TOKEN_PARENTHESIS_RIGHT, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON)) {
|
17040
17118
|
value = parse_pattern_hash_implicit_value(parser, captures, (pm_symbol_node_t *) key);
|
17041
17119
|
} else {
|
17042
|
-
value = parse_pattern(parser, captures, PM_PARSE_PATTERN_SINGLE, PM_ERR_PATTERN_EXPRESSION_AFTER_KEY);
|
17120
|
+
value = parse_pattern(parser, captures, PM_PARSE_PATTERN_SINGLE, PM_ERR_PATTERN_EXPRESSION_AFTER_KEY, (uint16_t) (depth + 1));
|
17043
17121
|
}
|
17044
17122
|
|
17045
17123
|
pm_token_t operator = not_provided(parser);
|
@@ -17064,7 +17142,7 @@ parse_pattern_hash(pm_parser_t *parser, pm_constant_id_list_t *captures, pm_node
|
|
17064
17142
|
* Parse a pattern expression primitive.
|
17065
17143
|
*/
|
17066
17144
|
static pm_node_t *
|
17067
|
-
parse_pattern_primitive(pm_parser_t *parser, pm_constant_id_list_t *captures, pm_diagnostic_id_t diag_id) {
|
17145
|
+
parse_pattern_primitive(pm_parser_t *parser, pm_constant_id_list_t *captures, pm_diagnostic_id_t diag_id, uint16_t depth) {
|
17068
17146
|
switch (parser->current.type) {
|
17069
17147
|
case PM_TOKEN_IDENTIFIER:
|
17070
17148
|
case PM_TOKEN_METHOD_NAME: {
|
@@ -17096,7 +17174,7 @@ parse_pattern_primitive(pm_parser_t *parser, pm_constant_id_list_t *captures, pm
|
|
17096
17174
|
|
17097
17175
|
// Otherwise, we'll parse the inner pattern, then deal with it depending
|
17098
17176
|
// on the type it returns.
|
17099
|
-
pm_node_t *inner = parse_pattern(parser, captures, PM_PARSE_PATTERN_MULTI, PM_ERR_PATTERN_EXPRESSION_AFTER_BRACKET);
|
17177
|
+
pm_node_t *inner = parse_pattern(parser, captures, PM_PARSE_PATTERN_MULTI, PM_ERR_PATTERN_EXPRESSION_AFTER_BRACKET, (uint16_t) (depth + 1));
|
17100
17178
|
|
17101
17179
|
accept1(parser, PM_TOKEN_NEWLINE);
|
17102
17180
|
expect1(parser, PM_TOKEN_BRACKET_RIGHT, PM_ERR_PATTERN_TERM_BRACKET);
|
@@ -17163,7 +17241,7 @@ parse_pattern_primitive(pm_parser_t *parser, pm_constant_id_list_t *captures, pm
|
|
17163
17241
|
first_node = parse_pattern_keyword_rest(parser, captures);
|
17164
17242
|
break;
|
17165
17243
|
case PM_TOKEN_STRING_BEGIN:
|
17166
|
-
first_node = parse_expression(parser, PM_BINDING_POWER_MAX, false, PM_ERR_PATTERN_HASH_KEY_LABEL);
|
17244
|
+
first_node = parse_expression(parser, PM_BINDING_POWER_MAX, false, true, PM_ERR_PATTERN_HASH_KEY_LABEL, (uint16_t) (depth + 1));
|
17167
17245
|
break;
|
17168
17246
|
default: {
|
17169
17247
|
PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_PATTERN_HASH_KEY, pm_token_type_human(parser->current.type));
|
@@ -17174,7 +17252,7 @@ parse_pattern_primitive(pm_parser_t *parser, pm_constant_id_list_t *captures, pm
|
|
17174
17252
|
}
|
17175
17253
|
}
|
17176
17254
|
|
17177
|
-
node = parse_pattern_hash(parser, captures, first_node);
|
17255
|
+
node = parse_pattern_hash(parser, captures, first_node, (uint16_t) (depth + 1));
|
17178
17256
|
|
17179
17257
|
accept1(parser, PM_TOKEN_NEWLINE);
|
17180
17258
|
expect1(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_PATTERN_TERM_BRACE);
|
@@ -17199,7 +17277,7 @@ parse_pattern_primitive(pm_parser_t *parser, pm_constant_id_list_t *captures, pm
|
|
17199
17277
|
// expression as the right side of the range.
|
17200
17278
|
switch (parser->current.type) {
|
17201
17279
|
case PM_CASE_PRIMITIVE: {
|
17202
|
-
pm_node_t *right = parse_expression(parser, PM_BINDING_POWER_MAX, false, PM_ERR_PATTERN_EXPRESSION_AFTER_RANGE);
|
17280
|
+
pm_node_t *right = parse_expression(parser, PM_BINDING_POWER_MAX, false, false, PM_ERR_PATTERN_EXPRESSION_AFTER_RANGE, (uint16_t) (depth + 1));
|
17203
17281
|
return (pm_node_t *) pm_range_node_create(parser, NULL, &operator, right);
|
17204
17282
|
}
|
17205
17283
|
default: {
|
@@ -17210,7 +17288,10 @@ parse_pattern_primitive(pm_parser_t *parser, pm_constant_id_list_t *captures, pm
|
|
17210
17288
|
}
|
17211
17289
|
}
|
17212
17290
|
case PM_CASE_PRIMITIVE: {
|
17213
|
-
pm_node_t *node = parse_expression(parser, PM_BINDING_POWER_MAX, false, diag_id);
|
17291
|
+
pm_node_t *node = parse_expression(parser, PM_BINDING_POWER_MAX, false, true, diag_id, (uint16_t) (depth + 1));
|
17292
|
+
|
17293
|
+
// If we found a label, we need to immediately return to the caller.
|
17294
|
+
if (pm_symbol_node_label_p(node)) return node;
|
17214
17295
|
|
17215
17296
|
// Now that we have a primitive, we need to check if it's part of a range.
|
17216
17297
|
if (accept2(parser, PM_TOKEN_DOT_DOT, PM_TOKEN_DOT_DOT_DOT)) {
|
@@ -17221,7 +17302,7 @@ parse_pattern_primitive(pm_parser_t *parser, pm_constant_id_list_t *captures, pm
|
|
17221
17302
|
// node. Otherwise, we'll create an endless range.
|
17222
17303
|
switch (parser->current.type) {
|
17223
17304
|
case PM_CASE_PRIMITIVE: {
|
17224
|
-
pm_node_t *right = parse_expression(parser, PM_BINDING_POWER_MAX, false, PM_ERR_PATTERN_EXPRESSION_AFTER_RANGE);
|
17305
|
+
pm_node_t *right = parse_expression(parser, PM_BINDING_POWER_MAX, false, false, PM_ERR_PATTERN_EXPRESSION_AFTER_RANGE, (uint16_t) (depth + 1));
|
17225
17306
|
return (pm_node_t *) pm_range_node_create(parser, node, &operator, right);
|
17226
17307
|
}
|
17227
17308
|
default:
|
@@ -17286,7 +17367,7 @@ parse_pattern_primitive(pm_parser_t *parser, pm_constant_id_list_t *captures, pm
|
|
17286
17367
|
pm_token_t lparen = parser->current;
|
17287
17368
|
parser_lex(parser);
|
17288
17369
|
|
17289
|
-
pm_node_t *expression = parse_value_expression(parser, PM_BINDING_POWER_STATEMENT, true, PM_ERR_PATTERN_EXPRESSION_AFTER_PIN);
|
17370
|
+
pm_node_t *expression = parse_value_expression(parser, PM_BINDING_POWER_STATEMENT, true, false, PM_ERR_PATTERN_EXPRESSION_AFTER_PIN, (uint16_t) (depth + 1));
|
17290
17371
|
parser->pattern_matching_newlines = previous_pattern_matching_newlines;
|
17291
17372
|
|
17292
17373
|
accept1(parser, PM_TOKEN_NEWLINE);
|
@@ -17309,14 +17390,14 @@ parse_pattern_primitive(pm_parser_t *parser, pm_constant_id_list_t *captures, pm
|
|
17309
17390
|
expect1(parser, PM_TOKEN_CONSTANT, PM_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT);
|
17310
17391
|
pm_constant_path_node_t *node = pm_constant_path_node_create(parser, NULL, &delimiter, &parser->previous);
|
17311
17392
|
|
17312
|
-
return parse_pattern_constant_path(parser, captures, (pm_node_t *) node);
|
17393
|
+
return parse_pattern_constant_path(parser, captures, (pm_node_t *) node, (uint16_t) (depth + 1));
|
17313
17394
|
}
|
17314
17395
|
case PM_TOKEN_CONSTANT: {
|
17315
17396
|
pm_token_t constant = parser->current;
|
17316
17397
|
parser_lex(parser);
|
17317
17398
|
|
17318
17399
|
pm_node_t *node = (pm_node_t *) pm_constant_read_node_create(parser, &constant);
|
17319
|
-
return parse_pattern_constant_path(parser, captures, node);
|
17400
|
+
return parse_pattern_constant_path(parser, captures, node, (uint16_t) (depth + 1));
|
17320
17401
|
}
|
17321
17402
|
default:
|
17322
17403
|
pm_parser_err_current(parser, diag_id);
|
@@ -17329,10 +17410,10 @@ parse_pattern_primitive(pm_parser_t *parser, pm_constant_id_list_t *captures, pm
|
|
17329
17410
|
* assignment.
|
17330
17411
|
*/
|
17331
17412
|
static pm_node_t *
|
17332
|
-
parse_pattern_primitives(pm_parser_t *parser, pm_constant_id_list_t *captures, pm_diagnostic_id_t diag_id) {
|
17333
|
-
pm_node_t *node =
|
17413
|
+
parse_pattern_primitives(pm_parser_t *parser, pm_constant_id_list_t *captures, pm_node_t *first_node, pm_diagnostic_id_t diag_id, uint16_t depth) {
|
17414
|
+
pm_node_t *node = first_node;
|
17334
17415
|
|
17335
|
-
|
17416
|
+
while ((node == NULL) || accept1(parser, PM_TOKEN_PIPE)) {
|
17336
17417
|
pm_token_t operator = parser->previous;
|
17337
17418
|
|
17338
17419
|
switch (parser->current.type) {
|
@@ -17346,9 +17427,9 @@ parse_pattern_primitives(pm_parser_t *parser, pm_constant_id_list_t *captures, p
|
|
17346
17427
|
case PM_TOKEN_UDOT_DOT_DOT:
|
17347
17428
|
case PM_CASE_PRIMITIVE: {
|
17348
17429
|
if (node == NULL) {
|
17349
|
-
node = parse_pattern_primitive(parser, captures, diag_id);
|
17430
|
+
node = parse_pattern_primitive(parser, captures, diag_id, (uint16_t) (depth + 1));
|
17350
17431
|
} else {
|
17351
|
-
pm_node_t *right = parse_pattern_primitive(parser, captures, PM_ERR_PATTERN_EXPRESSION_AFTER_PIPE);
|
17432
|
+
pm_node_t *right = parse_pattern_primitive(parser, captures, PM_ERR_PATTERN_EXPRESSION_AFTER_PIPE, (uint16_t) (depth + 1));
|
17352
17433
|
node = (pm_node_t *) pm_alternation_pattern_node_create(parser, node, right, &operator);
|
17353
17434
|
}
|
17354
17435
|
|
@@ -17359,7 +17440,7 @@ parse_pattern_primitives(pm_parser_t *parser, pm_constant_id_list_t *captures, p
|
|
17359
17440
|
pm_token_t opening = parser->current;
|
17360
17441
|
parser_lex(parser);
|
17361
17442
|
|
17362
|
-
pm_node_t *body = parse_pattern(parser, captures, PM_PARSE_PATTERN_SINGLE, PM_ERR_PATTERN_EXPRESSION_AFTER_PAREN);
|
17443
|
+
pm_node_t *body = parse_pattern(parser, captures, PM_PARSE_PATTERN_SINGLE, PM_ERR_PATTERN_EXPRESSION_AFTER_PAREN, (uint16_t) (depth + 1));
|
17363
17444
|
accept1(parser, PM_TOKEN_NEWLINE);
|
17364
17445
|
expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_PATTERN_TERM_PAREN);
|
17365
17446
|
pm_node_t *right = (pm_node_t *) pm_parentheses_node_create(parser, &opening, body, &parser->previous);
|
@@ -17385,7 +17466,7 @@ parse_pattern_primitives(pm_parser_t *parser, pm_constant_id_list_t *captures, p
|
|
17385
17466
|
break;
|
17386
17467
|
}
|
17387
17468
|
}
|
17388
|
-
}
|
17469
|
+
}
|
17389
17470
|
|
17390
17471
|
// If we have an =>, then we are assigning this pattern to a variable.
|
17391
17472
|
// In this case we should create an assignment node.
|
@@ -17401,7 +17482,7 @@ parse_pattern_primitives(pm_parser_t *parser, pm_constant_id_list_t *captures, p
|
|
17401
17482
|
}
|
17402
17483
|
|
17403
17484
|
parse_pattern_capture(parser, captures, constant_id, &PM_LOCATION_TOKEN_VALUE(&parser->previous));
|
17404
|
-
|
17485
|
+
pm_local_variable_target_node_t *target = pm_local_variable_target_node_create(
|
17405
17486
|
parser,
|
17406
17487
|
&PM_LOCATION_TOKEN_VALUE(&parser->previous),
|
17407
17488
|
constant_id,
|
@@ -17418,7 +17499,7 @@ parse_pattern_primitives(pm_parser_t *parser, pm_constant_id_list_t *captures, p
|
|
17418
17499
|
* Parse a pattern matching expression.
|
17419
17500
|
*/
|
17420
17501
|
static pm_node_t *
|
17421
|
-
parse_pattern(pm_parser_t *parser, pm_constant_id_list_t *captures, uint8_t flags, pm_diagnostic_id_t diag_id) {
|
17502
|
+
parse_pattern(pm_parser_t *parser, pm_constant_id_list_t *captures, uint8_t flags, pm_diagnostic_id_t diag_id, uint16_t depth) {
|
17422
17503
|
pm_node_t *node = NULL;
|
17423
17504
|
|
17424
17505
|
bool leading_rest = false;
|
@@ -17428,7 +17509,7 @@ parse_pattern(pm_parser_t *parser, pm_constant_id_list_t *captures, uint8_t flag
|
|
17428
17509
|
case PM_TOKEN_LABEL: {
|
17429
17510
|
parser_lex(parser);
|
17430
17511
|
pm_node_t *key = (pm_node_t *) pm_symbol_node_label_create(parser, &parser->previous);
|
17431
|
-
node = (pm_node_t *) parse_pattern_hash(parser, captures, key);
|
17512
|
+
node = (pm_node_t *) parse_pattern_hash(parser, captures, key, (uint16_t) (depth + 1));
|
17432
17513
|
|
17433
17514
|
if (!(flags & PM_PARSE_PATTERN_TOP)) {
|
17434
17515
|
pm_parser_err_node(parser, node, PM_ERR_PATTERN_HASH_IMPLICIT);
|
@@ -17438,7 +17519,7 @@ parse_pattern(pm_parser_t *parser, pm_constant_id_list_t *captures, uint8_t flag
|
|
17438
17519
|
}
|
17439
17520
|
case PM_TOKEN_USTAR_STAR: {
|
17440
17521
|
node = parse_pattern_keyword_rest(parser, captures);
|
17441
|
-
node = (pm_node_t *) parse_pattern_hash(parser, captures, node);
|
17522
|
+
node = (pm_node_t *) parse_pattern_hash(parser, captures, node, (uint16_t) (depth + 1));
|
17442
17523
|
|
17443
17524
|
if (!(flags & PM_PARSE_PATTERN_TOP)) {
|
17444
17525
|
pm_parser_err_node(parser, node, PM_ERR_PATTERN_HASH_IMPLICIT);
|
@@ -17446,6 +17527,24 @@ parse_pattern(pm_parser_t *parser, pm_constant_id_list_t *captures, uint8_t flag
|
|
17446
17527
|
|
17447
17528
|
return node;
|
17448
17529
|
}
|
17530
|
+
case PM_TOKEN_STRING_BEGIN: {
|
17531
|
+
// We need special handling for string beginnings because they could
|
17532
|
+
// be dynamic symbols leading to hash patterns.
|
17533
|
+
node = parse_pattern_primitive(parser, captures, diag_id, (uint16_t) (depth + 1));
|
17534
|
+
|
17535
|
+
if (pm_symbol_node_label_p(node)) {
|
17536
|
+
node = (pm_node_t *) parse_pattern_hash(parser, captures, node, (uint16_t) (depth + 1));
|
17537
|
+
|
17538
|
+
if (!(flags & PM_PARSE_PATTERN_TOP)) {
|
17539
|
+
pm_parser_err_node(parser, node, PM_ERR_PATTERN_HASH_IMPLICIT);
|
17540
|
+
}
|
17541
|
+
|
17542
|
+
return node;
|
17543
|
+
}
|
17544
|
+
|
17545
|
+
node = parse_pattern_primitives(parser, captures, node, diag_id, (uint16_t) (depth + 1));
|
17546
|
+
break;
|
17547
|
+
}
|
17449
17548
|
case PM_TOKEN_USTAR: {
|
17450
17549
|
if (flags & (PM_PARSE_PATTERN_TOP | PM_PARSE_PATTERN_MULTI)) {
|
17451
17550
|
parser_lex(parser);
|
@@ -17456,14 +17555,14 @@ parse_pattern(pm_parser_t *parser, pm_constant_id_list_t *captures, uint8_t flag
|
|
17456
17555
|
}
|
17457
17556
|
/* fallthrough */
|
17458
17557
|
default:
|
17459
|
-
node = parse_pattern_primitives(parser, captures, diag_id);
|
17558
|
+
node = parse_pattern_primitives(parser, captures, NULL, diag_id, (uint16_t) (depth + 1));
|
17460
17559
|
break;
|
17461
17560
|
}
|
17462
17561
|
|
17463
17562
|
// If we got a dynamic label symbol, then we need to treat it like the
|
17464
17563
|
// beginning of a hash pattern.
|
17465
17564
|
if (pm_symbol_node_label_p(node)) {
|
17466
|
-
return (pm_node_t *) parse_pattern_hash(parser, captures, node);
|
17565
|
+
return (pm_node_t *) parse_pattern_hash(parser, captures, node, (uint16_t) (depth + 1));
|
17467
17566
|
}
|
17468
17567
|
|
17469
17568
|
if ((flags & PM_PARSE_PATTERN_MULTI) && match1(parser, PM_TOKEN_COMMA)) {
|
@@ -17476,7 +17575,7 @@ parse_pattern(pm_parser_t *parser, pm_constant_id_list_t *captures, uint8_t flag
|
|
17476
17575
|
// Gather up all of the patterns into the list.
|
17477
17576
|
while (accept1(parser, PM_TOKEN_COMMA)) {
|
17478
17577
|
// Break early here in case we have a trailing comma.
|
17479
|
-
if (
|
17578
|
+
if (match4(parser, PM_TOKEN_KEYWORD_THEN, PM_TOKEN_BRACE_RIGHT, PM_TOKEN_BRACKET_RIGHT, PM_TOKEN_SEMICOLON)) {
|
17480
17579
|
node = (pm_node_t *) pm_implicit_rest_node_create(parser, &parser->previous);
|
17481
17580
|
pm_node_list_append(&nodes, node);
|
17482
17581
|
break;
|
@@ -17494,7 +17593,7 @@ parse_pattern(pm_parser_t *parser, pm_constant_id_list_t *captures, uint8_t flag
|
|
17494
17593
|
|
17495
17594
|
trailing_rest = true;
|
17496
17595
|
} else {
|
17497
|
-
node = parse_pattern_primitives(parser, captures, PM_ERR_PATTERN_EXPRESSION_AFTER_COMMA);
|
17596
|
+
node = parse_pattern_primitives(parser, captures, NULL, PM_ERR_PATTERN_EXPRESSION_AFTER_COMMA, (uint16_t) (depth + 1));
|
17498
17597
|
}
|
17499
17598
|
|
17500
17599
|
pm_node_list_append(&nodes, node);
|
@@ -17586,7 +17685,8 @@ pm_parser_err_prefix(pm_parser_t *parser, pm_diagnostic_id_t diag_id) {
|
|
17586
17685
|
PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->previous, diag_id, human, parser->previous.start[0]);
|
17587
17686
|
break;
|
17588
17687
|
}
|
17589
|
-
case PM_ERR_UNARY_DISALLOWED:
|
17688
|
+
case PM_ERR_UNARY_DISALLOWED:
|
17689
|
+
case PM_ERR_EXPECT_ARGUMENT: {
|
17590
17690
|
PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, diag_id, pm_token_type_human(parser->current.type));
|
17591
17691
|
break;
|
17592
17692
|
}
|
@@ -17601,7 +17701,12 @@ pm_parser_err_prefix(pm_parser_t *parser, pm_diagnostic_id_t diag_id) {
|
|
17601
17701
|
*/
|
17602
17702
|
static void
|
17603
17703
|
parse_retry(pm_parser_t *parser, const pm_node_t *node) {
|
17704
|
+
#define CONTEXT_NONE 0
|
17705
|
+
#define CONTEXT_THROUGH_ENSURE 1
|
17706
|
+
#define CONTEXT_THROUGH_ELSE 2
|
17707
|
+
|
17604
17708
|
pm_context_node_t *context_node = parser->current_context;
|
17709
|
+
int context = CONTEXT_NONE;
|
17605
17710
|
|
17606
17711
|
while (context_node != NULL) {
|
17607
17712
|
switch (context_node->context) {
|
@@ -17625,7 +17730,13 @@ parse_retry(pm_parser_t *parser, const pm_node_t *node) {
|
|
17625
17730
|
case PM_CONTEXT_SCLASS:
|
17626
17731
|
// These are the bad cases. We're not allowed to have a retry in
|
17627
17732
|
// these contexts.
|
17628
|
-
|
17733
|
+
if (context == CONTEXT_NONE) {
|
17734
|
+
pm_parser_err_node(parser, node, PM_ERR_INVALID_RETRY_WITHOUT_RESCUE);
|
17735
|
+
} else if (context == CONTEXT_THROUGH_ENSURE) {
|
17736
|
+
pm_parser_err_node(parser, node, PM_ERR_INVALID_RETRY_AFTER_ENSURE);
|
17737
|
+
} else if (context == CONTEXT_THROUGH_ELSE) {
|
17738
|
+
pm_parser_err_node(parser, node, PM_ERR_INVALID_RETRY_AFTER_ELSE);
|
17739
|
+
}
|
17629
17740
|
return;
|
17630
17741
|
case PM_CONTEXT_BEGIN_ELSE:
|
17631
17742
|
case PM_CONTEXT_BLOCK_ELSE:
|
@@ -17636,8 +17747,8 @@ parse_retry(pm_parser_t *parser, const pm_node_t *node) {
|
|
17636
17747
|
case PM_CONTEXT_SCLASS_ELSE:
|
17637
17748
|
// These are also bad cases, but with a more specific error
|
17638
17749
|
// message indicating the else.
|
17639
|
-
|
17640
|
-
|
17750
|
+
context = CONTEXT_THROUGH_ELSE;
|
17751
|
+
break;
|
17641
17752
|
case PM_CONTEXT_BEGIN_ENSURE:
|
17642
17753
|
case PM_CONTEXT_BLOCK_ENSURE:
|
17643
17754
|
case PM_CONTEXT_CLASS_ENSURE:
|
@@ -17647,8 +17758,8 @@ parse_retry(pm_parser_t *parser, const pm_node_t *node) {
|
|
17647
17758
|
case PM_CONTEXT_SCLASS_ENSURE:
|
17648
17759
|
// These are also bad cases, but with a more specific error
|
17649
17760
|
// message indicating the ensure.
|
17650
|
-
|
17651
|
-
|
17761
|
+
context = CONTEXT_THROUGH_ENSURE;
|
17762
|
+
break;
|
17652
17763
|
case PM_CONTEXT_NONE:
|
17653
17764
|
// This case should never happen.
|
17654
17765
|
assert(false && "unreachable");
|
@@ -17682,6 +17793,10 @@ parse_retry(pm_parser_t *parser, const pm_node_t *node) {
|
|
17682
17793
|
|
17683
17794
|
context_node = context_node->prev;
|
17684
17795
|
}
|
17796
|
+
|
17797
|
+
#undef CONTEXT_NONE
|
17798
|
+
#undef CONTEXT_ENSURE
|
17799
|
+
#undef CONTEXT_ELSE
|
17685
17800
|
}
|
17686
17801
|
|
17687
17802
|
/**
|
@@ -17826,7 +17941,7 @@ parse_regular_expression_errors(pm_parser_t *parser, pm_regular_expression_node_
|
|
17826
17941
|
* Parse an expression that begins with the previous node that we just lexed.
|
17827
17942
|
*/
|
17828
17943
|
static inline pm_node_t *
|
17829
|
-
parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, bool accepts_command_call, pm_diagnostic_id_t diag_id) {
|
17944
|
+
parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, bool accepts_command_call, bool accepts_label, pm_diagnostic_id_t diag_id, uint16_t depth) {
|
17830
17945
|
switch (parser->current.type) {
|
17831
17946
|
case PM_TOKEN_BRACKET_LEFT_ARRAY: {
|
17832
17947
|
parser_lex(parser);
|
@@ -17865,7 +17980,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
17865
17980
|
if (match3(parser, PM_TOKEN_BRACKET_RIGHT, PM_TOKEN_COMMA, PM_TOKEN_EOF)) {
|
17866
17981
|
pm_parser_scope_forwarding_positionals_check(parser, &operator);
|
17867
17982
|
} else {
|
17868
|
-
expression = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_ARRAY_EXPRESSION_AFTER_STAR);
|
17983
|
+
expression = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, false, PM_ERR_ARRAY_EXPRESSION_AFTER_STAR, (uint16_t) (depth + 1));
|
17869
17984
|
}
|
17870
17985
|
|
17871
17986
|
element = (pm_node_t *) pm_splat_node_create(parser, &operator, expression);
|
@@ -17878,13 +17993,13 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
17878
17993
|
pm_static_literals_t hash_keys = { 0 };
|
17879
17994
|
|
17880
17995
|
if (!match8(parser, PM_TOKEN_EOF, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON, PM_TOKEN_EOF, PM_TOKEN_BRACE_RIGHT, PM_TOKEN_BRACKET_RIGHT, PM_TOKEN_KEYWORD_DO, PM_TOKEN_PARENTHESIS_RIGHT)) {
|
17881
|
-
parse_assocs(parser, &hash_keys, element);
|
17996
|
+
parse_assocs(parser, &hash_keys, element, (uint16_t) (depth + 1));
|
17882
17997
|
}
|
17883
17998
|
|
17884
17999
|
pm_static_literals_free(&hash_keys);
|
17885
18000
|
parsed_bare_hash = true;
|
17886
18001
|
} else {
|
17887
|
-
element = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_ARRAY_EXPRESSION);
|
18002
|
+
element = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, true, PM_ERR_ARRAY_EXPRESSION, (uint16_t) (depth + 1));
|
17888
18003
|
|
17889
18004
|
if (pm_symbol_node_label_p(element) || accept1(parser, PM_TOKEN_EQUAL_GREATER)) {
|
17890
18005
|
if (parsed_bare_hash) {
|
@@ -17902,13 +18017,13 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
17902
18017
|
operator = not_provided(parser);
|
17903
18018
|
}
|
17904
18019
|
|
17905
|
-
pm_node_t *value = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_HASH_VALUE);
|
18020
|
+
pm_node_t *value = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, false, PM_ERR_HASH_VALUE, (uint16_t) (depth + 1));
|
17906
18021
|
pm_node_t *assoc = (pm_node_t *) pm_assoc_node_create(parser, element, &operator, value);
|
17907
18022
|
pm_keyword_hash_node_elements_append(hash, assoc);
|
17908
18023
|
|
17909
18024
|
element = (pm_node_t *) hash;
|
17910
18025
|
if (accept1(parser, PM_TOKEN_COMMA) && !match1(parser, PM_TOKEN_BRACKET_RIGHT)) {
|
17911
|
-
parse_assocs(parser, &hash_keys, element);
|
18026
|
+
parse_assocs(parser, &hash_keys, element, (uint16_t) (depth + 1));
|
17912
18027
|
}
|
17913
18028
|
|
17914
18029
|
pm_static_literals_free(&hash_keys);
|
@@ -17921,7 +18036,13 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
17921
18036
|
}
|
17922
18037
|
|
17923
18038
|
accept1(parser, PM_TOKEN_NEWLINE);
|
17924
|
-
|
18039
|
+
|
18040
|
+
if (!accept1(parser, PM_TOKEN_BRACKET_RIGHT)) {
|
18041
|
+
PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_ARRAY_TERM, pm_token_type_human(parser->current.type));
|
18042
|
+
parser->previous.start = parser->previous.end;
|
18043
|
+
parser->previous.type = PM_TOKEN_MISSING;
|
18044
|
+
}
|
18045
|
+
|
17925
18046
|
pm_array_node_close_set(array, &parser->previous);
|
17926
18047
|
pm_accepts_block_stack_pop(parser);
|
17927
18048
|
|
@@ -17952,7 +18073,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
17952
18073
|
// of statements within the parentheses.
|
17953
18074
|
pm_accepts_block_stack_push(parser, true);
|
17954
18075
|
context_push(parser, PM_CONTEXT_PARENS);
|
17955
|
-
pm_node_t *statement = parse_expression(parser, PM_BINDING_POWER_STATEMENT, true, PM_ERR_CANNOT_PARSE_EXPRESSION);
|
18076
|
+
pm_node_t *statement = parse_expression(parser, PM_BINDING_POWER_STATEMENT, true, false, PM_ERR_CANNOT_PARSE_EXPRESSION, (uint16_t) (depth + 1));
|
17956
18077
|
context_pop(parser);
|
17957
18078
|
|
17958
18079
|
// Determine if this statement is followed by a terminator. In the
|
@@ -18000,7 +18121,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18000
18121
|
|
18001
18122
|
if (match1(parser, PM_TOKEN_COMMA)) {
|
18002
18123
|
if (binding_power == PM_BINDING_POWER_STATEMENT) {
|
18003
|
-
return parse_targets_validate(parser, (pm_node_t *) multi_target, PM_BINDING_POWER_INDEX);
|
18124
|
+
return parse_targets_validate(parser, (pm_node_t *) multi_target, PM_BINDING_POWER_INDEX, (uint16_t) (depth + 1));
|
18004
18125
|
}
|
18005
18126
|
return (pm_node_t *) multi_target;
|
18006
18127
|
}
|
@@ -18032,7 +18153,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18032
18153
|
|
18033
18154
|
// Parse each statement within the parentheses.
|
18034
18155
|
while (true) {
|
18035
|
-
pm_node_t *node = parse_expression(parser, PM_BINDING_POWER_STATEMENT, true, PM_ERR_CANNOT_PARSE_EXPRESSION);
|
18156
|
+
pm_node_t *node = parse_expression(parser, PM_BINDING_POWER_STATEMENT, true, false, PM_ERR_CANNOT_PARSE_EXPRESSION, (uint16_t) (depth + 1));
|
18036
18157
|
pm_statements_node_body_append(parser, statements, node, true);
|
18037
18158
|
|
18038
18159
|
// If we're recovering from a syntax error, then we need to stop
|
@@ -18090,10 +18211,10 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18090
18211
|
|
18091
18212
|
if (!match2(parser, PM_TOKEN_BRACE_RIGHT, PM_TOKEN_EOF)) {
|
18092
18213
|
if (current_hash_keys != NULL) {
|
18093
|
-
parse_assocs(parser, current_hash_keys, (pm_node_t *) node);
|
18214
|
+
parse_assocs(parser, current_hash_keys, (pm_node_t *) node, (uint16_t) (depth + 1));
|
18094
18215
|
} else {
|
18095
18216
|
pm_static_literals_t hash_keys = { 0 };
|
18096
|
-
parse_assocs(parser, &hash_keys, (pm_node_t *) node);
|
18217
|
+
parse_assocs(parser, &hash_keys, (pm_node_t *) node, (uint16_t) (depth + 1));
|
18097
18218
|
pm_static_literals_free(&hash_keys);
|
18098
18219
|
}
|
18099
18220
|
|
@@ -18124,7 +18245,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18124
18245
|
// Characters can be followed by strings in which case they are
|
18125
18246
|
// automatically concatenated.
|
18126
18247
|
if (match1(parser, PM_TOKEN_STRING_BEGIN)) {
|
18127
|
-
return parse_strings(parser, node);
|
18248
|
+
return parse_strings(parser, node, false, (uint16_t) (depth + 1));
|
18128
18249
|
}
|
18129
18250
|
|
18130
18251
|
return node;
|
@@ -18134,7 +18255,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18134
18255
|
pm_node_t *node = (pm_node_t *) pm_class_variable_read_node_create(parser, &parser->previous);
|
18135
18256
|
|
18136
18257
|
if (binding_power == PM_BINDING_POWER_STATEMENT && match1(parser, PM_TOKEN_COMMA)) {
|
18137
|
-
node = parse_targets_validate(parser, node, PM_BINDING_POWER_INDEX);
|
18258
|
+
node = parse_targets_validate(parser, node, PM_BINDING_POWER_INDEX, (uint16_t) (depth + 1));
|
18138
18259
|
}
|
18139
18260
|
|
18140
18261
|
return node;
|
@@ -18152,7 +18273,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18152
18273
|
match1(parser, PM_TOKEN_BRACE_LEFT)
|
18153
18274
|
) {
|
18154
18275
|
pm_arguments_t arguments = { 0 };
|
18155
|
-
parse_arguments_list(parser, &arguments, true, accepts_command_call);
|
18276
|
+
parse_arguments_list(parser, &arguments, true, accepts_command_call, (uint16_t) (depth + 1));
|
18156
18277
|
return (pm_node_t *) pm_call_node_fcall_create(parser, &constant, &arguments);
|
18157
18278
|
}
|
18158
18279
|
|
@@ -18161,7 +18282,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18161
18282
|
if ((binding_power == PM_BINDING_POWER_STATEMENT) && match1(parser, PM_TOKEN_COMMA)) {
|
18162
18283
|
// If we get here, then we have a comma immediately following a
|
18163
18284
|
// constant, so we're going to parse this as a multiple assignment.
|
18164
|
-
node = parse_targets_validate(parser, node, PM_BINDING_POWER_INDEX);
|
18285
|
+
node = parse_targets_validate(parser, node, PM_BINDING_POWER_INDEX, (uint16_t) (depth + 1));
|
18165
18286
|
}
|
18166
18287
|
|
18167
18288
|
return node;
|
@@ -18174,7 +18295,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18174
18295
|
pm_node_t *node = (pm_node_t *) pm_constant_path_node_create(parser, NULL, &delimiter, &parser->previous);
|
18175
18296
|
|
18176
18297
|
if ((binding_power == PM_BINDING_POWER_STATEMENT) && match1(parser, PM_TOKEN_COMMA)) {
|
18177
|
-
node = parse_targets_validate(parser, node, PM_BINDING_POWER_INDEX);
|
18298
|
+
node = parse_targets_validate(parser, node, PM_BINDING_POWER_INDEX, (uint16_t) (depth + 1));
|
18178
18299
|
}
|
18179
18300
|
|
18180
18301
|
return node;
|
@@ -18184,7 +18305,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18184
18305
|
pm_token_t operator = parser->current;
|
18185
18306
|
parser_lex(parser);
|
18186
18307
|
|
18187
|
-
pm_node_t *right = parse_expression(parser, pm_binding_powers[operator.type].left, false, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
|
18308
|
+
pm_node_t *right = parse_expression(parser, pm_binding_powers[operator.type].left, false, false, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1));
|
18188
18309
|
|
18189
18310
|
// Unary .. and ... are special because these are non-associative
|
18190
18311
|
// operators that can also be unary operators. In this case we need
|
@@ -18213,7 +18334,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18213
18334
|
pm_node_t *node = (pm_node_t *) pm_numbered_reference_read_node_create(parser, &parser->previous);
|
18214
18335
|
|
18215
18336
|
if (binding_power == PM_BINDING_POWER_STATEMENT && match1(parser, PM_TOKEN_COMMA)) {
|
18216
|
-
node = parse_targets_validate(parser, node, PM_BINDING_POWER_INDEX);
|
18337
|
+
node = parse_targets_validate(parser, node, PM_BINDING_POWER_INDEX, (uint16_t) (depth + 1));
|
18217
18338
|
}
|
18218
18339
|
|
18219
18340
|
return node;
|
@@ -18223,7 +18344,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18223
18344
|
pm_node_t *node = (pm_node_t *) pm_global_variable_read_node_create(parser, &parser->previous);
|
18224
18345
|
|
18225
18346
|
if (binding_power == PM_BINDING_POWER_STATEMENT && match1(parser, PM_TOKEN_COMMA)) {
|
18226
|
-
node = parse_targets_validate(parser, node, PM_BINDING_POWER_INDEX);
|
18347
|
+
node = parse_targets_validate(parser, node, PM_BINDING_POWER_INDEX, (uint16_t) (depth + 1));
|
18227
18348
|
}
|
18228
18349
|
|
18229
18350
|
return node;
|
@@ -18233,7 +18354,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18233
18354
|
pm_node_t *node = (pm_node_t *) pm_back_reference_read_node_create(parser, &parser->previous);
|
18234
18355
|
|
18235
18356
|
if (binding_power == PM_BINDING_POWER_STATEMENT && match1(parser, PM_TOKEN_COMMA)) {
|
18236
|
-
node = parse_targets_validate(parser, node, PM_BINDING_POWER_INDEX);
|
18357
|
+
node = parse_targets_validate(parser, node, PM_BINDING_POWER_INDEX, (uint16_t) (depth + 1));
|
18237
18358
|
}
|
18238
18359
|
|
18239
18360
|
return node;
|
@@ -18252,7 +18373,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18252
18373
|
pm_call_node_t *call = (pm_call_node_t *) node;
|
18253
18374
|
pm_arguments_t arguments = { 0 };
|
18254
18375
|
|
18255
|
-
if (parse_arguments_list(parser, &arguments, true, accepts_command_call)) {
|
18376
|
+
if (parse_arguments_list(parser, &arguments, true, accepts_command_call, (uint16_t) (depth + 1))) {
|
18256
18377
|
// Since we found arguments, we need to turn off the
|
18257
18378
|
// variable call bit in the flags.
|
18258
18379
|
pm_node_flag_unset((pm_node_t *)call, PM_CALL_NODE_FLAGS_VARIABLE_CALL);
|
@@ -18284,7 +18405,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18284
18405
|
match1(parser, PM_TOKEN_BRACE_LEFT)
|
18285
18406
|
) {
|
18286
18407
|
pm_arguments_t arguments = { 0 };
|
18287
|
-
parse_arguments_list(parser, &arguments, true, accepts_command_call);
|
18408
|
+
parse_arguments_list(parser, &arguments, true, accepts_command_call, (uint16_t) (depth + 1));
|
18288
18409
|
pm_call_node_t *fcall = pm_call_node_fcall_create(parser, &identifier, &arguments);
|
18289
18410
|
|
18290
18411
|
if (PM_NODE_TYPE_P(node, PM_IT_LOCAL_VARIABLE_READ_NODE)) {
|
@@ -18313,7 +18434,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18313
18434
|
}
|
18314
18435
|
|
18315
18436
|
if ((binding_power == PM_BINDING_POWER_STATEMENT) && match1(parser, PM_TOKEN_COMMA)) {
|
18316
|
-
node = parse_targets_validate(parser, node, PM_BINDING_POWER_INDEX);
|
18437
|
+
node = parse_targets_validate(parser, node, PM_BINDING_POWER_INDEX, (uint16_t) (depth + 1));
|
18317
18438
|
}
|
18318
18439
|
|
18319
18440
|
return node;
|
@@ -18345,7 +18466,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18345
18466
|
}
|
18346
18467
|
|
18347
18468
|
node->location.end = opening.end;
|
18348
|
-
} else if ((part = parse_string_part(parser)) == NULL) {
|
18469
|
+
} else if ((part = parse_string_part(parser, (uint16_t) (depth + 1))) == NULL) {
|
18349
18470
|
// If we get here, then we tried to find something in the
|
18350
18471
|
// heredoc but couldn't actually parse anything, so we'll just
|
18351
18472
|
// return a missing node.
|
@@ -18385,7 +18506,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18385
18506
|
pm_node_list_append(&parts, part);
|
18386
18507
|
|
18387
18508
|
while (!match2(parser, PM_TOKEN_HEREDOC_END, PM_TOKEN_EOF)) {
|
18388
|
-
if ((part = parse_string_part(parser)) != NULL) {
|
18509
|
+
if ((part = parse_string_part(parser, (uint16_t) (depth + 1))) != NULL) {
|
18389
18510
|
pm_node_list_append(&parts, part);
|
18390
18511
|
}
|
18391
18512
|
}
|
@@ -18429,7 +18550,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18429
18550
|
}
|
18430
18551
|
|
18431
18552
|
if (match1(parser, PM_TOKEN_STRING_BEGIN)) {
|
18432
|
-
return parse_strings(parser, node);
|
18553
|
+
return parse_strings(parser, node, false, (uint16_t) (depth + 1));
|
18433
18554
|
}
|
18434
18555
|
|
18435
18556
|
return node;
|
@@ -18439,7 +18560,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18439
18560
|
pm_node_t *node = (pm_node_t *) pm_instance_variable_read_node_create(parser, &parser->previous);
|
18440
18561
|
|
18441
18562
|
if (binding_power == PM_BINDING_POWER_STATEMENT && match1(parser, PM_TOKEN_COMMA)) {
|
18442
|
-
node = parse_targets_validate(parser, node, PM_BINDING_POWER_INDEX);
|
18563
|
+
node = parse_targets_validate(parser, node, PM_BINDING_POWER_INDEX, (uint16_t) (depth + 1));
|
18443
18564
|
}
|
18444
18565
|
|
18445
18566
|
return node;
|
@@ -18481,8 +18602,8 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18481
18602
|
parser_lex(parser);
|
18482
18603
|
pm_token_t keyword = parser->previous;
|
18483
18604
|
|
18484
|
-
pm_node_t *new_name = parse_alias_argument(parser, true);
|
18485
|
-
pm_node_t *old_name = parse_alias_argument(parser, false);
|
18605
|
+
pm_node_t *new_name = parse_alias_argument(parser, true, (uint16_t) (depth + 1));
|
18606
|
+
pm_node_t *old_name = parse_alias_argument(parser, false, (uint16_t) (depth + 1));
|
18486
18607
|
|
18487
18608
|
switch (PM_NODE_TYPE(new_name)) {
|
18488
18609
|
case PM_BACK_REFERENCE_READ_NODE:
|
@@ -18527,12 +18648,12 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18527
18648
|
} else if (!token_begins_expression_p(parser->current.type)) {
|
18528
18649
|
predicate = NULL;
|
18529
18650
|
} else {
|
18530
|
-
predicate = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, true, PM_ERR_CASE_EXPRESSION_AFTER_CASE);
|
18651
|
+
predicate = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, true, false, PM_ERR_CASE_EXPRESSION_AFTER_CASE, (uint16_t) (depth + 1));
|
18531
18652
|
while (accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON));
|
18532
18653
|
}
|
18533
18654
|
|
18534
18655
|
if (match1(parser, PM_TOKEN_KEYWORD_END)) {
|
18535
|
-
parser_warn_indentation_mismatch(parser, opening_newline_index, &case_keyword, false);
|
18656
|
+
parser_warn_indentation_mismatch(parser, opening_newline_index, &case_keyword, false, false);
|
18536
18657
|
parser_lex(parser);
|
18537
18658
|
|
18538
18659
|
pop_block_exits(parser, previous_block_exits);
|
@@ -18555,7 +18676,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18555
18676
|
// case-when node. We will continue to parse the when nodes
|
18556
18677
|
// until we hit the end of the list.
|
18557
18678
|
while (match1(parser, PM_TOKEN_KEYWORD_WHEN)) {
|
18558
|
-
parser_warn_indentation_mismatch(parser, opening_newline_index, &case_keyword, false);
|
18679
|
+
parser_warn_indentation_mismatch(parser, opening_newline_index, &case_keyword, false, true);
|
18559
18680
|
parser_lex(parser);
|
18560
18681
|
|
18561
18682
|
pm_token_t when_keyword = parser->previous;
|
@@ -18564,14 +18685,14 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18564
18685
|
do {
|
18565
18686
|
if (accept1(parser, PM_TOKEN_USTAR)) {
|
18566
18687
|
pm_token_t operator = parser->previous;
|
18567
|
-
pm_node_t *expression = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_EXPECT_EXPRESSION_AFTER_STAR);
|
18688
|
+
pm_node_t *expression = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, false, PM_ERR_EXPECT_EXPRESSION_AFTER_STAR, (uint16_t) (depth + 1));
|
18568
18689
|
|
18569
18690
|
pm_splat_node_t *splat_node = pm_splat_node_create(parser, &operator, expression);
|
18570
18691
|
pm_when_node_conditions_append(when_node, (pm_node_t *) splat_node);
|
18571
18692
|
|
18572
18693
|
if (PM_NODE_TYPE_P(expression, PM_MISSING_NODE)) break;
|
18573
18694
|
} else {
|
18574
|
-
pm_node_t *condition = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_CASE_EXPRESSION_AFTER_WHEN);
|
18695
|
+
pm_node_t *condition = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, false, PM_ERR_CASE_EXPRESSION_AFTER_WHEN, (uint16_t) (depth + 1));
|
18575
18696
|
pm_when_node_conditions_append(when_node, condition);
|
18576
18697
|
|
18577
18698
|
// If we found a missing node, then this is a syntax
|
@@ -18600,7 +18721,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18600
18721
|
}
|
18601
18722
|
|
18602
18723
|
if (!match3(parser, PM_TOKEN_KEYWORD_WHEN, PM_TOKEN_KEYWORD_ELSE, PM_TOKEN_KEYWORD_END)) {
|
18603
|
-
pm_statements_node_t *statements = parse_statements(parser, PM_CONTEXT_CASE_WHEN);
|
18724
|
+
pm_statements_node_t *statements = parse_statements(parser, PM_CONTEXT_CASE_WHEN, (uint16_t) (depth + 1));
|
18604
18725
|
if (statements != NULL) {
|
18605
18726
|
pm_when_node_statements_set(when_node, statements);
|
18606
18727
|
}
|
@@ -18630,7 +18751,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18630
18751
|
// will continue to parse the in nodes until we hit the end of
|
18631
18752
|
// the list.
|
18632
18753
|
while (match1(parser, PM_TOKEN_KEYWORD_IN)) {
|
18633
|
-
parser_warn_indentation_mismatch(parser, opening_newline_index, &case_keyword, false);
|
18754
|
+
parser_warn_indentation_mismatch(parser, opening_newline_index, &case_keyword, false, true);
|
18634
18755
|
|
18635
18756
|
bool previous_pattern_matching_newlines = parser->pattern_matching_newlines;
|
18636
18757
|
parser->pattern_matching_newlines = true;
|
@@ -18642,7 +18763,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18642
18763
|
pm_token_t in_keyword = parser->previous;
|
18643
18764
|
|
18644
18765
|
pm_constant_id_list_t captures = { 0 };
|
18645
|
-
pm_node_t *pattern = parse_pattern(parser, &captures, PM_PARSE_PATTERN_TOP | PM_PARSE_PATTERN_MULTI, PM_ERR_PATTERN_EXPRESSION_AFTER_IN);
|
18766
|
+
pm_node_t *pattern = parse_pattern(parser, &captures, PM_PARSE_PATTERN_TOP | PM_PARSE_PATTERN_MULTI, PM_ERR_PATTERN_EXPRESSION_AFTER_IN, (uint16_t) (depth + 1));
|
18646
18767
|
|
18647
18768
|
parser->pattern_matching_newlines = previous_pattern_matching_newlines;
|
18648
18769
|
pm_constant_id_list_free(&captures);
|
@@ -18652,11 +18773,11 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18652
18773
|
// `unless` statements.
|
18653
18774
|
if (accept1(parser, PM_TOKEN_KEYWORD_IF_MODIFIER)) {
|
18654
18775
|
pm_token_t keyword = parser->previous;
|
18655
|
-
pm_node_t *predicate = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, true, PM_ERR_CONDITIONAL_IF_PREDICATE);
|
18776
|
+
pm_node_t *predicate = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, true, false, PM_ERR_CONDITIONAL_IF_PREDICATE, (uint16_t) (depth + 1));
|
18656
18777
|
pattern = (pm_node_t *) pm_if_node_modifier_create(parser, pattern, &keyword, predicate);
|
18657
18778
|
} else if (accept1(parser, PM_TOKEN_KEYWORD_UNLESS_MODIFIER)) {
|
18658
18779
|
pm_token_t keyword = parser->previous;
|
18659
|
-
pm_node_t *predicate = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, true, PM_ERR_CONDITIONAL_UNLESS_PREDICATE);
|
18780
|
+
pm_node_t *predicate = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, true, false, PM_ERR_CONDITIONAL_UNLESS_PREDICATE, (uint16_t) (depth + 1));
|
18660
18781
|
pattern = (pm_node_t *) pm_unless_node_modifier_create(parser, pattern, &keyword, predicate);
|
18661
18782
|
}
|
18662
18783
|
|
@@ -18681,7 +18802,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18681
18802
|
if (match3(parser, PM_TOKEN_KEYWORD_IN, PM_TOKEN_KEYWORD_ELSE, PM_TOKEN_KEYWORD_END)) {
|
18682
18803
|
statements = NULL;
|
18683
18804
|
} else {
|
18684
|
-
statements = parse_statements(parser, PM_CONTEXT_CASE_IN);
|
18805
|
+
statements = parse_statements(parser, PM_CONTEXT_CASE_IN, (uint16_t) (depth + 1));
|
18685
18806
|
}
|
18686
18807
|
|
18687
18808
|
// Now that we have the full pattern and statements, we can
|
@@ -18705,7 +18826,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18705
18826
|
pm_else_node_t *else_node;
|
18706
18827
|
|
18707
18828
|
if (!match1(parser, PM_TOKEN_KEYWORD_END)) {
|
18708
|
-
else_node = pm_else_node_create(parser, &else_keyword, parse_statements(parser, PM_CONTEXT_ELSE), &parser->current);
|
18829
|
+
else_node = pm_else_node_create(parser, &else_keyword, parse_statements(parser, PM_CONTEXT_ELSE, (uint16_t) (depth + 1)), &parser->current);
|
18709
18830
|
} else {
|
18710
18831
|
else_node = pm_else_node_create(parser, &else_keyword, NULL, &parser->current);
|
18711
18832
|
}
|
@@ -18717,7 +18838,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18717
18838
|
}
|
18718
18839
|
}
|
18719
18840
|
|
18720
|
-
parser_warn_indentation_mismatch(parser, opening_newline_index, &case_keyword, false);
|
18841
|
+
parser_warn_indentation_mismatch(parser, opening_newline_index, &case_keyword, false, false);
|
18721
18842
|
expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CASE_TERM);
|
18722
18843
|
|
18723
18844
|
if (PM_NODE_TYPE_P(node, PM_CASE_NODE)) {
|
@@ -18744,13 +18865,13 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18744
18865
|
|
18745
18866
|
if (!match4(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE, PM_TOKEN_KEYWORD_ELSE, PM_TOKEN_KEYWORD_END)) {
|
18746
18867
|
pm_accepts_block_stack_push(parser, true);
|
18747
|
-
begin_statements = parse_statements(parser, PM_CONTEXT_BEGIN);
|
18868
|
+
begin_statements = parse_statements(parser, PM_CONTEXT_BEGIN, (uint16_t) (depth + 1));
|
18748
18869
|
pm_accepts_block_stack_pop(parser);
|
18749
18870
|
accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON);
|
18750
18871
|
}
|
18751
18872
|
|
18752
18873
|
pm_begin_node_t *begin_node = pm_begin_node_create(parser, &begin_keyword, begin_statements);
|
18753
|
-
parse_rescues(parser, opening_newline_index, &begin_keyword, begin_node, PM_RESCUES_BEGIN);
|
18874
|
+
parse_rescues(parser, opening_newline_index, &begin_keyword, begin_node, PM_RESCUES_BEGIN, (uint16_t) (depth + 1));
|
18754
18875
|
expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_BEGIN_TERM);
|
18755
18876
|
|
18756
18877
|
begin_node->base.location.end = parser->previous.end;
|
@@ -18774,7 +18895,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18774
18895
|
|
18775
18896
|
expect1(parser, PM_TOKEN_BRACE_LEFT, PM_ERR_BEGIN_UPCASE_BRACE);
|
18776
18897
|
pm_token_t opening = parser->previous;
|
18777
|
-
pm_statements_node_t *statements = parse_statements(parser, PM_CONTEXT_PREEXE);
|
18898
|
+
pm_statements_node_t *statements = parse_statements(parser, PM_CONTEXT_PREEXE, (uint16_t) (depth + 1));
|
18778
18899
|
|
18779
18900
|
expect1(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_BEGIN_UPCASE_TERM);
|
18780
18901
|
pm_context_t context = parser->current_context->context;
|
@@ -18802,19 +18923,19 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18802
18923
|
pm_binding_power_t binding_power = pm_binding_powers[parser->current.type].left;
|
18803
18924
|
|
18804
18925
|
if (binding_power == PM_BINDING_POWER_UNSET || binding_power >= PM_BINDING_POWER_RANGE) {
|
18805
|
-
parse_arguments(parser, &arguments, false, PM_TOKEN_EOF);
|
18926
|
+
parse_arguments(parser, &arguments, false, PM_TOKEN_EOF, (uint16_t) (depth + 1));
|
18806
18927
|
}
|
18807
18928
|
}
|
18808
18929
|
|
18809
18930
|
switch (keyword.type) {
|
18810
18931
|
case PM_TOKEN_KEYWORD_BREAK: {
|
18811
18932
|
pm_node_t *node = (pm_node_t *) pm_break_node_create(parser, &keyword, arguments.arguments);
|
18812
|
-
if (!parser->
|
18933
|
+
if (!parser->partial_script) parse_block_exit(parser, node);
|
18813
18934
|
return node;
|
18814
18935
|
}
|
18815
18936
|
case PM_TOKEN_KEYWORD_NEXT: {
|
18816
18937
|
pm_node_t *node = (pm_node_t *) pm_next_node_create(parser, &keyword, arguments.arguments);
|
18817
|
-
if (!parser->
|
18938
|
+
if (!parser->partial_script) parse_block_exit(parser, node);
|
18818
18939
|
return node;
|
18819
18940
|
}
|
18820
18941
|
case PM_TOKEN_KEYWORD_RETURN: {
|
@@ -18832,7 +18953,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18832
18953
|
|
18833
18954
|
pm_token_t keyword = parser->previous;
|
18834
18955
|
pm_arguments_t arguments = { 0 };
|
18835
|
-
parse_arguments_list(parser, &arguments, true, accepts_command_call);
|
18956
|
+
parse_arguments_list(parser, &arguments, true, accepts_command_call, (uint16_t) (depth + 1));
|
18836
18957
|
|
18837
18958
|
if (
|
18838
18959
|
arguments.opening_loc.start == NULL &&
|
@@ -18849,7 +18970,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18849
18970
|
|
18850
18971
|
pm_token_t keyword = parser->previous;
|
18851
18972
|
pm_arguments_t arguments = { 0 };
|
18852
|
-
parse_arguments_list(parser, &arguments, false, accepts_command_call);
|
18973
|
+
parse_arguments_list(parser, &arguments, false, accepts_command_call, (uint16_t) (depth + 1));
|
18853
18974
|
|
18854
18975
|
// It's possible that we've parsed a block argument through our
|
18855
18976
|
// call to parse_arguments_list. If we found one, we should mark it
|
@@ -18862,7 +18983,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18862
18983
|
}
|
18863
18984
|
|
18864
18985
|
pm_node_t *node = (pm_node_t *) pm_yield_node_create(parser, &keyword, &arguments.opening_loc, arguments.arguments, &arguments.closing_loc);
|
18865
|
-
if (!parser->parsing_eval) parse_yield(parser, node);
|
18986
|
+
if (!parser->parsing_eval && !parser->partial_script) parse_yield(parser, node);
|
18866
18987
|
|
18867
18988
|
return node;
|
18868
18989
|
}
|
@@ -18878,23 +18999,25 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18878
18999
|
|
18879
19000
|
if (accept1(parser, PM_TOKEN_LESS_LESS)) {
|
18880
19001
|
pm_token_t operator = parser->previous;
|
18881
|
-
pm_node_t *expression = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, true, PM_ERR_EXPECT_EXPRESSION_AFTER_LESS_LESS);
|
19002
|
+
pm_node_t *expression = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, true, false, PM_ERR_EXPECT_EXPRESSION_AFTER_LESS_LESS, (uint16_t) (depth + 1));
|
18882
19003
|
|
18883
19004
|
pm_parser_scope_push(parser, true);
|
18884
|
-
|
19005
|
+
if (!match2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON)) {
|
19006
|
+
PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_EXPECT_SINGLETON_CLASS_DELIMITER, pm_token_type_human(parser->current.type));
|
19007
|
+
}
|
18885
19008
|
|
18886
19009
|
pm_node_t *statements = NULL;
|
18887
19010
|
if (!match4(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE, PM_TOKEN_KEYWORD_ELSE, PM_TOKEN_KEYWORD_END)) {
|
18888
19011
|
pm_accepts_block_stack_push(parser, true);
|
18889
|
-
statements = (pm_node_t *) parse_statements(parser, PM_CONTEXT_SCLASS);
|
19012
|
+
statements = (pm_node_t *) parse_statements(parser, PM_CONTEXT_SCLASS, (uint16_t) (depth + 1));
|
18890
19013
|
pm_accepts_block_stack_pop(parser);
|
18891
19014
|
}
|
18892
19015
|
|
18893
19016
|
if (match2(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) {
|
18894
19017
|
assert(statements == NULL || PM_NODE_TYPE_P(statements, PM_STATEMENTS_NODE));
|
18895
|
-
statements = (pm_node_t *) parse_rescues_implicit_begin(parser, opening_newline_index, &class_keyword, class_keyword.start, (pm_statements_node_t *) statements, PM_RESCUES_SCLASS);
|
19018
|
+
statements = (pm_node_t *) parse_rescues_implicit_begin(parser, opening_newline_index, &class_keyword, class_keyword.start, (pm_statements_node_t *) statements, PM_RESCUES_SCLASS, (uint16_t) (depth + 1));
|
18896
19019
|
} else {
|
18897
|
-
parser_warn_indentation_mismatch(parser, opening_newline_index, &class_keyword, false);
|
19020
|
+
parser_warn_indentation_mismatch(parser, opening_newline_index, &class_keyword, false, false);
|
18898
19021
|
}
|
18899
19022
|
|
18900
19023
|
expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CLASS_TERM);
|
@@ -18911,7 +19034,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18911
19034
|
return (pm_node_t *) pm_singleton_class_node_create(parser, &locals, &class_keyword, &operator, expression, statements, &parser->previous);
|
18912
19035
|
}
|
18913
19036
|
|
18914
|
-
pm_node_t *constant_path = parse_expression(parser, PM_BINDING_POWER_INDEX, false, PM_ERR_CLASS_NAME);
|
19037
|
+
pm_node_t *constant_path = parse_expression(parser, PM_BINDING_POWER_INDEX, false, false, PM_ERR_CLASS_NAME, (uint16_t) (depth + 1));
|
18915
19038
|
pm_token_t name = parser->previous;
|
18916
19039
|
if (name.type != PM_TOKEN_CONSTANT) {
|
18917
19040
|
pm_parser_err_token(parser, &name, PM_ERR_CLASS_NAME);
|
@@ -18927,7 +19050,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18927
19050
|
parser->command_start = true;
|
18928
19051
|
parser_lex(parser);
|
18929
19052
|
|
18930
|
-
superclass = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, true, PM_ERR_CLASS_SUPERCLASS);
|
19053
|
+
superclass = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, true, false, PM_ERR_CLASS_SUPERCLASS, (uint16_t) (depth + 1));
|
18931
19054
|
} else {
|
18932
19055
|
inheritance_operator = not_provided(parser);
|
18933
19056
|
superclass = NULL;
|
@@ -18944,15 +19067,15 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
18944
19067
|
|
18945
19068
|
if (!match4(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE, PM_TOKEN_KEYWORD_ELSE, PM_TOKEN_KEYWORD_END)) {
|
18946
19069
|
pm_accepts_block_stack_push(parser, true);
|
18947
|
-
statements = (pm_node_t *) parse_statements(parser, PM_CONTEXT_CLASS);
|
19070
|
+
statements = (pm_node_t *) parse_statements(parser, PM_CONTEXT_CLASS, (uint16_t) (depth + 1));
|
18948
19071
|
pm_accepts_block_stack_pop(parser);
|
18949
19072
|
}
|
18950
19073
|
|
18951
19074
|
if (match2(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) {
|
18952
19075
|
assert(statements == NULL || PM_NODE_TYPE_P(statements, PM_STATEMENTS_NODE));
|
18953
|
-
statements = (pm_node_t *) parse_rescues_implicit_begin(parser, opening_newline_index, &class_keyword, class_keyword.start, (pm_statements_node_t *) statements, PM_RESCUES_CLASS);
|
19076
|
+
statements = (pm_node_t *) parse_rescues_implicit_begin(parser, opening_newline_index, &class_keyword, class_keyword.start, (pm_statements_node_t *) statements, PM_RESCUES_CLASS, (uint16_t) (depth + 1));
|
18954
19077
|
} else {
|
18955
|
-
parser_warn_indentation_mismatch(parser, opening_newline_index, &class_keyword, false);
|
19078
|
+
parser_warn_indentation_mismatch(parser, opening_newline_index, &class_keyword, false, false);
|
18956
19079
|
}
|
18957
19080
|
|
18958
19081
|
expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CLASS_TERM);
|
@@ -19096,7 +19219,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
19096
19219
|
parser_lex(parser);
|
19097
19220
|
|
19098
19221
|
pm_token_t lparen = parser->previous;
|
19099
|
-
pm_node_t *expression = parse_value_expression(parser,
|
19222
|
+
pm_node_t *expression = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, true, false, PM_ERR_DEF_RECEIVER, (uint16_t) (depth + 1));
|
19100
19223
|
|
19101
19224
|
accept1(parser, PM_TOKEN_NEWLINE);
|
19102
19225
|
expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_EXPECT_RPAREN);
|
@@ -19133,12 +19256,13 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
19133
19256
|
if (match1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) {
|
19134
19257
|
params = NULL;
|
19135
19258
|
} else {
|
19136
|
-
params = parse_parameters(parser, PM_BINDING_POWER_DEFINED, true, false, true);
|
19259
|
+
params = parse_parameters(parser, PM_BINDING_POWER_DEFINED, true, false, true, true, (uint16_t) (depth + 1));
|
19137
19260
|
}
|
19138
19261
|
|
19139
19262
|
lex_state_set(parser, PM_LEX_STATE_BEG);
|
19140
19263
|
parser->command_start = true;
|
19141
19264
|
|
19265
|
+
context_pop(parser);
|
19142
19266
|
if (!accept1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) {
|
19143
19267
|
PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_DEF_PARAMS_TERM_PAREN, pm_token_type_human(parser->current.type));
|
19144
19268
|
parser->previous.start = parser->previous.end;
|
@@ -19157,18 +19281,21 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
19157
19281
|
|
19158
19282
|
lparen = not_provided(parser);
|
19159
19283
|
rparen = not_provided(parser);
|
19160
|
-
params = parse_parameters(parser, PM_BINDING_POWER_DEFINED, false, false, true);
|
19284
|
+
params = parse_parameters(parser, PM_BINDING_POWER_DEFINED, false, false, true, true, (uint16_t) (depth + 1));
|
19285
|
+
|
19286
|
+
context_pop(parser);
|
19161
19287
|
break;
|
19162
19288
|
}
|
19163
19289
|
default: {
|
19164
19290
|
lparen = not_provided(parser);
|
19165
19291
|
rparen = not_provided(parser);
|
19166
19292
|
params = NULL;
|
19293
|
+
|
19294
|
+
context_pop(parser);
|
19167
19295
|
break;
|
19168
19296
|
}
|
19169
19297
|
}
|
19170
19298
|
|
19171
|
-
context_pop(parser);
|
19172
19299
|
pm_node_t *statements = NULL;
|
19173
19300
|
pm_token_t equal;
|
19174
19301
|
pm_token_t end_keyword;
|
@@ -19183,13 +19310,13 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
19183
19310
|
pm_do_loop_stack_push(parser, false);
|
19184
19311
|
statements = (pm_node_t *) pm_statements_node_create(parser);
|
19185
19312
|
|
19186
|
-
pm_node_t *statement = parse_expression(parser, PM_BINDING_POWER_DEFINED + 1, binding_power < PM_BINDING_POWER_COMPOSITION, PM_ERR_DEF_ENDLESS);
|
19313
|
+
pm_node_t *statement = parse_expression(parser, PM_BINDING_POWER_DEFINED + 1, binding_power < PM_BINDING_POWER_COMPOSITION, false, PM_ERR_DEF_ENDLESS, (uint16_t) (depth + 1));
|
19187
19314
|
|
19188
19315
|
if (accept1(parser, PM_TOKEN_KEYWORD_RESCUE_MODIFIER)) {
|
19189
19316
|
context_push(parser, PM_CONTEXT_RESCUE_MODIFIER);
|
19190
19317
|
|
19191
19318
|
pm_token_t rescue_keyword = parser->previous;
|
19192
|
-
pm_node_t *value = parse_expression(parser, binding_power, false, PM_ERR_RESCUE_MODIFIER_VALUE);
|
19319
|
+
pm_node_t *value = parse_expression(parser, binding_power, false, false, PM_ERR_RESCUE_MODIFIER_VALUE, (uint16_t) (depth + 1));
|
19193
19320
|
context_pop(parser);
|
19194
19321
|
|
19195
19322
|
statement = (pm_node_t *) pm_rescue_modifier_node_create(parser, statement, &rescue_keyword, value);
|
@@ -19215,15 +19342,15 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
19215
19342
|
|
19216
19343
|
if (!match4(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE, PM_TOKEN_KEYWORD_ELSE, PM_TOKEN_KEYWORD_END)) {
|
19217
19344
|
pm_accepts_block_stack_push(parser, true);
|
19218
|
-
statements = (pm_node_t *) parse_statements(parser, PM_CONTEXT_DEF);
|
19345
|
+
statements = (pm_node_t *) parse_statements(parser, PM_CONTEXT_DEF, (uint16_t) (depth + 1));
|
19219
19346
|
pm_accepts_block_stack_pop(parser);
|
19220
19347
|
}
|
19221
19348
|
|
19222
19349
|
if (match3(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE, PM_TOKEN_KEYWORD_ELSE)) {
|
19223
19350
|
assert(statements == NULL || PM_NODE_TYPE_P(statements, PM_STATEMENTS_NODE));
|
19224
|
-
statements = (pm_node_t *) parse_rescues_implicit_begin(parser, opening_newline_index, &def_keyword, def_keyword.start, (pm_statements_node_t *) statements, PM_RESCUES_DEF);
|
19351
|
+
statements = (pm_node_t *) parse_rescues_implicit_begin(parser, opening_newline_index, &def_keyword, def_keyword.start, (pm_statements_node_t *) statements, PM_RESCUES_DEF, (uint16_t) (depth + 1));
|
19225
19352
|
} else {
|
19226
|
-
parser_warn_indentation_mismatch(parser, opening_newline_index, &def_keyword, false);
|
19353
|
+
parser_warn_indentation_mismatch(parser, opening_newline_index, &def_keyword, false, false);
|
19227
19354
|
}
|
19228
19355
|
|
19229
19356
|
pm_accepts_block_stack_pop(parser);
|
@@ -19274,7 +19401,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
19274
19401
|
|
19275
19402
|
if (accept1(parser, PM_TOKEN_PARENTHESIS_LEFT)) {
|
19276
19403
|
lparen = parser->previous;
|
19277
|
-
expression = parse_expression(parser, PM_BINDING_POWER_COMPOSITION, true, PM_ERR_DEFINED_EXPRESSION);
|
19404
|
+
expression = parse_expression(parser, PM_BINDING_POWER_COMPOSITION, true, false, PM_ERR_DEFINED_EXPRESSION, (uint16_t) (depth + 1));
|
19278
19405
|
|
19279
19406
|
if (parser->recovering) {
|
19280
19407
|
rparen = not_provided(parser);
|
@@ -19286,7 +19413,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
19286
19413
|
} else {
|
19287
19414
|
lparen = not_provided(parser);
|
19288
19415
|
rparen = not_provided(parser);
|
19289
|
-
expression = parse_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_DEFINED_EXPRESSION);
|
19416
|
+
expression = parse_expression(parser, PM_BINDING_POWER_DEFINED, false, false, PM_ERR_DEFINED_EXPRESSION, (uint16_t) (depth + 1));
|
19290
19417
|
}
|
19291
19418
|
|
19292
19419
|
context_pop(parser);
|
@@ -19312,7 +19439,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
19312
19439
|
|
19313
19440
|
expect1(parser, PM_TOKEN_BRACE_LEFT, PM_ERR_END_UPCASE_BRACE);
|
19314
19441
|
pm_token_t opening = parser->previous;
|
19315
|
-
pm_statements_node_t *statements = parse_statements(parser, PM_CONTEXT_POSTEXE);
|
19442
|
+
pm_statements_node_t *statements = parse_statements(parser, PM_CONTEXT_POSTEXE, (uint16_t) (depth + 1));
|
19316
19443
|
|
19317
19444
|
expect1(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_END_UPCASE_TERM);
|
19318
19445
|
return (pm_node_t *) pm_post_execution_node_create(parser, &keyword, &opening, statements, &parser->previous);
|
@@ -19335,12 +19462,12 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
19335
19462
|
pm_node_t *name = NULL;
|
19336
19463
|
|
19337
19464
|
if (token_begins_expression_p(parser->current.type)) {
|
19338
|
-
name = parse_expression(parser, PM_BINDING_POWER_INDEX, false, PM_ERR_EXPECT_EXPRESSION_AFTER_STAR);
|
19465
|
+
name = parse_expression(parser, PM_BINDING_POWER_INDEX, false, false, PM_ERR_EXPECT_EXPRESSION_AFTER_STAR, (uint16_t) (depth + 1));
|
19339
19466
|
}
|
19340
19467
|
|
19341
19468
|
index = (pm_node_t *) pm_splat_node_create(parser, &star_operator, name);
|
19342
19469
|
} else if (token_begins_expression_p(parser->current.type)) {
|
19343
|
-
index = parse_expression(parser, PM_BINDING_POWER_INDEX, false, PM_ERR_EXPECT_EXPRESSION_AFTER_COMMA);
|
19470
|
+
index = parse_expression(parser, PM_BINDING_POWER_INDEX, false, false, PM_ERR_EXPECT_EXPRESSION_AFTER_COMMA, (uint16_t) (depth + 1));
|
19344
19471
|
} else {
|
19345
19472
|
pm_parser_err_token(parser, &for_keyword, PM_ERR_FOR_INDEX);
|
19346
19473
|
index = (pm_node_t *) pm_missing_node_create(parser, for_keyword.start, for_keyword.end);
|
@@ -19348,7 +19475,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
19348
19475
|
|
19349
19476
|
// Now, if there are multiple index expressions, parse them out.
|
19350
19477
|
if (match1(parser, PM_TOKEN_COMMA)) {
|
19351
|
-
index = parse_targets(parser, index, PM_BINDING_POWER_INDEX);
|
19478
|
+
index = parse_targets(parser, index, PM_BINDING_POWER_INDEX, (uint16_t) (depth + 1));
|
19352
19479
|
} else {
|
19353
19480
|
index = parse_target(parser, index, false, false);
|
19354
19481
|
}
|
@@ -19359,7 +19486,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
19359
19486
|
expect1(parser, PM_TOKEN_KEYWORD_IN, PM_ERR_FOR_IN);
|
19360
19487
|
pm_token_t in_keyword = parser->previous;
|
19361
19488
|
|
19362
|
-
pm_node_t *collection = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, true, PM_ERR_FOR_COLLECTION);
|
19489
|
+
pm_node_t *collection = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, true, false, PM_ERR_FOR_COLLECTION, (uint16_t) (depth + 1));
|
19363
19490
|
pm_do_loop_stack_pop(parser);
|
19364
19491
|
|
19365
19492
|
pm_token_t do_keyword;
|
@@ -19367,16 +19494,17 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
19367
19494
|
do_keyword = parser->previous;
|
19368
19495
|
} else {
|
19369
19496
|
do_keyword = not_provided(parser);
|
19497
|
+
if (!match2(parser, PM_TOKEN_SEMICOLON, PM_TOKEN_NEWLINE)) {
|
19498
|
+
PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_EXPECT_FOR_DELIMITER, pm_token_type_human(parser->current.type));
|
19499
|
+
}
|
19370
19500
|
}
|
19371
19501
|
|
19372
|
-
accept2(parser, PM_TOKEN_SEMICOLON, PM_TOKEN_NEWLINE);
|
19373
|
-
|
19374
19502
|
pm_statements_node_t *statements = NULL;
|
19375
19503
|
if (!match1(parser, PM_TOKEN_KEYWORD_END)) {
|
19376
|
-
statements = parse_statements(parser, PM_CONTEXT_FOR);
|
19504
|
+
statements = parse_statements(parser, PM_CONTEXT_FOR, (uint16_t) (depth + 1));
|
19377
19505
|
}
|
19378
19506
|
|
19379
|
-
parser_warn_indentation_mismatch(parser, opening_newline_index, &for_keyword, false);
|
19507
|
+
parser_warn_indentation_mismatch(parser, opening_newline_index, &for_keyword, false, false);
|
19380
19508
|
expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_FOR_TERM);
|
19381
19509
|
|
19382
19510
|
return (pm_node_t *) pm_for_node_create(parser, index, collection, statements, &for_keyword, &in_keyword, &do_keyword, &parser->previous);
|
@@ -19390,7 +19518,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
19390
19518
|
bool if_after_else = parser->previous.type == PM_TOKEN_KEYWORD_ELSE;
|
19391
19519
|
parser_lex(parser);
|
19392
19520
|
|
19393
|
-
return parse_conditional(parser, PM_CONTEXT_IF, opening_newline_index, if_after_else);
|
19521
|
+
return parse_conditional(parser, PM_CONTEXT_IF, opening_newline_index, if_after_else, (uint16_t) (depth + 1));
|
19394
19522
|
case PM_TOKEN_KEYWORD_UNDEF: {
|
19395
19523
|
if (binding_power != PM_BINDING_POWER_STATEMENT) {
|
19396
19524
|
pm_parser_err_current(parser, PM_ERR_STATEMENT_UNDEF);
|
@@ -19398,7 +19526,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
19398
19526
|
|
19399
19527
|
parser_lex(parser);
|
19400
19528
|
pm_undef_node_t *undef = pm_undef_node_create(parser, &parser->previous);
|
19401
|
-
pm_node_t *name = parse_undef_argument(parser);
|
19529
|
+
pm_node_t *name = parse_undef_argument(parser, (uint16_t) (depth + 1));
|
19402
19530
|
|
19403
19531
|
if (PM_NODE_TYPE_P(name, PM_MISSING_NODE)) {
|
19404
19532
|
pm_node_destroy(parser, name);
|
@@ -19408,7 +19536,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
19408
19536
|
while (match1(parser, PM_TOKEN_COMMA)) {
|
19409
19537
|
lex_state_set(parser, PM_LEX_STATE_FNAME | PM_LEX_STATE_FITEM);
|
19410
19538
|
parser_lex(parser);
|
19411
|
-
name = parse_undef_argument(parser);
|
19539
|
+
name = parse_undef_argument(parser, (uint16_t) (depth + 1));
|
19412
19540
|
|
19413
19541
|
if (PM_NODE_TYPE_P(name, PM_MISSING_NODE)) {
|
19414
19542
|
pm_node_destroy(parser, name);
|
@@ -19436,7 +19564,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
19436
19564
|
if (accept1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) {
|
19437
19565
|
arguments.closing_loc = PM_LOCATION_TOKEN_VALUE(&parser->previous);
|
19438
19566
|
} else {
|
19439
|
-
receiver = parse_expression(parser, PM_BINDING_POWER_COMPOSITION, true, PM_ERR_NOT_EXPRESSION);
|
19567
|
+
receiver = parse_expression(parser, PM_BINDING_POWER_COMPOSITION, true, false, PM_ERR_NOT_EXPRESSION, (uint16_t) (depth + 1));
|
19440
19568
|
|
19441
19569
|
if (!parser->recovering) {
|
19442
19570
|
accept1(parser, PM_TOKEN_NEWLINE);
|
@@ -19445,7 +19573,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
19445
19573
|
}
|
19446
19574
|
}
|
19447
19575
|
} else {
|
19448
|
-
receiver = parse_expression(parser, PM_BINDING_POWER_NOT, true, PM_ERR_NOT_EXPRESSION);
|
19576
|
+
receiver = parse_expression(parser, PM_BINDING_POWER_NOT, true, false, PM_ERR_NOT_EXPRESSION, (uint16_t) (depth + 1));
|
19449
19577
|
}
|
19450
19578
|
|
19451
19579
|
return (pm_node_t *) pm_call_node_not_create(parser, receiver, &message, &arguments);
|
@@ -19454,7 +19582,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
19454
19582
|
size_t opening_newline_index = token_newline_index(parser);
|
19455
19583
|
parser_lex(parser);
|
19456
19584
|
|
19457
|
-
return parse_conditional(parser, PM_CONTEXT_UNLESS, opening_newline_index, false);
|
19585
|
+
return parse_conditional(parser, PM_CONTEXT_UNLESS, opening_newline_index, false, (uint16_t) (depth + 1));
|
19458
19586
|
}
|
19459
19587
|
case PM_TOKEN_KEYWORD_MODULE: {
|
19460
19588
|
pm_node_list_t current_block_exits = { 0 };
|
@@ -19464,7 +19592,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
19464
19592
|
parser_lex(parser);
|
19465
19593
|
pm_token_t module_keyword = parser->previous;
|
19466
19594
|
|
19467
|
-
pm_node_t *constant_path = parse_expression(parser, PM_BINDING_POWER_INDEX, false, PM_ERR_MODULE_NAME);
|
19595
|
+
pm_node_t *constant_path = parse_expression(parser, PM_BINDING_POWER_INDEX, false, false, PM_ERR_MODULE_NAME, (uint16_t) (depth + 1));
|
19468
19596
|
pm_token_t name;
|
19469
19597
|
|
19470
19598
|
// If we can recover from a syntax error that occurred while parsing
|
@@ -19498,15 +19626,15 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
19498
19626
|
|
19499
19627
|
if (!match4(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE, PM_TOKEN_KEYWORD_ELSE, PM_TOKEN_KEYWORD_END)) {
|
19500
19628
|
pm_accepts_block_stack_push(parser, true);
|
19501
|
-
statements = (pm_node_t *) parse_statements(parser, PM_CONTEXT_MODULE);
|
19629
|
+
statements = (pm_node_t *) parse_statements(parser, PM_CONTEXT_MODULE, (uint16_t) (depth + 1));
|
19502
19630
|
pm_accepts_block_stack_pop(parser);
|
19503
19631
|
}
|
19504
19632
|
|
19505
19633
|
if (match3(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE, PM_TOKEN_KEYWORD_ELSE)) {
|
19506
19634
|
assert(statements == NULL || PM_NODE_TYPE_P(statements, PM_STATEMENTS_NODE));
|
19507
|
-
statements = (pm_node_t *) parse_rescues_implicit_begin(parser, opening_newline_index, &module_keyword, module_keyword.start, (pm_statements_node_t *) statements, PM_RESCUES_MODULE);
|
19635
|
+
statements = (pm_node_t *) parse_rescues_implicit_begin(parser, opening_newline_index, &module_keyword, module_keyword.start, (pm_statements_node_t *) statements, PM_RESCUES_MODULE, (uint16_t) (depth + 1));
|
19508
19636
|
} else {
|
19509
|
-
parser_warn_indentation_mismatch(parser, opening_newline_index, &module_keyword, false);
|
19637
|
+
parser_warn_indentation_mismatch(parser, opening_newline_index, &module_keyword, false, false);
|
19510
19638
|
}
|
19511
19639
|
|
19512
19640
|
pm_constant_id_list_t locals;
|
@@ -19531,7 +19659,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
19531
19659
|
parser_lex(parser);
|
19532
19660
|
|
19533
19661
|
pm_node_t *node = (pm_node_t *) pm_redo_node_create(parser, &parser->previous);
|
19534
|
-
if (!parser->
|
19662
|
+
if (!parser->partial_script) parse_block_exit(parser, node);
|
19535
19663
|
|
19536
19664
|
return node;
|
19537
19665
|
}
|
@@ -19557,7 +19685,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
19557
19685
|
|
19558
19686
|
parser_lex(parser);
|
19559
19687
|
pm_token_t keyword = parser->previous;
|
19560
|
-
pm_node_t *predicate = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, true, PM_ERR_CONDITIONAL_UNTIL_PREDICATE);
|
19688
|
+
pm_node_t *predicate = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, true, false, PM_ERR_CONDITIONAL_UNTIL_PREDICATE, (uint16_t) (depth + 1));
|
19561
19689
|
|
19562
19690
|
pm_do_loop_stack_pop(parser);
|
19563
19691
|
context_pop(parser);
|
@@ -19567,12 +19695,12 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
19567
19695
|
|
19568
19696
|
if (!match1(parser, PM_TOKEN_KEYWORD_END)) {
|
19569
19697
|
pm_accepts_block_stack_push(parser, true);
|
19570
|
-
statements = parse_statements(parser, PM_CONTEXT_UNTIL);
|
19698
|
+
statements = parse_statements(parser, PM_CONTEXT_UNTIL, (uint16_t) (depth + 1));
|
19571
19699
|
pm_accepts_block_stack_pop(parser);
|
19572
19700
|
accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON);
|
19573
19701
|
}
|
19574
19702
|
|
19575
|
-
parser_warn_indentation_mismatch(parser, opening_newline_index, &keyword, false);
|
19703
|
+
parser_warn_indentation_mismatch(parser, opening_newline_index, &keyword, false, false);
|
19576
19704
|
expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_UNTIL_TERM);
|
19577
19705
|
|
19578
19706
|
return (pm_node_t *) pm_until_node_create(parser, &keyword, &parser->previous, predicate, statements, 0);
|
@@ -19585,7 +19713,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
19585
19713
|
|
19586
19714
|
parser_lex(parser);
|
19587
19715
|
pm_token_t keyword = parser->previous;
|
19588
|
-
pm_node_t *predicate = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, true, PM_ERR_CONDITIONAL_WHILE_PREDICATE);
|
19716
|
+
pm_node_t *predicate = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, true, false, PM_ERR_CONDITIONAL_WHILE_PREDICATE, (uint16_t) (depth + 1));
|
19589
19717
|
|
19590
19718
|
pm_do_loop_stack_pop(parser);
|
19591
19719
|
context_pop(parser);
|
@@ -19595,12 +19723,12 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
19595
19723
|
|
19596
19724
|
if (!match1(parser, PM_TOKEN_KEYWORD_END)) {
|
19597
19725
|
pm_accepts_block_stack_push(parser, true);
|
19598
|
-
statements = parse_statements(parser, PM_CONTEXT_WHILE);
|
19726
|
+
statements = parse_statements(parser, PM_CONTEXT_WHILE, (uint16_t) (depth + 1));
|
19599
19727
|
pm_accepts_block_stack_pop(parser);
|
19600
19728
|
accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON);
|
19601
19729
|
}
|
19602
19730
|
|
19603
|
-
parser_warn_indentation_mismatch(parser, opening_newline_index, &keyword, false);
|
19731
|
+
parser_warn_indentation_mismatch(parser, opening_newline_index, &keyword, false, false);
|
19604
19732
|
expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_WHILE_TERM);
|
19605
19733
|
|
19606
19734
|
return (pm_node_t *) pm_while_node_create(parser, &keyword, &parser->previous, predicate, statements, 0);
|
@@ -19728,7 +19856,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
19728
19856
|
// interpolated string, then we'll just add the embedded variable.
|
19729
19857
|
}
|
19730
19858
|
|
19731
|
-
pm_node_t *part = parse_string_part(parser);
|
19859
|
+
pm_node_t *part = parse_string_part(parser, (uint16_t) (depth + 1));
|
19732
19860
|
pm_interpolated_symbol_node_append((pm_interpolated_symbol_node_t *) current, part);
|
19733
19861
|
if (!start_location_set) {
|
19734
19862
|
current->location.start = part->location.start;
|
@@ -19765,7 +19893,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
19765
19893
|
assert(false && "unreachable");
|
19766
19894
|
}
|
19767
19895
|
|
19768
|
-
pm_node_t *part = parse_string_part(parser);
|
19896
|
+
pm_node_t *part = parse_string_part(parser, (uint16_t) (depth + 1));
|
19769
19897
|
pm_interpolated_symbol_node_append((pm_interpolated_symbol_node_t *) current, part);
|
19770
19898
|
if (!start_location_set) {
|
19771
19899
|
current->location.start = part->location.start;
|
@@ -19918,7 +20046,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
19918
20046
|
// add the embedded variable.
|
19919
20047
|
}
|
19920
20048
|
|
19921
|
-
pm_node_t *part = parse_string_part(parser);
|
20049
|
+
pm_node_t *part = parse_string_part(parser, (uint16_t) (depth + 1));
|
19922
20050
|
pm_interpolated_string_node_append((pm_interpolated_string_node_t *) current, part);
|
19923
20051
|
break;
|
19924
20052
|
}
|
@@ -19949,7 +20077,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
19949
20077
|
assert(false && "unreachable");
|
19950
20078
|
}
|
19951
20079
|
|
19952
|
-
pm_node_t *part = parse_string_part(parser);
|
20080
|
+
pm_node_t *part = parse_string_part(parser, (uint16_t) (depth + 1));
|
19953
20081
|
pm_interpolated_string_node_append((pm_interpolated_string_node_t *) current, part);
|
19954
20082
|
break;
|
19955
20083
|
}
|
@@ -20055,7 +20183,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
20055
20183
|
// parts into the list.
|
20056
20184
|
pm_node_t *part;
|
20057
20185
|
while (!match2(parser, PM_TOKEN_REGEXP_END, PM_TOKEN_EOF)) {
|
20058
|
-
if ((part = parse_string_part(parser)) != NULL) {
|
20186
|
+
if ((part = parse_string_part(parser, (uint16_t) (depth + 1))) != NULL) {
|
20059
20187
|
pm_interpolated_regular_expression_node_append(interpolated, part);
|
20060
20188
|
}
|
20061
20189
|
}
|
@@ -20132,7 +20260,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
20132
20260
|
|
20133
20261
|
pm_node_t *part;
|
20134
20262
|
while (!match2(parser, PM_TOKEN_STRING_END, PM_TOKEN_EOF)) {
|
20135
|
-
if ((part = parse_string_part(parser)) != NULL) {
|
20263
|
+
if ((part = parse_string_part(parser, (uint16_t) (depth + 1))) != NULL) {
|
20136
20264
|
pm_interpolated_xstring_node_append(node, part);
|
20137
20265
|
}
|
20138
20266
|
}
|
@@ -20163,13 +20291,13 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
20163
20291
|
pm_node_t *name = NULL;
|
20164
20292
|
|
20165
20293
|
if (token_begins_expression_p(parser->current.type)) {
|
20166
|
-
name = parse_expression(parser, PM_BINDING_POWER_INDEX, false, PM_ERR_EXPECT_EXPRESSION_AFTER_STAR);
|
20294
|
+
name = parse_expression(parser, PM_BINDING_POWER_INDEX, false, false, PM_ERR_EXPECT_EXPRESSION_AFTER_STAR, (uint16_t) (depth + 1));
|
20167
20295
|
}
|
20168
20296
|
|
20169
20297
|
pm_node_t *splat = (pm_node_t *) pm_splat_node_create(parser, &operator, name);
|
20170
20298
|
|
20171
20299
|
if (match1(parser, PM_TOKEN_COMMA)) {
|
20172
|
-
return parse_targets_validate(parser, splat, PM_BINDING_POWER_INDEX);
|
20300
|
+
return parse_targets_validate(parser, splat, PM_BINDING_POWER_INDEX, (uint16_t) (depth + 1));
|
20173
20301
|
} else {
|
20174
20302
|
return parse_target_validate(parser, splat, true);
|
20175
20303
|
}
|
@@ -20182,7 +20310,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
20182
20310
|
parser_lex(parser);
|
20183
20311
|
|
20184
20312
|
pm_token_t operator = parser->previous;
|
20185
|
-
pm_node_t *receiver = parse_expression(parser, pm_binding_powers[parser->previous.type].right, binding_power < PM_BINDING_POWER_MATCH, PM_ERR_UNARY_RECEIVER);
|
20313
|
+
pm_node_t *receiver = parse_expression(parser, pm_binding_powers[parser->previous.type].right, binding_power < PM_BINDING_POWER_MATCH, false, PM_ERR_UNARY_RECEIVER, (uint16_t) (depth + 1));
|
20186
20314
|
pm_call_node_t *node = pm_call_node_unary_create(parser, &operator, receiver, "!");
|
20187
20315
|
|
20188
20316
|
pm_conditional_predicate(parser, receiver, PM_CONDITIONAL_PREDICATE_TYPE_NOT);
|
@@ -20195,7 +20323,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
20195
20323
|
parser_lex(parser);
|
20196
20324
|
|
20197
20325
|
pm_token_t operator = parser->previous;
|
20198
|
-
pm_node_t *receiver = parse_expression(parser, pm_binding_powers[parser->previous.type].right, false, PM_ERR_UNARY_RECEIVER);
|
20326
|
+
pm_node_t *receiver = parse_expression(parser, pm_binding_powers[parser->previous.type].right, false, false, PM_ERR_UNARY_RECEIVER, (uint16_t) (depth + 1));
|
20199
20327
|
pm_call_node_t *node = pm_call_node_unary_create(parser, &operator, receiver, "~");
|
20200
20328
|
|
20201
20329
|
return (pm_node_t *) node;
|
@@ -20207,7 +20335,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
20207
20335
|
parser_lex(parser);
|
20208
20336
|
|
20209
20337
|
pm_token_t operator = parser->previous;
|
20210
|
-
pm_node_t *receiver = parse_expression(parser, pm_binding_powers[parser->previous.type].right, false, PM_ERR_UNARY_RECEIVER);
|
20338
|
+
pm_node_t *receiver = parse_expression(parser, pm_binding_powers[parser->previous.type].right, false, false, PM_ERR_UNARY_RECEIVER, (uint16_t) (depth + 1));
|
20211
20339
|
pm_call_node_t *node = pm_call_node_unary_create(parser, &operator, receiver, "-@");
|
20212
20340
|
|
20213
20341
|
return (pm_node_t *) node;
|
@@ -20216,11 +20344,11 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
20216
20344
|
parser_lex(parser);
|
20217
20345
|
|
20218
20346
|
pm_token_t operator = parser->previous;
|
20219
|
-
pm_node_t *node = parse_expression(parser, pm_binding_powers[parser->previous.type].right, false, PM_ERR_UNARY_RECEIVER);
|
20347
|
+
pm_node_t *node = parse_expression(parser, pm_binding_powers[parser->previous.type].right, false, false, PM_ERR_UNARY_RECEIVER, (uint16_t) (depth + 1));
|
20220
20348
|
|
20221
20349
|
if (accept1(parser, PM_TOKEN_STAR_STAR)) {
|
20222
20350
|
pm_token_t exponent_operator = parser->previous;
|
20223
|
-
pm_node_t *exponent = parse_expression(parser, pm_binding_powers[exponent_operator.type].right, false, PM_ERR_EXPECT_ARGUMENT);
|
20351
|
+
pm_node_t *exponent = parse_expression(parser, pm_binding_powers[exponent_operator.type].right, false, false, PM_ERR_EXPECT_ARGUMENT, (uint16_t) (depth + 1));
|
20224
20352
|
node = (pm_node_t *) pm_call_node_binary_create(parser, node, &exponent_operator, exponent, 0);
|
20225
20353
|
node = (pm_node_t *) pm_call_node_unary_create(parser, &operator, node, "-@");
|
20226
20354
|
} else {
|
@@ -20260,7 +20388,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
20260
20388
|
if (match1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) {
|
20261
20389
|
block_parameters = pm_block_parameters_node_create(parser, NULL, &opening);
|
20262
20390
|
} else {
|
20263
|
-
block_parameters = parse_block_parameters(parser, false, &opening, true);
|
20391
|
+
block_parameters = parse_block_parameters(parser, false, &opening, true, true, (uint16_t) (depth + 1));
|
20264
20392
|
}
|
20265
20393
|
|
20266
20394
|
accept1(parser, PM_TOKEN_NEWLINE);
|
@@ -20272,7 +20400,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
20272
20400
|
case PM_CASE_PARAMETER: {
|
20273
20401
|
pm_accepts_block_stack_push(parser, false);
|
20274
20402
|
pm_token_t opening = not_provided(parser);
|
20275
|
-
block_parameters = parse_block_parameters(parser, false, &opening, true);
|
20403
|
+
block_parameters = parse_block_parameters(parser, false, &opening, true, false, (uint16_t) (depth + 1));
|
20276
20404
|
pm_accepts_block_stack_pop(parser);
|
20277
20405
|
break;
|
20278
20406
|
}
|
@@ -20290,10 +20418,10 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
20290
20418
|
opening = parser->previous;
|
20291
20419
|
|
20292
20420
|
if (!match1(parser, PM_TOKEN_BRACE_RIGHT)) {
|
20293
|
-
body = (pm_node_t *) parse_statements(parser, PM_CONTEXT_LAMBDA_BRACES);
|
20421
|
+
body = (pm_node_t *) parse_statements(parser, PM_CONTEXT_LAMBDA_BRACES, (uint16_t) (depth + 1));
|
20294
20422
|
}
|
20295
20423
|
|
20296
|
-
parser_warn_indentation_mismatch(parser, opening_newline_index, &operator, false);
|
20424
|
+
parser_warn_indentation_mismatch(parser, opening_newline_index, &operator, false, false);
|
20297
20425
|
expect1(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_LAMBDA_TERM_BRACE);
|
20298
20426
|
} else {
|
20299
20427
|
expect1(parser, PM_TOKEN_KEYWORD_DO, PM_ERR_LAMBDA_OPEN);
|
@@ -20301,15 +20429,15 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
20301
20429
|
|
20302
20430
|
if (!match3(parser, PM_TOKEN_KEYWORD_END, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) {
|
20303
20431
|
pm_accepts_block_stack_push(parser, true);
|
20304
|
-
body = (pm_node_t *) parse_statements(parser, PM_CONTEXT_LAMBDA_DO_END);
|
20432
|
+
body = (pm_node_t *) parse_statements(parser, PM_CONTEXT_LAMBDA_DO_END, (uint16_t) (depth + 1));
|
20305
20433
|
pm_accepts_block_stack_pop(parser);
|
20306
20434
|
}
|
20307
20435
|
|
20308
20436
|
if (match2(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) {
|
20309
20437
|
assert(body == NULL || PM_NODE_TYPE_P(body, PM_STATEMENTS_NODE));
|
20310
|
-
body = (pm_node_t *) parse_rescues_implicit_begin(parser, opening_newline_index, &operator, opening.start, (pm_statements_node_t *) body, PM_RESCUES_LAMBDA);
|
20438
|
+
body = (pm_node_t *) parse_rescues_implicit_begin(parser, opening_newline_index, &operator, opening.start, (pm_statements_node_t *) body, PM_RESCUES_LAMBDA, (uint16_t) (depth + 1));
|
20311
20439
|
} else {
|
20312
|
-
parser_warn_indentation_mismatch(parser, opening_newline_index, &operator, false);
|
20440
|
+
parser_warn_indentation_mismatch(parser, opening_newline_index, &operator, false, false);
|
20313
20441
|
}
|
20314
20442
|
|
20315
20443
|
expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_LAMBDA_TERM_END);
|
@@ -20331,18 +20459,18 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
20331
20459
|
parser_lex(parser);
|
20332
20460
|
|
20333
20461
|
pm_token_t operator = parser->previous;
|
20334
|
-
pm_node_t *receiver = parse_expression(parser, pm_binding_powers[parser->previous.type].right, false, PM_ERR_UNARY_RECEIVER);
|
20462
|
+
pm_node_t *receiver = parse_expression(parser, pm_binding_powers[parser->previous.type].right, false, false, PM_ERR_UNARY_RECEIVER, (uint16_t) (depth + 1));
|
20335
20463
|
pm_call_node_t *node = pm_call_node_unary_create(parser, &operator, receiver, "+@");
|
20336
20464
|
|
20337
20465
|
return (pm_node_t *) node;
|
20338
20466
|
}
|
20339
20467
|
case PM_TOKEN_STRING_BEGIN:
|
20340
|
-
return parse_strings(parser, NULL);
|
20468
|
+
return parse_strings(parser, NULL, accepts_label, (uint16_t) (depth + 1));
|
20341
20469
|
case PM_TOKEN_SYMBOL_BEGIN: {
|
20342
20470
|
pm_lex_mode_t lex_mode = *parser->lex_modes.current;
|
20343
20471
|
parser_lex(parser);
|
20344
20472
|
|
20345
|
-
return parse_symbol(parser, &lex_mode, PM_LEX_STATE_END);
|
20473
|
+
return parse_symbol(parser, &lex_mode, PM_LEX_STATE_END, (uint16_t) (depth + 1));
|
20346
20474
|
}
|
20347
20475
|
default: {
|
20348
20476
|
pm_context_t recoverable = context_recoverable(parser, &parser->current);
|
@@ -20385,8 +20513,8 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
|
|
20385
20513
|
* or any of the binary operators that can be written to a variable.
|
20386
20514
|
*/
|
20387
20515
|
static pm_node_t *
|
20388
|
-
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) {
|
20389
|
-
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);
|
20516
|
+
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, uint16_t depth) {
|
20517
|
+
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, false, diag_id, (uint16_t) (depth + 1));
|
20390
20518
|
|
20391
20519
|
// Contradicting binding powers, the right-hand-side value of the assignment
|
20392
20520
|
// allows the `rescue` modifier.
|
@@ -20396,7 +20524,7 @@ parse_assignment_value(pm_parser_t *parser, pm_binding_power_t previous_binding_
|
|
20396
20524
|
pm_token_t rescue = parser->current;
|
20397
20525
|
parser_lex(parser);
|
20398
20526
|
|
20399
|
-
pm_node_t *right = parse_expression(parser, binding_power, false, PM_ERR_RESCUE_MODIFIER_VALUE);
|
20527
|
+
pm_node_t *right = parse_expression(parser, binding_power, false, false, PM_ERR_RESCUE_MODIFIER_VALUE, (uint16_t) (depth + 1));
|
20400
20528
|
context_pop(parser);
|
20401
20529
|
|
20402
20530
|
return (pm_node_t *) pm_rescue_modifier_node_create(parser, value, &rescue, right);
|
@@ -20454,11 +20582,11 @@ parse_assignment_value_local(pm_parser_t *parser, const pm_node_t *node) {
|
|
20454
20582
|
* operator that allows multiple values after it.
|
20455
20583
|
*/
|
20456
20584
|
static pm_node_t *
|
20457
|
-
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) {
|
20585
|
+
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, uint16_t depth) {
|
20458
20586
|
bool permitted = true;
|
20459
20587
|
if (previous_binding_power != PM_BINDING_POWER_STATEMENT && match1(parser, PM_TOKEN_USTAR)) permitted = false;
|
20460
20588
|
|
20461
|
-
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);
|
20589
|
+
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, (uint16_t) (depth + 1));
|
20462
20590
|
if (!permitted) pm_parser_err_node(parser, value, PM_ERR_UNEXPECTED_MULTI_WRITE);
|
20463
20591
|
|
20464
20592
|
parse_assignment_value_local(parser, value);
|
@@ -20474,7 +20602,7 @@ parse_assignment_values(pm_parser_t *parser, pm_binding_power_t previous_binding
|
|
20474
20602
|
value = (pm_node_t *) array;
|
20475
20603
|
|
20476
20604
|
while (accept1(parser, PM_TOKEN_COMMA)) {
|
20477
|
-
pm_node_t *element = parse_starred_expression(parser, binding_power, false, PM_ERR_ARRAY_ELEMENT);
|
20605
|
+
pm_node_t *element = parse_starred_expression(parser, binding_power, false, PM_ERR_ARRAY_ELEMENT, (uint16_t) (depth + 1));
|
20478
20606
|
|
20479
20607
|
pm_array_node_elements_append(array, element);
|
20480
20608
|
if (PM_NODE_TYPE_P(element, PM_MISSING_NODE)) break;
|
@@ -20502,7 +20630,7 @@ parse_assignment_values(pm_parser_t *parser, pm_binding_power_t previous_binding
|
|
20502
20630
|
}
|
20503
20631
|
}
|
20504
20632
|
|
20505
|
-
pm_node_t *right = parse_expression(parser, binding_power, accepts_command_call_inner, PM_ERR_RESCUE_MODIFIER_VALUE);
|
20633
|
+
pm_node_t *right = parse_expression(parser, binding_power, accepts_command_call_inner, false, PM_ERR_RESCUE_MODIFIER_VALUE, (uint16_t) (depth + 1));
|
20506
20634
|
context_pop(parser);
|
20507
20635
|
|
20508
20636
|
return (pm_node_t *) pm_rescue_modifier_node_create(parser, value, &rescue, right);
|
@@ -20657,7 +20785,7 @@ parse_regular_expression_named_captures(pm_parser_t *parser, const pm_string_t *
|
|
20657
20785
|
}
|
20658
20786
|
|
20659
20787
|
static inline pm_node_t *
|
20660
|
-
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) {
|
20788
|
+
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, uint16_t depth) {
|
20661
20789
|
pm_token_t token = parser->current;
|
20662
20790
|
|
20663
20791
|
switch (token.type) {
|
@@ -20676,7 +20804,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
20676
20804
|
/* fallthrough */
|
20677
20805
|
case PM_CASE_WRITABLE: {
|
20678
20806
|
parser_lex(parser);
|
20679
|
-
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);
|
20807
|
+
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, (uint16_t) (depth + 1));
|
20680
20808
|
|
20681
20809
|
if (PM_NODE_TYPE_P(node, PM_MULTI_TARGET_NODE) && previous_binding_power != PM_BINDING_POWER_STATEMENT) {
|
20682
20810
|
pm_parser_err_node(parser, node, PM_ERR_UNEXPECTED_MULTI_WRITE);
|
@@ -20689,7 +20817,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
20689
20817
|
pm_multi_target_node_targets_append(parser, multi_target, node);
|
20690
20818
|
|
20691
20819
|
parser_lex(parser);
|
20692
|
-
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);
|
20820
|
+
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, (uint16_t) (depth + 1));
|
20693
20821
|
return parse_write(parser, (pm_node_t *) multi_target, &token, value);
|
20694
20822
|
}
|
20695
20823
|
case PM_SOURCE_ENCODING_NODE:
|
@@ -20702,7 +20830,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
20702
20830
|
// In these special cases, we have specific error messages
|
20703
20831
|
// and we will replace them with local variable writes.
|
20704
20832
|
parser_lex(parser);
|
20705
|
-
pm_node_t *value = parse_assignment_values(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_EQUAL);
|
20833
|
+
pm_node_t *value = parse_assignment_values(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_EQUAL, (uint16_t) (depth + 1));
|
20706
20834
|
return parse_unwriteable_write(parser, node, &token, value);
|
20707
20835
|
}
|
20708
20836
|
default:
|
@@ -20723,7 +20851,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
20723
20851
|
case PM_GLOBAL_VARIABLE_READ_NODE: {
|
20724
20852
|
parser_lex(parser);
|
20725
20853
|
|
20726
|
-
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
|
20854
|
+
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ, (uint16_t) (depth + 1));
|
20727
20855
|
pm_node_t *result = (pm_node_t *) pm_global_variable_and_write_node_create(parser, node, &token, value);
|
20728
20856
|
|
20729
20857
|
pm_node_destroy(parser, node);
|
@@ -20732,7 +20860,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
20732
20860
|
case PM_CLASS_VARIABLE_READ_NODE: {
|
20733
20861
|
parser_lex(parser);
|
20734
20862
|
|
20735
|
-
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
|
20863
|
+
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ, (uint16_t) (depth + 1));
|
20736
20864
|
pm_node_t *result = (pm_node_t *) pm_class_variable_and_write_node_create(parser, (pm_class_variable_read_node_t *) node, &token, value);
|
20737
20865
|
|
20738
20866
|
pm_node_destroy(parser, node);
|
@@ -20741,7 +20869,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
20741
20869
|
case PM_CONSTANT_PATH_NODE: {
|
20742
20870
|
parser_lex(parser);
|
20743
20871
|
|
20744
|
-
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
|
20872
|
+
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ, (uint16_t) (depth + 1));
|
20745
20873
|
pm_node_t *write = (pm_node_t *) pm_constant_path_and_write_node_create(parser, (pm_constant_path_node_t *) node, &token, value);
|
20746
20874
|
|
20747
20875
|
return parse_shareable_constant_write(parser, write);
|
@@ -20749,7 +20877,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
20749
20877
|
case PM_CONSTANT_READ_NODE: {
|
20750
20878
|
parser_lex(parser);
|
20751
20879
|
|
20752
|
-
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
|
20880
|
+
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ, (uint16_t) (depth + 1));
|
20753
20881
|
pm_node_t *write = (pm_node_t *) pm_constant_and_write_node_create(parser, (pm_constant_read_node_t *) node, &token, value);
|
20754
20882
|
|
20755
20883
|
pm_node_destroy(parser, node);
|
@@ -20758,7 +20886,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
20758
20886
|
case PM_INSTANCE_VARIABLE_READ_NODE: {
|
20759
20887
|
parser_lex(parser);
|
20760
20888
|
|
20761
|
-
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
|
20889
|
+
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ, (uint16_t) (depth + 1));
|
20762
20890
|
pm_node_t *result = (pm_node_t *) pm_instance_variable_and_write_node_create(parser, (pm_instance_variable_read_node_t *) node, &token, value);
|
20763
20891
|
|
20764
20892
|
pm_node_destroy(parser, node);
|
@@ -20768,7 +20896,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
20768
20896
|
pm_local_variable_read_node_t *cast = (pm_local_variable_read_node_t *) node;
|
20769
20897
|
parser_lex(parser);
|
20770
20898
|
|
20771
|
-
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
|
20899
|
+
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ, (uint16_t) (depth + 1));
|
20772
20900
|
pm_node_t *result = (pm_node_t *) pm_local_variable_and_write_node_create(parser, node, &token, value, cast->name, cast->depth);
|
20773
20901
|
|
20774
20902
|
pm_node_destroy(parser, node);
|
@@ -20787,7 +20915,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
20787
20915
|
pm_constant_id_t constant_id = pm_parser_local_add_location(parser, message_loc->start, message_loc->end, 1);
|
20788
20916
|
parser_lex(parser);
|
20789
20917
|
|
20790
|
-
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
|
20918
|
+
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ, (uint16_t) (depth + 1));
|
20791
20919
|
pm_node_t *result = (pm_node_t *) pm_local_variable_and_write_node_create(parser, (pm_node_t *) cast, &token, value, constant_id, 0);
|
20792
20920
|
|
20793
20921
|
pm_node_destroy(parser, (pm_node_t *) cast);
|
@@ -20802,7 +20930,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
20802
20930
|
// this is an aref expression, and we can transform it into
|
20803
20931
|
// an aset expression.
|
20804
20932
|
if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_INDEX)) {
|
20805
|
-
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
|
20933
|
+
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ, (uint16_t) (depth + 1));
|
20806
20934
|
return (pm_node_t *) pm_index_and_write_node_create(parser, cast, &token, value);
|
20807
20935
|
}
|
20808
20936
|
|
@@ -20814,7 +20942,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
20814
20942
|
}
|
20815
20943
|
|
20816
20944
|
parse_call_operator_write(parser, cast, &token);
|
20817
|
-
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
|
20945
|
+
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ, (uint16_t) (depth + 1));
|
20818
20946
|
return (pm_node_t *) pm_call_and_write_node_create(parser, cast, &token, value);
|
20819
20947
|
}
|
20820
20948
|
case PM_MULTI_WRITE_NODE: {
|
@@ -20841,7 +20969,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
20841
20969
|
case PM_GLOBAL_VARIABLE_READ_NODE: {
|
20842
20970
|
parser_lex(parser);
|
20843
20971
|
|
20844
|
-
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
|
20972
|
+
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ, (uint16_t) (depth + 1));
|
20845
20973
|
pm_node_t *result = (pm_node_t *) pm_global_variable_or_write_node_create(parser, node, &token, value);
|
20846
20974
|
|
20847
20975
|
pm_node_destroy(parser, node);
|
@@ -20850,7 +20978,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
20850
20978
|
case PM_CLASS_VARIABLE_READ_NODE: {
|
20851
20979
|
parser_lex(parser);
|
20852
20980
|
|
20853
|
-
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
|
20981
|
+
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ, (uint16_t) (depth + 1));
|
20854
20982
|
pm_node_t *result = (pm_node_t *) pm_class_variable_or_write_node_create(parser, (pm_class_variable_read_node_t *) node, &token, value);
|
20855
20983
|
|
20856
20984
|
pm_node_destroy(parser, node);
|
@@ -20859,7 +20987,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
20859
20987
|
case PM_CONSTANT_PATH_NODE: {
|
20860
20988
|
parser_lex(parser);
|
20861
20989
|
|
20862
|
-
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
|
20990
|
+
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ, (uint16_t) (depth + 1));
|
20863
20991
|
pm_node_t *write = (pm_node_t *) pm_constant_path_or_write_node_create(parser, (pm_constant_path_node_t *) node, &token, value);
|
20864
20992
|
|
20865
20993
|
return parse_shareable_constant_write(parser, write);
|
@@ -20867,7 +20995,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
20867
20995
|
case PM_CONSTANT_READ_NODE: {
|
20868
20996
|
parser_lex(parser);
|
20869
20997
|
|
20870
|
-
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
|
20998
|
+
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ, (uint16_t) (depth + 1));
|
20871
20999
|
pm_node_t *write = (pm_node_t *) pm_constant_or_write_node_create(parser, (pm_constant_read_node_t *) node, &token, value);
|
20872
21000
|
|
20873
21001
|
pm_node_destroy(parser, node);
|
@@ -20876,7 +21004,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
20876
21004
|
case PM_INSTANCE_VARIABLE_READ_NODE: {
|
20877
21005
|
parser_lex(parser);
|
20878
21006
|
|
20879
|
-
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
|
21007
|
+
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ, (uint16_t) (depth + 1));
|
20880
21008
|
pm_node_t *result = (pm_node_t *) pm_instance_variable_or_write_node_create(parser, (pm_instance_variable_read_node_t *) node, &token, value);
|
20881
21009
|
|
20882
21010
|
pm_node_destroy(parser, node);
|
@@ -20886,7 +21014,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
20886
21014
|
pm_local_variable_read_node_t *cast = (pm_local_variable_read_node_t *) node;
|
20887
21015
|
parser_lex(parser);
|
20888
21016
|
|
20889
|
-
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
|
21017
|
+
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ, (uint16_t) (depth + 1));
|
20890
21018
|
pm_node_t *result = (pm_node_t *) pm_local_variable_or_write_node_create(parser, node, &token, value, cast->name, cast->depth);
|
20891
21019
|
|
20892
21020
|
pm_node_destroy(parser, node);
|
@@ -20905,7 +21033,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
20905
21033
|
pm_constant_id_t constant_id = pm_parser_local_add_location(parser, message_loc->start, message_loc->end, 1);
|
20906
21034
|
parser_lex(parser);
|
20907
21035
|
|
20908
|
-
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
|
21036
|
+
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ, (uint16_t) (depth + 1));
|
20909
21037
|
pm_node_t *result = (pm_node_t *) pm_local_variable_or_write_node_create(parser, (pm_node_t *) cast, &token, value, constant_id, 0);
|
20910
21038
|
|
20911
21039
|
pm_node_destroy(parser, (pm_node_t *) cast);
|
@@ -20920,7 +21048,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
20920
21048
|
// this is an aref expression, and we can transform it into
|
20921
21049
|
// an aset expression.
|
20922
21050
|
if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_INDEX)) {
|
20923
|
-
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
|
21051
|
+
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ, (uint16_t) (depth + 1));
|
20924
21052
|
return (pm_node_t *) pm_index_or_write_node_create(parser, cast, &token, value);
|
20925
21053
|
}
|
20926
21054
|
|
@@ -20932,7 +21060,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
20932
21060
|
}
|
20933
21061
|
|
20934
21062
|
parse_call_operator_write(parser, cast, &token);
|
20935
|
-
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
|
21063
|
+
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ, (uint16_t) (depth + 1));
|
20936
21064
|
return (pm_node_t *) pm_call_or_write_node_create(parser, cast, &token, value);
|
20937
21065
|
}
|
20938
21066
|
case PM_MULTI_WRITE_NODE: {
|
@@ -20969,7 +21097,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
20969
21097
|
case PM_GLOBAL_VARIABLE_READ_NODE: {
|
20970
21098
|
parser_lex(parser);
|
20971
21099
|
|
20972
|
-
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
|
21100
|
+
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1));
|
20973
21101
|
pm_node_t *result = (pm_node_t *) pm_global_variable_operator_write_node_create(parser, node, &token, value);
|
20974
21102
|
|
20975
21103
|
pm_node_destroy(parser, node);
|
@@ -20978,7 +21106,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
20978
21106
|
case PM_CLASS_VARIABLE_READ_NODE: {
|
20979
21107
|
parser_lex(parser);
|
20980
21108
|
|
20981
|
-
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
|
21109
|
+
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1));
|
20982
21110
|
pm_node_t *result = (pm_node_t *) pm_class_variable_operator_write_node_create(parser, (pm_class_variable_read_node_t *) node, &token, value);
|
20983
21111
|
|
20984
21112
|
pm_node_destroy(parser, node);
|
@@ -20987,7 +21115,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
20987
21115
|
case PM_CONSTANT_PATH_NODE: {
|
20988
21116
|
parser_lex(parser);
|
20989
21117
|
|
20990
|
-
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
|
21118
|
+
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1));
|
20991
21119
|
pm_node_t *write = (pm_node_t *) pm_constant_path_operator_write_node_create(parser, (pm_constant_path_node_t *) node, &token, value);
|
20992
21120
|
|
20993
21121
|
return parse_shareable_constant_write(parser, write);
|
@@ -20995,7 +21123,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
20995
21123
|
case PM_CONSTANT_READ_NODE: {
|
20996
21124
|
parser_lex(parser);
|
20997
21125
|
|
20998
|
-
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
|
21126
|
+
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1));
|
20999
21127
|
pm_node_t *write = (pm_node_t *) pm_constant_operator_write_node_create(parser, (pm_constant_read_node_t *) node, &token, value);
|
21000
21128
|
|
21001
21129
|
pm_node_destroy(parser, node);
|
@@ -21004,7 +21132,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
21004
21132
|
case PM_INSTANCE_VARIABLE_READ_NODE: {
|
21005
21133
|
parser_lex(parser);
|
21006
21134
|
|
21007
|
-
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
|
21135
|
+
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1));
|
21008
21136
|
pm_node_t *result = (pm_node_t *) pm_instance_variable_operator_write_node_create(parser, (pm_instance_variable_read_node_t *) node, &token, value);
|
21009
21137
|
|
21010
21138
|
pm_node_destroy(parser, node);
|
@@ -21014,7 +21142,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
21014
21142
|
pm_local_variable_read_node_t *cast = (pm_local_variable_read_node_t *) node;
|
21015
21143
|
parser_lex(parser);
|
21016
21144
|
|
21017
|
-
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
|
21145
|
+
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1));
|
21018
21146
|
pm_node_t *result = (pm_node_t *) pm_local_variable_operator_write_node_create(parser, node, &token, value, cast->name, cast->depth);
|
21019
21147
|
|
21020
21148
|
pm_node_destroy(parser, node);
|
@@ -21032,7 +21160,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
21032
21160
|
pm_refute_numbered_parameter(parser, message_loc->start, message_loc->end);
|
21033
21161
|
|
21034
21162
|
pm_constant_id_t constant_id = pm_parser_local_add_location(parser, message_loc->start, message_loc->end, 1);
|
21035
|
-
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
|
21163
|
+
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1));
|
21036
21164
|
pm_node_t *result = (pm_node_t *) pm_local_variable_operator_write_node_create(parser, (pm_node_t *) cast, &token, value, constant_id, 0);
|
21037
21165
|
|
21038
21166
|
pm_node_destroy(parser, (pm_node_t *) cast);
|
@@ -21043,7 +21171,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
21043
21171
|
// this is an aref expression, and we can transform it into
|
21044
21172
|
// an aset expression.
|
21045
21173
|
if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_INDEX)) {
|
21046
|
-
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
|
21174
|
+
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1));
|
21047
21175
|
return (pm_node_t *) pm_index_operator_write_node_create(parser, cast, &token, value);
|
21048
21176
|
}
|
21049
21177
|
|
@@ -21055,7 +21183,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
21055
21183
|
}
|
21056
21184
|
|
21057
21185
|
parse_call_operator_write(parser, cast, &token);
|
21058
|
-
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
|
21186
|
+
pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1));
|
21059
21187
|
return (pm_node_t *) pm_call_operator_write_node_create(parser, cast, &token, value);
|
21060
21188
|
}
|
21061
21189
|
case PM_MULTI_WRITE_NODE: {
|
@@ -21077,14 +21205,14 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
21077
21205
|
case PM_TOKEN_KEYWORD_AND: {
|
21078
21206
|
parser_lex(parser);
|
21079
21207
|
|
21080
|
-
pm_node_t *right = parse_expression(parser, binding_power, parser->previous.type == PM_TOKEN_KEYWORD_AND, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
|
21208
|
+
pm_node_t *right = parse_expression(parser, binding_power, parser->previous.type == PM_TOKEN_KEYWORD_AND, false, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1));
|
21081
21209
|
return (pm_node_t *) pm_and_node_create(parser, node, &token, right);
|
21082
21210
|
}
|
21083
21211
|
case PM_TOKEN_KEYWORD_OR:
|
21084
21212
|
case PM_TOKEN_PIPE_PIPE: {
|
21085
21213
|
parser_lex(parser);
|
21086
21214
|
|
21087
|
-
pm_node_t *right = parse_expression(parser, binding_power, parser->previous.type == PM_TOKEN_KEYWORD_OR, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
|
21215
|
+
pm_node_t *right = parse_expression(parser, binding_power, parser->previous.type == PM_TOKEN_KEYWORD_OR, false, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1));
|
21088
21216
|
return (pm_node_t *) pm_or_node_create(parser, node, &token, right);
|
21089
21217
|
}
|
21090
21218
|
case PM_TOKEN_EQUAL_TILDE: {
|
@@ -21096,7 +21224,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
21096
21224
|
//
|
21097
21225
|
// In this case, `foo` should be a method call and not a local yet.
|
21098
21226
|
parser_lex(parser);
|
21099
|
-
pm_node_t *argument = parse_expression(parser, binding_power, false, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
|
21227
|
+
pm_node_t *argument = parse_expression(parser, binding_power, false, false, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1));
|
21100
21228
|
|
21101
21229
|
// By default, we're going to create a call node and then return it.
|
21102
21230
|
pm_call_node_t *call = pm_call_node_binary_create(parser, node, &token, argument, 0);
|
@@ -21175,7 +21303,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
21175
21303
|
case PM_TOKEN_STAR:
|
21176
21304
|
case PM_TOKEN_STAR_STAR: {
|
21177
21305
|
parser_lex(parser);
|
21178
|
-
pm_node_t *argument = parse_expression(parser, binding_power, false, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
|
21306
|
+
pm_node_t *argument = parse_expression(parser, binding_power, false, false, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1));
|
21179
21307
|
return (pm_node_t *) pm_call_node_binary_create(parser, node, &token, argument, 0);
|
21180
21308
|
}
|
21181
21309
|
case PM_TOKEN_GREATER:
|
@@ -21187,7 +21315,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
21187
21315
|
}
|
21188
21316
|
|
21189
21317
|
parser_lex(parser);
|
21190
|
-
pm_node_t *argument = parse_expression(parser, binding_power, false, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
|
21318
|
+
pm_node_t *argument = parse_expression(parser, binding_power, false, false, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1));
|
21191
21319
|
return (pm_node_t *) pm_call_node_binary_create(parser, node, &token, argument, PM_CALL_NODE_FLAGS_COMPARISON);
|
21192
21320
|
}
|
21193
21321
|
case PM_TOKEN_AMPERSAND_DOT:
|
@@ -21198,7 +21326,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
21198
21326
|
|
21199
21327
|
// This if statement handles the foo.() syntax.
|
21200
21328
|
if (match1(parser, PM_TOKEN_PARENTHESIS_LEFT)) {
|
21201
|
-
parse_arguments_list(parser, &arguments, true, false);
|
21329
|
+
parse_arguments_list(parser, &arguments, true, false, (uint16_t) (depth + 1));
|
21202
21330
|
return (pm_node_t *) pm_call_node_shorthand_create(parser, node, &operator, &arguments);
|
21203
21331
|
}
|
21204
21332
|
|
@@ -21220,7 +21348,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
21220
21348
|
}
|
21221
21349
|
}
|
21222
21350
|
|
21223
|
-
parse_arguments_list(parser, &arguments, true, accepts_command_call);
|
21351
|
+
parse_arguments_list(parser, &arguments, true, accepts_command_call, (uint16_t) (depth + 1));
|
21224
21352
|
pm_call_node_t *call = pm_call_node_call_create(parser, node, &operator, &message, &arguments);
|
21225
21353
|
|
21226
21354
|
if (
|
@@ -21229,7 +21357,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
21229
21357
|
arguments.opening_loc.start == NULL &&
|
21230
21358
|
match1(parser, PM_TOKEN_COMMA)
|
21231
21359
|
) {
|
21232
|
-
return parse_targets_validate(parser, (pm_node_t *) call, PM_BINDING_POWER_INDEX);
|
21360
|
+
return parse_targets_validate(parser, (pm_node_t *) call, PM_BINDING_POWER_INDEX, (uint16_t) (depth + 1));
|
21233
21361
|
} else {
|
21234
21362
|
return (pm_node_t *) call;
|
21235
21363
|
}
|
@@ -21240,7 +21368,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
21240
21368
|
|
21241
21369
|
pm_node_t *right = NULL;
|
21242
21370
|
if (token_begins_expression_p(parser->current.type)) {
|
21243
|
-
right = parse_expression(parser, binding_power, false, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
|
21371
|
+
right = parse_expression(parser, binding_power, false, false, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1));
|
21244
21372
|
}
|
21245
21373
|
|
21246
21374
|
return (pm_node_t *) pm_range_node_create(parser, node, &token, right);
|
@@ -21249,14 +21377,14 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
21249
21377
|
pm_token_t keyword = parser->current;
|
21250
21378
|
parser_lex(parser);
|
21251
21379
|
|
21252
|
-
pm_node_t *predicate = parse_value_expression(parser, binding_power, true, PM_ERR_CONDITIONAL_IF_PREDICATE);
|
21380
|
+
pm_node_t *predicate = parse_value_expression(parser, binding_power, true, false, PM_ERR_CONDITIONAL_IF_PREDICATE, (uint16_t) (depth + 1));
|
21253
21381
|
return (pm_node_t *) pm_if_node_modifier_create(parser, node, &keyword, predicate);
|
21254
21382
|
}
|
21255
21383
|
case PM_TOKEN_KEYWORD_UNLESS_MODIFIER: {
|
21256
21384
|
pm_token_t keyword = parser->current;
|
21257
21385
|
parser_lex(parser);
|
21258
21386
|
|
21259
|
-
pm_node_t *predicate = parse_value_expression(parser, binding_power, true, PM_ERR_CONDITIONAL_UNLESS_PREDICATE);
|
21387
|
+
pm_node_t *predicate = parse_value_expression(parser, binding_power, true, false, PM_ERR_CONDITIONAL_UNLESS_PREDICATE, (uint16_t) (depth + 1));
|
21260
21388
|
return (pm_node_t *) pm_unless_node_modifier_create(parser, node, &keyword, predicate);
|
21261
21389
|
}
|
21262
21390
|
case PM_TOKEN_KEYWORD_UNTIL_MODIFIER: {
|
@@ -21264,7 +21392,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
21264
21392
|
pm_statements_node_t *statements = pm_statements_node_create(parser);
|
21265
21393
|
pm_statements_node_body_append(parser, statements, node, true);
|
21266
21394
|
|
21267
|
-
pm_node_t *predicate = parse_value_expression(parser, binding_power, true, PM_ERR_CONDITIONAL_UNTIL_PREDICATE);
|
21395
|
+
pm_node_t *predicate = parse_value_expression(parser, binding_power, true, false, PM_ERR_CONDITIONAL_UNTIL_PREDICATE, (uint16_t) (depth + 1));
|
21268
21396
|
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);
|
21269
21397
|
}
|
21270
21398
|
case PM_TOKEN_KEYWORD_WHILE_MODIFIER: {
|
@@ -21272,7 +21400,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
21272
21400
|
pm_statements_node_t *statements = pm_statements_node_create(parser);
|
21273
21401
|
pm_statements_node_body_append(parser, statements, node, true);
|
21274
21402
|
|
21275
|
-
pm_node_t *predicate = parse_value_expression(parser, binding_power, true, PM_ERR_CONDITIONAL_WHILE_PREDICATE);
|
21403
|
+
pm_node_t *predicate = parse_value_expression(parser, binding_power, true, false, PM_ERR_CONDITIONAL_WHILE_PREDICATE, (uint16_t) (depth + 1));
|
21276
21404
|
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);
|
21277
21405
|
}
|
21278
21406
|
case PM_TOKEN_QUESTION_MARK: {
|
@@ -21283,7 +21411,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
21283
21411
|
pm_token_t qmark = parser->current;
|
21284
21412
|
parser_lex(parser);
|
21285
21413
|
|
21286
|
-
pm_node_t *true_expression = parse_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_TERNARY_EXPRESSION_TRUE);
|
21414
|
+
pm_node_t *true_expression = parse_expression(parser, PM_BINDING_POWER_DEFINED, false, false, PM_ERR_TERNARY_EXPRESSION_TRUE, (uint16_t) (depth + 1));
|
21287
21415
|
|
21288
21416
|
if (parser->recovering) {
|
21289
21417
|
// If parsing the true expression of this ternary resulted in a syntax
|
@@ -21306,7 +21434,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
21306
21434
|
expect1(parser, PM_TOKEN_COLON, PM_ERR_TERNARY_COLON);
|
21307
21435
|
|
21308
21436
|
pm_token_t colon = parser->previous;
|
21309
|
-
pm_node_t *false_expression = parse_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_TERNARY_EXPRESSION_FALSE);
|
21437
|
+
pm_node_t *false_expression = parse_expression(parser, PM_BINDING_POWER_DEFINED, false, false, PM_ERR_TERNARY_EXPRESSION_FALSE, (uint16_t) (depth + 1));
|
21310
21438
|
|
21311
21439
|
context_pop(parser);
|
21312
21440
|
pop_block_exits(parser, previous_block_exits);
|
@@ -21336,7 +21464,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
21336
21464
|
pm_token_t message = parser->previous;
|
21337
21465
|
pm_arguments_t arguments = { 0 };
|
21338
21466
|
|
21339
|
-
parse_arguments_list(parser, &arguments, true, accepts_command_call);
|
21467
|
+
parse_arguments_list(parser, &arguments, true, accepts_command_call, (uint16_t) (depth + 1));
|
21340
21468
|
path = (pm_node_t *) pm_call_node_call_create(parser, node, &delimiter, &message, &arguments);
|
21341
21469
|
} else {
|
21342
21470
|
// Otherwise, this is a constant path. That would look like Foo::Bar.
|
@@ -21345,7 +21473,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
21345
21473
|
|
21346
21474
|
// If this is followed by a comma then it is a multiple assignment.
|
21347
21475
|
if (previous_binding_power == PM_BINDING_POWER_STATEMENT && match1(parser, PM_TOKEN_COMMA)) {
|
21348
|
-
return parse_targets_validate(parser, path, PM_BINDING_POWER_INDEX);
|
21476
|
+
return parse_targets_validate(parser, path, PM_BINDING_POWER_INDEX, (uint16_t) (depth + 1));
|
21349
21477
|
}
|
21350
21478
|
|
21351
21479
|
return path;
|
@@ -21360,12 +21488,12 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
21360
21488
|
// If we have an identifier following a '::' operator, then it is for
|
21361
21489
|
// sure a method call.
|
21362
21490
|
pm_arguments_t arguments = { 0 };
|
21363
|
-
parse_arguments_list(parser, &arguments, true, accepts_command_call);
|
21491
|
+
parse_arguments_list(parser, &arguments, true, accepts_command_call, (uint16_t) (depth + 1));
|
21364
21492
|
pm_call_node_t *call = pm_call_node_call_create(parser, node, &delimiter, &message, &arguments);
|
21365
21493
|
|
21366
21494
|
// If this is followed by a comma then it is a multiple assignment.
|
21367
21495
|
if (previous_binding_power == PM_BINDING_POWER_STATEMENT && match1(parser, PM_TOKEN_COMMA)) {
|
21368
|
-
return parse_targets_validate(parser, (pm_node_t *) call, PM_BINDING_POWER_INDEX);
|
21496
|
+
return parse_targets_validate(parser, (pm_node_t *) call, PM_BINDING_POWER_INDEX, (uint16_t) (depth + 1));
|
21369
21497
|
}
|
21370
21498
|
|
21371
21499
|
return (pm_node_t *) call;
|
@@ -21374,7 +21502,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
21374
21502
|
// If we have a parenthesis following a '::' operator, then it is the
|
21375
21503
|
// method call shorthand. That would look like Foo::(bar).
|
21376
21504
|
pm_arguments_t arguments = { 0 };
|
21377
|
-
parse_arguments_list(parser, &arguments, true, false);
|
21505
|
+
parse_arguments_list(parser, &arguments, true, false, (uint16_t) (depth + 1));
|
21378
21506
|
|
21379
21507
|
return (pm_node_t *) pm_call_node_shorthand_create(parser, node, &delimiter, &arguments);
|
21380
21508
|
}
|
@@ -21389,7 +21517,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
21389
21517
|
parser_lex(parser);
|
21390
21518
|
accept1(parser, PM_TOKEN_NEWLINE);
|
21391
21519
|
|
21392
|
-
pm_node_t *value = parse_expression(parser, binding_power, true, PM_ERR_RESCUE_MODIFIER_VALUE);
|
21520
|
+
pm_node_t *value = parse_expression(parser, binding_power, true, false, PM_ERR_RESCUE_MODIFIER_VALUE, (uint16_t) (depth + 1));
|
21393
21521
|
context_pop(parser);
|
21394
21522
|
|
21395
21523
|
return (pm_node_t *) pm_rescue_modifier_node_create(parser, node, &token, value);
|
@@ -21402,7 +21530,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
21402
21530
|
|
21403
21531
|
if (!accept1(parser, PM_TOKEN_BRACKET_RIGHT)) {
|
21404
21532
|
pm_accepts_block_stack_push(parser, true);
|
21405
|
-
parse_arguments(parser, &arguments, false, PM_TOKEN_BRACKET_RIGHT);
|
21533
|
+
parse_arguments(parser, &arguments, false, PM_TOKEN_BRACKET_RIGHT, (uint16_t) (depth + 1));
|
21406
21534
|
pm_accepts_block_stack_pop(parser);
|
21407
21535
|
expect1(parser, PM_TOKEN_BRACKET_RIGHT, PM_ERR_EXPECT_RBRACKET);
|
21408
21536
|
}
|
@@ -21413,7 +21541,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
21413
21541
|
// assignment and we should parse the targets.
|
21414
21542
|
if (previous_binding_power == PM_BINDING_POWER_STATEMENT && match1(parser, PM_TOKEN_COMMA)) {
|
21415
21543
|
pm_call_node_t *aref = pm_call_node_aref_create(parser, node, &arguments);
|
21416
|
-
return parse_targets_validate(parser, (pm_node_t *) aref, PM_BINDING_POWER_INDEX);
|
21544
|
+
return parse_targets_validate(parser, (pm_node_t *) aref, PM_BINDING_POWER_INDEX, (uint16_t) (depth + 1));
|
21417
21545
|
}
|
21418
21546
|
|
21419
21547
|
// If we're at the end of the arguments, we can now check if there is a
|
@@ -21421,10 +21549,10 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
21421
21549
|
// add it to the arguments.
|
21422
21550
|
pm_block_node_t *block = NULL;
|
21423
21551
|
if (accept1(parser, PM_TOKEN_BRACE_LEFT)) {
|
21424
|
-
block = parse_block(parser);
|
21552
|
+
block = parse_block(parser, (uint16_t) (depth + 1));
|
21425
21553
|
pm_arguments_validate_block(parser, &arguments, block);
|
21426
21554
|
} else if (pm_accepts_block_stack_p(parser) && accept1(parser, PM_TOKEN_KEYWORD_DO)) {
|
21427
|
-
block = parse_block(parser);
|
21555
|
+
block = parse_block(parser, (uint16_t) (depth + 1));
|
21428
21556
|
}
|
21429
21557
|
|
21430
21558
|
if (block != NULL) {
|
@@ -21451,7 +21579,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
21451
21579
|
parser_lex(parser);
|
21452
21580
|
|
21453
21581
|
pm_constant_id_list_t captures = { 0 };
|
21454
|
-
pm_node_t *pattern = parse_pattern(parser, &captures, PM_PARSE_PATTERN_TOP | PM_PARSE_PATTERN_MULTI, PM_ERR_PATTERN_EXPRESSION_AFTER_IN);
|
21582
|
+
pm_node_t *pattern = parse_pattern(parser, &captures, PM_PARSE_PATTERN_TOP | PM_PARSE_PATTERN_MULTI, PM_ERR_PATTERN_EXPRESSION_AFTER_IN, (uint16_t) (depth + 1));
|
21455
21583
|
|
21456
21584
|
parser->pattern_matching_newlines = previous_pattern_matching_newlines;
|
21457
21585
|
pm_constant_id_list_free(&captures);
|
@@ -21468,7 +21596,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
21468
21596
|
parser_lex(parser);
|
21469
21597
|
|
21470
21598
|
pm_constant_id_list_t captures = { 0 };
|
21471
|
-
pm_node_t *pattern = parse_pattern(parser, &captures, PM_PARSE_PATTERN_TOP | PM_PARSE_PATTERN_MULTI, PM_ERR_PATTERN_EXPRESSION_AFTER_HROCKET);
|
21599
|
+
pm_node_t *pattern = parse_pattern(parser, &captures, PM_PARSE_PATTERN_TOP | PM_PARSE_PATTERN_MULTI, PM_ERR_PATTERN_EXPRESSION_AFTER_HROCKET, (uint16_t) (depth + 1));
|
21472
21600
|
|
21473
21601
|
parser->pattern_matching_newlines = previous_pattern_matching_newlines;
|
21474
21602
|
pm_constant_id_list_free(&captures);
|
@@ -21485,6 +21613,19 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
21485
21613
|
#undef PM_PARSE_PATTERN_TOP
|
21486
21614
|
#undef PM_PARSE_PATTERN_MULTI
|
21487
21615
|
|
21616
|
+
/**
|
21617
|
+
* Determine if a given call node looks like a "command", which means it has
|
21618
|
+
* arguments but does not have parentheses.
|
21619
|
+
*/
|
21620
|
+
static inline bool
|
21621
|
+
pm_call_node_command_p(const pm_call_node_t *node) {
|
21622
|
+
return (
|
21623
|
+
(node->opening_loc.start == NULL) &&
|
21624
|
+
(node->block == NULL || PM_NODE_TYPE_P(node->block, PM_BLOCK_ARGUMENT_NODE)) &&
|
21625
|
+
(node->arguments != NULL || node->block != NULL)
|
21626
|
+
);
|
21627
|
+
}
|
21628
|
+
|
21488
21629
|
/**
|
21489
21630
|
* Parse an expression at the given point of the parser using the given binding
|
21490
21631
|
* power to parse subsequent chains. If this function finds a syntax error, it
|
@@ -21494,8 +21635,13 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
|
|
21494
21635
|
* determine if they need to perform additional cleanup.
|
21495
21636
|
*/
|
21496
21637
|
static pm_node_t *
|
21497
|
-
parse_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool accepts_command_call, pm_diagnostic_id_t diag_id) {
|
21498
|
-
|
21638
|
+
parse_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool accepts_command_call, bool accepts_label, pm_diagnostic_id_t diag_id, uint16_t depth) {
|
21639
|
+
if (PRISM_UNLIKELY(depth >= PRISM_DEPTH_MAXIMUM)) {
|
21640
|
+
pm_parser_err_current(parser, PM_ERR_NESTING_TOO_DEEP);
|
21641
|
+
return (pm_node_t *) pm_missing_node_create(parser, parser->current.start, parser->current.end);
|
21642
|
+
}
|
21643
|
+
|
21644
|
+
pm_node_t *node = parse_expression_prefix(parser, binding_power, accepts_command_call, accepts_label, diag_id, depth);
|
21499
21645
|
|
21500
21646
|
switch (PM_NODE_TYPE(node)) {
|
21501
21647
|
case PM_MISSING_NODE:
|
@@ -21514,6 +21660,23 @@ parse_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool acc
|
|
21514
21660
|
return node;
|
21515
21661
|
}
|
21516
21662
|
break;
|
21663
|
+
case PM_CALL_NODE:
|
21664
|
+
// If we have a call node, then we need to check if it looks like a
|
21665
|
+
// method call without parentheses that contains arguments. If it
|
21666
|
+
// does, then it has different rules for parsing infix operators,
|
21667
|
+
// namely that it only accepts composition (and/or) and modifiers
|
21668
|
+
// (if/unless/etc.).
|
21669
|
+
if ((pm_binding_powers[parser->current.type].left > PM_BINDING_POWER_COMPOSITION) && pm_call_node_command_p((pm_call_node_t *) node)) {
|
21670
|
+
return node;
|
21671
|
+
}
|
21672
|
+
break;
|
21673
|
+
case PM_SYMBOL_NODE:
|
21674
|
+
// If we have a symbol node that is being parsed as a label, then we
|
21675
|
+
// need to immediately return, because there should never be an
|
21676
|
+
// infix operator following this node.
|
21677
|
+
if (pm_symbol_node_label_p(node)) {
|
21678
|
+
return node;
|
21679
|
+
}
|
21517
21680
|
default:
|
21518
21681
|
break;
|
21519
21682
|
}
|
@@ -21526,9 +21689,16 @@ parse_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool acc
|
|
21526
21689
|
binding_power <= current_binding_powers.left &&
|
21527
21690
|
current_binding_powers.binary
|
21528
21691
|
) {
|
21529
|
-
node = parse_expression_infix(parser, node, binding_power, current_binding_powers.right, accepts_command_call);
|
21692
|
+
node = parse_expression_infix(parser, node, binding_power, current_binding_powers.right, accepts_command_call, (uint16_t) (depth + 1));
|
21530
21693
|
|
21531
21694
|
switch (PM_NODE_TYPE(node)) {
|
21695
|
+
case PM_MULTI_WRITE_NODE:
|
21696
|
+
// Multi-write nodes are statements, and cannot be followed by
|
21697
|
+
// operators except modifiers.
|
21698
|
+
if (pm_binding_powers[parser->current.type].left > PM_BINDING_POWER_MODIFIER) {
|
21699
|
+
return node;
|
21700
|
+
}
|
21701
|
+
break;
|
21532
21702
|
case PM_CLASS_VARIABLE_WRITE_NODE:
|
21533
21703
|
case PM_CONSTANT_PATH_WRITE_NODE:
|
21534
21704
|
case PM_CONSTANT_WRITE_NODE:
|
@@ -21553,16 +21723,26 @@ parse_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool acc
|
|
21553
21723
|
break;
|
21554
21724
|
}
|
21555
21725
|
|
21726
|
+
// If the operator is nonassoc and we should not be able to parse the
|
21727
|
+
// upcoming infix operator, break.
|
21556
21728
|
if (current_binding_powers.nonassoc) {
|
21557
|
-
|
21558
|
-
|
21559
|
-
|
21560
|
-
|
21561
|
-
|
21562
|
-
|
21563
|
-
|
21564
|
-
|
21565
|
-
|
21729
|
+
// If this is an endless range, then we need to reject a couple of
|
21730
|
+
// additional operators because it violates the normal operator
|
21731
|
+
// precedence rules. Those patterns are:
|
21732
|
+
//
|
21733
|
+
// 1.. & 2
|
21734
|
+
// 1.. * 2
|
21735
|
+
//
|
21736
|
+
if (PM_NODE_TYPE_P(node, PM_RANGE_NODE) && ((pm_range_node_t *) node)->right == NULL) {
|
21737
|
+
if (match4(parser, PM_TOKEN_UAMPERSAND, PM_TOKEN_USTAR, PM_TOKEN_DOT, PM_TOKEN_AMPERSAND_DOT)) {
|
21738
|
+
PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_NON_ASSOCIATIVE_OPERATOR, pm_token_type_human(parser->current.type), pm_token_type_human(parser->previous.type));
|
21739
|
+
break;
|
21740
|
+
}
|
21741
|
+
|
21742
|
+
if (PM_BINDING_POWER_TERM <= pm_binding_powers[parser->current.type].left) {
|
21743
|
+
break;
|
21744
|
+
}
|
21745
|
+
} else if (current_binding_powers.left <= pm_binding_powers[parser->current.type].left) {
|
21566
21746
|
break;
|
21567
21747
|
}
|
21568
21748
|
}
|
@@ -21708,7 +21888,7 @@ parse_program(pm_parser_t *parser) {
|
|
21708
21888
|
pm_node_list_t *previous_block_exits = push_block_exits(parser, ¤t_block_exits);
|
21709
21889
|
|
21710
21890
|
parser_lex(parser);
|
21711
|
-
pm_statements_node_t *statements = parse_statements(parser, PM_CONTEXT_MAIN);
|
21891
|
+
pm_statements_node_t *statements = parse_statements(parser, PM_CONTEXT_MAIN, 0);
|
21712
21892
|
|
21713
21893
|
if (statements == NULL) {
|
21714
21894
|
statements = pm_statements_node_create(parser);
|
@@ -21767,6 +21947,9 @@ pm_strnstr(const char *big, const char *little, size_t big_length) {
|
|
21767
21947
|
return NULL;
|
21768
21948
|
}
|
21769
21949
|
|
21950
|
+
#ifdef _WIN32
|
21951
|
+
#define pm_parser_warn_shebang_carriage_return(parser, start, length) ((void) 0)
|
21952
|
+
#else
|
21770
21953
|
/**
|
21771
21954
|
* Potentially warn the user if the shebang that has been found to include
|
21772
21955
|
* "ruby" has a carriage return at the end, as that can cause problems on some
|
@@ -21778,6 +21961,7 @@ pm_parser_warn_shebang_carriage_return(pm_parser_t *parser, const uint8_t *start
|
|
21778
21961
|
pm_parser_warn(parser, start, start + length, PM_WARN_SHEBANG_CARRIAGE_RETURN);
|
21779
21962
|
}
|
21780
21963
|
}
|
21964
|
+
#endif
|
21781
21965
|
|
21782
21966
|
/**
|
21783
21967
|
* Process the shebang when initializing the parser. This function assumes that
|
@@ -21852,6 +22036,7 @@ pm_parser_init(pm_parser_t *parser, const uint8_t *source, size_t size, const pm
|
|
21852
22036
|
.explicit_encoding = NULL,
|
21853
22037
|
.command_line = 0,
|
21854
22038
|
.parsing_eval = false,
|
22039
|
+
.partial_script = false,
|
21855
22040
|
.command_start = true,
|
21856
22041
|
.recovering = false,
|
21857
22042
|
.encoding_locked = false,
|
@@ -21915,8 +22100,12 @@ pm_parser_init(pm_parser_t *parser, const uint8_t *source, size_t size, const pm
|
|
21915
22100
|
// version option
|
21916
22101
|
parser->version = options->version;
|
21917
22102
|
|
22103
|
+
// partial_script
|
22104
|
+
parser->partial_script = options->partial_script;
|
22105
|
+
|
21918
22106
|
// scopes option
|
21919
22107
|
parser->parsing_eval = options->scopes_count > 0;
|
22108
|
+
if (parser->parsing_eval) parser->warn_mismatched_indentation = false;
|
21920
22109
|
|
21921
22110
|
for (size_t scope_index = 0; scope_index < options->scopes_count; scope_index++) {
|
21922
22111
|
const pm_options_scope_t *scope = pm_options_scope_get(options, scope_index);
|
@@ -21959,27 +22148,42 @@ pm_parser_init(pm_parser_t *parser, const uint8_t *source, size_t size, const pm
|
|
21959
22148
|
// "ruby" and start parsing from there.
|
21960
22149
|
bool search_shebang = PM_PARSER_COMMAND_LINE_OPTION_X(parser);
|
21961
22150
|
|
21962
|
-
// If the first two bytes of the source are a shebang, then we
|
21963
|
-
//
|
22151
|
+
// If the first two bytes of the source are a shebang, then we will do a bit
|
22152
|
+
// of extra processing.
|
22153
|
+
//
|
22154
|
+
// First, we'll indicate that the encoding comment is at the end of the
|
22155
|
+
// shebang. This means that when a shebang is present the encoding comment
|
22156
|
+
// can begin on the second line.
|
22157
|
+
//
|
22158
|
+
// Second, we will check if the shebang includes "ruby". If it does, then we
|
22159
|
+
// we will start parsing from there. We will also potentially warning the
|
22160
|
+
// user if there is a carriage return at the end of the shebang. We will
|
22161
|
+
// also potentially call the shebang callback if this is the main script to
|
22162
|
+
// allow the caller to parse the shebang and find any command-line options.
|
22163
|
+
// If the shebang does not include "ruby" and this is the main script being
|
22164
|
+
// parsed, then we will start searching the file for a shebang that does
|
22165
|
+
// contain "ruby" as if -x were passed on the command line.
|
21964
22166
|
const uint8_t *newline = next_newline(parser->start, parser->end - parser->start);
|
21965
22167
|
size_t length = (size_t) ((newline != NULL ? newline : parser->end) - parser->start);
|
21966
22168
|
|
21967
22169
|
if (length > 2 && parser->current.end[0] == '#' && parser->current.end[1] == '!') {
|
21968
22170
|
const char *engine;
|
22171
|
+
|
21969
22172
|
if ((engine = pm_strnstr((const char *) parser->start, "ruby", length)) != NULL) {
|
21970
22173
|
if (newline != NULL) {
|
21971
|
-
size_t length_including_newline = length + 1;
|
21972
|
-
pm_parser_warn_shebang_carriage_return(parser, parser->start, length_including_newline);
|
21973
|
-
|
21974
22174
|
parser->encoding_comment_start = newline + 1;
|
22175
|
+
|
22176
|
+
if (options == NULL || options->main_script) {
|
22177
|
+
pm_parser_warn_shebang_carriage_return(parser, parser->start, length + 1);
|
22178
|
+
}
|
21975
22179
|
}
|
21976
22180
|
|
21977
|
-
if (options != NULL && options->shebang_callback != NULL) {
|
22181
|
+
if (options != NULL && options->main_script && options->shebang_callback != NULL) {
|
21978
22182
|
pm_parser_init_shebang(parser, options, engine, length - ((size_t) (engine - (const char *) parser->start)));
|
21979
22183
|
}
|
21980
22184
|
|
21981
22185
|
search_shebang = false;
|
21982
|
-
} else if (!parser->parsing_eval) {
|
22186
|
+
} else if (options->main_script && !parser->parsing_eval) {
|
21983
22187
|
search_shebang = true;
|
21984
22188
|
}
|
21985
22189
|
}
|
@@ -22010,10 +22214,9 @@ pm_parser_init(pm_parser_t *parser, const uint8_t *source, size_t size, const pm
|
|
22010
22214
|
const char *engine;
|
22011
22215
|
if ((engine = pm_strnstr((const char *) cursor, "ruby", length)) != NULL) {
|
22012
22216
|
found_shebang = true;
|
22013
|
-
if (newline != NULL) {
|
22014
|
-
size_t length_including_newline = length + 1;
|
22015
|
-
pm_parser_warn_shebang_carriage_return(parser, cursor, length_including_newline);
|
22016
22217
|
|
22218
|
+
if (newline != NULL) {
|
22219
|
+
pm_parser_warn_shebang_carriage_return(parser, cursor, length + 1);
|
22017
22220
|
parser->encoding_comment_start = newline + 1;
|
22018
22221
|
}
|
22019
22222
|
|