30
30
#include < ostream>
31
31
#include < stack>
32
32
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
+
33
56
// / We use the precendences that most readers expect
34
57
// / (i.e., the ones you learn in primary school),
35
58
// / 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)
40
63
if (!sub_expr.has_operands ())
41
64
return false ;
42
65
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
+
43
70
// * and / bind stronger than + and -
44
71
if (
45
72
(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)
54
81
(expr.id () == ID_and || expr.id () == ID_or))
55
82
return false ;
56
83
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
+
57
94
return true ;
58
95
}
59
96
@@ -63,31 +100,20 @@ static std::ostream &format_rec(std::ostream &os, const multi_ary_exprt &src)
63
100
{
64
101
bool first = true ;
65
102
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)
83
108
{
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
88
110
}
89
111
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
+ }
91
117
92
118
for (const auto &op : src.operands ())
93
119
{
0 commit comments