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