diff options
author | Li Jin <dragon-fly@qq.com> | 2020-01-23 14:35:14 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2020-01-23 14:35:14 +0800 |
commit | 7ac3519dc40bb6f6ab979c9cd35fd585f25d1c25 (patch) | |
tree | 024fabcf12638dbd4cb9fe6c58251f9227fc9380 /src | |
parent | 782334d95720819f216004e0120ea84ba2c43afb (diff) | |
download | yuescript-7ac3519dc40bb6f6ab979c9cd35fd585f25d1c25.tar.gz yuescript-7ac3519dc40bb6f6ab979c9cd35fd585f25d1c25.tar.bz2 yuescript-7ac3519dc40bb6f6ab979c9cd35fd585f25d1c25.zip |
fix Moonscript issue 156, update new 'import' functions.
Diffstat (limited to 'src')
-rw-r--r-- | src/MoonP/moon_ast.cpp | 4 | ||||
-rw-r--r-- | src/MoonP/moon_ast.h | 25 | ||||
-rw-r--r-- | src/MoonP/moon_compiler.cpp | 348 | ||||
-rw-r--r-- | src/MoonP/moon_parser.cpp | 21 |
4 files changed, 250 insertions, 148 deletions
diff --git a/src/MoonP/moon_ast.cpp b/src/MoonP/moon_ast.cpp index f3fe31e..8b8a674 100644 --- a/src/MoonP/moon_ast.cpp +++ b/src/MoonP/moon_ast.cpp | |||
@@ -29,6 +29,10 @@ AST_IMPL(Seperator) | |||
29 | AST_IMPL(NameList) | 29 | AST_IMPL(NameList) |
30 | AST_IMPL(Local) | 30 | AST_IMPL(Local) |
31 | AST_IMPL(colon_import_name) | 31 | AST_IMPL(colon_import_name) |
32 | AST_IMPL(import_literal_inner) | ||
33 | AST_IMPL(ImportLiteral) | ||
34 | AST_IMPL(ImportFrom) | ||
35 | AST_IMPL(ImportAs) | ||
32 | AST_IMPL(Import) | 36 | AST_IMPL(Import) |
33 | AST_IMPL(ExpListLow) | 37 | AST_IMPL(ExpListLow) |
34 | AST_IMPL(ExpList) | 38 | AST_IMPL(ExpList) |
diff --git a/src/MoonP/moon_ast.h b/src/MoonP/moon_ast.h index 8b80af3..f8d2099 100644 --- a/src/MoonP/moon_ast.h +++ b/src/MoonP/moon_ast.h | |||
@@ -106,12 +106,33 @@ AST_NODE(colon_import_name, "colon_import_name"_id) | |||
106 | AST_END(colon_import_name) | 106 | AST_END(colon_import_name) |
107 | 107 | ||
108 | class Exp_t; | 108 | class Exp_t; |
109 | class TableLit_t; | ||
109 | 110 | ||
110 | AST_NODE(Import, "Import"_id) | 111 | AST_LEAF(import_literal_inner, "import_literal_inner"_id) |
112 | AST_END(import_literal_inner) | ||
113 | |||
114 | AST_NODE(ImportLiteral, "ImportLiteral"_id) | ||
115 | ast_ptr<true, Seperator_t> sep; | ||
116 | ast_sel_list<true, import_literal_inner_t> inners; | ||
117 | AST_MEMBER(ImportLiteral, &sep, &inners) | ||
118 | AST_END(ImportLiteral) | ||
119 | |||
120 | AST_NODE(ImportAs, "ImportAs"_id) | ||
121 | ast_ptr<true, ImportLiteral_t> literal; | ||
122 | ast_sel<false, Variable_t, TableLit_t> target; | ||
123 | AST_MEMBER(ImportAs, &literal, &target) | ||
124 | AST_END(ImportAs) | ||
125 | |||
126 | AST_NODE(ImportFrom, "ImportFrom"_id) | ||
111 | ast_ptr<true, Seperator_t> sep; | 127 | ast_ptr<true, Seperator_t> sep; |
112 | ast_sel_list<true, colon_import_name_t, Variable_t> names; | 128 | ast_sel_list<true, colon_import_name_t, Variable_t> names; |
113 | ast_ptr<true, Exp_t> exp; | 129 | ast_ptr<true, Exp_t> exp; |
114 | AST_MEMBER(Import, &sep, &names, &exp) | 130 | AST_MEMBER(ImportFrom, &sep, &names, &exp) |
131 | AST_END(ImportFrom) | ||
132 | |||
133 | AST_NODE(Import, "Import"_id) | ||
134 | ast_sel<true, ImportAs_t, ImportFrom_t> content; | ||
135 | AST_MEMBER(Import, &content) | ||
115 | AST_END(Import) | 136 | AST_END(Import) |
116 | 137 | ||
117 | AST_NODE(ExpListLow, "ExpListLow"_id) | 138 | AST_NODE(ExpListLow, "ExpListLow"_id) |
diff --git a/src/MoonP/moon_compiler.cpp b/src/MoonP/moon_compiler.cpp index 9164f6a..264ddc7 100644 --- a/src/MoonP/moon_compiler.cpp +++ b/src/MoonP/moon_compiler.cpp | |||
@@ -15,7 +15,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI | |||
15 | #include <memory> | 15 | #include <memory> |
16 | #include <sstream> | 16 | #include <sstream> |
17 | #include <string_view> | 17 | #include <string_view> |
18 | #include <iostream> | ||
19 | using namespace std::string_view_literals; | 18 | using namespace std::string_view_literals; |
20 | #include "MoonP/parser.hpp" | 19 | #include "MoonP/parser.hpp" |
21 | #include "MoonP/moon_ast.h" | 20 | #include "MoonP/moon_ast.h" |
@@ -698,9 +697,9 @@ private: | |||
698 | auto value = simpleValue->value.get(); | 697 | auto value = simpleValue->value.get(); |
699 | bool specialSingleValue = true; | 698 | bool specialSingleValue = true; |
700 | switch (value->getId()) { | 699 | switch (value->getId()) { |
701 | case "If"_id: transformIf(static_cast<If_t*>(value), out); break; | 700 | case "If"_id: transformIf(static_cast<If_t*>(value), out, ExpUsage::Common); break; |
702 | case "ClassDecl"_id: transformClassDecl(static_cast<ClassDecl_t*>(value), out); break; | 701 | case "ClassDecl"_id: transformClassDecl(static_cast<ClassDecl_t*>(value), out, ExpUsage::Common); break; |
703 | case "Unless"_id: transformUnless(static_cast<Unless_t*>(value), out); break; | 702 | case "Unless"_id: transformUnless(static_cast<Unless_t*>(value), out, ExpUsage::Common); break; |
704 | case "Switch"_id: transformSwitch(static_cast<Switch_t*>(value), out); break; | 703 | case "Switch"_id: transformSwitch(static_cast<Switch_t*>(value), out); break; |
705 | case "With"_id: transformWith(static_cast<With_t*>(value), out); break; | 704 | case "With"_id: transformWith(static_cast<With_t*>(value), out); break; |
706 | case "ForEach"_id: transformForEach(static_cast<ForEach_t*>(value), out); break; | 705 | case "ForEach"_id: transformForEach(static_cast<ForEach_t*>(value), out); break; |
@@ -900,8 +899,8 @@ private: | |||
900 | } | 899 | } |
901 | }); | 900 | }); |
902 | switch (value->getId()) { | 901 | switch (value->getId()) { |
903 | case "If"_id: transformIf(static_cast<If_t*>(value), temp); break; | 902 | case "If"_id: transformIf(static_cast<If_t*>(value), temp, ExpUsage::Common); break; |
904 | case "Unless"_id: transformUnless(static_cast<Unless_t*>(value), temp); break; | 903 | case "Unless"_id: transformUnless(static_cast<Unless_t*>(value), temp, ExpUsage::Common); break; |
905 | } | 904 | } |
906 | out.push_back(join(temp)); | 905 | out.push_back(join(temp)); |
907 | return; | 906 | return; |
@@ -941,14 +940,14 @@ private: | |||
941 | case "Comprehension"_id: { | 940 | case "Comprehension"_id: { |
942 | auto expList = assignment->expList.get(); | 941 | auto expList = assignment->expList.get(); |
943 | std::string preDefine = getPredefine(assignment); | 942 | std::string preDefine = getPredefine(assignment); |
944 | transformCompInPlace(static_cast<Comprehension_t*>(value), expList, out); | 943 | transformComprehension(static_cast<Comprehension_t*>(value), out, ExpUsage::Assignment, expList); |
945 | out.back() = preDefine + out.back(); | 944 | out.back() = preDefine + out.back(); |
946 | return; | 945 | return; |
947 | } | 946 | } |
948 | case "TblComprehension"_id: { | 947 | case "TblComprehension"_id: { |
949 | auto expList = assignment->expList.get(); | 948 | auto expList = assignment->expList.get(); |
950 | std::string preDefine = getPredefine(assignment); | 949 | std::string preDefine = getPredefine(assignment); |
951 | transformTblCompInPlace(static_cast<TblComprehension_t*>(value), expList, out); | 950 | transformTblComprehension(static_cast<TblComprehension_t*>(value), out, ExpUsage::Assignment, expList); |
952 | out.back() = preDefine + out.back(); | 951 | out.back() = preDefine + out.back(); |
953 | return; | 952 | return; |
954 | } | 953 | } |
@@ -1123,7 +1122,11 @@ private: | |||
1123 | case "variable_pair"_id: { | 1122 | case "variable_pair"_id: { |
1124 | auto vp = static_cast<variable_pair_t*>(pair); | 1123 | auto vp = static_cast<variable_pair_t*>(pair); |
1125 | auto name = toString(vp->name); | 1124 | auto name = toString(vp->name); |
1126 | pairs.push_back({true, name, s("."sv) + name}); | 1125 | if (State::keywords.find(name) != State::keywords.end()) { |
1126 | pairs.push_back({true, name, s("[\""sv) + name + s("\"]"sv)}); | ||
1127 | } else { | ||
1128 | pairs.push_back({true, name, s("."sv) + name}); | ||
1129 | } | ||
1127 | break; | 1130 | break; |
1128 | } | 1131 | } |
1129 | case "normal_pair"_id: { | 1132 | case "normal_pair"_id: { |
@@ -1136,9 +1139,15 @@ private: | |||
1136 | if (ast_cast<simple_table_t>(item) || | 1139 | if (ast_cast<simple_table_t>(item) || |
1137 | item->getByPath<TableLit_t>()) { | 1140 | item->getByPath<TableLit_t>()) { |
1138 | auto subPairs = destructFromExp(exp); | 1141 | auto subPairs = destructFromExp(exp); |
1142 | auto name = toString(key); | ||
1139 | for (auto& p : subPairs) { | 1143 | for (auto& p : subPairs) { |
1140 | pairs.push_back({p.isVariable, p.name, | 1144 | if (State::keywords.find(name) != State::keywords.end()) { |
1141 | s("."sv) + toString(key) + p.structure}); | 1145 | pairs.push_back({p.isVariable, p.name, |
1146 | s("[\""sv) + name + s("\"]"sv) + p.structure}); | ||
1147 | } else { | ||
1148 | pairs.push_back({p.isVariable, p.name, | ||
1149 | s("."sv) + name + p.structure}); | ||
1150 | } | ||
1142 | } | 1151 | } |
1143 | } else { | 1152 | } else { |
1144 | bool lintGlobal = _config.lintGlobalVariable; | 1153 | bool lintGlobal = _config.lintGlobalVariable; |
@@ -1151,11 +1160,20 @@ private: | |||
1151 | varName = std::move(temp.back()); | 1160 | varName = std::move(temp.back()); |
1152 | } | 1161 | } |
1153 | _config.lintGlobalVariable = lintGlobal; | 1162 | _config.lintGlobalVariable = lintGlobal; |
1154 | pairs.push_back({ | 1163 | auto name = toString(key); |
1155 | isVariable, | 1164 | if (State::keywords.find(name) != State::keywords.end()) { |
1156 | varName, | 1165 | pairs.push_back({ |
1157 | s("."sv) + toString(key) | 1166 | isVariable, |
1158 | }); | 1167 | varName, |
1168 | s("[\""sv) + name + s("\"]"sv) | ||
1169 | }); | ||
1170 | } else { | ||
1171 | pairs.push_back({ | ||
1172 | isVariable, | ||
1173 | varName, | ||
1174 | s("."sv) + name | ||
1175 | }); | ||
1176 | } | ||
1159 | } | 1177 | } |
1160 | break; | 1178 | break; |
1161 | } | 1179 | } |
@@ -1333,7 +1351,7 @@ private: | |||
1333 | } | 1351 | } |
1334 | } | 1352 | } |
1335 | 1353 | ||
1336 | void transformCond(const node_container& nodes, str_list& out, ExpUsage usage = ExpUsage::Common, bool unless = false) { | 1354 | void transformCond(const node_container& nodes, str_list& out, ExpUsage usage, bool unless = false) { |
1337 | std::vector<ast_ptr<false, ast_node>> ns(false); | 1355 | std::vector<ast_ptr<false, ast_node>> ns(false); |
1338 | for (auto it = nodes.rbegin(); it != nodes.rend(); ++it) { | 1356 | for (auto it = nodes.rbegin(); it != nodes.rend(); ++it) { |
1339 | ns.push_back(*it); | 1357 | ns.push_back(*it); |
@@ -1497,11 +1515,11 @@ private: | |||
1497 | out.push_back(join(temp)); | 1515 | out.push_back(join(temp)); |
1498 | } | 1516 | } |
1499 | 1517 | ||
1500 | void transformIf(If_t* ifNode, str_list& out, ExpUsage usage = ExpUsage::Common) { | 1518 | void transformIf(If_t* ifNode, str_list& out, ExpUsage usage) { |
1501 | transformCond(ifNode->nodes.objects(), out, usage); | 1519 | transformCond(ifNode->nodes.objects(), out, usage); |
1502 | } | 1520 | } |
1503 | 1521 | ||
1504 | void transformUnless(Unless_t* unless, str_list& out, ExpUsage usage = ExpUsage::Common) { | 1522 | void transformUnless(Unless_t* unless, str_list& out, ExpUsage usage) { |
1505 | transformCond(unless->nodes.objects(), out, usage, true); | 1523 | transformCond(unless->nodes.objects(), out, usage, true); |
1506 | } | 1524 | } |
1507 | 1525 | ||
@@ -1539,7 +1557,7 @@ private: | |||
1539 | case "simple_table"_id: transform_simple_table(static_cast<simple_table_t*>(item), out); break; | 1557 | case "simple_table"_id: transform_simple_table(static_cast<simple_table_t*>(item), out); break; |
1540 | case "ChainValue"_id: { | 1558 | case "ChainValue"_id: { |
1541 | auto chainValue = static_cast<ChainValue_t*>(item); | 1559 | auto chainValue = static_cast<ChainValue_t*>(item); |
1542 | transformChainValue(chainValue, out); | 1560 | transformChainValue(chainValue, out, ExpUsage::Closure); |
1543 | break; | 1561 | break; |
1544 | } | 1562 | } |
1545 | case "String"_id: transformString(static_cast<String_t*>(item), out); break; | 1563 | case "String"_id: transformString(static_cast<String_t*>(item), out); break; |
@@ -1597,9 +1615,9 @@ private: | |||
1597 | case "While"_id: transformWhileClosure(static_cast<While_t*>(value), out); break; | 1615 | case "While"_id: transformWhileClosure(static_cast<While_t*>(value), out); break; |
1598 | case "Do"_id: transformDoClosure(static_cast<Do_t*>(value), out); break; | 1616 | case "Do"_id: transformDoClosure(static_cast<Do_t*>(value), out); break; |
1599 | case "unary_exp"_id: transform_unary_exp(static_cast<unary_exp_t*>(value), out); break; | 1617 | case "unary_exp"_id: transform_unary_exp(static_cast<unary_exp_t*>(value), out); break; |
1600 | case "TblComprehension"_id: transformTblCompClosure(static_cast<TblComprehension_t*>(value), out); break; | 1618 | case "TblComprehension"_id: transformTblComprehension(static_cast<TblComprehension_t*>(value), out, ExpUsage::Closure); break; |
1601 | case "TableLit"_id: transformTableLit(static_cast<TableLit_t*>(value), out); break; | 1619 | case "TableLit"_id: transformTableLit(static_cast<TableLit_t*>(value), out); break; |
1602 | case "Comprehension"_id: transformCompClosure(static_cast<Comprehension_t*>(value), out); break; | 1620 | case "Comprehension"_id: transformComprehension(static_cast<Comprehension_t*>(value), out, ExpUsage::Closure); break; |
1603 | case "FunLit"_id: transformFunLit(static_cast<FunLit_t*>(value), out); break; | 1621 | case "FunLit"_id: transformFunLit(static_cast<FunLit_t*>(value), out); break; |
1604 | case "Num"_id: transformNum(static_cast<Num_t*>(value), out); break; | 1622 | case "Num"_id: transformNum(static_cast<Num_t*>(value), out); break; |
1605 | default: break; | 1623 | default: break; |
@@ -1771,10 +1789,10 @@ private: | |||
1771 | auto value = simpleValue->value.get(); | 1789 | auto value = simpleValue->value.get(); |
1772 | switch (value->getId()) { | 1790 | switch (value->getId()) { |
1773 | case "Comprehension"_id: | 1791 | case "Comprehension"_id: |
1774 | transformCompReturn(static_cast<Comprehension_t*>(value), out); | 1792 | transformComprehension(static_cast<Comprehension_t*>(value), out, ExpUsage::Return); |
1775 | return; | 1793 | return; |
1776 | case "TblComprehension"_id: | 1794 | case "TblComprehension"_id: |
1777 | transformTblCompReturn(static_cast<TblComprehension_t*>(value), out); | 1795 | transformTblComprehension(static_cast<TblComprehension_t*>(value), out, ExpUsage::Return); |
1778 | return; | 1796 | return; |
1779 | case "With"_id: | 1797 | case "With"_id: |
1780 | transformWith(static_cast<With_t*>(value), out, nullptr, true); | 1798 | transformWith(static_cast<With_t*>(value), out, nullptr, true); |
@@ -2223,12 +2241,14 @@ private: | |||
2223 | auto funLit = toAst<Exp_t>(s("(...)-> "sv) + fnVar + s(" "sv) + baseVar + s(", ..."sv), Exp, x); | 2241 | auto funLit = toAst<Exp_t>(s("(...)-> "sv) + fnVar + s(" "sv) + baseVar + s(", ..."sv), Exp, x); |
2224 | switch (usage) { | 2242 | switch (usage) { |
2225 | case ExpUsage::Closure: | 2243 | case ExpUsage::Closure: |
2226 | case ExpUsage::Return: | 2244 | case ExpUsage::Return: { |
2227 | transformExp(funLit, temp); | 2245 | auto returnNode = x->new_ptr<Return_t>(); |
2228 | _buf << temp.front(); | 2246 | auto expListLow = x->new_ptr<ExpListLow_t>(); |
2229 | _buf << *(++temp.begin()); | 2247 | expListLow->exprs.push_back(funLit); |
2230 | _buf << indent() << "return " << temp.back() << nll(x); | 2248 | returnNode->valueList.set(expListLow); |
2249 | transformReturn(returnNode, temp); | ||
2231 | break; | 2250 | break; |
2251 | } | ||
2232 | case ExpUsage::Assignment: { | 2252 | case ExpUsage::Assignment: { |
2233 | auto assign = x->new_ptr<Assign_t>(); | 2253 | auto assign = x->new_ptr<Assign_t>(); |
2234 | assign->values.push_back(funLit); | 2254 | assign->values.push_back(funLit); |
@@ -2395,7 +2415,7 @@ private: | |||
2395 | chainValue->items.push_back(callable); | 2415 | chainValue->items.push_back(callable); |
2396 | auto invoke = x->new_ptr<Invoke_t>(); | 2416 | auto invoke = x->new_ptr<Invoke_t>(); |
2397 | chainValue->items.push_back(invoke); | 2417 | chainValue->items.push_back(invoke); |
2398 | transformChainValue(chainValue, out); | 2418 | transformChainValue(chainValue, out, ExpUsage::Closure); |
2399 | return; | 2419 | return; |
2400 | } | 2420 | } |
2401 | transformColonChainItem(colonItem, temp); | 2421 | transformColonChainItem(colonItem, temp); |
@@ -2439,7 +2459,7 @@ private: | |||
2439 | } | 2459 | } |
2440 | } | 2460 | } |
2441 | 2461 | ||
2442 | void transformChainValue(ChainValue_t* chainValue, str_list& out, ExpUsage usage = ExpUsage::Closure, ExpList_t* assignList = nullptr) { | 2462 | void transformChainValue(ChainValue_t* chainValue, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { |
2443 | const auto& chainList = chainValue->items.objects(); | 2463 | const auto& chainList = chainValue->items.objects(); |
2444 | if (transformChainEndWithEOP(chainList, out, usage, assignList)) { | 2464 | if (transformChainEndWithEOP(chainList, out, usage, assignList)) { |
2445 | return; | 2465 | return; |
@@ -2548,12 +2568,21 @@ private: | |||
2548 | out.push_back(clearBuf()); | 2568 | out.push_back(clearBuf()); |
2549 | } | 2569 | } |
2550 | 2570 | ||
2551 | void transformComprehension(Comprehension_t* comp, str_list& out) { | 2571 | void transformComprehension(Comprehension_t* comp, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { |
2572 | auto x = comp; | ||
2573 | switch (usage) { | ||
2574 | case ExpUsage::Closure: | ||
2575 | case ExpUsage::Assignment: | ||
2576 | pushScope(); | ||
2577 | break; | ||
2578 | default: | ||
2579 | break; | ||
2580 | } | ||
2552 | str_list temp; | 2581 | str_list temp; |
2553 | std::string accum = getUnusedName("_accum_"); | 2582 | std::string accumVar = getUnusedName("_accum_"sv); |
2554 | std::string len = getUnusedName("_len_"); | 2583 | std::string lenVar = getUnusedName("_len_"sv); |
2555 | addToScope(accum); | 2584 | addToScope(accumVar); |
2556 | addToScope(len); | 2585 | addToScope(lenVar); |
2557 | auto compInner = comp->forLoop.get(); | 2586 | auto compInner = comp->forLoop.get(); |
2558 | for (auto item : compInner->items.objects()) { | 2587 | for (auto item : compInner->items.objects()) { |
2559 | switch (item->getId()) { | 2588 | switch (item->getId()) { |
@@ -2570,61 +2599,60 @@ private: | |||
2570 | break; | 2599 | break; |
2571 | } | 2600 | } |
2572 | } | 2601 | } |
2573 | transformExp(comp->value.to<Exp_t>(), temp); | 2602 | { |
2574 | auto value = temp.back(); | 2603 | auto assignLeft = toAst<ExpList_t>(accumVar + s("["sv) + lenVar + s("]"sv), ExpList, x); |
2604 | auto assign = x->new_ptr<Assign_t>(); | ||
2605 | assign->values.push_back(comp->value); | ||
2606 | auto assignment = x->new_ptr<ExpListAssign_t>(); | ||
2607 | assignment->expList.set(assignLeft); | ||
2608 | assignment->action.set(assign); | ||
2609 | transformAssignment(assignment, temp); | ||
2610 | } | ||
2611 | auto assignStr = temp.back(); | ||
2575 | temp.pop_back(); | 2612 | temp.pop_back(); |
2576 | for (size_t i = 0; i < compInner->items.objects().size(); ++i) { | 2613 | for (size_t i = 0; i < compInner->items.objects().size(); ++i) { |
2577 | popScope(); | 2614 | popScope(); |
2578 | } | 2615 | } |
2579 | _buf << indent() << "local "sv << accum << " = { }"sv << nll(comp); | 2616 | _buf << indent() << "local "sv << accumVar << " = { }"sv << nll(comp); |
2580 | _buf << indent() << "local "sv << len << " = 1"sv << nll(comp); | 2617 | _buf << indent() << "local "sv << lenVar << " = 1"sv << nll(comp); |
2581 | _buf << join(temp); | 2618 | _buf << join(temp); |
2582 | _buf << indent(int(temp.size())) << accum << "["sv << len << "] = "sv << value << nll(comp); | 2619 | _buf << assignStr; |
2583 | _buf << indent(int(temp.size())) << len << " = "sv << len << " + 1"sv << nll(comp); | 2620 | _buf << indent(int(temp.size())) << lenVar << " = "sv << lenVar << " + 1"sv << nll(comp); |
2584 | for (int ind = int(temp.size()) - 1; ind > -1 ; --ind) { | 2621 | for (int ind = int(temp.size()) - 1; ind > -1 ; --ind) { |
2585 | _buf << indent(ind) << "end"sv << nll(comp); | 2622 | _buf << indent(ind) << "end"sv << nll(comp); |
2586 | } | 2623 | } |
2587 | out.push_back(accum); | 2624 | switch (usage) { |
2588 | out.push_back(clearBuf()); | 2625 | case ExpUsage::Common: |
2589 | } | 2626 | break; |
2590 | 2627 | case ExpUsage::Closure: { | |
2591 | void transformCompInPlace(Comprehension_t* comp, ExpList_t* expList, str_list& out) { | 2628 | out.push_back(clearBuf()); |
2592 | auto x = comp; | 2629 | out.back().append(indent() + s("return "sv) + accumVar + nlr(comp)); |
2593 | str_list temp; | 2630 | popScope(); |
2594 | auto ind = indent(); | 2631 | out.back().insert(0, s("(function()"sv) + nll(comp)); |
2595 | pushScope(); | 2632 | out.back().append(indent() + s("end)()"sv)); |
2596 | transformComprehension(comp, temp); | 2633 | break; |
2597 | auto assign = x->new_ptr<Assign_t>(); | 2634 | } |
2598 | assign->values.push_back(toAst<Exp_t>(temp.front(), Exp, x)); | 2635 | case ExpUsage::Assignment: { |
2599 | auto assignment = x->new_ptr<ExpListAssign_t>(); | 2636 | out.push_back(clearBuf()); |
2600 | assignment->expList.set(expList); | 2637 | auto assign = x->new_ptr<Assign_t>(); |
2601 | assignment->action.set(assign); | 2638 | assign->values.push_back(toAst<Exp_t>(accumVar, Exp, x)); |
2602 | transformAssignment(assignment, temp); | 2639 | auto assignment = x->new_ptr<ExpListAssign_t>(); |
2603 | out.push_back( | 2640 | assignment->expList.set(assignList); |
2604 | ind + s("do"sv) + nll(comp) + | 2641 | assignment->action.set(assign); |
2605 | *(++temp.begin()) + | 2642 | transformAssignment(assignment, temp); |
2606 | temp.back()); | 2643 | popScope(); |
2607 | popScope(); | 2644 | out.back() = indent() + s("do"sv) + nll(comp) + |
2608 | out.back() = out.back() + indent() + s("end"sv) + nlr(comp); | 2645 | out.back() + temp.back() + |
2609 | } | 2646 | indent() + s("end"sv) + nlr(comp); |
2610 | 2647 | break; | |
2611 | void transformCompReturn(Comprehension_t* comp, str_list& out) { | 2648 | } |
2612 | str_list temp; | 2649 | case ExpUsage::Return: |
2613 | transformComprehension(comp, temp); | 2650 | out.push_back(clearBuf()); |
2614 | out.push_back(temp.back() + indent() + s("return "sv) + temp.front() + nlr(comp)); | 2651 | out.back().append(indent() + s("return "sv) + accumVar + nlr(comp)); |
2615 | } | 2652 | break; |
2616 | 2653 | default: | |
2617 | void transformCompClosure(Comprehension_t* comp, str_list& out) { | 2654 | break; |
2618 | str_list temp; | 2655 | } |
2619 | std::string before = s("(function()"sv) + nll(comp); | ||
2620 | pushScope(); | ||
2621 | transformComprehension(comp, temp); | ||
2622 | out.push_back( | ||
2623 | before + | ||
2624 | temp.back() + | ||
2625 | indent() + s("return "sv) + temp.front() + nlr(comp)); | ||
2626 | popScope(); | ||
2627 | out.back() = out.back() + indent() + s("end)()"sv); | ||
2628 | } | 2656 | } |
2629 | 2657 | ||
2630 | void transformForEachHead(AssignableNameList_t* nameList, ast_node* loopTarget, str_list& out) { | 2658 | void transformForEachHead(AssignableNameList_t* nameList, ast_node* loopTarget, str_list& out) { |
@@ -2698,7 +2726,7 @@ private: | |||
2698 | if (listVar.empty()) { | 2726 | if (listVar.empty()) { |
2699 | listVar = getUnusedName("_list_"); | 2727 | listVar = getUnusedName("_list_"); |
2700 | varBefore.push_back(listVar); | 2728 | varBefore.push_back(listVar); |
2701 | transformChainValue(chain, temp); | 2729 | transformChainValue(chain, temp, ExpUsage::Closure); |
2702 | _buf << indent() << "local "sv << listVar << " = "sv << temp.back() << nll(nameList); | 2730 | _buf << indent() << "local "sv << listVar << " = "sv << temp.back() << nll(nameList); |
2703 | } | 2731 | } |
2704 | std::string maxVar; | 2732 | std::string maxVar; |
@@ -2862,9 +2890,9 @@ private: | |||
2862 | 2890 | ||
2863 | std::string transformForInner(For_t* forNode, str_list& out) { | 2891 | std::string transformForInner(For_t* forNode, str_list& out) { |
2864 | auto x = forNode; | 2892 | auto x = forNode; |
2865 | std::string accum = getUnusedName("_accum_"); | 2893 | std::string accum = getUnusedName("_accum_"sv); |
2866 | addToScope(accum); | 2894 | addToScope(accum); |
2867 | std::string len = getUnusedName("_len_"); | 2895 | std::string len = getUnusedName("_len_"sv); |
2868 | addToScope(len); | 2896 | addToScope(len); |
2869 | _buf << indent() << "local "sv << accum << " = { }"sv << nll(forNode); | 2897 | _buf << indent() << "local "sv << accum << " = { }"sv << nll(forNode); |
2870 | _buf << indent() << "local "sv << len << " = 1"sv << nll(forNode); | 2898 | _buf << indent() << "local "sv << len << " = 1"sv << nll(forNode); |
@@ -2930,9 +2958,9 @@ private: | |||
2930 | 2958 | ||
2931 | std::string transformForEachInner(ForEach_t* forEach, str_list& out) { | 2959 | std::string transformForEachInner(ForEach_t* forEach, str_list& out) { |
2932 | auto x = forEach; | 2960 | auto x = forEach; |
2933 | std::string accum = getUnusedName("_accum_"); | 2961 | std::string accum = getUnusedName("_accum_"sv); |
2934 | addToScope(accum); | 2962 | addToScope(accum); |
2935 | std::string len = getUnusedName("_len_"); | 2963 | std::string len = getUnusedName("_len_"sv); |
2936 | addToScope(len); | 2964 | addToScope(len); |
2937 | _buf << indent() << "local "sv << accum << " = { }"sv << nll(forEach); | 2965 | _buf << indent() << "local "sv << accum << " = { }"sv << nll(forEach); |
2938 | _buf << indent() << "local "sv << len << " = 1"sv << nll(forEach); | 2966 | _buf << indent() << "local "sv << len << " = 1"sv << nll(forEach); |
@@ -3107,7 +3135,7 @@ private: | |||
3107 | out.push_back(join(temp)); | 3135 | out.push_back(join(temp)); |
3108 | } | 3136 | } |
3109 | 3137 | ||
3110 | void transformClassDecl(ClassDecl_t* classDecl, str_list& out, ExpUsage usage = ExpUsage::Common, ExpList_t* expList = nullptr) { | 3138 | void transformClassDecl(ClassDecl_t* classDecl, str_list& out, ExpUsage usage, ExpList_t* expList = nullptr) { |
3111 | str_list temp; | 3139 | str_list temp; |
3112 | auto x = classDecl; | 3140 | auto x = classDecl; |
3113 | auto body = classDecl->body.get(); | 3141 | auto body = classDecl->body.get(); |
@@ -3482,7 +3510,7 @@ private: | |||
3482 | } | 3510 | } |
3483 | } | 3511 | } |
3484 | if (withVar.empty()) { | 3512 | if (withVar.empty()) { |
3485 | withVar = getUnusedName("_with_"); | 3513 | withVar = getUnusedName("_with_"sv); |
3486 | auto assignment = x->new_ptr<ExpListAssign_t>(); | 3514 | auto assignment = x->new_ptr<ExpListAssign_t>(); |
3487 | assignment->expList.set(toAst<ExpList_t>(withVar, ExpList, x)); | 3515 | assignment->expList.set(toAst<ExpList_t>(withVar, ExpList, x)); |
3488 | auto assign = x->new_ptr<Assign_t>(); | 3516 | auto assign = x->new_ptr<Assign_t>(); |
@@ -3524,7 +3552,7 @@ private: | |||
3524 | } else { | 3552 | } else { |
3525 | withVar = singleVariableFrom(with->valueList); | 3553 | withVar = singleVariableFrom(with->valueList); |
3526 | if (withVar.empty()) { | 3554 | if (withVar.empty()) { |
3527 | withVar = getUnusedName("_with_"); | 3555 | withVar = getUnusedName("_with_"sv); |
3528 | auto assignment = x->new_ptr<ExpListAssign_t>(); | 3556 | auto assignment = x->new_ptr<ExpListAssign_t>(); |
3529 | assignment->expList.set(toAst<ExpList_t>(withVar, ExpList, x)); | 3557 | assignment->expList.set(toAst<ExpList_t>(withVar, ExpList, x)); |
3530 | auto assign = x->new_ptr<Assign_t>(); | 3558 | auto assign = x->new_ptr<Assign_t>(); |
@@ -3621,7 +3649,7 @@ private: | |||
3621 | markVarExported(ExportMode::Any, true); | 3649 | markVarExported(ExportMode::Any, true); |
3622 | addExportedVar(toString(classDecl->name->item)); | 3650 | addExportedVar(toString(classDecl->name->item)); |
3623 | } | 3651 | } |
3624 | transformClassDecl(classDecl, out); | 3652 | transformClassDecl(classDecl, out, ExpUsage::Common); |
3625 | break; | 3653 | break; |
3626 | } | 3654 | } |
3627 | case "export_op"_id: | 3655 | case "export_op"_id: |
@@ -3690,9 +3718,18 @@ private: | |||
3690 | transformTable(table, table->pairs.objects(), out); | 3718 | transformTable(table, table->pairs.objects(), out); |
3691 | } | 3719 | } |
3692 | 3720 | ||
3693 | void transformTblComprehension(TblComprehension_t* comp, str_list& out) { | 3721 | void transformTblComprehension(TblComprehension_t* comp, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { |
3722 | switch (usage) { | ||
3723 | case ExpUsage::Closure: | ||
3724 | case ExpUsage::Assignment: | ||
3725 | pushScope(); | ||
3726 | break; | ||
3727 | default: | ||
3728 | break; | ||
3729 | } | ||
3730 | auto x = comp; | ||
3694 | str_list kv; | 3731 | str_list kv; |
3695 | std::string tbl = getUnusedName("_tbl_"); | 3732 | std::string tbl = getUnusedName("_tbl_"sv); |
3696 | addToScope(tbl); | 3733 | addToScope(tbl); |
3697 | str_list temp; | 3734 | str_list temp; |
3698 | auto compInner = comp->forLoop.get(); | 3735 | auto compInner = comp->forLoop.get(); |
@@ -3722,8 +3759,8 @@ private: | |||
3722 | _buf << join(temp); | 3759 | _buf << join(temp); |
3723 | pushScope(); | 3760 | pushScope(); |
3724 | if (!comp->value) { | 3761 | if (!comp->value) { |
3725 | auto keyVar = getUnusedName("_key_"); | 3762 | auto keyVar = getUnusedName("_key_"sv); |
3726 | auto valVar = getUnusedName("_val_"); | 3763 | auto valVar = getUnusedName("_val_"sv); |
3727 | _buf << indent(int(temp.size()) - 1) << "local "sv << keyVar << ", "sv << valVar << " = "sv << kv.front() << nll(comp); | 3764 | _buf << indent(int(temp.size()) - 1) << "local "sv << keyVar << ", "sv << valVar << " = "sv << kv.front() << nll(comp); |
3728 | kv.front() = keyVar; | 3765 | kv.front() = keyVar; |
3729 | kv.push_back(valVar); | 3766 | kv.push_back(valVar); |
@@ -3735,48 +3772,33 @@ private: | |||
3735 | popScope(); | 3772 | popScope(); |
3736 | _buf << indent() << "end"sv << nll(comp); | 3773 | _buf << indent() << "end"sv << nll(comp); |
3737 | out.push_back(tbl); | 3774 | out.push_back(tbl); |
3738 | out.push_back(clearBuf()); | 3775 | switch (usage) { |
3739 | } | 3776 | case ExpUsage::Closure: |
3740 | 3777 | out.push_back(clearBuf() + indent() + s("return "sv) + tbl + nlr(comp)); | |
3741 | void transformTblCompInPlace(TblComprehension_t* comp, ExpList_t* expList, str_list& out) { | 3778 | popScope(); |
3742 | auto x = comp; | 3779 | out.back().insert(0, s("(function()"sv) + nll(comp)); |
3743 | str_list temp; | 3780 | out.back().append(indent() + s("end)()"sv)); |
3744 | auto ind = indent(); | 3781 | break; |
3745 | pushScope(); | 3782 | case ExpUsage::Assignment: { |
3746 | transformTblComprehension(comp, temp); | 3783 | out.push_back(clearBuf()); |
3747 | auto assign = x->new_ptr<Assign_t>(); | 3784 | auto assign = x->new_ptr<Assign_t>(); |
3748 | assign->values.push_back(toAst<Exp_t>(temp.front(), Exp, x)); | 3785 | assign->values.push_back(toAst<Exp_t>(tbl, Exp, x)); |
3749 | auto assignment = x->new_ptr<ExpListAssign_t>(); | 3786 | auto assignment = x->new_ptr<ExpListAssign_t>(); |
3750 | assignment->expList.set(expList); | 3787 | assignment->expList.set(assignList); |
3751 | assignment->action.set(assign); | 3788 | assignment->action.set(assign); |
3752 | transformAssignment(assignment, temp); | 3789 | transformAssignment(assignment, temp); |
3753 | out.push_back( | 3790 | out.back().append(temp.back()); |
3754 | ind + s("do"sv) + nll(comp) + | 3791 | popScope(); |
3755 | *(++temp.begin()) + | 3792 | out.back().insert(0, indent() + s("do"sv) + nll(comp)); |
3756 | temp.back()); | 3793 | out.back().append(indent() + s("end"sv) + nlr(comp)); |
3757 | popScope(); | 3794 | break; |
3758 | out.back() = out.back() + indent() + s("end"sv) + nlr(comp); | 3795 | } |
3759 | } | 3796 | case ExpUsage::Return: |
3760 | 3797 | out.push_back(clearBuf() + indent() + s("return "sv) + tbl + nlr(comp)); | |
3761 | void transformTblCompReturn(TblComprehension_t* comp, str_list& out) { | 3798 | break; |
3762 | str_list temp; | 3799 | default: |
3763 | transformTblComprehension(comp, temp); | 3800 | break; |
3764 | out.push_back(temp.back() + indent() + s("return "sv) + temp.front() + nlr(comp)); | 3801 | } |
3765 | } | ||
3766 | |||
3767 | void transformTblCompClosure(TblComprehension_t* comp, str_list& out) { | ||
3768 | str_list temp; | ||
3769 | std::string before = s("(function()"sv) + nll(comp); | ||
3770 | pushScope(); | ||
3771 | transformTblComprehension(comp, temp); | ||
3772 | const auto& tbVar = temp.front(); | ||
3773 | const auto& compBody = temp.back(); | ||
3774 | out.push_back( | ||
3775 | before + | ||
3776 | compBody + | ||
3777 | indent() + s("return "sv) + tbVar + nlr(comp)); | ||
3778 | popScope(); | ||
3779 | out.back() = out.back() + indent() + s("end)()"sv); | ||
3780 | } | 3802 | } |
3781 | 3803 | ||
3782 | void transformCompFor(CompFor_t* comp, str_list& out) { | 3804 | void transformCompFor(CompFor_t* comp, str_list& out) { |
@@ -3823,7 +3845,7 @@ private: | |||
3823 | out.push_back(join(temp)); | 3845 | out.push_back(join(temp)); |
3824 | } | 3846 | } |
3825 | 3847 | ||
3826 | void transformImport(Import_t* import, str_list& out) { | 3848 | void transformImportFrom(ImportFrom_t* import, str_list& out) { |
3827 | str_list temp; | 3849 | str_list temp; |
3828 | auto x = import; | 3850 | auto x = import; |
3829 | auto objVar = singleVariableFrom(import->exp); | 3851 | auto objVar = singleVariableFrom(import->exp); |
@@ -3917,6 +3939,54 @@ private: | |||
3917 | out.push_back(join(temp)); | 3939 | out.push_back(join(temp)); |
3918 | } | 3940 | } |
3919 | 3941 | ||
3942 | void transformImportAs(ImportAs_t* import, str_list& out) { | ||
3943 | auto x = import; | ||
3944 | if (!import->target) { | ||
3945 | auto name = toString(import->literal->inners.back()); | ||
3946 | replace(name, "-"sv, "_"sv); | ||
3947 | replace(name, " "sv, "_"sv); | ||
3948 | import->target.set(toAst<Variable_t>(name, Variable, x)); | ||
3949 | } | ||
3950 | auto target = import->target.get(); | ||
3951 | auto value = x->new_ptr<Value_t>(); | ||
3952 | if (auto var = ast_cast<Variable_t>(target)) { | ||
3953 | auto callable = x->new_ptr<Callable_t>(); | ||
3954 | callable->item.set(var); | ||
3955 | auto chainValue = x->new_ptr<ChainValue_t>(); | ||
3956 | chainValue->items.push_back(callable); | ||
3957 | value->item.set(chainValue); | ||
3958 | } else { | ||
3959 | auto tableLit = ast_to<TableLit_t>(target); | ||
3960 | auto simpleValue = x->new_ptr<SimpleValue_t>(); | ||
3961 | simpleValue->value.set(tableLit); | ||
3962 | value->item.set(simpleValue); | ||
3963 | } | ||
3964 | auto exp = x->new_ptr<Exp_t>(); | ||
3965 | exp->value.set(value); | ||
3966 | auto assignList = x->new_ptr<ExpList_t>(); | ||
3967 | assignList->exprs.push_back(exp); | ||
3968 | auto assign = x->new_ptr<Assign_t>(); | ||
3969 | assign->values.push_back(toAst<Exp_t>(s("require ") + toString(import->literal), Exp, x)); | ||
3970 | auto assignment = x->new_ptr<ExpListAssign_t>(); | ||
3971 | assignment->expList.set(assignList); | ||
3972 | assignment->action.set(assign); | ||
3973 | transformAssignment(assignment, out); | ||
3974 | } | ||
3975 | |||
3976 | void transformImport(Import_t* import, str_list& out) { | ||
3977 | auto content = import->content.get(); | ||
3978 | switch (content->getId()) { | ||
3979 | case "ImportAs"_id: | ||
3980 | transformImportAs(static_cast<ImportAs_t*>(content), out); | ||
3981 | break; | ||
3982 | case "ImportFrom"_id: | ||
3983 | transformImportFrom(static_cast<ImportFrom_t*>(content), out); | ||
3984 | break; | ||
3985 | default: | ||
3986 | break; | ||
3987 | } | ||
3988 | } | ||
3989 | |||
3920 | void transformWhileInPlace(While_t* whileNode, str_list& out, ExpList_t* expList = nullptr) { | 3990 | void transformWhileInPlace(While_t* whileNode, str_list& out, ExpList_t* expList = nullptr) { |
3921 | auto x = whileNode; | 3991 | auto x = whileNode; |
3922 | str_list temp; | 3992 | str_list temp; |
diff --git a/src/MoonP/moon_parser.cpp b/src/MoonP/moon_parser.cpp index 7cc4129..d3c0ed2 100644 --- a/src/MoonP/moon_parser.cpp +++ b/src/MoonP/moon_parser.cpp | |||
@@ -26,9 +26,9 @@ std::unordered_set<std::string> State::keywords = { | |||
26 | "in", "local", "nil", "not", "or", | 26 | "in", "local", "nil", "not", "or", |
27 | "repeat", "return", "then", "true", "until", | 27 | "repeat", "return", "then", "true", "until", |
28 | "while", // Lua keywords | 28 | "while", // Lua keywords |
29 | "class", "continue", "export", "extends", "from", | 29 | "as", "class", "continue", "export", "extends", |
30 | "import", "switch", "unless", "using", "when", | 30 | "from", "import", "switch", "unless", "using", |
31 | "with" // Moon keywords | 31 | "when", "with" // Moon keywords |
32 | }; | 32 | }; |
33 | 33 | ||
34 | rule plain_space = *set(" \t"); | 34 | rule plain_space = *set(" \t"); |
@@ -160,9 +160,16 @@ rule colon_import_name = sym('\\') >> Space >> Variable; | |||
160 | rule ImportName = colon_import_name | Space >> Variable; | 160 | rule ImportName = colon_import_name | Space >> Variable; |
161 | rule ImportNameList = Seperator >> *SpaceBreak >> ImportName >> *((+SpaceBreak | sym(',') >> *SpaceBreak) >> ImportName); | 161 | rule ImportNameList = Seperator >> *SpaceBreak >> ImportName >> *((+SpaceBreak | sym(',') >> *SpaceBreak) >> ImportName); |
162 | 162 | ||
163 | extern rule Exp; | 163 | extern rule Exp, TableLit; |
164 | 164 | ||
165 | rule Import = key("import") >> ImportNameList >> *SpaceBreak >> key("from") >> Exp; | 165 | rule import_literal_inner = (range('a', 'z') | range('A', 'Z') | set("_-")) >> *(AlphaNum | '-'); |
166 | rule import_literal_chain = Seperator >> import_literal_inner >> *(expr('.') >> import_literal_inner); | ||
167 | rule ImportLiteral = sym('\'') >> import_literal_chain >> symx('\'') | sym('"') >> import_literal_chain >> symx('"'); | ||
168 | |||
169 | rule ImportFrom = ImportNameList >> *SpaceBreak >> key("from") >> Exp; | ||
170 | rule ImportAs = ImportLiteral >> -(key("as") >> (Space >> Variable | TableLit)); | ||
171 | |||
172 | rule Import = key("import") >> (ImportAs | ImportFrom); | ||
166 | rule BreakLoop = (expr("break") | expr("continue")) >> not_(AlphaNum); | 173 | rule BreakLoop = (expr("break") | expr("continue")) >> not_(AlphaNum); |
167 | 174 | ||
168 | extern rule ExpListLow, ExpList, Assign; | 175 | extern rule ExpListLow, ExpList, Assign; |
@@ -301,12 +308,12 @@ rule Value = SimpleValue | simple_table | ChainValue | String; | |||
301 | extern rule LuaString; | 308 | extern rule LuaString; |
302 | 309 | ||
303 | rule single_string_inner = expr("\\'") | "\\\\" | not_(expr('\'')) >> Any; | 310 | rule single_string_inner = expr("\\'") | "\\\\" | not_(expr('\'')) >> Any; |
304 | rule SingleString = symx('\'') >> *single_string_inner >> sym('\''); | 311 | rule SingleString = symx('\'') >> *single_string_inner >> symx('\''); |
305 | rule interp = symx("#{") >> Exp >> sym('}'); | 312 | rule interp = symx("#{") >> Exp >> sym('}'); |
306 | rule double_string_plain = expr("\\\"") | "\\\\" | not_(expr('"')) >> Any; | 313 | rule double_string_plain = expr("\\\"") | "\\\\" | not_(expr('"')) >> Any; |
307 | rule double_string_inner = +(not_(interp) >> double_string_plain); | 314 | rule double_string_inner = +(not_(interp) >> double_string_plain); |
308 | rule double_string_content = double_string_inner | interp; | 315 | rule double_string_content = double_string_inner | interp; |
309 | rule DoubleString = symx('"') >> Seperator >> *double_string_content >> sym('"'); | 316 | rule DoubleString = symx('"') >> Seperator >> *double_string_content >> symx('"'); |
310 | rule String = Space >> (DoubleString | SingleString | LuaString); | 317 | rule String = Space >> (DoubleString | SingleString | LuaString); |
311 | 318 | ||
312 | rule lua_string_open = '[' >> *expr('=') >> '['; | 319 | rule lua_string_open = '[' >> *expr('=') >> '['; |