mirror of
https://github.com/appgurueu/modlib.git
synced 2024-11-25 16:53:46 +01:00
texmod.read
: Fix [transform
followed by a lowercase letter
This commit is contained in:
parent
5dc6307661
commit
520ecc641b
@ -166,6 +166,22 @@ function pr.lowpart(r)
|
|||||||
return percent, r:subtexp()
|
return percent, r:subtexp()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Build a prefix tree of parameter readers to greedily match the longest texture modifier prefix;
|
||||||
|
-- just matching `%a+` and looking it up in a table
|
||||||
|
-- doesn't work since `[transform` may be followed by a lowercase transform name
|
||||||
|
-- TODO (?...) consolidate with `modlib.trie`
|
||||||
|
local texmod_reader_trie = {}
|
||||||
|
for _, readers in pairs{pr, gr} do
|
||||||
|
for type in pairs(readers) do
|
||||||
|
local subtrie = texmod_reader_trie
|
||||||
|
for char in type:gmatch"." do
|
||||||
|
subtrie[char] = subtrie[char] or {}
|
||||||
|
subtrie = subtrie[char]
|
||||||
|
end
|
||||||
|
subtrie.type = type
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Reader methods. We use `r` instead of the `self` "sugar" for consistency (and to save us some typing).
|
-- Reader methods. We use `r` instead of the `self` "sugar" for consistency (and to save us some typing).
|
||||||
local rm = {}
|
local rm = {}
|
||||||
|
|
||||||
@ -185,6 +201,7 @@ function rm.peek(r)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
function rm.popchar(r)
|
function rm.popchar(r)
|
||||||
|
assert(not r.eof, "unexpected eof")
|
||||||
r.escapes = 0
|
r.escapes = 0
|
||||||
while true do
|
while true do
|
||||||
r.character = r:read_char()
|
r.character = r:read_char()
|
||||||
@ -277,7 +294,7 @@ function rm.basexp(r)
|
|||||||
return res
|
return res
|
||||||
end
|
end
|
||||||
if r:match"[" then
|
if r:match"[" then
|
||||||
local type = r:match_str"[a-z]"
|
local type = r:match_str"%a"
|
||||||
local gen_reader = gr[type]
|
local gen_reader = gr[type]
|
||||||
if not gen_reader then
|
if not gen_reader then
|
||||||
error("invalid texture modifier: " .. type)
|
error("invalid texture modifier: " .. type)
|
||||||
@ -288,17 +305,25 @@ function rm.basexp(r)
|
|||||||
end
|
end
|
||||||
function rm.colorspec(r)
|
function rm.colorspec(r)
|
||||||
-- Leave exact validation up to colorspec, only do a rough greedy charset matching
|
-- Leave exact validation up to colorspec, only do a rough greedy charset matching
|
||||||
return assert(colorspec.from_string(r:match_str"[#%xa-z]"))
|
return assert(colorspec.from_string(r:match_str"[#%x%a]"))
|
||||||
end
|
end
|
||||||
function rm.texp(r)
|
function rm.texp(r)
|
||||||
local base = r:basexp()
|
local base = r:basexp()
|
||||||
while r:hat() do
|
while r:hat() do
|
||||||
if r:match"[" then
|
if r:match"[" then
|
||||||
local type = r:match_str"[a-z]"
|
local reader_subtrie = texmod_reader_trie
|
||||||
local param_reader, gen_reader = pr[type], gr[type]
|
while true do
|
||||||
if not (param_reader or gen_reader) then
|
local next_subtrie = reader_subtrie[r:peek()]
|
||||||
error("invalid texture modifier: " .. type)
|
if next_subtrie then
|
||||||
|
reader_subtrie = next_subtrie
|
||||||
|
r:pop()
|
||||||
|
else
|
||||||
|
break
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
local type = assert(reader_subtrie.type, "invalid texture modifier")
|
||||||
|
local param_reader, gen_reader = pr[type], gr[type]
|
||||||
|
assert(param_reader or gen_reader)
|
||||||
if param_reader then
|
if param_reader then
|
||||||
base = base[type](base, param_reader(r))
|
base = base[type](base, param_reader(r))
|
||||||
elseif gen_reader then
|
elseif gen_reader then
|
||||||
|
Loading…
Reference in New Issue
Block a user