Merge pull request #43 from orsonmmz/record_elab
Elaboration & emit functions for aggregate expressions used as record initializers.
This commit is contained in:
commit
e1ec27e18c
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -56,6 +56,10 @@ const VType* Expression::fit_type(Entity*ent, Architecture*arc, const VTypeArray
|
|||
|
||||
const VType*ExpName::elaborate_adjust_type_with_range_(Entity*, Architecture*arc, const VType*type)
|
||||
{
|
||||
// Unfold typedefs
|
||||
while (const VTypeDef*tdef = dynamic_cast<const VTypeDef*>(type)) {
|
||||
type = tdef->peek_definition();
|
||||
}
|
||||
|
||||
if (const VTypeArray*array = dynamic_cast<const VTypeArray*>(type)) {
|
||||
if (index_ && !lsb_) {
|
||||
|
|
@ -411,6 +415,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 +483,46 @@ 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());
|
||||
choice_element tmp;
|
||||
int idx;
|
||||
|
||||
// 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(&tmp);
|
||||
choice_t*ch = tmp.choice;
|
||||
|
||||
ivl_assert(*this, !ch->others());
|
||||
ivl_assert(*this, !tmp.alias_flag);
|
||||
|
||||
// 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, &idx);
|
||||
|
||||
aggregate_[idx] = tmp;
|
||||
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,34 @@ 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*)
|
||||
{
|
||||
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*name = aggregate_[idx].choice->simple_expression(false);
|
||||
//ivl_assert(*this, name);
|
||||
Expression*val = aggregate_[idx].expr;
|
||||
ivl_assert(*this, val);
|
||||
|
||||
if(idx != 0)
|
||||
out << ",";
|
||||
|
||||
//errors += name->emit(out, ent, arc);
|
||||
//out << ": ";
|
||||
errors += val->emit(out, ent, arc);
|
||||
}
|
||||
|
||||
out << "}";
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
int ExpAttribute::emit(ostream&out, Entity*ent, Architecture*arc)
|
||||
{
|
||||
int errors = 0;
|
||||
|
|
|
|||
|
|
@ -37,21 +37,7 @@ SigVarBase::~SigVarBase()
|
|||
void SigVarBase::elaborate_init_expr(Entity*ent, Architecture*arc)
|
||||
{
|
||||
if(init_expr_) {
|
||||
// convert the initializing string to bitstring if applicable
|
||||
const ExpString*string = dynamic_cast<const ExpString*>(init_expr_);
|
||||
if(string) {
|
||||
const std::vector<char>& val = string->get_value();
|
||||
char buf[val.size() + 1];
|
||||
std::copy(val.begin(), val.end(), buf);
|
||||
buf[val.size()] = 0;
|
||||
|
||||
ExpBitstring*bitstring = new ExpBitstring(buf);
|
||||
delete init_expr_;
|
||||
init_expr_ = bitstring;
|
||||
}
|
||||
else {
|
||||
init_expr_->elaborate_expr(ent, arc, peek_type());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -205,13 +205,17 @@ void VTypeRecord::show(ostream&out) const
|
|||
write_to_stream(out);
|
||||
}
|
||||
|
||||
const VTypeRecord::element_t* VTypeRecord::element_by_name(perm_string name) const
|
||||
const VTypeRecord::element_t* VTypeRecord::element_by_name(perm_string name, int*index) const
|
||||
{
|
||||
for (vector<element_t*>::const_iterator cur = elements_.begin()
|
||||
; cur != elements_.end() ; ++cur) {
|
||||
element_t*curp = *cur;
|
||||
if (curp->peek_name() == name)
|
||||
if (curp->peek_name() == name) {
|
||||
if (index)
|
||||
*index = std::distance(elements_.begin(), cur);
|
||||
|
||||
return curp;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -288,8 +288,7 @@ class VTypeRecord : public VType {
|
|||
int emit_def(std::ostream&out, perm_string name) const;
|
||||
|
||||
bool can_be_packed() const { return true; }
|
||||
|
||||
const element_t* element_by_name(perm_string name) const;
|
||||
const element_t* element_by_name(perm_string name, int*index = NULL) const;
|
||||
|
||||
private:
|
||||
std::vector<element_t*> elements_;
|
||||
|
|
|
|||
Loading…
Reference in New Issue