Skip to content

Commit 89f6263

Browse files
committed
SMV: pre-traversal identifier conversion
1 parent 029f48a commit 89f6263

File tree

1 file changed

+57
-41
lines changed

1 file changed

+57
-41
lines changed

src/smvlang/smv_typecheck.cpp

Lines changed: 57 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1885,64 +1885,80 @@ Function: smv_typecheckt::convert
18851885
18861886
\*******************************************************************/
18871887

1888+
std::optional<std::string> merge_complex_identifier_opt(const exprt &expr)
1889+
{
1890+
if(expr.id() == ID_smv_identifier)
1891+
return id2string(to_smv_identifier_expr(expr).identifier());
1892+
else if(expr.id() == ID_member)
1893+
{
1894+
auto &member_expr = to_member_expr(expr);
1895+
auto rec = merge_complex_identifier_opt(member_expr.compound());
1896+
if(rec.has_value())
1897+
return rec.value() + '.' + id2string(member_expr.get_component_name());
1898+
else
1899+
return {};
1900+
}
1901+
else if(expr.id() == ID_index)
1902+
{
1903+
auto &index_expr = to_index_expr(expr);
1904+
auto &index = index_expr.index();
1905+
PRECONDITION(index.is_constant());
1906+
auto index_string = id2string(to_constant_expr(index).get_value());
1907+
auto rec = merge_complex_identifier_opt(index_expr.array());
1908+
if(rec.has_value())
1909+
return rec.value() + '.' + index_string;
1910+
else
1911+
return {};
1912+
}
1913+
else
1914+
{
1915+
// not a complex identifier
1916+
return {};
1917+
}
1918+
}
1919+
18881920
void smv_typecheckt::convert(exprt &expr)
18891921
{
1890-
for(auto &op : expr.operands())
1891-
convert(op);
1922+
// We want to find the maximally deep combination of
1923+
// smv_identifier, index, member that is a variable.
1924+
// Hence, look for these pre-traversal.
18921925

1893-
if(expr.id() == ID_smv_identifier)
1926+
auto complex_identifier_opt = merge_complex_identifier_opt(expr);
1927+
1928+
if(complex_identifier_opt.has_value())
18941929
{
1895-
const std::string &identifier=expr.get_string(ID_identifier);
1930+
auto identifier = complex_identifier_opt.value();
18961931

18971932
DATA_INVARIANT(
18981933
identifier.find("::") == std::string::npos, "conversion is done once");
18991934

1900-
// enum or variable?
1901-
if(modulep->enum_set.find(identifier) == modulep->enum_set.end())
1902-
{
1903-
std::string id = module + "::var::" + identifier;
1935+
std::string id = module + "::var::" + identifier;
19041936

1905-
expr.set(ID_identifier, id);
1906-
expr.id(ID_symbol);
1907-
}
1908-
else
1937+
// enum?
1938+
if(modulep->enum_set.find(identifier) != modulep->enum_set.end())
19091939
{
19101940
expr.id(ID_constant);
19111941
expr.type() = typet(ID_smv_enumeration);
19121942
expr.set(ID_value, identifier);
19131943
expr.remove(ID_identifier);
1944+
expr.operands().clear();
1945+
return;
1946+
}
1947+
else if(symbol_table.lookup(identifier) != nullptr) // variable?
1948+
{
1949+
expr.set(ID_identifier, id);
1950+
expr.id(ID_symbol);
1951+
expr.operands().clear();
1952+
return;
19141953
}
1915-
}
1916-
else if(expr.id() == ID_member)
1917-
{
1918-
auto &member_expr = to_member_expr(expr);
1919-
DATA_INVARIANT_WITH_DIAGNOSTICS(
1920-
member_expr.compound().id() == ID_symbol,
1921-
"unexpected complex_identifier",
1922-
expr.pretty());
19231954

1924-
auto tmp = to_symbol_expr(member_expr.compound());
1925-
tmp.set_identifier(
1926-
id2string(tmp.get_identifier()) + '.' +
1927-
id2string(member_expr.get_component_name()));
1928-
expr = tmp;
1929-
}
1930-
else if(expr.id() == ID_index)
1931-
{
1932-
auto &index_expr = to_index_expr(expr);
1933-
DATA_INVARIANT_WITH_DIAGNOSTICS(
1934-
index_expr.array().id() == ID_symbol,
1935-
"unexpected complex_identifier",
1936-
expr.pretty());
1937-
auto &index = index_expr.index();
1938-
PRECONDITION(index.is_constant());
1939-
auto index_string = id2string(to_constant_expr(index).get_value());
1940-
auto tmp = to_symbol_expr(index_expr.array());
1941-
tmp.set_identifier(id2string(tmp.get_identifier()) + '.' + index_string);
1942-
expr = tmp;
1955+
// not a variable, not an enum: leave as is
19431956
}
1944-
else if(expr.id()=="smv_nondet_choice" ||
1945-
expr.id()=="smv_union")
1957+
1958+
for(auto &op : expr.operands())
1959+
convert(op);
1960+
1961+
if(expr.id() == "smv_nondet_choice" || expr.id() == "smv_union")
19461962
{
19471963
if(expr.operands().size()==0)
19481964
{

0 commit comments

Comments
 (0)