diff src/corify.sml @ 39:02f42e9a1825

Corify removes modules
author Adam Chlipala <adamc@hcoop.net>
date Thu, 19 Jun 2008 12:39:22 -0400
parents 44b5405e74c7
children 3c1ce1b4eb3d
line wrap: on
line diff
--- a/src/corify.sml	Thu Jun 19 10:06:59 2008 -0400
+++ b/src/corify.sml	Thu Jun 19 12:39:22 2008 -0400
@@ -28,9 +28,133 @@
 structure Corify :> CORIFY = struct
 
 structure EM = ErrorMsg
-structure L = Elab
+structure L = Expl
 structure L' = Core
 
+structure IM = IntBinaryMap
+structure SM = BinaryMapFn(struct
+                           type ord_key = string
+                           val compare = String.compare
+                           end)
+
+local
+    val count = ref 0
+in
+
+fun reset v = count := v
+
+fun alloc () =
+    let
+        val r = !count
+    in
+        count := r + 1;
+        r
+end
+
+end
+
+structure St : sig
+    type t
+
+    val empty : t
+
+    val enter : t -> t
+    val leave : t -> {outer : t, inner : t}
+
+    val bindCore : t -> string -> int -> t * int
+    val lookupCoreById : t -> int -> int option
+    val lookupCoreByName : t -> string -> int
+
+    val bindStr : t -> string -> int -> t -> t
+    val lookupStrById : t -> int -> t
+    val lookupStrByName : string * t -> t
+end = struct
+
+datatype flattening = F of {
+         core : int SM.map,
+         strs : flattening SM.map
+}
+                           
+type t = {
+     core : int IM.map,
+     strs : flattening IM.map,
+     current : flattening,
+     nested : flattening list
+}
+
+val empty = {
+    core = IM.empty,
+    strs = IM.empty,
+    current = F { core = SM.empty, strs = SM.empty },
+    nested = []
+}
+
+fun bindCore {core, strs, current, nested} s n =
+    let
+        val n' = alloc ()
+
+        val current =
+            let
+                val F {core, strs} = current
+            in
+                F {core = SM.insert (core, s, n'),
+                   strs = strs}
+            end
+    in
+        ({core = IM.insert (core, n, n'),
+          strs = strs,
+          current = current,
+          nested = nested},
+         n')
+    end
+
+fun lookupCoreById ({core, ...} : t) n = IM.find (core, n)
+
+fun lookupCoreByName ({current = F {core, ...}, ...} : t) x =
+    case SM.find (core, x) of
+        NONE => raise Fail "Corify.St.lookupCoreByName"
+      | SOME n => n
+
+fun enter {core, strs, current, nested} =
+    {core = core,
+     strs = strs,
+     current = F {core = SM.empty,
+                  strs = SM.empty},
+     nested = current :: nested}
+
+fun dummy f = {core = IM.empty,
+               strs = IM.empty,
+               current = f,
+               nested = []}
+
+fun leave {core, strs, current, nested = m1 :: rest} =
+        {outer = {core = core,
+                  strs = strs,
+                  current = m1,
+                  nested = rest},
+         inner = dummy current}
+  | leave _ = raise Fail "Corify.St.leave"
+
+fun bindStr ({core, strs, current = F {core = mcore, strs = mstrs}, nested} : t) x n ({current = f, ...} : t) =
+    {core = core,
+     strs = IM.insert (strs, n, f),
+     current = F {core = mcore,
+                  strs = SM.insert (mstrs, x, f)},
+     nested = nested}
+
+fun lookupStrById ({strs, ...} : t) n =
+    case IM.find (strs, n) of
+        NONE => raise Fail "Corify.St.lookupStr"
+      | SOME f => dummy f
+
+fun lookupStrByName (m, {current = F {strs, ...}, ...} : t) =
+    case SM.find (strs, m) of
+        NONE => raise Fail "Corify.St.lookupStrByName"
+      | SOME f => dummy f
+
+end
+
+
 fun corifyKind (k, loc) =
     case k of
         L.KType => (L'.KType, loc)
@@ -38,57 +162,122 @@
       | L.KName => (L'.KName, loc)
       | L.KRecord k => (L'.KRecord (corifyKind k), loc)
 
-      | L.KError => raise Fail ("corifyKind: KError at " ^ EM.spanToString loc)
-      | L.KUnif (_, ref (SOME k)) => corifyKind k
-      | L.KUnif _ => raise Fail ("corifyKind: KUnif at " ^ EM.spanToString loc)
-
-fun corifyCon (c, loc) =
+fun corifyCon st (c, loc) =
     case c of
-        L.TFun (t1, t2) => (L'.TFun (corifyCon t1, corifyCon t2), loc)
-      | L.TCFun (_, x, k, t) => (L'.TCFun (x, corifyKind k, corifyCon t), loc)
-      | L.TRecord c => (L'.TRecord (corifyCon c), loc)
+        L.TFun (t1, t2) => (L'.TFun (corifyCon st t1, corifyCon st t2), loc)
+      | L.TCFun (x, k, t) => (L'.TCFun (x, corifyKind k, corifyCon st t), loc)
+      | L.TRecord c => (L'.TRecord (corifyCon st c), loc)
 
       | L.CRel n => (L'.CRel n, loc)
-      | L.CNamed n => (L'.CNamed n, loc)
-      | L.CModProj _ => raise Fail "Corify CModProj"
+      | L.CNamed n =>
+        (case St.lookupCoreById st n of
+             NONE => (L'.CNamed n, loc)
+           | SOME n => (L'.CNamed n, loc))
+      | L.CModProj (m, ms, x) =>
+        let
+            val st = St.lookupStrById st m
+            val st = foldl St.lookupStrByName st ms
+            val n = St.lookupCoreByName st x
+        in
+            (L'.CNamed n, loc)
+        end
 
-      | L.CApp (c1, c2) => (L'.CApp (corifyCon c1, corifyCon c2), loc)
-      | L.CAbs (x, k, c) => (L'.CAbs (x, corifyKind k, corifyCon c), loc)
+      | L.CApp (c1, c2) => (L'.CApp (corifyCon st c1, corifyCon st c2), loc)
+      | L.CAbs (x, k, c) => (L'.CAbs (x, corifyKind k, corifyCon st c), loc)
 
       | L.CName s => (L'.CName s, loc)
 
-      | L.CRecord (k, xcs) => (L'.CRecord (corifyKind k, map (fn (c1, c2) => (corifyCon c1, corifyCon c2)) xcs), loc)
-      | L.CConcat (c1, c2) => (L'.CConcat (corifyCon c1, corifyCon c2), loc)
+      | L.CRecord (k, xcs) =>
+        (L'.CRecord (corifyKind k, map (fn (c1, c2) => (corifyCon st c1, corifyCon st c2)) xcs), loc)
+      | L.CConcat (c1, c2) => (L'.CConcat (corifyCon st c1, corifyCon st c2), loc)
 
-      | L.CError => raise Fail ("corifyCon: CError at " ^ EM.spanToString loc)
-      | L.CUnif (_, _, ref (SOME c)) => corifyCon c
-      | L.CUnif _ => raise Fail ("corifyCon: CUnif at " ^ EM.spanToString loc)
-
-fun corifyExp (e, loc) =
+fun corifyExp st (e, loc) =
     case e of
         L.EPrim p => (L'.EPrim p, loc)
       | L.ERel n => (L'.ERel n, loc)
-      | L.ENamed n => (L'.ENamed n, loc)
-      | L.EModProj _ => raise Fail "Corify EModProj"
-      | L.EApp (e1, e2) => (L'.EApp (corifyExp e1, corifyExp e2), loc)
-      | L.EAbs (x, dom, ran, e1) => (L'.EAbs (x, corifyCon dom, corifyCon ran, corifyExp e1), loc)
-      | L.ECApp (e1, c) => (L'.ECApp (corifyExp e1, corifyCon c), loc)
-      | L.ECAbs (_, x, k, e1) => (L'.ECAbs (x, corifyKind k, corifyExp e1), loc)
+      | L.ENamed n =>
+        (case St.lookupCoreById st n of
+             NONE => (L'.ENamed n, loc)
+           | SOME n => (L'.ENamed n, loc))
+      | L.EModProj (m, ms, x) =>
+        let
+            val st = St.lookupStrById st m
+            val st = foldl St.lookupStrByName st ms
+            val n = St.lookupCoreByName st x
+        in
+            (L'.ENamed n, loc)
+        end
+      | L.EApp (e1, e2) => (L'.EApp (corifyExp st e1, corifyExp st e2), loc)
+      | L.EAbs (x, dom, ran, e1) => (L'.EAbs (x, corifyCon st dom, corifyCon st ran, corifyExp st e1), loc)
+      | L.ECApp (e1, c) => (L'.ECApp (corifyExp st e1, corifyCon st c), loc)
+      | L.ECAbs (x, k, e1) => (L'.ECAbs (x, corifyKind k, corifyExp st e1), loc)
 
-      | L.ERecord xes => (L'.ERecord (map (fn (c, e, t) => (corifyCon c, corifyExp e, corifyCon t)) xes), loc)
-      | L.EField (e1, c, {field, rest}) => (L'.EField (corifyExp e1, corifyCon c,
-                                                       {field = corifyCon field, rest = corifyCon rest}), loc)
+      | L.ERecord xes => (L'.ERecord (map (fn (c, e, t) => (corifyCon st c, corifyExp st e, corifyCon st t)) xes), loc)
+      | L.EField (e1, c, {field, rest}) => (L'.EField (corifyExp st e1, corifyCon st c,
+                                                       {field = corifyCon st field, rest = corifyCon st rest}), loc)
 
-      | L.EError => raise Fail ("corifyExp: EError at " ^ EM.spanToString loc)
+fun corifyDecl ((d, loc : EM.span), st) =
+    case d of
+        L.DCon (x, n, k, c) =>
+        let
+            val (st, n) = St.bindCore st x n
+        in
+            ([(L'.DCon (x, n, corifyKind k, corifyCon st c), loc)], st)
+        end
+      | L.DVal (x, n, t, e) =>
+        let
+            val (st, n) = St.bindCore st x n
+        in
+            ([(L'.DVal (x, n, corifyCon st t, corifyExp st e), loc)], st)
+        end
+                                                                        
+      | L.DSgn _ => ([], st)
 
-fun corifyDecl (d, loc : EM.span) =
-    case d of
-        L.DCon (x, n, k, c) => (L'.DCon (x, n, corifyKind k, corifyCon c), loc)
-      | L.DVal (x, n, t, e) => (L'.DVal (x, n, corifyCon t, corifyExp e), loc)
+      | L.DStr (x, n, _, str) =>
+        let
+            val (ds, {inner, outer}) = corifyStr (str, st)
+            val st = St.bindStr outer x n inner
+        in
+            (ds, st)
+        end
 
-      | L.DSgn _ => raise Fail "Not ready to corify signature"
-      | L.DStr _ => raise Fail "Not ready to corify structure"
+and corifyStr ((str, _), st) =
+    case str of
+        L.StrConst ds =>
+        let
+            val st = St.enter st
+            val (ds, st) = ListUtil.foldlMapConcat corifyDecl st ds
+        in
+            (ds, St.leave st)
+        end
+      | L.StrVar n => ([], {inner = St.lookupStrById st n, outer = st})
+      | L.StrProj (str, x) =>
+        let
+            val (ds, {inner, outer}) = corifyStr (str, st)
+        in
+            (ds, {inner = St.lookupStrByName (x, inner), outer = outer})
+        end
 
-val corify = map corifyDecl
+fun maxName ds = foldl (fn ((d, _), n) =>
+                           case d of
+                               L.DCon (_, n', _, _) => Int.max (n, n')
+                             | L.DVal (_, n', _ , _) => Int.max (n, n')
+                             | L.DSgn (_, n', _) => Int.max (n, n')
+                             | L.DStr (_, n', _, str) => Int.max (n, Int.max (n', maxNameStr str)))
+                 0 ds
+
+and maxNameStr (str, _) =
+    case str of
+        L.StrConst ds => maxName ds
+      | L.StrVar n => n
+      | L.StrProj (str, _) => maxNameStr str
+
+fun corify ds =
+    let
+        val () = reset (maxName ds + 1)
+        val (ds, _) = ListUtil.foldlMapConcat corifyDecl St.empty ds
+    in
+        ds
+    end
 
 end