diff options
Diffstat (limited to 'src/moonc.cpp')
| -rw-r--r-- | src/moonc.cpp | 155 |
1 files changed, 83 insertions, 72 deletions
diff --git a/src/moonc.cpp b/src/moonc.cpp index 4498bee..d04ce47 100644 --- a/src/moonc.cpp +++ b/src/moonc.cpp | |||
| @@ -9,9 +9,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI | |||
| 9 | #include <iomanip> | 9 | #include <iomanip> |
| 10 | #include <fstream> | 10 | #include <fstream> |
| 11 | #include <chrono> | 11 | #include <chrono> |
| 12 | #include <future> | ||
| 12 | #include "MoonP/moon_compiler.h" | 13 | #include "MoonP/moon_compiler.h" |
| 13 | #include "MoonP/parser.hpp" | 14 | #include "MoonP/moon_parser.h" |
| 14 | #include "MoonP/moon_ast.h" | ||
| 15 | 15 | ||
| 16 | int main(int narg, const char** args) { | 16 | int main(int narg, const char** args) { |
| 17 | const char* help = | 17 | const char* help = |
| @@ -82,87 +82,98 @@ int main(int narg, const char** args) { | |||
| 82 | std::cout << "Error: -o can not be used with multiple input files.\n"; | 82 | std::cout << "Error: -o can not be used with multiple input files.\n"; |
| 83 | std::cout << help; | 83 | std::cout << help; |
| 84 | } | 84 | } |
| 85 | if (targetPath.back() != '/' && targetPath.back() != '\\') { | ||
| 86 | targetPath.append("/"); | ||
| 87 | } | ||
| 88 | std::list<std::future<std::result_of_t<std::decay_t<int()>()>>> results; | ||
| 85 | for (const auto& file : files) { | 89 | for (const auto& file : files) { |
| 86 | std::ifstream input(file, input.in); | 90 | auto task = std::async(std::launch::async, [=]() { |
| 87 | if (input) { | 91 | std::ifstream input(file, input.in); |
| 88 | std::string s( | 92 | if (input) { |
| 89 | (std::istreambuf_iterator<char>(input)), | 93 | std::string s( |
| 90 | std::istreambuf_iterator<char>()); | 94 | (std::istreambuf_iterator<char>(input)), |
| 91 | if (dumpCompileTime) { | 95 | std::istreambuf_iterator<char>()); |
| 92 | auto start = std::chrono::high_resolution_clock::now(); | 96 | if (dumpCompileTime) { |
| 97 | auto start = std::chrono::high_resolution_clock::now(); | ||
| 98 | auto result = MoonP::moonCompile(s, config); | ||
| 99 | auto end = std::chrono::high_resolution_clock::now(); | ||
| 100 | if (!std::get<0>(result).empty()) { | ||
| 101 | std::chrono::duration<double> diff = end - start; | ||
| 102 | start = std::chrono::high_resolution_clock::now(); | ||
| 103 | MoonP::MoonParser{}.parse<MoonP::File_t>(s); | ||
| 104 | end = std::chrono::high_resolution_clock::now(); | ||
| 105 | std::chrono::duration<double> parseDiff = end - start; | ||
| 106 | std::cout << file << " \n"; | ||
| 107 | std::cout << "Parse time: " << std::setprecision(5) << parseDiff.count() * 1000 << " ms\n"; | ||
| 108 | std::cout << "Compile time: " << std::setprecision(5) << (diff.count() - parseDiff.count()) * 1000 << " ms\n\n"; | ||
| 109 | return 0; | ||
| 110 | } else { | ||
| 111 | std::cout << "Fail to compile: " << file << ".\n"; | ||
| 112 | std::cout << std::get<1>(result) << '\n'; | ||
| 113 | return 1; | ||
| 114 | } | ||
| 115 | } | ||
| 93 | auto result = MoonP::moonCompile(s, config); | 116 | auto result = MoonP::moonCompile(s, config); |
| 94 | auto end = std::chrono::high_resolution_clock::now(); | ||
| 95 | if (!std::get<0>(result).empty()) { | 117 | if (!std::get<0>(result).empty()) { |
| 96 | std::chrono::duration<double> diff = end - start; | 118 | if (!writeToFile) { |
| 97 | error_list el; | 119 | std::cout << std::get<0>(result) << '\n'; |
| 98 | MoonP::State st; | 120 | return 1; |
| 99 | start = std::chrono::high_resolution_clock::now(); | 121 | } else { |
| 100 | auto input = Converter{}.from_bytes(s); | 122 | std::string targetFile; |
| 101 | parserlib::parse<MoonP::File_t>(input, MoonP::File, el, &st); | 123 | if (resultFile.empty()) { |
| 102 | end = std::chrono::high_resolution_clock::now(); | 124 | std::string ext; |
| 103 | std::chrono::duration<double> parseDiff = end - start; | 125 | targetFile = file; |
| 104 | std::cout << file << " \n"; | 126 | size_t pos = file.rfind('.'); |
| 105 | std::cout << "Parse time: " << std::setprecision(5) << parseDiff.count() * 1000 << " ms\n"; | 127 | if (pos != std::string::npos) { |
| 106 | std::cout << "Compile time: " << std::setprecision(5) << (diff.count() - parseDiff.count()) * 1000 << " ms\n\n"; | 128 | ext = file.substr(pos + 1); |
| 107 | } else { | 129 | for (size_t i = 0; i < ext.length(); i++) { |
| 108 | std::cout << "Fail to compile: " << file << ".\n"; | 130 | ext[i] = static_cast<char>(tolower(ext[i])); |
| 109 | std::cout << std::get<1>(result) << '\n'; | 131 | } |
| 110 | return 1; | 132 | targetFile = file.substr(0, pos) + ".lua"; |
| 111 | } | ||
| 112 | continue; | ||
| 113 | } | ||
| 114 | auto result = MoonP::moonCompile(s, config); | ||
| 115 | if (!std::get<0>(result).empty()) { | ||
| 116 | if (!writeToFile) { | ||
| 117 | std::cout << std::get<0>(result) << '\n'; | ||
| 118 | } else { | ||
| 119 | std::string targetFile; | ||
| 120 | if (resultFile.empty()) { | ||
| 121 | std::string ext; | ||
| 122 | targetFile = file; | ||
| 123 | size_t pos = file.rfind('.'); | ||
| 124 | if (pos != std::string::npos) { | ||
| 125 | ext = file.substr(pos + 1); | ||
| 126 | for (size_t i = 0; i < ext.length(); i++) { | ||
| 127 | ext[i] = static_cast<char>(tolower(ext[i])); | ||
| 128 | } | ||
| 129 | targetFile = file.substr(0, pos) + ".lua"; | ||
| 130 | } | ||
| 131 | if (!targetPath.empty()) { | ||
| 132 | std::string name; | ||
| 133 | pos = targetFile.find_last_of("/\\"); | ||
| 134 | if (pos == std::string::npos) { | ||
| 135 | name = targetFile; | ||
| 136 | } else { | ||
| 137 | name = targetFile.substr(pos + 1); | ||
| 138 | } | 133 | } |
| 139 | if (targetPath.back() != '/' && targetPath.back() != '\\') { | 134 | if (!targetPath.empty()) { |
| 140 | targetPath.append("/"); | 135 | std::string name; |
| 136 | pos = targetFile.find_last_of("/\\"); | ||
| 137 | if (pos == std::string::npos) { | ||
| 138 | name = targetFile; | ||
| 139 | } else { | ||
| 140 | name = targetFile.substr(pos + 1); | ||
| 141 | } | ||
| 142 | targetFile = targetPath + name; | ||
| 141 | } | 143 | } |
| 142 | targetFile = targetPath + name; | 144 | } else { |
| 145 | targetFile = resultFile; | ||
| 146 | } | ||
| 147 | std::ofstream output(targetFile, output.trunc | output.out); | ||
| 148 | if (output) { | ||
| 149 | const auto& codes = std::get<0>(result); | ||
| 150 | output.write(codes.c_str(), codes.size()); | ||
| 151 | std::cout << "Built " << file << '\n'; | ||
| 152 | return 0; | ||
| 153 | } else { | ||
| 154 | std::cout << "Fail to write file: " << targetFile << ".\n"; | ||
| 155 | return 1; | ||
| 143 | } | 156 | } |
| 144 | } else { | ||
| 145 | targetFile = resultFile; | ||
| 146 | } | ||
| 147 | std::ofstream output(targetFile, output.trunc | output.out); | ||
| 148 | if (output) { | ||
| 149 | const auto& codes = std::get<0>(result); | ||
| 150 | output.write(codes.c_str(), codes.size()); | ||
| 151 | std::cout << "Built " << file << '\n'; | ||
| 152 | } else { | ||
| 153 | std::cout << "Fail to write file: " << targetFile << ".\n"; | ||
| 154 | return 1; | ||
| 155 | } | 157 | } |
| 158 | } else { | ||
| 159 | std::cout << "Fail to compile: " << file << ".\n"; | ||
| 160 | std::cout << std::get<1>(result) << '\n'; | ||
| 161 | return 1; | ||
| 156 | } | 162 | } |
| 157 | } else { | 163 | } else { |
| 158 | std::cout << "Fail to compile: " << file << ".\n"; | 164 | std::cout << "Fail to read file: " << file << ".\n"; |
| 159 | std::cout << std::get<1>(result) << '\n'; | ||
| 160 | return 1; | 165 | return 1; |
| 161 | } | 166 | } |
| 162 | } else { | 167 | }); |
| 163 | std::cout << "Fail to read file: " << file << ".\n"; | 168 | results.push_back(std::move(task)); |
| 164 | return 1; | 169 | } |
| 170 | int ret = 0; | ||
| 171 | for (auto& result : results) { | ||
| 172 | int val = result.get(); | ||
| 173 | if (val != 0) { | ||
| 174 | ret = val; | ||
| 165 | } | 175 | } |
| 166 | } | 176 | } |
| 167 | return 0; | 177 | return ret; |
| 168 | } | 178 | } |
| 179 | |||
