aboutsummaryrefslogtreecommitdiff
path: root/src/moonp.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/moonp.cpp')
-rw-r--r--src/moonp.cpp76
1 files changed, 66 insertions, 10 deletions
diff --git a/src/moonp.cpp b/src/moonp.cpp
index 7410994..57c3d6d 100644
--- a/src/moonp.cpp
+++ b/src/moonp.cpp
@@ -74,6 +74,19 @@ void pushOptions(lua_State* L, int lineOffset) {
74 lua_rawset(L, -3); 74 lua_rawset(L, -3);
75} 75}
76 76
77static const char luaminifyCodes[] =
78#include "LuaMinify.h"
79
80static void pushLuaminify(lua_State* L) {
81 if (luaL_loadbuffer(L, luaminifyCodes, sizeof(luaminifyCodes) / sizeof(luaminifyCodes[0]) - 1, "=(luaminify)") != 0) {
82 std::string err = std::string("fail to load luaminify module.\n") + lua_tostring(L, -1);
83 luaL_error(L, err.c_str());
84 } else if (lua_pcall(L, 0, 1, 0) != 0) {
85 std::string err = std::string("fail to init luaminify module.\n") + lua_tostring(L, -1);
86 luaL_error(L, err.c_str());
87 }
88}
89
77int main(int narg, const char** args) { 90int main(int narg, const char** args) {
78 const char* help = 91 const char* help =
79"Usage: moonp [options|files|directories] ...\n\n" 92"Usage: moonp [options|files|directories] ...\n\n"
@@ -82,6 +95,7 @@ int main(int narg, const char** args) {
82" -t path Specify where to place compiled files\n" 95" -t path Specify where to place compiled files\n"
83" -o file Write output to file\n" 96" -o file Write output to file\n"
84" -s Use space in generated codes instead of tabs\n" 97" -s Use space in generated codes instead of tabs\n"
98" -m Generate minified codes\n"
85" -p Write output to standard out\n" 99" -p Write output to standard out\n"
86" -b Dump compile time (doesn't write output)\n" 100" -b Dump compile time (doesn't write output)\n"
87" -l Write line numbers from source codes\n" 101" -l Write line numbers from source codes\n"
@@ -230,6 +244,7 @@ int main(int narg, const char** args) {
230 config.useSpaceOverTab = false; 244 config.useSpaceOverTab = false;
231 bool writeToFile = true; 245 bool writeToFile = true;
232 bool dumpCompileTime = false; 246 bool dumpCompileTime = false;
247 bool minify = false;
233 std::string targetPath; 248 std::string targetPath;
234 std::string resultFile; 249 std::string resultFile;
235 std::list<std::pair<std::string,std::string>> files; 250 std::list<std::pair<std::string,std::string>> files;
@@ -321,6 +336,8 @@ int main(int narg, const char** args) {
321 config.reserveLineNumber = true; 336 config.reserveLineNumber = true;
322 } else if (arg == "-p"sv) { 337 } else if (arg == "-p"sv) {
323 writeToFile = false; 338 writeToFile = false;
339 } else if (arg == "-m"sv) {
340 minify = true;
324 } else if (arg == "-t"sv) { 341 } else if (arg == "-t"sv) {
325 ++i; 342 ++i;
326 if (i < narg) { 343 if (i < narg) {
@@ -369,7 +386,7 @@ int main(int narg, const char** args) {
369 std::cout << "Error: -o can not be used with multiple input files.\n"sv; 386 std::cout << "Error: -o can not be used with multiple input files.\n"sv;
370 std::cout << help; 387 std::cout << help;
371 } 388 }
372 std::list<std::future<std::pair<int,std::string>>> results; 389 std::list<std::future<std::tuple<int,std::string,std::string>>> results;
373 for (const auto& file : files) { 390 for (const auto& file : files) {
374 auto task = std::async(std::launch::async, [=]() { 391 auto task = std::async(std::launch::async, [=]() {
375 std::ifstream input(file.first, std::ios::in); 392 std::ifstream input(file.first, std::ios::in);
@@ -391,18 +408,18 @@ int main(int narg, const char** args) {
391 buf << file.first << " \n"sv; 408 buf << file.first << " \n"sv;
392 buf << "Parse time: "sv << std::setprecision(5) << parseDiff.count() * 1000 << " ms\n"; 409 buf << "Parse time: "sv << std::setprecision(5) << parseDiff.count() * 1000 << " ms\n";
393 buf << "Compile time: "sv << std::setprecision(5) << (diff.count() - parseDiff.count()) * 1000 << " ms\n\n"; 410 buf << "Compile time: "sv << std::setprecision(5) << (diff.count() - parseDiff.count()) * 1000 << " ms\n\n";
394 return std::pair{0, buf.str()}; 411 return std::tuple{0, file.first, buf.str()};
395 } else { 412 } else {
396 std::ostringstream buf; 413 std::ostringstream buf;
397 buf << "Fail to compile: "sv << file.first << ".\n"sv; 414 buf << "Fail to compile: "sv << file.first << ".\n"sv;
398 buf << std::get<1>(result) << '\n'; 415 buf << std::get<1>(result) << '\n';
399 return std::pair{1, buf.str()}; 416 return std::tuple{1, file.first, buf.str()};
400 } 417 }
401 } 418 }
402 auto result = MoonP::MoonCompiler{nullptr, openlibs}.compile(s, config); 419 auto result = MoonP::MoonCompiler{nullptr, openlibs}.compile(s, config);
403 if (!std::get<0>(result).empty()) { 420 if (!std::get<0>(result).empty()) {
404 if (!writeToFile) { 421 if (!writeToFile) {
405 return std::pair{1, std::get<0>(result) + '\n'}; 422 return std::tuple{1, file.first, std::get<0>(result) + '\n'};
406 } else { 423 } else {
407 fs::path targetFile; 424 fs::path targetFile;
408 if (!resultFile.empty()) { 425 if (!resultFile.empty()) {
@@ -426,34 +443,73 @@ int main(int narg, const char** args) {
426 output.write(head.c_str(), head.size()); 443 output.write(head.c_str(), head.size());
427 } 444 }
428 output.write(codes.c_str(), codes.size()); 445 output.write(codes.c_str(), codes.size());
429 return std::pair{0, std::string("Built "sv) + file.first + '\n'}; 446 return std::tuple{0, targetFile.string(), std::string("Built "sv) + file.first + '\n'};
430 } else { 447 } else {
431 return std::pair{1, std::string("Fail to write file: "sv) + targetFile.string() + '\n'}; 448 return std::tuple{1, std::string(), std::string("Fail to write file: "sv) + targetFile.string() + '\n'};
432 } 449 }
433 } 450 }
434 } else { 451 } else {
435 std::ostringstream buf; 452 std::ostringstream buf;
436 buf << "Fail to compile: "sv << file.first << ".\n"; 453 buf << "Fail to compile: "sv << file.first << ".\n";
437 buf << std::get<1>(result) << '\n'; 454 buf << std::get<1>(result) << '\n';
438 return std::pair{1, buf.str()}; 455 return std::tuple{1, std::string(), buf.str()};
439 } 456 }
440 } else { 457 } else {
441 return std::pair{1, std::string("Fail to read file: "sv) + file.first + ".\n"}; 458 return std::tuple{1, std::string(), std::string("Fail to read file: "sv) + file.first + ".\n"};
442 } 459 }
443 }); 460 });
444 results.push_back(std::move(task)); 461 results.push_back(std::move(task));
445 } 462 }
446 int ret = 0; 463 int ret = 0;
464 lua_State* L = nullptr;
465 DEFER({
466 if (L) lua_close(L);
467 });
468 if (minify) {
469 L = luaL_newstate();
470 luaL_openlibs(L);
471 pushLuaminify(L);
472 }
447 std::list<std::string> errs; 473 std::list<std::string> errs;
448 for (auto& result : results) { 474 for (auto& result : results) {
449 int val = 0; 475 int val = 0;
476 std::string file;
450 std::string msg; 477 std::string msg;
451 std::tie(val, msg) = result.get(); 478 std::tie(val, file, msg) = result.get();
452 if (val != 0) { 479 if (val != 0) {
453 ret = val; 480 ret = val;
454 errs.push_back(msg); 481 errs.push_back(msg);
455 } else { 482 } else {
456 std::cout << msg; 483 if (minify) {
484 std::ifstream input(file, std::ios::in);
485 if (input) {
486 std::string s(
487 (std::istreambuf_iterator<char>(input)),
488 std::istreambuf_iterator<char>());
489 input.close();
490 int top = lua_gettop(L);
491 DEFER(lua_settop(L, top));
492 lua_pushvalue(L, -1);
493 lua_pushlstring(L, s.c_str(), s.size());
494 if (lua_pcall(L, 1, 1, 0) != 0) {
495 ret = 2;
496 std::string err = lua_tostring(L, -1);
497 errs.push_back(std::string("Fail to minify: "sv) + file + '\n' + err + '\n');
498 } else {
499 size_t size = 0;
500 const char* minifiedCodes = lua_tolstring(L, -1, &size);
501 std::ofstream output(file, std::ios::trunc | std::ios::out);
502 output.write(minifiedCodes, size);
503 output.close();
504 std::cout << "Built Minified "sv << file << '\n';
505 }
506 } else {
507 ret = 2;
508 errs.push_back(std::string("Fail to minify: "sv) + file + '\n');
509 }
510 } else {
511 std::cout << msg;
512 }
457 } 513 }
458 } 514 }
459 for (const auto& err : errs) { 515 for (const auto& err : errs) {