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