aboutsummaryrefslogtreecommitdiff
path: root/src/moonc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/moonc.cpp')
-rw-r--r--src/moonc.cpp155
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
16int main(int narg, const char** args) { 16int 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