From 1c4c3159374a5c4b08a06ca8e3e7f49442edd59c Mon Sep 17 00:00:00 2001 From: Li Jin Date: Mon, 30 Mar 2020 11:29:13 +0800 Subject: add useSpaceOverTab option for compiler, add variadic arguments declaration check, fix assignment with backcall expr not well handled issue. --- src/MoonP/moon_compiler.cpp | 53 ++++++++++++++++++++++++++++++--------------- src/MoonP/moon_compiler.h | 1 + src/MoonP/moonplus.cpp | 6 +++++ src/moonp.cpp | 10 +++++++++ 4 files changed, 53 insertions(+), 17 deletions(-) (limited to 'src') 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) { } const char* version() { - return "0.3.7"; + return "0.3.8"; } // name of table stored in lua registry @@ -89,7 +89,7 @@ public: try { str_list out; pushScope(); - enableReturn.push(_info.moduleName.empty()); + _enableReturn.push(_info.moduleName.empty()); transformBlock(_info.node.to()->block, out, config.implicitReturnRoot ? ExpUsage::Return : ExpUsage::Common, nullptr, true); @@ -121,8 +121,10 @@ public: _joinBuf.clear(); _globals.clear(); _info = {}; + _varArgs = {}; _withVars = {}; _continueVars = {}; + _enableReturn = {}; if (_useModule) { _useModule = false; if (!_sameModule) { @@ -144,10 +146,11 @@ private: MoonParser _parser; ParseInfo _info; int _indentOffset = 0; - std::stack enableReturn; - std::list> _codeCache; + std::stack _varArgs; + std::stack _enableReturn; std::stack _withVars; std::stack _continueVars; + std::list> _codeCache; std::unordered_map> _globals; std::ostringstream _buf; std::ostringstream _joinBuf; @@ -335,11 +338,19 @@ private: } std::string indent() const { - return std::string(_scopes.size() - 1 + _indentOffset, '\t'); + if (_config.useSpaceOverTab) { + return std::string((_scopes.size() - 1 + _indentOffset) * 2, ' '); + } else { + return std::string(_scopes.size() - 1 + _indentOffset, '\t'); + } } std::string indent(int offset) const { - return std::string(_scopes.size() - 1 + _indentOffset + offset, '\t'); + if (_config.useSpaceOverTab) { + return std::string((_scopes.size() - 1 + _indentOffset + offset) * 2, ' '); + } else { + return std::string(_scopes.size() - 1 + _indentOffset + offset, '\t'); + } } std::string clearBuf() { @@ -1010,6 +1021,11 @@ private: } auto exp = ast_cast(value); BREAK_IF(!exp); + if (isPureBackcall(exp)) { + auto expList = assignment->expList.get(); + transformExp(exp, out, ExpUsage::Assignment, expList); + return; + } BREAK_IF(!exp->opValues.empty()); if (auto chainValue = exp->value->item.as()) { auto type = specialChainValue(chainValue); @@ -1031,11 +1047,6 @@ private: break; } } - if (isPureBackcall(exp)) { - auto expList = assignment->expList.get(); - transformExp(exp, out, ExpUsage::Assignment, expList); - return; - } BLOCK_END auto info = extractDestructureInfo(assignment); if (info.first.empty()) { @@ -1707,7 +1718,12 @@ private: } break; } - case id(): out.push_back(s("..."sv)); break; + case id(): + if (_varArgs.empty() || !_varArgs.top()) { + throw std::logic_error(_info.errorMessage("cannot use '...' outside a vararg function near '...'"sv, item)); + } + out.push_back(s("..."sv)); + break; case id(): transformParens(static_cast(item), out); break; default: assert(false); break; } @@ -1743,7 +1759,8 @@ private: } void transformFunLit(FunLit_t* funLit, str_list& out) { - enableReturn.push(true); + _enableReturn.push(true); + _varArgs.push(false); str_list temp; bool isFatArrow = _parser.toString(funLit->arrow) == "=>"sv; pushScope(); @@ -1792,7 +1809,8 @@ private: } } out.push_back(clearBuf()); - enableReturn.pop(); + _enableReturn.pop(); + _varArgs.pop(); } void transformBody(Body_t* body, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { @@ -2205,7 +2223,7 @@ private: } void transformReturn(Return_t* returnNode, str_list& out) { - if (!enableReturn.top()) { + if (!_enableReturn.top()) { ast_node* target = returnNode->valueList.get(); if (!target) target = returnNode; throw std::logic_error(_info.errorMessage("illegal return statement here"sv, target)); @@ -2364,6 +2382,7 @@ private: arg.name = "..."sv; if (varNames.empty()) varNames = arg.name; else varNames.append(s(", "sv) + arg.name); + _varArgs.top() = true; } std::string initCodes = join(temp); if (assignSelf) { @@ -4441,7 +4460,7 @@ private: return; } str_list temp; - pushScope(); + incIndentOffset(); for (auto pair : pairs) { switch (pair->getId()) { case id(): transformExp(static_cast(pair), temp, ExpUsage::Closure); break; @@ -4452,7 +4471,7 @@ private: temp.back() = indent() + temp.back() + (pair == pairs.back() ? Empty : s(","sv)) + nll(pair); } out.push_back(s("{"sv) + nll(table) + join(temp)); - popScope(); + decIndentOffset(); out.back() += (indent() + s("}"sv)); } 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 { bool lintGlobalVariable = false; bool implicitReturnRoot = true; bool reserveLineNumber = true; + bool useSpaceOverTab = false; int lineOffset = 0; }; 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) { config.reserveLineNumber = lua_toboolean(L, -1) != 0; } lua_pop(L, 1); + lua_pushliteral(L, "space_over_tab"); + lua_gettable(L, -2); + if (lua_isboolean(L, -1) != 0) { + config.useSpaceOverTab = lua_toboolean(L, -1) != 0; + } + lua_pop(L, 1); lua_pushliteral(L, "same_module"); lua_gettable(L, -2); 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) { lua_pushliteral(L, "reserve_line_number"); lua_pushboolean(L, 1); lua_rawset(L, -3); + lua_pushliteral(L, "space_over_tab"); + lua_pushboolean(L, 0); + lua_rawset(L, -3); lua_pushliteral(L, "same_module"); lua_pushboolean(L, 1); lua_rawset(L, -3); @@ -78,6 +81,7 @@ int main(int narg, const char** args) { " -e str Execute a file or raw codes\n" " -t path Specify where to place compiled files\n" " -o file Write output to file\n" +" -s Use space in generated codes instead of tabs\n" " -p Write output to standard out\n" " -b Dump compile time (doesn't write output)\n" " -l Write line numbers from source codes\n" @@ -220,7 +224,10 @@ int main(int narg, const char** args) { return 0; } MoonP::MoonConfig config; + config.implicitReturnRoot = true; + config.lintGlobalVariable = false; config.reserveLineNumber = false; + config.useSpaceOverTab = false; bool writeToFile = true; bool dumpCompileTime = false; std::string targetPath; @@ -242,6 +249,7 @@ int main(int narg, const char** args) { conf.implicitReturnRoot = true; conf.lintGlobalVariable = false; conf.reserveLineNumber = false; + conf.useSpaceOverTab = true; auto result = MoonP::MoonCompiler{nullptr, openlibs}.compile(codes, conf); if (std::get<1>(result).empty()) { std::cout << std::get<0>(result); @@ -307,6 +315,8 @@ int main(int narg, const char** args) { std::cout << help; return 1; } + } else if (arg == "-s"sv) { + config.useSpaceOverTab = true; } else if (arg == "-l"sv) { config.reserveLineNumber = true; } else if (arg == "-p"sv) { -- cgit v1.2.3-55-g6feb