From cab694dcead92a554654d7fa3f08909d519425f0 Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Thu, 29 Jun 2017 08:55:09 -0700 Subject: 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. --- source/slang/visitor.h | 346 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 346 insertions(+) create mode 100644 source/slang/visitor.h (limited to 'source/slang/visitor.h') 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 +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 +struct TypeVisitor : 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 +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 +struct ExprVisitor : 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 +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 +struct StmtVisitor : 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 +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 +struct DeclVisitor : 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 +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 +struct ModifierVisitor : 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 +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 +struct ValVisitor : 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 -- cgit v1.2.3