diff options
author | Li Jin <dragon-fly@qq.com> | 2021-02-15 13:17:47 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2021-02-15 13:17:47 +0800 |
commit | c6e90a619d4bf027fa0c9fd81c71a6227b8cb3ca (patch) | |
tree | 31d0b1b50b718f0aa4e4c67a368c5acbf9e7e146 | |
parent | c3a389e2f9f53fb3e3e70a325bf42c8ce02a0b82 (diff) | |
download | yuescript-c6e90a619d4bf027fa0c9fd81c71a6227b8cb3ca.tar.gz yuescript-c6e90a619d4bf027fa0c9fd81c71a6227b8cb3ca.tar.bz2 yuescript-c6e90a619d4bf027fa0c9fd81c71a6227b8cb3ca.zip |
fix some ambiguous syntax.
-rw-r--r-- | spec/inputs/goto.mp | 6 | ||||
-rw-r--r-- | src/MoonP/moon_ast.h | 21 | ||||
-rw-r--r-- | src/MoonP/moon_compiler.cpp | 62 | ||||
-rw-r--r-- | src/MoonP/moon_parser.cpp | 69 | ||||
-rw-r--r-- | src/MoonP/moon_parser.h | 8 |
5 files changed, 104 insertions, 62 deletions
diff --git a/spec/inputs/goto.mp b/spec/inputs/goto.mp index 3410ca3..1197251 100644 --- a/spec/inputs/goto.mp +++ b/spec/inputs/goto.mp | |||
@@ -7,7 +7,7 @@ do | |||
7 | ::done:: | 7 | ::done:: |
8 | 8 | ||
9 | do | 9 | do |
10 | for z = 1, 10 for y = 1, 10 for x = 1, 10 | 10 | for z = 1, 10 do for y = 1, 10 do for x = 1, 10 |
11 | if x^2 + y^2 == z^2 | 11 | if x^2 + y^2 == z^2 |
12 | print 'found a Pythagorean triple:', x, y, z | 12 | print 'found a Pythagorean triple:', x, y, z |
13 | goto done | 13 | goto done |
@@ -15,7 +15,7 @@ do | |||
15 | 15 | ||
16 | do | 16 | do |
17 | for z = 1, 10 | 17 | for z = 1, 10 |
18 | for y = 1, 10 for x = 1, 10 | 18 | for y = 1, 10 do for x = 1, 10 |
19 | if x^2 + y^2 == z^2 | 19 | if x^2 + y^2 == z^2 |
20 | print 'found a Pythagorean triple:', x, y, z | 20 | print 'found a Pythagorean triple:', x, y, z |
21 | print 'now trying next z...' | 21 | print 'now trying next z...' |
@@ -24,7 +24,7 @@ do | |||
24 | 24 | ||
25 | do | 25 | do |
26 | ::redo:: | 26 | ::redo:: |
27 | for x = 1, 10 for y = 1, 10 | 27 | for x = 1, 10 do for y = 1, 10 |
28 | if not f x, y then goto continue | 28 | if not f x, y then goto continue |
29 | if not g x, y then goto skip | 29 | if not g x, y then goto skip |
30 | if not h x, y then goto redo | 30 | if not h x, y then goto redo |
diff --git a/src/MoonP/moon_ast.h b/src/MoonP/moon_ast.h index e2f54de..6b738d4 100644 --- a/src/MoonP/moon_ast.h +++ b/src/MoonP/moon_ast.h | |||
@@ -223,19 +223,20 @@ AST_END(Return) | |||
223 | 223 | ||
224 | class existential_op_t; | 224 | class existential_op_t; |
225 | class Assign_t; | 225 | class Assign_t; |
226 | class Body_t; | 226 | class Block_t; |
227 | class Statement_t; | ||
227 | 228 | ||
228 | AST_NODE(With) | 229 | AST_NODE(With) |
229 | ast_ptr<false, existential_op_t> eop; | 230 | ast_ptr<false, existential_op_t> eop; |
230 | ast_ptr<true, ExpList_t> valueList; | 231 | ast_ptr<true, ExpList_t> valueList; |
231 | ast_ptr<false, Assign_t> assigns; | 232 | ast_ptr<false, Assign_t> assigns; |
232 | ast_ptr<true, Body_t> body; | 233 | ast_sel<true, Block_t, Statement_t> body; |
233 | AST_MEMBER(With, &eop, &valueList, &assigns, &body) | 234 | AST_MEMBER(With, &eop, &valueList, &assigns, &body) |
234 | AST_END(With) | 235 | AST_END(With) |
235 | 236 | ||
236 | AST_NODE(SwitchCase) | 237 | AST_NODE(SwitchCase) |
237 | ast_ptr<true, ExpList_t> valueList; | 238 | ast_ptr<true, ExpList_t> valueList; |
238 | ast_ptr<true, Body_t> body; | 239 | ast_sel<true, Block_t, Statement_t> body; |
239 | AST_MEMBER(SwitchCase, &valueList, &body) | 240 | AST_MEMBER(SwitchCase, &valueList, &body) |
240 | AST_END(SwitchCase) | 241 | AST_END(SwitchCase) |
241 | 242 | ||
@@ -243,7 +244,7 @@ AST_NODE(Switch) | |||
243 | ast_ptr<true, Exp_t> target; | 244 | ast_ptr<true, Exp_t> target; |
244 | ast_ptr<true, Seperator_t> sep; | 245 | ast_ptr<true, Seperator_t> sep; |
245 | ast_list<true, SwitchCase_t> branches; | 246 | ast_list<true, SwitchCase_t> branches; |
246 | ast_ptr<false, Body_t> lastBranch; | 247 | ast_sel<false, Block_t, Statement_t> lastBranch; |
247 | AST_MEMBER(Switch, &target, &sep, &branches, &lastBranch) | 248 | AST_MEMBER(Switch, &target, &sep, &branches, &lastBranch) |
248 | AST_END(Switch) | 249 | AST_END(Switch) |
249 | 250 | ||
@@ -255,22 +256,24 @@ AST_END(IfCond) | |||
255 | 256 | ||
256 | AST_NODE(If) | 257 | AST_NODE(If) |
257 | ast_ptr<true, Seperator_t> sep; | 258 | ast_ptr<true, Seperator_t> sep; |
258 | ast_sel_list<true, IfCond_t, Body_t> nodes; | 259 | ast_sel_list<true, IfCond_t, Block_t, Statement_t> nodes; |
259 | AST_MEMBER(If, &sep, &nodes) | 260 | AST_MEMBER(If, &sep, &nodes) |
260 | AST_END(If) | 261 | AST_END(If) |
261 | 262 | ||
262 | AST_NODE(Unless) | 263 | AST_NODE(Unless) |
263 | ast_ptr<true, Seperator_t> sep; | 264 | ast_ptr<true, Seperator_t> sep; |
264 | ast_sel_list<true, IfCond_t, Body_t> nodes; | 265 | ast_sel_list<true, IfCond_t, Block_t, Statement_t> nodes; |
265 | AST_MEMBER(Unless, &sep, &nodes) | 266 | AST_MEMBER(Unless, &sep, &nodes) |
266 | AST_END(Unless) | 267 | AST_END(Unless) |
267 | 268 | ||
268 | AST_NODE(While) | 269 | AST_NODE(While) |
269 | ast_ptr<true, Exp_t> condition; | 270 | ast_ptr<true, Exp_t> condition; |
270 | ast_ptr<true, Body_t> body; | 271 | ast_sel<true, Block_t, Statement_t> body; |
271 | AST_MEMBER(While, &condition, &body) | 272 | AST_MEMBER(While, &condition, &body) |
272 | AST_END(While) | 273 | AST_END(While) |
273 | 274 | ||
275 | class Body_t; | ||
276 | |||
274 | AST_NODE(Repeat) | 277 | AST_NODE(Repeat) |
275 | ast_ptr<true, Body_t> body; | 278 | ast_ptr<true, Body_t> body; |
276 | ast_ptr<true, Exp_t> condition; | 279 | ast_ptr<true, Exp_t> condition; |
@@ -287,7 +290,7 @@ AST_NODE(For) | |||
287 | ast_ptr<true, Exp_t> startValue; | 290 | ast_ptr<true, Exp_t> startValue; |
288 | ast_ptr<true, Exp_t> stopValue; | 291 | ast_ptr<true, Exp_t> stopValue; |
289 | ast_ptr<false, for_step_value_t> stepValue; | 292 | ast_ptr<false, for_step_value_t> stepValue; |
290 | ast_ptr<true, Body_t> body; | 293 | ast_sel<true, Block_t, Statement_t> body; |
291 | AST_MEMBER(For, &varName, &startValue, &stopValue, &stepValue, &body) | 294 | AST_MEMBER(For, &varName, &startValue, &stopValue, &stepValue, &body) |
292 | AST_END(For) | 295 | AST_END(For) |
293 | 296 | ||
@@ -297,7 +300,7 @@ class star_exp_t; | |||
297 | AST_NODE(ForEach) | 300 | AST_NODE(ForEach) |
298 | ast_ptr<true, AssignableNameList_t> nameList; | 301 | ast_ptr<true, AssignableNameList_t> nameList; |
299 | ast_sel<true, star_exp_t, ExpList_t> loopValue; | 302 | ast_sel<true, star_exp_t, ExpList_t> loopValue; |
300 | ast_ptr<true, Body_t> body; | 303 | ast_sel<true, Block_t, Statement_t> body; |
301 | AST_MEMBER(ForEach, &nameList, &loopValue, &body) | 304 | AST_MEMBER(ForEach, &nameList, &loopValue, &body) |
302 | AST_END(ForEach) | 305 | AST_END(ForEach) |
303 | 306 | ||
diff --git a/src/MoonP/moon_compiler.cpp b/src/MoonP/moon_compiler.cpp index 6b721f1..24e4a97 100644 --- a/src/MoonP/moon_compiler.cpp +++ b/src/MoonP/moon_compiler.cpp | |||
@@ -53,7 +53,7 @@ inline std::string s(std::string_view sv) { | |||
53 | return std::string(sv); | 53 | return std::string(sv); |
54 | } | 54 | } |
55 | 55 | ||
56 | const std::string_view version = "0.6.2"sv; | 56 | const std::string_view version = "0.6.3"sv; |
57 | const std::string_view extension = "mp"sv; | 57 | const std::string_view extension = "mp"sv; |
58 | 58 | ||
59 | class MoonCompilerImpl { | 59 | class MoonCompilerImpl { |
@@ -516,6 +516,18 @@ private: | |||
516 | return nullptr; | 516 | return nullptr; |
517 | } | 517 | } |
518 | 518 | ||
519 | Statement_t* lastStatementFrom(ast_node* body) const { | ||
520 | switch (body->getId()) { | ||
521 | case id<Block_t>(): | ||
522 | return lastStatementFrom(static_cast<Block_t*>(body)); | ||
523 | case id<Statement_t>(): { | ||
524 | return static_cast<Statement_t*>(body); | ||
525 | } | ||
526 | default: assert(false); break; | ||
527 | } | ||
528 | return nullptr; | ||
529 | } | ||
530 | |||
519 | Statement_t* lastStatementFrom(const node_container& stmts) const { | 531 | Statement_t* lastStatementFrom(const node_container& stmts) const { |
520 | if (!stmts.empty()) { | 532 | if (!stmts.empty()) { |
521 | auto it = stmts.end(); --it; | 533 | auto it = stmts.end(); --it; |
@@ -803,9 +815,7 @@ private: | |||
803 | 815 | ||
804 | auto stmt = x->new_ptr<Statement_t>(); | 816 | auto stmt = x->new_ptr<Statement_t>(); |
805 | stmt->content.set(statement->content); | 817 | stmt->content.set(statement->content); |
806 | auto body = x->new_ptr<Body_t>(); | 818 | ifNode->nodes.push_back(stmt); |
807 | body->content.set(stmt); | ||
808 | ifNode->nodes.push_back(body); | ||
809 | 819 | ||
810 | statement->appendix.set(nullptr); | 820 | statement->appendix.set(nullptr); |
811 | auto simpleValue = x->new_ptr<SimpleValue_t>(); | 821 | auto simpleValue = x->new_ptr<SimpleValue_t>(); |
@@ -830,9 +840,7 @@ private: | |||
830 | 840 | ||
831 | auto stmt = x->new_ptr<Statement_t>(); | 841 | auto stmt = x->new_ptr<Statement_t>(); |
832 | stmt->content.set(statement->content); | 842 | stmt->content.set(statement->content); |
833 | auto body = x->new_ptr<Body_t>(); | 843 | unless->nodes.push_back(stmt); |
834 | body->content.set(stmt); | ||
835 | unless->nodes.push_back(body); | ||
836 | 844 | ||
837 | statement->appendix.set(nullptr); | 845 | statement->appendix.set(nullptr); |
838 | auto simpleValue = x->new_ptr<SimpleValue_t>(); | 846 | auto simpleValue = x->new_ptr<SimpleValue_t>(); |
@@ -1593,9 +1601,7 @@ private: | |||
1593 | expListAssign->expList.set(expList); | 1601 | expListAssign->expList.set(expList); |
1594 | auto stmt = x->new_ptr<Statement_t>(); | 1602 | auto stmt = x->new_ptr<Statement_t>(); |
1595 | stmt->content.set(expListAssign); | 1603 | stmt->content.set(expListAssign); |
1596 | auto body = x->new_ptr<Body_t>(); | 1604 | ns.push_back(stmt.get()); |
1597 | body->content.set(stmt); | ||
1598 | ns.push_back(body.get()); | ||
1599 | } | 1605 | } |
1600 | } | 1606 | } |
1601 | } | 1607 | } |
@@ -1614,15 +1620,16 @@ private: | |||
1614 | pushScope(); | 1620 | pushScope(); |
1615 | _enableReturn.push(true); | 1621 | _enableReturn.push(true); |
1616 | } | 1622 | } |
1617 | std::list<std::pair<IfCond_t*, Body_t*>> ifCondPairs; | 1623 | std::list<std::pair<IfCond_t*, ast_node*>> ifCondPairs; |
1618 | ifCondPairs.emplace_back(); | 1624 | ifCondPairs.emplace_back(); |
1619 | for (auto node : nodes) { | 1625 | for (auto node : nodes) { |
1620 | switch (node->getId()) { | 1626 | switch (node->getId()) { |
1621 | case id<IfCond_t>(): | 1627 | case id<IfCond_t>(): |
1622 | ifCondPairs.back().first = static_cast<IfCond_t*>(node); | 1628 | ifCondPairs.back().first = static_cast<IfCond_t*>(node); |
1623 | break; | 1629 | break; |
1624 | case id<Body_t>(): | 1630 | case id<Block_t>(): |
1625 | ifCondPairs.back().second = static_cast<Body_t*>(node); | 1631 | case id<Statement_t>(): |
1632 | ifCondPairs.back().second = node; | ||
1626 | ifCondPairs.emplace_back(); | 1633 | ifCondPairs.emplace_back(); |
1627 | break; | 1634 | break; |
1628 | default: assert(false); break; | 1635 | default: assert(false); break; |
@@ -1718,7 +1725,7 @@ private: | |||
1718 | if (pair == ifCondPairs.front() && extraAssignment) { | 1725 | if (pair == ifCondPairs.front() && extraAssignment) { |
1719 | transformAssignment(extraAssignment, temp); | 1726 | transformAssignment(extraAssignment, temp); |
1720 | } | 1727 | } |
1721 | transformBody(pair.second, temp, usage, assignList); | 1728 | transform_plain_body(pair.second, temp, usage, assignList); |
1722 | popScope(); | 1729 | popScope(); |
1723 | } | 1730 | } |
1724 | if (!pair.first) { | 1731 | if (!pair.first) { |
@@ -3945,7 +3952,22 @@ private: | |||
3945 | out.push_back(clearBuf()); | 3952 | out.push_back(clearBuf()); |
3946 | } | 3953 | } |
3947 | 3954 | ||
3948 | void transformLoopBody(Body_t* body, str_list& out, const std::string& appendContent, ExpUsage usage, ExpList_t* assignList = nullptr) { | 3955 | void transform_plain_body(ast_node* body, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { |
3956 | switch (body->getId()) { | ||
3957 | case id<Block_t>(): | ||
3958 | transformBlock(static_cast<Block_t*>(body), out, usage, assignList); | ||
3959 | break; | ||
3960 | case id<Statement_t>(): { | ||
3961 | auto newBlock = body->new_ptr<Block_t>(); | ||
3962 | newBlock->statements.push_back(body); | ||
3963 | transformBlock(newBlock, out, usage, assignList); | ||
3964 | break; | ||
3965 | } | ||
3966 | default: assert(false); break; | ||
3967 | } | ||
3968 | } | ||
3969 | |||
3970 | void transformLoopBody(ast_node* body, str_list& out, const std::string& appendContent, ExpUsage usage, ExpList_t* assignList = nullptr) { | ||
3949 | str_list temp; | 3971 | str_list temp; |
3950 | bool withContinue = traversal::Stop == body->traverse([&](ast_node* node) { | 3972 | bool withContinue = traversal::Stop == body->traverse([&](ast_node* node) { |
3951 | if (auto stmt = ast_cast<Statement_t>(node)) { | 3973 | if (auto stmt = ast_cast<Statement_t>(node)) { |
@@ -3968,7 +3990,7 @@ private: | |||
3968 | _continueVars.push(continueVar); | 3990 | _continueVars.push(continueVar); |
3969 | pushScope(); | 3991 | pushScope(); |
3970 | } | 3992 | } |
3971 | transformBody(body, temp, usage, assignList); | 3993 | transform_plain_body(body, temp, usage, assignList); |
3972 | if (withContinue) { | 3994 | if (withContinue) { |
3973 | if (!appendContent.empty()) { | 3995 | if (!appendContent.empty()) { |
3974 | _buf << indent() << appendContent; | 3996 | _buf << indent() << appendContent; |
@@ -4739,7 +4761,7 @@ private: | |||
4739 | ifNode->nodes.push_back(with->body); | 4761 | ifNode->nodes.push_back(with->body); |
4740 | transformIf(ifNode, temp, ExpUsage::Common); | 4762 | transformIf(ifNode, temp, ExpUsage::Common); |
4741 | } else { | 4763 | } else { |
4742 | transformBody(with->body, temp, ExpUsage::Common); | 4764 | transform_plain_body(with->body, temp, ExpUsage::Common); |
4743 | } | 4765 | } |
4744 | _withVars.pop(); | 4766 | _withVars.pop(); |
4745 | if (assignList) { | 4767 | if (assignList) { |
@@ -5401,7 +5423,7 @@ private: | |||
5401 | void transformRepeat(Repeat_t* repeat, str_list& out) { | 5423 | void transformRepeat(Repeat_t* repeat, str_list& out) { |
5402 | str_list temp; | 5424 | str_list temp; |
5403 | pushScope(); | 5425 | pushScope(); |
5404 | transformLoopBody(repeat->body, temp, Empty, ExpUsage::Common); | 5426 | transformLoopBody(repeat->body->content, temp, Empty, ExpUsage::Common); |
5405 | transformExp(repeat->condition, temp, ExpUsage::Closure); | 5427 | transformExp(repeat->condition, temp, ExpUsage::Closure); |
5406 | popScope(); | 5428 | popScope(); |
5407 | _buf << indent() << "repeat"sv << nll(repeat); | 5429 | _buf << indent() << "repeat"sv << nll(repeat); |
@@ -5442,13 +5464,13 @@ private: | |||
5442 | } | 5464 | } |
5443 | temp.back().append(s(" then"sv) + nll(branch)); | 5465 | temp.back().append(s(" then"sv) + nll(branch)); |
5444 | pushScope(); | 5466 | pushScope(); |
5445 | transformBody(branch->body, temp, usage, assignList); | 5467 | transform_plain_body(branch->body, temp, usage, assignList); |
5446 | popScope(); | 5468 | popScope(); |
5447 | } | 5469 | } |
5448 | if (switchNode->lastBranch) { | 5470 | if (switchNode->lastBranch) { |
5449 | temp.push_back(indent() + s("else"sv) + nll(switchNode->lastBranch)); | 5471 | temp.push_back(indent() + s("else"sv) + nll(switchNode->lastBranch)); |
5450 | pushScope(); | 5472 | pushScope(); |
5451 | transformBody(switchNode->lastBranch, temp, usage, assignList); | 5473 | transform_plain_body(switchNode->lastBranch, temp, usage, assignList); |
5452 | popScope(); | 5474 | popScope(); |
5453 | } | 5475 | } |
5454 | temp.push_back(indent() + s("end"sv) + nlr(switchNode)); | 5476 | temp.push_back(indent() + s("end"sv) + nlr(switchNode)); |
diff --git a/src/MoonP/moon_parser.cpp b/src/MoonP/moon_parser.cpp index aafe730..a581e15 100644 --- a/src/MoonP/moon_parser.cpp +++ b/src/MoonP/moon_parser.cpp | |||
@@ -70,8 +70,13 @@ MoonParser::MoonParser() { | |||
70 | 70 | ||
71 | #define sym(str) (Space >> str) | 71 | #define sym(str) (Space >> str) |
72 | #define symx(str) expr(str) | 72 | #define symx(str) expr(str) |
73 | #define ensure(patt, finally) (((patt) >> (finally)) | ((finally) >> (Cut))) | 73 | #define ensure(patt, finally) ((patt) >> (finally) | (finally) >> Cut) |
74 | #define key(str) (Space >> str >> not_(AlphaNum)) | 74 | #define key(str) (Space >> str >> not_(AlphaNum)) |
75 | #define disable_do(patt) (DisableDo >> ((patt) >> EnableDo | EnableDo >> Cut)) | ||
76 | #define disable_chain(patt) (DisableChain >> ((patt) >> EnableChain | EnableChain >> Cut)) | ||
77 | #define disable_do_chain(patt) (DisableDoChain >> ((patt) >> EnableDoChain | EnableDoChain >> Cut)) | ||
78 | #define plain_body_with(str) (-key(str) >> InBlock | key(str) >> Statement) | ||
79 | #define plain_body (InBlock | Statement) | ||
75 | 80 | ||
76 | Variable = pl::user(Name, [](const item_t& item) { | 81 | Variable = pl::user(Name, [](const item_t& item) { |
77 | State* st = reinterpret_cast<State*>(item.user_data); | 82 | State* st = reinterpret_cast<State*>(item.user_data); |
@@ -169,7 +174,7 @@ MoonParser::MoonParser() { | |||
169 | return true; | 174 | return true; |
170 | }); | 175 | }); |
171 | 176 | ||
172 | InBlock = Advance >> ensure(Block, PopIndent); | 177 | InBlock = +SpaceBreak >> Advance >> ensure(Block, PopIndent); |
173 | 178 | ||
174 | local_flag = expr('*') | expr('^'); | 179 | local_flag = expr('*') | expr('^'); |
175 | local_values = NameList >> -(sym('=') >> (TableBlock | ExpListLow)); | 180 | local_values = NameList >> -(sym('=') >> (TableBlock | ExpListLow)); |
@@ -219,11 +224,11 @@ MoonParser::MoonParser() { | |||
219 | 224 | ||
220 | Return = key("return") >> -ExpListLow; | 225 | Return = key("return") >> -ExpListLow; |
221 | 226 | ||
222 | WithExp = DisableChainBlock >> ensure(ExpList >> -Assign, PopChainBlock); | 227 | WithExp = ExpList >> -Assign; |
223 | 228 | ||
224 | With = key("with") >> -existential_op >> DisableDo >> ensure(WithExp, PopDo) >> -key("do") >> Body; | 229 | With = key("with") >> -existential_op >> disable_do_chain(WithExp) >> plain_body_with("do"); |
225 | SwitchCase = key("when") >> ExpList >> -key("then") >> Body; | 230 | SwitchCase = key("when") >> disable_chain(ExpList) >> plain_body_with("then"); |
226 | SwitchElse = key("else") >> Body; | 231 | SwitchElse = key("else") >> plain_body; |
227 | 232 | ||
228 | SwitchBlock = *EmptyLine >> | 233 | SwitchBlock = *EmptyLine >> |
229 | Advance >> Seperator >> | 234 | Advance >> Seperator >> |
@@ -232,31 +237,27 @@ MoonParser::MoonParser() { | |||
232 | -(+SpaceBreak >> SwitchElse) >> | 237 | -(+SpaceBreak >> SwitchElse) >> |
233 | PopIndent; | 238 | PopIndent; |
234 | 239 | ||
235 | Switch = key("switch") >> | 240 | Switch = key("switch") >> disable_do(Exp) >> -key("do") |
236 | DisableDo >> ensure(Exp, PopDo) >> | 241 | >> -Space >> Break >> SwitchBlock; |
237 | -key("do") >> -Space >> Break >> SwitchBlock; | ||
238 | 242 | ||
239 | IfCond = Exp >> -Assign; | 243 | IfCond = disable_chain(Exp >> -Assign); |
240 | IfElseIf = -(Break >> *EmptyLine >> CheckIndent) >> key("elseif") >> IfCond >> -key("then") >> Body; | 244 | IfElseIf = -(Break >> *EmptyLine >> CheckIndent) >> key("elseif") >> IfCond >> plain_body_with("then"); |
241 | IfElse = -(Break >> *EmptyLine >> CheckIndent) >> key("else") >> Body; | 245 | IfElse = -(Break >> *EmptyLine >> CheckIndent) >> key("else") >> plain_body; |
242 | If = key("if") >> Seperator >> IfCond >> -key("then") >> Body >> *IfElseIf >> -IfElse; | 246 | If = key("if") >> Seperator >> IfCond >> plain_body_with("then") >> *IfElseIf >> -IfElse; |
243 | Unless = key("unless") >> Seperator >> IfCond >> -key("then") >> Body >> *IfElseIf >> -IfElse; | 247 | Unless = key("unless") >> Seperator >> IfCond >> plain_body_with("then") >> *IfElseIf >> -IfElse; |
244 | 248 | ||
245 | While = key("while") >> DisableDo >> ensure(Exp, PopDo) >> -key("do") >> Body; | 249 | While = key("while") >> disable_do_chain(Exp) >> plain_body_with("do"); |
246 | Repeat = key("repeat") >> Body >> Break >> *EmptyLine >> CheckIndent >> key("until") >> Exp; | 250 | Repeat = key("repeat") >> Body >> Break >> *EmptyLine >> CheckIndent >> key("until") >> Exp; |
247 | 251 | ||
248 | for_step_value = sym(',') >> Exp; | 252 | for_step_value = sym(',') >> Exp; |
249 | for_args = Space >> Variable >> sym('=') >> Exp >> sym(',') >> Exp >> -for_step_value; | 253 | for_args = Space >> Variable >> sym('=') >> Exp >> sym(',') >> Exp >> -for_step_value; |
250 | 254 | ||
251 | For = key("for") >> DisableDo >> | 255 | For = key("for") >> disable_do_chain(for_args) >> plain_body_with("do"); |
252 | ensure(for_args, PopDo) >> | ||
253 | -key("do") >> Body; | ||
254 | 256 | ||
255 | for_in = star_exp | ExpList; | 257 | for_in = star_exp | ExpList; |
256 | 258 | ||
257 | ForEach = key("for") >> AssignableNameList >> key("in") >> | 259 | ForEach = key("for") >> AssignableNameList >> key("in") >> |
258 | DisableDo >> ensure(for_in, PopDo) >> | 260 | disable_do_chain(for_in) >> plain_body_with("do"); |
259 | -key("do") >> Body; | ||
260 | 261 | ||
261 | Do = pl::user(key("do"), [](const item_t& item) { | 262 | Do = pl::user(key("do"), [](const item_t& item) { |
262 | State* st = reinterpret_cast<State*>(item.user_data); | 263 | State* st = reinterpret_cast<State*>(item.user_data); |
@@ -269,12 +270,26 @@ MoonParser::MoonParser() { | |||
269 | return true; | 270 | return true; |
270 | }); | 271 | }); |
271 | 272 | ||
272 | PopDo = pl::user(true_(), [](const item_t& item) { | 273 | EnableDo = pl::user(true_(), [](const item_t& item) { |
273 | State* st = reinterpret_cast<State*>(item.user_data); | 274 | State* st = reinterpret_cast<State*>(item.user_data); |
274 | st->doStack.pop(); | 275 | st->doStack.pop(); |
275 | return true; | 276 | return true; |
276 | }); | 277 | }); |
277 | 278 | ||
279 | DisableDoChain = pl::user(true_(), [](const item_t& item) { | ||
280 | State* st = reinterpret_cast<State*>(item.user_data); | ||
281 | st->doStack.push(false); | ||
282 | st->chainBlockStack.push(false); | ||
283 | return true; | ||
284 | }); | ||
285 | |||
286 | EnableDoChain = pl::user(true_(), [](const item_t& item) { | ||
287 | State* st = reinterpret_cast<State*>(item.user_data); | ||
288 | st->doStack.pop(); | ||
289 | st->chainBlockStack.pop(); | ||
290 | return true; | ||
291 | }); | ||
292 | |||
278 | Comprehension = sym('[') >> Exp >> CompInner >> sym(']'); | 293 | Comprehension = sym('[') >> Exp >> CompInner >> sym(']'); |
279 | comp_value = sym(',') >> Exp; | 294 | comp_value = sym(',') >> Exp; |
280 | TblComprehension = sym('{') >> Exp >> -comp_value >> CompInner >> sym('}'); | 295 | TblComprehension = sym('{') >> Exp >> -comp_value >> CompInner >> sym('}'); |
@@ -338,13 +353,13 @@ MoonParser::MoonParser() { | |||
338 | exp_op_value = Space >> BinaryOperator >> *SpaceBreak >> backcall_exp; | 353 | exp_op_value = Space >> BinaryOperator >> *SpaceBreak >> backcall_exp; |
339 | Exp = Seperator >> backcall_exp >> *exp_op_value; | 354 | Exp = Seperator >> backcall_exp >> *exp_op_value; |
340 | 355 | ||
341 | DisableChainBlock = pl::user(true_(), [](const item_t& item) { | 356 | DisableChain = pl::user(true_(), [](const item_t& item) { |
342 | State* st = reinterpret_cast<State*>(item.user_data); | 357 | State* st = reinterpret_cast<State*>(item.user_data); |
343 | st->chainBlockStack.push(false); | 358 | st->chainBlockStack.push(false); |
344 | return true; | 359 | return true; |
345 | }); | 360 | }); |
346 | 361 | ||
347 | PopChainBlock = pl::user(true_(), [](const item_t& item) { | 362 | EnableChain = pl::user(true_(), [](const item_t& item) { |
348 | State* st = reinterpret_cast<State*>(item.user_data); | 363 | State* st = reinterpret_cast<State*>(item.user_data); |
349 | st->chainBlockStack.pop(); | 364 | st->chainBlockStack.pop(); |
350 | return true; | 365 | return true; |
@@ -356,7 +371,7 @@ MoonParser::MoonParser() { | |||
356 | return st->chainBlockStack.empty() || st->chainBlockStack.top(); | 371 | return st->chainBlockStack.empty() || st->chainBlockStack.top(); |
357 | }) >> +SpaceBreak >> Advance >> ensure( | 372 | }) >> +SpaceBreak >> Advance >> ensure( |
358 | chain_line >> *(+SpaceBreak >> chain_line), PopIndent); | 373 | chain_line >> *(+SpaceBreak >> chain_line), PopIndent); |
359 | ChainValue = Seperator >> (Chain | Callable) >> -existential_op >> (chain_block | -InvokeArgs); | 374 | ChainValue = Seperator >> (Chain | Callable) >> -existential_op >> -(InvokeArgs | chain_block); |
360 | 375 | ||
361 | simple_table = Seperator >> KeyValue >> *(sym(',') >> KeyValue); | 376 | simple_table = Seperator >> KeyValue >> *(sym(',') >> KeyValue); |
362 | Value = SimpleValue | simple_table | ChainValue | String; | 377 | Value = SimpleValue | simple_table | ChainValue | String; |
@@ -586,10 +601,10 @@ MoonParser::MoonParser() { | |||
586 | ) >> Space >> | 601 | ) >> Space >> |
587 | -statement_appendix >> -statement_sep; | 602 | -statement_appendix >> -statement_sep; |
588 | 603 | ||
589 | Body = Space >> Break >> *EmptyLine >> InBlock | Statement; | 604 | Body = InBlock | Statement; |
590 | 605 | ||
591 | empty_line_stop = Space >> and_(Stop); | 606 | empty_line_stop = Space >> and_(Stop); |
592 | Line = CheckIndent >> Statement | and_(Space >> BackcallOperator) >> Advance >> ensure(Statement, PopIndent) | empty_line_stop; | 607 | Line = and_(check_indent >> Space >> not_(BackcallOperator)) >> Statement | Advance >> ensure(and_(Space >> BackcallOperator) >> Statement, PopIndent) | empty_line_stop; |
593 | Block = Seperator >> Line >> *(+Break >> Line); | 608 | Block = Seperator >> Line >> *(+Break >> Line); |
594 | 609 | ||
595 | Shebang = expr("#!") >> *(not_(Stop) >> Any); | 610 | Shebang = expr("#!") >> *(not_(Stop) >> Any); |
diff --git a/src/MoonP/moon_parser.h b/src/MoonP/moon_parser.h index 66f2cd9..b165070 100644 --- a/src/MoonP/moon_parser.h +++ b/src/MoonP/moon_parser.h | |||
@@ -131,7 +131,11 @@ private: | |||
131 | rule import_tab_lines; | 131 | rule import_tab_lines; |
132 | rule WithExp; | 132 | rule WithExp; |
133 | rule DisableDo; | 133 | rule DisableDo; |
134 | rule PopDo; | 134 | rule EnableDo; |
135 | rule DisableChain; | ||
136 | rule EnableChain; | ||
137 | rule DisableDoChain; | ||
138 | rule EnableDoChain; | ||
135 | rule SwitchElse; | 139 | rule SwitchElse; |
136 | rule SwitchBlock; | 140 | rule SwitchBlock; |
137 | rule IfElseIf; | 141 | rule IfElseIf; |
@@ -158,8 +162,6 @@ private: | |||
158 | rule ChainItem; | 162 | rule ChainItem; |
159 | rule chain_line; | 163 | rule chain_line; |
160 | rule chain_block; | 164 | rule chain_block; |
161 | rule DisableChainBlock; | ||
162 | rule PopChainBlock; | ||
163 | rule Index; | 165 | rule Index; |
164 | rule invoke_chain; | 166 | rule invoke_chain; |
165 | rule TableValue; | 167 | rule TableValue; |