buildscripts/squish

1
#!/usr/bin/env lua5.4
2
package.preload['optlex']=(function(...)
3
local _ENV=_ENV;
4
local function e(t,...)
5
local e=package.loaded[t]or _ENV[t]or{_NAME=t};
6
package.loaded[t]=e;
7
for t=1,select("#",...)do
8
(select(t,...))(e);
9
end
10
_ENV=e;
11
_M=e;
12
return e;
13
end
14
local s=_G
15
local u=require"string"
16
local i=u.match
17
local e=u.sub
18
local r=u.find
19
local l=u.rep
20
local c
21
error=s.error
22
warn={}
23
local n,o,d
24
local q={
25
TK_KEYWORD=true,
26
TK_NAME=true,
27
TK_NUMBER=true,
28
TK_STRING=true,
29
TK_LSTRING=true,
30
TK_OP=true,
31
TK_EOS=true,
32
}
33
local b={
34
TK_COMMENT=true,
35
TK_LCOMMENT=true,
36
TK_EOL=true,
37
TK_SPACE=true,
38
}
39
local h
40
local function k(e)
41
local t=n[e-1]
42
if e<=1 or t=="TK_EOL"then
43
return true
44
elseif t==""then
45
return k(e-1)
46
end
47
return false
48
end
49
local function g(e)
50
local t=n[e+1]
51
if e>=#n or t=="TK_EOL"or t=="TK_EOS"then
52
return true
53
elseif t==""then
54
return g(e+1)
55
end
56
return false
57
end
58
local function E(a)
59
local t=#i(a,"^%-%-%[=*%[")
60
local a=e(a,t+1,-(t-1))
61
local e,t=1,0
62
while true do
63
local a,n,i,o=r(a,"([\r\n])([\r\n]?)",e)
64
if not a then break end
65
e=a+1
66
t=t+1
67
if#o>0 and i~=o then
68
e=e+1
69
end
70
end
71
return t
72
end
73
local function v(s,h)
74
local a=i
75
local t,e=n[s],n[h]
76
if t=="TK_STRING"or t=="TK_LSTRING"or
77
e=="TK_STRING"or e=="TK_LSTRING"then
78
return""
79
elseif t=="TK_OP"or e=="TK_OP"then
80
if(t=="TK_OP"and(e=="TK_KEYWORD"or e=="TK_NAME"))or
81
(e=="TK_OP"and(t=="TK_KEYWORD"or t=="TK_NAME"))then
82
return""
83
end
84
if t=="TK_OP"and e=="TK_OP"then
85
local t,e=o[s],o[h]
86
if(a(t,"^%.%.?$")and a(e,"^%."))or
87
(a(t,"^[~=<>]$")and e=="=")or
88
(t=="["and(e=="["or e=="="))then
89
return" "
90
end
91
return""
92
end
93
local t=o[s]
94
if e=="TK_OP"then t=o[h]end
95
if a(t,"^%.%.?%.?$")then
96
return" "
97
end
98
return""
99
else
100
return" "
101
end
102
end
103
local function j()
104
local a,s,i={},{},{}
105
local e=1
106
for t=1,#n do
107
local n=n[t]
108
if n~=""then
109
a[e],s[e],i[e]=n,o[t],d[t]
110
e=e+1
111
end
112
end
113
n,o,d=a,s,i
114
end
115
local function x(r)
116
local t=o[r]
117
local t=t
118
local n
119
if i(t,"^0[xX]")then
120
local e=s.tostring(s.tonumber(t))
121
if#e<=#t then
122
t=e
123
else
124
return
125
end
126
end
127
if i(t,"^%d+%.?0*$")then
128
t=i(t,"^(%d+)%.?0*$")
129
if t+0>0 then
130
t=i(t,"^0*([1-9]%d*)$")
131
local a=#i(t,"0*$")
132
local o=s.tostring(a)
133
if a>#o+1 then
134
t=e(t,1,#t-a).."e"..o
135
end
136
n=t
137
else
138
n="0"
139
end
140
elseif not i(t,"[eE]")then
141
local a,t=i(t,"^(%d*)%.(%d+)$")
142
if a==""then a=0 end
143
if t+0==0 and a==0 then
144
n="0"
145
else
146
local o=#i(t,"0*$")
147
if o>0 then
148
t=e(t,1,#t-o)
149
end
150
if a+0>0 then
151
n=a.."."..t
152
else
153
n="."..t
154
local a=#i(t,"^0*")
155
local o=#t-a
156
local a=s.tostring(#t)
157
if o+2+#a<1+#t then
158
n=e(t,-o).."e-"..a
159
end
160
end
161
end
162
else
163
local t,a=i(t,"^([^eE]+)[eE]([%+%-]?%d+)$")
164
a=s.tonumber(a)
165
local h,o=i(t,"^(%d*)%.(%d*)$")
166
if h then
167
a=a-#o
168
t=h..o
169
end
170
if t+0==0 then
171
n="0"
172
else
173
local o=#i(t,"^0*")
174
t=e(t,o+1)
175
o=#i(t,"0*$")
176
if o>0 then
177
t=e(t,1,#t-o)
178
a=a+o
179
end
180
local i=s.tostring(a)
181
if a==0 then
182
n=t
183
elseif a>0 and(a<=1+#i)then
184
n=t..l("0",a)
185
elseif a<0 and(a>=-#t)then
186
o=#t+a
187
n=e(t,1,o).."."..e(t,o+1)
188
elseif a<0 and(#i>=-a-#t)then
189
o=-a-#t
190
n="."..l("0",o)..t
191
else
192
n=t.."e"..a
193
end
194
end
195
end
196
if n and n~=o[r]then
197
if h then
198
c("<number> (line "..d[r]..") "..o[r].." -> "..n)
199
h=h+1
200
end
201
o[r]=n
202
end
203
end
204
local function z(m)
205
local t=o[m]
206
local n=e(t,1,1)
207
local f=(n=="'")and'"'or"'"
208
local t=e(t,2,-2)
209
local a=1
210
local l,s=0,0
211
while a<=#t do
212
local c=e(t,a,a)
213
if c=="\\"then
214
local o=a+1
215
local d=e(t,o,o)
216
local h=r("abfnrtv\\\n\r\"\'0123456789",d,1,true)
217
if not h then
218
t=e(t,1,a-1)..e(t,o)
219
a=a+1
220
elseif h<=8 then
221
a=a+2
222
elseif h<=10 then
223
local i=e(t,o,o+1)
224
if i=="\r\n"or i=="\n\r"then
225
t=e(t,1,a).."\n"..e(t,o+2)
226
elseif h==10 then
227
t=e(t,1,a).."\n"..e(t,o+1)
228
end
229
a=a+2
230
elseif h<=12 then
231
if d==n then
232
l=l+1
233
a=a+2
234
else
235
s=s+1
236
t=e(t,1,a-1)..e(t,o)
237
a=a+1
238
end
239
else
240
local i=i(t,"^(%d%d?%d?)",o)
241
o=a+1+#i
242
local d=i+0
243
local h=u.char(d)
244
local r=r("\a\b\f\n\r\t\v",h,1,true)
245
if r then
246
i="\\"..e("abfnrtv",r,r)
247
elseif d<32 then
248
i="\\"..d
249
elseif h==n then
250
i="\\"..h
251
l=l+1
252
elseif h=="\\"then
253
i="\\\\"
254
else
255
i=h
256
if h==f then
257
s=s+1
258
end
259
end
260
t=e(t,1,a-1)..i..e(t,o)
261
a=a+#i
262
end
263
else
264
a=a+1
265
if c==f then
266
s=s+1
267
end
268
end
269
end
270
if l>s then
271
a=1
272
while a<=#t do
273
local o,s,i=r(t,"([\'\"])",a)
274
if not o then break end
275
if i==n then
276
t=e(t,1,o-2)..e(t,o)
277
a=o
278
else
279
t=e(t,1,o-1).."\\"..e(t,o)
280
a=o+2
281
end
282
end
283
n=f
284
end
285
t=n..t..n
286
if t~=o[m]then
287
if h then
288
c("<string> (line "..d[m]..") "..o[m].." -> "..t)
289
h=h+1
290
end
291
o[m]=t
292
end
293
end
294
local function _(u)
295
local t=o[u]
296
local h=i(t,"^%[=*%[")
297
local a=#h
298
local c=e(t,-a,-1)
299
local s=e(t,a+1,-(a+1))
300
local n=""
301
local t=1
302
while true do
303
local a,o,r,h=r(s,"([\r\n])([\r\n]?)",t)
304
local o
305
if not a then
306
o=e(s,t)
307
elseif a>=t then
308
o=e(s,t,a-1)
309
end
310
if o~=""then
311
if i(o,"%s+$")then
312
warn.lstring="trailing whitespace in long string near line "..d[u]
313
end
314
n=n..o
315
end
316
if not a then
317
break
318
end
319
t=a+1
320
if a then
321
if#h>0 and r~=h then
322
t=t+1
323
end
324
if not(t==1 and t==a)then
325
n=n.."\n"
326
end
327
end
328
end
329
if a>=3 then
330
local e,t=a-1
331
while e>=2 do
332
local a="%]"..l("=",e-2).."%]"
333
if not i(n,a)then t=e end
334
e=e-1
335
end
336
if t then
337
a=l("=",t-2)
338
h,c="["..a.."[","]"..a.."]"
339
end
340
end
341
o[u]=h..n..c
342
end
343
local function w(u)
344
local a=o[u]
345
local h=i(a,"^%-%-%[=*%[")
346
local t=#h
347
local d=e(a,-t,-1)
348
local s=e(a,t+1,-(t-1))
349
local n=""
350
local a=1
351
while true do
352
local o,t,r,h=r(s,"([\r\n])([\r\n]?)",a)
353
local t
354
if not o then
355
t=e(s,a)
356
elseif o>=a then
357
t=e(s,a,o-1)
358
end
359
if t~=""then
360
local a=i(t,"%s*$")
361
if#a>0 then t=e(t,1,-(a+1))end
362
n=n..t
363
end
364
if not o then
365
break
366
end
367
a=o+1
368
if o then
369
if#h>0 and r~=h then
370
a=a+1
371
end
372
n=n.."\n"
373
end
374
end
375
t=t-2
376
if t>=3 then
377
local e,a=t-1
378
while e>=2 do
379
local t="%]"..l("=",e-2).."%]"
380
if not i(n,t)then a=e end
381
e=e-1
382
end
383
if a then
384
t=l("=",a-2)
385
h,d="--["..t.."[","]"..t.."]"
386
end
387
end
388
o[u]=h..n..d
389
end
390
local function p(a)
391
local t=o[a]
392
local i=i(t,"%s*$")
393
if#i>0 then
394
t=e(t,1,-(i+1))
395
end
396
o[a]=t
397
end
398
local function A(o,a)
399
if not o then return false end
400
local t=i(a,"^%-%-%[=*%[")
401
local t=#t
402
local i=e(a,-t,-1)
403
local e=e(a,t+1,-(t-1))
404
if r(e,o,1,true)then
405
return true
406
end
407
end
408
function optimize(t,i,r,a)
409
local m=t["opt-comments"]
410
local u=t["opt-whitespace"]
411
local f=t["opt-emptylines"]
412
local y=t["opt-eols"]
413
local I=t["opt-strings"]
414
local T=t["opt-numbers"]
415
local O=t.KEEP
416
h=t.DETAILS and 0
417
c=c or s.print
418
if y then
419
m=true
420
u=true
421
f=true
422
end
423
n,o,d
424
=i,r,a
425
local t=1
426
local a,r
427
local s
428
local function i(i,a,e)
429
e=e or t
430
n[e]=i or""
431
o[e]=a or""
432
end
433
while true do
434
a,r=n[t],o[t]
435
local h=k(t)
436
if h then s=nil end
437
if a=="TK_EOS"then
438
break
439
elseif a=="TK_KEYWORD"or
440
a=="TK_NAME"or
441
a=="TK_OP"then
442
s=t
443
elseif a=="TK_NUMBER"then
444
if T then
445
x(t)
446
end
447
s=t
448
elseif a=="TK_STRING"or
449
a=="TK_LSTRING"then
450
if I then
451
if a=="TK_STRING"then
452
z(t)
453
else
454
_(t)
455
end
456
end
457
s=t
458
elseif a=="TK_COMMENT"then
459
if m then
460
if t==1 and e(r,1,1)=="#"then
461
p(t)
462
else
463
i()
464
end
465
elseif u then
466
p(t)
467
end
468
elseif a=="TK_LCOMMENT"then
469
if A(O,r)then
470
if u then
471
w(t)
472
end
473
s=t
474
elseif m then
475
local e=E(r)
476
if b[n[t+1]]then
477
i()
478
a=""
479
else
480
i("TK_SPACE"," ")
481
end
482
if not f and e>0 then
483
i("TK_EOL",l("\n",e))
484
end
485
if u and a~=""then
486
t=t-1
487
end
488
else
489
if u then
490
w(t)
491
end
492
s=t
493
end
494
elseif a=="TK_EOL"then
495
if h and f then
496
i()
497
elseif r=="\r\n"or r=="\n\r"then
498
i("TK_EOL","\n")
499
end
500
elseif a=="TK_SPACE"then
501
if u then
502
if h or g(t)then
503
i()
504
else
505
local a=n[s]
506
if a=="TK_LCOMMENT"then
507
i()
508
else
509
local e=n[t+1]
510
if b[e]then
511
if(e=="TK_COMMENT"or e=="TK_LCOMMENT")and
512
a=="TK_OP"and o[s]=="-"then
513
else
514
i()
515
end
516
else
517
local e=v(s,t+1)
518
if e==""then
519
i()
520
else
521
i("TK_SPACE"," ")
522
end
523
end
524
end
525
end
526
end
527
else
528
error("unidentified token encountered")
529
end
530
t=t+1
531
end
532
j()
533
if y then
534
t=1
535
if n[1]=="TK_COMMENT"then
536
t=3
537
end
538
while true do
539
a,r=n[t],o[t]
540
if a=="TK_EOS"then
541
break
542
elseif a=="TK_EOL"then
543
local e,a=n[t-1],n[t+1]
544
if q[e]and q[a]then
545
local e=v(t-1,t+1)
546
if e==""then
547
i()
548
end
549
end
550
end
551
t=t+1
552
end
553
j()
554
end
555
if h and h>0 then c()end
556
return n,o,d
557
end
558
return{optimize=optimize}
559
end)
560
package.preload['optparser']=(function(...)
561
local _ENV=_ENV;
562
local function e(t,...)
563
local e=package.loaded[t]or _ENV[t]or{_NAME=t};
564
package.loaded[t]=e;
565
for t=1,select("#",...)do
566
(select(t,...))(e);
567
end
568
_ENV=e;
569
_M=e;
570
return e;
571
end
572
local e=_G
573
local a=require"string"
574
local l=require"table"
575
local s="etaoinshrdlucmfwypvbgkqjxz_ETAOINSHRDLUCMFWYPVBGKQJXZ"
576
local d="etaoinshrdlucmfwypvbgkqjxz_0123456789ETAOINSHRDLUCMFWYPVBGKQJXZ"
577
local w={}
578
for e in a.gmatch([[
579
and break do else elseif end false for function if in
580
local nil not or repeat return then true until while
581
self _ENV]],"%S+")do
582
w[e]=true
583
end
584
local h,u,
585
m,o,
586
c,v,
587
r,
588
n
589
local function f(e)
590
local i={}
591
for n=1,#e do
592
local e=e[n]
593
local o=e.name
594
if not i[o]then
595
i[o]={
596
decl=0,token=0,size=0,
597
}
598
end
599
local t=i[o]
600
t.decl=t.decl+1
601
local i=e.xref
602
local a=#i
603
t.token=t.token+a
604
t.size=t.size+a*#o
605
if e.decl then
606
e.id=n
607
e.xcount=a
608
if a>1 then
609
e.first=i[2]
610
e.last=i[a]
611
end
612
else
613
t.id=n
614
end
615
end
616
return i
617
end
618
local function y(e)
619
local i=a.byte
620
local n=a.char
621
local a={
622
TK_KEYWORD=true,TK_NAME=true,TK_NUMBER=true,
623
TK_STRING=true,TK_LSTRING=true,
624
}
625
if not e["opt-comments"]then
626
a.TK_COMMENT=true
627
a.TK_LCOMMENT=true
628
end
629
local e={}
630
for t=1,#h do
631
e[t]=u[t]
632
end
633
for t=1,#o do
634
local t=o[t]
635
local a=t.xref
636
for t=1,t.xcount do
637
local t=a[t]
638
e[t]=""
639
end
640
end
641
local t={}
642
for e=0,255 do t[e]=0 end
643
for o=1,#h do
644
local o,e=h[o],e[o]
645
if a[o]then
646
for a=1,#e do
647
local e=i(e,a)
648
t[e]=t[e]+1
649
end
650
end
651
end
652
local function o(a)
653
local e={}
654
for o=1,#a do
655
local a=i(a,o)
656
e[o]={c=a,freq=t[a],}
657
end
658
l.sort(e,
659
function(t,e)
660
return t.freq>e.freq
661
end
662
)
663
local t={}
664
for a=1,#e do
665
t[a]=n(e[a].c)
666
end
667
return l.concat(t)
668
end
669
s=o(s)
670
d=o(d)
671
end
672
local function p()
673
local t
674
local n,h=#s,#d
675
local e=r
676
if e<n then
677
e=e+1
678
t=a.sub(s,e,e)
679
else
680
local i,o=n,1
681
repeat
682
e=e-i
683
i=i*h
684
o=o+1
685
until i>e
686
local i=e%n
687
e=(e-i)/n
688
i=i+1
689
t=a.sub(s,i,i)
690
while o>1 do
691
local i=e%h
692
e=(e-i)/h
693
i=i+1
694
t=t..a.sub(d,i,i)
695
o=o-1
696
end
697
end
698
r=r+1
699
return t,c[t]~=nil
700
end
701
function optimize(e,i,t,s,a)
702
h,u,m,o
703
=i,t,s,a
704
r=0
705
n={}
706
c=f(m)
707
v=f(o)
708
if e["opt-entropy"]then
709
y(e)
710
end
711
local e={}
712
for t=1,#o do
713
e[t]=o[t]
714
end
715
l.sort(e,
716
function(t,e)
717
return t.xcount>e.xcount
718
end
719
)
720
local a,t,r={},1,false
721
for o=1,#e do
722
local e=e[o]
723
if not e.preserve then
724
a[t]=e
725
t=t+1
726
elseif e.name=="self"then
727
r=true
728
end
729
end
730
e=a
731
local s=#e
732
while s>0 do
733
local h,t
734
repeat
735
h,t=p()
736
until not w[h]
737
n[#n+1]=h
738
local a=s
739
if t then
740
local i=m[c[h].id].xref
741
local n=#i
742
for t=1,s do
743
local t=e[t]
744
local s,e=t.act,t.rem
745
while e<0 do
746
e=o[-e].rem
747
end
748
local o
749
for t=1,n do
750
local t=i[t]
751
if t>=s and t<=e then o=true end
752
end
753
if o then
754
t.skip=true
755
a=a-1
756
end
757
end
758
end
759
while a>0 do
760
local t=1
761
while e[t].skip do
762
t=t+1
763
end
764
a=a-1
765
local i=e[t]
766
t=t+1
767
i.newname=h
768
i.skip=true
769
i.done=true
770
local s,h=i.first,i.last
771
local r=i.xref
772
if s and a>0 then
773
local n=a
774
while n>0 do
775
while e[t].skip do
776
t=t+1
777
end
778
n=n-1
779
local e=e[t]
780
t=t+1
781
local n,t=e.act,e.rem
782
while t<0 do
783
t=o[-t].rem
784
end
785
if not(h<n or s>t)then
786
if n>=i.act then
787
for o=1,i.xcount do
788
local o=r[o]
789
if o>=n and o<=t then
790
a=a-1
791
e.skip=true
792
break
793
end
794
end
795
else
796
if e.last and e.last>=i.act then
797
a=a-1
798
e.skip=true
799
end
800
end
801
end
802
if a==0 then break end
803
end
804
end
805
end
806
local a,t={},1
807
for o=1,s do
808
local e=e[o]
809
if not e.done then
810
e.skip=false
811
a[t]=e
812
t=t+1
813
end
814
end
815
e=a
816
s=#e
817
end
818
for e=1,#o do
819
local e=o[e]
820
local t=e.xref
821
if e.newname then
822
for a=1,e.xcount do
823
local t=t[a]
824
u[t]=e.newname
825
end
826
e.name,e.oldname
827
=e.newname,e.name
828
else
829
e.oldname=e.name
830
end
831
end
832
if r then
833
n[#n+1]="self"
834
end
835
local e=f(o)
836
end
837
return{optimize=optimize}
838
end)
839
package.preload['llex']=(function(...)
840
local _ENV=_ENV;
841
local function e(t,...)
842
local e=package.loaded[t]or _ENV[t]or{_NAME=t};
843
package.loaded[t]=e;
844
for t=1,select("#",...)do
845
(select(t,...))(e);
846
end
847
_ENV=e;
848
_M=e;
849
return e;
850
end
851
local y=_G
852
local s=require"string"
853
local l=s.find
854
local c=s.match
855
local n=s.sub
856
local e=''
857
local r=''
858
local a=1
859
local d=1
860
local m={}
861
local w={}
862
local p={}
863
local i=''
864
local v={}
865
for e in s.gmatch([[
866
and break do else elseif end false for function if in
867
local nil not or repeat return then true until while]],"%S+")do
868
v[e]=true
869
end
870
local function o(a,t)
871
local e=#m+1
872
m[e]=a
873
w[e]=t
874
p[e]=d
875
end
876
local function h(t,s)
877
local n=n
878
local i=n(e,t,t)
879
t=t+1
880
local e=n(e,t,t)
881
if(e=="\n"or e=="\r")and(e~=i)then
882
t=t+1
883
i=i..e
884
end
885
if s then o("TK_EOL",i)end
886
d=d+1
887
a=t
888
return t
889
end
890
function init(i,t)
891
e=i
892
r=t
893
local t,n,e,i=l(e,"^(#[^\r\n]*)(\r?\n?)")
894
if t then
895
a=a+#e
896
o("TK_COMMENT",e)
897
if#i>0 then h(a,true)end
898
end
899
end
900
function chunkid()
901
if r and c(r,"^[=@]")then
902
return n(r,2)
903
end
904
return"[string]"
905
end
906
function errorline(t,a)
907
local e=error or y.error
908
e(s.format("%s:%d: %s",chunkid(),a or d,t))
909
end
910
local r=errorline
911
local function u(t)
912
local i=n
913
local n=i(e,t,t)
914
t=t+1
915
local o=#c(e,"=*",t)
916
t=t+o
917
a=t
918
return(i(e,t,t)==n)and o or(-o)-1
919
end
920
local function f(d,s)
921
local t=a+1
922
local n=n
923
local o=n(e,t,t)
924
if o=="\r"or o=="\n"then
925
t=h(t)
926
end
927
local o=t
928
while true do
929
local o,c,l=l(e,"([\r\n%]])",t)
930
if not o then
931
r(d and"unfinished long string"or
932
"unfinished long comment")
933
end
934
t=o
935
if l=="]"then
936
if u(t)==s then
937
i=n(e,i,a)
938
a=a+1
939
return i
940
end
941
t=a
942
else
943
i=i.."\n"
944
t=h(t)
945
end
946
end
947
end
948
local function b(u)
949
local t=a
950
local s=l
951
local d=n
952
while true do
953
local n,l,o=s(e,"([\n\r\\\"\'])",t)
954
if n then
955
if o=="\n"or o=="\r"then
956
r("unfinished string")
957
end
958
t=n
959
if o=="\\"then
960
t=t+1
961
o=d(e,t,t)
962
if o==""then break end
963
n=s("abfnrtv\n\r",o,1,true)
964
if n then
965
if n>7 then
966
t=h(t)
967
else
968
t=t+1
969
end
970
elseif s(o,"%D")then
971
t=t+1
972
else
973
local o,a,e=s(e,"^(%d%d?%d?)",t)
974
t=a+1
975
if e+1>256 then
976
r("escape sequence too large")
977
end
978
end
979
else
980
t=t+1
981
if o==u then
982
a=t
983
return d(e,i,t-1)
984
end
985
end
986
else
987
break
988
end
989
end
990
r("unfinished string")
991
end
992
function llex()
993
local s=l
994
local d=c
995
while true do
996
local t=a
997
while true do
998
local c,m,l=s(e,"^([_%a][_%w]*)",t)
999
if c then
1000
a=t+#l
1001
if v[l]then
1002
o("TK_KEYWORD",l)
1003
else
1004
o("TK_NAME",l)
1005
end
1006
break
1007
end
1008
local l,m,c=s(e,"^(%.?)%d",t)
1009
if l then
1010
if c=="."then t=t+1 end
1011
local u,h,i=s(e,"^%d*[%.%d]*([eE]?)",t)
1012
t=h+1
1013
if#i==1 then
1014
if d(e,"^[%+%-]",t)then
1015
t=t+1
1016
end
1017
end
1018
local i,t=s(e,"^[_%w]*",t)
1019
a=t+1
1020
local e=n(e,l,t)
1021
if not y.tonumber(e)then
1022
r("malformed number")
1023
end
1024
o("TK_NUMBER",e)
1025
break
1026
end
1027
local m,w,c,l=s(e,"^((%s)[ \t\v\f]*)",t)
1028
if m then
1029
if l=="\n"or l=="\r"then
1030
h(t,true)
1031
else
1032
a=w+1
1033
o("TK_SPACE",c)
1034
end
1035
break
1036
end
1037
local h=d(e,"^%p",t)
1038
if h then
1039
i=t
1040
local l=s("-[\"\'.=<>~",h,1,true)
1041
if l then
1042
if l<=2 then
1043
if l==1 then
1044
local r=d(e,"^%-%-(%[?)",t)
1045
if r then
1046
t=t+2
1047
local h=-1
1048
if r=="["then
1049
h=u(t)
1050
end
1051
if h>=0 then
1052
o("TK_LCOMMENT",f(false,h))
1053
else
1054
a=s(e,"[\n\r]",t)or(#e+1)
1055
o("TK_COMMENT",n(e,i,a-1))
1056
end
1057
break
1058
end
1059
else
1060
local e=u(t)
1061
if e>=0 then
1062
o("TK_LSTRING",f(true,e))
1063
elseif e==-1 then
1064
o("TK_OP","[")
1065
else
1066
r("invalid long string delimiter")
1067
end
1068
break
1069
end
1070
elseif l<=5 then
1071
if l<5 then
1072
a=t+1
1073
o("TK_STRING",b(h))
1074
break
1075
end
1076
h=d(e,"^%.%.?%.?",t)
1077
else
1078
h=d(e,"^%p=?",t)
1079
end
1080
end
1081
a=t+#h
1082
o("TK_OP",h)
1083
break
1084
end
1085
local e=n(e,t,t)
1086
if e~=""then
1087
a=t+1
1088
o("TK_OP",e)
1089
break
1090
end
1091
o("TK_EOS","")
1092
return
1093
end
1094
end
1095
end
1096
return{
1097
llex=llex,
1098
init=init,
1099
chunkid=chunkid,
1100
tok=m,
1101
tokln=p,
1102
seminfo=w
1103
}
1104
end)
1105
package.preload['lparser']=(function(...)
1106
local _ENV=_ENV;
1107
local function e(t,...)
1108
local e=package.loaded[t]or _ENV[t]or{_NAME=t};
1109
package.loaded[t]=e;
1110
for t=1,select("#",...)do
1111
(select(t,...))(e);
1112
end
1113
_ENV=e;
1114
_M=e;
1115
return e;
1116
end
1117
local U=_G
1118
local b=require"string"
1119
local D={}
1120
local T,
1121
j,
1122
A,
1123
C,
1124
d,
1125
r,
1126
P,
1127
t,k,l,y,
1128
p,
1129
a,
1130
W,
1131
q,
1132
N,
1133
u,
1134
g,
1135
E
1136
local f,n,w,_,x,v
1137
local e=b.gmatch
1138
local H={}
1139
for e in e("else elseif end until <eof>","%S+")do
1140
H[e]=true
1141
end
1142
local Y={}
1143
for e in e("if while do for repeat function local return break","%S+")do
1144
Y[e]=e.."_stat"
1145
end
1146
local S={}
1147
local V={}
1148
for e,a,t in e([[
1149
{+ 6 6}{- 6 6}{* 7 7}{/ 7 7}{% 7 7}
1150
{^ 10 9}{.. 5 4}
1151
{~= 3 3}{== 3 3}
1152
{< 3 3}{<= 3 3}{> 3 3}{>= 3 3}
1153
{and 2 2}{or 1 1}
1154
]],"{(%S+)%s(%d+)%s(%d+)}")do
1155
S[e]=a+0
1156
V[e]=t+0
1157
end
1158
local Z={["not"]=true,["-"]=true,
1159
["#"]=true,}
1160
local ee=8
1161
local function o(t,a)
1162
local e=error or U.error
1163
e(b.format("(source):%d: %s",a or l,t))
1164
end
1165
local function e()
1166
P=A[d]
1167
t,k,l,y
1168
=T[d],j[d],A[d],C[d]
1169
d=d+1
1170
end
1171
local function X()
1172
return T[d]
1173
end
1174
local function s(a)
1175
local e=t
1176
if e~="<number>"and e~="<string>"then
1177
if e=="<name>"then e=k end
1178
e="'"..e.."'"
1179
end
1180
o(a.." near "..e)
1181
end
1182
local function c(e)
1183
s("'"..e.."' expected")
1184
end
1185
local function o(a)
1186
if t==a then e();return true end
1187
end
1188
local function L(e)
1189
if t~=e then c(e)end
1190
end
1191
local function i(t)
1192
L(t);e()
1193
end
1194
local function F(e,t)
1195
if not e then s(t)end
1196
end
1197
local function h(e,a,t)
1198
if not o(e)then
1199
if t==l then
1200
c(e)
1201
else
1202
s("'"..e.."' expected (to close '"..a.."' at line "..t..")")
1203
end
1204
end
1205
end
1206
local function c()
1207
L("<name>")
1208
local t=k
1209
p=y
1210
e()
1211
return t
1212
end
1213
local function I(e,t)
1214
e.k="VK"
1215
end
1216
local function R(e)
1217
I(e,c())
1218
end
1219
local function m(o,i)
1220
local e=a.bl
1221
local t
1222
if e then
1223
t=e.locallist
1224
else
1225
t=a.locallist
1226
end
1227
local e=#u+1
1228
u[e]={
1229
name=o,
1230
xref={p},
1231
decl=p,
1232
}
1233
if i or o=="_ENV"then
1234
u[e].preserve=true
1235
end
1236
local a=#g+1
1237
g[a]=e
1238
E[a]=t
1239
end
1240
local function z(e)
1241
local t=#g
1242
while e>0 do
1243
e=e-1
1244
local t=t-e
1245
local a=g[t]
1246
local e=u[a]
1247
local o=e.name
1248
e.act=y
1249
g[t]=nil
1250
local i=E[t]
1251
E[t]=nil
1252
local t=i[o]
1253
if t then
1254
e=u[t]
1255
e.rem=-a
1256
end
1257
i[o]=a
1258
end
1259
end
1260
local function O()
1261
local t=a.bl
1262
local e
1263
if t then
1264
e=t.locallist
1265
else
1266
e=a.locallist
1267
end
1268
for t,e in U.pairs(e)do
1269
local e=u[e]
1270
e.rem=y
1271
end
1272
end
1273
local function y(e,t)
1274
if b.sub(e,1,1)=="("then
1275
return
1276
end
1277
m(e,t)
1278
end
1279
local function U(o,a)
1280
local t=o.bl
1281
local e
1282
if t then
1283
e=t.locallist
1284
while e do
1285
if e[a]then return e[a]end
1286
t=t.prev
1287
e=t and t.locallist
1288
end
1289
end
1290
e=o.locallist
1291
return e[a]or-1
1292
end
1293
local function b(t,o,e)
1294
if t==nil then
1295
e.k="VGLOBAL"
1296
return"VGLOBAL"
1297
else
1298
local a=U(t,o)
1299
if a>=0 then
1300
e.k="VLOCAL"
1301
e.id=a
1302
return"VLOCAL"
1303
else
1304
if b(t.prev,o,e)=="VGLOBAL"then
1305
return"VGLOBAL"
1306
end
1307
e.k="VUPVAL"
1308
return"VUPVAL"
1309
end
1310
end
1311
end
1312
local function Q(o)
1313
local t=c()
1314
b(a,t,o)
1315
if o.k=="VGLOBAL"then
1316
local e=N[t]
1317
if not e then
1318
e=#q+1
1319
q[e]={
1320
name=t,
1321
xref={p},
1322
}
1323
N[t]=e
1324
else
1325
local e=q[e].xref
1326
e[#e+1]=p
1327
end
1328
else
1329
local e=o.id
1330
local e=u[e].xref
1331
e[#e+1]=p
1332
end
1333
end
1334
local function p(t)
1335
local e={}
1336
e.isbreakable=t
1337
e.prev=a.bl
1338
e.locallist={}
1339
a.bl=e
1340
end
1341
local function b()
1342
local e=a.bl
1343
O()
1344
a.bl=e.prev
1345
end
1346
local function B()
1347
local e
1348
if not a then
1349
e=W
1350
else
1351
e={}
1352
end
1353
e.prev=a
1354
e.bl=nil
1355
e.locallist={}
1356
a=e
1357
end
1358
local function G()
1359
O()
1360
a=a.prev
1361
end
1362
local function U(t)
1363
local a={}
1364
e()
1365
R(a)
1366
t.k="VINDEXED"
1367
end
1368
local function K(t)
1369
e()
1370
n(t)
1371
i("]")
1372
end
1373
local function M(e)
1374
local e,a={},{}
1375
if t=="<name>"then
1376
R(e)
1377
else
1378
K(e)
1379
end
1380
i("=")
1381
n(a)
1382
end
1383
local function O(e)
1384
if e.v.k=="VVOID"then return end
1385
e.v.k="VVOID"
1386
end
1387
local function O(e)
1388
n(e.v)
1389
end
1390
local function J(a)
1391
local n=l
1392
local e={}
1393
e.v={}
1394
e.t=a
1395
a.k="VRELOCABLE"
1396
e.v.k="VVOID"
1397
i("{")
1398
repeat
1399
if t=="}"then break end
1400
local t=t
1401
if t=="<name>"then
1402
if X()~="="then
1403
O(e)
1404
else
1405
M(e)
1406
end
1407
elseif t=="["then
1408
M(e)
1409
else
1410
O(e)
1411
end
1412
until not o(",")and not o(";")
1413
h("}","{",n)
1414
end
1415
local function X()
1416
local i=0
1417
if t~=")"then
1418
repeat
1419
local t=t
1420
if t=="<name>"then
1421
m(c())
1422
i=i+1
1423
elseif t=="..."then
1424
e()
1425
a.is_vararg=true
1426
else
1427
s("<name> or '...' expected")
1428
end
1429
until a.is_vararg or not o(",")
1430
end
1431
z(i)
1432
end
1433
local function M(n)
1434
local a={}
1435
local i=l
1436
local o=t
1437
if o=="("then
1438
if i~=P then
1439
s("ambiguous syntax (function call x new statement)")
1440
end
1441
e()
1442
if t==")"then
1443
a.k="VVOID"
1444
else
1445
f(a)
1446
end
1447
h(")","(",i)
1448
elseif o=="{"then
1449
J(a)
1450
elseif o=="<string>"then
1451
I(a,k)
1452
e()
1453
else
1454
s("function arguments expected")
1455
return
1456
end
1457
n.k="VCALL"
1458
end
1459
local function P(a)
1460
local t=t
1461
if t=="("then
1462
local t=l
1463
e()
1464
n(a)
1465
h(")","(",t)
1466
elseif t=="<name>"then
1467
Q(a)
1468
else
1469
s("unexpected symbol")
1470
end
1471
end
1472
local function O(a)
1473
P(a)
1474
while true do
1475
local t=t
1476
if t=="."then
1477
U(a)
1478
elseif t=="["then
1479
local e={}
1480
K(e)
1481
elseif t==":"then
1482
local t={}
1483
e()
1484
R(t)
1485
M(a)
1486
elseif t=="("or t=="<string>"or t=="{"then
1487
M(a)
1488
else
1489
return
1490
end
1491
end
1492
end
1493
local function R(o)
1494
local t=t
1495
if t=="<number>"then
1496
o.k="VKNUM"
1497
elseif t=="<string>"then
1498
I(o,k)
1499
elseif t=="nil"then
1500
o.k="VNIL"
1501
elseif t=="true"then
1502
o.k="VTRUE"
1503
elseif t=="false"then
1504
o.k="VFALSE"
1505
elseif t=="..."then
1506
F(a.is_vararg==true,
1507
"cannot use '...' outside a vararg function");
1508
o.k="VVARARG"
1509
elseif t=="{"then
1510
J(o)
1511
return
1512
elseif t=="function"then
1513
e()
1514
x(o,false,l)
1515
return
1516
else
1517
O(o)
1518
return
1519
end
1520
e()
1521
end
1522
local function k(o,n)
1523
local a=t
1524
local i=Z[a]
1525
if i then
1526
e()
1527
k(o,ee)
1528
else
1529
R(o)
1530
end
1531
a=t
1532
local t=S[a]
1533
while t and t>n do
1534
local o={}
1535
e()
1536
local e=k(o,V[a])
1537
a=e
1538
t=S[a]
1539
end
1540
return a
1541
end
1542
function n(e)
1543
k(e,0)
1544
end
1545
local function I(e)
1546
local t={}
1547
local e=e.v.k
1548
F(e=="VLOCAL"or e=="VUPVAL"or e=="VGLOBAL"
1549
or e=="VINDEXED","syntax error")
1550
if o(",")then
1551
local e={}
1552
e.v={}
1553
O(e.v)
1554
I(e)
1555
else
1556
i("=")
1557
f(t)
1558
return
1559
end
1560
t.k="VNONRELOC"
1561
end
1562
local function k(e,t)
1563
i("do")
1564
p(false)
1565
z(e)
1566
w()
1567
b()
1568
end
1569
local function R(e)
1570
local t=r
1571
y("(for index)")
1572
y("(for limit)")
1573
y("(for step)")
1574
m(e)
1575
i("=")
1576
_()
1577
i(",")
1578
_()
1579
if o(",")then
1580
_()
1581
else
1582
end
1583
k(1,true)
1584
end
1585
local function M(e)
1586
local t={}
1587
y("(for generator)")
1588
y("(for state)")
1589
y("(for control)")
1590
m(e)
1591
local e=1
1592
while o(",")do
1593
m(c())
1594
e=e+1
1595
end
1596
i("in")
1597
local a=r
1598
f(t)
1599
k(e,false)
1600
end
1601
local function F(e)
1602
local a=false
1603
Q(e)
1604
while t=="."do
1605
U(e)
1606
end
1607
if t==":"then
1608
a=true
1609
U(e)
1610
end
1611
return a
1612
end
1613
function _()
1614
local e={}
1615
n(e)
1616
end
1617
local function k()
1618
local e={}
1619
n(e)
1620
end
1621
local function S()
1622
e()
1623
k()
1624
i("then")
1625
w()
1626
end
1627
local function P()
1628
local t,e={}
1629
m(c())
1630
t.k="VLOCAL"
1631
z(1)
1632
x(e,false,l)
1633
end
1634
local function U()
1635
local e=0
1636
local t={}
1637
repeat
1638
m(c())
1639
e=e+1
1640
until not o(",")
1641
if o("=")then
1642
f(t)
1643
else
1644
t.k="VVOID"
1645
end
1646
z(e)
1647
end
1648
function f(e)
1649
n(e)
1650
while o(",")do
1651
n(e)
1652
end
1653
end
1654
function x(a,t,e)
1655
B()
1656
i("(")
1657
if t then
1658
y("self",true)
1659
z(1)
1660
end
1661
X()
1662
i(")")
1663
v()
1664
h("end","function",e)
1665
G()
1666
end
1667
function w()
1668
p(false)
1669
v()
1670
b()
1671
end
1672
function for_stat()
1673
local o=r
1674
p(true)
1675
e()
1676
local a=c()
1677
local e=t
1678
if e=="="then
1679
R(a)
1680
elseif e==","or e=="in"then
1681
M(a)
1682
else
1683
s("'=' or 'in' expected")
1684
end
1685
h("end","for",o)
1686
b()
1687
end
1688
function while_stat()
1689
local t=r
1690
e()
1691
k()
1692
p(true)
1693
i("do")
1694
w()
1695
h("end","while",t)
1696
b()
1697
end
1698
function repeat_stat()
1699
local t=r
1700
p(true)
1701
p(false)
1702
e()
1703
v()
1704
h("until","repeat",t)
1705
k()
1706
b()
1707
b()
1708
end
1709
function if_stat()
1710
local a=r
1711
local o={}
1712
S()
1713
while t=="elseif"do
1714
S()
1715
end
1716
if t=="else"then
1717
e()
1718
w()
1719
end
1720
h("end","if",a)
1721
end
1722
function return_stat()
1723
local a={}
1724
e()
1725
local e=t
1726
if H[e]or e==";"then
1727
else
1728
f(a)
1729
end
1730
end
1731
function break_stat()
1732
local t=a.bl
1733
e()
1734
while t and not t.isbreakable do
1735
t=t.prev
1736
end
1737
if not t then
1738
s("no loop to break")
1739
end
1740
end
1741
function expr_stat()
1742
local e={}
1743
e.v={}
1744
O(e.v)
1745
if e.v.k=="VCALL"then
1746
else
1747
e.prev=nil
1748
I(e)
1749
end
1750
end
1751
function function_stat()
1752
local a=r
1753
local o,t={},{}
1754
e()
1755
local e=F(o)
1756
x(t,e,a)
1757
end
1758
function do_stat()
1759
local t=r
1760
e()
1761
w()
1762
h("end","do",t)
1763
end
1764
function local_stat()
1765
e()
1766
if o("function")then
1767
P()
1768
else
1769
U()
1770
end
1771
end
1772
local function i()
1773
r=l
1774
local e=t
1775
local t=Y[e]
1776
if t then
1777
D[t]()
1778
if e=="return"or e=="break"then return true end
1779
else
1780
expr_stat()
1781
end
1782
return false
1783
end
1784
function v()
1785
local e=false
1786
while not e and not H[t]do
1787
e=i()
1788
o(";")
1789
end
1790
end
1791
function parser()
1792
B()
1793
a.is_vararg=true
1794
e()
1795
v()
1796
L("<eof>")
1797
G()
1798
return q,u
1799
end
1800
function init(e,o,n)
1801
d=1
1802
W={}
1803
local t=1
1804
T,j,A,C={},{},{},{}
1805
for a=1,#e do
1806
local e=e[a]
1807
local i=true
1808
if e=="TK_KEYWORD"or e=="TK_OP"then
1809
e=o[a]
1810
elseif e=="TK_NAME"then
1811
e="<name>"
1812
j[t]=o[a]
1813
elseif e=="TK_NUMBER"then
1814
e="<number>"
1815
j[t]=0
1816
elseif e=="TK_STRING"or e=="TK_LSTRING"then
1817
e="<string>"
1818
j[t]=""
1819
elseif e=="TK_EOS"then
1820
e="<eof>"
1821
else
1822
i=false
1823
end
1824
if i then
1825
T[t]=e
1826
A[t]=n[a]
1827
C[t]=a
1828
t=t+1
1829
end
1830
end
1831
q,N,u={},{},{}
1832
g,E={},{}
1833
end
1834
D={
1835
expr=n,
1836
exp1=_,
1837
explist1=f,
1838
body=x,
1839
block=w,
1840
for_stat=for_stat,
1841
while_stat=while_stat,
1842
repeat_stat=repeat_stat,
1843
if_stat=if_stat,
1844
return_stat=return_stat,
1845
break_stat=break_stat,
1846
expr_stat=expr_stat,
1847
function_stat=function_stat,
1848
do_stat=do_stat,
1849
local_stat=local_stat,
1850
chunk=v,
1851
parser=parser,
1852
init=init
1853
}
1854
return D
1855
end)
1856
package.preload['minichunkspy']=(function(...)
1857
local _ENV=_ENV;
1858
local function e(t,...)
1859
local e=package.loaded[t]or _ENV[t]or{_NAME=t};
1860
package.loaded[t]=e;
1861
for t=1,select("#",...)do
1862
(select(t,...))(e);
1863
end
1864
_ENV=e;
1865
_M=e;
1866
return e;
1867
end
1868
local m,t,u=string,table,math
1869
local a,v,n,e=ipairs,setmetatable,type,assert
1870
local a=__END_OF_GLOBALS__
1871
local c,l,i=m.char,m.byte,m.sub
1872
local w,d,g=u.frexp,u.ldexp,u.abs
1873
local p=t.concat
1874
local a=u.huge
1875
local k=a-a
1876
local o=false
1877
local r=4
1878
local s=4
1879
local h=8
1880
local t={}
1881
local function y()
1882
t[#t+1]
1883
={o,r,s,h}
1884
end
1885
local function b()
1886
o,r,s,h
1887
=unpack(t[#t])
1888
t[#t]=nil
1889
end
1890
local function t(e,t)
1891
return e.new(e,t)
1892
end
1893
local f={}
1894
local t=t{
1895
new=
1896
function(e,a)
1897
local a=a or{}
1898
local t=f[e]or{
1899
__index=e,
1900
__call=t
1901
}
1902
f[e]=t
1903
return v(a,t)
1904
end,
1905
}
1906
local j=t{
1907
unpack=function(t,t,e)return nil,e end,
1908
pack=function(e,e)return""end
1909
}
1910
local f={}
1911
local function v(e)
1912
local t=f[e]or t{
1913
unpack=function(o,a,t)
1914
return i(a,t,t+e-1),t+e
1915
end,
1916
pack=function(a,t)return i(t,1,e)end
1917
}
1918
f[e]=t
1919
return t
1920
end
1921
local q=t{
1922
unpack=function(a,t,e)
1923
return l(t,e,e),e+1
1924
end,
1925
pack=function(t,e)return c(e)end
1926
}
1927
local i=t{
1928
unpack=
1929
function(t,e,n)
1930
local i,e,t,a=l(e,n,n+3)
1931
if o then i,e,t,a=a,t,e,i end
1932
return i+e*256+t*256^2+a*256^3,n+4
1933
end,
1934
pack=
1935
function(t,s)
1936
e(n(s)=="number",
1937
"unexpected value type to pack as an uint32")
1938
local i,a,t,e
1939
e=s%2^32
1940
i=e%256;e=(e-i)/256
1941
a=e%256;e=(e-a)/256
1942
t=e%256;e=(e-t)/256
1943
if o then i,a,t,e=e,t,a,i end
1944
return c(i,a,t,e)
1945
end
1946
}
1947
local x=t{
1948
unpack=
1949
function(a,e,t)
1950
local a=i:unpack(e,t)
1951
local e=i:unpack(e,t+4)
1952
if o then a,e=e,a end
1953
return a+e*2^32,t+8
1954
end,
1955
pack=
1956
function(a,t)
1957
e(n(t)=="number",
1958
"unexpected value type to pack as an uint64")
1959
local e=t%2^32
1960
local t=(t-e)/2^32
1961
if o then e,t=t,e end
1962
return i:pack(e)..i:pack(t)
1963
end
1964
}
1965
local function E(e,a)
1966
local t=i:unpack(e,a)
1967
local e=i:unpack(e,a+4)
1968
if o then t,e=e,t end
1969
local a=e%2^20
1970
local t=t
1971
local o=t+a*2^32
1972
e=(e-a)/2^20
1973
local t=e%2^11
1974
local e=e<=t and 1 or-1
1975
return e,t,o
1976
end
1977
local function c(n,a,t)
1978
local e=t%2^32
1979
local t=(t-e)/2^32
1980
local e=e
1981
local t=((n<0 and 2^11 or 0)+a)*2^20+t
1982
if o then e,t=t,e end
1983
return i.pack(nil,e)..i.pack(nil,t)
1984
end
1985
local function _(e)
1986
if e~=e then return e end
1987
if e==0 then e=1/e end
1988
return e>0 and 1 or-1
1989
end
1990
local l=d(1,-1022-52)
1991
local f=l*2^52
1992
local z=d(2^52-1,-1022-52)
1993
local f=d(2^53-1,1023-52)
1994
e(l~=0 and l/2==0)
1995
e(f~=a)
1996
e(f*2==a)
1997
local d=t{
1998
unpack=
1999
function(t,e,i)
2000
local n,o,t=E(e,i)
2001
local e
2002
if o==0 then
2003
e=d(t,-1022-52)
2004
elseif o==2047 then
2005
e=t==0 and a or k
2006
else
2007
e=d(2^52+t,o-1023-52)
2008
end
2009
e=n*e
2010
return e,i+8
2011
end,
2012
pack=
2013
function(t,e)
2014
if e~=e then
2015
return c(1,2047,2^52-1)
2016
end
2017
local o=_(e)
2018
e=g(e)
2019
if e==a then return c(o,2047,0)end
2020
if e==0 then return c(o,0,0)end
2021
local t,a
2022
if e<=z then
2023
t=0
2024
a=e/l
2025
else
2026
local o,e=w(e)
2027
a=(2*o-1)*2^52
2028
t=e+1022
2029
end
2030
return c(o,t,a)
2031
end
2032
}
2033
local a=q
2034
local l={
2035
[4]=i,
2036
[8]=x
2037
}
2038
local w={
2039
[4]=float,
2040
[8]=d
2041
}
2042
local c=t{
2043
unpack=function(a,t,e)
2044
return l[r]:unpack(t,e)
2045
end,
2046
pack=function(t,e)
2047
return l[r]:pack(e)
2048
end,
2049
}
2050
local i=t{
2051
unpack=function(a,e,t)
2052
return l[s]:unpack(e,t)
2053
end,
2054
pack=function(t,e)
2055
return l[s]:pack(e)
2056
end,
2057
}
2058
local g=t{
2059
unpack=function(a,t,e)
2060
return w[h]:unpack(t,e)
2061
end,
2062
pack=function(t,e)
2063
return w[h]:pack(e)
2064
end,
2065
}
2066
local k=v(4)
2067
local f=t{
2068
unpack=
2069
function(t,s,o)
2070
local i={}
2071
local e,a=1,1
2072
while t[e]do
2073
local n=t[e]
2074
local t=n.name
2075
if not t then t,a=a,a+1 end
2076
i[t],o=n:unpack(s,o)
2077
e=e+1
2078
end
2079
return i,o
2080
end,
2081
pack=
2082
function(a,n)
2083
local i={}
2084
local e,t=1,1
2085
while a[e]do
2086
local o=a[e]
2087
local a=o.name
2088
if not a then a,t=t,t+1 end
2089
i[e]=o:pack(n[a])
2090
e=e+1
2091
end
2092
return p(i)
2093
end
2094
}
2095
local d=t{
2096
unpack=
2097
function(n,t,e)
2098
local o,e=i:unpack(t,e)
2099
local a={}
2100
local i=n.type
2101
for o=1,o do
2102
a[o],e=i:unpack(t,e)
2103
end
2104
return a,e
2105
end,
2106
pack=
2107
function(o,a)
2108
local t=#a
2109
local e={i:pack(t)}
2110
local o=o.type
2111
for t=1,t do
2112
e[#e+1]=o:pack(a[t])
2113
end
2114
return p(e)
2115
end
2116
}
2117
local q=t{
2118
unpack=
2119
function(o,a,t)
2120
local t,a=i:unpack(a,t)
2121
e(t==0 or t==1,
2122
"unpacked an unexpected value "..t.." for a Boolean")
2123
return t==1,a
2124
end,
2125
pack=
2126
function(a,t)
2127
e(n(t)=="boolean",
2128
"unexpected value type to pack as a Boolean")
2129
return i:pack(t and 1 or 0)
2130
end
2131
}
2132
local c=t{
2133
unpack=
2134
function(t,a,e)
2135
local t,e=c:unpack(a,e)
2136
local o=nil
2137
if t>0 then
2138
local t=t-1
2139
o=a:sub(e,e+t-1)
2140
end
2141
return o,e+t
2142
end,
2143
pack=
2144
function(a,t)
2145
e(n(t)=="nil"or n(t)=="string",
2146
"unexpected value type to pack as a String")
2147
if t==nil then
2148
return c:pack(0)
2149
end
2150
return c:pack(#t+1)..t.."\000"
2151
end
2152
}
2153
local p=f{
2154
v(4){name="signature"},
2155
a{name="version"},
2156
a{name="format"},
2157
a{name="endianness"},
2158
a{name="sizeof_int"},
2159
a{name="sizeof_size_t"},
2160
a{name="sizeof_insn"},
2161
a{name="sizeof_Number"},
2162
a{name="integral_flag"},
2163
}
2164
local v={
2165
[0]=j,
2166
[1]=q,
2167
[3]=g,
2168
[4]=c,
2169
}
2170
local g=t{
2171
unpack=
2172
function(i,o,t)
2173
local t,i=a:unpack(o,t)
2174
local a=v[t]
2175
e(a,"unknown constant type "..t.." to unpack")
2176
local a,o=a:unpack(o,i)
2177
if t==3 then
2178
e(n(a)=="number")
2179
end
2180
return{
2181
type=t,
2182
value=a
2183
},o
2184
end,
2185
pack=
2186
function(t,e)
2187
local e,t=e.type,e.value
2188
return a:pack(e)..v[e]:pack(t)
2189
end
2190
}
2191
local v=f{
2192
c{name="name"},
2193
i{name="startpc"},
2194
i{name="endpc"}
2195
}
2196
local a=f{
2197
c{name="name"},
2198
i{name="line"},
2199
i{name="last_line"},
2200
a{name="num_upvalues"},
2201
a{name="num_parameters"},
2202
a{name="is_vararg"},
2203
a{name="max_stack_size"},
2204
d{name="insns",type=k},
2205
d{name="constants",type=g},
2206
d{name="prototypes",type=nil},
2207
d{name="source_lines",type=i},
2208
d{name="locals",type=v},
2209
d{name="upvalues",type=c},
2210
}
2211
e(a[10].name=="prototypes",
2212
"missed the function prototype list")
2213
a[10].type=a
2214
local a=t{
2215
unpack=
2216
function(i,d,t)
2217
local n={}
2218
local t,i=p:unpack(d,t)
2219
e(t.signature=="\027Lua","signature check failed")
2220
e(t.version==81,"version mismatch")
2221
e(t.format==0,"format mismatch")
2222
e(t.endianness==0 or
2223
t.endianness==1,"endianness mismatch")
2224
e(l[t.sizeof_int],"int size unsupported")
2225
e(l[t.sizeof_size_t],"size_t size unsupported")
2226
e(t.sizeof_insn==4,"insn size unsupported")
2227
e(w[t.sizeof_Number],"number size unsupported")
2228
e(t.integral_flag==0,"integral flag mismatch; only floats supported")
2229
y()
2230
o=t.endianness==0
2231
r=t.sizeof_size_t
2232
s=t.sizeof_int
2233
h=t.sizeof_Number
2234
n.header=t
2235
n.body,i=a:unpack(d,i)
2236
b()
2237
return n,i
2238
end,
2239
pack=
2240
function(e,t)
2241
local i
2242
y()
2243
local e=t.header
2244
o=e.endianness==0
2245
r=e.sizeof_size_t
2246
s=e.sizeof_int
2247
h=e.sizeof_Number
2248
i=p:pack(t.header)..a:pack(t.body)
2249
b()
2250
return i
2251
end
2252
}
2253
local function o(e)
2254
if n(e)=="function"then
2255
return o(m.dump(e))
2256
end
2257
local t=a:unpack(e,1)
2258
local a=a:pack(t)
2259
if e==a then return true end
2260
local t
2261
local t=u.min(#e,#a)
2262
for t=1,t do
2263
local a=e:sub(t,t)
2264
local e=e:sub(t,t)
2265
if a~=e then
2266
return false,("chunk roundtripping failed: "..
2267
"first byte difference at index %d"):format(t)
2268
end
2269
end
2270
return false,("chunk round tripping failed: "..
2271
"original length %d vs. %d"):format(#e,#a)
2272
end
2273
return{
2274
disassemble=function(e)return a:unpack(e,1)end,
2275
assemble=function(e)return a:pack(e)end,
2276
validate=o
2277
}
2278
end)
2279
do local e={};
2280
e["vio"]="local vio = {};\
2281
vio.__index = vio; \
2282
\9\
2283
function vio.open(string)\
2284
\9return setmetatable({ pos = 1, data = string }, vio);\
2285
end\
2286
\
2287
function vio:read(format, ...)\
2288
\9if self.pos >= #self.data then return; end\
2289
\9if format == \"*a\" then\
2290
\9\9local oldpos = self.pos;\
2291
\9\9self.pos = #self.data;\
2292
\9\9return self.data:sub(oldpos, self.pos);\
2293
\9elseif format == \"*l\" then\
2294
\9\9local data;\
2295
\9\9data, self.pos = self.data:match(\"([^\\r\\n]*)\\r?\\n?()\", self.pos)\
2296
\9\9return data;\
2297
\9elseif format == \"*n\" then\
2298
\9\9local data;\
2299
\9\9data, self.pos = self.data:match(\"(%d+)()\", self.pos)\
2300
\9\9return tonumber(data);\9\
2301
\9elseif type(format) == \"number\" then\
2302
\9\9local oldpos = self.pos;\
2303
\9\9self.pos = self.pos + format;\
2304
\9\9return self.data:sub(oldpos, self.pos-1);\
2305
\9end\
2306
end\
2307
\
2308
function vio:seek(whence, offset)\
2309
\9if type(whence) == \"number\" then\
2310
\9\9whence, offset = \"cur\", whence;\
2311
\9end\
2312
\9offset = offset or 0;\
2313
\9\
2314
\9if whence == \"cur\" then\
2315
\9\9self.pos = self.pos + offset;\
2316
\9elseif whence == \"set\" then\
2317
\9\9self.pos = offset + 1;\
2318
\9elseif whence == \"end\" then\
2319
\9\9self.pos = #self.data - offset;\
2320
\9end\
2321
\9\
2322
\9return self.pos;\
2323
end\
2324
\
2325
local function _readline(f) return f:read(\"*l\"); end\
2326
function vio:lines()\
2327
\9return _readline, self;\
2328
end\
2329
\
2330
function vio:write(...)\
2331
\9for i=1,select('#', ...) do\
2332
\9\9local dat = tostring(select(i, ...));\
2333
\9\9self.data = self.data:sub(1, self.pos-1)..dat..self.data:sub(self.pos+#dat, -1);\
2334
\9end\
2335
end\
2336
\
2337
function vio:close()\
2338
\9self.pos, self.data = nil, nil;\
2339
end\
2340
\
2341
"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)..\"]\", \
2342
\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,\
2343
u,v,l,l=\
2344
assert,error,ipairs,pairs,tostring,type,setmetatable,io,math,table.sort,\
2345
math.max,string.char,io.open,_G;\
2346
� � p(n)\
2347
� l={};\
2348
� e=e({},l)\
2349
� l:__index(l)\
2350
� n=n(l);e[l]=n\
2351
� n\
2352
�\
2353
� e\
2354
�\
2355
� � l(n,l)\
2356
l=l � 1\
2357
h({n},l+1)\
2358
�\
2359
� � _(n)\
2360
� l={}\
2361
l.outbs=n\
2362
l.wnd={}\
2363
l.�=1\
2364
� l\
2365
�\
2366
� � t(l,e)\
2367
� n=l.�\
2368
l.outbs(e)\
2369
l.wnd[n]=e\
2370
l.�=n%32768+1\
2371
�\
2372
� � n(l)\
2373
� i(l,'unexpected end of file')\
2374
�\
2375
� � o(n,l)\
2376
� n%(l+l)>=l\
2377
�\
2378
� a=p(�(l)� 2^l �)\
2379
� c=e({},{__mode='k'})\
2380
� � g(o)\
2381
� l=1\
2382
� e={}\
2383
� e:�()\
2384
� n\
2385
� l<=#o �\
2386
n=o:byte(l)\
2387
l=l+1\
2388
�\
2389
� n\
2390
�\
2391
� e\
2392
�\
2393
� l\
2394
� � s(d)\
2395
� n,l,o=0,0,{};\
2396
� o:�()\
2397
� l\
2398
�\
2399
� o:�(e)\
2400
e=e � 1\
2401
� l<e �\
2402
� e=d:�()\
2403
� � e � � �\
2404
n=n+a[l]*e\
2405
l=l+8\
2406
�\
2407
� o=a[e]\
2408
� a=n%o\
2409
n=(n-a)/o\
2410
l=l-e\
2411
� a\
2412
�\
2413
c[o]=�\
2414
� o\
2415
�\
2416
� � f(l)\
2417
� c[l]� l � s(g(l))\
2418
�\
2419
� � s(l)\
2420
� n\
2421
� y.type(l)=='file'�\
2422
n=�(n)l:write(v(n))�\
2423
� d(l)=='function'�\
2424
n=l\
2425
�\
2426
� n\
2427
�\
2428
� � d(e,o)\
2429
� l={}\
2430
� o �\
2431
� e,n � m(e)�\
2432
� n~=0 �\
2433
l[#l+1]={�=e,�=n}\
2434
�\
2435
�\
2436
�\
2437
� n=1,#e-2,2 �\
2438
� o,n,e=e[n],e[n+1],e[n+2]\
2439
� n~=0 �\
2440
� e=o,e-1 �\
2441
l[#l+1]={�=e,�=n}\
2442
�\
2443
�\
2444
�\
2445
�\
2446
w(l,�(n,l)\
2447
� n.�==l.� � n.�<l.� � n.�<l.�\
2448
�)\
2449
� e=1\
2450
� o=0\
2451
� n,l � b(l)�\
2452
� l.�~=o �\
2453
e=e*a[l.�-o]\
2454
o=l.�\
2455
�\
2456
l.code=e\
2457
e=e+1\
2458
�\
2459
� e=r.huge\
2460
� c={}\
2461
� n,l � b(l)�\
2462
e=r.min(e,l.�)\
2463
c[l.code]=l.�\
2464
�\
2465
� � o(n,e)\
2466
� l=0\
2467
� e=1,e �\
2468
� e=n%2\
2469
n=(n-e)/2\
2470
l=l*2+e\
2471
�\
2472
� l\
2473
�\
2474
� d=p(\
2475
�(l)� a[e]+o(l,e)�)\
2476
� l:�(a)\
2477
� o,l=1,0\
2478
� 1 �\
2479
� l==0 �\
2480
o=d[n(a:�(e))]\
2481
l=l+e\
2482
�\
2483
� n=n(a:�())\
2484
l=l+1\
2485
o=o*2+n\
2486
�\
2487
� l=c[o]\
2488
� l �\
2489
� l\
2490
�\
2491
�\
2492
�\
2493
� l\
2494
�\
2495
� � b(l)\
2496
� a=2^1\
2497
� e=2^2\
2498
� c=2^3\
2499
� d=2^4\
2500
� n=l:�(8)\
2501
� n=l:�(8)\
2502
� n=l:�(8)\
2503
� n=l:�(8)\
2504
� t=l:�(32)\
2505
� t=l:�(8)\
2506
� t=l:�(8)\
2507
� o(n,e)�\
2508
� n=l:�(16)\
2509
� e=0\
2510
� n=1,n �\
2511
e=l:�(8)\
2512
�\
2513
�\
2514
� o(n,c)�\
2515
� l:�(8)~=0 � �\
2516
�\
2517
� o(n,d)�\
2518
� l:�(8)~=0 � �\
2519
�\
2520
� o(n,a)�\
2521
l:�(16)\
2522
�\
2523
�\
2524
� � p(l)\
2525
� f=l:�(5)\
2526
� i=l:�(5)\
2527
� e=n(l:�(4))\
2528
� a=e+4\
2529
� e={}\
2530
� o={\
2531
16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}\
2532
� n=1,a �\
2533
� l=l:�(3)\
2534
� n=o[n]\
2535
e[n]=l\
2536
�\
2537
� e=d(e,�)\
2538
� � r(o)\
2539
� t={}\
2540
� a\
2541
� c=0\
2542
� c<o �\
2543
� o=e:�(l)\
2544
� e\
2545
� o<=15 �\
2546
e=1\
2547
a=o\
2548
� o==16 �\
2549
e=3+n(l:�(2))\
2550
� o==17 �\
2551
e=3+n(l:�(3))\
2552
a=0\
2553
� o==18 �\
2554
e=11+n(l:�(7))\
2555
a=0\
2556
�\
2557
h'ASSERT'\
2558
�\
2559
� l=1,e �\
2560
t[c]=a\
2561
c=c+1\
2562
�\
2563
�\
2564
� l=d(t,�)\
2565
� l\
2566
�\
2567
� n=f+257\
2568
� l=i+1\
2569
� n=r(n)\
2570
� l=r(l)\
2571
� n,l\
2572
�\
2573
� a\
2574
� o\
2575
� c\
2576
� r\
2577
� � h(e,n,l,d)\
2578
� l=l:�(e)\
2579
� l<256 �\
2580
t(n,l)\
2581
� l==256 �\
2582
� �\
2583
�\
2584
� � a �\
2585
� l={[257]=3}\
2586
� e=1\
2587
� n=258,285,4 �\
2588
� n=n,n+3 � l[n]=l[n-1]+e �\
2589
� n~=258 � e=e*2 �\
2590
�\
2591
l[285]=258\
2592
a=l\
2593
�\
2594
� � o �\
2595
� l={}\
2596
� e=257,285 �\
2597
� n=u(e-261,0)\
2598
l[e]=(n-(n%4))/4\
2599
�\
2600
l[285]=0\
2601
o=l\
2602
�\
2603
� a=a[l]\
2604
� l=o[l]\
2605
� l=e:�(l)\
2606
� o=a+l\
2607
� � c �\
2608
� e={[0]=1}\
2609
� l=1\
2610
� n=1,29,2 �\
2611
� n=n,n+1 � e[n]=e[n-1]+l �\
2612
� n~=1 � l=l*2 �\
2613
�\
2614
c=e\
2615
�\
2616
� � r �\
2617
� n={}\
2618
� e=0,29 �\
2619
� l=u(e-2,0)\
2620
n[e]=(l-(l%2))/2\
2621
�\
2622
r=n\
2623
�\
2624
� l=d:�(e)\
2625
� a=c[l]\
2626
� l=r[l]\
2627
� l=e:�(l)\
2628
� l=a+l\
2629
� e=1,o �\
2630
� l=(n.�-1-l)%32768+1\
2631
t(n,i(n.wnd[l],'invalid distance'))\
2632
�\
2633
�\
2634
� �\
2635
�\
2636
� � u(l,a)\
2637
� i=l:�(1)\
2638
� e=l:�(2)\
2639
� r=0\
2640
� o=1\
2641
� c=2\
2642
� f=3\
2643
� e==r �\
2644
l:�(l:�())\
2645
� e=l:�(16)\
2646
� o=n(l:�(16))\
2647
� e=1,e �\
2648
� l=n(l:�(8))\
2649
t(a,l)\
2650
�\
2651
� e==o � e==c �\
2652
� n,o\
2653
� e==c �\
2654
n,o=p(l)\
2655
�\
2656
n=d{0,8,144,9,256,7,280,8,288,�}\
2657
o=d{0,5,32,�}\
2658
�\
2659
� � h(\
2660
l,a,n,o\
2661
);\
2662
�\
2663
� i~=0\
2664
�\
2665
� � e(l)\
2666
� n,l=f(l.�)\
2667
,_(s(l.�))\
2668
� � u(n,l)\
2669
�\
2670
� �(n)\
2671
� l=f(n.�)\
2672
� n=s(n.�)\
2673
b(l)\
2674
e{�=l,�=n}\
2675
l:�(l:�())\
2676
l:�()\
2677
�\
2678
]===], '@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\
2679
_ENV=t;_M=t;return t;end\
2680
local string,table,math=string,table,math\
2681
local ipairs,setmetatable,type,assert=ipairs,setmetatable,type,assert\
2682
local _=__END_OF_GLOBALS__\
2683
local string_char,string_byte,string_sub=string.char,string.byte,string.sub\
2684
local table_concat=table.concat\
2685
local math_abs,math_ldexp,math_frexp=math.abs,math.ldexp,math.frexp\
2686
local Inf=math.huge\
2687
local Nan=Inf-Inf\
2688
local BIG_ENDIAN=false\
2689
local function construct(class,...)return class.new(class,...)end\
2690
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\
2691
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\
2692
end,pack=function(self,val)return string_sub(val,1,n)end}char_memo[n]=field\
2693
return field\
2694
end\
2695
local uint8=Field{unpack=function(self,bytes,ix)return string_byte(bytes,ix,ix),ix+1\
2696
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\
2697
return a+b*256+c*256^2+d*256^3,ix+4\
2698
end,pack=function(self,val)assert(type(val)==\"number\",\"unexpected value type to pack as an uint32\")local a,b,c,d\
2699
d=val%2^32\
2700
a=d%256;d=(d-a)/256\
2701
b=d%256;d=(d-b)/256\
2702
c=d%256;d=(d-c)/256\
2703
if BIG_ENDIAN then a,b,c,d=d,c,b,a end\
2704
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\
2705
end}local Byte=uint8\
2706
local Size_t=uint32\
2707
local Integer=int32\
2708
local Number=char(8)local Insn=char(4)local Struct=Field{unpack=function(self,bytes,ix)local val={}local i,j=1,1\
2709
while self[i]do\
2710
local field=self[i]local key=field.name\
2711
if not key then key,j=j,j+1 end\
2712
val[key],ix=field:unpack(bytes,ix)i=i+1\
2713
end\
2714
return val,ix\
2715
end,pack=function(self,val)local data={}local i,j=1,1\
2716
while self[i]do\
2717
local field=self[i]local key=field.name\
2718
if not key then key,j=j,j+1 end\
2719
data[i]=field:pack(val[key])i=i+1\
2720
end\
2721
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\
2722
for i=1,len do\
2723
vals[i],ix=field:unpack(bytes,ix)end\
2724
return vals,ix\
2725
end,pack=function(self,vals)local len=#vals\
2726
local data={Integer:pack(len)}local field=self.type\
2727
for i=1,len do\
2728
data[#data+1]=field:pack(vals[i])end\
2729
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\
2730
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\
2731
if len>0 then\
2732
local string_len=len-1\
2733
val=bytes:sub(ix,ix+string_len-1)end\
2734
return val,ix+len\
2735
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\
2736
return Integer:pack(0)end\
2737
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\
2738
end,pack=function(self,val)local t,v=val.type,val.value\
2739
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\
2740
local Chunk=Struct{ChunkHeader{name=\"header\"},Function{name=\"body\"}}local function validate(chunk)if type(chunk)==\"function\"then\
2741
return validate(string.dump(chunk))end\
2742
local f=Chunk:unpack(chunk,1)local chunk2=Chunk:pack(f)if chunk==chunk2 then return true end\
2743
local i\
2744
local len=math.min(#chunk,#chunk2)for i=1,len do\
2745
local a=chunk:sub(i,i)local b=chunk:sub(i,i)if a~=b then\
2746
return false,(\"chunk roundtripping failed: \"..\"first byte difference at index %d\"):format(i)end\
2747
end\
2748
return false,(\"chunk round tripping failed: \"..\"original length %d vs. %d\"):format(#chunk,#chunk2)end\
2749
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\
2750
c.source_lines[i]=line+lineshift;end\
2751
for i,f in ipairs(c.prototypes)do\
2752
shiftlines(f);end\
2753
end\
2754
shiftlines(c.body);return assert(loadstring(cs.assemble(c),newname))();end\
2755
"function require_resource(t)return e[t]or error("resource '"..tostring(t).."' not found");end end
2756
pcall(require,"luarocks.require");
2757
local o={v="verbose",vv="very_verbose",o="output",q="quiet",qq="very_quiet",g="debug"}
2758
local e={use_http=false,module_compat=not not _ENV};
2759
for t,a in ipairs(arg)do
2760
if a:match("^%-")then
2761
local t=a:match("^%-%-?([^%s=]+)()")
2762
t=(o[t]or t):gsub("%-+","_");
2763
if t:match("^no_")then
2764
t=t:sub(4,-1);
2765
e[t]=false;
2766
else
2767
e[t]=a:match("=(.*)$")or true;
2768
end
2769
else
2770
base_path=a;
2771
end
2772
end
2773
if e.very_verbose then e.verbose=true;end
2774
if e.very_quiet then e.quiet=true;end
2775
local t=function()end
2776
local t,o,s,h=t,t,t,t;
2777
if not e.very_quiet then t=print;end
2778
if not e.quiet then o=print;end
2779
if e.verbose or e.very_verbose then s=print;end
2780
if e.very_verbose then h=print;end
2781
print=s;
2782
local i,d,n={},{},{};
2783
function Module(e)
2784
if i[e]then
2785
s("Ignoring duplicate module definition for "..e);
2786
return function()end
2787
end
2788
local t=#i+1;
2789
i[t]={name=e,url=___fetch_url};
2790
i[e]=i[t];
2791
return function(e)
2792
i[t].path=e;
2793
end
2794
end
2795
function Resource(t,a)
2796
local e=#n+1;
2797
n[e]={name=t,path=a or t};
2798
return function(t)
2799
n[e].path=t;
2800
end
2801
end
2802
function AutoFetchURL(e)
2803
___fetch_url=e;
2804
end
2805
function Main(e)
2806
table.insert(d,e);
2807
end
2808
function Output(t)
2809
if e.output==nil then
2810
out_fn=t;
2811
end
2812
end
2813
function Option(t)
2814
t=t:gsub("%-","_");
2815
if e[t]==nil then
2816
e[t]=true;
2817
return function(a)
2818
e[t]=a;
2819
end
2820
else
2821
return function()end;
2822
end
2823
end
2824
function GetOption(t)
2825
return e[t:gsub('%-','_')];
2826
end
2827
function Message(t)
2828
if not e.quiet then
2829
o(t);
2830
end
2831
end
2832
function Error(a)
2833
if not e.very_quiet then
2834
t(a);
2835
end
2836
end
2837
function Exit()
2838
os.exit(1);
2839
end
2840
base_path=(base_path or"."):gsub("/$","").."/"
2841
squishy_file=base_path.."squishy";
2842
out_fn=e.output;
2843
local r,a=pcall(dofile,squishy_file);
2844
if not r then
2845
t("Couldn't read squishy file: "..a);
2846
os.exit(1);
2847
end
2848
if not out_fn then
2849
t("No output file specified by user or squishy file");
2850
os.exit(1);
2851
elseif#d==0 and#i==0 and#n==0 then
2852
t("No files, modules or resources. Not going to generate an empty file.");
2853
os.exit(1);
2854
end
2855
local r={};
2856
function r.filesystem(e)
2857
local e,t=io.open(e);
2858
if not e then return false,t;end
2859
local t=e:read("*a");
2860
e:close();
2861
return t;
2862
end
2863
if e.use_http then
2864
function r.http(t)
2865
local e=require"socket.http";
2866
local t,e=e.request(t);
2867
if e==200 then
2868
return t;
2869
end
2870
return false,"HTTP status code: "..tostring(e);
2871
end
2872
else
2873
function r.http(e)
2874
return false,"Module not found. Re-squish with --use-http option to fetch it from "..e;
2875
end
2876
end
2877
s("Resolving modules...");
2878
do
2879
local e=package.config:sub(1,1);
2880
local n=package.config:sub(5,5);
2881
local o=package.path:gsub("[^;]+",function(t)
2882
if not t:match("^%"..e)then
2883
return base_path..t;
2884
end
2885
end):gsub("/%./","/");
2886
local a=package.cpath:gsub("[^;]+",function(t)
2887
if not t:match("^%"..e)then
2888
return base_path..t;
2889
end
2890
end):gsub("/%./","/");
2891
function resolve_module(t,a)
2892
t=t:gsub("%.",e);
2893
for e in a:gmatch("[^;]+")do
2894
e=e:gsub("%"..n,t);
2895
h("Looking for "..e)
2896
local t=io.open(e);
2897
if t then
2898
h("Found!");
2899
t:close();
2900
return e;
2901
end
2902
end
2903
return nil;
2904
end
2905
for a,e in ipairs(i)do
2906
if not e.path then
2907
e.path=resolve_module(e.name,o);
2908
if not e.path then
2909
t("Couldn't resolve module: "..e.name);
2910
else
2911
e.path=e.path:gsub("^"..base_path:gsub("%p","%%%1"),"");
2912
end
2913
end
2914
end
2915
end
2916
for a,e in ipairs(i)do
2917
if not e.path then
2918
t("Exiting due to missing modules without a path");
2919
os.exit(1);
2920
end
2921
end
2922
if e.list_files or e.list_missing_files then
2923
local function t(t)
2924
if e.list_missing_files then
2925
local e=io.open(t);
2926
if e then
2927
e:close();
2928
return;
2929
end
2930
end
2931
io.write(t,"\n");
2932
end
2933
for a,e in pairs(d)do
2934
t(e);
2935
end
2936
for a,e in ipairs(i)do
2937
t(e.path);
2938
end
2939
for a,e in ipairs(n)do
2940
t(e.path);
2941
end
2942
return;
2943
end
2944
o("Writing "..out_fn.."...");
2945
local a,l=io.open(out_fn,"w+");
2946
if not a then
2947
t("Couldn't open output file: "..tostring(l));
2948
os.exit(1);
2949
end
2950
if e.executable then
2951
if e.executable==true then
2952
a:write("#!/usr/bin/env lua\n");
2953
else
2954
a:write("#!"..e.executable,"\n");
2955
end
2956
end
2957
s("Packing modules...");
2958
for o,i in ipairs(i)do
2959
local d,s=i.name,i.path;
2960
if i.path:sub(1,1)~="/"then
2961
s=base_path..i.path;
2962
end
2963
h("Packing "..d.." ("..s..")...");
2964
local o,n=r.filesystem(s);
2965
if(not o)and i.url then
2966
local e=i.url:gsub("%?",i.path);
2967
h("Fetching: "..e)
2968
if e:match("^https?://")then
2969
o,n=r.http(e);
2970
elseif e:match("^file://")or e:match("^[/%.]")then
2971
local e,t=io.open((e:gsub("^file://","")));
2972
if e then
2973
o,n=e:read("*a");
2974
e:close();
2975
else
2976
o,n=nil,t;
2977
end
2978
end
2979
end
2980
if o then
2981
o=o:gsub("^#[^\r\n]*\r?\n","");
2982
if not e.debug then
2983
a:write("package.preload['",d,"'] = (function (...)\n");
2984
if e.module_compat then
2985
a:write[[
2986
					local _ENV = _ENV;
2987
					local function module(name, ...)
2988
						local t = package.loaded[name] or _ENV[name] or { _NAME = name };
2989
						package.loaded[name] = t;
2990
						for i = 1, select("#", ...) do
2991
							(select(i, ...))(t);
2992
						end
2993
						_ENV = t;
2994
						_M = t;
2995
						return t;
2996
					end
2997
				]];
2998
end
2999
a:write(o);
3000
a:write(" end)\n");
3001
else
3002
a:write("package.preload['",d,"'] = assert(loadstring(\n");
3003
a:write(("%q\n"):format(o));
3004
a:write(", ",("%q"):format("@"..s),"))\n");
3005
end
3006
else
3007
t("Couldn't pack module '"..d.."': "..(n or"unknown error... path to module file correct?"));
3008
os.exit(1);
3009
end
3010
end
3011
if#n>0 then
3012
s("Packing resources...")
3013
a:write("do local resources = {};\n");
3014
for o,e in ipairs(n)do
3015
local o,e=e.name,e.path;
3016
local e,i=io.open(base_path..e,"rb");
3017
if not e then
3018
t("Couldn't load resource: "..tostring(i));
3019
os.exit(1);
3020
end
3021
local t=e:read("*a");
3022
local e=0;
3023
t:gsub("(=+)",function(t)e=math.max(e,#t);end);
3024
a:write(("resources[%q] = %q"):format(o,t));
3025
end
3026
if e.virtual_io then
3027
local e=require_resource("vio");
3028
if not e then
3029
t("Virtual IO requested but is not enabled in this build of squish");
3030
else
3031
a:write(e,"\n")
3032
a:write[[local io_open, io_lines = io.open, io.lines; function io.open(fn, mode)
3033
					if not resources[fn] then
3034
						return io_open(fn, mode);
3035
					else
3036
						return vio.open(resources[fn]);
3037
				end end
3038
				function io.lines(fn)
3039
					if not resources[fn] then
3040
						return io_lines(fn);
3041
					else
3042
						return vio.open(resources[fn]):lines()
3043
				end end
3044
				local _dofile = dofile;
3045
				function dofile(fn)
3046
					if not resources[fn] then
3047
						return _dofile(fn);
3048
					else
3049
						return assert(loadstring(resources[fn]))();
3050
				end end
3051
				local _loadfile = loadfile;
3052
				function loadfile(fn)
3053
					if not resources[fn] then
3054
						return _loadfile(fn);
3055
					else
3056
						return loadstring(resources[fn], "@"..fn);
3057
				end end ]]
3058
end
3059
end
3060
a:write[[function require_resource(name) return resources[name] or error("resource '"..tostring(name).."' not found"); end end ]]
3061
end
3062
h("Finalising...")
3063
for e,o in pairs(d)do
3064
local e,i=io.open(base_path..o);
3065
if not e then
3066
t("Failed to open "..o..": "..i);
3067
os.exit(1);
3068
else
3069
a:write((e:read("*a"):gsub("^#.-\n","")));
3070
e:close();
3071
end
3072
end
3073
a:close();
3074
o("OK!");
3075
local h=require"optlex"
3076
local r=require"optparser"
3077
local a=require"llex"
3078
local d=require"lparser"
3079
local i={
3080
none={};
3081
debug={"whitespace","locals","entropy","comments","numbers"};
3082
default={"comments","whitespace","emptylines","numbers","locals"};
3083
basic={"comments","whitespace","emptylines"};
3084
full={"comments","whitespace","emptylines","eols","strings","numbers","locals","entropy"};
3085
}
3086
if e.minify_level and not i[e.minify_level]then
3087
t("Unknown minify level: "..e.minify_level);
3088
t("Available minify levels: none, basic, default, full, debug");
3089
end
3090
for a,t in ipairs(i[e.minify_level or"default"]or{})do
3091
if e["minify_"..t]==nil then
3092
e["minify_"..t]=true;
3093
end
3094
end
3095
local n={
3096
["opt-locals"]=e.minify_locals;
3097
["opt-comments"]=e.minify_comments;
3098
["opt-entropy"]=e.minify_entropy;
3099
["opt-whitespace"]=e.minify_whitespace;
3100
["opt-emptylines"]=e.minify_emptylines;
3101
["opt-eols"]=e.minify_eols;
3102
["opt-strings"]=e.minify_strings;
3103
["opt-numbers"]=e.minify_numbers;
3104
}
3105
local function i(e)
3106
t("minify: "..e);os.exit(1);
3107
end
3108
local function l(e)
3109
local t=io.open(e,"rb")
3110
if not t then i("cannot open \""..e.."\" for reading")end
3111
local a=t:read("*a")
3112
if not a then i("cannot read from \""..e.."\"")end
3113
t:close()
3114
return a
3115
end
3116
local function u(e,a)
3117
local t=io.open(e,"wb")
3118
if not t then i("cannot open \""..e.."\" for writing")end
3119
local a=t:write(a)
3120
if not a then i("cannot write to \""..e.."\"")end
3121
t:close()
3122
end
3123
function minify_string(e)
3124
a.init(e)
3125
a.llex()
3126
local t,e,a
3127
=a.tok,a.seminfo,a.tokln
3128
if n["opt-locals"]then
3129
r.print=print
3130
d.init(t,e,a)
3131
local o,a=d.parser()
3132
r.optimize(n,t,e,o,a)
3133
end
3134
h.print=print
3135
t,e,a
3136
=h.optimize(n,t,e,a)
3137
local e=table.concat(e)
3138
if string.find(e,"\r\n",1,1)or
3139
string.find(e,"\n\r",1,1)then
3140
h.warn.mixedeol=true
3141
end
3142
return e;
3143
end
3144
function minify_file(e,t)
3145
local e=l(e);
3146
e=minify_string(e);
3147
u(t,e);
3148
end
3149
if e.minify~=false then
3150
o("Minifying "..out_fn.."...");
3151
minify_file(out_fn,out_fn);
3152
o("OK!");
3153
end
3154
local h=require"llex"
3155
local i=128;
3156
local n={"and","break","do","else","elseif",
3157
"end","false","for","function","if",
3158
"in","local","nil","not","or","repeat",
3159
"return","then","true","until","while"}
3160
function uglify_file(l,o)
3161
local r,a=io.open(l);
3162
if not r then
3163
t("Can't open input file for reading: "..tostring(a));
3164
return;
3165
end
3166
local a,s=io.open(o..".uglified","w+b");
3167
if not a then
3168
t("Can't open output file for writing: "..tostring(s));
3169
return;
3170
end
3171
local s=r:read("*a");
3172
r:close();
3173
local r,t=s:match("^(#.-\n)(.+)$");
3174
local t=t or s;
3175
if r then
3176
a:write(r)
3177
end
3178
while i+#n<=255 and t:find("["..string.char(i).."-"..string.char(i+#n-1).."]")do
3179
i=i+1;
3180
end
3181
if i+#n>255 then
3182
a:write(t);
3183
a:close();
3184
os.rename(o..".uglified",o);
3185
return;
3186
end
3187
local d={}
3188
for t,e in ipairs(n)do
3189
d[e]=string.char(i+t);
3190
end
3191
local r=0;
3192
s:gsub("(=+)",function(e)r=math.max(r,#e);end);
3193
h.init(t,"@"..l);
3194
h.llex()
3195
local s=h.seminfo;
3196
if e.uglify_level=="full"and i+#n<255 then
3197
local e={};
3198
for o,a in ipairs(h.tok)do
3199
if a=="TK_NAME"or a=="TK_STRING"then
3200
local t=string.format("%q,%q",a,s[o]);
3201
if not e[t]then
3202
e[t]={type=a,value=s[o],count=0};
3203
e[#e+1]=e[t];
3204
end
3205
e[t].count=e[t].count+1;
3206
end
3207
end
3208
for t=1,#e do
3209
local e=e[t];
3210
e.score=(e.count)*(#e.value-1)-#string.format("%q",e.value)-1;
3211
end
3212
table.sort(e,function(e,t)return e.score>t.score;end);
3213
local t=255-(i+#n);
3214
for t=t+1,#e do
3215
e[t]=nil;
3216
end
3217
local t=#n;
3218
for a,e in ipairs(e)do
3219
if e.score>0 then
3220
table.insert(n,e.value);
3221
d[e.value]=string.char(i+t+a);
3222
end
3223
end
3224
end
3225
a:write("local base_char,keywords=",tostring(i),",{");
3226
for t,e in ipairs(n)do
3227
a:write(string.format("%q",e),',');
3228
end
3229
a:write[[}; function prettify(code) return code:gsub("["..string.char(base_char).."-"..string.char(base_char+#keywords).."]", 
3230
	function (c) return keywords[c:byte()-base_char]; end) end ]]
3231
a:write[[return setfenv(assert(loadstring(prettify]]
3232
a:write("[",string.rep("=",r+1),"[");
3233
for e,t in ipairs(h.tok)do
3234
if t=="TK_KEYWORD"or t=="TK_NAME"or t=="TK_STRING"then
3235
local t=d[s[e]];
3236
if t then
3237
a:write(t);
3238
else
3239
a:write(s[e]);
3240
end
3241
else
3242
a:write(s[e]);
3243
end
3244
end
3245
a:write("]",string.rep("=",r+1),"]");
3246
a:write(", '@",o,"')), getfenv())()");
3247
a:close();
3248
os.rename(o..".uglified",o);
3249
end
3250
if e.uglify then
3251
o("Uglifying "..out_fn.."...");
3252
uglify_file(out_fn,out_fn);
3253
o("OK!");
3254
end
3255
local i=require"minichunkspy"
3256
function compile_string(t,a)
3257
local o=string.dump(loadstring(t,a));
3258
if((not e.debug)or e.compile_strip)and e.compile_strip~=false then
3259
local t=i.disassemble(o);
3260
local function a(e)
3261
e.source_lines,e.locals,e.upvalues={},{},{};
3262
for t,e in ipairs(e.prototypes)do
3263
a(e);
3264
end
3265
end
3266
s("Stripping debug info...");
3267
a(t.body);
3268
return i.assemble(t);
3269
end
3270
return o;
3271
end
3272
function compile_file(a,e)
3273
local o,a=io.open(a);
3274
if not o then
3275
t("Can't open input file for reading: "..tostring(a));
3276
return;
3277
end
3278
local a,i=io.open(e..".compiled","w+");
3279
if not a then
3280
t("Can't open output file for writing: "..tostring(i));
3281
return;
3282
end
3283
local i=o:read("*a");
3284
o:close();
3285
local t,o=i:match("^(#.-\n)(.+)$");
3286
local o=o or i;
3287
if t then
3288
a:write(t)
3289
end
3290
a:write(compile_string(o,e));
3291
os.rename(e..".compiled",e);
3292
end
3293
if e.compile then
3294
o("Compiling "..out_fn.."...");
3295
compile_file(out_fn,out_fn);
3296
o("OK!");
3297
end
3298
function gzip_file(e,a)
3299
local o,e=io.open(e);
3300
if not o then
3301
t("Can't open input file for reading: "..tostring(e));
3302
return;
3303
end
3304
local e,i=io.open(a..".gzipped","wb+");
3305
if not e then
3306
t("Can't open output file for writing: "..tostring(i));
3307
return;
3308
end
3309
local i=o:read("*a");
3310
o:close();
3311
local n,o=i:match("^(#.-\n)(.+)$");
3312
local o=o or i;
3313
if n then
3314
e:write(n)
3315
end
3316
local i,n=io.open(a..".pregzip","wb+");
3317
if not i then
3318
t("Can't open temp file for writing: "..tostring(n));
3319
return;
3320
end
3321
i:write(o);
3322
i:close();
3323
local t=io.popen("gzip -c '"..a..".pregzip'");
3324
o=t:read("*a");
3325
t:close();
3326
os.remove(a..".pregzip");
3327
local t=0;
3328
o:gsub("(=+)",function(e)t=math.max(t,#e);end);
3329
e:write("local ungz = (function ()",require_resource"gunzip.lua"," end)()\n");
3330
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) ]];
3331
e:write((string.format("%q",o):gsub("\026","\\026")));
3332
e:write(", '@",a,"'))()");
3333
e:close();
3334
os.rename(a..".gzipped",a);
3335
end
3336
if e.gzip then
3337
o("Gzipping "..out_fn.."...");
3338
gzip_file(out_fn,out_fn);
3339
o("OK!");
3340
end