summaryrefslogtreecommitdiff
path: root/tiger-compiler/src/astclone/cloner.hh
diff options
context:
space:
mode:
Diffstat (limited to 'tiger-compiler/src/astclone/cloner.hh')
-rw-r--r--tiger-compiler/src/astclone/cloner.hh102
1 files changed, 102 insertions, 0 deletions
diff --git a/tiger-compiler/src/astclone/cloner.hh b/tiger-compiler/src/astclone/cloner.hh
new file mode 100644
index 0000000..f1405d1
--- /dev/null
+++ b/tiger-compiler/src/astclone/cloner.hh
@@ -0,0 +1,102 @@
+/**
+ ** \file astclone/cloner.hh
+ ** \brief Declaration of astclone::Cloner.
+ */
+
+#pragma once
+
+#include <ast/default-visitor.hh>
+
+namespace astclone
+{
+ /// \brief Duplicate an Ast.
+ class Cloner : public ast::DefaultConstVisitor
+ {
+ public:
+ using super_type = ast::DefaultConstVisitor;
+
+ // Import overloaded virtual functions.
+ using super_type::operator();
+
+ /// Build a Cloner.
+ Cloner();
+
+ /// Destroy a Cloner.
+ ~Cloner() override = default;
+
+ // Return the cloned Ast.
+ ast::Ast* result_get();
+
+ template <typename T> T* recurse(const T& t);
+
+ template <typename T> T* recurse(const T* t);
+
+ /** \brief Clone a collection object.
+
+ Using overloading for this method is tempting, but it would
+ lead to the same prototype than the first \a recurse method.
+
+ A partial specialization for \a std::list<T> would work, but is
+ not allowed by C++ standard. As a consequence, we are stuck to
+ using different names.
+ */
+ template <typename CollectionType>
+ CollectionType* recurse_collection(const CollectionType& c);
+
+ // Visit methods.
+ public:
+ void operator()(const ast::ArrayExp&) override;
+ void operator()(const ast::ArrayTy&) override;
+ void operator()(const ast::AssertExp&) override;
+ void operator()(const ast::AssignExp&) override;
+ void operator()(const ast::BreakExp&) override;
+ void operator()(const ast::CallExp&) override;
+ void operator()(const ast::CastExp&) override;
+ void operator()(const ast::ChunkList&) override;
+ void operator()(const ast::ClassTy&) override;
+ void operator()(const ast::Field&) override;
+ void operator()(const ast::FieldInit&) override;
+ void operator()(const ast::FieldVar&) override;
+ void operator()(const ast::ForExp&) override;
+ void operator()(const ast::FunctionDec&) override;
+ void operator()(const ast::IfExp&) override;
+ void operator()(const ast::IntExp&) override;
+ void operator()(const ast::LetExp&) override;
+ void operator()(const ast::MethodCallExp&) override;
+ void operator()(const ast::MethodDec&) override;
+ void operator()(const ast::NameTy&) override;
+ void operator()(const ast::NilExp&) override;
+ void operator()(const ast::ObjectExp&) override;
+ void operator()(const ast::OpExp&) override;
+ void operator()(const ast::RecordExp&) override;
+ void operator()(const ast::RecordTy&) override;
+ void operator()(const ast::SeqExp&) override;
+ void operator()(const ast::SimpleVar&) override;
+ void operator()(const ast::StringExp&) override;
+ void operator()(const ast::SubscriptVar&) override;
+ void operator()(const ast::TypeDec&) override;
+ void operator()(const ast::VarDec&) override;
+ void operator()(const ast::WhileExp&) override;
+
+ template <typename ChunkType>
+ /** \brief Visit a chunk (i.e., a list of Function, Var, and Type declarations).
+ **
+ ** It is exactly the same in the three cases, so the code is
+ ** factored via a template method. */
+ void chunk_visit(const ChunkType& e);
+
+ // As we can't mix template and virtual methods, we have to
+ // duplicate these methods. That's too bad. :(
+ void operator()(const ast::FunctionChunk&) override;
+ void operator()(const ast::MethodChunk&) override;
+ void operator()(const ast::TypeChunk&) override;
+ void operator()(const ast::VarChunk&) override;
+
+ protected:
+ /// The cloned Ast.
+ ast::Ast* result_;
+ };
+
+} // namespace astclone
+
+#include <astclone/cloner.hxx>