Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit a218a0f

Browse files
committedFeb 16, 2024
Disallow numbered parameters within given scopes
1 parent 40059d3 commit a218a0f

File tree

2 files changed

+19
-13
lines changed

2 files changed

+19
-13
lines changed
 

‎include/prism/parser.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -488,13 +488,14 @@ typedef struct pm_scope {
488488
* numbered parameters, and to pass information to consumers of the AST
489489
* about how many numbered parameters exist.
490490
*/
491-
uint8_t numbered_parameters;
491+
int8_t numbered_parameters;
492492
} pm_scope_t;
493493

494494
static const uint8_t PM_FORWARDING_POSITIONALS = 0x1;
495495
static const uint8_t PM_FORWARDING_KEYWORDS = 0x2;
496496
static const uint8_t PM_FORWARDING_BLOCK = 0x4;
497497
static const uint8_t PM_FORWARDING_ALL = 0x8;
498+
static const int8_t PM_NUMBERED_PARAMETERS_DISALLOWED = -1;
498499

499500
/**
500501
* This struct represents the overall parser. It contains a reference to the

‎src/prism.c

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6383,7 +6383,7 @@ pm_parser_local_add(pm_parser_t *parser, pm_constant_id_t constant_id) {
63836383
* Set the numbered_parameters value of the current scope.
63846384
*/
63856385
static inline void
6386-
pm_parser_numbered_parameters_set(pm_parser_t *parser, uint8_t numbered_parameters) {
6386+
pm_parser_numbered_parameters_set(pm_parser_t *parser, int8_t numbered_parameters) {
63876387
parser->current_scope->numbered_parameters = numbered_parameters;
63886388
}
63896389

@@ -12588,10 +12588,10 @@ parse_block(pm_parser_t *parser) {
1258812588
}
1258912589

1259012590
pm_node_t *parameters = (pm_node_t *) block_parameters;
12591-
uint8_t maximum = parser->current_scope->numbered_parameters;
12591+
int8_t maximum = parser->current_scope->numbered_parameters;
1259212592

1259312593
if (parameters == NULL && (maximum > 0)) {
12594-
parameters = (pm_node_t *) pm_numbered_parameters_node_create(parser, &(pm_location_t) { .start = opening.start, .end = parser->previous.end }, maximum);
12594+
parameters = (pm_node_t *) pm_numbered_parameters_node_create(parser, &(pm_location_t) { .start = opening.start, .end = parser->previous.end }, (uint8_t) maximum);
1259512595
}
1259612596

1259712597
pm_constant_id_list_t locals = parser->current_scope->locals;
@@ -13289,7 +13289,7 @@ parse_alias_argument(pm_parser_t *parser, bool first) {
1328913289
static bool
1329013290
outer_scope_using_numbered_parameters_p(pm_parser_t *parser) {
1329113291
for (pm_scope_t *scope = parser->current_scope->previous; scope != NULL && !scope->closed; scope = scope->previous) {
13292-
if (scope->numbered_parameters) return true;
13292+
if (scope->numbered_parameters > 0) return true;
1329313293
}
1329413294

1329513295
return false;
@@ -13315,12 +13315,13 @@ parse_variable(pm_parser_t *parser) {
1331513315
return pm_local_variable_read_node_create(parser, &parser->previous, (uint32_t) depth);
1331613316
}
1331713317

13318-
if (!parser->current_scope->closed && pm_token_is_numbered_parameter(parser->previous.start, parser->previous.end)) {
13318+
pm_scope_t *current_scope = parser->current_scope;
13319+
if (!current_scope->closed && current_scope->numbered_parameters != PM_NUMBERED_PARAMETERS_DISALLOWED && pm_token_is_numbered_parameter(parser->previous.start, parser->previous.end)) {
1331913320
// Now that we know we have a numbered parameter, we need to check
1332013321
// if it's allowed in this context. If it is, then we will create a
1332113322
// local variable read. If it's not, then we'll create a normal call
1332213323
// node but add an error.
13323-
if (parser->current_scope->explicit_params) {
13324+
if (current_scope->explicit_params) {
1332413325
pm_parser_err_previous(parser, PM_ERR_NUMBERED_PARAMETER_NOT_ALLOWED);
1332513326
} else if (outer_scope_using_numbered_parameters_p(parser)) {
1332613327
pm_parser_err_previous(parser, PM_ERR_NUMBERED_PARAMETER_OUTER_SCOPE);
@@ -13329,9 +13330,9 @@ parse_variable(pm_parser_t *parser) {
1332913330
// scopes cannot. We subtract the value for the character '0' to get
1333013331
// the actual integer value of the number (only _1 through _9 are
1333113332
// valid).
13332-
uint8_t numbered_parameters = (uint8_t) (parser->previous.start[1] - '0');
13333-
if (numbered_parameters > parser->current_scope->numbered_parameters) {
13334-
parser->current_scope->numbered_parameters = numbered_parameters;
13333+
int8_t numbered_parameters = (int8_t) (parser->previous.start[1] - '0');
13334+
if (numbered_parameters > current_scope->numbered_parameters) {
13335+
current_scope->numbered_parameters = numbered_parameters;
1333513336
pm_parser_numbered_parameters_set(parser, numbered_parameters);
1333613337
}
1333713338

@@ -13340,7 +13341,7 @@ parse_variable(pm_parser_t *parser) {
1334013341
// referencing _2 means that _1 must exist. Therefore here we
1334113342
// loop through all of the possibilities and add them into the
1334213343
// constant pool.
13343-
for (uint8_t numbered_parameter = 1; numbered_parameter <= numbered_parameters - 1; numbered_parameter++) {
13344+
for (int8_t numbered_parameter = 1; numbered_parameter <= numbered_parameters - 1; numbered_parameter++) {
1334413345
pm_parser_local_add_constant(parser, pm_numbered_parameter_names[numbered_parameter - 1], 2);
1334513346
}
1334613347

@@ -16734,10 +16735,10 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
1673416735
}
1673516736

1673616737
pm_node_t *parameters = (pm_node_t *) block_parameters;
16737-
uint8_t maximum = parser->current_scope->numbered_parameters;
16738+
int8_t maximum = parser->current_scope->numbered_parameters;
1673816739

1673916740
if (parameters == NULL && (maximum > 0)) {
16740-
parameters = (pm_node_t *) pm_numbered_parameters_node_create(parser, &(pm_location_t) { .start = operator.start, .end = parser->previous.end }, maximum);
16741+
parameters = (pm_node_t *) pm_numbered_parameters_node_create(parser, &(pm_location_t) { .start = operator.start, .end = parser->previous.end }, (uint8_t) maximum);
1674116742
}
1674216743

1674316744
pm_constant_id_list_t locals = parser->current_scope->locals;
@@ -18008,6 +18009,10 @@ pm_parser_init(pm_parser_t *parser, const uint8_t *source, size_t size, const pm
1800818009
const pm_options_scope_t *scope = pm_options_scope_get(options, scope_index);
1800918010
pm_parser_scope_push(parser, scope_index == 0);
1801018011

18012+
// Scopes given from the outside are not allowed to have numbered
18013+
// parameters.
18014+
parser->current_scope->numbered_parameters = PM_NUMBERED_PARAMETERS_DISALLOWED;
18015+
1801118016
for (size_t local_index = 0; local_index < scope->locals_count; local_index++) {
1801218017
const pm_string_t *local = pm_options_scope_local_get(scope, local_index);
1801318018

0 commit comments

Comments
 (0)
Please sign in to comment.