Module:User:Cscott/compat

return (function local builders = {} local function register(name, f) builders[name] = f end register('advent.compat', function(myrequire) -- Compatibility functions -- (Things present in Lua 5.3 that are missing in Lua 5.1) local compat = {}

local string = myrequire('string') local table = myrequire('table')

function compat.len(v) -- the length metamethod is only available starting in Lua 5.2 if type(v) == 'table' then local mt = getmetatable(v) if mt ~= nil then local len = mt.__len if len ~= nil then return len(v) end end end return #v end

function compat.combineBytes(msb, lsb) -- (msb << 8) | lsb return (msb * 256) + lsb end

function compat.splitBytes(u16) -- u16 >> 8, u16 & 0xFF local lsb = math.fmod(u16, 256) local msb = (u16 - lsb) / 256 return msb, lsb end

function compat.rshift(x, disp) -- x >> disp return math.floor(x/(2^disp)) end

function compat.idiv(a, b) local tya, tyb = type(a), type(b) if tya ~= 'number' or tyb ~= 'number' then local op = nil local mt = getmetatable(a) if mt ~= nil then op = mt.__idiv end if op == nil then mt = getmetatable(b) if mt ~= nil then op = mt.__idiv end end if op ~= nil then return op(a, b)   end end return math.floor(a / b) end

function compat.utf8codes(s) local len = #s local f = function(state, _) local pos = state.nextpos if pos > len then return nil, nil end local c1 = string.byte(s, pos) if c1 <= 0x7F then state.nextpos = pos + 1 return pos, c1     end local c2 = string.byte(s, pos + 1) if c1 <= 0xDF then state.nextpos = pos + 2 return pos, ((c1 % 0x20 ) * 0x40) + (c2 % 0x40) end local c3 = string.byte(s, pos + 2) if c1 <= 0xEF then state.nextpos = pos + 3 return pos, (((c1 % 0x10) * 0x40) + (c2 % 0x40)) * 0x40 + (c3 % 0x40) end local c4 = string.byte(s, pos + 3) if c1 <= 0xF7 then state.nextpos = pos + 4 return pos, ((((c1 % 0x08) * 0x40) + (c2 % 0x40)) * 0x40 + (c3 % 0x40)) * 0x40 + (c4 % 0x40) end error("bad utf-8") end return f, { nextpos = 1 }, 0 end

function compat.utf8char(...) -- utf8.char(c) local result = {} for _,c in ipairs{...} do     local s      if c <= 0x7F then s = string.char(c) else local c1 = c % 0x40 local cN = (c - c1) / 0x40 if c <= 0x7FF then s = string.char(              cN + 0xC0,               c1 + 0x80            ) else local c2 = cN % 0x40 cN = (cN - c2) / 0x40 if c <= 0xFFFF then s = string.char(                 cN + 0xE0,                  c2 + 0x80,                  c1 + 0x80               ) else local c3 = cN % 0x40 cN = (cN - c3) / 0x40 if c <= 0x10FFFF then s = string.char(                    cN + 0xF0,                     c3 + 0x80,                     c2 + 0x80,                     c1 + 0x80                  ) else error end end end end table.insert(result, s)  end return table.concat(result) end

-- unpack is a global function for Lua 5.1, otherwise use table.unpack compat.unpack = table.unpack or function(tbl, i, j) local unpack = rawget(_G, "unpack") -- we also need to use compat.len to get the length of this table! if i == nil then i = 1 end if j == nil then j = compat.len(tbl) end return unpack(tbl, i, j) end -- table.pack was added in Lua 5.2 compat.pack = table.pack or function(...) local t = { ... }  t.n = select("#",...) return t end

-- table.move was added in Lua 5.3 compat.move = table.move or function(a1, f, e, t, a2) if a2 == nil then a2 = a1 end local tmp = {} for i=f,e do   tmp[1+i-f] = a1[i] end for i=f,e do   a2[t+i-f] = tmp[1+i-f] end return a2 end

return compat

end)

local modules = {} modules['bit32'] = require('bit32') modules['string'] = require('string') modules['strict'] = {} modules['table'] = require('table') local function myrequire(name) if modules[name] == nil then modules[name] = true modules[name] = (builders[name])(myrequire) end return modules[name] end return myrequire('advent.compat') end)