| 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 |