Revive External Core typechecker
authorTim Chevalier <chevalier@alum.wellesley.edu>
Mon, 14 Apr 2008 02:46:48 +0000 (02:46 +0000)
committerTim Chevalier <chevalier@alum.wellesley.edu>
Mon, 14 Apr 2008 02:46:48 +0000 (02:46 +0000)
The typechecker works again! Yay!

Details upon request.

12 files changed:
utils/ext-core/Check.hs
utils/ext-core/Core.hs
utils/ext-core/Driver.hs
utils/ext-core/Env.hs
utils/ext-core/Interp.hs
utils/ext-core/Makefile
utils/ext-core/ParsecParser.hs
utils/ext-core/Prep.hs
utils/ext-core/PrimCoercions.hs [new file with mode: 0644]
utils/ext-core/Prims.hs
utils/ext-core/Printer.hs
utils/ext-core/README

index dedc0f4..29fb71f 100644 (file)
@@ -1,12 +1,19 @@
-module Check where
+{-# OPTIONS -Wall -fno-warn-name-shadowing #-}
+module Check(
+  checkModule, envsModule,
+  checkExpr, checkType, 
+  primCoercionError, 
+  Menv, Venv, Tvenv, Envs(..),
+  CheckRes(..), splitTy, substl) where
 
 import Maybe
 import Control.Monad.Reader
 
 import Core
-import Printer
+import Printer()
 import List
 import Env
+import PrimEnv
 
 {- Checking is done in a simple error monad.  In addition to
    allowing errors to be captured, this makes it easy to guarantee
@@ -25,7 +32,7 @@ getGlobalEnv = ask >>= (return . snd)
 
 instance Monad CheckRes where
   OkC a >>= k = k a
-  FailC s >>= k = fail s
+  FailC s >>= _ = fail s
   return = OkC
   fail = FailC
 
@@ -40,19 +47,31 @@ requireM cond s =
 
 {- Environments. -}
 type Tvenv = Env Tvar Kind                    -- type variables  (local only)
-type Tcenv = Env Tcon Kind                    -- type constructors
+type Tcenv = Env Tcon KindOrCoercion          -- type constructors
 type Tsenv = Env Tcon ([Tvar],Ty)             -- type synonyms
 type Cenv = Env Dcon Ty                      -- data constructors
 type Venv = Env Var Ty                               -- values
 type Menv = Env AnMname Envs                 -- modules
 data Envs = Envs {tcenv_::Tcenv,tsenv_::Tsenv,cenv_::Cenv,venv_::Venv} -- all the exportable envs
+  deriving Show
 
-{- Extend an environment, checking for illegal shadowing of identifiers. -}
-extendM :: (Ord a, Show a) => Env a b -> (a,b) -> CheckResult (Env a b)
-extendM env (k,d) = 
+{- Extend an environment, checking for illegal shadowing of identifiers (for term
+   variables -- shadowing type variables is allowed.) -}
+data EnvType = Tv | NotTv
+  deriving Eq
+
+extendM :: (Ord a, Show a) => EnvType -> Env a b -> (a,b) -> CheckResult (Env a b)
+extendM envType env (k,d) = 
    case elookup env k of
-     Just _ -> fail ("multiply-defined identifier: " ++ show k)
-     Nothing -> return (eextend env (k,d))
+     Just _ | envType == NotTv -> fail ("multiply-defined identifier: " 
+                                      ++ show k)
+     _ -> return (eextend env (k,d))
+
+extendVenv :: (Ord a, Show a) => Env a b -> (a,b) -> CheckResult (Env a b)
+extendVenv = extendM NotTv
+
+extendTvenv :: (Ord a, Show a) => Env a b -> (a,b) -> CheckResult (Env a b)
+extendTvenv = extendM Tv
 
 lookupM :: (Ord a, Show a) => Env a b -> a -> CheckResult b
 lookupM env k =   
@@ -62,34 +81,72 @@ lookupM env k =
             
 {- Main entry point. -}
 checkModule :: Menv -> Module -> CheckRes Menv
-checkModule globalEnv mod@(Module mn tdefs vdefgs) = 
+checkModule globalEnv (Module mn tdefs vdefgs) = 
   runReaderT 
     (do (tcenv, tsenv, cenv) <- mkTypeEnvs tdefs
-        (e_venv,l_venv) <- foldM (checkVdefg True (tcenv,tsenv,eempty,cenv))
+        (e_venv,_) <- foldM (checkVdefg True (tcenv,tsenv,eempty,cenv))
                               (eempty,eempty) 
                               vdefgs
         return (eextend globalEnv 
             (mn,Envs{tcenv_=tcenv,tsenv_=tsenv,cenv_=cenv,venv_=e_venv})))
     (mn, globalEnv)   
 
+-- Like checkModule, but doesn't typecheck the code, instead just
+-- returning declared types for top-level defns.
+-- This is necessary in order to handle circular dependencies, but it's sort
+-- of unpleasant.
+envsModule :: Menv -> Module -> Menv
+envsModule globalEnv (Module mn tdefs vdefgs) = 
+   let (tcenv, tsenv, cenv) = mkTypeEnvsNoChecking tdefs
+       e_venv               = foldr vdefgTypes eempty vdefgs in
+     eextend globalEnv (mn, 
+             (Envs{tcenv_=tcenv,tsenv_=tsenv,cenv_=cenv,venv_=e_venv}))
+        where vdefgTypes :: Vdefg -> Venv -> Venv
+              vdefgTypes (Nonrec (Vdef (v,t,_))) e =
+                             add [(v,t)] e
+              vdefgTypes (Rec vds) e = 
+                             add (map (\ (Vdef (v,t,_)) -> (v,t)) vds) e
+              add :: [(Qual Var,Ty)] -> Venv -> Venv
+              add pairs e = foldr addOne e pairs
+              addOne :: (Qual Var, Ty) -> Venv -> Venv
+              addOne ((Nothing,_),_) e = e
+              addOne ((Just _,v),t) e  = eextend e (v,t)
+
 checkTdef0 :: (Tcenv,Tsenv) -> Tdef -> CheckResult (Tcenv,Tsenv)
 checkTdef0 (tcenv,tsenv) tdef = ch tdef
       where 
        ch (Data (m,c) tbs _) = 
            do mn <- getMname
                requireModulesEq m mn "data type declaration" tdef False
-              tcenv' <- extendM tcenv (c,k)
+              tcenv' <- extendM NotTv tcenv (c, Kind k)
               return (tcenv',tsenv)
            where k = foldr Karrow Klifted (map snd tbs)
-        -- TODO
-       ch (Newtype (m,c) tbs axiom rhs) = 
+       ch (Newtype (m,c) tbs ((_,coercion),cTbs,coercionKind) rhs) = 
            do mn <- getMname
                requireModulesEq m mn "newtype declaration" tdef False
-              tcenv' <- extendM tcenv (c,k)
+              tcenv' <- extendM NotTv tcenv (c, Kind k)
+               -- add newtype axiom to env
+               tcenv'' <- extendM NotTv tcenv' 
+                  (coercion, Coercion $ DefinedCoercion cTbs coercionKind)
               tsenv' <- case rhs of
                           Nothing -> return tsenv
-                          Just rep -> extendM tsenv (c,(map fst tbs,rep))
-              return (tcenv', tsenv')
+                          Just rep -> extendM NotTv tsenv (c,(map fst tbs,rep))
+              return (tcenv'', tsenv')
+           where k = foldr Karrow Klifted (map snd tbs)
+
+processTdef0NoChecking :: (Tcenv,Tsenv) -> Tdef -> (Tcenv,Tsenv)
+processTdef0NoChecking (tcenv,tsenv) tdef = ch tdef
+      where 
+       ch (Data (_,c) tbs _) = (eextend tcenv (c, Kind k), tsenv)
+           where k = foldr Karrow Klifted (map snd tbs)
+       ch (Newtype (_,c) tbs ((_,coercion),cTbs,coercionKind) rhs) = 
+           let tcenv' = eextend tcenv (c, Kind k)
+                -- add newtype axiom to env
+                tcenv'' = eextend tcenv' 
+                  (coercion, Coercion $ DefinedCoercion cTbs coercionKind)
+               tsenv' = maybe tsenv 
+                  (\ rep -> eextend tsenv (c, (map fst tbs, rep))) rhs in
+               (tcenv'', tsenv')
            where k = foldr Karrow Klifted (map snd tbs)
     
 checkTdef :: Tcenv -> Cenv -> Tdef -> CheckResult Cenv
@@ -97,12 +154,12 @@ checkTdef tcenv cenv = ch
        where 
         ch (Data (_,c) utbs cdefs) = 
            do cbinds <- mapM checkCdef cdefs
-              foldM extendM cenv cbinds
+              foldM (extendM NotTv) cenv cbinds
            where checkCdef (cdef@(Constr (m,dcon) etbs ts)) =
                    do mn <- getMname
                        requireModulesEq m mn "constructor declaration" cdef 
                          False 
-                      tvenv <- foldM extendM eempty tbs 
+                      tvenv <- foldM (extendM Tv) eempty tbs 
                       ks <- mapM (checkTy (tcenv,tvenv)) ts
                       mapM_ (\k -> require (baseKind k)
                                            ("higher-order kind in:\n" ++ show cdef ++ "\n" ++
@@ -113,26 +170,57 @@ checkTdef tcenv cenv = ch
                                  (foldr tArrow
                                          (foldl Tapp (Tcon (Just mn,c))
                                                 (map (Tvar . fst) utbs)) ts) tbs
-         -- TODO
-        ch (tdef@(Newtype c tbs axiom (Just t))) =  
-           do tvenv <- foldM extendM eempty tbs
+         ch (tdef@(Newtype _ tbs (_, coTbs, (coLhs, coRhs)) (Just t))) =  
+           do tvenv <- foldM (extendM Tv) eempty tbs
               k <- checkTy (tcenv,tvenv) t
-              require (k `eqKind` Klifted) ("bad kind:\n" ++ show tdef) 
+               -- Makes sure GHC is eta-expanding things properly
+               require (length tbs == length coTbs) $
+                 ("Arity mismatch between newtycon and newtype coercion: "
+                  ++ show tdef)
+               require (k `eqKind` Klifted) ("bad kind:\n" ++ show tdef)
+               axiomTvenv <- foldM (extendM Tv) eempty coTbs
+               kLhs <- checkTy (tcenv,axiomTvenv) coLhs
+               kRhs <- checkTy (tcenv,axiomTvenv) coRhs
+               require (kLhs `eqKind` kRhs) 
+                  ("Kind mismatch in newtype axiom types: " ++ show tdef 
+                    ++ " kinds: " ++
+                   (show kLhs) ++ " and " ++ (show kRhs))
               return cenv
-        ch (tdef@(Newtype c tbs axiom Nothing)) =
+        ch (Newtype _ _ _ Nothing) =
            {- should only occur for recursive Newtypes -}
            return cenv
 
+processCdef :: Cenv -> Tdef -> Cenv
+processCdef cenv = ch
+  where
+    ch (Data (_,c) utbs cdefs) = do 
+       let cbinds = map checkCdef cdefs
+       foldl eextend cenv cbinds
+     where checkCdef (Constr (mn,dcon) etbs ts) =
+             (dcon,t mn) 
+            where tbs = utbs ++ etbs
+                  t mn = foldr Tforall 
+                         (foldr tArrow
+                           (foldl Tapp (Tcon (mn,c))
+                               (map (Tvar . fst) utbs)) ts) tbs
+    ch _ = cenv
+
 mkTypeEnvs :: [Tdef] -> CheckResult (Tcenv, Tsenv, Cenv)
 mkTypeEnvs tdefs = do
   (tcenv, tsenv) <- foldM checkTdef0 (eempty,eempty) tdefs
   cenv <- foldM (checkTdef tcenv) eempty tdefs
   return (tcenv, tsenv, cenv)
 
+mkTypeEnvsNoChecking :: [Tdef] -> (Tcenv, Tsenv, Cenv)
+mkTypeEnvsNoChecking tdefs = 
+  let (tcenv, tsenv) = foldl processTdef0NoChecking (eempty,eempty) tdefs
+      cenv           = foldl processCdef eempty tdefs in
+    (tcenv, tsenv, cenv)
+
 requireModulesEq :: Show a => Mname -> AnMname -> String -> a 
                           -> Bool -> CheckResult ()
 requireModulesEq (Just mn) m msg t _      = require (mn == m) (mkErrMsg msg t)
-requireModulesEq Nothing m msg t emptyOk  = require emptyOk (mkErrMsg msg t)
+requireModulesEq Nothing _ msg t emptyOk  = require emptyOk (mkErrMsg msg t)
 
 mkErrMsg :: Show a => String -> a -> String
 mkErrMsg msg t = "wrong module name in " ++ msg ++ ":\n" ++ show t    
@@ -142,10 +230,10 @@ checkVdefg :: Bool -> (Tcenv,Tsenv,Tvenv,Cenv) -> (Venv,Venv)
 checkVdefg top_level (tcenv,tsenv,tvenv,cenv) (e_venv,l_venv) vdefg =
       case vdefg of
        Rec vdefs ->
-           do e_venv' <- foldM extendM e_venv e_vts
-              l_venv' <- foldM extendM l_venv l_vts
+           do e_venv' <- foldM extendVenv e_venv e_vts
+              l_venv' <- foldM extendVenv l_venv l_vts
               let env' = (tcenv,tsenv,tvenv,cenv,e_venv',l_venv')
-              mapM_ (\ (vdef@(Vdef ((m,v),t,e))) -> 
+              mapM_ (\ (vdef@(Vdef ((m,_),t,e))) -> 
                            do mn <- getMname
                                requireModulesEq m mn "value definition" vdef True
                               k <- checkTy (tcenv,tvenv) t
@@ -160,33 +248,58 @@ checkVdefg top_level (tcenv,tsenv,tvenv,cenv) (e_venv,l_venv) vdefg =
                  l_vts  = [ (v,t) | Vdef ((Nothing,v),t,_) <- vdefs]
        Nonrec (vdef@(Vdef ((m,v),t,e))) ->
            do mn <- getMname
-               requireModulesEq m mn "value definition" vdef True
+               -- TODO: document this weirdness
+               let isZcMain = vdefIsMainWrapper mn m 
+               unless isZcMain $
+                    requireModulesEq m mn "value definition" vdef True
               k <- checkTy (tcenv,tvenv) t 
               require (not (k `eqKind` Kopen)) ("open kind in:\n" ++ show vdef)
-              require ((not top_level) || (not (k `eqKind` Kunlifted))) ("top-level unlifted kind in:\n" ++ show vdef) 
+              require ((not top_level) || (not (k `eqKind` Kunlifted))) 
+                 ("top-level unlifted kind in:\n" ++ show vdef) 
               t' <- checkExp (tcenv,tsenv,tvenv,cenv,e_venv,l_venv) e
               requireM (equalTy tsenv t t') 
-                       ("declared type doesn't match expression type in:\n" ++ show vdef  ++ "\n"  ++
+                       ("declared type doesn't match expression type in:\n" 
+                         ++ show vdef  ++ "\n"  ++
                         "declared type: " ++ show t ++ "\n" ++
                         "expression type: " ++ show t') 
               if isNothing m then
-                 do l_venv' <- extendM l_venv (v,t)
+                 do l_venv' <- extendVenv l_venv (v,t)
                     return (e_venv,l_venv')
                else
-                do e_venv' <- extendM e_venv (v,t)
+                              -- awful, but avoids name shadowing --
+                              -- otherwise we'd have two bindings for "main"
+                do e_venv' <- if isZcMain 
+                                 then return e_venv 
+                                 else extendVenv e_venv (v,t)
                     return (e_venv',l_venv)
     
+vdefIsMainWrapper :: AnMname -> Mname -> Bool
+vdefIsMainWrapper enclosing defining = 
+   enclosing == mainMname && defining == wrapperMainMname
+
 checkExpr :: AnMname -> Menv -> [Tdef] -> Venv -> Tvenv 
                -> Exp -> Ty
-checkExpr mn menv tdefs venv tvenv e = case (runReaderT (do
+checkExpr mn menv tdefs venv tvenv e = case runReaderT (do
   (tcenv, tsenv, cenv) <- mkTypeEnvs tdefs
-  checkExp (tcenv, tsenv, tvenv, cenv, venv, eempty) e) 
-                            (mn, menv)) of
-    OkC t -> t
-    FailC s -> reportError s
+  -- Since the preprocessor calls checkExpr after code has been
+  -- typechecked, we expect to find the external env in the Menv.
+  case (elookup menv mn) of
+     Just thisEnv ->
+       checkExp (tcenv, tsenv, tvenv, cenv, (venv_ thisEnv), venv) e 
+     Nothing -> reportError e ("checkExpr: Environment for " ++ 
+                  show mn ++ " not found")) (mn,menv) of
+         OkC t -> t
+         FailC s -> reportError e s
+
+checkType :: AnMname -> Menv -> [Tdef] -> Tvenv -> Ty -> Kind
+checkType mn menv tdefs tvenv t = case runReaderT (do
+  (tcenv, _, _) <- mkTypeEnvs tdefs
+  checkTy (tcenv, tvenv) t) (mn, menv) of
+      OkC k -> k
+      FailC s -> reportError tvenv s
 
 checkExp :: (Tcenv,Tsenv,Tvenv,Cenv,Venv,Venv) -> Exp -> CheckResult Ty
-checkExp (tcenv,tsenv,tvenv,cenv,e_venv,l_venv) = ch 
+checkExp (tcenv,tsenv,tvenv,cenv,e_venv,l_venv) = ch
       where 
        ch e0 = 
          case e0 of
@@ -221,7 +334,7 @@ checkExp (tcenv,tsenv,tvenv,cenv,e_venv,l_venv) = ch
                   _ -> fail ("bad operator type at application in:\n" ++ show e0 ++ "\n" ++
                               "operator type: " ++ show t1)
            Lam (Tb tb) e ->
-             do tvenv' <- extendM tvenv tb 
+             do tvenv' <- extendTvenv tvenv tb 
                 t <- checkExp (tcenv,tsenv,tvenv',cenv,e_venv,l_venv) e 
                 return (Tforall tb t)
            Lam (Vb (vb@(_,vt))) e ->
@@ -229,7 +342,7 @@ checkExp (tcenv,tsenv,tvenv,cenv,e_venv,l_venv) = ch
                 require (baseKind k)   
                         ("higher-order kind in:\n" ++ show e0 ++ "\n" ++
                          "kind: " ++ show k) 
-                l_venv' <- extendM l_venv vb
+                l_venv' <- extendVenv l_venv vb
                 t <- checkExp (tcenv,tsenv,tvenv,cenv,e_venv,l_venv') e
                 require (not (isUtupleTy vt)) ("lambda-bound unboxed tuple in:\n" ++ show e0) 
                 return (tArrow vt t)
@@ -264,8 +377,8 @@ checkExp (tcenv,tsenv,tvenv,cenv,e_venv,l_venv) = ch
                          ok []                 _  = fail ("missing default alternative in literal case:\n" ++ show e0)
                      in ok as [l] 
                   [Adefault _] -> return ()
-                  [] -> fail ("no alternatives in case:\n" ++ show e0) 
-                l_venv' <- extendM l_venv (v,t)
+                  _ -> fail ("no alternatives in case:\n" ++ show e0) 
+                l_venv' <- extendVenv l_venv (v,t)
                 t:ts <- mapM (checkAlt (tcenv,tsenv,tvenv,cenv,e_venv,l_venv') t) alts  
                 bs <- mapM (equalTy tsenv t) ts
                 require (and bs)
@@ -276,11 +389,18 @@ checkExp (tcenv,tsenv,tvenv,cenv,e_venv,l_venv) = ch
                    " match case return type in:\n" ++ show e0 ++ "\n" ++
                    "alt type: " ++ show t ++ " return type: " ++ show resultTy)
                 return t
-           Cast e t -> 
-             do ch e 
-                checkTy (tcenv,tvenv) t 
-                return t
-           Note s e -> 
+           c@(Cast e t) -> 
+             do eTy <- ch e 
+                k <- checkTy (tcenv,tvenv) t
+                 case k of
+                    (Keq fromTy toTy) -> do
+                        require (eTy == fromTy) ("Type mismatch in cast: c = "
+                             ++ show c ++ " and " ++ show eTy
+                             ++ " and " ++ show fromTy)
+                        return toTy
+                    _ -> fail ("Cast with non-equality kind: " ++ show e 
+                               ++ " and " ++ show t ++ " has kind " ++ show k)
+           Note _ e -> 
              ch e
            External _ t -> 
              do checkTy (tcenv,eempty) t {- external types must be closed -}
@@ -308,7 +428,7 @@ checkAlt (env@(tcenv,tsenv,tvenv,cenv,e_venv,l_venv)) t0 = ch
                         ("existential kinds don't match in:\n" ++ show a0 ++ "\n" ++
                          "kinds declared in data constructor: " ++ show eks ++
                          "kinds declared in case alternative: " ++ show eks') 
-                tvenv' <- foldM extendM tvenv etbs
+                tvenv' <- foldM extendTvenv tvenv etbs
                 {- check term variables -}
                 let vts = map snd vbs
                 mapM_ (\vt -> require ((not . isUtupleTy) vt)
@@ -329,7 +449,7 @@ checkAlt (env@(tcenv,tsenv,tvenv,cenv,e_venv,l_venv)) t0 = ch
                          ("pattern constructor type doesn't match scrutinee type in:\n" ++ show a0 ++ "\n" ++
                           "pattern constructor type: " ++ show ct_res ++ "\n" ++
                           "scrutinee type: " ++ show t0) 
-                l_venv' <- foldM extendM l_venv vbs
+                l_venv' <- foldM extendVenv l_venv vbs
                 t <- checkExp (tcenv,tsenv,tvenv',cenv,e_venv,l_venv') e 
                 checkTy (tcenv,tvenv) t  {- check that existentials don't escape in result type -}
                 return t
@@ -344,25 +464,93 @@ checkAlt (env@(tcenv,tsenv,tvenv,cenv,e_venv,l_venv)) t0 = ch
              checkExp env e
     
 checkTy :: (Tcenv,Tvenv) -> Ty -> CheckResult Kind
-checkTy (tcenv,tvenv) = ch
+checkTy es@(tcenv,tvenv) t = ch t
      where
        ch (Tvar tv) = lookupM tvenv tv
-       ch (Tcon qtc) = qlookupM tcenv_ tcenv eempty qtc
+       ch (Tcon qtc) = do
+         kOrC <- qlookupM tcenv_ tcenv eempty qtc
+         case kOrC of
+            Kind k -> return k
+            Coercion (DefinedCoercion [] (t1,t2)) -> return $ Keq t1 t2
+            Coercion _ -> fail ("Unsaturated coercion app: " ++ show qtc)
        ch (t@(Tapp t1 t2)) = 
-          do k1 <- ch t1
-             k2 <- ch t2
-             case k1 of
-                Karrow k11 k12 ->
-                  do require (k2 `subKindOf` k11) 
-                            ("kinds don't match in type application: " ++ show t ++ "\n" ++
-                             "operator kind: " ++ show k11 ++ "\n" ++
-                             "operand kind: " ++ show k2)              
-                     return k12
-                _ -> fail ("applied type has non-arrow kind: " ++ show t)
+             case splitTyConApp_maybe t of
+               Just (tc, tys) -> do
+                 tcK <- qlookupM tcenv_ tcenv eempty tc 
+                 case tcK of
+                   Kind _ -> checkTapp t1 t2
+                   Coercion (DefinedCoercion tbs (from,to)) -> do
+                     -- makes sure coercion is fully applied
+                     require (length tys == length tbs) $
+                        ("Arity mismatch in coercion app: " ++ show t)
+                     let (tvs, tks) = unzip tbs
+                     argKs <- mapM (checkTy es) tys
+                     require (all (uncurry eqKind) (zip tks argKs))
+                        ("Kind mismatch in coercion app: " ++ show tks 
+                         ++ " and " ++ show argKs ++ " t = " ++ show t)
+                     return $ Keq (substl tvs tys from) (substl tvs tys to)
+               Nothing -> checkTapp t1 t2
+            where checkTapp t1 t2 = do 
+                   k1 <- ch t1
+                   k2 <- ch t2
+                   case k1 of
+                     Karrow k11 k12 ->
+                           case k2 of
+                               Keq eqTy1 eqTy2 -> do
+                                 -- Distribute the type operator over the
+                                 -- coercion
+                                 subK1 <- checkTy es eqTy1
+                                 subK2 <- checkTy es eqTy2
+                                 require (subK2 `subKindOf` k11 && 
+                                          subK1 `subKindOf` k11) $
+                                    kindError
+                                 return $ Keq (Tapp t1 eqTy1) (Tapp t1 eqTy2)
+                              _               -> do
+                                   require (k2 `subKindOf` k11) kindError
+                                   return k12
+                            where kindError = 
+                                    "kinds don't match in type application: "
+                                    ++ show t ++ "\n" ++
+                                   "operator kind: " ++ show k11 ++ "\n" ++
+                                   "operand kind: " ++ show k2 
+                     _ -> fail ("applied type has non-arrow kind: " ++ show t)
+                           
        ch (Tforall tb t) = 
-           do tvenv' <- extendM tvenv tb 
-              checkTy (tcenv,tvenv') t
-    
+           do tvenv' <- extendTvenv tvenv tb 
+              k <- checkTy (tcenv,tvenv') t
+               return $ case k of
+                 -- distribute the forall
+                 Keq t1 t2 -> Keq (Tforall tb t1) (Tforall tb t2)
+                 _         -> k
+       ch (TransCoercion t1 t2) = do
+            k1 <- checkTy es t1
+            k2 <- checkTy es t2
+            case (k1, k2) of
+              (Keq ty1 ty2, Keq ty3 ty4) | ty2 == ty3 ->
+                  return $ Keq ty1 ty4
+              _ -> fail ("Bad kinds in trans. coercion: " ++
+                           show k1 ++ " " ++ show k2)
+       ch (SymCoercion t1) = do
+            k <- checkTy es t1
+            case k of
+               Keq ty1 ty2 -> return $ Keq ty2 ty1
+               _           -> fail ("Bad kind in sym. coercion: "
+                            ++ show k)
+       ch (UnsafeCoercion t1 t2) = do
+            checkTy es t1
+            checkTy es t2
+            return $ Keq t1 t2
+       ch (LeftCoercion t1) = do
+            k <- checkTy es t1
+            case k of
+              Keq (Tapp u _) (Tapp w _) -> return $ Keq u w
+              _ -> fail ("Bad coercion kind in operand of left: " ++ show k)
+       ch (RightCoercion t1) = do
+            k <- checkTy es t1
+            case k of
+              Keq (Tapp _ v) (Tapp _ x) -> return $ Keq v x
+              _ -> fail ("Bad coercion kind in operand of left: " ++ show k)
+
 {- Type equality modulo newtype synonyms. -}
 equalTy :: Tsenv -> Ty -> Ty -> CheckResult Bool
 equalTy tsenv t1 t2 = 
@@ -377,10 +565,28 @@ equalTy tsenv t1 t2 =
            expand (Tforall tb t) = 
              do t' <- expand t
                 return (Tforall tb t')
+            expand (TransCoercion t1 t2) = do
+               exp1 <- expand t1
+               exp2 <- expand t2
+               return $ TransCoercion exp1 exp2
+            expand (SymCoercion t) = do
+               exp <- expand t
+               return $ SymCoercion exp
+            expand (UnsafeCoercion t1 t2) = do
+               exp1 <- expand t1
+               exp2 <- expand t2
+               return $ UnsafeCoercion exp1 exp2
+            expand (LeftCoercion t1) = do
+               exp1 <- expand t1
+               return $ LeftCoercion exp1
+            expand (RightCoercion t1) = do
+               exp1 <- expand t1
+               return $ RightCoercion exp1
            expapp (t@(Tcon (m,tc))) ts = 
              do env <- mlookupM tsenv_ tsenv eempty m
                 case elookup env tc of 
-                   Just (formals,rhs) | (length formals) == (length ts) -> return (substl formals ts rhs)
+                   Just (formals,rhs) | (length formals) == (length ts) ->
+                         return (substl formals ts rhs)
                    _ -> return (foldl Tapp t ts)
            expapp (Tapp t1 t2) ts = 
              do t2' <- expand t2
@@ -388,12 +594,11 @@ equalTy tsenv t1 t2 =
            expapp t ts = 
              do t' <- expand t
                 return (foldl Tapp t' ts)
-    
 
-mlookupM :: (Envs -> Env a b) -> Env a b -> Env a b -> Mname 
+mlookupM :: (Eq a, Show a) => (Envs -> Env a b) -> Env a b -> Env a b -> Mname
           -> CheckResult (Env a b)
 mlookupM _ _ local_env    Nothing            = return local_env
-mlookupM selector external_env _ (Just m) = do
+mlookupM selector external_env local_env (Just m) = do
   mn <- getMname
   if m == mn
      then return external_env
@@ -401,34 +606,33 @@ mlookupM selector external_env _ (Just m) = do
        globalEnv <- getGlobalEnv
        case elookup globalEnv m of
          Just env' -> return (selector env')
-         Nothing -> fail ("Check: undefined module name: " ++ show m)
+         Nothing -> fail ("Check: undefined module name: "
+                      ++ show m ++ show (edomain local_env))
 
-qlookupM :: (Ord a, Show a) => (Envs -> Env a b) -> Env a b -> Env a b 
+qlookupM :: (Ord a, Show a,Show b) => (Envs -> Env a b) -> Env a b -> Env a b
                   -> Qual a -> CheckResult b
-qlookupM selector external_env local_env (m,k) =   
+qlookupM selector external_env local_env (m,k) =
       do env <- mlookupM selector external_env local_env m
-        lookupM env k
-
+         lookupM env k
 
 checkLit :: Lit -> CheckResult Ty
 checkLit (Literal lit t) =
   case lit of
-      -- TODO: restore commented-out stuff.
     Lint _ -> 
-         do {- require (elem t [tIntzh, {- tInt32zh,tInt64zh, -} tWordzh, {- tWord32zh,tWord64zh, -} tAddrzh, tCharzh]) 
-                    ("invalid int literal: " ++ show lit ++ "\n" ++ "type: " ++ show t) -}
+         do require (t `elem` intLitTypes)
+                    ("invalid int literal: " ++ show lit ++ "\n" ++ "type: " ++ show t)
             return t
     Lrational _ ->
-         do {- require (elem t [tFloatzh,tDoublezh]) 
-                    ("invalid rational literal: " ++ show lit ++ "\n" ++ "type: " ++ show t) -}
+         do require (t `elem` ratLitTypes)
+                    ("invalid rational literal: " ++ show lit ++ "\n" ++ "type: " ++ show t)
             return t
     Lchar _ -> 
-         do {- require (t == tCharzh) 
-                    ("invalid char literal: " ++ show lit ++ "\n" ++ "type: " ++ show t)  -}
+         do require (t `elem` charLitTypes)
+                    ("invalid char literal: " ++ show lit ++ "\n" ++ "type: " ++ show t)
             return t   
     Lstring _ ->
-         do {- require (t == tAddrzh) 
-                    ("invalid string literal: " ++ show lit ++ "\n" ++ "type: " ++ show t)  -}
+         do require (t `elem` stringLitTypes)
+                    ("invalid string literal: " ++ show lit ++ "\n" ++ "type: " ++ show t)
             return t
 
 {- Utilities -}
@@ -460,6 +664,11 @@ substl tvs ts t = f (zip tvs ts) t
            Tforall (t',k) (f ((t,Tvar t'):env) t1)
          else 
           Tforall (t,k) (f (filter ((/=t).fst) env) t1)
+       TransCoercion t1 t2 -> TransCoercion (f env t1) (f env t2)
+       SymCoercion t1 -> SymCoercion (f env t1)
+       UnsafeCoercion t1 t2 -> UnsafeCoercion (f env t1) (f env t2)
+       LeftCoercion t1 -> LeftCoercion (f env t1)
+       RightCoercion t1 -> RightCoercion (f env t1)
      where free = foldr union [] (map (freeTvars.snd) env)
            t' = freshTvar free 
    
@@ -469,10 +678,21 @@ freeTvars (Tcon _) = []
 freeTvars (Tvar v) = [v]
 freeTvars (Tapp t1 t2) = (freeTvars t1) `union` (freeTvars t2)
 freeTvars (Tforall (t,_) t1) = delete t (freeTvars t1) 
+freeTvars (TransCoercion t1 t2) = freeTvars t1 `union` freeTvars t2
+freeTvars (SymCoercion t) = freeTvars t
+freeTvars (UnsafeCoercion t1 t2) = freeTvars t1 `union` freeTvars t2
+freeTvars (LeftCoercion t) = freeTvars t
+freeTvars (RightCoercion t) = freeTvars t
 
 {- Return any tvar *not* in the argument list. -}
 freshTvar :: [Tvar] -> Tvar
 freshTvar tvs = maximum ("":tvs) ++ "x" -- one simple way!
 
+primCoercionError :: Show a => a -> b
+primCoercionError s = error $ "Bad coercion application: " ++ show s
+
 -- todo
-reportError s = error $ ("Core parser error: checkExpr failed with " ++ s)
+reportError :: Show a => a -> String -> b
+reportError e s = error $ ("Core type error: checkExpr failed with "
+                   ++ s ++ " and " ++ show e)
+
index 46e8185..ce2a11d 100644 (file)
@@ -1,5 +1,7 @@
 module Core where
 
+import Encoding
+
 import List (elemIndex)
 
 data Module 
@@ -13,7 +15,7 @@ data Cdef
   = Constr (Qual Dcon) [Tbind] [Ty]
 
 -- Newtype coercion
-type Axiom = (Qual Tcon, Kind)
+type Axiom = (Qual Tcon, [Tbind], (Ty,Ty))
 
 data Vdefg 
   = Rec [Vdef]
@@ -51,6 +53,15 @@ data Ty
   | Tcon (Qual Tcon)
   | Tapp Ty Ty
   | Tforall Tbind Ty 
+-- Wired-in coercions:
+-- These are primitive tycons in GHC, but in ext-core,
+-- we make them explicit, to make the typechecker
+-- somewhat more clear. 
+  | TransCoercion Ty Ty
+  | SymCoercion Ty
+  | UnsafeCoercion Ty Ty
+  | LeftCoercion Ty
+  | RightCoercion Ty
 
 data Kind 
   = Klifted
@@ -59,6 +70,25 @@ data Kind
   | Karrow Kind Kind
   | Keq Ty Ty
 
+-- A CoercionKind isn't really a Kind at all, but rather,
+-- corresponds to an arbitrary user-declared axiom.
+-- A tycon whose CoercionKind is (DefinedCoercion <tbs> (from, to))
+-- represents a tycon with arity (length tbs), whose kind is
+-- (from :=: to) (modulo substituting type arguments.
+-- It's not a Kind because a coercion must always be fully applied:
+-- whenever we see a tycon that has such a CoercionKind, it must
+-- be fully applied if it's to be assigned an actual Kind.
+-- So, a CoercionKind *only* appears in the environment (mapping
+-- newtype axioms onto CoercionKinds).
+-- Was that clear??
+data CoercionKind = 
+   DefinedCoercion [Tbind] (Ty,Ty)
+
+-- The type constructor environment maps names that are
+-- either type constructors or coercion names onto either
+-- kinds or coercion kinds.
+data KindOrCoercion = Kind Kind | Coercion CoercionKind
+  
 data Lit = Literal CoreLit Ty
   deriving Eq   -- with nearlyEqualTy 
 
@@ -74,8 +104,8 @@ data CoreLit = Lint Integer
 -- module namespace, either when printing out
 -- Core or (probably preferably) in a 
 -- preprocessor.
--- The empty module name (as in an unqualified name)
--- is represented as Nothing.
+-- We represent the empty module name (as in an unqualified name)
+-- with Nothing.
 
 type Mname = Maybe AnMname
 type AnMname = (Pname, [Id], Id)
@@ -104,8 +134,18 @@ eqKind (Karrow k1 k2) (Karrow l1 l2) = k1 `eqKind` l1
 eqKind _ _ = False -- no Keq kind is ever equal to any other...
                    -- maybe ok for now?
 
---- tjc: I haven't looked at the rest of this file. ---
 
+splitTyConApp_maybe :: Ty -> Maybe (Qual Tcon,[Ty])
+splitTyConApp_maybe (Tvar _) = Nothing
+splitTyConApp_maybe (Tcon t) = Just (t,[])
+splitTyConApp_maybe (Tapp rator rand) = 
+   case (splitTyConApp_maybe rator) of
+      Just (r,rs) -> Just (r,rs++[rand])
+      Nothing     -> case rator of
+                       Tcon tc -> Just (tc,[rand])
+                       _       -> Nothing
+splitTyConApp_maybe t@(Tforall _ _) = Nothing
+           
 {- Doesn't expand out fully applied newtype synonyms
    (for which an environment is needed). -}
 nearlyEqualTy t1 t2 =  eqTy [] [] t1 t2 
@@ -125,6 +165,8 @@ instance Eq Ty where (==) = nearlyEqualTy
 
 subKindOf :: Kind -> Kind -> Bool
 _ `subKindOf` Kopen = True
+(Karrow a1 r1) `subKindOf` (Karrow a2 r2) = 
+  a2 `subKindOf` a1 && (r1 `subKindOf` r2)
 k1 `subKindOf` k2 = k1 `eqKind` k2  -- doesn't worry about higher kinds
 
 baseKind :: Kind -> Bool
@@ -134,17 +176,21 @@ baseKind _ = True
 isPrimVar (Just mn,_) = mn == primMname
 isPrimVar _ = False
 
-primMname = mkBaseMname "Prim"
+primMname = mkPrimMname "Prim"
 errMname  = mkBaseMname "Err"
-mkBaseMname :: Id -> AnMname
+mkBaseMname,mkPrimMname :: Id -> AnMname
 mkBaseMname mn = (basePkg, ghcPrefix, mn)
+mkPrimMname mn = (primPkg, ghcPrefix, mn)
 basePkg = "base"
 mainPkg = "main"
+primPkg = zEncodeString "ghc-prim"
 ghcPrefix = ["GHC"]
 mainPrefix = []
 baseMname = mkBaseMname "Base"
+boolMname = mkPrimMname "Bool"
 mainVar = qual mainMname "main"
 mainMname = (mainPkg, mainPrefix, "Main")
+wrapperMainMname = Just (mainPkg, mainPrefix, "ZCMain")
 
 tcArrow :: Qual Tcon
 tcArrow = (Just primMname, "ZLzmzgZR")
@@ -158,8 +204,6 @@ ktArrow = Karrow Kopen (Karrow Kopen Klifted)
 
 {- Unboxed tuples -}
 
--- tjc: not sure whether anything that follows is right
-
 maxUtuple :: Int
 maxUtuple = 100
 
@@ -178,7 +222,9 @@ isUtupleTy (Tcon tc) = tc `elem` [tcUtuple n | n <- [1..maxUtuple]]
 isUtupleTy _ = False
 
 dcUtuple :: Int -> Qual Dcon
-dcUtuple n = (Just primMname,"ZdwZ" ++ (show n) ++ "H")
+-- TODO: Seems like Z2H etc. appears in ext-core files,
+-- not $wZ2H etc. Is this right?
+dcUtuple n = (Just primMname,"Z" ++ (show n) ++ "H")
 
 isUtupleDc :: Qual Dcon -> Bool
 isUtupleDc dc = dc `elem` [dcUtuple n | n <- [1..maxUtuple]]
index b9d5556..684f31f 100644 (file)
@@ -4,10 +4,15 @@
    Note that, if compiled under GHC, this requires a very large heap to run!
 -}
 
+import Control.Exception
+import Data.List
+import Maybe
 import Monad
-import System.Environment
+import Prelude hiding (catch)
 import System.Cmd
+import System.Environment
 import System.Exit
+import System.FilePath
 
 import Core
 import Printer
@@ -20,9 +25,13 @@ import Interp
 
 -- You may need to change this.
 baseDir = "../../libraries/"
---------                   
+-- change to True to typecheck library files as well as reading type signatures
+typecheckLibs = False 
+
+-- You shouldn't *need* to change anything below this line...                  
+libDir = map (baseDir ++)
 
--- Code for checking that the external and GHC printers print the same results
+-- Code to check that the external and GHC printers print the same results
 testFlag = "-t"
 
 validateResults :: FilePath -> FilePath -> IO ()
@@ -34,71 +43,135 @@ validateResults origFile genFile = do
     _             -> "Error diffing files: " ++ origFile ++ " " ++ genFile
 ------------------------------------------------------------------------------
 
-process :: Bool -> (Check.Menv,[Module]) -> String -> IO (Check.Menv,[Module])
-process doTest (senv,modules) f = 
-       do putStrLn ("Processing " ++ f)
+process :: Bool -> (Check.Menv,[Module]) -> FilePath 
+             -> IO (Check.Menv,[Module])
+process doTest (senv,modules) f = catch
+      (do putStrLn ("Processing " ++ f)
           resultOrErr <- parseCore f
          case resultOrErr of
-           Right m -> do 
+           Right m@(Module mn _ _) -> do 
                         putStrLn "Parse succeeded"
                         let outF = f ++ ".parsed"
                        writeFile outF (show m) 
                         when doTest $ (validateResults f outF)
                        case checkModule senv m of
                          OkC senv' -> 
-                           do putStrLn "Check succeeded"
+                           do putStrLn $ "Check succeeded for " ++ show mn 
                               let m' = prepModule senv' m
-                               {- writeFile (f ++ ".prepped") (show m') -}
-                              case checkModule senv m' of
+                               let (dir,fname) = splitFileName f
+                               let preppedFile = dir </> (fname ++ ".prepped") 
+                               writeFile preppedFile (show m') 
+                              case checkModule senv' m' of
                                  OkC senv'' ->
                                   do putStrLn "Recheck succeeded"
                                       return (senv'',modules ++ [m'])
                                 FailC s -> 
                                   do putStrLn ("Recheck failed: " ++ s)
                                      error "quit"
-                         FailC s -> 
-                           do putStrLn ("Check failed: " ++ s)
-                              error "quit"
-            Left err -> do putStrLn ("Parse failed: " ++ show err)
-                           error "quit"
+                         FailC s -> error ("Typechecking failed: " ++ s)
+            Left err -> error ("Parsing failed: " ++ show err)) handler
+   where handler e = do
+           putStrLn ("WARNING: we caught an exception " ++ show e 
+                     ++ " while processing " ++ f)
+           return (senv, modules)
 
 main = do args <- getArgs
-          let (doTest, fname) = 
+          let (doTest, fnames) = 
                  case args of
-                   (f:fn:_) | f == testFlag -> (True,fn)
-                   (fn:_)                   -> (False,fn)
+                   (f:rest) | f == testFlag -> (True,rest)
+                   rest@(_:_)                   -> (False,rest)
                    _                        -> error $ 
                                               "usage: ./Driver [filename]"
-          mapM_ (process doTest (initialEnv,[])) (libs ++ [fname])
-          (_,modules) <- foldM (process doTest) (initialEnv,[]) (libs ++ [fname])
-         let result = evalProgram modules
-         putStrLn ("Result = " ++ show result)
-         putStrLn "All done"
-            where  libs = map (baseDir ++) ["./ghc-prim/GHC/Generics.hcr",
-                           "./ghc-prim/GHC/PrimopWrappers.hcr",
+          -- Note that we scan over the libraries twice:
+          -- first to gather together all type sigs, then to typecheck them
+          -- (the latter of which doesn't necessarily have to be done every time.)
+          -- This is a hack to avoid dealing with circular dependencies.
+
+          -- notice: scan over libraries *and* input modules first, not just libs
+          topEnv <- mkInitialEnv (map normalise libs `union` map normalise fnames)
+          doOneProgram doTest topEnv fnames
+            where  doOneProgram doTest topEnv fns = do
+                      putStrLn $ "========== Program " ++ (show fns) ++ " ================"
+                      let numToDo = length (typecheckLibraries fns)
+                      (_,modules) <- foldM (process doTest) (topEnv,[]) (typecheckLibraries fns)
+                      let succeeded = length modules
+                      putStrLn ("Finished typechecking. Successfully checked " ++ show succeeded
+                         ++ " out of " ++ show numToDo ++ " modules.")
+                      -- TODO: uncomment once interpreter works
+                      --let result = evalProgram modules
+                      --putStrLn ("Result = " ++ show result)
+                      putStrLn "All done\n============================================="
+
+                   typecheckLibraries = if typecheckLibs then (libs ++) else id
+                   -- Just my guess as to what's needed from the base libs.
+                   -- May well be missing some libraries and have some that
+                   -- aren't commonly used.
+                   -- However, the following is enough to check all of nofib.
+                   -- This points to how nice it would be to have explicit import lists in ext-core.
+                   libs = (libDir ["./ghc-prim/GHC/Generics.hcr",
                            "./ghc-prim/GHC/Bool.hcr",
                            "./ghc-prim/GHC/IntWord64.hcr",
                            "./base/GHC/Base.hcr",
+                           "./base/Data/Tuple.hcr",
+                           "./base/Data/Maybe.hcr",
+                           "./integer-gmp/GHC/Integer.hcr",
                            "./base/GHC/List.hcr",
                            "./base/GHC/Enum.hcr",
+                           "./base/Data/Ord.hcr",
+                           "./base/Data/String.hcr",
+                           "./base/Data/Either.hcr",
                            "./base/GHC/Show.hcr",
                            "./base/GHC/Num.hcr",
                            "./base/GHC/ST.hcr",
-                           "./base/GHC/Real.hcr",
                            "./base/GHC/STRef.hcr",
                            "./base/GHC/Arr.hcr",
-                           "./base/GHC/Float.hcr",
-                           "./base/GHC/Read.hcr",
-                           "./base/GHC/Ptr.hcr",
-                           "./base/GHC/Word.hcr",
+                           "./base/GHC/Real.hcr",
+                           "./base/Control/Monad.hcr",
                            "./base/GHC/Int.hcr",
                            "./base/GHC/Unicode.hcr",
-                           "./base/GHC/IOBase.hcr",
+                           "./base/Text/ParserCombinators/ReadP.hcr",
+                           "./base/Text/Read/Lex.hcr",
+                           "./base/Text/ParserCombinators/ReadPrec.hcr",
+                           "./base/GHC/Read.hcr",
+                           "./base/GHC/Word.hcr",
+                           "./base/Data/HashTable.hcr",
+                           "./base/Unsafe/Coerce.hcr",
+                           "./base/Foreign/Storable.hcr",
+                           "./base/Foreign/C/Types.hcr",
+                           "./base/GHC/IOBase.hcr",                           
+                           "./base/GHC/ForeignPtr.hcr",
+                           "./base/Data/Typeable.hcr",
+                           "./base/Data/Dynamic.hcr",
                            "./base/GHC/Err.hcr",
+                           "./base/Data/List.hcr",
+                           "./base/Data/Char.hcr",
+                           "./base/GHC/Pack.hcr",
+                           "./base/GHC/Storable.hcr",
+                           "./base/System/IO/Error.hcr",
+                           "./base/Foreign/Ptr.hcr",
+                           "./base/Foreign/Marshal/Error.hcr",
+                           "./base/Foreign/ForeignPtr.hcr",
+                           "./base/Foreign/Marshal/Alloc.hcr",
+                           "./base/Foreign/Marshal/Utils.hcr",
+                           "./base/Foreign/Marshal/Array.hcr",
+                           "./base/Foreign/C/String.hcr",
+                           "./base/Foreign/C/Error.hcr",
+                           "./base/Foreign/C.hcr",
+                           "./base/System/IO/Unsafe.hcr",
+                           "./base/Foreign/Marshal.hcr",
+                           "./base/Foreign/StablePtr.hcr",
+                           "./base/Foreign.hcr",
+                           "./base/System/Posix/Types.hcr",
+                           "./base/System/Posix/Internals.hcr",
+                           "./base/GHC/Conc.hcr",
+                           "./base/Control/Exception.hcr",
+                           "./base/GHC/TopHandler.hcr",
+                           "./base/Data/Bits.hcr",
+                           "./base/Numeric.hcr",
+                           "./base/GHC/Ptr.hcr",
+                           "./base/GHC/Float.hcr",
                            "./base/GHC/Exception.hcr",
                            "./base/GHC/Stable.hcr",
-                           "./base/GHC/Storable.hcr",
-                           "./base/GHC/Pack.hcr",
                            "./base/GHC/Weak.hcr",
                            "./base/GHC/Handle.hcr",
                            "./base/GHC/IO.hcr",
@@ -106,34 +179,32 @@ main = do args <- getArgs
                            "./base/GHC/Environment.hcr",
                            "./base/GHC/Exts.hcr",
                            "./base/GHC/PArr.hcr",
-                           "./base/GHC/TopHandler.hcr",
-                           "./base/GHC/Desugar.hcr",
-                           "./base/Data/Ord.hcr",
-                           "./base/Data/Maybe.hcr",
-                           "./base/Data/Bits.hcr",
-                           "./base/Data/STRef/Lazy.hcr",
+                           "./base/System/IO.hcr",
+                           "./base/System/Environment.hcr",
                            "./base/Data/Generics/Basics.hcr",
-                           "./base/Data/Generics/Aliases.hcr",
-                           "./base/Data/Generics/Twins.hcr",
-                           "./base/Data/Generics/Instances.hcr",
-                           "./base/Data/Generics/Text.hcr",
-                           "./base/Data/Generics/Schemes.hcr",
-                           "./base/Data/Tuple.hcr",
-                           "./base/Data/String.hcr",
-                           "./base/Data/Either.hcr",
-                           "./base/Data/Char.hcr",
-                           "./base/Data/List.hcr",
-                           "./base/Data/HashTable.hcr",
-                           "./base/Data/Typeable.hcr",
-                           "./base/Data/Dynamic.hcr",
-                           "./base/Data/Function.hcr",
-                           "./base/Data/IORef.hcr",
-                           "./base/Data/Fixed.hcr",
-                           "./base/Data/Monoid.hcr",
-                           "./base/Data/Ratio.hcr",
-                           "./base/Data/STRef.hcr",
-                           "./base/Data/Version.hcr",
                            "./base/Data/Complex.hcr",
-                           "./base/Data/Unique.hcr",
-                           "./base/Data/Foldable.hcr",
-                           "./base/Data/Traversable.hcr"]
\ No newline at end of file
+                           "./array/Data/Array/Base.hcr",
+                           "./base/System/Exit.hcr",
+                           "./base/Data/Ratio.hcr",
+                           "./base/Control/Monad/ST/Lazy.hcr",
+                           "./base/Prelude.hcr",
+                           "./base/Control/Concurrent/MVar.hcr",
+                           "./base/Data/Foldable.hcr"])
+
+mkInitialEnv :: [FilePath] -> IO Menv
+mkInitialEnv libs = foldM mkTypeEnv initialEnv libs
+
+mkTypeEnv :: Menv -> FilePath -> IO Menv
+mkTypeEnv globalEnv fn = catch (do
+  putStrLn $ "mkTypeEnv: reading library " ++ fn
+  resultOrErr <- parseCore fn
+  case resultOrErr of
+    Right mod@(Module mn _ _) -> do
+       let newE = envsModule globalEnv mod
+       return newE 
+    Left  err -> do putStrLn ("Failed to parse library module: " ++ show err)
+                    error "quit") handler
+  where handler e = do
+           putStrLn ("WARNING: mkTypeEnv caught an exception " ++ show e 
+                     ++ " while processing " ++ fn)
+           return globalEnv
index 6f6973c..642df00 100644 (file)
@@ -1,6 +1,6 @@
 {- Environments.
-   Uses lists for simplicity and to make the semantics clear.
-   A real implementation should use balanced trees or hash tables.
+  The original version used lists. I changed it to use Data.Map.
+  Sadly it doesn't seem to matter much. --tjc
 -}
 
 module Env (Env,
@@ -9,36 +9,41 @@ module Env (Env,
            eextend,
             edomain,
            efromlist,
+            etolist,
            efilter,
            eremove)
 where
 
-import List
+import qualified Data.Map as M
+import Data.List
 
-data Env a b = Env [(a,b)] 
- deriving (Show)
+data Env a b = Env (M.Map a b)
+ deriving Show
 
 eempty :: Env a b 
-eempty = Env []
+eempty = Env M.empty
 
 {- In case of duplicates, returns most recently added entry. -}
-elookup :: (Eq a) => Env a b -> a -> Maybe b
-elookup (Env l) k = lookup k l 
+elookup :: (Eq a, Ord a) => Env a b -> a -> Maybe b
+elookup (Env l) k = M.lookup k l 
 
 {- May hide existing entries. -}
-eextend :: Env a b -> (a,b) -> Env a b
-eextend (Env l) (k,d) = Env ((k,d):l)
+eextend :: Ord a => Env a b -> (a,b) -> Env a b
+eextend (Env l) (k,d) = Env (M.insert k d l)
 
 edomain :: (Eq a) => Env a b -> [a]
-edomain (Env l) = nub (map fst l)
+edomain (Env l) = M.keys l
 
 {- In case of duplicates, first entry hides others. -}
-efromlist :: [(a,b)] -> Env a b
-efromlist l = Env l
+efromlist :: Ord a => [(a,b)] -> Env a b
+efromlist = Env . M.fromList
 
-eremove :: (Eq a)  => Env a b -> a -> Env a b
-eremove (Env l) k = Env (filter ((/= k).fst) l)
+etolist :: Env a b -> [(a,b)]
+etolist (Env l) = M.toList l
 
-efilter :: Env a b -> (a -> Bool) -> Env a b
-efilter (Env l) p = Env (filter (p.fst) l)
+eremove :: (Eq a, Ord a)  => Env a b -> a -> Env a b
+eremove (Env l) k = Env (M.delete k l)
+
+efilter :: Ord a => Env a b -> (a -> Bool) -> Env a b
+efilter (Env l) p = Env (M.filterWithKey (\ k a -> p k) l)
 
index f5f9857..e730012 100644 (file)
@@ -15,7 +15,7 @@ The only major omission is garbage collection.
 Just a sampling of primitive types and operators are included.
 -}
 
-module Interp where
+module Interp ( evalProgram ) where
 
 import Core
 import Printer
index e302387..7015105 100644 (file)
@@ -1,5 +1,23 @@
-all:   Check.hs Core.hs Driver.hs Env.hs Interp.hs ParsecParser.hs ParseGlue.hs Prep.hs Prims.hs Printer.hs
-       ghc --make -fglasgow-exts -o Driver Driver.hs
+all:   Check.hs Core.hs Driver.hs Env.hs Interp.hs ParsecParser.hs ParseGlue.hs Prep.hs PrimCoercions.hs Prims.hs Printer.hs
+       ghc -O2 --make -fglasgow-exts -o Driver Driver.hs
+
+# Run this when the primops.txt file changes
+prims:  ../../compiler/prelude/primops.txt
+       ../genprimopcode/genprimopcode --make-ext-core-source < ../../compiler/prelude/primops.txt > PrimEnv.hs
 
 #Parser.hs: Parser.y
-#      happy -ad -ihappy.debug -o Parser.hs Parser.y
\ No newline at end of file
+#      happy -ad -ihappy.debug -o Parser.hs Parser.y
+
+# The following assumes that you've built all the GHC libs with -fext-core...
+libtest: all
+       ./Driver `find ../../libraries -print | grep .hcr$$ | grep -v bootstrapping`
+
+# ...or built all the nofib programs with -fext-core.
+nofibtest: all
+       ./Driver `find ../../nofib -print | grep .hcr$$`
+
+clean:
+       rm -f Driver *.hi *.o
+
+reallyclean: clean
+       rm PrimEnv.hs
\ No newline at end of file
index 8602bdc..b539962 100644 (file)
@@ -1,10 +1,14 @@
+{-# OPTIONS -Wall -Werror -fno-warn-missing-signatures #-}
+
 module ParsecParser where
 
 import Core
 import ParseGlue
+import Check
+import PrimCoercions
 
 import Text.ParserCombinators.Parsec
-import Text.ParserCombinators.Parsec.Expr
+--import Text.ParserCombinators.Parsec.Expr
 import qualified Text.ParserCombinators.Parsec.Token as P
 import Text.ParserCombinators.Parsec.Language
 import Data.Ratio
@@ -31,7 +35,9 @@ coreModuleName = do
    return (pkgName, modHierarchy, baseName)
 
 corePackageName :: Parser Pname
-corePackageName = identifier
+-- Package names can be lowercase or uppercase!
+-- TODO: update docs
+corePackageName = identifier <|> upperName
 
 coreHierModuleNames :: Parser ([Id], Id)
 coreHierModuleNames = do
@@ -83,7 +89,7 @@ coreNewtypeDecl = do
 
 coreQualifiedCon :: Parser (Mname, Id)
 coreQualifiedCon = coreQualifiedGen upperName
-
 coreQualifiedName = coreQualifiedGen identifier
 
 coreQualifiedGen p = do
@@ -110,10 +116,12 @@ coreAxiom :: Parser Axiom
 coreAxiom = parens (do
               coercionName <- coreQualifiedCon
               whiteSpace
+              tbs <- coreTbinds
+              whiteSpace
               symbol "::"
               whiteSpace
-              coercionKind <- coreKind
-              return (coercionName, coercionKind))
+              coercionK <- try equalityKind <|> parens equalityKind
+              return (coercionName, tbs, coercionK))
 
 coreTbinds :: Parser [Tbind]
 coreTbinds = many coreTbind 
@@ -145,7 +153,7 @@ coreCdef = do
   tBinds      <- try $ coreTbindsGen (symbol "@")
   -- This should be equivalent to (many coreAty)
   -- But it isn't. WHY??
-  tys         <- sepBy coreAty whiteSpace
+  tys         <- sepBy coreAtySaturated whiteSpace
   return $ Constr dataConName tBinds tys
 
 coreTRep :: Parser (Maybe Ty)
@@ -168,43 +176,71 @@ coreType = coreForallTy <|> (do
                          stuff -> foldl Tapp (Tcon tcArrow) (hd:stuff))
 
 coreBty :: Parser Ty
-coreBty = arrowThing coreAty coreAty whiteSpace Tapp
-
-arrowThing :: Parser a -> Parser a -> Parser b -> (a -> a -> a) -> Parser a
-arrowThing hdThing restThing sep op = do
-  hd <- hdThing
+coreBty = do
+  hd <- coreAty
                          -- The "try" is necessary:
                          -- otherwise, parsing "T " fails rather
                          -- than returning "T".
-  maybeRest <- option [] (many1 (try (sep >> restThing)))
-  return $ case maybeRest of 
-             [] -> hd
-             stuff -> foldl op hd maybeRest
-
-coreAppTy :: Parser Ty
-coreAppTy = do 
-  bTy <- try coreBty
-  whiteSpace
-  aTy <- try coreAty
-  return $ Tapp bTy aTy
-
-coreAty = try coreTcon <|> try coreTvar <|> parens coreType
-
+  maybeRest <- option [] (many1 (try (whiteSpace >> coreAtySaturated)))
+  return $ (case hd of
+             -- so I'm not sure I like this... it's basically doing
+             -- typechecking (kind-checking?) in the parser.
+             -- However, the type syntax as defined in Core.hs sort of
+             -- forces it.
+             ATy t     -> foldl Tapp t maybeRest
+             Trans k   -> app k 2 maybeRest "trans"
+             Sym k     -> app k 1 maybeRest "sym"
+             Unsafe k  -> app k 2 maybeRest "unsafe"
+             LeftCo k  -> app k 1 maybeRest "left"
+             RightCo k -> app k 1 maybeRest "right")
+                 where app k arity args _ | length args == arity = k args
+                       app _ _ args err = 
+                           primCoercionError (err ++ 
+                             ("Args were: " ++ show args))
+
+coreAtySaturated :: Parser Ty
+coreAtySaturated = do
+   t <- coreAty
+   case t of
+     ATy ty -> return ty
+     _     -> unexpected "coercion ty"
+
+coreAty :: Parser ATyOp
+coreAty = try coreTcon <|> ((try coreTvar <|> parens coreType)
+                             >>= return . ATy)
 coreTvar :: Parser Ty
 coreTvar = try identifier >>= (return . Tvar)
 
-coreTcon :: Parser Ty
+coreTcon :: Parser ATyOp
 -- TODO: Change the grammar
 -- A Tcon can be an uppercase type constructor
 -- or a lowercase (always qualified) coercion variable
-coreTcon = (try coreQualifiedCon <|> coreRequiredQualifiedName) 
-             >>= (return . Tcon)
-
-coreTyApp :: Parser Ty
-coreTyApp = do
-  operTy <- coreType
-  randTy <- coreType
-  return $ Tapp operTy randTy
+coreTcon =  
+         -- Special case is first so that (CoUnsafe .. ..) gets parsed as
+         -- a prim. coercion app and not a Tcon app.
+         -- But the whole thing is so bogus.
+        try (do
+                                    -- the "try"s are crucial; they force
+                                    -- backtracking
+           maybeCoercion <- choice [try symCo, try transCo, try unsafeCo,
+                                    try leftCo, rightCo]
+           return $ case maybeCoercion of
+              TransC  -> Trans (\ [x,y] -> TransCoercion x y)
+              SymC    -> Sym (\ [x] -> SymCoercion x)
+              UnsafeC -> Unsafe (\ [x,y] -> UnsafeCoercion x y)
+              LeftC   -> LeftCo (\ [x] -> LeftCoercion x)
+              RightC  -> RightCo (\ [x] -> RightCoercion x))
+    <|> (coreQualifiedCon >>= (return . ATy . Tcon))
+
+data CoercionTy = TransC | SymC | UnsafeC | LeftC | RightC
+
+symCo, transCo, unsafeCo :: Parser CoercionTy
+-- Would be better not to wire these in quite this way. Sigh
+symCo    = string "^ghczmprim:GHCziPrim.sym"      >> return SymC
+transCo  = string "^ghczmprim:GHCziPrim.trans"    >> return TransC 
+unsafeCo = string "^ghczmprim:GHCziPrim.CoUnsafe" >> return UnsafeC
+leftCo   = string "^ghczmprim:GHCziPrim.left"     >> return LeftC
+rightCo  = string "^ghczmprim:GHCziPrim.right"    >> return RightC
 
 coreFunTy :: Parser Ty
 coreFunTy = do
@@ -228,12 +264,10 @@ coreKind :: Parser Kind
 coreKind = do
   hd <- coreAtomicKind 
   maybeRest <- option [] (many1 (symbol "->" >> coreKind))
-  return $ case maybeRest of
-             [] -> hd
-             stuff -> foldl Karrow hd maybeRest
+  return $ foldl Karrow hd maybeRest
 
 coreAtomicKind = try liftedKind <|> try unliftedKind 
-       <|> try openKind <|> try (parens equalityKind) 
+       <|> try openKind {- <|> try (parens equalityKind) -}
        <|> try (parens coreKind)
 
 liftedKind = do
@@ -252,7 +286,19 @@ equalityKind = do
   ty1 <- coreBty
   symbol ":=:"
   ty2 <- coreBty
-  return $ Keq ty1 ty2
+  return (ty1, ty2)
+
+-- Only used internally within the parser:
+-- represents either a Tcon, or a continuation
+-- for a primitive coercion
+data ATyOp = 
+   ATy Ty
+ | Trans ([Ty] -> Ty)
+ | Sym ([Ty] -> Ty)
+ | Unsafe ([Ty] -> Ty)
+ | LeftCo ([Ty] -> Ty)
+ | RightCo ([Ty] -> Ty)
+
 coreVdefGroups :: Parser [Vdefg]
 coreVdefGroups = option [] (do
   theFirstVdef <- coreVdefg
@@ -290,7 +336,7 @@ coreAtomicExp = do
   return res
 
 coreFullExp = (choice [coreLam, coreLet,
-  coreCase, coreCast, coreNote, coreExternal]) <|> (try coreAppExp)
+  coreCase, coreCast, coreNote, coreExternal, coreLabel]) <|> (try coreAppExp)
 -- The "try" is necessary so that we backtrack
 -- when we see a var (that is not an app)
     <|> coreAtomicExp
@@ -306,7 +352,7 @@ coreAppExp = do
     args <- many1 (whiteSpace >> ((coreAtomicExp >>= (return . Left)) <|>
              -- note this MUST be coreAty, not coreType, because otherwise:
              -- "A @ B c" gets parsed as "A @ (B c)"
-             ((symbol "@" >> coreAty) >>= (return . Right))))
+             ((symbol "@" >> coreAtySaturated) >>= (return . Right))))
     return $ foldl (\ op ->
                      either (App op) (Appt op)) oper args
 
@@ -339,7 +385,7 @@ coreLet = do
   return $ Let vdefg body 
 coreCase = do
   reserved "case"
-  ty <- coreAty
+  ty <- coreAtySaturated
   scrut <- coreAtomicExp
   reserved "of"
   vBind <- parens lambdaBind
@@ -351,21 +397,33 @@ coreCast = do
 -- The parens are CRUCIAL, o/w it's ambiguous
   body <- try (parens coreFullExp)
   whiteSpace
-  ty <- try coreAty
+  ty <- try coreAtySaturated
   return $ Cast body ty
 coreNote = do
   reserved "note"
   s <- stringLiteral
   e <- coreFullExp
   return $ Note s e
-coreExternal = do
+coreExternal = (do
   reserved "external"
   -- TODO: This isn't in the grammar, but GHC
   -- always prints "external ccall". investigate...
   symbol "ccall"
   s <- stringLiteral
-  t <- coreAty
-  return $ External s t
+  t <- coreAtySaturated
+  return $ External s t) <|>
+    -- TODO: I don't really understand what this does
+                (do
+    reserved "dynexternal"
+    symbol "ccall"
+    t <- coreAtySaturated
+    return $ External "[dynamic]" t)
+coreLabel = do
+-- TODO: Totally punting this, but it needs to go in the grammar
+-- or not at all
+  reserved "label"
+  s <- stringLiteral
+  return $ External s tAddrzh
 
 coreLambdaBinds = many1 coreBind
 
index 4528d54..05250af 100644 (file)
@@ -1,3 +1,4 @@
+{-# OPTIONS -Wall -fno-warn-name-shadowing #-}
 {- 
 Preprocess a module to normalize it in the following ways:
        (1) Saturate all constructor and primop applications. 
@@ -10,14 +11,17 @@ After these preprocessing steps, Core can be interpreted (or given an operationa
 
 module Prep where
 
+import Data.Either
+
 import Prims
 import Core
-import Printer
 import Env
 import Check
 
+import Data.List
+
 primArgTys :: Env Var [Ty]
-primArgTys = efromlist (map f Prims.primVals)
+primArgTys = efromlist (map f (etolist (venv_ primEnv)))
   where f (v,t) = (v,atys)
              where (_,atys,_) = splitTy t
 
@@ -25,6 +29,7 @@ prepModule :: Menv -> Module -> Module
 prepModule globalEnv (Module mn tdefs vdefgs) = 
     Module mn tdefs vdefgs' 
   where
+
     (_,vdefgs') = foldl prepTopVdefg (eempty,[]) vdefgs
 
     prepTopVdefg (venv,vdefgs) vdefg = (venv',vdefgs ++ [vdefg'])
@@ -32,35 +37,36 @@ prepModule globalEnv (Module mn tdefs vdefgs) =
  
     prepVdefg (env@(venv,_)) (Nonrec(Vdef((Nothing,x),t,e))) = 
        (eextend venv (x,t), Nonrec(Vdef((Nothing,x),t,prepExp env e)))
-    prepVdefg (env@(venv,_))  (Nonrec(Vdef(qx,t,e))) = 
-       (venv, Nonrec(Vdef(qx,t,prepExp env e)))
+    prepVdefg (env@(venv,_))  (Nonrec(Vdef(qx,t,e))) =
+       (venv, Nonrec(Vdef(qx,t,prepExp env e)))
     prepVdefg (venv,tvenv) (Rec vdefs) = 
-       (venv',Rec [Vdef(qx,t,prepExp (venv',tvenv) e) | Vdef(qx,t,e) <- vdefs])
+       (venv',Rec [ Vdef(qx,t,prepExp (venv',tvenv) e) | Vdef(qx,t,e) <- vdefs])
        where venv' = foldl eextend venv [(x,t) | Vdef((Nothing,x),t,_) <- vdefs]
 
-    prepExp env (Var qv) = Var qv
-    prepExp env (Dcon qdc) = Dcon qdc
-    prepExp env (Lit l) = Lit l
+    prepExp _ (Var qv) = Var qv
+    prepExp _ (Dcon qdc) = Dcon qdc
+    prepExp _ (Lit l) = Lit l
     prepExp env e@(App _ _) = unwindApp env e []
     prepExp env e@(Appt _ _) = unwindApp env e []
     prepExp (venv,tvenv) (Lam (Vb vb) e) = Lam (Vb vb) (prepExp (eextend venv vb,tvenv) e)
     prepExp (venv,tvenv) (Lam (Tb tb) e) = Lam (Tb tb) (prepExp (venv,eextend tvenv tb) e)
     prepExp env@(venv,tvenv) (Let (Nonrec(Vdef((Nothing,x),t,b))) e) 
-        | kindof tvenv t `eqKind` Kunlifted && suspends b =
+        | (kindOfTy tvenv t `eqKind` Kunlifted && suspends b) = 
             -- There are two places where we call the typechecker, one of them
             -- here.
             -- We need to know the type of the let body in order to construct
             -- a case expression. 
-            let eTy = typeOfExp env e in
-               Case (prepExp env b) (x,t) 
+                                -- need to extend the env with the let-bound var too!
+            let eTy = typeOfExp (eextend venv (x, t), tvenv) e in
+               Case (prepExp env b) (x,t) 
                   eTy
-                  [Adefault (prepExp (eextend venv (x,t),tvenv) e)]
+                  [Adefault (prepExp (eextend venv (x,t),tvenv) e)] 
     prepExp (venv,tvenv) (Let vdefg e) =  Let vdefg' (prepExp (venv',tvenv) e)
                where (venv',vdefg') = prepVdefg (venv,tvenv) vdefg
     prepExp env@(venv,tvenv) (Case e vb t alts) = Case (prepExp env e) vb t (map (prepAlt (eextend venv vb,tvenv)) alts)
     prepExp env (Cast e t) = Cast (prepExp env e) t
     prepExp env (Note s e) = Note s (prepExp env e)
-    prepExp env (External s t) = External s t
+    prepExp _ (External s t) = External s t
 
     prepAlt (venv,tvenv) (Acon qdc tbs vbs e) = Acon qdc tbs vbs (prepExp (foldl eextend venv vbs,foldl eextend tvenv tbs) e)
     prepAlt env (Alit l e) = Alit l (prepExp env e)
@@ -69,7 +75,7 @@ prepModule globalEnv (Module mn tdefs vdefgs) =
 
     unwindApp env (App e1 e2) as = unwindApp env e1 (Left e2:as)
     unwindApp env (Appt e t) as  = unwindApp env e (Right t:as)
-    unwindApp env (op@(Dcon qdc)) as =
+    unwindApp env (op@(Dcon qdc)) as = 
         etaExpand (drop n atys) (rewindApp env op as)
         where (tbs,atys0,_) = splitTy (qlookup cenv_ eempty qdc)
              atys = map (substl (map fst tbs) ts) atys0
@@ -82,25 +88,40 @@ prepModule globalEnv (Module mn tdefs vdefgs) =
     unwindApp env op as = rewindApp env op as
 
 
-    etaExpand ts e = foldl g e [('$':(show i),t) | (i,t) <- zip [1..] ts]
-         where g e (v,t) = Lam (Vb(v,t)) (App e (Var (unqual v)))
+    etaExpand :: [Ty] -> Exp -> Exp
+    etaExpand ts e = 
+         let args = [('$':(show i),t) | (i,t) <- zip [(1::Integer)..] ts] in
+          foldr (\ (v,t) e -> Lam (Vb (v,t)) e)
+              (foldl (\ e (v,_) -> App e (Var (unqual v))) e args)
+              args
 
-    rewindApp env e [] = e
-    rewindApp env@(venv,tvenv) e1 (Left e2:as) | kindof tvenv t `eqKind` Kunlifted && suspends e2 =
+    rewindApp _ e [] = e
+    rewindApp env@(venv,tvenv) e1 (Left e2:as) | kindOfTy tvenv t `eqKind` Kunlifted && suspends e2 =
        -- This is the other place where we call the typechecker.
-       Case (prepExp env' e2) (v,t) (typeOfExp env rhs) [Adefault rhs]
-        where rhs = (rewindApp env' (App e1 (Var (unqual v))) as)
-              v = freshVar venv
+        Case newScrut (v,t) (typeOfExp env' rhs) [Adefault rhs]
+        where newScrut = prepExp env e2
+              rhs = (rewindApp env' (App e1 (Var (unqual v))) as)
+                 -- note:
+                 -- e1 gets moved inside rhs. so if we pick a case
+                 -- var name (outside e1) equal to a name bound *inside*
+                 -- e1, the binding *inside* e1 will shadow "v"
+                 -- Which would be name capture!
+                 -- So, we pass the bound vars of e1 to freshVar along with
+                 -- the domain of the current env.
+              v = freshVar (edomain venv `union` (boundVars e1))
               t = typeOfExp env e2
               env' = (eextend venv (v,t),tvenv)
     rewindApp env e1 (Left e2:as) = rewindApp env (App e1 (prepExp env e2)) as
     rewindApp env e (Right t:as) = rewindApp env (Appt e t) as
 
-    freshVar venv = maximum ("":edomain venv) ++ "x" -- one simple way!
+    freshVar vs = maximum ("":vs) ++ "x" -- one simple way!
 
     typeOfExp :: (Venv, Tvenv) -> Exp -> Ty
     typeOfExp = uncurry (checkExpr mn globalEnv tdefs)
 
+    kindOfTy :: Tvenv -> Ty -> Kind
+    kindOfTy tvenv = checkType mn globalEnv tdefs tvenv
+
     {- Return false for those expressions for which Interp.suspendExp builds a thunk. -}
     suspends (Var _) = False
     suspends (Lit _) = False
@@ -112,16 +133,6 @@ prepModule globalEnv (Module mn tdefs vdefgs) =
     suspends (External _ _) = False
     suspends _ = True
 
-    kindof :: Tvenv -> Ty -> Kind
-    kindof tvenv (Tvar tv) = 
-      case elookup tvenv tv of
-       Just k -> k
-        Nothing -> error ("impossible Tyvar " ++ show tv)
-    kindof tvenv (Tcon qtc) = qlookup tcenv_ eempty qtc
-    kindof tvenv (Tapp t1 t2) = k2
-       where Karrow _ k2 = kindof tvenv t1
-    kindof tvenv (Tforall _ t) = kindof tvenv t
-
     mlookup :: (Envs -> Env a b) -> Env a b -> Mname -> Env a b
     mlookup _ local_env Nothing = local_env
     mlookup selector _  (Just m) =   
@@ -135,3 +146,29 @@ prepModule globalEnv (Module mn tdefs vdefgs) =
         Just v -> v
         Nothing -> error ("undefined identifier: " ++ show k)
 
+boundVars :: Exp -> [Id]
+boundVars (Lam (Vb (v,_)) e) = [v] `union` boundVars e
+boundVars (Lam _ e) = boundVars e
+boundVars (Let vds e) = (boundVarsVdefs vds) `union` boundVars e
+boundVars (Case scrut (v,_) _ alts) = 
+   [v] `union` (boundVars scrut) `union` boundVarsAlts alts
+boundVars (Cast e _) = boundVars e
+boundVars (Note _ e) = boundVars e
+boundVars (App e1 e2) = boundVars e1 `union` boundVars e2
+boundVars (Appt e _) = boundVars e
+boundVars _ = []
+
+boundVarsVdefs :: Vdefg -> [Id]
+boundVarsVdefs (Rec vds) = nub (concatMap boundVarsVdef vds)
+boundVarsVdefs (Nonrec vd) = boundVarsVdef vd
+
+boundVarsVdef :: Vdef -> [Id]
+boundVarsVdef (Vdef ((_,v),_,e)) = [v] `union` boundVars e
+
+boundVarsAlts :: [Alt] -> [Var]
+boundVarsAlts as = nub (concatMap boundVarsAlt as)
+
+boundVarsAlt :: Alt -> [Var]
+boundVarsAlt (Acon _ _ vbs e) = (map fst vbs) `union` (boundVars e)
+boundVarsAlt (Alit _ e) = boundVars e
+boundVarsAlt (Adefault e) = boundVars e
\ No newline at end of file
diff --git a/utils/ext-core/PrimCoercions.hs b/utils/ext-core/PrimCoercions.hs
new file mode 100644 (file)
index 0000000..7536cb6
--- /dev/null
@@ -0,0 +1,24 @@
+{-# OPTIONS -Wall -fno-warn-missing-signatures #-}
+module PrimCoercions where
+import Core
+
+-- Stuff the parser needs to know about
+
+pv :: a -> Qual a
+pv = qual primMname
+
+pvz :: Id -> Qual Id
+pvz = (qual primMname) . (++ "zh")
+
+{- Coercions -}
+symCoercion, transCoercion, unsafeCoercion :: Qual Tcon
+symCoercion    = pv "sym"
+transCoercion  = pv "trans"
+unsafeCoercion = pv "CoUnsafe"
+leftCoercion   = pv "left"
+rightCoercion   = pv "right"
+
+{- Addrzh -}
+tcAddrzh = pvz "Addr"
+tAddrzh = Tcon tcAddrzh
+ktAddrzh = Kunlifted
index efcd60e..d061200 100644 (file)
@@ -1,21 +1,36 @@
-{- This module really should be auto-generated from the master primops.txt file. 
-   It is roughly correct (but may be slightly incomplete) wrt/ GHC5.02. -}
+{-# OPTIONS -Wall #-}
 
-module Prims where
+{- This module contains a few primitive types that need to be wired in.
+   Most are defined in PrimEnv, which is automatically generated from
+   GHC's primops.txt. -}
+
+module Prims(initialEnv, primEnv) where
 
 import Core
 import Env
 import Check
+import PrimCoercions
+
+import PrimEnv
 
 initialEnv :: Menv
 initialEnv = efromlist [(primMname,primEnv),
                     (errMname,errorEnv)]
 
 primEnv :: Envs
-primEnv = Envs {tcenv_=efromlist primTcs,
+-- Tediously, we add defs for ByteArray# etc. because these are
+-- declared as ByteArr# (etc.) in primops.txt, and GHC has
+-- ByteArray# etc. wired-in.
+-- At least this is better than when all primops were wired-in here.
+primEnv = Envs {tcenv_=efromlist $ map (\ (t,k) -> (t,Kind k)) $ 
+                  [(snd tcByteArrayzh,ktByteArrayzh), 
+                   (snd tcMutableArrayzh, ktMutableArrayzh),
+                   (snd tcMutableByteArrayzh, ktMutableByteArrayzh)] ++
+                 ([(snd $ tcUtuple n, ktUtuple n) | n <- [1..maxUtuple]] 
+                   ++ ((snd tcArrow,ktArrow):primTcs)),
                tsenv_=eempty,
                cenv_=efromlist primDcs,
-               venv_=efromlist primVals}
+               venv_=efromlist (opsState ++ primVals)}
 
 errorEnv :: Envs
 errorEnv = Envs {tcenv_=eempty,
@@ -23,816 +38,70 @@ errorEnv = Envs {tcenv_=eempty,
                 cenv_=eempty,
                 venv_=efromlist errorVals}
 
-{- Components of static environment -}
-
-primTcs :: [(Tcon,Kind)]
-primTcs = 
-       map (\ ((m,tc),k) -> (tc,k))
-       ([(tcArrow,ktArrow),
-        (tcAddrzh,ktAddrzh),
-        (tcCharzh,ktCharzh),
-        (tcDoublezh,ktDoublezh),
-        (tcFloatzh,ktFloatzh),
-        (tcIntzh,ktIntzh),
-        (tcInt32zh,ktInt32zh),
-        (tcInt64zh,ktInt64zh),
-        (tcWordzh,ktWordzh),
-        (tcWord32zh,ktWord32zh),
-        (tcWord64zh,ktWord64zh),
-        (tcRealWorld, ktRealWorld),
-        (tcStatezh, ktStatezh),
-        (tcArrayzh,ktArrayzh),
-        (tcByteArrayzh,ktByteArrayzh),
-        (tcMutableArrayzh,ktMutableArrayzh),
-        (tcMutableByteArrayzh,ktMutableByteArrayzh),
-        (tcMutVarzh,ktMutVarzh),
-        (tcMVarzh,ktMVarzh),
-        (tcWeakzh,ktWeakzh),
-        (tcForeignObjzh, ktForeignObjzh),
-        (tcStablePtrzh, ktStablePtrzh),
-        (tcThreadIdzh, ktThreadIdzh),
-        (tcZCTCCallable, ktZCTCCallable),
-        (tcZCTCReturnable, ktZCTCReturnable)]
-       ++ [(tcUtuple n, ktUtuple n) | n <- [1..maxUtuple]])
-
 
 primDcs :: [(Dcon,Ty)]
-primDcs = map (\ ((m,c),t) -> (c,t))
+primDcs = map (\ ((_,c),t) -> (c,t))
              [(dcUtuple n, dcUtupleTy n) | n <- [1..maxUtuple]]
 
-primVals :: [(Var,Ty)]
-primVals = 
-       opsAddrzh ++
-       opsCharzh ++
-       opsDoublezh ++
-       opsFloatzh ++
-       opsIntzh ++
-       opsInt32zh ++
-       opsInt64zh ++
-       opsIntegerzh ++
-       opsWordzh ++
-       opsWord32zh ++
-       opsWord64zh ++
-       opsSized ++
-       opsArray ++
-       opsMutVarzh ++
-       opsState ++
-       opsExn ++
-       opsMVar ++
-       opsWeak ++
-       opsForeignObjzh ++
-        opsStablePtrzh ++
-       opsConc ++
-       opsMisc
-
-
-dcUtuples :: [(Qual Dcon,Ty)]
-dcUtuples = map ( \n -> (dcUtuple n, typ n)) [1..100]
-     where typ n = foldr ( \tv t -> Tforall (tv,Kopen) t)
-                               (foldr ( \tv t -> tArrow (Tvar tv) t)
-                                            (tUtuple (map Tvar tvs)) tvs) tvs
-                     where tvs = map ( \i -> ("a" ++ (show i))) [1..n]
-
-pv = qual primMname
-pvz = (qual primMname) . (++ "zh")
-
-{- Addrzh -}
-tcAddrzh = pvz "Addr"
-tAddrzh = Tcon tcAddrzh
-ktAddrzh = Kunlifted
-
-opsAddrzh = [
- ("gtAddrzh",tcompare tAddrzh),
- ("geAddrzh",tcompare tAddrzh), 
- ("eqAddrzh",tcompare tAddrzh),  
- ("neAddrzh",tcompare tAddrzh),
- ("ltAddrzh",tcompare tAddrzh),  
- ("leAddrzh",tcompare tAddrzh),
- ("nullAddrzh", tAddrzh),
- ("plusAddrzh", tArrow tAddrzh (tArrow tIntzh tAddrzh)),
- ("minusAddrzh", tArrow tAddrzh (tArrow tAddrzh tIntzh)),
- ("remAddrzh", tArrow tAddrzh (tArrow tIntzh tIntzh))]
-
-{- Charzh -}
-
-tcCharzh = pvz "Char"
-tCharzh = Tcon tcCharzh
-ktCharzh = Kunlifted
-
-opsCharzh = [
- ("gtCharzh", tcompare tCharzh),
- ("geCharzh", tcompare tCharzh),
- ("eqCharzh", tcompare tCharzh),
- ("neCharzh", tcompare tCharzh),
- ("ltCharzh", tcompare tCharzh),
- ("leCharzh", tcompare tCharzh),
- ("ordzh",    tArrow tCharzh tIntzh)]
-
-
-{- Doublezh -}
-
-tcDoublezh = pvz "Double"
-tDoublezh = Tcon tcDoublezh
-ktDoublezh = Kunlifted
-
-opsDoublezh = [
- ("zgzhzh", tcompare tDoublezh),
- ("zgzezhzh", tcompare tDoublezh),
- ("zezezhzh", tcompare tDoublezh),
- ("zszezhzh", tcompare tDoublezh),
- ("zlzhzh", tcompare tDoublezh),
- ("zlzezhzh", tcompare tDoublezh),
- ("zpzhzh", tdyadic tDoublezh),
- ("zmzhzh", tdyadic tDoublezh),
- ("ztzhzh", tdyadic tDoublezh),
- ("zszhzh", tdyadic tDoublezh),
- ("negateDoublezh", tmonadic tDoublezh),
- ("double2Intzh", tArrow tDoublezh tIntzh),
- ("double2Floatzh", tArrow tDoublezh tFloatzh),
- ("expDoublezh", tmonadic tDoublezh),
- ("logDoublezh", tmonadic tDoublezh),
- ("sqrtDoublezh", tmonadic tDoublezh),
- ("sinDoublezh", tmonadic tDoublezh),
- ("cosDoublezh", tmonadic tDoublezh),
- ("tanDoublezh", tmonadic tDoublezh),
- ("asinDoublezh", tmonadic tDoublezh),
- ("acosDoublezh", tmonadic tDoublezh),
- ("atanDoublezh", tmonadic tDoublezh),
- ("sinhDoublezh", tmonadic tDoublezh),
- ("coshDoublezh", tmonadic tDoublezh),
- ("tanhDoublezh", tmonadic tDoublezh),
- ("ztztzhzh", tdyadic tDoublezh),
- ("decodeDoublezh", tArrow tDoublezh (tUtuple[tIntzh,tIntzh,tByteArrayzh]))]
-
-
-{- Floatzh -}
-
-tcFloatzh = pvz "Float"
-tFloatzh = Tcon tcFloatzh
-ktFloatzh = Kunlifted
-
-opsFloatzh = [
- ("gtFloatzh", tcompare tFloatzh),
- ("geFloatzh", tcompare tFloatzh),
- ("eqFloatzh", tcompare tFloatzh),
- ("neFloatzh", tcompare tFloatzh),
- ("ltFloatzh", tcompare tFloatzh),
- ("leFloatzh", tcompare tFloatzh),
- ("plusFloatzh", tdyadic tFloatzh),
- ("minusFloatzh", tdyadic tFloatzh),
- ("timesFloatzh", tdyadic tFloatzh),
- ("divideFloatzh", tdyadic tFloatzh),
- ("negateFloatzh", tmonadic tFloatzh),
- ("float2Intzh", tArrow tFloatzh tIntzh),
- ("expFloatzh", tmonadic tFloatzh),
- ("logFloatzh", tmonadic tFloatzh),
- ("sqrtFloatzh", tmonadic tFloatzh),
- ("sinFloatzh", tmonadic tFloatzh),
- ("cosFloatzh", tmonadic tFloatzh),
- ("tanFloatzh", tmonadic tFloatzh),
- ("asinFloatzh", tmonadic tFloatzh),
- ("acosFloatzh", tmonadic tFloatzh),
- ("atanFloatzh", tmonadic tFloatzh),
- ("sinhFloatzh", tmonadic tFloatzh),
- ("coshFloatzh", tmonadic tFloatzh),
- ("tanhFloatzh", tmonadic tFloatzh),
- ("powerFloatzh", tdyadic tFloatzh),
- ("float2Doublezh", tArrow tFloatzh tDoublezh),
- ("decodeFloatzh", tArrow tFloatzh (tUtuple[tIntzh,tIntzh,tByteArrayzh]))]
-
-
-{- Intzh -}
-
-tcIntzh = pvz "Int"
-tIntzh = Tcon tcIntzh
-ktIntzh = Kunlifted
-
-opsIntzh = [
- ("zpzh", tdyadic tIntzh),
- ("zmzh", tdyadic tIntzh),
- ("ztzh", tdyadic tIntzh),
- ("quotIntzh", tdyadic tIntzh),
- ("remIntzh", tdyadic tIntzh),
- ("gcdIntzh", tdyadic tIntzh),
- ("negateIntzh", tmonadic tIntzh),
- ("addIntCzh", tArrow tIntzh (tArrow tIntzh (tUtuple [tIntzh, tIntzh]))),
- ("subIntCzh", tArrow tIntzh (tArrow tIntzh (tUtuple [tIntzh, tIntzh]))),
- ("mulIntCzh", tArrow tIntzh (tArrow tIntzh (tUtuple [tIntzh, tIntzh]))),
- ("zgzh", tcompare tIntzh),
- ("zgzezh", tcompare tIntzh),
- ("zezezh", tcompare tIntzh),
- ("zszezh", tcompare tIntzh),
- ("zlzh", tcompare tIntzh),
- ("zlzezh", tcompare tIntzh),
- ("chrzh", tArrow tIntzh tCharzh),
- ("int2Wordzh", tArrow tIntzh tWordzh),
- ("int2Floatzh", tArrow tIntzh tFloatzh),
- ("int2Doublezh", tArrow tIntzh tDoublezh),
- ("intToInt32zh", tArrow tIntzh tInt32zh),
- ("int2Integerzh", tArrow tIntzh tIntegerzhRes),
- ("iShiftLzh", tdyadic tIntzh),
- ("iShiftRAzh", tdyadic tIntzh),
- ("iShiftRLh", tdyadic tIntzh)]
-
-
-{- Int32zh -}
-
-tcInt32zh = pvz "Int32"
-tInt32zh = Tcon tcInt32zh
-ktInt32zh = Kunlifted
-
-opsInt32zh = [
- ("int32ToIntzh", tArrow tInt32zh tIntzh),
- ("int32ToIntegerzh", tArrow tInt32zh tIntegerzhRes)]
-
-
-{- Int64zh -}
-
-tcInt64zh = pvz "Int64"
-tInt64zh = Tcon tcInt64zh
-ktInt64zh = Kunlifted
-
-opsInt64zh = [
- ("int64ToIntegerzh", tArrow tInt64zh tIntegerzhRes)]
-
-{- Integerzh -}
-
--- not actuallly a primitive type
-tIntegerzhRes = tUtuple [tIntzh, tByteArrayzh]
-tIntegerzhTo t = tArrow tIntzh (tArrow tByteArrayzh t)
-tdyadicIntegerzh = tIntegerzhTo (tIntegerzhTo tIntegerzhRes)
-
-opsIntegerzh = [
- ("plusIntegerzh", tdyadicIntegerzh),
- ("minusIntegerzh", tdyadicIntegerzh),
- ("timesIntegerzh", tdyadicIntegerzh),
- ("gcdIntegerzh", tdyadicIntegerzh),
- ("gcdIntegerIntzh", tIntegerzhTo (tArrow tIntzh tIntzh)),
- ("divExactIntegerzh", tdyadicIntegerzh),
- ("quotIntegerzh", tdyadicIntegerzh),
- ("remIntegerzh", tdyadicIntegerzh),
- ("cmpIntegerzh", tIntegerzhTo (tIntegerzhTo tIntzh)),
- ("cmpIntegerIntzh", tIntegerzhTo (tArrow tIntzh tIntzh)),
- ("quotRemIntegerzh", tIntegerzhTo (tIntegerzhTo (tUtuple [tIntzh,tByteArrayzh,tIntzh,tByteArrayzh]))),
- ("divModIntegerzh", tIntegerzhTo (tIntegerzhTo (tUtuple [tIntzh,tByteArrayzh,tIntzh,tByteArrayzh]))),
- ("integer2Intzh", tIntegerzhTo tIntzh),
- ("integer2Wordzh", tIntegerzhTo tWordzh),
- ("integerToInt32zh", tIntegerzhTo tInt32zh),
- ("integerToWord32zh", tIntegerzhTo tWord32zh),
- ("integerToInt64zh", tIntegerzhTo tInt64zh),
- ("integerToWord64zh", tIntegerzhTo tWord64zh),
- ("andIntegerzh", tdyadicIntegerzh),
- ("orIntegerzh", tdyadicIntegerzh),
- ("xorIntegerzh", tdyadicIntegerzh),
- ("complementIntegerzh", tIntegerzhTo tIntegerzhRes)]
-
-
-
-{- Wordzh -}
-
-tcWordzh = pvz "Word"
-tWordzh = Tcon tcWordzh
-ktWordzh = Kunlifted
-
-opsWordzh = [
- ("plusWordzh", tdyadic tWordzh),
- ("minusWordzh", tdyadic tWordzh),
- ("timesWordzh", tdyadic tWordzh),
- ("quotWordzh",   tdyadic tWordzh),
- ("remWordzh",   tdyadic tWordzh),
- ("andzh",    tdyadic tWordzh),
- ("orzh",    tdyadic tWordzh),
- ("xorzh",    tdyadic tWordzh),
- ("notzh",    tmonadic tWordzh),
- ("shiftLzh", tArrow tWordzh (tArrow tIntzh tWordzh)),
- ("shiftRLzh", tArrow tWordzh (tArrow tIntzh tWordzh)),
- ("word2Intzh", tArrow tWordzh tIntzh),
- ("wordToWord32zh", tArrow tWordzh tWord32zh),
- ("word2Integerzh", tArrow tWordzh tIntegerzhRes),
- ("gtWordzh", tcompare tWordzh),
- ("geWordzh", tcompare tWordzh),
- ("eqWordzh", tcompare tWordzh),
- ("neWordzh", tcompare tWordzh),
- ("ltWordzh", tcompare tWordzh),
- ("leWordzh", tcompare tWordzh)]
-
-{- Word32zh -}
-
-tcWord32zh = pvz "Word32"
-tWord32zh = Tcon tcWord32zh
-ktWord32zh = Kunlifted
-
-opsWord32zh = [
- ("word32ToWordzh", tArrow tWord32zh tWordzh),
- ("word32ToIntegerzh", tArrow tWord32zh tIntegerzhRes)]
-
-{- Word64zh -}
-
-tcWord64zh = pvz "Word64"
-tWord64zh = Tcon tcWord64zh
-ktWord64zh = Kunlifted
-
-opsWord64zh = [
- ("word64ToIntegerzh", tArrow tWord64zh tIntegerzhRes)]
-
-{- Explicitly sized Intzh and Wordzh -}
+tRWS :: Ty
+tRWS = tStatezh tRealWorld
 
-opsSized = [
- ("narrow8Intzh", tmonadic tIntzh),
- ("narrow16Intzh", tmonadic tIntzh),
- ("narrow32Intzh", tmonadic tIntzh),
- ("narrow8Wordzh", tmonadic tWordzh),
- ("narrow16Wordzh", tmonadic tWordzh),
- ("narrow32Wordzh", tmonadic tWordzh)]
+opsState :: [(Var, Ty)]
+opsState = [
+  ("realWorldzh", tRWS)]
 
 {- Arrays -}
 
-tcArrayzh = pvz "Array"
-tArrayzh t = Tapp (Tcon tcArrayzh) t
-ktArrayzh = Karrow Klifted Kunlifted
+tcByteArrayzh, tcMutableArrayzh, tcMutableByteArrayzh :: Qual Tcon
+ktByteArrayzh, ktMutableArrayzh, ktMutableByteArrayzh :: Kind
 
 tcByteArrayzh = pvz "ByteArray"
-tByteArrayzh = Tcon tcByteArrayzh
 ktByteArrayzh = Kunlifted
 
 tcMutableArrayzh = pvz "MutableArray"
-tMutableArrayzh s t = Tapp (Tapp (Tcon tcMutableArrayzh) s) t
 ktMutableArrayzh = Karrow Klifted (Karrow Klifted Kunlifted)
 
 tcMutableByteArrayzh = pvz "MutableByteArray"
-tMutableByteArrayzh s = Tapp (Tcon tcMutableByteArrayzh) s
 ktMutableByteArrayzh = Karrow Klifted Kunlifted
 
-opsArray = [
- ("newArrayzh", Tforall ("a",Klifted) 
-                      (Tforall ("s",Klifted)
-                                (tArrow tIntzh 
-                                       (tArrow (Tvar "a")
-                                               (tArrow (tStatezh (Tvar "s"))
-                                                       (tUtuple [tStatezh (Tvar "s"),tMutableArrayzh (Tvar "s") (Tvar "a")])))))),
- ("newByteArrayzh", Tforall ("s",Klifted)
-                           (tArrow tIntzh 
-                                   (tArrow (tStatezh (Tvar "s"))
-                                           (tUtuple [tStatezh (Tvar "s"),tMutableByteArrayzh (Tvar "s")])))),
- ("newPinnedByteArrayzh", Tforall ("s",Klifted)
-                           (tArrow tIntzh 
-                                   (tArrow (tStatezh (Tvar "s"))
-                                           (tUtuple [tStatezh (Tvar "s"),tMutableByteArrayzh (Tvar "s")])))),
- ("byteArrayContentszh", tArrow tByteArrayzh tAddrzh),
- ("indexCharArrayzh", tArrow tByteArrayzh (tArrow tIntzh tCharzh)),
- ("indexWideCharArrayzh", tArrow tByteArrayzh (tArrow tIntzh tCharzh)),
- ("indexIntArrayzh", tArrow tByteArrayzh (tArrow tIntzh tIntzh)),
- ("indexWordArrayzh", tArrow tByteArrayzh (tArrow tIntzh tWordzh)),
- ("indexAddrArrayzh", tArrow tByteArrayzh (tArrow tIntzh tAddrzh)),
- ("indexFloatArrayzh", tArrow tByteArrayzh (tArrow tIntzh tFloatzh)),
- ("indexDoubleArrayzh", tArrow tByteArrayzh (tArrow tIntzh tDoublezh)),
- ("indexStablePtrArrayzh", Tforall ("a",Klifted) (tArrow tByteArrayzh (tArrow tIntzh (tStablePtrzh (Tvar "a"))))),
- ("indexInt8Arrayzh", tArrow tByteArrayzh (tArrow tIntzh tIntzh)),
- ("indexInt16Arrayzh", tArrow tByteArrayzh (tArrow tIntzh tIntzh)),
- ("indexInt32Arrayzh", tArrow tByteArrayzh (tArrow tIntzh tInt32zh)),
- ("indexInt64Arrayzh", tArrow tByteArrayzh (tArrow tIntzh tInt64zh)),
- ("indexWord8Arrayzh", tArrow tByteArrayzh (tArrow tIntzh tWordzh)),
- ("indexWord16Arrayzh", tArrow tByteArrayzh (tArrow tIntzh tWordzh)),
- ("indexWord32Arrayzh", tArrow tByteArrayzh (tArrow tIntzh tWord32zh)),
- ("indexWord64Arrayzh", tArrow tByteArrayzh (tArrow tIntzh tWord64zh)),
- ("readCharArrayzh", tReadMutableByteArrayzh tCharzh),
- ("readWideCharArrayzh", tReadMutableByteArrayzh tCharzh),
- ("readIntArrayzh", tReadMutableByteArrayzh tIntzh),
- ("readWordArrayzh", tReadMutableByteArrayzh tWordzh),
- ("readAddrArrayzh", tReadMutableByteArrayzh tAddrzh),
- ("readFloatArrayzh", tReadMutableByteArrayzh tFloatzh),
- ("readDoubleArrayzh", tReadMutableByteArrayzh tDoublezh),
- ("readStablePtrArrayzh", Tforall ("s",Klifted)
-                                (Tforall ("a",Klifted)
-                                         (tArrow (tMutableByteArrayzh (Tvar "s"))
-                                                 (tArrow tIntzh
-                                                        (tArrow (tStatezh (Tvar "s"))
-                                                                (tUtuple [tStatezh (Tvar "s"),tStablePtrzh (Tvar "a")])))))),
- ("readInt8Arrayzh", tReadMutableByteArrayzh tIntzh),
- ("readInt16Arrayzh", tReadMutableByteArrayzh tIntzh),
- ("readInt32Arrayzh", tReadMutableByteArrayzh tInt32zh),
- ("readInt64Arrayzh", tReadMutableByteArrayzh tInt64zh),
- ("readWord8Arrayzh", tReadMutableByteArrayzh tWordzh),
- ("readWord16Arrayzh", tReadMutableByteArrayzh tWordzh),
- ("readWord32Arrayzh", tReadMutableByteArrayzh tWord32zh),
- ("readWord64Arrayzh", tReadMutableByteArrayzh tWord64zh),
-
- ("writeCharArrayzh", tWriteMutableByteArrayzh tCharzh),
- ("writeWideCharArrayzh", tWriteMutableByteArrayzh tCharzh),
- ("writeIntArrayzh", tWriteMutableByteArrayzh tIntzh),
- ("writeWordArrayzh", tWriteMutableByteArrayzh tWordzh),
- ("writeAddrArrayzh", tWriteMutableByteArrayzh tAddrzh),
- ("writeFloatArrayzh", tWriteMutableByteArrayzh tFloatzh),
- ("writeDoubleArrayzh", tWriteMutableByteArrayzh tDoublezh),
- ("writeStablePtrArrayzh", Tforall ("s",Klifted)
-                                 (Tforall ("a",Klifted)
-                                          (tArrow (tMutableByteArrayzh (Tvar "s"))
-                                                  (tArrow tIntzh
-                                                         (tArrow (tStablePtrzh (Tvar "a"))
-                                                                 (tArrow (tStatezh (Tvar "s"))
-                                                                         (tStatezh (Tvar "s")))))))),
- ("writeInt8Arrayzh", tWriteMutableByteArrayzh tIntzh),
- ("writeInt16Arrayzh", tWriteMutableByteArrayzh tIntzh),
- ("writeInt32Arrayzh", tWriteMutableByteArrayzh tIntzh),
- ("writeInt64Arrayzh", tWriteMutableByteArrayzh tInt64zh),
- ("writeWord8Arrayzh", tWriteMutableByteArrayzh tWordzh),
- ("writeWord16Arrayzh", tWriteMutableByteArrayzh tWordzh),
- ("writeWord32Arrayzh", tWriteMutableByteArrayzh tWord32zh),
- ("writeWord64Arrayzh", tWriteMutableByteArrayzh tWord64zh),
-
- ("indexCharOffAddrzh", tArrow tAddrzh (tArrow tIntzh tCharzh)),
- ("indexWideCharOffAddrzh", tArrow tAddrzh (tArrow tIntzh tCharzh)),
- ("indexIntOffAddrzh", tArrow tAddrzh (tArrow tIntzh tIntzh)),
- ("indexWordOffAddrzh", tArrow tAddrzh (tArrow tIntzh tWordzh)),
- ("indexAddrOffAddrzh", tArrow tAddrzh (tArrow tIntzh tAddrzh)),
- ("indexFloatOffAddrzh", tArrow tAddrzh (tArrow tIntzh tFloatzh)),
- ("indexDoubleOffAddrzh", tArrow tAddrzh (tArrow tIntzh tDoublezh)),
- ("indexStablePtrOffAddrzh", Tforall ("a",Klifted) (tArrow tAddrzh (tArrow tIntzh (tStablePtrzh (Tvar "a"))))),
- ("indexInt8OffAddrzh", tArrow tAddrzh (tArrow tIntzh tIntzh)),
- ("indexInt16OffAddrzh", tArrow tAddrzh (tArrow tIntzh tIntzh)),
- ("indexInt32OffAddrzh", tArrow tAddrzh (tArrow tIntzh tInt32zh)),
- ("indexInt64OffAddrzh", tArrow tAddrzh (tArrow tIntzh tInt64zh)),
- ("indexWord8OffAddrzh", tArrow tAddrzh (tArrow tIntzh tWordzh)),
- ("indexWord16OffAddrzh", tArrow tAddrzh (tArrow tIntzh tWordzh)),
- ("indexWord32ffAddrzh", tArrow tAddrzh (tArrow tIntzh tWord32zh)),
- ("indexWord64OffAddrzh", tArrow tAddrzh (tArrow tIntzh tWord64zh)),
-
- ("indexCharOffForeignObjzh", tArrow tForeignObjzh (tArrow tIntzh tCharzh)),
- ("indexWideCharOffForeignObjzh", tArrow tForeignObjzh (tArrow tIntzh tCharzh)),
- ("indexIntOffForeignObjzh", tArrow tForeignObjzh (tArrow tIntzh tIntzh)),
- ("indexWordOffForeignObjzh", tArrow tForeignObjzh (tArrow tIntzh tWordzh)),
- ("indexAddrOffForeignObjzh", tArrow tForeignObjzh (tArrow tIntzh tAddrzh)),
- ("indexFloatOffForeignObjzh", tArrow tForeignObjzh (tArrow tIntzh tFloatzh)),
- ("indexDoubleOffForeignObjzh", tArrow tForeignObjzh (tArrow tIntzh tDoublezh)),
- ("indexStablePtrOffForeignObjzh", Tforall ("a",Klifted) (tArrow tForeignObjzh (tArrow tIntzh (tStablePtrzh (Tvar "a"))))),
- ("indexInt8OffForeignObjzh", tArrow tForeignObjzh (tArrow tIntzh tIntzh)),
- ("indexInt16OffForeignObjzh", tArrow tForeignObjzh (tArrow tIntzh tIntzh)),
- ("indexInt32OffForeignObjzh", tArrow tForeignObjzh (tArrow tIntzh tInt32zh)),
- ("indexInt64OffForeignObjzh", tArrow tForeignObjzh (tArrow tIntzh tInt64zh)),
- ("indexWord8OffForeignObjzh", tArrow tForeignObjzh (tArrow tIntzh tWordzh)),
- ("indexWord16OffForeignObjzh", tArrow tForeignObjzh (tArrow tIntzh tWordzh)),
- ("indexWord32ffForeignObjzh", tArrow tForeignObjzh (tArrow tIntzh tWord32zh)),
- ("indexWord64OffForeignObjzh", tArrow tForeignObjzh (tArrow tIntzh tWord64zh)),
-
- ("readCharOffAddrzh", tReadOffAddrzh tCharzh),
- ("readWideCharOffAddrzh", tReadOffAddrzh tCharzh),
- ("readIntOffAddrzh", tReadOffAddrzh tIntzh),
- ("readWordOffAddrzh", tReadOffAddrzh tWordzh),
- ("readAddrOffAddrzh", tReadOffAddrzh tAddrzh),
- ("readFloatOffAddrzh", tReadOffAddrzh tFloatzh),
- ("readDoubleOffAddrzh", tReadOffAddrzh tDoublezh),
- ("readStablePtrOffAddrzh", Tforall ("s",Klifted) 
-                               (Tforall ("a",Klifted)
-                                    (tArrow tAddrzh
-                                            (tArrow tIntzh
-                                                   (tArrow (tStatezh (Tvar "s"))
-                                                           (tUtuple [tStatezh (Tvar "s"),tStablePtrzh (Tvar "a")])))))),
- ("readInt8OffAddrzh", tReadOffAddrzh tIntzh),
- ("readInt16OffAddrzh", tReadOffAddrzh tIntzh),
- ("readInt32OffAddrzh", tReadOffAddrzh tInt32zh),
- ("readInt64OffAddrzh", tReadOffAddrzh tInt64zh),
- ("readWord8OffAddrzh", tReadOffAddrzh tWordzh),
- ("readWord16OffAddrzh", tReadOffAddrzh tWordzh),
- ("readWord32OffAddrzh", tReadOffAddrzh tWord32zh),
- ("readWord64OffAddrzh", tReadOffAddrzh tWord64zh),
-
- ("writeCharOffAddrzh", tWriteOffAddrzh tCharzh),
- ("writeWideCharOffAddrzh", tWriteOffAddrzh tCharzh),
- ("writeIntOffAddrzh", tWriteOffAddrzh tIntzh),
- ("writeWordOffAddrzh", tWriteOffAddrzh tWordzh),
- ("writeAddrOffAddrzh", tWriteOffAddrzh tAddrzh),
- ("writeFloatOffAddrzh", tWriteOffAddrzh tFloatzh),
- ("writeDoubleOffAddrzh", tWriteOffAddrzh tDoublezh),
- ("writeStablePtrOffAddrzh", Tforall ("a",Klifted) (tWriteOffAddrzh (tStablePtrzh (Tvar "a")))),
- ("writeInt8OffAddrzh", tWriteOffAddrzh tIntzh),
- ("writeInt16OffAddrzh", tWriteOffAddrzh tIntzh),
- ("writeInt32OffAddrzh", tWriteOffAddrzh tInt32zh),
- ("writeInt64OffAddrzh", tWriteOffAddrzh tInt64zh),
- ("writeWord8OffAddrzh", tWriteOffAddrzh tWordzh),
- ("writeWord16OffAddrzh", tWriteOffAddrzh tWordzh),
- ("writeWord32OffAddrzh", tWriteOffAddrzh tWord32zh),
- ("writeWord64OffAddrzh", tWriteOffAddrzh tWord64zh),
- ("sameMutableArrayzh", Tforall ("s",Klifted)
-                               (Tforall ("a",Klifted)
-                                        (tArrow (tMutableArrayzh (Tvar "s") (Tvar "a"))
-                                                (tArrow (tMutableArrayzh (Tvar "s") (Tvar "a"))
-                                                        tBool)))),
- ("sameMutableByteArrayzh", Tforall ("s",Klifted)
-                                   (tArrow (tMutableByteArrayzh (Tvar "s"))
-                                           (tArrow (tMutableByteArrayzh (Tvar "s"))
-                                                   tBool))),
- ("readArrayzh",Tforall ("s",Klifted)
-                        (Tforall ("a",Klifted)
-                                 (tArrow (tMutableArrayzh (Tvar "s") (Tvar "a"))
-                                        (tArrow tIntzh
-                                                (tArrow (tStatezh (Tvar "s"))
-                                                         (tUtuple[tStatezh (Tvar "s"), Tvar "a"])))))),
- ("writeArrayzh",Tforall ("s",Klifted)
-                         (Tforall ("a",Klifted)
-                                  (tArrow (tMutableArrayzh (Tvar "s") (Tvar "a"))
-                                         (tArrow tIntzh
-                                                 (tArrow (Tvar "a")
-                                                         (tArrow (tStatezh (Tvar "s"))
-                                                                  (tStatezh (Tvar "s")))))))),
- ("indexArrayzh", Tforall ("a",Klifted)
-                          (tArrow (tArrayzh (Tvar "a"))
-                                  (tArrow tIntzh
-                                          (tUtuple[Tvar "a"])))),
- ("unsafeFreezzeArrayzh",Tforall ("s",Klifted)
-                                (Tforall ("a",Klifted)
-                                         (tArrow (tMutableArrayzh (Tvar "s") (Tvar "a"))
-                                                (tArrow (tStatezh (Tvar "s"))
-                                                         (tUtuple[tStatezh (Tvar "s"),tArrayzh (Tvar "a")]))))),
- ("unsafeFreezzeByteArrayzh",Tforall ("s",Klifted)
-                                    (tArrow (tMutableByteArrayzh (Tvar "s"))
-                                           (tArrow (tStatezh (Tvar "s"))
-                                                    (tUtuple[tStatezh (Tvar "s"),tByteArrayzh])))),
- ("unsafeThawArrayzh",Tforall ("a",Klifted)
-                             (Tforall ("s",Klifted)
-                                      (tArrow (tArrayzh (Tvar "a"))
-                                             (tArrow (tStatezh (Tvar "s"))
-                                                      (tUtuple[tStatezh (Tvar "s"),tMutableArrayzh (Tvar "s") (Tvar "a")]))))),
- ("sizzeofByteArrayzh", tArrow tByteArrayzh tIntzh), 
- ("sizzeofMutableByteArrayzh", Tforall ("s",Klifted) (tArrow (tMutableByteArrayzh (Tvar "s")) tIntzh))]
- where
- tReadMutableByteArrayzh t = 
-     Tforall ("s",Klifted)
-             (tArrow (tMutableByteArrayzh (Tvar "s"))
-                     (tArrow tIntzh
-                            (tArrow (tStatezh (Tvar "s"))
-                                    (tUtuple [tStatezh (Tvar "s"),t]))))
-
- tWriteMutableByteArrayzh t = 
-     Tforall ("s",Klifted)
-             (tArrow (tMutableByteArrayzh (Tvar "s"))
-                     (tArrow tIntzh
-                            (tArrow t
-                                    (tArrow (tStatezh (Tvar "s"))
-                                            (tStatezh (Tvar "s"))))))
-
- tReadOffAddrzh t = 
-     Tforall ("s",Klifted)
-             (tArrow tAddrzh
-                     (tArrow tIntzh
-                            (tArrow (tStatezh (Tvar "s"))
-                                    (tUtuple [tStatezh (Tvar "s"),t]))))
-
-
- tWriteOffAddrzh t = 
-     Tforall ("s",Klifted)
-             (tArrow tAddrzh
-                     (tArrow tIntzh
-                            (tArrow t
-                                    (tArrow (tStatezh (Tvar "s"))
-                                            (tStatezh (Tvar "s"))))))
-
-{- MutVars -}
-
-tcMutVarzh = pvz "MutVar"
-tMutVarzh s t = Tapp (Tapp (Tcon tcMutVarzh) s) t
-ktMutVarzh = Karrow Klifted (Karrow Klifted Kunlifted)
-
-opsMutVarzh = [
- ("newMutVarzh", Tforall ("a",Klifted)    
-                    (Tforall ("s",Klifted)
-                        (tArrow (Tvar "a") (tArrow (tStatezh (Tvar "s"))
-                                                  (tUtuple [tStatezh (Tvar "s"),
-                                                            tMutVarzh (Tvar "s") (Tvar "a")]))))),
- ("readMutVarzh", Tforall ("s",Klifted)
-                   (Tforall ("a",Klifted)
-                        (tArrow (tMutVarzh (Tvar "s")(Tvar "a"))
-                               (tArrow (tStatezh (Tvar "s"))
-                                        (tUtuple [tStatezh (Tvar "s"), Tvar "a"]))))),
- ("writeMutVarzh", Tforall ("s",Klifted)
-                   (Tforall ("a",Klifted)
-                        (tArrow (tMutVarzh (Tvar "s") (Tvar "a"))
-                               (tArrow (Tvar "a")
-                                        (tArrow (tStatezh (Tvar "s"))
-                                                (tStatezh (Tvar "s"))))))),
- ("sameMutVarzh", Tforall ("s",Klifted)
-                   (Tforall ("a",Klifted)
-                        (tArrow (tMutVarzh (Tvar "s") (Tvar "a"))
-                               (tArrow (tMutVarzh (Tvar "s") (Tvar "a"))
-                                       tBool))))]
-
 {- Real world and state. -}
 
 -- tjc: why isn't this one unboxed?
+tcRealWorld :: Qual Tcon
 tcRealWorld = pv "RealWorld"
+tRealWorld :: Ty
 tRealWorld = Tcon tcRealWorld
-ktRealWorld = Klifted
 
+tcStatezh :: Qual Tcon
 tcStatezh = pvz "State"
+tStatezh :: Ty -> Ty
 tStatezh t = Tapp (Tcon tcStatezh) t
-ktStatezh = Karrow Klifted Kunlifted
-
-tRWS = tStatezh tRealWorld
-
-opsState = [
-  ("realWorldzh", tRWS)]
-
-{- Exceptions -}
-
--- no primitive type
-opsExn = [
- ("catchzh", 
-       let t' = tArrow tRWS (tUtuple [tRWS, Tvar "a"]) in
-       Tforall ("a",Klifted)
-               (Tforall ("b",Klifted)
-                        (tArrow t'
-                                (tArrow (tArrow (Tvar "b") t') 
-                                         t')))),
-  ("raisezh", Tforall ("a",Klifted)
-                     (Tforall ("b",Klifted)
-                              (tArrow (Tvar "a") (Tvar "b")))),
-  ("blockAsyncExceptionszh", Tforall ("a",Klifted)                     
-                                    (tArrow (tArrow tRWS (tUtuple[tRWS,Tvar "a"]))
-                                           (tArrow tRWS (tUtuple[tRWS,Tvar "a"])))),
-  ("unblockAsyncExceptionszh", Tforall ("a",Klifted)                   
-                                    (tArrow (tArrow tRWS (tUtuple[tRWS,Tvar "a"]))
-                                           (tArrow tRWS (tUtuple[tRWS,Tvar "a"]))))]
-
-{- Mvars -} 
-
-tcMVarzh = pvz "MVar"
-tMVarzh s t = Tapp (Tapp (Tcon tcMVarzh) s) t
-ktMVarzh = Karrow Klifted (Karrow Klifted Kunlifted)
-
-opsMVar = [
- ("newMVarzh", Tforall ("s",Klifted)
-                     (Tforall ("a",Klifted)
-                               (tArrow (tStatezh (Tvar "s"))
-                                      (tUtuple[tStatezh (Tvar "s"),tMVarzh (Tvar "s") (Tvar "a")])))),
- ("takeMVarzh", Tforall ("s",Klifted)
-                     (Tforall ("a",Klifted)
-                              (tArrow (tMVarzh (Tvar "s") (Tvar "a"))
-                                      (tArrow (tStatezh (Tvar "s"))
-                                              (tUtuple[tStatezh (Tvar "s"),Tvar "a"]))))),
- ("tryTakeMVarzh", Tforall ("s",Klifted)
-                     (Tforall ("a",Klifted)
-                              (tArrow (tMVarzh (Tvar "s") (Tvar "a"))
-                                      (tArrow (tStatezh (Tvar "s"))
-                                              (tUtuple[tStatezh (Tvar "s"),tIntzh,Tvar "a"]))))),
- ("putMVarzh", Tforall ("s",Klifted)
-                     (Tforall ("a",Klifted)
-                              (tArrow (tMVarzh (Tvar "s") (Tvar "a"))
-                                      (tArrow (Tvar "a")
-                                              (tArrow (tStatezh (Tvar "s"))
-                                                      (tStatezh (Tvar "s"))))))),
- ("tryPutMVarzh", Tforall ("s",Klifted)
-                     (Tforall ("a",Klifted)
-                              (tArrow (tMVarzh (Tvar "s") (Tvar "a"))
-                                      (tArrow (Tvar "a")
-                                              (tArrow (tStatezh (Tvar "s"))
-                                                      (tUtuple [tStatezh (Tvar "s"), tIntzh])))))),
- ("sameMVarzh", Tforall ("s",Klifted)
-                     (Tforall ("a",Klifted)
-                              (tArrow (tMVarzh (Tvar "s") (Tvar "a"))
-                                      (tArrow (tMVarzh (Tvar "s") (Tvar "a"))
-                                              tBool)))),
- ("isEmptyMVarzh", Tforall ("s",Klifted)
-                     (Tforall ("a",Klifted)
-                              (tArrow (tMVarzh (Tvar "s") (Tvar "a"))
-                                      (tArrow (tStatezh (Tvar "s"))
-                                              (tUtuple[tStatezh (Tvar "s"),tIntzh])))))]
-
-
-{- Weak Objects -}
 
-tcWeakzh = pvz "Weak"
-tWeakzh t = Tapp (Tcon tcWeakzh) t
-ktWeakzh = Karrow Klifted Kunlifted
-
-opsWeak = [
-  ("mkWeakzh", Tforall ("o",Kopen)
-                      (Tforall ("b",Klifted)
-                              (Tforall ("c",Klifted)
-                                       (tArrow (Tvar "o")
-                                               (tArrow (Tvar "b")
-                                                       (tArrow (Tvar "c")
-                                                               (tArrow tRWS (tUtuple[tRWS, tWeakzh (Tvar "b")])))))))),
-  ("deRefWeakzh", Tforall ("a",Klifted)
-                        (tArrow (tWeakzh (Tvar "a"))
-                                (tArrow tRWS (tUtuple[tRWS, tIntzh, Tvar "a"])))),
-  ("finalizeWeakzh", Tforall ("a",Klifted)
-                           (tArrow (tWeakzh (Tvar "a"))
-                                    (tArrow tRWS
-                                           (tUtuple[tRWS,tIntzh,
-                                                    tArrow tRWS (tUtuple[tRWS, tUnit])]))))]
-
-
-{- Foreign Objects -}
-
-tcForeignObjzh = pvz "ForeignObj"
-tForeignObjzh = Tcon tcForeignObjzh
-ktForeignObjzh = Kunlifted
-
-opsForeignObjzh = [
- ("mkForeignObjzh", tArrow tAddrzh
-                          (tArrow tRWS (tUtuple [tRWS,tForeignObjzh]))),
- ("writeForeignObjzh", Tforall ("s",Klifted) 
-                              (tArrow tForeignObjzh
-                                      (tArrow tAddrzh
-                                              (tArrow (tStatezh (Tvar "s")) (tStatezh (Tvar "s")))))),
- ("foreignObjToAddrzh", tArrow tForeignObjzh tAddrzh),
- ("touchzh", Tforall ("o",Kopen)
-                    (tArrow (Tvar "o")
-                            (tArrow tRWS tRWS)))]
-
-
-{- Stable Pointers (but not names) -}
-
-tcStablePtrzh = pvz "StablePtr"
-tStablePtrzh t = Tapp (Tcon tcStablePtrzh) t
-ktStablePtrzh = Karrow Klifted Kunlifted
-
-opsStablePtrzh = [
-  ("makeStablePtrzh", Tforall ("a",Klifted) 
-                            (tArrow (Tvar "a")
-                                    (tArrow tRWS (tUtuple[tRWS,tStablePtrzh (Tvar "a")])))),
-  ("deRefStablePtrzh", Tforall ("a",Klifted)
-                             (tArrow (tStablePtrzh (Tvar "a"))
-                                     (tArrow tRWS (tUtuple[tRWS,Tvar "a"])))),
-  ("eqStablePtrzh", Tforall ("a",Klifted)
-                          (tArrow (tStablePtrzh (Tvar "a"))
-                                   (tArrow (tStablePtrzh (Tvar "a")) tIntzh)))]
-
-{- Concurrency  operations -}
-
-tcThreadIdzh = pvz "ThreadId"
-tThreadIdzh = Tcon tcThreadIdzh
-ktThreadIdzh = Kunlifted
-
-opsConc = [
-  ("seqzh", Tforall ("a",Klifted)
-                   (tArrow (Tvar "a") tIntzh)),
-  ("parzh", Tforall ("a",Klifted)
-                   (tArrow (Tvar "a") tIntzh)),
-  ("delayzh", Tforall ("s",Klifted)
-                    (tArrow tIntzh (tArrow (tStatezh (Tvar "s")) (tStatezh (Tvar "s"))))),
-  ("waitReadzh", Tforall ("s",Klifted)
-                    (tArrow tIntzh (tArrow (tStatezh (Tvar "s")) (tStatezh (Tvar "s"))))),
-  ("waitWritezh", Tforall ("s",Klifted)
-                    (tArrow tIntzh (tArrow (tStatezh (Tvar "s")) (tStatezh (Tvar "s"))))),
-  ("forkzh", Tforall ("a",Klifted)
-                   (tArrow (Tvar "a") 
-                           (tArrow tRWS (tUtuple[tRWS,tThreadIdzh])))),
-  ("killThreadzh", Tforall ("a",Klifted)
-                         (tArrow tThreadIdzh
-                                 (tArrow (Tvar "a")
-                                          (tArrow tRWS tRWS)))),
-  ("yieldzh", tArrow tRWS tRWS),
-  ("myThreadIdzh", tArrow tRWS (tUtuple[tRWS, tThreadIdzh]))]
-
-{- Miscellaneous operations -}
-
-opsMisc =  [
-  ("dataToTagzh", Tforall ("a",Klifted) 
-                         (tArrow (Tvar "a") tIntzh)),
-  ("tagToEnumzh", Tforall ("a",Klifted)
-                          (tArrow tIntzh (Tvar "a"))),
-  ("unsafeCoercezh", Tforall ("a",Kopen) 
-                             (Tforall ("b",Kopen) 
-                                      (tArrow (Tvar "a") (Tvar "b")))) -- maybe unneeded
-  ]
-
-{- CCallable and CReturnable.
-   We just define the type constructors for the dictionaries
-   corresponding to these pseudo-classes. -}
-
-tcZCTCCallable = pv "ZCTCCallable"
-ktZCTCCallable = Karrow Kopen Klifted  -- ??
-tcZCTCReturnable = pv "ZCTCReturnable"
-ktZCTCReturnable = Karrow Kopen Klifted  -- ??
+{- Properly defined in PrelError, but needed in many modules before that. -}
+errorVals :: [(Var, Ty)]
+errorVals = [
+ ("error", Tforall ("a",Kopen) (tArrow tString (Tvar "a"))),
+ ("irrefutPatError", str2A),
+ ("patError", str2A),
+ ("divZZeroError", forallAA),
+ ("overflowError", forallAA)]
 
 {- Non-primitive, but mentioned in the types of primitives. -}
 
+bv :: a -> Qual a
 bv = qual baseMname
 
-tcUnit = bv "Unit"
-tUnit = Tcon tcUnit
-ktUnit = Klifted
-tcBool = bv "Bool"
-tBool = Tcon tcBool
-ktBool = Klifted
+str2A, forallAA :: Ty  
+str2A = Tforall ("a",Kopen) (tArrow tAddrzh (Tvar "a"))
+forallAA = Tforall ("a",Kopen) (Tvar "a")
 
-{- Properly defined in PrelError, but needed in many modules before that. -}
-errorVals = [
- ("error", Tforall ("a",Kopen) (tArrow tString (Tvar "a"))),
- ("irrefutPatError", Tforall ("a",Kopen) (tArrow tString (Tvar "a"))),
- ("patError", Tforall ("a",Kopen) (tArrow tString (Tvar "a")))]
-  
+tcChar :: Qual Tcon
 tcChar = bv "Char"
+tChar :: Ty
 tChar = Tcon tcChar
-ktChar = Klifted
+tcList :: Qual Tcon
 tcList = bv "ZMZN"
+tList :: Ty -> Ty
 tList t = Tapp (Tcon tcList) t
-ktList = Karrow Klifted Klifted
+tString :: Ty
 tString = tList tChar
-
-{- Utilities for building types -}
-tmonadic t = tArrow t t
-tdyadic t = tArrow t (tArrow t t)
-tcompare t = tArrow t (tArrow t tBool)
-
index b3aa71e..0b6be42 100644 (file)
@@ -1,44 +1,52 @@
+{-# OPTIONS -Werror -Wall -fno-warn-missing-signatures #-}
+
 module Printer where
 
 import Text.PrettyPrint.HughesPJ
-import Numeric (fromRat)
 import Char
 
 import Core
 import Encoding
+import PrimCoercions
 
 instance Show Module where
-  showsPrec d m = shows (pmodule m)
+  showsPrec _ m = shows (pmodule m)
 
 instance Show Tdef where
-  showsPrec d t = shows (ptdef t)
+  showsPrec _ t = shows (ptdef t)
 
 instance Show Cdef where
-  showsPrec d c = shows (pcdef c)
+  showsPrec _ c = shows (pcdef c)
 
 instance Show Vdefg where
-  showsPrec d v = shows (pvdefg v)
+  showsPrec _ v = shows (pvdefg v)
 
 instance Show Vdef where
-  showsPrec d v = shows (pvdef v)
+  showsPrec _ v = shows (pvdef v)
 
 instance Show Exp where
-  showsPrec d e = shows (pexp e)
+  showsPrec _ e = shows (pexp e)
 
 instance Show Alt where
-  showsPrec d a = shows (palt a)
+  showsPrec _ a = shows (palt a)
 
 instance Show Ty where
-  showsPrec d t = shows (pty t)
+  showsPrec _ t = shows (pty t)
 
 instance Show Kind where
-  showsPrec d k = shows (pkind k)
+  showsPrec _ k = shows (pkind k)
 
 instance Show Lit where
-  showsPrec d l = shows (plit l)
+  showsPrec _ l = shows (plit l)
 
 instance Show CoreLit where
-  showsPrec d l = shows (pclit l)
+  showsPrec _ l = shows (pclit l)
+
+instance Show KindOrCoercion where
+  showsPrec _ (Kind k) = shows (text "<K" <+> pkind k <> text ">")
+  showsPrec _ (Coercion (DefinedCoercion tbs (t1,t2))) = 
+     shows (text "<C" <+> hsep (map ptbind tbs) <+>
+              parens (pkind (Keq t1 t2)) <> text ">") 
 
 indent = nest 2
 
@@ -55,11 +63,13 @@ ptdef (Data qtcon tbinds cdefs) =
   (text "%data" <+> pqname qtcon <+> (hsep (map ptbind tbinds)) <+> char '=')
   $$ indent (braces ((vcat (punctuate (char ';') (map pcdef cdefs)))))
 
-ptdef (Newtype qtcon tbinds (coercion,k) tyopt) =
+ptdef (Newtype qtcon tbinds (coercion,cTbs,k) tyopt) =
   text "%newtype" <+> pqname qtcon <+> (hsep (map ptbind tbinds))
     $$ indent (axiomclause $$ repclause)
-       where axiomclause = char '^' <+> parens (pqname coercion <+> text "::"
-                                    <+> pkind k)
+       where axiomclause = char '^' <+> parens (pqname coercion <+> 
+                                          (hsep (map ptbind cTbs)) <+>
+                                          text "::"
+                                      <+> peqkind k)
             repclause = case tyopt of
                            Just ty -> char '=' <+> pty ty 
                            Nothing -> empty
@@ -67,9 +77,9 @@ ptdef (Newtype qtcon tbinds (coercion,k) tyopt) =
 pcdef (Constr qdcon tbinds tys)  =
   (pqname qdcon) <+> (sep [hsep (map pattbind tbinds),sep (map paty tys)])
 
-pname id = text id
+pname = text
 
-pqname (m,id) = pmname m <> pname id
+pqname (m,v) = pmname m <> pname v
 
 -- be sure to print the '.' here so we don't print out
 -- ".foo" for unqualified foo...
@@ -78,7 +88,7 @@ pmname Nothing = empty
 -- "%module foo" doesn't get printed as "%module ^foo"
 pmname (Just m) = char '^' <> panmname m <> char '.'
 
-panmname p@(pkgName, parents, name) =
+panmname (pkgName, parents, name) =
   let parentStrs = map pname parents in
          pname pkgName <> char ':' <>
          -- This is to be sure to not print out:
@@ -107,11 +117,23 @@ pakind (Kopen) = char '?'
 pakind k = parens (pkind k)
 
 pkind (Karrow k1 k2) = parens (pakind k1 <> text "->" <> pkind k2)
-pkind (Keq t1 t2) = parens (parens (pty t1) <+> text ":=:" <+> parens (pty t2)) 
+pkind (Keq from to) = peqkind (from,to)
 pkind k = pakind k
 
+peqkind (t1, t2) = parens (parens (pty t1) <+> text ":=:" <+> parens (pty t2)) 
+
 paty (Tvar n) = pname n
 paty (Tcon c) = pqname c
+paty (TransCoercion t1 t2) = 
+    parens (sep ([pqname transCoercion, pbty t1, pbty t2]))
+paty (SymCoercion t) = 
+    parens (sep [pqname symCoercion, paty t])
+paty (UnsafeCoercion t1 t2) = 
+    parens (sep [pqname unsafeCoercion, pbty t1, pbty t2])
+paty (LeftCoercion t) = 
+    parens (pqname leftCoercion <+> paty t)
+paty (RightCoercion t) = 
+    parens (pqname rightCoercion <+> paty t)
 paty t = parens (pty t)
 
 pbty (Tapp(Tapp(Tcon tc) t1) t2) | tc == tcArrow = parens(fsep [pbty t1, text "->",pty t2])
@@ -153,7 +175,7 @@ pfexp e = paexp e
 pappexp (App e1 e2) as = pappexp e1 (Left e2:as)
 pappexp (Appt e t) as = pappexp e (Right t:as)
 pappexp e as = fsep (paexp e : map pa as)
-           where pa (Left e) = paexp e
+           where pa (Left ex) = paexp ex
                 pa (Right t) = char '@' <+> paty t
 
 pexp (Lam b e) = char '\\' <+> plamexp [b] e
@@ -204,6 +226,6 @@ escape s = foldr f [] (map ord s)
                  h0 = intToDigit r1
                 hs = dropWhile (=='0') $ reverse $ mkHex cv
                 mkHex 0 = ""
-                mkHex cv = intToDigit r : mkHex q
-                   where (q,r) = quotRem cv 16
+                mkHex num = intToDigit r : mkHex q
+                   where (q,r) = quotRem num 16
      f cv rest = (chr cv):rest
index 0f6c16b..9afd388 100644 (file)
@@ -3,13 +3,44 @@ A set of example programs for handling external core format.
 In particular, typechecker and interpreter give a precise semantics.
 
 To build, run "make".
+---------------------
+tjc April 2008:
+
+==== Notes ====
+
+The checker should work on most programs. Bugs I'm aware of:
+1. GHC generates some questionable coercion applications involving
+   partially-applied function arrows (for details, see:
+   http://www.haskell.org/pipermail/cvs-ghc/2008-April/041949.html)
+   This shows up when typechecking a few of the library modules.
+
+2. There's some weirdness involving funny character literals. This can
+   be fixed by writing a new lexer for chars rather than using Parsec's
+   built-in charLiteral lexer. But I haven't done that.
+
+Typechecking all the GHC libraries eats about a gig of heap and takes a
+long time. I blame Parsec. (Someone who was bored, or understood happy
+better than I do, could update the old happy parser, which is still in the
+repo.)
+
+The interpreter is not working yet.
+
+==== Building ====
+
+To run the checker and interpreter, you need to generate External Core
+for all the base, integer and ghc-prim libraries. This can be done by
+adding "-fext-core" to the GhcLibHcOpts in your build.mk file, then
+running "make" under libraries/.
 
-To run the checker and interpreter (which currently aren't working anyway),
-you need to generate External Core for all the base, integer and ghc-prim
-libraries. This can be done by adding "-fext-core" to the GhcLibHcOpts in
-your build.mk file, then running "make" under libraries/.
 Then you need to edit Driver.hs and change "baseDir" to point to your GHC
 libraries directory.
 
-Most recently tested with GHC 6.8.2. I make no claims of portability. --tjc
+Once you've done that:
+1. make prims (to generate the primops file)
+2. make
+3. make nofibtest (to run the parser/checker on all nofib programs...
+   for example.)
+
+Tested with GHC 6.8.2. I make no claims of portability.
+