OpenVDB  7.2.0
Visitor.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3 
13 
14 #ifndef OPENVDB_AX_AST_VISITOR_HAS_BEEN_INCLUDED
15 #define OPENVDB_AX_AST_VISITOR_HAS_BEEN_INCLUDED
16 
17 #include "AST.h"
18 #include "Tokens.h"
19 
20 #include <openvdb/version.h>
21 
22 #include <type_traits>
23 
24 namespace openvdb {
26 namespace OPENVDB_VERSION_NAME {
27 
28 namespace ax {
29 namespace ast {
30 
94 template <typename Derived, bool ConstVisit=true>
95 struct Visitor
96 {
99  template <typename NodeT>
100  using NodeType = typename std::conditional<ConstVisit, const NodeT, NodeT>::type;
101 
104  inline Derived& derived() {
105  return *static_cast<Derived*>(this);
106  }
107 
110 
122  inline bool postOrderNodes() const { return true; }
123 
128  inline bool reverseChildVisits() const { return false; }
129 
141  inline bool visitNodeHierarchies() const { return false; }
142 
151  inline bool reverseHierarchyVisits() const { return false; }
152 
154 
157 
160 
162  return this->defaultTraversal<ast::Tree>(tree);
163  }
164 
166  return this->defaultTraversal<ast::StatementList>(cond);
167  }
168 
170  return this->defaultTraversal<ast::Block>(block);
171  }
172 
174  return this->defaultTraversal<ast::CommaOperator>(comma);
175  }
176 
178  return this->defaultTraversal<ast::Loop>(loop);
179  }
180 
182  return this->defaultTraversal<ast::Keyword>(keyw);
183  }
184 
186  return this->defaultTraversal<ast::ConditionalStatement>(cond);
187  }
188 
190  return this->defaultTraversal<ast::AssignExpression>(asgn);
191  }
192 
194  return this->defaultTraversal<ast::Crement>(crmt);
195  }
196 
198  return this->defaultTraversal<ast::UnaryOperator>(unry);
199  }
200 
202  return this->defaultTraversal<ast::BinaryOperator>(bin);
203  }
204 
206  return this->defaultTraversal<ast::TernaryOperator>(tern);
207  }
208 
210  return this->defaultTraversal<ast::Cast>(cast);
211  }
212 
214  return this->defaultTraversal<ast::FunctionCall>(call);
215  }
216 
218  return this->defaultTraversal<ast::Attribute>(attr);
219  }
220 
222  return this->defaultTraversal<ast::ExternalVariable>(ext);
223  }
224 
226  return this->defaultTraversal<ast::DeclareLocal>(decl);
227  }
228 
230  return this->defaultTraversal<ast::Local>(loc);
231  }
232 
234  return this->defaultTraversal<ast::ArrayPack>(pack);
235  }
236 
238  return this->defaultTraversal<ast::ArrayUnpack>(pack);
239  }
240 
242  return this->defaultTraversal<ast::Value<bool>>(val);
243  }
244 
246  return this->defaultTraversal<ast::Value<int16_t>>(val);
247  }
248 
250  return this->defaultTraversal<ast::Value<int32_t>>(val);
251  }
252 
254  return this->defaultTraversal<ast::Value<int64_t>>(val);
255  }
256 
258  return this->defaultTraversal<ast::Value<float>>(val);
259  }
260 
262  return this->defaultTraversal<ast::Value<double>>(val);
263  }
264 
266  return this->defaultTraversal<ast::Value<std::string>>(val);
267  }
268 
274  if (!node) return true;
275  switch (node->nodetype()) {
276  case Node::TreeNode : return this->derived().traverse(static_cast<NodeType<ast::Tree>*>(node));
277  case Node::StatementListNode : return this->derived().traverse(static_cast<NodeType<ast::StatementList>*>(node));
278  case Node::BlockNode : return this->derived().traverse(static_cast<NodeType<ast::Block>*>(node));
279  case Node::CommaOperatorNode : return this->derived().traverse(static_cast<NodeType<ast::CommaOperator>*>(node));
280  case Node::LoopNode : return this->derived().traverse(static_cast<NodeType<ast::Loop>*>(node));
281  case Node::KeywordNode : return this->derived().traverse(static_cast<NodeType<ast::Keyword>*>(node));
282  case Node::ConditionalStatementNode : return this->derived().traverse(static_cast<NodeType<ast::ConditionalStatement>*>(node));
283  case Node::AssignExpressionNode : return this->derived().traverse(static_cast<NodeType<ast::AssignExpression>*>(node));
284  case Node::CrementNode : return this->derived().traverse(static_cast<NodeType<ast::Crement>*>(node));
285  case Node::UnaryOperatorNode : return this->derived().traverse(static_cast<NodeType<ast::UnaryOperator>*>(node));
286  case Node::BinaryOperatorNode : return this->derived().traverse(static_cast<NodeType<ast::BinaryOperator>*>(node));
287  case Node::TernaryOperatorNode : return this->derived().traverse(static_cast<NodeType<ast::TernaryOperator>*>(node));
288  case Node::CastNode : return this->derived().traverse(static_cast<NodeType<ast::Cast>*>(node));
289  case Node::AttributeNode : return this->derived().traverse(static_cast<NodeType<ast::Attribute>*>(node));
290  case Node::FunctionCallNode : return this->derived().traverse(static_cast<NodeType<ast::FunctionCall>*>(node));
291  case Node::ExternalVariableNode : return this->derived().traverse(static_cast<NodeType<ast::ExternalVariable>*>(node));
292  case Node::DeclareLocalNode : return this->derived().traverse(static_cast<NodeType<ast::DeclareLocal>*>(node));
293  case Node::ArrayPackNode : return this->derived().traverse(static_cast<NodeType<ast::ArrayPack>*>(node));
294  case Node::ArrayUnpackNode : return this->derived().traverse(static_cast<NodeType<ast::ArrayUnpack>*>(node));
295  case Node::LocalNode : return this->derived().traverse(static_cast<NodeType<ast::Local>*>(node));
296  case Node::ValueBoolNode : return this->derived().traverse(static_cast<NodeType<ast::Value<bool>>*>(node));
297  case Node::ValueInt16Node : return this->derived().traverse(static_cast<NodeType<ast::Value<int16_t>>*>(node));
298  case Node::ValueInt32Node : return this->derived().traverse(static_cast<NodeType<ast::Value<int32_t>>*>(node));
299  case Node::ValueInt64Node : return this->derived().traverse(static_cast<NodeType<ast::Value<int64_t>>*>(node));
300  case Node::ValueFloatNode : return this->derived().traverse(static_cast<NodeType<ast::Value<float>>*>(node));
301  case Node::ValueDoubleNode : return this->derived().traverse(static_cast<NodeType<ast::Value<double>>*>(node));
302  case Node::ValueStrNode : return this->derived().traverse(static_cast<NodeType<ast::Value<std::string>>*>(node));
303  default : return true;
304  }
305  }
306 
308 
311 
316  inline bool visit(NodeType<ast::Node>*) { return true; }
317  inline bool visit(NodeType<ast::Statement>*) { return true; }
318  inline bool visit(NodeType<ast::Expression>*) { return true; }
319  inline bool visit(NodeType<ast::Variable>*) { return true; }
320  inline bool visit(NodeType<ast::ValueBase>*) { return true; }
321 
324  inline bool visit(NodeType<ast::Tree>*) { return true; }
325  inline bool visit(NodeType<ast::StatementList>*) { return true; }
326  inline bool visit(NodeType<ast::Block>*) { return true; }
327  inline bool visit(NodeType<ast::CommaOperator>*) { return true; }
328  inline bool visit(NodeType<ast::Loop>*) { return true; }
329  inline bool visit(NodeType<ast::Keyword>*) { return true; }
330  inline bool visit(NodeType<ast::ConditionalStatement>*) { return true; }
331  inline bool visit(NodeType<ast::AssignExpression>*) { return true; }
332  inline bool visit(NodeType<ast::Crement>*) { return true; }
333  inline bool visit(NodeType<ast::UnaryOperator>*) { return true; }
334  inline bool visit(NodeType<ast::BinaryOperator>*) { return true; }
335  inline bool visit(NodeType<ast::TernaryOperator>*) { return true; }
336  inline bool visit(NodeType<ast::Cast>*) { return true; }
337  inline bool visit(NodeType<ast::FunctionCall>*) { return true; }
338  inline bool visit(NodeType<ast::Attribute>*) { return true; }
339  inline bool visit(NodeType<ast::ExternalVariable>*) { return true; }
340  inline bool visit(NodeType<ast::DeclareLocal>*) { return true; }
341  inline bool visit(NodeType<ast::Local>*) { return true; }
342  inline bool visit(NodeType<ast::ArrayPack>*) { return true; }
343  inline bool visit(NodeType<ast::ArrayUnpack>*) { return true; }
344  inline bool visit(NodeType<ast::Value<bool>>*) { return true; }
345  inline bool visit(NodeType<ast::Value<int16_t>>*) { return true; }
346  inline bool visit(NodeType<ast::Value<int32_t>>*) { return true; }
347  inline bool visit(NodeType<ast::Value<int64_t>>*) { return true; }
348  inline bool visit(NodeType<ast::Value<float>>*) { return true; }
349  inline bool visit(NodeType<ast::Value<double>>*) { return true; }
350  inline bool visit(NodeType<ast::Value<std::string>>*) { return true; }
351 
353 
354 private:
359  template <bool V, typename NodeT>
360  inline typename std::enable_if<V, const NodeT*>::type
361  strip(const NodeT& node) {
362  return &node;
363  }
364 
369  template <bool V, typename NodeT>
370  inline typename std::enable_if<!V, typename std::remove_const<NodeT>::type*>::type
371  strip(const NodeT& node) {
372  return &(const_cast<NodeT&>(node));
373  }
374 
379  template <typename NodeT>
380  bool hierarchyVisits(NodeT& node)
381  {
382  if (this->derived().reverseHierarchyVisits()) {
383  if (auto base = node.NodeT::basetype()) {
384  if (!hierarchyVisits(*base)) return false;
385  }
386  if (!this->derived().visit(this->strip<ConstVisit>(node))) return false;
387  }
388  else {
389  if (!this->derived().visit(this->strip<ConstVisit>(node))) return false;
390  if (auto base = node.NodeT::basetype()) {
391  return hierarchyVisits(*base);
392  }
393  }
394  return true;
395  }
396 
402  template <typename NodeT>
403  inline bool defaultTraversal(NodeType<NodeT>* node)
404  {
405  if (!node) return true;
406  const size_t children = node->children();
407 
408  if (this->derived().postOrderNodes()) {
409  if (this->derived().reverseChildVisits()) {
410  if (children != 0) {
411  for (int64_t i = static_cast<int64_t>(children - 1); i >= 0; --i) {
412  auto child = this->strip<ConstVisit>(*(node->child(i)));
413  if (!this->derived().traverse(child)) {
414  return false;
415  }
416  }
417  }
418  }
419  else {
420  for (size_t i = 0; i < children; ++i) {
421  auto child = this->strip<ConstVisit>(*(node->child(i)));
422  if (!this->derived().traverse(child)) {
423  return false;
424  }
425  }
426  }
427  if (this->derived().visitNodeHierarchies()) {
428  return this->hierarchyVisits(*node);
429  }
430  else {
431  return this->derived().visit(node);
432  }
433  }
434  else {
435  if (this->derived().visitNodeHierarchies()) {
436  if (!this->hierarchyVisits(*node)) return false;
437  }
438  else {
439  if (!this->derived().visit(node)) return false;
440  }
441  if (this->derived().reverseChildVisits()) {
442  if (children != 0) {
443  for (int64_t i = static_cast<int64_t>(children - 1); i >= 0; --i) {
444  auto child = this->strip<ConstVisit>(*(node->child(i)));
445  if (!this->derived().traverse(child)) {
446  return false;
447  }
448  }
449  }
450  }
451  else {
452  for (size_t i = 0; i < children; ++i) {
453  auto child = this->strip<ConstVisit>(*(node->child(i)));
454  if (!this->derived().traverse(child)) {
455  return false;
456  }
457  }
458  }
459  return true;
460  }
461  }
462 };
463 
464 } // namespace ast
465 } // namespace ax
466 
467 } // namespace OPENVDB_VERSION_NAME
468 } // namespace openvdb
469 
470 #endif // OPENVDB_AX_AST_VISITOR_HAS_BEEN_INCLUDED
471 
bool visit(NodeType< ast::Attribute > *)
Visits for abstract (pure-virtual) Node types.
Definition: Visitor.h:338
bool traverse(NodeType< ast::Cast > *cast)
Default traversals for a given concrete AST node type.
Definition: Visitor.h:209
Provides the definition for every abstract and concrete derived class which represent a particular ab...
bool visit(NodeType< ast::Value< float >> *)
Visits for abstract (pure-virtual) Node types.
Definition: Visitor.h:348
bool visit(NodeType< ast::Loop > *)
Visits for abstract (pure-virtual) Node types.
Definition: Visitor.h:328
bool visit(NodeType< ast::Local > *)
Visits for abstract (pure-virtual) Node types.
Definition: Visitor.h:341
bool visit(NodeType< ast::DeclareLocal > *)
Visits for abstract (pure-virtual) Node types.
Definition: Visitor.h:340
bool traverse(NodeType< ast::Value< double >> *val)
Default traversals for a given concrete AST node type.
Definition: Visitor.h:261
bool visit(NodeType< ast::ConditionalStatement > *)
Visits for abstract (pure-virtual) Node types.
Definition: Visitor.h:330
bool traverse(NodeType< ast::Value< std::string >> *val)
Default traversals for a given concrete AST node type.
Definition: Visitor.h:265
bool visit(NodeType< ast::ArrayPack > *)
Visits for abstract (pure-virtual) Node types.
Definition: Visitor.h:342
bool traverse(NodeType< ast::DeclareLocal > *decl)
Default traversals for a given concrete AST node type.
Definition: Visitor.h:225
bool visit(NodeType< ast::Value< bool >> *)
Visits for abstract (pure-virtual) Node types.
Definition: Visitor.h:344
bool traverse(NodeType< ast::Loop > *loop)
Default traversals for a given concrete AST node type.
Definition: Visitor.h:177
bool traverse(NodeType< ast::Block > *block)
Default traversals for a given concrete AST node type.
Definition: Visitor.h:169
bool visit(NodeType< ast::ValueBase > *)
Visits for abstract (pure-virtual) Node types.
Definition: Visitor.h:320
bool visit(NodeType< ast::Keyword > *)
Visits for abstract (pure-virtual) Node types.
Definition: Visitor.h:329
bool traverse(NodeType< ast::Node > *node)
The default traversal method which is hit for all child traversals. The correct derived traversal sch...
Definition: Visitor.h:273
bool visit(NodeType< ast::Value< std::string >> *)
Visits for abstract (pure-virtual) Node types.
Definition: Visitor.h:350
bool visit(NodeType< ast::Value< double >> *)
Visits for abstract (pure-virtual) Node types.
Definition: Visitor.h:349
bool postOrderNodes() const
Default behavior option. If true, this results in post-order traversal, where node children are trave...
Definition: Visitor.h:122
bool visit(NodeType< ast::CommaOperator > *)
Visits for abstract (pure-virtual) Node types.
Definition: Visitor.h:327
bool reverseChildVisits() const
Default behavior option. Reverses the traversal order of child nodes. If true, child nodes are access...
Definition: Visitor.h:128
bool traverse(NodeType< ast::AssignExpression > *asgn)
Default traversals for a given concrete AST node type.
Definition: Visitor.h:189
bool traverse(NodeType< ast::Attribute > *attr)
Default traversals for a given concrete AST node type.
Definition: Visitor.h:217
bool visitNodeHierarchies() const
Default behavior option. Controls whether nodes visit themselves at each stage of their class hierarc...
Definition: Visitor.h:141
bool traverse(NodeType< ast::ArrayPack > *pack)
Default traversals for a given concrete AST node type.
Definition: Visitor.h:233
bool visit(NodeType< ast::Statement > *)
Visits for abstract (pure-virtual) Node types.
Definition: Visitor.h:317
bool traverse(NodeType< ast::CommaOperator > *comma)
Default traversals for a given concrete AST node type.
Definition: Visitor.h:173
bool visit(NodeType< ast::StatementList > *)
Visits for abstract (pure-virtual) Node types.
Definition: Visitor.h:325
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:94
bool visit(NodeType< ast::Tree > *)
Visits for concrete Node types.
Definition: Visitor.h:324
bool visit(NodeType< ast::Value< int16_t >> *)
Visits for abstract (pure-virtual) Node types.
Definition: Visitor.h:345
The Visitor class uses the Curiously Recursive Template Pattern (CRTP) to provide a customizable inte...
Definition: Visitor.h:95
typename std::conditional< true, const NodeT, NodeT >::type NodeType
Templated conditional which resolves to a const NodeT if ConstVisit is true, or a non-const NodeT if ...
Definition: Visitor.h:100
bool traverse(NodeType< ast::BinaryOperator > *bin)
Default traversals for a given concrete AST node type.
Definition: Visitor.h:201
bool traverse(NodeType< ast::Tree > *tree)
Default traversals for a given concrete AST node type.
Definition: Visitor.h:161
Definition: openvdb/Exceptions.h:13
bool visit(NodeType< ast::TernaryOperator > *)
Visits for abstract (pure-virtual) Node types.
Definition: Visitor.h:335
Specialization of Values for strings.
Definition: AST.h:2334
bool visit(NodeType< ast::Crement > *)
Visits for abstract (pure-virtual) Node types.
Definition: Visitor.h:332
bool traverse(NodeType< ast::TernaryOperator > *tern)
Default traversals for a given concrete AST node type.
Definition: Visitor.h:205
bool traverse(NodeType< ast::StatementList > *cond)
Default traversals for a given concrete AST node type.
Definition: Visitor.h:165
bool traverse(NodeType< ast::Local > *loc)
Default traversals for a given concrete AST node type.
Definition: Visitor.h:229
Library and file format version numbers.
bool traverse(NodeType< ast::FunctionCall > *call)
Default traversals for a given concrete AST node type.
Definition: Visitor.h:213
bool traverse(NodeType< ast::Value< int64_t >> *val)
Default traversals for a given concrete AST node type.
Definition: Visitor.h:253
bool visit(NodeType< ast::Block > *)
Visits for abstract (pure-virtual) Node types.
Definition: Visitor.h:326
bool visit(NodeType< ast::ArrayUnpack > *)
Visits for abstract (pure-virtual) Node types.
Definition: Visitor.h:343
bool traverse(NodeType< ast::Keyword > *keyw)
Default traversals for a given concrete AST node type.
Definition: Visitor.h:181
bool traverse(NodeType< ast::ConditionalStatement > *cond)
Default traversals for a given concrete AST node type.
Definition: Visitor.h:185
bool visit(NodeType< ast::Variable > *)
Visits for abstract (pure-virtual) Node types.
Definition: Visitor.h:319
Various function and operator tokens used throughout the AST and code generation. ...
bool traverse(NodeType< ast::ArrayUnpack > *pack)
Default traversals for a given concrete AST node type.
Definition: Visitor.h:237
A Value (literal) AST node holds either literal text or absolute value information on all numerical...
Definition: AST.h:2252
bool visit(NodeType< ast::Expression > *)
Visits for abstract (pure-virtual) Node types.
Definition: Visitor.h:318
bool visit(NodeType< ast::ExternalVariable > *)
Visits for abstract (pure-virtual) Node types.
Definition: Visitor.h:339
bool visit(NodeType< ast::Node > *)
Visits for abstract (pure-virtual) Node types.
Definition: Visitor.h:316
bool visit(NodeType< ast::Cast > *)
Visits for abstract (pure-virtual) Node types.
Definition: Visitor.h:336
bool traverse(NodeType< ast::Crement > *crmt)
Default traversals for a given concrete AST node type.
Definition: Visitor.h:193
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:146
bool traverse(NodeType< ast::Value< bool >> *val)
Default traversals for a given concrete AST node type.
Definition: Visitor.h:241
bool traverse(NodeType< ast::Value< int32_t >> *val)
Default traversals for a given concrete AST node type.
Definition: Visitor.h:249
bool traverse(NodeType< ast::Value< int16_t >> *val)
Default traversals for a given concrete AST node type.
Definition: Visitor.h:245
bool visit(NodeType< ast::BinaryOperator > *)
Visits for abstract (pure-virtual) Node types.
Definition: Visitor.h:334
bool traverse(NodeType< ast::UnaryOperator > *unry)
Default traversals for a given concrete AST node type.
Definition: Visitor.h:197
bool visit(NodeType< ast::UnaryOperator > *)
Visits for abstract (pure-virtual) Node types.
Definition: Visitor.h:333
bool visit(NodeType< ast::Value< int32_t >> *)
Visits for abstract (pure-virtual) Node types.
Definition: Visitor.h:346
bool visit(NodeType< ast::AssignExpression > *)
Visits for abstract (pure-virtual) Node types.
Definition: Visitor.h:331
bool traverse(NodeType< ast::Value< float >> *val)
Default traversals for a given concrete AST node type.
Definition: Visitor.h:257
Derived & derived()
Accesses the derived class by static casting the current object. Assumes use of the Curiously Recursi...
Definition: Visitor.h:104
bool visit(NodeType< ast::FunctionCall > *)
Visits for abstract (pure-virtual) Node types.
Definition: Visitor.h:337
bool reverseHierarchyVisits() const
Default behavior option. Reverses the traversal order of node hierarchies. If true, hierarchical visits start at the very top of their inheritance structure (always a Node AST node) and visit downwards until the lowest derived concrete node is reached. If false, hierarchical visits start at the lowest derived concrete node and visit upwards until the very top of their inheritance structure (always a Node AST node) is reached.
Definition: Visitor.h:151
bool traverse(NodeType< ast::ExternalVariable > *ext)
Default traversals for a given concrete AST node type.
Definition: Visitor.h:221
bool visit(NodeType< ast::Value< int64_t >> *)
Visits for abstract (pure-virtual) Node types.
Definition: Visitor.h:347