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
38lexer = PTok.makeTokenParser idrisDef
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)
87 file_in <- liftIO $ readFile f
88 file <- if lidr then tclift $ unlit f file_in else return file_in
89 (mname, modules, rest, pos) <- parseImports f file
91 putIState (i { default_access = Hidden })
92 mapM_ loadModule modules
93 clearIBC -- start a new .ibc file
94 mapM_ (addIBC . IBCImport) modules
95 ds' <- parseProg (defaultSyntax {syn_namespace = reverse mname })
97 let ds = namespaces mname ds'
98 logLvl 3 (dumpDecls ds)
100 logLvl 10 (show (toAlist (idris_implicits i)))
101 logLvl 3 (show (idris_infixes i))
102 -- Now add all the declarations to the context
104 when v $ iputStrLn $ "Type checking " ++ f
105 mapM_ (elabDecl toplevel) ds
107 mapM_ checkDeclTotality (idris_totcheck i)
108 iLOG ("Finished " ++ f)
109 ibcsd <- valIBCSubDir i
110 let ibc = ibcPathNoFallback ibcsd f
111 iLOG "Universe checking"
114 addHides (hide_list i)
117 idrisCatch (do writeIBC f ibc; clearIBC)
118 (\c -> return ()) -- failure is harmless
120 putIState (i { hide_list = [] })
123 namespaces [] ds = ds
124 namespaces (x:xs) ds = [PNamespace x (namespaces xs ds)]
126addHides :: [(Name, Maybe Accessibility)] -> Idris ()
127addHides xs = do i <- getIState
128 let defh = default_access i
129 let (hs, as) = partition isNothing xs
132 (map (\ (n, _) -> (n, defh)) hs ++
133 map (\ (n, Just a) -> (n, a)) as)
134 where isNothing (_, Nothing) = True
137 doHide (n, a) = do setAccessibility n a
138 addIBC (IBCAccess n a)
140parseExpr i = runParser (pFullExpr defaultSyntax) i "(input)"
141parseTac i = runParser (do t <- pTactic defaultSyntax
143 return t) i "(proof)"
145iShowError fname err = let ln = sourceLine (errorPos err)
146 clm = sourceColumn (errorPos err)
147 msg = map messageString (errorMessages err) in
148 fname ++ ":" ++ show ln ++ ":parse error"
149 ++ " at column " ++ show clm -- ++ " with error:\n\t" ++ show msg
151parseImports :: FilePath -> String -> Idris ([String], [String], String, SourcePos)
152parseImports fname input
154 case runParser (do whiteSpace
159 return ((mname, ps, rest, pos), i)) i fname input of
160 Left err -> fail (iShowError fname err)
161 Right (x, i) -> do put i
164pHeader :: IParser [String]
165pHeader = try (do reserved "module"; i <- identifier; option ';' (lchar ';')
166 return (parseName i))
168 where parseName x = case span (/='.') x of
170 (x, '.':y) -> x : parseName y
172pushIndent :: IParser ()
173pushIndent = do pos <- getPosition
175 setState (ist { indent_stack = sourceColumn pos :
178lastIndent :: IParser Int
179lastIndent = do ist <- getState
180 case indent_stack ist of
185indent = liftM sourceColumn getPosition
187popIndent :: IParser ()
188popIndent = do ist <- getState
189 let (x : xs) = indent_stack ist
190 setState (ist { indent_stack = xs })
192openBlock :: IParser ()
193openBlock = do lchar '{'
195 setState (ist { brace_stack = Nothing : brace_stack ist })
196 <|> do ist <- getState
198 setState (ist { brace_stack = Just lvl : brace_stack ist })
200closeBlock :: IParser ()
201closeBlock = do ist <- getState
202 bs <- case brace_stack ist of
203 Nothing : xs -> do lchar '}'
205 Just lvl : xs -> do i <- indent
207-- trace (show (take 10 inp, i, lvl)) $
208 if i >= lvl && take 1 inp /= ")"
209 then fail "Not end of block"
211 setState (ist { brace_stack = bs })
213pTerminator = do lchar ';'; popIndent
214 <|> do c <- indent; l <- lastIndent
217 else fail "Not a terminator"
219 if "}" `isPrefixOf` i || ")" `isPrefixOf` i
221 else fail "Not a terminator"
225 = do lchar '|'; return ()
226 <|> do c <- indent; l <- lastIndent
227 unless (c <= l) $ fail "Not a terminator"
231 = do lchar ';'; return ()
232 <|> do c <- indent; l <- lastIndent
233 unless (c <= l) $ fail "Not a terminator"
236 unless (h `elem` ["}", ")", "|"]) $ fail "Not a terminator"
239notEndApp = do c <- indent; l <- lastIndent
241 when (c <= l) $ fail "Terminator"
243notEndBlock = do ist <- getState
244 case brace_stack ist of
245 Just lvl : xs -> do i <- indent
247 when (i < lvl || ")" `isPrefixOf` inp) $ fail "End of block"
251pfc = do s <- getPosition
252 let (dir, file) = splitFileName (sourceName s)
256 return $ FC f (sourceLine s)
258pImport :: IParser String
259pImport = do reserved "import"; f <- identifier; option ';' (lchar ';')
264parseProg :: SyntaxInfo -> FilePath -> String -> SourcePos -> Idris [PDecl]
265parseProg syn fname input pos
267 case runParser (do setPosition pos
269 ps <- many (pDecl syn)
272 return (concat ps, i')) i fname input of
273 Left err -> fail (iShowError fname err)
274 Right (x, i) -> do put i
277-- Collect PClauses with the same function name
279collect :: [PDecl] -> [PDecl]
280collect (c@(PClauses _ o _ _) : ds)
281 = clauses (cname c) [] (c : ds)
282 where clauses j@(Just n) acc (PClauses fc _ _ [PClause fc' n' l ws r w] : ds)
283 | n == n' = clauses j (PClause fc' n' l ws r (collect w) : acc) ds
284 clauses j@(Just n) acc (PClauses fc _ _ [PWith fc' n' l ws r w] : ds)
285 | n == n' = clauses j (PWith fc' n' l ws r (collect w) : acc) ds
286 clauses (Just n) acc xs = PClauses (getfc c) o n (reverse acc) : collect xs
287 clauses Nothing acc (x:xs) = collect xs
288 clauses Nothing acc [] = []
290 cname (PClauses fc _ _ [PClause _ n _ _ _ _]) = Just n
291 cname (PClauses fc _ _ [PWith _ n _ _ _ _]) = Just n
292 cname (PClauses fc _ _ [PClauseR _ _ _ _]) = Nothing
293 cname (PClauses fc _ _ [PWithR _ _ _ _]) = Nothing
294 getfc (PClauses fc _ _ _) = fc
296collect (PParams f ns ps : ds) = PParams f ns (collect ps) : collect ds
297collect (PNamespace ns ps : ds) = PNamespace ns (collect ps) : collect ds
298collect (PClass f s cs n ps ds : ds') = PClass f s cs n ps (collect ds) : collect ds'
299collect (PInstance f s cs n ps t en ds : ds')
300 = PInstance f s cs n ps t en (collect ds) : collect ds'
301collect (d : ds) = d : collect ds
304pFullExpr :: SyntaxInfo -> IParser PTerm
306 = do x <- pExpr syn; eof;
308 return $ desugar syn i x
310pDecl :: SyntaxInfo -> IParser [PDecl]
311pDecl syn = do notEndBlock
316 let d' = fmap (desugar syn i) d
323 <|> do d <- pDSL syn; return [d]
325 <|> try (do reserved "import"; fp <- identifier
326 fail "imports must be at the top of file")
328pFunDecl :: SyntaxInfo -> IParser [PDecl]
330 = try (do notEndBlock
333 let d' = fmap (desugar syn i) d
336--------- Top Level Declarations ---------
338pDecl' :: SyntaxInfo -> IParser PDecl
343 <|> try (pRecord syn)
346pSyntaxDecl :: SyntaxInfo -> IParser PDecl
348 = do s <- pSyntaxRule syn
350 let rs = syntax_rules i
351 let ns = syntax_keywords i
352 let ibc = ibc_write i
353 let ks = map show (names s)
354 setState (i { syntax_rules = s : rs,
355 syntax_keywords = ks ++ ns,
356 ibc_write = IBCSyntax s : map IBCKeyword ks ++ ibc
359 return (PSyntax fc s)
361 names (Rule syms _ _) = mapMaybe ename syms
362 ename (Keyword n) = Just n
365pSyntaxRule :: SyntaxInfo -> IParser Syntax
368 sty <- option AnySyntax (do reserved "term"; return TermSyntax
369 <|> do reserved "pattern"; return PatternSyntax)
371 syms <- many1 pSynSym
372 when (all expr syms) $ fail "No keywords in syntax rule"
373 let ns = mapMaybe name syms
374 when (length ns /= length (nub ns))
375 $ fail "Repeated variable in syntax rule"
377 tm <- pExpr (impOK syn)
379 return (Rule (mkSimple syms) tm sty)
383 name (Expr n) = Just n
386 -- Can't parse two full expressions (i.e. expressions with application) in a row
387 -- so change the first to a simple expression
389 mkSimple (Expr e : es) = SimpleExpr e : mkSimple' es
390 mkSimple xs = mkSimple' xs
392 mkSimple' (Expr e : Expr e1 : es) = SimpleExpr e : mkSimple' (Expr e1 : es)
393 mkSimple' (e : es) = e : mkSimple' es
396pSynSym :: IParser SSymbol
397pSynSym = try (do lchar '['; n <- pName; lchar ']'
399 <|> try (do lchar '{'; n <- pName; lchar '}'
406pFunDecl' :: SyntaxInfo -> IParser PDecl
407pFunDecl' syn = try (do pushIndent
409 acc <- pAccessibility
412 let n = expandNS syn n_in
413 ty <- pTSig (impOK syn)
416-- ty' <- implicit syn n ty
418 return (PTy syn fc (opts ++ opts') n ty))
419 <|> try (pPattern syn)
422pUsing :: SyntaxInfo -> IParser [PDecl]
424 do reserved "using"; lchar '('; ns <- tyDeclList syn; lchar ')'
426 let uvars = using syn
427 ds <- many1 (pDecl (syn { using = uvars ++ ns }))
431pParams :: SyntaxInfo -> IParser [PDecl]
433 do reserved "parameters"; lchar '('; ns <- tyDeclList syn; lchar ')'
435 let pvars = syn_params syn
436 ds <- many1 (pDecl syn { syn_params = pvars ++ ns })
439 return [PParams fc ns (concat ds)]
441pNamespace :: SyntaxInfo -> IParser [PDecl]
443 do reserved "namespace"; n <- identifier;
445 ds <- many1 (pDecl syn { syn_namespace = n : syn_namespace syn })
447 return [PNamespace n (concat ds)]
449--------- Fixity ---------
451pFixity :: IParser PDecl
452pFixity = do pushIndent
453 f <- fixity; i <- natural; ops <- sepBy1 operator (lchar ',')
455 let prec = fromInteger i
457 let fs = map (Fix (f prec)) ops
459 idris_infixes = nub $ sort (fs ++ idris_infixes istate),
460 ibc_write = map IBCFix fs ++ ibc_write istate })
462 return (PFix fc (f prec) ops)
464fixity :: IParser (Int -> Fixity)
465fixity = try (do reserved "infixl"; return Infixl)
466 <|> try (do reserved "infixr"; return Infixr)
467 <|> try (do reserved "infix"; return InfixN)
468 <|> try (do reserved "prefix"; return PrefixN)
470--------- Type classes ---------
472pClass :: SyntaxInfo -> IParser [PDecl]
473pClass syn = do acc <- pAccessibility
474 reserved "class"; fc <- pfc; cons <- pConstList syn; n_in <- pName
475 let n = expandNS syn n_in
477 reserved "where"; openBlock
478 ds <- many $ pFunDecl syn
480 let allDs = concat ds
481 accData acc n (concatMap declared allDs)
482 return [PClass syn fc cons n cs allDs]
484 carg = do lchar '('; i <- pName; lchar ':'; ty <- pExpr syn; lchar ')'
489pInstance :: SyntaxInfo -> IParser [PDecl]
490pInstance syn = do reserved "instance"; fc <- pfc
492 (do lchar '['; n_in <- pfName; lchar ']'
493 let n = expandNS syn n_in
497 args <- many1 (pSimpleExpr syn)
498 let sc = PApp fc (PRef fc cn) (map pexp args)
499 let t = bindList (PPi constraint) (map (\x -> (MN 0 "c", x)) cs) sc
500 reserved "where"; openBlock
501 ds <- many $ pFunDecl syn
503 return [PInstance syn fc cs cn args t en (concat ds)]
505--------- Expressions ---------
507pExpr syn = do i <- getState
508 buildExpressionParser (table (idris_infixes i)) (pExpr' syn)
510pExpr' :: SyntaxInfo -> IParser PTerm
515pExtExpr :: SyntaxInfo -> IParser PTerm
516pExtExpr syn = do i <- getState
517 pExtensions syn (syntax_rules i)
519pSimpleExtExpr :: SyntaxInfo -> IParser PTerm
520pSimpleExtExpr syn = do i <- getState
521 pExtensions syn (filter simple (syntax_rules i))
523 simple (Rule (Expr x:xs) _ _) = False
524 simple (Rule (SimpleExpr x:xs) _ _) = False
525 simple (Rule [Keyword _] _ _) = True
526 simple (Rule [Symbol _] _ _) = True
527 simple (Rule (_:xs) _ _) = case last xs of
536 <|> try (pSimpleExpr syn)
541 <|> pComprehension syn
543pExtensions :: SyntaxInfo -> [Syntax] -> IParser PTerm
544pExtensions syn rules = choice (map (try . pExt syn) (filter valid rules))
546 valid (Rule _ _ AnySyntax) = True
547 valid (Rule _ _ PatternSyntax) = inPattern syn
548 valid (Rule _ _ TermSyntax) = not (inPattern syn)
551data SynMatch = SynTm PTerm | SynBind Name
553pExt :: SyntaxInfo -> Syntax -> IParser PTerm
554pExt syn (Rule ssym ptm _)
555 = do smap <- mapM pSymbol ssym
556 let ns = mapMaybe id smap
557 return (update ns ptm) -- updated with smap
559 pSymbol (Keyword n) = do reserved (show n); return Nothing
560 pSymbol (Expr n) = do tm <- pExpr syn
561 return $ Just (n, SynTm tm)
562 pSymbol (SimpleExpr n) = do tm <- pSimpleExpr syn
563 return $ Just (n, SynTm tm)
564 pSymbol (Binding n) = do b <- pName
565 return $ Just (n, SynBind b)
566 pSymbol (Symbol s) = do symbol s
569 dropn n ((x,t) : xs) | n == x = xs
570 | otherwise = (x,t):dropn n xs
572 updateB ns n = case lookup n ns of
573 Just (SynBind t) -> t
576 update ns (PRef fc n) = case lookup n ns of
579 update ns (PLam n ty sc) = PLam (updateB ns n) (update ns ty) (update (dropn n ns) sc)
580 update ns (PPi p n ty sc) = PPi p (updateB ns n) (update ns ty) (update (dropn n ns) sc)
581 update ns (PLet n ty val sc) = PLet (updateB ns n) (update ns ty) (update ns val)
582 (update (dropn n ns) sc)
583 update ns (PApp fc t args) = PApp fc (update ns t) (map (fmap (update ns)) args)
584 update ns (PCase fc c opts) = PCase fc (update ns c) (map (pmap (update ns)) opts)
585 update ns (PPair fc l r) = PPair fc (update ns l) (update ns r)
586 update ns (PDPair fc l t r) = PDPair fc (update ns l) (update ns t) (update ns r)
587 update ns (PAlternative a as) = PAlternative a (map (update ns) as)
588 update ns (PHidden t) = PHidden (update ns t)
589 update ns (PDoBlock ds) = PDoBlock $ upd ns ds
590 where upd ns (DoExp fc t : ds) = DoExp fc (update ns t) : upd ns ds
591 upd ns (DoBind fc n t : ds) = DoBind fc n (update ns t) : upd (dropn n ns) ds
592 upd ns (DoLet fc n ty t : ds) = DoLet fc n (update ns ty) (update ns t)
593 : upd (dropn n ns) ds
594 upd ns (DoBindP fc i t : ds) = DoBindP fc (update ns i) (update ns t)
596 upd ns (DoLetP fc i t : ds) = DoLetP fc (update ns i) (update ns t)
600pName = do i <- getState
601 iName (syntax_keywords i)
602 <|> do reserved "instance"
604 UN n <- iName (syntax_keywords i)
607-- Parser for an operator in function position, i.e. enclosed by `()', with an
608-- optional namespace.
609pOpFront = maybeWithNS pOpFrontNoNS False []
610 where pOpFrontNoNS = do lchar '('; o <- operator; lchar ')'; return o
615pAccessibility' :: IParser Accessibility
617 = do reserved "public"; return Public
618 <|> do reserved "abstract"; return Frozen
619 <|> do reserved "private"; return Hidden
621pAccessibility :: IParser (Maybe Accessibility)
623 = do acc <- pAccessibility'; return (Just acc)
626pFnOpts :: IParser [FnOpt]
627pFnOpts = do reserved "total"; xs <- pFnOpts; return (TotalFn : xs)
628 <|> try (do lchar '%'; reserved "export"; c <- strlit; xs <- pFnOpts
629 return (CExport c : xs))
630 <|> do lchar '%'; reserved "assert_total"; xs <- pFnOpts; return (AssertTotal : xs)
631 <|> do lchar '%'; reserved "specialise";
632 lchar '['; ns <- sepBy pfName (lchar ','); lchar ']'
634 return (Specialise ns : xs)
637addAcc :: Name -> Maybe Accessibility -> IParser ()
638addAcc n a = do i <- getState
639 setState (i { hide_list = (n, a) : hide_list i })
642 reserved "case"; fc <- pfc; scr <- pExpr syn; reserved "of";
645 opts <- many1 (do notEndBlock
648 return x) -- sepBy1 (pCaseOpt syn) (lchar '|')
651 return (PCase fc scr opts)
654 reserved "proof"; lchar '{'
655 ts <- endBy (pTactic syn) (lchar ';')
660 reserved "tactics"; lchar '{'
661 ts <- endBy (pTactic syn) (lchar ';')
666 try (do symbol "!["; t <- pTerm; lchar ']'; return $ PQuote t)
667 <|> do lchar '?'; x <- pName; return (PMetavar x)
668 <|> do reserved "refl"; fc <- pfc;
669 tm <- option Placeholder (do lchar '{'; t <- pExpr syn; lchar '}';
672-- <|> do reserved "return"; fc <- pfc; return (PReturn fc)
676 <|> try (do x <- pfName
682 <|> try (do lchar '('
683 bracketed (noImp syn))
684 <|> try (do c <- pConstant
686 return (modifyConst syn fc (PConstant c)))
687 <|> do reserved "Set"; return PSet
688 <|> try (do symbol "()"
691 <|> try (do symbol "_|_"
694 <|> do lchar '_'; return Placeholder
695 <|> pSimpleExtExpr syn
699 <|> try (do e <- pExpr syn; lchar ')'; return e)
700-- <|> try (do reserved "typed"
701-- e <- pExpr syn; symbol ":"; t <- pExpr syn; lchar ')'
702-- return (PTyped e t))
703 <|> try (do fc <- pfc; o <- operator; e <- pExpr syn; lchar ')'
704 return $ PLam (MN 0 "x") Placeholder
705 (PApp fc (PRef fc (UN o)) [pexp (PRef fc (MN 0 "x")),
707 <|> try (do fc <- pfc; e <- pSimpleExpr syn; o <- operator; lchar ')'
708 return $ PLam (MN 0 "x") Placeholder
709 (PApp fc (PRef fc (UN o)) [pexp e,
710 pexp (PRef fc (MN 0 "x"))]))
712pCaseOpt :: SyntaxInfo -> IParser (PTerm, PTerm)
713pCaseOpt syn = do lhs <- pExpr syn; symbol "=>"; rhs <- pExpr syn
716modifyConst :: SyntaxInfo -> FC -> PTerm -> PTerm
717modifyConst syn fc (PConstant (I x))
718 | not (inPattern syn)
719 = PApp fc (PRef fc (UN "fromInteger")) [pexp (PConstant (I x))]
720 | otherwise = PConstant (I x)
721modifyConst syn fc x = x
723pList syn = do lchar '['; fc <- pfc; xs <- sepBy (pExpr syn) (lchar ','); lchar ']'
724 return (mkList fc xs)
726 mkList fc [] = PRef fc (UN "Nil")
727 mkList fc (x : xs) = PApp fc (PRef fc (UN "::")) [pexp x, pexp (mkList fc xs)]
729pPair syn = try (do l <- pExpr syn
734 [Left r] -> return (PPair fc l r)
735 [Right r] -> return (PDPair fc l Placeholder r))
736 <|> try (do x <- ntuple
739 <|> do ln <- pName; lchar ':'
745 return (PDPair fc (PRef fc ln) lty r)
747 restTuple = do lchar ')'; return []
752 <|> do reservedOp "**"
756 ntuple = try (do l <- pExpr syn; fc <- pfc; lchar ','
758 return (PPair fc l rest))
759 <|> (do l <- pExpr syn; fc <- pfc; lchar ','
761 return (PPair fc l r))
763pAlt syn = do symbol "(|"; alts <- sepBy1 (pExpr' syn) (lchar ','); symbol "|)"
764 return (PAlternative False alts)
772pApp syn = do f <- pSimpleExpr syn
774 args <- many1 (do notEndApp
777 return (dslify i $ PApp fc f args)
779 dslify i (PApp fc (PRef _ f) [a])
780 | [d] <- lookupCtxt Nothing f (idris_dsls i)
781 = desugar (syn { dsl_info = d }) i (getTm a)
784pArg :: SyntaxInfo -> IParser PArg
785pArg syn = try (pImplicitArg syn)
786 <|> try (pConstraintArg syn)
787 <|> do e <- pSimpleExpr syn
790pImplicitArg syn = do lchar '{'
793 v <- option (PRef fc n) (do lchar '='
798pConstraintArg syn = do symbol "@{"
804 = do reserved "record"
806 fields <- sepBy1 pFieldSet (lchar ',')
809 rec <- option Nothing (do e <- pSimpleExpr syn
813 return (PLam (MN 0 "fldx") Placeholder
814 (applyAll fc fields (PRef fc (MN 0 "fldx"))))
815 Just v -> return (applyAll fc fields v)
816 where pFieldSet = do n <- pfName
821 applyAll fc ((n, e) : es) x
822 = applyAll fc es (PApp fc (PRef fc (mkSet n)) [pexp e, pexp x])
824mkSet (UN n) = UN ("set_" ++ n)
825mkSet (MN 0 n) = MN 0 ("set_" ++ n)
826mkSet (NS n s) = NS (mkSet n) s
828noImp syn = syn { implicitAllowed = False }
829impOK syn = syn { implicitAllowed = True }
831pTSig syn = do lchar ':'
832 cs <- if implicitAllowed syn then pConstList syn else return []
834 return (bindList (PPi constraint) (map (\x -> (MN 0 "c", x)) cs) sc)
836pLambda syn = do lchar '\\'
837 try (do xt <- tyOptDeclList syn
840 return (bindList PLam xt sc)
841 <|> (do ps <- sepBy (do fc <- pfc
843 return (fc, e)) (lchar ',')
846 return (pmList (zip [0..] ps) sc)))
847 where pmList [] sc = sc
848 pmList ((i, (fc, x)) : xs) sc
849 = PLam (MN i "lamp") Placeholder
850 (PCase fc (PRef fc (MN i "lamp"))
853pLet syn = try (do reserved "let"; n <- pName;
854 ty <- option Placeholder (do lchar ':'; pExpr' syn)
857 reserved "in"; sc <- pExpr syn
858 return (PLet n ty v sc))
859 <|> (do reserved "let"; fc <- pfc; pat <- pExpr' (syn { inPattern = True } )
860 symbol "="; v <- pExpr syn
861 reserved "in"; sc <- pExpr syn
862 return (PCase fc v [(pat, sc)]))
865 try (do lazy <- option False (do lchar '|'; return True)
867 lchar '('; xt <- tyDeclList syn; lchar ')'
870 return (bindList (PPi (Exp lazy st)) xt sc))
871 <|> try (if implicitAllowed syn
872 then do lazy <- option False (do lchar '|'
880 return (bindList (PPi (Imp lazy st)) xt sc)
881 else fail "No implicit arguments allowed here")
882 <|> try (do lchar '{'
888 return (bindList (PPi (TacImp False Dynamic (PTactics [Trivial]))) xt sc))
889 <|> try (do lchar '{'
891 script <- pSimpleExpr syn
896 return (bindList (PPi (TacImp False Dynamic script)) xt sc))
897 <|> do --lazy <- option False (do lchar '|'; return True)
904 return (PPi (Exp False Static) (MN 42 "__pi_arg") t sc)
906pConstList :: SyntaxInfo -> IParser [PTerm]
907pConstList syn = try (do lchar '('
908 tys <- sepBy1 (pExpr' (noImp syn)) (lchar ',')
912 <|> try (do t <- pExpr (noImp syn)
917tyDeclList syn = try (sepBy1 (do x <- pfName
918 t <- pTSig (noImp syn)
921 <|> do ns <- sepBy1 pName (lchar ',')
922 t <- pTSig (noImp syn)
923 return (map (\x -> (x, t)) ns)
925tyOptDeclList syn = sepBy1 (do x <- pfName;
926 t <- option Placeholder (do lchar ':'
932bindList b ((n, t):bs) sc = b n t (bindList b bs sc)
939 qs <- sepBy1 (pDo syn) (lchar ',')
941 return (PDoBlock (map addGuard qs ++
942 [DoExp fc (PApp fc (PRef fc (UN "return"))
944 where addGuard (DoExp fc e) = DoExp fc (PApp fc (PRef fc (UN "guard"))
952 ds <- many1 (do notEndBlock
961 = try (do reserved "let"
963 ty <- option Placeholder (do lchar ':'
968 return (DoLet fc i ty e))
969 <|> try (do reserved "let"
974 return (DoLetP fc i sc))
975 <|> try (do i <- pName
979 return (DoBind fc i e))
980 <|> try (do i <- pExpr' syn
984 return (DoBindP fc i e))
985 <|> try (do e <- pExpr syn
996pConstant :: IParser Const
997pConstant = do reserved "Integer";return BIType
998 <|> do reserved "Int"; return IType
999 <|> do reserved "Char"; return ChType
1000 <|> do reserved "Float"; return FlType
1001 <|> do reserved "String"; return StrType
1002 <|> do reserved "Ptr"; return PtrType
1003 <|> try (do f <- float; return $ Fl f)
1004-- <|> try (do i <- natural; lchar 'L'; return $ BI i)
1005 <|> try (do i <- natural; return $ I (fromInteger i))
1006 <|> try (do s <- strlit; return $ Str s)
1007 <|> try (do c <- chlit; return $ Ch c)
1009pStatic :: IParser Static
1010pStatic = do lchar '['
1017 = [[prefix "-" (\fc x -> PApp fc (PRef fc (UN "-"))
1018 [pexp (PApp fc (PRef fc (UN "fromInteger")) [pexp (PConstant (I 0))]), pexp x])]]
1019 ++ toTable (reverse fixes) ++
1021 [binary "=" PEq AssocLeft],
1022 [binary "->" (\fc x y -> PPi expl (MN 42 "__pi_arg") x y) AssocRight]]
1024toTable fs = map (map toBin)
1025 (groupBy (\ (Fix x _) (Fix y _) -> prec x == prec y) fs)
1026 where toBin (Fix (PrefixN _) op) = prefix op
1027 (\fc x -> PApp fc (PRef fc (UN op)) [pexp x])
1029 = binary op (\fc x y -> PApp fc (PRef fc (UN op)) [pexp x,pexp y]) (assoc f)
1030 assoc (Infixl _) = AssocLeft
1031 assoc (Infixr _) = AssocRight
1032 assoc (InfixN _) = AssocNone
1034binary name f = Infix (do reservedOp name
1037prefix name f = Prefix (do reservedOp name
1040backtick = Infix (do lchar '`'; n <- pfName
1043 return (\x y -> PApp fc (PRef fc n) [pexp x, pexp y])) AssocNone
1045--------- Data declarations ---------
1047-- (works for classes too - 'abstract' means the data/class is visible but members not)
1048accData :: Maybe Accessibility -> Name -> [Name] -> IParser ()
1049accData (Just Frozen) n ns = do addAcc n (Just Frozen)
1050 mapM_ (\n -> addAcc n (Just Hidden)) ns
1051accData a n ns = do addAcc n a
1052 mapM_ (`addAcc` a) ns
1054pRecord :: SyntaxInfo -> IParser PDecl
1055pRecord syn = do acc <- pAccessibility
1059 ty <- pTSig (impOK syn)
1060 let tyn = expandNS syn tyn_in
1064 (cn, cty, _) <- pConstructor syn
1068 accData acc tyn [cn]
1069 let rsyn = syn { syn_namespace = show (nsroot tyn) :
1071 let fns = getRecNames rsyn cty
1072 mapM_ (\n -> addAcc n (toFreeze acc)) fns
1073 return $ PRecord rsyn fc tyn ty cn cty
1075 getRecNames syn (PPi _ n _ sc) = [expandNS syn n, expandNS syn (mkSet n)]
1076 ++ getRecNames syn sc
1077 getRecNames _ _ = []
1079 toFreeze (Just Frozen) = Just Hidden
1082pData :: SyntaxInfo -> IParser PDecl
1083pData syn = try (do acc <- pAccessibility
1087 ty <- pTSig (impOK syn)
1088 let tyn = expandNS syn tyn_in
1092 cons <- many (do notEndBlock
1093 c <- pConstructor syn
1095 return c) -- (lchar '|')
1098 accData acc tyn (map (\ (n, _, _) -> n) cons)
1099 return $ PData syn fc (PDatadecl tyn ty cons))
1100 <|> try (do pushIndent
1101 acc <- pAccessibility
1106 let tyn = expandNS syn tyn_in
1108 cons <- sepBy1 (pSimpleCon syn) (lchar '|')
1110 let conty = mkPApp fc (PRef fc tyn) (map (PRef fc) args)
1111 let ty = bindArgs (map (const PSet) args) PSet
1112 cons' <- mapM (\ (x, cargs, cfc) ->
1113 do let cty = bindArgs cargs conty
1114 return (x, cty, cfc)) cons
1115 accData acc tyn (map (\ (n, _, _) -> n) cons')
1116 return $ PData syn fc (PDatadecl tyn ty cons'))
1119 mkPApp fc t xs = PApp fc t (map pexp xs)
1121bindArgs :: [PTerm] -> PTerm -> PTerm
1122bindArgs xs t = foldr (PPi expl (MN 0 "t")) t xs
1124pConstructor :: SyntaxInfo -> IParser (Name, PTerm, FC)
1126 = do cn_in <- pfName; fc <- pfc
1127 let cn = expandNS syn cn_in
1128 ty <- pTSig (impOK syn)
1129-- ty' <- implicit syn cn ty
1133pSimpleCon :: SyntaxInfo -> IParser (Name, [PTerm], FC)
1135 = do cn_in <- pfName
1136 let cn = expandNS syn cn_in
1138 args <- many (do notEndApp
1140 return (cn, args, fc)
1142--------- DSL syntax overloading ---------
1144pDSL :: SyntaxInfo -> IParser PDecl
1145pDSL syn = do reserved "dsl"
1149 bs <- many1 (do notEndBlock
1153 popIndent; closeBlock
1154 let dsl = mkDSL bs (dsl_info syn)
1157 setState (i { idris_dsls = addDef n dsl (idris_dsls i) })
1159 where mkDSL bs dsl = let var = lookup "variable" bs
1160 first = lookup "index_first" bs
1161 next = lookup "index_next" bs
1162 leto = lookup "let" bs
1163 lambda = lookup "lambda" bs in
1164 initDSL { dsl_var = var,
1165 index_first = first,
1167 dsl_lambda = lambda,
1170checkDSL :: DSL -> IParser ()
1171checkDSL dsl = return ()
1173pOverload :: SyntaxInfo -> IParser (String, PTerm)
1174pOverload syn = do o <- identifier <|> do reserved "let"
1176 if o `notElem` overloadable
1177 then fail $ show o ++ " is not an overloading"
1182 where overloadable = ["let","lambda","index_first","index_next","variable"]
1184--------- Pattern match clauses ---------
1186pPattern :: SyntaxInfo -> IParser PDecl
1187pPattern syn = do fc <- pfc
1188 clause <- pClause syn
1189 return (PClauses fc [] (MN 2 "_") [clause]) -- collect together later
1191pCAF :: SyntaxInfo -> IParser PDecl
1192pCAF syn = do reserved "let"
1193 n_in <- pfName; let n = expandNS syn n_in
1198 return (PCAF fc n t)
1200pArgExpr syn = let syn' = syn { inPattern = True } in
1201 try (pHSimpleExpr syn') <|> pSimpleExtExpr syn'
1203pRHS :: SyntaxInfo -> Name -> IParser PTerm
1204pRHS syn n = do lchar '='; pExpr syn
1205 <|> do symbol "?="; rhs <- pExpr syn;
1207 <|> do reserved "impossible"; return PImpossible
1208 where mkN (UN x) = UN (x++"_lemma_1")
1209 mkN (NS x n) = NS (mkN x) n
1212 addLet (PLet n ty val rhs) = PLet n ty val (addLet rhs)
1213 addLet (PCase fc t cs) = PCase fc t (map addLetC cs)
1214 where addLetC (l, r) = (l, addLet r)
1215 addLet rhs = (PLet (UN "value") Placeholder rhs (PMetavar n'))
1217pClause :: SyntaxInfo -> IParser PClause
1219 = try (do pushIndent
1220 n_in <- pfName; let n = expandNS syn n_in
1221 cargs <- many (pConstraintArg syn)
1222 iargs <- many (pImplicitArg syn)
1224 args <- many (pArgExpr syn)
1225 wargs <- many (pWExpr syn)
1228 let ctxt = tt_ctxt ist
1229 let wsyn = syn { syn_namespace = [] }
1230 (wheres, nmap) <- choice [do x <- pWhereblock n wsyn
1235 let capp = PApp fc (PRef fc n)
1236 (iargs ++ cargs ++ map pexp args)
1238 setState (ist { lastParse = Just n })
1239 return $ PClause fc n capp wargs rhs wheres)
1240 <|> try (do pushIndent
1241 wargs <- many1 (pWExpr syn)
1243 n <- case lastParse ist of
1245 Nothing -> fail "Invalid clause"
1248 let ctxt = tt_ctxt ist
1249 let wsyn = syn { syn_namespace = [] }
1250 (wheres, nmap) <- choice [do x <- pWhereblock n wsyn
1255 return $ PClauseR fc wargs rhs wheres)
1257 <|> try (do pushIndent
1258 n_in <- pfName; let n = expandNS syn n_in
1259 cargs <- many (pConstraintArg syn)
1260 iargs <- many (pImplicitArg syn)
1262 args <- many (pArgExpr syn)
1263 wargs <- many (pWExpr syn)
1264 let capp = PApp fc (PRef fc n)
1265 (iargs ++ cargs ++ map pexp args)
1267 setState (ist { lastParse = Just n })
1269 wval <- pSimpleExpr syn
1271 ds <- many1 $ pFunDecl syn
1272 let withs = map (fillLHSD n capp wargs) $ concat ds
1275 return $ PWith fc n capp wargs wval withs)
1277 <|> try (do wargs <- many1 (pWExpr syn)
1280 wval <- pSimpleExpr syn
1282 ds <- many1 $ pFunDecl syn
1283 let withs = concat ds
1285 return $ PWithR fc wargs wval withs)
1290 let n = expandNS syn (UN op)
1293 wargs <- many (pWExpr syn)
1295 let wsyn = syn { syn_namespace = [] }
1296 (wheres, nmap) <- choice [do x <- pWhereblock n wsyn
1302 let capp = PApp fc (PRef fc n) [pexp l, pexp r]
1303 setState (ist { lastParse = Just n })
1304 return $ PClause fc n capp wargs rhs wheres
1306 <|> do l <- pArgExpr syn
1308 let n = expandNS syn (UN op)
1311 wargs <- many (pWExpr syn)
1313 wval <- pSimpleExpr syn
1315 ds <- many1 $ pFunDecl syn
1318 let capp = PApp fc (PRef fc n) [pexp l, pexp r]
1319 let withs = map (fillLHSD n capp wargs) $ concat ds
1320 setState (ist { lastParse = Just n })
1321 return $ PWith fc n capp wargs wval withs
1323 fillLHS n capp owargs (PClauseR fc wargs v ws)
1324 = PClause fc n capp (owargs ++ wargs) v ws
1325 fillLHS n capp owargs (PWithR fc wargs v ws)
1326 = PWith fc n capp (owargs ++ wargs) v
1327 (map (fillLHSD n capp (owargs ++ wargs)) ws)
1330 fillLHSD n c a (PClauses fc o fn cs) = PClauses fc o fn (map (fillLHS n c a) cs)
1331 fillLHSD n c a x = x
1333pWExpr :: SyntaxInfo -> IParser PTerm
1334pWExpr syn = do lchar '|'
1337pWhereblock :: Name -> SyntaxInfo -> IParser ([PDecl], [(Name, Name)])
1339 = do reserved "where"; openBlock
1340 ds <- many1 $ pDecl syn
1341 let dns = concatMap (concatMap declared) ds
1343 return (concat ds, map (\x -> (x, decoration syn x)) dns)
1345pDirective :: IParser [PDecl]
1346pDirective = try (do lchar '%'; reserved "lib"; lib <- strlit;
1347 return [PDirective (do addLib lib
1348 addIBC (IBCLib lib))])
1349 <|> try (do lchar '%'; reserved "link"; obj <- strlit;
1350 return [PDirective (do datadir <- liftIO getDataDir
1351 o <- liftIO $ findInPath [".", datadir] obj
1354 <|> try (do lchar '%'; reserved "include"; hdr <- strlit;
1355 return [PDirective (do addHdr hdr
1356 addIBC (IBCHeader hdr))])
1357 <|> try (do lchar '%'; reserved "hide"; n <- iName []
1358 return [PDirective (do setAccessibility n Hidden
1359 addIBC (IBCAccess n Hidden))])
1360 <|> try (do lchar '%'; reserved "freeze"; n <- iName []
1361 return [PDirective (do setAccessibility n Frozen
1362 addIBC (IBCAccess n Frozen))])
1363 <|> try (do lchar '%'; reserved "access"; acc <- pAccessibility'
1364 return [PDirective (do i <- getIState
1365 putIState (i { default_access = acc }))])
1366 <|> try (do lchar '%'; reserved "logging"; i <- natural;
1367 return [PDirective (setLogLevel (fromInteger i))])
1369pTactic :: SyntaxInfo -> IParser PTactic
1370pTactic syn = do reserved "intro"; ns <- sepBy pName (lchar ',')
1372 <|> do reserved "intros"; return Intros
1373 <|> try (do reserved "refine"; n <- pName
1375 return $ Refine n imps)
1376 <|> do reserved "refine"; n <- pName
1378 return $ Refine n []
1379 <|> do reserved "rewrite"; t <- pExpr syn;
1381 return $ Rewrite (desugar syn i t)
1382 <|> do reserved "let"; n <- pName; lchar '=';
1385 return $ LetTac n (desugar syn i t)
1386 <|> do reserved "focus"; n <- pName
1388 <|> do reserved "exact"; t <- pExpr syn;
1390 return $ Exact (desugar syn i t)
1391 <|> do reserved "try"; t <- pTactic syn;
1401 <|> do reserved "compute"; return Compute
1402 <|> do reserved "trivial"; return Trivial
1403 <|> do reserved "solve"; return Solve
1404 <|> do reserved "attack"; return Attack
1405 <|> do reserved "state"; return ProofState
1406 <|> do reserved "term"; return ProofTerm
1407 <|> do reserved "undo"; return Undo
1408 <|> do reserved "qed"; return Qed
1409 <|> do reserved "abandon"; return Abandon
1410 <|> do lchar ':'; reserved "q"; return Abandon
1412 imp = do lchar '?'; return False
1413 <|> 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