diff options
-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) { |