adamc@3
|
1 (* Copyright (c) 2008, Adam Chlipala
|
adamc@3
|
2 * All rights reserved.
|
adamc@3
|
3 *
|
adamc@3
|
4 * Redistribution and use in source and binary forms, with or without
|
adamc@3
|
5 * modification, are permitted provided that the following conditions are met:
|
adamc@3
|
6 *
|
adamc@3
|
7 * - Redistributions of source code must retain the above copyright notice,
|
adamc@3
|
8 * this list of conditions and the following disclaimer.
|
adamc@3
|
9 * - Redistributions in binary form must reproduce the above copyright notice,
|
adamc@3
|
10 * this list of conditions and the following disclaimer in the documentation
|
adamc@3
|
11 * and/or other materials provided with the distribution.
|
adamc@3
|
12 * - The names of contributors may not be used to endorse or promote products
|
adamc@3
|
13 * derived from this software without specific prior written permission.
|
adamc@3
|
14 *
|
adamc@3
|
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
adamc@3
|
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
adamc@3
|
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
adamc@3
|
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
adamc@3
|
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
adamc@3
|
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
adamc@3
|
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
adamc@3
|
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
adamc@3
|
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
adamc@3
|
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
adamc@3
|
25 * POSSIBILITY OF SUCH DAMAGE.
|
adamc@3
|
26 *)
|
adamc@3
|
27
|
adamc@3
|
28 (* Pretty-printing elaborated Laconic/Web *)
|
adamc@3
|
29
|
adamc@3
|
30 structure ElabPrint :> ELAB_PRINT = struct
|
adamc@3
|
31
|
adamc@3
|
32 open Print.PD
|
adamc@3
|
33 open Print
|
adamc@3
|
34
|
adamc@3
|
35 open Elab
|
adamc@3
|
36
|
adamc@3
|
37 structure E = ElabEnv
|
adamc@3
|
38
|
adamc@3
|
39 fun p_kind' par (k, _) =
|
adamc@3
|
40 case k of
|
adamc@3
|
41 KType => string "Type"
|
adamc@3
|
42 | KArrow (k1, k2) => parenIf par (box [p_kind' true k1,
|
adamc@3
|
43 space,
|
adamc@3
|
44 string "->",
|
adamc@3
|
45 space,
|
adamc@3
|
46 p_kind k2])
|
adamc@3
|
47 | KName => string "Name"
|
adamc@3
|
48 | KRecord k => box [string "{", p_kind k, string "}"]
|
adamc@3
|
49
|
adamc@3
|
50 | KError => string "<ERROR>"
|
adamc@3
|
51 | KUnif (_, ref (SOME k)) => p_kind' par k
|
adamc@3
|
52 | KUnif (s, _) => string ("<UNIF:" ^ s ^ ">")
|
adamc@3
|
53
|
adamc@3
|
54 and p_kind k = p_kind' false k
|
adamc@3
|
55
|
adamc@3
|
56 fun p_explicitness e =
|
adamc@3
|
57 case e of
|
adamc@3
|
58 Explicit => string "::"
|
adamc@3
|
59 | Implicit => string ":::"
|
adamc@3
|
60
|
adamc@3
|
61 fun p_con' par env (c, _) =
|
adamc@3
|
62 case c of
|
adamc@3
|
63 TFun (t1, t2) => parenIf par (box [p_con' true env t1,
|
adamc@3
|
64 space,
|
adamc@3
|
65 string "->",
|
adamc@3
|
66 space,
|
adamc@3
|
67 p_con env t2])
|
adamc@3
|
68 | TCFun (e, x, k, c) => parenIf par (box [string x,
|
adamc@3
|
69 space,
|
adamc@3
|
70 p_explicitness e,
|
adamc@3
|
71 space,
|
adamc@3
|
72 p_kind k,
|
adamc@3
|
73 space,
|
adamc@3
|
74 string "->",
|
adamc@3
|
75 space,
|
adamc@3
|
76 p_con (E.pushCRel env x k) c])
|
adamc@3
|
77 | TRecord (CRecord (_, xcs), _) => box [string "{",
|
adamc@3
|
78 p_list (fn (x, c) =>
|
adamc@3
|
79 box [p_con env x,
|
adamc@3
|
80 space,
|
adamc@3
|
81 string ":",
|
adamc@3
|
82 space,
|
adamc@3
|
83 p_con env c]) xcs,
|
adamc@3
|
84 string "}"]
|
adamc@3
|
85 | TRecord c => box [string "$",
|
adamc@3
|
86 p_con' true env c]
|
adamc@3
|
87
|
adamc@3
|
88 | CRel n => string (#1 (E.lookupCRel env n) ^ "_" ^ Int.toString n)
|
adamc@3
|
89 | CNamed n => string (#1 (E.lookupCNamed env n) ^ "__" ^ Int.toString n)
|
adamc@3
|
90
|
adamc@3
|
91 | CApp (c1, c2) => parenIf par (box [p_con env c1,
|
adamc@3
|
92 space,
|
adamc@3
|
93 p_con' true env c2])
|
adamc@8
|
94 | CAbs (x, k, c) => parenIf par (box [string "fn",
|
adamc@8
|
95 space,
|
adamc@8
|
96 string x,
|
adamc@8
|
97 space,
|
adamc@8
|
98 string "::",
|
adamc@8
|
99 space,
|
adamc@8
|
100 p_kind k,
|
adamc@8
|
101 space,
|
adamc@8
|
102 string "=>",
|
adamc@8
|
103 space,
|
adamc@8
|
104 p_con (E.pushCRel env x k) c])
|
adamc@3
|
105
|
adamc@3
|
106 | CName s => box [string "#", string s]
|
adamc@3
|
107
|
adamc@3
|
108 | CRecord (k, xcs) => parenIf par (box [string "[",
|
adamc@3
|
109 p_list (fn (x, c) =>
|
adamc@3
|
110 box [p_con env x,
|
adamc@3
|
111 space,
|
adamc@3
|
112 string "=",
|
adamc@3
|
113 space,
|
adamc@3
|
114 p_con env c]) xcs,
|
adamc@3
|
115 string "]::",
|
adamc@3
|
116 p_kind k])
|
adamc@3
|
117 | CConcat (c1, c2) => parenIf par (box [p_con' true env c1,
|
adamc@3
|
118 space,
|
adamc@3
|
119 string "++",
|
adamc@3
|
120 space,
|
adamc@3
|
121 p_con env c2])
|
adamc@3
|
122
|
adamc@3
|
123 | CError => string "<ERROR>"
|
adamc@6
|
124 | CUnif (_, _, ref (SOME c)) => p_con' par env c
|
adamc@6
|
125 | CUnif (k, s, _) => box [string ("<UNIF:" ^ s ^ "::"),
|
adamc@6
|
126 p_kind k,
|
adamc@6
|
127 string ">"]
|
adamc@3
|
128
|
adamc@3
|
129 and p_con env = p_con' false env
|
adamc@3
|
130
|
adamc@3
|
131 fun p_decl env ((d, _) : decl) =
|
adamc@3
|
132 case d of
|
adamc@5
|
133 DCon (x, n, k, c) => box [string "con",
|
adamc@5
|
134 space,
|
adamc@5
|
135 string x,
|
adamc@5
|
136 string "__",
|
adamc@5
|
137 string (Int.toString n),
|
adamc@5
|
138 space,
|
adamc@5
|
139 string "::",
|
adamc@5
|
140 space,
|
adamc@5
|
141 p_kind k,
|
adamc@5
|
142 space,
|
adamc@5
|
143 string "=",
|
adamc@5
|
144 space,
|
adamc@5
|
145 p_con env c]
|
adamc@3
|
146
|
adamc@3
|
147 fun p_file env file =
|
adamc@3
|
148 let
|
adamc@5
|
149 val (_, pds) = ListUtil.mapfoldl (fn (d, env) =>
|
adamc@5
|
150 (ElabUtil.declBinds env d,
|
adamc@5
|
151 p_decl env d))
|
adamc@5
|
152 env file
|
adamc@3
|
153 in
|
adamc@3
|
154 p_list_sep newline (fn x => x) pds
|
adamc@3
|
155 end
|
adamc@3
|
156
|
adamc@3
|
157 end
|