Mercurial > urweb
comparison src/flat_print.sml @ 26:4ab19c19665f
Closure conversion
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Tue, 10 Jun 2008 15:56:33 -0400 |
parents | |
children | 537db4ee89f4 |
comparison
equal
deleted
inserted
replaced
25:0a762c73824d | 26:4ab19c19665f |
---|---|
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 flat-code Laconic/Web *) | |
29 | |
30 structure FlatPrint :> FLAT_PRINT = struct | |
31 | |
32 open Print.PD | |
33 open Print | |
34 | |
35 open Flat | |
36 | |
37 structure E = FlatEnv | |
38 | |
39 val debug = ref false | |
40 | |
41 val dummyTyp = (TNamed 0, ErrorMsg.dummySpan) | |
42 | |
43 fun p_typ' par env (t, _) = | |
44 case t of | |
45 TFun (t1, t2) => parenIf par (box [p_typ' true env t1, | |
46 space, | |
47 string "->", | |
48 space, | |
49 p_typ env t2]) | |
50 | TCode (t1, t2) => parenIf par (box [p_typ' true env t1, | |
51 space, | |
52 string "-->", | |
53 space, | |
54 p_typ env t2]) | |
55 | TRecord xcs => box [string "{", | |
56 p_list (fn (x, t) => | |
57 box [string x, | |
58 space, | |
59 string ":", | |
60 space, | |
61 p_typ env t]) xcs, | |
62 string "}"] | |
63 | TNamed n => | |
64 if !debug then | |
65 string (#1 (E.lookupTNamed env n) ^ "__" ^ Int.toString n) | |
66 else | |
67 string (#1 (E.lookupTNamed env n)) | |
68 | |
69 and p_typ env = p_typ' false env | |
70 | |
71 fun p_exp' par env (e, _) = | |
72 case e of | |
73 EPrim p => Prim.p_t p | |
74 | ERel n => | |
75 ((if !debug then | |
76 string (#1 (E.lookupERel env n) ^ "_" ^ Int.toString n) | |
77 else | |
78 string (#1 (E.lookupERel env n))) | |
79 handle E.UnboundRel _ => string ("UNBOUND" ^ Int.toString n)) | |
80 | ENamed n => | |
81 if !debug then | |
82 string (#1 (E.lookupENamed env n) ^ "__" ^ Int.toString n) | |
83 else | |
84 string (#1 (E.lookupENamed env n)) | |
85 | ECode n => string ("code$" ^ Int.toString n) | |
86 | EApp (e1, e2) => parenIf par (box [p_exp env e1, | |
87 space, | |
88 p_exp' true env e2]) | |
89 | |
90 | ERecord xes => box [string "{", | |
91 p_list (fn (x, e) => | |
92 box [string x, | |
93 space, | |
94 string "=", | |
95 space, | |
96 p_exp env e]) xes, | |
97 string "}"] | |
98 | EField (e, x) => | |
99 box [p_exp' true env e, | |
100 string ".", | |
101 string x] | |
102 | |
103 | ELet (xes, e) => | |
104 let | |
105 val (env, pps) = foldl (fn ((x, e), (env, pps)) => | |
106 (E.pushERel env x dummyTyp, | |
107 List.revAppend ([space, | |
108 string "val", | |
109 space, | |
110 string x, | |
111 space, | |
112 string "=", | |
113 space, | |
114 p_exp env e], | |
115 pps))) | |
116 (env, []) xes | |
117 in | |
118 box [string "let", | |
119 space, | |
120 box (rev pps), | |
121 space, | |
122 string "in", | |
123 space, | |
124 p_exp env e, | |
125 space, | |
126 string "end"] | |
127 end | |
128 | |
129 and p_exp env = p_exp' false env | |
130 | |
131 fun p_decl env ((d, _) : decl) = | |
132 case d of | |
133 DVal (x, n, t, e) => | |
134 let | |
135 val xp = if !debug then | |
136 box [string x, | |
137 string "__", | |
138 string (Int.toString n)] | |
139 else | |
140 string x | |
141 in | |
142 box [string "val", | |
143 space, | |
144 xp, | |
145 space, | |
146 string ":", | |
147 space, | |
148 p_typ env t, | |
149 space, | |
150 string "=", | |
151 space, | |
152 p_exp env e] | |
153 | |
154 end | |
155 | DFun (n, x, dom, ran, e) => | |
156 let | |
157 val xp = if !debug then | |
158 box [string x, | |
159 string "__", | |
160 string (Int.toString n)] | |
161 else | |
162 string x | |
163 in | |
164 box [string "fun", | |
165 space, | |
166 string "code$", | |
167 string (Int.toString n), | |
168 space, | |
169 string "(", | |
170 xp, | |
171 space, | |
172 string ":", | |
173 space, | |
174 p_typ env dom, | |
175 string ")", | |
176 space, | |
177 string ":", | |
178 space, | |
179 p_typ env ran, | |
180 space, | |
181 string "=", | |
182 space, | |
183 p_exp (E.pushERel env x dom) e] | |
184 | |
185 end | |
186 | |
187 fun p_file env file = | |
188 let | |
189 val (_, pds) = ListUtil.mapfoldl (fn (d, env) => | |
190 (E.declBinds env d, | |
191 p_decl env d)) | |
192 env file | |
193 in | |
194 p_list_sep newline (fn x => x) pds | |
195 end | |
196 | |
197 end |