[nest] Add statement-related base classes (#662)
author박종현/동작제어Lab(SR)/Staff Engineer/삼성전자 <jh1302.park@samsung.com>
Mon, 16 Jul 2018 05:43:52 +0000 (14:43 +0900)
committerGitHub Enterprise <noreply-CODE@samsung.com>
Mon, 16 Jul 2018 05:43:52 +0000 (14:43 +0900)
This commit adds the follwoing statement-related base classes under
'nest::stmt' namespace:
 - Node
 - Visitor

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

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

diff --git a/contrib/nest/include/nest/Stmt.h b/contrib/nest/include/nest/Stmt.h
new file mode 100644 (file)
index 0000000..fb8d8dc
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef __NEST_STMT_H__
+#define __NEST_STMT_H__
+
+#include "nest/stmt/Node.h"
+#include "nest/stmt/Visitor.h"
+
+#endif // __NEST_STMT_H__
diff --git a/contrib/nest/include/nest/stmt/Forward.h b/contrib/nest/include/nest/stmt/Forward.h
new file mode 100644 (file)
index 0000000..e4dfd05
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef __NEST_STMT_FORWARD_H__
+#define __NEST_STMT_FORWARD_H__
+
+#include "nest/stmt/Macro.h"
+
+namespace nest
+{
+namespace stmt
+{
+
+#define STMT(Tag) class NEST_STMT_CLASS_NAME(Tag);
+#include "nest/stmt/Node.def"
+#undef STMT
+
+} // namespace stmt
+} // namespace nest
+
+#endif // __NEST_STMT_FORWARD_H__
diff --git a/contrib/nest/include/nest/stmt/Macro.h b/contrib/nest/include/nest/stmt/Macro.h
new file mode 100644 (file)
index 0000000..30073b1
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef __NEST_STMT_MACRO_H__
+#define __NEST_STMT_MACRO_H__
+
+#ifndef NEST_STMT_CLASS_NAME
+#define NEST_STMT_CLASS_NAME(Tag) Tag##Node
+#endif // NEST_STMT_CLASS_NAME
+
+#ifndef NEST_STMT_CAST_METHOD_NAME
+#define NEST_STMT_CAST_METHOD_NAME(Tag) as##Tag
+#endif // STMT_CAST_METHOD_NAME
+
+#endif // __NEST_STMT_MACRO_H__
diff --git a/contrib/nest/include/nest/stmt/Node.def b/contrib/nest/include/nest/stmt/Node.def
new file mode 100644 (file)
index 0000000..26c8943
--- /dev/null
@@ -0,0 +1,5 @@
+#ifndef STMT
+#error STMT is should be defined before including this file
+#endif
+
+// STMT(Tag)
diff --git a/contrib/nest/include/nest/stmt/Node.h b/contrib/nest/include/nest/stmt/Node.h
new file mode 100644 (file)
index 0000000..5d52caf
--- /dev/null
@@ -0,0 +1,46 @@
+#ifndef __NEST_STMT_NODE_H__
+#define __NEST_STMT_NODE_H__
+
+#include "nest/stmt/Macro.h"
+#include "nest/stmt/Forward.h"
+#include "nest/stmt/Visitor.h"
+
+#include <stdexcept>
+
+namespace nest
+{
+namespace stmt
+{
+
+struct Node
+{
+  virtual ~Node() = default;
+
+#define STMT(Tag)                                                                       \
+  virtual const NEST_STMT_CLASS_NAME(Tag) * NEST_STMT_CAST_METHOD_NAME(Tag)(void) const \
+  {                                                                                     \
+    return nullptr;                                                                     \
+  }
+#include "nest/stmt/Node.def"
+#undef STMT
+
+  template <typename T> T accept(Visitor<T> *v)
+  {
+#define STMT(Tag)                                 \
+  if (auto s = NEST_STMT_CAST_METHOD_NAME(Tag)()) \
+  {                                               \
+    return v->visit(s);                           \
+  }
+#include "nest/stmt/Node.def"
+#undef STMT
+
+    throw std::runtime_error{"unreachable"};
+  }
+
+  template <typename T> T accept(Visitor<T> &v) { return accept(&v); }
+};
+
+} // namespace stmt
+} // namespace nest
+
+#endif // __NEST_STMT_NODE_H__
diff --git a/contrib/nest/include/nest/stmt/Visitor.h b/contrib/nest/include/nest/stmt/Visitor.h
new file mode 100644 (file)
index 0000000..c915b4a
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef __NEST_STMT_VISITOR_H__
+#define __NEST_STMT_VISITOR_H__
+
+#include "nest/stmt/Macro.h"
+#include "nest/stmt/Forward.h"
+
+namespace nest
+{
+namespace stmt
+{
+
+template <typename T> struct Visitor
+{
+  virtual ~Visitor() = default;
+
+#define STMT(Tag) virtual T visit(const NEST_STMT_CLASS_NAME(Tag) *) = 0;
+#include "nest/stmt/Node.def"
+#undef STMT
+};
+
+} // namespace stmt
+} // namespace nest
+
+#endif // __NEST_STMT_VISITOR_H__
diff --git a/contrib/nest/src/stmt/Macro.cpp b/contrib/nest/src/stmt/Macro.cpp
new file mode 100644 (file)
index 0000000..cae5031
--- /dev/null
@@ -0,0 +1,5 @@
+#include "nest/stmt/Macro.h"
+
+// This file checkes the self-completeness of 'nest/stmt/Macro.h'.
+//
+// NOTE Please do NOT remove this file.
diff --git a/contrib/nest/src/stmt/Node.cpp b/contrib/nest/src/stmt/Node.cpp
new file mode 100644 (file)
index 0000000..a0bb830
--- /dev/null
@@ -0,0 +1,5 @@
+#include "nest/stmt/Node.h"
+
+// This file checkes the self-completeness of 'nest/stmt/Node.h'.
+//
+// NOTE Please do NOT remove this file.
diff --git a/contrib/nest/src/stmt/Visitor.cpp b/contrib/nest/src/stmt/Visitor.cpp
new file mode 100644 (file)
index 0000000..62cca1f
--- /dev/null
@@ -0,0 +1,5 @@
+#include "nest/stmt/Visitor.h"
+
+// This file checkes the self-completeness of 'nest/stmt/Visitor.h'.
+//
+// NOTE Please do NOT remove this file.