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)); |
