diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/MoonP/moon_compiler.cpp | 133 |
1 files changed, 94 insertions, 39 deletions
diff --git a/src/MoonP/moon_compiler.cpp b/src/MoonP/moon_compiler.cpp index 264ddc7..ca0ab5b 100644 --- a/src/MoonP/moon_compiler.cpp +++ b/src/MoonP/moon_compiler.cpp | |||
| @@ -447,7 +447,14 @@ private: | |||
| 447 | BREAK_IF(!chainValue); | 447 | BREAK_IF(!chainValue); |
| 448 | BREAK_IF(chainValue->items.size() != 1); | 448 | BREAK_IF(chainValue->items.size() != 1); |
| 449 | auto callable = ast_cast<Callable_t>(chainValue->items.front()); | 449 | auto callable = ast_cast<Callable_t>(chainValue->items.front()); |
| 450 | BREAK_IF(!callable || !(callable->item.is<Variable_t>() || callable->getByPath<SelfName_t,self_t>())); | 450 | BREAK_IF(!callable); |
| 451 | ast_node* var = callable->item.as<Variable_t>(); | ||
| 452 | if (!var) { | ||
| 453 | if (auto self = callable->item.as<SelfName_t>()) { | ||
| 454 | var = self->name.as<self_t>(); | ||
| 455 | } | ||
| 456 | } | ||
| 457 | BREAK_IF(!var); | ||
| 451 | str_list tmp; | 458 | str_list tmp; |
| 452 | transformCallable(callable, tmp); | 459 | transformCallable(callable, tmp); |
| 453 | return tmp.back(); | 460 | return tmp.back(); |
| @@ -757,9 +764,13 @@ private: | |||
| 757 | BREAK_IF(chain->items.size() != 1); | 764 | BREAK_IF(chain->items.size() != 1); |
| 758 | auto callable = ast_cast<Callable_t>(chain->items.front()); | 765 | auto callable = ast_cast<Callable_t>(chain->items.front()); |
| 759 | BREAK_IF(!callable); | 766 | BREAK_IF(!callable); |
| 760 | auto var = callable->item.as<Variable_t>(); | 767 | std::string name; |
| 761 | BREAK_IF(!var); | 768 | if (auto var = callable->item.as<Variable_t>()) { |
| 762 | auto name = toString(var); | 769 | name = toString(var); |
| 770 | } else if (auto self = callable->item.as<SelfName_t>()) { | ||
| 771 | if (self->name.is<self_t>()) name = "self"sv; | ||
| 772 | } | ||
| 773 | BREAK_IF(name.empty()); | ||
| 763 | if (!isDefined(name)) { | 774 | if (!isDefined(name)) { |
| 764 | preDefs.push_back(name); | 775 | preDefs.push_back(name); |
| 765 | } | 776 | } |
| @@ -782,9 +793,13 @@ private: | |||
| 782 | BREAK_IF(chain->items.size() != 1); | 793 | BREAK_IF(chain->items.size() != 1); |
| 783 | auto callable = ast_cast<Callable_t>(chain->items.front()); | 794 | auto callable = ast_cast<Callable_t>(chain->items.front()); |
| 784 | BREAK_IF(!callable); | 795 | BREAK_IF(!callable); |
| 785 | auto var = callable->item.as<Variable_t>(); | 796 | std::string name; |
| 786 | BREAK_IF(!var); | 797 | if (auto var = callable->item.as<Variable_t>()) { |
| 787 | auto name = toString(var); | 798 | name = toString(var); |
| 799 | } else if (auto self = callable->item.as<SelfName_t>()) { | ||
| 800 | if (self->name.is<self_t>()) name = "self"sv; | ||
| 801 | } | ||
| 802 | BREAK_IF(name.empty()); | ||
| 788 | if (addToScope(name)) { | 803 | if (addToScope(name)) { |
| 789 | preDefs.push_back(name); | 804 | preDefs.push_back(name); |
| 790 | } | 805 | } |
| @@ -823,7 +838,7 @@ private: | |||
| 823 | if (preDefine.empty()) { | 838 | if (preDefine.empty()) { |
| 824 | preDefine = getPredefine(transformAssignDefs(assignment->expList)); | 839 | preDefine = getPredefine(transformAssignDefs(assignment->expList)); |
| 825 | } | 840 | } |
| 826 | return preDefine.empty() ? preDefine : preDefine + nll(assignment); | 841 | return preDefine; |
| 827 | } | 842 | } |
| 828 | 843 | ||
| 829 | ExpList_t* expListFrom(Statement_t* statement) { | 844 | ExpList_t* expListFrom(Statement_t* statement) { |
| @@ -917,7 +932,7 @@ private: | |||
| 917 | } | 932 | } |
| 918 | std::string preDefine = getPredefine(assignment); | 933 | std::string preDefine = getPredefine(assignment); |
| 919 | transformSwitch(switchNode, out); | 934 | transformSwitch(switchNode, out); |
| 920 | out.back() = preDefine + out.back(); | 935 | out.back().insert(0, preDefine.empty() ? Empty : preDefine + nll(assignment)); |
| 921 | return; | 936 | return; |
| 922 | } | 937 | } |
| 923 | case "With"_id: { | 938 | case "With"_id: { |
| @@ -925,58 +940,58 @@ private: | |||
| 925 | auto expList = assignment->expList.get(); | 940 | auto expList = assignment->expList.get(); |
| 926 | std::string preDefine = getPredefine(assignment); | 941 | std::string preDefine = getPredefine(assignment); |
| 927 | transformWith(withNode, out, expList); | 942 | transformWith(withNode, out, expList); |
| 928 | out.back() = preDefine + out.back(); | 943 | out.back().insert(0, preDefine.empty() ? Empty : preDefine + nll(assignment)); |
| 929 | return; | 944 | return; |
| 930 | } | 945 | } |
| 931 | case "Do"_id: { | 946 | case "Do"_id: { |
| 932 | auto doNode = static_cast<Do_t*>(value); | ||
| 933 | auto expList = assignment->expList.get(); | 947 | auto expList = assignment->expList.get(); |
| 948 | auto doNode = static_cast<Do_t*>(value); | ||
| 934 | assignLastExplist(expList, doNode->body); | 949 | assignLastExplist(expList, doNode->body); |
| 935 | std::string preDefine = getPredefine(assignment); | 950 | std::string preDefine = getPredefine(assignment); |
| 936 | transformDo(doNode, out); | 951 | transformDo(doNode, out); |
| 937 | out.back() = preDefine + out.back(); | 952 | out.back().insert(0, preDefine.empty() ? Empty : preDefine + nll(assignment)); |
| 938 | return; | 953 | return; |
| 939 | } | 954 | } |
| 940 | case "Comprehension"_id: { | 955 | case "Comprehension"_id: { |
| 941 | auto expList = assignment->expList.get(); | 956 | auto expList = assignment->expList.get(); |
| 942 | std::string preDefine = getPredefine(assignment); | 957 | std::string preDefine = getPredefine(assignment); |
| 943 | transformComprehension(static_cast<Comprehension_t*>(value), out, ExpUsage::Assignment, expList); | 958 | transformComprehension(static_cast<Comprehension_t*>(value), out, ExpUsage::Assignment, expList); |
| 944 | out.back() = preDefine + out.back(); | 959 | out.back().insert(0, preDefine.empty() ? Empty : preDefine + nll(assignment)); |
| 945 | return; | 960 | return; |
| 946 | } | 961 | } |
| 947 | case "TblComprehension"_id: { | 962 | case "TblComprehension"_id: { |
| 948 | auto expList = assignment->expList.get(); | 963 | auto expList = assignment->expList.get(); |
| 949 | std::string preDefine = getPredefine(assignment); | 964 | std::string preDefine = getPredefine(assignment); |
| 950 | transformTblComprehension(static_cast<TblComprehension_t*>(value), out, ExpUsage::Assignment, expList); | 965 | transformTblComprehension(static_cast<TblComprehension_t*>(value), out, ExpUsage::Assignment, expList); |
| 951 | out.back() = preDefine + out.back(); | 966 | out.back().insert(0, preDefine.empty() ? Empty : preDefine + nll(assignment)); |
| 952 | return; | 967 | return; |
| 953 | } | 968 | } |
| 954 | case "For"_id: { | 969 | case "For"_id: { |
| 955 | auto expList = assignment->expList.get(); | 970 | auto expList = assignment->expList.get(); |
| 956 | std::string preDefine = getPredefine(assignment); | 971 | std::string preDefine = getPredefine(assignment); |
| 957 | transformForInPlace(static_cast<For_t*>(value), out, expList); | 972 | transformForInPlace(static_cast<For_t*>(value), out, expList); |
| 958 | out.back() = preDefine + out.back(); | 973 | out.back().insert(0, preDefine.empty() ? Empty : preDefine + nll(assignment)); |
| 959 | return; | 974 | return; |
| 960 | } | 975 | } |
| 961 | case "ForEach"_id: { | 976 | case "ForEach"_id: { |
| 962 | auto expList = assignment->expList.get(); | 977 | auto expList = assignment->expList.get(); |
| 963 | std::string preDefine = getPredefine(assignment); | 978 | std::string preDefine = getPredefine(assignment); |
| 964 | transformForEachInPlace(static_cast<ForEach_t*>(value), out, expList); | 979 | transformForEachInPlace(static_cast<ForEach_t*>(value), out, expList); |
| 965 | out.back() = preDefine + out.back(); | 980 | out.back().insert(0, preDefine.empty() ? Empty : preDefine + nll(assignment)); |
| 966 | return; | 981 | return; |
| 967 | } | 982 | } |
| 968 | case "ClassDecl"_id: { | 983 | case "ClassDecl"_id: { |
| 969 | auto expList = assignment->expList.get(); | 984 | auto expList = assignment->expList.get(); |
| 970 | std::string preDefine = getPredefine(assignment); | 985 | std::string preDefine = getPredefine(assignment); |
| 971 | transformClassDecl(static_cast<ClassDecl_t*>(value), out, ExpUsage::Assignment, expList); | 986 | transformClassDecl(static_cast<ClassDecl_t*>(value), out, ExpUsage::Assignment, expList); |
| 972 | out.back() = preDefine + out.back(); | 987 | out.back().insert(0, preDefine.empty() ? Empty : preDefine + nll(assignment)); |
| 973 | return; | 988 | return; |
| 974 | } | 989 | } |
| 975 | case "While"_id: { | 990 | case "While"_id: { |
| 976 | auto expList = assignment->expList.get(); | 991 | auto expList = assignment->expList.get(); |
| 977 | std::string preDefine = getPredefine(assignment); | 992 | std::string preDefine = getPredefine(assignment); |
| 978 | transformWhileInPlace(static_cast<While_t*>(value), out, expList); | 993 | transformWhileInPlace(static_cast<While_t*>(value), out, expList); |
| 979 | out.back() = preDefine + out.back(); | 994 | out.back().insert(0, preDefine.empty() ? Empty : preDefine + nll(assignment)); |
| 980 | return; | 995 | return; |
| 981 | } | 996 | } |
| 982 | } | 997 | } |
| @@ -985,9 +1000,13 @@ private: | |||
| 985 | if (auto chainValue = exp->value->item.as<ChainValue_t>()) { | 1000 | if (auto chainValue = exp->value->item.as<ChainValue_t>()) { |
| 986 | if (isSpecialChainValue(chainValue)) { | 1001 | if (isSpecialChainValue(chainValue)) { |
| 987 | auto expList = assignment->expList.get(); | 1002 | auto expList = assignment->expList.get(); |
| 988 | std::string preDefine = getPredefine(assignment); | 1003 | if (ast_is<ColonChainItem_t>(chainValue->items.back())) { |
| 989 | transformChainValue(chainValue, out, ExpUsage::Assignment, expList); | 1004 | std::string preDefine = getPredefine(assignment); |
| 990 | out.back() = preDefine + out.back(); | 1005 | transformChainValue(chainValue, out, ExpUsage::Assignment, expList); |
| 1006 | out.back().insert(0, preDefine.empty() ? Empty : preDefine + nll(assignment)); | ||
| 1007 | } else { | ||
| 1008 | transformChainValue(chainValue, out, ExpUsage::Assignment, expList); | ||
| 1009 | } | ||
| 991 | return; | 1010 | return; |
| 992 | } | 1011 | } |
| 993 | } | 1012 | } |
| @@ -1302,16 +1321,31 @@ private: | |||
| 1302 | auto defs = getAssignDefs(expList); | 1321 | auto defs = getAssignDefs(expList); |
| 1303 | bool oneLined = defs.size() == expList->exprs.objects().size() && | 1322 | bool oneLined = defs.size() == expList->exprs.objects().size() && |
| 1304 | traversal::Stop != action->traverse([&](ast_node* n) { | 1323 | traversal::Stop != action->traverse([&](ast_node* n) { |
| 1305 | if (n->getId() == "Callable"_id) { | 1324 | switch (n->getId()) { |
| 1306 | if (auto name = n->getByPath<Variable_t>()) { | 1325 | case "Callable"_id: { |
| 1307 | for (const auto& def : defs) { | 1326 | auto callable = static_cast<Callable_t*>(n); |
| 1308 | if (def == toString(name)) { | 1327 | switch (callable->item->getId()) { |
| 1309 | return traversal::Stop; | 1328 | case "Variable"_id: |
| 1310 | } | 1329 | for (const auto& def : defs) { |
| 1330 | if (def == toString(callable->item)) { | ||
| 1331 | return traversal::Stop; | ||
| 1332 | } | ||
| 1333 | } | ||
| 1334 | return traversal::Return; | ||
| 1335 | case "SelfName"_id: | ||
| 1336 | for (const auto& def : defs) { | ||
| 1337 | if (def == "self"sv) { | ||
| 1338 | return traversal::Stop; | ||
| 1339 | } | ||
| 1340 | } | ||
| 1341 | return traversal::Return; | ||
| 1342 | default: | ||
| 1343 | return traversal::Continue; | ||
| 1311 | } | 1344 | } |
| 1312 | } | 1345 | } |
| 1346 | default: | ||
| 1347 | return traversal::Continue; | ||
| 1313 | } | 1348 | } |
| 1314 | return traversal::Continue; | ||
| 1315 | }); | 1349 | }); |
| 1316 | if (oneLined) { | 1350 | if (oneLined) { |
| 1317 | auto assign = static_cast<Assign_t*>(action); | 1351 | auto assign = static_cast<Assign_t*>(action); |
| @@ -1999,9 +2033,9 @@ private: | |||
| 1999 | } | 2033 | } |
| 2000 | } | 2034 | } |
| 2001 | 2035 | ||
| 2002 | bool transformChainEndWithEOP(const node_container& chainList, str_list& out, ExpUsage usage, ExpList_t*) { | 2036 | bool transformChainEndWithEOP(const node_container& chainList, str_list& out, ExpUsage usage, ExpList_t* assignList) { |
| 2003 | auto x = chainList.front(); | 2037 | auto x = chainList.front(); |
| 2004 | if (ast_cast<existential_op_t>(chainList.back())) { | 2038 | if (ast_is<existential_op_t>(chainList.back())) { |
| 2005 | auto parens = x->new_ptr<Parens_t>(); | 2039 | auto parens = x->new_ptr<Parens_t>(); |
| 2006 | { | 2040 | { |
| 2007 | auto chainValue = x->new_ptr<ChainValue_t>(); | 2041 | auto chainValue = x->new_ptr<ChainValue_t>(); |
| @@ -2019,10 +2053,32 @@ private: | |||
| 2019 | exp->opValues.push_back(opValue); | 2053 | exp->opValues.push_back(opValue); |
| 2020 | parens->expr.set(exp); | 2054 | parens->expr.set(exp); |
| 2021 | } | 2055 | } |
| 2022 | transformParens(parens, out); | 2056 | switch (usage) { |
| 2023 | if (usage == ExpUsage::Return) { | 2057 | case ExpUsage::Assignment: { |
| 2024 | out.back().insert(0, indent() + s("return "sv)); | 2058 | auto callable = x->new_ptr<Callable_t>(); |
| 2025 | out.back().append(nlr(x)); | 2059 | callable->item.set(parens); |
| 2060 | auto chainValue = x->new_ptr<ChainValue_t>(); | ||
| 2061 | chainValue->items.push_back(callable); | ||
| 2062 | auto value = x->new_ptr<Value_t>(); | ||
| 2063 | value->item.set(chainValue); | ||
| 2064 | auto exp = x->new_ptr<Exp_t>(); | ||
| 2065 | exp->value.set(value); | ||
| 2066 | auto assignment = x->new_ptr<ExpListAssign_t>(); | ||
| 2067 | assignment->expList.set(assignList); | ||
| 2068 | auto assign = x->new_ptr<Assign_t>(); | ||
| 2069 | assign->values.push_back(exp); | ||
| 2070 | assignment->action.set(assign); | ||
| 2071 | transformAssignment(assignment, out); | ||
| 2072 | break; | ||
| 2073 | } | ||
| 2074 | case ExpUsage::Return: | ||
| 2075 | transformParens(parens, out); | ||
| 2076 | out.back().insert(0, indent() + s("return "sv)); | ||
| 2077 | out.back().append(nlr(x)); | ||
| 2078 | break; | ||
| 2079 | default: | ||
| 2080 | transformParens(parens, out); | ||
| 2081 | break; | ||
| 2026 | } | 2082 | } |
| 2027 | return true; | 2083 | return true; |
| 2028 | } | 2084 | } |
| @@ -2238,7 +2294,7 @@ private: | |||
| 2238 | assignment->action.set(assign); | 2294 | assignment->action.set(assign); |
| 2239 | transformAssignment(assignment, temp); | 2295 | transformAssignment(assignment, temp); |
| 2240 | } | 2296 | } |
| 2241 | auto funLit = toAst<Exp_t>(s("(...)-> "sv) + fnVar + s(" "sv) + baseVar + s(", ..."sv), Exp, x); | 2297 | auto funLit = toAst<Exp_t>(fnVar + s(" and (...)-> "sv) + fnVar + s(" "sv) + baseVar + s(", ..."sv), Exp, x); |
| 2242 | switch (usage) { | 2298 | switch (usage) { |
| 2243 | case ExpUsage::Closure: | 2299 | case ExpUsage::Closure: |
| 2244 | case ExpUsage::Return: { | 2300 | case ExpUsage::Return: { |
| @@ -2461,13 +2517,13 @@ private: | |||
| 2461 | 2517 | ||
| 2462 | void transformChainValue(ChainValue_t* chainValue, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { | 2518 | void transformChainValue(ChainValue_t* chainValue, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { |
| 2463 | const auto& chainList = chainValue->items.objects(); | 2519 | const auto& chainList = chainValue->items.objects(); |
| 2464 | if (transformChainEndWithEOP(chainList, out, usage, assignList)) { | 2520 | if (transformChainEndWithColonItem(chainList, out, usage, assignList)) { |
| 2465 | return; | 2521 | return; |
| 2466 | } | 2522 | } |
| 2467 | if (transformChainWithEOP(chainList, out, usage, assignList)) { | 2523 | if (transformChainEndWithEOP(chainList, out, usage, assignList)) { |
| 2468 | return; | 2524 | return; |
| 2469 | } | 2525 | } |
| 2470 | if (transformChainEndWithColonItem(chainList, out, usage, assignList)) { | 2526 | if (transformChainWithEOP(chainList, out, usage, assignList)) { |
| 2471 | return; | 2527 | return; |
| 2472 | } | 2528 | } |
| 2473 | transformChainList(chainList, out, usage, assignList); | 2529 | transformChainList(chainList, out, usage, assignList); |
| @@ -3771,7 +3827,6 @@ private: | |||
| 3771 | } | 3827 | } |
| 3772 | popScope(); | 3828 | popScope(); |
| 3773 | _buf << indent() << "end"sv << nll(comp); | 3829 | _buf << indent() << "end"sv << nll(comp); |
| 3774 | out.push_back(tbl); | ||
| 3775 | switch (usage) { | 3830 | switch (usage) { |
| 3776 | case ExpUsage::Closure: | 3831 | case ExpUsage::Closure: |
| 3777 | out.push_back(clearBuf() + indent() + s("return "sv) + tbl + nlr(comp)); | 3832 | out.push_back(clearBuf() + indent() + s("return "sv) + tbl + nlr(comp)); |
