summaryrefslogtreecommitdiff
path: root/source/slang/visitor.h
diff options
context:
space:
mode:
authorTim Foley <tfoley@nvidia.com>2017-06-29 08:55:09 -0700
committerTim Foley <tfoley@nvidia.com>2017-06-30 12:22:33 -0700
commitcab694dcead92a554654d7fa3f08909d519425f0 (patch)
tree6c2c07c3930ff68b5518e562b0b507d5ec54d0bf /source/slang/visitor.h
parentb2b08679a32506d629df84730f36639dab9f9593 (diff)
Add meta-definitions for AST types
- The big change here is that all the definitions for syntax-node classes have been macro-ized, to that we can do light metaprogramming over them - The use of macros for this has big down-sides, but I'm not quite ready to do anything more heavy-weight right now - The macro-ized definitions can be included multiple times, to generate different declarations/code as needed - The first example of using this meta-programming facility is a new visitor system - The actual visitor base classes and the dispatch logic are all generated from the meta-files - There was only one visitor left in the code: the semantics checker, so that was ported to the new system. - All current test cases pass, so *of course* that means all is well.
Diffstat (limited to 'source/slang/visitor.h')
-rw-r--r--source/slang/visitor.h346
1 files changed, 346 insertions, 0 deletions
diff --git a/source/slang/visitor.h b/source/slang/visitor.h
new file mode 100644
index 000000000..391769eca
--- /dev/null
+++ b/source/slang/visitor.h
@@ -0,0 +1,346 @@
+// visitor.h
+#ifndef SLANG_VISITOR_H_INCLUDED
+#define SLANG_VISITOR_H_INCLUDED
+
+// This file defines the basic "Visitor" pattern for doing dispatch
+// over the various categories of syntax node.
+
+#include "syntax.h"
+
+namespace Slang {
+
+//
+// Type Visitors
+//
+
+struct ITypeVisitor
+{
+#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
+#define SYNTAX_CLASS(NAME, BASE) \
+ virtual void dispatch_##NAME(NAME* obj, void* extra) = 0;
+
+#include "object-meta-begin.h"
+#include "type-defs.h"
+#include "object-meta-end.h"
+};
+
+template<typename Derived, typename Result = void>
+struct TypeVisitor : ITypeVisitor
+{
+ Result dispatch(ExpressionType* type)
+ {
+ Result result;
+ type->accept(this, &result);
+ return result;
+ }
+
+#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
+#define SYNTAX_CLASS(NAME, BASE) \
+ virtual void dispatch_##NAME(NAME* obj, void* extra) override \
+ { *(Result*)extra = ((Derived*) this)->visit(obj); }
+
+#include "object-meta-begin.h"
+#include "type-defs.h"
+#include "object-meta-end.h"
+
+};
+
+template<typename Derived>
+struct TypeVisitor<Derived,void> : ITypeVisitor
+{
+ void dispatch(ExpressionType* type)
+ {
+ type->accept(this, 0);
+ }
+
+#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
+#define SYNTAX_CLASS(NAME, BASE) \
+ virtual void dispatch_##NAME(NAME* obj, void*) override \
+ { ((Derived*) this)->visit(obj); }
+
+#include "object-meta-begin.h"
+#include "type-defs.h"
+#include "object-meta-end.h"
+
+};
+
+//
+// Expression Visitors
+//
+
+struct IExprVisitor
+{
+#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
+#define SYNTAX_CLASS(NAME, BASE) \
+ virtual void dispatch_##NAME(NAME* obj, void* extra) = 0;
+
+#include "object-meta-begin.h"
+#include "expr-defs.h"
+#include "object-meta-end.h"
+};
+
+template<typename Derived, typename Result = void>
+struct ExprVisitor : IExprVisitor
+{
+ Result dispatch(ExpressionSyntaxNode* expr)
+ {
+ Result result;
+ expr->accept(this, &result);
+ return result;
+ }
+
+#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
+#define SYNTAX_CLASS(NAME, BASE) \
+ virtual void dispatch_##NAME(NAME* obj, void* extra) override \
+ { *(Result*)extra = ((Derived*) this)->visit(obj); }
+
+#include "object-meta-begin.h"
+#include "expr-defs.h"
+#include "object-meta-end.h"
+
+};
+
+template<typename Derived>
+struct ExprVisitor<Derived,void> : IExprVisitor
+{
+ void dispatch(ExpressionSyntaxNode* expr)
+ {
+ expr->accept(this, 0);
+ }
+
+#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
+#define SYNTAX_CLASS(NAME, BASE) \
+ virtual void dispatch_##NAME(NAME* obj, void*) override \
+ { ((Derived*) this)->visit(obj); }
+
+#include "object-meta-begin.h"
+#include "expr-defs.h"
+#include "object-meta-end.h"
+
+};
+
+//
+// Statement Visitors
+//
+
+struct IStmtVisitor
+{
+#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
+#define SYNTAX_CLASS(NAME, BASE) \
+ virtual void dispatch_##NAME(NAME* obj, void* extra) = 0;
+
+#include "object-meta-begin.h"
+#include "stmt-defs.h"
+#include "object-meta-end.h"
+};
+
+template<typename Derived, typename Result = void>
+struct StmtVisitor : IStmtVisitor
+{
+ Result dispatch(StatementSyntaxNode* stmt)
+ {
+ Result result;
+ stmt->accept(this, &result);
+ return result;
+ }
+
+#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
+#define SYNTAX_CLASS(NAME, BASE) \
+ virtual void dispatch_##NAME(NAME* obj, void* extra) override \
+ { *(Result*)extra = ((Derived*) this)->visit(obj); }
+
+#include "object-meta-begin.h"
+#include "stmt-defs.h"
+#include "object-meta-end.h"
+
+};
+
+template<typename Derived>
+struct StmtVisitor<Derived,void> : IStmtVisitor
+{
+ void dispatch(StatementSyntaxNode* stmt)
+ {
+ stmt->accept(this, 0);
+ }
+
+#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
+#define SYNTAX_CLASS(NAME, BASE) \
+ virtual void dispatch_##NAME(NAME* obj, void*) override \
+ { ((Derived*) this)->visit(obj); }
+
+#include "object-meta-begin.h"
+#include "stmt-defs.h"
+#include "object-meta-end.h"
+
+};
+
+//
+// Declaration Visitors
+//
+
+struct IDeclVisitor
+{
+#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
+#define SYNTAX_CLASS(NAME, BASE) \
+ virtual void dispatch_##NAME(NAME* obj, void* extra) = 0;
+
+#include "object-meta-begin.h"
+#include "decl-defs.h"
+#include "object-meta-end.h"
+};
+
+template<typename Derived, typename Result = void>
+struct DeclVisitor : IDeclVisitor
+{
+ Result dispatch(DeclBase* decl)
+ {
+ Result result;
+ decl->accept(this, &result);
+ return result;
+ }
+
+#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
+#define SYNTAX_CLASS(NAME, BASE) \
+ virtual void dispatch_##NAME(NAME* obj, void* extra) override \
+ { *(Result*)extra = ((Derived*) this)->visit(obj); }
+
+#include "object-meta-begin.h"
+#include "decl-defs.h"
+#include "object-meta-end.h"
+
+};
+
+template<typename Derived>
+struct DeclVisitor<Derived,void> : IDeclVisitor
+{
+ void dispatch(DeclBase* decl)
+ {
+ decl->accept(this, 0);
+ }
+
+#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
+#define SYNTAX_CLASS(NAME, BASE) \
+ virtual void dispatch_##NAME(NAME* obj, void*) override \
+ { ((Derived*) this)->visit(obj); }
+
+#include "object-meta-begin.h"
+#include "decl-defs.h"
+#include "object-meta-end.h"
+
+};
+
+//
+// Modifier Visitors
+//
+
+struct IModifierVisitor
+{
+#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
+#define SYNTAX_CLASS(NAME, BASE) \
+ virtual void dispatch_##NAME(NAME* obj, void* extra) = 0;
+
+#include "object-meta-begin.h"
+#include "modifier-defs.h"
+#include "object-meta-end.h"
+};
+
+template<typename Derived, typename Result = void>
+struct ModifierVisitor : IModifierVisitor
+{
+ Result dispatch(Modifier* modifier)
+ {
+ Result result;
+ modifier->accept(this, &result);
+ return result;
+ }
+
+#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
+#define SYNTAX_CLASS(NAME, BASE) \
+ virtual void dispatch_##NAME(NAME* obj, void* extra) override \
+ { *(Result*)extra = ((Derived*) this)->visit(obj); }
+
+#include "object-meta-begin.h"
+#include "modifier-defs.h"
+#include "object-meta-end.h"
+
+};
+
+template<typename Derived>
+struct ModifierVisitor<Derived, void> : IModifierVisitor
+{
+ void dispatch(Modifier* modifier)
+ {
+ modifier->accept(this, 0);
+ }
+
+#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
+#define SYNTAX_CLASS(NAME, BASE) \
+ virtual void dispatch_##NAME(NAME* obj, void*) override \
+ { ((Derived*) this)->visit(obj); }
+
+#include "object-meta-begin.h"
+#include "modifier-defs.h"
+#include "object-meta-end.h"
+
+};
+
+//
+// Val Visitors
+//
+
+struct IValVisitor : ITypeVisitor
+{
+#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
+#define SYNTAX_CLASS(NAME, BASE) \
+ virtual void dispatch_##NAME(NAME* obj, void* extra) = 0;
+
+#include "object-meta-begin.h"
+#include "val-defs.h"
+#include "object-meta-end.h"
+};
+
+template<typename Derived, typename Result = void>
+struct ValVisitor : IValVisitor
+{
+ Result dispatch(Val* val)
+ {
+ Result result;
+ val->accept(this, &result);
+ return result;
+ }
+
+#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
+#define SYNTAX_CLASS(NAME, BASE) \
+ virtual void dispatch_##NAME(NAME* obj, void* extra) override \
+ { *(Result*)extra = ((Derived*) this)->visit(obj); }
+
+#include "object-meta-begin.h"
+#include "val-defs.h"
+#include "type-defs.h"
+#include "object-meta-end.h"
+
+};
+
+template<typename Derived>
+struct ValVisitor<Derived, void> : IValVisitor
+{
+ void dispatch(Val* val)
+ {
+ val->accept(this, 0);
+ }
+
+#define ABSTRACT_SYNTAX_CLASS(NAME,BASE) /* empty */
+#define SYNTAX_CLASS(NAME, BASE) \
+ virtual void dispatch_##NAME(NAME* obj, void*) override \
+ { ((Derived*) this)->visit(obj); }
+
+#include "object-meta-begin.h"
+#include "val-defs.h"
+#include "type-defs.h"
+#include "object-meta-end.h"
+
+};
+
+}
+
+#endif \ No newline at end of file