Skip to content

Commit

Permalink
Combine if and unless guard conditions
Browse files Browse the repository at this point in the history
  • Loading branch information
st0012 committed Oct 24, 2024
1 parent fb82456 commit af24f04
Showing 1 changed file with 22 additions and 25 deletions.
47 changes: 22 additions & 25 deletions parser/prism/Translator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1343,39 +1343,36 @@ unique_ptr<parser::Node> Translator::patternTranslate(pm_node_t *node) {
case PM_IN_NODE: { // An `in` pattern such as in a `case` statement, or as a standalone expression.
auto inNode = down_cast<pm_in_node>(node);

auto prismPattern = move(inNode->pattern);
auto prismPattern = inNode->pattern;
unique_ptr<parser::Node> sorbetPattern;
unique_ptr<parser::Node> sorbetGuard;
auto inlineIfSingle = true;
auto statements = translateStatements(inNode->statements, inlineIfSingle);

if (prismPattern != nullptr && PM_NODE_TYPE_P(prismPattern, PM_IF_NODE)) {
auto ifNode = reinterpret_cast<pm_if_node *>(prismPattern);
auto prismStatements = reinterpret_cast<pm_statements_node *>(ifNode->statements);

if (prismStatements->body.size != 1) {
unreachable("In pattern-matching's `in` clause, an `if` guard must have a single statement.");
if (prismPattern != nullptr &&
(PM_NODE_TYPE_P(prismPattern, PM_IF_NODE) || PM_NODE_TYPE_P(prismPattern, PM_UNLESS_NODE))) {
pm_statements_node *conditionalStatements = nullptr;

if (PM_NODE_TYPE_P(prismPattern, PM_IF_NODE)) {
auto ifNode = down_cast<pm_if_node>(prismPattern);
conditionalStatements = ifNode->statements;
sorbetGuard = make_unique<parser::IfGuard>(location, translate(ifNode->predicate));
} else { // PM_UNLESS_NODE
auto unlessNode = down_cast<pm_unless_node>(prismPattern);
conditionalStatements = unlessNode->statements;
sorbetGuard = make_unique<parser::UnlessGuard>(location, translate(unlessNode->predicate));
}

auto sorbetPattern = patternTranslate(prismStatements->body.nodes[0]);
auto sorbetGuard = make_unique<parser::IfGuard>(location, translate(ifNode->predicate));

return make_unique<parser::InPattern>(location, move(sorbetPattern), move(sorbetGuard), move(statements));
} else if (prismPattern != nullptr && PM_NODE_TYPE_P(prismPattern, PM_UNLESS_NODE)) {
auto unlessNode = reinterpret_cast<pm_unless_node *>(prismPattern);
auto prismStatements = reinterpret_cast<pm_statements_node *>(unlessNode->statements);

if (prismStatements->body.size != 1) {
unreachable("In pattern-matching's `in` clause, an `unless` guard must have a single statement.");
}
ENFORCE(
conditionalStatements->body.size == 1,
"In pattern-matching's `in` clause, a conditional (if/unless) guard must have a single statement.");

auto sorbetPattern = patternTranslate(prismStatements->body.nodes[0]);
auto sorbetGuard = make_unique<parser::UnlessGuard>(location, translate(unlessNode->predicate));

return make_unique<parser::InPattern>(location, move(sorbetPattern), move(sorbetGuard), move(statements));
sorbetPattern = patternTranslate(conditionalStatements->body.nodes[0]);
} else {
auto sorbetPattern = patternTranslate(prismPattern);

return make_unique<parser::InPattern>(location, move(sorbetPattern), nullptr, move(statements));
sorbetPattern = patternTranslate(prismPattern);
}

return make_unique<parser::InPattern>(location, move(sorbetPattern), move(sorbetGuard), move(statements));
}
case PM_LOCAL_VARIABLE_TARGET_NODE: { // A variable binding in a pattern, like the `head` in `[head, *tail]`
auto localVarTargetNode = down_cast<pm_local_variable_target_node>(node);
Expand Down

0 comments on commit af24f04

Please sign in to comment.