1{-# LANGUAGE GeneralizedNewtypeDeriving, ConstraintKinds, PatternGuards #-}
2module Idris.Parser(module Idris.Parser,
3 module Idris.ParseExpr,
4 module Idris.ParseData,
5 module Idris.ParseHelpers,
6 module Idris.ParseOps) where
8import Prelude hiding (pi)
10import Text.Trifecta.Delta
11import Text.Trifecta hiding (span, stringLiteral, charLiteral, natural, symbol, char, string, whiteSpace)
12import Text.Parser.LookAhead
13import Text.Parser.Expression
14import qualified Text.Parser.Token as Tok
15import qualified Text.Parser.Char as Chr
16import qualified Text.Parser.Token.Highlight as Hi
23import Idris.ElabTerm hiding (namespace, params)
29import Idris.ParseHelpers
36import Util.DynamicLinker
41import Control.Applicative
43import Control.Monad.State.Strict
46import qualified Data.List.Split as Spl
50import qualified Data.HashSet as HS
51import qualified Data.Text as T
52import qualified Data.ByteString.UTF8 as UTF8
60 grammar shortcut notation:
61 ~CHARSEQ = complement of char sequence (i.e. any character except CHARSEQ)
62 RULE? = optional rule (i.e. RULE or nothing)
63 RULE* = repeated rule (i.e. RULE zero or more times)
64 RULE+ = repeated rule with at least one match (i.e. RULE one or more times)
65 RULE! = invalid rule (i.e. rule that is not valid in context, report meaningful error in case)
66 RULE{n} = rule repeated n times
71{- | Parses module definition
72 ModuleHeader ::= 'module' Identifier_t ';'?;
74moduleHeader :: IdrisParser [String]
75moduleHeader = try (do reserved "module"
77 option ';' (lchar ';')
78 return (moduleName i))
80 where moduleName x = case span (/='.') x of
82 (x, '.':y) -> x : moduleName y
84{- | Parses an import statement
85 Import ::= 'import' Identifier_t ';'?;
87import_ :: IdrisParser String
88import_ = do reserved "import"
90 option ';' (lchar ';')
92 <?> "import statement"
93 where toPath f = foldl1' (</>) (Spl.splitOn "." f)
95{- | Parses program source
98prog :: SyntaxInfo -> IdrisParser [PDecl]
99prog syn = do whiteSpace
100 decls <- many (decl syn)
103 let c = (concat decls)
106{- | Parses a top-level declaration
122decl :: SyntaxInfo -> IdrisParser [PDecl]
123decl syn = do notEndBlock
125 where declBody :: IdrisParser [PDecl]
133 <|> do d <- dsl syn; return [d]
137 <|> do import_; fail "imports must be at top of file"
139 declBody' :: IdrisParser [PDecl]
140 declBody' = do d <- decl' syn
142 let d' = fmap (debindApp syn . (desugar syn i)) d
145{- | Parses a top-level declaration with possible syntax sugar
154decl' :: SyntaxInfo -> IdrisParser PDecl
162{- | Parses a syntax extension declaration (and adds the rule to parser state)
163 SyntaxDecl ::= SyntaxRule;
165syntaxDecl :: SyntaxInfo -> IdrisParser PDecl
166syntaxDecl syn = do s <- syntaxRule syn
168 let rs = syntax_rules i
169 let ns = syntax_keywords i
170 let ibc = ibc_write i
171 let ks = map show (names s)
172 put (i { syntax_rules = s : rs,
173 syntax_keywords = ks ++ ns,
174 ibc_write = IBCSyntax s : map IBCKeyword ks ++ ibc })
176 return (PSyntax fc s)
177 where names (Rule syms _ _) = mapMaybe ename syms
178 ename (Keyword n) = Just n
181{- | Parses a syntax extension declaration
182SyntaxRuleOpts ::= 'term' | 'pattern';
185 SyntaxRuleOpts? 'syntax' SyntaxSym+ '=' TypeExpr Terminator;
187SyntaxSym ::= '[' Name_t ']'
193syntaxRule :: SyntaxInfo -> IdrisParser Syntax
197 sty <- option AnySyntax (do reserved "term"; return TermSyntax
198 <|> do reserved "pattern"; return PatternSyntax)
201 syms <- some syntaxSym
202 when (all isExpr syms) $ unexpected "missing keywords in syntax rule"
203 let ns = mapMaybe getName syms
204 when (length ns /= length (nub ns))
205 $ unexpected "repeated variable in syntax rule"
207 tm <- typeExpr (allowImp syn)
209 return (Rule (mkSimple syms) tm sty)
211 isExpr (Expr _) = True
213 getName (Expr n) = Just n
215 -- Can't parse two full expressions (i.e. expressions with application) in a row
216 -- so change them both to a simple expression
217 mkSimple (Expr e : es) = SimpleExpr e : mkSimple' es
218 mkSimple xs = mkSimple' xs
220 mkSimple' (Expr e : Expr e1 : es) = SimpleExpr e : SimpleExpr e1 :
222 mkSimple' (e : es) = e : mkSimple' es
226{- | Parses a syntax symbol (either binding variable, keyword or expression)
227SyntaxSym ::= '[' Name_t ']'
233syntaxSym :: IdrisParser SSymbol
234syntaxSym = try (do lchar '['; n <- name; lchar ']'
236 <|> try (do lchar '{'; n <- name; lchar '}'
240 <|> do sym <- stringLiteral
244{- | Parses a function declaration with possible syntax sugar
245 FunDecl ::= FunDecl';
247fnDecl :: SyntaxInfo -> IdrisParser [PDecl]
249 = try (do notEndBlock
252 let d' = fmap (desugar syn i) d
254 <?> "function declaration"
256{- Parses a function declaration
258 DocComment_t? FnOpts* Accessibility? FnOpts* FnName TypeSig Terminator
264fnDecl' :: SyntaxInfo -> IdrisParser PDecl
265fnDecl' syn = do (doc, fc, opts', n, acc) <- try (do
266 doc <- option "" (docComment '|')
269 let initOpts = if default_total ist
272 opts <- fnOpts initOpts
273 acc <- optional accessibility
276 let n = expandNS syn n_in
279 return (doc, fc, opts', n, acc))
280 ty <- typeExpr (allowImp syn)
283 return (PTy doc syn fc opts' n ty)
287 <?> "function declaration"
290{- Parses function options given initial options
296 | '%' 'specialise' '[' NameTimesList? ']'
299NameTimes ::= FnName Natural?;
303 | NameTimes ',' NameTimesList
307-- FIXME: Check compatability for function options (i.e. partal/total)
308fnOpts :: [FnOpt] -> IdrisParser [FnOpt]
310 = do reserved "total"; fnOpts (TotalFn : opts)
311 <|> do reserved "partial"; fnOpts (PartialFn : (opts \\ [TotalFn]))
312 <|> do try (lchar '%' *> reserved "export"); c <- stringLiteral;
313 fnOpts (CExport c : opts)
314 <|> do try (lchar '%' *> reserved "assert_total");
315 fnOpts (AssertTotal : opts)
316 <|> do try (lchar '%' *> reserved "reflection");
317 fnOpts (Reflection : opts)
318 <|> do lchar '%'; reserved "specialise";
319 lchar '['; ns <- sepBy nameTimes (lchar ','); lchar ']'
320 fnOpts (Specialise ns : opts)
321 <|> do reserved "implicit"; fnOpts (Implicit : opts)
323 <?> "function modifier"
324 where nameTimes :: IdrisParser (Name, Maybe Int)
325 nameTimes = do n <- fnName
326 t <- option Nothing (do reds <- natural
327 return (Just (fromInteger reds)))
330{- | Parses a postulate
333 DocComment_t? 'postulate' FnOpts* Accesibility? FnOpts* FnName TypeSig Terminator
336postulate :: SyntaxInfo -> IdrisParser PDecl
337postulate syn = do doc <- try $ do doc <- option "" (docComment '|')
342 let initOpts = if default_total ist
345 opts <- fnOpts initOpts
346 acc <- optional accessibility
349 let n = expandNS syn n_in
351 ty <- typeExpr (allowImp syn)
355 return (PPostulate doc syn fc opts' n ty)
358{- | Parses a using declaration
361 'using' '(' UsingDeclList ')' OpenBlock Decl* CloseBlock
364using_ :: SyntaxInfo -> IdrisParser [PDecl]
366 do reserved "using"; lchar '('; ns <- usingDeclList syn; lchar ')'
368 let uvars = using syn
369 ds <- many (decl (syn { using = uvars ++ ns }))
372 <?> "using declaration"
374{- | Parses a parameters declaration
377 'parameters' '(' TypeDeclList ')' OpenBlock Decl* CloseBlock
380params :: SyntaxInfo -> IdrisParser [PDecl]
382 do reserved "parameters"; lchar '('; ns <- typeDeclList syn; lchar ')'
384 let pvars = syn_params syn
385 ds <- many (decl syn { syn_params = pvars ++ ns })
388 return [PParams fc ns (concat ds)]
389 <?> "parameters declaration"
391{- | Parses a mutual declaration (for mutually recursive functions)
394 'mutual' OpenBlock Decl* CloseBlock
397mutual :: SyntaxInfo -> IdrisParser [PDecl]
401 let pvars = syn_params syn
402 ds <- many (decl syn)
405 return [PMutual fc (concat ds)]
408{- | Parses a namespace declaration
411 'namespace' identifier OpenBlock Decl+ CloseBlock
414namespace :: SyntaxInfo -> IdrisParser [PDecl]
416 do reserved "namespace"; n <- identifier;
418 ds <- some (decl syn { syn_namespace = n : syn_namespace syn })
420 return [PNamespace n (concat ds)]
421 <?> "namespace declaration"
423{- |Parses a methods block (for type classes and instances)
424 MethodsBlock ::= 'where' OpenBlock FnDecl* CloseBlock
426methodsBlock :: SyntaxInfo -> IdrisParser [PDecl]
427methodsBlock syn = do reserved "where"
429 ds <- many (fnDecl syn)
434{- |Parses a type class declaration
438 | '(' Name ':' Expr ')'
442 DocComment_t? Accessibility? 'class' ConstraintList? Name ClassArgument* MethodsBlock?
445class_ :: SyntaxInfo -> IdrisParser [PDecl]
446class_ syn = do (doc, acc) <- try (do
447 doc <- option "" (docComment '|')
448 acc <- optional accessibility
450 reserved "class"; fc <- getFC; cons <- constraintList syn; n_in <- name
451 let n = expandNS syn n_in
453 ds <- option [] (methodsBlock syn)
454 accData acc n (concatMap declared ds)
455 return [PClass doc syn fc cons n cs ds]
456 <?> "type-class declaration"
458 carg :: IdrisParser (Name, PTerm)
459 carg = do lchar '('; i <- name; lchar ':'; ty <- expr syn; lchar ')'
464{- |Parses a type class instance declaration
467 'instance' InstanceName? ConstraintList? Name SimpleExpr* MethodsBlock?
470 InstanceName ::= '[' Name ']';
472instance_ :: SyntaxInfo -> IdrisParser [PDecl]
473instance_ syn = do reserved "instance"; fc <- getFC
474 en <- optional instanceName
475 cs <- constraintList syn
477 args <- many (simpleExpr syn)
478 let sc = PApp fc (PRef fc cn) (map pexp args)
479 let t = bindList (PPi constraint) (map (\x -> (MN 0 "c", x)) cs) sc
480 ds <- option [] (methodsBlock syn)
481 return [PInstance syn fc cs cn args t en ds]
482 <?> "instance declaratioN"
483 where instanceName :: IdrisParser Name
484 instanceName = do lchar '['; n_in <- fnName; lchar ']'
485 let n = expandNS syn n_in
490{- | Parses a using declaration list
498 | UsingDecl ',' UsingDeclList'
506usingDeclList :: SyntaxInfo -> IdrisParser [Using]
508 = try (sepBy1 (usingDecl syn) (lchar ','))
509 <|> do ns <- sepBy1 name (lchar ',')
511 t <- typeExpr (disallowImp syn)
512 return (map (\x -> UImplicit x t) ns)
513 <?> "using declaration list"
515{- |Parses a using declaration
521usingDecl :: SyntaxInfo -> IdrisParser Using
522usingDecl syn = try (do x <- fnName
524 t <- typeExpr (disallowImp syn)
525 return (UImplicit x t))
528 return (UConstraint c xs)
529 <?> "using declaration"
531{- | Parse a clause with patterns
534pattern :: SyntaxInfo -> IdrisParser PDecl
535pattern syn = do fc <- getFC
537 return (PClauses fc [] (MN 2 "_") [clause]) -- collect together later
540{- | Parse a constant applicative form declaration
541 CAF ::= 'let' FnName '=' Expr Terminator;
543caf :: SyntaxInfo -> IdrisParser PDecl
544caf syn = do reserved "let"
545 n_in <- fnName; let n = expandNS syn n_in
551 <?> "constant applicative form declaration"
553{- | Parse an argument expression
554 ArgExpr ::= HSimpleExpr | {- In Pattern External (User-defined) Expression -};
556argExpr :: SyntaxInfo -> IdrisParser PTerm
557argExpr syn = let syn' = syn { inPattern = True } in
558 try (hsimpleExpr syn') <|> simpleExternalExpr syn'
559 <?> "argument expression"
561{- | Parse a right hand side of a function
567RHSName ::= '{' FnName '}';
569rhs :: SyntaxInfo -> Name -> IdrisParser PTerm
570rhs syn n = do lchar '='; expr syn
572 name <- option n' (do symbol "{"; n <- fnName; symbol "}";
575 return (addLet name r)
576 <|> do reserved "impossible"; return PImpossible
577 <?> "function right hand side"
578 where mkN :: Name -> Name
579 mkN (UN x) = UN (x++"_lemma_1")
580 mkN (NS x n) = NS (mkN x) n
583 addLet :: Name -> PTerm -> PTerm
584 addLet nm (PLet n ty val r) = PLet n ty val (addLet nm r)
585 addLet nm (PCase fc t cs) = PCase fc t (map addLetC cs)
586 where addLetC (l, r) = (l, addLet nm r)
587 addLet nm r = (PLet (UN "value") Placeholder r (PMetavar nm))
589{- |Parses a function clause
590RHSOrWithBlock ::= RHS WhereOrTerminator
591 | 'with' SimpleExpr OpenBlock FnDecl+ CloseBlock
593Clause ::= WExpr+ RHSOrWithBlock
594 | SimpleExpr '<==' FnName RHS WhereOrTerminator
595 | ArgExpr Operator ArgExpr WExpr* RHSOrWithBlock {- Except "=" and "?=" operators to avoid ambiguity -}
596 | FnName ConstraintArg* ImplicitOrArgExpr* WExpr* RHSOrWithBlock
598ImplicitOrArgExpr ::= ImplicitArg | ArgExpr;
599WhereOrTerminator ::= WhereBlock | Terminator;
601clause :: SyntaxInfo -> IdrisParser PClause
603 = do wargs <- try (do pushIndent; some (wExpr syn))
606 n <- case lastParse ist of
608 Nothing -> fail "Invalid clause"
610 let ctxt = tt_ctxt ist
611 let wsyn = syn { syn_namespace = [] }
612 (wheres, nmap) <- choice [do x <- whereBlock n wsyn
617 return $ PClauseR fc wargs r wheres) <|> (do
620 wval <- simpleExpr syn
622 ds <- some $ fnDecl syn
623 let withs = concat ds
625 return $ PWithR fc wargs wval withs)
626 <|> do ty <- try (do pushIndent
631 n_in <- fnName; let n = expandNS syn n_in
634 let ctxt = tt_ctxt ist
635 let wsyn = syn { syn_namespace = [] }
636 (wheres, nmap) <- choice [do x <- whereBlock n wsyn
641 let capp = PLet (MN 0 "match")
644 (PRef fc (MN 0 "match"))
646 put (ist { lastParse = Just n })
647 return $ PClause fc n capp [] r wheres
648 <|> do (l, op) <- try (do
652 when (op == "=" || op == "?=" ) (fail "infix clause definition with \"=\" and \"?=\" not supported ")
654 let n = expandNS syn (UN op)
657 wargs <- many (wExpr syn)
659 let wsyn = syn { syn_namespace = [] }
660 (wheres, nmap) <- choice [do x <- whereBlock n wsyn
666 let capp = PApp fc (PRef fc n) [pexp l, pexp r]
667 put (ist { lastParse = Just n })
668 return $ PClause fc n capp wargs rs wheres) <|> (do
671 lchar '(' <?> "parenthesized expression"
672 wval <- bracketed syn
674 ds <- some $ fnDecl syn
677 let capp = PApp fc (PRef fc n) [pexp l, pexp r]
678 let withs = map (fillLHSD n capp wargs) $ concat ds
679 put (ist { lastParse = Just n })
680 return $ PWith fc n capp wargs wval withs)
682 n_in <- fnName; let n = expandNS syn n_in
683 cargs <- many (constraintArg syn)
685 args <- many (try (implicitArg (syn { inPattern = True } ))
686 <|> (fmap pexp (argExpr syn)))
687 wargs <- many (wExpr syn)
688 let capp = PApp fc (PRef fc n)
692 let ctxt = tt_ctxt ist
693 let wsyn = syn { syn_namespace = [] }
694 (wheres, nmap) <- choice [do x <- whereBlock n wsyn
700 put (ist { lastParse = Just n })
701 return $ PClause fc n capp wargs r wheres) <|> (do
704 put (ist { lastParse = Just n })
705 lchar '(' <?> "parenthesized expression"
706 wval <- bracketed syn
708 ds <- some $ fnDecl syn
709 let withs = map (fillLHSD n capp wargs) $ concat ds
712 return $ PWith fc n capp wargs wval withs)
713 <?> "function clause"
715 fillLHS :: Name -> PTerm -> [PTerm] -> PClause -> PClause
716 fillLHS n capp owargs (PClauseR fc wargs v ws)
717 = PClause fc n capp (owargs ++ wargs) v ws
718 fillLHS n capp owargs (PWithR fc wargs v ws)
719 = PWith fc n capp (owargs ++ wargs) v
720 (map (fillLHSD n capp (owargs ++ wargs)) ws)
723 fillLHSD :: Name -> PTerm -> [PTerm] -> PDecl -> PDecl
724 fillLHSD n c a (PClauses fc o fn cs) = PClauses fc o fn (map (fillLHS n c a) cs)
727{- |Parses with pattern
730wExpr :: SyntaxInfo -> IdrisParser PTerm
731wExpr syn = do lchar '|'
735{- |Parses a where block
736WhereBlock ::= 'where' OpenBlock Decl+ CloseBlock;
738whereBlock :: Name -> SyntaxInfo -> IdrisParser ([PDecl], [(Name, Name)])
740 = do reserved "where"
741 ds <- indentedBlock1 (decl syn)
742 let dns = concatMap (concatMap declared) ds
743 return (concat ds, map (\x -> (x, decoration syn x)) dns)
746{- |Parses a code generation target language name
755codegen_ :: IdrisParser Codegen
756codegen_ = do reserved "C"; return ViaC
757 <|> do reserved "Java"; return ViaJava
758 <|> do reserved "JavaScript"; return ViaJavaScript
759 <|> do reserved "Node"; return ViaNode
760 <|> do reserved "LLVM"; return ViaLLVM
761 <|> do reserved "Bytecode"; return Bytecode
762 <?> "code generation language"
764{- |Parses a compiler directive
767 | String ',' StringList
770Directive ::= '%' Directive';
772Directive' ::= 'lib' CodeGen String_t
773 | 'link' CodeGen String_t
774 | 'flag' CodeGen String_t
775 | 'include' CodeGen String_t
778 | 'access' Accessibility
781 | 'dynamic' StringList
782 | 'language' 'TypeProviders'
783 | 'language' 'ErrorReflection'
786directive :: SyntaxInfo -> IdrisParser [PDecl]
787directive syn = do try (lchar '%' *> reserved "lib"); cgn <- codegen_; lib <- stringLiteral;
788 return [PDirective (do addLib cgn lib
789 addIBC (IBCLib cgn lib))]
790 <|> do try (lchar '%' *> reserved "link"); cgn <- codegen_; obj <- stringLiteral;
791 return [PDirective (do dirs <- allImportDirs
792 o <- liftIO $ findInPath dirs obj
793 addIBC (IBCObj cgn obj) -- just name, search on loading ibc
794 addObjectFile cgn o)]
795 <|> do try (lchar '%' *> reserved "flag"); cgn <- codegen_;
796 flag <- stringLiteral
797 return [PDirective (do addIBC (IBCCGFlag cgn flag)
799 <|> do try (lchar '%' *> reserved "include"); cgn <- codegen_; hdr <- stringLiteral;
800 return [PDirective (do addHdr cgn hdr
801 addIBC (IBCHeader cgn hdr))]
802 <|> do try (lchar '%' *> reserved "hide"); n <- fnName
803 return [PDirective (do setAccessibility n Hidden
804 addIBC (IBCAccess n Hidden))]
805 <|> do try (lchar '%' *> reserved "freeze"); n <- iName []
806 return [PDirective (do setAccessibility n Frozen
807 addIBC (IBCAccess n Frozen))]
808 <|> do try (lchar '%' *> reserved "access"); acc <- accessibility
809 return [PDirective (do i <- get
810 put(i { default_access = acc }))]
811 <|> do try (lchar '%' *> reserved "default"); tot <- totality
813 put (i { default_total = tot } )
814 return [PDirective (do i <- get
815 put(i { default_total = tot }))]
816 <|> do try (lchar '%' *> reserved "logging"); i <- natural;
817 return [PDirective (setLogLevel (fromInteger i))]
818 <|> do try (lchar '%' *> reserved "dynamic"); libs <- sepBy1 stringLiteral (lchar ',');
819 return [PDirective (do added <- addDyLib libs
821 Left lib -> addIBC (IBCDyLib (lib_name lib))
824 <|> do try (lchar '%' *> reserved "language"); ext <- pLangExt;
825 return [PDirective (addLangExt ext)]
828pLangExt :: IdrisParser LanguageExt
829pLangExt = (reserved "TypeProviders" >> return TypeProviders)
830 <|> (reserved "ErrorReflection" >> return ErrorReflection)
832{- | Parses a totality
833Totality ::= 'partial' | 'total'
835totality :: IdrisParser Bool
837 = do reserved "total"; return True
838 <|> do reserved "partial"; return False
840{- | Parses a type provider
841Provider ::= '%' 'provide' '(' FnName TypeSig ')' 'with' Expr;
843provider :: SyntaxInfo -> IdrisParser [PDecl]
844provider syn = do try (lchar '%' *> reserved "provide");
845 lchar '('; n <- fnName; lchar ':'; t <- typeExpr syn; lchar ')'
849 return [PProvider syn fc n t e]
852{- | Parses a transform
853Transform ::= '%' 'transform' Expr '==>' Expr
855transform :: SyntaxInfo -> IdrisParser [PDecl]
856transform syn = do try (lchar '%' *> reserved "transform")
857 -- leave it unchecked, until we work out what this should
859-- safety <- option True (do reserved "unsafe"
865 return [PTransform fc False l r]
869{- * Loading and parsing -}
870{- | Parses an expression from input -}
871parseExpr :: IState -> String -> Result PTerm
872parseExpr st = parseString (runInnerParser (evalStateT (fullExpr defaultSyntax) st)) (Directed (UTF8.fromString "(input)") 0 0 0 0)
874{- | Parses a tactic from input -}
875parseTactic :: IState -> String -> Result PTactic
876parseTactic st = parseString (runInnerParser (evalStateT (fullTactic defaultSyntax) st)) (Directed (UTF8.fromString "(input)") 0 0 0 0)
878-- | Parse module header and imports
879parseImports :: FilePath -> String -> Idris ([String], [String], Maybe Delta)
880parseImports fname input
882 case parseString (runInnerParser (evalStateT imports i)) (Directed (UTF8.fromString fname) 0 0 0 0) input of
883 Failure err -> fail (show err)
884 Success (x, i) -> do -- Discard state updates (there should be
887 where imports :: IdrisParser (([String], [String], Maybe Delta), IState)
888 imports = do whiteSpace
889 mname <- moduleHeader
892 isEof <- lookAheadMatches eof
897 return ((mname, ps, mrk'), i)
900-- | A program is a list of declarations, possibly with associated
901-- documentation strings.
902parseProg :: SyntaxInfo -> FilePath -> String -> Maybe Delta ->
904parseProg syn fname input mrk
906 case parseString (runInnerParser (evalStateT mainProg i)) (Directed (UTF8.fromString fname) 0 0 0 0) input of
907 Failure doc -> do -- FIXME: Get error location from trifecta
908 --let errl = sourceLine (errorPos err)
910 ihputStrLn (idris_outh i) (show doc)
911 putIState (i { errLine = Just 0 }) -- Just errl })
913 Success (x, i) -> do putIState i
915 where mainProg :: IdrisParser ([PDecl], IState)
916 mainProg = case mrk of
917 Nothing -> do i <- get; return ([], i)
924{- | Load idris module -}
925loadModule :: Handle -> FilePath -> Idris String
927 = idrisCatch (do i <- getIState
928 let file = takeWhile (/= ' ') f
929 ibcsd <- valIBCSubDir i
931 fp <- liftIO $ findImport ids ibcsd file
932 if file `elem` imported i
933 then iLOG $ "Already read " ++ file
934 else do putIState (i { imported = file : imported i })
936 IDR fn -> loadSource outh False fn
937 LIDR fn -> loadSource outh True fn
939 idrisCatch (loadIBC fn)
940 (\c -> do iLOG $ fn ++ " failed " ++ show c
942 IDR sfn -> loadSource outh False sfn
943 LIDR sfn -> loadSource outh True sfn)
944 let (dir, fh) = splitFileName file
945 return (dropExtension fh))
946 (\e -> do setErrLine (getErrLine e)
952{- | Load idris code from file -}
953loadFromIFile :: Handle -> IFileType -> Idris ()
954loadFromIFile h i@(IBC fn src)
955 = do iLOG $ "Skipping " ++ getSrcFile i
956 idrisCatch (loadIBC fn)
957 (\err -> ierror $ LoadingFailed fn err)
959 getSrcFile (IDR fn) = fn
960 getSrcFile (LIDR fn) = fn
961 getSrcFile (IBC f src) = getSrcFile src
963loadFromIFile h (IDR fn) = loadSource' h False fn
964loadFromIFile h (LIDR fn) = loadSource' h True fn
966{-| Load idris source code and show error if something wrong happens -}
967loadSource' :: Handle -> Bool -> FilePath -> Idris ()
969 = idrisCatch (loadSource h lidr r)
970 (\e -> do setErrLine (getErrLine e)
974{- | Load Idris source code-}
975loadSource :: Handle -> Bool -> FilePath -> Idris ()
977 = do iLOG ("Reading " ++ f)
979 let def_total = default_total i
980 file_in <- runIO $ readFile f
981 file <- if lidr then tclift $ unlit f file_in else return file_in
982 (mname, modules, pos) <- parseImports f file
984 putIState (i { default_access = Hidden })
985 clearIBC -- start a new .ibc file
986 mapM_ (addIBC . IBCImport) modules
987 ds' <- parseProg (defaultSyntax {syn_namespace = reverse mname })
989 unless (null ds') $ do
990 let ds = namespaces mname ds'
991 logLvl 3 (dumpDecls ds)
993 logLvl 10 (show (toAlist (idris_implicits i)))
994 logLvl 3 (show (idris_infixes i))
995 -- Now add all the declarations to the context
997 when v $ ihputStrLn h $ "Type checking " ++ f
998 -- we totality check after every Mutual block, so if
999 -- anything is a single definition, wrap it in a
1000 -- mutual block on its own
1001 elabDecls toplevel (map toMutual ds)
1003 -- simplify every definition do give the totality checker
1005 mapM_ (\n -> do logLvl 5 $ "Simplifying " ++ show n
1006 updateContext (simplifyCasedef n))
1007 (map snd (idris_totcheck i))
1008 -- build size change graph from simplified definitions
1009 iLOG "Totality checking"
1011 mapM_ buildSCG (idris_totcheck i)
1012 mapM_ checkDeclTotality (idris_totcheck i)
1013 iLOG ("Finished " ++ f)
1014 ibcsd <- valIBCSubDir i
1015 iLOG "Universe checking"
1017 let ibc = ibcPathNoFallback ibcsd f
1019 addHides (hide_list i)
1022 idrisCatch (do writeIBC f ibc; clearIBC)
1023 (\c -> return ()) -- failure is harmless
1025 putIState (i { default_total = def_total,
1030 namespaces :: [String] -> [PDecl] -> [PDecl]
1031 namespaces [] ds = ds
1032 namespaces (x:xs) ds = [PNamespace x (namespaces xs ds)]
1034 toMutual :: PDecl -> PDecl
1035 toMutual m@(PMutual _ d) = m
1036 toMutual (PNamespace x ds) = PNamespace x (map toMutual ds)
1037 toMutual x = let r = PMutual (fileFC "single mutual") [x] in
1039 PClauses _ _ _ _ -> r
1040 PClass _ _ _ _ _ _ _ -> r
1041 PInstance _ _ _ _ _ _ _ _ -> r
1044{- | Adds names to hide list -}
1045addHides :: [(Name, Maybe Accessibility)] -> Idris ()
1046addHides xs = do i <- getIState
1047 let defh = default_access i
1048 let (hs, as) = partition isNothing xs
1051 (map (\ (n, _) -> (n, defh)) hs ++
1052 map (\ (n, Just a) -> (n, a)) as)
1053 where isNothing (_, Nothing) = True
1056 doHide (n, a) = do setAccessibility n a
1057 addIBC (IBCAccess n a)
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