aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MoonParser/moon_ast.cpp83
-rw-r--r--MoonParser/moon_parser.cpp2
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;
481rule Statement = 481rule 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;