diff options
author | chriseth <c@ethdev.com> | 2015-05-06 16:43:59 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2015-05-06 16:43:59 +0800 |
commit | c3e5fe6a1205068c9b5ded84f8ae96d97f855c1b (patch) | |
tree | a1a16e63550143e4dcbec6283be8b2f11710c80f /ASTVisitor.h | |
parent | 22eaf8ecd80d3bf091826a4c71d07d4f6269ce80 (diff) | |
download | dexon-solidity-c3e5fe6a1205068c9b5ded84f8ae96d97f855c1b.tar.gz dexon-solidity-c3e5fe6a1205068c9b5ded84f8ae96d97f855c1b.tar.zst dexon-solidity-c3e5fe6a1205068c9b5ded84f8ae96d97f855c1b.zip |
Structural gas estimator.
Diffstat (limited to 'ASTVisitor.h')
-rw-r--r-- | ASTVisitor.h | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/ASTVisitor.h b/ASTVisitor.h index ec22bd44..fbda5079 100644 --- a/ASTVisitor.h +++ b/ASTVisitor.h @@ -23,6 +23,8 @@ #pragma once #include <string> +#include <functional> +#include <vector> #include <libsolidity/AST.h> namespace dev @@ -218,5 +220,47 @@ protected: virtual void endVisitNode(ASTNode const&) { } }; +/** + * Utility class that visits the AST in depth-first order and calls a function on each node and each edge. + * Child nodes are only visited if the node callback of the parent returns true. + * The node callback of a parent is called before any edge or node callback involving the children. + * The edge callbacks of all children are called before the edge callback of the parent. + * This way, the node callback can be used as an initializing callback and the edge callbacks can be + * used to compute a "reduce" function. + */ +class ASTReduce: public ASTConstVisitor +{ +public: + /** + * Constructs a new ASTReduce object with the given callback functions. + * @param _onNode called for each node, before its child edges and nodes, should return true to descend deeper + * @param _onEdge called for each edge with (parent, child) + */ + ASTReduce( + std::function<bool(ASTNode const&)> _onNode, + std::function<void(ASTNode const&, ASTNode const&)> _onEdge + ): m_onNode(_onNode), m_onEdge(_onEdge) + { + } + +protected: + bool visitNode(ASTNode const& _node) override + { + m_parents.push_back(&_node); + return m_onNode(_node); + } + void endVisitNode(ASTNode const& _node) override + { + m_parents.pop_back(); + if (!m_parents.empty()) + m_onEdge(*m_parents.back(), _node); + } + +private: + std::vector<ASTNode const*> m_parents; + std::function<bool(ASTNode const&)> m_onNode; + std::function<void(ASTNode const&, ASTNode const&)> m_onEdge; +}; + } } |