diff options
Diffstat (limited to 'MoonParser/ast.hpp')
-rw-r--r-- | MoonParser/ast.hpp | 44 |
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>(); } |
83 | private: | 94 | private: |
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 | ||
91 | template<class T> | 103 | template<class T> |
92 | T* ast_cast(ast_node *node) { | 104 | T* 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 | ||
108 | template<class T> | ||
109 | T* ast_to(ast_node* node) { | ||
110 | assert(node->get_type() == ast_type<T>()); | ||
111 | return static_cast<T*>(node); | ||
112 | } | ||
113 | |||
96 | template <class ...Args> | 114 | template <class ...Args> |
97 | bool ast_is(ast_node* node) { | 115 | bool 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 | */ |
411 | template <class T> class ast_list : public _ast_list { | 443 | template <class T> class ast_list : public _ast_list { |
412 | public: | 444 | public: |
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 | ||
451 | template <class ...Args> class ast_sel_list : public _ast_list { | 482 | template <class ...Args> class ast_sel_list : public _ast_list { |
452 | public: | 483 | public: |
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) { |