diff options
-rw-r--r-- | MoonParser/moon_ast.cpp | 83 | ||||
-rw-r--r-- | MoonParser/moon_parser.cpp | 2 |
2 files changed, 54 insertions, 31 deletions
diff --git a/MoonParser/moon_ast.cpp b/MoonParser/moon_ast.cpp index 2dfab8e..2893672 100644 --- a/MoonParser/moon_ast.cpp +++ b/MoonParser/moon_ast.cpp | |||
@@ -706,6 +706,19 @@ private: | |||
706 | return preDefine.empty() ? preDefine : preDefine + nll(assignment); | 706 | return preDefine.empty() ? preDefine : preDefine + nll(assignment); |
707 | } | 707 | } |
708 | 708 | ||
709 | void assignLastExplist(ExpList_t* expList, Body_t* body) { | ||
710 | auto last = lastStatementFrom(body); | ||
711 | auto valueList = last ? last->content.as<ExpList_t>() : nullptr; | ||
712 | if (last && valueList) { | ||
713 | auto newAssignment = new_ptr<Assignment_t>(); | ||
714 | newAssignment->assignable.set(expList); | ||
715 | auto assign = new_ptr<Assign_t>(); | ||
716 | assign->values.dup(valueList->exprs); | ||
717 | newAssignment->target.set(assign); | ||
718 | last->content.set(newAssignment); | ||
719 | } | ||
720 | } | ||
721 | |||
709 | void transformAssignment(Assignment_t* assignment, std::vector<std::string>& out) { | 722 | void transformAssignment(Assignment_t* assignment, std::vector<std::string>& out) { |
710 | auto assign = ast_cast<Assign_t>(assignment->target); | 723 | auto assign = ast_cast<Assign_t>(assignment->target); |
711 | do { | 724 | do { |
@@ -715,7 +728,7 @@ private: | |||
715 | if (ast_is<If_t>(value)) { | 728 | if (ast_is<If_t>(value)) { |
716 | item = value; | 729 | item = value; |
717 | } else if (auto val = simpleSingleValueFrom(value)) { | 730 | } else if (auto val = simpleSingleValueFrom(value)) { |
718 | if (ast_is<If_t,Unless_t>(val->value)) { | 731 | if (ast_is<If_t, Unless_t>(val->value)) { |
719 | item = val->value; | 732 | item = val->value; |
720 | } | 733 | } |
721 | } | 734 | } |
@@ -729,16 +742,7 @@ private: | |||
729 | case "IfCond"_id: return traversal::Return; | 742 | case "IfCond"_id: return traversal::Return; |
730 | case "Body"_id: { | 743 | case "Body"_id: { |
731 | auto body = static_cast<Body_t*>(node); | 744 | auto body = static_cast<Body_t*>(node); |
732 | auto last = lastStatementFrom(body); | 745 | assignLastExplist(expList, body); |
733 | auto valueList = last ? last->content.as<ExpList_t>() : nullptr; | ||
734 | if (last && valueList) { | ||
735 | auto newAssignment = new_ptr<Assignment_t>(); | ||
736 | newAssignment->assignable.set(expList); | ||
737 | auto assign = new_ptr<Assign_t>(); | ||
738 | assign->values.dup(valueList->exprs); | ||
739 | newAssignment->target.set(assign); | ||
740 | last->content.set(newAssignment); | ||
741 | } | ||
742 | return traversal::Return; | 746 | return traversal::Return; |
743 | } | 747 | } |
744 | default: return traversal::Continue; | 748 | default: return traversal::Continue; |
@@ -751,27 +755,32 @@ private: | |||
751 | out.push_back(join(temp)); | 755 | out.push_back(join(temp)); |
752 | return; | 756 | return; |
753 | } | 757 | } |
758 | if (auto switchNode = ast_cast<Switch_t>(value)) { | ||
759 | auto expList = assignment->assignable.get(); | ||
760 | for (auto branch_ : switchNode->branches.objects()) { | ||
761 | auto branch = static_cast<SwitchCase_t*>(branch_); | ||
762 | assignLastExplist(expList, branch->body); | ||
763 | } | ||
764 | if (switchNode->lastBranch) { | ||
765 | assignLastExplist(expList, switchNode->lastBranch); | ||
766 | } | ||
767 | std::string preDefine = getPredefine(assignment); | ||
768 | transformSwitch(switchNode, out); | ||
769 | out.back() = preDefine + out.back(); | ||
770 | return; | ||
771 | } | ||
754 | auto exp = ast_cast<Exp_t>(value); | 772 | auto exp = ast_cast<Exp_t>(value); |
755 | if (!exp) break; | 773 | if (!exp) break; |
756 | if (auto simpleVal = exp->value->item.as<SimpleValue_t>()) { | 774 | if (auto simpleVal = exp->value->item.as<SimpleValue_t>()) { |
757 | auto valueItem = simpleVal->value.get(); | 775 | auto valueItem = simpleVal->value.get(); |
758 | switch (valueItem->getId()) { | 776 | switch (valueItem->getId()) { |
759 | case "Do"_id: { | 777 | case "Do"_id: { |
760 | auto expList = assignment->assignable.get(); | ||
761 | auto doNode = static_cast<Do_t*>(valueItem); | 778 | auto doNode = static_cast<Do_t*>(valueItem); |
762 | auto last = lastStatementFrom(doNode->body); | 779 | auto expList = assignment->assignable.get(); |
763 | auto valueList = last ? last->content.as<ExpList_t>() : nullptr; | 780 | assignLastExplist(expList, doNode->body); |
764 | if (last && valueList) { | 781 | std::string preDefine = getPredefine(assignment); |
765 | auto newAssignment = new_ptr<Assignment_t>(); | 782 | transformDo(doNode, out); |
766 | newAssignment->assignable.set(expList); | 783 | out.back() = preDefine + out.back(); |
767 | auto assign = new_ptr<Assign_t>(); | ||
768 | assign->values.dup(valueList->exprs); | ||
769 | newAssignment->target.set(assign); | ||
770 | last->content.set(newAssignment); | ||
771 | std::string preDefine = getPredefine(assignment); | ||
772 | transformDo(doNode, out); | ||
773 | out.back() = preDefine + out.back(); | ||
774 | } | ||
775 | return; | 784 | return; |
776 | } | 785 | } |
777 | case "Comprehension"_id: { | 786 | case "Comprehension"_id: { |
@@ -899,7 +908,7 @@ private: | |||
899 | switch (value->getId()) { | 908 | switch (value->getId()) { |
900 | case "With"_id: transformWith(static_cast<With_t*>(value), out); break; | 909 | case "With"_id: transformWith(static_cast<With_t*>(value), out); break; |
901 | case "If"_id: transformIf(static_cast<If_t*>(value), out, IfUsage::Closure); break; | 910 | case "If"_id: transformIf(static_cast<If_t*>(value), out, IfUsage::Closure); break; |
902 | case "Switch"_id: transformSwitchClosure(static_cast<>(value), out); break; | 911 | case "Switch"_id: transformSwitchClosure(static_cast<Switch_t*>(value), out); break; |
903 | case "TableBlock"_id: transformTableBlock(static_cast<TableBlock_t*>(value), out); break; | 912 | case "TableBlock"_id: transformTableBlock(static_cast<TableBlock_t*>(value), out); break; |
904 | case "Exp"_id: transformExp(static_cast<Exp_t*>(value), out); break; | 913 | case "Exp"_id: transformExp(static_cast<Exp_t*>(value), out); break; |
905 | default: break; | 914 | default: break; |
@@ -1322,7 +1331,7 @@ private: | |||
1322 | case "const_value"_id: transform_const_value(static_cast<const_value_t*>(value), out); break; | 1331 | case "const_value"_id: transform_const_value(static_cast<const_value_t*>(value), out); break; |
1323 | case "If"_id: transformIf(static_cast<If_t*>(value), out, IfUsage::Closure); break; | 1332 | case "If"_id: transformIf(static_cast<If_t*>(value), out, IfUsage::Closure); break; |
1324 | case "Unless"_id: transformUnless(static_cast<Unless_t*>(value), out, IfUsage::Closure); break; | 1333 | case "Unless"_id: transformUnless(static_cast<Unless_t*>(value), out, IfUsage::Closure); break; |
1325 | case "Switch"_id: transformSwitch(value, out); break; | 1334 | case "Switch"_id: transformSwitchClosure(static_cast<Switch_t*>(value), out); break; |
1326 | case "With"_id: transformWith(static_cast<With_t*>(value), out); break; | 1335 | case "With"_id: transformWith(static_cast<With_t*>(value), out); break; |
1327 | case "ClassDecl"_id: transformClassDeclClosure(static_cast<ClassDecl_t*>(value), out); break; | 1336 | case "ClassDecl"_id: transformClassDeclClosure(static_cast<ClassDecl_t*>(value), out); break; |
1328 | case "ForEach"_id: transformForEachClosure(static_cast<ForEach_t*>(value), out); break; | 1337 | case "ForEach"_id: transformForEachClosure(static_cast<ForEach_t*>(value), out); break; |
@@ -1438,6 +1447,10 @@ private: | |||
1438 | transformDo(doNode, out, true); | 1447 | transformDo(doNode, out, true); |
1439 | return; | 1448 | return; |
1440 | } | 1449 | } |
1450 | if (auto switchNode = singleValue->getByPath<SimpleValue_t, Switch_t>()) { | ||
1451 | transformSwitch(switchNode, out, true); | ||
1452 | return; | ||
1453 | } | ||
1441 | if (auto chainValue = singleValue->getByPath<ChainValue_t>()) { | 1454 | if (auto chainValue = singleValue->getByPath<ChainValue_t>()) { |
1442 | if (isColonChain(chainValue)) { | 1455 | if (isColonChain(chainValue)) { |
1443 | transformColonChain(chainValue, out, ExpUsage::Return); | 1456 | transformColonChain(chainValue, out, ExpUsage::Return); |
@@ -3084,11 +3097,21 @@ private: | |||
3084 | out.push_back(clearBuf()); | 3097 | out.push_back(clearBuf()); |
3085 | } | 3098 | } |
3086 | 3099 | ||
3100 | void transformSwitchClosure(Switch_t* switchNode, std::vector<std::string>& out) { | ||
3101 | std::vector<std::string> temp; | ||
3102 | temp.push_back(s("(function()"sv) + nll(switchNode)); | ||
3103 | pushScope(); | ||
3104 | transformSwitch(switchNode, temp, true); | ||
3105 | popScope(); | ||
3106 | temp.push_back(indent() + s("end)()"sv)); | ||
3107 | out.push_back(join(temp)); | ||
3108 | } | ||
3109 | |||
3087 | void transformSwitch(Switch_t* switchNode, std::vector<std::string>& out, bool implicitReturn = false) { | 3110 | void transformSwitch(Switch_t* switchNode, std::vector<std::string>& out, bool implicitReturn = false) { |
3088 | std::vector<std::string> temp; | 3111 | std::vector<std::string> temp; |
3089 | auto objVar = variableFrom(switchNode->target); | 3112 | auto objVar = variableFrom(switchNode->target); |
3090 | if (objVar.empty()) { | 3113 | if (objVar.empty()) { |
3091 | objVar = getUnusedName("_obj_"sv); | 3114 | objVar = getUnusedName("_exp_"sv); |
3092 | addToScope(objVar); | 3115 | addToScope(objVar); |
3093 | transformExp(switchNode->target, temp); | 3116 | transformExp(switchNode->target, temp); |
3094 | _buf << indent() << "local "sv << objVar << " = "sv << temp.back() << nll(switchNode); | 3117 | _buf << indent() << "local "sv << objVar << " = "sv << temp.back() << nll(switchNode); |
@@ -3103,8 +3126,8 @@ private: | |||
3103 | for (auto exp_ : exprs) { | 3126 | for (auto exp_ : exprs) { |
3104 | auto exp = static_cast<Exp_t*>(exp_); | 3127 | auto exp = static_cast<Exp_t*>(exp_); |
3105 | transformExp(exp, tmp); | 3128 | transformExp(exp, tmp); |
3106 | temp.back().append(s(" "sv) + objVar + s(" == "sv) + tmp.back + | 3129 | temp.back().append(s(" "sv) + tmp.back() + s(" == "sv) + objVar + |
3107 | (exp == exprs.back() ? ""sv : " or"sv)); | 3130 | s(exp == exprs.back() ? ""sv : " or"sv)); |
3108 | } | 3131 | } |
3109 | temp.back().append(s(" then"sv) + nll(branch)); | 3132 | temp.back().append(s(" then"sv) + nll(branch)); |
3110 | pushScope(); | 3133 | pushScope(); |
diff --git a/MoonParser/moon_parser.cpp b/MoonParser/moon_parser.cpp index 7fab4f5..c33469b 100644 --- a/MoonParser/moon_parser.cpp +++ b/MoonParser/moon_parser.cpp | |||
@@ -481,7 +481,7 @@ rule statement_appendix = (if_else_line | unless_line | CompInner) >> Space; | |||
481 | rule Statement = | 481 | rule Statement = |
482 | ( | 482 | ( |
483 | Import | While | With | For | ForEach | | 483 | Import | While | With | For | ForEach | |
484 | Switch | Return | Local | Export | BreakLoop | | 484 | Return | Local | Export | BreakLoop | |
485 | Assignment | ExpList | 485 | Assignment | ExpList |
486 | ) >> Space >> | 486 | ) >> Space >> |
487 | -statement_appendix; | 487 | -statement_appendix; |