vhdlpp: VTypeRange split to VTypeRangeConst and VTypeRangeExpr.

When range cannot be evaluated it uses the original expressions.
This commit is contained in:
Maciej Suminski 2015-12-04 11:40:03 +01:00
parent 7cebed7382
commit ab025f1e3b
4 changed files with 105 additions and 34 deletions

View File

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

View File

@ -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<perm_string>*names)
: names_(names->size())
{

View File

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

View File

@ -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<const VTypePrimitive*> (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<const VTypePrimitive*>(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