From ab025f1e3b0807d8f8dd6365399e9476720c975c Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 4 Dec 2015 11:40:03 +0100 Subject: [PATCH] vhdlpp: VTypeRange split to VTypeRangeConst and VTypeRangeExpr. When range cannot be evaluated it uses the original expressions. --- vhdlpp/parse_misc.cc | 18 +++++++--------- vhdlpp/vtype.cc | 26 ++++++++++++++++++++-- vhdlpp/vtype.h | 49 ++++++++++++++++++++++++++++++++++-------- vhdlpp/vtype_stream.cc | 46 ++++++++++++++++++++++++++++----------- 4 files changed, 105 insertions(+), 34 deletions(-) diff --git a/vhdlpp/parse_misc.cc b/vhdlpp/parse_misc.cc index f49a631c3..752f7eeb9 100644 --- a/vhdlpp/parse_misc.cc +++ b/vhdlpp/parse_misc.cc @@ -130,7 +130,7 @@ const VType* calculate_subtype_array(const YYLTYPE&loc, const char*base_name, const VType* calculate_subtype_range(const YYLTYPE&loc, const char*base_name, ScopeBase*scope, Expression*range_left, - bool /* downto*/ , + bool downto, Expression*range_right) { const VType*base_type = parse_type_by_name(lex_strings.make(base_name)); @@ -143,15 +143,13 @@ const VType* calculate_subtype_range(const YYLTYPE&loc, const char*base_name, assert(range_left && range_right); int64_t left_val, right_val; - bool rc = range_left->evaluate(scope, left_val); - if (rc == false) - return 0; + VTypeRange*subtype; - rc = range_right->evaluate(scope, right_val); - if (rc == false) - return 0; + if(range_left->evaluate(scope, left_val) && range_right->evaluate(scope, right_val)) { + subtype = new VTypeRangeConst(base_type, left_val, right_val); + } else { + subtype = new VTypeRangeExpr(base_type, range_left, range_right, downto); + } - VTypeRange*sub_type = new VTypeRange(base_type, left_val, right_val); - - return sub_type; + return subtype; } diff --git a/vhdlpp/vtype.cc b/vhdlpp/vtype.cc index 58e7e9a16..6bf8c4eb2 100644 --- a/vhdlpp/vtype.cc +++ b/vhdlpp/vtype.cc @@ -265,8 +265,8 @@ void VTypeArray::evaluate_ranges(ScopeBase*scope) { } } -VTypeRange::VTypeRange(const VType*base, int64_t start_val, int64_t end_val) -: base_(base), start_(start_val), end_(end_val) +VTypeRange::VTypeRange(const VType*base) +: base_(base) { } @@ -274,6 +274,28 @@ VTypeRange::~VTypeRange() { } +VTypeRangeConst::VTypeRangeConst(const VType*base, int64_t start_val, int64_t end_val) +: VTypeRange(base), start_(start_val), end_(end_val) +{ +} + +VTypeRangeExpr::VTypeRangeExpr(const VType*base, Expression*start_expr, + Expression*end_expr, bool downto) +: VTypeRange(base), start_(start_expr), end_(end_expr), downto_(downto) +{ +} + +VTypeRangeExpr::~VTypeRangeExpr() +{ + delete start_; + delete end_; +} + +VType*VTypeRangeExpr::clone() const { + return new VTypeRangeExpr(base_type()->clone(), start_->clone(), + end_->clone(), downto_); +} + VTypeEnum::VTypeEnum(const std::list*names) : names_(names->size()) { diff --git a/vhdlpp/vtype.h b/vhdlpp/vtype.h index 617bd72c4..d97d13a9a 100644 --- a/vhdlpp/vtype.h +++ b/vhdlpp/vtype.h @@ -269,21 +269,52 @@ class VTypeArray : public VType { class VTypeRange : public VType { public: - VTypeRange(const VType*base, int64_t end, int64_t start); - ~VTypeRange(); + VTypeRange(const VType*base); + virtual ~VTypeRange() = 0; - VType*clone() const { return new VTypeRange(base_->clone(), start_, end_); } + bool write_std_types(std::ostream&fd) const; + int emit_def(std::ostream&out, perm_string name) const; // Get the type that is limited by the range. - inline const VType* base_type() const { return base_; } - - public: // Virtual methods - void write_to_stream(std::ostream&fd) const; - int emit_def(std::ostream&out, perm_string name) const; + inline const VType*base_type() const { return base_; } private: const VType*base_; - int64_t start_, end_; +}; + +class VTypeRangeConst : public VTypeRange { + + public: + VTypeRangeConst(const VType*base, int64_t end, int64_t start); + + VType*clone() const { + return new VTypeRangeConst(base_type()->clone(), start_, end_); + } + + public: // Virtual methods + void write_to_stream(std::ostream&fd) const; + + private: + const int64_t start_, end_; +}; + +class VTypeRangeExpr : public VTypeRange { + + public: + VTypeRangeExpr(const VType*base, Expression*end, Expression*start, bool downto); + ~VTypeRangeExpr(); + + VType*clone() const; + + public: // Virtual methods + void write_to_stream(std::ostream&fd) const; + + private: + // Boundaries + Expression*start_, *end_; + + // Range direction (downto/to) + bool downto_; }; class VTypeEnum : public VType { diff --git a/vhdlpp/vtype_stream.cc b/vhdlpp/vtype_stream.cc index 0b4a12f1e..96d9eff4d 100644 --- a/vhdlpp/vtype_stream.cc +++ b/vhdlpp/vtype_stream.cc @@ -171,21 +171,41 @@ void VTypePrimitive::write_to_stream(ostream&fd) const } } -void VTypeRange::write_to_stream(ostream&fd) const +bool VTypeRange::write_std_types(ostream&fd) const { - // Detect some special cases that can be written as ieee or - // standard types. - if (const VTypePrimitive*tmp = dynamic_cast (base_)) { - if (tmp->type()==VTypePrimitive::NATURAL) { - fd << "natural"; - return; - } - } + // Detect some special cases that can be written as ieee or + // standard types. + if (const VTypePrimitive*tmp = dynamic_cast(base_)) { + if (tmp->type()==VTypePrimitive::NATURAL) { + fd << "natural"; + return true; + } + } - base_->write_to_stream(fd); - fd << " range " << start_; - fd << (start_ < end_ ? " to " : " downto "); - fd << end_; + return false; +} + +void VTypeRangeConst::write_to_stream(ostream&fd) const +{ + if(write_std_types(fd)) + return; + + base_type()->write_to_stream(fd); + fd << " range " << start_; + fd << (start_ < end_ ? " to " : " downto "); + fd << end_; +} + +void VTypeRangeExpr::write_to_stream(ostream&fd) const +{ + if(write_std_types(fd)) + return; + + base_type()->write_to_stream(fd); + fd << " range "; + start_->write_to_stream(fd); + fd << (downto_ ? " downto " : " to "); + end_->write_to_stream(fd); } void VTypeRecord::write_to_stream(ostream&fd) const