Skip to content

Commit ebc91c2

Browse files
committed
Fully destroy call operator write arguments
If we are about to delete a call operator write argument, it needs to be removed from the list of block exits as well.
1 parent d3f99ec commit ebc91c2

File tree

2 files changed

+49
-0
lines changed

2 files changed

+49
-0
lines changed

src/prism.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21062,6 +21062,42 @@ parse_assignment_values(pm_parser_t *parser, pm_binding_power_t previous_binding
2106221062
return value;
2106321063
}
2106421064

21065+
static bool
21066+
parse_call_operator_write_block_exits_each(const pm_node_t *node, void *data) {
21067+
pm_parser_t *parser = (pm_parser_t *) data;
21068+
size_t index = 0;
21069+
21070+
while (index < parser->current_block_exits->size) {
21071+
pm_node_t *block_exit = parser->current_block_exits->nodes[index];
21072+
21073+
if (block_exit == node) {
21074+
if (index + 1 < parser->current_block_exits->size) {
21075+
memmove(
21076+
&parser->current_block_exits->nodes[index],
21077+
&parser->current_block_exits->nodes[index + 1],
21078+
(parser->current_block_exits->size - index - 1) * sizeof(pm_node_t *)
21079+
);
21080+
}
21081+
parser->current_block_exits->size--;
21082+
return false;
21083+
}
21084+
21085+
index++;
21086+
}
21087+
21088+
return true;
21089+
}
21090+
21091+
/**
21092+
* When we are about to destroy a set of nodes that could potentially contain
21093+
* block exits for the current scope, we need to check if they are contained in
21094+
* the list of block exits and remove them if they are.
21095+
*/
21096+
static void
21097+
parse_call_operator_write_block_exits(pm_parser_t *parser, const pm_node_t *node) {
21098+
pm_visit_node(node, parse_call_operator_write_block_exits_each, parser);
21099+
}
21100+
2106521101
/**
2106621102
* Ensure a call node that is about to become a call operator node does not
2106721103
* have arguments or a block attached. If it does, then we'll need to add an
@@ -21073,12 +21109,14 @@ static void
2107321109
parse_call_operator_write(pm_parser_t *parser, pm_call_node_t *call_node, const pm_token_t *operator) {
2107421110
if (call_node->arguments != NULL) {
2107521111
pm_parser_err_token(parser, operator, PM_ERR_OPERATOR_WRITE_ARGUMENTS);
21112+
parse_call_operator_write_block_exits(parser, (pm_node_t *) call_node->arguments);
2107621113
pm_node_destroy(parser, (pm_node_t *) call_node->arguments);
2107721114
call_node->arguments = NULL;
2107821115
}
2107921116

2108021117
if (call_node->block != NULL) {
2108121118
pm_parser_err_token(parser, operator, PM_ERR_OPERATOR_WRITE_BLOCK);
21119+
parse_call_operator_write_block_exits(parser, (pm_node_t *) call_node->block);
2108221120
pm_node_destroy(parser, (pm_node_t *) call_node->block);
2108321121
call_node->block = NULL;
2108421122
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
t next&&do end&=
2+
^~ unexpected 'do'; expected an expression after the operator
3+
^~~~ unexpected void value expression
4+
^~~~ unexpected void value expression
5+
^~~~~~~~~~~~~~ unexpected write target
6+
^~ unexpected operator after a call with arguments
7+
^~ unexpected operator after a call with a block
8+
''while=
9+
^~~~~ expected a predicate expression for the `while` statement
10+
^ unexpected '='; target cannot be written
11+

0 commit comments

Comments
 (0)