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:
parent
5547858372
commit
7f3621d47d
3
PExpr.h
3
PExpr.h
|
|
@ -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;
|
||||
|
|
|
|||
32
elab_expr.cc
32
elab_expr.cc
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Reference in New Issue