Mercurial > urweb
comparison src/marshalcheck.sml @ 680:54ec237a3028
Marshalcheck
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Sat, 28 Mar 2009 11:13:36 -0400 |
parents | |
children | 09df0c85f306 |
comparison
equal
deleted
inserted
replaced
679:44f23712020d | 680:54ec237a3028 |
---|---|
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 MarshalCheck :> MARSHAL_CHECK = struct | |
29 | |
30 open Core | |
31 | |
32 structure U = CoreUtil | |
33 structure E = ErrorMsg | |
34 | |
35 structure PK = struct | |
36 open Order | |
37 type ord_key = string * string | |
38 fun compare ((m1, x1), (m2, x2)) = | |
39 join (String.compare (m1, m2), | |
40 fn () => String.compare (x1, x2)) | |
41 end | |
42 | |
43 structure PS = BinarySetFn(PK) | |
44 structure PS = struct | |
45 open PS | |
46 fun toString' (m, x) = m ^ "." ^ x | |
47 fun toString set = | |
48 case PS.listItems set of | |
49 [] => "{}" | |
50 | [x] => toString' x | |
51 | x :: xs => List.foldl (fn (x, s) => s ^ ", " ^ toString' x) (toString' x) xs | |
52 end | |
53 | |
54 structure IM = IntBinaryMap | |
55 | |
56 val clientToServer = [("Basis", "int"), | |
57 ("Basis", "float"), | |
58 ("Basis", "string"), | |
59 ("Basis", "time"), | |
60 ("Basis", "unit"), | |
61 ("Basis", "option")] | |
62 | |
63 val clientToServer = PS.addList (PS.empty, clientToServer) | |
64 | |
65 fun check file = | |
66 let | |
67 fun kind (_, st) = st | |
68 | |
69 fun con cmap (c, st) = | |
70 case c of | |
71 CFfi mx => | |
72 if PS.member (clientToServer, mx) then | |
73 st | |
74 else | |
75 PS.add (st, mx) | |
76 | CNamed n => | |
77 (case IM.find (cmap, n) of | |
78 NONE => st | |
79 | SOME st' => PS.union (st, st')) | |
80 | _ => st | |
81 | |
82 fun sins cmap = U.Con.fold {kind = kind, con = con cmap} PS.empty | |
83 in | |
84 ignore (foldl (fn ((d, _), (cmap, emap)) => | |
85 case d of | |
86 DCon (_, n, _, c) => (IM.insert (cmap, n, sins cmap c), emap) | |
87 | DDatatype (_, n, _, xncs) => | |
88 (IM.insert (cmap, n, foldl (fn ((_, _, co), s) => | |
89 case co of | |
90 NONE => s | |
91 | SOME c => PS.union (s, sins cmap c)) | |
92 PS.empty xncs), | |
93 emap) | |
94 | |
95 | DVal (_, n, t, _, tag) => (cmap, IM.insert (emap, n, (t, tag))) | |
96 | DValRec vis => (cmap, | |
97 foldl (fn ((_, n, t, _, tag), emap) => IM.insert (emap, n, (t, tag))) | |
98 emap vis) | |
99 | |
100 | DExport (_, n) => | |
101 (case IM.find (emap, n) of | |
102 NONE => raise Fail "MarshalCheck: Unknown export" | |
103 | SOME (t, tag) => | |
104 let | |
105 fun makeS (t, _) = | |
106 case t of | |
107 TFun (dom, ran) => PS.union (sins cmap dom, makeS ran) | |
108 | _ => PS.empty | |
109 val s = makeS t | |
110 in | |
111 if PS.isEmpty s then | |
112 () | |
113 else | |
114 E.error ("Input to exported function '" | |
115 ^ tag ^ "' involves one or more disallowed types: " | |
116 ^ PS.toString s); | |
117 (cmap, emap) | |
118 end) | |
119 | |
120 | DCookie (_, _, t, tag) => | |
121 let | |
122 val s = sins cmap t | |
123 in | |
124 if PS.isEmpty s then | |
125 () | |
126 else | |
127 E.error ("Cookie '" ^ tag ^ "' includes one or more disallowed types: " | |
128 ^ PS.toString s); | |
129 (cmap, emap) | |
130 end | |
131 | |
132 | _ => (cmap, emap)) | |
133 (IM.empty, IM.empty) file) | |
134 end | |
135 | |
136 end |