70 lines
2.1 KiB
Lua
70 lines
2.1 KiB
Lua
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
|
|
|