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 | |||