vhdlpp: Visitor for Expression class.

This commit is contained in:
Maciej Suminski 2015-05-28 17:51:18 +02:00
parent 80403d2ade
commit 1f1d47887e
2 changed files with 123 additions and 1 deletions

View File

@ -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)
{

View File

@ -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_;