aboutsummaryrefslogtreecommitdiff
path: root/src/MoonP/ast.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/MoonP/ast.hpp')
-rw-r--r--src/MoonP/ast.hpp63
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;
33typedef std::vector<ast_node*> ast_stack; 34typedef std::vector<ast_node*> ast_stack;
34typedef std::list<ast_node*> node_container; 35typedef std::list<ast_node*> node_container;
35 36
36extern int ast_type_id;
37 37
38template<size_t Num> struct Counter { enum { value = Counter<Num-1>::value }; };
39template<> 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
44class ast_node;
38template<class T> 45template<class T>
39int ast_type() { 46constexpr typename std::enable_if<std::is_base_of<ast_node,T>::value,int>::type
40 static int type = ast_type_id++; 47id();
41 return type;
42}
43 48
44enum class traversal { 49enum 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
108template<class T> 111template<class T>
112constexpr typename std::enable_if<std::is_base_of<ast_node,T>::value,int>::type
113id() { return 0; }
114
115template<class T>
109T* ast_cast(ast_node* node) { 116T* 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
113template<class T> 120template<class T>
114T* ast_to(ast_node* node) { 121T* 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>
120bool ast_is(ast_node* node) { 127bool 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
176enum 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
186template<class T>
187T* ast_cast(ast_member* member) {
188 return member && ast_type<T>() == member->get_type() ? static_cast<T*>(member) : nullptr;
189}
190 197
191class _ast_ptr : public ast_member { 198class _ast_ptr : public ast_member {
192public: 199public:
@@ -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 }
241protected: 248protected:
242 ast_node* m_ptr; 249 ast_node* m_ptr;
@@ -305,7 +312,7 @@ public:
305 } 312 }
306private: 313private:
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 }
433protected: 442protected:
434 node_container m_objects; 443 node_container m_objects;
435}; 444};
@@ -479,7 +488,7 @@ public:
479 } 488 }
480private: 489private:
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};