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 )
28 import TcEnv ( spliceOK, tcMetaTy )
29 import TcRnTypes ( TopEnv(..) )
30 import TcMType ( newTyVarTy )
34 import TysWiredIn ( mkListTy )
35 import DsMeta ( exprTyConName, declTyConName )
37 import GHC.Base ( unsafeCoerce# ) -- Should have a better home in the module hierarchy
41 %************************************************************************
43 \subsection{Main interface + stubs for the non-GHCI case
45 %************************************************************************
48 tcSpliceDecls :: RenamedHsExpr -> TcM [RdrNameHsDecl]
56 tcSpliceExpr n e ty = pprPanic "Cant do tcSpliceExpr without GHCi" (ppr e)
57 tcSpliceDecls e = pprPanic "Cant do tcSpliceDecls without GHCi" (ppr e)
61 %************************************************************************
63 \subsection{Splicing an expression}
65 %************************************************************************
68 tcBracket :: HsBracket Name -> TcM TcType
69 tcBracket (ExpBr expr)
70 = newTyVarTy openTypeKind `thenM` \ any_ty ->
71 tcMonoExpr expr any_ty `thenM_`
72 tcMetaTy exprTyConName
74 tcBracket (DecBr decls)
75 = tcTopSrcDecls decls `thenM_`
76 tcMetaTy declTyConName `thenM` \ decl_ty ->
77 returnM (mkListTy decl_ty)
80 %************************************************************************
82 \subsection{Splicing an expression}
84 %************************************************************************
87 tcSpliceExpr name expr res_ty
88 = getStage `thenM` \ level ->
89 case spliceOK level of {
90 Nothing -> failWithTc (illegalSplice level) ;
94 Comp -> tcTopSplice expr res_ty ;
95 Brack _ ps_var lie_var ->
97 -- A splice inside brackets
99 -- e.g. [| reverse $(h 4) |]
100 -- Here (h 4) :: Q Exp
101 -- but $(h 4) :: forall a.a i.e. anything!
103 tcMetaTy exprTyConName `thenM` \ meta_exp_ty ->
104 setStage (Splice next_level) (
106 tcMonoExpr expr meta_exp_ty
109 -- Write the pending splice into the bucket
110 readMutVar ps_var `thenM` \ ps ->
111 writeMutVar ps_var ((name,expr') : ps) `thenM_`
113 returnM (panic "tcSpliceExpr") -- The returned expression is ignored
116 -- tcTopSplice used to have this:
117 -- Note that we do not decrement the level (to -1) before
118 -- typechecking the expression. For example:
119 -- f x = $( ...$(g 3) ... )
120 -- The recursive call to tcMonoExpr will simply expand the
121 -- inner escape before dealing with the outer one
123 tcTopSplice expr res_ty
124 = tcMetaTy exprTyConName `thenM` \ meta_exp_ty ->
125 setStage topSpliceStage (
126 getLIE (tcMonoExpr expr meta_exp_ty)
127 ) `thenM` \ (expr', lie) ->
129 -- Solve the constraints
130 tcSimplifyTop lie `thenM` \ const_binds ->
132 q_expr = mkHsLet const_binds expr'
134 zonkTopExpr q_expr `thenM` \ zonked_q_expr ->
136 -- Run the expression
137 traceTc (text "About to run" <+> ppr zonked_q_expr) `thenM_`
138 runMetaE zonked_q_expr `thenM` \ simple_expr ->
141 -- simple_expr :: Meta.Exp
143 expr2 :: RdrNameHsExpr
144 expr2 = convertToHsExpr simple_expr
146 traceTc (text "Got result" <+> ppr expr2) `thenM_`
148 showSplice "expression"
149 zonked_q_expr (ppr expr2) `thenM_`
150 initRn SourceMode (rnExpr expr2) `thenM` \ (exp3, fvs) ->
151 importSupportingDecls fvs `thenM` \ env ->
153 setGblEnv env (tcMonoExpr exp3 res_ty)
157 %************************************************************************
159 \subsection{Splicing an expression}
161 %************************************************************************
164 -- Always at top level
166 = tcMetaTy declTyConName `thenM` \ meta_dec_ty ->
167 setStage topSpliceStage (
168 getLIE (tcMonoExpr expr (mkListTy meta_dec_ty))
169 ) `thenM` \ (expr', lie) ->
170 -- Solve the constraints
171 tcSimplifyTop lie `thenM` \ const_binds ->
173 q_expr = mkHsLet const_binds expr'
175 zonkTopExpr q_expr `thenM` \ zonked_q_expr ->
177 -- Run the expression
178 traceTc (text "About to run" <+> ppr zonked_q_expr) `thenM_`
179 runMetaD zonked_q_expr `thenM` \ simple_expr ->
181 -- simple_expr :: [Meta.Dec]
182 decls :: [RdrNameHsDecl]
183 decls = convertToHsDecls simple_expr
185 traceTc (text "Got result" <+> vcat (map ppr decls)) `thenM_`
186 showSplice "declarations"
187 zonked_q_expr (vcat (map ppr decls)) `thenM_`
192 %************************************************************************
194 \subsection{Running an expression}
196 %************************************************************************
199 runMetaE :: TypecheckedHsExpr -- Of type (Q Exp)
200 -> TcM Meta.Exp -- Of type Exp
201 runMetaE e = runMeta tcRunQ e
203 runMetaD :: TypecheckedHsExpr -- Of type [Q Dec]
204 -> TcM [Meta.Dec] -- Of type [Dec]
205 runMetaD e = runMeta run_decl e
207 run_decl :: [Meta.Decl] -> TcM [Meta.Dec]
208 run_decl ds = mappM tcRunQ ds
210 -- Warning: if Q is anything other than IO, we need to change this
211 tcRunQ :: Meta.Q a -> TcM a
212 tcRunQ thing = ioToTcRn thing
215 runMeta :: (x -> TcM t) -- :: X -> IO t
216 -> TypecheckedHsExpr -- Of type X
217 -> TcM t -- Of type t
218 runMeta run_it expr :: TcM t
219 = getTopEnv `thenM` \ top_env ->
220 getEps `thenM` \ eps ->
221 getNameCache `thenM` \ name_cache ->
222 getModule `thenM` \ this_mod ->
223 getGlobalRdrEnv `thenM` \ rdr_env ->
225 ghci_mode = top_mode top_env
227 hsc_env = HscEnv { hsc_mode = ghci_mode, hsc_HPT = top_hpt top_env,
228 hsc_dflags = top_dflags top_env }
230 pcs = PCS { pcs_nc = name_cache, pcs_EPS = eps }
232 print_unqual = unQualInScope rdr_env
234 if (ghci_mode == OneShot) then
235 failWithTc (ptext SLIT("You must use --make or --interactive to run splice expressions"))
236 -- The reason for this is that the demand-linker doesn't have
237 -- enough information available to link all the things that
238 -- are needed when you try to run a splice
241 ioToTcRn (HscMain.compileExpr hsc_env pcs this_mod
242 print_unqual expr) `thenM` \ hval ->
244 tryM (run_it (unsafeCoerce# hval)) `thenM` \ either_tval ->
247 Left exn -> failWithTc (vcat [text "Exception when running compile-time code:",
248 nest 4 (vcat [text "Code:" <+> ppr expr,
249 text ("Exn: " ++ show exn)])])
255 -----------------------------------
260 import Lib( g :: Int -> M Exp )
262 f x y = [| \z -> (x, $(g y), z, map, h) |]
264 h p = $( (\q r -> if q then [| \s -> (p,r,s) |]
269 f :: Liftable a => a -> Int -> M Exp
270 f = /\a -> \d::Liftable a ->
271 \ x y -> genSym "z" `bindM` \ z::String ->
272 g y `bindM` \ vv::Exp ->
273 Lam z (Tup [lift d x, v, Var z,
274 Glob "Prelude" "map",
278 h :: Tree Int -> M Exp
279 h = \p -> \s' -> (p,3,s')
284 map: C0 C1 (top-level/imp)
296 f x y = lam "z" (tup [lift x, g y, var "z",
297 [| map |], [| h |] ])
300 f = \x y -> lam "z" (tup [lift d x, g y, var "z",
301 return (Glob "Prelude" "map"),
302 return (Glob "Foo" "h")])
311 h v = [| \x -> map $v x |]
313 g :: Tree Int -> M Exp
316 g x = \x' -> map x x'
318 *** Simon claims x does not have to be liftable! **
322 Level 2 code returned by run time (generation time)
324 Non-top-level variables
327 bound at level 0 --> x
328 bound at level 1 --> var "x"
330 not inside brackets --> x
334 bound at level 0 --> x
335 bound at level 1 --> var "x"
339 Two successive brackets aren't allowed
342 %************************************************************************
344 \subsection{Errors and contexts}
346 %************************************************************************
349 showSplice :: String -> TypecheckedHsExpr -> SDoc -> TcM ()
350 showSplice what before after
351 = getSrcLocM `thenM` \ loc ->
352 traceSplice (hang (ppr loc <> colon <+> text "Splicing" <+> text what) 4
353 (sep [nest 2 (ppr before),
358 = ptext SLIT("Illegal splice at level") <+> ppr level