@@ -5932,6 +5932,33 @@ pm_parser_scope_push(pm_parser_t *parser, bool closed) {
5932
5932
return true;
5933
5933
}
5934
5934
5935
+ /**
5936
+ * Save the current param name as the return value and set it to the given
5937
+ * constant id.
5938
+ */
5939
+ static inline pm_constant_id_t
5940
+ pm_parser_current_param_name_set(pm_parser_t *parser, pm_constant_id_t current_param_name) {
5941
+ pm_constant_id_t saved_param_name = parser->current_param_name;
5942
+ parser->current_param_name = current_param_name;
5943
+ return saved_param_name;
5944
+ }
5945
+
5946
+ /**
5947
+ * Save the current param name as the return value and clear it.
5948
+ */
5949
+ static inline pm_constant_id_t
5950
+ pm_parser_current_param_name_unset(pm_parser_t *parser) {
5951
+ return pm_parser_current_param_name_set(parser, PM_CONSTANT_ID_UNSET);
5952
+ }
5953
+
5954
+ /**
5955
+ * Restore the current param name from the given value.
5956
+ */
5957
+ static inline void
5958
+ pm_parser_current_param_name_restore(pm_parser_t *parser, pm_constant_id_t saved_param_name) {
5959
+ parser->current_param_name = saved_param_name;
5960
+ }
5961
+
5935
5962
/**
5936
5963
* Check if any of the currently visible scopes contain a local variable
5937
5964
* described by the given constant id.
@@ -11715,8 +11742,8 @@ parse_parameters(
11715
11742
if (accept1(parser, PM_TOKEN_EQUAL)) {
11716
11743
pm_token_t operator = parser->previous;
11717
11744
context_push(parser, PM_CONTEXT_DEFAULT_PARAMS);
11718
- pm_constant_id_t old_param_name = parser->current_param_name;
11719
- parser->current_param_name = pm_parser_constant_id_token(parser, &name);
11745
+
11746
+ pm_constant_id_t saved_param_name = pm_parser_current_param_name_set(parser, pm_parser_constant_id_token(parser, &name) );
11720
11747
pm_node_t *value = parse_value_expression(parser, binding_power, false, PM_ERR_PARAMETER_NO_DEFAULT);
11721
11748
11722
11749
pm_optional_parameter_node_t *param = pm_optional_parameter_node_create(parser, &name, &operator, value);
@@ -11725,7 +11752,7 @@ parse_parameters(
11725
11752
}
11726
11753
pm_parameters_node_optionals_append(params, param);
11727
11754
11728
- parser->current_param_name = old_param_name ;
11755
+ pm_parser_current_param_name_restore( parser, saved_param_name) ;
11729
11756
context_pop(parser);
11730
11757
11731
11758
// If parsing the value of the parameter resulted in error recovery,
@@ -11793,11 +11820,13 @@ parse_parameters(
11793
11820
11794
11821
if (token_begins_expression_p(parser->current.type)) {
11795
11822
context_push(parser, PM_CONTEXT_DEFAULT_PARAMS);
11796
- pm_constant_id_t old_param_name = parser->current_param_name;
11797
- parser->current_param_name = pm_parser_constant_id_token(parser, &local);
11823
+
11824
+ pm_constant_id_t saved_param_name = pm_parser_current_param_name_set(parser, pm_parser_constant_id_token(parser, &local) );
11798
11825
pm_node_t *value = parse_value_expression(parser, binding_power, false, PM_ERR_PARAMETER_NO_DEFAULT_KW);
11799
- parser->current_param_name = old_param_name;
11826
+
11827
+ pm_parser_current_param_name_restore(parser, saved_param_name);
11800
11828
context_pop(parser);
11829
+
11801
11830
param = (pm_node_t *) pm_optional_keyword_parameter_node_create(parser, &name, value);
11802
11831
}
11803
11832
else {
@@ -12142,8 +12171,10 @@ parse_block(pm_parser_t *parser) {
12142
12171
pm_token_t opening = parser->previous;
12143
12172
accept1(parser, PM_TOKEN_NEWLINE);
12144
12173
12174
+ pm_constant_id_t saved_param_name = pm_parser_current_param_name_unset(parser);
12145
12175
pm_accepts_block_stack_push(parser, true);
12146
12176
pm_parser_scope_push(parser, false);
12177
+
12147
12178
pm_block_parameters_node_t *block_parameters = NULL;
12148
12179
12149
12180
if (accept1(parser, PM_TOKEN_PIPE)) {
@@ -12207,6 +12238,8 @@ parse_block(pm_parser_t *parser) {
12207
12238
pm_constant_id_list_t locals = parser->current_scope->locals;
12208
12239
pm_parser_scope_pop(parser);
12209
12240
pm_accepts_block_stack_pop(parser);
12241
+ pm_parser_current_param_name_restore(parser, saved_param_name);
12242
+
12210
12243
return pm_block_node_create(parser, &locals, locals_body_index, &opening, parameters, statements, &parser->previous);
12211
12244
}
12212
12245
@@ -14910,8 +14943,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
14910
14943
pm_token_t operator = parser->previous;
14911
14944
pm_node_t *expression = parse_value_expression(parser, PM_BINDING_POWER_NOT, true, PM_ERR_EXPECT_EXPRESSION_AFTER_LESS_LESS);
14912
14945
14913
- pm_constant_id_t old_param_name = parser->current_param_name;
14914
- parser->current_param_name = 0;
14946
+ pm_constant_id_t saved_param_name = pm_parser_current_param_name_unset(parser);
14915
14947
pm_parser_scope_push(parser, true);
14916
14948
accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON);
14917
14949
@@ -14928,11 +14960,12 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
14928
14960
}
14929
14961
14930
14962
expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CLASS_TERM);
14931
-
14932
14963
pm_constant_id_list_t locals = parser->current_scope->locals;
14964
+
14933
14965
pm_parser_scope_pop(parser);
14934
- parser->current_param_name = old_param_name;
14935
14966
pm_do_loop_stack_pop(parser);
14967
+ pm_parser_current_param_name_restore(parser, saved_param_name);
14968
+
14936
14969
return (pm_node_t *) pm_singleton_class_node_create(parser, &locals, &class_keyword, &operator, expression, statements, &parser->previous);
14937
14970
}
14938
14971
@@ -14958,9 +14991,9 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
14958
14991
superclass = NULL;
14959
14992
}
14960
14993
14961
- pm_constant_id_t old_param_name = parser->current_param_name;
14962
- parser->current_param_name = 0;
14994
+ pm_constant_id_t saved_param_name = pm_parser_current_param_name_unset(parser);
14963
14995
pm_parser_scope_push(parser, true);
14996
+
14964
14997
if (inheritance_operator.type != PM_TOKEN_NOT_PROVIDED) {
14965
14998
expect2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON, PM_ERR_CLASS_UNEXPECTED_END);
14966
14999
} else {
@@ -14986,9 +15019,10 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
14986
15019
}
14987
15020
14988
15021
pm_constant_id_list_t locals = parser->current_scope->locals;
15022
+
14989
15023
pm_parser_scope_pop(parser);
14990
- parser->current_param_name = old_param_name;
14991
15024
pm_do_loop_stack_pop(parser);
15025
+ pm_parser_current_param_name_restore(parser, saved_param_name);
14992
15026
14993
15027
if (!PM_NODE_TYPE_P(constant_path, PM_CONSTANT_PATH_NODE) && !(PM_NODE_TYPE_P(constant_path, PM_CONSTANT_READ_NODE))) {
14994
15028
pm_parser_err_node(parser, constant_path, PM_ERR_CLASS_NAME);
@@ -15003,18 +15037,21 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
15003
15037
pm_token_t operator = not_provided(parser);
15004
15038
pm_token_t name = (pm_token_t) { .type = PM_TOKEN_MISSING, .start = def_keyword.end, .end = def_keyword.end };
15005
15039
15006
- // This context is necessary for lexing `...` in a bare params correctly.
15007
- // It must be pushed before lexing the first param, so it is here.
15040
+ // This context is necessary for lexing `...` in a bare params
15041
+ // correctly. It must be pushed before lexing the first param, so it
15042
+ // is here.
15008
15043
context_push(parser, PM_CONTEXT_DEF_PARAMS);
15044
+ pm_constant_id_t saved_param_name;
15045
+
15009
15046
parser_lex(parser);
15010
- pm_constant_id_t old_param_name = parser->current_param_name;
15011
15047
15012
15048
switch (parser->current.type) {
15013
15049
case PM_CASE_OPERATOR:
15050
+ saved_param_name = pm_parser_current_param_name_unset(parser);
15014
15051
pm_parser_scope_push(parser, true);
15015
- parser->current_param_name = 0;
15016
15052
lex_state_set(parser, PM_LEX_STATE_ENDFN);
15017
15053
parser_lex(parser);
15054
+
15018
15055
name = parser->previous;
15019
15056
break;
15020
15057
case PM_TOKEN_IDENTIFIER: {
@@ -15023,17 +15060,18 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
15023
15060
if (match2(parser, PM_TOKEN_DOT, PM_TOKEN_COLON_COLON)) {
15024
15061
receiver = parse_variable_call(parser);
15025
15062
15063
+ saved_param_name = pm_parser_current_param_name_unset(parser);
15026
15064
pm_parser_scope_push(parser, true);
15027
- parser->current_param_name = 0;
15028
15065
lex_state_set(parser, PM_LEX_STATE_FNAME);
15029
15066
parser_lex(parser);
15030
15067
15031
15068
operator = parser->previous;
15032
15069
name = parse_method_definition_name(parser);
15033
15070
} else {
15071
+ saved_param_name = pm_parser_current_param_name_unset(parser);
15034
15072
pm_refute_numbered_parameter(parser, parser->previous.start, parser->previous.end);
15035
15073
pm_parser_scope_push(parser, true);
15036
- parser->current_param_name = 0;
15074
+
15037
15075
name = parser->previous;
15038
15076
}
15039
15077
@@ -15050,9 +15088,10 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
15050
15088
case PM_TOKEN_KEYWORD___FILE__:
15051
15089
case PM_TOKEN_KEYWORD___LINE__:
15052
15090
case PM_TOKEN_KEYWORD___ENCODING__: {
15091
+ saved_param_name = pm_parser_current_param_name_unset(parser);
15053
15092
pm_parser_scope_push(parser, true);
15054
- parser->current_param_name = 0;
15055
15093
parser_lex(parser);
15094
+
15056
15095
pm_token_t identifier = parser->previous;
15057
15096
15058
15097
if (match2(parser, PM_TOKEN_DOT, PM_TOKEN_COLON_COLON)) {
@@ -15124,17 +15163,18 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
15124
15163
operator = parser->previous;
15125
15164
receiver = (pm_node_t *) pm_parentheses_node_create(parser, &lparen, expression, &rparen);
15126
15165
15166
+ saved_param_name = pm_parser_current_param_name_unset(parser);
15127
15167
pm_parser_scope_push(parser, true);
15128
- parser->current_param_name = 0;
15129
15168
15130
15169
// To push `PM_CONTEXT_DEF_PARAMS` again is for the same reason as described the above.
15131
15170
context_push(parser, PM_CONTEXT_DEF_PARAMS);
15132
15171
name = parse_method_definition_name(parser);
15133
15172
break;
15134
15173
}
15135
15174
default:
15175
+ saved_param_name = pm_parser_current_param_name_unset(parser);
15136
15176
pm_parser_scope_push(parser, true);
15137
- parser->current_param_name = 0;
15177
+
15138
15178
name = parse_method_definition_name(parser);
15139
15179
break;
15140
15180
}
@@ -15249,8 +15289,9 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
15249
15289
}
15250
15290
15251
15291
pm_constant_id_list_t locals = parser->current_scope->locals;
15252
- parser->current_param_name = old_param_name;
15292
+
15253
15293
pm_parser_scope_pop(parser);
15294
+ pm_parser_current_param_name_restore(parser, saved_param_name);
15254
15295
15255
15296
return (pm_node_t *) pm_def_node_create(
15256
15297
parser,
@@ -15478,9 +15519,9 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
15478
15519
pm_parser_err_token(parser, &name, PM_ERR_MODULE_NAME);
15479
15520
}
15480
15521
15481
- pm_constant_id_t old_param_name = parser->current_param_name;
15482
- parser->current_param_name = 0;
15522
+ pm_constant_id_t saved_param_name = pm_parser_current_param_name_unset(parser);
15483
15523
pm_parser_scope_push(parser, true);
15524
+
15484
15525
accept2(parser, PM_TOKEN_SEMICOLON, PM_TOKEN_NEWLINE);
15485
15526
pm_node_t *statements = NULL;
15486
15527
@@ -15497,7 +15538,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
15497
15538
15498
15539
pm_constant_id_list_t locals = parser->current_scope->locals;
15499
15540
pm_parser_scope_pop(parser);
15500
- parser->current_param_name = old_param_name ;
15541
+ pm_parser_current_param_name_restore( parser, saved_param_name) ;
15501
15542
15502
15543
expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_MODULE_TERM);
15503
15544
@@ -16164,7 +16205,9 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
16164
16205
parser_lex(parser);
16165
16206
16166
16207
pm_token_t operator = parser->previous;
16208
+ pm_constant_id_t saved_param_name = pm_parser_current_param_name_unset(parser);
16167
16209
pm_parser_scope_push(parser, false);
16210
+
16168
16211
pm_block_parameters_node_t *block_parameters;
16169
16212
16170
16213
switch (parser->current.type) {
@@ -16243,8 +16286,11 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
16243
16286
}
16244
16287
16245
16288
pm_constant_id_list_t locals = parser->current_scope->locals;
16289
+
16246
16290
pm_parser_scope_pop(parser);
16247
16291
pm_accepts_block_stack_pop(parser);
16292
+ pm_parser_current_param_name_restore(parser, saved_param_name);
16293
+
16248
16294
return (pm_node_t *) pm_lambda_node_create(parser, &locals, locals_body_index, &operator, &opening, &parser->previous, parameters, body);
16249
16295
}
16250
16296
case PM_TOKEN_UPLUS: {
0 commit comments