2 | import Compiler.Common
5 | import Core.Directory
6 | import Core.InitPrimitives
8 | import Core.UnifyState
10 | import Idris.CommandLine
12 | import Idris.IDEMode.REPL
13 | import Idris.Package
14 | import Idris.ProcessIdr
16 | import Idris.SetOptions
18 | import Idris.Version
26 | import System.Directory
27 | import System.File.Meta
28 | import System.File.Virtual
29 | import Libraries.Utils.Path
36 | findInputs : List CLOpt -> Maybe (List1 String)
37 | findInputs [] = Nothing
38 | findInputs (InputFile f :: fs) =
39 | let rest = maybe [] toList (findInputs fs)
40 | in Just (f ::: rest)
41 | findInputs (_ :: fs) = findInputs fs
43 | splitPaths : String -> List1 String
44 | splitPaths = map trim . split (==pathSeparator)
47 | updateEnv : {auto c : Ref Ctxt Defs} ->
48 | {auto o : Ref ROpts REPLOpts} ->
51 | = do defs <- get Ctxt
52 | noColor <- coreLift [ isJust noc || not tty | noc <- idrisGetEnv "NO_COLOR", tty <- isTTY stdout ]
53 | when noColor $
setColor False
54 | bprefix <- coreLift $
idrisGetEnv "IDRIS2_PREFIX"
55 | setPrefix (fromMaybe yprefix bprefix)
56 | bpath <- coreLift $
idrisGetEnv "IDRIS2_PATH"
57 | whenJust bpath $
traverseList1_ addExtraDir . splitPaths
58 | bdata <- coreLift $
idrisGetEnv "IDRIS2_DATA"
59 | whenJust bdata $
traverseList1_ addDataDir . splitPaths
60 | blibs <- coreLift $
idrisGetEnv "IDRIS2_LIBS"
61 | whenJust blibs $
traverseList1_ addLibDir . splitPaths
62 | pdirs <- coreLift $
idrisGetEnv "IDRIS2_PACKAGE_PATH"
63 | whenJust pdirs $
traverseList1_ addPackageSearchPath . splitPaths
64 | cg <- coreLift $
idrisGetEnv "IDRIS2_CG"
65 | whenJust cg $
\ e => case getCG (options defs) e of
67 | Nothing => throw (InternalError ("Unknown code generator " ++ show e))
68 | inccgs <- coreLift $
idrisGetEnv "IDRIS2_INC_CGS"
69 | whenJust inccgs $
\ cgs =>
70 | traverseList1_ (setIncrementalCG False) $
71 | map trim (split (==',') cgs)
79 | addPackageSearchPath !pkgGlobalDirectory
81 | catch (addPkgDir "prelude" anyBounds) (const (pure ()))
82 | catch (addPkgDir "base" anyBounds) (const (pure ()))
83 | addDataDir (prefix_dir (dirs (options defs)) </>
84 | ("idris2-" ++ showVersion False version) </> "support")
85 | addLibDir (prefix_dir (dirs (options defs)) </>
86 | ("idris2-" ++ showVersion False version) </> "lib")
87 | Just cwd <- coreLift $
currentDir
88 | | Nothing => throw (InternalError "Can't get current directory")
91 | updateREPLOpts : {auto o : Ref ROpts REPLOpts} ->
94 | = do ed <- coreLift $
idrisGetEnv "EDITOR"
95 | whenJust ed $
\ e => update ROpts { editor := e }
97 | tryYaffle : List CLOpt -> Core Bool
98 | tryYaffle [] = pure False
99 | tryYaffle (Yaffle f :: _) = do yaffleMain f []
101 | tryYaffle (c :: cs) = tryYaffle cs
103 | ignoreMissingIpkg : List CLOpt -> Bool
104 | ignoreMissingIpkg [] = False
105 | ignoreMissingIpkg (IgnoreMissingIPKG :: _) = True
106 | ignoreMissingIpkg (c :: cs) = ignoreMissingIpkg cs
108 | tryTTM : List CLOpt -> Core Bool
109 | tryTTM [] = pure False
110 | tryTTM (Metadata f :: _) = do dumpTTM f
112 | tryTTM (c :: cs) = tryTTM cs
118 | / _/___/ /____(_)____ |__ \
119 | / // __ / ___/ / ___/ __/ / Version \#{ showVersion True version }
120 | _/ // /_/ / / / (__ ) / __/ https://www.idris-lang.org
121 | /___/\__,_/_/ /_/____/ /____/ Type :? for help
123 | Welcome to Idris 2. Enjoy yourself!
126 | checkVerbose : List CLOpt -> Bool
127 | checkVerbose [] = False
128 | checkVerbose (Verbose :: _) = True
129 | checkVerbose (_ :: xs) = checkVerbose xs
131 | stMain : List (String, Codegen) -> List CLOpt -> Core ()
133 | = do False <- tryYaffle opts
135 | False <- tryTTM opts
138 | let updated = foldl (\o, (s, _) => addCG (s, Other s) o) (options defs) cgs
139 | c <- newRef Ctxt ({ options := updated } defs)
140 | s <- newRef Syn initSyntax
141 | setCG {c} $
maybe Chez (Other . fst) (head' cgs)
145 | when (ignoreMissingIpkg opts) $
146 | setSession ({ ignoreMissingPkg := True } !getSession)
148 | let ide = ideMode opts
149 | let ideSocket = ideModeSocket opts
150 | let outmode = if ide then IDEMode 0 stdin stdout else REPL InfoLvl
151 | o <- newRef ROpts (REPL.Opts.defaultOpts Nothing outmode cgs)
153 | fname <- case (findInputs opts) of
154 | Just (fname ::: Nil) => pure $
Just fname
155 | Nothing => pure Nothing
156 | Just (fname1 ::: fnames) => do
157 | let suggestion = nearMatchOptSuggestion fname1
158 | renderedSuggestion <- maybe (pure "") render suggestion
161 | Expected at most one input file but was given: \{joinBy ", " (fname1 :: fnames)}
162 | \{renderedSuggestion}
164 | update ROpts { mainfile := fname }
168 | True <- preOptions opts
172 | done <- flip catch quitWithError $
processPackageOpts opts
174 | when (not done) $
flip catch quitWithError $
175 | do when (checkVerbose opts) $
176 | setOutput (REPL InfoLvl)
177 | u <- newRef UST initUState
179 | (pure $
Virtual Interactive) (\fname => do
180 | modIdent <- ctxtPathToNS fname
181 | pure (PhysicalIdrSrc modIdent)
183 | m <- newRef MD (initMetadata origin)
185 | session <- getSession
186 | when (not $
nobanner session) $
do
187 | iputStrLn $
pretty0 banner
188 | when (isCons cgs) $
iputStrLn (reflow "With codegen for:" <++> hsep (pretty0 . fst <$> cgs))
189 | fname <- if findipkg session
190 | then findIpkg fname
193 | result <- case fname of
194 | Nothing => logTime 1 "Loading prelude" $
do
195 | when (not $
noprelude session) $
198 | Just f => logTime 1 "Loading main file" $
do
199 | res <- loadMainFile f
200 | displayStartupErrors res
203 | doRepl <- catch (postOptions result opts)
204 | (\err => emitError err *> pure False)
206 | if ide || ideSocket then
209 | setOutput (IDEMode 0 stdin stdout)
210 | replIDE {c} {u} {m}
212 | let (host, port) = ideSocketModeAddress opts
213 | f <- coreLift $
initIDESocketFile host port
216 | coreLift $
putStrLn err
217 | coreLift $
exitWith (ExitFailure 1)
219 | setOutput (IDEMode 0 file file)
220 | replIDE {c} {u} {m}
227 | do ropts <- get ROpts
229 | whenJust (errorLine ropts) $
\ _ =>
230 | coreLift $
exitWith (ExitFailure 1)
234 | quitWithError : {auto c : Ref Ctxt Defs} ->
235 | {auto s : Ref Syn SyntaxInfo} ->
236 | {auto o : Ref ROpts REPLOpts} ->
238 | quitWithError err = do
246 | quitOpts : List CLOpt -> IO Bool
247 | quitOpts [] = pure True
248 | quitOpts (Version :: _)
249 | = do putStrLn versionMsg
251 | quitOpts (TTCVersion :: _)
252 | = do printLn ttcVersion
254 | quitOpts (Help Nothing :: _)
255 | = do putStrLn usage
257 | quitOpts (Help (Just HelpLogging) :: _)
258 | = do putStrLn helpTopics
260 | quitOpts (Help (Just HelpPragma) :: _)
261 | = do putStrLn pragmaTopics
263 | quitOpts (_ :: opts) = quitOpts opts
266 | mainWithCodegens : List (String, Codegen) -> IO ()
267 | mainWithCodegens cgs = do
268 | Right opts <- getCmdOpts
269 | | Left err => do ignore $
fPutStrLn stderr $
"Error: " ++ err
270 | exitWith (ExitFailure 1)
271 | continue <- quitOpts opts
274 | coreRun (stMain cgs opts)
275 | (\err : Error => do ignore $
fPutStrLn stderr $
"Uncaught error: " ++ show err
276 | exitWith (ExitFailure 1))