src/Tools/Metis/src/Print.sml
author blanchet
Mon, 13 Sep 2010 21:09:43 +0200
changeset 39348 6f9c9899f99f
child 39349 2d0a4361c3ef
permissions -rw-r--r--
new version of the Metis files
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
39348
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
     1
(* ========================================================================= *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
     2
(* PRETTY-PRINTING                                                           *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
     3
(* Copyright (c) 2001-2008 Joe Hurd, distributed under the GNU GPL version 2 *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
     4
(* ========================================================================= *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
     5
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
     6
structure Print :> Print =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
     7
struct
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
     8
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
     9
open Useful;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    10
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    11
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    12
(* Constants.                                                                *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    13
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    14
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    15
val initialLineLength = 75;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    16
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    17
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    18
(* Helper functions.                                                         *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    19
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    20
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    21
fun revAppend xs s =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    22
    case xs of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    23
      [] => s ()
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    24
    | x :: xs => revAppend xs (K (Stream.Cons (x,s)));
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    25
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    26
fun revConcat strm =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    27
    case strm of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    28
      Stream.Nil => Stream.Nil
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    29
    | Stream.Cons (h,t) => revAppend h (revConcat o t);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    30
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    31
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    32
  fun join current prev = (prev ^ "\n", current);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    33
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    34
  fun joinNewline strm =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    35
      case strm of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    36
        Stream.Nil => Stream.Nil
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    37
      | Stream.Cons (h,t) => Stream.maps join Stream.singleton h (t ());
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    38
end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    39
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    40
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    41
  fun calcSpaces n = nChars #" " n;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    42
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    43
  val cachedSpaces = Vector.tabulate (initialLineLength,calcSpaces);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    44
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    45
  fun nSpaces n =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    46
      if n < initialLineLength then Vector.sub (cachedSpaces,n)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    47
      else calcSpaces n;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    48
end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    49
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    50
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    51
(* A type of pretty-printers.                                                *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    52
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    53
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    54
datatype breakStyle = Consistent | Inconsistent;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    55
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    56
datatype ppStep =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    57
    BeginBlock of breakStyle * int
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    58
  | EndBlock
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    59
  | AddString of string
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    60
  | AddBreak of int
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    61
  | AddNewline;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    62
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    63
type ppstream = ppStep Stream.stream;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    64
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    65
type 'a pp = 'a -> ppstream;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    66
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    67
fun breakStyleToString style =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    68
    case style of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    69
      Consistent => "Consistent"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    70
    | Inconsistent => "Inconsistent";
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    71
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    72
fun ppStepToString step =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    73
    case step of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    74
      BeginBlock _ => "BeginBlock"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    75
    | EndBlock => "EndBlock"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    76
    | AddString _ => "AddString"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    77
    | AddBreak _ => "AddBreak"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    78
    | AddNewline => "AddNewline";
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    79
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    80
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    81
(* Pretty-printer primitives.                                                *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    82
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    83
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    84
fun beginBlock style indent = Stream.singleton (BeginBlock (style,indent));
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    85
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    86
val endBlock = Stream.singleton EndBlock;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    87
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    88
fun addString s = Stream.singleton (AddString s);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    89
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    90
fun addBreak spaces = Stream.singleton (AddBreak spaces);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    91
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    92
val addNewline = Stream.singleton AddNewline;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    93
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    94
val skip : ppstream = Stream.Nil;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    95
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    96
fun sequence pp1 pp2 : ppstream = Stream.append pp1 (K pp2);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    97
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    98
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    99
  fun dup pp n () = if n = 1 then pp else Stream.append pp (dup pp (n - 1));
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   100
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   101
  fun duplicate n pp = if n = 0 then skip else dup pp n ();
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   102
end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   103
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   104
val program : ppstream list -> ppstream = Stream.concatList;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   105
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   106
val stream : ppstream Stream.stream -> ppstream = Stream.concat;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   107
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   108
fun block style indent pp = program [beginBlock style indent, pp, endBlock];
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   109
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   110
fun blockProgram style indent pps = block style indent (program pps);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   111
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   112
fun bracket l r pp =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   113
    blockProgram Inconsistent (size l)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   114
      [addString l,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   115
       pp,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   116
       addString r];
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   117
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   118
fun field f pp =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   119
    blockProgram Inconsistent 2
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   120
      [addString (f ^ " ="),
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   121
       addBreak 1,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   122
       pp];
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   123
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   124
val record =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   125
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   126
      val sep = sequence (addString ",") (addBreak 1)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   127
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   128
      fun recordField (f,pp) = field f pp
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   129
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   130
      fun sepField f = sequence sep (recordField f)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   131
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   132
      fun fields [] = []
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   133
        | fields (f :: fs) = recordField f :: map sepField fs
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   134
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   135
      bracket "{" "}" o blockProgram Consistent 0 o fields
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   136
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   137
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   138
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   139
(* Pretty-printer combinators.                                               *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   140
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   141
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   142
fun ppMap f ppB a : ppstream = ppB (f a);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   143
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   144
fun ppBracket l r ppA a = bracket l r (ppA a);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   145
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   146
fun ppOp s = sequence (if s = "" then skip else addString s) (addBreak 1);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   147
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   148
fun ppOp2 ab ppA ppB (a,b) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   149
    blockProgram Inconsistent 0
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   150
      [ppA a,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   151
       ppOp ab,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   152
       ppB b];
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   153
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   154
fun ppOp3 ab bc ppA ppB ppC (a,b,c) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   155
    blockProgram Inconsistent 0
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   156
      [ppA a,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   157
       ppOp ab,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   158
       ppB b,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   159
       ppOp bc,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   160
       ppC c];
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   161
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   162
fun ppOpList s ppA =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   163
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   164
      fun ppOpA a = sequence (ppOp s) (ppA a)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   165
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   166
      fn [] => skip
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   167
       | h :: t => blockProgram Inconsistent 0 (ppA h :: map ppOpA t)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   168
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   169
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   170
fun ppOpStream s ppA =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   171
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   172
      fun ppOpA a = sequence (ppOp s) (ppA a)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   173
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   174
      fn Stream.Nil => skip
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   175
       | Stream.Cons (h,t) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   176
         blockProgram Inconsistent 0
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   177
           [ppA h,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   178
            Stream.concat (Stream.map ppOpA (t ()))]
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   179
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   180
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   181
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   182
(* Pretty-printers for common types.                                         *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   183
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   184
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   185
fun ppChar c = addString (str c);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   186
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   187
val ppString = addString;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   188
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   189
fun ppEscapeString {escape} =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   190
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   191
      val escapeMap = map (fn c => (c, "\\" ^ str c)) escape
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   192
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   193
      fun escapeChar c =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   194
          case c of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   195
            #"\\" => "\\\\"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   196
          | #"\n" => "\\n"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   197
          | #"\t" => "\\t"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   198
          | _ =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   199
            case List.find (equal c o fst) escapeMap of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   200
              SOME (_,s) => s
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   201
            | NONE => str c
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   202
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   203
      fn s => addString (String.translate escapeChar s)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   204
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   205
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   206
val ppUnit : unit pp = K (addString "()");
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   207
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   208
fun ppBool b = addString (if b then "true" else "false");
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   209
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   210
fun ppInt i = addString (Int.toString i);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   211
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   212
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   213
  val ppNeg = addString "~"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   214
  and ppSep = addString ","
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   215
  and ppZero = addString "0"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   216
  and ppZeroZero = addString "00";
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   217
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   218
  fun ppIntBlock i =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   219
      if i < 10 then sequence ppZeroZero (ppInt i)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   220
      else if i < 100 then sequence ppZero (ppInt i)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   221
      else ppInt i;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   222
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   223
  fun ppIntBlocks i =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   224
      if i < 1000 then ppInt i
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   225
      else sequence (ppIntBlocks (i div 1000))
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   226
             (sequence ppSep (ppIntBlock (i mod 1000)));
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   227
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   228
  fun ppPrettyInt i =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   229
      if i < 0 then sequence ppNeg (ppIntBlocks (~i))
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   230
      else ppIntBlocks i;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   231
end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   232
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   233
fun ppReal r = addString (Real.toString r);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   234
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   235
fun ppPercent p = addString (percentToString p);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   236
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   237
fun ppOrder x =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   238
    addString
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   239
      (case x of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   240
         LESS => "Less"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   241
       | EQUAL => "Equal"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   242
       | GREATER => "Greater");
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   243
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   244
fun ppList ppA = ppBracket "[" "]" (ppOpList "," ppA);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   245
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   246
fun ppStream ppA = ppBracket "[" "]" (ppOpStream "," ppA);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   247
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   248
fun ppOption ppA ao =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   249
    case ao of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   250
      SOME a => ppA a
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   251
    | NONE => addString "-";
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   252
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   253
fun ppPair ppA ppB = ppBracket "(" ")" (ppOp2 "," ppA ppB);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   254
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   255
fun ppTriple ppA ppB ppC = ppBracket "(" ")" (ppOp3 "," "," ppA ppB ppC);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   256
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   257
fun ppBreakStyle style = addString (breakStyleToString style);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   258
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   259
fun ppPpStep step =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   260
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   261
      val cmd = ppStepToString step
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   262
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   263
      blockProgram Inconsistent 2
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   264
        (addString cmd ::
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   265
         (case step of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   266
            BeginBlock style_indent =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   267
              [addBreak 1,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   268
               ppPair ppBreakStyle ppInt style_indent]
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   269
          | EndBlock => []
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   270
          | AddString s =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   271
              [addBreak 1,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   272
               addString ("\"" ^ s ^ "\"")]
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   273
          | AddBreak n =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   274
              [addBreak 1,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   275
               ppInt n]
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   276
          | AddNewline => []))
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   277
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   278
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   279
val ppPpstream = ppStream ppPpStep;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   280
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   281
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   282
(* Pretty-printing infix operators.                                          *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   283
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   284
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   285
datatype infixes =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   286
    Infixes of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   287
      {token : string,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   288
       precedence : int,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   289
       leftAssoc : bool} list;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   290
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   291
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   292
  fun chop l =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   293
      case l of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   294
        #" " :: l => let val (n,l) = chop l in (n + 1, l) end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   295
      | _ => (0,l);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   296
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   297
  fun opSpaces tok =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   298
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   299
        val tok = explode tok
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   300
        val (r,tok) = chop (rev tok)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   301
        val (l,tok) = chop (rev tok)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   302
        val tok = implode tok
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   303
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   304
        {leftSpaces = l, token = tok, rightSpaces = r}
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   305
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   306
end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   307
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   308
fun ppOpSpaces {leftSpaces,token,rightSpaces} =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   309
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   310
      val leftSpacesToken =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   311
          if leftSpaces = 0 then token else nSpaces leftSpaces ^ token
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   312
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   313
      sequence
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   314
        (addString leftSpacesToken)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   315
        (addBreak rightSpaces)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   316
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   317
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   318
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   319
  fun new t l acc = {tokens = [opSpaces t], leftAssoc = l} :: acc;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   320
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   321
  fun add t l acc =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   322
      case acc of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   323
        [] => raise Bug "Print.layerInfixOps.layer"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   324
      | {tokens = ts, leftAssoc = l'} :: acc =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   325
        if l = l' then {tokens = opSpaces t :: ts, leftAssoc = l} :: acc
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   326
        else raise Bug "Print.layerInfixOps: mixed assocs";
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   327
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   328
  fun layer ({token = t, precedence = p, leftAssoc = l}, (acc,p')) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   329
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   330
        val acc = if p = p' then add t l acc else new t l acc
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   331
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   332
        (acc,p)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   333
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   334
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   335
  fun layerInfixes (Infixes i) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   336
      case sortMap #precedence Int.compare i of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   337
        [] => []
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   338
      | {token = t, precedence = p, leftAssoc = l} :: i =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   339
        let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   340
          val acc = new t l []
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   341
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   342
          val (acc,_) = List.foldl layer (acc,p) i
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   343
        in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   344
          acc
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   345
        end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   346
end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   347
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   348
val tokensLayeredInfixes =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   349
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   350
      fun addToken ({leftSpaces = _, token = t, rightSpaces = _}, s) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   351
          StringSet.add s t
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   352
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   353
      fun addTokens ({tokens = t, leftAssoc = _}, s) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   354
          List.foldl addToken s t
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   355
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   356
      List.foldl addTokens StringSet.empty
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   357
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   358
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   359
val tokensInfixes = tokensLayeredInfixes o layerInfixes;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   360
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   361
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   362
  val mkTokenMap =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   363
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   364
        fun add (token,m) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   365
            let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   366
              val {leftSpaces = _, token = t, rightSpaces = _} = token
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   367
            in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   368
              StringMap.insert m (t, ppOpSpaces token)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   369
            end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   370
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   371
        List.foldl add (StringMap.new ())
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   372
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   373
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   374
  fun ppGenInfix {tokens,leftAssoc} =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   375
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   376
        val tokenMap = mkTokenMap tokens
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   377
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   378
        fn dest => fn ppSub =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   379
           let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   380
             fun dest' tm =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   381
                 case dest tm of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   382
                   NONE => NONE
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   383
                 | SOME (t,a,b) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   384
                   case StringMap.peek tokenMap t of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   385
                     NONE => NONE
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   386
                   | SOME p => SOME (p,a,b)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   387
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   388
             fun ppGo (tmr as (tm,r)) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   389
                 case dest' tm of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   390
                   NONE => ppSub tmr
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   391
                 | SOME (p,a,b) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   392
                   program
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   393
                     [(if leftAssoc then ppGo else ppSub) (a,true),
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   394
                      p,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   395
                      (if leftAssoc then ppSub else ppGo) (b,r)]
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   396
           in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   397
             fn tmr as (tm,_) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   398
                if Option.isSome (dest' tm) then
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   399
                  block Inconsistent 0 (ppGo tmr)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   400
                else
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   401
                  ppSub tmr
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   402
           end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   403
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   404
end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   405
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   406
fun ppInfixes ops =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   407
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   408
      val layeredOps = layerInfixes ops
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   409
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   410
      val toks = tokensLayeredInfixes layeredOps
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   411
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   412
      val iprinters = List.map ppGenInfix layeredOps
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   413
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   414
      fn dest => fn ppSub =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   415
         let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   416
           fun printer sub = foldl (fn (ip,p) => ip dest p) sub iprinters
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   417
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   418
           fun isOp t =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   419
               case dest t of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   420
                 SOME (x,_,_) => StringSet.member x toks
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   421
               | NONE => false
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   422
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   423
           fun subpr (tmr as (tm,_)) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   424
               if isOp tm then
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   425
                 blockProgram Inconsistent 1
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   426
                   [addString "(",
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   427
                    printer subpr (tm,false),
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   428
                    addString ")"]
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   429
               else
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   430
                 ppSub tmr
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   431
         in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   432
           fn tmr => block Inconsistent 0 (printer subpr tmr)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   433
         end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   434
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   435
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   436
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   437
(* Executing pretty-printers to generate lines.                              *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   438
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   439
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   440
datatype blockBreakStyle =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   441
    InconsistentBlock
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   442
  | ConsistentBlock
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   443
  | BreakingBlock;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   444
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   445
datatype block =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   446
    Block of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   447
      {indent : int,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   448
       style : blockBreakStyle,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   449
       size : int,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   450
       chunks : chunk list}
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   451
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   452
and chunk =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   453
    StringChunk of {size : int, string : string}
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   454
  | BreakChunk of int
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   455
  | BlockChunk of block;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   456
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   457
datatype state =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   458
    State of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   459
      {blocks : block list,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   460
       lineIndent : int,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   461
       lineSize : int};
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   462
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   463
val initialIndent = 0;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   464
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   465
val initialStyle = Inconsistent;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   466
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   467
fun liftStyle style =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   468
    case style of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   469
      Inconsistent => InconsistentBlock
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   470
    | Consistent => ConsistentBlock;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   471
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   472
fun breakStyle style =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   473
    case style of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   474
      ConsistentBlock => BreakingBlock
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   475
    | _ => style;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   476
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   477
fun sizeBlock (Block {size,...}) = size;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   478
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   479
fun sizeChunk chunk =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   480
    case chunk of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   481
      StringChunk {size,...} => size
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   482
    | BreakChunk spaces => spaces
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   483
    | BlockChunk block => sizeBlock block;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   484
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   485
val splitChunks =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   486
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   487
      fun split _ [] = NONE
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   488
        | split acc (chunk :: chunks) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   489
          case chunk of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   490
            BreakChunk _ => SOME (rev acc, chunks)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   491
          | _ => split (chunk :: acc) chunks
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   492
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   493
      split []
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   494
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   495
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   496
val sizeChunks = List.foldl (fn (c,z) => sizeChunk c + z) 0;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   497
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   498
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   499
  fun render acc [] = acc
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   500
    | render acc (chunk :: chunks) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   501
      case chunk of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   502
        StringChunk {string = s, ...} => render (acc ^ s) chunks
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   503
      | BreakChunk n => render (acc ^ nSpaces n) chunks
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   504
      | BlockChunk (Block {chunks = l, ...}) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   505
        render acc (List.revAppend (l,chunks));
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   506
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   507
  fun renderChunks indent chunks = render (nSpaces indent) (rev chunks);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   508
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   509
  fun renderChunk indent chunk = renderChunks indent [chunk];
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   510
end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   511
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   512
fun isEmptyBlock block =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   513
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   514
      val Block {indent = _, style = _, size, chunks} = block
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   515
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   516
      val empty = null chunks
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   517
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   518
(*BasicDebug
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   519
      val _ = not empty orelse size = 0 orelse
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   520
              raise Bug "Print.isEmptyBlock: bad size"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   521
*)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   522
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   523
      empty
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   524
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   525
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   526
fun checkBlock ind block =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   527
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   528
      val Block {indent, style = _, size, chunks} = block
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   529
      val _ = indent >= ind orelse raise Bug "Print.checkBlock: bad indents"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   530
      val size' = checkChunks indent chunks
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   531
      val _ = size = size' orelse raise Bug "Print.checkBlock: wrong size"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   532
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   533
      size
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   534
    end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   535
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   536
and checkChunks ind chunks =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   537
    case chunks of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   538
      [] => 0
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   539
    | chunk :: chunks => checkChunk ind chunk + checkChunks ind chunks
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   540
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   541
and checkChunk ind chunk =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   542
    case chunk of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   543
      StringChunk {size,...} => size
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   544
    | BreakChunk spaces => spaces
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   545
    | BlockChunk block => checkBlock ind block;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   546
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   547
val checkBlocks =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   548
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   549
      fun check ind blocks =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   550
          case blocks of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   551
            [] => 0
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   552
          | block :: blocks =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   553
            let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   554
              val Block {indent,...} = block
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   555
            in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   556
              checkBlock ind block + check indent blocks
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   557
            end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   558
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   559
      check initialIndent o rev
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   560
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   561
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   562
val initialBlock =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   563
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   564
      val indent = initialIndent
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   565
      val style = liftStyle initialStyle
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   566
      val size = 0
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   567
      val chunks = []
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   568
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   569
      Block
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   570
        {indent = indent,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   571
         style = style,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   572
         size = size,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   573
         chunks = chunks}
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   574
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   575
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   576
val initialState =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   577
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   578
      val blocks = [initialBlock]
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   579
      val lineIndent = initialIndent
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   580
      val lineSize = 0
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   581
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   582
      State
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   583
        {blocks = blocks,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   584
         lineIndent = lineIndent,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   585
         lineSize = lineSize}
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   586
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   587
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   588
(*BasicDebug
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   589
fun checkState state =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   590
    (let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   591
       val State {blocks, lineIndent = _, lineSize} = state
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   592
       val lineSize' = checkBlocks blocks
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   593
       val _ = lineSize = lineSize' orelse
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   594
               raise Error "wrong lineSize"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   595
     in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   596
       ()
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   597
     end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   598
     handle Error err => raise Bug err)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   599
    handle Bug bug => raise Bug ("Print.checkState: " ^ bug);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   600
*)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   601
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   602
fun isFinalState state =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   603
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   604
      val State {blocks,lineIndent,lineSize} = state
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   605
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   606
      case blocks of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   607
        [] => raise Bug "Print.isFinalState: no block"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   608
      | [block] => isEmptyBlock block
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   609
      | _ :: _ :: _ => false
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   610
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   611
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   612
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   613
  fun renderBreak lineIndent (chunks,lines) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   614
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   615
        val line = renderChunks lineIndent chunks
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   616
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   617
        val lines = line :: lines
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   618
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   619
        lines
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   620
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   621
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   622
  fun renderBreaks lineIndent lineIndent' breaks lines =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   623
      case rev breaks of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   624
        [] => raise Bug "Print.renderBreaks"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   625
      | c :: cs =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   626
        let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   627
          val lines = renderBreak lineIndent (c,lines)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   628
        in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   629
          List.foldl (renderBreak lineIndent') lines cs
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   630
        end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   631
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   632
  fun splitAllChunks cumulatingChunks =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   633
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   634
        fun split chunks =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   635
            case splitChunks chunks of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   636
              SOME (prefix,chunks) => prefix :: split chunks
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   637
            | NONE => [List.concat (chunks :: cumulatingChunks)]
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   638
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   639
        split
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   640
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   641
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   642
  fun mkBreak style cumulatingChunks chunks =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   643
      case splitChunks chunks of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   644
        NONE => NONE
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   645
      | SOME (chunks,broken) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   646
        let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   647
          val breaks =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   648
              case style of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   649
                InconsistentBlock =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   650
                [List.concat (broken :: cumulatingChunks)]
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   651
              | _ => splitAllChunks cumulatingChunks broken
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   652
        in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   653
          SOME (breaks,chunks)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   654
        end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   655
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   656
  fun naturalBreak blocks =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   657
      case blocks of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   658
        [] => Right ([],[])
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   659
      | block :: blocks =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   660
        case naturalBreak blocks of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   661
          Left (breaks,blocks,lineIndent,lineSize) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   662
          let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   663
            val Block {size,...} = block
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   664
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   665
            val blocks = block :: blocks
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   666
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   667
            val lineSize = lineSize + size
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   668
          in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   669
            Left (breaks,blocks,lineIndent,lineSize)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   670
          end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   671
        | Right (cumulatingChunks,blocks) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   672
          let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   673
            val Block {indent,style,size,chunks} = block
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   674
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   675
            val style = breakStyle style
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   676
          in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   677
            case mkBreak style cumulatingChunks chunks of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   678
              SOME (breaks,chunks) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   679
              let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   680
                val size = sizeChunks chunks
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   681
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   682
                val block =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   683
                    Block
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   684
                      {indent = indent,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   685
                       style = style,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   686
                       size = size,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   687
                       chunks = chunks}
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   688
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   689
                val blocks = block :: blocks
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   690
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   691
                val lineIndent = indent
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   692
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   693
                val lineSize = size
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   694
              in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   695
                Left (breaks,blocks,lineIndent,lineSize)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   696
              end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   697
            | NONE =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   698
              let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   699
                val cumulatingChunks = chunks :: cumulatingChunks
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   700
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   701
                val size = 0
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   702
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   703
                val chunks = []
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   704
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   705
                val block =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   706
                    Block
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   707
                      {indent = indent,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   708
                       style = style,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   709
                       size = size,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   710
                       chunks = chunks}
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   711
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   712
                val blocks = block :: blocks
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   713
              in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   714
                Right (cumulatingChunks,blocks)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   715
              end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   716
          end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   717
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   718
  fun forceBreakBlock cumulatingChunks block =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   719
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   720
        val Block {indent, style, size = _, chunks} = block
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   721
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   722
        val style = breakStyle style
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   723
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   724
        val break =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   725
            case mkBreak style cumulatingChunks chunks of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   726
              SOME (breaks,chunks) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   727
              let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   728
                val lineSize = sizeChunks chunks
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   729
                val lineIndent = indent
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   730
              in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   731
                SOME (breaks,chunks,lineIndent,lineSize)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   732
              end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   733
            | NONE => forceBreakChunks cumulatingChunks chunks
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   734
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   735
        case break of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   736
          SOME (breaks,chunks,lineIndent,lineSize) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   737
          let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   738
            val size = lineSize
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   739
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   740
            val block =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   741
                Block
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   742
                  {indent = indent,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   743
                   style = style,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   744
                   size = size,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   745
                   chunks = chunks}
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   746
          in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   747
            SOME (breaks,block,lineIndent,lineSize)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   748
          end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   749
        | NONE => NONE
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   750
      end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   751
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   752
  and forceBreakChunks cumulatingChunks chunks =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   753
      case chunks of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   754
        [] => NONE
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   755
      | chunk :: chunks =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   756
        case forceBreakChunk (chunks :: cumulatingChunks) chunk of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   757
          SOME (breaks,chunk,lineIndent,lineSize) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   758
          let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   759
            val chunks = [chunk]
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   760
          in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   761
            SOME (breaks,chunks,lineIndent,lineSize)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   762
          end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   763
        | NONE =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   764
          case forceBreakChunks cumulatingChunks chunks of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   765
            SOME (breaks,chunks,lineIndent,lineSize) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   766
            let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   767
              val chunks = chunk :: chunks
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   768
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   769
              val lineSize = lineSize + sizeChunk chunk
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   770
            in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   771
              SOME (breaks,chunks,lineIndent,lineSize)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   772
            end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   773
          | NONE => NONE
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   774
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   775
  and forceBreakChunk cumulatingChunks chunk =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   776
      case chunk of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   777
        StringChunk _ => NONE
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   778
      | BreakChunk _ => raise Bug "Print.forceBreakChunk: BreakChunk"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   779
      | BlockChunk block =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   780
        case forceBreakBlock cumulatingChunks block of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   781
          SOME (breaks,block,lineIndent,lineSize) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   782
          let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   783
            val chunk = BlockChunk block
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   784
          in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   785
            SOME (breaks,chunk,lineIndent,lineSize)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   786
          end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   787
        | NONE => NONE;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   788
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   789
  fun forceBreak cumulatingChunks blocks' blocks =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   790
      case blocks of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   791
        [] => NONE
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   792
      | block :: blocks =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   793
        let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   794
          val cumulatingChunks =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   795
              case cumulatingChunks of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   796
                [] => raise Bug "Print.forceBreak: null cumulatingChunks"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   797
              | _ :: cumulatingChunks => cumulatingChunks
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   798
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   799
          val blocks' =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   800
              case blocks' of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   801
                [] => raise Bug "Print.forceBreak: null blocks'"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   802
              | _ :: blocks' => blocks'
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   803
        in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   804
          case forceBreakBlock cumulatingChunks block of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   805
            SOME (breaks,block,lineIndent,lineSize) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   806
            let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   807
              val blocks = block :: blocks'
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   808
            in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   809
              SOME (breaks,blocks,lineIndent,lineSize)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   810
            end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   811
          | NONE =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   812
            case forceBreak cumulatingChunks blocks' blocks of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   813
              SOME (breaks,blocks,lineIndent,lineSize) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   814
              let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   815
                val blocks = block :: blocks
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   816
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   817
                val Block {size,...} = block
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   818
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   819
                val lineSize = lineSize + size
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   820
              in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   821
                SOME (breaks,blocks,lineIndent,lineSize)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   822
              end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   823
            | NONE => NONE
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   824
        end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   825
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   826
  fun normalize lineLength lines state =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   827
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   828
        val State {blocks,lineIndent,lineSize} = state
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   829
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   830
        if lineIndent + lineSize <= lineLength then (lines,state)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   831
        else
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   832
          let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   833
            val break =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   834
                case naturalBreak blocks of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   835
                  Left break => SOME break
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   836
                | Right (c,b) => forceBreak c b blocks
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   837
          in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   838
            case break of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   839
              SOME (breaks,blocks,lineIndent',lineSize) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   840
              let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   841
                val lines = renderBreaks lineIndent lineIndent' breaks lines
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   842
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   843
                val state =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   844
                    State
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   845
                      {blocks = blocks,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   846
                       lineIndent = lineIndent',
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   847
                       lineSize = lineSize}
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   848
              in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   849
                normalize lineLength lines state
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   850
              end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   851
            | NONE => (lines,state)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   852
          end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   853
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   854
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   855
(*BasicDebug
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   856
  val normalize = fn lineLength => fn lines => fn state =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   857
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   858
        val () = checkState state
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   859
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   860
        normalize lineLength lines state
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   861
      end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   862
      handle Bug bug =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   863
        raise Bug ("Print.normalize: before normalize:\n" ^ bug)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   864
*)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   865
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   866
  fun executeBeginBlock (style,ind) lines state =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   867
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   868
        val State {blocks,lineIndent,lineSize} = state
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   869
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   870
        val Block {indent,...} =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   871
            case blocks of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   872
              [] => raise Bug "Print.executeBeginBlock: no block"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   873
            | block :: _ => block
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   874
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   875
        val indent = indent + ind
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   876
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   877
        val style = liftStyle style
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   878
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   879
        val size = 0
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   880
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   881
        val chunks = []
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   882
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   883
        val block =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   884
            Block
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   885
              {indent = indent,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   886
               style = style,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   887
               size = size,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   888
               chunks = chunks}
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   889
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   890
        val blocks = block :: blocks
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   891
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   892
        val state =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   893
            State
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   894
              {blocks = blocks,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   895
               lineIndent = lineIndent,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   896
               lineSize = lineSize}
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   897
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   898
        (lines,state)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   899
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   900
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   901
  fun executeEndBlock lines state =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   902
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   903
        val State {blocks,lineIndent,lineSize} = state
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   904
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   905
        val (lineSize,blocks) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   906
            case blocks of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   907
              [] => raise Bug "Print.executeEndBlock: no block"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   908
            | topBlock :: blocks =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   909
              let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   910
                val Block
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   911
                      {indent = topIndent,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   912
                       style = topStyle,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   913
                       size = topSize,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   914
                       chunks = topChunks} = topBlock
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   915
              in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   916
                case topChunks of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   917
                  [] => (lineSize,blocks)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   918
                | headTopChunks :: tailTopChunks =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   919
                  let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   920
                    val (lineSize,topSize,topChunks) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   921
                        case headTopChunks of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   922
                          BreakChunk spaces =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   923
                          let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   924
                            val lineSize = lineSize - spaces
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   925
                            and topSize = topSize - spaces
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   926
                            and topChunks = tailTopChunks
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   927
                          in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   928
                            (lineSize,topSize,topChunks)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   929
                          end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   930
                        | _ => (lineSize,topSize,topChunks)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   931
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   932
                    val topBlock =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   933
                        Block
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   934
                          {indent = topIndent,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   935
                           style = topStyle,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   936
                           size = topSize,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   937
                           chunks = topChunks}
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   938
                  in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   939
                    case blocks of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   940
                      [] => raise Error "Print.executeEndBlock: no block"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   941
                    | block :: blocks =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   942
                      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   943
                        val Block {indent,style,size,chunks} = block
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   944
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   945
                        val size = size + topSize
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   946
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   947
                        val chunks = BlockChunk topBlock :: chunks
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   948
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   949
                        val block =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   950
                            Block
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   951
                              {indent = indent,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   952
                               style = style,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   953
                               size = size,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   954
                               chunks = chunks}
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   955
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   956
                        val blocks = block :: blocks
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   957
                      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   958
                        (lineSize,blocks)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   959
                      end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   960
                  end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   961
              end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   962
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   963
        val state =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   964
            State
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   965
              {blocks = blocks,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   966
               lineIndent = lineIndent,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   967
               lineSize = lineSize}
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   968
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   969
        (lines,state)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   970
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   971
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   972
  fun executeAddString lineLength s lines state =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   973
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   974
        val State {blocks,lineIndent,lineSize} = state
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   975
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   976
        val n = size s
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   977
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   978
        val blocks =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   979
            case blocks of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   980
              [] => raise Bug "Print.executeAddString: no block"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   981
            | Block {indent,style,size,chunks} :: blocks =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   982
              let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   983
                val size = size + n
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   984
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   985
                val chunk = StringChunk {size = n, string = s}
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   986
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   987
                val chunks = chunk :: chunks
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   988
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   989
                val block =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   990
                    Block
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   991
                      {indent = indent,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   992
                       style = style,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   993
                       size = size,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   994
                       chunks = chunks}
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   995
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   996
                val blocks = block :: blocks
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   997
              in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   998
                blocks
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   999
              end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1000
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1001
        val lineSize = lineSize + n
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1002
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1003
        val state =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1004
            State
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1005
              {blocks = blocks,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1006
               lineIndent = lineIndent,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1007
               lineSize = lineSize}
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1008
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1009
        normalize lineLength lines state
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1010
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1011
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1012
  fun executeAddBreak lineLength spaces lines state =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1013
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1014
        val State {blocks,lineIndent,lineSize} = state
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1015
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1016
        val (blocks,lineSize) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1017
            case blocks of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1018
              [] => raise Bug "Print.executeAddBreak: no block"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1019
            | Block {indent,style,size,chunks} :: blocks' =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1020
              case chunks of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1021
                [] => (blocks,lineSize)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1022
              | chunk :: chunks' =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1023
                let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1024
                  val spaces =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1025
                      case style of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1026
                        BreakingBlock => lineLength + 1
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1027
                      | _ => spaces
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1028
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1029
                  val size = size + spaces
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1030
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1031
                  val chunks =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1032
                      case chunk of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1033
                        BreakChunk k => BreakChunk (k + spaces) :: chunks'
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1034
                      | _ => BreakChunk spaces :: chunks
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1035
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1036
                  val block =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1037
                      Block
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1038
                        {indent = indent,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1039
                         style = style,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1040
                         size = size,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1041
                         chunks = chunks}
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1042
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1043
                  val blocks = block :: blocks'
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1044
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1045
                  val lineSize = lineSize + spaces
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1046
                in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1047
                  (blocks,lineSize)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1048
                end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1049
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1050
        val state =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1051
            State
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1052
              {blocks = blocks,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1053
               lineIndent = lineIndent,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1054
               lineSize = lineSize}
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1055
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1056
        normalize lineLength lines state
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1057
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1058
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1059
  fun executeBigBreak lineLength lines state =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1060
      executeAddBreak lineLength (lineLength + 1) lines state;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1061
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1062
  fun executeAddNewline lineLength lines state =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1063
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1064
        val (lines,state) = executeAddString lineLength "" lines state
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1065
        val (lines,state) = executeBigBreak lineLength lines state
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1066
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1067
        executeAddString lineLength "" lines state
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1068
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1069
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1070
  fun final lineLength lines state =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1071
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1072
        val lines =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1073
            if isFinalState state then lines
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1074
            else
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1075
              let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1076
                val (lines,state) = executeBigBreak lineLength lines state
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1077
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1078
(*BasicDebug
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1079
                val _ = isFinalState state orelse raise Bug "Print.final"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1080
*)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1081
              in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1082
                lines
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1083
              end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1084
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1085
        if null lines then Stream.Nil else Stream.singleton lines
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1086
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1087
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1088
  fun execute {lineLength} =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1089
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1090
        fun advance step state =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1091
            let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1092
              val lines = []
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1093
            in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1094
              case step of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1095
                BeginBlock style_ind => executeBeginBlock style_ind lines state
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1096
              | EndBlock => executeEndBlock lines state
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1097
              | AddString s => executeAddString lineLength s lines state
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1098
              | AddBreak spaces => executeAddBreak lineLength spaces lines state
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1099
              | AddNewline => executeAddNewline lineLength lines state
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1100
            end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1101
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1102
(*BasicDebug
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1103
        val advance = fn step => fn state =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1104
            let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1105
              val (lines,state) = advance step state
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1106
              val () = checkState state
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1107
            in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1108
              (lines,state)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1109
            end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1110
            handle Bug bug =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1111
              raise Bug ("Print.advance: after " ^ ppStepToString step ^
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1112
                         " command:\n" ^ bug)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1113
*)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1114
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1115
        revConcat o Stream.maps advance (final lineLength []) initialState
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1116
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1117
end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1118
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1119
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1120
(* Executing pretty-printers with a global line length.                      *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1121
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1122
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1123
val lineLength = ref initialLineLength;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1124
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1125
fun toStream ppA a =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1126
    Stream.map (fn s => s ^ "\n")
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1127
      (execute {lineLength = !lineLength} (ppA a));
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1128
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1129
fun toString ppA a =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1130
    case execute {lineLength = !lineLength} (ppA a) of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1131
      Stream.Nil => ""
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1132
    | Stream.Cons (h,t) => Stream.foldl (fn (s,z) => z ^ "\n" ^ s) h (t ());
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1133
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1134
fun trace ppX nameX x =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1135
    Useful.trace (toString (ppOp2 " =" ppString ppX) (nameX,x) ^ "\n");
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1136
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1137
end