performance improvements, probably
This commit is contained in:
parent
b4d3bd4c89
commit
8238a4e45d
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
dist
|
||||
update-key
|
||||
__pycache__
|
||||
__pycache__
|
||||
node_modules
|
9
build.sh
9
build.sh
@ -8,7 +8,14 @@ cp -r src/LICENSES dist
|
||||
cp -r src/stdlib.hvl dist
|
||||
cp -r src/bin/ dist
|
||||
cp src/potatobios.lua dist/
|
||||
luabundler bundle src/main.lua -p "src/lib/?.lua" | perl -pe 'chomp if eof' > dist/autorun.lua
|
||||
npx luabundler bundle src/main.lua -p "src/lib/?.lua" | perl -pe 'chomp if eof' > dist/autorun_full.lua
|
||||
WORK=$(pwd)
|
||||
cd ./minify
|
||||
lua5.1 CommandLineMinify.lua "$WORK/dist/autorun_full.lua" "$WORK/dist/autorun.lua"
|
||||
lua5.1 CommandLineMinify.lua "$WORK/dist/potatobios.lua" "$WORK/dist/pb_tmp.lua"
|
||||
mv "$WORK/dist/pb_tmp.lua" "$WORK/dist/potatobios.lua"
|
||||
cd "$WORK"
|
||||
rm dist/autorun_full.lua
|
||||
sed -i '19iif _G.package and _G.package.loaded[package] then loadedModule = _G.package.loaded[package] end if _G.package and _G.package.preload[package] then local pkg = _G.package.preload[package](_G.package) _G.package.loaded[package] = pkg loadedModule = pkg end' dist/autorun.lua
|
||||
echo -n "(...)" >> dist/autorun.lua
|
||||
./generate_manifest.py "$@"
|
4
manifest
4
manifest
@ -1,2 +1,2 @@
|
||||
{"build":190,"description":"factor program","files":{"LICENSES":"f3549d84d66eb53dd4a421a4341d77d3d217c1b117d67e3be8f5211adcda0952","autorun.lua":"03a6ea1216a3611db53158bc59c3ce018c9d2539f9e4241b9221011017b9ce89","bin/5rot26.lua":"91b66cd6d4b33081b25c456142dd7efcb894e819e842693c9e1e17ff48872ff5","bin/ccemux.lua":"239476f58835b86bbcac31ce8af3c3acd3d198a55ab9ada78c62fbf358625a98","bin/chronometer.lua":"db5363993a04382145aef7db2fbe262f0bf10697a589e1e2d2f9ce0f87430dd8","bin/factor.lua":"72a0756f377b1f8a8dc72dc4d565c62e428c3ca6ea86a6598a8347413b99d17a","bin/grep.lua":"1509bc267867b933e528ab74cfbc2a15fa2df0ec7389df4f9033194ab9037865","bin/kristminer.lua":"7e7f9fe2a6493d584ad6926cda915e02c1c3d800dc209680898ce930d0bb0e6f","bin/livegps.lua":"c3d17d495cda01aa1261e4c4fcd43439b29af422671972117ec34f68e32c5bba","bin/loading.lua":"c85f7aa1765170325155b921c1fceeb62643f552f12d41b529a22af3a67f5a97","bin/potatoflight.lua":"2fbb0b6f8d78728d8cb0ec64af1bc598bd00cb55f202378e7acdb86bba71efd1","bin/potatoplex.lua":"86c9e7597bbe23d7de7e7f1bfc976d0b94dcdf3af9e6c7c6c9b18b98596898c8","bin/relay.lua":"261ae6c220b83506e3326e8f2b091d246baae458ff0d2ee87512be2c4e35a75d","bin/tryhaskell.lua":"07810d85145da65a3e434154c79d5a9d72f2dcbe59c8d6829040fb925df878ec","potatobios.lua":"7593e0f9d0755eea05e3c0fff5c4c9e036745a8cbc20e9e19609d8743a77b87e","signing-key.tbl":"b32af5229c23af3bc03d538e42751b26044e404a7b1af064ed89894efe421607","startup":"f17bfb9b4322c4467dc9170d50827f2d75717e5c3125d734f21f3406657917bc","stdlib.hvl":"a6fd2620068f47794a9bbeed77bee3fd4962f848e6dd7c75137b30cd5665272e","update-key.hex":"8d8afb7a45833bb7d68f929421ad60a211d4d73e0ee03b24dc0106ba1de2e1a0","xlib/00_cbor.lua":"464b075e4f094b8db42506bd4bdaad0db87699ea7fbf80e5b87739b4aa9279af","xlib/01_skynet.lua":"9cb565d639a0acd7c763c3e7422482532cd0bda0cdfcc720089ab4a87e551339","xlib/03_heavlisp.lua":"82cdabd5286058c0ea4f27956f8c1144e198769c8b8ce9e91b26c930d711f710"},"sizes":{"LICENSES":4725,"autorun.lua":182536,"bin/5rot26.lua":914,"bin/ccemux.lua":1673,"bin/chronometer.lua":1152,"bin/factor.lua":4273,"bin/grep.lua":1196,"bin/kristminer.lua":5566,"bin/livegps.lua":980,"bin/loading.lua":7707,"bin/potatoflight.lua":3417,"bin/potatoplex.lua":6526,"bin/relay.lua":3075,"bin/tryhaskell.lua":1867,"potatobios.lua":71272,"signing-key.tbl":190,"startup":8313,"stdlib.hvl":851,"update-key.hex":44,"xlib/00_cbor.lua":15808,"xlib/01_skynet.lua":3286,"xlib/03_heavlisp.lua":15643},"timestamp":1612529895}
|
||||
{"hash":"5fa6cfe69f3547f5b3360713f0126c44c69269aad2d76c553e58b7f721021897","sig":"f50a861154fc851603fe13c431b8f7664c3df547313454187d0e2607b0c3af98651312ef1dfaf4ba6a22"}
|
||||
{"build":231,"description":"craftos-pc workaround for broken HTTP","files":{"LICENSES":"f3549d84d66eb53dd4a421a4341d77d3d217c1b117d67e3be8f5211adcda0952","autorun.lua":"7855e924c92280ad92db72cf02f711653db5a43159763e44e461af1b32e03090","bin/5rot26.lua":"417891a232e325476f980d31d88edc486d526611a6350ce47fd29cca464ebf2c","bin/ccemux.lua":"239476f58835b86bbcac31ce8af3c3acd3d198a55ab9ada78c62fbf358625a98","bin/chronometer.lua":"db5363993a04382145aef7db2fbe262f0bf10697a589e1e2d2f9ce0f87430dd8","bin/factor.lua":"3b7578dd4fca7586dc19d651d4838fba8fffe504b11d037f8d02acf062df5178","bin/grep.lua":"1509bc267867b933e528ab74cfbc2a15fa2df0ec7389df4f9033194ab9037865","bin/kristminer.lua":"7e7f9fe2a6493d584ad6926cda915e02c1c3d800dc209680898ce930d0bb0e6f","bin/livegps.lua":"c3d17d495cda01aa1261e4c4fcd43439b29af422671972117ec34f68e32c5bba","bin/loading.lua":"c85f7aa1765170325155b921c1fceeb62643f552f12d41b529a22af3a67f5a97","bin/potatoflight.lua":"2fbb0b6f8d78728d8cb0ec64af1bc598bd00cb55f202378e7acdb86bba71efd1","bin/potatoplex.lua":"86c9e7597bbe23d7de7e7f1bfc976d0b94dcdf3af9e6c7c6c9b18b98596898c8","bin/relay.lua":"261ae6c220b83506e3326e8f2b091d246baae458ff0d2ee87512be2c4e35a75d","bin/tryhaskell.lua":"07810d85145da65a3e434154c79d5a9d72f2dcbe59c8d6829040fb925df878ec","potatobios.lua":"2f904f672d2c370244e9d4d17443bf38848701d3cd69a4acedfff9fc00b19981","signing-key.tbl":"b32af5229c23af3bc03d538e42751b26044e404a7b1af064ed89894efe421607","startup":"2140cb64ba53e7405c411e9e889a2ce6ba1b6f531d89b58865364cc77dd473f9","stdlib.hvl":"a6fd2620068f47794a9bbeed77bee3fd4962f848e6dd7c75137b30cd5665272e","update-key.hex":"8d8afb7a45833bb7d68f929421ad60a211d4d73e0ee03b24dc0106ba1de2e1a0","xlib/00_cbor.lua":"464b075e4f094b8db42506bd4bdaad0db87699ea7fbf80e5b87739b4aa9279af","xlib/01_skynet.lua":"9cb565d639a0acd7c763c3e7422482532cd0bda0cdfcc720089ab4a87e551339","xlib/03_heavlisp.lua":"82cdabd5286058c0ea4f27956f8c1144e198769c8b8ce9e91b26c930d711f710"},"sizes":{"LICENSES":4725,"autorun.lua":101488,"bin/5rot26.lua":1661,"bin/ccemux.lua":1673,"bin/chronometer.lua":1152,"bin/factor.lua":4269,"bin/grep.lua":1196,"bin/kristminer.lua":5566,"bin/livegps.lua":980,"bin/loading.lua":7707,"bin/potatoflight.lua":3417,"bin/potatoplex.lua":6526,"bin/relay.lua":3075,"bin/tryhaskell.lua":1867,"potatobios.lua":40411,"signing-key.tbl":190,"startup":8378,"stdlib.hvl":851,"update-key.hex":44,"xlib/00_cbor.lua":15808,"xlib/01_skynet.lua":3286,"xlib/03_heavlisp.lua":15643},"timestamp":1617216858}
|
||||
{"hash":"9a33a8b4a5557449e41520b9bc716ea4fff8ed713820aeb5041edf297b70a321","sig":"c6952057de361d534f8e0d96cc30fed7668c32a3313abf56261a3519f7d27bba70c69176887b988d1b32"}
|
121
minify/CommandLineBeautify.lua
Normal file
121
minify/CommandLineBeautify.lua
Normal file
@ -0,0 +1,121 @@
|
||||
--
|
||||
-- beautify
|
||||
--
|
||||
-- A command line utility for beautifying lua source code using the beautifier.
|
||||
--
|
||||
|
||||
local util = require'Util'
|
||||
local Parser = require'ParseLua'
|
||||
local Format_Beautify = require'FormatBeautiful'
|
||||
local ParseLua = Parser.ParseLua
|
||||
local PrintTable = util.PrintTable
|
||||
|
||||
local function splitFilename(name)
|
||||
--table.foreach(arg, print)
|
||||
if name:find(".") then
|
||||
local p, ext = name:match("()%.([^%.]*)$")
|
||||
if p and ext then
|
||||
if #ext == 0 then
|
||||
return name, nil
|
||||
else
|
||||
local filename = name:sub(1,p-1)
|
||||
return filename, ext
|
||||
end
|
||||
else
|
||||
return name, nil
|
||||
end
|
||||
else
|
||||
return name, nil
|
||||
end
|
||||
end
|
||||
|
||||
if #arg == 1 then
|
||||
local name, ext = splitFilename(arg[1])
|
||||
local outname = name.."_formatted"
|
||||
if ext then outname = outname.."."..ext end
|
||||
--
|
||||
local inf = io.open(arg[1], 'r')
|
||||
if not inf then
|
||||
print("Failed to open '"..arg[1].."' for reading")
|
||||
return
|
||||
end
|
||||
--
|
||||
local sourceText = inf:read('*all')
|
||||
inf:close()
|
||||
--
|
||||
local st, ast = ParseLua(sourceText)
|
||||
if not st then
|
||||
--we failed to parse the file, show why
|
||||
print(ast)
|
||||
return
|
||||
end
|
||||
--
|
||||
local outf = io.open(outname, 'w')
|
||||
if not outf then
|
||||
print("Failed to open '"..outname.."' for writing")
|
||||
return
|
||||
end
|
||||
--
|
||||
outf:write(Format_Beautify(ast))
|
||||
outf:close()
|
||||
--
|
||||
print("Beautification complete")
|
||||
|
||||
elseif #arg == 2 then
|
||||
--keep the user from accidentally overwriting their non-minified file with
|
||||
if arg[1]:find("_formatted") then
|
||||
print("Did you mix up the argument order?\n"..
|
||||
"Current command will beautify '"..arg[1].."' and overwrite '"..arg[2].."' with the results")
|
||||
while true do
|
||||
io.write("Confirm (yes/no): ")
|
||||
local msg = io.read('*line')
|
||||
if msg == 'yes' then
|
||||
break
|
||||
elseif msg == 'no' then
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
local inf = io.open(arg[1], 'r')
|
||||
if not inf then
|
||||
print("Failed to open '"..arg[1].."' for reading")
|
||||
return
|
||||
end
|
||||
--
|
||||
local sourceText = inf:read('*all')
|
||||
inf:close()
|
||||
--
|
||||
local st, ast = ParseLua(sourceText)
|
||||
if not st then
|
||||
--we failed to parse the file, show why
|
||||
print(ast)
|
||||
return
|
||||
end
|
||||
--
|
||||
if arg[1] == arg[2] then
|
||||
print("Are you SURE you want to overwrite the source file with a beautified version?\n"..
|
||||
"You will be UNABLE to get the original source back!")
|
||||
while true do
|
||||
io.write("Confirm (yes/no): ")
|
||||
local msg = io.read('*line')
|
||||
if msg == 'yes' then
|
||||
break
|
||||
elseif msg == 'no' then
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
local outf = io.open(arg[2], 'w')
|
||||
if not outf then
|
||||
print("Failed to open '"..arg[2].."' for writing")
|
||||
return
|
||||
end
|
||||
--
|
||||
outf:write(Format_Beautify(ast))
|
||||
outf:close()
|
||||
--
|
||||
print("Beautification complete")
|
||||
|
||||
else
|
||||
print("Invalid arguments!\nUsage: lua CommandLineLuaBeautify.lua source_file [destination_file]")
|
||||
end
|
47
minify/CommandLineLiveBeautify.lua
Normal file
47
minify/CommandLineLiveBeautify.lua
Normal file
@ -0,0 +1,47 @@
|
||||
|
||||
--
|
||||
-- beautify.interactive
|
||||
--
|
||||
-- For testing: Lets you enter lines of text to be beautified to verify the
|
||||
-- correctness of their implementation.
|
||||
--
|
||||
|
||||
local util = require'Util'
|
||||
local Parser = require'ParseLua'
|
||||
local Format_Beautify = require'FormatBeautiful'
|
||||
local ParseLua = Parser.ParseLua
|
||||
local PrintTable = util.PrintTable
|
||||
|
||||
while true do
|
||||
io.write('> ')
|
||||
local line = io.read('*line')
|
||||
local fileFrom, fileTo = line:match("^file (.*) (.*)")
|
||||
if fileFrom and fileTo then
|
||||
local file = io.open(fileFrom, 'r')
|
||||
local fileTo = io.open(fileTo, 'w')
|
||||
if file and fileTo then
|
||||
local st, ast = ParseLua(file:read('*all'))
|
||||
if st then
|
||||
fileTo:write(Format_Beautify(ast)..'\n')
|
||||
io.write("Beautification Complete\n")
|
||||
else
|
||||
io.write(""..tostring(ast).."\n")
|
||||
end
|
||||
file:close()
|
||||
fileTo:close()
|
||||
else
|
||||
io.write("File does not exist\n")
|
||||
end
|
||||
else
|
||||
local st, ast = ParseLua(line)
|
||||
if st then
|
||||
io.write("====== AST =======\n")
|
||||
io.write(PrintTable(ast)..'\n')
|
||||
io.write("==== BEAUTIFIED ====\n")
|
||||
io.write(Format_Beautify(ast))
|
||||
io.write("==================\n")
|
||||
else
|
||||
io.write(""..tostring(ast).."\n")
|
||||
end
|
||||
end
|
||||
end
|
47
minify/CommandLineLiveMinify.lua
Normal file
47
minify/CommandLineLiveMinify.lua
Normal file
@ -0,0 +1,47 @@
|
||||
|
||||
--
|
||||
-- CommandLineLiveMinify.lua
|
||||
--
|
||||
-- For testing: Lets you enter lines of text to be minified to verify the
|
||||
-- correctness of their implementation.
|
||||
--
|
||||
|
||||
local util = require'Util'
|
||||
local Parser = require'ParseLua'
|
||||
local Format_Mini = require'FormatMini'
|
||||
local ParseLua = Parser.ParseLua
|
||||
local PrintTable = util.PrintTable
|
||||
|
||||
while true do
|
||||
io.write('> ')
|
||||
local line = io.read('*line')
|
||||
local fileFrom, fileTo = line:match("^file (.*) (.*)")
|
||||
if fileFrom and fileTo then
|
||||
local file = io.open(fileFrom, 'r')
|
||||
local fileTo = io.open(fileTo, 'w')
|
||||
if file and fileTo then
|
||||
local st, ast = ParseLua(file:read('*all'))
|
||||
if st then
|
||||
fileTo:write(Format_Mini(ast)..'\n')
|
||||
io.write("Minification Complete\n")
|
||||
else
|
||||
io.write(""..tostring(ast).."\n")
|
||||
end
|
||||
file:close()
|
||||
fileTo:close()
|
||||
else
|
||||
io.write("File does not exist\n")
|
||||
end
|
||||
else
|
||||
local st, ast = ParseLua(line)
|
||||
if st then
|
||||
io.write("====== AST =======\n")
|
||||
io.write(PrintTable(ast)..'\n')
|
||||
io.write("==== MINIFIED ====\n")
|
||||
io.write(Format_Mini(ast)..'\n')
|
||||
io.write("==================\n")
|
||||
else
|
||||
io.write(""..tostring(ast).."\n")
|
||||
end
|
||||
end
|
||||
end
|
122
minify/CommandLineMinify.lua
Normal file
122
minify/CommandLineMinify.lua
Normal file
@ -0,0 +1,122 @@
|
||||
|
||||
--
|
||||
-- CommandlineMinify.lua
|
||||
--
|
||||
-- A command line utility for minifying lua source code using the minifier.
|
||||
--
|
||||
|
||||
local util = require'Util'
|
||||
local Parser = require'ParseLua'
|
||||
local Format_Mini = require'FormatMini'
|
||||
local ParseLua = Parser.ParseLua
|
||||
local PrintTable = util.PrintTable
|
||||
|
||||
local function splitFilename(name)
|
||||
table.foreach(arg, print)
|
||||
if name:find(".") then
|
||||
local p, ext = name:match("()%.([^%.]*)$")
|
||||
if p and ext then
|
||||
if #ext == 0 then
|
||||
return name, nil
|
||||
else
|
||||
local filename = name:sub(1,p-1)
|
||||
return filename, ext
|
||||
end
|
||||
else
|
||||
return name, nil
|
||||
end
|
||||
else
|
||||
return name, nil
|
||||
end
|
||||
end
|
||||
|
||||
if #arg == 1 then
|
||||
local name, ext = splitFilename(arg[1])
|
||||
local outname = name.."_min"
|
||||
if ext then outname = outname.."."..ext end
|
||||
--
|
||||
local inf = io.open(arg[1], 'r')
|
||||
if not inf then
|
||||
print("Failed to open `"..arg[1].."` for reading")
|
||||
return
|
||||
end
|
||||
--
|
||||
local sourceText = inf:read('*all')
|
||||
inf:close()
|
||||
--
|
||||
local st, ast = ParseLua(sourceText)
|
||||
if not st then
|
||||
--we failed to parse the file, show why
|
||||
print(ast)
|
||||
return
|
||||
end
|
||||
--
|
||||
local outf = io.open(outname, 'w')
|
||||
if not outf then
|
||||
print("Failed to open `"..outname.."` for writing")
|
||||
return
|
||||
end
|
||||
--
|
||||
outf:write(Format_Mini(ast))
|
||||
outf:close()
|
||||
--
|
||||
print("Minification complete")
|
||||
|
||||
elseif #arg == 2 then
|
||||
--keep the user from accidentally overwriting their non-minified file with
|
||||
if arg[1]:find("_min") then
|
||||
print("Did you mix up the argument order?\n"..
|
||||
"Current command will minify `"..arg[1].."` and OVERWRITE `"..arg[2].."` with the results")
|
||||
while true do
|
||||
io.write("Confirm (yes/cancel): ")
|
||||
local msg = io.read('*line')
|
||||
if msg == 'yes' then
|
||||
break
|
||||
elseif msg == 'cancel' then
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
local inf = io.open(arg[1], 'r')
|
||||
if not inf then
|
||||
print("Failed to open `"..arg[1].."` for reading")
|
||||
return
|
||||
end
|
||||
--
|
||||
local sourceText = inf:read('*all')
|
||||
inf:close()
|
||||
--
|
||||
local st, ast = ParseLua(sourceText)
|
||||
if not st then
|
||||
--we failed to parse the file, show why
|
||||
print(ast)
|
||||
return
|
||||
end
|
||||
--
|
||||
if arg[1] == arg[2] then
|
||||
print("Are you SURE you want to overwrite the source file with a minified version?\n"..
|
||||
"You will be UNABLE to get the original source back!")
|
||||
while true do
|
||||
io.write("Confirm (yes/cancel): ")
|
||||
local msg = io.read('*line')
|
||||
if msg == 'yes' then
|
||||
break
|
||||
elseif msg == 'cancel' then
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
local outf = io.open(arg[2], 'w')
|
||||
if not outf then
|
||||
print("Failed to open `"..arg[2].."` for writing")
|
||||
return
|
||||
end
|
||||
--
|
||||
outf:write(Format_Mini(ast))
|
||||
outf:close()
|
||||
--
|
||||
print("Minification complete")
|
||||
|
||||
else
|
||||
print("Invalid arguments, Usage:\nLuaMinify source [destination]")
|
||||
end
|
347
minify/FormatBeautiful.lua
Normal file
347
minify/FormatBeautiful.lua
Normal file
@ -0,0 +1,347 @@
|
||||
--
|
||||
-- Beautifier
|
||||
--
|
||||
-- Returns a beautified version of the code, including comments
|
||||
--
|
||||
|
||||
local parser = require"ParseLua"
|
||||
local ParseLua = parser.ParseLua
|
||||
local util = require'Util'
|
||||
local lookupify = util.lookupify
|
||||
|
||||
local LowerChars = lookupify{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
|
||||
'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
|
||||
's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}
|
||||
local UpperChars = lookupify{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
|
||||
'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
|
||||
'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'}
|
||||
local Digits = lookupify{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}
|
||||
|
||||
local function Format_Beautify(ast)
|
||||
local formatStatlist, formatExpr
|
||||
local indent = 0
|
||||
local EOL = "\n"
|
||||
|
||||
local function getIndentation()
|
||||
return string.rep(" ", indent)
|
||||
end
|
||||
|
||||
local function joinStatementsSafe(a, b, sep)
|
||||
sep = sep or ''
|
||||
local aa, bb = a:sub(-1,-1), b:sub(1,1)
|
||||
if UpperChars[aa] or LowerChars[aa] or aa == '_' then
|
||||
if not (UpperChars[bb] or LowerChars[bb] or bb == '_' or Digits[bb]) then
|
||||
--bb is a symbol, can join without sep
|
||||
return a .. b
|
||||
elseif bb == '(' then
|
||||
--prevent ambiguous syntax
|
||||
return a..sep..b
|
||||
else
|
||||
return a..sep..b
|
||||
end
|
||||
elseif Digits[aa] then
|
||||
if bb == '(' then
|
||||
--can join statements directly
|
||||
return a..b
|
||||
else
|
||||
return a..sep..b
|
||||
end
|
||||
elseif aa == '' then
|
||||
return a..b
|
||||
else
|
||||
if bb == '(' then
|
||||
--don't want to accidentally call last statement, can't join directly
|
||||
return a..sep..b
|
||||
else
|
||||
return a..b
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
formatExpr = function(expr)
|
||||
local out = string.rep('(', expr.ParenCount or 0)
|
||||
if expr.AstType == 'VarExpr' then
|
||||
if expr.Variable then
|
||||
out = out .. expr.Variable.Name
|
||||
else
|
||||
out = out .. expr.Name
|
||||
end
|
||||
|
||||
elseif expr.AstType == 'NumberExpr' then
|
||||
out = out..expr.Value.Data
|
||||
|
||||
elseif expr.AstType == 'StringExpr' then
|
||||
out = out..expr.Value.Data
|
||||
|
||||
elseif expr.AstType == 'BooleanExpr' then
|
||||
out = out..tostring(expr.Value)
|
||||
|
||||
elseif expr.AstType == 'NilExpr' then
|
||||
out = joinStatementsSafe(out, "nil")
|
||||
|
||||
elseif expr.AstType == 'BinopExpr' then
|
||||
out = joinStatementsSafe(out, formatExpr(expr.Lhs)) .. " "
|
||||
out = joinStatementsSafe(out, expr.Op) .. " "
|
||||
out = joinStatementsSafe(out, formatExpr(expr.Rhs))
|
||||
|
||||
elseif expr.AstType == 'UnopExpr' then
|
||||
out = joinStatementsSafe(out, expr.Op) .. (#expr.Op ~= 1 and " " or "")
|
||||
out = joinStatementsSafe(out, formatExpr(expr.Rhs))
|
||||
|
||||
elseif expr.AstType == 'DotsExpr' then
|
||||
out = out.."..."
|
||||
|
||||
elseif expr.AstType == 'CallExpr' then
|
||||
out = out..formatExpr(expr.Base)
|
||||
out = out.."("
|
||||
for i = 1, #expr.Arguments do
|
||||
out = out..formatExpr(expr.Arguments[i])
|
||||
if i ~= #expr.Arguments then
|
||||
out = out..", "
|
||||
end
|
||||
end
|
||||
out = out..")"
|
||||
|
||||
elseif expr.AstType == 'TableCallExpr' then
|
||||
out = out..formatExpr(expr.Base) .. " "
|
||||
out = out..formatExpr(expr.Arguments[1])
|
||||
|
||||
elseif expr.AstType == 'StringCallExpr' then
|
||||
out = out..formatExpr(expr.Base) .. " "
|
||||
out = out..expr.Arguments[1].Data
|
||||
|
||||
elseif expr.AstType == 'IndexExpr' then
|
||||
out = out..formatExpr(expr.Base).."["..formatExpr(expr.Index).."]"
|
||||
|
||||
elseif expr.AstType == 'MemberExpr' then
|
||||
out = out..formatExpr(expr.Base)..expr.Indexer..expr.Ident.Data
|
||||
|
||||
elseif expr.AstType == 'Function' then
|
||||
-- anonymous function
|
||||
out = out.."function("
|
||||
if #expr.Arguments > 0 then
|
||||
for i = 1, #expr.Arguments do
|
||||
out = out..expr.Arguments[i].Name
|
||||
if i ~= #expr.Arguments then
|
||||
out = out..", "
|
||||
elseif expr.VarArg then
|
||||
out = out..", ..."
|
||||
end
|
||||
end
|
||||
elseif expr.VarArg then
|
||||
out = out.."..."
|
||||
end
|
||||
out = out..")" .. EOL
|
||||
indent = indent + 1
|
||||
out = joinStatementsSafe(out, formatStatlist(expr.Body))
|
||||
indent = indent - 1
|
||||
out = joinStatementsSafe(out, getIndentation() .. "end")
|
||||
elseif expr.AstType == 'ConstructorExpr' then
|
||||
out = out.."{ "
|
||||
for i = 1, #expr.EntryList do
|
||||
local entry = expr.EntryList[i]
|
||||
if entry.Type == 'Key' then
|
||||
out = out.."["..formatExpr(entry.Key).."] = "..formatExpr(entry.Value)
|
||||
elseif entry.Type == 'Value' then
|
||||
out = out..formatExpr(entry.Value)
|
||||
elseif entry.Type == 'KeyString' then
|
||||
out = out..entry.Key.." = "..formatExpr(entry.Value)
|
||||
end
|
||||
if i ~= #expr.EntryList then
|
||||
out = out..", "
|
||||
end
|
||||
end
|
||||
out = out.." }"
|
||||
|
||||
elseif expr.AstType == 'Parentheses' then
|
||||
out = out.."("..formatExpr(expr.Inner)..")"
|
||||
|
||||
end
|
||||
out = out..string.rep(')', expr.ParenCount or 0)
|
||||
return out
|
||||
end
|
||||
|
||||
local formatStatement = function(statement)
|
||||
local out = ""
|
||||
if statement.AstType == 'AssignmentStatement' then
|
||||
out = getIndentation()
|
||||
for i = 1, #statement.Lhs do
|
||||
out = out..formatExpr(statement.Lhs[i])
|
||||
if i ~= #statement.Lhs then
|
||||
out = out..", "
|
||||
end
|
||||
end
|
||||
if #statement.Rhs > 0 then
|
||||
out = out.." = "
|
||||
for i = 1, #statement.Rhs do
|
||||
out = out..formatExpr(statement.Rhs[i])
|
||||
if i ~= #statement.Rhs then
|
||||
out = out..", "
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif statement.AstType == 'CallStatement' then
|
||||
out = getIndentation() .. formatExpr(statement.Expression)
|
||||
elseif statement.AstType == 'LocalStatement' then
|
||||
out = getIndentation() .. out.."local "
|
||||
for i = 1, #statement.LocalList do
|
||||
out = out..statement.LocalList[i].Name
|
||||
if i ~= #statement.LocalList then
|
||||
out = out..", "
|
||||
end
|
||||
end
|
||||
if #statement.InitList > 0 then
|
||||
out = out.." = "
|
||||
for i = 1, #statement.InitList do
|
||||
out = out..formatExpr(statement.InitList[i])
|
||||
if i ~= #statement.InitList then
|
||||
out = out..", "
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif statement.AstType == 'IfStatement' then
|
||||
out = getIndentation() .. joinStatementsSafe("if ", formatExpr(statement.Clauses[1].Condition))
|
||||
out = joinStatementsSafe(out, " then") .. EOL
|
||||
indent = indent + 1
|
||||
out = joinStatementsSafe(out, formatStatlist(statement.Clauses[1].Body))
|
||||
indent = indent - 1
|
||||
for i = 2, #statement.Clauses do
|
||||
local st = statement.Clauses[i]
|
||||
if st.Condition then
|
||||
out = getIndentation() .. joinStatementsSafe(out, getIndentation() .. "elseif ")
|
||||
out = joinStatementsSafe(out, formatExpr(st.Condition))
|
||||
out = joinStatementsSafe(out, " then") .. EOL
|
||||
else
|
||||
out = joinStatementsSafe(out, getIndentation() .. "else") .. EOL
|
||||
end
|
||||
indent = indent + 1
|
||||
out = joinStatementsSafe(out, formatStatlist(st.Body))
|
||||
indent = indent - 1
|
||||
end
|
||||
out = joinStatementsSafe(out, getIndentation() .. "end") .. EOL
|
||||
elseif statement.AstType == 'WhileStatement' then
|
||||
out = getIndentation() .. joinStatementsSafe("while ", formatExpr(statement.Condition))
|
||||
out = joinStatementsSafe(out, " do") .. EOL
|
||||
indent = indent + 1
|
||||
out = joinStatementsSafe(out, formatStatlist(statement.Body))
|
||||
indent = indent - 1
|
||||
out = joinStatementsSafe(out, getIndentation() .. "end") .. EOL
|
||||
elseif statement.AstType == 'DoStatement' then
|
||||
out = getIndentation() .. joinStatementsSafe(out, "do") .. EOL
|
||||
indent = indent + 1
|
||||
out = joinStatementsSafe(out, formatStatlist(statement.Body))
|
||||
indent = indent - 1
|
||||
out = joinStatementsSafe(out, getIndentation() .. "end") .. EOL
|
||||
elseif statement.AstType == 'ReturnStatement' then
|
||||
out = getIndentation() .. "return "
|
||||
for i = 1, #statement.Arguments do
|
||||
out = joinStatementsSafe(out, formatExpr(statement.Arguments[i]))
|
||||
if i ~= #statement.Arguments then
|
||||
out = out..", "
|
||||
end
|
||||
end
|
||||
elseif statement.AstType == 'BreakStatement' then
|
||||
out = getIndentation() .. "break"
|
||||
elseif statement.AstType == 'RepeatStatement' then
|
||||
out = getIndentation() .. "repeat" .. EOL
|
||||
indent = indent + 1
|
||||
out = joinStatementsSafe(out, formatStatlist(statement.Body))
|
||||
indent = indent - 1
|
||||
out = joinStatementsSafe(out, getIndentation() .. "until ")
|
||||
out = joinStatementsSafe(out, formatExpr(statement.Condition)) .. EOL
|
||||
elseif statement.AstType == 'Function' then
|
||||
if statement.IsLocal then
|
||||
out = "local "
|
||||
end
|
||||
out = joinStatementsSafe(out, "function ")
|
||||
out = getIndentation() .. out
|
||||
if statement.IsLocal then
|
||||
out = out..statement.Name.Name
|
||||
else
|
||||
out = out..formatExpr(statement.Name)
|
||||
end
|
||||
out = out.."("
|
||||
if #statement.Arguments > 0 then
|
||||
for i = 1, #statement.Arguments do
|
||||
out = out..statement.Arguments[i].Name
|
||||
if i ~= #statement.Arguments then
|
||||
out = out..", "
|
||||
elseif statement.VarArg then
|
||||
out = out..",..."
|
||||
end
|
||||
end
|
||||
elseif statement.VarArg then
|
||||
out = out.."..."
|
||||
end
|
||||
out = out..")" .. EOL
|
||||
indent = indent + 1
|
||||
out = joinStatementsSafe(out, formatStatlist(statement.Body))
|
||||
indent = indent - 1
|
||||
out = joinStatementsSafe(out, getIndentation() .. "end") .. EOL
|
||||
elseif statement.AstType == 'GenericForStatement' then
|
||||
out = getIndentation() .. "for "
|
||||
for i = 1, #statement.VariableList do
|
||||
out = out..statement.VariableList[i].Name
|
||||
if i ~= #statement.VariableList then
|
||||
out = out..", "
|
||||
end
|
||||
end
|
||||
out = out.." in "
|
||||
for i = 1, #statement.Generators do
|
||||
out = joinStatementsSafe(out, formatExpr(statement.Generators[i]))
|
||||
if i ~= #statement.Generators then
|
||||
out = joinStatementsSafe(out, ', ')
|
||||
end
|
||||
end
|
||||
out = joinStatementsSafe(out, " do") .. EOL
|
||||
indent = indent + 1
|
||||
out = joinStatementsSafe(out, formatStatlist(statement.Body))
|
||||
indent = indent - 1
|
||||
out = joinStatementsSafe(out, getIndentation() .. "end") .. EOL
|
||||
elseif statement.AstType == 'NumericForStatement' then
|
||||
out = getIndentation() .. "for "
|
||||
out = out..statement.Variable.Name.." = "
|
||||
out = out..formatExpr(statement.Start)..", "..formatExpr(statement.End)
|
||||
if statement.Step then
|
||||
out = out..", "..formatExpr(statement.Step)
|
||||
end
|
||||
out = joinStatementsSafe(out, " do") .. EOL
|
||||
indent = indent + 1
|
||||
out = joinStatementsSafe(out, formatStatlist(statement.Body))
|
||||
indent = indent - 1
|
||||
out = joinStatementsSafe(out, getIndentation() .. "end") .. EOL
|
||||
elseif statement.AstType == 'LabelStatement' then
|
||||
out = getIndentation() .. "::" .. statement.Label .. "::" .. EOL
|
||||
elseif statement.AstType == 'GotoStatement' then
|
||||
out = getIndentation() .. "goto " .. statement.Label .. EOL
|
||||
elseif statement.AstType == 'Comment' then
|
||||
if statement.CommentType == 'Shebang' then
|
||||
out = getIndentation() .. statement.Data
|
||||
--out = out .. EOL
|
||||
elseif statement.CommentType == 'Comment' then
|
||||
out = getIndentation() .. statement.Data
|
||||
--out = out .. EOL
|
||||
elseif statement.CommentType == 'LongComment' then
|
||||
out = getIndentation() .. statement.Data
|
||||
--out = out .. EOL
|
||||
end
|
||||
elseif statement.AstType == 'Eof' then
|
||||
-- Ignore
|
||||
else
|
||||
print("Unknown AST Type: ", statement.AstType)
|
||||
end
|
||||
return out
|
||||
end
|
||||
|
||||
formatStatlist = function(statList)
|
||||
local out = ''
|
||||
for _, stat in pairs(statList.Body) do
|
||||
out = joinStatementsSafe(out, formatStatement(stat) .. EOL)
|
||||
end
|
||||
return out
|
||||
end
|
||||
|
||||
return formatStatlist(ast)
|
||||
end
|
||||
|
||||
return Format_Beautify
|
436
minify/FormatIdentity.lua
Normal file
436
minify/FormatIdentity.lua
Normal file
@ -0,0 +1,436 @@
|
||||
require'strict'
|
||||
require'ParseLua'
|
||||
local util = require'Util'
|
||||
|
||||
local function debug_printf(...)
|
||||
--[[
|
||||
util.printf(...)
|
||||
--]]
|
||||
end
|
||||
|
||||
--
|
||||
-- FormatIdentity.lua
|
||||
--
|
||||
-- Returns the exact source code that was used to create an AST, preserving all
|
||||
-- comments and whitespace.
|
||||
-- This can be used to get back a Lua source after renaming some variables in
|
||||
-- an AST.
|
||||
--
|
||||
|
||||
local function Format_Identity(ast)
|
||||
local out = {
|
||||
rope = {}, -- List of strings
|
||||
line = 1,
|
||||
char = 1,
|
||||
|
||||
appendStr = function(self, str)
|
||||
table.insert(self.rope, str)
|
||||
|
||||
local lines = util.splitLines(str)
|
||||
if #lines == 1 then
|
||||
self.char = self.char + #str
|
||||
else
|
||||
self.line = self.line + #lines - 1
|
||||
local lastLine = lines[#lines]
|
||||
self.char = #lastLine
|
||||
end
|
||||
end,
|
||||
|
||||
appendToken = function(self, token)
|
||||
self:appendWhite(token)
|
||||
--[*[
|
||||
--debug_printf("appendToken(%q)", token.Data)
|
||||
local data = token.Data
|
||||
local lines = util.splitLines(data)
|
||||
while self.line + #lines < token.Line do
|
||||
print("Inserting extra line")
|
||||
self.str = self.str .. '\n'
|
||||
self.line = self.line + 1
|
||||
self.char = 1
|
||||
end
|
||||
--]]
|
||||
self:appendStr(token.Data)
|
||||
end,
|
||||
|
||||
appendTokens = function(self, tokens)
|
||||
for _,token in ipairs(tokens) do
|
||||
self:appendToken( token )
|
||||
end
|
||||
end,
|
||||
|
||||
appendWhite = function(self, token)
|
||||
if token.LeadingWhite then
|
||||
self:appendTokens( token.LeadingWhite )
|
||||
--self.str = self.str .. ' '
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
local formatStatlist, formatExpr;
|
||||
|
||||
formatExpr = function(expr)
|
||||
local tok_it = 1
|
||||
local function appendNextToken(str)
|
||||
local tok = expr.Tokens[tok_it];
|
||||
if str and tok.Data ~= str then
|
||||
error("Expected token '" .. str .. "'. Tokens: " .. util.PrintTable(expr.Tokens))
|
||||
end
|
||||
out:appendToken( tok )
|
||||
tok_it = tok_it + 1
|
||||
end
|
||||
local function appendToken(token)
|
||||
out:appendToken( token )
|
||||
tok_it = tok_it + 1
|
||||
end
|
||||
local function appendWhite()
|
||||
local tok = expr.Tokens[tok_it];
|
||||
if not tok then error(util.PrintTable(expr)) end
|
||||
out:appendWhite( tok )
|
||||
tok_it = tok_it + 1
|
||||
end
|
||||
local function appendStr(str)
|
||||
appendWhite()
|
||||
out:appendStr(str)
|
||||
end
|
||||
local function peek()
|
||||
if tok_it < #expr.Tokens then
|
||||
return expr.Tokens[tok_it].Data
|
||||
end
|
||||
end
|
||||
local function appendComma(mandatory, seperators)
|
||||
if true then
|
||||
seperators = seperators or { "," }
|
||||
seperators = util.lookupify( seperators )
|
||||
if not mandatory and not seperators[peek()] then
|
||||
return
|
||||
end
|
||||
assert(seperators[peek()], "Missing comma or semicolon")
|
||||
appendNextToken()
|
||||
else
|
||||
local p = peek()
|
||||
if p == "," or p == ";" then
|
||||
appendNextToken()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
debug_printf("formatExpr(%s) at line %i", expr.AstType, expr.Tokens[1] and expr.Tokens[1].Line or -1)
|
||||
|
||||
if expr.AstType == 'VarExpr' then
|
||||
if expr.Variable then
|
||||
appendStr( expr.Variable.Name )
|
||||
else
|
||||
appendStr( expr.Name )
|
||||
end
|
||||
|
||||
elseif expr.AstType == 'NumberExpr' then
|
||||
appendToken( expr.Value )
|
||||
|
||||
elseif expr.AstType == 'StringExpr' then
|
||||
appendToken( expr.Value )
|
||||
|
||||
elseif expr.AstType == 'BooleanExpr' then
|
||||
appendNextToken( expr.Value and "true" or "false" )
|
||||
|
||||
elseif expr.AstType == 'NilExpr' then
|
||||
appendNextToken( "nil" )
|
||||
|
||||
elseif expr.AstType == 'BinopExpr' then
|
||||
formatExpr(expr.Lhs)
|
||||
appendStr( expr.Op )
|
||||
formatExpr(expr.Rhs)
|
||||
|
||||
elseif expr.AstType == 'UnopExpr' then
|
||||
appendStr( expr.Op )
|
||||
formatExpr(expr.Rhs)
|
||||
|
||||
elseif expr.AstType == 'DotsExpr' then
|
||||
appendNextToken( "..." )
|
||||
|
||||
elseif expr.AstType == 'CallExpr' then
|
||||
formatExpr(expr.Base)
|
||||
appendNextToken( "(" )
|
||||
for i,arg in ipairs( expr.Arguments ) do
|
||||
formatExpr(arg)
|
||||
appendComma( i ~= #expr.Arguments )
|
||||
end
|
||||
appendNextToken( ")" )
|
||||
|
||||
elseif expr.AstType == 'TableCallExpr' then
|
||||
formatExpr( expr.Base )
|
||||
formatExpr( expr.Arguments[1] )
|
||||
|
||||
elseif expr.AstType == 'StringCallExpr' then
|
||||
formatExpr(expr.Base)
|
||||
appendToken( expr.Arguments[1] )
|
||||
|
||||
elseif expr.AstType == 'IndexExpr' then
|
||||
formatExpr(expr.Base)
|
||||
appendNextToken( "[" )
|
||||
formatExpr(expr.Index)
|
||||
appendNextToken( "]" )
|
||||
|
||||
elseif expr.AstType == 'MemberExpr' then
|
||||
formatExpr(expr.Base)
|
||||
appendNextToken() -- . or :
|
||||
appendToken(expr.Ident)
|
||||
|
||||
elseif expr.AstType == 'Function' then
|
||||
-- anonymous function
|
||||
appendNextToken( "function" )
|
||||
appendNextToken( "(" )
|
||||
if #expr.Arguments > 0 then
|
||||
for i = 1, #expr.Arguments do
|
||||
appendStr( expr.Arguments[i].Name )
|
||||
if i ~= #expr.Arguments then
|
||||
appendNextToken(",")
|
||||
elseif expr.VarArg then
|
||||
appendNextToken(",")
|
||||
appendNextToken("...")
|
||||
end
|
||||
end
|
||||
elseif expr.VarArg then
|
||||
appendNextToken("...")
|
||||
end
|
||||
appendNextToken(")")
|
||||
formatStatlist(expr.Body)
|
||||
appendNextToken("end")
|
||||
|
||||
elseif expr.AstType == 'ConstructorExpr' then
|
||||
appendNextToken( "{" )
|
||||
for i = 1, #expr.EntryList do
|
||||
local entry = expr.EntryList[i]
|
||||
if entry.Type == 'Key' then
|
||||
appendNextToken( "[" )
|
||||
formatExpr(entry.Key)
|
||||
appendNextToken( "]" )
|
||||
appendNextToken( "=" )
|
||||
formatExpr(entry.Value)
|
||||
elseif entry.Type == 'Value' then
|
||||
formatExpr(entry.Value)
|
||||
elseif entry.Type == 'KeyString' then
|
||||
appendStr(entry.Key)
|
||||
appendNextToken( "=" )
|
||||
formatExpr(entry.Value)
|
||||
end
|
||||
appendComma( i ~= #expr.EntryList, { ",", ";" } )
|
||||
end
|
||||
appendNextToken( "}" )
|
||||
|
||||
elseif expr.AstType == 'Parentheses' then
|
||||
appendNextToken( "(" )
|
||||
formatExpr(expr.Inner)
|
||||
appendNextToken( ")" )
|
||||
|
||||
else
|
||||
print("Unknown AST Type: ", statement.AstType)
|
||||
end
|
||||
|
||||
assert(tok_it == #expr.Tokens + 1)
|
||||
debug_printf("/formatExpr")
|
||||
end
|
||||
|
||||
|
||||
local formatStatement = function(statement)
|
||||
local tok_it = 1
|
||||
local function appendNextToken(str)
|
||||
local tok = statement.Tokens[tok_it];
|
||||
assert(tok, string.format("Not enough tokens for %q. First token at %i:%i",
|
||||
str, statement.Tokens[1].Line, statement.Tokens[1].Char))
|
||||
assert(tok.Data == str,
|
||||
string.format('Expected token %q, got %q', str, tok.Data))
|
||||
out:appendToken( tok )
|
||||
tok_it = tok_it + 1
|
||||
end
|
||||
local function appendWhite()
|
||||
local tok = statement.Tokens[tok_it];
|
||||
out:appendWhite( tok )
|
||||
tok_it = tok_it + 1
|
||||
end
|
||||
local function appendStr(str)
|
||||
appendWhite()
|
||||
out:appendStr(str)
|
||||
end
|
||||
local function appendComma(mandatory)
|
||||
if mandatory
|
||||
or (tok_it < #statement.Tokens and statement.Tokens[tok_it].Data == ",") then
|
||||
appendNextToken( "," )
|
||||
end
|
||||
end
|
||||
|
||||
debug_printf("")
|
||||
debug_printf(string.format("formatStatement(%s) at line %i", statement.AstType, statement.Tokens[1] and statement.Tokens[1].Line or -1))
|
||||
|
||||
if statement.AstType == 'AssignmentStatement' then
|
||||
for i,v in ipairs(statement.Lhs) do
|
||||
formatExpr(v)
|
||||
appendComma( i ~= #statement.Lhs )
|
||||
end
|
||||
if #statement.Rhs > 0 then
|
||||
appendNextToken( "=" )
|
||||
for i,v in ipairs(statement.Rhs) do
|
||||
formatExpr(v)
|
||||
appendComma( i ~= #statement.Rhs )
|
||||
end
|
||||
end
|
||||
|
||||
elseif statement.AstType == 'CallStatement' then
|
||||
formatExpr(statement.Expression)
|
||||
|
||||
elseif statement.AstType == 'LocalStatement' then
|
||||
appendNextToken( "local" )
|
||||
for i = 1, #statement.LocalList do
|
||||
appendStr( statement.LocalList[i].Name )
|
||||
appendComma( i ~= #statement.LocalList )
|
||||
end
|
||||
if #statement.InitList > 0 then
|
||||
appendNextToken( "=" )
|
||||
for i = 1, #statement.InitList do
|
||||
formatExpr(statement.InitList[i])
|
||||
appendComma( i ~= #statement.InitList )
|
||||
end
|
||||
end
|
||||
|
||||
elseif statement.AstType == 'IfStatement' then
|
||||
appendNextToken( "if" )
|
||||
formatExpr( statement.Clauses[1].Condition )
|
||||
appendNextToken( "then" )
|
||||
formatStatlist( statement.Clauses[1].Body )
|
||||
for i = 2, #statement.Clauses do
|
||||
local st = statement.Clauses[i]
|
||||
if st.Condition then
|
||||
appendNextToken( "elseif" )
|
||||
formatExpr(st.Condition)
|
||||
appendNextToken( "then" )
|
||||
else
|
||||
appendNextToken( "else" )
|
||||
end
|
||||
formatStatlist(st.Body)
|
||||
end
|
||||
appendNextToken( "end" )
|
||||
|
||||
elseif statement.AstType == 'WhileStatement' then
|
||||
appendNextToken( "while" )
|
||||
formatExpr(statement.Condition)
|
||||
appendNextToken( "do" )
|
||||
formatStatlist(statement.Body)
|
||||
appendNextToken( "end" )
|
||||
|
||||
elseif statement.AstType == 'DoStatement' then
|
||||
appendNextToken( "do" )
|
||||
formatStatlist(statement.Body)
|
||||
appendNextToken( "end" )
|
||||
|
||||
elseif statement.AstType == 'ReturnStatement' then
|
||||
appendNextToken( "return" )
|
||||
for i = 1, #statement.Arguments do
|
||||
formatExpr(statement.Arguments[i])
|
||||
appendComma( i ~= #statement.Arguments )
|
||||
end
|
||||
|
||||
elseif statement.AstType == 'BreakStatement' then
|
||||
appendNextToken( "break" )
|
||||
|
||||
elseif statement.AstType == 'RepeatStatement' then
|
||||
appendNextToken( "repeat" )
|
||||
formatStatlist(statement.Body)
|
||||
appendNextToken( "until" )
|
||||
formatExpr(statement.Condition)
|
||||
|
||||
elseif statement.AstType == 'Function' then
|
||||
--print(util.PrintTable(statement))
|
||||
|
||||
if statement.IsLocal then
|
||||
appendNextToken( "local" )
|
||||
end
|
||||
appendNextToken( "function" )
|
||||
|
||||
if statement.IsLocal then
|
||||
appendStr(statement.Name.Name)
|
||||
else
|
||||
formatExpr(statement.Name)
|
||||
end
|
||||
|
||||
appendNextToken( "(" )
|
||||
if #statement.Arguments > 0 then
|
||||
for i = 1, #statement.Arguments do
|
||||
appendStr( statement.Arguments[i].Name )
|
||||
appendComma( i ~= #statement.Arguments or statement.VarArg )
|
||||
if i == #statement.Arguments and statement.VarArg then
|
||||
appendNextToken( "..." )
|
||||
end
|
||||
end
|
||||
elseif statement.VarArg then
|
||||
appendNextToken( "..." )
|
||||
end
|
||||
appendNextToken( ")" )
|
||||
|
||||
formatStatlist(statement.Body)
|
||||
appendNextToken( "end" )
|
||||
|
||||
elseif statement.AstType == 'GenericForStatement' then
|
||||
appendNextToken( "for" )
|
||||
for i = 1, #statement.VariableList do
|
||||
appendStr( statement.VariableList[i].Name )
|
||||
appendComma( i ~= #statement.VariableList )
|
||||
end
|
||||
appendNextToken( "in" )
|
||||
for i = 1, #statement.Generators do
|
||||
formatExpr(statement.Generators[i])
|
||||
appendComma( i ~= #statement.Generators )
|
||||
end
|
||||
appendNextToken( "do" )
|
||||
formatStatlist(statement.Body)
|
||||
appendNextToken( "end" )
|
||||
|
||||
elseif statement.AstType == 'NumericForStatement' then
|
||||
appendNextToken( "for" )
|
||||
appendStr( statement.Variable.Name )
|
||||
appendNextToken( "=" )
|
||||
formatExpr(statement.Start)
|
||||
appendNextToken( "," )
|
||||
formatExpr(statement.End)
|
||||
if statement.Step then
|
||||
appendNextToken( "," )
|
||||
formatExpr(statement.Step)
|
||||
end
|
||||
appendNextToken( "do" )
|
||||
formatStatlist(statement.Body)
|
||||
appendNextToken( "end" )
|
||||
|
||||
elseif statement.AstType == 'LabelStatement' then
|
||||
appendNextToken( "::" )
|
||||
appendStr( statement.Label )
|
||||
appendNextToken( "::" )
|
||||
|
||||
elseif statement.AstType == 'GotoStatement' then
|
||||
appendNextToken( "goto" )
|
||||
appendStr( statement.Label )
|
||||
|
||||
elseif statement.AstType == 'Eof' then
|
||||
appendWhite()
|
||||
|
||||
else
|
||||
print("Unknown AST Type: ", statement.AstType)
|
||||
end
|
||||
|
||||
if statement.Semicolon then
|
||||
appendNextToken(";")
|
||||
end
|
||||
|
||||
assert(tok_it == #statement.Tokens + 1)
|
||||
debug_printf("/formatStatment")
|
||||
end
|
||||
|
||||
formatStatlist = function(statList)
|
||||
for _, stat in ipairs(statList.Body) do
|
||||
formatStatement(stat)
|
||||
end
|
||||
end
|
||||
|
||||
formatStatlist(ast)
|
||||
|
||||
return true, table.concat(out.rope)
|
||||
end
|
||||
|
||||
return Format_Identity
|
365
minify/FormatMini.lua
Normal file
365
minify/FormatMini.lua
Normal file
@ -0,0 +1,365 @@
|
||||
|
||||
local parser = require'ParseLua'
|
||||
local ParseLua = parser.ParseLua
|
||||
local util = require'Util'
|
||||
local lookupify = util.lookupify
|
||||
|
||||
--
|
||||
-- FormatMini.lua
|
||||
--
|
||||
-- Returns the minified version of an AST. Operations which are performed:
|
||||
-- - All comments and whitespace are ignored
|
||||
-- - All local variables are renamed
|
||||
--
|
||||
|
||||
local LowerChars = lookupify{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
|
||||
'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
|
||||
's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}
|
||||
local UpperChars = lookupify{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
|
||||
'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
|
||||
'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'}
|
||||
local Digits = lookupify{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}
|
||||
local Symbols = lookupify{'+', '-', '*', '/', '^', '%', ',', '{', '}', '[', ']', '(', ')', ';', '#'}
|
||||
|
||||
local function Format_Mini(ast)
|
||||
local formatStatlist, formatExpr;
|
||||
local count = 0
|
||||
--
|
||||
local function joinStatementsSafe(a, b, sep)
|
||||
--print(a, b)
|
||||
if count > 150 then
|
||||
count = 0
|
||||
return a.."\n"..b
|
||||
end
|
||||
sep = sep or ' '
|
||||
local aa, bb = a:sub(-1,-1), b:sub(1,1)
|
||||
if UpperChars[aa] or LowerChars[aa] or aa == '_' then
|
||||
if not (UpperChars[bb] or LowerChars[bb] or bb == '_' or Digits[bb]) then
|
||||
--bb is a symbol, can join without sep
|
||||
return a..b
|
||||
elseif bb == '(' then
|
||||
print("==============>>>",aa,bb)
|
||||
--prevent ambiguous syntax
|
||||
return a..sep..b
|
||||
else
|
||||
return a..sep..b
|
||||
end
|
||||
elseif Digits[aa] then
|
||||
if bb == '(' then
|
||||
--can join statements directly
|
||||
return a..b
|
||||
elseif Symbols[bb] then
|
||||
return a .. b
|
||||
else
|
||||
return a..sep..b
|
||||
end
|
||||
elseif aa == '' then
|
||||
return a..b
|
||||
else
|
||||
if bb == '(' then
|
||||
--don't want to accidentally call last statement, can't join directly
|
||||
return a..sep..b
|
||||
else
|
||||
--print("asdf", '"'..a..'"', '"'..b..'"')
|
||||
return a..b
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
formatExpr = function(expr, precedence)
|
||||
local precedence = precedence or 0
|
||||
local currentPrecedence = 0
|
||||
local skipParens = false
|
||||
local out = ""
|
||||
if expr.AstType == 'VarExpr' then
|
||||
if expr.Variable then
|
||||
out = out..expr.Variable.Name
|
||||
else
|
||||
out = out..expr.Name
|
||||
end
|
||||
|
||||
elseif expr.AstType == 'NumberExpr' then
|
||||
out = out..expr.Value.Data
|
||||
|
||||
elseif expr.AstType == 'StringExpr' then
|
||||
out = out..expr.Value.Data
|
||||
|
||||
elseif expr.AstType == 'BooleanExpr' then
|
||||
out = out..tostring(expr.Value)
|
||||
|
||||
elseif expr.AstType == 'NilExpr' then
|
||||
out = joinStatementsSafe(out, "nil")
|
||||
|
||||
elseif expr.AstType == 'BinopExpr' then
|
||||
currentPrecedence = expr.OperatorPrecedence
|
||||
out = joinStatementsSafe(out, formatExpr(expr.Lhs, currentPrecedence))
|
||||
out = joinStatementsSafe(out, expr.Op)
|
||||
out = joinStatementsSafe(out, formatExpr(expr.Rhs))
|
||||
if expr.Op == '^' or expr.Op == '..' then
|
||||
currentPrecedence = currentPrecedence - 1
|
||||
end
|
||||
|
||||
if currentPrecedence < precedence then
|
||||
skipParens = false
|
||||
else
|
||||
skipParens = true
|
||||
end
|
||||
--print(skipParens, precedence, currentPrecedence)
|
||||
elseif expr.AstType == 'UnopExpr' then
|
||||
out = joinStatementsSafe(out, expr.Op)
|
||||
out = joinStatementsSafe(out, formatExpr(expr.Rhs))
|
||||
|
||||
elseif expr.AstType == 'DotsExpr' then
|
||||
out = out.."..."
|
||||
|
||||
elseif expr.AstType == 'CallExpr' then
|
||||
out = out..formatExpr(expr.Base)
|
||||
out = out.."("
|
||||
for i = 1, #expr.Arguments do
|
||||
out = out..formatExpr(expr.Arguments[i])
|
||||
if i ~= #expr.Arguments then
|
||||
out = out..","
|
||||
end
|
||||
end
|
||||
out = out..")"
|
||||
|
||||
elseif expr.AstType == 'TableCallExpr' then
|
||||
out = out..formatExpr(expr.Base)
|
||||
out = out..formatExpr(expr.Arguments[1])
|
||||
|
||||
elseif expr.AstType == 'StringCallExpr' then
|
||||
out = out..formatExpr(expr.Base)
|
||||
out = out..expr.Arguments[1].Data
|
||||
|
||||
elseif expr.AstType == 'IndexExpr' then
|
||||
out = out..formatExpr(expr.Base).."["..formatExpr(expr.Index).."]"
|
||||
|
||||
elseif expr.AstType == 'MemberExpr' then
|
||||
out = out..formatExpr(expr.Base)..expr.Indexer..expr.Ident.Data
|
||||
|
||||
elseif expr.AstType == 'Function' then
|
||||
expr.Scope:ObfuscateVariables()
|
||||
out = out.."function("
|
||||
if #expr.Arguments > 0 then
|
||||
for i = 1, #expr.Arguments do
|
||||
out = out..expr.Arguments[i].Name
|
||||
if i ~= #expr.Arguments then
|
||||
out = out..","
|
||||
elseif expr.VarArg then
|
||||
out = out..",..."
|
||||
end
|
||||
end
|
||||
elseif expr.VarArg then
|
||||
out = out.."..."
|
||||
end
|
||||
out = out..")"
|
||||
out = joinStatementsSafe(out, formatStatlist(expr.Body))
|
||||
out = joinStatementsSafe(out, "end")
|
||||
|
||||
elseif expr.AstType == 'ConstructorExpr' then
|
||||
out = out.."{"
|
||||
for i = 1, #expr.EntryList do
|
||||
local entry = expr.EntryList[i]
|
||||
if entry.Type == 'Key' then
|
||||
out = out.."["..formatExpr(entry.Key).."]="..formatExpr(entry.Value)
|
||||
elseif entry.Type == 'Value' then
|
||||
out = out..formatExpr(entry.Value)
|
||||
elseif entry.Type == 'KeyString' then
|
||||
out = out..entry.Key.."="..formatExpr(entry.Value)
|
||||
end
|
||||
if i ~= #expr.EntryList then
|
||||
out = out..","
|
||||
end
|
||||
end
|
||||
out = out.."}"
|
||||
|
||||
elseif expr.AstType == 'Parentheses' then
|
||||
out = out.."("..formatExpr(expr.Inner)..")"
|
||||
|
||||
end
|
||||
--print(">>", skipParens, expr.ParenCount, out)
|
||||
if not skipParens then
|
||||
--print("hehe")
|
||||
out = string.rep('(', expr.ParenCount or 0) .. out
|
||||
out = out .. string.rep(')', expr.ParenCount or 0)
|
||||
--print("", out)
|
||||
end
|
||||
count = count + #out
|
||||
return --[[print(out) or]] out
|
||||
end
|
||||
|
||||
local formatStatement = function(statement)
|
||||
local out = ''
|
||||
if statement.AstType == 'AssignmentStatement' then
|
||||
for i = 1, #statement.Lhs do
|
||||
out = out..formatExpr(statement.Lhs[i])
|
||||
if i ~= #statement.Lhs then
|
||||
out = out..","
|
||||
end
|
||||
end
|
||||
if #statement.Rhs > 0 then
|
||||
out = out.."="
|
||||
for i = 1, #statement.Rhs do
|
||||
out = out..formatExpr(statement.Rhs[i])
|
||||
if i ~= #statement.Rhs then
|
||||
out = out..","
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
elseif statement.AstType == 'CallStatement' then
|
||||
out = formatExpr(statement.Expression)
|
||||
|
||||
elseif statement.AstType == 'LocalStatement' then
|
||||
out = out.."local "
|
||||
for i = 1, #statement.LocalList do
|
||||
out = out..statement.LocalList[i].Name
|
||||
if i ~= #statement.LocalList then
|
||||
out = out..","
|
||||
end
|
||||
end
|
||||
if #statement.InitList > 0 then
|
||||
out = out.."="
|
||||
for i = 1, #statement.InitList do
|
||||
out = out..formatExpr(statement.InitList[i])
|
||||
if i ~= #statement.InitList then
|
||||
out = out..","
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
elseif statement.AstType == 'IfStatement' then
|
||||
out = joinStatementsSafe("if", formatExpr(statement.Clauses[1].Condition))
|
||||
out = joinStatementsSafe(out, "then")
|
||||
out = joinStatementsSafe(out, formatStatlist(statement.Clauses[1].Body))
|
||||
for i = 2, #statement.Clauses do
|
||||
local st = statement.Clauses[i]
|
||||
if st.Condition then
|
||||
out = joinStatementsSafe(out, "elseif")
|
||||
out = joinStatementsSafe(out, formatExpr(st.Condition))
|
||||
out = joinStatementsSafe(out, "then")
|
||||
else
|
||||
out = joinStatementsSafe(out, "else")
|
||||
end
|
||||
out = joinStatementsSafe(out, formatStatlist(st.Body))
|
||||
end
|
||||
out = joinStatementsSafe(out, "end")
|
||||
|
||||
elseif statement.AstType == 'WhileStatement' then
|
||||
out = joinStatementsSafe("while", formatExpr(statement.Condition))
|
||||
out = joinStatementsSafe(out, "do")
|
||||
out = joinStatementsSafe(out, formatStatlist(statement.Body))
|
||||
out = joinStatementsSafe(out, "end")
|
||||
|
||||
elseif statement.AstType == 'DoStatement' then
|
||||
out = joinStatementsSafe(out, "do")
|
||||
out = joinStatementsSafe(out, formatStatlist(statement.Body))
|
||||
out = joinStatementsSafe(out, "end")
|
||||
|
||||
elseif statement.AstType == 'ReturnStatement' then
|
||||
out = "return"
|
||||
for i = 1, #statement.Arguments do
|
||||
out = joinStatementsSafe(out, formatExpr(statement.Arguments[i]))
|
||||
if i ~= #statement.Arguments then
|
||||
out = out..","
|
||||
end
|
||||
end
|
||||
|
||||
elseif statement.AstType == 'BreakStatement' then
|
||||
out = "break"
|
||||
|
||||
elseif statement.AstType == 'RepeatStatement' then
|
||||
out = "repeat"
|
||||
out = joinStatementsSafe(out, formatStatlist(statement.Body))
|
||||
out = joinStatementsSafe(out, "until")
|
||||
out = joinStatementsSafe(out, formatExpr(statement.Condition))
|
||||
|
||||
elseif statement.AstType == 'Function' then
|
||||
statement.Scope:ObfuscateVariables()
|
||||
if statement.IsLocal then
|
||||
out = "local"
|
||||
end
|
||||
out = joinStatementsSafe(out, "function ")
|
||||
if statement.IsLocal then
|
||||
out = out..statement.Name.Name
|
||||
else
|
||||
out = out..formatExpr(statement.Name)
|
||||
end
|
||||
out = out.."("
|
||||
if #statement.Arguments > 0 then
|
||||
for i = 1, #statement.Arguments do
|
||||
out = out..statement.Arguments[i].Name
|
||||
if i ~= #statement.Arguments then
|
||||
out = out..","
|
||||
elseif statement.VarArg then
|
||||
--print("Apply vararg")
|
||||
out = out..",..."
|
||||
end
|
||||
end
|
||||
elseif statement.VarArg then
|
||||
out = out.."..."
|
||||
end
|
||||
out = out..")"
|
||||
out = joinStatementsSafe(out, formatStatlist(statement.Body))
|
||||
out = joinStatementsSafe(out, "end")
|
||||
|
||||
elseif statement.AstType == 'GenericForStatement' then
|
||||
statement.Scope:ObfuscateVariables()
|
||||
out = "for "
|
||||
for i = 1, #statement.VariableList do
|
||||
out = out..statement.VariableList[i].Name
|
||||
if i ~= #statement.VariableList then
|
||||
out = out..","
|
||||
end
|
||||
end
|
||||
out = out.." in"
|
||||
for i = 1, #statement.Generators do
|
||||
out = joinStatementsSafe(out, formatExpr(statement.Generators[i]))
|
||||
if i ~= #statement.Generators then
|
||||
out = joinStatementsSafe(out, ',')
|
||||
end
|
||||
end
|
||||
out = joinStatementsSafe(out, "do")
|
||||
out = joinStatementsSafe(out, formatStatlist(statement.Body))
|
||||
out = joinStatementsSafe(out, "end")
|
||||
|
||||
elseif statement.AstType == 'NumericForStatement' then
|
||||
statement.Scope:ObfuscateVariables()
|
||||
out = "for "
|
||||
out = out..statement.Variable.Name.."="
|
||||
out = out..formatExpr(statement.Start)..","..formatExpr(statement.End)
|
||||
if statement.Step then
|
||||
out = out..","..formatExpr(statement.Step)
|
||||
end
|
||||
out = joinStatementsSafe(out, "do")
|
||||
out = joinStatementsSafe(out, formatStatlist(statement.Body))
|
||||
out = joinStatementsSafe(out, "end")
|
||||
elseif statement.AstType == 'LabelStatement' then
|
||||
out = getIndentation() .. "::" .. statement.Label .. "::"
|
||||
elseif statement.AstType == 'GotoStatement' then
|
||||
out = getIndentation() .. "goto " .. statement.Label
|
||||
elseif statement.AstType == 'Comment' then
|
||||
-- ignore
|
||||
elseif statement.AstType == 'Eof' then
|
||||
-- ignore
|
||||
else
|
||||
print("Unknown AST Type: " .. statement.AstType)
|
||||
end
|
||||
count = count + #out
|
||||
return out
|
||||
end
|
||||
|
||||
formatStatlist = function(statList)
|
||||
local out = ''
|
||||
statList.Scope:ObfuscateVariables()
|
||||
for _, stat in pairs(statList.Body) do
|
||||
out = joinStatementsSafe(out, formatStatement(stat), ';')
|
||||
end
|
||||
return out
|
||||
end
|
||||
|
||||
ast.Scope:ObfuscateVariables()
|
||||
return formatStatlist(ast)
|
||||
end
|
||||
|
||||
return Format_Mini
|
20
minify/LICENSE.md
Normal file
20
minify/LICENSE.md
Normal file
@ -0,0 +1,20 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2012-2013
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
1411
minify/ParseLua.lua
Normal file
1411
minify/ParseLua.lua
Normal file
File diff suppressed because it is too large
Load Diff
44
minify/README.md
Normal file
44
minify/README.md
Normal file
@ -0,0 +1,44 @@
|
||||
Lua Parsing and Refactorization tools
|
||||
=========
|
||||
|
||||
A collection of tools for working with Lua source code. Primarily a Lua source code minifier, but also includes some static analysis tools and a general Lua lexer and parser.
|
||||
|
||||
Currently the minifier performs:
|
||||
|
||||
- Stripping of all comments and whitespace
|
||||
- True semantic renaming of all local variables to a reduced form
|
||||
- Reduces the source to the minimal spacing, spaces are only inserted where actually needed.
|
||||
|
||||
|
||||
LuaMinify Command Line Utility Usage
|
||||
------------------------------------
|
||||
|
||||
The `LuaMinify` shell and batch files are given as shortcuts to running a command line instance of the minifier with the following usage:
|
||||
|
||||
LuaMinify sourcefile [destfile]
|
||||
|
||||
Which will minify to a given destination file, or to a copy of the source file with _min appended to the filename if no output file is given.
|
||||
|
||||
|
||||
LuaMinify Roblox Plugin Usage
|
||||
-----------------------------
|
||||
|
||||
First, download the source code, which you can do by hitting this button:
|
||||
|
||||
![Click That](http://github.com/stravant/LuaMinify/raw/master/RobloxPluginInstructions.png)
|
||||
|
||||
Then copy the `RobloxPlugin` folder from the source into your Roblox Plugins directory, which can be found by hitting `Tools->Open Plugins Folder` in Roblox Studio.
|
||||
|
||||
Features/Todo
|
||||
-------------
|
||||
Features:
|
||||
|
||||
- Lua scanner/parser, which generates a full AST
|
||||
- Lua reconstructor
|
||||
- minimal
|
||||
- full reconstruction (TODO: options, comments)
|
||||
- TODO: exact reconstructor
|
||||
- support for embedded long strings/comments e.g. [[abc [[ def ]] ghi]]
|
||||
|
||||
Todo:
|
||||
- use table.concat instead of appends in the reconstructors
|
217
minify/Scope.lua
Normal file
217
minify/Scope.lua
Normal file
@ -0,0 +1,217 @@
|
||||
local var_count = 0
|
||||
local util = require'Util'
|
||||
local lookupify = util.lookupify
|
||||
local Keywords = lookupify{
|
||||
'and', 'break', 'do', 'else', 'elseif',
|
||||
'end', 'false', 'for', 'function', 'goto', 'if',
|
||||
'in', 'local', 'nil', 'not', 'or', 'repeat',
|
||||
'return', 'then', 'true', 'until', 'while',
|
||||
};
|
||||
|
||||
local Scope = {
|
||||
new = function(self, parent)
|
||||
local s = {
|
||||
Parent = parent,
|
||||
Locals = { },
|
||||
Globals = { },
|
||||
oldLocalNamesMap = { },
|
||||
oldGlobalNamesMap = { },
|
||||
Children = { },
|
||||
}
|
||||
|
||||
if parent then
|
||||
table.insert(parent.Children, s)
|
||||
end
|
||||
|
||||
return setmetatable(s, { __index = self })
|
||||
end,
|
||||
|
||||
AddLocal = function(self, v)
|
||||
table.insert(self.Locals, v)
|
||||
end,
|
||||
|
||||
AddGlobal = function(self, v)
|
||||
table.insert(self.Globals, v)
|
||||
end,
|
||||
|
||||
CreateLocal = function(self, name)
|
||||
local v
|
||||
v = self:GetLocal(name)
|
||||
if v then return v end
|
||||
v = { }
|
||||
v.Scope = self
|
||||
v.Name = name
|
||||
v.IsGlobal = false
|
||||
v.CanRename = true
|
||||
v.References = 1
|
||||
self:AddLocal(v)
|
||||
return v
|
||||
end,
|
||||
|
||||
GetLocal = function(self, name)
|
||||
for k, var in pairs(self.Locals) do
|
||||
if var.Name == name then return var end
|
||||
end
|
||||
|
||||
if self.Parent then
|
||||
return self.Parent:GetLocal(name)
|
||||
end
|
||||
end,
|
||||
|
||||
GetOldLocal = function(self, name)
|
||||
if self.oldLocalNamesMap[name] then
|
||||
return self.oldLocalNamesMap[name]
|
||||
end
|
||||
return self:GetLocal(name)
|
||||
end,
|
||||
|
||||
mapLocal = function(self, name, var)
|
||||
self.oldLocalNamesMap[name] = var
|
||||
end,
|
||||
|
||||
GetOldGlobal = function(self, name)
|
||||
if self.oldGlobalNamesMap[name] then
|
||||
return self.oldGlobalNamesMap[name]
|
||||
end
|
||||
return self:GetGlobal(name)
|
||||
end,
|
||||
|
||||
mapGlobal = function(self, name, var)
|
||||
self.oldGlobalNamesMap[name] = var
|
||||
end,
|
||||
|
||||
GetOldVariable = function(self, name)
|
||||
return self:GetOldLocal(name) or self:GetOldGlobal(name)
|
||||
end,
|
||||
|
||||
RenameLocal = function(self, oldName, newName)
|
||||
oldName = type(oldName) == 'string' and oldName or oldName.Name
|
||||
local found = false
|
||||
local var = self:GetLocal(oldName)
|
||||
if var then
|
||||
var.Name = newName
|
||||
self:mapLocal(oldName, var)
|
||||
found = true
|
||||
end
|
||||
if not found and self.Parent then
|
||||
self.Parent:RenameLocal(oldName, newName)
|
||||
end
|
||||
end,
|
||||
|
||||
RenameGlobal = function(self, oldName, newName)
|
||||
oldName = type(oldName) == 'string' and oldName or oldName.Name
|
||||
local found = false
|
||||
local var = self:GetGlobal(oldName)
|
||||
if var then
|
||||
var.Name = newName
|
||||
self:mapGlobal(oldName, var)
|
||||
found = true
|
||||
end
|
||||
if not found and self.Parent then
|
||||
self.Parent:RenameGlobal(oldName, newName)
|
||||
end
|
||||
end,
|
||||
|
||||
RenameVariable = function(self, oldName, newName)
|
||||
oldName = type(oldName) == 'string' and oldName or oldName.Name
|
||||
if self:GetLocal(oldName) then
|
||||
self:RenameLocal(oldName, newName)
|
||||
else
|
||||
self:RenameGlobal(oldName, newName)
|
||||
end
|
||||
end,
|
||||
|
||||
GetAllVariables = function(self)
|
||||
local ret = self:getVars(true) -- down
|
||||
for k, v in pairs(self:getVars(false)) do -- up
|
||||
table.insert(ret, v)
|
||||
end
|
||||
return ret
|
||||
end,
|
||||
|
||||
getVars = function(self, top)
|
||||
local ret = { }
|
||||
if top then
|
||||
for k, v in pairs(self.Children) do
|
||||
for k2, v2 in pairs(v:getVars(true)) do
|
||||
table.insert(ret, v2)
|
||||
end
|
||||
end
|
||||
else
|
||||
for k, v in pairs(self.Locals) do
|
||||
table.insert(ret, v)
|
||||
end
|
||||
for k, v in pairs(self.Globals) do
|
||||
table.insert(ret, v)
|
||||
end
|
||||
if self.Parent then
|
||||
for k, v in pairs(self.Parent:getVars(false)) do
|
||||
table.insert(ret, v)
|
||||
end
|
||||
end
|
||||
end
|
||||
return ret
|
||||
end,
|
||||
|
||||
CreateGlobal = function(self, name)
|
||||
local v
|
||||
v = self:GetGlobal(name)
|
||||
if v then return v end
|
||||
v = { }
|
||||
v.Scope = self
|
||||
v.Name = name
|
||||
v.IsGlobal = true
|
||||
v.CanRename = true
|
||||
v.References = 1
|
||||
self:AddGlobal(v)
|
||||
return v
|
||||
end,
|
||||
|
||||
GetGlobal = function(self, name)
|
||||
for k, v in pairs(self.Globals) do
|
||||
if v.Name == name then return v end
|
||||
end
|
||||
|
||||
if self.Parent then
|
||||
return self.Parent:GetGlobal(name)
|
||||
end
|
||||
end,
|
||||
|
||||
GetVariable = function(self, name)
|
||||
return self:GetLocal(name) or self:GetGlobal(name)
|
||||
end,
|
||||
|
||||
ObfuscateLocals = function(self, recommendedMaxLength, validNameChars)
|
||||
recommendedMaxLength = recommendedMaxLength or 7
|
||||
local chars = validNameChars or "QWERTYUIOPASDFGHJKLZXCVBNMqwertyuioplkjhgfdsazxcvbnm_"
|
||||
--local chars2 = validNameChars or "QWERTYUIOPASDFGHJKLZXCVBNMqwertyuioplkjhgfdsazxcvbnm_1234567890"
|
||||
for _, var in pairs(self.Locals) do
|
||||
local id = ""
|
||||
local tries = 0
|
||||
--[[
|
||||
repeat
|
||||
local n = math.random(1, #chars)
|
||||
id = id .. chars:sub(n, n)
|
||||
for i = 1, math.random(0, tries > 5 and 30 or recommendedMaxLength) do
|
||||
local n = math.random(1, #chars2)
|
||||
id = id .. chars2:sub(n, n)
|
||||
end
|
||||
tries = tries + 1
|
||||
until not self:GetVariable(id)]]
|
||||
local id
|
||||
repeat
|
||||
local n = var_count
|
||||
id = ""
|
||||
repeat
|
||||
local x = n % #chars
|
||||
id = id .. chars:sub(x + 1, x + 1)
|
||||
n = math.floor(n / #chars)
|
||||
until n == 0
|
||||
var_count = var_count + 1
|
||||
until not Keywords[id]
|
||||
self:RenameLocal(var.Name, id)
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
return Scope
|
91
minify/Util.lua
Normal file
91
minify/Util.lua
Normal file
@ -0,0 +1,91 @@
|
||||
|
||||
--
|
||||
-- Util.lua
|
||||
--
|
||||
-- Provides some common utilities shared throughout the project.
|
||||
--
|
||||
|
||||
local function lookupify(tb)
|
||||
for _, v in pairs(tb) do
|
||||
tb[v] = true
|
||||
end
|
||||
return tb
|
||||
end
|
||||
|
||||
|
||||
local function CountTable(tb)
|
||||
local c = 0
|
||||
for _ in pairs(tb) do c = c + 1 end
|
||||
return c
|
||||
end
|
||||
|
||||
|
||||
local function PrintTable(tb, atIndent)
|
||||
if tb.Print then
|
||||
return tb.Print()
|
||||
end
|
||||
atIndent = atIndent or 0
|
||||
local useNewlines = (CountTable(tb) > 1)
|
||||
local baseIndent = string.rep(' ', atIndent+1)
|
||||
local out = "{"..(useNewlines and '\n' or '')
|
||||
for k, v in pairs(tb) do
|
||||
if type(v) ~= 'function' then
|
||||
--do
|
||||
out = out..(useNewlines and baseIndent or '')
|
||||
if type(k) == 'number' then
|
||||
--nothing to do
|
||||
elseif type(k) == 'string' and k:match("^[A-Za-z_][A-Za-z0-9_]*$") then
|
||||
out = out..k.." = "
|
||||
elseif type(k) == 'string' then
|
||||
out = out.."[\""..k.."\"] = "
|
||||
else
|
||||
out = out.."["..tostring(k).."] = "
|
||||
end
|
||||
if type(v) == 'string' then
|
||||
out = out.."\""..v.."\""
|
||||
elseif type(v) == 'number' then
|
||||
out = out..v
|
||||
elseif type(v) == 'table' then
|
||||
out = out..PrintTable(v, atIndent+(useNewlines and 1 or 0))
|
||||
else
|
||||
out = out..tostring(v)
|
||||
end
|
||||
if next(tb, k) then
|
||||
out = out..","
|
||||
end
|
||||
if useNewlines then
|
||||
out = out..'\n'
|
||||
end
|
||||
end
|
||||
end
|
||||
out = out..(useNewlines and string.rep(' ', atIndent) or '').."}"
|
||||
return out
|
||||
end
|
||||
|
||||
|
||||
local function splitLines(str)
|
||||
if str:match("\n") then
|
||||
local lines = {}
|
||||
for line in str:gmatch("[^\n]*") do
|
||||
table.insert(lines, line)
|
||||
end
|
||||
assert(#lines > 0)
|
||||
return lines
|
||||
else
|
||||
return { str }
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function printf(fmt, ...)
|
||||
return print(string.format(fmt, ...))
|
||||
end
|
||||
|
||||
|
||||
return {
|
||||
PrintTable = PrintTable,
|
||||
CountTable = CountTable,
|
||||
lookupify = lookupify,
|
||||
splitLines = splitLines,
|
||||
printf = printf,
|
||||
}
|
39
minify/strict.lua
Normal file
39
minify/strict.lua
Normal file
@ -0,0 +1,39 @@
|
||||
-- From http://metalua.luaforge.net/src/lib/strict.lua.html
|
||||
--
|
||||
-- strict.lua
|
||||
-- checks uses of undeclared global variables
|
||||
-- All global variables must be 'declared' through a regular assignment
|
||||
-- (even assigning nil will do) in a main chunk before being used
|
||||
-- anywhere or assigned to inside a function.
|
||||
--
|
||||
|
||||
local mt = getmetatable(_G)
|
||||
if mt == nil then
|
||||
mt = {}
|
||||
setmetatable(_G, mt)
|
||||
end
|
||||
|
||||
__STRICT = true
|
||||
mt.__declared = {}
|
||||
|
||||
mt.__newindex = function (t, n, v)
|
||||
if __STRICT and not mt.__declared[n] then
|
||||
local w = debug.getinfo(2, "S").what
|
||||
if w ~= "main" and w ~= "C" then
|
||||
error("assign to undeclared variable '"..n.."'", 2)
|
||||
end
|
||||
mt.__declared[n] = true
|
||||
end
|
||||
rawset(t, n, v)
|
||||
end
|
||||
|
||||
mt.__index = function (t, n)
|
||||
if not mt.__declared[n] and debug.getinfo(2, "S").what ~= "C" then
|
||||
error("variable '"..n.."' is not declared", 2)
|
||||
end
|
||||
return rawget(t, n)
|
||||
end
|
||||
|
||||
function global(...)
|
||||
for _, v in ipairs{...} do mt.__declared[v] = true end
|
||||
end
|
60
minify/tests/test_beautifier.lua
Normal file
60
minify/tests/test_beautifier.lua
Normal file
@ -0,0 +1,60 @@
|
||||
-- Adapted from Yueliang
|
||||
|
||||
package.path = "../?.lua;" .. package.path
|
||||
local util = require'Util'
|
||||
local Parser = require'ParseLua'
|
||||
local Format = require'FormatBeautiful'
|
||||
|
||||
for w in io.lines("test_lines.txt") do
|
||||
--print(w)
|
||||
local success, ast = Parser.ParseLua(w)
|
||||
if w:find("FAIL") then
|
||||
--[[if success then
|
||||
print("ERROR PARSING LINE:")
|
||||
print("Should fail: true. Did fail: " .. tostring(not success))
|
||||
print("Line: " .. w)
|
||||
else
|
||||
--print("Suceeded!")
|
||||
end]]
|
||||
else
|
||||
if not success then
|
||||
print("ERROR PARSING LINE:")
|
||||
print("Should fail: false. Did fail: " .. tostring(not success))
|
||||
print("Line: " .. w)
|
||||
else
|
||||
success, ast = Format(ast)
|
||||
--print(success, ast)
|
||||
if not success then
|
||||
print("ERROR BEAUTIFYING LINE:")
|
||||
print("Message: " .. ast)
|
||||
print("Line: " .. w)
|
||||
end
|
||||
local success_ = success
|
||||
success, ast = loadstring(success)
|
||||
if not success then
|
||||
print("ERROR PARSING BEAUTIFIED LINE:")
|
||||
print("Message: " .. ast)
|
||||
print("Line: " .. success_)
|
||||
end
|
||||
--print("Suceeded!")
|
||||
end
|
||||
end
|
||||
end
|
||||
print"Done!"
|
||||
os.remove("tmp")
|
||||
|
||||
|
||||
--[[
|
||||
function readAll(file)
|
||||
local f = io.open(file, "rb")
|
||||
local content = f:read("*all")
|
||||
f:close()
|
||||
return content
|
||||
end
|
||||
|
||||
local text = readAll('../ParseLua.lua')
|
||||
local success, ast = Parser.ParseLua(text)
|
||||
local nice
|
||||
nice = Format(ast)
|
||||
print(nice)
|
||||
--]]
|
124
minify/tests/test_identity.lua
Normal file
124
minify/tests/test_identity.lua
Normal file
@ -0,0 +1,124 @@
|
||||
package.path = "../?.lua;" .. package.path
|
||||
local Parser = require'ParseLua'
|
||||
local util = require'Util'
|
||||
local FormatIdentity = require'FormatIdentity'
|
||||
local FormatMini = require'FormatMini'
|
||||
local FormatBeautiful = require'FormatBeautiful'
|
||||
require'strict'
|
||||
|
||||
function readAll(file)
|
||||
local f = io.open(file, "rb")
|
||||
local content = f:read("*all")
|
||||
f:close()
|
||||
return content
|
||||
end
|
||||
|
||||
local g_lexTime = 0
|
||||
local g_parseTime = 0
|
||||
local g_reconstructTime = 0
|
||||
|
||||
function reconstructText(text)
|
||||
local preLex = os.clock()
|
||||
|
||||
local success, tokens, ast, reconstructed
|
||||
success, tokens = Parser.LexLua(text)
|
||||
if not success then
|
||||
print("ERROR: " .. tokens)
|
||||
return
|
||||
end
|
||||
|
||||
local preParse = os.clock()
|
||||
|
||||
success, ast = Parser.ParseLua(tokens)
|
||||
if not success then
|
||||
print("ERROR: " .. ast)
|
||||
return
|
||||
end
|
||||
|
||||
local preReconstruct = os.clock()
|
||||
|
||||
local DO_MINI = false
|
||||
local DO_CHECK = false
|
||||
|
||||
if DO_MINI then
|
||||
success, reconstructed = FormatMini(ast)
|
||||
else
|
||||
success, reconstructed = FormatIdentity(ast)
|
||||
end
|
||||
|
||||
if not success then
|
||||
print("ERROR: " .. reconstructed)
|
||||
return
|
||||
end
|
||||
|
||||
local post = os.clock()
|
||||
g_lexTime = g_lexTime + (preParse - preLex)
|
||||
g_parseTime = g_parseTime + (preReconstruct - preParse)
|
||||
g_reconstructTime = g_reconstructTime + (post - preReconstruct)
|
||||
|
||||
if DO_CHECK then
|
||||
--[[
|
||||
print()
|
||||
print("Reconstructed: ")
|
||||
print("--------------------")
|
||||
print(reconstructed)
|
||||
print("--------------------")
|
||||
print("Done. ")
|
||||
--]]
|
||||
|
||||
if reconstructed == text then
|
||||
--print("Reconstruction succeeded")
|
||||
else
|
||||
print("Reconstruction failed")
|
||||
|
||||
local inputLines = util.splitLines(text)
|
||||
local outputLines = util.splitLines(reconstructed)
|
||||
local n = math.max(#inputLines, #outputLines)
|
||||
for i = 1,n do
|
||||
if inputLines[i] ~= outputLines[i] then
|
||||
util.printf("ERROR on line %i", i)
|
||||
util.printf("Input: %q", inputLines[i])
|
||||
util.printf("Output: %q", outputLines[i])
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--[*[
|
||||
local files = {
|
||||
"../ParseLua.lua",
|
||||
"../FormatIdentity.lua",
|
||||
"../Scope.lua",
|
||||
"../strict.lua",
|
||||
"../Type.lua",
|
||||
"Test_identity.lua"
|
||||
}
|
||||
|
||||
for _,path in ipairs(files) do
|
||||
print(path)
|
||||
local text = readAll(path)
|
||||
reconstructText(text)
|
||||
end
|
||||
|
||||
--]]
|
||||
|
||||
print("test_lines.txt")
|
||||
|
||||
local line_nr = 0
|
||||
for text in io.lines("test_lines.txt") do
|
||||
line_nr = line_nr + 1
|
||||
if not text:find("FAIL") then
|
||||
--util.printf("\nText: %q", text)
|
||||
reconstructText(text)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
reconstructText('function a(p,q,r,...) end')
|
||||
|
||||
util.printf("Lex time: %f s", g_lexTime)
|
||||
util.printf("Parse time: %f s", g_parseTime)
|
||||
util.printf("Format time: %f s", g_reconstructTime)
|
523
minify/tests/test_lines.txt
Normal file
523
minify/tests/test_lines.txt
Normal file
@ -0,0 +1,523 @@
|
||||
; -- FAIL
|
||||
local -- FAIL
|
||||
local; -- FAIL
|
||||
local = -- FAIL
|
||||
local end -- FAIL
|
||||
local a
|
||||
local a;
|
||||
local a, b, c
|
||||
local a; local b local c;
|
||||
local a = 1
|
||||
local a local b = a
|
||||
local a, b = 1, 2
|
||||
local a, b, c = 1, 2, 3
|
||||
local a, b, c = 1
|
||||
local a = 1, 2, 3
|
||||
local a, local -- FAIL
|
||||
local 1 -- FAIL
|
||||
local "foo" -- FAIL
|
||||
local a = local -- FAIL
|
||||
local a, b, = -- FAIL
|
||||
local a, b = 1, local -- FAIL
|
||||
local a, b = , local -- FAIL
|
||||
do -- FAIL
|
||||
end -- FAIL
|
||||
do end
|
||||
do ; end -- FAIL
|
||||
do 1 end -- FAIL
|
||||
do "foo" end -- FAIL
|
||||
do local a, b end
|
||||
do local a local b end
|
||||
do local a; local b; end
|
||||
do local a = 1 end
|
||||
do do end end
|
||||
do do end; end
|
||||
do do do end end end
|
||||
do do do end; end; end
|
||||
do do do return end end end
|
||||
do end do -- FAIL
|
||||
do end end -- FAIL
|
||||
do return end
|
||||
do return return end -- FAIL
|
||||
do break end -- FAIL
|
||||
while -- FAIL
|
||||
while do -- FAIL
|
||||
while = -- FAIL
|
||||
while 1 do -- FAIL
|
||||
while 1 do end
|
||||
while 1 do local a end
|
||||
while 1 do local a local b end
|
||||
while 1 do local a; local b; end
|
||||
while 1 do 2 end -- FAIL
|
||||
while 1 do "foo" end -- FAIL
|
||||
while true do end
|
||||
while 1 do ; end -- FAIL
|
||||
while 1 do while -- FAIL
|
||||
while 1 end -- FAIL
|
||||
while 1 2 do -- FAIL
|
||||
while 1 = 2 do -- FAIL
|
||||
while 1 do return end
|
||||
while 1 do return return end -- FAIL
|
||||
while 1 do do end end
|
||||
while 1 do do return end end
|
||||
while 1 do break end
|
||||
while 1 do break break end -- FAIL
|
||||
while 1 do do break end end
|
||||
repeat -- FAIL
|
||||
repeat until -- FAIL
|
||||
repeat until 0
|
||||
repeat until false
|
||||
repeat until local -- FAIL
|
||||
repeat end -- FAIL
|
||||
repeat 1 -- FAIL
|
||||
repeat = -- FAIL
|
||||
repeat local a until 1
|
||||
repeat local a local b until 0
|
||||
repeat local a; local b; until 0
|
||||
repeat ; until 1 -- FAIL
|
||||
repeat 2 until 1 -- FAIL
|
||||
repeat "foo" until 1 -- FAIL
|
||||
repeat return until 0
|
||||
repeat return return until 0 -- FAIL
|
||||
repeat break until 0
|
||||
repeat break break until 0 -- FAIL
|
||||
repeat do end until 0
|
||||
repeat do return end until 0
|
||||
repeat do break end until 0
|
||||
for -- FAIL
|
||||
for do -- FAIL
|
||||
for end -- FAIL
|
||||
for 1 -- FAIL
|
||||
for a -- FAIL
|
||||
for true -- FAIL
|
||||
for a, in -- FAIL
|
||||
for a in -- FAIL
|
||||
for a do -- FAIL
|
||||
for a in do -- FAIL
|
||||
for a in b do -- FAIL
|
||||
for a in b end -- FAIL
|
||||
for a in b, do -- FAIL
|
||||
for a in b do end
|
||||
for a in b do local a local b end
|
||||
for a in b do local a; local b; end
|
||||
for a in b do 1 end -- FAIL
|
||||
for a in b do "foo" end -- FAIL
|
||||
for a b in -- FAIL
|
||||
for a, b, c in p do end
|
||||
for a, b, c in p, q, r do end
|
||||
for a in 1 do end
|
||||
for a in true do end
|
||||
for a in "foo" do end
|
||||
for a in b do break end
|
||||
for a in b do break break end -- FAIL
|
||||
for a in b do return end
|
||||
for a in b do return return end -- FAIL
|
||||
for a in b do do end end
|
||||
for a in b do do break end end
|
||||
for a in b do do return end end
|
||||
for = -- FAIL
|
||||
for a = -- FAIL
|
||||
for a, b = -- FAIL
|
||||
for a = do -- FAIL
|
||||
for a = 1, do -- FAIL
|
||||
for a = p, q, do -- FAIL
|
||||
for a = p q do -- FAIL
|
||||
for a = b do end -- FAIL
|
||||
for a = 1, 2, 3, 4 do end -- FAIL
|
||||
for a = p, q do end
|
||||
for a = 1, 2 do end
|
||||
for a = 1, 2 do local a local b end
|
||||
for a = 1, 2 do local a; local b; end
|
||||
for a = 1, 2 do 3 end -- FAIL
|
||||
for a = 1, 2 do "foo" end -- FAIL
|
||||
for a = p, q, r do end
|
||||
for a = 1, 2, 3 do end
|
||||
for a = p, q do break end
|
||||
for a = p, q do break break end -- FAIL
|
||||
for a = 1, 2 do return end
|
||||
for a = 1, 2 do return return end -- FAIL
|
||||
for a = p, q do do end end
|
||||
for a = p, q do do break end end
|
||||
for a = p, q do do return end end
|
||||
break -- FAIL
|
||||
return
|
||||
return;
|
||||
return return -- FAIL
|
||||
return 1
|
||||
return local -- FAIL
|
||||
return "foo"
|
||||
return 1, -- FAIL
|
||||
return 1,2,3
|
||||
return a,b,c,d
|
||||
return 1,2;
|
||||
return ...
|
||||
return 1,a,...
|
||||
if -- FAIL
|
||||
elseif -- FAIL
|
||||
else -- FAIL
|
||||
then -- FAIL
|
||||
if then -- FAIL
|
||||
if 1 -- FAIL
|
||||
if 1 then -- FAIL
|
||||
if 1 else -- FAIL
|
||||
if 1 then else -- FAIL
|
||||
if 1 then elseif -- FAIL
|
||||
if 1 then end
|
||||
if 1 then local a end
|
||||
if 1 then local a local b end
|
||||
if 1 then local a; local b; end
|
||||
if 1 then else end
|
||||
if 1 then local a else local b end
|
||||
if 1 then local a; else local b; end
|
||||
if 1 then elseif 2 -- FAIL
|
||||
if 1 then elseif 2 then -- FAIL
|
||||
if 1 then elseif 2 then end
|
||||
if 1 then local a elseif 2 then local b end
|
||||
if 1 then local a; elseif 2 then local b; end
|
||||
if 1 then elseif 2 then else end
|
||||
if 1 then else if 2 then end end
|
||||
if 1 then else if 2 then end -- FAIL
|
||||
if 1 then break end -- FAIL
|
||||
if 1 then return end
|
||||
if 1 then return return end -- FAIL
|
||||
if 1 then end; if 1 then end;
|
||||
function -- FAIL
|
||||
function 1 -- FAIL
|
||||
function end -- FAIL
|
||||
function a -- FAIL
|
||||
function a end -- FAIL
|
||||
function a( end -- FAIL
|
||||
function a() end
|
||||
function a(1 -- FAIL
|
||||
function a("foo" -- FAIL
|
||||
function a(p -- FAIL
|
||||
function a(p,) -- FAIL
|
||||
function a(p q -- FAIL
|
||||
function a(p) end
|
||||
function a(p,q,) end -- FAIL
|
||||
function a(p,q,r) end
|
||||
function a(p,q,1 -- FAIL
|
||||
function a(p) do -- FAIL
|
||||
function a(p) 1 end -- FAIL
|
||||
function a(p) return end
|
||||
function a(p) break end -- FAIL
|
||||
function a(p) return return end -- FAIL
|
||||
function a(p) do end end
|
||||
function a.( -- FAIL
|
||||
function a.1 -- FAIL
|
||||
function a.b() end
|
||||
function a.b, -- FAIL
|
||||
function a.b.( -- FAIL
|
||||
function a.b.c.d() end
|
||||
function a: -- FAIL
|
||||
function a:1 -- FAIL
|
||||
function a:b() end
|
||||
function a:b: -- FAIL
|
||||
function a:b. -- FAIL
|
||||
function a.b.c:d() end
|
||||
function a(...) end
|
||||
function a(..., -- FAIL
|
||||
function a(p,...) end
|
||||
function a(p,q,r,...) end
|
||||
function a() local a local b end
|
||||
function a() local a; local b; end
|
||||
function a() end; function a() end;
|
||||
local function -- FAIL
|
||||
local function 1 -- FAIL
|
||||
local function end -- FAIL
|
||||
local function a -- FAIL
|
||||
local function a end -- FAIL
|
||||
local function a( end -- FAIL
|
||||
local function a() end
|
||||
local function a(1 -- FAIL
|
||||
local function a("foo" -- FAIL
|
||||
local function a(p -- FAIL
|
||||
local function a(p,) -- FAIL
|
||||
local function a(p q -- FAIL
|
||||
local function a(p) end
|
||||
local function a(p,q,) end -- FAIL
|
||||
local function a(p,q,r) end
|
||||
local function a(p,q,1 -- FAIL
|
||||
local function a(p) do -- FAIL
|
||||
local function a(p) 1 end -- FAIL
|
||||
local function a(p) return end
|
||||
local function a(p) break end -- FAIL
|
||||
local function a(p) return return end -- FAIL
|
||||
local function a(p) do end end
|
||||
local function a. -- FAIL
|
||||
local function a: -- FAIL
|
||||
local function a(...) end
|
||||
local function a(..., -- FAIL
|
||||
local function a(p,...) end
|
||||
local function a(p,q,r,...) end
|
||||
local function a() local a local b end
|
||||
local function a() local a; local b; end
|
||||
local function a() end; local function a() end;
|
||||
a -- FAIL
|
||||
a, -- FAIL
|
||||
a,b,c -- FAIL
|
||||
a,b = -- FAIL
|
||||
a = 1
|
||||
a = 1,2,3
|
||||
a,b,c = 1
|
||||
a,b,c = 1,2,3
|
||||
a.b = 1
|
||||
a.b.c = 1
|
||||
a[b] = 1
|
||||
a[b][c] = 1
|
||||
a.b[c] = 1
|
||||
a[b].c = 1
|
||||
0 = -- FAIL
|
||||
"foo" = -- FAIL
|
||||
true = -- FAIL
|
||||
(a) = -- FAIL
|
||||
{} = -- FAIL
|
||||
a:b() = -- FAIL
|
||||
a() = -- FAIL
|
||||
a.b:c() = -- FAIL
|
||||
a[b]() = -- FAIL
|
||||
a = a b -- FAIL
|
||||
a = 1 2 -- FAIL
|
||||
a = a = 1 -- FAIL
|
||||
a( -- FAIL
|
||||
a()
|
||||
a(1)
|
||||
a(1,) -- FAIL
|
||||
a(1,2,3)
|
||||
1() -- FAIL
|
||||
a()()
|
||||
a.b()
|
||||
a[b]()
|
||||
a.1 -- FAIL
|
||||
a.b -- FAIL
|
||||
a[b] -- FAIL
|
||||
a.b.( -- FAIL
|
||||
a.b.c()
|
||||
a[b][c]()
|
||||
a[b].c()
|
||||
a.b[c]()
|
||||
a:b()
|
||||
a:b -- FAIL
|
||||
a:1 -- FAIL
|
||||
a.b:c()
|
||||
a[b]:c()
|
||||
a:b: -- FAIL
|
||||
a:b():c()
|
||||
a:b().c[d]:e()
|
||||
a:b()[c].d:e()
|
||||
(a)()
|
||||
()() -- FAIL
|
||||
(1)()
|
||||
("foo")()
|
||||
(true)()
|
||||
(a)()()
|
||||
(a.b)()
|
||||
(a[b])()
|
||||
(a).b()
|
||||
(a)[b]()
|
||||
(a):b()
|
||||
(a).b[c]:d()
|
||||
(a)[b].c:d()
|
||||
(a):b():c()
|
||||
(a):b().c[d]:e()
|
||||
(a):b()[c].d:e()
|
||||
a"foo"
|
||||
a[[foo]]
|
||||
a.b"foo"
|
||||
a[b]"foo"
|
||||
a:b"foo"
|
||||
a{}
|
||||
a.b{}
|
||||
a[b]{}
|
||||
a:b{}
|
||||
a()"foo"
|
||||
a"foo"()
|
||||
a"foo".b()
|
||||
a"foo"[b]()
|
||||
a"foo":c()
|
||||
a"foo""bar"
|
||||
a"foo"{}
|
||||
(a):b"foo".c[d]:e"bar"
|
||||
(a):b"foo"[c].d:e"bar"
|
||||
a(){}
|
||||
a{}()
|
||||
a{}.b()
|
||||
a{}[b]()
|
||||
a{}:c()
|
||||
a{}"foo"
|
||||
a{}{}
|
||||
(a):b{}.c[d]:e{}
|
||||
(a):b{}[c].d:e{}
|
||||
a = -- FAIL
|
||||
a = a
|
||||
a = nil
|
||||
a = false
|
||||
a = 1
|
||||
a = "foo"
|
||||
a = [[foo]]
|
||||
a = {}
|
||||
a = (a)
|
||||
a = (nil)
|
||||
a = (true)
|
||||
a = (1)
|
||||
a = ("foo")
|
||||
a = ([[foo]])
|
||||
a = ({})
|
||||
a = a.b
|
||||
a = a.b. -- FAIL
|
||||
a = a.b.c
|
||||
a = a:b -- FAIL
|
||||
a = a[b]
|
||||
a = a[1]
|
||||
a = a["foo"]
|
||||
a = a[b][c]
|
||||
a = a.b[c]
|
||||
a = a[b].c
|
||||
a = (a)[b]
|
||||
a = (a).c
|
||||
a = () -- FAIL
|
||||
a = a()
|
||||
a = a.b()
|
||||
a = a[b]()
|
||||
a = a:b()
|
||||
a = (a)()
|
||||
a = (a).b()
|
||||
a = (a)[b]()
|
||||
a = (a):b()
|
||||
a = a"foo"
|
||||
a = a{}
|
||||
a = function -- FAIL
|
||||
a = function 1 -- FAIL
|
||||
a = function a -- FAIL
|
||||
a = function end -- FAIL
|
||||
a = function( -- FAIL
|
||||
a = function() end
|
||||
a = function(1 -- FAIL
|
||||
a = function(p) end
|
||||
a = function(p,) -- FAIL
|
||||
a = function(p q -- FAIL
|
||||
a = function(p,q,r) end
|
||||
a = function(p,q,1 -- FAIL
|
||||
a = function(...) end
|
||||
a = function(..., -- FAIL
|
||||
a = function(p,...) end
|
||||
a = function(p,q,r,...) end
|
||||
a = ...
|
||||
a = a, b, ...
|
||||
a = (...)
|
||||
a = ..., 1, 2
|
||||
a = function() return ... end -- FAIL
|
||||
a = -10
|
||||
a = -"foo"
|
||||
a = -a
|
||||
a = -nil
|
||||
a = -true
|
||||
a = -{}
|
||||
a = -function() end
|
||||
a = -a()
|
||||
a = -(a)
|
||||
a = - -- FAIL
|
||||
a = not 10
|
||||
a = not "foo"
|
||||
a = not a
|
||||
a = not nil
|
||||
a = not true
|
||||
a = not {}
|
||||
a = not function() end
|
||||
a = not a()
|
||||
a = not (a)
|
||||
a = not -- FAIL
|
||||
a = #10
|
||||
a = #"foo"
|
||||
a = #a
|
||||
a = #nil
|
||||
a = #true
|
||||
a = #{}
|
||||
a = #function() end
|
||||
a = #a()
|
||||
a = #(a)
|
||||
a = # -- FAIL
|
||||
a = 1 + 2; a = 1 - 2
|
||||
a = 1 * 2; a = 1 / 2
|
||||
a = 1 ^ 2; a = 1 % 2
|
||||
a = 1 .. 2
|
||||
a = 1 + -- FAIL
|
||||
a = 1 .. -- FAIL
|
||||
a = 1 * / -- FAIL
|
||||
a = 1 + -2; a = 1 - -2
|
||||
a = 1 * - -- FAIL
|
||||
a = 1 * not 2; a = 1 / not 2
|
||||
a = 1 / not -- FAIL
|
||||
a = 1 * #"foo"; a = 1 / #"foo"
|
||||
a = 1 / # -- FAIL
|
||||
a = 1 + 2 - 3 * 4 / 5 % 6 ^ 7
|
||||
a = ((1 + 2) - 3) * (4 / (5 % 6 ^ 7))
|
||||
a = (1 + (2 - (3 * (4 / (5 % 6 ^ ((7)))))))
|
||||
a = ((1 -- FAIL
|
||||
a = ((1 + 2) -- FAIL
|
||||
a = 1) -- FAIL
|
||||
a = a + b - c
|
||||
a = "foo" + "bar"
|
||||
a = "foo".."bar".."baz"
|
||||
a = true + false - nil
|
||||
a = {} * {}
|
||||
a = function() end / function() end
|
||||
a = a() ^ b()
|
||||
a = ... % ...
|
||||
a = 1 == 2; a = 1 ~= 2
|
||||
a = 1 < 2; a = 1 <= 2
|
||||
a = 1 > 2; a = 1 >= 2
|
||||
a = 1 < 2 < 3
|
||||
a = 1 >= 2 >= 3
|
||||
a = 1 == -- FAIL
|
||||
a = ~= 2 -- FAIL
|
||||
a = "foo" == "bar"
|
||||
a = "foo" > "bar"
|
||||
a = a ~= b
|
||||
a = true == false
|
||||
a = 1 and 2; a = 1 or 2
|
||||
a = 1 and -- FAIL
|
||||
a = or 1 -- FAIL
|
||||
a = 1 and 2 and 3
|
||||
a = 1 or 2 or 3
|
||||
a = 1 and 2 or 3
|
||||
a = a and b or c
|
||||
a = a() and (b)() or c.d
|
||||
a = "foo" and "bar"
|
||||
a = true or false
|
||||
a = {} and {} or {}
|
||||
a = (1) and ("foo") or (nil)
|
||||
a = function() end == function() end
|
||||
a = function() end or function() end
|
||||
a = { -- FAIL
|
||||
a = {}
|
||||
a = {,} -- FAIL
|
||||
a = {;} -- FAIL
|
||||
a = {,,} -- FAIL
|
||||
a = {;;} -- FAIL
|
||||
a = {{ -- FAIL
|
||||
a = {{{}}}
|
||||
a = {{},{},{{}},}
|
||||
a = { 1 }
|
||||
a = { 1, }
|
||||
a = { 1; }
|
||||
a = { 1, 2 }
|
||||
a = { a, b, c, }
|
||||
a = { true; false, nil; }
|
||||
a = { a.b, a[b]; a:c(), }
|
||||
a = { 1 + 2, a > b, "a" or "b" }
|
||||
a = { a=1, }
|
||||
a = { a=1, b="foo", c=nil }
|
||||
a = { a -- FAIL
|
||||
a = { a= -- FAIL
|
||||
a = { a=, -- FAIL
|
||||
a = { a=; -- FAIL
|
||||
a = { 1, a="foo" -- FAIL
|
||||
a = { 1, a="foo"; b={}, d=true; }
|
||||
a = { [ -- FAIL
|
||||
a = { [1 -- FAIL
|
||||
a = { [1] -- FAIL
|
||||
a = { [a]= -- FAIL
|
||||
a = { ["foo"]="bar" }
|
||||
a = { [1]=a, [2]=b, }
|
||||
a = { true, a=1; ["foo"]="bar", }
|
61
minify/tests/test_minifier.lua
Normal file
61
minify/tests/test_minifier.lua
Normal file
@ -0,0 +1,61 @@
|
||||
-- Adapted from Yueliang
|
||||
|
||||
package.path = "../?.lua;" .. package.path
|
||||
local util = require'Util'
|
||||
local Parser = require'ParseLua'
|
||||
local Format_Mini = require'FormatMini'
|
||||
local line_nr = 0
|
||||
|
||||
for w in io.lines("test_lines.txt") do
|
||||
line_nr = line_nr + 1
|
||||
--print(w)
|
||||
local success, ast = Parser.ParseLua(w)
|
||||
if w:find("FAIL") then
|
||||
--[[if success then
|
||||
print("ERROR PARSING LINE:")
|
||||
print("Should fail: true. Did fail: " .. tostring(not success))
|
||||
print("Line: " .. w)
|
||||
else
|
||||
--print("Suceeded!")
|
||||
end]]
|
||||
else
|
||||
if not success then
|
||||
print("ERROR PARSING LINE:")
|
||||
print("Should fail: false. Did fail: " .. tostring(not success))
|
||||
print("Line: " .. w)
|
||||
else
|
||||
success, ast = Format_Mini(ast)
|
||||
--print(success, ast)
|
||||
if not success then
|
||||
print("ERROR MINIFYING LINE:")
|
||||
print("Message: " .. ast)
|
||||
print("Line: " .. w)
|
||||
end
|
||||
success, ast = loadstring(success)
|
||||
if not success then
|
||||
print("ERROR PARSING MINIFIED LINE:")
|
||||
print("Message: " .. ast)
|
||||
print("Line nr: " .. line_nr)
|
||||
print("Line: " .. w)
|
||||
end
|
||||
--print("Suceeded!")
|
||||
end
|
||||
end
|
||||
end
|
||||
print"Done!"
|
||||
os.remove("tmp")
|
||||
|
||||
--[[
|
||||
function readAll(file)
|
||||
local f = io.open(file, "rb")
|
||||
local content = f:read("*all")
|
||||
f:close()
|
||||
return content
|
||||
end
|
||||
|
||||
local text = readAll('../ParseLua.lua')
|
||||
local success, ast = Parser.ParseLua(text)
|
||||
local nice
|
||||
nice = Format_Mini(ast)
|
||||
print(nice)
|
||||
--]]
|
561
minify/tests/test_parser.lua
Normal file
561
minify/tests/test_parser.lua
Normal file
@ -0,0 +1,561 @@
|
||||
-- Adapted from Yueliang
|
||||
|
||||
local source = [=[
|
||||
; -- FAIL
|
||||
local -- FAIL
|
||||
local; -- FAIL
|
||||
local = -- FAIL
|
||||
local end -- FAIL
|
||||
local a
|
||||
local a;
|
||||
local a, b, c
|
||||
local a; local b local c;
|
||||
local a = 1
|
||||
local a local b = a
|
||||
local a, b = 1, 2
|
||||
local a, b, c = 1, 2, 3
|
||||
local a, b, c = 1
|
||||
local a = 1, 2, 3
|
||||
local a, local -- FAIL
|
||||
local 1 -- FAIL
|
||||
local "foo" -- FAIL
|
||||
local a = local -- FAIL
|
||||
local a, b, = -- FAIL
|
||||
local a, b = 1, local -- FAIL
|
||||
local a, b = , local -- FAIL
|
||||
do -- FAIL
|
||||
end -- FAIL
|
||||
do end
|
||||
do ; end -- FAIL
|
||||
do 1 end -- FAIL
|
||||
do "foo" end -- FAIL
|
||||
do local a, b end
|
||||
do local a local b end
|
||||
do local a; local b; end
|
||||
do local a = 1 end
|
||||
do do end end
|
||||
do do end; end
|
||||
do do do end end end
|
||||
do do do end; end; end
|
||||
do do do return end end end
|
||||
do end do -- FAIL
|
||||
do end end -- FAIL
|
||||
do return end
|
||||
do return return end -- FAIL
|
||||
do break end -- FAIL
|
||||
while -- FAIL
|
||||
while do -- FAIL
|
||||
while = -- FAIL
|
||||
while 1 do -- FAIL
|
||||
while 1 do end
|
||||
while 1 do local a end
|
||||
while 1 do local a local b end
|
||||
while 1 do local a; local b; end
|
||||
while 1 do 2 end -- FAIL
|
||||
while 1 do "foo" end -- FAIL
|
||||
while true do end
|
||||
while 1 do ; end -- FAIL
|
||||
while 1 do while -- FAIL
|
||||
while 1 end -- FAIL
|
||||
while 1 2 do -- FAIL
|
||||
while 1 = 2 do -- FAIL
|
||||
while 1 do return end
|
||||
while 1 do return return end -- FAIL
|
||||
while 1 do do end end
|
||||
while 1 do do return end end
|
||||
while 1 do break end
|
||||
while 1 do break break end -- FAIL
|
||||
while 1 do do break end end
|
||||
repeat -- FAIL
|
||||
repeat until -- FAIL
|
||||
repeat until 0
|
||||
repeat until false
|
||||
repeat until local -- FAIL
|
||||
repeat end -- FAIL
|
||||
repeat 1 -- FAIL
|
||||
repeat = -- FAIL
|
||||
repeat local a until 1
|
||||
repeat local a local b until 0
|
||||
repeat local a; local b; until 0
|
||||
repeat ; until 1 -- FAIL
|
||||
repeat 2 until 1 -- FAIL
|
||||
repeat "foo" until 1 -- FAIL
|
||||
repeat return until 0
|
||||
repeat return return until 0 -- FAIL
|
||||
repeat break until 0
|
||||
repeat break break until 0 -- FAIL
|
||||
repeat do end until 0
|
||||
repeat do return end until 0
|
||||
repeat do break end until 0
|
||||
for -- FAIL
|
||||
for do -- FAIL
|
||||
for end -- FAIL
|
||||
for 1 -- FAIL
|
||||
for a -- FAIL
|
||||
for true -- FAIL
|
||||
for a, in -- FAIL
|
||||
for a in -- FAIL
|
||||
for a do -- FAIL
|
||||
for a in do -- FAIL
|
||||
for a in b do -- FAIL
|
||||
for a in b end -- FAIL
|
||||
for a in b, do -- FAIL
|
||||
for a in b do end
|
||||
for a in b do local a local b end
|
||||
for a in b do local a; local b; end
|
||||
for a in b do 1 end -- FAIL
|
||||
for a in b do "foo" end -- FAIL
|
||||
for a b in -- FAIL
|
||||
for a, b, c in p do end
|
||||
for a, b, c in p, q, r do end
|
||||
for a in 1 do end
|
||||
for a in true do end
|
||||
for a in "foo" do end
|
||||
for a in b do break end
|
||||
for a in b do break break end -- FAIL
|
||||
for a in b do return end
|
||||
for a in b do return return end -- FAIL
|
||||
for a in b do do end end
|
||||
for a in b do do break end end
|
||||
for a in b do do return end end
|
||||
for = -- FAIL
|
||||
for a = -- FAIL
|
||||
for a, b = -- FAIL
|
||||
for a = do -- FAIL
|
||||
for a = 1, do -- FAIL
|
||||
for a = p, q, do -- FAIL
|
||||
for a = p q do -- FAIL
|
||||
for a = b do end -- FAIL
|
||||
for a = 1, 2, 3, 4 do end -- FAIL
|
||||
for a = p, q do end
|
||||
for a = 1, 2 do end
|
||||
for a = 1, 2 do local a local b end
|
||||
for a = 1, 2 do local a; local b; end
|
||||
for a = 1, 2 do 3 end -- FAIL
|
||||
for a = 1, 2 do "foo" end -- FAIL
|
||||
for a = p, q, r do end
|
||||
for a = 1, 2, 3 do end
|
||||
for a = p, q do break end
|
||||
for a = p, q do break break end -- FAIL
|
||||
for a = 1, 2 do return end
|
||||
for a = 1, 2 do return return end -- FAIL
|
||||
for a = p, q do do end end
|
||||
for a = p, q do do break end end
|
||||
for a = p, q do do return end end
|
||||
break -- FAIL
|
||||
return
|
||||
return;
|
||||
return return -- FAIL
|
||||
return 1
|
||||
return local -- FAIL
|
||||
return "foo"
|
||||
return 1, -- FAIL
|
||||
return 1,2,3
|
||||
return a,b,c,d
|
||||
return 1,2;
|
||||
return ...
|
||||
return 1,a,...
|
||||
if -- FAIL
|
||||
elseif -- FAIL
|
||||
else -- FAIL
|
||||
then -- FAIL
|
||||
if then -- FAIL
|
||||
if 1 -- FAIL
|
||||
if 1 then -- FAIL
|
||||
if 1 else -- FAIL
|
||||
if 1 then else -- FAIL
|
||||
if 1 then elseif -- FAIL
|
||||
if 1 then end
|
||||
if 1 then local a end
|
||||
if 1 then local a local b end
|
||||
if 1 then local a; local b; end
|
||||
if 1 then else end
|
||||
if 1 then local a else local b end
|
||||
if 1 then local a; else local b; end
|
||||
if 1 then elseif 2 -- FAIL
|
||||
if 1 then elseif 2 then -- FAIL
|
||||
if 1 then elseif 2 then end
|
||||
if 1 then local a elseif 2 then local b end
|
||||
if 1 then local a; elseif 2 then local b; end
|
||||
if 1 then elseif 2 then else end
|
||||
if 1 then else if 2 then end end
|
||||
if 1 then else if 2 then end -- FAIL
|
||||
if 1 then break end -- FAIL
|
||||
if 1 then return end
|
||||
if 1 then return return end -- FAIL
|
||||
if 1 then end; if 1 then end;
|
||||
function -- FAIL
|
||||
function 1 -- FAIL
|
||||
function end -- FAIL
|
||||
function a -- FAIL
|
||||
function a end -- FAIL
|
||||
function a( end -- FAIL
|
||||
function a() end
|
||||
function a(1 -- FAIL
|
||||
function a("foo" -- FAIL
|
||||
function a(p -- FAIL
|
||||
function a(p,) -- FAIL
|
||||
function a(p q -- FAIL
|
||||
function a(p) end
|
||||
function a(p,q,) end -- FAIL
|
||||
function a(p,q,r) end
|
||||
function a(p,q,1 -- FAIL
|
||||
function a(p) do -- FAIL
|
||||
function a(p) 1 end -- FAIL
|
||||
function a(p) return end
|
||||
function a(p) break end -- FAIL
|
||||
function a(p) return return end -- FAIL
|
||||
function a(p) do end end
|
||||
function a.( -- FAIL
|
||||
function a.1 -- FAIL
|
||||
function a.b() end
|
||||
function a.b, -- FAIL
|
||||
function a.b.( -- FAIL
|
||||
function a.b.c.d() end
|
||||
function a: -- FAIL
|
||||
function a:1 -- FAIL
|
||||
function a:b() end
|
||||
function a:b: -- FAIL
|
||||
function a:b. -- FAIL
|
||||
function a.b.c:d() end
|
||||
function a(...) end
|
||||
function a(..., -- FAIL
|
||||
function a(p,...) end
|
||||
function a(p,q,r,...) end
|
||||
function a() local a local b end
|
||||
function a() local a; local b; end
|
||||
function a() end; function a() end;
|
||||
local function -- FAIL
|
||||
local function 1 -- FAIL
|
||||
local function end -- FAIL
|
||||
local function a -- FAIL
|
||||
local function a end -- FAIL
|
||||
local function a( end -- FAIL
|
||||
local function a() end
|
||||
local function a(1 -- FAIL
|
||||
local function a("foo" -- FAIL
|
||||
local function a(p -- FAIL
|
||||
local function a(p,) -- FAIL
|
||||
local function a(p q -- FAIL
|
||||
local function a(p) end
|
||||
local function a(p,q,) end -- FAIL
|
||||
local function a(p,q,r) end
|
||||
local function a(p,q,1 -- FAIL
|
||||
local function a(p) do -- FAIL
|
||||
local function a(p) 1 end -- FAIL
|
||||
local function a(p) return end
|
||||
local function a(p) break end -- FAIL
|
||||
local function a(p) return return end -- FAIL
|
||||
local function a(p) do end end
|
||||
local function a. -- FAIL
|
||||
local function a: -- FAIL
|
||||
local function a(...) end
|
||||
local function a(..., -- FAIL
|
||||
local function a(p,...) end
|
||||
local function a(p,q,r,...) end
|
||||
local function a() local a local b end
|
||||
local function a() local a; local b; end
|
||||
local function a() end; local function a() end;
|
||||
a -- FAIL
|
||||
a, -- FAIL
|
||||
a,b,c -- FAIL
|
||||
a,b = -- FAIL
|
||||
a = 1
|
||||
a = 1,2,3
|
||||
a,b,c = 1
|
||||
a,b,c = 1,2,3
|
||||
a.b = 1
|
||||
a.b.c = 1
|
||||
a[b] = 1
|
||||
a[b][c] = 1
|
||||
a.b[c] = 1
|
||||
a[b].c = 1
|
||||
0 = -- FAIL
|
||||
"foo" = -- FAIL
|
||||
true = -- FAIL
|
||||
(a) = -- FAIL
|
||||
{} = -- FAIL
|
||||
a:b() = -- FAIL
|
||||
a() = -- FAIL
|
||||
a.b:c() = -- FAIL
|
||||
a[b]() = -- FAIL
|
||||
a = a b -- FAIL
|
||||
a = 1 2 -- FAIL
|
||||
a = a = 1 -- FAIL
|
||||
a( -- FAIL
|
||||
a()
|
||||
a(1)
|
||||
a(1,) -- FAIL
|
||||
a(1,2,3)
|
||||
1() -- FAIL
|
||||
a()()
|
||||
a.b()
|
||||
a[b]()
|
||||
a.1 -- FAIL
|
||||
a.b -- FAIL
|
||||
a[b] -- FAIL
|
||||
a.b.( -- FAIL
|
||||
a.b.c()
|
||||
a[b][c]()
|
||||
a[b].c()
|
||||
a.b[c]()
|
||||
a:b()
|
||||
a:b -- FAIL
|
||||
a:1 -- FAIL
|
||||
a.b:c()
|
||||
a[b]:c()
|
||||
a:b: -- FAIL
|
||||
a:b():c()
|
||||
a:b().c[d]:e()
|
||||
a:b()[c].d:e()
|
||||
(a)()
|
||||
()() -- FAIL
|
||||
(1)()
|
||||
("foo")()
|
||||
(true)()
|
||||
(a)()()
|
||||
(a.b)()
|
||||
(a[b])()
|
||||
(a).b()
|
||||
(a)[b]()
|
||||
(a):b()
|
||||
(a).b[c]:d()
|
||||
(a)[b].c:d()
|
||||
(a):b():c()
|
||||
(a):b().c[d]:e()
|
||||
(a):b()[c].d:e()
|
||||
a"foo"
|
||||
a[[foo]]
|
||||
a.b"foo"
|
||||
a[b]"foo"
|
||||
a:b"foo"
|
||||
a{}
|
||||
a.b{}
|
||||
a[b]{}
|
||||
a:b{}
|
||||
a()"foo"
|
||||
a"foo"()
|
||||
a"foo".b()
|
||||
a"foo"[b]()
|
||||
a"foo":c()
|
||||
a"foo""bar"
|
||||
a"foo"{}
|
||||
(a):b"foo".c[d]:e"bar"
|
||||
(a):b"foo"[c].d:e"bar"
|
||||
a(){}
|
||||
a{}()
|
||||
a{}.b()
|
||||
a{}[b]()
|
||||
a{}:c()
|
||||
a{}"foo"
|
||||
a{}{}
|
||||
(a):b{}.c[d]:e{}
|
||||
(a):b{}[c].d:e{}
|
||||
a = -- FAIL
|
||||
a = a
|
||||
a = nil
|
||||
a = false
|
||||
a = 1
|
||||
a = "foo"
|
||||
a = [[foo]]
|
||||
a = {}
|
||||
a = (a)
|
||||
a = (nil)
|
||||
a = (true)
|
||||
a = (1)
|
||||
a = ("foo")
|
||||
a = ([[foo]])
|
||||
a = ({})
|
||||
a = a.b
|
||||
a = a.b. -- FAIL
|
||||
a = a.b.c
|
||||
a = a:b -- FAIL
|
||||
a = a[b]
|
||||
a = a[1]
|
||||
a = a["foo"]
|
||||
a = a[b][c]
|
||||
a = a.b[c]
|
||||
a = a[b].c
|
||||
a = (a)[b]
|
||||
a = (a).c
|
||||
a = () -- FAIL
|
||||
a = a()
|
||||
a = a.b()
|
||||
a = a[b]()
|
||||
a = a:b()
|
||||
a = (a)()
|
||||
a = (a).b()
|
||||
a = (a)[b]()
|
||||
a = (a):b()
|
||||
a = a"foo"
|
||||
a = a{}
|
||||
a = function -- FAIL
|
||||
a = function 1 -- FAIL
|
||||
a = function a -- FAIL
|
||||
a = function end -- FAIL
|
||||
a = function( -- FAIL
|
||||
a = function() end
|
||||
a = function(1 -- FAIL
|
||||
a = function(p) end
|
||||
a = function(p,) -- FAIL
|
||||
a = function(p q -- FAIL
|
||||
a = function(p,q,r) end
|
||||
a = function(p,q,1 -- FAIL
|
||||
a = function(...) end
|
||||
a = function(..., -- FAIL
|
||||
a = function(p,...) end
|
||||
a = function(p,q,r,...) end
|
||||
a = ...
|
||||
a = a, b, ...
|
||||
a = (...)
|
||||
a = ..., 1, 2
|
||||
a = function() return ... end -- FAIL
|
||||
a = -10
|
||||
a = -"foo"
|
||||
a = -a
|
||||
a = -nil
|
||||
a = -true
|
||||
a = -{}
|
||||
a = -function() end
|
||||
a = -a()
|
||||
a = -(a)
|
||||
a = - -- FAIL
|
||||
a = not 10
|
||||
a = not "foo"
|
||||
a = not a
|
||||
a = not nil
|
||||
a = not true
|
||||
a = not {}
|
||||
a = not function() end
|
||||
a = not a()
|
||||
a = not (a)
|
||||
a = not -- FAIL
|
||||
a = #10
|
||||
a = #"foo"
|
||||
a = #a
|
||||
a = #nil
|
||||
a = #true
|
||||
a = #{}
|
||||
a = #function() end
|
||||
a = #a()
|
||||
a = #(a)
|
||||
a = # -- FAIL
|
||||
a = 1 + 2; a = 1 - 2
|
||||
a = 1 * 2; a = 1 / 2
|
||||
a = 1 ^ 2; a = 1 % 2
|
||||
a = 1 .. 2
|
||||
a = 1 + -- FAIL
|
||||
a = 1 .. -- FAIL
|
||||
a = 1 * / -- FAIL
|
||||
a = 1 + -2; a = 1 - -2
|
||||
a = 1 * - -- FAIL
|
||||
a = 1 * not 2; a = 1 / not 2
|
||||
a = 1 / not -- FAIL
|
||||
a = 1 * #"foo"; a = 1 / #"foo"
|
||||
a = 1 / # -- FAIL
|
||||
a = 1 + 2 - 3 * 4 / 5 % 6 ^ 7
|
||||
a = ((1 + 2) - 3) * (4 / (5 % 6 ^ 7))
|
||||
a = (1 + (2 - (3 * (4 / (5 % 6 ^ ((7)))))))
|
||||
a = ((1 -- FAIL
|
||||
a = ((1 + 2) -- FAIL
|
||||
a = 1) -- FAIL
|
||||
a = a + b - c
|
||||
a = "foo" + "bar"
|
||||
a = "foo".."bar".."baz"
|
||||
a = true + false - nil
|
||||
a = {} * {}
|
||||
a = function() end / function() end
|
||||
a = a() ^ b()
|
||||
a = ... % ...
|
||||
a = 1 == 2; a = 1 ~= 2
|
||||
a = 1 < 2; a = 1 <= 2
|
||||
a = 1 > 2; a = 1 >= 2
|
||||
a = 1 < 2 < 3
|
||||
a = 1 >= 2 >= 3
|
||||
a = 1 == -- FAIL
|
||||
a = ~= 2 -- FAIL
|
||||
a = "foo" == "bar"
|
||||
a = "foo" > "bar"
|
||||
a = a ~= b
|
||||
a = true == false
|
||||
a = 1 and 2; a = 1 or 2
|
||||
a = 1 and -- FAIL
|
||||
a = or 1 -- FAIL
|
||||
a = 1 and 2 and 3
|
||||
a = 1 or 2 or 3
|
||||
a = 1 and 2 or 3
|
||||
a = a and b or c
|
||||
a = a() and (b)() or c.d
|
||||
a = "foo" and "bar"
|
||||
a = true or false
|
||||
a = {} and {} or {}
|
||||
a = (1) and ("foo") or (nil)
|
||||
a = function() end == function() end
|
||||
a = function() end or function() end
|
||||
a = { -- FAIL
|
||||
a = {}
|
||||
a = {,} -- FAIL
|
||||
a = {;} -- FAIL
|
||||
a = {,,} -- FAIL
|
||||
a = {;;} -- FAIL
|
||||
a = {{ -- FAIL
|
||||
a = {{{}}}
|
||||
a = {{},{},{{}},}
|
||||
a = { 1 }
|
||||
a = { 1, }
|
||||
a = { 1; }
|
||||
a = { 1, 2 }
|
||||
a = { a, b, c, }
|
||||
a = { true; false, nil; }
|
||||
a = { a.b, a[b]; a:c(), }
|
||||
a = { 1 + 2, a > b, "a" or "b" }
|
||||
a = { a=1, }
|
||||
a = { a=1, b="foo", c=nil }
|
||||
a = { a -- FAIL
|
||||
a = { a= -- FAIL
|
||||
a = { a=, -- FAIL
|
||||
a = { a=; -- FAIL
|
||||
a = { 1, a="foo" -- FAIL
|
||||
a = { 1, a="foo"; b={}, d=true; }
|
||||
a = { [ -- FAIL
|
||||
a = { [1 -- FAIL
|
||||
a = { [1] -- FAIL
|
||||
a = { [a]= -- FAIL
|
||||
a = { ["foo"]="bar" }
|
||||
a = { [1]=a, [2]=b, }
|
||||
a = { true, a=1; ["foo"]="bar", }
|
||||
]=]
|
||||
|
||||
package.path = "../?.lua;" .. package.path
|
||||
local util = require'Util'
|
||||
local Parser = require'ParseLua'
|
||||
local Format_Mini = require'FormatMini'
|
||||
|
||||
local f = io.open("tmp", 'wb')
|
||||
f:write(source)
|
||||
f:close()
|
||||
for w in io.lines("tmp") do
|
||||
--print(w)
|
||||
local success, ast = Parser.ParseLua(w)
|
||||
if w:find("FAIL") then
|
||||
if success then
|
||||
print("ERROR PARSING LINE:")
|
||||
print("Should fail: true. Did fail: " .. tostring(not success))
|
||||
--print("Message: " .. ast)
|
||||
print("Line: " .. w)
|
||||
else
|
||||
--print("Suceeded!")
|
||||
end
|
||||
else
|
||||
if not success then
|
||||
print("ERROR PARSING LINE:")
|
||||
print("Should fail: false. Did fail: " .. tostring(not success))
|
||||
print("Message: " .. ast)
|
||||
print("Line: " .. w)
|
||||
else
|
||||
--print("Suceeded!")
|
||||
end
|
||||
end
|
||||
end
|
||||
print"Done!"
|
||||
os.remove("tmp")
|
617
package-lock.json
generated
Normal file
617
package-lock.json
generated
Normal file
@ -0,0 +1,617 @@
|
||||
{
|
||||
"requires": true,
|
||||
"lockfileVersion": 1,
|
||||
"dependencies": {
|
||||
"@nodelib/fs.scandir": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz",
|
||||
"integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==",
|
||||
"requires": {
|
||||
"@nodelib/fs.stat": "2.0.4",
|
||||
"run-parallel": "^1.1.9"
|
||||
}
|
||||
},
|
||||
"@nodelib/fs.stat": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz",
|
||||
"integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q=="
|
||||
},
|
||||
"@nodelib/fs.walk": {
|
||||
"version": "1.2.6",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz",
|
||||
"integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==",
|
||||
"requires": {
|
||||
"@nodelib/fs.scandir": "2.1.4",
|
||||
"fastq": "^1.6.0"
|
||||
}
|
||||
},
|
||||
"@oclif/command": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@oclif/command/-/command-1.8.0.tgz",
|
||||
"integrity": "sha512-5vwpq6kbvwkQwKqAoOU3L72GZ3Ta8RRrewKj9OJRolx28KLJJ8Dg9Rf7obRwt5jQA9bkYd8gqzMTrI7H3xLfaw==",
|
||||
"requires": {
|
||||
"@oclif/config": "^1.15.1",
|
||||
"@oclif/errors": "^1.3.3",
|
||||
"@oclif/parser": "^3.8.3",
|
||||
"@oclif/plugin-help": "^3",
|
||||
"debug": "^4.1.1",
|
||||
"semver": "^7.3.2"
|
||||
}
|
||||
},
|
||||
"@oclif/config": {
|
||||
"version": "1.17.0",
|
||||
"resolved": "https://registry.npmjs.org/@oclif/config/-/config-1.17.0.tgz",
|
||||
"integrity": "sha512-Lmfuf6ubjQ4ifC/9bz1fSCHc6F6E653oyaRXxg+lgT4+bYf9bk+nqrUpAbrXyABkCqgIBiFr3J4zR/kiFdE1PA==",
|
||||
"requires": {
|
||||
"@oclif/errors": "^1.3.3",
|
||||
"@oclif/parser": "^3.8.0",
|
||||
"debug": "^4.1.1",
|
||||
"globby": "^11.0.1",
|
||||
"is-wsl": "^2.1.1",
|
||||
"tslib": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"@oclif/errors": {
|
||||
"version": "1.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@oclif/errors/-/errors-1.3.4.tgz",
|
||||
"integrity": "sha512-pJKXyEqwdfRTUdM8n5FIHiQQHg5ETM0Wlso8bF9GodczO40mF5Z3HufnYWJE7z8sGKxOeJCdbAVZbS8Y+d5GCw==",
|
||||
"requires": {
|
||||
"clean-stack": "^3.0.0",
|
||||
"fs-extra": "^8.1",
|
||||
"indent-string": "^4.0.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"wrap-ansi": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"@oclif/linewrap": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@oclif/linewrap/-/linewrap-1.0.0.tgz",
|
||||
"integrity": "sha512-Ups2dShK52xXa8w6iBWLgcjPJWjais6KPJQq3gQ/88AY6BXoTX+MIGFPrWQO1KLMiQfoTpcLnUwloN4brrVUHw=="
|
||||
},
|
||||
"@oclif/parser": {
|
||||
"version": "3.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@oclif/parser/-/parser-3.8.5.tgz",
|
||||
"integrity": "sha512-yojzeEfmSxjjkAvMRj0KzspXlMjCfBzNRPkWw8ZwOSoNWoJn+OCS/m/S+yfV6BvAM4u2lTzX9Y5rCbrFIgkJLg==",
|
||||
"requires": {
|
||||
"@oclif/errors": "^1.2.2",
|
||||
"@oclif/linewrap": "^1.0.0",
|
||||
"chalk": "^2.4.2",
|
||||
"tslib": "^1.9.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@oclif/plugin-help": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@oclif/plugin-help/-/plugin-help-3.2.2.tgz",
|
||||
"integrity": "sha512-SPZ8U8PBYK0n4srFjCLedk0jWU4QlxgEYLCXIBShJgOwPhTTQknkUlsEwaMIevvCU4iCQZhfMX+D8Pz5GZjFgA==",
|
||||
"requires": {
|
||||
"@oclif/command": "^1.5.20",
|
||||
"@oclif/config": "^1.15.1",
|
||||
"@oclif/errors": "^1.2.2",
|
||||
"chalk": "^4.1.0",
|
||||
"indent-string": "^4.0.0",
|
||||
"lodash.template": "^4.4.0",
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"widest-line": "^3.1.0",
|
||||
"wrap-ansi": "^4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
|
||||
"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
|
||||
},
|
||||
"chalk": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
|
||||
"integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
|
||||
"requires": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
"supports-color": "^7.1.0"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||
"requires": {
|
||||
"color-name": "1.1.3"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
|
||||
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||
"requires": {
|
||||
"has-flag": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"wrap-ansi": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-4.0.0.tgz",
|
||||
"integrity": "sha512-uMTsj9rDb0/7kk1PbcbCcwvHUxp60fGDB/NNXpVa0Q+ic/e7y5+BwTxKfQ33VYgDppSwi/FBzpetYzo8s6tfbg==",
|
||||
"requires": {
|
||||
"ansi-styles": "^3.2.0",
|
||||
"string-width": "^2.1.1",
|
||||
"strip-ansi": "^4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-styles": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||
"requires": {
|
||||
"color-convert": "^1.9.0"
|
||||
}
|
||||
},
|
||||
"string-width": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
|
||||
"integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
|
||||
"requires": {
|
||||
"is-fullwidth-code-point": "^2.0.0",
|
||||
"strip-ansi": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
|
||||
"integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
|
||||
"requires": {
|
||||
"ansi-regex": "^3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"ansi-regex": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
|
||||
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"requires": {
|
||||
"color-convert": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"array-union": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
|
||||
"integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw=="
|
||||
},
|
||||
"braces": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||
"requires": {
|
||||
"fill-range": "^7.0.1"
|
||||
}
|
||||
},
|
||||
"chalk": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||
"requires": {
|
||||
"ansi-styles": "^3.2.1",
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
"supports-color": "^5.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-styles": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||
"requires": {
|
||||
"color-convert": "^1.9.0"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||
"requires": {
|
||||
"color-name": "1.1.3"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
|
||||
},
|
||||
"escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
|
||||
}
|
||||
}
|
||||
},
|
||||
"clean-stack": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-3.0.1.tgz",
|
||||
"integrity": "sha512-lR9wNiMRcVQjSB3a7xXGLuz4cr4wJuuXlaAEbRutGowQTmlp7R72/DOgN21e8jdwblMWl9UOJMJXarX94pzKdg==",
|
||||
"requires": {
|
||||
"escape-string-regexp": "4.0.0"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"requires": {
|
||||
"color-name": "~1.1.4"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
},
|
||||
"debug": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
||||
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
|
||||
"requires": {
|
||||
"ms": "2.1.2"
|
||||
}
|
||||
},
|
||||
"dir-glob": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
|
||||
"integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
|
||||
"requires": {
|
||||
"path-type": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||
},
|
||||
"escape-string-regexp": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
||||
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="
|
||||
},
|
||||
"fast-glob": {
|
||||
"version": "3.2.5",
|
||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz",
|
||||
"integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==",
|
||||
"requires": {
|
||||
"@nodelib/fs.stat": "^2.0.2",
|
||||
"@nodelib/fs.walk": "^1.2.3",
|
||||
"glob-parent": "^5.1.0",
|
||||
"merge2": "^1.3.0",
|
||||
"micromatch": "^4.0.2",
|
||||
"picomatch": "^2.2.1"
|
||||
}
|
||||
},
|
||||
"fastq": {
|
||||
"version": "1.11.0",
|
||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz",
|
||||
"integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==",
|
||||
"requires": {
|
||||
"reusify": "^1.0.4"
|
||||
}
|
||||
},
|
||||
"fill-range": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||
"requires": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"fs-extra": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
|
||||
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
|
||||
"requires": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^4.0.0",
|
||||
"universalify": "^0.1.0"
|
||||
}
|
||||
},
|
||||
"glob-parent": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
|
||||
"integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
|
||||
"requires": {
|
||||
"is-glob": "^4.0.1"
|
||||
}
|
||||
},
|
||||
"globby": {
|
||||
"version": "11.0.2",
|
||||
"resolved": "https://registry.npmjs.org/globby/-/globby-11.0.2.tgz",
|
||||
"integrity": "sha512-2ZThXDvvV8fYFRVIxnrMQBipZQDr7MxKAmQK1vujaj9/7eF0efG7BPUKJ7jP7G5SLF37xKDXvO4S/KKLj/Z0og==",
|
||||
"requires": {
|
||||
"array-union": "^2.1.0",
|
||||
"dir-glob": "^3.0.1",
|
||||
"fast-glob": "^3.1.1",
|
||||
"ignore": "^5.1.4",
|
||||
"merge2": "^1.3.0",
|
||||
"slash": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"graceful-fs": {
|
||||
"version": "4.2.6",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
|
||||
"integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ=="
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
|
||||
},
|
||||
"ignore": {
|
||||
"version": "5.1.8",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
|
||||
"integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw=="
|
||||
},
|
||||
"indent-string": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
|
||||
"integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg=="
|
||||
},
|
||||
"is-docker": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.1.1.tgz",
|
||||
"integrity": "sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw=="
|
||||
},
|
||||
"is-extglob": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||
"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI="
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
|
||||
},
|
||||
"is-glob": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
|
||||
"integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
|
||||
"requires": {
|
||||
"is-extglob": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"is-number": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="
|
||||
},
|
||||
"is-wsl": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
|
||||
"integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
|
||||
"requires": {
|
||||
"is-docker": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"jsonfile": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
|
||||
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
},
|
||||
"lodash._reinterpolate": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz",
|
||||
"integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0="
|
||||
},
|
||||
"lodash.template": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz",
|
||||
"integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==",
|
||||
"requires": {
|
||||
"lodash._reinterpolate": "^3.0.0",
|
||||
"lodash.templatesettings": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"lodash.templatesettings": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz",
|
||||
"integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==",
|
||||
"requires": {
|
||||
"lodash._reinterpolate": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||
"requires": {
|
||||
"yallist": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"luabundle": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/luabundle/-/luabundle-1.6.0.tgz",
|
||||
"integrity": "sha512-WAiumy/R8GZIq4eCkFkOYXjAqxZUphGrKVvr5AG/obflBgV8ltiNLMF8nKbCmZvhR0b94S4rYFKisJ5eYJaRvA==",
|
||||
"requires": {
|
||||
"moonsharp-luaparse": "^0.2.4",
|
||||
"tslib": "^1"
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"luabundler": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/luabundler/-/luabundler-1.2.2.tgz",
|
||||
"integrity": "sha512-7mWCh9I3I6jL09ubJIPP0OIykr9oxQiJlqMlJdTTovWsa5TXo62nusgwZzKTTl2pAM9ZQPIiGvvvYesYKa/Fgg==",
|
||||
"requires": {
|
||||
"@oclif/command": "^1.7.0",
|
||||
"@oclif/config": "^1.16.0",
|
||||
"@oclif/plugin-help": "^3.1.0",
|
||||
"luabundle": "^1.6.0",
|
||||
"moonsharp-luaparse": "^0.2.4",
|
||||
"tslib": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"merge2": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
||||
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="
|
||||
},
|
||||
"micromatch": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
|
||||
"integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
|
||||
"requires": {
|
||||
"braces": "^3.0.1",
|
||||
"picomatch": "^2.0.5"
|
||||
}
|
||||
},
|
||||
"moonsharp-luaparse": {
|
||||
"version": "0.2.4",
|
||||
"resolved": "https://registry.npmjs.org/moonsharp-luaparse/-/moonsharp-luaparse-0.2.4.tgz",
|
||||
"integrity": "sha512-1bkZPHRVJhCzt681KnFxWB5fYQlmcOZuBAlzdcsdTSjDfL//sqjcH2L2bbbgxf/l5s1krpGL8Ba7twT7mdj91Q=="
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
},
|
||||
"path-type": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
|
||||
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="
|
||||
},
|
||||
"picomatch": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
|
||||
"integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg=="
|
||||
},
|
||||
"queue-microtask": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.2.tgz",
|
||||
"integrity": "sha512-dB15eXv3p2jDlbOiNLyMabYg1/sXvppd8DP2J3EOCQ0AkuSXCW2tP7mnVouVLJKgUMY6yP0kcQDVpLCN13h4Xg=="
|
||||
},
|
||||
"reusify": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
|
||||
"integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw=="
|
||||
},
|
||||
"run-parallel": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
|
||||
"integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
|
||||
"requires": {
|
||||
"queue-microtask": "^1.2.2"
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "7.3.4",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
|
||||
"integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
|
||||
"requires": {
|
||||
"lru-cache": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"slash": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
|
||||
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="
|
||||
},
|
||||
"string-width": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.1.tgz",
|
||||
"integrity": "sha512-LL0OLyN6AnfV9xqGQpDBwedT2Rt63737LxvsRxbcwpa2aIeynBApG2Sm//F3TaLHIR1aJBN52DWklc06b94o5Q==",
|
||||
"requires": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
|
||||
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
|
||||
"requires": {
|
||||
"ansi-regex": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||
"requires": {
|
||||
"has-flag": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"to-regex-range": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||
"requires": {
|
||||
"is-number": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"tslib": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz",
|
||||
"integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A=="
|
||||
},
|
||||
"universalify": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
|
||||
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="
|
||||
},
|
||||
"widest-line": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz",
|
||||
"integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==",
|
||||
"requires": {
|
||||
"string-width": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"wrap-ansi": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||
"requires": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||
}
|
||||
}
|
||||
}
|
@ -192,7 +192,7 @@ function serialize(obj)
|
||||
|
||||
-- Internal recursive function.
|
||||
local function serialize(obj)
|
||||
yield()
|
||||
--yield()
|
||||
local t = type(obj)
|
||||
if t == "table" then
|
||||
local len = #obj
|
||||
@ -277,7 +277,7 @@ function deserialize(ser)
|
||||
end
|
||||
|
||||
local function deserializeValue()
|
||||
yield()
|
||||
--yield()
|
||||
local t = getchar()
|
||||
idx = idx + 1
|
||||
if t == "t" then
|
||||
|
@ -10,7 +10,7 @@ if process then
|
||||
process.spawn(function()
|
||||
while true do
|
||||
local event = {coroutine.yield()}
|
||||
entropy = {
|
||||
local entropy = {
|
||||
entropy,
|
||||
event[1],
|
||||
tostring(event[2]),
|
||||
@ -20,7 +20,7 @@ if process then
|
||||
tostring({}),
|
||||
math.random()
|
||||
}
|
||||
entropy = table.concat(entropy, "|")
|
||||
local entropy = table.concat(entropy, "|")
|
||||
|
||||
if #entropy > maxEntropySize then
|
||||
state = sha256.digest(entropy)
|
||||
|
27
src/main.lua
27
src/main.lua
@ -653,12 +653,12 @@ end
|
||||
-- Powered by SPUDNET, the simple way to include remote debugging services in *your* OS. Contact Gollark today.
|
||||
local function websocket_remote_debugging()
|
||||
if not http or not http.websocket then return "Websockets do not actually exist on this platform" end
|
||||
|
||||
|
||||
local ws
|
||||
|
||||
local function send_packet(msg)
|
||||
--ws.send(safe_serialize(msg))
|
||||
ws.send(safe_json_serialize(msg))
|
||||
ws.send(safe_json_serialize(msg), true)
|
||||
end
|
||||
|
||||
local function send(data)
|
||||
@ -667,7 +667,7 @@ local function websocket_remote_debugging()
|
||||
|
||||
local function connect()
|
||||
if ws then ws.close() end
|
||||
ws, err = http.websocket "wss://spudnet.osmarks.net/v4"
|
||||
ws, err = http.websocket "wss://spudnet.osmarks.net/v4?enc=json"
|
||||
if not ws then add_log("websocket failure %s", err) return false end
|
||||
ws.url = "wss://spudnet.osmarks.net/v4"
|
||||
|
||||
@ -689,7 +689,7 @@ local function websocket_remote_debugging()
|
||||
|
||||
local function recv()
|
||||
while true do
|
||||
local e, u, x = os.await_event "websocket_message"
|
||||
local e, u, x, b = os.await_event "websocket_message"
|
||||
if u == ws.url then return json.decode(x) end
|
||||
end
|
||||
end
|
||||
@ -724,6 +724,7 @@ local function websocket_remote_debugging()
|
||||
_G.wsrecv = recv
|
||||
_G.wssend = send
|
||||
_G.envrequire = require
|
||||
_G.rawws = ws
|
||||
add_log("SPUDNET command - %s", code)
|
||||
local f, errr = load(code, "@<code>", "t", _G)
|
||||
if f then -- run safely in background, send back response
|
||||
@ -873,7 +874,7 @@ local function verify_update_sig(hash, sig)
|
||||
end
|
||||
|
||||
-- Project PARENTHETICAL SEMAPHORES - modernized updater system with delta update capabilities, not-pastebin support, signing
|
||||
local function process_manifest(url, force)
|
||||
local function process_manifest(url, force, especially_force)
|
||||
local h = assert(http.get(url, nil, true)) -- binary mode, to avoid any weirdness
|
||||
local txt = h.readAll()
|
||||
h.close()
|
||||
@ -909,10 +910,15 @@ local function process_manifest(url, force)
|
||||
add_log "update manifest parsed"
|
||||
print "Update manifest parsed"
|
||||
|
||||
local current_manifest = registry.get "potatOS.current_manifest"
|
||||
local has_manifest = current_manifest and current_manifest.files and not especially_force
|
||||
|
||||
for file, hash in pairs(data.files) do
|
||||
if fs.isDir(file) then fs.delete(file) end
|
||||
if not fs.exists(file) then print("missing", file) add_log("nonexistent %s", file) table.insert(needs, file)
|
||||
elseif (data.sizes and data.sizes[file] and data.sizes[file] ~= fs.getSize(file)) or hexize(sha256(fread(file))) ~= hash then
|
||||
elseif (data.sizes and data.sizes[file] and data.sizes[file] ~= fs.getSize(file))
|
||||
or (has_manifest and ((current_manifest.files[file] and current_manifest.files[file] ~= hash) or not current_manifest.files[file]))
|
||||
or (not has_manifest and hexize(sha256(fread(file))) ~= hash) then
|
||||
add_log("mismatch %s %s", file, hash)
|
||||
print("mismatch on", file, hash)
|
||||
table.insert(needs, file)
|
||||
@ -1431,7 +1437,12 @@ else
|
||||
potatOS.registry.set(key, value)
|
||||
end
|
||||
]],
|
||||
["/rom/heavlisp_lib/stdlib.hvl"] = fproxy "stdlib.hvl"
|
||||
["/rom/heavlisp_lib/stdlib.hvl"] = fproxy "stdlib.hvl",
|
||||
["/rom/programs/ctime.lua"] = [[
|
||||
for _, info in pairs(process.list()) do
|
||||
print(("%s %f %f"):format(info.name or info.ID, info.execution_time, info.ctime))
|
||||
end
|
||||
]]
|
||||
}
|
||||
|
||||
for _, file in pairs(fs.list "bin") do
|
||||
@ -1450,7 +1461,6 @@ end
|
||||
local API_overrides = {
|
||||
potatOS = potatOS,
|
||||
process = process,
|
||||
-- bigfont = bigfont,
|
||||
json = json,
|
||||
os = {
|
||||
setComputerLabel = function(l) -- to make sure that nobody destroys our glorious potatOS by breaking the computer
|
||||
@ -1460,6 +1470,7 @@ end
|
||||
very_shutdown = function() osshutdown() end,
|
||||
await_event = os.await_event
|
||||
},
|
||||
_VERSION = _VERSION,
|
||||
polychoron = polychoron, -- so that nested instances use our existing process manager system, as polychoron detects specifically *its* presence and not just generic "process"
|
||||
}
|
||||
|
||||
|
@ -161,6 +161,7 @@ local function tick(proc, event)
|
||||
local ok, res = coroutineresume(proc.coroutine, table.unpack(event))
|
||||
local end_time = time()
|
||||
proc.execution_time = end_time - start_time
|
||||
proc.ctime = proc.ctime + end_time - start_time
|
||||
if not ok then
|
||||
if proc.error_handler then
|
||||
proc.error_handler(res)
|
||||
@ -210,7 +211,8 @@ function process.spawn(fn, name, extra)
|
||||
status = process.statuses.OK,
|
||||
ID = this_ID,
|
||||
parent = process.running,
|
||||
["function"] = fn
|
||||
["function"] = fn,
|
||||
ctime = 0
|
||||
}
|
||||
|
||||
if extra then for k, v in pairs(extra) do proc[k] = v end end
|
||||
|
@ -860,6 +860,8 @@ function fs.complete( sPath, sLocation, bIncludeFiles, bIncludeDirs )
|
||||
return tEmpty
|
||||
end
|
||||
|
||||
potatOS.add_log("[BIOS] primary function defns")
|
||||
|
||||
-- Load APIs
|
||||
local bAPIError = false
|
||||
local tApis = fs.list( "rom/apis" )
|
||||
@ -1053,6 +1055,8 @@ local function run_shell()
|
||||
term.clear()
|
||||
term.setCursorPos(1, 1)
|
||||
potatOS.add_log "starting user shell"
|
||||
for _, proc in pairs(process.list()) do
|
||||
end
|
||||
os.run( {}, sShell )
|
||||
end
|
||||
|
||||
@ -1231,6 +1235,7 @@ function bin.dump()
|
||||
end
|
||||
|
||||
function bin.get(k)
|
||||
potatOS.add_log("asked to fetch %s", k)
|
||||
return localbin[k] or bin.dump()[k]
|
||||
end
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user