+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, [Name])
+cmRunStmt cmstate dflags expr
+ = do (new_pcs, maybe_stuff) <- hscStmt dflags hst hit pcs (ic cmstate) expr
+ case maybe_stuff of
+ Nothing -> return (cmstate{ pcs=new_pcs }, [])
+ Just (new_ic, ids, bcos) -> do
+ hval <- linkExpr pls bcos
+ hvals <- unsafeCoerce# hval :: IO [HValue]
+ let names = map idName ids
+ new_pls <- updateClosureEnv pls (zip names hvals)
+ return (cmstate{ pcs=new_pcs, pls=new_pls, ic=new_ic }, names)
+
+ -- ToDo: check that the module we passed in is sane/exists?
+ where
+ CmState{ hst=hst, hit=hit, pcs=pcs, pls=pls } = cmstate
+#endif
+
+-----------------------------------------------------------------------------
+-- cmTypeOf: returns a string representing the type of a name.
+
+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)
+ str = case lookupIfaceByModName hit pit modname of
+ Nothing -> showSDoc (ppr (idType id))
+ Just iface -> showSDocForUser unqual (ppr (idType id))
+ where unqual = unQualInScope (mi_globals iface)
+ in return (Just str)
+
+ _ -> panic "cmTypeOfName"
+
+-----------------------------------------------------------------------------
+-- 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.