diff options
| author | Martial Simon <msimon_fr@hotmail.com> | 2025-09-15 01:07:58 +0200 |
|---|---|---|
| committer | Martial Simon <msimon_fr@hotmail.com> | 2025-09-15 01:07:58 +0200 |
| commit | 967be9e750221ab2ab783f95df79bb26d290a45e (patch) | |
| tree | 6802900a5e975f9f68b169f0f503f040056d6952 /tiger-compiler/src/ast/visitor.hh | |
Diffstat (limited to 'tiger-compiler/src/ast/visitor.hh')
| -rw-r--r-- | tiger-compiler/src/ast/visitor.hh | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/tiger-compiler/src/ast/visitor.hh b/tiger-compiler/src/ast/visitor.hh new file mode 100644 index 0000000..420db00 --- /dev/null +++ b/tiger-compiler/src/ast/visitor.hh @@ -0,0 +1,114 @@ +/** + ** \file ast/visitor.hh + ** \brief Definition of ast::Visitor. + */ + +#pragma once + +#include <functional> +#include <ast/fwd.hh> +#include <misc/select-const.hh> + +namespace ast +{ + /** \brief Root class of all Ast visitors. + ** + ** GenVisitor<CONSTIFY> is the root class of all Ast visitors. */ + template <template <typename> class Const> class GenVisitor + { + /** \name Ctor & dtor. + ** \{ */ + public: + /// Convenient abbreviation. + template <typename Type> using const_t = typename Const<Type>::type; + + /// Destroy a GenVisitor. + virtual ~GenVisitor(); + /** \} */ + + /// The entry point: visit \a e. + virtual void operator()(const_t<Ast>& e); + virtual void operator()(const_t<ArrayExp>&) = 0; + virtual void operator()(const_t<ArrayTy>&) = 0; + virtual void operator()(const_t<AssignExp>&) = 0; + virtual void operator()(const_t<BreakExp>&) = 0; + virtual void operator()(const_t<CallExp>&) = 0; + virtual void operator()(const_t<CastExp>&) = 0; + virtual void operator()(const_t<ChunkList>&) = 0; + virtual void operator()(const_t<ClassTy>&) = 0; + virtual void operator()(const_t<Field>&) = 0; + virtual void operator()(const_t<FieldInit>&) = 0; + virtual void operator()(const_t<FieldVar>&) = 0; + virtual void operator()(const_t<ForExp>&) = 0; + virtual void operator()(const_t<FunctionDec>&) = 0; + virtual void operator()(const_t<IfExp>&) = 0; + virtual void operator()(const_t<IntExp>&) = 0; + virtual void operator()(const_t<LetExp>&) = 0; + virtual void operator()(const_t<MethodCallExp>&) = 0; + virtual void operator()(const_t<MethodDec>&) = 0; + virtual void operator()(const_t<NameTy>&) = 0; + virtual void operator()(const_t<NilExp>&) = 0; + virtual void operator()(const_t<ObjectExp>&) = 0; + virtual void operator()(const_t<OpExp>&) = 0; + virtual void operator()(const_t<RecordExp>&) = 0; + virtual void operator()(const_t<RecordTy>&) = 0; + virtual void operator()(const_t<SeqExp>&) = 0; + virtual void operator()(const_t<SimpleVar>&) = 0; + virtual void operator()(const_t<StringExp>&) = 0; + virtual void operator()(const_t<SubscriptVar>&) = 0; + virtual void operator()(const_t<TypeDec>&) = 0; + virtual void operator()(const_t<VarDec>&) = 0; + virtual void operator()(const_t<WhileExp>&) = 0; + + virtual void operator()(const_t<FunctionChunk>&) = 0; + virtual void operator()(const_t<MethodChunk>&) = 0; + virtual void operator()(const_t<TypeChunk>&) = 0; + virtual void operator()(const_t<VarChunk>&) = 0; + + virtual void operator()(const_t<AssertExp>&) = 0; + + /// Helper to visit nodes manipulated via a pointer. + template <class E> void operator()(E* e); + + protected: + /** A convenient shortcut for recurring code like this: + + \code + if (e) + e->accept(*this); + \endcode + + However, the drawback of this approach is that it doesn't take + care of the constness, and any \a const violation will be + reported \em within the body of this method, not at its + corresponding call site. + + We cannot use the misc/select_const.hh approach here, since + the compiler cannot resolve a function overloaded or + specialized on an associated type of a template. E.g., writing + \a accept like this: + + \code + template <typename E> + void accept(const_t<E>* e); + \endcode + + won't work directly. Of course, one can help the compiler, + providing it with \a E + + \code + accept<ast::NameTy>(e.result_get()); + \endcode + + but this is painful. */ + template <typename E> void accept(E* e); + }; + + /// Shorthand for a const visitor. + using ConstVisitor = GenVisitor<misc::constify_traits>; + /// Shorthand for a non const visitor. + using Visitor = GenVisitor<misc::id_traits>; + +} // namespace ast + +#include <ast/visitor.hxx> |
