@@ -9,29 +9,30 @@ Author: Daniel Kroening, kroening@kroening.com
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"
21+ #include " lispexpr.h"
2022#include " mp_arith.h"
2123#include " rational.h"
2224#include " rational_tools.h"
25+ #include " std_code.h"
2326#include " std_expr.h"
2427#include " string2int.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}
0 commit comments