vhdlpp: Visitor for Expression class.
This commit is contained in:
parent
80403d2ade
commit
1f1d47887e
|
|
@ -69,6 +69,12 @@ Expression*ExpAttribute::clone() const
|
|||
return new ExpAttribute(static_cast<ExpName*>(base_->clone()), name_);
|
||||
}
|
||||
|
||||
void ExpAttribute::visit(ExprVisitor& func)
|
||||
{
|
||||
base_->visit(func);
|
||||
func(this);
|
||||
}
|
||||
|
||||
ExpBinary::ExpBinary(Expression*op1, Expression*op2)
|
||||
: operand1_(op1), operand2_(op2)
|
||||
{
|
||||
|
|
@ -90,6 +96,13 @@ bool ExpBinary::eval_operand2(ScopeBase*scope, int64_t&val) const
|
|||
return operand2_->evaluate(scope, val);
|
||||
}
|
||||
|
||||
void ExpBinary::visit(ExprVisitor& func)
|
||||
{
|
||||
operand1_->visit(func);
|
||||
operand2_->visit(func);
|
||||
func(this);
|
||||
}
|
||||
|
||||
ExpUnary::ExpUnary(Expression*op1)
|
||||
: operand1_(op1)
|
||||
{
|
||||
|
|
@ -100,6 +113,12 @@ ExpUnary::~ExpUnary()
|
|||
delete operand1_;
|
||||
}
|
||||
|
||||
void ExpUnary::visit(ExprVisitor& func)
|
||||
{
|
||||
operand1_->visit(func);
|
||||
func(this);
|
||||
}
|
||||
|
||||
ExpAggregate::ExpAggregate(std::list<element_t*>*el)
|
||||
: elements_(el? el->size() : 0)
|
||||
{
|
||||
|
|
@ -135,6 +154,24 @@ Expression* ExpAggregate::clone() const
|
|||
return new ExpAggregate(new_elements);
|
||||
}
|
||||
|
||||
void ExpAggregate::visit(ExprVisitor& func)
|
||||
{
|
||||
for(std::vector<element_t*>::iterator it = elements_.begin();
|
||||
it != elements_.end(); ++it) {
|
||||
(*it)->extract_expression()->visit(func);
|
||||
}
|
||||
|
||||
for(std::vector<choice_element>::iterator it = aggregate_.begin();
|
||||
it != aggregate_.end(); ++it) {
|
||||
if(Expression*choice_expr = it->choice->simple_expression(false))
|
||||
choice_expr->visit(func);
|
||||
|
||||
it->expr->visit(func);
|
||||
}
|
||||
|
||||
func(this);
|
||||
}
|
||||
|
||||
ExpAggregate::choice_t::choice_t(Expression*exp)
|
||||
: expr_(exp)
|
||||
{
|
||||
|
|
@ -256,6 +293,13 @@ ExpConcat::~ExpConcat()
|
|||
delete operand2_;
|
||||
}
|
||||
|
||||
void ExpConcat::visit(ExprVisitor& func)
|
||||
{
|
||||
operand1_->visit(func);
|
||||
operand2_->visit(func);
|
||||
func(this);
|
||||
}
|
||||
|
||||
ExpConditional::ExpConditional(Expression*co, list<Expression*>*tru,
|
||||
list<ExpConditional::else_t*>*fal)
|
||||
: cond_(co)
|
||||
|
|
@ -304,6 +348,30 @@ Expression*ExpConditional::clone() const
|
|||
return new ExpConditional(cond_->clone(), new_true_clause, new_else_clause);
|
||||
}
|
||||
|
||||
void ExpConditional::visit(ExprVisitor& func)
|
||||
{
|
||||
if(!true_clause_.empty()) {
|
||||
for(std::list<Expression*>::iterator it = true_clause_.begin();
|
||||
it != true_clause_.end(); ++it) {
|
||||
(*it)->visit(func);
|
||||
}
|
||||
}
|
||||
|
||||
if(!else_clause_.empty()) {
|
||||
for(std::list<else_t*>::iterator it = else_clause_.begin();
|
||||
it != else_clause_.end(); ++it) {
|
||||
std::list<Expression*>& else_clause = (*it)->extract_true_clause();
|
||||
|
||||
for(std::list<Expression*>::iterator jt = else_clause.begin();
|
||||
jt != else_clause.end(); ++jt) {
|
||||
(*jt)->visit(func);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func(this);
|
||||
}
|
||||
|
||||
ExpConditional::else_t::else_t(Expression*cond, std::list<Expression*>*tru)
|
||||
: cond_(cond)
|
||||
{
|
||||
|
|
@ -378,6 +446,16 @@ Expression*ExpFunc::clone() const {
|
|||
return f;
|
||||
}
|
||||
|
||||
void ExpFunc::visit(ExprVisitor& func) {
|
||||
if(!argv_.empty()) {
|
||||
for(std::vector<Expression*>::iterator it = argv_.begin();
|
||||
it != argv_.end(); ++it)
|
||||
(*it)->visit(func);
|
||||
}
|
||||
|
||||
func(this);
|
||||
}
|
||||
|
||||
const VType* ExpFunc::func_ret_type() const
|
||||
{
|
||||
return def_ ? def_->peek_return_type() : NULL;
|
||||
|
|
@ -481,6 +559,20 @@ void ExpName::set_range(Expression*msb, Expression*lsb)
|
|||
lsb_ = lsb;
|
||||
}
|
||||
|
||||
void ExpName::visit(ExprVisitor& func)
|
||||
{
|
||||
if(prefix_.get())
|
||||
prefix_.get()->visit(func);
|
||||
|
||||
if(index_)
|
||||
index_->visit(func);
|
||||
|
||||
if(lsb_)
|
||||
lsb_->visit(func);
|
||||
|
||||
func(this);
|
||||
}
|
||||
|
||||
int ExpName::index_t::emit(ostream&out, Entity*ent, ScopeBase*scope)
|
||||
{
|
||||
int errors = 0;
|
||||
|
|
@ -555,6 +647,12 @@ ExpCast::~ExpCast()
|
|||
{
|
||||
}
|
||||
|
||||
void ExpCast::visit(ExprVisitor& func)
|
||||
{
|
||||
base_->visit(func);
|
||||
func(this);
|
||||
}
|
||||
|
||||
ExpNew::ExpNew(Expression*size) :
|
||||
size_(size)
|
||||
{
|
||||
|
|
@ -565,6 +663,12 @@ ExpNew::~ExpNew()
|
|||
delete size_;
|
||||
}
|
||||
|
||||
void ExpNew::visit(ExprVisitor& func)
|
||||
{
|
||||
size_->visit(func);
|
||||
func(this);
|
||||
}
|
||||
|
||||
ExpTime::ExpTime(uint64_t amount, timeunit_t unit)
|
||||
: amount_(amount), unit_(unit)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -38,6 +38,11 @@ class VTypeArray;
|
|||
class VTypePrimitive;
|
||||
class ExpName;
|
||||
|
||||
struct ExprVisitor {
|
||||
virtual ~ExprVisitor() {};
|
||||
virtual void operator() (Expression*s) = 0;
|
||||
};
|
||||
|
||||
/*
|
||||
* The Expression class represents parsed expressions from the parsed
|
||||
* VHDL input. The Expression class is a virtual class that holds more
|
||||
|
|
@ -120,6 +125,9 @@ class Expression : public LineInfo {
|
|||
virtual void dump(ostream&out, int indent = 0) const =0;
|
||||
virtual ostream& dump_inline(ostream&out) const;
|
||||
|
||||
// Recursively visits a tree of expressions (useful of complex expressions).
|
||||
virtual void visit(ExprVisitor& func) { func(this); }
|
||||
|
||||
protected:
|
||||
// This function is called by the derived class during
|
||||
// elaboration to set the type of the current expression that
|
||||
|
|
@ -160,6 +168,7 @@ class ExpUnary : public Expression {
|
|||
inline const Expression*peek_operand() const { return operand1_; }
|
||||
|
||||
const VType*fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*atype) const;
|
||||
void visit(ExprVisitor& func);
|
||||
|
||||
protected:
|
||||
inline void write_to_stream_operand1(std::ostream&fd) const
|
||||
|
|
@ -186,6 +195,7 @@ class ExpBinary : public Expression {
|
|||
inline const Expression* peek_operand2(void) const { return operand2_; }
|
||||
|
||||
const VType*probe_type(Entity*ent, ScopeBase*scope) const;
|
||||
void visit(ExprVisitor& func);
|
||||
|
||||
protected:
|
||||
|
||||
|
|
@ -299,6 +309,7 @@ class ExpAggregate : public Expression {
|
|||
void write_to_stream(std::ostream&fd) const;
|
||||
int emit(ostream&out, Entity*ent, ScopeBase*scope);
|
||||
void dump(ostream&out, int indent = 0) const;
|
||||
void visit(ExprVisitor& func);
|
||||
|
||||
private:
|
||||
int elaborate_expr_array_(Entity*ent, ScopeBase*scope, const VTypeArray*ltype);
|
||||
|
|
@ -360,6 +371,7 @@ class ExpAttribute : public Expression {
|
|||
bool evaluate(ScopeBase*scope, int64_t&val) const;
|
||||
bool evaluate(Entity*ent, ScopeBase*scope, int64_t&val) const;
|
||||
void dump(ostream&out, int indent = 0) const;
|
||||
void visit(ExprVisitor& func);
|
||||
|
||||
private:
|
||||
ExpName*base_;
|
||||
|
|
@ -430,6 +442,7 @@ class ExpConcat : public Expression {
|
|||
virtual bool evaluate(ScopeBase*scope, int64_t&val) const;
|
||||
bool is_primary(void) const;
|
||||
void dump(ostream&out, int indent = 0) const;
|
||||
void visit(ExprVisitor& func);
|
||||
|
||||
private:
|
||||
int elaborate_expr_array_(Entity*ent, ScopeBase*scope, const VTypeArray*ltype);
|
||||
|
|
@ -457,6 +470,7 @@ class ExpConditional : public Expression {
|
|||
int emit_when_else(ostream&out, Entity*ent, ScopeBase*scope);
|
||||
int emit_else(ostream&out, Entity*ent, ScopeBase*scope);
|
||||
void dump(ostream&out, int indent = 0) const;
|
||||
std::list<Expression*>& extract_true_clause() { return true_clause_; }
|
||||
|
||||
private:
|
||||
Expression*cond_;
|
||||
|
|
@ -475,6 +489,7 @@ class ExpConditional : public Expression {
|
|||
void write_to_stream(std::ostream&fd) const;
|
||||
int emit(ostream&out, Entity*ent, ScopeBase*scope);
|
||||
void dump(ostream&out, int indent = 0) const;
|
||||
void visit(ExprVisitor& func);
|
||||
|
||||
private:
|
||||
Expression*cond_;
|
||||
|
|
@ -528,6 +543,7 @@ class ExpFunc : public Expression {
|
|||
void write_to_stream(std::ostream&fd) const;
|
||||
int emit(ostream&out, Entity*ent, ScopeBase*scope);
|
||||
void dump(ostream&out, int indent = 0) const;
|
||||
void visit(ExprVisitor& func); // NOTE: does not handle expressions in subprogram
|
||||
|
||||
private:
|
||||
perm_string name_;
|
||||
|
|
@ -638,8 +654,8 @@ class ExpName : public Expression {
|
|||
void dump(ostream&out, int indent = 0) const;
|
||||
inline const char* name() const { return name_; }
|
||||
inline const perm_string& peek_name() const { return name_; }
|
||||
|
||||
void set_range(Expression*msb, Expression*lsb);
|
||||
void visit(ExprVisitor& func);
|
||||
|
||||
private:
|
||||
class index_t {
|
||||
|
|
@ -811,6 +827,7 @@ class ExpCast : public Expression {
|
|||
void write_to_stream(std::ostream&fd) const;
|
||||
int emit(ostream&out, Entity*ent, ScopeBase*scope);
|
||||
void dump(ostream&out, int indent = 0) const;
|
||||
void visit(ExprVisitor& func);
|
||||
|
||||
private:
|
||||
Expression*base_;
|
||||
|
|
@ -833,6 +850,7 @@ class ExpNew : public Expression {
|
|||
void write_to_stream(std::ostream&) const {};
|
||||
int emit(ostream&out, Entity*ent, ScopeBase*scope);
|
||||
void dump(ostream&out, int indent = 0) const;
|
||||
void visit(ExprVisitor& func);
|
||||
|
||||
private:
|
||||
Expression*size_;
|
||||
|
|
|
|||
Loading…
Reference in New Issue