Add initial support for struct assignment pattern

Structs can be initialized by an assignment pattern. E.g.

```
struct packed {
  int x;
  shortint y;
} S = '{ 1, 2};
```

is the same as

```
struct packed {
  int x;
  shortint y;
} S;
s.x = 1;
s.y = 2;
```

Add initial support for unnamed struct assignment patterns. Named struct
assignment patterns like

```
struct packed {
  int x;
  shortint y;
} S = '{x: 1, y: 2};
```

are still unsupported.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
Lars-Peter Clausen 2022-10-05 00:06:58 +02:00
parent 5547858372
commit 7f3621d47d
3 changed files with 36 additions and 0 deletions

View File

@ -219,6 +219,9 @@ class PEAssignPattern : public PExpr {
const std::vector<netrange_t> &dims,
unsigned int cur_dim,
bool need_const) const;
NetExpr* elaborate_expr_struct_(Design *des, NetScope *scope,
const netstruct_t *struct_type,
bool need_const) const;
NetExpr* elaborate_expr_darray_(Design *des, NetScope *scope,
const netdarray_t *array_type,
bool need_const) const;

View File

@ -252,6 +252,11 @@ NetExpr*PEAssignPattern::elaborate_expr(Design*des, NetScope*scope,
need_const);
}
if (auto struct_type = dynamic_cast<const netstruct_t*>(ntype)) {
return elaborate_expr_struct_(des, scope, struct_type,
need_const);
}
cerr << get_fileline() << ": sorry: I don't know how to elaborate "
<< "assignment_pattern expressions for " << *ntype << " type yet." << endl;
cerr << get_fileline() << ": : Expression is: " << *this
@ -336,6 +341,33 @@ NetExpr* PEAssignPattern::elaborate_expr_packed_(Design *des, NetScope *scope,
return concat;
}
NetExpr* PEAssignPattern::elaborate_expr_struct_(Design *des, NetScope *scope,
const netstruct_t *struct_type,
bool need_const) const
{
auto &members = struct_type->members();
if (members.size() != parms_.size()) {
cerr << get_fileline() << ": error: Struct assignment pattern expects "
<< members.size() << " element(s) in this context.\n"
<< get_fileline() << ": : Found "
<< parms_.size() << " element(s)." << endl;
des->errors++;
}
NetEConcat *concat = new NetEConcat(parms_.size(), 1,
struct_type->base_type());
for (size_t idx = 0; idx < std::min(parms_.size(), members.size()); idx++) {
auto expr = elaborate_rval_expr(des, scope,
members[idx].net_type,
parms_[idx], need_const);
if (expr)
concat->set(idx, expr);
}
return concat;
}
NetExpr* PEAssignPattern::elaborate_expr(Design*des, NetScope*, unsigned, unsigned) const
{
cerr << get_fileline() << ": sorry: I do not know how to"

View File

@ -65,6 +65,7 @@ class netstruct_t : public LineInfo, public ivl_type_s {
// description, and set the off value to be the offset into
// the packed value where the member begins.
const struct member_t* packed_member(perm_string name, unsigned long&off) const;
const std::vector<member_t>& members() const { return members_; }
// Return the width (in bits) of the packed record, or -1 if
// the record is not packed.