From 6402a8896c78440aee03cc4b7bb315fc236e6ff8 Mon Sep 17 00:00:00 2001 From: Li Jin Date: Sat, 2 May 2020 14:41:40 +0800 Subject: fix Moonscript issue 416: ambiguous Lua output in some cases. --- spec/inputs/ambiguous.moon | 26 ++++++++++++++++++++++++++ src/MoonP/moon_ast.h | 10 +++++++--- src/MoonP/moon_compiler.cpp | 35 +++++++++++++++++++++++++++++++++-- src/MoonP/moon_parser.cpp | 3 ++- src/MoonP/moon_parser.h | 3 ++- 5 files changed, 70 insertions(+), 7 deletions(-) create mode 100644 spec/inputs/ambiguous.moon diff --git a/spec/inputs/ambiguous.moon b/spec/inputs/ambiguous.moon new file mode 100644 index 0000000..a5980db --- /dev/null +++ b/spec/inputs/ambiguous.moon @@ -0,0 +1,26 @@ +import bind from grasp +(bind stmt) color: "Red" + +a = 'b' +c = d +(a b) c d +import c from d +(a b) c d +(c d) a b +a, b = c, d +(d a) c + +macro block f = (func,arg)-> "(#{func}) #{arg}" +for i = 1, 10 + a = -> + $f print, 1 + a = f + $f print, 2 + if cond + $f print, 3 + ::abc:: + (print) 4 + goto abc + (print) 5 +nil + diff --git a/src/MoonP/moon_ast.h b/src/MoonP/moon_ast.h index dd11ac4..4918a0a 100644 --- a/src/MoonP/moon_ast.h +++ b/src/MoonP/moon_ast.h @@ -663,20 +663,24 @@ AST_NODE(unless_line) AST_MEMBER(unless_line, &condition) AST_END(unless_line) +AST_LEAF(BreakLoop) +AST_END(BreakLoop) + AST_NODE(statement_appendix) ast_sel item; AST_MEMBER(statement_appendix, &item) AST_END(statement_appendix) -AST_LEAF(BreakLoop) -AST_END(BreakLoop) +AST_LEAF(statement_sep) +AST_END(statement_sep) AST_NODE(Statement) ast_sel content; ast_ptr appendix; - AST_MEMBER(Statement, &content, &appendix) + ast_ptr needSep; + AST_MEMBER(Statement, &content, &appendix, &needSep) AST_END(Statement) class Block_t; diff --git a/src/MoonP/moon_compiler.cpp b/src/MoonP/moon_compiler.cpp index f79df07..6d07e9e 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 std::string_view version() { - return "0.3.11"sv; + return "0.3.12"sv; } // name of table stored in lua registry @@ -802,6 +802,25 @@ private: } default: assert(false); break; } + if (statement->needSep && !out.back().empty()) { + auto index = std::string::npos; + if (_config.reserveLineNumber) { + index = out.back().rfind(" -- "sv); + } else { + index = out.back().find_last_not_of('\n'); + if (index != std::string::npos) index++; + } + if (index != std::string::npos) { + auto ending = out.back().substr(0, index); + auto ind = ending.find_last_of(" \t\n"sv); + if (ind != std::string::npos) { + ending = ending.substr(ind + 1); + } + if (Keywords.find(ending) == Keywords.end()) { + out.back().insert(index, ";"sv); + } + } + } } str_list getAssignVars(ExpListAssign_t* assignment) { @@ -2016,6 +2035,11 @@ private: returnNode->valueList.set(expListLow); returnNode->allowBlockMacroReturn = true; last->content.set(returnNode); + last->needSep.set(nullptr); + auto bLast = ++nodes.rbegin(); + if (bLast != nodes.rend()) { + static_cast(*bLast)->needSep.set(nullptr); + } BLOCK_END break; } @@ -2041,6 +2065,11 @@ private: } newAssignment->action.set(assign); last->content.set(newAssignment); + last->needSep.set(nullptr); + auto bLast = ++nodes.rbegin(); + if (bLast != nodes.rend()) { + static_cast(*bLast)->needSep.set(nullptr); + } } break; } @@ -4029,7 +4058,9 @@ private: _buf << indent(1) << "end"sv << nll(classDecl); _buf << indent() << "})"sv << nll(classDecl); _buf << indent() << baseVar << ".__class = "sv << classVar << nll(classDecl); - if (!statements.empty()) _buf << indent() << "local self = "sv << classVar << nll(classDecl); + if (!statements.empty()) { + _buf << indent() << "local self = "sv << classVar << ';' << nll(classDecl); + } _buf << join(statements); if (extend) { _buf << indent() << "if "sv << parentVar << ".__inherited then"sv << nll(classDecl); diff --git a/src/MoonP/moon_parser.cpp b/src/MoonP/moon_parser.cpp index 4f12a34..5b537a1 100644 --- a/src/MoonP/moon_parser.cpp +++ b/src/MoonP/moon_parser.cpp @@ -538,12 +538,13 @@ MoonParser::MoonParser() { unless_line = key("unless") >> Exp; statement_appendix = (if_line | unless_line | CompInner) >> Space; + statement_sep = and_(*SpaceBreak >> CheckIndent >> Space >> (set("($'\"") | expr("[[") | expr("[="))); Statement = ( Import | While | Repeat | For | ForEach | Return | Local | Global | Export | Macro | Space >> BreakLoop | Label | Goto | Backcall | ExpListAssign ) >> Space >> - -statement_appendix; + -statement_appendix >> -statement_sep; Body = Space >> Break >> *EmptyLine >> InBlock | Statement; diff --git a/src/MoonP/moon_parser.h b/src/MoonP/moon_parser.h index 1f9caf8..00bbcd5 100644 --- a/src/MoonP/moon_parser.h +++ b/src/MoonP/moon_parser.h @@ -289,8 +289,9 @@ private: AST_RULE(ExpListAssign) AST_RULE(if_line) AST_RULE(unless_line) - AST_RULE(statement_appendix) AST_RULE(BreakLoop) + AST_RULE(statement_appendix) + AST_RULE(statement_sep) AST_RULE(Statement) AST_RULE(Body) AST_RULE(Block) -- cgit v1.2.3-55-g6feb