first commit
This commit is contained in:
69
lib/knife/system.lua
Normal file
69
lib/knife/system.lua
Normal 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
|
||||
|
||||
Reference in New Issue
Block a user