change name of string-extraction placeholder
[coq-hetmet.git] / src / Extraction-prefix.hs
1 module CoqPass ( coqPassCoreToString, coqPassCoreToCore )
2 where
3 import qualified Unique
4 import qualified UniqSupply
5 import qualified MkCore
6 import qualified TysWiredIn
7 import qualified TysPrim
8 import qualified Outputable
9 import qualified PrelNames
10 import qualified OccName
11 import qualified Name
12 import qualified Literal
13 import qualified Type
14 import qualified TypeRep
15 import qualified DataCon
16 import qualified TyCon
17 import qualified Coercion
18 import qualified Var
19 import qualified Id
20 import qualified FastString
21 import qualified BasicTypes
22 import qualified DataCon
23 import qualified CoreSyn
24 import qualified CoreUtils
25 import qualified Class
26 import qualified Data.Char 
27 import qualified Data.List
28 import qualified Data.Ord
29 import qualified Data.Typeable
30 import Data.Bits ((.&.), shiftL, (.|.))
31 import Prelude ( (++), (+), (==), Show, show, Char, (.), ($) )
32 import qualified Prelude
33 import qualified Debug.Trace
34 import qualified GHC.Base
35 import qualified System.IO
36 import qualified System.IO.Unsafe
37
38 getTyConTyVars :: TyCon.TyCon -> [Var.TyVar]
39 getTyConTyVars tc =
40   if TyCon.isFunTyCon tc
41   then []
42   else if TyCon.isPrimTyCon tc
43        then []
44        else TyCon.tyConTyVars tc
45
46 cmpAlts :: (CoreSyn.AltCon,[Var.Var],CoreSyn.Expr Var.Var) -> (CoreSyn.AltCon,[Var.Var],CoreSyn.Expr Var.Var) -> Data.Ord.Ordering
47 cmpAlts (CoreSyn.DEFAULT,_,_) _   = Data.Ord.LT
48 cmpAlts _ (CoreSyn.DEFAULT,_,_)   = Data.Ord.GT
49 cmpAlts (a1,_,_) (a2,_,_)         = Data.Ord.compare a2 a1
50
51 sortAlts :: [(CoreSyn.AltCon,[Var.Var],CoreSyn.Expr Var.Var)] -> [(CoreSyn.AltCon,[Var.Var],CoreSyn.Expr Var.Var)]
52 sortAlts x = Data.List.sortBy (\a b -> if a `CoreSyn.ltAlt` b then Data.Ord.LT else Data.Ord.GT) x
53
54 -- to do: this could be moved into Coq
55 coreVarToWeakVar :: Var.Var -> WeakVar
56 coreVarToWeakVar v | Id.isId     v = WExprVar (WeakExprVar v (errOrFail (coreTypeToWeakType (Var.varType v))))
57  where
58   errOrFail (OK x)    = x
59   errOrFail (Error s) = Prelude.error s
60 coreVarToWeakVar v | Var.isTyVar v = WTypeVar (WeakTypeVar v (coreKindToKind (Var.varType v)))
61 coreVarToWeakVar v | Var.isCoVar v = WCoerVar (WeakCoerVar v (Prelude.error "FIXME") 
62                                                              (Prelude.error "FIXME") (Prelude.error "FIXME"))
63 coreVarToWeakVar _                 =
64    Prelude.error "Var.Var that is neither an expression variable, type variable, nor coercion variable!"
65
66 tyConOrTyFun :: TyCon.TyCon -> Prelude.Either TyCon.TyCon TyCon.TyCon
67 tyConOrTyFun n =
68    if n == TysPrim.statePrimTyCon     -- special-purpose hack treat State# as a type family since it has kind *->* but no tyvars
69    then Prelude.Right n
70    else if TyCon.isFamInstTyCon n
71         then Prelude.Right n
72         else Prelude.Left n
73
74 nat2int :: Nat -> Prelude.Int
75 nat2int O     = 0
76 nat2int (S x) = 1 + (nat2int x)
77
78 natToString :: Nat -> Prelude.String
79 natToString n = show (nat2int n)
80
81 -- only needs to sanitize characters which might appear in Haskell identifiers
82 sanitizeForLatex :: Prelude.String -> Prelude.String
83 sanitizeForLatex []      = []
84 sanitizeForLatex ('_':x) = "\\_"++(sanitizeForLatex x)
85 sanitizeForLatex ('$':x) = "\\$"++(sanitizeForLatex x)
86 sanitizeForLatex ('#':x) = "\\#"++(sanitizeForLatex x)
87 sanitizeForLatex (c:x)   = c:(sanitizeForLatex x)
88
89 kindToCoreKind :: Kind -> TypeRep.Kind
90 kindToCoreKind KindStar          = TypeRep.liftedTypeKind
91 kindToCoreKind (KindArrow k1 k2) = Coercion.mkArrowKind (kindToCoreKind k1) (kindToCoreKind k2)
92 kindToCoreKind _                 = Prelude.error "kindToCoreKind does not know how to handle that"
93
94 coreKindToKind :: TypeRep.Kind -> Kind
95 coreKindToKind k =
96   case Coercion.splitKindFunTy_maybe k of
97       Prelude.Just (k1,k2) -> KindArrow (coreKindToKind k1) (coreKindToKind k2)
98       Prelude.Nothing -> 
99                       if (Coercion.isLiftedTypeKind k)   then KindStar
100                  else if (Coercion.isUnliftedTypeKind k) then KindStar
101                  else if (Coercion.isArgTypeKind k)      then KindStar
102                  else if (Coercion.isUbxTupleKind k)     then KindStar
103                  else if (Coercion.isOpenTypeKind k)     then KindStar
104 --                 else if (Coercion.isUnliftedTypeKind k) then KindUnliftedType
105 --                 else if (Coercion.isOpenTypeKind k)     then KindOpenType
106 --                 else if (Coercion.isArgTypeKind k)      then KindArgType
107 --                 else if (Coercion.isUbxTupleKind k)     then KindUnboxedTuple
108                  else if (Coercion.isTySuperKind k)      then Prelude.error "coreKindToKind got the kind-of-the-kind-of-types"
109                  else if (Coercion.isCoSuperKind k)      then Prelude.error "coreKindToKind got the kind-of-the-kind-of-coercions"
110                  else                                         Prelude.error ((Prelude.++) "coreKindToKind got an unknown kind: "
111                                                                                (Outputable.showSDoc (Outputable.ppr k)))
112 outputableToString :: Outputable.Outputable a => a -> Prelude.String
113 outputableToString = (\x -> Outputable.showSDoc (Outputable.ppr x))
114
115 -- I'm leaving this here (commented out) in case I ever need it again)
116 --checkTypeEquality :: Type.Type -> Type.Type -> Prelude.Bool
117 --checkTypeEquality t1 t2 = Type.tcEqType (Type.expandTypeSynonyms t1) (Type.expandTypeSynonyms t2)
118
119 coreViewDeep :: Type.Type -> Type.Type
120 coreViewDeep t =
121     case t of
122       TypeRep.TyVarTy tv       -> TypeRep.TyVarTy tv
123       TypeRep.FunTy arg res    -> TypeRep.FunTy (coreViewDeep arg) (coreViewDeep res)
124       TypeRep.AppTy fun arg    -> TypeRep.AppTy (coreViewDeep fun) (coreViewDeep arg)
125       TypeRep.ForAllTy fun arg -> TypeRep.ForAllTy fun (coreViewDeep arg)
126       TypeRep.TyConApp tc tys  -> let t' = TypeRep.TyConApp tc (Prelude.map coreViewDeep tys)
127                         in case Type.coreView t' of
128                                Prelude.Nothing     -> t'
129                                Prelude.Just    t'' -> t''
130       TypeRep.PredTy p         -> case Type.coreView t of
131                                Prelude.Nothing     -> TypeRep.PredTy p
132                                Prelude.Just    t'  -> t'
133
134 -- FIXME: cotycon applications may be oversaturated
135 coreCoercionToWeakCoercion :: Type.Type -> WeakCoercion
136 coreCoercionToWeakCoercion c =
137  case c of
138   TypeRep.TyVarTy  v     -> WCoVar (WeakCoerVar v (Prelude.error "FIXME") (Prelude.error "FIXME") (Prelude.error "FIXME"))
139   TypeRep.AppTy    t1 t2 -> WCoApp   (coreCoercionToWeakCoercion t1) (coreCoercionToWeakCoercion t2)
140   TypeRep.TyConApp tc t  ->
141       case TyCon.isCoercionTyCon_maybe tc of
142         Prelude.Nothing -> Prelude.error ((Prelude.++) "coreCoercionToWeakCoercion got " (outputableToString c))
143         Prelude.Just (_, ctcd) ->
144             case (ctcd,t) of
145               (TyCon.CoTrans , [x,y]     ) -> WCoComp   (coreCoercionToWeakCoercion x) (coreCoercionToWeakCoercion y)
146               (TyCon.CoSym   , [x]       ) -> WCoSym    (coreCoercionToWeakCoercion x)
147               (TyCon.CoLeft  , [x]       ) -> WCoLeft   (coreCoercionToWeakCoercion x)
148               (TyCon.CoRight , [x]       ) -> WCoLeft   (coreCoercionToWeakCoercion x)
149 -- FIXME      (TyCon.CoUnsafe, [t1, t2 ] ) -> WCoUnsafe (coreTypeToWeakType t1) (coreTypeToWeakType t2)
150               (TyCon.CoTrans , []        ) -> Prelude.error "CoTrans is not in post-publication-appendix SystemFC1"
151               (TyCon.CoCsel1 , []        ) -> Prelude.error "CoCsel1 is not in post-publication-appendix SystemFC1"
152               (TyCon.CoCsel2 , []        ) -> Prelude.error "CoCsel2 is not in post-publication-appendix SystemFC1"
153               (TyCon.CoCselR , []        ) -> Prelude.error "CoCselR is not in post-publication-appendix SystemFC1"
154               (TyCon.CoInst  , []        ) -> Prelude.error "CoInst  is not in post-publication-appendix SystemFC1"
155               (TyCon.CoAxiom , []        ) -> Prelude.error "CoAxiom is not yet implemented (FIXME)"
156               _ -> Prelude.error ((Prelude.++) "coreCoercionToWeakCoercion got " (outputableToString c))
157   _ -> Prelude.error ((Prelude.++) "coreCoercionToWeakCoercion got " (outputableToString c))
158 --  TypeRep.ForAllTy v t   -> WCoAll  (Prelude.error "FIXME") (coreTypeToWeakType t)
159 -- FIXME   x y                                  -> WCoAppT    (coreCoercionToWeakCoercion x) (coreCoercionToWeakType y)
160 --  CoreSyn.Type t                            -> WCoType   (coreTypeToWeakType t)
161
162 {-
163 weakCoercionToCoreCoercion :: CoreCoercion -> Type.Type
164 | WCoVar     (weakCoerVar _ _ t1 t2) => (t1,t2)
165 | WCoType    t                       => Prelude_error "FIXME WCoType"
166 | WCoApp     c1 c2                   => Prelude_error "FIXME WCoApp"
167 | WCoAppT    c t                     => Prelude_error "FIXME WCoAppT"
168 | WCoAll     k f                     => Prelude_error "FIXME WCoAll"
169 | WCoSym     c                       => let (t2,t1) := weakCoercionTypes c in (t1,t2)
170 | WCoComp    c1 c2                   => Prelude_error "FIXME WCoComp"
171 | WCoLeft    c                       => Prelude_error "FIXME WCoLeft"
172 | WCoRight   c                       => Prelude_error "FIXME WCoRight"
173 | WCoUnsafe  t1 t2                   => (t1,t2)
174 -}
175
176
177 --trace = Debug.Trace.trace
178 --trace msg x = x
179 trace msg x = System.IO.Unsafe.unsafePerformIO $ Prelude.return x
180 {-
181 trace s x = x
182 trace msg x = System.IO.Unsafe.unsafePerformIO $
183                 (Prelude.>>=) (System.IO.hPutStrLn System.IO.stdout msg) (\_ -> Prelude.return x)
184 trace msg x = System.IO.Unsafe.unsafePerformIO $
185                 (Prelude.>>=) (System.IO.hPutStr System.IO.stdout " ") (\_ -> Prelude.return x)
186 -}
187
188 {-  -- used for extracting strings WITHOUT the patch for Coq
189 bin2ascii =
190   (\ b0 b1 b2 b3 b4 b5 b6 b7 ->
191      let f b i = if b then 1 `shiftL` i else 0
192      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))
193 -}