diff options
Diffstat (limited to 'src/MoonP/moon_compiler.cpp')
-rw-r--r-- | src/MoonP/moon_compiler.cpp | 138 |
1 files changed, 131 insertions, 7 deletions
diff --git a/src/MoonP/moon_compiler.cpp b/src/MoonP/moon_compiler.cpp index 4723af4..6173389 100644 --- a/src/MoonP/moon_compiler.cpp +++ b/src/MoonP/moon_compiler.cpp | |||
@@ -739,6 +739,23 @@ private: | |||
739 | break; | 739 | break; |
740 | } | 740 | } |
741 | } | 741 | } |
742 | } else if (expList->exprs.size() == 1){ | ||
743 | auto exp = static_cast<Exp_t*>(expList->exprs.back()); | ||
744 | if (exp->opValues.size() > 0) { | ||
745 | bool backcall = true; | ||
746 | for (auto _opValue : exp->opValues.objects()) { | ||
747 | auto opValue = static_cast<exp_op_value_t*>(_opValue); | ||
748 | if (!opValue->op.is<BackcallOperator_t>()) { | ||
749 | backcall = false; | ||
750 | break; | ||
751 | } | ||
752 | } | ||
753 | if (backcall) { | ||
754 | transformExp(exp, out); | ||
755 | out.back().append(nll(exp)); | ||
756 | break; | ||
757 | } | ||
758 | } | ||
742 | } | 759 | } |
743 | throw std::logic_error(debugInfo("Expression list must appear at the end of body block."sv, expList)); | 760 | throw std::logic_error(debugInfo("Expression list must appear at the end of body block."sv, expList)); |
744 | } | 761 | } |
@@ -1593,11 +1610,55 @@ private: | |||
1593 | } | 1610 | } |
1594 | 1611 | ||
1595 | void transformExp(Exp_t* exp, str_list& out) { | 1612 | void transformExp(Exp_t* exp, str_list& out) { |
1613 | auto x = exp; | ||
1614 | const auto& opValues = exp->opValues.objects(); | ||
1615 | for (auto it = opValues.begin(); it != opValues.end(); ++it) { | ||
1616 | auto opValue = static_cast<exp_op_value_t*>(*it); | ||
1617 | if (opValue->op.is<BackcallOperator_t>()) { | ||
1618 | if (auto chainValue = opValue->value->item.as<ChainValue_t>()) { | ||
1619 | auto newExp = x->new_ptr<Exp_t>(); | ||
1620 | { | ||
1621 | auto arg = x->new_ptr<Exp_t>(); | ||
1622 | arg->value.set(exp->value); | ||
1623 | for (auto i = opValues.begin(); i != it; ++i) { | ||
1624 | arg->opValues.push_back(*i); | ||
1625 | } | ||
1626 | auto next = it; ++next; | ||
1627 | for (auto i = next; i != opValues.end(); ++i) { | ||
1628 | newExp->opValues.push_back(*i); | ||
1629 | } | ||
1630 | if (isChainValueCall(chainValue)) { | ||
1631 | auto last = chainValue->items.back(); | ||
1632 | if (auto invoke = ast_cast<InvokeArgs_t>(last)) { | ||
1633 | invoke->args.push_front(arg); | ||
1634 | } else { | ||
1635 | ast_to<Invoke_t>(last)->args.push_front(arg); | ||
1636 | } | ||
1637 | } else { | ||
1638 | auto invoke = x->new_ptr<Invoke_t>(); | ||
1639 | invoke->args.push_front(arg); | ||
1640 | chainValue->items.push_back(invoke); | ||
1641 | } | ||
1642 | auto value = x->new_ptr<Value_t>(); | ||
1643 | value->item.set(chainValue); | ||
1644 | newExp->value.set(value); | ||
1645 | } | ||
1646 | transformExp(newExp, out); | ||
1647 | return; | ||
1648 | } else { | ||
1649 | throw std::logic_error(debugInfo("Backcall operator must be followed by chain value."sv, opValue->value)); | ||
1650 | } | ||
1651 | } | ||
1652 | } | ||
1596 | str_list temp; | 1653 | str_list temp; |
1597 | transformValue(exp->value, temp); | 1654 | transformValue(exp->value, temp); |
1598 | for (auto _opValue : exp->opValues.objects()) { | 1655 | for (auto _opValue : exp->opValues.objects()) { |
1599 | auto opValue = static_cast<exp_op_value_t*>(_opValue); | 1656 | auto opValue = static_cast<exp_op_value_t*>(_opValue); |
1600 | transformBinaryOperator(opValue->op, temp); | 1657 | if (auto op = opValue->op.as<BinaryOperator_t>()) { |
1658 | transformBinaryOperator(op, temp); | ||
1659 | } else { | ||
1660 | temp.push_back(s("|>"sv)); | ||
1661 | } | ||
1601 | transformValue(opValue->value, temp); | 1662 | transformValue(opValue->value, temp); |
1602 | } | 1663 | } |
1603 | out.push_back(join(temp, " "sv)); | 1664 | out.push_back(join(temp, " "sv)); |
@@ -1731,8 +1792,68 @@ private: | |||
1731 | void transformCodes(const node_container& nodes, str_list& out, bool implicitReturn) { | 1792 | void transformCodes(const node_container& nodes, str_list& out, bool implicitReturn) { |
1732 | LocalMode mode = LocalMode::None; | 1793 | LocalMode mode = LocalMode::None; |
1733 | Local_t* any = nullptr, *capital = nullptr; | 1794 | Local_t* any = nullptr, *capital = nullptr; |
1734 | for (auto node : nodes) { | 1795 | for (auto it = nodes.begin(); it != nodes.end(); ++it) { |
1796 | auto node = *it; | ||
1735 | auto stmt = static_cast<Statement_t*>(node); | 1797 | auto stmt = static_cast<Statement_t*>(node); |
1798 | if (auto backcall = stmt->content.as<Backcall_t>()) { | ||
1799 | auto x = *nodes.begin(); | ||
1800 | auto newBlock = x->new_ptr<Block_t>(); | ||
1801 | if (it != nodes.begin()) { | ||
1802 | for (auto i = nodes.begin(); i != it; ++i) { | ||
1803 | newBlock->statements.push_back(*i); | ||
1804 | } | ||
1805 | } | ||
1806 | x = backcall; | ||
1807 | auto arg = x->new_ptr<Exp_t>(); | ||
1808 | { | ||
1809 | auto block = x->new_ptr<Block_t>(); | ||
1810 | auto next = it; ++next; | ||
1811 | if (next != nodes.end()) { | ||
1812 | for (auto i = next; i != nodes.end(); ++i) { | ||
1813 | block->statements.push_back(*i); | ||
1814 | } | ||
1815 | } | ||
1816 | auto body = x->new_ptr<Body_t>(); | ||
1817 | body->content.set(block); | ||
1818 | auto funLit = x->new_ptr<FunLit_t>(); | ||
1819 | funLit->argsDef.set(backcall->argsDef); | ||
1820 | funLit->arrow.set(toAst<fn_arrow_t>("->"sv, fn_arrow, x)); | ||
1821 | funLit->body.set(body); | ||
1822 | auto simpleValue = x->new_ptr<SimpleValue_t>(); | ||
1823 | simpleValue->value.set(funLit); | ||
1824 | auto value = x->new_ptr<Value_t>(); | ||
1825 | value->item.set(simpleValue); | ||
1826 | arg->value.set(value); | ||
1827 | } | ||
1828 | if (isChainValueCall(backcall->value)) { | ||
1829 | auto last = backcall->value->items.back(); | ||
1830 | if (auto invoke = ast_cast<Invoke_t>(last)) { | ||
1831 | invoke->args.push_back(arg); | ||
1832 | } else { | ||
1833 | ast_to<InvokeArgs_t>(last)->args.push_back(arg); | ||
1834 | } | ||
1835 | } else { | ||
1836 | auto invoke = x->new_ptr<Invoke_t>(); | ||
1837 | invoke->args.push_back(arg); | ||
1838 | backcall->value->items.push_back(invoke); | ||
1839 | } | ||
1840 | auto newStmt = x->new_ptr<Statement_t>(); | ||
1841 | { | ||
1842 | auto chainValue = backcall->value.get(); | ||
1843 | auto value = x->new_ptr<Value_t>(); | ||
1844 | value->item.set(chainValue); | ||
1845 | auto exp = x->new_ptr<Exp_t>(); | ||
1846 | exp->value.set(value); | ||
1847 | auto expList = x->new_ptr<ExpList_t>(); | ||
1848 | expList->exprs.push_back(exp); | ||
1849 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); | ||
1850 | expListAssign->expList.set(expList); | ||
1851 | newStmt->content.set(expListAssign); | ||
1852 | newBlock->statements.push_back(newStmt); | ||
1853 | } | ||
1854 | transformBlock(newBlock, out, implicitReturn); | ||
1855 | return; | ||
1856 | } | ||
1736 | if (auto local = stmt->content.as<Local_t>()) { | 1857 | if (auto local = stmt->content.as<Local_t>()) { |
1737 | if (auto flag = local->name.as<local_flag_t>()) { | 1858 | if (auto flag = local->name.as<local_flag_t>()) { |
1738 | LocalMode newMode = toString(flag) == "*"sv ? LocalMode::Any : LocalMode::Capital; | 1859 | LocalMode newMode = toString(flag) == "*"sv ? LocalMode::Any : LocalMode::Capital; |
@@ -1802,9 +1923,10 @@ private: | |||
1802 | } | 1923 | } |
1803 | } | 1924 | } |
1804 | if (implicitReturn) { | 1925 | if (implicitReturn) { |
1926 | BLOCK_START | ||
1927 | BREAK_IF(nodes.empty()); | ||
1805 | auto last = static_cast<Statement_t*>(nodes.back()); | 1928 | auto last = static_cast<Statement_t*>(nodes.back()); |
1806 | auto x = last; | 1929 | auto x = last; |
1807 | BLOCK_START | ||
1808 | auto expList = expListFrom(last); | 1930 | auto expList = expListFrom(last); |
1809 | BREAK_IF(!expList || | 1931 | BREAK_IF(!expList || |
1810 | (last->appendix && | 1932 | (last->appendix && |
@@ -1816,11 +1938,13 @@ private: | |||
1816 | last->content.set(returnNode); | 1938 | last->content.set(returnNode); |
1817 | BLOCK_END | 1939 | BLOCK_END |
1818 | } | 1940 | } |
1819 | str_list temp; | 1941 | if (!nodes.empty()) { |
1820 | for (auto node : nodes) { | 1942 | str_list temp; |
1821 | transformStatement(static_cast<Statement_t*>(node), temp); | 1943 | for (auto node : nodes) { |
1944 | transformStatement(static_cast<Statement_t*>(node), temp); | ||
1945 | } | ||
1946 | out.push_back(join(temp)); | ||
1822 | } | 1947 | } |
1823 | out.push_back(join(temp)); | ||
1824 | } | 1948 | } |
1825 | 1949 | ||
1826 | void transformBody(Body_t* body, str_list& out, bool implicitReturn = false) { | 1950 | void transformBody(Body_t* body, str_list& out, bool implicitReturn = false) { |