aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2021-02-15 13:17:47 +0800
committerLi Jin <dragon-fly@qq.com>2021-02-15 13:17:47 +0800
commitc6e90a619d4bf027fa0c9fd81c71a6227b8cb3ca (patch)
tree31d0b1b50b718f0aa4e4c67a368c5acbf9e7e146
parentc3a389e2f9f53fb3e3e70a325bf42c8ce02a0b82 (diff)
downloadyuescript-c6e90a619d4bf027fa0c9fd81c71a6227b8cb3ca.tar.gz
yuescript-c6e90a619d4bf027fa0c9fd81c71a6227b8cb3ca.tar.bz2
yuescript-c6e90a619d4bf027fa0c9fd81c71a6227b8cb3ca.zip
fix some ambiguous syntax.
-rw-r--r--spec/inputs/goto.mp6
-rw-r--r--src/MoonP/moon_ast.h21
-rw-r--r--src/MoonP/moon_compiler.cpp62
-rw-r--r--src/MoonP/moon_parser.cpp69
-rw-r--r--src/MoonP/moon_parser.h8
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
9do 9do
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
16do 16do
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
25do 25do
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
224class existential_op_t; 224class existential_op_t;
225class Assign_t; 225class Assign_t;
226class Body_t; 226class Block_t;
227class Statement_t;
227 228
228AST_NODE(With) 229AST_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)
234AST_END(With) 235AST_END(With)
235 236
236AST_NODE(SwitchCase) 237AST_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)
240AST_END(SwitchCase) 241AST_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)
248AST_END(Switch) 249AST_END(Switch)
249 250
@@ -255,22 +256,24 @@ AST_END(IfCond)
255 256
256AST_NODE(If) 257AST_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)
260AST_END(If) 261AST_END(If)
261 262
262AST_NODE(Unless) 263AST_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)
266AST_END(Unless) 267AST_END(Unless)
267 268
268AST_NODE(While) 269AST_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)
272AST_END(While) 273AST_END(While)
273 274
275class Body_t;
276
274AST_NODE(Repeat) 277AST_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)
292AST_END(For) 295AST_END(For)
293 296
@@ -297,7 +300,7 @@ class star_exp_t;
297AST_NODE(ForEach) 300AST_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)
302AST_END(ForEach) 305AST_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
56const std::string_view version = "0.6.2"sv; 56const std::string_view version = "0.6.3"sv;
57const std::string_view extension = "mp"sv; 57const std::string_view extension = "mp"sv;
58 58
59class MoonCompilerImpl { 59class 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;