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