aboutsummaryrefslogtreecommitdiff
path: root/src/MoonP/moon_compiler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/MoonP/moon_compiler.cpp')
-rw-r--r--src/MoonP/moon_compiler.cpp138
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) {