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