1{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, DeriveFunctor,
11import Idris.Delaborate
15import Idris.Primitives
17import Idris.UnusedArgs
26import Core.Constraints
30import IRTS.CodegenCommon
37import System.Console.Haskeline as H
40import System.Environment
42import System.Directory
45import Control.Monad.Trans.State.Strict ( StateT, execStateT, get, put )
46import Control.Monad.Trans ( liftIO, lift )
52repl :: IState -> [FilePath] -> Idris ()
55 (do let prompt = mkPrompt mods
56 x <- lift $ getInputLine (prompt ++ "> ")
58 Nothing -> do iputStrLn "Bye bye"
61 (do ms <- processInput input orig mods
63 Just mods -> repl orig mods
67 where ctrlC :: SomeException -> Idris ()
68 ctrlC e = do iputStrLn (show e)
72mkPrompt [x] = "*" ++ dropExtension x
73mkPrompt (x:xs) = "*" ++ dropExtension x ++ " " ++ mkPrompt xs
75lit f = case splitExtension f of
79processInput :: String -> IState -> [FilePath] -> Idris (Maybe [FilePath])
80processInput cmd orig inputs
82 let fn = case inputs of
85 case parseCmd i cmd of
86 Left err -> do liftIO $ print err
89 do put (orig { idris_options = idris_options i })
91 mods <- mapM loadModule inputs
94 do put (orig { idris_options = idris_options i })
98 Right (ModImport f) ->
101 return (Just (inputs ++ [fmod]))
102 Right Edit -> do edit fn orig
104 Right Proofs -> do proofs orig
106 Right Quit -> do iputStrLn "Bye bye"
108 Right cmd -> do idrisCatch (process fn cmd)
109 (\e -> iputStrLn (show e))
112resolveProof :: Name -> Idris Name
116 n <- case lookupNames Nothing n' ctxt of
119 ns -> fail $ pshow i (CantResolveAlts (map show ns))
122removeProof :: Name -> Idris ()
125 let proofs = proof_list i
126 let ps = filter ((/= n) . fst) proofs
127 put $ i { proof_list = ps }
129edit :: FilePath -> IState -> Idris ()
130edit "" orig = iputStrLn "Nothing to edit"
133 env <- liftIO $ getEnvironment
134 let editor = getEditor env
135 let line = case errLine i of
136 Just l -> " +" ++ show l ++ " "
138 let cmd = editor ++ line ++ f
141 put (orig { idris_options = idris_options i })
145 where getEditor env | Just ed <- lookup "EDITOR" env = ed
146 | Just ed <- lookup "VISUAL" env = ed
150proofs :: IState -> Idris ()
153 let ps = proof_list i
155 [] -> iputStrLn "No proofs available"
156 _ -> iputStrLn $ "Proofs:\n\t" ++ (show $ map fst ps)
158insertScript :: String -> [String] -> [String]
159insertScript prf [] = "\n---------- Proofs ----------" : "" : [prf]
160insertScript prf (p@"---------- Proofs ----------" : "" : xs)
162insertScript prf (x : xs) = x : insertScript prf xs
164process :: FilePath -> Command -> Idris ()
165process fn Help = iputStrLn displayHelp
167 = do (tm, ty) <- elabVal toplevel False t
170 let tm' = normaliseAll ctxt [] tm
171 let ty' = normaliseAll ctxt [] ty
172 logLvl 3 $ "Raw: " ++ show (tm', ty')
174 iputStrLn (showImp imp (delab ist tm') ++ " : " ++
175 showImp imp (delab ist ty'))
176process fn (ExecVal t)
177 = do (tm, ty) <- elabVal toplevel False t
178-- (PApp fc (PRef fc (NS (UN "print") ["Prelude"]))
180 (tmpn, tmph) <- liftIO tempfile
186 where fc = FC "(input)" 0
187process fn (Check (PRef _ n))
188 = do ctxt <- getContext
191 case lookupTy Nothing n ctxt of
192 ts@(_:_) -> mapM_ (\t -> iputStrLn $ show n ++ " : " ++
193 showImp imp (delab ist t)) ts
194 [] -> iputStrLn $ "No such variable " ++ show n
195process fn (Check t) = do (tm, ty) <- elabVal toplevel False t
199 let ty' = normaliseC ctxt [] ty
200 iputStrLn (showImp imp (delab ist tm) ++ " : " ++
201 showImp imp (delab ist ty))
203process fn (DocStr n) = do i <- get
204 case lookupCtxtName Nothing n (idris_docstrings i) of
205 [] -> iputStrLn $ "No documentation for " ++ show n
206 ns -> mapM_ showDoc ns
208 = do doc <- getDocs n
210process fn Universes = do i <- get
211 let cs = idris_constraints i
212-- iputStrLn $ showSep "\n" (map show cs)
213 liftIO $ print (map fst cs)
215 iputStrLn $ "(" ++ show n ++ " constraints)"
217 Error e -> iputStrLn $ pshow i e
218 OK _ -> iputStrLn "Universes OK"
219process fn (Defn n) = do i <- get
220 iputStrLn "Compiled patterns:\n"
221 liftIO $ print (lookupDef Nothing n (tt_ctxt i))
222 case lookupCtxt Nothing n (idris_patdefs i) of
224 [d] -> do iputStrLn "Original definiton:\n"
225 mapM_ (printCase i) d
226 case lookupTotal n (tt_ctxt i) of
227 [t] -> iputStrLn (showTotal t i)
229 where printCase i (_, lhs, rhs)
230 = do liftIO $ putStr $ showImp True (delab i lhs)
231 liftIO $ putStr " = "
232 liftIO $ putStrLn $ showImp True (delab i rhs)
233process fn (TotCheck n) = do i <- get
234 case lookupTotal n (tt_ctxt i) of
235 [t] -> iputStrLn (showTotal t i)
237process fn (DebugInfo n)
239 let oi = lookupCtxtName Nothing n (idris_optimisation i)
240 when (not (null oi)) $ iputStrLn (show oi)
241 let si = lookupCtxt Nothing n (idris_statics i)
242 when (not (null si)) $ iputStrLn (show si)
243 let d = lookupDef Nothing n (tt_ctxt i)
244 when (not (null d)) $ liftIO $
246 let cg = lookupCtxtName Nothing n (idris_callgraph i)
247 findUnusedArgs (map fst cg)
249 let cg' = lookupCtxtName Nothing n (idris_callgraph i)
250 sc <- checkSizeChange n
251 iputStrLn $ "Size change: " ++ show sc
252 when (not (null cg')) $ do iputStrLn "Call graph:\n"
254process fn (Info n) = do i <- get
255 case lookupCtxt Nothing n (idris_classes i) of
257 _ -> iputStrLn "Not a class"
258process fn (Search t) = iputStrLn "Not implemented"
259process fn (Spec t) = do (tm, ty) <- elabVal toplevel False t
262 let tm' = simplify ctxt True [] {- (idris_statics ist) -} tm
263 iputStrLn (show (delab ist tm'))
265process fn (RmProof n')
268 let proofs = proof_list i
269 case lookup n proofs of
270 Nothing -> iputStrLn "No proof to remove"
271 Just _ -> do removeProof n
273 iputStrLn $ "Removed proof " ++ show n
275 insertMetavar :: Name -> Idris ()
278 let ms = idris_metavars i
279 put $ i { idris_metavars = n : ms }
281process fn (AddProof prf)
282 = do let fb = fn ++ "~"
283 liftIO $ copyFile fn fb -- make a backup in case something goes wrong!
284 prog <- liftIO $ readFile fb
286 let proofs = proof_list i
288 Nothing -> case proofs of
289 [] -> fail "No proof to add"
290 ((x, p) : _) -> return x
293 case lookup n proofs of
294 Nothing -> iputStrLn "No proof to add"
295 Just p -> do let prog' = insertScript (showProof (lit fn) n p) ls
296 liftIO $ writeFile fn (unlines prog')
298 iputStrLn $ "Added proof " ++ show n
299 where ls = (lines prog)
301process fn (ShowProof n')
304 let proofs = proof_list i
305 case lookup n proofs of
306 Nothing -> iputStrLn "No proof to show"
307 Just p -> iputStrLn $ showProof False n p
310 = do ctxt <- getContext
312 n <- case lookupNames Nothing n' ctxt of
315 ns -> fail $ pshow ist (CantResolveAlts (map show ns))
319 totcheck (FC "(input)" 0, n)
320 mapM_ (\ (f,n) -> setTotality n Unchecked) (idris_totcheck i)
321 mapM_ checkDeclTotality (idris_totcheck i)
323process fn (HNF t) = do (tm, ty) <- elabVal toplevel False t
326 let tm' = simplify ctxt True [] tm
327 iputStrLn (show (delab ist tm'))
328process fn TTShell = do ist <- get
329 let shst = initState (tt_ctxt ist)
330 shst' <- lift $ runShell shst
332process fn Execute = do (m, _) <- elabVal toplevel False
334 (PRef fc (UN "run__IO"))
335 [pexp $ PRef fc (NS (UN "main") ["Main"])])
336-- (PRef (FC "main" 0) (NS (UN "main") ["main"]))
337 (tmpn, tmph) <- liftIO tempfile
343 where fc = FC "main" 0
344process fn (NewCompile f)
345 = do (m, _) <- elabVal toplevel False
346 (PApp fc (PRef fc (UN "run__IO"))
347 [pexp $ PRef fc (NS (UN "main") ["Main"])])
349 where fc = FC "main" 0
350process fn (Compile target f)
351 = do (m, _) <- elabVal toplevel False
352 (PApp fc (PRef fc (UN "run__IO"))
353 [pexp $ PRef fc (NS (UN "main") ["Main"])])
355 where fc = FC "main" 0
356process fn (LogLvl i) = setLogLevel i
357-- Elaborate as if LHS of a pattern (debug command)
358process fn (Pattelab t)
359 = do (tm, ty) <- elabVal toplevel True t
360 iputStrLn $ show tm ++ "\n\n : " ++ show ty
362process fn (Missing n) = do i <- get
363 case lookupDef Nothing n (tt_ctxt i) of
364 [CaseOp _ _ _ _ _ args t _ _]
365 -> do tms <- genMissing n args t
366 iputStrLn (showSep "\n" (map (showImp True) tms))
367 [] -> iputStrLn $ show n ++ " undefined"
368 _ -> iputStrLn $ "Ambiguous name"
371 let mvs = idris_metavars ist \\ primDefs
373 [] -> iputStrLn "No global metavariables to solve"
374 _ -> iputStrLn $ "Global metavariables:\n\t" ++ show mvs
375process fn NOP = return ()
377process fn (SetOpt ErrContext) = setErrContext True
378process fn (UnsetOpt ErrContext) = setErrContext False
379process fn (SetOpt ShowImpl) = setImpShow True
380process fn (UnsetOpt ShowImpl) = setImpShow False
382process fn (SetOpt _) = iputStrLn "Not a valid option"
383process fn (UnsetOpt _) = iputStrLn "Not a valid option"
386classInfo :: ClassInfo -> Idris ()
387classInfo ci = do iputStrLn "Methods:\n"
388 mapM_ dumpMethod (class_methods ci)
390 iputStrLn "Instances:\n"
391 mapM_ dumpInstance (class_instances ci)
393dumpMethod :: (Name, (FnOpts, PTerm)) -> Idris ()
394dumpMethod (n, (_, t)) = iputStrLn $ show n ++ " : " ++ show t
396dumpInstance :: Name -> Idris ()
397dumpInstance n = do i <- get
400 case lookupTy Nothing n ctxt of
401 ts -> mapM_ (\t -> iputStrLn $ showImp imp (delab i t)) ts
403showTotal t@(Partial (Other ns)) i
404 = show t ++ "\n\t" ++ showSep "\n\t" (map (showTotalN i) ns)
405showTotal t i = show t
406showTotalN i n = case lookupTotal n (tt_ctxt i) of
410displayHelp = let vstr = showVersion version in
411 "\nIdris version " ++ vstr ++ "\n" ++
412 "--------------" ++ map (\x -> '-') vstr ++ "\n\n" ++
413 concatMap cmdInfo help
414 where cmdInfo (cmds, args, text) = " " ++ col 16 12 (showSep " " cmds) args text
416 l ++ take (c1 - length l) (repeat ' ') ++
417 m ++ take (c2 - length m) (repeat ' ') ++ r ++ "\n"
419parseArgs :: [String] -> [Opt]
421parseArgs ("--log":lvl:ns) = OLogging (read lvl) : (parseArgs ns)
422parseArgs ("--noprelude":ns) = NoPrelude : (parseArgs ns)
423parseArgs ("--check":ns) = NoREPL : (parseArgs ns)
424parseArgs ("-o":n:ns) = NoREPL : Output n : (parseArgs ns)
425parseArgs ("-no":n:ns) = NoREPL : NewOutput n : (parseArgs ns)
426parseArgs ("--typecase":ns) = TypeCase : (parseArgs ns)
427parseArgs ("--typeintype":ns) = TypeInType : (parseArgs ns)
428parseArgs ("--total":ns) = DefaultTotal : (parseArgs ns)
429parseArgs ("--partial":ns) = DefaultPartial : (parseArgs ns)
430parseArgs ("--warnpartial":ns) = WarnPartial : (parseArgs ns)
431parseArgs ("--nocoverage":ns) = NoCoverage : (parseArgs ns)
432parseArgs ("--errorcontext":ns) = ErrContext : (parseArgs ns)
433parseArgs ("--help":ns) = Usage : (parseArgs ns)
434parseArgs ("--link":ns) = ShowLibs : (parseArgs ns)
435parseArgs ("--libdir":ns) = ShowLibdir : (parseArgs ns)
436parseArgs ("--include":ns) = ShowIncs : (parseArgs ns)
437parseArgs ("--version":ns) = Ver : (parseArgs ns)
438parseArgs ("--verbose":ns) = Verbose : (parseArgs ns)
439parseArgs ("--ibcsubdir":n:ns) = IBCSubDir n : (parseArgs ns)
440parseArgs ("-i":n:ns) = ImportDir n : (parseArgs ns)
441parseArgs ("--warn":ns) = WarnOnly : (parseArgs ns)
442parseArgs ("--package":n:ns) = Pkg n : (parseArgs ns)
443parseArgs ("-p":n:ns) = Pkg n : (parseArgs ns)
444parseArgs ("--build":n:ns) = PkgBuild n : (parseArgs ns)
445parseArgs ("--install":n:ns) = PkgInstall n : (parseArgs ns)
446parseArgs ("--clean":n:ns) = PkgClean n : (parseArgs ns)
447parseArgs ("--bytecode":n:ns) = NoREPL : BCAsm n : (parseArgs ns)
448parseArgs ("--fovm":n:ns) = NoREPL : FOVM n : (parseArgs ns)
449parseArgs ("-S":ns) = OutputTy Raw : (parseArgs ns)
450parseArgs ("-c":ns) = OutputTy Object : (parseArgs ns)
451parseArgs ("--dumpdefuns":n:ns) = DumpDefun n : (parseArgs ns)
452parseArgs ("--dumpcases":n:ns) = DumpCases n : (parseArgs ns)
453parseArgs (n:ns) = Filename n : (parseArgs ns)
456 [ (["Command"], "Arguments", "Purpose"),
458 (["<expr>"], "", "Evaluate an expression"),
459 ([":t"], "<expr>", "Check the type of an expression"),
460 ([":miss", ":missing"], "<name>", "Show missing clauses"),
461 ([":i", ":info"], "<name>", "Display information about a type class"),
462 ([":total"], "<name>", "Check the totality of a name"),
463 ([":r",":reload"], "", "Reload current file"),
464 ([":l",":load"], "<filename>", "Load a new file"),
465 ([":m",":module"], "<module>", "Import an extra module"),
466 ([":e",":edit"], "", "Edit current file using $EDITOR or $VISUAL"),
467 ([":m",":metavars"], "", "Show remaining proof obligations (metavariables)"),
468 ([":p",":prove"], "<name>", "Prove a metavariable"),
469 ([":a",":addproof"], "<name>", "Add proof to source file"),
470 ([":rmproof"], "<name>", "Remove proof from proof stack"),
471 ([":showproof"], "<name>", "Show proof"),
472 ([":proofs"], "", "Show available proofs"),
473 ([":c",":compile"], "<filename>", "Compile to an executable <filename>"),
474 ([":exec",":execute"], "", "Compile to an executable and run"),
475 ([":?",":h",":help"], "", "Display this help text"),
476 ([":set"], "<option>", "Set an option (errorcontext, showimplicits)"),
477 ([":unset"], "<option>", "Unset an option"),
478 ([":q",":quit"], "", "Exit the Idris system")
481-- invoke as if from command line
482idris :: [Opt] -> IO IState
483idris opts = runInputT defaultSettings $ execStateT (idrisMain opts) idrisInit
485idrisMain :: [Opt] -> Idris ()
487 do let inputs = opt getFile opts
488 let runrepl = not (NoREPL `elem` opts)
489 let output = opt getOutput opts
490 let newoutput = opt getNewOutput opts
491 let ibcsubdir = opt getIBCSubDir opts
492 let importdirs = opt getImportDir opts
493 let bcs = opt getBC opts
494 let vm = opt getFOVM opts
495 let pkgdirs = opt getPkgDir opts
496 let outty = case opt getOutputTy opts of
499 let tgt = case opt getTarget opts of
502 when (DefaultTotal `elem` opts) $ do i <- get
503 put (i { default_total = True })
509 when (Verbose `elem` opts) $ setVerbose True
510 mapM_ makeOption opts
511 -- if we have the --fovm flag, drop into the first order VM testing
514 xs -> liftIO $ mapM_ (fovm tgt outty) xs
515 -- if we have the --bytecode flag, drop into the bytecode assembler
518 xs -> return () -- liftIO $ mapM_ bcAsm xs
520 [] -> setIBCSubDir ""
521 (d:_) -> setIBCSubDir d
522 setImportDirs importdirs
524 mapM_ addPkgDir pkgdirs
526 when (not (NoPrelude `elem` opts)) $ do x <- loadModule "Prelude"
528 when runrepl $ iputStrLn banner
530 mods <- mapM loadModule inputs
532 when ok $ case output of
534 (o:_) -> process "" (Compile tgt o)
535 when ok $ case newoutput of
537 (o:_) -> process "" (NewCompile o)
538 when runrepl $ repl ist inputs
540 when (not ok) $ liftIO (exitWith (ExitFailure 1))
542 makeOption (OLogging i) = setLogLevel i
543 makeOption TypeCase = setTypeCase True
544 makeOption TypeInType = setTypeInType True
545 makeOption NoCoverage = setCoverage False
546 makeOption ErrContext = setErrContext True
547 makeOption _ = return ()
549 addPkgDir :: String -> Idris ()
550 addPkgDir p = do ddir <- liftIO $ getDataDir
551 addImportDir (ddir </> p)
553getFile :: Opt -> Maybe String
554getFile (Filename str) = Just str
557getBC :: Opt -> Maybe String
558getBC (BCAsm str) = Just str
561getFOVM :: Opt -> Maybe String
562getFOVM (FOVM str) = Just str
565getOutput :: Opt -> Maybe String
566getOutput (Output str) = Just str
569getNewOutput :: Opt -> Maybe String
570getNewOutput (NewOutput str) = Just str
571getNewOutput _ = Nothing
573getIBCSubDir :: Opt -> Maybe String
574getIBCSubDir (IBCSubDir str) = Just str
575getIBCSubDir _ = Nothing
577getImportDir :: Opt -> Maybe String
578getImportDir (ImportDir str) = Just str
579getImportDir _ = Nothing
581getPkgDir :: Opt -> Maybe String
582getPkgDir (Pkg str) = Just str
585getPkg :: Opt -> Maybe (Bool, String)
586getPkg (PkgBuild str) = Just (False, str)
587getPkg (PkgInstall str) = Just (True, str)
590getPkgClean :: Opt -> Maybe String
591getPkgClean (PkgClean str) = Just str
592getPkgClean _ = Nothing
594getTarget :: Opt -> Maybe Target
595getTarget (UseTarget x) = Just x
598getOutputTy :: Opt -> Maybe OutputType
599getOutputTy (OutputTy t) = Just t
600getOutputTy _ = Nothing
602opt :: (Opt -> Maybe a) -> [Opt] -> [a]
605ver = showVersion version
607banner = " ____ __ _ \n" ++
608 " / _/___/ /____(_)____ \n" ++
609 " / // __ / ___/ / ___/ Version " ++ ver ++ "\n" ++
610 " _/ // /_/ / / / (__ ) http://www.idris-lang.org/ \n" ++
611 " /___/\\__,_/_/ /_/____/ Type :? for help \n"
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