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

69
lib/knife/system.lua Normal file
View File

@@ -0,0 +1,69 @@
local loadstring = _G.loadstring or _G.load
local tconcat = table.concat
local type = type
local function hasSigil (sigil, value)
return type(value) == 'string' and sigil:byte() == value:byte()
end
return function (aspects, process)
local args = {}
local cond = {}
local results = {}
local localIndex = 0
local choicePattern = '([^|]+)'
local function suppress (aspect, condition)
cond[#cond + 1] = 'if nil'
for option in aspect:gmatch(choicePattern) do
cond[#cond + 1] = condition:format(option)
end
cond[#cond + 1] = 'then return end'
end
local function supply (aspect, isOptional, isReturned)
localIndex = localIndex + 1
cond[#cond + 1] = ('local l%d = nil'):format(localIndex)
for option in aspect:gmatch(choicePattern) do
cond[#cond + 1] = ('or _entity[%q]'):format(option)
end
if not isOptional then
cond[#cond + 1] = ('if not l%d then return end'):format(localIndex)
end
if isReturned then
results[#results + 1] = ('_entity[%q]'):format(aspect)
end
args[#args + 1] = ('l%d'):format(localIndex)
end
for index = 1, #aspects do
local aspect = aspects[index]
if hasSigil('_', aspect) then
args[#args + 1] = aspect
elseif hasSigil('!', aspect) or hasSigil('~', aspect) then
suppress(aspect:sub(2), 'or _entity[%q]')
elseif hasSigil('-', aspect) then
suppress(aspect:sub(2), 'or not _entity[%q]')
elseif hasSigil('?', aspect) then
supply(aspect:sub(2), true)
elseif hasSigil('=', aspect) then
supply(aspect:sub(2), false, true)
else
supply(aspect, false)
end
end
local source = ([[
local _aspects, _process = ...
return function (_entity, ...)
%s
%s _process(%s ...)
return true
end]]):format(
tconcat(cond, ' '),
results[1] and (tconcat(results, ',') .. ' = ') or '',
args[1] and (tconcat(args, ', ') .. ', ') or '')
return loadstring(source)(aspects, process)
end