From 10dc1c48eba6670f7598b3ebf6db5a2ba7ce213b Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EB=B0=95=EC=A2=85=ED=98=84/=EB=8F=99=EC=9E=91=EC=A0=9C?= =?utf8?q?=EC=96=B4Lab=28SR=29/Staff=20Engineer/=EC=82=BC=EC=84=B1?= =?utf8?q?=EC=A0=84=EC=9E=90?= Date: Mon, 16 Jul 2018 13:15:00 +0900 Subject: [PATCH] [nest] Add expression-related base classes (#661) 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 --- contrib/nest/include/nest/Expr.h | 7 +++++ contrib/nest/include/nest/expr/Forward.h | 18 +++++++++++++ contrib/nest/include/nest/expr/Macro.h | 12 +++++++++ contrib/nest/include/nest/expr/Node.def | 5 ++++ contrib/nest/include/nest/expr/Node.h | 46 ++++++++++++++++++++++++++++++++ contrib/nest/include/nest/expr/Visitor.h | 24 +++++++++++++++++ contrib/nest/src/expr/Macro.cpp | 5 ++++ contrib/nest/src/expr/Node.cpp | 5 ++++ contrib/nest/src/expr/Visitor.cpp | 5 ++++ 9 files changed, 127 insertions(+) create mode 100644 contrib/nest/include/nest/Expr.h create mode 100644 contrib/nest/include/nest/expr/Forward.h create mode 100644 contrib/nest/include/nest/expr/Macro.h create mode 100644 contrib/nest/include/nest/expr/Node.def create mode 100644 contrib/nest/include/nest/expr/Node.h create mode 100644 contrib/nest/include/nest/expr/Visitor.h create mode 100644 contrib/nest/src/expr/Macro.cpp create mode 100644 contrib/nest/src/expr/Node.cpp create mode 100644 contrib/nest/src/expr/Visitor.cpp diff --git a/contrib/nest/include/nest/Expr.h b/contrib/nest/include/nest/Expr.h new file mode 100644 index 0000000..d7447d3 --- /dev/null +++ b/contrib/nest/include/nest/Expr.h @@ -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 index 0000000..ca3b219 --- /dev/null +++ b/contrib/nest/include/nest/expr/Forward.h @@ -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 index 0000000..68d4785 --- /dev/null +++ b/contrib/nest/include/nest/expr/Macro.h @@ -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 index 0000000..64c522f --- /dev/null +++ b/contrib/nest/include/nest/expr/Node.def @@ -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 index 0000000..990045a --- /dev/null +++ b/contrib/nest/include/nest/expr/Node.h @@ -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 + +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 T accept(Visitor *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 T accept(Visitor &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 index 0000000..b1c339b --- /dev/null +++ b/contrib/nest/include/nest/expr/Visitor.h @@ -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 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 index 0000000..a2ceaa7 --- /dev/null +++ b/contrib/nest/src/expr/Macro.cpp @@ -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 index 0000000..2c515e1 --- /dev/null +++ b/contrib/nest/src/expr/Node.cpp @@ -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 index 0000000..b423fd1 --- /dev/null +++ b/contrib/nest/src/expr/Visitor.cpp @@ -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. -- 2.7.4