Skip to content

Commit c314272

Browse files
author
Daniel Kroening
authored
Merge pull request diffblue#2181 from diffblue/format-expr-constants
format_expr now does index, c_bool constants, string constants
2 parents 514a0a5 + 0102452 commit c314272

File tree

7 files changed

+90
-66
lines changed

7 files changed

+90
-66
lines changed

src/util/format_expr.cpp

+66-44
Original file line numberDiff line numberDiff line change
@@ -9,29 +9,30 @@ Author: Daniel Kroening, [email protected]
99
/// \file
1010
/// Expression Pretty Printing
1111

12+
#include "format_expr.h"
13+
1214
#include "arith_tools.h"
1315
#include "expr.h"
1416
#include "expr_iterator.h"
1517
#include "fixedbv.h"
16-
#include "format_expr.h"
1718
#include "format_type.h"
1819
#include "ieee_float.h"
1920
#include "invariant.h"
2021
#include "mp_arith.h"
2122
#include "rational.h"
2223
#include "rational_tools.h"
24+
#include "std_code.h"
2325
#include "std_expr.h"
2426
#include "string2int.h"
27+
#include "string_utils.h"
2528

26-
#include <stack>
2729
#include <ostream>
30+
#include <stack>
2831

2932
/// We use the precendences that most readers expect
3033
/// (i.e., the ones you learn in primary school),
3134
/// and stay clear of the surprising ones that C has.
32-
static bool bracket_subexpression(
33-
const exprt &sub_expr,
34-
const exprt &expr)
35+
static bool bracket_subexpression(const exprt &sub_expr, const exprt &expr)
3536
{
3637
// no need for parentheses whenever the subexpression
3738
// doesn't have operands
@@ -57,9 +58,7 @@ static bool bracket_subexpression(
5758

5859
/// This formats a multi-ary expression,
5960
/// adding parentheses where indicated by \ref bracket_subexpression
60-
static std::ostream &format_rec(
61-
std::ostream &os,
62-
const multi_ary_exprt &src)
61+
static std::ostream &format_rec(std::ostream &os, const multi_ary_exprt &src)
6362
{
6463
bool first = true;
6564

@@ -86,18 +85,14 @@ static std::ostream &format_rec(
8685

8786
/// This formats a binary expression,
8887
/// which we do as for multi-ary expressions
89-
static std::ostream &format_rec(
90-
std::ostream &os,
91-
const binary_exprt &src)
88+
static std::ostream &format_rec(std::ostream &os, const binary_exprt &src)
9289
{
9390
return format_rec(os, to_multi_ary_expr(src));
9491
}
9592

9693
/// This formats a unary expression,
9794
/// adding parentheses very aggressively.
98-
static std::ostream &format_rec(
99-
std::ostream &os,
100-
const unary_exprt &src)
95+
static std::ostream &format_rec(std::ostream &os, const unary_exprt &src)
10196
{
10297
if(src.id() == ID_not)
10398
os << '!';
@@ -113,9 +108,7 @@ static std::ostream &format_rec(
113108
}
114109

115110
/// This formats a constant
116-
static std::ostream &format_rec(
117-
std::ostream &os,
118-
const constant_exprt &src)
111+
static std::ostream &format_rec(std::ostream &os, const constant_exprt &src)
119112
{
120113
auto type = src.type().id();
121114

@@ -128,22 +121,53 @@ static std::ostream &format_rec(
128121
else
129122
return os << src.pretty();
130123
}
131-
else if(type == ID_unsignedbv || type == ID_signedbv)
124+
else if(type == ID_unsignedbv || type == ID_signedbv || type == ID_c_bool)
132125
return os << *numeric_cast<mp_integer>(src);
133126
else if(type == ID_integer)
134127
return os << src.get_value();
128+
else if(type == ID_string)
129+
return os << '"' << escape(id2string(src.get_value())) << '"';
135130
else if(type == ID_floatbv)
136131
return os << ieee_floatt(src);
132+
else if(type == ID_pointer && src.is_zero())
133+
return os << src.get_value();
137134
else
138135
return os << src.pretty();
139136
}
140137

138+
std::ostream &fallback_format_rec(std::ostream &os, const exprt &expr)
139+
{
140+
os << expr.id();
141+
142+
for(const auto &s : expr.get_named_sub())
143+
if(s.first != ID_type)
144+
os << ' ' << s.first << "=\"" << s.second.id() << '"';
145+
146+
if(expr.has_operands())
147+
{
148+
os << '(';
149+
bool first = true;
150+
151+
for(const auto &op : expr.operands())
152+
{
153+
if(first)
154+
first = false;
155+
else
156+
os << ", ";
157+
158+
os << format(op);
159+
}
160+
161+
os << ')';
162+
}
163+
164+
return os;
165+
}
166+
141167
// The below generates a string in a generic syntax
142168
// that is inspired by C/C++/Java, and is meant for debugging
143169
// purposes.
144-
std::ostream &format_rec(
145-
std::ostream &os,
146-
const exprt &expr)
170+
std::ostream &format_rec(std::ostream &os, const exprt &expr)
147171
{
148172
const auto &id = expr.id();
149173

@@ -165,6 +189,12 @@ std::ostream &format_rec(
165189
<< to_member_expr(expr).get_component_name();
166190
else if(id == ID_symbol)
167191
return os << to_symbol_expr(expr).get_identifier();
192+
else if(id == ID_index)
193+
{
194+
const auto &index_expr = to_index_expr(expr);
195+
return os << format(index_expr.array()) << '[' << format(index_expr.index())
196+
<< ']';
197+
}
168198
else if(id == ID_type)
169199
return format_rec(os, expr.type());
170200
else if(id == ID_forall || id == ID_exists)
@@ -199,32 +229,24 @@ std::ostream &format_rec(
199229
return os << format(if_expr.cond()) << '?' << format(if_expr.true_case())
200230
<< ':' << format(if_expr.false_case());
201231
}
202-
else
232+
else if(id == ID_code)
203233
{
204-
os << id;
234+
const auto &code = to_code(expr);
235+
const irep_idt &statement = code.get_statement();
205236

206-
for(const auto &s : expr.get_named_sub())
207-
if(s.first!=ID_type)
208-
os << ' ' << s.first << "=\"" << s.second.id() << '"';
209-
210-
if(expr.has_operands())
237+
if(statement == ID_assign)
238+
return os << format(to_code_assign(code).lhs()) << " = "
239+
<< format(to_code_assign(code).rhs()) << ';';
240+
else if(statement == ID_block)
211241
{
212-
os << '(';
213-
bool first = true;
214-
215-
for(const auto &op : expr.operands())
216-
{
217-
if(first)
218-
first = false;
219-
else
220-
os << ", ";
221-
222-
os << format(op);
223-
}
224-
225-
os << ')';
242+
os << '{';
243+
for(const auto &s : to_code_block(code).operands())
244+
os << ' ' << format(s);
245+
return os << " }";
226246
}
227-
228-
return os;
247+
else
248+
return fallback_format_rec(os, expr);
229249
}
250+
else
251+
return fallback_format_rec(os, expr);
230252
}

src/util/format_expr.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ Author: Daniel Kroening, [email protected]
99
#ifndef CPROVER_UTIL_FORMAT_EXPR_H
1010
#define CPROVER_UTIL_FORMAT_EXPR_H
1111

12-
#include "format.h"
1312
#include "expr.h"
13+
#include "format.h"
1414

1515
//! Formats an expression in a generic syntax
1616
//! that is inspired by C/C++/Java, and is meant for debugging

src/util/format_type.cpp

+2-4
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,14 @@ Author: Daniel Kroening, [email protected]
66
77
\*******************************************************************/
88

9-
#include "format_expr.h"
109
#include "format_type.h"
10+
#include "format_expr.h"
1111
#include "std_types.h"
1212

1313
#include <ostream>
1414

1515
/// format a \ref struct_typet
16-
static std::ostream &format_rec(
17-
std::ostream &os,
18-
const struct_typet &src)
16+
static std::ostream &format_rec(std::ostream &os, const struct_typet &src)
1917
{
2018
os << "struct"
2119
<< " {";

src/util/lispexpr.cpp

+2-15
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ Author: Daniel Kroening, [email protected]
88

99
#include "lispexpr.h"
1010

11+
#include "string_utils.h"
12+
1113
#include <iostream>
1214

1315
std::string lispexprt::expr2string() const
@@ -147,21 +149,6 @@ bool lispexprt::parse(
147149
return false;
148150
}
149151

150-
std::string escape(const std::string &s)
151-
{
152-
std::string result;
153-
154-
for(std::size_t i=0; i<s.size(); i++)
155-
{
156-
if(s[i]=='\\' || s[i]=='"')
157-
result+='\\';
158-
159-
result+=s[i];
160-
}
161-
162-
return result;
163-
}
164-
165152
int test_lispexpr()
166153
{
167154
std::string line;

src/util/lispexpr.h

-2
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,6 @@ inline std::ostream &operator<<(
9999
return out << expr.expr2string();
100100
}
101101

102-
std::string escape(const std::string &s);
103-
104102
int test_lispexpr();
105103

106104
#endif // CPROVER_UTIL_LISPEXPR_H

src/util/string_utils.cpp

+15
Original file line numberDiff line numberDiff line change
@@ -133,3 +133,18 @@ std::string trim_from_last_delimiter(
133133
result=s.substr(0, index);
134134
return result;
135135
}
136+
137+
std::string escape(const std::string &s)
138+
{
139+
std::string result;
140+
141+
for(std::size_t i=0; i<s.size(); i++)
142+
{
143+
if(s[i]=='\\' || s[i]=='"')
144+
result+='\\';
145+
146+
result+=s[i];
147+
}
148+
149+
return result;
150+
}

src/util/string_utils.h

+4
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,8 @@ Stream &join_strings(
6363
return os;
6464
}
6565

66+
/// Generic escaping of strings; this is not meant to be a particular
67+
/// programming language.
68+
std::string escape(const std::string &);
69+
6670
#endif

0 commit comments

Comments
 (0)