changeset 178:eb3f9913bf31

First part of getting cases through monoize
author Adam Chlipala <adamc@hcoop.net>
date Sun, 03 Aug 2008 09:26:49 -0400
parents 5d030ee143e2
children 3bbed533fbd2
files src/cjrize.sml src/mono.sml src/mono_env.sig src/mono_env.sml src/mono_print.sml src/mono_shake.sml src/mono_util.sml src/monoize.sml
diffstat 8 files changed, 152 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/src/cjrize.sml	Sat Aug 02 11:15:32 2008 -0400
+++ b/src/cjrize.sml	Sun Aug 03 09:26:49 2008 -0400
@@ -108,6 +108,7 @@
         L.EPrim p => ((L'.EPrim p, loc), sm)
       | L.ERel n => ((L'.ERel n, loc), sm)
       | L.ENamed n => ((L'.ENamed n, loc), sm)
+      | L.ECon _ => raise Fail "Cjrize ECon"
       | L.EFfi mx => ((L'.EFfi mx, loc), sm)
       | L.EFfiApp (m, x, es) =>
         let
@@ -152,6 +153,8 @@
             ((L'.EField (e, x), loc), sm)
         end
 
+      | L.ECase _ => raise Fail "Cjrize ECase"
+
       | L.EStrcat _ => raise Fail "Cjrize EStrcat"
 
       | L.EWrite e =>
--- a/src/mono.sml	Sat Aug 02 11:15:32 2008 -0400
+++ b/src/mono.sml	Sun Aug 03 09:26:49 2008 -0400
@@ -37,10 +37,24 @@
 
 withtype typ = typ' located
 
+datatype patCon =
+         PConVar of int
+       | PConFfi of string * string
+
+datatype pat' =
+         PWild
+       | PVar of string
+       | PPrim of Prim.t
+       | PCon of patCon * pat option
+       | PRecord of (string * pat) list
+
+withtype pat = pat' located
+
 datatype exp' =
          EPrim of Prim.t
        | ERel of int
        | ENamed of int
+       | ECon of int * exp option
        | EFfi of string * string
        | EFfiApp of string * string * exp list
        | EApp of exp * exp
@@ -49,6 +63,8 @@
        | ERecord of (string * exp * typ) list
        | EField of exp * string
 
+       | ECase of exp * (pat * exp) list * typ
+
        | EStrcat of exp * exp
 
        | EWrite of exp
--- a/src/mono_env.sig	Sat Aug 02 11:15:32 2008 -0400
+++ b/src/mono_env.sig	Sun Aug 03 09:26:49 2008 -0400
@@ -37,6 +37,8 @@
     val pushDatatype : env -> string -> int -> (string * int * Mono.typ option) list -> env
     val lookupDatatype : env -> int -> string * (string * int * Mono.typ option) list
 
+    val lookupConstructor : env -> int -> string * Mono.typ option * int
+
     val pushERel : env -> string -> Mono.typ -> env
     val lookupERel : env -> int -> string * Mono.typ
 
--- a/src/mono_env.sml	Sat Aug 02 11:15:32 2008 -0400
+++ b/src/mono_env.sml	Sun Aug 03 09:26:49 2008 -0400
@@ -37,6 +37,7 @@
 
 type env = {
      datatypes : (string * (string * int * typ option) list) IM.map,
+     constructors : (string * typ option * int) IM.map,
 
      relE : (string * typ) list,
      namedE : (string * typ * exp option * string) IM.map
@@ -44,6 +45,7 @@
 
 val empty = {
     datatypes = IM.empty,
+    constructors = IM.empty,
 
     relE = [],
     namedE = IM.empty
@@ -51,6 +53,9 @@
 
 fun pushDatatype (env : env) x n xncs =
     {datatypes = IM.insert (#datatypes env, n, (x, xncs)),
+     constructors = foldl (fn ((x, n, to), constructors) =>
+                              IM.insert (constructors, n, (x, to, n)))
+                          (#constructors env) xncs,
 
      relE = #relE env,
      namedE = #namedE env}
@@ -60,8 +65,14 @@
         NONE => raise UnboundNamed n
       | SOME x => x
 
+fun lookupConstructor (env : env) n =
+    case IM.find (#constructors env, n) of
+        NONE => raise UnboundNamed n
+      | SOME x => x
+
 fun pushERel (env : env) x t =
     {datatypes = #datatypes env,
+     constructors = #constructors env,
 
      relE = (x, t) :: #relE env,
      namedE = #namedE env}
@@ -72,6 +83,7 @@
 
 fun pushENamed (env : env) x n t eo s =
     {datatypes = #datatypes env,
+     constructors = #constructors env,
 
      relE = #relE env,
      namedE = IM.insert (#namedE env, n, (x, t, eo, s))}
--- a/src/mono_print.sml	Sat Aug 02 11:15:32 2008 -0400
+++ b/src/mono_print.sml	Sun Aug 03 09:26:49 2008 -0400
@@ -54,29 +54,73 @@
                                             p_typ env t]) xcs,
                             string "}"]
       | TDatatype (n, _) =>
-        if !debug then
-            string (#1 (E.lookupDatatype env n) ^ "__" ^ Int.toString n)
-        else
-            string (#1 (E.lookupDatatype env n))
+        ((if !debug then
+              string (#1 (E.lookupDatatype env n) ^ "__" ^ Int.toString n)
+          else
+              string (#1 (E.lookupDatatype env n)))
+         handle E.UnboundNamed _ => string ("UNBOUND_DATATYPE_" ^ Int.toString n))
       | TFfi (m, x) => box [string "FFI(", string m, string ".", string x, string ")"]
 
 and p_typ env = p_typ' false env
 
 fun p_enamed env n =
-    if !debug then
-        string (#1 (E.lookupENamed env n) ^ "__" ^ Int.toString n)
-    else
-        string (#1 (E.lookupENamed env n))
+    (if !debug then
+         string (#1 (E.lookupENamed env n) ^ "__" ^ Int.toString n)
+     else
+         string (#1 (E.lookupENamed env n)))
+    handle E.UnboundNamed _ => string ("UNBOUNDN_" ^ Int.toString n)
+
+fun p_con_named env n =
+    (if !debug then
+        string (#1 (E.lookupConstructor env n) ^ "__" ^ Int.toString n)
+     else
+         string (#1 (E.lookupConstructor env n)))
+    handle E.UnboundNamed _ => string ("CONSTRUCTOR_" ^ Int.toString n)
+
+fun p_patCon env pc =
+    case pc of
+        PConVar n => p_con_named env n
+      | PConFfi (m, x) => box [string "FFI(",
+                               string m,
+                               string ".",
+                               string x,
+                               string ")"]
+
+fun p_pat' par env (p, _) =
+    case p of
+        PWild => string "_"
+      | PVar s => string s
+      | PPrim p => Prim.p_t p
+      | PCon (n, NONE) => p_patCon env n
+      | PCon (n, SOME p) => parenIf par (box [p_patCon env n,
+                                              space,
+                                              p_pat' true env p])
+      | PRecord xps =>
+        box [string "{",
+             p_list_sep (box [string ",", space]) (fn (x, p) =>
+                                                      box [string x,
+                                                           space,
+                                                           string "=",
+                                                           space,
+                                                           p_pat env p]) xps,
+             string "}"]
+
+and p_pat x = p_pat' false x
 
 fun p_exp' par env (e, _) =
     case e of
         EPrim p => Prim.p_t p
       | ERel n =>
-        if !debug then
-            string (#1 (E.lookupERel env n) ^ "_" ^ Int.toString n)
-        else
-            string (#1 (E.lookupERel env n))
+        ((if !debug then
+              string (#1 (E.lookupERel env n) ^ "_" ^ Int.toString n)
+          else
+              string (#1 (E.lookupERel env n)))
+         handle E.UnboundRel _ => string ("UNBOUND_" ^ Int.toString n))
       | ENamed n => p_enamed env n
+      | ECon (n, NONE) => p_con_named env n
+      | ECon (n, SOME e) => parenIf par (box [p_con_named env n,
+                                              space,
+                                              p_exp' true env e])
 
       | EFfi (m, x) => box [string "FFI(", string m, string ".", string x, string ")"]
       | EFfiApp (m, x, es) => box [string "FFI(",
@@ -114,6 +158,18 @@
              string ".",
              string x]
 
+      | ECase (e, pes, _) => parenIf par (box [string "case",
+                                               space,
+                                               p_exp env e,
+                                               space,
+                                               string "of",
+                                               space,
+                                               p_list_sep (box [space, string "|", space])
+                                                          (fn (p, e) => box [p_pat env p,
+                                                                             space,
+                                                                             string "=>",
+                                                                             space,
+                                                                             p_exp env e]) pes])
 
       | EStrcat (e1, e2) => box [p_exp' true env e1,
                                  space,
--- a/src/mono_shake.sml	Sat Aug 02 11:15:32 2008 -0400
+++ b/src/mono_shake.sml	Sun Aug 03 09:26:49 2008 -0400
@@ -47,8 +47,10 @@
                           (fn ((DExport (_, _, n, _), _), page_es) => n :: page_es
                             | (_, page_es) => page_es) [] file
 
-        val (cdef, edef) = foldl (fn ((DDatatype _, _), acc) => acc
-                                   | ((DVal (_, n, t, e, _), _), (cdef, edef)) => (cdef, IM.insert (edef, n, (t, e)))
+        val (cdef, edef) = foldl (fn ((DDatatype (_, n, xncs), _), (cdef, edef)) =>
+                                     (IM.insert (cdef, n, xncs), edef)
+                                   | ((DVal (_, n, t, e, _), _), (cdef, edef)) =>
+                                     (cdef, IM.insert (edef, n, (t, e)))
                                    | ((DValRec vis, _), (cdef, edef)) =>
                                      (cdef, foldl (fn ((_, n, t, e, _), edef) => IM.insert (edef, n, (t, e))) edef vis)
                                    | ((DExport _, _), acc) => acc)
@@ -60,10 +62,22 @@
                 if IS.member (#con s, n) then
                     s
                 else
-                    {exp = #exp s,
-                     con = IS.add (#con s, n)}
+                    let
+                        val s' = {exp = #exp s,
+                                  con = IS.add (#con s, n)}
+                    in
+                        case IM.find (cdef, n) of
+                            NONE => s'
+                          | SOME xncs => foldl (fn ((_, _, to), s) =>
+                                                   case to of
+                                                       NONE => s
+                                                     | SOME t => shakeTyp s t)
+                                         s' xncs
+                    end
               | _ => s
 
+        and shakeTyp s = U.Typ.fold typ s
+
         fun exp (e, s) =
             case e of
                 ENamed n =>
--- a/src/mono_util.sml	Sat Aug 02 11:15:32 2008 -0400
+++ b/src/mono_util.sml	Sun Aug 03 09:26:49 2008 -0400
@@ -141,6 +141,11 @@
                 EPrim _ => S.return2 eAll
               | ERel _ => S.return2 eAll
               | ENamed _ => S.return2 eAll
+              | ECon (_, NONE) => S.return2 eAll
+              | ECon (n, SOME e) =>
+                S.map2 (mfe ctx e,
+                        fn e' =>
+                           (ECon (n, SOME e'), loc))
               | EFfi _ => S.return2 eAll
               | EFfiApp (m, x, es) =>
                 S.map2 (ListUtil.mapfold (fn e => mfe ctx e) es,
@@ -176,6 +181,17 @@
                       fn e' =>
                          (EField (e', x), loc))
 
+              | ECase (e, pes, t) =>
+                S.bind2 (mfe ctx e,
+                         fn e' =>
+                            S.bind2 (ListUtil.mapfold (fn (p, e) =>
+                                                         S.map2 (mfe ctx e,
+                                                              fn e' => (p, e'))) pes,
+                                    fn pes' =>
+                                       S.map2 (mft t,
+                                               fn t' =>
+                                                  (ECase (e', pes', t'), loc))))
+
               | EStrcat (e1, e2) =>
                 S.bind2 (mfe ctx e1,
                       fn e1' =>
--- a/src/monoize.sml	Sat Aug 02 11:15:32 2008 -0400
+++ b/src/monoize.sml	Sun Aug 03 09:26:49 2008 -0400
@@ -160,6 +160,19 @@
 
 end
 
+fun monoPatCon pc =
+    case pc of
+        L.PConVar n => L'.PConVar n
+      | L.PConFfi mx => L'.PConFfi mx
+
+fun monoPat (p, loc) =
+    case p of
+        L.PWild => (L'.PWild, loc)
+      | L.PVar x => (L'.PVar x, loc)
+      | L.PPrim p => (L'.PPrim p, loc)
+      | L.PCon (pc, po) => (L'.PCon (monoPatCon pc, Option.map monoPat po), loc)
+      | L.PRecord xps => (L'.PRecord (map (fn (x, p) => (x, monoPat p)) xps), loc)
+
 fun monoExp (env, st) (all as (e, loc)) =
     let
         fun poly () =
@@ -171,7 +184,7 @@
             L.EPrim p => (L'.EPrim p, loc)
           | L.ERel n => (L'.ERel n, loc)
           | L.ENamed n => (L'.ENamed n, loc)
-          | L.ECon _ => raise Fail "Monoize ECon"
+          | L.ECon (n, eo) => (L'.ECon (n, Option.map (monoExp (env, st)) eo), loc)
           | L.EFfi mx => (L'.EFfi mx, loc)
           | L.EFfiApp (m, x, es) => (L'.EFfiApp (m, x, map (monoExp (env, st)) es), loc)
 
@@ -450,7 +463,9 @@
           | L.ECut _ => poly ()
           | L.EFold _ => poly ()
 
-          | L.ECase _ => raise Fail "Monoize ECase"
+          | L.ECase (e, pes, t) => (L'.ECase (monoExp (env, st) e,
+                                              map (fn (p, e) => (monoPat p, monoExp (env, st) e)) pes,
+                                              monoType env t), loc)
 
           | L.EWrite e => (L'.EWrite (monoExp (env, st) e), loc)