uglify/squish.uglify.lua

changeset 62
15c48274ee1f
parent 56
791c9d8b750c
child 63
f42b3815ce77
equal deleted inserted replaced
61:b8af42b7ddf8 62:15c48274ee1f
45 45
46 local keyword_map_to_char = {} 46 local keyword_map_to_char = {}
47 for i, keyword in ipairs(keywords) do 47 for i, keyword in ipairs(keywords) do
48 keyword_map_to_char[keyword] = string.char(base_char + i); 48 keyword_map_to_char[keyword] = string.char(base_char + i);
49 end 49 end
50
51 -- Write loadstring and open string
52 local maxequals = 0;
53 data:gsub("(=+)", function (equals_string) maxequals = math.max(maxequals, #equals_string); end);
54
55 -- Go lexer!
56 llex.init(code, "@"..infile_fn);
57 llex.llex()
58 local seminfo = llex.seminfo;
59
60 if opts.uglify_level == "full" then
61 -- Find longest TK_NAME and TK_STRING tokens
62 local scores = {};
63 for k,v in ipairs(llex.tok) do
64 if v == "TK_NAME" or v == "TK_STRING" then
65 local key = string.format("%q,%q", v, seminfo[k]);
66 if not scores[key] then
67 scores[key] = { type = v, value = seminfo[k], count = 0 };
68 scores[#scores+1] = scores[key];
69 end
70 scores[key].count = scores[key].count + 1;
71 end
72 end
73 for i=1,#scores do
74 local v = scores[i];
75 v.score = (v.count)*(#v.value-1)- #string.format("%q", v.value) - 1;
76 end
77 table.sort(scores, function (a, b) return a.score > b.score; end);
78 local free_space = 255-(base_char+#keywords);
79 for i=free_space+1,#scores do
80 scores[i] = nil; -- Drop any over the limit
81 end
82
83 local base_keywords_len = #keywords;
84 for k,v in ipairs(scores) do
85 if v.score > 0 then
86 table.insert(keywords, v.value);
87 keyword_map_to_char[v.value] = string.char(base_char+base_keywords_len+k);
88 end
89 end
90 end
50 91
51 outfile:write("local base_char,keywords=", tostring(base_char), ",{"); 92 outfile:write("local base_char,keywords=", tostring(base_char), ",{");
52 for _, keyword in ipairs(keywords) do 93 for _, keyword in ipairs(keywords) do
53 outfile:write('"', keyword, '",'); 94 outfile:write(string.format("%q", keyword), ',');
54 end 95 end
55 outfile:write[[}; function prettify(code) return code:gsub("["..string.char(base_char).."-"..string.char(base_char+#keywords).."]", 96 outfile:write[[}; function prettify(code) return code:gsub("["..string.char(base_char).."-"..string.char(base_char+#keywords).."]",
56 function (c) return keywords[c:byte()-base_char]; end) end ]] 97 function (c) return keywords[c:byte()-base_char]; end) end ]]
57
58 -- Write loadstring and open string
59 local maxequals = 0;
60 data:gsub("(=+)", function (equals_string) maxequals = math.max(maxequals, #equals_string); end);
61 98
62 outfile:write [[return assert(loadstring(prettify]] 99 outfile:write [[return assert(loadstring(prettify]]
63 outfile:write("[", string.rep("=", maxequals+1), "["); 100 outfile:write("[", string.rep("=", maxequals+1), "[");
64 101
65 -- Write code, substituting tokens as we go 102 -- Write code, substituting tokens as we go
66 llex.init(code, "@"..infile_fn);
67 llex.llex()
68 local seminfo = llex.seminfo;
69 for k,v in ipairs(llex.tok) do 103 for k,v in ipairs(llex.tok) do
70 if v == "TK_KEYWORD" then 104 if v == "TK_KEYWORD" or v == "TK_NAME" or v == "TK_STRING" then
71 local keyword_char = keyword_map_to_char[seminfo[k]]; 105 local keyword_char = keyword_map_to_char[seminfo[k]];
72 if keyword_char then 106 if keyword_char then
73 outfile:write(keyword_char); 107 outfile:write(keyword_char);
74 else -- Those who think Lua shouldn't have 'continue, fix this please :) 108 else -- Those who think Lua shouldn't have 'continue, fix this please :)
75 outfile:write(seminfo[k]); 109 outfile:write(seminfo[k]);
89 if opts.uglify then 123 if opts.uglify then
90 print_info("Uglifying "..out_fn.."..."); 124 print_info("Uglifying "..out_fn.."...");
91 uglify_file(out_fn, out_fn); 125 uglify_file(out_fn, out_fn);
92 print_info("OK!"); 126 print_info("OK!");
93 end 127 end
94

mercurial