[project @ 2003-07-02 14:59:00 by simonpj]
[ghc-hetmet.git] / ghc / compiler / typecheck / TcSplice.lhs
1 2%
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
3 %
4 \section[TcSplice]{Template Haskell splices}
5
6 \begin{code}
7 module TcSplice( tcSpliceExpr, tcSpliceDecls, tcBracket ) where
8
9 #include "HsVersions.h"
10
11 import HscMain          ( compileExpr )
12 import TcRnDriver       ( importSupportingDecls, tcTopSrcDecls )
13         -- These imports are the reason that TcSplice 
14         -- is very high up the module hierarchy
15
16 import qualified Language.Haskell.THSyntax as Meta
17
18 import HscTypes         ( HscEnv(..), PersistentCompilerState(..) )
19 import HsSyn            ( HsBracket(..), HsExpr(..) )
20 import Convert          ( convertToHsExpr, convertToHsDecls )
21 import RnExpr           ( rnExpr )
22 import RdrHsSyn         ( RdrNameHsExpr, RdrNameHsDecl )
23 import RnHsSyn          ( RenamedHsExpr )
24 import TcExpr           ( tcCheckRho, tcMonoExpr )
25 import TcHsSyn          ( TcExpr, TypecheckedHsExpr, mkHsLet, zonkTopExpr )
26 import TcSimplify       ( tcSimplifyTop, tcSimplifyBracket )
27 import TcUnify          ( Expected, zapExpectedTo, zapExpectedType )
28 import TcType           ( TcType, openTypeKind, mkAppTy )
29 import TcEnv            ( spliceOK, tcMetaTy, tcWithTempInstEnv, bracketOK )
30 import TcRnTypes        ( TopEnv(..) )
31 import TcMType          ( newTyVarTy, UserTypeCtxt(ExprSigCtxt) )
32 import TcMonoType       ( tcHsSigType )
33 import Name             ( Name )
34 import TcRnMonad
35
36 import TysWiredIn       ( mkListTy )
37 import DsMeta           ( expQTyConName, typeQTyConName, decTyConName, qTyConName )
38 import ErrUtils (Message)
39 import Outputable
40 import Panic            ( showException )
41 import GHC.Base         ( unsafeCoerce# )       -- Should have a better home in the module hierarchy
42 import Monad (liftM)
43 \end{code}
44
45
46 %************************************************************************
47 %*                                                                      *
48 \subsection{Main interface + stubs for the non-GHCI case
49 %*                                                                      *
50 %************************************************************************
51
52 \begin{code}
53 tcSpliceDecls :: RenamedHsExpr -> TcM [RdrNameHsDecl]
54
55 tcSpliceExpr :: Name 
56              -> RenamedHsExpr
57              -> Expected TcType
58              -> TcM TcExpr
59
60 #ifndef GHCI
61 tcSpliceExpr n e ty = pprPanic "Cant do tcSpliceExpr without GHCi" (ppr e)
62 tcSpliceDecls e     = pprPanic "Cant do tcSpliceDecls without GHCi" (ppr e)
63 #else
64 \end{code}
65
66 %************************************************************************
67 %*                                                                      *
68 \subsection{Quoting an expression}
69 %*                                                                      *
70 %************************************************************************
71
72 \begin{code}
73 tcBracket :: HsBracket Name -> Expected TcType -> TcM TcExpr
74 tcBracket brack res_ty
75   = getStage                            `thenM` \ level ->
76     case bracketOK level of {
77         Nothing         -> failWithTc (illegalBracket level) ;
78         Just next_level ->
79
80         -- Typecheck expr to make sure it is valid,
81         -- but throw away the results.  We'll type check
82         -- it again when we actually use it.
83     newMutVar []                        `thenM` \ pending_splices ->
84     getLIEVar                           `thenM` \ lie_var ->
85
86     setStage (Brack next_level pending_splices lie_var) (
87         getLIE (tc_bracket brack)
88     )                                   `thenM` \ (meta_ty, lie) ->
89     tcSimplifyBracket lie               `thenM_`  
90
91         -- Make the expected type have the right shape
92     zapExpectedTo res_ty meta_ty        `thenM_`
93
94         -- Return the original expression, not the type-decorated one
95     readMutVar pending_splices          `thenM` \ pendings ->
96     returnM (HsBracketOut brack pendings)
97     }
98
99 tc_bracket :: HsBracket Name -> TcM TcType
100 tc_bracket (ExpBr expr) 
101   = newTyVarTy openTypeKind     `thenM` \ any_ty ->
102     tcCheckRho expr any_ty      `thenM_`
103     tcMetaTy expQTyConName
104         -- Result type is Expr (= Q Exp)
105
106 tc_bracket (TypBr typ) 
107   = tcHsSigType ExprSigCtxt typ         `thenM_`
108     tcMetaTy typeQTyConName
109         -- Result type is Type (= Q Typ)
110
111 tc_bracket (DecBr decls)
112   = tcWithTempInstEnv (tcTopSrcDecls decls)     `thenM_`
113         -- Typecheck the declarations, dicarding any side effects
114         -- on the instance environment (which is in a mutable variable)
115         -- and the extended environment.  We'll get all that stuff
116         -- later, when we splice it in
117
118     tcMetaTy decTyConName               `thenM` \ decl_ty ->
119     tcMetaTy qTyConName                 `thenM` \ q_ty ->
120     returnM (mkAppTy q_ty (mkListTy decl_ty))
121         -- Result type is Q [Dec]
122 \end{code}
123
124
125 %************************************************************************
126 %*                                                                      *
127 \subsection{Splicing an expression}
128 %*                                                                      *
129 %************************************************************************
130
131 \begin{code}
132 tcSpliceExpr name expr res_ty
133   = getStage            `thenM` \ level ->
134     case spliceOK level of {
135         Nothing         -> failWithTc (illegalSplice level) ;
136         Just next_level -> 
137
138     case level of {
139         Comp                   -> tcTopSplice expr res_ty ;
140         Brack _ ps_var lie_var ->  
141
142         -- A splice inside brackets
143         -- NB: ignore res_ty, apart from zapping it to a mono-type
144         -- e.g.   [| reverse $(h 4) |]
145         -- Here (h 4) :: Q Exp
146         -- but $(h 4) :: forall a.a     i.e. anything!
147
148     zapExpectedType res_ty                      `thenM_`
149     tcMetaTy expQTyConName                      `thenM` \ meta_exp_ty ->
150     setStage (Splice next_level) (
151         setLIEVar lie_var          $
152         tcCheckRho expr meta_exp_ty
153     )                                           `thenM` \ expr' ->
154
155         -- Write the pending splice into the bucket
156     readMutVar ps_var                           `thenM` \ ps ->
157     writeMutVar ps_var ((name,expr') : ps)      `thenM_`
158
159     returnM (panic "tcSpliceExpr")      -- The returned expression is ignored
160     }} 
161
162 -- tcTopSplice used to have this:
163 -- Note that we do not decrement the level (to -1) before 
164 -- typechecking the expression.  For example:
165 --      f x = $( ...$(g 3) ... )
166 -- The recursive call to tcMonoExpr will simply expand the 
167 -- inner escape before dealing with the outer one
168
169 tcTopSplice expr res_ty
170   = tcMetaTy expQTyConName              `thenM` \ meta_exp_ty ->
171
172         -- Typecheck the expression
173     tcTopSpliceExpr expr meta_exp_ty    `thenM` \ zonked_q_expr ->
174
175         -- Run the expression
176     traceTc (text "About to run" <+> ppr zonked_q_expr)         `thenM_`
177     runMetaE zonked_q_expr              `thenM` \ simple_expr ->
178   
179     let 
180         -- simple_expr :: Meta.Exp
181
182         expr2 :: RdrNameHsExpr
183         expr2 = convertToHsExpr simple_expr 
184     in
185     traceTc (text "Got result" <+> ppr expr2)   `thenM_`
186
187     showSplice "expression" 
188                zonked_q_expr (ppr expr2)        `thenM_`
189     initRn SourceMode (rnExpr expr2)            `thenM` \ (exp3, fvs) ->
190     importSupportingDecls fvs                   `thenM` \ env ->
191
192     setGblEnv env (tcMonoExpr exp3 res_ty)
193
194
195 tcTopSpliceExpr :: RenamedHsExpr -> TcType -> TcM TypecheckedHsExpr
196 -- Type check an expression that is the body of a top-level splice
197 --   (the caller will compile and run it)
198 tcTopSpliceExpr expr meta_ty
199   = checkNoErrs $       -- checkNoErrs: must not try to run the thing
200                         --              if the type checker fails!
201
202     setStage topSpliceStage $
203
204         -- Typecheck the expression
205     getLIE (tcCheckRho expr meta_ty)    `thenM` \ (expr', lie) ->
206
207         -- Solve the constraints
208     tcSimplifyTop lie                   `thenM` \ const_binds ->
209         
210         -- And zonk it
211     zonkTopExpr (mkHsLet const_binds expr')
212 \end{code}
213
214
215 %************************************************************************
216 %*                                                                      *
217 \subsection{Splicing an expression}
218 %*                                                                      *
219 %************************************************************************
220
221 \begin{code}
222 -- Always at top level
223 tcSpliceDecls expr
224   = tcMetaTy decTyConName               `thenM` \ meta_dec_ty ->
225     tcMetaTy qTyConName                 `thenM` \ meta_q_ty ->
226     let
227         list_q = mkAppTy meta_q_ty (mkListTy meta_dec_ty)
228     in
229     tcTopSpliceExpr expr list_q         `thenM` \ zonked_q_expr ->
230
231         -- Run the expression
232     traceTc (text "About to run" <+> ppr zonked_q_expr)         `thenM_`
233     runMetaD zonked_q_expr              `thenM` \ simple_expr ->
234     -- simple_expr :: [Meta.Dec]
235     -- decls :: [RdrNameHsDecl]
236     handleErrors (convertToHsDecls simple_expr) `thenM` \ decls ->
237     traceTc (text "Got result" <+> vcat (map ppr decls))        `thenM_`
238     showSplice "declarations"
239                zonked_q_expr (vcat (map ppr decls))             `thenM_`
240     returnM decls
241
242   where handleErrors :: [Either a Message] -> TcM [a]
243         handleErrors [] = return []
244         handleErrors (Left x:xs) = liftM (x:) (handleErrors xs)
245         handleErrors (Right m:xs) = do addErrTc m
246                                        handleErrors xs
247 \end{code}
248
249
250 %************************************************************************
251 %*                                                                      *
252 \subsection{Running an expression}
253 %*                                                                      *
254 %************************************************************************
255
256 \begin{code}
257 runMetaE :: TypecheckedHsExpr   -- Of type (Q Exp)
258          -> TcM Meta.Exp        -- Of type Exp
259 runMetaE e = runMeta e
260
261 runMetaD :: TypecheckedHsExpr   -- Of type Q [Dec]
262          -> TcM [Meta.Dec]      -- Of type [Dec]
263 runMetaD e = runMeta e
264
265 runMeta :: TypecheckedHsExpr    -- Of type X
266         -> TcM t                -- Of type t
267 runMeta expr
268   = getTopEnv           `thenM` \ top_env ->
269     getGblEnv           `thenM` \ tcg_env ->
270     getEps              `thenM` \ eps ->
271     getNameCache        `thenM` \ name_cache -> 
272     getModule           `thenM` \ this_mod ->
273     let
274         ghci_mode = top_mode top_env
275
276         hsc_env = HscEnv { hsc_mode = ghci_mode, hsc_HPT = top_hpt top_env,
277                            hsc_dflags = top_dflags top_env }
278
279         pcs = PCS { pcs_nc = name_cache, pcs_EPS = eps }
280
281         type_env = tcg_type_env tcg_env
282         rdr_env  = tcg_rdr_env tcg_env
283     in
284         -- Wrap the compile-and-run in an exception-catcher
285         -- Compiling might fail if linking fails
286         -- Running might fail if it throws an exception
287     tryM (ioToTcRn (do
288         hval <- HscMain.compileExpr 
289                       hsc_env pcs this_mod 
290                       rdr_env type_env expr
291         Meta.runQ (unsafeCoerce# hval)          -- Coerce it to Q t, and run it
292     ))                                  `thenM` \ either_tval ->
293
294     case either_tval of
295           Left exn -> failWithTc (vcat [text "Exception when trying to run compile-time code:", 
296                                         nest 4 (vcat [text "Code:" <+> ppr expr,
297                                                       text ("Exn: " ++ Panic.showException exn)])])
298           Right v  -> returnM v
299 \end{code}
300
301
302
303 -----------------------------------
304         Random comments
305
306
307       module Foo where
308         import Lib( g :: Int -> M Exp )
309         h x = not x     
310         f x y = [| \z -> (x, $(g y), z, map, h) |]
311
312         h p = $( (\q r -> if q then [| \s -> (p,r,s) |] 
313                                else ... ) True 3)   )
314
315 ==> core
316
317         f :: Liftable a => a -> Int -> M Exp
318         f = /\a -> \d::Liftable a ->
319             \ x y -> genSym "z"         `bindM` \ z::String ->
320                      g y                `bindM` \ vv::Exp ->
321                      Lam z (Tup [lift d x, v, Var z, 
322                                  Glob "Prelude" "map",
323                                  Glob "Foo" "h"])
324
325
326         h :: Tree Int -> M Exp
327         h = \p -> \s' -> (p,3,s')
328
329
330                 Bound   Used
331
332         map:    C0      C1      (top-level/imp)
333         x:      C0      C1      (lam/case)
334         y:      C0      C0
335         z:      C1      C1
336
337         p:      C0      S1
338         r:      S0      S1
339         q:      S0      S0
340         s:      S1      S1
341
342 -------
343
344         f x y = lam "z" (tup [lift x, g y, var "z", 
345                               [| map |], [| h |] ])
346 ==> core
347         
348         f = \x y -> lam "z" (tup [lift d x, g y, var "z",
349                                   return (Glob "Prelude" "map"),
350                                   return (Glob "Foo" "h")])
351
352
353
354
355
356
357
358         h :: M Exp -> M Exp
359         h v = [| \x -> map $v x |]
360
361         g :: Tree Int -> M Exp
362         g x = $(h [| x |])
363 ==>
364         g x = \x' -> map x x'
365
366 *** Simon claims x does not have to be liftable! **
367         
368 Level 0 compile time
369 Level 1 run time
370 Level 2 code returned by run time (generation time)
371
372 Non-top-level variables
373         x occurs at level 1
374           inside brackets
375             bound at level 0    --> x
376             bound at level 1    --> var "x"
377
378           not inside brackets   --> x
379
380         x at level 2
381           inside brackets
382             bound at level 0    --> x
383             bound at level 1    --> var "x"
384
385         f x = x
386
387 Two successive brackets aren't allowed
388
389
390 %************************************************************************
391 %*                                                                      *
392 \subsection{Errors and contexts}
393 %*                                                                      *
394 %************************************************************************
395
396 \begin{code}
397 showSplice :: String -> TypecheckedHsExpr -> SDoc -> TcM ()
398 showSplice what before after
399   = getSrcLocM          `thenM` \ loc ->
400     traceSplice (vcat [ppr loc <> colon <+> text "Splicing" <+> text what, 
401                        nest 2 (sep [nest 2 (ppr before),
402                                     text "======>",
403                                     nest 2 after])])
404
405 illegalBracket level
406   = ptext SLIT("Illegal bracket at level") <+> ppr level
407
408 illegalSplice level
409   = ptext SLIT("Illegal splice at level") <+> ppr level
410
411 #endif  /* GHCI */
412 \end{code}