diff options
-rw-r--r-- | spec/inputs/existential.moon | 4 | ||||
-rw-r--r-- | spec/inputs/loops.moon | 9 | ||||
-rw-r--r-- | src/MoonP/moon_ast.h | 12 | ||||
-rw-r--r-- | src/MoonP/moon_compiler.cpp | 26 | ||||
-rw-r--r-- | src/MoonP/moon_parser.cpp | 10 | ||||
-rw-r--r-- | src/MoonP/moon_parser.h | 1 |
6 files changed, 52 insertions, 10 deletions
diff --git a/spec/inputs/existential.moon b/spec/inputs/existential.moon index 7ee3bde..3055705 100644 --- a/spec/inputs/existential.moon +++ b/spec/inputs/existential.moon | |||
@@ -45,3 +45,7 @@ a = tb1?\end? 123 + tb2?\then 456 | |||
45 | 45 | ||
46 | b = tb1?\end? or tb2?\then | 46 | b = tb1?\end? or tb2?\then |
47 | 47 | ||
48 | with? io.open "test.txt", "w" | ||
49 | \write "hello" | ||
50 | \close! | ||
51 | |||
diff --git a/spec/inputs/loops.moon b/spec/inputs/loops.moon index 35427f6..24d960f 100644 --- a/spec/inputs/loops.moon +++ b/spec/inputs/loops.moon | |||
@@ -91,6 +91,15 @@ while true | |||
91 | break if true | 91 | break if true |
92 | print "no" | 92 | print "no" |
93 | 93 | ||
94 | a = 1 | ||
95 | repeat | ||
96 | a += 1 | ||
97 | if a == 5 | ||
98 | continue | ||
99 | if a == 6 | ||
100 | break | ||
101 | print a | ||
102 | until a == 10 | ||
94 | 103 | ||
95 | for x=1,10 | 104 | for x=1,10 |
96 | continue if x > 3 and x < 7 | 105 | continue if x > 3 and x < 7 |
diff --git a/src/MoonP/moon_ast.h b/src/MoonP/moon_ast.h index 7ef25a9..dd11ac4 100644 --- a/src/MoonP/moon_ast.h +++ b/src/MoonP/moon_ast.h | |||
@@ -190,14 +190,16 @@ AST_NODE(Return) | |||
190 | AST_MEMBER(Return, &valueList) | 190 | AST_MEMBER(Return, &valueList) |
191 | AST_END(Return) | 191 | AST_END(Return) |
192 | 192 | ||
193 | class existential_op_t; | ||
193 | class Assign_t; | 194 | class Assign_t; |
194 | class Body_t; | 195 | class Body_t; |
195 | 196 | ||
196 | AST_NODE(With) | 197 | AST_NODE(With) |
198 | ast_ptr<false, existential_op_t> eop; | ||
197 | ast_ptr<true, ExpList_t> valueList; | 199 | ast_ptr<true, ExpList_t> valueList; |
198 | ast_ptr<false, Assign_t> assigns; | 200 | ast_ptr<false, Assign_t> assigns; |
199 | ast_ptr<true, Body_t> body; | 201 | ast_ptr<true, Body_t> body; |
200 | AST_MEMBER(With, &valueList, &assigns, &body) | 202 | AST_MEMBER(With, &eop, &valueList, &assigns, &body) |
201 | AST_END(With) | 203 | AST_END(With) |
202 | 204 | ||
203 | AST_NODE(SwitchCase) | 205 | AST_NODE(SwitchCase) |
@@ -238,6 +240,12 @@ AST_NODE(While) | |||
238 | AST_MEMBER(While, &condition, &body) | 240 | AST_MEMBER(While, &condition, &body) |
239 | AST_END(While) | 241 | AST_END(While) |
240 | 242 | ||
243 | AST_NODE(Repeat) | ||
244 | ast_ptr<true, Body_t> body; | ||
245 | ast_ptr<true, Exp_t> condition; | ||
246 | AST_MEMBER(Repeat, &body, &condition) | ||
247 | AST_END(Repeat) | ||
248 | |||
241 | AST_NODE(for_step_value) | 249 | AST_NODE(for_step_value) |
242 | ast_ptr<true, Exp_t> value; | 250 | ast_ptr<true, Exp_t> value; |
243 | AST_MEMBER(for_step_value, &value) | 251 | AST_MEMBER(for_step_value, &value) |
@@ -664,7 +672,7 @@ AST_LEAF(BreakLoop) | |||
664 | AST_END(BreakLoop) | 672 | AST_END(BreakLoop) |
665 | 673 | ||
666 | AST_NODE(Statement) | 674 | AST_NODE(Statement) |
667 | ast_sel<true, Import_t, While_t, For_t, ForEach_t, | 675 | ast_sel<true, Import_t, While_t, Repeat_t, For_t, ForEach_t, |
668 | Return_t, Local_t, Global_t, Export_t, Macro_t, BreakLoop_t, | 676 | Return_t, Local_t, Global_t, Export_t, Macro_t, BreakLoop_t, |
669 | Label_t, Goto_t, Backcall_t, ExpListAssign_t> content; | 677 | Label_t, Goto_t, Backcall_t, ExpListAssign_t> content; |
670 | ast_ptr<false, statement_appendix_t> appendix; | 678 | ast_ptr<false, statement_appendix_t> appendix; |
diff --git a/src/MoonP/moon_compiler.cpp b/src/MoonP/moon_compiler.cpp index c9d9c78..f79df07 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.10"sv; | 46 | return "0.3.11"sv; |
47 | } | 47 | } |
48 | 48 | ||
49 | // name of table stored in lua registry | 49 | // name of table stored in lua registry |
@@ -741,6 +741,7 @@ private: | |||
741 | switch (content->getId()) { | 741 | switch (content->getId()) { |
742 | case id<Import_t>(): transformImport(static_cast<Import_t*>(content), out); break; | 742 | case id<Import_t>(): transformImport(static_cast<Import_t*>(content), out); break; |
743 | case id<While_t>(): transformWhile(static_cast<While_t*>(content), out); break; | 743 | case id<While_t>(): transformWhile(static_cast<While_t*>(content), out); break; |
744 | case id<Repeat_t>(): transformRepeat(static_cast<Repeat_t*>(content), out); break; | ||
744 | case id<For_t>(): transformFor(static_cast<For_t*>(content), out); break; | 745 | case id<For_t>(): transformFor(static_cast<For_t*>(content), out); break; |
745 | case id<ForEach_t>(): transformForEach(static_cast<ForEach_t*>(content), out); break; | 746 | case id<ForEach_t>(): transformForEach(static_cast<ForEach_t*>(content), out); break; |
746 | case id<Return_t>(): transformReturn(static_cast<Return_t*>(content), out); break; | 747 | case id<Return_t>(): transformReturn(static_cast<Return_t*>(content), out); break; |
@@ -4251,7 +4252,7 @@ private: | |||
4251 | transformAssignment(assignment, temp); | 4252 | transformAssignment(assignment, temp); |
4252 | } | 4253 | } |
4253 | } | 4254 | } |
4254 | if (!scoped && !returnValue) { | 4255 | if (!with->eop && !scoped && !returnValue) { |
4255 | pushScope(); | 4256 | pushScope(); |
4256 | scoped = traversal::Stop == with->body->traverse([&](ast_node* node) { | 4257 | scoped = traversal::Stop == with->body->traverse([&](ast_node* node) { |
4257 | if (auto statement = ast_cast<Statement_t>(node)) { | 4258 | if (auto statement = ast_cast<Statement_t>(node)) { |
@@ -4297,7 +4298,14 @@ private: | |||
4297 | } | 4298 | } |
4298 | } | 4299 | } |
4299 | _withVars.push(withVar); | 4300 | _withVars.push(withVar); |
4300 | transformBody(with->body, temp, ExpUsage::Common); | 4301 | if (with->eop) { |
4302 | auto ifNode = x->new_ptr<If_t>(); | ||
4303 | ifNode->nodes.push_back(toAst<IfCond_t>(withVar + s("~=nil"sv), x)); | ||
4304 | ifNode->nodes.push_back(with->body); | ||
4305 | transformIf(ifNode, temp, ExpUsage::Common); | ||
4306 | } else { | ||
4307 | transformBody(with->body, temp, ExpUsage::Common); | ||
4308 | } | ||
4301 | _withVars.pop(); | 4309 | _withVars.pop(); |
4302 | if (assignList) { | 4310 | if (assignList) { |
4303 | auto assignment = x->new_ptr<ExpListAssign_t>(); | 4311 | auto assignment = x->new_ptr<ExpListAssign_t>(); |
@@ -4914,6 +4922,18 @@ private: | |||
4914 | out.push_back(clearBuf()); | 4922 | out.push_back(clearBuf()); |
4915 | } | 4923 | } |
4916 | 4924 | ||
4925 | void transformRepeat(Repeat_t* repeat, str_list& out) { | ||
4926 | str_list temp; | ||
4927 | pushScope(); | ||
4928 | transformLoopBody(repeat->body, temp, Empty, ExpUsage::Common); | ||
4929 | transformExp(repeat->condition, temp, ExpUsage::Closure); | ||
4930 | popScope(); | ||
4931 | _buf << indent() << "repeat"sv << nll(repeat); | ||
4932 | _buf << temp.front(); | ||
4933 | _buf << indent() << "until "sv << temp.back() << nlr(repeat); | ||
4934 | out.push_back(clearBuf()); | ||
4935 | } | ||
4936 | |||
4917 | void transformSwitch(Switch_t* switchNode, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { | 4937 | void transformSwitch(Switch_t* switchNode, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { |
4918 | str_list temp; | 4938 | str_list temp; |
4919 | if (usage == ExpUsage::Closure) { | 4939 | if (usage == ExpUsage::Closure) { |
diff --git a/src/MoonP/moon_parser.cpp b/src/MoonP/moon_parser.cpp index 7de2a84..4f12a34 100644 --- a/src/MoonP/moon_parser.cpp +++ b/src/MoonP/moon_parser.cpp | |||
@@ -209,7 +209,7 @@ MoonParser::MoonParser() { | |||
209 | 209 | ||
210 | WithExp = ExpList >> -Assign; | 210 | WithExp = ExpList >> -Assign; |
211 | 211 | ||
212 | With = key("with") >> DisableDo >> ensure(WithExp, PopDo) >> -key("do") >> Body; | 212 | With = key("with") >> -existential_op >> DisableDo >> ensure(WithExp, PopDo) >> -key("do") >> Body; |
213 | SwitchCase = key("when") >> ExpList >> -key("then") >> Body; | 213 | SwitchCase = key("when") >> ExpList >> -key("then") >> Body; |
214 | SwitchElse = key("else") >> Body; | 214 | SwitchElse = key("else") >> Body; |
215 | 215 | ||
@@ -231,6 +231,7 @@ MoonParser::MoonParser() { | |||
231 | Unless = key("unless") >> Seperator >> IfCond >> -key("then") >> Body >> *IfElseIf >> -IfElse; | 231 | Unless = key("unless") >> Seperator >> IfCond >> -key("then") >> Body >> *IfElseIf >> -IfElse; |
232 | 232 | ||
233 | While = key("while") >> DisableDo >> ensure(Exp, PopDo) >> -key("do") >> Body; | 233 | While = key("while") >> DisableDo >> ensure(Exp, PopDo) >> -key("do") >> Body; |
234 | Repeat = key("repeat") >> Body >> Break >> *EmptyLine >> CheckIndent >> key("until") >> Exp; | ||
234 | 235 | ||
235 | for_step_value = sym(',') >> White >> Exp; | 236 | for_step_value = sym(',') >> White >> Exp; |
236 | for_args = Space >> Variable >> sym('=') >> Exp >> sym(',') >> White >> Exp >> -for_step_value; | 237 | for_args = Space >> Variable >> sym('=') >> Exp >> sym(',') >> White >> Exp >> -for_step_value; |
@@ -538,10 +539,9 @@ MoonParser::MoonParser() { | |||
538 | 539 | ||
539 | statement_appendix = (if_line | unless_line | CompInner) >> Space; | 540 | statement_appendix = (if_line | unless_line | CompInner) >> Space; |
540 | Statement = ( | 541 | Statement = ( |
541 | Import | While | For | ForEach | | 542 | Import | While | Repeat | For | ForEach | |
542 | Return | Local | Global | Export | | 543 | Return | Local | Global | Export | Macro | |
543 | Macro | Space >> BreakLoop | Label | | 544 | Space >> BreakLoop | Label | Goto | Backcall | ExpListAssign |
544 | Goto | Backcall | ExpListAssign | ||
545 | ) >> Space >> | 545 | ) >> Space >> |
546 | -statement_appendix; | 546 | -statement_appendix; |
547 | 547 | ||
diff --git a/src/MoonP/moon_parser.h b/src/MoonP/moon_parser.h index ec51340..1f9caf8 100644 --- a/src/MoonP/moon_parser.h +++ b/src/MoonP/moon_parser.h | |||
@@ -216,6 +216,7 @@ private: | |||
216 | AST_RULE(If) | 216 | AST_RULE(If) |
217 | AST_RULE(Unless) | 217 | AST_RULE(Unless) |
218 | AST_RULE(While) | 218 | AST_RULE(While) |
219 | AST_RULE(Repeat) | ||
219 | AST_RULE(for_step_value) | 220 | AST_RULE(for_step_value) |
220 | AST_RULE(For) | 221 | AST_RULE(For) |
221 | AST_RULE(ForEach) | 222 | AST_RULE(ForEach) |