+cmInit :: GhciMode -> IO CmState
+cmInit mode = do
+ prel <- moduleNameToModule defaultCurrentModuleName
+ writeIORef defaultCurrentModule prel
+ emptyCmState mode prel
+
+-----------------------------------------------------------------------------
+-- Setting the context doesn't throw away any bindings; the bindings
+-- we've built up in the InteractiveContext simply move to the new
+-- module. They always shadow anything in scope in the current context.
+
+cmSetContext :: CmState -> String -> IO CmState
+cmSetContext cmstate str
+ = do let mn = mkModuleName str
+ modules_loaded = [ (name_of_summary s, ms_mod s) | s <- mg cmstate ]
+
+ m <- case lookup mn modules_loaded of
+ Just m -> return m
+ Nothing -> do
+ mod <- moduleNameToModule mn
+ if isHomeModule mod
+ then throwDyn (OtherError (showSDoc
+ (quotes (ppr (moduleName mod))
+ <+> text "is not currently loaded")))
+ else return mod
+
+ return cmstate{ ic = (ic cmstate){ic_module=m} }
+
+cmGetContext :: CmState -> IO String
+cmGetContext cmstate = return (moduleUserString (ic_module (ic cmstate)))
+
+moduleNameToModule :: ModuleName -> IO Module
+moduleNameToModule mn
+ = do maybe_stuff <- findModule mn
+ case maybe_stuff of
+ Nothing -> throwDyn (OtherError ("can't find module `"
+ ++ moduleNameUserString mn ++ "'"))
+ Just (m,_) -> return m
+
+-----------------------------------------------------------------------------
+-- cmRunStmt: Run a statement/expr.
+
+#ifdef GHCI
+cmRunStmt :: CmState -> DynFlags -> String
+ -> IO (CmState, -- new state
+ [Name]) -- names bound by this evaluation
+cmRunStmt cmstate dflags expr
+ = do
+ let InteractiveContext {
+ ic_rn_env = rn_env,
+ ic_type_env = type_env,
+ ic_module = this_mod } = icontext
+
+ (new_pcs, maybe_stuff)
+ <- hscStmt dflags hst hit pcs icontext expr False{-stmt-}
+
+ case maybe_stuff of
+ Nothing -> return (cmstate{ pcs=new_pcs }, [])
+ Just (ids, _, bcos) -> do
+
+ -- update the interactive context
+ let
+ new_rn_env = extendLocalRdrEnv rn_env (map idName ids)
+
+ -- Extend the renamer-env from bound_ids, not
+ -- bound_names, because the latter may contain
+ -- [it] when the former is empty
+ new_type_env = extendNameEnvList type_env
+ [ (getName id, AnId id) | id <- ids]
+
+ new_ic = icontext { ic_rn_env = new_rn_env,
+ ic_type_env = new_type_env }
+
+ -- link it
+ hval <- linkExpr pls bcos
+
+ -- run it!
+ let thing_to_run = unsafeCoerce# hval :: IO [HValue]
+ hvals <- thing_to_run
+
+ -- get the newly bound things, and bind them
+ let names = map idName ids
+ new_pls <- updateClosureEnv pls (zip names hvals)
+
+ return (cmstate{ pcs=new_pcs, pls=new_pls, ic=new_ic }, names)
+ where
+ CmState{ hst=hst, hit=hit, pcs=pcs, pls=pls, ic=icontext } = cmstate
+#endif
+
+-----------------------------------------------------------------------------
+-- cmTypeOfExpr: returns a string representing the type of an expression
+
+#ifdef GHCI
+cmTypeOfExpr :: CmState -> DynFlags -> String -> IO (CmState, Maybe String)
+cmTypeOfExpr cmstate dflags expr
+ = do (new_pcs, maybe_stuff)
+ <- hscStmt dflags hst hit pcs ic expr True{-just an expr-}
+
+ let new_cmstate = cmstate{pcs = new_pcs}
+
+ case maybe_stuff of
+ Nothing -> return (new_cmstate, Nothing)
+ Just (_, ty, _) ->
+ let pit = pcs_PIT pcs
+ modname = moduleName (ic_module ic)
+ tidy_ty = tidyType emptyTidyEnv ty
+ str = case lookupIfaceByModName hit pit modname of
+ Nothing -> showSDoc (ppr tidy_ty)
+ Just iface -> showSDocForUser unqual (ppr tidy_ty)
+ where unqual = unQualInScope (mi_globals iface)
+ in return (new_cmstate, Just str)
+ where
+ CmState{ hst=hst, hit=hit, pcs=pcs, ic=ic } = cmstate
+#endif
+
+-----------------------------------------------------------------------------
+-- cmTypeOfName: returns a string representing the type of a name.
+
+#ifdef GHCI
+cmTypeOfName :: CmState -> Name -> IO (Maybe String)
+cmTypeOfName CmState{ hit=hit, pcs=pcs, ic=ic } name
+ = case lookupNameEnv (ic_type_env ic) name of
+ Nothing -> return Nothing
+ Just (AnId id) ->
+ let pit = pcs_PIT pcs
+ modname = moduleName (ic_module ic)
+ ty = tidyType emptyTidyEnv (idType id)
+ str = case lookupIfaceByModName hit pit modname of
+ Nothing -> showSDoc (ppr ty)
+ Just iface -> showSDocForUser unqual (ppr ty)
+ where unqual = unQualInScope (mi_globals iface)
+ in return (Just str)
+
+ _ -> panic "cmTypeOfName"
+#endif
+
+-----------------------------------------------------------------------------
+-- cmCompileExpr: compile an expression and deliver an HValue
+
+#ifdef GHCI
+cmCompileExpr :: CmState -> DynFlags -> String -> IO (CmState, Maybe HValue)
+cmCompileExpr cmstate dflags expr
+ = do
+ let InteractiveContext {
+ ic_rn_env = rn_env,
+ ic_type_env = type_env,
+ ic_module = this_mod } = icontext
+
+ (new_pcs, maybe_stuff)
+ <- hscStmt dflags hst hit pcs icontext
+ ("let __cmCompileExpr = "++expr) False{-stmt-}
+
+ case maybe_stuff of
+ Nothing -> return (cmstate{ pcs=new_pcs }, Nothing)
+ Just (ids, _, bcos) -> do
+
+ -- link it
+ hval <- linkExpr pls bcos
+
+ -- run it!
+ let thing_to_run = unsafeCoerce# hval :: IO [HValue]
+ hvals <- thing_to_run
+
+ case (ids,hvals) of
+ ([id],[hv]) -> return (cmstate{ pcs=new_pcs }, Just hv)
+ _ -> panic "cmCompileExpr"
+
+ where
+ CmState{ hst=hst, hit=hit, pcs=pcs, pls=pls, ic=icontext } = cmstate
+#endif
+
+-----------------------------------------------------------------------------
+-- cmInfo: return "info" about an expression. The info might be:
+--
+-- * its type, for an expression,
+-- * the class definition, for a class
+-- * the datatype definition, for a tycon (or synonym)
+-- * the export list, for a module
+--
+-- Can be used to find the type of the last expression compiled, by looking
+-- for "it".
+
+cmInfo :: CmState -> String -> IO (Maybe String)
+cmInfo cmstate str
+ = do error "cmInfo not implemented yet"
+
+-----------------------------------------------------------------------------
+-- Unload the compilation manager's state: everything it knows about the
+-- current collection of modules in the Home package.