vhdlpp: ExprVisitor stores the recursion level.
This commit is contained in:
parent
cef45ff21a
commit
e4bc404e99
|
|
@ -87,6 +87,9 @@ list<Expression*>*ExpAttribute::clone_args() const {
|
|||
|
||||
void ExpAttribute::visit_args(ExprVisitor& func)
|
||||
{
|
||||
func.down();
|
||||
func(this);
|
||||
|
||||
if(args_) {
|
||||
for(list<Expression*>::iterator it = args_->begin();
|
||||
it != args_->end(); ++it) {
|
||||
|
|
@ -94,7 +97,7 @@ void ExpAttribute::visit_args(ExprVisitor& func)
|
|||
}
|
||||
}
|
||||
|
||||
func(this);
|
||||
func.up();
|
||||
}
|
||||
|
||||
ExpObjAttribute::ExpObjAttribute(ExpName*base, perm_string name, list<Expression*>*args)
|
||||
|
|
@ -113,11 +116,13 @@ Expression*ExpObjAttribute::clone() const
|
|||
name_, clone_args());
|
||||
}
|
||||
|
||||
void ExpObjAttribute::visit(ExprVisitor& func)
|
||||
void ExpObjAttribute::visit(ExprVisitor&func)
|
||||
{
|
||||
func.down();
|
||||
func(this);
|
||||
visit_args(func);
|
||||
base_->visit(func);
|
||||
func(this);
|
||||
func.up();
|
||||
}
|
||||
|
||||
ExpTypeAttribute::ExpTypeAttribute(const VType*base, perm_string name, list<Expression*>*args)
|
||||
|
|
@ -130,10 +135,12 @@ Expression*ExpTypeAttribute::clone() const
|
|||
return new ExpTypeAttribute(base_, name_, clone_args());
|
||||
}
|
||||
|
||||
void ExpTypeAttribute::visit(ExprVisitor& func)
|
||||
void ExpTypeAttribute::visit(ExprVisitor&func)
|
||||
{
|
||||
visit_args(func);
|
||||
func.down();
|
||||
func(this);
|
||||
visit_args(func);
|
||||
func.up();
|
||||
}
|
||||
|
||||
const perm_string ExpAttribute::LEFT = perm_string::literal("left");
|
||||
|
|
@ -160,11 +167,13 @@ bool ExpBinary::eval_operand2(Entity*ent, ScopeBase*scope, int64_t&val) const
|
|||
return operand2_->evaluate(ent, scope, val);
|
||||
}
|
||||
|
||||
void ExpBinary::visit(ExprVisitor& func)
|
||||
void ExpBinary::visit(ExprVisitor&func)
|
||||
{
|
||||
func.down();
|
||||
func(this);
|
||||
operand1_->visit(func);
|
||||
operand2_->visit(func);
|
||||
func(this);
|
||||
func.up();
|
||||
}
|
||||
|
||||
ExpUnary::ExpUnary(Expression*op1)
|
||||
|
|
@ -177,10 +186,12 @@ ExpUnary::~ExpUnary()
|
|||
delete operand1_;
|
||||
}
|
||||
|
||||
void ExpUnary::visit(ExprVisitor& func)
|
||||
void ExpUnary::visit(ExprVisitor&func)
|
||||
{
|
||||
operand1_->visit(func);
|
||||
func.down();
|
||||
func(this);
|
||||
operand1_->visit(func);
|
||||
func.up();
|
||||
}
|
||||
|
||||
ExpAggregate::ExpAggregate(std::list<element_t*>*el)
|
||||
|
|
@ -227,8 +238,11 @@ Expression* ExpAggregate::clone() const
|
|||
return new ExpAggregate(new_elements);
|
||||
}
|
||||
|
||||
void ExpAggregate::visit(ExprVisitor& func)
|
||||
void ExpAggregate::visit(ExprVisitor&func)
|
||||
{
|
||||
func.down();
|
||||
func(this);
|
||||
|
||||
for(std::vector<element_t*>::iterator it = elements_.begin();
|
||||
it != elements_.end(); ++it) {
|
||||
(*it)->extract_expression()->visit(func);
|
||||
|
|
@ -242,7 +256,7 @@ void ExpAggregate::visit(ExprVisitor& func)
|
|||
it->expr->visit(func);
|
||||
}
|
||||
|
||||
func(this);
|
||||
func.up();
|
||||
}
|
||||
|
||||
ExpAggregate::choice_t::choice_t(Expression*exp)
|
||||
|
|
@ -366,11 +380,13 @@ ExpConcat::~ExpConcat()
|
|||
delete operand2_;
|
||||
}
|
||||
|
||||
void ExpConcat::visit(ExprVisitor& func)
|
||||
void ExpConcat::visit(ExprVisitor&func)
|
||||
{
|
||||
operand1_->visit(func);
|
||||
operand2_->visit(func);
|
||||
func(this);
|
||||
func.down();
|
||||
func(this);
|
||||
operand1_->visit(func);
|
||||
operand2_->visit(func);
|
||||
func.up();
|
||||
}
|
||||
|
||||
ExpConditional::ExpConditional(Expression*co, list<Expression*>*tru,
|
||||
|
|
@ -404,13 +420,16 @@ Expression*ExpConditional::clone() const
|
|||
return new ExpConditional(NULL, NULL, new_options);
|
||||
}
|
||||
|
||||
void ExpConditional::visit(ExprVisitor& func)
|
||||
void ExpConditional::visit(ExprVisitor&func)
|
||||
{
|
||||
func.down();
|
||||
func(this);
|
||||
|
||||
for(std::list<case_t*>::iterator it = options_.begin();
|
||||
it != options_.end(); ++it)
|
||||
(*it)->visit(func);
|
||||
|
||||
func(this);
|
||||
func.up();
|
||||
}
|
||||
|
||||
ExpConditional::case_t::case_t(Expression*cond, std::list<Expression*>*tru)
|
||||
|
|
@ -472,14 +491,16 @@ Expression*ExpSelected::clone() const
|
|||
return new ExpSelected(selector_->clone(), new_options);
|
||||
}
|
||||
|
||||
void ExpConditional::case_t::visit(ExprVisitor& func)
|
||||
void ExpConditional::case_t::visit(ExprVisitor&func)
|
||||
{
|
||||
func.down();
|
||||
if(cond_)
|
||||
cond_->visit(func);
|
||||
|
||||
for(std::list<Expression*>::iterator it = true_clause_.begin();
|
||||
it != true_clause_.end(); ++it)
|
||||
(*it)->visit(func);
|
||||
func.up();
|
||||
}
|
||||
|
||||
ExpEdge::ExpEdge(ExpEdge::fun_t typ, Expression*op)
|
||||
|
|
@ -529,14 +550,18 @@ Expression*ExpFunc::clone() const {
|
|||
return f;
|
||||
}
|
||||
|
||||
void ExpFunc::visit(ExprVisitor& func) {
|
||||
void ExpFunc::visit(ExprVisitor&func)
|
||||
{
|
||||
func.down();
|
||||
func(this);
|
||||
|
||||
if(!argv_.empty()) {
|
||||
for(std::vector<Expression*>::iterator it = argv_.begin();
|
||||
it != argv_.end(); ++it)
|
||||
(*it)->visit(func);
|
||||
}
|
||||
|
||||
func(this);
|
||||
func.up();
|
||||
}
|
||||
|
||||
const VType* ExpFunc::func_ret_type() const
|
||||
|
|
@ -681,8 +706,11 @@ Expression*ExpName::index(unsigned int number) const
|
|||
return *it;
|
||||
}
|
||||
|
||||
void ExpName::visit(ExprVisitor& func)
|
||||
void ExpName::visit(ExprVisitor&func)
|
||||
{
|
||||
func.down();
|
||||
func(this);
|
||||
|
||||
if(prefix_.get())
|
||||
prefix_.get()->visit(func);
|
||||
|
||||
|
|
@ -693,7 +721,7 @@ void ExpName::visit(ExprVisitor& func)
|
|||
}
|
||||
}
|
||||
|
||||
func(this);
|
||||
func.up();
|
||||
}
|
||||
|
||||
int ExpName::index_t::emit(ostream&out, Entity*ent, ScopeBase*scope) const
|
||||
|
|
@ -768,10 +796,12 @@ ExpCast::~ExpCast()
|
|||
{
|
||||
}
|
||||
|
||||
void ExpCast::visit(ExprVisitor& func)
|
||||
void ExpCast::visit(ExprVisitor&func)
|
||||
{
|
||||
base_->visit(func);
|
||||
func.down();
|
||||
func(this);
|
||||
base_->visit(func);
|
||||
func.up();
|
||||
}
|
||||
|
||||
ExpNew::ExpNew(Expression*size) :
|
||||
|
|
@ -784,10 +814,12 @@ ExpNew::~ExpNew()
|
|||
delete size_;
|
||||
}
|
||||
|
||||
void ExpNew::visit(ExprVisitor& func)
|
||||
void ExpNew::visit(ExprVisitor&func)
|
||||
{
|
||||
size_->visit(func);
|
||||
func.down();
|
||||
func(this);
|
||||
size_->visit(func);
|
||||
func.up();
|
||||
}
|
||||
|
||||
ExpTime::ExpTime(uint64_t amount, timeunit_t unit)
|
||||
|
|
@ -895,10 +927,11 @@ ExpDelay::~ExpDelay()
|
|||
delete delay_;
|
||||
}
|
||||
|
||||
void ExpDelay::visit(ExprVisitor& func)
|
||||
void ExpDelay::visit(ExprVisitor&func)
|
||||
{
|
||||
func.down();
|
||||
func(this);
|
||||
expr_->visit(func);
|
||||
delay_->visit(func);
|
||||
|
||||
func(this);
|
||||
func.up();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
# include <list>
|
||||
# include <memory>
|
||||
# include <vector>
|
||||
# include <cassert>
|
||||
|
||||
class ExpRange;
|
||||
class ScopeBase;
|
||||
|
|
@ -38,9 +39,25 @@ class VTypeArray;
|
|||
class VTypePrimitive;
|
||||
class ExpName;
|
||||
|
||||
/*
|
||||
* Helper class to recursively traverse an expression tree
|
||||
* (i.e. complex expressions).
|
||||
*/
|
||||
struct ExprVisitor {
|
||||
virtual ~ExprVisitor() {};
|
||||
ExprVisitor() : level_(0) {}
|
||||
virtual ~ExprVisitor() {}
|
||||
virtual void operator() (Expression*s) = 0;
|
||||
|
||||
// Methods to manage recursion depth. Every Expression::visit() method
|
||||
// should call down() in the beginning and up() in the end.
|
||||
inline void down() { ++level_; }
|
||||
inline void up() { --level_; assert(level_ >= 0); }
|
||||
|
||||
protected:
|
||||
int level() const { return level_; }
|
||||
|
||||
private:
|
||||
int level_;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -126,7 +143,7 @@ class Expression : public LineInfo {
|
|||
virtual ostream& dump_inline(ostream&out) const;
|
||||
|
||||
// Recursively visits a tree of expressions (useful for complex expressions).
|
||||
virtual void visit(ExprVisitor& func) { func(this); }
|
||||
virtual void visit(ExprVisitor& func) { func.down(); func(this); func.up(); }
|
||||
|
||||
protected:
|
||||
// This function is called by the derived class during
|
||||
|
|
|
|||
Loading…
Reference in New Issue