[PRISM] Fix case without predicate

Fixes ruby/prism#2149.
This commit is contained in:
Peter Zhu 2024-01-12 13:04:59 -05:00
Родитель e0312f90bb
Коммит 7c6d7fbc28
2 изменённых файлов: 30 добавлений и 24 удалений

Просмотреть файл

@ -3408,42 +3408,38 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
for (size_t i = 0; i < conditions.size; i++) {
label = NEW_LABEL(lineno);
conditions_labels[i] = label;
if (has_predicate) {
pm_when_node_t *when_node = (pm_when_node_t *)conditions.nodes[i];
pm_when_node_t *when_node = (pm_when_node_t *)conditions.nodes[i];
for (size_t i = 0; i < when_node->conditions.size; i++) {
pm_node_t *condition_node = when_node->conditions.nodes[i];
for (size_t i = 0; i < when_node->conditions.size; i++) {
pm_node_t *condition_node = when_node->conditions.nodes[i];
if (PM_NODE_TYPE_P(condition_node, PM_SPLAT_NODE)) {
ADD_INSN (ret, &dummy_line_node, dup);
PM_COMPILE_NOT_POPPED(condition_node);
ADD_INSN1(ret, &dummy_line_node, splatarray, Qfalse);
ADD_INSN1(ret, &dummy_line_node, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_CASE | VM_CHECKMATCH_ARRAY));
}
else {
PM_COMPILE_NOT_POPPED(condition_node);
if (PM_NODE_TYPE_P(condition_node, PM_SPLAT_NODE)) {
ADD_INSN (ret, &dummy_line_node, dup);
PM_COMPILE_NOT_POPPED(condition_node);
ADD_INSN1(ret, &dummy_line_node, splatarray, Qfalse);
ADD_INSN1(ret, &dummy_line_node, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_CASE | VM_CHECKMATCH_ARRAY));
}
else {
PM_COMPILE_NOT_POPPED(condition_node);
if (has_predicate) {
ADD_INSN1(ret, &dummy_line_node, topn, INT2FIX(1));
ADD_SEND_WITH_FLAG(ret, &dummy_line_node, idEqq, INT2NUM(1), INT2FIX(VM_CALL_FCALL | VM_CALL_ARGS_SIMPLE));
}
ADD_INSNL(ret, &dummy_line_node, branchif, label);
}
}
else {
ADD_INSNL(ret, &dummy_line_node, jump, label);
PM_PUTNIL;
ADD_INSNL(ret, &dummy_line_node, branchif, label);
}
}
if (has_predicate) {
PM_POP;
}
if (case_node->consequent) {
PM_COMPILE((pm_node_t *)case_node->consequent);
}
else {
PM_PUTNIL_UNLESS_POPPED;
}
if (case_node->consequent) {
PM_COMPILE((pm_node_t *)case_node->consequent);
}
else {
PM_PUTNIL_UNLESS_POPPED;
}
ADD_INSNL(ret, &dummy_line_node, jump, end_label);

Просмотреть файл

@ -794,6 +794,16 @@ module Prism
:ng
end
RUBY
# Test case without predicate
assert_prism_eval(<<~RUBY)
case
when 1 == 2
:ng
else
:ok
end
RUBY
end
def test_ElseNode