diff options
author | Li Jin <dragon-fly@qq.com> | 2020-03-26 14:12:43 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2020-03-26 14:12:43 +0800 |
commit | a97ca224f23b4101e44c099dbe29d1cc4a72c758 (patch) | |
tree | feaa385e12a5406666c7a816ea90b9d7ecf9ecf5 | |
parent | de47e975ff05a7fa3b9d066db9d500b090990f11 (diff) | |
download | yuescript-a97ca224f23b4101e44c099dbe29d1cc4a72c758.tar.gz yuescript-a97ca224f23b4101e44c099dbe29d1cc4a72c758.tar.bz2 yuescript-a97ca224f23b4101e44c099dbe29d1cc4a72c758.zip |
add REPL support for moonp.
-rw-r--r-- | MoonPlus.vcxproj | 4 | ||||
-rw-r--r-- | src/MoonP/moon_parser.cpp | 2 | ||||
-rw-r--r-- | src/moonp.cpp | 101 |
3 files changed, 102 insertions, 5 deletions
diff --git a/MoonPlus.vcxproj b/MoonPlus.vcxproj index d027aa0..11d5c85 100644 --- a/MoonPlus.vcxproj +++ b/MoonPlus.vcxproj | |||
@@ -97,6 +97,7 @@ | |||
97 | <ConformanceMode>true</ConformanceMode> | 97 | <ConformanceMode>true</ConformanceMode> |
98 | <LanguageStandard>stdcpplatest</LanguageStandard> | 98 | <LanguageStandard>stdcpplatest</LanguageStandard> |
99 | <AdditionalIncludeDirectories>.\src;.\src\lua-5.3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | 99 | <AdditionalIncludeDirectories>.\src;.\src\lua-5.3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> |
100 | <AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions> | ||
100 | </ClCompile> | 101 | </ClCompile> |
101 | <Link> | 102 | <Link> |
102 | <SubSystem>Console</SubSystem> | 103 | <SubSystem>Console</SubSystem> |
@@ -111,6 +112,7 @@ | |||
111 | <ConformanceMode>true</ConformanceMode> | 112 | <ConformanceMode>true</ConformanceMode> |
112 | <LanguageStandard>stdcpplatest</LanguageStandard> | 113 | <LanguageStandard>stdcpplatest</LanguageStandard> |
113 | <AdditionalIncludeDirectories>.\src;.\src\lua-5.3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | 114 | <AdditionalIncludeDirectories>.\src;.\src\lua-5.3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> |
115 | <AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions> | ||
114 | </ClCompile> | 116 | </ClCompile> |
115 | <Link> | 117 | <Link> |
116 | <SubSystem>Console</SubSystem> | 118 | <SubSystem>Console</SubSystem> |
@@ -127,6 +129,7 @@ | |||
127 | <ConformanceMode>true</ConformanceMode> | 129 | <ConformanceMode>true</ConformanceMode> |
128 | <LanguageStandard>stdcpplatest</LanguageStandard> | 130 | <LanguageStandard>stdcpplatest</LanguageStandard> |
129 | <AdditionalIncludeDirectories>.\src;.\src\lua-5.3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | 131 | <AdditionalIncludeDirectories>.\src;.\src\lua-5.3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> |
132 | <AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions> | ||
130 | </ClCompile> | 133 | </ClCompile> |
131 | <Link> | 134 | <Link> |
132 | <SubSystem>Console</SubSystem> | 135 | <SubSystem>Console</SubSystem> |
@@ -145,6 +148,7 @@ | |||
145 | <ConformanceMode>true</ConformanceMode> | 148 | <ConformanceMode>true</ConformanceMode> |
146 | <LanguageStandard>stdcpplatest</LanguageStandard> | 149 | <LanguageStandard>stdcpplatest</LanguageStandard> |
147 | <AdditionalIncludeDirectories>.\src;.\src\lua-5.3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | 150 | <AdditionalIncludeDirectories>.\src;.\src\lua-5.3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> |
151 | <AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions> | ||
148 | </ClCompile> | 152 | </ClCompile> |
149 | <Link> | 153 | <Link> |
150 | <SubSystem>Console</SubSystem> | 154 | <SubSystem>Console</SubSystem> |
diff --git a/src/MoonP/moon_parser.cpp b/src/MoonP/moon_parser.cpp index 872e30e..58f8fb3 100644 --- a/src/MoonP/moon_parser.cpp +++ b/src/MoonP/moon_parser.cpp | |||
@@ -646,7 +646,7 @@ std::string ParseInfo::errorMessage(std::string_view msg, const input_range* loc | |||
646 | int oldCol = loc->m_begin.m_col; | 646 | int oldCol = loc->m_begin.m_col; |
647 | int col = std::max(0, oldCol - 1); | 647 | int col = std::max(0, oldCol - 1); |
648 | auto it = begin; | 648 | auto it = begin; |
649 | for (int i = 0; i < oldCol; ++i) { | 649 | for (int i = 0; i < oldCol && it != end; ++i) { |
650 | if (*it > ASCII) { | 650 | if (*it > ASCII) { |
651 | ++col; | 651 | ++col; |
652 | } | 652 | } |
diff --git a/src/moonp.cpp b/src/moonp.cpp index fd9548a..d1c565f 100644 --- a/src/moonp.cpp +++ b/src/moonp.cpp | |||
@@ -11,6 +11,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI | |||
11 | 11 | ||
12 | #include <iostream> | 12 | #include <iostream> |
13 | #include <iomanip> | 13 | #include <iomanip> |
14 | #include <cstdlib> | ||
15 | #include <limits> | ||
14 | #include <fstream> | 16 | #include <fstream> |
15 | #include <chrono> | 17 | #include <chrono> |
16 | #include <future> | 18 | #include <future> |
@@ -49,6 +51,25 @@ void pushMoonp(lua_State* L, std::string_view name) { | |||
49 | lua_pop(L, 3); // item | 51 | lua_pop(L, 3); // item |
50 | } | 52 | } |
51 | 53 | ||
54 | void pushOptions(lua_State* L, int lineOffset) { | ||
55 | lua_newtable(L); | ||
56 | lua_pushliteral(L, "lint_global"); | ||
57 | lua_pushboolean(L, 0); | ||
58 | lua_rawset(L, -3); | ||
59 | lua_pushliteral(L, "implicit_return_root"); | ||
60 | lua_pushboolean(L, 1); | ||
61 | lua_rawset(L, -3); | ||
62 | lua_pushliteral(L, "reserve_line_number"); | ||
63 | lua_pushboolean(L, 1); | ||
64 | lua_rawset(L, -3); | ||
65 | lua_pushliteral(L, "same_module"); | ||
66 | lua_pushboolean(L, 1); | ||
67 | lua_rawset(L, -3); | ||
68 | lua_pushliteral(L, "line_offset"); | ||
69 | lua_pushinteger(L, lineOffset); | ||
70 | lua_rawset(L, -3); | ||
71 | } | ||
72 | |||
52 | int main(int narg, const char** args) { | 73 | int main(int narg, const char** args) { |
53 | const char* help = | 74 | const char* help = |
54 | "Usage: moonp [options|files|directories] ...\n\n" | 75 | "Usage: moonp [options|files|directories] ...\n\n" |
@@ -61,9 +82,76 @@ int main(int narg, const char** args) { | |||
61 | " -l Write line numbers from source codes\n" | 82 | " -l Write line numbers from source codes\n" |
62 | " -v Print version\n" | 83 | " -v Print version\n" |
63 | " -- Read from standard in, print to standard out\n" | 84 | " -- Read from standard in, print to standard out\n" |
64 | " (Must be first and only argument)\n"; | 85 | " (Must be first and only argument)\n\n" |
65 | if (narg == 0) { | 86 | " Execute without options to enter REPL, type symbol '$'\n" |
66 | std::cout << help; | 87 | " in a single line to start/stop multi-line mode\n"; |
88 | if (narg == 1) { | ||
89 | lua_State* L = luaL_newstate(); | ||
90 | openlibs(L); | ||
91 | DEFER(lua_close(L)); | ||
92 | pushMoonp(L, "insert_loader"sv); | ||
93 | if (lua_pcall(L, 0, 0, 0) != 0) { | ||
94 | std::cout << lua_tostring(L, -1) << '\n'; | ||
95 | return 1; | ||
96 | } | ||
97 | int count = 0; | ||
98 | while (!std::cin.fail()) { | ||
99 | count++; | ||
100 | std::cout << "moon> "sv; | ||
101 | std::string codes; | ||
102 | std::getline(std::cin, codes); | ||
103 | MoonP::Utils::trim(codes); | ||
104 | if (codes == "$"sv) { | ||
105 | codes.clear(); | ||
106 | for (std::string line; std::getline(std::cin, line);) { | ||
107 | auto temp = line; | ||
108 | MoonP::Utils::trim(temp); | ||
109 | if (temp == "$"sv) { | ||
110 | break; | ||
111 | } | ||
112 | codes += '\n'; | ||
113 | codes += line; | ||
114 | } | ||
115 | } | ||
116 | codes.insert(0, "global *\n"sv); | ||
117 | int top = lua_gettop(L); | ||
118 | DEFER(lua_settop(L, top)); | ||
119 | pushMoonp(L, "loadstring"sv); | ||
120 | lua_pushlstring(L, codes.c_str(), codes.size()); | ||
121 | lua_pushstring(L, (std::string("=(repl:") + std::to_string(count) + ')').c_str()); | ||
122 | pushOptions(L, -1); | ||
123 | const std::string_view Err = "\033[35m"sv, Val = "\033[33m"sv, Stop = "\033[0m\n"sv; | ||
124 | if (lua_pcall(L, 3, 2, 0) != 0) { | ||
125 | std::cout << Err << lua_tostring(L, -1) << Stop; | ||
126 | continue; | ||
127 | } | ||
128 | if (lua_isnil(L, -2) != 0) { | ||
129 | std::cout << Err << lua_tostring(L, -1) << Stop; | ||
130 | continue; | ||
131 | } | ||
132 | lua_pop(L, 1); | ||
133 | pushMoonp(L, "pcall"sv); | ||
134 | lua_insert(L, -2); | ||
135 | int last = lua_gettop(L) - 2; | ||
136 | if (lua_pcall(L, 1, LUA_MULTRET, 0) != 0) { | ||
137 | std::cout << Err << lua_tostring(L, -1) << Stop; | ||
138 | continue; | ||
139 | } | ||
140 | int cur = lua_gettop(L); | ||
141 | int retCount = cur - last; | ||
142 | bool success = lua_toboolean(L, -retCount) != 0; | ||
143 | if (success) { | ||
144 | if (retCount > 1) { | ||
145 | for (int i = 1; i < retCount; ++i) { | ||
146 | std::cout << Val << luaL_tolstring(L, -retCount + i, nullptr) << Stop; | ||
147 | lua_pop(L, 1); | ||
148 | } | ||
149 | } | ||
150 | } else { | ||
151 | std::cout << Err << lua_tostring(L, -1) << Stop; | ||
152 | } | ||
153 | } | ||
154 | std::cout << '\n'; | ||
67 | return 0; | 155 | return 0; |
68 | } | 156 | } |
69 | MoonP::MoonConfig config; | 157 | MoonP::MoonConfig config; |
@@ -129,10 +217,15 @@ int main(int narg, const char** args) { | |||
129 | lua_pushlstring(L, evalStr.c_str(), evalStr.size()); | 217 | lua_pushlstring(L, evalStr.c_str(), evalStr.size()); |
130 | lua_pushliteral(L, "=(eval str)"); | 218 | lua_pushliteral(L, "=(eval str)"); |
131 | } | 219 | } |
132 | if (lua_pcall(L, 2, 1, 0) != 0) { | 220 | if (lua_pcall(L, 2, 2, 0) != 0) { |
221 | std::cout << lua_tostring(L, -1) << '\n'; | ||
222 | return 1; | ||
223 | } | ||
224 | if (lua_isnil(L, -2) != 0) { | ||
133 | std::cout << lua_tostring(L, -1) << '\n'; | 225 | std::cout << lua_tostring(L, -1) << '\n'; |
134 | return 1; | 226 | return 1; |
135 | } | 227 | } |
228 | lua_pop(L, 1); | ||
136 | pushMoonp(L, "pcall"sv); | 229 | pushMoonp(L, "pcall"sv); |
137 | lua_insert(L, -2); | 230 | lua_insert(L, -2); |
138 | if (lua_pcall(L, 1, 2, 0) != 0) { | 231 | if (lua_pcall(L, 1, 2, 0) != 0) { |