src/Pure/ML/ml_pretty.ML
author nipkow
Tue, 17 Jun 2025 14:11:40 +0200
changeset 82733 8b537e1af2ec
parent 82591 ae1e6ff06b03
permissions -rw-r--r--
reinstated intersection of lists as inter_list_set
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
62508
d0b68218ea55 discontinued RAW session: bootstrap directly from isabelle_process RAW_ML_SYSTEM;
wenzelm
parents: 62503
diff changeset
     1
(*  Title:      Pure/ML/ml_pretty.ML
30622
dba663f1afa8 Datatype for ML pretty printing (cf. mlsource/MLCompiler/Pretty.sml in Poly/ML 5.3).
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
dba663f1afa8 Datatype for ML pretty printing (cf. mlsource/MLCompiler/Pretty.sml in Poly/ML 5.3).
wenzelm
parents:
diff changeset
     3
62503
19afb533028e clarified modules;
wenzelm
parents: 62387
diff changeset
     4
Minimal support for raw ML pretty printing, notably for toplevel pp.
30622
dba663f1afa8 Datatype for ML pretty printing (cf. mlsource/MLCompiler/Pretty.sml in Poly/ML 5.3).
wenzelm
parents:
diff changeset
     5
*)
dba663f1afa8 Datatype for ML pretty printing (cf. mlsource/MLCompiler/Pretty.sml in Poly/ML 5.3).
wenzelm
parents:
diff changeset
     6
62503
19afb533028e clarified modules;
wenzelm
parents: 62387
diff changeset
     7
signature ML_PRETTY =
19afb533028e clarified modules;
wenzelm
parents: 62387
diff changeset
     8
sig
80809
4a64fc4d1cde clarified signature: type ML_Pretty.pretty coincides with PolyML.pretty;
wenzelm
parents: 68918
diff changeset
     9
  datatype context = datatype PolyML.context
81266
8300511f4c45 clarified signature;
wenzelm
parents: 81121
diff changeset
    10
  val markup_get: PolyML.context list -> string * string
80856
300c75231e2b clarified signature and modules;
wenzelm
parents: 80840
diff changeset
    11
  val markup_context: string * string -> PolyML.context list
82591
ae1e6ff06b03 more robust output: no markup as last resort;
wenzelm
parents: 81686
diff changeset
    12
  val no_markup_context: PolyML.context list -> PolyML.context list
81266
8300511f4c45 clarified signature;
wenzelm
parents: 81121
diff changeset
    13
  val open_block_detect: PolyML.context list -> bool
81121
7cacedbddba7 support for pretty blocks that are "open" and thus have no impact on formatting, only on markup;
wenzelm
parents: 80857
diff changeset
    14
  val open_block_context: bool -> PolyML.context list
80809
4a64fc4d1cde clarified signature: type ML_Pretty.pretty coincides with PolyML.pretty;
wenzelm
parents: 68918
diff changeset
    15
  datatype pretty = datatype PolyML.pretty
82591
ae1e6ff06b03 more robust output: no markup as last resort;
wenzelm
parents: 81686
diff changeset
    16
  val no_markup: pretty -> pretty
62503
19afb533028e clarified modules;
wenzelm
parents: 62387
diff changeset
    17
  val block: pretty list -> pretty
19afb533028e clarified modules;
wenzelm
parents: 62387
diff changeset
    18
  val str: string -> pretty
19afb533028e clarified modules;
wenzelm
parents: 62387
diff changeset
    19
  val brk: FixedInt.int -> pretty
80813
9dd4dcb08d37 clarified signature, following 1f718be3608b: Pretty.str is now value-oriented;
wenzelm
parents: 80810
diff changeset
    20
  val dots: pretty
62784
0371c369ab1d adapted to Poly/ML repository version 2e40cadc975a;
wenzelm
parents: 62711
diff changeset
    21
  val pair: ('a * FixedInt.int -> pretty) -> ('b * FixedInt.int -> pretty) ->
0371c369ab1d adapted to Poly/ML repository version 2e40cadc975a;
wenzelm
parents: 62711
diff changeset
    22
    ('a * 'b) * FixedInt.int -> pretty
0371c369ab1d adapted to Poly/ML repository version 2e40cadc975a;
wenzelm
parents: 62711
diff changeset
    23
  val enum: string -> string -> string -> ('a * FixedInt.int -> pretty) ->
0371c369ab1d adapted to Poly/ML repository version 2e40cadc975a;
wenzelm
parents: 62711
diff changeset
    24
    'a list * FixedInt.int -> pretty
80810
1f718be3608b clarified Pretty.T vs. output tree (following Isabelle/Scala): Output.output_width (via print_mode) happens during formatting, instead of construction;
wenzelm
parents: 80809
diff changeset
    25
  val prune: FixedInt.int -> pretty -> pretty
62662
291cc01f56f5 @{make_string} is available during Pure bootstrap;
wenzelm
parents: 62661
diff changeset
    26
  val format: int -> pretty -> string
62899
845ed4584e21 clarified bootstrap of @{make_string} -- avoid query on ML environment;
wenzelm
parents: 62878
diff changeset
    27
  val default_margin: int
80840
793e490d7bd1 tuned signature;
wenzelm
parents: 80814
diff changeset
    28
  val get_margin: int option -> int
80809
4a64fc4d1cde clarified signature: type ML_Pretty.pretty coincides with PolyML.pretty;
wenzelm
parents: 68918
diff changeset
    29
  val string_of: pretty -> string
62900
c641bf9402fd simplified default print_depth: context is usually available, in contrast to 0d295e339f52;
wenzelm
parents: 62899
diff changeset
    30
  val make_string_fn: string
62503
19afb533028e clarified modules;
wenzelm
parents: 62387
diff changeset
    31
end;
19afb533028e clarified modules;
wenzelm
parents: 62387
diff changeset
    32
19afb533028e clarified modules;
wenzelm
parents: 62387
diff changeset
    33
structure ML_Pretty: ML_PRETTY =
30622
dba663f1afa8 Datatype for ML pretty printing (cf. mlsource/MLCompiler/Pretty.sml in Poly/ML 5.3).
wenzelm
parents:
diff changeset
    34
struct
dba663f1afa8 Datatype for ML pretty printing (cf. mlsource/MLCompiler/Pretty.sml in Poly/ML 5.3).
wenzelm
parents:
diff changeset
    35
81121
7cacedbddba7 support for pretty blocks that are "open" and thus have no impact on formatting, only on markup;
wenzelm
parents: 80857
diff changeset
    36
(** context **)
7cacedbddba7 support for pretty blocks that are "open" and thus have no impact on formatting, only on markup;
wenzelm
parents: 80857
diff changeset
    37
7cacedbddba7 support for pretty blocks that are "open" and thus have no impact on formatting, only on markup;
wenzelm
parents: 80857
diff changeset
    38
(* properties *)
80856
300c75231e2b clarified signature and modules;
wenzelm
parents: 80840
diff changeset
    39
300c75231e2b clarified signature and modules;
wenzelm
parents: 80840
diff changeset
    40
datatype context = datatype PolyML.context;
300c75231e2b clarified signature and modules;
wenzelm
parents: 80840
diff changeset
    41
81266
8300511f4c45 clarified signature;
wenzelm
parents: 81121
diff changeset
    42
fun get_property context name =
80856
300c75231e2b clarified signature and modules;
wenzelm
parents: 80840
diff changeset
    43
  (case List.find (fn ContextProperty (a, _) => name = a | _ => false) context of
300c75231e2b clarified signature and modules;
wenzelm
parents: 80840
diff changeset
    44
    SOME (ContextProperty (_, b)) => b
300c75231e2b clarified signature and modules;
wenzelm
parents: 80840
diff changeset
    45
  | _ => "");
300c75231e2b clarified signature and modules;
wenzelm
parents: 80840
diff changeset
    46
81121
7cacedbddba7 support for pretty blocks that are "open" and thus have no impact on formatting, only on markup;
wenzelm
parents: 80857
diff changeset
    47
7cacedbddba7 support for pretty blocks that are "open" and thus have no impact on formatting, only on markup;
wenzelm
parents: 80857
diff changeset
    48
(* markup *)
7cacedbddba7 support for pretty blocks that are "open" and thus have no impact on formatting, only on markup;
wenzelm
parents: 80857
diff changeset
    49
80857
aff85c86737b clarified properties;
wenzelm
parents: 80856
diff changeset
    50
val markup_bg = "markup_bg";
aff85c86737b clarified properties;
wenzelm
parents: 80856
diff changeset
    51
val markup_en = "markup_en";
80856
300c75231e2b clarified signature and modules;
wenzelm
parents: 80840
diff changeset
    52
81266
8300511f4c45 clarified signature;
wenzelm
parents: 81121
diff changeset
    53
fun markup_get context =
80856
300c75231e2b clarified signature and modules;
wenzelm
parents: 80840
diff changeset
    54
  let
81266
8300511f4c45 clarified signature;
wenzelm
parents: 81121
diff changeset
    55
    val bg = get_property context markup_bg;
8300511f4c45 clarified signature;
wenzelm
parents: 81121
diff changeset
    56
    val en = get_property context markup_en;
80856
300c75231e2b clarified signature and modules;
wenzelm
parents: 80840
diff changeset
    57
  in (bg, en) end;
300c75231e2b clarified signature and modules;
wenzelm
parents: 80840
diff changeset
    58
300c75231e2b clarified signature and modules;
wenzelm
parents: 80840
diff changeset
    59
fun markup_context (bg, en) =
300c75231e2b clarified signature and modules;
wenzelm
parents: 80840
diff changeset
    60
  (if bg = "" then [] else [ContextProperty (markup_bg, bg)]) @
300c75231e2b clarified signature and modules;
wenzelm
parents: 80840
diff changeset
    61
  (if en = "" then [] else [ContextProperty (markup_en, en)]);
300c75231e2b clarified signature and modules;
wenzelm
parents: 80840
diff changeset
    62
82591
ae1e6ff06b03 more robust output: no markup as last resort;
wenzelm
parents: 81686
diff changeset
    63
val no_markup_context =
ae1e6ff06b03 more robust output: no markup as last resort;
wenzelm
parents: 81686
diff changeset
    64
  List.filter (fn ContextProperty (a, _) => a <> markup_bg andalso a <> markup_en | _ => true);
ae1e6ff06b03 more robust output: no markup as last resort;
wenzelm
parents: 81686
diff changeset
    65
80856
300c75231e2b clarified signature and modules;
wenzelm
parents: 80840
diff changeset
    66
81121
7cacedbddba7 support for pretty blocks that are "open" and thus have no impact on formatting, only on markup;
wenzelm
parents: 80857
diff changeset
    67
(* open_block flag *)
7cacedbddba7 support for pretty blocks that are "open" and thus have no impact on formatting, only on markup;
wenzelm
parents: 80857
diff changeset
    68
81686
8473f4f57368 clarified data representation: less redundancy;
wenzelm
parents: 81266
diff changeset
    69
val open_block = ContextProperty ("open_block", "");
81121
7cacedbddba7 support for pretty blocks that are "open" and thus have no impact on formatting, only on markup;
wenzelm
parents: 80857
diff changeset
    70
81686
8473f4f57368 clarified data representation: less redundancy;
wenzelm
parents: 81266
diff changeset
    71
val open_block_detect =
8473f4f57368 clarified data representation: less redundancy;
wenzelm
parents: 81266
diff changeset
    72
  List.exists (fn ContextProperty ("open_block", _) => true | _ => false);
81121
7cacedbddba7 support for pretty blocks that are "open" and thus have no impact on formatting, only on markup;
wenzelm
parents: 80857
diff changeset
    73
81686
8473f4f57368 clarified data representation: less redundancy;
wenzelm
parents: 81266
diff changeset
    74
fun open_block_context true = [open_block]
8473f4f57368 clarified data representation: less redundancy;
wenzelm
parents: 81266
diff changeset
    75
  | open_block_context false = [];
81121
7cacedbddba7 support for pretty blocks that are "open" and thus have no impact on formatting, only on markup;
wenzelm
parents: 80857
diff changeset
    76
7cacedbddba7 support for pretty blocks that are "open" and thus have no impact on formatting, only on markup;
wenzelm
parents: 80857
diff changeset
    77
7cacedbddba7 support for pretty blocks that are "open" and thus have no impact on formatting, only on markup;
wenzelm
parents: 80857
diff changeset
    78
7cacedbddba7 support for pretty blocks that are "open" and thus have no impact on formatting, only on markup;
wenzelm
parents: 80857
diff changeset
    79
(** pretty printing **)
7cacedbddba7 support for pretty blocks that are "open" and thus have no impact on formatting, only on markup;
wenzelm
parents: 80857
diff changeset
    80
80809
4a64fc4d1cde clarified signature: type ML_Pretty.pretty coincides with PolyML.pretty;
wenzelm
parents: 68918
diff changeset
    81
(* datatype pretty with derived operations *)
62661
c23ff2f45a18 clarified modules;
wenzelm
parents: 62508
diff changeset
    82
80809
4a64fc4d1cde clarified signature: type ML_Pretty.pretty coincides with PolyML.pretty;
wenzelm
parents: 68918
diff changeset
    83
datatype pretty = datatype PolyML.pretty;
30622
dba663f1afa8 Datatype for ML pretty printing (cf. mlsource/MLCompiler/Pretty.sml in Poly/ML 5.3).
wenzelm
parents:
diff changeset
    84
82591
ae1e6ff06b03 more robust output: no markup as last resort;
wenzelm
parents: 81686
diff changeset
    85
fun no_markup (PrettyBlock (a, b, c, d)) = PrettyBlock (a, b, no_markup_context c, map no_markup d)
ae1e6ff06b03 more robust output: no markup as last resort;
wenzelm
parents: 81686
diff changeset
    86
  | no_markup a = a;
ae1e6ff06b03 more robust output: no markup as last resort;
wenzelm
parents: 81686
diff changeset
    87
80809
4a64fc4d1cde clarified signature: type ML_Pretty.pretty coincides with PolyML.pretty;
wenzelm
parents: 68918
diff changeset
    88
fun block prts = PrettyBlock (2, false, [], prts);
4a64fc4d1cde clarified signature: type ML_Pretty.pretty coincides with PolyML.pretty;
wenzelm
parents: 68918
diff changeset
    89
val str = PrettyString;
4a64fc4d1cde clarified signature: type ML_Pretty.pretty coincides with PolyML.pretty;
wenzelm
parents: 68918
diff changeset
    90
fun brk width = PrettyBreak (width, 0);
38635
f76ad0771f67 added ML toplevel pretty-printing for tables, using dummy for anything other than Poly/ML 5.3.0 (or later);
wenzelm
parents: 30623
diff changeset
    91
80813
9dd4dcb08d37 clarified signature, following 1f718be3608b: Pretty.str is now value-oriented;
wenzelm
parents: 80810
diff changeset
    92
val dots = str "...";
9dd4dcb08d37 clarified signature, following 1f718be3608b: Pretty.str is now value-oriented;
wenzelm
parents: 80810
diff changeset
    93
62387
ad3eb2889f9a support for polyml-git ec49a49972c5 (branch FixedPrecisionInt);
wenzelm
parents: 61925
diff changeset
    94
fun pair pretty1 pretty2 ((x, y), depth: FixedInt.int) =
80814
f06fc05f7c01 more accurate output: observe depth as in "prune" operation;
wenzelm
parents: 80813
diff changeset
    95
  if depth = 0 then dots
f06fc05f7c01 more accurate output: observe depth as in "prune" operation;
wenzelm
parents: 80813
diff changeset
    96
  else block [str "(", pretty1 (x, depth), str ",", brk 1, pretty2 (y, depth - 1), str ")"];
38635
f76ad0771f67 added ML toplevel pretty-printing for tables, using dummy for anything other than Poly/ML 5.3.0 (or later);
wenzelm
parents: 30623
diff changeset
    97
62387
ad3eb2889f9a support for polyml-git ec49a49972c5 (branch FixedPrecisionInt);
wenzelm
parents: 61925
diff changeset
    98
fun enum sep lpar rpar pretty (args, depth: FixedInt.int) =
80814
f06fc05f7c01 more accurate output: observe depth as in "prune" operation;
wenzelm
parents: 80813
diff changeset
    99
  if depth = 0 then dots
f06fc05f7c01 more accurate output: observe depth as in "prune" operation;
wenzelm
parents: 80813
diff changeset
   100
  else
f06fc05f7c01 more accurate output: observe depth as in "prune" operation;
wenzelm
parents: 80813
diff changeset
   101
    let
f06fc05f7c01 more accurate output: observe depth as in "prune" operation;
wenzelm
parents: 80813
diff changeset
   102
      fun elems _ [] = []
f06fc05f7c01 more accurate output: observe depth as in "prune" operation;
wenzelm
parents: 80813
diff changeset
   103
        | elems 0 _ = [dots]
f06fc05f7c01 more accurate output: observe depth as in "prune" operation;
wenzelm
parents: 80813
diff changeset
   104
        | elems d [x] = [pretty (x, d)]
f06fc05f7c01 more accurate output: observe depth as in "prune" operation;
wenzelm
parents: 80813
diff changeset
   105
        | elems d (x :: xs) = pretty (x, d) :: str sep :: brk 1 :: elems (d - 1) xs;
f06fc05f7c01 more accurate output: observe depth as in "prune" operation;
wenzelm
parents: 80813
diff changeset
   106
    in block (str lpar :: (elems (FixedInt.max (depth, 0)) args @ [str rpar])) end;
38635
f76ad0771f67 added ML toplevel pretty-printing for tables, using dummy for anything other than Poly/ML 5.3.0 (or later);
wenzelm
parents: 30623
diff changeset
   107
62503
19afb533028e clarified modules;
wenzelm
parents: 62387
diff changeset
   108
80810
1f718be3608b clarified Pretty.T vs. output tree (following Isabelle/Scala): Output.output_width (via print_mode) happens during formatting, instead of construction;
wenzelm
parents: 80809
diff changeset
   109
(* prune *)
1f718be3608b clarified Pretty.T vs. output tree (following Isabelle/Scala): Output.output_width (via print_mode) happens during formatting, instead of construction;
wenzelm
parents: 80809
diff changeset
   110
80813
9dd4dcb08d37 clarified signature, following 1f718be3608b: Pretty.str is now value-oriented;
wenzelm
parents: 80810
diff changeset
   111
fun prune (0: FixedInt.int) (PrettyBlock _) = dots
80810
1f718be3608b clarified Pretty.T vs. output tree (following Isabelle/Scala): Output.output_width (via print_mode) happens during formatting, instead of construction;
wenzelm
parents: 80809
diff changeset
   112
  | prune depth (PrettyBlock (ind, consistent, context, body)) =
1f718be3608b clarified Pretty.T vs. output tree (following Isabelle/Scala): Output.output_width (via print_mode) happens during formatting, instead of construction;
wenzelm
parents: 80809
diff changeset
   113
      PrettyBlock (ind, consistent, context, map (prune (depth - 1)) body)
1f718be3608b clarified Pretty.T vs. output tree (following Isabelle/Scala): Output.output_width (via print_mode) happens during formatting, instead of construction;
wenzelm
parents: 80809
diff changeset
   114
  | prune _ prt = prt;
1f718be3608b clarified Pretty.T vs. output tree (following Isabelle/Scala): Output.output_width (via print_mode) happens during formatting, instead of construction;
wenzelm
parents: 80809
diff changeset
   115
1f718be3608b clarified Pretty.T vs. output tree (following Isabelle/Scala): Output.output_width (via print_mode) happens during formatting, instead of construction;
wenzelm
parents: 80809
diff changeset
   116
62662
291cc01f56f5 @{make_string} is available during Pure bootstrap;
wenzelm
parents: 62661
diff changeset
   117
(* format *)
291cc01f56f5 @{make_string} is available during Pure bootstrap;
wenzelm
parents: 62661
diff changeset
   118
80809
4a64fc4d1cde clarified signature: type ML_Pretty.pretty coincides with PolyML.pretty;
wenzelm
parents: 68918
diff changeset
   119
fun format margin prt =
62662
291cc01f56f5 @{make_string} is available during Pure bootstrap;
wenzelm
parents: 62661
diff changeset
   120
  let
291cc01f56f5 @{make_string} is available during Pure bootstrap;
wenzelm
parents: 62661
diff changeset
   121
    val result = Unsynchronized.ref [];
80809
4a64fc4d1cde clarified signature: type ML_Pretty.pretty coincides with PolyML.pretty;
wenzelm
parents: 68918
diff changeset
   122
    val () = PolyML.prettyPrint (fn s => result := s :: ! result, margin) prt;
4a64fc4d1cde clarified signature: type ML_Pretty.pretty coincides with PolyML.pretty;
wenzelm
parents: 68918
diff changeset
   123
  in implode (rev (! result)) end;
62662
291cc01f56f5 @{make_string} is available during Pure bootstrap;
wenzelm
parents: 62661
diff changeset
   124
62899
845ed4584e21 clarified bootstrap of @{make_string} -- avoid query on ML environment;
wenzelm
parents: 62878
diff changeset
   125
val default_margin = 76;
845ed4584e21 clarified bootstrap of @{make_string} -- avoid query on ML environment;
wenzelm
parents: 62878
diff changeset
   126
80840
793e490d7bd1 tuned signature;
wenzelm
parents: 80814
diff changeset
   127
val get_margin = the_default default_margin;
793e490d7bd1 tuned signature;
wenzelm
parents: 80814
diff changeset
   128
62662
291cc01f56f5 @{make_string} is available during Pure bootstrap;
wenzelm
parents: 62661
diff changeset
   129
291cc01f56f5 @{make_string} is available during Pure bootstrap;
wenzelm
parents: 62661
diff changeset
   130
(* make string *)
291cc01f56f5 @{make_string} is available during Pure bootstrap;
wenzelm
parents: 62661
diff changeset
   131
80809
4a64fc4d1cde clarified signature: type ML_Pretty.pretty coincides with PolyML.pretty;
wenzelm
parents: 68918
diff changeset
   132
val string_of = format default_margin;
62662
291cc01f56f5 @{make_string} is available during Pure bootstrap;
wenzelm
parents: 62661
diff changeset
   133
62900
c641bf9402fd simplified default print_depth: context is usually available, in contrast to 0d295e339f52;
wenzelm
parents: 62899
diff changeset
   134
val make_string_fn =
80809
4a64fc4d1cde clarified signature: type ML_Pretty.pretty coincides with PolyML.pretty;
wenzelm
parents: 68918
diff changeset
   135
  "(fn x => ML_Pretty.string_of (ML_system_pretty \
62900
c641bf9402fd simplified default print_depth: context is usually available, in contrast to 0d295e339f52;
wenzelm
parents: 62899
diff changeset
   136
    \(x, FixedInt.fromInt (ML_Print_Depth.get_print_depth ()))))";
62662
291cc01f56f5 @{make_string} is available during Pure bootstrap;
wenzelm
parents: 62661
diff changeset
   137
62661
c23ff2f45a18 clarified modules;
wenzelm
parents: 62508
diff changeset
   138
end;