aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2020-03-24 10:19:30 +0800
committerLi Jin <dragon-fly@qq.com>2020-03-24 10:19:30 +0800
commit2447d158241aeaaf9c0b1ab21a08db7a40e5cef3 (patch)
treea8c17610aae77e61ee713b090546e3ae7d35f967
parent14d7e02285857226e26288c1ac83a14eb4fbd478 (diff)
downloadyuescript-2447d158241aeaaf9c0b1ab21a08db7a40e5cef3.tar.gz
yuescript-2447d158241aeaaf9c0b1ab21a08db7a40e5cef3.tar.bz2
yuescript-2447d158241aeaaf9c0b1ab21a08db7a40e5cef3.zip
add goto statement support.
-rw-r--r--README.md2
-rw-r--r--spec/inputs/goto.moon41
-rw-r--r--src/MoonP/moon_ast.h17
-rw-r--r--src/MoonP/moon_compiler.cpp12
-rw-r--r--src/MoonP/moon_parser.cpp33
-rw-r--r--src/MoonP/moon_parser.h3
6 files changed, 96 insertions, 12 deletions
diff --git a/README.md b/README.md
index 319e821..c8159c4 100644
--- a/README.md
+++ b/README.md
@@ -42,6 +42,8 @@ f!
42 42
43The original Moonscript language 0.5.0 support can be found in the `0.5.0` branch. Moonscript with new features is in the master branch. Here are the new features introduced in MoonPlus. 43The original Moonscript language 0.5.0 support can be found in the `0.5.0` branch. Moonscript with new features is in the master branch. Here are the new features introduced in MoonPlus.
44 44
45* Add goto statement support.
46
45* Add macro functions. 47* Add macro functions.
46```Moonscript 48```Moonscript
47-- file 'macro.moon' 49-- file 'macro.moon'
diff --git a/spec/inputs/goto.moon b/spec/inputs/goto.moon
new file mode 100644
index 0000000..3410ca3
--- /dev/null
+++ b/spec/inputs/goto.moon
@@ -0,0 +1,41 @@
1do
2 a = 0
3 ::start::
4 a += 1
5 goto done if a == 5
6 goto start
7 ::done::
8
9do
10 for z = 1, 10 for y = 1, 10 for x = 1, 10
11 if x^2 + y^2 == z^2
12 print 'found a Pythagorean triple:', x, y, z
13 goto done
14 ::done::
15
16do
17 for z = 1, 10
18 for y = 1, 10 for x = 1, 10
19 if x^2 + y^2 == z^2
20 print 'found a Pythagorean triple:', x, y, z
21 print 'now trying next z...'
22 goto zcontinue
23 ::zcontinue::
24
25do
26 ::redo::
27 for x = 1, 10 for y = 1, 10
28 if not f x, y then goto continue
29 if not g x, y then goto skip
30 if not h x, y then goto redo
31 ::continue::
32 ::skip::
33
34do
35 for x in *t
36 if x % 2 == 0
37 print 'list has even number'
38 goto has
39 print 'list lacks even number'
40 ::has::
41
diff --git a/src/MoonP/moon_ast.h b/src/MoonP/moon_ast.h
index 0725bda..3f9ce79 100644
--- a/src/MoonP/moon_ast.h
+++ b/src/MoonP/moon_ast.h
@@ -46,6 +46,11 @@ AST_NODE(Variable)
46 AST_MEMBER(Variable, &name) 46 AST_MEMBER(Variable, &name)
47AST_END(Variable) 47AST_END(Variable)
48 48
49AST_NODE(LabelName)
50 ast_ptr<true, Name_t> name;
51 AST_MEMBER(LabelName, &name)
52AST_END(LabelName)
53
49AST_NODE(LuaKeyword) 54AST_NODE(LuaKeyword)
50 ast_ptr<true, Name_t> name; 55 ast_ptr<true, Name_t> name;
51 AST_MEMBER(LuaKeyword, &name) 56 AST_MEMBER(LuaKeyword, &name)
@@ -142,6 +147,16 @@ AST_NODE(Import)
142 AST_MEMBER(Import, &content) 147 AST_MEMBER(Import, &content)
143AST_END(Import) 148AST_END(Import)
144 149
150AST_NODE(Label)
151 ast_ptr<true, LabelName_t> label;
152 AST_MEMBER(Label, &label)
153AST_END(Label)
154
155AST_NODE(Goto)
156 ast_ptr<true, LabelName_t> label;
157 AST_MEMBER(Goto, &label)
158AST_END(Goto)
159
145class FnArgsDef_t; 160class FnArgsDef_t;
146 161
147AST_LEAF(fn_arrow_back) 162AST_LEAF(fn_arrow_back)
@@ -650,7 +665,7 @@ AST_END(BreakLoop)
650AST_NODE(Statement) 665AST_NODE(Statement)
651 ast_sel<true, Import_t, While_t, For_t, ForEach_t, 666 ast_sel<true, Import_t, While_t, For_t, ForEach_t,
652 Return_t, Local_t, Global_t, Export_t, Macro_t, BreakLoop_t, 667 Return_t, Local_t, Global_t, Export_t, Macro_t, BreakLoop_t,
653 Backcall_t, ExpListAssign_t> content; 668 Label_t, Goto_t, Backcall_t, ExpListAssign_t> content;
654 ast_ptr<false, statement_appendix_t> appendix; 669 ast_ptr<false, statement_appendix_t> appendix;
655 AST_MEMBER(Statement, &content, &appendix) 670 AST_MEMBER(Statement, &content, &appendix)
656AST_END(Statement) 671AST_END(Statement)
diff --git a/src/MoonP/moon_compiler.cpp b/src/MoonP/moon_compiler.cpp
index c176c01..b89f6d1 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* moonScriptVersion() { 45const char* moonScriptVersion() {
46 return "0.5.0-r0.3.4"; 46 return "0.5.0-r0.3.5";
47} 47}
48 48
49// name of table stored in lua registry 49// name of table stored in lua registry
@@ -750,6 +750,8 @@ private:
750 case id<Export_t>(): transformExport(static_cast<Export_t*>(content), out); break; 750 case id<Export_t>(): transformExport(static_cast<Export_t*>(content), out); break;
751 case id<Macro_t>(): transformMacro(static_cast<Macro_t*>(content), out, false); break; 751 case id<Macro_t>(): transformMacro(static_cast<Macro_t*>(content), out, false); break;
752 case id<BreakLoop_t>(): transformBreakLoop(static_cast<BreakLoop_t*>(content), out); break; 752 case id<BreakLoop_t>(): transformBreakLoop(static_cast<BreakLoop_t*>(content), out); break;
753 case id<Label_t>(): transformLabel(static_cast<Label_t*>(content), out); break;
754 case id<Goto_t>(): transformGoto(static_cast<Goto_t*>(content), out); break;
753 case id<ExpListAssign_t>(): { 755 case id<ExpListAssign_t>(): {
754 auto expListAssign = static_cast<ExpListAssign_t*>(content); 756 auto expListAssign = static_cast<ExpListAssign_t*>(content);
755 if (expListAssign->action) { 757 if (expListAssign->action) {
@@ -4997,6 +4999,14 @@ private:
4997 _buf << indent() << "break"sv << nll(breakLoop); 4999 _buf << indent() << "break"sv << nll(breakLoop);
4998 out.push_back(clearBuf()); 5000 out.push_back(clearBuf());
4999 } 5001 }
5002
5003 void transformLabel(Label_t* label, str_list& out) {
5004 out.push_back(indent() + s("::"sv) + _parser.toString(label->label) + s("::"sv) + nll(label));
5005 }
5006
5007 void transformGoto(Goto_t* gotoNode, str_list& out) {
5008 out.push_back(indent() + s("goto "sv) + _parser.toString(gotoNode->label) + nll(gotoNode));
5009 }
5000}; 5010};
5001 5011
5002const std::string MoonCompilerImpl::Empty; 5012const std::string MoonCompilerImpl::Empty;
diff --git a/src/MoonP/moon_parser.cpp b/src/MoonP/moon_parser.cpp
index c8a3a23..872e30e 100644
--- a/src/MoonP/moon_parser.cpp
+++ b/src/MoonP/moon_parser.cpp
@@ -15,18 +15,18 @@ using namespace std::string_view_literals;
15 15
16std::unordered_set<std::string> LuaKeywords = { 16std::unordered_set<std::string> LuaKeywords = {
17 "and", "break", "do", "else", "elseif", 17 "and", "break", "do", "else", "elseif",
18 "end", "false", "for", "function", "if", 18 "end", "false", "for", "function", "goto",
19 "in", "local", "nil", "not", "or", 19 "if", "in", "local", "nil", "not",
20 "repeat", "return", "then", "true", "until", 20 "or", "repeat", "return", "then", "true",
21 "while" 21 "until", "while"
22}; 22};
23 23
24std::unordered_set<std::string> Keywords = { 24std::unordered_set<std::string> Keywords = {
25 "and", "break", "do", "else", "elseif", 25 "and", "break", "do", "else", "elseif",
26 "end", "false", "for", "function", "if", 26 "end", "false", "for", "function", "goto",
27 "in", "local", "nil", "not", "or", 27 "if", "in", "local", "nil", "not",
28 "repeat", "return", "then", "true", "until", 28 "or", "repeat", "return", "then", "true",
29 "while", // Lua keywords 29 "until", "while", // Lua keywords
30 "as", "class", "continue", "export", "extends", 30 "as", "class", "continue", "export", "extends",
31 "from", "global", "import", "macro", "switch", 31 "from", "global", "import", "macro", "switch",
32 "unless", "using", "when", "with" // Moon keywords 32 "unless", "using", "when", "with" // Moon keywords
@@ -85,6 +85,14 @@ MoonParser::MoonParser() {
85 return isValid; 85 return isValid;
86 }); 86 });
87 87
88 LabelName = pl::user(Name, [](const item_t& item) {
89 State* st = reinterpret_cast<State*>(item.user_data);
90 for (auto it = item.begin; it != item.end; ++it) st->buffer += static_cast<char>(*it);
91 auto isValid = LuaKeywords.find(st->buffer) == LuaKeywords.end();
92 st->buffer.clear();
93 return isValid;
94 });
95
88 LuaKeyword = pl::user(Name, [](const item_t& item) { 96 LuaKeyword = pl::user(Name, [](const item_t& item) {
89 State* st = reinterpret_cast<State*>(item.user_data); 97 State* st = reinterpret_cast<State*>(item.user_data);
90 for (auto it = item.begin; it != item.end; ++it) st->buffer += static_cast<char>(*it); 98 for (auto it = item.begin; it != item.end; ++it) st->buffer += static_cast<char>(*it);
@@ -191,9 +199,14 @@ MoonParser::MoonParser() {
191 199
192 Import = key("import") >> (ImportAs | ImportFrom); 200 Import = key("import") >> (ImportAs | ImportFrom);
193 201
202 Label = Space >> expr("::") >> LabelName >> expr("::");
203
204 Goto = key("goto") >> Space >> LabelName;
205
194 BreakLoop = (expr("break") | expr("continue")) >> not_(AlphaNum); 206 BreakLoop = (expr("break") | expr("continue")) >> not_(AlphaNum);
195 207
196 Return = key("return") >> -ExpListLow; 208 Return = key("return") >> -ExpListLow;
209
197 WithExp = ExpList >> -Assign; 210 WithExp = ExpList >> -Assign;
198 211
199 With = key("with") >> DisableDo >> ensure(WithExp, PopDo) >> -key("do") >> Body; 212 With = key("with") >> DisableDo >> ensure(WithExp, PopDo) >> -key("do") >> Body;
@@ -527,8 +540,8 @@ MoonParser::MoonParser() {
527 Statement = ( 540 Statement = (
528 Import | While | For | ForEach | 541 Import | While | For | ForEach |
529 Return | Local | Global | Export | 542 Return | Local | Global | Export |
530 Macro | Space >> BreakLoop | 543 Macro | Space >> BreakLoop | Label |
531 Backcall | ExpListAssign 544 Goto | Backcall | ExpListAssign
532 ) >> Space >> 545 ) >> Space >>
533 -statement_appendix; 546 -statement_appendix;
534 547
diff --git a/src/MoonP/moon_parser.h b/src/MoonP/moon_parser.h
index 4d67696..cea14fa 100644
--- a/src/MoonP/moon_parser.h
+++ b/src/MoonP/moon_parser.h
@@ -182,6 +182,7 @@ private:
182 AST_RULE(Num) 182 AST_RULE(Num)
183 AST_RULE(Name) 183 AST_RULE(Name)
184 AST_RULE(Variable) 184 AST_RULE(Variable)
185 AST_RULE(LabelName)
185 AST_RULE(LuaKeyword) 186 AST_RULE(LuaKeyword)
186 AST_RULE(self) 187 AST_RULE(self)
187 AST_RULE(self_name) 188 AST_RULE(self_name)
@@ -201,6 +202,8 @@ private:
201 AST_RULE(ImportFrom) 202 AST_RULE(ImportFrom)
202 AST_RULE(ImportAs) 203 AST_RULE(ImportAs)
203 AST_RULE(Import) 204 AST_RULE(Import)
205 AST_RULE(Label)
206 AST_RULE(Goto)
204 AST_RULE(fn_arrow_back) 207 AST_RULE(fn_arrow_back)
205 AST_RULE(Backcall) 208 AST_RULE(Backcall)
206 AST_RULE(ExpListLow) 209 AST_RULE(ExpListLow)