aboutsummaryrefslogtreecommitdiff
path: root/MoonParser/ast.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'MoonParser/ast.hpp')
-rw-r--r--MoonParser/ast.hpp44
1 files changed, 37 insertions, 7 deletions
diff --git a/MoonParser/ast.hpp b/MoonParser/ast.hpp
index 1077f5d..63dccba 100644
--- a/MoonParser/ast.hpp
+++ b/MoonParser/ast.hpp
@@ -63,7 +63,18 @@ public:
63 */ 63 */
64 virtual traversal traverse(const std::function<traversal (ast_node*)>& func); 64 virtual traversal traverse(const std::function<traversal (ast_node*)>& func);
65 65
66 virtual ast_node* getByPath(std::initializer_list<size_t> paths); 66 template <typename... Ts>
67 struct select_last {
68 using type = typename decltype((std::enable_if<true,Ts>{}, ...))::type;
69 };
70 template <typename... Ts>
71 using select_last_t = typename select_last<Ts...>::type;
72
73 template <class ...Args>
74 select_last_t<Args...>* getByPath() {
75 int types[] = {ast_type<Args>()...};
76 return static_cast<select_last_t<Args...>*>(getByTypeIds(std::begin(types), std::end(types)));
77 }
67 78
68 virtual bool visitChild(const std::function<bool (ast_node*)>& func); 79 virtual bool visitChild(const std::function<bool (ast_node*)>& func);
69 80
@@ -82,6 +93,7 @@ public:
82 virtual int get_type() { return ast_type<ast_node>(); } 93 virtual int get_type() { return ast_type<ast_node>(); }
83private: 94private:
84 int _ref; 95 int _ref;
96 ast_node* getByTypeIds(int* begin, int* end);
85 template <class T, bool OPT, bool MEM> friend class ast_ptr; 97 template <class T, bool OPT, bool MEM> friend class ast_ptr;
86 template <class ...Args> friend class ast_choice; 98 template <class ...Args> friend class ast_choice;
87 template <class T> friend class ast_list; 99 template <class T> friend class ast_list;
@@ -89,10 +101,16 @@ private:
89}; 101};
90 102
91template<class T> 103template<class T>
92T* ast_cast(ast_node *node) { 104T* ast_cast(ast_node* node) {
93 return node && ast_type<T>() == node->get_type() ? static_cast<T*>(node) : nullptr; 105 return node && ast_type<T>() == node->get_type() ? static_cast<T*>(node) : nullptr;
94} 106}
95 107
108template<class T>
109T* ast_to(ast_node* node) {
110 assert(node->get_type() == ast_type<T>());
111 return static_cast<T*>(node);
112}
113
96template <class ...Args> 114template <class ...Args>
97bool ast_is(ast_node* node) { 115bool ast_is(ast_node* node) {
98 if (!node) return false; 116 if (!node) return false;
@@ -132,8 +150,6 @@ public:
132 */ 150 */
133 virtual void construct(ast_stack& st) override; 151 virtual void construct(ast_stack& st) override;
134 152
135 virtual ast_node* getByPath(std::initializer_list<size_t> paths) override;
136
137 virtual traversal traverse(const std::function<traversal (ast_node*)>& func) override; 153 virtual traversal traverse(const std::function<traversal (ast_node*)>& func) override;
138 154
139 virtual bool visitChild(const std::function<bool (ast_node*)>& func) override; 155 virtual bool visitChild(const std::function<bool (ast_node*)>& func) override;
@@ -210,7 +226,7 @@ public:
210 226
211 template <class T> 227 template <class T>
212 T* to() const { 228 T* to() const {
213 assert(m_ptr->getId() != ast_type<T>()); 229 assert(m_ptr->get_type() == ast_type<T>());
214 return static_cast<T*>(m_ptr); 230 return static_cast<T*>(m_ptr);
215 } 231 }
216 232
@@ -380,6 +396,22 @@ public:
380 } 396 }
381 } 397 }
382 398
399 void set_front(ast_node* node) {
400 if (accept(node)) {
401 m_objects.front()->release();
402 m_objects.front() = node;
403 node->retain();
404 }
405 }
406
407 void set_back(ast_node* node) {
408 if (accept(node)) {
409 m_objects.back()->release();
410 m_objects.back() = node;
411 node->retain();
412 }
413 }
414
383 const container& objects() const { 415 const container& objects() const {
384 return m_objects; 416 return m_objects;
385 } 417 }
@@ -410,7 +442,6 @@ protected:
410 */ 442 */
411template <class T> class ast_list : public _ast_list { 443template <class T> class ast_list : public _ast_list {
412public: 444public:
413 ///the default constructor.
414 ast_list() {} 445 ast_list() {}
415 446
416 ast_list(const ast_list<T>& other) { 447 ast_list(const ast_list<T>& other) {
@@ -450,7 +481,6 @@ private:
450 481
451template <class ...Args> class ast_sel_list : public _ast_list { 482template <class ...Args> class ast_sel_list : public _ast_list {
452public: 483public:
453 ///the default constructor.
454 ast_sel_list() {} 484 ast_sel_list() {}
455 485
456 ast_sel_list(const ast_sel_list<Args...>& other) { 486 ast_sel_list(const ast_sel_list<Args...>& other) {