aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--spec/inputs/existential.moon4
-rw-r--r--spec/inputs/loops.moon9
-rw-r--r--src/MoonP/moon_ast.h12
-rw-r--r--src/MoonP/moon_compiler.cpp26
-rw-r--r--src/MoonP/moon_parser.cpp10
-rw-r--r--src/MoonP/moon_parser.h1
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
46b = tb1?\end? or tb2?\then 46b = tb1?\end? or tb2?\then
47 47
48with? 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
94a = 1
95repeat
96 a += 1
97 if a == 5
98 continue
99 if a == 6
100 break
101 print a
102until a == 10
94 103
95for x=1,10 104for 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)
191AST_END(Return) 191AST_END(Return)
192 192
193class existential_op_t;
193class Assign_t; 194class Assign_t;
194class Body_t; 195class Body_t;
195 196
196AST_NODE(With) 197AST_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)
201AST_END(With) 203AST_END(With)
202 204
203AST_NODE(SwitchCase) 205AST_NODE(SwitchCase)
@@ -238,6 +240,12 @@ AST_NODE(While)
238 AST_MEMBER(While, &condition, &body) 240 AST_MEMBER(While, &condition, &body)
239AST_END(While) 241AST_END(While)
240 242
243AST_NODE(Repeat)
244 ast_ptr<true, Body_t> body;
245 ast_ptr<true, Exp_t> condition;
246 AST_MEMBER(Repeat, &body, &condition)
247AST_END(Repeat)
248
241AST_NODE(for_step_value) 249AST_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)
664AST_END(BreakLoop) 672AST_END(BreakLoop)
665 673
666AST_NODE(Statement) 674AST_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
45const std::string_view version() { 45const 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)