1{-# LANGUAGE PatternGuards #-}
3module Idris.Parser where
19import Text.ParserCombinators.Parsec
20import Text.ParserCombinators.Parsec.Error
21import Text.ParserCombinators.Parsec.Expr
22import Text.ParserCombinators.Parsec.Language
23import qualified Text.ParserCombinators.Parsec.Token as PTok
26import Control.Monad.State
31type TokenParser a = PTok.TokenParser a
33type IParser = GenParser Char IState
35lexer :: TokenParser IState
36lexer = PTok.makeTokenParser idrisDef
38whiteSpace= PTok.whiteSpace lexer
39lexeme = PTok.lexeme lexer
40symbol = PTok.symbol lexer
41natural = PTok.natural lexer
42parens = PTok.parens lexer
44comma = PTok.comma lexer
45identifier= PTok.identifier lexer
46reserved = PTok.reserved lexer
47operator = PTok.operator lexer
48reservedOp= PTok.reservedOp lexer
49integer = PTok.integer lexer
50float = PTok.float lexer
51strlit = PTok.stringLiteral lexer
52chlit = PTok.charLiteral lexer
57loadModule :: FilePath -> Idris String
59 = idrisCatch (do datadir <- liftIO $ getDataDir
60 fp <- liftIO $ findImport [".", datadir] f
62 if (f `elem` imported i)
63 then iLOG $ "Already read " ++ f
64 else do putIState (i { imported = f : imported i })
66 IDR fn -> loadSource False fn
67 LIDR fn -> loadSource True fn
69 idrisCatch (loadIBC fn)
70 (\c -> do iLOG $ fn ++ " failed " ++ show c
72 IDR sfn -> loadSource False sfn
73 LIDR sfn -> loadSource True sfn)
74 let (dir, fh) = splitFileName f
75 return (dropExtension fh))
76 (\e -> do let msg = show e
77 setErrLine (getErrLine msg)
81loadSource :: Bool -> FilePath -> Idris ()
83 = do iLOG ("Reading " ++ f)
84 file_in <- liftIO $ readFile f
85 file <- if lidr then tclift $ unlit f file_in else return file_in
86 (mname, modules, rest, pos) <- parseImports f file
88 putIState (i { default_access = Hidden })
89 mapM_ loadModule modules
90 clearIBC -- start a new .ibc file
91 mapM_ (\m -> addIBC (IBCImport m)) modules
92 ds' <- parseProg (defaultSyntax {syn_namespace = reverse mname })
94 let ds = namespaces mname ds'
95 logLvl 3 (dumpDecls ds)
97 logLvl 10 (show (toAlist (idris_implicits i)))
98 logLvl 3 (show (idris_infixes i))
99 -- Now add all the declarations to the context
101 when v $ iputStrLn $ "Type checking " ++ f
102 mapM_ (elabDecl toplevel) ds
103 iLOG ("Finished " ++ f)
104 let ibc = dropExtension f ++ ".ibc"
107 addHides (hide_list i)
110 idrisCatch (do writeIBC f ibc; clearIBC)
111 (\c -> return ()) -- failure is harmless
112 putIState (i { hide_list = [] })
115 namespaces [] ds = ds
116 namespaces (x:xs) ds = [PNamespace x (namespaces xs ds)]
118addHides :: [(Name, Maybe Accessibility)] -> Idris ()
119addHides xs = do i <- getIState
120 let defh = default_access i
121 let (hs, as) = partition isNothing xs
122 if null as then return ()
124 (map (\ (n, _) -> (n, defh)) hs ++
125 map (\ (n, Just a) -> (n, a)) as)
126 where isNothing (_, Nothing) = True
129 doHide (n, a) = do setAccessibility n a
130 addIBC (IBCAccess n a)
132parseExpr i = runParser (pFullExpr defaultSyntax) i "(input)"
133parseTac i = runParser (do t <- pTactic defaultSyntax
135 return t) i "(proof)"
137parseImports :: FilePath -> String -> Idris ([String], [String], String, SourcePos)
138parseImports fname input
140 case (runParser (do mname <- pHeader
144 return ((mname, ps, rest, pos), i)) i fname input) of
145 Left err -> fail (ishow err)
146 Right (x, i) -> do put i
148 where ishow err = let ln = sourceLine (errorPos err) in
149 fname ++ ":" ++ show ln ++ ":parse error"
150-- show (map messageString (errorMessages err))
152pHeader :: IParser [String]
153pHeader = try (do reserved "module"; i <- identifier; option ';' (lchar ';')
154 return (parseName i))
156 where parseName x = case span (/='.') x of
158 (x, '.':y) -> x : parseName y
160push_indent :: IParser ()
161push_indent = do pos <- getPosition
163 setState (ist { indent_stack = sourceColumn pos :
166last_indent :: IParser Int
167last_indent = do ist <- getState
168 case indent_stack ist of
173indent = do pos <- getPosition
174 return (sourceColumn pos)
176pop_indent :: IParser ()
177pop_indent = do ist <- getState
178 let (x : xs) = indent_stack ist
179 setState (ist { indent_stack = xs })
181open_block :: IParser ()
182open_block = do lchar '{'
184 setState (ist { brace_stack = Nothing : brace_stack ist })
185 <|> do ist <- getState
187 setState (ist { brace_stack = Just lvl : brace_stack ist })
189close_block :: IParser ()
190close_block = do ist <- getState
191 bs <- case brace_stack ist of
192 Nothing : xs -> do lchar '}'
194 Just lvl : xs -> do i <- indent
196-- trace (show (take 10 inp, i, lvl)) $
197 if (i >= lvl && take 1 inp /= ")")
198 then fail "Not end of block"
200 setState (ist { brace_stack = bs })
202pTerminator = do lchar ';'; pop_indent
203 <|> do c <- indent; l <- last_indent
204 if (c <= l) then pop_indent
205 else fail "Not a terminator"
206 <|> do i <- getInput; if (take 1 i == "}" || take 1 i == ")") then pop_indent
207 else fail "Not a terminator"
211 = do lchar '|'; return ()
212 <|> do c <- indent; l <- last_indent
213 if (c <= l) then return ()
214 else fail "Not a terminator"
218 = do lchar ';'; return ()
219 <|> do c <- indent; l <- last_indent
220 if (c <= l) then return ()
221 else fail "Not a terminator"
222 <|> do i <- getInput; let h = take 1 i
223 if (h == "}" || h == ")" || h == "|") then return ()
224 else fail "Not a terminator"
227notEndApp = do c <- indent; l <- last_indent
229 if (c <= l) then fail "Terminator"
232notEndBlock = do ist <- getState
233 case brace_stack ist of
234 Just lvl : xs -> do i <- indent
236 if (i < lvl || take 1 inp == ")")
237 then fail "End of block"
242pfc = do s <- getPosition
243 let (dir, file) = splitFileName (sourceName s)
247 return $ FC f (sourceLine s)
249pImport :: IParser String
250pImport = do reserved "import"
252 option ';' (lchar ';')
257parseProg :: SyntaxInfo -> FilePath -> String -> SourcePos -> Idris [PDecl]
258parseProg syn fname input pos
260 case (runParser (do setPosition pos
262 ps <- many (pDecl syn)
265 return (concat ps, i')) i fname input) of
266 Left err -> fail (ishow err)
267 Right (x, i) -> do put i
269 where ishow err = let ln = sourceLine (errorPos err) in
270 fname ++ ":" ++ show ln ++ ":parse error"
271 ++ " at column " ++ show (sourceColumn (errorPos err))
272-- show (map messageString (errorMessages err))
274-- Collect PClauses with the same function name
276collect :: [PDecl] -> [PDecl]
277collect (c@(PClauses _ o _ _) : ds)
278 = clauses (cname c) [] (c : ds)
279 where clauses n acc (PClauses fc _ _ [PClause n' l ws r w] : ds)
280 | n == n' = clauses n (PClause n' l ws r (collect w) : acc) ds
281 clauses n acc (PClauses fc _ _ [PWith n' l ws r w] : ds)
282 | n == n' = clauses n (PWith n' l ws r (collect w) : acc) ds
283 clauses n acc xs = PClauses (getfc c) o n (reverse acc) : collect xs
285 cname (PClauses fc _ _ [PClause n _ _ _ _]) = n
286 cname (PClauses fc _ _ [PWith n _ _ _ _]) = n
287 getfc (PClauses fc _ _ _) = fc
289collect (PParams f ns ps : ds) = PParams f ns (collect ps) : collect ds
290collect (PNamespace ns ps : ds) = PNamespace ns (collect ps) : collect ds
291collect (PClass f s cs n ps ds : ds') = PClass f s cs n ps (collect ds) : collect ds'
292collect (PInstance f s cs n ps t ds : ds')
293 = PInstance f s cs n ps t (collect ds) : collect ds'
294collect (d : ds) = d : collect ds
297pFullExpr :: SyntaxInfo -> IParser PTerm
299 = do x <- pExpr syn; eof;
301 return $ desugar syn i x
303pDecl :: SyntaxInfo -> IParser [PDecl]
304pDecl syn = do notEndBlock
309 let d' = fmap (desugar syn i) d
316 <|> do d <- pDSL syn; return [d]
318 <|> try (do reserved "import"
320 fail "imports must be at the top of file")
322pFunDecl :: SyntaxInfo -> IParser [PDecl]
324 = try (do notEndBlock
327 let d' = fmap (desugar syn i) d
330--------- Top Level Declarations ---------
332pDecl' :: SyntaxInfo -> IParser PDecl
337 <|> try (pRecord syn)
340pSyntaxDecl :: SyntaxInfo -> IParser PDecl
342 = do s <- pSyntaxRule syn
344 let rs = syntax_rules i
345 let ns = syntax_keywords i
346 let ibc = ibc_write i
347 let ks = map show (names s)
348 setState (i { syntax_rules = s : rs,
349 syntax_keywords = ks ++ ns,
350 ibc_write = IBCSyntax s : map IBCKeyword ks ++ ibc
353 return (PSyntax fc s)
355 names (Rule syms _ _) = mapMaybe ename syms
356 ename (Keyword n) = Just n
359pSyntaxRule :: SyntaxInfo -> IParser Syntax
362 sty <- option AnySyntax (do reserved "term"; return TermSyntax
363 <|> do reserved "pattern"; return PatternSyntax)
365 syms <- many1 pSynSym
366 when (all expr syms) $ fail "No keywords in syntax rule"
367 let ns = mapMaybe name syms
368 when (length ns /= length (nub ns))
369 $ fail "Repeated variable in syntax rule"
373 return (Rule (mkSimple syms) tm sty)
377 name (Expr n) = Just n
380 -- Can't parse two full expressions (i.e. expressions with application) in a row
381 -- so change the first to a simple expression
383 mkSimple (Expr e : es) = SimpleExpr e : mkSimple' es
384 mkSimple xs = mkSimple' xs
386 mkSimple' (Expr e : Expr e1 : es) = SimpleExpr e : mkSimple' (Expr e1 : es)
387 mkSimple' (e : es) = e : mkSimple' es
390pSynSym :: IParser SSymbol
391pSynSym = try (do lchar '['; n <- pName; lchar ']'
398pFunDecl' :: SyntaxInfo -> IParser PDecl
399pFunDecl' syn = try (do push_indent
400 acc <- pAccessibility
402 let n = expandNS syn n_in
406-- ty' <- implicit syn n ty
408 return (PTy syn fc n ty))
409 <|> try (pPattern syn)
411pUsing :: SyntaxInfo -> IParser [PDecl]
418 let uvars = using syn
419 ds <- many1 (pDecl (syn { using = uvars ++ ns }))
423pParams :: SyntaxInfo -> IParser [PDecl]
425 do reserved "params";
430 let pvars = syn_params syn
431 ds <- many1 (pDecl syn { syn_params = pvars ++ ns })
434 return [PParams fc ns (concat ds)]
436pNamespace :: SyntaxInfo -> IParser [PDecl]
438 do reserved "namespace";
441 ds <- many1 (pDecl syn { syn_namespace = n : syn_namespace syn })
443 return [PNamespace n (concat ds)]
445expandNS :: SyntaxInfo -> Name -> Name
446expandNS syn n@(NS _ _) = n
447expandNS syn n = case syn_namespace syn of
451--------- Fixity ---------
453pFixity :: IParser PDecl
454pFixity = do push_indent
455 f <- fixity; i <- natural; ops <- sepBy1 operator (lchar ',')
457 let prec = fromInteger i
459 let fs = map (Fix (f prec)) ops
461 idris_infixes = sort (fs ++ idris_infixes istate),
462 ibc_write = map IBCFix fs ++ ibc_write istate })
464 return (PFix fc (f prec) ops)
466fixity :: IParser (Int -> Fixity)
467fixity = try (do reserved "infixl"; return Infixl)
468 <|> try (do reserved "infixr"; return Infixr)
469 <|> try (do reserved "infix"; return InfixN)
470 <|> try (do reserved "prefix"; return PrefixN)
472--------- Tyoe classes ---------
474pClass :: SyntaxInfo -> IParser [PDecl]
475pClass syn = do acc <- pAccessibility
478 cons <- pConstList syn
479 n_in <- pName; let n = expandNS syn n_in
481 reserved "where"; open_block
482 ds <- many1 $ pFunDecl syn
484 let allDs = concat ds
485 accData acc n (concatMap declared allDs)
486 return [PClass syn fc cons n cs allDs]
488 carg = do lchar '('; i <- pName; lchar ':'; ty <- pExpr syn; lchar ')'
493pInstance :: SyntaxInfo -> IParser [PDecl]
494pInstance syn = do reserved "instance"
498 args <- many1 (pSimpleExpr syn)
499 let sc = PApp fc (PRef fc cn) (map pexp args)
500 let t = bindList (PPi constraint) (map (\x -> (MN 0 "c", x)) cs) sc
501 reserved "where"; open_block
502 ds <- many1 $ pFunDecl syn
504 return [PInstance syn fc cs cn args t (concat ds)]
506--------- Expressions ---------
508pExpr syn = do i <- getState
509 buildExpressionParser (table (idris_infixes i)) (pExpr' syn)
511pExpr' :: SyntaxInfo -> IParser PTerm
516pExtExpr :: SyntaxInfo -> IParser PTerm
517pExtExpr syn = do i <- getState
518 pExtensions syn (syntax_rules i)
520pSimpleExtExpr :: SyntaxInfo -> IParser PTerm
521pSimpleExtExpr syn = do i <- getState
522 pExtensions syn (filter simple (syntax_rules i))
524 simple (Rule (Expr x:xs) _ _) = False
525 simple (Rule (SimpleExpr x:xs) _ _) = False
526 simple (Rule [Keyword _] _ _) = True
527 simple (Rule [Symbol _] _ _) = True
528 simple (Rule (_:xs) _ _) = case (last xs) of
536 <|> try (pSimpleExpr syn)
541 <|> pComprehension syn
543pExtensions :: SyntaxInfo -> [Syntax] -> IParser PTerm
544pExtensions syn rules = choice (map (\x -> try (pExt syn x)) (filter valid rules))
546 valid (Rule _ _ AnySyntax) = True
547 valid (Rule _ _ PatternSyntax) = inPattern syn
548 valid (Rule _ _ TermSyntax) = not (inPattern syn)
551pExt :: SyntaxInfo -> Syntax -> IParser PTerm
552pExt syn (Rule ssym ptm _)
553 = do smap <- mapM pSymbol ssym
554 let ns = mapMaybe id smap
555 return (update ns ptm) -- updated with smap
557 pSymbol (Keyword n) = do reserved (show n); return Nothing
558 pSymbol (Expr n) = do tm <- pExpr syn
559 return $ Just (n, tm)
560 pSymbol (SimpleExpr n) = do tm <- pSimpleExpr syn
561 return $ Just (n, tm)
562 pSymbol (Symbol s) = do symbol s
565 dropn n ((x,t) : xs) | n == x = xs
566 | otherwise = (x,t):dropn n xs
568 update ns (PRef fc n) = case lookup n ns of
571 update ns (PLam n ty sc) = PLam n (update ns ty) (update (dropn n ns) sc)
572 update ns (PPi p n ty sc) = PPi p n (update ns ty) (update (dropn n ns) sc)
573 update ns (PLet n ty val sc) = PLet n (update ns ty) (update ns val)
574 (update (dropn n ns) sc)
575 update ns (PApp fc t args) = PApp fc (update ns t) (map (fmap (update ns)) args)
576 update ns (PCase fc c opts) = PCase fc (update ns c) (map (pmap (update ns)) opts)
577 update ns (PPair fc l r) = PPair fc (update ns l) (update ns r)
578 update ns (PDPair fc l t r) = PDPair fc (update ns l) (update ns t) (update ns r)
579 update ns (PAlternative as) = PAlternative (map (update ns) as)
580 update ns (PHidden t) = PHidden (update ns t)
581 update ns (PDoBlock ds) = PDoBlock $ upd ns ds
582 where upd ns (DoExp fc t : ds) = DoExp fc (update ns t) : upd ns ds
583 upd ns (DoBind fc n t : ds) = DoBind fc n (update ns t) : upd (dropn n ns) ds
584 upd ns (DoLet fc n ty t : ds) = DoLet fc n (update ns ty) (update ns t)
585 : upd (dropn n ns) ds
586 upd ns (DoBindP fc i t : ds) = DoBindP fc (update ns i) (update ns t)
588 upd ns (DoLetP fc i t : ds) = DoLetP fc (update ns i) (update ns t)
592pName = do i <- getState
593 iName (syntax_keywords i)
594 <|> do reserved "instance"
596 UN n <- iName (syntax_keywords i)
601 <|> do lchar '('; o <- operator; lchar ')'; return (UN o)
603pAccessibility' :: IParser Accessibility
605 = do reserved "public"; return Public
606 <|> do reserved "abstract"; return Frozen
607 <|> do reserved "private"; return Hidden
609pAccessibility :: IParser (Maybe Accessibility)
611 = do acc <- pAccessibility'; return (Just acc)
614addAcc :: Name -> Maybe Accessibility -> IParser ()
615addAcc n a = do i <- getState
616 setState (i { hide_list = (n, a) : hide_list i })
619 try (do symbol "!["; t <- pTerm; lchar ']'
621 <|> do lchar '?'; x <- pName; return (PMetavar x)
622 <|> do reserved "refl"; fc <- pfc; return (PRefl fc)
623-- <|> do reserved "return"; fc <- pfc; return (PReturn fc)
624 <|> do reserved "proof"; lchar '{';
625 ts <- endBy (pTactic syn) (lchar ';')
628 <|> do reserved "tactics"; lchar '{';
629 ts <- endBy (pTactic syn) (lchar ';')
632 <|> do reserved "case"; fc <- pfc; scr <- pExpr syn; reserved "of";
635 opts <- many1 (do notEndBlock
638 return x) -- sepBy1 (pCaseOpt syn) (lchar '|')
641 return (PCase fc scr opts)
642 <|> try (do x <- pfName; fc <- pfc; return (PRef fc x))
646 <|> try (do lchar '('; bracketed syn)
647 <|> try (do c <- pConstant; fc <- pfc
648 return (modifyConst syn fc (PConstant c)))
649 <|> do reserved "Set"; return PSet
650 <|> try (do symbol "()"; fc <- pfc; return (PTrue fc))
651 <|> try (do symbol "_|_"; fc <- pfc; return (PFalse fc))
652 <|> do lchar '_'; return Placeholder
653 <|> pSimpleExtExpr syn
657 <|> try (do e <- pExpr syn; lchar ')'; return e)
658-- <|> try (do reserved "typed"
659-- e <- pExpr syn; symbol ":"; t <- pExpr syn; lchar ')'
660-- return (PTyped e t))
661 <|> try (do fc <- pfc; o <- operator; e <- pExpr syn; lchar ')'
662 return $ PLam (MN 0 "x") Placeholder
663 (PApp fc (PRef fc (UN o)) [pexp (PRef fc (MN 0 "x")),
665 <|> try (do fc <- pfc; e <- pSimpleExpr syn; o <- operator; lchar ')'
666 return $ PLam (MN 0 "x") Placeholder
667 (PApp fc (PRef fc (UN o)) [pexp e,
668 pexp (PRef fc (MN 0 "x"))]))
670pCaseOpt :: SyntaxInfo -> IParser (PTerm, PTerm)
671pCaseOpt syn = do lhs <- pExpr syn; symbol "=>";
675modifyConst :: SyntaxInfo -> FC -> PTerm -> PTerm
676modifyConst syn fc (PConstant (I x))
677 | not (inPattern syn)
678 = PApp fc (PRef fc (UN "fromInteger")) [pexp (PConstant (I x))]
679modifyConst syn fc x = x
681pList syn = do lchar '['; fc <- pfc
682 xs <- sepBy (pExpr syn) (lchar ','); lchar ']'
683 return (mkList fc xs)
685 mkList fc [] = PRef fc (UN "Nil")
686 mkList fc (x : xs) = PApp fc (PRef fc (UN "::")) [pexp x, pexp (mkList fc xs)]
688pPair syn = try (do l <- pExpr syn
693 [Left r] -> return (PPair fc l r)
694 [Right r] -> return (PDPair fc l Placeholder r))
695 <|> try (do x <- ntuple
698 <|> do ln <- pName; lchar ':'; lty <- pExpr syn;
701 r <- pExpr syn; lchar ')';
702 return (PDPair fc (PRef fc ln) lty r)
704 restTuple = do lchar ')'; return []
709 <|> do reservedOp "**"
713 ntuple = try (do l <- pExpr syn; fc <- pfc; lchar ','
715 return (PPair fc l rest))
716 <|> (do l <- pExpr syn; fc <- pfc; lchar ','
718 return (PPair fc l r))
720pAlt syn = do symbol "(|";
721 alts <- sepBy1 (pExpr' syn) (lchar ',')
723 return (PAlternative alts)
731pApp syn = do f <- pSimpleExpr syn
733 args <- many1 (do notEndApp
736 return (dslify i $ PApp fc f args)
738 dslify i (PApp fc (PRef _ f) [a])
739 | [d] <- lookupCtxt Nothing f (idris_dsls i)
740 = desugar (syn { dsl_info = d }) i (getTm a)
743pArg :: SyntaxInfo -> IParser PArg
744pArg syn = try (pImplicitArg syn)
745 <|> try (pConstraintArg syn)
746 <|> do e <- pSimpleExpr syn
749pImplicitArg syn = do lchar '{'; n <- pName
751 v <- option (PRef fc n) (do lchar '='; pExpr syn)
755pConstraintArg syn = do symbol "@{"; e <- pExpr syn; symbol "}"
758pTSig syn = do lchar ':'
761 return (bindList (PPi constraint) (map (\x -> (MN 0 "c", x)) cs) sc)
763pLambda syn = do lchar '\\'
764 (try (do xt <- tyOptDeclList syn
767 return (bindList PLam xt sc))
768 <|> (do ps <- sepBy (do fc <- pfc
770 return (fc, e)) (lchar ',')
773 return (pmList (zip [0..] ps) sc)))
774 where pmList [] sc = sc
775 pmList ((i, (fc, x)) : xs) sc
776 = PLam (MN i "lamp") Placeholder
777 (PCase fc (PRef fc (MN i "lamp"))
778 [(x, (pmList xs sc))])
780pLet syn = try (do reserved "let"; n <- pName;
781 ty <- option Placeholder (do lchar ':'; pExpr' syn)
782 lchar '='; v <- pExpr syn
783 reserved "in"; sc <- pExpr syn
784 return (PLet n ty v sc))
785 <|> (do reserved "let"; fc <- pfc; pat <- pExpr' syn
786 symbol "="; v <- pExpr syn
787 reserved "in"; sc <- pExpr syn
788 return (PCase fc v [(pat, sc)]))
791 try (do lazy <- option False (do lchar '|'; return True)
793 lchar '('; xt <- tyDeclList syn; lchar ')'
796 return (bindList (PPi (Exp lazy st)) xt sc))
797 <|> try (do lazy <- option False (do lchar '|'; return True)
799 lchar '{'; xt <- tyDeclList syn; lchar '}'
802 return (bindList (PPi (Imp lazy st)) xt sc))
803 <|> do --lazy <- option False (do lchar '|'; return True)
804 lchar '{'; reserved "static"; lchar '}'
808 return (PPi (Exp False Static) (MN 42 "__pi_arg") t sc)
810pConstList :: SyntaxInfo -> IParser [PTerm]
811pConstList syn = try (do lchar '('
812 tys <- sepBy1 (pExpr' syn) (lchar ',')
816 <|> try (do t <- pExpr syn
821tyDeclList syn = try (sepBy1 (do x <- pfName; t <- pTSig syn; return (x,t))
823 <|> do ns <- sepBy1 pName (lchar ',')
825 return (map (\x -> (x, t)) ns)
827tyOptDeclList syn = sepBy1 (do x <- pfName;
828 t <- option Placeholder (do lchar ':'
834bindList b ((n, t):bs) sc = b n t (bindList b bs sc)
837 = do lchar '['; fc <- pfc; pat <- pExpr syn; lchar '|';
838 qs <- sepBy1 (pDo syn) (lchar ','); lchar ']';
839 return (PDoBlock (map addGuard qs ++
840 [DoExp fc (PApp fc (PRef fc (UN "return"))
842 where addGuard (DoExp fc e) = DoExp fc (PApp fc (PRef fc (UN "guard"))
847 = do reserved "do"; open_block
849 ds <- many1 (do notEndBlock
850 x <- pDo syn; pKeepTerminator; return x)
856 = try (do reserved "let"; i <- pName;
857 ty <- option Placeholder (do lchar ':'; pExpr' syn)
858 reservedOp "="; fc <- pfc
860 return (DoLet fc i ty e))
861 <|> try (do reserved "let"; i <- pExpr' syn; reservedOp "="; fc <- pfc
863 return (DoLetP fc i sc))
864 <|> try (do i <- pName; symbol "<-"; fc <- pfc
866 return (DoBind fc i e))
867 <|> try (do i <- pExpr' syn; symbol "<-"; fc <- pfc
869 return (DoBindP fc i e))
870 <|> try (do e <- pExpr syn; fc <- pfc
874 = do symbol "[|"; fc <- pfc; e <- pExpr syn; symbol "|]"
877pConstant :: IParser Const
878pConstant = do reserved "Integer";return BIType
879 <|> do reserved "Int"; return IType
880 <|> do reserved "Char"; return ChType
881 <|> do reserved "Float"; return FlType
882 <|> do reserved "String"; return StrType
883 <|> do reserved "Ptr"; return PtrType
884 <|> try (do f <- float; return $ Fl f)
885 <|> try (do i <- natural; lchar 'L'; return $ BI i)
886 <|> try (do i <- natural; return $ I (fromInteger i))
887 <|> try (do s <- strlit; return $ Str s)
888 <|> try (do c <- chlit; return $ Ch c)
890pStatic :: IParser Static
891pStatic = do lchar '['; reserved "static"; lchar ']';
896 = [[prefix "-" (\fc x -> PApp fc (PRef fc (UN "-"))
897 [pexp (PApp fc (PRef fc (UN "fromInteger")) [pexp (PConstant (I 0))]), pexp x])]]
898 ++ toTable (reverse fixes) ++
899 [[binary "=" (\fc x y -> PEq fc x y) AssocLeft],
900 [binary "->" (\fc x y -> PPi expl (MN 42 "__pi_arg") x y) AssocRight]]
902toTable fs = map (map toBin)
903 (groupBy (\ (Fix x _) (Fix y _) -> prec x == prec y) fs)
904 where toBin (Fix (PrefixN _) op) = prefix op
905 (\fc x -> PApp fc (PRef fc (UN op)) [pexp x])
907 = binary op (\fc x y -> PApp fc (PRef fc (UN op)) [pexp x,pexp y]) (assoc f)
908 assoc (Infixl _) = AssocLeft
909 assoc (Infixr _) = AssocRight
910 assoc (InfixN _) = AssocNone
912binary name f assoc = Infix (do { reservedOp name; fc <- pfc;
913 return (f fc) }) assoc
914prefix name f = Prefix (do { reservedOp name; fc <- pfc;
917--------- Data declarations ---------
919-- (works for classes too - 'abstract' means the data/class is visible but members not)
920accData :: Maybe Accessibility -> Name -> [Name] -> IParser ()
921accData (Just Frozen) n ns = do addAcc n (Just Frozen)
922 mapM_ (\n -> addAcc n (Just Hidden)) ns
923accData a n ns = do addAcc n a; mapM_ (\n -> addAcc n a) ns
925pRecord :: SyntaxInfo -> IParser PDecl
926pRecord syn = try (do acc <- pAccessibility
927 reserved "record"; fc <- pfc
928 tyn_in <- pfName; ty <- pTSig syn
929 let tyn = expandNS syn tyn_in
931 (cn, cty, _) <- pConstructor syn
934 return $ PRecord syn fc tyn ty cn cty)
936pData :: SyntaxInfo -> IParser PDecl
937pData syn = try (do acc <- pAccessibility
938 reserved "data"; fc <- pfc
939 tyn_in <- pfName; ty <- pTSig syn
940 let tyn = expandNS syn tyn_in
944 cons <- many (do notEndBlock
945 c <- pConstructor syn
947 return c) -- (lchar '|')
950 accData acc tyn (map (\ (n, _, _) -> n) cons)
951 return $ PData syn fc (PDatadecl tyn ty cons))
952 <|> try (do push_indent
953 acc <- pAccessibility
954 reserved "data"; fc <- pfc
955 tyn_in <- pfName; args <- many pName
956 let tyn = expandNS syn tyn_in
958 cons <- sepBy1 (pSimpleCon syn) (lchar '|')
960 let conty = mkPApp fc (PRef fc tyn) (map (PRef fc) args)
961 let ty = bindArgs (map (\a -> PSet) args) PSet
962 cons' <- mapM (\ (x, cargs, cfc) ->
963 do let cty = bindArgs cargs conty
964 return (x, cty, cfc)) cons
965 accData acc tyn (map (\ (n, _, _) -> n) cons')
966 return $ PData syn fc (PDatadecl tyn ty cons'))
969 mkPApp fc t xs = PApp fc t (map pexp xs)
971bindArgs :: [PTerm] -> PTerm -> PTerm
973bindArgs (x:xs) t = PPi expl (MN 0 "t") x (bindArgs xs t)
975pConstructor :: SyntaxInfo -> IParser (Name, PTerm, FC)
977 = do cn_in <- pfName; fc <- pfc
978 let cn = expandNS syn cn_in
980-- ty' <- implicit syn cn ty
983pSimpleCon :: SyntaxInfo -> IParser (Name, [PTerm], FC)
986 let cn = expandNS syn cn_in
988 args <- many (do notEndApp
990 return (cn, args, fc)
992--------- DSL syntax overloading ---------
994pDSL :: SyntaxInfo -> IParser PDecl
995pDSL syn = do reserved "dsl"; n <- pfName
996 open_block; push_indent
997 bs <- many1 (do notEndBlock
1001 pop_indent; close_block
1002 let dsl = mkDSL bs (dsl_info syn)
1005 setState (i { idris_dsls = addDef n dsl (idris_dsls i) })
1007 where mkDSL bs dsl = let var = lookup "variable" bs
1008 first = lookup "index_first" bs
1009 next = lookup "index_next" bs
1010 leto = lookup "let" bs
1011 lambda = lookup "lambda" bs in
1012 initDSL { dsl_var = var,
1013 index_first = first,
1015 dsl_lambda = lambda,
1018checkDSL :: DSL -> IParser ()
1019checkDSL dsl = return ()
1021pOverload :: SyntaxInfo -> IParser (String, PTerm)
1022pOverload syn = do o <- identifier <|> do reserved "let"; return "let"
1023 if (not (o `elem` overloadable))
1024 then fail $ show o ++ " is not an overloading"
1029 where overloadable = ["let","lambda","index_first","index_next","variable"]
1031--------- Pattern match clauses ---------
1033pPattern :: SyntaxInfo -> IParser PDecl
1034pPattern syn = do clause <- pClause syn
1036 return (PClauses fc [] (MN 2 "_") [clause]) -- collect together later
1038pArgExpr syn = let syn' = syn { inPattern = True } in
1039 try (pHSimpleExpr syn') <|> pSimpleExtExpr syn'
1041pRHS :: SyntaxInfo -> Name -> IParser PTerm
1042pRHS syn n = do lchar '='; pExpr syn
1043 <|> do symbol "?="; rhs <- pExpr syn;
1044 return (PLet (UN "value") Placeholder rhs (PMetavar n'))
1045 <|> do reserved "impossible"; return PImpossible
1046 where mkN (UN x) = UN (x++"_lemma_1")
1047 mkN (NS x n) = NS (mkN x) n
1050pClause :: SyntaxInfo -> IParser PClause
1052 = try (do push_indent
1053 n_in <- pfName; let n = expandNS syn n_in
1054 cargs <- many (pConstraintArg syn)
1055 iargs <- many (pImplicitArg syn)
1057 args <- many (pArgExpr syn)
1058 wargs <- many (pWExpr syn)
1061 let ctxt = tt_ctxt ist
1062 let wsyn = syn { syn_namespace = [] }
1063 (wheres, nmap) <- choice [do x <- pWhereblock n wsyn
1068 let capp = PApp fc (PRef fc n)
1069 (iargs ++ cargs ++ map pexp args)
1071 setState (ist { lastParse = Just n })
1072 return $ PClause n capp wargs rhs wheres)
1073 <|> try (do push_indent
1074 wargs <- many1 (pWExpr syn)
1076 n <- case lastParse ist of
1078 Nothing -> fail "Invalid clause"
1080 let ctxt = tt_ctxt ist
1081 let wsyn = syn { syn_namespace = [] }
1082 (wheres, nmap) <- choice [do x <- pWhereblock n wsyn
1087 return $ PClauseR wargs rhs wheres)
1089 <|> try (do push_indent
1090 n_in <- pfName; let n = expandNS syn n_in
1091 cargs <- many (pConstraintArg syn)
1092 iargs <- many (pImplicitArg syn)
1094 args <- many (pArgExpr syn)
1095 wargs <- many (pWExpr syn)
1096 let capp = PApp fc (PRef fc n)
1097 (iargs ++ cargs ++ map pexp args)
1099 wval <- pSimpleExpr syn
1101 ds <- many1 $ pFunDecl syn
1102 let withs = map (fillLHSD n capp wargs) $ concat ds
1105 setState (ist { lastParse = Just n })
1107 return $ PWith n capp wargs wval withs)
1109 <|> try (do wargs <- many1 (pWExpr syn)
1111 wval <- pSimpleExpr syn
1113 ds <- many1 $ pFunDecl syn
1114 let withs = concat ds
1116 return $ PWithR wargs wval withs)
1121 let n = expandNS syn (UN op)
1124 wargs <- many (pWExpr syn)
1126 let wsyn = syn { syn_namespace = [] }
1127 (wheres, nmap) <- choice [do x <- pWhereblock n wsyn
1133 let capp = PApp fc (PRef fc n) [pexp l, pexp r]
1134 setState (ist { lastParse = Just n })
1135 return $ PClause n capp wargs rhs wheres
1137 <|> do l <- pArgExpr syn
1139 let n = expandNS syn (UN op)
1142 wargs <- many (pWExpr syn)
1144 wval <- pSimpleExpr syn
1146 ds <- many1 $ pFunDecl syn
1149 let capp = PApp fc (PRef fc n) [pexp l, pexp r]
1150 let withs = map (fillLHSD n capp wargs) $ concat ds
1151 setState (ist { lastParse = Just n })
1152 return $ PWith n capp wargs wval withs
1154 fillLHS n capp owargs (PClauseR wargs v ws)
1155 = PClause n capp (owargs ++ wargs) v ws
1156 fillLHS n capp owargs (PWithR wargs v ws)
1157 = PWith n capp (owargs ++ wargs) v
1158 (map (fillLHSD n capp (owargs ++ wargs)) ws)
1161 fillLHSD n c a (PClauses fc o fn cs) = PClauses fc o fn (map (fillLHS n c a) cs)
1162 fillLHSD n c a x = x
1164pWExpr :: SyntaxInfo -> IParser PTerm
1165pWExpr syn = do lchar '|'; pExpr' syn
1167pWhereblock :: Name -> SyntaxInfo -> IParser ([PDecl], [(Name, Name)])
1169 = do reserved "where"; open_block
1170 ds <- many1 $ pFunDecl syn
1171 let dns = concatMap (concatMap declared) ds
1173 return (concat ds, map (\x -> (x, decoration syn x)) dns)
1175pDirective :: IParser [PDecl]
1176pDirective = try (do lchar '%'; reserved "lib"; lib <- strlit;
1177 return [PDirective (do addLib lib
1178 addIBC (IBCLib lib))])
1179 <|> try (do lchar '%'; reserved "link"; obj <- strlit;
1180 return [PDirective (do datadir <- liftIO $ getDataDir
1181 o <- liftIO $ findInPath [".", datadir] obj
1184 <|> try (do lchar '%'; reserved "include"; hdr <- strlit;
1185 return [PDirective (do addHdr hdr
1186 addIBC (IBCHeader hdr))])
1187 <|> try (do lchar '%'; reserved "hide"; n <- iName []
1188 return [PDirective (do setAccessibility n Hidden
1189 addIBC (IBCAccess n Hidden))])
1190 <|> try (do lchar '%'; reserved "freeze"; n <- iName []
1191 return [PDirective (do setAccessibility n Frozen
1192 addIBC (IBCAccess n Frozen))])
1193 <|> try (do lchar '%'; reserved "access"; acc <- pAccessibility'
1194 return [PDirective (do i <- getIState
1195 putIState (i { default_access = acc }))])
1196 <|> do lchar '%'; reserved "logging"; i <- natural;
1197 return [PDirective (setLogLevel (fromInteger i))]
1199pTactic :: SyntaxInfo -> IParser PTactic
1200pTactic syn = do reserved "intro"; ns <- sepBy pName (lchar ',')
1202 <|> do reserved "intros"; return Intros
1203 <|> try (do reserved "refine"; n <- pName
1205 return $ Refine n imps)
1206 <|> do reserved "refine"; n <- pName
1208 return $ Refine n []
1209 <|> do reserved "rewrite"; t <- pExpr syn;
1211 return $ Rewrite (desugar syn i t)
1212 <|> do reserved "let"; n <- pName; lchar '=';
1215 return $ LetTac n (desugar syn i t)
1216 <|> do reserved "focus"; n <- pName
1218 <|> do reserved "exact"; t <- pExpr syn;
1220 return $ Exact (desugar syn i t)
1221 <|> do reserved "try"; t <- pTactic syn;
1231 <|> do reserved "compute"; return Compute
1232 <|> do reserved "trivial"; return Trivial
1233 <|> do reserved "solve"; return Solve
1234 <|> do reserved "attack"; return Attack
1235 <|> do reserved "state"; return ProofState
1236 <|> do reserved "term"; return ProofTerm
1237 <|> do reserved "undo"; return Undo
1238 <|> do reserved "qed"; return Qed
1239 <|> do reserved "abandon"; return Abandon
1240 <|> do lchar ':'; reserved "q"; return Abandon
1242 imp = do lchar '?'; return False
1243 <|> 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