1 {-# OPTIONS_GHC -fno-warn-unused-matches -fno-warn-unused-binds -fno-warn-unused-imports #-}
2 module CoqPass ( coqPassCoreToString, coqPassCoreToCore )
4 import qualified Unique
5 import qualified UniqSupply
6 import qualified MkCore
7 import qualified TysWiredIn
8 import qualified TysPrim
9 import qualified Outputable
10 import qualified PrelNames
11 import qualified OccName
13 import qualified Literal
15 import qualified TypeRep
16 import qualified DataCon
17 import qualified TyCon
18 import qualified Coercion
21 import qualified FastString
22 import qualified BasicTypes
23 import qualified DataCon
24 import qualified CoreSyn
25 import qualified CoreUtils
26 import qualified Class
27 import qualified Data.Char
28 import qualified Data.List
29 import qualified Data.Ord
30 import qualified Data.Typeable
31 import Data.Bits ((.&.), shiftL, (.|.))
32 import Prelude ( (++), (+), (==), Show, show, (.), ($) )
33 import qualified Prelude
34 import qualified GHC.Base
35 import qualified System.IO.Unsafe
37 getTyConTyVars :: TyCon.TyCon -> [Var.TyVar]
39 if TyCon.isFunTyCon tc
41 else if TyCon.isPrimTyCon tc
43 else TyCon.tyConTyVars tc
45 cmpAlts :: (CoreSyn.AltCon,[Var.Var],CoreSyn.Expr Var.Var) -> (CoreSyn.AltCon,[Var.Var],CoreSyn.Expr Var.Var) -> Data.Ord.Ordering
46 cmpAlts (CoreSyn.DEFAULT,_,_) _ = Data.Ord.LT
47 cmpAlts _ (CoreSyn.DEFAULT,_,_) = Data.Ord.GT
48 cmpAlts (a1,_,_) (a2,_,_) = Data.Ord.compare a2 a1
50 sortAlts :: [(CoreSyn.AltCon,[Var.Var],CoreSyn.Expr Var.Var)] -> [(CoreSyn.AltCon,[Var.Var],CoreSyn.Expr Var.Var)]
51 sortAlts x = Data.List.sortBy (\a b -> if a `CoreSyn.ltAlt` b then Data.Ord.LT else Data.Ord.GT) x
53 coreVarToWeakVar :: Var.Var -> CoreVarToWeakVarResult
54 coreVarToWeakVar v | Id.isId v = CVTWVR_EVar (Var.varType v)
55 coreVarToWeakVar v | Var.isTyVar v = CVTWVR_TyVar (coreKindToKind (Var.varType v))
56 coreVarToWeakVar v | Var.isCoVar v = CVTWVR_CoVar (Prelude.fst (Coercion.coercionKind (Var.varType v)))
57 (Prelude.snd (Coercion.coercionKind (Var.varType v)))
58 coreVarToWeakVar _ = Prelude.error "Var.Var that is neither an expression, type variable, nor coercion variable!"
60 rawTyFunKind :: TyCon.TyCon -> ( [Kind] , Kind )
61 rawTyFunKind tc = ((Prelude.map coreKindToKind (Prelude.take (TyCon.tyConArity tc) argk))
63 coreKindToKind (Coercion.mkArrowKinds (Prelude.drop (TyCon.tyConArity tc) argk) retk))
64 where (argk,retk) = Coercion.splitKindFunTys (TyCon.tyConKind tc)
66 tyConOrTyFun :: TyCon.TyCon -> Prelude.Either TyCon.TyCon TyCon.TyCon
68 if n == TysPrim.statePrimTyCon -- special-purpose hack treat State# as a type family since it has kind *->* but no tyvars
70 else if TyCon.isFamInstTyCon n
72 else if TyCon.isSynTyCon n
76 nat2int :: Nat -> Prelude.Int
78 nat2int (S x) = 1 + (nat2int x)
80 natToString :: Nat -> Prelude.String
81 natToString n = show (nat2int n)
83 sanitizeForLatex :: Prelude.String -> Prelude.String
84 sanitizeForLatex [] = []
85 sanitizeForLatex ('_':x) = "\\_"++(sanitizeForLatex x)
86 sanitizeForLatex ('$':x) = "\\$"++(sanitizeForLatex x)
87 sanitizeForLatex ('#':x) = "\\#"++(sanitizeForLatex x)
88 sanitizeForLatex (c:x) = c:(sanitizeForLatex x)
90 kindToCoreKind :: Kind -> TypeRep.Kind
91 kindToCoreKind KindStar = TypeRep.liftedTypeKind
92 kindToCoreKind (KindArrow k1 k2) = Coercion.mkArrowKind (kindToCoreKind k1) (kindToCoreKind k2)
93 kindToCoreKind k = Prelude.error ((Prelude.++)
94 "kindToCoreKind does not know how to handle kind "
96 coreKindToKind :: TypeRep.Kind -> Kind
98 case Coercion.splitKindFunTy_maybe k of
99 Prelude.Just (k1,k2) -> KindArrow (coreKindToKind k1) (coreKindToKind k2)
101 if (Coercion.isLiftedTypeKind k) then KindStar
102 else if (Coercion.isUnliftedTypeKind k) then KindStar
103 else if (Coercion.isArgTypeKind k) then KindStar
104 else if (Coercion.isUbxTupleKind k) then KindStar
105 else if (Coercion.isOpenTypeKind k) then KindStar
107 -- The "subkinding" in GHC is not dealt with in System FC, and dealing
108 -- with it is not actually as simple as you'd think.
110 -- else if (Coercion.isUnliftedTypeKind k) then KindUnliftedType
111 -- else if (Coercion.isOpenTypeKind k) then KindOpenType
112 -- else if (Coercion.isArgTypeKind k) then KindArgType
113 -- else if (Coercion.isUbxTupleKind k) then KindUnboxedTuple
115 else if (Coercion.isTySuperKind k) then Prelude.error "coreKindToKind got the kind-of-the-kind-of-types"
116 else if (Coercion.isCoSuperKind k) then Prelude.error "coreKindToKind got the kind-of-the-kind-of-coercions"
117 else Prelude.error ((Prelude.++) "coreKindToKind got an unknown kind: "
118 (Outputable.showSDoc (Outputable.ppr k)))
119 outputableToString :: Outputable.Outputable a => a -> Prelude.String
120 outputableToString = (\x -> Outputable.showSDocDebug (Outputable.ppr x))
122 coreViewDeep :: Type.Type -> Type.Type
125 TypeRep.TyVarTy tv -> TypeRep.TyVarTy tv
126 TypeRep.FunTy arg res -> TypeRep.FunTy (coreViewDeep arg) (coreViewDeep res)
127 TypeRep.AppTy fun arg -> TypeRep.AppTy (coreViewDeep fun) (coreViewDeep arg)
128 TypeRep.ForAllTy fun arg -> TypeRep.ForAllTy fun (coreViewDeep arg)
129 TypeRep.TyConApp tc tys -> let t' = TypeRep.TyConApp tc (Prelude.map coreViewDeep tys)
130 in case Type.coreView t' of
131 Prelude.Nothing -> t'
132 Prelude.Just t'' -> t''
133 TypeRep.PredTy p -> case Type.coreView t of
134 Prelude.Nothing -> TypeRep.PredTy p
135 Prelude.Just t' -> t'
137 getSourceAndTargetTypesOfCoercion :: Type.Type -> (Type.Type,Type.Type)
138 getSourceAndTargetTypesOfCoercion c = Coercion.coercionKind (Coercion.typeKind c)
141 -- REMEMBER: cotycon applications may be oversaturated
143 TypeRep.TyVarTy v -> WCoVar (WeakCoerVar v (Prelude.error "FIXME") (Prelude.error "FIXME") (Prelude.error "FIXME"))
144 TypeRep.AppTy t1 t2 -> WCoApp (coreCoercionToWeakCoercion t1) (coreCoercionToWeakCoercion t2)
145 TypeRep.TyConApp tc t ->
146 case TyCon.isCoercionTyCon_maybe tc of
147 Prelude.Nothing -> Prelude.error ((Prelude.++) "coreCoercionToWeakCoercion got isCoercionTyCon_maybe " (outputableToString c))
148 Prelude.Just (_, ctcd) ->
150 (TyCon.CoTrans , [x,y] ) -> WCoComp (coreCoercionToWeakCoercion x) (coreCoercionToWeakCoercion y)
151 (TyCon.CoSym , [x] ) -> WCoSym (coreCoercionToWeakCoercion x)
152 (TyCon.CoLeft , [x] ) -> WCoLeft (coreCoercionToWeakCoercion x)
153 (TyCon.CoRight , [x] ) -> WCoLeft (coreCoercionToWeakCoercion x)
154 -- (TyCon.CoUnsafe, [t1, t2 ] ) -> WCoUnsafe (coreTypeToWeakType t1) (coreTypeToWeakType t2)
155 (TyCon.CoTrans , [] ) -> Prelude.error "CoTrans is not in post-publication-appendix SystemFC1"
156 (TyCon.CoCsel1 , [] ) -> Prelude.error "CoCsel1 is not in post-publication-appendix SystemFC1"
157 (TyCon.CoCsel2 , [] ) -> Prelude.error "CoCsel2 is not in post-publication-appendix SystemFC1"
158 (TyCon.CoCselR , [] ) -> Prelude.error "CoCselR is not in post-publication-appendix SystemFC1"
159 (TyCon.CoInst , [] ) -> Prelude.error "CoInst is not in post-publication-appendix SystemFC1"
160 (TyCon.CoAxiom _ _ _ , _ ) -> Prelude.error "CoAxiom is not yet implemented (FIXME)"
161 ( _, [ t1 , t2 ]) -> WCoUnsafe (errOrFail (coreTypeToWeakType t1)) (errOrFail (coreTypeToWeakType t2))
162 _ -> Prelude.error ((Prelude.++) "coreCoercionToWeakCoercion got " (outputableToString c))
163 _ -> Prelude.error ((Prelude.++) "coreCoercionToWeakCoercion got " (outputableToString c))
165 -- TypeRep.ForAllTy v t -> WCoAll (Prelude.error "FIXME") (coreTypeToWeakType t)
166 -- FIXME x y -> WCoAppT (coreCoercionToWeakCoercion x) (coreCoercionToWeakType y)
167 -- CoreSyn.Type t -> WCoType (coreTypeToWeakType t)
170 weakCoercionToCoreCoercion :: CoreCoercion -> Type.Type
171 | WCoVar (weakCoerVar _ _ t1 t2) => (t1,t2)
172 | WCoType t => Prelude_error "FIXME WCoType"
173 | WCoApp c1 c2 => Prelude_error "FIXME WCoApp"
174 | WCoAppT c t => Prelude_error "FIXME WCoAppT"
175 | WCoAll k f => Prelude_error "FIXME WCoAll"
176 | WCoSym c => let (t2,t1) := weakCoercionTypes c in (t1,t2)
177 | WCoComp c1 c2 => Prelude_error "FIXME WCoComp"
178 | WCoLeft c => Prelude_error "FIXME WCoLeft"
179 | WCoRight c => Prelude_error "FIXME WCoRight"
180 | WCoUnsafe t1 t2 => (t1,t2)
183 {-# NOINLINE trace #-}
184 trace :: Prelude.String -> a -> a
187 --trace = Debug.Trace.trace
189 --trace msg x = System.IO.Unsafe.unsafePerformIO $ Prelude.return x
191 --trace msg x = System.IO.Unsafe.unsafePerformIO $
192 -- (Prelude.>>=) (System.IO.hPutStrLn System.IO.stdout msg) (\_ -> Prelude.return x)
193 --trace msg x = System.IO.Unsafe.unsafePerformIO $
194 -- (Prelude.>>=) (System.IO.hPutStr System.IO.stdout " ") (\_ -> Prelude.return x)
197 {- -- used for extracting strings WITHOUT the patch for Coq
199 (\ b0 b1 b2 b3 b4 b5 b6 b7 ->
200 let f b i = if b then 1 `shiftL` i else 0
201 in Data.Char.chr (f b0 0 .|. f b1 1 .|. f b2 2 .|. f b3 3 .|. f b4 4 .|. f b5 5 .|. f b6 6 .|. f b7 7))
204 -- I'm leaving this here (commented out) in case I ever need it again)
205 --checkTypeEquality :: Type.Type -> Type.Type -> Prelude.Bool
206 --checkTypeEquality t1 t2 = Type.tcEqType (Type.expandTypeSynonyms t1) (Type.expandTypeSynonyms t2)