Improve External Core syntax for newtypes
[ghc-hetmet.git] / compiler / coreSyn / MkExternalCore.lhs
1
2 % (c) The University of Glasgow 2001-2006
3 %
4 \begin{code}
5 module MkExternalCore (
6         emitExternalCore
7 ) where
8
9 #include "HsVersions.h"
10
11 import qualified ExternalCore as C
12 import Module
13 import CoreSyn
14 import HscTypes 
15 import TyCon
16 import TypeRep
17 import Type
18 import PprExternalCore () -- Instances
19 import DataCon
20 import Coercion
21 import Var
22 import IdInfo
23 import Literal
24 import Name
25 import Outputable
26 import Encoding
27 import ForeignCall
28 import DynFlags
29 import StaticFlags
30 import FastString
31
32 import IO
33 import Data.Char
34
35 emitExternalCore :: DynFlags -> CgGuts -> IO ()
36 emitExternalCore dflags cg_guts
37  | opt_EmitExternalCore 
38  = (do handle <- openFile corename WriteMode
39        hPutStrLn handle (show (mkExternalCore cg_guts))      
40        hClose handle)
41    `catch` (\_ -> pprPanic "Failed to open or write external core output file"
42                            (text corename))
43    where corename = extCoreName dflags
44 emitExternalCore _ _
45  | otherwise
46  = return ()
47
48 -- Reinventing the Reader monad; whee.
49 newtype CoreM a = CoreM (CoreState -> (CoreState, a))
50 type CoreState = Module
51 instance Monad CoreM where
52   (CoreM m) >>= f = CoreM (\ s -> case m s of
53                                     (s',r) -> case f r of
54                                                 CoreM f' -> f' s')
55   return x = CoreM (\ s -> (s, x))
56 runCoreM :: CoreM a -> CoreState -> a
57 runCoreM (CoreM f) s = snd $ f s
58 ask :: CoreM CoreState
59 ask = CoreM (\ s -> (s,s))
60
61 mkExternalCore :: CgGuts -> C.Module
62 -- The ModGuts has been tidied, but the implicit bindings have
63 -- not been injected, so we have to add them manually here
64 -- We don't include the strange data-con *workers* because they are
65 -- implicit in the data type declaration itself
66 mkExternalCore (CgGuts {cg_module=this_mod, cg_tycons = tycons, 
67                         cg_binds = binds})
68  -- Note that we flatten binds at the top level:
69  -- every module is just a single recursive bag of declarations.
70  -- Rationale: since modules can be mutually recursive, 
71  -- there's not much reason to preserve dependency info within a module.
72   = C.Module mname tdefs (case flattenBinds binds of
73                           -- check for empty list so we don't create an
74                           -- empty Rec group
75                             [] -> []
76                             bs  -> [(runCoreM (make_vdef True
77                                       (Rec bs)) this_mod)])
78   where
79     mname  = make_mid this_mod
80     tdefs  = foldr collect_tdefs [] tycons
81
82 collect_tdefs :: TyCon -> [C.Tdef] -> [C.Tdef]
83 collect_tdefs tcon tdefs 
84   | isAlgTyCon tcon = tdef: tdefs
85   where
86     tdef | isNewTyCon tcon = 
87                 C.Newtype (qtc tcon) 
88                   (case newTyConCo_maybe tcon of
89                      Just co -> qtc co
90                      Nothing       -> pprPanic ("MkExternalCore: newtype tcon\
91                                        should have a coercion: ") (ppr tcon))
92                   (map make_tbind tyvars) 
93                    repclause 
94          | otherwise = 
95                 C.Data (qtc tcon) (map make_tbind tyvars) 
96                    (map make_cdef (tyConDataCons tcon)) 
97          where repclause | isRecursiveTyCon tcon || isOpenTyCon tcon= Nothing
98                          | otherwise = Just (make_ty (snd (newTyConRhs tcon)))
99     tyvars = tyConTyVars tcon
100
101 collect_tdefs _ tdefs = tdefs
102
103 qtc :: TyCon -> C.Qual C.Tcon
104 qtc = make_con_qid . tyConName
105
106
107 make_cdef :: DataCon -> C.Cdef
108 make_cdef dcon =  C.Constr dcon_name existentials tys
109   where 
110     dcon_name    = make_qid False False (dataConName dcon)
111     existentials = map make_tbind ex_tyvars
112     ex_tyvars    = dataConExTyVars dcon
113     tys          = map make_ty (dataConRepArgTys dcon)
114
115 make_tbind :: TyVar -> C.Tbind
116 make_tbind tv = (make_var_id (tyVarName tv), make_kind (tyVarKind tv))
117     
118 make_vbind :: Var -> C.Vbind
119 make_vbind v = (make_var_id  (Var.varName v), make_ty (idType v))
120
121 make_vdef :: Bool -> CoreBind -> CoreM C.Vdefg
122 make_vdef topLevel b = 
123   case b of
124     NonRec v e -> f (v,e)     >>= (return . C.Nonrec)
125     Rec ves    -> mapM f ves  >>= (return . C.Rec)
126   where
127   f :: (CoreBndr,CoreExpr) -> CoreM C.Vdef
128   f (v,e) = do
129           localN <- isALocal vName
130           let local = not topLevel || localN
131           rhs <- make_exp e
132           -- use local flag to determine where to add the module name
133           return (local, make_qid local True vName, make_ty (idType v),rhs)
134         where vName = Var.varName v
135
136 make_exp :: CoreExpr -> CoreM C.Exp
137 make_exp (Var v) = do
138   let vName = Var.varName v
139   isLocal <- isALocal vName
140   return $
141      case globalIdDetails v of
142        FCallId (CCall (CCallSpec (StaticTarget nm) callconv _)) 
143            -> C.External (unpackFS nm) (showSDoc (ppr callconv)) (make_ty (idType v))
144        FCallId (CCall (CCallSpec DynamicTarget     callconv _)) 
145            -> C.DynExternal            (showSDoc (ppr callconv)) (make_ty (idType v))
146        FCallId _ 
147            -> pprPanic "MkExternalCore died: can't handle non-{static,dynamic}-C foreign call"
148                     (ppr v)
149        -- Constructors are always exported, so make sure to declare them
150        -- with qualified names
151        DataConWorkId _ -> C.Var (make_var_qid False vName)
152        DataConWrapId _ -> C.Var (make_var_qid False vName)
153        _ -> C.Var (make_var_qid isLocal vName)
154 make_exp (Lit (MachLabel s _)) = return $ C.Label (unpackFS s)
155 make_exp (Lit l) = return $ C.Lit (make_lit l)
156 make_exp (App e (Type t)) = make_exp e >>= (\ b -> return $ C.Appt b (make_ty t))
157 make_exp (App e1 e2) = do
158    rator <- make_exp e1
159    rand <- make_exp e2
160    return $ C.App rator rand
161 make_exp (Lam v e) | isTyVar v = make_exp e >>= (\ b -> 
162                                     return $ C.Lam (C.Tb (make_tbind v)) b)
163 make_exp (Lam v e) | otherwise = make_exp e >>= (\ b -> 
164                                     return $ C.Lam (C.Vb (make_vbind v)) b)
165 make_exp (Cast e co) = make_exp e >>= (\ b -> return $ C.Cast b (make_ty co))
166 make_exp (Let b e) = do
167   vd   <- make_vdef False b
168   body <- make_exp e
169   return $ C.Let vd body
170 make_exp (Case e v ty alts) = do
171   scrut <- make_exp e
172   newAlts  <- mapM make_alt alts
173   return $ C.Case scrut (make_vbind v) (make_ty ty) newAlts
174 make_exp (Note (SCC _) e) = make_exp e >>= (return . C.Note "SCC") -- temporary
175 make_exp (Note (CoreNote s) e) = make_exp e >>= (return . C.Note s)  -- hdaume: core annotations
176 make_exp (Note InlineMe e) = make_exp e >>= (return . C.Note "InlineMe")
177 make_exp _ = error "MkExternalCore died: make_exp"
178
179 make_alt :: CoreAlt -> CoreM C.Alt
180 make_alt (DataAlt dcon, vs, e) = do
181     newE <- make_exp e
182     return $ C.Acon (make_con_qid (dataConName dcon))
183            (map make_tbind tbs)
184            (map make_vbind vbs)
185            newE
186         where (tbs,vbs) = span isTyVar vs
187 make_alt (LitAlt l,_,e)   = make_exp e >>= (return . (C.Alit (make_lit l)))
188 make_alt (DEFAULT,[],e)   = make_exp e >>= (return . C.Adefault)
189 -- This should never happen, as the DEFAULT alternative binds no variables,
190 -- but we might as well check for it:
191 make_alt a@(DEFAULT,_ ,_) = pprPanic ("MkExternalCore: make_alt: DEFAULT "
192              ++ "alternative had a non-empty var list") (ppr a)
193
194
195 make_lit :: Literal -> C.Lit
196 make_lit l = 
197   case l of
198     -- Note that we need to check whether the character is "big".
199     -- External Core only allows character literals up to '\xff'.
200     MachChar i | i <= chr 0xff -> C.Lchar i t
201     -- For a character bigger than 0xff, we represent it in ext-core
202     -- as an int lit with a char type.
203     MachChar i             -> C.Lint (fromIntegral $ ord i) t 
204     MachStr s -> C.Lstring (unpackFS s) t
205     MachNullAddr -> C.Lint 0 t
206     MachInt i -> C.Lint i t
207     MachInt64 i -> C.Lint i t
208     MachWord i -> C.Lint i t
209     MachWord64 i -> C.Lint i t
210     MachFloat r -> C.Lrational r t
211     MachDouble r -> C.Lrational r t
212     _ -> error "MkExternalCore died: make_lit"
213   where 
214     t = make_ty (literalType l)
215
216 -- Expand type synonyms, then convert.
217 make_ty :: Type -> C.Ty                 -- Be sure to expand types recursively!
218                                         -- example: FilePath ~> String ~> [Char]
219 make_ty t | Just expanded <- tcView t = make_ty expanded
220 make_ty t = make_ty' t
221  
222 -- note calls to make_ty so as to expand types recursively
223 make_ty' :: Type -> C.Ty
224 make_ty' (TyVarTy tv)            = C.Tvar (make_var_id (tyVarName tv))
225 make_ty' (AppTy t1 t2)           = C.Tapp (make_ty t1) (make_ty t2)
226 make_ty' (FunTy t1 t2)           = make_ty (TyConApp funTyCon [t1,t2])
227 make_ty' (ForAllTy tv t)         = C.Tforall (make_tbind tv) (make_ty t)
228 make_ty' (TyConApp tc ts)        = foldl C.Tapp (C.Tcon (qtc tc)) 
229                                          (map make_ty ts)
230 -- Newtypes are treated just like any other type constructor; not expanded
231 -- Reason: predTypeRep does substitution and, while substitution deals
232 --         correctly with name capture, it's only correct if you see the uniques!
233 --         If you just see occurrence names, name capture may occur.
234 -- Example: newtype A a = A (forall b. b -> a)
235 --          test :: forall q b. q -> A b
236 --          test _ = undefined
237 --      Here the 'a' gets substituted by 'b', which is captured.
238 -- Another solution would be to expand newtypes before tidying; but that would
239 -- expose the representation in interface files, which definitely isn't right.
240 -- Maybe CoreTidy should know whether to expand newtypes or not?
241
242 make_ty' (PredTy p)     = make_ty (predTypeRep p)
243
244
245
246 make_kind :: Kind -> C.Kind
247 make_kind (PredTy p) | isEqPred p = C.Keq (make_ty t1) (make_ty t2)
248     where (t1, t2) = getEqPredTys p
249 make_kind (FunTy k1 k2)  = C.Karrow (make_kind k1) (make_kind k2)
250 make_kind k
251   | isLiftedTypeKind k   = C.Klifted
252   | isUnliftedTypeKind k = C.Kunlifted
253   | isOpenTypeKind k     = C.Kopen
254 make_kind _ = error "MkExternalCore died: make_kind"
255
256 {- Id generation. -}
257
258 make_id :: Bool -> Name -> C.Id
259 -- include uniques for internal names in order to avoid name shadowing
260 make_id _is_var nm = ((occNameString . nameOccName) nm)
261   ++ (if isInternalName nm then (show . nameUnique) nm else "")
262
263 make_var_id :: Name -> C.Id
264 make_var_id = make_id True
265
266 -- It's important to encode the module name here, because in External Core,
267 -- base:GHC.Base => base:GHCziBase
268 -- We don't do this in pprExternalCore because we
269 -- *do* want to keep the package name (we don't want baseZCGHCziBase,
270 -- because that would just be ugly.)
271 -- SIGH.
272 -- We encode the package name as well.
273 make_mid :: Module -> C.Id
274 -- Super ugly code, but I can't find anything else that does quite what I
275 -- want (encodes the hierarchical module name without encoding the colon
276 -- that separates the package name from it.)
277 make_mid m = showSDoc $
278               (text $ zEncodeString $ packageIdString $ modulePackageId m)
279               <> text ":"
280               <> (pprEncoded $ pprModuleName $ moduleName m)
281      where pprEncoded = pprCode CStyle
282                
283 make_qid :: Bool -> Bool -> Name -> C.Qual C.Id
284 make_qid force_unqual is_var n = (mname,make_id is_var n)
285     where mname = 
286            case nameModule_maybe n of
287             Just m | not force_unqual -> make_mid m
288             _ -> "" 
289
290 make_var_qid :: Bool -> Name -> C.Qual C.Id
291 make_var_qid force_unqual = make_qid force_unqual True
292
293 make_con_qid :: Name -> C.Qual C.Id
294 make_con_qid = make_qid False False
295
296 -------
297 isALocal :: Name -> CoreM Bool
298 isALocal vName = do
299   modName <- ask
300   return $ case nameModule_maybe vName of
301              -- Not sure whether isInternalName corresponds to "local"ness
302              -- in the External Core sense; need to re-read the spec.
303              Just m | m == modName -> isInternalName vName
304              _                     -> False
305 \end{code}
306
307
308
309