aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/3rdParty/LuaMinify.h428
-rw-r--r--src/yue.cpp33
-rw-r--r--src/yuescript/yue_compiler.cpp4
3 files changed, 432 insertions, 33 deletions
diff --git a/src/3rdParty/LuaMinify.h b/src/3rdParty/LuaMinify.h
index d01a8fe..5512f5b 100644
--- a/src/3rdParty/LuaMinify.h
+++ b/src/3rdParty/LuaMinify.h
@@ -319,8 +319,6 @@ R"lua_codes(
319-- ParseLua returns an AST, internally relying on LexLua. 319-- ParseLua returns an AST, internally relying on LexLua.
320-- 320--
321 321
322local WhiteChars = lookupify{' ', '\n', '\t', '\r'}
323local EscapeLookup = {['\r'] = '\\r', ['\n'] = '\\n', ['\t'] = '\\t', ['"'] = '\\"', ["'"] = "\\'"}
324local LowerChars = lookupify{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 322local LowerChars = lookupify{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
325 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 323 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
326 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'} 324 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}
@@ -549,7 +547,7 @@ local function LexLua(src)
549 --get the initial char 547 --get the initial char
550 local thisLine = line 548 local thisLine = line
551 local thisChar = char 549 local thisChar = char
552 local errorAt = ":"..line..":"..char..":> " 550 --local errorAt = ":"..line..":"..char..":> "
553 local c = peek() 551 local c = peek()
554 552
555 --symbol to emit 553 --symbol to emit
@@ -822,9 +820,9 @@ local function ParseLua(src)
822 return err 820 return err
823 end 821 end
824 -- 822 --
825 local VarUid = 0 823 -- local VarUid = 0
826 -- No longer needed: handled in Scopes now local GlobalVarGetMap = {} 824 -- No longer needed: handled in Scopes now local GlobalVarGetMap = {}
827 local VarDigits = {'_', 'a', 'b', 'c', 'd'} 825 -- local VarDigits = {'_', 'a', 'b', 'c', 'd'}
828 local function CreateScope(parent) 826 local function CreateScope(parent)
829 --[[ 827 --[[
830 local scope = {} 828 local scope = {}
@@ -1736,15 +1734,6 @@ R"lua_codes(
1736-- - All local variables are renamed 1734-- - All local variables are renamed
1737-- 1735--
1738 1736
1739local LowerChars = lookupify{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
1740 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
1741 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}
1742local UpperChars = lookupify{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
1743 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
1744 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'}
1745local Digits = lookupify{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}
1746local Symbols = lookupify{'+', '-', '*', '/', '^', '%', ',', '{', '}', '[', ']', '(', ')', ';', '#'}
1747
1748local function Format_Mini(ast) 1737local function Format_Mini(ast)
1749 local formatStatlist, formatExpr; 1738 local formatStatlist, formatExpr;
1750 --local count = 0 1739 --local count = 0
@@ -2092,14 +2081,413 @@ local function Format_Mini(ast)
2092 ast.Scope:ObfuscateVariables() 2081 ast.Scope:ObfuscateVariables()
2093 return formatStatlist(ast) 2082 return formatStatlist(ast)
2094end 2083end
2084)lua_codes"
2095 2085
2096return function(src) 2086R"lua_codes(
2097 local st, ast = ParseLua(src) 2087local function FormatYue(ast, lineMap)
2098 if st then 2088 local currentLine = 1
2099 return Format_Mini(ast) 2089 local formatStatlist, formatExpr
2100 else 2090
2101 return nil, ast 2091 local function joinStatementsSafe(out, b, sep)
2092 local aa = ''
2093 for i = #out, 1, -1 do
2094 local a = out[i]
2095 aa = a:match("([^%s])%s*$")
2096 if aa then
2097 break
2098 end
2099 end
2100 sep = sep or ' '
2101 if (out[#out] or ''):sub(-1,-1) == ' ' then
2102 sep = ''
2103 end
2104 local bb = b:match("^%s*([^%s])")
2105 if UpperChars[aa] or LowerChars[aa] or aa == '_' then
2106 if not (UpperChars[bb] or LowerChars[bb] or bb == '_' or Digits[bb]) then
2107 --bb is a symbol, can join without sep
2108 out[#out + 1] = b
2109 elseif bb == '(' then
2110 --prevent ambiguous syntax
2111 out[#out + 1] = sep
2112 out[#out + 1] = b
2113 else
2114 out[#out + 1] = sep
2115 out[#out + 1] = b
2116 end
2117 elseif Digits[aa] then
2118 if bb == '(' then
2119 --can join statements directly
2120 out[#out + 1] = b
2121 elseif Symbols[bb] then
2122 out[#out + 1] = b
2123 else
2124 out[#out + 1] = sep
2125 out[#out + 1] = b
2126 end
2127 elseif aa == '' then
2128 out[#out + 1] = b
2129 else
2130 if bb == '(' then
2131 --don't want to accidentally call last statement, can't join directly
2132 out[#out + 1] = sep
2133 out[#out + 1] = b
2134 else
2135 out[#out + 1] = b
2136 end
2137 end
2102 end 2138 end
2139
2140 formatExpr = function(expr)
2141 local out = {string.rep('(', expr.ParenCount or 0)}
2142 if expr.Tokens then
2143 local line = expr.Tokens[1].Line
2144 local targetLine = lineMap[line]
2145 if targetLine and currentLine < targetLine then
2146 out[#out + 1] = string.rep('\n', targetLine - currentLine)
2147 currentLine = targetLine
2148 end
2149 elseif expr.Value then
2150 local line = expr.Value.Line
2151 local targetLine = lineMap[line]
2152 if targetLine and currentLine < targetLine then
2153 out[#out + 1] = string.rep('\n', targetLine - currentLine)
2154 currentLine = targetLine
2155 end
2156 end
2157 if expr.AstType == 'VarExpr' then
2158 if expr.Variable then
2159 out[#out + 1] = expr.Variable.Name
2160 else
2161 out[#out + 1] = expr.Name
2162 end
2163
2164 elseif expr.AstType == 'NumberExpr' then
2165 out[#out + 1] = expr.Value.Data
2166
2167 elseif expr.AstType == 'StringExpr' then
2168 out[#out + 1] = expr.Value.Data
2169
2170 elseif expr.AstType == 'BooleanExpr' then
2171 out[#out + 1] = tostring(expr.Value)
2172
2173 elseif expr.AstType == 'NilExpr' then
2174 joinStatementsSafe(out, "nil", nil)
2175
2176 elseif expr.AstType == 'BinopExpr' then
2177 joinStatementsSafe(out, formatExpr(expr.Lhs), nil)
2178 out[#out + 1] = " "
2179 joinStatementsSafe(out, expr.Op, nil)
2180 out[#out + 1] = " "
2181 joinStatementsSafe(out, formatExpr(expr.Rhs), nil)
2182
2183 elseif expr.AstType == 'UnopExpr' then
2184 joinStatementsSafe(out, expr.Op, nil)
2185 out[#out + 1] = (#expr.Op ~= 1 and " " or "")
2186 joinStatementsSafe(out, formatExpr(expr.Rhs), nil)
2187
2188 elseif expr.AstType == 'DotsExpr' then
2189 out[#out + 1] = "..."
2190
2191 elseif expr.AstType == 'CallExpr' then
2192 out[#out + 1] = formatExpr(expr.Base)
2193 out[#out + 1] = "("
2194 for i = 1, #expr.Arguments do
2195 out[#out + 1] = formatExpr(expr.Arguments[i])
2196 if i ~= #expr.Arguments then
2197 out[#out + 1] = ", "
2198 end
2199 end
2200 out[#out + 1] = ")"
2201
2202 elseif expr.AstType == 'TableCallExpr' then
2203 out[#out + 1] = formatExpr(expr.Base)
2204 out[#out + 1] = " "
2205 out[#out + 1] = formatExpr(expr.Arguments[1])
2206
2207 elseif expr.AstType == 'StringCallExpr' then
2208 out[#out + 1] = formatExpr(expr.Base)
2209 out[#out + 1] = " "
2210 out[#out + 1] = expr.Arguments[1].Data
2211
2212 elseif expr.AstType == 'IndexExpr' then
2213 out[#out + 1] = formatExpr(expr.Base)
2214 out[#out + 1] = "["
2215 out[#out + 1] = formatExpr(expr.Index)
2216 out[#out + 1] = "]"
2217
2218 elseif expr.AstType == 'MemberExpr' then
2219 out[#out + 1] = formatExpr(expr.Base)
2220 out[#out + 1] = expr.Indexer
2221 out[#out + 1] = expr.Ident.Data
2222
2223 elseif expr.AstType == 'Function' then
2224 -- anonymous function
2225 out[#out + 1] = "function("
2226 if #expr.Arguments > 0 then
2227 for i = 1, #expr.Arguments do
2228 out[#out + 1] = expr.Arguments[i].Name
2229 if i ~= #expr.Arguments then
2230 out[#out + 1] = ", "
2231 elseif expr.VarArg then
2232 out[#out + 1] = ", ..."
2233 end
2234 end
2235 elseif expr.VarArg then
2236 out[#out + 1] = "..."
2237 end
2238 out[#out + 1] = ")"
2239 joinStatementsSafe(out, formatStatlist(expr.Body), nil)
2240 joinStatementsSafe(out, "end", nil)
2241 elseif expr.AstType == 'ConstructorExpr' then
2242 out[#out + 1] = "{ "
2243 for i = 1, #expr.EntryList do
2244 local entry = expr.EntryList[i]
2245 if entry.Type == 'Key' then
2246 out[#out + 1] = "["
2247 out[#out + 1] = formatExpr(entry.Key)
2248 out[#out + 1] = "] = "
2249 out[#out + 1] = formatExpr(entry.Value)
2250 elseif entry.Type == 'Value' then
2251 out[#out + 1] = formatExpr(entry.Value)
2252 elseif entry.Type == 'KeyString' then
2253 out[#out + 1] = entry.Key
2254 out[#out + 1] = " = "
2255 out[#out + 1] = formatExpr(entry.Value)
2256 end
2257 if i ~= #expr.EntryList then
2258 out[#out + 1] = ", "
2259 end
2260 end
2261 out[#out + 1] = " }"
2262
2263 elseif expr.AstType == 'Parentheses' then
2264 out[#out + 1] = "("
2265 out[#out + 1] = formatExpr(expr.Inner)
2266 out[#out + 1] = ")"
2267
2268 end
2269 out[#out + 1] = string.rep(')', expr.ParenCount or 0)
2270 return table.concat(out)
2271 end
2272
2273 local formatStatement = function(statement)
2274 local out = {""}
2275 if statement.Tokens and statement.Tokens[1] then
2276 local line = statement.Tokens[1].Line
2277 local targetLine = lineMap[line]
2278 if targetLine and currentLine < targetLine then
2279 out[#out + 1] = string.rep('\n', targetLine - currentLine)
2280 currentLine = targetLine
2281 end
2282 end
2283 if statement.AstType == 'AssignmentStatement' then
2284 for i = 1, #statement.Lhs do
2285 out[#out + 1] = formatExpr(statement.Lhs[i])
2286 if i ~= #statement.Lhs then
2287 out[#out + 1] = ", "
2288 end
2289 end
2290 if #statement.Rhs > 0 then
2291 out[#out + 1] = " = "
2292 for i = 1, #statement.Rhs do
2293 out[#out + 1] = formatExpr(statement.Rhs[i])
2294 if i ~= #statement.Rhs then
2295 out[#out + 1] = ", "
2296 end
2297 end
2298 end
2299 elseif statement.AstType == 'CallStatement' then
2300 out[#out + 1] = formatExpr(statement.Expression)
2301 elseif statement.AstType == 'LocalStatement' then
2302 out[#out + 1] = "local "
2303 for i = 1, #statement.LocalList do
2304 out[#out + 1] = statement.LocalList[i].Name
2305 if statement.AttrList[i] then
2306 out[#out + 1] = " <"
2307 out[#out + 1] = statement.AttrList[i]
2308 out[#out + 1] = ">"
2309 end
2310 if i ~= #statement.LocalList then
2311 out[#out + 1] = ","
2312 end
2313 end
2314 if #statement.InitList > 0 then
2315 out[#out + 1] = " = "
2316 for i = 1, #statement.InitList do
2317 out[#out + 1] = formatExpr(statement.InitList[i])
2318 if i ~= #statement.InitList then
2319 out[#out + 1] = ", "
2320 end
2321 end
2322 end
2323 elseif statement.AstType == 'IfStatement' then
2324 out[#out + 1] = "if "
2325 joinStatementsSafe(out, formatExpr(statement.Clauses[1].Condition), nil)
2326 joinStatementsSafe(out, " then", nil)
2327 joinStatementsSafe(out, formatStatlist(statement.Clauses[1].Body), nil)
2328 for i = 2, #statement.Clauses do
2329 local st = statement.Clauses[i]
2330 if st.Condition then
2331 joinStatementsSafe(out, "elseif ", nil)
2332 joinStatementsSafe(out, formatExpr(st.Condition), nil)
2333 joinStatementsSafe(out, " then", nil)
2334 else
2335 joinStatementsSafe(out, "else", nil)
2336 end
2337 joinStatementsSafe(out, formatStatlist(st.Body), nil)
2338 end
2339 joinStatementsSafe(out, "end", nil)
2340 elseif statement.AstType == 'WhileStatement' then
2341 out[#out + 1] = "while "
2342 joinStatementsSafe(out, formatExpr(statement.Condition), nil)
2343 joinStatementsSafe(out, " do", nil)
2344 joinStatementsSafe(out, formatStatlist(statement.Body), nil)
2345 joinStatementsSafe(out, "end", nil)
2346 elseif statement.AstType == 'DoStatement' then
2347 joinStatementsSafe(out, "do", nil)
2348 joinStatementsSafe(out, formatStatlist(statement.Body), nil)
2349 joinStatementsSafe(out, "end", nil)
2350 elseif statement.AstType == 'ReturnStatement' then
2351 out[#out + 1] = "return "
2352 for i = 1, #statement.Arguments do
2353 joinStatementsSafe(out, formatExpr(statement.Arguments[i]), nil)
2354 if i ~= #statement.Arguments then
2355 out[#out + 1] = ", "
2356 end
2357 end
2358 elseif statement.AstType == 'BreakStatement' then
2359 out[#out + 1] = "break"
2360 elseif statement.AstType == 'RepeatStatement' then
2361 out[#out + 1] = "repeat"
2362 joinStatementsSafe(out, formatStatlist(statement.Body), nil)
2363 joinStatementsSafe(out, "until ", nil)
2364 joinStatementsSafe(out, formatExpr(statement.Condition), nil)
2365 elseif statement.AstType == 'Function' then
2366 if statement.IsLocal then
2367 out[#out + 1] = "local "
2368 end
2369 joinStatementsSafe(out, "function ", nil)
2370 if statement.IsLocal then
2371 out[#out + 1] = statement.Name.Name
2372 else
2373 out[#out + 1] = formatExpr(statement.Name)
2374 end
2375 out[#out + 1] = "("
2376 if #statement.Arguments > 0 then
2377 for i = 1, #statement.Arguments do
2378 out[#out + 1] = statement.Arguments[i].Name
2379 if i ~= #statement.Arguments then
2380 out[#out + 1] = ", "
2381 elseif statement.VarArg then
2382 out[#out + 1] = ",..."
2383 end
2384 end
2385 elseif statement.VarArg then
2386 out[#out + 1] = "..."
2387 end
2388 out[#out + 1] = ")"
2389 joinStatementsSafe(out, formatStatlist(statement.Body), nil)
2390 joinStatementsSafe(out, "end", nil)
2391 elseif statement.AstType == 'GenericForStatement' then
2392 out[#out + 1] = "for "
2393 for i = 1, #statement.VariableList do
2394 out[#out + 1] = statement.VariableList[i].Name
2395 if i ~= #statement.VariableList then
2396 out[#out + 1] = ", "
2397 end
2398 end
2399 out[#out + 1] = " in "
2400 for i = 1, #statement.Generators do
2401 joinStatementsSafe(out, formatExpr(statement.Generators[i]), nil)
2402 if i ~= #statement.Generators then
2403 joinStatementsSafe(out, ', ', nil)
2404 end
2405 end
2406 joinStatementsSafe(out, " do", nil)
2407 joinStatementsSafe(out, formatStatlist(statement.Body), nil)
2408 joinStatementsSafe(out, "end", nil)
2409 elseif statement.AstType == 'NumericForStatement' then
2410 out[#out + 1] = "for "
2411 out[#out + 1] = statement.Variable.Name
2412 out[#out + 1] = " = "
2413 out[#out + 1] = formatExpr(statement.Start)
2414 out[#out + 1] = ", "
2415 out[#out + 1] = formatExpr(statement.End)
2416 if statement.Step then
2417 out[#out + 1] = ", "
2418 out[#out + 1] = formatExpr(statement.Step)
2419 end
2420 joinStatementsSafe(out, " do", nil)
2421 joinStatementsSafe(out, formatStatlist(statement.Body), nil)
2422 joinStatementsSafe(out, "end", nil)
2423 elseif statement.AstType == 'LabelStatement' then
2424 out[#out + 1] = "::"
2425 out[#out + 1] = statement.Label
2426 out[#out + 1] = "::"
2427 elseif statement.AstType == 'GotoStatement' then
2428 out[#out + 1] = "goto "
2429 out[#out + 1] = statement.Label
2430 elseif statement.AstType == 'Comment' then
2431 -- Ignore
2432 elseif statement.AstType == 'Eof' then
2433 -- Ignore
2434 else
2435 print("Unknown AST Type: ", statement.AstType)
2436 end
2437 return table.concat(out)
2438 end
2439
2440 formatStatlist = function(statList)
2441 local out = {""}
2442 for _, stat in pairs(statList.Body) do
2443 joinStatementsSafe(out, formatStatement(stat), ';')
2444 end
2445 return table.concat(out)
2446 end
2447
2448 return formatStatlist(ast)
2449end
2450
2451local function GetYueLineMap(luaCodes)
2452 local current = 1
2453 local lastLine = 1
2454 local lineMap = { }
2455 for lineCode in luaCodes:gmatch("[^\n\r]*") do
2456 local num = lineCode:match("--%s*(%d+)%s*$")
2457 if num then
2458 local line = tonumber(num)
2459 if line > lastLine then
2460 lastLine = line
2461 end
2462 end
2463 lineMap[current] = lastLine
2464 current = current + 1
2465 end
2466 return lineMap
2103end 2467end
2468
2469return {
2470 FormatMini = function(src)
2471 local st, ast = ParseLua(src)
2472 if st then
2473 return Format_Mini(ast)
2474 else
2475 return nil, ast
2476 end
2477 end,
2478
2479 FormatYue = function(src)
2480 local st, ast = ParseLua(src)
2481 if st then
2482 local lineMap = GetYueLineMap(src)
2483 if #lineMap == 0 then
2484 return src
2485 end
2486 return FormatYue(ast, lineMap)
2487 else
2488 return nil, ast
2489 end
2490 end
2491}
2104)lua_codes"; 2492)lua_codes";
2105 2493
diff --git a/src/yue.cpp b/src/yue.cpp
index 98bf4b4..4dec0e4 100644
--- a/src/yue.cpp
+++ b/src/yue.cpp
@@ -246,6 +246,7 @@ int main(int narg, const char** args) {
246#ifndef YUE_COMPILER_ONLY 246#ifndef YUE_COMPILER_ONLY
247 " -e str Execute a file or raw codes\n" 247 " -e str Execute a file or raw codes\n"
248 " -m Generate minified codes\n" 248 " -m Generate minified codes\n"
249 " -r Rewrite output to match original line numbers\n"
249#endif // YUE_COMPILER_ONLY 250#endif // YUE_COMPILER_ONLY
250 " -t path Specify where to place compiled files\n" 251 " -t path Specify where to place compiled files\n"
251 " -o file Write output to file\n" 252 " -o file Write output to file\n"
@@ -409,6 +410,7 @@ int main(int narg, const char** args) {
409 return 0; 410 return 0;
410 } 411 }
411 bool minify = false; 412 bool minify = false;
413 bool rewrite = false;
412#endif // YUE_COMPILER_ONLY 414#endif // YUE_COMPILER_ONLY
413 yue::YueConfig config; 415 yue::YueConfig config;
414 config.implicitReturnRoot = true; 416 config.implicitReturnRoot = true;
@@ -522,6 +524,8 @@ int main(int narg, const char** args) {
522 } 524 }
523 } else if (arg == "-m"sv) { 525 } else if (arg == "-m"sv) {
524 minify = true; 526 minify = true;
527 } else if (arg == "-r"sv) {
528 rewrite = true;
525#endif // YUE_COMPILER_ONLY 529#endif // YUE_COMPILER_ONLY
526 } else if (arg == "-s"sv) { 530 } else if (arg == "-s"sv) {
527 config.useSpaceOverTab = true; 531 config.useSpaceOverTab = true;
@@ -607,6 +611,16 @@ int main(int narg, const char** args) {
607 std::cout << "Error: -o can not be used with multiple input files\n"sv; 611 std::cout << "Error: -o can not be used with multiple input files\n"sv;
608 return 1; 612 return 1;
609 } 613 }
614#ifndef YUE_COMPILER_ONLY
615 if (minify || rewrite) {
616 if (minify) {
617 rewrite = false;
618 }
619 if (rewrite) {
620 config.reserveLineNumber = true;
621 }
622 }
623#endif // YUE_COMPILER_ONLY
610#ifndef YUE_NO_WATCHER 624#ifndef YUE_NO_WATCHER
611 if (watchFiles) { 625 if (watchFiles) {
612 auto fullWorkPath = fs::absolute(fs::path(workPath)).string(); 626 auto fullWorkPath = fs::absolute(fs::path(workPath)).string();
@@ -744,7 +758,7 @@ int main(int narg, const char** args) {
744 DEFER({ 758 DEFER({
745 if (L) lua_close(L); 759 if (L) lua_close(L);
746 }); 760 });
747 if (minify) { 761 if (minify || rewrite) {
748 L = luaL_newstate(); 762 L = luaL_newstate();
749 luaL_openlibs(L); 763 luaL_openlibs(L);
750 pushLuaminify(L); 764 pushLuaminify(L);
@@ -766,7 +780,7 @@ int main(int narg, const char** args) {
766 errs.push_back(msg); 780 errs.push_back(msg);
767 } else { 781 } else {
768#ifndef YUE_COMPILER_ONLY 782#ifndef YUE_COMPILER_ONLY
769 if (minify) { 783 if (minify || rewrite) {
770 std::ifstream input(file, std::ios::in); 784 std::ifstream input(file, std::ios::in);
771 if (input) { 785 if (input) {
772 std::string s; 786 std::string s;
@@ -780,27 +794,24 @@ int main(int narg, const char** args) {
780 input.close(); 794 input.close();
781 int top = lua_gettop(L); 795 int top = lua_gettop(L);
782 DEFER(lua_settop(L, top)); 796 DEFER(lua_settop(L, top));
783 lua_pushvalue(L, -1); 797 lua_getfield(L, -1, rewrite ? "FormatYue" : "FormatMini");
784 lua_pushlstring(L, s.c_str(), s.size()); 798 lua_pushlstring(L, s.c_str(), s.size());
785 if (lua_pcall(L, 1, 1, 0) != 0) { 799 if (lua_pcall(L, 1, 1, 0) != 0) {
786 ret = 2; 800 ret = 2;
787 std::string err = lua_tostring(L, -1); 801 std::string err = lua_tostring(L, -1);
788 errs.push_back("Failed to minify: "s + file + '\n' + err + '\n'); 802 errs.push_back((rewrite ? "Failed to rewrite: "s : "Failed to minify: "s) + file + '\n' + err + '\n');
789 } else { 803 } else {
790 size_t size = 0; 804 size_t size = 0;
791 const char* minifiedCodes = lua_tolstring(L, -1, &size); 805 const char* transformedCodes = lua_tolstring(L, -1, &size);
792 if (writeToFile) { 806 if (writeToFile) {
793 std::ofstream output(file, std::ios::trunc | std::ios::out); 807 std::ofstream output(file, std::ios::trunc | std::ios::out);
794 output.write(minifiedCodes, size); 808 output.write(transformedCodes, size);
795 output.close(); 809 output.close();
796 std::cout << "Minified built "sv << file << '\n'; 810 std::cout << (rewrite ? "Rewrited built "sv : "Minified built "sv) << file << '\n';
797 } else { 811 } else {
798 std::cout << minifiedCodes << '\n'; 812 std::cout << transformedCodes << '\n';
799 } 813 }
800 } 814 }
801 } else {
802 ret = 2;
803 errs.push_back("Failed to minify: "s + file + '\n');
804 } 815 }
805 } else { 816 } else {
806 std::cout << msg; 817 std::cout << msg;
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp
index 09da047..2a3cb8c 100644
--- a/src/yuescript/yue_compiler.cpp
+++ b/src/yuescript/yue_compiler.cpp
@@ -72,7 +72,7 @@ static std::unordered_set<std::string> Metamethods = {
72 "close"s // Lua 5.4 72 "close"s // Lua 5.4
73}; 73};
74 74
75const std::string_view version = "0.17.8"sv; 75const std::string_view version = "0.17.9"sv;
76const std::string_view extension = "yue"sv; 76const std::string_view extension = "yue"sv;
77 77
78class CompileError : public std::logic_error { 78class CompileError : public std::logic_error {
@@ -435,7 +435,7 @@ private:
435 struct ClassMember { 435 struct ClassMember {
436 std::string item; 436 std::string item;
437 MemType type; 437 MemType type;
438 ast_node* node; 438 ast_ptr<true, ast_node> node;
439 }; 439 };
440 440
441 struct DestructItem { 441 struct DestructItem {