diff options
author | Li Jin <dragon-fly@qq.com> | 2020-05-02 14:41:40 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2020-05-02 14:41:40 +0800 |
commit | 6402a8896c78440aee03cc4b7bb315fc236e6ff8 (patch) | |
tree | a5c23153a2285ae4ae79d9b1ff5b64f39f7c379f | |
parent | 5eac89411f056e4e6ad56c9a41944a341780d68b (diff) | |
download | yuescript-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.moon | 26 | ||||
-rw-r--r-- | src/MoonP/moon_ast.h | 10 | ||||
-rw-r--r-- | src/MoonP/moon_compiler.cpp | 35 | ||||
-rw-r--r-- | src/MoonP/moon_parser.cpp | 3 | ||||
-rw-r--r-- | src/MoonP/moon_parser.h | 3 |
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 @@ | |||
1 | import bind from grasp | ||
2 | (bind stmt) color: "Red" | ||
3 | |||
4 | a = 'b' | ||
5 | c = d | ||
6 | (a b) c d | ||
7 | import c from d | ||
8 | (a b) c d | ||
9 | (c d) a b | ||
10 | a, b = c, d | ||
11 | (d a) c | ||
12 | |||
13 | macro block f = (func,arg)-> "(#{func}) #{arg}" | ||
14 | for 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 | ||
25 | nil | ||
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) |
664 | AST_END(unless_line) | 664 | AST_END(unless_line) |
665 | 665 | ||
666 | AST_LEAF(BreakLoop) | ||
667 | AST_END(BreakLoop) | ||
668 | |||
666 | AST_NODE(statement_appendix) | 669 | AST_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) |
669 | AST_END(statement_appendix) | 672 | AST_END(statement_appendix) |
670 | 673 | ||
671 | AST_LEAF(BreakLoop) | 674 | AST_LEAF(statement_sep) |
672 | AST_END(BreakLoop) | 675 | AST_END(statement_sep) |
673 | 676 | ||
674 | AST_NODE(Statement) | 677 | AST_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) | ||
680 | AST_END(Statement) | 684 | AST_END(Statement) |
681 | 685 | ||
682 | class Block_t; | 686 | 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) { | |||
43 | } | 43 | } |
44 | 44 | ||
45 | const std::string_view version() { | 45 | const 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) |