Skip to content

Commit

Permalink
[ruby/prism] Add locals_body_index to DefNode, BlockNode, LambdaNode
Browse files Browse the repository at this point in the history
The locals_body_index gives the index in the locals array where
the locals from the body start. This allows compilers to easily
index past the parameters in the locals array.

ruby/prism@5d4627b890
  • Loading branch information
jemmaissroff committed Dec 6, 2023
1 parent da1519b commit 018dbf1
Show file tree
Hide file tree
Showing 291 changed files with 873 additions and 3 deletions.
6 changes: 6 additions & 0 deletions prism/config.yml
Expand Up @@ -587,6 +587,8 @@ nodes:
fields:
- name: locals
type: constant[]
- name: locals_body_index
type: uint32
- name: parameters
type: node?
- name: body
Expand Down Expand Up @@ -1103,6 +1105,8 @@ nodes:
type: node?
- name: locals
type: constant[]
- name: locals_body_index
type: uint32
- name: def_keyword_loc
type: location
- name: operator_loc
Expand Down Expand Up @@ -1761,6 +1765,8 @@ nodes:
fields:
- name: locals
type: constant[]
- name: locals_body_index
type: uint32
- name: operator_loc
type: location
- name: opening_loc
Expand Down
28 changes: 25 additions & 3 deletions prism/prism.c
Expand Up @@ -1467,7 +1467,7 @@ pm_block_argument_node_create(pm_parser_t *parser, const pm_token_t *operator, p
* Allocate and initialize a new BlockNode node.
*/
static pm_block_node_t *
pm_block_node_create(pm_parser_t *parser, pm_constant_id_list_t *locals, const pm_token_t *opening, pm_node_t *parameters, pm_node_t *body, const pm_token_t *closing) {
pm_block_node_create(pm_parser_t *parser, pm_constant_id_list_t *locals, uint32_t locals_body_index, const pm_token_t *opening, pm_node_t *parameters, pm_node_t *body, const pm_token_t *closing) {
pm_block_node_t *node = PM_ALLOC_NODE(parser, pm_block_node_t);

*node = (pm_block_node_t) {
Expand All @@ -1476,6 +1476,7 @@ pm_block_node_create(pm_parser_t *parser, pm_constant_id_list_t *locals, const p
.location = { .start = opening->start, .end = closing->end },
},
.locals = *locals,
.locals_body_index = locals_body_index,
.parameters = parameters,
.body = body,
.opening_loc = PM_LOCATION_TOKEN_VALUE(opening),
Expand Down Expand Up @@ -2631,6 +2632,7 @@ pm_def_node_create(
pm_parameters_node_t *parameters,
pm_node_t *body,
pm_constant_id_list_t *locals,
uint32_t locals_body_index,
const pm_token_t *def_keyword,
const pm_token_t *operator,
const pm_token_t *lparen,
Expand Down Expand Up @@ -2658,6 +2660,7 @@ pm_def_node_create(
.parameters = parameters,
.body = body,
.locals = *locals,
.locals_body_index = locals_body_index,
.def_keyword_loc = PM_LOCATION_TOKEN_VALUE(def_keyword),
.operator_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(operator),
.lparen_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(lparen),
Expand Down Expand Up @@ -3954,6 +3957,7 @@ static pm_lambda_node_t *
pm_lambda_node_create(
pm_parser_t *parser,
pm_constant_id_list_t *locals,
uint32_t locals_body_index,
const pm_token_t *operator,
const pm_token_t *opening,
const pm_token_t *closing,
Expand All @@ -3971,6 +3975,7 @@ pm_lambda_node_create(
},
},
.locals = *locals,
.locals_body_index = locals_body_index,
.operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
.opening_loc = PM_LOCATION_TOKEN_VALUE(opening),
.closing_loc = PM_LOCATION_TOKEN_VALUE(closing),
Expand Down Expand Up @@ -11915,6 +11920,12 @@ parse_block(pm_parser_t *parser) {
pm_block_parameters_node_closing_set(block_parameters, &parser->previous);
}

uint32_t locals_body_index = 0;

if (block_parameters) {
locals_body_index = (uint32_t) parser->current_scope->locals.size;
}

accept1(parser, PM_TOKEN_NEWLINE);
pm_node_t *statements = NULL;

Expand Down Expand Up @@ -11946,12 +11957,13 @@ parse_block(pm_parser_t *parser) {

if (parameters == NULL && (maximum > 0)) {
parameters = (pm_node_t *) pm_numbered_parameters_node_create(parser, &(pm_location_t) { .start = opening.start, .end = parser->previous.end }, maximum);
locals_body_index = maximum;
}

pm_constant_id_list_t locals = parser->current_scope->locals;
pm_parser_scope_pop(parser);
pm_accepts_block_stack_pop(parser);
return pm_block_node_create(parser, &locals, &opening, parameters, statements, &parser->previous);
return pm_block_node_create(parser, &locals, locals_body_index, &opening, parameters, statements, &parser->previous);
}

/**
Expand Down Expand Up @@ -14807,6 +14819,8 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
}
}

uint32_t locals_body_index = (uint32_t) parser->current_scope->locals.size;

context_pop(parser);
pm_node_t *statements = NULL;
pm_token_t equal;
Expand Down Expand Up @@ -14877,6 +14891,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
params,
statements,
&locals,
locals_body_index,
&def_keyword,
&operator,
&lparen,
Expand Down Expand Up @@ -15798,6 +15813,12 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
}
}

uint32_t locals_body_index = 0;

if (block_parameters) {
locals_body_index = (uint32_t) parser->current_scope->locals.size;
}

pm_token_t opening;
pm_node_t *body = NULL;
parser->lambda_enclosure_nesting = previous_lambda_enclosure_nesting;
Expand Down Expand Up @@ -15832,12 +15853,13 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b

if (parameters == NULL && (maximum > 0)) {
parameters = (pm_node_t *) pm_numbered_parameters_node_create(parser, &(pm_location_t) { .start = operator.start, .end = parser->previous.end }, maximum);
locals_body_index = maximum;
}

pm_constant_id_list_t locals = parser->current_scope->locals;
pm_parser_scope_pop(parser);
pm_accepts_block_stack_pop(parser);
return (pm_node_t *) pm_lambda_node_create(parser, &locals, &operator, &opening, &parser->previous, parameters, body);
return (pm_node_t *) pm_lambda_node_create(parser, &locals, locals_body_index, &operator, &opening, &parser->previous, parameters, body);
}
case PM_TOKEN_UPLUS: {
parser_lex(parser);
Expand Down
25 changes: 25 additions & 0 deletions test/prism/errors_test.rb
Expand Up @@ -419,6 +419,7 @@ def test_module_definition_in_method_body
nil,
StatementsNode([ModuleNode([], Location(), ConstantReadNode(:A), nil, Location(), :A)]),
[],
0,
Location(),
nil,
nil,
Expand Down Expand Up @@ -449,6 +450,7 @@ def test_module_definition_in_method_body_within_block
nil,
BlockNode(
[],
0,
nil,
StatementsNode([ModuleNode([], Location(), ConstantReadNode(:Foo), nil, Location(), :Foo)]),
Location(),
Expand All @@ -458,6 +460,7 @@ def test_module_definition_in_method_body_within_block
)]
),
[],
0,
Location(),
nil,
nil,
Expand Down Expand Up @@ -508,6 +511,7 @@ def test_class_definition_in_method_body
)]
),
[],
0,
Location(),
nil,
nil,
Expand Down Expand Up @@ -548,6 +552,7 @@ def test_bad_arguments
], [], nil, [], [], nil, nil),
nil,
[:A, :@a, :$A, :@@a],
4,
Location(),
nil,
Location(),
Expand Down Expand Up @@ -619,6 +624,7 @@ def test_do_not_allow_trailing_commas_in_method_parameters
),
nil,
[:a, :b, :c],
3,
Location(),
nil,
Location(),
Expand All @@ -635,6 +641,7 @@ def test_do_not_allow_trailing_commas_in_method_parameters
def test_do_not_allow_trailing_commas_in_lambda_parameters
expected = LambdaNode(
[:a, :b],
2,
Location(),
Location(),
Location(),
Expand Down Expand Up @@ -703,6 +710,7 @@ def test_method_parameters_after_block
),
nil,
[:block, :a],
2,
Location(),
nil,
Location(),
Expand All @@ -723,6 +731,7 @@ def test_method_with_arguments_after_anonymous_block
ParametersNode([], [], nil, [RequiredParameterNode(:a)], [], nil, BlockParameterNode(nil, nil, Location())),
nil,
[:&, :a],
2,
Location(),
nil,
Location(),
Expand Down Expand Up @@ -752,6 +761,7 @@ def test_method_parameters_after_arguments_forwarding
),
nil,
[:"...", :a],
2,
Location(),
nil,
Location(),
Expand Down Expand Up @@ -780,6 +790,7 @@ def test_keywords_parameters_before_required_parameters
),
nil,
[:b, :a],
2,
Location(),
nil,
Location(),
Expand Down Expand Up @@ -808,6 +819,7 @@ def test_rest_keywords_parameters_before_required_parameters
),
nil,
[:rest, :b],
2,
Location(),
nil,
Location(),
Expand All @@ -829,6 +841,7 @@ def test_double_arguments_forwarding
ParametersNode([], [], nil, [], [], ForwardingParameterNode(), nil),
nil,
[:"..."],
1,
Location(),
nil,
Location(),
Expand Down Expand Up @@ -858,6 +871,7 @@ def test_multiple_error_in_parameters_order
),
nil,
[:args, :a, :b],
3,
Location(),
nil,
Location(),
Expand Down Expand Up @@ -888,6 +902,7 @@ def test_switching_to_optional_arguments_twice
),
nil,
[:args, :a, :b],
3,
Location(),
nil,
Location(),
Expand Down Expand Up @@ -918,6 +933,7 @@ def test_switching_to_named_arguments_twice
),
nil,
[:args, :a, :b],
3,
Location(),
nil,
Location(),
Expand Down Expand Up @@ -951,6 +967,7 @@ def test_returning_to_optional_parameters_multiple_times
),
nil,
[:a, :b, :c, :d, :e],
5,
Location(),
nil,
Location(),
Expand Down Expand Up @@ -1000,6 +1017,7 @@ def test_setter_method_cannot_be_defined_in_an_endless_method_definition
nil,
StatementsNode([IntegerNode(IntegerBaseFlags::DECIMAL)]),
[],
0,
Location(),
nil,
Location(),
Expand All @@ -1016,6 +1034,7 @@ def test_setter_method_cannot_be_defined_in_an_endless_method_definition
def test_do_not_allow_forward_arguments_in_lambda_literals
expected = LambdaNode(
[],
0,
Location(),
Location(),
Location(),
Expand All @@ -1039,6 +1058,7 @@ def test_do_not_allow_forward_arguments_in_blocks
nil,
BlockNode(
[],
0,
BlockParametersNode(ParametersNode([], [], nil, [], [], ForwardingParameterNode(), nil), [], Location(), Location()),
nil,
Location(),
Expand Down Expand Up @@ -1114,6 +1134,7 @@ def test_duplicated_parameter_names
ParametersNode([RequiredParameterNode(:a), RequiredParameterNode(:b), RequiredParameterNode(:a)], [], nil, [], [], nil, nil),
nil,
[:a, :b],
2,
Location(),
nil,
Location(),
Expand All @@ -1134,6 +1155,7 @@ def test_duplicated_parameter_names
ParametersNode([RequiredParameterNode(:a), RequiredParameterNode(:b)], [], RestParameterNode(:a, Location(), Location()), [], [], nil, nil),
nil,
[:a, :b],
2,
Location(),
nil,
Location(),
Expand All @@ -1153,6 +1175,7 @@ def test_duplicated_parameter_names
ParametersNode([RequiredParameterNode(:a), RequiredParameterNode(:b)], [], nil, [], [], KeywordRestParameterNode(:a, Location(), Location()), nil),
nil,
[:a, :b],
2,
Location(),
nil,
Location(),
Expand All @@ -1172,6 +1195,7 @@ def test_duplicated_parameter_names
ParametersNode([RequiredParameterNode(:a), RequiredParameterNode(:b)], [], nil, [], [], nil, BlockParameterNode(:a, Location(), Location())),
nil,
[:a, :b],
2,
Location(),
nil,
Location(),
Expand All @@ -1191,6 +1215,7 @@ def test_duplicated_parameter_names
ParametersNode([], [OptionalParameterNode(:a, Location(), Location(), IntegerNode(IntegerBaseFlags::DECIMAL))], RestParameterNode(:c, Location(), Location()), [RequiredParameterNode(:b)], [], nil, nil),
nil,
[:a, :b, :c],
3,
Location(),
nil,
Location(),
Expand Down

0 comments on commit 018dbf1

Please sign in to comment.