diff options
Diffstat (limited to 'src/MoonP/moon_compiler.cpp')
-rw-r--r-- | src/MoonP/moon_compiler.cpp | 62 |
1 files changed, 42 insertions, 20 deletions
diff --git a/src/MoonP/moon_compiler.cpp b/src/MoonP/moon_compiler.cpp index 6b721f1..24e4a97 100644 --- a/src/MoonP/moon_compiler.cpp +++ b/src/MoonP/moon_compiler.cpp | |||
@@ -53,7 +53,7 @@ inline std::string s(std::string_view sv) { | |||
53 | return std::string(sv); | 53 | return std::string(sv); |
54 | } | 54 | } |
55 | 55 | ||
56 | const std::string_view version = "0.6.2"sv; | 56 | const std::string_view version = "0.6.3"sv; |
57 | const std::string_view extension = "mp"sv; | 57 | const std::string_view extension = "mp"sv; |
58 | 58 | ||
59 | class MoonCompilerImpl { | 59 | class MoonCompilerImpl { |
@@ -516,6 +516,18 @@ private: | |||
516 | return nullptr; | 516 | return nullptr; |
517 | } | 517 | } |
518 | 518 | ||
519 | Statement_t* lastStatementFrom(ast_node* body) const { | ||
520 | switch (body->getId()) { | ||
521 | case id<Block_t>(): | ||
522 | return lastStatementFrom(static_cast<Block_t*>(body)); | ||
523 | case id<Statement_t>(): { | ||
524 | return static_cast<Statement_t*>(body); | ||
525 | } | ||
526 | default: assert(false); break; | ||
527 | } | ||
528 | return nullptr; | ||
529 | } | ||
530 | |||
519 | Statement_t* lastStatementFrom(const node_container& stmts) const { | 531 | Statement_t* lastStatementFrom(const node_container& stmts) const { |
520 | if (!stmts.empty()) { | 532 | if (!stmts.empty()) { |
521 | auto it = stmts.end(); --it; | 533 | auto it = stmts.end(); --it; |
@@ -803,9 +815,7 @@ private: | |||
803 | 815 | ||
804 | auto stmt = x->new_ptr<Statement_t>(); | 816 | auto stmt = x->new_ptr<Statement_t>(); |
805 | stmt->content.set(statement->content); | 817 | stmt->content.set(statement->content); |
806 | auto body = x->new_ptr<Body_t>(); | 818 | ifNode->nodes.push_back(stmt); |
807 | body->content.set(stmt); | ||
808 | ifNode->nodes.push_back(body); | ||
809 | 819 | ||
810 | statement->appendix.set(nullptr); | 820 | statement->appendix.set(nullptr); |
811 | auto simpleValue = x->new_ptr<SimpleValue_t>(); | 821 | auto simpleValue = x->new_ptr<SimpleValue_t>(); |
@@ -830,9 +840,7 @@ private: | |||
830 | 840 | ||
831 | auto stmt = x->new_ptr<Statement_t>(); | 841 | auto stmt = x->new_ptr<Statement_t>(); |
832 | stmt->content.set(statement->content); | 842 | stmt->content.set(statement->content); |
833 | auto body = x->new_ptr<Body_t>(); | 843 | unless->nodes.push_back(stmt); |
834 | body->content.set(stmt); | ||
835 | unless->nodes.push_back(body); | ||
836 | 844 | ||
837 | statement->appendix.set(nullptr); | 845 | statement->appendix.set(nullptr); |
838 | auto simpleValue = x->new_ptr<SimpleValue_t>(); | 846 | auto simpleValue = x->new_ptr<SimpleValue_t>(); |
@@ -1593,9 +1601,7 @@ private: | |||
1593 | expListAssign->expList.set(expList); | 1601 | expListAssign->expList.set(expList); |
1594 | auto stmt = x->new_ptr<Statement_t>(); | 1602 | auto stmt = x->new_ptr<Statement_t>(); |
1595 | stmt->content.set(expListAssign); | 1603 | stmt->content.set(expListAssign); |
1596 | auto body = x->new_ptr<Body_t>(); | 1604 | ns.push_back(stmt.get()); |
1597 | body->content.set(stmt); | ||
1598 | ns.push_back(body.get()); | ||
1599 | } | 1605 | } |
1600 | } | 1606 | } |
1601 | } | 1607 | } |
@@ -1614,15 +1620,16 @@ private: | |||
1614 | pushScope(); | 1620 | pushScope(); |
1615 | _enableReturn.push(true); | 1621 | _enableReturn.push(true); |
1616 | } | 1622 | } |
1617 | std::list<std::pair<IfCond_t*, Body_t*>> ifCondPairs; | 1623 | std::list<std::pair<IfCond_t*, ast_node*>> ifCondPairs; |
1618 | ifCondPairs.emplace_back(); | 1624 | ifCondPairs.emplace_back(); |
1619 | for (auto node : nodes) { | 1625 | for (auto node : nodes) { |
1620 | switch (node->getId()) { | 1626 | switch (node->getId()) { |
1621 | case id<IfCond_t>(): | 1627 | case id<IfCond_t>(): |
1622 | ifCondPairs.back().first = static_cast<IfCond_t*>(node); | 1628 | ifCondPairs.back().first = static_cast<IfCond_t*>(node); |
1623 | break; | 1629 | break; |
1624 | case id<Body_t>(): | 1630 | case id<Block_t>(): |
1625 | ifCondPairs.back().second = static_cast<Body_t*>(node); | 1631 | case id<Statement_t>(): |
1632 | ifCondPairs.back().second = node; | ||
1626 | ifCondPairs.emplace_back(); | 1633 | ifCondPairs.emplace_back(); |
1627 | break; | 1634 | break; |
1628 | default: assert(false); break; | 1635 | default: assert(false); break; |
@@ -1718,7 +1725,7 @@ private: | |||
1718 | if (pair == ifCondPairs.front() && extraAssignment) { | 1725 | if (pair == ifCondPairs.front() && extraAssignment) { |
1719 | transformAssignment(extraAssignment, temp); | 1726 | transformAssignment(extraAssignment, temp); |
1720 | } | 1727 | } |
1721 | transformBody(pair.second, temp, usage, assignList); | 1728 | transform_plain_body(pair.second, temp, usage, assignList); |
1722 | popScope(); | 1729 | popScope(); |
1723 | } | 1730 | } |
1724 | if (!pair.first) { | 1731 | if (!pair.first) { |
@@ -3945,7 +3952,22 @@ private: | |||
3945 | out.push_back(clearBuf()); | 3952 | out.push_back(clearBuf()); |
3946 | } | 3953 | } |
3947 | 3954 | ||
3948 | void transformLoopBody(Body_t* body, str_list& out, const std::string& appendContent, ExpUsage usage, ExpList_t* assignList = nullptr) { | 3955 | void transform_plain_body(ast_node* body, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { |
3956 | switch (body->getId()) { | ||
3957 | case id<Block_t>(): | ||
3958 | transformBlock(static_cast<Block_t*>(body), out, usage, assignList); | ||
3959 | break; | ||
3960 | case id<Statement_t>(): { | ||
3961 | auto newBlock = body->new_ptr<Block_t>(); | ||
3962 | newBlock->statements.push_back(body); | ||
3963 | transformBlock(newBlock, out, usage, assignList); | ||
3964 | break; | ||
3965 | } | ||
3966 | default: assert(false); break; | ||
3967 | } | ||
3968 | } | ||
3969 | |||
3970 | void transformLoopBody(ast_node* body, str_list& out, const std::string& appendContent, ExpUsage usage, ExpList_t* assignList = nullptr) { | ||
3949 | str_list temp; | 3971 | str_list temp; |
3950 | bool withContinue = traversal::Stop == body->traverse([&](ast_node* node) { | 3972 | bool withContinue = traversal::Stop == body->traverse([&](ast_node* node) { |
3951 | if (auto stmt = ast_cast<Statement_t>(node)) { | 3973 | if (auto stmt = ast_cast<Statement_t>(node)) { |
@@ -3968,7 +3990,7 @@ private: | |||
3968 | _continueVars.push(continueVar); | 3990 | _continueVars.push(continueVar); |
3969 | pushScope(); | 3991 | pushScope(); |
3970 | } | 3992 | } |
3971 | transformBody(body, temp, usage, assignList); | 3993 | transform_plain_body(body, temp, usage, assignList); |
3972 | if (withContinue) { | 3994 | if (withContinue) { |
3973 | if (!appendContent.empty()) { | 3995 | if (!appendContent.empty()) { |
3974 | _buf << indent() << appendContent; | 3996 | _buf << indent() << appendContent; |
@@ -4739,7 +4761,7 @@ private: | |||
4739 | ifNode->nodes.push_back(with->body); | 4761 | ifNode->nodes.push_back(with->body); |
4740 | transformIf(ifNode, temp, ExpUsage::Common); | 4762 | transformIf(ifNode, temp, ExpUsage::Common); |
4741 | } else { | 4763 | } else { |
4742 | transformBody(with->body, temp, ExpUsage::Common); | 4764 | transform_plain_body(with->body, temp, ExpUsage::Common); |
4743 | } | 4765 | } |
4744 | _withVars.pop(); | 4766 | _withVars.pop(); |
4745 | if (assignList) { | 4767 | if (assignList) { |
@@ -5401,7 +5423,7 @@ private: | |||
5401 | void transformRepeat(Repeat_t* repeat, str_list& out) { | 5423 | void transformRepeat(Repeat_t* repeat, str_list& out) { |
5402 | str_list temp; | 5424 | str_list temp; |
5403 | pushScope(); | 5425 | pushScope(); |
5404 | transformLoopBody(repeat->body, temp, Empty, ExpUsage::Common); | 5426 | transformLoopBody(repeat->body->content, temp, Empty, ExpUsage::Common); |
5405 | transformExp(repeat->condition, temp, ExpUsage::Closure); | 5427 | transformExp(repeat->condition, temp, ExpUsage::Closure); |
5406 | popScope(); | 5428 | popScope(); |
5407 | _buf << indent() << "repeat"sv << nll(repeat); | 5429 | _buf << indent() << "repeat"sv << nll(repeat); |
@@ -5442,13 +5464,13 @@ private: | |||
5442 | } | 5464 | } |
5443 | temp.back().append(s(" then"sv) + nll(branch)); | 5465 | temp.back().append(s(" then"sv) + nll(branch)); |
5444 | pushScope(); | 5466 | pushScope(); |
5445 | transformBody(branch->body, temp, usage, assignList); | 5467 | transform_plain_body(branch->body, temp, usage, assignList); |
5446 | popScope(); | 5468 | popScope(); |
5447 | } | 5469 | } |
5448 | if (switchNode->lastBranch) { | 5470 | if (switchNode->lastBranch) { |
5449 | temp.push_back(indent() + s("else"sv) + nll(switchNode->lastBranch)); | 5471 | temp.push_back(indent() + s("else"sv) + nll(switchNode->lastBranch)); |
5450 | pushScope(); | 5472 | pushScope(); |
5451 | transformBody(switchNode->lastBranch, temp, usage, assignList); | 5473 | transform_plain_body(switchNode->lastBranch, temp, usage, assignList); |
5452 | popScope(); | 5474 | popScope(); |
5453 | } | 5475 | } |
5454 | temp.push_back(indent() + s("end"sv) + nlr(switchNode)); | 5476 | temp.push_back(indent() + s("end"sv) + nlr(switchNode)); |