diff options
| author | Li Jin <dragon-fly@qq.com> | 2020-03-11 00:21:33 +0800 |
|---|---|---|
| committer | Li Jin <dragon-fly@qq.com> | 2020-03-11 00:21:33 +0800 |
| commit | 1ee056eedf773ac6166247755439092e0e0a9bca (patch) | |
| tree | 1b8863338d37fe6ded7fbaecd92d76cdb3801ab3 /src/moonp.cpp | |
| parent | 015af4b70cd751e1c1580fd542997a796e1ca225 (diff) | |
| download | yuescript-1ee056eedf773ac6166247755439092e0e0a9bca.tar.gz yuescript-1ee056eedf773ac6166247755439092e0e0a9bca.tar.bz2 yuescript-1ee056eedf773ac6166247755439092e0e0a9bca.zip | |
add macro functions.
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 | |||
