aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2022-02-21 17:08:58 +0800
committerLi Jin <dragon-fly@qq.com>2022-02-21 17:08:58 +0800
commit00acd729f39c7e6b5db35c6c8a49ba5c55382e58 (patch)
tree1338128b83f24646198def33b581979297044f63
parentb668018486572362b7cbba5257baa7a37ef8d01d (diff)
downloadyuescript-00acd729f39c7e6b5db35c6c8a49ba5c55382e58.tar.gz
yuescript-00acd729f39c7e6b5db35c6c8a49ba5c55382e58.tar.bz2
yuescript-00acd729f39c7e6b5db35c6c8a49ba5c55382e58.zip
add an extra idiom for Lua pcall / xpcall: print result if success, result = try func
-rw-r--r--spec/inputs/try-catch.yue47
-rw-r--r--spec/outputs/try-catch.lua41
-rwxr-xr-xsrc/yuescript/yue_ast.h24
-rwxr-xr-xsrc/yuescript/yue_compiler.cpp71
-rwxr-xr-xsrc/yuescript/yue_parser.cpp8
-rwxr-xr-xsrc/yuescript/yue_parser.h2
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 @@
1try 1try
2 func 1, 2, 3 2 func 1, 2, 3
3catch err 3catch err
4 print err 4 print err
5
6success, result = try
7 func 1, 2, 3
8catch err
9 print err
10 5
11try func 1, 2, 3 6try func 1, 2, 3
12catch err 7catch err
13 print err 8 print err
14
15success, result = try func 1, 2, 3
16 9
17try 10try
18 print "trying" 11 print "trying"
19 func 1, 2, 3 12 func 1, 2, 3
13
14do
15 success, result = try
16 func 1, 2, 3
17 catch err
18 print err
19
20 success, result = try func 1, 2, 3
20 21
21try tb.func 22try tb.func
22try tb.func! 23try tb.func!
@@ -26,5 +27,27 @@ try (tb.func!)
26try tb.func 1 27try tb.func 1
27try tb.func(1) 28try tb.func(1)
28 29
30if (try func 1
31catch err
32 print err)
33 print "OK"
34
35if try func 1
36catch err
37 print err
38 print "OK"
39
40do
41 if success, result = try func "abc", 123
42 print result
43
44 success, result = try func "abc", 123
45 catch err
46 print err
47
48 print result if success, result = try func "abc", 123
49 catch err
50 print err
51
29nil 52nil
30 53
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()
3end, function(err) 3end, function(err)
4 return print(err) 4 return print(err)
5end) 5end)
6local success, result = xpcall(function()
7 return func(1, 2, 3)
8end, function(err)
9 return print(err)
10end)
11xpcall(func, function(err) 6xpcall(func, function(err)
12 return print(err) 7 return print(err)
13end, 1, 2, 3) 8end, 1, 2, 3)
14success, result = pcall(func, 1, 2, 3)
15pcall(function() 9pcall(function()
16 print("trying") 10 print("trying")
17 return func(1, 2, 3) 11 return func(1, 2, 3)
18end) 12end)
13do
14 local success, result = xpcall(function()
15 return func(1, 2, 3)
16 end, function(err)
17 return print(err)
18 end)
19 success, result = pcall(func, 1, 2, 3)
20end
19pcall(tb.func) 21pcall(tb.func)
20pcall(tb.func) 22pcall(tb.func)
21pcall(tb.func) 23pcall(tb.func)
22pcall((tb.func())) 24pcall((tb.func()))
23pcall(tb.func, 1) 25pcall(tb.func, 1)
24pcall(tb.func, 1) 26pcall(tb.func, 1)
27if (xpcall(func, function(err)
28 return print(err)
29end, 1)) then
30 print("OK")
31end
32if xpcall(func, function(err)
33 return print(err)
34end, 1) then
35 print("OK")
36end
37do
38 do
39 local success, result = pcall(func, "abc", 123)
40 if success then
41 print(result)
42 end
43 end
44 local success, result = xpcall(func, function(err)
45 return print(err)
46 end, "abc", 123)
47 success, result = xpcall(func, function(err)
48 return print(err)
49 end, "abc", 123)
50 if success then
51 print(result)
52 end
53end
25return nil 54return 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)
254 AST_MEMBER(Switch, &target, &sep, &branches, &lastBranch) 254 AST_MEMBER(Switch, &target, &sep, &branches, &lastBranch)
255AST_END(Switch) 255AST_END(Switch)
256 256
257AST_NODE(assignment)
258 ast_ptr<true, ExpList_t> expList;
259 ast_ptr<true, Assign_t> assign;
260 AST_MEMBER(assignment, &expList, &assign)
261AST_END(assignment)
262
257AST_NODE(IfCond) 263AST_NODE(IfCond)
258 ast_ptr<true, Exp_t> condition; 264 ast_sel<true, Exp_t, assignment_t> condition;
259 ast_ptr<false, Assign_t> assign; 265 AST_MEMBER(IfCond, &condition)
260 AST_MEMBER(IfCond, &condition, &assign)
261AST_END(IfCond) 266AST_END(IfCond)
262 267
263AST_LEAF(IfType) 268AST_LEAF(IfType)
@@ -766,16 +771,11 @@ AST_NODE(ExpListAssign)
766AST_END(ExpListAssign) 771AST_END(ExpListAssign)
767 772
768AST_NODE(if_line) 773AST_NODE(if_line)
769 ast_ptr<true, Exp_t> condition; 774 ast_ptr<true, IfType_t> type;
770 ast_ptr<false, Assign_t> assign; 775 ast_ptr<true, IfCond_t> condition;
771 AST_MEMBER(if_line, &condition, &assign) 776 AST_MEMBER(if_line, &type, &condition)
772AST_END(if_line) 777AST_END(if_line)
773 778
774AST_NODE(unless_line)
775 ast_ptr<true, Exp_t> condition;
776 AST_MEMBER(unless_line, &condition)
777AST_END(unless_line)
778
779AST_LEAF(BreakLoop) 779AST_LEAF(BreakLoop)
780AST_END(BreakLoop) 780AST_END(BreakLoop)
781 781
@@ -786,7 +786,7 @@ AST_NODE(PipeBody)
786AST_END(PipeBody) 786AST_END(PipeBody)
787 787
788AST_NODE(statement_appendix) 788AST_NODE(statement_appendix)
789 ast_sel<true, if_line_t, unless_line_t, CompInner_t> item; 789 ast_sel<true, if_line_t, CompInner_t> item;
790 AST_MEMBER(statement_appendix, &item) 790 AST_MEMBER(statement_appendix, &item)
791AST_END(statement_appendix) 791AST_END(statement_appendix)
792 792
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;
60 60
61typedef std::list<std::string> str_list; 61typedef std::list<std::string> str_list;
62 62
63const std::string_view version = "0.10.1"sv; 63const std::string_view version = "0.10.2"sv;
64const std::string_view extension = "yue"sv; 64const std::string_view extension = "yue"sv;
65 65
66class YueCompilerImpl { 66class YueCompilerImpl {
@@ -922,13 +922,8 @@ private:
922 case id<if_line_t>(): { 922 case id<if_line_t>(): {
923 auto if_line = static_cast<if_line_t*>(appendix->item.get()); 923 auto if_line = static_cast<if_line_t*>(appendix->item.get());
924 auto ifNode = x->new_ptr<If_t>(); 924 auto ifNode = x->new_ptr<If_t>();
925 auto ifType = toAst<IfType_t>("if"sv, x); 925 ifNode->type.set(if_line->type);
926 ifNode->type.set(ifType); 926 ifNode->nodes.push_back(if_line->condition);
927
928 auto ifCond = x->new_ptr<IfCond_t>();
929 ifCond->condition.set(if_line->condition);
930 ifCond->assign.set(if_line->assign);
931 ifNode->nodes.push_back(ifCond);
932 927
933 auto stmt = x->new_ptr<Statement_t>(); 928 auto stmt = x->new_ptr<Statement_t>();
934 stmt->content.set(statement->content); 929 stmt->content.set(statement->content);
@@ -947,33 +942,6 @@ private:
947 statement->content.set(expListAssign); 942 statement->content.set(expListAssign);
948 break; 943 break;
949 } 944 }
950 case id<unless_line_t>(): {
951 auto unless_line = static_cast<unless_line_t*>(appendix->item.get());
952 auto ifNode = x->new_ptr<If_t>();
953 auto ifType = toAst<IfType_t>("unless"sv, x);
954 ifNode->type.set(ifType);
955
956 auto ifCond = x->new_ptr<IfCond_t>();
957 ifCond->condition.set(unless_line->condition);
958 ifNode->nodes.push_back(ifCond);
959
960 auto stmt = x->new_ptr<Statement_t>();
961 stmt->content.set(statement->content);
962 ifNode->nodes.push_back(stmt);
963
964 statement->appendix.set(nullptr);
965 auto simpleValue = x->new_ptr<SimpleValue_t>();
966 simpleValue->value.set(ifNode);
967 auto value = x->new_ptr<Value_t>();
968 value->item.set(simpleValue);
969 auto exp = newExp(value, x);
970 auto exprList = x->new_ptr<ExpList_t>();
971 exprList->exprs.push_back(exp);
972 auto expListAssign = x->new_ptr<ExpListAssign_t>();
973 expListAssign->expList.set(exprList);
974 statement->content.set(expListAssign);
975 break;
976 }
977 case id<CompInner_t>(): { 945 case id<CompInner_t>(): {
978 auto compInner = appendix->item.to<CompInner_t>(); 946 auto compInner = appendix->item.to<CompInner_t>();
979 auto comp = x->new_ptr<Comprehension_t>(); 947 auto comp = x->new_ptr<Comprehension_t>();
@@ -2185,11 +2153,11 @@ private:
2185 } 2153 }
2186 2154
2187 void transformCond(const node_container& nodes, str_list& out, ExpUsage usage, bool unless, ExpList_t* assignList) { 2155 void transformCond(const node_container& nodes, str_list& out, ExpUsage usage, bool unless, ExpList_t* assignList) {
2188 std::vector<ast_ptr<false, ast_node>> ns(false); 2156 std::vector<ast_ptr<false, ast_node>> ns;
2189 for (auto it = nodes.rbegin(); it != nodes.rend(); ++it) { 2157 for (auto it = nodes.rbegin(); it != nodes.rend(); ++it) {
2190 ns.push_back(*it); 2158 ns.push_back(*it);
2191 if (auto cond = ast_cast<IfCond_t>(*it)) { 2159 if (auto cond = ast_cast<IfCond_t>(*it)) {
2192 if (*it != nodes.front() && cond->assign) { 2160 if (*it != nodes.front() && cond->condition.is<assignment_t>()) {
2193 auto x = *it; 2161 auto x = *it;
2194 auto newIf = x->new_ptr<If_t>(); 2162 auto newIf = x->new_ptr<If_t>();
2195 newIf->type.set(toAst<IfType_t>("if"sv, x)); 2163 newIf->type.set(toAst<IfType_t>("if"sv, x));
@@ -2245,11 +2213,11 @@ private:
2245 default: YUEE("AST node mismatch", node); break; 2213 default: YUEE("AST node mismatch", node); break;
2246 } 2214 }
2247 } 2215 }
2248 auto assign = ifCondPairs.front().first->assign.get(); 2216 auto asmt = ifCondPairs.front().first->condition.as<assignment_t>();
2249 bool storingValue = false; 2217 bool storingValue = false;
2250 ast_ptr<false, ExpListAssign_t> extraAssignment; 2218 ast_ptr<false, ExpListAssign_t> extraAssignment;
2251 if (assign) { 2219 if (asmt) {
2252 auto exp = ifCondPairs.front().first->condition.get(); 2220 ast_ptr<false, ast_node> exp = asmt->expList->exprs.front();
2253 auto x = exp; 2221 auto x = exp;
2254 bool lintGlobal = _config.lintGlobalVariable; 2222 bool lintGlobal = _config.lintGlobalVariable;
2255 _config.lintGlobalVariable = false; 2223 _config.lintGlobalVariable = false;
@@ -2258,8 +2226,8 @@ private:
2258 if (var.empty()) { 2226 if (var.empty()) {
2259 storingValue = true; 2227 storingValue = true;
2260 auto desVar = getUnusedName("_des_"sv); 2228 auto desVar = getUnusedName("_des_"sv);
2261 if (assign->values.objects().size() == 1) { 2229 if (asmt->assign->values.objects().size() == 1) {
2262 auto var = singleVariableFrom(assign->values.objects().front()); 2230 auto var = singleVariableFrom(asmt->assign->values.objects().front());
2263 if (!var.empty() && isLocal(var)) { 2231 if (!var.empty() && isLocal(var)) {
2264 desVar = var; 2232 desVar = var;
2265 storingValue = false; 2233 storingValue = false;
@@ -2267,13 +2235,17 @@ private:
2267 } 2235 }
2268 if (storingValue) { 2236 if (storingValue) {
2269 if (usage != ExpUsage::Closure) { 2237 if (usage != ExpUsage::Closure) {
2270 temp.push_back(indent() + "do"s + nll(assign)); 2238 temp.push_back(indent() + "do"s + nll(asmt));
2271 pushScope(); 2239 pushScope();
2272 } 2240 }
2241 asmt->expList->exprs.pop_front();
2273 auto expList = toAst<ExpList_t>(desVar, x); 2242 auto expList = toAst<ExpList_t>(desVar, x);
2274 auto assignment = x->new_ptr<ExpListAssign_t>(); 2243 auto assignment = x->new_ptr<ExpListAssign_t>();
2244 for (auto expr : asmt->expList->exprs.objects()) {
2245 expList->exprs.push_back(expr);
2246 }
2275 assignment->expList.set(expList); 2247 assignment->expList.set(expList);
2276 assignment->action.set(assign); 2248 assignment->action.set(asmt->assign);
2277 transformAssignment(assignment, temp); 2249 transformAssignment(assignment, temp);
2278 } 2250 }
2279 { 2251 {
@@ -2292,22 +2264,27 @@ private:
2292 if (!isDefined(var)) { 2264 if (!isDefined(var)) {
2293 storingValue = true; 2265 storingValue = true;
2294 if (usage != ExpUsage::Closure) { 2266 if (usage != ExpUsage::Closure) {
2295 temp.push_back(indent() + "do"s + nll(assign)); 2267 temp.push_back(indent() + "do"s + nll(asmt));
2296 pushScope(); 2268 pushScope();
2297 } 2269 }
2298 } 2270 }
2299 auto expList = x->new_ptr<ExpList_t>(); 2271 auto expList = x->new_ptr<ExpList_t>();
2300 expList->exprs.push_back(exp); 2272 expList->exprs.push_back(exp);
2273 asmt->expList->exprs.pop_front();
2274 for (auto expr : asmt->expList->exprs.objects()) {
2275 expList->exprs.push_back(expr);
2276 }
2301 auto assignment = x->new_ptr<ExpListAssign_t>(); 2277 auto assignment = x->new_ptr<ExpListAssign_t>();
2302 assignment->expList.set(expList); 2278 assignment->expList.set(expList);
2303 assignment->action.set(assign); 2279 assignment->action.set(asmt->assign);
2304 transformAssignment(assignment, temp); 2280 transformAssignment(assignment, temp);
2281 ifCondPairs.front().first->condition.set(exp);
2305 } 2282 }
2306 } 2283 }
2307 for (const auto& pair : ifCondPairs) { 2284 for (const auto& pair : ifCondPairs) {
2308 if (pair.first) { 2285 if (pair.first) {
2309 str_list tmp; 2286 str_list tmp;
2310 auto condition = pair.first->condition.get(); 2287 auto condition = pair.first->condition.to<Exp_t>();
2311 auto condStr = transformCondExp(condition, unless); 2288 auto condStr = transformCondExp(condition, unless);
2312 if (unless) unless = false; 2289 if (unless) unless = false;
2313 _buf << indent(); 2290 _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() {
237 Switch = Space >> key("switch") >> disable_do(Exp) >> -(Space >> key("do")) 237 Switch = Space >> key("switch") >> disable_do(Exp) >> -(Space >> key("do"))
238 >> -Space >> Break >> SwitchBlock; 238 >> -Space >> Break >> SwitchBlock;
239 239
240 IfCond = disable_do_chain(disable_arg_table_block(Exp >> -Assign)); 240 assignment = ExpList >> Assign;
241 IfCond = disable_do_chain(disable_arg_table_block(assignment | Exp));
241 IfElseIf = -(Break >> *EmptyLine >> CheckIndent) >> Space >> key("elseif") >> IfCond >> plain_body_with("then"); 242 IfElseIf = -(Break >> *EmptyLine >> CheckIndent) >> Space >> key("elseif") >> IfCond >> plain_body_with("then");
242 IfElse = -(Break >> *EmptyLine >> CheckIndent) >> Space >> key("else") >> plain_body; 243 IfElse = -(Break >> *EmptyLine >> CheckIndent) >> Space >> key("else") >> plain_body;
243 IfType = (expr("if") | expr("unless")) >> not_(AlphaNum); 244 IfType = (expr("if") | expr("unless")) >> not_(AlphaNum);
@@ -619,10 +620,9 @@ YueParser::YueParser() {
619 620
620 ExpListAssign = ExpList >> -(Update | Assign); 621 ExpListAssign = ExpList >> -(Update | Assign);
621 622
622 if_line = Space >> key("if") >> Exp >> -Assign; 623 if_line = Space >> IfType >> IfCond;
623 unless_line = Space >> key("unless") >> Exp;
624 624
625 statement_appendix = (if_line | unless_line | CompInner) >> Space; 625 statement_appendix = (if_line | CompInner) >> Space;
626 statement_sep = and_(*SpaceBreak >> CheckIndent >> Space >> (set("($'\"") | expr("[[") | expr("[="))); 626 statement_sep = and_(*SpaceBreak >> CheckIndent >> Space >> (set("($'\"") | expr("[[") | expr("[=")));
627 Statement = Space >> ( 627 Statement = Space >> (
628 Import | While | Repeat | For | ForEach | 628 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:
228 AST_RULE(With) 228 AST_RULE(With)
229 AST_RULE(SwitchCase) 229 AST_RULE(SwitchCase)
230 AST_RULE(Switch) 230 AST_RULE(Switch)
231 AST_RULE(assignment)
231 AST_RULE(IfCond) 232 AST_RULE(IfCond)
232 AST_RULE(IfType) 233 AST_RULE(IfType)
233 AST_RULE(If) 234 AST_RULE(If)
@@ -315,7 +316,6 @@ private:
315 AST_RULE(unary_exp) 316 AST_RULE(unary_exp)
316 AST_RULE(ExpListAssign) 317 AST_RULE(ExpListAssign)
317 AST_RULE(if_line) 318 AST_RULE(if_line)
318 AST_RULE(unless_line)
319 AST_RULE(BreakLoop) 319 AST_RULE(BreakLoop)
320 AST_RULE(statement_appendix) 320 AST_RULE(statement_appendix)
321 AST_RULE(statement_sep) 321 AST_RULE(statement_sep)