aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2020-05-02 14:41:40 +0800
committerLi Jin <dragon-fly@qq.com>2020-05-02 14:41:40 +0800
commit6402a8896c78440aee03cc4b7bb315fc236e6ff8 (patch)
treea5c23153a2285ae4ae79d9b1ff5b64f39f7c379f
parent5eac89411f056e4e6ad56c9a41944a341780d68b (diff)
downloadyuescript-6402a8896c78440aee03cc4b7bb315fc236e6ff8.tar.gz
yuescript-6402a8896c78440aee03cc4b7bb315fc236e6ff8.tar.bz2
yuescript-6402a8896c78440aee03cc4b7bb315fc236e6ff8.zip
fix Moonscript issue 416: ambiguous Lua output in some cases.
-rw-r--r--spec/inputs/ambiguous.moon26
-rw-r--r--src/MoonP/moon_ast.h10
-rw-r--r--src/MoonP/moon_compiler.cpp35
-rw-r--r--src/MoonP/moon_parser.cpp3
-rw-r--r--src/MoonP/moon_parser.h3
5 files changed, 70 insertions, 7 deletions
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 @@
1import bind from grasp
2(bind stmt) color: "Red"
3
4a = 'b'
5c = d
6(a b) c d
7import c from d
8(a b) c d
9(c d) a b
10a, b = c, d
11(d a) c
12
13macro block f = (func,arg)-> "(#{func}) #{arg}"
14for i = 1, 10
15 a = ->
16 $f print, 1
17 a = f
18 $f print, 2
19 if cond
20 $f print, 3
21 ::abc::
22 (print) 4
23 goto abc
24 (print) 5
25nil
26
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)
663 AST_MEMBER(unless_line, &condition) 663 AST_MEMBER(unless_line, &condition)
664AST_END(unless_line) 664AST_END(unless_line)
665 665
666AST_LEAF(BreakLoop)
667AST_END(BreakLoop)
668
666AST_NODE(statement_appendix) 669AST_NODE(statement_appendix)
667 ast_sel<true, if_line_t, unless_line_t, CompInner_t> item; 670 ast_sel<true, if_line_t, unless_line_t, CompInner_t> item;
668 AST_MEMBER(statement_appendix, &item) 671 AST_MEMBER(statement_appendix, &item)
669AST_END(statement_appendix) 672AST_END(statement_appendix)
670 673
671AST_LEAF(BreakLoop) 674AST_LEAF(statement_sep)
672AST_END(BreakLoop) 675AST_END(statement_sep)
673 676
674AST_NODE(Statement) 677AST_NODE(Statement)
675 ast_sel<true, Import_t, While_t, Repeat_t, For_t, ForEach_t, 678 ast_sel<true, Import_t, While_t, Repeat_t, For_t, ForEach_t,
676 Return_t, Local_t, Global_t, Export_t, Macro_t, BreakLoop_t, 679 Return_t, Local_t, Global_t, Export_t, Macro_t, BreakLoop_t,
677 Label_t, Goto_t, Backcall_t, ExpListAssign_t> content; 680 Label_t, Goto_t, Backcall_t, ExpListAssign_t> content;
678 ast_ptr<false, statement_appendix_t> appendix; 681 ast_ptr<false, statement_appendix_t> appendix;
679 AST_MEMBER(Statement, &content, &appendix) 682 ast_ptr<false, statement_sep_t> needSep;
683 AST_MEMBER(Statement, &content, &appendix, &needSep)
680AST_END(Statement) 684AST_END(Statement)
681 685
682class Block_t; 686class 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) {
43} 43}
44 44
45const std::string_view version() { 45const std::string_view version() {
46 return "0.3.11"sv; 46 return "0.3.12"sv;
47} 47}
48 48
49// name of table stored in lua registry 49// name of table stored in lua registry
@@ -802,6 +802,25 @@ private:
802 } 802 }
803 default: assert(false); break; 803 default: assert(false); break;
804 } 804 }
805 if (statement->needSep && !out.back().empty()) {
806 auto index = std::string::npos;
807 if (_config.reserveLineNumber) {
808 index = out.back().rfind(" -- "sv);
809 } else {
810 index = out.back().find_last_not_of('\n');
811 if (index != std::string::npos) index++;
812 }
813 if (index != std::string::npos) {
814 auto ending = out.back().substr(0, index);
815 auto ind = ending.find_last_of(" \t\n"sv);
816 if (ind != std::string::npos) {
817 ending = ending.substr(ind + 1);
818 }
819 if (Keywords.find(ending) == Keywords.end()) {
820 out.back().insert(index, ";"sv);
821 }
822 }
823 }
805 } 824 }
806 825
807 str_list getAssignVars(ExpListAssign_t* assignment) { 826 str_list getAssignVars(ExpListAssign_t* assignment) {
@@ -2016,6 +2035,11 @@ private:
2016 returnNode->valueList.set(expListLow); 2035 returnNode->valueList.set(expListLow);
2017 returnNode->allowBlockMacroReturn = true; 2036 returnNode->allowBlockMacroReturn = true;
2018 last->content.set(returnNode); 2037 last->content.set(returnNode);
2038 last->needSep.set(nullptr);
2039 auto bLast = ++nodes.rbegin();
2040 if (bLast != nodes.rend()) {
2041 static_cast<Statement_t*>(*bLast)->needSep.set(nullptr);
2042 }
2019 BLOCK_END 2043 BLOCK_END
2020 break; 2044 break;
2021 } 2045 }
@@ -2041,6 +2065,11 @@ private:
2041 } 2065 }
2042 newAssignment->action.set(assign); 2066 newAssignment->action.set(assign);
2043 last->content.set(newAssignment); 2067 last->content.set(newAssignment);
2068 last->needSep.set(nullptr);
2069 auto bLast = ++nodes.rbegin();
2070 if (bLast != nodes.rend()) {
2071 static_cast<Statement_t*>(*bLast)->needSep.set(nullptr);
2072 }
2044 } 2073 }
2045 break; 2074 break;
2046 } 2075 }
@@ -4029,7 +4058,9 @@ private:
4029 _buf << indent(1) << "end"sv << nll(classDecl); 4058 _buf << indent(1) << "end"sv << nll(classDecl);
4030 _buf << indent() << "})"sv << nll(classDecl); 4059 _buf << indent() << "})"sv << nll(classDecl);
4031 _buf << indent() << baseVar << ".__class = "sv << classVar << nll(classDecl); 4060 _buf << indent() << baseVar << ".__class = "sv << classVar << nll(classDecl);
4032 if (!statements.empty()) _buf << indent() << "local self = "sv << classVar << nll(classDecl); 4061 if (!statements.empty()) {
4062 _buf << indent() << "local self = "sv << classVar << ';' << nll(classDecl);
4063 }
4033 _buf << join(statements); 4064 _buf << join(statements);
4034 if (extend) { 4065 if (extend) {
4035 _buf << indent() << "if "sv << parentVar << ".__inherited then"sv << nll(classDecl); 4066 _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() {
538 unless_line = key("unless") >> Exp; 538 unless_line = key("unless") >> Exp;
539 539
540 statement_appendix = (if_line | unless_line | CompInner) >> Space; 540 statement_appendix = (if_line | unless_line | CompInner) >> Space;
541 statement_sep = and_(*SpaceBreak >> CheckIndent >> Space >> (set("($'\"") | expr("[[") | expr("[=")));
541 Statement = ( 542 Statement = (
542 Import | While | Repeat | For | ForEach | 543 Import | While | Repeat | For | ForEach |
543 Return | Local | Global | Export | Macro | 544 Return | Local | Global | Export | Macro |
544 Space >> BreakLoop | Label | Goto | Backcall | ExpListAssign 545 Space >> BreakLoop | Label | Goto | Backcall | ExpListAssign
545 ) >> Space >> 546 ) >> Space >>
546 -statement_appendix; 547 -statement_appendix >> -statement_sep;
547 548
548 Body = Space >> Break >> *EmptyLine >> InBlock | Statement; 549 Body = Space >> Break >> *EmptyLine >> InBlock | Statement;
549 550
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:
289 AST_RULE(ExpListAssign) 289 AST_RULE(ExpListAssign)
290 AST_RULE(if_line) 290 AST_RULE(if_line)
291 AST_RULE(unless_line) 291 AST_RULE(unless_line)
292 AST_RULE(statement_appendix)
293 AST_RULE(BreakLoop) 292 AST_RULE(BreakLoop)
293 AST_RULE(statement_appendix)
294 AST_RULE(statement_sep)
294 AST_RULE(Statement) 295 AST_RULE(Statement)
295 AST_RULE(Body) 296 AST_RULE(Body)
296 AST_RULE(Block) 297 AST_RULE(Block)