Mercurial > urweb
comparison src/expl_print.sml @ 38:d16ef24de78b
Explify
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Thu, 19 Jun 2008 10:06:59 -0400 |
parents | |
children | 3c1ce1b4eb3d |
comparison
equal
deleted
inserted
replaced
37:367f058aba23 | 38:d16ef24de78b |
---|---|
1 (* Copyright (c) 2008, Adam Chlipala | |
2 * All rights reserved. | |
3 * | |
4 * Redistribution and use in source and binary forms, with or without | |
5 * modification, are permitted provided that the following conditions are met: | |
6 * | |
7 * - Redistributions of source code must retain the above copyright notice, | |
8 * this list of conditions and the following disclaimer. | |
9 * - Redistributions in binary form must reproduce the above copyright notice, | |
10 * this list of conditions and the following disclaimer in the documentation | |
11 * and/or other materials provided with the distribution. | |
12 * - The names of contributors may not be used to endorse or promote products | |
13 * derived from this software without specific prior written permission. | |
14 * | |
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
25 * POSSIBILITY OF SUCH DAMAGE. | |
26 *) | |
27 | |
28 (* Pretty-printing elaborated Laconic/Web *) | |
29 | |
30 structure ExplPrint :> EXPL_PRINT = struct | |
31 | |
32 open Print.PD | |
33 open Print | |
34 | |
35 open Expl | |
36 | |
37 structure E = ExplEnv | |
38 | |
39 val debug = ref false | |
40 | |
41 fun p_kind' par (k, _) = | |
42 case k of | |
43 KType => string "Type" | |
44 | KArrow (k1, k2) => parenIf par (box [p_kind' true k1, | |
45 space, | |
46 string "->", | |
47 space, | |
48 p_kind k2]) | |
49 | KName => string "Name" | |
50 | KRecord k => box [string "{", p_kind k, string "}"] | |
51 | |
52 and p_kind k = p_kind' false k | |
53 | |
54 fun p_con' par env (c, _) = | |
55 case c of | |
56 TFun (t1, t2) => parenIf par (box [p_con' true env t1, | |
57 space, | |
58 string "->", | |
59 space, | |
60 p_con env t2]) | |
61 | TCFun (x, k, c) => parenIf par (box [string x, | |
62 space, | |
63 string "::", | |
64 space, | |
65 p_kind k, | |
66 space, | |
67 string "->", | |
68 space, | |
69 p_con (E.pushCRel env x k) c]) | |
70 | TRecord (CRecord (_, xcs), _) => box [string "{", | |
71 p_list (fn (x, c) => | |
72 box [p_name env x, | |
73 space, | |
74 string ":", | |
75 space, | |
76 p_con env c]) xcs, | |
77 string "}"] | |
78 | TRecord c => box [string "$", | |
79 p_con' true env c] | |
80 | |
81 | CRel n => | |
82 if !debug then | |
83 string (#1 (E.lookupCRel env n) ^ "_" ^ Int.toString n) | |
84 else | |
85 string (#1 (E.lookupCRel env n)) | |
86 | CNamed n => | |
87 ((if !debug then | |
88 string (#1 (E.lookupCNamed env n) ^ "__" ^ Int.toString n) | |
89 else | |
90 string (#1 (E.lookupCNamed env n))) | |
91 handle E.UnboundNamed _ => string ("UNBOUND_NAMED" ^ Int.toString n)) | |
92 | CModProj (m1, ms, x) => | |
93 let | |
94 val (m1x, sgn) = E.lookupStrNamed env m1 | |
95 | |
96 val m1s = if !debug then | |
97 m1x ^ "__" ^ Int.toString m1 | |
98 else | |
99 m1x | |
100 in | |
101 p_list_sep (string ".") string (m1x :: ms @ [x]) | |
102 end | |
103 | |
104 | CApp (c1, c2) => parenIf par (box [p_con env c1, | |
105 space, | |
106 p_con' true env c2]) | |
107 | CAbs (x, k, c) => parenIf par (box [string "fn", | |
108 space, | |
109 string x, | |
110 space, | |
111 string "::", | |
112 space, | |
113 p_kind k, | |
114 space, | |
115 string "=>", | |
116 space, | |
117 p_con (E.pushCRel env x k) c]) | |
118 | |
119 | CName s => box [string "#", string s] | |
120 | |
121 | CRecord (k, xcs) => | |
122 if !debug then | |
123 parenIf par (box [string "[", | |
124 p_list (fn (x, c) => | |
125 box [p_con env x, | |
126 space, | |
127 string "=", | |
128 space, | |
129 p_con env c]) xcs, | |
130 string "]::", | |
131 p_kind k]) | |
132 else | |
133 parenIf par (box [string "[", | |
134 p_list (fn (x, c) => | |
135 box [p_con env x, | |
136 space, | |
137 string "=", | |
138 space, | |
139 p_con env c]) xcs, | |
140 string "]"]) | |
141 | CConcat (c1, c2) => parenIf par (box [p_con' true env c1, | |
142 space, | |
143 string "++", | |
144 space, | |
145 p_con env c2]) | |
146 | |
147 and p_con env = p_con' false env | |
148 | |
149 and p_name env (all as (c, _)) = | |
150 case c of | |
151 CName s => string s | |
152 | _ => p_con env all | |
153 | |
154 fun p_exp' par env (e, _) = | |
155 case e of | |
156 EPrim p => Prim.p_t p | |
157 | ERel n => | |
158 if !debug then | |
159 string (#1 (E.lookupERel env n) ^ "_" ^ Int.toString n) | |
160 else | |
161 string (#1 (E.lookupERel env n)) | |
162 | ENamed n => | |
163 if !debug then | |
164 string (#1 (E.lookupENamed env n) ^ "__" ^ Int.toString n) | |
165 else | |
166 string (#1 (E.lookupENamed env n)) | |
167 | EModProj (m1, ms, x) => | |
168 let | |
169 val (m1x, sgn) = E.lookupStrNamed env m1 | |
170 | |
171 val m1s = if !debug then | |
172 m1x ^ "__" ^ Int.toString m1 | |
173 else | |
174 m1x | |
175 in | |
176 p_list_sep (string ".") string (m1x :: ms @ [x]) | |
177 end | |
178 | |
179 | EApp (e1, e2) => parenIf par (box [p_exp env e1, | |
180 space, | |
181 p_exp' true env e2]) | |
182 | EAbs (x, t, _, e) => parenIf par (box [string "fn", | |
183 space, | |
184 string x, | |
185 space, | |
186 string ":", | |
187 space, | |
188 p_con env t, | |
189 space, | |
190 string "=>", | |
191 space, | |
192 p_exp (E.pushERel env x t) e]) | |
193 | ECApp (e, c) => parenIf par (box [p_exp env e, | |
194 space, | |
195 string "[", | |
196 p_con env c, | |
197 string "]"]) | |
198 | ECAbs (x, k, e) => parenIf par (box [string "fn", | |
199 space, | |
200 string x, | |
201 space, | |
202 string "::", | |
203 space, | |
204 p_kind k, | |
205 space, | |
206 string "=>", | |
207 space, | |
208 p_exp (E.pushCRel env x k) e]) | |
209 | |
210 | ERecord xes => box [string "{", | |
211 p_list (fn (x, e, _) => | |
212 box [p_name env x, | |
213 space, | |
214 string "=", | |
215 space, | |
216 p_exp env e]) xes, | |
217 string "}"] | |
218 | EField (e, c, {field, rest}) => | |
219 if !debug then | |
220 box [p_exp' true env e, | |
221 string ".", | |
222 p_con' true env c, | |
223 space, | |
224 string "[", | |
225 p_con env field, | |
226 space, | |
227 string " in ", | |
228 space, | |
229 p_con env rest, | |
230 string "]"] | |
231 else | |
232 box [p_exp' true env e, | |
233 string ".", | |
234 p_con' true env c] | |
235 | |
236 and p_exp env = p_exp' false env | |
237 | |
238 fun p_named x n = | |
239 if !debug then | |
240 box [string x, | |
241 string "__", | |
242 string (Int.toString n)] | |
243 else | |
244 string x | |
245 | |
246 fun p_sgn_item env (sgi, _) = | |
247 case sgi of | |
248 SgiConAbs (x, n, k) => box [string "con", | |
249 space, | |
250 p_named x n, | |
251 space, | |
252 string "::", | |
253 space, | |
254 p_kind k] | |
255 | SgiCon (x, n, k, c) => box [string "con", | |
256 space, | |
257 p_named x n, | |
258 space, | |
259 string "::", | |
260 space, | |
261 p_kind k, | |
262 space, | |
263 string "=", | |
264 space, | |
265 p_con env c] | |
266 | SgiVal (x, n, c) => box [string "val", | |
267 space, | |
268 p_named x n, | |
269 space, | |
270 string ":", | |
271 space, | |
272 p_con env c] | |
273 | SgiStr (x, n, sgn) => box [string "structure", | |
274 space, | |
275 p_named x n, | |
276 space, | |
277 string ":", | |
278 space, | |
279 p_sgn env sgn] | |
280 | |
281 and p_sgn env (sgn, _) = | |
282 case sgn of | |
283 SgnConst sgis => box [string "sig", | |
284 newline, | |
285 let | |
286 val (psgis, _) = ListUtil.foldlMap (fn (sgi, env) => | |
287 (p_sgn_item env sgi, | |
288 E.sgiBinds env sgi)) | |
289 env sgis | |
290 in | |
291 p_list_sep newline (fn x => x) psgis | |
292 end, | |
293 newline, | |
294 string "end"] | |
295 | SgnVar n => string (#1 (E.lookupSgnNamed env n)) | |
296 | |
297 fun p_decl env ((d, _) : decl) = | |
298 case d of | |
299 DCon (x, n, k, c) => box [string "con", | |
300 space, | |
301 p_named x n, | |
302 space, | |
303 string "::", | |
304 space, | |
305 p_kind k, | |
306 space, | |
307 string "=", | |
308 space, | |
309 p_con env c] | |
310 | DVal (x, n, t, e) => box [string "val", | |
311 space, | |
312 p_named x n, | |
313 space, | |
314 string ":", | |
315 space, | |
316 p_con env t, | |
317 space, | |
318 string "=", | |
319 space, | |
320 p_exp env e] | |
321 | |
322 | DSgn (x, n, sgn) => box [string "signature", | |
323 space, | |
324 p_named x n, | |
325 space, | |
326 string "=", | |
327 space, | |
328 p_sgn env sgn] | |
329 | DStr (x, n, sgn, str) => box [string "structure", | |
330 space, | |
331 p_named x n, | |
332 space, | |
333 string ":", | |
334 space, | |
335 p_sgn env sgn, | |
336 space, | |
337 string "=", | |
338 space, | |
339 p_str env str] | |
340 | |
341 and p_str env (str, _) = | |
342 case str of | |
343 StrConst ds => box [string "struct", | |
344 newline, | |
345 p_file env ds, | |
346 newline, | |
347 string "end"] | |
348 | StrVar n => string (#1 (E.lookupStrNamed env n)) | |
349 | StrProj (str, s) => box [p_str env str, | |
350 string ".", | |
351 string s] | |
352 | |
353 and p_file env file = | |
354 let | |
355 val (pds, _) = ListUtil.foldlMap (fn (d, env) => | |
356 (p_decl env d, | |
357 E.declBinds env d)) | |
358 env file | |
359 in | |
360 p_list_sep newline (fn x => x) pds | |
361 end | |
362 | |
363 end |