vhdlpp: Elaboration & emit support for aggregate initializer expressions in records.
This commit is contained in:
parent
9842035d89
commit
54696e0127
|
|
@ -283,7 +283,9 @@ class ExpAggregate : public Expression {
|
|||
|
||||
private:
|
||||
int elaborate_expr_array_(Entity*ent, Architecture*arc, const VTypeArray*ltype);
|
||||
int elaborate_expr_record_(Entity*ent, Architecture*arc, const VTypeRecord*ltype);
|
||||
int emit_array_(ostream&out, Entity*ent, Architecture*arc, const VTypeArray*ltype);
|
||||
int emit_record_(ostream&out, Entity*ent, Architecture*arc, const VTypeRecord*ltype);
|
||||
|
||||
private:
|
||||
// This is the elements as directly parsed.
|
||||
|
|
@ -575,6 +577,7 @@ class ExpName : public Expression {
|
|||
bool symbolic_compare(const Expression*that) const;
|
||||
void dump(ostream&out, int indent = 0) const;
|
||||
const char* name() const;
|
||||
inline perm_string peek_name() const { return name_; }
|
||||
|
||||
void set_range(Expression*msb, Expression*lsb);
|
||||
|
||||
|
|
|
|||
|
|
@ -411,6 +411,9 @@ int ExpAggregate::elaborate_expr(Entity*ent, Architecture*arc, const VType*ltype
|
|||
if (const VTypeArray*larray = dynamic_cast<const VTypeArray*>(ltype)) {
|
||||
return elaborate_expr_array_(ent, arc, larray);
|
||||
}
|
||||
else if(const VTypeRecord*lrecord = dynamic_cast<const VTypeRecord*>(ltype)) {
|
||||
return elaborate_expr_record_(ent, arc, lrecord);
|
||||
}
|
||||
|
||||
cerr << get_fileline() << ": internal error: I don't know how to elaborate aggregate expressions. type=" << typeid(*ltype).name() << endl;
|
||||
return 1;
|
||||
|
|
@ -476,6 +479,48 @@ int ExpAggregate::elaborate_expr_array_(Entity*ent, Architecture*arc, const VTyp
|
|||
return errors;
|
||||
}
|
||||
|
||||
int ExpAggregate::elaborate_expr_record_(Entity*ent, Architecture*arc, const VTypeRecord*ltype)
|
||||
{
|
||||
int errors = 0;
|
||||
|
||||
aggregate_.resize(elements_.size());
|
||||
|
||||
// Translate the elements_ array to the aggregate_ array. In
|
||||
// the target array, each expression is attached to a single
|
||||
// choice.
|
||||
for (size_t edx = 0 ; edx < elements_.size() ; edx += 1) {
|
||||
element_t*ecur = elements_[edx];
|
||||
|
||||
// it is invalid to have more than one choice in record assignment
|
||||
ivl_assert(*this, ecur->count_choices() == 1);
|
||||
|
||||
ecur->map_choices(&aggregate_[edx]);
|
||||
}
|
||||
|
||||
// Now run through the more convenient mapping and elaborate
|
||||
// all the expressions that I find.
|
||||
for (size_t idx = 0 ; idx < aggregate_.size() ; idx += 1) {
|
||||
ivl_assert(*this, !aggregate_[idx].alias_flag);
|
||||
|
||||
choice_t*ch = aggregate_[idx].choice;
|
||||
ivl_assert(*this, !ch->others());
|
||||
|
||||
// Get the appropriate type for a field
|
||||
const ExpName*field = dynamic_cast<const ExpName*>(ch->simple_expression(false));
|
||||
ivl_assert(*this, field);
|
||||
|
||||
perm_string field_name = field->peek_name();
|
||||
const VTypeRecord::element_t*el = ltype->element_by_name(field_name);
|
||||
|
||||
errors += aggregate_[idx].expr->elaborate_expr(ent, arc, el->peek_type());
|
||||
}
|
||||
|
||||
// done with the obsolete elements_ vector.
|
||||
elements_.clear();
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
void ExpAggregate::element_t::map_choices(ExpAggregate::choice_element*dst)
|
||||
{
|
||||
for (size_t idx = 0 ; idx < fields_.size() ; idx += 1) {
|
||||
|
|
|
|||
|
|
@ -95,6 +95,8 @@ int ExpAggregate::emit(ostream&out, Entity*ent, Architecture*arc)
|
|||
|
||||
if (const VTypeArray*atype = dynamic_cast<const VTypeArray*> (use_type))
|
||||
return emit_array_(out, ent, arc, atype);
|
||||
else if (const VTypeRecord*arecord = dynamic_cast<const VTypeRecord*> (use_type))
|
||||
return emit_record_(out, ent, arc, arecord);
|
||||
|
||||
out << "/* " << get_fileline() << ": internal error: "
|
||||
<< "I don't know how to elab/emit aggregate in " << typeid(use_type).name()
|
||||
|
|
@ -271,6 +273,30 @@ int ExpAggregate::emit_array_(ostream&out, Entity*ent, Architecture*arc, const V
|
|||
return errors;
|
||||
}
|
||||
|
||||
int ExpAggregate::emit_record_(ostream&out, Entity*ent, Architecture*arc, const VTypeRecord*ltype)
|
||||
{
|
||||
int errors = 0;
|
||||
|
||||
out << "{";
|
||||
|
||||
for (size_t idx = 0 ; idx < aggregate_.size() ; idx += 1) {
|
||||
ivl_assert(*this, !aggregate_[idx].choice->others());
|
||||
ivl_assert(*this, !aggregate_[idx].choice->range_expressions());
|
||||
|
||||
Expression*val = aggregate_[idx].expr;
|
||||
ivl_assert(*this, val);
|
||||
|
||||
if(idx != 0)
|
||||
out << ",";
|
||||
|
||||
errors += val->emit(out, ent, arc);
|
||||
}
|
||||
|
||||
out << "}";
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
int ExpAttribute::emit(ostream&out, Entity*ent, Architecture*arc)
|
||||
{
|
||||
int errors = 0;
|
||||
|
|
|
|||
Loading…
Reference in New Issue