diff options
Diffstat (limited to 'libyul/optimiser/SyntacticalEquality.h')
-rw-r--r-- | libyul/optimiser/SyntacticalEquality.h | 60 |
1 files changed, 51 insertions, 9 deletions
diff --git a/libyul/optimiser/SyntacticalEquality.h b/libyul/optimiser/SyntacticalEquality.h index 63c51b4f..d4630d95 100644 --- a/libyul/optimiser/SyntacticalEquality.h +++ b/libyul/optimiser/SyntacticalEquality.h @@ -21,27 +21,69 @@ #pragma once #include <libyul/AsmDataForward.h> +#include <libyul/YulString.h> -#include <vector> +#include <map> +#include <type_traits> namespace yul { + /** * Component that can compare ASTs for equality on a syntactic basis. - * Ignores source locations but requires exact matches otherwise. + * Ignores source locations and allows for different variable names but requires exact matches otherwise. * - * TODO: Only implemented for Expressions for now. - * A future version might also recognize renamed variables and thus could be used to - * remove duplicate functions. + * Prerequisite: Disambiguator (unless only expressions are compared) */ -class SyntacticalEqualityChecker +class SyntacticallyEqual { public: - static bool equal(Expression const& _e1, Expression const& _e2); + bool operator()(Expression const& _lhs, Expression const& _rhs); + bool operator()(Statement const& _lhs, Statement const& _rhs); + + bool expressionEqual(FunctionalInstruction const& _lhs, FunctionalInstruction const& _rhs); + bool expressionEqual(FunctionCall const& _lhs, FunctionCall const& _rhs); + bool expressionEqual(Identifier const& _lhs, Identifier const& _rhs); + bool expressionEqual(Literal const& _lhs, Literal const& _rhs); + + bool statementEqual(ExpressionStatement const& _lhs, ExpressionStatement const& _rhs); + bool statementEqual(Assignment const& _lhs, Assignment const& _rhs); + bool statementEqual(VariableDeclaration const& _lhs, VariableDeclaration const& _rhs); + bool statementEqual(FunctionDefinition const& _lhs, FunctionDefinition const& _rhs); + bool statementEqual(If const& _lhs, If const& _rhs); + bool statementEqual(Switch const& _lhs, Switch const& _rhs); + bool switchCaseEqual(Case const& _lhs, Case const& _rhs); + bool statementEqual(ForLoop const& _lhs, ForLoop const& _rhs); + bool statementEqual(Block const& _lhs, Block const& _rhs); +private: + bool statementEqual(Instruction const& _lhs, Instruction const& _rhs); + bool statementEqual(Label const& _lhs, Label const& _rhs); + bool statementEqual(StackAssignment const& _lhs, StackAssignment const& _rhs); + + bool visitDeclaration(TypedName const& _lhs, TypedName const& _rhs); + + template<typename U, typename V> + bool expressionEqual(U const&, V const&, std::enable_if_t<!std::is_same<U, V>::value>* = nullptr) + { + return false; + } + + template<typename U, typename V> + bool statementEqual(U const&, V const&, std::enable_if_t<!std::is_same<U, V>::value>* = nullptr) + { + return false; + } + + template<typename T, bool (SyntacticallyEqual::*CompareMember)(T const&, T const&)> + bool compareSharedPtr(std::shared_ptr<T> const& _lhs, std::shared_ptr<T> const& _rhs) + { + return (_lhs == _rhs) || (_lhs && _rhs && (this->*CompareMember)(*_lhs, *_rhs)); + } -protected: - static bool equalVector(std::vector<Expression> const& _e1, std::vector<Expression> const& _e2); + std::size_t m_idsUsed = 0; + std::map<YulString, std::size_t> m_identifiersLHS; + std::map<YulString, std::size_t> m_identifiersRHS; }; } |