diff options
Diffstat (limited to 'src/moonp.cpp')
-rw-r--r-- | src/moonp.cpp | 180 |
1 files changed, 40 insertions, 140 deletions
diff --git a/src/moonp.cpp b/src/moonp.cpp index a4bc1fa..a43f11c 100644 --- a/src/moonp.cpp +++ b/src/moonp.cpp | |||
@@ -10,10 +10,25 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI | |||
10 | #include <fstream> | 10 | #include <fstream> |
11 | #include <chrono> | 11 | #include <chrono> |
12 | #include <future> | 12 | #include <future> |
13 | #include <sstream> | ||
14 | #include <tuple> | ||
13 | #include "MoonP/moon_compiler.h" | 15 | #include "MoonP/moon_compiler.h" |
14 | #include "MoonP/moon_parser.h" | 16 | #include "MoonP/moon_parser.h" |
15 | 17 | ||
16 | #ifndef LIBMOONP | 18 | extern "C" { |
19 | |||
20 | #include "lua.h" | ||
21 | #include "lauxlib.h" | ||
22 | #include "lualib.h" | ||
23 | int luaopen_moonp(lua_State* L); | ||
24 | |||
25 | } // extern "C" | ||
26 | |||
27 | static void openlibs(void* state) { | ||
28 | lua_State* L = static_cast<lua_State*>(state); | ||
29 | luaL_openlibs(L); | ||
30 | luaopen_moonp(L); | ||
31 | } | ||
17 | 32 | ||
18 | int main(int narg, const char** args) { | 33 | int main(int narg, const char** args) { |
19 | const char* help = | 34 | const char* help = |
@@ -81,7 +96,7 @@ int main(int narg, const char** args) { | |||
81 | if (!targetPath.empty() && targetPath.back() != '/' && targetPath.back() != '\\') { | 96 | if (!targetPath.empty() && targetPath.back() != '/' && targetPath.back() != '\\') { |
82 | targetPath.append("/"); | 97 | targetPath.append("/"); |
83 | } | 98 | } |
84 | std::list<std::future<int>> results; | 99 | std::list<std::future<std::pair<int,std::string>>> results; |
85 | for (const auto& file : files) { | 100 | for (const auto& file : files) { |
86 | auto task = std::async(std::launch::async, [=]() { | 101 | auto task = std::async(std::launch::async, [=]() { |
87 | std::ifstream input(file, std::ios::in); | 102 | std::ifstream input(file, std::ios::in); |
@@ -91,7 +106,7 @@ int main(int narg, const char** args) { | |||
91 | std::istreambuf_iterator<char>()); | 106 | std::istreambuf_iterator<char>()); |
92 | if (dumpCompileTime) { | 107 | if (dumpCompileTime) { |
93 | auto start = std::chrono::high_resolution_clock::now(); | 108 | auto start = std::chrono::high_resolution_clock::now(); |
94 | auto result = MoonP::MoonCompiler{}.compile(s, config); | 109 | auto result = MoonP::MoonCompiler{nullptr,openlibs}.compile(s, config); |
95 | auto end = std::chrono::high_resolution_clock::now(); | 110 | auto end = std::chrono::high_resolution_clock::now(); |
96 | if (!std::get<0>(result).empty()) { | 111 | if (!std::get<0>(result).empty()) { |
97 | std::chrono::duration<double> diff = end - start; | 112 | std::chrono::duration<double> diff = end - start; |
@@ -99,21 +114,22 @@ int main(int narg, const char** args) { | |||
99 | MoonP::MoonParser{}.parse<MoonP::File_t>(s); | 114 | MoonP::MoonParser{}.parse<MoonP::File_t>(s); |
100 | end = std::chrono::high_resolution_clock::now(); | 115 | end = std::chrono::high_resolution_clock::now(); |
101 | std::chrono::duration<double> parseDiff = end - start; | 116 | std::chrono::duration<double> parseDiff = end - start; |
102 | std::cout << file << " \n"; | 117 | std::ostringstream buf; |
103 | std::cout << "Parse time: " << std::setprecision(5) << parseDiff.count() * 1000 << " ms\n"; | 118 | buf << file << " \n"; |
104 | std::cout << "Compile time: " << std::setprecision(5) << (diff.count() - parseDiff.count()) * 1000 << " ms\n\n"; | 119 | buf << "Parse time: " << std::setprecision(5) << parseDiff.count() * 1000 << " ms\n"; |
105 | return 0; | 120 | buf << "Compile time: " << std::setprecision(5) << (diff.count() - parseDiff.count()) * 1000 << " ms\n\n"; |
121 | return std::pair{0, buf.str()}; | ||
106 | } else { | 122 | } else { |
107 | std::cout << "Fail to compile: " << file << ".\n"; | 123 | std::ostringstream buf; |
108 | std::cout << std::get<1>(result) << '\n'; | 124 | buf << "Fail to compile: " << file << ".\n"; |
109 | return 1; | 125 | buf << std::get<1>(result) << '\n'; |
126 | return std::pair{1, buf.str()}; | ||
110 | } | 127 | } |
111 | } | 128 | } |
112 | auto result = MoonP::MoonCompiler{}.compile(s, config); | 129 | auto result = MoonP::MoonCompiler{nullptr,openlibs}.compile(s, config); |
113 | if (!std::get<0>(result).empty()) { | 130 | if (!std::get<0>(result).empty()) { |
114 | if (!writeToFile) { | 131 | if (!writeToFile) { |
115 | std::cout << std::get<0>(result) << '\n'; | 132 | return std::pair{1, std::get<0>(result) + '\n'}; |
116 | return 1; | ||
117 | } else { | 133 | } else { |
118 | std::string targetFile; | 134 | std::string targetFile; |
119 | if (resultFile.empty()) { | 135 | if (resultFile.empty()) { |
@@ -139,149 +155,33 @@ int main(int narg, const char** args) { | |||
139 | if (output) { | 155 | if (output) { |
140 | const auto& codes = std::get<0>(result); | 156 | const auto& codes = std::get<0>(result); |
141 | output.write(codes.c_str(), codes.size()); | 157 | output.write(codes.c_str(), codes.size()); |
142 | std::cout << "Built " << file << '\n'; | 158 | return std::pair{0, std::string("Built ") + file + '\n'}; |
143 | return 0; | ||
144 | } else { | 159 | } else { |
145 | std::cout << "Fail to write file: " << targetFile << ".\n"; | 160 | return std::pair{1, std::string("Fail to write file: ") + targetFile + '\n'}; |
146 | return 1; | ||
147 | } | 161 | } |
148 | } | 162 | } |
149 | } else { | 163 | } else { |
150 | std::cout << "Fail to compile: " << file << ".\n"; | 164 | std::ostringstream buf; |
151 | std::cout << std::get<1>(result) << '\n'; | 165 | buf << "Fail to compile: " << file << ".\n"; |
152 | return 1; | 166 | buf << std::get<1>(result) << '\n'; |
167 | return std::pair{1, buf.str()}; | ||
153 | } | 168 | } |
154 | } else { | 169 | } else { |
155 | std::cout << "Fail to read file: " << file << ".\n"; | 170 | return std::pair{1, std::string("Fail to read file: ") + file + ".\n"}; |
156 | return 1; | ||
157 | } | 171 | } |
158 | }); | 172 | }); |
159 | results.push_back(std::move(task)); | 173 | results.push_back(std::move(task)); |
160 | } | 174 | } |
161 | int ret = 0; | 175 | int ret = 0; |
176 | std::string msg; | ||
162 | for (auto& result : results) { | 177 | for (auto& result : results) { |
163 | int val = result.get(); | 178 | int val = 0; |
179 | std::tie(val, msg) = result.get(); | ||
164 | if (val != 0) { | 180 | if (val != 0) { |
165 | ret = val; | 181 | ret = val; |
166 | } | 182 | } |
183 | std::cout << msg; | ||
167 | } | 184 | } |
168 | return ret; | 185 | return ret; |
169 | } | 186 | } |
170 | 187 | ||
171 | #else | ||
172 | |||
173 | extern "C" { | ||
174 | |||
175 | #include "lua.h" | ||
176 | #include "lauxlib.h" | ||
177 | |||
178 | static const char moonplusCodes[] = | ||
179 | #include "Moonscript.h" | ||
180 | |||
181 | static int init_moonplus(lua_State* L) { | ||
182 | MoonP::MoonConfig config; | ||
183 | std::string s(moonplusCodes, sizeof(moonplusCodes) / sizeof(moonplusCodes[0]) - 1); | ||
184 | std::string codes, err; | ||
185 | MoonP::GlobalVars globals; | ||
186 | std::tie(codes, err, globals) = MoonP::MoonCompiler{}.compile(s, config); | ||
187 | if (codes.empty()) { | ||
188 | luaL_error(L, "fail to compile moonplus init codes.\n%s", err.c_str()); | ||
189 | } | ||
190 | int top = lua_gettop(L); | ||
191 | if (luaL_loadbuffer(L, codes.c_str(), codes.size(), "=(moonplus)") != 0) { | ||
192 | luaL_error(L, "fail to init moonplus module."); | ||
193 | } else { | ||
194 | lua_call(L, 0, 0); | ||
195 | } | ||
196 | lua_settop(L, top); | ||
197 | return 0; | ||
198 | } | ||
199 | |||
200 | static const char stpCodes[] = | ||
201 | #include "StackTracePlus.h" | ||
202 | |||
203 | static int init_stacktraceplus(lua_State* L) { | ||
204 | if (luaL_loadbuffer(L, stpCodes, sizeof(stpCodes) / sizeof(stpCodes[0]) - 1, "=(stacktraceplus)") != 0) { | ||
205 | luaL_error(L, "fail to init stacktraceplus module."); | ||
206 | } else { | ||
207 | lua_call(L, 0, 1); | ||
208 | } | ||
209 | return 1; | ||
210 | } | ||
211 | |||
212 | static int moontolua(lua_State* L) { | ||
213 | size_t size = 0; | ||
214 | const char* input = luaL_checklstring(L, 1, &size); | ||
215 | MoonP::MoonConfig config; | ||
216 | if (lua_gettop(L) == 2) { | ||
217 | lua_pushstring(L, "lint_global"); | ||
218 | lua_gettable(L, -2); | ||
219 | if (!lua_isnil(L, -1)) { | ||
220 | config.lintGlobalVariable = lua_toboolean(L, -1) != 0; | ||
221 | } | ||
222 | lua_pop(L, 1); | ||
223 | lua_pushstring(L, "implicit_return_root"); | ||
224 | lua_gettable(L, -2); | ||
225 | if (!lua_isnil(L, -1)) { | ||
226 | config.implicitReturnRoot = lua_toboolean(L, -1) != 0; | ||
227 | } | ||
228 | lua_pop(L, 1); | ||
229 | lua_pushstring(L, "reserve_line_number"); | ||
230 | lua_gettable(L, -2); | ||
231 | if (!lua_isnil(L, -1)) { | ||
232 | config.reserveLineNumber = lua_toboolean(L, -1) != 0; | ||
233 | } | ||
234 | lua_pop(L, 1); | ||
235 | } | ||
236 | std::string s(input, size); | ||
237 | std::string codes, err; | ||
238 | MoonP::GlobalVars globals; | ||
239 | std::tie(codes, err, globals) = MoonP::MoonCompiler{}.compile(s, config); | ||
240 | if (codes.empty()) { | ||
241 | lua_pushnil(L); | ||
242 | } else { | ||
243 | lua_pushlstring(L, codes.c_str(), codes.size()); | ||
244 | } | ||
245 | if (err.empty()) { | ||
246 | lua_pushnil(L); | ||
247 | } else { | ||
248 | lua_pushlstring(L, err.c_str(), err.size()); | ||
249 | } | ||
250 | if (globals) { | ||
251 | lua_createtable(L, static_cast<int>(globals->size()), 0); | ||
252 | int i = 1; | ||
253 | for (const auto& var : *globals) { | ||
254 | lua_createtable(L, 3, 0); | ||
255 | lua_pushlstring(L, var.name.c_str(), var.name.size()); | ||
256 | lua_rawseti(L, -2, 1); | ||
257 | lua_pushinteger(L, var.line); | ||
258 | lua_rawseti(L, -2, 2); | ||
259 | lua_pushinteger(L, var.col); | ||
260 | lua_rawseti(L, -2, 3); | ||
261 | lua_rawseti(L, -2, i); | ||
262 | i++; | ||
263 | } | ||
264 | } else { | ||
265 | lua_pushnil(L); | ||
266 | } | ||
267 | return 3; | ||
268 | } | ||
269 | |||
270 | int luaopen_moonp(lua_State* L) { | ||
271 | lua_getglobal(L, "package"); | ||
272 | lua_getfield(L, -1, "loaded"); | ||
273 | lua_createtable(L, 0, 0); | ||
274 | lua_pushcfunction(L, moontolua); | ||
275 | lua_setfield(L, -2, "to_lua"); | ||
276 | lua_pushcfunction(L, init_stacktraceplus); | ||
277 | lua_setfield(L, -2, "load_stacktraceplus"); | ||
278 | lua_setfield(L, -2, "moonp"); | ||
279 | lua_pop(L, 2); | ||
280 | init_moonplus(L); | ||
281 | return 0; | ||
282 | } | ||
283 | |||
284 | } // extern "C" | ||
285 | |||
286 | #endif // LIBMOONP | ||
287 | |||