aboutsummaryrefslogtreecommitdiff
path: root/MoonParser/ast.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'MoonParser/ast.hpp')
-rw-r--r--MoonParser/ast.hpp60
1 files changed, 51 insertions, 9 deletions
diff --git a/MoonParser/ast.hpp b/MoonParser/ast.hpp
index e7ae74f..1077f5d 100644
--- a/MoonParser/ast.hpp
+++ b/MoonParser/ast.hpp
@@ -25,8 +25,7 @@ typedef std::vector<ast_node*> ast_stack;
25extern int ast_type_id; 25extern int ast_type_id;
26 26
27template<class T> 27template<class T>
28int ast_type() 28int ast_type() {
29{
30 static int type = ast_type_id++; 29 static int type = ast_type_id++;
31 return type; 30 return type;
32} 31}
@@ -211,7 +210,7 @@ public:
211 210
212 template <class T> 211 template <class T>
213 T* to() const { 212 T* to() const {
214 assert(m_ptr->getId() == ast_type<T>()); 213 assert(m_ptr->getId() != ast_type<T>());
215 return static_cast<T*>(m_ptr); 214 return static_cast<T*>(m_ptr);
216 } 215 }
217 216
@@ -313,13 +312,13 @@ inline ast_ptr<T, false, false> new_ptr() {
313 return ast_ptr<T, false, false>(new T); 312 return ast_ptr<T, false, false>(new T);
314} 313}
315 314
316template <class ...Args> class ast_choice : public _ast_ptr { 315template <class ...Args> class ast_sel : public _ast_ptr {
317public: 316public:
318 ast_choice() : _ast_ptr(nullptr, true) {} 317 ast_sel() : _ast_ptr(nullptr, true) {}
319 318
320 ast_choice(const ast_choice<Args...>& other) : _ast_ptr(other.get(), true) {} 319 ast_sel(const ast_sel<Args...>& other) : _ast_ptr(other.get(), true) {}
321 320
322 ast_choice<Args...>& operator=(const ast_choice<Args...>& other) { 321 ast_sel<Args...>& operator=(const ast_sel<Args...>& other) {
323 set(other.get()); 322 set(other.get());
324 return *this; 323 return *this;
325 } 324 }
@@ -340,7 +339,7 @@ public:
340 339
341 ast_node* node = st.back(); 340 ast_node* node = st.back();
342 341
343 if (!ast_choice::accept(node)) throw std::logic_error("invalid AST node"); 342 if (!ast_sel::accept(node)) throw std::logic_error("invalid AST node");
344 343
345 st.pop_back(); 344 st.pop_back();
346 345
@@ -351,7 +350,7 @@ private:
351 virtual bool accept(ast_node* node) override { 350 virtual bool accept(ast_node* node) override {
352 if (!node) return false; 351 if (!node) return false;
353 using swallow = bool[]; 352 using swallow = bool[];
354 bool* result = nullptr; 353 bool result = false;
355 (void)swallow{result || (result = ast_type<Args>() == node->get_type())...}; 354 (void)swallow{result || (result = ast_type<Args>() == node->get_type())...};
356 return result; 355 return result;
357 } 356 }
@@ -449,6 +448,49 @@ private:
449 } 448 }
450}; 449};
451 450
451template <class ...Args> class ast_sel_list : public _ast_list {
452public:
453 ///the default constructor.
454 ast_sel_list() {}
455
456 ast_sel_list(const ast_sel_list<Args...>& other) {
457 clear();
458 dup(other);
459 }
460
461 ast_sel_list<Args...>& operator=(const ast_sel_list<Args...>& other) {
462 clear();
463 dup(other);
464 return *this;
465 }
466
467 /** Pops objects of type T from the stack until no more objects can be popped.
468 @param st stack.
469 */
470 virtual void construct(ast_stack &st) override {
471 while (!st.empty()) {
472 ast_node* node = st.back();
473
474 //if the object was not not of the appropriate type,
475 //end the list parsing
476 if (!ast_sel_list<Args...>::accept(node)) return;
477
478 st.pop_back();
479
480 //insert the object in the list, in reverse order
481 m_objects.push_front(node);
482 node->retain();
483 }
484 }
485private:
486 virtual bool accept(ast_node* node) override {
487 if (!node) return false;
488 using swallow = bool[];
489 bool result = false;
490 (void)swallow{result || (result = ast_type<Args>() == node->get_type())...};
491 return result;
492 }
493};
452 494
453/** AST function which creates an object of type T 495/** AST function which creates an object of type T
454 and pushes it to the node stack. 496 and pushes it to the node stack.