@@ -30,6 +30,29 @@ Author: Daniel Kroening, kroening@kroening.com
3030#include < ostream>
3131#include < stack>
3232
33+ // expressions that are rendered with infix operators
34+ struct infix_opt
35+ {
36+ const char *rep;
37+ };
38+
39+ const std::map<irep_idt, infix_opt> infix_map = {
40+ {ID_plus, {" +" }},
41+ {ID_minus, {" -" }},
42+ {ID_mult, {" *" }},
43+ {ID_div, {" /" }},
44+ {ID_equal, {" =" }},
45+ {ID_notequal, {u8" \u2260 " }}, // /=, U+2260
46+ {ID_and, {u8" \u2227 " }}, // wedge, U+2227
47+ {ID_or, {u8" \u2228 " }}, // vee, U+2228
48+ {ID_xor, {u8" \u2295 " }}, // + in circle, U+2295
49+ {ID_implies, {u8" \u21d2 " }}, // =>, U+21D2
50+ {ID_le, {u8" \u2264 " }}, // <=, U+2264
51+ {ID_ge, {u8" \u2265 " }}, // >=, U+2265
52+ {ID_lt, {" <" }},
53+ {ID_gt, {" >" }},
54+ };
55+
3356// / We use the precendences that most readers expect
3457// / (i.e., the ones you learn in primary school),
3558// / and stay clear of the surprising ones that C has.
@@ -40,6 +63,10 @@ static bool bracket_subexpression(const exprt &sub_expr, const exprt &expr)
4063 if (!sub_expr.has_operands ())
4164 return false ;
4265
66+ // no need if subexpression isn't an infix operator
67+ if (infix_map.find (sub_expr.id ()) == infix_map.end ())
68+ return false ;
69+
4370 // * and / bind stronger than + and -
4471 if (
4572 (sub_expr.id () == ID_mult || sub_expr.id () == ID_div) &&
@@ -54,6 +81,16 @@ static bool bracket_subexpression(const exprt &sub_expr, const exprt &expr)
5481 (expr.id () == ID_and || expr.id () == ID_or))
5582 return false ;
5683
84+ // +, -, *, / bind stronger than ==, !=, <, <=, >, >=
85+ if (
86+ (sub_expr.id () == ID_plus || sub_expr.id () == ID_minus ||
87+ sub_expr.id () == ID_mult || sub_expr.id () == ID_div) &&
88+ (expr.id () == ID_equal || expr.id () == ID_notequal || expr.id () == ID_lt ||
89+ expr.id () == ID_gt || expr.id () == ID_le || expr.id () == ID_ge))
90+ {
91+ return false ;
92+ }
93+
5794 return true ;
5895}
5996
@@ -63,31 +100,20 @@ static std::ostream &format_rec(std::ostream &os, const multi_ary_exprt &src)
63100{
64101 bool first = true ;
65102
66- std::string operator_str;
67-
68- if (src.id () == ID_and)
69- operator_str = u8" \u2227 " ; // wedge, U+2227
70- else if (src.id () == ID_or)
71- operator_str = u8" \u2228 " ; // vee, U+2228
72- else if (src.id () == ID_xor)
73- operator_str = u8" \u2295 " ; // + in circle, U+2295
74- else if (src.id () == ID_le)
75- operator_str = u8" \u2264 " ; // <=, U+2264
76- else if (src.id () == ID_ge)
77- operator_str = u8" \u2265 " ; // >=, U+2265
78- else if (src.id () == ID_notequal)
79- operator_str = u8" \u2260 " ; // /=, U+2260
80- else if (src.id () == ID_implies)
81- operator_str = u8" \u21d2 " ; // =>, U+21D2
82- else if (src.id () == ID_equal)
103+ std::string operator_str = id2string (src.id ()); // default
104+
105+ if (
106+ src.id () == ID_equal && !src.operands ().empty () &&
107+ src.op0 ().type ().id () == ID_bool)
83108 {
84- if (!src.operands ().empty () && src.op0 ().type ().id () == ID_bool)
85- operator_str = u8" \u21d4 " ; // <=>, U+21D4
86- else
87- operator_str = " =" ;
109+ operator_str = u8" \u21d4 " ; // <=>, U+21D4
88110 }
89111 else
90- operator_str = id2string (src.id ());
112+ {
113+ auto infix_map_it = infix_map.find (src.id ());
114+ if (infix_map_it != infix_map.end ())
115+ operator_str = infix_map_it->second .rep ;
116+ }
91117
92118 for (const auto &op : src.operands ())
93119 {
0 commit comments