aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2020-01-23 14:35:14 +0800
committerLi Jin <dragon-fly@qq.com>2020-01-23 14:35:14 +0800
commit7ac3519dc40bb6f6ab979c9cd35fd585f25d1c25 (patch)
tree024fabcf12638dbd4cb9fe6c58251f9227fc9380 /src
parent782334d95720819f216004e0120ea84ba2c43afb (diff)
downloadyuescript-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.cpp4
-rw-r--r--src/MoonP/moon_ast.h25
-rw-r--r--src/MoonP/moon_compiler.cpp348
-rw-r--r--src/MoonP/moon_parser.cpp21
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)
29AST_IMPL(NameList) 29AST_IMPL(NameList)
30AST_IMPL(Local) 30AST_IMPL(Local)
31AST_IMPL(colon_import_name) 31AST_IMPL(colon_import_name)
32AST_IMPL(import_literal_inner)
33AST_IMPL(ImportLiteral)
34AST_IMPL(ImportFrom)
35AST_IMPL(ImportAs)
32AST_IMPL(Import) 36AST_IMPL(Import)
33AST_IMPL(ExpListLow) 37AST_IMPL(ExpListLow)
34AST_IMPL(ExpList) 38AST_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)
106AST_END(colon_import_name) 106AST_END(colon_import_name)
107 107
108class Exp_t; 108class Exp_t;
109class TableLit_t;
109 110
110AST_NODE(Import, "Import"_id) 111AST_LEAF(import_literal_inner, "import_literal_inner"_id)
112AST_END(import_literal_inner)
113
114AST_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)
118AST_END(ImportLiteral)
119
120AST_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)
124AST_END(ImportAs)
125
126AST_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)
131AST_END(ImportFrom)
132
133AST_NODE(Import, "Import"_id)
134 ast_sel<true, ImportAs_t, ImportFrom_t> content;
135 AST_MEMBER(Import, &content)
115AST_END(Import) 136AST_END(Import)
116 137
117AST_NODE(ExpListLow, "ExpListLow"_id) 138AST_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>
19using namespace std::string_view_literals; 18using 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
34rule plain_space = *set(" \t"); 34rule plain_space = *set(" \t");
@@ -160,9 +160,16 @@ rule colon_import_name = sym('\\') >> Space >> Variable;
160rule ImportName = colon_import_name | Space >> Variable; 160rule ImportName = colon_import_name | Space >> Variable;
161rule ImportNameList = Seperator >> *SpaceBreak >> ImportName >> *((+SpaceBreak | sym(',') >> *SpaceBreak) >> ImportName); 161rule ImportNameList = Seperator >> *SpaceBreak >> ImportName >> *((+SpaceBreak | sym(',') >> *SpaceBreak) >> ImportName);
162 162
163extern rule Exp; 163extern rule Exp, TableLit;
164 164
165rule Import = key("import") >> ImportNameList >> *SpaceBreak >> key("from") >> Exp; 165rule import_literal_inner = (range('a', 'z') | range('A', 'Z') | set("_-")) >> *(AlphaNum | '-');
166rule import_literal_chain = Seperator >> import_literal_inner >> *(expr('.') >> import_literal_inner);
167rule ImportLiteral = sym('\'') >> import_literal_chain >> symx('\'') | sym('"') >> import_literal_chain >> symx('"');
168
169rule ImportFrom = ImportNameList >> *SpaceBreak >> key("from") >> Exp;
170rule ImportAs = ImportLiteral >> -(key("as") >> (Space >> Variable | TableLit));
171
172rule Import = key("import") >> (ImportAs | ImportFrom);
166rule BreakLoop = (expr("break") | expr("continue")) >> not_(AlphaNum); 173rule BreakLoop = (expr("break") | expr("continue")) >> not_(AlphaNum);
167 174
168extern rule ExpListLow, ExpList, Assign; 175extern rule ExpListLow, ExpList, Assign;
@@ -301,12 +308,12 @@ rule Value = SimpleValue | simple_table | ChainValue | String;
301extern rule LuaString; 308extern rule LuaString;
302 309
303rule single_string_inner = expr("\\'") | "\\\\" | not_(expr('\'')) >> Any; 310rule single_string_inner = expr("\\'") | "\\\\" | not_(expr('\'')) >> Any;
304rule SingleString = symx('\'') >> *single_string_inner >> sym('\''); 311rule SingleString = symx('\'') >> *single_string_inner >> symx('\'');
305rule interp = symx("#{") >> Exp >> sym('}'); 312rule interp = symx("#{") >> Exp >> sym('}');
306rule double_string_plain = expr("\\\"") | "\\\\" | not_(expr('"')) >> Any; 313rule double_string_plain = expr("\\\"") | "\\\\" | not_(expr('"')) >> Any;
307rule double_string_inner = +(not_(interp) >> double_string_plain); 314rule double_string_inner = +(not_(interp) >> double_string_plain);
308rule double_string_content = double_string_inner | interp; 315rule double_string_content = double_string_inner | interp;
309rule DoubleString = symx('"') >> Seperator >> *double_string_content >> sym('"'); 316rule DoubleString = symx('"') >> Seperator >> *double_string_content >> symx('"');
310rule String = Space >> (DoubleString | SingleString | LuaString); 317rule String = Space >> (DoubleString | SingleString | LuaString);
311 318
312rule lua_string_open = '[' >> *expr('=') >> '['; 319rule lua_string_open = '[' >> *expr('=') >> '[';