2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4 \section[TcSplice]{Template Haskell splices}
7 module TcSplice( tcSpliceExpr, tcSpliceDecls, tcBracket ) where
9 #include "HsVersions.h"
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
16 import qualified Language.Haskell.THSyntax as Meta
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 )
34 import TysWiredIn ( mkListTy )
35 import DsMeta ( exprTyConName, declTyConName, decTyConName, qTyConName )
36 import CmdLineOpts ( DynFlags(..), CoreToDo(..), SimplifierMode(..), SimplifierSwitch(..) )
38 import GHC.Base ( unsafeCoerce# ) -- Should have a better home in the module hierarchy
42 %************************************************************************
44 \subsection{Main interface + stubs for the non-GHCI case
46 %************************************************************************
49 tcSpliceDecls :: RenamedHsExpr -> TcM [RdrNameHsDecl]
57 tcSpliceExpr n e ty = pprPanic "Cant do tcSpliceExpr without GHCi" (ppr e)
58 tcSpliceDecls e = pprPanic "Cant do tcSpliceDecls without GHCi" (ppr e)
62 %************************************************************************
64 \subsection{Splicing an expression}
66 %************************************************************************
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)
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]
85 %************************************************************************
87 \subsection{Splicing an expression}
89 %************************************************************************
92 tcSpliceExpr name expr res_ty
93 = getStage `thenM` \ level ->
94 case spliceOK level of {
95 Nothing -> failWithTc (illegalSplice level) ;
99 Comp -> tcTopSplice expr res_ty ;
100 Brack _ ps_var lie_var ->
102 -- A splice inside brackets
104 -- e.g. [| reverse $(h 4) |]
105 -- Here (h 4) :: Q Exp
106 -- but $(h 4) :: forall a.a i.e. anything!
108 tcMetaTy exprTyConName `thenM` \ meta_exp_ty ->
109 setStage (Splice next_level) (
111 tcMonoExpr expr meta_exp_ty
114 -- Write the pending splice into the bucket
115 readMutVar ps_var `thenM` \ ps ->
116 writeMutVar ps_var ((name,expr') : ps) `thenM_`
118 returnM (panic "tcSpliceExpr") -- The returned expression is ignored
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
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) ->
134 -- Solve the constraints
135 tcSimplifyTop lie `thenM` \ const_binds ->
137 q_expr = mkHsLet const_binds expr'
139 zonkTopExpr q_expr `thenM` \ zonked_q_expr ->
141 -- Run the expression
142 traceTc (text "About to run" <+> ppr zonked_q_expr) `thenM_`
143 runMetaE zonked_q_expr `thenM` \ simple_expr ->
146 -- simple_expr :: Meta.Exp
148 expr2 :: RdrNameHsExpr
149 expr2 = convertToHsExpr simple_expr
151 traceTc (text "Got result" <+> ppr expr2) `thenM_`
153 showSplice "expression"
154 zonked_q_expr (ppr expr2) `thenM_`
155 initRn SourceMode (rnExpr expr2) `thenM` \ (exp3, fvs) ->
156 importSupportingDecls fvs `thenM` \ env ->
158 setGblEnv env (tcMonoExpr exp3 res_ty)
162 %************************************************************************
164 \subsection{Splicing an expression}
166 %************************************************************************
169 -- Always at top level
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 ->
179 q_expr = mkHsLet const_binds expr'
181 zonkTopExpr q_expr `thenM` \ zonked_q_expr ->
183 -- Run the expression
184 traceTc (text "About to run" <+> ppr zonked_q_expr) `thenM_`
185 runMetaD zonked_q_expr `thenM` \ simple_expr ->
187 -- simple_expr :: [Meta.Dec]
188 decls :: [RdrNameHsDecl]
189 decls = convertToHsDecls simple_expr
191 traceTc (text "Got result" <+> vcat (map ppr decls)) `thenM_`
192 showSplice "declarations"
193 zonked_q_expr (vcat (map ppr decls)) `thenM_`
198 %************************************************************************
200 \subsection{Running an expression}
202 %************************************************************************
205 runMetaE :: TypecheckedHsExpr -- Of type (Q Exp)
206 -> TcM Meta.Exp -- Of type Exp
207 runMetaE e = runMeta e
209 runMetaD :: TypecheckedHsExpr -- Of type Q [Dec]
210 -> TcM [Meta.Dec] -- Of type [Dec]
211 runMetaD e = runMeta e
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
218 runMeta :: TypecheckedHsExpr -- Of type X
219 -> TcM t -- Of type t
221 = getTopEnv `thenM` \ top_env ->
222 getEps `thenM` \ eps ->
223 getNameCache `thenM` \ name_cache ->
224 getModule `thenM` \ this_mod ->
225 getGlobalRdrEnv `thenM` \ rdr_env ->
227 ghci_mode = top_mode top_env
228 dflags = top_dflags top_env
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 }
235 hsc_env = HscEnv { hsc_mode = ghci_mode,
236 hsc_HPT = top_hpt top_env,
237 hsc_dflags = th_dflags }
239 pcs = PCS { pcs_nc = name_cache, pcs_EPS = eps }
241 print_unqual = unQualInScope rdr_env
243 ioToTcRn (HscMain.compileExpr hsc_env pcs this_mod
244 print_unqual expr) `thenM` \ hval ->
246 tryM (tcRunQ (unsafeCoerce# hval)) `thenM` \ either_tval ->
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)])])
255 thCoreToDo :: [CoreToDo]
256 thCoreToDo = [] -- CoreDoSimplify (SimplPhase 0) [MaxSimplifierIterations 3]]
261 -----------------------------------
266 import Lib( g :: Int -> M Exp )
268 f x y = [| \z -> (x, $(g y), z, map, h) |]
270 h p = $( (\q r -> if q then [| \s -> (p,r,s) |]
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",
284 h :: Tree Int -> M Exp
285 h = \p -> \s' -> (p,3,s')
290 map: C0 C1 (top-level/imp)
302 f x y = lam "z" (tup [lift x, g y, var "z",
303 [| map |], [| h |] ])
306 f = \x y -> lam "z" (tup [lift d x, g y, var "z",
307 return (Glob "Prelude" "map"),
308 return (Glob "Foo" "h")])
317 h v = [| \x -> map $v x |]
319 g :: Tree Int -> M Exp
322 g x = \x' -> map x x'
324 *** Simon claims x does not have to be liftable! **
328 Level 2 code returned by run time (generation time)
330 Non-top-level variables
333 bound at level 0 --> x
334 bound at level 1 --> var "x"
336 not inside brackets --> x
340 bound at level 0 --> x
341 bound at level 1 --> var "x"
345 Two successive brackets aren't allowed
348 %************************************************************************
350 \subsection{Errors and contexts}
352 %************************************************************************
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),
364 = ptext SLIT("Illegal splice at level") <+> ppr level