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