cymoca
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
node.h
Go to the documentation of this file.
1 #ifndef CYMOCA_AST_NODE_H_
2 #define CYMOCA_AST_NODE_H_
3 
4 #include <cassert>
5 #include <memory>
6 #include <vector>
7 
8 #include "listener/listener.h"
9 
15 #define NODE_MACRO \
16  void enter(listener::Base &listener) override { listener.enter(this); } \
17  void exit(listener::Base &listener) override { listener.exit(this); }
18 
19 namespace cymoca::ast {
20 
27 class INode {
28  public:
29  virtual ~INode(){};
33  virtual void enter(listener::Base &listener) = 0;
37  virtual void exit(listener::Base &listener) = 0;
41  virtual std::vector<INode *> getChildren() = 0;
45  virtual std::unique_ptr<INode> clone() const = 0;
49  template <class T>
50  std::unique_ptr<T> cloneAs() {
51  auto n = this->clone();
52  auto p = std::unique_ptr<T>(dynamic_cast<T *>(n.get()));
53  assert(p.get());
54  n.release();
55  return p;
56  }
57 };
58 
62 template <class Left, class Right, class Base>
63 class TBinary : public Base {
64  protected:
65  std::unique_ptr<Left> m_left{};
66  std::unique_ptr<Right> m_right{};
67 
68  public:
69  TBinary(std::unique_ptr<Left> left, std::unique_ptr<Right> right)
70  : m_left(move(left)), m_right(move(right)) {}
71  Left *getLeft() { return m_left.get(); }
72  Right *getRight() { return m_right.get(); }
73  std::vector<INode *> getChildren() override {
74  return {m_left.get(), m_right.get()};
75  }
76  template <class T>
77  std::unique_ptr<INode> cloneBinary() const {
78  return std::make_unique<T>(
79  dynamic_cast<INode *>(m_left.get())->cloneAs<Left>(),
80  dynamic_cast<INode *>(m_right.get())->cloneAs<Right>());
81  }
82 };
83 
87 template <class Right, class Base>
88 class TUnary : public Base {
89  protected:
90  std::unique_ptr<Right> m_right{};
91 
92  public:
93  explicit TUnary(std::unique_ptr<Right> right) : m_right(move(right)) {}
94  Right *getRight() { return m_right.get(); }
95  std::vector<INode *> getChildren() override { return {m_right.get()}; }
96  template <class T>
97  std::unique_ptr<INode> cloneUnary() const {
98  return std::make_unique<T>(
99  dynamic_cast<INode *>(m_right.get())->cloneAs<Right>());
100  }
101 };
102 
106 template <class Item, class Base>
107 class TList : public Base {
108  protected:
109  std::vector<std::unique_ptr<Item>> m_list{};
110 
111  public:
112  TList() = default;
113  void append(std::unique_ptr<Item> item) { m_list.push_back(std::move(item)); }
114  std::vector<std::unique_ptr<Item>> &list() { return m_list; };
115  template <class Arg1, class... Args>
116  explicit TList(Arg1 arg1, Args... args) {
117  m_list.push_back(move(arg1));
118  // trick to get variadic template to pushback
119  int dummy[1 + sizeof...(Args)] = {0, (m_list.push_back(move(args)), 0)...};
120  (void)dummy;
121  }
122  std::vector<INode *> getChildren() override {
123  std::vector<INode *> v;
124  for (auto &c : m_list) {
125  v.push_back(c.get());
126  }
127  return v;
128  }
129  template <class T>
130  std::unique_ptr<INode> cloneList() const {
131  auto res = std::make_unique<T>();
132  for (auto &item : m_list) {
133  auto p = static_cast<INode *>(item.get())->cloneAs<Item>();
134  res->m_list.push_back(move(p));
135  }
136  return std::move(res);
137  }
138 };
139 
148 namespace condition {
153 class Base : public INode {};
154 } // namespace condition
155 
156 namespace element {
157 class Base : public INode {};
158 } // namespace element
159 
160 namespace equation {
161 class Base : public INode {};
162 } // namespace equation
163 
164 namespace expression {
168 class Base : public INode {};
169 } // namespace expression
170 
171 namespace model {
175 class Base : public INode {};
176 } // namespace model
177 
178 namespace statement {
182 class Base : public INode {};
183 } // namespace statement
184 
185 } // namespace cymoca::ast
186 
187 namespace std {
188 template <>
189 struct hash<cymoca::ast::INode> {
190  size_t operator()(const cymoca::ast::INode &obj) const {
191  return hash<int>()(size_t(&obj));
192  }
193 };
194 } // namespace std
195 #endif
std::unique_ptr< INode > cloneUnary() const
Definition: node.h:97
Right * getRight()
Definition: node.h:72
Left * getLeft()
Definition: node.h:71
void append(std::unique_ptr< Item > item)
Definition: node.h:113
std::vector< INode * > getChildren() override
Definition: node.h:95
std::unique_ptr< T > cloneAs()
Definition: node.h:50
size_t operator()(const cymoca::ast::INode &obj) const
Definition: node.h:190
virtual std::unique_ptr< INode > clone() const =0
TUnary(std::unique_ptr< Right > right)
Definition: node.h:93
virtual std::vector< INode * > getChildren()=0
std::unique_ptr< Right > m_right
Definition: node.h:90
std::unique_ptr< INode > cloneBinary() const
Definition: node.h:77
std::vector< std::unique_ptr< Item > > m_list
Definition: node.h:109
std::unique_ptr< Left > m_left
Definition: node.h:65
std::unique_ptr< Right > m_right
Definition: node.h:66
Right * getRight()
Definition: node.h:94
TBinary(std::unique_ptr< Left > left, std::unique_ptr< Right > right)
Definition: node.h:69
std::vector< std::unique_ptr< Item > > & list()
Definition: node.h:114
std::vector< INode * > getChildren() override
Definition: node.h:122
virtual ~INode()
Definition: node.h:29
std::vector< INode * > getChildren() override
Definition: node.h:73
std::unique_ptr< INode > cloneList() const
Definition: node.h:130
TList(Arg1 arg1, Args...args)
Definition: node.h:116
virtual void enter(listener::Base &listener)=0
virtual void exit(listener::Base &listener)=0