diff options
Diffstat (limited to '')
| -rw-r--r-- | src/MoonP/moon_compiler.cpp | 53 |
1 files changed, 36 insertions, 17 deletions
diff --git a/src/MoonP/moon_compiler.cpp b/src/MoonP/moon_compiler.cpp index c854f58..0ac7a60 100644 --- a/src/MoonP/moon_compiler.cpp +++ b/src/MoonP/moon_compiler.cpp | |||
| @@ -43,7 +43,7 @@ inline std::string s(std::string_view sv) { | |||
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | const char* version() { | 45 | const char* version() { |
| 46 | return "0.3.7"; | 46 | return "0.3.8"; |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | // name of table stored in lua registry | 49 | // name of table stored in lua registry |
| @@ -89,7 +89,7 @@ public: | |||
| 89 | try { | 89 | try { |
| 90 | str_list out; | 90 | str_list out; |
| 91 | pushScope(); | 91 | pushScope(); |
| 92 | enableReturn.push(_info.moduleName.empty()); | 92 | _enableReturn.push(_info.moduleName.empty()); |
| 93 | transformBlock(_info.node.to<File_t>()->block, out, | 93 | transformBlock(_info.node.to<File_t>()->block, out, |
| 94 | config.implicitReturnRoot ? ExpUsage::Return : ExpUsage::Common, | 94 | config.implicitReturnRoot ? ExpUsage::Return : ExpUsage::Common, |
| 95 | nullptr, true); | 95 | nullptr, true); |
| @@ -121,8 +121,10 @@ public: | |||
| 121 | _joinBuf.clear(); | 121 | _joinBuf.clear(); |
| 122 | _globals.clear(); | 122 | _globals.clear(); |
| 123 | _info = {}; | 123 | _info = {}; |
| 124 | _varArgs = {}; | ||
| 124 | _withVars = {}; | 125 | _withVars = {}; |
| 125 | _continueVars = {}; | 126 | _continueVars = {}; |
| 127 | _enableReturn = {}; | ||
| 126 | if (_useModule) { | 128 | if (_useModule) { |
| 127 | _useModule = false; | 129 | _useModule = false; |
| 128 | if (!_sameModule) { | 130 | if (!_sameModule) { |
| @@ -144,10 +146,11 @@ private: | |||
| 144 | MoonParser _parser; | 146 | MoonParser _parser; |
| 145 | ParseInfo _info; | 147 | ParseInfo _info; |
| 146 | int _indentOffset = 0; | 148 | int _indentOffset = 0; |
| 147 | std::stack<bool> enableReturn; | 149 | std::stack<bool> _varArgs; |
| 148 | std::list<std::unique_ptr<input>> _codeCache; | 150 | std::stack<bool> _enableReturn; |
| 149 | std::stack<std::string> _withVars; | 151 | std::stack<std::string> _withVars; |
| 150 | std::stack<std::string> _continueVars; | 152 | std::stack<std::string> _continueVars; |
| 153 | std::list<std::unique_ptr<input>> _codeCache; | ||
| 151 | std::unordered_map<std::string,std::pair<int,int>> _globals; | 154 | std::unordered_map<std::string,std::pair<int,int>> _globals; |
| 152 | std::ostringstream _buf; | 155 | std::ostringstream _buf; |
| 153 | std::ostringstream _joinBuf; | 156 | std::ostringstream _joinBuf; |
| @@ -335,11 +338,19 @@ private: | |||
| 335 | } | 338 | } |
| 336 | 339 | ||
| 337 | std::string indent() const { | 340 | std::string indent() const { |
| 338 | return std::string(_scopes.size() - 1 + _indentOffset, '\t'); | 341 | if (_config.useSpaceOverTab) { |
| 342 | return std::string((_scopes.size() - 1 + _indentOffset) * 2, ' '); | ||
| 343 | } else { | ||
| 344 | return std::string(_scopes.size() - 1 + _indentOffset, '\t'); | ||
| 345 | } | ||
| 339 | } | 346 | } |
| 340 | 347 | ||
| 341 | std::string indent(int offset) const { | 348 | std::string indent(int offset) const { |
| 342 | return std::string(_scopes.size() - 1 + _indentOffset + offset, '\t'); | 349 | if (_config.useSpaceOverTab) { |
| 350 | return std::string((_scopes.size() - 1 + _indentOffset + offset) * 2, ' '); | ||
| 351 | } else { | ||
| 352 | return std::string(_scopes.size() - 1 + _indentOffset + offset, '\t'); | ||
| 353 | } | ||
| 343 | } | 354 | } |
| 344 | 355 | ||
| 345 | std::string clearBuf() { | 356 | std::string clearBuf() { |
| @@ -1010,6 +1021,11 @@ private: | |||
| 1010 | } | 1021 | } |
| 1011 | auto exp = ast_cast<Exp_t>(value); | 1022 | auto exp = ast_cast<Exp_t>(value); |
| 1012 | BREAK_IF(!exp); | 1023 | BREAK_IF(!exp); |
| 1024 | if (isPureBackcall(exp)) { | ||
| 1025 | auto expList = assignment->expList.get(); | ||
| 1026 | transformExp(exp, out, ExpUsage::Assignment, expList); | ||
| 1027 | return; | ||
| 1028 | } | ||
| 1013 | BREAK_IF(!exp->opValues.empty()); | 1029 | BREAK_IF(!exp->opValues.empty()); |
| 1014 | if (auto chainValue = exp->value->item.as<ChainValue_t>()) { | 1030 | if (auto chainValue = exp->value->item.as<ChainValue_t>()) { |
| 1015 | auto type = specialChainValue(chainValue); | 1031 | auto type = specialChainValue(chainValue); |
| @@ -1031,11 +1047,6 @@ private: | |||
| 1031 | break; | 1047 | break; |
| 1032 | } | 1048 | } |
| 1033 | } | 1049 | } |
| 1034 | if (isPureBackcall(exp)) { | ||
| 1035 | auto expList = assignment->expList.get(); | ||
| 1036 | transformExp(exp, out, ExpUsage::Assignment, expList); | ||
| 1037 | return; | ||
| 1038 | } | ||
| 1039 | BLOCK_END | 1050 | BLOCK_END |
| 1040 | auto info = extractDestructureInfo(assignment); | 1051 | auto info = extractDestructureInfo(assignment); |
| 1041 | if (info.first.empty()) { | 1052 | if (info.first.empty()) { |
| @@ -1707,7 +1718,12 @@ private: | |||
| 1707 | } | 1718 | } |
| 1708 | break; | 1719 | break; |
| 1709 | } | 1720 | } |
| 1710 | case id<VarArg_t>(): out.push_back(s("..."sv)); break; | 1721 | case id<VarArg_t>(): |
| 1722 | if (_varArgs.empty() || !_varArgs.top()) { | ||
| 1723 | throw std::logic_error(_info.errorMessage("cannot use '...' outside a vararg function near '...'"sv, item)); | ||
| 1724 | } | ||
| 1725 | out.push_back(s("..."sv)); | ||
| 1726 | break; | ||
| 1711 | case id<Parens_t>(): transformParens(static_cast<Parens_t*>(item), out); break; | 1727 | case id<Parens_t>(): transformParens(static_cast<Parens_t*>(item), out); break; |
| 1712 | default: assert(false); break; | 1728 | default: assert(false); break; |
| 1713 | } | 1729 | } |
| @@ -1743,7 +1759,8 @@ private: | |||
| 1743 | } | 1759 | } |
| 1744 | 1760 | ||
| 1745 | void transformFunLit(FunLit_t* funLit, str_list& out) { | 1761 | void transformFunLit(FunLit_t* funLit, str_list& out) { |
| 1746 | enableReturn.push(true); | 1762 | _enableReturn.push(true); |
| 1763 | _varArgs.push(false); | ||
| 1747 | str_list temp; | 1764 | str_list temp; |
| 1748 | bool isFatArrow = _parser.toString(funLit->arrow) == "=>"sv; | 1765 | bool isFatArrow = _parser.toString(funLit->arrow) == "=>"sv; |
| 1749 | pushScope(); | 1766 | pushScope(); |
| @@ -1792,7 +1809,8 @@ private: | |||
| 1792 | } | 1809 | } |
| 1793 | } | 1810 | } |
| 1794 | out.push_back(clearBuf()); | 1811 | out.push_back(clearBuf()); |
| 1795 | enableReturn.pop(); | 1812 | _enableReturn.pop(); |
| 1813 | _varArgs.pop(); | ||
| 1796 | } | 1814 | } |
| 1797 | 1815 | ||
| 1798 | void transformBody(Body_t* body, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { | 1816 | void transformBody(Body_t* body, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { |
| @@ -2205,7 +2223,7 @@ private: | |||
| 2205 | } | 2223 | } |
| 2206 | 2224 | ||
| 2207 | void transformReturn(Return_t* returnNode, str_list& out) { | 2225 | void transformReturn(Return_t* returnNode, str_list& out) { |
| 2208 | if (!enableReturn.top()) { | 2226 | if (!_enableReturn.top()) { |
| 2209 | ast_node* target = returnNode->valueList.get(); | 2227 | ast_node* target = returnNode->valueList.get(); |
| 2210 | if (!target) target = returnNode; | 2228 | if (!target) target = returnNode; |
| 2211 | throw std::logic_error(_info.errorMessage("illegal return statement here"sv, target)); | 2229 | throw std::logic_error(_info.errorMessage("illegal return statement here"sv, target)); |
| @@ -2364,6 +2382,7 @@ private: | |||
| 2364 | arg.name = "..."sv; | 2382 | arg.name = "..."sv; |
| 2365 | if (varNames.empty()) varNames = arg.name; | 2383 | if (varNames.empty()) varNames = arg.name; |
| 2366 | else varNames.append(s(", "sv) + arg.name); | 2384 | else varNames.append(s(", "sv) + arg.name); |
| 2385 | _varArgs.top() = true; | ||
| 2367 | } | 2386 | } |
| 2368 | std::string initCodes = join(temp); | 2387 | std::string initCodes = join(temp); |
| 2369 | if (assignSelf) { | 2388 | if (assignSelf) { |
| @@ -4441,7 +4460,7 @@ private: | |||
| 4441 | return; | 4460 | return; |
| 4442 | } | 4461 | } |
| 4443 | str_list temp; | 4462 | str_list temp; |
| 4444 | pushScope(); | 4463 | incIndentOffset(); |
| 4445 | for (auto pair : pairs) { | 4464 | for (auto pair : pairs) { |
| 4446 | switch (pair->getId()) { | 4465 | switch (pair->getId()) { |
| 4447 | case id<Exp_t>(): transformExp(static_cast<Exp_t*>(pair), temp, ExpUsage::Closure); break; | 4466 | case id<Exp_t>(): transformExp(static_cast<Exp_t*>(pair), temp, ExpUsage::Closure); break; |
| @@ -4452,7 +4471,7 @@ private: | |||
| 4452 | temp.back() = indent() + temp.back() + (pair == pairs.back() ? Empty : s(","sv)) + nll(pair); | 4471 | temp.back() = indent() + temp.back() + (pair == pairs.back() ? Empty : s(","sv)) + nll(pair); |
| 4453 | } | 4472 | } |
| 4454 | out.push_back(s("{"sv) + nll(table) + join(temp)); | 4473 | out.push_back(s("{"sv) + nll(table) + join(temp)); |
| 4455 | popScope(); | 4474 | decIndentOffset(); |
| 4456 | out.back() += (indent() + s("}"sv)); | 4475 | out.back() += (indent() + s("}"sv)); |
| 4457 | } | 4476 | } |
| 4458 | 4477 | ||
