1(* ========================================================================= *) 2(* PRETTY-PRINTING *) 3(* Copyright (c) 2008 Joe Hurd, distributed under the BSD License *) 4(* ========================================================================= *) 5 6signature Print = 7sig 8 9(* ------------------------------------------------------------------------- *) 10(* Escaping strings. *) 11(* ------------------------------------------------------------------------- *) 12 13val escapeString : {escape : char list} -> string -> string 14 15(* ------------------------------------------------------------------------- *) 16(* A type of pretty-printers. *) 17(* ------------------------------------------------------------------------- *) 18 19type ppstream 20 21type 'a pp = 'a -> ppstream 22 23val skip : ppstream 24 25val sequence : ppstream -> ppstream -> ppstream 26 27val duplicate : int -> ppstream -> ppstream 28 29val program : ppstream list -> ppstream 30 31val stream : ppstream Stream.stream -> ppstream 32 33val ppPpstream : ppstream pp 34 35(* ------------------------------------------------------------------------- *) 36(* Pretty-printing blocks. *) 37(* ------------------------------------------------------------------------- *) 38 39datatype style = Consistent | Inconsistent 40 41datatype block = 42 Block of 43 {style : style, 44 indent : int} 45 46val styleBlock : block -> style 47 48val indentBlock : block -> int 49 50val block : block -> ppstream -> ppstream 51 52val consistentBlock : int -> ppstream list -> ppstream 53 54val inconsistentBlock : int -> ppstream list -> ppstream 55 56(* ------------------------------------------------------------------------- *) 57(* Words are unbreakable strings annotated with their effective size. *) 58(* ------------------------------------------------------------------------- *) 59 60datatype word = Word of {word : string, size : int} 61 62val mkWord : string -> word 63 64val emptyWord : word 65 66val charWord : char -> word 67 68val ppWord : word pp 69 70val space : ppstream 71 72val spaces : int -> ppstream 73 74(* ------------------------------------------------------------------------- *) 75(* Possible line breaks. *) 76(* ------------------------------------------------------------------------- *) 77 78datatype break = Break of {size : int, extraIndent : int} 79 80val mkBreak : int -> break 81 82val ppBreak : break pp 83 84val break : ppstream 85 86val breaks : int -> ppstream 87 88(* ------------------------------------------------------------------------- *) 89(* Forced line breaks. *) 90(* ------------------------------------------------------------------------- *) 91 92val newline : ppstream 93 94val newlines : int -> ppstream 95 96(* ------------------------------------------------------------------------- *) 97(* Pretty-printer combinators. *) 98(* ------------------------------------------------------------------------- *) 99 100val ppMap : ('a -> 'b) -> 'b pp -> 'a pp 101 102val ppBracket : string -> string -> 'a pp -> 'a pp 103 104val ppOp : string -> ppstream 105 106val ppOp2 : string -> 'a pp -> 'b pp -> ('a * 'b) pp 107 108val ppOp3 : string -> string -> 'a pp -> 'b pp -> 'c pp -> ('a * 'b * 'c) pp 109 110val ppOpList : string -> 'a pp -> 'a list pp 111 112val ppOpStream : string -> 'a pp -> 'a Stream.stream pp 113 114(* ------------------------------------------------------------------------- *) 115(* Pretty-printers for common types. *) 116(* ------------------------------------------------------------------------- *) 117 118val ppChar : char pp 119 120val ppString : string pp 121 122val ppEscapeString : {escape : char list} -> string pp 123 124val ppUnit : unit pp 125 126val ppBool : bool pp 127 128val ppInt : int pp 129 130val ppPrettyInt : int pp 131 132val ppReal : real pp 133 134val ppPercent : real pp 135 136val ppOrder : order pp 137 138val ppList : 'a pp -> 'a list pp 139 140val ppStream : 'a pp -> 'a Stream.stream pp 141 142val ppOption : 'a pp -> 'a option pp 143 144val ppPair : 'a pp -> 'b pp -> ('a * 'b) pp 145 146val ppTriple : 'a pp -> 'b pp -> 'c pp -> ('a * 'b * 'c) pp 147 148val ppException : exn pp 149 150(* ------------------------------------------------------------------------- *) 151(* Pretty-printing infix operators. *) 152(* ------------------------------------------------------------------------- *) 153 154type token = string 155 156datatype assoc = 157 LeftAssoc 158 | NonAssoc 159 | RightAssoc 160 161datatype infixes = 162 Infixes of 163 {token : token, 164 precedence : int, 165 assoc : assoc} list 166 167val tokensInfixes : infixes -> StringSet.set 168 169val layerInfixes : infixes -> {tokens : StringSet.set, assoc : assoc} list 170 171val ppInfixes : 172 infixes -> 173 ('a -> (token * 'a * 'a) option) -> ('a * token) pp -> 174 ('a * bool) pp -> ('a * bool) pp 175 176(* ------------------------------------------------------------------------- *) 177(* Pretty-printer rendering. *) 178(* ------------------------------------------------------------------------- *) 179 180val render : 181 {lineLength : int option} -> ppstream -> 182 {indent : int, line : string} Stream.stream 183 184val toStringWithLineLength : 185 {lineLength : int option} -> 'a pp -> 'a -> string 186 187val toStreamWithLineLength : 188 {lineLength : int option} -> 'a pp -> 'a -> string Stream.stream 189 190val toLine : 'a pp -> 'a -> string 191 192(* ------------------------------------------------------------------------- *) 193(* Pretty-printer rendering with a global line length. *) 194(* ------------------------------------------------------------------------- *) 195 196val lineLength : int ref 197 198val toString : 'a pp -> 'a -> string 199 200val toStream : 'a pp -> 'a -> string Stream.stream 201 202val trace : 'a pp -> string -> 'a -> unit 203 204end 205