[project @ 2003-11-06 17:09:50 by simonpj]
[ghc-hetmet.git] / ghc / compiler / hsSyn / Convert.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
3 %
4
5 This module converts Template Haskell syntax into HsSyn
6
7
8 \begin{code}
9 module Convert( convertToHsExpr, convertToHsDecls ) where
10
11 #include "HsVersions.h"
12
13 import Language.Haskell.TH.THSyntax as TH
14 import Language.Haskell.TH.THLib    as TH       -- Pretty printing
15
16 import HsSyn as Hs
17         (       HsExpr(..), HsLit(..), ArithSeqInfo(..), 
18                 HsStmtContext(..), TyClDecl(..), HsBang(..),
19                 Match(..), GRHSs(..), GRHS(..), HsPred(..),
20                 HsDecl(..), TyClDecl(..), InstDecl(..), ConDecl(..),
21                 Stmt(..), HsBinds(..), MonoBinds(..), Sig(..),
22                 Pat(..), HsConDetails(..), HsOverLit, BangType(..),
23                 placeHolderType, HsType(..), HsExplicitForAll(..),
24                 HsTyVarBndr(..), HsContext,
25                 mkSimpleMatch, mkImplicitHsForAllTy, mkExplicitHsForAllTy
26         ) 
27
28 import RdrName  ( RdrName, mkRdrUnqual, mkRdrQual, mkOrig, nameRdrName, getRdrName )
29 import Module   ( ModuleName, mkModuleName )
30 import RdrHsSyn ( mkHsIntegral, mkHsFractional, mkClassDecl, mkTyData )
31 import Name     ( mkInternalName )
32 import qualified OccName
33 import SrcLoc   ( SrcLoc, generatedSrcLoc )
34 import Type     ( Type )
35 import TysWiredIn ( unitTyCon, tupleTyCon, trueDataCon, falseDataCon )
36 import BasicTypes( Boxity(..), RecFlag(Recursive), NewOrData(..) )
37 import ForeignCall ( Safety(..), CCallConv(..), CCallTarget(..),
38                      CExportSpec(..)) 
39 import HsDecls ( CImportSpec(..), ForeignImport(..), ForeignExport(..),
40                  ForeignDecl(..) )
41 import FastString( FastString, mkFastString, nilFS )
42 import Char     ( ord, isAscii, isAlphaNum, isAlpha )
43 import List     ( partition )
44 import SrcLoc   ( noSrcLoc )
45 import Unique   ( Unique, mkUniqueGrimily )
46 import ErrUtils (Message)
47 import GLAEXTS  ( Int#, Int(..) )
48 import Outputable
49
50
51 -------------------------------------------------------------------
52 convertToHsDecls :: [TH.Dec] -> [Either (HsDecl RdrName) Message]
53 convertToHsDecls ds = map cvt_top ds
54
55 mk_con con = case con of
56         NormalC c strtys
57          -> ConDecl (cName c) noExistentials noContext
58                   (PrefixCon (map mk_arg strtys)) loc0
59         RecC c varstrtys
60          -> ConDecl (cName c) noExistentials noContext
61                   (RecCon (map mk_id_arg varstrtys)) loc0
62         InfixC st1 c st2
63          -> ConDecl (cName c) noExistentials noContext
64                   (InfixCon (mk_arg st1) (mk_arg st2)) loc0
65   where
66     mk_arg (IsStrict, ty)  = BangType HsStrict (cvtType ty)
67     mk_arg (NotStrict, ty) = BangType HsNoBang (cvtType ty)
68
69     mk_id_arg (i, IsStrict, ty)
70         = (vName i, BangType HsStrict (cvtType ty))
71     mk_id_arg (i, NotStrict, ty)
72         = (vName i, BangType HsNoBang (cvtType ty))
73
74 mk_derivs [] = Nothing
75 mk_derivs cs = Just [HsClassP (tconName c) [] | c <- cs]
76
77 cvt_top :: TH.Dec -> Either (HsDecl RdrName) Message
78 cvt_top d@(TH.ValD _ _ _) = Left $ Hs.ValD (cvtd d)
79 cvt_top d@(TH.FunD _ _)   = Left $ Hs.ValD (cvtd d)
80  
81 cvt_top (TySynD tc tvs rhs)
82   = Left $ TyClD (TySynonym (tconName tc) (cvt_tvs tvs) (cvtType rhs) loc0)
83
84 cvt_top (DataD ctxt tc tvs constrs derivs)
85   = Left $ TyClD (mkTyData DataType 
86                            (cvt_context ctxt, tconName tc, cvt_tvs tvs)
87                            (map mk_con constrs)
88                            (mk_derivs derivs) loc0)
89
90 cvt_top (NewtypeD ctxt tc tvs constr derivs)
91   = Left $ TyClD (mkTyData NewType 
92                            (cvt_context ctxt, tconName tc, cvt_tvs tvs)
93                            [mk_con constr]
94                            (mk_derivs derivs) loc0)
95
96 cvt_top (ClassD ctxt cl tvs decs)
97   = Left $ TyClD (mkClassDecl (cvt_context ctxt, tconName cl, cvt_tvs tvs)
98                               noFunDeps sigs
99                               binds loc0)
100   where
101     (binds,sigs) = cvtBindsAndSigs decs
102
103 cvt_top (InstanceD tys ty decs)
104   = Left $ InstD (InstDecl inst_ty binds sigs loc0)
105   where
106     (binds, sigs) = cvtBindsAndSigs decs
107     inst_ty = mkImplicitHsForAllTy (cvt_context tys) (HsPredTy (cvt_pred ty))
108
109 cvt_top (TH.SigD nm typ) = Left $ Hs.SigD (Sig (vName nm) (cvtType typ) loc0)
110
111 cvt_top (ForeignD (ImportF callconv safety from nm typ))
112  = case parsed of
113        Just (c_header, cis) ->
114            let i = CImport callconv' safety' c_header nilFS cis
115            in Left $ ForD (ForeignImport (vName nm) (cvtType typ) i False loc0)
116        Nothing -> Right $     text (show from)
117                           <+> ptext SLIT("is not a valid ccall impent")
118     where callconv' = case callconv of
119                           CCall -> CCallConv
120                           StdCall -> StdCallConv
121           safety' = case safety of
122                         Unsafe     -> PlayRisky
123                         Safe       -> PlaySafe False
124                         Threadsafe -> PlaySafe True
125           parsed = parse_ccall_impent (TH.nameBase nm) from
126
127 cvt_top (ForeignD (ExportF callconv as nm typ))
128  = let e = CExport (CExportStatic (mkFastString as) callconv')
129    in Left $ ForD (ForeignExport (vName nm) (cvtType typ) e False loc0)
130     where callconv' = case callconv of
131                           CCall -> CCallConv
132                           StdCall -> StdCallConv
133
134 parse_ccall_impent :: String -> String -> Maybe (FastString, CImportSpec)
135 parse_ccall_impent nm s
136  = case lex_ccall_impent s of
137        Just ["dynamic"] -> Just (nilFS, CFunction DynamicTarget)
138        Just ["wrapper"] -> Just (nilFS, CWrapper)
139        Just ("static":ts) -> parse_ccall_impent_static nm ts
140        Just ts -> parse_ccall_impent_static nm ts
141        Nothing -> Nothing
142
143 parse_ccall_impent_static :: String
144                           -> [String]
145                           -> Maybe (FastString, CImportSpec)
146 parse_ccall_impent_static nm ts
147  = let ts' = case ts of
148                  [       "&", cid] -> [       cid]
149                  [fname, "&"     ] -> [fname     ]
150                  [fname, "&", cid] -> [fname, cid]
151                  _                 -> ts
152    in case ts' of
153           [       cid] | is_cid cid -> Just (nilFS,              mk_cid cid)
154           [fname, cid] | is_cid cid -> Just (mkFastString fname, mk_cid cid)
155           [          ]              -> Just (nilFS,              mk_cid nm)
156           [fname     ]              -> Just (mkFastString fname, mk_cid nm)
157           _                         -> Nothing
158     where is_cid :: String -> Bool
159           is_cid x = all (/= '.') x && (isAlpha (head x) || head x == '_')
160           mk_cid :: String -> CImportSpec
161           mk_cid  = CFunction . StaticTarget . mkFastString
162
163 lex_ccall_impent :: String -> Maybe [String]
164 lex_ccall_impent "" = Just []
165 lex_ccall_impent ('&':xs) = fmap ("&":) $ lex_ccall_impent xs
166 lex_ccall_impent (' ':xs) = lex_ccall_impent xs
167 lex_ccall_impent ('\t':xs) = lex_ccall_impent xs
168 lex_ccall_impent xs = case span is_valid xs of
169                           ("", _) -> Nothing
170                           (t, xs') -> fmap (t:) $ lex_ccall_impent xs'
171     where is_valid :: Char -> Bool
172           is_valid c = isAscii c && (isAlphaNum c || c `elem` "._")
173
174 noContext      = []
175 noExistentials = []
176 noFunDeps      = []
177
178 -------------------------------------------------------------------
179 convertToHsExpr :: TH.Exp -> HsExpr RdrName
180 convertToHsExpr = cvt
181
182 cvt (VarE s)      = HsVar (vName s)
183 cvt (ConE s)      = HsVar (cName s)
184 cvt (LitE l) 
185   | overloadedLit l = HsOverLit (cvtOverLit l)
186   | otherwise       = HsLit (cvtLit l)
187
188 cvt (AppE x y)     = HsApp (cvt x) (cvt y)
189 cvt (LamE ps e)    = HsLam (mkSimpleMatch (map cvtp ps) (cvt e) void loc0)
190 cvt (TupE [e])    = cvt e
191 cvt (TupE es)     = ExplicitTuple(map cvt es) Boxed
192 cvt (CondE x y z)  = HsIf (cvt x) (cvt y) (cvt z) loc0
193 cvt (LetE ds e)   = HsLet (cvtdecs ds) (cvt e)
194 cvt (CaseE e ms)   = HsCase (cvt e) (map cvtm ms) loc0
195 cvt (DoE ss)      = HsDo DoExpr (cvtstmts ss) [] void loc0
196 cvt (CompE ss)     = HsDo ListComp (cvtstmts ss) [] void loc0
197 cvt (ArithSeqE dd) = ArithSeqIn (cvtdd dd)
198 cvt (ListE xs)  = ExplicitList void (map cvt xs)
199 cvt (InfixE (Just x) s (Just y))
200     = HsPar (OpApp (cvt x) (cvt s) undefined (cvt y))
201 cvt (InfixE Nothing  s (Just y)) = SectionR (cvt s) (cvt y)
202 cvt (InfixE (Just x) s Nothing ) = SectionL (cvt x) (cvt s)
203 cvt (InfixE Nothing  s Nothing ) = cvt s        -- Can I indicate this is an infix thing?
204 cvt (SigE e t)          = ExprWithTySig (cvt e) (cvtType t)
205 cvt (RecConE c flds) = RecordCon (cName c) (map (\(x,y) -> (vName x, cvt y)) flds)
206 cvt (RecUpdE e flds) = RecordUpd (cvt e) (map (\(x,y) -> (vName x, cvt y)) flds)
207
208 cvtdecs :: [TH.Dec] -> HsBinds RdrName
209 cvtdecs [] = EmptyBinds
210 cvtdecs ds = MonoBind binds sigs Recursive
211            where
212              (binds, sigs) = cvtBindsAndSigs ds
213
214 cvtBindsAndSigs ds 
215   = (cvtds non_sigs, map cvtSig sigs)
216   where 
217     (sigs, non_sigs) = partition sigP ds
218
219 cvtSig (TH.SigD nm typ) = Hs.Sig (vName nm) (cvtType typ) loc0
220
221 cvtds :: [TH.Dec] -> MonoBinds RdrName
222 cvtds []     = EmptyMonoBinds
223 cvtds (d:ds) = AndMonoBinds (cvtd d) (cvtds ds)
224
225 cvtd :: TH.Dec -> MonoBinds RdrName
226 -- Used only for declarations in a 'let/where' clause,
227 -- not for top level decls
228 cvtd (TH.ValD (TH.VarP s) body ds) = FunMonoBind (vName s) False 
229                                           [cvtclause (Clause [] body ds)] loc0
230 cvtd (FunD nm cls)          = FunMonoBind (vName nm) False (map cvtclause cls) loc0
231 cvtd (TH.ValD p body ds)            = PatMonoBind (cvtp p) (GRHSs (cvtguard body) 
232                                                           (cvtdecs ds) 
233                                                           void) loc0
234
235 cvtd d = cvtPanic "Illegal kind of declaration in where clause" 
236                   (text (show (TH.pprDec d)))
237
238
239 cvtclause :: TH.Clause -> Hs.Match RdrName
240 cvtclause (Clause ps body wheres)
241     = Hs.Match (map cvtp ps) Nothing (GRHSs (cvtguard body) (cvtdecs wheres) void)
242
243
244
245 cvtdd :: Range -> ArithSeqInfo RdrName
246 cvtdd (FromR x)               = (From (cvt x))
247 cvtdd (FromThenR x y)     = (FromThen (cvt x) (cvt y))
248 cvtdd (FromToR x y)           = (FromTo (cvt x) (cvt y))
249 cvtdd (FromThenToR x y z) = (FromThenTo (cvt x) (cvt y) (cvt z))
250
251
252 cvtstmts :: [TH.Stmt] -> [Hs.Stmt RdrName]
253 cvtstmts []                    = [] -- this is probably an error as every [stmt] should end with ResultStmt
254 cvtstmts [NoBindS e]           = [ResultStmt (cvt e) loc0]      -- when its the last element use ResultStmt
255 cvtstmts (NoBindS e : ss)      = ExprStmt (cvt e) void loc0     : cvtstmts ss
256 cvtstmts (TH.BindS p e : ss) = BindStmt (cvtp p) (cvt e) loc0 : cvtstmts ss
257 cvtstmts (TH.LetS ds : ss)   = LetStmt (cvtdecs ds)         : cvtstmts ss
258 cvtstmts (TH.ParS dss : ss)  = ParStmt [(cvtstmts ds, undefined) | ds <- dss] : cvtstmts ss
259
260 cvtm :: TH.Match -> Hs.Match RdrName
261 cvtm (TH.Match p body wheres)
262     = Hs.Match [cvtp p] Nothing (GRHSs (cvtguard body) (cvtdecs wheres) void)
263                              
264 cvtguard :: TH.Body -> [GRHS RdrName]
265 cvtguard (GuardedB pairs) = map cvtpair pairs
266 cvtguard (NormalB e)     = [GRHS [  ResultStmt (cvt e) loc0 ] loc0]
267
268 cvtpair :: (TH.Exp,TH.Exp) -> GRHS RdrName
269 cvtpair (x,y) = GRHS [Hs.BindStmt truePat (cvt x) loc0,
270                       ResultStmt (cvt y) loc0] loc0
271
272 cvtOverLit :: Lit -> HsOverLit
273 cvtOverLit (IntegerL i)  = mkHsIntegral i
274 cvtOverLit (RationalL r) = mkHsFractional r
275 -- An Integer is like an an (overloaded) '3' in a Haskell source program
276 -- Similarly 3.5 for fractionals
277
278 cvtLit :: Lit -> HsLit
279 cvtLit (IntPrimL i)    = HsIntPrim i
280 cvtLit (FloatPrimL f)  = HsFloatPrim f
281 cvtLit (DoublePrimL f) = HsDoublePrim f
282 cvtLit (CharL c)       = HsChar (ord c)
283 cvtLit (StringL s)     = HsString (mkFastString s)
284
285 cvtp :: TH.Pat -> Hs.Pat RdrName
286 cvtp (TH.LitP l)
287   | overloadedLit l = NPatIn (cvtOverLit l) Nothing     -- Not right for negative
288                                                         -- patterns; need to think
289                                                         -- about that!
290   | otherwise       = Hs.LitPat (cvtLit l)
291 cvtp (TH.VarP s)     = Hs.VarPat(vName s)
292 cvtp (TupP [p])   = cvtp p
293 cvtp (TupP ps)    = TuplePat (map cvtp ps) Boxed
294 cvtp (ConP s ps)  = ConPatIn (cName s) (PrefixCon (map cvtp ps))
295 cvtp (TildeP p)   = LazyPat (cvtp p)
296 cvtp (TH.AsP s p) = AsPat (vName s) (cvtp p)
297 cvtp TH.WildP   = WildPat void
298 cvtp (RecP c fs)  = ConPatIn (cName c) $ Hs.RecCon (map (\(s,p) -> (vName s,cvtp p)) fs)
299 cvtp (ListP ps)   = ListPat (map cvtp ps) void
300
301 -----------------------------------------------------------
302 --      Types and type variables
303
304 cvt_tvs :: [TH.Name] -> [HsTyVarBndr RdrName]
305 cvt_tvs tvs = map (UserTyVar . tName) tvs
306
307 cvt_context :: Cxt -> HsContext RdrName 
308 cvt_context tys = map cvt_pred tys
309
310 cvt_pred :: TH.Type -> HsPred RdrName
311 cvt_pred ty = case split_ty_app ty of
312                 (ConT tc, tys) -> HsClassP (tconName tc) (map cvtType tys)
313                 (VarT tv, tys) -> HsClassP (tName tv) (map cvtType tys)
314                 other -> cvtPanic "Malformed predicate" (text (show (TH.pprType ty)))
315
316 cvtType :: TH.Type -> HsType RdrName
317 cvtType ty = trans (root ty [])
318   where root (AppT a b) zs = root a (cvtType b : zs)
319         root t zs          = (t,zs)
320
321         trans (TupleT n,args)
322             | length args == n = HsTupleTy Boxed args
323             | n == 0    = foldl HsAppTy (HsTyVar (getRdrName unitTyCon))            args
324             | otherwise = foldl HsAppTy (HsTyVar (getRdrName (tupleTyCon Boxed n))) args
325         trans (ArrowT,   [x,y]) = HsFunTy x y
326         trans (ListT,    [x])   = HsListTy x
327
328         trans (VarT nm, args)       = foldl HsAppTy (HsTyVar (tName nm)) args
329         trans (ConT tc, args)       = foldl HsAppTy (HsTyVar (tconName tc)) args
330
331         trans (ForallT tvs cxt ty, []) = mkExplicitHsForAllTy 
332                                                 (cvt_tvs tvs) (cvt_context cxt) (cvtType ty)
333
334 split_ty_app :: TH.Type -> (TH.Type, [TH.Type])
335 split_ty_app ty = go ty []
336   where
337     go (AppT f a) as = go f (a:as)
338     go f as          = (f,as)
339
340 -----------------------------------------------------------
341 sigP :: Dec -> Bool
342 sigP (TH.SigD _ _) = True
343 sigP other       = False
344
345
346 -----------------------------------------------------------
347 cvtPanic :: String -> SDoc -> b
348 cvtPanic herald thing
349   = pprPanic herald (thing $$ ptext SLIT("When splicing generated code into the program"))
350
351 -----------------------------------------------------------
352 -- some useful things
353
354 truePat  = ConPatIn (getRdrName trueDataCon)  (PrefixCon [])
355 falsePat = ConPatIn (getRdrName falseDataCon) (PrefixCon [])
356
357 overloadedLit :: Lit -> Bool
358 -- True for literals that Haskell treats as overloaded
359 overloadedLit (IntegerL  l) = True
360 overloadedLit (RationalL l) = True
361 overloadedLit l             = False
362
363 void :: Type.Type
364 void = placeHolderType
365
366 loc0 :: SrcLoc
367 loc0 = generatedSrcLoc
368
369 --------------------------------------------------------------------
370 --      Turning Name back into RdrName
371 --------------------------------------------------------------------
372
373 -- variable names
374 vName :: TH.Name -> RdrName
375 vName = mk_name OccName.varName
376
377 -- Constructor function names; this is Haskell source, hence srcDataName
378 cName :: TH.Name -> RdrName
379 cName = mk_name OccName.srcDataName
380
381 -- Type variable names
382 tName :: TH.Name -> RdrName
383 tName = mk_name OccName.tvName
384
385 -- Type Constructor names
386 tconName = mk_name OccName.tcName
387
388 mk_name :: OccName.NameSpace -> TH.Name -> RdrName
389
390 -- This turns a Name into a RdrName
391 -- The last case is slightly interesting.  It constructs a
392 -- unique name from the unique in the TH thingy, so that the renamer
393 -- won't mess about.  I hope.  (Another possiblity would be to generate 
394 -- "x_77" etc, but that could conceivably clash.)
395
396 mk_name ns (TH.Name occ (TH.NameG ns' mod))  = mkOrig (mk_mod mod) (mk_occ ns occ)
397 mk_name ns (TH.Name occ TH.NameS)            = mkRdrUnqual (mk_occ ns occ)
398 mk_name ns (TH.Name occ (TH.NameU uniq))     = nameRdrName (mkInternalName (mk_uniq uniq) (mk_occ ns occ) noSrcLoc)
399
400 mk_uniq :: Int# -> Unique
401 mk_uniq u = mkUniqueGrimily (I# u)
402
403 -- The packing and unpacking is rather turgid :-(
404 mk_occ :: OccName.NameSpace -> TH.OccName -> OccName.OccName
405 mk_occ ns occ = OccName.mkOccFS ns (mkFastString (TH.occString occ))
406
407 mk_mod :: TH.ModName -> ModuleName
408 mk_mod mod = mkModuleName (TH.modString mod)
409 \end{code}
410