diff options
Diffstat (limited to '')
| -rw-r--r-- | src/yuescript/yue_compiler.cpp | 59 | ||||
| -rw-r--r-- | src/yuescript/yuescript.h | 17 |
2 files changed, 50 insertions, 26 deletions
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index 1378436..4d8ed86 100644 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp | |||
| @@ -72,7 +72,7 @@ static std::unordered_set<std::string> Metamethods = { | |||
| 72 | "close"s // Lua 5.4 | 72 | "close"s // Lua 5.4 |
| 73 | }; | 73 | }; |
| 74 | 74 | ||
| 75 | const std::string_view version = "0.17.11"sv; | 75 | const std::string_view version = "0.17.12"sv; |
| 76 | const std::string_view extension = "yue"sv; | 76 | const std::string_view extension = "yue"sv; |
| 77 | 77 | ||
| 78 | class CompileError : public std::logic_error { | 78 | class CompileError : public std::logic_error { |
| @@ -7978,31 +7978,50 @@ private: | |||
| 7978 | auto chainValue = value->item.as<ChainValue_t>(); | 7978 | auto chainValue = value->item.as<ChainValue_t>(); |
| 7979 | BREAK_IF(!chainValue); | 7979 | BREAK_IF(!chainValue); |
| 7980 | BREAK_IF(!isChainValueCall(chainValue)); | 7980 | BREAK_IF(!isChainValueCall(chainValue)); |
| 7981 | ast_ptr<true, ast_node> last = chainValue->items.back(); | 7981 | if (errHandler && getLuaTarget(x) < 502) { |
| 7982 | chainValue->items.pop_back(); | 7982 | auto tryExp = toAst<Exp_t>("->"sv, x); |
| 7983 | _ast_list* args = nullptr; | 7983 | auto funLit = simpleSingleValueFrom(tryExp)->value.to<FunLit_t>(); |
| 7984 | if (auto invoke = ast_cast<InvokeArgs_t>(last)) { | 7984 | auto expList = x->new_ptr<ExpList_t>(); |
| 7985 | args = &invoke->args; | 7985 | expList->exprs.push_back(tryNode->func); |
| 7986 | } else { | 7986 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); |
| 7987 | args = &(ast_to<Invoke_t>(last)->args); | 7987 | expListAssign->expList.set(expList); |
| 7988 | } | 7988 | auto stmt = x->new_ptr<Statement_t>(); |
| 7989 | if (errHandler) { | 7989 | stmt->content.set(expListAssign); |
| 7990 | auto body = x->new_ptr<Body_t>(); | ||
| 7991 | body->content.set(stmt); | ||
| 7992 | funLit->body.set(body); | ||
| 7990 | auto xpcall = toAst<ChainValue_t>("xpcall()", x); | 7993 | auto xpcall = toAst<ChainValue_t>("xpcall()", x); |
| 7991 | auto invoke = ast_to<Invoke_t>(xpcall->items.back()); | 7994 | auto invoke = ast_to<Invoke_t>(xpcall->items.back()); |
| 7992 | invoke->args.push_back(tryNode->func); | 7995 | invoke->args.push_back(tryExp); |
| 7993 | invoke->args.push_back(errHandler); | 7996 | invoke->args.push_back(errHandler); |
| 7994 | for (auto arg : args->objects()) { | ||
| 7995 | invoke->args.push_back(arg); | ||
| 7996 | } | ||
| 7997 | transformChainValue(xpcall, out, ExpUsage::Closure); | 7997 | transformChainValue(xpcall, out, ExpUsage::Closure); |
| 7998 | } else { | 7998 | } else { |
| 7999 | auto pcall = toAst<ChainValue_t>("pcall()", x); | 7999 | ast_ptr<true, ast_node> last = chainValue->items.back(); |
| 8000 | auto invoke = ast_to<Invoke_t>(pcall->items.back()); | 8000 | chainValue->items.pop_back(); |
| 8001 | invoke->args.push_back(tryNode->func); | 8001 | _ast_list* args = nullptr; |
| 8002 | for (auto arg : args->objects()) { | 8002 | if (auto invoke = ast_cast<InvokeArgs_t>(last)) { |
| 8003 | invoke->args.push_back(arg); | 8003 | args = &invoke->args; |
| 8004 | } else { | ||
| 8005 | args = &(ast_to<Invoke_t>(last)->args); | ||
| 8006 | } | ||
| 8007 | if (errHandler) { | ||
| 8008 | auto xpcall = toAst<ChainValue_t>("xpcall()", x); | ||
| 8009 | auto invoke = ast_to<Invoke_t>(xpcall->items.back()); | ||
| 8010 | invoke->args.push_back(tryNode->func); | ||
| 8011 | invoke->args.push_back(errHandler); | ||
| 8012 | for (auto arg : args->objects()) { | ||
| 8013 | invoke->args.push_back(arg); | ||
| 8014 | } | ||
| 8015 | transformChainValue(xpcall, out, ExpUsage::Closure); | ||
| 8016 | } else { | ||
| 8017 | auto pcall = toAst<ChainValue_t>("pcall()", x); | ||
| 8018 | auto invoke = ast_to<Invoke_t>(pcall->items.back()); | ||
| 8019 | invoke->args.push_back(tryNode->func); | ||
| 8020 | for (auto arg : args->objects()) { | ||
| 8021 | invoke->args.push_back(arg); | ||
| 8022 | } | ||
| 8023 | transformChainValue(pcall, out, ExpUsage::Closure); | ||
| 8004 | } | 8024 | } |
| 8005 | transformChainValue(pcall, out, ExpUsage::Closure); | ||
| 8006 | } | 8025 | } |
| 8007 | if (usage == ExpUsage::Common) { | 8026 | if (usage == ExpUsage::Common) { |
| 8008 | out.back().append(nlr(x)); | 8027 | out.back().append(nlr(x)); |
diff --git a/src/yuescript/yuescript.h b/src/yuescript/yuescript.h index 3d8d65c..a160f55 100644 --- a/src/yuescript/yuescript.h +++ b/src/yuescript/yuescript.h | |||
| @@ -106,9 +106,12 @@ local function yue_loader(name) | |||
| 106 | return concat(tried, "\n\t") | 106 | return concat(tried, "\n\t") |
| 107 | end | 107 | end |
| 108 | local function yue_call(f, ...) | 108 | local function yue_call(f, ...) |
| 109 | return xpcall(f, function(err) | 109 | local args = {...} |
| 110 | return yue.traceback(err, 1) | 110 | return xpcall(function() |
| 111 | end, ...) | 111 | return f(unpack(args)) |
| 112 | end, function(err) | ||
| 113 | return yue.traceback(err, 2) | ||
| 114 | end) | ||
| 112 | end | 115 | end |
| 113 | yue_loadstring = function(...) | 116 | yue_loadstring = function(...) |
| 114 | local options, str, chunk_name, mode, env = get_options(...) | 117 | local options, str, chunk_name, mode, env = get_options(...) |
| @@ -166,9 +169,11 @@ local function yue_traceback(err, level) | |||
| 166 | end | 169 | end |
| 167 | local function yue_require(name) | 170 | local function yue_require(name) |
| 168 | insert_loader() | 171 | insert_loader() |
| 169 | local success, res = xpcall(require, function(err) | 172 | local success, res = xpcall(function() |
| 170 | return yue_traceback(err, 2) | 173 | return require(name) |
| 171 | end, name) | 174 | end, function(err) |
| 175 | return yue_traceback(err, 3) | ||
| 176 | end) | ||
| 172 | if success then | 177 | if success then |
| 173 | return res | 178 | return res |
| 174 | else | 179 | else |
