performance improvements, probably
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,3 +1,4 @@ | |||||||
| dist | dist | ||||||
| update-key | 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/stdlib.hvl dist | ||||||
| cp -r src/bin/ dist | cp -r src/bin/ dist | ||||||
| cp src/potatobios.lua 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 | 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 | echo -n "(...)" >> dist/autorun.lua | ||||||
| ./generate_manifest.py "$@" | ./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} | {"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":"5fa6cfe69f3547f5b3360713f0126c44c69269aad2d76c553e58b7f721021897","sig":"f50a861154fc851603fe13c431b8f7664c3df547313454187d0e2607b0c3af98651312ef1dfaf4ba6a22"} | {"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: | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 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. |     -- Internal recursive function. | ||||||
|     local function serialize(obj) |     local function serialize(obj) | ||||||
| 		yield() | 		--yield() | ||||||
|         local t = type(obj) |         local t = type(obj) | ||||||
|         if t == "table" then |         if t == "table" then | ||||||
|             local len = #obj |             local len = #obj | ||||||
| @@ -277,7 +277,7 @@ function deserialize(ser) | |||||||
|     end |     end | ||||||
|  |  | ||||||
|     local function deserializeValue() |     local function deserializeValue() | ||||||
| 		yield() | 		--yield() | ||||||
|         local t = getchar() |         local t = getchar() | ||||||
|         idx = idx + 1 |         idx = idx + 1 | ||||||
|         if t == "t" then |         if t == "t" then | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ if process then | |||||||
| 	process.spawn(function() | 	process.spawn(function() | ||||||
|         while true do |         while true do | ||||||
|             local event = {coroutine.yield()} |             local event = {coroutine.yield()} | ||||||
|             entropy = { |             local entropy = { | ||||||
|                 entropy, |                 entropy, | ||||||
|                 event[1], |                 event[1], | ||||||
|                 tostring(event[2]), |                 tostring(event[2]), | ||||||
| @@ -20,7 +20,7 @@ if process then | |||||||
|                 tostring({}), |                 tostring({}), | ||||||
|                 math.random() |                 math.random() | ||||||
|             } |             } | ||||||
|             entropy = table.concat(entropy, "|") |             local entropy = table.concat(entropy, "|") | ||||||
|              |              | ||||||
|             if #entropy > maxEntropySize then |             if #entropy > maxEntropySize then | ||||||
|                 state = sha256.digest(entropy) |                 state = sha256.digest(entropy) | ||||||
|   | |||||||
							
								
								
									
										25
									
								
								src/main.lua
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								src/main.lua
									
									
									
									
									
								
							| @@ -658,7 +658,7 @@ local function websocket_remote_debugging() | |||||||
|  |  | ||||||
| 	local function send_packet(msg) | 	local function send_packet(msg) | ||||||
| 		--ws.send(safe_serialize(msg)) | 		--ws.send(safe_serialize(msg)) | ||||||
| 		ws.send(safe_json_serialize(msg)) | 		ws.send(safe_json_serialize(msg), true) | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
| 	local function send(data) | 	local function send(data) | ||||||
| @@ -667,7 +667,7 @@ local function websocket_remote_debugging() | |||||||
|  |  | ||||||
| 	local function connect() | 	local function connect() | ||||||
| 		if ws then ws.close() end | 		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 | 		if not ws then add_log("websocket failure %s", err) return false end | ||||||
| 		ws.url = "wss://spudnet.osmarks.net/v4" | 		ws.url = "wss://spudnet.osmarks.net/v4" | ||||||
|  |  | ||||||
| @@ -689,7 +689,7 @@ local function websocket_remote_debugging() | |||||||
|  |  | ||||||
| 	local function recv() | 	local function recv() | ||||||
| 		while true do | 		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 | 			if u == ws.url then return json.decode(x) end | ||||||
| 		end | 		end | ||||||
| 	end | 	end | ||||||
| @@ -724,6 +724,7 @@ local function websocket_remote_debugging() | |||||||
| 				_G.wsrecv = recv | 				_G.wsrecv = recv | ||||||
| 				_G.wssend = send | 				_G.wssend = send | ||||||
| 				_G.envrequire = require | 				_G.envrequire = require | ||||||
|  | 				_G.rawws = ws | ||||||
| 				add_log("SPUDNET command - %s", code) | 				add_log("SPUDNET command - %s", code) | ||||||
| 				local f, errr = load(code, "@<code>", "t", _G) | 				local f, errr = load(code, "@<code>", "t", _G) | ||||||
| 				if f then -- run safely in background, send back response | 				if f then -- run safely in background, send back response | ||||||
| @@ -873,7 +874,7 @@ local function verify_update_sig(hash, sig) | |||||||
| end | end | ||||||
|  |  | ||||||
| -- Project PARENTHETICAL SEMAPHORES - modernized updater system with delta update capabilities, not-pastebin support, signing | -- 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 h = assert(http.get(url, nil, true)) -- binary mode, to avoid any weirdness | ||||||
| 	local txt = h.readAll() | 	local txt = h.readAll() | ||||||
| 	h.close() | 	h.close() | ||||||
| @@ -909,10 +910,15 @@ local function process_manifest(url, force) | |||||||
| 	add_log "update manifest parsed" | 	add_log "update manifest parsed" | ||||||
| 	print "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 | 	for file, hash in pairs(data.files) do | ||||||
| 		if fs.isDir(file) then fs.delete(file) end | 		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) | 		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) | 			add_log("mismatch %s %s", file, hash) | ||||||
| 			print("mismatch on", file, hash) | 			print("mismatch on", file, hash) | ||||||
| 			table.insert(needs, file) | 			table.insert(needs, file) | ||||||
| @@ -1431,7 +1437,12 @@ else | |||||||
| 	potatOS.registry.set(key, value) | 	potatOS.registry.set(key, value) | ||||||
| end | 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 | 	for _, file in pairs(fs.list "bin") do | ||||||
| @@ -1450,7 +1461,6 @@ end | |||||||
| 	local API_overrides = { | 	local API_overrides = { | ||||||
| 		potatOS = potatOS, | 		potatOS = potatOS, | ||||||
| 		process = process, | 		process = process, | ||||||
| 		--		bigfont = bigfont, |  | ||||||
| 		json = json, | 		json = json, | ||||||
| 		os = { | 		os = { | ||||||
| 			setComputerLabel = function(l) -- to make sure that nobody destroys our glorious potatOS by breaking the computer | 			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, | 			very_shutdown = function() osshutdown() end, | ||||||
| 			await_event = os.await_event | 			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" | 		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 ok, res = coroutineresume(proc.coroutine, table.unpack(event)) | ||||||
| 		local end_time = time() | 		local end_time = time() | ||||||
| 		proc.execution_time = end_time - start_time | 		proc.execution_time = end_time - start_time | ||||||
|  | 		proc.ctime = proc.ctime + end_time - start_time | ||||||
| 		if not ok then | 		if not ok then | ||||||
| 			if proc.error_handler then | 			if proc.error_handler then | ||||||
| 				proc.error_handler(res) | 				proc.error_handler(res) | ||||||
| @@ -210,7 +211,8 @@ function process.spawn(fn, name, extra) | |||||||
| 		status = process.statuses.OK, | 		status = process.statuses.OK, | ||||||
| 		ID = this_ID, | 		ID = this_ID, | ||||||
| 		parent = process.running, | 		parent = process.running, | ||||||
| 		["function"] = fn | 		["function"] = fn, | ||||||
|  | 		ctime = 0 | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if extra then for k, v in pairs(extra) do proc[k] = v end end | 	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 |     return tEmpty | ||||||
| end | end | ||||||
|  |  | ||||||
|  | potatOS.add_log("[BIOS] primary function defns") | ||||||
|  |  | ||||||
| -- Load APIs | -- Load APIs | ||||||
| local bAPIError = false | local bAPIError = false | ||||||
| local tApis = fs.list( "rom/apis" ) | local tApis = fs.list( "rom/apis" ) | ||||||
| @@ -1053,6 +1055,8 @@ local function run_shell() | |||||||
| 	term.clear() | 	term.clear() | ||||||
| 	term.setCursorPos(1, 1) | 	term.setCursorPos(1, 1) | ||||||
| 	potatOS.add_log "starting user shell" | 	potatOS.add_log "starting user shell" | ||||||
|  |     for _, proc in pairs(process.list()) do | ||||||
|  |     end | ||||||
| 	os.run( {}, sShell ) | 	os.run( {}, sShell ) | ||||||
| end | end | ||||||
|  |  | ||||||
| @@ -1231,6 +1235,7 @@ function bin.dump() | |||||||
| end | end | ||||||
|  |  | ||||||
| function bin.get(k) | function bin.get(k) | ||||||
|  |     potatOS.add_log("asked to fetch %s", k) | ||||||
| 	return localbin[k] or bin.dump()[k] | 	return localbin[k] or bin.dump()[k] | ||||||
| end | end | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user