aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--spec/inputs/bubbling.moon15
-rw-r--r--spec/inputs/stub.moon4
-rw-r--r--spec/inputs/syntax.moon2
-rw-r--r--src/MoonP/moon_compiler.cpp53
-rw-r--r--src/MoonP/moon_compiler.h1
-rw-r--r--src/MoonP/moonplus.cpp6
-rw-r--r--src/moonp.cpp10
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
15m = (...) -> 15m = (...) ->
16 [x for x in *{...} when f(...) > 4] 16 [x for x in *{...} when f(...) > 4]
17 17
18x = for i in *{...} do i 18_ = (...)->
19y = [x for x in *{...}] 19 x = for i in *{...} do i
20z = [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
23a = for i=1,10 do ... 25 b = for i=1,10
24 26 (...)-> print ...
25b = 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
15x = hello(...)\world 15((...)-> x = hello(...)\world)!
16
17nil
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
125print "what" if cool 125print "what" if cool
126 126
127arg = {...} 127((...)-> arg = {...})!
128 128
129x = (...) -> 129x = (...) ->
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
45const char* version() { 45const 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) {