Merge branch 'master' of git://cams.pavlovian.net/questhelper
[QuestHelper.git] / pattern.lua
blob65636d33b243a2b6858c53338ab6a81ef227249a
1 QuestHelper_File["pattern.lua"] = "Development Version"
2 QuestHelper_Loadtime["pattern.lua"] = GetTime()
4 -- The following junk is for building functions to parse strings for various locales.
6 local varindex, varswap = 0, {}
8 local function replacePattern(p)
9 varindex = varindex + 1
10 local b, e, i = string.find(p, "(%d-)%$")
12 if i then
13 -- String contains an index.
14 p = string.sub(p, 1, b-1)..string.sub(p, e+1)
15 i = tonumber(i)
16 else
17 -- String doesn't contains an index, assume its index is the position we found it in.
18 i = varindex
19 end
21 varswap[i] = varindex
23 if p == "d" then return "(%d+)" end
24 if p == "s" then return "(.-)" end
26 -- Only know about strings and integers. Other types are broken.
27 assert(false, "Unknown pattern: %"..p)
28 end
30 -- Used to cache results, so we don't produce multiple functions for the same string.
31 local known_patterns = {}
33 function QuestHelper:convertPattern(pattern)
34 local result = known_patterns[pattern]
36 if result then
37 return result
38 end
40 while(table.remove(varswap)) do end
42 varindex = 0
44 local pat = string.format("^%s$", string.gsub(pattern, "%%(.-[%%%a])", replacePattern))
46 if varindex == 0 then
47 -- The string doesn't contain any variables.
48 result = self.nop
49 else
50 local func = "local function parse(input)\n"
51 local linear = true
53 for i = 1,varindex do
54 if varswap[i] ~= i then
55 linear = false
56 break
57 end
58 end
60 if linear then
61 -- All the arguments are in order, we can just return them.
62 func = func .. string.format("return select(3, string.find(input, %q))", pat)
63 else
64 -- The order has been changed, use temporary variables.
65 for i = 1,varindex do
66 func = func ..(i==1 and "local " or ", ")..("n"..i)
67 end
69 func = func .. string.format(" = select(3, string.find(input, %q))\n", pat)
71 for i = 1,varindex do
72 func = func ..(i==1 and "return " or ", ")..(varswap[i] and ("n"..varswap[i]) or "nil")
73 end
74 end
76 func = func .. "\nend\nreturn parse\n"
78 result = loadstring(func)()
79 end
81 known_patterns[pattern] = result
82 return result
83 end