buildscripts/squish

Fri, 17 Mar 2023 11:07:02 +0000

author
Matthew Wild <mwild1@gmail.com>
date
Fri, 17 Mar 2023 11:07:02 +0000
changeset 472
864c9dc27c60
parent 428
bde804b01f28
permissions
-rwxr-xr-x

buildscripts: Update included squish (now supports Lua 5.2)

#!/usr/bin/lua5.2
package.preload['optlex']=(function(...)
local _ENV=_ENV;
local function e(t,...)
local e=package.loaded[t]or _ENV[t]or{_NAME=t};
package.loaded[t]=e;
for t=1,select("#",...)do
(select(t,...))(e);
end
_ENV=e;
_M=e;
return e;
end
local s=_G
local u=require"string"
local i=u.match
local e=u.sub
local r=u.find
local l=u.rep
local c
error=s.error
warn={}
local n,o,d
local q={
TK_KEYWORD=true,
TK_NAME=true,
TK_NUMBER=true,
TK_STRING=true,
TK_LSTRING=true,
TK_OP=true,
TK_EOS=true,
}
local b={
TK_COMMENT=true,
TK_LCOMMENT=true,
TK_EOL=true,
TK_SPACE=true,
}
local h
local function k(e)
local t=n[e-1]
if e<=1 or t=="TK_EOL"then
return true
elseif t==""then
return k(e-1)
end
return false
end
local function g(e)
local t=n[e+1]
if e>=#n or t=="TK_EOL"or t=="TK_EOS"then
return true
elseif t==""then
return g(e+1)
end
return false
end
local function E(a)
local t=#i(a,"^%-%-%[=*%[")
local a=e(a,t+1,-(t-1))
local e,t=1,0
while true do
local a,n,i,o=r(a,"([\r\n])([\r\n]?)",e)
if not a then break end
e=a+1
t=t+1
if#o>0 and i~=o then
e=e+1
end
end
return t
end
local function v(s,h)
local a=i
local t,e=n[s],n[h]
if t=="TK_STRING"or t=="TK_LSTRING"or
e=="TK_STRING"or e=="TK_LSTRING"then
return""
elseif t=="TK_OP"or e=="TK_OP"then
if(t=="TK_OP"and(e=="TK_KEYWORD"or e=="TK_NAME"))or
(e=="TK_OP"and(t=="TK_KEYWORD"or t=="TK_NAME"))then
return""
end
if t=="TK_OP"and e=="TK_OP"then
local t,e=o[s],o[h]
if(a(t,"^%.%.?$")and a(e,"^%."))or
(a(t,"^[~=<>]$")and e=="=")or
(t=="["and(e=="["or e=="="))then
return" "
end
return""
end
local t=o[s]
if e=="TK_OP"then t=o[h]end
if a(t,"^%.%.?%.?$")then
return" "
end
return""
else
return" "
end
end
local function j()
local a,s,i={},{},{}
local e=1
for t=1,#n do
local n=n[t]
if n~=""then
a[e],s[e],i[e]=n,o[t],d[t]
e=e+1
end
end
n,o,d=a,s,i
end
local function x(r)
local t=o[r]
local t=t
local n
if i(t,"^0[xX]")then
local e=s.tostring(s.tonumber(t))
if#e<=#t then
t=e
else
return
end
end
if i(t,"^%d+%.?0*$")then
t=i(t,"^(%d+)%.?0*$")
if t+0>0 then
t=i(t,"^0*([1-9]%d*)$")
local a=#i(t,"0*$")
local o=s.tostring(a)
if a>#o+1 then
t=e(t,1,#t-a).."e"..o
end
n=t
else
n="0"
end
elseif not i(t,"[eE]")then
local a,t=i(t,"^(%d*)%.(%d+)$")
if a==""then a=0 end
if t+0==0 and a==0 then
n="0"
else
local o=#i(t,"0*$")
if o>0 then
t=e(t,1,#t-o)
end
if a+0>0 then
n=a.."."..t
else
n="."..t
local a=#i(t,"^0*")
local o=#t-a
local a=s.tostring(#t)
if o+2+#a<1+#t then
n=e(t,-o).."e-"..a
end
end
end
else
local t,a=i(t,"^([^eE]+)[eE]([%+%-]?%d+)$")
a=s.tonumber(a)
local h,o=i(t,"^(%d*)%.(%d*)$")
if h then
a=a-#o
t=h..o
end
if t+0==0 then
n="0"
else
local o=#i(t,"^0*")
t=e(t,o+1)
o=#i(t,"0*$")
if o>0 then
t=e(t,1,#t-o)
a=a+o
end
local i=s.tostring(a)
if a==0 then
n=t
elseif a>0 and(a<=1+#i)then
n=t..l("0",a)
elseif a<0 and(a>=-#t)then
o=#t+a
n=e(t,1,o).."."..e(t,o+1)
elseif a<0 and(#i>=-a-#t)then
o=-a-#t
n="."..l("0",o)..t
else
n=t.."e"..a
end
end
end
if n and n~=o[r]then
if h then
c("<number> (line "..d[r]..") "..o[r].." -> "..n)
h=h+1
end
o[r]=n
end
end
local function z(m)
local t=o[m]
local n=e(t,1,1)
local f=(n=="'")and'"'or"'"
local t=e(t,2,-2)
local a=1
local l,s=0,0
while a<=#t do
local c=e(t,a,a)
if c=="\\"then
local o=a+1
local d=e(t,o,o)
local h=r("abfnrtv\\\n\r\"\'0123456789",d,1,true)
if not h then
t=e(t,1,a-1)..e(t,o)
a=a+1
elseif h<=8 then
a=a+2
elseif h<=10 then
local i=e(t,o,o+1)
if i=="\r\n"or i=="\n\r"then
t=e(t,1,a).."\n"..e(t,o+2)
elseif h==10 then
t=e(t,1,a).."\n"..e(t,o+1)
end
a=a+2
elseif h<=12 then
if d==n then
l=l+1
a=a+2
else
s=s+1
t=e(t,1,a-1)..e(t,o)
a=a+1
end
else
local i=i(t,"^(%d%d?%d?)",o)
o=a+1+#i
local d=i+0
local h=u.char(d)
local r=r("\a\b\f\n\r\t\v",h,1,true)
if r then
i="\\"..e("abfnrtv",r,r)
elseif d<32 then
i="\\"..d
elseif h==n then
i="\\"..h
l=l+1
elseif h=="\\"then
i="\\\\"
else
i=h
if h==f then
s=s+1
end
end
t=e(t,1,a-1)..i..e(t,o)
a=a+#i
end
else
a=a+1
if c==f then
s=s+1
end
end
end
if l>s then
a=1
while a<=#t do
local o,s,i=r(t,"([\'\"])",a)
if not o then break end
if i==n then
t=e(t,1,o-2)..e(t,o)
a=o
else
t=e(t,1,o-1).."\\"..e(t,o)
a=o+2
end
end
n=f
end
t=n..t..n
if t~=o[m]then
if h then
c("<string> (line "..d[m]..") "..o[m].." -> "..t)
h=h+1
end
o[m]=t
end
end
local function _(u)
local t=o[u]
local h=i(t,"^%[=*%[")
local a=#h
local c=e(t,-a,-1)
local s=e(t,a+1,-(a+1))
local n=""
local t=1
while true do
local a,o,r,h=r(s,"([\r\n])([\r\n]?)",t)
local o
if not a then
o=e(s,t)
elseif a>=t then
o=e(s,t,a-1)
end
if o~=""then
if i(o,"%s+$")then
warn.lstring="trailing whitespace in long string near line "..d[u]
end
n=n..o
end
if not a then
break
end
t=a+1
if a then
if#h>0 and r~=h then
t=t+1
end
if not(t==1 and t==a)then
n=n.."\n"
end
end
end
if a>=3 then
local e,t=a-1
while e>=2 do
local a="%]"..l("=",e-2).."%]"
if not i(n,a)then t=e end
e=e-1
end
if t then
a=l("=",t-2)
h,c="["..a.."[","]"..a.."]"
end
end
o[u]=h..n..c
end
local function w(u)
local a=o[u]
local h=i(a,"^%-%-%[=*%[")
local t=#h
local d=e(a,-t,-1)
local s=e(a,t+1,-(t-1))
local n=""
local a=1
while true do
local o,t,r,h=r(s,"([\r\n])([\r\n]?)",a)
local t
if not o then
t=e(s,a)
elseif o>=a then
t=e(s,a,o-1)
end
if t~=""then
local a=i(t,"%s*$")
if#a>0 then t=e(t,1,-(a+1))end
n=n..t
end
if not o then
break
end
a=o+1
if o then
if#h>0 and r~=h then
a=a+1
end
n=n.."\n"
end
end
t=t-2
if t>=3 then
local e,a=t-1
while e>=2 do
local t="%]"..l("=",e-2).."%]"
if not i(n,t)then a=e end
e=e-1
end
if a then
t=l("=",a-2)
h,d="--["..t.."[","]"..t.."]"
end
end
o[u]=h..n..d
end
local function p(a)
local t=o[a]
local i=i(t,"%s*$")
if#i>0 then
t=e(t,1,-(i+1))
end
o[a]=t
end
local function A(o,a)
if not o then return false end
local t=i(a,"^%-%-%[=*%[")
local t=#t
local i=e(a,-t,-1)
local e=e(a,t+1,-(t-1))
if r(e,o,1,true)then
return true
end
end
function optimize(t,i,r,a)
local m=t["opt-comments"]
local u=t["opt-whitespace"]
local f=t["opt-emptylines"]
local y=t["opt-eols"]
local I=t["opt-strings"]
local T=t["opt-numbers"]
local O=t.KEEP
h=t.DETAILS and 0
c=c or s.print
if y then
m=true
u=true
f=true
end
n,o,d
=i,r,a
local t=1
local a,r
local s
local function i(i,a,e)
e=e or t
n[e]=i or""
o[e]=a or""
end
while true do
a,r=n[t],o[t]
local h=k(t)
if h then s=nil end
if a=="TK_EOS"then
break
elseif a=="TK_KEYWORD"or
a=="TK_NAME"or
a=="TK_OP"then
s=t
elseif a=="TK_NUMBER"then
if T then
x(t)
end
s=t
elseif a=="TK_STRING"or
a=="TK_LSTRING"then
if I then
if a=="TK_STRING"then
z(t)
else
_(t)
end
end
s=t
elseif a=="TK_COMMENT"then
if m then
if t==1 and e(r,1,1)=="#"then
p(t)
else
i()
end
elseif u then
p(t)
end
elseif a=="TK_LCOMMENT"then
if A(O,r)then
if u then
w(t)
end
s=t
elseif m then
local e=E(r)
if b[n[t+1]]then
i()
a=""
else
i("TK_SPACE"," ")
end
if not f and e>0 then
i("TK_EOL",l("\n",e))
end
if u and a~=""then
t=t-1
end
else
if u then
w(t)
end
s=t
end
elseif a=="TK_EOL"then
if h and f then
i()
elseif r=="\r\n"or r=="\n\r"then
i("TK_EOL","\n")
end
elseif a=="TK_SPACE"then
if u then
if h or g(t)then
i()
else
local a=n[s]
if a=="TK_LCOMMENT"then
i()
else
local e=n[t+1]
if b[e]then
if(e=="TK_COMMENT"or e=="TK_LCOMMENT")and
a=="TK_OP"and o[s]=="-"then
else
i()
end
else
local e=v(s,t+1)
if e==""then
i()
else
i("TK_SPACE"," ")
end
end
end
end
end
else
error("unidentified token encountered")
end
t=t+1
end
j()
if y then
t=1
if n[1]=="TK_COMMENT"then
t=3
end
while true do
a,r=n[t],o[t]
if a=="TK_EOS"then
break
elseif a=="TK_EOL"then
local e,a=n[t-1],n[t+1]
if q[e]and q[a]then
local e=v(t-1,t+1)
if e==""then
i()
end
end
end
t=t+1
end
j()
end
if h and h>0 then c()end
return n,o,d
end
return{optimize=optimize}
end)
package.preload['optparser']=(function(...)
local _ENV=_ENV;
local function e(t,...)
local e=package.loaded[t]or _ENV[t]or{_NAME=t};
package.loaded[t]=e;
for t=1,select("#",...)do
(select(t,...))(e);
end
_ENV=e;
_M=e;
return e;
end
local e=_G
local a=require"string"
local l=require"table"
local s="etaoinshrdlucmfwypvbgkqjxz_ETAOINSHRDLUCMFWYPVBGKQJXZ"
local d="etaoinshrdlucmfwypvbgkqjxz_0123456789ETAOINSHRDLUCMFWYPVBGKQJXZ"
local w={}
for e in a.gmatch([[
and break do else elseif end false for function if in
local nil not or repeat return then true until while
self _ENV]],"%S+")do
w[e]=true
end
local h,u,
m,o,
c,v,
r,
n
local function f(e)
local i={}
for n=1,#e do
local e=e[n]
local o=e.name
if not i[o]then
i[o]={
decl=0,token=0,size=0,
}
end
local t=i[o]
t.decl=t.decl+1
local i=e.xref
local a=#i
t.token=t.token+a
t.size=t.size+a*#o
if e.decl then
e.id=n
e.xcount=a
if a>1 then
e.first=i[2]
e.last=i[a]
end
else
t.id=n
end
end
return i
end
local function y(e)
local i=a.byte
local n=a.char
local a={
TK_KEYWORD=true,TK_NAME=true,TK_NUMBER=true,
TK_STRING=true,TK_LSTRING=true,
}
if not e["opt-comments"]then
a.TK_COMMENT=true
a.TK_LCOMMENT=true
end
local e={}
for t=1,#h do
e[t]=u[t]
end
for t=1,#o do
local t=o[t]
local a=t.xref
for t=1,t.xcount do
local t=a[t]
e[t]=""
end
end
local t={}
for e=0,255 do t[e]=0 end
for o=1,#h do
local o,e=h[o],e[o]
if a[o]then
for a=1,#e do
local e=i(e,a)
t[e]=t[e]+1
end
end
end
local function o(a)
local e={}
for o=1,#a do
local a=i(a,o)
e[o]={c=a,freq=t[a],}
end
l.sort(e,
function(t,e)
return t.freq>e.freq
end
)
local t={}
for a=1,#e do
t[a]=n(e[a].c)
end
return l.concat(t)
end
s=o(s)
d=o(d)
end
local function p()
local t
local n,h=#s,#d
local e=r
if e<n then
e=e+1
t=a.sub(s,e,e)
else
local i,o=n,1
repeat
e=e-i
i=i*h
o=o+1
until i>e
local i=e%n
e=(e-i)/n
i=i+1
t=a.sub(s,i,i)
while o>1 do
local i=e%h
e=(e-i)/h
i=i+1
t=t..a.sub(d,i,i)
o=o-1
end
end
r=r+1
return t,c[t]~=nil
end
function optimize(e,i,t,s,a)
h,u,m,o
=i,t,s,a
r=0
n={}
c=f(m)
v=f(o)
if e["opt-entropy"]then
y(e)
end
local e={}
for t=1,#o do
e[t]=o[t]
end
l.sort(e,
function(t,e)
return t.xcount>e.xcount
end
)
local a,t,r={},1,false
for o=1,#e do
local e=e[o]
if not e.preserve then
a[t]=e
t=t+1
elseif e.name=="self"then
r=true
end
end
e=a
local s=#e
while s>0 do
local h,t
repeat
h,t=p()
until not w[h]
n[#n+1]=h
local a=s
if t then
local i=m[c[h].id].xref
local n=#i
for t=1,s do
local t=e[t]
local s,e=t.act,t.rem
while e<0 do
e=o[-e].rem
end
local o
for t=1,n do
local t=i[t]
if t>=s and t<=e then o=true end
end
if o then
t.skip=true
a=a-1
end
end
end
while a>0 do
local t=1
while e[t].skip do
t=t+1
end
a=a-1
local i=e[t]
t=t+1
i.newname=h
i.skip=true
i.done=true
local s,h=i.first,i.last
local r=i.xref
if s and a>0 then
local n=a
while n>0 do
while e[t].skip do
t=t+1
end
n=n-1
local e=e[t]
t=t+1
local n,t=e.act,e.rem
while t<0 do
t=o[-t].rem
end
if not(h<n or s>t)then
if n>=i.act then
for o=1,i.xcount do
local o=r[o]
if o>=n and o<=t then
a=a-1
e.skip=true
break
end
end
else
if e.last and e.last>=i.act then
a=a-1
e.skip=true
end
end
end
if a==0 then break end
end
end
end
local a,t={},1
for o=1,s do
local e=e[o]
if not e.done then
e.skip=false
a[t]=e
t=t+1
end
end
e=a
s=#e
end
for e=1,#o do
local e=o[e]
local t=e.xref
if e.newname then
for a=1,e.xcount do
local t=t[a]
u[t]=e.newname
end
e.name,e.oldname
=e.newname,e.name
else
e.oldname=e.name
end
end
if r then
n[#n+1]="self"
end
local e=f(o)
end
return{optimize=optimize}
end)
package.preload['llex']=(function(...)
local _ENV=_ENV;
local function e(t,...)
local e=package.loaded[t]or _ENV[t]or{_NAME=t};
package.loaded[t]=e;
for t=1,select("#",...)do
(select(t,...))(e);
end
_ENV=e;
_M=e;
return e;
end
local y=_G
local s=require"string"
local l=s.find
local c=s.match
local n=s.sub
local e=''
local r=''
local a=1
local d=1
local m={}
local w={}
local p={}
local i=''
local v={}
for e in s.gmatch([[
and break do else elseif end false for function if in
local nil not or repeat return then true until while]],"%S+")do
v[e]=true
end
local function o(a,t)
local e=#m+1
m[e]=a
w[e]=t
p[e]=d
end
local function h(t,s)
local n=n
local i=n(e,t,t)
t=t+1
local e=n(e,t,t)
if(e=="\n"or e=="\r")and(e~=i)then
t=t+1
i=i..e
end
if s then o("TK_EOL",i)end
d=d+1
a=t
return t
end
function init(i,t)
e=i
r=t
local t,n,e,i=l(e,"^(#[^\r\n]*)(\r?\n?)")
if t then
a=a+#e
o("TK_COMMENT",e)
if#i>0 then h(a,true)end
end
end
function chunkid()
if r and c(r,"^[=@]")then
return n(r,2)
end
return"[string]"
end
function errorline(t,a)
local e=error or y.error
e(s.format("%s:%d: %s",chunkid(),a or d,t))
end
local r=errorline
local function u(t)
local i=n
local n=i(e,t,t)
t=t+1
local o=#c(e,"=*",t)
t=t+o
a=t
return(i(e,t,t)==n)and o or(-o)-1
end
local function f(d,s)
local t=a+1
local n=n
local o=n(e,t,t)
if o=="\r"or o=="\n"then
t=h(t)
end
local o=t
while true do
local o,c,l=l(e,"([\r\n%]])",t)
if not o then
r(d and"unfinished long string"or
"unfinished long comment")
end
t=o
if l=="]"then
if u(t)==s then
i=n(e,i,a)
a=a+1
return i
end
t=a
else
i=i.."\n"
t=h(t)
end
end
end
local function b(u)
local t=a
local s=l
local d=n
while true do
local n,l,o=s(e,"([\n\r\\\"\'])",t)
if n then
if o=="\n"or o=="\r"then
r("unfinished string")
end
t=n
if o=="\\"then
t=t+1
o=d(e,t,t)
if o==""then break end
n=s("abfnrtv\n\r",o,1,true)
if n then
if n>7 then
t=h(t)
else
t=t+1
end
elseif s(o,"%D")then
t=t+1
else
local o,a,e=s(e,"^(%d%d?%d?)",t)
t=a+1
if e+1>256 then
r("escape sequence too large")
end
end
else
t=t+1
if o==u then
a=t
return d(e,i,t-1)
end
end
else
break
end
end
r("unfinished string")
end
function llex()
local s=l
local d=c
while true do
local t=a
while true do
local c,m,l=s(e,"^([_%a][_%w]*)",t)
if c then
a=t+#l
if v[l]then
o("TK_KEYWORD",l)
else
o("TK_NAME",l)
end
break
end
local l,m,c=s(e,"^(%.?)%d",t)
if l then
if c=="."then t=t+1 end
local u,h,i=s(e,"^%d*[%.%d]*([eE]?)",t)
t=h+1
if#i==1 then
if d(e,"^[%+%-]",t)then
t=t+1
end
end
local i,t=s(e,"^[_%w]*",t)
a=t+1
local e=n(e,l,t)
if not y.tonumber(e)then
r("malformed number")
end
o("TK_NUMBER",e)
break
end
local m,w,c,l=s(e,"^((%s)[ \t\v\f]*)",t)
if m then
if l=="\n"or l=="\r"then
h(t,true)
else
a=w+1
o("TK_SPACE",c)
end
break
end
local h=d(e,"^%p",t)
if h then
i=t
local l=s("-[\"\'.=<>~",h,1,true)
if l then
if l<=2 then
if l==1 then
local r=d(e,"^%-%-(%[?)",t)
if r then
t=t+2
local h=-1
if r=="["then
h=u(t)
end
if h>=0 then
o("TK_LCOMMENT",f(false,h))
else
a=s(e,"[\n\r]",t)or(#e+1)
o("TK_COMMENT",n(e,i,a-1))
end
break
end
else
local e=u(t)
if e>=0 then
o("TK_LSTRING",f(true,e))
elseif e==-1 then
o("TK_OP","[")
else
r("invalid long string delimiter")
end
break
end
elseif l<=5 then
if l<5 then
a=t+1
o("TK_STRING",b(h))
break
end
h=d(e,"^%.%.?%.?",t)
else
h=d(e,"^%p=?",t)
end
end
a=t+#h
o("TK_OP",h)
break
end
local e=n(e,t,t)
if e~=""then
a=t+1
o("TK_OP",e)
break
end
o("TK_EOS","")
return
end
end
end
return{
llex=llex,
init=init,
chunkid=chunkid,
tok=m,
tokln=p,
seminfo=w
}
end)
package.preload['lparser']=(function(...)
local _ENV=_ENV;
local function e(t,...)
local e=package.loaded[t]or _ENV[t]or{_NAME=t};
package.loaded[t]=e;
for t=1,select("#",...)do
(select(t,...))(e);
end
_ENV=e;
_M=e;
return e;
end
local U=_G
local b=require"string"
local D={}
local T,
j,
A,
C,
d,
r,
P,
t,k,l,y,
p,
a,
W,
q,
N,
u,
g,
E
local f,n,w,_,x,v
local e=b.gmatch
local H={}
for e in e("else elseif end until <eof>","%S+")do
H[e]=true
end
local Y={}
for e in e("if while do for repeat function local return break","%S+")do
Y[e]=e.."_stat"
end
local S={}
local V={}
for e,a,t in e([[
{+ 6 6}{- 6 6}{* 7 7}{/ 7 7}{% 7 7}
{^ 10 9}{.. 5 4}
{~= 3 3}{== 3 3}
{< 3 3}{<= 3 3}{> 3 3}{>= 3 3}
{and 2 2}{or 1 1}
]],"{(%S+)%s(%d+)%s(%d+)}")do
S[e]=a+0
V[e]=t+0
end
local Z={["not"]=true,["-"]=true,
["#"]=true,}
local ee=8
local function o(t,a)
local e=error or U.error
e(b.format("(source):%d: %s",a or l,t))
end
local function e()
P=A[d]
t,k,l,y
=T[d],j[d],A[d],C[d]
d=d+1
end
local function X()
return T[d]
end
local function s(a)
local e=t
if e~="<number>"and e~="<string>"then
if e=="<name>"then e=k end
e="'"..e.."'"
end
o(a.." near "..e)
end
local function c(e)
s("'"..e.."' expected")
end
local function o(a)
if t==a then e();return true end
end
local function L(e)
if t~=e then c(e)end
end
local function i(t)
L(t);e()
end
local function F(e,t)
if not e then s(t)end
end
local function h(e,a,t)
if not o(e)then
if t==l then
c(e)
else
s("'"..e.."' expected (to close '"..a.."' at line "..t..")")
end
end
end
local function c()
L("<name>")
local t=k
p=y
e()
return t
end
local function I(e,t)
e.k="VK"
end
local function R(e)
I(e,c())
end
local function m(o,i)
local e=a.bl
local t
if e then
t=e.locallist
else
t=a.locallist
end
local e=#u+1
u[e]={
name=o,
xref={p},
decl=p,
}
if i or o=="_ENV"then
u[e].preserve=true
end
local a=#g+1
g[a]=e
E[a]=t
end
local function z(e)
local t=#g
while e>0 do
e=e-1
local t=t-e
local a=g[t]
local e=u[a]
local o=e.name
e.act=y
g[t]=nil
local i=E[t]
E[t]=nil
local t=i[o]
if t then
e=u[t]
e.rem=-a
end
i[o]=a
end
end
local function O()
local t=a.bl
local e
if t then
e=t.locallist
else
e=a.locallist
end
for t,e in U.pairs(e)do
local e=u[e]
e.rem=y
end
end
local function y(e,t)
if b.sub(e,1,1)=="("then
return
end
m(e,t)
end
local function U(o,a)
local t=o.bl
local e
if t then
e=t.locallist
while e do
if e[a]then return e[a]end
t=t.prev
e=t and t.locallist
end
end
e=o.locallist
return e[a]or-1
end
local function b(t,o,e)
if t==nil then
e.k="VGLOBAL"
return"VGLOBAL"
else
local a=U(t,o)
if a>=0 then
e.k="VLOCAL"
e.id=a
return"VLOCAL"
else
if b(t.prev,o,e)=="VGLOBAL"then
return"VGLOBAL"
end
e.k="VUPVAL"
return"VUPVAL"
end
end
end
local function Q(o)
local t=c()
b(a,t,o)
if o.k=="VGLOBAL"then
local e=N[t]
if not e then
e=#q+1
q[e]={
name=t,
xref={p},
}
N[t]=e
else
local e=q[e].xref
e[#e+1]=p
end
else
local e=o.id
local e=u[e].xref
e[#e+1]=p
end
end
local function p(t)
local e={}
e.isbreakable=t
e.prev=a.bl
e.locallist={}
a.bl=e
end
local function b()
local e=a.bl
O()
a.bl=e.prev
end
local function B()
local e
if not a then
e=W
else
e={}
end
e.prev=a
e.bl=nil
e.locallist={}
a=e
end
local function G()
O()
a=a.prev
end
local function U(t)
local a={}
e()
R(a)
t.k="VINDEXED"
end
local function K(t)
e()
n(t)
i("]")
end
local function M(e)
local e,a={},{}
if t=="<name>"then
R(e)
else
K(e)
end
i("=")
n(a)
end
local function O(e)
if e.v.k=="VVOID"then return end
e.v.k="VVOID"
end
local function O(e)
n(e.v)
end
local function J(a)
local n=l
local e={}
e.v={}
e.t=a
a.k="VRELOCABLE"
e.v.k="VVOID"
i("{")
repeat
if t=="}"then break end
local t=t
if t=="<name>"then
if X()~="="then
O(e)
else
M(e)
end
elseif t=="["then
M(e)
else
O(e)
end
until not o(",")and not o(";")
h("}","{",n)
end
local function X()
local i=0
if t~=")"then
repeat
local t=t
if t=="<name>"then
m(c())
i=i+1
elseif t=="..."then
e()
a.is_vararg=true
else
s("<name> or '...' expected")
end
until a.is_vararg or not o(",")
end
z(i)
end
local function M(n)
local a={}
local i=l
local o=t
if o=="("then
if i~=P then
s("ambiguous syntax (function call x new statement)")
end
e()
if t==")"then
a.k="VVOID"
else
f(a)
end
h(")","(",i)
elseif o=="{"then
J(a)
elseif o=="<string>"then
I(a,k)
e()
else
s("function arguments expected")
return
end
n.k="VCALL"
end
local function P(a)
local t=t
if t=="("then
local t=l
e()
n(a)
h(")","(",t)
elseif t=="<name>"then
Q(a)
else
s("unexpected symbol")
end
end
local function O(a)
P(a)
while true do
local t=t
if t=="."then
U(a)
elseif t=="["then
local e={}
K(e)
elseif t==":"then
local t={}
e()
R(t)
M(a)
elseif t=="("or t=="<string>"or t=="{"then
M(a)
else
return
end
end
end
local function R(o)
local t=t
if t=="<number>"then
o.k="VKNUM"
elseif t=="<string>"then
I(o,k)
elseif t=="nil"then
o.k="VNIL"
elseif t=="true"then
o.k="VTRUE"
elseif t=="false"then
o.k="VFALSE"
elseif t=="..."then
F(a.is_vararg==true,
"cannot use '...' outside a vararg function");
o.k="VVARARG"
elseif t=="{"then
J(o)
return
elseif t=="function"then
e()
x(o,false,l)
return
else
O(o)
return
end
e()
end
local function k(o,n)
local a=t
local i=Z[a]
if i then
e()
k(o,ee)
else
R(o)
end
a=t
local t=S[a]
while t and t>n do
local o={}
e()
local e=k(o,V[a])
a=e
t=S[a]
end
return a
end
function n(e)
k(e,0)
end
local function I(e)
local t={}
local e=e.v.k
F(e=="VLOCAL"or e=="VUPVAL"or e=="VGLOBAL"
or e=="VINDEXED","syntax error")
if o(",")then
local e={}
e.v={}
O(e.v)
I(e)
else
i("=")
f(t)
return
end
t.k="VNONRELOC"
end
local function k(e,t)
i("do")
p(false)
z(e)
w()
b()
end
local function R(e)
local t=r
y("(for index)")
y("(for limit)")
y("(for step)")
m(e)
i("=")
_()
i(",")
_()
if o(",")then
_()
else
end
k(1,true)
end
local function M(e)
local t={}
y("(for generator)")
y("(for state)")
y("(for control)")
m(e)
local e=1
while o(",")do
m(c())
e=e+1
end
i("in")
local a=r
f(t)
k(e,false)
end
local function F(e)
local a=false
Q(e)
while t=="."do
U(e)
end
if t==":"then
a=true
U(e)
end
return a
end
function _()
local e={}
n(e)
end
local function k()
local e={}
n(e)
end
local function S()
e()
k()
i("then")
w()
end
local function P()
local t,e={}
m(c())
t.k="VLOCAL"
z(1)
x(e,false,l)
end
local function U()
local e=0
local t={}
repeat
m(c())
e=e+1
until not o(",")
if o("=")then
f(t)
else
t.k="VVOID"
end
z(e)
end
function f(e)
n(e)
while o(",")do
n(e)
end
end
function x(a,t,e)
B()
i("(")
if t then
y("self",true)
z(1)
end
X()
i(")")
v()
h("end","function",e)
G()
end
function w()
p(false)
v()
b()
end
function for_stat()
local o=r
p(true)
e()
local a=c()
local e=t
if e=="="then
R(a)
elseif e==","or e=="in"then
M(a)
else
s("'=' or 'in' expected")
end
h("end","for",o)
b()
end
function while_stat()
local t=r
e()
k()
p(true)
i("do")
w()
h("end","while",t)
b()
end
function repeat_stat()
local t=r
p(true)
p(false)
e()
v()
h("until","repeat",t)
k()
b()
b()
end
function if_stat()
local a=r
local o={}
S()
while t=="elseif"do
S()
end
if t=="else"then
e()
w()
end
h("end","if",a)
end
function return_stat()
local a={}
e()
local e=t
if H[e]or e==";"then
else
f(a)
end
end
function break_stat()
local t=a.bl
e()
while t and not t.isbreakable do
t=t.prev
end
if not t then
s("no loop to break")
end
end
function expr_stat()
local e={}
e.v={}
O(e.v)
if e.v.k=="VCALL"then
else
e.prev=nil
I(e)
end
end
function function_stat()
local a=r
local o,t={},{}
e()
local e=F(o)
x(t,e,a)
end
function do_stat()
local t=r
e()
w()
h("end","do",t)
end
function local_stat()
e()
if o("function")then
P()
else
U()
end
end
local function i()
r=l
local e=t
local t=Y[e]
if t then
D[t]()
if e=="return"or e=="break"then return true end
else
expr_stat()
end
return false
end
function v()
local e=false
while not e and not H[t]do
e=i()
o(";")
end
end
function parser()
B()
a.is_vararg=true
e()
v()
L("<eof>")
G()
return q,u
end
function init(e,o,n)
d=1
W={}
local t=1
T,j,A,C={},{},{},{}
for a=1,#e do
local e=e[a]
local i=true
if e=="TK_KEYWORD"or e=="TK_OP"then
e=o[a]
elseif e=="TK_NAME"then
e="<name>"
j[t]=o[a]
elseif e=="TK_NUMBER"then
e="<number>"
j[t]=0
elseif e=="TK_STRING"or e=="TK_LSTRING"then
e="<string>"
j[t]=""
elseif e=="TK_EOS"then
e="<eof>"
else
i=false
end
if i then
T[t]=e
A[t]=n[a]
C[t]=a
t=t+1
end
end
q,N,u={},{},{}
g,E={},{}
end
D={
expr=n,
exp1=_,
explist1=f,
body=x,
block=w,
for_stat=for_stat,
while_stat=while_stat,
repeat_stat=repeat_stat,
if_stat=if_stat,
return_stat=return_stat,
break_stat=break_stat,
expr_stat=expr_stat,
function_stat=function_stat,
do_stat=do_stat,
local_stat=local_stat,
chunk=v,
parser=parser,
init=init
}
return D
end)
package.preload['minichunkspy']=(function(...)
local _ENV=_ENV;
local function e(t,...)
local e=package.loaded[t]or _ENV[t]or{_NAME=t};
package.loaded[t]=e;
for t=1,select("#",...)do
(select(t,...))(e);
end
_ENV=e;
_M=e;
return e;
end
local m,t,u=string,table,math
local a,v,n,e=ipairs,setmetatable,type,assert
local a=__END_OF_GLOBALS__
local c,l,i=m.char,m.byte,m.sub
local w,d,g=u.frexp,u.ldexp,u.abs
local p=t.concat
local a=u.huge
local k=a-a
local o=false
local r=4
local s=4
local h=8
local t={}
local function y()
t[#t+1]
={o,r,s,h}
end
local function b()
o,r,s,h
=unpack(t[#t])
t[#t]=nil
end
local function t(e,t)
return e.new(e,t)
end
local f={}
local t=t{
new=
function(e,a)
local a=a or{}
local t=f[e]or{
__index=e,
__call=t
}
f[e]=t
return v(a,t)
end,
}
local j=t{
unpack=function(t,t,e)return nil,e end,
pack=function(e,e)return""end
}
local f={}
local function v(e)
local t=f[e]or t{
unpack=function(o,a,t)
return i(a,t,t+e-1),t+e
end,
pack=function(a,t)return i(t,1,e)end
}
f[e]=t
return t
end
local q=t{
unpack=function(a,t,e)
return l(t,e,e),e+1
end,
pack=function(t,e)return c(e)end
}
local i=t{
unpack=
function(t,e,n)
local i,e,t,a=l(e,n,n+3)
if o then i,e,t,a=a,t,e,i end
return i+e*256+t*256^2+a*256^3,n+4
end,
pack=
function(t,s)
e(n(s)=="number",
"unexpected value type to pack as an uint32")
local i,a,t,e
e=s%2^32
i=e%256;e=(e-i)/256
a=e%256;e=(e-a)/256
t=e%256;e=(e-t)/256
if o then i,a,t,e=e,t,a,i end
return c(i,a,t,e)
end
}
local x=t{
unpack=
function(a,e,t)
local a=i:unpack(e,t)
local e=i:unpack(e,t+4)
if o then a,e=e,a end
return a+e*2^32,t+8
end,
pack=
function(a,t)
e(n(t)=="number",
"unexpected value type to pack as an uint64")
local e=t%2^32
local t=(t-e)/2^32
if o then e,t=t,e end
return i:pack(e)..i:pack(t)
end
}
local function E(e,a)
local t=i:unpack(e,a)
local e=i:unpack(e,a+4)
if o then t,e=e,t end
local a=e%2^20
local t=t
local o=t+a*2^32
e=(e-a)/2^20
local t=e%2^11
local e=e<=t and 1 or-1
return e,t,o
end
local function c(n,a,t)
local e=t%2^32
local t=(t-e)/2^32
local e=e
local t=((n<0 and 2^11 or 0)+a)*2^20+t
if o then e,t=t,e end
return i.pack(nil,e)..i.pack(nil,t)
end
local function _(e)
if e~=e then return e end
if e==0 then e=1/e end
return e>0 and 1 or-1
end
local l=d(1,-1022-52)
local f=l*2^52
local z=d(2^52-1,-1022-52)
local f=d(2^53-1,1023-52)
e(l~=0 and l/2==0)
e(f~=a)
e(f*2==a)
local d=t{
unpack=
function(t,e,i)
local n,o,t=E(e,i)
local e
if o==0 then
e=d(t,-1022-52)
elseif o==2047 then
e=t==0 and a or k
else
e=d(2^52+t,o-1023-52)
end
e=n*e
return e,i+8
end,
pack=
function(t,e)
if e~=e then
return c(1,2047,2^52-1)
end
local o=_(e)
e=g(e)
if e==a then return c(o,2047,0)end
if e==0 then return c(o,0,0)end
local t,a
if e<=z then
t=0
a=e/l
else
local o,e=w(e)
a=(2*o-1)*2^52
t=e+1022
end
return c(o,t,a)
end
}
local a=q
local l={
[4]=i,
[8]=x
}
local w={
[4]=float,
[8]=d
}
local c=t{
unpack=function(a,t,e)
return l[r]:unpack(t,e)
end,
pack=function(t,e)
return l[r]:pack(e)
end,
}
local i=t{
unpack=function(a,e,t)
return l[s]:unpack(e,t)
end,
pack=function(t,e)
return l[s]:pack(e)
end,
}
local g=t{
unpack=function(a,t,e)
return w[h]:unpack(t,e)
end,
pack=function(t,e)
return w[h]:pack(e)
end,
}
local k=v(4)
local f=t{
unpack=
function(t,s,o)
local i={}
local e,a=1,1
while t[e]do
local n=t[e]
local t=n.name
if not t then t,a=a,a+1 end
i[t],o=n:unpack(s,o)
e=e+1
end
return i,o
end,
pack=
function(a,n)
local i={}
local e,t=1,1
while a[e]do
local o=a[e]
local a=o.name
if not a then a,t=t,t+1 end
i[e]=o:pack(n[a])
e=e+1
end
return p(i)
end
}
local d=t{
unpack=
function(n,t,e)
local o,e=i:unpack(t,e)
local a={}
local i=n.type
for o=1,o do
a[o],e=i:unpack(t,e)
end
return a,e
end,
pack=
function(o,a)
local t=#a
local e={i:pack(t)}
local o=o.type
for t=1,t do
e[#e+1]=o:pack(a[t])
end
return p(e)
end
}
local q=t{
unpack=
function(o,a,t)
local t,a=i:unpack(a,t)
e(t==0 or t==1,
"unpacked an unexpected value "..t.." for a Boolean")
return t==1,a
end,
pack=
function(a,t)
e(n(t)=="boolean",
"unexpected value type to pack as a Boolean")
return i:pack(t and 1 or 0)
end
}
local c=t{
unpack=
function(t,a,e)
local t,e=c:unpack(a,e)
local o=nil
if t>0 then
local t=t-1
o=a:sub(e,e+t-1)
end
return o,e+t
end,
pack=
function(a,t)
e(n(t)=="nil"or n(t)=="string",
"unexpected value type to pack as a String")
if t==nil then
return c:pack(0)
end
return c:pack(#t+1)..t.."\000"
end
}
local p=f{
v(4){name="signature"},
a{name="version"},
a{name="format"},
a{name="endianness"},
a{name="sizeof_int"},
a{name="sizeof_size_t"},
a{name="sizeof_insn"},
a{name="sizeof_Number"},
a{name="integral_flag"},
}
local v={
[0]=j,
[1]=q,
[3]=g,
[4]=c,
}
local g=t{
unpack=
function(i,o,t)
local t,i=a:unpack(o,t)
local a=v[t]
e(a,"unknown constant type "..t.." to unpack")
local a,o=a:unpack(o,i)
if t==3 then
e(n(a)=="number")
end
return{
type=t,
value=a
},o
end,
pack=
function(t,e)
local e,t=e.type,e.value
return a:pack(e)..v[e]:pack(t)
end
}
local v=f{
c{name="name"},
i{name="startpc"},
i{name="endpc"}
}
local a=f{
c{name="name"},
i{name="line"},
i{name="last_line"},
a{name="num_upvalues"},
a{name="num_parameters"},
a{name="is_vararg"},
a{name="max_stack_size"},
d{name="insns",type=k},
d{name="constants",type=g},
d{name="prototypes",type=nil},
d{name="source_lines",type=i},
d{name="locals",type=v},
d{name="upvalues",type=c},
}
e(a[10].name=="prototypes",
"missed the function prototype list")
a[10].type=a
local a=t{
unpack=
function(i,d,t)
local n={}
local t,i=p:unpack(d,t)
e(t.signature=="\027Lua","signature check failed")
e(t.version==81,"version mismatch")
e(t.format==0,"format mismatch")
e(t.endianness==0 or
t.endianness==1,"endianness mismatch")
e(l[t.sizeof_int],"int size unsupported")
e(l[t.sizeof_size_t],"size_t size unsupported")
e(t.sizeof_insn==4,"insn size unsupported")
e(w[t.sizeof_Number],"number size unsupported")
e(t.integral_flag==0,"integral flag mismatch; only floats supported")
y()
o=t.endianness==0
r=t.sizeof_size_t
s=t.sizeof_int
h=t.sizeof_Number
n.header=t
n.body,i=a:unpack(d,i)
b()
return n,i
end,
pack=
function(e,t)
local i
y()
local e=t.header
o=e.endianness==0
r=e.sizeof_size_t
s=e.sizeof_int
h=e.sizeof_Number
i=p:pack(t.header)..a:pack(t.body)
b()
return i
end
}
local function o(e)
if n(e)=="function"then
return o(m.dump(e))
end
local t=a:unpack(e,1)
local a=a:pack(t)
if e==a then return true end
local t
local t=u.min(#e,#a)
for t=1,t do
local a=e:sub(t,t)
local e=e:sub(t,t)
if a~=e then
return false,("chunk roundtripping failed: "..
"first byte difference at index %d"):format(t)
end
end
return false,("chunk round tripping failed: "..
"original length %d vs. %d"):format(#e,#a)
end
return{
disassemble=function(e)return a:unpack(e,1)end,
assemble=function(e)return a:pack(e)end,
validate=o
}
end)
do local e={};
e["vio"]="local vio = {};\
vio.__index = vio; \
\9\
function vio.open(string)\
\9return setmetatable({ pos = 1, data = string }, vio);\
end\
\
function vio:read(format, ...)\
\9if self.pos >= #self.data then return; end\
\9if format == \"*a\" then\
\9\9local oldpos = self.pos;\
\9\9self.pos = #self.data;\
\9\9return self.data:sub(oldpos, self.pos);\
\9elseif format == \"*l\" then\
\9\9local data;\
\9\9data, self.pos = self.data:match(\"([^\\r\\n]*)\\r?\\n?()\", self.pos)\
\9\9return data;\
\9elseif format == \"*n\" then\
\9\9local data;\
\9\9data, self.pos = self.data:match(\"(%d+)()\", self.pos)\
\9\9return tonumber(data);\9\
\9elseif type(format) == \"number\" then\
\9\9local oldpos = self.pos;\
\9\9self.pos = self.pos + format;\
\9\9return self.data:sub(oldpos, self.pos-1);\
\9end\
end\
\
function vio:seek(whence, offset)\
\9if type(whence) == \"number\" then\
\9\9whence, offset = \"cur\", whence;\
\9end\
\9offset = offset or 0;\
\9\
\9if whence == \"cur\" then\
\9\9self.pos = self.pos + offset;\
\9elseif whence == \"set\" then\
\9\9self.pos = offset + 1;\
\9elseif whence == \"end\" then\
\9\9self.pos = #self.data - offset;\
\9end\
\9\
\9return self.pos;\
end\
\
local function _readline(f) return f:read(\"*l\"); end\
function vio:lines()\
\9return _readline, self;\
end\
\
function vio:write(...)\
\9for i=1,select('#', ...) do\
\9\9local dat = tostring(select(i, ...));\
\9\9self.data = self.data:sub(1, self.pos-1)..dat..self.data:sub(self.pos+#dat, -1);\
\9end\
end\
\
function vio:close()\
\9self.pos, self.data = nil, nil;\
end\
\
"e["gunzip.lua"]="local base_char,keywords=128,{\"and\",\"break\",\"do\",\"else\",\"elseif\",\"end\",\"false\",\"for\",\"function\",\"if\",\"in\",\"local\",\"nil\",\"not\",\"or\",\"repeat\",\"return\",\"then\",\"true\",\"until\",\"while\",\"read\",\"nbits\",\"nbits_left_in_byte\",\"wnd_pos\",\"output\",\"val\",\"input\",}; function prettify(code) return code:gsub(\"[\"..string.char(base_char)..\"-\"..string.char(base_char+#keywords)..\"]\", \
\9function (c) return keywords[c:byte()-base_char]; end) end return setfenv(assert(loadstring(prettify[===[ i,h,b,m,l,d,e,y,r,w,\
u,v,l,l=\
assert,error,ipairs,pairs,tostring,type,setmetatable,io,math,table.sort,\
math.max,string.char,io.open,_G;\
  p(n)\
 l={};\
 e=e({},l)\
 l:__index(l)\
 n=n(l);e[l]=n\
 n\
\
 e\
\
  l(n,l)\
l=l  1\
h({n},l+1)\
\
  _(n)\
 l={}\
l.outbs=n\
l.wnd={}\
l.=1\
 l\
\
  t(l,e)\
 n=l.\
l.outbs(e)\
l.wnd[n]=e\
l.=n%32768+1\
\
  n(l)\
 i(l,'unexpected end of file')\
\
  o(n,l)\
 n%(l+l)>=l\
\
 a=p((l) 2^l )\
 c=e({},{__mode='k'})\
  g(o)\
 l=1\
 e={}\
 e:()\
 n\
 l<=#o \
n=o:byte(l)\
l=l+1\
\
 n\
\
 e\
\
 l\
  s(d)\
 n,l,o=0,0,{};\
 o:()\
 l\
\
 o:(e)\
e=e  1\
 l<e \
 e=d:()\
  e   \
n=n+a[l]*e\
l=l+8\
\
 o=a[e]\
 a=n%o\
n=(n-a)/o\
l=l-e\
 a\
\
c[o]=\
 o\
\
  f(l)\
 c[l] l  s(g(l))\
\
  s(l)\
 n\
 y.type(l)=='file'\
n=(n)l:write(v(n))\
 d(l)=='function'\
n=l\
\
 n\
\
  d(e,o)\
 l={}\
 o \
 e,n  m(e)\
 n~=0 \
l[#l+1]={=e,=n}\
\
\
\
 n=1,#e-2,2 \
 o,n,e=e[n],e[n+1],e[n+2]\
 n~=0 \
 e=o,e-1 \
l[#l+1]={=e,=n}\
\
\
\
\
w(l,(n,l)\
 n.==l.  n.<l.  n.<l.\
)\
 e=1\
 o=0\
 n,l  b(l)\
 l.~=o \
e=e*a[l.-o]\
o=l.\
\
l.code=e\
e=e+1\
\
 e=r.huge\
 c={}\
 n,l  b(l)\
e=r.min(e,l.)\
c[l.code]=l.\
\
  o(n,e)\
 l=0\
 e=1,e \
 e=n%2\
n=(n-e)/2\
l=l*2+e\
\
 l\
\
 d=p(\
(l) a[e]+o(l,e))\
 l:(a)\
 o,l=1,0\
 1 \
 l==0 \
o=d[n(a:(e))]\
l=l+e\
\
 n=n(a:())\
l=l+1\
o=o*2+n\
\
 l=c[o]\
 l \
 l\
\
\
\
 l\
\
  b(l)\
 a=2^1\
 e=2^2\
 c=2^3\
 d=2^4\
 n=l:(8)\
 n=l:(8)\
 n=l:(8)\
 n=l:(8)\
 t=l:(32)\
 t=l:(8)\
 t=l:(8)\
 o(n,e)\
 n=l:(16)\
 e=0\
 n=1,n \
e=l:(8)\
\
\
 o(n,c)\
 l:(8)~=0  \
\
 o(n,d)\
 l:(8)~=0  \
\
 o(n,a)\
l:(16)\
\
\
  p(l)\
 f=l:(5)\
 i=l:(5)\
 e=n(l:(4))\
 a=e+4\
 e={}\
 o={\
16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}\
 n=1,a \
 l=l:(3)\
 n=o[n]\
e[n]=l\
\
 e=d(e,)\
  r(o)\
 t={}\
 a\
 c=0\
 c<o \
 o=e:(l)\
 e\
 o<=15 \
e=1\
a=o\
 o==16 \
e=3+n(l:(2))\
 o==17 \
e=3+n(l:(3))\
a=0\
 o==18 \
e=11+n(l:(7))\
a=0\
\
h'ASSERT'\
\
 l=1,e \
t[c]=a\
c=c+1\
\
\
 l=d(t,)\
 l\
\
 n=f+257\
 l=i+1\
 n=r(n)\
 l=r(l)\
 n,l\
\
 a\
 o\
 c\
 r\
  h(e,n,l,d)\
 l=l:(e)\
 l<256 \
t(n,l)\
 l==256 \
 \
\
  a \
 l={[257]=3}\
 e=1\
 n=258,285,4 \
 n=n,n+3  l[n]=l[n-1]+e \
 n~=258  e=e*2 \
\
l[285]=258\
a=l\
\
  o \
 l={}\
 e=257,285 \
 n=u(e-261,0)\
l[e]=(n-(n%4))/4\
\
l[285]=0\
o=l\
\
 a=a[l]\
 l=o[l]\
 l=e:(l)\
 o=a+l\
  c \
 e={[0]=1}\
 l=1\
 n=1,29,2 \
 n=n,n+1  e[n]=e[n-1]+l \
 n~=1  l=l*2 \
\
c=e\
\
  r \
 n={}\
 e=0,29 \
 l=u(e-2,0)\
n[e]=(l-(l%2))/2\
\
r=n\
\
 l=d:(e)\
 a=c[l]\
 l=r[l]\
 l=e:(l)\
 l=a+l\
 e=1,o \
 l=(n.-1-l)%32768+1\
t(n,i(n.wnd[l],'invalid distance'))\
\
\
 \
\
  u(l,a)\
 i=l:(1)\
 e=l:(2)\
 r=0\
 o=1\
 c=2\
 f=3\
 e==r \
l:(l:())\
 e=l:(16)\
 o=n(l:(16))\
 e=1,e \
 l=n(l:(8))\
t(a,l)\
\
 e==o  e==c \
 n,o\
 e==c \
n,o=p(l)\
\
n=d{0,8,144,9,256,7,280,8,288,}\
o=d{0,5,32,}\
\
  h(\
l,a,n,o\
);\
\
 i~=0\
\
  e(l)\
 n,l=f(l.)\
,_(s(l.))\
  u(n,l)\
\
 (n)\
 l=f(n.)\
 n=s(n.)\
b(l)\
e{=l,=n}\
l:(l:())\
l:()\
\
]===], '@gunzip.lua')), getfenv())()"e["squish.debug"]="package.preload['minichunkspy']=(function(...)local _ENV=_ENV;local function module(name,...)local t=package.loaded[name]or _ENV[name]or{_NAME=name};package.loaded[name]=t;for i=1,select(\"#\",...)do(select(i,...))(t);end\
_ENV=t;_M=t;return t;end\
local string,table,math=string,table,math\
local ipairs,setmetatable,type,assert=ipairs,setmetatable,type,assert\
local _=__END_OF_GLOBALS__\
local string_char,string_byte,string_sub=string.char,string.byte,string.sub\
local table_concat=table.concat\
local math_abs,math_ldexp,math_frexp=math.abs,math.ldexp,math.frexp\
local Inf=math.huge\
local Nan=Inf-Inf\
local BIG_ENDIAN=false\
local function construct(class,...)return class.new(class,...)end\
local mt_memo={}local Field=construct{new=function(class,self)local self=self or{}local mt=mt_memo[class]or{__index=class,__call=construct}mt_memo[class]=mt\
return setmetatable(self,mt)end,}local None=Field{unpack=function(self,bytes,ix)return nil,ix end,pack=function(self,val)return\"\"end}local char_memo={}local function char(n)local field=char_memo[n]or Field{unpack=function(self,bytes,ix)return string_sub(bytes,ix,ix+n-1),ix+n\
end,pack=function(self,val)return string_sub(val,1,n)end}char_memo[n]=field\
return field\
end\
local uint8=Field{unpack=function(self,bytes,ix)return string_byte(bytes,ix,ix),ix+1\
end,pack=function(self,val)return string_char(val)end}local uint32=Field{unpack=function(self,bytes,ix)local a,b,c,d=string_byte(bytes,ix,ix+3)if BIG_ENDIAN then a,b,c,d=d,c,b,a end\
return a+b*256+c*256^2+d*256^3,ix+4\
end,pack=function(self,val)assert(type(val)==\"number\",\"unexpected value type to pack as an uint32\")local a,b,c,d\
d=val%2^32\
a=d%256;d=(d-a)/256\
b=d%256;d=(d-b)/256\
c=d%256;d=(d-c)/256\
if BIG_ENDIAN then a,b,c,d=d,c,b,a end\
return string_char(a,b,c,d)end}local int32=uint32{unpack=function(self,bytes,ix)local val,ix=uint32:unpack(bytes,ix)return val<2^32 and val or(val-2^31),ix\
end}local Byte=uint8\
local Size_t=uint32\
local Integer=int32\
local Number=char(8)local Insn=char(4)local Struct=Field{unpack=function(self,bytes,ix)local val={}local i,j=1,1\
while self[i]do\
local field=self[i]local key=field.name\
if not key then key,j=j,j+1 end\
val[key],ix=field:unpack(bytes,ix)i=i+1\
end\
return val,ix\
end,pack=function(self,val)local data={}local i,j=1,1\
while self[i]do\
local field=self[i]local key=field.name\
if not key then key,j=j,j+1 end\
data[i]=field:pack(val[key])i=i+1\
end\
return table_concat(data)end}local List=Field{unpack=function(self,bytes,ix)local len,ix=Integer:unpack(bytes,ix)local vals={}local field=self.type\
for i=1,len do\
vals[i],ix=field:unpack(bytes,ix)end\
return vals,ix\
end,pack=function(self,vals)local len=#vals\
local data={Integer:pack(len)}local field=self.type\
for i=1,len do\
data[#data+1]=field:pack(vals[i])end\
return table_concat(data)end}local Boolean=Field{unpack=function(self,bytes,ix)local val,ix=Integer:unpack(bytes,ix)assert(val==0 or val==1,\"unpacked an unexpected value \"..val..\" for a Boolean\")return val==1,ix\
end,pack=function(self,val)assert(type(val)==\"boolean\",\"unexpected value type to pack as a Boolean\")return Integer:pack(val and 1 or 0)end}local String=Field{unpack=function(self,bytes,ix)local len,ix=Integer:unpack(bytes,ix)local val=nil\
if len>0 then\
local string_len=len-1\
val=bytes:sub(ix,ix+string_len-1)end\
return val,ix+len\
end,pack=function(self,val)assert(type(val)==\"nil\"or type(val)==\"string\",\"unexpected value type to pack as a String\")if val==nil then\
return Integer:pack(0)end\
return Integer:pack(#val+1)..val..\"\\0\"end}local ChunkHeader=Struct{char(4){name=\"signature\"},Byte{name=\"version\"},Byte{name=\"format\"},Byte{name=\"endianness\"},Byte{name=\"sizeof_int\"},Byte{name=\"sizeof_size_t\"},Byte{name=\"sizeof_insn\"},Byte{name=\"sizeof_Number\"},Byte{name=\"integral_flag\"},}local ConstantTypes={[0]=None,[1]=Boolean,[3]=Number,[4]=String,}local Constant=Field{unpack=function(self,bytes,ix)local t,ix=Byte:unpack(bytes,ix)local field=ConstantTypes[t]assert(field,\"unknown constant type \"..t..\" to unpack\")local v,ix=field:unpack(bytes,ix)return{type=t,value=v},ix\
end,pack=function(self,val)local t,v=val.type,val.value\
return Byte:pack(t)..ConstantTypes[t]:pack(v)end}local Local=Struct{String{name=\"name\"},Integer{name=\"startpc\"},Integer{name=\"endpc\"}}local Function=Struct{String{name=\"name\"},Integer{name=\"line\"},Integer{name=\"last_line\"},Byte{name=\"num_upvalues\"},Byte{name=\"num_parameters\"},Byte{name=\"is_vararg\"},Byte{name=\"max_stack_size\"},List{name=\"insns\",type=Insn},List{name=\"constants\",type=Constant},List{name=\"prototypes\",type=nil},List{name=\"source_lines\",type=Integer},List{name=\"locals\",type=Local},List{name=\"upvalues\",type=String},}assert(Function[10].name==\"prototypes\",\"missed the function prototype list\")Function[10].type=Function\
local Chunk=Struct{ChunkHeader{name=\"header\"},Function{name=\"body\"}}local function validate(chunk)if type(chunk)==\"function\"then\
return validate(string.dump(chunk))end\
local f=Chunk:unpack(chunk,1)local chunk2=Chunk:pack(f)if chunk==chunk2 then return true end\
local i\
local len=math.min(#chunk,#chunk2)for i=1,len do\
local a=chunk:sub(i,i)local b=chunk:sub(i,i)if a~=b then\
return false,(\"chunk roundtripping failed: \"..\"first byte difference at index %d\"):format(i)end\
end\
return false,(\"chunk round tripping failed: \"..\"original length %d vs. %d\"):format(#chunk,#chunk2)end\
return{disassemble=function(chunk)return Chunk:unpack(chunk,1)end,assemble=function(disassembled)return Chunk:pack(disassembled)end,validate=validate}end)local cs=require\"minichunkspy\"local function ___adjust_chunk(chunk,newname,lineshift)local c=cs.disassemble(string.dump(chunk));c.body.name=newname;lineshift=-c.body.line;local function shiftlines(c)c.line=c.line+lineshift;c.last_line=c.last_line+lineshift;for i,line in ipairs(c.source_lines)do\
c.source_lines[i]=line+lineshift;end\
for i,f in ipairs(c.prototypes)do\
shiftlines(f);end\
end\
shiftlines(c.body);return assert(loadstring(cs.assemble(c),newname))();end\
"function require_resource(t)return e[t]or error("resource '"..tostring(t).."' not found");end end
pcall(require,"luarocks.require");
local o={v="verbose",vv="very_verbose",o="output",q="quiet",qq="very_quiet",g="debug"}
local e={use_http=false,module_compat=not not _ENV};
for t,a in ipairs(arg)do
if a:match("^%-")then
local t=a:match("^%-%-?([^%s=]+)()")
t=(o[t]or t):gsub("%-+","_");
if t:match("^no_")then
t=t:sub(4,-1);
e[t]=false;
else
e[t]=a:match("=(.*)$")or true;
end
else
base_path=a;
end
end
if e.very_verbose then e.verbose=true;end
if e.very_quiet then e.quiet=true;end
local t=function()end
local t,o,s,h=t,t,t,t;
if not e.very_quiet then t=print;end
if not e.quiet then o=print;end
if e.verbose or e.very_verbose then s=print;end
if e.very_verbose then h=print;end
print=s;
local i,d,n={},{},{};
function Module(e)
if i[e]then
s("Ignoring duplicate module definition for "..e);
return function()end
end
local t=#i+1;
i[t]={name=e,url=___fetch_url};
i[e]=i[t];
return function(e)
i[t].path=e;
end
end
function Resource(t,a)
local e=#n+1;
n[e]={name=t,path=a or t};
return function(t)
n[e].path=t;
end
end
function AutoFetchURL(e)
___fetch_url=e;
end
function Main(e)
table.insert(d,e);
end
function Output(t)
if e.output==nil then
out_fn=t;
end
end
function Option(t)
t=t:gsub("%-","_");
if e[t]==nil then
e[t]=true;
return function(a)
e[t]=a;
end
else
return function()end;
end
end
function GetOption(t)
return e[t:gsub('%-','_')];
end
function Message(t)
if not e.quiet then
o(t);
end
end
function Error(a)
if not e.very_quiet then
t(a);
end
end
function Exit()
os.exit(1);
end
base_path=(base_path or"."):gsub("/$","").."/"
squishy_file=base_path.."squishy";
out_fn=e.output;
local r,a=pcall(dofile,squishy_file);
if not r then
t("Couldn't read squishy file: "..a);
os.exit(1);
end
if not out_fn then
t("No output file specified by user or squishy file");
os.exit(1);
elseif#d==0 and#i==0 and#n==0 then
t("No files, modules or resources. Not going to generate an empty file.");
os.exit(1);
end
local r={};
function r.filesystem(e)
local e,t=io.open(e);
if not e then return false,t;end
local t=e:read("*a");
e:close();
return t;
end
if e.use_http then
function r.http(t)
local e=require"socket.http";
local t,e=e.request(t);
if e==200 then
return t;
end
return false,"HTTP status code: "..tostring(e);
end
else
function r.http(e)
return false,"Module not found. Re-squish with --use-http option to fetch it from "..e;
end
end
s("Resolving modules...");
do
local e=package.config:sub(1,1);
local n=package.config:sub(5,5);
local o=package.path:gsub("[^;]+",function(t)
if not t:match("^%"..e)then
return base_path..t;
end
end):gsub("/%./","/");
local a=package.cpath:gsub("[^;]+",function(t)
if not t:match("^%"..e)then
return base_path..t;
end
end):gsub("/%./","/");
function resolve_module(t,a)
t=t:gsub("%.",e);
for e in a:gmatch("[^;]+")do
e=e:gsub("%"..n,t);
h("Looking for "..e)
local t=io.open(e);
if t then
h("Found!");
t:close();
return e;
end
end
return nil;
end
for a,e in ipairs(i)do
if not e.path then
e.path=resolve_module(e.name,o);
if not e.path then
t("Couldn't resolve module: "..e.name);
else
e.path=e.path:gsub("^"..base_path:gsub("%p","%%%1"),"");
end
end
end
end
for a,e in ipairs(i)do
if not e.path then
t("Exiting due to missing modules without a path");
os.exit(1);
end
end
if e.list_files or e.list_missing_files then
local function t(t)
if e.list_missing_files then
local e=io.open(t);
if e then
e:close();
return;
end
end
io.write(t,"\n");
end
for a,e in pairs(d)do
t(e);
end
for a,e in ipairs(i)do
t(e.path);
end
for a,e in ipairs(n)do
t(e.path);
end
return;
end
o("Writing "..out_fn.."...");
local a,l=io.open(out_fn,"w+");
if not a then
t("Couldn't open output file: "..tostring(l));
os.exit(1);
end
if e.executable then
if e.executable==true then
a:write("#!/usr/bin/env lua\n");
else
a:write("#!"..e.executable,"\n");
end
end
s("Packing modules...");
for o,i in ipairs(i)do
local d,s=i.name,i.path;
if i.path:sub(1,1)~="/"then
s=base_path..i.path;
end
h("Packing "..d.." ("..s..")...");
local o,n=r.filesystem(s);
if(not o)and i.url then
local e=i.url:gsub("%?",i.path);
h("Fetching: "..e)
if e:match("^https?://")then
o,n=r.http(e);
elseif e:match("^file://")or e:match("^[/%.]")then
local e,t=io.open((e:gsub("^file://","")));
if e then
o,n=e:read("*a");
e:close();
else
o,n=nil,t;
end
end
end
if o then
o=o:gsub("^#[^\r\n]*\r?\n","");
if not e.debug then
a:write("package.preload['",d,"'] = (function (...)\n");
if e.module_compat then
a:write[[
					local _ENV = _ENV;
					local function module(name, ...)
						local t = package.loaded[name] or _ENV[name] or { _NAME = name };
						package.loaded[name] = t;
						for i = 1, select("#", ...) do
							(select(i, ...))(t);
						end
						_ENV = t;
						_M = t;
						return t;
					end
				]];
end
a:write(o);
a:write(" end)\n");
else
a:write("package.preload['",d,"'] = assert(loadstring(\n");
a:write(("%q\n"):format(o));
a:write(", ",("%q"):format("@"..s),"))\n");
end
else
t("Couldn't pack module '"..d.."': "..(n or"unknown error... path to module file correct?"));
os.exit(1);
end
end
if#n>0 then
s("Packing resources...")
a:write("do local resources = {};\n");
for o,e in ipairs(n)do
local o,e=e.name,e.path;
local e,i=io.open(base_path..e,"rb");
if not e then
t("Couldn't load resource: "..tostring(i));
os.exit(1);
end
local t=e:read("*a");
local e=0;
t:gsub("(=+)",function(t)e=math.max(e,#t);end);
a:write(("resources[%q] = %q"):format(o,t));
end
if e.virtual_io then
local e=require_resource("vio");
if not e then
t("Virtual IO requested but is not enabled in this build of squish");
else
a:write(e,"\n")
a:write[[local io_open, io_lines = io.open, io.lines; function io.open(fn, mode)
					if not resources[fn] then
						return io_open(fn, mode);
					else
						return vio.open(resources[fn]);
				end end
				function io.lines(fn)
					if not resources[fn] then
						return io_lines(fn);
					else
						return vio.open(resources[fn]):lines()
				end end
				local _dofile = dofile;
				function dofile(fn)
					if not resources[fn] then
						return _dofile(fn);
					else
						return assert(loadstring(resources[fn]))();
				end end
				local _loadfile = loadfile;
				function loadfile(fn)
					if not resources[fn] then
						return _loadfile(fn);
					else
						return loadstring(resources[fn], "@"..fn);
				end end ]]
end
end
a:write[[function require_resource(name) return resources[name] or error("resource '"..tostring(name).."' not found"); end end ]]
end
h("Finalising...")
for e,o in pairs(d)do
local e,i=io.open(base_path..o);
if not e then
t("Failed to open "..o..": "..i);
os.exit(1);
else
a:write((e:read("*a"):gsub("^#.-\n","")));
e:close();
end
end
a:close();
o("OK!");
local h=require"optlex"
local r=require"optparser"
local a=require"llex"
local d=require"lparser"
local i={
none={};
debug={"whitespace","locals","entropy","comments","numbers"};
default={"comments","whitespace","emptylines","numbers","locals"};
basic={"comments","whitespace","emptylines"};
full={"comments","whitespace","emptylines","eols","strings","numbers","locals","entropy"};
}
if e.minify_level and not i[e.minify_level]then
t("Unknown minify level: "..e.minify_level);
t("Available minify levels: none, basic, default, full, debug");
end
for a,t in ipairs(i[e.minify_level or"default"]or{})do
if e["minify_"..t]==nil then
e["minify_"..t]=true;
end
end
local n={
["opt-locals"]=e.minify_locals;
["opt-comments"]=e.minify_comments;
["opt-entropy"]=e.minify_entropy;
["opt-whitespace"]=e.minify_whitespace;
["opt-emptylines"]=e.minify_emptylines;
["opt-eols"]=e.minify_eols;
["opt-strings"]=e.minify_strings;
["opt-numbers"]=e.minify_numbers;
}
local function i(e)
t("minify: "..e);os.exit(1);
end
local function l(e)
local t=io.open(e,"rb")
if not t then i("cannot open \""..e.."\" for reading")end
local a=t:read("*a")
if not a then i("cannot read from \""..e.."\"")end
t:close()
return a
end
local function u(e,a)
local t=io.open(e,"wb")
if not t then i("cannot open \""..e.."\" for writing")end
local a=t:write(a)
if not a then i("cannot write to \""..e.."\"")end
t:close()
end
function minify_string(e)
a.init(e)
a.llex()
local t,e,a
=a.tok,a.seminfo,a.tokln
if n["opt-locals"]then
r.print=print
d.init(t,e,a)
local o,a=d.parser()
r.optimize(n,t,e,o,a)
end
h.print=print
t,e,a
=h.optimize(n,t,e,a)
local e=table.concat(e)
if string.find(e,"\r\n",1,1)or
string.find(e,"\n\r",1,1)then
h.warn.mixedeol=true
end
return e;
end
function minify_file(e,t)
local e=l(e);
e=minify_string(e);
u(t,e);
end
if e.minify~=false then
o("Minifying "..out_fn.."...");
minify_file(out_fn,out_fn);
o("OK!");
end
local h=require"llex"
local i=128;
local n={"and","break","do","else","elseif",
"end","false","for","function","if",
"in","local","nil","not","or","repeat",
"return","then","true","until","while"}
function uglify_file(l,o)
local r,a=io.open(l);
if not r then
t("Can't open input file for reading: "..tostring(a));
return;
end
local a,s=io.open(o..".uglified","w+b");
if not a then
t("Can't open output file for writing: "..tostring(s));
return;
end
local s=r:read("*a");
r:close();
local r,t=s:match("^(#.-\n)(.+)$");
local t=t or s;
if r then
a:write(r)
end
while i+#n<=255 and t:find("["..string.char(i).."-"..string.char(i+#n-1).."]")do
i=i+1;
end
if i+#n>255 then
a:write(t);
a:close();
os.rename(o..".uglified",o);
return;
end
local d={}
for t,e in ipairs(n)do
d[e]=string.char(i+t);
end
local r=0;
s:gsub("(=+)",function(e)r=math.max(r,#e);end);
h.init(t,"@"..l);
h.llex()
local s=h.seminfo;
if e.uglify_level=="full"and i+#n<255 then
local e={};
for o,a in ipairs(h.tok)do
if a=="TK_NAME"or a=="TK_STRING"then
local t=string.format("%q,%q",a,s[o]);
if not e[t]then
e[t]={type=a,value=s[o],count=0};
e[#e+1]=e[t];
end
e[t].count=e[t].count+1;
end
end
for t=1,#e do
local e=e[t];
e.score=(e.count)*(#e.value-1)-#string.format("%q",e.value)-1;
end
table.sort(e,function(e,t)return e.score>t.score;end);
local t=255-(i+#n);
for t=t+1,#e do
e[t]=nil;
end
local t=#n;
for a,e in ipairs(e)do
if e.score>0 then
table.insert(n,e.value);
d[e.value]=string.char(i+t+a);
end
end
end
a:write("local base_char,keywords=",tostring(i),",{");
for t,e in ipairs(n)do
a:write(string.format("%q",e),',');
end
a:write[[}; function prettify(code) return code:gsub("["..string.char(base_char).."-"..string.char(base_char+#keywords).."]", 
	function (c) return keywords[c:byte()-base_char]; end) end ]]
a:write[[return setfenv(assert(loadstring(prettify]]
a:write("[",string.rep("=",r+1),"[");
for e,t in ipairs(h.tok)do
if t=="TK_KEYWORD"or t=="TK_NAME"or t=="TK_STRING"then
local t=d[s[e]];
if t then
a:write(t);
else
a:write(s[e]);
end
else
a:write(s[e]);
end
end
a:write("]",string.rep("=",r+1),"]");
a:write(", '@",o,"')), getfenv())()");
a:close();
os.rename(o..".uglified",o);
end
if e.uglify then
o("Uglifying "..out_fn.."...");
uglify_file(out_fn,out_fn);
o("OK!");
end
local i=require"minichunkspy"
function compile_string(t,a)
local o=string.dump(loadstring(t,a));
if((not e.debug)or e.compile_strip)and e.compile_strip~=false then
local t=i.disassemble(o);
local function a(e)
e.source_lines,e.locals,e.upvalues={},{},{};
for t,e in ipairs(e.prototypes)do
a(e);
end
end
s("Stripping debug info...");
a(t.body);
return i.assemble(t);
end
return o;
end
function compile_file(a,e)
local o,a=io.open(a);
if not o then
t("Can't open input file for reading: "..tostring(a));
return;
end
local a,i=io.open(e..".compiled","w+");
if not a then
t("Can't open output file for writing: "..tostring(i));
return;
end
local i=o:read("*a");
o:close();
local t,o=i:match("^(#.-\n)(.+)$");
local o=o or i;
if t then
a:write(t)
end
a:write(compile_string(o,e));
os.rename(e..".compiled",e);
end
if e.compile then
o("Compiling "..out_fn.."...");
compile_file(out_fn,out_fn);
o("OK!");
end
function gzip_file(e,a)
local o,e=io.open(e);
if not o then
t("Can't open input file for reading: "..tostring(e));
return;
end
local e,i=io.open(a..".gzipped","wb+");
if not e then
t("Can't open output file for writing: "..tostring(i));
return;
end
local i=o:read("*a");
o:close();
local n,o=i:match("^(#.-\n)(.+)$");
local o=o or i;
if n then
e:write(n)
end
local i,n=io.open(a..".pregzip","wb+");
if not i then
t("Can't open temp file for writing: "..tostring(n));
return;
end
i:write(o);
i:close();
local t=io.popen("gzip -c '"..a..".pregzip'");
o=t:read("*a");
t:close();
os.remove(a..".pregzip");
local t=0;
o:gsub("(=+)",function(e)t=math.max(t,#e);end);
e:write("local ungz = (function ()",require_resource"gunzip.lua"," end)()\n");
e:write[[return assert(loadstring((function (i)local o={} ungz{input=i,output=function(b)table.insert(o,string.char(b))end}return table.concat(o)end) ]];
e:write((string.format("%q",o):gsub("\026","\\026")));
e:write(", '@",a,"'))()");
e:close();
os.rename(a..".gzipped",a);
end
if e.gzip then
o("Gzipping "..out_fn.."...");
gzip_file(out_fn,out_fn);
o("OK!");
end

mercurial