From fe317e2bdd9cb60b3c7cd347e21ce65cf90396e7 Mon Sep 17 00:00:00 2001 From: Li Jin Date: Thu, 16 May 2024 17:25:37 +0800 Subject: fix ambiguous issue in try-catch syntax. --- spec/inputs/try_catch.yue | 86 +++++++++++----------- spec/outputs/5.1/try_catch.lua | 141 +++++++++++++++++++++---------------- spec/outputs/try_catch.lua | 117 +++++++++++++++++------------- spec/outputs/unicode/try_catch.lua | 39 ++++++---- src/yuescript/yue_compiler.cpp | 69 ++++++++++++++---- 5 files changed, 272 insertions(+), 180 deletions(-) diff --git a/spec/inputs/try_catch.yue b/spec/inputs/try_catch.yue index ccb3f52..419eef4 100644 --- a/spec/inputs/try_catch.yue +++ b/spec/inputs/try_catch.yue @@ -1,60 +1,60 @@ -try - func 1, 2, 3 -catch err - print err - -try func 1, 2, 3 -catch err - print err - -try - print "trying" - func 1, 2, 3 - -do - success, result = try +f = -> + try func 1, 2, 3 catch err print err - success, result = try func 1, 2, 3 + try func 1, 2, 3 + catch err + print err -try tb.func -try tb.func! -try tb.func() -try (tb.func!) -try (tb\func(1, 2, 3)) + try + print "trying" + func 1, 2, 3 -try tb.func 1 -try tb.func(1) + do + success, result = try + func 1, 2, 3 + catch err + print err -if (try func 1 -catch err - print err) - print "OK" + success, result = try func 1, 2, 3 -if try (func 1) -catch err - print err - print "OK" + try tb.func + try tb.func! + try tb.func() + try (tb.func!) + try (tb\func(1, 2, 3)) -do - if success, result := try func "abc", 123 - print result + try tb.func 1 + try tb.func(1) - success, result = try func "abc", 123 + if (try func 1 catch err - print err + print err) + print "OK" - print result if success, result := try func "abc", 123 + if try (func 1) catch err - print err + print err + print "OK" -do - try - func 1, 2, 3 + do + if success, result := try func "abc", 123 + print result - try func 1, 2, 3 + success, result = try func "abc", 123 + catch err + print err + + print result if success, result := try func "abc", 123 + catch err + print err + + do + try + func 1, 2, 3 -nil + try func 1, 2, 3 + nil diff --git a/spec/outputs/5.1/try_catch.lua b/spec/outputs/5.1/try_catch.lua index 9972dca..f63cd91 100644 --- a/spec/outputs/5.1/try_catch.lua +++ b/spec/outputs/5.1/try_catch.lua @@ -1,75 +1,94 @@ -xpcall(function() - return func(1, 2, 3) -end, function(err) - return print(err) -end) -xpcall(function() - return func(1, 2, 3) -end, function(err) - return print(err) -end) -pcall(function() +local _anon_func_0 = function(func, print) print("trying") return func(1, 2, 3) -end) -do - local success, result = xpcall(function() +end +local _anon_func_1 = function(tb) + return tb.func +end +local _anon_func_2 = function(tb) + return tb.func() +end +local _anon_func_3 = function(tb) + return tb.func() +end +local _anon_func_4 = function(tb) + return tb.func() +end +local _anon_func_5 = function(tb) + return tb:func(1, 2, 3) +end +local _anon_func_6 = function(tb) + return tb.func(1) +end +local _anon_func_7 = function(tb) + return tb.func(1) +end +local f +f = function() + 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(((function() - local _base_0 = tb - local _fn_0 = _base_0.func - return _fn_0 and function(...) - return _fn_0(_base_0, ...) - end -end)()), 1, 2, 3) -pcall(tb.func, 1) -pcall(tb.func, 1) -if (xpcall(function() - return func(1) -end, function(err) - return print(err) -end)) then - print("OK") -end -if xpcall(function() - return func(1) -end, function(err) - return print(err) -end) then - print("OK") -end -do + xpcall(function() + return func(1, 2, 3) + end, function(err) + return print(err) + end) + pcall(_anon_func_0, func, print) do - local success, result = pcall(func, "abc", 123) - if success then - print(result) - end + 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 - local success, result = xpcall(function() - return func("abc", 123) + pcall(_anon_func_1, tb) + pcall(_anon_func_2, tb) + pcall(_anon_func_3, tb) + pcall(_anon_func_4, tb) + pcall(_anon_func_5, tb) + pcall(_anon_func_6, tb) + pcall(_anon_func_7, tb) + if (xpcall(function() + return func(1) end, function(err) return print(err) - end) - success, result = xpcall(function() - return func("abc", 123) + end)) then + print("OK") + end + if xpcall(function() + return func(1) end, function(err) return print(err) - end) - if success then - print(result) + end) then + print("OK") end + do + do + local success, result = pcall(func, "abc", 123) + if success then + print(result) + end + end + local success, result = xpcall(function() + return func("abc", 123) + end, function(err) + return print(err) + end) + success, result = xpcall(function() + return func("abc", 123) + end, function(err) + return print(err) + end) + if success then + print(result) + end + end + do + pcall(func, 1, 2, 3) + pcall(func, 1, 2, 3) + end + return nil end -do -pcall(func, 1, 2, 3) -pcall(func, 1, 2, 3) -end -return nil diff --git a/spec/outputs/try_catch.lua b/spec/outputs/try_catch.lua index de52c6c..3c3dd3c 100644 --- a/spec/outputs/try_catch.lua +++ b/spec/outputs/try_catch.lua @@ -1,61 +1,80 @@ -xpcall(func, function(err) - return print(err) -end, 1, 2, 3) -xpcall(func, function(err) - return print(err) -end, 1, 2, 3) -pcall(function() +local _anon_func_0 = function(func, print) print("trying") return func(1, 2, 3) -end) -do - local success, result = xpcall(func, function(err) +end +local _anon_func_1 = function(tb) + return tb.func +end +local _anon_func_2 = function(tb) + return tb.func() +end +local _anon_func_3 = function(tb) + return tb.func() +end +local _anon_func_4 = function(tb) + return tb.func() +end +local _anon_func_5 = function(tb) + return tb:func(1, 2, 3) +end +local _anon_func_6 = function(tb) + return tb.func(1) +end +local _anon_func_7 = function(tb) + return tb.func(1) +end +local f +f = function() + xpcall(func, function(err) + return print(err) + end, 1, 2, 3) + xpcall(func, function(err) return print(err) end, 1, 2, 3) - success, result = pcall(func, 1, 2, 3) -end -pcall(tb.func) -pcall(tb.func) -pcall(tb.func) -pcall((tb.func)) -pcall(((function() - local _base_0 = tb - local _fn_0 = _base_0.func - return _fn_0 and function(...) - return _fn_0(_base_0, ...) + pcall(_anon_func_0, func, print) + do + local success, result = xpcall(func, function(err) + return print(err) + end, 1, 2, 3) + success, result = pcall(func, 1, 2, 3) + end + pcall(_anon_func_1, tb) + pcall(_anon_func_2, tb) + pcall(_anon_func_3, tb) + pcall(_anon_func_4, tb) + pcall(_anon_func_5, tb) + pcall(_anon_func_6, tb) + pcall(_anon_func_7, tb) + 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 -end)()), 1, 2, 3) -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) + 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 - 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) + do + pcall(func, 1, 2, 3) + pcall(func, 1, 2, 3) end + return nil end -do -pcall(func, 1, 2, 3) -pcall(func, 1, 2, 3) -end -return nil diff --git a/spec/outputs/unicode/try_catch.lua b/spec/outputs/unicode/try_catch.lua index fde63d6..7d95f9b 100644 --- a/spec/outputs/unicode/try_catch.lua +++ b/spec/outputs/unicode/try_catch.lua @@ -14,19 +14,28 @@ do end, 1, 2, 3) _u6210_u529f, _u7ed3_u679c = pcall(_u51fd_u6570, 1, 2, 3) end -pcall(_u8868["函数"]) -pcall(_u8868["函数"]) -pcall(_u8868["函数"]) -pcall((_u8868["函数"])) -pcall(((function() - local _base_0 = _u8868 - local _fn_0 = _base_0["函数"] - return _fn_0 and function(...) - return _fn_0(_base_0, ...) - end -end)()), 1, 2, 3) -pcall(_u8868["函数"], 1) -pcall(_u8868["函数"], 1) +pcall(function() + return _u8868["函数"] +end) +pcall(function() + return _u8868["函数"]() +end) +pcall(function() + return _u8868["函数"]() +end) +pcall(function() + return _u8868["函数"]() +end) +pcall(function() + local _call_0 = _u8868 + return _call_0["函数"](_call_0, 1, 2, 3) +end) +pcall(function() + return _u8868["函数"](1) +end) +pcall(function() + return _u8868["函数"](1) +end) if (xpcall(_u51fd_u6570, function(_u9519_u8bef) return _u6253_u5370(_u9519_u8bef) end, 1)) then @@ -55,7 +64,7 @@ do end end do -pcall(_u51fd_u6570, 1, 2, 3) -pcall(_u51fd_u6570, 1, 2, 3) + pcall(_u51fd_u6570, 1, 2, 3) + pcall(_u51fd_u6570, 1, 2, 3) end return nil diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index 9a632fb..c205031 100644 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp @@ -75,7 +75,7 @@ static std::unordered_set Metamethods = { "close"s // Lua 5.4 }; -const std::string_view version = "0.23.3"sv; +const std::string_view version = "0.23.4"sv; const std::string_view extension = "yue"sv; class CompileError : public std::logic_error { @@ -4663,8 +4663,10 @@ private: return 503; } else if (target.value() == "5.4"sv) { return 504; + } else if (target.value() == "5.5"sv) { + return 505; } else { - throw CompileError("get invalid Lua target \""s + target.value() + "\", should be 5.1, 5.2, 5.3 or 5.4"s, x); + throw CompileError("get invalid Lua target \""s + target.value() + "\", should be from 5.1 to 5.5"s, x); } } #ifndef YUE_NO_MACRO @@ -9112,7 +9114,9 @@ private: body->content.set(tryNode->catchBlock->block); funLit->body.set(body); } - if (auto tryBlock = tryNode->func.as()) { + ast_sel tryFunc; + tryFunc.set(tryNode->func); + if (auto tryBlock = tryFunc.as()) { BLOCK_START BREAK_IF(tryBlock->statements.size() != 1); auto stmt = static_cast(tryBlock->statements.front()); @@ -9124,11 +9128,43 @@ private: auto chainValue = value->item.as(); BREAK_IF(!chainValue); BREAK_IF(!isChainValueCall(chainValue)); - tryNode->func.set(expListAssign->expList->exprs.front()); + auto tmpChain = chainValue->new_ptr(); + tmpChain->items.dup(chainValue->items); + tmpChain->items.pop_back(); + auto var = singleVariableFrom(tmpChain, AccessType::None); + BREAK_IF(var.empty()); + tryFunc.set(expListAssign->expList->exprs.front()); BLOCK_END + } else { + auto tryExp = tryFunc.as(); + bool needWrap = singleVariableFrom(tryExp, AccessType::None).empty(); + BLOCK_START + auto value = singleValueFrom(tryExp); + BREAK_IF(!value); + auto chainValue = value->item.as(); + BREAK_IF(!chainValue); + BREAK_IF(!isChainValueCall(chainValue)); + auto tmpChain = chainValue->new_ptr(); + tmpChain->items.dup(chainValue->items); + tmpChain->items.pop_back(); + auto var = singleVariableFrom(tmpChain, AccessType::None); + BREAK_IF(var.empty()); + needWrap = false; + BLOCK_END + if (needWrap) { + auto expList = x->new_ptr(); + expList->exprs.push_back(tryFunc); + auto expListAssign = x->new_ptr(); + expListAssign->expList.set(expList); + auto stmt = x->new_ptr(); + stmt->content.set(expListAssign); + auto block = x->new_ptr(); + block->statements.push_back(stmt); + tryFunc.set(block); + } } - if (auto tryBlock = tryNode->func.as()) { - { + if (auto tryBlock = tryFunc.as()) { + if (getLuaTarget(tryBlock) >= 502 || !errHandler) { if (auto result = upValueFuncFrom(tryBlock)) { auto [funcName, args] = std::move(*result); if (errHandler) { @@ -9150,6 +9186,7 @@ private: transformChainValue(pcall, out, ExpUsage::Closure); } if (usage == ExpUsage::Common) { + out.back().insert(0, indent()); out.back().append(nlr(x)); } return; @@ -9173,19 +9210,25 @@ private: transformChainValue(pcall, out, ExpUsage::Closure); } if (usage == ExpUsage::Common) { + out.back().insert(0, indent()); out.back().append(nlr(x)); } return; - } else if (auto value = singleValueFrom(tryNode->func)) { + } else if (auto value = singleValueFrom(tryFunc)) { BLOCK_START auto chainValue = value->item.as(); BREAK_IF(!chainValue); BREAK_IF(!isChainValueCall(chainValue)); + auto tmpChain = chainValue->new_ptr(); + tmpChain->items.dup(chainValue->items); + tmpChain->items.pop_back(); + auto var = singleVariableFrom(tmpChain, AccessType::None); + BREAK_IF(var.empty()); if (errHandler && getLuaTarget(x) < 502) { auto tryExp = toAst("->"sv, x); auto funLit = simpleSingleValueFrom(tryExp)->value.to(); auto expList = x->new_ptr(); - expList->exprs.push_back(tryNode->func); + expList->exprs.push_back(tryFunc); auto expListAssign = x->new_ptr(); expListAssign->expList.set(expList); auto stmt = x->new_ptr(); @@ -9210,7 +9253,7 @@ private: if (errHandler) { auto xpcall = toAst("xpcall()", x); auto invoke = ast_to(xpcall->items.back()); - invoke->args.push_back(tryNode->func); + invoke->args.push_back(tryFunc); invoke->args.push_back(errHandler); for (auto arg : args->objects()) { invoke->args.push_back(arg); @@ -9219,7 +9262,7 @@ private: } else { auto pcall = toAst("pcall()", x); auto invoke = ast_to(pcall->items.back()); - invoke->args.push_back(tryNode->func); + invoke->args.push_back(tryFunc); for (auto arg : args->objects()) { invoke->args.push_back(arg); } @@ -9227,6 +9270,7 @@ private: } } if (usage == ExpUsage::Common) { + out.back().insert(0, indent()); out.back().append(nlr(x)); } return; @@ -9235,16 +9279,17 @@ private: if (errHandler) { auto xpcall = toAst("xpcall()", x); auto invoke = ast_to(xpcall->items.back()); - invoke->args.push_back(tryNode->func); + invoke->args.push_back(tryFunc); invoke->args.push_back(errHandler); transformChainValue(xpcall, out, ExpUsage::Closure); } else { auto pcall = toAst("pcall()", x); auto invoke = ast_to(pcall->items.back()); - invoke->args.push_back(tryNode->func); + invoke->args.push_back(tryFunc); transformChainValue(pcall, out, ExpUsage::Closure); } if (usage == ExpUsage::Common) { + out.back().insert(0, indent()); out.back().append(nlr(x)); } } -- cgit v1.2.3-55-g6feb