Skip to content

Commit

Permalink
Merge pull request #31 from Shopify/emily/if-node
Browse files Browse the repository at this point in the history
Implement Prism → Sorbet conversion for `True`, `False`, and `If` nodes
  • Loading branch information
egiurleo authored Jul 29, 2024
2 parents 12195ec + 529367c commit 44e414f
Show file tree
Hide file tree
Showing 11 changed files with 102 additions and 24 deletions.
70 changes: 46 additions & 24 deletions main/pipeline/pipeline.cc
Original file line number Diff line number Diff line change
Expand Up @@ -157,14 +157,35 @@ core::LocOffsets locOffset(pm_location_t *loc, pm_parser_t *parser) {
return core::LocOffsets{locStart, locEnd};
}

const unique_ptr<parser::Node> convertPrismToSorbet(pm_node_t *node, pm_parser_t *parser, core::GlobalState &gs) {
unique_ptr<parser::Node> convertPrismToSorbet(pm_node_t *node, pm_parser_t *parser, core::GlobalState &gs) {
switch (PM_NODE_TYPE(node)) {
case PM_FALSE_NODE: {
auto falseNode = reinterpret_cast<pm_false_node *>(node);
pm_location_t *loc = &falseNode->base.location;

return make_unique<parser::False>(locOffset(loc, parser));
}
case PM_FLOAT_NODE: {
auto floatNode = reinterpret_cast<pm_float_node *>(node);
pm_location_t *loc = &floatNode->base.location;

return make_unique<parser::Float>(locOffset(loc, parser), std::to_string(floatNode->value));
}
case PM_IF_NODE: {
auto ifNode = reinterpret_cast<pm_if_node *>(node);
auto *loc = &ifNode->base.location;

auto predicate = convertPrismToSorbet(ifNode->predicate, parser, gs);

std::unique_ptr<parser::Node> ifTrue;

if (ifNode->statements != nullptr) {
ifTrue = convertPrismToSorbet(reinterpret_cast<pm_node *>(ifNode->statements), parser, gs);
}

// TODO: handle elsif/else clause
return make_unique<parser::If>(locOffset(loc, parser), std::move(predicate), std::move(ifTrue), nullptr);
}
case PM_INTEGER_NODE: {
auto intNode = reinterpret_cast<pm_integer_node *>(node);
pm_location_t *loc = &intNode->base.location;
Expand All @@ -174,12 +195,25 @@ const unique_ptr<parser::Node> convertPrismToSorbet(pm_node_t *node, pm_parser_t
}
case PM_PROGRAM_NODE: {
pm_program_node *programNode = reinterpret_cast<pm_program_node *>(node);
pm_statements_node *stmts = programNode->statements;

auto size = stmts->body.size;
return convertPrismToSorbet(reinterpret_cast<pm_node *>(programNode->statements), parser, gs);
}
case PM_RATIONAL_NODE: {
auto *rationalNode = reinterpret_cast<pm_rational_node *>(node);
pm_location_t *loc = &rationalNode->base.location;

const uint8_t *start = rationalNode->numeric->location.start;
const uint8_t *end = rationalNode->numeric->location.end;

std::string value = std::string(reinterpret_cast<const char *>(start), end - start);

return make_unique<parser::Rational>(locOffset(loc, parser), value);
}
case PM_STATEMENTS_NODE: {
pm_statements_node *stmts = reinterpret_cast<pm_statements_node *>(node);

// For a single statement, do not create a Begin node and just return the statement
if (size == 1) {
if (stmts->body.size == 1) {
return convertPrismToSorbet((pm_node *)stmts->body.nodes[0], parser, gs);
}

Expand All @@ -192,26 +226,10 @@ const unique_ptr<parser::Node> convertPrismToSorbet(pm_node_t *node, pm_parser_t
sorbetStmts.emplace_back(std::move(convertedStmt));
}

auto *loc = &programNode->base.location;
auto *loc = &stmts->base.location;

return make_unique<parser::Begin>(locOffset(loc, parser), std::move(sorbetStmts));
}
case PM_RATIONAL_NODE: {
auto *rationalNode = reinterpret_cast<pm_rational_node *>(node);
pm_location_t *loc = &rationalNode->base.location;

const uint8_t *start = rationalNode->numeric->location.start;
const uint8_t *end = rationalNode->numeric->location.end;

std::string value = std::string(reinterpret_cast<const char *>(start), end - start);

return make_unique<parser::Rational>(locOffset(loc, parser), value);

break;
}
case PM_STATEMENTS_NODE: {
Exception::raise("Handling for statements node should be performed in program node");
}
case PM_STRING_NODE: {
auto strNode = reinterpret_cast<pm_string_node *>(node);
pm_location_t *loc = &strNode->base.location;
Expand All @@ -223,6 +241,13 @@ const unique_ptr<parser::Node> convertPrismToSorbet(pm_node_t *node, pm_parser_t
// TODO: handle different string encodings
return make_unique<parser::String>(locOffset(loc, parser), gs.enterNameUTF8(source));
}
case PM_TRUE_NODE: {
auto trueNode = reinterpret_cast<pm_true_node *>(node);
pm_location_t *loc = &trueNode->base.location;

return make_unique<parser::True>(locOffset(loc, parser));
}

case PM_ALIAS_GLOBAL_VARIABLE_NODE:
case PM_ALIAS_METHOD_NODE:
case PM_ALTERNATION_PATTERN_NODE:
Expand Down Expand Up @@ -273,7 +298,6 @@ const unique_ptr<parser::Node> convertPrismToSorbet(pm_node_t *node, pm_parser_t
case PM_EMBEDDED_STATEMENTS_NODE:
case PM_EMBEDDED_VARIABLE_NODE:
case PM_ENSURE_NODE:
case PM_FALSE_NODE:
case PM_FIND_PATTERN_NODE:
case PM_FLIP_FLOP_NODE:
case PM_FOR_NODE:
Expand All @@ -288,7 +312,6 @@ const unique_ptr<parser::Node> convertPrismToSorbet(pm_node_t *node, pm_parser_t
case PM_GLOBAL_VARIABLE_WRITE_NODE:
case PM_HASH_NODE:
case PM_HASH_PATTERN_NODE:
case PM_IF_NODE:
case PM_IMAGINARY_NODE:
case PM_IMPLICIT_NODE:
case PM_IMPLICIT_REST_NODE:
Expand Down Expand Up @@ -359,7 +382,6 @@ const unique_ptr<parser::Node> convertPrismToSorbet(pm_node_t *node, pm_parser_t
case PM_SPLAT_NODE:
case PM_SUPER_NODE:
case PM_SYMBOL_NODE:
case PM_TRUE_NODE:
case PM_UNDEF_NODE:
case PM_UNLESS_NODE:
case PM_UNTIL_NODE:
Expand Down
2 changes: 2 additions & 0 deletions test/prism_regression/false.parse-tree.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
False {
}
3 changes: 3 additions & 0 deletions test/prism_regression/false.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# typed: strict

false
6 changes: 6 additions & 0 deletions test/prism_regression/if.parse-tree.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
If {
condition = True {
}
then_ = NULL
else_ = NULL
}
3 changes: 3 additions & 0 deletions test/prism_regression/if.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# typed: strict

if true; end
8 changes: 8 additions & 0 deletions test/prism_regression/if_with_stmt.parse-tree.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
If {
condition = False {
}
then_ = Integer {
val = "5"
}
else_ = NULL
}
5 changes: 5 additions & 0 deletions test/prism_regression/if_with_stmt.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# typed: static

if false
5
end
17 changes: 17 additions & 0 deletions test/prism_regression/if_with_stmts.parse-tree.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
If {
condition = True {
}
then_ = Begin {
stmts = [
True {
}
Integer {
val = "4"
}
String {
val = <U string>
}
]
}
else_ = NULL
}
7 changes: 7 additions & 0 deletions test/prism_regression/if_with_stmts.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# typed: strict

if true
true
4
"string"
end
2 changes: 2 additions & 0 deletions test/prism_regression/true.parse-tree.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
True {
}
3 changes: 3 additions & 0 deletions test/prism_regression/true.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# typed: strict

true

0 comments on commit 44e414f

Please sign in to comment.