on master help sign in
Merge pull request #1655 from david-christiansen/docs

Retain parser and type errors in documentation code samples

commitb0e1ecf90c03f11f21dfd08a61d183114f99962c authorDavid Christiansen <david@davidchristiansen.dk> dateSat 18 Oct 2014, 10:02 (12 years ago) parent0ac10a88d486a7
27 files changed+461−151
CHANGELOG+2 idris.cabal+1−1 libs/prelude/Prelude/List.idr+71−35 src/Idris/AbsSyntax.hs+1−1 src/Idris/AbsSyntaxTree.hs+16−15 src/Idris/Core/Binary.hs+171−1 src/Idris/Core/TT.hs+2−1 src/Idris/Delaborate.hs+6−4 src/Idris/Docs.hs+12−12 src/Idris/Docstrings.hs+79−39 src/Idris/Elab/Class.hs+2−2 src/Idris/Elab/Clause.hs+1−1 src/Idris/Elab/Data.hs+8−8 src/Idris/Elab/Provider.hs+1−1 src/Idris/Elab/Record.hs+2−2 src/Idris/Elab/Type.hs+3−3 src/Idris/Elab/Value.hs+21−8 src/Idris/ElabDecls.hs+1−1 src/Idris/IBC.hs+17−3 src/Idris/IdeSlave.hs+13 src/Idris/Output.hs+6−3 src/Idris/ParseData.hs+3−3 src/Idris/ParseExpr.hs+4−4 src/Idris/Parser.hs+1−1 src/Idris/REPL.hs+13−1 test/interactive005/input+3 test/interactive005/run+1−1
CHANGELOG+2
@@ -28,6 +28,8 @@ New in 0.9.15:
2828 documentation lookups, and with semantic highlighting for IDEs.
2929* Fenced code blocks in docs defined with the "example" attribute are rendered
3030 as code examples.
31+* Fenced code blocks declared to be Idris code that fail to parse or type check now
32+ provide error messages to IDE clients.
3133* EXPERIMENTAL support for partial evaluation (Scrapping your Inefficient
3234 Engine style)
3335
idris.cabal+1−1
@@ -692,7 +692,7 @@ Library
692692 , ansi-terminal < 0.7
693693 , ansi-wl-pprint < 0.7
694694 , base64-bytestring < 1.1
695− , binary < 0.8
695+ , binary >= 0.7 && < 0.8
696696 , blaze-html >= 0.6.1.3 && < 0.8
697697 , blaze-markup >= 0.5.2.1 && < 0.7.0.0
698698 , bytestring < 0.11
libs/prelude/Prelude/List.idr+71−35
@@ -341,13 +341,15 @@ reverse = reverse' []
341341
342342||| Insert some separator between the elements of a list.
343343|||
344−||| > intersperse ',' (unpack "abcde") == unpack "a,b,c,d,e"
344+||| ````idris example
345+||| with List (intersperse ',' ['a', 'b', 'c', 'd', 'e'])
346+||| ````
345347|||
346348intersperse : a -> List a -> List a
347349intersperse sep [] = []
348350intersperse sep (x::xs) = x :: intersperse' sep xs
349351 where
350−-- intersperse' : a -> List a -> List a
352+ intersperse' : a -> List a -> List a
351353 intersperse' sep [] = []
352354 intersperse' sep (y::ys) = sep :: y :: intersperse' sep ys
353355
@@ -356,13 +358,15 @@ intercalate sep l = concat $ intersperse sep l
356358
357359||| Transposes rows and columns of a list of lists.
358360|||
359−||| > transpose [[1, 2], [3, 4]] = [[1, 3], [2, 4]]
361+||| ```idris example
362+||| with List transpose [[1, 2], [3, 4]]
363+||| ```
360364|||
361365||| This also works for non square scenarios, thus
362366||| involution does not always hold:
363367|||
364−||| > transpose [[], [1, 2]] = [[1], [2]]
365−||| > transpose (transpose [[], [1, 2]]) = [[1, 2]]
368+||| transpose [[], [1, 2]] = [[1], [2]]
369+||| transpose (transpose [[], [1, 2]]) = [[1, 2]]
366370|||
367371||| TODO: Solution which satisfies the totality checker?
368372%assert_total
@@ -473,7 +477,9 @@ elemIndices = elemIndicesBy (==)
473477
474478||| filter, applied to a predicate and a list, returns the list of those elements that satisfy the predicate; e.g.,
475479|||
476−||| > filter (<3) [0..5] == [0,1,2]
480+||| ````idris example
481+||| filter (< 3) [Z, S Z, S (S Z), S (S (S Z)), S (S (S (S Z)))]
482+||| ````
477483|||
478484filter : (a -> Bool) -> List a -> List a
479485filter p [] = []
@@ -495,10 +501,14 @@ nubBy = nubBy' []
495501 else
496502 x :: nubBy' (x::acc) p xs
497503
498−||| O(n^2). The nub function removes duplicate elements from a list. In particular, it keeps only the first occurrence of each element. It is a special case of nubBy, which allows the programmer to supply their own equality test.
499−|||
500−||| > nub (the (List _) [1,2,1,3]) == [1,2,3]
504+||| O(n^2). The nub function removes duplicate elements from a list. In
505+||| particular, it keeps only the first occurrence of each element. It is a
506+||| special case of nubBy, which allows the programmer to supply their own
507+||| equality test.
501508|||
509+||| ```idris example
510+||| nub (the (List _) [1,2,1,3])
511+||| ```
502512nub : Eq a => List a -> List a
503513nub = nubBy (==)
504514
@@ -507,18 +517,25 @@ deleteBy : (a -> a -> Bool) -> a -> List a -> List a
507517deleteBy _ _ [] = []
508518deleteBy eq x (y::ys) = if x `eq` y then ys else y :: deleteBy eq x ys
509519
510−||| delete x removes the first occurrence of x from its list argument. For example,
520+||| `delete x` removes the first occurrence of `x` from its list argument. For
521+||| example,
511522|||
512−||| > delete 'a' (unpack "banana") == unpack "bnana"
523+|||````idris example
524+|||delete 'a' ['b', 'a', 'n', 'a', 'n', 'a']
525+|||````
513526|||
514−||| It is a special case of deleteBy, which allows the programmer to supply their own equality test.
527+||| It is a special case of deleteBy, which allows the programmer to supply
528+||| their own equality test.
515529delete : (Eq a) => a -> List a -> List a
516530delete = deleteBy (==)
517531
518−||| The \\ function is list difference (non-associative). In the result of xs \\ ys, the first occurrence of each element of ys in turn (if any) has been removed from xs, e.g.,
519−|||
520−||| > (([1,2] ++ [2,3]) \\ [1,2]) == [2,3]
532+||| The `\\` function is list difference (non-associative). In the result of
533+||| `xs \\ ys`, the first occurrence of each element of ys in turn (if any) has
534+||| been removed from `xs`, e.g.,
521535|||
536+||| ```idris example
537+||| (([1,2] ++ [2,3]) \\ [1,2])
538+||| ```
522539(\\) : (Eq a) => List a -> List a -> List a
523540(\\) = foldl (flip delete)
524541
@@ -527,7 +544,9 @@ unionBy eq xs ys = xs ++ foldl (flip (deleteBy eq)) (nubBy eq ys) xs
527544
528545||| The union function returns the list union of the two lists. For example,
529546|||
530−||| > union (unpack "dog") (unpack "cow") == unpack "dogcw"
547+||| ```idris example
548+||| union ['d', 'o', 'g'] ['c', 'o', 'w']
549+||| ```
531550|||
532551union : (Eq a) => List a -> List a -> List a
533552union = unionBy (==)
@@ -539,8 +558,9 @@ union = unionBy (==)
539558||| Given a list and a predicate, returns a pair consisting of the longest
540559||| prefix of the list that satisfies a predicate and the rest of the list.
541560|||
542−||| > span (<3) [1,2,3,2,1] == the ((List _, List _)) ([1, 2], [3, 2, 1])
543−|||
561+||| ```idris example
562+||| span (<3) [1,2,3,2,1]
563+||| ```
544564span : (a -> Bool) -> List a -> (List a, List a)
545565span p [] = ([], [])
546566span p (x::xs) =
@@ -551,17 +571,20 @@ span p (x::xs) =
551571 ([], x::xs)
552572
553573||| Given a list and a predicate, returns a pair consisting of the longest
554−||| prefix of the list that does not satisfy a predicate and the rest of the list.
555−|||
556−||| > break (>=3) [1,2,3,2,1] == the ((List _, List _)) ([1, 2], [3, 2, 1])
574+||| prefix of the list that does not satisfy a predicate and the rest of the
575+||| list.
557576|||
577+||| ```idris example
578+||| break (>=3) [1,2,3,2,1]
579+||| ```
558580break : (a -> Bool) -> List a -> (List a, List a)
559581break p = span (not . p)
560582
561583||| Split on any elements that satisfy the given predicate.
562584|||
563−||| > split (<2) [2,0,3,1,4] == [[2], [3], [4]]
564−|||
585+||| ```idris example
586+||| split (<2) [2,0,3,1,4]
587+||| ```
565588split : (a -> Bool) -> List a -> List (List a)
566589split p xs =
567590 case break p xs of
@@ -578,8 +601,9 @@ splitAt n xs = (take n xs, drop n xs)
578601
579602||| The partition function takes a predicate a list and returns the pair of lists of elements which do and do not satisfy the predicate, respectively; e.g.,
580603|||
581−||| > partition (<3) [0..5] == (the (List Integer) [0,1,2], the (List Integer) [3,4,5])
582−|||
604+||| ```idris example
605+||| partition (<3) [0, 1, 2, 3, 4, 5]
606+||| ```
583607partition : (a -> Bool) -> List a -> (List a, List a)
584608partition p [] = ([], [])
585609partition p (x::xs) =
@@ -589,19 +613,23 @@ partition p (x::xs) =
589613 else
590614 (lefts, x::rights)
591615
592−||| The inits function returns all initial segments of the argument, shortest first. For example,
593−|||
594−||| > inits [1,2,3] == [[],[1],[1,2],[1,2,3]]
616+||| The inits function returns all initial segments of the argument, shortest
617+||| first. For example,
595618|||
619+||| ```idris example
620+||| inits [1,2,3]
621+||| ```
596622inits : List a -> List (List a)
597623inits xs = [] :: case xs of
598624 [] => []
599625 x :: xs' => map (x ::) (inits xs')
600626
601−||| The tails function returns all final segments of the argument, longest first. For example,
602−|||
603−||| > tails [1,2,3] == [[1,2,3], [2,3], [3], []]
627+||| The tails function returns all final segments of the argument, longest
628+||| first. For example,
604629|||
630+||| ```idris example
631+||| tails [1,2,3] == [[1,2,3], [2,3], [3], []]
632+|||```
605633tails : List a -> List (List a)
606634tails xs = xs :: case xs of
607635 [] => []
@@ -609,14 +637,18 @@ tails xs = xs :: case xs of
609637
610638||| Split on the given element.
611639|||
612−||| > splitOn 0 [1,0,2,0,0,3] == [[1],[2],[],[3]]
640+||| ```idris example
641+||| splitOn 0 [1,0,2,0,0,3]
642+||| ```
613643|||
614644splitOn : Eq a => a -> List a -> List (List a)
615645splitOn a = split (== a)
616646
617647||| Replaces all occurences of the first argument with the second argument in a list.
618648|||
619−||| > replaceOn '-' ',' (unpack "1-2-3") == unpack "1,2,3"
649+||| ```idris example
650+||| replaceOn '-' ',' ['1', '-', '2', '-', '3']
651+||| ```
620652|||
621653replaceOn : Eq a => a -> a -> List a -> List a
622654replaceOn a b l = map (\c => if c == a then b else c) l
@@ -647,8 +679,12 @@ isSuffixOf = isSuffixOfBy (==)
647679
648680||| The isInfixOf function takes two lists and returns True iff the first list is contained, wholly and intact, anywhere within the second.
649681|||
650−||| > isInfixOf "Idris" "I really like Idris." == True
651−||| > isInfixOf "Ial" "I really like Idris." == False
682+||| ```idris example
683+||| isInfixOf ['b','c'] ['a', 'b', 'c', 'd']
684+||| ```
685+||| ```idris example
686+||| isInfixOf ['b','d'] ['a', 'b', 'c', 'd']
687+||| ```
652688|||
653689isInfixOf : Eq a => List a -> List a -> Bool
654690isInfixOf n h = any (isPrefixOf n) (tails h)
src/Idris/AbsSyntax.hs+1−1
@@ -286,7 +286,7 @@ addCoercion :: Name -> Idris ()
286286addCoercion n = do i <- getIState
287287 putIState $ i { idris_coercions = nub $ n : idris_coercions i }
288288
289−addDocStr :: Name -> Docstring (Maybe Term) -> [(Name, Docstring (Maybe Term))] -> Idris ()
289+addDocStr :: Name -> Docstring DocTerm -> [(Name, Docstring DocTerm)] -> Idris ()
290290addDocStr n doc args
291291 = do i <- getIState
292292 putIState $ i { idris_docstrings = addDef n (doc, args) (idris_docstrings i) }
src/Idris/AbsSyntaxTree.hs+16−15
@@ -158,7 +158,7 @@ data IState = IState {
158158 idris_flags :: Ctxt [FnOpt],
159159 idris_callgraph :: Ctxt CGInfo, -- name, args used in each pos
160160 idris_calledgraph :: Ctxt [Name],
161− idris_docstrings :: Ctxt (Docstring (Maybe Term), [(Name, Docstring (Maybe Term))]),
161+ idris_docstrings :: Ctxt (Docstring DocTerm, [(Name, Docstring DocTerm)]),
162162 idris_tyinfodata :: Ctxt TIData,
163163 idris_fninfo :: Ctxt FnInfo,
164164 idris_transforms :: Ctxt [(Term, Term)],
@@ -536,19 +536,19 @@ type ProvideWhat = ProvideWhat' PTerm
536536-- datatypes and typeclasses.
537537data PDecl' t
538538 = PFix FC Fixity [String] -- ^ Fixity declaration
539− | PTy (Docstring (Maybe PTerm)) [(Name, Docstring (Maybe PTerm))] SyntaxInfo FC FnOpts Name t -- ^ Type declaration
540− | PPostulate (Docstring (Maybe PTerm)) SyntaxInfo FC FnOpts Name t -- ^ Postulate
539+ | PTy (Docstring (Either Err PTerm)) [(Name, Docstring (Either Err PTerm))] SyntaxInfo FC FnOpts Name t -- ^ Type declaration
540+ | PPostulate (Docstring (Either Err PTerm)) SyntaxInfo FC FnOpts Name t -- ^ Postulate
541541 | PClauses FC FnOpts Name [PClause' t] -- ^ Pattern clause
542542 | PCAF FC Name t -- ^ Top level constant
543− | PData (Docstring (Maybe PTerm)) [(Name, Docstring (Maybe PTerm))] SyntaxInfo FC DataOpts (PData' t) -- ^ Data declaration.
543+ | PData (Docstring (Either Err PTerm)) [(Name, Docstring (Either Err PTerm))] SyntaxInfo FC DataOpts (PData' t) -- ^ Data declaration.
544544 | PParams FC [(Name, t)] [PDecl' t] -- ^ Params block
545545 | PNamespace String [PDecl' t] -- ^ New namespace
546− | PRecord (Docstring (Maybe PTerm)) SyntaxInfo FC Name t DataOpts (Docstring (Maybe PTerm)) Name t -- ^ Record declaration
547− | PClass (Docstring (Maybe PTerm)) SyntaxInfo FC
546+ | PRecord (Docstring (Either Err PTerm)) SyntaxInfo FC Name t DataOpts (Docstring (Either Err PTerm)) Name t -- ^ Record declaration
547+ | PClass (Docstring (Either Err PTerm)) SyntaxInfo FC
548548 [t] -- constraints
549549 Name
550550 [(Name, t)] -- parameters
551− [(Name, Docstring (Maybe PTerm))] -- parameter docstrings
551+ [(Name, Docstring (Either Err PTerm))] -- parameter docstrings
552552 [PDecl' t] -- declarations
553553 -- ^ Type class: arguments are documentation, syntax info, source location, constraints,
554554 -- class name, parameters, method declarations
@@ -599,7 +599,7 @@ deriving instance NFData PClause'
599599-- | Data declaration
600600data PData' t = PDatadecl { d_name :: Name, -- ^ The name of the datatype
601601 d_tcon :: t, -- ^ Type constructor
602− d_cons :: [(Docstring (Maybe PTerm), [(Name, Docstring (Maybe PTerm))], Name, t, FC, [Name])] -- ^ Constructors
602+ d_cons :: [(Docstring (Either Err PTerm), [(Name, Docstring (Either Err PTerm))], Name, t, FC, [Name])] -- ^ Constructors
603603 }
604604 -- ^ Data declaration
605605 | PLaterdecl { d_name :: Name, d_tcon :: t }
@@ -1079,7 +1079,7 @@ unitTy = sUN "Unit"
10791079unitCon = sUN "MkUnit"
10801080
10811081-- TODO: elaborate the code samples in the docstring
1082−falseDoc = fmap (const Nothing) . parseDocstring . T.pack $
1082+falseDoc = fmap (const $ Msg "") . parseDocstring . T.pack $
10831083 "The empty type, also known as the trivially false proposition." ++
10841084 "\n\n" ++
10851085 "Use `void` or `absurd` to prove anything if you have a variable " ++
@@ -1091,7 +1091,7 @@ pairCon = sUN "MkPair"
10911091
10921092eqTy = sUN "="
10931093eqCon = sUN "Refl"
1094−eqDoc = fmap (const Nothing) . parseDocstring . T.pack $
1094+eqDoc = fmap (const (Left $ Msg "")) . parseDocstring . T.pack $
10951095 "The propositional equality type. A proof that `x` = `y`." ++
10961096 "\n\n" ++
10971097 "To use such a proof, pattern-match on it, and the two equal things will " ++
@@ -1114,14 +1114,14 @@ eqDecl = PDatadecl eqTy (piBindp impl [(n "A", PType), (n "B", PType)]
11141114 pexp (PRef bi (n "x")),
11151115 pexp (PRef bi (n "x"))])), bi, [])]
11161116 where n a = sUN a
1117− reflDoc = annotCode (const Nothing) . parseDocstring . T.pack $
1117+ reflDoc = annotCode (const (Left $ Msg "")) . parseDocstring . T.pack $
11181118 "A proof that `x` in fact equals `x`. To construct this, you must have already " ++
11191119 "shown that both sides are in fact equal."
1120− reflParamDoc = [(n "A", annotCode (const Nothing) . parseDocstring . T.pack $ "the type at which the equality is proven"),
1121− (n "x", annotCode (const Nothing) . parseDocstring . T.pack $ "the element shown to be equal to itself.")]
1120+ reflParamDoc = [(n "A", annotCode (const (Left $ Msg "")) . parseDocstring . T.pack $ "the type at which the equality is proven"),
1121+ (n "x", annotCode (const (Left $ Msg "")) . parseDocstring . T.pack $ "the element shown to be equal to itself.")]
11221122
1123−eqParamDoc = [(n "A", annotCode (const Nothing) . parseDocstring . T.pack $ "the type of the left side of the equality"),
1124− (n "B", annotCode (const Nothing) . parseDocstring . T.pack $ "the type of the right side of the equality")
1123+eqParamDoc = [(n "A", annotCode (const (Left $ Msg "")) . parseDocstring . T.pack $ "the type of the left side of the equality"),
1124+ (n "B", annotCode (const (Left $ Msg "")) . parseDocstring . T.pack $ "the type of the right side of the equality")
11251125 ]
11261126 where n a = sUN a
11271127
@@ -1188,6 +1188,7 @@ consoleDecorate ist (AnnTextFmt fmt) = Idris.Colours.colourise (colour fmt)
11881188 colour ItalicText = IdrisColour Nothing True False False True
11891189consoleDecorate ist (AnnTerm _ _) = id
11901190consoleDecorate ist (AnnSearchResult _) = id
1191+consoleDecorate ist (AnnErr _) = id
11911192
11921193isPostulateName :: Name -> IState -> Bool
11931194isPostulateName n ist = S.member n (idris_postulates ist)
src/Idris/Core/Binary.hs+171−1
@@ -1,3 +1,5 @@
1+{-# OPTIONS_GHC -fwarn-incomplete-patterns -Werror #-}
2+
13{-| Binary instances for the core datatypes -}
24module Idris.Core.Binary where
35
@@ -7,6 +9,169 @@ import qualified Data.Text as T
79
810import Idris.Core.TT
911
12+instance Binary ErrorReportPart where
13+ put (TextPart msg) = do putWord8 0 ; put msg
14+ put (NamePart n) = do putWord8 1 ; put n
15+ put (TermPart t) = do putWord8 2 ; put t
16+ put (SubReport ps) = do putWord8 3 ; put ps
17+
18+ get = do i <- getWord8
19+ case i of
20+ 0 -> fmap TextPart get
21+ 1 -> fmap NamePart get
22+ 2 -> fmap TermPart get
23+ 3 -> fmap SubReport get
24+ _ -> error "Corrupted binary data for ErrorReportPart"
25+
26+instance Binary a => Binary (Err' a) where
27+ put (Msg str) = do putWord8 0
28+ put str
29+ put (InternalMsg str) = do putWord8 1
30+ put str
31+ put (CantUnify x y z e ctxt i) = do putWord8 2
32+ put x
33+ put y
34+ put z
35+ put e
36+ put ctxt
37+ put i
38+ put (InfiniteUnify n t ctxt) = do putWord8 3
39+ put n
40+ put t
41+ put ctxt
42+ put (CantConvert x y ctxt) = do putWord8 4
43+ put x
44+ put y
45+ put ctxt
46+ put (CantSolveGoal x ctxt) = do putWord8 5
47+ put x
48+ put ctxt
49+ put (UnifyScope n1 n2 x ctxt) = do putWord8 6
50+ put n1
51+ put n2
52+ put x
53+ put ctxt
54+ put (CantInferType str) = do putWord8 7
55+ put str
56+ put (NonFunctionType t1 t2) = do putWord8 8
57+ put t1
58+ put t2
59+ put (NotEquality t1 t2) = do putWord8 9
60+ put t1
61+ put t2
62+ put (TooManyArguments n) = do putWord8 10
63+ put n
64+ put (CantIntroduce t) = do putWord8 11
65+ put t
66+ put (NoSuchVariable n) = do putWord8 12
67+ put n
68+ put (NoTypeDecl n) = do putWord8 13
69+ put n
70+ put (NotInjective x y z) = do putWord8 14
71+ put x
72+ put y
73+ put z
74+ put (CantResolve t) = do putWord8 15
75+ put t
76+ put (CantResolveAlts ns) = do putWord8 16
77+ put ns
78+ put (IncompleteTerm t) = do putWord8 17
79+ put t
80+ put UniverseError = putWord8 18
81+ put (UniqueError u n) = do putWord8 19
82+ put u
83+ put n
84+ put (UniqueKindError u n) = do putWord8 20
85+ put u
86+ put n
87+ put ProgramLineComment = putWord8 21
88+ put (Inaccessible n) = do putWord8 22
89+ put n
90+ put (NonCollapsiblePostulate n) = do putWord8 23
91+ put n
92+ put (AlreadyDefined n) = do putWord8 24
93+ put n
94+ put (ProofSearchFail e) = do putWord8 25
95+ put e
96+ put (NoRewriting t) = do putWord8 26
97+ put t
98+ put (At fc e) = do putWord8 27
99+ put fc
100+ put e
101+ put (Elaborating str n e) = do putWord8 28
102+ put str
103+ put n
104+ put e
105+ put (ElaboratingArg n1 n2 ns e) = do putWord8 29
106+ put n1
107+ put n2
108+ put ns
109+ put e
110+ put (ProviderError str) = do putWord8 30
111+ put str
112+ put (LoadingFailed str e) = do putWord8 31
113+ put str
114+ put e
115+ put (ReflectionError parts e) = do putWord8 32
116+ put parts
117+ put e
118+ put (ReflectionFailed str e) = do putWord8 33
119+ put str
120+ put e
121+
122+ get = do i <- getWord8
123+ case i of
124+ 0 -> fmap Msg get
125+ 1 -> fmap InternalMsg get
126+ 2 -> do x <- get ; y <- get ; z <- get ; e <- get ; ctxt <- get ; i <- get
127+ return $ CantUnify x y z e ctxt i
128+ 3 -> do x <- get ; y <- get ; z <- get
129+ return $ InfiniteUnify x y z
130+ 4 -> do x <- get ; y <- get ; z <- get
131+ return $ CantConvert x y z
132+ 5 -> do x <- get ; y <- get
133+ return $ CantSolveGoal x y
134+ 6 -> do w <- get ; x <- get ; y <- get ; z <- get
135+ return $ UnifyScope w x y z
136+ 7 -> fmap CantInferType get
137+ 8 -> do x <- get ; y <- get
138+ return $ NonFunctionType x y
139+ 9 -> do x <- get ; y <- get
140+ return $ NotEquality x y
141+ 10 -> fmap TooManyArguments get
142+ 11 -> fmap CantIntroduce get
143+ 12 -> fmap NoSuchVariable get
144+ 13 -> fmap NoTypeDecl get
145+ 14 -> do x <- get ; y <- get ; z <- get
146+ return $ NotInjective x y z
147+ 15 -> fmap CantResolve get
148+ 16 -> fmap CantResolveAlts get
149+ 17 -> fmap IncompleteTerm get
150+ 18 -> return UniverseError
151+ 19 -> do x <- get ; y <- get
152+ return $ UniqueError x y
153+ 20 -> do x <- get ; y <- get
154+ return $ UniqueKindError x y
155+ 21 -> return ProgramLineComment
156+ 22 -> fmap Inaccessible get
157+ 23 -> fmap NonCollapsiblePostulate get
158+ 24 -> fmap AlreadyDefined get
159+ 25 -> fmap ProofSearchFail get
160+ 26 -> fmap NoRewriting get
161+ 27 -> do x <- get ; y <- get
162+ return $ At x y
163+ 28 -> do x <- get ; y <- get ; z <- get
164+ return $ Elaborating x y z
165+ 29 -> do w <- get ; x <- get ; y <- get ; z <- get
166+ return $ ElaboratingArg w x y z
167+ 30 -> fmap ProviderError get
168+ 31 -> do x <- get ; y <- get
169+ return $ LoadingFailed x y
170+ 32 -> do x <- get ; y <- get
171+ return $ ReflectionError x y
172+ 33 -> do x <- get ; y <- get
173+ return $ ReflectionFailed x y
174+ _ -> error "Corrupted binary data for Err'"
10175----- Generated by 'derive'
11176
12177instance Binary FC where
@@ -145,6 +310,7 @@ instance Binary Const where
145310 B64V x1 -> putWord8 24 >> put x1
146311 BufferType -> putWord8 25
147312 ManagedPtrType -> putWord8 26
313+ VoidType -> putWord8 27
148314 get
149315 = do i <- getWord8
150316 case i of
@@ -187,7 +353,7 @@ instance Binary Const where
187353 24 -> fmap B64V get
188354 25 -> return BufferType
189355 26 -> return ManagedPtrType
190−
356+ 27 -> return VoidType
191357 _ -> error "Corrupted binary data for Const"
192358
193359
@@ -208,6 +374,8 @@ instance Binary Raw where
208374 put x1
209375 RForce x1 -> do putWord8 5
210376 put x1
377+ RUType x1 -> do putWord8 6
378+ put x1
211379 get
212380 = do i <- getWord8
213381 case i of
@@ -225,6 +393,8 @@ instance Binary Raw where
225393 return (RConstant x1)
226394 5 -> do x1 <- get
227395 return (RForce x1)
396+ 6 -> do x1 <- get
397+ return (RUType x1)
228398 _ -> error "Corrupted binary data for Raw"
229399
230400
src/Idris/Core/TT.hs+2−1
@@ -103,6 +103,7 @@ data OutputAnnotation = AnnName Name (Maybe NameOutput) (Maybe String) (Maybe St
103103 | AnnTextFmt TextFormatting
104104 | AnnTerm [(Name, Bool)] (TT Name) -- ^ pprint bound vars, original term
105105 | AnnSearchResult Ordering -- ^ more general, isomorphic, or more specific
106+ | AnnErr Err
106107
107108-- | Used for error reflection
108109data ErrorReportPart = TextPart String
@@ -117,7 +118,7 @@ data ErrorReportPart = TextPart String
117118
118119-- | Idris errors. Used as exceptions in the compiler, but reported to users
119120-- if they reach the top level.
120−data Err' t
121+data Err' t
121122 = Msg String
122123 | InternalMsg String
123124 | CantUnify Bool t t (Err' t) [(Name, t)] Int
src/Idris/Delaborate.hs+6−4
@@ -9,7 +9,7 @@ import Util.Pretty
99import Idris.AbsSyntax
1010import Idris.Core.TT
1111import Idris.Core.Evaluate
12−import Idris.Docstrings (overview, renderDocstring)
12+import Idris.Docstrings (overview, renderDocstring, renderDocTerm)
1313import Idris.ErrReverse
1414
1515import Data.List (intersperse, nub)
@@ -435,12 +435,14 @@ fancifyAnnots ist annot@(AnnName n _ _ _) =
435435 _ | otherwise -> annot
436436 where docOverview :: IState -> Name -> Maybe String -- pretty-print first paragraph of docs
437437 docOverview ist n = do docs <- lookupCtxtExact n (idris_docstrings ist)
438− let o = overview (fst docs)
438+ let o = overview (fst docs)
439+ norm = normaliseAll (tt_ctxt ist) []
439440 -- TODO make width configurable
440441 -- Issue #1588 on the Issue Tracker
441442 -- https://github.com/idris-lang/Idris-dev/issues/1588
442− out = displayS . renderPretty 1.0 50 $
443− renderDocstring (pprintDelab ist) (normaliseAll (tt_ctxt ist) []) o
443+ out = displayS . renderPretty 1.0 50 $
444+ renderDocstring (renderDocTerm (pprintDelab ist)
445+ norm) o
444446 return (out "")
445447 getTy :: IState -> Name -> String -- fails if name not already extant!
446448 getTy ist n = let theTy = pprintPTerm (ppOptionIst ist) [] [] (idris_infixes ist) $
src/Idris/Docs.hs+12−12
@@ -6,7 +6,7 @@ import Idris.AbsSyntaxTree
66import Idris.Delaborate
77import Idris.Core.TT
88import Idris.Core.Evaluate
9−import Idris.Docstrings (Docstring, emptyDocstring, noDocs, nullDocstring, renderDocstring)
9+import Idris.Docstrings (Docstring, emptyDocstring, noDocs, nullDocstring, renderDocstring, DocTerm, renderDocTerm)
1010
1111import Util.Pretty
1212
@@ -18,31 +18,31 @@ import qualified Data.Text as T
1818--
1919-- Issue #1573 on the Issue tracker.
2020-- https://github.com/idris-lang/Idris-dev/issues/1573
21−data FunDoc = FD Name (Docstring (Maybe Term))
22− [(Name, PTerm, Plicity, Maybe (Docstring (Maybe Term)))] -- args: name, ty, implicit, docs
21+data FunDoc = FD Name (Docstring DocTerm)
22+ [(Name, PTerm, Plicity, Maybe (Docstring DocTerm))] -- args: name, ty, implicit, docs
2323 PTerm -- function type
2424 (Maybe Fixity)
25− deriving Show
2625
2726data Docs = FunDoc FunDoc
2827 | DataDoc FunDoc -- type constructor docs
2928 [FunDoc] -- data constructor docs
30− | ClassDoc Name (Docstring (Maybe Term))-- class docs
29+ | ClassDoc Name (Docstring DocTerm)-- class docs
3130 [FunDoc] -- method docs
32− [(Name, Maybe (Docstring (Maybe Term)))] -- parameters and their docstrings
31+ [(Name, Maybe (Docstring DocTerm))] -- parameters and their docstrings
3332 [PTerm] -- instances
3433 [PTerm] -- superclasses
35− deriving Show
3634
37−showDoc ist d | nullDocstring d = empty
38− | otherwise = text " -- " <> renderDocstring (pprintDelab ist) (normaliseAll (tt_ctxt ist) []) d
35+showDoc ist d
36+ | nullDocstring d = empty
37+ | otherwise = text " -- " <>
38+ renderDocstring (renderDocTerm (pprintDelab ist) (normaliseAll (tt_ctxt ist) [])) d
3939
4040pprintFD :: IState -> FunDoc -> Doc OutputAnnotation
4141pprintFD ist (FD n doc args ty f)
4242 = nest 4 (prettyName True (ppopt_impl ppo) [] n <+> colon <+>
4343 pprintPTerm ppo [] [ n | (n@(UN n'),_,_,_) <- args
4444 , not (T.isPrefixOf (T.pack "__") n') ] infixes ty <$>
45− renderDocstring (pprintDelab ist) (normaliseAll (tt_ctxt ist) []) doc <$>
45+ renderDocstring (renderDocTerm (pprintDelab ist) (normaliseAll (tt_ctxt ist) [])) doc <$>
4646 maybe empty (\f -> text (show f) <> line) f <>
4747 let argshow = showArgs args [] in
4848 if not (null argshow)
@@ -84,7 +84,7 @@ pprintDocs ist (ClassDoc n doc meths params instances superclasses)
8484 = nest 4 (text "Type class" <+> prettyName True (ppopt_impl ppo) [] n <>
8585 if nullDocstring doc
8686 then empty
87− else line <> renderDocstring (pprintDelab ist) (normaliseAll (tt_ctxt ist) []) doc)
87+ else line <> renderDocstring (renderDocTerm (pprintDelab ist) (normaliseAll (tt_ctxt ist) [])) doc)
8888 <> line <$>
8989 nest 4 (text "Parameters:" <$> prettyParameters)
9090 <> line <$>
@@ -187,7 +187,7 @@ docFun n
187187 funName (UN n) = str n
188188 funName (NS n _) = funName n
189189
190−getPArgNames :: PTerm -> [(Name, Docstring (Maybe Term))] -> [(Name, PTerm, Plicity, Maybe (Docstring (Maybe Term)))]
190+getPArgNames :: PTerm -> [(Name, Docstring DocTerm)] -> [(Name, PTerm, Plicity, Maybe (Docstring DocTerm))]
191191getPArgNames (PPi plicity name ty body) ds =
192192 (name, ty, plicity, lookup name ds) : getPArgNames body ds
193193getPArgNames _ _ = []
src/Idris/Docstrings.hs+79−39
@@ -1,10 +1,10 @@
11{-# LANGUAGE DeriveFunctor, ScopedTypeVariables #-}
2−{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
2+{-# OPTIONS_GHC -fwarn-incomplete-patterns -Werror #-}
33
44-- | Wrapper around Markdown library
55module Idris.Docstrings (
66 Docstring(..), Block(..), Inline(..), parseDocstring, renderDocstring, emptyDocstring, nullDocstring, noDocs,
7− overview, containsText, renderHtml, annotCode
7+ overview, containsText, renderHtml, annotCode, DocTerm(..), renderDocTerm, checkDocstring
88 ) where
99
1010import qualified Cheapskate as C
@@ -13,7 +13,7 @@ import Cheapskate.Html (renderDoc)
1313
1414import Util.Pretty
1515
16−import Idris.Core.TT (OutputAnnotation(..), TextFormatting(..), Name, Term)
16+import Idris.Core.TT (OutputAnnotation(..), TextFormatting(..), Name, Term, Err)
1717
1818import qualified Data.Text as T
1919import qualified Data.Foldable as F
@@ -25,6 +25,22 @@ import Control.DeepSeq (NFData(..))
2525
2626import Text.Blaze.Html (Html)
2727
28+-- | The various kinds of code samples that can be embedded in docs
29+data DocTerm = Unchecked
30+ | Checked Term
31+ | Example Term
32+ | Failing Err
33+ deriving Show
34+
35+-- | Render a term in the documentation
36+renderDocTerm :: (Term -> Doc OutputAnnotation) -> (Term -> Term) -> DocTerm -> String -> Doc OutputAnnotation
37+renderDocTerm pp norm Unchecked src = text src
38+renderDocTerm pp norm (Checked tm) src = pp tm
39+renderDocTerm pp norm (Example tm) src = align $
40+ text ">" <+> align (pp tm) <$>
41+ pp (norm tm)
42+renderDocTerm pp norm (Failing err) src = annotate (AnnErr err) $ text src
43+
2844-- | Representation of Idris's inline documentation. The type paramter
2945-- represents the type of terms that are associated with code blocks.
3046data Docstring a = DocString CT.Options (Blocks a)
@@ -58,6 +74,37 @@ data Inline a = Str T.Text
5874type Inlines a = S.Seq (Inline a)
5975
6076
77+-- | Run some kind of processing step over code in a Docstring. The code
78+-- processor gets the language and annotations as parameters, along with the
79+-- source and the original annotation.
80+checkDocstring :: forall a b. (String -> [String] -> String -> a -> b) -> Docstring a -> Docstring b
81+checkDocstring f (DocString opts blocks) = DocString opts (fmap (checkBlock f) blocks)
82+ where checkBlock :: (String -> [String] -> String -> a -> b) -> Block a -> Block b
83+ checkBlock f (Para inlines) = Para (fmap (checkInline f) inlines)
84+ checkBlock f (Header i inlines) = Header i (fmap (checkInline f) inlines)
85+ checkBlock f (Blockquote bs) = Blockquote (fmap (checkBlock f) bs)
86+ checkBlock f (List b t blocks) = List b t (fmap (fmap (checkBlock f)) blocks)
87+ checkBlock f (CodeBlock attrs src tm) = CodeBlock attrs src
88+ (f (T.unpack $ CT.codeLang attrs)
89+ (words . T.unpack $ CT.codeInfo attrs)
90+ (T.unpack src)
91+ tm)
92+ checkBlock f (HtmlBlock src) = HtmlBlock src
93+ checkBlock f HRule = HRule
94+
95+ checkInline :: (String -> [String] -> String -> a -> b) -> Inline a -> Inline b
96+ checkInline f (Str txt) = Str txt
97+ checkInline f Space = Space
98+ checkInline f SoftBreak = SoftBreak
99+ checkInline f LineBreak = LineBreak
100+ checkInline f (Emph is) = Emph (fmap (checkInline f) is)
101+ checkInline f (Strong is) = Strong (fmap (checkInline f) is)
102+ checkInline f (Code src x) = Code src (f "" [] (T.unpack src) x)
103+ checkInline f (Link is url title) = Link (fmap (checkInline f) is) url title
104+ checkInline f (Image is url title) = Image (fmap (checkInline f) is) url title
105+ checkInline f (Entity txt) = Entity txt
106+ checkInline f (RawHtml src) = RawHtml src
107+
61108-- | Construct a docstring from a Text that contains Markdown-formatted docs
62109parseDocstring :: T.Text -> Docstring ()
63110parseDocstring = toDocstring . C.markdown options
@@ -94,60 +141,53 @@ options = CT.Options { CT.sanitize = True
94141 }
95142
96143-- | Convert a docstring to be shown by the pretty-printer
97−renderDocstring :: (a -> Doc OutputAnnotation) -> (a -> a) -> Docstring (Maybe a) -> Doc OutputAnnotation
98−renderDocstring pp norm (DocString _ blocks) = renderBlocks pp norm blocks
144+renderDocstring :: (a -> String -> Doc OutputAnnotation) -> Docstring a -> Doc OutputAnnotation
145+renderDocstring pp (DocString _ blocks) = renderBlocks pp blocks
99146
100147-- | Construct a docstring consisting of the first block-level element of the
101148-- argument docstring, for use in summaries.
102149overview :: Docstring a -> Docstring a
103150overview (DocString opts blocks) = DocString opts (S.take 1 blocks)
104151
105−renderBlocks :: (a -> Doc OutputAnnotation) -> (a -> a)
106− -> Blocks (Maybe a) -> Doc OutputAnnotation
107−renderBlocks pp norm blocks | S.length blocks > 1 = F.foldr1 (\b1 b2 -> b1 <> line <> line <> b2) $
108− fmap (renderBlock pp norm) blocks
109− | S.length blocks == 1 = renderBlock pp norm (S.index blocks 0)
152+renderBlocks :: (a -> String -> Doc OutputAnnotation)
153+ -> Blocks a -> Doc OutputAnnotation
154+renderBlocks pp blocks | S.length blocks > 1 = F.foldr1 (\b1 b2 -> b1 <> line <> line <> b2) $
155+ fmap (renderBlock pp) blocks
156+ | S.length blocks == 1 = renderBlock pp (S.index blocks 0)
110157 | otherwise = empty
111158
112−renderBlock :: (a -> Doc OutputAnnotation) -> (a -> a)
113− -> Block (Maybe a) -> Doc OutputAnnotation
114−renderBlock pp norm (Para inlines) = renderInlines pp inlines
115−renderBlock pp norm (Header lvl inlines) = renderInlines pp inlines <+> parens (text (show lvl))
116−renderBlock pp norm (Blockquote blocks) = indent 8 $ renderBlocks pp norm blocks
117−renderBlock pp norm (List b ty blockss) = renderList pp norm b ty blockss
118−renderBlock pp norm (CodeBlock attr src Nothing) = indent 8 $ text (T.unpack src)
119−renderBlock pp norm (CodeBlock attr src (Just tm))
120− | isExample attr = indent 4 $
121− text ">" <+> align (group (pp tm)) <$>
122− align (group (pp (norm tm)))
123− | otherwise = indent 4 $ pp tm
124− where isExample (CT.CodeAttr lang info) = T.pack "example" `elem` lang : T.words info
125−renderBlock pp norm (HtmlBlock txt) = text "<html block>" -- TODO
126−renderBlock pp norm HRule = text "----------------------"
127−
128−renderList :: (a -> Doc OutputAnnotation) -> (a -> a)
129− -> Bool -> CT.ListType -> [Blocks (Maybe a)] -> Doc OutputAnnotation
130−renderList pp norm b (CT.Bullet c) blockss = vsep $ map (hang 4 . (char c <+>) . renderBlocks pp norm) blockss
131−renderList pp norm b (CT.Numbered nw i) blockss =
159+renderBlock :: (a -> String -> Doc OutputAnnotation)
160+ -> Block a -> Doc OutputAnnotation
161+renderBlock pp (Para inlines) = renderInlines pp inlines
162+renderBlock pp (Header lvl inlines) = renderInlines pp inlines <+> parens (text (show lvl))
163+renderBlock pp (Blockquote blocks) = indent 8 $ renderBlocks pp blocks
164+renderBlock pp (List b ty blockss) = renderList pp b ty blockss
165+renderBlock pp (CodeBlock attr src tm) = indent 4 $ pp tm (T.unpack src)
166+renderBlock pp (HtmlBlock txt) = text "<html block>" -- TODO
167+renderBlock pp HRule = text "----------------------"
168+
169+renderList :: (a -> String -> Doc OutputAnnotation)
170+ -> Bool -> CT.ListType -> [Blocks a] -> Doc OutputAnnotation
171+renderList pp b (CT.Bullet c) blockss = vsep $ map (hang 4 . (char c <+>) . renderBlocks pp) blockss
172+renderList pp b (CT.Numbered nw i) blockss =
132173 vsep $
133174 zipWith3 (\n p txt -> hang 4 $ text (show n) <> p <+> txt)
134− [i..] (repeat punc) (map (renderBlocks pp norm) blockss)
175+ [i..] (repeat punc) (map (renderBlocks pp) blockss)
135176 where punc = case nw of
136177 CT.PeriodFollowing -> char '.'
137178 CT.ParenFollowing -> char '('
138179
139−renderInlines :: (a -> Doc OutputAnnotation) -> Inlines (Maybe a) -> Doc OutputAnnotation
180+renderInlines :: (a -> String -> Doc OutputAnnotation) -> Inlines a -> Doc OutputAnnotation
140181renderInlines pp = F.foldr (<>) empty . fmap (renderInline pp)
141182
142−renderInline :: (a -> Doc OutputAnnotation) -> Inline (Maybe a) -> Doc OutputAnnotation
183+renderInline :: (a -> String -> Doc OutputAnnotation) -> Inline a -> Doc OutputAnnotation
143184renderInline pp (Str s) = text $ T.unpack s
144185renderInline pp Space = softline
145186renderInline pp SoftBreak = softline
146187renderInline pp LineBreak = line
147188renderInline pp (Emph txt) = annotate (AnnTextFmt ItalicText) $ renderInlines pp txt
148189renderInline pp (Strong txt) = annotate (AnnTextFmt BoldText) $ renderInlines pp txt
149−renderInline pp (Code txt Nothing) = text $ T.unpack txt
150−renderInline pp (Code txt (Just tm)) = pp tm
190+renderInline pp (Code txt tm) = pp tm $ T.unpack txt
151191renderInline pp (Link body url title) = annotate (AnnTextFmt UnderlineText) (renderInlines pp body) <+>
152192 parens (text $ T.unpack url)
153193renderInline pp (Image body url title) = text "<image>" -- TODO
@@ -193,13 +233,13 @@ containsText str (DocString _ blocks) = F.any (blockContains (T.toLower str)) bl
193233 inlineContains str (RawHtml txt) = T.isInfixOf str (T.toLower txt)
194234
195235
196−renderHtml :: Docstring (Maybe Term) -> Html
236+renderHtml :: Docstring DocTerm -> Html
197237renderHtml = renderDoc . fromDocstring
198238 where
199− fromDocstring :: Docstring (Maybe Term) -> CT.Doc
239+ fromDocstring :: Docstring DocTerm -> CT.Doc
200240 fromDocstring (DocString opts blocks) = CT.Doc opts (fmap fromBlock blocks)
201241
202− fromBlock :: Block (Maybe Term) -> CT.Block
242+ fromBlock :: Block DocTerm -> CT.Block
203243 fromBlock (Para inlines) = CT.Para (fmap fromInline inlines)
204244 fromBlock (Header i inlines) = CT.Header i (fmap fromInline inlines)
205245 fromBlock (Blockquote blocks) = CT.Blockquote (fmap fromBlock blocks)
@@ -208,7 +248,7 @@ renderHtml = renderDoc . fromDocstring
208248 fromBlock (HtmlBlock src) = CT.HtmlBlock src
209249 fromBlock HRule = CT.HRule
210250
211− fromInline :: Inline (Maybe Term) -> CT.Inline
251+ fromInline :: Inline DocTerm -> CT.Inline
212252 fromInline (Str t) = CT.Str t
213253 fromInline Space = CT.Space
214254 fromInline SoftBreak = CT.SoftBreak
src/Idris/Elab/Class.hs+2−2
@@ -52,9 +52,9 @@ import Util.Pretty(pretty, text)
5252
5353data MArgTy = IA | EA | CA deriving Show
5454
55−elabClass :: ElabInfo -> SyntaxInfo -> Docstring (Maybe PTerm) ->
55+elabClass :: ElabInfo -> SyntaxInfo -> Docstring (Either Err PTerm) ->
5656 FC -> [PTerm] ->
57− Name -> [(Name, PTerm)] -> [(Name, Docstring (Maybe PTerm))] -> [PDecl] -> Idris ()
57+ Name -> [(Name, PTerm)] -> [(Name, Docstring (Either Err PTerm))] -> [PDecl] -> Idris ()
5858elabClass info syn_in doc fc constraints tn ps pDocs ds
5959 = do let cn = SN (InstanceCtorN tn) -- sUN ("instance" ++ show tn) -- MN 0 ("instance" ++ show tn)
6060 let tty = pibind ps PType
src/Idris/Elab/Clause.hs+1−1
@@ -30,7 +30,7 @@ import Idris.Core.Execute
3030import Idris.Core.Typecheck
3131import Idris.Core.CaseTree
3232
33−import Idris.Docstrings
33+import Idris.Docstrings hiding (Unchecked)
3434import Util.Pretty hiding ((<$>))
3535
3636import Prelude hiding (id, (.))
src/Idris/Elab/Data.hs+8−8
@@ -50,7 +50,7 @@ import Data.List.Split (splitOn)
5050
5151import Util.Pretty(pretty, text)
5252
53−elabData :: ElabInfo -> SyntaxInfo -> Docstring (Maybe PTerm)-> [(Name, Docstring (Maybe PTerm))] -> FC -> DataOpts -> PData -> Idris ()
53+elabData :: ElabInfo -> SyntaxInfo -> Docstring (Either Err PTerm)-> [(Name, Docstring (Either Err PTerm))] -> FC -> DataOpts -> PData -> Idris ()
5454elabData info syn doc argDocs fc opts (PLaterdecl n t_in)
5555 = do let codata = Codata `elem` opts
5656 iLOG (show (fc, doc))
@@ -78,7 +78,7 @@ elabData info syn doc argDocs fc opts (PDatadecl n t_in dcons)
7878 cons <- mapM (elabCon cnameinfo syn n codata (getRetTy cty)) dcons
7979 ttag <- getName
8080 i <- getIState
81− let as = map (const Nothing) (getArgTys cty)
81+ let as = map (const (Left (Msg ""))) (getArgTys cty)
8282 let params = findParams (map snd cons)
8383 logLvl 2 $ "Parameters : " ++ show params
8484 -- TI contains information about mutually declared types - this will
@@ -206,7 +206,7 @@ elabData info syn doc argDocs fc opts (PDatadecl n t_in dcons)
206206
207207elabCon :: ElabInfo -> SyntaxInfo -> Name -> Bool ->
208208 Type -> -- for kind checking
209− (Docstring (Maybe PTerm), [(Name, Docstring (Maybe PTerm))], Name, PTerm, FC, [Name]) ->
209+ (Docstring (Either Err PTerm), [(Name, Docstring (Either Err PTerm))], Name, PTerm, FC, [Name]) ->
210210 Idris (Name, Type)
211211elabCon info syn tn codata expkind (doc, argDocs, n, t_in, fc, forcenames)
212212 = do checkUndefined fc n
@@ -279,7 +279,7 @@ type EliminatorState = StateT (Map.Map String Int) Idris
279279-- FIXME: Many things have name starting with elim internally since this was the only purpose in the first edition of the function
280280-- rename to caseFun to match updated intend
281281elabCaseFun :: Bool -> [Int] -> Name -> PTerm ->
282− [(Docstring (Maybe PTerm), [(Name, Docstring (Maybe PTerm))], Name, PTerm, FC, [Name])] ->
282+ [(Docstring (Either Err PTerm), [(Name, Docstring (Either Err PTerm))], Name, PTerm, FC, [Name])] ->
283283 ElabInfo -> EliminatorState ()
284284elabCaseFun ind paramPos n ty cons info = do
285285 elimLog $ "Elaborating case function"
@@ -298,7 +298,7 @@ elabCaseFun ind paramPos n ty cons info = do
298298 let motiveConstr = [(motiveName, expl, motive)]
299299 let scrutinee = (scrutineeName, expl, applyCons n (interlievePos paramPos generalParams scrutineeIdxs 0))
300300 let eliminatorTy = piConstr (generalParams ++ motiveConstr ++ consTerms ++ scrutineeIdxs ++ [scrutinee]) (applyMotive (map (\(n,_,_) -> PRef elimFC n) scrutineeIdxs) (PRef elimFC scrutineeName))
301− let eliminatorTyDecl = PTy (fmap (const Nothing) . parseDocstring . T.pack $ show n) [] defaultSyntax elimFC [TotalFn] elimDeclName eliminatorTy
301+ let eliminatorTyDecl = PTy (fmap (const (Left $ Msg "")) . parseDocstring . T.pack $ show n) [] defaultSyntax elimFC [TotalFn] elimDeclName eliminatorTy
302302 let clauseConsElimArgs = map getPiName consTerms
303303 let clauseGeneralArgs' = map getPiName generalParams ++ [motiveName] ++ clauseConsElimArgs
304304 let clauseGeneralArgs = map (\arg -> pexp (PRef elimFC arg)) clauseGeneralArgs'
@@ -448,7 +448,7 @@ elabCaseFun ind paramPos n ty cons info = do
448448 splitArgPms _ = ([],[])
449449
450450
451− implicitIndexes :: (Docstring (Maybe PTerm), Name, PTerm, FC, [Name]) -> EliminatorState [(Name, Plicity, PTerm)]
451+ implicitIndexes :: (Docstring (Either Err PTerm), Name, PTerm, FC, [Name]) -> EliminatorState [(Name, Plicity, PTerm)]
452452 implicitIndexes (cns@(doc, cnm, ty, fc, fs)) = do
453453 i <- State.lift getIState
454454 implargs' <- case lookupCtxt cnm (idris_implicits i) of
@@ -463,7 +463,7 @@ elabCaseFun ind paramPos n ty cons info = do
463463 in return $ filter (\(n,_,_) -> not (n `elem` oldParams))implargs
464464 _ -> return implargs
465465
466− extractConsTerm :: (Docstring (Maybe PTerm), [(Name, Docstring (Maybe PTerm))], Name, PTerm, FC, [Name]) -> [(Name, Plicity, PTerm)] -> EliminatorState PTerm
466+ extractConsTerm :: (Docstring (Either Err PTerm), [(Name, Docstring (Either Err PTerm))], Name, PTerm, FC, [Name]) -> [(Name, Plicity, PTerm)] -> EliminatorState PTerm
467467 extractConsTerm (doc, argDocs, cnm, ty, fc, fs) generalParameters = do
468468 let cons' = replaceParams paramPos generalParameters ty
469469 let (args, resTy) = splitPi cons'
@@ -499,7 +499,7 @@ elabCaseFun ind paramPos n ty cons info = do
499499 convertImplPi (PImp {getTm = t, pname = n}) = Just (n, expl, t)
500500 convertImplPi _ = Nothing
501501
502− generateEliminatorClauses :: (Docstring (Maybe PTerm), [(Name, Docstring (Maybe PTerm))], Name, PTerm, FC, [Name]) -> Name -> [PArg] -> [(Name, Plicity, PTerm)] -> EliminatorState PClause
502+ generateEliminatorClauses :: (Docstring (Either Err PTerm), [(Name, Docstring (Either Err PTerm))], Name, PTerm, FC, [Name]) -> Name -> [PArg] -> [(Name, Plicity, PTerm)] -> EliminatorState PClause
503503 generateEliminatorClauses (doc, _, cnm, ty, fc, fs) cnsElim generalArgs generalParameters = do
504504 let cons' = replaceParams paramPos generalParameters ty
505505 let (args, resTy) = splitPi cons'
src/Idris/Elab/Provider.hs+1−1
@@ -98,7 +98,7 @@ elabProvider info syn fc what n
9898 logLvl 3 $ "Elaborated provider " ++ show n ++ " as: " ++ show tm
9999 | ProvPostulate _ <- what ->
100100 do -- Add the postulate
101− elabPostulate info syn (fmap (const Nothing) . parseDocstring $ T.pack "Provided postulate") fc [] n (delab i tm)
101+ elabPostulate info syn (fmap (const (Left $ Msg "")) . parseDocstring $ T.pack "Provided postulate") fc [] n (delab i tm)
102102 logLvl 3 $ "Elaborated provided postulate " ++ show n
103103 | otherwise ->
104104 ierror . Msg $ "Attempted to provide a postulate where a term was expected."
src/Idris/Elab/Record.hs+2−2
@@ -50,8 +50,8 @@ import Data.List.Split (splitOn)
5050
5151import Util.Pretty(pretty, text)
5252
53−elabRecord :: ElabInfo -> SyntaxInfo -> Docstring (Maybe PTerm) -> FC -> Name ->
54− PTerm -> DataOpts -> Docstring (Maybe PTerm) -> Name -> PTerm -> Idris ()
53+elabRecord :: ElabInfo -> SyntaxInfo -> Docstring (Either Err PTerm) -> FC -> Name ->
54+ PTerm -> DataOpts -> Docstring (Either Err PTerm) -> Name -> PTerm -> Idris ()
5555elabRecord info syn doc fc tyn ty opts cdoc cn cty_in
5656 = do elabData info syn doc [] fc opts (PDatadecl tyn ty [(cdoc, [], cn, cty_in, fc, [])])
5757 -- TODO think: something more in info?
src/Idris/Elab/Type.hs+3−3
@@ -114,12 +114,12 @@ buildType info syn fc opts n ty' = do
114114 param_pos i ns t = []
115115
116116-- | Elaborate a top-level type declaration - for example, "foo : Int -> Int".
117−elabType :: ElabInfo -> SyntaxInfo -> Docstring (Maybe PTerm)-> [(Name, Docstring (Maybe PTerm))] ->
117+elabType :: ElabInfo -> SyntaxInfo -> Docstring (Either Err PTerm)-> [(Name, Docstring (Either Err PTerm))] ->
118118 FC -> FnOpts -> Name -> PTerm -> Idris Type
119119elabType = elabType' False
120120
121121elabType' :: Bool -> -- normalise it
122− ElabInfo -> SyntaxInfo -> Docstring (Maybe PTerm) -> [(Name, Docstring (Maybe PTerm))] ->
122+ ElabInfo -> SyntaxInfo -> Docstring (Either Err PTerm) -> [(Name, Docstring (Either Err PTerm))] ->
123123 FC -> FnOpts -> Name -> PTerm -> Idris Type
124124elabType' norm info syn doc argDocs fc opts n ty' = {- let ty' = piBind (params info) ty_in
125125 n = liftname info n_in in -}
@@ -207,7 +207,7 @@ elabType' norm info syn doc argDocs fc opts n ty' = {- let ty' = piBind (params
207207 , ns4 == map txt ["Reflection","Language"] = True
208208 tyIsHandler _ = False
209209
210−elabPostulate :: ElabInfo -> SyntaxInfo -> Docstring (Maybe PTerm) ->
210+elabPostulate :: ElabInfo -> SyntaxInfo -> Docstring (Either Err PTerm) ->
211211 FC -> FnOpts -> Name -> PTerm -> Idris ()
212212elabPostulate info syn doc fc opts n ty = do
213213 elabType info syn doc [] fc opts n ty
src/Idris/Elab/Value.hs+21−8
@@ -1,4 +1,5 @@
11{-# LANGUAGE PatternGuards #-}
2+{-# OPTIONS_GHC -fwarn-incomplete-patterns -Werror #-}
23module Idris.Elab.Value(elabVal, elabValBind, elabDocTerms) where
34
45import Idris.AbsSyntax
@@ -22,7 +23,7 @@ import Idris.Elab.Utils
2223
2324import Idris.Core.TT
2425import Idris.Core.Elaborate hiding (Tactic(..))
25−import Idris.Core.Evaluate
26+import Idris.Core.Evaluate hiding (Unchecked)
2627import Idris.Core.Execute
2728import Idris.Core.Typecheck
2829import Idris.Core.CaseTree
@@ -88,11 +89,23 @@ elabVal info aspat tm_in
8889
8990
9091
91−elabDocTerms :: ElabInfo -> Docstring (Maybe PTerm) -> Idris (Docstring (Maybe Term))
92−elabDocTerms info str = Traversable.mapM decorate str
93− where decorate Nothing = return Nothing
94− decorate (Just pt) = fmap (fmap fst) (tryElabVal info ERHS pt)
95− tryElabVal :: ElabInfo -> ElabMode -> PTerm -> Idris (Maybe (Term, Type))
92+elabDocTerms :: ElabInfo -> Docstring (Either Err PTerm) -> Idris (Docstring DocTerm)
93+elabDocTerms info str = do typechecked <- Traversable.mapM decorate str
94+ return $ checkDocstring mkDocTerm typechecked
95+ where decorate (Left err) = return (Left err)
96+ decorate (Right pt) = fmap (fmap fst) (tryElabVal info ERHS pt)
97+
98+ tryElabVal :: ElabInfo -> ElabMode -> PTerm -> Idris (Either Err (Term, Type))
9699 tryElabVal info aspat tm_in
97− = idrisCatch (fmap Just $ elabVal info aspat tm_in)
98− (const $ return Nothing)
100+ = idrisCatch (fmap Right $ elabVal info aspat tm_in)
101+ (return . Left)
102+
103+ mkDocTerm :: String -> [String] -> String -> Either Err Term -> DocTerm
104+ mkDocTerm lang attrs src (Left err)
105+ | map toLower lang == "idris" = Failing err
106+ | otherwise = Unchecked
107+ mkDocTerm lang attrs src (Right tm)
108+ | map toLower lang == "idris" = if "example" `elem` map (map toLower) attrs
109+ then Example tm
110+ else Checked tm
111+ | otherwise = Unchecked
src/Idris/ElabDecls.hs+1−1
@@ -38,7 +38,7 @@ import Idris.Core.Execute
3838import Idris.Core.Typecheck
3939import Idris.Core.CaseTree
4040
41−import Idris.Docstrings
41+import Idris.Docstrings hiding (Unchecked)
4242
4343import Prelude hiding (id, (.))
4444import Control.Category
src/Idris/IBC.hs+17−3
@@ -32,7 +32,7 @@ import Codec.Compression.Zlib (compress)
3232import Util.Zlib (decompressEither)
3333
3434ibcVersion :: Word8
35−ibcVersion = 83
35+ibcVersion = 84
3636
3737data IBCFile = IBCFile { ver :: Word8,
3838 sourcefile :: FilePath,
@@ -61,7 +61,7 @@ data IBCFile = IBCFile { ver :: Word8,
6161 ibc_fninfo :: [(Name, FnInfo)],
6262 ibc_cg :: [(Name, CGInfo)],
6363 ibc_defs :: [(Name, Def)],
64− ibc_docstrings :: [(Name, (Docstring (Maybe Term), [(Name, Docstring (Maybe Term))]))],
64+ ibc_docstrings :: [(Name, (Docstring D.DocTerm, [(Name, Docstring D.DocTerm)]))],
6565 ibc_transforms :: [(Name, (Term, Term))],
6666 ibc_errRev :: [(Term, Term)],
6767 ibc_coercions :: [Name],
@@ -459,7 +459,7 @@ pDefs syms ds
459459 update (Proj t i) = Proj (update t) i
460460 update t = t
461461
462−pDocs :: [(Name, (Docstring (Maybe Term), [(Name, Docstring (Maybe Term))]))] -> Idris ()
462+pDocs :: [(Name, (Docstring D.DocTerm, [(Name, Docstring D.DocTerm)]))] -> Idris ()
463463pDocs ds = mapM_ (\ (n, a) -> addDocStr n (fst a) (snd a)) ds
464464
465465pAccess :: [(Name, Accessibility)] -> Idris ()
@@ -538,6 +538,20 @@ instance Binary CT.Options where
538538 x4 <- get
539539 return (CT.Options x1 x2 x3 x4)
540540
541+instance Binary D.DocTerm where
542+ put D.Unchecked = putWord8 0
543+ put (D.Checked t) = putWord8 1 >> put t
544+ put (D.Example t) = putWord8 2 >> put t
545+ put (D.Failing e) = putWord8 3 >> put e
546+
547+ get = do i <- getWord8
548+ case i of
549+ 0 -> return D.Unchecked
550+ 1 -> fmap D.Checked get
551+ 2 -> fmap D.Example get
552+ 3 -> fmap D.Failing get
553+ _ -> error "Corrupted binary data for DocTerm"
554+
541555instance Binary a => Binary (D.Block a) where
542556 put (D.Para lines) = do putWord8 0 ; put lines
543557 put (D.Header i lines) = do putWord8 1 ; put i ; put lines
src/Idris/IdeSlave.hs+13
@@ -1,3 +1,5 @@
1+{-# OPTIONS_GHC -fwarn-incomplete-patterns -Werror #-}
2+
13{-# LANGUAGE FlexibleInstances, IncoherentInstances, PatternGuards #-}
24
35module Idris.IdeSlave(parseMessage, convSExp, IdeSlaveCommand(..), sexpToCommand, toSExp, SExp(..), SExpable, Opt(..), ideSlaveEpoch, getLen, getNChar) where
@@ -151,6 +153,7 @@ instance SExpable OutputAnnotation where
151153 EQ -> "isomorphic"
152154 LT -> "more general than searched type"
153155 GT -> "more specific than searched type"
156+ toSExp (AnnErr e) = toSExp [(SymbolAtom "error", StringAtom (encodeErr e))]
154157
155158encodeTerm :: [(Name, Bool)] -> Term -> String
156159encodeTerm bnd tm = UTF8.toString . Base64.encode . Lazy.toStrict . Binary.encode $
@@ -159,6 +162,12 @@ encodeTerm bnd tm = UTF8.toString . Base64.encode . Lazy.toStrict . Binary.encod
159162decodeTerm :: String -> ([(Name, Bool)], Term)
160163decodeTerm = Binary.decode . Lazy.fromStrict . Base64.decodeLenient . UTF8.fromString
161164
165+encodeErr :: Err -> String
166+encodeErr e = UTF8.toString . Base64.encode . Lazy.toStrict . Binary.encode $ e
167+
168+decodeErr :: String -> Err
169+decodeErr = Binary.decode . Lazy.fromStrict . Base64.decodeLenient . UTF8.fromString
170+
162171instance SExpable FC where
163172 toSExp (FC f (sl, sc) (el, ec)) =
164173 toSExp ((SymbolAtom "filename", StringAtom f),
@@ -219,6 +228,8 @@ data IdeSlaveCommand = REPLCompletions String
219228 | TermShowImplicits [(Name, Bool)] Term
220229 | TermNoImplicits [(Name, Bool)] Term
221230 | PrintDef String
231+ | ErrString Err
232+ | ErrPPrint Err
222233
223234sexpToCommand :: SExp -> Maybe IdeSlaveCommand
224235sexpToCommand (SexpList (x:[])) = sexpToCommand x
@@ -262,6 +273,8 @@ sexpToCommand (SexpList [SymbolAtom "show-term-implicits", StringAtom encoded])
262273sexpToCommand (SexpList [SymbolAtom "hide-term-implicits", StringAtom encoded]) = let (bnd, tm) = decodeTerm encoded in
263274 Just (TermNoImplicits bnd tm)
264275sexpToCommand (SexpList [SymbolAtom "print-definition", StringAtom name]) = Just (PrintDef name)
276+sexpToCommand (SexpList [SymbolAtom "error-string", StringAtom encoded]) = Just . ErrString . decodeErr $ encoded
277+sexpToCommand (SexpList [SymbolAtom "error-pprint", StringAtom encoded]) = Just . ErrPPrint . decodeErr $ encoded
265278sexpToCommand _ = Nothing
266279
267280parseMessage :: String -> Either Err (SExp, Integer)
src/Idris/Output.hs+6−3
@@ -1,4 +1,4 @@
1−{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
1+{-# OPTIONS_GHC -fwarn-incomplete-patterns -Werror #-}
22
33module Idris.Output where
44
@@ -177,12 +177,13 @@ printUndefinedNames ns = text "Undefined " <> names <> text "."
177177
178178
179179prettyDocumentedIst :: IState
180− -> (Name, PTerm, Maybe (Docstring (Maybe Term)))
180+ -> (Name, PTerm, Maybe (Docstring DocTerm))
181181 -> Doc OutputAnnotation
182182prettyDocumentedIst ist (name, ty, docs) =
183183 prettyName True True [] name <+> colon <+> align (prettyIst ist ty) <$>
184− fromMaybe empty (fmap (\d -> renderDocstring ppTm (normaliseAll (tt_ctxt ist) []) d <> line) docs)
184+ fromMaybe empty (fmap (\d -> renderDocstring (renderDocTerm ppTm norm) d <> line) docs)
185185 where ppTm = pprintDelab ist
186+ norm = normaliseAll (tt_ctxt ist) []
186187
187188
188189renderExternal :: OutputFmt -> Int -> Doc OutputAnnotation -> Idris String
@@ -220,6 +221,7 @@ renderExternal fmt width doc
220221 decorate HTMLOutput (AnnTextFmt _) = id -- TODO
221222 decorate HTMLOutput (AnnTerm _ _) = id
222223 decorate HTMLOutput (AnnSearchResult _) = id
224+ decorate HTMLOutput (AnnErr _) = id
223225
224226 decorate LaTeXOutput (AnnName _ (Just TypeOutput) _ _) =
225227 latex "IdrisType"
@@ -242,6 +244,7 @@ renderExternal fmt width doc
242244 decorate LaTeXOutput (AnnTextFmt _) = id -- TODO
243245 decorate LaTeXOutput (AnnTerm _ _) = id
244246 decorate LaTeXOutput (AnnSearchResult _) = id
247+ decorate LaTeXOutput (AnnErr _) = id
245248
246249 tag cls docs str = "<span class=\""++cls++"\""++title++">" ++ str ++ "</span>"
247250 where title = maybe "" (\d->" title=\"" ++ d ++ "\"") docs
src/Idris/ParseData.hs+3−3
@@ -4,7 +4,7 @@ module Idris.ParseData where
44import Prelude hiding (pi)
55
66import Text.Trifecta.Delta
7−import Text.Trifecta hiding (span, stringLiteral, charLiteral, natural, symbol, char, string, whiteSpace)
7+import Text.Trifecta hiding (span, stringLiteral, charLiteral, natural, symbol, char, string, whiteSpace, Err)
88import Text.Parser.LookAhead
99import Text.Parser.Expression
1010import qualified Text.Parser.Token as Tok
@@ -172,7 +172,7 @@ data_ syn = do (doc, argDocs, acc, dataOpts) <- try (do
172172{- | Parses a type constructor declaration
173173 Constructor ::= DocComment? FnName TypeSig;
174174-}
175−constructor :: SyntaxInfo -> IdrisParser (Docstring (Maybe PTerm), [(Name, Docstring (Maybe PTerm))], Name, PTerm, FC, [Name])
175+constructor :: SyntaxInfo -> IdrisParser (Docstring (Either Err PTerm), [(Name, Docstring (Either Err PTerm))], Name, PTerm, FC, [Name])
176176constructor syn
177177 = do (doc, argDocs) <- option noDocs docComment
178178 cn_in <- fnName; fc <- getFC
@@ -191,7 +191,7 @@ constructor syn
191191{- | Parses a constructor for simple discriminated union data types
192192 SimpleConstructor ::= FnName SimpleExpr* DocComment?
193193-}
194−simpleConstructor :: SyntaxInfo -> IdrisParser (Docstring (Maybe PTerm), [(Name, Docstring (Maybe PTerm))], Name, [PTerm], FC, [Name])
194+simpleConstructor :: SyntaxInfo -> IdrisParser (Docstring (Either Err PTerm), [(Name, Docstring (Either Err PTerm))], Name, [PTerm], FC, [Name])
195195simpleConstructor syn
196196 = do (doc, _) <- option noDocs (try docComment)
197197 ist <- get
src/Idris/ParseExpr.hs+4−4
@@ -5,7 +5,7 @@ module Idris.ParseExpr where
55import Prelude hiding (pi)
66
77import Text.Trifecta.Delta
8−import Text.Trifecta hiding (span, stringLiteral, charLiteral, natural, symbol, char, string, whiteSpace)
8+import Text.Trifecta hiding (span, stringLiteral, charLiteral, natural, symbol, char, string, whiteSpace, Err)
99import Text.Parser.LookAhead
1010import Text.Parser.Expression
1111import qualified Text.Parser.Token as Tok
@@ -53,11 +53,11 @@ fullExpr syn = do x <- expr syn
5353 i <- get
5454 return $ debindApp syn (desugar syn i x)
5555
56−tryFullExpr :: SyntaxInfo -> IState -> String -> Maybe PTerm
56+tryFullExpr :: SyntaxInfo -> IState -> String -> Either Err PTerm
5757tryFullExpr syn st input =
5858 case runparser (fullExpr syn) st "" input of
59− Success tm -> Just tm
60− _ -> Nothing
59+ Success tm -> Right tm
60+ Failure e -> Left (Msg (show e))
6161
6262{- | Parses an expression
6363@
src/Idris/Parser.hs+1−1
@@ -37,7 +37,7 @@ import Idris.ParseOps
3737import Idris.ParseExpr
3838import Idris.ParseData
3939
40−import Idris.Docstrings
40+import Idris.Docstrings hiding (Unchecked)
4141
4242import Paths_idris
4343
src/Idris/REPL.hs+13−1
@@ -485,7 +485,19 @@ runIdeSlaveCommand h id orig fn mods (IdeSlave.PrintDef name) =
485485 [] -> Left ("Didn't understand name '" ++ s ++ "'")
486486 [n] -> Right $ sUN n
487487 (n:ns) -> Right $ sNS (sUN n) ns
488−
488+runIdeSlaveCommand h id orig fn modes (IdeSlave.ErrString e) =
489+ do ist <- getIState
490+ let out = displayS . renderPretty 1.0 60 $ pprintErr ist e
491+ msg = (IdeSlave.SymbolAtom "ok", IdeSlave.StringAtom $ out "")
492+ runIO . hPutStrLn h $ IdeSlave.convSExp "return" msg id
493+runIdeSlaveCommand h id orig fn modes (IdeSlave.ErrPPrint e) =
494+ do ist <- getIState
495+ let (out, spans) =
496+ displaySpans .
497+ renderPretty 0.9 80 .
498+ fmap (fancifyAnnots ist) $ pprintErr ist e
499+ msg = (IdeSlave.SymbolAtom "ok", out, spans)
500+ runIO . hPutStrLn h $ IdeSlave.convSExp "return" msg id
489501
490502-- | Show a term for IDESlave with the specified implicitness
491503ideSlaveForceTermImplicits :: Handle -> Integer -> [(Name, Bool)] -> Bool -> Term -> Idris ()
test/interactive005/input+3
@@ -1,12 +1,15 @@
1+:consolewidth 80
12the Nat (1 + 2)
23:exec
34:c bytecode hello.bytecode
45:c c hello
56:doc main
67:reload
8+:consolewidth 80
79:load interactive005.idr
810:total main
911:exec
12+:consolewidth 80
1013:t id
1114:set showimplicits
1215:t id
test/interactive005/run+1−1
@@ -1,5 +1,5 @@
11#!/usr/bin/env bash
2−idris --quiet interactive005.idr < input
2+idris --nocolour --quiet interactive005.idr < input
33rm -f *.ibc
44rm -f hello.bytecode
55rm -f hello