3Description : Main function to decide Idris' mode of use.
5Maintainer : The Idris Community.
11 , runClient -- taken from Idris.REPL.
12 , loadInputs -- taken from Idris.ModeCommon
16import Idris.Core.Execute (execute)
19import Idris.Elab.Value
24import Idris.ModeCommon
27import Idris.Parser hiding (indent)
29import Idris.REPL.Commands
30import Idris.REPL.Parser
31import IRTS.CodegenCommon
35import Control.Category
38import Control.Monad.Trans (lift)
39import Control.Monad.Trans.Except (runExceptT)
40import Control.Monad.Trans.State.Strict (execStateT)
43import Prelude hiding (id, (.), (<$>))
44import System.Console.Haskeline as H
45import System.Directory
49import System.IO.CodePage (withCP65001)
50import Text.Trifecta.Result (ErrInfo(..), Result(..))
52-- | How to run Idris programs.
53runMain :: Idris () -> IO ()
54runMain prog = withCP65001 $ do
55 -- Run in codepage 65001 on Windows so that UTF-8 characters can
56 -- be displayed properly. See #3000.
57 res <- runExceptT $ execStateT prog idrisInit
60 putStrLn $ "Uncaught error: " ++ show err
64-- | The main function of Idris that when given a set of Options will
65-- launch Idris into the desired interaction mode either: REPL;
66-- Compiler; Script execution; or IDE Mode.
67idrisMain :: [Opt] -> Idris ()
69 do mapM_ setWidth (opt getConsoleWidth opts)
70 let inputs = opt getFile opts
71 let quiet = Quiet `elem` opts
72 let nobanner = NoBanner `elem` opts
73 let idesl = Idemode `elem` opts || IdemodeSocket `elem` opts
74 let runrepl = not (NoREPL `elem` opts)
75 let output = opt getOutput opts
76 let ibcsubdir = opt getIBCSubDir opts
77 let importdirs = opt getImportDir opts
78 let sourcedirs = opt getSourceDir opts
79 setSourceDirs sourcedirs
80 let bcs = opt getBC opts
81 let pkgdirs = opt getPkgDir opts
82 -- Set default optimisations
83 let optimise = case opt getOptLevel opts of
88 let outty = case opt getOutputTy opts of
89 [] -> if Interface `elem` opts then
90 Object else Executable
92 let cgn = case opt getCodegen opts of
93 [] -> Via IBCFormat "c"
95 let cgFlags = opt getCodegenArgs opts
97 -- Now set/unset specifically chosen optimisations
98 let os = opt getOptimisation opts
100 mapM_ processOptimisation os
102 script <- case opt getExecScript opts of
104 x:y:xs -> do iputStrLn "More than one interpreter expression found."
105 runIO $ exitWith (ExitFailure 1)
106 [expr] -> return (Just expr)
107 let immediate = opt getEvalExpr opts
108 let port = case getPort opts of
109 Nothing -> ListenPort defaultPort
112 when (DefaultTotal `elem` opts) $ do i <- getIState
113 putIState (i { default_total = DefaultCheckingTotal })
115 setColourise $ not quiet && last (tty : opt getColour opts)
119 mapM_ addLangExt (opt getLanguageExt opts)
121 setQuiet (quiet || isJust script || not (null immediate))
127 mapM_ (addFlag cgn) cgFlags
128 mapM_ makeOption opts
130 when (runrepl && vlevel == 0) $ setVerbose 1
132 -- if we have the --bytecode flag, drop into the bytecode assembler
135 xs -> return () -- runIO $ mapM_ bcAsm xs
137 [] -> setIBCSubDir ""
138 (d:_) -> setIBCSubDir d
139 setImportDirs importdirs
143 -- Check if listed packages are actually installed
145 idrisCatch (do ipkgs <- runIO $ getIdrisInstalledPackages
146 let diff_pkgs = (\\) pkgdirs ipkgs
148 when (not $ null diff_pkgs) $ do
149 iputStrLn "The following packages were specified but cannot be found:"
150 iputStr $ unlines $ map (\x -> unwords ["-", x]) diff_pkgs
151 runIO $ exitWith (ExitFailure 1))
154 when (not (NoBasePkgs `elem` opts)) $ do
158 mapM_ addPkgDir pkgdirs
160 when (not (NoBuiltins `elem` opts)) $ do x <- loadModule "Builtins" (IBC_REPL True)
161 addAutoImport "Builtins"
163 when (not (NoPrelude `elem` opts)) $ do x <- loadModule "Prelude" (IBC_REPL True)
164 addAutoImport "Prelude"
166 when (runrepl && not idesl) initScript
168 nobanner <- getNoBanner
173 not (isJust script) &&
180 mods <- if idesl then return [] else loadInputs inputs Nothing
181 let efile = case inputs of
185 runIO $ hSetBuffering stdout LineBuffering
188 when ok $ case output of
190 (o:_) -> idrisCatch (process "" (Compile cgn o))
191 (\e -> do ist <- getIState ; iputStrLn $ pshow ist e)
195 exprs -> do setWidth InfinitelyWide
196 mapM_ (\str -> do ist <- getIState
198 case parseExpr ist str of
199 Failure (ErrInfo err _) -> do iputStrLn $ show (fixColour c err)
200 runIO $ exitWith (ExitFailure 1)
201 Success e -> process "" (Eval e))
208 Just expr -> execScript expr
210 -- Create Idris data dir + repl history and config dir
211 idrisCatch (do dir <- runIO $ getIdrisUserDataDir
212 exists <- runIO $ doesDirectoryExist dir
213 unless exists $ logLvl 1 ("Creating " ++ dir)
214 runIO $ createDirectoryIfMissing True (dir </> "repl"))
217 historyFile <- runIO $ getIdrisHistoryFile
219 when ok $ case opt getPkgIndex opts of
220 (f : _) -> writePkgIndex f
223 when (runrepl && not idesl) $ do
226 DontListen -> return ()
227 ListenPort port' -> startServer port' orig mods
228 runInputT (replSettings (Just historyFile)) $ repl (force orig) mods efile
229 let idesock = IdemodeSocket `elem` opts
230 when (idesl) $ idemodeStart idesock orig inputs
232 when (not ok) $ runIO (exitWith (ExitFailure 1))
234 makeOption (OLogging i) = setLogLevel i
235 makeOption (OLogCats cs) = setLogCats cs
236 makeOption (Verbose v) = setVerbose v
237 makeOption TypeCase = setTypeCase True
238 makeOption TypeInType = setTypeInType True
239 makeOption NoCoverage = setCoverage False
240 makeOption ErrContext = setErrContext True
241 makeOption (IndentWith n) = setIndentWith n
242 makeOption (IndentClause n) = setIndentClause n
243 makeOption _ = return ()
245 processOptimisation :: (Bool,Optimisation) -> Idris ()
246 processOptimisation (True, p) = addOptimise p
247 processOptimisation (False, p) = removeOptimise p
249 addPkgDir :: String -> Idris ()
250 addPkgDir p = do ddir <- runIO getIdrisLibDir
251 addImportDir (ddir </> p)
252 addIBC (IBCImportDir (ddir </> p))
256-- | Invoke as if from command line. It is an error if there are
257-- unresolved totality problems.
258idris :: [Opt] -> IO (Maybe IState)
259idris opts = do res <- runExceptT $ execStateT totalMain idrisInit
261 Left err -> do putStrLn $ pshow idrisInit err
263 Right ist -> return (Just ist)
264 where totalMain = do idrisMain opts
266 case idris_totcheckfail ist of
267 ((fc, msg):_) -> ierror . At fc . Msg $ "Could not build: "++ msg
271-- | Execute the provided Idris expression.
272execScript :: String -> Idris ()
273execScript expr = do i <- getIState
275 case parseExpr i expr of
276 Failure (ErrInfo err _) -> do iputStrLn $ show (fixColour c err)
277 runIO $ exitWith (ExitFailure 1)
278 Success term -> do ctxt <- getContext
279 (tm, _) <- elabVal (recinfo (fileFC "toplevel")) ERHS term
283-- | Run the initialisation script
284initScript :: Idris ()
285initScript = do script <- runIO $ getIdrisInitScript
286 idrisCatch (do go <- runIO $ doesFileExist script
288 h <- runIO $ openFile script ReadMode
291 (\e -> iPrintError $ "Error reading init file: " ++ show e)
292 where runInit :: Handle -> Idris ()
293 runInit h = do eof <- lift . lift $ hIsEOF h
296 line <- runIO $ hGetLine h
297 script <- runIO $ getIdrisInitScript
299 processLine ist line script c
301 processLine i cmd input clr =
302 case parseCmd i input cmd of
303 Failure (ErrInfo err _) -> runIO $ print (fixColour clr err)
304 Success (Right Reload) -> iPrintError "Init scripts cannot reload the file"
305 Success (Right (Load f _)) -> iPrintError "Init scripts cannot load files"
306 Success (Right (ModImport f)) -> iPrintError "Init scripts cannot import modules"
307 Success (Right Edit) -> iPrintError "Init scripts cannot invoke the editor"
308 Success (Right Proofs) -> proofs i
309 Success (Right Quit) -> iPrintError "Init scripts cannot quit Idris"
310 Success (Right cmd ) -> process [] cmd
311 Success (Left err) -> runIO $ print err
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list