@@ -1465,7 +1465,7 @@ pm_block_argument_node_create(pm_parser_t *parser, const pm_token_t *operator, p
1465
1465
* Allocate and initialize a new BlockNode node.
1466
1466
*/
1467
1467
static pm_block_node_t *
1468
- pm_block_node_create(pm_parser_t *parser, pm_constant_id_list_t *locals, const pm_token_t *opening, pm_block_parameters_node_t *parameters, pm_node_t *body, const pm_token_t *closing) {
1468
+ pm_block_node_create(pm_parser_t *parser, pm_constant_id_list_t *locals, const pm_token_t *opening, pm_block_parameters_node_t *parameters, pm_node_t *body, const pm_token_t *closing, uint32_t numbered_parameters ) {
1469
1469
pm_block_node_t *node = PM_ALLOC_NODE(parser, pm_block_node_t);
1470
1470
1471
1471
*node = (pm_block_node_t) {
@@ -1476,6 +1476,7 @@ pm_block_node_create(pm_parser_t *parser, pm_constant_id_list_t *locals, const p
1476
1476
.locals = *locals,
1477
1477
.parameters = parameters,
1478
1478
.body = body,
1479
+ .numbered_parameters = numbered_parameters,
1479
1480
.opening_loc = PM_LOCATION_TOKEN_VALUE(opening),
1480
1481
.closing_loc = PM_LOCATION_TOKEN_VALUE(closing)
1481
1482
};
@@ -3937,7 +3938,8 @@ pm_lambda_node_create(
3937
3938
const pm_token_t *opening,
3938
3939
const pm_token_t *closing,
3939
3940
pm_block_parameters_node_t *parameters,
3940
- pm_node_t *body
3941
+ pm_node_t *body,
3942
+ uint32_t numbered_parameters
3941
3943
) {
3942
3944
pm_lambda_node_t *node = PM_ALLOC_NODE(parser, pm_lambda_node_t);
3943
3945
@@ -3954,7 +3956,8 @@ pm_lambda_node_create(
3954
3956
.opening_loc = PM_LOCATION_TOKEN_VALUE(opening),
3955
3957
.closing_loc = PM_LOCATION_TOKEN_VALUE(closing),
3956
3958
.parameters = parameters,
3957
- .body = body
3959
+ .body = body,
3960
+ .numbered_parameters = numbered_parameters
3958
3961
};
3959
3962
3960
3963
return node;
@@ -5746,7 +5749,7 @@ pm_parser_scope_push(pm_parser_t *parser, bool closed) {
5746
5749
.previous = parser->current_scope,
5747
5750
.closed = closed,
5748
5751
.explicit_params = false,
5749
- .numbered_params = false ,
5752
+ .numbered_parameters = 0 ,
5750
5753
.transparent = false
5751
5754
};
5752
5755
@@ -5768,7 +5771,7 @@ pm_parser_scope_push_transparent(pm_parser_t *parser) {
5768
5771
.previous = parser->current_scope,
5769
5772
.closed = false,
5770
5773
.explicit_params = false,
5771
- .numbered_params = false ,
5774
+ .numbered_parameters = 0 ,
5772
5775
.transparent = true
5773
5776
};
5774
5777
@@ -5821,6 +5824,18 @@ pm_parser_local_add(pm_parser_t *parser, pm_constant_id_t constant_id) {
5821
5824
}
5822
5825
}
5823
5826
5827
+ /**
5828
+ * Add a constant id to the local table of the current scope.
5829
+ */
5830
+ static inline void
5831
+ pm_parser_numbered_parameters_set(pm_parser_t *parser, uint32_t numbered_parameters) {
5832
+ pm_scope_t *scope = parser->current_scope;
5833
+ while (scope && scope->transparent) scope = scope->previous;
5834
+
5835
+ assert(scope != NULL);
5836
+ scope->numbered_parameters = numbered_parameters;
5837
+ }
5838
+
5824
5839
/**
5825
5840
* Add a local variable from a location to the current scope.
5826
5841
*/
@@ -12052,9 +12067,10 @@ parse_block(pm_parser_t *parser) {
12052
12067
}
12053
12068
12054
12069
pm_constant_id_list_t locals = parser->current_scope->locals;
12070
+ uint32_t numbered_parameters = parser->current_scope->numbered_parameters;
12055
12071
pm_parser_scope_pop(parser);
12056
12072
pm_accepts_block_stack_pop(parser);
12057
- return pm_block_node_create(parser, &locals, &opening, parameters, statements, &parser->previous);
12073
+ return pm_block_node_create(parser, &locals, &opening, parameters, statements, &parser->previous, numbered_parameters );
12058
12074
}
12059
12075
12060
12076
/**
@@ -12625,9 +12641,9 @@ parse_alias_argument(pm_parser_t *parser, bool first) {
12625
12641
* numbered parameters.
12626
12642
*/
12627
12643
static bool
12628
- outer_scope_using_numbered_params_p (pm_parser_t *parser) {
12644
+ outer_scope_using_numbered_parameters_p (pm_parser_t *parser) {
12629
12645
for (pm_scope_t *scope = parser->current_scope->previous; scope != NULL && !scope->closed; scope = scope->previous) {
12630
- if (scope->numbered_params ) return true;
12646
+ if (scope->numbered_parameters ) return true;
12631
12647
}
12632
12648
12633
12649
return false;
@@ -12647,25 +12663,32 @@ parse_variable_call(pm_parser_t *parser) {
12647
12663
}
12648
12664
12649
12665
if (!parser->current_scope->closed && pm_token_is_numbered_parameter(parser->previous.start, parser->previous.end)) {
12650
- // Indicate that this scope is using numbered params so that child
12651
- // scopes cannot.
12652
- parser->current_scope->numbered_params = true;
12653
-
12654
12666
// Now that we know we have a numbered parameter, we need to check
12655
12667
// if it's allowed in this context. If it is, then we will create a
12656
12668
// local variable read. If it's not, then we'll create a normal call
12657
12669
// node but add an error.
12658
12670
if (parser->current_scope->explicit_params) {
12659
12671
pm_parser_err_previous(parser, PM_ERR_NUMBERED_PARAMETER_NOT_ALLOWED);
12660
- } else if (outer_scope_using_numbered_params_p (parser)) {
12672
+ } else if (outer_scope_using_numbered_parameters_p (parser)) {
12661
12673
pm_parser_err_previous(parser, PM_ERR_NUMBERED_PARAMETER_OUTER_SCOPE);
12662
12674
} else {
12675
+ // Indicate that this scope is using numbered params so that child
12676
+ // scopes cannot.
12677
+ uint8_t number = parser->previous.start[1];
12678
+
12679
+ // We subtract the value for the character '0' to get the actual
12680
+ // integer value of the number (only _1 through _9 are valid)
12681
+ uint32_t number_as_int = (uint32_t) (number - '0');
12682
+ if (number_as_int > parser->current_scope->numbered_parameters) {
12683
+ parser->current_scope->numbered_parameters = number_as_int;
12684
+ pm_parser_numbered_parameters_set(parser, number_as_int);
12685
+ }
12686
+
12663
12687
// When you use a numbered parameter, it implies the existence
12664
12688
// of all of the locals that exist before it. For example,
12665
12689
// referencing _2 means that _1 must exist. Therefore here we
12666
12690
// loop through all of the possibilities and add them into the
12667
12691
// constant pool.
12668
- uint8_t number = parser->previous.start[1];
12669
12692
uint8_t current = '1';
12670
12693
uint8_t *value;
12671
12694
@@ -15856,9 +15879,10 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) {
15856
15879
}
15857
15880
15858
15881
pm_constant_id_list_t locals = parser->current_scope->locals;
15882
+ uint32_t numbered_parameters = parser->current_scope->numbered_parameters;
15859
15883
pm_parser_scope_pop(parser);
15860
15884
pm_accepts_block_stack_pop(parser);
15861
- return (pm_node_t *) pm_lambda_node_create(parser, &locals, &operator, &opening, &parser->previous, params, body);
15885
+ return (pm_node_t *) pm_lambda_node_create(parser, &locals, &operator, &opening, &parser->previous, params, body, numbered_parameters );
15862
15886
}
15863
15887
case PM_TOKEN_UPLUS: {
15864
15888
parser_lex(parser);
0 commit comments