diff options
author | Li Jin <dragon-fly@qq.com> | 2022-02-21 17:08:58 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2022-02-21 17:08:58 +0800 |
commit | 00acd729f39c7e6b5db35c6c8a49ba5c55382e58 (patch) | |
tree | 1338128b83f24646198def33b581979297044f63 | |
parent | b668018486572362b7cbba5257baa7a37ef8d01d (diff) | |
download | yuescript-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.yue | 47 | ||||
-rw-r--r-- | spec/outputs/try-catch.lua | 41 | ||||
-rwxr-xr-x | src/yuescript/yue_ast.h | 24 | ||||
-rwxr-xr-x | src/yuescript/yue_compiler.cpp | 71 | ||||
-rwxr-xr-x | src/yuescript/yue_parser.cpp | 8 | ||||
-rwxr-xr-x | 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 @@ | |||
1 | try | 1 | try |
2 | func 1, 2, 3 | 2 | func 1, 2, 3 |
3 | catch err | 3 | catch err |
4 | print err | 4 | print err |
5 | |||
6 | success, result = try | ||
7 | func 1, 2, 3 | ||
8 | catch err | ||
9 | print err | ||
10 | 5 | ||
11 | try func 1, 2, 3 | 6 | try func 1, 2, 3 |
12 | catch err | 7 | catch err |
13 | print err | 8 | print err |
14 | |||
15 | success, result = try func 1, 2, 3 | ||
16 | 9 | ||
17 | try | 10 | try |
18 | print "trying" | 11 | print "trying" |
19 | func 1, 2, 3 | 12 | func 1, 2, 3 |
13 | |||
14 | do | ||
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 | ||
21 | try tb.func | 22 | try tb.func |
22 | try tb.func! | 23 | try tb.func! |
@@ -26,5 +27,27 @@ try (tb.func!) | |||
26 | try tb.func 1 | 27 | try tb.func 1 |
27 | try tb.func(1) | 28 | try tb.func(1) |
28 | 29 | ||
30 | if (try func 1 | ||
31 | catch err | ||
32 | print err) | ||
33 | print "OK" | ||
34 | |||
35 | if try func 1 | ||
36 | catch err | ||
37 | print err | ||
38 | print "OK" | ||
39 | |||
40 | do | ||
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 | |||
29 | nil | 52 | nil |
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() | |||
3 | end, function(err) | 3 | end, function(err) |
4 | return print(err) | 4 | return print(err) |
5 | end) | 5 | end) |
6 | local success, result = xpcall(function() | ||
7 | return func(1, 2, 3) | ||
8 | end, function(err) | ||
9 | return print(err) | ||
10 | end) | ||
11 | xpcall(func, function(err) | 6 | xpcall(func, function(err) |
12 | return print(err) | 7 | return print(err) |
13 | end, 1, 2, 3) | 8 | end, 1, 2, 3) |
14 | success, result = pcall(func, 1, 2, 3) | ||
15 | pcall(function() | 9 | pcall(function() |
16 | print("trying") | 10 | print("trying") |
17 | return func(1, 2, 3) | 11 | return func(1, 2, 3) |
18 | end) | 12 | end) |
13 | do | ||
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) | ||
20 | end | ||
19 | pcall(tb.func) | 21 | pcall(tb.func) |
20 | pcall(tb.func) | 22 | pcall(tb.func) |
21 | pcall(tb.func) | 23 | pcall(tb.func) |
22 | pcall((tb.func())) | 24 | pcall((tb.func())) |
23 | pcall(tb.func, 1) | 25 | pcall(tb.func, 1) |
24 | pcall(tb.func, 1) | 26 | pcall(tb.func, 1) |
27 | if (xpcall(func, function(err) | ||
28 | return print(err) | ||
29 | end, 1)) then | ||
30 | print("OK") | ||
31 | end | ||
32 | if xpcall(func, function(err) | ||
33 | return print(err) | ||
34 | end, 1) then | ||
35 | print("OK") | ||
36 | end | ||
37 | do | ||
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 | ||
53 | end | ||
25 | return nil | 54 | 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) | |||
254 | AST_MEMBER(Switch, &target, &sep, &branches, &lastBranch) | 254 | AST_MEMBER(Switch, &target, &sep, &branches, &lastBranch) |
255 | AST_END(Switch) | 255 | AST_END(Switch) |
256 | 256 | ||
257 | AST_NODE(assignment) | ||
258 | ast_ptr<true, ExpList_t> expList; | ||
259 | ast_ptr<true, Assign_t> assign; | ||
260 | AST_MEMBER(assignment, &expList, &assign) | ||
261 | AST_END(assignment) | ||
262 | |||
257 | AST_NODE(IfCond) | 263 | AST_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) | ||
261 | AST_END(IfCond) | 266 | AST_END(IfCond) |
262 | 267 | ||
263 | AST_LEAF(IfType) | 268 | AST_LEAF(IfType) |
@@ -766,16 +771,11 @@ AST_NODE(ExpListAssign) | |||
766 | AST_END(ExpListAssign) | 771 | AST_END(ExpListAssign) |
767 | 772 | ||
768 | AST_NODE(if_line) | 773 | AST_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) |
772 | AST_END(if_line) | 777 | AST_END(if_line) |
773 | 778 | ||
774 | AST_NODE(unless_line) | ||
775 | ast_ptr<true, Exp_t> condition; | ||
776 | AST_MEMBER(unless_line, &condition) | ||
777 | AST_END(unless_line) | ||
778 | |||
779 | AST_LEAF(BreakLoop) | 779 | AST_LEAF(BreakLoop) |
780 | AST_END(BreakLoop) | 780 | AST_END(BreakLoop) |
781 | 781 | ||
@@ -786,7 +786,7 @@ AST_NODE(PipeBody) | |||
786 | AST_END(PipeBody) | 786 | AST_END(PipeBody) |
787 | 787 | ||
788 | AST_NODE(statement_appendix) | 788 | AST_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) |
791 | AST_END(statement_appendix) | 791 | AST_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 | ||
61 | typedef std::list<std::string> str_list; | 61 | typedef std::list<std::string> str_list; |
62 | 62 | ||
63 | const std::string_view version = "0.10.1"sv; | 63 | const std::string_view version = "0.10.2"sv; |
64 | const std::string_view extension = "yue"sv; | 64 | const std::string_view extension = "yue"sv; |
65 | 65 | ||
66 | class YueCompilerImpl { | 66 | class 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) |