summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2019-09-24 20:17:22 +0800
committerLi Jin <dragon-fly@qq.com>2019-09-24 20:17:22 +0800
commit0a4164b929e9532236df5645464e68188b3dd4c3 (patch)
treeb1a3a6d33cc98d9dbe219bf8763cfa977f1c4d48
parent50eeb71a81d86cd7eb334058d1fd2d7eb899e12d (diff)
downloadyuescript-0a4164b929e9532236df5645464e68188b3dd4c3.tar.gz
yuescript-0a4164b929e9532236df5645464e68188b3dd4c3.tar.bz2
yuescript-0a4164b929e9532236df5645464e68188b3dd4c3.zip
updating.
-rw-r--r--MoonParser.xcodeproj/project.pbxproj4
-rw-r--r--MoonParser/moon_ast.cpp989
-rw-r--r--MoonParser/moon_ast.h16
-rw-r--r--MoonParser/moon_parser.cpp4
4 files changed, 659 insertions, 354 deletions
diff --git a/MoonParser.xcodeproj/project.pbxproj b/MoonParser.xcodeproj/project.pbxproj
index 4d48a86..db93034 100644
--- a/MoonParser.xcodeproj/project.pbxproj
+++ b/MoonParser.xcodeproj/project.pbxproj
@@ -107,7 +107,7 @@
107 3C0F0F641EF3781E000EADDB /* Project object */ = { 107 3C0F0F641EF3781E000EADDB /* Project object */ = {
108 isa = PBXProject; 108 isa = PBXProject;
109 attributes = { 109 attributes = {
110 LastUpgradeCheck = 1030; 110 LastUpgradeCheck = 1100;
111 ORGANIZATIONNAME = "Li Jin"; 111 ORGANIZATIONNAME = "Li Jin";
112 TargetAttributes = { 112 TargetAttributes = {
113 3C0F0F6B1EF3781E000EADDB = { 113 3C0F0F6B1EF3781E000EADDB = {
@@ -257,6 +257,7 @@
257 3C0F0F741EF3781E000EADDB /* Debug */ = { 257 3C0F0F741EF3781E000EADDB /* Debug */ = {
258 isa = XCBuildConfiguration; 258 isa = XCBuildConfiguration;
259 buildSettings = { 259 buildSettings = {
260 CODE_SIGN_IDENTITY = "-";
260 OTHER_CPLUSPLUSFLAGS = ( 261 OTHER_CPLUSPLUSFLAGS = (
261 "$(OTHER_CFLAGS)", 262 "$(OTHER_CFLAGS)",
262 "-ftemplate-depth=512", 263 "-ftemplate-depth=512",
@@ -269,6 +270,7 @@
269 3C0F0F751EF3781E000EADDB /* Release */ = { 270 3C0F0F751EF3781E000EADDB /* Release */ = {
270 isa = XCBuildConfiguration; 271 isa = XCBuildConfiguration;
271 buildSettings = { 272 buildSettings = {
273 CODE_SIGN_IDENTITY = "-";
272 OTHER_CPLUSPLUSFLAGS = ( 274 OTHER_CPLUSPLUSFLAGS = (
273 "$(OTHER_CFLAGS)", 275 "$(OTHER_CFLAGS)",
274 "-ftemplate-depth=512", 276 "-ftemplate-depth=512",
diff --git a/MoonParser/moon_ast.cpp b/MoonParser/moon_ast.cpp
index 217f2b5..c2e940c 100644
--- a/MoonParser/moon_ast.cpp
+++ b/MoonParser/moon_ast.cpp
@@ -36,7 +36,6 @@ AST_IMPL(Seperator)
36AST_IMPL(NameList) 36AST_IMPL(NameList)
37AST_IMPL(Local) 37AST_IMPL(Local)
38AST_IMPL(colon_import_name) 38AST_IMPL(colon_import_name)
39AST_IMPL(ImportName)
40AST_IMPL(Import) 39AST_IMPL(Import)
41AST_IMPL(ExpListLow) 40AST_IMPL(ExpListLow)
42AST_IMPL(ExpList) 41AST_IMPL(ExpList)
@@ -58,7 +57,6 @@ AST_IMPL(TblComprehension)
58AST_IMPL(star_exp) 57AST_IMPL(star_exp)
59AST_IMPL(CompForEach) 58AST_IMPL(CompForEach)
60AST_IMPL(CompFor) 59AST_IMPL(CompFor)
61AST_IMPL(CompClause)
62AST_IMPL(CompInner) 60AST_IMPL(CompInner)
63AST_IMPL(Assign) 61AST_IMPL(Assign)
64AST_IMPL(update_op) 62AST_IMPL(update_op)
@@ -154,7 +152,7 @@ public:
154private: 152private:
155 int _indentOffset = 0; 153 int _indentOffset = 0;
156 Converter _converter; 154 Converter _converter;
157 std::vector<input> _codeCache; 155 std::list<input> _codeCache;
158 std::stack<std::string> _withVars; 156 std::stack<std::string> _withVars;
159 std::ostringstream _buf; 157 std::ostringstream _buf;
160 std::string _newLine = "\n"; 158 std::string _newLine = "\n";
@@ -186,6 +184,7 @@ private:
186 }; 184 };
187 185
188 struct DestructItem { 186 struct DestructItem {
187 bool isVariable = false;
189 std::string name; 188 std::string name;
190 std::string structure; 189 std::string structure;
191 }; 190 };
@@ -219,18 +218,19 @@ private:
219 bool isDefined(const std::string& name, bool checkShadowScopeOnly = false) { 218 bool isDefined(const std::string& name, bool checkShadowScopeOnly = false) {
220 bool isDefined = false; 219 bool isDefined = false;
221 int mode = int(std::isupper(name[0]) ? ExportMode::Capital : ExportMode::Any); 220 int mode = int(std::isupper(name[0]) ? ExportMode::Capital : ExportMode::Any);
222 for (auto it = _scopes.rbegin(); it != _scopes.rend(); ++it) { 221 const auto& current = _scopes.back();
223 if (int(it->mode) >= mode) { 222 if (int(current.mode) >= mode) {
224 if (it->exports) { 223 if (current.exports) {
225 if (it->exports->find(name) != it->exports->end()) { 224 if (current.exports->find(name) != current.exports->end()) {
226 isDefined = true;
227 break;
228 }
229 } else {
230 isDefined = true; 225 isDefined = true;
231 break; 226 current.vars->insert(name);
232 } 227 }
228 } else {
229 isDefined = true;
230 current.vars->insert(name);
233 } 231 }
232 }
233 for (auto it = _scopes.rbegin(); it != _scopes.rend(); ++it) {
234 auto vars = it->vars.get(); 234 auto vars = it->vars.get();
235 if (vars->find(name) != vars->end()) { 235 if (vars->find(name) != vars->end()) {
236 isDefined = true; 236 isDefined = true;
@@ -324,8 +324,12 @@ private:
324 return _newLine; 324 return _newLine;
325 } 325 }
326 326
327 void setIndentOffset(int offset) { 327 void incIndentOffset() {
328 _indentOffset = offset; 328 _indentOffset++;
329 }
330
331 void decIndentOffset() {
332 _indentOffset--;
329 } 333 }
330 334
331 std::string indent() { 335 std::string indent() {
@@ -436,12 +440,12 @@ private:
436 return parse<T>(_codeCache.back(), r, el, &st); 440 return parse<T>(_codeCache.back(), r, el, &st);
437 } 441 }
438 442
439 template <class T> 443 bool matchAst(rule& r, std::string_view codes) {
440 bool matchAst(std::string_view codes, rule& r) {
441 error_list el; 444 error_list el;
442 State st; 445 State st;
443 input i = _converter.from_bytes(s(codes)); 446 input i = _converter.from_bytes(s(codes));
444 return parse<T>(i, r, el, &st); 447 auto rEnd = rule(r >> eof());
448 return _parse(i, rEnd, el, &st);
445 } 449 }
446 450
447 bool isChainValueCall(ChainValue_t* chainValue) { 451 bool isChainValueCall(ChainValue_t* chainValue) {
@@ -453,6 +457,20 @@ private:
453 return false; 457 return false;
454 } 458 }
455 459
460 std::string variableFrom(ast_node* expList) {
461 if (!ast_is<Exp_t, ExpList_t>(expList)) return Empty;
462 if (auto value = singleValueFrom(expList)) {
463 if (auto chainValue = value->getByPath<ChainValue_t>()) {
464 if (!chainValue->arguments) {
465 if (auto callable = chainValue->caller.as<Callable_t>()) {
466 return toString(callable->item);
467 }
468 }
469 }
470 }
471 return Empty;
472 }
473
456 bool isColonChain(ChainValue_t* chainValue) { 474 bool isColonChain(ChainValue_t* chainValue) {
457 if (chainValue->arguments) return false; 475 if (chainValue->arguments) return false;
458 if (auto chain = chainValue->caller.as<Chain_t>()) { 476 if (auto chain = chainValue->caller.as<Chain_t>()) {
@@ -550,39 +568,13 @@ private:
550 } 568 }
551 case "CompInner"_id: { 569 case "CompInner"_id: {
552 auto compInner = appendix->item.to<CompInner_t>(); 570 auto compInner = appendix->item.to<CompInner_t>();
553 switch (compInner->compFor->getId()) { 571 auto comp = new_ptr<Comprehension_t>();
554 case "CompFor"_id: { 572 comp->forLoop.set(compInner);
555 auto compFor = compInner->compFor.to<CompFor_t>(); 573 auto stmt = new_ptr<Statement_t>();
556 auto forNode = new_ptr<For_t>(); 574 stmt->content.set(statement->content);
557 forNode->startValue.set(compFor->startValue); 575 comp->value.set(stmt);
558 forNode->stopValue.set(compFor->stopValue); 576 statement->content.set(comp);
559 forNode->stepValue.set(compFor->stepValue); 577 statement->appendix.set(nullptr);
560 forNode->varName.set(compFor->varName);
561 auto stmt = new_ptr<Statement_t>();
562 stmt->content.set(statement->content);
563 auto body = new_ptr<Body_t>();
564 body->content.set(stmt);
565 forNode->body.set(body);
566 statement->appendix.set(nullptr);
567 statement->content.set(forNode);
568 break;
569 }
570 case "CompForEach"_id: {
571 auto compForEach = compInner->compFor.to<CompForEach_t>();
572 auto forEach = new_ptr<ForEach_t>();
573 forEach->nameList.set(compForEach->nameList);
574 forEach->loopValue.set(compForEach->loopValue);
575 auto stmt = new_ptr<Statement_t>();
576 stmt->content.set(statement->content);
577 auto body = new_ptr<Body_t>();
578 body->content.set(stmt);
579 forEach->body.set(body);
580 statement->appendix.set(nullptr);
581 statement->content.set(forEach);
582 break;
583 }
584 default: break;
585 }
586 break; 578 break;
587 } 579 }
588 default: break; 580 default: break;
@@ -594,8 +586,8 @@ private:
594 return; 586 return;
595 } 587 }
596 switch (content->getId()) { 588 switch (content->getId()) {
597 case "Import"_id: transformImport(content, out); break; 589 case "Import"_id: transformImport(static_cast<Import_t*>(content), out); break;
598 case "While"_id: transformWhile(content, out); break; 590 case "While"_id: transformWhile(static_cast<While_t*>(content), out); break;
599 case "With"_id: transformWith(static_cast<With_t*>(content), out); break; 591 case "With"_id: transformWith(static_cast<With_t*>(content), out); break;
600 case "For"_id: transformFor(static_cast<For_t*>(content), out); break; 592 case "For"_id: transformFor(static_cast<For_t*>(content), out); break;
601 case "ForEach"_id: transformForEach(static_cast<ForEach_t*>(content), out); break; 593 case "ForEach"_id: transformForEach(static_cast<ForEach_t*>(content), out); break;
@@ -605,6 +597,7 @@ private:
605 case "Export"_id: transformExport(static_cast<Export_t*>(content), out); break; 597 case "Export"_id: transformExport(static_cast<Export_t*>(content), out); break;
606 case "BreakLoop"_id: transformBreakLoop(content, out); break; 598 case "BreakLoop"_id: transformBreakLoop(content, out); break;
607 case "Assignment"_id: transformAssignment(static_cast<Assignment_t*>(content), out); break; 599 case "Assignment"_id: transformAssignment(static_cast<Assignment_t*>(content), out); break;
600 case "Comprehension"_id: transformCompCommon(static_cast<Comprehension_t*>(content), out); break;
608 case "ExpList"_id: { 601 case "ExpList"_id: {
609 auto expList = static_cast<ExpList_t*>(content); 602 auto expList = static_cast<ExpList_t*>(content);
610 if (expList->exprs.objects().empty()) { 603 if (expList->exprs.objects().empty()) {
@@ -653,18 +646,10 @@ private:
653 646
654 std::vector<std::string> getAssignVars(ExpList_t* expList) { 647 std::vector<std::string> getAssignVars(ExpList_t* expList) {
655 std::vector<std::string> vars; 648 std::vector<std::string> vars;
656 expList->traverse([&](ast_node* child) { 649 for (auto exp : expList->exprs.objects()) {
657 if (child->getId() == "Value"_id) { 650 auto var = variableFrom(exp);
658 if (auto target = child->getByPath<ChainValue_t, Callable_t, Variable_t>()) { 651 vars.push_back(var.empty() ? Empty : var);
659 auto name = toString(target); 652 }
660 vars.push_back(name);
661 } else {
662 vars.push_back(Empty);
663 }
664 return traversal::Return;
665 }
666 return traversal::Continue;
667 });
668 return vars; 653 return vars;
669 } 654 }
670 655
@@ -697,6 +682,30 @@ private:
697 return indent() + s("local "sv) + join(defs, ", "sv); 682 return indent() + s("local "sv) + join(defs, ", "sv);
698 } 683 }
699 684
685 std::string getDestrucureDefine(Assignment_t* assignment) {
686 auto info = extractDestructureInfo(assignment);
687 if (!info.first.empty()) {
688 for (const auto& destruct : info.first) {
689 std::vector<std::string> defs;
690 for (const auto& item : destruct.items) {
691 if (item.isVariable && addToScope(item.name)) {
692 defs.push_back(item.name);
693 }
694 }
695 if (!defs.empty()) _buf << indent() << "local "sv << join(defs,", "sv);
696 }
697 }
698 return clearBuf();
699 }
700
701 std::string getPredefine(Assignment_t* assignment) {
702 auto preDefine = getDestrucureDefine(assignment);
703 if (preDefine.empty()) {
704 preDefine = getPredefine(transformAssignDefs(assignment->assignable));
705 }
706 return preDefine.empty() ? preDefine : preDefine + nll(assignment);
707 }
708
700 void transformAssignment(Assignment_t* assignment, std::vector<std::string>& out) { 709 void transformAssignment(Assignment_t* assignment, std::vector<std::string>& out) {
701 auto assign = ast_cast<Assign_t>(assignment->target); 710 auto assign = ast_cast<Assign_t>(assignment->target);
702 do { 711 do {
@@ -744,71 +753,73 @@ private:
744 } 753 }
745 auto exp = ast_cast<Exp_t>(value); 754 auto exp = ast_cast<Exp_t>(value);
746 if (!exp) break; 755 if (!exp) break;
747 auto simpleVal = exp->value->item.as<SimpleValue_t>(); 756 if (auto simpleVal = exp->value->item.as<SimpleValue_t>()) {
748 if (!simpleVal) break; 757 auto valueItem = simpleVal->value.get();
749 auto valueItem = simpleVal->value.get(); 758 switch (valueItem->getId()) {
750 switch (valueItem->getId()) { 759 case "Do"_id: {
751 case "Do"_id: { 760 auto expList = assignment->assignable.get();
752 auto expList = assignment->assignable.get(); 761 auto doNode = static_cast<Do_t*>(valueItem);
753 auto doNode = static_cast<Do_t*>(valueItem); 762 auto last = lastStatementFrom(doNode->body);
754 auto last = lastStatementFrom(doNode->body); 763 auto valueList = last ? last->content.as<ExpList_t>() : nullptr;
755 auto valueList = last ? last->content.as<ExpList_t>() : nullptr; 764 if (last && valueList) {
756 if (last && valueList) { 765 auto newAssignment = new_ptr<Assignment_t>();
757 auto newAssignment = new_ptr<Assignment_t>(); 766 newAssignment->assignable.set(expList);
758 newAssignment->assignable.set(expList); 767 auto assign = new_ptr<Assign_t>();
759 auto assign = new_ptr<Assign_t>(); 768 assign->values.dup(valueList->exprs);
760 assign->values.dup(valueList->exprs); 769 newAssignment->target.set(assign);
761 newAssignment->target.set(assign); 770 last->content.set(newAssignment);
762 last->content.set(newAssignment); 771 std::string preDefine = getPredefine(assignment);
763 std::string preDefine = getPredefine(transformAssignDefs(expList)); 772 transformDo(doNode, out);
764 auto nl = preDefine.empty() ? Empty : nll(assignment); 773 out.back() = preDefine + out.back();
765 transformDo(doNode, out); 774 }
766 out.back() = preDefine + nl + out.back(); 775 return;
776 }
777 case "Comprehension"_id: {
778 auto expList = assignment->assignable.get();
779 std::string preDefine = getPredefine(assignment);
780 transformCompInPlace(static_cast<Comprehension_t*>(valueItem), expList, out);
781 out.back() = preDefine + out.back();
782 return;
783 }
784 case "TblComprehension"_id: {
785 auto expList = assignment->assignable.get();
786 std::string preDefine = getPredefine(assignment);
787 transformTblCompInPlace(static_cast<TblComprehension_t*>(valueItem), expList, out);
788 out.back() = preDefine + out.back();
789 return;
790 }
791 case "For"_id: {
792 std::vector<std::string> temp;
793 auto expList = assignment->assignable.get();
794 std::string preDefine = getPredefine(assignment);
795 transformForInPlace(static_cast<For_t*>(valueItem), temp, expList);
796 out.push_back(preDefine + temp.front());
797 return;
798 }
799 case "ForEach"_id: {
800 std::vector<std::string> temp;
801 auto expList = assignment->assignable.get();
802 std::string preDefine = getPredefine(assignment);
803 transformForEachInPlace(static_cast<ForEach_t*>(valueItem), temp, expList);
804 out.push_back(preDefine + temp.front());
805 return;
806 }
807 case "ClassDecl"_id: {
808 std::vector<std::string> temp;
809 auto expList = assignment->assignable.get();
810 std::string preDefine = getPredefine(assignment);
811 transformClassDecl(static_cast<ClassDecl_t*>(valueItem), temp, ExpUsage::Assignment, expList);
812 out.push_back(preDefine + temp.front());
813 return;
814 }
815 case "While"_id: {
816 std::vector<std::string> temp;
817 auto expList = assignment->assignable.get();
818 std::string preDefine = getPredefine(assignment);
819 transformWhileClosure(static_cast<While_t*>(valueItem), temp, expList);
820 out.push_back(preDefine + temp.front());
821 return;
767 } 822 }
768 return;
769 }
770 case "Comprehension"_id: {
771 auto expList = assignment->assignable.get();
772 std::string preDefine = getPredefine(transformAssignDefs(expList));
773 auto nl = preDefine.empty() ? Empty : nll(assignment);
774 transformCompInPlace(static_cast<Comprehension_t*>(valueItem), expList, out);
775 out.back() = preDefine + nl + out.back();
776 return;
777 }
778 case "TblComprehension"_id: {
779 auto expList = assignment->assignable.get();
780 std::string preDefine = getPredefine(transformAssignDefs(expList));
781 auto nl = preDefine.empty() ? Empty : nll(assignment);
782 transformTblCompInPlace(static_cast<TblComprehension_t*>(valueItem), expList, out);
783 out.back() = preDefine + nl + out.back();
784 return;
785 }
786 case "For"_id: {
787 std::vector<std::string> temp;
788 auto expList = assignment->assignable.get();
789 std::string preDefine = getPredefine(transformAssignDefs(expList));
790 auto nl = preDefine.empty() ? Empty : nll(assignment);
791 transformForInPlace(static_cast<For_t*>(valueItem), temp, expList);
792 out.push_back(preDefine + nl + temp.front());
793 return;
794 }
795 case "ForEach"_id: {
796 std::vector<std::string> temp;
797 auto expList = assignment->assignable.get();
798 std::string preDefine = getPredefine(transformAssignDefs(expList));
799 transformForEachInPlace(static_cast<ForEach_t*>(valueItem), temp, expList);
800 auto nl = preDefine.empty() ? Empty : nll(assignment);
801 out.push_back(preDefine + nl + temp.front());
802 return;
803 }
804 case "ClassDecl"_id: {
805 std::vector<std::string> temp;
806 auto expList = assignment->assignable.get();
807 std::string preDefine = getPredefine(transformAssignDefs(expList));
808 transformClassDecl(static_cast<ClassDecl_t*>(valueItem), temp, ExpUsage::Assignment, expList);
809 auto nl = preDefine.empty() ? Empty : nll(assignment);
810 out.push_back(preDefine + nl + temp.front());
811 return;
812 } 823 }
813 } 824 }
814 if (auto chainValue = exp->value->item.as<ChainValue_t>()) { 825 if (auto chainValue = exp->value->item.as<ChainValue_t>()) {
@@ -831,28 +842,35 @@ private:
831 if (destruct.items.size() == 1) { 842 if (destruct.items.size() == 1) {
832 auto& pair = destruct.items.front(); 843 auto& pair = destruct.items.front();
833 _buf << indent(); 844 _buf << indent();
834 if (addToScope(pair.name)) { 845 if (pair.isVariable && addToScope(pair.name)) {
835 _buf << s("local "sv); 846 _buf << s("local "sv);
836 } 847 }
837 _buf << pair.name << " = "sv << info.first.front().value << pair.structure << nll(assignment); 848 _buf << pair.name << " = "sv << info.first.front().value << pair.structure << nll(assignment);
838 temp.push_back(clearBuf()); 849 temp.push_back(clearBuf());
839 } else if (matchAst<Name_t>(destruct.value, Name)) { 850 } else if (matchAst(Name, destruct.value)) {
840 std::vector<std::string> defs, names, values; 851 std::vector<std::string> defs, names, values;
841 for (const auto& item : destruct.items) { 852 for (const auto& item : destruct.items) {
842 if (addToScope(item.name)) { 853 if (item.isVariable && addToScope(item.name)) {
843 defs.push_back(item.name); 854 defs.push_back(item.name);
844 } 855 }
845 names.push_back(item.name); 856 names.push_back(item.name);
846 values.push_back(item.structure); 857 values.push_back(item.structure);
847 } 858 }
848 if (!defs.empty()) _buf << indent() << "local "sv << join(defs,", "sv) << nll(assignment);
849 for (auto& v : values) v.insert(0, destruct.value); 859 for (auto& v : values) v.insert(0, destruct.value);
850 _buf << indent() << join(names, ", "sv) << " = "sv << join(values, ", "sv) << nll(assignment); 860 if (defs.empty()) {
861 _buf << indent() << join(names, ", "sv) << " = "sv << join(values, ", "sv) << nll(assignment);
862 } else {
863 _buf << indent() << "local "sv;
864 if (defs.size() != names.size()) {
865 _buf << join(defs,", "sv) << nll(assignment) << indent();
866 }
867 _buf << join(names, ", "sv) << " = "sv << join(values, ", "sv) << nll(assignment);
868 }
851 temp.push_back(clearBuf()); 869 temp.push_back(clearBuf());
852 } else { 870 } else {
853 std::vector<std::string> defs, names, values; 871 std::vector<std::string> defs, names, values;
854 for (const auto& item : destruct.items) { 872 for (const auto& item : destruct.items) {
855 if (addToScope(item.name)) { 873 if (item.isVariable && addToScope(item.name)) {
856 defs.push_back(item.name); 874 defs.push_back(item.name);
857 } 875 }
858 names.push_back(item.name); 876 names.push_back(item.name);
@@ -888,7 +906,7 @@ private:
888 } 906 }
889 } 907 }
890 908
891 std::list<std::pair<std::string, std::string>> destructFromExp(ast_node* node) { 909 std::list<DestructItem> destructFromExp(ast_node* node) {
892 const std::list<ast_node*>* tableItems = nullptr; 910 const std::list<ast_node*>* tableItems = nullptr;
893 if (ast_cast<Exp_t>(node)) { 911 if (ast_cast<Exp_t>(node)) {
894 auto item = singleValueFrom(node)->item.get(); 912 auto item = singleValueFrom(node)->item.get();
@@ -903,7 +921,7 @@ private:
903 } else if (auto table = ast_cast<TableBlock_t>(node)) { 921 } else if (auto table = ast_cast<TableBlock_t>(node)) {
904 tableItems = &table->values.objects(); 922 tableItems = &table->values.objects();
905 } 923 }
906 std::list<std::pair<std::string, std::string>> pairs; 924 std::list<DestructItem> pairs;
907 int index = 0; 925 int index = 0;
908 for (auto pair : *tableItems) { 926 for (auto pair : *tableItems) {
909 switch (pair->getId()) { 927 switch (pair->getId()) {
@@ -911,26 +929,29 @@ private:
911 ++index; 929 ++index;
912 auto item = singleValueFrom(pair)->item.get(); 930 auto item = singleValueFrom(pair)->item.get();
913 if (!item) throw std::logic_error("Invalid destructure value"); 931 if (!item) throw std::logic_error("Invalid destructure value");
914 if (auto value = item->getByPath<Callable_t, Variable_t>()) { 932 if (item->getId() == "Parens"_id) throw std::logic_error("Can't destructure value of type: parens");
915 auto name = toString(value);
916 //"Can't destructure value of type: parens"
917 pairs.push_back({name, s("["sv) + std::to_string(index) + s("]"sv)});
918 break;
919 }
920 if (ast_cast<simple_table_t>(item) || 933 if (ast_cast<simple_table_t>(item) ||
921 item->getByPath<TableLit_t>()) { 934 item->getByPath<TableLit_t>()) {
922 auto subPairs = destructFromExp(pair); 935 auto subPairs = destructFromExp(pair);
923 for (auto& p : subPairs) { 936 for (auto& p : subPairs) {
924 pairs.push_back({p.first, s("["sv) + std::to_string(index) + s("]"sv) + p.second}); 937 pairs.push_back({p.isVariable, p.name,
938 s("["sv) + std::to_string(index) + s("]"sv) + p.structure});
925 } 939 }
926 break; 940 } else {
941 std::vector<std::string> temp;
942 transformExp(static_cast<Exp_t*>(pair), temp);
943 pairs.push_back({
944 item->getByPath<Callable_t, Variable_t>(),
945 temp.back(),
946 s("["sv) + std::to_string(index) + s("]"sv)
947 });
927 } 948 }
928 break; 949 break;
929 } 950 }
930 case "variable_pair"_id: { 951 case "variable_pair"_id: {
931 auto vp = static_cast<variable_pair_t*>(pair); 952 auto vp = static_cast<variable_pair_t*>(pair);
932 auto name = toString(vp->name); 953 auto name = toString(vp->name);
933 pairs.push_back({name, s("."sv) + name}); 954 pairs.push_back({true, name, s("."sv) + name});
934 break; 955 break;
935 } 956 }
936 case "normal_pair"_id: { 957 case "normal_pair"_id: {
@@ -940,23 +961,28 @@ private:
940 if (auto exp = np->value.as<Exp_t>()) { 961 if (auto exp = np->value.as<Exp_t>()) {
941 auto item = singleValueFrom(exp)->item.get(); 962 auto item = singleValueFrom(exp)->item.get();
942 if (!item) throw std::logic_error("Invalid destructure value"); 963 if (!item) throw std::logic_error("Invalid destructure value");
943 if (auto var = item->getByPath<Callable_t, Variable_t>()) {
944 pairs.push_back({toString(var), s("."sv) + toString(key)});
945 break;
946 }
947 if (ast_cast<simple_table_t>(item) || 964 if (ast_cast<simple_table_t>(item) ||
948 item->getByPath<TableLit_t>()) { 965 item->getByPath<TableLit_t>()) {
949 auto subPairs = destructFromExp(exp); 966 auto subPairs = destructFromExp(exp);
950 for (auto& p : subPairs) { 967 for (auto& p : subPairs) {
951 pairs.push_back({p.first, s("."sv) + toString(key) + p.second}); 968 pairs.push_back({p.isVariable, p.name,
969 s("."sv) + toString(key) + p.structure});
952 } 970 }
953 break; 971 } else {
972 std::vector<std::string> temp;
973 transformExp(exp, temp);
974 pairs.push_back({
975 item->getByPath<Callable_t, Variable_t>(),
976 temp.back(), s("."sv) + toString(key)
977 });
954 } 978 }
979 break;
955 } 980 }
956 if (np->value.as<TableBlock_t>()) { 981 if (np->value.as<TableBlock_t>()) {
957 auto subPairs = destructFromExp(pair); 982 auto subPairs = destructFromExp(pair);
958 for (auto& p : subPairs) { 983 for (auto& p : subPairs) {
959 pairs.push_back({p.first, s("."sv) + toString(key) + p.second}); 984 pairs.push_back({p.isVariable, p.name,
985 s("."sv) + toString(key) + p.structure});
960 } 986 }
961 } 987 }
962 break; 988 break;
@@ -990,16 +1016,14 @@ private:
990 ast_node* destructNode = expr->getByPath<Value_t, SimpleValue_t, TableLit_t>(); 1016 ast_node* destructNode = expr->getByPath<Value_t, SimpleValue_t, TableLit_t>();
991 if (destructNode || (destructNode = expr->getByPath<Value_t, simple_table_t>())) { 1017 if (destructNode || (destructNode = expr->getByPath<Value_t, simple_table_t>())) {
992 destructPairs.push_back({i,j}); 1018 destructPairs.push_back({i,j});
1019 pushScope();
993 transformAssignItem(*j, temp); 1020 transformAssignItem(*j, temp);
1021 popScope();
994 auto& destruct = destructs.emplace_back(); 1022 auto& destruct = destructs.emplace_back();
995 destruct.value = temp.back(); 1023 destruct.value = temp.back();
996 temp.pop_back(); 1024 temp.pop_back();
997 auto pairs = destructFromExp(expr); 1025 auto pairs = destructFromExp(expr);
998 for (auto& pair : pairs) { 1026 destruct.items = std::move(pairs);
999 auto& item = destruct.items.emplace_back();
1000 item.name = std::move(pair.first);
1001 item.structure = std::move(pair.second);
1002 }
1003 } 1027 }
1004 } 1028 }
1005 for (const auto& p : destructPairs) { 1029 for (const auto& p : destructPairs) {
@@ -1116,17 +1140,50 @@ private:
1116 } 1140 }
1117 auto assign = ifCondPairs.front().first->assign.get(); 1141 auto assign = ifCondPairs.front().first->assign.get();
1118 if (assign) { 1142 if (assign) {
1119 auto exp = ifCondPairs.front().first->condition.get();
1120 auto expList = new_ptr<ExpList_t>();
1121 expList->exprs.push_back(exp);
1122 auto assignment = new_ptr<Assignment_t>();
1123 assignment->assignable.set(expList);
1124 assignment->target.set(assign);
1125 if (usage != IfUsage::Closure) { 1143 if (usage != IfUsage::Closure) {
1126 temp.push_back(indent() + s("do"sv) + nll(assign)); 1144 temp.push_back(indent() + s("do"sv) + nll(assign));
1127 pushScope(); 1145 pushScope();
1128 } 1146 }
1129 transformAssignment(assignment, temp); 1147 auto exp = ifCondPairs.front().first->condition.get();
1148 if (auto table = exp->getByPath<Value_t, SimpleValue_t, TableLit_t>()) {
1149 std::string desVar = getUnusedName("_des_");
1150 bool storingValue = true;
1151 if (assign->values.objects().size() == 1) {
1152 auto var = variableFrom(assign->values.objects().front());
1153 if (!var.empty()) {
1154 desVar = var;
1155 storingValue = false;
1156 }
1157 }
1158 if (storingValue) {
1159 auto expList = toAst<ExpList_t>(desVar, ExpList);
1160 auto assignment = new_ptr<Assignment_t>();
1161 assignment->assignable.set(expList);
1162 assignment->target.set(assign);
1163 transformAssignment(assignment, temp);
1164 }
1165 {
1166 auto expList = new_ptr<ExpList_t>();
1167 expList->exprs.push_back(exp);
1168 auto assignOne = new_ptr<Assign_t>();
1169 auto valExp = toAst<Exp_t>(desVar, Exp);
1170 assignOne->values.push_back(valExp);
1171 auto assignment = new_ptr<Assignment_t>();
1172 assignment->assignable.set(expList);
1173 assignment->target.set(assignOne);
1174 transformAssignment(assignment, temp);
1175 auto pair = destructFromExp(exp);
1176 auto cond = toAst<Exp_t>(pair.front().name, Exp);
1177 ifCondPairs.front().first->condition.set(cond);
1178 }
1179 } else {
1180 auto expList = new_ptr<ExpList_t>();
1181 expList->exprs.push_back(exp);
1182 auto assignment = new_ptr<Assignment_t>();
1183 assignment->assignable.set(expList);
1184 assignment->target.set(assign);
1185 transformAssignment(assignment, temp);
1186 }
1130 } 1187 }
1131 for (const auto& pair : ifCondPairs) { 1188 for (const auto& pair : ifCondPairs) {
1132 if (pair.first) { 1189 if (pair.first) {
@@ -1260,7 +1317,7 @@ private:
1260 case "ClassDecl"_id: transformClassDeclClosure(static_cast<ClassDecl_t*>(value), out); break; 1317 case "ClassDecl"_id: transformClassDeclClosure(static_cast<ClassDecl_t*>(value), out); break;
1261 case "ForEach"_id: transformForEachClosure(static_cast<ForEach_t*>(value), out); break; 1318 case "ForEach"_id: transformForEachClosure(static_cast<ForEach_t*>(value), out); break;
1262 case "For"_id: transformForClosure(static_cast<For_t*>(value), out); break; 1319 case "For"_id: transformForClosure(static_cast<For_t*>(value), out); break;
1263 case "While"_id: transformWhile(value, out); break; 1320 case "While"_id: transformWhileClosure(static_cast<While_t*>(value), out); break;
1264 case "Do"_id: transformDoClosure(static_cast<Do_t*>(value), out); break; 1321 case "Do"_id: transformDoClosure(static_cast<Do_t*>(value), out); break;
1265 case "unary_exp"_id: transform_unary_exp(static_cast<unary_exp_t*>(value), out); break; 1322 case "unary_exp"_id: transform_unary_exp(static_cast<unary_exp_t*>(value), out); break;
1266 case "TblComprehension"_id: transformTblCompClosure(static_cast<TblComprehension_t*>(value), out); break; 1323 case "TblComprehension"_id: transformTblCompClosure(static_cast<TblComprehension_t*>(value), out); break;
@@ -1294,8 +1351,8 @@ private:
1294 popScope(); 1351 popScope();
1295 _buf << indent() << "end"sv; 1352 _buf << indent() << "end"sv;
1296 } else { 1353 } else {
1297 _buf << " end"sv;
1298 popScope(); 1354 popScope();
1355 _buf << " end"sv;
1299 } 1356 }
1300 } else { 1357 } else {
1301 if (funLit->body) { 1358 if (funLit->body) {
@@ -1312,8 +1369,8 @@ private:
1312 popScope(); 1369 popScope();
1313 _buf << indent() << "end"sv; 1370 _buf << indent() << "end"sv;
1314 } else { 1371 } else {
1315 _buf << " end"sv;
1316 popScope(); 1372 popScope();
1373 _buf << " end"sv;
1317 } 1374 }
1318 } 1375 }
1319 out.push_back(clearBuf()); 1376 out.push_back(clearBuf());
@@ -1329,8 +1386,7 @@ private:
1329 expListLow->exprs = expList->exprs; 1386 expListLow->exprs = expList->exprs;
1330 auto returnNode = new_ptr<Return_t>(); 1387 auto returnNode = new_ptr<Return_t>();
1331 returnNode->valueList.set(expListLow); 1388 returnNode->valueList.set(expListLow);
1332 auto statement = ast_cast<Statement_t>(last); 1389 last->content.set(returnNode);
1333 statement->content.set(returnNode);
1334 } 1390 }
1335 } 1391 }
1336 std::vector<std::string> temp; 1392 std::vector<std::string> temp;
@@ -1391,13 +1447,14 @@ private:
1391 out.push_back(indent() + s("return "sv) + temp.back() + nlr(returnNode)); 1447 out.push_back(indent() + s("return "sv) + temp.back() + nlr(returnNode));
1392 } 1448 }
1393 } else { 1449 } else {
1394 out.push_back(s("return"sv) + nll(returnNode)); 1450 out.push_back(indent() + s("return"sv) + nll(returnNode));
1395 } 1451 }
1396 } 1452 }
1397 1453
1398 void transformFnArgsDef(FnArgsDef_t* argsDef, std::vector<std::string>& out) { 1454 void transformFnArgsDef(FnArgsDef_t* argsDef, std::vector<std::string>& out) {
1399 if (!argsDef->defList) { 1455 if (!argsDef->defList) {
1400 out.push_back(Empty); 1456 out.push_back(Empty);
1457 out.push_back(Empty);
1401 return; 1458 return;
1402 } 1459 }
1403 transformFnArgDefList(argsDef->defList, out); 1460 transformFnArgDefList(argsDef->defList, out);
@@ -1419,7 +1476,6 @@ private:
1419 struct ArgItem { 1476 struct ArgItem {
1420 std::string name; 1477 std::string name;
1421 std::string assignSelf; 1478 std::string assignSelf;
1422 std::string defaultVal;
1423 }; 1479 };
1424 std::list<ArgItem> argItems; 1480 std::list<ArgItem> argItems;
1425 std::vector<std::string> temp; 1481 std::vector<std::string> temp;
@@ -1453,17 +1509,24 @@ private:
1453 break; 1509 break;
1454 } 1510 }
1455 } 1511 }
1512 forceAddToScope(arg.name);
1456 if (def->defaultValue) { 1513 if (def->defaultValue) {
1457 transformExp(static_cast<Exp_t*>(def->defaultValue.get()), temp); 1514 pushScope();
1458 arg.defaultVal = temp.front(); 1515 auto expList = toAst<ExpList_t>(arg.name, ExpList);
1459 temp.clear(); 1516 auto assign = new_ptr<Assign_t>();
1460 _buf << indent() << "if "sv << arg.name << " == nil then"sv << nll(def) << 1517 assign->values.push_back(def->defaultValue.get());
1461 indent(1) << arg.name << " = "sv << arg.defaultVal << nll(def) << 1518 auto assignment = new_ptr<Assignment_t>();
1462 indent() << "end"sv << nll(def); 1519 assignment->assignable.set(expList);
1520 assignment->target.set(assign);
1521 transformAssignment(assignment, temp);
1522 popScope();
1523 _buf << indent() << "if "sv << arg.name << " == nil then"sv << nll(def);
1524 _buf << temp.back();
1525 _buf << indent() << "end"sv << nll(def);
1526 temp.back() = clearBuf();
1463 } 1527 }
1464 if (varNames.empty()) varNames = arg.name; 1528 if (varNames.empty()) varNames = arg.name;
1465 else varNames.append(s(", "sv) + arg.name); 1529 else varNames.append(s(", "sv) + arg.name);
1466 forceAddToScope(arg.name);
1467 } 1530 }
1468 if (argDefList->varArg) { 1531 if (argDefList->varArg) {
1469 auto& arg = argItems.emplace_back(); 1532 auto& arg = argItems.emplace_back();
@@ -1471,7 +1534,7 @@ private:
1471 if (varNames.empty()) varNames = arg.name; 1534 if (varNames.empty()) varNames = arg.name;
1472 else varNames.append(s(", "sv) + arg.name); 1535 else varNames.append(s(", "sv) + arg.name);
1473 } 1536 }
1474 std::string initCodes = clearBuf(); 1537 std::string initCodes = join(temp);
1475 if (assignSelf) { 1538 if (assignSelf) {
1476 auto sjoin = [](const decltype(argItems)& items, int index) { 1539 auto sjoin = [](const decltype(argItems)& items, int index) {
1477 std::string result; 1540 std::string result;
@@ -1514,7 +1577,7 @@ private:
1514 pushScope(); 1577 pushScope();
1515 transformColonChain(chainValue, temp, ExpUsage::Return); 1578 transformColonChain(chainValue, temp, ExpUsage::Return);
1516 popScope(); 1579 popScope();
1517 temp.push_back(s("end)()"sv)); 1580 temp.push_back(indent() + s("end)()"sv));
1518 out.push_back(join(temp)); 1581 out.push_back(join(temp));
1519 } 1582 }
1520 1583
@@ -1670,28 +1733,37 @@ private:
1670 out.push_back(toString(num)); 1733 out.push_back(toString(num));
1671 } 1734 }
1672 1735
1673 void transformTableLit(TableLit_t* tableLit, std::vector<std::string>& out) { 1736 void transformTableLit(TableLit_t* table, std::vector<std::string>& out) {
1737 transformTable(table, table->values.objects(), out);
1738 }
1739
1740 void transformCompCommon(Comprehension_t* comp, std::vector<std::string>& out) {
1674 std::vector<std::string> temp; 1741 std::vector<std::string> temp;
1675 ast_node* lastNode = nullptr; 1742 auto compInner = comp->forLoop.get();
1676 for (auto value : tableLit->values.objects()) { 1743 for (auto item : compInner->items.objects()) {
1677 switch (value->getId()) { 1744 switch (item->getId()) {
1678 case "variable_pair"_id: 1745 case "CompForEach"_id:
1679 transform_variable_pair(static_cast<variable_pair_t*>(value), temp); 1746 transformCompForEach(static_cast<CompForEach_t*>(item), temp);
1680 break; 1747 break;
1681 case "normal_pair"_id: 1748 case "CompFor"_id:
1682 transform_normal_pair(static_cast<normal_pair_t*>(value), temp); 1749 transformCompFor(static_cast<CompFor_t*>(item), temp);
1683 break; 1750 break;
1684 case "Exp"_id: 1751 case "Exp"_id:
1752 transformExp(static_cast<Exp_t*>(item), temp);
1753 temp.back() = indent() + s("if "sv) + temp.back() + s(" then"sv) + nll(item);
1685 pushScope(); 1754 pushScope();
1686 transformExp(static_cast<Exp_t*>(value), temp);
1687 popScope();
1688 break; 1755 break;
1689 default: break;
1690 } 1756 }
1691 temp.back() = (lastNode ? s(","sv) + nll(lastNode) : Empty) + indent(1) + temp.back();
1692 lastNode = value;
1693 } 1757 }
1694 out.push_back(s("{"sv) + nll(tableLit) + join(temp) + nlr(tableLit) + indent() + s("}"sv)); 1758 transformStatement(comp->value.to<Statement_t>(), temp);
1759 auto value = temp.back();
1760 temp.pop_back();
1761 _buf << join(temp) << value;
1762 for (size_t i = 0; i < compInner->items.objects().size(); ++i) {
1763 popScope();
1764 _buf << indent() << "end"sv << nll(comp);
1765 }
1766 out.push_back(clearBuf());
1695 } 1767 }
1696 1768
1697 void transformComprehension(Comprehension_t* comp, std::vector<std::string>& out) { 1769 void transformComprehension(Comprehension_t* comp, std::vector<std::string>& out) {
@@ -1701,56 +1773,35 @@ private:
1701 addToScope(accum); 1773 addToScope(accum);
1702 addToScope(len); 1774 addToScope(len);
1703 auto compInner = comp->forLoop.get(); 1775 auto compInner = comp->forLoop.get();
1704 switch (compInner->compFor->getId()) { 1776 for (auto item : compInner->items.objects()) {
1705 case "CompForEach"_id: 1777 switch (item->getId()) {
1706 transformCompForEach(compInner->compFor.to<CompForEach_t>(), temp);
1707 break;
1708 case "CompFor"_id:
1709 transformCompFor(compInner->compFor.to<CompFor_t>(), temp);
1710 break;
1711 default: break;
1712 }
1713 std::vector<std::string> clauseCodes;
1714 for (auto clause : compInner->clauses.objects()) {
1715 pushScope();
1716 auto child = clause->getFirstChild();
1717 switch (child->getId()) {
1718 case "CompForEach"_id: 1778 case "CompForEach"_id:
1719 transformCompForEach(static_cast<CompForEach_t*>(child), clauseCodes); 1779 transformCompForEach(static_cast<CompForEach_t*>(item), temp);
1780 break;
1781 case "CompFor"_id:
1782 transformCompFor(static_cast<CompFor_t*>(item), temp);
1720 break; 1783 break;
1721 case "CompFor"_id: transformCompFor(static_cast<CompFor_t*>(child), clauseCodes); break;
1722 case "Exp"_id: 1784 case "Exp"_id:
1723 transformExp(static_cast<Exp_t*>(child), clauseCodes); 1785 transformExp(static_cast<Exp_t*>(item), temp);
1724 clauseCodes.back() = indent() + s("if "sv) + clauseCodes.back() + s(" then"sv) + nll(clause); 1786 temp.back() = indent() + s("if "sv) + temp.back() + s(" then"sv) + nll(item);
1787 pushScope();
1725 break; 1788 break;
1726 default: break;
1727 } 1789 }
1728 } 1790 }
1729 pushScope(); 1791 transformExp(comp->value.to<Exp_t>(), temp);
1730 transformExp(comp->value, temp);
1731 popScope();
1732 auto value = temp.back(); 1792 auto value = temp.back();
1733 temp.pop_back(); 1793 temp.pop_back();
1734 for (size_t i = 0; i < compInner->clauses.objects().size(); ++i) { 1794 for (size_t i = 0; i < compInner->items.objects().size(); ++i) {
1735 popScope(); 1795 popScope();
1736 } 1796 }
1737 _buf << indent() << "local "sv << accum << " = { }"sv << nll(comp); 1797 _buf << indent() << "local "sv << accum << " = { }"sv << nll(comp);
1738 _buf << indent() << "local "sv << len << " = 1"sv << nll(comp); 1798 _buf << indent() << "local "sv << len << " = 1"sv << nll(comp);
1739 _buf << temp.back(); 1799 _buf << join(temp);
1740 pushScope(); 1800 _buf << indent(int(temp.size())) << accum << "["sv << len << "] = "sv << value << nll(comp);
1741 if (clauseCodes.empty()) { 1801 _buf << indent(int(temp.size())) << len << " = "sv << len << " + 1"sv << nll(comp);
1742 _buf << indent() << accum << "["sv << len << "] = "sv << value << nll(comp); 1802 for (int ind = int(temp.size()) - 1; ind > -1 ; --ind) {
1743 _buf << indent() << len << " = "sv << len << " + 1"sv << nll(comp); 1803 _buf << indent(ind) << "end"sv << nll(comp);
1744 } else {
1745 _buf << join(clauseCodes);
1746 _buf << indent(int(clauseCodes.size())) << accum << "["sv << len << "] = "sv << value << nll(comp);
1747 _buf << indent(int(clauseCodes.size())) << len << " = "sv << len << " + 1"sv << nll(comp);
1748 for (int ind = int(clauseCodes.size()) - 1; ind > -1 ; --ind) {
1749 _buf << indent(ind) << "end"sv << nll(comp);
1750 }
1751 } 1804 }
1752 popScope();
1753 _buf << indent() << "end"sv << nll(comp);
1754 out.push_back(accum); 1805 out.push_back(accum);
1755 out.push_back(clearBuf()); 1806 out.push_back(clearBuf());
1756 } 1807 }
@@ -1759,11 +1810,18 @@ private:
1759 std::vector<std::string> temp; 1810 std::vector<std::string> temp;
1760 pushScope(); 1811 pushScope();
1761 transformComprehension(comp, temp); 1812 transformComprehension(comp, temp);
1762 transformExpList(expList, temp); 1813 auto assign = new_ptr<Assign_t>();
1814 assign->values.push_back(toAst<Exp_t>(temp.front(), Exp));
1815 auto assignment = new_ptr<Assignment_t>();
1816 assignment->assignable.set(expList);
1817 assignment->target.set(assign);
1818 assignment->m_begin.m_line = comp->m_end.m_line;
1819 assignment->m_end.m_line = comp->m_end.m_line;
1820 transformAssignment(assignment, temp);
1763 out.push_back( 1821 out.push_back(
1764 s("do"sv) + nll(comp) + 1822 s("do"sv) + nll(comp) +
1765 temp[1] + 1823 temp[1] +
1766 indent() + temp.back() + s(" = "sv) + temp.front() + nll(comp)); 1824 temp.back());
1767 popScope(); 1825 popScope();
1768 out.back() = out.back() + indent() + s("end"sv) + nlr(comp); 1826 out.back() = out.back() + indent() + s("end"sv) + nlr(comp);
1769 } 1827 }
@@ -1806,13 +1864,19 @@ private:
1806 default: break; 1864 default: break;
1807 } 1865 }
1808 } 1866 }
1867 std::list<std::string> varBefore, varAfter;
1809 switch (loopTarget->getId()) { 1868 switch (loopTarget->getId()) {
1810 case "star_exp"_id: { 1869 case "star_exp"_id: {
1811 auto star_exp = static_cast<star_exp_t*>(loopTarget); 1870 auto star_exp = static_cast<star_exp_t*>(loopTarget);
1812 auto listVar = getUnusedName("_list_"); 1871 bool newListVal = false;
1872 auto listVar = variableFrom(star_exp->value);
1873 if (listVar.empty()) {
1874 newListVal = true;
1875 listVar = getUnusedName("_list_");
1876 varBefore.push_back(listVar);
1877 }
1813 auto indexVar = getUnusedName("_index_"); 1878 auto indexVar = getUnusedName("_index_");
1814 addToScope(listVar); 1879 varAfter.push_back(indexVar);
1815 addToScope(indexVar);
1816 auto value = singleValueFrom(star_exp->value); 1880 auto value = singleValueFrom(star_exp->value);
1817 if (!value) throw std::logic_error("Invalid star syntax"); 1881 if (!value) throw std::logic_error("Invalid star syntax");
1818 bool endWithSlice = false; 1882 bool endWithSlice = false;
@@ -1846,12 +1910,14 @@ private:
1846 stepValue = temp.back(); 1910 stepValue = temp.back();
1847 temp.pop_back(); 1911 temp.pop_back();
1848 } 1912 }
1849 transformChain(chain, temp); 1913 if (newListVal) {
1850 _buf << indent() << "local "sv << listVar << " = "sv << temp.back() << nll(nameList); 1914 transformChain(chain, temp);
1915 _buf << indent() << "local "sv << listVar << " = "sv << temp.back() << nll(nameList);
1916 }
1851 std::string maxVar; 1917 std::string maxVar;
1852 if (!stopValue.empty()) { 1918 if (!stopValue.empty()) {
1853 maxVar = getUnusedName("_max_"); 1919 maxVar = getUnusedName("_max_");
1854 addToScope(maxVar); 1920 varBefore.push_back(maxVar);
1855 _buf << indent() << "local "sv << maxVar << " = "sv << stopValue << nll(nameList); 1921 _buf << indent() << "local "sv << maxVar << " = "sv << stopValue << nll(nameList);
1856 } 1922 }
1857 _buf << indent() << "for "sv << indexVar << " = "sv; 1923 _buf << indent() << "for "sv << indexVar << " = "sv;
@@ -1870,7 +1936,7 @@ private:
1870 } while (false); 1936 } while (false);
1871 if (!endWithSlice) { 1937 if (!endWithSlice) {
1872 transformExp(star_exp->value, temp); 1938 transformExp(star_exp->value, temp);
1873 _buf << indent() << "local "sv << listVar << " = "sv << temp.back() << nll(nameList); 1939 if (newListVal) _buf << indent() << "local "sv << listVar << " = "sv << temp.back() << nll(nameList);
1874 _buf << indent() << "for "sv << indexVar << " = 1, #"sv << listVar << " do"sv << nlr(loopTarget); 1940 _buf << indent() << "for "sv << indexVar << " = 1, #"sv << listVar << " do"sv << nlr(loopTarget);
1875 _buf << indent(1) << "local "sv << join(vars) << " = "sv << listVar << "["sv << indexVar << "]"sv << nll(nameList); 1941 _buf << indent(1) << "local "sv << join(vars) << " = "sv << listVar << "["sv << indexVar << "]"sv << nll(nameList);
1876 out.push_back(clearBuf()); 1942 out.push_back(clearBuf());
@@ -1911,6 +1977,9 @@ private:
1911 out.back().append(join(temp)); 1977 out.back().append(join(temp));
1912 popScope(); 1978 popScope();
1913 } 1979 }
1980 for (auto& var : varBefore) addToScope(var);
1981 pushScope();
1982 for (auto& var : varAfter) addToScope(var);
1914 } 1983 }
1915 1984
1916 void transformCompForEach(CompForEach_t* comp, std::vector<std::string>& out) { 1985 void transformCompForEach(CompForEach_t* comp, std::vector<std::string>& out) {
@@ -2017,8 +2086,14 @@ private:
2017 temp.push_back(indent() + len + s(" = "sv) + len + s(" + 1"sv) + nlr(forNode->body)); 2086 temp.push_back(indent() + len + s(" = "sv) + len + s(" + 1"sv) + nlr(forNode->body));
2018 popScope(); 2087 popScope();
2019 temp.push_back(indent() + s("end"sv) + nlr(forNode)); 2088 temp.push_back(indent() + s("end"sv) + nlr(forNode));
2020 transformExpList(assignExpList, temp); 2089 auto assign = new_ptr<Assign_t>();
2021 temp.back() = indent() + temp.back() + s(" = "sv) + accum + nlr(forNode); 2090 assign->values.push_back(toAst<Exp_t>(accum, Exp));
2091 auto assignment = new_ptr<Assignment_t>();
2092 assignment->assignable.set(assignExpList);
2093 assignment->target.set(assign);
2094 assignment->m_begin.m_line = forNode->m_end.m_line;
2095 assignment->m_end.m_line = forNode->m_end.m_line;
2096 transformAssignment(assignment, temp);
2022 popScope(); 2097 popScope();
2023 temp.push_back(indent() + s("end"sv) + nlr(forNode)); 2098 temp.push_back(indent() + s("end"sv) + nlr(forNode));
2024 out.push_back(join(temp)); 2099 out.push_back(join(temp));
@@ -2103,8 +2178,14 @@ private:
2103 temp.push_back(indent() + len + s(" = "sv) + len + s(" + 1"sv) + nlr(forEach->body)); 2178 temp.push_back(indent() + len + s(" = "sv) + len + s(" + 1"sv) + nlr(forEach->body));
2104 popScope(); 2179 popScope();
2105 temp.push_back(indent() + s("end"sv) + nlr(forEach)); 2180 temp.push_back(indent() + s("end"sv) + nlr(forEach));
2106 transformExpList(assignExpList, temp); 2181 auto assign = new_ptr<Assign_t>();
2107 temp.back() = indent() + temp.back() + s(" = "sv) + accum + nlr(forEach); 2182 assign->values.push_back(toAst<Exp_t>(accum, Exp));
2183 auto assignment = new_ptr<Assignment_t>();
2184 assignment->assignable.set(assignExpList);
2185 assignment->target.set(assign);
2186 assignment->m_begin.m_line = forEach->m_end.m_line;
2187 assignment->m_end.m_line = forEach->m_end.m_line;
2188 transformAssignment(assignment, temp);
2108 popScope(); 2189 popScope();
2109 temp.push_back(indent() + s("end"sv) + nlr(forEach)); 2190 temp.push_back(indent() + s("end"sv) + nlr(forEach));
2110 out.push_back(join(temp)); 2191 out.push_back(join(temp));
@@ -2116,7 +2197,6 @@ private:
2116 } 2197 }
2117 2198
2118 void transform_normal_pair(normal_pair_t* pair, std::vector<std::string>& out) { 2199 void transform_normal_pair(normal_pair_t* pair, std::vector<std::string>& out) {
2119 pushScope();
2120 auto key = pair->key.get(); 2200 auto key = pair->key.get();
2121 std::vector<std::string> temp; 2201 std::vector<std::string> temp;
2122 switch (key->getId()) { 2202 switch (key->getId()) {
@@ -2141,7 +2221,6 @@ private:
2141 default: break; 2221 default: break;
2142 } 2222 }
2143 out.push_back(temp[0] + s(" = "sv) + temp[1]); 2223 out.push_back(temp[0] + s(" = "sv) + temp[1]);
2144 popScope();
2145 } 2224 }
2146 2225
2147 void transformKeyName(KeyName_t* keyName, std::vector<std::string>& out) { 2226 void transformKeyName(KeyName_t* keyName, std::vector<std::string>& out) {
@@ -2247,9 +2326,9 @@ private:
2247 assignItem = temp.back(); 2326 assignItem = temp.back();
2248 temp.pop_back(); 2327 temp.pop_back();
2249 } else if (expList) { 2328 } else if (expList) {
2250 auto firstValue = firstValueFrom(expList); 2329 auto name = variableFrom(expList);
2251 if (auto name = firstValue->getByPath<ChainValue_t, Callable_t, Variable_t>()) { 2330 if (!name.empty()) {
2252 className = s("\""sv) + toString(name) + s("\""sv); 2331 className = s("\""sv) + name + s("\""sv);
2253 } 2332 }
2254 } 2333 }
2255 temp.push_back(indent() + s("do"sv) + nll(classDecl)); 2334 temp.push_back(indent() + s("do"sv) + nll(classDecl));
@@ -2268,7 +2347,7 @@ private:
2268 if (!info.first.empty()) { 2347 if (!info.first.empty()) {
2269 for (const auto& destruct : info.first) 2348 for (const auto& destruct : info.first)
2270 for (const auto& item : destruct.items) 2349 for (const auto& item : destruct.items)
2271 if (addToScope(item.name)) 2350 if (item.isVariable && addToScope(item.name))
2272 varDefs.push_back(item.name); 2351 varDefs.push_back(item.name);
2273 } 2352 }
2274 } 2353 }
@@ -2345,6 +2424,15 @@ private:
2345 temp.back() += s("{ }"sv) + nll(classDecl); 2424 temp.back() += s("{ }"sv) + nll(classDecl);
2346 } 2425 }
2347 temp.push_back(indent() + baseVar + s(".__index = "sv) + baseVar + nll(classDecl)); 2426 temp.push_back(indent() + baseVar + s(".__index = "sv) + baseVar + nll(classDecl));
2427 std::vector<std::string> tmp;
2428 if (usage == ExpUsage::Assignment) {
2429 auto assign = new_ptr<Assign_t>();
2430 assign->values.push_back(toAst<Exp_t>(classVar, Exp));
2431 auto assignment = new_ptr<Assignment_t>();
2432 assignment->assignable.set(expList);
2433 assignment->target.set(assign);
2434 transformAssignment(assignment, tmp);
2435 }
2348 if (extend) { 2436 if (extend) {
2349 _buf << indent() << "setmetatable("sv << baseVar << ", "sv << parentVar << ".__base)"sv << nll(classDecl); 2437 _buf << indent() << "setmetatable("sv << baseVar << ", "sv << parentVar << ".__base)"sv << nll(classDecl);
2350 } 2438 }
@@ -2408,9 +2496,7 @@ private:
2408 break; 2496 break;
2409 } 2497 }
2410 case ExpUsage::Assignment: { 2498 case ExpUsage::Assignment: {
2411 std::vector<std::string> tmp; 2499 _buf << tmp.back();
2412 transformExpList(expList, tmp);
2413 _buf << indent() << tmp.back() << " = "sv << classVar << nlr(classDecl);
2414 break; 2500 break;
2415 } 2501 }
2416 default: break; 2502 default: break;
@@ -2509,8 +2595,9 @@ private:
2509 return traversal::Continue; 2595 return traversal::Continue;
2510 }); 2596 });
2511 } while (false); 2597 } while (false);
2598 pushScope();
2512 if (type == MemType::Property) { 2599 if (type == MemType::Property) {
2513 setIndentOffset(-1); 2600 decIndentOffset();
2514 } 2601 }
2515 switch (keyValue->getId()) { 2602 switch (keyValue->getId()) {
2516 case "variable_pair"_id: 2603 case "variable_pair"_id:
@@ -2521,8 +2608,9 @@ private:
2521 break; 2608 break;
2522 } 2609 }
2523 if (type == MemType::Property) { 2610 if (type == MemType::Property) {
2524 setIndentOffset(0); 2611 incIndentOffset();
2525 } 2612 }
2613 popScope();
2526 out.push_back({temp.back(), type, keyValue}); 2614 out.push_back({temp.back(), type, keyValue});
2527 temp.clear(); 2615 temp.clear();
2528 ++count; 2616 ++count;
@@ -2542,42 +2630,51 @@ private:
2542 2630
2543 void transformWith(With_t* with, std::vector<std::string>& out) { 2631 void transformWith(With_t* with, std::vector<std::string>& out) {
2544 std::vector<std::string> temp; 2632 std::vector<std::string> temp;
2545 temp.push_back(indent() + s("do"sv) + nll(with));
2546 pushScope();
2547 std::string withVar; 2633 std::string withVar;
2634 bool scoped = false;
2548 if (with->assigns) { 2635 if (with->assigns) {
2549 auto vars = getAssignVars(with->valueList); 2636 auto vars = getAssignVars(with->valueList);
2550 if (vars.front().empty()) { 2637 if (vars.front().empty()) {
2551 withVar = getUnusedName("_with_"); 2638 if (with->assigns->values.objects().size() == 1) {
2552 { 2639 auto var = variableFrom(with->assigns->values.objects().front());
2640 if (!var.empty()) {
2641 withVar = var;
2642 }
2643 }
2644 if (withVar.empty()) {
2645 withVar = getUnusedName("_with_");
2553 auto assignment = new_ptr<Assignment_t>(); 2646 auto assignment = new_ptr<Assignment_t>();
2554 assignment->assignable.set(toAst<ExpList_t>(withVar, ExpList)); 2647 assignment->assignable.set(toAst<ExpList_t>(withVar, ExpList));
2555 auto assign = new_ptr<Assign_t>(); 2648 auto assign = new_ptr<Assign_t>();
2556 assign->values.push_back(with->assigns->values.objects().front()); 2649 assign->values.push_back(with->assigns->values.objects().front());
2557 assignment->target.set(assign); 2650 assignment->target.set(assign);
2651 scoped = true;
2652 temp.push_back(indent() + s("do"sv) + nll(with));
2653 pushScope();
2558 transformAssignment(assignment, temp); 2654 transformAssignment(assignment, temp);
2559 } 2655 }
2560 { 2656 auto assignment = new_ptr<Assignment_t>();
2561 auto assignment = new_ptr<Assignment_t>(); 2657 assignment->assignable.set(with->valueList);
2562 assignment->assignable.set(with->valueList); 2658 auto assign = new_ptr<Assign_t>();
2563 auto assign = new_ptr<Assign_t>(); 2659 assign->values.push_back(toAst<Exp_t>(withVar, Exp));
2564 assign->values.push_back(toAst<Exp_t>(withVar, Exp)); 2660 bool skipFirst = true;
2565 bool skipFirst = true; 2661 for (auto value : with->assigns->values.objects()) {
2566 for (auto value : with->assigns->values.objects()) { 2662 if (skipFirst) {
2567 if (skipFirst) { 2663 skipFirst = false;
2568 skipFirst = false; 2664 continue;
2569 continue;
2570 }
2571 assign->values.push_back(value);
2572 } 2665 }
2573 assignment->target.set(assign); 2666 assign->values.push_back(value);
2574 transformAssignment(assignment, temp);
2575 } 2667 }
2668 assignment->target.set(assign);
2669 transformAssignment(assignment, temp);
2576 } else { 2670 } else {
2577 withVar = vars.front(); 2671 withVar = vars.front();
2578 auto assignment = new_ptr<Assignment_t>(); 2672 auto assignment = new_ptr<Assignment_t>();
2579 assignment->assignable.set(with->valueList); 2673 assignment->assignable.set(with->valueList);
2580 assignment->target.set(with->assigns); 2674 assignment->target.set(with->assigns);
2675 scoped = true;
2676 temp.push_back(indent() + s("do"sv) + nll(with));
2677 pushScope();
2581 transformAssignment(assignment, temp); 2678 transformAssignment(assignment, temp);
2582 } 2679 }
2583 } else { 2680 } else {
@@ -2587,13 +2684,23 @@ private:
2587 auto assign = new_ptr<Assign_t>(); 2684 auto assign = new_ptr<Assign_t>();
2588 assign->values.dup(with->valueList->exprs); 2685 assign->values.dup(with->valueList->exprs);
2589 assignment->target.set(assign); 2686 assignment->target.set(assign);
2687 scoped = true;
2688 temp.push_back(indent() + s("do"sv) + nll(with));
2689 pushScope();
2590 transformAssignment(assignment, temp); 2690 transformAssignment(assignment, temp);
2591 } 2691 }
2692 auto exp = with->valueList->exprs.objects().front();
2693 if (exp->getByPath<Value_t, SimpleValue_t, TableLit_t>()) {
2694 auto pair = destructFromExp(exp);
2695 withVar = pair.front().name;
2696 }
2592 _withVars.push(withVar); 2697 _withVars.push(withVar);
2593 transformBody(with->body, temp); 2698 transformBody(with->body, temp);
2594 _withVars.pop(); 2699 _withVars.pop();
2595 popScope(); 2700 if (scoped) {
2596 temp.push_back(indent() + s("end"sv) + nll(with)); 2701 popScope();
2702 temp.push_back(indent() + s("end"sv) + nll(with));
2703 }
2597 out.push_back(join(temp)); 2704 out.push_back(join(temp));
2598 } 2705 }
2599 2706
@@ -2643,6 +2750,10 @@ private:
2643 assign->values.dup(values->valueList->exprs); 2750 assign->values.dup(values->valueList->exprs);
2644 assignment->target.set(assign); 2751 assignment->target.set(assign);
2645 transformAssignment(assignment, out); 2752 transformAssignment(assignment, out);
2753 } else {
2754 for (auto name : values->nameList->names.objects()) {
2755 addExportedVar(toString(name));
2756 }
2646 } 2757 }
2647 break; 2758 break;
2648 } 2759 }
@@ -2651,19 +2762,24 @@ private:
2651 } 2762 }
2652 } 2763 }
2653 2764
2654 void transform_simple_table(simple_table_t* table, std::vector<std::string>& out) { 2765 void transformTable(ast_node* table, const std::list<ast_node*>& pairs, std::vector<std::string>& out) {
2655 std::vector<std::string> temp; 2766 std::vector<std::string> temp;
2656 pushScope(); 2767 pushScope();
2657 const auto& pairs = table->pairs.objects();
2658 for (auto pair : pairs) { 2768 for (auto pair : pairs) {
2659 switch (pair->getId()) { 2769 switch (pair->getId()) {
2770 case "Exp"_id: transformExp(static_cast<Exp_t*>(pair), temp); break;
2660 case "variable_pair"_id: transform_variable_pair(static_cast<variable_pair_t*>(pair), temp); break; 2771 case "variable_pair"_id: transform_variable_pair(static_cast<variable_pair_t*>(pair), temp); break;
2661 case "normal_pair"_id: transform_normal_pair(static_cast<normal_pair_t*>(pair), temp); break; 2772 case "normal_pair"_id: transform_normal_pair(static_cast<normal_pair_t*>(pair), temp); break;
2662 } 2773 }
2663 temp.back() = indent() + temp.back() + (pair == pairs.back() ? Empty : s(","sv)) + nll(pair); 2774 temp.back() = indent() + temp.back() + (pair == pairs.back() ? Empty : s(","sv)) + nll(pair);
2664 } 2775 }
2776 out.push_back(s("{"sv) + nll(table) + join(temp));
2665 popScope(); 2777 popScope();
2666 out.push_back(s("{"sv) + nll(table) + join(temp) + s("}"sv)); 2778 out.back() += (indent() + s("}"sv));
2779 }
2780
2781 void transform_simple_table(simple_table_t* table, std::vector<std::string>& out) {
2782 transformTable(table, table->pairs.objects(), out);
2667 } 2783 }
2668 2784
2669 void transformTblComprehension(TblComprehension_t* comp, std::vector<std::string>& out) { 2785 void transformTblComprehension(TblComprehension_t* comp, std::vector<std::string>& out) {
@@ -2672,60 +2788,41 @@ private:
2672 addToScope(tbl); 2788 addToScope(tbl);
2673 std::vector<std::string> temp; 2789 std::vector<std::string> temp;
2674 auto compInner = comp->forLoop.get(); 2790 auto compInner = comp->forLoop.get();
2675 switch (compInner->compFor->getId()) { 2791 for (auto item : compInner->items.objects()) {
2676 case "CompForEach"_id: 2792 switch (item->getId()) {
2677 transformCompForEach(compInner->compFor.to<CompForEach_t>(), temp);
2678 break;
2679 case "CompFor"_id:
2680 transformCompFor(compInner->compFor.to<CompFor_t>(), temp);
2681 break;
2682 default: break;
2683 }
2684 std::vector<std::string> clauseCodes;
2685 for (auto clause : compInner->clauses.objects()) {
2686 pushScope();
2687 auto child = clause->getFirstChild();
2688 switch (child->getId()) {
2689 case "CompForEach"_id: 2793 case "CompForEach"_id:
2690 transformCompForEach(static_cast<CompForEach_t*>(child), clauseCodes); 2794 transformCompForEach(static_cast<CompForEach_t*>(item), temp);
2691 break; 2795 break;
2692 case "CompFor"_id: 2796 case "CompFor"_id:
2693 transformCompFor(static_cast<CompFor_t*>(child), clauseCodes); 2797 transformCompFor(static_cast<CompFor_t*>(item), temp);
2694 break; 2798 break;
2695 case "Exp"_id: 2799 case "Exp"_id:
2696 transformExp(static_cast<Exp_t*>(child), clauseCodes); 2800 transformExp(static_cast<Exp_t*>(item), temp);
2697 clauseCodes.back() = indent() + s("if "sv) + clauseCodes.back() + s(" then"sv) + nll(clause); 2801 temp.back() = indent() + s("if "sv) + temp.back() + s(" then"sv) + nll(item);
2802 pushScope();
2698 break; 2803 break;
2699 default: break;
2700 } 2804 }
2701 } 2805 }
2702 pushScope();
2703 transformExp(comp->key, kv); 2806 transformExp(comp->key, kv);
2704 popScope();
2705 if (comp->value) { 2807 if (comp->value) {
2706 transformExp(comp->value->value, kv); 2808 transformExp(comp->value->value, kv);
2707 } 2809 }
2708 for (size_t i = 0; i < compInner->clauses.objects().size(); ++i) { 2810 for (size_t i = 0; i < compInner->items.objects().size(); ++i) {
2709 popScope(); 2811 popScope();
2710 } 2812 }
2711 _buf << indent() << "local "sv << tbl << " = { }"sv << nll(comp); 2813 _buf << indent() << "local "sv << tbl << " = { }"sv << nll(comp);
2712 _buf << temp.back(); 2814 _buf << join(temp);
2713 pushScope(); 2815 pushScope();
2714 if (!comp->value) { 2816 if (!comp->value) {
2715 auto keyVar = getUnusedName("_key_"); 2817 auto keyVar = getUnusedName("_key_");
2716 auto valVar = getUnusedName("_val_"); 2818 auto valVar = getUnusedName("_val_");
2717 _buf << indent() << "local "sv << keyVar << ", "sv << valVar << " = "sv << kv.front() << nll(comp); 2819 _buf << indent(int(temp.size())-1) << "local "sv << keyVar << ", "sv << valVar << " = "sv << kv.front() << nll(comp);
2718 kv.front() = keyVar; 2820 kv.front() = keyVar;
2719 kv.push_back(valVar); 2821 kv.push_back(valVar);
2720 } 2822 }
2721 if (clauseCodes.empty()) { 2823 _buf << indent(int(temp.size())-1) << tbl << "["sv << kv.front() << "] = "sv << kv.back() << nll(comp);
2722 _buf << indent() << tbl << "["sv << kv.front() << "] = "sv << kv.back() << nll(comp); 2824 for (int ind = int(temp.size()) - 2; ind > -1 ; --ind) {
2723 } else { 2825 _buf << indent(ind) << "end"sv << nll(comp);
2724 _buf << join(clauseCodes);
2725 _buf << indent(int(clauseCodes.size())) << tbl << "["sv << kv.front() << "] = "sv << kv.back() << nll(comp);
2726 for (int ind = int(clauseCodes.size()) - 1; ind > -1 ; --ind) {
2727 _buf << indent(ind) << "end"sv << nll(comp);
2728 }
2729 } 2826 }
2730 popScope(); 2827 popScope();
2731 _buf << indent() << "end"sv << nll(comp); 2828 _buf << indent() << "end"sv << nll(comp);
@@ -2737,14 +2834,18 @@ private:
2737 std::vector<std::string> temp; 2834 std::vector<std::string> temp;
2738 pushScope(); 2835 pushScope();
2739 transformTblComprehension(comp, temp); 2836 transformTblComprehension(comp, temp);
2740 const auto& tbVar = temp.front(); 2837 auto assign = new_ptr<Assign_t>();
2741 const auto& compBody = temp.back(); 2838 assign->values.push_back(toAst<Exp_t>(temp.front(), Exp));
2742 transformExpList(expList, temp); 2839 auto assignment = new_ptr<Assignment_t>();
2743 const auto& assignLeft = temp.back(); 2840 assignment->assignable.set(expList);
2841 assignment->target.set(assign);
2842 assignment->m_begin.m_line = comp->m_end.m_line;
2843 assignment->m_end.m_line = comp->m_end.m_line;
2844 transformAssignment(assignment, temp);
2744 out.push_back( 2845 out.push_back(
2745 s("do"sv) + nll(comp) + 2846 s("do"sv) + nll(comp) +
2746 compBody + 2847 temp[1] +
2747 indent() + assignLeft + s(" = "sv) + tbVar + nll(comp)); 2848 temp.back());
2748 popScope(); 2849 popScope();
2749 out.back() = out.back() + indent() + s("end"sv) + nlr(comp); 2850 out.back() = out.back() + indent() + s("end"sv) + nlr(comp);
2750 } 2851 }
@@ -2782,22 +2883,12 @@ private:
2782 } 2883 }
2783 _buf << indent() << "for "sv << varName << " = "sv << temp[0] << ", "sv << temp[1] << (temp[2].empty() ? Empty : s(", "sv) + temp[2]) << " do"sv << nll(comp); 2884 _buf << indent() << "for "sv << varName << " = "sv << temp[0] << ", "sv << temp[1] << (temp[2].empty() ? Empty : s(", "sv) + temp[2]) << " do"sv << nll(comp);
2784 out.push_back(clearBuf()); 2885 out.push_back(clearBuf());
2886 pushScope();
2887 addToScope(varName);
2785 } 2888 }
2786 2889
2787 void transformTableBlock(TableBlock_t* table, std::vector<std::string>& out) { 2890 void transformTableBlock(TableBlock_t* table, std::vector<std::string>& out) {
2788 std::vector<std::string> temp; 2891 transformTable(table, table->values.objects(), out);
2789 pushScope();
2790 const auto& pairs = table->values.objects();
2791 for (auto pair : pairs) {
2792 switch (pair->getId()) {
2793 case "Exp"_id: transformExp(static_cast<Exp_t*>(pair), temp); break;
2794 case "variable_pair"_id: transform_variable_pair(static_cast<variable_pair_t*>(pair), temp); break;
2795 case "normal_pair"_id: transform_normal_pair(static_cast<normal_pair_t*>(pair), temp); break;
2796 }
2797 temp.back() = indent() + temp.back() + (pair == pairs.back() ? Empty : s(","sv)) + nll(pair);
2798 }
2799 popScope();
2800 out.push_back(s("{"sv) + nll(table) + join(temp) + s("}"sv));
2801 } 2892 }
2802 2893
2803 void transformDo(Do_t* doNode, std::vector<std::string>& out, bool implicitReturn = false) { 2894 void transformDo(Do_t* doNode, std::vector<std::string>& out, bool implicitReturn = false) {
@@ -2820,9 +2911,166 @@ private:
2820 out.push_back(join(temp)); 2911 out.push_back(join(temp));
2821 } 2912 }
2822 2913
2914 void transformImport(Import_t* import, std::vector<std::string>& out) {
2915 std::vector<std::string> temp;
2916 auto objVar = variableFrom(import->exp);
2917 ast_ptr<Assignment_t, false, false> objAssign;
2918 if (objVar.empty()) {
2919 objVar = getUnusedName("_obj_"sv);
2920 auto expList = toAst<ExpList_t>(objVar, ExpList);
2921 auto assign = new_ptr<Assign_t>();
2922 assign->values.push_back(import->exp);
2923 auto assignment = new_ptr<Assignment_t>();
2924 assignment->assignable.set(expList);
2925 assignment->target.set(assign);
2926 objAssign.set(assignment);
2927 }
2928 auto expList = new_ptr<ExpList_t>();
2929 auto assign = new_ptr<Assign_t>();
2930 for (auto name : import->names.objects()) {
2931 switch (name->getId()) {
2932 case "Variable"_id: {
2933 auto var = ast_to<Variable_t>(name);
2934 {
2935 auto callable = toAst<Callable_t>(objVar, Callable);
2936 auto dotChainItem = new_ptr<DotChainItem_t>();
2937 dotChainItem->name.set(var->name);
2938 auto chain = new_ptr<Chain_t>();
2939 chain->items.push_back(callable);
2940 chain->items.push_back(dotChainItem);
2941 auto chainValue = new_ptr<ChainValue_t>();
2942 chainValue->caller.set(chain);
2943 auto value = new_ptr<Value_t>();
2944 value->item.set(chainValue);
2945 auto exp = new_ptr<Exp_t>();
2946 exp->value.set(value);
2947 assign->values.push_back(exp);
2948 }
2949 auto callable = new_ptr<Callable_t>();
2950 callable->item.set(var);
2951 auto chainValue = new_ptr<ChainValue_t>();
2952 chainValue->caller.set(callable);
2953 auto value = new_ptr<Value_t>();
2954 value->item.set(chainValue);
2955 auto exp = new_ptr<Exp_t>();
2956 exp->value.set(value);
2957 expList->exprs.push_back(exp);
2958 break;
2959 }
2960 case "colon_import_name"_id: {
2961 auto var = static_cast<colon_import_name_t*>(name)->name.get();
2962 {
2963 auto nameNode = var->name.get();
2964 auto callable = toAst<Callable_t>(objVar, Callable);
2965 auto colonChain = new_ptr<ColonChainItem_t>();
2966 colonChain->name.set(nameNode);
2967 auto chain = new_ptr<Chain_t>();
2968 chain->items.push_back(callable);
2969 chain->items.push_back(colonChain);
2970 auto chainValue = new_ptr<ChainValue_t>();
2971 chainValue->caller.set(chain);
2972 auto value = new_ptr<Value_t>();
2973 value->item.set(chainValue);
2974 auto exp = new_ptr<Exp_t>();
2975 exp->value.set(value);
2976 assign->values.push_back(exp);
2977 }
2978 auto callable = new_ptr<Callable_t>();
2979 callable->item.set(var);
2980 auto chainValue = new_ptr<ChainValue_t>();
2981 chainValue->caller.set(callable);
2982 auto value = new_ptr<Value_t>();
2983 value->item.set(chainValue);
2984 auto exp = new_ptr<Exp_t>();
2985 exp->value.set(value);
2986 expList->exprs.push_back(exp);
2987 break;
2988 }
2989 }
2990 }
2991 if (objAssign) {
2992 auto preDef = getPredefine(transformAssignDefs(expList));
2993 if (!preDef.empty()) {
2994 temp.push_back(preDef + nll(import));
2995 }
2996 temp.push_back(indent() + s("do"sv) + nll(import));
2997 pushScope();
2998 transformAssignment(objAssign, temp);
2999 }
3000 auto assignment = new_ptr<Assignment_t>();
3001 assignment->assignable.set(expList);
3002 assignment->target.set(assign);
3003 transformAssignment(assignment, temp);
3004 if (objAssign) {
3005 popScope();
3006 temp.push_back(indent() + s("end"sv) + nlr(import));
3007 }
3008 out.push_back(join(temp));
3009 }
3010
3011 void transformWhileClosure(While_t* whileNode, std::vector<std::string>& out, ExpList_t* expList = nullptr) {
3012 std::vector<std::string> temp;
3013 if (expList) {
3014 temp.push_back(indent() + s("do"sv) + nll(whileNode));
3015 } else {
3016 temp.push_back(s("(function() "sv) + nll(whileNode));
3017 }
3018 pushScope();
3019 auto accumVar = getUnusedName("_accum_"sv);
3020 addToScope(accumVar);
3021 auto lenVar = getUnusedName("_len_"sv);
3022 addToScope(lenVar);
3023 temp.push_back(indent() + s("local "sv) + accumVar + s(" = { }"sv) + nll(whileNode));
3024 temp.push_back(indent() + s("local "sv) + lenVar + s(" = 1"sv) + nll(whileNode));
3025 transformExp(whileNode->condition, temp);
3026 temp.back() = indent() + s("while "sv) + temp.back() + s(" do"sv) + nll(whileNode);
3027 pushScope();
3028 auto last = lastStatementFrom(whileNode->body);
3029 auto valueList = last ? last->content.as<ExpList_t>() : nullptr;
3030 if (last && valueList) {
3031 auto newAssignment = new_ptr<Assignment_t>();
3032 newAssignment->assignable.set(toAst<ExpList_t>(accumVar + s("["sv) + lenVar + s("]"sv), ExpList));
3033 auto assign = new_ptr<Assign_t>();
3034 assign->values.dup(valueList->exprs);
3035 newAssignment->target.set(assign);
3036 last->content.set(newAssignment);
3037 }
3038 transformBody(whileNode->body, temp);
3039 temp.push_back(indent() + lenVar + s(" = "sv) + lenVar + s(" + 1"sv) + nlr(whileNode));
3040 popScope();
3041 temp.push_back(indent() + s("end"sv) + nlr(whileNode));
3042 if (expList) {
3043 auto assign = new_ptr<Assign_t>();
3044 assign->values.push_back(toAst<Exp_t>(accumVar, Exp));
3045 auto assignment = new_ptr<Assignment_t>();
3046 assignment->assignable.set(expList);
3047 assignment->target.set(assign);
3048 transformAssignment(assignment, temp);
3049 } else {
3050 temp.push_back(indent() + s("return "sv) + accumVar + nlr(whileNode));
3051 }
3052 popScope();
3053 if (expList) {
3054 temp.push_back(indent() + s("end"sv) + nlr(whileNode));
3055 } else {
3056 temp.push_back(indent() + s("end)()"sv));
3057 }
3058 out.push_back(join(temp));
3059 }
3060
3061 void transformWhile(While_t* whileNode, std::vector<std::string>& out) {
3062 std::vector<std::string> temp;
3063 pushScope();
3064 transformExp(whileNode->condition, temp);
3065 transformBody(whileNode->body, temp);
3066 popScope();
3067 _buf << indent() << "while "sv << temp.front() << " do"sv << nll(whileNode);
3068 _buf << temp.back();
3069 _buf << indent() << "end"sv << nlr(whileNode);
3070 out.push_back(clearBuf());
3071 }
3072
2823 void transformUpdate(ast_node* node, std::vector<std::string>& out) {noop(node, out);} 3073 void transformUpdate(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
2824 void transformImport(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
2825 void transformWhile(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
2826 void transformSwitch(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);} 3074 void transformSwitch(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
2827 void transformLocal(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);} 3075 void transformLocal(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
2828 void transformBreakLoop(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);} 3076 void transformBreakLoop(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
@@ -2833,17 +3081,80 @@ const std::string MoonCompliler::Empty;
2833 3081
2834int main() 3082int main()
2835{ 3083{
2836 std::string s = R"TestCodesHere(a = 1 + do 3084 std::string s = R"TestCodesHere(
2837 123 3085
3086hi = [x*2 for _, x in ipairs{1,2,3,4}]
3087
3088items = {1,2,3,4,5,6}
3089
3090[z for z in ipairs items when z > 4]
3091
3092rad = [{a} for a in ipairs {
3093 1,2,3,4,5,6,
3094} when good_number a]
3095
3096
3097[z for z in items for j in list when z > 4]
3098
3099require "util"
3100
3101dump = (x) -> print util.dump x
3102
3103range = (count) ->
3104 i = 0
3105 return coroutine.wrap ->
3106 while i < count
3107 coroutine.yield i
3108 i = i + 1
3109
3110dump [x for x in range 10]
3111dump [{x, y} for x in range 5 when x > 2 for y in range 5]
3112
3113things = [x + y for x in range 10 when x > 5 for y in range 10 when y > 7]
3114
3115print x,y for x in ipairs{1,2,4} for y in ipairs{1,2,3} when x != 2
3116
3117print "hello", x for x in items
3118
3119[x for x in x]
3120x = [x for x in x]
3121
3122print x,y for x in ipairs{1,2,4} for y in ipairs{1,2,3} when x != 2
3123
3124double = [x*2 for x in *items]
3125
3126print x for x in *double
3127
3128cut = [x for x in *items when x > 3]
3129
3130hello = [x + y for x in *items for y in *items]
3131
3132print z for z in *hello
3133
3134
3135-- slice
3136x = {1, 2, 3, 4, 5, 6, 7}
3137print y for y in *x[2,-5,2]
3138print y for y in *x[,3]
3139print y for y in *x[2,]
3140print y for y in *x[,,2]
3141print y for y in *x[2,,2]
3142
3143a, b, c = 1, 5, 2
3144print y for y in *x[a,b,c]
3145
3146
3147normal = (hello) ->
3148 [x for x in yeah]
3149
3150
3151test = x 1,2,3,4,5
3152print thing for thing in *test
2838 3153
2839a = do 3154-> a = b for row in *rows
2840 123
2841 3155
2842do
2843 123
2844 3156
2845do 3157)TestCodesHere";
2846 123)TestCodesHere";
2847 MoonCompliler{}.complile(s); 3158 MoonCompliler{}.complile(s);
2848 return 0; 3159 return 0;
2849} 3160}
diff --git a/MoonParser/moon_ast.h b/MoonParser/moon_ast.h
index 4f6dc92..adaf29f 100644
--- a/MoonParser/moon_ast.h
+++ b/MoonParser/moon_ast.h
@@ -101,13 +101,9 @@ AST_END(colon_import_name)
101 101
102class Exp_t; 102class Exp_t;
103 103
104AST_NODE(ImportName, "ImportName"_id)
105 ast_ptr<ast_node> name; // colon_import_name_t | Variable_t
106AST_END(ImportName)
107
108AST_NODE(Import, "Import"_id) 104AST_NODE(Import, "Import"_id)
109 ast_ptr<Seperator_t> sep; 105 ast_ptr<Seperator_t> sep;
110 ast_list<ImportName_t> names; 106 ast_sel_list<colon_import_name_t, Variable_t> names;
111 ast_ptr<Exp_t> exp; 107 ast_ptr<Exp_t> exp;
112AST_END(Import) 108AST_END(Import)
113 109
@@ -191,9 +187,10 @@ AST_NODE(Do, "Do"_id)
191AST_END(Do) 187AST_END(Do)
192 188
193class CompInner_t; 189class CompInner_t;
190class Statement_t;
194 191
195AST_NODE(Comprehension, "Comprehension"_id) 192AST_NODE(Comprehension, "Comprehension"_id)
196 ast_ptr<Exp_t> value; 193 ast_sel<Exp_t, Statement_t> value;
197 ast_ptr<CompInner_t> forLoop; 194 ast_ptr<CompInner_t> forLoop;
198AST_END(Comprehension) 195AST_END(Comprehension)
199 196
@@ -223,14 +220,9 @@ AST_NODE(CompFor, "CompFor"_id)
223 ast_ptr<for_step_value_t, true> stepValue; 220 ast_ptr<for_step_value_t, true> stepValue;
224AST_END(CompFor) 221AST_END(CompFor)
225 222
226AST_NODE(CompClause, "CompClause"_id)
227 ast_ptr<ast_node> nestExp; // CompFor_t | CompForEach_t | Exp_t
228AST_END(CompClause)
229
230AST_NODE(CompInner, "CompInner"_id) 223AST_NODE(CompInner, "CompInner"_id)
231 ast_ptr<ast_node> compFor; // CompFor_t | CompForEach_t
232 ast_ptr<Seperator_t> sep; 224 ast_ptr<Seperator_t> sep;
233 ast_list<CompClause_t> clauses; 225 ast_sel_list<CompFor_t, CompForEach_t, Exp_t> items;
234AST_END(CompInner) 226AST_END(CompInner)
235 227
236class TableBlock_t; 228class TableBlock_t;
diff --git a/MoonParser/moon_parser.cpp b/MoonParser/moon_parser.cpp
index 99cf1a1..3c3078a 100644
--- a/MoonParser/moon_parser.cpp
+++ b/MoonParser/moon_parser.cpp
@@ -208,11 +208,11 @@ extern rule CompInner;
208 208
209rule Comprehension = sym('[') >> Exp >> CompInner >> sym(']'); 209rule Comprehension = sym('[') >> Exp >> CompInner >> sym(']');
210rule comp_value = sym(',') >> Exp; 210rule comp_value = sym(',') >> Exp;
211rule TblComprehension = sym('{') >> (Exp >> -comp_value) >> CompInner >> sym('}'); 211rule TblComprehension = sym('{') >> (Exp >> -comp_value) >> CompInner >> sym('}');
212 212
213extern rule CompForEach, CompFor, CompClause; 213extern rule CompForEach, CompFor, CompClause;
214 214
215rule CompInner = (CompForEach | CompFor) >> Seperator >> *CompClause; 215rule CompInner = Seperator >> (CompForEach | CompFor) >> *CompClause;
216rule star_exp = sym('*') >> Exp; 216rule star_exp = sym('*') >> Exp;
217rule CompForEach = key("for") >> AssignableNameList >> key("in") >> (star_exp | Exp); 217rule CompForEach = key("for") >> AssignableNameList >> key("in") >> (star_exp | Exp);
218rule CompFor = key("for") >> Space >> Variable >> sym('=') >> Exp >> sym(',') >> Exp >> -for_step_value; 218rule CompFor = key("for") >> Space >> Variable >> sym('=') >> Exp >> sym(',') >> Exp >> -for_step_value;