[nest] Add expression-related base classes (#661)
author박종현/동작제어Lab(SR)/Staff Engineer/삼성전자 <jh1302.park@samsung.com>
Mon, 16 Jul 2018 04:15:00 +0000 (13:15 +0900)
committerGitHub Enterprise <noreply-CODE@samsung.com>
Mon, 16 Jul 2018 04:15:00 +0000 (13:15 +0900)
This commit adds the following expression-related base classes (under
'nest::expr' namespace):
 - Node
 - Visitor

The boilterplate implementations of Node and Visitor are derived from
'Node.def' to make it easy to extend expressions.

Signed-off-by: Jonghyun Park <jh1302.park@samsung.com>
contrib/nest/include/nest/Expr.h [new file with mode: 0644]
contrib/nest/include/nest/expr/Forward.h [new file with mode: 0644]
contrib/nest/include/nest/expr/Macro.h [new file with mode: 0644]
contrib/nest/include/nest/expr/Node.def [new file with mode: 0644]
contrib/nest/include/nest/expr/Node.h [new file with mode: 0644]
contrib/nest/include/nest/expr/Visitor.h [new file with mode: 0644]
contrib/nest/src/expr/Macro.cpp [new file with mode: 0644]
contrib/nest/src/expr/Node.cpp [new file with mode: 0644]
contrib/nest/src/expr/Visitor.cpp [new file with mode: 0644]

diff --git a/contrib/nest/include/nest/Expr.h b/contrib/nest/include/nest/Expr.h
new file mode 100644 (file)
index 0000000..d7447d3
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef __NEST_EXPR_H__
+#define __NEST_EXPR_H__
+
+#include "nest/expr/Node.h"
+#include "nest/expr/Visitor.h"
+
+#endif // __NEST_EXPR_H__
diff --git a/contrib/nest/include/nest/expr/Forward.h b/contrib/nest/include/nest/expr/Forward.h
new file mode 100644 (file)
index 0000000..ca3b219
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef __NEST_EXPR_FORWARD_H__
+#define __NEST_EXPR_FORWARD_H__
+
+#include "nest/expr/Macro.h"
+
+namespace nest
+{
+namespace expr
+{
+
+#define EXPR(Tag) class NEST_EXPR_CLASS_NAME(Tag);
+#include "nest/expr/Node.def"
+#undef EXPR
+
+} // namespace expr
+} // namespace nest
+
+#endif // __NEST_EXPR_FORWARD_H__
diff --git a/contrib/nest/include/nest/expr/Macro.h b/contrib/nest/include/nest/expr/Macro.h
new file mode 100644 (file)
index 0000000..68d4785
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef __NEST_EXPR_MACRO_H__
+#define __NEST_EXPR_MACRO_H__
+
+#ifndef NEST_EXPR_CLASS_NAME
+#define NEST_EXPR_CLASS_NAME(Tag) Tag##Node
+#endif // NEST_EXPR_CLASS_NAME
+
+#ifndef NEST_EXPR_CAST_METHOD_NAME
+#define NEST_EXPR_CAST_METHOD_NAME(Tag) as##Tag
+#endif // NEST_EXPR_CAST_METHOD_NAME
+
+#endif // __NEST_EXPR_MACRO_H__
diff --git a/contrib/nest/include/nest/expr/Node.def b/contrib/nest/include/nest/expr/Node.def
new file mode 100644 (file)
index 0000000..64c522f
--- /dev/null
@@ -0,0 +1,5 @@
+#ifndef EXPR
+#error EXPR is should be defined before include this file
+#endif
+
+// EXPR(Tag)
diff --git a/contrib/nest/include/nest/expr/Node.h b/contrib/nest/include/nest/expr/Node.h
new file mode 100644 (file)
index 0000000..990045a
--- /dev/null
@@ -0,0 +1,46 @@
+#ifndef __NEST_EXPR_NODE_H__
+#define __NEST_EXPR_NODE_H__
+
+#include "nest/expr/Macro.h"
+#include "nest/expr/Forward.h"
+#include "nest/expr/Visitor.h"
+
+#include <stdexcept>
+
+namespace nest
+{
+namespace expr
+{
+
+struct Node
+{
+  virtual ~Node() = default;
+
+#define EXPR(Tag)                                                                       \
+  virtual const NEST_EXPR_CLASS_NAME(Tag) * NEST_EXPR_CAST_METHOD_NAME(Tag)(void) const \
+  {                                                                                     \
+    return nullptr;                                                                     \
+  }
+#include "nest/expr/Node.def"
+#undef EXPR
+
+  template <typename T> T accept(Visitor<T> *v)
+  {
+#define EXPR(Tag)                                 \
+  if (auto e = NEST_EXPR_CAST_METHOD_NAME(Tag)()) \
+  {                                               \
+    return v->visit(e);                           \
+  }
+#include "nest/expr/Node.def"
+#undef EXPR
+
+    throw std::runtime_error{"unreachable"};
+  }
+
+  template <typename T> T accept(Visitor<T> &v) { return accept(&v); }
+};
+
+} // namespace expr
+} // namespace nest
+
+#endif // __NEST_EXPR_NODE_H__
diff --git a/contrib/nest/include/nest/expr/Visitor.h b/contrib/nest/include/nest/expr/Visitor.h
new file mode 100644 (file)
index 0000000..b1c339b
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef __NEST_EXPR_VISITOR_H__
+#define __NEST_EXPR_VISITOR_H__
+
+#include "nest/expr/Macro.h"
+#include "nest/expr/Forward.h"
+
+namespace nest
+{
+namespace expr
+{
+
+template <typename T> struct Visitor
+{
+  virtual ~Visitor() = default;
+
+#define EXPR(Tag) virtual T visit(const NEST_EXPR_CLASS_NAME(Tag) *) = 0;
+#include "nest/expr/Node.def"
+#undef EXPR
+};
+
+} // namespace expr
+} // namespace nest
+
+#endif // __NEST_EXPR_VISITOR_H__
diff --git a/contrib/nest/src/expr/Macro.cpp b/contrib/nest/src/expr/Macro.cpp
new file mode 100644 (file)
index 0000000..a2ceaa7
--- /dev/null
@@ -0,0 +1,5 @@
+#include "nest/expr/Macro.h"
+
+// This file checkes the self-completeness of 'nest/expr/Macro.h'.
+//
+// NOTE Please do NOT remove this file.
diff --git a/contrib/nest/src/expr/Node.cpp b/contrib/nest/src/expr/Node.cpp
new file mode 100644 (file)
index 0000000..2c515e1
--- /dev/null
@@ -0,0 +1,5 @@
+#include "nest/expr/Node.h"
+
+// This file checkes the self-completeness of 'nest/expr/Node.h'.
+//
+// NOTE Please do NOT remove this file.
diff --git a/contrib/nest/src/expr/Visitor.cpp b/contrib/nest/src/expr/Visitor.cpp
new file mode 100644 (file)
index 0000000..b423fd1
--- /dev/null
@@ -0,0 +1,5 @@
+#include "nest/expr/Visitor.h"
+
+// This file checkes the self-completeness of 'nest/expr/Visitor.h'.
+//
+// NOTE Please do NOT remove this file.