vhdlpp: Refactored prange_t (class ExpRange).

This commit is contained in:
Maciej Suminski 2015-12-15 18:13:33 +01:00
parent 2c010d34bb
commit e0b2a5b337
18 changed files with 253 additions and 150 deletions

View File

@ -137,7 +137,7 @@ GenerateStatement::~GenerateStatement()
}
ForGenerate::ForGenerate(perm_string gname, perm_string genvar,
prange_t*rang, std::list<Architecture::Statement*>&s)
ExpRange*rang, std::list<Architecture::Statement*>&s)
: GenerateStatement(gname, s), genvar_(genvar),
lsb_(rang->lsb()), msb_(rang->msb())
{

View File

@ -33,7 +33,7 @@ class GenerateStatement;
class SequentialStmt;
class Signal;
class named_expr_t;
class prange_t;
class ExpRange;
/*
* The Architecture class carries the contents (name, statements,
@ -142,7 +142,7 @@ class ForGenerate : public GenerateStatement {
public:
ForGenerate(perm_string gname, perm_string genvar,
prange_t*rang, std::list<Architecture::Statement*>&s);
ExpRange*rang, std::list<Architecture::Statement*>&s);
~ForGenerate();
int elaborate(Entity*ent, Architecture*arc);

View File

@ -442,13 +442,6 @@ void named_expr_t::dump(ostream&out, int indent) const
expr_->dump(out, indent);
}
void prange_t::dump(ostream&out, int indent) const
{
left_->dump(out, indent);
out << setw(indent) << "" << (direction_ ? "downto" : "to");
right_->dump(out, indent);
}
ostream& Expression::dump_inline(ostream&out) const
{
out << typeid(*this).name();

View File

@ -77,6 +77,9 @@ void ExpAttribute::visit(ExprVisitor& func)
func(this);
}
const perm_string ExpAttribute::LEFT = perm_string::literal("left");
const perm_string ExpAttribute::RIGHT = perm_string::literal("right");
ExpBinary::ExpBinary(Expression*op1, Expression*op2)
: operand1_(op1), operand2_(op2)
{
@ -192,7 +195,7 @@ ExpAggregate::choice_t::choice_t()
{
}
ExpAggregate::choice_t::choice_t(prange_t*rang)
ExpAggregate::choice_t::choice_t(ExpRange*rang)
: range_(rang)
{
}
@ -203,7 +206,7 @@ ExpAggregate::choice_t::choice_t(const choice_t&other)
expr_.reset(e->clone());
if(other.range_.get())
range_.reset(new prange_t(*other.range_.get()));
range_.reset(static_cast<ExpRange*>(other.range_.get()->clone()));
}
ExpAggregate::choice_t::~choice_t()
@ -221,7 +224,7 @@ Expression*ExpAggregate::choice_t::simple_expression(bool detach_flag)
return res;
}
prange_t*ExpAggregate::choice_t::range_expressions(void)
ExpRange*ExpAggregate::choice_t::range_expressions(void)
{
return range_.get();
}
@ -535,6 +538,7 @@ ExpName::ExpName(perm_string nn, list<Expression*>*indices)
ExpName::ExpName(perm_string nn, Expression*msb, Expression*lsb)
: name_(nn), index_(msb), lsb_(lsb)
{
ivl_assert(*this, !msb || msb != lsb);
}
ExpName::ExpName(ExpName*prefix, perm_string nn)
@ -545,6 +549,7 @@ ExpName::ExpName(ExpName*prefix, perm_string nn)
ExpName::ExpName(ExpName*prefix, perm_string nn, Expression*msb, Expression*lsb)
: prefix_(prefix), name_(nn), index_(msb), lsb_(lsb)
{
ivl_assert(*this, !msb || msb != lsb);
}
ExpName::~ExpName()
@ -712,3 +717,70 @@ double ExpTime::to_fs() const
return val;
}
ExpRange::ExpRange(Expression*left, Expression*right, range_dir_t direction)
: left_(left), right_(right), direction_(direction), range_expr_(false)
{
}
ExpRange::ExpRange(ExpName*base, bool reverse_range)
: direction_(AUTO), range_expr_(true), range_base_(base), range_reverse_(reverse_range)
{
}
ExpRange::~ExpRange()
{
delete left_;
delete right_;
delete range_base_;
}
Expression*ExpRange::clone() const
{
if(range_expr_)
return new ExpRange(static_cast<ExpName*>(range_base_->clone()), range_reverse_);
else
return new ExpRange(left_->clone(), right_->clone(), direction_);
}
Expression* ExpRange::msb()
{
ivl_assert(*this, direction() != AUTO);
switch(direction()) {
case DOWNTO: return left_;
case TO: return right_;
default: return NULL;
}
return NULL;
}
Expression* ExpRange::lsb()
{
ivl_assert(*this, direction() != AUTO);
switch(direction()) {
case DOWNTO: return right_;
case TO: return left_;
default: return NULL;
}
return NULL;
}
Expression*ExpRange::left()
{
if(range_expr_ && !left_)
left_ = new ExpAttribute(range_base_, ExpAttribute::LEFT);
return left_;
}
Expression*ExpRange::right()
{
if(range_expr_ && !right_)
right_ = new ExpAttribute(range_base_, ExpAttribute::RIGHT);
return right_;
}

View File

@ -29,8 +29,7 @@
# include <memory>
# include <vector>
class prange_t;
class Entity;
class ExpRange;
class ScopeBase;
class SubprogramHeader;
class VType;
@ -239,7 +238,7 @@ class ExpAggregate : public Expression {
// Create a named choice
explicit choice_t(perm_string name);
// discreate_range choice
explicit choice_t(prange_t*ran);
explicit choice_t(ExpRange*ran);
choice_t(const choice_t&other);
@ -249,15 +248,15 @@ class ExpAggregate : public Expression {
bool others() const;
// Return expression if this represents a simple_expression.
Expression*simple_expression(bool detach_flag =true);
// Return prange_t if this represents a range_expression
prange_t*range_expressions(void);
// Return ExpRange if this represents a range_expression
ExpRange*range_expressions(void);
void write_to_stream(std::ostream&fd);
void dump(ostream&out, int indent) const;
private:
std::auto_ptr<Expression>expr_;
std::auto_ptr<prange_t> range_;
std::auto_ptr<ExpRange> range_;
private: // not implemented
choice_t& operator= (const choice_t&);
};
@ -373,6 +372,10 @@ class ExpAttribute : public Expression {
void dump(ostream&out, int indent = 0) const;
void visit(ExprVisitor& func);
// Constants for the standard attributes
static const perm_string LEFT;
static const perm_string RIGHT;
private:
ExpName*base_;
perm_string name_;
@ -898,6 +901,46 @@ class ExpTime : public Expression {
timeunit_t unit_;
};
class ExpRange : public Expression {
public:
typedef enum { DOWNTO, TO, AUTO } range_dir_t;
// Regular range
ExpRange(Expression*left, Expression*right, range_dir_t direction);
// 'range/'reverse range attribute
ExpRange(ExpName*base, bool reverse_range);
~ExpRange();
Expression*clone() const;
// Returns the upper boundary
Expression*msb();
// Returns the lower boundary
Expression*lsb();
Expression*left();
Expression*right();
range_dir_t direction() const { return direction_; }
int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
void write_to_stream(std::ostream&) const;
int emit(ostream&out, Entity*ent, ScopeBase*scope);
void dump(ostream&out, int indent = 0) const;
private:
// Regular range related fields
Expression*left_, *right_;
range_dir_t direction_;
// 'range/'reverse_range attribute related fields
// Flag to indicate it is a 'range/'reverse_range expression
bool range_expr_;
// Object name to which the attribute is applied
ExpName*range_base_;
// Flag to distinguish between 'range & 'reverse_range
bool range_reverse_;
};
// Elaborates an expression used as an argument in a procedure/function call.
int elaborate_argument(Expression*expr, const SubprogramHeader*subp,
int idx, Entity*ent, ScopeBase*scope);

View File

@ -117,3 +117,9 @@ void ExpTime::dump(ostream&out, int indent) const
out << setw(indent) << "" << "Time ";
write_to_stream(out);
}
void ExpRange::dump(ostream&out, int indent) const
{
out << setw(indent) << "" << "Range ";
write_to_stream(out);
}

View File

@ -402,7 +402,7 @@ const VType*ExpAggregate::fit_type(Entity*, ScopeBase*, const VTypeArray*host) c
elements_[0]->map_choices(&ce[0]);
ivl_assert(*this, ce.size() == 1);
prange_t*prange = ce[0].choice->range_expressions();
ExpRange*prange = ce[0].choice->range_expressions();
ivl_assert(*this, prange);
Expression*use_msb = prange->msb();
@ -657,8 +657,8 @@ const VType*ExpConcat::fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*at
new ExpArithmetic(ExpArithmetic::PLUS, sizes[0], sizes[1]),
new ExpInteger(1));
std::list<prange_t*> ranges;
ranges.push_front(new prange_t(size, new ExpInteger(0), true));
std::list<ExpRange*> ranges;
ranges.push_front(new ExpRange(size, new ExpInteger(0), ExpRange::DOWNTO));
const VType*array = new VTypeArray(types[1], &ranges);
return array;
@ -1057,6 +1057,19 @@ int ExpTime::elaborate_expr(Entity*, ScopeBase*, const VType*)
return 0;
}
int ExpRange::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*)
{
int errors = 0;
if(left_)
errors += left_->elaborate_expr(ent, scope, &primitive_INTEGER);
if(right_)
errors += right_->elaborate_expr(ent, scope, &primitive_INTEGER);
return errors;
}
int elaborate_argument(Expression*expr, const SubprogramHeader*subp,
int idx, Entity*ent, ScopeBase*scope)
{

View File

@ -224,7 +224,7 @@ int ExpAggregate::emit_array_(ostream&out, Entity*ent, ScopeBase*scope, const VT
// If this is a range choice, then calculate the bounds
// of the range and scan through the values, mapping the
// value to the aggregate_[idx] element.
if (prange_t*range = aggregate_[idx].choice->range_expressions()) {
if (ExpRange*range = aggregate_[idx].choice->range_expressions()) {
int64_t begin_val, end_val;
if (! range->msb()->evaluate(ent, scope, begin_val)) {
@ -1031,3 +1031,25 @@ int ExpTime::emit(ostream&out, Entity*, ScopeBase*)
return 0;
}
int ExpRange::emit(ostream&out, Entity*ent, ScopeBase*scope)
{
int errors = 0;
if(range_expr_) {
out << "$left(";
errors += range_base_->emit(out, ent, scope);
out << "):$right(";
errors += range_base_->emit(out, ent, scope);
out << ")";
} else if(direction_ == AUTO) {
ivl_assert(*this, false);
out << "/* auto dir */";
} else {
errors += left_->emit(out, ent, scope);
out << ":";
errors += right_->emit(out, ent, scope);
}
return 0;
}

View File

@ -61,13 +61,9 @@ void ExpAggregate::choice_t::write_to_stream(ostream&fd)
return;
}
if (prange_t*rp = range_expressions()) {
rp->msb()->write_to_stream(fd);
if (rp->is_downto())
fd << " downto ";
else
fd << " to ";
rp->msb()->write_to_stream(fd);
if (ExpRange*rp = range_expressions()) {
rp->write_to_stream(fd);
return;
}
fd << "/* ERROR */";
@ -316,3 +312,19 @@ void ExpTime::write_to_stream(ostream&fd) const
case S: fd << " s"; break;
}
}
void ExpRange::write_to_stream(ostream&fd) const
{
if(range_expr_) {
range_base_->write_to_stream(fd);
fd << (range_reverse_ ? "'reverse_range" : "'range");
} else {
left_->write_to_stream(fd);
switch(direction_) {
case DOWNTO: fd << " downto "; break;
case TO: fd << " to "; break;
default: ivl_assert(*this, false); break;
}
right_->write_to_stream(fd);
}
}

View File

@ -87,10 +87,6 @@ static ActiveScope*active_scope = new ActiveScope;
static stack<ActiveScope*> scope_stack;
static SubprogramHeader*active_sub = NULL;
// perm_strings for attributes
const static perm_string left_attr = perm_string::literal("left");
const static perm_string right_attr = perm_string::literal("right");
/*
* When a scope boundary starts, call the push_scope function to push
* a scope context. Preload this scope context with the contents of
@ -245,8 +241,9 @@ static void touchup_interface_for_functions(std::list<InterfacePort*>*ports)
const VType* vtype;
prange_t* range;
std::list<prange_t*>*range_list;
ExpRange*range;
std::list<ExpRange*>*range_list;
ExpRange::range_dir_t range_dir;
ExpArithmetic::fun_t arithmetic_op;
std::list<struct adding_term>*adding_terms;
@ -305,8 +302,6 @@ static void touchup_interface_for_functions(std::list<InterfacePort*>*ports)
/* The rules may have types. */
%type <flag> direction
%type <arithmetic_op> adding_operator
%type <adding_terms> simple_expression_terms
@ -372,6 +367,7 @@ static void touchup_interface_for_functions(std::list<InterfacePort*>*ports)
%type <range> range
%type <range_list> range_list index_constraint
%type <range_dir> direction
%type <case_alt> case_statement_alternative
%type <case_alt_list> case_statement_alternative_list
@ -752,8 +748,9 @@ 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<prange_t*> r;
r.push_back(new prange_t(NULL, NULL, true)); // NULL boundaries indicate unbounded array type
{ std::list<ExpRange*> r;
// NULL boundaries indicate unbounded array type
r.push_back(new ExpRange(NULL, NULL, ExpRange::DOWNTO));
VTypeArray*tmp = new VTypeArray($6, &r);
$$ = tmp;
}
@ -983,8 +980,10 @@ design_units
| design_unit
;
/* Indicate the direction as a flag, with "downto" being TRUE. */
direction : K_to { $$ = false; } | K_downto { $$ = true; } ;
direction
: K_to { $$ = ExpRange::TO; }
| K_downto { $$ = ExpRange::DOWNTO; }
;
element_association
: choices ARROW expression
@ -1498,7 +1497,7 @@ index_constraint
| '(' error ')'
{ errormsg(@2, "Errors in the index constraint.\n");
yyerrok;
$$ = new list<prange_t*>;
$$ = new list<ExpRange*>;
}
;
@ -2096,18 +2095,15 @@ process_sensitivity_list
range
: simple_expression direction simple_expression
{ prange_t* tmp = new prange_t($1, $3, $2);
{ ExpRange* tmp = new ExpRange($1, $3, $2);
$$ = tmp;
}
| name '\'' K_range
{
prange_t*tmp = NULL;
ExpRange*tmp = NULL;
ExpName*name = NULL;
if((name = dynamic_cast<ExpName*>($1))) {
ExpAttribute*left = new ExpAttribute(name, left_attr);
ExpAttribute*right = new ExpAttribute(name, right_attr);
tmp = new prange_t(left, right, true);
tmp->set_auto_dir();
tmp = new ExpRange(name, false);
} else {
errormsg(@1, "'range attribute can be used with named expressions only");
}
@ -2115,13 +2111,10 @@ range
}
| name '\'' K_reverse_range
{
prange_t*tmp = NULL;
ExpRange*tmp = NULL;
ExpName*name = NULL;
if((name = dynamic_cast<ExpName*>($1))) {
ExpAttribute*left = new ExpAttribute(name, left_attr);
ExpAttribute*right = new ExpAttribute(name, right_attr);
tmp = new prange_t(left, right, false);
tmp->set_auto_dir();
tmp = new ExpRange(name, true);
} else {
errormsg(@1, "'reverse_range attribute can be used with named expressions only");
}
@ -2131,12 +2124,12 @@ range
range_list
: range
{ list<prange_t*>*tmp = new list<prange_t*>;
{ list<ExpRange*>*tmp = new list<ExpRange*>;
tmp->push_back($1);
$$ = tmp;
}
| range_list ',' range
{ list<prange_t*>*tmp = $1;
{ list<ExpRange*>*tmp = $1;
tmp->push_back($3);
$$ = tmp;
}

View File

@ -113,14 +113,14 @@ static const VType* calculate_subtype_array(const YYLTYPE&loc, const char*base_n
}
const VType* calculate_subtype_array(const YYLTYPE&loc, const char*base_name,
ScopeBase*scope, list<prange_t*>*ranges)
ScopeBase*scope, list<ExpRange*>*ranges)
{
if (ranges->size() == 1) {
prange_t*tmpr = ranges->front();
Expression*lef = tmpr->expr_left();
Expression*rig = tmpr->expr_right();
ExpRange*tmpr = ranges->front();
Expression*lef = tmpr->left();
Expression*rig = tmpr->right();
return calculate_subtype_array(loc, base_name, scope,
lef, tmpr->is_downto(), rig);
lef, tmpr->direction(), rig);
}
sorrymsg(loc, "Don't know how to handle multiple ranges here.\n");
@ -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,
int direction,
Expression*range_right)
{
const VType*base_type = parse_type_by_name(lex_strings.make(base_name));
@ -148,7 +148,7 @@ const VType* calculate_subtype_range(const YYLTYPE&loc, const char*base_name,
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);
subtype = new VTypeRangeExpr(base_type, range_left, range_right, direction);
}
return subtype;

View File

@ -26,7 +26,7 @@ class ActiveScope;
class Architecture;
class Expression;
class Package;
class prange_t;
class ExpRange;
class ScopeBase;
class VType;
@ -35,11 +35,11 @@ extern void bind_architecture_to_entity(const char*ename, Architecture*arch);
extern const VType* calculate_subtype_array(const YYLTYPE&loc, const char*base_name,
ScopeBase*scope,
std::list<prange_t*>*ranges);
std::list<ExpRange*>*ranges);
extern const VType* calculate_subtype_range(const YYLTYPE&loc, const char*base_name,
ScopeBase*scope,
Expression*range_left,
bool downto,
int direction,
Expression*range_right);
/*

View File

@ -68,35 +68,6 @@ class instant_list_t {
std::list<perm_string>* labels_;
};
class prange_t {
public:
prange_t(Expression* left, Expression* right, bool dir)
: left_(left), right_(right), direction_(dir), auto_dir_(false) {}
prange_t(const prange_t&other) :
left_(other.left_->clone()), right_(other.right_->clone()),
direction_(other.direction_), auto_dir_(other.auto_dir_) {}
~prange_t() { delete left_; delete right_; }
void dump(ostream&out, int indent) const;
inline Expression*msb() { return direction_? left_ : right_; }
inline Expression*lsb() { return direction_? right_: left_; }
inline bool is_downto() const { return direction_; }
inline void set_auto_dir(bool enabled = true) { auto_dir_ = enabled; };
inline bool is_auto_dir() const { return auto_dir_; }
inline Expression*expr_left() { return left_; }
inline Expression*expr_right() { return right_; }
private:
Expression *left_, *right_;
bool direction_;
bool auto_dir_;
private: //not implemented
prange_t operator=(const prange_t&);
};
struct adding_term {
ExpArithmetic::fun_t op;
Expression*term;

View File

@ -238,7 +238,7 @@ void LoopStatement::visit(SeqStmtVisitor& func)
func(this);
}
ForLoopStatement::ForLoopStatement(perm_string scope_name, perm_string it, prange_t* range, list<SequentialStmt*>* stmts)
ForLoopStatement::ForLoopStatement(perm_string scope_name, perm_string it, ExpRange* range, list<SequentialStmt*>* stmts)
: LoopStatement(scope_name, stmts), it_(it), range_(range)
{
}

View File

@ -250,7 +250,7 @@ class WhileLoopStatement : public LoopStatement {
class ForLoopStatement : public LoopStatement {
public:
ForLoopStatement(perm_string loop_name,
perm_string index, prange_t*, list<SequentialStmt*>*);
perm_string index, ExpRange*, list<SequentialStmt*>*);
~ForLoopStatement();
int elaborate(Entity*ent, ScopeBase*scope);
@ -264,7 +264,7 @@ class ForLoopStatement : public LoopStatement {
int emit_runtime_(ostream&out, Entity*ent, ScopeBase*scope);
perm_string it_;
prange_t* range_;
ExpRange* range_;
};
class BasicLoopStatement : public LoopStatement {

View File

@ -383,10 +383,10 @@ int ForLoopStatement::emit(ostream&out, Entity*ent, ScopeBase*scope)
ivl_assert(*this, range_);
int64_t start_val;
bool start_rc = range_->msb()->evaluate(ent, scope, start_val);
bool start_rc = range_->left()->evaluate(ent, scope, start_val);
int64_t finish_val;
bool finish_rc = range_->lsb()->evaluate(ent, scope, finish_val);
bool finish_rc = range_->right()->evaluate(ent, scope, finish_val);
perm_string scope_name = loop_name();
if (scope_name.nil()) {
@ -403,48 +403,31 @@ int ForLoopStatement::emit(ostream&out, Entity*ent, ScopeBase*scope)
// determined during the run-time
errors += emit_runtime_(out, ent, scope);
} else {
bool dir = range_->is_downto();
ExpRange::range_dir_t dir = range_->direction();
if (!dir) {
int64_t tmp = start_val;
start_val = finish_val;
finish_val = tmp;
}
if(dir == ExpRange::AUTO)
dir = start_val < finish_val ? ExpRange::TO : ExpRange::DOWNTO;
if (dir && (start_val < finish_val)) {
if(range_->is_auto_dir()) {
dir = false;
} else {
out << "begin /* Degenerate loop at " << get_fileline()
<< ": " << start_val
<< " downto " << finish_val << " */ end" << endl
<< "end" << endl;
return errors;
}
}
else if (!dir && start_val > finish_val) {
if(range_->is_auto_dir()) {
dir = true;
} else {
out << "begin /* Degenerate loop at " << get_fileline()
<< ": " << start_val
<< " to " << finish_val << " */ end" << endl
<< "end" << endl;
return errors;
}
if ((dir == ExpRange::DOWNTO && start_val < finish_val) ||
(dir == ExpRange::TO && start_val > finish_val)) {
out << "begin /* Degenerate loop at " << get_fileline()
<< ": " << start_val;
out << (dir == ExpRange::DOWNTO ? " downto " : " to ");
out << finish_val << " */ end" << endl
<< "end" << endl;
return errors;
}
out << "for (\\" << it_ << " = " << start_val << " ; ";
if (dir)
if (dir == ExpRange::DOWNTO)
out << "\\" << it_ << " >= " << finish_val;
else
out << "\\" << it_ << " <= " << finish_val;
out << "; \\" << it_ << " = \\" << it_;
if (dir)
if (dir == ExpRange::DOWNTO)
out << " - 1)";
else
out << " + 1)";
@ -463,9 +446,7 @@ int ForLoopStatement::emit(ostream&out, Entity*ent, ScopeBase*scope)
void ForLoopStatement::write_to_stream(ostream&fd)
{
fd << "for " << it_ << " in ";
range_->expr_left()->write_to_stream(fd);
fd << " to ";
range_->expr_right()->write_to_stream(fd);
range_->write_to_stream(fd);
fd << " loop" << endl;
write_to_stream_substatements(fd);
fd << "end loop;" << endl;
@ -476,21 +457,21 @@ int ForLoopStatement::emit_runtime_(ostream&out, Entity*ent, ScopeBase*scope)
int errors = 0;
out << "for (\\" << it_ << " = ";
errors += range_->expr_left()->emit(out, ent, scope);
errors += range_->left()->emit(out, ent, scope);
// Twisted way of determining the loop direction at runtime
out << " ;\n(";
errors += range_->expr_left()->emit(out, ent, scope);
errors += range_->left()->emit(out, ent, scope);
out << " < ";
errors += range_->expr_right()->emit(out, ent, scope);
errors += range_->right()->emit(out, ent, scope);
out << " ? \\" << it_ << " <= ";
errors += range_->expr_right()->emit(out, ent, scope);
errors += range_->right()->emit(out, ent, scope);
out << " : \\" << it_ << " >= ";
errors += range_->expr_right()->emit(out, ent, scope);
errors += range_->right()->emit(out, ent, scope);
out << ");\n\\" << it_ << " = \\" << it_ << " + (";
errors += range_->expr_left()->emit(out, ent, scope);
errors += range_->left()->emit(out, ent, scope);
out << " < ";
errors += range_->expr_right()->emit(out, ent, scope);
errors += range_->right()->emit(out, ent, scope);
out << " ? 1 : -1))";
return errors;

View File

@ -108,21 +108,18 @@ VTypeArray::VTypeArray(const VType*element, const vector<VTypeArray::range_t>&r,
/*
* Create a VTypeArray range set from a list of parsed ranges.
* FIXME: We are copying pointers from the prange_t object into the
* range_t. This means that we cannot delete the prange_t object
* FIXME: We are copying pointers from the ExpRange object into the
* range_t. This means that we cannot delete the ExpRange object
* unless we invent a way to remove the pointers from that object. So
* this is a memory leak. Something to fix.
*/
VTypeArray::VTypeArray(const VType*element, std::list<prange_t*>*r, bool sv)
VTypeArray::VTypeArray(const VType*element, std::list<ExpRange*>*r, bool sv)
: etype_(element), ranges_(r->size()), signed_flag_(sv), parent_(NULL)
{
for (size_t idx = 0 ; idx < ranges_.size() ; idx += 1) {
prange_t*curp = r->front();
ExpRange*curp = r->front();
r->pop_front();
Expression*msb = curp->msb();
Expression*lsb = curp->lsb();
bool dir = curp->is_downto();
ranges_[idx] = range_t(msb, lsb, dir);
ranges_[idx] = range_t(curp->msb(), curp->lsb(), curp->direction());
}
}

View File

@ -33,7 +33,7 @@ class Architecture;
class ScopeBase;
class Entity;
class Expression;
class prange_t;
class ExpRange;
class VTypeDef;
class ScopeBase;
@ -210,7 +210,7 @@ class VTypeArray : public VType {
public:
VTypeArray(const VType*etype, const std::vector<range_t>&r, bool signed_vector = false);
VTypeArray(const VType*etype, std::list<prange_t*>*r, bool signed_vector = false);
VTypeArray(const VType*etype, std::list<ExpRange*>*r, bool signed_vector = false);
VTypeArray(const VType*etype, int msb, int lsb, bool signed_vector = false);
~VTypeArray();