#pragma once
#include <libyul/ASTForward.h>
#include <libyul/YulString.h>
#include <memory>
#include <optional>
#include <set>
#include <vector>
#include <map>
namespace solidity::yul
{
class ExpressionCopier
{
public:
virtual ~ExpressionCopier() = default;
virtual Expression operator()(Literal const& _literal) = 0;
virtual Expression operator()(Identifier const& _identifier) = 0;
virtual Expression operator()(FunctionCall const&) = 0;
};
class StatementCopier
{
public:
virtual ~StatementCopier() = default;
virtual Statement operator()(ExpressionStatement const& _statement) = 0;
virtual Statement operator()(Assignment const& _assignment) = 0;
virtual Statement operator()(VariableDeclaration const& _varDecl) = 0;
virtual Statement operator()(If const& _if) = 0;
virtual Statement operator()(Switch const& _switch) = 0;
virtual Statement operator()(FunctionDefinition const&) = 0;
virtual Statement operator()(ForLoop const&) = 0;
virtual Statement operator()(Break const&) = 0;
virtual Statement operator()(Continue const&) = 0;
virtual Statement operator()(Leave const&) = 0;
virtual Statement operator()(Block const& _block) = 0;
};
class ASTCopier: public ExpressionCopier, public StatementCopier
{
public:
~ASTCopier() override = default;
Expression operator()(Literal const& _literal) override;
Expression operator()(Identifier const& _identifier) override;
Expression operator()(FunctionCall const&) override;
Statement operator()(ExpressionStatement const& _statement) override;
Statement operator()(Assignment const& _assignment) override;
Statement operator()(VariableDeclaration const& _varDecl) override;
Statement operator()(If const& _if) override;
Statement operator()(Switch const& _switch) override;
Statement operator()(FunctionDefinition const&) override;
Statement operator()(ForLoop const&) override;
Statement operator()(Break const&) override;
Statement operator()(Continue const&) override;
Statement operator()(Leave const&) override;
Statement operator()(Block const& _block) override;
virtual Expression translate(Expression const& _expression);
virtual Statement translate(Statement const& _statement);
Block translate(Block const& _block);
protected:
template <typename T>
std::vector<T> translateVector(std::vector<T> const& _values);
template <typename T>
std::unique_ptr<T> translate(std::unique_ptr<T> const& _v)
{
return _v ? std::make_unique<T>(translate(*_v)) : nullptr;
}
Case translate(Case const& _case);
virtual Identifier translate(Identifier const& _identifier);
Literal translate(Literal const& _literal);
TypedName translate(TypedName const& _typedName);
virtual void enterScope(Block const&) { }
virtual void leaveScope(Block const&) { }
virtual void enterFunction(FunctionDefinition const&) { }
virtual void leaveFunction(FunctionDefinition const&) { }
virtual YulString translateIdentifier(YulString _name) { return _name; }
};
template <typename T>
std::vector<T> ASTCopier::translateVector(std::vector<T> const& _values)
{
std::vector<T> translated;
for (auto const& v: _values)
translated.emplace_back(translate(v));
return translated;
}
class FunctionCopier: public ASTCopier
{
public:
FunctionCopier(
std::map<YulString, YulString> const& _translations
):
m_translations(_translations)
{}
using ASTCopier::operator();
YulString translateIdentifier(YulString _name) override;
private:
std::map<YulString, YulString> const& m_translations;
};
}