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 Control.Monad.State
33type TokenParser a = PTok.TokenParser a
35type IParser = GenParser Char IState
37lexer :: TokenParser IState
40whiteSpace = PTok.whiteSpace lexer
41lexeme = PTok.lexeme lexer
42symbol = PTok.symbol lexer
43natural = PTok.natural lexer
44parens = PTok.parens lexer
46comma = PTok.comma lexer
47identifier = PTok.identifier lexer
48reserved = PTok.reserved lexer
49operator = PTok.operator lexer
50reservedOp = PTok.reservedOp lexer
51integer = PTok.integer lexer
52float = PTok.float lexer
53strlit = PTok.stringLiteral lexer
54chlit = PTok.charLiteral lexer
59loadModule :: FilePath -> Idris String
61 = idrisCatch (do i <- getIState
62 ibcsd <- valIBCSubDir i
63 ids <- allImportDirs i
64 fp <- liftIO $ findImport ids ibcsd f
65 if f `elem` imported i
66 then iLOG $ "Already read " ++ f
67 else do putIState (i { imported = f : imported i })
69 IDR fn -> loadSource False fn
70 LIDR fn -> loadSource True fn
72 idrisCatch (loadIBC fn)
73 (\c -> do iLOG $ fn ++ " failed " ++ show c
75 IDR sfn -> loadSource False sfn
76 LIDR sfn -> loadSource True sfn)
77 let (dir, fh) = splitFileName f
78 return (dropExtension fh))
79 (\e -> do let msg = show e
80 setErrLine (getErrLine msg)
84loadSource :: Bool -> FilePath -> Idris ()
86 = do iLOG ("Reading " ++ f)
88 let def_total = default_total i
89 file_in <- liftIO $ readFile f
90 file <- if lidr then tclift $ unlit f file_in else return file_in
91 (mname, modules, rest, pos) <- parseImports f file
93 putIState (i { default_access = Hidden })
94 mapM_ loadModule modules
95 clearIBC -- start a new .ibc file
96 mapM_ (addIBC . IBCImport) modules
97 ds' <- parseProg (defaultSyntax {syn_namespace = reverse mname })
99 let ds = namespaces mname ds'
100 logLvl 3 (dumpDecls ds)
102 logLvl 10 (show (toAlist (idris_implicits i)))
103 logLvl 3 (show (idris_infixes i))
104 -- Now add all the declarations to the context
106 when v $ iputStrLn $ "Type checking " ++ f
107 elabDecls toplevel ds
109 -- simplify every definition do give the totality checker
111 mapM_ (\n -> do logLvl 5 $ "Simplifying " ++ show n
112 updateContext (simplifyCasedef n))
113 (map snd (idris_totcheck i))
114 -- build size change graph from simplified definitions
115 iLOG "Totality checking"
117-- mapM_ buildSCG (idris_totcheck i)
118 mapM_ checkDeclTotality (idris_totcheck i)
119 iLOG ("Finished " ++ f)
120 ibcsd <- valIBCSubDir i
121 let ibc = ibcPathNoFallback ibcsd f
122 iLOG "Universe checking"
125 addHides (hide_list i)
128 idrisCatch (do writeIBC f ibc; clearIBC)
129 (\c -> return ()) -- failure is harmless
131 putIState (i { default_total = def_total,
135 namespaces [] ds = ds
136 namespaces (x:xs) ds = [PNamespace x (namespaces xs ds)]
138addHides :: [(Name, Maybe Accessibility)] -> Idris ()
139addHides xs = do i <- getIState
140 let defh = default_access i
141 let (hs, as) = partition isNothing xs
144 (map (\ (n, _) -> (n, defh)) hs ++
145 map (\ (n, Just a) -> (n, a)) as)
146 where isNothing (_, Nothing) = True
149 doHide (n, a) = do setAccessibility n a
150 addIBC (IBCAccess n a)
152parseExpr i = runParser (pFullExpr defaultSyntax) i "(input)"
153parseTac i = runParser (do t <- pTactic defaultSyntax
155 return t) i "(proof)"
157iShowError fname err = let ln = sourceLine (errorPos err)
158 clm = sourceColumn (errorPos err)
159 msg = map messageString (errorMessages err) in
160 fname ++ ":" ++ show ln ++ ":parse error"
161 ++ " at column " ++ show clm -- ++ " with error:\n\t" ++ show msg
163parseImports :: FilePath -> String -> Idris ([String], [String], String, SourcePos)
164parseImports fname input
166 case runParser (do whiteSpace
171 return ((mname, ps, rest, pos), i)) i fname input of
172 Left err -> fail (iShowError fname err)
173 Right (x, i) -> do put i
176pHeader :: IParser [String]
177pHeader = try (do reserved "module"; i <- identifier; option ';' (lchar ';')
178 return (parseName i))
180 where parseName x = case span (/='.') x of
182 (x, '.':y) -> x : parseName y
184pushIndent :: IParser ()
185pushIndent = do pos <- getPosition
187 setState (ist { indent_stack = sourceColumn pos :
190lastIndent :: IParser Int
191lastIndent = do ist <- getState
192 case indent_stack ist of
197indent = liftM sourceColumn getPosition
199popIndent :: IParser ()
200popIndent = do ist <- getState
201 let (x : xs) = indent_stack ist
202 setState (ist { indent_stack = xs })
204openBlock :: IParser ()
205openBlock = do lchar '{'
207 setState (ist { brace_stack = Nothing : brace_stack ist })
208 <|> do ist <- getState
210 setState (ist { brace_stack = Just lvl : brace_stack ist })
212closeBlock :: IParser ()
213closeBlock = do ist <- getState
214 bs <- case brace_stack ist of
215 Nothing : xs -> do lchar '}'
217 Just lvl : xs -> do i <- indent
219-- trace (show (take 10 inp, i, lvl)) $
220 if i >= lvl && take 1 inp /= ")"
221 then fail "Not end of block"
223 setState (ist { brace_stack = bs })
225pTerminator = do lchar ';'; popIndent
226 <|> do c <- indent; l <- lastIndent
229 else fail "Not a terminator"
231 if "}" `isPrefixOf` i || ")" `isPrefixOf` i
233 else fail "Not a terminator"
237 = do lchar '|'; return ()
238 <|> do c <- indent; l <- lastIndent
239 unless (c <= l) $ fail "Not a terminator"
243 = do lchar ';'; return ()
244 <|> do c <- indent; l <- lastIndent
245 unless (c <= l) $ fail "Not a terminator"
248 unless (h `elem` ["}", ")", "|"]) $ fail "Not a terminator"
251notEndApp = do c <- indent; l <- lastIndent
253 when (c <= l) $ fail "Terminator"
255notEndBlock = do ist <- getState
256 case brace_stack ist of
257 Just lvl : xs -> do i <- indent
259 when (i < lvl || ")" `isPrefixOf` inp) $ fail "End of block"
263pfc = do s <- getPosition
264 let (dir, file) = splitFileName (sourceName s)
268 return $ FC f (sourceLine s)
270pImport :: IParser String
271pImport = do reserved "import"; f <- identifier; option ';' (lchar ';')
276-- a program is a list of declarations, possibly with associated
277-- documentation strings
279parseProg :: SyntaxInfo -> FilePath -> String -> SourcePos ->
281parseProg syn fname input pos
283 case runParser (do setPosition pos
285 ps <- many (pDecl syn)
288 return (concat ps, i')) i fname input of
289 Left err -> fail (iShowError fname err)
290 Right (x, i) -> do put i
293-- Collect PClauses with the same function name
295collect :: [PDecl] -> [PDecl]
296collect (c@(PClauses _ o _ _) : ds)
297 = clauses (cname c) [] (c : ds)
298 where clauses j@(Just n) acc (PClauses fc _ _ [PClause fc' n' l ws r w] : ds)
299 | n == n' = clauses j (PClause fc' n' l ws r (collect w) : acc) ds
300 clauses j@(Just n) acc (PClauses fc _ _ [PWith fc' n' l ws r w] : ds)
301 | n == n' = clauses j (PWith fc' n' l ws r (collect w) : acc) ds
302 clauses (Just n) acc xs = PClauses (getfc c) o n (reverse acc) : collect xs
303 clauses Nothing acc (x:xs) = collect xs
304 clauses Nothing acc [] = []
306 cname (PClauses fc _ _ [PClause _ n _ _ _ _]) = Just n
307 cname (PClauses fc _ _ [PWith _ n _ _ _ _]) = Just n
308 cname (PClauses fc _ _ [PClauseR _ _ _ _]) = Nothing
309 cname (PClauses fc _ _ [PWithR _ _ _ _]) = Nothing
310 getfc (PClauses fc _ _ _) = fc
312collect (PParams f ns ps : ds) = PParams f ns (collect ps) : collect ds
313collect (PMutual f ms : ds) = PMutual f (collect ms) : collect ds
314collect (PNamespace ns ps : ds) = PNamespace ns (collect ps) : collect ds
315collect (PClass doc f s cs n ps ds : ds')
316 = PClass doc f s cs n ps (collect ds) : collect ds'
317collect (PInstance f s cs n ps t en ds : ds')
318 = PInstance f s cs n ps t en (collect ds) : collect ds'
319collect (d : ds) = d : collect ds
322pFullExpr :: SyntaxInfo -> IParser PTerm
324 = do x <- pExpr syn; eof;
326 return $ desugar syn i x
328pDecl :: SyntaxInfo -> IParser [PDecl]
329pDecl syn = do notEndBlock
334 let d' = fmap (desugar syn i) d
342 <|> do d <- pDSL syn; return [d]
344 <|> try (do reserved "import"; fp <- identifier
345 fail "imports must be at the top of file")
347pFunDecl :: SyntaxInfo -> IParser [PDecl]
349 = try (do notEndBlock
352 let d' = fmap (desugar syn i) d
355--------- Top Level Declarations ---------
357pDecl' :: SyntaxInfo -> IParser PDecl
362 <|> try (pRecord syn)
365pSyntaxDecl :: SyntaxInfo -> IParser PDecl
367 = do s <- pSyntaxRule syn
369 let rs = syntax_rules i
370 let ns = syntax_keywords i
371 let ibc = ibc_write i
372 let ks = map show (names s)
373 setState (i { syntax_rules = s : rs,
374 syntax_keywords = ks ++ ns,
375 ibc_write = IBCSyntax s : map IBCKeyword ks ++ ibc
378 return (PSyntax fc s)
380 names (Rule syms _ _) = mapMaybe ename syms
381 ename (Keyword n) = Just n
384pSyntaxRule :: SyntaxInfo -> IParser Syntax
387 sty <- option AnySyntax (do reserved "term"; return TermSyntax
388 <|> do reserved "pattern"; return PatternSyntax)
390 syms <- many1 pSynSym
391 when (all expr syms) $ fail "No keywords in syntax rule"
392 let ns = mapMaybe name syms
393 when (length ns /= length (nub ns))
394 $ fail "Repeated variable in syntax rule"
396 tm <- pExpr (impOK syn)
398 return (Rule (mkSimple syms) tm sty)
402 name (Expr n) = Just n
405 -- Can't parse two full expressions (i.e. expressions with application) in a row
406 -- so change the first to a simple expression
408 mkSimple (Expr e : es) = SimpleExpr e : mkSimple' es
409 mkSimple xs = mkSimple' xs
411 mkSimple' (Expr e : Expr e1 : es) = SimpleExpr e : mkSimple' (Expr e1 : es)
412 mkSimple' (e : es) = e : mkSimple' es
415pSynSym :: IParser SSymbol
416pSynSym = try (do lchar '['; n <- pName; lchar ']'
418 <|> try (do lchar '{'; n <- pName; lchar '}'
425pFunDecl' :: SyntaxInfo -> IParser PDecl
426pFunDecl' syn = try (do doc <- option "" (pDocComment '|')
427 -- trace ("Doc: " ++ show doc) $
431 let initOpts = if default_total ist
434 opts <- pFnOpts initOpts
435 acc <- pAccessibility
436 opts' <- pFnOpts opts
438 let n = expandNS syn n_in
439 ty <- pTSig (impOK syn)
442-- ty' <- implicit syn n ty
444 return (PTy doc syn fc opts' n ty))
445 <|> try (pPattern syn)
448pUsing :: SyntaxInfo -> IParser [PDecl]
450 do reserved "using"; lchar '('; ns <- tyDeclList syn; lchar ')'
452 let uvars = using syn
453 ds <- many1 (pDecl (syn { using = uvars ++ ns }))
457pParams :: SyntaxInfo -> IParser [PDecl]
459 do reserved "parameters"; lchar '('; ns <- tyDeclList syn; lchar ')'
461 let pvars = syn_params syn
462 ds <- many1 (pDecl syn { syn_params = pvars ++ ns })
465 return [PParams fc ns (concat ds)]
467pMutual :: SyntaxInfo -> IParser [PDecl]
471 let pvars = syn_params syn
472 ds <- many1 (pDecl syn)
475 return [PMutual fc (concat ds)]
477pNamespace :: SyntaxInfo -> IParser [PDecl]
479 do reserved "namespace"; n <- identifier;
481 ds <- many1 (pDecl syn { syn_namespace = n : syn_namespace syn })
483 return [PNamespace n (concat ds)]
485--------- Fixity ---------
487pFixity :: IParser PDecl
488pFixity = do pushIndent
489 f <- fixity; i <- natural; ops <- sepBy1 operator (lchar ',')
491 let prec = fromInteger i
493 let infixes = idris_infixes istate
494 let fs = map (Fix (f prec)) ops
495 let redecl = map (alreadyDeclared infixes) fs
496 if False `notElem` map checkValidity redecl
497 then do setState (istate { idris_infixes = nub $ sort (fs ++ infixes)
498 , ibc_write = map IBCFix fs ++ ibc_write istate
501 return (PFix fc (f prec) ops)
502 else fail "Illegal redeclaration of fixity"
503 where alreadyDeclared :: [FixDecl] -> FixDecl -> (FixDecl, [FixDecl])
504 alreadyDeclared fs f = (f, filter ((extractName f ==) . extractName) fs)
506 checkValidity :: (FixDecl, [FixDecl]) -> Bool
507 checkValidity (f, fs) = all (== f) fs
509 extractName :: FixDecl -> String
510 extractName (Fix _ n) = n
512fixity :: IParser (Int -> Fixity)
513fixity = try (do reserved "infixl"; return Infixl)
514 <|> try (do reserved "infixr"; return Infixr)
515 <|> try (do reserved "infix"; return InfixN)
516 <|> try (do reserved "prefix"; return PrefixN)
518--------- Type classes ---------
520pClass :: SyntaxInfo -> IParser [PDecl]
521pClass syn = do doc <- option "" (pDocComment '|')
522 acc <- pAccessibility
523 reserved "class"; fc <- pfc; cons <- pConstList syn; n_in <- pName
524 let n = expandNS syn n_in
526 reserved "where"; openBlock
527 ds <- many $ pFunDecl syn
529 let allDs = concat ds
530 accData acc n (concatMap declared allDs)
531 return [PClass doc syn fc cons n cs allDs]
533 carg = do lchar '('; i <- pName; lchar ':'; ty <- pExpr syn; lchar ')'
538pInstance :: SyntaxInfo -> IParser [PDecl]
539pInstance syn = do reserved "instance"; fc <- pfc
541 (do lchar '['; n_in <- pfName; lchar ']'
542 let n = expandNS syn n_in
546 args <- many1 (pSimpleExpr syn)
547 let sc = PApp fc (PRef fc cn) (map pexp args)
548 let t = bindList (PPi constraint) (map (\x -> (MN 0 "c", x)) cs) sc
549 reserved "where"; openBlock
550 ds <- many $ pFunDecl syn
552 return [PInstance syn fc cs cn args t en (concat ds)]
554--------- Expressions ---------
556pExpr syn = do i <- getState
557 buildExpressionParser (table (idris_infixes i)) (pExpr' syn)
559pExpr' :: SyntaxInfo -> IParser PTerm
564pExtExpr :: SyntaxInfo -> IParser PTerm
565pExtExpr syn = do i <- getState
566 pExtensions syn (syntax_rules i)
568pSimpleExtExpr :: SyntaxInfo -> IParser PTerm
569pSimpleExtExpr syn = do i <- getState
570 pExtensions syn (filter simple (syntax_rules i))
572 simple (Rule (Expr x:xs) _ _) = False
573 simple (Rule (SimpleExpr x:xs) _ _) = False
574 simple (Rule [Keyword _] _ _) = True
575 simple (Rule [Symbol _] _ _) = True
576 simple (Rule (_:xs) _ _) = case last xs of
585 <|> try (pSimpleExpr syn)
590 <|> pComprehension syn
592pExtensions :: SyntaxInfo -> [Syntax] -> IParser PTerm
593pExtensions syn rules = choice (map (try . pExt syn) (filter valid rules))
595 valid (Rule _ _ AnySyntax) = True
596 valid (Rule _ _ PatternSyntax) = inPattern syn
597 valid (Rule _ _ TermSyntax) = not (inPattern syn)
600data SynMatch = SynTm PTerm | SynBind Name
602pExt :: SyntaxInfo -> Syntax -> IParser PTerm
603pExt syn (Rule ssym ptm _)
604 = do smap <- mapM pSymbol ssym
605 let ns = mapMaybe id smap
606 return (update ns ptm) -- updated with smap
608 pSymbol (Keyword n) = do reserved (show n); return Nothing
609 pSymbol (Expr n) = do tm <- pExpr syn
610 return $ Just (n, SynTm tm)
611 pSymbol (SimpleExpr n) = do tm <- pSimpleExpr syn
612 return $ Just (n, SynTm tm)
613 pSymbol (Binding n) = do b <- pName
614 return $ Just (n, SynBind b)
615 pSymbol (Symbol s) = do symbol s
618 dropn n ((x,t) : xs) | n == x = xs
619 | otherwise = (x,t):dropn n xs
621 updateB ns n = case lookup n ns of
622 Just (SynBind t) -> t
625 update ns (PRef fc n) = case lookup n ns of
628 update ns (PLam n ty sc) = PLam (updateB ns n) (update ns ty) (update (dropn n ns) sc)
629 update ns (PPi p n ty sc) = PPi p (updateB ns n) (update ns ty) (update (dropn n ns) sc)
630 update ns (PLet n ty val sc) = PLet (updateB ns n) (update ns ty) (update ns val)
631 (update (dropn n ns) sc)
632 update ns (PApp fc t args) = PApp fc (update ns t) (map (fmap (update ns)) args)
633 update ns (PCase fc c opts) = PCase fc (update ns c) (map (pmap (update ns)) opts)
634 update ns (PPair fc l r) = PPair fc (update ns l) (update ns r)
635 update ns (PDPair fc l t r) = PDPair fc (update ns l) (update ns t) (update ns r)
636 update ns (PAlternative a as) = PAlternative a (map (update ns) as)
637 update ns (PHidden t) = PHidden (update ns t)
638 update ns (PDoBlock ds) = PDoBlock $ upd ns ds
639 where upd ns (DoExp fc t : ds) = DoExp fc (update ns t) : upd ns ds
640 upd ns (DoBind fc n t : ds) = DoBind fc n (update ns t) : upd (dropn n ns) ds
641 upd ns (DoLet fc n ty t : ds) = DoLet fc n (update ns ty) (update ns t)
642 : upd (dropn n ns) ds
643 upd ns (DoBindP fc i t : ds) = DoBindP fc (update ns i) (update ns t)
645 upd ns (DoLetP fc i t : ds) = DoLetP fc (update ns i) (update ns t)
649pName = do i <- getState
650 iName (syntax_keywords i)
651 <|> do reserved "instance"
653 UN n <- iName (syntax_keywords i)
656-- Parser for an operator in function position, i.e. enclosed by `()', with an
657-- optional namespace.
658pOpFront = maybeWithNS pOpFrontNoNS False []
659 where pOpFrontNoNS = do lchar '('; o <- operator; lchar ')'; return o
664pTotality :: IParser Bool
666 = do reserved "total"; return True
667 <|> do reserved "partial"; return False
669pAccessibility' :: IParser Accessibility
671 = do reserved "public"; return Public
672 <|> do reserved "abstract"; return Frozen
673 <|> do reserved "private"; return Hidden
675pAccessibility :: IParser (Maybe Accessibility)
677 = do acc <- pAccessibility'; return (Just acc)
680pFnOpts :: [FnOpt] -> IParser [FnOpt]
682 = do reserved "total"; pFnOpts (TotalFn : opts)
683 <|> do reserved "partial"; pFnOpts (PartialFn : (opts \\ [TotalFn]))
684 <|> try (do lchar '%'; reserved "export"; c <- strlit;
685 pFnOpts (CExport c : opts))
686 <|> do lchar '%'; reserved "assert_total"; pFnOpts (AssertTotal : opts)
687 <|> do lchar '%'; reserved "specialise";
688 lchar '['; ns <- sepBy pfName (lchar ','); lchar ']'
689 pFnOpts (Specialise ns : opts)
692addAcc :: Name -> Maybe Accessibility -> IParser ()
693addAcc n a = do i <- getState
694 setState (i { hide_list = (n, a) : hide_list i })
697 reserved "case"; fc <- pfc; scr <- pExpr syn; reserved "of";
700 opts <- many1 (do notEndBlock
703 return x) -- sepBy1 (pCaseOpt syn) (lchar '|')
706 return (PCase fc scr opts)
709 reserved "proof"; lchar '{'
710 ts <- endBy (pTactic syn) (lchar ';')
715 reserved "tactics"; lchar '{'
716 ts <- endBy (pTactic syn) (lchar ';')
721 try (do symbol "!["; t <- pTerm; lchar ']'; return $ PQuote t)
722 <|> do lchar '?'; x <- pName; return (PMetavar x)
723 <|> do reserved "refl"; fc <- pfc;
724 tm <- option Placeholder (do lchar '{'; t <- pExpr syn; lchar '}';
727-- <|> do reserved "return"; fc <- pfc; return (PReturn fc)
731 <|> try (do x <- pfName
737 <|> try (do lchar '('
738 bracketed (noImp syn))
739 <|> try (do c <- pConstant
741 return (modifyConst syn fc (PConstant c)))
742 <|> do reserved "Set"; return PSet
743 <|> try (do symbol "()"
746 <|> try (do symbol "_|_"
749 <|> do lchar '_'; return Placeholder
750 <|> pSimpleExtExpr syn
754 <|> try (do e <- pExpr syn; lchar ')'; return e)
755-- <|> try (do reserved "typed"
756-- e <- pExpr syn; symbol ":"; t <- pExpr syn; lchar ')'
757-- return (PTyped e t))
758 <|> try (do fc <- pfc; o <- operator; e <- pExpr syn; lchar ')'
759 return $ PLam (MN 1000 "ARG") Placeholder
760 (PApp fc (PRef fc (UN o)) [pexp (PRef fc (MN 1000 "ARG")),
762 <|> try (do fc <- pfc; e <- pSimpleExpr syn; o <- operator; lchar ')'
763 return $ PLam (MN 1000 "ARG") Placeholder
764 (PApp fc (PRef fc (UN o)) [pexp e,
765 pexp (PRef fc (MN 1000 "ARG"))]))
767pCaseOpt :: SyntaxInfo -> IParser (PTerm, PTerm)
768pCaseOpt syn = do lhs <- pExpr syn; symbol "=>"; rhs <- pExpr syn
771modifyConst :: SyntaxInfo -> FC -> PTerm -> PTerm
772modifyConst syn fc (PConstant (I x))
773 | not (inPattern syn)
774 = PApp fc (PRef fc (UN "fromInteger")) [pexp (PConstant (I x))]
775 | otherwise = PAlternative False
776 [PConstant (I x), PConstant (BI (toEnum x))]
777modifyConst syn fc x = x
779pList syn = do lchar '['; fc <- pfc; xs <- sepBy (pExpr syn) (lchar ','); lchar ']'
780 return (mkList fc xs)
782 mkList fc [] = PRef fc (UN "Nil")
783 mkList fc (x : xs) = PApp fc (PRef fc (UN "::")) [pexp x, pexp (mkList fc xs)]
785pPair syn = try (do l <- pExpr syn
790 [Left r] -> return (PPair fc l r)
791 [Right r] -> return (PDPair fc l Placeholder r))
792 <|> try (do x <- ntuple
795 <|> do ln <- pName; lchar ':'
801 return (PDPair fc (PRef fc ln) lty r)
803 restTuple = do lchar ')'; return []
808 <|> do reservedOp "**"
812 ntuple = try (do l <- pExpr syn; fc <- pfc; lchar ','
814 return (PPair fc l rest))
815 <|> (do l <- pExpr syn; fc <- pfc; lchar ','
817 return (PPair fc l r))
819pAlt syn = do symbol "(|"; alts <- sepBy1 (pExpr' syn) (lchar ','); symbol "|)"
820 return (PAlternative False alts)
828pApp syn = do f <- pSimpleExpr syn
830 args <- many1 (do notEndApp
833 return (dslify i $ PApp fc f args)
835 dslify i (PApp fc (PRef _ f) [a])
836 | [d] <- lookupCtxt Nothing f (idris_dsls i)
837 = desugar (syn { dsl_info = d }) i (getTm a)
840pArg :: SyntaxInfo -> IParser PArg
841pArg syn = try (pImplicitArg syn)
842 <|> try (pConstraintArg syn)
843 <|> do e <- pSimpleExpr syn
846pImplicitArg syn = do lchar '{'
849 v <- option (PRef fc n) (do lchar '='
854pConstraintArg syn = do symbol "@{"
860 = do reserved "record"
862 fields <- sepBy1 pFieldSet (lchar ',')
865 rec <- option Nothing (do e <- pSimpleExpr syn
869 return (PLam (MN 0 "fldx") Placeholder
870 (applyAll fc fields (PRef fc (MN 0 "fldx"))))
871 Just v -> return (applyAll fc fields v)
872 where pFieldSet = do n <- pfName
877 applyAll fc ((n, e) : es) x
878 = applyAll fc es (PApp fc (PRef fc (mkSet n)) [pexp e, pexp x])
880mkSet (UN n) = UN ("set_" ++ n)
881mkSet (MN 0 n) = MN 0 ("set_" ++ n)
882mkSet (NS n s) = NS (mkSet n) s
884noImp syn = syn { implicitAllowed = False }
885impOK syn = syn { implicitAllowed = True }
887pTSig syn = do lchar ':'
888 cs <- if implicitAllowed syn then pConstList syn else return []
890 return (bindList (PPi constraint) (map (\x -> (MN 0 "c", x)) cs) sc)
892pLambda syn = do lchar '\\'
893 try (do xt <- tyOptDeclList syn
896 return (bindList PLam xt sc)
897 <|> (do ps <- sepBy (do fc <- pfc
899 return (fc, e)) (lchar ',')
902 return (pmList (zip [0..] ps) sc)))
903 where pmList [] sc = sc
904 pmList ((i, (fc, x)) : xs) sc
905 = PLam (MN i "lamp") Placeholder
906 (PCase fc (PRef fc (MN i "lamp"))
909pLet syn = try (do reserved "let"; n <- pName;
910 ty <- option Placeholder (do lchar ':'; pExpr' syn)
913 reserved "in"; sc <- pExpr syn
914 return (PLet n ty v sc))
915 <|> (do reserved "let"; fc <- pfc; pat <- pExpr' (syn { inPattern = True } )
916 symbol "="; v <- pExpr syn
917 reserved "in"; sc <- pExpr syn
918 return (PCase fc v [(pat, sc)]))
921 try (do lazy <- option False (do lchar '|'; return True)
923 lchar '('; xt <- tyDeclList syn; lchar ')'
924 doc <- option "" (pDocComment '^')
927 return (bindList (PPi (Exp lazy st doc)) xt sc))
928 <|> try (if implicitAllowed syn
929 then do lazy <- option False (do lchar '|'
937 return (bindList (PPi (Imp lazy st "")) xt sc)
938 else fail "No implicit arguments allowed here")
939 <|> try (do lchar '{'
945 return (bindList (PPi
946 (TacImp False Dynamic (PTactics [Trivial]) "")) xt sc))
947 <|> try (do lchar '{'
949 script <- pSimpleExpr syn
954 return (bindList (PPi (TacImp False Dynamic script "")) xt sc))
955 <|> do --lazy <- option False (do lchar '|'; return True)
962 return (PPi (Exp False Static "") (MN 42 "__pi_arg") t sc)
964pConstList :: SyntaxInfo -> IParser [PTerm]
965pConstList syn = try (do lchar '('
966 tys <- sepBy1 (pExpr' (noImp syn)) (lchar ',')
970 <|> try (do t <- pExpr (noImp syn)
975tyDeclList syn = try (sepBy1 (do x <- pfName
976 t <- pTSig (noImp syn)
979 <|> do ns <- sepBy1 pName (lchar ',')
980 t <- pTSig (noImp syn)
981 return (map (\x -> (x, t)) ns)
983tyOptDeclList syn = sepBy1 (do x <- pfName;
984 t <- option Placeholder (do lchar ':'
990bindList b ((n, t):bs) sc = b n t (bindList b bs sc)
997 qs <- sepBy1 (pDo syn) (lchar ',')
999 return (PDoBlock (map addGuard qs ++
1000 [DoExp fc (PApp fc (PRef fc (UN "return"))
1002 where addGuard (DoExp fc e) = DoExp fc (PApp fc (PRef fc (UN "guard"))
1010 ds <- many1 (do notEndBlock
1016 return (PDoBlock ds)
1019 = try (do reserved "let"
1021 ty <- option Placeholder (do lchar ':'
1026 return (DoLet fc i ty e))
1027 <|> try (do reserved "let"
1032 return (DoLetP fc i sc))
1033 <|> try (do i <- pName
1037 return (DoBind fc i e))
1038 <|> try (do i <- pExpr' syn
1042 return (DoBindP fc i e))
1043 <|> try (do e <- pExpr syn
1045 return (DoExp fc e))
1052 return (PIdiom fc e)
1054pConstant :: IParser Const
1055pConstant = do reserved "Integer";return BIType
1056 <|> do reserved "Int"; return IType
1057 <|> do reserved "Char"; return ChType
1058 <|> do reserved "Float"; return FlType
1059 <|> do reserved "String"; return StrType
1060 <|> do reserved "Ptr"; return PtrType
1061 <|> try (do f <- float; return $ Fl f)
1062-- <|> try (do i <- natural; lchar 'L'; return $ BI i)
1063 <|> try (do i <- natural; return $ I (fromInteger i))
1064 <|> try (do s <- strlit; return $ Str s)
1065 <|> try (do c <- chlit; return $ Ch c)
1067pStatic :: IParser Static
1068pStatic = do lchar '['
1075 = [[prefix "-" (\fc x -> PApp fc (PRef fc (UN "-"))
1076 [pexp (PApp fc (PRef fc (UN "fromInteger")) [pexp (PConstant (I 0))]), pexp x])]]
1077 ++ toTable (reverse fixes) ++
1079 [binary "=" PEq AssocLeft],
1080 [binary "->" (\fc x y -> PPi expl (MN 42 "__pi_arg") x y) AssocRight]]
1082toTable fs = map (map toBin)
1083 (groupBy (\ (Fix x _) (Fix y _) -> prec x == prec y) fs)
1084 where toBin (Fix (PrefixN _) op) = prefix op
1085 (\fc x -> PApp fc (PRef fc (UN op)) [pexp x])
1087 = binary op (\fc x y -> PApp fc (PRef fc (UN op)) [pexp x,pexp y]) (assoc f)
1088 assoc (Infixl _) = AssocLeft
1089 assoc (Infixr _) = AssocRight
1090 assoc (InfixN _) = AssocNone
1092binary name f = Infix (do reservedOp name
1094 doc <- option "" (pDocComment '^')
1096prefix name f = Prefix (do reservedOp name
1099backtick = Infix (do lchar '`'; n <- pfName
1102 return (\x y -> PApp fc (PRef fc n) [pexp x, pexp y])) AssocNone
1104--------- Data declarations ---------
1106-- (works for classes too - 'abstract' means the data/class is visible but members not)
1107accData :: Maybe Accessibility -> Name -> [Name] -> IParser ()
1108accData (Just Frozen) n ns = do addAcc n (Just Frozen)
1109 mapM_ (\n -> addAcc n (Just Hidden)) ns
1110accData a n ns = do addAcc n a
1111 mapM_ (`addAcc` a) ns
1113pRecord :: SyntaxInfo -> IParser PDecl
1114pRecord syn = do acc <- pAccessibility
1118 ty <- pTSig (impOK syn)
1119 let tyn = expandNS syn tyn_in
1123 (cdoc, cn, cty, _) <- pConstructor syn
1127 accData acc tyn [cn]
1128 let rsyn = syn { syn_namespace = show (nsroot tyn) :
1130 let fns = getRecNames rsyn cty
1131 mapM_ (\n -> addAcc n acc) fns
1132 return $ PRecord "" rsyn fc tyn ty cdoc cn cty
1134 getRecNames syn (PPi _ n _ sc) = [expandNS syn n, expandNS syn (mkSet n)]
1135 ++ getRecNames syn sc
1136 getRecNames _ _ = []
1138 toFreeze (Just Frozen) = Just Hidden
1141pDataI = do reserved "data"; return False
1142 <|> do reserved "codata"; return True
1144pData :: SyntaxInfo -> IParser PDecl
1145pData syn = try (do doc <- option "" (pDocComment '|')
1146 acc <- pAccessibility
1150 ty <- pTSig (impOK syn)
1151 let tyn = expandNS syn tyn_in
1152 option (PData doc syn fc co (PLaterdecl tyn ty)) (do
1156 cons <- many (do notEndBlock
1157 c <- pConstructor syn
1159 return c) -- (lchar '|')
1162 accData acc tyn (map (\ (_, n, _, _) -> n) cons)
1163 return $ PData doc syn fc co (PDatadecl tyn ty cons)))
1164 <|> try (do doc <- option "" (pDocComment '|')
1166 acc <- pAccessibility
1171 let ty = bindArgs (map (const PSet) args) PSet
1172 let tyn = expandNS syn tyn_in
1173 option (PData doc syn fc co (PLaterdecl tyn ty)) (do
1175 cons <- sepBy1 (pSimpleCon syn) (lchar '|')
1177 let conty = mkPApp fc (PRef fc tyn) (map (PRef fc) args)
1178 cons' <- mapM (\ (doc, x, cargs, cfc) ->
1179 do let cty = bindArgs cargs conty
1180 return (doc, x, cty, cfc)) cons
1181 accData acc tyn (map (\ (_, n, _, _) -> n) cons')
1182 return $ PData doc syn fc co (PDatadecl tyn ty cons')))
1185 mkPApp fc t xs = PApp fc t (map pexp xs)
1187bindArgs :: [PTerm] -> PTerm -> PTerm
1188bindArgs xs t = foldr (PPi expl (MN 0 "t")) t xs
1190pConstructor :: SyntaxInfo -> IParser (String, Name, PTerm, FC)
1192 = do doc <- option "" (pDocComment '|')
1193 cn_in <- pfName; fc <- pfc
1194 let cn = expandNS syn cn_in
1195 ty <- pTSig (impOK syn)
1196-- ty' <- implicit syn cn ty
1197 return (doc, cn, ty, fc)
1200pSimpleCon :: SyntaxInfo -> IParser (String, Name, [PTerm], FC)
1202 = do cn_in <- pfName
1203 let cn = expandNS syn cn_in
1205 args <- many (do notEndApp
1207 doc <- option "" (pDocComment '^')
1208 return (doc, cn, args, fc)
1210--------- DSL syntax overloading ---------
1212pDSL :: SyntaxInfo -> IParser PDecl
1213pDSL syn = do reserved "dsl"
1217 bs <- many1 (do notEndBlock
1221 popIndent; closeBlock
1222 let dsl = mkDSL bs (dsl_info syn)
1225 setState (i { idris_dsls = addDef n dsl (idris_dsls i) })
1227 where mkDSL bs dsl = let var = lookup "variable" bs
1228 first = lookup "index_first" bs
1229 next = lookup "index_next" bs
1230 leto = lookup "let" bs
1231 lambda = lookup "lambda" bs in
1232 initDSL { dsl_var = var,
1233 index_first = first,
1235 dsl_lambda = lambda,
1238checkDSL :: DSL -> IParser ()
1239checkDSL dsl = return ()
1241pOverload :: SyntaxInfo -> IParser (String, PTerm)
1242pOverload syn = do o <- identifier <|> do reserved "let"
1244 if o `notElem` overloadable
1245 then fail $ show o ++ " is not an overloading"
1250 where overloadable = ["let","lambda","index_first","index_next","variable"]
1252--------- Pattern match clauses ---------
1254pPattern :: SyntaxInfo -> IParser PDecl
1255pPattern syn = do fc <- pfc
1256 clause <- pClause syn
1257 return (PClauses fc [] (MN 2 "_") [clause]) -- collect together later
1259pCAF :: SyntaxInfo -> IParser PDecl
1260pCAF syn = do reserved "let"
1261 n_in <- pfName; let n = expandNS syn n_in
1266 return (PCAF fc n t)
1268pArgExpr syn = let syn' = syn { inPattern = True } in
1269 try (pHSimpleExpr syn') <|> pSimpleExtExpr syn'
1271pRHS :: SyntaxInfo -> Name -> IParser PTerm
1272pRHS syn n = do lchar '='; pExpr syn
1273 <|> do symbol "?="; rhs <- pExpr syn;
1275 <|> do reserved "impossible"; return PImpossible
1276 where mkN (UN x) = UN (x++"_lemma_1")
1277 mkN (NS x n) = NS (mkN x) n
1280 addLet (PLet n ty val rhs) = PLet n ty val (addLet rhs)
1281 addLet (PCase fc t cs) = PCase fc t (map addLetC cs)
1282 where addLetC (l, r) = (l, addLet r)
1283 addLet rhs = (PLet (UN "value") Placeholder rhs (PMetavar n'))
1285pClause :: SyntaxInfo -> IParser PClause
1287 = try (do pushIndent
1288 n_in <- pfName; let n = expandNS syn n_in
1289 cargs <- many (pConstraintArg syn)
1290 iargs <- many (pImplicitArg (syn { inPattern = True } ))
1292 args <- many (pArgExpr syn)
1293 wargs <- many (pWExpr syn)
1296 let ctxt = tt_ctxt ist
1297 let wsyn = syn { syn_namespace = [] }
1298 (wheres, nmap) <- choice [do x <- pWhereblock n wsyn
1303 let capp = PApp fc (PRef fc n)
1304 (iargs ++ cargs ++ map pexp args)
1306 setState (ist { lastParse = Just n })
1307 return $ PClause fc n capp wargs rhs wheres)
1308 <|> try (do pushIndent
1309 wargs <- many1 (pWExpr syn)
1311 n <- case lastParse ist of
1313 Nothing -> fail "Invalid clause"
1316 let ctxt = tt_ctxt ist
1317 let wsyn = syn { syn_namespace = [] }
1318 (wheres, nmap) <- choice [do x <- pWhereblock n wsyn
1323 return $ PClauseR fc wargs rhs wheres)
1325 <|> try (do pushIndent
1326 n_in <- pfName; let n = expandNS syn n_in
1327 cargs <- many (pConstraintArg syn)
1328 iargs <- many (pImplicitArg (syn { inPattern = True } ))
1330 args <- many (pArgExpr syn)
1331 wargs <- many (pWExpr syn)
1332 let capp = PApp fc (PRef fc n)
1333 (iargs ++ cargs ++ map pexp args)
1335 setState (ist { lastParse = Just n })
1337 wval <- pSimpleExpr syn
1339 ds <- many1 $ pFunDecl syn
1340 let withs = map (fillLHSD n capp wargs) $ concat ds
1343 return $ PWith fc n capp wargs wval withs)
1345 <|> try (do wargs <- many1 (pWExpr syn)
1348 wval <- pSimpleExpr syn
1350 ds <- many1 $ pFunDecl syn
1351 let withs = concat ds
1353 return $ PWithR fc wargs wval withs)
1358 let n = expandNS syn (UN op)
1361 wargs <- many (pWExpr syn)
1363 let wsyn = syn { syn_namespace = [] }
1364 (wheres, nmap) <- choice [do x <- pWhereblock n wsyn
1370 let capp = PApp fc (PRef fc n) [pexp l, pexp r]
1371 setState (ist { lastParse = Just n })
1372 return $ PClause fc n capp wargs rhs wheres
1374 <|> do l <- pArgExpr syn
1376 let n = expandNS syn (UN op)
1379 wargs <- many (pWExpr syn)
1381 wval <- pSimpleExpr syn
1383 ds <- many1 $ pFunDecl syn
1386 let capp = PApp fc (PRef fc n) [pexp l, pexp r]
1387 let withs = map (fillLHSD n capp wargs) $ concat ds
1388 setState (ist { lastParse = Just n })
1389 return $ PWith fc n capp wargs wval withs
1391 fillLHS n capp owargs (PClauseR fc wargs v ws)
1392 = PClause fc n capp (owargs ++ wargs) v ws
1393 fillLHS n capp owargs (PWithR fc wargs v ws)
1394 = PWith fc n capp (owargs ++ wargs) v
1395 (map (fillLHSD n capp (owargs ++ wargs)) ws)
1398 fillLHSD n c a (PClauses fc o fn cs) = PClauses fc o fn (map (fillLHS n c a) cs)
1399 fillLHSD n c a x = x
1401pWExpr :: SyntaxInfo -> IParser PTerm
1402pWExpr syn = do lchar '|'
1405pWhereblock :: Name -> SyntaxInfo -> IParser ([PDecl], [(Name, Name)])
1407 = do reserved "where"; openBlock
1408 ds <- many1 $ pDecl syn
1409 let dns = concatMap (concatMap declared) ds
1411 return (concat ds, map (\x -> (x, decoration syn x)) dns)
1413pDirective :: IParser [PDecl]
1414pDirective = try (do lchar '%'; reserved "lib"; lib <- strlit;
1415 return [PDirective (do addLib lib
1416 addIBC (IBCLib lib))])
1417 <|> try (do lchar '%'; reserved "link"; obj <- strlit;
1418 return [PDirective (do datadir <- liftIO getDataDir
1419 o <- liftIO $ findInPath [".", datadir] obj
1422 <|> try (do lchar '%'; reserved "include"; hdr <- strlit;
1423 return [PDirective (do addHdr hdr
1424 addIBC (IBCHeader hdr))])
1425 <|> try (do lchar '%'; reserved "hide"; n <- iName []
1426 return [PDirective (do setAccessibility n Hidden
1427 addIBC (IBCAccess n Hidden))])
1428 <|> try (do lchar '%'; reserved "freeze"; n <- iName []
1429 return [PDirective (do setAccessibility n Frozen
1430 addIBC (IBCAccess n Frozen))])
1431 <|> try (do lchar '%'; reserved "access"; acc <- pAccessibility'
1432 return [PDirective (do i <- getIState
1433 putIState (i { default_access = acc }))])
1434 <|> try (do lchar '%'; reserved "default"; tot <- pTotality
1436 setState (i { default_total = tot } )
1437 return [PDirective (do i <- getIState
1438 putIState (i { default_total = tot }))])
1439 <|> try (do lchar '%'; reserved "logging"; i <- natural;
1440 return [PDirective (setLogLevel (fromInteger i))])
1442pTactic :: SyntaxInfo -> IParser PTactic
1443pTactic syn = do reserved "intro"; ns <- sepBy pName (lchar ',')
1445 <|> do reserved "intros"; return Intros
1446 <|> try (do reserved "refine"; n <- pName
1448 return $ Refine n imps)
1449 <|> do reserved "refine"; n <- pName
1451 return $ Refine n []
1452 <|> do reserved "rewrite"; t <- pExpr syn;
1454 return $ Rewrite (desugar syn i t)
1455 <|> do reserved "let"; n <- pName; lchar '=';
1458 return $ LetTac n (desugar syn i t)
1459 <|> do reserved "focus"; n <- pName
1461 <|> do reserved "exact"; t <- pExpr syn;
1463 return $ Exact (desugar syn i t)
1464 <|> do reserved "try"; t <- pTactic syn;
1474 <|> do reserved "compute"; return Compute
1475 <|> do reserved "trivial"; return Trivial
1476 <|> do reserved "solve"; return Solve
1477 <|> do reserved "attack"; return Attack
1478 <|> do reserved "state"; return ProofState
1479 <|> do reserved "term"; return ProofTerm
1480 <|> do reserved "undo"; return Undo
1481 <|> do reserved "qed"; return Qed
1482 <|> do reserved "abandon"; return Abandon
1483 <|> do lchar ':'; reserved "q"; return Abandon
1485 imp = do lchar '?'; return False
1486 <|> 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