diff --git a/vhdlpp/parse.y b/vhdlpp/parse.y index 0372d4925..906395f67 100644 --- a/vhdlpp/parse.y +++ b/vhdlpp/parse.y @@ -685,7 +685,7 @@ composite_type_definition /* unbounded_array_definition IEEE 1076-2008 P5.3.2.1 */ | K_array '(' index_subtype_definition_list ')' K_of subtype_indication { std::list r; - r.push_back(new prange_t(NULL, NULL, true)); // NULL boundaries indicate unbounded array type + r.push_back(new prange_t(NULL, NULL, true)); // NULL boundaries indicate unbounded array type VTypeArray*tmp = new VTypeArray($6, &r); $$ = tmp; } diff --git a/vhdlpp/parse_misc.cc b/vhdlpp/parse_misc.cc index 3956b4a1a..7134faf76 100644 --- a/vhdlpp/parse_misc.cc +++ b/vhdlpp/parse_misc.cc @@ -70,7 +70,7 @@ void bind_architecture_to_entity(const char*ename, Architecture*arch) static const VType* calculate_subtype_array(const YYLTYPE&loc, const char*base_name, ScopeBase* /* scope */, Expression*array_left, - bool /* downto*/ , + bool downto, Expression*array_right) { const VType*base_type = parse_type_by_name(lex_strings.make(base_name)); @@ -97,7 +97,7 @@ static const VType* calculate_subtype_array(const YYLTYPE&loc, const char*base_n // For now, I only know how to handle 1 dimension assert(base_array->dimensions() == 1); - range[0] = VTypeArray::range_t(array_left, array_right); + range[0] = VTypeArray::range_t(array_left, array_right, downto); VTypeArray*subtype = new VTypeArray(base_array->element_type(), range, base_array->signed_vector()); return subtype; diff --git a/vhdlpp/vtype.cc b/vhdlpp/vtype.cc index 7c0875f44..199d06fd7 100644 --- a/vhdlpp/vtype.cc +++ b/vhdlpp/vtype.cc @@ -88,7 +88,8 @@ VTypeArray::VTypeArray(const VType*element, std::list*r, bool sv) r->pop_front(); Expression*msb = curp->msb(); Expression*lsb = curp->lsb(); - ranges_[idx] = range_t(msb, lsb); + bool dir = curp->is_downto(); + ranges_[idx] = range_t(msb, lsb, dir); } } diff --git a/vhdlpp/vtype.h b/vhdlpp/vtype.h index 7ee6ca66a..b0e540062 100644 --- a/vhdlpp/vtype.h +++ b/vhdlpp/vtype.h @@ -173,17 +173,19 @@ class VTypeArray : public VType { public: class range_t { public: - range_t() : msb_(0), lsb_(0) { } - range_t(Expression*m, Expression*l) : msb_(m), lsb_(l) { } + range_t(Expression*m = NULL, Expression*l = NULL, bool dir = true) : + msb_(m), lsb_(l), direction_(dir) { } - bool is_box() const { return msb_==0 && lsb_==0; } + inline bool is_box() const { return msb_==0 && lsb_==0; } + inline bool is_downto() const { return direction_; } - Expression* msb() const { return msb_; } - Expression* lsb() const { return lsb_; } + inline Expression* msb() const { return msb_; } + inline Expression* lsb() const { return lsb_; } private: Expression* msb_; Expression* lsb_; + bool direction_; }; public: @@ -210,6 +212,7 @@ class VTypeArray : public VType { bool can_be_packed() const { return etype_->can_be_packed(); } private: + void write_range_to_stream_(std::ostream&fd) const; const VType*etype_; std::vector ranges_; diff --git a/vhdlpp/vtype_stream.cc b/vhdlpp/vtype_stream.cc index e184aa5bf..d9fef3df2 100644 --- a/vhdlpp/vtype_stream.cc +++ b/vhdlpp/vtype_stream.cc @@ -42,18 +42,7 @@ void VTypeArray::write_to_stream(ostream&fd) const if (etype_ == &primitive_STDLOGIC) { fd << "std_logic_vector"; if (! ranges_.empty() && ! ranges_[0].is_box()) { - assert(ranges_.size() < 2); - fd << " ("; - if (ranges_[0].msb()) - ranges_[0].msb()->write_to_stream(fd); - else - fd << "<>"; - fd << " downto "; - if (ranges_[0].lsb()) - ranges_[0].lsb()->write_to_stream(fd); - else - fd << "<>"; - fd << ") "; + write_range_to_stream_(fd); } return; } @@ -64,18 +53,7 @@ void VTypeArray::write_to_stream(ostream&fd) const if (ranges_[0].is_box()) { fd << "(INTEGER range <>) "; } else { - assert(ranges_[0].msb() && ranges_[0].lsb()); - fd << "("; - if (ranges_[0].msb()) - ranges_[0].msb()->write_to_stream(fd); - else - fd << "<>"; - fd << " downto "; - if (ranges_[0].lsb()) - ranges_[0].lsb()->write_to_stream(fd); - else - fd << "<>"; - fd << ") "; + write_range_to_stream_(fd); } } @@ -83,6 +61,26 @@ void VTypeArray::write_to_stream(ostream&fd) const etype_->write_to_stream(fd); } +void VTypeArray::write_range_to_stream_(std::ostream&fd) const +{ + assert(ranges_.size() < 2); + assert(ranges_[0].msb() && ranges_[0].lsb()); + + fd << "("; + if (ranges_[0].msb()) + ranges_[0].msb()->write_to_stream(fd); + else + fd << "<>"; + + fd << (ranges_[0].is_downto() ? " downto " : " to "); + + if (ranges_[0].lsb()) + ranges_[0].lsb()->write_to_stream(fd); + else + fd << "<>"; + fd << ") "; +} + void VTypeDef::write_type_to_stream(ostream&fd) const { type_->write_to_stream(fd);