Mercurial > urweb
comparison src/rpcify.sml @ 607:0dd40b6bfdf3
Start of RPCification
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Sat, 14 Feb 2009 14:07:56 -0500 |
parents | |
children | 330a7de47914 |
comparison
equal
deleted
inserted
replaced
606:5145181b02fa | 607:0dd40b6bfdf3 |
---|---|
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 Rpcify :> RPCIFY = struct | |
29 | |
30 open Core | |
31 | |
32 structure U = CoreUtil | |
33 structure E = CoreEnv | |
34 | |
35 structure IS = IntBinarySet | |
36 structure IM = IntBinaryMap | |
37 | |
38 structure SS = BinarySetFn(struct | |
39 type ord_key = string | |
40 val compare = String.compare | |
41 end) | |
42 | |
43 val ssBasis = SS.addList (SS.empty, | |
44 ["requestHeader", | |
45 "query", | |
46 "dml", | |
47 "nextval"]) | |
48 | |
49 val csBasis = SS.addList (SS.empty, | |
50 ["source", | |
51 "get", | |
52 "set", | |
53 "alert"]) | |
54 | |
55 type state = { | |
56 exps : int IM.map, | |
57 decls : (string * int * con * exp * string) list | |
58 } | |
59 | |
60 fun frob file = | |
61 let | |
62 fun sideish (basis, ssids) = | |
63 U.Exp.exists {kind = fn _ => false, | |
64 con = fn _ => false, | |
65 exp = fn ENamed n => IS.member (ssids, n) | |
66 | EFfi ("Basis", x) => SS.member (basis, x) | |
67 | EFfiApp ("Basis", x, _) => SS.member (basis, x) | |
68 | _ => false} | |
69 | |
70 fun whichIds basis = | |
71 let | |
72 fun decl ((d, _), ssids) = | |
73 let | |
74 val impure = sideish (basis, ssids) | |
75 in | |
76 case d of | |
77 DVal (_, n, _, e, _) => if impure e then | |
78 IS.add (ssids, n) | |
79 else | |
80 ssids | |
81 | DValRec xes => if List.exists (fn (_, _, _, e, _) => impure e) xes then | |
82 foldl (fn ((_, n, _, _, _), ssids) => IS.add (ssids, n)) | |
83 ssids xes | |
84 else | |
85 ssids | |
86 | _ => ssids | |
87 end | |
88 in | |
89 foldl decl IS.empty file | |
90 end | |
91 | |
92 val ssids = whichIds ssBasis | |
93 val csids = whichIds csBasis | |
94 | |
95 val serverSide = sideish (ssBasis, ssids) | |
96 val clientSide = sideish (csBasis, csids) | |
97 | |
98 fun exp (e, st) = | |
99 case e of | |
100 EApp ( | |
101 (EApp | |
102 ((EApp ((ECApp ((ECApp ((ECApp ((EFfi ("Basis", "bind"), loc), _), _), t1), _), t2), _), | |
103 (EFfi ("Basis", "transaction_monad"), _)), _), | |
104 trans1), _), | |
105 trans2) => | |
106 (case (serverSide trans1, clientSide trans1, serverSide trans2, clientSide trans2) of | |
107 (true, false, false, _) => | |
108 let | |
109 fun getApp (e, args) = | |
110 case #1 e of | |
111 ENamed n => (n, args) | |
112 | EApp (e1, e2) => getApp (e1, e2 :: args) | |
113 | _ => (ErrorMsg.errorAt loc "Mixed client/server code doesn't use a named function for server part"; | |
114 (0, [])) | |
115 | |
116 val (n, args) = getApp (trans1, []) | |
117 in | |
118 (EServerCall (n, args, trans2), st) | |
119 end | |
120 | _ => (e, st)) | |
121 | _ => (e, st) | |
122 | |
123 fun decl (d, st : state) = | |
124 let | |
125 val (d, st) = U.Decl.foldMap {kind = fn x => x, | |
126 con = fn x => x, | |
127 exp = exp, | |
128 decl = fn x => x} | |
129 st d | |
130 in | |
131 (case #decls st of | |
132 [] => [d] | |
133 | ds => | |
134 case d of | |
135 (DValRec vis, loc) => [(DValRec (ds @ vis), loc)] | |
136 | (_, loc) => [(DValRec ds, loc), d], | |
137 {decls = [], | |
138 exps = #exps st}) | |
139 end | |
140 | |
141 val (file, _) = ListUtil.foldlMapConcat decl | |
142 {decls = [], | |
143 exps = IM.empty} | |
144 file | |
145 in | |
146 file | |
147 end | |
148 | |
149 end |