From 00acd729f39c7e6b5db35c6c8a49ba5c55382e58 Mon Sep 17 00:00:00 2001 From: Li Jin Date: Mon, 21 Feb 2022 17:08:58 +0800 Subject: add an extra idiom for Lua pcall / xpcall: print result if success, result = try func --- spec/inputs/try-catch.yue | 47 +++++++++++++++++++++------- spec/outputs/try-catch.lua | 41 ++++++++++++++++++++---- src/yuescript/yue_ast.h | 24 +++++++------- src/yuescript/yue_compiler.cpp | 71 ++++++++++++++---------------------------- src/yuescript/yue_parser.cpp | 8 ++--- src/yuescript/yue_parser.h | 2 +- 6 files changed, 111 insertions(+), 82 deletions(-) diff --git a/spec/inputs/try-catch.yue b/spec/inputs/try-catch.yue index ad8b1f0..f5cb97e 100644 --- a/spec/inputs/try-catch.yue +++ b/spec/inputs/try-catch.yue @@ -1,22 +1,23 @@ try - func 1, 2, 3 + func 1, 2, 3 catch err - print err - -success, result = try - func 1, 2, 3 -catch err - print err + print err try func 1, 2, 3 catch err - print err - -success, result = try func 1, 2, 3 + print err try - print "trying" - func 1, 2, 3 + print "trying" + func 1, 2, 3 + +do + success, result = try + func 1, 2, 3 + catch err + print err + + success, result = try func 1, 2, 3 try tb.func try tb.func! @@ -26,5 +27,27 @@ try (tb.func!) try tb.func 1 try tb.func(1) +if (try func 1 +catch err + print err) + print "OK" + +if try func 1 +catch err + print err + print "OK" + +do + if success, result = try func "abc", 123 + print result + + success, result = try func "abc", 123 + catch err + print err + + print result if success, result = try func "abc", 123 + catch err + print err + nil diff --git a/spec/outputs/try-catch.lua b/spec/outputs/try-catch.lua index d4c02ac..692905e 100644 --- a/spec/outputs/try-catch.lua +++ b/spec/outputs/try-catch.lua @@ -3,23 +3,52 @@ xpcall(function() end, function(err) return print(err) end) -local success, result = xpcall(function() - return func(1, 2, 3) -end, function(err) - return print(err) -end) xpcall(func, function(err) return print(err) end, 1, 2, 3) -success, result = pcall(func, 1, 2, 3) pcall(function() print("trying") return func(1, 2, 3) end) +do + local success, result = xpcall(function() + return func(1, 2, 3) + end, function(err) + return print(err) + end) + success, result = pcall(func, 1, 2, 3) +end pcall(tb.func) pcall(tb.func) pcall(tb.func) pcall((tb.func())) pcall(tb.func, 1) pcall(tb.func, 1) +if (xpcall(func, function(err) + return print(err) +end, 1)) then + print("OK") +end +if xpcall(func, function(err) + return print(err) +end, 1) then + print("OK") +end +do + do + local success, result = pcall(func, "abc", 123) + if success then + print(result) + end + end + local success, result = xpcall(func, function(err) + return print(err) + end, "abc", 123) + success, result = xpcall(func, function(err) + return print(err) + end, "abc", 123) + if success then + print(result) + end +end return nil diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h index d2a6557..ecf5afc 100755 --- a/src/yuescript/yue_ast.h +++ b/src/yuescript/yue_ast.h @@ -254,10 +254,15 @@ AST_NODE(Switch) AST_MEMBER(Switch, &target, &sep, &branches, &lastBranch) AST_END(Switch) +AST_NODE(assignment) + ast_ptr expList; + ast_ptr assign; + AST_MEMBER(assignment, &expList, &assign) +AST_END(assignment) + AST_NODE(IfCond) - ast_ptr condition; - ast_ptr assign; - AST_MEMBER(IfCond, &condition, &assign) + ast_sel condition; + AST_MEMBER(IfCond, &condition) AST_END(IfCond) AST_LEAF(IfType) @@ -766,16 +771,11 @@ AST_NODE(ExpListAssign) AST_END(ExpListAssign) AST_NODE(if_line) - ast_ptr condition; - ast_ptr assign; - AST_MEMBER(if_line, &condition, &assign) + ast_ptr type; + ast_ptr condition; + AST_MEMBER(if_line, &type, &condition) AST_END(if_line) -AST_NODE(unless_line) - ast_ptr condition; - AST_MEMBER(unless_line, &condition) -AST_END(unless_line) - AST_LEAF(BreakLoop) AST_END(BreakLoop) @@ -786,7 +786,7 @@ AST_NODE(PipeBody) AST_END(PipeBody) AST_NODE(statement_appendix) - ast_sel item; + ast_sel item; AST_MEMBER(statement_appendix, &item) AST_END(statement_appendix) diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index 41bf207..32a3335 100755 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp @@ -60,7 +60,7 @@ using namespace parserlib; typedef std::list str_list; -const std::string_view version = "0.10.1"sv; +const std::string_view version = "0.10.2"sv; const std::string_view extension = "yue"sv; class YueCompilerImpl { @@ -922,13 +922,8 @@ private: case id(): { auto if_line = static_cast(appendix->item.get()); auto ifNode = x->new_ptr(); - auto ifType = toAst("if"sv, x); - ifNode->type.set(ifType); - - auto ifCond = x->new_ptr(); - ifCond->condition.set(if_line->condition); - ifCond->assign.set(if_line->assign); - ifNode->nodes.push_back(ifCond); + ifNode->type.set(if_line->type); + ifNode->nodes.push_back(if_line->condition); auto stmt = x->new_ptr(); stmt->content.set(statement->content); @@ -947,33 +942,6 @@ private: statement->content.set(expListAssign); break; } - case id(): { - auto unless_line = static_cast(appendix->item.get()); - auto ifNode = x->new_ptr(); - auto ifType = toAst("unless"sv, x); - ifNode->type.set(ifType); - - auto ifCond = x->new_ptr(); - ifCond->condition.set(unless_line->condition); - ifNode->nodes.push_back(ifCond); - - auto stmt = x->new_ptr(); - stmt->content.set(statement->content); - ifNode->nodes.push_back(stmt); - - statement->appendix.set(nullptr); - auto simpleValue = x->new_ptr(); - simpleValue->value.set(ifNode); - auto value = x->new_ptr(); - value->item.set(simpleValue); - auto exp = newExp(value, x); - auto exprList = x->new_ptr(); - exprList->exprs.push_back(exp); - auto expListAssign = x->new_ptr(); - expListAssign->expList.set(exprList); - statement->content.set(expListAssign); - break; - } case id(): { auto compInner = appendix->item.to(); auto comp = x->new_ptr(); @@ -2185,11 +2153,11 @@ private: } void transformCond(const node_container& nodes, str_list& out, ExpUsage usage, bool unless, ExpList_t* assignList) { - std::vector> ns(false); + std::vector> ns; for (auto it = nodes.rbegin(); it != nodes.rend(); ++it) { ns.push_back(*it); if (auto cond = ast_cast(*it)) { - if (*it != nodes.front() && cond->assign) { + if (*it != nodes.front() && cond->condition.is()) { auto x = *it; auto newIf = x->new_ptr(); newIf->type.set(toAst("if"sv, x)); @@ -2245,11 +2213,11 @@ private: default: YUEE("AST node mismatch", node); break; } } - auto assign = ifCondPairs.front().first->assign.get(); + auto asmt = ifCondPairs.front().first->condition.as(); bool storingValue = false; ast_ptr extraAssignment; - if (assign) { - auto exp = ifCondPairs.front().first->condition.get(); + if (asmt) { + ast_ptr exp = asmt->expList->exprs.front(); auto x = exp; bool lintGlobal = _config.lintGlobalVariable; _config.lintGlobalVariable = false; @@ -2258,8 +2226,8 @@ private: if (var.empty()) { storingValue = true; auto desVar = getUnusedName("_des_"sv); - if (assign->values.objects().size() == 1) { - auto var = singleVariableFrom(assign->values.objects().front()); + if (asmt->assign->values.objects().size() == 1) { + auto var = singleVariableFrom(asmt->assign->values.objects().front()); if (!var.empty() && isLocal(var)) { desVar = var; storingValue = false; @@ -2267,13 +2235,17 @@ private: } if (storingValue) { if (usage != ExpUsage::Closure) { - temp.push_back(indent() + "do"s + nll(assign)); + temp.push_back(indent() + "do"s + nll(asmt)); pushScope(); } + asmt->expList->exprs.pop_front(); auto expList = toAst(desVar, x); auto assignment = x->new_ptr(); + for (auto expr : asmt->expList->exprs.objects()) { + expList->exprs.push_back(expr); + } assignment->expList.set(expList); - assignment->action.set(assign); + assignment->action.set(asmt->assign); transformAssignment(assignment, temp); } { @@ -2292,22 +2264,27 @@ private: if (!isDefined(var)) { storingValue = true; if (usage != ExpUsage::Closure) { - temp.push_back(indent() + "do"s + nll(assign)); + temp.push_back(indent() + "do"s + nll(asmt)); pushScope(); } } auto expList = x->new_ptr(); expList->exprs.push_back(exp); + asmt->expList->exprs.pop_front(); + for (auto expr : asmt->expList->exprs.objects()) { + expList->exprs.push_back(expr); + } auto assignment = x->new_ptr(); assignment->expList.set(expList); - assignment->action.set(assign); + assignment->action.set(asmt->assign); transformAssignment(assignment, temp); + ifCondPairs.front().first->condition.set(exp); } } for (const auto& pair : ifCondPairs) { if (pair.first) { str_list tmp; - auto condition = pair.first->condition.get(); + auto condition = pair.first->condition.to(); auto condStr = transformCondExp(condition, unless); if (unless) unless = false; _buf << indent(); diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index 8325366..258997e 100755 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp @@ -237,7 +237,8 @@ YueParser::YueParser() { Switch = Space >> key("switch") >> disable_do(Exp) >> -(Space >> key("do")) >> -Space >> Break >> SwitchBlock; - IfCond = disable_do_chain(disable_arg_table_block(Exp >> -Assign)); + assignment = ExpList >> Assign; + IfCond = disable_do_chain(disable_arg_table_block(assignment | Exp)); IfElseIf = -(Break >> *EmptyLine >> CheckIndent) >> Space >> key("elseif") >> IfCond >> plain_body_with("then"); IfElse = -(Break >> *EmptyLine >> CheckIndent) >> Space >> key("else") >> plain_body; IfType = (expr("if") | expr("unless")) >> not_(AlphaNum); @@ -619,10 +620,9 @@ YueParser::YueParser() { ExpListAssign = ExpList >> -(Update | Assign); - if_line = Space >> key("if") >> Exp >> -Assign; - unless_line = Space >> key("unless") >> Exp; + if_line = Space >> IfType >> IfCond; - statement_appendix = (if_line | unless_line | CompInner) >> Space; + statement_appendix = (if_line | CompInner) >> Space; statement_sep = and_(*SpaceBreak >> CheckIndent >> Space >> (set("($'\"") | expr("[[") | expr("[="))); Statement = Space >> ( Import | While | Repeat | For | ForEach | diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h index bd86f50..51e6977 100755 --- a/src/yuescript/yue_parser.h +++ b/src/yuescript/yue_parser.h @@ -228,6 +228,7 @@ private: AST_RULE(With) AST_RULE(SwitchCase) AST_RULE(Switch) + AST_RULE(assignment) AST_RULE(IfCond) AST_RULE(IfType) AST_RULE(If) @@ -315,7 +316,6 @@ private: AST_RULE(unary_exp) AST_RULE(ExpListAssign) AST_RULE(if_line) - AST_RULE(unless_line) AST_RULE(BreakLoop) AST_RULE(statement_appendix) AST_RULE(statement_sep) -- cgit v1.2.3-55-g6feb