diff options
| author | Tim Foley <tfoley@nvidia.com> | 2017-06-29 08:55:09 -0700 |
|---|---|---|
| committer | Tim Foley <tfoley@nvidia.com> | 2017-06-30 12:22:33 -0700 |
| commit | cab694dcead92a554654d7fa3f08909d519425f0 (patch) | |
| tree | 6c2c07c3930ff68b5518e562b0b507d5ec54d0bf /source/slang/visitor.h | |
| parent | b2b08679a32506d629df84730f36639dab9f9593 (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.h | 346 |
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 |
