Files
Techmino/polyfill.lua
2023-06-14 14:35:08 +08:00

3392 lines
66 KiB
Lua

-- Written by Rabia Alhaffar in 24/February/2021
-- polyfill.lua, Polyfills for Lua and LuaJIT in one file!
-- Updated: 11/April/2021
--[[
MIT License
Copyright (c) 2021 - 2022 Rabia Alhaffar
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
]]
-- require
if (not require) and package then
require = function(p)
if package.loaded[p] then
return package.loaded[p]
else
return package.searchpath(p, "./?/?.lua;./?.lua;./?.lc;./"..package.loaddir.."/?/init.lua"..";./"..package.loaddir.."/?.lua")
end
end
end
local polyfill = {
_VERSION = 0.1,
_AUTHOR = "Rabia Alhaffar (steria773/@Rabios)",
_AUTHOR_URL = "https://github.com/Rabios",
_URL = "https://github.com/Rabios/polyfill.lua",
_LICENSE = "MIT",
_DATE = "3/March/2021",
_LUAJIT = ((require("jit") or jit) and true or false),
}
local ffi = ((require("ffi") or require("luaffi") or ffi) or nil) --> Do we have FFI?
if not _VERSION then
_VERSION = "Lua 5.1"
end
-- module: ffi
-- Partial FFI polyfill for LuaJIT (And PUC-RIO's Lua if yours have FFI installed)
if ffi then
-- ffi.string
if not ffi.string then
ffi.string = function(s)
local str = ffi.new("char[?]", #s)
ffi.copy(str, s)
return str
end
end
-- ffi.os
if polyfill._LUAJIT then
if not ffi.os then
ffi.os = (require("jit").os or jit.os)
end
end
-- ffi.arch
if not ffi.arch then
if (0xfffffffff == 0xffffffff) then
ffi.arch = "x86"
else
ffi.arch = "x64"
end
end
end
-- module: Runtime (Global functions)
-- Functions
-- setglobal
if not setglobal then
setglobal = function(var, val)
_G[var] = val
end
end
-- getglobal
if not getglobal then
getglobal = function(var)
return _G[var]
end
end
-- rawgetglobal
if not rawgetglobal then
rawgetglobal = function(var)
return _G[var]
end
end
-- rawsetglobal
if not rawsetglobal then
rawsetglobal = function(var, val)
_G[var] = val
end
end
-- globals
if not globals then
globals = function(t)
if not t then
return _G
else
_G = t
end
end
end
-- newtag
if not newtag then
newtag = function()
return { __index = self }
end
end
-- setfallback
if not setfallback then
setfallback = function(fname, f)
_G[fname] = f
end
end
-- select
if not select then
select = function(n, ...)
local args = { ... }
return args[n]
end
end
-- _ALERT
if not _ALERT then
_ALERT = function(msg)
local n = select("#", msg)
for i = 1, n do
local v = tostring(select(i, msg))
io.stderr:write(v)
if i ~= n then
io.stderr:write("\t")
end
end
io.stderr:write("\n")
io.stderr:flush()
end
end
-- error
if not error then
error = function(msg)
coroutine.yield(msg)
end
end
-- print
if not print then
print = function(...)
local n = select("#", ...)
for i = 1, n do
local v = tostring(select(i, ...))
io.write(v)
if i ~= n then
io.write("\t")
end
end
io.write("\n")
io.flush()
end
end
-- next
if not next then
next = function(t, k)
local m = getmetatable(t)
local n = m and m.__next or next
return n(t, k)
end
end
-- nextvar
if not nextvar then
nextvar = function(name)
local m = _G[name]
local n = m and m.__next or nextvar
return n(_G, name)
end
end
-- tostring
if not tostring then
tostring = function(n)
return "\""..(n).."\""
end
end
-- tonumber (Requires FFI for atof function)
if not tonumber then
if ffi then
ffi.cdef("float atof(const char *_Str);")
tonumber = function(s)
return ffi.C.atof(s)
end
end
end
-- ipairs
if not ipairs then
iterate = function(t, i)
i = i + 1
local v = t[i]
if v then
return i, v
end
end
ipairs = function(t)
return iterate, t, 0
end
end
-- pairs
if not pairs then
pairs = function(t)
return next, t, nil
end
end
-- foreach
if not foreach then
foreach = function(t, f)
for k, v in pairs(t) do
f(k, v)
end
end
end
-- foreachi
if not foreachi then
foreachi = function(t, f)
for k, v in ipairs(t) do
f(k, v)
end
end
end
-- foreachvar
if not foreachvar then
foreachvar = function(f)
local n, v = nextvar(nil)
while n do
local res = f(n, v)
if res then
return res
end
n, v = nextvar(n)
end
end
end
-- gcinfo
if not gcinfo then
gcinfo = function()
return collectgarbage("count")
end
end
-- settag
if not settag then
settag = function(t, tag)
setmetatable(t, tag)
end
end
-- assert
if not assert then
assert = function(v, m)
if not v then
m = m or ""
error("assertion failed! " .. m)
end
end
end
-- loadfile
if not loadfile then
loadfile = function(src)
local file = io.open(src)
content = ""
if not (_VERSION == "Lua 5.4" or _VERSION == "Lua 5.3") then
content = file:read("*all")
else
content = file:read("*a")
end
file:close()
return function()
if assert(load(content), "Loading code string failed!") then
return load(content)
end
end
end
end
-- loadstring
if not loadstring then
loadstring = function(str)
if assert(load(str), "Loading code string failed!") then
return load(str)
end
end
end
-- dofile
if not dofile then
dofile = function(path)
if assert(loadfile(path), "Loading file " .. path .. " failed!\n") then
return loadfile(path)()
end
end
end
-- dostring
if not dostring then
dostring = function(str)
if assert(load(str), "Loading code string failed!") then
return load(str)
end
end
end
-- loadlib
if not loadlib then
if package.loadlib then
loadlib = function(lib, fname)
return package.loadlib(lib, fname)
end
end
end
-- rawlen
if not rawlen then
rawlen = function(o)
if o then
return #o
end
end
end
-- rawget
if not rawget then
rawget = function(t, i)
if t then
return t[i]
end
end
end
-- rawset
if not rawset then
rawset = function(t, i, v)
if t then
t[i] = v
end
end
end
-- rawequal
if not rawequal then
rawequal = function(a, b)
if (a and type(a) == "table") and (b and type(b) == "table") then
return (#a == #b)
end
end
end
-- copytagmethods
if not copytagmethods then
copytagmethods = function(from, to)
local funcs = {}
for k, v in pairs(getmetatable(from)) do
if (type(v) == "function") then
funcs[k] = v
end
end
for k, v in pairs(getmetatable(to)) do
getmetatable(to)[k] = funcs[k]
end
end
end
-- gettagmethod
if not gettagmethod then
gettagmethod = function(tag, method)
return getmetatable(tag)[method]
end
end
-- settagmethod
if not settagmethod then
settagmethod = function(tag, event, newmethod)
getmetatable(tag)[event] = newmethod or function() end
end
end
-- call
if not call then
call = function(f, args)
if (type(f) == "function") then
return f(table.unpack(args))
end
end
end
-- pcall
if not pcall then
pcall = function(f, ...)
local args = { ... }
local co = coroutine.create(f)
local err = coroutine.resume(co, table.unpack(args))
if (coroutine.status == "dead") then
return true
else
return false, err
end
end
end
-- xpcall
if not xpcall then
xpcall = function(f, msgh, ...)
local args = { ... }
local co = coroutine.create(f)
local err = coroutine.resume(co, table.unpack(args))
if (coroutine.status == "dead") then
return true
else
return false, "Error: " .. msgh
end
end
end
-- setenv
if not setenv then
setenv = function(t)
_ENV = t
--_G = t
end
end
-- getinfo
if not getinfo then
getinfo = debug.getinfo
end
-- getlocal
if not getlocal then
getlocal = debug.getlocal
end
-- setlocal
if not setlocal then
setlocal = debug.setlocal
end
-- getlinehook
if not getlinehook then
getlinehook = debug.gethook
end
-- setlinehook
if not setlinehook then
setlinehook = debug.sethook
end
-- rawgettable
if not rawgettable then
rawgettable = rawget
end
-- rawsettable
if not rawsettable then
rawsettable = rawset
end
-- debug.debug
if type(debug) == "function" then
local df = debug
debug = {}
debug.debug = df
end
-- module: table
table = require("table") or {}
-- Functions
-- table.insert
if not table.insert then
table.insert = function(t, i, v)
if not v then
t[#t + 1] = i
else
t[i] = v
end
end
end
-- tinsert
if not tinsert then
tinsert = function(t, i, v)
if not v then
t[#t + 1] = i
else
t[i] = v
end
end
end
-- table.remove
if not table.remove then
table.remove = function(t, i)
if not i then
i = #t
end
local result = t[i]
t[i] = nil
return result
end
end
-- tremove
if not tremove then
tremove = function(t, i)
if not i then
i = #t
end
local result = t[i]
t[i] = nil
return result
end
end
-- table.concat
if not table.concat then
table.concat = function(t, s)
local result = ""
for str in ipairs(t, str) do
if (type(t[str]) == "string") then
if (str == #t) then s = "" end
result = result..(t[str]..s)
elseif (type(t[str]) == "number") then
if (str == #t) then s = "" end
result = result..(tostring(t[str])..s)
end
end
return result
end
end
-- table.unpack
if not table.unpack then
table.unpack = function(t, i)
i = i or 1
if (i <= #t) then
return t[i], table.unpack(t, i + 1)
end
end
end
-- unpack
if not unpack then
unpack = function(t, i)
i = i or 1
if (t[i] ~= nil) then
return t[i], unpack(t, i + 1)
end
end
end
-- table.pack
if not table.pack then
table.pack = function(...)
local t = { ... }
t.n = #t
return t
end
end
-- table.move
if not table.move then
table.move = function(t1, f, e, t, t2)
local nums = (e - 1)
for i = 0, nums, 1 do
t2[t + i] = t1[f + i]
end
end
end
-- table.sort
if not table.sort then
table.sort = function(t, f)
f = f or nil
if #t < 2 then
return t
end
local pivot = t[1]
if (type(pivot) == "string") then
pivot = #t[1]
end
local a, b, c = {}, {}, {}
for _, v in ipairs(t) do
if (type(f) == "function") then
if (type(v) == "number") then
if (f(v, pivot) == true) then
a[#a + 1] = v
elseif(f(v, pivot) == false) then
c[#c + 1] = v
elseif (type(f(v, pivot)) ~= "boolean") then
b[#b + 1] = v
end
end
else
if (type(v) == "number") then
if v < pivot then
a[#a + 1] = v
elseif v > pivot then
c[#c + 1] = v
else
b[#b + 1] = v
end
elseif (type(v) == "string") then
if #v < pivot then
a[#a + 1] = v
elseif #v > pivot then
c[#c + 1] = v
else
b[#b + 1] = v
end
end
end
end
a = table.sort(a)
c = table.sort(c)
for _, v in ipairs(b) do a[#a + 1] = v end
for _, v in ipairs(c) do a[#a + 1] = v end
return a
end
end
-- sort
if not sort then
sort = function(t, f)
f = f or nil
if #t < 2 then
return t
end
local pivot = t[1]
if (type(pivot) == "string") then
pivot = #t[1]
end
local a, b, c = {}, {}, {}
for _, v in ipairs(t) do
if (type(f) == "function") then
if (type(v) == "number") then
if (f(v, pivot) == true) then
a[#a + 1] = v
elseif(f(v, pivot) == false) then
c[#c + 1] = v
elseif (type(f(v, pivot)) ~= "boolean") then
b[#b + 1] = v
end
end
else
if (type(v) == "number") then
if v < pivot then
a[#a + 1] = v
elseif v > pivot then
c[#c + 1] = v
else
b[#b + 1] = v
end
elseif (type(v) == "string") then
if #v < pivot then
a[#a + 1] = v
elseif #v > pivot then
c[#c + 1] = v
else
b[#b + 1] = v
end
end
end
end
a = sort(a)
c = sort(c)
for _, v in ipairs(b) do a[#a + 1] = v end
for _, v in ipairs(c) do a[#a + 1] = v end
return a
end
end
-- table.getn
if not table.getn then
table.getn = function(t)
if type(t.n) == "number" then
return t.n
end
local m = 0
for i, _ in t do
if (type(i) == "number" and i > max) then
m = i
end
end
return m
end
end
-- getn
if not getn then
getn = function(t)
if type(t.n) == "number" then
return t.n
end
local m = 0
for i, _ in t do
if (type(i) == "number" and i > max) then
m = i
end
end
return m
end
end
-- table.setn
if not table.setn then
table.setn = function(t, n)
setmetatable(t, {
__len = function()
return n
end
})
end
end
-- table.foreach
if not table.foreach then
table.foreach = function(t, f)
for k, v in pairs(t) do
if (type(f) == "function") then
f(k, v)
end
end
end
end
-- table.foreachi
if not table.foreachi then
table.foreachi = function(t, f)
for k, v in pairs(t) do
if (type(f) == "function") then
if (type(k) == "number") then
f(k, v)
end
end
end
end
end
-- table.maxn
if not table.maxn then
table.maxn = function(t)
local result = 0
for i, k in ipairs(t) do
if (i > result) then
result = i
end
end
return result
end
end
-- table_ext_solar2d.lua
-- Written by Rabia Alhaffar in 11/March/2021
-- Polyfill for some table functions from Corona SDK/Solar2D
-- Updated: 27/March/2021
if CoronaPrototype then
-- table.indexOf
if not table.indexOf then
table.indexOf = function(arr, elem)
for i = 1, #arr do
if arr[i] == elem then
return i
end
end
end
end
-- table.copy
if not table.copy then
table.copy = function(...)
local arg = { ... }
local result = {}
if #arg == 1 then
return arg[1]
else
for i = 1, #arg do
for j = 1, #arg[i] do
table.insert(result, arg[i][j])
end
end
end
return result
end
end
end
-- table_ext_amulet.lua
-- Written by Rabia Alhaffar in 11/March/2021
-- Polyfill for some table functions from Amulet
-- Updated: 27/March/2021
if (type(am) == "table") then
-- table.search
if not table.search then
table.search = function(arr, elem)
for i = 1, #arr do
if arr[i] == elem then
return i
end
end
end
end
-- table.clear
if not table.clear then
table.clear = function(t)
for k, v in pairs(t) do
if t[k] then
t[k] = nil
end
end
end
end
-- table.remove_all
if not table.remove_all then
table.remove_all = function(arr, elem)
for i = 1, #arr do
if arr[i] == elem then
arr[i] = nil
end
end
end
end
-- table.append
if not table.append then
table.append = function(t1, t2)
for i = 1, #t2 do
table.insert(t1, t2[i])
end
end
end
-- table.merge
if not table.merge then
table.merge = function(t1, t2)
for k, v in pairs(t2) do
t1[k] = t2[k]
end
end
end
-- table.keys
if not table.keys then
table.keys = function(t)
local result = {}
for k in pairs(t) do
table.insert(result, k)
end
end
return result
end
-- table.values
if not table.values then
table.values = function(t)
local result = {}
for k, v in pairs(t) do
table.insert(result, v)
end
end
return result
end
-- table.count
if not table.count then
table.count = function(t)
local result = 0
for k, v in pairs(t) do
if t[k] then
result = result + 1
end
end
return result
end
end
-- table.filter
if not table.filter then
table.filter = function(t, f)
local result = {}
for i = 1, #t do
local a = t[i]
local b = t[i + 1] or t[i]
if (f(a, b) == true) then
t[i] = a
t[i + 1] = b
else
t[i] = b
t[i + 1] = a
end
end
return result
end
end
-- table.tostring
if not table.tostring then
table.tostring = function(t)
local result = "{"
for k, v in pairs(t) do
if assert(type(tonumber(k)) == "number") then
result = result .. v .. ","
else
result = result .. "\"" .. k .. "\"" .. " = " .. v .. ","
end
end
result = result .. "}"
return result
end
end
-- table.shuffle
if not table.shuffle then
table.shuffle = function(t, r)
math.randomseed(os.time())
for i = #t, 2, -1 do
local j = r or math.random(i)
t[i], t[j] = t[j], t[i]
end
return t
end
end
end
-- module: package (Config for require function polyfill)
if package then
if ffi then
if not package.loaddir then
package.loaddir = "lualibs"
end
if not package.config then
if (ffi.os == "Windows") then
package.config = "\\\n;\n?\n!\n-"
else
package.config = "///n;/n?/n!/n-"
end
end
end
end
-- module: os (Requires FFI)
os = require("os") or {}
if ffi then
if ffi.arch == "x86" then
ffi.cdef([[
typedef long __time32_t;
typedef __time32_t time_t;
]])
elseif ffi.arch == "x64" then
ffi.cdef([[
typedef __int64 __time64_t;
typedef __time64_t time_t;
]])
end
ffi.cdef([[
typedef long clock_t;
time_t time(time_t *_Time);
char * ctime(const time_t *_Time);
int system(const char *_Command);
void exit(int _Code);
int rename(const char *_OldFilename, const char *_NewFilename);
int remove(const char *_Filename);
char* setlocale(int _Category, const char *_Locale);
char* getenv(const char *_VarName);
double difftime(time_t _Time1, time_t _Time2);
char tmpnam(char *_Buffer);
char *_strdate(char *_Buffer);
clock_t clock(void);
]])
end
-- os.time
if not os.time then
if ffi then
os.time = function()
return ffi.C.time(ffi.new("time_t *"))
end
end
end
-- os.execute
if not os.execute then
if ffi then
os.execute = function(cmd)
return (ffi.C.system(cmd) == 0)
end
end
end
-- execute
if not execute then
if ffi then
execute = function(cmd)
return (ffi.C.system(cmd) == 0)
end
end
end
-- os.exit
if not os.exit then
if ffi then
os.exit = function(c)
return ffi.C.exit(c or 0)
end
end
end
-- exit
if not exit then
if ffi then
exit = function(c)
return ffi.C.exit(c or 0)
end
end
end
-- os.rename
if not os.rename then
if ffi then
os.rename = function(o, n)
return (ffi.C.rename(o, n) == 0)
end
end
end
-- rename
if not rename then
if ffi then
rename = function(o, n)
return (ffi.C.rename(o, n) == 0)
end
end
end
-- os.remove
if not os.remove then
if ffi then
os.remove = function(f)
return (ffi.C.remove(f) == 0)
end
end
end
-- remove
if not remove then
if ffi then
remove = function(f)
return (ffi.C.remove(f) == 0)
end
end
end
-- os.setlocale
if not os.setlocale then
if ffi then
os.setlocale = function(v)
return ffi.string(ffi.C.setlocale(v))
end
end
end
-- setlocale
if not setlocale then
if ffi then
setlocale = function(v)
return ffi.string(ffi.C.setlocale(v))
end
end
end
-- os.getenv
if not os.getenv then
if ffi then
os.getenv = function(v)
return ffi.string(ffi.C.getenv(v))
end
end
end
-- getenv
if not getenv then
if ffi then
getenv = function(v)
return ffi.string(ffi.C.getenv(v))
end
end
end
-- os.difftime
if not os.difftime then
if ffi then
os.difftime = function(t1, t2)
return ffi.C.difftime(t1, t2)
end
end
end
-- os.tmpname
if not os.tmpname then
if ffi then
os.tmpname = function(str)
return ffi.string(ffi.C.tmpnam(str))
end
end
end
-- os.date
if not os.date == "nil" then
if ffi then
os.date = function(form)
return ffi.string(ffi.C._strdate(form))
end
end
end
-- date
if not date == "nil" then
if ffi then
date = function(form)
return ffi.string(ffi.C._strdate(form))
end
end
end
-- os.clock
if not os.clock then
if ffi then
os.clock = function()
return ffi.C.clock()
end
end
end
-- clock
if not clock then
if ffi then
clock = function()
return ffi.C.clock()
end
end
end
-- module: math
math = require("math") or {}
-- Variables
-- math.pi
if not math.pi then
math.pi = 3.14159265358979323846
end
-- PI
if not PI then
PI = 3.14159265358979323846
end
-- math.huge
if not math.huge then
math.huge = 1 / 0
end
-- math.mininteger
if not math.mininteger then
math.mininteger = -2147483648
end
-- math.maxinteger
if not math.maxinteger then
math.maxinteger = 2147483647
end
-- Functions
-- math.sqrt
if not math.sqrt then
if ffi then
ffi.cdef("double sqrt(double);")
math.sqrt = function(n)
return ffi.C.sqrt(n)
end
end
end
-- sqrt
if not sqrt then
if ffi then
ffi.cdef("double sqrt(double);")
sqrt = function(n)
return ffi.C.sqrt(n)
end
end
end
-- math.sinh
if not math.sinh then
if ffi then
ffi.cdef("double sinh(double);")
math.sinh = function(n)
return ffi.C.sinh(n)
end
end
end
-- math.cosh
if not math.cosh then
if ffi then
ffi.cdef("double cosh(double);")
math.cosh = function(n)
return ffi.C.cosh(n)
end
end
end
-- math.tanh
if not math.tanh then
if ffi then
ffi.cdef("double tanh(double);")
math.tanh = function(n)
return ffi.C.tanh(n)
end
end
end
-- math.asin
if not math.asin then
if ffi then
ffi.cdef("double asin(double);")
math.asin = function(n)
return ffi.C.asin(n)
end
else
math.asin = function(n)
return (n + (1 / 2) * (math.pow(n, 3) / 3) + ((1 * 3) / (2 * 4)) * (math.pow(n, 5) / 5) + ((1 * 3 * 5) / (2 * 4 * 6)) * (math.pow(n, 7) / 7))
end
end
end
-- asin
if not asin then
if ffi then
ffi.cdef("double asin(double);")
asin = function(n)
return ffi.C.asin(n)
end
else
asin = function(n)
return (n + (1 / 2) * (math.pow(n, 3) / 3) + ((1 * 3) / (2 * 4)) * (math.pow(n, 5) / 5) + ((1 * 3 * 5) / (2 * 4 * 6)) * (math.pow(n, 7) / 7))
end
end
end
-- math.acos
if not math.acos then
if ffi then
ffi.cdef("double acos(double);")
math.acos = function(n)
return ffi.C.acos(n)
end
else
math.acos = function(n)
return (-0.69813170079773212 * n * n - 0.87266462599716477) * n + 1.5707963267948966
end
end
end
-- acos
if not acos then
if ffi then
ffi.cdef("double acos(double);")
acos = function(n)
return ffi.C.acos(n)
end
else
acos = function(n)
return (-0.69813170079773212 * n * n - 0.87266462599716477) * n + 1.5707963267948966
end
end
end
-- math.atan
if not math.atan then
if ffi then
math.atan = function(...)
local args = { ... }
if (#args == 1) then
ffi.cdef("double atan(double);")
return ffi.C.atan(args[1])
elseif (#args == 2) then
ffi.cdef("double atan2(double, double);")
return ffi.C.atan2(args[1], args[2])
end
end
end
end
-- atan
if not atan then
if ffi then
atan = function(...)
local args = { ... }
if (#args == 1) then
ffi.cdef("double atan(double);")
return ffi.C.atan(args[1])
elseif (#args == 2) then
ffi.cdef("double atan2(double, double);")
return ffi.C.atan2(args[1], args[2])
end
end
end
end
-- math.atan2
if not math.atan2 then
if ffi then
ffi.cdef("double atan2(double, double);")
math.atan2 = function(x, y)
return ffi.C.atan2(args[1], args[2])
end
end
end
-- atan2
if not atan2 then
if ffi then
ffi.cdef("double atan2(double, double);")
atan2 = function(x, y)
return ffi.C.atan2(args[1], args[2])
end
end
end
-- math.exp
if not math.exp then
if ffi then
ffi.cdef("double exp(double);")
math.exp = function(n)
return ffi.C.exp(n)
end
end
end
-- exp
if not exp then
if ffi then
ffi.cdef("double exp(double);")
exp = function(n)
return ffi.C.exp(n)
end
end
end
-- math.log
if not math.log then
if ffi then
ffi.cdef("double log(double);")
math.log = function(n)
return ffi.C.log(n)
end
end
end
-- log
if not log then
if ffi then
ffi.cdef("double log(double);")
log = function(n)
return ffi.C.log(n)
end
end
end
-- math.log10
if not math.log10 then
if ffi then
ffi.cdef("double log10(double);")
math.log10 = function(n)
return ffi.C.log10(n)
end
end
end
-- log10
if not log10 then
if ffi then
ffi.cdef("double log10(double);")
log10 = function(n)
return ffi.C.log10(n)
end
end
end
-- math.ldexp
if not math.ldexp then
if ffi then
ffi.cdef("double ldexp(double, int);")
math.ldexp = function(x, y)
return ffi.C.ldexp(x, y)
end
end
end
-- ldexp
if not ldexp then
if ffi then
ffi.cdef("double ldexp(double, int);")
ldexp = function(x, y)
return ffi.C.ldexp(x, y)
end
end
end
-- math.frexp
if not math.frexp then
if ffi then
ffi.cdef("double frexp(double, int*);")
math.frexp = function(x, y)
return ffi.C.frexp(x, y)
end
end
end
-- frexp
if not frexp then
if ffi then
ffi.cdef("double frexp(double, int*);")
frexp = function(x, y)
return ffi.C.frexp(x, y)
end
end
end
-- math.modf
if not math.modf then
if ffi then
ffi.cdef("double modf(double, double*);")
math.modf = function(x, y)
return ffi.C.modf(x, y)
end
end
end
-- math.mod
if not math.mod then
if ffi then
ffi.cdef("double fmod(double, double);")
math.mod = function(x, y)
return ffi.C.fmod(x, y)
end
end
end
-- math.fmod
if not math.fmod then
if ffi then
ffi.cdef("double fmod(double, double);")
math.fmod = function(x, y)
return ffi.C.fmod(x, y)
end
end
end
-- mod
if not mod then
if ffi then
ffi.cdef("double fmod(double, double);")
mod = function(x, y)
return ffi.C.fmod(x, y)
end
end
end
-- math.pow
if not math.pow then
if ffi then
ffi.cdef("double pow(double, double);")
math.pow = function(n, p)
return ffi.C.pow(n, p)
end
else
math.pow = function(n, p)
local e = n
if (p == 0) then
return 1
end
if (p < 0) then
p = p * -1
end
for c = p, 2, -1 do
e = e * n
end
return e
end
end
end
-- math.abs
if not math.abs then
math.abs = function(n)
if (n < 0) then
return -n
else
return n
end
end
end
-- abs
if not abs then
abs = function(n)
if (n < 0) then
return -n
else
return n
end
end
end
-- math.deg
if not math.deg then
math.deg = function(n)
return n * (180 / math.pi)
end
end
-- deg
if not deg then
deg = function(n)
return n * (180 / math.pi)
end
end
-- math.rad
if not math.rad then
math.rad = function(d)
return d * (math.pi / 180)
end
end
-- rad
if not rad then
rad = function(d)
return d * (math.pi / 180)
end
end
-- math.min
if not math.min then
math.min = function(x, y)
if x < y then
return x
else
return y
end
end
end
-- min
if not min then
min = function(x, y)
if x < y then
return x
else
return y
end
end
end
-- math.max
if not math.max then
math.max = function(x, y)
if x > y then
return x
else
return y
end
end
end
-- max
if not max then
max = function(x, y)
if x > y then
return x
else
return y
end
end
end
-- math.tointeger
if not math.tointeger then
math.tointeger = function(n)
return math.floor(n)
end
end
-- math.hypot
if not math.hypot then
if ffi then
ffi.cdef("double hypot(double, double);")
math.hypot = function(x, y)
return ffi.C.hypot(x, y)
end
else
math.hypot = function(x, y)
return math.sqrt(math.pow(x, 2) + math.pow(y, 2))
end
end
end
-- math.sin
if not math.sin then
if ffi then
ffi.cdef("double sin(double);")
math.sin = function(n)
return ffi.C.sin(n)
end
end
end
-- sin
if not sin then
if ffi then
ffi.cdef("double sin(double);")
sin = function(n)
return ffi.C.sin(n)
end
end
end
-- math.cos
if not math.cos then
if ffi then
ffi.cdef("double cos(double);")
math.cos = function(n)
return ffi.C.cos(n)
end
else
function fact(a)
if (a == 1) or (a == 0) then
return 1
end
local e = 1
for c = a, 1, -1 do
e = e * c
end
return e
end
function correctRadians(v)
while v > math.pi * 2 do
v = v - math.pi * 2
end
while v < -math.pi * 2 do
v = v + math.pi * 2
end
return v
end
math.cos = function(a, b)
local e = 1
a = correctRadians(a)
b = b or 10
for i = 1, b do
e = e + (math.pow(-1, i) * math.pow(a, 2 * i) / fact(2 * i))
end
return e
end
end
end
-- cos
if not cos then
if ffi then
ffi.cdef("double cos(double);")
cos = function(n)
return ffi.C.cos(n)
end
else
function fact(a)
if (a == 1) or (a == 0) then
return 1
end
local e = 1
for c = a, 1, -1 do
e = e * c
end
return e
end
function correctRadians(v)
while v > math.pi * 2 do
v = v - math.pi * 2
end
while v < -math.pi * 2 do
v = v + math.pi * 2
end
return v
end
cos = function(a, b)
local e = 1
a = correctRadians(a)
b = b or 10
for i = 1, b do
e = e + (math.pow(-1, i) * math.pow(a, 2 * i) / fact(2 * i))
end
return e
end
end
end
-- math.tan
if not math.tan then
if ffi then
ffi.cdef("double tan(double);")
math.tan = function(n)
return ffi.C.tan(n)
end
end
end
-- tan
if not tan then
if ffi then
ffi.cdef("double tan(double);")
tan = function(n)
return ffi.C.tan(n)
end
end
end
-- math.ult
if not math.ult then
if ffi then
math.ult = function(x, y)
return (ffi.cast("unsigned int", x) < ffi.cast("unsigned int", y))
end
end
end
-- math.ceil
if not math.ceil then
if ffi then
math.ceil = function(n)
ffi.cdef("double ceil(double);")
return ffi.C.ceil(n)
end
end
end
-- ceil
if not ceil then
if ffi then
ceil = function(n)
ffi.cdef("double ceil(double);")
return ffi.C.ceil(n)
end
end
end
-- math.round
if not math.round then
if ffi then
math.round = function(n)
ffi.cdef("double round(double);")
return ffi.C.round(n)
end
end
end
-- round
if not round then
if ffi then
round = function(n)
ffi.cdef("double round(double);")
return ffi.C.round(n)
end
end
end
-- math.floor
if not math.floor then
if ffi then
math.floor = function(n)
ffi.cdef("double floor(double);")
return ffi.C.floor(n)
end
end
end
-- floor
if not floor then
if ffi then
floor = function(n)
ffi.cdef("double floor(double);")
return ffi.C.floor(n)
end
end
end
-- math.randomseed
if not math.randomseed then
if ffi then
ffi.cdef("void srand(unsigned int _Seed);")
math.randomseed = function(n)
ffi.C.srand(n)
end
end
end
-- randomseed
if not randomseed then
if ffi then
ffi.cdef("void srand(unsigned int _Seed);")
randomseed = function(n)
ffi.C.srand(n)
end
end
end
-- math.random
if not math.random then
if ffi then
ffi.cdef("int rand(void);")
math.random = function(...)
local pownum = 100000
local n = { ... }
if (#n == 0) then
return (ffi.C.rand() / pownum)
elseif (#n == 1) then
local num = (n[1] * (n[1] - 2))
local result = math.floor((ffi.C.rand() / pownum) * num)
if (result > n[1]) then
return n[1]
end
return result
elseif (#n == 2) then
local num1 = (n[1] * (n[1] - 2))
local num2 = (n[2] * (n[2] - 2))
local result = math.floor((ffi.C.rand() / pownum) * (num2 - num1) + num1)
if (result > n[2]) then
return n[2]
end
if (result < n[1]) then
return n[1]
end
return result
end
end
end
end
-- random
if not random then
if ffi then
ffi.cdef("int rand(void);")
random = function(...)
local pownum = 100000
local n = { ... }
if (#n == 0) then
return (ffi.C.rand() / pownum)
elseif (#n == 1) then
local num = (n[1] * (n[1] - 2))
local result = math.floor((ffi.C.rand() / pownum) * num)
if (result > n[1]) then
return n[1]
end
return result
elseif (#n == 2) then
local num1 = (n[1] * (n[1] - 2))
local num2 = (n[2] * (n[2] - 2))
local result = math.floor((ffi.C.rand() / pownum) * (num2 - num1) + num1)
if (result > n[2]) then
return n[2]
end
if (result < n[1]) then
return n[1]
end
return result
end
end
end
end
-- module: bit32
bit32 = bit32 or {}
bit32.bits = 32
bit32.powtab = { 1 }
for b = 1, bit32.bits - 1 do
bit32.powtab[#bit32.powtab + 1] = math.pow(2, b)
end
-- Functions
-- bit32.band
if not bit32.band then
bit32.band = function(a, b)
local result = 0
for x = 1, bit32.bits do
result = result + result
if (a < 0) then
if (b < 0) then
result = result + 1
end
end
a = a + a
b = b + b
end
return result
end
end
-- bit32.bor
if not bit32.bor then
bit32.bor = function(a, b)
local result = 0
for x = 1, bit32.bits do
result = result + result
if (a < 0) then
result = result + 1
elseif (b < 0) then
result = result + 1
end
a = a + a
b = b + b
end
return result
end
end
-- bit32.bnot
if not bit32.bnot then
bit32.bnot = function(x)
return bit32.bxor(x, math.pow((bit32.bits or math.floor(math.log(x, 2))), 2) - 1)
end
end
-- bit32.lshift
if not bit32.lshift then
bit32.lshift = function(a, n)
if (n > bit32.bits) then
a = 0
else
a = a * bit32.powtab[n]
end
return a
end
end
-- bit32.rshift
if not bit32.rshift then
bit32.rshift = function(a, n)
if (n > bit32.bits) then
a = 0
elseif (n > 0) then
if (a < 0) then
a = a - bit32.powtab[#bit32.powtab]
a = a / bit32.powtab[n]
a = a + bit32.powtab[bit32.bits - n]
else
a = a / bit32.powtab[n]
end
end
return a
end
end
-- bit32.arshift
if not bit32.arshift then
bit32.arshift = function(a, n)
if (n >= bit32.bits) then
if (a < 0) then
a = -1
else
a = 0
end
elseif (n > 0) then
if (a < 0) then
a = a - bit32.powtab[#bit32.powtab]
a = a / bit32.powtab[n]
a = a - bit32.powtab[bit32.bits - n]
else
a = a / bit32.powtab[n]
end
end
return a
end
end
-- bit32.bxor
if not bit32.bxor then
bit32.bxor = function(a, b)
local result = 0
for x = 1, bit32.bits, 1 do
result = result + result
if (a < 0) then
if (b >= 0) then
result = result + 1
end
elseif (b < 0) then
result = result + 1
end
a = a + a
b = b + b
end
return result
end
end
-- bit32.btest
if not bit32.btest then
bit32.btest = function(a, b)
return (bit32.band(a, b) ~= 0)
end
end
-- bit32.lrotate
if not bit32.lrotate then
bit32.lrotate = function(a, b)
local bits = bit32.band(b, bit32.bits - 1)
a = bit32.band(a, 0xffffffff)
a = bit32.bor(bit32.lshift(a, b), bit32.rshift(a, ((bit32.bits - 1) - b)))
return bit32.band(n, 0xffffffff)
end
end
-- bit32.rrotate
if not bit32.rrotate then
bit32.rrotate = function(a, b)
return bit32.lrotate(a, -b)
end
end
-- bit32.extract
if not bit32.extract then
bit32.extract = function(a, b, c)
c = c or 1
return bit32.band(bit32.rshift(a, b, c), math.pow(b, 2) - 1)
end
end
-- bit32.replace
if not bit32.replace then
bit32.replace = function(a, b, c, d)
d = d or 1
local mask1 = math.pow(d, 2) -1
b = bit32.band(b, mask1)
local mask = bit32.bnot(bit32.lshift(mask1, c))
return bit32.band(n, mask) + bit32.lshift(b, c)
end
end
-- module: bit
bit = bit or {}
bit.bits = 32
bit.powtab = { 1 }
for b = 1, bit.bits - 1 do
bit.powtab[#bit.powtab + 1] = math.pow(2, b)
end
-- Functions
-- bit.band
if not bit.band then
bit.band = function(a, b)
local result = 0
for x = 1, bit.bits do
result = result + result
if (a < 0) then
if (b < 0) then
result = result + 1
end
end
a = a + a
b = b + b
end
return result
end
end
-- bit.bor
if not bit.bor then
bit.bor = function(a, b)
local result = 0
for x = 1, bit.bits do
result = result + result
if (a < 0) then
result = result + 1
elseif (b < 0) then
result = result + 1
end
a = a + a
b = b + b
end
return result
end
end
-- bit.bnot
if not bit.bnot then
bit.bnot = function(x)
return bit.bxor(x, math.pow((bit.bits or math.floor(math.log(x, 2))), 2) - 1)
end
end
-- bit.lshift
if not bit.lshift then
bit.lshift = function(a, n)
if (n > bit.bits) then
a = 0
else
a = a * bit.powtab[n]
end
return a
end
end
-- bit.rshift
if not bit.rshift then
bit.rshift = function(a, n)
if (n > bit.bits) then
a = 0
elseif (n > 0) then
if (a < 0) then
a = a - bit.powtab[#bit.powtab]
a = a / bit.powtab[n]
a = a + bit.powtab[bit.bits - n]
else
a = a / bit.powtab[n]
end
end
return a
end
end
-- bit.arshift
if not bit.arshift then
bit.arshift = function(a, n)
if (n >= bit.bits) then
if (a < 0) then
a = -1
else
a = 0
end
elseif (n > 0) then
if (a < 0) then
a = a - bit.powtab[#bit.powtab]
a = a / bit.powtab[n]
a = a - bit.powtab[bit.bits - n]
else
a = a / bit.powtab[n]
end
end
return a
end
end
-- bit.bxor
if not bit.bxor then
bit.bxor = function(a, b)
local result = 0
for x = 1, bit.bits, 1 do
result = result + result
if (a < 0) then
if (b >= 0) then
result = result + 1
end
elseif (b < 0) then
result = result + 1
end
a = a + a
b = b + b
end
return result
end
end
-- bit.rol
if not bit.rol then
bit.rol = function(a, b)
local bits = bit.band(b, bit.bits - 1)
a = bit.band(a,0xffffffff)
a = bit.bor(bit.lshift(a, b), bit.rshift(a, ((bit.bits - 1) - b)))
return bit.band(n, 0xffffffff)
end
end
-- bit.ror
if not bit.ror then
bit.ror = function(a, b)
return bit.rol(a, -b)
end
end
-- bit.bswap
if not bit.bswap then
bit.bswap = function(n)
local a = bit.band(n, 0xff)
n = bit.rshift(n, 8)
local b = bit.band(n, 0xff)
n = bit.rshift(n, 8)
local c = bit.band(n, 0xff)
n = bit.rshift(n, 8)
local d = bit.band(n, 0xff)
return bit.lshift(bit.lshift(bit.lshift(a, 8) + b, 8) + c, 8) + d
end
end
-- bit.tobit
if not bit.tobit then
bit.tobit = function(n)
local MOD = 2^32
n = n % MOD
if (n >= 0x80000000) then
n = n - MOD
end
return n
end
end
-- bit.tohex
if not bit.tohex then
bit.tohex = function(x, n)
n = n or 8
local up
if n <= 0 then
if n == 0 then
return ''
end
up = true
n = -n
end
x = bit.band(x, 16^n-1)
return ('%0'..n..(up and 'X' or 'x')):format(x)
end
end
-- module: io
io = require("io") or {}
if not _INPUT then
_INPUT = io.stdin
end
if not _OUTPUT then
_OUTPUT = io.stdout
end
if not _STDIN then
_STDIN = io.stdin
end
if not _STDOUT then
_STDOUT = io.stdout
end
if not _STDERR then
_STDERR = io.stderr
end
-- Used by io.input and io.output, And works as usable file with IO functions lol
io.__DEFAULT__INPUT__FILE__ = nil
io.__DEFAULT__OUTPUT__FILE__ = nil
if ffi then
ffi.cdef([[
struct _iobuf {
char *_ptr;
int _cnt;
char *_base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
char *_tmpfname;
};
typedef struct _iobuf FILE;
typedef struct SExIO_Stream {
FILE *f; /* stream (NULL for incompletely created streams) */
} SExIO_Stream;
]])
end
-- Native file type
_FILE = {}
function _FILE:new(f, m, s)
o = {}
setmetatable(o, self)
self.__index = self
self.__FILE = f
self.__MODE = m
self.__STATE = "file"
self.__SRC = s
return o
end
function _FILE:close()
if ffi then
ffi.cdef("int fclose(FILE *_File);")
local result = (ffi.C.fclose(self.__FILE) == 0)
if result then
self.__STATE = "closed file"
end
end
end
function _FILE:flush()
if ffi then
ffi.cdef("int fflush(FILE *_File);")
return (ffi.C.flush(self.__FILE) == 0)
end
end
function _FILE:seek(w, o)
if ffi then
ffi.cdef("int fseek(FILE *stream, long int offset, int whence);")
if (w == "set") then
return ffi.C.fseek(self.__FILE, o, 0)
elseif (w == "cur") then
return ffi.C.fseek(self.__FILE, o, 1)
elseif (w == "end") then
return ffi.C.fseek(self.__FILE, o, 2)
else
return ffi.C.fseek(self.__FILE, o, w)
end
end
end
function _FILE:read(t)
if (t == "*all" or t == "*a") then
while not cast("bool", ffi.C.feof(f)) do
local content = ""
local ch = ffi.string(ffi.cast("char", ffi.C.fgetc(f)))
if (ch ~= nil) then
content = content .. ch
end
end
elseif (t == "*line" or t == "*l") then
if not cast("bool", ffi.C.feof(f)) then
local line = ""
while not cast("bool", ffi.C.feof(f)) do
local ch = ffi.string(ffi.cast("char", ffi.C.fgetc(f)))
if (ch == "\n") then
break
else
line = line .. ch
end
end
return line
end
elseif (t == "*number" or t == "*n") then
local line = ""
while not cast("bool", ffi.C.feof(f)) do
local ch = tonumber(ffi.string(ffi.cast("char", ffi.C.fgetc(f))))
if not ch then
break
else
line = line .. ch
end
end
return line
elseif (type(t) == "number") then
if not cast("bool", ffi.C.feof(f)) then
local line = ffi.new("char[?]", t)
return ffi.string(ffi.C.fgets(line, t, f))
end
end
end
function _FILE:write(...)
if ffi then
ffi.cdef("int fprintf(FILE *stream, const char *format, ...);")
local args = { ... }
if (#args == 0) then
args[1] = f
end
local form = args[1]
table.remove(args, 1)
if (#args == 0) then
ffi.C.fprintf(f.__FILE, form)
else
ffi.C.fprintf(f.__FILE, form, table.unpack(args))
end
end
end
function _FILE:setvbuf(m, s)
if ffi then
ffi.cdef("int setvbuf(FILE *stream, char *buffer, int mode, size_t size);")
if (m == "no") then
return (ffi.C.setvbuf(self.__FILE, nil, 0x0004, s) == 0)
elseif (m == "full") then
return (ffi.C.setvbuf(self.__FILE, nil, 0x0000, s) == 0)
elseif (m == "line") then
return (ffi.C.setvbuf(self.__FILE, nil, 0x0040, s) == 0)
end
end
end
function _FILE:lines()
if ffi then
local lines = {}
local line = ""
while not cast("bool", ffi.C.feof(self.__FILE)) do
local ch = ffi.string(ffi.cast("char", ffi.C.fgetc(self.__FILE)))
if (ch == "\n") then
lines[#lines + 1] = line
line = ""
else
line = line .. ch
end
end
return ipairs(lines)
end
end
-- Functions and Variables
-- io.tmpfile
if not io.tmpfile then
io.tmpfile = function()
if ffi then
ffi.cdef("FILE *tmpfile(void);")
return _FILE:new(ffi.C.tmpfile(), nil, nil)
end
end
end
-- tmpfile
if not tmpfile then
tmpfile = function()
if ffi then
ffi.cdef("FILE *tmpfile(void);")
return _FILE:new(ffi.C.tmpfile(), nil, nil)
end
end
end
-- io.open
if not io.open then
if ffi then
io.open = function(s, m)
ffi.cdef("FILE *fopen(const char *_Filename,const char *_Mode);")
return _FILE:new(ffi.C.fopen(s, m), m, s)
end
end
end
-- openfile
if not openfile then
if ffi then
openfile = function(s, m)
ffi.cdef("FILE *fopen(const char *_Filename,const char *_Mode);")
return _FILE:new(ffi.C.fopen(s, m), m, s)
end
end
end
-- io.write
if not io.write then
if ffi then
io.write = function(f, ...)
ffi.cdef("int fprintf(FILE *stream, const char *format, ...);")
local args = { ... }
if ((#args == 0) and (io.__DEFAULT__OUTPUT__FILE__)) then
args[1] = f
return (ffi.C.fprintf(io.__DEFAULT__OUTPUT__FILE__, args[1]) == 0)
elseif (f.__FILE) then
local form = args[1]
table.remove(args, 1)
return (ffi.C.fprintf(f.__FILE, form, table.unpack(args)) == 0)
end
end
end
end
-- write
if not write then
if ffi then
write = function(f, ...)
ffi.cdef("int fprintf(FILE *stream, const char *format, ...);")
local args = { ... }
if ((#args == 0) and (io.__DEFAULT__OUTPUT__FILE__)) then
args[1] = f
return (ffi.C.fprintf(io.__DEFAULT__OUTPUT__FILE__, args[1]) == 0)
elseif (f.__FILE) then
local form = args[1]
table.remove(args, 1)
return (ffi.C.fprintf(f.__FILE, form, table.unpack(args)) == 0)
end
end
end
end
-- io.seek
if not io.seek then
if ffi then
io.seek = function(f, w, o)
ffi.cdef("int fseek(FILE *stream, long int offset, int whence);")
if (w == "set") then
return ffi.C.fseek(f, o, 0)
elseif (w == "cur") then
return ffi.C.fseek(f, o, 1)
elseif (w == "end") then
return ffi.C.fseek(f, o, 2)
else
return ffi.C.fseek(f, o, w)
end
end
end
end
-- seek
if not seek then
if ffi then
seek = function(f, w, o)
ffi.cdef("int fseek(FILE *stream, long int offset, int whence);")
if (w == "set") then
return ffi.C.fseek(f, o, 0)
elseif (w == "cur") then
return ffi.C.fseek(f, o, 1)
elseif (w == "end") then
return ffi.C.fseek(f, o, 2)
else
return ffi.C.fseek(f, o, w)
end
end
end
end
-- io.read
if not io.read then
if ffi then
io.read = function(f, t)
ffi.cdef([[
char *fgets(char *str, int n, FILE *stream);
int fgetc(FILE *stream);
int feof(FILE *stream);
int scanf(const char *format, ...);
]])
if t and f then
if (t == "*all" or t == "*a") then
while not cast("bool", ffi.C.feof(f)) do
local content = ""
local ch = ffi.string(ffi.cast("char", ffi.C.fgetc(f)))
if (ch ~= nil) then
content = content .. ch
end
end
elseif (t == "*line" or t == "*l") then
if not cast("bool", ffi.C.feof(f)) then
local line = ""
while not cast("bool", ffi.C.feof(f)) do
local ch = ffi.string(ffi.cast("char", ffi.C.fgetc(f)))
if (ch == "\n") then
break
else
line = line .. ch
end
end
return line
end
elseif (t == "*number" or t == "*n") then
local line = ""
while not cast("bool", ffi.C.feof(f)) do
local ch = tonumber(ffi.string(ffi.cast("char", ffi.C.fgetc(f))))
if not ch then
break
else
line = line .. ch
end
end
return line
elseif (type(t) == "number") then
if not cast("bool", ffi.C.feof(f)) then
local line = ffi.new("char[?]", t)
return ffi.string(ffi.C.fgets(line, t, f))
end
elseif io.__DEFAULT__INPUT__FILE__ then
--if not cast("bool", ffi.C.feof(io.__DEFAULT__INPUT__FILE__)) then
--local line = ffi.new("char[?]", 512)
local line = ""
while not cast("bool", ffi.C.feof(io.__DEFAULT__INPUT__FILE__)) do
local ch = ffi.string(ffi.cast("char", ffi.C.fgetc(io.__DEFAULT__INPUT__FILE__)))
if (ch == "\n") then
break
else
line = line .. ch
end
end
return line
--return ffi.string(ffi.C.fgets(line, 512, io.__DEFAULT__INPUT__FILE__))
else
local input = ffi.new("char[?]", 512)
local execution_code = ffi.C.scanf("%s\0", input)
return input, (execution_code == 0)
end
end
end
end
end
-- read
if not read then
if ffi then
read = function(f, t)
ffi.cdef([[
char *fgets(char *str, int n, FILE *stream);
int fgetc(FILE *stream);
int feof(FILE *stream);
int scanf(const char *format, ...);
]])
if t and f then
if (t == "*all" or t == "*a") then
while not cast("bool", ffi.C.feof(f)) do
local content = ""
local ch = ffi.string(ffi.cast("char", ffi.C.fgetc(f)))
if (ch ~= nil) then
content = content .. ch
end
end
elseif (t == "*line" or t == "*l") then
if not cast("bool", ffi.C.feof(f)) then
local line = ""
while not cast("bool", ffi.C.feof(f)) do
local ch = ffi.string(ffi.cast("char", ffi.C.fgetc(f)))
if (ch == "\n") then
break
else
line = line .. ch
end
end
return line
end
elseif (t == "*number" or t == "*n") then
local line = ""
while not cast("bool", ffi.C.feof(f)) do
local ch = tonumber(ffi.string(ffi.cast("char", ffi.C.fgetc(f))))
if not ch then
break
else
line = line .. ch
end
end
return line
elseif (type(t) == "number") then
if not cast("bool", ffi.C.feof(f)) then
local line = ffi.new("char[?]", t)
return ffi.string(ffi.C.fgets(line, t, f))
end
elseif io.__DEFAULT__INPUT__FILE__ then
--if not cast("bool", ffi.C.feof(io.__DEFAULT__INPUT__FILE__)) then
--local line = ffi.new("char[?]", 512)
local line = ""
while not cast("bool", ffi.C.feof(io.__DEFAULT__INPUT__FILE__)) do
local ch = ffi.string(ffi.cast("char", ffi.C.fgetc(io.__DEFAULT__INPUT__FILE__)))
if (ch == "\n") then
break
else
line = line .. ch
end
end
return line
--return ffi.string(ffi.C.fgets(line, 512, io.__DEFAULT__INPUT__FILE__))
else
local input = ffi.new("char[?]", 512)
local execution_code = ffi.C.scanf("%s\0", input)
return input, (execution_code == 0)
end
end
end
end
end
-- io.close
if not io.close then
if ffi then
io.close = function(f)
if f and (f.__FILE or f.__STATE) then
ffi.cdef("int fclose(FILE *_File);")
local result = (ffi.C.fclose(f.__FILE) == 0)
if result then
f.__STATE = "closed file"
end
end
end
end
end
-- closefile
if not closefile then
if ffi then
closefile = function(f)
if f and (f.__FILE or f.__STATE) then
ffi.cdef("int fclose(FILE *_File);")
local result = (ffi.C.fclose(f.__FILE) == 0)
if result then
f.__STATE = "closed file"
end
end
end
end
end
-- io.flush
if not io.flush then
if ffi then
io.flush = function(f)
ffi.cdef("int fflush(FILE *_File);")
return (ffi.C.fflush(f or io.stdout) == 0)
end
end
end
-- flush
if not flush then
if ffi then
flush = function(f)
ffi.cdef("int fflush(FILE *_File);")
return (ffi.C.fflush(f or io.stdout) == 0)
end
end
end
-- io.type
if not io.type then
io.type = function(f)
if f and f.__STATE and ffi.istype("FILE", f) then
return f.__STATE
else
return nil
end
end
end
-- io.input
if not io.input then
io.input = function(f)
if f and (f.__FILE or f.__STATE) then
if (f.__FILE or f.__MODE or f.__STATE) then
io.__DEFAULT__INPUT__FILE__ = f
end
end
end
end
-- readfrom
if not readfrom then
readfrom = function(f)
if f and (f.__FILE or f.__STATE) then
if (f.__FILE or f.__MODE or f.__STATE) then
io.__DEFAULT__OUTPUT__FILE__ = f
end
end
end
end
-- io.output
if not io.output then
io.output = function(f)
if f and (f.__FILE or f.__STATE) then
if (f.__FILE or f.__MODE or f.__STATE) then
io.__DEFAULT__OUTPUT__FILE__ = f
end
end
end
end
-- writeto
if not writeto then
writeto = function(f)
if f and (f.__FILE or f.__STATE) then
if (f.__FILE or f.__MODE or f.__STATE) then
io.__DEFAULT__OUTPUT__FILE__ = f
end
end
end
end
-- appendto
if not appendto then
appendto = function(f)
if f and (f.__FILE or f.__STATE) then
if (f.__FILE or f.__MODE or f.__STATE) then
io.__DEFAULT__OUTPUT__FILE__ = f
end
end
end
end
-- io.popen
if not io.popen then
if ffi then
io.popen = function(c, m)
ffi.cdef("FILE *_popen(const char *_Command, const char *_Mode);")
return _FILE:new(ffi.C._popen(c, m), m, nil)
end
end
end
-- io.lines
if not io.lines then
if ffi then
io.lines = function(filename)
local lines = {}
local line = ""
local file = nil
if (not filename) and io.__DEFAULT__INPUT__FILE__ and io.__DEFAULT__INPUT__FILE__.__FILE then
filename = io.__DEFAULT__INPUT__FILE__
file = io.__DEFAULT__INPUT__FILE__.__FILE
else
file = io.open(filename, "r")
end
while not cast("bool", ffi.C.feof(file)) do
local ch = ffi.string(ffi.cast("char", ffi.C.fgetc(file)))
if (ch == "\n") then
lines[#lines + 1] = line
line = ""
else
line = line .. ch
end
end
return ipairs(lines)
end
end
end
-- io.stdin
if not io.stdin then
if ffi then
io.stdin = _FILE:new(io.open("stdin", "w"), "w", "stdin")
end
end
-- io.stdout
if not io.stdout then
if ffi then
io.stdout = _FILE:new(io.open("stdout", "w"), "w", "stdout")
end
end
-- io.stderr
if not io.stderr then
if ffi then
io.stderr = _FILE:new(io.open("stderr", "w"), "w", "stderr")
end
end
-- module: string
-- Functions
string = require("string") or {}
string.chars = {}
string.chars["a"] = 97
string.chars["b"] = 98
string.chars["c"] = 99
string.chars["d"] = 100
string.chars["e"] = 101
string.chars["f"] = 102
string.chars["g"] = 103
string.chars["h"] = 104
string.chars["i"] = 105
string.chars["j"] = 106
string.chars["k"] = 107
string.chars["l"] = 108
string.chars["m"] = 109
string.chars["n"] = 110
string.chars["o"] = 111
string.chars["p"] = 112
string.chars["q"] = 113
string.chars["r"] = 114
string.chars["s"] = 115
string.chars["t"] = 116
string.chars["u"] = 117
string.chars["v"] = 118
string.chars["w"] = 119
string.chars["x"] = 120
string.chars["y"] = 121
string.chars["z"] = 122
string.chars["0"] = 48
string.chars["1"] = 49
string.chars["2"] = 50
string.chars["3"] = 51
string.chars["4"] = 52
string.chars["5"] = 53
string.chars["6"] = 54
string.chars["7"] = 55
string.chars["8"] = 56
string.chars["9"] = 57
string.chars["!"] = 33
string.chars["@"] = 64
string.chars["#"] = 35
string.chars["$"] = 36
string.chars["%"] = 37
string.chars["^"] = 94
string.chars["&"] = 38
string.chars["*"] = 42
string.chars["("] = 40
string.chars[")"] = 41
string.chars["-"] = 45
string.chars["+"] = 43
string.chars["_"] = 95
string.chars["="] = 61
string.chars["{"] = 123
string.chars["}"] = 125
string.chars["["] = 91
string.chars["]"] = 93
string.chars[":"] = 58
string.chars["'"] = 39
string.chars["\""] = 34
string.chars[";"] = 95
string.chars["/"] = 47
string.chars["`"] = 96
string.chars["~"] = 126
string.chars["|"] = 124
string.chars["\\"] = 92
string.chars[","] = 44
string.chars["."] = 46
string.chars["<"] = 60
string.chars[">"] = 62
string.chars["?"] = 63
-- string.split
if not string.split then
string.split = function(s, sep)
local result = {}
local line = ""
for i = 1, #s do
if (string.char(string.byte(s, i)) == sep) then
result[#result + 1] = line
line = ""
else
line = line .. string.char(string.byte(s, i))
end
end
return result
end
end
-- string.rep
if not string.rep then
string.rep = function(s, n, sep)
local str = ""
local sp = sep or ""
for i = 1, n, 1 do
if (i == n) then
sp = ""
end
str = str .. s .. sp
end
return str
end
end
-- strrep
if not strrep then
strrep = function(s, n, sep)
local str = ""
local sp = sep or ""
for i = 1, n, 1 do
if (i == n) then
sp = ""
end
str = str .. s .. sp
end
return str
end
end
-- string.len
if not string.len then
string.len = function(s)
if not ffi then
return #n
else
ffi.cdef("size_t strlen(const char *_Str);")
return ffi.cast("int", ffi.C.strlen(s))
end
end
end
-- strlen
if not strlen then
strlen = function(s)
if not ffi then
return #n
else
ffi.cdef("size_t strlen(const char *_Str);")
return ffi.cast("int", ffi.C.strlen(s))
end
end
end
-- string.byte
if not string.byte then
if (type(ffi) == "string") then
string.byte = function(s, i)
i = i or 1
local strarr = ffi.new("char[?]", #s)
ffi.copy(strarr, s)
return ffi.cast("int", strarr[i])
end
end
end
-- strbyte
if not strbyte then
if (type(ffi) == "string") then
strbyte = function(s, i)
i = i or 1
local strarr = ffi.new("char[?]", #s)
ffi.copy(strarr, s)
return ffi.cast("int", strarr[i])
end
end
end
-- string.char
if not string.char then
string.char = function(...)
local args = { ... }
local str = ""
for i = 1, #args do
for k, v in pairs(string.chars) do
if (v == args[i]) then
str = str .. k
end
end
end
return str
end
end
-- strchar
if not strchar then
strchar = function(...)
local args = { ... }
local str = ""
for i = 1, #args do
for k, v in pairs(string.chars) do
if (v == args[i]) then
str = str .. k
end
end
end
return str
end
end
-- string.upper
if not string.upper then
if ffi then
string.upper = function(s)
ffi.cdef("int toupper(int _C);")
local result = {}
local t = ffi.new("char[?]", #s)
ffi.copy(t, s)
for i = 1, #s, 1 do
result[i] = ffi.C.toupper(string.char(ffi.cast("int", t[i])))
end
return table.concat(result, "")
end
end
end
-- strupper
if not strupper then
if ffi then
strupper = function(s)
ffi.cdef("int toupper(int _C);")
local result = {}
local t = ffi.new("char[?]", #s)
ffi.copy(t, s)
for i = 1, #s, 1 do
result[i] = ffi.C.toupper(string.char(ffi.cast("int", t[i])))
end
return table.concat(result, "")
end
end
end
-- string.lower
if not string.lower then
if ffi then
string.lower = function(s)
ffi.cdef("int tolower(int _C);")
local result = {}
local t = ffi.new("char[?]", #s)
ffi.copy(t, s)
for i = 1, #s, 1 do
result[i] = ffi.C.tolower(string.char(ffi.cast("int", t[i])))
end
return table.concat(result, "")
end
end
end
-- strlower
if not strlower then
if ffi then
string.lower = function(s)
ffi.cdef("int tolower(int _C);")
local result = {}
local t = ffi.new("char[?]", #s)
ffi.copy(t, s)
for i = 1, #s, 1 do
result[i] = ffi.C.tolower(string.char(ffi.cast("int", t[i])))
end
return table.concat(result, "")
end
end
end
-- string.pack
if not string.pack then
if ffi then
string.pack = function(f, ...)
local packtype = string.char(string.byte(f, 1))
local arrtype = ""
local arrsize = 0
if packtype == "i" then
arrtype = "int"
arrsize = 2
elseif packtype == "f" then
arrtype = "float"
arrsize = 4
elseif packtype == "d" then
arrtype = "double"
arrsize = 8
elseif packtype == "c" then
arrtype = "char" -- char could be int?
arrsize = 1
end
local occurences = string.match(args[1], packtype)
local args = { ... }
return ffi.string(ffi.new(arrtype.."[?]", #args, args), arrsize * #args)
end
end
end
-- string.unpack
if not string.unpack then
if ffi then
string.unpack = function(f, s, o)
local packtype = string.char(string.byte(f, 1))
local arrtype = ""
local arrsize = 0
if packtype == "i" then
arrtype = "int"
arrsize = 2
elseif packtype == "f" then
arrtype = "float"
arrsize = 4
elseif packtype == "d" then
arrtype = "double"
arrsize = 8
elseif packtype == "c" then
arrtype = "char" -- char could be int?
arrsize = 1
end
local str = ffi.cast(arrtype .. "*", ffi.new("char[?]", #str, str))
local t = {}
for i = o, #str / arrsize do
t[#t + 1] = str[#t]
end
return table.concat(t)
end
end
end
-- string.packsize
if not string.packsize then
if ffi then
string.packsize = function(str)
if str[1] then
return #str
end
end
end
end
-- string.sub
if not string.sub then
string.sub = function(s, f, t)
t = t or #s
local result = ""
for i = f, t do
result = result .. string.char(string.byte(s, i))
end
return result
end
end
-- strsub
if not strsub then
strsub = function(s, f, t)
t = t or #s
local result = ""
for i = f, t do
result = result .. string.char(string.byte(s, i))
end
return result
end
end
-- string.format
if not string.format then
if ffi then
string.format = function(...)
ffi.cdef("int sprintf(char *str, const char *format, ...);")
local args = { ... }
local str = ""
ffi.C.sprintf(str, table.unpack(args))
return ffi.string(str)
end
end
end
-- format
if not format then
if ffi then
format = function(...)
ffi.cdef("int sprintf(char *str, const char *format, ...);")
local args = { ... }
local str = ""
ffi.C.sprintf(str, table.unpack(args))
return ffi.string(str)
end
end
end
-- string.match
if not string.match then
if ffi then
string.match = function(s1, s2, init)
ffi.cdef("char* strstr(const char*, const char*);")
init = init or 0
local occurences = 0
local count = 0
local ptr = s1
local lastfind = nil
while (ffi.C.strstr(ptr, s2) ~= nil) do
lastfind = ffi.C.strstr(ptr, s2)
ptr = lastfind + 1
if (occurences >= init) then
count = count + 1
end
occurences = occurences + 1
end
if (occurences > 1) then
return (occurences * #s2) - 1, #s2
else
return occurences, #s2
end
end
end
end
-- string.gmatch
if not string.gmatch then
if ffi then
string.gmatch = function(s1, s2)
ffi.cdef("char* strstr(const char*, const char*);")
local occurences = {}
local ptr = s1
local lastfind = nil
while (ffi.C.strstr(ptr, s2) ~= nil) do
lastfind = ffi.C.strstr(ptr, s2)
ptr = lastfind + 1
occurences[#occurences + 1] = lastfind
end
return ipairs(occurences)
end
end
end
-- string.find
if not string.find then
if ffi then
string.find = function(s1, s2, init)
ffi.cdef("char* strstr(const char*, const char*);")
init = init or 0
local occurences = 0
local count = 0
local ptr = s1
local lastfind = nil
while (ffi.C.strstr(ptr, s2) ~= nil) do
lastfind = ffi.C.strstr(ptr, s2)
ptr = lastfind + 1
if (occurences >= init) then
count = count + 1
end
occurences = occurences + 1
end
return occurences, #s2
end
end
end
-- strfind
if not strfind then
if ffi then
strfind = function(s1, s2, init)
ffi.cdef("char* strstr(const char*, const char*);")
init = init or 0
local occurences = 0
local count = 0
local ptr = s1
local lastfind = nil
while (ffi.C.strstr(ptr, s2) ~= nil) do
lastfind = ffi.C.strstr(ptr, s2)
ptr = lastfind + 1
if (occurences >= init) then
count = count + 1
end
occurences = occurences + 1
end
return occurences, #s2
end
end
end
-- string.gfind
if not string.gfind then
if ffi then
string.gfind = function(s1, s2)
ffi.cdef("char* strstr(const char*, const char*);")
local occurences = {}
local ptr = s1
local lastfind = nil
while (ffi.C.strstr(ptr, s2) ~= nil) do
lastfind = strstr(ptr, s2)
ptr = lastfind + 1
occurences[#occurences + 1] = lastfind
end
return ipairs(occurences)
end
end
end
return polyfill