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,
|
const std::vector<netrange_t> &dims,
|
||||||
unsigned int cur_dim,
|
unsigned int cur_dim,
|
||||||
bool need_const) const;
|
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,
|
NetExpr* elaborate_expr_darray_(Design *des, NetScope *scope,
|
||||||
const netdarray_t *array_type,
|
const netdarray_t *array_type,
|
||||||
bool need_const) const;
|
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);
|
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 "
|
cerr << get_fileline() << ": sorry: I don't know how to elaborate "
|
||||||
<< "assignment_pattern expressions for " << *ntype << " type yet." << endl;
|
<< "assignment_pattern expressions for " << *ntype << " type yet." << endl;
|
||||||
cerr << get_fileline() << ": : Expression is: " << *this
|
cerr << get_fileline() << ": : Expression is: " << *this
|
||||||
|
|
@ -336,6 +341,33 @@ NetExpr* PEAssignPattern::elaborate_expr_packed_(Design *des, NetScope *scope,
|
||||||
return concat;
|
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
|
NetExpr* PEAssignPattern::elaborate_expr(Design*des, NetScope*, unsigned, unsigned) const
|
||||||
{
|
{
|
||||||
cerr << get_fileline() << ": sorry: I do not know how to"
|
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
|
// description, and set the off value to be the offset into
|
||||||
// the packed value where the member begins.
|
// the packed value where the member begins.
|
||||||
const struct member_t* packed_member(perm_string name, unsigned long&off) const;
|
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
|
// Return the width (in bits) of the packed record, or -1 if
|
||||||
// the record is not packed.
|
// the record is not packed.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue