diff options
Diffstat (limited to 'src/MoonP/ast.hpp')
-rw-r--r-- | src/MoonP/ast.hpp | 63 |
1 files changed, 36 insertions, 27 deletions
diff --git a/src/MoonP/ast.hpp b/src/MoonP/ast.hpp index b56cfde..d576395 100644 --- a/src/MoonP/ast.hpp +++ b/src/MoonP/ast.hpp | |||
@@ -16,6 +16,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |||
16 | #include <list> | 16 | #include <list> |
17 | #include <stdexcept> | 17 | #include <stdexcept> |
18 | #include <type_traits> | 18 | #include <type_traits> |
19 | |||
19 | #include "MoonP/parser.hpp" | 20 | #include "MoonP/parser.hpp" |
20 | 21 | ||
21 | 22 | ||
@@ -33,13 +34,17 @@ template <class T> class ast; | |||
33 | typedef std::vector<ast_node*> ast_stack; | 34 | typedef std::vector<ast_node*> ast_stack; |
34 | typedef std::list<ast_node*> node_container; | 35 | typedef std::list<ast_node*> node_container; |
35 | 36 | ||
36 | extern int ast_type_id; | ||
37 | 37 | ||
38 | template<size_t Num> struct Counter { enum { value = Counter<Num-1>::value }; }; | ||
39 | template<> struct Counter<0> { enum { value = 0 }; }; | ||
40 | |||
41 | #define COUNTER_READ Counter<__LINE__>::value | ||
42 | #define COUNTER_INC template<> struct Counter<__LINE__> { enum { value = Counter<__LINE__-1>::value + 1}; } | ||
43 | |||
44 | class ast_node; | ||
38 | template<class T> | 45 | template<class T> |
39 | int ast_type() { | 46 | constexpr typename std::enable_if<std::is_base_of<ast_node,T>::value,int>::type |
40 | static int type = ast_type_id++; | 47 | id(); |
41 | return type; | ||
42 | } | ||
43 | 48 | ||
44 | enum class traversal { | 49 | enum class traversal { |
45 | Continue, | 50 | Continue, |
@@ -83,15 +88,13 @@ public: | |||
83 | 88 | ||
84 | template <class ...Args> | 89 | template <class ...Args> |
85 | select_last_t<Args...>* getByPath() { | 90 | select_last_t<Args...>* getByPath() { |
86 | int types[] = {ast_type<Args>()...}; | 91 | int types[] = {id<Args>()...}; |
87 | return static_cast<select_last_t<Args...>*>(getByTypeIds(std::begin(types), std::end(types))); | 92 | return static_cast<select_last_t<Args...>*>(getByTypeIds(std::begin(types), std::end(types))); |
88 | } | 93 | } |
89 | 94 | ||
90 | virtual bool visitChild(const std::function<bool (ast_node*)>& func); | 95 | virtual bool visitChild(const std::function<bool (ast_node*)>& func); |
91 | 96 | ||
92 | virtual size_t getId() const = 0; | 97 | virtual int getId() const = 0; |
93 | |||
94 | virtual int get_type() = 0; | ||
95 | 98 | ||
96 | template<class T> | 99 | template<class T> |
97 | inline ast_ptr<false, T> new_ptr() { | 100 | inline ast_ptr<false, T> new_ptr() { |
@@ -106,13 +109,17 @@ private: | |||
106 | }; | 109 | }; |
107 | 110 | ||
108 | template<class T> | 111 | template<class T> |
112 | constexpr typename std::enable_if<std::is_base_of<ast_node,T>::value,int>::type | ||
113 | id() { return 0; } | ||
114 | |||
115 | template<class T> | ||
109 | T* ast_cast(ast_node* node) { | 116 | T* ast_cast(ast_node* node) { |
110 | return node && ast_type<T>() == node->get_type() ? static_cast<T*>(node) : nullptr; | 117 | return node && id<T>() == node->getId() ? static_cast<T*>(node) : nullptr; |
111 | } | 118 | } |
112 | 119 | ||
113 | template<class T> | 120 | template<class T> |
114 | T* ast_to(ast_node* node) { | 121 | T* ast_to(ast_node* node) { |
115 | assert(node->get_type() == ast_type<T>()); | 122 | assert(node->getId() == id<T>()); |
116 | return static_cast<T*>(node); | 123 | return static_cast<T*>(node); |
117 | } | 124 | } |
118 | 125 | ||
@@ -120,9 +127,9 @@ template <class ...Args> | |||
120 | bool ast_is(ast_node* node) { | 127 | bool ast_is(ast_node* node) { |
121 | if (!node) return false; | 128 | if (!node) return false; |
122 | bool result = false; | 129 | bool result = false; |
123 | int type = node->get_type(); | 130 | int i = node->getId(); |
124 | using swallow = bool[]; | 131 | using swallow = bool[]; |
125 | (void)swallow{result || (result = ast_type<Args>() == type)...}; | 132 | (void)swallow{result || (result = id<Args>() == i)...}; |
126 | return result; | 133 | return result; |
127 | } | 134 | } |
128 | 135 | ||
@@ -166,6 +173,10 @@ private: | |||
166 | friend class ast_member; | 173 | friend class ast_member; |
167 | }; | 174 | }; |
168 | 175 | ||
176 | enum class ast_holder_type { | ||
177 | Pointer, | ||
178 | List | ||
179 | }; | ||
169 | 180 | ||
170 | /** Base class for children of ast_container. | 181 | /** Base class for children of ast_container. |
171 | */ | 182 | */ |
@@ -180,13 +191,9 @@ public: | |||
180 | 191 | ||
181 | virtual bool accept(ast_node* node) = 0; | 192 | virtual bool accept(ast_node* node) = 0; |
182 | 193 | ||
183 | virtual int get_type() { return ast_type<ast_member>(); } | 194 | virtual ast_holder_type get_type() const = 0; |
184 | }; | 195 | }; |
185 | 196 | ||
186 | template<class T> | ||
187 | T* ast_cast(ast_member* member) { | ||
188 | return member && ast_type<T>() == member->get_type() ? static_cast<T*>(member) : nullptr; | ||
189 | } | ||
190 | 197 | ||
191 | class _ast_ptr : public ast_member { | 198 | class _ast_ptr : public ast_member { |
192 | public: | 199 | public: |
@@ -212,13 +219,13 @@ public: | |||
212 | 219 | ||
213 | template <class T> | 220 | template <class T> |
214 | T* to() const { | 221 | T* to() const { |
215 | assert(m_ptr && m_ptr->get_type() == ast_type<T>()); | 222 | assert(m_ptr && m_ptr->getId() == id<T>()); |
216 | return static_cast<T*>(m_ptr); | 223 | return static_cast<T*>(m_ptr); |
217 | } | 224 | } |
218 | 225 | ||
219 | template <class T> | 226 | template <class T> |
220 | bool is() const { | 227 | bool is() const { |
221 | return m_ptr && m_ptr->get_type() == ast_type<T>(); | 228 | return m_ptr && m_ptr->getId() == id<T>(); |
222 | } | 229 | } |
223 | 230 | ||
224 | void set(ast_node* node) { | 231 | void set(ast_node* node) { |
@@ -235,8 +242,8 @@ public: | |||
235 | } | 242 | } |
236 | } | 243 | } |
237 | 244 | ||
238 | virtual int get_type() override { | 245 | virtual ast_holder_type get_type() const override { |
239 | return ast_type<_ast_ptr>(); | 246 | return ast_holder_type::Pointer; |
240 | } | 247 | } |
241 | protected: | 248 | protected: |
242 | ast_node* m_ptr; | 249 | ast_node* m_ptr; |
@@ -305,7 +312,7 @@ public: | |||
305 | } | 312 | } |
306 | private: | 313 | private: |
307 | virtual bool accept(ast_node* node) override { | 314 | virtual bool accept(ast_node* node) override { |
308 | return node && (std::is_same<ast_node,T>() || ast_type<T>() == node->get_type()); | 315 | return node && (std::is_same<ast_node,T>() || id<T>() == node->getId()); |
309 | } | 316 | } |
310 | }; | 317 | }; |
311 | 318 | ||
@@ -348,7 +355,7 @@ private: | |||
348 | if (!node) return false; | 355 | if (!node) return false; |
349 | using swallow = bool[]; | 356 | using swallow = bool[]; |
350 | bool result = false; | 357 | bool result = false; |
351 | (void)swallow{result || (result = ast_type<Args>() == node->get_type())...}; | 358 | (void)swallow{result || (result = id<Args>() == node->getId())...}; |
352 | return result; | 359 | return result; |
353 | } | 360 | } |
354 | }; | 361 | }; |
@@ -429,7 +436,9 @@ public: | |||
429 | } | 436 | } |
430 | } | 437 | } |
431 | 438 | ||
432 | virtual int get_type() override { return ast_type<_ast_list>(); } | 439 | virtual ast_holder_type get_type() const override { |
440 | return ast_holder_type::List; | ||
441 | } | ||
433 | protected: | 442 | protected: |
434 | node_container m_objects; | 443 | node_container m_objects; |
435 | }; | 444 | }; |
@@ -479,7 +488,7 @@ public: | |||
479 | } | 488 | } |
480 | private: | 489 | private: |
481 | virtual bool accept(ast_node* node) override { | 490 | virtual bool accept(ast_node* node) override { |
482 | return node && (std::is_same<ast_node,T>() || ast_type<T>() == node->get_type()); | 491 | return node && (std::is_same<ast_node,T>() || id<T>() == node->getId()); |
483 | } | 492 | } |
484 | }; | 493 | }; |
485 | 494 | ||
@@ -519,7 +528,7 @@ private: | |||
519 | if (!node) return false; | 528 | if (!node) return false; |
520 | using swallow = bool[]; | 529 | using swallow = bool[]; |
521 | bool result = false; | 530 | bool result = false; |
522 | (void)swallow{result || (result = ast_type<Args>() == node->get_type())...}; | 531 | (void)swallow{result || (result = id<Args>() == node->getId())...}; |
523 | return result; | 532 | return result; |
524 | } | 533 | } |
525 | }; | 534 | }; |