Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions spec/lang/compat/lua_versions_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,20 @@ describe("Lua version compatibility", function()
local x = bit32.band(2, (bit32.bor(bit32.rshift(c, bit32.bnot(4)), 0xff)))
]], "5.1"))

it("distinguishes unary and binary '~' operators", util.gen([[


local c = 0xcafebabe
local x = c ~ 0xff
local y = ~c ~ c
]], [[
local bit32 = bit32; if not bit32 then local p, m = pcall(require, 'bit32'); if p then bit32 = m end end

local c = 0xcafebabe
local x = bit32.bxor(c, 0xff)
local y = bit32.bxor(bit32.bnot(c), c)
]], "5.1"))

it("generates compat code for bitwise unary operator metamethods", util.gen([[

local type Rec = record
Expand Down Expand Up @@ -100,6 +114,42 @@ describe("Lua version compatibility", function()
print(_tl_mt("__shl", 1, r, s))
]], "5.1"))

it("generates compat code for the binary '~' operator metamethod", util.gen([[

local type Rec = record
x: number
metamethod __bxor: function(Rec, Rec): number
end

local rec_mt: metatable<Rec> = {
__bxor = function(a: Rec, b: Rec): number
return a.x + b.x
end
}

local r = setmetatable({} as Rec, rec_mt)
local s = setmetatable({} as Rec, rec_mt)

print(r ~ s)
]], [[
local _tl_mt = function(m, s, a, b) return (getmetatable(s == 1 and a or b)[m](a, b)) end





local rec_mt = {
__bxor = function(a, b)
return a.x + b.x
end,
}

local r = setmetatable({}, rec_mt)
local s = setmetatable({}, rec_mt)

print(_tl_mt("__bxor", 1, r, s))
]], "5.1"))

-- varargs
it("generates compatibility code for named varargs with Lua 5.1", util.gen([[

Expand Down
4 changes: 2 additions & 2 deletions spec/util.lua
Original file line number Diff line number Diff line change
Expand Up @@ -743,12 +743,12 @@ local function gen(lax, code, expected, gen_target, type_errors)
local expected_code = util.dedent(expected):match("^(.-)%s*$")

local expected_lines = {}
for line in expected_code:gmatch("([^\n]*)\n") do
for line in expected_code:gmatch("([^\n]*)\n?") do
table.insert(expected_lines, line)
end

local output_lines = {}
for line in output_code:gmatch("([^\n]*)\n") do
for line in output_code:gmatch("([^\n]*)\n?") do
table.insert(output_lines, line)
end

Expand Down
3 changes: 2 additions & 1 deletion teal.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11277,7 +11277,8 @@ local function adjust_code(ast, needs_compat, gen_compat, gen_target)
needs_compat[key] = true
end
end
elseif node.op.op == "~" and gen_target == "5.1" then

elseif node.op.op == "~" and node.op.arity == 1 and gen_target == "5.1" then
if node.op.meta_on_operand then
needs_compat["mt"] = true
convert_node_to_compat_mt_call(node, unop_to_metamethod[node.op.op], 1, node.e1)
Expand Down
3 changes: 2 additions & 1 deletion teal/gen/lua_compat.lua
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,8 @@ local function adjust_code(ast, needs_compat, gen_compat, gen_target)
needs_compat[key] = true
end
end
elseif node.op.op == "~" and gen_target == "5.1" then

elseif node.op.op == "~" and node.op.arity == 1 and gen_target == "5.1" then
if node.op.meta_on_operand then
needs_compat["mt"] = true
convert_node_to_compat_mt_call(node, unop_to_metamethod[node.op.op], 1, node.e1)
Expand Down
3 changes: 2 additions & 1 deletion teal/gen/lua_compat.tl
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,8 @@ local function adjust_code(ast: Node, needs_compat: {string:boolean}, gen_compat
needs_compat[key] = true
end
end
elseif node.op.op == "~" and gen_target == "5.1" then
-- unary '~' only; binary '~' is bxor, handled below
elseif node.op.op == "~" and node.op.arity == 1 and gen_target == "5.1" then
if node.op.meta_on_operand then
needs_compat["mt"] = true
convert_node_to_compat_mt_call(node, unop_to_metamethod[node.op.op], 1, node.e1)
Expand Down
3 changes: 2 additions & 1 deletion tl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11531,7 +11531,8 @@ local function adjust_code(ast, needs_compat, gen_compat, gen_target)
needs_compat[key] = true
end
end
elseif node.op.op == "~" and gen_target == "5.1" then

elseif node.op.op == "~" and node.op.arity == 1 and gen_target == "5.1" then
if node.op.meta_on_operand then
needs_compat["mt"] = true
convert_node_to_compat_mt_call(node, unop_to_metamethod[node.op.op], 1, node.e1)
Expand Down
Loading