[PRISM] Implement more compilation of SplatNodes

There was a bug with the rest argument in SplatNodes, this commit
fixes it, and adds more tests illustrating the behavior of
SplatNodes
This commit is contained in:
Jemma Issroff 2023-11-28 11:33:40 -05:00
parent 2760f23774
commit 7bd172744f
2 changed files with 32 additions and 13 deletions

View File

@ -3307,8 +3307,17 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
PM_COMPILE_NOT_POPPED(multi_write_node->value);
PM_DUP_UNLESS_POPPED;
pm_node_t *rest_expression = NULL;
if (multi_write_node->rest) {
RUBY_ASSERT(PM_NODE_TYPE_P(multi_write_node->rest, PM_SPLAT_NODE));
pm_splat_node_t *rest_splat = ((pm_splat_node_t *)multi_write_node->rest);
rest_expression = rest_splat->expression;
}
if (lefts->size) {
ADD_INSN2(ret, &dummy_line_node, expandarray, INT2FIX(lefts->size), INT2FIX((int) (bool) rights->size));
ADD_INSN2(ret, &dummy_line_node, expandarray, INT2FIX(lefts->size), INT2FIX((int) (bool) (rights->size || rest_expression)));
for (size_t index = 0; index < lefts->size; index++) {
pm_node_t *considered_node = lefts->nodes[index];
@ -3333,22 +3342,22 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
}
}
if (multi_write_node->rest) {
RUBY_ASSERT(PM_NODE_TYPE_P(multi_write_node->rest, PM_SPLAT_NODE));
pm_splat_node_t *rest_splat = ((pm_splat_node_t *)multi_write_node->rest);
if (rest_splat->expression) {
ADD_INSN2(ret, &dummy_line_node, expandarray, INT2FIX(0), INT2FIX(1));
PM_COMPILE(rest_splat->expression);
}
}
if (rights->size) {
ADD_INSN2(ret, &dummy_line_node, expandarray, INT2FIX(rights->size), INT2FIX(2));
if (rest_expression) {
ADD_INSN2(ret, &dummy_line_node, expandarray, INT2FIX(rights->size), INT2FIX(3));
PM_COMPILE(rest_expression);
}
else {
ADD_INSN2(ret, &dummy_line_node, expandarray, INT2FIX(rights->size), INT2FIX(2));
}
for (size_t index = 0; index < rights->size; index++) {
PM_COMPILE(rights->nodes[index]);
}
}
else if (rest_expression) {
PM_COMPILE(rest_expression);
}
return;
}

View File

@ -596,7 +596,17 @@ module Prism
end
def test_SplatNode
assert_prism_eval("*b = []")
assert_prism_eval("*b = []; b")
assert_prism_eval("*b = [1, 2, 3]; b")
assert_prism_eval("a, *b = [1, 2, 3]; a")
assert_prism_eval("a, *b = [1, 2, 3]; b")
assert_prism_eval("a, *b, c = [1, 2, 3]; a")
assert_prism_eval("a, *b, c = [1, 2, 3]; b")
assert_prism_eval("a, *b, c = [1, 2, 3]; c")
assert_prism_eval("*b, c = [1, 2, 3]; b")
assert_prism_eval("*b, c = [1, 2, 3]; c")
assert_prism_eval("a, *, c = [1, 2, 3]; a")
assert_prism_eval("a, *, c = [1, 2, 3]; c")
end
############################################################################