From 7bb4cef9bc4d555212dda76f9e237362b2154b1c Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 24 Feb 2016 10:17:39 +0100 Subject: [PATCH] vhdlpp: ExpScopedName class to handle names with a specified scope. --- vhdlpp/expression.cc | 31 +++++++++++++++++++ vhdlpp/expression.h | 62 ++++++++++++++++++++++++++++++++++++-- vhdlpp/expression_debug.cc | 11 +++++-- 3 files changed, 100 insertions(+), 4 deletions(-) diff --git a/vhdlpp/expression.cc b/vhdlpp/expression.cc index 0bf306a2f..d52fa4d11 100644 --- a/vhdlpp/expression.cc +++ b/vhdlpp/expression.cc @@ -755,6 +755,37 @@ ExpRelation::~ExpRelation() { } +ExpScopedName::ExpScopedName(perm_string scope, ExpName*exp) +: scope_name_(scope), scope_(NULL), name_(exp) +{ +} + +ExpScopedName::~ExpScopedName() +{ + delete name_; +} + +void ExpScopedName::visit(ExprVisitor&func) +{ + func.down(); + func(this); + name_->visit(func); + func.up(); +} + +ScopeBase*ExpScopedName::get_scope(const ScopeBase*scope) +{ + if(!scope_) + scope_ = scope->find_scope(scope_name_); + + return scope_; +} + +ScopeBase*ExpScopedName::get_scope(const ScopeBase*scope) const +{ + return scope_ ? scope_ : scope->find_scope(scope_name_); +} + ExpShift::ExpShift(ExpShift::shift_t op, Expression*op1, Expression*op2) : ExpBinary(op1, op2), shift_(op) { diff --git a/vhdlpp/expression.h b/vhdlpp/expression.h index c513c7f89..b1b6ae244 100644 --- a/vhdlpp/expression.h +++ b/vhdlpp/expression.h @@ -708,7 +708,7 @@ class ExpName : public Expression { explicit ExpName(perm_string nn); ExpName(perm_string nn, std::list*indices); ExpName(ExpName*prefix, perm_string nn, std::list*indices = NULL); - ~ExpName(); + virtual ~ExpName(); public: // Base methods Expression*clone() const; @@ -783,7 +783,7 @@ class ExpName : public Expression { class ExpNameALL : public ExpName { public: - ExpNameALL() : ExpName(perm_string()) { } + ExpNameALL() : ExpName(empty_perm_string) { } public: const VType* probe_type(Entity*ent, ScopeBase*scope) const; @@ -815,6 +815,64 @@ class ExpRelation : public ExpBinary { fun_t fun_; }; +/* + * Helper class to handle name expressions coming from another scope. As such, + * we get more information regarding their type, etc. from the associated scope. + */ +class ExpScopedName : public Expression { + public: + ExpScopedName(perm_string scope, ExpName*exp); + ~ExpScopedName(); + + Expression*clone() const + { return new ExpScopedName(scope_name_, static_cast(name_->clone())); } + + int elaborate_lval(Entity*ent, ScopeBase*scope, bool is_sequ) + { return name_->elaborate_lval(ent, get_scope(scope), is_sequ); } + + int elaborate_rval(Entity*ent, ScopeBase*scope, const InterfacePort*lval) + { return name_->elaborate_rval(ent, get_scope(scope), lval); } + + const VType* probe_type(Entity*ent, ScopeBase*scope) const + { return name_->probe_type(ent, get_scope(scope)); } + + const VType* fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*host) const + { return name_->fit_type(ent, get_scope(scope), host); } + + int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype) + { return name_->elaborate_expr(ent, get_scope(scope), ltype); } + + void write_to_stream(std::ostream&fd) const + { name_->write_to_stream(fd); } + + int emit(ostream&out, Entity*ent, ScopeBase*scope) const { + out << scope_name_ << "."; + return name_->emit(out, ent, scope); + } + + bool is_primary(void) const + { return name_->is_primary(); } + + bool evaluate(Entity*ent, ScopeBase*, int64_t&val) const + { return name_->evaluate(ent, scope_, val); } + + bool symbolic_compare(const Expression*that) const + { return name_->symbolic_compare(that); } + + void dump(ostream&out, int indent = 0) const; + + void visit(ExprVisitor&func); + + private: + // Functions that resolve the origin scope for the name expression + ScopeBase*get_scope(const ScopeBase*scope); + ScopeBase*get_scope(const ScopeBase*scope) const; + + perm_string scope_name_; + ScopeBase*scope_; + ExpName*name_; +}; + class ExpShift : public ExpBinary { public: enum shift_t { SRL, SLL, SRA, SLA, ROL, ROR }; diff --git a/vhdlpp/expression_debug.cc b/vhdlpp/expression_debug.cc index e3f70fd5d..feaaf9510 100644 --- a/vhdlpp/expression_debug.cc +++ b/vhdlpp/expression_debug.cc @@ -71,7 +71,7 @@ void ExpConcat::dump(ostream&out, int indent) const void ExpCast::dump(ostream&out, int indent) const { - out << "Casting "; + out << setw(indent) << "" << "Casting "; base_->dump(out, indent+4); out << " to "; type_->emit_def(out, empty_perm_string); @@ -79,10 +79,17 @@ void ExpCast::dump(ostream&out, int indent) const void ExpNew::dump(ostream&out, int indent) const { - out << "New dynamic array size: "; + out << setw(indent) << "" << "New dynamic array size: " << endl; size_->dump(out, indent); } +void ExpScopedName::dump(ostream&out, int indent) const +{ + out << setw(indent) << "" << "Scoped name expression: " << endl; + out << " scope " << scope_name_ << " " << scope_ << endl; + name_->dump(out, indent+4); +} + void ExpShift::dump(ostream&out, int indent) const { const char*fun_name = "?";