From 1890294226034d27165af016c8c93a484d978b49 Mon Sep 17 00:00:00 2001 From: Li Jin <dragon-fly@qq.com> Date: Thu, 23 May 2024 16:30:05 +0800 Subject: prevent more anonymous functions generating from `const`, `close` decl. --- spec/outputs/5.1/attrib.lua | 115 +++++++++++++++++++--------------------- spec/outputs/attrib.lua | 94 ++++++++++++++++---------------- spec/outputs/compile_doc.lua | 70 ++++++++++++------------ spec/outputs/unicode/attrib.lua | 96 ++++++++++++++++----------------- src/yuescript/yue_compiler.cpp | 48 ++++++++++++----- 5 files changed, 221 insertions(+), 202 deletions(-) diff --git a/spec/outputs/5.1/attrib.lua b/spec/outputs/5.1/attrib.lua index 8361b24..c48c72c 100644 --- a/spec/outputs/5.1/attrib.lua +++ b/spec/outputs/5.1/attrib.lua @@ -55,22 +55,16 @@ local _anon_func_0 = function(_close_1, error, f, _arg_0, ...) end end end -local _anon_func_1 = function(io) - local _with_0 = io.open("file.txt") - _with_0:write("Hello") - return _with_0 -end -local _anon_func_2 = function() end +local _anon_func_1 = function() end do - local v = (function() - if flag then - return func() - else - return setmetatable({ }, { - __close = function(self) end - }) - end - end)() + local v + if flag then + v = func() + else + v = setmetatable({ }, { + __close = function(self) end + }) + end local _close_0 = assert(getmetatable(v).__close); (function(_arg_0, ...) local _ok_0 = _arg_0 @@ -81,12 +75,17 @@ do return error(...) end end)(pcall(function() - local f = _anon_func_1(io) + local f + do + local _with_0 = io.open("file.txt") + _with_0:write("Hello") + f = _with_0 + end local _close_1 = assert(getmetatable(f).__close) - return _anon_func_0(_close_1, error, f, pcall(_anon_func_2)) + return _anon_func_0(_close_1, error, f, pcall(_anon_func_1)) end)) end -local _anon_func_3 = function(_close_1, d, error, _arg_0, ...) +local _anon_func_2 = function(_close_1, d, error, _arg_0, ...) do local _ok_0 = _arg_0 _close_1(d) @@ -97,41 +96,25 @@ local _anon_func_3 = function(_close_1, d, error, _arg_0, ...) end end end -local _anon_func_4 = function(x) - if true then - if "abc" == x then - return 998 - end - end -end -local _anon_func_6 = function(a, b) +local _anon_func_3 = function(a, b) if a ~= nil then return a else return b end end -local _anon_func_5 = function(a, b) - if _anon_func_6(a, b) then - return { - value = value - } - end -end -local _anon_func_7 = function() end +local _anon_func_4 = function() end do - local a = (function() - if true then - return 1 - end - end)() - local b = (function() - if not false then - if x then - return 1 - end + local a + if true then + a = 1 + end + local b + if not false then + if x then + b = 1 end - end)() + end local _close_0 = assert(getmetatable(b).__close); (function(_arg_0, ...) local _ok_0 = _arg_0 @@ -142,13 +125,24 @@ do return error(...) end end)(pcall(function() - local c = _anon_func_4(x) - local d = _anon_func_5(a, b) + local c + if true then + local _exp_0 = x + if "abc" == _exp_0 then + c = 998 + end + end + local d + if _anon_func_3(a, b) then + d = { + value = value + } + end local _close_1 = assert(getmetatable(d).__close) - return _anon_func_3(_close_1, d, error, pcall(_anon_func_7)) + return _anon_func_2(_close_1, d, error, pcall(_anon_func_4)) end)) end -local _anon_func_8 = function(_, _close_1, error, _arg_0, ...) +local _anon_func_5 = function(_, _close_1, error, _arg_0, ...) do local _ok_0 = _arg_0 _close_1(_) @@ -159,7 +153,7 @@ local _anon_func_8 = function(_, _close_1, error, _arg_0, ...) end end end -local _anon_func_9 = function(_, _close_2, error, _arg_0, ...) +local _anon_func_6 = function(_, _close_2, error, _arg_0, ...) do local _ok_0 = _arg_0 _close_2(_) @@ -171,11 +165,12 @@ local _anon_func_9 = function(_, _close_2, error, _arg_0, ...) end end do - local _ = (function() + local _ + do local _with_0 = io.open("file.txt") _with_0:write("Hello") - return _with_0 - end)() + _ = _with_0 + end local _close_0 = assert(getmetatable(_).__close); (function(_arg_0, ...) local _ok_0 = _arg_0 @@ -192,14 +187,14 @@ do end }) local _close_1 = assert(getmetatable(_).__close) - return _anon_func_8(_, _close_1, error, pcall(function() + return _anon_func_5(_, _close_1, error, pcall(function() local _ = setmetatable({ }, { __close = function() return print("first") end }) local _close_2 = assert(getmetatable(_).__close) - return _anon_func_9(_, _close_2, error, pcall(function() + return _anon_func_6(_, _close_2, error, pcall(function() return print("third") end)) end)) @@ -216,7 +211,7 @@ def = function(item) _defers[#_defers + 1] = item return _defers end -local _anon_func_10 = function(_, _close_1, error, _arg_0, ...) +local _anon_func_7 = function(_, _close_1, error, _arg_0, ...) do local _ok_0 = _arg_0 _close_1(_) @@ -227,7 +222,7 @@ local _anon_func_10 = function(_, _close_1, error, _arg_0, ...) end end end -local _anon_func_11 = function(_, _close_2, error, _arg_0, ...) +local _anon_func_8 = function(_, _close_2, error, _arg_0, ...) do local _ok_0 = _arg_0 _close_2(_) @@ -238,7 +233,7 @@ local _anon_func_11 = function(_, _close_2, error, _arg_0, ...) end end end -local _anon_func_12 = function() end +local _anon_func_9 = function() end do local _ = def(function() return print(3) @@ -257,12 +252,12 @@ do return print(2) end) local _close_1 = assert(getmetatable(_).__close) - return _anon_func_10(_, _close_1, error, pcall(function() + return _anon_func_7(_, _close_1, error, pcall(function() local _ = def(function() return print(1) end) local _close_2 = assert(getmetatable(_).__close) - return _anon_func_11(_, _close_2, error, pcall(_anon_func_12)) + return _anon_func_8(_, _close_2, error, pcall(_anon_func_9)) end)) end)) end diff --git a/spec/outputs/attrib.lua b/spec/outputs/attrib.lua index 626944e..e48963c 100644 --- a/spec/outputs/attrib.lua +++ b/spec/outputs/attrib.lua @@ -34,62 +34,62 @@ do a, b = _obj_0[1], _obj_0[2] end do - local v <close> = (function() - if flag then - return func() - else - return setmetatable({ }, { - __close = function(self) end - }) - end - end)() - local f <close> = (function() - local _with_0 = io.open("file.txt") - _with_0:write("Hello") - return _with_0 - end)() + local v + if flag then + v = func() + else + v = setmetatable({ }, { + __close = function(self) end + }) + end + local _close_0 <close> = v + local f + local _with_0 = io.open("file.txt") + _with_0:write("Hello") + f = _with_0 + local _close_1 <close> = f end do - local a <const> = (function() - if true then - return 1 - end - end)() - local b <close> = (function() - if not false then - if x then - return 1 - end + local a + if true then + a = 1 + end + local b + if not false then + if x then + b = 1 end - end)() - local c <const> = (function() - if true then - local _exp_0 = x - if "abc" == _exp_0 then - return 998 - end + end + local _close_0 <close> = b + local c + if true then + local _exp_0 = x + if "abc" == _exp_0 then + c = 998 end - end)() - local d <close> = (function() - if (function() - if a ~= nil then - return a - else - return b - end - end)() then - return { - value = value - } + end + local d + if (function() + if a ~= nil then + return a + else + return b end - end)() + end)() then + d = { + value = value + } + end + local _close_1 <close> = d end do - local _ <close> = (function() + local _ + do local _with_0 = io.open("file.txt") _with_0:write("Hello") - return _with_0 - end)() + _ = _with_0 + end + local _close_0 <close> = _ local _ <close> = setmetatable({ }, { __close = function() return print("second") diff --git a/spec/outputs/compile_doc.lua b/spec/outputs/compile_doc.lua index 29f4aeb..3781fb9 100644 --- a/spec/outputs/compile_doc.lua +++ b/spec/outputs/compile_doc.lua @@ -12,42 +12,42 @@ local _list_0 = { for _index_0 = 1, #_list_0 do local _des_0 = _list_0[_index_0] local compiledFile, docFile = _des_0[1], _des_0[2] - local input <close> = (function() - local _with_0 = io.open(docFile) - if _with_0 ~= nil then - local to_lua = require("yue").to_lua - local text = _with_0:read("*a") - local codes = { } - for code in text:gmatch("```moonscript(.-)```") do - local result, err = to_lua(code, { - implicit_return_root = false, - reserve_line_number = false - }) - if result then - codes[#codes + 1] = result - elseif not err:match("macro exporting module only accepts macro definition") then - print(err) - os.exit(1) - end + local input + local _with_0 = io.open(docFile) + if _with_0 ~= nil then + local to_lua = require("yue").to_lua + local text = _with_0:read("*a") + local codes = { } + for code in text:gmatch("```moonscript(.-)```") do + local result, err = to_lua(code, { + implicit_return_root = false, + reserve_line_number = false + }) + if result then + codes[#codes + 1] = result + elseif not err:match("macro exporting module only accepts macro definition") then + print(err) + os.exit(1) end - for code in text:gmatch("<pre>(.-)</pre>") do - local result, err = to_lua(code:gsub("<", "<"):gsub(">", ">"), { - implicit_return_root = false, - reserve_line_number = false - }) - if result then - codes[#codes + 1] = result - else - print(err) - os.exit(1) - end + end + for code in text:gmatch("<pre>(.-)</pre>") do + local result, err = to_lua(code:gsub("<", "<"):gsub(">", ">"), { + implicit_return_root = false, + reserve_line_number = false + }) + if result then + codes[#codes + 1] = result + else + print(err) + os.exit(1) end - local output <close> = (function() - local _with_1 = io.open(tostring(outputFolder) .. "/" .. tostring(compiledFile), "w+") - _with_1:write(table.concat(codes)) - return _with_1 - end)() end - return _with_0 - end)() + local output + local _with_1 = io.open(tostring(outputFolder) .. "/" .. tostring(compiledFile), "w+") + _with_1:write(table.concat(codes)) + output = _with_1 + local _close_0 <close> = output + end + input = _with_0 + local _close_0 <close> = input end diff --git a/spec/outputs/unicode/attrib.lua b/spec/outputs/unicode/attrib.lua index 58ad4b2..1c48de4 100644 --- a/spec/outputs/unicode/attrib.lua +++ b/spec/outputs/unicode/attrib.lua @@ -26,63 +26,63 @@ do _u5143_u7d20d = _obj_2[1] end do - local _u5173_u95ed_u53d8_u91cfv <close> = (function() - if _u6807_u8bb0_u4e3a_u771f then - return _u51fd_u6570_u8c03_u7528() - else - return setmetatable({ }, { - __close = function(self) end - }) - end - end)() - local _u5173_u95ed_u53d8_u91cff <close> = (function() - local _with_0 = io.open("文件.txt") - _with_0:write("你好") - return _with_0 - end)() + local _u5173_u95ed_u53d8_u91cfv + if _u6807_u8bb0_u4e3a_u771f then + _u5173_u95ed_u53d8_u91cfv = _u51fd_u6570_u8c03_u7528() + else + _u5173_u95ed_u53d8_u91cfv = setmetatable({ }, { + __close = function(self) end + }) + end + local _close_0 <close> = _u5173_u95ed_u53d8_u91cfv + local _u5173_u95ed_u53d8_u91cff + local _with_0 = io.open("文件.txt") + _with_0:write("你好") + _u5173_u95ed_u53d8_u91cff = _with_0 + local _close_1 <close> = _u5173_u95ed_u53d8_u91cff end do - local _u5e38_u91cfa <const> = (function() - if true then - return 1 - end - end)() - local _u5173_u95ed_u53d8_u91cfb <close> = (function() - if not false then - if _u6761_u4ef6x then - return 1 - end + local _u5e38_u91cfa + if true then + _u5e38_u91cfa = 1 + end + local _u5173_u95ed_u53d8_u91cfb + if not false then + if _u6761_u4ef6x then + _u5173_u95ed_u53d8_u91cfb = 1 end - end)() - local _u5e38_u91cfc <const> = (function() - if true then - local _exp_0 = _u6761_u4ef6x - if "abc" == _exp_0 then - return 998 - end + end + local _close_0 <close> = _u5173_u95ed_u53d8_u91cfb + local _u5e38_u91cfc + if true then + local _exp_0 = _u6761_u4ef6x + if "abc" == _exp_0 then + _u5e38_u91cfc = 998 end - end)() - local _u5173_u95ed_u53d8_u91cfd <close> = (function() - if (function() - local _exp_0 = _u6761_u4ef6a - if _exp_0 ~= nil then - return _exp_0 - else - return _u6761_u4ef6b - end - end)() then - return { - ["数值"] = _u6570_u503c - } + end + local _u5173_u95ed_u53d8_u91cfd + if (function() + local _exp_0 = _u6761_u4ef6a + if _exp_0 ~= nil then + return _exp_0 + else + return _u6761_u4ef6b end - end)() + end)() then + _u5173_u95ed_u53d8_u91cfd = { + ["数值"] = _u6570_u503c + } + end + local _close_1 <close> = _u5173_u95ed_u53d8_u91cfd end do - local __u65e0_u6548_u53d8_u91cf <close> = (function() + local __u65e0_u6548_u53d8_u91cf + do local _with_0 = io.open("文件.txt") _with_0:write("你好") - return _with_0 - end)() + __u65e0_u6548_u53d8_u91cf = _with_0 + end + local _close_0 <close> = __u65e0_u6548_u53d8_u91cf local __u65e0_u6548_u53d8_u91cf <close> = setmetatable({ }, { __close = function() return _u6253_u5370("第二") diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index 7f6a042..04874d5 100644 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp @@ -75,7 +75,7 @@ static std::unordered_set<std::string> Metamethods = { "close"s // Lua 5.4 }; -const std::string_view version = "0.23.6"sv; +const std::string_view version = "0.23.7"sv; const std::string_view extension = "yue"sv; class CompileError : public std::logic_error { @@ -10294,10 +10294,25 @@ private: if (j != je) ++j; } bool checkValuesLater = false; - if (listA->names.size() > assignA->values.size()) { + for (ast_node* value : assignA->values.objects()) { + if (ast_is<Exp_t>(value)) { + if (auto sVal = singleValueFrom(value)) { + if (auto spValue = sVal->item.as<SimpleValue_t>()) { + if (auto funLit = spValue->value.as<FunLit_t>()) { + if (!funLit->noRecursion) { + checkValuesLater = true; + } + break; + } + } + } + } + } + if (!checkValuesLater && assignA->values.size() > 0 && listA->names.size() >= assignA->values.size()) { BLOCK_START switch (assignA->values.back()->get_id()) { case id<If_t>(): + case id<With_t>(): case id<Switch_t>(): checkValuesLater = true; break; @@ -10305,24 +10320,33 @@ private: BREAK_IF(checkValuesLater); auto value = singleValueFrom(assignA->values.back()); if (!value) { - _buf << listA->names.size() << " right values expected, got "sv << assignA->values.size(); - throw CompileError(clearBuf(), assignA->values.front()); + if (listA->names.size() > assignA->values.size()) { + _buf << listA->names.size() << " right values expected, got "sv << assignA->values.size(); + throw CompileError(clearBuf(), assignA->values.front()); + } else { + break; + } } if (auto val = value->item.as<SimpleValue_t>()) { switch (val->value->get_id()) { - case id<If_t>(): - case id<Switch_t>(): - case id<Do_t>(): - case id<Try_t>(): + case id<TableLit_t>(): + case id<ConstValue_t>(): + case id<UnaryValue_t>(): + case id<Num_t>(): + case id<VarArg_t>(): + break; + default: checkValuesLater = true; break; } BREAK_IF(checkValuesLater); } - auto chainValue = value->item.as<ChainValue_t>(); - if (!chainValue || !ast_is<Invoke_t, InvokeArgs_t>(chainValue->items.back())) { - _buf << listA->names.size() << " right values expected, got "sv << assignA->values.size(); - throw CompileError(clearBuf(), assignA->values.front()); + if (listA->names.size() > assignA->values.size()) { + auto chainValue = value->item.as<ChainValue_t>(); + if (!chainValue || !ast_is<Invoke_t, InvokeArgs_t>(chainValue->items.back())) { + _buf << listA->names.size() << " right values expected, got "sv << assignA->values.size(); + throw CompileError(clearBuf(), assignA->values.front()); + } } BLOCK_END } -- cgit v1.2.3-55-g6feb