Skip to content

Commit 9867c06

Browse files
authored
Merge pull request #1297 from diffblue/move-verilog_assignment_pattern
Verilog: move code for assignment patterns
2 parents 16e2b70 + 360d7bf commit 9867c06

File tree

2 files changed

+98
-96
lines changed

2 files changed

+98
-96
lines changed

src/verilog/verilog_typecheck.cpp

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,104 @@ void verilog_typecheckt::assignment_conversion(
4141
exprt &rhs,
4242
const typet &lhs_type)
4343
{
44+
// 1800-2017 10.9
45+
if(rhs.type().id() == ID_verilog_assignment_pattern)
46+
{
47+
DATA_INVARIANT(
48+
rhs.id() == ID_verilog_assignment_pattern,
49+
"verilog_assignment_pattern expression expected");
50+
if(lhs_type.id() == ID_struct)
51+
{
52+
auto &struct_type = to_struct_type(lhs_type);
53+
auto &components = struct_type.components();
54+
55+
if(
56+
!rhs.operands().empty() &&
57+
rhs.operands().front().id() == ID_member_initializer)
58+
{
59+
exprt::operandst initializers{components.size(), nil_exprt{}};
60+
61+
for(auto &op : rhs.operands())
62+
{
63+
PRECONDITION(op.id() == ID_member_initializer);
64+
auto member_name = op.get(ID_member_name);
65+
if(!struct_type.has_component(member_name))
66+
{
67+
throw errort().with_location(op.source_location())
68+
<< "struct does not have a member `" << member_name << "'";
69+
}
70+
auto nr = struct_type.component_number(member_name);
71+
auto value = to_unary_expr(op).op();
72+
// rec. call
73+
assignment_conversion(value, components[nr].type());
74+
initializers[nr] = std::move(value);
75+
}
76+
77+
// Is every member covered?
78+
for(std::size_t i = 0; i < components.size(); i++)
79+
if(initializers[i].is_nil())
80+
{
81+
throw errort().with_location(rhs.source_location())
82+
<< "assignment pattern does not assign member `"
83+
<< components[i].get_name() << "'";
84+
}
85+
86+
rhs = struct_exprt{std::move(initializers), struct_type}
87+
.with_source_location(rhs.source_location());
88+
}
89+
else
90+
{
91+
if(rhs.operands().size() != components.size())
92+
{
93+
throw errort().with_location(rhs.source_location())
94+
<< "number of expressions does not match number of struct members";
95+
}
96+
97+
for(std::size_t i = 0; i < components.size(); i++)
98+
{
99+
// rec. call
100+
assignment_conversion(rhs.operands()[i], components[i].type());
101+
}
102+
103+
// turn into struct expression
104+
rhs.id(ID_struct);
105+
rhs.type() = lhs_type;
106+
}
107+
108+
return;
109+
}
110+
else if(lhs_type.id() == ID_array)
111+
{
112+
auto &array_type = to_array_type(lhs_type);
113+
auto &element_type = array_type.element_type();
114+
auto array_size =
115+
numeric_cast_v<mp_integer>(to_constant_expr(array_type.size()));
116+
117+
if(array_size != rhs.operands().size())
118+
{
119+
throw errort().with_location(rhs.source_location())
120+
<< "number of expressions does not match number of array elements";
121+
}
122+
123+
for(std::size_t i = 0; i < array_size; i++)
124+
{
125+
// rec. call
126+
assignment_conversion(rhs.operands()[i], element_type);
127+
}
128+
129+
// turn into array expression
130+
rhs.id(ID_array);
131+
rhs.type() = lhs_type;
132+
return;
133+
}
134+
else
135+
{
136+
throw errort().with_location(rhs.source_location())
137+
<< "cannot convert assignment pattern to '" << to_string(lhs_type)
138+
<< '\'';
139+
}
140+
}
141+
44142
// Implements 1800-2017 10.7
45143
// If the RHS is smaller than the LHS:
46144
// * if the RHS is unsigned, it is zero-padded

src/verilog/verilog_typecheck_expr.cpp

Lines changed: 0 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -2191,102 +2191,6 @@ void verilog_typecheck_exprt::implicit_typecast(
21912191
return;
21922192
}
21932193
}
2194-
else if(src_type.id() == ID_verilog_assignment_pattern)
2195-
{
2196-
DATA_INVARIANT(
2197-
expr.id() == ID_verilog_assignment_pattern,
2198-
"verilog_assignment_pattern expression expected");
2199-
if(dest_type.id() == ID_struct)
2200-
{
2201-
auto &struct_type = to_struct_type(dest_type);
2202-
auto &components = struct_type.components();
2203-
2204-
if(
2205-
!expr.operands().empty() &&
2206-
expr.operands().front().id() == ID_member_initializer)
2207-
{
2208-
exprt::operandst initializers{components.size(), nil_exprt{}};
2209-
2210-
for(auto &op : expr.operands())
2211-
{
2212-
PRECONDITION(op.id() == ID_member_initializer);
2213-
auto member_name = op.get(ID_member_name);
2214-
if(!struct_type.has_component(member_name))
2215-
{
2216-
throw errort().with_location(op.source_location())
2217-
<< "struct does not have a member `" << member_name << "'";
2218-
}
2219-
auto nr = struct_type.component_number(member_name);
2220-
auto value = to_unary_expr(op).op();
2221-
// rec. call
2222-
implicit_typecast(value, components[nr].type());
2223-
initializers[nr] = std::move(value);
2224-
}
2225-
2226-
// Is every member covered?
2227-
for(std::size_t i = 0; i < components.size(); i++)
2228-
if(initializers[i].is_nil())
2229-
{
2230-
throw errort().with_location(expr.source_location())
2231-
<< "assignment pattern does not assign member `"
2232-
<< components[i].get_name() << "'";
2233-
}
2234-
2235-
expr = struct_exprt{std::move(initializers), struct_type}
2236-
.with_source_location(expr.source_location());
2237-
}
2238-
else
2239-
{
2240-
if(expr.operands().size() != components.size())
2241-
{
2242-
throw errort().with_location(expr.source_location())
2243-
<< "number of expressions does not match number of struct members";
2244-
}
2245-
2246-
for(std::size_t i = 0; i < components.size(); i++)
2247-
{
2248-
// rec. call
2249-
implicit_typecast(expr.operands()[i], components[i].type());
2250-
}
2251-
2252-
// turn into struct expression
2253-
expr.id(ID_struct);
2254-
expr.type() = dest_type;
2255-
}
2256-
2257-
return;
2258-
}
2259-
else if(dest_type.id() == ID_array)
2260-
{
2261-
auto &array_type = to_array_type(dest_type);
2262-
auto &element_type = array_type.element_type();
2263-
auto array_size =
2264-
numeric_cast_v<mp_integer>(to_constant_expr(array_type.size()));
2265-
2266-
if(array_size != expr.operands().size())
2267-
{
2268-
throw errort().with_location(expr.source_location())
2269-
<< "number of expressions does not match number of array elements";
2270-
}
2271-
2272-
for(std::size_t i = 0; i < array_size; i++)
2273-
{
2274-
// rec. call
2275-
implicit_typecast(expr.operands()[i], element_type);
2276-
}
2277-
2278-
// turn into array expression
2279-
expr.id(ID_array);
2280-
expr.type() = dest_type;
2281-
return;
2282-
}
2283-
else
2284-
{
2285-
throw errort().with_location(expr.source_location())
2286-
<< "cannot convert assignment pattern to '" << to_string(dest_type)
2287-
<< '\'';
2288-
}
2289-
}
22902194
else if(src_type.id() == ID_verilog_real)
22912195
{
22922196
if(

0 commit comments

Comments
 (0)