Skip to content

Commit b5f33de

Browse files
author
Daniel Kroening
committed
adding instructiont::transform(f)
This avoids duplicating the idiom of iterating over the expressions in an instruction.
1 parent 4e30927 commit b5f33de

File tree

2 files changed

+109
-0
lines changed

2 files changed

+109
-0
lines changed

src/goto-programs/goto_program.cpp

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -887,6 +887,111 @@ void goto_programt::instructiont::validate(
887887
}
888888
}
889889

890+
void goto_programt::instructiont::transform(
891+
std::function<optionalt<exprt>(exprt)> f)
892+
{
893+
switch(type)
894+
{
895+
case OTHER:
896+
if(get_other().get_statement() == ID_expression)
897+
{
898+
auto new_expression = f(to_code_expression(get_other()).expression());
899+
if(new_expression.has_value())
900+
{
901+
auto new_other = to_code_expression(get_other());
902+
new_other.expression() = *new_expression;
903+
set_other(new_other);
904+
}
905+
}
906+
break;
907+
908+
case RETURN:
909+
{
910+
auto new_return_value = f(get_return().return_value());
911+
if(new_return_value.has_value())
912+
{
913+
auto new_return = get_return();
914+
new_return.return_value() = *new_return_value;
915+
set_return(new_return);
916+
}
917+
}
918+
break;
919+
920+
case ASSIGN:
921+
{
922+
auto new_assign_lhs = f(get_assign().lhs());
923+
auto new_assign_rhs = f(get_assign().rhs());
924+
if(new_assign_lhs.has_value() || new_assign_rhs.has_value())
925+
{
926+
auto new_assignment = get_assign();
927+
new_assignment.lhs() = new_assign_lhs.value_or(new_assignment.lhs());
928+
new_assignment.rhs() = new_assign_rhs.value_or(new_assignment.rhs());
929+
set_assign(new_assignment);
930+
}
931+
}
932+
break;
933+
934+
case DECL:
935+
{
936+
auto new_symbol = f(get_decl().symbol());
937+
if(new_symbol.has_value())
938+
{
939+
auto new_decl = get_decl();
940+
new_decl.symbol() = to_symbol_expr(*new_symbol);
941+
set_decl(new_decl);
942+
}
943+
}
944+
break;
945+
946+
case DEAD:
947+
{
948+
auto new_symbol = f(get_dead().symbol());
949+
if(new_symbol.has_value())
950+
{
951+
auto new_dead = get_dead();
952+
new_dead.symbol() = to_symbol_expr(*new_symbol);
953+
set_dead(new_dead);
954+
}
955+
}
956+
break;
957+
958+
case FUNCTION_CALL:
959+
{
960+
auto new_call = get_function_call();
961+
bool change = false;
962+
963+
auto new_lhs = f(new_call.lhs());
964+
if(new_lhs.has_value())
965+
{
966+
new_call.lhs() = *new_lhs;
967+
change = true;
968+
}
969+
970+
for(auto &a : new_call.arguments())
971+
{
972+
auto new_a = f(a);
973+
if(new_a.has_value())
974+
{
975+
a = *new_a;
976+
change = true;
977+
}
978+
}
979+
980+
if(change)
981+
set_function_call(new_call);
982+
}
983+
break;
984+
985+
default:
986+
if(has_condition())
987+
{
988+
auto new_condition = f(get_condition());
989+
if(new_condition.has_value())
990+
set_condition(new_condition.value());
991+
}
992+
}
993+
}
994+
890995
bool goto_programt::equals(const goto_programt &other) const
891996
{
892997
if(instructions.size() != other.instructions.size())

src/goto-programs/goto_program.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,10 @@ class goto_programt
555555
/// The validation mode indicates whether well-formedness check failures are
556556
/// reported via DATA_INVARIANT violations or exceptions.
557557
void validate(const namespacet &ns, const validation_modet vm) const;
558+
559+
/// Apply given transformer to all expressions; no return value
560+
/// means no change needed.
561+
void transform(std::function<optionalt<exprt>(exprt)>);
558562
};
559563

560564
// Never try to change this to vector-we mutate the list while iterating

0 commit comments

Comments
 (0)