1{-# LANGUAGE PatternGuards #-}
3module Idris.Parser where
21import Text.Parsec.Error
22import Text.Parsec.Expr
23import Text.Parsec.Language
24import Text.Parsec.String
25import qualified Text.Parsec.Token as PTok
28import Data.List.Split(splitOn)
29import Control.Monad.State
34type TokenParser a = PTok.TokenParser a
36type IParser = GenParser Char IState
38lexer :: TokenParser IState
41whiteSpace = PTok.whiteSpace lexer
42lexeme = PTok.lexeme lexer
43symbol = PTok.symbol lexer
44natural = PTok.natural lexer
45parens = PTok.parens lexer
47comma = PTok.comma lexer
48identifier = PTok.identifier lexer
49reserved = PTok.reserved lexer
50operator = PTok.operator lexer
51reservedOp = PTok.reservedOp lexer
52integer = PTok.integer lexer
53float = PTok.float lexer
54strlit = PTok.stringLiteral lexer
55chlit = PTok.charLiteral lexer
60loadModule :: FilePath -> Idris String
62 = idrisCatch (do i <- getIState
63 ibcsd <- valIBCSubDir i
64 ids <- allImportDirs i
65 fp <- liftIO $ findImport ids ibcsd f
66 if f `elem` imported i
67 then iLOG $ "Already read " ++ f
68 else do putIState (i { imported = f : imported i })
70 IDR fn -> loadSource False fn
71 LIDR fn -> loadSource True fn
73 idrisCatch (loadIBC fn)
74 (\c -> do iLOG $ fn ++ " failed " ++ show c
76 IDR sfn -> loadSource False sfn
77 LIDR sfn -> loadSource True sfn)
78 let (dir, fh) = splitFileName f
79 return (dropExtension fh))
80 (\e -> do let msg = show e
81 setErrLine (getErrLine msg)
85loadSource :: Bool -> FilePath -> Idris ()
87 = do iLOG ("Reading " ++ f)
89 let def_total = default_total i
90 file_in <- liftIO $ readFile f
91 file <- if lidr then tclift $ unlit f file_in else return file_in
92 (mname, modules, rest, pos) <- parseImports f file
94 putIState (i { default_access = Hidden })
95 mapM_ loadModule modules
96 clearIBC -- start a new .ibc file
97 mapM_ (addIBC . IBCImport) modules
98 ds' <- parseProg (defaultSyntax {syn_namespace = reverse mname })
100 unless (null ds') $ do
101 let ds = namespaces mname ds'
102 logLvl 3 (dumpDecls ds)
104 logLvl 10 (show (toAlist (idris_implicits i)))
105 logLvl 3 (show (idris_infixes i))
106 -- Now add all the declarations to the context
108 when v $ iputStrLn $ "Type checking " ++ f
109 elabDecls toplevel ds
111 -- simplify every definition do give the totality checker
113 mapM_ (\n -> do logLvl 5 $ "Simplifying " ++ show n
114 updateContext (simplifyCasedef n))
115 (map snd (idris_totcheck i))
116 -- build size change graph from simplified definitions
117 iLOG "Totality checking"
119 -- mapM_ buildSCG (idris_totcheck i)
120 mapM_ checkDeclTotality (idris_totcheck i)
121 iLOG ("Finished " ++ f)
122 ibcsd <- valIBCSubDir i
123 let ibc = ibcPathNoFallback ibcsd f
124 iLOG "Universe checking"
127 addHides (hide_list i)
130 idrisCatch (do writeIBC f ibc; clearIBC)
131 (\c -> return ()) -- failure is harmless
133 putIState (i { default_total = def_total,
138 namespaces [] ds = ds
139 namespaces (x:xs) ds = [PNamespace x (namespaces xs ds)]
141addHides :: [(Name, Maybe Accessibility)] -> Idris ()
142addHides xs = do i <- getIState
143 let defh = default_access i
144 let (hs, as) = partition isNothing xs
147 (map (\ (n, _) -> (n, defh)) hs ++
148 map (\ (n, Just a) -> (n, a)) as)
149 where isNothing (_, Nothing) = True
152 doHide (n, a) = do setAccessibility n a
153 addIBC (IBCAccess n a)
155parseExpr i = runParser (pFullExpr defaultSyntax) i "(input)"
156parseTac i = runParser (do t <- pTactic defaultSyntax
158 return t) i "(proof)"
160parseImports :: FilePath -> String -> Idris ([String], [String], String, SourcePos)
161parseImports fname input
163 case runParser (do whiteSpace
168 return ((mname, ps, rest, pos), i)) i fname input of
169 Left err -> fail (show err)
170 Right (x, i) -> do put i
173pHeader :: IParser [String]
174pHeader = try (do reserved "module"; i <- identifier; option ';' (lchar ';')
175 return (parseName i))
177 where parseName x = case span (/='.') x of
179 (x, '.':y) -> x : parseName y
181pushIndent :: IParser ()
182pushIndent = do pos <- getPosition
184 setState (ist { indent_stack = sourceColumn pos :
187lastIndent :: IParser Int
188lastIndent = do ist <- getState
189 case indent_stack ist of
194indent = liftM sourceColumn getPosition
196popIndent :: IParser ()
197popIndent = do ist <- getState
198 let (x : xs) = indent_stack ist
199 setState (ist { indent_stack = xs })
201openBlock :: IParser ()
202openBlock = do lchar '{'
204 setState (ist { brace_stack = Nothing : brace_stack ist })
205 <|> do ist <- getState
207 setState (ist { brace_stack = Just lvl : brace_stack ist })
209closeBlock :: IParser ()
210closeBlock = do ist <- getState
211 bs <- case brace_stack ist of
212 Nothing : xs -> (lchar '}' >> return xs) <|> (eof >> return [])
213 Just lvl : xs -> (do i <- indent
215-- trace (show (take 10 inp, i, lvl)) $
216 if i >= lvl && take 1 inp /= ")"
217 then fail "Not end of block"
218 else return xs) <|> (eof >> return [])
219 setState (ist { brace_stack = bs })
221pTerminator = do lchar ';'; popIndent
222 <|> do c <- indent; l <- lastIndent
225 else fail "Not a terminator"
227 if "}" `isPrefixOf` i || ")" `isPrefixOf` i
229 else fail "Not a terminator"
233 = do lchar '|'; return ()
234 <|> do c <- indent; l <- lastIndent
235 unless (c <= l) $ fail "Not a terminator"
239 = do lchar ';'; return ()
240 <|> do c <- indent; l <- lastIndent
241 unless (c <= l) $ fail "Not a terminator"
244 unless (h `elem` ["}", ")", "|"]) $ fail "Not a terminator"
247notEndApp = do c <- indent; l <- lastIndent
249 when (c <= l) $ fail "Terminator"
251notEndBlock = do ist <- getState
252 case brace_stack ist of
253 Just lvl : xs -> do i <- indent
255 when (i < lvl || ")" `isPrefixOf` inp) $ fail "End of block"
259pfc = do s <- getPosition
260 let (dir, file) = splitFileName (sourceName s)
261 let f = if dir == addTrailingPathSeparator "." then file else sourceName s
262 return $ FC f (sourceLine s)
264pImport :: IParser String
265pImport = do reserved "import"; f <- identifier; option ';' (lchar ';')
267 where toPath n = foldl1 (</>) $ splitOn "." n
269-- a program is a list of declarations, possibly with associated
270-- documentation strings
272parseProg :: SyntaxInfo -> FilePath -> String -> SourcePos ->
274parseProg syn fname input pos
276 case runParser (do setPosition pos
278 ps <- many (pDecl syn)
281 return (concat ps, i')) i fname input of
282 Left err -> do iputStrLn (show err)
284 Right (x, i) -> do put i
287-- Collect PClauses with the same function name
289collect :: [PDecl] -> [PDecl]
290collect (c@(PClauses _ o _ _) : ds)
291 = clauses (cname c) [] (c : ds)
292 where clauses j@(Just n) acc (PClauses fc _ _ [PClause fc' n' l ws r w] : ds)
293 | n == n' = clauses j (PClause fc' n' l ws r (collect w) : acc) ds
294 clauses j@(Just n) acc (PClauses fc _ _ [PWith fc' n' l ws r w] : ds)
295 | n == n' = clauses j (PWith fc' n' l ws r (collect w) : acc) ds
296 clauses (Just n) acc xs = PClauses (getfc c) o n (reverse acc) : collect xs
297 clauses Nothing acc (x:xs) = collect xs
298 clauses Nothing acc [] = []
300 cname (PClauses fc _ _ [PClause _ n _ _ _ _]) = Just n
301 cname (PClauses fc _ _ [PWith _ n _ _ _ _]) = Just n
302 cname (PClauses fc _ _ [PClauseR _ _ _ _]) = Nothing
303 cname (PClauses fc _ _ [PWithR _ _ _ _]) = Nothing
304 getfc (PClauses fc _ _ _) = fc
306collect (PParams f ns ps : ds) = PParams f ns (collect ps) : collect ds
307collect (PMutual f ms : ds) = PMutual f (collect ms) : collect ds
308collect (PNamespace ns ps : ds) = PNamespace ns (collect ps) : collect ds
309collect (PClass doc f s cs n ps ds : ds')
310 = PClass doc f s cs n ps (collect ds) : collect ds'
311collect (PInstance f s cs n ps t en ds : ds')
312 = PInstance f s cs n ps t en (collect ds) : collect ds'
313collect (d : ds) = d : collect ds
316pFullExpr :: SyntaxInfo -> IParser PTerm
318 = do x <- pExpr syn; eof;
320 return $ desugar syn i x
322pDecl :: SyntaxInfo -> IParser [PDecl]
323pDecl syn = do notEndBlock
328 let d' = fmap (desugar syn i) d
336 <|> do d <- pDSL syn; return [d]
338 <|> try (do reserved "import"; fp <- identifier
339 fail "imports must be at the top of file")
341pFunDecl :: SyntaxInfo -> IParser [PDecl]
343 = try (do notEndBlock
346 let d' = fmap (desugar syn i) d
349--------- Top Level Declarations ---------
351pDecl' :: SyntaxInfo -> IParser PDecl
354 <|> try (pFunDecl' syn)
356 <|> try (pRecord syn)
357 <|> try (pSyntaxDecl syn)
359pSyntaxDecl :: SyntaxInfo -> IParser PDecl
361 = do s <- pSyntaxRule syn
363 let rs = syntax_rules i
364 let ns = syntax_keywords i
365 let ibc = ibc_write i
366 let ks = map show (names s)
367 setState (i { syntax_rules = s : rs,
368 syntax_keywords = ks ++ ns,
369 ibc_write = IBCSyntax s : map IBCKeyword ks ++ ibc
372 return (PSyntax fc s)
374 names (Rule syms _ _) = mapMaybe ename syms
375 ename (Keyword n) = Just n
378pSyntaxRule :: SyntaxInfo -> IParser Syntax
381 sty <- option AnySyntax (do reserved "term"; return TermSyntax
382 <|> do reserved "pattern"; return PatternSyntax)
384 syms <- many1 pSynSym
385 when (all expr syms) $ fail "No keywords in syntax rule"
386 let ns = mapMaybe name syms
387 when (length ns /= length (nub ns))
388 $ fail "Repeated variable in syntax rule"
390 tm <- pExpr (impOK syn)
392 return (Rule (mkSimple syms) tm sty)
396 name (Expr n) = Just n
399 -- Can't parse two full expressions (i.e. expressions with application) in a row
400 -- so change the first to a simple expression
402 mkSimple (Expr e : es) = SimpleExpr e : mkSimple' es
403 mkSimple xs = mkSimple' xs
405 mkSimple' (Expr e : Expr e1 : es) = SimpleExpr e : mkSimple' (Expr e1 : es)
406 mkSimple' (e : es) = e : mkSimple' es
409pSynSym :: IParser SSymbol
410pSynSym = try (do lchar '['; n <- pName; lchar ']'
412 <|> try (do lchar '{'; n <- pName; lchar '}'
419pFunDecl' :: SyntaxInfo -> IParser PDecl
420pFunDecl' syn = try (do doc <- option "" (pDocComment '|')
423 let initOpts = if default_total ist
426 opts <- pFnOpts initOpts
427 acc <- pAccessibility
428 opts' <- pFnOpts opts
430 let n = expandNS syn n_in
431 ty <- pTSig (impOK syn)
434-- ty' <- implicit syn n ty
436 return (PTy doc syn fc opts' n ty))
437 <|> try (pPostulate syn)
438 <|> try (pPattern syn)
441pPostulate :: SyntaxInfo -> IParser PDecl
442pPostulate syn = do doc <- option "" (pDocComment '|')
446 let initOpts = if default_total ist
449 opts <- pFnOpts initOpts
450 acc <- pAccessibility
451 opts' <- pFnOpts opts
453 let n = expandNS syn n_in
454 ty <- pTSig (impOK syn)
458 return (PPostulate doc syn fc opts' n ty)
461pUsing :: SyntaxInfo -> IParser [PDecl]
463 do reserved "using"; lchar '('; ns <- tyDeclList syn; lchar ')'
465 let uvars = using syn
466 ds <- many1 (pDecl (syn { using = uvars ++ ns }))
470pParams :: SyntaxInfo -> IParser [PDecl]
472 do reserved "parameters"; lchar '('; ns <- tyDeclList syn; lchar ')'
474 let pvars = syn_params syn
475 ds <- many1 (pDecl syn { syn_params = pvars ++ ns })
478 return [PParams fc ns (concat ds)]
480pMutual :: SyntaxInfo -> IParser [PDecl]
484 let pvars = syn_params syn
485 ds <- many1 (pDecl syn)
488 return [PMutual fc (concat ds)]
490pNamespace :: SyntaxInfo -> IParser [PDecl]
492 do reserved "namespace"; n <- identifier;
494 ds <- many1 (pDecl syn { syn_namespace = n : syn_namespace syn })
496 return [PNamespace n (concat ds)]
498--------- Fixity ---------
500pFixity :: IParser PDecl
501pFixity = do pushIndent
502 f <- fixity; i <- natural; ops <- sepBy1 operator (lchar ',')
504 let prec = fromInteger i
506 let infixes = idris_infixes istate
507 let fs = map (Fix (f prec)) ops
508 let redecls = map (alreadyDeclared infixes) fs
509 let ill = filter (not . checkValidity) redecls
511 then do setState (istate { idris_infixes = nub $ sort (fs ++ infixes)
512 , ibc_write = map IBCFix fs ++ ibc_write istate
515 return (PFix fc (f prec) ops)
516 else fail $ concatMap (\(f, (x:xs)) -> "Illegal redeclaration of fixity:\n\t\""
517 ++ show f ++ "\" overrides \"" ++ show x ++ "\"") ill
518 where alreadyDeclared :: [FixDecl] -> FixDecl -> (FixDecl, [FixDecl])
519 alreadyDeclared fs f = (f, filter ((extractName f ==) . extractName) fs)
521 checkValidity :: (FixDecl, [FixDecl]) -> Bool
522 checkValidity (f, fs) = all (== f) fs
524 extractName :: FixDecl -> String
525 extractName (Fix _ n) = n
527fixity :: IParser (Int -> Fixity)
528fixity = try (do reserved "infixl"; return Infixl)
529 <|> try (do reserved "infixr"; return Infixr)
530 <|> try (do reserved "infix"; return InfixN)
531 <|> try (do reserved "prefix"; return PrefixN)
533--------- Type classes ---------
535pClass :: SyntaxInfo -> IParser [PDecl]
536pClass syn = do doc <- option "" (pDocComment '|')
537 acc <- pAccessibility
538 reserved "class"; fc <- pfc; cons <- pConstList syn; n_in <- pName
539 let n = expandNS syn n_in
541 reserved "where"; openBlock
542 ds <- many $ pFunDecl syn
544 let allDs = concat ds
545 accData acc n (concatMap declared allDs)
546 return [PClass doc syn fc cons n cs allDs]
548 carg = do lchar '('; i <- pName; lchar ':'; ty <- pExpr syn; lchar ')'
553pInstance :: SyntaxInfo -> IParser [PDecl]
554pInstance syn = do reserved "instance"; fc <- pfc
556 (do lchar '['; n_in <- pfName; lchar ']'
557 let n = expandNS syn n_in
561 args <- many1 (pSimpleExpr syn)
562 let sc = PApp fc (PRef fc cn) (map pexp args)
563 let t = bindList (PPi constraint) (map (\x -> (MN 0 "c", x)) cs) sc
564 reserved "where"; openBlock
565 ds <- many $ pFunDecl syn
567 return [PInstance syn fc cs cn args t en (concat ds)]
569--------- Expressions ---------
571pExpr syn = do i <- getState
572 buildExpressionParser (table (idris_infixes i)) (pExpr' syn)
574pExpr' :: SyntaxInfo -> IParser PTerm
579pExtExpr :: SyntaxInfo -> IParser PTerm
580pExtExpr syn = do i <- getState
581 pExtensions syn (syntax_rules i)
583pSimpleExtExpr :: SyntaxInfo -> IParser PTerm
584pSimpleExtExpr syn = do i <- getState
585 pExtensions syn (filter simple (syntax_rules i))
587 simple (Rule (Expr x:xs) _ _) = False
588 simple (Rule (SimpleExpr x:xs) _ _) = False
589 simple (Rule [Keyword _] _ _) = True
590 simple (Rule [Symbol _] _ _) = True
591 simple (Rule (_:xs) _ _) = case last xs of
600 <|> try (pSimpleExpr syn)
605 <|> pComprehension syn
607pExtensions :: SyntaxInfo -> [Syntax] -> IParser PTerm
608pExtensions syn rules = choice (map (try . pExt syn) (filter valid rules))
610 valid (Rule _ _ AnySyntax) = True
611 valid (Rule _ _ PatternSyntax) = inPattern syn
612 valid (Rule _ _ TermSyntax) = not (inPattern syn)
615data SynMatch = SynTm PTerm | SynBind Name
617pExt :: SyntaxInfo -> Syntax -> IParser PTerm
618pExt syn (Rule ssym ptm _)
619 = do smap <- mapM pSymbol ssym
620 let ns = mapMaybe id smap
621 return (update ns ptm) -- updated with smap
623 pSymbol (Keyword n) = do reserved (show n); return Nothing
624 pSymbol (Expr n) = do tm <- pExpr syn
625 return $ Just (n, SynTm tm)
626 pSymbol (SimpleExpr n) = do tm <- pSimpleExpr syn
627 return $ Just (n, SynTm tm)
628 pSymbol (Binding n) = do b <- pName
629 return $ Just (n, SynBind b)
630 pSymbol (Symbol s) = do symbol s
633 dropn n ((x,t) : xs) | n == x = xs
634 | otherwise = (x,t):dropn n xs
636 updateB ns n = case lookup n ns of
637 Just (SynBind t) -> t
640 update ns (PRef fc n) = case lookup n ns of
643 update ns (PLam n ty sc) = PLam (updateB ns n) (update ns ty) (update (dropn n ns) sc)
644 update ns (PPi p n ty sc) = PPi p (updateB ns n) (update ns ty) (update (dropn n ns) sc)
645 update ns (PLet n ty val sc) = PLet (updateB ns n) (update ns ty) (update ns val)
646 (update (dropn n ns) sc)
647 update ns (PApp fc t args) = PApp fc (update ns t) (map (fmap (update ns)) args)
648 update ns (PCase fc c opts) = PCase fc (update ns c) (map (pmap (update ns)) opts)
649 update ns (PPair fc l r) = PPair fc (update ns l) (update ns r)
650 update ns (PDPair fc l t r) = PDPair fc (update ns l) (update ns t) (update ns r)
651 update ns (PAlternative a as) = PAlternative a (map (update ns) as)
652 update ns (PHidden t) = PHidden (update ns t)
653 update ns (PDoBlock ds) = PDoBlock $ upd ns ds
654 where upd ns (DoExp fc t : ds) = DoExp fc (update ns t) : upd ns ds
655 upd ns (DoBind fc n t : ds) = DoBind fc n (update ns t) : upd (dropn n ns) ds
656 upd ns (DoLet fc n ty t : ds) = DoLet fc n (update ns ty) (update ns t)
657 : upd (dropn n ns) ds
658 upd ns (DoBindP fc i t : ds) = DoBindP fc (update ns i) (update ns t)
660 upd ns (DoLetP fc i t : ds) = DoLetP fc (update ns i) (update ns t)
664pName = do i <- getState
665 iName (syntax_keywords i)
666 <|> do reserved "instance"
668 UN n <- iName (syntax_keywords i)
671-- Parser for an operator in function position, i.e. enclosed by `()', with an
672-- optional namespace.
673pOpFront = maybeWithNS pOpFrontNoNS False []
674 where pOpFrontNoNS = do lchar '('; o <- operator; lchar ')'; return o
679pTotality :: IParser Bool
681 = do reserved "total"; return True
682 <|> do reserved "partial"; return False
684pAccessibility' :: IParser Accessibility
686 = do reserved "public"; return Public
687 <|> do reserved "abstract"; return Frozen
688 <|> do reserved "private"; return Hidden
690pAccessibility :: IParser (Maybe Accessibility)
692 = do acc <- pAccessibility'; return (Just acc)
695pFnOpts :: [FnOpt] -> IParser [FnOpt]
697 = do reserved "total"; pFnOpts (TotalFn : opts)
698 <|> do reserved "partial"; pFnOpts (PartialFn : (opts \\ [TotalFn]))
699 <|> try (do lchar '%'; reserved "export"; c <- strlit;
700 pFnOpts (CExport c : opts))
701 <|> do lchar '%'; reserved "assert_total"; pFnOpts (AssertTotal : opts)
702 <|> do lchar '%'; reserved "specialise";
703 lchar '['; ns <- sepBy pfName (lchar ','); lchar ']'
704 pFnOpts (Specialise ns : opts)
707addAcc :: Name -> Maybe Accessibility -> IParser ()
708addAcc n a = do i <- getState
709 setState (i { hide_list = (n, a) : hide_list i })
712 reserved "case"; fc <- pfc; scr <- pExpr syn; reserved "of";
715 opts <- many1 (do notEndBlock
718 return x) -- sepBy1 (pCaseOpt syn) (lchar '|')
721 return (PCase fc scr opts)
724 reserved "proof"; lchar '{'
725 ts <- endBy (pTactic syn) (lchar ';')
730 reserved "tactics"; lchar '{'
731 ts <- endBy (pTactic syn) (lchar ';')
736 try (do symbol "!["; t <- pTerm; lchar ']'; return $ PQuote t)
737 <|> do lchar '?'; x <- pName; return (PMetavar x)
738 <|> do reserved "refl"; fc <- pfc;
739 tm <- option Placeholder (do lchar '{'; t <- pExpr syn; lchar '}';
742-- <|> do reserved "return"; fc <- pfc; return (PReturn fc)
746 <|> try (do x <- pfName
749 <|> try (do lchar '!'; x <- pfName
751 return (PInferRef fc x))
755 <|> try (do lchar '('
756 bracketed (noImp syn))
757 <|> try (do c <- pConstant
759 return (modifyConst syn fc (PConstant c)))
760 <|> do reserved "Set"; return PSet
761 <|> try (do symbol "()"
764 <|> try (do symbol "_|_"
767 <|> do lchar '_'; return Placeholder
768 <|> pSimpleExtExpr syn
772 <|> try (do e <- pExpr syn; lchar ')'; return e)
773-- <|> try (do reserved "typed"
774-- e <- pExpr syn; symbol ":"; t <- pExpr syn; lchar ')'
775-- return (PTyped e t))
776 <|> try (do fc <- pfc; o <- operator; e <- pExpr syn; lchar ')'
777 return $ PLam (MN 1000 "ARG") Placeholder
778 (PApp fc (PRef fc (UN o)) [pexp (PRef fc (MN 1000 "ARG")),
780 <|> try (do fc <- pfc; e <- pSimpleExpr syn; o <- operator; lchar ')'
781 return $ PLam (MN 1000 "ARG") Placeholder
782 (PApp fc (PRef fc (UN o)) [pexp e,
783 pexp (PRef fc (MN 1000 "ARG"))]))
785pCaseOpt :: SyntaxInfo -> IParser (PTerm, PTerm)
786pCaseOpt syn = do lhs <- pExpr syn; symbol "=>"; rhs <- pExpr syn
789modifyConst :: SyntaxInfo -> FC -> PTerm -> PTerm
790modifyConst syn fc (PConstant (I x))
791 | not (inPattern syn)
793 [PApp fc (PRef fc (UN "fromInteger")) [pexp (PConstant (I x))],
794 PConstant (I x), PConstant (BI (toEnum x))]
795 | otherwise = PAlternative False
796 [PConstant (I x), PConstant (BI (toEnum x))]
797modifyConst syn fc x = x
799pList syn = do lchar '['; fc <- pfc; xs <- sepBy (pExpr syn) (lchar ','); lchar ']'
800 return (mkList fc xs)
802 mkList fc [] = PRef fc (UN "Nil")
803 mkList fc (x : xs) = PApp fc (PRef fc (UN "::")) [pexp x, pexp (mkList fc xs)]
805pPair syn = try (do l <- pExpr syn
810 [Left r] -> return (PPair fc l r)
811 [Right r] -> return (PDPair fc l Placeholder r))
812 <|> try (do x <- ntuple
815 <|> do ln <- pName; lchar ':'
821 return (PDPair fc (PRef fc ln) lty r)
823 restTuple = do lchar ')'; return []
828 <|> do reservedOp "**"
832 ntuple = try (do l <- pExpr syn; fc <- pfc; lchar ','
834 return (PPair fc l rest))
835 <|> (do l <- pExpr syn; fc <- pfc; lchar ','
837 return (PPair fc l r))
839pAlt syn = do symbol "(|"; alts <- sepBy1 (pExpr' syn) (lchar ','); symbol "|)"
840 return (PAlternative False alts)
848pApp syn = do f <- pSimpleExpr syn
850 args <- many1 (do notEndApp
853 return (dslify i $ PApp fc f args)
855 dslify i (PApp fc (PRef _ f) [a])
856 | [d] <- lookupCtxt Nothing f (idris_dsls i)
857 = desugar (syn { dsl_info = d }) i (getTm a)
860pArg :: SyntaxInfo -> IParser PArg
861pArg syn = try (pImplicitArg syn)
862 <|> try (pConstraintArg syn)
863 <|> do e <- pSimpleExpr syn
866pImplicitArg syn = do lchar '{'
869 v <- option (PRef fc n) (do lchar '='
874pConstraintArg syn = do symbol "@{"
880 = do reserved "record"
882 fields <- sepBy1 pFieldSet (lchar ',')
885 rec <- option Nothing (do e <- pSimpleExpr syn
889 return (PLam (MN 0 "fldx") Placeholder
890 (applyAll fc fields (PRef fc (MN 0 "fldx"))))
891 Just v -> return (applyAll fc fields v)
892 where pFieldSet = do n <- pfName
897 applyAll fc ((n, e) : es) x
898 = applyAll fc es (PApp fc (PRef fc (mkSet n)) [pexp e, pexp x])
900mkSet (UN n) = UN ("set_" ++ n)
901mkSet (MN 0 n) = MN 0 ("set_" ++ n)
902mkSet (NS n s) = NS (mkSet n) s
904noImp syn = syn { implicitAllowed = False }
905impOK syn = syn { implicitAllowed = True }
907pTSig syn = do lchar ':'
908 cs <- if implicitAllowed syn then pConstList syn else return []
910 return (bindList (PPi constraint) (map (\x -> (MN 0 "c", x)) cs) sc)
912pLambda syn = do lchar '\\'
913 try (do xt <- tyOptDeclList syn
916 return (bindList PLam xt sc)
917 <|> (do ps <- sepBy (do fc <- pfc
919 return (fc, e)) (lchar ',')
922 return (pmList (zip [0..] ps) sc)))
923 where pmList [] sc = sc
924 pmList ((i, (fc, x)) : xs) sc
925 = PLam (MN i "lamp") Placeholder
926 (PCase fc (PRef fc (MN i "lamp"))
929pLet syn = try (do reserved "let"; n <- pName;
930 ty <- option Placeholder (do lchar ':'; pExpr' syn)
933 reserved "in"; sc <- pExpr syn
934 return (PLet n ty v sc))
935 <|> (do reserved "let"; fc <- pfc; pat <- pExpr' (syn { inPattern = True } )
936 symbol "="; v <- pExpr syn
937 reserved "in"; sc <- pExpr syn
938 return (PCase fc v [(pat, sc)]))
941 try (do lazy <- option False (do lchar '|'; return True)
943 lchar '('; xt <- tyDeclList syn; lchar ')'
944 doc <- option "" (pDocComment '^')
947 return (bindList (PPi (Exp lazy st doc)) xt sc))
948 <|> try (if implicitAllowed syn
949 then do lazy <- option False (do lchar '|'
957 return (bindList (PPi (Imp lazy st "")) xt sc)
958 else fail "No implicit arguments allowed here")
959 <|> try (do lchar '{'
965 return (bindList (PPi
966 (TacImp False Dynamic (PTactics [Trivial]) "")) xt sc))
967 <|> try (do lchar '{'
969 script <- pSimpleExpr syn
974 return (bindList (PPi (TacImp False Dynamic script "")) xt sc))
975 <|> do --lazy <- option False (do lchar '|'; return True)
982 return (PPi (Exp False Static "") (MN 42 "__pi_arg") t sc)
984pConstList :: SyntaxInfo -> IParser [PTerm]
985pConstList syn = try (do lchar '('
986 tys <- sepBy1 (pExpr' (noImp syn)) (lchar ',')
990 <|> try (do t <- pExpr (noImp syn)
995tyDeclList syn = try (sepBy1 (do x <- pfName
996 t <- pTSig (noImp syn)
999 <|> do ns <- sepBy1 pName (lchar ',')
1000 t <- pTSig (noImp syn)
1001 return (map (\x -> (x, t)) ns)
1003tyOptDeclList syn = sepBy1 (do x <- pfName;
1004 t <- option Placeholder (do lchar ':'
1009bindList b [] sc = sc
1010bindList b ((n, t):bs) sc = b n t (bindList b bs sc)
1017 qs <- sepBy1 (pDo syn) (lchar ',')
1019 return (PDoBlock (map addGuard qs ++
1020 [DoExp fc (PApp fc (PRef fc (UN "return"))
1022 where addGuard (DoExp fc e) = DoExp fc (PApp fc (PRef fc (UN "guard"))
1030 ds <- many1 (do notEndBlock
1036 return (PDoBlock ds)
1039 = try (do reserved "let"
1041 ty <- option Placeholder (do lchar ':'
1046 return (DoLet fc i ty e))
1047 <|> try (do reserved "let"
1052 return (DoLetP fc i sc))
1053 <|> try (do i <- pName
1057 return (DoBind fc i e))
1058 <|> try (do i <- pExpr' syn
1062 return (DoBindP fc i e))
1063 <|> try (do e <- pExpr syn
1065 return (DoExp fc e))
1072 return (PIdiom fc e)
1074pConstant :: IParser Const
1075pConstant = do reserved "Integer";return BIType
1076 <|> do reserved "Int"; return IType
1077 <|> do reserved "Char"; return ChType
1078 <|> do reserved "Float"; return FlType
1079 <|> do reserved "String"; return StrType
1080 <|> do reserved "Ptr"; return PtrType
1081 <|> try (do f <- float; return $ Fl f)
1082-- <|> try (do i <- natural; lchar 'L'; return $ BI i)
1083 <|> try (do i <- natural; return $ I (fromInteger i))
1084 <|> try (do s <- strlit; return $ Str s)
1085 <|> try (do c <- chlit; return $ Ch c)
1087pStatic :: IParser Static
1088pStatic = do lchar '['
1095 = [[prefix "-" (\fc x -> PApp fc (PRef fc (UN "-"))
1096 [pexp (PApp fc (PRef fc (UN "fromInteger")) [pexp (PConstant (I 0))]), pexp x])]]
1097 ++ toTable (reverse fixes) ++
1099 [binary "=" PEq AssocLeft],
1100 [binary "->" (\fc x y -> PPi expl (MN 42 "__pi_arg") x y) AssocRight]]
1102toTable fs = map (map toBin)
1103 (groupBy (\ (Fix x _) (Fix y _) -> prec x == prec y) fs)
1104 where toBin (Fix (PrefixN _) op) = prefix op
1105 (\fc x -> PApp fc (PRef fc (UN op)) [pexp x])
1107 = binary op (\fc x y -> PApp fc (PRef fc (UN op)) [pexp x,pexp y]) (assoc f)
1108 assoc (Infixl _) = AssocLeft
1109 assoc (Infixr _) = AssocRight
1110 assoc (InfixN _) = AssocNone
1112binary name f = Infix (do reservedOp name
1114 doc <- option "" (pDocComment '^')
1116prefix name f = Prefix (do reservedOp name
1119backtick = Infix (do lchar '`'; n <- pfName
1122 return (\x y -> PApp fc (PRef fc n) [pexp x, pexp y])) AssocNone
1124--------- Data declarations ---------
1126-- (works for classes too - 'abstract' means the data/class is visible but members not)
1127accData :: Maybe Accessibility -> Name -> [Name] -> IParser ()
1128accData (Just Frozen) n ns = do addAcc n (Just Frozen)
1129 mapM_ (\n -> addAcc n (Just Hidden)) ns
1130accData a n ns = do addAcc n a
1131 mapM_ (`addAcc` a) ns
1133pRecord :: SyntaxInfo -> IParser PDecl
1134pRecord syn = do acc <- pAccessibility
1138 ty <- pTSig (impOK syn)
1139 let tyn = expandNS syn tyn_in
1143 (cdoc, cn, cty, _) <- pConstructor syn
1147 accData acc tyn [cn]
1148 let rsyn = syn { syn_namespace = show (nsroot tyn) :
1150 let fns = getRecNames rsyn cty
1151 mapM_ (\n -> addAcc n acc) fns
1152 return $ PRecord "" rsyn fc tyn ty cdoc cn cty
1154 getRecNames syn (PPi _ n _ sc) = [expandNS syn n, expandNS syn (mkSet n)]
1155 ++ getRecNames syn sc
1156 getRecNames _ _ = []
1158 toFreeze (Just Frozen) = Just Hidden
1161pDataI = do reserved "data"; return False
1162 <|> do reserved "codata"; return True
1164pData :: SyntaxInfo -> IParser PDecl
1165pData syn = try (do doc <- option "" (pDocComment '|')
1166 acc <- pAccessibility
1170 ty <- pTSig (impOK syn)
1171 let tyn = expandNS syn tyn_in
1172 option (PData doc syn fc co (PLaterdecl tyn ty)) (do
1176 cons <- many (do notEndBlock
1177 c <- pConstructor syn
1179 return c) -- (lchar '|')
1182 accData acc tyn (map (\ (_, n, _, _) -> n) cons)
1183 return $ PData doc syn fc co (PDatadecl tyn ty cons)))
1184 <|> try (do doc <- option "" (pDocComment '|')
1186 acc <- pAccessibility
1191 let ty = bindArgs (map (const PSet) args) PSet
1192 let tyn = expandNS syn tyn_in
1193 option (PData doc syn fc co (PLaterdecl tyn ty)) (do
1195 cons <- sepBy1 (pSimpleCon syn) (lchar '|')
1197 let conty = mkPApp fc (PRef fc tyn) (map (PRef fc) args)
1198 cons' <- mapM (\ (doc, x, cargs, cfc) ->
1199 do let cty = bindArgs cargs conty
1200 return (doc, x, cty, cfc)) cons
1201 accData acc tyn (map (\ (_, n, _, _) -> n) cons')
1202 return $ PData doc syn fc co (PDatadecl tyn ty cons')))
1205 mkPApp fc t xs = PApp fc t (map pexp xs)
1207bindArgs :: [PTerm] -> PTerm -> PTerm
1208bindArgs xs t = foldr (PPi expl (MN 0 "t")) t xs
1210pConstructor :: SyntaxInfo -> IParser (String, Name, PTerm, FC)
1212 = do doc <- option "" (pDocComment '|')
1213 cn_in <- pfName; fc <- pfc
1214 let cn = expandNS syn cn_in
1215 ty <- pTSig (impOK syn)
1216-- ty' <- implicit syn cn ty
1217 return (doc, cn, ty, fc)
1220pSimpleCon :: SyntaxInfo -> IParser (String, Name, [PTerm], FC)
1222 = do cn_in <- pfName
1223 let cn = expandNS syn cn_in
1225 args <- many (do notEndApp
1227 doc <- option "" (pDocComment '^')
1228 return (doc, cn, args, fc)
1230--------- DSL syntax overloading ---------
1232pDSL :: SyntaxInfo -> IParser PDecl
1233pDSL syn = do reserved "dsl"
1237 bs <- many1 (do notEndBlock
1241 popIndent; closeBlock
1242 let dsl = mkDSL bs (dsl_info syn)
1245 setState (i { idris_dsls = addDef n dsl (idris_dsls i) })
1247 where mkDSL bs dsl = let var = lookup "variable" bs
1248 first = lookup "index_first" bs
1249 next = lookup "index_next" bs
1250 leto = lookup "let" bs
1251 lambda = lookup "lambda" bs in
1252 initDSL { dsl_var = var,
1253 index_first = first,
1255 dsl_lambda = lambda,
1258checkDSL :: DSL -> IParser ()
1259checkDSL dsl = return ()
1261pOverload :: SyntaxInfo -> IParser (String, PTerm)
1262pOverload syn = do o <- identifier <|> do reserved "let"
1264 if o `notElem` overloadable
1265 then fail $ show o ++ " is not an overloading"
1270 where overloadable = ["let","lambda","index_first","index_next","variable"]
1272--------- Pattern match clauses ---------
1274pPattern :: SyntaxInfo -> IParser PDecl
1275pPattern syn = do fc <- pfc
1276 clause <- pClause syn
1277 return (PClauses fc [] (MN 2 "_") [clause]) -- collect together later
1279pCAF :: SyntaxInfo -> IParser PDecl
1280pCAF syn = do reserved "let"
1281 n_in <- pfName; let n = expandNS syn n_in
1286 return (PCAF fc n t)
1288pArgExpr syn = let syn' = syn { inPattern = True } in
1289 try (pHSimpleExpr syn') <|> pSimpleExtExpr syn'
1291pRHS :: SyntaxInfo -> Name -> IParser PTerm
1292pRHS syn n = do lchar '='; pExpr syn
1293 <|> do symbol "?="; rhs <- pExpr syn;
1295 <|> do reserved "impossible"; return PImpossible
1296 where mkN (UN x) = UN (x++"_lemma_1")
1297 mkN (NS x n) = NS (mkN x) n
1300 addLet (PLet n ty val rhs) = PLet n ty val (addLet rhs)
1301 addLet (PCase fc t cs) = PCase fc t (map addLetC cs)
1302 where addLetC (l, r) = (l, addLet r)
1303 addLet rhs = (PLet (UN "value") Placeholder rhs (PMetavar n'))
1305pClause :: SyntaxInfo -> IParser PClause
1307 = try (do pushIndent
1308 n_in <- pfName; let n = expandNS syn n_in
1309 cargs <- many (pConstraintArg syn)
1310 iargs <- many (pImplicitArg (syn { inPattern = True } ))
1312 args <- many (pArgExpr syn)
1313 wargs <- many (pWExpr syn)
1316 let ctxt = tt_ctxt ist
1317 let wsyn = syn { syn_namespace = [] }
1318 (wheres, nmap) <- choice [do x <- pWhereblock n wsyn
1323 let capp = PApp fc (PRef fc n)
1324 (iargs ++ cargs ++ map pexp args)
1326 setState (ist { lastParse = Just n })
1327 return $ PClause fc n capp wargs rhs wheres)
1328 <|> try (do pushIndent
1329 wargs <- many1 (pWExpr syn)
1331 n <- case lastParse ist of
1333 Nothing -> fail "Invalid clause"
1336 let ctxt = tt_ctxt ist
1337 let wsyn = syn { syn_namespace = [] }
1338 (wheres, nmap) <- choice [do x <- pWhereblock n wsyn
1343 return $ PClauseR fc wargs rhs wheres)
1345 <|> try (do pushIndent
1346 n_in <- pfName; let n = expandNS syn n_in
1347 cargs <- many (pConstraintArg syn)
1348 iargs <- many (pImplicitArg (syn { inPattern = True } ))
1350 args <- many (pArgExpr syn)
1351 wargs <- many (pWExpr syn)
1352 let capp = PApp fc (PRef fc n)
1353 (iargs ++ cargs ++ map pexp args)
1355 setState (ist { lastParse = Just n })
1357 wval <- pSimpleExpr syn
1359 ds <- many1 $ pFunDecl syn
1360 let withs = map (fillLHSD n capp wargs) $ concat ds
1363 return $ PWith fc n capp wargs wval withs)
1365 <|> try (do wargs <- many1 (pWExpr syn)
1368 wval <- pSimpleExpr syn
1370 ds <- many1 $ pFunDecl syn
1371 let withs = concat ds
1373 return $ PWithR fc wargs wval withs)
1378 let n = expandNS syn (UN op)
1381 wargs <- many (pWExpr syn)
1383 let wsyn = syn { syn_namespace = [] }
1384 (wheres, nmap) <- choice [do x <- pWhereblock n wsyn
1390 let capp = PApp fc (PRef fc n) [pexp l, pexp r]
1391 setState (ist { lastParse = Just n })
1392 return $ PClause fc n capp wargs rhs wheres
1394 <|> do l <- pArgExpr syn
1396 let n = expandNS syn (UN op)
1399 wargs <- many (pWExpr syn)
1401 wval <- pSimpleExpr syn
1403 ds <- many1 $ pFunDecl syn
1406 let capp = PApp fc (PRef fc n) [pexp l, pexp r]
1407 let withs = map (fillLHSD n capp wargs) $ concat ds
1408 setState (ist { lastParse = Just n })
1409 return $ PWith fc n capp wargs wval withs
1411 fillLHS n capp owargs (PClauseR fc wargs v ws)
1412 = PClause fc n capp (owargs ++ wargs) v ws
1413 fillLHS n capp owargs (PWithR fc wargs v ws)
1414 = PWith fc n capp (owargs ++ wargs) v
1415 (map (fillLHSD n capp (owargs ++ wargs)) ws)
1418 fillLHSD n c a (PClauses fc o fn cs) = PClauses fc o fn (map (fillLHS n c a) cs)
1419 fillLHSD n c a x = x
1421pWExpr :: SyntaxInfo -> IParser PTerm
1422pWExpr syn = do lchar '|'
1425pWhereblock :: Name -> SyntaxInfo -> IParser ([PDecl], [(Name, Name)])
1427 = do reserved "where"; openBlock
1428 ds <- many1 $ pDecl syn
1429 let dns = concatMap (concatMap declared) ds
1431 return (concat ds, map (\x -> (x, decoration syn x)) dns)
1433pDirective :: IParser [PDecl]
1434pDirective = try (do lchar '%'; reserved "lib"; lib <- strlit;
1435 return [PDirective (do addLib lib
1436 addIBC (IBCLib lib))])
1437 <|> try (do lchar '%'; reserved "link"; obj <- strlit;
1438 return [PDirective (do datadir <- liftIO getDataDir
1439 o <- liftIO $ findInPath [".", datadir] obj
1442 <|> try (do lchar '%'; reserved "include"; hdr <- strlit;
1443 return [PDirective (do addHdr hdr
1444 addIBC (IBCHeader hdr))])
1445 <|> try (do lchar '%'; reserved "hide"; n <- iName []
1446 return [PDirective (do setAccessibility n Hidden
1447 addIBC (IBCAccess n Hidden))])
1448 <|> try (do lchar '%'; reserved "freeze"; n <- iName []
1449 return [PDirective (do setAccessibility n Frozen
1450 addIBC (IBCAccess n Frozen))])
1451 <|> try (do lchar '%'; reserved "access"; acc <- pAccessibility'
1452 return [PDirective (do i <- getIState
1453 putIState (i { default_access = acc }))])
1454 <|> try (do lchar '%'; reserved "default"; tot <- pTotality
1456 setState (i { default_total = tot } )
1457 return [PDirective (do i <- getIState
1458 putIState (i { default_total = tot }))])
1459 <|> try (do lchar '%'; reserved "logging"; i <- natural;
1460 return [PDirective (setLogLevel (fromInteger i))])
1462pTactic :: SyntaxInfo -> IParser PTactic
1463pTactic syn = do reserved "intro"; ns <- sepBy pName (lchar ',')
1465 <|> do reserved "intros"; return Intros
1466 <|> try (do reserved "refine"; n <- pName
1468 return $ Refine n imps)
1469 <|> do reserved "refine"; n <- pName
1471 return $ Refine n []
1472 <|> do reserved "rewrite"; t <- pExpr syn;
1474 return $ Rewrite (desugar syn i t)
1475 <|> try (do reserved "let"; n <- pName; lchar ':';
1476 ty <- pExpr' syn; lchar '='; t <- pExpr syn;
1478 return $ LetTacTy n (desugar syn i ty) (desugar syn i t))
1479 <|> try (do reserved "let"; n <- pName; lchar '=';
1482 return $ LetTac n (desugar syn i t))
1483 <|> do reserved "focus"; n <- pName
1485 <|> do reserved "exact"; t <- pExpr syn;
1487 return $ Exact (desugar syn i t)
1488 <|> do reserved "try"; t <- pTactic syn;
1498 <|> do reserved "compute"; return Compute
1499 <|> do reserved "trivial"; return Trivial
1500 <|> do reserved "solve"; return Solve
1501 <|> do reserved "attack"; return Attack
1502 <|> do reserved "state"; return ProofState
1503 <|> do reserved "term"; return ProofTerm
1504 <|> do reserved "undo"; return Undo
1505 <|> do reserved "qed"; return Qed
1506 <|> do reserved "abandon"; return Abandon
1507 <|> do lchar ':'; reserved "q"; return Abandon
1509 imp = do lchar '?'; return False
1510 <|> do lchar '_'; return True
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