diff --git a/conf.lua b/conf.lua index a62defa6..7ade3138 100644 --- a/conf.lua +++ b/conf.lua @@ -3,6 +3,7 @@ MOBILE=SYSTEM=='Android' or SYSTEM=='iOS' FNNS=SYSTEM:find'\79\83'-- What does FNSF stand for? IDK so don't ask me lol if SYSTEM=='Web' then + POLYFILL = require"polyfill" local oldRead=love.filesystem.read function love.filesystem.read(name,size) if love.filesystem.getInfo(name) then diff --git a/polyfill.lua b/polyfill.lua new file mode 100644 index 00000000..093a710e --- /dev/null +++ b/polyfill.lua @@ -0,0 +1,3391 @@ +-- 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