aboutsummaryrefslogtreecommitdiff
path: root/src/MoonP
diff options
context:
space:
mode:
Diffstat (limited to 'src/MoonP')
-rw-r--r--src/MoonP/moon_ast.h26
-rw-r--r--src/MoonP/moon_compiler.cpp192
-rw-r--r--src/MoonP/moon_parser.cpp74
-rw-r--r--src/MoonP/moon_parser.h19
4 files changed, 237 insertions, 74 deletions
diff --git a/src/MoonP/moon_ast.h b/src/MoonP/moon_ast.h
index dd01165..9fab215 100644
--- a/src/MoonP/moon_ast.h
+++ b/src/MoonP/moon_ast.h
@@ -500,18 +500,28 @@ AST_NODE(ClassDecl)
500 AST_MEMBER(ClassDecl, &name, &extend, &body) 500 AST_MEMBER(ClassDecl, &name, &extend, &body)
501AST_END(ClassDecl) 501AST_END(ClassDecl)
502 502
503AST_NODE(export_values) 503AST_NODE(global_values)
504 ast_ptr<true, NameList_t> nameList; 504 ast_ptr<true, NameList_t> nameList;
505 ast_ptr<false, ExpListLow_t> valueList; 505 ast_ptr<false, ExpListLow_t> valueList;
506 AST_MEMBER(export_values, &nameList, &valueList) 506 AST_MEMBER(global_values, &nameList, &valueList)
507AST_END(export_values) 507AST_END(global_values)
508 508
509AST_LEAF(export_op) 509AST_LEAF(global_op)
510AST_END(export_op) 510AST_END(global_op)
511
512AST_NODE(Global)
513 ast_sel<true, ClassDecl_t, global_op_t, global_values_t> item;
514 AST_MEMBER(Global, &item)
515AST_END(Global)
516
517AST_LEAF(export_default)
518AST_END(export_default)
511 519
512AST_NODE(Export) 520AST_NODE(Export)
513 ast_sel<true, ClassDecl_t, export_op_t, export_values_t> item; 521 ast_ptr<false, export_default_t> def;
514 AST_MEMBER(Export, &item) 522 ast_sel<true, ExpList_t, Exp_t> target;
523 ast_ptr<false, Assign_t> assign;
524 AST_MEMBER(Export, &def, &target, &assign)
515AST_END(Export) 525AST_END(Export)
516 526
517AST_NODE(FnArgDef) 527AST_NODE(FnArgDef)
@@ -601,7 +611,7 @@ AST_END(BreakLoop)
601 611
602AST_NODE(Statement) 612AST_NODE(Statement)
603 ast_sel<true, Import_t, While_t, For_t, ForEach_t, 613 ast_sel<true, Import_t, While_t, For_t, ForEach_t,
604 Return_t, Local_t, Export_t, BreakLoop_t, 614 Return_t, Local_t, Global_t, Export_t, BreakLoop_t,
605 Backcall_t, ExpListAssign_t> content; 615 Backcall_t, ExpListAssign_t> content;
606 ast_ptr<false, statement_appendix_t> appendix; 616 ast_ptr<false, statement_appendix_t> appendix;
607 AST_MEMBER(Statement, &content, &appendix) 617 AST_MEMBER(Statement, &content, &appendix)
diff --git a/src/MoonP/moon_compiler.cpp b/src/MoonP/moon_compiler.cpp
index 83b91e6..1adfec9 100644
--- a/src/MoonP/moon_compiler.cpp
+++ b/src/MoonP/moon_compiler.cpp
@@ -32,7 +32,7 @@ inline std::string s(std::string_view sv) {
32} 32}
33 33
34const char* moonScriptVersion() { 34const char* moonScriptVersion() {
35 return "0.5.0-r0.1.5"; 35 return "0.5.0-r0.2.0";
36} 36}
37 37
38class MoonCompilerImpl { 38class MoonCompilerImpl {
@@ -45,7 +45,10 @@ public:
45 try { 45 try {
46 str_list out; 46 str_list out;
47 pushScope(); 47 pushScope();
48 transformBlock(_info.node.to<File_t>()->block, out, config.implicitReturnRoot ? ExpUsage::Return : ExpUsage::Common); 48 enableReturn.push(_info.moduleName.empty());
49 transformBlock(_info.node.to<File_t>()->block, out,
50 config.implicitReturnRoot ? ExpUsage::Return : ExpUsage::Common,
51 nullptr, true);
49 popScope(); 52 popScope();
50 if (config.lintGlobalVariable) { 53 if (config.lintGlobalVariable) {
51 globals = std::make_unique<std::list<GlobalVar>>(); 54 globals = std::make_unique<std::list<GlobalVar>>();
@@ -86,6 +89,7 @@ private:
86 MoonParser _parser; 89 MoonParser _parser;
87 ParseInfo _info; 90 ParseInfo _info;
88 int _indentOffset = 0; 91 int _indentOffset = 0;
92 std::stack<bool> enableReturn;
89 std::list<std::unique_ptr<input>> _codeCache; 93 std::list<std::unique_ptr<input>> _codeCache;
90 std::stack<std::string> _withVars; 94 std::stack<std::string> _withVars;
91 std::stack<std::string> _continueVars; 95 std::stack<std::string> _continueVars;
@@ -98,16 +102,16 @@ private:
98 Capital = 1, 102 Capital = 1,
99 Any = 2 103 Any = 2
100 }; 104 };
101 enum class ExportMode { 105 enum class GlobalMode {
102 None = 0, 106 None = 0,
103 Capital = 1, 107 Capital = 1,
104 Any = 2 108 Any = 2
105 }; 109 };
106 struct Scope { 110 struct Scope {
107 ExportMode mode = ExportMode::None; 111 GlobalMode mode = GlobalMode::None;
108 std::unique_ptr<std::unordered_set<std::string>> vars; 112 std::unique_ptr<std::unordered_set<std::string>> vars;
109 std::unique_ptr<std::unordered_set<std::string>> allows; 113 std::unique_ptr<std::unordered_set<std::string>> allows;
110 std::unique_ptr<std::unordered_set<std::string>> exports; 114 std::unique_ptr<std::unordered_set<std::string>> globals;
111 }; 115 };
112 std::list<Scope> _scopes; 116 std::list<Scope> _scopes;
113 static const std::string Empty; 117 static const std::string Empty;
@@ -153,11 +157,11 @@ private:
153 157
154 bool isDefined(const std::string& name) const { 158 bool isDefined(const std::string& name) const {
155 bool isDefined = false; 159 bool isDefined = false;
156 int mode = int(std::isupper(name[0]) ? ExportMode::Capital : ExportMode::Any); 160 int mode = int(std::isupper(name[0]) ? GlobalMode::Capital : GlobalMode::Any);
157 const auto& current = _scopes.back(); 161 const auto& current = _scopes.back();
158 if (int(current.mode) >= mode) { 162 if (int(current.mode) >= mode) {
159 if (current.exports) { 163 if (current.globals) {
160 if (current.exports->find(name) != current.exports->end()) { 164 if (current.globals->find(name) != current.globals->end()) {
161 isDefined = true; 165 isDefined = true;
162 current.vars->insert(name); 166 current.vars->insert(name);
163 } 167 }
@@ -202,17 +206,17 @@ private:
202 scope.allows = std::make_unique<std::unordered_set<std::string>>(); 206 scope.allows = std::make_unique<std::unordered_set<std::string>>();
203 } 207 }
204 208
205 void markVarExported(ExportMode mode, bool specified) { 209 void markVarGlobal(GlobalMode mode, bool specified) {
206 auto& scope = _scopes.back(); 210 auto& scope = _scopes.back();
207 scope.mode = mode; 211 scope.mode = mode;
208 if (specified && !scope.exports) { 212 if (specified && !scope.globals) {
209 scope.exports = std::make_unique<std::unordered_set<std::string>>(); 213 scope.globals = std::make_unique<std::unordered_set<std::string>>();
210 } 214 }
211 } 215 }
212 216
213 void addExportedVar(const std::string& name) { 217 void addGlobalVar(const std::string& name) {
214 auto& scope = _scopes.back(); 218 auto& scope = _scopes.back();
215 scope.exports->insert(name); 219 scope.globals->insert(name);
216 } 220 }
217 221
218 void addToAllowList(const std::string& name) { 222 void addToAllowList(const std::string& name) {
@@ -457,6 +461,20 @@ private:
457 return Empty; 461 return Empty;
458 } 462 }
459 463
464 Variable_t* variableFrom(Exp_t* exp) {
465 BLOCK_START
466 auto value = singleValueFrom(exp);
467 BREAK_IF(!value);
468 auto chainValue = value->getByPath<ChainValue_t>();
469 BREAK_IF(!chainValue);
470 BREAK_IF(chainValue->items.size() != 1);
471 auto callable = ast_cast<Callable_t>(chainValue->items.front());
472 BREAK_IF(!callable);
473 return callable->item.as<Variable_t>();
474 BLOCK_END
475 return nullptr;
476 }
477
460 bool isAssignable(const node_container& chainItems) const { 478 bool isAssignable(const node_container& chainItems) const {
461 if (chainItems.size() == 1) { 479 if (chainItems.size() == 1) {
462 auto firstItem = chainItems.back(); 480 auto firstItem = chainItems.back();
@@ -647,6 +665,7 @@ private:
647 case id<ForEach_t>(): transformForEach(static_cast<ForEach_t*>(content), out); break; 665 case id<ForEach_t>(): transformForEach(static_cast<ForEach_t*>(content), out); break;
648 case id<Return_t>(): transformReturn(static_cast<Return_t*>(content), out); break; 666 case id<Return_t>(): transformReturn(static_cast<Return_t*>(content), out); break;
649 case id<Local_t>(): transformLocal(static_cast<Local_t*>(content), out); break; 667 case id<Local_t>(): transformLocal(static_cast<Local_t*>(content), out); break;
668 case id<Global_t>(): transformGlobal(static_cast<Global_t*>(content), out); break;
650 case id<Export_t>(): transformExport(static_cast<Export_t*>(content), out); break; 669 case id<Export_t>(): transformExport(static_cast<Export_t*>(content), out); break;
651 case id<BreakLoop_t>(): transformBreakLoop(static_cast<BreakLoop_t*>(content), out); break; 670 case id<BreakLoop_t>(): transformBreakLoop(static_cast<BreakLoop_t*>(content), out); break;
652 case id<ExpListAssign_t>(): { 671 case id<ExpListAssign_t>(): {
@@ -693,7 +712,7 @@ private:
693 break; 712 break;
694 } 713 }
695 } 714 }
696 throw std::logic_error(_info.errorMessage("Expression list must appear at the end of body or block."sv, expList)); 715 throw std::logic_error(_info.errorMessage("Expression list is not supported here."sv, expList));
697 } 716 }
698 break; 717 break;
699 } 718 }
@@ -749,8 +768,8 @@ private:
749 return preDefs; 768 return preDefs;
750 } 769 }
751 770
752 str_list transformAssignDefs(ExpList_t* expList) { 771 str_list transformAssignDefs(ExpList_t* expList, bool markDefined = true) {
753 str_list preDefs; 772 str_list defs;
754 for (auto exp_ : expList->exprs.objects()) { 773 for (auto exp_ : expList->exprs.objects()) {
755 auto exp = static_cast<Exp_t*>(exp_); 774 auto exp = static_cast<Exp_t*>(exp_);
756 if (auto value = singleValueFrom(exp)) { 775 if (auto value = singleValueFrom(exp)) {
@@ -766,8 +785,8 @@ private:
766 if (self->name.is<self_t>()) name = "self"sv; 785 if (self->name.is<self_t>()) name = "self"sv;
767 } 786 }
768 BREAK_IF(name.empty()); 787 BREAK_IF(name.empty());
769 if (addToScope(name)) { 788 if (!markDefined || addToScope(name)) {
770 preDefs.push_back(name); 789 defs.push_back(name);
771 } 790 }
772 BLOCK_END 791 BLOCK_END
773 } 792 }
@@ -775,7 +794,7 @@ private:
775 throw std::logic_error(_info.errorMessage("Left hand expression is not assignable."sv, exp)); 794 throw std::logic_error(_info.errorMessage("Left hand expression is not assignable."sv, exp));
776 } 795 }
777 } 796 }
778 return preDefs; 797 return defs;
779 } 798 }
780 799
781 std::string getPredefine(const str_list& defs) { 800 std::string getPredefine(const str_list& defs) {
@@ -1650,6 +1669,7 @@ private:
1650 } 1669 }
1651 1670
1652 void transformFunLit(FunLit_t* funLit, str_list& out) { 1671 void transformFunLit(FunLit_t* funLit, str_list& out) {
1672 enableReturn.push(true);
1653 str_list temp; 1673 str_list temp;
1654 bool isFatArrow = _parser.toString(funLit->arrow) == "=>"sv; 1674 bool isFatArrow = _parser.toString(funLit->arrow) == "=>"sv;
1655 pushScope(); 1675 pushScope();
@@ -1698,6 +1718,7 @@ private:
1698 } 1718 }
1699 } 1719 }
1700 out.push_back(clearBuf()); 1720 out.push_back(clearBuf());
1721 enableReturn.pop();
1701 } 1722 }
1702 1723
1703 void transformBody(Body_t* body, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { 1724 void transformBody(Body_t* body, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) {
@@ -1711,7 +1732,7 @@ private:
1711 } 1732 }
1712 } 1733 }
1713 1734
1714 void transformBlock(Block_t* block, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { 1735 void transformBlock(Block_t* block, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr, bool isRoot = false) {
1715 const auto& nodes = block->statements.objects(); 1736 const auto& nodes = block->statements.objects();
1716 LocalMode mode = LocalMode::None; 1737 LocalMode mode = LocalMode::None;
1717 Local_t* any = nullptr, *capital = nullptr; 1738 Local_t* any = nullptr, *capital = nullptr;
@@ -1768,7 +1789,7 @@ private:
1768 args->swap(a, arg); 1789 args->swap(a, arg);
1769 findPlaceHolder = true; 1790 findPlaceHolder = true;
1770 } else { 1791 } else {
1771 throw std::logic_error(_info.errorMessage("backcall placeholder can be used only in one place."sv, a)); 1792 throw std::logic_error(_info.errorMessage("Backcall placeholder can be used only in one place."sv, a));
1772 } 1793 }
1773 } 1794 }
1774 } 1795 }
@@ -1792,9 +1813,10 @@ private:
1792 auto expListAssign = x->new_ptr<ExpListAssign_t>(); 1813 auto expListAssign = x->new_ptr<ExpListAssign_t>();
1793 expListAssign->expList.set(expList); 1814 expListAssign->expList.set(expList);
1794 newStmt->content.set(expListAssign); 1815 newStmt->content.set(expListAssign);
1816 newStmt->appendix.set(stmt->appendix);
1795 newBlock->statements.push_back(newStmt); 1817 newBlock->statements.push_back(newStmt);
1796 } 1818 }
1797 transformBlock(newBlock, out, usage, assignList); 1819 transformBlock(newBlock, out, usage, assignList, isRoot);
1798 return; 1820 return;
1799 } 1821 }
1800 if (auto local = stmt->content.as<Local_t>()) { 1822 if (auto local = stmt->content.as<Local_t>()) {
@@ -1838,6 +1860,15 @@ private:
1838 } 1860 }
1839 } 1861 }
1840 } 1862 }
1863 if (info.second) {
1864 auto defs = transformAssignDefs(info.second->expList, false);
1865 for (const auto& def : defs) {
1866 if (std::isupper(def[0]) && capital) { capital->decls.push_back(def);
1867 } else if (any) {
1868 any->decls.push_back(def);
1869 }
1870 }
1871 }
1841 BLOCK_START 1872 BLOCK_START
1842 auto assign = assignment->action.as<Assign_t>(); 1873 auto assign = assignment->action.as<Assign_t>();
1843 BREAK_IF(!assign); 1874 BREAK_IF(!assign);
@@ -1865,10 +1896,14 @@ private:
1865 } 1896 }
1866 } 1897 }
1867 } 1898 }
1899 if (isRoot && !_info.moduleName.empty()) {
1900 block->statements.push_front(toAst<Statement_t>(_info.moduleName + s(_info.exportDefault ? "=nil"sv : "={}"sv), block));
1901 }
1868 switch (usage) { 1902 switch (usage) {
1869 case ExpUsage::Closure: 1903 case ExpUsage::Closure:
1870 case ExpUsage::Return: { 1904 case ExpUsage::Return: {
1871 BLOCK_START 1905 BLOCK_START
1906 BREAK_IF(isRoot && !_info.moduleName.empty());
1872 BREAK_IF(nodes.empty()); 1907 BREAK_IF(nodes.empty());
1873 auto last = static_cast<Statement_t*>(nodes.back()); 1908 auto last = static_cast<Statement_t*>(nodes.back());
1874 auto x = last; 1909 auto x = last;
@@ -1920,9 +1955,17 @@ private:
1920 } else { 1955 } else {
1921 out.push_back(Empty); 1956 out.push_back(Empty);
1922 } 1957 }
1958 if (isRoot && !_info.moduleName.empty()) {
1959 out.back().append(indent() + s("return "sv) + _info.moduleName + nlr(block));
1960 }
1923 } 1961 }
1924 1962
1925 void transformReturn(Return_t* returnNode, str_list& out) { 1963 void transformReturn(Return_t* returnNode, str_list& out) {
1964 if (!enableReturn.top()) {
1965 ast_node* target = returnNode->valueList.get();
1966 if (!target) target = returnNode;
1967 throw std::logic_error(_info.errorMessage("Illegal return statement here."sv, target));
1968 }
1926 if (auto valueList = returnNode->valueList.get()) { 1969 if (auto valueList = returnNode->valueList.get()) {
1927 if (valueList->exprs.size() == 1) { 1970 if (valueList->exprs.size() == 1) {
1928 auto exp = static_cast<Exp_t*>(valueList->exprs.back()); 1971 auto exp = static_cast<Exp_t*>(valueList->exprs.back());
@@ -3797,33 +3840,33 @@ private:
3797 out.push_back(_parser.toString(const_value)); 3840 out.push_back(_parser.toString(const_value));
3798 } 3841 }
3799 3842
3800 void transformExport(Export_t* exportNode, str_list& out) { 3843 void transformGlobal(Global_t* global, str_list& out) {
3801 auto x = exportNode; 3844 auto x = global;
3802 auto item = exportNode->item.get(); 3845 auto item = global->item.get();
3803 switch (item->getId()) { 3846 switch (item->getId()) {
3804 case id<ClassDecl_t>(): { 3847 case id<ClassDecl_t>(): {
3805 auto classDecl = static_cast<ClassDecl_t*>(item); 3848 auto classDecl = static_cast<ClassDecl_t*>(item);
3806 if (classDecl->name && classDecl->name->item->getId() == id<Variable_t>()) { 3849 if (classDecl->name && classDecl->name->item->getId() == id<Variable_t>()) {
3807 markVarExported(ExportMode::Any, true); 3850 markVarGlobal(GlobalMode::Any, true);
3808 addExportedVar(_parser.toString(classDecl->name->item)); 3851 addGlobalVar(_parser.toString(classDecl->name->item));
3809 } 3852 }
3810 transformClassDecl(classDecl, out, ExpUsage::Common); 3853 transformClassDecl(classDecl, out, ExpUsage::Common);
3811 break; 3854 break;
3812 } 3855 }
3813 case id<export_op_t>(): 3856 case id<global_op_t>():
3814 if (_parser.toString(item) == "*"sv) { 3857 if (_parser.toString(item) == "*"sv) {
3815 markVarExported(ExportMode::Any, false); 3858 markVarGlobal(GlobalMode::Any, false);
3816 } else { 3859 } else {
3817 markVarExported(ExportMode::Capital, false); 3860 markVarGlobal(GlobalMode::Capital, false);
3818 } 3861 }
3819 break; 3862 break;
3820 case id<export_values_t>(): { 3863 case id<global_values_t>(): {
3821 markVarExported(ExportMode::Any, true); 3864 markVarGlobal(GlobalMode::Any, true);
3822 auto values = exportNode->item.to<export_values_t>(); 3865 auto values = global->item.to<global_values_t>();
3823 if (values->valueList) { 3866 if (values->valueList) {
3824 auto expList = x->new_ptr<ExpList_t>(); 3867 auto expList = x->new_ptr<ExpList_t>();
3825 for (auto name : values->nameList->names.objects()) { 3868 for (auto name : values->nameList->names.objects()) {
3826 addExportedVar(_parser.toString(name)); 3869 addGlobalVar(_parser.toString(name));
3827 auto callable = x->new_ptr<Callable_t>(); 3870 auto callable = x->new_ptr<Callable_t>();
3828 callable->item.set(name); 3871 callable->item.set(name);
3829 auto chainValue = x->new_ptr<ChainValue_t>(); 3872 auto chainValue = x->new_ptr<ChainValue_t>();
@@ -3842,7 +3885,7 @@ private:
3842 transformAssignment(assignment, out); 3885 transformAssignment(assignment, out);
3843 } else { 3886 } else {
3844 for (auto name : values->nameList->names.objects()) { 3887 for (auto name : values->nameList->names.objects()) {
3845 addExportedVar(_parser.toString(name)); 3888 addGlobalVar(_parser.toString(name));
3846 } 3889 }
3847 } 3890 }
3848 break; 3891 break;
@@ -3851,6 +3894,85 @@ private:
3851 } 3894 }
3852 } 3895 }
3853 3896
3897 void transformExport(Export_t* exportNode, str_list& out) {
3898 auto x = exportNode;
3899 if (_scopes.size() > 1) {
3900 throw std::logic_error(_info.errorMessage("Can not do module export outside root block."sv, x));
3901 }
3902 if (exportNode->assign) {
3903 auto expList = exportNode->target.to<ExpList_t>();
3904 if (expList->exprs.size() != exportNode->assign->values.size()) {
3905 throw std::logic_error(_info.errorMessage("Left and right expressions must be matched in export statement."sv, x));
3906 }
3907 for (auto _exp : expList->exprs.objects()) {
3908 auto exp = static_cast<Exp_t*>(_exp);
3909 if (!variableFrom(exp) &&
3910 !exp->getByPath<Value_t, SimpleValue_t, TableLit_t>() &&
3911 !exp->getByPath<Value_t, simple_table_t>()) {
3912 throw std::logic_error(_info.errorMessage("Left hand expressions must be variables in export statement."sv, x));
3913 }
3914 }
3915 auto assignment = x->new_ptr<ExpListAssign_t>();
3916 assignment->expList.set(expList);
3917 assignment->action.set(exportNode->assign);
3918 transformAssignment(assignment, out);
3919 str_list names = transformAssignDefs(expList, false);
3920 auto info = extractDestructureInfo(assignment, true);
3921 if (!info.first.empty()) {
3922 for (const auto& destruct : info.first)
3923 for (const auto& item : destruct.items)
3924 if (item.isVariable)
3925 names.push_back(item.name);
3926 }
3927 if (_info.exportDefault) {
3928 out.back().append(indent() + _info.moduleName + s(" = "sv) + names.back() + nlr(exportNode));
3929 } else {
3930 str_list lefts, rights;
3931 for (const auto& name : names) {
3932 lefts.push_back(_info.moduleName + s("[\""sv) + name + s("\"]"sv));
3933 rights.push_back(name);
3934 }
3935 out.back().append(indent() + join(lefts,", "sv) + s(" = "sv) + join(rights, ", "sv) + nlr(exportNode));
3936 }
3937 } else {
3938 if (_info.exportDefault) {
3939 auto exp = exportNode->target.to<Exp_t>();
3940 auto assignment = x->new_ptr<ExpListAssign_t>();
3941 assignment->expList.set(toAst<ExpList_t>(_info.moduleName, x));
3942 auto assign = x->new_ptr<Assign_t>();
3943 assign->values.push_back(exp);
3944 assignment->action.set(assign);
3945 transformAssignment(assignment, out);
3946 } else {
3947 str_list temp;
3948 auto expList = exportNode->target.to<ExpList_t>();
3949 auto assignment = x->new_ptr<ExpListAssign_t>();
3950 auto assignList = toAst<ExpList_t>(_info.moduleName + s("[#"sv) + _info.moduleName + s("+1]"sv), x);
3951 assignment->expList.set(assignList);
3952 for (auto exp : expList->exprs.objects()) {
3953 if (auto classDecl = exp->getByPath<Value_t, SimpleValue_t, ClassDecl_t>()) {
3954 if (classDecl->name && classDecl->name->item->getId() == id<Variable_t>()) {
3955 transformClassDecl(classDecl, temp, ExpUsage::Common);
3956 auto name = _parser.toString(classDecl->name->item);
3957 assignment->expList.set(toAst<ExpList_t>(_info.moduleName + s("[\""sv) + name + s("\"]"sv), x));
3958 auto assign = x->new_ptr<Assign_t>();
3959 assign->values.push_back(toAst<Exp_t>(name, x));
3960 assignment->action.set(assign);
3961 transformAssignment(assignment, temp);
3962 assignment->expList.set(assignList);
3963 continue;
3964 }
3965 }
3966 auto assign = x->new_ptr<Assign_t>();
3967 assign->values.push_back(exp);
3968 assignment->action.set(assign);
3969 transformAssignment(assignment, temp);
3970 }
3971 out.push_back(join(temp));
3972 }
3973 }
3974 }
3975
3854 void transformTable(ast_node* table, const node_container& pairs, str_list& out) { 3976 void transformTable(ast_node* table, const node_container& pairs, str_list& out) {
3855 if (pairs.empty()) { 3977 if (pairs.empty()) {
3856 out.push_back(s("{ }"sv)); 3978 out.push_back(s("{ }"sv));
diff --git a/src/MoonP/moon_parser.cpp b/src/MoonP/moon_parser.cpp
index fecf869..baa8eff 100644
--- a/src/MoonP/moon_parser.cpp
+++ b/src/MoonP/moon_parser.cpp
@@ -28,8 +28,8 @@ std::unordered_set<std::string> Keywords = {
28 "repeat", "return", "then", "true", "until", 28 "repeat", "return", "then", "true", "until",
29 "while", // Lua keywords 29 "while", // Lua keywords
30 "as", "class", "continue", "export", "extends", 30 "as", "class", "continue", "export", "extends",
31 "from", "import", "switch", "unless", "using", 31 "from", "global", "import", "switch", "unless",
32 "when", "with" // Moon keywords 32 "using", "when", "with" // Moon keywords
33}; 33};
34 34
35MoonParser::MoonParser() { 35MoonParser::MoonParser() {
@@ -74,9 +74,15 @@ MoonParser::MoonParser() {
74 Variable = pl::user(Name, [](const item_t& item) { 74 Variable = pl::user(Name, [](const item_t& item) {
75 State* st = reinterpret_cast<State*>(item.user_data); 75 State* st = reinterpret_cast<State*>(item.user_data);
76 for (auto it = item.begin; it != item.end; ++it) st->buffer += static_cast<char>(*it); 76 for (auto it = item.begin; it != item.end; ++it) st->buffer += static_cast<char>(*it);
77 auto it = Keywords.find(st->buffer); 77 auto isValid = Keywords.find(st->buffer) == Keywords.end();
78 if (isValid) {
79 if (st->buffer == st->moduleName) {
80 st->moduleFix++;
81 st->moduleName = std::string("_module_"sv) + std::to_string(st->moduleFix);
82 }
83 }
78 st->buffer.clear(); 84 st->buffer.clear();
79 return it == Keywords.end(); 85 return isValid;
80 }); 86 });
81 87
82 LuaKeyword = pl::user(Name, [](const item_t& item) { 88 LuaKeyword = pl::user(Name, [](const item_t& item) {
@@ -153,7 +159,7 @@ MoonParser::MoonParser() {
153 return true; 159 return true;
154 }); 160 });
155 161
156 InBlock = Advance >> Block >> PopIndent; 162 InBlock = Advance >> ensure(Block, PopIndent);
157 163
158 local_flag = expr('*') | expr('^'); 164 local_flag = expr('*') | expr('^');
159 Local = key("local") >> ((Space >> local_flag) | NameList); 165 Local = key("local") >> ((Space >> local_flag) | NameList);
@@ -211,21 +217,18 @@ MoonParser::MoonParser() {
211 DisableDo >> ensure(for_in, PopDo) >> 217 DisableDo >> ensure(for_in, PopDo) >>
212 -key("do") >> Body; 218 -key("do") >> Body;
213 219
214 Do = pl::user(key("do") >> Body, [](const item_t& item) 220 Do = pl::user(key("do"), [](const item_t& item) {
215 {
216 State* st = reinterpret_cast<State*>(item.user_data); 221 State* st = reinterpret_cast<State*>(item.user_data);
217 return st->doStack.empty() || st->doStack.top(); 222 return st->doStack.empty() || st->doStack.top();
218 }); 223 }) >> Body;
219 224
220 DisableDo = pl::user(true_(), [](const item_t& item) 225 DisableDo = pl::user(true_(), [](const item_t& item) {
221 {
222 State* st = reinterpret_cast<State*>(item.user_data); 226 State* st = reinterpret_cast<State*>(item.user_data);
223 st->doStack.push(false); 227 st->doStack.push(false);
224 return true; 228 return true;
225 }); 229 });
226 230
227 PopDo = pl::user(true_(), [](const item_t& item) 231 PopDo = pl::user(true_(), [](const item_t& item) {
228 {
229 State* st = reinterpret_cast<State*>(item.user_data); 232 State* st = reinterpret_cast<State*>(item.user_data);
230 st->doStack.pop(); 233 st->doStack.pop();
231 return true; 234 return true;
@@ -312,11 +315,7 @@ MoonParser::MoonParser() {
312 315
313 LuaStringContent = *(not_(LuaStringClose) >> Any); 316 LuaStringContent = *(not_(LuaStringClose) >> Any);
314 317
315 LuaString = pl::user(LuaStringOpen >> -Break >> LuaStringContent >> LuaStringClose, [](const item_t& item) { 318 LuaString = LuaStringOpen >> -Break >> LuaStringContent >> LuaStringClose;
316 State* st = reinterpret_cast<State*>(item.user_data);
317 st->stringOpen = -1;
318 return true;
319 });
320 319
321 Parens = sym('(') >> *SpaceBreak >> Exp >> *SpaceBreak >> sym(')'); 320 Parens = sym('(') >> *SpaceBreak >> Exp >> *SpaceBreak >> sym(')');
322 Callable = Space >> Variable | SelfName | VarArg | Parens; 321 Callable = Space >> Variable | SelfName | VarArg | Parens;
@@ -392,9 +391,30 @@ MoonParser::MoonParser() {
392 -(key("extends") >> PreventIndent >> ensure(Exp, PopIndent)) >> 391 -(key("extends") >> PreventIndent >> ensure(Exp, PopIndent)) >>
393 -ClassBlock; 392 -ClassBlock;
394 393
395 export_values = NameList >> -(sym('=') >> ExpListLow); 394 global_values = NameList >> -(sym('=') >> ExpListLow);
396 export_op = expr('*') | expr('^'); 395 global_op = expr('*') | expr('^');
397 Export = key("export") >> (ClassDecl | (Space >> export_op) | export_values); 396 Global = key("global") >> (ClassDecl | (Space >> global_op) | global_values);
397
398 export_default = key("default");
399
400 Export = pl::user(key("export"), [](const item_t& item) {
401 State* st = reinterpret_cast<State*>(item.user_data);
402 st->exportCount++;
403 return true;
404 }) >> ((pl::user(export_default, [](const item_t& item) {
405 State* st = reinterpret_cast<State*>(item.user_data);
406 bool isValid = !st->exportDefault && st->exportCount == 1;
407 st->exportDefault = true;
408 return isValid;
409 }) >> Exp)
410 | (pl::user(true_(), [](const item_t& item) {
411 State* st = reinterpret_cast<State*>(item.user_data);
412 if (st->exportDefault && st->exportCount > 1) {
413 return false;
414 } else {
415 return true;
416 }
417 }) >> ExpList >> -Assign)) >> not_(Space >> statement_appendix);
398 418
399 variable_pair = sym(':') >> Variable; 419 variable_pair = sym(':') >> Variable;
400 420
@@ -479,12 +499,12 @@ MoonParser::MoonParser() {
479 statement_appendix = (if_else_line | unless_line | CompInner) >> Space; 499 statement_appendix = (if_else_line | unless_line | CompInner) >> Space;
480 Statement = ( 500 Statement = (
481 Import | While | For | ForEach | 501 Import | While | For | ForEach |
482 Return | Local | Export | Space >> BreakLoop | 502 Return | Local | Global | Export | Space >> BreakLoop |
483 Backcall | ExpListAssign 503 Backcall | ExpListAssign
484 ) >> Space >> 504 ) >> Space >>
485 -statement_appendix; 505 -statement_appendix;
486 506
487 Body = -Space >> Break >> *EmptyLine >> InBlock | Statement; 507 Body = Space >> Break >> *EmptyLine >> InBlock | Statement;
488 508
489 empty_line_stop = Space >> and_(Stop); 509 empty_line_stop = Space >> and_(Stop);
490 Line = CheckIndent >> Statement | empty_line_stop; 510 Line = CheckIndent >> Statement | empty_line_stop;
@@ -498,7 +518,7 @@ ParseInfo MoonParser::parse(std::string_view codes, rule& r) {
498 ParseInfo res; 518 ParseInfo res;
499 try { 519 try {
500 res.codes = std::make_unique<input>(); 520 res.codes = std::make_unique<input>();
501 *(res.codes) = _converter.from_bytes(codes.begin(), codes.end()); 521 *(res.codes) = _converter.from_bytes(&codes.front(), &codes.back() + 1);
502 } catch (const std::range_error&) { 522 } catch (const std::range_error&) {
503 res.error = "Invalid text encoding."sv; 523 res.error = "Invalid text encoding."sv;
504 return res; 524 return res;
@@ -507,6 +527,10 @@ ParseInfo MoonParser::parse(std::string_view codes, rule& r) {
507 try { 527 try {
508 State state; 528 State state;
509 res.node.set(pl::parse(*(res.codes), r, errors, &state)); 529 res.node.set(pl::parse(*(res.codes), r, errors, &state));
530 if (state.exportCount > 0) {
531 res.moduleName = std::move(state.moduleName);
532 res.exportDefault = state.exportDefault;
533 }
510 } catch (const std::logic_error& err) { 534 } catch (const std::logic_error& err) {
511 res.error = err.what(); 535 res.error = err.what();
512 return res; 536 return res;
@@ -538,7 +562,7 @@ std::string MoonParser::toString(input::iterator begin, input::iterator end) {
538} 562}
539 563
540input MoonParser::encode(std::string_view codes) { 564input MoonParser::encode(std::string_view codes) {
541 return _converter.from_bytes(codes.begin(), codes.end()); 565 return _converter.from_bytes(&codes.front(), &codes.back() + 1);
542} 566}
543 567
544std::string MoonParser::decode(const input& codes) { 568std::string MoonParser::decode(const input& codes) {
@@ -572,7 +596,6 @@ std::string ParseInfo::errorMessage(std::string_view msg, const input_range* loc
572 count++; 596 count++;
573 } 597 }
574 } 598 }
575 auto line = Converter{}.to_bytes(std::wstring(begin, end));
576 int oldCol = loc->m_begin.m_col; 599 int oldCol = loc->m_begin.m_col;
577 int col = std::max(0, oldCol - 1); 600 int col = std::max(0, oldCol - 1);
578 auto it = begin; 601 auto it = begin;
@@ -582,6 +605,7 @@ std::string ParseInfo::errorMessage(std::string_view msg, const input_range* loc
582 } 605 }
583 ++it; 606 ++it;
584 } 607 }
608 auto line = Converter{}.to_bytes(std::wstring(begin, end));
585 Utils::replace(line, "\t"sv, " "sv); 609 Utils::replace(line, "\t"sv, " "sv);
586 std::ostringstream buf; 610 std::ostringstream buf;
587 buf << loc->m_begin.m_line << ": "sv << msg << 611 buf << loc->m_begin.m_line << ": "sv << msg <<
diff --git a/src/MoonP/moon_parser.h b/src/MoonP/moon_parser.h
index 12f735b..eefcba5 100644
--- a/src/MoonP/moon_parser.h
+++ b/src/MoonP/moon_parser.h
@@ -26,6 +26,8 @@ struct ParseInfo {
26 ast_ptr<false, ast_node> node; 26 ast_ptr<false, ast_node> node;
27 std::string error; 27 std::string error;
28 std::unique_ptr<input> codes; 28 std::unique_ptr<input> codes;
29 bool exportDefault = false;
30 std::string moduleName;
29 std::string errorMessage(std::string_view msg, const input_range* loc) const; 31 std::string errorMessage(std::string_view msg, const input_range* loc) const;
30}; 32};
31 33
@@ -72,10 +74,13 @@ protected:
72 struct State { 74 struct State {
73 State() { 75 State() {
74 indents.push(0); 76 indents.push(0);
75 stringOpen = -1;
76 } 77 }
78 bool exportDefault = false;
79 int exportCount = 0;
80 int moduleFix = 0;
81 size_t stringOpen = 0;
82 std::string moduleName = "_module_0";
77 std::string buffer; 83 std::string buffer;
78 size_t stringOpen;
79 std::stack<int> indents; 84 std::stack<int> indents;
80 std::stack<bool> doStack; 85 std::stack<bool> doStack;
81 }; 86 };
@@ -124,8 +129,8 @@ private:
124 rule ImportNameList; 129 rule ImportNameList;
125 rule import_literal_chain; 130 rule import_literal_chain;
126 rule WithExp; 131 rule WithExp;
127 rule PopDo;
128 rule DisableDo; 132 rule DisableDo;
133 rule PopDo;
129 rule SwitchElse; 134 rule SwitchElse;
130 rule SwitchBlock; 135 rule SwitchBlock;
131 rule IfElseIf; 136 rule IfElseIf;
@@ -181,9 +186,9 @@ private:
181 AST_RULE(SelfName) 186 AST_RULE(SelfName)
182 AST_RULE(KeyName) 187 AST_RULE(KeyName)
183 AST_RULE(VarArg) 188 AST_RULE(VarArg)
184 AST_RULE(local_flag)
185 AST_RULE(Seperator) 189 AST_RULE(Seperator)
186 AST_RULE(NameList) 190 AST_RULE(NameList)
191 AST_RULE(local_flag)
187 AST_RULE(Local) 192 AST_RULE(Local)
188 AST_RULE(colon_import_name) 193 AST_RULE(colon_import_name)
189 AST_RULE(import_literal_inner) 194 AST_RULE(import_literal_inner)
@@ -249,8 +254,10 @@ private:
249 AST_RULE(class_member_list) 254 AST_RULE(class_member_list)
250 AST_RULE(ClassBlock) 255 AST_RULE(ClassBlock)
251 AST_RULE(ClassDecl) 256 AST_RULE(ClassDecl)
252 AST_RULE(export_values) 257 AST_RULE(global_values)
253 AST_RULE(export_op) 258 AST_RULE(global_op)
259 AST_RULE(Global)
260 AST_RULE(export_default)
254 AST_RULE(Export) 261 AST_RULE(Export)
255 AST_RULE(variable_pair) 262 AST_RULE(variable_pair)
256 AST_RULE(normal_pair) 263 AST_RULE(normal_pair)