Mercurial > urweb
comparison src/checknest.sml @ 879:b2a175a0f2ef
Demo working with MySQL
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Thu, 16 Jul 2009 18:10:29 -0400 |
parents | |
children | 217eb87dde31 |
comparison
equal
deleted
inserted
replaced
878:a8952047e1d3 | 879:b2a175a0f2ef |
---|---|
1 (* Copyright (c) 2009, 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 structure Checknest :> CHECKNEST = struct | |
29 | |
30 open Cjr | |
31 | |
32 structure IS = IntBinarySet | |
33 structure IM = IntBinaryMap | |
34 | |
35 fun expUses globals = | |
36 let | |
37 fun eu (e, _) = | |
38 case e of | |
39 EPrim _ => IS.empty | |
40 | ERel _ => IS.empty | |
41 | ENamed n => Option.getOpt (IM.find (globals, n), IS.empty) | |
42 | ECon (_, _, NONE) => IS.empty | |
43 | ECon (_, _, SOME e) => eu e | |
44 | ENone _ => IS.empty | |
45 | ESome (_, e) => eu e | |
46 | EFfi _ => IS.empty | |
47 | EFfiApp (_, _, es) => foldl IS.union IS.empty (map eu es) | |
48 | EApp (e, es) => foldl IS.union (eu e) (map eu es) | |
49 | |
50 | EUnop (_, e) => eu e | |
51 | EBinop (_, e1, e2) => IS.union (eu e1, eu e2) | |
52 | |
53 | ERecord (_, xes) => foldl (fn ((_, e), s) => IS.union (eu e, s)) IS.empty xes | |
54 | EField (e, _) => eu e | |
55 | |
56 | ECase (e, pes, _) => foldl (fn ((_, e), s) => IS.union (eu e, s)) (eu e) pes | |
57 | |
58 | EError (e, _) => eu e | |
59 | EReturnBlob {blob, mimeType, ...} => IS.union (eu blob, eu mimeType) | |
60 | |
61 | EWrite e => eu e | |
62 | ESeq (e1, e2) => IS.union (eu e1, eu e2) | |
63 | ELet (_, _, e1, e2) => IS.union (eu e1, eu e2) | |
64 | |
65 | EQuery {query, body, initial, prepared, ...} => | |
66 let | |
67 val s = IS.union (eu query, IS.union (eu body, eu initial)) | |
68 in | |
69 case prepared of | |
70 SOME {id, ...} => IS.add (s, id) | |
71 | _ => s | |
72 end | |
73 | EDml {dml, prepared, ...} => | |
74 let | |
75 val s = eu dml | |
76 in | |
77 case prepared of | |
78 SOME {id, ...} => IS.add (s, id) | |
79 | _ => s | |
80 end | |
81 | ENextval {seq, prepared, ...} => | |
82 let | |
83 val s = eu seq | |
84 in | |
85 case prepared of | |
86 SOME {id, ...} => IS.add (s, id) | |
87 | _ => s | |
88 end | |
89 | |
90 | EUnurlify (e, _) => eu e | |
91 in | |
92 eu | |
93 end | |
94 | |
95 fun annotateExp globals = | |
96 let | |
97 fun ae (e as (_, loc)) = | |
98 case #1 e of | |
99 EPrim _ => e | |
100 | ERel _ => e | |
101 | ENamed n => e | |
102 | ECon (_, _, NONE) => e | |
103 | ECon (dk, pc, SOME e) => (ECon (dk, pc, SOME (ae e)), loc) | |
104 | ENone _ => e | |
105 | ESome (t, e) => (ESome (t, ae e), loc) | |
106 | EFfi _ => e | |
107 | EFfiApp (m, f, es) => (EFfiApp (m, f, map ae es), loc) | |
108 | EApp (e, es) => (EApp (ae e, map ae es), loc) | |
109 | |
110 | EUnop (uo, e) => (EUnop (uo, ae e), loc) | |
111 | EBinop (bo, e1, e2) => (EBinop (bo, ae e1, ae e2), loc) | |
112 | |
113 | ERecord (n, xes) => (ERecord (n, map (fn (x, e) => (x, ae e)) xes), loc) | |
114 | EField (e, f) => (EField (ae e, f), loc) | |
115 | |
116 | ECase (e, pes, ts) => (ECase (ae e, map (fn (p, e) => (p, ae e)) pes, ts), loc) | |
117 | |
118 | EError (e, t) => (EError (ae e, t), loc) | |
119 | EReturnBlob {blob, mimeType, t} => (EReturnBlob {blob = ae blob, mimeType = ae mimeType, t = t}, loc) | |
120 | |
121 | EWrite e => (EWrite (ae e), loc) | |
122 | ESeq (e1, e2) => (ESeq (ae e1, ae e2), loc) | |
123 | ELet (x, t, e1, e2) => (ELet (x, t, ae e1, ae e2), loc) | |
124 | |
125 | EQuery {exps, tables, rnum, state, query, body, initial, prepared} => | |
126 (EQuery {exps = exps, | |
127 tables = tables, | |
128 rnum = rnum, | |
129 state = state, | |
130 query = ae query, | |
131 body = ae body, | |
132 initial = ae initial, | |
133 prepared = case prepared of | |
134 NONE => NONE | |
135 | SOME {id, query, ...} => SOME {id = id, query = query, | |
136 nested = IS.member (expUses globals body, id)}}, | |
137 loc) | |
138 | EDml {dml, prepared} => | |
139 (EDml {dml = ae dml, | |
140 prepared = prepared}, loc) | |
141 | |
142 | ENextval {seq, prepared} => | |
143 (ENextval {seq = ae seq, | |
144 prepared = prepared}, loc) | |
145 | |
146 | EUnurlify (e, t) => (EUnurlify (ae e, t), loc) | |
147 in | |
148 ae | |
149 end | |
150 | |
151 fun annotate (ds, syms) = | |
152 let | |
153 val globals = | |
154 foldl (fn ((d, _), globals) => | |
155 case d of | |
156 DVal (_, n, _, e) => IM.insert (globals, n, expUses globals e) | |
157 | DFun (_, n, _, _, e) => IM.insert (globals, n, expUses globals e) | |
158 | DFunRec fs => | |
159 let | |
160 val s = foldl (fn ((_, _, _, _, e), s) => IS.union (expUses globals e, s)) IS.empty fs | |
161 in | |
162 foldl (fn ((_, n, _, _, _), globals) => IM.insert (globals, n, s)) globals fs | |
163 end | |
164 | _ => globals) IM.empty ds | |
165 | |
166 val ds = | |
167 map (fn d as (_, loc) => | |
168 case #1 d of | |
169 DVal (x, n, t, e) => (DVal (x, n, t, annotateExp globals e), loc) | |
170 | DFun (x, n, ts, t, e) => (DFun (x, n, ts, t, annotateExp globals e), loc) | |
171 | DFunRec fs => (DFunRec | |
172 (map (fn (x, n, ts, t, e) => (x, n, ts, t, annotateExp globals e)) fs), loc) | |
173 | _ => d) ds | |
174 in | |
175 (ds, syms) | |
176 end | |
177 | |
178 end |