diff options
author | Li Jin <dragon-fly@qq.com> | 2019-09-24 20:17:22 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2019-09-24 20:17:22 +0800 |
commit | 0a4164b929e9532236df5645464e68188b3dd4c3 (patch) | |
tree | b1a3a6d33cc98d9dbe219bf8763cfa977f1c4d48 | |
parent | 50eeb71a81d86cd7eb334058d1fd2d7eb899e12d (diff) | |
download | yuescript-0a4164b929e9532236df5645464e68188b3dd4c3.tar.gz yuescript-0a4164b929e9532236df5645464e68188b3dd4c3.tar.bz2 yuescript-0a4164b929e9532236df5645464e68188b3dd4c3.zip |
updating.
-rw-r--r-- | MoonParser.xcodeproj/project.pbxproj | 4 | ||||
-rw-r--r-- | MoonParser/moon_ast.cpp | 989 | ||||
-rw-r--r-- | MoonParser/moon_ast.h | 16 | ||||
-rw-r--r-- | MoonParser/moon_parser.cpp | 4 |
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) | |||
36 | AST_IMPL(NameList) | 36 | AST_IMPL(NameList) |
37 | AST_IMPL(Local) | 37 | AST_IMPL(Local) |
38 | AST_IMPL(colon_import_name) | 38 | AST_IMPL(colon_import_name) |
39 | AST_IMPL(ImportName) | ||
40 | AST_IMPL(Import) | 39 | AST_IMPL(Import) |
41 | AST_IMPL(ExpListLow) | 40 | AST_IMPL(ExpListLow) |
42 | AST_IMPL(ExpList) | 41 | AST_IMPL(ExpList) |
@@ -58,7 +57,6 @@ AST_IMPL(TblComprehension) | |||
58 | AST_IMPL(star_exp) | 57 | AST_IMPL(star_exp) |
59 | AST_IMPL(CompForEach) | 58 | AST_IMPL(CompForEach) |
60 | AST_IMPL(CompFor) | 59 | AST_IMPL(CompFor) |
61 | AST_IMPL(CompClause) | ||
62 | AST_IMPL(CompInner) | 60 | AST_IMPL(CompInner) |
63 | AST_IMPL(Assign) | 61 | AST_IMPL(Assign) |
64 | AST_IMPL(update_op) | 62 | AST_IMPL(update_op) |
@@ -154,7 +152,7 @@ public: | |||
154 | private: | 152 | private: |
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 | ||
2834 | int main() | 3082 | int main() |
2835 | { | 3083 | { |
2836 | std::string s = R"TestCodesHere(a = 1 + do | 3084 | std::string s = R"TestCodesHere( |
2837 | 123 | 3085 | |
3086 | hi = [x*2 for _, x in ipairs{1,2,3,4}] | ||
3087 | |||
3088 | items = {1,2,3,4,5,6} | ||
3089 | |||
3090 | [z for z in ipairs items when z > 4] | ||
3091 | |||
3092 | rad = [{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 | |||
3099 | require "util" | ||
3100 | |||
3101 | dump = (x) -> print util.dump x | ||
3102 | |||
3103 | range = (count) -> | ||
3104 | i = 0 | ||
3105 | return coroutine.wrap -> | ||
3106 | while i < count | ||
3107 | coroutine.yield i | ||
3108 | i = i + 1 | ||
3109 | |||
3110 | dump [x for x in range 10] | ||
3111 | dump [{x, y} for x in range 5 when x > 2 for y in range 5] | ||
3112 | |||
3113 | things = [x + y for x in range 10 when x > 5 for y in range 10 when y > 7] | ||
3114 | |||
3115 | print x,y for x in ipairs{1,2,4} for y in ipairs{1,2,3} when x != 2 | ||
3116 | |||
3117 | print "hello", x for x in items | ||
3118 | |||
3119 | [x for x in x] | ||
3120 | x = [x for x in x] | ||
3121 | |||
3122 | print x,y for x in ipairs{1,2,4} for y in ipairs{1,2,3} when x != 2 | ||
3123 | |||
3124 | double = [x*2 for x in *items] | ||
3125 | |||
3126 | print x for x in *double | ||
3127 | |||
3128 | cut = [x for x in *items when x > 3] | ||
3129 | |||
3130 | hello = [x + y for x in *items for y in *items] | ||
3131 | |||
3132 | print z for z in *hello | ||
3133 | |||
3134 | |||
3135 | -- slice | ||
3136 | x = {1, 2, 3, 4, 5, 6, 7} | ||
3137 | print y for y in *x[2,-5,2] | ||
3138 | print y for y in *x[,3] | ||
3139 | print y for y in *x[2,] | ||
3140 | print y for y in *x[,,2] | ||
3141 | print y for y in *x[2,,2] | ||
3142 | |||
3143 | a, b, c = 1, 5, 2 | ||
3144 | print y for y in *x[a,b,c] | ||
3145 | |||
3146 | |||
3147 | normal = (hello) -> | ||
3148 | [x for x in yeah] | ||
3149 | |||
3150 | |||
3151 | test = x 1,2,3,4,5 | ||
3152 | print thing for thing in *test | ||
2838 | 3153 | ||
2839 | a = do | 3154 | -> a = b for row in *rows |
2840 | 123 | ||
2841 | 3155 | ||
2842 | do | ||
2843 | 123 | ||
2844 | 3156 | ||
2845 | do | 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 | ||
102 | class Exp_t; | 102 | class Exp_t; |
103 | 103 | ||
104 | AST_NODE(ImportName, "ImportName"_id) | ||
105 | ast_ptr<ast_node> name; // colon_import_name_t | Variable_t | ||
106 | AST_END(ImportName) | ||
107 | |||
108 | AST_NODE(Import, "Import"_id) | 104 | AST_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; |
112 | AST_END(Import) | 108 | AST_END(Import) |
113 | 109 | ||
@@ -191,9 +187,10 @@ AST_NODE(Do, "Do"_id) | |||
191 | AST_END(Do) | 187 | AST_END(Do) |
192 | 188 | ||
193 | class CompInner_t; | 189 | class CompInner_t; |
190 | class Statement_t; | ||
194 | 191 | ||
195 | AST_NODE(Comprehension, "Comprehension"_id) | 192 | AST_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; |
198 | AST_END(Comprehension) | 195 | AST_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; |
224 | AST_END(CompFor) | 221 | AST_END(CompFor) |
225 | 222 | ||
226 | AST_NODE(CompClause, "CompClause"_id) | ||
227 | ast_ptr<ast_node> nestExp; // CompFor_t | CompForEach_t | Exp_t | ||
228 | AST_END(CompClause) | ||
229 | |||
230 | AST_NODE(CompInner, "CompInner"_id) | 223 | AST_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; |
234 | AST_END(CompInner) | 226 | AST_END(CompInner) |
235 | 227 | ||
236 | class TableBlock_t; | 228 | class 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 | ||
209 | rule Comprehension = sym('[') >> Exp >> CompInner >> sym(']'); | 209 | rule Comprehension = sym('[') >> Exp >> CompInner >> sym(']'); |
210 | rule comp_value = sym(',') >> Exp; | 210 | rule comp_value = sym(',') >> Exp; |
211 | rule TblComprehension = sym('{') >> (Exp >> -comp_value) >> CompInner >> sym('}'); | 211 | rule TblComprehension = sym('{') >> (Exp >> -comp_value) >> CompInner >> sym('}'); |
212 | 212 | ||
213 | extern rule CompForEach, CompFor, CompClause; | 213 | extern rule CompForEach, CompFor, CompClause; |
214 | 214 | ||
215 | rule CompInner = (CompForEach | CompFor) >> Seperator >> *CompClause; | 215 | rule CompInner = Seperator >> (CompForEach | CompFor) >> *CompClause; |
216 | rule star_exp = sym('*') >> Exp; | 216 | rule star_exp = sym('*') >> Exp; |
217 | rule CompForEach = key("for") >> AssignableNameList >> key("in") >> (star_exp | Exp); | 217 | rule CompForEach = key("for") >> AssignableNameList >> key("in") >> (star_exp | Exp); |
218 | rule CompFor = key("for") >> Space >> Variable >> sym('=') >> Exp >> sym(',') >> Exp >> -for_step_value; | 218 | rule CompFor = key("for") >> Space >> Variable >> sym('=') >> Exp >> sym(',') >> Exp >> -for_step_value; |