Skip to content

Commit

Permalink
Implement translation for case and when
Browse files Browse the repository at this point in the history
  • Loading branch information
egiurleo committed Aug 26, 2024
1 parent f0ae699 commit 2e05551
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 2 deletions.
41 changes: 39 additions & 2 deletions parser/prism/Translator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,26 @@ std::unique_ptr<parser::Node> Translator::translate(pm_node_t *node) {
return sendNode;
}
}
case PM_CASE_NODE: {
auto caseNode = reinterpret_cast<pm_case_node *>(node);
pm_location_t *loc = &caseNode->base.location;

auto predicate = translate(caseNode->predicate);

auto prismConditions = absl::MakeSpan(caseNode->conditions.nodes, caseNode->conditions.size);

parser::NodeVec sorbetConditions{};
sorbetConditions.reserve(prismConditions.size());

for (auto &prismCondition : prismConditions) {
sorbetConditions.emplace_back(translate(prismCondition));
}

auto consequent = translate(reinterpret_cast<pm_node_t *>(caseNode->consequent));

return make_unique<Case>(parser.translateLocation(loc), std::move(predicate), std::move(sorbetConditions),
std::move(consequent));
}
case PM_CLASS_NODE: { // Class declarations, not including singleton class declarations (`class <<`)
auto classNode = reinterpret_cast<pm_class_node *>(node);
pm_location_t *loc = &classNode->base.location;
Expand Down Expand Up @@ -581,6 +601,25 @@ std::unique_ptr<parser::Node> Translator::translate(pm_node_t *node) {

return make_unique<parser::Until>(parser.translateLocation(loc), std::move(predicate), std::move(body));
}
case PM_WHEN_NODE: {
auto whenNode = reinterpret_cast<pm_when_node *>(node);
auto *loc = &whenNode->base.location;

auto prismConditions = absl::MakeSpan(whenNode->conditions.nodes, whenNode->conditions.size);

parser::NodeVec sorbetConditions{};
sorbetConditions.reserve(prismConditions.size());

for (auto &prismCondition : prismConditions) {
sorbetConditions.emplace_back(translate(prismCondition));
}

auto inlineIfSingle = true;
auto statements = translateStatements(whenNode->statements, inlineIfSingle);

return make_unique<parser::When>(parser.translateLocation(loc), std::move(sorbetConditions),
std::move(statements));
}
case PM_YIELD_NODE: {
auto yieldNode = reinterpret_cast<pm_yield_node *>(node);
pm_location_t *loc = &yieldNode->base.location;
Expand All @@ -604,7 +643,6 @@ std::unique_ptr<parser::Node> Translator::translate(pm_node_t *node) {
case PM_CALL_TARGET_NODE:
case PM_CAPTURE_PATTERN_NODE:
case PM_CASE_MATCH_NODE:
case PM_CASE_NODE:
case PM_CLASS_VARIABLE_AND_WRITE_NODE:
case PM_CLASS_VARIABLE_OPERATOR_WRITE_NODE:
case PM_CLASS_VARIABLE_OR_WRITE_NODE:
Expand Down Expand Up @@ -684,7 +722,6 @@ std::unique_ptr<parser::Node> Translator::translate(pm_node_t *node) {
case PM_SOURCE_FILE_NODE:
case PM_SOURCE_LINE_NODE:
case PM_UNDEF_NODE:
case PM_WHEN_NODE:
case PM_WHILE_NODE:
case PM_X_STRING_NODE:
case PM_SCOPE_NODE:
Expand Down
98 changes: 98 additions & 0 deletions test/prism_regression/case.parse-tree.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
Begin {
stmts = [
DefMethod {
name = <U foo>
args = NULL
body = NULL
}
Case {
condition = Send {
receiver = NULL
method = <U foo>
args = [
]
}
whens = [
When {
patterns = [
Integer {
val = "1"
}
]
body = Send {
receiver = NULL
method = <U puts>
args = [
String {
val = <U one!>
}
]
}
}
When {
patterns = [
Integer {
val = "2"
}
Integer {
val = "3"
}
]
body = Send {
receiver = NULL
method = <U puts>
args = [
String {
val = <U two or three!>
}
]
}
}
]
else_ = Send {
receiver = NULL
method = <U puts>
args = [
String {
val = <U Who knows!>
}
]
}
}
Case {
condition = Send {
receiver = NULL
method = <U foo>
args = [
]
}
whens = [
When {
patterns = [
Const {
scope = NULL
name = <C <U Integer>>
}
]
body = Begin {
stmts = [
Integer {
val = "4"
}
Send {
receiver = NULL
method = <U puts>
args = [
String {
val = <U surprise, multi-line!>
}
]
}
]
}
}
]
else_ = NULL
}
]
}
19 changes: 19 additions & 0 deletions test/prism_regression/case.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# typed: true

def foo; end

case foo
when 1
puts "one!"
when 2, 3
puts "two or three!"
else
puts "Who knows!"
end

# no else
case foo
when Integer
4
puts "surprise, multi-line!"
end

0 comments on commit 2e05551

Please sign in to comment.