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