diff options
| author | Li Jin <dragon-fly@qq.com> | 2020-03-30 11:29:13 +0800 |
|---|---|---|
| committer | Li Jin <dragon-fly@qq.com> | 2020-03-30 11:29:13 +0800 |
| commit | 1c4c3159374a5c4b08a06ca8e3e7f49442edd59c (patch) | |
| tree | 735dd2dc501e8f32d89bef3a76d826c73ffafdf7 | |
| parent | 147893cdbf00d40ebda6b7840d3734ccda294347 (diff) | |
| download | yuescript-1c4c3159374a5c4b08a06ca8e3e7f49442edd59c.tar.gz yuescript-1c4c3159374a5c4b08a06ca8e3e7f49442edd59c.tar.bz2 yuescript-1c4c3159374a5c4b08a06ca8e3e7f49442edd59c.zip | |
add useSpaceOverTab option for compiler, add variadic arguments declaration check, fix assignment with backcall expr not well handled issue.
| -rw-r--r-- | spec/inputs/bubbling.moon | 15 | ||||
| -rw-r--r-- | spec/inputs/stub.moon | 4 | ||||
| -rw-r--r-- | spec/inputs/syntax.moon | 2 | ||||
| -rw-r--r-- | src/MoonP/moon_compiler.cpp | 53 | ||||
| -rw-r--r-- | src/MoonP/moon_compiler.h | 1 | ||||
| -rw-r--r-- | src/MoonP/moonplus.cpp | 6 | ||||
| -rw-r--r-- | src/moonp.cpp | 10 |
7 files changed, 64 insertions, 27 deletions
diff --git a/spec/inputs/bubbling.moon b/spec/inputs/bubbling.moon index 62d1550..23a85d4 100644 --- a/spec/inputs/bubbling.moon +++ b/spec/inputs/bubbling.moon | |||
| @@ -15,14 +15,13 @@ j = for i=1,10 | |||
| 15 | m = (...) -> | 15 | m = (...) -> |
| 16 | [x for x in *{...} when f(...) > 4] | 16 | [x for x in *{...} when f(...) > 4] |
| 17 | 17 | ||
| 18 | x = for i in *{...} do i | 18 | _ = (...)-> |
| 19 | y = [x for x in *{...}] | 19 | x = for i in *{...} do i |
| 20 | z = [x for x in hallo when f(...) > 4] | 20 | y = [x for x in *{...}] |
| 21 | z = [x for x in hallo when f(...) > 4] | ||
| 21 | 22 | ||
| 23 | a = for i=1,10 do ... | ||
| 22 | 24 | ||
| 23 | a = for i=1,10 do ... | 25 | b = for i=1,10 |
| 24 | 26 | (...)-> print ... | |
| 25 | b = for i=1,10 | ||
| 26 | -> print ... | ||
| 27 | |||
| 28 | 27 | ||
diff --git a/spec/inputs/stub.moon b/spec/inputs/stub.moon index b38056a..60347e7 100644 --- a/spec/inputs/stub.moon +++ b/spec/inputs/stub.moon | |||
| @@ -12,5 +12,7 @@ print x\val! | |||
| 12 | 12 | ||
| 13 | 13 | ||
| 14 | -- ... should be bubbled up anon functions | 14 | -- ... should be bubbled up anon functions |
| 15 | x = hello(...)\world | 15 | ((...)-> x = hello(...)\world)! |
| 16 | |||
| 17 | nil | ||
| 16 | 18 | ||
diff --git a/spec/inputs/syntax.moon b/spec/inputs/syntax.moon index b5f973b..23b44ce 100644 --- a/spec/inputs/syntax.moon +++ b/spec/inputs/syntax.moon | |||
| @@ -124,7 +124,7 @@ if hello then _ = 343 | |||
| 124 | 124 | ||
| 125 | print "what" if cool | 125 | print "what" if cool |
| 126 | 126 | ||
| 127 | arg = {...} | 127 | ((...)-> arg = {...})! |
| 128 | 128 | ||
| 129 | x = (...) -> | 129 | x = (...) -> |
| 130 | dump {...} | 130 | dump {...} |
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 | ||
diff --git a/src/MoonP/moon_compiler.h b/src/MoonP/moon_compiler.h index d22a95a..540f9e7 100644 --- a/src/MoonP/moon_compiler.h +++ b/src/MoonP/moon_compiler.h | |||
| @@ -23,6 +23,7 @@ struct MoonConfig { | |||
| 23 | bool lintGlobalVariable = false; | 23 | bool lintGlobalVariable = false; |
| 24 | bool implicitReturnRoot = true; | 24 | bool implicitReturnRoot = true; |
| 25 | bool reserveLineNumber = true; | 25 | bool reserveLineNumber = true; |
| 26 | bool useSpaceOverTab = false; | ||
| 26 | int lineOffset = 0; | 27 | int lineOffset = 0; |
| 27 | }; | 28 | }; |
| 28 | 29 | ||
diff --git a/src/MoonP/moonplus.cpp b/src/MoonP/moonplus.cpp index d6352f5..cb6d3ec 100644 --- a/src/MoonP/moonplus.cpp +++ b/src/MoonP/moonplus.cpp | |||
| @@ -64,6 +64,12 @@ static int moontolua(lua_State* L) { | |||
| 64 | config.reserveLineNumber = lua_toboolean(L, -1) != 0; | 64 | config.reserveLineNumber = lua_toboolean(L, -1) != 0; |
| 65 | } | 65 | } |
| 66 | lua_pop(L, 1); | 66 | lua_pop(L, 1); |
| 67 | lua_pushliteral(L, "space_over_tab"); | ||
| 68 | lua_gettable(L, -2); | ||
| 69 | if (lua_isboolean(L, -1) != 0) { | ||
| 70 | config.useSpaceOverTab = lua_toboolean(L, -1) != 0; | ||
| 71 | } | ||
| 72 | lua_pop(L, 1); | ||
| 67 | lua_pushliteral(L, "same_module"); | 73 | lua_pushliteral(L, "same_module"); |
| 68 | lua_gettable(L, -2); | 74 | lua_gettable(L, -2); |
| 69 | if (lua_isboolean(L, -1) != 0) { | 75 | if (lua_isboolean(L, -1) != 0) { |
diff --git a/src/moonp.cpp b/src/moonp.cpp index ca5265f..7410994 100644 --- a/src/moonp.cpp +++ b/src/moonp.cpp | |||
| @@ -63,6 +63,9 @@ void pushOptions(lua_State* L, int lineOffset) { | |||
| 63 | lua_pushliteral(L, "reserve_line_number"); | 63 | lua_pushliteral(L, "reserve_line_number"); |
| 64 | lua_pushboolean(L, 1); | 64 | lua_pushboolean(L, 1); |
| 65 | lua_rawset(L, -3); | 65 | lua_rawset(L, -3); |
| 66 | lua_pushliteral(L, "space_over_tab"); | ||
| 67 | lua_pushboolean(L, 0); | ||
| 68 | lua_rawset(L, -3); | ||
| 66 | lua_pushliteral(L, "same_module"); | 69 | lua_pushliteral(L, "same_module"); |
| 67 | lua_pushboolean(L, 1); | 70 | lua_pushboolean(L, 1); |
| 68 | lua_rawset(L, -3); | 71 | lua_rawset(L, -3); |
| @@ -78,6 +81,7 @@ int main(int narg, const char** args) { | |||
| 78 | " -e str Execute a file or raw codes\n" | 81 | " -e str Execute a file or raw codes\n" |
| 79 | " -t path Specify where to place compiled files\n" | 82 | " -t path Specify where to place compiled files\n" |
| 80 | " -o file Write output to file\n" | 83 | " -o file Write output to file\n" |
| 84 | " -s Use space in generated codes instead of tabs\n" | ||
| 81 | " -p Write output to standard out\n" | 85 | " -p Write output to standard out\n" |
| 82 | " -b Dump compile time (doesn't write output)\n" | 86 | " -b Dump compile time (doesn't write output)\n" |
| 83 | " -l Write line numbers from source codes\n" | 87 | " -l Write line numbers from source codes\n" |
| @@ -220,7 +224,10 @@ int main(int narg, const char** args) { | |||
| 220 | return 0; | 224 | return 0; |
| 221 | } | 225 | } |
| 222 | MoonP::MoonConfig config; | 226 | MoonP::MoonConfig config; |
| 227 | config.implicitReturnRoot = true; | ||
| 228 | config.lintGlobalVariable = false; | ||
| 223 | config.reserveLineNumber = false; | 229 | config.reserveLineNumber = false; |
| 230 | config.useSpaceOverTab = false; | ||
| 224 | bool writeToFile = true; | 231 | bool writeToFile = true; |
| 225 | bool dumpCompileTime = false; | 232 | bool dumpCompileTime = false; |
| 226 | std::string targetPath; | 233 | std::string targetPath; |
| @@ -242,6 +249,7 @@ int main(int narg, const char** args) { | |||
| 242 | conf.implicitReturnRoot = true; | 249 | conf.implicitReturnRoot = true; |
| 243 | conf.lintGlobalVariable = false; | 250 | conf.lintGlobalVariable = false; |
| 244 | conf.reserveLineNumber = false; | 251 | conf.reserveLineNumber = false; |
| 252 | conf.useSpaceOverTab = true; | ||
| 245 | auto result = MoonP::MoonCompiler{nullptr, openlibs}.compile(codes, conf); | 253 | auto result = MoonP::MoonCompiler{nullptr, openlibs}.compile(codes, conf); |
| 246 | if (std::get<1>(result).empty()) { | 254 | if (std::get<1>(result).empty()) { |
| 247 | std::cout << std::get<0>(result); | 255 | std::cout << std::get<0>(result); |
| @@ -307,6 +315,8 @@ int main(int narg, const char** args) { | |||
| 307 | std::cout << help; | 315 | std::cout << help; |
| 308 | return 1; | 316 | return 1; |
| 309 | } | 317 | } |
| 318 | } else if (arg == "-s"sv) { | ||
| 319 | config.useSpaceOverTab = true; | ||
| 310 | } else if (arg == "-l"sv) { | 320 | } else if (arg == "-l"sv) { |
| 311 | config.reserveLineNumber = true; | 321 | config.reserveLineNumber = true; |
| 312 | } else if (arg == "-p"sv) { | 322 | } else if (arg == "-p"sv) { |
