first commit

This commit is contained in:
2021-12-18 20:10:30 +01:00
parent 4d04f63b99
commit 215bed9faf
108 changed files with 3630 additions and 0 deletions

77
lib/knife/memoize.lua Normal file
View File

@@ -0,0 +1,77 @@
local loadstring = _G.loadstring or _G.load
local weakKeys = { __mode = 'k' }
local cache = setmetatable({}, weakKeys)
local resultsKey = {}
local nilKey = {}
local function getMetaCall (callable)
local meta = getmetatable(callable)
return meta and meta.__call
end
local tupleConstructorCache = {}
local function buildTupleConstructor (n)
if tupleConstructorCache[n] then
return tupleConstructorCache[n]
end
local t = {}
for i = 1, n do
t[i] = "a" .. i
end
local args = table.concat(t, ',')
local ctor = loadstring('return function(' .. args ..
') return function() return ' .. args .. ' end end')()
tupleConstructorCache[n] = ctor
return ctor
end
local function tuple (...)
return buildTupleConstructor(select('#', ...))(...)
end
return function (callable)
local metaCall = getMetaCall(callable)
if type(callable) ~= 'function' and not metaCall then
error 'Attempted to memoize a non-callable value.'
end
cache[callable] = setmetatable({}, weakKeys)
local function run (...)
local node = cache[callable]
local argc = select('#', ...)
for i = 1, argc do
local key = select(i, ...)
if key == nil then
key = nilKey
end
if not node[key] then
node[key] = setmetatable({}, weakKeys)
end
node = node[key]
end
if not node[resultsKey] then
node[resultsKey] = tuple(callable(...))
end
return node[resultsKey]()
end
if metaCall then
return function (...)
local call = getMetaCall(callable)
if call ~= metaCall then
cache[callable] = setmetatable({}, weakKeys)
metaCall = call
end
return run(...)
end, cache, resultsKey, nilKey
end
return run, cache, resultsKey, nilKey
end