diff options
| author | Li Jin <dragon-fly@qq.com> | 2024-03-19 10:01:17 +0800 |
|---|---|---|
| committer | Li Jin <dragon-fly@qq.com> | 2024-03-19 10:01:17 +0800 |
| commit | 62ddb888d67d047324aa6c411d47aaeac9b658fd (patch) | |
| tree | 60879c8e772ceda2b7926254f09fdd6c6cbc551f | |
| parent | a291e14a5dc25cbe517a3fa3f2a5f33b2cfe05ba (diff) | |
| download | yuescript-62ddb888d67d047324aa6c411d47aaeac9b658fd.tar.gz yuescript-62ddb888d67d047324aa6c411d47aaeac9b658fd.tar.bz2 yuescript-62ddb888d67d047324aa6c411d47aaeac9b658fd.zip | |
fix Lua 5.1 close attribute compatible function.
| -rw-r--r-- | spec/outputs/5.1/attrib.lua | 72 | ||||
| -rw-r--r-- | src/yuescript/yue_compiler.cpp | 23 |
2 files changed, 50 insertions, 45 deletions
diff --git a/spec/outputs/5.1/attrib.lua b/spec/outputs/5.1/attrib.lua index 7391e6e..a9f12e3 100644 --- a/spec/outputs/5.1/attrib.lua +++ b/spec/outputs/5.1/attrib.lua | |||
| @@ -16,11 +16,11 @@ do | |||
| 16 | else | 16 | else |
| 17 | return error(...) | 17 | return error(...) |
| 18 | end | 18 | end |
| 19 | end)(pcall(function(...) | 19 | end)(pcall(function() |
| 20 | local c, d = 123, 'abc' | 20 | local c, d = 123, 'abc' |
| 21 | close(a, b) | 21 | close(a, b) |
| 22 | return const(c, d) | 22 | return const(c, d) |
| 23 | end, ...)) | 23 | end)) |
| 24 | end | 24 | end |
| 25 | do | 25 | do |
| 26 | local a = f() | 26 | local a = f() |
| @@ -66,6 +66,10 @@ local _anon_func_1 = function(io) | |||
| 66 | _with_0:write("Hello") | 66 | _with_0:write("Hello") |
| 67 | return _with_0 | 67 | return _with_0 |
| 68 | end | 68 | end |
| 69 | local _anon_func_2 = function() | ||
| 70 | do | ||
| 71 | end | ||
| 72 | end | ||
| 69 | do | 73 | do |
| 70 | local v = (function() | 74 | local v = (function() |
| 71 | if flag then | 75 | if flag then |
| @@ -85,13 +89,13 @@ do | |||
| 85 | else | 89 | else |
| 86 | return error(...) | 90 | return error(...) |
| 87 | end | 91 | end |
| 88 | end)(pcall(function(...) | 92 | end)(pcall(function() |
| 89 | local f = _anon_func_1(io) | 93 | local f = _anon_func_1(io) |
| 90 | local _close_1 = assert(getmetatable(f).__close) | 94 | local _close_1 = assert(getmetatable(f).__close) |
| 91 | return _anon_func_0(_close_1, error, f, pcall(function(...) end, ...)) | 95 | return _anon_func_0(_close_1, error, f, pcall(_anon_func_2)) |
| 92 | end, ...)) | 96 | end)) |
| 93 | end | 97 | end |
| 94 | local _anon_func_2 = function(_close_1, d, error, _arg_0, ...) | 98 | local _anon_func_3 = function(_close_1, d, error, _arg_0, ...) |
| 95 | do | 99 | do |
| 96 | local _ok_0 = _arg_0 | 100 | local _ok_0 = _arg_0 |
| 97 | _close_1(d) | 101 | _close_1(d) |
| @@ -102,27 +106,31 @@ local _anon_func_2 = function(_close_1, d, error, _arg_0, ...) | |||
| 102 | end | 106 | end |
| 103 | end | 107 | end |
| 104 | end | 108 | end |
| 105 | local _anon_func_3 = function(x) | 109 | local _anon_func_4 = function(x) |
| 106 | if true then | 110 | if true then |
| 107 | if "abc" == x then | 111 | if "abc" == x then |
| 108 | return 998 | 112 | return 998 |
| 109 | end | 113 | end |
| 110 | end | 114 | end |
| 111 | end | 115 | end |
| 112 | local _anon_func_5 = function(a, b) | 116 | local _anon_func_6 = function(a, b) |
| 113 | if a ~= nil then | 117 | if a ~= nil then |
| 114 | return a | 118 | return a |
| 115 | else | 119 | else |
| 116 | return b | 120 | return b |
| 117 | end | 121 | end |
| 118 | end | 122 | end |
| 119 | local _anon_func_4 = function(a, b) | 123 | local _anon_func_5 = function(a, b) |
| 120 | if _anon_func_5(a, b) then | 124 | if _anon_func_6(a, b) then |
| 121 | return { | 125 | return { |
| 122 | value = value | 126 | value = value |
| 123 | } | 127 | } |
| 124 | end | 128 | end |
| 125 | end | 129 | end |
| 130 | local _anon_func_7 = function() | ||
| 131 | do | ||
| 132 | end | ||
| 133 | end | ||
| 126 | do | 134 | do |
| 127 | local a = (function() | 135 | local a = (function() |
| 128 | if true then | 136 | if true then |
| @@ -145,14 +153,14 @@ do | |||
| 145 | else | 153 | else |
| 146 | return error(...) | 154 | return error(...) |
| 147 | end | 155 | end |
| 148 | end)(pcall(function(...) | 156 | end)(pcall(function() |
| 149 | local c = _anon_func_3(x) | 157 | local c = _anon_func_4(x) |
| 150 | local d = _anon_func_4(a, b) | 158 | local d = _anon_func_5(a, b) |
| 151 | local _close_1 = assert(getmetatable(d).__close) | 159 | local _close_1 = assert(getmetatable(d).__close) |
| 152 | return _anon_func_2(_close_1, d, error, pcall(function(...) end, ...)) | 160 | return _anon_func_3(_close_1, d, error, pcall(_anon_func_7)) |
| 153 | end, ...)) | 161 | end)) |
| 154 | end | 162 | end |
| 155 | local _anon_func_6 = function(_, _close_1, error, _arg_0, ...) | 163 | local _anon_func_8 = function(_, _close_1, error, _arg_0, ...) |
| 156 | do | 164 | do |
| 157 | local _ok_0 = _arg_0 | 165 | local _ok_0 = _arg_0 |
| 158 | _close_1(_) | 166 | _close_1(_) |
| @@ -163,7 +171,7 @@ local _anon_func_6 = function(_, _close_1, error, _arg_0, ...) | |||
| 163 | end | 171 | end |
| 164 | end | 172 | end |
| 165 | end | 173 | end |
| 166 | local _anon_func_7 = function(_, _close_2, error, _arg_0, ...) | 174 | local _anon_func_9 = function(_, _close_2, error, _arg_0, ...) |
| 167 | do | 175 | do |
| 168 | local _ok_0 = _arg_0 | 176 | local _ok_0 = _arg_0 |
| 169 | _close_2(_) | 177 | _close_2(_) |
| @@ -189,25 +197,23 @@ do | |||
| 189 | else | 197 | else |
| 190 | return error(...) | 198 | return error(...) |
| 191 | end | 199 | end |
| 192 | end)(pcall(function(...) | 200 | end)(pcall(function() |
| 193 | local _ = setmetatable({ }, { | 201 | local _ = setmetatable({ }, { |
| 194 | __close = function() | 202 | __close = function() |
| 195 | return print("second") | 203 | return print("second") |
| 196 | end | 204 | end |
| 197 | }) | 205 | }) |
| 198 | local _close_1 = assert(getmetatable(_).__close) | 206 | local _close_1 = assert(getmetatable(_).__close) |
| 199 | return _anon_func_6(_, _close_1, error, pcall(function(...) | 207 | return _anon_func_8(_, _close_1, error, pcall(function() |
| 200 | local _ = setmetatable({ }, { | 208 | local _ = setmetatable({ }, { |
| 201 | __close = function() | 209 | __close = function() |
| 202 | return print("first") | 210 | return print("first") |
| 203 | end | 211 | end |
| 204 | }) | 212 | }) |
| 205 | local _close_2 = assert(getmetatable(_).__close) | 213 | local _close_2 = assert(getmetatable(_).__close) |
| 206 | return _anon_func_7(_, _close_2, error, pcall(function(...) | 214 | return _anon_func_9(_, _close_2, error, pcall(print, "third")) |
| 207 | return print("third") | 215 | end)) |
| 208 | end, ...)) | 216 | end)) |
| 209 | end, ...)) | ||
| 210 | end, ...)) | ||
| 211 | end | 217 | end |
| 212 | local _defers = setmetatable({ }, { | 218 | local _defers = setmetatable({ }, { |
| 213 | __close = function(self) | 219 | __close = function(self) |
| @@ -220,7 +226,7 @@ def = function(item) | |||
| 220 | _defers[#_defers + 1] = item | 226 | _defers[#_defers + 1] = item |
| 221 | return _defers | 227 | return _defers |
| 222 | end | 228 | end |
| 223 | local _anon_func_8 = function(_, _close_1, error, _arg_0, ...) | 229 | local _anon_func_10 = function(_, _close_1, error, _arg_0, ...) |
| 224 | do | 230 | do |
| 225 | local _ok_0 = _arg_0 | 231 | local _ok_0 = _arg_0 |
| 226 | _close_1(_) | 232 | _close_1(_) |
| @@ -231,7 +237,7 @@ local _anon_func_8 = function(_, _close_1, error, _arg_0, ...) | |||
| 231 | end | 237 | end |
| 232 | end | 238 | end |
| 233 | end | 239 | end |
| 234 | local _anon_func_9 = function(_, _close_2, error, _arg_0, ...) | 240 | local _anon_func_11 = function(_, _close_2, error, _arg_0, ...) |
| 235 | do | 241 | do |
| 236 | local _ok_0 = _arg_0 | 242 | local _ok_0 = _arg_0 |
| 237 | _close_2(_) | 243 | _close_2(_) |
| @@ -242,6 +248,10 @@ local _anon_func_9 = function(_, _close_2, error, _arg_0, ...) | |||
| 242 | end | 248 | end |
| 243 | end | 249 | end |
| 244 | end | 250 | end |
| 251 | local _anon_func_12 = function() | ||
| 252 | do | ||
| 253 | end | ||
| 254 | end | ||
| 245 | do | 255 | do |
| 246 | local _ = def(function() | 256 | local _ = def(function() |
| 247 | return print(3) | 257 | return print(3) |
| @@ -255,17 +265,17 @@ do | |||
| 255 | else | 265 | else |
| 256 | return error(...) | 266 | return error(...) |
| 257 | end | 267 | end |
| 258 | end)(pcall(function(...) | 268 | end)(pcall(function() |
| 259 | local _ = def(function() | 269 | local _ = def(function() |
| 260 | return print(2) | 270 | return print(2) |
| 261 | end) | 271 | end) |
| 262 | local _close_1 = assert(getmetatable(_).__close) | 272 | local _close_1 = assert(getmetatable(_).__close) |
| 263 | return _anon_func_8(_, _close_1, error, pcall(function(...) | 273 | return _anon_func_10(_, _close_1, error, pcall(function() |
| 264 | local _ = def(function() | 274 | local _ = def(function() |
| 265 | return print(1) | 275 | return print(1) |
| 266 | end) | 276 | end) |
| 267 | local _close_2 = assert(getmetatable(_).__close) | 277 | local _close_2 = assert(getmetatable(_).__close) |
| 268 | return _anon_func_9(_, _close_2, error, pcall(function(...) end, ...)) | 278 | return _anon_func_11(_, _close_2, error, pcall(_anon_func_12)) |
| 269 | end, ...)) | 279 | end)) |
| 270 | end, ...)) | 280 | end)) |
| 271 | end | 281 | end |
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index de41b45..a443f39 100644 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp | |||
| @@ -4352,21 +4352,11 @@ private: | |||
| 4352 | } | 4352 | } |
| 4353 | popScope(); | 4353 | popScope(); |
| 4354 | auto okVar = getUnusedName("_ok_"sv); | 4354 | auto okVar = getUnusedName("_ok_"sv); |
| 4355 | std::string pCallStmtStr; | 4355 | std::string pCallStmtStr = okVar + ", ... = try\n\tnil"s; |
| 4356 | if (!_varArgs.empty() && _varArgs.top().hasVar) { | ||
| 4357 | pCallStmtStr = okVar + ", ... = pcall((...)->, ...)"s; | ||
| 4358 | } else { | ||
| 4359 | pCallStmtStr = okVar + ", ... = pcall(->)"s; | ||
| 4360 | } | ||
| 4361 | auto pCallStmt = toAst<Statement_t>(pCallStmtStr, x); | 4356 | auto pCallStmt = toAst<Statement_t>(pCallStmtStr, x); |
| 4362 | auto pCallExp = ast_to<Exp_t>(pCallStmt->content.to<ExpListAssign_t>()->action.to<Assign_t>()->values.back()); | 4357 | auto pCallExp = ast_to<Exp_t>(pCallStmt->content.to<ExpListAssign_t>()->action.to<Assign_t>()->values.back()); |
| 4363 | auto value = singleValueFrom(pCallExp); | 4358 | auto value = singleValueFrom(pCallExp); |
| 4364 | auto invoke = ast_to<Invoke_t>(value->item.to<ChainValue_t>()->items.back()); | 4359 | value->item.to<SimpleValue_t>()->value.to<Try_t>()->func.set(followingBlock); |
| 4365 | auto pCallValue = singleValueFrom(ast_to<Exp_t>(invoke->args.front())); | ||
| 4366 | auto pCallFunc = pCallValue->item.to<SimpleValue_t>()->value.to<FunLit_t>(); | ||
| 4367 | auto pCallBody = x->new_ptr<Body_t>(); | ||
| 4368 | pCallBody->content.set(followingBlock); | ||
| 4369 | pCallFunc->body.set(pCallBody); | ||
| 4370 | for (const auto& stmt : getCloses) { | 4360 | for (const auto& stmt : getCloses) { |
| 4371 | newBlock->statements.push_back(toAst<Statement_t>(stmt, x)); | 4361 | newBlock->statements.push_back(toAst<Statement_t>(stmt, x)); |
| 4372 | } | 4362 | } |
| @@ -9028,6 +9018,7 @@ private: | |||
| 9028 | BREAK_IF(tryBlock->statements.size() != 1); | 9018 | BREAK_IF(tryBlock->statements.size() != 1); |
| 9029 | auto stmt = static_cast<Statement_t*>(tryBlock->statements.front()); | 9019 | auto stmt = static_cast<Statement_t*>(tryBlock->statements.front()); |
| 9030 | auto expListAssign = stmt->content.as<ExpListAssign_t>(); | 9020 | auto expListAssign = stmt->content.as<ExpListAssign_t>(); |
| 9021 | BREAK_IF(!expListAssign); | ||
| 9031 | BREAK_IF(expListAssign->action); | 9022 | BREAK_IF(expListAssign->action); |
| 9032 | auto value = singleValueFrom(expListAssign->expList); | 9023 | auto value = singleValueFrom(expListAssign->expList); |
| 9033 | BREAK_IF(!value); | 9024 | BREAK_IF(!value); |
| @@ -9052,13 +9043,17 @@ private: | |||
| 9052 | auto invoke = ast_to<Invoke_t>(xpcall->items.back()); | 9043 | auto invoke = ast_to<Invoke_t>(xpcall->items.back()); |
| 9053 | invoke->args.push_back(toAst<Exp_t>(funcName, x)); | 9044 | invoke->args.push_back(toAst<Exp_t>(funcName, x)); |
| 9054 | invoke->args.push_back(errHandler); | 9045 | invoke->args.push_back(errHandler); |
| 9055 | invoke->args.dup(toAst<ExpList_t>(join(args, ","sv), x)->exprs); | 9046 | if (!args.empty()) { |
| 9047 | invoke->args.dup(toAst<ExpList_t>(join(args, ","sv), x)->exprs); | ||
| 9048 | } | ||
| 9056 | transformChainValue(xpcall, out, ExpUsage::Closure); | 9049 | transformChainValue(xpcall, out, ExpUsage::Closure); |
| 9057 | } else { | 9050 | } else { |
| 9058 | auto pcall = toAst<ChainValue_t>("pcall()", x); | 9051 | auto pcall = toAst<ChainValue_t>("pcall()", x); |
| 9059 | auto invoke = ast_to<Invoke_t>(pcall->items.back()); | 9052 | auto invoke = ast_to<Invoke_t>(pcall->items.back()); |
| 9060 | invoke->args.push_back(toAst<Exp_t>(funcName, x)); | 9053 | invoke->args.push_back(toAst<Exp_t>(funcName, x)); |
| 9061 | invoke->args.dup(toAst<ExpList_t>(join(args, ","sv), x)->exprs); | 9054 | if (!args.empty()) { |
| 9055 | invoke->args.dup(toAst<ExpList_t>(join(args, ","sv), x)->exprs); | ||
| 9056 | } | ||
| 9062 | transformChainValue(pcall, out, ExpUsage::Closure); | 9057 | transformChainValue(pcall, out, ExpUsage::Closure); |
| 9063 | } | 9058 | } |
| 9064 | if (usage == ExpUsage::Common) { | 9059 | if (usage == ExpUsage::Common) { |
