import TcExpr ( tcMonoExpr )
import TcHsSyn ( TcExpr, TypecheckedHsExpr, mkHsLet, zonkTopExpr )
import TcSimplify ( tcSimplifyTop )
-import TcType ( TcType, openTypeKind )
+import TcType ( TcType, openTypeKind, mkAppTy )
import TcEnv ( spliceOK, tcMetaTy )
import TcRnTypes ( TopEnv(..) )
import TcMType ( newTyVarTy )
import TcRnMonad
import TysWiredIn ( mkListTy )
-import DsMeta ( exprTyConName, declTyConName )
+import DsMeta ( exprTyConName, declTyConName, decTyConName, qTyConName )
import Outputable
import GHC.Base ( unsafeCoerce# ) -- Should have a better home in the module hierarchy
\end{code}
= newTyVarTy openTypeKind `thenM` \ any_ty ->
tcMonoExpr expr any_ty `thenM_`
tcMetaTy exprTyConName
+ -- Result type is Expr (= Q Exp)
tcBracket (DecBr decls)
= tcTopSrcDecls decls `thenM_`
- tcMetaTy declTyConName `thenM` \ decl_ty ->
- returnM (mkListTy decl_ty)
+ tcMetaTy decTyConName `thenM` \ decl_ty ->
+ tcMetaTy qTyConName `thenM` \ q_ty ->
+ returnM (mkAppTy q_ty (mkListTy decl_ty))
+ -- Result type is Q [Dec]
\end{code}
+
%************************************************************************
%* *
\subsection{Splicing an expression}
\begin{code}
-- Always at top level
tcSpliceDecls expr
- = tcMetaTy declTyConName `thenM` \ meta_dec_ty ->
+ = tcMetaTy decTyConName `thenM` \ meta_dec_ty ->
+ tcMetaTy qTyConName `thenM` \ meta_q_ty ->
setStage topSpliceStage (
- getLIE (tcMonoExpr expr (mkListTy meta_dec_ty))
+ getLIE (tcMonoExpr expr (mkAppTy meta_q_ty (mkListTy meta_dec_ty)))
) `thenM` \ (expr', lie) ->
-- Solve the constraints
tcSimplifyTop lie `thenM` \ const_binds ->
\begin{code}
runMetaE :: TypecheckedHsExpr -- Of type (Q Exp)
-> TcM Meta.Exp -- Of type Exp
-runMetaE e = runMeta tcRunQ e
+runMetaE e = runMeta e
-runMetaD :: TypecheckedHsExpr -- Of type [Q Dec]
+runMetaD :: TypecheckedHsExpr -- Of type Q [Dec]
-> TcM [Meta.Dec] -- Of type [Dec]
-runMetaD e = runMeta run_decl e
- where
- run_decl :: [Meta.Decl] -> TcM [Meta.Dec]
- run_decl ds = mappM tcRunQ ds
+runMetaD e = runMeta e
--- Warning: if Q is anything other than IO, we need to change this
tcRunQ :: Meta.Q a -> TcM a
-tcRunQ thing = ioToTcRn thing
-
+tcRunQ thing = ioToTcRn (Meta.runQ thing)
-runMeta :: (x -> TcM t) -- :: X -> IO t
- -> TypecheckedHsExpr -- Of type X
+runMeta :: TypecheckedHsExpr -- Of type X
-> TcM t -- Of type t
-runMeta run_it expr :: TcM t
+runMeta expr
= getTopEnv `thenM` \ top_env ->
+ getGblEnv `thenM` \ tcg_env ->
getEps `thenM` \ eps ->
getNameCache `thenM` \ name_cache ->
getModule `thenM` \ this_mod ->
- getGlobalRdrEnv `thenM` \ rdr_env ->
let
ghci_mode = top_mode top_env
pcs = PCS { pcs_nc = name_cache, pcs_EPS = eps }
- print_unqual = unQualInScope rdr_env
+ type_env = tcg_type_env tcg_env
+ rdr_env = tcg_rdr_env tcg_env
in
- if (ghci_mode == OneShot) then
- failWithTc (ptext SLIT("You must use --make or --interactive to run splice expressions"))
- -- The reason for this is that the demand-linker doesn't have
- -- enough information available to link all the things that
- -- are needed when you try to run a splice
- else
-
- ioToTcRn (HscMain.compileExpr hsc_env pcs this_mod
- print_unqual expr) `thenM` \ hval ->
+ ioToTcRn (HscMain.compileExpr
+ hsc_env pcs this_mod
+ rdr_env type_env expr) `thenM` \ hval ->
- tryM (run_it (unsafeCoerce# hval)) `thenM` \ either_tval ->
+ tryM (tcRunQ (unsafeCoerce# hval)) `thenM` \ either_tval ->
case either_tval of
Left exn -> failWithTc (vcat [text "Exception when running compile-time code:",
showSplice :: String -> TypecheckedHsExpr -> SDoc -> TcM ()
showSplice what before after
= getSrcLocM `thenM` \ loc ->
- traceSplice (hang (ppr loc <> colon <+> text "Splicing" <+> text what) 4
- (sep [nest 2 (ppr before),
- text "======>",
- nest 2 after]))
+ traceSplice (vcat [ppr loc <> colon <+> text "Splicing" <+> text what,
+ nest 2 (sep [nest 2 (ppr before),
+ text "======>",
+ nest 2 after])])
illegalSplice level
= ptext SLIT("Illegal splice at level") <+> ppr level