diff options
Diffstat (limited to '')
| -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; |
