diff options
author | Li Jin <dragon-fly@qq.com> | 2022-08-19 18:05:31 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2022-08-19 18:05:31 +0800 |
commit | 2ef8f936224fe8506673561d033142aeddcc44c1 (patch) | |
tree | 274c816874b28cf363d3aec0ef7c9a9b1a630c02 | |
parent | a4d4893c77f9c48dedc88472a2e418bfd65e33a1 (diff) | |
download | yuescript-2ef8f936224fe8506673561d033142aeddcc44c1.tar.gz yuescript-2ef8f936224fe8506673561d033142aeddcc44c1.tar.bz2 yuescript-2ef8f936224fe8506673561d033142aeddcc44c1.zip |
fix format.
-rw-r--r-- | src/.clang-format | 17 | ||||
-rw-r--r-- | src/yue.cpp | 62 | ||||
-rw-r--r-- | src/yue_wasm.cpp | 12 | ||||
-rw-r--r-- | src/yuescript/ast.cpp | 24 | ||||
-rw-r--r-- | src/yuescript/ast.hpp | 138 | ||||
-rw-r--r-- | src/yuescript/parser.cpp | 701 | ||||
-rw-r--r-- | src/yuescript/parser.hpp | 140 | ||||
-rwxr-xr-x | src/yuescript/yue_ast.h | 28 | ||||
-rwxr-xr-x | src/yuescript/yue_compiler.cpp | 353 | ||||
-rw-r--r-- | src/yuescript/yue_compiler.h | 9 | ||||
-rwxr-xr-x | src/yuescript/yue_parser.cpp | 48 | ||||
-rwxr-xr-x | src/yuescript/yue_parser.h | 18 | ||||
-rw-r--r-- | src/yuescript/yuescript.cpp | 8 |
13 files changed, 737 insertions, 821 deletions
diff --git a/src/.clang-format b/src/.clang-format new file mode 100644 index 0000000..5d305ae --- /dev/null +++ b/src/.clang-format | |||
@@ -0,0 +1,17 @@ | |||
1 | # Format Style Options - Created with Clang Power Tools | ||
2 | --- | ||
3 | BasedOnStyle: WebKit | ||
4 | AllowShortCaseLabelsOnASingleLine: true | ||
5 | AllowShortIfStatementsOnASingleLine: WithoutElse | ||
6 | AllowShortLoopsOnASingleLine: true | ||
7 | BreakBeforeBraces: Attach | ||
8 | Cpp11BracedListStyle: true | ||
9 | IndentCaseLabels: true | ||
10 | NamespaceIndentation: None | ||
11 | SpaceBeforeCpp11BracedList: false | ||
12 | TabWidth: 4 | ||
13 | AlignEscapedNewlines: DontAlign | ||
14 | AlwaysBreakBeforeMultilineStrings: true | ||
15 | FixNamespaceComments: true | ||
16 | UseTab: Always | ||
17 | ... | ||
diff --git a/src/yue.cpp b/src/yue.cpp index 6011d94..07d0fef 100644 --- a/src/yue.cpp +++ b/src/yue.cpp | |||
@@ -9,28 +9,28 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI | |||
9 | #include "yuescript/yue_compiler.h" | 9 | #include "yuescript/yue_compiler.h" |
10 | #include "yuescript/yue_parser.h" | 10 | #include "yuescript/yue_parser.h" |
11 | 11 | ||
12 | #include <iostream> | 12 | #include <chrono> |
13 | #include <iomanip> | ||
14 | #include <cstdlib> | 13 | #include <cstdlib> |
15 | #include <limits> | ||
16 | #include <fstream> | 14 | #include <fstream> |
17 | #include <chrono> | ||
18 | #include <future> | 15 | #include <future> |
16 | #include <iomanip> | ||
17 | #include <iostream> | ||
18 | #include <limits> | ||
19 | #include <memory> | ||
19 | #include <sstream> | 20 | #include <sstream> |
20 | #include <tuple> | ||
21 | #include <string_view> | 21 | #include <string_view> |
22 | #include <memory> | 22 | #include <tuple> |
23 | using namespace std::string_view_literals; | 23 | using namespace std::string_view_literals; |
24 | using namespace std::string_literals; | 24 | using namespace std::string_literals; |
25 | #include "ghc/fs_std.hpp" | 25 | #include "ghc/fs_std.hpp" |
26 | #include "linenoise.hpp" | 26 | #include "linenoise.hpp" |
27 | 27 | ||
28 | #if not (defined YUE_NO_MACRO && defined YUE_COMPILER_ONLY) | 28 | #if not(defined YUE_NO_MACRO && defined YUE_COMPILER_ONLY) |
29 | #define _DEFER(code,line) std::shared_ptr<void> _defer_##line(nullptr, [&](auto){code;}) | 29 | #define _DEFER(code, line) std::shared_ptr<void> _defer_##line(nullptr, [&](auto) { code; }) |
30 | #define DEFER(code) _DEFER(code,__LINE__) | 30 | #define DEFER(code) _DEFER(code, __LINE__) |
31 | extern "C" { | 31 | extern "C" { |
32 | #include "lua.h" | ||
33 | #include "lauxlib.h" | 32 | #include "lauxlib.h" |
33 | #include "lua.h" | ||
34 | #include "lualib.h" | 34 | #include "lualib.h" |
35 | int luaopen_yue(lua_State* L); | 35 | int luaopen_yue(lua_State* L); |
36 | } // extern "C" | 36 | } // extern "C" |
@@ -81,7 +81,7 @@ void pushOptions(lua_State* L, int lineOffset) { | |||
81 | #endif // not (defined YUE_NO_MACRO && defined YUE_COMPILER_ONLY) | 81 | #endif // not (defined YUE_NO_MACRO && defined YUE_COMPILER_ONLY) |
82 | 82 | ||
83 | #ifndef YUE_NO_MACRO | 83 | #ifndef YUE_NO_MACRO |
84 | #define YUE_ARGS nullptr,openlibs | 84 | #define YUE_ARGS nullptr, openlibs |
85 | #else | 85 | #else |
86 | #define YUE_ARGS | 86 | #define YUE_ARGS |
87 | #endif // YUE_NO_MACRO | 87 | #endif // YUE_NO_MACRO |
@@ -90,7 +90,7 @@ void pushOptions(lua_State* L, int lineOffset) { | |||
90 | static const char luaminifyCodes[] = | 90 | static const char luaminifyCodes[] = |
91 | #include "LuaMinify.h" | 91 | #include "LuaMinify.h" |
92 | 92 | ||
93 | static void pushLuaminify(lua_State* L) { | 93 | static void pushLuaminify(lua_State * L) { |
94 | if (luaL_loadbuffer(L, luaminifyCodes, sizeof(luaminifyCodes) / sizeof(luaminifyCodes[0]) - 1, "=(luaminify)") != 0) { | 94 | if (luaL_loadbuffer(L, luaminifyCodes, sizeof(luaminifyCodes) / sizeof(luaminifyCodes[0]) - 1, "=(luaminify)") != 0) { |
95 | std::string err = "failed to load luaminify module.\n"s + lua_tostring(L, -1); | 95 | std::string err = "failed to load luaminify module.\n"s + lua_tostring(L, -1); |
96 | luaL_error(L, err.c_str()); | 96 | luaL_error(L, err.c_str()); |
@@ -103,27 +103,27 @@ static void pushLuaminify(lua_State* L) { | |||
103 | 103 | ||
104 | int main(int narg, const char** args) { | 104 | int main(int narg, const char** args) { |
105 | const char* help = | 105 | const char* help = |
106 | "Usage: yue [options|files|directories] ...\n\n" | 106 | "Usage: yue [options|files|directories] ...\n\n" |
107 | " -h Print this message\n" | 107 | " -h Print this message\n" |
108 | #ifndef YUE_COMPILER_ONLY | 108 | #ifndef YUE_COMPILER_ONLY |
109 | " -e str Execute a file or raw codes\n" | 109 | " -e str Execute a file or raw codes\n" |
110 | " -m Generate minified codes\n" | 110 | " -m Generate minified codes\n" |
111 | #endif // YUE_COMPILER_ONLY | 111 | #endif // YUE_COMPILER_ONLY |
112 | " -t path Specify where to place compiled files\n" | 112 | " -t path Specify where to place compiled files\n" |
113 | " -o file Write output to file\n" | 113 | " -o file Write output to file\n" |
114 | " -s Use spaces in generated codes instead of tabs\n" | 114 | " -s Use spaces in generated codes instead of tabs\n" |
115 | " -p Write output to standard out\n" | 115 | " -p Write output to standard out\n" |
116 | " -b Dump compile time (doesn't write output)\n" | 116 | " -b Dump compile time (doesn't write output)\n" |
117 | " -g Dump global variables used in NAME LINE COLUMN\n" | 117 | " -g Dump global variables used in NAME LINE COLUMN\n" |
118 | " -l Write line numbers from source codes\n" | 118 | " -l Write line numbers from source codes\n" |
119 | " -v Print version\n" | 119 | " -v Print version\n" |
120 | #ifndef YUE_COMPILER_ONLY | 120 | #ifndef YUE_COMPILER_ONLY |
121 | " -- Read from standard in, print to standard out\n" | 121 | " -- Read from standard in, print to standard out\n" |
122 | " (Must be first and only argument)\n\n" | 122 | " (Must be first and only argument)\n\n" |
123 | " Execute without options to enter REPL, type symbol '$'\n" | 123 | " Execute without options to enter REPL, type symbol '$'\n" |
124 | " in a single line to start/stop multi-line mode\n" | 124 | " in a single line to start/stop multi-line mode\n" |
125 | #endif // YUE_COMPILER_ONLY | 125 | #endif // YUE_COMPILER_ONLY |
126 | ; | 126 | ; |
127 | #ifndef YUE_COMPILER_ONLY | 127 | #ifndef YUE_COMPILER_ONLY |
128 | if (narg == 1) { | 128 | if (narg == 1) { |
129 | lua_State* L = luaL_newstate(); | 129 | lua_State* L = luaL_newstate(); |
@@ -276,7 +276,7 @@ int main(int narg, const char** args) { | |||
276 | std::string targetPath; | 276 | std::string targetPath; |
277 | std::string resultFile; | 277 | std::string resultFile; |
278 | std::string workPath; | 278 | std::string workPath; |
279 | std::list<std::pair<std::string,std::string>> files; | 279 | std::list<std::pair<std::string, std::string>> files; |
280 | for (int i = 1; i < narg; ++i) { | 280 | for (int i = 1; i < narg; ++i) { |
281 | std::string arg = args[i]; | 281 | std::string arg = args[i]; |
282 | if (arg == "--"sv) { | 282 | if (arg == "--"sv) { |
@@ -449,7 +449,7 @@ int main(int narg, const char** args) { | |||
449 | std::cout << "Error: -o can not be used with multiple input files\n"sv; | 449 | std::cout << "Error: -o can not be used with multiple input files\n"sv; |
450 | std::cout << help; | 450 | std::cout << help; |
451 | } | 451 | } |
452 | std::list<std::future<std::tuple<int,std::string,std::string>>> results; | 452 | std::list<std::future<std::tuple<int, std::string, std::string>>> results; |
453 | for (const auto& file : files) { | 453 | for (const auto& file : files) { |
454 | auto task = std::async(std::launch::async, [=]() { | 454 | auto task = std::async(std::launch::async, [=]() { |
455 | std::ifstream input(file.first, std::ios::in); | 455 | std::ifstream input(file.first, std::ios::in); |
diff --git a/src/yue_wasm.cpp b/src/yue_wasm.cpp index 8c93eb1..395388b 100644 --- a/src/yue_wasm.cpp +++ b/src/yue_wasm.cpp | |||
@@ -9,8 +9,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI | |||
9 | #include "yuescript/yue_compiler.h" | 9 | #include "yuescript/yue_compiler.h" |
10 | 10 | ||
11 | extern "C" { | 11 | extern "C" { |
12 | #include "lua.h" | ||
13 | #include "lauxlib.h" | 12 | #include "lauxlib.h" |
13 | #include "lua.h" | ||
14 | #include "lualib.h" | 14 | #include "lualib.h" |
15 | int luaopen_yue(lua_State* L); | 15 | int luaopen_yue(lua_State* L); |
16 | } // extern "C" | 16 | } // extern "C" |
@@ -23,15 +23,14 @@ static void openlibs(void* state) { | |||
23 | lua_pop(L, 1); | 23 | lua_pop(L, 1); |
24 | } | 24 | } |
25 | 25 | ||
26 | #define YUE_ARGS nullptr,openlibs | 26 | #define YUE_ARGS nullptr, openlibs |
27 | 27 | ||
28 | #include <string_view> | 28 | #include <string_view> |
29 | using namespace std::string_view_literals; | 29 | using namespace std::string_view_literals; |
30 | #include <emscripten/bind.h> | 30 | #include <emscripten/bind.h> |
31 | using namespace emscripten; | 31 | using namespace emscripten; |
32 | 32 | ||
33 | struct YueResult | 33 | struct YueResult { |
34 | { | ||
35 | std::string codes; | 34 | std::string codes; |
36 | std::string err; | 35 | std::string err; |
37 | }; | 36 | }; |
@@ -47,8 +46,8 @@ YueResult tolua(const std::string& codes, bool reserveLineNumber = true, bool im | |||
47 | 46 | ||
48 | std::string version() { return std::string(yue::version); } | 47 | std::string version() { return std::string(yue::version); } |
49 | 48 | ||
50 | #define _DEFER(code,line) std::shared_ptr<void> _defer_##line(nullptr, [&](auto){code;}) | 49 | #define _DEFER(code, line) std::shared_ptr<void> _defer_##line(nullptr, [&](auto) { code; }) |
51 | #define DEFER(code) _DEFER(code,__LINE__) | 50 | #define DEFER(code) _DEFER(code, __LINE__) |
52 | 51 | ||
53 | void pushYue(lua_State* L, std::string_view name) { | 52 | void pushYue(lua_State* L, std::string_view name) { |
54 | lua_getglobal(L, "package"); // package | 53 | lua_getglobal(L, "package"); // package |
@@ -167,4 +166,3 @@ EMSCRIPTEN_BINDINGS(yue) { | |||
167 | function("exec", &exec); | 166 | function("exec", &exec); |
168 | function("version", &version); | 167 | function("version", &version); |
169 | } | 168 | } |
170 | |||
diff --git a/src/yuescript/ast.cpp b/src/yuescript/ast.cpp index 3deefb1..239aec6 100644 --- a/src/yuescript/ast.cpp +++ b/src/yuescript/ast.cpp | |||
@@ -13,11 +13,9 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |||
13 | 13 | ||
14 | #include "yuescript/ast.hpp" | 14 | #include "yuescript/ast.hpp" |
15 | 15 | ||
16 | |||
17 | namespace parserlib { | 16 | namespace parserlib { |
18 | 17 | ||
19 | 18 | traversal ast_node::traverse(const std::function<traversal(ast_node*)>& func) { | |
20 | traversal ast_node::traverse(const std::function<traversal (ast_node*)>& func) { | ||
21 | return func(this); | 19 | return func(this); |
22 | } | 20 | } |
23 | 21 | ||
@@ -45,27 +43,25 @@ ast_node* ast_node::getByTypeIds(int* begin, int* end) { | |||
45 | return current; | 43 | return current; |
46 | } | 44 | } |
47 | 45 | ||
48 | bool ast_node::visitChild(const std::function<bool (ast_node*)>&) { | 46 | bool ast_node::visitChild(const std::function<bool(ast_node*)>&) { |
49 | return false; | 47 | return false; |
50 | } | 48 | } |
51 | 49 | ||
52 | |||
53 | /** Asks all members to construct themselves from the stack. | 50 | /** Asks all members to construct themselves from the stack. |
54 | The members are asked to construct themselves in reverse order. | 51 | The members are asked to construct themselves in reverse order. |
55 | from a node stack. | 52 | from a node stack. |
56 | @param st stack. | 53 | @param st stack. |
57 | */ | 54 | */ |
58 | void ast_container::construct(ast_stack &st) { | 55 | void ast_container::construct(ast_stack& st) { |
59 | for(ast_member_vector::reverse_iterator it = m_members.rbegin(); | 56 | for (ast_member_vector::reverse_iterator it = m_members.rbegin(); |
60 | it != m_members.rend(); | 57 | it != m_members.rend(); |
61 | ++it) | 58 | ++it) { |
62 | { | ||
63 | ast_member* member = *it; | 59 | ast_member* member = *it; |
64 | member->construct(st); | 60 | member->construct(st); |
65 | } | 61 | } |
66 | } | 62 | } |
67 | 63 | ||
68 | traversal ast_container::traverse(const std::function<traversal (ast_node*)>& func) { | 64 | traversal ast_container::traverse(const std::function<traversal(ast_node*)>& func) { |
69 | traversal action = func(this); | 65 | traversal action = func(this); |
70 | switch (action) { | 66 | switch (action) { |
71 | case traversal::Stop: return traversal::Stop; | 67 | case traversal::Stop: return traversal::Stop; |
@@ -96,7 +92,7 @@ traversal ast_container::traverse(const std::function<traversal (ast_node*)>& fu | |||
96 | return traversal::Continue; | 92 | return traversal::Continue; |
97 | } | 93 | } |
98 | 94 | ||
99 | bool ast_container::visitChild(const std::function<bool (ast_node*)>& func) { | 95 | bool ast_container::visitChild(const std::function<bool(ast_node*)>& func) { |
100 | const auto& members = this->members(); | 96 | const auto& members = this->members(); |
101 | for (auto member : members) { | 97 | for (auto member : members) { |
102 | switch (member->get_type()) { | 98 | switch (member->get_type()) { |
@@ -121,7 +117,6 @@ bool ast_container::visitChild(const std::function<bool (ast_node*)>& func) { | |||
121 | return false; | 117 | return false; |
122 | } | 118 | } |
123 | 119 | ||
124 | |||
125 | /** parses the given input. | 120 | /** parses the given input. |
126 | @param i input. | 121 | @param i input. |
127 | @param g root rule of grammar. | 122 | @param g root rule of grammar. |
@@ -143,5 +138,4 @@ ast_node* parse(input& i, rule& g, error_list& el, void* ud) { | |||
143 | return st.front(); | 138 | return st.front(); |
144 | } | 139 | } |
145 | 140 | ||
146 | 141 | } // namespace parserlib | |
147 | } //namespace parserlib | ||
diff --git a/src/yuescript/ast.hpp b/src/yuescript/ast.hpp index 4860fc9..681c27f 100644 --- a/src/yuescript/ast.hpp +++ b/src/yuescript/ast.hpp | |||
@@ -11,40 +11,48 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |||
11 | 11 | ||
12 | #pragma once | 12 | #pragma once |
13 | 13 | ||
14 | |||
15 | #include <cassert> | 14 | #include <cassert> |
16 | #include <list> | 15 | #include <list> |
17 | #include <stdexcept> | 16 | #include <stdexcept> |
18 | #include <type_traits> | ||
19 | #include <string_view> | 17 | #include <string_view> |
18 | #include <type_traits> | ||
20 | 19 | ||
21 | #include "yuescript/parser.hpp" | 20 | #include "yuescript/parser.hpp" |
22 | 21 | ||
23 | |||
24 | namespace parserlib { | 22 | namespace parserlib { |
25 | 23 | ||
26 | |||
27 | class ast_node; | 24 | class ast_node; |
28 | template <bool Required, class T> class ast_ptr; | 25 | template <bool Required, class T> |
29 | template <bool Required, class T> class ast_list; | 26 | class ast_ptr; |
30 | template <class T> class ast; | 27 | template <bool Required, class T> |
31 | 28 | class ast_list; | |
29 | template <class T> | ||
30 | class ast; | ||
32 | 31 | ||
33 | /** type of AST node stack. | 32 | /** type of AST node stack. |
34 | */ | 33 | */ |
35 | typedef std::vector<ast_node*> ast_stack; | 34 | typedef std::vector<ast_node*> ast_stack; |
36 | typedef std::list<ast_node*> node_container; | 35 | typedef std::list<ast_node*> node_container; |
37 | 36 | ||
38 | 37 | template <size_t Num> | |
39 | template<size_t Num> struct Counter { enum { value = Counter<Num-1>::value }; }; | 38 | struct Counter { |
40 | template<> struct Counter<0> { enum { value = 0 }; }; | 39 | enum { value = Counter<Num - 1>::value }; |
40 | }; | ||
41 | template <> | ||
42 | struct Counter<0> { | ||
43 | enum { value = 0 }; | ||
44 | }; | ||
41 | 45 | ||
42 | #define COUNTER_READ Counter<__LINE__>::value | 46 | #define COUNTER_READ Counter<__LINE__>::value |
43 | #define COUNTER_INC template<> struct Counter<__LINE__> { enum { value = Counter<__LINE__-1>::value + 1}; } | 47 | #define COUNTER_INC \ |
48 | template <> \ | ||
49 | struct Counter<__LINE__> { \ | ||
50 | enum { value = Counter<__LINE__ - 1>::value + 1 }; \ | ||
51 | } | ||
44 | 52 | ||
45 | class ast_node; | 53 | class ast_node; |
46 | template<class T> | 54 | template <class T> |
47 | constexpr typename std::enable_if<std::is_base_of<ast_node,T>::value,int>::type | 55 | constexpr typename std::enable_if<std::is_base_of<ast_node, T>::value, int>::type |
48 | id(); | 56 | id(); |
49 | 57 | ||
50 | enum class traversal { | 58 | enum class traversal { |
@@ -54,10 +62,11 @@ enum class traversal { | |||
54 | }; | 62 | }; |
55 | 63 | ||
56 | /** Base class for AST nodes. | 64 | /** Base class for AST nodes. |
57 | */ | 65 | */ |
58 | class ast_node : public input_range { | 66 | class ast_node : public input_range { |
59 | public: | 67 | public: |
60 | ast_node() : _ref(0) {} | 68 | ast_node() |
69 | : _ref(0) { } | ||
61 | 70 | ||
62 | void retain() { | 71 | void retain() { |
63 | ++_ref; | 72 | ++_ref; |
@@ -74,32 +83,32 @@ public: | |||
74 | from a node stack. | 83 | from a node stack. |
75 | @param st stack. | 84 | @param st stack. |
76 | */ | 85 | */ |
77 | virtual void construct(ast_stack&) {} | 86 | virtual void construct(ast_stack&) { } |
78 | 87 | ||
79 | /** interface for visiting AST tree use. | 88 | /** interface for visiting AST tree use. |
80 | */ | 89 | */ |
81 | virtual traversal traverse(const std::function<traversal (ast_node*)>& func); | 90 | virtual traversal traverse(const std::function<traversal(ast_node*)>& func); |
82 | 91 | ||
83 | template <typename... Ts> | 92 | template <typename... Ts> |
84 | struct select_last { | 93 | struct select_last { |
85 | using type = typename decltype((std::enable_if<true,Ts>{}, ...))::type; | 94 | using type = typename decltype((std::enable_if<true, Ts>{}, ...))::type; |
86 | }; | 95 | }; |
87 | template <typename... Ts> | 96 | template <typename... Ts> |
88 | using select_last_t = typename select_last<Ts...>::type; | 97 | using select_last_t = typename select_last<Ts...>::type; |
89 | 98 | ||
90 | template <class ...Args> | 99 | template <class... Args> |
91 | select_last_t<Args...>* getByPath() { | 100 | select_last_t<Args...>* getByPath() { |
92 | int types[] = {id<Args>()...}; | 101 | int types[] = {id<Args>()...}; |
93 | return static_cast<select_last_t<Args...>*>(getByTypeIds(std::begin(types), std::end(types))); | 102 | return static_cast<select_last_t<Args...>*>(getByTypeIds(std::begin(types), std::end(types))); |
94 | } | 103 | } |
95 | 104 | ||
96 | virtual bool visitChild(const std::function<bool (ast_node*)>& func); | 105 | virtual bool visitChild(const std::function<bool(ast_node*)>& func); |
97 | 106 | ||
98 | virtual int getId() const = 0; | 107 | virtual int getId() const = 0; |
99 | 108 | ||
100 | virtual const std::string_view getName() const = 0; | 109 | virtual const std::string_view getName() const = 0; |
101 | 110 | ||
102 | template<class T> | 111 | template <class T> |
103 | inline ast_ptr<false, T> new_ptr() const { | 112 | inline ast_ptr<false, T> new_ptr() const { |
104 | auto item = new T; | 113 | auto item = new T; |
105 | item->m_begin.m_line = m_begin.m_line; | 114 | item->m_begin.m_line = m_begin.m_line; |
@@ -108,27 +117,28 @@ public: | |||
108 | item->m_end.m_col = m_end.m_col; | 117 | item->m_end.m_col = m_end.m_col; |
109 | return ast_ptr<false, T>(item); | 118 | return ast_ptr<false, T>(item); |
110 | } | 119 | } |
120 | |||
111 | private: | 121 | private: |
112 | int _ref; | 122 | int _ref; |
113 | ast_node* getByTypeIds(int* begin, int* end); | 123 | ast_node* getByTypeIds(int* begin, int* end); |
114 | }; | 124 | }; |
115 | 125 | ||
116 | template<class T> | 126 | template <class T> |
117 | constexpr typename std::enable_if<std::is_base_of<ast_node,T>::value,int>::type | 127 | constexpr typename std::enable_if<std::is_base_of<ast_node, T>::value, int>::type |
118 | id() { return 0; } | 128 | id() { return 0; } |
119 | 129 | ||
120 | template<class T> | 130 | template <class T> |
121 | T* ast_cast(ast_node* node) { | 131 | T* ast_cast(ast_node* node) { |
122 | return node && id<T>() == node->getId() ? static_cast<T*>(node) : nullptr; | 132 | return node && id<T>() == node->getId() ? static_cast<T*>(node) : nullptr; |
123 | } | 133 | } |
124 | 134 | ||
125 | template<class T> | 135 | template <class T> |
126 | T* ast_to(ast_node* node) { | 136 | T* ast_to(ast_node* node) { |
127 | assert(node->getId() == id<T>()); | 137 | assert(node->getId() == id<T>()); |
128 | return static_cast<T*>(node); | 138 | return static_cast<T*>(node); |
129 | } | 139 | } |
130 | 140 | ||
131 | template <class ...Args> | 141 | template <class... Args> |
132 | bool ast_is(ast_node* node) { | 142 | bool ast_is(ast_node* node) { |
133 | if (!node) return false; | 143 | if (!node) return false; |
134 | bool result = false; | 144 | bool result = false; |
@@ -141,12 +151,11 @@ bool ast_is(ast_node* node) { | |||
141 | class ast_member; | 151 | class ast_member; |
142 | 152 | ||
143 | /** type of ast member vector. | 153 | /** type of ast member vector. |
144 | */ | 154 | */ |
145 | typedef std::vector<ast_member*> ast_member_vector; | 155 | typedef std::vector<ast_member*> ast_member_vector; |
146 | 156 | ||
147 | |||
148 | /** base class for AST nodes with children. | 157 | /** base class for AST nodes with children. |
149 | */ | 158 | */ |
150 | class ast_container : public ast_node { | 159 | class ast_container : public ast_node { |
151 | public: | 160 | public: |
152 | void add_members(std::initializer_list<ast_member*> members) { | 161 | void add_members(std::initializer_list<ast_member*> members) { |
@@ -169,9 +178,10 @@ public: | |||
169 | */ | 178 | */ |
170 | virtual void construct(ast_stack& st) override; | 179 | virtual void construct(ast_stack& st) override; |
171 | 180 | ||
172 | virtual traversal traverse(const std::function<traversal (ast_node*)>& func) override; | 181 | virtual traversal traverse(const std::function<traversal(ast_node*)>& func) override; |
182 | |||
183 | virtual bool visitChild(const std::function<bool(ast_node*)>& func) override; | ||
173 | 184 | ||
174 | virtual bool visitChild(const std::function<bool (ast_node*)>& func) override; | ||
175 | private: | 185 | private: |
176 | ast_member_vector m_members; | 186 | ast_member_vector m_members; |
177 | 187 | ||
@@ -184,10 +194,10 @@ enum class ast_holder_type { | |||
184 | }; | 194 | }; |
185 | 195 | ||
186 | /** Base class for children of ast_container. | 196 | /** Base class for children of ast_container. |
187 | */ | 197 | */ |
188 | class ast_member { | 198 | class ast_member { |
189 | public: | 199 | public: |
190 | virtual ~ast_member() {} | 200 | virtual ~ast_member() { } |
191 | 201 | ||
192 | /** interface for filling the the member from a node stack. | 202 | /** interface for filling the the member from a node stack. |
193 | @param st stack. | 203 | @param st stack. |
@@ -199,10 +209,10 @@ public: | |||
199 | virtual ast_holder_type get_type() const = 0; | 209 | virtual ast_holder_type get_type() const = 0; |
200 | }; | 210 | }; |
201 | 211 | ||
202 | |||
203 | class _ast_ptr : public ast_member { | 212 | class _ast_ptr : public ast_member { |
204 | public: | 213 | public: |
205 | _ast_ptr(ast_node* node) : m_ptr(node) { | 214 | _ast_ptr(ast_node* node) |
215 | : m_ptr(node) { | ||
206 | if (node) node->retain(); | 216 | if (node) node->retain(); |
207 | } | 217 | } |
208 | 218 | ||
@@ -250,6 +260,7 @@ public: | |||
250 | virtual ast_holder_type get_type() const override { | 260 | virtual ast_holder_type get_type() const override { |
251 | return ast_holder_type::Pointer; | 261 | return ast_holder_type::Pointer; |
252 | } | 262 | } |
263 | |||
253 | protected: | 264 | protected: |
254 | ast_node* m_ptr; | 265 | ast_node* m_ptr; |
255 | }; | 266 | }; |
@@ -260,11 +271,14 @@ protected: | |||
260 | @tparam Required if true, the object is required. | 271 | @tparam Required if true, the object is required. |
261 | @tparam T type of object to control. | 272 | @tparam T type of object to control. |
262 | */ | 273 | */ |
263 | template <bool Required, class T> class ast_ptr : public _ast_ptr { | 274 | template <bool Required, class T> |
275 | class ast_ptr : public _ast_ptr { | ||
264 | public: | 276 | public: |
265 | ast_ptr(T* node = nullptr) : _ast_ptr(node) {} | 277 | ast_ptr(T* node = nullptr) |
278 | : _ast_ptr(node) { } | ||
266 | 279 | ||
267 | ast_ptr(const ast_ptr& other) : _ast_ptr(other.get()) {} | 280 | ast_ptr(const ast_ptr& other) |
281 | : _ast_ptr(other.get()) { } | ||
268 | 282 | ||
269 | ast_ptr& operator=(const ast_ptr& other) { | 283 | ast_ptr& operator=(const ast_ptr& other) { |
270 | set(other.get()); | 284 | set(other.get()); |
@@ -315,17 +329,21 @@ public: | |||
315 | m_ptr = node; | 329 | m_ptr = node; |
316 | node->retain(); | 330 | node->retain(); |
317 | } | 331 | } |
332 | |||
318 | private: | 333 | private: |
319 | virtual bool accept(ast_node* node) override { | 334 | virtual bool accept(ast_node* node) override { |
320 | return node && (std::is_same<ast_node,T>() || id<T>() == node->getId()); | 335 | return node && (std::is_same<ast_node, T>() || id<T>() == node->getId()); |
321 | } | 336 | } |
322 | }; | 337 | }; |
323 | 338 | ||
324 | template <bool Required, class ...Args> class ast_sel : public _ast_ptr { | 339 | template <bool Required, class... Args> |
340 | class ast_sel : public _ast_ptr { | ||
325 | public: | 341 | public: |
326 | ast_sel() : _ast_ptr(nullptr) {} | 342 | ast_sel() |
343 | : _ast_ptr(nullptr) { } | ||
327 | 344 | ||
328 | ast_sel(const ast_sel& other) : _ast_ptr(other.get()) {} | 345 | ast_sel(const ast_sel& other) |
346 | : _ast_ptr(other.get()) { } | ||
329 | 347 | ||
330 | ast_sel& operator=(const ast_sel& other) { | 348 | ast_sel& operator=(const ast_sel& other) { |
331 | set(other.get()); | 349 | set(other.get()); |
@@ -355,6 +373,7 @@ public: | |||
355 | m_ptr = node; | 373 | m_ptr = node; |
356 | node->retain(); | 374 | node->retain(); |
357 | } | 375 | } |
376 | |||
358 | private: | 377 | private: |
359 | virtual bool accept(ast_node* node) override { | 378 | virtual bool accept(ast_node* node) override { |
360 | if (!node) return false; | 379 | if (!node) return false; |
@@ -428,14 +447,14 @@ public: | |||
428 | } | 447 | } |
429 | 448 | ||
430 | void clear() { | 449 | void clear() { |
431 | for(ast_node* obj : m_objects) { | 450 | for (ast_node* obj : m_objects) { |
432 | if (obj) obj->release(); | 451 | if (obj) obj->release(); |
433 | } | 452 | } |
434 | m_objects.clear(); | 453 | m_objects.clear(); |
435 | } | 454 | } |
436 | 455 | ||
437 | void dup(const _ast_list& src) { | 456 | void dup(const _ast_list& src) { |
438 | for(ast_node* obj : src.m_objects) { | 457 | for (ast_node* obj : src.m_objects) { |
439 | m_objects.push_back(obj); | 458 | m_objects.push_back(obj); |
440 | obj->retain(); | 459 | obj->retain(); |
441 | } | 460 | } |
@@ -444,6 +463,7 @@ public: | |||
444 | virtual ast_holder_type get_type() const override { | 463 | virtual ast_holder_type get_type() const override { |
445 | return ast_holder_type::List; | 464 | return ast_holder_type::List; |
446 | } | 465 | } |
466 | |||
447 | protected: | 467 | protected: |
448 | node_container m_objects; | 468 | node_container m_objects; |
449 | }; | 469 | }; |
@@ -454,7 +474,8 @@ protected: | |||
454 | @tparam Required if true, the object is required. | 474 | @tparam Required if true, the object is required. |
455 | @tparam T type of object to control. | 475 | @tparam T type of object to control. |
456 | */ | 476 | */ |
457 | template <bool Required, class T> class ast_list : public _ast_list { | 477 | template <bool Required, class T> |
478 | class ast_list : public _ast_list { | ||
458 | public: | 479 | public: |
459 | ast_list() { } | 480 | ast_list() { } |
460 | 481 | ||
@@ -471,7 +492,7 @@ public: | |||
471 | /** Pops objects of type T from the stack until no more objects can be popped. | 492 | /** Pops objects of type T from the stack until no more objects can be popped. |
472 | @param st stack. | 493 | @param st stack. |
473 | */ | 494 | */ |
474 | virtual void construct(ast_stack &st) override { | 495 | virtual void construct(ast_stack& st) override { |
475 | while (!st.empty()) { | 496 | while (!st.empty()) { |
476 | ast_node* node = st.back(); | 497 | ast_node* node = st.back(); |
477 | // if the object was not not of the appropriate type, | 498 | // if the object was not not of the appropriate type, |
@@ -491,13 +512,15 @@ public: | |||
491 | throw std::logic_error("Invalid AST stack."); | 512 | throw std::logic_error("Invalid AST stack."); |
492 | } | 513 | } |
493 | } | 514 | } |
515 | |||
494 | private: | 516 | private: |
495 | virtual bool accept(ast_node* node) override { | 517 | virtual bool accept(ast_node* node) override { |
496 | return node && (std::is_same<ast_node,T>() || id<T>() == node->getId()); | 518 | return node && (std::is_same<ast_node, T>() || id<T>() == node->getId()); |
497 | } | 519 | } |
498 | }; | 520 | }; |
499 | 521 | ||
500 | template <bool Required, class ...Args> class ast_sel_list : public _ast_list { | 522 | template <bool Required, class... Args> |
523 | class ast_sel_list : public _ast_list { | ||
501 | public: | 524 | public: |
502 | ast_sel_list() { } | 525 | ast_sel_list() { } |
503 | 526 | ||
@@ -511,7 +534,7 @@ public: | |||
511 | return *this; | 534 | return *this; |
512 | } | 535 | } |
513 | 536 | ||
514 | virtual void construct(ast_stack &st) override { | 537 | virtual void construct(ast_stack& st) override { |
515 | while (!st.empty()) { | 538 | while (!st.empty()) { |
516 | ast_node* node = st.back(); | 539 | ast_node* node = st.back(); |
517 | if (!ast_sel_list::accept(node)) { | 540 | if (!ast_sel_list::accept(node)) { |
@@ -528,6 +551,7 @@ public: | |||
528 | throw std::logic_error("Invalid AST stack."); | 551 | throw std::logic_error("Invalid AST stack."); |
529 | } | 552 | } |
530 | } | 553 | } |
554 | |||
531 | private: | 555 | private: |
532 | virtual bool accept(ast_node* node) override { | 556 | virtual bool accept(ast_node* node) override { |
533 | if (!node) return false; | 557 | if (!node) return false; |
@@ -541,7 +565,8 @@ private: | |||
541 | /** AST function which creates an object of type T | 565 | /** AST function which creates an object of type T |
542 | and pushes it to the node stack. | 566 | and pushes it to the node stack. |
543 | */ | 567 | */ |
544 | template <class T> class ast { | 568 | template <class T> |
569 | class ast { | ||
545 | public: | 570 | public: |
546 | /** constructor. | 571 | /** constructor. |
547 | @param r rule to attach the AST function to. | 572 | @param r rule to attach the AST function to. |
@@ -549,8 +574,9 @@ public: | |||
549 | ast(rule& r) { | 574 | ast(rule& r) { |
550 | r.set_parse_proc(&_parse_proc); | 575 | r.set_parse_proc(&_parse_proc); |
551 | } | 576 | } |
577 | |||
552 | private: | 578 | private: |
553 | //parse proc | 579 | // parse proc |
554 | static void _parse_proc(const pos& b, const pos& e, void* d) { | 580 | static void _parse_proc(const pos& b, const pos& e, void* d) { |
555 | ast_stack* st = reinterpret_cast<ast_stack*>(d); | 581 | ast_stack* st = reinterpret_cast<ast_stack*>(d); |
556 | T* obj = new T; | 582 | T* obj = new T; |
@@ -561,7 +587,6 @@ private: | |||
561 | } | 587 | } |
562 | }; | 588 | }; |
563 | 589 | ||
564 | |||
565 | /** parses the given input. | 590 | /** parses the given input. |
566 | @param i input. | 591 | @param i input. |
567 | @param g root rule of grammar. | 592 | @param g root rule of grammar. |
@@ -572,5 +597,4 @@ private: | |||
572 | */ | 597 | */ |
573 | ast_node* parse(input& i, rule& g, error_list& el, void* ud); | 598 | ast_node* parse(input& i, rule& g, error_list& el, void* ud); |
574 | 599 | ||
575 | 600 | } // namespace parserlib | |
576 | } //namespace parserlib | ||
diff --git a/src/yuescript/parser.cpp b/src/yuescript/parser.cpp index a44ae34..a6eb513 100644 --- a/src/yuescript/parser.cpp +++ b/src/yuescript/parser.cpp | |||
@@ -9,222 +9,210 @@ Redistributions in binary form must reproduce the above copyright notice, this l | |||
9 | 9 | ||
10 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/ | 10 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/ |
11 | 11 | ||
12 | #include <cassert> | ||
12 | #include <cstdlib> | 13 | #include <cstdlib> |
13 | #include <cstring> | 14 | #include <cstring> |
14 | #include <cassert> | ||
15 | #include <stdexcept> | 15 | #include <stdexcept> |
16 | #include <unordered_map> | 16 | #include <unordered_map> |
17 | #include <unordered_set> | 17 | #include <unordered_set> |
18 | 18 | ||
19 | #include "yuescript/parser.hpp" | 19 | #include "yuescript/parser.hpp" |
20 | 20 | ||
21 | |||
22 | namespace parserlib { | 21 | namespace parserlib { |
23 | 22 | ||
24 | 23 | // internal private class that manages access to the public classes' internals. | |
25 | //internal private class that manages access to the public classes' internals. | ||
26 | class _private { | 24 | class _private { |
27 | public: | 25 | public: |
28 | //get the internal expression object from the expression. | 26 | // get the internal expression object from the expression. |
29 | static _expr* get_expr(const expr& e) { | 27 | static _expr* get_expr(const expr& e) { |
30 | return e.m_expr; | 28 | return e.m_expr; |
31 | } | 29 | } |
32 | 30 | ||
33 | //create new expression from given expression | 31 | // create new expression from given expression |
34 | static expr construct_expr(_expr* e) { | 32 | static expr construct_expr(_expr* e) { |
35 | return e; | 33 | return e; |
36 | } | 34 | } |
37 | 35 | ||
38 | //get the internal expression object from the rule. | 36 | // get the internal expression object from the rule. |
39 | static _expr* get_expr(rule& r) { | 37 | static _expr* get_expr(rule& r) { |
40 | return r.m_expr; | 38 | return r.m_expr; |
41 | } | 39 | } |
42 | 40 | ||
43 | //get the internal parse proc from the rule. | 41 | // get the internal parse proc from the rule. |
44 | static parse_proc get_parse_proc(rule& r) { | 42 | static parse_proc get_parse_proc(rule& r) { |
45 | return r.m_parse_proc; | 43 | return r.m_parse_proc; |
46 | } | 44 | } |
47 | }; | 45 | }; |
48 | 46 | ||
49 | |||
50 | class _context; | 47 | class _context; |
51 | 48 | ||
52 | 49 | // parser state | |
53 | //parser state | ||
54 | class _state { | 50 | class _state { |
55 | public: | 51 | public: |
56 | //position | 52 | // position |
57 | pos m_pos; | 53 | pos m_pos; |
58 | 54 | ||
59 | //size of match vector | 55 | // size of match vector |
60 | size_t m_matches; | 56 | size_t m_matches; |
61 | 57 | ||
62 | //constructor | 58 | // constructor |
63 | _state(_context& con); | 59 | _state(_context& con); |
64 | }; | 60 | }; |
65 | 61 | ||
66 | 62 | // match | |
67 | //match | ||
68 | class _match { | 63 | class _match { |
69 | public: | 64 | public: |
70 | //rule matched | 65 | // rule matched |
71 | rule* m_rule; | 66 | rule* m_rule; |
72 | 67 | ||
73 | //begin position | 68 | // begin position |
74 | pos m_begin; | 69 | pos m_begin; |
75 | 70 | ||
76 | //end position | 71 | // end position |
77 | pos m_end; | 72 | pos m_end; |
78 | 73 | ||
79 | //null constructor | 74 | // null constructor |
80 | _match() {} | 75 | _match() { } |
81 | 76 | ||
82 | //constructor from parameters | 77 | // constructor from parameters |
83 | _match(rule* r, const pos& b, const pos& e) : | 78 | _match(rule* r, const pos& b, const pos& e) |
84 | m_rule(r), | 79 | : m_rule(r) |
85 | m_begin(b), | 80 | , m_begin(b) |
86 | m_end(e) | 81 | , m_end(e) { |
87 | { | ||
88 | } | 82 | } |
89 | }; | 83 | }; |
90 | 84 | ||
91 | 85 | // match vector | |
92 | //match vector | ||
93 | typedef std::vector<_match> _match_vector; | 86 | typedef std::vector<_match> _match_vector; |
94 | 87 | ||
95 | 88 | // parsing context | |
96 | //parsing context | ||
97 | class _context { | 89 | class _context { |
98 | public: | 90 | public: |
99 | //user data | 91 | // user data |
100 | void* m_user_data; | 92 | void* m_user_data; |
101 | 93 | ||
102 | //current position | 94 | // current position |
103 | pos m_pos; | 95 | pos m_pos; |
104 | 96 | ||
105 | //error position | 97 | // error position |
106 | pos m_error_pos; | 98 | pos m_error_pos; |
107 | 99 | ||
108 | //input begin | 100 | // input begin |
109 | input::iterator m_begin; | 101 | input::iterator m_begin; |
110 | 102 | ||
111 | //input end | 103 | // input end |
112 | input::iterator m_end; | 104 | input::iterator m_end; |
113 | 105 | ||
114 | //matches | 106 | // matches |
115 | _match_vector m_matches; | 107 | _match_vector m_matches; |
116 | 108 | ||
117 | //constructor | 109 | // constructor |
118 | _context(input& i, void* ud) : | 110 | _context(input& i, void* ud) |
119 | m_user_data(ud), | 111 | : m_user_data(ud) |
120 | m_pos(i), | 112 | , m_pos(i) |
121 | m_error_pos(i), | 113 | , m_error_pos(i) |
122 | m_begin(i.begin()), | 114 | , m_begin(i.begin()) |
123 | m_end(i.end()) | 115 | , m_end(i.end()) { |
124 | { | ||
125 | } | 116 | } |
126 | 117 | ||
127 | //check if the end is reached | 118 | // check if the end is reached |
128 | bool end() const { | 119 | bool end() const { |
129 | return m_pos.m_it == m_end; | 120 | return m_pos.m_it == m_end; |
130 | } | 121 | } |
131 | 122 | ||
132 | //get the current symbol | 123 | // get the current symbol |
133 | input::value_type symbol() const { | 124 | input::value_type symbol() const { |
134 | assert(!end()); | 125 | assert(!end()); |
135 | return *m_pos.m_it; | 126 | return *m_pos.m_it; |
136 | } | 127 | } |
137 | 128 | ||
138 | //set the longest possible error | 129 | // set the longest possible error |
139 | void set_error_pos() { | 130 | void set_error_pos() { |
140 | if (m_pos.m_it > m_error_pos.m_it) { | 131 | if (m_pos.m_it > m_error_pos.m_it) { |
141 | m_error_pos = m_pos; | 132 | m_error_pos = m_pos; |
142 | } | 133 | } |
143 | } | 134 | } |
144 | 135 | ||
145 | //next column | 136 | // next column |
146 | void next_col() { | 137 | void next_col() { |
147 | ++m_pos.m_it; | 138 | ++m_pos.m_it; |
148 | ++m_pos.m_col; | 139 | ++m_pos.m_col; |
149 | } | 140 | } |
150 | 141 | ||
151 | //next line | 142 | // next line |
152 | void next_line() { | 143 | void next_line() { |
153 | ++m_pos.m_line; | 144 | ++m_pos.m_line; |
154 | m_pos.m_col = 1; | 145 | m_pos.m_col = 1; |
155 | } | 146 | } |
156 | 147 | ||
157 | //restore the state | 148 | // restore the state |
158 | void restore(const _state& st) { | 149 | void restore(const _state& st) { |
159 | m_pos = st.m_pos; | 150 | m_pos = st.m_pos; |
160 | m_matches.resize(st.m_matches); | 151 | m_matches.resize(st.m_matches); |
161 | } | 152 | } |
162 | 153 | ||
163 | //parse non-term rule. | 154 | // parse non-term rule. |
164 | bool parse_non_term(rule& r); | 155 | bool parse_non_term(rule& r); |
165 | 156 | ||
166 | //parse term rule. | 157 | // parse term rule. |
167 | bool parse_term(rule& r); | 158 | bool parse_term(rule& r); |
168 | 159 | ||
169 | //execute all the parse procs | 160 | // execute all the parse procs |
170 | void do_parse_procs(void* d) const { | 161 | void do_parse_procs(void* d) const { |
171 | for(_match_vector::const_iterator it = m_matches.begin(); | 162 | for (_match_vector::const_iterator it = m_matches.begin(); |
172 | it != m_matches.end(); | 163 | it != m_matches.end(); |
173 | ++it) { | 164 | ++it) { |
174 | const _match &m = *it; | 165 | const _match& m = *it; |
175 | parse_proc p = _private::get_parse_proc(*m.m_rule); | 166 | parse_proc p = _private::get_parse_proc(*m.m_rule); |
176 | p(m.m_begin, m.m_end, d); | 167 | p(m.m_begin, m.m_end, d); |
177 | } | 168 | } |
178 | } | 169 | } |
179 | 170 | ||
180 | private: | 171 | private: |
181 | //parse non-term rule. | 172 | // parse non-term rule. |
182 | bool _parse_non_term(rule& r); | 173 | bool _parse_non_term(rule& r); |
183 | 174 | ||
184 | //parse term rule. | 175 | // parse term rule. |
185 | bool _parse_term(rule& r); | 176 | bool _parse_term(rule& r); |
186 | }; | 177 | }; |
187 | 178 | ||
188 | 179 | // base class for expressions | |
189 | //base class for expressions | ||
190 | class _expr { | 180 | class _expr { |
191 | public: | 181 | public: |
192 | //destructor. | 182 | // destructor. |
193 | virtual ~_expr() { | 183 | virtual ~_expr() { |
194 | } | 184 | } |
195 | 185 | ||
196 | //parse with whitespace | 186 | // parse with whitespace |
197 | virtual bool parse_non_term(_context& con) const = 0; | 187 | virtual bool parse_non_term(_context& con) const = 0; |
198 | 188 | ||
199 | //parse terminal | 189 | // parse terminal |
200 | virtual bool parse_term(_context& con) const = 0; | 190 | virtual bool parse_term(_context& con) const = 0; |
201 | }; | 191 | }; |
202 | 192 | ||
203 | 193 | // single character expression. | |
204 | //single character expression. | ||
205 | class _char : public _expr { | 194 | class _char : public _expr { |
206 | public: | 195 | public: |
207 | //constructor. | 196 | // constructor. |
208 | _char(char c) : | 197 | _char(char c) |
209 | m_char(c) | 198 | : m_char(c) { |
210 | { | ||
211 | } | 199 | } |
212 | 200 | ||
213 | //parse with whitespace | 201 | // parse with whitespace |
214 | virtual bool parse_non_term(_context& con) const { | 202 | virtual bool parse_non_term(_context& con) const { |
215 | return _parse(con); | 203 | return _parse(con); |
216 | } | 204 | } |
217 | 205 | ||
218 | //parse terminal | 206 | // parse terminal |
219 | virtual bool parse_term(_context& con) const { | 207 | virtual bool parse_term(_context& con) const { |
220 | return _parse(con); | 208 | return _parse(con); |
221 | } | 209 | } |
222 | 210 | ||
223 | private: | 211 | private: |
224 | //character | 212 | // character |
225 | input::value_type m_char; | 213 | input::value_type m_char; |
226 | 214 | ||
227 | //internal parse | 215 | // internal parse |
228 | bool _parse(_context& con) const { | 216 | bool _parse(_context& con) const { |
229 | if (!con.end()) { | 217 | if (!con.end()) { |
230 | input::value_type ch = con.symbol(); | 218 | input::value_type ch = con.symbol(); |
@@ -238,34 +226,33 @@ private: | |||
238 | } | 226 | } |
239 | }; | 227 | }; |
240 | 228 | ||
241 | 229 | // string expression. | |
242 | //string expression. | ||
243 | class _string : public _expr { | 230 | class _string : public _expr { |
244 | public: | 231 | public: |
245 | //constructor from ansi string. | 232 | // constructor from ansi string. |
246 | _string(const char* s) : | 233 | _string(const char* s) |
247 | m_string(Converter{}.from_bytes(s)) | 234 | : m_string(Converter{}.from_bytes(s)) { |
248 | { | ||
249 | } | 235 | } |
250 | 236 | ||
251 | //parse with whitespace | 237 | // parse with whitespace |
252 | virtual bool parse_non_term(_context& con) const { | 238 | virtual bool parse_non_term(_context& con) const { |
253 | return _parse(con); | 239 | return _parse(con); |
254 | } | 240 | } |
255 | 241 | ||
256 | //parse terminal | 242 | // parse terminal |
257 | virtual bool parse_term(_context& con) const { | 243 | virtual bool parse_term(_context& con) const { |
258 | return _parse(con); | 244 | return _parse(con); |
259 | } | 245 | } |
260 | 246 | ||
261 | private: | 247 | private: |
262 | //string | 248 | // string |
263 | input m_string; | 249 | input m_string; |
264 | 250 | ||
265 | //parse the string | 251 | // parse the string |
266 | bool _parse(_context& con) const { | 252 | bool _parse(_context& con) const { |
267 | for(input::const_iterator it = m_string.begin(), | 253 | for (input::const_iterator it = m_string.begin(), |
268 | end = m_string.end();;) { | 254 | end = m_string.end(); |
255 | ;) { | ||
269 | if (it == end) return true; | 256 | if (it == end) return true; |
270 | if (con.end()) break; | 257 | if (con.end()) break; |
271 | if (con.symbol() != *it) break; | 258 | if (con.symbol() != *it) break; |
@@ -277,44 +264,43 @@ private: | |||
277 | } | 264 | } |
278 | }; | 265 | }; |
279 | 266 | ||
280 | 267 | // set expression. | |
281 | //set expression. | ||
282 | class _set : public _expr { | 268 | class _set : public _expr { |
283 | public: | 269 | public: |
284 | //constructor from ansi string. | 270 | // constructor from ansi string. |
285 | _set(const char* s) { | 271 | _set(const char* s) { |
286 | auto str = Converter{}.from_bytes(s); | 272 | auto str = Converter{}.from_bytes(s); |
287 | for (auto ch : str) { | 273 | for (auto ch : str) { |
288 | _add(ch); | 274 | _add(ch); |
289 | } | 275 | } |
290 | } | 276 | } |
291 | 277 | ||
292 | //constructor from range. | 278 | // constructor from range. |
293 | _set(int min, int max) { | 279 | _set(int min, int max) { |
294 | assert(min >= 0); | 280 | assert(min >= 0); |
295 | assert(min <= max); | 281 | assert(min <= max); |
296 | m_quick_set.resize((size_t)max + 1U); | 282 | m_quick_set.resize((size_t)max + 1U); |
297 | for(; min <= max; ++min) { | 283 | for (; min <= max; ++min) { |
298 | m_quick_set[(size_t)min] = true; | 284 | m_quick_set[(size_t)min] = true; |
299 | } | 285 | } |
300 | } | 286 | } |
301 | 287 | ||
302 | //parse with whitespace | 288 | // parse with whitespace |
303 | virtual bool parse_non_term(_context& con) const { | 289 | virtual bool parse_non_term(_context& con) const { |
304 | return _parse(con); | 290 | return _parse(con); |
305 | } | 291 | } |
306 | 292 | ||
307 | //parse terminal | 293 | // parse terminal |
308 | virtual bool parse_term(_context& con) const { | 294 | virtual bool parse_term(_context& con) const { |
309 | return _parse(con); | 295 | return _parse(con); |
310 | } | 296 | } |
311 | 297 | ||
312 | private: | 298 | private: |
313 | //set is kept as an array of flags, for quick access | 299 | // set is kept as an array of flags, for quick access |
314 | std::vector<bool> m_quick_set; | 300 | std::vector<bool> m_quick_set; |
315 | std::unordered_set<size_t> m_large_set; | 301 | std::unordered_set<size_t> m_large_set; |
316 | 302 | ||
317 | //add character | 303 | // add character |
318 | void _add(size_t i) { | 304 | void _add(size_t i) { |
319 | if (i <= m_quick_set.size() || i <= 255) { | 305 | if (i <= m_quick_set.size() || i <= 255) { |
320 | if (i >= m_quick_set.size()) { | 306 | if (i >= m_quick_set.size()) { |
@@ -326,7 +312,7 @@ private: | |||
326 | } | 312 | } |
327 | } | 313 | } |
328 | 314 | ||
329 | //internal parse | 315 | // internal parse |
330 | bool _parse(_context& con) const { | 316 | bool _parse(_context& con) const { |
331 | if (!con.end()) { | 317 | if (!con.end()) { |
332 | size_t ch = con.symbol(); | 318 | size_t ch = con.symbol(); |
@@ -345,59 +331,53 @@ private: | |||
345 | } | 331 | } |
346 | }; | 332 | }; |
347 | 333 | ||
348 | 334 | // base class for unary expressions | |
349 | //base class for unary expressions | ||
350 | class _unary : public _expr { | 335 | class _unary : public _expr { |
351 | public: | 336 | public: |
352 | //constructor. | 337 | // constructor. |
353 | _unary(_expr* e) : | 338 | _unary(_expr* e) |
354 | m_expr(e) | 339 | : m_expr(e) { |
355 | { | ||
356 | } | 340 | } |
357 | 341 | ||
358 | //destructor. | 342 | // destructor. |
359 | virtual ~_unary() { | 343 | virtual ~_unary() { |
360 | delete m_expr; | 344 | delete m_expr; |
361 | } | 345 | } |
362 | 346 | ||
363 | protected: | 347 | protected: |
364 | //expression | 348 | // expression |
365 | _expr *m_expr; | 349 | _expr* m_expr; |
366 | }; | 350 | }; |
367 | 351 | ||
368 | 352 | // terminal | |
369 | //terminal | ||
370 | class _term : public _unary { | 353 | class _term : public _unary { |
371 | public: | 354 | public: |
372 | //constructor. | 355 | // constructor. |
373 | _term(_expr* e) : | 356 | _term(_expr* e) |
374 | _unary(e) | 357 | : _unary(e) { |
375 | { | ||
376 | } | 358 | } |
377 | 359 | ||
378 | //parse with whitespace | 360 | // parse with whitespace |
379 | virtual bool parse_non_term(_context& con) const { | 361 | virtual bool parse_non_term(_context& con) const { |
380 | return m_expr->parse_term(con); | 362 | return m_expr->parse_term(con); |
381 | } | 363 | } |
382 | 364 | ||
383 | //parse terminal | 365 | // parse terminal |
384 | virtual bool parse_term(_context& con) const { | 366 | virtual bool parse_term(_context& con) const { |
385 | return m_expr->parse_term(con); | 367 | return m_expr->parse_term(con); |
386 | } | 368 | } |
387 | }; | 369 | }; |
388 | 370 | ||
389 | 371 | // user | |
390 | //user | ||
391 | class _user : public _unary { | 372 | class _user : public _unary { |
392 | public: | 373 | public: |
393 | //constructor. | 374 | // constructor. |
394 | _user(_expr* e, const user_handler& callback) : | 375 | _user(_expr* e, const user_handler& callback) |
395 | _unary(e), | 376 | : _unary(e) |
396 | m_handler(callback) | 377 | , m_handler(callback) { |
397 | { | ||
398 | } | 378 | } |
399 | 379 | ||
400 | //parse with whitespace | 380 | // parse with whitespace |
401 | virtual bool parse_non_term(_context& con) const { | 381 | virtual bool parse_non_term(_context& con) const { |
402 | pos pos = con.m_pos; | 382 | pos pos = con.m_pos; |
403 | if (m_expr->parse_non_term(con)) { | 383 | if (m_expr->parse_non_term(con)) { |
@@ -407,7 +387,7 @@ public: | |||
407 | return false; | 387 | return false; |
408 | } | 388 | } |
409 | 389 | ||
410 | //parse terminal | 390 | // parse terminal |
411 | virtual bool parse_term(_context& con) const { | 391 | virtual bool parse_term(_context& con) const { |
412 | pos pos = con.m_pos; | 392 | pos pos = con.m_pos; |
413 | if (m_expr->parse_term(con)) { | 393 | if (m_expr->parse_term(con)) { |
@@ -416,31 +396,30 @@ public: | |||
416 | } | 396 | } |
417 | return false; | 397 | return false; |
418 | } | 398 | } |
399 | |||
419 | private: | 400 | private: |
420 | user_handler m_handler; | 401 | user_handler m_handler; |
421 | }; | 402 | }; |
422 | 403 | ||
423 | 404 | // loop 0 | |
424 | //loop 0 | ||
425 | class _loop0 : public _unary { | 405 | class _loop0 : public _unary { |
426 | public: | 406 | public: |
427 | //constructor. | 407 | // constructor. |
428 | _loop0(_expr* e) : | 408 | _loop0(_expr* e) |
429 | _unary(e) | 409 | : _unary(e) { |
430 | { | ||
431 | } | 410 | } |
432 | 411 | ||
433 | //parse with whitespace | 412 | // parse with whitespace |
434 | virtual bool parse_non_term(_context& con) const { | 413 | virtual bool parse_non_term(_context& con) const { |
435 | //if parsing of the first fails, restore the context and stop | 414 | // if parsing of the first fails, restore the context and stop |
436 | _state st(con); | 415 | _state st(con); |
437 | if (!m_expr->parse_non_term(con)) { | 416 | if (!m_expr->parse_non_term(con)) { |
438 | con.restore(st); | 417 | con.restore(st); |
439 | return true; | 418 | return true; |
440 | } | 419 | } |
441 | 420 | ||
442 | //parse the rest | 421 | // parse the rest |
443 | for(;;) { | 422 | for (;;) { |
444 | _state st(con); | 423 | _state st(con); |
445 | if (!m_expr->parse_non_term(con)) { | 424 | if (!m_expr->parse_non_term(con)) { |
446 | con.restore(st); | 425 | con.restore(st); |
@@ -451,17 +430,17 @@ public: | |||
451 | return true; | 430 | return true; |
452 | } | 431 | } |
453 | 432 | ||
454 | //parse terminal | 433 | // parse terminal |
455 | virtual bool parse_term(_context& con) const { | 434 | virtual bool parse_term(_context& con) const { |
456 | //if parsing of the first fails, restore the context and stop | 435 | // if parsing of the first fails, restore the context and stop |
457 | _state st(con); | 436 | _state st(con); |
458 | if (!m_expr->parse_term(con)) { | 437 | if (!m_expr->parse_term(con)) { |
459 | con.restore(st); | 438 | con.restore(st); |
460 | return true; | 439 | return true; |
461 | } | 440 | } |
462 | 441 | ||
463 | //parse the rest until no more parsing is possible | 442 | // parse the rest until no more parsing is possible |
464 | for(;;) { | 443 | for (;;) { |
465 | _state st(con); | 444 | _state st(con); |
466 | if (!m_expr->parse_term(con)) { | 445 | if (!m_expr->parse_term(con)) { |
467 | con.restore(st); | 446 | con.restore(st); |
@@ -473,23 +452,21 @@ public: | |||
473 | } | 452 | } |
474 | }; | 453 | }; |
475 | 454 | ||
476 | 455 | // loop 1 | |
477 | //loop 1 | ||
478 | class _loop1 : public _unary { | 456 | class _loop1 : public _unary { |
479 | public: | 457 | public: |
480 | //constructor. | 458 | // constructor. |
481 | _loop1(_expr* e) : | 459 | _loop1(_expr* e) |
482 | _unary(e) | 460 | : _unary(e) { |
483 | { | ||
484 | } | 461 | } |
485 | 462 | ||
486 | //parse with whitespace | 463 | // parse with whitespace |
487 | virtual bool parse_non_term(_context& con) const { | 464 | virtual bool parse_non_term(_context& con) const { |
488 | //parse the first; if the first fails, stop | 465 | // parse the first; if the first fails, stop |
489 | if (!m_expr->parse_non_term(con)) return false; | 466 | if (!m_expr->parse_non_term(con)) return false; |
490 | 467 | ||
491 | //parse the rest until no more parsing is possible | 468 | // parse the rest until no more parsing is possible |
492 | for(;;) { | 469 | for (;;) { |
493 | _state st(con); | 470 | _state st(con); |
494 | if (!m_expr->parse_non_term(con)) { | 471 | if (!m_expr->parse_non_term(con)) { |
495 | con.restore(st); | 472 | con.restore(st); |
@@ -500,13 +477,13 @@ public: | |||
500 | return true; | 477 | return true; |
501 | } | 478 | } |
502 | 479 | ||
503 | //parse terminal | 480 | // parse terminal |
504 | virtual bool parse_term(_context& con) const { | 481 | virtual bool parse_term(_context& con) const { |
505 | //parse the first; if the first fails, stop | 482 | // parse the first; if the first fails, stop |
506 | if (!m_expr->parse_term(con)) return false; | 483 | if (!m_expr->parse_term(con)) return false; |
507 | 484 | ||
508 | //parse the rest until no more parsing is possible | 485 | // parse the rest until no more parsing is possible |
509 | for(;;) { | 486 | for (;;) { |
510 | _state st(con); | 487 | _state st(con); |
511 | if (!m_expr->parse_term(con)) { | 488 | if (!m_expr->parse_term(con)) { |
512 | con.restore(st); | 489 | con.restore(st); |
@@ -518,24 +495,22 @@ public: | |||
518 | } | 495 | } |
519 | }; | 496 | }; |
520 | 497 | ||
521 | 498 | // optional | |
522 | //optional | ||
523 | class _optional : public _unary { | 499 | class _optional : public _unary { |
524 | public: | 500 | public: |
525 | //constructor. | 501 | // constructor. |
526 | _optional(_expr* e) : | 502 | _optional(_expr* e) |
527 | _unary(e) | 503 | : _unary(e) { |
528 | { | ||
529 | } | 504 | } |
530 | 505 | ||
531 | //parse with whitespace | 506 | // parse with whitespace |
532 | virtual bool parse_non_term(_context& con) const { | 507 | virtual bool parse_non_term(_context& con) const { |
533 | _state st(con); | 508 | _state st(con); |
534 | if (!m_expr->parse_non_term(con)) con.restore(st); | 509 | if (!m_expr->parse_non_term(con)) con.restore(st); |
535 | return true; | 510 | return true; |
536 | } | 511 | } |
537 | 512 | ||
538 | //parse terminal | 513 | // parse terminal |
539 | virtual bool parse_term(_context& con) const { | 514 | virtual bool parse_term(_context& con) const { |
540 | _state st(con); | 515 | _state st(con); |
541 | if (!m_expr->parse_term(con)) con.restore(st); | 516 | if (!m_expr->parse_term(con)) con.restore(st); |
@@ -543,17 +518,15 @@ public: | |||
543 | } | 518 | } |
544 | }; | 519 | }; |
545 | 520 | ||
546 | 521 | // and | |
547 | //and | ||
548 | class _and : public _unary { | 522 | class _and : public _unary { |
549 | public: | 523 | public: |
550 | //constructor. | 524 | // constructor. |
551 | _and(_expr* e) : | 525 | _and(_expr* e) |
552 | _unary(e) | 526 | : _unary(e) { |
553 | { | ||
554 | } | 527 | } |
555 | 528 | ||
556 | //parse with whitespace | 529 | // parse with whitespace |
557 | virtual bool parse_non_term(_context& con) const { | 530 | virtual bool parse_non_term(_context& con) const { |
558 | _state st(con); | 531 | _state st(con); |
559 | bool ok = m_expr->parse_non_term(con); | 532 | bool ok = m_expr->parse_non_term(con); |
@@ -561,7 +534,7 @@ public: | |||
561 | return ok; | 534 | return ok; |
562 | } | 535 | } |
563 | 536 | ||
564 | //parse terminal | 537 | // parse terminal |
565 | virtual bool parse_term(_context& con) const { | 538 | virtual bool parse_term(_context& con) const { |
566 | _state st(con); | 539 | _state st(con); |
567 | bool ok = m_expr->parse_term(con); | 540 | bool ok = m_expr->parse_term(con); |
@@ -570,17 +543,15 @@ public: | |||
570 | } | 543 | } |
571 | }; | 544 | }; |
572 | 545 | ||
573 | 546 | // not | |
574 | //not | ||
575 | class _not : public _unary { | 547 | class _not : public _unary { |
576 | public: | 548 | public: |
577 | //constructor. | 549 | // constructor. |
578 | _not(_expr* e) : | 550 | _not(_expr* e) |
579 | _unary(e) | 551 | : _unary(e) { |
580 | { | ||
581 | } | 552 | } |
582 | 553 | ||
583 | //parse with whitespace | 554 | // parse with whitespace |
584 | virtual bool parse_non_term(_context& con) const { | 555 | virtual bool parse_non_term(_context& con) const { |
585 | _state st(con); | 556 | _state st(con); |
586 | bool ok = !m_expr->parse_non_term(con); | 557 | bool ok = !m_expr->parse_non_term(con); |
@@ -588,7 +559,7 @@ public: | |||
588 | return ok; | 559 | return ok; |
589 | } | 560 | } |
590 | 561 | ||
591 | //parse terminal | 562 | // parse terminal |
592 | virtual bool parse_term(_context& con) const { | 563 | virtual bool parse_term(_context& con) const { |
593 | _state st(con); | 564 | _state st(con); |
594 | bool ok = !m_expr->parse_term(con); | 565 | bool ok = !m_expr->parse_term(con); |
@@ -597,24 +568,22 @@ public: | |||
597 | } | 568 | } |
598 | }; | 569 | }; |
599 | 570 | ||
600 | 571 | // newline | |
601 | //newline | ||
602 | class _nl : public _unary { | 572 | class _nl : public _unary { |
603 | public: | 573 | public: |
604 | //constructor. | 574 | // constructor. |
605 | _nl(_expr* e) : | 575 | _nl(_expr* e) |
606 | _unary(e) | 576 | : _unary(e) { |
607 | { | ||
608 | } | 577 | } |
609 | 578 | ||
610 | //parse with whitespace | 579 | // parse with whitespace |
611 | virtual bool parse_non_term(_context& con) const { | 580 | virtual bool parse_non_term(_context& con) const { |
612 | if (!m_expr->parse_non_term(con)) return false; | 581 | if (!m_expr->parse_non_term(con)) return false; |
613 | con.next_line(); | 582 | con.next_line(); |
614 | return true; | 583 | return true; |
615 | } | 584 | } |
616 | 585 | ||
617 | //parse terminal | 586 | // parse terminal |
618 | virtual bool parse_term(_context& con) const { | 587 | virtual bool parse_term(_context& con) const { |
619 | if (!m_expr->parse_term(con)) return false; | 588 | if (!m_expr->parse_term(con)) return false; |
620 | con.next_line(); | 589 | con.next_line(); |
@@ -622,61 +591,56 @@ public: | |||
622 | } | 591 | } |
623 | }; | 592 | }; |
624 | 593 | ||
625 | 594 | // base class for binary expressions | |
626 | //base class for binary expressions | ||
627 | class _binary : public _expr { | 595 | class _binary : public _expr { |
628 | public: | 596 | public: |
629 | //constructor. | 597 | // constructor. |
630 | _binary(_expr* left, _expr* right) : | 598 | _binary(_expr* left, _expr* right) |
631 | m_left(left), m_right(right) | 599 | : m_left(left) |
632 | { | 600 | , m_right(right) { |
633 | } | 601 | } |
634 | 602 | ||
635 | //destructor. | 603 | // destructor. |
636 | virtual ~_binary() { | 604 | virtual ~_binary() { |
637 | delete m_left; | 605 | delete m_left; |
638 | delete m_right; | 606 | delete m_right; |
639 | } | 607 | } |
640 | 608 | ||
641 | protected: | 609 | protected: |
642 | //left and right expressions | 610 | // left and right expressions |
643 | _expr* m_left, *m_right; | 611 | _expr *m_left, *m_right; |
644 | }; | 612 | }; |
645 | 613 | ||
646 | 614 | // sequence | |
647 | //sequence | ||
648 | class _seq : public _binary { | 615 | class _seq : public _binary { |
649 | public: | 616 | public: |
650 | //constructor. | 617 | // constructor. |
651 | _seq(_expr* left, _expr* right) : | 618 | _seq(_expr* left, _expr* right) |
652 | _binary(left, right) | 619 | : _binary(left, right) { |
653 | { | ||
654 | } | 620 | } |
655 | 621 | ||
656 | //parse with whitespace | 622 | // parse with whitespace |
657 | virtual bool parse_non_term(_context& con) const { | 623 | virtual bool parse_non_term(_context& con) const { |
658 | if (!m_left->parse_non_term(con)) return false; | 624 | if (!m_left->parse_non_term(con)) return false; |
659 | return m_right->parse_non_term(con); | 625 | return m_right->parse_non_term(con); |
660 | } | 626 | } |
661 | 627 | ||
662 | //parse terminal | 628 | // parse terminal |
663 | virtual bool parse_term(_context& con) const { | 629 | virtual bool parse_term(_context& con) const { |
664 | if (!m_left->parse_term(con)) return false; | 630 | if (!m_left->parse_term(con)) return false; |
665 | return m_right->parse_term(con); | 631 | return m_right->parse_term(con); |
666 | } | 632 | } |
667 | }; | 633 | }; |
668 | 634 | ||
669 | 635 | // choice | |
670 | //choice | ||
671 | class _choice : public _binary { | 636 | class _choice : public _binary { |
672 | public: | 637 | public: |
673 | //constructor. | 638 | // constructor. |
674 | _choice(_expr* left, _expr* right) : | 639 | _choice(_expr* left, _expr* right) |
675 | _binary(left, right) | 640 | : _binary(left, right) { |
676 | { | ||
677 | } | 641 | } |
678 | 642 | ||
679 | //parse with whitespace | 643 | // parse with whitespace |
680 | virtual bool parse_non_term(_context& con) const { | 644 | virtual bool parse_non_term(_context& con) const { |
681 | _state st(con); | 645 | _state st(con); |
682 | if (m_left->parse_non_term(con)) return true; | 646 | if (m_left->parse_non_term(con)) return true; |
@@ -684,7 +648,7 @@ public: | |||
684 | return m_right->parse_non_term(con); | 648 | return m_right->parse_non_term(con); |
685 | } | 649 | } |
686 | 650 | ||
687 | //parse terminal | 651 | // parse terminal |
688 | virtual bool parse_term(_context& con) const { | 652 | virtual bool parse_term(_context& con) const { |
689 | _state st(con); | 653 | _state st(con); |
690 | if (m_left->parse_term(con)) return true; | 654 | if (m_left->parse_term(con)) return true; |
@@ -693,56 +657,52 @@ public: | |||
693 | } | 657 | } |
694 | }; | 658 | }; |
695 | 659 | ||
696 | 660 | // reference to rule | |
697 | //reference to rule | ||
698 | class _ref : public _expr { | 661 | class _ref : public _expr { |
699 | public: | 662 | public: |
700 | //constructor. | 663 | // constructor. |
701 | _ref(rule& r) : | 664 | _ref(rule& r) |
702 | m_rule(r) | 665 | : m_rule(r) { |
703 | { | ||
704 | } | 666 | } |
705 | 667 | ||
706 | //parse with whitespace | 668 | // parse with whitespace |
707 | virtual bool parse_non_term(_context& con) const { | 669 | virtual bool parse_non_term(_context& con) const { |
708 | return con.parse_non_term(m_rule); | 670 | return con.parse_non_term(m_rule); |
709 | } | 671 | } |
710 | 672 | ||
711 | //parse terminal | 673 | // parse terminal |
712 | virtual bool parse_term(_context& con) const { | 674 | virtual bool parse_term(_context& con) const { |
713 | return con.parse_term(m_rule); | 675 | return con.parse_term(m_rule); |
714 | } | 676 | } |
715 | 677 | ||
716 | private: | 678 | private: |
717 | //reference | 679 | // reference |
718 | rule &m_rule; | 680 | rule& m_rule; |
719 | }; | 681 | }; |
720 | 682 | ||
721 | 683 | // eof | |
722 | //eof | ||
723 | class _eof : public _expr { | 684 | class _eof : public _expr { |
724 | public: | 685 | public: |
725 | //parse with whitespace | 686 | // parse with whitespace |
726 | virtual bool parse_non_term(_context& con) const { | 687 | virtual bool parse_non_term(_context& con) const { |
727 | return parse_term(con); | 688 | return parse_term(con); |
728 | } | 689 | } |
729 | 690 | ||
730 | //parse terminal | 691 | // parse terminal |
731 | virtual bool parse_term(_context& con) const { | 692 | virtual bool parse_term(_context& con) const { |
732 | return con.end(); | 693 | return con.end(); |
733 | } | 694 | } |
734 | }; | 695 | }; |
735 | 696 | ||
736 | 697 | // any | |
737 | //any | ||
738 | class _any : public _expr { | 698 | class _any : public _expr { |
739 | public: | 699 | public: |
740 | //parse with whitespace | 700 | // parse with whitespace |
741 | virtual bool parse_non_term(_context& con) const { | 701 | virtual bool parse_non_term(_context& con) const { |
742 | return parse_term(con); | 702 | return parse_term(con); |
743 | } | 703 | } |
744 | 704 | ||
745 | //parse terminal | 705 | // parse terminal |
746 | virtual bool parse_term(_context& con) const { | 706 | virtual bool parse_term(_context& con) const { |
747 | if (!con.end()) { | 707 | if (!con.end()) { |
748 | con.next_col(); | 708 | con.next_col(); |
@@ -753,115 +713,108 @@ public: | |||
753 | } | 713 | } |
754 | }; | 714 | }; |
755 | 715 | ||
756 | 716 | // true | |
757 | //true | ||
758 | class _true : public _expr { | 717 | class _true : public _expr { |
759 | public: | 718 | public: |
760 | //parse with whitespace | 719 | // parse with whitespace |
761 | virtual bool parse_non_term(_context&) const { | 720 | virtual bool parse_non_term(_context&) const { |
762 | return true; | 721 | return true; |
763 | } | 722 | } |
764 | 723 | ||
765 | //parse terminal | 724 | // parse terminal |
766 | virtual bool parse_term(_context&) const { | 725 | virtual bool parse_term(_context&) const { |
767 | return true; | 726 | return true; |
768 | } | 727 | } |
769 | }; | 728 | }; |
770 | 729 | ||
771 | 730 | // false | |
772 | //false | 731 | class _false : public _expr { |
773 | class _false: public _expr { | ||
774 | public: | 732 | public: |
775 | //parse with whitespace | 733 | // parse with whitespace |
776 | virtual bool parse_non_term(_context&) const { | 734 | virtual bool parse_non_term(_context&) const { |
777 | return false; | 735 | return false; |
778 | } | 736 | } |
779 | 737 | ||
780 | //parse terminal | 738 | // parse terminal |
781 | virtual bool parse_term(_context&) const { | 739 | virtual bool parse_term(_context&) const { |
782 | return false; | 740 | return false; |
783 | } | 741 | } |
784 | }; | 742 | }; |
785 | 743 | ||
786 | //exception thrown when left recursion terminates successfully | 744 | // exception thrown when left recursion terminates successfully |
787 | struct _lr_ok { | 745 | struct _lr_ok { |
788 | rule* m_rule; | 746 | rule* m_rule; |
789 | _lr_ok(rule* r) : m_rule(r) {} | 747 | _lr_ok(rule* r) |
748 | : m_rule(r) { } | ||
790 | }; | 749 | }; |
791 | 750 | ||
792 | 751 | // constructor | |
793 | //constructor | 752 | _state::_state(_context& con) |
794 | _state::_state(_context& con) : | 753 | : m_pos(con.m_pos) |
795 | m_pos(con.m_pos), | 754 | , m_matches(con.m_matches.size()) { |
796 | m_matches(con.m_matches.size()) | ||
797 | { | ||
798 | } | 755 | } |
799 | 756 | ||
800 | 757 | // parse non-term rule. | |
801 | //parse non-term rule. | ||
802 | bool _context::parse_non_term(rule& r) { | 758 | bool _context::parse_non_term(rule& r) { |
803 | //save the state of the rule | 759 | // save the state of the rule |
804 | rule::_state old_state = r.m_state; | 760 | rule::_state old_state = r.m_state; |
805 | 761 | ||
806 | //success/failure result | 762 | // success/failure result |
807 | bool ok = false; | 763 | bool ok = false; |
808 | 764 | ||
809 | //compute the new position | 765 | // compute the new position |
810 | size_t new_pos = m_pos.m_it - m_begin; | 766 | size_t new_pos = m_pos.m_it - m_begin; |
811 | 767 | ||
812 | //check if we have left recursion | 768 | // check if we have left recursion |
813 | bool lr = new_pos == r.m_state.m_pos; | 769 | bool lr = new_pos == r.m_state.m_pos; |
814 | 770 | ||
815 | //update the rule's state | 771 | // update the rule's state |
816 | r.m_state.m_pos = new_pos; | 772 | r.m_state.m_pos = new_pos; |
817 | 773 | ||
818 | //handle the mode of the rule | 774 | // handle the mode of the rule |
819 | switch (r.m_state.m_mode) { | 775 | switch (r.m_state.m_mode) { |
820 | //normal parse | 776 | // normal parse |
821 | case rule::_PARSE: | 777 | case rule::_PARSE: |
822 | if (lr) { | 778 | if (lr) { |
823 | //first try to parse the rule by rejecting it, so alternative branches are examined | 779 | // first try to parse the rule by rejecting it, so alternative branches are examined |
824 | r.m_state.m_mode = rule::_REJECT; | 780 | r.m_state.m_mode = rule::_REJECT; |
825 | ok = _parse_non_term(r); | 781 | ok = _parse_non_term(r); |
826 | 782 | ||
827 | //if the first try is successful, try accepting the rule, | 783 | // if the first try is successful, try accepting the rule, |
828 | //so other elements of the sequence are parsed | 784 | // so other elements of the sequence are parsed |
829 | if (ok) { | 785 | if (ok) { |
830 | r.m_state.m_mode = rule::_ACCEPT; | 786 | r.m_state.m_mode = rule::_ACCEPT; |
831 | 787 | ||
832 | //loop until no more parsing can be done | 788 | // loop until no more parsing can be done |
833 | for(;;) { | 789 | for (;;) { |
834 | //store the correct state, in order to backtrack if the call fails | 790 | // store the correct state, in order to backtrack if the call fails |
835 | _state st(*this); | 791 | _state st(*this); |
836 | 792 | ||
837 | //update the rule position to the current position, | 793 | // update the rule position to the current position, |
838 | //because at this state the rule is resolving the left recursion | 794 | // because at this state the rule is resolving the left recursion |
839 | r.m_state.m_pos = m_pos.m_it - m_begin; | 795 | r.m_state.m_pos = m_pos.m_it - m_begin; |
840 | 796 | ||
841 | //if parsing fails, restore the last good state and stop | 797 | // if parsing fails, restore the last good state and stop |
842 | if (!_parse_non_term(r)) { | 798 | if (!_parse_non_term(r)) { |
843 | restore(st); | 799 | restore(st); |
844 | break; | 800 | break; |
845 | } | 801 | } |
846 | } | 802 | } |
847 | 803 | ||
848 | //since the left recursion was resolved successfully, | 804 | // since the left recursion was resolved successfully, |
849 | //return via a non-local exit | 805 | // return via a non-local exit |
850 | r.m_state = old_state; | 806 | r.m_state = old_state; |
851 | throw _lr_ok(r.this_ptr()); | 807 | throw _lr_ok(r.this_ptr()); |
852 | } | 808 | } |
853 | } | 809 | } else { |
854 | else { | ||
855 | try { | 810 | try { |
856 | ok = _parse_non_term(r); | 811 | ok = _parse_non_term(r); |
857 | } | 812 | } catch (const _lr_ok& ex) { |
858 | catch (const _lr_ok &ex) { | 813 | // since left recursions may be mutual, we must test which rule's left recursion |
859 | //since left recursions may be mutual, we must test which rule's left recursion | 814 | // was ended successfully |
860 | //was ended successfully | ||
861 | if (ex.m_rule == r.this_ptr()) { | 815 | if (ex.m_rule == r.this_ptr()) { |
862 | ok = true; | 816 | ok = true; |
863 | } | 817 | } else { |
864 | else { | ||
865 | r.m_state = old_state; | 818 | r.m_state = old_state; |
866 | throw; | 819 | throw; |
867 | } | 820 | } |
@@ -869,24 +822,22 @@ bool _context::parse_non_term(rule& r) { | |||
869 | } | 822 | } |
870 | break; | 823 | break; |
871 | 824 | ||
872 | //reject the left recursive rule | 825 | // reject the left recursive rule |
873 | case rule::_REJECT: | 826 | case rule::_REJECT: |
874 | if (lr) { | 827 | if (lr) { |
875 | ok = false; | 828 | ok = false; |
876 | } | 829 | } else { |
877 | else { | ||
878 | r.m_state.m_mode = rule::_PARSE; | 830 | r.m_state.m_mode = rule::_PARSE; |
879 | ok = _parse_non_term(r); | 831 | ok = _parse_non_term(r); |
880 | r.m_state.m_mode = rule::_REJECT; | 832 | r.m_state.m_mode = rule::_REJECT; |
881 | } | 833 | } |
882 | break; | 834 | break; |
883 | 835 | ||
884 | //accept the left recursive rule | 836 | // accept the left recursive rule |
885 | case rule::_ACCEPT: | 837 | case rule::_ACCEPT: |
886 | if (lr) { | 838 | if (lr) { |
887 | ok = true; | 839 | ok = true; |
888 | } | 840 | } else { |
889 | else { | ||
890 | r.m_state.m_mode = rule::_PARSE; | 841 | r.m_state.m_mode = rule::_PARSE; |
891 | ok = _parse_non_term(r); | 842 | ok = _parse_non_term(r); |
892 | r.m_state.m_mode = rule::_ACCEPT; | 843 | r.m_state.m_mode = rule::_ACCEPT; |
@@ -894,76 +845,73 @@ bool _context::parse_non_term(rule& r) { | |||
894 | break; | 845 | break; |
895 | } | 846 | } |
896 | 847 | ||
897 | //restore the rule's state | 848 | // restore the rule's state |
898 | r.m_state = old_state; | 849 | r.m_state = old_state; |
899 | 850 | ||
900 | return ok; | 851 | return ok; |
901 | } | 852 | } |
902 | 853 | ||
903 | 854 | // parse term rule. | |
904 | //parse term rule. | ||
905 | bool _context::parse_term(rule& r) { | 855 | bool _context::parse_term(rule& r) { |
906 | //save the state of the rule | 856 | // save the state of the rule |
907 | rule::_state old_state = r.m_state; | 857 | rule::_state old_state = r.m_state; |
908 | 858 | ||
909 | //success/failure result | 859 | // success/failure result |
910 | bool ok = false; | 860 | bool ok = false; |
911 | 861 | ||
912 | //compute the new position | 862 | // compute the new position |
913 | size_t new_pos = m_pos.m_it - m_begin; | 863 | size_t new_pos = m_pos.m_it - m_begin; |
914 | 864 | ||
915 | //check if we have left recursion | 865 | // check if we have left recursion |
916 | bool lr = new_pos == r.m_state.m_pos; | 866 | bool lr = new_pos == r.m_state.m_pos; |
917 | 867 | ||
918 | //update the rule's state | 868 | // update the rule's state |
919 | r.m_state.m_pos = new_pos; | 869 | r.m_state.m_pos = new_pos; |
920 | 870 | ||
921 | //handle the mode of the rule | 871 | // handle the mode of the rule |
922 | switch (r.m_state.m_mode) { | 872 | switch (r.m_state.m_mode) { |
923 | //normal parse | 873 | // normal parse |
924 | case rule::_PARSE: | 874 | case rule::_PARSE: |
925 | if (lr) { | 875 | if (lr) { |
926 | //first try to parse the rule by rejecting it, so alternative branches are examined | 876 | // first try to parse the rule by rejecting it, so alternative branches are examined |
927 | r.m_state.m_mode = rule::_REJECT; | 877 | r.m_state.m_mode = rule::_REJECT; |
928 | ok = _parse_term(r); | 878 | ok = _parse_term(r); |
929 | 879 | ||
930 | //if the first try is successful, try accepting the rule, | 880 | // if the first try is successful, try accepting the rule, |
931 | //so other elements of the sequence are parsed | 881 | // so other elements of the sequence are parsed |
932 | if (ok) { | 882 | if (ok) { |
933 | r.m_state.m_mode = rule::_ACCEPT; | 883 | r.m_state.m_mode = rule::_ACCEPT; |
934 | 884 | ||
935 | //loop until no more parsing can be done | 885 | // loop until no more parsing can be done |
936 | for(;;) { | 886 | for (;;) { |
937 | //store the correct state, in order to backtrack if the call fails | 887 | // store the correct state, in order to backtrack if the call fails |
938 | _state st(*this); | 888 | _state st(*this); |
939 | 889 | ||
940 | //update the rule position to the current position, | 890 | // update the rule position to the current position, |
941 | //because at this state the rule is resolving the left recursion | 891 | // because at this state the rule is resolving the left recursion |
942 | r.m_state.m_pos = m_pos.m_it - m_begin; | 892 | r.m_state.m_pos = m_pos.m_it - m_begin; |
943 | 893 | ||
944 | //if parsing fails, restore the last good state and stop | 894 | // if parsing fails, restore the last good state and stop |
945 | if (!_parse_term(r)) { | 895 | if (!_parse_term(r)) { |
946 | restore(st); | 896 | restore(st); |
947 | break; | 897 | break; |
948 | } | 898 | } |
949 | } | 899 | } |
950 | 900 | ||
951 | //since the left recursion was resolved successfully, | 901 | // since the left recursion was resolved successfully, |
952 | //return via a non-local exit | 902 | // return via a non-local exit |
953 | r.m_state = old_state; | 903 | r.m_state = old_state; |
954 | throw _lr_ok(r.this_ptr()); | 904 | throw _lr_ok(r.this_ptr()); |
955 | } | 905 | } |
956 | } else { | 906 | } else { |
957 | try { | 907 | try { |
958 | ok = _parse_term(r); | 908 | ok = _parse_term(r); |
959 | } | 909 | } catch (const _lr_ok& ex) { |
960 | catch (const _lr_ok& ex) { | 910 | // since left recursions may be mutual, we must test which rule's left recursion |
961 | //since left recursions may be mutual, we must test which rule's left recursion | 911 | // was ended successfully |
962 | //was ended successfully | ||
963 | if (ex.m_rule == r.this_ptr()) { | 912 | if (ex.m_rule == r.this_ptr()) { |
964 | ok = true; | 913 | ok = true; |
965 | } | 914 | } else { |
966 | else { | ||
967 | r.m_state = old_state; | 915 | r.m_state = old_state; |
968 | throw; | 916 | throw; |
969 | } | 917 | } |
@@ -971,7 +919,7 @@ bool _context::parse_term(rule& r) { | |||
971 | } | 919 | } |
972 | break; | 920 | break; |
973 | 921 | ||
974 | //reject the left recursive rule | 922 | // reject the left recursive rule |
975 | case rule::_REJECT: | 923 | case rule::_REJECT: |
976 | if (lr) { | 924 | if (lr) { |
977 | ok = false; | 925 | ok = false; |
@@ -982,7 +930,7 @@ bool _context::parse_term(rule& r) { | |||
982 | } | 930 | } |
983 | break; | 931 | break; |
984 | 932 | ||
985 | //accept the left recursive rule | 933 | // accept the left recursive rule |
986 | case rule::_ACCEPT: | 934 | case rule::_ACCEPT: |
987 | if (lr) { | 935 | if (lr) { |
988 | ok = true; | 936 | ok = true; |
@@ -994,14 +942,13 @@ bool _context::parse_term(rule& r) { | |||
994 | break; | 942 | break; |
995 | } | 943 | } |
996 | 944 | ||
997 | //restore the rule's state | 945 | // restore the rule's state |
998 | r.m_state = old_state; | 946 | r.m_state = old_state; |
999 | 947 | ||
1000 | return ok; | 948 | return ok; |
1001 | } | 949 | } |
1002 | 950 | ||
1003 | 951 | // parse non-term rule internal. | |
1004 | //parse non-term rule internal. | ||
1005 | bool _context::_parse_non_term(rule& r) { | 952 | bool _context::_parse_non_term(rule& r) { |
1006 | bool ok = false; | 953 | bool ok = false; |
1007 | if (_private::get_parse_proc(r)) { | 954 | if (_private::get_parse_proc(r)) { |
@@ -1016,8 +963,7 @@ bool _context::_parse_non_term(rule& r) { | |||
1016 | return ok; | 963 | return ok; |
1017 | } | 964 | } |
1018 | 965 | ||
1019 | 966 | // parse term rule internal. | |
1020 | //parse term rule internal. | ||
1021 | bool _context::_parse_term(rule& r) { | 967 | bool _context::_parse_term(rule& r) { |
1022 | bool ok = false; | 968 | bool ok = false; |
1023 | if (_private::get_parse_proc(r)) { | 969 | if (_private::get_parse_proc(r)) { |
@@ -1032,57 +978,46 @@ bool _context::_parse_term(rule& r) { | |||
1032 | return ok; | 978 | return ok; |
1033 | } | 979 | } |
1034 | 980 | ||
1035 | 981 | // get syntax error | |
1036 | //get syntax error | ||
1037 | static error _syntax_error(_context& con) { | 982 | static error _syntax_error(_context& con) { |
1038 | return error(con.m_error_pos, con.m_error_pos, ERROR_SYNTAX_ERROR); | 983 | return error(con.m_error_pos, con.m_error_pos, ERROR_SYNTAX_ERROR); |
1039 | } | 984 | } |
1040 | 985 | ||
1041 | 986 | // get eof error | |
1042 | //get eof error | ||
1043 | static error _eof_error(_context& con) { | 987 | static error _eof_error(_context& con) { |
1044 | return error(con.m_error_pos, con.m_error_pos, ERROR_INVALID_EOF); | 988 | return error(con.m_error_pos, con.m_error_pos, ERROR_INVALID_EOF); |
1045 | } | 989 | } |
1046 | 990 | ||
1047 | |||
1048 | /** constructor from input. | 991 | /** constructor from input. |
1049 | @param i input. | 992 | @param i input. |
1050 | */ | 993 | */ |
1051 | pos::pos(input& i) : | 994 | pos::pos(input& i) |
1052 | m_it(i.begin()), | 995 | : m_it(i.begin()) |
1053 | m_line(1), | 996 | , m_line(1) |
1054 | m_col(1) | 997 | , m_col(1) { |
1055 | { | ||
1056 | } | 998 | } |
1057 | 999 | ||
1058 | |||
1059 | /** character terminal constructor. | 1000 | /** character terminal constructor. |
1060 | @param c character. | 1001 | @param c character. |
1061 | */ | 1002 | */ |
1062 | expr::expr(char c) : | 1003 | expr::expr(char c) |
1063 | m_expr(new _char(c)) | 1004 | : m_expr(new _char(c)) { |
1064 | { | ||
1065 | } | 1005 | } |
1066 | 1006 | ||
1067 | |||
1068 | /** null-terminated string terminal constructor. | 1007 | /** null-terminated string terminal constructor. |
1069 | @param s null-terminated string. | 1008 | @param s null-terminated string. |
1070 | */ | 1009 | */ |
1071 | expr::expr(const char* s) : | 1010 | expr::expr(const char* s) |
1072 | m_expr(new _string(s)) | 1011 | : m_expr(new _string(s)) { |
1073 | { | ||
1074 | } | 1012 | } |
1075 | 1013 | ||
1076 | |||
1077 | /** rule reference constructor. | 1014 | /** rule reference constructor. |
1078 | @param r rule. | 1015 | @param r rule. |
1079 | */ | 1016 | */ |
1080 | expr::expr(rule& r) : | 1017 | expr::expr(rule& r) |
1081 | m_expr(new _ref(r)) | 1018 | : m_expr(new _ref(r)) { |
1082 | { | ||
1083 | } | 1019 | } |
1084 | 1020 | ||
1085 | |||
1086 | /** creates a zero-or-more loop out of this expression. | 1021 | /** creates a zero-or-more loop out of this expression. |
1087 | @return a zero-or-more loop expression. | 1022 | @return a zero-or-more loop expression. |
1088 | */ | 1023 | */ |
@@ -1090,7 +1025,6 @@ expr expr::operator*() const { | |||
1090 | return _private::construct_expr(new _loop0(m_expr)); | 1025 | return _private::construct_expr(new _loop0(m_expr)); |
1091 | } | 1026 | } |
1092 | 1027 | ||
1093 | |||
1094 | /** creates a one-or-more loop out of this expression. | 1028 | /** creates a one-or-more loop out of this expression. |
1095 | @return a one-or-more loop expression. | 1029 | @return a one-or-more loop expression. |
1096 | */ | 1030 | */ |
@@ -1098,7 +1032,6 @@ expr expr::operator+() const { | |||
1098 | return _private::construct_expr(new _loop1(m_expr)); | 1032 | return _private::construct_expr(new _loop1(m_expr)); |
1099 | } | 1033 | } |
1100 | 1034 | ||
1101 | |||
1102 | /** creates an optional out of this expression. | 1035 | /** creates an optional out of this expression. |
1103 | @return an optional expression. | 1036 | @return an optional expression. |
1104 | */ | 1037 | */ |
@@ -1106,7 +1039,6 @@ expr expr::operator-() const { | |||
1106 | return _private::construct_expr(new _optional(m_expr)); | 1039 | return _private::construct_expr(new _optional(m_expr)); |
1107 | } | 1040 | } |
1108 | 1041 | ||
1109 | |||
1110 | /** creates an AND-expression. | 1042 | /** creates an AND-expression. |
1111 | @return an AND-expression. | 1043 | @return an AND-expression. |
1112 | */ | 1044 | */ |
@@ -1114,7 +1046,6 @@ expr expr::operator&() const { | |||
1114 | return _private::construct_expr((new _and(m_expr))); | 1046 | return _private::construct_expr((new _and(m_expr))); |
1115 | } | 1047 | } |
1116 | 1048 | ||
1117 | |||
1118 | /** creates a NOT-expression. | 1049 | /** creates a NOT-expression. |
1119 | @return a NOT-expression. | 1050 | @return a NOT-expression. |
1120 | */ | 1051 | */ |
@@ -1122,25 +1053,22 @@ expr expr::operator!() const { | |||
1122 | return _private::construct_expr(new _not(m_expr)); | 1053 | return _private::construct_expr(new _not(m_expr)); |
1123 | } | 1054 | } |
1124 | 1055 | ||
1125 | |||
1126 | /** constructor. | 1056 | /** constructor. |
1127 | @param b begin position. | 1057 | @param b begin position. |
1128 | @param e end position. | 1058 | @param e end position. |
1129 | */ | 1059 | */ |
1130 | input_range::input_range(const pos& b, const pos& e) : | 1060 | input_range::input_range(const pos& b, const pos& e) |
1131 | m_begin(b), | 1061 | : m_begin(b) |
1132 | m_end(e) {} | 1062 | , m_end(e) { } |
1133 | |||
1134 | 1063 | ||
1135 | /** constructor. | 1064 | /** constructor. |
1136 | @param b begin position. | 1065 | @param b begin position. |
1137 | @param e end position. | 1066 | @param e end position. |
1138 | @param t error type. | 1067 | @param t error type. |
1139 | */ | 1068 | */ |
1140 | error::error(const pos& b, const pos& e, int t) : | 1069 | error::error(const pos& b, const pos& e, int t) |
1141 | input_range(b, e), | 1070 | : input_range(b, e) |
1142 | m_type(t) {} | 1071 | , m_type(t) { } |
1143 | |||
1144 | 1072 | ||
1145 | /** compare on begin position. | 1073 | /** compare on begin position. |
1146 | @param e the other error to compare this with. | 1074 | @param e the other error to compare this with. |
@@ -1150,45 +1078,44 @@ bool error::operator<(const error& e) const { | |||
1150 | return m_begin.m_it < e.m_begin.m_it; | 1078 | return m_begin.m_it < e.m_begin.m_it; |
1151 | } | 1079 | } |
1152 | 1080 | ||
1153 | rule::rule() : | 1081 | rule::rule() |
1154 | m_expr(nullptr), | 1082 | : m_expr(nullptr) |
1155 | m_parse_proc(nullptr) {} | 1083 | , m_parse_proc(nullptr) { } |
1156 | 1084 | ||
1157 | /** character terminal constructor. | 1085 | /** character terminal constructor. |
1158 | @param c character. | 1086 | @param c character. |
1159 | */ | 1087 | */ |
1160 | rule::rule(char c) : | 1088 | rule::rule(char c) |
1161 | m_expr(new _char(c)), | 1089 | : m_expr(new _char(c)) |
1162 | m_parse_proc(nullptr) {} | 1090 | , m_parse_proc(nullptr) { } |
1163 | 1091 | ||
1164 | /** null-terminated string terminal constructor. | 1092 | /** null-terminated string terminal constructor. |
1165 | @param s null-terminated string. | 1093 | @param s null-terminated string. |
1166 | */ | 1094 | */ |
1167 | rule::rule(const char* s) : | 1095 | rule::rule(const char* s) |
1168 | m_expr(new _string(s)), | 1096 | : m_expr(new _string(s)) |
1169 | m_parse_proc(nullptr) {} | 1097 | , m_parse_proc(nullptr) { } |
1170 | 1098 | ||
1171 | /** constructor from expression. | 1099 | /** constructor from expression. |
1172 | @param e expression. | 1100 | @param e expression. |
1173 | */ | 1101 | */ |
1174 | rule::rule(const expr& e) : | 1102 | rule::rule(const expr& e) |
1175 | m_expr(_private::get_expr(e)), | 1103 | : m_expr(_private::get_expr(e)) |
1176 | m_parse_proc(nullptr) {} | 1104 | , m_parse_proc(nullptr) { } |
1177 | |||
1178 | 1105 | ||
1179 | /** constructor from rule. | 1106 | /** constructor from rule. |
1180 | @param r rule. | 1107 | @param r rule. |
1181 | */ | 1108 | */ |
1182 | rule::rule(rule& r) : | 1109 | rule::rule(rule& r) |
1183 | m_expr(new _ref(r)), | 1110 | : m_expr(new _ref(r)) |
1184 | m_parse_proc(nullptr) {} | 1111 | , m_parse_proc(nullptr) { } |
1185 | 1112 | ||
1186 | rule& rule::operator=(rule& r) { | 1113 | rule& rule::operator=(rule& r) { |
1187 | m_expr = new _ref(r); | 1114 | m_expr = new _ref(r); |
1188 | return *this; | 1115 | return *this; |
1189 | } | 1116 | } |
1190 | 1117 | ||
1191 | rule &rule::operator=(const expr& e) { | 1118 | rule& rule::operator=(const expr& e) { |
1192 | m_expr = _private::get_expr(e); | 1119 | m_expr = _private::get_expr(e); |
1193 | return *this; | 1120 | return *this; |
1194 | } | 1121 | } |
@@ -1200,14 +1127,12 @@ rule::rule(const rule&) { | |||
1200 | throw std::logic_error("invalid operation"); | 1127 | throw std::logic_error("invalid operation"); |
1201 | } | 1128 | } |
1202 | 1129 | ||
1203 | |||
1204 | /** deletes the internal object that represents the expression. | 1130 | /** deletes the internal object that represents the expression. |
1205 | */ | 1131 | */ |
1206 | rule::~rule() { | 1132 | rule::~rule() { |
1207 | delete m_expr; | 1133 | delete m_expr; |
1208 | } | 1134 | } |
1209 | 1135 | ||
1210 | |||
1211 | /** creates a zero-or-more loop out of this rule. | 1136 | /** creates a zero-or-more loop out of this rule. |
1212 | @return a zero-or-more loop rule. | 1137 | @return a zero-or-more loop rule. |
1213 | */ | 1138 | */ |
@@ -1215,7 +1140,6 @@ expr rule::operator*() { | |||
1215 | return _private::construct_expr(new _loop0(new _ref(*this))); | 1140 | return _private::construct_expr(new _loop0(new _ref(*this))); |
1216 | } | 1141 | } |
1217 | 1142 | ||
1218 | |||
1219 | /** creates a one-or-more loop out of this rule. | 1143 | /** creates a one-or-more loop out of this rule. |
1220 | @return a one-or-more loop rule. | 1144 | @return a one-or-more loop rule. |
1221 | */ | 1145 | */ |
@@ -1223,7 +1147,6 @@ expr rule::operator+() { | |||
1223 | return _private::construct_expr(new _loop1(new _ref(*this))); | 1147 | return _private::construct_expr(new _loop1(new _ref(*this))); |
1224 | } | 1148 | } |
1225 | 1149 | ||
1226 | |||
1227 | /** creates an optional out of this rule. | 1150 | /** creates an optional out of this rule. |
1228 | @return an optional rule. | 1151 | @return an optional rule. |
1229 | */ | 1152 | */ |
@@ -1231,7 +1154,6 @@ expr rule::operator-() { | |||
1231 | return _private::construct_expr(new _optional(new _ref(*this))); | 1154 | return _private::construct_expr(new _optional(new _ref(*this))); |
1232 | } | 1155 | } |
1233 | 1156 | ||
1234 | |||
1235 | /** creates an AND-expression out of this rule. | 1157 | /** creates an AND-expression out of this rule. |
1236 | @return an AND-expression out of this rule. | 1158 | @return an AND-expression out of this rule. |
1237 | */ | 1159 | */ |
@@ -1239,7 +1161,6 @@ expr rule::operator&() { | |||
1239 | return _private::construct_expr(new _and(new _ref(*this))); | 1161 | return _private::construct_expr(new _and(new _ref(*this))); |
1240 | } | 1162 | } |
1241 | 1163 | ||
1242 | |||
1243 | /** creates a NOT-expression out of this rule. | 1164 | /** creates a NOT-expression out of this rule. |
1244 | @return a NOT-expression out of this rule. | 1165 | @return a NOT-expression out of this rule. |
1245 | */ | 1166 | */ |
@@ -1247,7 +1168,6 @@ expr rule::operator!() { | |||
1247 | return _private::construct_expr(new _not(new _ref(*this))); | 1168 | return _private::construct_expr(new _not(new _ref(*this))); |
1248 | } | 1169 | } |
1249 | 1170 | ||
1250 | |||
1251 | /** sets the parse procedure. | 1171 | /** sets the parse procedure. |
1252 | @param p procedure. | 1172 | @param p procedure. |
1253 | */ | 1173 | */ |
@@ -1256,29 +1176,26 @@ void rule::set_parse_proc(parse_proc p) { | |||
1256 | m_parse_proc = p; | 1176 | m_parse_proc = p; |
1257 | } | 1177 | } |
1258 | 1178 | ||
1259 | |||
1260 | /** creates a sequence of expressions. | 1179 | /** creates a sequence of expressions. |
1261 | @param left left operand. | 1180 | @param left left operand. |
1262 | @param right right operand. | 1181 | @param right right operand. |
1263 | @return an expression which parses a sequence. | 1182 | @return an expression which parses a sequence. |
1264 | */ | 1183 | */ |
1265 | expr operator >> (const expr& left, const expr& right) { | 1184 | expr operator>>(const expr& left, const expr& right) { |
1266 | return _private::construct_expr( | 1185 | return _private::construct_expr( |
1267 | new _seq(_private::get_expr(left), _private::get_expr(right))); | 1186 | new _seq(_private::get_expr(left), _private::get_expr(right))); |
1268 | } | 1187 | } |
1269 | 1188 | ||
1270 | |||
1271 | /** creates a choice of expressions. | 1189 | /** creates a choice of expressions. |
1272 | @param left left operand. | 1190 | @param left left operand. |
1273 | @param right right operand. | 1191 | @param right right operand. |
1274 | @return an expression which parses a choice. | 1192 | @return an expression which parses a choice. |
1275 | */ | 1193 | */ |
1276 | expr operator | (const expr& left, const expr& right) { | 1194 | expr operator|(const expr& left, const expr& right) { |
1277 | return _private::construct_expr( | 1195 | return _private::construct_expr( |
1278 | new _choice(_private::get_expr(left), _private::get_expr(right))); | 1196 | new _choice(_private::get_expr(left), _private::get_expr(right))); |
1279 | } | 1197 | } |
1280 | 1198 | ||
1281 | |||
1282 | /** converts a parser expression into a terminal. | 1199 | /** converts a parser expression into a terminal. |
1283 | @param e expression. | 1200 | @param e expression. |
1284 | @return an expression which parses a terminal. | 1201 | @return an expression which parses a terminal. |
@@ -1288,7 +1205,6 @@ expr term(const expr& e) { | |||
1288 | new _term(_private::get_expr(e))); | 1205 | new _term(_private::get_expr(e))); |
1289 | } | 1206 | } |
1290 | 1207 | ||
1291 | |||
1292 | /** creates a set expression from a null-terminated string. | 1208 | /** creates a set expression from a null-terminated string. |
1293 | @param s null-terminated string with characters of the set. | 1209 | @param s null-terminated string with characters of the set. |
1294 | @return an expression which parses a single character out of a set. | 1210 | @return an expression which parses a single character out of a set. |
@@ -1297,7 +1213,6 @@ expr set(const char* s) { | |||
1297 | return _private::construct_expr(new _set(s)); | 1213 | return _private::construct_expr(new _set(s)); |
1298 | } | 1214 | } |
1299 | 1215 | ||
1300 | |||
1301 | /** creates a range expression. | 1216 | /** creates a range expression. |
1302 | @param min min character. | 1217 | @param min min character. |
1303 | @param max max character. | 1218 | @param max max character. |
@@ -1307,7 +1222,6 @@ expr range(int min, int max) { | |||
1307 | return _private::construct_expr(new _set(min, max)); | 1222 | return _private::construct_expr(new _set(min, max)); |
1308 | } | 1223 | } |
1309 | 1224 | ||
1310 | |||
1311 | /** creates an expression which increments the line counter | 1225 | /** creates an expression which increments the line counter |
1312 | and resets the column counter when the given expression | 1226 | and resets the column counter when the given expression |
1313 | is parsed successfully; used for newline characters. | 1227 | is parsed successfully; used for newline characters. |
@@ -1318,7 +1232,6 @@ expr nl(const expr& e) { | |||
1318 | return _private::construct_expr(new _nl(_private::get_expr(e))); | 1232 | return _private::construct_expr(new _nl(_private::get_expr(e))); |
1319 | } | 1233 | } |
1320 | 1234 | ||
1321 | |||
1322 | /** creates an expression which tests for the end of input. | 1235 | /** creates an expression which tests for the end of input. |
1323 | @return an expression that handles the end of input. | 1236 | @return an expression that handles the end of input. |
1324 | */ | 1237 | */ |
@@ -1326,7 +1239,6 @@ expr eof() { | |||
1326 | return _private::construct_expr(new _eof()); | 1239 | return _private::construct_expr(new _eof()); |
1327 | } | 1240 | } |
1328 | 1241 | ||
1329 | |||
1330 | /** creates a not expression. | 1242 | /** creates a not expression. |
1331 | @param e expression. | 1243 | @param e expression. |
1332 | @return the appropriate expression. | 1244 | @return the appropriate expression. |
@@ -1335,7 +1247,6 @@ expr not_(const expr& e) { | |||
1335 | return !e; | 1247 | return !e; |
1336 | } | 1248 | } |
1337 | 1249 | ||
1338 | |||
1339 | /** creates an and expression. | 1250 | /** creates an and expression. |
1340 | @param e expression. | 1251 | @param e expression. |
1341 | @return the appropriate expression. | 1252 | @return the appropriate expression. |
@@ -1344,7 +1255,6 @@ expr and_(const expr& e) { | |||
1344 | return &e; | 1255 | return &e; |
1345 | } | 1256 | } |
1346 | 1257 | ||
1347 | |||
1348 | /** creates an expression that parses any character. | 1258 | /** creates an expression that parses any character. |
1349 | @return the appropriate expression. | 1259 | @return the appropriate expression. |
1350 | */ | 1260 | */ |
@@ -1352,28 +1262,24 @@ expr any() { | |||
1352 | return _private::construct_expr(new _any()); | 1262 | return _private::construct_expr(new _any()); |
1353 | } | 1263 | } |
1354 | 1264 | ||
1355 | |||
1356 | /** parsing succeeds without consuming any input. | 1265 | /** parsing succeeds without consuming any input. |
1357 | */ | 1266 | */ |
1358 | expr true_() { | 1267 | expr true_() { |
1359 | return _private::construct_expr(new _true()); | 1268 | return _private::construct_expr(new _true()); |
1360 | } | 1269 | } |
1361 | 1270 | ||
1362 | |||
1363 | /** parsing fails without consuming any input. | 1271 | /** parsing fails without consuming any input. |
1364 | */ | 1272 | */ |
1365 | expr false_() { | 1273 | expr false_() { |
1366 | return _private::construct_expr(new _false()); | 1274 | return _private::construct_expr(new _false()); |
1367 | } | 1275 | } |
1368 | 1276 | ||
1369 | |||
1370 | /** parse with target expression and let user handle result. | 1277 | /** parse with target expression and let user handle result. |
1371 | */ | 1278 | */ |
1372 | expr user(const expr& e, const user_handler& handler) { | 1279 | expr user(const expr& e, const user_handler& handler) { |
1373 | return _private::construct_expr(new _user(_private::get_expr(e), handler)); | 1280 | return _private::construct_expr(new _user(_private::get_expr(e), handler)); |
1374 | } | 1281 | } |
1375 | 1282 | ||
1376 | |||
1377 | /** parses the given input. | 1283 | /** parses the given input. |
1378 | The parse procedures of each rule parsed are executed | 1284 | The parse procedures of each rule parsed are executed |
1379 | before this function returns, if parsing succeeds. | 1285 | before this function returns, if parsing succeeds. |
@@ -1384,16 +1290,16 @@ expr user(const expr& e, const user_handler& handler) { | |||
1384 | @return true on parsing success, false on failure. | 1290 | @return true on parsing success, false on failure. |
1385 | */ | 1291 | */ |
1386 | bool parse(input& i, rule& g, error_list& el, void* d, void* ud) { | 1292 | bool parse(input& i, rule& g, error_list& el, void* d, void* ud) { |
1387 | //prepare context | 1293 | // prepare context |
1388 | _context con(i, ud); | 1294 | _context con(i, ud); |
1389 | 1295 | ||
1390 | //parse grammar | 1296 | // parse grammar |
1391 | if (!con.parse_non_term(g)) { | 1297 | if (!con.parse_non_term(g)) { |
1392 | el.push_back(_syntax_error(con)); | 1298 | el.push_back(_syntax_error(con)); |
1393 | return false; | 1299 | return false; |
1394 | } | 1300 | } |
1395 | 1301 | ||
1396 | //if end is not reached, there was an error | 1302 | // if end is not reached, there was an error |
1397 | if (!con.end()) { | 1303 | if (!con.end()) { |
1398 | if (con.m_error_pos.m_it < con.m_end) { | 1304 | if (con.m_error_pos.m_it < con.m_end) { |
1399 | el.push_back(_syntax_error(con)); | 1305 | el.push_back(_syntax_error(con)); |
@@ -1403,10 +1309,9 @@ bool parse(input& i, rule& g, error_list& el, void* d, void* ud) { | |||
1403 | return false; | 1309 | return false; |
1404 | } | 1310 | } |
1405 | 1311 | ||
1406 | //success; execute the parse procedures | 1312 | // success; execute the parse procedures |
1407 | con.do_parse_procs(d); | 1313 | con.do_parse_procs(d); |
1408 | return true; | 1314 | return true; |
1409 | } | 1315 | } |
1410 | 1316 | ||
1411 | 1317 | } // namespace parserlib | |
1412 | } //namespace parserlib | ||
diff --git a/src/yuescript/parser.hpp b/src/yuescript/parser.hpp index f70475f..eed0bff 100644 --- a/src/yuescript/parser.hpp +++ b/src/yuescript/parser.hpp | |||
@@ -11,24 +11,22 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |||
11 | 11 | ||
12 | #pragma once | 12 | #pragma once |
13 | 13 | ||
14 | 14 | // gcc chokes without rule::rule(const rule &), | |
15 | //gcc chokes without rule::rule(const rule &), | 15 | // msvc complains when rule::rule(const rule &) is defined. |
16 | //msvc complains when rule::rule(const rule &) is defined. | ||
17 | #ifdef _MSC_VER | 16 | #ifdef _MSC_VER |
18 | #pragma warning (disable: 4521) | 17 | #pragma warning(disable : 4521) |
19 | #endif | 18 | #endif |
20 | 19 | ||
21 | |||
22 | #include <vector> | ||
23 | #include <string> | ||
24 | #include <list> | ||
25 | #include <functional> | ||
26 | #include <codecvt> | 20 | #include <codecvt> |
21 | #include <functional> | ||
22 | #include <list> | ||
27 | #include <locale> | 23 | #include <locale> |
24 | #include <string> | ||
25 | #include <vector> | ||
28 | 26 | ||
29 | namespace parserlib { | 27 | namespace parserlib { |
30 | 28 | ||
31 | ///type of the parser's input. | 29 | /// type of the parser's input. |
32 | typedef std::basic_string<wchar_t> input; | 30 | typedef std::basic_string<wchar_t> input; |
33 | typedef input::iterator input_it; | 31 | typedef input::iterator input_it; |
34 | typedef std::wstring_convert<std::codecvt_utf8_utf16<input::value_type>> Converter; | 32 | typedef std::wstring_convert<std::codecvt_utf8_utf16<input::value_type>> Converter; |
@@ -38,7 +36,6 @@ class _expr; | |||
38 | class _context; | 36 | class _context; |
39 | class rule; | 37 | class rule; |
40 | 38 | ||
41 | |||
42 | struct item_t { | 39 | struct item_t { |
43 | input_it begin; | 40 | input_it begin; |
44 | input_it end; | 41 | input_it end; |
@@ -46,31 +43,31 @@ struct item_t { | |||
46 | }; | 43 | }; |
47 | typedef std::function<bool(const item_t&)> user_handler; | 44 | typedef std::function<bool(const item_t&)> user_handler; |
48 | 45 | ||
49 | 46 | /// position into the input. | |
50 | ///position into the input. | ||
51 | class pos { | 47 | class pos { |
52 | public: | 48 | public: |
53 | ///interator into the input. | 49 | /// interator into the input. |
54 | input::iterator m_it; | 50 | input::iterator m_it; |
55 | 51 | ||
56 | ///line. | 52 | /// line. |
57 | int m_line; | 53 | int m_line; |
58 | 54 | ||
59 | ///column. | 55 | /// column. |
60 | int m_col; | 56 | int m_col; |
61 | 57 | ||
62 | ///null constructor. | 58 | /// null constructor. |
63 | pos():m_line(0),m_col(0) {} | 59 | pos() |
60 | : m_line(0) | ||
61 | , m_col(0) { } | ||
64 | 62 | ||
65 | /** constructor from input. | 63 | /** constructor from input. |
66 | @param i input. | 64 | @param i input. |
67 | */ | 65 | */ |
68 | pos(input &i); | 66 | pos(input& i); |
69 | }; | 67 | }; |
70 | 68 | ||
71 | |||
72 | /** a grammar expression. | 69 | /** a grammar expression. |
73 | */ | 70 | */ |
74 | class expr { | 71 | class expr { |
75 | public: | 72 | public: |
76 | /** character terminal constructor. | 73 | /** character terminal constructor. |
@@ -114,19 +111,19 @@ public: | |||
114 | expr operator!() const; | 111 | expr operator!() const; |
115 | 112 | ||
116 | private: | 113 | private: |
117 | //internal expression | 114 | // internal expression |
118 | _expr* m_expr; | 115 | _expr* m_expr; |
119 | 116 | ||
120 | //internal constructor from internal expression | 117 | // internal constructor from internal expression |
121 | expr(_expr* e) : m_expr(e) {} | 118 | expr(_expr* e) |
119 | : m_expr(e) { } | ||
122 | 120 | ||
123 | //assignment not allowed | 121 | // assignment not allowed |
124 | expr& operator=(expr&); | 122 | expr& operator=(expr&); |
125 | 123 | ||
126 | friend class _private; | 124 | friend class _private; |
127 | }; | 125 | }; |
128 | 126 | ||
129 | |||
130 | /** type of procedure to invoke when a rule is successfully parsed. | 127 | /** type of procedure to invoke when a rule is successfully parsed. |
131 | @param b begin position of input. | 128 | @param b begin position of input. |
132 | @param e end position of input. | 129 | @param e end position of input. |
@@ -134,20 +131,19 @@ private: | |||
134 | */ | 131 | */ |
135 | typedef void (*parse_proc)(const pos& b, const pos& e, void* d); | 132 | typedef void (*parse_proc)(const pos& b, const pos& e, void* d); |
136 | 133 | ||
137 | 134 | /// input range. | |
138 | ///input range. | ||
139 | class input_range { | 135 | class input_range { |
140 | public: | 136 | public: |
141 | virtual ~input_range() {} | 137 | virtual ~input_range() { } |
142 | 138 | ||
143 | ///begin position. | 139 | /// begin position. |
144 | pos m_begin; | 140 | pos m_begin; |
145 | 141 | ||
146 | ///end position. | 142 | /// end position. |
147 | pos m_end; | 143 | pos m_end; |
148 | 144 | ||
149 | ///empty constructor. | 145 | /// empty constructor. |
150 | input_range() {} | 146 | input_range() { } |
151 | 147 | ||
152 | /** constructor. | 148 | /** constructor. |
153 | @param b begin position. | 149 | @param b begin position. |
@@ -156,24 +152,22 @@ public: | |||
156 | input_range(const pos& b, const pos& e); | 152 | input_range(const pos& b, const pos& e); |
157 | }; | 153 | }; |
158 | 154 | ||
159 | 155 | /// enum with error types. | |
160 | ///enum with error types. | ||
161 | enum ERROR_TYPE { | 156 | enum ERROR_TYPE { |
162 | ///syntax error | 157 | /// syntax error |
163 | ERROR_SYNTAX_ERROR = 1, | 158 | ERROR_SYNTAX_ERROR = 1, |
164 | 159 | ||
165 | ///invalid end of file | 160 | /// invalid end of file |
166 | ERROR_INVALID_EOF, | 161 | ERROR_INVALID_EOF, |
167 | 162 | ||
168 | ///first user error | 163 | /// first user error |
169 | ERROR_USER = 100 | 164 | ERROR_USER = 100 |
170 | }; | 165 | }; |
171 | 166 | ||
172 | 167 | /// error. | |
173 | ///error. | ||
174 | class error : public input_range { | 168 | class error : public input_range { |
175 | public: | 169 | public: |
176 | ///type | 170 | /// type |
177 | int m_type; | 171 | int m_type; |
178 | 172 | ||
179 | /** constructor. | 173 | /** constructor. |
@@ -190,13 +184,11 @@ public: | |||
190 | bool operator<(const error& e) const; | 184 | bool operator<(const error& e) const; |
191 | }; | 185 | }; |
192 | 186 | ||
193 | 187 | /// type of error list. | |
194 | ///type of error list. | ||
195 | typedef std::list<error> error_list; | 188 | typedef std::list<error> error_list; |
196 | 189 | ||
197 | |||
198 | /** represents a rule. | 190 | /** represents a rule. |
199 | */ | 191 | */ |
200 | class rule { | 192 | class rule { |
201 | public: | 193 | public: |
202 | /** character terminal constructor. | 194 | /** character terminal constructor. |
@@ -227,7 +219,7 @@ public: | |||
227 | rule(const rule& r); | 219 | rule(const rule& r); |
228 | 220 | ||
229 | /** deletes the internal object that represents the expression. | 221 | /** deletes the internal object that represents the expression. |
230 | */ | 222 | */ |
231 | ~rule(); | 223 | ~rule(); |
232 | 224 | ||
233 | /** creates a zero-or-more loop out of this rule. | 225 | /** creates a zero-or-more loop out of this rule. |
@@ -270,40 +262,40 @@ public: | |||
270 | rule& operator=(const expr&); | 262 | rule& operator=(const expr&); |
271 | 263 | ||
272 | private: | 264 | private: |
273 | //mode | 265 | // mode |
274 | enum _MODE { | 266 | enum _MODE { |
275 | _PARSE, | 267 | _PARSE, |
276 | _REJECT, | 268 | _REJECT, |
277 | _ACCEPT | 269 | _ACCEPT |
278 | }; | 270 | }; |
279 | 271 | ||
280 | //state | 272 | // state |
281 | struct _state { | 273 | struct _state { |
282 | //position in source code, relative to start | 274 | // position in source code, relative to start |
283 | size_t m_pos; | 275 | size_t m_pos; |
284 | 276 | ||
285 | //mode | 277 | // mode |
286 | _MODE m_mode; | 278 | _MODE m_mode; |
287 | 279 | ||
288 | //constructor | 280 | // constructor |
289 | _state(size_t pos = -1, _MODE mode = _PARSE) : | 281 | _state(size_t pos = -1, _MODE mode = _PARSE) |
290 | m_pos(pos), m_mode(mode) {} | 282 | : m_pos(pos) |
283 | , m_mode(mode) { } | ||
291 | }; | 284 | }; |
292 | 285 | ||
293 | //internal expression | 286 | // internal expression |
294 | _expr* m_expr; | 287 | _expr* m_expr; |
295 | 288 | ||
296 | //associated parse procedure. | 289 | // associated parse procedure. |
297 | parse_proc m_parse_proc; | 290 | parse_proc m_parse_proc; |
298 | 291 | ||
299 | //state | 292 | // state |
300 | _state m_state; | 293 | _state m_state; |
301 | 294 | ||
302 | friend class _private; | 295 | friend class _private; |
303 | friend class _context; | 296 | friend class _context; |
304 | }; | 297 | }; |
305 | 298 | ||
306 | |||
307 | /** creates a sequence of expressions. | 299 | /** creates a sequence of expressions. |
308 | @param left left operand. | 300 | @param left left operand. |
309 | @param right right operand. | 301 | @param right right operand. |
@@ -311,7 +303,6 @@ private: | |||
311 | */ | 303 | */ |
312 | expr operator>>(const expr& left, const expr& right); | 304 | expr operator>>(const expr& left, const expr& right); |
313 | 305 | ||
314 | |||
315 | /** creates a choice of expressions. | 306 | /** creates a choice of expressions. |
316 | @param left left operand. | 307 | @param left left operand. |
317 | @param right right operand. | 308 | @param right right operand. |
@@ -319,21 +310,18 @@ expr operator>>(const expr& left, const expr& right); | |||
319 | */ | 310 | */ |
320 | expr operator|(const expr& left, const expr& right); | 311 | expr operator|(const expr& left, const expr& right); |
321 | 312 | ||
322 | |||
323 | /** converts a parser expression into a terminal. | 313 | /** converts a parser expression into a terminal. |
324 | @param e expression. | 314 | @param e expression. |
325 | @return an expression which parses a terminal. | 315 | @return an expression which parses a terminal. |
326 | */ | 316 | */ |
327 | expr term(const expr& e); | 317 | expr term(const expr& e); |
328 | 318 | ||
329 | |||
330 | /** creates a set expression from a null-terminated string. | 319 | /** creates a set expression from a null-terminated string. |
331 | @param s null-terminated string with characters of the set. | 320 | @param s null-terminated string with characters of the set. |
332 | @return an expression which parses a single character out of a set. | 321 | @return an expression which parses a single character out of a set. |
333 | */ | 322 | */ |
334 | expr set(const char* s); | 323 | expr set(const char* s); |
335 | 324 | ||
336 | |||
337 | /** creates a range expression. | 325 | /** creates a range expression. |
338 | @param min min character. | 326 | @param min min character. |
339 | @param max max character. | 327 | @param max max character. |
@@ -341,7 +329,6 @@ expr set(const char* s); | |||
341 | */ | 329 | */ |
342 | expr range(int min, int max); | 330 | expr range(int min, int max); |
343 | 331 | ||
344 | |||
345 | /** creates an expression which increments the line counter | 332 | /** creates an expression which increments the line counter |
346 | and resets the column counter when the given expression | 333 | and resets the column counter when the given expression |
347 | is parsed successfully; used for newline characters. | 334 | is parsed successfully; used for newline characters. |
@@ -350,48 +337,40 @@ expr range(int min, int max); | |||
350 | */ | 337 | */ |
351 | expr nl(const expr& e); | 338 | expr nl(const expr& e); |
352 | 339 | ||
353 | |||
354 | /** creates an expression which tests for the end of input. | 340 | /** creates an expression which tests for the end of input. |
355 | @return an expression that handles the end of input. | 341 | @return an expression that handles the end of input. |
356 | */ | 342 | */ |
357 | expr eof(); | 343 | expr eof(); |
358 | 344 | ||
359 | |||
360 | /** creates a not expression. | 345 | /** creates a not expression. |
361 | @param e expression. | 346 | @param e expression. |
362 | @return the appropriate expression. | 347 | @return the appropriate expression. |
363 | */ | 348 | */ |
364 | expr not_(const expr& e); | 349 | expr not_(const expr& e); |
365 | 350 | ||
366 | |||
367 | /** creates an and expression. | 351 | /** creates an and expression. |
368 | @param e expression. | 352 | @param e expression. |
369 | @return the appropriate expression. | 353 | @return the appropriate expression. |
370 | */ | 354 | */ |
371 | expr and_(const expr& e); | 355 | expr and_(const expr& e); |
372 | 356 | ||
373 | |||
374 | /** creates an expression that parses any character. | 357 | /** creates an expression that parses any character. |
375 | @return the appropriate expression. | 358 | @return the appropriate expression. |
376 | */ | 359 | */ |
377 | expr any(); | 360 | expr any(); |
378 | 361 | ||
379 | |||
380 | /** parsing succeeds without consuming any input. | 362 | /** parsing succeeds without consuming any input. |
381 | */ | 363 | */ |
382 | expr true_(); | 364 | expr true_(); |
383 | 365 | ||
384 | |||
385 | /** parsing fails without consuming any input. | 366 | /** parsing fails without consuming any input. |
386 | */ | 367 | */ |
387 | expr false_(); | 368 | expr false_(); |
388 | 369 | ||
389 | |||
390 | /** parse with target expression and let user handle result. | 370 | /** parse with target expression and let user handle result. |
391 | */ | 371 | */ |
392 | expr user(const expr& e, const user_handler& handler); | 372 | expr user(const expr& e, const user_handler& handler); |
393 | 373 | ||
394 | |||
395 | /** parses the given input. | 374 | /** parses the given input. |
396 | The parse procedures of each rule parsed are executed | 375 | The parse procedures of each rule parsed are executed |
397 | before this function returns, if parsing succeeds. | 376 | before this function returns, if parsing succeeds. |
@@ -403,20 +382,19 @@ expr user(const expr& e, const user_handler& handler); | |||
403 | */ | 382 | */ |
404 | bool parse(input& i, rule& g, error_list& el, void* d, void* ud); | 383 | bool parse(input& i, rule& g, error_list& el, void* d, void* ud); |
405 | 384 | ||
406 | |||
407 | /** output the specific input range to the specific stream. | 385 | /** output the specific input range to the specific stream. |
408 | @param stream stream. | 386 | @param stream stream. |
409 | @param ir input range. | 387 | @param ir input range. |
410 | @return the stream. | 388 | @return the stream. |
411 | */ | 389 | */ |
412 | template <class T> T& operator<<(T& stream, const input_range& ir) { | 390 | template <class T> |
413 | for(input::const_iterator it = ir.m_begin.m_it; | 391 | T& operator<<(T& stream, const input_range& ir) { |
414 | it != ir.m_end.m_it; | 392 | for (input::const_iterator it = ir.m_begin.m_it; |
415 | ++it) { | 393 | it != ir.m_end.m_it; |
416 | stream << (typename T::char_type)*it; | 394 | ++it) { |
395 | stream << (typename T::char_type) * it; | ||
417 | } | 396 | } |
418 | return stream; | 397 | return stream; |
419 | } | 398 | } |
420 | 399 | ||
421 | 400 | } // namespace parserlib | |
422 | } //namespace parserlib | ||
diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h index 620dfcc..386fa28 100755 --- a/src/yuescript/yue_ast.h +++ b/src/yuescript/yue_ast.h | |||
@@ -14,18 +14,16 @@ namespace parserlib { | |||
14 | using namespace std::string_view_literals; | 14 | using namespace std::string_view_literals; |
15 | 15 | ||
16 | #define AST_LEAF(type) \ | 16 | #define AST_LEAF(type) \ |
17 | COUNTER_INC; \ | 17 | COUNTER_INC; \ |
18 | class type##_t : public ast_node \ | 18 | class type##_t : public ast_node { \ |
19 | { \ | 19 | public: \ |
20 | public: \ | 20 | virtual int getId() const override { return COUNTER_READ; } |
21 | virtual int getId() const override { return COUNTER_READ; } | ||
22 | 21 | ||
23 | #define AST_NODE(type) \ | 22 | #define AST_NODE(type) \ |
24 | COUNTER_INC; \ | 23 | COUNTER_INC; \ |
25 | class type##_t : public ast_container \ | 24 | class type##_t : public ast_container { \ |
26 | { \ | 25 | public: \ |
27 | public: \ | 26 | virtual int getId() const override { return COUNTER_READ; } |
28 | virtual int getId() const override { return COUNTER_READ; } | ||
29 | 27 | ||
30 | #define AST_MEMBER(type, ...) \ | 28 | #define AST_MEMBER(type, ...) \ |
31 | type##_t() { \ | 29 | type##_t() { \ |
@@ -34,8 +32,12 @@ public: \ | |||
34 | 32 | ||
35 | #define AST_END(type, name) \ | 33 | #define AST_END(type, name) \ |
36 | virtual const std::string_view getName() const override { return name; } \ | 34 | virtual const std::string_view getName() const override { return name; } \ |
37 | }; \ | 35 | } \ |
38 | template<> constexpr int id<type##_t>() { return COUNTER_READ; } | 36 | ; \ |
37 | template <> \ | ||
38 | constexpr int id<type##_t>() { return COUNTER_READ; } | ||
39 | |||
40 | // clang-format off | ||
39 | 41 | ||
40 | AST_LEAF(Num) | 42 | AST_LEAF(Num) |
41 | AST_END(Num, "num"sv) | 43 | AST_END(Num, "num"sv) |
@@ -849,4 +851,6 @@ AST_NODE(File) | |||
849 | AST_MEMBER(File, &block) | 851 | AST_MEMBER(File, &block) |
850 | AST_END(File, "file"sv) | 852 | AST_END(File, "file"sv) |
851 | 853 | ||
854 | // clang-format on | ||
855 | |||
852 | } // namespace parserlib | 856 | } // namespace parserlib |
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index b730a9f..17979ab 100755 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp | |||
@@ -6,23 +6,23 @@ The above copyright notice and this permission notice shall be included in all c | |||
6 | 6 | ||
7 | THE 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.*/ | 7 | THE 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 | 8 | ||
9 | #include <memory> | ||
10 | #include <optional> | ||
11 | #include <set> | ||
12 | #include <stack> | ||
9 | #include <string> | 13 | #include <string> |
10 | #include <unordered_set> | ||
11 | #include <unordered_map> | 14 | #include <unordered_map> |
12 | #include <stack> | 15 | #include <unordered_set> |
13 | #include <vector> | 16 | #include <vector> |
14 | #include <memory> | ||
15 | #include <set> | ||
16 | #include <optional> | ||
17 | 17 | ||
18 | #include "yuescript/yue_parser.h" | ||
19 | #include "yuescript/yue_compiler.h" | 18 | #include "yuescript/yue_compiler.h" |
19 | #include "yuescript/yue_parser.h" | ||
20 | 20 | ||
21 | #ifndef YUE_NO_MACRO | 21 | #ifndef YUE_NO_MACRO |
22 | 22 | ||
23 | extern "C" { | 23 | extern "C" { |
24 | #include "lua.h" | ||
25 | #include "lauxlib.h" | 24 | #include "lauxlib.h" |
25 | #include "lua.h" | ||
26 | #include "lualib.h" | 26 | #include "lualib.h" |
27 | } // extern "C" | 27 | } // extern "C" |
28 | 28 | ||
@@ -30,9 +30,9 @@ extern "C" { | |||
30 | #define YUE_MODULE "__yue_modules__" | 30 | #define YUE_MODULE "__yue_modules__" |
31 | 31 | ||
32 | #if LUA_VERSION_NUM > 501 | 32 | #if LUA_VERSION_NUM > 501 |
33 | #ifndef LUA_COMPAT_5_1 | 33 | #ifndef LUA_COMPAT_5_1 |
34 | #define lua_objlen lua_rawlen | 34 | #define lua_objlen lua_rawlen |
35 | #endif // LUA_COMPAT_5_1 | 35 | #endif // LUA_COMPAT_5_1 |
36 | #endif // LUA_VERSION_NUM | 36 | #endif // LUA_VERSION_NUM |
37 | 37 | ||
38 | #endif // YUE_NO_MACRO | 38 | #endif // YUE_NO_MACRO |
@@ -40,17 +40,22 @@ extern "C" { | |||
40 | namespace yue { | 40 | namespace yue { |
41 | 41 | ||
42 | #define BLOCK_START do { | 42 | #define BLOCK_START do { |
43 | #define BLOCK_END } while (false); | 43 | #define BLOCK_END \ |
44 | #define BREAK_IF(cond) if (cond) break | 44 | } \ |
45 | 45 | while (false) \ | |
46 | #define _DEFER(code,line) std::shared_ptr<void> _defer_##line(nullptr, [&](auto){code;}) | 46 | ; |
47 | #define DEFER(code) _DEFER(code,__LINE__) | 47 | #define BREAK_IF(cond) \ |
48 | #define YUEE(msg,node) throw std::logic_error( \ | 48 | if (cond) break |
49 | |||
50 | #define _DEFER(code, line) std::shared_ptr<void> _defer_##line(nullptr, [&](auto) { code; }) | ||
51 | #define DEFER(code) _DEFER(code, __LINE__) | ||
52 | #define YUEE(msg, node) throw std::logic_error( \ | ||
49 | _info.errorMessage( \ | 53 | _info.errorMessage( \ |
50 | "[File] "s + __FILE__ \ | 54 | "[File] "s + __FILE__ \ |
51 | + ",\n[Func] "s + __FUNCTION__ \ | 55 | + ",\n[Func] "s + __FUNCTION__ \ |
52 | + ",\n[Line] "s + std::to_string(__LINE__) \ | 56 | + ",\n[Line] "s + std::to_string(__LINE__) \ |
53 | + ",\n[Error] "s + msg, node)) | 57 | + ",\n[Error] "s + msg, \ |
58 | node)) | ||
54 | 59 | ||
55 | typedef std::list<std::string> str_list; | 60 | typedef std::list<std::string> str_list; |
56 | 61 | ||
@@ -62,9 +67,9 @@ public: | |||
62 | #ifndef YUE_NO_MACRO | 67 | #ifndef YUE_NO_MACRO |
63 | YueCompilerImpl(lua_State* sharedState, | 68 | YueCompilerImpl(lua_State* sharedState, |
64 | const std::function<void(void*)>& luaOpen, | 69 | const std::function<void(void*)>& luaOpen, |
65 | bool sameModule): | 70 | bool sameModule) |
66 | L(sharedState), | 71 | : L(sharedState) |
67 | _luaOpen(luaOpen) { | 72 | , _luaOpen(luaOpen) { |
68 | BLOCK_START | 73 | BLOCK_START |
69 | BREAK_IF(!sameModule); | 74 | BREAK_IF(!sameModule); |
70 | BREAK_IF(!L); | 75 | BREAK_IF(!L); |
@@ -153,8 +158,7 @@ public: | |||
153 | std::tie(line, col) = var.second; | 158 | std::tie(line, col) = var.second; |
154 | globals->push_back({var.first, line, col}); | 159 | globals->push_back({var.first, line, col}); |
155 | } | 160 | } |
156 | std::sort(globals->begin(), globals->end(), [](const GlobalVar& varA, const GlobalVar& varB) | 161 | std::sort(globals->begin(), globals->end(), [](const GlobalVar& varA, const GlobalVar& varB) { |
157 | { | ||
158 | if (varA.line < varB.line) { | 162 | if (varA.line < varB.line) { |
159 | return true; | 163 | return true; |
160 | } else if (varA.line == varB.line) { | 164 | } else if (varA.line == varB.line) { |
@@ -222,6 +226,7 @@ public: | |||
222 | } | 226 | } |
223 | #endif // YUE_NO_MACRO | 227 | #endif // YUE_NO_MACRO |
224 | } | 228 | } |
229 | |||
225 | private: | 230 | private: |
226 | #ifndef YUE_NO_MACRO | 231 | #ifndef YUE_NO_MACRO |
227 | bool _stateOwner = false; | 232 | bool _stateOwner = false; |
@@ -234,22 +239,20 @@ private: | |||
234 | YueParser _parser; | 239 | YueParser _parser; |
235 | ParseInfo _info; | 240 | ParseInfo _info; |
236 | int _indentOffset = 0; | 241 | int _indentOffset = 0; |
237 | struct VarArgState | 242 | struct VarArgState { |
238 | { | ||
239 | bool hasVar; | 243 | bool hasVar; |
240 | bool usedVar; | 244 | bool usedVar; |
241 | }; | 245 | }; |
242 | std::stack<VarArgState> _varArgs; | 246 | std::stack<VarArgState> _varArgs; |
243 | std::stack<bool> _enableReturn; | 247 | std::stack<bool> _enableReturn; |
244 | std::stack<std::string> _withVars; | 248 | std::stack<std::string> _withVars; |
245 | struct ContinueVar | 249 | struct ContinueVar { |
246 | { | ||
247 | std::string var; | 250 | std::string var; |
248 | ast_ptr<false, ExpListAssign_t> condAssign; | 251 | ast_ptr<false, ExpListAssign_t> condAssign; |
249 | }; | 252 | }; |
250 | std::stack<ContinueVar> _continueVars; | 253 | std::stack<ContinueVar> _continueVars; |
251 | std::list<std::unique_ptr<input>> _codeCache; | 254 | std::list<std::unique_ptr<input>> _codeCache; |
252 | std::unordered_map<std::string,std::pair<int, int>> _globals; | 255 | std::unordered_map<std::string, std::pair<int, int>> _globals; |
253 | std::ostringstream _buf; | 256 | std::ostringstream _buf; |
254 | std::ostringstream _joinBuf; | 257 | std::ostringstream _joinBuf; |
255 | const std::string _newLine = "\n"; | 258 | const std::string _newLine = "\n"; |
@@ -271,7 +274,7 @@ private: | |||
271 | }; | 274 | }; |
272 | struct Scope { | 275 | struct Scope { |
273 | GlobalMode mode = GlobalMode::None; | 276 | GlobalMode mode = GlobalMode::None; |
274 | std::unique_ptr<std::unordered_map<std::string,VarType>> vars; | 277 | std::unique_ptr<std::unordered_map<std::string, VarType>> vars; |
275 | std::unique_ptr<std::unordered_set<std::string>> allows; | 278 | std::unique_ptr<std::unordered_set<std::string>> allows; |
276 | std::unique_ptr<std::unordered_set<std::string>> globals; | 279 | std::unique_ptr<std::unordered_set<std::string>> globals; |
277 | }; | 280 | }; |
@@ -312,7 +315,7 @@ private: | |||
312 | 315 | ||
313 | void pushScope() { | 316 | void pushScope() { |
314 | _scopes.emplace_back(); | 317 | _scopes.emplace_back(); |
315 | _scopes.back().vars = std::make_unique<std::unordered_map<std::string,VarType>>(); | 318 | _scopes.back().vars = std::make_unique<std::unordered_map<std::string, VarType>>(); |
316 | } | 319 | } |
317 | 320 | ||
318 | void popScope() { | 321 | void popScope() { |
@@ -377,7 +380,7 @@ private: | |||
377 | bool isConst(const std::string& name) const { | 380 | bool isConst(const std::string& name) const { |
378 | bool isConst = false; | 381 | bool isConst = false; |
379 | decltype(_scopes.back().allows.get()) allows = nullptr; | 382 | decltype(_scopes.back().allows.get()) allows = nullptr; |
380 | for (auto it = _scopes.rbegin(); it != _scopes.rend(); ++it) { | 383 | for (auto it = _scopes.rbegin(); it != _scopes.rend(); ++it) { |
381 | if (it->allows) allows = it->allows.get(); | 384 | if (it->allows) allows = it->allows.get(); |
382 | } | 385 | } |
383 | bool checkShadowScopeOnly = false; | 386 | bool checkShadowScopeOnly = false; |
@@ -524,8 +527,10 @@ private: | |||
524 | } | 527 | } |
525 | 528 | ||
526 | std::string join(const str_list& items) { | 529 | std::string join(const str_list& items) { |
527 | if (items.empty()) return Empty; | 530 | if (items.empty()) |
528 | else if (items.size() == 1) return items.front(); | 531 | return Empty; |
532 | else if (items.size() == 1) | ||
533 | return items.front(); | ||
529 | for (const auto& item : items) { | 534 | for (const auto& item : items) { |
530 | _joinBuf << item; | 535 | _joinBuf << item; |
531 | } | 536 | } |
@@ -536,8 +541,10 @@ private: | |||
536 | } | 541 | } |
537 | 542 | ||
538 | std::string join(const str_list& items, std::string_view sep) { | 543 | std::string join(const str_list& items, std::string_view sep) { |
539 | if (items.empty()) return Empty; | 544 | if (items.empty()) |
540 | else if (items.size() == 1) return items.front(); | 545 | return Empty; |
546 | else if (items.size() == 1) | ||
547 | return items.front(); | ||
541 | std::string sepStr = std::string(sep); | 548 | std::string sepStr = std::string(sep); |
542 | auto begin = ++items.begin(); | 549 | auto begin = ++items.begin(); |
543 | _joinBuf << items.front(); | 550 | _joinBuf << items.front(); |
@@ -659,7 +666,8 @@ private: | |||
659 | 666 | ||
660 | Statement_t* lastStatementFrom(const node_container& stmts) const { | 667 | Statement_t* lastStatementFrom(const node_container& stmts) const { |
661 | if (!stmts.empty()) { | 668 | if (!stmts.empty()) { |
662 | auto it = stmts.end(); --it; | 669 | auto it = stmts.end(); |
670 | --it; | ||
663 | while (!static_cast<Statement_t*>(*it)->content && it != stmts.begin()) { | 671 | while (!static_cast<Statement_t*>(*it)->content && it != stmts.begin()) { |
664 | --it; | 672 | --it; |
665 | } | 673 | } |
@@ -864,15 +872,17 @@ private: | |||
864 | case id<SelfName_t>(): | 872 | case id<SelfName_t>(): |
865 | return true; | 873 | return true; |
866 | } | 874 | } |
867 | } else switch (firstItem->getId()) { | 875 | } else |
868 | case id<DotChainItem_t>(): | 876 | switch (firstItem->getId()) { |
869 | case id<Exp_t>(): | 877 | case id<DotChainItem_t>(): |
870 | return true; | 878 | case id<Exp_t>(): |
871 | } | 879 | return true; |
880 | } | ||
872 | } else { | 881 | } else { |
873 | if (std::find_if(chainItems.begin(), chainItems.end(), [](ast_node* node) { | 882 | if (std::find_if(chainItems.begin(), chainItems.end(), [](ast_node* node) { |
874 | return ast_is<existential_op_t>(node); | 883 | return ast_is<existential_op_t>(node); |
875 | }) != chainItems.end()) { | 884 | }) |
885 | != chainItems.end()) { | ||
876 | return false; | 886 | return false; |
877 | } | 887 | } |
878 | auto lastItem = chainItems.back(); | 888 | auto lastItem = chainItems.back(); |
@@ -1155,7 +1165,7 @@ private: | |||
1155 | break; | 1165 | break; |
1156 | } | 1166 | } |
1157 | } | 1167 | } |
1158 | } else if (expList->exprs.size() == 1){ | 1168 | } else if (expList->exprs.size() == 1) { |
1159 | auto exp = static_cast<Exp_t*>(expList->exprs.back()); | 1169 | auto exp = static_cast<Exp_t*>(expList->exprs.back()); |
1160 | if (isPureBackcall(exp)) { | 1170 | if (isPureBackcall(exp)) { |
1161 | transformExp(exp, out, ExpUsage::Common); | 1171 | transformExp(exp, out, ExpUsage::Common); |
@@ -1277,7 +1287,7 @@ private: | |||
1277 | } | 1287 | } |
1278 | } | 1288 | } |
1279 | } | 1289 | } |
1280 | if (!defs.empty()) _buf << indent() << "local "sv << join(defs,", "sv); | 1290 | if (!defs.empty()) _buf << indent() << "local "sv << join(defs, ", "sv); |
1281 | } | 1291 | } |
1282 | } | 1292 | } |
1283 | return clearBuf(); | 1293 | return clearBuf(); |
@@ -1392,15 +1402,15 @@ private: | |||
1392 | auto j = values.begin(); | 1402 | auto j = values.begin(); |
1393 | auto je = --values.end(); | 1403 | auto je = --values.end(); |
1394 | while (j != je) { | 1404 | while (j != je) { |
1395 | ++i; ++j; | 1405 | ++i; |
1406 | ++j; | ||
1396 | } | 1407 | } |
1397 | bool holdItem = false; | 1408 | bool holdItem = false; |
1398 | for (auto it = i; it != exprs.end(); ++it) { | 1409 | for (auto it = i; it != exprs.end(); ++it) { |
1399 | BLOCK_START | 1410 | BLOCK_START |
1400 | auto value = singleValueFrom(*it); | 1411 | auto value = singleValueFrom(*it); |
1401 | BREAK_IF(!value); | 1412 | BREAK_IF(!value); |
1402 | if (value->item.is<simple_table_t>() || | 1413 | if (value->item.is<simple_table_t>() || value->getByPath<SimpleValue_t, TableLit_t>()) { |
1403 | value->getByPath<SimpleValue_t, TableLit_t>()) { | ||
1404 | holdItem = true; | 1414 | holdItem = true; |
1405 | break; | 1415 | break; |
1406 | } | 1416 | } |
@@ -1524,7 +1534,8 @@ private: | |||
1524 | popScope(); | 1534 | popScope(); |
1525 | temp.push_back(indent() + "end"s + nlr(x)); | 1535 | temp.push_back(indent() + "end"s + nlr(x)); |
1526 | } | 1536 | } |
1527 | } else break; | 1537 | } else |
1538 | break; | ||
1528 | auto newExpList = x->new_ptr<ExpList_t>(); | 1539 | auto newExpList = x->new_ptr<ExpList_t>(); |
1529 | auto newAssign = x->new_ptr<Assign_t>(); | 1540 | auto newAssign = x->new_ptr<Assign_t>(); |
1530 | auto newAssignment = x->new_ptr<ExpListAssign_t>(); | 1541 | auto newAssignment = x->new_ptr<ExpListAssign_t>(); |
@@ -1946,13 +1957,12 @@ private: | |||
1946 | switch (pair->getId()) { | 1957 | switch (pair->getId()) { |
1947 | case id<Exp_t>(): { | 1958 | case id<Exp_t>(): { |
1948 | ++index; | 1959 | ++index; |
1949 | if (!isAssignable(static_cast<Exp_t*>(pair))) { | 1960 | if (!isAssignable(static_cast<Exp_t*>(pair))) { |
1950 | throw std::logic_error(_info.errorMessage("can't destructure value"sv, pair)); | 1961 | throw std::logic_error(_info.errorMessage("can't destructure value"sv, pair)); |
1951 | } | 1962 | } |
1952 | auto value = singleValueFrom(pair); | 1963 | auto value = singleValueFrom(pair); |
1953 | auto item = value->item.get(); | 1964 | auto item = value->item.get(); |
1954 | if (ast_is<simple_table_t>(item) || | 1965 | if (ast_is<simple_table_t>(item) || item->getByPath<TableLit_t>()) { |
1955 | item->getByPath<TableLit_t>()) { | ||
1956 | auto subPairs = destructFromExp(pair, optional); | 1966 | auto subPairs = destructFromExp(pair, optional); |
1957 | for (auto& p : subPairs) { | 1967 | for (auto& p : subPairs) { |
1958 | pairs.push_back({p.target, p.targetVar, | 1968 | pairs.push_back({p.target, p.targetVar, |
@@ -1963,12 +1973,10 @@ private: | |||
1963 | auto exp = static_cast<Exp_t*>(pair); | 1973 | auto exp = static_cast<Exp_t*>(pair); |
1964 | auto varName = singleVariableFrom(exp, false); | 1974 | auto varName = singleVariableFrom(exp, false); |
1965 | if (varName == "_"sv) break; | 1975 | if (varName == "_"sv) break; |
1966 | pairs.push_back({ | 1976 | pairs.push_back({exp, |
1967 | exp, | ||
1968 | varName, | 1977 | varName, |
1969 | '[' + std::to_string(index) + ']', | 1978 | '[' + std::to_string(index) + ']', |
1970 | nullptr | 1979 | nullptr}); |
1971 | }); | ||
1972 | } | 1980 | } |
1973 | break; | 1981 | break; |
1974 | } | 1982 | } |
@@ -1994,37 +2002,30 @@ private: | |||
1994 | if (auto exp = np->value.as<Exp_t>()) { | 2002 | if (auto exp = np->value.as<Exp_t>()) { |
1995 | if (!isAssignable(exp)) throw std::logic_error(_info.errorMessage("can't destructure value"sv, exp)); | 2003 | if (!isAssignable(exp)) throw std::logic_error(_info.errorMessage("can't destructure value"sv, exp)); |
1996 | auto item = singleValueFrom(exp)->item.get(); | 2004 | auto item = singleValueFrom(exp)->item.get(); |
1997 | if (ast_is<simple_table_t>(item) || | 2005 | if (ast_is<simple_table_t>(item) || item->getByPath<TableLit_t>()) { |
1998 | item->getByPath<TableLit_t>()) { | ||
1999 | auto subPairs = destructFromExp(exp, optional); | 2006 | auto subPairs = destructFromExp(exp, optional); |
2000 | for (auto& p : subPairs) { | 2007 | for (auto& p : subPairs) { |
2001 | pairs.push_back({ | 2008 | pairs.push_back({p.target, |
2002 | p.target, | ||
2003 | p.targetVar, | 2009 | p.targetVar, |
2004 | keyName + sep + p.structure, | 2010 | keyName + sep + p.structure, |
2005 | p.defVal | 2011 | p.defVal}); |
2006 | }); | ||
2007 | } | 2012 | } |
2008 | } else { | 2013 | } else { |
2009 | auto varName = singleVariableFrom(exp, false); | 2014 | auto varName = singleVariableFrom(exp, false); |
2010 | pairs.push_back({ | 2015 | pairs.push_back({exp, |
2011 | exp, | ||
2012 | varName, | 2016 | varName, |
2013 | keyName, | 2017 | keyName, |
2014 | nullptr | 2018 | nullptr}); |
2015 | }); | ||
2016 | } | 2019 | } |
2017 | break; | 2020 | break; |
2018 | } | 2021 | } |
2019 | if (np->value.is<TableBlock_t>()) { | 2022 | if (np->value.is<TableBlock_t>()) { |
2020 | auto subPairs = destructFromExp(np->value, optional); | 2023 | auto subPairs = destructFromExp(np->value, optional); |
2021 | for (auto& p : subPairs) { | 2024 | for (auto& p : subPairs) { |
2022 | pairs.push_back({ | 2025 | pairs.push_back({p.target, |
2023 | p.target, | ||
2024 | p.targetVar, | 2026 | p.targetVar, |
2025 | keyName + sep + p.structure, | 2027 | keyName + sep + p.structure, |
2026 | p.defVal | 2028 | p.defVal}); |
2027 | }); | ||
2028 | } | 2029 | } |
2029 | } | 2030 | } |
2030 | break; | 2031 | break; |
@@ -2034,16 +2035,14 @@ private: | |||
2034 | ++index; | 2035 | ++index; |
2035 | auto subPairs = destructFromExp(tb, optional); | 2036 | auto subPairs = destructFromExp(tb, optional); |
2036 | for (auto& p : subPairs) { | 2037 | for (auto& p : subPairs) { |
2037 | pairs.push_back({ | 2038 | pairs.push_back({p.target, |
2038 | p.target, | ||
2039 | p.targetVar, | 2039 | p.targetVar, |
2040 | '[' + std::to_string(index) + ']' + sep + p.structure, | 2040 | '[' + std::to_string(index) + ']' + sep + p.structure, |
2041 | p.defVal | 2041 | p.defVal}); |
2042 | }); | ||
2043 | } | 2042 | } |
2044 | break; | 2043 | break; |
2045 | } | 2044 | } |
2046 | case id<default_pair_t>() : { | 2045 | case id<default_pair_t>(): { |
2047 | auto dp = static_cast<default_pair_t*>(pair); | 2046 | auto dp = static_cast<default_pair_t*>(pair); |
2048 | if (auto exp = dp->key.as<Exp_t>()) { | 2047 | if (auto exp = dp->key.as<Exp_t>()) { |
2049 | ++index; | 2048 | ++index; |
@@ -2052,17 +2051,14 @@ private: | |||
2052 | } | 2051 | } |
2053 | auto value = singleValueFrom(exp); | 2052 | auto value = singleValueFrom(exp); |
2054 | auto item = value->item.get(); | 2053 | auto item = value->item.get(); |
2055 | if (ast_is<simple_table_t>(item) || | 2054 | if (ast_is<simple_table_t>(item) || item->getByPath<TableLit_t>()) { |
2056 | item->getByPath<TableLit_t>()) { | ||
2057 | throw std::logic_error(_info.errorMessage("invalid use of default value"sv, dp->defVal)); | 2055 | throw std::logic_error(_info.errorMessage("invalid use of default value"sv, dp->defVal)); |
2058 | } else { | 2056 | } else { |
2059 | auto varName = singleVariableFrom(exp, false); | 2057 | auto varName = singleVariableFrom(exp, false); |
2060 | pairs.push_back({ | 2058 | pairs.push_back({exp, |
2061 | exp, | ||
2062 | varName, | 2059 | varName, |
2063 | '[' + std::to_string(index) + ']', | 2060 | '[' + std::to_string(index) + ']', |
2064 | dp->defVal | 2061 | dp->defVal}); |
2065 | }); | ||
2066 | } | 2062 | } |
2067 | break; | 2063 | break; |
2068 | } | 2064 | } |
@@ -2081,19 +2077,15 @@ private: | |||
2081 | if (auto exp = dp->value.get()) { | 2077 | if (auto exp = dp->value.get()) { |
2082 | if (!isAssignable(exp)) throw std::logic_error(_info.errorMessage("can't destructure value"sv, exp)); | 2078 | if (!isAssignable(exp)) throw std::logic_error(_info.errorMessage("can't destructure value"sv, exp)); |
2083 | auto varName = singleVariableFrom(exp, false); | 2079 | auto varName = singleVariableFrom(exp, false); |
2084 | pairs.push_back({ | 2080 | pairs.push_back({exp, |
2085 | exp, | ||
2086 | varName, | 2081 | varName, |
2087 | keyName, | 2082 | keyName, |
2088 | dp->defVal | 2083 | dp->defVal}); |
2089 | }); | ||
2090 | } else { | 2084 | } else { |
2091 | pairs.push_back({ | 2085 | pairs.push_back({toAst<Exp_t>(valueStr, dp).get(), |
2092 | toAst<Exp_t>(valueStr, dp).get(), | ||
2093 | valueStr, | 2086 | valueStr, |
2094 | keyName, | 2087 | keyName, |
2095 | dp->defVal | 2088 | dp->defVal}); |
2096 | }); | ||
2097 | } | 2089 | } |
2098 | break; | 2090 | break; |
2099 | } | 2091 | } |
@@ -2157,12 +2149,10 @@ private: | |||
2157 | value->item.set(simpleValue); | 2149 | value->item.set(simpleValue); |
2158 | auto subPairs = destructFromExp(newExp(value, subMetaDestruct), optional); | 2150 | auto subPairs = destructFromExp(newExp(value, subMetaDestruct), optional); |
2159 | for (const auto& p : subPairs) { | 2151 | for (const auto& p : subPairs) { |
2160 | pairs.push_back({ | 2152 | pairs.push_back({p.target, |
2161 | p.target, | ||
2162 | p.targetVar, | 2153 | p.targetVar, |
2163 | ".#"s + (p.structure.empty() ? Empty : sep + p.structure), | 2154 | ".#"s + (p.structure.empty() ? Empty : sep + p.structure), |
2164 | p.defVal | 2155 | p.defVal}); |
2165 | }); | ||
2166 | } | 2156 | } |
2167 | } | 2157 | } |
2168 | return pairs; | 2158 | return pairs; |
@@ -2373,8 +2363,7 @@ private: | |||
2373 | if (!leftValue) throw std::logic_error(_info.errorMessage("left hand expression is not assignable"sv, leftExp)); | 2363 | if (!leftValue) throw std::logic_error(_info.errorMessage("left hand expression is not assignable"sv, leftExp)); |
2374 | auto chain = leftValue->item.as<ChainValue_t>(); | 2364 | auto chain = leftValue->item.as<ChainValue_t>(); |
2375 | if (!chain) throw std::logic_error(_info.errorMessage("left hand expression is not assignable"sv, leftValue)); | 2365 | if (!chain) throw std::logic_error(_info.errorMessage("left hand expression is not assignable"sv, leftValue)); |
2376 | BLOCK_START | 2366 | BLOCK_START { |
2377 | { | ||
2378 | auto dot = ast_cast<DotChainItem_t>(chain->items.back()); | 2367 | auto dot = ast_cast<DotChainItem_t>(chain->items.back()); |
2379 | if (dot && dot->name.is<Metatable_t>()) { | 2368 | if (dot && dot->name.is<Metatable_t>()) { |
2380 | throw std::logic_error(_info.errorMessage("can not apply update to a metatable"sv, leftExp)); | 2369 | throw std::logic_error(_info.errorMessage("can not apply update to a metatable"sv, leftExp)); |
@@ -2457,10 +2446,11 @@ private: | |||
2457 | right = '(' + right + ')'; | 2446 | right = '(' + right + ')'; |
2458 | } | 2447 | } |
2459 | _buf << join(temp); | 2448 | _buf << join(temp); |
2460 | if (!defs.empty()) _buf << defs; | 2449 | if (!defs.empty()) |
2461 | else _buf << indent() << left; | 2450 | _buf << defs; |
2462 | _buf << " = "sv << left << | 2451 | else |
2463 | ' ' << op << ' ' << right << nll(assignment); | 2452 | _buf << indent() << left; |
2453 | _buf << " = "sv << left << ' ' << op << ' ' << right << nll(assignment); | ||
2464 | out.push_back(clearBuf()); | 2454 | out.push_back(clearBuf()); |
2465 | break; | 2455 | break; |
2466 | } | 2456 | } |
@@ -2709,7 +2699,8 @@ private: | |||
2709 | } else { | 2699 | } else { |
2710 | auto x = values.front(); | 2700 | auto x = values.front(); |
2711 | auto arg = newExp(static_cast<unary_exp_t*>(x), x); | 2701 | auto arg = newExp(static_cast<unary_exp_t*>(x), x); |
2712 | auto begin = values.begin(); begin++; | 2702 | auto begin = values.begin(); |
2703 | begin++; | ||
2713 | for (auto it = begin; it != values.end(); ++it) { | 2704 | for (auto it = begin; it != values.end(); ++it) { |
2714 | auto unary = static_cast<unary_exp_t*>(*it); | 2705 | auto unary = static_cast<unary_exp_t*>(*it); |
2715 | auto value = static_cast<Value_t*>(singleUnaryExpFrom(unary) ? unary->expos.back() : nullptr); | 2706 | auto value = static_cast<Value_t*>(singleUnaryExpFrom(unary) ? unary->expos.back() : nullptr); |
@@ -2943,7 +2934,7 @@ private: | |||
2943 | } | 2934 | } |
2944 | } | 2935 | } |
2945 | 2936 | ||
2946 | void transformCallable(Callable_t* callable, str_list& out, const ast_sel<false,Invoke_t,InvokeArgs_t>& invoke = {}) { | 2937 | void transformCallable(Callable_t* callable, str_list& out, const ast_sel<false, Invoke_t, InvokeArgs_t>& invoke = {}) { |
2947 | auto item = callable->item.get(); | 2938 | auto item = callable->item.get(); |
2948 | switch (item->getId()) { | 2939 | switch (item->getId()) { |
2949 | case id<Variable_t>(): { | 2940 | case id<Variable_t>(): { |
@@ -3042,9 +3033,7 @@ private: | |||
3042 | temp.push_back(Empty); | 3033 | temp.push_back(Empty); |
3043 | } | 3034 | } |
3044 | auto& bodyCodes = temp.back(); | 3035 | auto& bodyCodes = temp.back(); |
3045 | _buf << "function("sv << | 3036 | _buf << "function("sv << (isFatArrow ? "self"s : Empty) << ')'; |
3046 | (isFatArrow ? "self"s : Empty) << | ||
3047 | ')'; | ||
3048 | if (!bodyCodes.empty()) { | 3037 | if (!bodyCodes.empty()) { |
3049 | _buf << nll(funLit) << bodyCodes; | 3038 | _buf << nll(funLit) << bodyCodes; |
3050 | popScope(); | 3039 | popScope(); |
@@ -3077,7 +3066,7 @@ private: | |||
3077 | } | 3066 | } |
3078 | const auto& nodes = block->statements.objects(); | 3067 | const auto& nodes = block->statements.objects(); |
3079 | LocalMode mode = LocalMode::None; | 3068 | LocalMode mode = LocalMode::None; |
3080 | Local_t* any = nullptr, *capital = nullptr; | 3069 | Local_t *any = nullptr, *capital = nullptr; |
3081 | for (auto it = nodes.begin(); it != nodes.end(); ++it) { | 3070 | for (auto it = nodes.begin(); it != nodes.end(); ++it) { |
3082 | auto node = *it; | 3071 | auto node = *it; |
3083 | auto stmt = static_cast<Statement_t*>(node); | 3072 | auto stmt = static_cast<Statement_t*>(node); |
@@ -3086,7 +3075,8 @@ private: | |||
3086 | bool cond = false; | 3075 | bool cond = false; |
3087 | BLOCK_START | 3076 | BLOCK_START |
3088 | BREAK_IF(it == nodes.begin()); | 3077 | BREAK_IF(it == nodes.begin()); |
3089 | auto last = it; --last; | 3078 | auto last = it; |
3079 | --last; | ||
3090 | auto lst = static_cast<Statement_t*>(*last); | 3080 | auto lst = static_cast<Statement_t*>(*last); |
3091 | if (lst->appendix) { | 3081 | if (lst->appendix) { |
3092 | throw std::logic_error(_info.errorMessage("statement decorator must be placed at the end of pipe chain"sv, lst->appendix.get())); | 3082 | throw std::logic_error(_info.errorMessage("statement decorator must be placed at the end of pipe chain"sv, lst->appendix.get())); |
@@ -3104,7 +3094,8 @@ private: | |||
3104 | BLOCK_END | 3094 | BLOCK_END |
3105 | if (!cond) throw std::logic_error(_info.errorMessage("pipe chain must be following a value"sv, x)); | 3095 | if (!cond) throw std::logic_error(_info.errorMessage("pipe chain must be following a value"sv, x)); |
3106 | stmt->content.set(nullptr); | 3096 | stmt->content.set(nullptr); |
3107 | auto next = it; ++next; | 3097 | auto next = it; |
3098 | ++next; | ||
3108 | BLOCK_START | 3099 | BLOCK_START |
3109 | BREAK_IF(next == nodes.end()); | 3100 | BREAK_IF(next == nodes.end()); |
3110 | BREAK_IF(!static_cast<Statement_t*>(*next)->content.as<PipeBody_t>()); | 3101 | BREAK_IF(!static_cast<Statement_t*>(*next)->content.as<PipeBody_t>()); |
@@ -3122,7 +3113,8 @@ private: | |||
3122 | ast_ptr<false, Exp_t> arg; | 3113 | ast_ptr<false, Exp_t> arg; |
3123 | { | 3114 | { |
3124 | auto block = x->new_ptr<Block_t>(); | 3115 | auto block = x->new_ptr<Block_t>(); |
3125 | auto next = it; ++next; | 3116 | auto next = it; |
3117 | ++next; | ||
3126 | if (next != nodes.end()) { | 3118 | if (next != nodes.end()) { |
3127 | for (auto i = next; i != nodes.end(); ++i) { | 3119 | for (auto i = next; i != nodes.end(); ++i) { |
3128 | block->statements.push_back(*i); | 3120 | block->statements.push_back(*i); |
@@ -3240,7 +3232,8 @@ private: | |||
3240 | for (const auto& destruct : info.destructures) | 3232 | for (const auto& destruct : info.destructures) |
3241 | for (const auto& item : destruct.items) | 3233 | for (const auto& item : destruct.items) |
3242 | if (!item.targetVar.empty()) { | 3234 | if (!item.targetVar.empty()) { |
3243 | if (std::isupper(item.targetVar[0]) && capital) { capital->decls.push_back(item.targetVar); | 3235 | if (std::isupper(item.targetVar[0]) && capital) { |
3236 | capital->decls.push_back(item.targetVar); | ||
3244 | } else if (any) { | 3237 | } else if (any) { |
3245 | any->decls.push_back(item.targetVar); | 3238 | any->decls.push_back(item.targetVar); |
3246 | } | 3239 | } |
@@ -3249,7 +3242,8 @@ private: | |||
3249 | if (info.assignment) { | 3242 | if (info.assignment) { |
3250 | auto defs = transformAssignDefs(info.assignment->expList, DefOp::Get); | 3243 | auto defs = transformAssignDefs(info.assignment->expList, DefOp::Get); |
3251 | for (const auto& def : defs) { | 3244 | for (const auto& def : defs) { |
3252 | if (std::isupper(def[0]) && capital) { capital->decls.push_back(def); | 3245 | if (std::isupper(def[0]) && capital) { |
3246 | capital->decls.push_back(def); | ||
3253 | } else if (any) { | 3247 | } else if (any) { |
3254 | any->decls.push_back(def); | 3248 | any->decls.push_back(def); |
3255 | } | 3249 | } |
@@ -3295,9 +3289,7 @@ private: | |||
3295 | BREAK_IF(!last); | 3289 | BREAK_IF(!last); |
3296 | auto x = last; | 3290 | auto x = last; |
3297 | auto expList = expListFrom(last); | 3291 | auto expList = expListFrom(last); |
3298 | BREAK_IF(!expList || | 3292 | BREAK_IF(!expList || (last->appendix && last->appendix->item.is<CompInner_t>())); |
3299 | (last->appendix && | ||
3300 | last->appendix->item.is<CompInner_t>())); | ||
3301 | auto expListLow = x->new_ptr<ExpListLow_t>(); | 3293 | auto expListLow = x->new_ptr<ExpListLow_t>(); |
3302 | expListLow->exprs.dup(expList->exprs); | 3294 | expListLow->exprs.dup(expList->exprs); |
3303 | auto returnNode = x->new_ptr<Return_t>(); | 3295 | auto returnNode = x->new_ptr<Return_t>(); |
@@ -3764,14 +3756,18 @@ private: | |||
3764 | _buf << indent() << "end"sv << nll(def); | 3756 | _buf << indent() << "end"sv << nll(def); |
3765 | temp.back() = clearBuf(); | 3757 | temp.back() = clearBuf(); |
3766 | } | 3758 | } |
3767 | if (varNames.empty()) varNames = arg.name; | 3759 | if (varNames.empty()) |
3768 | else varNames.append(", "s + arg.name); | 3760 | varNames = arg.name; |
3761 | else | ||
3762 | varNames.append(", "s + arg.name); | ||
3769 | } | 3763 | } |
3770 | if (argDefList->varArg) { | 3764 | if (argDefList->varArg) { |
3771 | auto& arg = argItems.emplace_back(); | 3765 | auto& arg = argItems.emplace_back(); |
3772 | arg.name = "..."sv; | 3766 | arg.name = "..."sv; |
3773 | if (varNames.empty()) varNames = arg.name; | 3767 | if (varNames.empty()) |
3774 | else varNames.append(", "s + arg.name); | 3768 | varNames = arg.name; |
3769 | else | ||
3770 | varNames.append(", "s + arg.name); | ||
3775 | _varArgs.top().hasVar = true; | 3771 | _varArgs.top().hasVar = true; |
3776 | } | 3772 | } |
3777 | if (assignSelf) { | 3773 | if (assignSelf) { |
@@ -3790,7 +3786,7 @@ private: | |||
3790 | out.push_back(join(temp)); | 3786 | out.push_back(join(temp)); |
3791 | } | 3787 | } |
3792 | 3788 | ||
3793 | void transformSelfName(SelfName_t* selfName, str_list& out, const ast_sel<false,Invoke_t,InvokeArgs_t>& invoke = {}) { | 3789 | void transformSelfName(SelfName_t* selfName, str_list& out, const ast_sel<false, Invoke_t, InvokeArgs_t>& invoke = {}) { |
3794 | auto x = selfName; | 3790 | auto x = selfName; |
3795 | auto name = selfName->name.get(); | 3791 | auto name = selfName->name.get(); |
3796 | switch (name->getId()) { | 3792 | switch (name->getId()) { |
@@ -3899,7 +3895,7 @@ private: | |||
3899 | pushScope(); | 3895 | pushScope(); |
3900 | } | 3896 | } |
3901 | auto partOne = x->new_ptr<ChainValue_t>(); | 3897 | auto partOne = x->new_ptr<ChainValue_t>(); |
3902 | for (auto it = chainList.begin();it != opIt;++it) { | 3898 | for (auto it = chainList.begin(); it != opIt; ++it) { |
3903 | partOne->items.push_back(*it); | 3899 | partOne->items.push_back(*it); |
3904 | } | 3900 | } |
3905 | BLOCK_START | 3901 | BLOCK_START |
@@ -3972,7 +3968,8 @@ private: | |||
3972 | partOne->items.clear(); | 3968 | partOne->items.clear(); |
3973 | partOne->items.push_back(toAst<Callable_t>(objVar, x)); | 3969 | partOne->items.push_back(toAst<Callable_t>(objVar, x)); |
3974 | partOne->items.push_back(dotItem); | 3970 | partOne->items.push_back(dotItem); |
3975 | auto it = opIt; ++it; | 3971 | auto it = opIt; |
3972 | ++it; | ||
3976 | if (it != chainList.end() && ast_is<Invoke_t, InvokeArgs_t>(*it)) { | 3973 | if (it != chainList.end() && ast_is<Invoke_t, InvokeArgs_t>(*it)) { |
3977 | 3974 | ||
3978 | if (auto invoke = ast_cast<Invoke_t>(*it)) { | 3975 | if (auto invoke = ast_cast<Invoke_t>(*it)) { |
@@ -3999,7 +3996,7 @@ private: | |||
3999 | pushScope(); | 3996 | pushScope(); |
4000 | auto partTwo = x->new_ptr<ChainValue_t>(); | 3997 | auto partTwo = x->new_ptr<ChainValue_t>(); |
4001 | partTwo->items.push_back(toAst<Callable_t>(objVar, x)); | 3998 | partTwo->items.push_back(toAst<Callable_t>(objVar, x)); |
4002 | for (auto it = ++opIt;it != chainList.end();++it) { | 3999 | for (auto it = ++opIt; it != chainList.end(); ++it) { |
4003 | partTwo->items.push_back(*it); | 4000 | partTwo->items.push_back(*it); |
4004 | } | 4001 | } |
4005 | switch (usage) { | 4002 | switch (usage) { |
@@ -4248,7 +4245,8 @@ private: | |||
4248 | case id<ColonChainItem_t>(): { | 4245 | case id<ColonChainItem_t>(): { |
4249 | auto colonItem = static_cast<ColonChainItem_t*>(item); | 4246 | auto colonItem = static_cast<ColonChainItem_t*>(item); |
4250 | auto current = it; | 4247 | auto current = it; |
4251 | auto next = current; ++next; | 4248 | auto next = current; |
4249 | ++next; | ||
4252 | auto followItem = next != chainList.end() ? *next : nullptr; | 4250 | auto followItem = next != chainList.end() ? *next : nullptr; |
4253 | if (current != chainList.begin()) { | 4251 | if (current != chainList.begin()) { |
4254 | --current; | 4252 | --current; |
@@ -4272,7 +4270,7 @@ private: | |||
4272 | switch (chainList.front()->getId()) { | 4270 | switch (chainList.front()->getId()) { |
4273 | case id<DotChainItem_t>(): | 4271 | case id<DotChainItem_t>(): |
4274 | case id<ColonChainItem_t>(): | 4272 | case id<ColonChainItem_t>(): |
4275 | chainValue->items.push_back(toAst<Callable_t>(_withVars.top(), x)); | 4273 | chainValue->items.push_back(toAst<Callable_t>(_withVars.top(), x)); |
4276 | break; | 4274 | break; |
4277 | } | 4275 | } |
4278 | for (auto i = chainList.begin(); i != current; ++i) { | 4276 | for (auto i = chainList.begin(); i != current; ++i) { |
@@ -4366,7 +4364,8 @@ private: | |||
4366 | transformSlice(static_cast<Slice_t*>(item), temp); | 4364 | transformSlice(static_cast<Slice_t*>(item), temp); |
4367 | break; | 4365 | break; |
4368 | case id<Callable_t>(): { | 4366 | case id<Callable_t>(): { |
4369 | auto next = it; ++next; | 4367 | auto next = it; |
4368 | ++next; | ||
4370 | auto followItem = next != chainList.end() ? *next : nullptr; | 4369 | auto followItem = next != chainList.end() ? *next : nullptr; |
4371 | ast_sel<false, Invoke_t, InvokeArgs_t> invoke; | 4370 | ast_sel<false, Invoke_t, InvokeArgs_t> invoke; |
4372 | if (ast_is<Invoke_t, InvokeArgs_t>(followItem)) { | 4371 | if (ast_is<Invoke_t, InvokeArgs_t>(followItem)) { |
@@ -4464,7 +4463,7 @@ private: | |||
4464 | return Empty; | 4463 | return Empty; |
4465 | } | 4464 | } |
4466 | 4465 | ||
4467 | std::tuple<std::string,std::string,str_list> expandMacroStr(ChainValue_t* chainValue) { | 4466 | std::tuple<std::string, std::string, str_list> expandMacroStr(ChainValue_t* chainValue) { |
4468 | const auto& chainList = chainValue->items.objects(); | 4467 | const auto& chainList = chainValue->items.objects(); |
4469 | auto x = ast_to<Callable_t>(chainList.front())->item.to<MacroName_t>(); | 4468 | auto x = ast_to<Callable_t>(chainList.front())->item.to<MacroName_t>(); |
4470 | auto macroName = _parser.toString(x->name); | 4469 | auto macroName = _parser.toString(x->name); |
@@ -4490,7 +4489,7 @@ private: | |||
4490 | auto item = *(++chainList.begin()); | 4489 | auto item = *(++chainList.begin()); |
4491 | if (auto invoke = ast_cast<Invoke_t>(item)) { | 4490 | if (auto invoke = ast_cast<Invoke_t>(item)) { |
4492 | args = &invoke->args.objects(); | 4491 | args = &invoke->args.objects(); |
4493 | } else if (auto invoke = ast_cast<InvokeArgs_t>(item)){ | 4492 | } else if (auto invoke = ast_cast<InvokeArgs_t>(item)) { |
4494 | args = &invoke->args.objects(); | 4493 | args = &invoke->args.objects(); |
4495 | } | 4494 | } |
4496 | } | 4495 | } |
@@ -4599,7 +4598,7 @@ private: | |||
4599 | return {type, codes, std::move(localVars)}; | 4598 | return {type, codes, std::move(localVars)}; |
4600 | } | 4599 | } |
4601 | 4600 | ||
4602 | std::tuple<ast_ptr<false,ast_node>, std::unique_ptr<input>, std::string, str_list> expandMacro(ChainValue_t* chainValue, ExpUsage usage, bool allowBlockMacroReturn) { | 4601 | std::tuple<ast_ptr<false, ast_node>, std::unique_ptr<input>, std::string, str_list> expandMacro(ChainValue_t* chainValue, ExpUsage usage, bool allowBlockMacroReturn) { |
4603 | auto x = ast_to<Callable_t>(chainValue->items.front())->item.to<MacroName_t>(); | 4602 | auto x = ast_to<Callable_t>(chainValue->items.front())->item.to<MacroName_t>(); |
4604 | const auto& chainList = chainValue->items.objects(); | 4603 | const auto& chainList = chainValue->items.objects(); |
4605 | std::string type, codes; | 4604 | std::string type, codes; |
@@ -4928,10 +4927,10 @@ private: | |||
4928 | forceAddToScope(indexVar); | 4927 | forceAddToScope(indexVar); |
4929 | temp.push_back(indent() + "local "s + indexVar + " = 1"s + nll(item)); | 4928 | temp.push_back(indent() + "local "s + indexVar + " = 1"s + nll(item)); |
4930 | _buf << "for "sv << keyVar << ',' << valueVar << " in pairs "sv << objVar | 4929 | _buf << "for "sv << keyVar << ',' << valueVar << " in pairs "sv << objVar |
4931 | << "\n\tif "sv << indexVar << "=="sv << keyVar | 4930 | << "\n\tif "sv << indexVar << "=="sv << keyVar |
4932 | << "\n\t\t"sv << tableVar << "[]="sv << valueVar | 4931 | << "\n\t\t"sv << tableVar << "[]="sv << valueVar |
4933 | << "\n\t\t"sv << indexVar << "+=1"sv | 4932 | << "\n\t\t"sv << indexVar << "+=1"sv |
4934 | << "\n\telse "sv << tableVar << '[' << keyVar << "]="sv << valueVar; | 4933 | << "\n\telse "sv << tableVar << '[' << keyVar << "]="sv << valueVar; |
4935 | auto forEach = toAst<ForEach_t>(clearBuf(), item); | 4934 | auto forEach = toAst<ForEach_t>(clearBuf(), item); |
4936 | transformForEach(forEach, temp); | 4935 | transformForEach(forEach, temp); |
4937 | break; | 4936 | break; |
@@ -4998,7 +4997,7 @@ private: | |||
4998 | auto chainValue = value->item.as<ChainValue_t>(); | 4997 | auto chainValue = value->item.as<ChainValue_t>(); |
4999 | BREAK_IF(!chainValue); | 4998 | BREAK_IF(!chainValue); |
5000 | BREAK_IF(chainValue->items.size() != 1); | 4999 | BREAK_IF(chainValue->items.size() != 1); |
5001 | BREAK_IF((!chainValue->getByPath<Callable_t,VarArg_t>())); | 5000 | BREAK_IF((!chainValue->getByPath<Callable_t, VarArg_t>())); |
5002 | auto indexVar = getUnusedName("_index_"); | 5001 | auto indexVar = getUnusedName("_index_"); |
5003 | _buf << "for "sv << indexVar << "=1,select '#',...\n\t"sv << tableVar << "[]= select "sv << indexVar << ",..."sv; | 5002 | _buf << "for "sv << indexVar << "=1,select '#',...\n\t"sv << tableVar << "[]= select "sv << indexVar << ",..."sv; |
5004 | transformFor(toAst<For_t>(clearBuf(), item), temp); | 5003 | transformFor(toAst<For_t>(clearBuf(), item), temp); |
@@ -5098,8 +5097,7 @@ private: | |||
5098 | transformAssignment(assignment, temp); | 5097 | transformAssignment(assignment, temp); |
5099 | popScope(); | 5098 | popScope(); |
5100 | out.push_back(join(temp)); | 5099 | out.push_back(join(temp)); |
5101 | out.back() = indent() + "do"s + nll(x) + | 5100 | out.back() = indent() + "do"s + nll(x) + out.back() + indent() + "end"s + nlr(x); |
5102 | out.back() + indent() + "end"s + nlr(x); | ||
5103 | break; | 5101 | break; |
5104 | } | 5102 | } |
5105 | case ExpUsage::Return: | 5103 | case ExpUsage::Return: |
@@ -5205,14 +5203,15 @@ private: | |||
5205 | str_list tmp; | 5203 | str_list tmp; |
5206 | if (!metatable->pairs.empty()) { | 5204 | if (!metatable->pairs.empty()) { |
5207 | transform_simple_table(metatable, tmp); | 5205 | transform_simple_table(metatable, tmp); |
5208 | } else switch (metatableItem->getId()) { | 5206 | } else |
5209 | case id<Exp_t>(): | 5207 | switch (metatableItem->getId()) { |
5210 | transformExp(static_cast<Exp_t*>(metatableItem.get()), tmp, ExpUsage::Closure); | 5208 | case id<Exp_t>(): |
5211 | break; | 5209 | transformExp(static_cast<Exp_t*>(metatableItem.get()), tmp, ExpUsage::Closure); |
5212 | case id<TableBlock_t>(): | 5210 | break; |
5213 | transformTableBlock(static_cast<TableBlock_t*>(metatableItem.get()), tmp); | 5211 | case id<TableBlock_t>(): |
5214 | break; | 5212 | transformTableBlock(static_cast<TableBlock_t*>(metatableItem.get()), tmp); |
5215 | } | 5213 | break; |
5214 | } | ||
5216 | tabStr += tmp.back(); | 5215 | tabStr += tmp.back(); |
5217 | tabStr += ')'; | 5216 | tabStr += ')'; |
5218 | out.push_back(tabStr); | 5217 | out.push_back(tabStr); |
@@ -5349,9 +5348,7 @@ private: | |||
5349 | assignment->action.set(assign); | 5348 | assignment->action.set(assign); |
5350 | transformAssignment(assignment, temp); | 5349 | transformAssignment(assignment, temp); |
5351 | popScope(); | 5350 | popScope(); |
5352 | out.back() = indent() + "do"s + nll(comp) + | 5351 | out.back() = indent() + "do"s + nll(comp) + out.back() + temp.back() + indent() + "end"s + nlr(comp); |
5353 | out.back() + temp.back() + | ||
5354 | indent() + "end"s + nlr(comp); | ||
5355 | break; | 5352 | break; |
5356 | } | 5353 | } |
5357 | case ExpUsage::Return: | 5354 | case ExpUsage::Return: |
@@ -5529,7 +5526,7 @@ private: | |||
5529 | } | 5526 | } |
5530 | 5527 | ||
5531 | void transformInvokeArgs(InvokeArgs_t* invokeArgs, str_list& out) { | 5528 | void transformInvokeArgs(InvokeArgs_t* invokeArgs, str_list& out) { |
5532 | if (invokeArgs->args.size() > 1) { | 5529 | if (invokeArgs->args.size() > 1) { |
5533 | /* merge all the key-value pairs into one table | 5530 | /* merge all the key-value pairs into one table |
5534 | from arguments in the end */ | 5531 | from arguments in the end */ |
5535 | auto lastArg = invokeArgs->args.back(); | 5532 | auto lastArg = invokeArgs->args.back(); |
@@ -5614,18 +5611,18 @@ private: | |||
5614 | return traversal::Stop == body->traverse([&](ast_node* node) { | 5611 | return traversal::Stop == body->traverse([&](ast_node* node) { |
5615 | if (auto stmt = ast_cast<Statement_t>(node)) { | 5612 | if (auto stmt = ast_cast<Statement_t>(node)) { |
5616 | if (stmt->content.is<BreakLoop_t>()) { | 5613 | if (stmt->content.is<BreakLoop_t>()) { |
5617 | return _parser.toString(stmt->content) == "continue"sv ? | 5614 | return _parser.toString(stmt->content) == "continue"sv ? traversal::Stop : traversal::Return; |
5618 | traversal::Stop : traversal::Return; | ||
5619 | } else if (expListFrom(stmt)) { | 5615 | } else if (expListFrom(stmt)) { |
5620 | return traversal::Continue; | 5616 | return traversal::Continue; |
5621 | } | 5617 | } |
5622 | return traversal::Return; | 5618 | return traversal::Return; |
5623 | } else switch (node->getId()) { | 5619 | } else |
5624 | case id<FunLit_t>(): | 5620 | switch (node->getId()) { |
5625 | case id<Invoke_t>(): | 5621 | case id<FunLit_t>(): |
5626 | case id<InvokeArgs_t>(): | 5622 | case id<Invoke_t>(): |
5627 | return traversal::Return; | 5623 | case id<InvokeArgs_t>(): |
5628 | } | 5624 | return traversal::Return; |
5625 | } | ||
5629 | return traversal::Continue; | 5626 | return traversal::Continue; |
5630 | }); | 5627 | }); |
5631 | } | 5628 | } |
@@ -5781,7 +5778,7 @@ private: | |||
5781 | out.push_back(join(temp)); | 5778 | out.push_back(join(temp)); |
5782 | } | 5779 | } |
5783 | 5780 | ||
5784 | void transformForInPlace(For_t* forNode, str_list& out, ExpList_t* assignExpList = nullptr) { | 5781 | void transformForInPlace(For_t* forNode, str_list& out, ExpList_t* assignExpList = nullptr) { |
5785 | auto x = forNode; | 5782 | auto x = forNode; |
5786 | str_list temp; | 5783 | str_list temp; |
5787 | if (assignExpList) { | 5784 | if (assignExpList) { |
@@ -5807,11 +5804,7 @@ private: | |||
5807 | } | 5804 | } |
5808 | 5805 | ||
5809 | void checkOperatorAvailable(const std::string& op, ast_node* node) { | 5806 | void checkOperatorAvailable(const std::string& op, ast_node* node) { |
5810 | if (op == "&"sv || | 5807 | if (op == "&"sv || op == "~"sv || op == "|"sv || op == ">>"sv || op == "<<"sv) { |
5811 | op == "~"sv || | ||
5812 | op == "|"sv || | ||
5813 | op == ">>"sv || | ||
5814 | op == "<<"sv) { | ||
5815 | if (getLuaTarget(node) < 503) { | 5808 | if (getLuaTarget(node) < 503) { |
5816 | throw std::logic_error(_info.errorMessage("bitwise operator is not available when not targeting Lua version 5.3 or higher"sv, node)); | 5809 | throw std::logic_error(_info.errorMessage("bitwise operator is not available when not targeting Lua version 5.3 or higher"sv, node)); |
5817 | } | 5810 | } |
@@ -5874,7 +5867,7 @@ private: | |||
5874 | out.push_back(join(temp)); | 5867 | out.push_back(join(temp)); |
5875 | } | 5868 | } |
5876 | 5869 | ||
5877 | void transformForEachInPlace(ForEach_t* forEach, str_list& out, ExpList_t* assignExpList = nullptr) { | 5870 | void transformForEachInPlace(ForEach_t* forEach, str_list& out, ExpList_t* assignExpList = nullptr) { |
5878 | auto x = forEach; | 5871 | auto x = forEach; |
5879 | str_list temp; | 5872 | str_list temp; |
5880 | if (assignExpList) { | 5873 | if (assignExpList) { |
@@ -5929,10 +5922,12 @@ private: | |||
5929 | transformDoubleString(static_cast<DoubleString_t*>(key), temp); | 5922 | transformDoubleString(static_cast<DoubleString_t*>(key), temp); |
5930 | temp.back() = '[' + temp.back() + ']'; | 5923 | temp.back() = '[' + temp.back() + ']'; |
5931 | break; | 5924 | break; |
5932 | case id<SingleString_t>(): transformSingleString(static_cast<SingleString_t*>(key), temp); | 5925 | case id<SingleString_t>(): |
5926 | transformSingleString(static_cast<SingleString_t*>(key), temp); | ||
5933 | temp.back() = '[' + temp.back() + ']'; | 5927 | temp.back() = '[' + temp.back() + ']'; |
5934 | break; | 5928 | break; |
5935 | case id<LuaString_t>(): transformLuaString(static_cast<LuaString_t*>(key), temp); | 5929 | case id<LuaString_t>(): |
5930 | transformLuaString(static_cast<LuaString_t*>(key), temp); | ||
5936 | temp.back() = "[ "s + temp.back() + ']'; | 5931 | temp.back() = "[ "s + temp.back() + ']'; |
5937 | break; | 5932 | break; |
5938 | default: YUEE("AST node mismatch", key); break; | 5933 | default: YUEE("AST node mismatch", key); break; |
@@ -6012,7 +6007,7 @@ private: | |||
6012 | } | 6007 | } |
6013 | } | 6008 | } |
6014 | 6009 | ||
6015 | std::pair<std::string,bool> defineClassVariable(Assignable_t* assignable) { | 6010 | std::pair<std::string, bool> defineClassVariable(Assignable_t* assignable) { |
6016 | if (auto variable = assignable->item.as<Variable_t>()) { | 6011 | if (auto variable = assignable->item.as<Variable_t>()) { |
6017 | auto name = _parser.toString(variable); | 6012 | auto name = _parser.toString(variable); |
6018 | if (addToScope(name)) { | 6013 | if (addToScope(name)) { |
@@ -6150,7 +6145,8 @@ private: | |||
6150 | case id<class_member_list_t>(): { | 6145 | case id<class_member_list_t>(): { |
6151 | size_t inc = transform_class_member_list(static_cast<class_member_list_t*>(content), members, classVar); | 6146 | size_t inc = transform_class_member_list(static_cast<class_member_list_t*>(content), members, classVar); |
6152 | auto it = members.end(); | 6147 | auto it = members.end(); |
6153 | for (size_t i = 0; i < inc; ++i, --it); | 6148 | for (size_t i = 0; i < inc; ++i, --it) |
6149 | ; | ||
6154 | for (; it != members.end(); ++it) { | 6150 | for (; it != members.end(); ++it) { |
6155 | auto& member = *it; | 6151 | auto& member = *it; |
6156 | if (member.type == MemType::Property) { | 6152 | if (member.type == MemType::Property) { |
@@ -6164,7 +6160,7 @@ private: | |||
6164 | case id<Statement_t>(): | 6160 | case id<Statement_t>(): |
6165 | transformStatement(static_cast<Statement_t*>(content), statements); | 6161 | transformStatement(static_cast<Statement_t*>(content), statements); |
6166 | break; | 6162 | break; |
6167 | default:YUEE("AST node mismatch", content); break; | 6163 | default: YUEE("AST node mismatch", content); break; |
6168 | } | 6164 | } |
6169 | } | 6165 | } |
6170 | for (auto& member : members) { | 6166 | for (auto& member : members) { |
@@ -6667,9 +6663,7 @@ private: | |||
6667 | } | 6663 | } |
6668 | for (auto _exp : expList->exprs.objects()) { | 6664 | for (auto _exp : expList->exprs.objects()) { |
6669 | auto exp = static_cast<Exp_t*>(_exp); | 6665 | auto exp = static_cast<Exp_t*>(_exp); |
6670 | if (!variableFrom(exp) && | 6666 | if (!variableFrom(exp) && !exp->getByPath<unary_exp_t, Value_t, SimpleValue_t, TableLit_t>() && !exp->getByPath<unary_exp_t, Value_t, simple_table_t>()) { |
6671 | !exp->getByPath<unary_exp_t, Value_t, SimpleValue_t, TableLit_t>() && | ||
6672 | !exp->getByPath<unary_exp_t, Value_t, simple_table_t>()) { | ||
6673 | throw std::logic_error(_info.errorMessage("left hand expressions must be variables in export statement"sv, x)); | 6667 | throw std::logic_error(_info.errorMessage("left hand expressions must be variables in export statement"sv, x)); |
6674 | } | 6668 | } |
6675 | } | 6669 | } |
@@ -7068,7 +7062,7 @@ private: | |||
7068 | if (ast_is<import_all_macro_t, ImportTabLit_t>(import->target)) { | 7062 | if (ast_is<import_all_macro_t, ImportTabLit_t>(import->target)) { |
7069 | x = import->target.get(); | 7063 | x = import->target.get(); |
7070 | bool importAllMacro = import->target.is<import_all_macro_t>(); | 7064 | bool importAllMacro = import->target.is<import_all_macro_t>(); |
7071 | std::list<std::pair<std::string,std::string>> macroPairs; | 7065 | std::list<std::pair<std::string, std::string>> macroPairs; |
7072 | auto newTab = x->new_ptr<ImportTabLit_t>(); | 7066 | auto newTab = x->new_ptr<ImportTabLit_t>(); |
7073 | if (auto tabLit = import->target.as<ImportTabLit_t>()) { | 7067 | if (auto tabLit = import->target.as<ImportTabLit_t>()) { |
7074 | for (auto item : tabLit->items.objects()) { | 7068 | for (auto item : tabLit->items.objects()) { |
@@ -7369,8 +7363,7 @@ private: | |||
7369 | for (auto branch_ : branches) { | 7363 | for (auto branch_ : branches) { |
7370 | auto branch = static_cast<SwitchCase_t*>(branch_); | 7364 | auto branch = static_cast<SwitchCase_t*>(branch_); |
7371 | if (auto value = singleValueFrom(branch->valueList); | 7365 | if (auto value = singleValueFrom(branch->valueList); |
7372 | value && (value->item.is<simple_table_t>() || | 7366 | value && (value->item.is<simple_table_t>() || value->getByPath<SimpleValue_t, TableLit_t>())) { |
7373 | value->getByPath<SimpleValue_t, TableLit_t>())) { | ||
7374 | if (!firstBranch) { | 7367 | if (!firstBranch) { |
7375 | temp.push_back(indent() + "else"s + nll(branch)); | 7368 | temp.push_back(indent() + "else"s + nll(branch)); |
7376 | pushScope(); | 7369 | pushScope(); |
@@ -7440,8 +7433,7 @@ private: | |||
7440 | if (!singleValueFrom(exp)) { | 7433 | if (!singleValueFrom(exp)) { |
7441 | tmp.back() = '(' + tmp.back() + ')'; | 7434 | tmp.back() = '(' + tmp.back() + ')'; |
7442 | } | 7435 | } |
7443 | temp.back().append(' ' + tmp.back() + " == "s + | 7436 | temp.back().append(' ' + tmp.back() + " == "s + (exp == exprs.back() ? objVar : objVar + " or"s)); |
7444 | (exp == exprs.back() ? objVar : objVar + " or"s)); | ||
7445 | } | 7437 | } |
7446 | temp.back().append(" then"s + nll(branch)); | 7438 | temp.back().append(" then"s + nll(branch)); |
7447 | pushScope(); | 7439 | pushScope(); |
@@ -7674,22 +7666,23 @@ const std::string YueCompilerImpl::Empty; | |||
7674 | 7666 | ||
7675 | YueCompiler::YueCompiler(void* sharedState, | 7667 | YueCompiler::YueCompiler(void* sharedState, |
7676 | const std::function<void(void*)>& luaOpen, | 7668 | const std::function<void(void*)>& luaOpen, |
7677 | bool sameModule): | 7669 | bool sameModule) |
7670 | : | ||
7678 | #ifndef YUE_NO_MACRO | 7671 | #ifndef YUE_NO_MACRO |
7679 | _compiler(std::make_unique<YueCompilerImpl>(static_cast<lua_State*>(sharedState), luaOpen, sameModule)) {} | 7672 | _compiler(std::make_unique<YueCompilerImpl>(static_cast<lua_State*>(sharedState), luaOpen, sameModule)) { |
7673 | } | ||
7680 | #else | 7674 | #else |
7681 | _compiler(std::make_unique<YueCompilerImpl>()) { | 7675 | _compiler(std::make_unique<YueCompilerImpl>()) { |
7682 | (void)sharedState; | 7676 | (void)sharedState; |
7683 | (void)luaOpen; | 7677 | (void)luaOpen; |
7684 | (void)sameModule; | 7678 | (void)sameModule; |
7685 | } | 7679 | } |
7686 | #endif // YUE_NO_MACRO | 7680 | #endif // YUE_NO_MACRO |
7687 | 7681 | ||
7688 | YueCompiler::~YueCompiler() {} | 7682 | YueCompiler::~YueCompiler() { } |
7689 | 7683 | ||
7690 | CompileInfo YueCompiler::compile(std::string_view codes, const YueConfig& config) { | 7684 | CompileInfo YueCompiler::compile(std::string_view codes, const YueConfig& config) { |
7691 | return _compiler->compile(codes, config); | 7685 | return _compiler->compile(codes, config); |
7692 | } | 7686 | } |
7693 | 7687 | ||
7694 | } // namespace yue | 7688 | } // namespace yue |
7695 | |||
diff --git a/src/yuescript/yue_compiler.h b/src/yuescript/yue_compiler.h index 3df5451..9ca641a 100644 --- a/src/yuescript/yue_compiler.h +++ b/src/yuescript/yue_compiler.h | |||
@@ -8,14 +8,14 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI | |||
8 | 8 | ||
9 | #pragma once | 9 | #pragma once |
10 | 10 | ||
11 | #include <functional> | ||
12 | #include <list> | ||
13 | #include <memory> | ||
11 | #include <string> | 14 | #include <string> |
12 | #include <string_view> | 15 | #include <string_view> |
13 | #include <tuple> | 16 | #include <tuple> |
14 | #include <list> | ||
15 | #include <vector> | ||
16 | #include <memory> | ||
17 | #include <unordered_map> | 17 | #include <unordered_map> |
18 | #include <functional> | 18 | #include <vector> |
19 | 19 | ||
20 | namespace yue { | 20 | namespace yue { |
21 | 21 | ||
@@ -59,6 +59,7 @@ public: | |||
59 | bool sameModule = false); | 59 | bool sameModule = false); |
60 | virtual ~YueCompiler(); | 60 | virtual ~YueCompiler(); |
61 | CompileInfo compile(std::string_view codes, const YueConfig& config = {}); | 61 | CompileInfo compile(std::string_view codes, const YueConfig& config = {}); |
62 | |||
62 | private: | 63 | private: |
63 | std::unique_ptr<YueCompilerImpl> _compiler; | 64 | std::unique_ptr<YueCompilerImpl> _compiler; |
64 | }; | 65 | }; |
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index 31a2560..a22bd3a 100755 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp | |||
@@ -17,8 +17,7 @@ std::unordered_set<std::string> LuaKeywords = { | |||
17 | "end"s, "false"s, "for"s, "function"s, "goto"s, | 17 | "end"s, "false"s, "for"s, "function"s, "goto"s, |
18 | "if"s, "in"s, "local"s, "nil"s, "not"s, | 18 | "if"s, "in"s, "local"s, "nil"s, "not"s, |
19 | "or"s, "repeat"s, "return"s, "then"s, "true"s, | 19 | "or"s, "repeat"s, "return"s, "then"s, "true"s, |
20 | "until"s, "while"s | 20 | "until"s, "while"s}; |
21 | }; | ||
22 | 21 | ||
23 | std::unordered_set<std::string> Keywords = { | 22 | std::unordered_set<std::string> Keywords = { |
24 | "and"s, "break"s, "do"s, "else"s, "elseif"s, | 23 | "and"s, "break"s, "do"s, "else"s, "elseif"s, |
@@ -31,6 +30,7 @@ std::unordered_set<std::string> Keywords = { | |||
31 | "try"s, "unless"s, "using"s, "when"s, "with"s // Yue keywords | 30 | "try"s, "unless"s, "using"s, "when"s, "with"s // Yue keywords |
32 | }; | 31 | }; |
33 | 32 | ||
33 | // clang-format off | ||
34 | YueParser::YueParser() { | 34 | YueParser::YueParser() { |
35 | plain_space = *set(" \t"); | 35 | plain_space = *set(" \t"); |
36 | Break = nl(-expr('\r') >> '\n'); | 36 | Break = nl(-expr('\r') >> '\n'); |
@@ -55,14 +55,14 @@ YueParser::YueParser() { | |||
55 | +(range('0', '9') | range('a', 'f') | range('A', 'F')) >> | 55 | +(range('0', '9') | range('a', 'f') | range('A', 'F')) >> |
56 | -(-set("uU") >> set("lL") >> set("lL")) | 56 | -(-set("uU") >> set("lL") >> set("lL")) |
57 | ) | ( | 57 | ) | ( |
58 | +range('0', '9') >> -set("uU") >> set("lL") >> set("lL") | 58 | +range('0', '9') >> ( |
59 | ) | ( | 59 | '.' >> +range('0', '9') >> -(set("eE") >> -expr('-') >> +range('0', '9')) | |
60 | ( | 60 | -set("uU") >> set("lL") >> set("lL") | |
61 | +range('0', '9') >> -('.' >> +range('0', '9')) | 61 | true_() |
62 | ) | ( | ||
63 | '.' >> +range('0', '9') | ||
64 | ) | 62 | ) |
65 | ) >> -(set("eE") >> -expr('-') >> +range('0', '9')); | 63 | ) | ( |
64 | '.' >> +range('0', '9') >> -(set("eE") >> -expr('-') >> +range('0', '9')) | ||
65 | ); | ||
66 | 66 | ||
67 | Cut = false_(); | 67 | Cut = false_(); |
68 | Seperator = true_(); | 68 | Seperator = true_(); |
@@ -652,6 +652,7 @@ YueParser::YueParser() { | |||
652 | BlockEnd = Block >> -(+Break >> Space >> and_(Stop)) >> Stop; | 652 | BlockEnd = Block >> -(+Break >> Space >> and_(Stop)) >> Stop; |
653 | File = White >> -Shebang >> -Block >> White >> eof(); | 653 | File = White >> -Shebang >> -Block >> White >> eof(); |
654 | } | 654 | } |
655 | // clang-format on | ||
655 | 656 | ||
656 | ParseInfo YueParser::parse(std::string_view codes, rule& r) { | 657 | ParseInfo YueParser::parse(std::string_view codes, rule& r) { |
657 | ParseInfo res; | 658 | ParseInfo res; |
@@ -710,20 +711,20 @@ std::string YueParser::decode(const input& codes) { | |||
710 | } | 711 | } |
711 | 712 | ||
712 | namespace Utils { | 713 | namespace Utils { |
713 | void replace(std::string& str, std::string_view from, std::string_view to) { | 714 | void replace(std::string& str, std::string_view from, std::string_view to) { |
714 | size_t start_pos = 0; | 715 | size_t start_pos = 0; |
715 | while((start_pos = str.find(from, start_pos)) != std::string::npos) { | 716 | while ((start_pos = str.find(from, start_pos)) != std::string::npos) { |
716 | str.replace(start_pos, from.size(), to); | 717 | str.replace(start_pos, from.size(), to); |
717 | start_pos += to.size(); | 718 | start_pos += to.size(); |
718 | } | ||
719 | } | 719 | } |
720 | } | ||
720 | 721 | ||
721 | void trim(std::string& str) { | 722 | void trim(std::string& str) { |
722 | if (str.empty()) return; | 723 | if (str.empty()) return; |
723 | str.erase(0, str.find_first_not_of(" \t\r\n")); | 724 | str.erase(0, str.find_first_not_of(" \t\r\n")); |
724 | str.erase(str.find_last_not_of(" \t\r\n") + 1); | 725 | str.erase(str.find_last_not_of(" \t\r\n") + 1); |
725 | } | ||
726 | } | 726 | } |
727 | } // namespace Utils | ||
727 | 728 | ||
728 | std::string ParseInfo::errorMessage(std::string_view msg, const input_range* loc) const { | 729 | std::string ParseInfo::errorMessage(std::string_view msg, const input_range* loc) const { |
729 | const int ASCII = 255; | 730 | const int ASCII = 255; |
@@ -753,13 +754,14 @@ std::string ParseInfo::errorMessage(std::string_view msg, const input_range* loc | |||
753 | } | 754 | } |
754 | auto line = Converter{}.to_bytes(std::wstring(begin, end)); | 755 | auto line = Converter{}.to_bytes(std::wstring(begin, end)); |
755 | while (col < static_cast<int>(line.size()) | 756 | while (col < static_cast<int>(line.size()) |
756 | && (line[col] == ' ' || line[col] == '\t')) { | 757 | && (line[col] == ' ' || line[col] == '\t')) { |
757 | col++; | 758 | col++; |
758 | } | 759 | } |
759 | Utils::replace(line, "\t"sv, " "sv); | 760 | Utils::replace(line, "\t"sv, " "sv); |
760 | std::ostringstream buf; | 761 | std::ostringstream buf; |
761 | buf << loc->m_begin.m_line << ": "sv << msg << | 762 | buf << loc->m_begin.m_line << ": "sv << msg << '\n' |
762 | '\n' << line << '\n' << std::string(col, ' ') << "^"sv; | 763 | << line << '\n' |
764 | << std::string(col, ' ') << "^"sv; | ||
763 | return buf.str(); | 765 | return buf.str(); |
764 | } | 766 | } |
765 | 767 | ||
diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h index b363ad7..3ee219e 100755 --- a/src/yuescript/yue_parser.h +++ b/src/yuescript/yue_parser.h | |||
@@ -8,14 +8,14 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI | |||
8 | 8 | ||
9 | #pragma once | 9 | #pragma once |
10 | 10 | ||
11 | #include <string> | ||
12 | #include <unordered_set> | ||
13 | #include <stack> | ||
14 | #include <algorithm> | 11 | #include <algorithm> |
15 | #include <list> | 12 | #include <list> |
13 | #include <memory> | ||
16 | #include <sstream> | 14 | #include <sstream> |
15 | #include <stack> | ||
16 | #include <string> | ||
17 | #include <string_view> | 17 | #include <string_view> |
18 | #include <memory> | 18 | #include <unordered_set> |
19 | 19 | ||
20 | #include "yuescript/ast.hpp" | 20 | #include "yuescript/ast.hpp" |
21 | #include "yuescript/yue_ast.h" | 21 | #include "yuescript/yue_ast.h" |
@@ -35,7 +35,7 @@ struct ParseInfo { | |||
35 | std::string errorMessage(std::string_view msg, const input_range* loc) const; | 35 | std::string errorMessage(std::string_view msg, const input_range* loc) const; |
36 | }; | 36 | }; |
37 | 37 | ||
38 | template<typename T> | 38 | template <typename T> |
39 | struct identity { typedef T type; }; | 39 | struct identity { typedef T type; }; |
40 | 40 | ||
41 | #define AST_RULE(type) \ | 41 | #define AST_RULE(type) \ |
@@ -50,7 +50,7 @@ class YueParser { | |||
50 | public: | 50 | public: |
51 | YueParser(); | 51 | YueParser(); |
52 | 52 | ||
53 | template<class AST> | 53 | template <class AST> |
54 | ParseInfo parse(std::string_view codes) { | 54 | ParseInfo parse(std::string_view codes) { |
55 | return parse(codes, getRule<AST>()); | 55 | return parse(codes, getRule<AST>()); |
56 | } | 56 | } |
@@ -338,8 +338,8 @@ private: | |||
338 | }; | 338 | }; |
339 | 339 | ||
340 | namespace Utils { | 340 | namespace Utils { |
341 | void replace(std::string& str, std::string_view from, std::string_view to); | 341 | void replace(std::string& str, std::string_view from, std::string_view to); |
342 | void trim(std::string& str); | 342 | void trim(std::string& str); |
343 | }; | 343 | } // namespace Utils |
344 | 344 | ||
345 | } // namespace yue | 345 | } // namespace yue |
diff --git a/src/yuescript/yuescript.cpp b/src/yuescript/yuescript.cpp index 98e214f..08978e5 100644 --- a/src/yuescript/yuescript.cpp +++ b/src/yuescript/yuescript.cpp | |||
@@ -19,11 +19,12 @@ using namespace std::string_literals; | |||
19 | 19 | ||
20 | extern "C" { | 20 | extern "C" { |
21 | 21 | ||
22 | #include "lua.h" | ||
23 | #include "lauxlib.h" | 22 | #include "lauxlib.h" |
23 | #include "lua.h" | ||
24 | 24 | ||
25 | static const char yuescriptCodes[] = | 25 | static const char yuescriptCodes[] = |
26 | #include "yuescript/yuescript.h" | 26 | #include "yuescript/yuescript.h" |
27 | ; | ||
27 | 28 | ||
28 | static void init_yuescript(lua_State* L) { | 29 | static void init_yuescript(lua_State* L) { |
29 | if (luaL_loadbuffer(L, yuescriptCodes, sizeof(yuescriptCodes) / sizeof(yuescriptCodes[0]) - 1, "=(yuescript)") != 0) { | 30 | if (luaL_loadbuffer(L, yuescriptCodes, sizeof(yuescriptCodes) / sizeof(yuescriptCodes[0]) - 1, "=(yuescript)") != 0) { |
@@ -40,6 +41,7 @@ static void init_yuescript(lua_State* L) { | |||
40 | 41 | ||
41 | static const char stpCodes[] = | 42 | static const char stpCodes[] = |
42 | #include "yuescript/stacktraceplus.h" | 43 | #include "yuescript/stacktraceplus.h" |
44 | ; | ||
43 | 45 | ||
44 | static int init_stacktraceplus(lua_State* L) { | 46 | static int init_stacktraceplus(lua_State* L) { |
45 | if (luaL_loadbuffer(L, stpCodes, sizeof(stpCodes) / sizeof(stpCodes[0]) - 1, "=(stacktraceplus)") != 0) { | 47 | if (luaL_loadbuffer(L, stpCodes, sizeof(stpCodes) / sizeof(stpCodes[0]) - 1, "=(stacktraceplus)") != 0) { |
@@ -218,8 +220,7 @@ static const luaL_Reg yuelib[] = { | |||
218 | {"version", nullptr}, | 220 | {"version", nullptr}, |
219 | {"options", nullptr}, | 221 | {"options", nullptr}, |
220 | {"load_stacktraceplus", nullptr}, | 222 | {"load_stacktraceplus", nullptr}, |
221 | {nullptr, nullptr} | 223 | {nullptr, nullptr}}; |
222 | }; | ||
223 | 224 | ||
224 | YUE_API int luaopen_yue(lua_State* L) { | 225 | YUE_API int luaopen_yue(lua_State* L) { |
225 | #if LUA_VERSION_NUM > 501 | 226 | #if LUA_VERSION_NUM > 501 |
@@ -243,4 +244,3 @@ YUE_API int luaopen_yue(lua_State* L) { | |||
243 | } | 244 | } |
244 | 245 | ||
245 | } // extern "C" | 246 | } // extern "C" |
246 | |||