mirror of
https://github.com/smogon/sprites.git
synced 2026-03-22 01:45:27 -05:00
There's still more implementation cleanup to do, but I at least wanted to publish the new build DSL, which is stable-ish at this point
135 lines
2.8 KiB
Lua
135 lines
2.8 KiB
Lua
--
|
|
|
|
local function rep_fn(f, var, modifier)
|
|
local v = f(var)
|
|
if v == nil then
|
|
error("unknown substitution: " .. var)
|
|
end
|
|
if modifier ~= nil then
|
|
if modifier == "b" then
|
|
return tup.file(v)
|
|
elseif modifier == "B" then
|
|
return tup.base(v)
|
|
elseif modifier == "e" then
|
|
return tup.ext(v)
|
|
else
|
|
error("unknown modifier: " .. modifier)
|
|
end
|
|
else
|
|
return v
|
|
end
|
|
end
|
|
|
|
-- Lua doesn't have alternation...
|
|
local function do_rep(prefix, str, fn)
|
|
str = str:gsub(prefix .. "{(%a+)}",
|
|
function(var)
|
|
return rep_fn(fn, var, nil)
|
|
end
|
|
)
|
|
str = str:gsub(prefix .. "{(%a+):(%a)}",
|
|
function(var, modifier)
|
|
return rep_fn(fn, var, modifier)
|
|
end
|
|
)
|
|
str = str:gsub(prefix .. "(%a)",
|
|
function(var)
|
|
if var == "f" then
|
|
return rep_fn(fn, "input", nil)
|
|
elseif var == "b" then
|
|
return rep_fn(fn, "input", "b")
|
|
elseif var == "B" then
|
|
return rep_fn(fn, "input", "B")
|
|
elseif var == "o" then
|
|
return rep_fn(fn, "output", nil)
|
|
end
|
|
end
|
|
)
|
|
return str
|
|
end
|
|
|
|
function rep(args)
|
|
local str = args[1]
|
|
local vars = args
|
|
return do_rep(
|
|
"$",
|
|
str,
|
|
function(var)
|
|
return vars[var]
|
|
end
|
|
)
|
|
end
|
|
|
|
-- Variable interpolation with dynamic scoping
|
|
|
|
local FRAMES = {}
|
|
|
|
function push_frame()
|
|
local frame = {}
|
|
table.insert(FRAMES, frame)
|
|
return frame
|
|
end
|
|
|
|
function pop_frame()
|
|
table.remove(FRAMES)
|
|
end
|
|
|
|
function adjust_frame(t)
|
|
local last_frame = FRAMES[#FRAMES]
|
|
for k, v in pairs(t) do
|
|
last_frame[k] = v
|
|
end
|
|
end
|
|
|
|
function print_frame()
|
|
local last_frame = FRAMES[#FRAMES]
|
|
for k, v in pairs(last_frame) do
|
|
print("frame", k, v)
|
|
end
|
|
end
|
|
|
|
function dim(var)
|
|
for i = #FRAMES, 1, -1 do
|
|
if FRAMES[i][var] ~= nil then
|
|
return FRAMES[i][var]
|
|
end
|
|
end
|
|
end
|
|
|
|
function expand(str)
|
|
return do_rep(
|
|
"%%",
|
|
str,
|
|
function(var)
|
|
return dim(var)
|
|
end
|
|
)
|
|
end
|
|
|
|
function with_rep(vars, f)
|
|
push_frame()
|
|
adjust_frame(vars)
|
|
local ret = f()
|
|
pop_frame()
|
|
return ret
|
|
end
|
|
|
|
function iter_rep(varspec, f)
|
|
local frame = push_frame()
|
|
local keys = table_keys(varspec)
|
|
local function loop(i)
|
|
if #keys + 1 == i then
|
|
f()
|
|
else
|
|
local k = keys[i]
|
|
for v in iter(varspec[k]) do
|
|
frame[k] = v
|
|
loop(i+1)
|
|
end
|
|
end
|
|
end
|
|
loop(1)
|
|
pop_frame()
|
|
end
|
|
|