From 502af415a7d72bd8229613056e5c5e1dd8ce518d Mon Sep 17 00:00:00 2001 From: Li Jin Date: Sun, 26 Apr 2020 16:07:18 +0800 Subject: add existential op support for with statement, add repeat until statement. --- src/MoonP/moon_ast.h | 12 ++++++++++-- src/MoonP/moon_compiler.cpp | 26 +++++++++++++++++++++++--- src/MoonP/moon_parser.cpp | 10 +++++----- src/MoonP/moon_parser.h | 1 + 4 files changed, 39 insertions(+), 10 deletions(-) (limited to 'src') 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) AST_MEMBER(Return, &valueList) AST_END(Return) +class existential_op_t; class Assign_t; class Body_t; AST_NODE(With) + ast_ptr eop; ast_ptr valueList; ast_ptr assigns; ast_ptr body; - AST_MEMBER(With, &valueList, &assigns, &body) + AST_MEMBER(With, &eop, &valueList, &assigns, &body) AST_END(With) AST_NODE(SwitchCase) @@ -238,6 +240,12 @@ AST_NODE(While) AST_MEMBER(While, &condition, &body) AST_END(While) +AST_NODE(Repeat) + ast_ptr body; + ast_ptr condition; + AST_MEMBER(Repeat, &body, &condition) +AST_END(Repeat) + AST_NODE(for_step_value) ast_ptr value; AST_MEMBER(for_step_value, &value) @@ -664,7 +672,7 @@ AST_LEAF(BreakLoop) AST_END(BreakLoop) AST_NODE(Statement) - ast_sel content; ast_ptr 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) { } const std::string_view version() { - return "0.3.10"sv; + return "0.3.11"sv; } // name of table stored in lua registry @@ -741,6 +741,7 @@ private: switch (content->getId()) { case id(): transformImport(static_cast(content), out); break; case id(): transformWhile(static_cast(content), out); break; + case id(): transformRepeat(static_cast(content), out); break; case id(): transformFor(static_cast(content), out); break; case id(): transformForEach(static_cast(content), out); break; case id(): transformReturn(static_cast(content), out); break; @@ -4251,7 +4252,7 @@ private: transformAssignment(assignment, temp); } } - if (!scoped && !returnValue) { + if (!with->eop && !scoped && !returnValue) { pushScope(); scoped = traversal::Stop == with->body->traverse([&](ast_node* node) { if (auto statement = ast_cast(node)) { @@ -4297,7 +4298,14 @@ private: } } _withVars.push(withVar); - transformBody(with->body, temp, ExpUsage::Common); + if (with->eop) { + auto ifNode = x->new_ptr(); + ifNode->nodes.push_back(toAst(withVar + s("~=nil"sv), x)); + ifNode->nodes.push_back(with->body); + transformIf(ifNode, temp, ExpUsage::Common); + } else { + transformBody(with->body, temp, ExpUsage::Common); + } _withVars.pop(); if (assignList) { auto assignment = x->new_ptr(); @@ -4914,6 +4922,18 @@ private: out.push_back(clearBuf()); } + void transformRepeat(Repeat_t* repeat, str_list& out) { + str_list temp; + pushScope(); + transformLoopBody(repeat->body, temp, Empty, ExpUsage::Common); + transformExp(repeat->condition, temp, ExpUsage::Closure); + popScope(); + _buf << indent() << "repeat"sv << nll(repeat); + _buf << temp.front(); + _buf << indent() << "until "sv << temp.back() << nlr(repeat); + out.push_back(clearBuf()); + } + void transformSwitch(Switch_t* switchNode, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { str_list temp; 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() { WithExp = ExpList >> -Assign; - With = key("with") >> DisableDo >> ensure(WithExp, PopDo) >> -key("do") >> Body; + With = key("with") >> -existential_op >> DisableDo >> ensure(WithExp, PopDo) >> -key("do") >> Body; SwitchCase = key("when") >> ExpList >> -key("then") >> Body; SwitchElse = key("else") >> Body; @@ -231,6 +231,7 @@ MoonParser::MoonParser() { Unless = key("unless") >> Seperator >> IfCond >> -key("then") >> Body >> *IfElseIf >> -IfElse; While = key("while") >> DisableDo >> ensure(Exp, PopDo) >> -key("do") >> Body; + Repeat = key("repeat") >> Body >> Break >> *EmptyLine >> CheckIndent >> key("until") >> Exp; for_step_value = sym(',') >> White >> Exp; for_args = Space >> Variable >> sym('=') >> Exp >> sym(',') >> White >> Exp >> -for_step_value; @@ -538,10 +539,9 @@ MoonParser::MoonParser() { statement_appendix = (if_line | unless_line | CompInner) >> Space; Statement = ( - Import | While | For | ForEach | - Return | Local | Global | Export | - Macro | Space >> BreakLoop | Label | - Goto | Backcall | ExpListAssign + Import | While | Repeat | For | ForEach | + Return | Local | Global | Export | Macro | + Space >> BreakLoop | Label | Goto | Backcall | ExpListAssign ) >> Space >> -statement_appendix; 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: AST_RULE(If) AST_RULE(Unless) AST_RULE(While) + AST_RULE(Repeat) AST_RULE(for_step_value) AST_RULE(For) AST_RULE(ForEach) -- cgit v1.2.3-55-g6feb