aboutsummaryrefslogtreecommitdiff
path: root/src/MoonP/moonplus.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/MoonP/moonplus.cpp')
-rw-r--r--src/MoonP/moonplus.cpp129
1 files changed, 129 insertions, 0 deletions
diff --git a/src/MoonP/moonplus.cpp b/src/MoonP/moonplus.cpp
new file mode 100644
index 0000000..d6352f5
--- /dev/null
+++ b/src/MoonP/moonplus.cpp
@@ -0,0 +1,129 @@
1/* Copyright (c) 2020 Jin Li, http://www.luvfight.me
2
3Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
5The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
7THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
8#include "MoonP/moon_compiler.h"
9
10extern "C" {
11
12#include "lua.h"
13#include "lauxlib.h"
14
15static const char moonplusCodes[] =
16#include "MoonP/moonplus.h"
17
18static void init_moonplus(lua_State* L) {
19 if (luaL_loadbuffer(L, moonplusCodes, sizeof(moonplusCodes) / sizeof(moonplusCodes[0]) - 1, "=(moonplus)") != 0) {
20 std::string err = std::string("fail to load moonplus module.\n") + lua_tostring(L, -1);
21 luaL_error(L, err.c_str());
22 } else if (lua_pcall(L, 0, 0, 0) != 0) {
23 std::string err = std::string("fail to init moonplus module.\n") + lua_tostring(L, -1);
24 luaL_error(L, err.c_str());
25 }
26}
27
28static const char stpCodes[] =
29#include "MoonP/stacktraceplus.h"
30
31static int init_stacktraceplus(lua_State* L) {
32 if (luaL_loadbuffer(L, stpCodes, sizeof(stpCodes) / sizeof(stpCodes[0]) - 1, "=(stacktraceplus)") != 0) {
33 std::string err = std::string("fail to load stacktraceplus module.\n") + lua_tostring(L, -1);
34 luaL_error(L, err.c_str());
35 } else if (lua_pcall(L, 0, 1, 0) != 0) {
36 std::string err = std::string("fail to init stacktraceplus module.\n") + lua_tostring(L, -1);
37 luaL_error(L, err.c_str());
38 }
39 return 1;
40}
41
42static int moontolua(lua_State* L) {
43 size_t size = 0;
44 const char* input = luaL_checklstring(L, 1, &size);
45 MoonP::MoonConfig config;
46 bool sameModule = false;
47 if (lua_gettop(L) == 2) {
48 luaL_checktype(L, 2, LUA_TTABLE);
49 lua_pushliteral(L, "lint_global");
50 lua_gettable(L, -2);
51 if (lua_isboolean(L, -1) != 0) {
52 config.lintGlobalVariable = lua_toboolean(L, -1) != 0;
53 }
54 lua_pop(L, 1);
55 lua_pushliteral(L, "implicit_return_root");
56 lua_gettable(L, -2);
57 if (lua_isboolean(L, -1) != 0) {
58 config.implicitReturnRoot = lua_toboolean(L, -1) != 0;
59 }
60 lua_pop(L, 1);
61 lua_pushliteral(L, "reserve_line_number");
62 lua_gettable(L, -2);
63 if (lua_isboolean(L, -1) != 0) {
64 config.reserveLineNumber = lua_toboolean(L, -1) != 0;
65 }
66 lua_pop(L, 1);
67 lua_pushliteral(L, "same_module");
68 lua_gettable(L, -2);
69 if (lua_isboolean(L, -1) != 0) {
70 sameModule = lua_toboolean(L, -1) != 0;
71 }
72 lua_pop(L, 1);
73 lua_pushliteral(L, "line_offset");
74 lua_gettable(L, -2);
75 if (lua_isnumber(L, -1) != 0) {
76 config.lineOffset = static_cast<int>(lua_tonumber(L, -1));
77 }
78 lua_pop(L, 1);
79 }
80 std::string s(input, size);
81 std::string codes, err;
82 MoonP::GlobalVars globals;
83 std::tie(codes, err, globals) = MoonP::MoonCompiler(L, nullptr, sameModule).compile(s, config);
84 if (codes.empty() && !err.empty()) {
85 lua_pushnil(L);
86 } else {
87 lua_pushlstring(L, codes.c_str(), codes.size());
88 }
89 if (err.empty()) {
90 lua_pushnil(L);
91 } else {
92 lua_pushlstring(L, err.c_str(), err.size());
93 }
94 if (globals) {
95 lua_createtable(L, static_cast<int>(globals->size()), 0);
96 int i = 1;
97 for (const auto& var : *globals) {
98 lua_createtable(L, 3, 0);
99 lua_pushlstring(L, var.name.c_str(), var.name.size());
100 lua_rawseti(L, -2, 1);
101 lua_pushinteger(L, var.line);
102 lua_rawseti(L, -2, 2);
103 lua_pushinteger(L, var.col);
104 lua_rawseti(L, -2, 3);
105 lua_rawseti(L, -2, i);
106 i++;
107 }
108 } else {
109 lua_pushnil(L);
110 }
111 return 3;
112}
113
114int luaopen_moonp(lua_State* L) {
115 lua_getglobal(L, "package"); // package
116 lua_getfield(L, -1, "loaded"); // package loaded
117 lua_createtable(L, 0, 0); // package loaded moonp
118 lua_pushcfunction(L, moontolua); // package loaded moonp func
119 lua_setfield(L, -2, "to_lua"); // moonp["to_lua"] = func, package loaded tb
120 lua_pushcfunction(L, init_stacktraceplus); // package loaded moonp func1
121 lua_setfield(L, -2, "load_stacktraceplus"); // moonp["load_stacktraceplus"] = func1, package loaded moonp
122 lua_setfield(L, -2, "moonp"); // loaded["moonp"] = moonp, package loaded
123 lua_pop(L, 2); // empty
124 init_moonplus(L);
125 return 0;
126}
127
128} // extern "C"
129