2Module : Idris.Parser.Expr
3Description : Parse Expressions.
6Maintainer : The Idris Community.
8{-# LANGUAGE ConstraintKinds, FlexibleContexts, GeneralizedNewtypeDeriving,
9 PatternGuards, TupleSections #-}
10module Idris.Parser.Expr where
16import Idris.Parser.Helpers
17import Idris.Parser.Ops
19import Prelude hiding (pi)
21import Control.Applicative
22import Control.Arrow (left)
24import Control.Monad.State.Strict
25import Data.Function (on)
28import qualified Text.Parser.Token as Tok
29import Text.Parser.Expression
30import Text.Megaparsec ((<?>))
31import qualified Text.Megaparsec as P
32import qualified Text.Megaparsec.Char as P
34-- | Allow implicit type declarations
35allowImp :: SyntaxInfo -> SyntaxInfo
36allowImp syn = syn { implicitAllowed = True,
37 constraintAllowed = False }
39-- | Disallow implicit type declarations
40disallowImp :: SyntaxInfo -> SyntaxInfo
41disallowImp = scopedImp
43-- | Implicits hare are scoped rather than top level
44scopedImp :: SyntaxInfo -> SyntaxInfo
45scopedImp syn = syn { implicitAllowed = False,
46 constraintAllowed = False }
48-- | Allow scoped constraint arguments
49allowConstr :: SyntaxInfo -> SyntaxInfo
50allowConstr syn = syn { constraintAllowed = True }
52{-| Parses an expression as a whole
54 FullExpr ::= Expr EOF_t;
57fullExpr :: SyntaxInfo -> IdrisParser PTerm
58fullExpr syn = do x <- expr syn
61 return $ debindApp syn (desugar syn i x)
63tryFullExpr :: SyntaxInfo -> IState -> String -> Either Err PTerm
64tryFullExpr syn st = left (Msg . show . parseErrorDoc) . runparser (fullExpr syn) st ""
66{- | Parses an expression
71expr :: SyntaxInfo -> IdrisParser PTerm
74{- | Parses an expression with possible operator applied
76 OpExpr ::= {- Expression Parser with Operators based on Expr' -};
79opExpr :: SyntaxInfo -> IdrisParser PTerm
80opExpr syn = do i <- get
81 buildExpressionParser (table (idris_infixes i))
84{- | Parses either an internally defined expression or
87Expr' ::= "External (User-defined) Syntax"
91expr' :: SyntaxInfo -> IdrisParser PTerm
92expr' syn = P.try (externalExpr syn)
96{- | Parses a user-defined expression -}
97externalExpr :: SyntaxInfo -> IdrisParser PTerm
98externalExpr syn = do i <- get
99 (FC fn start _) <- getFC
100 expr <- extensions syn (syntaxRulesList $ syntax_rules i)
101 (FC _ _ end) <- getFC
102 let outerFC = FC fn start end
103 return (mapPTermFC (fixFC outerFC) (fixFCH fn outerFC) expr)
104 <?> "user-defined expression"
105 where -- Fix non-highlighting FCs by approximating with the span of the syntax application
106 fixFC outer inner | inner `fcIn` outer = inner
108 -- Fix highlighting FCs by making them useless, to avoid spurious highlights
109 fixFCH fn outer inner | inner `fcIn` outer = inner
110 | otherwise = FileFC fn
112{- | Parses a simple user-defined expression -}
113simpleExternalExpr :: SyntaxInfo -> IdrisParser PTerm
114simpleExternalExpr syn = do i <- get
115 extensions syn (filter isSimple (syntaxRulesList $ syntax_rules i))
117 isSimple (Rule (Expr x:xs) _ _) = False
118 isSimple (Rule (SimpleExpr x:xs) _ _) = False
119 isSimple (Rule [Keyword _] _ _) = True
120 isSimple (Rule [Symbol _] _ _) = True
121 isSimple (Rule (_:xs) _ _) = case last xs of
127{- | Tries to parse a user-defined expression given a list of syntactic extensions -}
128extensions :: SyntaxInfo -> [Syntax] -> IdrisParser PTerm
129extensions syn rules = extension syn [] (filter isValid rules)
130 <?> "user-defined expression"
132 isValid :: Syntax -> Bool
133 isValid (Rule _ _ AnySyntax) = True
134 isValid (Rule _ _ PatternSyntax) = inPattern syn
135 isValid (Rule _ _ TermSyntax) = not (inPattern syn)
136 isValid (DeclRule _ _) = False
138data SynMatch = SynTm PTerm | SynBind FC Name -- ^ the FC is for highlighting information
141extension :: SyntaxInfo -> [Maybe (Name, SynMatch)] -> [Syntax] -> IdrisParser PTerm
142extension syn ns rules =
143 P.choice $ flip map (groupBy (ruleGroup `on` syntaxSymbols) rules) $ \rs ->
144 case head rs of -- can never be []
145 Rule (symb:_) _ _ -> P.try $ do
146 n <- extensionSymbol symb
147 extension syn (n : ns) [Rule ss t ctx | (Rule (_:ss) t ctx) <- rs]
148 -- If we have more than one Rule in this bucket, our grammar is
150 Rule [] ptm _ -> return (flatten (updateSynMatch (mapMaybe id ns) ptm))
152 ruleGroup [] [] = True
153 ruleGroup (s1:_) (s2:_) = s1 == s2
154 ruleGroup _ _ = False
156 extensionSymbol :: SSymbol -> IdrisParser (Maybe (Name, SynMatch))
157 extensionSymbol (Keyword n) = do fc <- reservedFC (show n)
158 highlightP fc AnnKeyword
160 extensionSymbol (Expr n) = do tm <- expr syn
161 return $ Just (n, SynTm tm)
162 extensionSymbol (SimpleExpr n) = do tm <- simpleExpr syn
163 return $ Just (n, SynTm tm)
164 extensionSymbol (Binding n) = do (b, fc) <- name
165 return $ Just (n, SynBind fc b)
166 extensionSymbol (Symbol s) = do fc <- symbolFC s
167 highlightP fc AnnKeyword
170 flatten :: PTerm -> PTerm -- flatten application
171 flatten (PApp fc (PApp _ f as) bs) = flatten (PApp fc f (as ++ bs))
174updateSynMatch = update
176 updateB :: [(Name, SynMatch)] -> (Name, FC) -> (Name, FC)
177 updateB ns (n, fc) = case lookup n ns of
178 Just (SynBind tfc t) -> (t, tfc)
181 update :: [(Name, SynMatch)] -> PTerm -> PTerm
182 update ns (PRef fc hls n) = case lookup n ns of
185 update ns (PPatvar fc n) = uncurry (flip PPatvar) $ updateB ns (n, fc)
186 update ns (PLam fc n nfc ty sc)
187 = let (n', nfc') = updateB ns (n, nfc)
188 in PLam fc n' nfc' (update ns ty) (update (dropn n ns) sc)
189 update ns (PPi p n fc ty sc)
190 = let (n', nfc') = updateB ns (n, fc)
191 in PPi (updTacImp ns p) n' nfc'
192 (update ns ty) (update (dropn n ns) sc)
193 update ns (PLet fc rc n nfc ty val sc)
194 = let (n', nfc') = updateB ns (n, nfc)
195 in PLet fc rc n' nfc' (update ns ty)
196 (update ns val) (update (dropn n ns) sc)
197 update ns (PApp fc t args)
198 = PApp fc (update ns t) (map (fmap (update ns)) args)
199 update ns (PAppBind fc t args)
200 = PAppBind fc (update ns t) (map (fmap (update ns)) args)
201 update ns (PMatchApp fc n) = let (n', nfc') = updateB ns (n, fc)
203 update ns (PIfThenElse fc c t f)
204 = PIfThenElse fc (update ns c) (update ns t) (update ns f)
205 update ns (PCase fc c opts)
206 = PCase fc (update ns c) (map (pmap (update ns)) opts)
207 update ns (PRewrite fc by eq tm mty)
208 = PRewrite fc by (update ns eq) (update ns tm) (fmap (update ns) mty)
209 update ns (PPair fc hls p l r) = PPair fc hls p (update ns l) (update ns r)
210 update ns (PDPair fc hls p l t r)
211 = PDPair fc hls p (update ns l) (update ns t) (update ns r)
212 update ns (PAs fc n t) = PAs fc (fst $ updateB ns (n, NoFC)) (update ns t)
213 update ns (PAlternative ms a as) = PAlternative ms a (map (update ns) as)
214 update ns (PHidden t) = PHidden (update ns t)
215 update ns (PGoal fc r n sc) = PGoal fc (update ns r) n (update ns sc)
216 update ns (PDoBlock ds) = PDoBlock $ map (upd ns) ds
217 where upd :: [(Name, SynMatch)] -> PDo -> PDo
218 upd ns (DoExp fc t) = DoExp fc (update ns t)
219 upd ns (DoBind fc n nfc t) = DoBind fc n nfc (update ns t)
220 upd ns (DoLet fc rc n nfc ty t) = DoLet fc rc n nfc (update ns ty) (update ns t)
221 upd ns (DoBindP fc i t ts)
222 = DoBindP fc (update ns i) (update ns t)
223 (map (\(l,r) -> (update ns l, update ns r)) ts)
224 upd ns (DoLetP fc i t) = DoLetP fc (update ns i) (update ns t)
225 upd ns (DoRewrite fc h) = DoRewrite fc (update ns h)
226 update ns (PIdiom fc t) = PIdiom fc $ update ns t
227 update ns (PMetavar fc n) = uncurry (flip PMetavar) $ updateB ns (n, fc)
228 update ns (PProof tacs) = PProof $ map (updTactic ns) tacs
229 update ns (PTactics tacs) = PTactics $ map (updTactic ns) tacs
230 update ns (PDisamb nsps t) = PDisamb nsps $ update ns t
231 update ns (PUnifyLog t) = PUnifyLog $ update ns t
232 update ns (PNoImplicits t) = PNoImplicits $ update ns t
233 update ns (PQuasiquote tm mty) = PQuasiquote (update ns tm) (fmap (update ns) mty)
234 update ns (PUnquote t) = PUnquote $ update ns t
235 update ns (PQuoteName n res fc) = let (n', fc') = (updateB ns (n, fc))
236 in PQuoteName n' res fc'
237 update ns (PRunElab fc t nsp) = PRunElab fc (update ns t) nsp
238 update ns (PConstSugar fc t) = PConstSugar fc $ update ns t
239 -- PConstSugar probably can't contain anything substitutable, but it's hard to track
242 updTactic :: [(Name, SynMatch)] -> PTactic -> PTactic
243 -- handle all the ones with Names explicitly, then use fmap for the rest with PTerms
244 updTactic ns (Intro ns') = Intro $ map (fst . updateB ns . (, NoFC)) ns'
245 updTactic ns (Focus n) = Focus . fst $ updateB ns (n, NoFC)
246 updTactic ns (Refine n bs) = Refine (fst $ updateB ns (n, NoFC)) bs
247 updTactic ns (Claim n t) = Claim (fst $ updateB ns (n, NoFC)) (update ns t)
248 updTactic ns (MatchRefine n) = MatchRefine (fst $ updateB ns (n, NoFC))
249 updTactic ns (LetTac n t) = LetTac (fst $ updateB ns (n, NoFC)) (update ns t)
250 updTactic ns (LetTacTy n ty tm) = LetTacTy (fst $ updateB ns (n, NoFC)) (update ns ty) (update ns tm)
251 updTactic ns (ProofSearch rec prover depth top psns hints) = ProofSearch rec prover depth
252 (fmap (fst . updateB ns . (, NoFC)) top) (map (fst . updateB ns . (, NoFC)) psns) (map (fst . updateB ns . (, NoFC)) hints)
253 updTactic ns (Try l r) = Try (updTactic ns l) (updTactic ns r)
254 updTactic ns (TSeq l r) = TSeq (updTactic ns l) (updTactic ns r)
255 updTactic ns (GoalType s tac) = GoalType s $ updTactic ns tac
256 updTactic ns (TDocStr (Left n)) = TDocStr . Left . fst $ updateB ns (n, NoFC)
257 updTactic ns t = fmap (update ns) t
259 updTacImp ns (TacImp o st scr r) = TacImp o st (update ns scr) r
262 dropn :: Name -> [(Name, a)] -> [(Name, a)]
264 dropn n ((x,t) : xs) | n == x = xs
265 | otherwise = (x,t):dropn n xs
268{- | Parses a (normal) built-in expression
285internalExpr :: SyntaxInfo -> IdrisParser PTerm
302{- | Parses the "impossible" keyword
304Impossible ::= 'impossible'
307impossible :: IdrisParser PTerm
308impossible = do fc <- reservedFC "impossible"
309 highlightP fc AnnKeyword
312{- | Parses a case expression
315 'case' Expr 'of' OpenBlock CaseOption+ CloseBlock;
318caseExpr :: SyntaxInfo -> IdrisParser PTerm
319caseExpr syn = do kw1 <- reservedFC "case"; fc <- getFC
320 scr <- expr syn; kw2 <- reservedFC "of";
321 opts <- indentedBlock1 (caseOption syn)
322 highlightP kw1 AnnKeyword
323 highlightP kw2 AnnKeyword
324 return (PCase fc scr opts)
325 <?> "case expression"
327{- | Parses a case in a case expression
330 Expr (Impossible | '=>' Expr) Terminator
334caseOption :: SyntaxInfo -> IdrisParser (PTerm, PTerm)
335caseOption syn = do lhs <- expr (disallowImp (syn { inPattern = True }))
336 r <- impossible <|> symbol "=>" *> expr syn
340warnTacticDeprecation :: FC -> IdrisParser ()
341warnTacticDeprecation fc =
342 parserWarning fc (Just NoOldTacticDeprecationWarnings) (Msg "This style of tactic proof is deprecated. See %runElab for the replacement.")
344{- | Parses a proof block
347 'proof' OpenBlock Tactic'* CloseBlock
351proofExpr :: SyntaxInfo -> IdrisParser PTerm
352proofExpr syn = do kw <- reservedFC "proof"
353 ts <- indentedBlock1 (tactic syn)
354 highlightP kw AnnKeyword
355 warnTacticDeprecation kw
359{- | Parses a tactics block
362 'tactics' OpenBlock Tactic'* CloseBlock
366tacticsExpr :: SyntaxInfo -> IdrisParser PTerm
367tacticsExpr syn = do kw <- reservedFC "tactics"
368 ts <- indentedBlock1 (tactic syn)
369 highlightP kw AnnKeyword
370 warnTacticDeprecation kw
374{- | Parses a simple expression
377 {- External (User-defined) Simple Expression -}
380 | 'Refl' ('{' Expr '}')?
398simpleExpr :: SyntaxInfo -> IdrisParser PTerm
400 P.try (simpleExternalExpr syn)
401 <|> do (x, FC f (l, c) end) <- P.try (lchar '?' *> name)
402 return (PMetavar (FC f (l, c-1) end) x)
403 <|> do lchar '%'; fc <- getFC; reserved "implementation"; return (PResolveTC fc)
404 <|> do lchar '%'; fc <- getFC; reserved "instance"
405 parserWarning fc Nothing $ Msg "The use of %instance is deprecated, use %implementation instead."
406 return (PResolveTC fc)
407 <|> do reserved "elim_for"; fc <- getFC; t <- fst <$> fnName; return (PRef fc [] (SN $ ElimN t))
410 <|> P.try (do fc <- reservedFC "Type*"; return $ PUniverse fc AllTypes)
411 <|> do fc <- reservedFC "AnyType"; return $ PUniverse fc AllTypes
412 <|> PType <$> reservedFC "Type"
413 <|> do fc <- reservedFC "UniqueType"; return $ PUniverse fc UniqueType
414 <|> do fc <- reservedFC "NullType"; return $ PUniverse fc NullType
415 <|> do (c, cfc) <- constant
417 return (modifyConst syn fc (PConstant cfc c))
418 <|> do symbol "'"; fc <- getFC; str <- fst <$> name
419 return (PApp fc (PRef fc [] (sUN "Symbol_"))
420 [pexp (PConstant NoFC (Str (show str)))])
421 <|> do (x, fc) <- fnName
423 then P.option (PRef fc [fc] x)
427 return (PAs fcIn x s))
428 else return (PRef fc [fc] x)
432 <|> do reservedOp "!"
435 return (PAppBind fc s [])
436 <|> bracketed (disallowImp syn)
440 <|> do lchar '_'; return Placeholder
443{- |Parses an expression in parentheses
445Bracketed ::= '(' Bracketed'
448bracketed :: SyntaxInfo -> IdrisParser PTerm
449bracketed syn = do (FC fn (sl, sc) _) <- getFC
450 lchar '(' <?> "parenthesized expression"
451 bracketed' (FC fn (sl, sc) (sl, sc+1)) (syn { withAppAllowed = True })
453{- |Parses the rest of an expression in braces
465bracketed' :: FC -> SyntaxInfo -> IdrisParser PTerm
467 do (FC f start (l, c)) <- getFC
469 return $ PTrue (spanFC open (FC f start (l, c+1))) TypeOrTerm
470 <|> P.try (dependentPair TypeOrTerm [] open syn)
471 <|> P.try (do (opName, fc) <- operatorName
472 guardNotPrefix opName
476 return $ PLam fc (sMN 1000 "ARG") NoFC Placeholder
477 (PApp fc (PRef fc [] opName) [pexp (PRef fc [] (sMN 1000 "ARG")),
479 <|> P.try (simpleExpr syn >>= \l ->
480 P.try (do (opName, _) <- operatorName
483 return $ PLam fc (sMN 1000 "ARG") NoFC Placeholder
484 (PApp fc (PRef fc [] opName) [pexp l,
485 pexp (PRef fc [] (sMN 1000 "ARG"))]))
486 <|> bracketedExpr syn open l)
487 <|> do l <- expr (allowConstr syn)
488 bracketedExpr (allowConstr syn) open l
490 justPrefix :: FixDecl -> Maybe Name
491 justPrefix (Fix (PrefixN _) opName) = Just (sUN opName)
492 justPrefix _ = Nothing
494 guardNotPrefix :: Name -> IdrisParser ()
495 guardNotPrefix opName = do
496 guard $ opName /= sUN "-"
497 guard $ opName /= sUN "!"
499 ops <- idris_infixes <$> get
500 guard . not . (opName `elem`) . mapMaybe justPrefix $ ops
502{-| Parses the rest of a dependent pair after '(' or '(Expr **' -}
503dependentPair :: PunInfo -> [(PTerm, Maybe (FC, PTerm), FC)] -> FC -> SyntaxInfo -> IdrisParser PTerm
504dependentPair pun prev openFC syn =
506 nametypePart <|> namePart
509 IsType -> nametypePart <|> namePart <|> exprPart True
510 IsTerm -> exprPart False
511 TypeOrTerm -> nametypePart <|> namePart <|> exprPart False
512 where nametypePart = do
513 (ln, lnfc, colonFC) <- P.try $ do
515 colonFC <- lcharFC ':'
516 return (ln, lnfc, colonFC)
518 starsFC <- reservedOpFC "**"
519 dependentPair IsType ((PRef lnfc [] ln, Just (colonFC, lty), starsFC):prev) openFC syn
520 namePart = P.try $ do
522 starsFC <- reservedOpFC "**"
523 dependentPair pun ((PRef lnfc [] ln, Nothing, starsFC):prev) openFC syn
527 let stars = (Left <$> reservedOpFC "**")
528 ending = (Right <$> lcharFC ')')
529 in if isEnd then ending else stars <|> ending
531 Left starsFC -> dependentPair IsTerm ((e, Nothing, starsFC):prev) openFC syn
533 return (mkPDPairs pun openFC closeFC (reverse prev) e)
534 mkPDPairs pun openFC closeFC ((e, cfclty, starsFC):bnds) r =
535 (PDPair openFC ([openFC] ++ maybe [] ((: []) . fst) cfclty ++ [starsFC, closeFC] ++ (=<<) (\(_,cfclty,sfc) -> maybe [] ((: []) . fst) cfclty ++ [sfc]) bnds)
536 pun e (maybe Placeholder snd cfclty) (mergePDPairs pun starsFC bnds r))
537 mergePDPairs pun starsFC' [] r = r
538 mergePDPairs pun starsFC' ((e, cfclty, starsFC):bnds) r =
539 PDPair starsFC' [] pun e (maybe Placeholder snd cfclty) (mergePDPairs pun starsFC bnds r)
541-- | Parse the contents of parentheses, after an expression has been parsed.
542bracketedExpr :: SyntaxInfo -> FC -> PTerm -> IdrisParser PTerm
543bracketedExpr syn openParenFC e =
544 do lchar ')'; return e
545 <|> do exprs <- some (do comma <- lcharFC ','
548 closeParenFC <- lcharFC ')'
549 let hilite = [openParenFC, closeParenFC] ++ map snd exprs
550 return $ PPair openParenFC hilite TypeOrTerm e (mergePairs exprs)
551 <|> do starsFC <- reservedOpFC "**"
552 dependentPair IsTerm [(e, Nothing, starsFC)] openParenFC syn
553 <?> "end of bracketed expression"
554 where mergePairs :: [(PTerm, FC)] -> PTerm
555 mergePairs [(t, fc)] = t
556 mergePairs ((t, fc):rs) = PPair fc [] TypeOrTerm t (mergePairs rs)
558-- bit of a hack here. If the integer doesn't fit in an Int, treat it as a
559-- big integer, otherwise try fromInteger and the constants as alternatives.
560-- a better solution would be to fix fromInteger to work with Integer, as the
561-- name suggests, rather than Int
562{-| Finds optimal type for integer constant -}
563modifyConst :: SyntaxInfo -> FC -> PTerm -> PTerm
564modifyConst syn fc (PConstant inFC (BI x))
565 | not (inPattern syn)
566 = PConstSugar inFC $ -- wrap in original location for highlighting
567 PAlternative [] FirstSuccess
568 (PApp fc (PRef fc [] (sUN "fromInteger")) [pexp (PConstant NoFC (BI (fromInteger x)))]
570 | otherwise = PConstSugar inFC $
571 PAlternative [] FirstSuccess consts
573 consts = [ PConstant inFC (BI x)
574 , PConstant inFC (I (fromInteger x))
575 , PConstant inFC (B8 (fromInteger x))
576 , PConstant inFC (B16 (fromInteger x))
577 , PConstant inFC (B32 (fromInteger x))
578 , PConstant inFC (B64 (fromInteger x))
580modifyConst syn fc x = x
582{- | Parses an alternative expression
584 Alt ::= '(|' Expr_List '|)';
588 | Expr' ',' Expr_List
592alt :: SyntaxInfo -> IdrisParser PTerm
593alt syn = do symbol "(|"; alts <- P.sepBy1 (expr' (syn { withAppAllowed = False })) (lchar ','); symbol "|)"
594 return (PAlternative [] FirstSuccess alts)
596{- | Parses a possibly hidden simple expression
604hsimpleExpr :: SyntaxInfo -> IdrisParser PTerm
612{- | Parses a unification log expression
614 '%' 'unifyLog' SimpleExpr
617unifyLog :: SyntaxInfo -> IdrisParser PTerm
618unifyLog syn = do (FC fn (sl, sc) kwEnd) <- P.try (lchar '%' *> reservedFC "unifyLog")
620 highlightP (FC fn (sl, sc-1) kwEnd) AnnKeyword
621 return (PUnifyLog tm)
622 <?> "unification log expression"
624{- | Parses a new-style tactics expression
626 '%' 'runElab' SimpleExpr
629runElab :: SyntaxInfo -> IdrisParser PTerm
630runElab syn = do (FC fn (sl, sc) kwEnd) <- P.try (lchar '%' *> reservedFC "runElab")
633 highlightP (FC fn (sl, sc-1) kwEnd) AnnKeyword
634 return $ PRunElab fc tm (syn_namespace syn)
635 <?> "new-style tactics expression"
637{- | Parses a disambiguation expression
642disamb :: SyntaxInfo -> IdrisParser PTerm
643disamb syn = do kw <- reservedFC "with"
644 ns <- P.sepBy1 (fst <$> name) (lchar ',')
646 highlightP kw AnnKeyword
647 return (PDisamb (map tons ns) tm)
648 <?> "namespace disambiguation expression"
649 where tons (NS n s) = txt (show n) : s
650 tons n = [txt (show n)]
651{- | Parses a no implicits expression
654 '%' 'noImplicits' SimpleExpr
658noImplicits :: SyntaxInfo -> IdrisParser PTerm
659noImplicits syn = do P.try (lchar '%' *> reserved "noImplicits")
661 return (PNoImplicits tm)
662 <?> "no implicits expression"
664{- | Parses a function application expression
672 SimpleExpr '<==' FnName
676app :: SyntaxInfo -> IdrisParser PTerm
677app syn = do f <- simpleExpr syn
678 (do P.try $ reservedOp "<=="
681 return (PLet fc RigW (sMN 0 "match") NoFC
684 (PRef fc [] (sMN 0 "match")))
685 <?> "matching application expression") <|>
688 args <- many (do notEndApp; arg syn)
689 wargs <- if withAppAllowed syn && not (inPattern syn)
690 then many (do notEndApp; reservedOp "|"; expr' syn)
694 _ -> return (withApp fc (flattenFromInt fc f args) wargs))
695 <?> "function application"
697 -- bit of a hack to deal with the situation where we're applying a
698 -- literal to an argument, which we may want for obscure applications
699 -- of fromInteger, and this will help disambiguate better.
700 -- We know, at least, it won't be one of the constants!
701 flattenFromInt fc (PAlternative _ x alts) args
702 | Just i <- getFromInt alts
703 = PApp fc (PRef fc [] (sUN "fromInteger")) (i : args)
704 flattenFromInt fc f args = PApp fc f args
706 withApp fc tm [] = tm
707 withApp fc tm (a : as) = withApp fc (PWithApp fc tm a) as
709 getFromInt ((PApp _ (PRef _ _ n) [a]) : _) | n == sUN "fromInteger" = Just a
710 getFromInt (_ : xs) = getFromInt xs
711 getFromInt _ = Nothing
713{-| Parses a function argument
722arg :: SyntaxInfo -> IdrisParser PArg
723arg syn = implicitArg syn
724 <|> constraintArg syn
725 <|> do e <- simpleExpr syn
727 <?> "function argument"
729{-| Parses an implicit function argument
732 '{' Name ('=' Expr)? '}'
736implicitArg :: SyntaxInfo -> IdrisParser PArg
737implicitArg syn = do lchar '{'
740 v <- P.option (PRef nfc [nfc] n) (do lchar '='
743 return (pimp n v True)
744 <?> "implicit function argument"
746{-| Parses a constraint argument (for selecting a named interface implementation)
753constraintArg :: SyntaxInfo -> IdrisParser PArg
754constraintArg syn = do symbol "@{"
758 <?> "constraint argument"
760{-| Parses a quasiquote expression (for building reflected terms using the elaborator)
762> Quasiquote ::= '`(' Expr ')'
765quasiquote :: SyntaxInfo -> IdrisParser PTerm
766quasiquote syn = do startFC <- symbolFC "`("
767 e <- expr syn { syn_in_quasiquote = (syn_in_quasiquote syn) + 1 ,
770 do fc <- symbolFC ":"
771 ty <- expr syn { inPattern = False } -- don't allow antiquotes
773 endFC <- symbolFC ")"
774 mapM_ (uncurry highlightP) [(startFC, AnnKeyword), (endFC, AnnKeyword), (spanFC startFC endFC, AnnQuasiquote)]
776 Just (_, fc) -> highlightP fc AnnKeyword
778 return $ PQuasiquote e (fst <$> g)
781{-| Parses an unquoting inside a quasiquotation (for building reflected terms using the elaborator)
783> Unquote ::= ',' Expr
786unquote :: SyntaxInfo -> IdrisParser PTerm
787unquote syn = do guard (syn_in_quasiquote syn > 0)
788 startFC <- symbolFC "~"
789 e <- simpleExpr syn { syn_in_quasiquote = syn_in_quasiquote syn - 1 }
791 highlightP startFC AnnKeyword
792 highlightP (spanFC startFC endFC) AnnAntiquote
796{-| Parses a quotation of a name (for using the elaborator to resolve boring details)
798> NameQuote ::= '`{' Name '}'
801namequote :: SyntaxInfo -> IdrisParser PTerm
802namequote syn = do (startFC, res) <-
803 P.try (do fc <- symbolFC "`{{"
804 return (fc, False)) <|>
805 (do fc <- symbolFC "`{"
808 endFC <- if res then symbolFC "}" else symbolFC "}}"
809 mapM_ (uncurry highlightP)
810 [ (startFC, AnnKeyword)
811 , (endFC, AnnKeyword)
812 , (spanFC startFC endFC, AnnQuasiquote)
814 return $ PQuoteName n res nfc
818{-| Parses a record field setter expression
821 'record' '{' FieldTypeList '}';
826 | FieldType ',' FieldTypeList
836data SetOrUpdate = FieldSet PTerm | FieldUpdate PTerm
838recordType :: SyntaxInfo -> IdrisParser PTerm
840 do kw <- reservedFC "record"
845 rec <- optional (do notEndApp; simpleExpr syn)
846 highlightP kw AnnKeyword
851 return (PLam fc (sMN 0 "fldx") NoFC Placeholder
852 (applyAll fc fields (PRef fc [] (sMN 0 "fldx"))))
853 Just v -> return (applyAll fc fields v)
857 return (PLam fc (sMN 0 "fldx") NoFC Placeholder
858 (getAll fc (reverse fields)
859 (PRef fc [] (sMN 0 "fldx"))))
860 Just v -> return (getAll fc (reverse fields) v)
862 <?> "record setting expression"
863 where fieldSet :: IdrisParser ([Name], SetOrUpdate)
864 fieldSet = do ns <- fieldGet
867 return (ns, FieldSet e))
870 return (ns, FieldUpdate e)
873 fieldGet :: IdrisParser [Name]
874 fieldGet = P.sepBy1 (fst <$> fnName) (symbol "->")
876 fieldGetOrSet :: IdrisParser (Either [([Name], SetOrUpdate)] [Name])
877 fieldGetOrSet = P.try (Left <$> P.sepBy1 fieldSet (lchar ','))
881 applyAll :: FC -> [([Name], SetOrUpdate)] -> PTerm -> PTerm
883 applyAll fc ((ns, e) : es) x
884 = applyAll fc es (doUpdate fc ns e x)
886 doUpdate fc ns (FieldUpdate e) get
887 = let get' = getAll fc (reverse ns) get in
888 doUpdate fc ns (FieldSet (PApp fc e [pexp get'])) get
889 doUpdate fc [n] (FieldSet e) get
890 = PApp fc (PRef fc [] (mkType n)) [pexp e, pexp get]
891 doUpdate fc (n : ns) e get
892 = PApp fc (PRef fc [] (mkType n))
893 [pexp (doUpdate fc ns e (PApp fc (PRef fc [] n) [pexp get])),
896 getAll :: FC -> [Name] -> PTerm -> PTerm
897 getAll fc [n] e = PApp fc (PRef fc [] n) [pexp e]
898 getAll fc (n:ns) e = PApp fc (PRef fc [] n) [pexp (getAll fc ns e)]
901-- | Creates setters for record types on necessary functions
902mkType :: Name -> Name
903mkType (UN n) = sUN ("set_" ++ str n)
904mkType (MN 0 n) = sMN 0 ("set_" ++ str n)
905mkType (NS n s) = NS (mkType n) s
907{- | Parses a type signature
914TypeExpr ::= ConstraintList? Expr;
917typeExpr :: SyntaxInfo -> IdrisParser PTerm
918typeExpr syn = do cs <- if implicitAllowed syn then constraintList syn else return []
919 sc <- expr (allowConstr syn)
920 return (bindList (\r -> PPi (constraint { pcount = r })) cs sc)
923{- | Parses a lambda expression
926 '\\' TypeOptDeclList LambdaTail
927 | '\\' SimpleExprList LambdaTail
933 | SimpleExpr ',' SimpleExprList
942lambda :: SyntaxInfo -> IdrisParser PTerm
943lambda syn = do lchar '\\' <?> "lambda expression"
944 ((do xt <- P.try $ tyOptDeclList (disallowImp syn)
947 return (bindList (\r -> PLam fc) xt sc))
949 (do ps <- P.sepBy (do fc <- getFC
950 e <- simpleExpr (disallowImp (syn { inPattern = True }))
954 return (pmList (zip [0..] ps) sc)))
955 <?> "lambda expression"
956 where pmList :: [(Int, (FC, PTerm))] -> PTerm -> PTerm
958 pmList ((i, (fc, x)) : xs) sc
959 = PLam fc (sMN i "lamp") NoFC Placeholder
960 (PCase fc (PRef fc [] (sMN i "lamp"))
962 lambdaTail :: IdrisParser PTerm
963 lambdaTail = impossible <|> symbol "=>" *> expr syn
965{- | Parses a term rewrite expression
968 'rewrite' Expr ('==>' Expr)? 'in' Expr
972rewriteTerm :: SyntaxInfo -> IdrisParser PTerm
973rewriteTerm syn = do kw <- reservedFC "rewrite"
976 giving <- optional (do symbol "==>"; expr' syn)
977 using <- optional (do reserved "using"
980 kw' <- reservedFC "in"; sc <- expr syn
981 highlightP kw AnnKeyword
982 highlightP kw' AnnKeyword
983 return (PRewrite fc using prf sc giving)
984 <?> "term rewrite expression"
986{- |Parses a let binding
989 'let' Name TypeSig'? '=' Expr 'in' Expr
990| 'let' Expr' '=' Expr' 'in' Expr
997let_ :: SyntaxInfo -> IdrisParser PTerm
998let_ syn = P.try (do kw <- reservedFC "let"
999 ls <- indentedBlock (let_binding syn)
1000 kw' <- reservedFC "in"; sc <- expr syn
1001 highlightP kw AnnKeyword; highlightP kw' AnnKeyword
1002 return (buildLets ls sc))
1004 where buildLets [] sc = sc
1005 buildLets ((fc, PRef nfc _ n, ty, v, []) : ls) sc
1006 = PLet fc RigW n nfc ty v (buildLets ls sc)
1007 buildLets ((fc, pat, ty, v, alts) : ls) sc
1008 = PCase fc v ((pat, buildLets ls sc) : alts)
1010let_binding syn = do fc <- getFC;
1011 pat <- expr' (syn { inPattern = True })
1012 ty <- P.option Placeholder (do lchar ':'; expr' syn)
1014 v <- expr (syn { withAppAllowed = isVar pat })
1015 ts <- P.option [] (do lchar '|'
1016 P.sepBy1 (do_alt syn) (lchar '|'))
1017 return (fc,pat,ty,v,ts)
1018 where isVar (PRef _ _ _) = True
1021{- | Parses a conditional expression
1023If ::= 'if' Expr 'then' Expr 'else' Expr
1027if_ :: SyntaxInfo -> IdrisParser PTerm
1028if_ syn = (do ifFC <- reservedFC "if"
1031 thenFC <- reservedFC "then"
1033 elseFC <- reservedFC "else"
1035 mapM_ (flip highlightP AnnKeyword) [ifFC, thenFC, elseFC]
1036 return (PIfThenElse fc c t f))
1037 <?> "conditional expression"
1040{- | Parses a quote goal
1044 'quoteGoal' Name 'by' Expr 'in' Expr
1048quoteGoal :: SyntaxInfo -> IdrisParser PTerm
1049quoteGoal syn = do kw1 <- reservedFC "quoteGoal"; n <- fst <$> name;
1050 kw2 <- reservedFC "by"
1052 kw3 <- reservedFC "in"
1055 mapM_ (flip highlightP AnnKeyword) [kw1, kw2, kw3]
1056 return (PGoal fc r n sc)
1057 <?> "quote goal expression"
1059{- | Parses a dependent type signature
1062Pi ::= PiOpts Static? Pi'
1068 | '(' TypeDeclList ')' '->' Pi
1069 | '{' TypeDeclList '}' '->' Pi
1070 | '{' 'auto' TypeDeclList '}' '->' Pi
1071 | '{' 'default' SimpleExpr TypeDeclList '}' '->' Pi
1076bindsymbol opts st syn
1078 return (Exp opts st False RigW)
1080explicitPi opts st syn
1081 = do xt <- P.try (lchar '(' *> typeDeclList syn <* lchar ')')
1082 binder <- bindsymbol opts st syn
1083 sc <- expr (allowConstr syn)
1084 return (bindList (\r -> PPi (binder { pcount = r })) xt sc)
1086autoImplicit opts st syn
1087 = do kw <- reservedFC "auto"
1088 when (st == Static) $ fail "auto implicits can not be static"
1089 xt <- typeDeclList syn
1092 sc <- expr (allowConstr syn)
1093 highlightP kw AnnKeyword
1094 return (bindList (\r -> PPi
1095 (TacImp [] Dynamic (PTactics [ProofSearch True True 100 Nothing [] []]) r)) xt sc)
1097defaultImplicit opts st syn = do
1098 kw <- reservedFC "default"
1099 when (st == Static) $ fail "default implicits can not be static"
1101 script' <- simpleExpr syn
1102 let script = debindApp syn . desugar syn ist $ script'
1103 xt <- typeDeclList syn
1106 sc <- expr (allowConstr syn)
1107 highlightP kw AnnKeyword
1108 return (bindList (\r -> PPi (TacImp [] Dynamic script r)) xt sc)
1110normalImplicit opts st syn = do
1111 xt <- typeDeclList syn <* lchar '}'
1113 cs <- constraintList syn
1116 = if implicitAllowed syn
1117 then (Imp opts st False (Just (Impl False True False)) True RigW,
1119 else (Imp opts st False (Just (Impl False False False)) True RigW,
1120 Imp opts st False (Just (Impl True False False)) True RigW)
1121 return (bindList (\r -> PPi (im { pcount = r })) xt
1122 (bindList (\r -> PPi (cl { pcount = r })) cs sc))
1124constraintPi opts st syn =
1125 do cs <- constraintList1 syn
1127 if implicitAllowed syn
1128 then return (bindList (\r -> PPi constraint { pcount = r }) cs sc)
1129 else return (bindList (\r -> PPi (Imp opts st False (Just (Impl True False False)) True r))
1132implicitPi opts st syn =
1133 autoImplicit opts st syn
1134 <|> defaultImplicit opts st syn
1135 <|> normalImplicit opts st syn
1137unboundPi opts st syn = do
1139 (do binder <- bindsymbol opts st syn
1141 return (PPi binder (sUN "__pi_arg") NoFC x sc))
1144-- This is used when we need to disambiguate from a constraint list
1145unboundPiNoConstraint opts st syn = do
1147 (do binder <- bindsymbol opts st syn
1149 P.notFollowedBy $ reservedOp "=>"
1150 return (PPi binder (sUN "__pi_arg") NoFC x sc))
1151 <|> do P.notFollowedBy $ reservedOp "=>"
1155pi :: SyntaxInfo -> IdrisParser PTerm
1157 do opts <- piOpts syn
1159 explicitPi opts st syn
1160 <|> P.try (do lchar '{'; implicitPi opts st syn)
1161 <|> if constraintAllowed syn
1162 then P.try (unboundPiNoConstraint opts st syn)
1163 <|> constraintPi opts st syn
1164 else unboundPi opts st syn
1165 <?> "dependent type signature"
1167{- | Parses Possible Options for Pi Expressions
1172piOpts :: SyntaxInfo -> IdrisParser [ArgOpt]
1173piOpts syn | implicitAllowed syn =
1174 lchar '.' *> return [InaccessibleArg]
1176piOpts syn = return []
1178{- | Parses a type constraint list
1182 '(' Expr_List ')' '=>'
1187constraintList :: SyntaxInfo -> IdrisParser [(RigCount, Name, FC, PTerm)]
1188constraintList syn = P.try (constraintList1 syn)
1191constraintList1 :: SyntaxInfo -> IdrisParser [(RigCount, Name, FC, PTerm)]
1192constraintList1 syn = P.try (do lchar '('
1193 tys <- P.sepBy1 nexpr (lchar ',')
1197 <|> P.try (do t <- opExpr (disallowImp syn)
1199 return [(RigW, defname, NoFC, t)])
1200 <?> "type constraint list"
1201 where nexpr = P.try (do (n, fc) <- name; lchar ':'
1202 e <- expr (disallowImp syn)
1203 return (RigW, n, fc, e))
1204 <|> do e <- expr (disallowImp syn)
1205 return (RigW, defname, NoFC, e)
1206 defname = sMN 0 "constraint"
1208{- | Parses a type declaration list
1211 FunctionSignatureList
1217FunctionSignatureList ::=
1219 | Name TypeSig ',' FunctionSignatureList
1223typeDeclList :: SyntaxInfo -> IdrisParser [(RigCount, Name, FC, PTerm)]
1224typeDeclList syn = P.try (P.sepBy1 (do rig <- P.option RigW rigCount
1227 t <- typeExpr (disallowImp syn)
1228 return (rig, x, xfc, t))
1230 <|> do ns <- P.sepBy1 name (lchar ',')
1232 t <- typeExpr (disallowImp syn)
1233 return (map (\(x, xfc) -> (RigW, x, xfc, t)) ns)
1234 <?> "type declaration list"
1236 rigCount = do lchar '1'; return Rig1
1237 <|> do lchar '0'; return Rig0
1239{- | Parses a type declaration list with optional parameters
1242 NameOrPlaceholder TypeSig?
1243 | NameOrPlaceholder TypeSig? ',' TypeOptDeclList
1248NameOrPlaceHolder ::= Name | '_';
1251tyOptDeclList :: SyntaxInfo -> IdrisParser [(RigCount, Name, FC, PTerm)]
1252tyOptDeclList syn = P.sepBy1 (do (x, fc) <- nameOrPlaceholder
1253 t <- P.option Placeholder (do lchar ':'
1255 return (RigW, x, fc, t))
1257 <?> "type declaration list"
1258 where nameOrPlaceholder :: IdrisParser (Name, FC)
1259 nameOrPlaceholder = fnName
1261 return (sMN 0 "underscore", NoFC)
1262 <?> "name or placeholder"
1264{- | Parses a list literal expression e.g. [1,2,3] or a comprehension [ (x, y) | x <- xs , y <- ys ]
1268 | '[' Expr '|' DoList ']'
1285listExpr :: SyntaxInfo -> IdrisParser PTerm
1286listExpr syn = do (FC f (l, c) _) <- getFC
1287 lchar '['; fc <- getFC;
1288 (P.try . Tok.token $ do (char ']' <?> "end of list expression")
1289 (FC _ _ (l', c')) <- getFC
1290 return (mkNil (FC f (l, c) (l', c'))))
1291 <|> (do x <- expr (syn { withAppAllowed = False }) <?> "expression"
1292 (do P.try (lchar '|') <?> "list comprehension"
1293 qs <- P.sepBy1 (do_ syn) (lchar ',')
1295 return (PDoBlock (map addGuard qs ++
1296 [DoExp fc (PApp fc (PRef fc [] (sUN "pure"))
1298 (do xs <- many (do (FC fn (sl, sc) _) <- getFC
1299 lchar ',' <?> "list element"
1300 let commaFC = FC fn (sl, sc) (sl, sc + 1)
1302 return (elt, commaFC))
1303 (FC fn (sl, sc) _) <- getFC
1304 lchar ']' <?> "end of list expression"
1305 let rbrackFC = FC fn (sl, sc) (sl, sc+1)
1306 return (mkList fc rbrackFC ((x, (FC f (l, c) (l, c+1))) : xs))))
1307 <?> "list expression"
1309 mkNil :: FC -> PTerm
1310 mkNil fc = PRef fc [fc] (sUN "Nil")
1311 mkList :: FC -> FC -> [(PTerm, FC)] -> PTerm
1312 mkList errFC nilFC [] = PRef nilFC [nilFC] (sUN "Nil")
1313 mkList errFC nilFC ((x, fc) : xs) = PApp errFC (PRef fc [fc] (sUN "::")) [pexp x, pexp (mkList errFC nilFC xs)]
1314 addGuard :: PDo -> PDo
1315 addGuard (DoExp fc e) = DoExp fc (PApp fc (PRef fc [] (sUN "guard"))
1319{- | Parses a do-block
1321Do' ::= Do KeepTerminator;
1326 'do' OpenBlock Do'+ CloseBlock
1330doBlock :: SyntaxInfo -> IdrisParser PTerm
1332 = do kw <- reservedFC "do"
1333 ds <- indentedBlock1 (do_ syn)
1334 highlightP kw AnnKeyword
1335 return (PDoBlock ds)
1338{- | Parses an expression inside a do block
1341 'let' Name TypeSig'? '=' Expr
1342 | 'let' Expr' '=' Expr
1350do_ :: SyntaxInfo -> IdrisParser PDo
1352 = P.try (do kw <- reservedFC "let"
1354 ty <- P.option Placeholder (do lchar ':'
1359 highlightP kw AnnKeyword
1360 return (DoLet fc RigW i ifc ty e))
1361 <|> P.try (do kw <- reservedFC "let"
1366 highlightP kw AnnKeyword
1367 return (DoLetP fc i sc))
1368 <|> P.try (do kw <- reservedFC "rewrite"
1371 highlightP kw AnnKeyword
1372 return (DoRewrite fc sc))
1373 <|> P.try (do (i, ifc) <- name
1376 e <- expr (syn { withAppAllowed = False });
1377 P.option (DoBind fc i ifc e)
1379 ts <- P.sepBy1 (do_alt (syn { withAppAllowed = False })) (lchar '|')
1380 return (DoBindP fc (PRef ifc [ifc] i) e ts)))
1381 <|> P.try (do i <- expr' syn
1384 e <- expr (syn { withAppAllowed = False });
1385 P.option (DoBindP fc i e [])
1387 ts <- P.sepBy1 (do_alt (syn { withAppAllowed = False })) (lchar '|')
1388 return (DoBindP fc i e ts)))
1389 <|> do e <- expr syn
1392 <?> "do block expression"
1394do_alt syn = do l <- expr' syn
1395 P.option (Placeholder, l)
1400{- | Parses an expression in idiom brackets
1402Idiom ::= '[|' Expr '|]';
1405idiom :: SyntaxInfo -> IdrisParser PTerm
1409 e <- expr (syn { withAppAllowed = False })
1411 return (PIdiom fc e)
1412 <?> "expression in idiom brackets"
1414{- |Parses a constant or literal expression
1436constants :: [(String, Idris.Core.TT.Const)]
1438 [ ("Integer", AType (ATInt ITBig))
1439 , ("Int", AType (ATInt ITNative))
1440 , ("Char", AType (ATInt ITChar))
1441 , ("Double", AType ATFloat)
1442 , ("String", StrType)
1443 , ("prim__WorldType", WorldType)
1444 , ("prim__TheWorld", TheWorld)
1445 , ("Bits8", AType (ATInt (ITFixed IT8)))
1446 , ("Bits16", AType (ATInt (ITFixed IT16)))
1447 , ("Bits32", AType (ATInt (ITFixed IT32)))
1448 , ("Bits64", AType (ATInt (ITFixed IT64)))
1451-- | Parse a constant and its source span
1452constant :: IdrisParser (Idris.Core.TT.Const, FC)
1453constant = P.choice [ do fc <- reservedFC name; return (ty, fc)
1454 | (name, ty) <- constants
1456 <|> do (f, fc) <- P.try float; return (Fl f, fc)
1457 <|> do (i, fc) <- natural; return (BI i, fc)
1458 <|> do (s, fc) <- verbatimStringLiteral; return (Str s, fc)
1459 <|> do (s, fc) <- stringLiteral; return (Str s, fc)
1460 <|> do (c, fc) <- P.try charLiteral; return (Ch c, fc) --Currently ambigous with symbols
1461 <?> "constant or literal"
1463{- | Parses a verbatim multi-line string literal (triple-quoted)
1467 '\"\"\"' ~'\"\"\"' '\"\"\"'
1471verbatimStringLiteral :: IdrisParser (String, FC)
1472verbatimStringLiteral = Tok.token $ do (FC f start _) <- getFC
1473 P.try $ string "\"\"\""
1474 str <- P.manyTill P.anyChar $ P.try (string "\"\"\"")
1475 (FC _ _ end) <- getFC
1476 return (str, FC f start end)
1478{- | Parses a static modifier
1486static :: IdrisParser Static
1487static = do reserved "%static"; return Static
1488 <|> do reserved "[static]"
1490 parserWarning fc Nothing (Msg "The use of [static] is deprecated, use %static instead.")
1493 <?> "static modifier"
1495{- | Parses a tactic script
1498Tactic ::= 'intro' NameList?
1500 | 'refine' Name Imp+
1505 | 'let' Name ':' Expr' '=' Expr
1506 | 'let' Name '=' Expr
1509 | 'applyTactic' Expr
1512 | 'try' Tactic '|' Tactic
1530 | Tactic ';' TacticSeq
1535-- | A specification of the arguments that tactics can take
1536data TacticArg = NameTArg -- ^ Names: n1, n2, n3, ... n
1541-- The FIXMEs are Issue #1766 in the issue tracker.
1542-- https://github.com/idris-lang/Idris-dev/issues/1766
1543-- | A list of available tactics and their argument requirements
1544tactics :: [([String], Maybe TacticArg, SyntaxInfo -> IdrisParser PTactic)]
1546 [ (["intro"], Nothing, const $ -- FIXME syntax for intro (fresh name)
1547 do ns <- P.sepBy (spaced (fst <$> name)) (lchar ','); return $ Intro ns)
1548 , noArgs ["intros"] Intros
1549 , noArgs ["unfocus"] Unfocus
1550 , (["refine"], Just ExprTArg, const $
1551 do n <- spaced (fst <$> fnName)
1553 return $ Refine n imps)
1554 , (["claim"], Nothing, \syn ->
1555 do n <- indentGt *> (fst <$> name)
1556 goal <- indentGt *> expr syn
1557 return $ Claim n goal)
1558 , (["mrefine"], Just ExprTArg, const $
1559 do n <- spaced (fst <$> fnName)
1560 return $ MatchRefine n)
1561 , expressionTactic ["rewrite"] Rewrite
1562 , expressionTactic ["case"] CaseTac
1563 , expressionTactic ["induction"] Induction
1564 , expressionTactic ["equiv"] Equiv
1565 , (["let"], Nothing, \syn -> -- FIXME syntax for let
1566 do n <- (indentGt *> (fst <$> name))
1567 (do indentGt *> lchar ':'
1568 ty <- indentGt *> expr' syn
1569 indentGt *> lchar '='
1570 t <- indentGt *> expr syn
1572 return $ LetTacTy n (desugar syn i ty) (desugar syn i t))
1573 <|> (do indentGt *> lchar '='
1574 t <- indentGt *> expr syn
1576 return $ LetTac n (desugar syn i t)))
1578 , (["focus"], Just ExprTArg, const $
1579 do n <- spaced (fst <$> name)
1581 , expressionTactic ["exact"] Exact
1582 , expressionTactic ["applyTactic"] ApplyTactic
1583 , expressionTactic ["byReflection"] ByReflection
1584 , expressionTactic ["reflect"] Reflect
1585 , expressionTactic ["fill"] Fill
1586 , (["try"], Just AltsTArg, \syn ->
1587 do t <- spaced (tactic syn)
1589 t1 <- spaced (tactic syn)
1591 , noArgs ["compute"] Compute
1592 , noArgs ["trivial"] Trivial
1593 , noArgs ["unify"] DoUnify
1594 , (["search"], Nothing, const $
1595 do depth <- P.option 10 $ fst <$> natural
1596 return (ProofSearch True True (fromInteger depth) Nothing [] []))
1597 , noArgs ["implementation"] TCImplementation
1598 , noArgs ["solve"] Solve
1599 , noArgs ["attack"] Attack
1600 , noArgs ["state", ":state"] ProofState
1601 , noArgs ["term", ":term"] ProofTerm
1602 , noArgs ["undo", ":undo"] Undo
1603 , noArgs ["qed", ":qed"] Qed
1604 , noArgs ["abandon", ":q"] Abandon
1605 , noArgs ["skip"] Skip
1606 , noArgs ["sourceLocation"] SourceFC
1607 , expressionTactic [":e", ":eval"] TEval
1608 , expressionTactic [":t", ":type"] TCheck
1609 , expressionTactic [":search"] TSearch
1610 , (["fail"], Just StringLitTArg, const $
1611 do msg <- fst <$> stringLiteral
1612 return $ TFail [Idris.Core.TT.TextPart msg])
1613 , ([":doc"], Just ExprTArg, const $
1615 doc <- (Right . fst <$> constant) <|> (Left . fst <$> fnName)
1617 return (TDocStr doc))
1620 expressionTactic names tactic = (names, Just ExprTArg, \syn ->
1621 do t <- spaced (expr syn)
1623 return $ tactic (desugar syn i t))
1624 noArgs names tactic = (names, Nothing, const (return tactic))
1625 spaced parser = indentGt *> parser
1626 imp :: IdrisParser Bool
1627 imp = do lchar '?'; return False
1628 <|> do lchar '_'; return True
1631tactic :: SyntaxInfo -> IdrisParser PTactic
1632tactic syn = P.choice [ do P.choice (map reserved names); parser syn
1633 | (names, _, parser) <- tactics ]
1637 ts <- P.sepBy1 (tactic syn) (lchar ';')
1639 return $ TSeq t (mergeSeq ts)
1640 <|> ((lchar ':' >> empty) <?> "prover command")
1643 mergeSeq :: [PTactic] -> PTactic
1645 mergeSeq (t:ts) = TSeq t (mergeSeq ts)
1647-- | Parses a tactic as a whole
1648fullTactic :: SyntaxInfo -> IdrisParser PTactic
1649fullTactic syn = do t <- tactic syn
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