annotate src/corify.sml @ 45:3c1ce1b4eb3d

Explifying functors
author Adam Chlipala <adamc@hcoop.net>
date Thu, 19 Jun 2008 17:11:24 -0400
parents 02f42e9a1825
children 44a1bc863f0f
rev   line source
adamc@16 1 (* Copyright (c) 2008, Adam Chlipala
adamc@16 2 * All rights reserved.
adamc@16 3 *
adamc@16 4 * Redistribution and use in source and binary forms, with or without
adamc@16 5 * modification, are permitted provided that the following conditions are met:
adamc@16 6 *
adamc@16 7 * - Redistributions of source code must retain the above copyright notice,
adamc@16 8 * this list of conditions and the following disclaimer.
adamc@16 9 * - Redistributions in binary form must reproduce the above copyright notice,
adamc@16 10 * this list of conditions and the following disclaimer in the documentation
adamc@16 11 * and/or other materials provided with the distribution.
adamc@16 12 * - The names of contributors may not be used to endorse or promote products
adamc@16 13 * derived from this software without specific prior written permission.
adamc@16 14 *
adamc@16 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
adamc@16 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
adamc@16 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
adamc@16 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
adamc@16 19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
adamc@16 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
adamc@16 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
adamc@16 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
adamc@16 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
adamc@16 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
adamc@16 25 * POSSIBILITY OF SUCH DAMAGE.
adamc@16 26 *)
adamc@16 27
adamc@16 28 structure Corify :> CORIFY = struct
adamc@16 29
adamc@16 30 structure EM = ErrorMsg
adamc@39 31 structure L = Expl
adamc@16 32 structure L' = Core
adamc@16 33
adamc@39 34 structure IM = IntBinaryMap
adamc@39 35 structure SM = BinaryMapFn(struct
adamc@39 36 type ord_key = string
adamc@39 37 val compare = String.compare
adamc@39 38 end)
adamc@39 39
adamc@39 40 local
adamc@39 41 val count = ref 0
adamc@39 42 in
adamc@39 43
adamc@39 44 fun reset v = count := v
adamc@39 45
adamc@39 46 fun alloc () =
adamc@39 47 let
adamc@39 48 val r = !count
adamc@39 49 in
adamc@39 50 count := r + 1;
adamc@39 51 r
adamc@39 52 end
adamc@39 53
adamc@39 54 end
adamc@39 55
adamc@39 56 structure St : sig
adamc@39 57 type t
adamc@39 58
adamc@39 59 val empty : t
adamc@39 60
adamc@39 61 val enter : t -> t
adamc@39 62 val leave : t -> {outer : t, inner : t}
adamc@39 63
adamc@39 64 val bindCore : t -> string -> int -> t * int
adamc@39 65 val lookupCoreById : t -> int -> int option
adamc@39 66 val lookupCoreByName : t -> string -> int
adamc@39 67
adamc@39 68 val bindStr : t -> string -> int -> t -> t
adamc@39 69 val lookupStrById : t -> int -> t
adamc@39 70 val lookupStrByName : string * t -> t
adamc@39 71 end = struct
adamc@39 72
adamc@39 73 datatype flattening = F of {
adamc@39 74 core : int SM.map,
adamc@39 75 strs : flattening SM.map
adamc@39 76 }
adamc@39 77
adamc@39 78 type t = {
adamc@39 79 core : int IM.map,
adamc@39 80 strs : flattening IM.map,
adamc@39 81 current : flattening,
adamc@39 82 nested : flattening list
adamc@39 83 }
adamc@39 84
adamc@39 85 val empty = {
adamc@39 86 core = IM.empty,
adamc@39 87 strs = IM.empty,
adamc@39 88 current = F { core = SM.empty, strs = SM.empty },
adamc@39 89 nested = []
adamc@39 90 }
adamc@39 91
adamc@39 92 fun bindCore {core, strs, current, nested} s n =
adamc@39 93 let
adamc@39 94 val n' = alloc ()
adamc@39 95
adamc@39 96 val current =
adamc@39 97 let
adamc@39 98 val F {core, strs} = current
adamc@39 99 in
adamc@39 100 F {core = SM.insert (core, s, n'),
adamc@39 101 strs = strs}
adamc@39 102 end
adamc@39 103 in
adamc@39 104 ({core = IM.insert (core, n, n'),
adamc@39 105 strs = strs,
adamc@39 106 current = current,
adamc@39 107 nested = nested},
adamc@39 108 n')
adamc@39 109 end
adamc@39 110
adamc@39 111 fun lookupCoreById ({core, ...} : t) n = IM.find (core, n)
adamc@39 112
adamc@39 113 fun lookupCoreByName ({current = F {core, ...}, ...} : t) x =
adamc@39 114 case SM.find (core, x) of
adamc@39 115 NONE => raise Fail "Corify.St.lookupCoreByName"
adamc@39 116 | SOME n => n
adamc@39 117
adamc@39 118 fun enter {core, strs, current, nested} =
adamc@39 119 {core = core,
adamc@39 120 strs = strs,
adamc@39 121 current = F {core = SM.empty,
adamc@39 122 strs = SM.empty},
adamc@39 123 nested = current :: nested}
adamc@39 124
adamc@39 125 fun dummy f = {core = IM.empty,
adamc@39 126 strs = IM.empty,
adamc@39 127 current = f,
adamc@39 128 nested = []}
adamc@39 129
adamc@39 130 fun leave {core, strs, current, nested = m1 :: rest} =
adamc@39 131 {outer = {core = core,
adamc@39 132 strs = strs,
adamc@39 133 current = m1,
adamc@39 134 nested = rest},
adamc@39 135 inner = dummy current}
adamc@39 136 | leave _ = raise Fail "Corify.St.leave"
adamc@39 137
adamc@39 138 fun bindStr ({core, strs, current = F {core = mcore, strs = mstrs}, nested} : t) x n ({current = f, ...} : t) =
adamc@39 139 {core = core,
adamc@39 140 strs = IM.insert (strs, n, f),
adamc@39 141 current = F {core = mcore,
adamc@39 142 strs = SM.insert (mstrs, x, f)},
adamc@39 143 nested = nested}
adamc@39 144
adamc@39 145 fun lookupStrById ({strs, ...} : t) n =
adamc@39 146 case IM.find (strs, n) of
adamc@39 147 NONE => raise Fail "Corify.St.lookupStr"
adamc@39 148 | SOME f => dummy f
adamc@39 149
adamc@39 150 fun lookupStrByName (m, {current = F {strs, ...}, ...} : t) =
adamc@39 151 case SM.find (strs, m) of
adamc@39 152 NONE => raise Fail "Corify.St.lookupStrByName"
adamc@39 153 | SOME f => dummy f
adamc@39 154
adamc@39 155 end
adamc@39 156
adamc@39 157
adamc@16 158 fun corifyKind (k, loc) =
adamc@16 159 case k of
adamc@16 160 L.KType => (L'.KType, loc)
adamc@16 161 | L.KArrow (k1, k2) => (L'.KArrow (corifyKind k1, corifyKind k2), loc)
adamc@16 162 | L.KName => (L'.KName, loc)
adamc@16 163 | L.KRecord k => (L'.KRecord (corifyKind k), loc)
adamc@16 164
adamc@39 165 fun corifyCon st (c, loc) =
adamc@16 166 case c of
adamc@39 167 L.TFun (t1, t2) => (L'.TFun (corifyCon st t1, corifyCon st t2), loc)
adamc@39 168 | L.TCFun (x, k, t) => (L'.TCFun (x, corifyKind k, corifyCon st t), loc)
adamc@39 169 | L.TRecord c => (L'.TRecord (corifyCon st c), loc)
adamc@16 170
adamc@16 171 | L.CRel n => (L'.CRel n, loc)
adamc@39 172 | L.CNamed n =>
adamc@39 173 (case St.lookupCoreById st n of
adamc@39 174 NONE => (L'.CNamed n, loc)
adamc@39 175 | SOME n => (L'.CNamed n, loc))
adamc@39 176 | L.CModProj (m, ms, x) =>
adamc@39 177 let
adamc@39 178 val st = St.lookupStrById st m
adamc@39 179 val st = foldl St.lookupStrByName st ms
adamc@39 180 val n = St.lookupCoreByName st x
adamc@39 181 in
adamc@39 182 (L'.CNamed n, loc)
adamc@39 183 end
adamc@34 184
adamc@39 185 | L.CApp (c1, c2) => (L'.CApp (corifyCon st c1, corifyCon st c2), loc)
adamc@39 186 | L.CAbs (x, k, c) => (L'.CAbs (x, corifyKind k, corifyCon st c), loc)
adamc@16 187
adamc@16 188 | L.CName s => (L'.CName s, loc)
adamc@16 189
adamc@39 190 | L.CRecord (k, xcs) =>
adamc@39 191 (L'.CRecord (corifyKind k, map (fn (c1, c2) => (corifyCon st c1, corifyCon st c2)) xcs), loc)
adamc@39 192 | L.CConcat (c1, c2) => (L'.CConcat (corifyCon st c1, corifyCon st c2), loc)
adamc@16 193
adamc@39 194 fun corifyExp st (e, loc) =
adamc@16 195 case e of
adamc@16 196 L.EPrim p => (L'.EPrim p, loc)
adamc@16 197 | L.ERel n => (L'.ERel n, loc)
adamc@39 198 | L.ENamed n =>
adamc@39 199 (case St.lookupCoreById st n of
adamc@39 200 NONE => (L'.ENamed n, loc)
adamc@39 201 | SOME n => (L'.ENamed n, loc))
adamc@39 202 | L.EModProj (m, ms, x) =>
adamc@39 203 let
adamc@39 204 val st = St.lookupStrById st m
adamc@39 205 val st = foldl St.lookupStrByName st ms
adamc@39 206 val n = St.lookupCoreByName st x
adamc@39 207 in
adamc@39 208 (L'.ENamed n, loc)
adamc@39 209 end
adamc@39 210 | L.EApp (e1, e2) => (L'.EApp (corifyExp st e1, corifyExp st e2), loc)
adamc@39 211 | L.EAbs (x, dom, ran, e1) => (L'.EAbs (x, corifyCon st dom, corifyCon st ran, corifyExp st e1), loc)
adamc@39 212 | L.ECApp (e1, c) => (L'.ECApp (corifyExp st e1, corifyCon st c), loc)
adamc@39 213 | L.ECAbs (x, k, e1) => (L'.ECAbs (x, corifyKind k, corifyExp st e1), loc)
adamc@16 214
adamc@39 215 | L.ERecord xes => (L'.ERecord (map (fn (c, e, t) => (corifyCon st c, corifyExp st e, corifyCon st t)) xes), loc)
adamc@39 216 | L.EField (e1, c, {field, rest}) => (L'.EField (corifyExp st e1, corifyCon st c,
adamc@39 217 {field = corifyCon st field, rest = corifyCon st rest}), loc)
adamc@16 218
adamc@39 219 fun corifyDecl ((d, loc : EM.span), st) =
adamc@39 220 case d of
adamc@39 221 L.DCon (x, n, k, c) =>
adamc@39 222 let
adamc@39 223 val (st, n) = St.bindCore st x n
adamc@39 224 in
adamc@39 225 ([(L'.DCon (x, n, corifyKind k, corifyCon st c), loc)], st)
adamc@39 226 end
adamc@39 227 | L.DVal (x, n, t, e) =>
adamc@39 228 let
adamc@39 229 val (st, n) = St.bindCore st x n
adamc@39 230 in
adamc@39 231 ([(L'.DVal (x, n, corifyCon st t, corifyExp st e), loc)], st)
adamc@39 232 end
adamc@39 233
adamc@39 234 | L.DSgn _ => ([], st)
adamc@16 235
adamc@39 236 | L.DStr (x, n, _, str) =>
adamc@39 237 let
adamc@39 238 val (ds, {inner, outer}) = corifyStr (str, st)
adamc@39 239 val st = St.bindStr outer x n inner
adamc@39 240 in
adamc@39 241 (ds, st)
adamc@39 242 end
adamc@16 243
adamc@39 244 and corifyStr ((str, _), st) =
adamc@39 245 case str of
adamc@39 246 L.StrConst ds =>
adamc@39 247 let
adamc@39 248 val st = St.enter st
adamc@39 249 val (ds, st) = ListUtil.foldlMapConcat corifyDecl st ds
adamc@39 250 in
adamc@39 251 (ds, St.leave st)
adamc@39 252 end
adamc@39 253 | L.StrVar n => ([], {inner = St.lookupStrById st n, outer = st})
adamc@39 254 | L.StrProj (str, x) =>
adamc@39 255 let
adamc@39 256 val (ds, {inner, outer}) = corifyStr (str, st)
adamc@39 257 in
adamc@39 258 (ds, {inner = St.lookupStrByName (x, inner), outer = outer})
adamc@39 259 end
adamc@45 260 | L.StrFun _ => raise Fail "Corify functor"
adamc@45 261 | L.StrApp _ => raise Fail "Corify functor app"
adamc@31 262
adamc@39 263 fun maxName ds = foldl (fn ((d, _), n) =>
adamc@39 264 case d of
adamc@39 265 L.DCon (_, n', _, _) => Int.max (n, n')
adamc@39 266 | L.DVal (_, n', _ , _) => Int.max (n, n')
adamc@39 267 | L.DSgn (_, n', _) => Int.max (n, n')
adamc@39 268 | L.DStr (_, n', _, str) => Int.max (n, Int.max (n', maxNameStr str)))
adamc@39 269 0 ds
adamc@39 270
adamc@39 271 and maxNameStr (str, _) =
adamc@39 272 case str of
adamc@39 273 L.StrConst ds => maxName ds
adamc@39 274 | L.StrVar n => n
adamc@39 275 | L.StrProj (str, _) => maxNameStr str
adamc@45 276 | L.StrFun (_, _, _, _, str) => maxNameStr str
adamc@45 277 | L.StrApp (str1, str2) => Int.max (maxNameStr str1, maxNameStr str2)
adamc@39 278
adamc@39 279 fun corify ds =
adamc@39 280 let
adamc@39 281 val () = reset (maxName ds + 1)
adamc@39 282 val (ds, _) = ListUtil.foldlMapConcat corifyDecl St.empty ds
adamc@39 283 in
adamc@39 284 ds
adamc@39 285 end
adamc@16 286
adamc@16 287 end