@@ -217,81 +217,145 @@ std::ostream &fallback_format_rec(std::ostream &os, const exprt &expr)
217
217
return os;
218
218
}
219
219
220
- // The below generates a string in a generic syntax
220
+ class format_expr_configt
221
+ {
222
+ public:
223
+ format_expr_configt ()
224
+ {
225
+ setup ();
226
+ }
227
+
228
+ using formattert =
229
+ std::function<std::ostream &(std::ostream &, const exprt &)>;
230
+ using expr_mapt = std::unordered_map<irep_idt, formattert>;
231
+
232
+ expr_mapt expr_map;
233
+
234
+ // / find the formatter for a given expression
235
+ const formattert &find_formatter (const exprt &);
236
+
237
+ private:
238
+ // / setup the expressions we can format
239
+ void setup ();
240
+
241
+ formattert fallback;
242
+ };
243
+
244
+ // The below generates textual output in a generic syntax
221
245
// that is inspired by C/C++/Java, and is meant for debugging
222
246
// purposes.
223
- std::ostream & format_rec (std::ostream &os, const exprt &expr )
247
+ void format_expr_configt::setup ( )
224
248
{
225
- const auto &id = expr.id ();
226
-
227
- if (
228
- id == ID_plus || id == ID_mult || id == ID_and || id == ID_or ||
229
- id == ID_xor)
230
- {
249
+ auto multi_ary_expr =
250
+ [](std::ostream &os, const exprt &expr) -> std::ostream & {
231
251
return format_rec (os, to_multi_ary_expr (expr));
232
- }
233
- else if (
234
- id == ID_lt || id == ID_gt || id == ID_ge || id == ID_le || id == ID_div ||
235
- id == ID_minus || id == ID_implies || id == ID_equal || id == ID_notequal)
236
- {
252
+ };
253
+
254
+ expr_map[ID_plus] = multi_ary_expr;
255
+ expr_map[ID_mult] = multi_ary_expr;
256
+ expr_map[ID_and] = multi_ary_expr;
257
+ expr_map[ID_or] = multi_ary_expr;
258
+ expr_map[ID_xor] = multi_ary_expr;
259
+
260
+ auto binary_expr = [](std::ostream &os, const exprt &expr) -> std::ostream & {
237
261
return format_rec (os, to_binary_expr (expr));
238
- }
239
- else if (id == ID_not || id == ID_unary_minus)
262
+ };
263
+
264
+ expr_map[ID_lt] = binary_expr;
265
+ expr_map[ID_gt] = binary_expr;
266
+ expr_map[ID_ge] = binary_expr;
267
+ expr_map[ID_le] = binary_expr;
268
+ expr_map[ID_div] = binary_expr;
269
+ expr_map[ID_minus] = binary_expr;
270
+ expr_map[ID_implies] = binary_expr;
271
+ expr_map[ID_equal] = binary_expr;
272
+ expr_map[ID_notequal] = binary_expr;
273
+
274
+ auto unary_expr = [](std::ostream &os, const exprt &expr) -> std::ostream & {
240
275
return format_rec (os, to_unary_expr (expr));
241
- else if (id == ID_constant)
276
+ };
277
+
278
+ expr_map[ID_not] = unary_expr;
279
+ expr_map[ID_unary_minus] = unary_expr;
280
+
281
+ expr_map[ID_constant] =
282
+ [](std::ostream &os, const exprt &expr) -> std::ostream & {
242
283
return format_rec (os, to_constant_expr (expr));
243
- else if (id == ID_typecast)
284
+ };
285
+
286
+ expr_map[ID_typecast] =
287
+ [](std::ostream &os, const exprt &expr) -> std::ostream & {
244
288
return os << " cast(" << format (to_typecast_expr (expr).op ()) << " , "
245
289
<< format (expr.type ()) << ' )' ;
246
- else if (
247
- id == ID_byte_extract_little_endian || id == ID_byte_extract_big_endian)
248
- {
290
+ };
291
+
292
+ auto byte_extract =
293
+ [](std::ostream &os, const exprt &expr) -> std::ostream & {
249
294
const auto &byte_extract_expr = to_byte_extract_expr (expr);
250
- return os << id << ' (' << format (byte_extract_expr.op ()) << " , "
295
+ return os << expr. id () << ' (' << format (byte_extract_expr.op ()) << " , "
251
296
<< format (byte_extract_expr.offset ()) << " , "
252
297
<< format (byte_extract_expr.type ()) << ' )' ;
253
- }
254
- else if (id == ID_byte_update_little_endian || id == ID_byte_update_big_endian)
255
- {
298
+ };
299
+
300
+ expr_map[ID_byte_extract_little_endian] = byte_extract;
301
+ expr_map[ID_byte_extract_big_endian] = byte_extract;
302
+
303
+ auto byte_update = [](std::ostream &os, const exprt &expr) -> std::ostream & {
256
304
const auto &byte_update_expr = to_byte_update_expr (expr);
257
- return os << id << ' (' << format (byte_update_expr.op ()) << " , "
305
+ return os << expr. id () << ' (' << format (byte_update_expr.op ()) << " , "
258
306
<< format (byte_update_expr.offset ()) << " , "
259
307
<< format (byte_update_expr.value ()) << " , "
260
308
<< format (byte_update_expr.type ()) << ' )' ;
261
- }
262
- else if (id == ID_member)
309
+ };
310
+
311
+ expr_map[ID_byte_update_little_endian] = byte_update;
312
+ expr_map[ID_byte_update_big_endian] = byte_update;
313
+
314
+ expr_map[ID_member] =
315
+ [](std::ostream &os, const exprt &expr) -> std::ostream & {
263
316
return os << format (to_member_expr (expr).op ()) << ' .'
264
317
<< to_member_expr (expr).get_component_name ();
265
- else if (id == ID_symbol)
318
+ };
319
+
320
+ expr_map[ID_symbol] =
321
+ [](std::ostream &os, const exprt &expr) -> std::ostream & {
266
322
return os << to_symbol_expr (expr).get_identifier ();
267
- else if (id == ID_index)
268
- {
323
+ };
324
+
325
+ expr_map[ID_index] =
326
+ [](std::ostream &os, const exprt &expr) -> std::ostream & {
269
327
const auto &index_expr = to_index_expr (expr);
270
328
return os << format (index_expr.array ()) << ' [' << format (index_expr.index ())
271
329
<< ' ]' ;
272
- }
273
- else if (id == ID_type)
330
+ };
331
+
332
+ expr_map[ID_type] =
333
+ [](std::ostream &os, const exprt &expr) -> std::ostream & {
274
334
return format_rec (os, expr.type ());
275
- else if (id == ID_forall)
276
- {
335
+ };
336
+
337
+ expr_map[ID_forall] =
338
+ [](std::ostream &os, const exprt &expr) -> std::ostream & {
277
339
return os << u8" \u2200 " << format (to_quantifier_expr (expr).symbol ())
278
340
<< " : " << format (to_quantifier_expr (expr).symbol ().type ())
279
341
<< " . " << format (to_quantifier_expr (expr).where ());
280
- }
281
- else if (id == ID_exists)
282
- {
342
+ };
343
+
344
+ expr_map[ID_exists] =
345
+ [](std::ostream &os, const exprt &expr) -> std::ostream & {
283
346
return os << u8" \u2203 " << format (to_quantifier_expr (expr).symbol ())
284
347
<< " : " << format (to_quantifier_expr (expr).symbol ().type ())
285
348
<< " . " << format (to_quantifier_expr (expr).where ());
286
- }
287
- else if (id == ID_let)
288
- {
349
+ };
350
+
351
+ expr_map[ID_let] = [](std::ostream &os, const exprt &expr) -> std::ostream & {
289
352
return os << " LET " << format (to_let_expr (expr).symbol ()) << " = "
290
353
<< format (to_let_expr (expr).value ()) << " IN "
291
354
<< format (to_let_expr (expr).where ());
292
- }
293
- else if (id == ID_lambda)
294
- {
355
+ };
356
+
357
+ expr_map[ID_lambda] =
358
+ [](std::ostream &os, const exprt &expr) -> std::ostream & {
295
359
const auto &lambda_expr = to_lambda_expr (expr);
296
360
297
361
os << u8" \u03bb " ;
@@ -309,9 +373,9 @@ std::ostream &format_rec(std::ostream &os, const exprt &expr)
309
373
}
310
374
311
375
return os << " . " << format (lambda_expr.where ());
312
- }
313
- else if (id == ID_array || id == ID_struct)
314
- {
376
+ };
377
+
378
+ auto compound = [](std::ostream &os, const exprt &expr) -> std::ostream & {
315
379
os << " { " ;
316
380
317
381
bool first = true ;
@@ -327,16 +391,20 @@ std::ostream &format_rec(std::ostream &os, const exprt &expr)
327
391
}
328
392
329
393
return os << " }" ;
330
- }
331
- else if (id == ID_if)
332
- {
394
+ };
395
+
396
+ expr_map[ID_array] = compound ;
397
+ expr_map[ID_struct] = compound ;
398
+
399
+ expr_map[ID_if] = [](std::ostream &os, const exprt &expr) -> std::ostream & {
333
400
const auto &if_expr = to_if_expr (expr);
334
401
return os << ' (' << format (if_expr.cond ()) << " ? "
335
402
<< format (if_expr.true_case ()) << " : "
336
403
<< format (if_expr.false_case ()) << ' )' ;
337
- }
338
- else if (id == ID_code)
339
- {
404
+ };
405
+
406
+ expr_map[ID_code] =
407
+ [](std::ostream &os, const exprt &expr) -> std::ostream & {
340
408
const auto &code = to_code (expr);
341
409
const irep_idt &statement = code.get_statement ();
342
410
@@ -377,7 +445,27 @@ std::ostream &format_rec(std::ostream &os, const exprt &expr)
377
445
}
378
446
else
379
447
return fallback_format_rec (os, expr);
380
- }
381
- else
448
+ };
449
+
450
+ fallback = [](std::ostream &os, const exprt &expr) -> std::ostream & {
382
451
return fallback_format_rec (os, expr);
452
+ };
453
+ }
454
+
455
+ const format_expr_configt::formattert &
456
+ format_expr_configt::find_formatter (const exprt &expr)
457
+ {
458
+ auto m_it = expr_map.find (expr.id ());
459
+ if (m_it == expr_map.end ())
460
+ return fallback;
461
+ else
462
+ return m_it->second ;
463
+ }
464
+
465
+ format_expr_configt format_expr_config;
466
+
467
+ std::ostream &format_rec (std::ostream &os, const exprt &expr)
468
+ {
469
+ auto &formatter = format_expr_config.find_formatter (expr);
470
+ return formatter (os, expr);
383
471
}
0 commit comments