on master help sign in
Merge branch 'master' into JavaBackendFixes
4aadf4cJan Bessai
.travis.yml+8−6
@@ -6,6 +6,8 @@ before_install:
6 - sudo apt-get install -qq libghc-unordered-containers-dev libghc-mtl-dev libghc-network-dev libghc-xml-dev libghc-transformers-dev libghc-text-dev libghc-utf8-string-dev libghc-vector-dev libghc-split-dev libghc-ansi-terminal-dev libghc-ansi-wl-pprint-dev
6 - sudo apt-get install -qq libghc-unordered-containers-dev libghc-mtl-dev libghc-network-dev libghc-xml-dev libghc-transformers-dev libghc-text-dev libghc-utf8-string-dev libghc-vector-dev libghc-split-dev libghc-ansi-terminal-dev libghc-ansi-wl-pprint-dev
7 # trifecta dependencies
7 # trifecta dependencies
8 - sudo apt-get install -qq libghc-blaze-builder-dev libghc-blaze-html-dev libghc-data-lens-dev libghc-bifunctors-dev libghc-hashable-dev libghc-semigroups-dev libghc-semigroupoids-dev libghc-parallel-dev libghc-comonad-dev libghc-terminfo-dev libghc-keys-dev
8 - sudo apt-get install -qq libghc-blaze-builder-dev libghc-blaze-html-dev libghc-data-lens-dev libghc-bifunctors-dev libghc-hashable-dev libghc-semigroups-dev libghc-semigroupoids-dev libghc-parallel-dev libghc-comonad-dev libghc-terminfo-dev libghc-keys-dev
9+ # Haddock dependencies
10+ - sudo apt-get install hscolour
9 # test dependency
11 # test dependency
10 - sudo apt-get install -qq expect
12 - sudo apt-get install -qq expect
11install:
13install:
@@ -17,11 +19,11 @@ before_script:
17 - cd idris*
19 - cd idris*
18script:
20script:
19 - cabal configure -f FFI -f LLVM
21 - cabal configure -f FFI -f LLVM
20− - cabal build
22+ - if [[ "$TESTS" != "doc" ]]; then cabal build; fi
21− - cabal copy
23+ - if [[ "$TESTS" != "doc" ]]; then cabal copy; fi
22 - make -j2 $TESTS
24 - make -j2 $TESTS
23env:
25env:
24− # TESTS=doc
26+ - TESTS="doc"
25− - TESTS=test_c
27+ - TESTS="test_c"
26− - TESTS=test_llvm
28+ - TESTS="test_llvm"
27− - TESTS=test_js
29+ - TESTS="test_js"
CHANGELOG+35
@@ -1,6 +1,41 @@
1+New in 0.9.14:
2+--------------
3+* Support for running tests for a package with the tests section of .ipkg files and the
4+ --testpkg command-line option
5+* Clearly distinguish between type providers and postulate providers at the use site
6+
1New in 0.9.13:
7New in 0.9.13:
2--------------
8--------------
3* IDE support for retrieving structured information about metavariables
9* IDE support for retrieving structured information about metavariables
10+* Experimental Bits support for JavaScript
11+* IdrisDoc: a Haddock- and JavaDoc-like HTML documentation generator
12+* Command line option -e (or --eval) to evaluate expressions without loading the
13+ REPL. This is useful for writing more portable tests.
14+* Many more of the basic functions and datatypes are documented.
15+* Primitive types such as Int and String are documented
16+* Removed javascript lib in favor of idris-hackers/iQuery
17+* Specify codegen for :compile REPL command (e.g. :compile javascript program.js)
18+* Remove :info REPL command, subsume and enhance its functionality in the :doc command
19+* New (first class) nested record update/access syntax:
20+ record { a->b->c = val } x -- sets field accessed by c (b (a x)) to val
21+ record { a->b->c } x -- accesses field, equivalent to c (b (a x))
22+* The banner at startup can be suppressed by adding :set nobanner to the initialisation script.
23+* :apropos now accepts space-delimited lists of query items, and searches for the conjunction
24+ of its inputs. It also accepts binder syntax as search strings - for instance, -> finds
25+ functions.
26+* Totality errors are now treated as warnings until code generation time, when they become
27+ errors again. This allows users to use the interactive editing features to fix totality
28+ issues, but no programs that violate the stated assumptions will actually run.
29+* Added :makelemma command, which adds a new top level definition to solve
30+ a metavariable.
31+* Extend :addclause to add instance bodies as well as definitions
32+* Reverse parameters to BoundedList -- now matches Vect, and is easier to instantiate classes.
33+* Move foldl into Foldable so it can be overridden.
34+* Experimental :search REPL command for finding functions by type
35+
36+Internal changes
37+
38+* New implementation of erasure
4
39
5New in 0.9.12:
40New in 0.9.12:
6--------------
41--------------
CONTRIBUTORS+7−4
@@ -8,24 +8,27 @@ Edwin Brady
8David Raymond Christiansen
8David Raymond Christiansen
9Jason Dagit
9Jason Dagit
10Simon Fowler
10Simon Fowler
11+Google
11Cezar Ionescu
12Cezar Ionescu
12Irene Knapp
13Irene Knapp
14+Paul Koerbitz
15+Shea Levy
13Mathnerd314
16Mathnerd314
14Hannes Mehnert
17Hannes Mehnert
15Mekeor Melire
18Mekeor Melire
16Melissa Mozifian
19Melissa Mozifian
17Dominic Mulligan
20Dominic Mulligan
18Jan de Muijnck-Hughes
21Jan de Muijnck-Hughes
19−raichoo
20Tom Prince
22Tom Prince
23+raichoo
24+Philip Rasmussen
25+Reynir Reynisson
21Seo Sanghyeon
26Seo Sanghyeon
22Benjamin Saunders
27Benjamin Saunders
23startling
28startling
24Chetan T
29Chetan T
30+Matúš Tejiščák
25Dirk Ullrich
31Dirk Ullrich
26Leif Warner
32Leif Warner
27Daniel Waterworth
33Daniel Waterworth
28Jonas Westerlund
34Jonas Westerlund
29−Reynir Reynisson
30−Shea Levy
31−
Makefile+1−1
@@ -43,7 +43,7 @@ linecount:
43
43
44#Note: this doesn't yet link to Hackage properly
44#Note: this doesn't yet link to Hackage properly
45doc: dist/setup-config
45doc: dist/setup-config
46− $(CABAL) haddock --executables --hyperlink-source --html --hoogle --html-location="http://hackage.haskell.org/packages/archive/\$$pkg/latest/doc/html" --haddock-options="--title Idris"
46+ $(CABAL) haddock --hyperlink-source --html --hoogle --html-location="http://hackage.haskell.org/packages/archive/\$$pkg/latest/doc/html" --haddock-options="--title Idris"
47
47
48
48
49dist/setup-config:
49dist/setup-config:
benchmarks/ALL+1
@@ -1,2 +1,3 @@
1trivial/sortvec 2000
1trivial/sortvec 2000
2quasigroups/qgsolve board
2quasigroups/qgsolve board
3+fasta/fasta 1
benchmarks/fasta/fasta.idrnew file+84
@@ -0,0 +1,84 @@
1+module Main
2+
3+import System
4+import Data.Floats
5+
6+alu : String
7+alu = "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGG\
8+ \TCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGG\
9+ \CGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGC\
10+ \GGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA"
11+
12+iub : List (Char, Float)
13+iub = [('a',0.27),('c',0.12),('g',0.12),('t',0.27),('B',0.02)
14+ ,('D',0.02),('H',0.02),('K',0.02),('M',0.02),('N',0.02)
15+ ,('R',0.02),('S',0.02),('V',0.02),('W',0.02),('Y',0.02)]
16+
17+homosapiens : List (Char, Float)
18+homosapiens = [('a',0.3029549426680),('c',0.1979883004921)
19+ ,('g',0.1975473066391),('t',0.3015094502008)]
20+
21+
22+takeRepeat : Int -> String -> String
23+takeRepeat n s = if n > m
24+ then s ++ takeRepeat (n-m) s
25+ else pack $ take (cast n) $ unpack s
26+ where
27+ m = cast $ length s
28+
29+splitAt' : Nat -> String -> (String, String)
30+splitAt' n s = let s' = unpack s in (pack $ take n s', pack $ drop n s')
31+
32+writeAlu : String -> String -> IO ()
33+writeAlu name s0 = putStrLn name $> go s0
34+ where
35+ go "" = return ()
36+ go s = let (h,t) = splitAt' 60 s in putStrLn h $> go t
37+
38+replicate : Int -> Char -> String
39+replicate 0 c = ""
40+replicate n c = singleton c <+> replicate (n-1) c
41+
42+scanl : (f : acc -> a -> acc) -> acc -> List a -> List acc
43+scanl f q ls = q :: (case ls of
44+ [] => []
45+ x::xs => scanl f (f q x) xs)
46+
47+accum : (Char,Float) -> (Char,Float) -> (Char,Float)
48+accum (_,p) (c,q) = (c,p+q)
49+
50+make : String -> Int -> List (Char, Float) -> Int -> IO Int
51+make name n0 tbl seed0 = do
52+ putStrLn name
53+ make' n0 0 seed0 ""
54+ where
55+ modulus : Int
56+ modulus = 139968
57+
58+ fill : List (Char,Float) -> Int -> List String
59+ fill ((c,p) :: cps) j =
60+ let k = min modulus (cast (cast modulus * p + 1))
61+ in replicate (k - j) c :: fill cps k
62+ fill _ _ = []
63+
64+ lookupTable : String
65+ lookupTable = Foldable.concat (fill (scanl accum ('a',0) tbl) 0)
66+
67+ make' : Int -> Int -> Int -> String -> IO Int
68+ make' 0 col seed buf = when (col > 0) (putStrLn buf) $> return seed
69+ make' n col seed buf = do
70+ let newseed = modInt (seed * 3877 + 29573) modulus
71+ let nextchar = strIndex lookupTable newseed
72+ let newbuf = buf <+> singleton nextchar
73+ if col+1 >= 60
74+ then putStrLn newbuf $> make' (n-1) 0 newseed ""
75+ else make' (n-1) (col+1) newseed newbuf
76+
77+
78+main : IO ()
79+main = do
80+ (_ :: n :: _) <- getArgs
81+ writeAlu ">ONE Homo sapiens alu" (takeRepeat (fromInteger (cast n)*2) alu)
82+ nseed <- make ">TWO IUB ambiguity codes" (fromInteger (cast n)*3) iub 42
83+ make ">THREE Homo sapiens frequency" (fromInteger (cast n)*5) homosapiens nseed
84+ return ()
benchmarks/fasta/fasta.ipkgnew file+6
@@ -0,0 +1,6 @@
1+package fasta
2+
3+modules = fasta
4+
5+executable = fasta
6+main = fasta
config.mk+1−1
@@ -1,4 +1,4 @@
1−CC :=cc
1+CC ?=cc
2CABAL :=cabal
2CABAL :=cabal
3CFLAGS :=-O2 -Wall $(CFLAGS)
3CFLAGS :=-O2 -Wall $(CFLAGS)
4#CABALFLAGS :=
4#CABALFLAGS :=
idris.cabal+89−8
@@ -1,5 +1,5 @@
1Name: idris
1Name: idris
2−Version: 0.9.12
2+Version: 0.9.13
3License: BSD3
3License: BSD3
4License-file: LICENSE
4License-file: LICENSE
5Author: Edwin Brady
5Author: Edwin Brady
@@ -46,7 +46,8 @@ Cabal-Version: >= 1.8
46
46
47Build-type: Custom
47Build-type: Custom
48
48
49+Data-files: idrisdoc/styles.css
49−Data-files: jsrts/Runtime-browser.js
50+ jsrts/Runtime-browser.js
50 jsrts/Runtime-common.js
51 jsrts/Runtime-common.js
51 jsrts/Runtime-node.js
52 jsrts/Runtime-node.js
52 jsrts/jsbn/jsbn.js
53 jsrts/jsbn/jsbn.js
@@ -65,6 +66,7 @@ Extra-source-files:
65
66
66 rts/*.c
67 rts/*.c
67 rts/*.h
68 rts/*.h
69+ rts/windows/*.c
68 rts/Makefile
70 rts/Makefile
69
71
70 libs/Makefile
72 libs/Makefile
@@ -88,6 +90,7 @@ Extra-source-files:
88 libs/base/Language/Reflection/*.idr
90 libs/base/Language/Reflection/*.idr
89 libs/base/Makefile
91 libs/base/Makefile
90 libs/base/Network/*.idr
92 libs/base/Network/*.idr
93+ libs/base/System/*.idr
91 libs/base/System/Concurrency/*.idr
94 libs/base/System/Concurrency/*.idr
92 libs/base/Syntax/*.idr
95 libs/base/Syntax/*.idr
93
96
@@ -102,11 +105,6 @@ Extra-source-files:
102 libs/oldeffects/Effect/*.idr
105 libs/oldeffects/Effect/*.idr
103 libs/oldeffects/*.idr
106 libs/oldeffects/*.idr
104
107
105− libs/javascript/*.idr
106− libs/javascript/JavaScript/*.idr
107− libs/javascript/Makefile
108− libs/javascript/javascript.ipkg
109−
110 llvm/*.c
108 llvm/*.c
111 llvm/Makefile
109 llvm/Makefile
112
110
@@ -227,6 +225,23 @@ Extra-source-files:
227 test/reg038/run
225 test/reg038/run
228 test/reg038/*.idr
226 test/reg038/*.idr
229 test/reg038/expected
227 test/reg038/expected
228+ test/reg039/run
229+ test/reg039/*.idr
230+ test/reg039/expected
231+ test/reg040/run
232+ test/reg040/*.idr
233+ test/reg040/expected
234+ test/reg041/run
235+ test/reg041/*.idr
236+ test/reg041/expected
237+ test/reg042/run
238+ test/reg042/*.idr
239+ test/reg042/expected
240+ test/reg043/run
241+ test/reg043/expected
242+ test/reg044/run
243+ test/reg044/*.idr
244+ test/reg044/expected
230
245
231 test/basic001/run
246 test/basic001/run
232 test/basic001/*.idr
247 test/basic001/*.idr
@@ -256,6 +271,9 @@ Extra-source-files:
256 test/basic009/*.idr
271 test/basic009/*.idr
257 test/basic009/expected
272 test/basic009/expected
258 test/basic009/B/*.idr
273 test/basic009/B/*.idr
274+ test/basic010/run
275+ test/basic010/*.idr
276+ test/basic010/expected
259
277
260 test/buffer001-disabled/*.idr
278 test/buffer001-disabled/*.idr
261 test/buffer001-disabled/run
279 test/buffer001-disabled/run
@@ -309,6 +327,40 @@ Extra-source-files:
309 test/ffi005/run
327 test/ffi005/run
310 test/ffi005/expected
328 test/ffi005/expected
311
329
330+ test/idrisdoc001/run
331+ test/idrisdoc001/expected
332+ test/idrisdoc001/*.idr
333+ test/idrisdoc001/*.ipkg
334+ test/idrisdoc002/run
335+ test/idrisdoc002/expected
336+ test/idrisdoc002/*.idr
337+ test/idrisdoc002/*.ipkg
338+ test/idrisdoc003/run
339+ test/idrisdoc003/expected
340+ test/idrisdoc003/*.idr
341+ test/idrisdoc003/*.ipkg
342+ test/idrisdoc004/run
343+ test/idrisdoc004/expected
344+ test/idrisdoc004/*.idr
345+ test/idrisdoc004/*.ipkg
346+ test/idrisdoc005/run
347+ test/idrisdoc005/expected
348+ test/idrisdoc005/*.idr
349+ test/idrisdoc005/*.ipkg
350+ test/idrisdoc006/run
351+ test/idrisdoc006/expected
352+ test/idrisdoc006/A/fully/Qualified/NAME.idr
353+ test/idrisdoc006/*.idr
354+ test/idrisdoc006/*.ipkg
355+ test/idrisdoc007/run
356+ test/idrisdoc007/expected
357+ test/idrisdoc007/*.idr
358+ test/idrisdoc007/*.ipkg
359+ test/idrisdoc008/run
360+ test/idrisdoc008/expected
361+ test/idrisdoc008/*.idr
362+ test/idrisdoc008/*.ipkg
363+
312 test/interactive001/run
364 test/interactive001/run
313 test/interactive001/input
365 test/interactive001/input
314 test/interactive001/*.idr
366 test/interactive001/*.idr
@@ -321,6 +373,10 @@ Extra-source-files:
321 test/interactive003/input
373 test/interactive003/input
322 test/interactive003/*.idr
374 test/interactive003/*.idr
323 test/interactive003/expected
375 test/interactive003/expected
376+ test/interactive004/run
377+ test/interactive004/input
378+ test/interactive004/*.idr
379+ test/interactive004/expected
324
380
325 test/io001/run
381 test/io001/run
326 test/io001/*.idr
382 test/io001/*.idr
@@ -361,6 +417,12 @@ Extra-source-files:
361 test/records001/run
417 test/records001/run
362 test/records001/*.idr
418 test/records001/*.idr
363 test/records001/expected
419 test/records001/expected
420+ test/records002/run
421+ test/records002/*.idr
422+ test/records002/expected
423+ test/records003/run
424+ test/records003/*.idr
425+ test/records003/expected
364
426
365 test/sugar001/run
427 test/sugar001/run
366 test/sugar001/*.idr
428 test/sugar001/*.idr
@@ -387,6 +449,16 @@ Extra-source-files:
387 test/totality005/run
449 test/totality005/run
388 test/totality005/*.idr
450 test/totality005/*.idr
389 test/totality005/expected
451 test/totality005/expected
452+ test/totality006/run
453+ test/totality006/*.idr
454+ test/totality006/expected
455+ test/totality007/run
456+ test/totality007/*.ipkg
457+ test/totality007/src/*.idr
458+ test/totality007/expected
459+ test/totality008/run
460+ test/totality008/*.idr
461+ test/totality008/expected
390
462
391 test/tutorial001/run
463 test/tutorial001/run
392 test/tutorial001/*.idr
464 test/tutorial001/*.idr
@@ -456,6 +528,7 @@ Library
456 , Idris.AbsSyntax
528 , Idris.AbsSyntax
457 , Idris.AbsSyntaxTree
529 , Idris.AbsSyntaxTree
458 , Idris.Apropos
530 , Idris.Apropos
531+ , Idris.ASTUtils
459 , Idris.CaseSplit
532 , Idris.CaseSplit
460 , Idris.Chaser
533 , Idris.Chaser
461 , Idris.Colours
534 , Idris.Colours
@@ -475,8 +548,10 @@ Library
475 , Idris.Help
548 , Idris.Help
476 , Idris.IBC
549 , Idris.IBC
477 , Idris.IdeSlave
550 , Idris.IdeSlave
551+ , Idris.IdrisDoc
478 , Idris.Imports
552 , Idris.Imports
479 , Idris.Inliner
553 , Idris.Inliner
554+ , Idris.Interactive
480 , Idris.Output
555 , Idris.Output
481 , Idris.Parser
556 , Idris.Parser
482 , Idris.ParseHelpers
557 , Idris.ParseHelpers
@@ -491,7 +566,10 @@ Library
491 , Idris.REPL
566 , Idris.REPL
492 , Idris.REPLParser
567 , Idris.REPLParser
493 , Idris.Transforms
568 , Idris.Transforms
569+ , Idris.TypeSearch
494 , Idris.Unlit
570 , Idris.Unlit
571+ , Idris.WhoCalls
572+ , Idris.CmdOptions
495
573
496 , IRTS.BCImp
574 , IRTS.BCImp
497 , IRTS.Bytecode
575 , IRTS.Bytecode
@@ -533,6 +611,8 @@ Library
533 , ansi-terminal
611 , ansi-terminal
534 , ansi-wl-pprint
612 , ansi-wl-pprint
535 , binary
613 , binary
614+ , blaze-html >= 0.6.1.3
615+ , blaze-markup >= 0.5.2.1 && < 0.7.0.0
536 , bytestring
616 , bytestring
537 , cheapskate
617 , cheapskate
538 , containers >= 0.5
618 , containers >= 0.5
@@ -543,7 +623,7 @@ Library
543 , language-java >= 0.2.6
623 , language-java >= 0.2.6
544 , lens >= 4.1.1
624 , lens >= 4.1.1
545 , mtl
625 , mtl
546− , parsers >= 0.9
626+ , parsers >= 0.9 && < 0.11.0.2
547 , pretty
627 , pretty
548 , process
628 , process
549 , split
629 , split
@@ -559,6 +639,7 @@ Library
559 , xml
639 , xml
560 , deepseq
640 , deepseq
561 , zlib
641 , zlib
642+ , optparse-applicative
562 Extensions: MultiParamTypeClasses
643 Extensions: MultiParamTypeClasses
563 , FunctionalDependencies
644 , FunctionalDependencies
564 , FlexibleContexts
645 , FlexibleContexts
idrisdoc/styles.cssnew file+320
@@ -0,0 +1,320 @@
1+html, body {
2+
3+ margin: 0;
4+ padding: 0;
5+ border: 0;
6+
7+ height: 100%;
8+
9+ font-family: "Trebuchet MS", Helvetica, sans-serif;
10+ font-size: 11pt;
11+
12+ background-color: #FFF;
13+}
14+
15+a, a:active, a:visited {
16+
17+ text-decoration: none;
18+ color: inherit;
19+}
20+
21+a:hover {
22+
23+ text-decoration: underline;
24+}
25+
26+header {
27+
28+ padding: 5px 11px;
29+
30+ border-bottom: 3px solid #659FDB;
31+ box-shadow: 0 -8px 22px 0px;
32+
33+ background-color: #252525;
34+ color: white;
35+
36+ font-size: 9pt;
37+}
38+
39+.wrapper {
40+
41+ min-height: 100%;
42+}
43+
44+header nav, header strong {
45+
46+ font-size: 11pt;
47+}
48+
49+header nav {
50+
51+ float: right;
52+}
53+
54+footer {
55+
56+ height: 30px;
57+ width: 100%;
58+ border-top: 1px solid #AAAAAA;
59+
60+ margin-top: -31px;
61+
62+ text-align: center;
63+ color: #666;
64+ line-height: 30px;
65+ font-size: 9pt;
66+
67+ background: none repeat scroll 0 0 #DDDDDD;
68+}
69+
70+.container {
71+
72+ padding: 10px 10px 41px 20px;
73+}
74+
75+body.index .container a:visited {
76+
77+ color: #666;
78+}
79+
80+body.index .container a:hover {
81+
82+ color: #04819E;
83+}
84+
85+h1 {
86+
87+ margin: 0;
88+ margin-bottom: 5px;
89+ font-size: 14pt;
90+
91+ font-family: "Trebuchet MS", Helvetica, sans-serif;
92+}
93+
94+body.namespace h1 {
95+
96+ border-bottom: 1px solid #BBB;
97+ padding-bottom: 2px;
98+}
99+
100+ul {
101+
102+ list-style-type: none;
103+
104+ margin: 0;
105+ padding: 0;
106+}
107+
108+hr {
109+
110+ margin: 0;
111+ padding: 0;
112+ border: 0;
113+
114+ border-bottom: 1px solid #BBB;
115+}
116+
117+p {
118+
119+ margin: 0;
120+ padding: 0;
121+}
122+
123+.code {
124+
125+ font-family: "Lucida Console", Monaco, monospace;
126+ font-size: 10pt;
127+}
128+
129+.decls {
130+
131+ margin-top: 15px;
132+}
133+
134+.decls > dt {
135+
136+ font-family: "Lucida Console", Monaco, monospace;
137+ font-size: 10pt;
138+ line-height: 20px;
139+
140+ padding: 2px 0;
141+
142+ border: 1px solid #CCC;
143+ background-color: #F0F0F0;
144+
145+ display: table;
146+ width: 100%;
147+}
148+
149+.decls > dt > :first-child {
150+
151+ padding-left: 6px;
152+}
153+
154+.decls > dt > :last-child {
155+
156+ padding-right: 6px;
157+}
158+
159+.decls > dd {
160+
161+ margin: 10px 0 10px 20px;
162+
163+ font-family: Arial, sans-serif;
164+ font-size: 10pt;
165+}
166+
167+.decls > dd > p {
168+
169+ margin-bottom: 8px;
170+}
171+
172+.decls > dd > dl:not(.decls):not(:first-child) {
173+
174+ padding-top: 5px;
175+ border-top: 1px solid #EEE;
176+}
177+
178+.decls > dd > dl:not(.decls) > dt {
179+
180+ display: block;
181+ min-width: 70px;
182+
183+ float: left;
184+
185+ font-weight: bold;
186+}
187+
188+.decls > dd > dl:not(.decls) > dd {
189+
190+ margin-bottom: 2px;
191+}
192+
193+.fixity {
194+
195+ font-style: italic;
196+ font-weight: normal !important;
197+}
198+
199+dd.fixity {
200+
201+ cursor: default;
202+}
203+
204+.word {
205+
206+ display: table-cell;
207+ white-space: nowrap;
208+ width: 0;
209+}
210+
211+.signature {
212+
213+ display: table-cell;
214+ width: 100%;
215+}
216+
217+.name {
218+
219+ display: table-cell;
220+ white-space: nowrap;
221+ width: 0;
222+}
223+
224+.documented, .name {
225+
226+ cursor: default;
227+}
228+
229+.documented {
230+
231+ font-weight: bold;
232+}
233+
234+a.function {
235+
236+ color: #00BA00;
237+}
238+
239+.function {
240+
241+ color: #007C21;
242+}
243+
244+a.constructor {
245+
246+ color: #FF0000;
247+}
248+
249+.constructor {
250+
251+ color: #BF3030;
252+}
253+
254+a.type {
255+
256+ color: #0000FF;
257+}
258+
259+.type {
260+
261+ color: #050599;
262+}
263+
264+.keyword {
265+
266+ color: inherit;
267+}
268+
269+.boundvar {
270+
271+ color: #BF30BF; /* Too much colour makes it hard to differ the rest of the colours */
272+ color: inherit;
273+}
274+
275+.boundvar.implicit {
276+
277+ text-decoration: underline;
278+}
279+
280+/******************* Old colours
281+
282+a {
283+
284+ color: #04819E;
285+}
286+
287+a:visited {
288+
289+ color: #26A3BF;
290+}
291+
292+********************/
293+
294+ul.names {
295+
296+ border: 1px solid #666;
297+}
298+
299+ul.names li:nth-child(odd) {
300+
301+ background-color: #EEEEEF;
302+}
303+
304+ul.names li:nth-child(even) {
305+
306+ background-color: white;
307+}
308+
309+ul.names li {
310+
311+ padding-left: 5px;
312+}
313+
314+ul.names li a {
315+
316+ display: inline-block;
317+ width: 100%;
318+
319+ padding: 2px 0;
320+}
jsrts/Runtime-browser.js+11
@@ -1,3 +1,14 @@
1var __IDRRT__print = function(s) {
1var __IDRRT__print = function(s) {
2 console.log(s);
2 console.log(s);
3};
3};
4+
5+
6+var __IDRRT__systemInfo = function(index) {
7+ switch(index) {
8+ case 0:
9+ return "javascript";
10+ case 1:
11+ return navigator.platform;
12+ }
13+ return "";
14+}
jsrts/Runtime-common.js+16
@@ -34,3 +34,19 @@ var __IDRRT__tailcall = function(k) {
34
34
35 return ret;
35 return ret;
36};
36};
37+
38+var __IDRRT__charCode = function(str) {
39+ var type = typeof str;
40+ if (type == "string")
41+ return str.charCodeAt(0);
42+ else
43+ return str;
44+}
45+
46+var __IDRRT__fromCharCode = function(chr) {
47+ var type = typeof chr;
48+ if (type == "string")
49+ return chr;
50+ else
51+ return String.fromCharCode(chr);
52+}
jsrts/Runtime-node.js+11
@@ -4,3 +4,14 @@ var __IDRRT__print = (function() {
4 util.print(s);
4 util.print(s);
5 };
5 };
6})();
6})();
7+
8+var __IDRRT__systemInfo = function(index) {
9+ var os = require('os')
10+ switch(index) {
11+ case 0:
12+ return "node";
13+ case 1:
14+ return os.platform();
15+ }
16+ return "";
17+}
libs/Makefile−3
@@ -2,19 +2,16 @@ build:
2 $(MAKE) -C prelude build
2 $(MAKE) -C prelude build
3 $(MAKE) -C base build
3 $(MAKE) -C base build
4 $(MAKE) -C effects build
4 $(MAKE) -C effects build
5− $(MAKE) -C javascript build
6
5
7
6
8install:
7install:
9 $(MAKE) -C prelude install
8 $(MAKE) -C prelude install
10 $(MAKE) -C base install
9 $(MAKE) -C base install
11 $(MAKE) -C effects install
10 $(MAKE) -C effects install
12− $(MAKE) -C javascript install
13
11
14clean:
12clean:
15 $(MAKE) -C prelude clean
13 $(MAKE) -C prelude clean
16 $(MAKE) -C base clean
14 $(MAKE) -C base clean
17 $(MAKE) -C effects clean
15 $(MAKE) -C effects clean
18− $(MAKE) -C javascript clean
19
16
20.PHONY: build install clean
17.PHONY: build install clean
libs/base/Data/Bits.idr+7−7
@@ -356,8 +356,8 @@ bitsToInt : Bits n -> Integer
356bitsToInt (MkBits x) = bitsToInt' x
356bitsToInt (MkBits x) = bitsToInt' x
357
357
358-- Zero out the high bits of a truncated bitstring
358-- Zero out the high bits of a truncated bitstring
359−--zeroUnused : machineTy (nextBytes n) -> machineTy (nextBytes n)
359+zeroUnused : machineTy (nextBytes n) -> machineTy (nextBytes n)
360−--zeroUnused {n} x = x `and'` complement' (intToBits' {n=n} 0)
360+zeroUnused {n} x = x `and'` complement' (intToBits' {n=n} 0)
361
361
362--instance Cast Nat (Bits n) where
362--instance Cast Nat (Bits n) where
363-- cast x = MkBits (zeroUnused (natToBits n))
363-- cast x = MkBits (zeroUnused (natToBits n))
@@ -399,8 +399,8 @@ sext' {n=n} {m=m} x with (nextBytes n, nextBytes (n+m))
399
399
400-- TODO: Prove
400-- TODO: Prove
401%assert_total -- can't verify coverage of with block
401%assert_total -- can't verify coverage of with block
402−trunc' : machineTy (nextBytes (n+m)) -> machineTy (nextBytes n)
402+trunc' : machineTy (nextBytes (m+n)) -> machineTy (nextBytes n)
403−trunc' {n=n} {m=m} x with (nextBytes n, nextBytes (n+m))
403+trunc' {m=m} {n=n} x with (nextBytes n, nextBytes (m+n))
404 | (Z, Z) = believe_me x
404 | (Z, Z) = believe_me x
405 | (Z, S Z) = believe_me (prim__truncB16_B8 (believe_me x))
405 | (Z, S Z) = believe_me (prim__truncB16_B8 (believe_me x))
406 | (Z, S (S Z)) = believe_me (prim__truncB32_B8 (believe_me x))
406 | (Z, S (S Z)) = believe_me (prim__truncB32_B8 (believe_me x))
@@ -412,9 +412,9 @@ trunc' {n=n} {m=m} x with (nextBytes n, nextBytes (n+m))
412 | (S (S Z), S (S (S _))) = believe_me (prim__truncB64_B32 (believe_me x))
412 | (S (S Z), S (S (S _))) = believe_me (prim__truncB64_B32 (believe_me x))
413 | (S (S (S _)), S (S (S _))) = believe_me x
413 | (S (S (S _)), S (S (S _))) = believe_me x
414
414
415−--public
415+public
416−--truncate : Bits (n+m) -> Bits n
416+truncate : Bits (m+n) -> Bits n
417−--truncate (MkBits x) = MkBits (zeroUnused (trunc' x))
417+truncate (MkBits x) = MkBits (zeroUnused (trunc' x))
418
418
419public
419public
420bitAt : Fin n -> Bits n
420bitAt : Fin n -> Bits n
libs/base/Data/BoundedList.idr+25−23
@@ -3,11 +3,13 @@ module Data.BoundedList
3%access public
3%access public
4%default total
4%default total
5
5
6+||| A list with an upper bound on its length.
6−data BoundedList : Type -> Nat -> Type where
7+data BoundedList : Nat -> Type -> Type where
7− Nil : BoundedList a n
8+ Nil : BoundedList n a
8− (::) : a -> BoundedList a n -> BoundedList a (S n)
9+ (::) : a -> BoundedList n a -> BoundedList (S n) a
9
10
11+||| Compute the length of a list.
10−length : BoundedList a n -> Fin (S n)
12+length : BoundedList n a -> Fin (S n)
11length [] = fZ
13length [] = fZ
12length (x :: xs) = fS (length xs)
14length (x :: xs) = fS (length xs)
13
15
@@ -15,7 +17,7 @@ length (x :: xs) = fS (length xs)
15-- Indexing into bounded lists
17-- Indexing into bounded lists
16--------------------------------------------------------------------------------
18--------------------------------------------------------------------------------
17
19
18−index : Fin (S n) -> BoundedList a n -> Maybe a
20+index : Fin (S n) -> BoundedList n a -> Maybe a
19index _ [] = Nothing
21index _ [] = Nothing
20index fZ (x :: _) = Just x
22index fZ (x :: _) = Just x
21index (fS f) (_ :: xs) = index f xs
23index (fS f) (_ :: xs) = index f xs
@@ -24,7 +26,8 @@ index (fS f) (_ :: xs) = index f xs
24-- Adjusting bounds
26-- Adjusting bounds
25--------------------------------------------------------------------------------
27--------------------------------------------------------------------------------
26
28
29+||| Loosen the bounds on a list's length.
27−weaken : BoundedList a n -> BoundedList a (n + m)
30+weaken : BoundedList n a -> BoundedList (n + m) a
28weaken [] = []
31weaken [] = []
29weaken (x :: xs) = x :: weaken xs
32weaken (x :: xs) = x :: weaken xs
30
33
@@ -32,16 +35,16 @@ weaken (x :: xs) = x :: weaken xs
32-- Conversions to and from list
35-- Conversions to and from list
33--------------------------------------------------------------------------------
36--------------------------------------------------------------------------------
34
37
35−take : (n : Nat) -> List a -> BoundedList a n
38+take : (n : Nat) -> List a -> BoundedList n a
36take _ [] = []
39take _ [] = []
37take Z _ = []
40take Z _ = []
38take (S n') (x :: xs) = x :: take n' xs
41take (S n') (x :: xs) = x :: take n' xs
39
42
40−toList : BoundedList a n -> List a
43+toList : BoundedList n a -> List a
41toList [] = []
44toList [] = []
42−toList (x :: xs) = x :: toList xs
45+toList (x :: xs) = x :: Data.BoundedList.toList xs
43
46
44−fromList : (xs : List a) -> BoundedList a (length xs)
47+fromList : (xs : List a) -> BoundedList (length xs) a
45fromList [] = []
48fromList [] = []
46fromList (x :: xs) = x :: fromList xs
49fromList (x :: xs) = x :: fromList xs
47
50
@@ -49,7 +52,7 @@ fromList (x :: xs) = x :: fromList xs
49-- Building (bigger) bounded lists
52-- Building (bigger) bounded lists
50--------------------------------------------------------------------------------
53--------------------------------------------------------------------------------
51
54
52−replicate : (n : Nat) -> a -> BoundedList a n
55+replicate : (n : Nat) -> a -> BoundedList n a
53replicate Z _ = []
56replicate Z _ = []
54replicate (S n) x = x :: replicate n x
57replicate (S n) x = x :: replicate n x
55
58
@@ -57,27 +60,26 @@ replicate (S n) x = x :: replicate n x
57-- Folds
60-- Folds
58--------------------------------------------------------------------------------
61--------------------------------------------------------------------------------
59
62
60−foldl : (a -> b -> a) -> a -> BoundedList b n -> a
63+instance Foldable (BoundedList n) where
61−foldl f e [] = e
64+ foldr f e [] = e
62−foldl f e (x::xs) = foldl f (f e x) xs
65+ foldr f e (x::xs) = f x (foldr f e xs)
63−
66+ foldl f e [] = e
64−foldr : (a -> b -> b) -> b -> BoundedList a n -> b
67+ foldl f e (x::xs) = foldl f (f e x) xs
65−foldr f e [] = e
66−foldr f e (x::xs) = f x (foldr f e xs)
67
68
68--------------------------------------------------------------------------------
69--------------------------------------------------------------------------------
69-- Maps
70-- Maps
70--------------------------------------------------------------------------------
71--------------------------------------------------------------------------------
71
72
72−map : (a -> b) -> BoundedList a n -> BoundedList b n
73+instance Functor (BoundedList n) where
73−map f [] = []
74+ map f [] = []
74−map f (x :: xs) = f x :: map f xs
75+ map f (x :: xs) = f x :: map f xs
75
76
76--------------------------------------------------------------------------------
77--------------------------------------------------------------------------------
77-- Misc
78-- Misc
78--------------------------------------------------------------------------------
79--------------------------------------------------------------------------------
79
80
81+||| Extend a bounded list to the maximum size by padding on the left.
80−pad : (xs : BoundedList a n) -> (padding : a) -> BoundedList a n
82+pad : BoundedList n a -> a -> BoundedList n a
81pad {n=Z} [] _ = []
83pad {n=Z} [] _ = []
82pad {n=S n'} [] padding = padding :: (pad {n=n'} [] padding)
84pad {n=S n'} [] padding = padding :: (pad {n=n'} [] padding)
83pad {n=S n'} (x :: xs) padding = x :: pad {n=n'} xs padding
85pad {n=S n'} (x :: xs) padding = x :: pad {n=n'} xs padding
@@ -87,6 +89,6 @@ pad {n=S n'} (x :: xs) padding = x :: pad {n=n'} xs padding
87-- Simple properties
89-- Simple properties
88--------------------------------------------------------------------------------
90--------------------------------------------------------------------------------
89
91
90−zeroBoundIsEmpty : (xs : BoundedList a 0) -> xs = the (BoundedList a 0) []
92+zeroBoundIsEmpty : (xs : BoundedList 0 a) -> xs = the (BoundedList 0 a) []
91zeroBoundIsEmpty [] = refl
93zeroBoundIsEmpty [] = refl
92zeroBoundIsEmpty (_ :: _) impossible
94zeroBoundIsEmpty (_ :: _) impossible
libs/base/Data/Buffer.idr+28−28
@@ -36,15 +36,15 @@ bitsFromFin : Fin n -> Bits64
36bitsFromFin fZ = 0
36bitsFromFin fZ = 0
37bitsFromFin (fS k) = 1 + bitsFromFin k
37bitsFromFin (fS k) = 1 + bitsFromFin k
38
38
39−-- Allocate an empty Buffer. The size hint can be used to avoid
39+||| Allocate an empty Buffer. The size hint can be used to avoid
40−-- unnecessary reallocations and copies under the hood if the
40+||| unnecessary reallocations and copies under the hood if the
41−-- approximate ultimate size of the Buffer is known. Users can assume
41+||| approximate ultimate size of the Buffer is known. Users can assume
42−-- the new Buffer is word-aligned.
42+||| the new Buffer is word-aligned.
43public
43public
44allocate : ( hint : Nat ) -> Buffer Z
44allocate : ( hint : Nat ) -> Buffer Z
45allocate = MkBuffer Z . prim__allocate . bitsFromNat
45allocate = MkBuffer Z . prim__allocate . bitsFromNat
46
46
47−-- Append count repetitions of a Buffer to another Buffer
47+||| Append count repetitions of a Buffer to another Buffer
48%assert_total
48%assert_total
49public
49public
50appendBuffer : Buffer n ->
50appendBuffer : Buffer n ->
@@ -63,13 +63,13 @@ appendBuffer { n } { m } ( MkBuffer o1 r1 ) c ( MkBuffer o2 r2 ) =
63 off : Bits64
63 off : Bits64
64 off = bitsFromNat o2
64 off = bitsFromNat o2
65
65
66−-- Copy a buffer, potentially allowing the (potentially large) space it
66+||| Copy a buffer, potentially allowing the (potentially large) space it
67−-- pointed to to be freed
67+||| pointed to to be freed
68public
68public
69copy : Buffer n -> Buffer n
69copy : Buffer n -> Buffer n
70copy { n } = replace ( plusZeroRightNeutral n ) . appendBuffer ( allocate n ) 1
70copy { n } = replace ( plusZeroRightNeutral n ) . appendBuffer ( allocate n ) 1
71
71
72−-- Create a view over a buffer
72+||| Create a view over a buffer
73public
73public
74peekBuffer : { n : Nat } -> { offset : Nat } -> Buffer ( n + offset ) -> ( offset : Nat ) -> Buffer n
74peekBuffer : { n : Nat } -> { offset : Nat } -> Buffer ( n + offset ) -> ( offset : Nat ) -> Buffer n
75peekBuffer ( MkBuffer o r ) off = MkBuffer ( o + off ) r
75peekBuffer ( MkBuffer o r ) off = MkBuffer ( o + off ) r
@@ -93,7 +93,7 @@ appendBits { n } prim ( MkBuffer o r ) count =
93 MkBuffer o . prim r ( bitsFromNat $ n + o ) ( bitsFromNat count )
93 MkBuffer o . prim r ( bitsFromNat $ n + o ) ( bitsFromNat count )
94
94
95
95
96−-- Read a Bits8 from a Buffer starting at offset
96+||| Read a Bits8 from a Buffer starting at offset
97%assert_total
97%assert_total
98public
98public
99peekBits8 : Buffer ( 1 + n ) ->
99peekBits8 : Buffer ( 1 + n ) ->
@@ -101,7 +101,7 @@ peekBits8 : Buffer ( 1 + n ) ->
101 Bits8
101 Bits8
102peekBits8 = peekBits { m = 1 } prim__peekB8Native
102peekBits8 = peekBits { m = 1 } prim__peekB8Native
103
103
104−-- Append count repetitions of a Bits8 to a Buffer
104+||| Append count repetitions of a Bits8 to a Buffer
105%assert_total
105%assert_total
106public
106public
107appendBits8 : Buffer n ->
107appendBits8 : Buffer n ->
@@ -110,7 +110,7 @@ appendBits8 : Buffer n ->
110 Buffer ( n + count * 1 )
110 Buffer ( n + count * 1 )
111appendBits8 = appendBits prim__appendB8Native
111appendBits8 = appendBits prim__appendB8Native
112
112
113−-- Read a Bits16 in native byte order from a Buffer starting at offset
113+||| Read a Bits16 in native byte order from a Buffer starting at offset
114%assert_total
114%assert_total
115public
115public
116peekBits16Native : Buffer ( 2 + n ) ->
116peekBits16Native : Buffer ( 2 + n ) ->
@@ -118,19 +118,19 @@ peekBits16Native : Buffer ( 2 + n ) ->
118 Bits16
118 Bits16
119peekBits16Native = peekBits { m = 2 } prim__peekB16Native
119peekBits16Native = peekBits { m = 2 } prim__peekB16Native
120
120
121−-- Read a little-endian Bits16 from a Buffer starting at offset
121+||| Read a little-endian Bits16 from a Buffer starting at offset
122%assert_total
122%assert_total
123public
123public
124peekBits16LE : Buffer ( 2 + n ) -> ( offset : Fin ( S n ) ) -> Bits16
124peekBits16LE : Buffer ( 2 + n ) -> ( offset : Fin ( S n ) ) -> Bits16
125peekBits16LE = peekBits { m = 2 } prim__peekB16LE
125peekBits16LE = peekBits { m = 2 } prim__peekB16LE
126
126
127−-- Read a big-endian Bits16 from a Buffer starting at offset
127+||| Read a big-endian Bits16 from a Buffer starting at offset
128%assert_total
128%assert_total
129public
129public
130peekBits16BE : Buffer ( 2 + n ) -> ( offset : Fin ( S n ) ) -> Bits16
130peekBits16BE : Buffer ( 2 + n ) -> ( offset : Fin ( S n ) ) -> Bits16
131peekBits16BE = peekBits { m = 2 } prim__peekB16BE
131peekBits16BE = peekBits { m = 2 } prim__peekB16BE
132
132
133−-- Append count repetitions of a Bits16 in native byte order to a Buffer
133+||| Append count repetitions of a Bits16 in native byte order to a Buffer
134%assert_total
134%assert_total
135public
135public
136appendBits16Native : Buffer n ->
136appendBits16Native : Buffer n ->
@@ -139,7 +139,7 @@ appendBits16Native : Buffer n ->
139 Buffer ( n + count * 2 )
139 Buffer ( n + count * 2 )
140appendBits16Native = appendBits prim__appendB16Native
140appendBits16Native = appendBits prim__appendB16Native
141
141
142−-- Append count repetitions of a little-endian Bits16 to a Buffer
142+||| Append count repetitions of a little-endian Bits16 to a Buffer
143%assert_total
143%assert_total
144public
144public
145appendBits16LE : Buffer n ->
145appendBits16LE : Buffer n ->
@@ -148,7 +148,7 @@ appendBits16LE : Buffer n ->
148 Buffer ( n + count * 2 )
148 Buffer ( n + count * 2 )
149appendBits16LE = appendBits prim__appendB16LE
149appendBits16LE = appendBits prim__appendB16LE
150
150
151−-- Append count repetitions of a big-endian Bits16 to a Buffer
151+||| Append count repetitions of a big-endian Bits16 to a Buffer
152%assert_total
152%assert_total
153public
153public
154appendBits16BE : Buffer n ->
154appendBits16BE : Buffer n ->
@@ -157,7 +157,7 @@ appendBits16BE : Buffer n ->
157 Buffer ( n + count * 2 )
157 Buffer ( n + count * 2 )
158appendBits16BE = appendBits prim__appendB16BE
158appendBits16BE = appendBits prim__appendB16BE
159
159
160−-- Read a Bits32 in native byte order from a Buffer starting at offset
160+||| Read a Bits32 in native byte order from a Buffer starting at offset
161%assert_total
161%assert_total
162public
162public
163peekBits32Native : Buffer ( 4 + n ) ->
163peekBits32Native : Buffer ( 4 + n ) ->
@@ -165,19 +165,19 @@ peekBits32Native : Buffer ( 4 + n ) ->
165 Bits32
165 Bits32
166peekBits32Native = peekBits { m = 4 } prim__peekB32Native
166peekBits32Native = peekBits { m = 4 } prim__peekB32Native
167
167
168−-- Read a little-endian Bits32 from a Buffer starting at offset
168+||| Read a little-endian Bits32 from a Buffer starting at offset
169%assert_total
169%assert_total
170public
170public
171peekBits32LE : Buffer ( 4 + n ) -> ( offset : Fin ( S n ) ) -> Bits32
171peekBits32LE : Buffer ( 4 + n ) -> ( offset : Fin ( S n ) ) -> Bits32
172peekBits32LE = peekBits { m = 4 } prim__peekB32LE
172peekBits32LE = peekBits { m = 4 } prim__peekB32LE
173
173
174−-- Read a big-endian Bits32 from a Buffer starting at offset
174+||| Read a big-endian Bits32 from a Buffer starting at offset
175%assert_total
175%assert_total
176public
176public
177peekBits32BE : Buffer ( 4 + n ) -> ( offset : Fin ( S n ) ) -> Bits32
177peekBits32BE : Buffer ( 4 + n ) -> ( offset : Fin ( S n ) ) -> Bits32
178peekBits32BE = peekBits { m = 4 } prim__peekB32BE
178peekBits32BE = peekBits { m = 4 } prim__peekB32BE
179
179
180−-- Append count repetitions of a Bits32 in native byte order to a Buffer
180+||| Append count repetitions of a Bits32 in native byte order to a Buffer
181%assert_total
181%assert_total
182public
182public
183appendBits32Native : Buffer n ->
183appendBits32Native : Buffer n ->
@@ -186,7 +186,7 @@ appendBits32Native : Buffer n ->
186 Buffer ( n + count * 4 )
186 Buffer ( n + count * 4 )
187appendBits32Native = appendBits prim__appendB32Native
187appendBits32Native = appendBits prim__appendB32Native
188
188
189−-- Append count repetitions of a little-endian Bits32 to a Buffer
189+||| Append count repetitions of a little-endian Bits32 to a Buffer
190%assert_total
190%assert_total
191public
191public
192appendBits32LE : Buffer n ->
192appendBits32LE : Buffer n ->
@@ -195,7 +195,7 @@ appendBits32LE : Buffer n ->
195 Buffer ( n + count * 4 )
195 Buffer ( n + count * 4 )
196appendBits32LE = appendBits prim__appendB32LE
196appendBits32LE = appendBits prim__appendB32LE
197
197
198−-- Append count repetitions of a big-endian Bits32 to a Buffer
198+||| Append count repetitions of a big-endian Bits32 to a Buffer
199%assert_total
199%assert_total
200public
200public
201appendBits32BE : Buffer n ->
201appendBits32BE : Buffer n ->
@@ -204,7 +204,7 @@ appendBits32BE : Buffer n ->
204 Buffer ( n + count * 4 )
204 Buffer ( n + count * 4 )
205appendBits32BE = appendBits prim__appendB32BE
205appendBits32BE = appendBits prim__appendB32BE
206
206
207−-- Read a Bits64 in native byte order from a Buffer starting at offset
207+||| Read a Bits64 in native byte order from a Buffer starting at offset
208%assert_total
208%assert_total
209public
209public
210peekBits64Native : Buffer ( 8 + n ) ->
210peekBits64Native : Buffer ( 8 + n ) ->
@@ -212,19 +212,19 @@ peekBits64Native : Buffer ( 8 + n ) ->
212 Bits64
212 Bits64
213peekBits64Native = peekBits { m = 8 } prim__peekB64Native
213peekBits64Native = peekBits { m = 8 } prim__peekB64Native
214
214
215−-- Read a little-endian Bits64 from a Buffer starting at offset
215+||| Read a little-endian Bits64 from a Buffer starting at offset
216%assert_total
216%assert_total
217public
217public
218peekBits64LE : Buffer ( 8 + n ) -> ( offset : Fin ( S n ) ) -> Bits64
218peekBits64LE : Buffer ( 8 + n ) -> ( offset : Fin ( S n ) ) -> Bits64
219peekBits64LE = peekBits { m = 8 } prim__peekB64LE
219peekBits64LE = peekBits { m = 8 } prim__peekB64LE
220
220
221−-- Read a big-endian Bits64 from a Buffer starting at offset
221+||| Read a big-endian Bits64 from a Buffer starting at offset
222%assert_total
222%assert_total
223public
223public
224peekBits64BE : Buffer ( 8 + n ) -> ( offset : Fin ( S n ) ) -> Bits64
224peekBits64BE : Buffer ( 8 + n ) -> ( offset : Fin ( S n ) ) -> Bits64
225peekBits64BE = peekBits { m = 8 } prim__peekB64BE
225peekBits64BE = peekBits { m = 8 } prim__peekB64BE
226
226
227−-- Append count repetitions of a Bits64 in native byte order to a Buffer
227+||| Append count repetitions of a Bits64 in native byte order to a Buffer
228%assert_total
228%assert_total
229public
229public
230appendBits64Native : Buffer n ->
230appendBits64Native : Buffer n ->
@@ -233,7 +233,7 @@ appendBits64Native : Buffer n ->
233 Buffer ( n + count * 8 )
233 Buffer ( n + count * 8 )
234appendBits64Native = appendBits prim__appendB64Native
234appendBits64Native = appendBits prim__appendB64Native
235
235
236−-- Append count repetitions of a little-endian Bits64 to a Buffer
236+||| Append count repetitions of a little-endian Bits64 to a Buffer
237%assert_total
237%assert_total
238public
238public
239appendBits64LE : Buffer n ->
239appendBits64LE : Buffer n ->
@@ -242,7 +242,7 @@ appendBits64LE : Buffer n ->
242 Buffer ( n + count * 8 )
242 Buffer ( n + count * 8 )
243appendBits64LE = appendBits prim__appendB64LE
243appendBits64LE = appendBits prim__appendB64LE
244
244
245−-- Append count repetitions of a big-endian Bits64 to a Buffer
245+||| Append count repetitions of a big-endian Bits64 to a Buffer
246%assert_total
246%assert_total
247public
247public
248appendBits64BE : Buffer n ->
248appendBits64BE : Buffer n ->
libs/base/Data/Complex.idr+2−2
@@ -62,8 +62,8 @@ conjugate (r:+i) = (r :+ (0-i))
62-- We can't do "instance Num a => Num (Complex a)" because
62-- We can't do "instance Num a => Num (Complex a)" because
63-- we need "abs" which needs "magnitude" which needs "sqrt" which needs Float
63-- we need "abs" which needs "magnitude" which needs "sqrt" which needs Float
64instance Num (Complex Float) where
64instance Num (Complex Float) where
65− (+) (a:+b) (c:+d) = ((a+b):+(c+d))
65+ (+) (a:+b) (c:+d) = ((a+c):+(b+d))
66− (-) (a:+b) (c:+d) = ((a-b):+(c-d))
66+ (-) (a:+b) (c:+d) = ((a-c):+(b-d))
67 (*) (a:+b) (c:+d) = ((a*c-b*d):+(b*c+a*d))
67 (*) (a:+b) (c:+d) = ((a*c-b*d):+(b*c+a*d))
68 fromInteger x = (fromInteger x:+0)
68 fromInteger x = (fromInteger x:+0)
69 abs (a:+b) = (magnitude (a:+b):+0)
69 abs (a:+b) = (magnitude (a:+b):+0)
libs/base/Data/Erased.idrnew file+29
@@ -0,0 +1,29 @@
1+module Data.Erased
2+
3+%access public
4+%default total
5+
6+||| The erasure monad.
7+|||
8+||| Used when explicit modelling of erasure in the type system is needed.
9+data Erased : Type -> Type where
10+
11+ ||| Construct an erased value from any value.
12+ Erase : .(x : a) -> Erased a
13+
14+instance Functor Erased where
15+ map f (Erase x) = Erase (f x)
16+
17+instance Applicative Erased where
18+ pure = Erase
19+ (<$>) (Erase f) (Erase x) = Erase (f x)
20+
21+instance Monad Erased where
22+ (>>=) (Erase x) f = f x
23+
24+||| Project the erased value out of the monad.
25+|||
26+||| This is usable only in types and other erased contexts,
27+||| where it won't cause erasure violations.
28+unerase : Erased a -> a
29+unerase (Erase x) = x
libs/base/Data/Fun.idr+2−5
@@ -2,9 +2,7 @@ module Data.Fun
2
2
3%default total
3%default total
4
4
5−--------------------------------------------------------------------------------
6−-- Build an n-ary function type from a Vect of Types and a result type
5+||| Build an n-ary function type from a Vect of Types and a result type
7−--------------------------------------------------------------------------------
8Fun : Vect n Type -> Type -> Type
6Fun : Vect n Type -> Type -> Type
9Fun [] r = r
7Fun [] r = r
10Fun (t::ts) r = t -> Fun ts r
8Fun (t::ts) r = t -> Fun ts r
@@ -14,5 +12,4 @@ chain {ts = []} g r = g r
14chain {ts = (_::_)} g f = \ x => chain g (f x)
12chain {ts = (_::_)} g f = \ x => chain g (f x)
15
13
16target : {ts : Vect n Type} -> Fun ts r -> Type
14target : {ts : Vect n Type} -> Fun ts r -> Type
17−target {r} _ = r
15+target {r} _ = r
18−
libs/base/Data/HVect.idr+6−2
@@ -6,7 +6,8 @@ import Data.Vect
6%default total
6%default total
7
7
8using (k : Nat, ts : Vect k Type)
8using (k : Nat, ts : Vect k Type)
9− ||| Heterogeneous vectors where the type index gives, element-wise, the types of the contents
9+ ||| Heterogeneous vectors where the type index gives, element-wise,
10+ ||| the types of the contents.
10 data HVect : Vect k Type -> Type where
11 data HVect : Vect k Type -> Type where
11 Nil : HVect []
12 Nil : HVect []
12 (::) : t -> HVect ts -> HVect (t::ts)
13 (::) : t -> HVect ts -> HVect (t::ts)
@@ -30,6 +31,7 @@ using (k : Nat, ts : Vect k Type)
30 updateAt fZ f (x::xs) = f x :: xs
31 updateAt fZ f (x::xs) = f x :: xs
31 updateAt (fS j) f (x::xs) = x :: updateAt j f xs
32 updateAt (fS j) f (x::xs) = x :: updateAt j f xs
32
33
34+ ||| Append two `HVect`s.
33 (++) : {us : Vect l Type} -> HVect ts -> HVect us -> HVect (ts ++ us)
35 (++) : {us : Vect l Type} -> HVect ts -> HVect us -> HVect (ts ++ us)
34 (++) [] ys = ys
36 (++) [] ys = ys
35 (++) (x::xs) ys = x :: (xs ++ ys)
37 (++) (x::xs) ys = x :: (xs ++ ys)
@@ -52,16 +54,18 @@ using (k : Nat, ts : Vect k Type)
52 instance (Shows k ts) => Show (HVect ts) where
54 instance (Shows k ts) => Show (HVect ts) where
53 show xs = show (shows xs)
55 show xs = show (shows xs)
54
56
55− ||| Extract an arbitrary element of the correct type
57+ ||| Extract an arbitrary element of the correct type.
56 ||| @ t the goal type
58 ||| @ t the goal type
57 get : {default tactics { applyTactic findElem 100; solve; } p : Elem t ts} -> HVect ts -> t
59 get : {default tactics { applyTactic findElem 100; solve; } p : Elem t ts} -> HVect ts -> t
58 get {p = Here} (x::xs) = x
60 get {p = Here} (x::xs) = x
59 get {p = There p'} (x::xs) = get {p = p'} xs
61 get {p = There p'} (x::xs) = get {p = p'} xs
60
62
63+ ||| Replace an element with the correct type.
61 put : {default tactics { applyTactic findElem 100; solve; } p : Elem t ts} -> t -> HVect ts -> HVect ts
64 put : {default tactics { applyTactic findElem 100; solve; } p : Elem t ts} -> t -> HVect ts -> HVect ts
62 put {p = Here} y (x::xs) = y :: xs
65 put {p = Here} y (x::xs) = y :: xs
63 put {p = There p'} y (x::xs) = x :: put {p = p'} y xs
66 put {p = There p'} y (x::xs) = x :: put {p = p'} y xs
64
67
68+ ||| Replace an element with the correct type.
65 update : {default tactics { applyTactic findElem 100; solve; } p : Elem t ts} -> (t -> u) -> HVect ts -> HVect (replaceByElem ts p u)
69 update : {default tactics { applyTactic findElem 100; solve; } p : Elem t ts} -> (t -> u) -> HVect ts -> HVect (replaceByElem ts p u)
66 update {p = Here} f (x::xs) = f x :: xs
70 update {p = Here} f (x::xs) = f x :: xs
67 update {p = There p'} f (x::xs) = x :: update {p = p'} f xs
71 update {p = There p'} f (x::xs) = x :: update {p = p'} f xs
libs/base/Data/List.idrnew file+31
@@ -0,0 +1,31 @@
1+module Data.List
2+
3+%access public
4+
5+using (xs : List a)
6+ ||| A proof that some element is found in a list
7+ data Elem : a -> List a -> Type where
8+ Here : Elem x (x :: xs)
9+ There : Elem x xs -> Elem x (y :: xs)
10+
11+ instance Uninhabited (Elem {a} x []) where
12+ uninhabited Here impossible
13+ uninhabited (There p) impossible
14+
15+ ||| Is the given element a member of the given list.
16+ |||
17+ ||| @x The element to be tested.
18+ ||| @xs The list to be checked against
19+ isElem : DecEq a => (x : a) -> (xs : List a) -> Dec (Elem x xs)
20+ isElem x [] = No absurd
21+ isElem x (y :: xs) with (decEq x y)
22+ isElem x (x :: xs) | (Yes refl) = Yes Here
23+ isElem x (y :: xs) | (No contra) with (isElem x xs)
24+ isElem x (y :: xs) | (No contra) | (Yes prf) = Yes (There prf)
25+ isElem x (y :: xs) | (No contra) | (No f) = No (mkNo contra f)
26+ where
27+ mkNo : {xs' : List a} ->
28+ ((x' = y') -> _|_) -> (Elem x' xs' -> _|_) ->
29+ Elem x' (y' :: xs') -> _|_
30+ mkNo f g Here = f refl
31+ mkNo f g (There x) = g x
libs/base/Data/Mod2.idr+1−1
@@ -4,7 +4,7 @@ import Data.Bits
4
4
5%default total
5%default total
6
6
7−-- Integers modulo 2^n
7+||| Integers modulo 2^n
8public
8public
9data Mod2 : Nat -> Type where
9data Mod2 : Nat -> Type where
10 MkMod2 : {n : Nat} -> Bits n -> Mod2 n
10 MkMod2 : {n : Nat} -> Bits n -> Mod2 n
libs/base/Data/Rel.idr+2−3
@@ -2,9 +2,8 @@ module Data.Rel
2
2
3import Data.Fun
3import Data.Fun
4
4
5−--------------------------------------------------------------------------------
5+
6−-- Build an n-ary relation type from a Vect of Types
6+||| Build an n-ary relation type from a Vect of Types
7−--------------------------------------------------------------------------------
8Rel : Vect n Type -> Type
7Rel : Vect n Type -> Type
9Rel ts = Fun ts Type
8Rel ts = Fun ts Type
10
9
libs/base/Data/SortedMap.idr+3−3
@@ -183,10 +183,10 @@ treeDelete {n=(S (S _))} k (Branch3 t1 k1 t2 k2 t3) =
183 Left t3' => Left (Branch3 t1 k1 t2 k2 t3')
183 Left t3' => Left (Branch3 t1 k1 t2 k2 t3')
184 Right t3' => Left (merge3 t1 k1 t2 k2 t3')
184 Right t3' => Left (merge3 t1 k1 t2 k2 t3')
185
185
186−treeToList : Ord k => Tree n k v -> List (k, v)
186+treeToList : Tree n k v -> List (k, v)
187treeToList = treeToList' (:: [])
187treeToList = treeToList' (:: [])
188 where
188 where
189− treeToList' : Ord k => ((k, v) -> List (k, v)) -> Tree n k v -> List (k, v)
189+ treeToList' : ((k, v) -> List (k, v)) -> Tree n k v -> List (k, v)
190 treeToList' cont (Leaf k v) = cont (k, v)
190 treeToList' cont (Leaf k v) = cont (k, v)
191 treeToList' cont (Branch2 t1 _ t2) = treeToList' (:: treeToList' cont t2) t1
191 treeToList' cont (Branch2 t1 _ t2) = treeToList' (:: treeToList' cont t2) t1
192 treeToList' cont (Branch3 t1 _ t2 _ t3) = treeToList' (:: treeToList' (:: treeToList' cont t3) t2) t1
192 treeToList' cont (Branch3 t1 _ t2 _ t3) = treeToList' (:: treeToList' (:: treeToList' cont t3) t2) t1
@@ -223,7 +223,7 @@ delete k (M (S _) t) =
223fromList : Ord k => List (k, v) -> SortedMap k v
223fromList : Ord k => List (k, v) -> SortedMap k v
224fromList l = foldl (flip (uncurry insert)) empty l
224fromList l = foldl (flip (uncurry insert)) empty l
225
225
226−toList : Ord k => SortedMap k v -> List (k, v)
226+toList : SortedMap k v -> List (k, v)
227toList Empty = []
227toList Empty = []
228toList (M _ t) = treeToList t
228toList (M _ t) = treeToList t
229
229
libs/base/Data/SortedSet.idr+4−1
@@ -21,5 +21,8 @@ contains k (SetWrapper m) = isJust (Data.SortedMap.lookup k m)
21fromList : Ord k => List k -> SortedSet k
21fromList : Ord k => List k -> SortedSet k
22fromList l = SetWrapper (Data.SortedMap.fromList (map (\i => (i, ())) l))
22fromList l = SetWrapper (Data.SortedMap.fromList (map (\i => (i, ())) l))
23
23
24−toList : Ord k => SortedSet k -> List k
24+toList : SortedSet k -> List k
25toList (SetWrapper m) = map (\(i, _) => i) (Data.SortedMap.toList m)
25toList (SetWrapper m) = map (\(i, _) => i) (Data.SortedMap.toList m)
26+
27+instance Foldable SortedSet where
28+ foldr f e xs = foldr f e (Data.SortedSet.toList xs)
libs/base/Data/Vect.idr+18
@@ -15,6 +15,24 @@ using (xs : Vect k a)
15 Here : Elem x (x::xs)
15 Here : Elem x (x::xs)
16 There : Elem x xs -> Elem x (y::xs)
16 There : Elem x xs -> Elem x (y::xs)
17
17
18+||| Nothing can be in an empty Vect
19+noEmptyElem : {x : a} -> Elem x [] -> _|_
20+noEmptyElem Here impossible
21+
22+||| An item not in the head and not in the tail is not in the Vect at all
23+neitherHereNorThere : {x, y : a} -> {xs : Vect n a} -> Not (x = y) -> Not (Elem x xs) -> Not (Elem x (y :: xs))
24+neitherHereNorThere xneqy xninxs Here = xneqy refl
25+neitherHereNorThere xneqy xninxs (There xinxs) = xninxs xinxs
26+
27+||| A decision procedure for Elem
28+isElem : DecEq a => (x : a) -> (xs : Vect n a) -> Dec (Elem x xs)
29+isElem x [] = No noEmptyElem
30+isElem x (y :: xs) with (decEq x y)
31+ isElem x (x :: xs) | (Yes refl) = Yes Here
32+ isElem x (y :: xs) | (No xneqy) with (isElem x xs)
33+ isElem x (y :: xs) | (No xneqy) | (Yes xinxs) = Yes (There xinxs)
34+ isElem x (y :: xs) | (No xneqy) | (No xninxs) = No (neitherHereNorThere xneqy xninxs)
35+
18||| A tactic for discovering where, if anywhere, an element is in a vector
36||| A tactic for discovering where, if anywhere, an element is in a vector
19||| @ n how many elements to search before giving up
37||| @ n how many elements to search before giving up
20findElem : (n : Nat) -> List (TTName, Binder TT) -> TT -> Tactic
38findElem : (n : Nat) -> List (TTName, Binder TT) -> TT -> Tactic
libs/base/Language/Reflection.idr+2
@@ -167,6 +167,8 @@ data Tactic = Try Tactic Tactic
167 -- ^ apply both tactics in sequence
167 -- ^ apply both tactics in sequence
168 | Trivial
168 | Trivial
169 -- ^ intelligently construct the proof target from the context
169 -- ^ intelligently construct the proof target from the context
170+ | Search Int
171+ -- ^ build a proof by applying contructors up to a maximum depth
170 | Instance
172 | Instance
171 -- ^ resolve a type class
173 -- ^ resolve a type class
172 | Solve
174 | Solve
libs/base/Providers.idr−9
@@ -11,26 +11,17 @@ data Provider : (a : Type) -> Type where
11 ||| @ msg the error message
11 ||| @ msg the error message
12 Error : (msg : String) -> Provider a
12 Error : (msg : String) -> Provider a
13
13
14− ||| Postulate the goal type
15− Postulate : Provider a
16−
17-- instances
14-- instances
18instance Functor Provider where
15instance Functor Provider where
19 map f (Provide a) = Provide (f a)
16 map f (Provide a) = Provide (f a)
20 map f (Error err) = Error err
17 map f (Error err) = Error err
21− map f Postulate = Postulate
22
18
23instance Applicative Provider where
19instance Applicative Provider where
24 (Provide f) <$> (Provide x) = Provide (f x)
20 (Provide f) <$> (Provide x) = Provide (f x)
25 (Provide f) <$> (Error err) = Error err
21 (Provide f) <$> (Error err) = Error err
26− (Provide f) <$> Postulate = Postulate
27 (Error err) <$> _ = Error err
22 (Error err) <$> _ = Error err
28− Postulate <$> (Error err) = Error err
29− Postulate <$> _ = Postulate
30 pure = Provide
23 pure = Provide
31
24
32−-- is this correct for Postulate?
33instance Monad Provider where
25instance Monad Provider where
34 (Provide x) >>= f = f x
26 (Provide x) >>= f = f x
35 (Error err) >>= _ = Error err
27 (Error err) >>= _ = Error err
36− Postulate >>= f = Postulate
libs/base/System/Concurrency/Process.idr+7−14
@@ -9,9 +9,8 @@ import System.Concurrency.Raw
9abstract
9abstract
10data ProcID msg = MkPID Ptr
10data ProcID msg = MkPID Ptr
11
11
12−-- Type safe message passing programs. Parameterised over the type of
12+||| Type safe message passing programs. Parameterised over the type of
13−-- message which can be send, and the return type.
13+||| message which can be send, and the return type.
14−
15data Process : (msgType : Type) -> Type -> Type where
14data Process : (msgType : Type) -> Type -> Type where
16 lift : IO a -> Process msg a
15 lift : IO a -> Process msg a
17
16
@@ -30,31 +29,26 @@ instance Monad (Process msg) where
30run : Process msg x -> IO x
29run : Process msg x -> IO x
31run (lift prog) = prog
30run (lift prog) = prog
32
31
33−-- Get current process ID
32+||| Get current process ID
34−
35myID : Process msg (ProcID msg)
33myID : Process msg (ProcID msg)
36myID = lift (return (MkPID prim__vm))
34myID = lift (return (MkPID prim__vm))
37
35
38−-- Send a message to another process
36+||| Send a message to another process
39−
40send : ProcID msg -> msg -> Process msg ()
37send : ProcID msg -> msg -> Process msg ()
41send (MkPID p) m = lift (sendToThread p (prim__vm, m))
38send (MkPID p) m = lift (sendToThread p (prim__vm, m))
42
39
43−-- Return whether a message is waiting in the queue
40+||| Return whether a message is waiting in the queue
44−
45msgWaiting : Process msg Bool
41msgWaiting : Process msg Bool
46msgWaiting = lift checkMsgs
42msgWaiting = lift checkMsgs
47
43
48−-- Receive a message - blocks if there is no message waiting
44+||| Receive a message - blocks if there is no message waiting
49−
50recv : Process msg msg
45recv : Process msg msg
51recv {msg} = do (senderid, m) <- lift get
46recv {msg} = do (senderid, m) <- lift get
52 return m
47 return m
53 where get : IO (Ptr, msg)
48 where get : IO (Ptr, msg)
54 get = getMsg
49 get = getMsg
55
50
56−-- receive a message, and return with the sender's process ID.
51+||| receive a message, and return with the sender's process ID.
57−
58recvWithSender : Process msg (ProcID msg, msg)
52recvWithSender : Process msg (ProcID msg, msg)
59recvWithSender {msg}
53recvWithSender {msg}
60 = do (senderid, m) <- lift get
54 = do (senderid, m) <- lift get
@@ -65,4 +59,3 @@ recvWithSender {msg}
65create : Process msg () -> Process msg (ProcID msg)
59create : Process msg () -> Process msg (ProcID msg)
66create (lift p) = do ptr <- lift (fork p)
60create (lift p) = do ptr <- lift (fork p)
67 return (MkPID ptr)
61 return (MkPID ptr)
68−
libs/base/System/Concurrency/Raw.idr+3−6
@@ -6,8 +6,7 @@ module System.Concurrency.Raw
6
6
7import System
7import System
8
8
9−-- Send a message of any type to the thread with the given thread id
9+||| Send a message of any type to the thread with the given thread id
10−
11sendToThread : (thread_id : Ptr) -> a -> IO ()
10sendToThread : (thread_id : Ptr) -> a -> IO ()
12sendToThread {a} dest val
11sendToThread {a} dest val
13 = mkForeign (FFun "idris_sendMessage"
12 = mkForeign (FFun "idris_sendMessage"
@@ -18,10 +17,8 @@ checkMsgs = do msgs <- mkForeign (FFun "idris_checkMessages"
18 [FPtr] FInt) prim__vm
17 [FPtr] FInt) prim__vm
19 return (intToBool msgs)
18 return (intToBool msgs)
20
19
21−-- Check inbox for messages. If there are none, blocks until a message
20+||| Check inbox for messages. If there are none, blocks until a message
22−-- arrives.
21+||| arrives.
23−
24getMsg : IO a
22getMsg : IO a
25getMsg {a} = mkForeign (FFun "idris_recvMessage"
23getMsg {a} = mkForeign (FFun "idris_recvMessage"
26 [FPtr] (FAny a)) prim__vm
24 [FPtr] (FAny a)) prim__vm
27−
libs/base/System/Info.idrnew file+13
@@ -0,0 +1,13 @@
1+module System.Info
2+
3+||| The Idris backend in use
4+backend : String
5+backend = prim__systemInfo 0
6+
7+||| The operating system in use.
8+os : String
9+os = prim__systemInfo 1
10+
11+||| The triple this program was targeted for
12+targetTriple : String
13+targetTriple = prim__systemInfo 2
libs/base/base.ipkg+3−1
@@ -6,6 +6,7 @@ modules = System,
6 Network.Cgi, Network.Socket,
6 Network.Cgi, Network.Socket,
7 Debug.Trace,
7 Debug.Trace,
8
8
9+ System.Info,
9 System.Concurrency.Raw, System.Concurrency.Process,
10 System.Concurrency.Raw, System.Concurrency.Process,
10
11
11 Decidable.Decidable, Decidable.Order,
12 Decidable.Decidable, Decidable.Order,
@@ -22,7 +23,8 @@ modules = System,
22 Data.SortedMap, Data.SortedSet, Data.BoundedList,
23 Data.SortedMap, Data.SortedSet, Data.BoundedList,
23 Data.Vect, Data.HVect, Data.Vect.Quantifiers,
24 Data.Vect, Data.HVect, Data.Vect.Quantifiers,
24 Data.Floats, Data.Complex, Data.Heap, Data.Fun,
25 Data.Floats, Data.Complex, Data.Heap, Data.Fun,
25− Data.Rel, Data.Buffer,
26+ Data.Rel, Data.Buffer, Data.Erased,
27+ Data.List,
26
28
27 Control.Isomorphism, Control.Isomorphism.Primitives,
29 Control.Isomorphism, Control.Isomorphism.Primitives,
28 Control.Monad.Identity,
30 Control.Monad.Identity,
libs/effects/Effect/Exception.idr+1−1
@@ -27,7 +27,7 @@ EXCEPTION : Type -> EFFECT
27EXCEPTION t = MkEff () (Exception t)
27EXCEPTION t = MkEff () (Exception t)
28
28
29raise : a -> { [EXCEPTION a ] } Eff m b
29raise : a -> { [EXCEPTION a ] } Eff m b
30−raise err = Raise err
30+raise err = call $ Raise err
31
31
32
32
33
33
libs/effects/Effect/File.idr+10−15
@@ -101,33 +101,28 @@ FILE_IO t = MkEff t FileIO
101|||
101|||
102||| @ fname The file name to be opened.
102||| @ fname The file name to be opened.
103||| @ m The file mode.
103||| @ m The file mode.
104−open : Handler FileIO e =>
105− (fname : String)
104+open : (fname : String)
106 -> (m : Mode)
105 -> (m : Mode)
107 -> { [FILE_IO ()] ==> [FILE_IO (if result
106 -> { [FILE_IO ()] ==> [FILE_IO (if result
108 then OpenFile m
107 then OpenFile m
109 else ())] } Eff e Bool
108 else ())] } Eff e Bool
110−open f m = Open f m
109+open f m = call $ Open f m
111
110
112
111
113||| Close a file.
112||| Close a file.
114−close : Handler FileIO e =>
115− { [FILE_IO (OpenFile m)] ==> [FILE_IO ()] } Eff e ()
113+close : { [FILE_IO (OpenFile m)] ==> [FILE_IO ()] } Eff e ()
116−close = Close
114+close = call $ Close
117
115
118||| Read a line from the file.
116||| Read a line from the file.
119−readLine : Handler FileIO e =>
120− { [FILE_IO (OpenFile Read)] } Eff e String
117+readLine : { [FILE_IO (OpenFile Read)] } Eff e String
121−readLine = ReadLine
118+readLine = call $ ReadLine
122
119
123||| Write a line to a file.
120||| Write a line to a file.
124−writeLine : Handler FileIO e =>
125− String -> { [FILE_IO (OpenFile Write)] } Eff e ()
121+writeLine : String -> { [FILE_IO (OpenFile Write)] } Eff e ()
126−writeLine str = WriteLine str
122+writeLine str = call $ WriteLine str
127
123
128||| End of file?
124||| End of file?
129−eof : Handler FileIO e =>
130− { [FILE_IO (OpenFile Read)] } Eff e Bool
125+eof : { [FILE_IO (OpenFile Read)] } Eff e Bool
131−eof = EOF
126+eof = call $ EOF
132
127
133-- --------------------------------------------------------------------- [ EOF ]
128-- --------------------------------------------------------------------- [ EOF ]
libs/effects/Effect/Memory.idr+7−7
@@ -102,7 +102,7 @@ RAW_MEMORY t = MkEff t RawMemory
102
102
103allocate : (n : Nat) ->
103allocate : (n : Nat) ->
104 Eff m () [RAW_MEMORY ()] (\v => [RAW_MEMORY (MemoryChunk n 0)])
104 Eff m () [RAW_MEMORY ()] (\v => [RAW_MEMORY (MemoryChunk n 0)])
105−allocate size = Allocate size
105+allocate size = call $ Allocate size
106
106
107initialize : {i : Nat} ->
107initialize : {i : Nat} ->
108 {n : Nat} ->
108 {n : Nat} ->
@@ -111,17 +111,17 @@ initialize : {i : Nat} ->
111 so (i + size <= n) ->
111 so (i + size <= n) ->
112 Eff m () [RAW_MEMORY (MemoryChunk n i)]
112 Eff m () [RAW_MEMORY (MemoryChunk n i)]
113 (\v => [RAW_MEMORY (MemoryChunk n (i + size))])
113 (\v => [RAW_MEMORY (MemoryChunk n (i + size))])
114−initialize c size prf = Initialize c size prf
114+initialize c size prf = call $ Initialize c size prf
115
115
116free : Eff m () [RAW_MEMORY (MemoryChunk n i)] (\v => [RAW_MEMORY ()])
116free : Eff m () [RAW_MEMORY (MemoryChunk n i)] (\v => [RAW_MEMORY ()])
117−free = Free
117+free = call Free
118
118
119peek : {i : Nat} ->
119peek : {i : Nat} ->
120 (offset : Nat) ->
120 (offset : Nat) ->
121 (size : Nat) ->
121 (size : Nat) ->
122 so (offset + size <= i) ->
122 so (offset + size <= i) ->
123 { [RAW_MEMORY (MemoryChunk n i)] } Eff m (Vect size Bits8)
123 { [RAW_MEMORY (MemoryChunk n i)] } Eff m (Vect size Bits8)
124−peek offset size prf = Peek offset size prf
124+peek offset size prf = call $ Peek offset size prf
125
125
126poke : {n : Nat} ->
126poke : {n : Nat} ->
127 {i : Nat} ->
127 {i : Nat} ->
@@ -130,11 +130,11 @@ poke : {n : Nat} ->
130 so (offset <= i && offset + size <= n) ->
130 so (offset <= i && offset + size <= n) ->
131 Eff m () [RAW_MEMORY (MemoryChunk n i)]
131 Eff m () [RAW_MEMORY (MemoryChunk n i)]
132 (\v => [RAW_MEMORY (MemoryChunk n (max i (offset + size)))])
132 (\v => [RAW_MEMORY (MemoryChunk n (max i (offset + size)))])
133−poke offset content prf = Poke offset content prf
133+poke offset content prf = call $ Poke offset content prf
134
134
135private
135private
136getRawPtr : { [RAW_MEMORY (MemoryChunk n i)] } Eff m (MemoryChunk n i)
136getRawPtr : { [RAW_MEMORY (MemoryChunk n i)] } Eff m (MemoryChunk n i)
137−getRawPtr = GetRawPtr
137+getRawPtr = call $ GetRawPtr
138
138
139private
139private
140move' : {dst_size : Nat} ->
140move' : {dst_size : Nat} ->
@@ -149,7 +149,7 @@ move' : {dst_size : Nat} ->
149 Eff m () [RAW_MEMORY (MemoryChunk dst_size dst_init)]
149 Eff m () [RAW_MEMORY (MemoryChunk dst_size dst_init)]
150 (\v => [RAW_MEMORY (MemoryChunk dst_size (max dst_init (dst_offset + size)))])
150 (\v => [RAW_MEMORY (MemoryChunk dst_size (max dst_init (dst_offset + size)))])
151move' src_ptr dst_offset src_offset size dst_bounds src_bounds
151move' src_ptr dst_offset src_offset size dst_bounds src_bounds
152− = Move src_ptr dst_offset src_offset size dst_bounds src_bounds
152+ = call $ Move src_ptr dst_offset src_offset size dst_bounds src_bounds
153
153
154data MoveDescriptor = Dst | Src
154data MoveDescriptor = Dst | Src
155
155
libs/effects/Effect/Random.idr+18−4
@@ -9,25 +9,39 @@ data Random : Effect where
9using (m : Type -> Type)
9using (m : Type -> Type)
10 instance Handler Random m where
10 instance Handler Random m where
11 handle seed getRandom k
11 handle seed getRandom k
12− = let seed' = (1664525 * seed + 1013904223) `prim__sremBigInt` (pow 2 32) in
12+ = let seed' = assert_total ((1664525 * seed + 1013904223) `prim__sremBigInt` (pow 2 32)) in
13 k seed' seed'
13 k seed' seed'
14 handle seed (setSeed n) k = k () n
14 handle seed (setSeed n) k = k () n
15
15
16RND : EFFECT
16RND : EFFECT
17RND = MkEff Integer Random
17RND = MkEff Integer Random
18
18
19+||| Generates a random Integer in a given range
19rndInt : Integer -> Integer -> { [RND] } Eff m Integer
20rndInt : Integer -> Integer -> { [RND] } Eff m Integer
20−rndInt lower upper = do v <- getRandom
21+rndInt lower upper = do v <- call $ getRandom
21 return (v `prim__sremBigInt` (upper - lower) + lower)
22 return (v `prim__sremBigInt` (upper - lower) + lower)
22
23
24+||| Generate a random number in Fin (S `k`)
25+|||
26+||| Note that rndFin k takes values 0, 1, ..., k.
23rndFin : (k : Nat) -> { [RND] } Eff m (Fin (S k))
27rndFin : (k : Nat) -> { [RND] } Eff m (Fin (S k))
24−rndFin k = do let v = !getRandom `prim__sremBigInt` (cast k)
28+rndFin k = do let v = assert_total $ !(call getRandom) `prim__sremBigInt` (cast (S k))
25 return (toFin v)
29 return (toFin v)
26 where toFin : Integer -> Fin (S k)
30 where toFin : Integer -> Fin (S k)
27 toFin x = case integerToFin x (S k) of
31 toFin x = case integerToFin x (S k) of
28 Just v => v
32 Just v => v
29 Nothing => toFin (assert_smaller x (x - cast (S k)))
33 Nothing => toFin (assert_smaller x (x - cast (S k)))
30
34
35+||| Select a random element from a vector
36+rndSelect' : Vect (S k) a -> { [RND] } Eff IO a
37+rndSelect' {k} xs = return (Vect.index !(rndFin k) xs)
38+
39+||| Select a random element from a list, or Nothing if the list is empty
40+rndSelect : List a -> { [RND] } Eff IO (Maybe a)
41+rndSelect [] = return Nothing
42+rndSelect (x::xs) = return (Just !(rndSelect' (x::(fromList xs))))
43+
44+||| Sets the random seed
31srand : Integer -> { [RND] } Eff m ()
45srand : Integer -> { [RND] } Eff m ()
32−srand n = setSeed n
46+srand n = call $ setSeed n
33
47
libs/effects/Effect/Select.idr+1−1
@@ -19,5 +19,5 @@ SELECT : EFFECT
19SELECT = MkEff () Selection
19SELECT = MkEff () Selection
20
20
21select : List a -> { [SELECT] } Eff m a
21select : List a -> { [SELECT] } Eff m a
22−select xs = Select xs
22+select xs = call $ Select xs
23
23
libs/effects/Effect/State.idr+3−3
@@ -17,13 +17,13 @@ STATE : Type -> EFFECT
17STATE t = MkEff t State
17STATE t = MkEff t State
18
18
19get : { [STATE x] } Eff m x
19get : { [STATE x] } Eff m x
20−get = Get
20+get = call $ Get
21
21
22put : x -> { [STATE x] } Eff m ()
22put : x -> { [STATE x] } Eff m ()
23−put val = Put val
23+put val = call $ Put val
24
24
25putM : y -> { [STATE x] ==> [STATE y] } Eff m ()
25putM : y -> { [STATE x] ==> [STATE y] } Eff m ()
26−putM val = Put val
26+putM val = call $ Put val
27
27
28update : (x -> x) -> { [STATE x] } Eff m ()
28update : (x -> x) -> { [STATE x] } Eff m ()
29update f = put (f !get)
29update f = put (f !get)
libs/effects/Effect/StdIO.idr+26−9
@@ -3,12 +3,22 @@ module Effect.StdIO
3import Effects
3import Effects
4import Control.IOExcept
4import Control.IOExcept
5
5
6+-------------------------------------------------------------
7+-- IO effects internals
8+-------------------------------------------------------------
9+
10+||| The internal representation of StdIO effects
6data StdIO : Effect where
11data StdIO : Effect where
7 PutStr : String -> { () } StdIO ()
12 PutStr : String -> { () } StdIO ()
8 GetStr : { () } StdIO String
13 GetStr : { () } StdIO String
9 PutCh : Char -> { () } StdIO ()
14 PutCh : Char -> { () } StdIO ()
10 GetCh : { () } StdIO Char
15 GetCh : { () } StdIO Char
11
16
17+
18+-------------------------------------------------------------
19+-- IO effects handlers
20+-------------------------------------------------------------
21+
12instance Handler StdIO IO where
22instance Handler StdIO IO where
13 handle () (PutStr s) k = do putStr s; k () ()
23 handle () (PutStr s) k = do putStr s; k () ()
14 handle () GetStr k = do x <- getLine; k x ()
24 handle () GetStr k = do x <- getLine; k x ()
@@ -21,23 +31,30 @@ instance Handler StdIO (IOExcept a) where
21 handle () (PutCh c) k = do ioe_lift $ putChar c; k () ()
31 handle () (PutCh c) k = do ioe_lift $ putChar c; k () ()
22 handle () GetCh k = do x <- ioe_lift $ getChar; k x ()
32 handle () GetCh k = do x <- ioe_lift $ getChar; k x ()
23
33
34+-------------------------------------------------------------
24--- The Effect and associated functions
35--- The Effect and associated functions
36+-------------------------------------------------------------
25
37
26STDIO : EFFECT
38STDIO : EFFECT
27STDIO = MkEff () StdIO
39STDIO = MkEff () StdIO
28
40
41+||| Write a string to standard output.
29−putStr : Handler StdIO e => String -> { [STDIO] } Eff e ()
42+putStr : String -> { [STDIO] } Eff e ()
30−putStr s = PutStr s
43+putStr s = call $ PutStr s
31
44
45+||| Write a character to standard output.
32−putChar : Handler StdIO e => Char -> { [STDIO] } Eff e ()
46+putChar : Char -> { [STDIO] } Eff e ()
33−putChar c = PutCh c
47+putChar c = call $ PutCh c
34
48
49+||| Write a string to standard output, terminating with a newline.
35−putStrLn : Handler StdIO e => String -> { [STDIO] } Eff e ()
50+putStrLn : String -> { [STDIO] } Eff e ()
36putStrLn s = putStr (s ++ "\n")
51putStrLn s = putStr (s ++ "\n")
37
52
53+||| Read a string from standard input.
38−getStr : Handler StdIO e => { [STDIO] } Eff e String
54+getStr : { [STDIO] } Eff e String
39−getStr = GetStr
55+getStr = call $ GetStr
40
56
57+||| Read a character from standard input.
41−getChar : Handler StdIO e => { [STDIO] } Eff e Char
58+getChar : { [STDIO] } Eff e Char
42−getChar = GetCh
59+getChar = call $ GetCh
43
60
libs/effects/Effect/System.idr+3−3
@@ -28,11 +28,11 @@ SYSTEM : EFFECT
28SYSTEM = MkEff () System
28SYSTEM = MkEff () System
29
29
30getArgs : Handler System e => { [SYSTEM] } Eff e (List String)
30getArgs : Handler System e => { [SYSTEM] } Eff e (List String)
31−getArgs = Args
31+getArgs = call Args
32
32
33time : Handler System e => { [SYSTEM] } Eff e Int
33time : Handler System e => { [SYSTEM] } Eff e Int
34−time = Time
34+time = call Time
35
35
36getEnv : Handler System e => String -> { [SYSTEM] } Eff e (Maybe String)
36getEnv : Handler System e => String -> { [SYSTEM] } Eff e (Maybe String)
37−getEnv s = GetEnv s
37+getEnv s = call $ GetEnv s
38
38
libs/effects/Effects.idr+37−69
@@ -31,9 +31,9 @@ class Handler (e : Effect) (m : Type -> Type) where
31 |||
31 |||
32 ||| @ r The resource being handled.
32 ||| @ r The resource being handled.
33 ||| @ eff The effect to be applied.
33 ||| @ eff The effect to be applied.
34− ||| @ ctxt The context in which to handle the effect.
34+ ||| @ k The continuation to pass the result of the effect
35− handle : (r : res) -> (eff : e t res resk) ->
35+ covering handle : (r : res) -> (eff : e t res resk) ->
36− (ctxt : ((x : t) -> resk x -> m a)) -> m a
36+ (k : ((x : t) -> resk x -> m a)) -> m a
37
37
38||| Get the resource type (handy at the REPL to find out about an effect)
38||| Get the resource type (handy at the REPL to find out about an effect)
39resourceType : EFFECT -> Type
39resourceType : EFFECT -> Type
@@ -100,53 +100,6 @@ rebuildEnv xs (Drop rest) (y :: env) = y :: rebuildEnv xs rest env
100
100
101
101
102-- -------------------------------------------------- [ The Effect EDSL itself ]
102-- -------------------------------------------------- [ The Effect EDSL itself ]
103−-- some proof automation
104−
105−%reflection
106−reflectListEffElem : List a -> Tactic
107−reflectListEffElem [] = Refine "Here" `Seq` Solve
108−reflectListEffElem (x :: xs)
109− = Try (Refine "Here" `Seq` Solve)
110− (Refine "There" `Seq` (Solve `Seq` reflectListEffElem xs))
111−-- TMP HACK! FIXME!
112−-- The evaluator needs a 'function case' to know its a reflection function
113−-- until we propagate that information! Without this, the _ case won't get
114−-- matched.
115−reflectListEffElem (x ++ y) = Refine "Here" `Seq` Solve
116−reflectListEffElem _ = Refine "Here" `Seq` Solve
117−
118−%reflection
119−reflectSubList : List a -> Tactic
120−reflectSubList [] = Refine "subListId" `Seq` Solve
121−reflectSubList (x :: xs)
122− = Try (Refine "subListId" `Seq` Solve)
123− (Try (Refine "Keep" `Seq` (Solve `Seq` reflectSubList xs))
124− (Refine "Drop" `Seq` (Solve `Seq` reflectSubList xs)))
125−reflectSubList (x ++ y) = Refine "subListId" `Seq` Solve
126−reflectSubList _ = Refine "subListId" `Seq` Solve
127−
128−%reflection
129−reflectDefaultList : List a -> Tactic
130−reflectDefaultList [] = Refine "enil" `Seq` Solve
131−reflectDefaultList (x :: xs)
132− = Refine "econs" `Seq`
133− (Solve `Seq`
134− (Instance `Seq`
135− (Refine "default" `Seq`
136− (Solve `Seq`
137− (Instance `Seq`
138− (reflectDefaultList xs))))))
139−reflectDefaultList (x ++ y) = Refine "Nil" `Seq` Solve
140−reflectDefaultList _ = Refine "Nil" `Seq` Solve
141−
142−%reflection
143−reflectEff : (P : Type) -> Tactic
144−reflectEff (EffElem m a xs)
145− = reflectListEffElem xs `Seq` Solve
146−reflectEff (SubList xs ys)
147− = reflectSubList ys `Seq` Solve
148−reflectEff (Env m xs)
149− = reflectDefaultList xs `Seq` Solve
150
103
151updateResTy : (val : t) ->
104updateResTy : (val : t) ->
152 (xs : List EFFECT) -> EffElem e a xs -> e t a b ->
105 (xs : List EFFECT) -> EffElem e a xs -> e t a b ->
@@ -191,11 +144,11 @@ data Eff : (m : Type -> Type)
191 Eff m a xs xs'
144 Eff m a xs xs'
192 ebind : Eff m a xs xs' ->
145 ebind : Eff m a xs xs' ->
193 ((val : a) -> Eff m b (xs' val) xs'') -> Eff m b xs xs''
146 ((val : a) -> Eff m b (xs' val) xs'') -> Eff m b xs xs''
194− effect : (prf : EffElem e a xs) ->
147+ callP : (prf : EffElem e a xs) ->
195 (eff : e t a b) ->
148 (eff : e t a b) ->
196 Eff m t xs (\v => updateResTy v xs prf eff)
149 Eff m t xs (\v => updateResTy v xs prf eff)
197
150
198− lift : (prf : SubList ys xs) ->
151+ liftP : (prf : SubList ys xs) ->
199 Eff m t ys ys' -> Eff m t xs (\v => updateWith (ys' v) xs prf)
152 Eff m t ys ys' -> Eff m t xs (\v => updateWith (ys' v) xs prf)
200 newInit : Handler e m =>
153 newInit : Handler e m =>
201 res ->
154 res ->
@@ -213,6 +166,20 @@ data Eff : (m : Type -> Type)
213 ((val : a) -> Eff m b (xs' val) xs'') -> Eff m b xs xs''
166 ((val : a) -> Eff m b (xs' val) xs'') -> Eff m b xs xs''
214(>>=) = ebind
167(>>=) = ebind
215
168
169+-- namespace SimpleBind
170+-- (>>=) : Eff m a xs (\v => xs) ->
171+-- ((val : a) -> Eff m b xs xs') -> Eff m b xs xs'
172+-- (>>=) = ebind
173+
174+||| Run a subprogram which results in an effect state the same as the input.
175+staticEff : Eff m a xs (\v => xs) -> Eff m a xs (\v => xs)
176+staticEff = id
177+
178+||| Explicitly give the expected set of result effects for an effectful
179+||| operation.
180+toEff : .(xs' : List EFFECT) -> Eff m a xs (\v => xs') -> Eff m a xs (\v => xs')
181+toEff xs' = id
182+
216return : a -> Eff m a xs (\v => xs)
183return : a -> Eff m a xs (\v => xs)
217return x = value x
184return x = value x
218
185
@@ -251,8 +218,8 @@ eff env (value x) k = k x env
251eff env (with_val x prog) k = eff env prog (\p', env' => k x env')
218eff env (with_val x prog) k = eff env prog (\p', env' => k x env')
252eff env (prog `ebind` c) k
219eff env (prog `ebind` c) k
253 = eff env prog (\p', env' => eff env' (c p') k)
220 = eff env prog (\p', env' => eff env' (c p') k)
254−eff env (effect prf effP) k = execEff env prf effP k
221+eff env (callP prf effP) k = execEff env prf effP k
255−eff env (lift prf effP) k
222+eff env (liftP prf effP) k
256 = let env' = dropEnv env prf in
223 = let env' = dropEnv env prf in
257 eff env' effP (\p', envk => k p' (rebuildEnv envk prf env))
224 eff env' effP (\p', envk => k p' (rebuildEnv envk prf env))
258eff env (newInit r prog) k
225eff env (newInit r prog) k
@@ -269,7 +236,8 @@ eff {xs = [l ::: x]} env (l :- prog) k
269 eff env' prog (\p', envk => k p' (relabel l envk))
236 eff env' prog (\p', envk => k p' (relabel l envk))
270
237
271-- yuck :) Haven't got type class instances working nicely in tactic
238-- yuck :) Haven't got type class instances working nicely in tactic
239+-- proofs yet, and 'search' can't be told about any hints yet,
272−-- proofs yet, so just brute force it.
240+-- so just brute force it.
273syntax MkDefaultEnv = with Env
241syntax MkDefaultEnv = with Env
274 (| [], [default], [default, default],
242 (| [], [default], [default, default],
275 [default, default, default],
243 [default, default, default],
@@ -279,20 +247,20 @@ syntax MkDefaultEnv = with Env
279 [default, default, default, default, default, default, default],
247 [default, default, default, default, default, default, default],
280 [default, default, default, default, default, default, default, default] |)
248 [default, default, default, default, default, default, default, default] |)
281
249
282−implicit
250+call : {a, b: _} -> {e : Effect} ->
283−lift' : Eff m t ys ys' ->
251+ (eff : e t a b) ->
284− {default tactics { byReflection reflectEff; }
252+ {default tactics { search 100; }
285− prf : SubList ys xs} ->
253+ prf : EffElem e a xs} ->
286− Eff m t xs (\v => updateWith (ys' v) xs prf)
254+ Eff m t xs (\v => updateResTy v xs prf eff)
287−lift' e {prf} = lift prf e
255+call e {prf} = callP prf e
288
256
289implicit
257implicit
290−effect' : {a, b: _} -> {e : Effect} ->
258+lift : Eff m t ys ys' ->
291− (eff : e t a b) ->
292− {default tactics { byReflection reflectEff; }
259+ {default tactics { search 100; }
293− prf : EffElem e a xs} ->
260+ prf : SubList ys xs} ->
294− Eff m t xs (\v => updateResTy v xs prf eff)
261+ Eff m t xs (\v => updateWith (ys' v) xs prf)
295−effect' e {prf} = effect prf e
262+lift e {prf} = liftP prf e
263+
296
264
297new : Handler e m =>
265new : Handler e m =>
298 {default default r : res} ->
266 {default default r : res} ->
@@ -337,8 +305,8 @@ mapVE f [] = pure []
337mapVE f (x :: xs) = [| f x :: mapVE f xs |]
305mapVE f (x :: xs) = [| f x :: mapVE f xs |]
338
306
339
307
340−when : Applicative m => Bool -> ({xs} Eff m ()) -> {xs} Eff m ()
308+when : Applicative m => Bool -> Lazy ({xs} Eff m ()) -> {xs} Eff m ()
341−when True e = e
309+when True e = Force e
342when False e = pure ()
310when False e = pure ()
343
311
344-- --------------------------------------------------------------------- [ EOF ]
312-- --------------------------------------------------------------------- [ EOF ]
libs/javascript/JavaScript.idrdeleted−104
@@ -1,104 +0,0 @@
1−module JavaScript
2−
3−%access public
4−
5−private
6−isUndefined : Ptr -> IO Bool
7−isUndefined p = do
8− res <- mkForeign (
9− FFun "%0 === undefined" [FPtr] FString) p
10− if res == "false"
11− then (return False)
12− else (return True)
13−
14−--------------------------------------------------------------------------------
15−-- Events
16−--------------------------------------------------------------------------------
17−abstract
18−data Event : Type where
19− MkEvent : Ptr -> Event
20−
21−--------------------------------------------------------------------------------
22−-- Elements
23−--------------------------------------------------------------------------------
24−abstract
25−data Element : Type where
26− MkElem : Ptr -> Element
27−
28−setText : Element -> String -> IO ()
29−setText (MkElem p) s =
30− mkForeign (FFun "%0.textContent=%1" [FPtr, FString] FUnit) p s
31−
32−
33−setOnClick : Element -> (Event -> IO Bool) -> IO ()
34−setOnClick (MkElem e) f =
35− mkForeign (
36− FFun "%0['onclick']=%1" [ FPtr
37− , FFunction (FAny Event) (FAny (IO Bool))
38− ] FUnit) e f
39−--------------------------------------------------------------------------------
40−-- Nodelists
41−--------------------------------------------------------------------------------
42−abstract
43−data NodeList : Type where
44− MkNodeList : Ptr -> NodeList
45−
46−elemAt : NodeList -> Nat -> IO (Maybe Element)
47−elemAt (MkNodeList p) i = do
48− e <- mkForeign (FFun "%0.item(%1)" [FPtr, FInt] FPtr) p (
49− prim__truncBigInt_Int (cast i)
50− )
51− d <- isUndefined e
52− if d
53− then return $ Just (MkElem e)
54− else return Nothing
55−
56−--------------------------------------------------------------------------------
57−-- Intervals
58−--------------------------------------------------------------------------------
59−abstract
60−data Interval : Type where
61− MkInterval : Ptr -> Interval
62−
63−setInterval : (() -> IO ()) -> Float -> IO Interval
64−setInterval f t = do
65− e <- mkForeign (
66− FFun "setInterval(%0,%1)" [FFunction FUnit (FAny (IO ())), FFloat] FPtr
67− ) f t
68− return (MkInterval e)
69−
70−clearInterval : Interval -> IO ()
71−clearInterval (MkInterval p) =
72− mkForeign (FFun "clearInterval(%0)" [FPtr] FUnit) p
73−
74−--------------------------------------------------------------------------------
75−-- Timeouts
76−--------------------------------------------------------------------------------
77−data Timeout : Type where
78− MkTimeout : Ptr -> Timeout
79−
80−setTimeout : (() -> IO ()) -> Float -> IO Timeout
81−setTimeout f t = do
82− e <- mkForeign (
83− FFun "setTimeout(%0,%1)" [FFunction FUnit (FAny (IO ())), FFloat] FPtr
84− ) f t
85− return (MkTimeout e)
86−
87−clearTimeout : Timeout -> IO ()
88−clearTimeout (MkTimeout p) =
89− mkForeign (FFun "clearTimeout(%0)" [FPtr] FUnit) p
90−
91−--------------------------------------------------------------------------------
92−-- Basic IO
93−--------------------------------------------------------------------------------
94−alert : String -> IO ()
95−alert msg =
96− mkForeign (FFun "alert(%0)" [FString] FUnit) msg
97−
98−--------------------------------------------------------------------------------
99−-- DOM
100−--------------------------------------------------------------------------------
101−query : String -> IO NodeList
102−query q = do
103− e <- mkForeign (FFun "document.querySelectorAll(%0)" [FString] FPtr) q
104− return (MkNodeList e)
libs/javascript/JavaScript/JSON.idrdeleted−44
@@ -1,44 +0,0 @@
1−module JSON
2−
3−import Data.SortedMap
4−
5−data JSONType : Type where
6− JSONArray : (n : Nat) -> Vect n JSONType -> JSONType
7− JSONString : JSONType
8− JSONNumber : JSONType
9− JSONBool : JSONType
10− JSONObject : SortedMap String JSONType -> JSONType
11− JSONNull : JSONType
12−
13−mutual
14− using (ts : Vect n JSONType, fs : SortedMap String JSONType)
15− namespace JArray
16− data JArray : (n : Nat) -> Vect n JSONType -> Type where
17− Nil : JArray 0 []
18− (::) : JSON t -> JArray n ts -> JArray (S n) (t :: ts)
19−
20− namespace JObject
21− data JObject : SortedMap String JSONType -> Type where
22− Nil : JObject empty
23− (::) : (f : (String, JSON t)) ->
24− JObject fs ->
25− JObject (insert (fst f) t fs)
26−
27− data JSON : JSONType -> Type where
28− JSString : String -> JSON JSONString
29− JSNumber : Float -> JSON JSONNumber
30− JSBool : Bool -> JSON JSONBool
31− JSNull : JSON JSONNull
32− JSArray : JArray n ts -> JSON (JSONArray n ts)
33− JSObject : JObject fs -> JSON (JSONObject fs)
34−
35−index : (i : Fin n) -> JSON (JSONArray n ts) -> JSON (index i ts)
36−index fZ (JSArray (x :: xs)) = x
37−index (fS i) (JSArray (x :: xs)) = index i (JSArray xs)
38−
39−(++) : JSON (JSONArray m ts1) ->
40− JSON (JSONArray n ts2) ->
41− JSON (JSONArray (m + n) (ts1 ++ ts2))
42−(++) (JSArray []) ys = ys
43−(++) (JSArray (x :: xs)) ys with ((JSArray xs) ++ ys)
44− | (JSArray as) = JSArray (x :: as)
libs/javascript/Makefiledeleted−14
@@ -1,14 +0,0 @@
1−IDRIS := idris
2−
3−build:
4− $(IDRIS) --build javascript.ipkg
5−
6−install:
7− $(IDRIS) --install javascript.ipkg
8−
9−clean:
10− $(IDRIS) --clean javascript.ipkg
11−
12−rebuild: clean build
13−
14−.PHONY: build install clean rebuild
libs/javascript/javascript.ipkgdeleted−5
@@ -1,5 +0,0 @@
1−package javascript
2−
3−opts = "--nobasepkgs -i ../prelude -i ../base"
4−modules = JavaScript, JavaScript.JSON
5−
libs/oldeffects/Effects.idr+1−1
@@ -303,6 +303,6 @@ mapE : Applicative m => (a -> Eff m xs b) -> List a -> Eff m xs (List b)
303mapE f [] = pure []
303mapE f [] = pure []
304mapE f (x :: xs) = [| f x :: mapE f xs |]
304mapE f (x :: xs) = [| f x :: mapE f xs |]
305
305
306−when : Applicative m => Bool -> Eff m xs () -> Eff m xs ()
306+when : Applicative m => Bool -> Lazy (Eff m xs ()) -> Eff m xs ()
307when True e = e
307when True e = e
308when False e = pure ()
308when False e = pure ()
libs/prelude/Builtins.idr+24−18
@@ -6,17 +6,10 @@
6||| Dependent pairs, in their internal representation
6||| Dependent pairs, in their internal representation
7||| @ a the type of the witness
7||| @ a the type of the witness
8||| @ P the type of the proof
8||| @ P the type of the proof
9−data Exists : (a : Type) -> (P : a -> Type) -> Type where
9+data Sigma : (a : Type) -> (P : a -> Type) -> Type where
10− Ex_intro : {P : a -> Type} -> (x : a) -> P x -> Exists a P
10+ Sg_intro : .{P : a -> Type} -> (x : a) -> (pf : P x) -> Sigma a P
11−
12−||| The first projection from a dependent pair
13−getWitness : {P : a -> Type} -> Exists a P -> a
14−getWitness (a ** v) = a
15−
16−||| The second projection from a dependent pair
17−getProof : {P : a -> Type} -> (s : Exists a P) -> P (getWitness s)
18−getProof (a ** v) = v
19
11
12+||| The eliminator for the empty type.
20FalseElim : _|_ -> a
13FalseElim : _|_ -> a
21
14
22||| For 'symbol syntax. 'foo becomes Symbol_ "foo"
15||| For 'symbol syntax. 'foo becomes Symbol_ "foo"
@@ -34,26 +27,39 @@ sym : {l:a} -> {r:a} -> l = r -> r = l
34sym refl = refl
27sym refl = refl
35
28
36||| Transitivity of propositional equality
29||| Transitivity of propositional equality
37−trans : {a:x} -> {b:x} -> {c:x} -> a = b -> b = c -> a = c
30+trans : {a:x} -> {b:y} -> {c:z} -> a = b -> b = c -> a = c
38trans refl refl = refl
31trans refl refl = refl
39
32
40−lazy : a -> a
33+||| There are two types of laziness: that arising from lazy functions, and that
41−lazy x = x -- compiled specially
34+||| arising from codata. They differ in their totality condition.
42−
43−force : a -> a
44−force x = x -- compiled specially
45−
46data LazyType = LazyCodata | LazyEval
35data LazyType = LazyCodata | LazyEval
47
36
37+||| The underlying implementation of Lazy and Inf.
38+%error_reverse
48data Lazy' : LazyType -> Type -> Type where
39data Lazy' : LazyType -> Type -> Type where
40+ ||| A delayed computation.
41+ |||
42+ ||| Delay is inserted automatically by the elaborator where necessary.
43+ |||
44+ ||| Note that compiled code gives `Delay` special semantics.
45+ ||| @ t whether this is laziness from codata or normal lazy evaluation
46+ ||| @ a the type of the eventual value
47+ ||| @ val a computation that will produce a value
49 Delay : {t, a : _} -> (val : a) -> Lazy' t a
48 Delay : {t, a : _} -> (val : a) -> Lazy' t a
50
49
50+||| Compute a value from a delayed computation.
51+|||
52+||| Inserted by the elaborator where necessary.
51Force : {t, a : _} -> Lazy' t a -> a
53Force : {t, a : _} -> Lazy' t a -> a
52Force (Delay x) = x
54Force (Delay x) = x
53
55
56+||| Lazily evaluated values. This has special evaluation semantics.
54Lazy : Type -> Type
57Lazy : Type -> Type
55Lazy t = Lazy' LazyEval t
58Lazy t = Lazy' LazyEval t
56
59
60+||| Recursive parameters to codata. Inserted automatically by the elaborator
61+||| on a "codata" definition but is necessary by hand if mixing inductive and
62+||| coinductive parameters.
57Inf : Type -> Type
63Inf : Type -> Type
58Inf t = Lazy' LazyCodata t
64Inf t = Lazy' LazyCodata t
59
65
@@ -71,7 +77,7 @@ trace_malloc x = x -- compiled specially
71||| x (which is typically a pattern argument)
77||| x (which is typically a pattern argument)
72||| @ x the larger value (typically a pattern argument)
78||| @ x the larger value (typically a pattern argument)
73||| @ y the smaller value (typically an argument to a recursive call)
79||| @ y the smaller value (typically an argument to a recursive call)
74−assert_smaller : (x, y : a) -> a
80+assert_smaller : (x : a) -> (y : b) -> b
75assert_smaller x y = y
81assert_smaller x y = y
76
82
77||| Assert to the totality checker than the given expression will always
83||| Assert to the totality checker than the given expression will always
libs/prelude/Prelude.idr+44−14
@@ -21,6 +21,7 @@ import Prelude.Traversable
21import Prelude.Bits
21import Prelude.Bits
22import Prelude.Stream
22import Prelude.Stream
23import Prelude.Uninhabited
23import Prelude.Uninhabited
24+import Prelude.Pairs
24
25
25import Decidable.Equality
26import Decidable.Equality
26
27
@@ -347,27 +348,38 @@ natRange n = List.reverse (go n)
347 where go Z = []
348 where go Z = []
348 go (S n) = n :: go n
349 go (S n) = n :: go n
349
350
351+-- predefine Nat versions of Enum, so we can use them in the default impls
352+total natEnumFromThen : Nat -> Nat -> Stream Nat
353+natEnumFromThen n inc = n :: natEnumFromThen (inc + n) inc
354+total natEnumFromTo : Nat -> Nat -> List Nat
355+natEnumFromTo n m = map (plus n) (natRange ((S m) - n))
356+total natEnumFromThenTo : Nat -> Nat -> Nat -> List Nat
357+natEnumFromThenTo _ Z _ = []
358+natEnumFromThenTo n inc m = map (plus n . (* inc)) (natRange (S ((m - n) `div` inc)))
359+
350class Enum a where
360class Enum a where
351 total pred : a -> a
361 total pred : a -> a
352 total succ : a -> a
362 total succ : a -> a
363+ succ e = fromNat (S (toNat e))
353 total toNat : a -> Nat
364 total toNat : a -> Nat
354 total fromNat : Nat -> a
365 total fromNat : Nat -> a
355 total enumFrom : a -> Stream a
366 total enumFrom : a -> Stream a
356 enumFrom n = n :: enumFrom (succ n)
367 enumFrom n = n :: enumFrom (succ n)
357 total enumFromThen : a -> a -> Stream a
368 total enumFromThen : a -> a -> Stream a
369+ enumFromThen x y = map fromNat (natEnumFromThen (toNat x) (toNat y))
358 total enumFromTo : a -> a -> List a
370 total enumFromTo : a -> a -> List a
371+ enumFromTo x y = map fromNat (natEnumFromTo (toNat x) (toNat y))
359 total enumFromThenTo : a -> a -> a -> List a
372 total enumFromThenTo : a -> a -> a -> List a
360−
373+ enumFromThenTo x1 x2 y = map fromNat (natEnumFromThenTo (toNat x1) (toNat x2) (toNat y))
361
374
362instance Enum Nat where
375instance Enum Nat where
363− pred = Nat.pred
376+ pred n = Nat.pred n
364− succ = S
377+ succ n = S n
365− toNat = id
378+ toNat x = id x
366− fromNat = id
379+ fromNat x = id x
367− enumFromThen n inc = n :: enumFromThen (fromNat (plus (toNat inc) (toNat n))) inc
380+ enumFromThen x y = natEnumFromThen x y
368− enumFromThenTo _ Z _ = []
381+ enumFromThenTo x y z = natEnumFromThenTo x y z
369− enumFromThenTo n inc m = map (plus n . (* inc)) (natRange (S ((m - n) `div` inc)))
382+ enumFromTo x y = natEnumFromTo x y
370− enumFromTo n m = map (plus n) (natRange ((S m) - n))
371
383
372instance Enum Integer where
384instance Enum Integer where
373 pred n = n - 1
385 pred n = n - 1
@@ -407,14 +419,25 @@ instance Enum Int where
407 go [] = []
419 go [] = []
408 go (x :: xs) = n + (cast x * inc) :: go xs
420 go (x :: xs) = n + (cast x * inc) :: go xs
409
421
422+instance Enum (Fin (S n)) where
423+ pred fZ = fZ
424+ pred (fS n) = weaken n
425+ succ n = case strengthen (fS n) of
426+ Left _ => last
427+ Right k => k
428+ toNat n = cast n
429+ fromNat {n=n} m = case natToFin m (S n) of
430+ Just k => k
431+ Nothing => last
432+
410syntax "[" [start] ".." [end] "]"
433syntax "[" [start] ".." [end] "]"
411 = enumFromTo start end
434 = enumFromTo start end
412syntax "[" [start] "," [next] ".." [end] "]"
435syntax "[" [start] "," [next] ".." [end] "]"
413 = enumFromThenTo start (next - start) end
436 = enumFromThenTo start (next - start) end
414
437
415−syntax "[" [start] "..]"
438+syntax "[" [start] ".." "]"
416 = enumFrom start
439 = enumFrom start
417−syntax "[" [start] "," [next] "..]"
440+syntax "[" [start] "," [next] ".." "]"
418 = enumFromThen start (next - start)
441 = enumFromThen start (next - start)
419
442
420---- More utilities
443---- More utilities
@@ -478,6 +501,14 @@ data File = FHandle Ptr
478partial stdin : File
501partial stdin : File
479stdin = FHandle prim__stdin
502stdin = FHandle prim__stdin
480
503
504+||| Standard output
505+partial stdout : File
506+stdout = FHandle prim__stdout
507+
508+||| Standard output
509+partial stderr : File
510+stderr = FHandle prim__stderr
511+
481||| Call the RTS's file opening function
512||| Call the RTS's file opening function
482do_fopen : String -> String -> IO Ptr
513do_fopen : String -> String -> IO Ptr
483do_fopen f m
514do_fopen f m
@@ -519,9 +550,9 @@ fgetc : File -> IO Char
519fgetc (FHandle h) = return (cast !(mkForeign (FFun "fgetc" [FPtr] FInt) h))
550fgetc (FHandle h) = return (cast !(mkForeign (FFun "fgetc" [FPtr] FInt) h))
520
551
521fgetc' : File -> IO (Maybe Char)
552fgetc' : File -> IO (Maybe Char)
522−fgetc' (FHandle h)
553+fgetc' (FHandle h)
523 = do x <- mkForeign (FFun "fgetc" [FPtr] FInt) h
554 = do x <- mkForeign (FFun "fgetc" [FPtr] FInt) h
524− if (x < 0) then return Nothing
555+ if (x < 0) then return Nothing
525 else return (Just (cast x))
556 else return (Just (cast x))
526
557
527fflush : File -> IO ()
558fflush : File -> IO ()
@@ -620,4 +651,3 @@ readFile fn = do h <- openFile fn Read
620 if not x then do l <- fread h
651 if not x then do l <- fread h
621 readFile' h (contents ++ l)
652 readFile' h (contents ++ l)
622 else return contents
653 else return contents
623−
libs/prelude/Prelude/Algebra.idr+191−176
@@ -13,238 +13,253 @@ infixl 6 <*>
13-- A modest class hierarchy
13-- A modest class hierarchy
14--------------------------------------------------------------------------------
14--------------------------------------------------------------------------------
15
15
16−-- Sets equipped with a single binary operation that is associative. Must
16+||| Sets equipped with a single binary operation that is associative. Must
17−-- satisfy the following laws:
17+||| satisfy the following laws:
18+|||
18−-- Associativity of <+>:
19+||| + Associativity of `<+>`:
19−-- forall a b c, a <+> (b <+> c) == (a <+> b) <+> c
20+||| forall a b c, a <+> (b <+> c) == (a <+> b) <+> c
20class Semigroup a where
21class Semigroup a where
21 (<+>) : a -> a -> a
22 (<+>) : a -> a -> a
22
23
23class Semigroup a => VerifiedSemigroup a where
24class Semigroup a => VerifiedSemigroup a where
24− semigroupOpIsAssociative : (l, c, r : a) -> l <+> (c <+> r) = (l <+> c) <+> r
25+ total semigroupOpIsAssociative : (l, c, r : a) -> l <+> (c <+> r) = (l <+> c) <+> r
25
26
26−-- Sets equipped with a single binary operation that is associative, along with
27+||| Sets equipped with a single binary operation that is associative, along with
27−-- a neutral element for that binary operation. Must satisfy the following
28+||| a neutral element for that binary operation. Must satisfy the following
28−-- laws:
29+||| laws:
30+|||
29−-- Associativity of <+>:
31+||| + Associativity of `<+>`:
30−-- forall a b c, a <+> (b <+> c) == (a <+> b) <+> c
32+||| forall a b c, a <+> (b <+> c) == (a <+> b) <+> c
31−-- Neutral for <+>:
33+||| + Neutral for `<+>`:
32−-- forall a, a <+> neutral == a
34+||| forall a, a <+> neutral == a
33−-- forall a, neutral <+> a == a
35+||| forall a, neutral <+> a == a
34class Semigroup a => Monoid a where
36class Semigroup a => Monoid a where
35 neutral : a
37 neutral : a
36
38
37class (VerifiedSemigroup a, Monoid a) => VerifiedMonoid a where
39class (VerifiedSemigroup a, Monoid a) => VerifiedMonoid a where
38− monoidNeutralIsNeutralL : (l : a) -> l <+> neutral = l
40+ total monoidNeutralIsNeutralL : (l : a) -> l <+> neutral = l
39− monoidNeutralIsNeutralR : (r : a) -> neutral <+> r = r
41+ total monoidNeutralIsNeutralR : (r : a) -> neutral <+> r = r
40
42
41−-- Sets equipped with a single binary operation that is associative, along with
43+||| Sets equipped with a single binary operation that is associative, along with
42−-- a neutral element for that binary operation and inverses for all elements.
44+||| a neutral element for that binary operation and inverses for all elements.
43−-- Must satisfy the following laws:
45+||| Must satisfy the following laws:
44−-- Associativity of <+>:
46+||| + Associativity of `<+>`:
45−-- forall a b c, a <+> (b <+> c) == (a <+> b) <+> c
47+||| forall a b c, a <+> (b <+> c) == (a <+> b) <+> c
46−-- Neutral for <+>:
48+||| + Neutral for `<+>`:
47−-- forall a, a <+> neutral == a
49+||| forall a, a <+> neutral == a
48−-- forall a, neutral <+> a == a
50+||| forall a, neutral <+> a == a
49−-- Inverse for <+>:
51+||| + Inverse for `<+>`:
50−-- forall a, a <+> inverse a == neutral
52+||| forall a, a <+> inverse a == neutral
51−-- forall a, inverse a <+> a == neutral
53+||| forall a, inverse a <+> a == neutral
52class Monoid a => Group a where
54class Monoid a => Group a where
53 inverse : a -> a
55 inverse : a -> a
54
56
55class (VerifiedMonoid a, Group a) => VerifiedGroup a where
57class (VerifiedMonoid a, Group a) => VerifiedGroup a where
56− groupInverseIsInverseL : (l : a) -> l <+> inverse l = neutral
58+ total groupInverseIsInverseL : (l : a) -> l <+> inverse l = neutral
57− groupInverseIsInverseR : (r : a) -> inverse r <+> r = neutral
59+ total groupInverseIsInverseR : (r : a) -> inverse r <+> r = neutral
58
60
59(<->) : Group a => a -> a -> a
61(<->) : Group a => a -> a -> a
60(<->) left right = left <+> (inverse right)
62(<->) left right = left <+> (inverse right)
61
63
62−-- Sets equipped with a single binary operation that is associative and
64+||| Sets equipped with a single binary operation that is associative and
63−-- commutative, along with a neutral element for that binary operation and
65+||| commutative, along with a neutral element for that binary operation and
64−-- inverses for all elements. Must satisfy the following laws:
66+||| inverses for all elements. Must satisfy the following laws:
67+|||
65−-- Associativity of <+>:
68+||| + Associativity of `<+>`:
66−-- forall a b c, a <+> (b <+> c) == (a <+> b) <+> c
69+||| forall a b c, a <+> (b <+> c) == (a <+> b) <+> c
67−-- Commutativity of <+>:
70+||| + Commutativity of `<+>`:
68−-- forall a b, a <+> b == b <+> a
71+||| forall a b, a <+> b == b <+> a
69−-- Neutral for <+>:
72+||| + Neutral for `<+>`:
70−-- forall a, a <+> neutral == a
73+||| forall a, a <+> neutral == a
71−-- forall a, neutral <+> a == a
74+||| forall a, neutral <+> a == a
72−-- Inverse for <+>:
75+||| + Inverse for `<+>`:
73−-- forall a, a <+> inverse a == neutral
76+||| forall a, a <+> inverse a == neutral
74−-- forall a, inverse a <+> a == neutral
77+||| forall a, inverse a <+> a == neutral
75class Group a => AbelianGroup a where { }
78class Group a => AbelianGroup a where { }
76
79
77class (VerifiedGroup a, AbelianGroup a) => VerifiedAbelianGroup a where
80class (VerifiedGroup a, AbelianGroup a) => VerifiedAbelianGroup a where
78− abelianGroupOpIsCommutative : (l, r : a) -> l <+> r = r <+> l
81+ total abelianGroupOpIsCommutative : (l, r : a) -> l <+> r = r <+> l
79
82
80−-- Sets equipped with two binary operations, one associative and commutative
83+||| Sets equipped with two binary operations, one associative and commutative
81−-- supplied with a neutral element, and the other associative, with
84+||| supplied with a neutral element, and the other associative, with
82−-- distributivity laws relating the two operations. Must satisfy the following
85+||| distributivity laws relating the two operations. Must satisfy the following
83−-- laws:
86+||| laws:
87+|||
84−-- Associativity of <+>:
88+||| + Associativity of `<+>`:
85−-- forall a b c, a <+> (b <+> c) == (a <+> b) <+> c
89+||| forall a b c, a <+> (b <+> c) == (a <+> b) <+> c
86−-- Commutativity of <+>:
90+||| + Commutativity of `<+>`:
87−-- forall a b, a <+> b == b <+> a
91+||| forall a b, a <+> b == b <+> a
88−-- Neutral for <+>:
92+||| + Neutral for `<+>`:
89−-- forall a, a <+> neutral == a
93+||| forall a, a <+> neutral == a
90−-- forall a, neutral <+> a == a
94+||| forall a, neutral <+> a == a
91−-- Inverse for <+>:
95+||| + Inverse for `<+>`:
92−-- forall a, a <+> inverse a == neutral
96+||| forall a, a <+> inverse a == neutral
93−-- forall a, inverse a <+> a == neutral
97+||| forall a, inverse a <+> a == neutral
94−-- Associativity of <*>:
98+||| + Associativity of `<*>`:
95−-- forall a b c, a <*> (b <*> c) == (a <*> b) <*> c
99+||| forall a b c, a <*> (b <*> c) == (a <*> b) <*> c
96−-- Distributivity of <*> and <->:
100+||| + Distributivity of `<*>` and `<->`:
97−-- forall a b c, a <*> (b <+> c) == (a <*> b) <+> (a <*> c)
101+||| forall a b c, a <*> (b <+> c) == (a <*> b) <+> (a <*> c)
98−-- forall a b c, (a <+> b) <*> c == (a <*> c) <+> (b <*> c)
102+||| forall a b c, (a <+> b) <*> c == (a <*> c) <+> (b <*> c)
99class AbelianGroup a => Ring a where
103class AbelianGroup a => Ring a where
100 (<*>) : a -> a -> a
104 (<*>) : a -> a -> a
101
105
102class (VerifiedAbelianGroup a, Ring a) => VerifiedRing a where
106class (VerifiedAbelianGroup a, Ring a) => VerifiedRing a where
103− ringOpIsAssociative : (l, c, r : a) -> l <*> (c <*> r) = (l <*> c) <*> r
107+ total ringOpIsAssociative : (l, c, r : a) -> l <*> (c <*> r) = (l <*> c) <*> r
104− ringOpIsDistributiveL : (l, c, r : a) -> l <*> (c <+> r) = (l <*> c) <+> (l <*> r)
108+ total ringOpIsDistributiveL : (l, c, r : a) -> l <*> (c <+> r) = (l <*> c) <+> (l <*> r)
105− ringOpIsDistributiveR : (l, c, r : a) -> (l <+> c) <*> r = (l <*> r) <+> (l <*> c)
109+ total ringOpIsDistributiveR : (l, c, r : a) -> (l <+> c) <*> r = (l <*> r) <+> (c <*> r)
106
110
107−-- Sets equipped with two binary operations, one associative and commutative
111+||| Sets equipped with two binary operations, one associative and commutative
108−-- supplied with a neutral element, and the other associative supplied with a
112+||| supplied with a neutral element, and the other associative supplied with a
109−-- neutral element, with distributivity laws relating the two operations. Must
113+||| neutral element, with distributivity laws relating the two operations. Must
110−-- satisfy the following laws:
114+||| satisfy the following laws:
115+|||
111−-- Associativity of <+>:
116+||| + Associativity of `<+>`:
112−-- forall a b c, a <+> (b <+> c) == (a <+> b) <+> c
117+||| forall a b c, a <+> (b <+> c) == (a <+> b) <+> c
113−-- Commutativity of <+>:
118+||| + Commutativity of `<+>`:
114−-- forall a b, a <+> b == b <+> a
119+||| forall a b, a <+> b == b <+> a
115−-- Neutral for <+>:
120+||| + Neutral for `<+>`:
116−-- forall a, a <+> neutral == a
121+||| forall a, a <+> neutral == a
117−-- forall a, neutral <+> a == a
122+||| forall a, neutral <+> a == a
118−-- Inverse for <+>:
123+||| + Inverse for `<+>`:
119−-- forall a, a <+> inverse a == neutral
124+||| forall a, a <+> inverse a == neutral
120−-- forall a, inverse a <+> a == neutral
125+||| forall a, inverse a <+> a == neutral
121−-- Associativity of <*>:
126+||| + Associativity of `<*>a:
122−-- forall a b c, a <*> (b <*> c) == (a <*> b) <*> c
127+||| forall a b c, a <*> (b <*> c) == (a <*> b) <*> c
123−-- Neutral for <*>:
128+||| + Neutral for `<*>`:
124−-- forall a, a <*> unity == a
129+||| forall a, a <*> unity == a
125−-- forall a, unity <*> a == a
130+||| forall a, unity <*> a == a
126−-- Distributivity of <*> and <->:
131+||| + Distributivity of `<*>` and `<->`:
127−-- forall a b c, a <*> (b <+> c) == (a <*> b) <+> (a <*> c)
132+||| forall a b c, a <*> (b <+> c) == (a <*> b) <+> (a <*> c)
128−-- forall a b c, (a <+> b) <*> c == (a <*> c) <+> (b <*> c)
133+||| forall a b c, (a <+> b) <*> c == (a <*> c) <+> (b <*> c)
129class Ring a => RingWithUnity a where
134class Ring a => RingWithUnity a where
130 unity : a
135 unity : a
131
136
132class (VerifiedRing a, RingWithUnity a) => VerifiedRingWithUnity a where
137class (VerifiedRing a, RingWithUnity a) => VerifiedRingWithUnity a where
133− ringWithUnityIsUnityL : (l : a) -> l <*> unity = l
138+ total ringWithUnityIsUnityL : (l : a) -> l <*> unity = l
134− ringWithUnityIsUnityR : (r : a) -> unity <*> r = r
139+ total ringWithUnityIsUnityR : (r : a) -> unity <*> r = r
135
140
136−-- Sets equipped with a binary operation that is commutative, associative and
141+||| Sets equipped with a binary operation that is commutative, associative and
137−-- idempotent. Must satisfy the following laws:
142+||| idempotent. Must satisfy the following laws:
143+|||
138−-- Associativity of join:
144+||| + Associativity of join:
139−-- forall a b c, join a (join b c) == join (join a b) c
145+||| forall a b c, join a (join b c) == join (join a b) c
140−-- Commutativity of join:
146+||| + Commutativity of join:
141−-- forall a b, join a b == join b a
147+||| forall a b, join a b == join b a
142−-- Idempotency of join:
148+||| + Idempotency of join:
143−-- forall a, join a a == a
149+||| forall a, join a a == a
150+|||
144−-- Join semilattices capture the notion of sets with a "least upper bound".
151+||| Join semilattices capture the notion of sets with a "least upper bound".
145class JoinSemilattice a where
152class JoinSemilattice a where
146 join : a -> a -> a
153 join : a -> a -> a
147
154
148class JoinSemilattice a => VerifiedJoinSemilattice a where
155class JoinSemilattice a => VerifiedJoinSemilattice a where
149− joinSemilatticeJoinIsAssociative : (l, c, r : a) -> join l (join c r) = join (join l c) r
156+ total joinSemilatticeJoinIsAssociative : (l, c, r : a) -> join l (join c r) = join (join l c) r
150− joinSemilatticeJoinIsCommutative : (l, r : a) -> join l r = join r l
157+ total joinSemilatticeJoinIsCommutative : (l, r : a) -> join l r = join r l
151− joinSemilatticeJoinIsIdempotent : (e : a) -> join e e = e
158+ total joinSemilatticeJoinIsIdempotent : (e : a) -> join e e = e
152
159
153−-- Sets equipped with a binary operation that is commutative, associative and
160+||| Sets equipped with a binary operation that is commutative, associative and
154−-- idempotent. Must satisfy the following laws:
161+||| idempotent. Must satisfy the following laws:
162+|||
155−-- Associativity of meet:
163+||| + Associativity of meet:
156−-- forall a b c, meet a (meet b c) == meet (meet a b) c
164+||| forall a b c, meet a (meet b c) == meet (meet a b) c
157−-- Commutativity of meet:
165+||| + Commutativity of meet:
158−-- forall a b, meet a b == meet b a
166+||| forall a b, meet a b == meet b a
159−-- Idempotency of meet:
167+||| + Idempotency of meet:
160−-- forall a, meet a a == a
168+||| forall a, meet a a == a
169+|||
161−-- Meet semilattices capture the notion of sets with a "greatest lower bound".
170+||| Meet semilattices capture the notion of sets with a "greatest lower bound".
162class MeetSemilattice a where
171class MeetSemilattice a where
163 meet : a -> a -> a
172 meet : a -> a -> a
164
173
165class MeetSemilattice a => VerifiedMeetSemilattice a where
174class MeetSemilattice a => VerifiedMeetSemilattice a where
166− meetSemilatticeMeetIsAssociative : (l, c, r : a) -> meet l (meet c r) = meet (meet l c) r
175+ total meetSemilatticeMeetIsAssociative : (l, c, r : a) -> meet l (meet c r) = meet (meet l c) r
167− meetSemilatticeMeetIsCommutative : (l, r : a) -> meet l r = meet r l
176+ total meetSemilatticeMeetIsCommutative : (l, r : a) -> meet l r = meet r l
168− meetSemilatticeMeetIsIdempotent : (e : a) -> meet e e = e
177+ total meetSemilatticeMeetIsIdempotent : (e : a) -> meet e e = e
169
178
170−-- Sets equipped with a binary operation that is commutative, associative and
179+||| Sets equipped with a binary operation that is commutative, associative and
171−-- idempotent and supplied with a neutral element. Must satisfy the following
180+||| idempotent and supplied with a neutral element. Must satisfy the following
172−-- laws:
181+||| laws:
182+|||
173−-- Associativity of join:
183+||| + Associativity of join:
174−-- forall a b c, join a (join b c) == join (join a b) c
184+||| forall a b c, join a (join b c) == join (join a b) c
175−-- Commutativity of join:
185+||| + Commutativity of join:
176−-- forall a b, join a b == join b a
186+||| forall a b, join a b == join b a
177−-- Idempotency of join:
187+||| + Idempotency of join:
178−-- forall a, join a a == a
188+||| forall a, join a a == a
179−-- Bottom:
189+||| + Bottom:
180−-- forall a, join a bottom == bottom
190+||| forall a, join a bottom == bottom
191+|||
181−-- Join semilattices capture the notion of sets with a "least upper bound"
192+||| Join semilattices capture the notion of sets with a "least upper bound"
182−-- equipped with a "bottom" element.
193+||| equipped with a "bottom" element.
183class JoinSemilattice a => BoundedJoinSemilattice a where
194class JoinSemilattice a => BoundedJoinSemilattice a where
184 bottom : a
195 bottom : a
185
196
186class (VerifiedJoinSemilattice a, BoundedJoinSemilattice a) => VerifiedBoundedJoinSemilattice a where
197class (VerifiedJoinSemilattice a, BoundedJoinSemilattice a) => VerifiedBoundedJoinSemilattice a where
187− boundedJoinSemilatticeBottomIsBottom : (e : a) -> join e bottom = bottom
198+ total boundedJoinSemilatticeBottomIsBottom : (e : a) -> join e bottom = bottom
188
199
189−-- Sets equipped with a binary operation that is commutative, associative and
200+||| Sets equipped with a binary operation that is commutative, associative and
190−-- idempotent and supplied with a neutral element. Must satisfy the following
201+||| idempotent and supplied with a neutral element. Must satisfy the following
191−-- laws:
202+||| laws:
203+|||
192−-- Associativity of meet:
204+||| + Associativity of meet:
193−-- forall a b c, meet a (meet b c) == meet (meet a b) c
205+||| forall a b c, meet a (meet b c) == meet (meet a b) c
194−-- Commutativity of meet:
206+||| + Commutativity of meet:
195−-- forall a b, meet a b == meet b a
207+||| forall a b, meet a b == meet b a
196−-- Idempotency of meet:
208+||| + Idempotency of meet:
197−-- forall a, meet a a == a
209+||| forall a, meet a a == a
198−-- Top:
210+||| + Top:
199−-- forall a, meet a top == top
211+||| forall a, meet a top == top
212+|||
200−-- Meet semilattices capture the notion of sets with a "greatest lower bound"
213+||| Meet semilattices capture the notion of sets with a "greatest lower bound"
201−-- equipped with a "top" element.
214+||| equipped with a "top" element.
202class MeetSemilattice a => BoundedMeetSemilattice a where
215class MeetSemilattice a => BoundedMeetSemilattice a where
203 top : a
216 top : a
204
217
205class (VerifiedMeetSemilattice a, BoundedMeetSemilattice a) => VerifiedBoundedMeetSemilattice a where
218class (VerifiedMeetSemilattice a, BoundedMeetSemilattice a) => VerifiedBoundedMeetSemilattice a where
206− boundedMeetSemilatticeTopIsTop : (e : a) -> meet e top = top
219+ total boundedMeetSemilatticeTopIsTop : (e : a) -> meet e top = top
207
220
208−-- Sets equipped with two binary operations that are both commutative,
221+||| Sets equipped with two binary operations that are both commutative,
209−-- associative and idempotent, along with absorbtion laws for relating the two
222+||| associative and idempotent, along with absorbtion laws for relating the two
210−-- binary operations. Must satisfy the following:
223+||| binary operations. Must satisfy the following:
224+|||
211−-- Associativity of meet and join:
225+||| + Associativity of meet and join:
212−-- forall a b c, meet a (meet b c) == meet (meet a b) c
226+||| forall a b c, meet a (meet b c) == meet (meet a b) c
213−-- forall a b c, join a (join b c) == join (join a b) c
227+||| forall a b c, join a (join b c) == join (join a b) c
214−-- Commutativity of meet and join:
228+||| + Commutativity of meet and join:
215−-- forall a b, meet a b == meet b a
229+||| forall a b, meet a b == meet b a
216−-- forall a b, join a b == join b a
230+||| forall a b, join a b == join b a
217−-- Idempotency of meet and join:
231+||| + Idempotency of meet and join:
218−-- forall a, meet a a == a
232+||| forall a, meet a a == a
219−-- forall a, join a a == a
233+||| forall a, join a a == a
220−-- Absorbtion laws for meet and join:
234+||| + Absorbtion laws for meet and join:
221−-- forall a b, meet a (join a b) == a
235+||| forall a b, meet a (join a b) == a
222−-- forall a b, join a (meet a b) == a
236+||| forall a b, join a (meet a b) == a
223class (JoinSemilattice a, MeetSemilattice a) => Lattice a where { }
237class (JoinSemilattice a, MeetSemilattice a) => Lattice a where { }
224
238
225class (VerifiedJoinSemilattice a, VerifiedMeetSemilattice a) => VerifiedLattice a where
239class (VerifiedJoinSemilattice a, VerifiedMeetSemilattice a) => VerifiedLattice a where
226− latticeMeetAbsorbsJoin : (l, r : a) -> meet l (join l r) = l
240+ total latticeMeetAbsorbsJoin : (l, r : a) -> meet l (join l r) = l
227− latticeJoinAbsorbsMeet : (l, r : a) -> join l (meet l r) = l
241+ total latticeJoinAbsorbsMeet : (l, r : a) -> join l (meet l r) = l
228
242
229−-- Sets equipped with two binary operations that are both commutative,
243+||| Sets equipped with two binary operations that are both commutative,
230−-- associative and idempotent and supplied with neutral elements, along with
244+||| associative and idempotent and supplied with neutral elements, along with
231−-- absorbtion laws for relating the two binary operations. Must satisfy the
245+||| absorbtion laws for relating the two binary operations. Must satisfy the
232−-- following:
246+||| following:
247+|||
233−-- Associativity of meet and join:
248+||| + Associativity of meet and join:
234−-- forall a b c, meet a (meet b c) == meet (meet a b) c
249+||| forall a b c, meet a (meet b c) == meet (meet a b) c
235−-- forall a b c, join a (join b c) == join (join a b) c
250+||| forall a b c, join a (join b c) == join (join a b) c
236−-- Commutativity of meet and join:
251+||| + Commutativity of meet and join:
237−-- forall a b, meet a b == meet b a
252+||| forall a b, meet a b == meet b a
238−-- forall a b, join a b == join b a
253+||| forall a b, join a b == join b a
239−-- Idempotency of meet and join:
254+||| + Idempotency of meet and join:
240−-- forall a, meet a a == a
255+||| forall a, meet a a == a
241−-- forall a, join a a == a
256+||| forall a, join a a == a
242−-- Absorbtion laws for meet and join:
257+||| + Absorbtion laws for meet and join:
243−-- forall a b, meet a (join a b) == a
258+||| forall a b, meet a (join a b) == a
244−-- forall a b, join a (meet a b) == a
259+||| forall a b, join a (meet a b) == a
245−-- Neutral for meet and join:
260+||| + Neutral for meet and join:
246−-- forall a, meet a top == top
261+||| forall a, meet a top == top
247−-- forall a, join a bottom == bottom
262+||| forall a, join a bottom == bottom
248class (BoundedJoinSemilattice a, BoundedMeetSemilattice a) => BoundedLattice a where { }
263class (BoundedJoinSemilattice a, BoundedMeetSemilattice a) => BoundedLattice a where { }
249
264
250class (VerifiedBoundedJoinSemilattice a, VerifiedBoundedMeetSemilattice a, VerifiedLattice a) => VerifiedBoundedLattice a where { }
265class (VerifiedBoundedJoinSemilattice a, VerifiedBoundedMeetSemilattice a, VerifiedLattice a) => VerifiedBoundedLattice a where { }
libs/prelude/Prelude/Applicative.idr+5−2
@@ -38,8 +38,11 @@ class Applicative f => Alternative (f : Type -> Type) where
38 empty : f a
38 empty : f a
39 (<|>) : f a -> f a -> f a
39 (<|>) : f a -> f a -> f a
40
40
41+||| `guard a` is `pure ()` if `a` is `True` and `empty` if `a` is `False`
41guard : Alternative f => Bool -> f ()
42guard : Alternative f => Bool -> f ()
42guard a = if a then pure () else empty
43guard a = if a then pure () else empty
43
44
45+||| Conditionally execute an applicative expression
44−when : Applicative f => Bool -> f () -> f ()
46+when : Applicative f => Bool -> Lazy (f ()) -> f ()
45−when a f = if a then f else pure ()
47+when True f = Force f
48+when False f = pure ()
libs/prelude/Prelude/Bool.idr+18−5
@@ -2,6 +2,8 @@ module Prelude.Bool
2
2
3import Builtins
3import Builtins
4
4
5+import Prelude.Uninhabited
6+
5||| Boolean Data Type
7||| Boolean Data Type
6data Bool = False | True
8data Bool = False | True
7
9
@@ -13,22 +15,33 @@ boolElim : (b : Bool) -> (t : Lazy a) -> (e : Lazy a) -> a
13boolElim True t e = t
15boolElim True t e = t
14boolElim False t e = e
16boolElim False t e = e
15
17
16−||| Defines a predicate on Bool which guarantees that the value is true.
18+||| Ensure that some run-time Boolean test has been performed.
19+|||
20+||| This lifts a Boolean predicate to the type level. See the function `choose`
21+||| if you need to perform a Boolean test and convince the type checker of this
22+||| fact.
23+|||
24+||| If you find yourself using `so` for something other than primitive types,
25+||| it may be appropriate to define a type of evidence for the property that you
26+||| care about instead.
17data so : Bool -> Type where oh : so True
27data so : Bool -> Type where oh : so True
18
28
29+instance Uninhabited (so False) where
30+ uninhabited oh impossible
31+
19-- Syntactic sugar for boolean elimination.
32-- Syntactic sugar for boolean elimination.
20syntax if [test] then [t] else [e] = boolElim test (Delay t) (Delay e)
33syntax if [test] then [t] else [e] = boolElim test (Delay t) (Delay e)
21
34
22-- Boolean Operator Precedence
35-- Boolean Operator Precedence
23infixl 4 &&, ||
36infixl 4 &&, ||
24
37
25−||| Boolean OR
38+||| Boolean OR only evaluates the second argument if the first is `False`.
26−(||) : Bool -> Bool -> Bool
39+(||) : Bool -> Lazy Bool -> Bool
27(||) False x = x
40(||) False x = x
28(||) True _ = True
41(||) True _ = True
29
42
30−||| Boolean AND
43+||| Boolean AND only evaluates the second argument if the first is `True`.
31−(&&) : Bool -> Bool -> Bool
44+(&&) : Bool -> Lazy Bool -> Bool
32(&&) True x = x
45(&&) True x = x
33(&&) False _ = False
46(&&) False _ = False
34
47
libs/prelude/Prelude/Cast.idr+5−3
@@ -1,7 +1,11 @@
1module Prelude.Cast
1module Prelude.Cast
2
2
3+||| Type class for transforming a instance of a data type to another type.
3class Cast from to where
4class Cast from to where
5+ ||| Perform a cast operation.
6+ |||
7+ ||| @orig The original type.
4− cast : from -> to
8+ cast : (orig : from) -> to
5
9
6-- String casts
10-- String casts
7
11
@@ -45,5 +49,3 @@ instance Cast Integer String where
45
49
46instance Cast Char Int where
50instance Cast Char Int where
47 cast = prim__charToInt
51 cast = prim__charToInt
48−
49−
libs/prelude/Prelude/Classes.idr+8−2
@@ -244,14 +244,20 @@ instance Ord Bits64 where
244
244
245-- ------------------------------------------------------------- [ Bounded ]
245-- ------------------------------------------------------------- [ Bounded ]
246
246
247−class MinBound b where
247+class Ord b => MinBound b where
248 ||| The lower bound for the type
248 ||| The lower bound for the type
249 minBound : b
249 minBound : b
250
250
251−class MaxBound b where
251+class Ord b => MaxBound b where
252 ||| The upper bound for the type
252 ||| The upper bound for the type
253 maxBound : b
253 maxBound : b
254
254
255+instance MinBound Bits8 where
256+ minBound = 0x0
257+
258+instance MaxBound Bits8 where
259+ maxBound = 0xff
260+
255instance MinBound Bits16 where
261instance MinBound Bits16 where
256 minBound = 0x0
262 minBound = 0x0
257
263
libs/prelude/Prelude/Either.idr+4−4
@@ -39,9 +39,9 @@ choose False = Right oh
39||| @ f the action to take on Left
39||| @ f the action to take on Left
40||| @ g the action to take on Right
40||| @ g the action to take on Right
41||| @ e the sum to analyze
41||| @ e the sum to analyze
42−either : (f : a -> c) -> (g : b -> c) -> (e : Either a b) -> c
42+either : (f : Lazy (a -> c)) -> (g : Lazy (b -> c)) -> (e : Either a b) -> c
43−either l r (Left x) = l x
43+either l r (Left x) = (Force l) x
44−either l r (Right x) = r x
44+either l r (Right x) = (Force r) x
45
45
46||| Keep the payloads of all Left constructors in a list of Eithers
46||| Keep the payloads of all Left constructors in a list of Eithers
47lefts : List (Either a b) -> List a
47lefts : List (Either a b) -> List a
@@ -74,7 +74,7 @@ fromEither (Right r) = r
74
74
75||| Convert a Maybe to an Either by using a default value in case of Nothing
75||| Convert a Maybe to an Either by using a default value in case of Nothing
76||| @ e the default value
76||| @ e the default value
77−maybeToEither : (def : e) -> Maybe a -> Either e a
77+maybeToEither : (def : Lazy e) -> Maybe a -> Either e a
78maybeToEither def (Just j) = Right j
78maybeToEither def (Just j) = Right j
79maybeToEither def Nothing = Left def
79maybeToEither def Nothing = Left def
80
80
libs/prelude/Prelude/Fin.idr+18−2
@@ -6,7 +6,10 @@ import Prelude.Uninhabited
6
6
7%default total
7%default total
8
8
9−||| Numbers strictly less than some bound. The name comes from "finite sets"
9+||| Numbers strictly less than some bound. The name comes from "finite sets".
10+|||
11+||| It's probably not a good idea to use `Fin` for arithmetic, and they will be
12+||| exceedingly inefficient at run time.
10||| @ n the upper bound
13||| @ n the upper bound
11data Fin : (n : Nat) -> Type where
14data Fin : (n : Nat) -> Type where
12 fZ : Fin (S k)
15 fZ : Fin (S k)
@@ -24,16 +27,19 @@ instance Eq (Fin n) where
24 (==) (fS k) (fS k') = k == k'
27 (==) (fS k) (fS k') = k == k'
25 (==) _ _ = False
28 (==) _ _ = False
26
29
30+||| There are no elements of `Fin Z`
27FinZAbsurd : Fin Z -> _|_
31FinZAbsurd : Fin Z -> _|_
28FinZAbsurd fZ impossible
32FinZAbsurd fZ impossible
29
33
30FinZElim : Fin Z -> a
34FinZElim : Fin Z -> a
31FinZElim x = FalseElim (FinZAbsurd x)
35FinZElim x = FalseElim (FinZAbsurd x)
32
36
37+||| Convert a Fin to a Nat
33finToNat : Fin n -> Nat
38finToNat : Fin n -> Nat
34finToNat fZ = Z
39finToNat fZ = Z
35finToNat (fS k) = S (finToNat k)
40finToNat (fS k) = S (finToNat k)
36
41
42+||| `finToNat` is injective
37finToNatInjective : (fm : Fin k) -> (fn : Fin k) -> (finToNat fm) = (finToNat fn) -> fm = fn
43finToNatInjective : (fm : Fin k) -> (fn : Fin k) -> (finToNat fm) = (finToNat fn) -> fm = fn
38finToNatInjective fZ fZ refl = refl
44finToNatInjective fZ fZ refl = refl
39finToNatInjective (fS m) fZ refl impossible
45finToNatInjective (fS m) fZ refl impossible
@@ -44,6 +50,7 @@ finToNatInjective (fS m) (fS n) prf =
44instance Cast (Fin n) Nat where
50instance Cast (Fin n) Nat where
45 cast x = finToNat x
51 cast x = finToNat x
46
52
53+||| Convert a Fin to an Integer
47finToInteger : Fin n -> Integer
54finToInteger : Fin n -> Integer
48finToInteger fZ = 0
55finToInteger fZ = 0
49finToInteger (fS k) = 1 + finToInteger k
56finToInteger (fS k) = 1 + finToInteger k
@@ -85,7 +92,12 @@ last {n=S _} = fS last
85total fSinjective : {f : Fin n} -> {f' : Fin n} -> (fS f = fS f') -> f = f'
92total fSinjective : {f : Fin n} -> {f' : Fin n} -> (fS f = fS f') -> f = f'
86fSinjective refl = refl
93fSinjective refl = refl
87
94
88−
95+instance Ord (Fin n) where
96+ compare fZ fZ = EQ
97+ compare fZ (fS _) = LT
98+ compare (fS _) fZ = GT
99+ compare (fS x) (fS y) = compare x y
100+
89instance MinBound (Fin (S n)) where
101instance MinBound (Fin (S n)) where
90 minBound = fZ
102 minBound = fZ
91
103
@@ -123,9 +135,13 @@ natToFin _ _ = Nothing
123integerToFin : Integer -> (n : Nat) -> Maybe (Fin n)
135integerToFin : Integer -> (n : Nat) -> Maybe (Fin n)
124integerToFin x n = if x >= 0 then natToFin (cast x) n else Nothing
136integerToFin x n = if x >= 0 then natToFin (cast x) n else Nothing
125
137
138+||| Proof that some `Maybe` is actually `Just`
126data IsJust : Maybe a -> Type where
139data IsJust : Maybe a -> Type where
127 ItIsJust : IsJust {a} (Just x)
140 ItIsJust : IsJust {a} (Just x)
128
141
142+||| Allow overloading of Integer literals for Fin.
143+||| @ x the Integer that the user typed
144+||| @ prf an automatically-constructed proof that `x` is in bounds
129fromInteger : (x : Integer) ->
145fromInteger : (x : Integer) ->
130 {default ItIsJust
146 {default ItIsJust
131 prf : (IsJust (integerToFin x n))} ->
147 prf : (IsJust (integerToFin x n))} ->
libs/prelude/Prelude/Foldable.idr+27−11
@@ -10,31 +10,47 @@ import Prelude.Algebra
10
10
11class Foldable (t : Type -> Type) where
11class Foldable (t : Type -> Type) where
12 foldr : (elt -> acc -> acc) -> acc -> t elt -> acc
12 foldr : (elt -> acc -> acc) -> acc -> t elt -> acc
13+ foldl : Foldable t => (acc -> elt -> acc) -> acc -> t elt -> acc
14+ foldl f z t = foldr (flip (.) . flip f) id t z
13
15
14−foldl : Foldable t => (acc -> elt -> acc) -> acc -> t elt -> acc
16+||| Combine each element of a structure into a monoid
15−foldl f z t = foldr (flip (.) . flip f) id t z
16−
17concat : (Foldable t, Monoid a) => t a -> a
17concat : (Foldable t, Monoid a) => t a -> a
18concat = foldr (<+>) neutral
18concat = foldr (<+>) neutral
19
19
20+||| Combine into a monoid the collective results of applying a function
21+||| to each element of a structure
20concatMap : (Foldable t, Monoid m) => (a -> m) -> t a -> m
22concatMap : (Foldable t, Monoid m) => (a -> m) -> t a -> m
21concatMap f = foldr ((<+>) . f) neutral
23concatMap f = foldr ((<+>) . f) neutral
22
24
25+||| The conjunction of all elements of a structure containing
26+||| lazy boolean values. `and` short-circuits from left to right,
27+||| evaluating until either an element is `False` or no elements remain.
23−and : Foldable t => t Bool -> Bool
28+and : Foldable t => t (Lazy Bool) -> Bool
24−and = foldr (&&) True
29+and = foldl (&&) True
25−
30+
31+||| The disjunction of all elements of a structure containing
32+||| lazy boolean values. `or` short-circuits from left to right, evaluating
33+||| either until an element is `True` or no elements remain.
26−or : Foldable t => t Bool -> Bool
34+or : Foldable t => t (Lazy Bool) -> Bool
27−or = foldr (||) False
35+or = foldl (||) False
28−
36+
37+||| The disjunction of the collective results of applying a
38+||| predicate to all elements of a structure. `any` short-circuits
39+||| from left to right.
29any : Foldable t => (a -> Bool) -> t a -> Bool
40any : Foldable t => (a -> Bool) -> t a -> Bool
30−any p = foldr ((||) . p) False
41+any p = foldl (\x => \y => x || p y) False
31
42
43+||| The disjunction of the collective results of applying a
44+||| predicate to all elements of a structure. `all` short-circuits
45+||| from left to right.
32all : Foldable t => (a -> Bool) -> t a -> Bool
46all : Foldable t => (a -> Bool) -> t a -> Bool
33−all p = foldr ((&&) . p) True
47+all p = foldl (\x => \y => x && p y) True
34
48
49+||| Add together all the elements of a structure
35sum : (Foldable t, Num a) => t a -> a
50sum : (Foldable t, Num a) => t a -> a
36sum = foldr (+) 0
51sum = foldr (+) 0
37
52
53+||| Multiply together all elements of a structure
38product : (Foldable t, Num a) => t a -> a
54product : (Foldable t, Num a) => t a -> a
39product = foldr (*) 1
55product = foldr (*) 1
40
56
libs/prelude/Prelude/List.idr+157−32
@@ -12,11 +12,15 @@ import Prelude.Nat
12%access public
12%access public
13%default total
13%default total
14
14
15+infix 5 \\
15infixr 7 ::,++
16infixr 7 ::,++
16
17
18+||| Linked lists
17−%elim data List a
19+%elim data List a =
20+ ||| The empty list
18− = Nil
21+ Nil |
22+ ||| Cons cell
19− | (::) a (List a)
23+ (::) a (List a)
20
24
21-- Name hints for interactive editing
25-- Name hints for interactive editing
22%name List xs, ys, zs, ws
26%name List xs, ys, zs, ws
@@ -25,10 +29,12 @@ infixr 7 ::,++
25-- Syntactic tests
29-- Syntactic tests
26--------------------------------------------------------------------------------
30--------------------------------------------------------------------------------
27
31
32+||| Returns `True` iff the argument is empty
28isNil : List a -> Bool
33isNil : List a -> Bool
29isNil [] = True
34isNil [] = True
30isNil (x::xs) = False
35isNil (x::xs) = False
31
36
37+||| Returns `True` iff the argument is not empty
32isCons : List a -> Bool
38isCons : List a -> Bool
33isCons [] = False
39isCons [] = False
34isCons (x::xs) = True
40isCons (x::xs) = True
@@ -37,6 +43,9 @@ isCons (x::xs) = True
37-- Length
43-- Length
38--------------------------------------------------------------------------------
44--------------------------------------------------------------------------------
39
45
46+||| Compute the length of a list.
47+|||
48+||| Runs in linear time
40length : List a -> Nat
49length : List a -> Nat
41length [] = 0
50length [] = 0
42length (x::xs) = 1 + length xs
51length (x::xs) = 1 + length xs
@@ -45,49 +54,74 @@ length (x::xs) = 1 + length xs
45-- Indexing into lists
54-- Indexing into lists
46--------------------------------------------------------------------------------
55--------------------------------------------------------------------------------
47
56
57+||| Find a particular element of a list.
58+|||
59+||| @ ok a proof that the index is within bounds
48−index : (n : Nat) -> (l : List a) -> (lt n (length l) = True) -> a
60+index : (n : Nat) -> (l : List a) -> (ok : lt n (length l) = True) -> a
49index Z (x::xs) p = x
61index Z (x::xs) p = x
50index (S n) (x::xs) p = index n xs ?indexTailProof
62index (S n) (x::xs) p = index n xs ?indexTailProof
51index _ [] refl impossible
63index _ [] refl impossible
52
64
65+||| Attempt to find a particular element of a list.
66+|||
67+||| If the provided index is out of bounds, return Nothing.
53index' : (n : Nat) -> (l : List a) -> Maybe a
68index' : (n : Nat) -> (l : List a) -> Maybe a
54index' Z (x::xs) = Just x
69index' Z (x::xs) = Just x
55index' (S n) (x::xs) = index' n xs
70index' (S n) (x::xs) = index' n xs
56index' _ [] = Nothing
71index' _ [] = Nothing
57
72
73+||| Get the first element of a non-empty list
74+||| @ ok proof that the list is non-empty
58−head : (l : List a) -> (isCons l = True) -> a
75+head : (l : List a) -> (ok : isCons l = True) -> a
59head [] refl impossible
76head [] refl impossible
60head (x::xs) p = x
77head (x::xs) p = x
61
78
79+||| Attempt to get the first element of a list. If the list is empty, return
80+||| `Nothing`.
62head' : (l : List a) -> Maybe a
81head' : (l : List a) -> Maybe a
63head' [] = Nothing
82head' [] = Nothing
64head' (x::xs) = Just x
83head' (x::xs) = Just x
65
84
85+||| Get the tail of a non-empty list.
86+||| @ ok proof that the list is non-empty
66−tail : (l : List a) -> (isCons l = True) -> List a
87+tail : (l : List a) -> (ok : isCons l = True) -> List a
67tail [] refl impossible
88tail [] refl impossible
68tail (x::xs) p = xs
89tail (x::xs) p = xs
69
90
91+||| Attempt to get the tail of a list.
92+|||
93+||| If the list is empty, return `Nothing`.
70tail' : (l : List a) -> Maybe (List a)
94tail' : (l : List a) -> Maybe (List a)
71tail' [] = Nothing
95tail' [] = Nothing
72tail' (x::xs) = Just xs
96tail' (x::xs) = Just xs
73
97
98+||| Retrieve the last element of a non-empty list.
99+||| @ ok proof that the list is non-empty
74−last : (l : List a) -> (isCons l = True) -> a
100+last : (l : List a) -> (ok : isCons l = True) -> a
75last [] refl impossible
101last [] refl impossible
76last [x] p = x
102last [x] p = x
77last (x::y::ys) p = last (y::ys) refl
103last (x::y::ys) p = last (y::ys) refl
78
104
105+||| Attempt to retrieve the last element of a non-empty list.
106+|||
107+||| If the list is empty, return `Nothing`.
79last' : (l : List a) -> Maybe a
108last' : (l : List a) -> Maybe a
80last' [] = Nothing
109last' [] = Nothing
81−last' (x::xs) =
110+last' (x::xs) =
82 case xs of
111 case xs of
83 [] => Just x
112 [] => Just x
84 y :: ys => last' xs
113 y :: ys => last' xs
85
114
115+||| Return all but the last element of a non-empty list.
116+||| @ ok proof that the list is non-empty
86−init : (l : List a) -> (isCons l = True) -> List a
117+init : (l : List a) -> (ok : isCons l = True) -> List a
87init [] refl impossible
118init [] refl impossible
88init [x] p = []
119init [x] p = []
89init (x::y::ys) p = x :: init (y::ys) refl
120init (x::y::ys) p = x :: init (y::ys) refl
90
121
122+||| Attempt to Return all but the last element of a list.
123+|||
124+||| If the list is empty, return `Nothing`.
91init' : (l : List a) -> Maybe (List a)
125init' : (l : List a) -> Maybe (List a)
92init' [] = Nothing
126init' [] = Nothing
93init' (x::xs) =
127init' (x::xs) =
@@ -103,21 +137,39 @@ init' (x::xs) =
103-- Sublists
137-- Sublists
104--------------------------------------------------------------------------------
138--------------------------------------------------------------------------------
105
139
140+||| Take the first `n` elements of `xs`
141+|||
142+||| If there are not enough elements, return the whole list.
143+||| @ n how many elements to take
144+||| @ xs the list to take them from
106−take : Nat -> List a -> List a
145+take : (n : Nat) -> (xs : List a) -> List a
107take Z xs = []
146take Z xs = []
108take (S n) [] = []
147take (S n) [] = []
109take (S n) (x::xs) = x :: take n xs
148take (S n) (x::xs) = x :: take n xs
110
149
150+||| Drop the first `n` elements of `xs`
151+|||
152+||| If there are not enough elements, return the empty list.
153+||| @ n how many elements to drop
154+||| @ xs the list to drop them from
111−drop : Nat -> List a -> List a
155+drop : (n : Nat) -> (xs : List a) -> List a
112drop Z xs = xs
156drop Z xs = xs
113drop (S n) [] = []
157drop (S n) [] = []
114drop (S n) (x::xs) = drop n xs
158drop (S n) (x::xs) = drop n xs
115
159
160+||| Take the longest prefix of a list such that all elements satsify some
161+||| Boolean predicate.
162+|||
163+||| @ p the predicate
116−takeWhile : (a -> Bool) -> List a -> List a
164+takeWhile : (p : a -> Bool) -> List a -> List a
117takeWhile p [] = []
165takeWhile p [] = []
118takeWhile p (x::xs) = if p x then x :: takeWhile p xs else []
166takeWhile p (x::xs) = if p x then x :: takeWhile p xs else []
119
167
168+||| Remove the longest prefix of a list such that all removed elements satsify some
169+||| Boolean predicate.
170+|||
171+||| @ p the predicate
120−dropWhile : (a -> Bool) -> List a -> List a
172+dropWhile : (p : a -> Bool) -> List a -> List a
121dropWhile p [] = []
173dropWhile p [] = []
122dropWhile p (x::xs) = if p x then dropWhile p xs else x::xs
174dropWhile p (x::xs) = if p x then dropWhile p xs else x::xs
123
175
@@ -125,24 +177,29 @@ dropWhile p (x::xs) = if p x then dropWhile p xs else x::xs
125-- Misc.
177-- Misc.
126--------------------------------------------------------------------------------
178--------------------------------------------------------------------------------
127
179
180+||| Simply-typed recursion operator for lists.
181+|||
182+||| @ nil what to return at the end of the list
183+||| @ cons what to do at each step of recursion
184+||| @ xs the list to recurse over
128−list : a -> (a -> List a -> a) -> List a -> a
185+list : (nil : Lazy b) -> (cons : Lazy (a -> List a -> b)) -> (xs : List a) -> b
129list nil cons [] = nil
186list nil cons [] = nil
130−list nil cons (x::xs) = cons x xs
187+list nil cons (x::xs) = (Force cons) x xs
131
188
132--------------------------------------------------------------------------------
189--------------------------------------------------------------------------------
133-- Building (bigger) lists
190-- Building (bigger) lists
134--------------------------------------------------------------------------------
191--------------------------------------------------------------------------------
135
192
193+||| Append two lists
136(++) : List a -> List a -> List a
194(++) : List a -> List a -> List a
137−(++) [] right = right
195+(++) [] right = right
138(++) (x::xs) right = x :: (xs ++ right)
196(++) (x::xs) right = x :: (xs ++ right)
139
197
140−partial
198+||| Construct a list with `n` copies of `x`
141−repeat : a -> List a
199+||| @ n how many copies
142−repeat x = x :: lazy (repeat x)
200+||| @ x the element to replicate
143−
144−replicate : Nat -> a -> List a
201+replicate : (n : Nat) -> (x : a) -> List a
145−replicate Z x = []
202+replicate Z x = []
146replicate (S n) x = x :: replicate n x
203replicate (S n) x = x :: replicate n x
147
204
148--------------------------------------------------------------------------------
205--------------------------------------------------------------------------------
@@ -187,15 +244,27 @@ instance Functor List where
187-- Zips and unzips
244-- Zips and unzips
188--------------------------------------------------------------------------------
245--------------------------------------------------------------------------------
189
246
247+||| Combine two lists of the same length elementwise using some function.
248+||| @ f the function to combine elements with
249+||| @ l the first list
250+||| @ r the second list
251+||| @ ok a proof that the lengths of the inputs are equal
190zipWith : (f : a -> b -> c) -> (l : List a) -> (r : List b) ->
252zipWith : (f : a -> b -> c) -> (l : List a) -> (r : List b) ->
191− (length l = length r) -> List c
253+ (ok : length l = length r) -> List c
192zipWith f [] (y::ys) refl impossible
254zipWith f [] (y::ys) refl impossible
193zipWith f (x::xs) [] refl impossible
255zipWith f (x::xs) [] refl impossible
194zipWith f [] [] p = []
256zipWith f [] [] p = []
195zipWith f (x::xs) (y::ys) p = f x y :: (zipWith f xs ys ?zipWithTailProof)
257zipWith f (x::xs) (y::ys) p = f x y :: (zipWith f xs ys ?zipWithTailProof)
196
258
259+||| Combine three lists of the same length elementwise using some function.
260+||| @ f the function to combine elements with
261+||| @ x the first list
262+||| @ y the second list
263+||| @ z the third list
264+||| @ ok a proof that the lengths of the first two inputs are equal
265+||| @ ok' a proof that the lengths of the second and third inputs are equal
197zipWith3 : (f : a -> b -> c -> d) -> (x : List a) -> (y : List b) ->
266zipWith3 : (f : a -> b -> c -> d) -> (x : List a) -> (y : List b) ->
198− (z : List c) -> (length x = length y) -> (length y = length z) -> List d
267+ (z : List c) -> (ok : length x = length y) -> (ok' : length y = length z) -> List d
199zipWith3 f _ [] (z::zs) p refl impossible
268zipWith3 f _ [] (z::zs) p refl impossible
200zipWith3 f _ (y::ys) [] p refl impossible
269zipWith3 f _ (y::ys) [] p refl impossible
201zipWith3 f [] (y::ys) _ refl q impossible
270zipWith3 f [] (y::ys) _ refl q impossible
@@ -204,18 +273,22 @@ zipWith3 f [] [] [] p q = []
204zipWith3 f (x::xs) (y::ys) (z::zs) p q =
273zipWith3 f (x::xs) (y::ys) (z::zs) p q =
205 f x y z :: (zipWith3 f xs ys zs ?zipWith3TailProof ?zipWith3TailProof')
274 f x y z :: (zipWith3 f xs ys zs ?zipWith3TailProof ?zipWith3TailProof')
206
275
276+||| Combine two lists elementwise into pairs
207zip : (l : List a) -> (r : List b) -> (length l = length r) -> List (a, b)
277zip : (l : List a) -> (r : List b) -> (length l = length r) -> List (a, b)
208zip = zipWith (\x => \y => (x, y))
278zip = zipWith (\x => \y => (x, y))
209
279
280+||| Combine three lists elementwise into tuples
210zip3 : (x : List a) -> (y : List b) -> (z : List c) -> (length x = length y) ->
281zip3 : (x : List a) -> (y : List b) -> (z : List c) -> (length x = length y) ->
211 (length y = length z) -> List (a, b, c)
282 (length y = length z) -> List (a, b, c)
212zip3 = zipWith3 (\x => \y => \z => (x, y, z))
283zip3 = zipWith3 (\x => \y => \z => (x, y, z))
213
284
285+||| Split a list of pairs into two lists
214unzip : List (a, b) -> (List a, List b)
286unzip : List (a, b) -> (List a, List b)
215unzip [] = ([], [])
287unzip [] = ([], [])
216unzip ((l, r)::xs) with (unzip xs)
288unzip ((l, r)::xs) with (unzip xs)
217 | (lefts, rights) = (l::lefts, r::rights)
289 | (lefts, rights) = (l::lefts, r::rights)
218
290
291+||| Split a list of triples into three lists
219unzip3 : List (a, b, c) -> (List a, List b, List c)
292unzip3 : List (a, b, c) -> (List a, List b, List c)
220unzip3 [] = ([], [], [])
293unzip3 [] = ([], [], [])
221unzip3 ((l, c, r)::xs) with (unzip3 xs)
294unzip3 ((l, c, r)::xs) with (unzip3 xs)
@@ -225,6 +298,8 @@ unzip3 ((l, c, r)::xs) with (unzip3 xs)
225-- Maps
298-- Maps
226--------------------------------------------------------------------------------
299--------------------------------------------------------------------------------
227
300
301+||| Apply a partial function to the elements of a list, keeping the ones at which
302+||| it is defined.
228mapMaybe : (a -> Maybe b) -> List a -> List b
303mapMaybe : (a -> Maybe b) -> List a -> List b
229mapMaybe f [] = []
304mapMaybe f [] = []
230mapMaybe f (x::xs) =
305mapMaybe f (x::xs) =
@@ -236,6 +311,7 @@ mapMaybe f (x::xs) =
236-- Folds
311-- Folds
237--------------------------------------------------------------------------------
312--------------------------------------------------------------------------------
238
313
314+||| A tail recursive right fold on Lists.
239total foldrImpl : (t -> acc -> acc) -> acc -> (acc -> acc) -> List t -> acc
315total foldrImpl : (t -> acc -> acc) -> acc -> (acc -> acc) -> List t -> acc
240foldrImpl f e go [] = go e
316foldrImpl f e go [] = go e
241foldrImpl f e go (x::xs) = foldrImpl f e (go . (f x)) xs
317foldrImpl f e go (x::xs) = foldrImpl f e (go . (f x)) xs
@@ -247,6 +323,7 @@ instance Foldable List where
247-- Special folds
323-- Special folds
248--------------------------------------------------------------------------------
324--------------------------------------------------------------------------------
249
325
326+||| Convert any Foldable structure to a list.
250toList : Foldable t => t a -> List a
327toList : Foldable t => t a -> List a
251toList = foldr (::) []
328toList = foldr (::) []
252
329
@@ -254,6 +331,7 @@ toList = foldr (::) []
254-- Transformations
331-- Transformations
255--------------------------------------------------------------------------------
332--------------------------------------------------------------------------------
256
333
334+||| Return the elements of a list in reverse order.
257reverse : List a -> List a
335reverse : List a -> List a
258reverse = reverse' []
336reverse = reverse' []
259 where
337 where
@@ -261,6 +339,7 @@ reverse = reverse' []
261 reverse' acc [] = acc
339 reverse' acc [] = acc
262 reverse' acc (x::xs) = reverse' (x::acc) xs
340 reverse' acc (x::xs) = reverse' (x::acc) xs
263
341
342+||| Insert some separator between the elements of a list.
264intersperse : a -> List a -> List a
343intersperse : a -> List a -> List a
265intersperse sep [] = []
344intersperse sep [] = []
266intersperse sep (x::xs) = x :: intersperse' sep xs
345intersperse sep (x::xs) = x :: intersperse' sep xs
@@ -274,13 +353,13 @@ intercalate sep l = concat $ intersperse sep l
274
353
275||| Transposes rows and columns of a list of lists.
354||| Transposes rows and columns of a list of lists.
276|||
355|||
277−||| > transpose [[1, 2], [3, 4]] = [[1, 3], [2, 4]]
356+||| > transpose [[1, 2], [3, 4]] = [[1, 3], [2, 4]]
278|||
357|||
279||| This also works for non square scenarios, thus
358||| This also works for non square scenarios, thus
280||| involution does not always hold:
359||| involution does not always hold:
281|||
360|||
282−||| > transpose [[], [1, 2]] = [[1], [2]]
361+||| > transpose [[], [1, 2]] = [[1], [2]]
283−||| > transpose (transpose [[], [1, 2]]) = [[1, 2]]
362+||| > transpose (transpose [[], [1, 2]]) = [[1, 2]]
284|||
363|||
285||| TODO: Solution which satisfies the totality checker?
364||| TODO: Solution which satisfies the totality checker?
286%assert_total
365%assert_total
@@ -293,6 +372,7 @@ transpose ((x::xs) :: xss) = (x :: (mapMaybe head' xss)) :: (transpose (xs :: (m
293-- Membership tests
372-- Membership tests
294--------------------------------------------------------------------------------
373--------------------------------------------------------------------------------
295
374
375+||| Check if something is a member of a list using a custom comparison.
296elemBy : (a -> a -> Bool) -> a -> List a -> Bool
376elemBy : (a -> a -> Bool) -> a -> List a -> Bool
297elemBy p e [] = False
377elemBy p e [] = False
298elemBy p e (x::xs) =
378elemBy p e (x::xs) =
@@ -301,9 +381,11 @@ elemBy p e (x::xs) =
301 else
381 else
302 elemBy p e xs
382 elemBy p e xs
303
383
384+||| Check if something is a member of a list using the default Boolean equality.
304elem : Eq a => a -> List a -> Bool
385elem : Eq a => a -> List a -> Bool
305elem = elemBy (==)
386elem = elemBy (==)
306
387
388+||| Find associated information in a list using a custom comparison.
307lookupBy : (a -> a -> Bool) -> a -> List (a, b) -> Maybe b
389lookupBy : (a -> a -> Bool) -> a -> List (a, b) -> Maybe b
308lookupBy p e [] = Nothing
390lookupBy p e [] = Nothing
309lookupBy p e (x::xs) =
391lookupBy p e (x::xs) =
@@ -313,9 +395,12 @@ lookupBy p e (x::xs) =
313 else
395 else
314 lookupBy p e xs
396 lookupBy p e xs
315
397
398+||| Find associated information in a list using Boolean equality.
316lookup : Eq a => a -> List (a, b) -> Maybe b
399lookup : Eq a => a -> List (a, b) -> Maybe b
317lookup = lookupBy (==)
400lookup = lookupBy (==)
318
401
402+||| Check if any elements of the first list are found in the second, using
403+||| a custom comparison.
319hasAnyBy : (a -> a -> Bool) -> List a -> List a -> Bool
404hasAnyBy : (a -> a -> Bool) -> List a -> List a -> Bool
320hasAnyBy p elems [] = False
405hasAnyBy p elems [] = False
321hasAnyBy p elems (x::xs) =
406hasAnyBy p elems (x::xs) =
@@ -324,6 +409,8 @@ hasAnyBy p elems (x::xs) =
324 else
409 else
325 hasAnyBy p elems xs
410 hasAnyBy p elems xs
326
411
412+||| Check if any elements of the first list are found in the second, using
413+||| Boolean equality.
327hasAny : Eq a => List a -> List a -> Bool
414hasAny : Eq a => List a -> List a -> Bool
328hasAny = hasAnyBy (==)
415hasAny = hasAnyBy (==)
329
416
@@ -331,6 +418,7 @@ hasAny = hasAnyBy (==)
331-- Searching with a predicate
418-- Searching with a predicate
332--------------------------------------------------------------------------------
419--------------------------------------------------------------------------------
333
420
421+||| Find the first element of a list that satisfies a predicate, or `Nothing` if none do.
334find : (a -> Bool) -> List a -> Maybe a
422find : (a -> Bool) -> List a -> Maybe a
335find p [] = Nothing
423find p [] = Nothing
336find p (x::xs) =
424find p (x::xs) =
@@ -339,6 +427,8 @@ find p (x::xs) =
339 else
427 else
340 find p xs
428 find p xs
341
429
430+||| Find the index of the first element of a list that satisfies a predicate, or
431+||| `Nothing` if none do.
342findIndex : (a -> Bool) -> List a -> Maybe Nat
432findIndex : (a -> Bool) -> List a -> Maybe Nat
343findIndex = findIndex' Z
433findIndex = findIndex' Z
344 where
434 where
@@ -350,6 +440,7 @@ findIndex = findIndex' Z
350 else
440 else
351 findIndex' (S cnt) p xs
441 findIndex' (S cnt) p xs
352
442
443+||| Find the indices of all elements that satisfy some predicate.
353findIndices : (a -> Bool) -> List a -> List Nat
444findIndices : (a -> Bool) -> List a -> List Nat
354findIndices = findIndices' Z
445findIndices = findIndices' Z
355 where
446 where
@@ -399,10 +490,28 @@ nubBy = nubBy' []
399nub : Eq a => List a -> List a
490nub : Eq a => List a -> List a
400nub = nubBy (==)
491nub = nubBy (==)
401
492
493+deleteBy : (a -> a -> Bool) -> a -> List a -> List a
494+deleteBy _ _ [] = []
495+deleteBy eq x (y::ys) = if x `eq` y then ys else y :: deleteBy eq x ys
496+
497+delete : (Eq a) => a -> List a -> List a
498+delete = deleteBy (==)
499+
500+(\\) : (Eq a) => List a -> List a -> List a
501+(\\) = foldl (flip delete)
502+
503+unionBy : (a -> a -> Bool) -> List a -> List a -> List a
504+unionBy eq xs ys = xs ++ foldl (flip (deleteBy eq)) (nubBy eq ys) xs
505+
506+union : (Eq a) => List a -> List a -> List a
507+union = unionBy (==)
508+
402--------------------------------------------------------------------------------
509--------------------------------------------------------------------------------
403-- Splitting and breaking lists
510-- Splitting and breaking lists
404--------------------------------------------------------------------------------
511--------------------------------------------------------------------------------
405
512
513+||| Given a list and a predicate, returns a pair consisting of the longest
514+||| prefix of the list that satisfies a predicate and the rest of the list.
406span : (a -> Bool) -> List a -> (List a, List a)
515span : (a -> Bool) -> List a -> (List a, List a)
407span p [] = ([], [])
516span p [] = ([], [])
408span p (x::xs) =
517span p (x::xs) =
@@ -416,7 +525,6 @@ break : (a -> Bool) -> List a -> (List a, List a)
416break p = span (not . p)
525break p = span (not . p)
417
526
418split : (a -> Bool) -> List a -> List (List a)
527split : (a -> Bool) -> List a -> List (List a)
419−split p [] = []
420split p xs =
528split p xs =
421 case break p xs of
529 case break p xs of
422 (chunk, []) => [chunk]
530 (chunk, []) => [chunk]
@@ -439,6 +547,16 @@ partition p (x::xs) =
439 else
547 else
440 (lefts, x::rights)
548 (lefts, x::rights)
441
549
550+inits : List a -> List (List a)
551+inits xs = [] :: case xs of
552+ [] => []
553+ x :: xs' => map (x ::) (inits xs')
554+
555+tails : List a -> List (List a)
556+tails xs = xs :: case xs of
557+ [] => []
558+ _ :: xs' => tails xs'
559+
442--------------------------------------------------------------------------------
560--------------------------------------------------------------------------------
443-- Predicates
561-- Predicates
444--------------------------------------------------------------------------------
562--------------------------------------------------------------------------------
@@ -501,6 +619,7 @@ sort xs = let (x, y) = split xs in
501-- Conversions
619-- Conversions
502--------------------------------------------------------------------------------
620--------------------------------------------------------------------------------
503
621
622+||| Either return the head of a list, or `Nothing` if it is empty.
504listToMaybe : List a -> Maybe a
623listToMaybe : List a -> Maybe a
505listToMaybe [] = Nothing
624listToMaybe [] = Nothing
506listToMaybe (x::xs) = Just x
625listToMaybe (x::xs) = Just x
@@ -520,7 +639,7 @@ catMaybes (x::xs) =
520-- Properties
639-- Properties
521--------------------------------------------------------------------------------
640--------------------------------------------------------------------------------
522
641
523−-- append
642+||| The empty list is a right identity for append.
524appendNilRightNeutral : (l : List a) ->
643appendNilRightNeutral : (l : List a) ->
525 l ++ [] = l
644 l ++ [] = l
526appendNilRightNeutral [] = refl
645appendNilRightNeutral [] = refl
@@ -528,6 +647,7 @@ appendNilRightNeutral (x::xs) =
528 let inductiveHypothesis = appendNilRightNeutral xs in
647 let inductiveHypothesis = appendNilRightNeutral xs in
529 ?appendNilRightNeutralStepCase
648 ?appendNilRightNeutralStepCase
530
649
650+||| Appending lists is associative.
531appendAssociative : (l : List a) -> (c : List a) -> (r : List a) ->
651appendAssociative : (l : List a) -> (c : List a) -> (r : List a) ->
532 l ++ (c ++ r) = (l ++ c) ++ r
652 l ++ (c ++ r) = (l ++ c) ++ r
533appendAssociative [] c r = refl
653appendAssociative [] c r = refl
@@ -535,7 +655,8 @@ appendAssociative (x::xs) c r =
535 let inductiveHypothesis = appendAssociative xs c r in
655 let inductiveHypothesis = appendAssociative xs c r in
536 ?appendAssociativeStepCase
656 ?appendAssociativeStepCase
537
657
538−-- length
658+||| The length of two lists that are appended is the sum of the lengths
659+||| of the input lists.
539lengthAppend : (left : List a) -> (right : List a) ->
660lengthAppend : (left : List a) -> (right : List a) ->
540 length (left ++ right) = length left + length right
661 length (left ++ right) = length left + length right
541lengthAppend [] right = refl
662lengthAppend [] right = refl
@@ -543,7 +664,7 @@ lengthAppend (x::xs) right =
543 let inductiveHypothesis = lengthAppend xs right in
664 let inductiveHypothesis = lengthAppend xs right in
544 ?lengthAppendStepCase
665 ?lengthAppendStepCase
545
666
546−-- map
667+||| Mapping a function over a list doesn't change its length.
547mapPreservesLength : (f : a -> b) -> (l : List a) ->
668mapPreservesLength : (f : a -> b) -> (l : List a) ->
548 length (map f l) = length l
669 length (map f l) = length l
549mapPreservesLength f [] = refl
670mapPreservesLength f [] = refl
@@ -551,6 +672,8 @@ mapPreservesLength f (x::xs) =
551 let inductiveHypothesis = mapPreservesLength f xs in
672 let inductiveHypothesis = mapPreservesLength f xs in
552 ?mapPreservesLengthStepCase
673 ?mapPreservesLengthStepCase
553
674
675+||| Mapping a function over two lists and appending them is equivalent
676+||| to appending them and then mapping the function.
554mapDistributesOverAppend : (f : a -> b) -> (l : List a) -> (r : List a) ->
677mapDistributesOverAppend : (f : a -> b) -> (l : List a) -> (r : List a) ->
555 map f (l ++ r) = map f l ++ map f r
678 map f (l ++ r) = map f l ++ map f r
556mapDistributesOverAppend f [] r = refl
679mapDistributesOverAppend f [] r = refl
@@ -558,6 +681,7 @@ mapDistributesOverAppend f (x::xs) r =
558 let inductiveHypothesis = mapDistributesOverAppend f xs r in
681 let inductiveHypothesis = mapDistributesOverAppend f xs r in
559 ?mapDistributesOverAppendStepCase
682 ?mapDistributesOverAppendStepCase
560
683
684+||| Mapping two functions is the same as mapping their composition.
561mapFusion : (f : b -> c) -> (g : a -> b) -> (l : List a) ->
685mapFusion : (f : b -> c) -> (g : a -> b) -> (l : List a) ->
562 map f (map g l) = map (f . g) l
686 map f (map g l) = map (f . g) l
563mapFusion f g [] = refl
687mapFusion f g [] = refl
@@ -565,7 +689,7 @@ mapFusion f g (x::xs) =
565 let inductiveHypothesis = mapFusion f g xs in
689 let inductiveHypothesis = mapFusion f g xs in
566 ?mapFusionStepCase
690 ?mapFusionStepCase
567
691
568−-- hasAny
692+||| No list contains an element of the empty list by any predicate.
569hasAnyByNilFalse : (p : a -> a -> Bool) -> (l : List a) ->
693hasAnyByNilFalse : (p : a -> a -> Bool) -> (l : List a) ->
570 hasAnyBy p [] l = False
694 hasAnyBy p [] l = False
571hasAnyByNilFalse p [] = refl
695hasAnyByNilFalse p [] = refl
@@ -573,6 +697,7 @@ hasAnyByNilFalse p (x::xs) =
573 let inductiveHypothesis = hasAnyByNilFalse p xs in
697 let inductiveHypothesis = hasAnyByNilFalse p xs in
574 ?hasAnyByNilFalseStepCase
698 ?hasAnyByNilFalseStepCase
575
699
700+||| No list contains an element of the empty list.
576hasAnyNilFalse : Eq a => (l : List a) -> hasAny [] l = False
701hasAnyNilFalse : Eq a => (l : List a) -> hasAny [] l = False
577hasAnyNilFalse l = ?hasAnyNilFalseBody
702hasAnyNilFalse l = ?hasAnyNilFalseBody
578
703
libs/prelude/Prelude/Maybe.idr+10−3
@@ -28,25 +28,32 @@ isJust (Just j) = True
28-- Misc
28-- Misc
29--------------------------------------------------------------------------------
29--------------------------------------------------------------------------------
30
30
31−maybe : Lazy b -> (a -> b) -> Maybe a -> b
31+maybe : Lazy b -> Lazy (a -> b) -> Maybe a -> b
32maybe n j Nothing = n
32maybe n j Nothing = n
33−maybe n j (Just x) = j x
33+maybe n j (Just x) = (Force j) x
34
34
35+||| Convert a `Maybe a` value to an `a` value by providing a default `a` value
36+||| in the case that the `Maybe` value is `Nothing`.
35fromMaybe : (Lazy a) -> Maybe a -> a
37fromMaybe : (Lazy a) -> Maybe a -> a
36fromMaybe def Nothing = def
38fromMaybe def Nothing = def
37fromMaybe def (Just j) = j
39fromMaybe def (Just j) = j
38
40
41+||| Returns `Just` the given value if the conditional is `True`
42+||| and `Nothing` if the conditional is `False`.
39−toMaybe : Bool -> a -> Maybe a
43+toMaybe : Bool -> Lazy a -> Maybe a
40toMaybe True j = Just j
44toMaybe True j = Just j
41toMaybe False j = Nothing
45toMaybe False j = Nothing
42
46
43justInjective : {x : t} -> {y : t} -> (Just x = Just y) -> x = y
47justInjective : {x : t} -> {y : t} -> (Just x = Just y) -> x = y
44justInjective refl = refl
48justInjective refl = refl
45
49
50+||| Convert a `Maybe a` value to an `a` value, using `neutral` in the case
51+||| that the `Maybe` value is `Nothing`.
46lowerMaybe : Monoid a => Maybe a -> a
52lowerMaybe : Monoid a => Maybe a -> a
47lowerMaybe Nothing = neutral
53lowerMaybe Nothing = neutral
48lowerMaybe (Just x) = x
54lowerMaybe (Just x) = x
49
55
56+||| Returns `Nothing` when applied to `neutral`, and `Just` the value otherwise.
50raiseToMaybe : (Monoid a, Eq a) => a -> Maybe a
57raiseToMaybe : (Monoid a, Eq a) => a -> Maybe a
51raiseToMaybe x = if x == neutral then Nothing else Just x
58raiseToMaybe x = if x == neutral then Nothing else Just x
52
59
libs/prelude/Prelude/Pairs.idrnew file+42
@@ -0,0 +1,42 @@
1+module Prelude.Pairs
2+
3+import Builtins
4+
5+%access public
6+%default total
7+
8+using (a : Type, P : a -> Type)
9+
10+ ||| Dependent pair where the first field is erased.
11+ data Exists : (P : a -> Type) -> Type where
12+ evidence : .(x : a) -> (pf : P x) -> Exists P
13+
14+ ||| Dependent pair where the second field is erased.
15+ data Subset : (a : Type) -> (P : a -> Type) -> Type where
16+ element : (x : a) -> .(pf : P x) -> Subset a P
17+
18+ -- Monomorphic projections
19+
20+ namespace Exists
21+ getWitness : Exists {a} P -> a
22+ getWitness (evidence x pf) = x
23+
24+ getProof : (x : Exists {a} P) -> P (getWitness x)
25+ getProof (evidence x pf) = pf
26+
27+ namespace Subset
28+ getWitness : Subset a P -> a
29+ getWitness (element x pf) = x
30+
31+ getProof : (x : Subset a P) -> P (getWitness x)
32+ getProof (element x pf) = pf
33+
34+ namespace Sigma
35+ getWitness : Sigma a P -> a
36+ getWitness (x ** pf) = x
37+
38+ getProof : (x : Sigma a P) -> P (getWitness x)
39+ getProof (x ** pf) = pf
40+
41+ -- Polymorphic (class-based) projections have been removed
42+ -- because type-directed name disambiguation works better.
libs/prelude/Prelude/Stream.idr+30−1
@@ -31,8 +31,10 @@ take : (n : Nat) -> (xs : Stream a) -> Vect n a
31take Z _ = []
31take Z _ = []
32take (S n) (x :: xs) = x :: (take n xs)
32take (S n) (x :: xs) = x :: (take n xs)
33
33
34+||| Drop the first n elements from the stream
35+||| @ n how many elements to drop
34%assert_total
36%assert_total
35−drop : Nat -> Stream a -> Stream a
37+drop : (n : Nat) -> Stream a -> Stream a
36drop Z xs = xs
38drop Z xs = xs
37drop (S k) (x::xs) = drop k xs
39drop (S k) (x::xs) = drop k xs
38
40
@@ -67,4 +69,31 @@ unzip xs = (map fst xs, map snd xs)
67diag : Stream (Stream a) -> Stream a
69diag : Stream (Stream a) -> Stream a
68diag ((x::xs)::xss) = x :: diag (map tail xss)
70diag ((x::xs)::xss) = x :: diag (map tail xss)
69
71
72+||| Fold a Stream corecursively. Since there is no Nil, no initial value is used.
73+||| @ f the combining function
74+||| @ xs the Stream to fold up
75+foldr : (f : a -> Inf b -> b) -> (xs : Stream a) -> b
76+foldr f (x :: xs) = f x (foldr f xs)
77+
78+||| Produce a Stream of left folds of prefixes of the given Stream
79+||| @ f the combining function
80+||| @ acc the initial value
81+||| @ xs the Stream to process
82+scanl : (f : a -> b -> a) -> (acc : a) -> (xs : Stream b) -> Stream a
83+scanl f acc (x :: xs) = acc :: scanl f (f acc x) xs
84+
85+||| Produce a Stream of (corecursive) right folds of tails of the given Stream
86+||| @ f the combining function
87+||| @ xs the Stream to fold up
88+-- Reusing the head of the corecursion in the obvious way doesn’t productivity check
89+scanr : (f : a -> Inf b -> b) -> (xs : Stream a) -> Stream b
90+scanr f (x :: Delay xs) = f x (foldr f xs) :: scanr f xs
91+
92+||| Produce a Stream repeating a sequence
93+||| @ xs the sequence to repeat
94+cycle : (xs : Vect (S n) a) -> Stream a
95+cycle xs = cycle_ xs xs
96+ where cycle_ : Vect (S n) a -> Vect m a -> Stream a
97+ cycle_ (x :: xs) [] = x :: cycle_ (x :: xs) xs
98+ cycle_ xs (x :: ys) = x :: cycle_ xs ys
70
99
libs/prelude/Prelude/Strings.idr+111−1
@@ -8,29 +8,59 @@ import Prelude.Either
8import Prelude.Foldable
8import Prelude.Foldable
9
9
10||| Appends two strings together.
10||| Appends two strings together.
11+|||
12+||| Idris> "AB" ++ "C"
13+||| "ABC" : String
11(++) : String -> String -> String
14(++) : String -> String -> String
12(++) = prim__concat
15(++) = prim__concat
13
16
14||| Returns the first character in the specified string.
17||| Returns the first character in the specified string.
18+|||
19+||| Doesn't work for empty strings.
20+|||
21+||| Idris> strHead "A"
22+||| 'A' : Char
15partial
23partial
16strHead : String -> Char
24strHead : String -> Char
17strHead = prim__strHead
25strHead = prim__strHead
18
26
19||| Returns the characters specified after the head of the string.
27||| Returns the characters specified after the head of the string.
28+|||
29+||| Doesn't work for empty strings.
30+|||
31+||| Idris> strTail "AB"
32+||| "B" : String
33+||| Idris> strTail "A"
34+||| "" : String
20partial
35partial
21strTail : String -> String
36strTail : String -> String
22strTail = prim__strTail
37strTail = prim__strTail
23
38
24−||| Adds a character to the from of the specified string.
39+||| Adds a character to the front of the specified string.
40+|||
41+||| Idris> strCons 'A' "B"
42+||| "AB" : String
43+||| Idris> strCons 'A' ""
44+||| "A" : String
25strCons : Char -> String -> String
45strCons : Char -> String -> String
26strCons = prim__strCons
46strCons = prim__strCons
27
47
28||| Returns the nth character (starting from 0) of the specified string.
48||| Returns the nth character (starting from 0) of the specified string.
49+|||
50+||| Precondition: '0 < i < length s' for 'strIndex s i'.
51+|||
52+||| Idris> strIndex "AB" 1
53+||| 'B' : Char
29partial
54partial
30strIndex : String -> Int -> Char
55strIndex : String -> Int -> Char
31strIndex = prim__strIndex
56strIndex = prim__strIndex
32
57
33||| Reverses the elements within a String.
58||| Reverses the elements within a String.
59+|||
60+||| Idris> reverse "ABC"
61+||| "CBA" : String
62+||| Idris> reverse ""
63+||| "" : String
34reverse : String -> String
64reverse : String -> String
35reverse = prim__strRev
65reverse = prim__strRev
36
66
@@ -43,9 +73,11 @@ data StrM : String -> Type where
43 StrNil : StrM ""
73 StrNil : StrM ""
44 StrCons : (x : Char) -> (xs : String) -> StrM (strCons x xs)
74 StrCons : (x : Char) -> (xs : String) -> StrM (strCons x xs)
45
75
76+||| Version of 'strHead' that statically verifies that the string is not empty.
46strHead' : (x : String) -> so (not (x == "")) -> Char
77strHead' : (x : String) -> so (not (x == "")) -> Char
47strHead' x p = assert_total $ prim__strHead x
78strHead' x p = assert_total $ prim__strHead x
48
79
80+||| Version of 'strTail' that statically verifies that the string is not empty.
49strTail' : (x : String) -> so (not (x == "")) -> String
81strTail' : (x : String) -> so (not (x == "")) -> String
50strTail' x p = assert_total $ prim__strTail x
82strTail' x p = assert_total $ prim__strTail x
51
83
@@ -61,14 +93,23 @@ strM x with (choose (not (x == "")))
61-- a recursive argument, therefore the termination checker doesn't believe
93-- a recursive argument, therefore the termination checker doesn't believe
62-- the string is guaranteed smaller. It makes a good point.
94-- the string is guaranteed smaller. It makes a good point.
63
95
96+||| Turns a string into a list of characters.
97+|||
98+||| Idris> unpack "ABC"
99+||| ['A', 'B', 'C'] : List Char
64unpack : String -> List Char
100unpack : String -> List Char
65unpack s with (strM s)
101unpack s with (strM s)
66 unpack "" | StrNil = []
102 unpack "" | StrNil = []
67 unpack (strCons x xs) | (StrCons x xs) = x :: assert_total (unpack xs)
103 unpack (strCons x xs) | (StrCons x xs) = x :: assert_total (unpack xs)
68
104
105+||| Turns a Foldable of characters into a string.
69pack : (Foldable t) => t Char -> String
106pack : (Foldable t) => t Char -> String
70pack = foldr strCons ""
107pack = foldr strCons ""
71
108
109+||| Creates a string of a single character.
110+|||
111+||| Idris> singleton 'A'
112+||| "A" : String
72singleton : Char -> String
113singleton : Char -> String
73singleton c = strCons c ""
114singleton c = strCons c ""
74
115
@@ -87,6 +128,13 @@ instance Semigroup String where
87instance Monoid String where
128instance Monoid String where
88 neutral = ""
129 neutral = ""
89
130
131+||| Splits the string into a part before the predicate
132+||| returns False and the rest of the string.
133+|||
134+||| Idris> span (/= 'C') "ABCD"
135+||| ("AB", "CD") : (String, String)
136+||| Idris> span (/= 'C') "EFGH"
137+||| ("EFGH", "") : (String, String)
90span : (Char -> Bool) -> String -> (String, String)
138span : (Char -> Bool) -> String -> (String, String)
91span p xs with (strM xs)
139span p xs with (strM xs)
92 span p "" | StrNil = ("", "")
140 span p "" | StrNil = ("", "")
@@ -95,36 +143,76 @@ span p xs with (strM xs)
95 | (ys, zs) = (strCons x ys, zs)
143 | (ys, zs) = (strCons x ys, zs)
96 | False = ("", strCons x xs)
144 | False = ("", strCons x xs)
97
145
146+||| Splits the string into a part before the predicate
147+||| returns True and the rest of the string.
148+|||
149+||| Idris> break (== 'C') "ABCD"
150+||| ("AB", "CD") : (String, String)
151+||| Idris> break (== 'C') "EFGH"
152+||| ("EFGH", "") : (String, String)
98break : (Char -> Bool) -> String -> (String, String)
153break : (Char -> Bool) -> String -> (String, String)
99break p = span (not . p)
154break p = span (not . p)
100
155
156+||| Splits the string into parts with the predicate
157+||| indicating separator characters.
158+|||
159+||| Idris> split (== '.') ".AB.C..D"
160+||| ["", "AB", "C", "", "D"] : List String
101split : (Char -> Bool) -> String -> List String
161split : (Char -> Bool) -> String -> List String
102split p xs = map pack (split p (unpack xs))
162split p xs = map pack (split p (unpack xs))
103
163
164+||| Removes whitespace (determined with 'isSpace') from
165+||| the start of the string.
166+|||
167+||| Idris> ltrim " A\nB"
168+||| "A\nB" : String
169+||| Idris> ltrim " \nAB"
170+||| "AB" : String
104ltrim : String -> String
171ltrim : String -> String
105ltrim xs with (strM xs)
172ltrim xs with (strM xs)
106 ltrim "" | StrNil = ""
173 ltrim "" | StrNil = ""
107 ltrim (strCons x xs) | StrCons _ _
174 ltrim (strCons x xs) | StrCons _ _
108 = if (isSpace x) then assert_total (ltrim xs) else (strCons x xs)
175 = if (isSpace x) then assert_total (ltrim xs) else (strCons x xs)
109
176
177+||| Removes whitespace (determined with 'isSpace') from
178+||| the start and end of the string.
179+|||
180+||| Idris> trim " A\nB C "
181+||| "A\nB C" : String
110trim : String -> String
182trim : String -> String
111trim xs = ltrim (reverse (ltrim (reverse xs)))
183trim xs = ltrim (reverse (ltrim (reverse xs)))
112
184
185+||| Splits a character list into a list of whitespace separated character lists.
186+|||
187+||| Idris> words' (unpack " A B C D E ")
188+||| [['A'], ['B'], ['C'], ['D'], ['E']] : List (List Char)
113words' : List Char -> List (List Char)
189words' : List Char -> List (List Char)
114words' s = case dropWhile isSpace s of
190words' s = case dropWhile isSpace s of
115 [] => []
191 [] => []
116 s' => let (w, s'') = break isSpace s'
192 s' => let (w, s'') = break isSpace s'
117 in w :: words' (assert_smaller s s'')
193 in w :: words' (assert_smaller s s'')
118
194
195+||| Splits a string into a list of whitespace separated strings.
196+|||
197+||| Idris> words " A B C D E "
198+||| ["A", "B", "C", "D", "E"] : List String
119words : String -> List String
199words : String -> List String
120words s = map pack $ words' $ unpack s
200words s = map pack $ words' $ unpack s
121
201
202+||| Splits a character list into a list of newline separated character lists.
203+|||
204+||| Idris> lines' (unpack "\rA BC\nD\r\nE\n")
205+||| [['A', ' ', 'B', 'C'], ['D'], ['E']] : List (List Char)
122lines' : List Char -> List (List Char)
206lines' : List Char -> List (List Char)
123lines' s = case dropWhile isNL s of
207lines' s = case dropWhile isNL s of
124 [] => []
208 [] => []
125 s' => let (w, s'') = break isNL s'
209 s' => let (w, s'') = break isNL s'
126 in w :: lines' (assert_smaller s s'')
210 in w :: lines' (assert_smaller s s'')
127
211
212+||| Splits a string into a list of newline separated strings.
213+|||
214+||| Idris> lines "\rA BC\nD\r\nE\n"
215+||| ["A BC", "D", "E"] : List String
128lines : String -> List String
216lines : String -> List String
129lines s = map pack $ lines' $ unpack s
217lines s = map pack $ lines' $ unpack s
130
218
@@ -133,6 +221,10 @@ foldr1 : (a -> a -> a) -> List a -> a
133foldr1 f [x] = x
221foldr1 f [x] = x
134foldr1 f (x::xs) = f x (foldr1 f xs)
222foldr1 f (x::xs) = f x (foldr1 f xs)
135
223
224+||| Joins the character lists by spaces into a single character list.
225+|||
226+||| Idris> unwords' [['A'], ['B', 'C'], ['D'], ['E']]
227+||| ['A', ' ', 'B', 'C', ' ', 'D', ' ', 'E'] : List Char
136unwords' : List (List Char) -> List Char
228unwords' : List (List Char) -> List Char
137unwords' [] = []
229unwords' [] = []
138unwords' ws = assert_total (foldr1 addSpace ws)
230unwords' ws = assert_total (foldr1 addSpace ws)
@@ -140,18 +232,36 @@ unwords' ws = assert_total (foldr1 addSpace ws)
140 addSpace : List Char -> List Char -> List Char
232 addSpace : List Char -> List Char -> List Char
141 addSpace w s = w ++ (' ' :: s)
233 addSpace w s = w ++ (' ' :: s)
142
234
235+||| Joins the strings by spaces into a single string.
236+|||
237+||| Idris> unwords ["A", "BC", "D", "E"]
238+||| "A BC D E" : String
143unwords : List String -> String
239unwords : List String -> String
144unwords = pack . unwords' . map unpack
240unwords = pack . unwords' . map unpack
145
241
242+||| Returns the length of the string.
243+|||
244+||| Idris> length ""
245+||| 0 : Nat
246+||| Idris> length "ABC"
247+||| 3 : Nat
146length : String -> Nat
248length : String -> Nat
147length = fromInteger . prim__zextInt_BigInt . prim_lenString
249length = fromInteger . prim__zextInt_BigInt . prim_lenString
148
250
251+||| Lowercases all characters in the string.
252+|||
253+||| Idris> toLower "aBc12!"
254+||| "abc12!" : String
149toLower : String -> String
255toLower : String -> String
150toLower x with (strM x)
256toLower x with (strM x)
151 strToLower "" | StrNil = ""
257 strToLower "" | StrNil = ""
152 strToLower (strCons c cs) | (StrCons c cs) =
258 strToLower (strCons c cs) | (StrCons c cs) =
153 strCons (toLower c) (toLower (assert_smaller (strCons c cs) cs))
259 strCons (toLower c) (toLower (assert_smaller (strCons c cs) cs))
154
260
261+||| Uppercases all characters in the string.
262+|||
263+||| Idris> toLower "aBc12!"
264+||| "ABC12!" : String
155toUpper : String -> String
265toUpper : String -> String
156toUpper x with (strM x)
266toUpper x with (strM x)
157 strToLower "" | StrNil = ""
267 strToLower "" | StrNil = ""
libs/prelude/Prelude/Uninhabited.idr+3
@@ -8,6 +8,9 @@ class Uninhabited t where
8 ||| @ t the uninhabited type
8 ||| @ t the uninhabited type
9 total uninhabited : t -> _|_
9 total uninhabited : t -> _|_
10
10
11+instance Uninhabited _|_ where
12+ uninhabited a = a
13+
11||| Use an absurd assumption to discharge a proof obligation
14||| Use an absurd assumption to discharge a proof obligation
12||| @ t some empty type
15||| @ t some empty type
13||| @ a the goal type
16||| @ a the goal type
libs/prelude/Prelude/Vect.idr+43
@@ -68,6 +68,12 @@ index fZ (x::xs) = x
68index (fS k) (x::xs) = index k xs
68index (fS k) (x::xs) = index k xs
69index fZ [] impossible
69index fZ [] impossible
70
70
71+||| Insert an element at a particular index
72+insertAt : Fin (S n) -> a -> Vect n a -> Vect (S n) a
73+insertAt fZ y xs = y :: xs
74+insertAt (fS k) y (x::xs) = x :: insertAt k y xs
75+insertAt (fS k) y [] = absurd k
76+
71||| Construct a new vector consisting of all but the indicated element
77||| Construct a new vector consisting of all but the indicated element
72deleteAt : Fin (S n) -> Vect (S n) a -> Vect n a
78deleteAt : Fin (S n) -> Vect (S n) a -> Vect n a
73deleteAt fZ (x::xs) = xs
79deleteAt fZ (x::xs) = xs
@@ -254,6 +260,18 @@ concat : Vect m (Vect n a) -> Vect (m * n) a
254concat [] = []
260concat [] = []
255concat (v::vs) = v ++ concat vs
261concat (v::vs) = v ++ concat vs
256
262
263+||| Fold without seeding the accumulator
264+foldr1 : (t -> t -> t) -> Vect (S n) t -> t
265+foldr1 f (x::xs) = foldr f x xs
266+
267+--------------------------------------------------------------------------------
268+-- Scans
269+--------------------------------------------------------------------------------
270+
271+scanl : (b -> a -> b) -> b -> Vect n a -> Vect (S n) b
272+scanl f q [] = [q]
273+scanl f q (x::xs) = q :: scanl f (f q x) xs
274+
257--------------------------------------------------------------------------------
275--------------------------------------------------------------------------------
258-- Membership tests
276-- Membership tests
259--------------------------------------------------------------------------------
277--------------------------------------------------------------------------------
@@ -439,6 +457,31 @@ range : Vect n (Fin n)
439range {n=Z} = []
457range {n=Z} = []
440range {n=S _} = fZ :: map fS range
458range {n=S _} = fZ :: map fS range
441
459
460+||| Transpose a Vect of Vects, turning rows into columns and vice versa.
461+|||
462+||| As the types ensure rectangularity, this is an involution, unlike `Prelude.List.transpose`.
463+transpose : Vect m (Vect n a) -> Vect n (Vect m a)
464+transpose [] = replicate _ []
465+transpose (x :: xs) = zipWith (::) x (transpose xs)
466+
467+--------------------------------------------------------------------------------
468+-- Properties
469+--------------------------------------------------------------------------------
470+
471+vectConsCong : (x : a) -> (xs : Vect n a) -> (ys : Vect m a) -> (xs = ys) -> (x :: xs = x :: ys)
472+vectConsCong x xs xs refl = refl
473+
474+vectNilRightNeutral : (xs : Vect n a) -> xs ++ [] = xs
475+vectNilRightNeutral [] = refl
476+vectNilRightNeutral (x :: xs) =
477+ vectConsCong _ _ _ (vectNilRightNeutral xs)
478+
479+vectAppendAssociative : (x : Vect xLen a) -> (y : Vect yLen a) -> (z : Vect zLen a) -> x ++ (y ++ z) = (x ++ y) ++ z
480+vectAppendAssociative [] y z = refl
481+vectAppendAssociative (x :: xs) ys zs =
482+ vectConsCong _ _ _ (vectAppendAssociative xs ys zs)
483+
484+
442--------------------------------------------------------------------------------
485--------------------------------------------------------------------------------
443-- Proofs
486-- Proofs
444--------------------------------------------------------------------------------
487--------------------------------------------------------------------------------
libs/prelude/prelude.ipkg+1−1
@@ -8,7 +8,7 @@ modules = Builtins, Prelude, IO,
8 Prelude.Maybe, Prelude.Monad, Prelude.Applicative, Prelude.Either,
8 Prelude.Maybe, Prelude.Monad, Prelude.Applicative, Prelude.Either,
9 Prelude.Vect, Prelude.Strings, Prelude.Chars, Prelude.Functor,
9 Prelude.Vect, Prelude.Strings, Prelude.Chars, Prelude.Functor,
10 Prelude.Foldable, Prelude.Traversable, Prelude.Bits, Prelude.Stream,
10 Prelude.Foldable, Prelude.Traversable, Prelude.Bits, Prelude.Stream,
11− Prelude.Uninhabited,
11+ Prelude.Uninhabited, Prelude.Pairs,
12
12
13 Decidable.Equality
13 Decidable.Equality
14
14
main/Main.hs+10−61
@@ -24,6 +24,7 @@ import Idris.ElabDecls
24import Idris.Primitives
24import Idris.Primitives
25import Idris.Imports
25import Idris.Imports
26import Idris.Error
26import Idris.Error
27+import Idris.CmdOptions
27
28
28import IRTS.System ( getLibFlags, getIdrisLibDir, getIncFlags )
29import IRTS.System ( getLibFlags, getIdrisLibDir, getIncFlags )
29
30
@@ -36,8 +37,7 @@ import Paths_idris
36-- Main program reads command line options, parses the main program, and gets
37-- Main program reads command line options, parses the main program, and gets
37-- on with the REPL.
38-- on with the REPL.
38
39
39−main = do xs <- getArgs
40+main = do opts <- runArgParser
40− let opts = parseArgs xs
41 result <- runErrorT $ execStateT (runIdris opts) idrisInit
41 result <- runErrorT $ execStateT (runIdris opts) idrisInit
42 case result of
42 case result of
43 Left err -> putStrLn $ "Uncaught error: " ++ show err
43 Left err -> putStrLn $ "Uncaught error: " ++ show err
@@ -48,8 +48,6 @@ runIdris [Client c] = do setVerbose False
48 setQuiet True
48 setQuiet True
49 runIO $ runClient c
49 runIO $ runClient c
50runIdris opts = do
50runIdris opts = do
51− when (Ver `elem` opts) $ runIO showver
52− when (Usage `elem` opts) $ runIO usage
53 when (ShowIncs `elem` opts) $ runIO showIncs
51 when (ShowIncs `elem` opts) $ runIO showIncs
54 when (ShowLibs `elem` opts) $ runIO showLibs
52 when (ShowLibs `elem` opts) $ runIO showLibs
55 when (ShowLibdir `elem` opts) $ runIO showLibdir
53 when (ShowLibdir `elem` opts) $ runIO showLibdir
@@ -61,6 +59,14 @@ runIdris opts = do
61 [] -> return ()
59 [] -> return ()
62 fs -> do runIO $ mapM_ cleanPkg fs
60 fs -> do runIO $ mapM_ cleanPkg fs
63 runIO $ exitWith ExitSuccess
61 runIO $ exitWith ExitSuccess
62+ case opt getPkgMkDoc opts of -- IdrisDoc
63+ [] -> return ()
64+ fs -> do runIO $ mapM_ documentPkg fs
65+ runIO $ exitWith ExitSuccess
66+ case opt getPkgTest opts of
67+ [] -> return ()
68+ fs -> do runIO $ mapM_ testPkg fs
69+ runIO $ exitWith ExitSuccess
64 case opt getPkg opts of
70 case opt getPkg opts of
65 [] -> case opt getPkgREPL opts of
71 [] -> case opt getPkgREPL opts of
66 [] -> idrisMain opts
72 [] -> idrisMain opts
@@ -68,9 +74,6 @@ runIdris opts = do
68 _ -> ifail "Too many packages"
74 _ -> ifail "Too many packages"
69 fs -> runIO $ mapM_ (buildPkg (WarnOnly `elem` opts)) fs
75 fs -> runIO $ mapM_ (buildPkg (WarnOnly `elem` opts)) fs
70
76
71−usage = do putStrLn usagemsg
72− exitWith ExitSuccess
73−
74showver = do putStrLn $ "Idris version " ++ ver
77showver = do putStrLn $ "Idris version " ++ ver
75 exitWith ExitSuccess
78 exitWith ExitSuccess
76
79
@@ -85,57 +88,3 @@ showLibdir = do dir <- getIdrisLibDir
85showIncs = do incFlags <- getIncFlags
88showIncs = do incFlags <- getIncFlags
86 putStrLn incFlags
89 putStrLn incFlags
87 exitWith ExitSuccess
90 exitWith ExitSuccess
88−
89−usagemsghdr = "Idris version " ++ ver ++ ", (C) The Idris Community 2014"
90−
91−usagemsg = usagemsghdr ++ "\n" ++
92− map (\x -> '-') usagemsghdr ++ "\n" ++
93− "idris [OPTIONS] [FILE]\n\n" ++
94− "Common flags:\n" ++
95− "\t --install IPKG Install package\n" ++
96− "\t --clean IPKG Clean package\n" ++
97− "\t --build IPKG Build package\n" ++
98− "\t --exec EXPR Execute as idris\n" ++
99− "\t --libdir Display library directory\n" ++
100− "\t --link Display link directory\n" ++
101− "\t --include Display the includes directory\n" ++
102− "\t --nobanner Suppress the banner\n" ++
103− "\t --color, --colour Force coloured output\n" ++
104− "\t --nocolor, --nocolour Disable coloured output\n" ++
105− "\t --errorcontent Undocumented\n" ++
106− "\t --nocoverage Undocumented\n" ++
107− "\t -o --output FILE Specify output file\n" ++
108− "\t --check Undocumented\n" ++
109− "\t --total Require functions to be total by default\n" ++
110− "\t --partial Undocumented\n" ++
111− "\t --warnreach Warn about reachable but inaccessible arguments\n" ++
112− "\t --warnpartial Warn about undeclared partial functions.\n" ++
113− "\t --warn Undocumented\n" ++
114− "\t --typecase Undocumented\n" ++
115− "\t --typeintype Undocumented\n" ++
116− "\t --nobasepkgs Undocumented\n" ++
117− "\t --noprelude Undocumented\n" ++
118− "\t --nobuiltins Undocumented\n" ++
119− "\t -O --level LEVEL Undocumented\n" ++
120− "\t -i --idrispath DIR Add directory to the list of import paths\n" ++
121− "\t --package ITEM Undocumented\n" ++
122− "\t --ibcsubdir FILE Write IBC files into sub directory\n" ++
123− "\t --codegen TARGET Select code generator: C, Java, bytecode,\n" ++
124− "\t javascript, node, or llvm\n" ++
125− "\t --mvn Create a maven project (for Java codegen)\n" ++
126− "\t --cpu=CPU Select target CPU e.g. corei7 or cortex-m3\n" ++
127− "\t (for LLVM codegen)\n" ++
128− "\t --target=TRIPLE Select target triple (for llvm codegen)\n" ++
129− "\t -S --codegenonly Do no further compilation of code generator output\n" ++
130− "\t -c --compileonly Compile to object files rather than an executable\n" ++
131− "\t -X --extension EXT Turn on langage extension (TypeProviders or ErrorReflection)\n" ++
132− "\t --dumpdefuns Undocumented\n" ++
133− "\t --dumpcases Undocumented\n" ++
134− "\t --log LEVEL --loglevel Debugging log level\n" ++
135− "\t --ideslave Undocumented\n" ++
136− "\t --client Undocumented\n" ++
137− "\t -h --help Display help message\n" ++
138− "\t -v --version Print version information\n" ++
139− "\t -V --verbose Loud verbosity\n" ++
140− "\t -q --quiet Quiet verbosity\n"
141−
rts/Makefile+3−4
@@ -3,16 +3,15 @@ include ../config.mk
3OBJS = idris_rts.o idris_heap.o idris_gc.o idris_gmp.o idris_bitstring.o \
3OBJS = idris_rts.o idris_heap.o idris_gc.o idris_gmp.o idris_bitstring.o \
4 idris_opts.o idris_stats.o mini-gmp.o
4 idris_opts.o idris_stats.o mini-gmp.o
5HDRS = idris_rts.h idris_heap.h idris_gc.h idris_gmp.h idris_bitstring.h \
5HDRS = idris_rts.h idris_heap.h idris_gc.h idris_gmp.h idris_bitstring.h \
6− idris_opts.h idris_stats.h mini-gmp.h
6+ idris_opts.h idris_stats.h mini-gmp.h idris_stdfgn.h idris_net.h
7CFLAGS:=-fPIC $(CFLAGS)
7CFLAGS:=-fPIC $(CFLAGS)
8−CFLAGS += $(GMP_INCLUDE_DIR) $(GMP)
8+CFLAGS += $(GMP_INCLUDE_DIR) $(GMP) -DIDRIS_TARGET_OS="\"$(OS)\""
9+CFLAGS += -DIDRIS_TARGET_TRIPLE="\"$(MACHINE)\""
9
10
10ifeq ($(OS), windows)
11ifeq ($(OS), windows)
11 OBJS += windows/idris_stdfgn.o windows/idris_net.o
12 OBJS += windows/idris_stdfgn.o windows/idris_net.o
12− HDRS += windows/idris_stdfgn.h windows/idris_net.h
13else
13else
14 OBJS += idris_stdfgn.o idris_net.o
14 OBJS += idris_stdfgn.o idris_net.o
15− HDRS += idris_stdfgn.h idris_net.h
16endif
15endif
17
16
18LIBTARGET = libidris_rts.a
17LIBTARGET = libidris_rts.a
rts/idris_net.c+11−1
@@ -1,9 +1,19 @@
1// C-Side of the Idris network library
1// C-Side of the Idris network library
2// (C) Simon Fowler, 2014
2// (C) Simon Fowler, 2014
3// MIT Licensed. Have fun!
3// MIT Licensed. Have fun!
4−#include "idris_net.h"
4+#include <errno.h>
5+#include <netdb.h>
6+#include <stdbool.h>
7+#include <stdlib.h>
8+#include <stdio.h>
9+#include <string.h>
10+#include <sys/types.h>
11+#include <sys/socket.h>
12+#include <netinet/in.h>
5#include <arpa/inet.h>
13#include <arpa/inet.h>
6
14
15+#include "idris_net.h"
16+
7void* idrnet_malloc(int size) {
17void* idrnet_malloc(int size) {
8 return malloc(size);
18 return malloc(size);
9}
19}
rts/idris_net.h−10
@@ -1,16 +1,6 @@
1#ifndef IDRISNET_H
1#ifndef IDRISNET_H
2#define IDRISNET_H
2#define IDRISNET_H
3
3
4−#include <errno.h>
5−#include <netdb.h>
6−#include <stdbool.h>
7−#include <stdlib.h>
8−#include <stdio.h>
9−#include <string.h>
10−#include <sys/types.h>
11−#include <sys/socket.h>
12−#include <netinet/in.h>
13−
14typedef struct idrnet_recv_result {
4typedef struct idrnet_recv_result {
15 int result;
5 int result;
16 void* payload;
6 void* payload;
rts/idris_rts.c+13
@@ -506,6 +506,19 @@ VAL idris_strRev(VM* vm, VAL str) {
506 return cl;
506 return cl;
507}
507}
508
508
509+VAL idris_systemInfo(VM* vm, VAL index) {
510+ int i = GETINT(index);
511+ switch(i) {
512+ case 0: // backend
513+ return MKSTR(vm, "c");
514+ case 1:
515+ return MKSTR(vm, IDRIS_TARGET_OS);
516+ case 2:
517+ return MKSTR(vm, IDRIS_TARGET_TRIPLE);
518+ }
519+ return MKSTR(vm, "");
520+}
521+
509VAL MKBUFFERc(VM* vm, Buffer* buf) {
522VAL MKBUFFERc(VM* vm, Buffer* buf) {
510 Closure* cl = allocate(vm, sizeof(Closure) + sizeof *buf + buf->cap, 1);
523 Closure* cl = allocate(vm, sizeof(Closure) + sizeof *buf + buf->cap, 1);
511 SETTY(cl, BUFFER);
524 SETTY(cl, BUFFER);
rts/idris_rts.h+6
@@ -279,6 +279,12 @@ VAL idris_peekB64Native(VM* vm, VAL buf, VAL off);
279VAL idris_peekB64LE(VM* vm, VAL buf, VAL off);
279VAL idris_peekB64LE(VM* vm, VAL buf, VAL off);
280VAL idris_peekB64BE(VM* vm, VAL buf, VAL off);
280VAL idris_peekB64BE(VM* vm, VAL buf, VAL off);
281
281
282+// system infox
283+// used indices:
284+// 0 returns backend
285+// 1 returns OS
286+VAL idris_systemInfo(VM* vm, VAL index);
287+
282// Command line args
288// Command line args
283
289
284extern int __idris_argc;
290extern int __idris_argc;
rts/windows/idris_net.c+15−4
@@ -1,7 +1,7 @@
1// C-Side of the Idris network library
1// C-Side of the Idris network library
2// (C) Simon Fowler, 2014
2// (C) Simon Fowler, 2014
3// MIT Licensed. Have fun!
3// MIT Licensed. Have fun!
4−#include "idris_net.h"
4+#include "../idris_net.h"
5
5
6#include <errno.h>
6#include <errno.h>
7#include <stdbool.h>
7#include <stdbool.h>
@@ -11,6 +11,12 @@
11#include <Winsock2.h>
11#include <Winsock2.h>
12#include <Ws2tcpip.h>
12#include <Ws2tcpip.h>
13
13
14+
15+// inet_ntop isn't defined in the old mingw delivered with GHC,
16+// so put the prototype here, cribbed from a newer version of it
17+WINSOCK_API_LINKAGE LPCSTR WSAAPI InetNtopA(INT Family, PVOID pAddr,
18+ LPSTR pStringBuf, size_t StringBufSize);
19+
14static int socket_inited = 0;
20static int socket_inited = 0;
15static WSADATA wsa_data;
21static WSADATA wsa_data;
16
22
@@ -22,12 +28,17 @@ void idrnet_free(void* ptr) {
22 free(ptr);
28 free(ptr);
23}
29}
24
30
31+static void clean_sockets(void) {
32+ WSACleanup();
33+}
34+
25−static int check_init()
35+static int check_init(void)
26{
36{
27 if (!socket_inited) {
37 if (!socket_inited) {
28 int result = WSAStartup(MAKEWORD(2, 2), &wsa_data);
38 int result = WSAStartup(MAKEWORD(2, 2), &wsa_data);
29 if (result == NO_ERROR) {
39 if (result == NO_ERROR) {
30 socket_inited = 1;
40 socket_inited = 1;
41+ atexit(clean_sockets);
31 }
42 }
32 }
43 }
33 return socket_inited;
44 return socket_inited;
@@ -104,7 +115,7 @@ int idrnet_sockaddr_family(void* sockaddr) {
104char* idrnet_sockaddr_ipv4(void* sockaddr) {
115char* idrnet_sockaddr_ipv4(void* sockaddr) {
105 struct sockaddr_in* addr = (struct sockaddr_in*) sockaddr;
116 struct sockaddr_in* addr = (struct sockaddr_in*) sockaddr;
106 char* ip_addr = (char*) malloc(sizeof(char) * INET_ADDRSTRLEN);
117 char* ip_addr = (char*) malloc(sizeof(char) * INET_ADDRSTRLEN);
107− inet_ntop(AF_INET, &(addr->sin_addr), ip_addr, INET_ADDRSTRLEN);
118+ InetNtopA(AF_INET, &(addr->sin_addr), ip_addr, INET_ADDRSTRLEN);
108 return ip_addr;
119 return ip_addr;
109}
120}
110
121
@@ -139,7 +150,7 @@ int idrnet_send_buf(int sockfd, void* data, int len) {
139
150
140void* idrnet_recv(int sockfd, int len) {
151void* idrnet_recv(int sockfd, int len) {
141 if (!check_init()) {
152 if (!check_init()) {
142− return -1;
153+ return NULL;
143 }
154 }
144 idrnet_recv_result* res_struct =
155 idrnet_recv_result* res_struct =
145 (idrnet_recv_result*) malloc(sizeof(idrnet_recv_result));
156 (idrnet_recv_result*) malloc(sizeof(idrnet_recv_result));
rts/windows/idris_net.hdeleted−45
@@ -1,45 +0,0 @@
1−#ifndef IDRISNET_H
2−#define IDRISNET_H
3−
4−
5−typedef struct idrnet_recv_result {
6− int result;
7− void* payload;
8−} idrnet_recv_result;
9−
10−// Memory management functions
11−void* idrnet_malloc(int size);
12−void idrnet_free(void* ptr);
13−
14−// Gets value of errno
15−int idrnet_errno();
16−
17−// Bind
18−int idrnet_bind(int sockfd, int family, int socket_type, char* host, int port);
19−
20−// Connect
21−int idrnet_connect(int sockfd, int family, int socket_type, char* host, int port);
22−
23−// Accessor functions for struct_sockaddr
24−int idrnet_sockaddr_family(void* sockaddr);
25−char* idrnet_sockaddr_ipv4(void* sockaddr);
26−void* idrnet_create_sockaddr();
27−
28−// Accept
29−int idrnet_accept(int sockfd, void* sockaddr);
30−
31−// Send
32−int idrnet_send(int sockfd, char* data);
33−int idrnet_send_buf(int sockfd, void* data, int len);
34−
35−// Receive
36−// Creates a result structure containing result and payload
37−void* idrnet_recv(int sockfd, int len);
38−// Receives directly into a buffer
39−int idrnet_recv_buf(int sockfd, void* buf, int len);
40−
41−// Receive structure accessors
42−int idrnet_get_recv_res(void* res_struct);
43−void* idrnet_get_recv_payload(void* res_struct);
44−void idrnet_free_recv_struct(void* res_struct);
45−#endif
rts/windows/idris_stdfgn.c+13−1
@@ -1,7 +1,10 @@
1−#include "idris_stdfgn.h"
1+#include "../idris_stdfgn.h"
2#include "../idris_rts.h"
2#include "../idris_rts.h"
3+#include "../idris_gc.h"
4+
3#include <fcntl.h>
5#include <fcntl.h>
4#include <stdio.h>
6#include <stdio.h>
7+#include <time.h>
5
8
6extern char** environ;
9extern char** environ;
7
10
@@ -61,3 +64,12 @@ void* idris_stdin() {
61char* getEnvPair(int i) {
64char* getEnvPair(int i) {
62 return *(environ + i);
65 return *(environ + i);
63}
66}
67+
68+int idris_time() {
69+ time_t t = time(NULL);
70+ return (int)t;
71+}
72+
73+void idris_forceGC(void* vm) {
74+ idris_gc((VM*)vm);
75+}
rts/windows/idris_stdfgn.hdeleted−24
@@ -1,24 +0,0 @@
1−#ifndef _IDRISSTDFGN_H
2−#define _IDRISSTDFGN_H
3−
4−// A collection of useful standard functions to be used by the prelude.
5−
6−void putStr(char* str);
7−//char* readStr();
8−
9−void* fileOpen(char* f, char* mode);
10−void fileClose(void* h);
11−int fileEOF(void* h);
12−int fileError(void* h);
13−void fputStr(void*h, char* str);
14−
15−void* do_popen(const char* cmd, const char* mode);
16−int fpoll(void* h);
17−
18−int idris_eqPtr(void* x, void* y);
19−int isNull(void* ptr);
20−void* idris_stdin();
21−
22−char* getEnvPair(int i);
23−
24−#endif
src/IRTS/CodegenC.hs+5−4
@@ -62,7 +62,6 @@ codegenC' defs out exec incs objs libs flags dbg
62 hPutStr tmph cout
62 hPutStr tmph cout
63 hFlush tmph
63 hFlush tmph
64 hClose tmph
64 hClose tmph
65− let useclang = False
66 comp <- getCC
65 comp <- getCC
67 libFlags <- getLibFlags
66 libFlags <- getLibFlags
68 incFlags <- getIncFlags
67 incFlags <- getIncFlags
@@ -175,15 +174,15 @@ bcc i (CASE True r code def)
175 | length code < 4 = showCase i def code
174 | length code < 4 = showCase i def code
176 where
175 where
177 showCode :: Int -> [BC] -> String
176 showCode :: Int -> [BC] -> String
178− showCode i bc = "{\n" ++ indent i ++ concatMap (bcc (i + 1)) bc ++
177+ showCode i bc = "{\n" ++ concatMap (bcc (i + 1)) bc ++
179 indent i ++ "}\n"
178 indent i ++ "}\n"
180
179
181 showCase :: Int -> Maybe [BC] -> [(Int, [BC])] -> String
180 showCase :: Int -> Maybe [BC] -> [(Int, [BC])] -> String
182 showCase i Nothing [(t, c)] = showCode i c
181 showCase i Nothing [(t, c)] = showCode i c
183 showCase i (Just def) [] = showCode i def
182 showCase i (Just def) [] = showCode i def
184 showCase i def ((t, c) : cs)
183 showCase i def ((t, c) : cs)
185− = "if (CTAG(" ++ creg r ++ ") == " ++ show t ++ ") " ++ showCode i c
184+ = indent i ++ "if (CTAG(" ++ creg r ++ ") == " ++ show t ++ ") " ++ showCode i c
186− ++ "else " ++ showCase i def cs
185+ ++ indent i ++ "else " ++ showCase i def cs
187
186
188bcc i (CASE safe r code def)
187bcc i (CASE safe r code def)
189 = indent i ++ "switch(" ++ ctag safe ++ "(" ++ creg r ++ ")) {\n" ++
188 = indent i ++ "switch(" ++ ctag safe ++ "(" ++ creg r ++ ")) {\n" ++
@@ -494,6 +493,8 @@ doOp v (LChInt ITNative) args = v ++ creg (last args)
494doOp v (LChInt ITChar) args = doOp v (LChInt ITNative) args
493doOp v (LChInt ITChar) args = doOp v (LChInt ITNative) args
495doOp v (LIntCh ITNative) args = v ++ creg (last args)
494doOp v (LIntCh ITNative) args = v ++ creg (last args)
496doOp v (LIntCh ITChar) args = doOp v (LIntCh ITNative) args
495doOp v (LIntCh ITChar) args = doOp v (LIntCh ITNative) args
496+
497+doOp v LSystemInfo [x] = v ++ "idris_systemInfo(vm, " ++ creg x ++ ")"
497doOp v LNoOp args = v ++ creg (last args)
498doOp v LNoOp args = v ++ creg (last args)
498doOp _ op _ = "FAIL /* " ++ show op ++ " */"
499doOp _ op _ = "FAIL /* " ++ show op ++ " */"
499
500
src/IRTS/CodegenJavaScript.hs+598−42
@@ -17,6 +17,7 @@ import Data.Char
17import Numeric
17import Numeric
18import Data.List
18import Data.List
19import Data.Maybe
19import Data.Maybe
20+import Data.Word
20import System.IO
21import System.IO
21import System.Directory
22import System.Directory
22
23
@@ -53,6 +54,13 @@ data JSNum = JSInt Int
53 deriving Eq
54 deriving Eq
54
55
55
56
57+data JSWord = JSWord8 Word8
58+ | JSWord16 Word16
59+ | JSWord32 Word32
60+ | JSWord64 Word64
61+ deriving Eq
62+
63+
56data JSAnnotation = JSConstructor deriving Eq
64data JSAnnotation = JSConstructor deriving Eq
57
65
58
66
@@ -81,6 +89,7 @@ data JS = JSRaw String
81 | JSArray [JS]
89 | JSArray [JS]
82 | JSString String
90 | JSString String
83 | JSNum JSNum
91 | JSNum JSNum
92+ | JSWord JSWord
84 | JSAssign JS JS
93 | JSAssign JS JS
85 | JSAlloc String (Maybe JS)
94 | JSAlloc String (Maybe JS)
86 | JSIndex JS JS
95 | JSIndex JS JS
@@ -257,6 +266,13 @@ compileJS (JSWhile cond body) =
257 ++ compileJS body
266 ++ compileJS body
258 ++ "\n}"
267 ++ "\n}"
259
268
269+compileJS (JSWord word)
270+ | JSWord8 b <- word = "new Uint8Array([" ++ show b ++ "])"
271+ | JSWord16 b <- word = "new Uint16Array([" ++ show b ++ "])"
272+ | JSWord32 b <- word = "new Uint32Array([" ++ show b ++ "])"
273+ | JSWord64 b <- word = idrRTNamespace ++ "bigInt(\"" ++ show b ++ "\")"
274+
275+
260jsTailcall :: JS -> JS
276jsTailcall :: JS -> JS
261jsTailcall call =
277jsTailcall call =
262 jsCall (idrRTNamespace ++ "tailcall") [
278 jsCall (idrRTNamespace ++ "tailcall") [
@@ -280,6 +296,8 @@ jsInstanceOf = JSBinOp "instanceof"
280jsEq :: JS -> JS -> JS
296jsEq :: JS -> JS -> JS
281jsEq = JSBinOp "=="
297jsEq = JSBinOp "=="
282
298
299+jsNotEq :: JS -> JS -> JS
300+jsNotEq = JSBinOp "!="
283
301
284jsAnd :: JS -> JS -> JS
302jsAnd :: JS -> JS -> JS
285jsAnd = JSBinOp "&&"
303jsAnd = JSBinOp "&&"
@@ -327,6 +345,28 @@ jsLet name value body =
327jsError :: String -> JS
345jsError :: String -> JS
328jsError err = JSApp (JSFunction [] (JSError err)) []
346jsError err = JSApp (JSFunction [] (JSError err)) []
329
347
348+jsUnPackBits :: JS -> JS
349+jsUnPackBits js = JSIndex js $ JSNum (JSInt 0)
350+
351+
352+jsPackUBits8 :: JS -> JS
353+jsPackUBits8 js = JSNew "Uint8Array" [JSArray [js]]
354+
355+jsPackUBits16 :: JS -> JS
356+jsPackUBits16 js = JSNew "Uint16Array" [JSArray [js]]
357+
358+jsPackUBits32 :: JS -> JS
359+jsPackUBits32 js = JSNew "Uint32Array" [JSArray [js]]
360+
361+jsPackSBits8 :: JS -> JS
362+jsPackSBits8 js = JSNew "Int8Array" [JSArray [js]]
363+
364+jsPackSBits16 :: JS -> JS
365+jsPackSBits16 js = JSNew "Int16Array" [JSArray [js]]
366+
367+jsPackSBits32 :: JS -> JS
368+jsPackSBits32 js = JSNew "Int32Array" [JSArray [js]]
369+
330
370
331foldJS :: (JS -> a) -> (a -> a -> a) -> a -> JS -> a
371foldJS :: (JS -> a) -> (a -> a -> a) -> a -> JS -> a
332foldJS tr add acc js =
372foldJS tr add acc js =
@@ -702,21 +742,44 @@ removeIDs js =
702 JSReturn (JSApp (JSIdent fun) args)
742 JSReturn (JSApp (JSIdent fun) args)
703 )])
743 )])
704 | Just pos <- lookup fun ids
744 | Just pos <- lookup fun ids
705− , pos < length args = args !! pos
745+ , pos < length args = removeIDCall ids (args !! pos)
706
746
707 removeIDCall ids (JSNew _ [JSFunction [] (
747 removeIDCall ids (JSNew _ [JSFunction [] (
708 JSReturn (JSApp (JSIdent fun) args)
748 JSReturn (JSApp (JSIdent fun) args)
709 )])
749 )])
710 | Just pos <- lookup fun ids
750 | Just pos <- lookup fun ids
711− , pos < length args = args !! pos
751+ , pos < length args = removeIDCall ids (args !! pos)
712
752
713 removeIDCall ids js@(JSApp id@(JSIdent fun) args)
753 removeIDCall ids js@(JSApp id@(JSIdent fun) args)
714 | Just pos <- lookup fun ids
754 | Just pos <- lookup fun ids
715− , pos < length args = args !! pos
755+ , pos < length args = removeIDCall ids (args !! pos)
716
756
717 removeIDCall ids js = transformJS (removeIDCall ids) js
757 removeIDCall ids js = transformJS (removeIDCall ids) js
718
758
719
759
760+inlineFunction :: String -> [String] -> JS -> JS -> JS
761+inlineFunction fun args body js = inline' js
762+ where
763+ inline' :: JS -> JS
764+ inline' (JSApp (JSIdent name) vals)
765+ | name == fun =
766+ let (js, phs) = insertPlaceHolders args body in
767+ inline' $ foldr (uncurry jsSubst) js (zip phs vals)
768+
769+ inline' js = transformJS inline' js
770+
771+ insertPlaceHolders :: [String] -> JS -> (JS, [JS])
772+ insertPlaceHolders args body = insertPlaceHolders' args body []
773+ where
774+ insertPlaceHolders' :: [String] -> JS -> [JS] -> (JS, [JS])
775+ insertPlaceHolders' (a:as) body ph
776+ | (body', ph') <- insertPlaceHolders' as body ph =
777+ let phvar = JSIdent $ "__PH_" ++ show (length ph') in
778+ (jsSubst (JSIdent a) phvar body', phvar : ph')
779+
780+ insertPlaceHolders' [] body ph = (body, ph)
781+
782+
720inlineFunctions :: [JS] -> [JS]
783inlineFunctions :: [JS] -> [JS]
721inlineFunctions js =
784inlineFunctions js =
722 inlineHelper ([], js)
785 inlineHelper ([], js)
@@ -728,7 +791,7 @@ inlineFunctions js =
728 | Just new <- inlineAble (
791 | Just new <- inlineAble (
729 countAll fun front + countAll fun back
792 countAll fun front + countAll fun back
730 ) fun args body =
793 ) fun args body =
731− let f = map (inline fun args new) in
794+ let f = map (inlineFunction fun args new) in
732 inlineHelper (f front, f back)
795 inlineHelper (f front, f back)
733
796
734 inlineHelper (front, next:back) = inlineHelper (front ++ [next], back)
797 inlineHelper (front, next:back) = inlineHelper (front ++ [next], back)
@@ -745,29 +808,6 @@ inlineFunctions js =
745 inlineAble _ _ _ _ = Nothing
808 inlineAble _ _ _ _ = Nothing
746
809
747
810
748− inline :: String -> [String] -> JS -> JS -> JS
749− inline fun args body js = inline' js
750− where
751− inline' :: JS -> JS
752− inline' (JSApp (JSIdent name) vals)
753− | name == fun =
754− let (js, phs) = insertPlaceHolders args body in
755− inline' $ foldr (uncurry jsSubst) js (zip phs vals)
756−
757− inline' js = transformJS inline' js
758−
759− insertPlaceHolders :: [String] -> JS -> (JS, [JS])
760− insertPlaceHolders args body = insertPlaceHolders' args body []
761− where
762− insertPlaceHolders' :: [String] -> JS -> [JS] -> (JS, [JS])
763− insertPlaceHolders' (a:as) body ph
764− | (body', ph') <- insertPlaceHolders' as body ph =
765− let phvar = JSIdent $ "__PH_" ++ show (length ph') in
766− (jsSubst (JSIdent a) phvar body', phvar : ph')
767−
768− insertPlaceHolders' [] body ph = (body, ph)
769−
770−
771 nonRecur :: String -> JS -> Bool
811 nonRecur :: String -> JS -> Bool
772 nonRecur name body = countInvokations name body == 0
812 nonRecur name body = countInvokations name body == 0
773
813
@@ -1378,6 +1418,67 @@ evalCons js =
1378 match js = transformJS match js
1418 match js = transformJS match js
1379
1419
1380
1420
1421+elimConds :: [JS] -> [JS]
1422+elimConds js =
1423+ let (conds, rest) = partition isCond js in
1424+ foldl' eraseCond rest conds
1425+ where
1426+ isCond :: JS -> Bool
1427+ isCond (JSAlloc
1428+ fun (Just (JSFunction args (JSCond
1429+ [ (JSBinOp "==" (JSNum (JSInt tag)) (JSProj (JSIdent _) "tag"), JSReturn t)
1430+ , (JSNoop, JSReturn f)
1431+ ])))
1432+ )
1433+ | isJSConstant t && isJSConstant f =
1434+ True
1435+
1436+ | JSIdent _ <- t
1437+ , JSIdent _ <- f =
1438+ True
1439+
1440+ isCond (JSAlloc
1441+ fun (Just (JSFunction args (JSCond
1442+ [ (JSBinOp "==" (JSIdent _) c, JSReturn t)
1443+ , (JSNoop, JSReturn f)
1444+ ])))
1445+ )
1446+ | isJSConstant t && isJSConstant f && isJSConstant c =
1447+ True
1448+
1449+ | JSIdent _ <- t
1450+ , JSIdent _ <- f
1451+ , isJSConstant c =
1452+ True
1453+
1454+ isCond _ = False
1455+
1456+
1457+ eraseCond :: [JS] -> JS -> [JS]
1458+ eraseCond js (JSAlloc
1459+ fun (Just (JSFunction args (JSCond
1460+ [ (c, JSReturn t)
1461+ , (_, JSReturn f)
1462+ ])
1463+ )
1464+ )) = map (inlineFunction fun args (JSTernary c t f)) js
1465+
1466+
1467+removeUselessCons :: [JS] -> [JS]
1468+removeUselessCons js =
1469+ let (cons, rest) = partition isUseless js in
1470+ foldl' eraseCon rest cons
1471+ where
1472+ isUseless :: JS -> Bool
1473+ isUseless (JSAlloc fun (Just JSNull)) = True
1474+ isUseless (JSAlloc fun (Just (JSIdent _))) = True
1475+ isUseless _ = False
1476+
1477+
1478+ eraseCon :: [JS] -> JS -> [JS]
1479+ eraseCon js (JSAlloc fun (Just val)) = map (jsSubst (JSIdent fun) val) js
1480+
1481+
1381getGlobalCons :: JS -> [(String, JS)]
1482getGlobalCons :: JS -> [(String, JS)]
1382getGlobalCons js = foldJS match (++) [] js
1483getGlobalCons js = foldJS match (++) [] js
1383 where
1484 where
@@ -1441,6 +1542,7 @@ codegenJS_all target definitions includes filename outputType = do
1441
1542
1442 match :: JS -> Bool
1543 match :: JS -> Bool
1443 match (JSIdent "__IDRRT__bigInt") = True
1544 match (JSIdent "__IDRRT__bigInt") = True
1545+ match (JSWord (JSWord64 _)) = True
1444 match (JSNum (JSInteger _)) = True
1546 match (JSNum (JSInteger _)) = True
1445 match js = False
1547 match js = False
1446
1548
@@ -1478,6 +1580,8 @@ codegenJS_all target definitions includes filename outputType = do
1478 , extractLocalConstructors
1580 , extractLocalConstructors
1479 , unfoldLookupTable
1581 , unfoldLookupTable
1480 , evalCons
1582 , evalCons
1583+ , elimConds
1584+ , removeUselessCons
1481 ]
1585 ]
1482
1586
1483 functions :: [String]
1587 functions :: [String]
@@ -1499,23 +1603,36 @@ codegenJS_all target definitions includes filename outputType = do
1499
1603
1500 mainLoop :: JS
1604 mainLoop :: JS
1501 mainLoop =
1605 mainLoop =
1502− JSAlloc "main" $ Just $ JSFunction [] (
1606+ JSAlloc "main" $ Just $ JSFunction [] (
1503− case target of
1607+ case target of
1504− Node -> mainFun
1608+ Node -> mainFun
1505− JavaScript -> JSCond [(isReady, mainFun), (JSTrue, jsMeth (JSIdent "window") "addEventListener" [
1609+ JavaScript -> JSCond [ (exists document `jsAnd` isReady, mainFun)
1506− JSString "DOMContentLoaded", JSFunction [] (
1610+ , (exists window, windowMainFun)
1507− mainFun
1611+ , (JSTrue, mainFun)
1508− ), JSFalse
1509− ])]
1612+ ]
1510 )
1613 )
1511 where
1614 where
1615+ exists :: JS -> JS
1616+ exists js = (JSPreOp "typeof " js) `jsNotEq` JSString "undefined"
1617+
1512 mainFun :: JS
1618 mainFun :: JS
1513 mainFun = jsTailcall $ jsCall runMain []
1619 mainFun = jsTailcall $ jsCall runMain []
1514
1620
1621+ window :: JS
1622+ window = JSIdent "window"
1515
1623
1516− isReady :: JS
1624+ document :: JS
1517− isReady = readyState `jsEq` JSString "complete" `jsOr` readyState `jsEq` JSString "loaded"
1625+ document = JSIdent "document"
1518
1626
1627+ windowMainFun :: JS
1628+ windowMainFun = jsMeth window "addEventListener" [
1629+ JSString "DOMContentLoaded"
1630+ , JSFunction [] ( mainFun )
1631+ , JSFalse
1632+ ]
1633+
1634+ isReady :: JS
1635+ isReady = JSParens $ readyState `jsEq` JSString "complete" `jsOr` readyState `jsEq` JSString "loaded"
1519
1636
1520 readyState :: JS
1637 readyState :: JS
1521 readyState = JSProj (JSIdent "document") "readyState"
1638 readyState = JSProj (JSIdent "document") "readyState"
@@ -1633,6 +1750,10 @@ translateConstant (AType (ATInt ITChar)) = JSType JSCharTy
1633translateConstant PtrType = JSType JSPtrTy
1750translateConstant PtrType = JSType JSPtrTy
1634translateConstant Forgot = JSType JSForgotTy
1751translateConstant Forgot = JSType JSForgotTy
1635translateConstant (BI i) = jsBigInt $ JSString (show i)
1752translateConstant (BI i) = jsBigInt $ JSString (show i)
1753+translateConstant (B8 b) = JSWord (JSWord8 b)
1754+translateConstant (B16 b) = JSWord (JSWord16 b)
1755+translateConstant (B32 b) = JSWord (JSWord32 b)
1756+translateConstant (B64 b) = JSWord (JSWord64 b)
1636translateConstant c =
1757translateConstant c =
1637 jsError $ "Unimplemented Constant: " ++ show c
1758 jsError $ "Unimplemented Constant: " ++ show c
1638
1759
@@ -1809,6 +1930,10 @@ translateExpression (SApp tc name vars)
1809translateExpression (SOp op vars)
1930translateExpression (SOp op vars)
1810 | LNoOp <- op = JSVar (last vars)
1931 | LNoOp <- op = JSVar (last vars)
1811
1932
1933+ | (LZExt (ITFixed IT8) ITNative) <- op = jsUnPackBits $ JSVar (last vars)
1934+ | (LZExt (ITFixed IT16) ITNative) <- op = jsUnPackBits $ JSVar (last vars)
1935+ | (LZExt (ITFixed IT32) ITNative) <- op = jsUnPackBits $ JSVar (last vars)
1936+
1812 | (LZExt _ ITBig) <- op = jsBigInt $ jsCall "String" [JSVar (last vars)]
1937 | (LZExt _ ITBig) <- op = jsBigInt $ jsCall "String" [JSVar (last vars)]
1813 | (LPlus (ATInt ITBig)) <- op
1938 | (LPlus (ATInt ITBig)) <- op
1814 , (lhs:rhs:_) <- vars = invokeMeth lhs "add" [rhs]
1939 , (lhs:rhs:_) <- vars = invokeMeth lhs "add" [rhs]
@@ -1850,6 +1975,435 @@ translateExpression (SOp op vars)
1850 | (LSGe ATFloat) <- op
1975 | (LSGe ATFloat) <- op
1851 , (lhs:rhs:_) <- vars = translateBinaryOp ">=" lhs rhs
1976 , (lhs:rhs:_) <- vars = translateBinaryOp ">=" lhs rhs
1852
1977
1978+ | (LPlus (ATInt ITChar)) <- op
1979+ , (lhs:rhs:_) <- vars =
1980+ jsCall "__IDRRT__fromCharCode" [
1981+ JSBinOp "+" (
1982+ jsCall "__IDRRT__charCode" [JSVar lhs]
1983+ ) (
1984+ jsCall "__IDRRT__charCode" [JSVar rhs]
1985+ )
1986+ ]
1987+
1988+ | (LTrunc (ITFixed IT16) (ITFixed IT8)) <- op
1989+ , (arg:_) <- vars =
1990+ jsPackUBits8 (
1991+ JSBinOp "&" (jsUnPackBits $ JSVar arg) (JSNum (JSInt 0xFF))
1992+ )
1993+
1994+ | (LTrunc (ITFixed IT32) (ITFixed IT16)) <- op
1995+ , (arg:_) <- vars =
1996+ jsPackUBits16 (
1997+ JSBinOp "&" (jsUnPackBits $ JSVar arg) (JSNum (JSInt 0xFFFF))
1998+ )
1999+
2000+ | (LTrunc (ITFixed IT64) (ITFixed IT32)) <- op
2001+ , (arg:_) <- vars =
2002+ jsPackUBits32 (
2003+ jsMeth (jsMeth (JSVar arg) "and" [
2004+ jsBigInt (JSString $ show 0xFFFFFFFF)
2005+ ]) "intValue" []
2006+ )
2007+
2008+ | (LTrunc ITBig (ITFixed IT64)) <- op
2009+ , (arg:_) <- vars =
2010+ jsMeth (JSVar arg) "and" [
2011+ jsBigInt (JSString $ show 0xFFFFFFFFFFFFFFFF)
2012+ ]
2013+
2014+ | (LLSHR (ITFixed IT8)) <- op
2015+ , (lhs:rhs:_) <- vars =
2016+ jsPackUBits8 (
2017+ JSBinOp ">>" (jsUnPackBits $ JSVar lhs) (jsUnPackBits $ JSVar rhs)
2018+ )
2019+
2020+ | (LLSHR (ITFixed IT16)) <- op
2021+ , (lhs:rhs:_) <- vars =
2022+ jsPackUBits16 (
2023+ JSBinOp ">>" (jsUnPackBits $ JSVar lhs) (jsUnPackBits $ JSVar rhs)
2024+ )
2025+
2026+ | (LLSHR (ITFixed IT32)) <- op
2027+ , (lhs:rhs:_) <- vars =
2028+ jsPackUBits32 (
2029+ JSBinOp ">>" (jsUnPackBits $ JSVar lhs) (jsUnPackBits $ JSVar rhs)
2030+ )
2031+
2032+ | (LLSHR (ITFixed IT64)) <- op
2033+ , (lhs:rhs:_) <- vars =
2034+ jsMeth (JSVar lhs) "shiftRight" [JSVar rhs]
2035+
2036+ | (LSHL (ITFixed IT8)) <- op
2037+ , (lhs:rhs:_) <- vars =
2038+ jsPackUBits8 (
2039+ JSBinOp "<<" (jsUnPackBits $ JSVar lhs) (jsUnPackBits $ JSVar rhs)
2040+ )
2041+
2042+ | (LSHL (ITFixed IT16)) <- op
2043+ , (lhs:rhs:_) <- vars =
2044+ jsPackUBits16 (
2045+ JSBinOp "<<" (jsUnPackBits $ JSVar lhs) (jsUnPackBits $ JSVar rhs)
2046+ )
2047+
2048+ | (LSHL (ITFixed IT32)) <- op
2049+ , (lhs:rhs:_) <- vars =
2050+ jsPackUBits32 (
2051+ JSBinOp "<<" (jsUnPackBits $ JSVar lhs) (jsUnPackBits $ JSVar rhs)
2052+ )
2053+
2054+ | (LSHL (ITFixed IT64)) <- op
2055+ , (lhs:rhs:_) <- vars =
2056+ jsMeth (jsMeth (JSVar lhs) "shiftLeft" [JSVar rhs]) "and" [
2057+ jsBigInt (JSString $ show 0xFFFFFFFFFFFFFFFF)
2058+ ]
2059+
2060+ | (LAnd (ITFixed IT8)) <- op
2061+ , (lhs:rhs:_) <- vars =
2062+ jsPackUBits8 (
2063+ JSBinOp "&" (jsUnPackBits (JSVar lhs)) (jsUnPackBits (JSVar rhs))
2064+ )
2065+
2066+ | (LAnd (ITFixed IT16)) <- op
2067+ , (lhs:rhs:_) <- vars =
2068+ jsPackUBits16 (
2069+ JSBinOp "&" (jsUnPackBits (JSVar lhs)) (jsUnPackBits (JSVar rhs))
2070+ )
2071+
2072+ | (LAnd (ITFixed IT32)) <- op
2073+ , (lhs:rhs:_) <- vars =
2074+ jsPackUBits32 (
2075+ JSBinOp "&" (jsUnPackBits (JSVar lhs)) (jsUnPackBits (JSVar rhs))
2076+ )
2077+
2078+ | (LAnd (ITFixed IT64)) <- op
2079+ , (lhs:rhs:_) <- vars =
2080+ jsMeth (JSVar lhs) "and" [JSVar rhs]
2081+
2082+ | (LOr (ITFixed IT8)) <- op
2083+ , (lhs:rhs:_) <- vars =
2084+ jsPackUBits8 (
2085+ JSBinOp "|" (jsUnPackBits (JSVar lhs)) (jsUnPackBits (JSVar rhs))
2086+ )
2087+
2088+ | (LOr (ITFixed IT16)) <- op
2089+ , (lhs:rhs:_) <- vars =
2090+ jsPackUBits16 (
2091+ JSBinOp "|" (jsUnPackBits (JSVar lhs)) (jsUnPackBits (JSVar rhs))
2092+ )
2093+
2094+ | (LOr (ITFixed IT32)) <- op
2095+ , (lhs:rhs:_) <- vars =
2096+ jsPackUBits32 (
2097+ JSBinOp "|" (jsUnPackBits (JSVar lhs)) (jsUnPackBits (JSVar rhs))
2098+ )
2099+
2100+ | (LOr (ITFixed IT64)) <- op
2101+ , (lhs:rhs:_) <- vars =
2102+ jsMeth (JSVar lhs) "or" [JSVar rhs]
2103+
2104+ | (LXOr (ITFixed IT8)) <- op
2105+ , (lhs:rhs:_) <- vars =
2106+ jsPackUBits8 (
2107+ JSBinOp "^" (jsUnPackBits (JSVar lhs)) (jsUnPackBits (JSVar rhs))
2108+ )
2109+
2110+ | (LXOr (ITFixed IT16)) <- op
2111+ , (lhs:rhs:_) <- vars =
2112+ jsPackUBits16 (
2113+ JSBinOp "^" (jsUnPackBits (JSVar lhs)) (jsUnPackBits (JSVar rhs))
2114+ )
2115+
2116+ | (LXOr (ITFixed IT32)) <- op
2117+ , (lhs:rhs:_) <- vars =
2118+ jsPackUBits32 (
2119+ JSBinOp "^" (jsUnPackBits (JSVar lhs)) (jsUnPackBits (JSVar rhs))
2120+ )
2121+
2122+ | (LXOr (ITFixed IT64)) <- op
2123+ , (lhs:rhs:_) <- vars =
2124+ jsMeth (JSVar lhs) "xor" [JSVar rhs]
2125+
2126+ | (LPlus (ATInt (ITFixed IT8))) <- op
2127+ , (lhs:rhs:_) <- vars =
2128+ jsPackUBits8 (
2129+ JSBinOp "+" (jsUnPackBits (JSVar lhs)) (jsUnPackBits (JSVar rhs))
2130+ )
2131+
2132+ | (LPlus (ATInt (ITFixed IT16))) <- op
2133+ , (lhs:rhs:_) <- vars =
2134+ jsPackUBits16 (
2135+ JSBinOp "+" (jsUnPackBits (JSVar lhs)) (jsUnPackBits (JSVar rhs))
2136+ )
2137+
2138+ | (LPlus (ATInt (ITFixed IT32))) <- op
2139+ , (lhs:rhs:_) <- vars =
2140+ jsPackUBits32 (
2141+ JSBinOp "+" (jsUnPackBits (JSVar lhs)) (jsUnPackBits (JSVar rhs))
2142+ )
2143+
2144+ | (LPlus (ATInt (ITFixed IT64))) <- op
2145+ , (lhs:rhs:_) <- vars =
2146+ jsMeth (jsMeth (JSVar lhs) "add" [JSVar rhs]) "and" [
2147+ jsBigInt (JSString $ show 0xFFFFFFFFFFFFFFFF)
2148+ ]
2149+
2150+ | (LMinus (ATInt (ITFixed IT8))) <- op
2151+ , (lhs:rhs:_) <- vars =
2152+ jsPackUBits8 (
2153+ JSBinOp "-" (jsUnPackBits (JSVar lhs)) (jsUnPackBits (JSVar rhs))
2154+ )
2155+
2156+ | (LMinus (ATInt (ITFixed IT16))) <- op
2157+ , (lhs:rhs:_) <- vars =
2158+ jsPackUBits16 (
2159+ JSBinOp "-" (jsUnPackBits (JSVar lhs)) (jsUnPackBits (JSVar rhs))
2160+ )
2161+
2162+ | (LMinus (ATInt (ITFixed IT32))) <- op
2163+ , (lhs:rhs:_) <- vars =
2164+ jsPackUBits32 (
2165+ JSBinOp "-" (jsUnPackBits (JSVar lhs)) (jsUnPackBits (JSVar rhs))
2166+ )
2167+
2168+ | (LMinus (ATInt (ITFixed IT64))) <- op
2169+ , (lhs:rhs:_) <- vars =
2170+ jsMeth (jsMeth (JSVar lhs) "subtract" [JSVar rhs]) "and" [
2171+ jsBigInt (JSString $ show 0xFFFFFFFFFFFFFFFF)
2172+ ]
2173+
2174+ | (LTimes (ATInt (ITFixed IT8))) <- op
2175+ , (lhs:rhs:_) <- vars =
2176+ jsPackUBits8 (
2177+ JSBinOp "*" (jsUnPackBits (JSVar lhs)) (jsUnPackBits (JSVar rhs))
2178+ )
2179+
2180+ | (LTimes (ATInt (ITFixed IT16))) <- op
2181+ , (lhs:rhs:_) <- vars =
2182+ jsPackUBits16 (
2183+ JSBinOp "*" (jsUnPackBits (JSVar lhs)) (jsUnPackBits (JSVar rhs))
2184+ )
2185+
2186+ | (LTimes (ATInt (ITFixed IT32))) <- op
2187+ , (lhs:rhs:_) <- vars =
2188+ jsPackUBits32 (
2189+ JSBinOp "*" (jsUnPackBits (JSVar lhs)) (jsUnPackBits (JSVar rhs))
2190+ )
2191+
2192+ | (LTimes (ATInt (ITFixed IT64))) <- op
2193+ , (lhs:rhs:_) <- vars =
2194+ jsMeth (jsMeth (JSVar lhs) "multiply" [JSVar rhs]) "and" [
2195+ jsBigInt (JSString $ show 0xFFFFFFFFFFFFFFFF)
2196+ ]
2197+
2198+ | (LEq (ATInt (ITFixed IT8))) <- op
2199+ , (lhs:rhs:_) <- vars =
2200+ jsPackUBits8 (
2201+ JSBinOp "==" (jsUnPackBits (JSVar lhs)) (jsUnPackBits (JSVar rhs))
2202+ )
2203+
2204+ | (LEq (ATInt (ITFixed IT16))) <- op
2205+ , (lhs:rhs:_) <- vars =
2206+ jsPackUBits16 (
2207+ JSBinOp "==" (jsUnPackBits (JSVar lhs)) (jsUnPackBits (JSVar rhs))
2208+ )
2209+
2210+ | (LEq (ATInt (ITFixed IT32))) <- op
2211+ , (lhs:rhs:_) <- vars =
2212+ jsPackUBits32 (
2213+ JSBinOp "==" (jsUnPackBits (JSVar lhs)) (jsUnPackBits (JSVar rhs))
2214+ )
2215+
2216+ | (LEq (ATInt (ITFixed IT64))) <- op
2217+ , (lhs:rhs:_) <- vars =
2218+ jsMeth (jsMeth (JSVar lhs) "equals" [JSVar rhs]) "and" [
2219+ jsBigInt (JSString $ show 0xFFFFFFFFFFFFFFFF)
2220+ ]
2221+
2222+ | (LLt (ITFixed IT8)) <- op
2223+ , (lhs:rhs:_) <- vars =
2224+ jsPackUBits8 (
2225+ JSBinOp "<" (jsUnPackBits (JSVar lhs)) (jsUnPackBits (JSVar rhs))
2226+ )
2227+
2228+ | (LLt (ITFixed IT16)) <- op
2229+ , (lhs:rhs:_) <- vars =
2230+ jsPackUBits16 (
2231+ JSBinOp "<" (jsUnPackBits (JSVar lhs)) (jsUnPackBits (JSVar rhs))
2232+ )
2233+
2234+ | (LLt (ITFixed IT32)) <- op
2235+ , (lhs:rhs:_) <- vars =
2236+ jsPackUBits32 (
2237+ JSBinOp "<" (jsUnPackBits (JSVar lhs)) (jsUnPackBits (JSVar rhs))
2238+ )
2239+
2240+ | (LLt (ITFixed IT64)) <- op
2241+ , (lhs:rhs:_) <- vars = invokeMeth lhs "lesser" [rhs]
2242+
2243+ | (LLe (ITFixed IT8)) <- op
2244+ , (lhs:rhs:_) <- vars =
2245+ jsPackUBits8 (
2246+ JSBinOp "<=" (jsUnPackBits (JSVar lhs)) (jsUnPackBits (JSVar rhs))
2247+ )
2248+
2249+ | (LLe (ITFixed IT16)) <- op
2250+ , (lhs:rhs:_) <- vars =
2251+ jsPackUBits16 (
2252+ JSBinOp "<=" (jsUnPackBits (JSVar lhs)) (jsUnPackBits (JSVar rhs))
2253+ )
2254+
2255+ | (LLe (ITFixed IT32)) <- op
2256+ , (lhs:rhs:_) <- vars =
2257+ jsPackUBits32 (
2258+ JSBinOp "<=" (jsUnPackBits (JSVar lhs)) (jsUnPackBits (JSVar rhs))
2259+ )
2260+
2261+ | (LLe (ITFixed IT64)) <- op
2262+ , (lhs:rhs:_) <- vars = invokeMeth lhs "lesserOrEquals" [rhs]
2263+
2264+ | (LGt (ITFixed IT8)) <- op
2265+ , (lhs:rhs:_) <- vars =
2266+ jsPackUBits8 (
2267+ JSBinOp ">" (jsUnPackBits (JSVar lhs)) (jsUnPackBits (JSVar rhs))
2268+ )
2269+
2270+ | (LGt (ITFixed IT16)) <- op
2271+ , (lhs:rhs:_) <- vars =
2272+ jsPackUBits16 (
2273+ JSBinOp ">" (jsUnPackBits (JSVar lhs)) (jsUnPackBits (JSVar rhs))
2274+ )
2275+ | (LGt (ITFixed IT32)) <- op
2276+ , (lhs:rhs:_) <- vars =
2277+ jsPackUBits32 (
2278+ JSBinOp ">" (jsUnPackBits (JSVar lhs)) (jsUnPackBits (JSVar rhs))
2279+ )
2280+
2281+ | (LGt (ITFixed IT64)) <- op
2282+ , (lhs:rhs:_) <- vars = invokeMeth lhs "greater" [rhs]
2283+
2284+ | (LGe (ITFixed IT8)) <- op
2285+ , (lhs:rhs:_) <- vars =
2286+ jsPackUBits8 (
2287+ JSBinOp ">=" (jsUnPackBits (JSVar lhs)) (jsUnPackBits (JSVar rhs))
2288+ )
2289+
2290+ | (LGe (ITFixed IT16)) <- op
2291+ , (lhs:rhs:_) <- vars =
2292+ jsPackUBits16 (
2293+ JSBinOp ">=" (jsUnPackBits (JSVar lhs)) (jsUnPackBits (JSVar rhs))
2294+ )
2295+ | (LGe (ITFixed IT32)) <- op
2296+ , (lhs:rhs:_) <- vars =
2297+ jsPackUBits32 (
2298+ JSBinOp ">=" (jsUnPackBits (JSVar lhs)) (jsUnPackBits (JSVar rhs))
2299+ )
2300+
2301+ | (LGe (ITFixed IT64)) <- op
2302+ , (lhs:rhs:_) <- vars = invokeMeth lhs "greaterOrEquals" [rhs]
2303+
2304+ | (LUDiv (ITFixed IT8)) <- op
2305+ , (lhs:rhs:_) <- vars =
2306+ jsPackUBits8 (
2307+ JSBinOp "/" (jsUnPackBits (JSVar lhs)) (jsUnPackBits (JSVar rhs))
2308+ )
2309+
2310+ | (LUDiv (ITFixed IT16)) <- op
2311+ , (lhs:rhs:_) <- vars =
2312+ jsPackUBits16 (
2313+ JSBinOp "/" (jsUnPackBits (JSVar lhs)) (jsUnPackBits (JSVar rhs))
2314+ )
2315+
2316+ | (LUDiv (ITFixed IT32)) <- op
2317+ , (lhs:rhs:_) <- vars =
2318+ jsPackUBits32 (
2319+ JSBinOp "/" (jsUnPackBits (JSVar lhs)) (jsUnPackBits (JSVar rhs))
2320+ )
2321+
2322+ | (LUDiv (ITFixed IT64)) <- op
2323+ , (lhs:rhs:_) <- vars = invokeMeth lhs "divide" [rhs]
2324+
2325+ | (LSDiv (ATInt (ITFixed IT8))) <- op
2326+ , (lhs:rhs:_) <- vars =
2327+ jsPackSBits8 (
2328+ JSBinOp "/" (
2329+ jsUnPackBits $ jsPackSBits8 $ jsUnPackBits (JSVar lhs)
2330+ ) (
2331+ jsUnPackBits $ jsPackSBits8 $ jsUnPackBits (JSVar rhs)
2332+ )
2333+ )
2334+
2335+ | (LSDiv (ATInt (ITFixed IT16))) <- op
2336+ , (lhs:rhs:_) <- vars =
2337+ jsPackSBits16 (
2338+ JSBinOp "/" (
2339+ jsUnPackBits $ jsPackSBits16 $ jsUnPackBits (JSVar lhs)
2340+ ) (
2341+ jsUnPackBits $ jsPackSBits16 $ jsUnPackBits (JSVar rhs)
2342+ )
2343+ )
2344+
2345+ | (LSDiv (ATInt (ITFixed IT32))) <- op
2346+ , (lhs:rhs:_) <- vars =
2347+ jsPackSBits32 (
2348+ JSBinOp "/" (
2349+ jsUnPackBits $ jsPackSBits32 $ jsUnPackBits (JSVar lhs)
2350+ ) (
2351+ jsUnPackBits $ jsPackSBits32 $ jsUnPackBits (JSVar rhs)
2352+ )
2353+ )
2354+
2355+ | (LSDiv (ATInt (ITFixed IT64))) <- op
2356+ , (lhs:rhs:_) <- vars = invokeMeth lhs "divide" [rhs]
2357+
2358+ | (LSRem (ATInt (ITFixed IT8))) <- op
2359+ , (lhs:rhs:_) <- vars =
2360+ jsPackSBits8 (
2361+ JSBinOp "%" (
2362+ jsUnPackBits $ jsPackSBits8 $ jsUnPackBits (JSVar lhs)
2363+ ) (
2364+ jsUnPackBits $ jsPackSBits8 $ jsUnPackBits (JSVar rhs)
2365+ )
2366+ )
2367+
2368+ | (LSRem (ATInt (ITFixed IT16))) <- op
2369+ , (lhs:rhs:_) <- vars =
2370+ jsPackSBits16 (
2371+ JSBinOp "%" (
2372+ jsUnPackBits $ jsPackSBits16 $ jsUnPackBits (JSVar lhs)
2373+ ) (
2374+ jsUnPackBits $ jsPackSBits16 $ jsUnPackBits (JSVar rhs)
2375+ )
2376+ )
2377+
2378+ | (LSRem (ATInt (ITFixed IT32))) <- op
2379+ , (lhs:rhs:_) <- vars =
2380+ jsPackSBits32 (
2381+ JSBinOp "%" (
2382+ jsUnPackBits $ jsPackSBits32 $ jsUnPackBits (JSVar lhs)
2383+ ) (
2384+ jsUnPackBits $ jsPackSBits32 $ jsUnPackBits (JSVar rhs)
2385+ )
2386+ )
2387+
2388+ | (LSRem (ATInt (ITFixed IT64))) <- op
2389+ , (lhs:rhs:_) <- vars = invokeMeth lhs "mod" [rhs]
2390+
2391+ | (LCompl (ITFixed IT8)) <- op
2392+ , (arg:_) <- vars =
2393+ jsPackSBits8 $ JSPreOp "~" $ jsUnPackBits (JSVar arg)
2394+
2395+ | (LCompl (ITFixed IT16)) <- op
2396+ , (arg:_) <- vars =
2397+ jsPackSBits16 $ JSPreOp "~" $ jsUnPackBits (JSVar arg)
2398+
2399+ | (LCompl (ITFixed IT32)) <- op
2400+ , (arg:_) <- vars =
2401+ jsPackSBits32 $ JSPreOp "~" $ jsUnPackBits (JSVar arg)
2402+
2403+ | (LCompl (ITFixed IT64)) <- op
2404+ , (arg:_) <- vars =
2405+ invokeMeth arg "not" []
2406+
1853 | (LPlus _) <- op
2407 | (LPlus _) <- op
1854 , (lhs:rhs:_) <- vars = translateBinaryOp "+" lhs rhs
2408 , (lhs:rhs:_) <- vars = translateBinaryOp "+" lhs rhs
1855 | (LMinus _) <- op
2409 | (LMinus _) <- op
@@ -1884,7 +2438,7 @@ translateExpression (SOp op vars)
1884 , (arg:_) <- vars = JSPreOp "~" (JSVar arg)
2438 , (arg:_) <- vars = JSPreOp "~" (JSVar arg)
1885
2439
1886 | LStrConcat <- op
2440 | LStrConcat <- op
1887− , (lhs:rhs:_) <- vars = translateBinaryOp "+" lhs rhs
2441+ , (lhs:rhs:_) <- vars = invokeMeth lhs "concat" [rhs]
1888 | LStrEq <- op
2442 | LStrEq <- op
1889 , (lhs:rhs:_) <- vars = translateBinaryOp "==" lhs rhs
2443 , (lhs:rhs:_) <- vars = translateBinaryOp "==" lhs rhs
1890 | LStrLt <- op
2444 | LStrLt <- op
@@ -1913,9 +2467,9 @@ translateExpression (SOp op vars)
1913 | (LFloatInt ITNative) <- op
2467 | (LFloatInt ITNative) <- op
1914 , (arg:_) <- vars = JSVar arg
2468 , (arg:_) <- vars = JSVar arg
1915 | (LChInt ITNative) <- op
2469 | (LChInt ITNative) <- op
1916− , (arg:_) <- vars = JSProj (JSVar arg) "charCodeAt(0)"
2470+ , (arg:_) <- vars = jsCall "__IDRRT__charCode" [JSVar arg]
1917 | (LIntCh ITNative) <- op
2471 | (LIntCh ITNative) <- op
1918− , (arg:_) <- vars = jsCall "String.fromCharCode" [JSVar arg]
2472+ , (arg:_) <- vars = jsCall "__IDRRT__fromCharCode" [JSVar arg]
1919
2473
1920 | LFExp <- op
2474 | LFExp <- op
1921 , (arg:_) <- vars = jsCall "Math.exp" [JSVar arg]
2475 , (arg:_) <- vars = jsCall "Math.exp" [JSVar arg]
@@ -1941,7 +2495,7 @@ translateExpression (SOp op vars)
1941 , (arg:_) <- vars = jsCall "Math.ceil" [JSVar arg]
2495 , (arg:_) <- vars = jsCall "Math.ceil" [JSVar arg]
1942
2496
1943 | LStrCons <- op
2497 | LStrCons <- op
1944− , (lhs:rhs:_) <- vars = translateBinaryOp "+" lhs rhs
2498+ , (lhs:rhs:_) <- vars = invokeMeth lhs "concat" [rhs]
1945 | LStrHead <- op
2499 | LStrHead <- op
1946 , (arg:_) <- vars = JSIndex (JSVar arg) (JSNum (JSInt 0))
2500 , (arg:_) <- vars = JSIndex (JSVar arg) (JSNum (JSInt 0))
1947 | LStrRev <- op
2501 | LStrRev <- op
@@ -1954,12 +2508,14 @@ translateExpression (SOp op vars)
1954 JSNum (JSInt 1),
2508 JSNum (JSInt 1),
1955 JSBinOp "-" (JSProj (JSIdent v) "length") (JSNum (JSInt 1))
2509 JSBinOp "-" (JSProj (JSIdent v) "length") (JSNum (JSInt 1))
1956 ]
2510 ]
2511+ | LSystemInfo <- op
2512+ , (arg:_) <- vars = jsCall "__IDRRT__systemInfo" [JSVar arg]
1957 | LNullPtr <- op
2513 | LNullPtr <- op
1958 , (_) <- vars = JSNull
2514 , (_) <- vars = JSNull
1959
2515
1960 where
2516 where
1961 translateBinaryOp :: String -> LVar -> LVar -> JS
2517 translateBinaryOp :: String -> LVar -> LVar -> JS
1962− translateBinaryOp f lhs rhs = JSBinOp f (JSVar lhs) (JSVar rhs)
2518+ translateBinaryOp f lhs rhs = JSParens $ JSBinOp f (JSVar lhs) (JSVar rhs)
1963
2519
1964
2520
1965 invokeMeth :: LVar -> String -> [LVar] -> JS
2521 invokeMeth :: LVar -> String -> [LVar] -> JS
src/IRTS/Compiler.hs+145−64
@@ -19,6 +19,7 @@ import IRTS.Inliner
19
19
20import Idris.AbsSyntax
20import Idris.AbsSyntax
21import Idris.AbsSyntaxTree
21import Idris.AbsSyntaxTree
22+import Idris.ASTUtils
22import Idris.Erasure
23import Idris.Erasure
23import Idris.Error
24import Idris.Error
24
25
@@ -28,6 +29,9 @@ import Idris.Core.TT
28import Idris.Core.Evaluate
29import Idris.Core.Evaluate
29import Idris.Core.CaseTree
30import Idris.Core.CaseTree
30
31
32+import Control.Category
33+import Prelude hiding (id, (.))
34+
31import Control.Applicative
35import Control.Applicative
32import Control.Monad.State
36import Control.Monad.State
33import Data.Maybe
37import Data.Maybe
@@ -48,6 +52,7 @@ import Paths_idris
48compile :: Codegen -> FilePath -> Term -> Idris ()
52compile :: Codegen -> FilePath -> Term -> Idris ()
49compile codegen f tm
53compile codegen f tm
50 = do checkMVs -- check for undefined metavariables
54 = do checkMVs -- check for undefined metavariables
55+ checkTotality -- refuse to compile if there are totality problems
51 reachableNames <- performUsageAnalysis
56 reachableNames <- performUsageAnalysis
52 maindef <- irMain tm
57 maindef <- irMain tm
53 iLOG $ "MAIN: " ++ show maindef
58 iLOG $ "MAIN: " ++ show maindef
@@ -101,6 +106,10 @@ compile codegen f tm
101 case map fst (idris_metavars i) \\ primDefs of
106 case map fst (idris_metavars i) \\ primDefs of
102 [] -> return ()
107 [] -> return ()
103 ms -> ifail $ "There are undefined metavariables: " ++ show ms
108 ms -> ifail $ "There are undefined metavariables: " ++ show ms
109+ checkTotality = do i <- getIState
110+ case idris_totcheckfail i of
111+ [] -> return ()
112+ ((fc, msg):fs) -> ierror . At fc . Msg $ "Cannot compile:\n " ++ msg
104 inDir d h = do let f = d </> h
113 inDir d h = do let f = d </> h
105 ex <- doesFileExist f
114 ex <- doesFileExist f
106 if ex then return f else return h
115 if ex then return f else return h
@@ -172,10 +181,7 @@ mkLDecl n (CaseOp ci _ _ _ pats cd)
172 (args, sc) = cases_runtime cd
181 (args, sc) = cases_runtime cd
173
182
174mkLDecl n (TyDecl (DCon tag arity) _) =
183mkLDecl n (TyDecl (DCon tag arity) _) =
175− LConstructor n tag . erasedArity . lookup n <$> getIState
184+ LConstructor n tag . length <$> fgetState (cg_usedpos . ist_callgraph n)
176− where
177− lookup n = lookupCtxtExact n . idris_callgraph
178− erasedArity = maybe 0 (length . usedpos)
179
185
180mkLDecl n (TyDecl (TCon t a) _) = return $ LConstructor n (-1) a
186mkLDecl n (TyDecl (TCon t a) _) = return $ LConstructor n (-1) a
181mkLDecl n _ = return $ (declArgs [] True n LNothing) -- postulate, never run
187mkLDecl n _ = return $ (declArgs [] True n LNothing) -- postulate, never run
@@ -220,7 +226,7 @@ irTerm vs env tm@(App f a) = case unApply tm of
220 | l == txt "Force"
226 | l == txt "Force"
221 -> LForce <$> irTerm vs env arg
227 -> LForce <$> irTerm vs env arg
222
228
223− (P _ (UN a) _, [_, _, arg])
229+ (P _ (UN a) _, [_, _, _, arg])
224 | a == txt "assert_smaller"
230 | a == txt "assert_smaller"
225 -> irTerm vs env arg
231 -> irTerm vs env arg
226
232
@@ -248,8 +254,8 @@ irTerm vs env tm@(App f a) = case unApply tm of
248
254
249 -- This case is here until we get more general inlining. It's just
255 -- This case is here until we get more general inlining. It's just
250 -- a really common case, and the laziness hurts...
256 -- a really common case, and the laziness hurts...
251− (P _ (NS (UN be) [b,p]) _, [_,x,(App (P _ (UN d) _) t),
257+ (P _ (NS (UN be) [b,p]) _, [_,x,(App (App (App (P _ (UN d) _) _) _) t),
252− (App (P _ (UN d') _) e)])
258+ (App (App (App (P _ (UN d') _) _) _) e)])
253 | be == txt "boolElim"
259 | be == txt "boolElim"
254 , d == txt "Delay"
260 , d == txt "Delay"
255 , d' == txt "Delay"
261 , d' == txt "Delay"
@@ -261,21 +267,67 @@ irTerm vs env tm@(App f a) = case unApply tm of
261 ,LConCase 1 (sNS (sUN "True" ) ["Bool","Prelude"]) [] t'
267 ,LConCase 1 (sNS (sUN "True" ) ["Bool","Prelude"]) [] t'
262 ])
268 ])
263
269
270+ -- data constructor
264 (P (DCon t arity) n _, args) -> do
271 (P (DCon t arity) n _, args) -> do
265− ist <- getIState
272+ detag <- fgetState (opt_detaggable . ist_optimisation n)
266− let detag = maybe False detaggable . lookupCtxtExact n $ idris_optimisation ist
273+ used <- map fst <$> fgetState (cg_usedpos . ist_callgraph n)
267− used = maybe [] (map fst . usedpos) . lookupCtxtExact n $ idris_callgraph ist
274+
275+ let isNewtype = length used == 1 && detag
268− args' = [a | (i,a) <- zip [0..] args, i `elem` used]
276+ let argsPruned = [a | (i,a) <- zip [0..] args, i `elem` used]
269−
277+
270− when (length args > arity) $
278+ -- The following code removes fields from data constructors
279+ -- and performs the newtype optimisation.
280+ --
281+ -- The general rule here is:
282+ -- Everything we get as input is not touched by erasure,
283+ -- so it conforms to the official arities and types
284+ -- and we can reason about it like it's plain TT.
285+ --
286+ -- It's only the data that leaves this point that's erased
287+ -- and possibly no longer typed as the original TT version.
288+ --
289+ -- Especially, underapplied constructors must yield functions
290+ -- even if all the remaining arguments are erased
291+ -- (the resulting function *will* be applied, to NULLs).
292+ --
293+ -- This will probably need rethinking when we get erasure from functions.
294+
295+ -- "padLams" will wrap our term in LLam-bdas and give us
296+ -- the "list of future unerased args" coming from these lambdas.
297+ --
298+ -- We can do whatever we like with the list of unerased args,
299+ -- hence it takes a lambda: \unerased_argname_list -> resulting_LExp.
300+ let padLams = padLambdas used (length args) arity
301+
302+ case compare arity (length args) of
303+
304+ -- overapplied
271− ifail ("oversaturated data ctor: " ++ show tm)
305+ GT -> ifail ("overapplied data constructor: " ++ show tm)
272−
306+
273− if length args' == 1 && detag -- detaggable
307+ -- exactly saturated
308+ EQ | isNewtype
309+ -> irTerm vs env (head argsPruned)
310+
311+ | otherwise -- not newtype, plain data ctor
312+ -> buildApp (LV $ Glob n) argsPruned
313+
314+ -- not saturated, underapplied
315+ LT | isNewtype -- newtype
316+ , length argsPruned == 1 -- and we already have the value
317+ -> padLams . (\tm [] -> tm) -- the [] asserts there are no unerased args
274− then irTerm vs env (head args') -- newtype
318+ <$> irTerm vs env (head argsPruned)
275− else irCon vs env (length used) n args'
319+
276−
320+ | isNewtype -- newtype but the value is not among args yet
321+ -> return . padLams $ \[vn] -> LApp False (LV $ Glob n) [LV $ Glob vn]
322+
323+ -- not a newtype, just apply to a constructor
324+ | otherwise
325+ -> padLams . applyToNames <$> buildApp (LV $ Glob n) argsPruned
326+
327+ -- type constructor
277 (P (TCon t a) n _, args) -> return LNothing
328 (P (TCon t a) n _, args) -> return LNothing
278
329
330+ -- a name applied to arguments
279 (P _ n _, args) -> do
331 (P _ n _, args) -> do
280 ist <- getIState
332 ist <- getIState
281 case lookup n (idris_scprims ist) of
333 case lookup n (idris_scprims ist) of
@@ -296,29 +348,44 @@ irTerm vs env tm@(App f a) = case unApply tm of
296 <*> mapM (irTerm vs env) args
348 <*> mapM (irTerm vs env) args
297
349
298 where
350 where
351+ buildApp :: LExp -> [Term] -> Idris LExp
352+ buildApp e [] = return e
353+ buildApp e xs = LApp False e <$> mapM (irTerm vs env) xs
354+
355+ applyToNames :: LExp -> [Name] -> LExp
356+ applyToNames tm [] = tm
357+ applyToNames tm ns = LApp False tm $ map (LV . Glob) ns
358+
359+ padLambdas :: [Int] -> Int -> Int -> ([Name] -> LExp) -> LExp
360+ padLambdas used startIdx endSIdx mkTerm
361+ = LLam allNames $ mkTerm nonerasedNames
362+ where
363+ allNames = [sMN i "sat" | i <- [startIdx .. endSIdx-1]]
364+ nonerasedNames = [sMN i "sat" | i <- [startIdx .. endSIdx-1], i `elem` used]
365+
299 applyName :: Name -> IState -> [Term] -> Idris LExp
366 applyName :: Name -> IState -> [Term] -> Idris LExp
300 applyName n ist args =
367 applyName n ist args =
301 LApp False (LV $ Glob n) <$> mapM (irTerm vs env . erase) (zip [0..] args)
368 LApp False (LV $ Glob n) <$> mapM (irTerm vs env . erase) (zip [0..] args)
302− where
369+ where
303− erase (i, x)
370+ erase (i, x)
304− | i >= arity || i `elem` used = x
371+ | i >= arity || i `elem` used = x
305− | otherwise = Erased
372+ | otherwise = Erased
306−
373+
307− arity = case fst4 <$> lookupCtxtExact n (definitions . tt_ctxt $ ist) of
374+ arity = case fst4 <$> lookupCtxtExact n (definitions . tt_ctxt $ ist) of
308− Just (CaseOp ci ty tys def tot cdefs) -> length tys
375+ Just (CaseOp ci ty tys def tot cdefs) -> length tys
309− Just (TyDecl (DCon tag ar) _) -> ar
376+ Just (TyDecl (DCon tag ar) _) -> ar
310− Just (TyDecl Ref ty) -> length $ getArgTys ty
377+ Just (TyDecl Ref ty) -> length $ getArgTys ty
311− Just (Operator ty ar op) -> ar
378+ Just (Operator ty ar op) -> ar
312− Just def -> error $ "unknown arity: " ++ show (n, def)
379+ Just def -> error $ "unknown arity: " ++ show (n, def)
313− Nothing -> 0 -- no definition, probably local name => can't erase anything
380+ Nothing -> 0 -- no definition, probably local name => can't erase anything
314−
381+
315− -- name for purposes of usage info lookup
382+ -- name for purposes of usage info lookup
316− uName
383+ uName
317− | Just n' <- viMethod =<< M.lookup n vs = n'
384+ | Just n' <- viMethod =<< M.lookup n vs = n'
318− | otherwise = n
385+ | otherwise = n
319−
386+
320− used = maybe [] (map fst . usedpos) $ lookupCtxtExact uName (idris_callgraph ist)
387+ used = maybe [] (map fst . usedpos) $ lookupCtxtExact uName (idris_callgraph ist)
321− fst4 (x,_,_,_) = x
388+ fst4 (x,_,_,_) = x
322
389
323irTerm vs env (P _ n _) = return $ LV (Glob n)
390irTerm vs env (P _ n _) = return $ LV (Glob n)
324irTerm vs env (V i)
391irTerm vs env (V i)
@@ -345,24 +412,6 @@ irTerm vs env (TType _) = return $ LNothing
345irTerm vs env Erased = return $ LNothing
412irTerm vs env Erased = return $ LNothing
346irTerm vs env Impossible = return $ LNothing
413irTerm vs env Impossible = return $ LNothing
347
414
348−irCon :: Vars -> [Name] -> Int -> Name -> [Term] -> Idris LExp
349−irCon vs env arity n args
350− | length args > arity
351− = error $ "oversaturated data constructor: " ++ show (n, args)
352−
353− -- saturated
354− | length args == arity
355− = buildApp (LV (Glob n)) args
356−
357− -- undersaturated, wrap in lambdas
358− | otherwise
359− = let extraNs = [sMN i "sat" | i <- [length args .. arity-1]]
360− extraTs = [P Bound n undefined | n <- extraNs]
361− in LLam extraNs <$> irCon vs env arity n (args ++ extraTs)
362− where
363− buildApp e [] = return e
364− buildApp e xs = LApp False e <$> mapM (irTerm vs env) xs
365−
366doForeign :: Vars -> [Name] -> [TT Name] -> Idris LExp
415doForeign :: Vars -> [Name] -> [TT Name] -> Idris LExp
367doForeign vs env (_ : fgn : args)
416doForeign vs env (_ : fgn : args)
368 | (_, (Constant (Str fgnName) : fgnArgTys : ret : [])) <- unApply fgn
417 | (_, (Constant (Str fgnName) : fgnArgTys : ret : [])) <- unApply fgn
@@ -470,11 +519,12 @@ irSC vs (Case n [ConCase (UN delay) i [_, _, n'] sc])
470--
519--
471-- Hence, we check whether the variables are used at all
520-- Hence, we check whether the variables are used at all
472-- and erase the casesplit if they are not.
521-- and erase the casesplit if they are not.
522+--
473irSC vs (Case n [alt]) = do
523irSC vs (Case n [alt]) = do
474 replacement <- case alt of
524 replacement <- case alt of
475 ConCase cn a ns sc -> do
525 ConCase cn a ns sc -> do
476− detag <- maybe False detaggable . lookupCtxtExact cn . idris_optimisation <$> getIState
526+ detag <- fgetState (opt_detaggable . ist_optimisation cn)
477− used <- maybe [] (map fst . usedpos) . lookupCtxtExact cn . idris_callgraph <$> getIState
527+ used <- map fst <$> fgetState (cg_usedpos . ist_callgraph cn)
478 if detag && length used == 1
528 if detag && length used == 1
479 then return . Just $ substSC (ns !! head used) n sc
529 then return . Just $ substSC (ns !! head used) n sc
480 else return Nothing
530 else return Nothing
@@ -498,20 +548,51 @@ irSC vs (Case n [alt]) = do
498 subexpr (LConstCase _ e) = e
548 subexpr (LConstCase _ e) = e
499 subexpr (LDefaultCase e) = e
549 subexpr (LDefaultCase e) = e
500
550
551+-- FIXME: When we have a non-singleton case-tree of the form
552+--
553+-- case {e0} of
554+-- C(x) => ...
555+-- ... => ...
556+--
557+-- and C is detaggable (the only constructor of the family), we can be sure
558+-- that the first branch will be always taken -- so we add special handling
559+-- to remove the dead default branch.
560+--
561+-- If we don't do so and C is newtype-optimisable, we will miss this newtype
562+-- transformation and the resulting code will probably segfault.
563+--
564+-- This work-around is not entirely optimal; the best approach would be
565+-- to ensure that such case trees don't arise in the first place.
566+--
567+irSC vs (Case n alts@[ConCase cn a ns sc, DefaultCase sc']) = do
568+ detag <- fgetState (opt_detaggable . ist_optimisation cn)
569+ if detag
570+ then irSC vs (Case n [ConCase cn a ns sc])
501−irSC vs (Case n alts) = LCase (LV (Glob n)) <$> mapM (irAlt vs (LV (Glob n))) alts
571+ else LCase (LV (Glob n)) <$> mapM (irAlt vs (LV (Glob n))) alts
572+
573+irSC vs sc@(Case n alts) = do
574+ -- check that neither alternative needs the newtype optimisation,
575+ -- see comment above
576+ goneWrong <- or <$> mapM isDetaggable alts
577+ when goneWrong
578+ $ ifail ("irSC: non-trivial case-match on detaggable data: " ++ show sc)
579+
580+ -- everything okay
581+ LCase (LV (Glob n)) <$> mapM (irAlt vs (LV (Glob n))) alts
582+ where
583+ isDetaggable (ConCase cn _ _ _) = fgetState $ opt_detaggable . ist_optimisation cn
584+ isDetaggable _ = return False
585+
502irSC vs ImpossibleCase = return LNothing
586irSC vs ImpossibleCase = return LNothing
503
587
504irAlt :: Vars -> LExp -> CaseAlt -> Idris LAlt
588irAlt :: Vars -> LExp -> CaseAlt -> Idris LAlt
505
589
506-- this leaves out all unused arguments of the constructor
590-- this leaves out all unused arguments of the constructor
507irAlt vs _ (ConCase n t args sc) = do
591irAlt vs _ (ConCase n t args sc) = do
508− used <- getUsed . lookup n <$> getIState
592+ used <- map fst <$> fgetState (cg_usedpos . ist_callgraph n)
509 let usedArgs = [a | (i,a) <- zip [0..] args, i `elem` used]
593 let usedArgs = [a | (i,a) <- zip [0..] args, i `elem` used]
510 LConCase (-1) n usedArgs <$> irSC (methodVars `M.union` vs) sc
594 LConCase (-1) n usedArgs <$> irSC (methodVars `M.union` vs) sc
511 where
595 where
512− lookup n = lookupCtxtExact n . idris_callgraph
513− getUsed = maybe [] (map fst . usedpos)
514−
515 methodVars = case n of
596 methodVars = case n of
516 SN (InstanceCtorN className)
597 SN (InstanceCtorN className)
517 -> M.fromList [(v, VI
598 -> M.fromList [(v, VI
src/IRTS/Defunctionalise.hs+1−1
@@ -195,7 +195,7 @@ toCons ns (n, i)
195 (DApp False n (map (DV . Glob) (take i (genArgs 0))))))))
195 (DApp False n (map (DV . Glob) (take i (genArgs 0))))))))
196 : [] -- mkApplyCase n 0 i
196 : [] -- mkApplyCase n 0 i
197 | otherwise = []
197 | otherwise = []
198− where dupdate tlarg x = x
198+ where dupdate tlarg x = DUpdate tlarg x
199
199
200toConsA :: [(Name, Int)] -> (Name, Int) -> [(Name, Int, EvalApply DAlt)]
200toConsA :: [(Name, Int)] -> (Name, Int) -> [(Name, Int, EvalApply DAlt)]
201toConsA ns (n, i)
201toConsA ns (n, i)
src/IRTS/Lang.hs+2
@@ -55,6 +55,8 @@ data PrimFn = LPlus ArithTy | LMinus ArithTy | LTimes ArithTy
55 -- Buffers
55 -- Buffers
56 | LAllocate
56 | LAllocate
57 | LAppendBuffer
57 | LAppendBuffer
58+ -- system info
59+ | LSystemInfo
58 -- Note that for Bits8 only Native endianness is actually used
60 -- Note that for Bits8 only Native endianness is actually used
59 -- and the user-exposed interface for Bits8 doesn't mention
61 -- and the user-exposed interface for Bits8 doesn't mention
60 -- endianness
62 -- endianness
src/IRTS/Simplified.hs+16−14
@@ -125,15 +125,17 @@ checkDefs ctxt (con@(n, DConstructor _ _ _) : xs)
125 return xs'
125 return xs'
126checkDefs ctxt ((n, DFun n' args exp) : xs)
126checkDefs ctxt ((n, DFun n' args exp) : xs)
127 = do let sexp = evalState (simplify True exp) (ctxt, 0)
127 = do let sexp = evalState (simplify True exp) (ctxt, 0)
128− (exp', locs) <- runStateT (scopecheck ctxt (zip args [0..]) sexp) (length args)
128+ (exp', locs) <- runStateT (scopecheck n ctxt (zip args [0..]) sexp) (length args)
129 xs' <- checkDefs ctxt xs
129 xs' <- checkDefs ctxt xs
130 return ((n, SFun n' args ((locs + 1) - length args) exp') : xs')
130 return ((n, SFun n' args ((locs + 1) - length args) exp') : xs')
131
131
132lvar v = do i <- get
132lvar v = do i <- get
133 put (max i v)
133 put (max i v)
134
134
135−scopecheck :: DDefs -> [(Name, Int)] -> SExp -> StateT Int TC SExp
135+scopecheck :: Name -> DDefs -> [(Name, Int)] -> SExp -> StateT Int TC SExp
136−scopecheck ctxt envTop tm = sc envTop tm where
136+scopecheck fn ctxt envTop tm = sc envTop tm where
137+ failsc err = fail $ "Codegen error in " ++ show fn ++ ":" ++ err
138+
137 sc env (SV (Glob n)) =
139 sc env (SV (Glob n)) =
138 case lookup n (reverse env) of -- most recent first
140 case lookup n (reverse env) of -- most recent first
139 Just i -> do lvar i; return (SV (Loc i))
141 Just i -> do lvar i; return (SV (Loc i))
@@ -141,20 +143,20 @@ scopecheck ctxt envTop tm = sc envTop tm where
141 Just (DConstructor _ i ar) ->
143 Just (DConstructor _ i ar) ->
142 if True -- ar == 0
144 if True -- ar == 0
143 then return (SCon i n [])
145 then return (SCon i n [])
144− else fail $ "Codegen error: Constructor " ++ show n ++
146+ else failsc $ "Constructor " ++ show n ++
145 " has arity " ++ show ar
147 " has arity " ++ show ar
146 Just _ -> return (SV (Glob n))
148 Just _ -> return (SV (Glob n))
147− Nothing -> fail $ "Codegen error: No such variable " ++ show n
149+ Nothing -> failsc $ "No such variable " ++ show n
148 sc env (SApp tc f args)
150 sc env (SApp tc f args)
149 = do args' <- mapM (scVar env) args
151 = do args' <- mapM (scVar env) args
150 case lookupCtxtExact f ctxt of
152 case lookupCtxtExact f ctxt of
151 Just (DConstructor n tag ar) ->
153 Just (DConstructor n tag ar) ->
152 if True -- (ar == length args)
154 if True -- (ar == length args)
153 then return $ SCon tag n args'
155 then return $ SCon tag n args'
154− else fail $ "Codegen error: Constructor " ++ show f ++
156+ else failsc $ "Constructor " ++ show f ++
155 " has arity " ++ show ar
157 " has arity " ++ show ar
156 Just _ -> return $ SApp tc f args'
158 Just _ -> return $ SApp tc f args'
157− Nothing -> fail $ "Codegen error: No such variable " ++ show f
159+ Nothing -> failsc $ "No such variable " ++ show f
158 sc env (SForeign l ty f args)
160 sc env (SForeign l ty f args)
159 = do args' <- mapM (\ (t, a) -> do a' <- scVar env a
161 = do args' <- mapM (\ (t, a) -> do a' <- scVar env a
160 return (t, a')) args
162 return (t, a')) args
@@ -165,9 +167,9 @@ scopecheck ctxt envTop tm = sc envTop tm where
165 Just (DConstructor n tag ar) ->
167 Just (DConstructor n tag ar) ->
166 if True -- (ar == length args)
168 if True -- (ar == length args)
167 then return $ SCon tag n args'
169 then return $ SCon tag n args'
168− else fail $ "Codegen error: Constructor " ++ show f ++
170+ else failsc $ "Constructor " ++ show f ++
169− " has arity " ++ show ar
171+ " has arity " ++ show ar
170− _ -> fail $ "Codegen error: No such constructor " ++ show f
172+ _ -> failsc $ "No such constructor " ++ show f
171 sc env (SProj e i)
173 sc env (SProj e i)
172 = do e' <- scVar env e
174 = do e' <- scVar env e
173 return (SProj e' i)
175 return (SProj e' i)
@@ -200,9 +202,9 @@ scopecheck ctxt envTop tm = sc envTop tm where
200 Just i -> do lvar i; return (Loc i)
202 Just i -> do lvar i; return (Loc i)
201 Nothing -> case lookupCtxtExact n ctxt of
203 Nothing -> case lookupCtxtExact n ctxt of
202 Just (DConstructor _ i ar) ->
204 Just (DConstructor _ i ar) ->
203− fail $ "Codegen error : can't pass constructor here"
205+ failsc $ "can't pass constructor here"
204 Just _ -> return (Glob n)
206 Just _ -> return (Glob n)
205− Nothing -> fail $ "Codegen error: No such variable " ++ show n ++
207+ Nothing -> failsc $ "No such variable " ++ show n ++
206 " in " ++ show tm ++ " " ++ show envTop
208 " in " ++ show tm ++ " " ++ show envTop
207 scVar _ x = return x
209 scVar _ x = return x
208
210
@@ -212,9 +214,9 @@ scopecheck ctxt envTop tm = sc envTop tm where
212 Just (DConstructor _ i ar) ->
214 Just (DConstructor _ i ar) ->
213 if True -- (length args == ar)
215 if True -- (length args == ar)
214 then return i
216 then return i
215− else fail $ "Codegen error: Constructor " ++ show n ++
217+ else failsc $ "Constructor " ++ show n ++
216 " has arity " ++ show ar
218 " has arity " ++ show ar
217− _ -> fail $ "Codegen error: No constructor " ++ show n
219+ _ -> failsc $ "No constructor " ++ show n
218 e' <- sc env' e
220 e' <- sc env' e
219 return (SConCase (length env) tag n args e')
221 return (SConCase (length env) tag n args e')
220 scalt env (SConstCase c e) = do e' <- sc env e
222 scalt env (SConstCase c e) = do e' <- sc env e
src/Idris/ASTUtils.hsnew file+134
@@ -0,0 +1,134 @@
1+module Idris.ASTUtils where
2+
3+-- This implements just a few basic lens-like concepts to ease state updates.
4+-- Similar to fclabels in approach, just without the extra dependency.
5+--
6+-- We don't include an explicit export list
7+-- because everything here is meant to be exported.
8+--
9+-- Short synopsis:
10+-- ---------------
11+--
12+-- f :: Idris ()
13+-- f = do
14+-- -- these two steps:
15+-- detaggable <- fgetState (opt_detaggable . ist_optimisation typeName)
16+-- fputState (opt_detaggable . ist_optimisation typeName) (not detaggable)
17+--
18+-- -- are equivalent to:
19+-- fmodifyState (opt_detaggable . ist_optimisation typeName) not
20+--
21+-- -- of course, the long accessor can be put in a variable;
22+-- -- everything is first-class
23+-- let detag n = opt_detaggable . ist_optimisation n
24+-- fputState (detag n1) True
25+-- fputState (detag n2) False
26+--
27+-- -- Note that all these operations handle missing items consistently
28+-- -- and transparently, as prescribed by the default values included
29+-- -- in the definitions of the ist_* functions.
30+-- --
31+-- -- Especially, it's no longer necessary to have initial values of
32+-- -- data structures copied (possibly inconsistently) all over the compiler.
33+
34+import Control.Category
35+import Control.Applicative
36+import Control.Monad.State.Class
37+import Data.Maybe
38+import Prelude hiding (id, (.))
39+
40+import Idris.Core.TT
41+import Idris.AbsSyntaxTree
42+
43+data Field rec fld = Field
44+ { fget :: rec -> fld
45+ , fset :: fld -> rec -> rec
46+ }
47+
48+fmodify :: Field rec fld -> (fld -> fld) -> rec -> rec
49+fmodify field f x = fset field (f $ fget field x) x
50+
51+instance Category Field where
52+ id = Field id const
53+ Field g2 s2 . Field g1 s1 = Field (g2 . g1) (\v2 x1 -> s1 (s2 v2 $ g1 x1) x1)
54+
55+fgetState :: MonadState s m => Field s a -> m a
56+fgetState field = gets $ fget field
57+
58+fputState :: MonadState s m => Field s a -> a -> m ()
59+fputState field x = fmodifyState field (const x)
60+
61+fmodifyState :: MonadState s m => Field s a -> (a -> a) -> m ()
62+fmodifyState field f = modify $ fmodify field f
63+
64+-- Exact-name context lookup; uses Nothing for deleted values (read+write!).
65+--
66+-- Reading a non-existing value yields Nothing,
67+-- writing Nothing deletes the value (if it existed).
68+ctxt_lookup :: Name -> Field (Ctxt a) (Maybe a)
69+ctxt_lookup n = Field
70+ { fget = lookupCtxtExact n
71+ , fset = \newVal -> case newVal of
72+ Just x -> addDef n x
73+ Nothing -> deleteDefExact n
74+ }
75+
76+-- Maybe-lens with a default value.
77+maybe_default :: a -> Field (Maybe a) a
78+maybe_default dflt = Field (fromMaybe dflt) (const . Just)
79+
80+
81+-----------------------------------
82+-- Individual records and fields --
83+-----------------------------------
84+--
85+-- These could probably be generated; let's use lazy addition for now.
86+--
87+
88+
89+-- OptInfo
90+----------
91+
92+-- the optimisation record for the given (exact) name
93+ist_optimisation :: Name -> Field IState OptInfo
94+ist_optimisation n =
95+ maybe_default Optimise
96+ { inaccessible = []
97+ , detaggable = False
98+ }
99+ . ctxt_lookup n
100+ . Field idris_optimisation (\v ist -> ist{ idris_optimisation = v })
101+
102+-- two fields of the optimisation record
103+opt_inaccessible :: Field OptInfo [(Int, Name)]
104+opt_inaccessible = Field inaccessible (\v opt -> opt{ inaccessible = v })
105+
106+opt_detaggable :: Field OptInfo Bool
107+opt_detaggable = Field detaggable (\v opt -> opt{ detaggable = v })
108+
109+
110+-- CGInfo
111+---------
112+
113+-- callgraph record for the given (exact) name
114+ist_callgraph :: Name -> Field IState CGInfo
115+ist_callgraph n =
116+ maybe_default CGInfo
117+ { argsdef = [], calls = [], scg = []
118+ , argsused = [], usedpos = []
119+ }
120+ . ctxt_lookup n
121+ . Field idris_callgraph (\v ist -> ist{ idris_callgraph = v })
122+
123+-- some fields of the CGInfo record
124+cg_usedpos :: Field CGInfo [(Int, [UsageReason])]
125+cg_usedpos = Field usedpos (\v cg -> cg{ usedpos = v })
126+
127+
128+-- Commandline flags
129+--------------------
130+
131+opts_idrisCmdline :: Field IState [Opt]
132+opts_idrisCmdline =
133+ Field opt_cmdline (\v opts -> opts{ opt_cmdline = v })
134+ . Field idris_options (\v ist -> ist{ idris_options = v })
src/Idris/AbsSyntax.hs+34−17
@@ -278,7 +278,7 @@ addNameHint ty n
278 ty' <- case lookupCtxtName ty (idris_implicits i) of
278 ty' <- case lookupCtxtName ty (idris_implicits i) of
279 [(tyn, _)] -> return tyn
279 [(tyn, _)] -> return tyn
280 [] -> throwError (NoSuchVariable ty)
280 [] -> throwError (NoSuchVariable ty)
281− tyns -> throwError (CantResolveAlts (map show (map fst tyns)))
281+ tyns -> throwError (CantResolveAlts (map fst tyns))
282 let ns' = case lookupCtxt ty' (idris_namehints i) of
282 let ns' = case lookupCtxt ty' (idris_namehints i) of
283 [ns] -> ns ++ [n]
283 [ns] -> ns ++ [n]
284 _ -> [n]
284 _ -> [n]
@@ -530,7 +530,7 @@ renderWidth = do iw <- getWidth
530
530
531
531
532type1Doc :: Doc OutputAnnotation
532type1Doc :: Doc OutputAnnotation
533−type1Doc = (annotate AnnConstType $ text "Type 1")
533+type1Doc = (annotate (AnnType "Type" "The type of types, one level up") $ text "Type 1")
534
534
535
535
536isetPrompt :: String -> Idris ()
536isetPrompt :: String -> Idris ()
@@ -538,6 +538,18 @@ isetPrompt p = do i <- getIState
538 case idris_outputmode i of
538 case idris_outputmode i of
539 IdeSlave n -> runIO . putStrLn $ convSExp "set-prompt" p n
539 IdeSlave n -> runIO . putStrLn $ convSExp "set-prompt" p n
540
540
541+-- | Tell clients how much was parsed and loaded
542+isetLoadedRegion :: Idris ()
543+isetLoadedRegion = do i <- getIState
544+ let span = idris_parsedSpan i
545+ case span of
546+ Just fc ->
547+ case idris_outputmode i of
548+ IdeSlave n ->
549+ runIO . putStrLn $
550+ convSExp "set-loaded-region" fc n
551+ Nothing -> return ()
552+
541setLogLevel :: Int -> Idris ()
553setLogLevel :: Int -> Idris ()
542setLogLevel l = do i <- getIState
554setLogLevel l = do i <- getIState
543 let opts = idris_options i
555 let opts = idris_options i
@@ -766,13 +778,14 @@ setColour :: ColourType -> IdrisColour -> Idris ()
766setColour ct c = do i <- getIState
778setColour ct c = do i <- getIState
767 let newTheme = setColour' ct c (idris_colourTheme i)
779 let newTheme = setColour' ct c (idris_colourTheme i)
768 putIState $ i { idris_colourTheme = newTheme }
780 putIState $ i { idris_colourTheme = newTheme }
769− where setColour' KeywordColour c t = t { keywordColour = c }
781+ where setColour' KeywordColour c t = t { keywordColour = c }
770− setColour' BoundVarColour c t = t { boundVarColour = c }
782+ setColour' BoundVarColour c t = t { boundVarColour = c }
771− setColour' ImplicitColour c t = t { implicitColour = c }
783+ setColour' ImplicitColour c t = t { implicitColour = c }
772− setColour' FunctionColour c t = t { functionColour = c }
784+ setColour' FunctionColour c t = t { functionColour = c }
773− setColour' TypeColour c t = t { typeColour = c }
785+ setColour' TypeColour c t = t { typeColour = c }
774− setColour' DataColour c t = t { dataColour = c }
786+ setColour' DataColour c t = t { dataColour = c }
775− setColour' PromptColour c t = t { promptColour = c }
787+ setColour' PromptColour c t = t { promptColour = c }
788+ setColour' PostulateColour c t = t { postulateColour = c }
776
789
777logLvl :: Int -> String -> Idris ()
790logLvl :: Int -> String -> Idris ()
778logLvl l str = do i <- getIState
791logLvl l str = do i <- getIState
@@ -937,7 +950,7 @@ expandParamsD rhsonly ist dec ps ns (PClauses fc opts n cs)
937 updateps yn nm [] = []
950 updateps yn nm [] = []
938 updateps yn nm (((a, t), i):as)
951 updateps yn nm (((a, t), i):as)
939 | (a `elem` nm) == yn = (a, t) : updateps yn nm as
952 | (a `elem` nm) == yn = (a, t) : updateps yn nm as
940− | otherwise = (sMN i (show n ++ "_u"), t) : updateps yn nm as
953+ | otherwise = (sMN i ('_' : show n ++ "_u"), t) : updateps yn nm as
941
954
942 removeBound lhs ns = ns \\ nub (bnames lhs)
955 removeBound lhs ns = ns \\ nub (bnames lhs)
943
956
@@ -947,6 +960,7 @@ expandParamsD rhsonly ist dec ps ns (PClauses fc opts n cs)
947 bnames (PDPair _ _ l Placeholder r) = bnames l ++ bnames r
960 bnames (PDPair _ _ l Placeholder r) = bnames l ++ bnames r
948 bnames _ = []
961 bnames _ = []
949
962
963+-- | Expands parameters defined in parameter and where blocks inside of declarations
950expandParamsD rhs ist dec ps ns (PData doc argDocs syn fc co pd)
964expandParamsD rhs ist dec ps ns (PData doc argDocs syn fc co pd)
951 = PData doc argDocs syn fc co (expandPData pd)
965 = PData doc argDocs syn fc co (expandPData pd)
952 where
966 where
@@ -959,12 +973,12 @@ expandParamsD rhs ist dec ps ns (PData doc argDocs syn fc co pd)
959 else PDatadecl n (expandParams dec ps ns [] ty) (map econ cons)
973 else PDatadecl n (expandParams dec ps ns [] ty) (map econ cons)
960 econ (doc, argDocs, n, t, fc, fs)
974 econ (doc, argDocs, n, t, fc, fs)
961 = (doc, argDocs, dec n, piBindp expl ps (expandParams dec ps ns [] t), fc, fs)
975 = (doc, argDocs, dec n, piBindp expl ps (expandParams dec ps ns [] t), fc, fs)
962−expandParamsD rhs ist dec ps ns (PRecord doc syn fc tn tty cdoc cn cty)
976+expandParamsD rhs ist dec ps ns (PRecord doc syn fc tn tty opts cdoc cn cty)
963 = if tn `elem` ns
977 = if tn `elem` ns
964 then PRecord doc syn fc (dec tn) (piBind ps (expandParams dec ps ns [] tty))
978 then PRecord doc syn fc (dec tn) (piBind ps (expandParams dec ps ns [] tty))
965− cdoc (dec cn) conty
979+ opts cdoc (dec cn) conty
966 else PRecord doc syn fc (dec tn) (expandParams dec ps ns [] tty)
980 else PRecord doc syn fc (dec tn) (expandParams dec ps ns [] tty)
967− cdoc (dec cn) conty
981+ opts cdoc (dec cn) conty
968 where conty = piBindp expl ps (expandParams dec ps ns [] cty)
982 where conty = piBindp expl ps (expandParams dec ps ns [] cty)
969expandParamsD rhs ist dec ps ns (PParams f params pds)
983expandParamsD rhs ist dec ps ns (PParams f params pds)
970 = PParams f (ps ++ map (mapsnd (expandParams dec ps ns [])) params)
984 = PParams f (ps ++ map (mapsnd (expandParams dec ps ns [])) params)
@@ -972,11 +986,12 @@ expandParamsD rhs ist dec ps ns (PParams f params pds)
972-- (map (expandParamsD ist dec ps ns) pds)
986-- (map (expandParamsD ist dec ps ns) pds)
973expandParamsD rhs ist dec ps ns (PMutual f pds)
987expandParamsD rhs ist dec ps ns (PMutual f pds)
974 = PMutual f (map (expandParamsD rhs ist dec ps ns) pds)
988 = PMutual f (map (expandParamsD rhs ist dec ps ns) pds)
975−expandParamsD rhs ist dec ps ns (PClass doc info f cs n params decls)
989+expandParamsD rhs ist dec ps ns (PClass doc info f cs n params pDocs decls)
976 = PClass doc info f
990 = PClass doc info f
977 (map (expandParams dec ps ns []) cs)
991 (map (expandParams dec ps ns []) cs)
978 n
992 n
979 (map (mapsnd (expandParams dec ps ns [])) params)
993 (map (mapsnd (expandParams dec ps ns [])) params)
994+ pDocs
980 (map (expandParamsD rhs ist dec ps ns) decls)
995 (map (expandParamsD rhs ist dec ps ns) decls)
981expandParamsD rhs ist dec ps ns (PInstance info f cs n params ty cn decls)
996expandParamsD rhs ist dec ps ns (PInstance info f cs n params ty cn decls)
982 = PInstance info f
997 = PInstance info f
@@ -1315,9 +1330,11 @@ addImpl' inpat env infns ist ptm
1315 as' = map (fmap (ai env ds)) as in
1330 as' = map (fmap (ai env ds)) as in
1316 mkPApp fc 1 f' as'
1331 mkPApp fc 1 f' as'
1317 ai env ds (PCase fc c os)
1332 ai env ds (PCase fc c os)
1318− = let c' = ai env ds c
1333+ = let c' = ai env ds c in
1319− os' = map (pmap (ai env ds)) os in
1334+ -- leave os alone, because they get lifted into a new pattern match
1335+ -- definition which is passed through addImpl again with more scope
1336+ -- information
1320− PCase fc c' os'
1337+ PCase fc c' os
1321 ai env ds (PLam n ty sc)
1338 ai env ds (PLam n ty sc)
1322 = let ty' = ai env ds ty
1339 = let ty' = ai env ds ty
1323 sc' = ai ((n, Just ty):env) ds sc in
1340 sc' = ai ((n, Just ty):env) ds sc in
src/Idris/AbsSyntaxTree.hs+256−139
@@ -31,6 +31,7 @@ import qualified Data.Map as M
31import Data.Either
31import Data.Either
32import qualified Data.Set as S
32import qualified Data.Set as S
33import Data.Word (Word)
33import Data.Word (Word)
34+import Data.Maybe (fromMaybe)
34
35
35import Debug.Trace
36import Debug.Trace
36
37
@@ -94,6 +95,28 @@ defaultOpts = IOption { opt_logLevel = 0
94 , opt_autoSolve = True
95 , opt_autoSolve = True
95 }
96 }
96
97
98+data PPOption = PPOption {
99+ ppopt_impl :: Bool -- ^^ whether to show implicits
100+} deriving (Show)
101+
102+-- | Pretty printing options with default verbosity.
103+defaultPPOption :: PPOption
104+defaultPPOption = PPOption { ppopt_impl = False }
105+
106+-- | Pretty printing options with the most verbosity.
107+verbosePPOption :: PPOption
108+verbosePPOption = PPOption { ppopt_impl = True }
109+
110+-- | Get pretty printing options from the big options record.
111+ppOption :: IOption -> PPOption
112+ppOption opt = PPOption {
113+ ppopt_impl = opt_showimp opt
114+}
115+
116+-- | Get pretty printing options from an idris state record.
117+ppOptionIst :: IState -> PPOption
118+ppOptionIst = ppOption . idris_options
119+
97data LanguageExt = TypeProviders | ErrorReflection deriving (Show, Eq, Read, Ord)
120data LanguageExt = TypeProviders | ErrorReflection deriving (Show, Eq, Read, Ord)
98
121
99-- | The output mode in use
122-- | The output mode in use
@@ -124,8 +147,9 @@ data IState = IState {
124 idris_calledgraph :: Ctxt [Name],
147 idris_calledgraph :: Ctxt [Name],
125 idris_docstrings :: Ctxt (Docstring, [(Name, Docstring)]),
148 idris_docstrings :: Ctxt (Docstring, [(Name, Docstring)]),
126 idris_tyinfodata :: Ctxt TIData,
149 idris_tyinfodata :: Ctxt TIData,
127− idris_totcheck :: [(FC, Name)], -- names to check totality on
150+ idris_totcheck :: [(FC, Name)], -- names to check totality on
128 idris_defertotcheck :: [(FC, Name)], -- names to check at the end
151 idris_defertotcheck :: [(FC, Name)], -- names to check at the end
152+ idris_totcheckfail :: [(FC, String)],
129 idris_options :: IOption,
153 idris_options :: IOption,
130 idris_name :: Int,
154 idris_name :: Int,
131 idris_lineapps :: [((FilePath, Int), PTerm)],
155 idris_lineapps :: [((FilePath, Int), PTerm)],
@@ -150,6 +174,7 @@ data IState = IState {
150 indent_stack :: [Int],
174 indent_stack :: [Int],
151 brace_stack :: [Maybe Int],
175 brace_stack :: [Maybe Int],
152 lastTokenSpan :: Maybe FC, -- ^ What was the span of the latest token parsed?
176 lastTokenSpan :: Maybe FC, -- ^ What was the span of the latest token parsed?
177+ idris_parsedSpan :: Maybe FC,
153 hide_list :: [(Name, Maybe Accessibility)],
178 hide_list :: [(Name, Maybe Accessibility)],
154 default_access :: Accessibility,
179 default_access :: Accessibility,
155 default_total :: Bool,
180 default_total :: Bool,
@@ -166,7 +191,9 @@ data IState = IState {
166 idris_function_errorhandlers :: Ctxt (M.Map Name (S.Set Name)), -- ^ Specific error handlers
191 idris_function_errorhandlers :: Ctxt (M.Map Name (S.Set Name)), -- ^ Specific error handlers
167 module_aliases :: M.Map [T.Text] [T.Text],
192 module_aliases :: M.Map [T.Text] [T.Text],
168 idris_consolewidth :: ConsoleWidth, -- ^ How many chars wide is the console?
193 idris_consolewidth :: ConsoleWidth, -- ^ How many chars wide is the console?
169− idris_postulates :: S.Set Name
194+ idris_postulates :: S.Set Name,
195+ idris_whocalls :: Maybe (M.Map Name [Name]),
196+ idris_callswho :: Maybe (M.Map Name [Name])
170 }
197 }
171
198
172data SizeChange = Smaller | Same | Bigger | Unknown
199data SizeChange = Smaller | Same | Bigger | Unknown
@@ -177,12 +204,13 @@ deriving instance NFData SizeChange
177!-}
204!-}
178
205
179type SCGEntry = (Name, [Maybe (Int, SizeChange)])
206type SCGEntry = (Name, [Maybe (Int, SizeChange)])
207+type UsageReason = (Name, Int) -- fn_name, its_arg_number
180
208
181data CGInfo = CGInfo { argsdef :: [Name],
209data CGInfo = CGInfo { argsdef :: [Name],
182 calls :: [(Name, [[Name]])],
210 calls :: [(Name, [[Name]])],
183 scg :: [SCGEntry],
211 scg :: [SCGEntry],
184 argsused :: [Name],
212 argsused :: [Name],
185− usedpos :: [(Int, [(Name, Int)])] } -- (used_arg#, [(using_fn, its_arg#)])
213+ usedpos :: [(Int, [UsageReason])] }
186 deriving Show
214 deriving Show
187{-!
215{-!
188deriving instance Binary CGInfo
216deriving instance Binary CGInfo
@@ -227,6 +255,8 @@ data IBCWrite = IBCFix FixDecl
227 | IBCErrorHandler Name
255 | IBCErrorHandler Name
228 | IBCFunctionErrorHandler Name Name Name
256 | IBCFunctionErrorHandler Name Name Name
229 | IBCPostulate Name
257 | IBCPostulate Name
258+ | IBCTotCheckErr FC String
259+ | IBCParsedRegion FC
230 deriving Show
260 deriving Show
231
261
232-- | The initial state for the compiler
262-- | The initial state for the compiler
@@ -235,10 +265,10 @@ idrisInit = IState initContext [] [] emptyContext emptyContext emptyContext
235 emptyContext emptyContext emptyContext emptyContext
265 emptyContext emptyContext emptyContext emptyContext
236 emptyContext emptyContext emptyContext emptyContext
266 emptyContext emptyContext emptyContext emptyContext
237 emptyContext emptyContext
267 emptyContext emptyContext
238− [] [] defaultOpts 6 [] [] [] [] [] [] [] [] [] [] [] [] []
268+ [] [] [] defaultOpts 6 [] [] [] [] [] [] [] [] [] [] [] [] []
239− [] [] Nothing [] Nothing [] [] Nothing [] Hidden False [] Nothing [] [] RawOutput
269+ [] [] Nothing [] Nothing [] [] Nothing Nothing [] Hidden False [] Nothing [] [] RawOutput
240 True defaultTheme stdout [] (0, emptyContext) emptyContext M.empty
270 True defaultTheme stdout [] (0, emptyContext) emptyContext M.empty
241− AutomaticWidth S.empty
271+ AutomaticWidth S.empty Nothing Nothing
242
272
243-- | The monad for the main REPL - reading and processing files and updating
273-- | The monad for the main REPL - reading and processing files and updating
244-- global state (hence the IO inner monad).
274-- global state (hence the IO inner monad).
@@ -260,10 +290,10 @@ data Command = Quit
260 | Help
290 | Help
261 | Eval PTerm
291 | Eval PTerm
262 | Check PTerm
292 | Check PTerm
263− | DocStr Name
293+ | DocStr (Either Name Const)
264 | TotCheck Name
294 | TotCheck Name
265 | Reload
295 | Reload
266− | Load FilePath
296+ | Load FilePath (Maybe Int) -- up to maximum line number
267 | ChangeDirectory FilePath
297 | ChangeDirectory FilePath
268 | ModImport String
298 | ModImport String
269 | Edit
299 | Edit
@@ -282,7 +312,6 @@ data Command = Quit
282 | HNF PTerm
312 | HNF PTerm
283 | TestInline PTerm
313 | TestInline PTerm
284 | Defn Name
314 | Defn Name
285− | Info Name
286 | Missing Name
315 | Missing Name
287 | DynamicLink FilePath
316 | DynamicLink FilePath
288 | ListDynamic
317 | ListDynamic
@@ -294,7 +323,10 @@ data Command = Quit
294 | AddProofClauseFrom Bool Int Name
323 | AddProofClauseFrom Bool Int Name
295 | AddMissing Bool Int Name
324 | AddMissing Bool Int Name
296 | MakeWith Bool Int Name
325 | MakeWith Bool Int Name
326+ | MakeLemma Bool Int Name
297− | DoProofSearch Bool Int Name [Name]
327+ | DoProofSearch Bool Bool Int Name [Name]
328+ -- ^ the first bool is whether to update,
329+ -- the second is whether to search recursively (i.e. for the arguments)
298 | SetOpt Opt
330 | SetOpt Opt
299 | UnsetOpt Opt
331 | UnsetOpt Opt
300 | NOP
332 | NOP
@@ -304,10 +336,12 @@ data Command = Quit
304 | ListErrorHandlers
336 | ListErrorHandlers
305 | SetConsoleWidth ConsoleWidth
337 | SetConsoleWidth ConsoleWidth
306 | Apropos String
338 | Apropos String
339+ | WhoCalls Name
340+ | CallsWho Name
341+ | MakeDoc String -- IdrisDoc
342+ | Warranty
307
343
308data Opt = Filename String
344data Opt = Filename String
309− | Ver
310− | Usage
311 | Quiet
345 | Quiet
312 | NoBanner
346 | NoBanner
313 | ColourREPL Bool
347 | ColourREPL Bool
@@ -338,6 +372,8 @@ data Opt = Filename String
338 | PkgClean String
372 | PkgClean String
339 | PkgCheck String
373 | PkgCheck String
340 | PkgREPL String
374 | PkgREPL String
375+ | PkgMkDoc String -- IdrisDoc
376+ | PkgTest String
341 | WarnOnly
377 | WarnOnly
342 | Pkg String
378 | Pkg String
343 | BCAsm String
379 | BCAsm String
@@ -347,6 +383,7 @@ data Opt = Filename String
347 | OutputTy OutputType
383 | OutputTy OutputType
348 | Extension LanguageExt
384 | Extension LanguageExt
349 | InterpretScript String
385 | InterpretScript String
386+ | EvalExpr String
350 | TargetTriple String
387 | TargetTriple String
351 | TargetCPU String
388 | TargetCPU String
352 | OptLevel Word
389 | OptLevel Word
@@ -429,7 +466,7 @@ data FnOpt = Inlinable -- always evaluate when simplifying
429 | Implicit -- implicit coercion
466 | Implicit -- implicit coercion
430 | CExport String -- export, with a C name
467 | CExport String -- export, with a C name
431 | ErrorHandler -- ^^ an error handler for use with the ErrorReflection extension
468 | ErrorHandler -- ^^ an error handler for use with the ErrorReflection extension
432− | ErrorReverse -- ^^ attempt to reverse normalise before showing in error
469+ | ErrorReverse -- ^^ attempt to reverse normalise before showing in error
433 | Reflection -- a reflecting function, compile-time only
470 | Reflection -- a reflecting function, compile-time only
434 | Specialise [(Name, Maybe Int)] -- specialise it, freeze these names
471 | Specialise [(Name, Maybe Int)] -- specialise it, freeze these names
435 deriving (Show, Eq)
472 deriving (Show, Eq)
@@ -456,10 +493,11 @@ data DataOpt = Codata -- Set if the the data-type is coinductive
456type DataOpts = [DataOpt]
493type DataOpts = [DataOpt]
457
494
458-- | Type provider - what to provide
495-- | Type provider - what to provide
459−data ProvideWhat = ProvTerm -- ^ only allow providing terms
496+data ProvideWhat' t = ProvTerm t t -- ^ the first is the goal type, the second is the term
460− | ProvPostulate -- ^ only allow postulates
497+ | ProvPostulate t -- ^ goal type must be Type, so only term
461− | ProvAny -- ^ either is ok
462− deriving (Show, Eq)
498+ deriving (Show, Eq, Functor)
499+
500+type ProvideWhat = ProvideWhat' PTerm
463
501
464-- | Top-level declarations such as compiler directives, definitions,
502-- | Top-level declarations such as compiler directives, definitions,
465-- datatypes and typeclasses.
503-- datatypes and typeclasses.
@@ -472,11 +510,12 @@ data PDecl' t
472 | PData Docstring [(Name, Docstring)] SyntaxInfo FC DataOpts (PData' t) -- ^ Data declaration.
510 | PData Docstring [(Name, Docstring)] SyntaxInfo FC DataOpts (PData' t) -- ^ Data declaration.
473 | PParams FC [(Name, t)] [PDecl' t] -- ^ Params block
511 | PParams FC [(Name, t)] [PDecl' t] -- ^ Params block
474 | PNamespace String [PDecl' t] -- ^ New namespace
512 | PNamespace String [PDecl' t] -- ^ New namespace
475− | PRecord Docstring SyntaxInfo FC Name t Docstring Name t -- ^ Record declaration
513+ | PRecord Docstring SyntaxInfo FC Name t DataOpts Docstring Name t -- ^ Record declaration
476 | PClass Docstring SyntaxInfo FC
514 | PClass Docstring SyntaxInfo FC
477 [t] -- constraints
515 [t] -- constraints
478 Name
516 Name
479 [(Name, t)] -- parameters
517 [(Name, t)] -- parameters
518+ [(Name, Docstring)] -- parameter docstrings
480 [PDecl' t] -- declarations
519 [PDecl' t] -- declarations
481 -- ^ Type class: arguments are documentation, syntax info, source location, constraints,
520 -- ^ Type class: arguments are documentation, syntax info, source location, constraints,
482 -- class name, parameters, method declarations
521 -- class name, parameters, method declarations
@@ -492,7 +531,7 @@ data PDecl' t
492 | PSyntax FC Syntax -- ^ Syntax definition
531 | PSyntax FC Syntax -- ^ Syntax definition
493 | PMutual FC [PDecl' t] -- ^ Mutual block
532 | PMutual FC [PDecl' t] -- ^ Mutual block
494 | PDirective (Idris ()) -- ^ Compiler directive. The parser inserts the corresponding action in the Idris monad.
533 | PDirective (Idris ()) -- ^ Compiler directive. The parser inserts the corresponding action in the Idris monad.
495− | PProvider SyntaxInfo FC ProvideWhat Name t t -- ^ Type provider. The first t is the type, the second is the term
534+ | PProvider SyntaxInfo FC (ProvideWhat' t) Name -- ^ Type provider. The first t is the type, the second is the term
496 | PTransform FC Bool t t -- ^ Source-to-source transformation rule. If
535 | PTransform FC Bool t t -- ^ Source-to-source transformation rule. If
497 -- bool is True, lhs and rhs must be convertible
536 -- bool is True, lhs and rhs must be convertible
498 deriving Functor
537 deriving Functor
@@ -558,8 +597,8 @@ declared (PData _ _ _ _ _ (PDatadecl n _ ts)) = n : map fstt ts
558declared (PData _ _ _ _ _ (PLaterdecl n _)) = [n]
597declared (PData _ _ _ _ _ (PLaterdecl n _)) = [n]
559declared (PParams _ _ ds) = concatMap declared ds
598declared (PParams _ _ ds) = concatMap declared ds
560declared (PNamespace _ ds) = concatMap declared ds
599declared (PNamespace _ ds) = concatMap declared ds
561−declared (PRecord _ _ _ n _ _ c _) = [n, c]
600+declared (PRecord _ _ _ n _ _ _ c _) = [n, c]
562−declared (PClass _ _ _ _ n _ ms) = n : concatMap declared ms
601+declared (PClass _ _ _ _ n _ _ ms) = n : concatMap declared ms
563declared (PInstance _ _ _ _ _ _ _ _) = []
602declared (PInstance _ _ _ _ _ _ _ _) = []
564declared (PDSL n _) = [n]
603declared (PDSL n _) = [n]
565declared (PSyntax _ _) = []
604declared (PSyntax _ _) = []
@@ -572,13 +611,13 @@ tldeclared (PFix _ _ _) = []
572tldeclared (PTy _ _ _ _ _ n t) = [n]
611tldeclared (PTy _ _ _ _ _ n t) = [n]
573tldeclared (PPostulate _ _ _ _ n t) = [n]
612tldeclared (PPostulate _ _ _ _ n t) = [n]
574tldeclared (PClauses _ _ n _) = [] -- not a declaration
613tldeclared (PClauses _ _ n _) = [] -- not a declaration
575−tldeclared (PRecord _ _ _ n _ _ c _) = [n, c]
614+tldeclared (PRecord _ _ _ n _ _ _ c _) = [n, c]
576tldeclared (PData _ _ _ _ _ (PDatadecl n _ ts)) = n : map fstt ts
615tldeclared (PData _ _ _ _ _ (PDatadecl n _ ts)) = n : map fstt ts
577 where fstt (_, _, a, _, _, _) = a
616 where fstt (_, _, a, _, _, _) = a
578tldeclared (PParams _ _ ds) = []
617tldeclared (PParams _ _ ds) = []
579tldeclared (PMutual _ ds) = concatMap tldeclared ds
618tldeclared (PMutual _ ds) = concatMap tldeclared ds
580tldeclared (PNamespace _ ds) = concatMap tldeclared ds
619tldeclared (PNamespace _ ds) = concatMap tldeclared ds
581−tldeclared (PClass _ _ _ _ n _ ms) = concatMap tldeclared ms
620+tldeclared (PClass _ _ _ _ n _ _ ms) = concatMap tldeclared ms
582tldeclared (PInstance _ _ _ _ _ _ _ _) = []
621tldeclared (PInstance _ _ _ _ _ _ _ _) = []
583tldeclared _ = []
622tldeclared _ = []
584
623
@@ -593,8 +632,8 @@ defined (PData _ _ _ _ _ (PDatadecl n _ ts)) = n : map fstt ts
593defined (PData _ _ _ _ _ (PLaterdecl n _)) = []
632defined (PData _ _ _ _ _ (PLaterdecl n _)) = []
594defined (PParams _ _ ds) = concatMap defined ds
633defined (PParams _ _ ds) = concatMap defined ds
595defined (PNamespace _ ds) = concatMap defined ds
634defined (PNamespace _ ds) = concatMap defined ds
596−defined (PRecord _ _ _ n _ _ c _) = [n, c]
635+defined (PRecord _ _ _ n _ _ _ c _) = [n, c]
597−defined (PClass _ _ _ _ n _ ms) = n : concatMap defined ms
636+defined (PClass _ _ _ _ n _ _ ms) = n : concatMap defined ms
598defined (PInstance _ _ _ _ _ _ _ _) = []
637defined (PInstance _ _ _ _ _ _ _ _) = []
599defined (PDSL n _) = [n]
638defined (PDSL n _) = [n]
600defined (PSyntax _ _) = []
639defined (PSyntax _ _) = []
@@ -631,26 +670,26 @@ data PTerm = PQuote Raw
631 | PInferRef FC Name -- ^ A name to be defined later
670 | PInferRef FC Name -- ^ A name to be defined later
632 | PPatvar FC Name
671 | PPatvar FC Name
633 | PLam Name PTerm PTerm
672 | PLam Name PTerm PTerm
634− | PPi Plicity Name PTerm PTerm
673+ | PPi Plicity Name PTerm PTerm -- ^ (n : t1) -> t2
635 | PLet Name PTerm PTerm PTerm
674 | PLet Name PTerm PTerm PTerm
636 | PTyped PTerm PTerm -- ^ Term with explicit type
675 | PTyped PTerm PTerm -- ^ Term with explicit type
637− | PApp FC PTerm [PArg]
676+ | PApp FC PTerm [PArg] -- ^ e.g. IO (), List Char, length x
638 | PAppBind FC PTerm [PArg] -- ^ implicitly bound application
677 | PAppBind FC PTerm [PArg] -- ^ implicitly bound application
639 | PMatchApp FC Name -- ^ Make an application by type matching
678 | PMatchApp FC Name -- ^ Make an application by type matching
640 | PCase FC PTerm [(PTerm, PTerm)]
679 | PCase FC PTerm [(PTerm, PTerm)]
641− | PTrue FC PunInfo
680+ | PTrue FC PunInfo -- ^ Unit type..?
642− | PFalse FC
681+ | PFalse FC -- ^ _|_
643 | PRefl FC PTerm
682 | PRefl FC PTerm
644 | PResolveTC FC
683 | PResolveTC FC
645− | PEq FC PTerm PTerm
684+ | PEq FC PTerm PTerm -- ^ Equality type: A = B
646 | PRewrite FC PTerm PTerm (Maybe PTerm)
685 | PRewrite FC PTerm PTerm (Maybe PTerm)
647 | PPair FC PunInfo PTerm PTerm
686 | PPair FC PunInfo PTerm PTerm
648 | PDPair FC PunInfo PTerm PTerm PTerm
687 | PDPair FC PunInfo PTerm PTerm PTerm
649 | PAlternative Bool [PTerm] -- True if only one may work
688 | PAlternative Bool [PTerm] -- True if only one may work
650 | PHidden PTerm -- ^ Irrelevant or hidden pattern
689 | PHidden PTerm -- ^ Irrelevant or hidden pattern
651− | PType
690+ | PType -- ^ 'Type' type
652 | PGoal FC PTerm Name PTerm
691 | PGoal FC PTerm Name PTerm
653− | PConstant Const
692+ | PConstant Const -- ^ Builtin types
654 | Placeholder
693 | Placeholder
655 | PDoBlock [PDo]
694 | PDoBlock [PDo]
656 | PIdiom FC PTerm
695 | PIdiom FC PTerm
@@ -699,13 +738,14 @@ mapPT f t = f (mpt t) where
699
738
700
739
701data PTactic' t = Intro [Name] | Intros | Focus Name
740data PTactic' t = Intro [Name] | Intros | Focus Name
702− | Refine Name [Bool] | Rewrite t
741+ | Refine Name [Bool] | Rewrite t | DoUnify
703 | Induction Name
742 | Induction Name
704 | Equiv t
743 | Equiv t
705 | MatchRefine Name
744 | MatchRefine Name
706 | LetTac Name t | LetTacTy Name t t
745 | LetTac Name t | LetTacTy Name t t
707 | Exact t | Compute | Trivial | TCInstance
746 | Exact t | Compute | Trivial | TCInstance
708− | ProofSearch (Maybe Name) [Name]
747+ | ProofSearch Bool Bool Int (Maybe Name) [Name]
748+ -- ^ the bool is whether to search recursively
709 | Solve
749 | Solve
710 | Attack
750 | Attack
711 | ProofState | ProofTerm | Undo
751 | ProofState | ProofTerm | Undo
@@ -831,10 +871,10 @@ deriving instance NFData ClassInfo
831-- Type inference data
871-- Type inference data
832
872
833data TIData = TIPartial -- ^ a function with a partially defined type
873data TIData = TIPartial -- ^ a function with a partially defined type
834− | TISolution [Term] -- ^ possible solutions to a metavariable in a type
874+ | TISolution [Term] -- ^ possible solutions to a metavariable in a type
835 deriving Show
875 deriving Show
836
876
837−data OptInfo = Optimise { inaccessible :: [(Int,Name)], -- includes names for error reporting
877+data OptInfo = Optimise { inaccessible :: [(Int,Name)], -- includes names for error reporting
838 detaggable :: Bool }
878 detaggable :: Bool }
839 deriving Show
879 deriving Show
840{-!
880{-!
@@ -846,7 +886,8 @@ deriving instance NFData OptInfo
846data TypeInfo = TI { con_names :: [Name],
886data TypeInfo = TI { con_names :: [Name],
847 codata :: Bool,
887 codata :: Bool,
848 data_opts :: DataOpts,
888 data_opts :: DataOpts,
849− param_pos :: [Int] }
889+ param_pos :: [Int],
890+ mutual_types :: [Name] }
850 deriving Show
891 deriving Show
851{-!
892{-!
852deriving instance Binary TypeInfo
893deriving instance Binary TypeInfo
@@ -924,6 +965,8 @@ data SyntaxInfo = Syn { using :: [Using],
924 decoration :: Name -> Name,
965 decoration :: Name -> Name,
925 inPattern :: Bool,
966 inPattern :: Bool,
926 implicitAllowed :: Bool,
967 implicitAllowed :: Bool,
968+ maxline :: Maybe Int,
969+ mut_nesting :: Int,
927 dsl_info :: DSL }
970 dsl_info :: DSL }
928 deriving Show
971 deriving Show
929{-!
972{-!
@@ -931,7 +974,7 @@ deriving instance NFData SyntaxInfo
931deriving instance Binary SyntaxInfo
974deriving instance Binary SyntaxInfo
932!-}
975!-}
933
976
934−defaultSyntax = Syn [] [] [] [] id False False initDSL
977+defaultSyntax = Syn [] [] [] [] id False False Nothing 0 initDSL
935
978
936expandNS :: SyntaxInfo -> Name -> Name
979expandNS :: SyntaxInfo -> Name -> Name
937expandNS syn n@(NS _ _) = n
980expandNS syn n@(NS _ _) = n
@@ -975,52 +1018,92 @@ primNames = [unitTy, unitCon,
975 falseTy, pairTy, pairCon,
1018 falseTy, pairTy, pairCon,
976 eqTy, eqCon, inferTy, inferCon]
1019 eqTy, eqCon, inferTy, inferCon]
977
1020
1021+unitDoc = parseDocstring . T.pack $ "The canonical single-element type, also known as the trivially true proposition."
978unitTy = sMN 0 "__Unit"
1022unitTy = sMN 0 "__Unit"
979unitCon = sMN 0 "__II"
1023unitCon = sMN 0 "__II"
980unitDecl = PDatadecl unitTy PType
1024unitDecl = PDatadecl unitTy PType
981− [(emptyDocstring, [], unitCon, PRef bi unitTy, bi, [])]
1025+ [(parseDocstring . T.pack $ "The trivial constructor for `()`. ", [], unitCon, PRef bi unitTy, bi, [])]
982unitOpts = [DefaultEliminator]
1026unitOpts = [DefaultEliminator]
983
1027
1028+falseDoc = parseDocstring . T.pack $
1029+ "The empty type, also known as the trivially false proposition." ++
1030+ "\n\n" ++
1031+ "Use `FalseElim` or `absurd` to prove anything if you have a variable " ++
1032+ "of type `_|_` in scope."
984falseTy = sMN 0 "__False"
1033falseTy = sMN 0 "__False"
985falseDecl = PDatadecl falseTy PType []
1034falseDecl = PDatadecl falseTy PType []
986falseOpts = []
1035falseOpts = []
987
1036
1037+pairDoc = parseDocstring . T.pack $ "The non-dependent pair type, also known as conjunction."
988pairTy = sMN 0 "__Pair"
1038pairTy = sMN 0 "__Pair"
989pairCon = sMN 0 "__MkPair"
1039pairCon = sMN 0 "__MkPair"
990pairDecl = PDatadecl pairTy (piBind [(n "A", PType), (n "B", PType)] PType)
1040pairDecl = PDatadecl pairTy (piBind [(n "A", PType), (n "B", PType)] PType)
1041+ [(pairConDoc, pairConParamDoc,
991− [(emptyDocstring, [], pairCon, PPi impl (n "A") PType (
1042+ pairCon, PPi impl (n "A") PType (
992− PPi impl (n "B") PType (
1043+ PPi impl (n "B") PType (
993− PPi expl (n "a") (PRef bi (n "A")) (
1044+ PPi expl (n "a") (PRef bi (n "A")) (
994− PPi expl (n "b") (PRef bi (n "B"))
1045+ PPi expl (n "b") (PRef bi (n "B"))
995− (PApp bi (PRef bi pairTy) [pexp (PRef bi (n "A")),
1046+ (PApp bi (PRef bi pairTy) [pexp (PRef bi (n "A")),
996− pexp (PRef bi (n "B"))])))), bi, [])]
1047+ pexp (PRef bi (n "B"))])))), bi, [])]
997 where n a = sMN 0 a
1048 where n a = sMN 0 a
1049+ pairConDoc = parseDocstring . T.pack $ "A pair of elements"
1050+ pairConParamDoc = [(n "a", parseDocstring . T.pack $ "the left element of the pair"),
1051+ (n "b", parseDocstring . T.pack $ "the right element of the pair")]
998pairOpts = []
1052pairOpts = []
1053+pairParamDoc = [(n "A", parseDocstring . T.pack $ "the type of the left elements in the pair"),
1054+ (n "B", parseDocstring . T.pack $ "the type of the left elements in the pair")]
1055+ where n a = sMN 0 a
999
1056
1000eqTy = sUN "="
1057eqTy = sUN "="
1001eqCon = sUN "refl"
1058eqCon = sUN "refl"
1059+eqDoc = parseDocstring . T.pack $
1060+ "The propositional equality type. A proof that `x` = `y`." ++
1061+ "\n\n" ++
1062+ "To use such a proof, pattern-match on it, and the two equal things will " ++
1063+ "then need to be the _same_ pattern." ++
1064+ "\n\n" ++
1065+ "**Note**: Idris's equality type is _heterogeneous_, which means that it " ++
1066+ "is possible to state equalities between values of potentially different " ++
1067+ "types. This is sometimes referred to in the literature as \"John Major\" " ++
1068+ "equality." ++
1069+ "\n\n" ++
1070+ "Thus, if Idris can't infer the type of one side of the equality, then " ++
1071+ "you may need to annotate it. See the function `the`."
1072+
1002eqDecl = PDatadecl eqTy (piBind [(n "A", PType), (n "B", PType),
1073eqDecl = PDatadecl eqTy (piBind [(n "A", PType), (n "B", PType),
1003 (n "x", PRef bi (n "A")), (n "y", PRef bi (n "B"))]
1074 (n "x", PRef bi (n "A")), (n "y", PRef bi (n "B"))]
1004 PType)
1075 PType)
1076+ [(reflDoc, reflParamDoc,
1005− [(emptyDocstring, [], eqCon, PPi impl (n "A") PType (
1077+ eqCon, PPi impl (n "A") PType (
1006− PPi impl (n "x") (PRef bi (n "A"))
1078+ PPi impl (n "x") (PRef bi (n "A"))
1007− (PApp bi (PRef bi eqTy) [pimp (n "A") Placeholder False,
1079+ (PApp bi (PRef bi eqTy) [pimp (n "A") Placeholder False,
1008− pimp (n "B") Placeholder False,
1080+ pimp (n "B") Placeholder False,
1009− pexp (PRef bi (n "x")),
1081+ pexp (PRef bi (n "x")),
1010− pexp (PRef bi (n "x"))])), bi, [])]
1082+ pexp (PRef bi (n "x"))])), bi, [])]
1083+ where n a = sMN 0 a
1084+ reflDoc = parseDocstring . T.pack $
1085+ "A proof that `x` in fact equals `x`. To construct this, you must have already " ++
1086+ "shown that both sides are in fact equal."
1087+ reflParamDoc = [(n "A", parseDocstring . T.pack $ "the type at which the equality is proven"),
1088+ (n "x", parseDocstring . T.pack $ "the element shown to be equal to itself.")]
1089+
1090+eqParamDoc = [(n "A", parseDocstring . T.pack $ "the type of the left side of the equality"),
1091+ (n "B", parseDocstring . T.pack $ "the type of the right side of the equality")
1092+ ]
1011 where n a = sMN 0 a
1093 where n a = sMN 0 a
1094+
1012eqOpts = []
1095eqOpts = []
1013
1096
1014elimName = sUN "__Elim"
1097elimName = sUN "__Elim"
1015elimMethElimTy = sUN "__elimTy"
1098elimMethElimTy = sUN "__elimTy"
1016elimMethElim = sUN "elim"
1099elimMethElim = sUN "elim"
1017−elimDecl = PClass (parseDocstring . T.pack $ "Type class for eliminators") defaultSyntax bi [] elimName [(sUN "scrutineeType", PType)]
1100+elimDecl = PClass (parseDocstring . T.pack $ "Type class for eliminators") defaultSyntax bi [] elimName [(sUN "scrutineeType", PType)] []
1018 [PTy emptyDocstring [] defaultSyntax bi [TotalFn] elimMethElimTy PType,
1101 [PTy emptyDocstring [] defaultSyntax bi [TotalFn] elimMethElimTy PType,
1019 PTy emptyDocstring [] defaultSyntax bi [TotalFn] elimMethElim (PRef bi elimMethElimTy)]
1102 PTy emptyDocstring [] defaultSyntax bi [TotalFn] elimMethElim (PRef bi elimMethElimTy)]
1020
1103
1021-- Defined in builtins.idr
1104-- Defined in builtins.idr
1022−sigmaTy = sUN "Exists"
1105+sigmaTy = sUN "Sigma"
1023−existsCon = sUN "Ex_intro"
1106+existsCon = sUN "Sg_intro"
1024
1107
1025piBind :: [(Name, PTerm)] -> PTerm -> PTerm
1108piBind :: [(Name, PTerm)] -> PTerm -> PTerm
1026piBind = piBindp expl
1109piBind = piBindp expl
@@ -1036,58 +1119,69 @@ piBindp p ((n, ty):ns) t = PPi p n ty (piBindp p ns t)
1036-- could interfere with interactive editing, which calls "show".
1119-- could interfere with interactive editing, which calls "show".
1037
1120
1038instance Show PTerm where
1121instance Show PTerm where
1039− showsPrec _ tm = (displayS . renderPretty 1.0 10000000 . prettyImp False) tm
1122+ showsPrec _ tm = (displayS . renderPretty 1.0 10000000 . prettyImp defaultPPOption) tm
1040
1123
1041instance Show PDecl where
1124instance Show PDecl where
1042− showsPrec _ d = (displayS . renderPretty 1.0 10000000 . showDeclImp False) d
1125+ showsPrec _ d = (displayS . renderPretty 1.0 10000000 . showDeclImp defaultPPOption) d
1043
1126
1044instance Show PClause where
1127instance Show PClause where
1045− showsPrec _ c = (displayS . renderPretty 1.0 10000000 . showCImp True) c
1128+ showsPrec _ c = (displayS . renderPretty 1.0 10000000 . showCImp verbosePPOption) c
1046
1129
1047instance Show PData where
1130instance Show PData where
1048− showsPrec _ d = (displayS . renderPretty 1.0 10000000 . showDImp False) d
1131+ showsPrec _ d = (displayS . renderPretty 1.0 10000000 . showDImp defaultPPOption) d
1049
1132
1050instance Pretty PTerm OutputAnnotation where
1133instance Pretty PTerm OutputAnnotation where
1051− pretty = prettyImp False
1134+ pretty = prettyImp defaultPPOption
1052
1135
1053-- | Colourise annotations according to an Idris state. It ignores the names
1136-- | Colourise annotations according to an Idris state. It ignores the names
1054-- in the annotation, as there's no good way to show extended information on a
1137-- in the annotation, as there's no good way to show extended information on a
1055-- terminal.
1138-- terminal.
1056consoleDecorate :: IState -> OutputAnnotation -> String -> String
1139consoleDecorate :: IState -> OutputAnnotation -> String -> String
1057consoleDecorate ist _ | not (idris_colourRepl ist) = id
1140consoleDecorate ist _ | not (idris_colourRepl ist) = id
1058−consoleDecorate ist AnnConstData = let theme = idris_colourTheme ist
1141+consoleDecorate ist (AnnConst c) = let theme = idris_colourTheme ist
1142+ in if constIsType c
1143+ then colouriseType theme
1059− in colouriseData theme
1144+ else colouriseData theme
1060−consoleDecorate ist AnnConstType = let theme = idris_colourTheme ist
1145+consoleDecorate ist (AnnData _ _) = colouriseData (idris_colourTheme ist)
1061− in colouriseType theme
1146+consoleDecorate ist (AnnType _ _) = colouriseType (idris_colourTheme ist)
1062consoleDecorate ist (AnnBoundName _ True) = colouriseImplicit (idris_colourTheme ist)
1147consoleDecorate ist (AnnBoundName _ True) = colouriseImplicit (idris_colourTheme ist)
1063consoleDecorate ist (AnnBoundName _ False) = colouriseBound (idris_colourTheme ist)
1148consoleDecorate ist (AnnBoundName _ False) = colouriseBound (idris_colourTheme ist)
1064consoleDecorate ist AnnKeyword = colouriseKeyword (idris_colourTheme ist)
1149consoleDecorate ist AnnKeyword = colouriseKeyword (idris_colourTheme ist)
1065consoleDecorate ist (AnnName n _ _ _) = let ctxt = tt_ctxt ist
1150consoleDecorate ist (AnnName n _ _ _) = let ctxt = tt_ctxt ist
1066 theme = idris_colourTheme ist
1151 theme = idris_colourTheme ist
1067 in case () of
1152 in case () of
1068− _ | isDConName n ctxt -> colouriseData theme
1153+ _ | isDConName n ctxt -> colouriseData theme
1069− _ | isFnName n ctxt -> colouriseFun theme
1154+ _ | isFnName n ctxt -> colouriseFun theme
1070− _ | isTConName n ctxt -> colouriseType theme
1155+ _ | isTConName n ctxt -> colouriseType theme
1156+ _ | isPostulateName n ist -> colourisePostulate theme
1071− _ | otherwise -> id -- don't colourise unknown names
1157+ _ | otherwise -> id -- don't colourise unknown names
1072consoleDecorate ist (AnnFC _) = id
1158consoleDecorate ist (AnnFC _) = id
1073consoleDecorate ist (AnnTextFmt fmt) = Idris.Colours.colourise (colour fmt)
1159consoleDecorate ist (AnnTextFmt fmt) = Idris.Colours.colourise (colour fmt)
1074 where colour BoldText = IdrisColour Nothing True False True False
1160 where colour BoldText = IdrisColour Nothing True False True False
1075 colour UnderlineText = IdrisColour Nothing True True False False
1161 colour UnderlineText = IdrisColour Nothing True True False False
1076 colour ItalicText = IdrisColour Nothing True False False True
1162 colour ItalicText = IdrisColour Nothing True False False True
1077
1163
1164+isPostulateName :: Name -> IState -> Bool
1165+isPostulateName n ist = S.member n (idris_postulates ist)
1166+
1078−-- | Pretty-print a high-level closed Idris term
1167+-- | Pretty-print a high-level closed Idris term with no information about precedence/associativity
1079−prettyImp :: Bool -- ^^ whether to show implicits
1168+prettyImp :: PPOption -- ^^ pretty printing options
1080 -> PTerm -- ^^ the term to pretty-print
1169 -> PTerm -- ^^ the term to pretty-print
1081 -> Doc OutputAnnotation
1170 -> Doc OutputAnnotation
1082−prettyImp impl = pprintPTerm impl [] []
1171+prettyImp impl = pprintPTerm impl [] [] []
1172+
1173+-- | Do the right thing for rendering a term in an IState
1174+prettyIst :: IState -> PTerm -> Doc OutputAnnotation
1175+prettyIst ist = pprintPTerm (ppOptionIst ist) [] [] (idris_infixes ist)
1083
1176
1084−-- | Pretty-print a high-level Idris term in some bindings context
1177+-- | Pretty-print a high-level Idris term in some bindings context with infix info
1085−pprintPTerm :: Bool -- ^^ whether to show implicits
1178+pprintPTerm :: PPOption -- ^^ pretty printing options
1086 -> [(Name, Bool)] -- ^^ the currently-bound names and whether they are implicit
1179 -> [(Name, Bool)] -- ^^ the currently-bound names and whether they are implicit
1087 -> [Name] -- ^^ names to always show in pi, even if not used
1180 -> [Name] -- ^^ names to always show in pi, even if not used
1181+ -> [FixDecl] -- ^^ Fixity declarations
1088 -> PTerm -- ^^ the term to pretty-print
1182 -> PTerm -- ^^ the term to pretty-print
1089 -> Doc OutputAnnotation
1183 -> Doc OutputAnnotation
1090−pprintPTerm impl bnd docArgs = prettySe 10 bnd
1184+pprintPTerm ppo bnd docArgs infixes = prettySe 10 bnd
1091 where
1185 where
1092 prettySe :: Int -> [(Name, Bool)] -> PTerm -> Doc OutputAnnotation
1186 prettySe :: Int -> [(Name, Bool)] -> PTerm -> Doc OutputAnnotation
1093 prettySe p bnd (PQuote r) =
1187 prettySe p bnd (PQuote r) =
@@ -1095,8 +1189,8 @@ pprintPTerm impl bnd docArgs = prettySe 10 bnd
1095 prettySe p bnd (PPatvar fc n) = pretty n
1189 prettySe p bnd (PPatvar fc n) = pretty n
1096 prettySe p bnd e
1190 prettySe p bnd e
1097 | Just str <- slist p bnd e = str
1191 | Just str <- slist p bnd e = str
1098− | Just n <- snat p e = annotate AnnConstData (text (show n))
1192+ | Just n <- snat p e = annotate (AnnData "Nat" "") (text (show n))
1099− prettySe p bnd (PRef fc n) = prettyName impl bnd n
1193+ prettySe p bnd (PRef fc n) = prettyName (ppopt_impl ppo) bnd n
1100 prettySe p bnd (PLam n ty sc) =
1194 prettySe p bnd (PLam n ty sc) =
1101 bracket p 2 . group . align . hang 2 $
1195 bracket p 2 . group . align . hang 2 $
1102 text "\\" <> bindingOf n False <+> text "=>" <$>
1196 text "\\" <> bindingOf n False <+> text "=>" <$>
@@ -1107,22 +1201,22 @@ pprintPTerm impl bnd docArgs = prettySe 10 bnd
1107 prettySe 10 bnd v <+> kwd "in" </>
1201 prettySe 10 bnd v <+> kwd "in" </>
1108 prettySe 10 ((n, False):bnd) sc
1202 prettySe 10 ((n, False):bnd) sc
1109 prettySe p bnd (PPi (Exp l s _) n ty sc)
1203 prettySe p bnd (PPi (Exp l s _) n ty sc)
1110− | n `elem` allNamesIn sc || impl || n `elem` docArgs =
1204+ | n `elem` allNamesIn sc || ppopt_impl ppo || n `elem` docArgs =
1111 bracket p 2 . group $
1205 bracket p 2 . group $
1112 enclose lparen rparen (group . align $ bindingOf n False <+> colon <+> prettySe 10 bnd ty) <+>
1206 enclose lparen rparen (group . align $ bindingOf n False <+> colon <+> prettySe 10 bnd ty) <+>
1113 st <> text "->" <$> prettySe 10 ((n, False):bnd) sc
1207 st <> text "->" <$> prettySe 10 ((n, False):bnd) sc
1114 | otherwise =
1208 | otherwise =
1115 bracket p 2 . group $
1209 bracket p 2 . group $
1116− group (prettySe 0 bnd ty <+> st) <> text "->" <$> group (prettySe 10 ((n, False):bnd) sc)
1210+ group (prettySe 1 bnd ty <+> st) <> text "->" <$> group (prettySe 10 ((n, False):bnd) sc)
1117 where
1211 where
1118 st =
1212 st =
1119 case s of
1213 case s of
1120 Static -> text "[static]" <> space
1214 Static -> text "[static]" <> space
1121 _ -> empty
1215 _ -> empty
1122 prettySe p bnd (PPi (Imp l s _) n ty sc)
1216 prettySe p bnd (PPi (Imp l s _) n ty sc)
1123− | impl =
1217+ | ppopt_impl ppo =
1124 bracket p 2 $
1218 bracket p 2 $
1125− lparen <> bindingOf n True <+> colon <+> prettySe 10 bnd ty <> rbrace <+>
1219+ lbrace <> bindingOf n True <+> colon <+> prettySe 10 bnd ty <> rbrace <+>
1126 st <> text "->" </> prettySe 10 ((n, True):bnd) sc
1220 st <> text "->" </> prettySe 10 ((n, True):bnd) sc
1127 | otherwise = prettySe 10 ((n, True):bnd) sc
1221 | otherwise = prettySe 10 ((n, True):bnd) sc
1128 where
1222 where
@@ -1139,35 +1233,46 @@ pprintPTerm impl bnd docArgs = prettySe 10 bnd
1139 rbrace <+> text "->" </> prettySe 10 ((n, True):bnd) sc
1233 rbrace <+> text "->" </> prettySe 10 ((n, True):bnd) sc
1140 prettySe p bnd (PApp _ (PRef _ f) args) -- normal names, no explicit args
1234 prettySe p bnd (PApp _ (PRef _ f) args) -- normal names, no explicit args
1141 | UN nm <- basename f
1235 | UN nm <- basename f
1236+ , not (ppopt_impl ppo) && null (getExps args) =
1142− , not impl && null (getExps args) = if isAlpha (thead nm)
1237+ if isAlpha (thead nm)
1143− then prettyName impl bnd f
1238+ then prettyName (ppopt_impl ppo) bnd f
1144− else enclose lparen rparen $
1239+ else enclose lparen rparen $ prettyName (ppopt_impl ppo) bnd f
1145− prettyName impl bnd f
1146 prettySe p bnd (PAppBind _ (PRef _ f) [])
1240 prettySe p bnd (PAppBind _ (PRef _ f) [])
1147− | not impl = text "!" <> prettyName impl bnd f
1241+ | not (ppopt_impl ppo) = text "!" <> prettyName (ppopt_impl ppo) bnd f
1148− prettySe p bnd (PApp _ (PRef _ op) args)
1242+ prettySe p bnd (PApp _ (PRef _ op) args) -- infix operators
1149 | UN nm <- basename op
1243 | UN nm <- basename op
1150 , not (tnull nm) &&
1244 , not (tnull nm) &&
1151− (not impl) && (not $ isAlpha (thead nm)) =
1245+ (not (ppopt_impl ppo)) && (not $ isAlpha (thead nm)) =
1152 case getExps args of
1246 case getExps args of
1153 [] -> enclose lparen rparen opName
1247 [] -> enclose lparen rparen opName
1154 [x] -> group (enclose lparen rparen opName <$> group (prettySe 0 bnd x))
1248 [x] -> group (enclose lparen rparen opName <$> group (prettySe 0 bnd x))
1249+ [l,r] -> let precedence = fromMaybe 20 (fmap prec f)
1155− [l,r] -> bracket p 1 $ inFix l r
1250+ in bracket p precedence $ inFix l r
1156 (l:r:rest) -> bracket p 1 $
1251 (l:r:rest) -> bracket p 1 $
1157 enclose lparen rparen (inFix l r) <+>
1252 enclose lparen rparen (inFix l r) <+>
1158 align (group (vsep (map (prettyArgSe bnd) rest)))
1253 align (group (vsep (map (prettyArgSe bnd) rest)))
1159− where opName = prettyName impl bnd op
1254+ where opName = prettyName (ppopt_impl ppo) bnd op
1255+ f = getFixity (opStr op)
1256+ left l = case f of
1257+ Nothing -> prettySe (-1) bnd l
1258+ Just (Infixl p') -> prettySe p' bnd l
1259+ Just f' -> prettySe (prec f'-1) bnd l
1260+ right r = case f of
1261+ Nothing -> prettySe (-1) bnd r
1262+ Just (Infixr p') -> prettySe p' bnd r
1263+ Just f' -> prettySe (prec f'-1) bnd r
1160 inFix l r = align . group $
1264 inFix l r = align . group $
1161− (prettySe 1 bnd l <+> opName) <$> group (prettySe 0 bnd r)
1265+ (left l <+> opName) <$> group (right r)
1162− prettySe p bnd (PApp _ hd@(PRef fc f) [tm])
1266+ prettySe p bnd (PApp _ hd@(PRef fc f) [tm]) -- symbols, like 'foo
1163 | PConstant (Idris.Core.TT.Str str) <- getTm tm,
1267 | PConstant (Idris.Core.TT.Str str) <- getTm tm,
1268+ f == sUN "Symbol_" = annotate (AnnType ("'" ++ str) ("The symbol " ++ str)) $
1164− f == sUN "Symbol_" = char '\'' <> prettySe 10 bnd (PRef fc (sUN str))
1269+ char '\'' <> prettySe 10 bnd (PRef fc (sUN str))
1165− prettySe p bnd (PApp _ f as) =
1270+ prettySe p bnd (PApp _ f as) = -- Normal prefix applications
1166 let args = getExps as
1271 let args = getExps as
1167 fp = prettySe 1 bnd f
1272 fp = prettySe 1 bnd f
1168 in
1273 in
1169 bracket p 1 . group $
1274 bracket p 1 . group $
1170− if impl
1275+ if ppopt_impl ppo
1171 then if null as
1276 then if null as
1172 then fp
1277 then fp
1173 else fp <+> align (vsep (map (prettyArgS bnd) as))
1278 else fp <+> align (vsep (map (prettyArgS bnd) as))
@@ -1229,13 +1334,8 @@ pprintPTerm impl bnd docArgs = prettySe 10 bnd
1229 where
1334 where
1230 prettyAs =
1335 prettyAs =
1231 foldr (\l -> \r -> l <+> text "," <+> r) empty $ map (prettySe 10 bnd) as
1336 foldr (\l -> \r -> l <+> text "," <+> r) empty $ map (prettySe 10 bnd) as
1232− prettySe p bnd PType = annotate AnnConstType $ text "Type"
1337+ prettySe p bnd PType = annotate (AnnType "Type" "The type of types") $ text "Type"
1233− prettySe p bnd (PConstant c) = annotate (annot c) (text (show c))
1338+ prettySe p bnd (PConstant c) = annotate (AnnConst c) (text (show c))
1234− where annot (AType _) = AnnConstType
1235− annot StrType = AnnConstType
1236− annot PtrType = AnnConstType
1237− annot VoidType = AnnConstType
1238− annot _ = AnnConstData
1239 -- XXX: add pretty for tactics
1339 -- XXX: add pretty for tactics
1240 prettySe p bnd (PProof ts) =
1340 prettySe p bnd (PProof ts) =
1241 text "proof" <+> lbrace <> nest nestingSize (text . show $ ts) <> rbrace
1341 text "proof" <+> lbrace <> nest nestingSize (text . show $ ts) <> rbrace
@@ -1246,6 +1346,7 @@ pprintPTerm impl bnd docArgs = prettySe 10 bnd
1246 prettySe p bnd PImpossible = kwd "impossible"
1346 prettySe p bnd PImpossible = kwd "impossible"
1247 prettySe p bnd Placeholder = text "_"
1347 prettySe p bnd Placeholder = text "_"
1248 prettySe p bnd (PDoBlock _) = text "do block pretty not implemented"
1348 prettySe p bnd (PDoBlock _) = text "do block pretty not implemented"
1349+ prettySe p bnd (PCoerced t) = prettySe p bnd t
1249 prettySe p bnd (PElabError s) = pretty s
1350 prettySe p bnd (PElabError s) = pretty s
1250
1351
1251 prettySe p bnd _ = text "test"
1352 prettySe p bnd _ = text "test"
@@ -1263,14 +1364,18 @@ pprintPTerm impl bnd docArgs = prettySe 10 bnd
1263 annName :: Name -> Doc OutputAnnotation -> Doc OutputAnnotation
1364 annName :: Name -> Doc OutputAnnotation -> Doc OutputAnnotation
1264 annName n = annotate (AnnName n Nothing Nothing Nothing)
1365 annName n = annotate (AnnName n Nothing Nothing Nothing)
1265
1366
1367+ opStr :: Name -> String
1368+ opStr (NS n _) = opStr n
1369+ opStr (UN n) = T.unpack n
1370+
1266 basename :: Name -> Name
1371 basename :: Name -> Name
1267 basename (NS n _) = basename n
1372 basename (NS n _) = basename n
1268 basename n = n
1373 basename n = n
1269
1374
1270 slist' p bnd (PApp _ (PRef _ nil) _)
1375 slist' p bnd (PApp _ (PRef _ nil) _)
1271− | not impl && nsroot nil == sUN "Nil" = Just []
1376+ | not (ppopt_impl ppo) && nsroot nil == sUN "Nil" = Just []
1272 slist' p bnd (PRef _ nil)
1377 slist' p bnd (PRef _ nil)
1273− | not impl && nsroot nil == sUN "Nil" = Just []
1378+ | not (ppopt_impl ppo) && nsroot nil == sUN "Nil" = Just []
1274 slist' p bnd (PApp _ (PRef _ cons) args)
1379 slist' p bnd (PApp _ (PRef _ cons) args)
1275 | nsroot cons == sUN "::",
1380 | nsroot cons == sUN "::",
1276 (PExp {getTm=tl}):(PExp {getTm=hd}):imps <- reverse args,
1381 (PExp {getTm=tl}):(PExp {getTm=hd}):imps <- reverse args,
@@ -1283,16 +1388,16 @@ pprintPTerm impl bnd docArgs = prettySe 10 bnd
1283 slist' _ _ tm = Nothing
1388 slist' _ _ tm = Nothing
1284
1389
1285 slist p bnd e | Just es <- slist' p bnd e = Just $
1390 slist p bnd e | Just es <- slist' p bnd e = Just $
1286− case es of [] -> annotate AnnConstData $ text "[]"
1391+ case es of [] -> annotate (AnnData "" "") $ text "[]"
1287 [x] -> enclose left right . group $
1392 [x] -> enclose left right . group $
1288 prettySe p bnd x
1393 prettySe p bnd x
1289 xs -> (enclose left right .
1394 xs -> (enclose left right .
1290 align . group . vsep .
1395 align . group . vsep .
1291 punctuate comma .
1396 punctuate comma .
1292 map (prettySe p bnd)) xs
1397 map (prettySe p bnd)) xs
1293− where left = (annotate AnnConstData (text "["))
1398+ where left = (annotate (AnnData "" "") (text "["))
1294− right = (annotate AnnConstData (text "]"))
1399+ right = (annotate (AnnData "" "") (text "]"))
1295− comma = (annotate AnnConstData (text ","))
1400+ comma = (annotate (AnnData "" "") (text ","))
1296 slist _ _ _ = Nothing
1401 slist _ _ _ = Nothing
1297
1402
1298 pairElts :: PTerm -> Maybe [PTerm]
1403 pairElts :: PTerm -> Maybe [PTerm]
@@ -1316,6 +1421,17 @@ pprintPTerm impl bnd docArgs = prettySe 10 bnd
1316
1421
1317 kwd = annotate AnnKeyword . text
1422 kwd = annotate AnnKeyword . text
1318
1423
1424+ fixities :: M.Map String Fixity
1425+ fixities = M.fromList [(s, f) | (Fix f s) <- infixes]
1426+
1427+ getFixity :: String -> Maybe Fixity
1428+ getFixity = flip M.lookup fixities
1429+
1430+prettyDocumentedIst :: IState -> (Name, PTerm, Maybe Docstring) -> Doc OutputAnnotation
1431+prettyDocumentedIst ist (name, ty, docs) =
1432+ prettyName True [] name <+> colon <+> align (prettyIst ist ty) <$>
1433+ fromMaybe empty (fmap (\d -> renderDocstring d <> line) docs)
1434+
1319-- | Pretty-printer helper for the binding site of a name
1435-- | Pretty-printer helper for the binding site of a name
1320bindingOf :: Name -- ^^ the bound name
1436bindingOf :: Name -- ^^ the bound name
1321 -> Bool -- ^^ whether the name is implicit
1437 -> Bool -- ^^ whether the name is implicit
@@ -1332,47 +1448,48 @@ prettyName showNS bnd n | Just imp <- lookup n bnd = annotate (AnnBoundName n im
1332 where strName (UN n) = T.unpack n
1448 where strName (UN n) = T.unpack n
1333 strName (NS n ns) | showNS = (concatMap (++ ".") . map T.unpack . reverse) ns ++ strName n
1449 strName (NS n ns) | showNS = (concatMap (++ ".") . map T.unpack . reverse) ns ++ strName n
1334 | otherwise = strName n
1450 | otherwise = strName n
1451+ strName n | n == falseTy = "_|_"
1335− strName (MN i s) = T.unpack s
1452+ strName (MN i s) = T.unpack s
1336 strName other = show other
1453 strName other = show other
1337
1454
1338
1455
1339−showCImp :: Bool -> PClause -> Doc OutputAnnotation
1456+showCImp :: PPOption -> PClause -> Doc OutputAnnotation
1340−showCImp impl (PClause _ n l ws r w)
1457+showCImp ppo (PClause _ n l ws r w)
1341− = prettyImp impl l <+> showWs ws <+> text "=" <+> prettyImp impl r
1458+ = prettyImp ppo l <+> showWs ws <+> text "=" <+> prettyImp ppo r
1342 <+> text "where" <+> text (show w)
1459 <+> text "where" <+> text (show w)
1343 where
1460 where
1344 showWs [] = empty
1461 showWs [] = empty
1345− showWs (x : xs) = text "|" <+> prettyImp impl x <+> showWs xs
1462+ showWs (x : xs) = text "|" <+> prettyImp ppo x <+> showWs xs
1346−showCImp impl (PWith _ n l ws r w)
1463+showCImp ppo (PWith _ n l ws r w)
1347− = prettyImp impl l <+> showWs ws <+> text "with" <+> prettyImp impl r
1464+ = prettyImp ppo l <+> showWs ws <+> text "with" <+> prettyImp ppo r
1348 <+> braces (text (show w))
1465 <+> braces (text (show w))
1349 where
1466 where
1350 showWs [] = empty
1467 showWs [] = empty
1351− showWs (x : xs) = text "|" <+> prettyImp impl x <+> showWs xs
1468+ showWs (x : xs) = text "|" <+> prettyImp ppo x <+> showWs xs
1352
1469
1353
1470
1354−showDImp :: Bool -> PData -> Doc OutputAnnotation
1471+showDImp :: PPOption -> PData -> Doc OutputAnnotation
1355−showDImp impl (PDatadecl n ty cons)
1472+showDImp ppo (PDatadecl n ty cons)
1356− = text "data" <+> text (show n) <+> colon <+> prettyImp impl ty <+> text "where" <$>
1473+ = text "data" <+> text (show n) <+> colon <+> prettyImp ppo ty <+> text "where" <$>
1357− (indent 2 $ vsep (map (\ (_, _, n, t, _, _) -> pipe <+> prettyName False [] n <+> colon <+> prettyImp impl t) cons))
1474+ (indent 2 $ vsep (map (\ (_, _, n, t, _, _) -> pipe <+> prettyName False [] n <+> colon <+> prettyImp ppo t) cons))
1358
1475
1359−showDecls :: Bool -> [PDecl] -> Doc OutputAnnotation
1476+showDecls :: PPOption -> [PDecl] -> Doc OutputAnnotation
1360−showDecls i ds = vsep (map (showDeclImp i) ds)
1477+showDecls o ds = vsep (map (showDeclImp o) ds)
1361
1478
1362showDeclImp _ (PFix _ f ops) = text (show f) <+> cat (punctuate (text ",") (map text ops))
1479showDeclImp _ (PFix _ f ops) = text (show f) <+> cat (punctuate (text ",") (map text ops))
1363−showDeclImp i (PTy _ _ _ _ _ n t) = text "tydecl" <+> text (showCG n) <+> colon <+> prettyImp i t
1480+showDeclImp o (PTy _ _ _ _ _ n t) = text "tydecl" <+> text (showCG n) <+> colon <+> prettyImp o t
1364−showDeclImp i (PClauses _ _ n cs) = text "pat" <+> text (showCG n) <+> text "\t" <+>
1481+showDeclImp o (PClauses _ _ n cs) = text "pat" <+> text (showCG n) <+> text "\t" <+>
1365− indent 2 (vsep (map (showCImp i) cs))
1482+ indent 2 (vsep (map (showCImp o) cs))
1366−showDeclImp _ (PData _ _ _ _ _ d) = showDImp True d
1483+showDeclImp o (PData _ _ _ _ _ d) = showDImp o { ppopt_impl = True } d
1367−showDeclImp i (PParams _ ns ps) = text "params" <+> braces (text (show ns) <> line <> showDecls i ps <> line)
1484+showDeclImp o (PParams _ ns ps) = text "params" <+> braces (text (show ns) <> line <> showDecls o ps <> line)
1368−showDeclImp i (PNamespace n ps) = text "namespace" <+> text n <> braces (line <> showDecls i ps <> line)
1485+showDeclImp o (PNamespace n ps) = text "namespace" <+> text n <> braces (line <> showDecls o ps <> line)
1369showDeclImp _ (PSyntax _ syn) = text "syntax" <+> text (show syn)
1486showDeclImp _ (PSyntax _ syn) = text "syntax" <+> text (show syn)
1370−showDeclImp i (PClass _ _ _ cs n ps ds)
1487+showDeclImp o (PClass _ _ _ cs n ps _ ds)
1371− = text "class" <+> text (show cs) <+> text (show n) <+> text (show ps) <> line <> showDecls i ds
1488+ = text "class" <+> text (show cs) <+> text (show n) <+> text (show ps) <> line <> showDecls o ds
1372−showDeclImp i (PInstance _ _ cs n _ t _ ds)
1489+showDeclImp o (PInstance _ _ cs n _ t _ ds)
1373− = text "instance" <+> text (show cs) <+> text (show n) <+> prettyImp i t <> line <> showDecls i ds
1490+ = text "instance" <+> text (show cs) <+> text (show n) <+> prettyImp o t <> line <> showDecls o ds
1374showDeclImp _ _ = text "..."
1491showDeclImp _ _ = text "..."
1375−-- showDeclImp (PImport i) = "import " ++ i
1492+-- showDeclImp (PImport o) = "import " ++ o
1376
1493
1377instance Show (Doc OutputAnnotation) where
1494instance Show (Doc OutputAnnotation) where
1378 show = flip (displayS . renderCompact) ""
1495 show = flip (displayS . renderCompact) ""
@@ -1399,14 +1516,14 @@ getAll = map getTm
1399-- | Show Idris name
1516-- | Show Idris name
1400showName :: Maybe IState -- ^^ the Idris state, for information about names and colours
1517showName :: Maybe IState -- ^^ the Idris state, for information about names and colours
1401 -> [(Name, Bool)] -- ^^ the bound variables and whether they're implicit
1518 -> [(Name, Bool)] -- ^^ the bound variables and whether they're implicit
1402− -> Bool -- ^^ whether to show implicits
1519+ -> PPOption -- ^^ pretty printing options
1403 -> Bool -- ^^ whether to colourise
1520 -> Bool -- ^^ whether to colourise
1404 -> Name -- ^^ the term to show
1521 -> Name -- ^^ the term to show
1405 -> String
1522 -> String
1406−showName ist bnd impl colour n = case ist of
1523+showName ist bnd ppo colour n = case ist of
1407 Just i -> if colour then colourise n (idris_colourTheme i) else showbasic n
1524 Just i -> if colour then colourise n (idris_colourTheme i) else showbasic n
1408 Nothing -> showbasic n
1525 Nothing -> showbasic n
1409− where name = if impl then show n else showbasic n
1526+ where name = if ppopt_impl ppo then show n else showbasic n
1410 showbasic n@(UN _) = showCG n
1527 showbasic n@(UN _) = showCG n
1411 showbasic (MN _ s) = str s
1528 showbasic (MN _ s) = str s
1412 showbasic (NS n s) = showSep "." (map str (reverse s)) ++ "." ++ showbasic n
1529 showbasic (NS n s) = showSep "." (map str (reverse s)) ++ "." ++ showbasic n
@@ -1430,11 +1547,12 @@ showTm :: IState -- ^^ the Idris state, for information about identifiers and co
1430 -> String
1547 -> String
1431showTm ist = displayDecorated (consoleDecorate ist) .
1548showTm ist = displayDecorated (consoleDecorate ist) .
1432 renderPretty 0.8 100000 .
1549 renderPretty 0.8 100000 .
1433− prettyImp (opt_showimp (idris_options ist))
1550+ prettyImp (ppOptionIst ist)
1434
1551
1435-- | Show a term with implicits, no colours
1552-- | Show a term with implicits, no colours
1436showTmImpls :: PTerm -> String
1553showTmImpls :: PTerm -> String
1437−showTmImpls = flip (displayS . renderCompact . prettyImp True) ""
1554+showTmImpls = flip (displayS . renderCompact . prettyImp verbosePPOption) ""
1555+
1438
1556
1439
1557
1440instance Sized PTerm where
1558instance Sized PTerm where
@@ -1567,8 +1685,8 @@ usedNamesIn vars ist tm = nub $ ni [] tm
1567 where -- TODO THINK added niTacImp, but is it right?
1685 where -- TODO THINK added niTacImp, but is it right?
1568 ni env (PRef _ n)
1686 ni env (PRef _ n)
1569 | n `elem` vars && not (n `elem` env)
1687 | n `elem` vars && not (n `elem` env)
1570− = case lookupTy n (tt_ctxt ist) of
1688+ = case lookupDefExact n (tt_ctxt ist) of
1571− [] -> [n]
1689+ Nothing -> [n]
1572 _ -> []
1690 _ -> []
1573 ni env (PApp _ f as) = ni env f ++ concatMap (ni env) (map getTm as)
1691 ni env (PApp _ f as) = ni env f ++ concatMap (ni env) (map getTm as)
1574 ni env (PAppBind _ f as) = ni env f ++ concatMap (ni env) (map getTm as)
1692 ni env (PAppBind _ f as) = ni env f ++ concatMap (ni env) (map getTm as)
@@ -1590,4 +1708,3 @@ usedNamesIn vars ist tm = nub $ ni [] tm
1590
1708
1591 niTacImp env (TacImp _ _ scr) = ni env scr
1709 niTacImp env (TacImp _ _ scr) = ni env scr
1592 niTacImp _ _ = []
1710 niTacImp _ _ = []
1593−
src/Idris/Apropos.hs+12−8
@@ -9,8 +9,8 @@ import Idris.Docstrings (Docstring, containsText)
9import Data.List (nub)
9import Data.List (nub)
10import qualified Data.Text as T
10import qualified Data.Text as T
11
11
12−-- | Find definitions that are relevant to some string. Relevance is one or
12+-- | Find definitions that are relevant to all space-delimited components of
13−-- more of the following:
13+-- some string. Relevance is one or more of the following:
14--
14--
15-- * the string is a substring of the name
15-- * the string is a substring of the name
16--
16--
@@ -20,8 +20,12 @@ import qualified Data.Text as T
20apropos :: IState -> T.Text -> [Name]
20apropos :: IState -> T.Text -> [Name]
21apropos ist what = let defs = ctxtAlist (tt_ctxt ist)
21apropos ist what = let defs = ctxtAlist (tt_ctxt ist)
22 docs = toAlist (idris_docstrings ist)
22 docs = toAlist (idris_docstrings ist)
23− in nub (map fst (filter (isApropos what) defs) ++
23+ in nub (map fst (isAproposAll parts defs) ++
24− map fst (filter (isApropos what) docs))
24+ map fst (isAproposAll parts docs))
25+ where isAproposAll [] xs = xs
26+ isAproposAll (what:more) xs = filter (isApropos what)
27+ (isAproposAll more xs)
28+ parts = filter ((> 0) . T.length) . T.splitOn (T.pack " ") $ what
25
29
26textIn :: T.Text -> T.Text -> Bool
30textIn :: T.Text -> T.Text -> Bool
27textIn a b = T.isInfixOf (T.toLower a) (T.toLower b)
31textIn a b = T.isInfixOf (T.toLower a) (T.toLower b)
@@ -48,10 +52,10 @@ instance Apropos Def where
48 isApropos str (CaseOp _ ty ty' _ _ _) = isApropos str ty
52 isApropos str (CaseOp _ ty ty' _ _ _) = isApropos str ty
49
53
50instance Apropos (Binder (TT Name)) where
54instance Apropos (Binder (TT Name)) where
51− isApropos str (Lam ty) = isApropos str ty
55+ isApropos str (Lam ty) = str == T.pack "\\" || isApropos str ty
52− isApropos str (Pi ty) = isApropos str ty
56+ isApropos str (Pi ty) = str == T.pack "->" || isApropos str ty
53− isApropos str (Let ty val) = isApropos str ty || isApropos str val
57+ isApropos str (Let ty val) = str == T.pack "let" || isApropos str ty || isApropos str val
54− isApropos str (NLet ty val) = isApropos str ty || isApropos str val
58+ isApropos str (NLet ty val) = str == T.pack "let" || isApropos str ty || isApropos str val
55 isApropos str _ = False -- these shouldn't occur in defined libraries
59 isApropos str _ = False -- these shouldn't occur in defined libraries
56
60
57instance Apropos (TT Name) where
61instance Apropos (TT Name) where
src/Idris/CaseSplit.hs+42−13
@@ -22,6 +22,7 @@ import Idris.Core.Evaluate
22
22
23import Data.Maybe
23import Data.Maybe
24import Data.Char
24import Data.Char
25+import Data.List (isPrefixOf, isSuffixOf)
25import Control.Monad
26import Control.Monad
26import Control.Monad.State.Strict
27import Control.Monad.State.Strict
27
28
@@ -54,7 +55,10 @@ split n t'
54 = do ist <- getIState
55 = do ist <- getIState
55 -- Make sure all the names in the term are accessible
56 -- Make sure all the names in the term are accessible
56 mapM_ (\n -> setAccessibility n Public) (allNamesIn t')
57 mapM_ (\n -> setAccessibility n Public) (allNamesIn t')
57− (tm, ty, pats) <- elabValBind toplevel True (addImplPat ist t')
58+ (tm, ty, pats) <- elabValBind toplevel True True (addImplPat ist t')
59+ -- ASSUMPTION: tm is in normal form after elabValBind, so we don't
60+ -- need to do anything special to find out what family each argument
61+ -- is in
58 logLvl 4 ("Elaborated:\n" ++ show tm ++ " : " ++ show ty ++ "\n" ++ show pats)
62 logLvl 4 ("Elaborated:\n" ++ show tm ++ " : " ++ show ty ++ "\n" ++ show pats)
59-- iputStrLn (show (delab ist tm) ++ " : " ++ show (delab ist ty))
63-- iputStrLn (show (delab ist tm) ++ " : " ++ show (delab ist ty))
60-- iputStrLn (show pats)
64-- iputStrLn (show pats)
@@ -276,6 +280,8 @@ replaceSplits l ups = updateRHSs 1 (map (rep (expandBraces l)) ups)
276 nshow t = show t
280 nshow t = show t
277
281
278 -- if there's any {n} replace with {n=n}
282 -- if there's any {n} replace with {n=n}
283+ -- but don't replace it in comments
284+ expandBraces ('{' : '-' : xs) = '{' : '-' : xs
279 expandBraces ('{' : xs)
285 expandBraces ('{' : xs)
280 = let (brace, (_:rest)) = span (/= '}') xs in
286 = let (brace, (_:rest)) = span (/= '}') xs in
281 if (not ('=' `elem` brace))
287 if (not ('=' `elem` brace))
@@ -294,9 +300,11 @@ replaceSplits l ups = updateRHSs 1 (map (rep (expandBraces l)) ups)
294 if (before == n && not (isAlphaNum next))
300 if (before == n && not (isAlphaNum next))
295 then addBrackets tm ++ updatePat False n tm after
301 then addBrackets tm ++ updatePat False n tm after
296 else c : updatePat (not (isAlphaNum c)) n tm rest
302 else c : updatePat (not (isAlphaNum c)) n tm rest
297− updatePat start n tm (c:rest) = c : updatePat (not (isAlpha c)) n tm rest
303+ updatePat start n tm (c:rest) = c : updatePat (not ((isAlphaNum c) || c == '_')) n tm rest
298
304
299− addBrackets tm | ' ' `elem` tm = "(" ++ tm ++ ")"
305+ addBrackets tm | ' ' `elem` tm
306+ , not (isPrefixOf "(" tm)
307+ , not (isSuffixOf ")" tm) = "(" ++ tm ++ ")"
300 | otherwise = tm
308 | otherwise = tm
301
309
302getUniq nm i
310getUniq nm i
@@ -316,12 +324,17 @@ getClause :: Int -- ^ line number that the type is declared on
316 -> Name -- ^ Function name
324 -> Name -- ^ Function name
317 -> FilePath -- ^ Source file name
325 -> FilePath -- ^ Source file name
318 -> Idris String
326 -> Idris String
327+getClause l fn fp
328+ = do i <- getIState
329+ case lookupCtxt fn (idris_classes i) of
330+ [c] -> return (mkClassBodies i (class_methods c))
319−getClause l fn fp = do ty <- getInternalApp fp l
331+ _ -> do ty <- getInternalApp fp l
320− ist <- get
332+ ist <- get
321− let ap = mkApp ist ty []
333+ let ap = mkApp ist ty []
322− return (show fn ++ " " ++ ap ++
334+ return (show fn ++ " " ++ ap ++ "= ?"
323− "= ?" ++ show fn ++ "_rhs")
335+ ++ show fn ++ "_rhs")
336+ where mkApp :: IState -> PTerm -> [Name] -> String
324− where mkApp i (PPi (Exp _ _ False) (MN _ _) ty sc) used
337+ mkApp i (PPi (Exp _ _ False) (MN _ _) ty sc) used
325 = let n = getNameFrom i used ty in
338 = let n = getNameFrom i used ty in
326 show n ++ " " ++ mkApp i sc (n : used)
339 show n ++ " " ++ mkApp i sc (n : used)
327 mkApp i (PPi (Exp _ _ False) (UN n) ty sc) used
340 mkApp i (PPi (Exp _ _ False) (UN n) ty sc) used
@@ -343,6 +356,19 @@ getClause l fn fp = do ty <- getInternalApp fp l
343 ns -> uniqueNameFrom (mkSupply ns) used
356 ns -> uniqueNameFrom (mkSupply ns) used
344 getNameFrom i used _ = uniqueName (sUN "x") used
357 getNameFrom i used _ = uniqueName (sUN "x") used
345
358
359+ -- write method declarations, indent with 4 spaces
360+ mkClassBodies :: IState -> [(Name, (FnOpts, PTerm))] -> String
361+ mkClassBodies i ns
362+ = showSep "\n"
363+ (zipWith (\(n, (_, ty)) m -> " " ++
364+ def (show (nsroot n)) ++ " "
365+ ++ mkApp i ty []
366+ ++ "= ?"
367+ ++ show fn ++ "_rhs_" ++ show m) ns [1..])
368+
369+ def n@(x:xs) | not (isAlphaNum x) = "(" ++ n ++ ")"
370+ def n = n
371+
346getProofClause :: Int -- ^ line number that the type is declared
372getProofClause :: Int -- ^ line number that the type is declared
347 -> Name -- ^ Function name
373 -> Name -- ^ Function name
348 -> FilePath -- ^ Source file name
374 -> FilePath -- ^ Source file name
@@ -358,16 +384,19 @@ getProofClause l fn fp
358
384
359mkWith :: String -> Name -> String
385mkWith :: String -> Name -> String
360mkWith str n = let str' = replaceRHS str "with (_)"
386mkWith str n = let str' = replaceRHS str "with (_)"
361− newpat = " " ++
362− replaceRHS str "| with_pat = ?" ++ show n ++ "_rhs" in
363− str' ++ "\n" ++ newpat
387+ in str' ++ "\n" ++ newpat str
364
388
365 where replaceRHS [] str = str
389 where replaceRHS [] str = str
366 replaceRHS ('?':'=': rest) str = str
390 replaceRHS ('?':'=': rest) str = str
367− replaceRHS ('=': rest) str
391+ replaceRHS ('=': rest) str
368 | not ('=' `elem` rest) = str
392 | not ('=' `elem` rest) = str
369 replaceRHS (x : rest) str = x : replaceRHS rest str
393 replaceRHS (x : rest) str = x : replaceRHS rest str
370
394
395+ newpat ('>':patstr) = '>':newpat patstr
396+ newpat patstr =
397+ " " ++
398+ replaceRHS patstr "| with_pat = ?" ++ show n ++ "_rhs"
399+
371-- Replace _ with names in missing clauses
400-- Replace _ with names in missing clauses
372
401
373nameMissing :: [PTerm] -> Idris [PTerm]
402nameMissing :: [PTerm] -> Idris [PTerm]
src/Idris/Chaser.hs+1−1
@@ -82,7 +82,7 @@ buildTree built fp = btree [] fp
82 iLOG $ "CHASING " ++ show file
82 iLOG $ "CHASING " ++ show file
83 ibcsd <- valIBCSubDir i
83 ibcsd <- valIBCSubDir i
84 ids <- allImportDirs
84 ids <- allImportDirs
85− fp <- runIO $ findImport ids ibcsd file
85+ fp <- findImport ids ibcsd file
86 iLOG $ "Found " ++ show fp
86 iLOG $ "Found " ++ show fp
87 mt <- runIO $ getIModTime fp
87 mt <- runIO $ getIModTime fp
88 if (file `elem` built)
88 if (file `elem` built)
src/Idris/CmdOptions.hsnew file+149
@@ -0,0 +1,149 @@
1+{-# LANGUAGE Arrows #-}
2+module Idris.CmdOptions where
3+
4+import Idris.AbsSyntaxTree
5+import Idris.REPL
6+
7+import IRTS.CodegenCommon
8+
9+import Options.Applicative
10+import Options.Applicative.Arrows
11+import Data.Maybe
12+
13+import qualified Text.PrettyPrint.ANSI.Leijen as PP
14+
15+runArgParser :: IO [Opt]
16+runArgParser = do opts <- execParser $ info parser
17+ (fullDesc
18+ <> headerDoc (Just idrisHeader)
19+ <> progDescDoc (Just idrisProgDesc)
20+ <> footerDoc (Just idrisFooter)
21+ )
22+ return $ preProcOpts opts []
23+ where
24+ idrisHeader = PP.hsep [PP.text "Idris version", PP.text ver, PP.text ", (C) The Idris Community 2014"]
25+ idrisProgDesc = PP.vsep [PP.text "Idris is a general purpose pure functional programming language with dependent",
26+ PP.text "types. Dependent types allow types to be predicated on values, meaning that",
27+ PP.text "some aspects of a program’s behaviour can be specified precisely in the type.",
28+ PP.text "It is compiled, with eager evaluation. Its features are influenced by Haskell",
29+ PP.text "and ML.",
30+ PP.empty,
31+ PP.vsep $ map (\x -> PP.indent 4 (PP.text x)) [
32+ "+ Full dependent types with dependent pattern matching",
33+ "+ where clauses, with rule, simple case expressions",
34+ "+ pattern matching let and lambda bindings",
35+ "+ Type classes, monad comprehensions",
36+ "+ do notation, idiom brackets",
37+ "+ syntactic conveniences for lists, tuples, dependent pairs",
38+ "+ Totality checking",
39+ "+ Coinductive types",
40+ "+ Indentation significant syntax, extensible syntax",
41+ "+ Tactic based theorem proving (influenced by Coq)",
42+ "+ Cumulative universes",
43+ "+ Simple foreign function interface (to C)",
44+ "+ Hugs style interactive environment"
45+ ],
46+ PP.empty]
47+ idrisFooter = PP.vsep [PP.text "It is important to note that Idris is first and foremost a research tool",
48+ PP.text "and project. Thus the tooling provided and resulting programs created",
49+ PP.text "should not necessarily be seen as production ready nor for industrial use.",
50+ PP.empty,
51+ PP.text "More details over Idris can be found online here:",
52+ PP.empty,
53+ PP.indent 4 (PP.text "http://www.idris-lang.org/")]
54+
55+
56+
57+
58+pureArgParser :: [String] -> [Opt]
59+pureArgParser args = case execParserMaybe (info parser idm) args of
60+ Just opts -> preProcOpts opts []
61+ Nothing -> []
62+
63+parser :: Parser [Opt]
64+parser = runA $ proc () -> do
65+ flags <- asA parseFlags -< ()
66+ files <- asA (many $ argument ((fmap . fmap) Filename str) (metavar "FILES")) -< ()
67+ A parseVersion >>> A helper -< (flags ++ files)
68+
69+parseFlags :: Parser [Opt]
70+parseFlags = many $
71+ flag' NoBanner (long "nobanner" <> help "Suppress the banner")
72+ <|> flag' Quiet (short 'q' <> long "quiet" <> help "Quiet verbosity")
73+ <|> flag' Ideslave (long "ideslave")
74+ <|> (Client <$> strOption (long "client"))
75+ <|> (OLogging <$> option (long "log" <> metavar "LEVEL" <> help "Debugging log level"))
76+ <|> flag' NoBasePkgs (long "nobasepkgs")
77+ <|> flag' NoPrelude (long "noprelude")
78+ <|> flag' NoBuiltins (long "nobuiltins")
79+ <|> flag' NoREPL (long "check")
80+ <|> (Output <$> strOption (short 'o' <> long "output" <> metavar "FILE" <> help "Specify output file"))
81+ <|> flag' TypeCase (long "typecase")
82+ <|> flag' TypeInType (long "typeintype")
83+ <|> flag' DefaultTotal (long "total" <> help "Require functions to be total by default")
84+ <|> flag' DefaultPartial (long "partial")
85+ <|> flag' WarnPartial (long "warnpartial" <> help "Warn about undeclared partial functions")
86+ <|> flag' WarnReach (long "warnreach" <> help "Warn about reachable but inaccessible arguments")
87+ <|> flag' NoCoverage (long "nocoverage")
88+ <|> flag' ErrContext (long "errorcontext")
89+ <|> flag' ShowLibs (long "link" <> help "Display link flags")
90+ <|> flag' ShowLibdir (long "libdir" <> help "Display library directory")
91+ <|> flag' ShowIncs (long "include" <> help "Display the includes flags")
92+ <|> flag' Verbose (short 'V' <> long "verbose" <> help "Loud verbosity")
93+ <|> (IBCSubDir <$> strOption (long "ibcsubdir" <> metavar "FILE" <> help "Write IBC files into sub directory"))
94+ <|> (ImportDir <$> strOption (short 'i' <> long "idrispath" <> help "Add directory to the list of import paths"))
95+ <|> flag' WarnOnly (long "warn")
96+ <|> (Pkg <$> strOption (short 'p' <> long "package"))
97+ -- Package commands
98+ <|> (PkgBuild <$> strOption (long "build" <> metavar "IPKG" <> help "Build package"))
99+ <|> (PkgInstall <$> strOption (long "install" <> metavar "IPKG" <> help "Install package"))
100+ <|> (PkgREPL <$> strOption (long "repl"))
101+ <|> (PkgClean <$> strOption (long "clean" <> metavar "IPKG" <> help "Clean package"))
102+ <|> (PkgMkDoc <$> strOption (long "mkdoc" <> metavar "IPKG" <> help "Generate IdrisDoc for package"))
103+ <|> (PkgCheck <$> strOption (long "checkpkg" <> metavar "IPKG" <> help "Check package only"))
104+ <|> (PkgTest <$> strOption (long "testpkg" <> metavar "IPKG" <> help "Run tests for package"))
105+ -- Misc options
106+ <|> (BCAsm <$> strOption (long "bytecode"))
107+ <|> flag' (OutputTy Raw) (short 'S' <> long "codegenonly" <> help "Do no further compilation of code generator output")
108+ <|> flag' (OutputTy Object) (short 'c' <> long "compileonly" <> help "Compile to object files rather than an executable")
109+ <|> flag' (OutputTy MavenProject) (long "mvn" <> help "Create a maven project (for Java codegen)")
110+ <|> (DumpDefun <$> strOption (long "dumpdefuns"))
111+ <|> (DumpCases <$> strOption (long "dumpcases"))
112+ <|> ((\s -> UseCodegen $ parseCodegen s) <$> strOption (long "codegen" <> metavar "TARGET" <> help "Select code generator: C, Java, bytecode"))
113+ <|> (EvalExpr <$> strOption (long "eval" <> short 'e' <> metavar "EXPR" <> help "Evaluate an expression without loading the REPL"))
114+ <|> flag' (InterpretScript "Main.main") (long "execute" <> help "Execute as idris")
115+ <|> (InterpretScript <$> strOption (long "exec" <> metavar "EXPR" <> help "Execute as idris"))
116+ <|> ((\s -> Extension $ getExt s) <$> strOption (long "extension" <> short 'X' <> metavar "EXT" <> help "Turn on langage extension (TypeProviders or ErrorReflection)"))
117+ <|> flag' (OptLevel 3) (long "O3")
118+ <|> flag' (OptLevel 2) (long "O2")
119+ <|> flag' (OptLevel 1) (long "O1")
120+ <|> flag' (OptLevel 0) (long "O0")
121+ <|> (OptLevel <$> option (short 'O' <> long "level"))
122+ <|> (TargetTriple <$> strOption (long "target" <> metavar "TRIPLE" <> help "Select target triple (for llvm codegen)"))
123+ <|> (TargetCPU <$> strOption (long "cpu" <> metavar "CPU" <> help "Select target CPU e.g. corei7 or cortex-m3 (for LLVM codegen)"))
124+ <|> flag' (ColourREPL True) (long "colour" <> long "color" <> help "Force coloured output")
125+ <|> flag' (ColourREPL False) (long "nocolour" <> long "nocolor" <> help "Disable coloured output")
126+ where
127+ getExt s = case maybeRead s of
128+ Just ext -> ext
129+ Nothing -> error ("Unknown extension " ++ s)
130+ maybeRead = fmap fst . listToMaybe . reads
131+
132+parseVersion :: Parser (a -> a)
133+parseVersion = infoOption ver (short 'v' <> long "version" <> help "Print version information")
134+
135+preProcOpts :: [Opt] -> [Opt] -> [Opt]
136+preProcOpts [] ys = ys
137+preProcOpts (NoBuiltins:xs) ys = NoBuiltins : NoPrelude : preProcOpts xs ys
138+preProcOpts (Output s:xs) ys = Output s : NoREPL : preProcOpts xs ys
139+preProcOpts (BCAsm s:xs) ys = BCAsm s : NoREPL : preProcOpts xs ys
140+preProcOpts (x:xs) ys = preProcOpts xs (x:ys)
141+
142+parseCodegen :: String -> Codegen
143+parseCodegen "C" = ViaC
144+parseCodegen "Java" = ViaJava
145+parseCodegen "bytecode" = Bytecode
146+parseCodegen "javascript" = ViaJavaScript
147+parseCodegen "node" = ViaNode
148+parseCodegen "llvm" = ViaLLVM
149+parseCodegen _ = error "unknown codegen" -- FIXME: partial function
src/Idris/Colours.hs+15−8
@@ -2,7 +2,7 @@ module Idris.Colours (
2 IdrisColour(..),
2 IdrisColour(..),
3 ColourTheme(..),
3 ColourTheme(..),
4 defaultTheme,
4 defaultTheme,
5− colouriseKwd, colouriseBound, colouriseImplicit,
5+ colouriseKwd, colouriseBound, colouriseImplicit, colourisePostulate,
6 colouriseType, colouriseFun, colouriseData, colouriseKeyword,
6 colouriseType, colouriseFun, colouriseData, colouriseKeyword,
7 colourisePrompt, colourise, ColourType(..)) where
7 colourisePrompt, colourise, ColourType(..)) where
8
8
@@ -19,13 +19,14 @@ data IdrisColour = IdrisColour { colour :: Maybe Color
19mkColour :: Color -> IdrisColour
19mkColour :: Color -> IdrisColour
20mkColour c = IdrisColour (Just c) True False False False
20mkColour c = IdrisColour (Just c) True False False False
21
21
22−data ColourTheme = ColourTheme { keywordColour :: IdrisColour
22+data ColourTheme = ColourTheme { keywordColour :: IdrisColour
23− , boundVarColour :: IdrisColour
23+ , boundVarColour :: IdrisColour
24− , implicitColour :: IdrisColour
24+ , implicitColour :: IdrisColour
25− , functionColour :: IdrisColour
25+ , functionColour :: IdrisColour
26− , typeColour :: IdrisColour
26+ , typeColour :: IdrisColour
27− , dataColour :: IdrisColour
27+ , dataColour :: IdrisColour
28− , promptColour :: IdrisColour
28+ , promptColour :: IdrisColour
29+ , postulateColour :: IdrisColour
29 }
30 }
30 deriving (Eq, Show)
31 deriving (Eq, Show)
31
32
@@ -38,6 +39,7 @@ defaultTheme = ColourTheme { keywordColour = IdrisColour Nothing True False True
38 , typeColour = mkColour Blue
39 , typeColour = mkColour Blue
39 , dataColour = mkColour Red
40 , dataColour = mkColour Red
40 , promptColour = IdrisColour Nothing True False True False
41 , promptColour = IdrisColour Nothing True False True False
42+ , postulateColour = IdrisColour (Just Green) True False True False
41 }
43 }
42
44
43-- | Set the colour of a string using POSIX escape codes
45-- | Set the colour of a string using POSIX escape codes
@@ -74,6 +76,10 @@ colourisePrompt t = colourise (promptColour t)
74colouriseKeyword :: ColourTheme -> String -> String
76colouriseKeyword :: ColourTheme -> String -> String
75colouriseKeyword t = colourise (keywordColour t)
77colouriseKeyword t = colourise (keywordColour t)
76
78
79+colourisePostulate :: ColourTheme -> String -> String
80+colourisePostulate t = colourise (postulateColour t)
81+
82+
77data ColourType = KeywordColour
83data ColourType = KeywordColour
78 | BoundVarColour
84 | BoundVarColour
79 | ImplicitColour
85 | ImplicitColour
@@ -81,4 +87,5 @@ data ColourType = KeywordColour
81 | TypeColour
87 | TypeColour
82 | DataColour
88 | DataColour
83 | PromptColour
89 | PromptColour
90+ | PostulateColour
84 deriving (Eq, Show, Bounded, Enum)
91 deriving (Eq, Show, Bounded, Enum)
src/Idris/Completion.hs+3−1
@@ -51,7 +51,7 @@ tacticArgs = [ ("intro", Nothing) -- FIXME syntax for intro (fresh name)
51 , (":eval", Just ExprTArg)
51 , (":eval", Just ExprTArg)
52 ] ++ map (\x -> (x, Nothing)) [
52 ] ++ map (\x -> (x, Nothing)) [
53 "intros", "compute", "trivial", "search", "solve", "attack",
53 "intros", "compute", "trivial", "search", "solve", "attack",
54− "state", "term", "undo", "qed", "abandon", ":q"
54+ "unify", "state", "term", "undo", "qed", "abandon", ":q"
55 ]
55 ]
56tactics = map fst tacticArgs
56tactics = map fst tacticArgs
57
57
@@ -112,6 +112,7 @@ completeOption = completeWord Nothing " \t" completeOpt
112 , "showimplicits"
112 , "showimplicits"
113 , "originalerrors"
113 , "originalerrors"
114 , "autosolve"
114 , "autosolve"
115+ , "nobanner"
115 ]
116 ]
116
117
117completeConsoleWidth :: CompletionFunc Idris
118completeConsoleWidth :: CompletionFunc Idris
@@ -160,6 +161,7 @@ completeCmd cmd (prev, next) = fromMaybe completeCmdName $ fmap completeArg $ lo
160 completeArg NameArg = completeExpr [] (prev, next) -- FIXME only complete one name
161 completeArg NameArg = completeExpr [] (prev, next) -- FIXME only complete one name
161 completeArg OptionArg = completeOption (prev, next)
162 completeArg OptionArg = completeOption (prev, next)
162 completeArg ModuleArg = noCompletion (prev, next) -- FIXME do later
163 completeArg ModuleArg = noCompletion (prev, next) -- FIXME do later
164+ completeArg NamespaceArg = noCompletion (prev, next) -- FIXME do later
163 completeArg ExprArg = completeExpr [] (prev, next)
165 completeArg ExprArg = completeExpr [] (prev, next)
164 completeArg MetaVarArg = completeMetaVar (prev, next) -- FIXME only complete one name
166 completeArg MetaVarArg = completeMetaVar (prev, next) -- FIXME only complete one name
165 completeArg ColourArg = completeColour (prev, next)
167 completeArg ColourArg = completeColour (prev, next)
src/Idris/Core/CaseTree.hs+21−1
@@ -10,6 +10,7 @@ import Idris.Core.TT
10import Control.Monad.State
10import Control.Monad.State
11import Data.Maybe
11import Data.Maybe
12import Data.List hiding (partition)
12import Data.List hiding (partition)
13+import qualified Data.List(partition)
13import Debug.Trace
14import Debug.Trace
14
15
15data CaseDef = CaseDef [Name] !SC [Term]
16data CaseDef = CaseDef [Name] !SC [Term]
@@ -417,8 +418,15 @@ order :: [(Name, Bool)] -> [Clause] -> ([Name], [Clause])
417order [] cs = ([], cs)
418order [] cs = ([], cs)
418order ns' [] = (map fst ns', [])
419order ns' [] = (map fst ns', [])
419order ns' cs = let patnames = transpose (map (zip ns') (map fst cs))
420order ns' cs = let patnames = transpose (map (zip ns') (map fst cs))
421+ -- only sort the arguments where there is no clash in
422+ -- constructor tags between families, and no constructor/constant
423+ -- clash, because otherwise we can't reliable make the
424+ -- case distinction on evaluation
425+ (patnames_ord, patnames_rest)
426+ = Data.List.partition (noClash . map snd) patnames
420 -- note: sortBy . reverse is not nonsense because sortBy is stable
427 -- note: sortBy . reverse is not nonsense because sortBy is stable
421− pats' = transpose (sortBy moreDistinct (reverse patnames)) in
428+ pats' = transpose (sortBy moreDistinct (reverse patnames_ord)
429+ ++ patnames_rest) in
422 (getNOrder pats', zipWith rebuild pats' cs)
430 (getNOrder pats', zipWith rebuild pats' cs)
423 where
431 where
424 getNOrder [] = error $ "Failed order on " ++ show (map fst ns', cs)
432 getNOrder [] = error $ "Failed order on " ++ show (map fst ns', cs)
@@ -426,6 +434,16 @@ order ns' cs = let patnames = transpose (map (zip ns') (map fst cs))
426
434
427 rebuild patnames clause = (map snd patnames, snd clause)
435 rebuild patnames clause = (map snd patnames, snd clause)
428
436
437+ noClash [] = True
438+ noClash (p : ps) = not (any (clashPat p) ps) && noClash ps
439+
440+ clashPat (PCon _ _ _) (PConst _) = True
441+ clashPat (PConst _) (PCon _ _ _) = True
442+ clashPat (PCon _ _ _) (PSuc _) = True
443+ clashPat (PSuc _) (PCon _ _ _) = True
444+ clashPat (PCon n i _) (PCon n' i' _) | i == i' = n /= n'
445+ clashPat _ _ = False
446+
429 -- this compares (+isInaccessible, -numberOfCases)
447 -- this compares (+isInaccessible, -numberOfCases)
430 moreDistinct xs ys = compare (snd . fst . head $ xs, numNames [] (map snd ys))
448 moreDistinct xs ys = compare (snd . fst . head $ xs, numNames [] (map snd ys))
431 (snd . fst . head $ ys, numNames [] (map snd xs))
449 (snd . fst . head $ ys, numNames [] (map snd xs))
@@ -694,6 +712,8 @@ substSC n repl (Case n' alts)
694 | n == n' = Case repl (map (substAlt n repl) alts)
712 | n == n' = Case repl (map (substAlt n repl) alts)
695 | otherwise = Case n' (map (substAlt n repl) alts)
713 | otherwise = Case n' (map (substAlt n repl) alts)
696substSC n repl (STerm t) = STerm $ subst n (P Bound repl Erased) t
714substSC n repl (STerm t) = STerm $ subst n (P Bound repl Erased) t
715+substSC n repl (UnmatchedCase errmsg) = UnmatchedCase errmsg
716+substSC n repl ImpossibleCase = ImpossibleCase
697substSC n repl sc = error $ "unsupported in substSC: " ++ show sc
717substSC n repl sc = error $ "unsupported in substSC: " ++ show sc
698
718
699substAlt :: Name -> Name -> CaseAlt -> CaseAlt
719substAlt :: Name -> Name -> CaseAlt -> CaseAlt
src/Idris/Core/Elaborate.hs+14−6
@@ -64,7 +64,7 @@ loadState :: Elab' aux ()
64loadState = do (ES p s e) <- get
64loadState = do (ES p s e) <- get
65 case e of
65 case e of
66 Just st -> put st
66 Just st -> put st
67− _ -> fail "Nothing to undo"
67+ _ -> lift $ Error . Msg $ "Nothing to undo"
68
68
69getNameFrom :: Name -> Elab' aux Name
69getNameFrom :: Name -> Elab' aux Name
70getNameFrom n = do (ES (p, a) s e) <- get
70getNameFrom n = do (ES (p, a) s e) <- get
@@ -328,6 +328,10 @@ start_unify n = processTactic' (StartUnify n)
328end_unify :: Elab' aux ()
328end_unify :: Elab' aux ()
329end_unify = processTactic' EndUnify
329end_unify = processTactic' EndUnify
330
330
331+-- Clear the list of variables not to unify, and try to solve them
332+unify_all :: Elab' aux ()
333+unify_all = processTactic' UnifyAll
334+
331regret :: Elab' aux ()
335regret :: Elab' aux ()
332regret = processTactic' Regret
336regret = processTactic' Regret
333
337
@@ -642,6 +646,7 @@ no_errors tac err
642 Error _ -> lift $ Error e
646 Error _ -> lift $ Error e
643 OK (a, s') -> do put s'
647 OK (a, s') -> do put s'
644 return a
648 return a
649+ unifyProblems
645 ps' <- get_probs
650 ps' <- get_probs
646 if (length ps' > length ps) then
651 if (length ps' > length ps) then
647 case reverse ps' of
652 case reverse ps' of
@@ -676,11 +681,13 @@ try' :: Elab' aux a -> Elab' aux a -> Bool -> Elab' aux a
676try' t1 t2 proofSearch
681try' t1 t2 proofSearch
677 = do s <- get
682 = do s <- get
678 ps <- get_probs
683 ps <- get_probs
684+ ulog <- getUnifyLog
679 case prunStateT 999999 False ps t1 s of
685 case prunStateT 999999 False ps t1 s of
680 OK ((v, _, _), s') -> do put s'
686 OK ((v, _, _), s') -> do put s'
681 return $! v
687 return $! v
688+ Error e1 -> traceWhen ulog ("try failed " ++ show e1) $
682− Error e1 -> if recoverableErr e1 then
689+ if recoverableErr e1 then
683− do case runStateT t2 s of
690+ do case runStateT t2 s of
684 OK (v, s') -> do put s'; return $! v
691 OK (v, s') -> do put s'; return $! v
685 Error e2 -> if score e1 >= score e2
692 Error e2 -> if score e1 >= score e2
686 then lift (tfail e1)
693 then lift (tfail e1)
@@ -690,6 +697,7 @@ try' t1 t2 proofSearch
690 = -- traceWhen r (show err) $
697 = -- traceWhen r (show err) $
691 r || proofSearch
698 r || proofSearch
692 recoverableErr (CantSolveGoal _ _) = False
699 recoverableErr (CantSolveGoal _ _) = False
700+ recoverableErr (ProofSearchFail (Msg _)) = True
693 recoverableErr (ProofSearchFail _) = False
701 recoverableErr (ProofSearchFail _) = False
694 recoverableErr (ElaboratingArg _ _ _ e) = recoverableErr e
702 recoverableErr (ElaboratingArg _ _ _ e) = recoverableErr e
695 recoverableErr (At _ e) = recoverableErr e
703 recoverableErr (At _ e) = recoverableErr e
@@ -701,7 +709,7 @@ tryWhen False a b = a
701
709
702
710
703-- Try a selection of tactics. Exactly one must work, all others must fail
711-- Try a selection of tactics. Exactly one must work, all others must fail
704−tryAll :: [(Elab' aux a, String)] -> Elab' aux a
712+tryAll :: [(Elab' aux a, Name)] -> Elab' aux a
705tryAll xs = tryAll' [] 999999 (cantResolve, 0) xs
713tryAll xs = tryAll' [] 999999 (cantResolve, 0) xs
706 where
714 where
707 cantResolve :: Elab' aux a
715 cantResolve :: Elab' aux a
@@ -710,7 +718,7 @@ tryAll xs = tryAll' [] 999999 (cantResolve, 0) xs
710 tryAll' :: [Elab' aux a] -> -- successes
718 tryAll' :: [Elab' aux a] -> -- successes
711 Int -> -- most problems
719 Int -> -- most problems
712 (Elab' aux a, Int) -> -- smallest failure
720 (Elab' aux a, Int) -> -- smallest failure
713− [(Elab' aux a, String)] -> -- still to try
721+ [(Elab' aux a, Name)] -> -- still to try
714 Elab' aux a
722 Elab' aux a
715 tryAll' [res] pmax _ [] = res
723 tryAll' [res] pmax _ [] = res
716 tryAll' (_:_) pmax _ [] = cantResolve
724 tryAll' (_:_) pmax _ [] = cantResolve
@@ -719,7 +727,7 @@ tryAll xs = tryAll' [] 999999 (cantResolve, 0) xs
719 = do s <- get
727 = do s <- get
720 ps <- get_probs
728 ps <- get_probs
721 case prunStateT pmax True ps x s of
729 case prunStateT pmax True ps x s of
722− OK ((v, newps, probs), s') ->
730+ OK ((v, newps, probs), s') ->
723 do let cs' = if (newps < pmax)
731 do let cs' = if (newps < pmax)
724 then [do put s'; return $! v]
732 then [do put s'; return $! v]
725 else (do put s'; return $! v) : cs
733 else (do put s'; return $! v) : cs
src/Idris/Core/Evaluate.hs+32−10
@@ -8,10 +8,10 @@ module Idris.Core.Evaluate(normalise, normaliseTrace, normaliseC, normaliseAll,
8 Context, initContext, ctxtAlist, uconstraints, next_tvar,
8 Context, initContext, ctxtAlist, uconstraints, next_tvar,
9 addToCtxt, setAccess, setTotal, setMetaInformation, addCtxtDef, addTyDecl,
9 addToCtxt, setAccess, setTotal, setMetaInformation, addCtxtDef, addTyDecl,
10 addDatatype, addCasedef, simplifyCasedef, addOperator,
10 addDatatype, addCasedef, simplifyCasedef, addOperator,
11− lookupNames, lookupTy, lookupP, lookupDef, lookupDefExact, lookupDefAcc, lookupVal,
11+ lookupNames, lookupTyName, lookupTy, lookupP, lookupDef, lookupNameDef, lookupDefExact, lookupDefAcc, lookupVal,
12 mapDefCtxt,
12 mapDefCtxt,
13 lookupTotal, lookupNameTotal, lookupMetaInformation, lookupTyEnv, isDConName, isTConName, isConName, isFnName,
13 lookupTotal, lookupNameTotal, lookupMetaInformation, lookupTyEnv, isDConName, isTConName, isConName, isFnName,
14− Value(..), Quote(..), initEval, uniqueNameCtxt, definitions) where
14+ Value(..), Quote(..), initEval, uniqueNameCtxt, uniqueBindersCtxt, definitions) where
15
15
16import Debug.Trace
16import Debug.Trace
17import Control.Applicative hiding (Const)
17import Control.Applicative hiding (Const)
@@ -537,7 +537,7 @@ wknV i t = return t
537convEq' ctxt hs x y = evalStateT (convEq ctxt hs x y) (0, [])
537convEq' ctxt hs x y = evalStateT (convEq ctxt hs x y) (0, [])
538
538
539convEq :: Context -> [Name] -> TT Name -> TT Name -> StateT UCs (TC' Err) Bool
539convEq :: Context -> [Name] -> TT Name -> TT Name -> StateT UCs (TC' Err) Bool
540−convEq ctxt holes = ceq [] where
540+convEq ctxt holes topx topy = ceq [] topx topy where
541 ceq :: [(Name, Name)] -> TT Name -> TT Name -> StateT UCs (TC' Err) Bool
541 ceq :: [(Name, Name)] -> TT Name -> TT Name -> StateT UCs (TC' Err) Bool
542 ceq ps (P xt x _) (P yt y _)
542 ceq ps (P xt x _) (P yt y _)
543 | x `elem` holes || y `elem` holes = return True
543 | x `elem` holes || y `elem` holes = return True
@@ -550,8 +550,12 @@ convEq ctxt holes = ceq [] where
550 ceq ps (Bind n (Lam t) (App x (P Bound n' _))) y
550 ceq ps (Bind n (Lam t) (App x (P Bound n' _))) y
551 | n == n' = ceq ps x y
551 | n == n' = ceq ps x y
552 ceq ps (V x) (V y) = return (x == y)
552 ceq ps (V x) (V y) = return (x == y)
553− ceq ps (V x) (P _ y _) = return (fst (ps!!x) == y)
553+ ceq ps (V x) (P _ y _)
554+ | x >= 0 && length ps > x = return (fst (ps!!x) == y)
555+ | otherwise = return False
554− ceq ps (P _ x _) (V y) = return (x == snd (ps!!y))
556+ ceq ps (P _ x _) (V y)
557+ | y >= 0 && length ps > y = return (x == snd (ps!!y))
558+ | otherwise = return False
555 ceq ps (Bind n xb xs) (Bind n' yb ys)
559 ceq ps (Bind n xb xs) (Bind n' yb ys)
556 = liftM2 (&&) (ceqB ps xb yb) (ceq ((n,n'):ps) xs ys)
560 = liftM2 (&&) (ceqB ps xb yb) (ceq ((n,n'):ps) xs ys)
557 where
561 where
@@ -678,7 +682,7 @@ data Totality = Total [Int] -- ^ well-founded arguments
678
682
679-- | Reasons why a function may not be total
683-- | Reasons why a function may not be total
680data PReason = Other [Name] | Itself | NotCovering | NotPositive | UseUndef Name
684data PReason = Other [Name] | Itself | NotCovering | NotPositive | UseUndef Name
681− | BelieveMe | Mutual [Name] | NotProductive
685+ | ExternalIO | BelieveMe | Mutual [Name] | NotProductive
682 deriving (Show, Eq)
686 deriving (Show, Eq)
683
687
684instance Show Totality where
688instance Show Totality where
@@ -688,6 +692,7 @@ instance Show Totality where
688 show (Partial Itself) = "possibly not total as it is not well founded"
692 show (Partial Itself) = "possibly not total as it is not well founded"
689 show (Partial NotCovering) = "not total as there are missing cases"
693 show (Partial NotCovering) = "not total as there are missing cases"
690 show (Partial NotPositive) = "not strictly positive"
694 show (Partial NotPositive) = "not strictly positive"
695+ show (Partial ExternalIO) = "an external IO primitive"
691 show (Partial NotProductive) = "not productive"
696 show (Partial NotProductive) = "not productive"
692 show (Partial BelieveMe) = "not total due to use of believe_me in proof"
697 show (Partial BelieveMe) = "not total due to use of believe_me in proof"
693 show (Partial (Other ns)) = "possibly not total due to: " ++ showSep ", " (map show ns)
698 show (Partial (Other ns)) = "possibly not total due to: " ++ showSep ", " (map show ns)
@@ -863,14 +868,19 @@ lookupNames n ctxt
863 = let ns = lookupCtxtName n (definitions ctxt) in
868 = let ns = lookupCtxtName n (definitions ctxt) in
864 map fst ns
869 map fst ns
865
870
866−lookupTy :: Name -> Context -> [Type]
871+lookupTyName :: Name -> Context -> [(Name, Type)]
867−lookupTy n ctxt
872+lookupTyName n ctxt = do
868− = do def <- lookupCtxt n (definitions ctxt)
873+ (name, def) <- lookupCtxtName n (definitions ctxt)
869− case tfst def of
874+ ty <- case tfst def of
870 (Function ty _) -> return ty
875 (Function ty _) -> return ty
871 (TyDecl _ ty) -> return ty
876 (TyDecl _ ty) -> return ty
872 (Operator ty _ _) -> return ty
877 (Operator ty _ _) -> return ty
873 (CaseOp _ ty _ _ _ _) -> return ty
878 (CaseOp _ ty _ _ _ _) -> return ty
879+ return (name, ty)
880+
881+
882+lookupTy :: Name -> Context -> [Type]
883+lookupTy n ctxt = map snd (lookupTyName n ctxt)
874
884
875isConName :: Name -> Context -> Bool
885isConName :: Name -> Context -> Bool
876isConName n ctxt = isTConName n ctxt || isDConName n ctxt
886isConName n ctxt = isTConName n ctxt || isDConName n ctxt
@@ -916,6 +926,11 @@ lookupDefExact n ctxt = tfst <$> lookupCtxtExact n (definitions ctxt)
916lookupDef :: Name -> Context -> [Def]
926lookupDef :: Name -> Context -> [Def]
917lookupDef n ctxt = tfst <$> lookupCtxt n (definitions ctxt)
927lookupDef n ctxt = tfst <$> lookupCtxt n (definitions ctxt)
918
928
929+lookupNameDef :: Name -> Context -> [(Name, Def)]
930+lookupNameDef n ctxt = mapSnd tfst $ lookupCtxtName n (definitions ctxt)
931+ where mapSnd f [] = []
932+ mapSnd f ((x,y):xys) = (x, f y) : mapSnd f xys
933+
919lookupDefAcc :: Name -> Bool -> Context ->
934lookupDefAcc :: Name -> Bool -> Context ->
920 [(Def, Accessibility)]
935 [(Def, Accessibility)]
921lookupDefAcc n mkpublic ctxt
936lookupDefAcc n mkpublic ctxt
@@ -956,3 +971,10 @@ uniqueNameCtxt ctxt n hs
956 | n `elem` hs = uniqueNameCtxt ctxt (nextName n) hs
971 | n `elem` hs = uniqueNameCtxt ctxt (nextName n) hs
957 | [_] <- lookupTy n ctxt = uniqueNameCtxt ctxt (nextName n) hs
972 | [_] <- lookupTy n ctxt = uniqueNameCtxt ctxt (nextName n) hs
958 | otherwise = n
973 | otherwise = n
974+
975+uniqueBindersCtxt :: Context -> [Name] -> TT Name -> TT Name
976+uniqueBindersCtxt ctxt ns (Bind n b sc)
977+ = let n' = uniqueNameCtxt ctxt n ns in
978+ Bind n' (fmap (uniqueBindersCtxt ctxt (n':ns)) b) (uniqueBindersCtxt ctxt ns sc)
979+uniqueBindersCtxt ctxt ns (App f a) = App (uniqueBindersCtxt ctxt ns f) (uniqueBindersCtxt ctxt ns a)
980+uniqueBindersCtxt ctxt ns t = t
src/Idris/Core/Execute.hs+98−61
@@ -11,6 +11,8 @@ import Idris.Core.TT
11import Idris.Core.Evaluate
11import Idris.Core.Evaluate
12import Idris.Core.CaseTree
12import Idris.Core.CaseTree
13
13
14+import Idris.Error
15+
14import Debug.Trace
16import Debug.Trace
15
17
16import Util.DynamicLinker
18import Util.DynamicLinker
@@ -113,9 +115,9 @@ initState :: Idris ExecState
113initState = do ist <- getIState
115initState = do ist <- getIState
114 return $ ExecState (idris_dynamic_libs ist)
116 return $ ExecState (idris_dynamic_libs ist)
115
117
116−type Exec = ErrorT String (StateT ExecState IO)
118+type Exec = ErrorT Err (StateT ExecState IO)
117
119
118−runExec :: Exec a -> ExecState -> IO (Either String a)
120+runExec :: Exec a -> ExecState -> IO (Either Err a)
119runExec ex st = fst <$> runStateT (runErrorT ex) st
121runExec ex st = fst <$> runStateT (runErrorT ex) st
120
122
121getExecState :: Exec ExecState
123getExecState :: Exec ExecState
@@ -124,7 +126,7 @@ getExecState = lift get
124putExecState :: ExecState -> Exec ()
126putExecState :: ExecState -> Exec ()
125putExecState = lift . put
127putExecState = lift . put
126
128
127−execFail :: String -> Exec a
129+execFail :: Err -> Exec a
128execFail = throwError
130execFail = throwError
129
131
130execIO :: IO a -> Exec a
132execIO :: IO a -> Exec a
@@ -138,7 +140,7 @@ execute tm = do est <- initState
138 do res <- doExec [] ctxt tm
140 do res <- doExec [] ctxt tm
139 toTT res
141 toTT res
140 case res of
142 case res of
141− Left err -> fail err
143+ Left err -> ierror err
142 Right tm' -> return tm'
144 Right tm' -> return tm'
143
145
144ioWrap :: ExecVal -> ExecVal
146ioWrap :: ExecVal -> ExecVal
@@ -160,16 +162,16 @@ doExec env ctxt p@(P Ref n ty) =
160 [CaseOp _ _ _ _ _ (CaseDefs _ ([], STerm tm) _ _)] -> -- nullary fun
162 [CaseOp _ _ _ _ _ (CaseDefs _ ([], STerm tm) _ _)] -> -- nullary fun
161 doExec env ctxt tm
163 doExec env ctxt tm
162 [CaseOp _ _ _ _ _ (CaseDefs _ (ns, sc) _ _)] -> return (EP Ref n EErased)
164 [CaseOp _ _ _ _ _ (CaseDefs _ (ns, sc) _ _)] -> return (EP Ref n EErased)
163− [] -> execFail $ "Could not find " ++ show n ++ " in definitions."
165+ [] -> execFail . Msg $ "Could not find " ++ show n ++ " in definitions."
164 thing -> trace (take 200 $ "got to " ++ show thing ++ " lookup up " ++ show n) $ undefined
166 thing -> trace (take 200 $ "got to " ++ show thing ++ " lookup up " ++ show n) $ undefined
165doExec env ctxt p@(P Bound n ty) =
167doExec env ctxt p@(P Bound n ty) =
166 case lookup n env of
168 case lookup n env of
167− Nothing -> execFail "not found"
169+ Nothing -> execFail . Msg $ "not found"
168 Just tm -> return tm
170 Just tm -> return tm
169doExec env ctxt (P (DCon a b) n _) = return (EP (DCon a b) n EErased)
171doExec env ctxt (P (DCon a b) n _) = return (EP (DCon a b) n EErased)
170doExec env ctxt (P (TCon a b) n _) = return (EP (TCon a b) n EErased)
172doExec env ctxt (P (TCon a b) n _) = return (EP (TCon a b) n EErased)
171doExec env ctxt v@(V i) | i < length env = return (snd (env !! i))
173doExec env ctxt v@(V i) | i < length env = return (snd (env !! i))
172− | otherwise = execFail "env too small"
174+ | otherwise = execFail . Msg $ "env too small"
173doExec env ctxt (Bind n (Let t v) body) = do v' <- doExec env ctxt v
175doExec env ctxt (Bind n (Let t v) body) = do v' <- doExec env ctxt v
174 doExec ((n, v'):env) ctxt body
176 doExec ((n, v'):env) ctxt body
175doExec env ctxt (Bind n (NLet t v) body) = trace "NLet" $ undefined
177doExec env ctxt (Bind n (NLet t v) body) = trace "NLet" $ undefined
@@ -216,71 +218,107 @@ execApp env ctxt con@(EP _ fp _) args@(tp:v:rest)
216 | fp == pioret = execApp env ctxt (mkEApp con [tp, v]) rest
218 | fp == pioret = execApp env ctxt (mkEApp con [tp, v]) rest
217
219
218-- Special cases arising from not having access to the C RTS in the interpreter
220-- Special cases arising from not having access to the C RTS in the interpreter
219−execApp env ctxt (EP _ fp _) (_:fn:EConstant (Str arg):_:rest)
221+execApp env ctxt (EP _ fp _) (_:fn:str:_:rest)
222+ | fp == mkfprim,
223+ Just (FFun "putStr" _ _) <- foreignFromTT fn
224+ = case str of
225+ EConstant (Str arg) -> do execIO (putStr arg)
226+ execApp env ctxt ioUnit rest
227+ _ -> execFail . Msg $
228+ "The argument to putStr should be a constant string, but it was " ++
229+ show str ++
230+ ". Are all cases covered?"
231+execApp env ctxt (EP _ fp _) (_:fn:ch:_:rest)
220 | fp == mkfprim,
232 | fp == mkfprim,
221− Just (FFun "putStr" _ _) <- foreignFromTT fn
233+ Just (FFun "putchar" _ _) <- foreignFromTT fn
222− = do execIO (putStr arg)
234+ = case ch of
235+ EConstant (Ch c) -> do execIO (putChar c)
236+ execApp env ctxt ioUnit rest
237+ EConstant (I i) -> do execIO (putChar (toEnum i))
223− execApp env ctxt ioUnit rest
238+ execApp env ctxt ioUnit rest
239+ _ -> execFail . Msg $
240+ "The argument to putchar should be a constant character, but it was " ++
241+ show str ++
242+ ". Are all cases covered?"
224−execApp env ctxt (EP _ fp _) (_:fn:_:EHandle h:_:rest)
243+execApp env ctxt (EP _ fp _) (_:fn:_:handle:_:rest)
225 | fp == mkfprim,
244 | fp == mkfprim,
226 Just (FFun "idris_readStr" _ _) <- foreignFromTT fn
245 Just (FFun "idris_readStr" _ _) <- foreignFromTT fn
246+ = case handle of
227− = do contents <- execIO $ hGetLine h
247+ EHandle h -> do contents <- execIO $ hGetLine h
228− execApp env ctxt (EConstant (Str (contents ++ "\n"))) rest
248+ execApp env ctxt (EConstant (Str (contents ++ "\n"))) rest
249+ _ -> execFail . Msg $
250+ "The argument to idris_readStr should be a handle, but it was " ++
251+ show handle ++
252+ ". Are all cases covered?"
229−execApp env ctxt (EP _ fp _) (_:fn:EConstant (Str f):EConstant (Str mode):rest)
253+execApp env ctxt (EP _ fp _) (_:fn:fileStr:modeStr:rest)
230 | fp == mkfprim,
254 | fp == mkfprim,
231 Just (FFun "fileOpen" _ _) <- foreignFromTT fn
255 Just (FFun "fileOpen" _ _) <- foreignFromTT fn
256+ = case (fileStr, modeStr) of
257+ (EConstant (Str f), EConstant (Str mode)) ->
232− = do f <- execIO $
258+ do f <- execIO $
233− catch (do let m = case mode of
259+ catch (do let m = case mode of
234− "r" -> Right ReadMode
260+ "r" -> Right ReadMode
235− "w" -> Right WriteMode
261+ "w" -> Right WriteMode
236− "a" -> Right AppendMode
262+ "a" -> Right AppendMode
237− "rw" -> Right ReadWriteMode
263+ "rw" -> Right ReadWriteMode
238− "wr" -> Right ReadWriteMode
264+ "wr" -> Right ReadWriteMode
239− "r+" -> Right ReadWriteMode
265+ "r+" -> Right ReadWriteMode
240− _ -> Left ("Invalid mode for " ++ f ++ ": " ++ mode)
266+ _ -> Left ("Invalid mode for " ++ f ++ ": " ++ mode)
241− case fmap (openFile f) m of
267+ case fmap (openFile f) m of
242− Right h -> do h' <- h; return $ Right (ioWrap (EHandle h'), tail rest)
268+ Right h -> do h' <- h; return $ Right (ioWrap (EHandle h'), tail rest)
243− Left err -> return $ Left err)
269+ Left err -> return $ Left err)
244− (\e -> let _ = ( e::SomeException)
270+ (\e -> let _ = ( e::SomeException)
245− in return $ Right (ioWrap (EPtr nullPtr), tail rest))
271+ in return $ Right (ioWrap (EPtr nullPtr), tail rest))
246− case f of
272+ case f of
247− Left err -> execFail err
273+ Left err -> execFail . Msg $ err
248− Right (res, rest) -> execApp env ctxt res rest
274+ Right (res, rest) -> execApp env ctxt res rest
249−
275+ _ -> execFail . Msg $
276+ "The arguments to fileOpen should be constant strings, but they were " ++
277+ show fileStr ++ " and " ++ show modeStr ++
278+ ". Are all cases covered?"
279+
250−execApp env ctxt (EP _ fp _) (_:fn:(EHandle h):rest)
280+execApp env ctxt (EP _ fp _) (_:fn:handle:rest)
251 | fp == mkfprim,
281 | fp == mkfprim,
252 Just (FFun "fileEOF" _ _) <- foreignFromTT fn
282 Just (FFun "fileEOF" _ _) <- foreignFromTT fn
283+ = case handle of
253− = do eofp <- execIO $ hIsEOF h
284+ EHandle h -> do eofp <- execIO $ hIsEOF h
254− let res = ioWrap (EConstant (I $ if eofp then 1 else 0))
285+ let res = ioWrap (EConstant (I $ if eofp then 1 else 0))
255− execApp env ctxt res (tail rest)
286+ execApp env ctxt res (tail rest)
256−
287+ _ -> execFail . Msg $
288+ "The argument to fileEOF should be a file handle, but it was " ++
289+ show handle ++
290+ ". Are all cases covered?"
291+
257−execApp env ctxt (EP _ fp _) (_:fn:(EHandle h):rest)
292+execApp env ctxt (EP _ fp _) (_:fn:handle:rest)
258 | fp == mkfprim,
293 | fp == mkfprim,
259 Just (FFun "fileClose" _ _) <- foreignFromTT fn
294 Just (FFun "fileClose" _ _) <- foreignFromTT fn
295+ = case handle of
260− = do execIO $ hClose h
296+ EHandle h -> do execIO $ hClose h
261− execApp env ctxt ioUnit (tail rest)
297+ execApp env ctxt ioUnit (tail rest)
262−
298+ _ -> execFail . Msg $
299+ "The argument to fileClose should be a file handle, but it was " ++
300+ show handle ++
301+ ". Are all cases covered?"
302+
263−execApp env ctxt (EP _ fp _) (_:fn:(EPtr p):rest)
303+execApp env ctxt (EP _ fp _) (_:fn:ptr:rest)
264 | fp == mkfprim,
304 | fp == mkfprim,
265 Just (FFun "isNull" _ _) <- foreignFromTT fn
305 Just (FFun "isNull" _ _) <- foreignFromTT fn
306+ = case ptr of
266− = let res = ioWrap . EConstant . I $
307+ EPtr p -> let res = ioWrap . EConstant . I $
267− if p == nullPtr then 1 else 0
308+ if p == nullPtr then 1 else 0
309+ in execApp env ctxt res (tail rest)
310+ -- Handles will be checked as null pointers sometimes - but if we got a
311+ -- real Handle, then it's valid, so just return 1.
312+ EHandle h -> let res = ioWrap . EConstant . I $ 0
313+ in execApp env ctxt res (tail rest)
314+ -- A foreign-returned char* has to be tested for NULL sometimes
315+ EConstant (Str s) -> let res = ioWrap . EConstant . I $ 0
268− in execApp env ctxt res (tail rest)
316+ in execApp env ctxt res (tail rest)
317+ _ -> execFail . Msg $
318+ "The argument to isNull should be a pointer or file handle or string, but it was " ++
319+ show ptr ++
320+ ". Are all cases covered?"
269
321
270−-- Handles will be checked as null pointers sometimes - but if we got a
271−-- real Handle, then it's valid, so just return 1.
272−execApp env ctxt (EP _ fp _) (_:fn:(EHandle h):rest)
273− | fp == mkfprim,
274− Just (FFun "isNull" _ _) <- foreignFromTT fn
275− = let res = ioWrap . EConstant . I $ 0
276− in execApp env ctxt res (tail rest)
277−
278−-- A foreign-returned char* has to be tested for NULL sometimes
279−execApp env ctxt (EP _ fp _) (_:fn:EConstant (Str s):rest)
280− | fp == mkfprim,
281− Just (FFun "isNull" _ _) <- foreignFromTT fn
282− = let res = ioWrap . EConstant . I $ 0
283− in execApp env ctxt res (tail rest)
284
322
285-- Right now, there's no way to send command-line arguments to the executor,
323-- Right now, there's no way to send command-line arguments to the executor,
286-- so just return 0.
324-- so just return 0.
@@ -289,7 +327,6 @@ execApp env ctxt (EP _ fp _) (_:fn:rest)
289 Just (FFun "idris_numArgs" _ _) <- foreignFromTT fn
327 Just (FFun "idris_numArgs" _ _) <- foreignFromTT fn
290 = let res = ioWrap . EConstant . I $ 0
328 = let res = ioWrap . EConstant . I $ 0
291 in execApp env ctxt res (tail rest)
329 in execApp env ctxt res (tail rest)
292−-- Throw away the 'World' argument to the foreign function
293
330
294execApp env ctxt f@(EP _ fp _) args@(ty:fn:xs) | fp == mkfprim
331execApp env ctxt f@(EP _ fp _) args@(ty:fn:xs) | fp == mkfprim
295 = case foreignFromTT fn of
332 = case foreignFromTT fn of
src/Idris/Core/ProofState.hs+53−13
@@ -15,7 +15,7 @@ import Idris.Core.Unify
15
15
16import Control.Monad.State.Strict
16import Control.Monad.State.Strict
17import Control.Applicative hiding (empty)
17import Control.Applicative hiding (empty)
18−import Control.Arrow (first)
18+import Control.Arrow ((***))
19import Data.List
19import Data.List
20import Debug.Trace
20import Debug.Trace
21
21
@@ -59,6 +59,7 @@ data Tactic = Attack
59 | Solve
59 | Solve
60 | StartUnify Name
60 | StartUnify Name
61 | EndUnify
61 | EndUnify
62+ | UnifyAll
62 | Compute
63 | Compute
63 | ComputeLet Name
64 | ComputeLet Name
64 | Simplify
65 | Simplify
@@ -179,6 +180,19 @@ match_unify' ctxt env topx topy =
179-- -- ++ show (pterm ps)
180-- -- ++ show (pterm ps)
180-- ++ "\n----------") $
181-- ++ "\n----------") $
181
182
183+mergeSolutions :: Env -> [(Name, TT Name)] -> StateT TState TC [(Name, TT Name)]
184+mergeSolutions env ns = merge [] ns
185+ where
186+ merge acc [] = return (reverse acc)
187+ merge acc ((n, t) : ns)
188+ | Just t' <- lookup n ns
189+ = do ps <- get
190+ let probs = problems ps
191+ put (ps { problems = probs ++ [(t,t',env,Msg "New problem",
192+ [], Unify)] })
193+ merge acc ns
194+ | otherwise = merge ((n, t): acc) ns
195+
182unify' :: Context -> Env -> TT Name -> TT Name ->
196unify' :: Context -> Env -> TT Name -> TT Name ->
183 StateT TState TC [(Name, TT Name)]
197 StateT TState TC [(Name, TT Name)]
184unify' ctxt env topx topy =
198unify' ctxt env topx topy =
@@ -205,16 +219,22 @@ unify' ctxt env topx topy =
205 ++ "\nCurrent problems:\n" ++ qshow (problems ps)
219 ++ "\nCurrent problems:\n" ++ qshow (problems ps)
206-- ++ show (pterm ps)
220-- ++ show (pterm ps)
207 ++ "\n----------") $
221 ++ "\n----------") $
208− do ps <- get
209− let (h, ns) = unified ps
222+ do let (h, ns) = unified ps
223+ -- if a metavar has multiple solutions, make a new unification
224+ -- problem for each.
225+ uns <- mergeSolutions env (u ++ ns)
226+ ps <- get
210− let (ns', probs') = updateProblems (context ps) (u ++ ns)
227+ let (ns', probs') = updateProblems (context ps) uns
211 (fails ++ problems ps)
228 (fails ++ problems ps)
212 (injective ps)
229 (injective ps)
213 (holes ps)
230 (holes ps)
231+ let (notu', probs_notu) = mergeNotunified env (notu ++ notunified ps)
232+ traceWhen (unifylog ps)
233+ ("Now solved: " ++ show ns') $
214− put (ps { problems = probs',
234+ put (ps { problems = probs' ++ probs_notu,
215− unified = (h, ns'),
235+ unified = (h, ns'),
216− injective = updateInj u (injective ps),
236+ injective = updateInj u (injective ps),
217− notunified = notu ++ notunified ps })
237+ notunified = notu' })
218 return u
238 return u
219 where updateInj ((n, a) : us) inj
239 where updateInj ((n, a) : us) inj
220 | (P _ n' _, _) <- unApply a,
240 | (P _ n' _, _) <- unApply a,
@@ -664,7 +684,7 @@ induction nm ctxt env (Bind x (Hole t) (P _ x' _)) | x == x' = do
664 let scr = last $ tail args'
684 let scr = last $ tail args'
665 let indxnames = makeIndexNames indicies
685 let indxnames = makeIndexNames indicies
666 prop <- replaceIndicies indxnames indicies $ Bind nm (Lam tmt') t
686 prop <- replaceIndicies indxnames indicies $ Bind nm (Lam tmt') t
667− consargs' <- query (\ps -> map (first $ flip (uniqueNameCtxt (context ps)) (holes ps)) consargs)
687+ consargs' <- query (\ps -> map (flip (uniqueNameCtxt (context ps)) (holes ps ++ allTTNames (pterm ps)) *** uniqueBindersCtxt (context ps) (holes ps ++ allTTNames (pterm ps))) consargs)
668 let res = flip (foldr substV) params $ (substV prop $ bindConsArgs consargs' (mkApp (P Ref (SN (ElimN tnm)) (TType (UVal 0)))
688 let res = flip (foldr substV) params $ (substV prop $ bindConsArgs consargs' (mkApp (P Ref (SN (ElimN tnm)) (TType (UVal 0)))
669 (params ++ [prop] ++ map makeConsArg consargs' ++ indicies ++ [tmv])))
689 (params ++ [prop] ++ map makeConsArg consargs' ++ indicies ++ [tmv])))
670 action (\ps -> ps {holes = holes ps \\ [x]})
690 action (\ps -> ps {holes = holes ps \\ [x]})
@@ -781,13 +801,15 @@ keepGiven du (u@(n, _) : us) hs
781 | n `elem` du = u : keepGiven du us hs
801 | n `elem` du = u : keepGiven du us hs
782keepGiven du (u : us) hs = keepGiven du us hs
802keepGiven du (u : us) hs = keepGiven du us hs
783
803
804+updateSolved :: [(Name, Term)] -> Term -> Term
784updateSolved xs x = updateSolved' xs x
805updateSolved xs x = updateSolved' xs x
785updateSolved' [] x = x
806updateSolved' [] x = x
786updateSolved' xs (Bind n (Hole ty) t)
807updateSolved' xs (Bind n (Hole ty) t)
787 | Just v <- lookup n xs
808 | Just v <- lookup n xs
788 = case xs of
809 = case xs of
789− [_] -> psubst n v t
810+ [_] -> substV v $ psubst n v t -- some may be Vs! Can't assume
811+ -- explicit names
790− _ -> psubst n v (updateSolved' xs t)
812+ _ -> substV v $ psubst n v (updateSolved' xs t)
791updateSolved' xs (Bind n b t)
813updateSolved' xs (Bind n b t)
792 | otherwise = Bind n (fmap (updateSolved' xs) b) (updateSolved' xs t)
814 | otherwise = Bind n (fmap (updateSolved' xs) b) (updateSolved' xs t)
793updateSolved' xs (App f a)
815updateSolved' xs (App f a)
@@ -801,6 +823,10 @@ updateEnv ns [] = []
801updateEnv ns ((n, b) : env) = (n, fmap (updateSolved ns) b) : updateEnv ns env
823updateEnv ns ((n, b) : env) = (n, fmap (updateSolved ns) b) : updateEnv ns env
802
824
803updateError [] err = err
825updateError [] err = err
826+updateError ns (At f e) = At f (updateError ns e)
827+updateError ns (Elaborating s n e) = Elaborating s n (updateError ns e)
828+updateError ns (ElaboratingArg f a env e)
829+ = ElaboratingArg f a env (updateError ns e)
804updateError ns (CantUnify b l r e xs sc)
830updateError ns (CantUnify b l r e xs sc)
805 = CantUnify b (updateSolved ns l) (updateSolved ns r) (updateError ns e) xs sc
831 = CantUnify b (updateSolved ns l) (updateSolved ns r) (updateError ns e) xs sc
806updateError ns e = e
832updateError ns e = e
@@ -810,6 +836,15 @@ solveInProblems x val ((l, r, env, err) : ps)
810 = ((psubst x val l, psubst x val r,
836 = ((psubst x val l, psubst x val r,
811 updateEnv [(x, val)] env, err) : solveInProblems x val ps)
837 updateEnv [(x, val)] env, err) : solveInProblems x val ps)
812
838
839+mergeNotunified :: Env -> [(Name, Term)] -> ([(Name, Term)], Fails)
840+mergeNotunified env ns = mnu ns [] [] where
841+ mnu [] ns_acc ps_acc = (reverse ns_acc, reverse ps_acc)
842+ mnu ((n, t):ns) ns_acc ps_acc
843+ | Just t' <- lookup n ns, t /= t'
844+ = mnu ns ((n,t') : ns_acc)
845+ ((t,t',env,Msg "", [],Unify) : ps_acc)
846+ | otherwise = mnu ns ((n,t) : ns_acc) ps_acc
847+
813updateNotunified [] nu = nu
848updateNotunified [] nu = nu
814updateNotunified ns nu = up nu where
849updateNotunified ns nu = up nu where
815 up [] = []
850 up [] = []
@@ -826,7 +861,7 @@ updateProblems ctxt ns ps inj holes = up ns ps where
826 y' = updateSolved ns y
861 y' = updateSolved ns y
827 err' = updateError ns err
862 err' = updateError ns err
828 env' = updateEnv ns env in
863 env' = updateEnv ns env in
829−-- trace ("Updating " ++ show (x',y')) $
864+-- trace ("Updating " ++ show (x',y')) $
830 case unify ctxt env' x' y' inj holes while of
865 case unify ctxt env' x' y' inj holes while of
831 OK (v, []) -> -- trace ("Added " ++ show v ++ " from " ++ show (x', y')) $
866 OK (v, []) -> -- trace ("Added " ++ show v ++ " from " ++ show (x', y')) $
832 up (ns ++ v) ps
867 up (ns ++ v) ps
@@ -860,7 +895,7 @@ processTactic QED ps = case holes ps of
860 _ -> fail "Still holes to fill."
895 _ -> fail "Still holes to fill."
861processTactic ProofState ps = return (ps, showEnv [] (pterm ps))
896processTactic ProofState ps = return (ps, showEnv [] (pterm ps))
862processTactic Undo ps = case previous ps of
897processTactic Undo ps = case previous ps of
863− Nothing -> fail "Nothing to undo."
898+ Nothing -> Error . Msg $ "Nothing to undo."
864 Just pold -> return (pold, "")
899 Just pold -> return (pold, "")
865processTactic EndUnify ps
900processTactic EndUnify ps
866 = let (h, ns_in) = unified ps
901 = let (h, ns_in) = unified ps
@@ -874,6 +909,11 @@ processTactic EndUnify ps
874 problems = probs',
909 problems = probs',
875 notunified = updateNotunified ns'' (notunified ps),
910 notunified = updateNotunified ns'' (notunified ps),
876 holes = holes ps \\ map fst ns'' }, "")
911 holes = holes ps \\ map fst ns'' }, "")
912+processTactic UnifyAll ps
913+ = let tm' = updateSolved (notunified ps) (pterm ps) in
914+ return (ps { pterm = tm',
915+ notunified = [],
916+ holes = holes ps \\ map fst (notunified ps) }, "")
877processTactic (Reorder n) ps
917processTactic (Reorder n) ps
878 = do ps' <- execStateT (tactic (Just n) reorder_claims) ps
918 = do ps' <- execStateT (tactic (Just n) reorder_claims) ps
879 return (ps' { previous = Just ps, plog = "" }, plog ps')
919 return (ps' { previous = Just ps, plog = "" }, plog ps')
src/Idris/Core/TC.hs+9
@@ -2,6 +2,7 @@
2
2
3module Idris.Core.TC(TC'(..)) where
3module Idris.Core.TC(TC'(..)) where
4
4
5+import Control.Applicative
5import Control.Monad
6import Control.Monad
6import Control.Monad.Trans.Error(Error(..))
7import Control.Monad.Trans.Error(Error(..))
7
8
@@ -26,3 +27,11 @@ instance Error e => MonadPlus (TC' e) where
26 _ `mplus` (OK y) = OK y
27 _ `mplus` (OK y) = OK y
27 err `mplus` _ = err
28 err `mplus` _ = err
28
29
30+
31+instance Error e => Applicative (TC' e) where
32+ pure = return
33+ (<*>) = ap
34+
35+instance Error e => Alternative (TC' e) where
36+ empty = mzero
37+ (<|>) = mplus
src/Idris/Core/TT.hs+84−10
@@ -27,6 +27,7 @@ import Control.Monad.Trans.Error (Error(..))
27import Debug.Trace
27import Debug.Trace
28import qualified Data.Map.Strict as Map
28import qualified Data.Map.Strict as Map
29import Data.Char
29import Data.Char
30+import Numeric (showIntAtBase)
30import qualified Data.Text as T
31import qualified Data.Text as T
31import Data.List
32import Data.List
32import Data.Maybe (listToMaybe)
33import Data.Maybe (listToMaybe)
@@ -82,7 +83,7 @@ instance Show FC where
82 | otherwise = show sl ++ ":" ++ show sc ++ "-" ++ show el ++ ":" ++ show ec
83 | otherwise = show sl ++ ":" ++ show sc ++ "-" ++ show el ++ ":" ++ show ec
83
84
84-- | Output annotation for pretty-printed name - decides colour
85-- | Output annotation for pretty-printed name - decides colour
85−data NameOutput = TypeOutput | FunOutput | DataOutput | MetavarOutput
86+data NameOutput = TypeOutput | FunOutput | DataOutput | MetavarOutput | PostulateOutput
86
87
87-- | Text formatting output
88-- | Text formatting output
88data TextFormatting = BoldText | ItalicText | UnderlineText
89data TextFormatting = BoldText | ItalicText | UnderlineText
@@ -92,8 +93,9 @@ data OutputAnnotation = AnnName Name (Maybe NameOutput) (Maybe String) (Maybe St
92 -- ^^ The name, classification, docs overview, and pretty-printed type
93 -- ^^ The name, classification, docs overview, and pretty-printed type
93 | AnnBoundName Name Bool
94 | AnnBoundName Name Bool
94 -- ^^ The name and whether it is implicit
95 -- ^^ The name and whether it is implicit
95− | AnnConstData
96+ | AnnConst Const
96− | AnnConstType
97+ | AnnData String String -- ^ type, doc overview
98+ | AnnType String String -- ^ name, doc overview
97 | AnnKeyword
99 | AnnKeyword
98 | AnnFC FC
100 | AnnFC FC
99 | AnnTextFmt TextFormatting
101 | AnnTextFmt TextFormatting
@@ -131,7 +133,7 @@ data Err' t
131 | NoTypeDecl Name
133 | NoTypeDecl Name
132 | NotInjective t t t
134 | NotInjective t t t
133 | CantResolve t
135 | CantResolve t
134− | CantResolveAlts [String]
136+ | CantResolveAlts [Name]
135 | IncompleteTerm t
137 | IncompleteTerm t
136 | UniverseError
138 | UniverseError
137 | ProgramLineComment
139 | ProgramLineComment
@@ -182,9 +184,12 @@ score :: Err -> Int
182score (CantUnify _ _ _ m _ s) = s + score m
184score (CantUnify _ _ _ m _ s) = s + score m
183score (CantResolve _) = 20
185score (CantResolve _) = 20
184score (NoSuchVariable _) = 1000
186score (NoSuchVariable _) = 1000
185−score (ProofSearchFail _) = 10000
187+score (ProofSearchFail e) = score e
186−score (CantSolveGoal _ _) = 10000
188+score (CantSolveGoal _ _) = 100000
187score (InternalMsg _) = -1
189score (InternalMsg _) = -1
190+score (At _ e) = score e
191+score (ElaboratingArg _ _ _ e) = score e
192+score (Elaborating _ _ e) = score e
188score _ = 0
193score _ = 0
189
194
190instance Show Err where
195instance Show Err where
@@ -201,6 +206,7 @@ instance Show Err where
201 show (ElaboratingArg f x prev e) = "Elaborating " ++ show f ++ " arg " ++
206 show (ElaboratingArg f x prev e) = "Elaborating " ++ show f ++ " arg " ++
202 show x ++ ": " ++ show e
207 show x ++ ": " ++ show e
203 show (Elaborating what n e) = "Elaborating " ++ what ++ show n ++ ":" ++ show e
208 show (Elaborating what n e) = "Elaborating " ++ what ++ show n ++ ":" ++ show e
209+ show (ProofSearchFail e) = "Proof search fail: " ++ show e
204 show _ = "Error"
210 show _ = "Error"
205
211
206instance Pretty Err OutputAnnotation where
212instance Pretty Err OutputAnnotation where
@@ -256,7 +262,7 @@ traceWhen False _ a = a
256data Name = UN T.Text -- ^ User-provided name
262data Name = UN T.Text -- ^ User-provided name
257 | NS Name [T.Text] -- ^ Root, namespaces
263 | NS Name [T.Text] -- ^ Root, namespaces
258 | MN Int T.Text -- ^ Machine chosen names
264 | MN Int T.Text -- ^ Machine chosen names
259− | NErased -- ^ Name of somethng which is never used in scope
265+ | NErased -- ^ Name of something which is never used in scope
260 | SN SpecialName -- ^ Decorated function names
266 | SN SpecialName -- ^ Decorated function names
261 | SymRef Int -- ^ Reference to IBC file symbol table (used during serialisation)
267 | SymRef Int -- ^ Reference to IBC file symbol table (used during serialisation)
262 deriving (Eq, Ord)
268 deriving (Eq, Ord)
@@ -383,6 +389,7 @@ implicitable _ = False
383nsroot (NS n _) = n
389nsroot (NS n _) = n
384nsroot n = n
390nsroot n = n
385
391
392+-- this will overwrite already existing definitions
386addDef :: Name -> a -> Ctxt a -> Ctxt a
393addDef :: Name -> a -> Ctxt a -> Ctxt a
387addDef n v ctxt = case Map.lookup (nsroot n) ctxt of
394addDef n v ctxt = case Map.lookup (nsroot n) ctxt of
388 Nothing -> Map.insert (nsroot n)
395 Nothing -> Map.insert (nsroot n)
@@ -425,6 +432,9 @@ lookupCtxt n ctxt = map snd (lookupCtxtName n ctxt)
425lookupCtxtExact :: Name -> Ctxt a -> Maybe a
432lookupCtxtExact :: Name -> Ctxt a -> Maybe a
426lookupCtxtExact n ctxt = listToMaybe [ v | (nm, v) <- lookupCtxtName n ctxt, nm == n]
433lookupCtxtExact n ctxt = listToMaybe [ v | (nm, v) <- lookupCtxtName n ctxt, nm == n]
427
434
435+deleteDefExact :: Name -> Ctxt a -> Ctxt a
436+deleteDefExact n = Map.adjust (Map.delete n) (nsroot n)
437+
428updateDef :: Name -> (a -> a) -> Ctxt a -> Ctxt a
438updateDef :: Name -> (a -> a) -> Ctxt a -> Ctxt a
429updateDef n f ctxt
439updateDef n f ctxt
430 = let ds = lookupCtxtName n ctxt in
440 = let ds = lookupCtxtName n ctxt in
@@ -432,7 +442,7 @@ updateDef n f ctxt
432
442
433toAlist :: Ctxt a -> [(Name, a)]
443toAlist :: Ctxt a -> [(Name, a)]
434toAlist ctxt = let allns = map snd (Map.toList ctxt) in
444toAlist ctxt = let allns = map snd (Map.toList ctxt) in
435− concat (map (Map.toList) allns)
445+ concatMap (Map.toList) allns
436
446
437addAlist :: Show a => [(Name, a)] -> Ctxt a -> Ctxt a
447addAlist :: Show a => [(Name, a)] -> Ctxt a -> Ctxt a
438addAlist [] ctxt = ctxt
448addAlist [] ctxt = ctxt
@@ -520,6 +530,60 @@ instance Pretty Const OutputAnnotation where
520 pretty (B32 w) = text . show $ w
530 pretty (B32 w) = text . show $ w
521 pretty (B64 w) = text . show $ w
531 pretty (B64 w) = text . show $ w
522
532
533+-- | Determines whether the input constant represents a type
534+constIsType :: Const -> Bool
535+constIsType (I _) = False
536+constIsType (BI _) = False
537+constIsType (Fl _) = False
538+constIsType (Ch _) = False
539+constIsType (Str _) = False
540+constIsType (B8 _) = False
541+constIsType (B16 _) = False
542+constIsType (B32 _) = False
543+constIsType (B64 _) = False
544+constIsType (B8V _) = False
545+constIsType (B16V _) = False
546+constIsType (B32V _) = False
547+constIsType (B64V _) = False
548+constIsType _ = True
549+
550+-- | Get the docstring for a Const
551+constDocs :: Const -> String
552+constDocs c@(AType (ATInt ITBig)) = "Arbitrary-precision integers"
553+constDocs c@(AType (ATInt ITNative)) = "Fixed-precision integers of undefined size"
554+constDocs c@(AType (ATInt ITChar)) = "Characters in some unspecified encoding"
555+constDocs c@(AType ATFloat) = "Double-precision floating-point numbers"
556+constDocs StrType = "Strings in some unspecified encoding"
557+constDocs PtrType = "Foreign pointers"
558+constDocs ManagedPtrType = "Managed pointers"
559+constDocs BufferType = "Copy-on-write buffers"
560+constDocs c@(AType (ATInt (ITFixed IT8))) = "Eight bits (unsigned)"
561+constDocs c@(AType (ATInt (ITFixed IT16))) = "Sixteen bits (unsigned)"
562+constDocs c@(AType (ATInt (ITFixed IT32))) = "Thirty-two bits (unsigned)"
563+constDocs c@(AType (ATInt (ITFixed IT64))) = "Sixty-four bits (unsigned)"
564+constDocs c@(AType (ATInt (ITVec IT8 16))) = "Vectors of sixteen eight-bit values"
565+constDocs c@(AType (ATInt (ITVec IT16 8))) = "Vectors of eight sixteen-bit values"
566+constDocs c@(AType (ATInt (ITVec IT32 4))) = "Vectors of four thirty-two-bit values"
567+constDocs c@(AType (ATInt (ITVec IT64 2))) = "Vectors of two sixty-four-bit values"
568+constDocs (Fl f) = "A float"
569+constDocs (I i) = "A fixed-precision integer"
570+constDocs (BI i) = "An arbitrary-precision integer"
571+constDocs (Str s) = "A string of length " ++ show (length s)
572+constDocs (Ch c) = "A character"
573+constDocs (B8 w) = "The eight-bit value 0x" ++
574+ showIntAtBase 16 intToDigit w ""
575+constDocs (B16 w) = "The sixteen-bit value 0x" ++
576+ showIntAtBase 16 intToDigit w ""
577+constDocs (B32 w) = "The thirty-two-bit value 0x" ++
578+ showIntAtBase 16 intToDigit w ""
579+constDocs (B64 w) = "The sixty-four-bit value 0x" ++
580+ showIntAtBase 16 intToDigit w ""
581+constDocs (B8V v) = "A vector of eight-bit values"
582+constDocs (B16V v) = "A vector of sixteen-bit values"
583+constDocs (B32V v) = "A vector of thirty-two-bit values"
584+constDocs (B64V v) = "A vector of sixty-four-bit values"
585+constDocs prim = "Undocumented"
586+
523data Raw = Var Name
587data Raw = Var Name
524 | RBind Name (Binder Raw) Raw
588 | RBind Name (Binder Raw) Raw
525 | RApp Raw Raw
589 | RApp Raw Raw
@@ -996,8 +1060,9 @@ uniqueName n hs | n `elem` hs = uniqueName (nextName n) hs
996
1060
997uniqueBinders :: [Name] -> TT Name -> TT Name
1061uniqueBinders :: [Name] -> TT Name -> TT Name
998uniqueBinders ns (Bind n b sc)
1062uniqueBinders ns (Bind n b sc)
999− = let n' = uniqueName n ns in
1063+ = let n' = uniqueName n ns
1064+ ns' = n' : ns in
1000− Bind n' (fmap (uniqueBinders (n':ns)) b) (uniqueBinders ns sc)
1065+ Bind n' (fmap (uniqueBinders ns') b) (uniqueBinders ns' sc)
1001uniqueBinders ns (App f a) = App (uniqueBinders ns f) (uniqueBinders ns a)
1066uniqueBinders ns (App f a) = App (uniqueBinders ns f) (uniqueBinders ns a)
1002uniqueBinders ns t = t
1067uniqueBinders ns t = t
1003
1068
@@ -1222,3 +1287,12 @@ orderPats tm = op [] tm
1222 = (n', t') : insert n t ps
1287 = (n', t') : insert n t ps
1223 | otherwise = (n,t):(n',t'):ps
1288 | otherwise = (n,t):(n',t'):ps
1224
1289
1290+allTTNames :: Eq n => TT n -> [n]
1291+allTTNames = nub . allNamesIn
1292+ where allNamesIn (P _ n _) = [n]
1293+ allNamesIn (Bind n b t) = [n] ++ nb b ++ allNamesIn t
1294+ where nb (Let t v) = allNamesIn t ++ allNamesIn v
1295+ nb (Guess t v) = allNamesIn t ++ allNamesIn v
1296+ nb t = allNamesIn (binderTy t)
1297+ allNamesIn (App f a) = allNamesIn f ++ allNamesIn a
1298+ allNamesIn _ = []
src/Idris/Core/Unify.hs+40−16
@@ -69,7 +69,20 @@ match_unify ctxt env topx topy inj holes from =
69 return (map (renameBinders env) (trimSolutions v))
69 return (map (renameBinders env) (trimSolutions v))
70 _ -> tfail e
70 _ -> tfail e
71 where
71 where
72−
72+ -- This rule is highly dubious... it certainly produces a valid answer
73+ -- but it scares me. However, matching is never guaranteed to give a unique
74+ -- answer, merely a valid one, so perhaps we're okay.
75+ -- In other words: it may vanish without warning some day :)
76+ un names x tm@(App (P _ f (Bind fn (Pi t) sc)) a)
77+ | (P (DCon _ _) _ _, _) <- unApply x,
78+ holeIn env f || f `elem` holes
79+ = let n' = uniqueName (sMN 0 "mv") (map fst env) in
80+ checkCycle names (f, Bind n' (Lam t) x)
81+ un names tm@(App (P _ f (Bind fn (Pi t) sc)) a) x
82+ | (P (DCon _ _) _ _, _) <- unApply x,
83+ holeIn env f || f `elem` holes
84+ = let n' = uniqueName fn (map fst env) in
85+ checkCycle names (f, Bind n' (Lam t) x)
73
86
74 un names (P _ x _) tm
87 un names (P _ x _) tm
75 | holeIn env x || x `elem` holes
88 | holeIn env x || x `elem` holes
@@ -85,7 +98,7 @@ match_unify ctxt env topx topy inj holes from =
85 | length bnames > i,
98 | length bnames > i,
86 fst (fst (bnames!!i)) == x ||
99 fst (fst (bnames!!i)) == x ||
87 snd (fst (bnames!!i)) == x = do sc 1; return []
100 snd (fst (bnames!!i)) == x = do sc 1; return []
88− un bnames (Bind x bx sx) (Bind y by sy)
101+ un bnames (Bind x bx sx) (Bind y by sy) | notHole bx && notHole by
89 = do h1 <- uB bnames bx by
102 = do h1 <- uB bnames bx by
90 h2 <- un (((x, y), binderTy bx) : bnames) sx sy
103 h2 <- un (((x, y), binderTy bx) : bnames) sx sy
91 combine bnames h1 h2
104 combine bnames h1 h2
@@ -119,6 +132,9 @@ match_unify ctxt env topx topy inj holes from =
119 put (UI s ((binderTy x, binderTy y, env, err, from, Match) : f))
132 put (UI s ((binderTy x, binderTy y, env, err, from, Match) : f))
120 return []
133 return []
121
134
135+ notHole (Hole _) = False
136+ notHole _ = True
137+
122 -- TODO: there's an annoying amount of repetition between this and the
138 -- TODO: there's an annoying amount of repetition between this and the
123 -- main unification function. Consider lifting it out.
139 -- main unification function. Consider lifting it out.
124
140
@@ -173,7 +189,7 @@ renameBindersTm env tm = uniqueBinders (map fst env) tm
173 uniqueBinders env (Bind n b sc)
189 uniqueBinders env (Bind n b sc)
174 | n `elem` env
190 | n `elem` env
175 = let n' = uniqueName n env in
191 = let n' = uniqueName n env in
176− Bind n' (fmap (uniqueBinders env) b)
192+ explicitHole $ Bind n' (fmap (uniqueBinders env) b)
177 (uniqueBinders (n':env) (rename n n' sc))
193 (uniqueBinders (n':env) (rename n n' sc))
178 | otherwise = Bind n (fmap (uniqueBinders (n:env)) b)
194 | otherwise = Bind n (fmap (uniqueBinders (n:env)) b)
179 (uniqueBinders (n:env) sc)
195 (uniqueBinders (n:env) sc)
@@ -185,6 +201,10 @@ renameBindersTm env tm = uniqueBinders (map fst env) tm
185 rename n n' (App f a) = App (rename n n' f) (rename n n' a)
201 rename n n' (App f a) = App (rename n n' f) (rename n n' a)
186 rename n n' t = t
202 rename n n' t = t
187
203
204+ explicitHole (Bind n (Hole ty) sc)
205+ = Bind n (Hole ty) (instantiate (P Bound n ty) sc)
206+ explicitHole t = t
207+
188trimSolutions ns = dropPairs ns
208trimSolutions ns = dropPairs ns
189 where dropPairs [] = []
209 where dropPairs [] = []
190 dropPairs (n@(x, P _ x' _) : ns)
210 dropPairs (n@(x, P _ x' _) : ns)
@@ -204,11 +224,16 @@ expandLets env (x, tm) = (x, doSubst (reverse env) tm)
204 doSubst (_ : env) tm
224 doSubst (_ : env) tm
205 = doSubst env tm
225 = doSubst env tm
206
226
227+hasv (V x) = True
228+hasv (App f a) = hasv f || hasv a
229+hasv (Bind x b sc) = hasv (binderTy b) || hasv sc
230+hasv _ = False
207
231
208unify :: Context -> Env -> TT Name -> TT Name -> [Name] -> [Name] -> [FailContext] ->
232unify :: Context -> Env -> TT Name -> TT Name -> [Name] -> [Name] -> [FailContext] ->
209 TC ([(Name, TT Name)], Fails)
233 TC ([(Name, TT Name)], Fails)
210unify ctxt env topx topy inj holes from =
234unify ctxt env topx topy inj holes from =
235+-- traceWhen (hasv topx || hasv topy)
211−-- trace ("Unifying " ++ show (topx, topy)) $
236+-- ("Unifying " ++ show topx ++ "\nAND\n" ++ show topy ++ "\n") $
212 -- don't bother if topx and topy are different at the head
237 -- don't bother if topx and topy are different at the head
213 case runStateT (un False [] (renameBindersTm env topx)
238 case runStateT (un False [] (renameBindersTm env topx)
214 (renameBindersTm env topy)) (UI 0 []) of
239 (renameBindersTm env topy)) (UI 0 []) of
@@ -295,7 +320,7 @@ unify ctxt env topx topy inj holes from =
295 | injective ty && not (holeIn env x || x `elem` holes)
320 | injective ty && not (holeIn env x || x `elem` holes)
296 = unifyTmpFail tx ty
321 = unifyTmpFail tx ty
297 un' fn bnames xtm@(P _ x _) tm
322 un' fn bnames xtm@(P _ x _) tm
298− | holeIn env x || x `elem` holes
323+ | pureTerm tm, holeIn env x || x `elem` holes
299 = do UI s f <- get
324 = do UI s f <- get
300 -- injectivity check
325 -- injectivity check
301 x <- checkCycle bnames (x, tm)
326 x <- checkCycle bnames (x, tm)
@@ -305,11 +330,11 @@ unify ctxt env topx topy inj holes from =
305 then unifyTmpFail xtm tm
330 then unifyTmpFail xtm tm
306 else do sc 1
331 else do sc 1
307 return x
332 return x
308− | not (injective xtm) && injective tm
333+ | pureTerm tm, not (injective xtm) && injective tm
309 = do checkCycle bnames (x, tm)
334 = do checkCycle bnames (x, tm)
310 unifyTmpFail xtm tm
335 unifyTmpFail xtm tm
311 un' fn bnames tm ytm@(P _ y _)
336 un' fn bnames tm ytm@(P _ y _)
312− | holeIn env y || y `elem` holes
337+ | pureTerm tm, holeIn env y || y `elem` holes
313 = do UI s f <- get
338 = do UI s f <- get
314 -- injectivity check
339 -- injectivity check
315 x <- checkCycle bnames (y, tm)
340 x <- checkCycle bnames (y, tm)
@@ -319,7 +344,7 @@ unify ctxt env topx topy inj holes from =
319 then unifyTmpFail tm ytm
344 then unifyTmpFail tm ytm
320 else do sc 1
345 else do sc 1
321 return x
346 return x
322− | not (injective ytm) && injective tm
347+ | pureTerm tm, not (injective ytm) && injective tm
323 = do checkCycle bnames (y, tm)
348 = do checkCycle bnames (y, tm)
324 unifyTmpFail tm ytm
349 unifyTmpFail tm ytm
325 un' fn bnames (V i) (P _ x _)
350 un' fn bnames (V i) (P _ x _)
@@ -524,7 +549,7 @@ unify ctxt env topx topy inj holes from =
524 | not (x `elem` freeNames tm) = checkScope ns (x, tm)
549 | not (x `elem` freeNames tm) = checkScope ns (x, tm)
525 | otherwise = lift $ tfail (InfiniteUnify x tm (errEnv env))
550 | otherwise = lift $ tfail (InfiniteUnify x tm (errEnv env))
526
551
527− checkScope ns (x, tm) =
552+ checkScope ns (x, tm) | pureTerm tm =
528-- case boundVs (envPos x 0 env) tm of
553-- case boundVs (envPos x 0 env) tm of
529-- [] -> return [(x, tm)]
554-- [] -> return [(x, tm)]
530-- (i:_) -> lift $ tfail (UnifyScope x (fst (fst (ns!!i)))
555-- (i:_) -> lift $ tfail (UnifyScope x (fst (fst (ns!!i)))
@@ -535,6 +560,7 @@ unify ctxt env topx topy inj holes from =
535 else return [(x, bind v ns tm)]
560 else return [(x, bind v ns tm)]
536 where inst [] tm = tm
561 where inst [] tm = tm
537 inst (((n, _), _) : ns) tm = inst ns (substV (P Bound n Erased) tm)
562 inst (((n, _), _) : ns) tm = inst ns (substV (P Bound n Erased) tm)
563+ checkScope ns (x, tm) = lift $ tfail (Msg "HOLE ERROR")
538
564
539 bind i ns tm
565 bind i ns tm
540 | i < 0 = tm
566 | i < 0 = tm
@@ -588,12 +614,8 @@ recoverable t@(App _ _) _
588 | (P _ (UN l) _, _) <- unApply t, l == txt "Lazy" = False
614 | (P _ (UN l) _, _) <- unApply t, l == txt "Lazy" = False
589recoverable _ t@(App _ _)
615recoverable _ t@(App _ _)
590 | (P _ (UN l) _, _) <- unApply t, l == txt "Lazy" = False
616 | (P _ (UN l) _, _) <- unApply t, l == txt "Lazy" = False
591−recoverable (P (DCon _ _) x _) (P (DCon _ _) y _)
617+recoverable (P (DCon _ _) x _) (P (DCon _ _) y _) = x == y
592− | x == y = True
593− | otherwise = False
594−recoverable (P (TCon _ _) x _) (P (TCon _ _) y _)
618+recoverable (P (TCon _ _) x _) (P (TCon _ _) y _) = x == y
595− | x == y = True
596− | otherwise = False
597recoverable (Constant _) (P (DCon _ _) y _) = False
619recoverable (Constant _) (P (DCon _ _) y _) = False
598recoverable (P (DCon _ _) x _) (Constant _) = False
620recoverable (P (DCon _ _) x _) (Constant _) = False
599recoverable (Constant _) (P (TCon _ _) y _) = False
621recoverable (Constant _) (P (TCon _ _) y _) = False
@@ -612,7 +634,9 @@ recoverable f (Bind _ (Pi _) sc)
612recoverable (Bind _ (Pi _) sc) f
634recoverable (Bind _ (Pi _) sc) f
613 | (P (DCon _ _) _ _, _) <- unApply f = False
635 | (P (DCon _ _) _ _, _) <- unApply f = False
614 | (P (TCon _ _) _ _, _) <- unApply f = False
636 | (P (TCon _ _) _ _, _) <- unApply f = False
615−recoverable _ _ = True
637+recoverable (Bind _ (Lam _) sc) f = recoverable sc f
638+recoverable f (Bind _ (Lam _) sc) = recoverable f sc
639+recoverable x y = True
616
640
617errEnv = map (\(x, b) -> (x, binderTy b))
641errEnv = map (\(x, b) -> (x, binderTy b))
618
642
src/Idris/Coverage.hs+52−26
@@ -9,7 +9,7 @@ import Idris.Core.CaseTree
9import Idris.AbsSyntax
9import Idris.AbsSyntax
10import Idris.Delaborate
10import Idris.Delaborate
11import Idris.Error
11import Idris.Error
12−import Idris.Output (iputStrLn)
12+import Idris.Output (iWarn, iputStrLn)
13
13
14import Data.List
14import Data.List
15import Data.Either
15import Data.Either
@@ -211,7 +211,7 @@ genAll i args
211 let p = resugar (PApp fc (PRef fc n) (zipWith upd xs' xs))
211 let p = resugar (PApp fc (PRef fc n) (zipWith upd xs' xs))
212 let tyn = getTy n (tt_ctxt i)
212 let tyn = getTy n (tt_ctxt i)
213 case lookupCtxt tyn (idris_datatypes i) of
213 case lookupCtxt tyn (idris_datatypes i) of
214− (TI ns _ _ _ : _) -> p : map (mkPat fc) (ns \\ [n])
214+ (TI ns _ _ _ _ : _) -> p : map (mkPat fc) (ns \\ [n])
215 _ -> [p]
215 _ -> [p]
216 ops fc n arg o = return Placeholder
216 ops fc n arg o = return Placeholder
217
217
@@ -253,39 +253,50 @@ checkAllCovering :: FC -> [Name] -> Name -> Name -> Idris ()
253checkAllCovering fc done top n | not (n `elem` done)
253checkAllCovering fc done top n | not (n `elem` done)
254 = do i <- get
254 = do i <- get
255 case lookupTotal n (tt_ctxt i) of
255 case lookupTotal n (tt_ctxt i) of
256− [tot@(Partial NotCovering)] ->
256+ [tot@(Partial NotCovering)] ->
257− tclift $ tfail (At fc (Msg (show top ++ " is " ++ show tot
257+ do let msg = show top ++ " is " ++ show tot ++ " due to " ++ show n
258− ++ " due to " ++ show n)))
258+ putIState i { idris_totcheckfail = (fc, msg) : idris_totcheckfail i }
259− _ -> return ()
259+ addIBC (IBCTotCheckErr fc msg)
260+ [Partial _] ->
260− case lookupCtxt n (idris_callgraph i) of
261+ case lookupCtxt n (idris_callgraph i) of
261− [cg] -> mapM_ (checkAllCovering fc (n : done) top)
262+ [cg] -> mapM_ (checkAllCovering fc (n : done) top)
262− (map fst (calls cg))
263+ (map fst (calls cg))
264+ _ -> return ()
263− _ -> return ()
265+ x -> return () -- stop if total
264checkAllCovering _ _ _ _ = return ()
266checkAllCovering _ _ _ _ = return ()
265
267
268+-- Check if, in a given group of type declarations mut_ns,
266−-- Check if, in a given type n, the constructor cn : ty is strictly positive,
269+-- the constructor cn : ty is strictly positive,
267-- and update the context accordingly
270-- and update the context accordingly
268
271
269−checkPositive :: Name -> (Name, Type) -> Idris ()
272+checkPositive :: [Name] -> (Name, Type) -> Idris Totality
270−checkPositive n (cn, ty')
273+checkPositive mut_ns (cn, ty')
271− = do let ty = delazy ty'
274+ = do let ty = delazy' True ty'
272 let p = cp ty
275 let p = cp ty
273 i <- getIState
276 i <- getIState
274 let tot = if p then Total (args ty) else Partial NotPositive
277 let tot = if p then Total (args ty) else Partial NotPositive
275 let ctxt' = setTotal cn tot (tt_ctxt i)
278 let ctxt' = setTotal cn tot (tt_ctxt i)
276 putIState (i { tt_ctxt = ctxt' })
279 putIState (i { tt_ctxt = ctxt' })
277− logLvl 5 $ "Constructor " ++ show cn ++ " is " ++ show tot
280+ logLvl 5 $ "Constructor " ++ show cn ++ " is " ++ show tot ++ " with " ++ show mut_ns
278 addIBC (IBCTotal cn tot)
281 addIBC (IBCTotal cn tot)
282+ return tot
279 where
283 where
280 args t = [0..length (getArgTys t)-1]
284 args t = [0..length (getArgTys t)-1]
281
285
282 cp (Bind n (Pi aty) sc) = posArg aty && cp sc
286 cp (Bind n (Pi aty) sc) = posArg aty && cp sc
287+ cp t | (P _ n' _, args) <- unApply t,
288+ n' `elem` mut_ns = all noRec args
283− cp t = True
289+ cp _ = True
284
290
285 posArg (Bind _ (Pi nty) sc)
291 posArg (Bind _ (Pi nty) sc)
286 | (P _ n' _, args) <- unApply nty
292 | (P _ n' _, args) <- unApply nty
287− = n /= n' && posArg sc
293+ = n' `notElem` mut_ns && all noRec args && posArg sc
288− posArg t = True
294+ posArg t | (P _ n' _, args) <- unApply t,
295+ n' `elem` mut_ns = all noRec args
296+ posArg _ = True
297+
298+ noRec arg = all (\x -> x `notElem` mut_ns) (allTTNames arg)
299+
289
300
290calcProd :: IState -> FC -> Name -> [([Name], Term, Term)] -> Idris Totality
301calcProd :: IState -> FC -> Name -> [([Name], Term, Term)] -> Idris Totality
291calcProd i fc topn pats
302calcProd i fc topn pats
@@ -333,7 +344,7 @@ calcProd i fc topn pats
333 cotype (DCon _ _) n ty
344 cotype (DCon _ _) n ty
334 | (P _ t _, _) <- unApply (getRetTy ty)
345 | (P _ t _, _) <- unApply (getRetTy ty)
335 = case lookupCtxt t (idris_datatypes i) of
346 = case lookupCtxt t (idris_datatypes i) of
336− [TI _ True _ _] -> True
347+ [TI _ True _ _ _] -> True
337 _ -> False
348 _ -> False
338 cotype nt n ty = False
349 cotype nt n ty = False
339
350
@@ -381,6 +392,14 @@ checkTotality path fc n
381 setTotality n t'
392 setTotality n t'
382 addIBC (IBCTotal n t')
393 addIBC (IBCTotal n t')
383 return t'
394 return t'
395+ [TyDecl (DCon _ _) ty] ->
396+ case unApply (getRetTy ty) of
397+ (P _ tyn _, _) -> do
398+ let ms = case lookupCtxt tyn (idris_datatypes i) of
399+ [TI _ _ _ _ xs@(_:_)] -> xs
400+ ts -> [tyn]
401+ checkPositive ms (n, ty)
402+ _-> return $ Total []
384 _ -> return $ Total []
403 _ -> return $ Total []
385 x -> return x
404 x -> return x
386 case t' of
405 case t' of
@@ -388,18 +407,21 @@ checkTotality path fc n
388 Productive -> return t'
407 Productive -> return t'
389 e -> do w <- cmdOptType WarnPartial
408 e -> do w <- cmdOptType WarnPartial
390 if TotalFn `elem` opts
409 if TotalFn `elem` opts
391− then totalityError t'
410+ then do totalityError t'; return t'
392 else do when (w && not (PartialFn `elem` opts)) $
411 else do when (w && not (PartialFn `elem` opts)) $
393 warnPartial n t'
412 warnPartial n t'
394 return t'
413 return t'
395 where
414 where
396− totalityError t = tclift $ tfail (At fc (Msg (show n ++ " is " ++ show t)))
415+ totalityError t = do i <- getIState
416+ let msg = show n ++ " is " ++ show t
417+ putIState i { idris_totcheckfail = (fc, msg) : idris_totcheckfail i}
418+ addIBC (IBCTotCheckErr fc msg)
397
419
398 warnPartial n t
420 warnPartial n t
399 = do i <- getIState
421 = do i <- getIState
400 case lookupDef n (tt_ctxt i) of
422 case lookupDef n (tt_ctxt i) of
401 [x] -> do
423 [x] -> do
402− iputStrLn $ show fc ++ ":Warning - " ++ show n ++ " is " ++ show t
424+ iWarn fc . pprintErr i . Msg $ "Warning - " ++ show n ++ " is " ++ show t
403-- ++ "\n" ++ show x
425-- ++ "\n" ++ show x
404-- let cg = lookupCtxtName Nothing n (idris_callgraph i)
426-- let cg = lookupCtxtName Nothing n (idris_callgraph i)
405-- iputStrLn (show cg)
427-- iputStrLn (show cg)
@@ -410,7 +432,11 @@ checkDeclTotality (fc, n)
410 = do logLvl 2 $ "Checking " ++ show n ++ " for totality"
432 = do logLvl 2 $ "Checking " ++ show n ++ " for totality"
411-- buildSCG (fc, n)
433-- buildSCG (fc, n)
412-- logLvl 2 $ "Built SCG"
434-- logLvl 2 $ "Built SCG"
413− i <- getIState
435+ i <- getIState
436+ let opts = case lookupCtxt n (idris_flags i) of
437+ [fs] -> fs
438+ _ -> []
439+ when (CoveringFn `elem` opts) $ checkAllCovering fc [] n n
414 t <- checkTotality [] fc n
440 t <- checkTotality [] fc n
415 case t of
441 case t of
416 -- if it's not total, it can't reduce, to keep
442 -- if it's not total, it can't reduce, to keep
@@ -517,7 +543,7 @@ buildSCG' ist pats args = nub $ concatMap scgPat pats where
517 -- find which argument in pargs <a> is smaller than, if any
543 -- find which argument in pargs <a> is smaller than, if any
518 checkSize a (p : ps) i
544 checkSize a (p : ps) i
519 | a == p = Just (i, Same)
545 | a == p = Just (i, Same)
520− | (P _ (UN as) _, [_,arg,_]) <- unApply a,
546+ | (P _ (UN as) _, [_,_,arg,_]) <- unApply a,
521 as == txt "assert_smaller" && arg == p
547 as == txt "assert_smaller" && arg == p
522 = Just (i, Smaller)
548 = Just (i, Smaller)
523 | smaller Nothing a (p, Nothing) = Just (i, Smaller)
549 | smaller Nothing a (p, Nothing) = Just (i, Smaller)
@@ -547,7 +573,7 @@ buildSCG' ist pats args = nub $ concatMap scgPat pats where
547
573
548 isInductive (P _ nty _) (P _ nty' _) =
574 isInductive (P _ nty _) (P _ nty' _) =
549 let co = case lookupCtxt nty (idris_datatypes ist) of
575 let co = case lookupCtxt nty (idris_datatypes ist) of
550− [TI _ x _ _] -> x
576+ [TI _ x _ _ _] -> x
551 _ -> False in
577 _ -> False in
552 nty == nty' && not co
578 nty == nty' && not co
553 isInductive _ _ = False
579 isInductive _ _ = False
@@ -630,7 +656,7 @@ checkMP ist i mp = if i > 0
630 = case lookupTotal f (tt_ctxt ist) of
656 = case lookupTotal f (tt_ctxt ist) of
631 [Total _] -> Unchecked -- okay so far
657 [Total _] -> Unchecked -- okay so far
632 [Partial _] -> Partial (Other [f])
658 [Partial _] -> Partial (Other [f])
633− x -> error (show x)
659+ x -> error $ "CAN'T HAPPEN: " ++ (show x)
634 | [TyDecl (TCon _ _) _] <- lookupDef f (tt_ctxt ist)
660 | [TyDecl (TCon _ _) _] <- lookupDef f (tt_ctxt ist)
635 = Total []
661 = Total []
636 tryPath desc path (e@(f, args) : es) arg
662 tryPath desc path (e@(f, args) : es) arg
src/Idris/DeepSeq.hs+13−15
@@ -138,15 +138,15 @@ instance (NFData t) => NFData (PDecl' t) where
138 rnf x3 `seq` rnf x4 `seq` rnf x5 `seq` rnf x6 `seq` ()
138 rnf x3 `seq` rnf x4 `seq` rnf x5 `seq` rnf x6 `seq` ()
139 rnf (PParams x1 x2 x3) = rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` ()
139 rnf (PParams x1 x2 x3) = rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` ()
140 rnf (PNamespace x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
140 rnf (PNamespace x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
141− rnf (PRecord x1 x2 x3 x4 x5 x6 x7 x8)
141+ rnf (PRecord x1 x2 x3 x4 x5 x6 x7 x8 x9)
142 = rnf x1 `seq`
142 = rnf x1 `seq`
143 rnf x2 `seq`
143 rnf x2 `seq`
144 rnf x3 `seq`
144 rnf x3 `seq`
145− rnf x4 `seq` rnf x5 `seq` rnf x6 `seq` rnf x7 `seq` rnf x8 `seq` ()
145+ rnf x4 `seq` rnf x5 `seq` rnf x6 `seq` rnf x7 `seq` rnf x8 `seq` rnf x9 `seq` ()
146− rnf (PClass x1 x2 x3 x4 x5 x6 x7)
146+ rnf (PClass x1 x2 x3 x4 x5 x6 x8 x7)
147 = rnf x1 `seq`
147 = rnf x1 `seq`
148 rnf x2 `seq`
148 rnf x2 `seq`
149− rnf x3 `seq` rnf x4 `seq` rnf x5 `seq` rnf x6 `seq` rnf x7 `seq` ()
149+ rnf x3 `seq` rnf x4 `seq` rnf x5 `seq` rnf x6 `seq` rnf x7 `seq` rnf x8 `seq` ()
150 rnf (PInstance x1 x2 x3 x4 x5 x6 x7 x8)
150 rnf (PInstance x1 x2 x3 x4 x5 x6 x7 x8)
151 = rnf x1 `seq`
151 = rnf x1 `seq`
152 rnf x2 `seq`
152 rnf x2 `seq`
@@ -156,16 +156,14 @@ instance (NFData t) => NFData (PDecl' t) where
156 rnf (PSyntax x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
156 rnf (PSyntax x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
157 rnf (PMutual x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
157 rnf (PMutual x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
158 rnf (PDirective x1) = ()
158 rnf (PDirective x1) = ()
159− rnf (PProvider x1 x2 x3 x4 x5 x6)
159+ rnf (PProvider x1 x2 x3 x4)
160− = rnf x1 `seq`
161− rnf x2 `seq` rnf x3 `seq` rnf x4 `seq` rnf x5 `seq` rnf x6 `seq` ()
160+ = rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` rnf x4 `seq` ()
162 rnf (PTransform x1 x2 x3 x4)
161 rnf (PTransform x1 x2 x3 x4)
163 = rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` rnf x4 `seq` ()
162 = rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` rnf x4 `seq` ()
164
163
165−instance NFData ProvideWhat where
164+instance NFData t => NFData (ProvideWhat' t) where
166− rnf ProvAny = ()
165+ rnf (ProvTerm ty tm) = rnf ty `seq` rnf tm `seq` ()
167− rnf ProvTerm = ()
168− rnf ProvPostulate = ()
166+ rnf (ProvPostulate tm) = rnf tm `seq` ()
169
167
170instance NFData PunInfo where
168instance NFData PunInfo where
171 rnf x = x `seq` ()
169 rnf x = x `seq` ()
@@ -245,7 +243,7 @@ instance (NFData t) => NFData (PTactic' t) where
245 rnf (Exact x1) = rnf x1 `seq` ()
243 rnf (Exact x1) = rnf x1 `seq` ()
246 rnf Compute = ()
244 rnf Compute = ()
247 rnf Trivial = ()
245 rnf Trivial = ()
248− rnf (ProofSearch x1 x2)
246+ rnf (ProofSearch r r1 r2 x1 x2)
249 = rnf x1 `seq` rnf x2 `seq` ()
247 = rnf x1 `seq` rnf x2 `seq` ()
250 rnf Solve = ()
248 rnf Solve = ()
251 rnf Attack = ()
249 rnf Attack = ()
@@ -290,7 +288,7 @@ instance NFData OptInfo where
290 = rnf x1 `seq` rnf x2 `seq` ()
288 = rnf x1 `seq` rnf x2 `seq` ()
291
289
292instance NFData TypeInfo where
290instance NFData TypeInfo where
293− rnf (TI x1 x2 x3 x4) = rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` rnf x4 `seq` ()
291+ rnf (TI x1 x2 x3 x4 x5) = rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` rnf x4 `seq` rnf x5 `seq` ()
294
292
295instance (NFData t) => NFData (DSL' t) where
293instance (NFData t) => NFData (DSL' t) where
296 rnf (DSL x1 x2 x3 x4 x5 x6 x7 x8 x9)
294 rnf (DSL x1 x2 x3 x4 x5 x6 x7 x8 x9)
@@ -321,11 +319,11 @@ instance NFData Using where
321
319
322
320
323instance NFData SyntaxInfo where
321instance NFData SyntaxInfo where
324− rnf (Syn x1 x2 x3 x4 x5 x6 x7 x8)
322+ rnf (Syn x1 x2 x3 x4 x5 x6 x7 x8 x9 x10)
325 = rnf x1 `seq`
323 = rnf x1 `seq`
326 rnf x2 `seq`
324 rnf x2 `seq`
327 rnf x3 `seq`
325 rnf x3 `seq`
328− rnf x4 `seq` rnf x5 `seq` rnf x6 `seq` rnf x7 `seq` rnf x8 `seq` ()
326+ rnf x4 `seq` rnf x5 `seq` rnf x6 `seq` rnf x7 `seq` rnf x8 `seq` rnf x9 `seq` rnf x10 `seq` ()
329
327
330
328
331
329
src/Idris/Delaborate.hs+31−6
@@ -1,5 +1,5 @@
1{-# LANGUAGE PatternGuards #-}
1{-# LANGUAGE PatternGuards #-}
2−module Idris.Delaborate (bugaddr, delab, delab', delabMV, delabTy, delabTy', pprintErr) where
2+module Idris.Delaborate (bugaddr, delab, delab', delabMV, delabTy, delabTy', fancifyAnnots, pprintErr) where
3
3
4-- Convert core TT back into high level syntax, primarily for display
4-- Convert core TT back into high level syntax, primarily for display
5-- purposes.
5-- purposes.
@@ -9,6 +9,7 @@ import Util.Pretty
9import Idris.AbsSyntax
9import Idris.AbsSyntax
10import Idris.Core.TT
10import Idris.Core.TT
11import Idris.Core.Evaluate
11import Idris.Core.Evaluate
12+import Idris.Docstrings (overview, renderDocstring)
12import Idris.ErrReverse
13import Idris.ErrReverse
13
14
14import Data.List (intersperse)
15import Data.List (intersperse)
@@ -92,13 +93,13 @@ delabTy' ist imps tm fullname mvs = de [] imps tm
92 | n == eqCon = PRefl un (de env [] r)
93 | n == eqCon = PRefl un (de env [] r)
93 | n == sUN "lazy" = de env [] r
94 | n == sUN "lazy" = de env [] r
94 deFn env (P _ n _) [ty, Bind x (Lam _) r]
95 deFn env (P _ n _) [ty, Bind x (Lam _) r]
95− | n == sUN "Exists"
96+ | n == sUN "Sigma"
96 = PDPair un IsType (PRef un x) (de env [] ty)
97 = PDPair un IsType (PRef un x) (de env [] ty)
97 (de ((x,x):env) [] (instantiate (P Bound x ty) r))
98 (de ((x,x):env) [] (instantiate (P Bound x ty) r))
98 deFn env (P _ n _) [_,_,l,r]
99 deFn env (P _ n _) [_,_,l,r]
99 | n == pairCon = PPair un IsTerm (de env [] l) (de env [] r)
100 | n == pairCon = PPair un IsTerm (de env [] l) (de env [] r)
100 | n == eqTy = PEq un (de env [] l) (de env [] r)
101 | n == eqTy = PEq un (de env [] l) (de env [] r)
101− | n == sUN "Ex_intro" = PDPair un IsTerm (de env [] l) Placeholder
102+ | n == sUN "Sg_intro" = PDPair un IsTerm (de env [] l) Placeholder
102 (de env [] r)
103 (de env [] r)
103 deFn env f@(P _ n _) args
104 deFn env f@(P _ n _) args
104 | n `elem` map snd env
105 | n `elem` map snd env
@@ -138,7 +139,7 @@ pprintTerm :: IState -> PTerm -> Doc OutputAnnotation
138pprintTerm ist = pprintTerm' ist []
139pprintTerm ist = pprintTerm' ist []
139
140
140pprintTerm' :: IState -> [(Name, Bool)] -> PTerm -> Doc OutputAnnotation
141pprintTerm' :: IState -> [(Name, Bool)] -> PTerm -> Doc OutputAnnotation
141−pprintTerm' ist bnd tm = pprintPTerm (opt_showimp (idris_options ist)) bnd [] tm
142+pprintTerm' ist bnd tm = pprintPTerm (ppOptionIst ist) bnd [] (idris_infixes ist) tm
142
143
143pprintErr :: IState -> Err -> Doc OutputAnnotation
144pprintErr :: IState -> Err -> Doc OutputAnnotation
144pprintErr i err = pprintErr' i (fmap (errReverse i) err)
145pprintErr i err = pprintErr' i (fmap (errReverse i) err)
@@ -195,7 +196,7 @@ pprintErr' i (NotInjective p x y) =
195 pprintTerm i (delab i y)
196 pprintTerm i (delab i y)
196pprintErr' i (CantResolve c) = text "Can't resolve type class" <+> pprintTerm i (delab i c)
197pprintErr' i (CantResolve c) = text "Can't resolve type class" <+> pprintTerm i (delab i c)
197pprintErr' i (CantResolveAlts as) = text "Can't disambiguate name:" <+>
198pprintErr' i (CantResolveAlts as) = text "Can't disambiguate name:" <+>
198− align (cat (punctuate (comma <> space) (map text as)))
199+ align (cat (punctuate (comma <> space) (map (fmap (fancifyAnnots i) . annName) as)))
199pprintErr' i (NoTypeDecl n) = text "No type declaration for" <+> annName n
200pprintErr' i (NoTypeDecl n) = text "No type declaration for" <+> annName n
200pprintErr' i (NoSuchVariable n) = text "No such variable" <+> annName n
201pprintErr' i (NoSuchVariable n) = text "No such variable" <+> annName n
201pprintErr' i (IncompleteTerm t) = text "Incomplete term" <+> pprintTerm i (delab i t)
202pprintErr' i (IncompleteTerm t) = text "Incomplete term" <+> pprintTerm i (delab i t)
@@ -258,6 +259,30 @@ annName n = annName' n (showbasic n)
258annName' :: Name -> String -> Doc OutputAnnotation
259annName' :: Name -> String -> Doc OutputAnnotation
259annName' n str = annotate (AnnName n Nothing Nothing Nothing) (text str)
260annName' n str = annotate (AnnName n Nothing Nothing Nothing) (text str)
260
261
262+fancifyAnnots :: IState -> OutputAnnotation -> OutputAnnotation
263+fancifyAnnots ist annot@(AnnName n _ _ _) =
264+ do let ctxt = tt_ctxt ist
265+ docs = docOverview ist n
266+ ty = Just (getTy ist n)
267+ case () of
268+ _ | isDConName n ctxt -> AnnName n (Just DataOutput) docs ty
269+ _ | isFnName n ctxt -> AnnName n (Just FunOutput) docs ty
270+ _ | isTConName n ctxt -> AnnName n (Just TypeOutput) docs ty
271+ _ | isMetavarName n ist -> AnnName n (Just MetavarOutput) docs ty
272+ _ | isPostulateName n ist -> AnnName n (Just PostulateOutput) docs ty
273+ _ | otherwise -> annot
274+ where docOverview :: IState -> Name -> Maybe String -- pretty-print first paragraph of docs
275+ docOverview ist n = do docs <- lookupCtxtExact n (idris_docstrings ist)
276+ let o = overview (fst docs)
277+ -- TODO make width configurable
278+ out = displayS . renderPretty 1.0 50 $ renderDocstring o
279+ return (out "")
280+ getTy :: IState -> Name -> String -- fails if name not already extant!
281+ getTy ist n = let theTy = pprintPTerm (ppOptionIst ist) [] [] (idris_infixes ist) $
282+ delabTy ist n
283+ in (displayS . renderPretty 1.0 50 $ theTy) ""
284+fancifyAnnots _ annot = annot
285+
261showSc :: IState -> [(Name, Term)] -> Doc OutputAnnotation
286showSc :: IState -> [(Name, Term)] -> Doc OutputAnnotation
262showSc i [] = empty
287showSc i [] = empty
263showSc i xs = line <> line <> text "In context:" <>
288showSc i xs = line <> line <> text "In context:" <>
@@ -269,7 +294,7 @@ showSc i xs = line <> line <> text "In context:" <>
269
294
270
295
271showqual :: IState -> Name -> String
296showqual :: IState -> Name -> String
272−showqual i n = showName (Just i) [] False False (dens n)
297+showqual i n = showName (Just i) [] (ppOptionIst i) { ppopt_impl = False } False (dens n)
273 where
298 where
274 dens ns@(NS n _) = case lookupCtxt n (idris_implicits i) of
299 dens ns@(NS n _) = case lookupCtxt n (idris_implicits i) of
275 [_] -> n -- just one thing
300 [_] -> n -- just one thing
src/Idris/Docs.hs+100−24
@@ -1,5 +1,5 @@
1{-# LANGUAGE PatternGuards #-}
1{-# LANGUAGE PatternGuards #-}
2−module Idris.Docs where
2+module Idris.Docs (pprintDocs, getDocs, pprintConstDocs, FunDoc(..), Docs (..)) where
3
3
4import Idris.AbsSyntax
4import Idris.AbsSyntax
5import Idris.AbsSyntaxTree
5import Idris.AbsSyntaxTree
@@ -27,16 +27,19 @@ data Docs = FunDoc FunDoc
27 [FunDoc] -- data constructor docs
27 [FunDoc] -- data constructor docs
28 | ClassDoc Name Docstring -- class docs
28 | ClassDoc Name Docstring -- class docs
29 [FunDoc] -- method docs
29 [FunDoc] -- method docs
30+ [(Name, Maybe Docstring)] -- parameters and their docstrings
31+ [PTerm] -- instances
32+ [PTerm] -- superclasses
30 deriving Show
33 deriving Show
31
34
32showDoc d | nullDocstring d = empty
35showDoc d | nullDocstring d = empty
33 | otherwise = text " -- " <> renderDocstring d
36 | otherwise = text " -- " <> renderDocstring d
34
37
35−pprintFD :: Bool -> FunDoc -> Doc OutputAnnotation
38+pprintFD :: IState -> FunDoc -> Doc OutputAnnotation
36−pprintFD imp (FD n doc args ty f)
39+pprintFD ist (FD n doc args ty f)
37− = nest 4 (prettyName imp [] n <+> colon <+>
40+ = nest 4 (prettyName (ppopt_impl ppo) [] n <+> colon <+>
38− pprintPTerm imp [] [ n | (n@(UN n'),_,_,_) <- args
41+ pprintPTerm ppo [] [ n | (n@(UN n'),_,_,_) <- args
39− , not (T.isPrefixOf (T.pack "__") n') ] ty <$>
42+ , not (T.isPrefixOf (T.pack "__") n') ] infixes ty <$>
40 renderDocstring doc <$>
43 renderDocstring doc <$>
41 maybe empty (\f -> text (show f) <> line) f <>
44 maybe empty (\f -> text (show f) <> line) f <>
42 let argshow = showArgs args [] in
45 let argshow = showArgs args [] in
@@ -44,21 +47,23 @@ pprintFD imp (FD n doc args ty f)
44 then nest 4 $ text "Arguments:" <$> vsep argshow
47 then nest 4 $ text "Arguments:" <$> vsep argshow
45 else empty)
48 else empty)
46
49
50+ where ppo = ppOptionIst ist
51+ infixes = idris_infixes ist
47− where showArgs ((n, ty, Exp {}, Just d):args) bnd
52+ showArgs ((n, ty, Exp {}, Just d):args) bnd
48 = bindingOf n False <+> colon <+>
53 = bindingOf n False <+> colon <+>
49− pprintPTerm imp bnd [] ty <>
54+ pprintPTerm ppo bnd [] infixes ty <>
50 showDoc d <> line
55 showDoc d <> line
51 :
56 :
52 showArgs args ((n, False):bnd)
57 showArgs args ((n, False):bnd)
53 showArgs ((n, ty, Constraint {}, Just d):args) bnd
58 showArgs ((n, ty, Constraint {}, Just d):args) bnd
54 = text "Class constraint" <+>
59 = text "Class constraint" <+>
55− pprintPTerm imp bnd [] ty <> showDoc d <> line
60+ pprintPTerm ppo bnd [] infixes ty <> showDoc d <> line
56 :
61 :
57 showArgs args ((n, True):bnd)
62 showArgs args ((n, True):bnd)
58 showArgs ((n, ty, Imp {}, Just d):args) bnd
63 showArgs ((n, ty, Imp {}, Just d):args) bnd
59 = text "(implicit)" <+>
64 = text "(implicit)" <+>
60 bindingOf n True <+> colon <+>
65 bindingOf n True <+> colon <+>
61− pprintPTerm imp bnd [] ty <>
66+ pprintPTerm ppo bnd [] infixes ty <>
62 showDoc d <> line
67 showDoc d <> line
63 :
68 :
64 showArgs args ((n, True):bnd)
69 showArgs args ((n, True):bnd)
@@ -66,16 +71,68 @@ pprintFD imp (FD n doc args ty f)
66 showArgs [] _ = []
71 showArgs [] _ = []
67
72
68
73
69−
74+pprintDocs :: IState -> Docs -> Doc OutputAnnotation
70−pprintDocs imp (FunDoc d) = pprintFD imp d
75+pprintDocs ist (FunDoc d) = pprintFD ist d
71−pprintDocs imp (DataDoc t args)
76+pprintDocs ist (DataDoc t args)
72− = text "Data type" <+> pprintFD imp t <$>
77+ = text "Data type" <+> pprintFD ist t <$>
78+ if null args then text "No constructors."
73− nest 4 (text "Constructors:" <> line <>
79+ else nest 4 (text "Constructors:" <> line <>
74− vsep (map (pprintFD imp) args))
80+ vsep (map (pprintFD ist) args))
75−pprintDocs imp (ClassDoc n doc meths)
81+pprintDocs ist (ClassDoc n doc meths params instances superclasses)
76− = text "Type class" <+> prettyName imp [] n <$> -- parameters?
82+ = nest 4 (text "Type class" <+> prettyName (ppopt_impl ppo) [] n <>
83+ if nullDocstring doc then empty else line <> renderDocstring doc)
84+ <> line <$>
85+ nest 4 (text "Parameters:" <$> prettyParameters)
86+ <> line <$>
77 nest 4 (text "Methods:" <$>
87 nest 4 (text "Methods:" <$>
78− vsep (map (pprintFD imp) meths))
88+ vsep (map (pprintFD ist) meths))
89+ <$>
90+ nest 4 (text "Instances:" <$>
91+ vsep (if null instances' then [text "<no instances>"]
92+ else map dumpInstance instances'))
93+ <>
94+ (if null subclasses then empty
95+ else line <$> nest 4 (text "Subclasses:" <$>
96+ vsep (map (dumpInstance . prettifySubclasses) subclasses)))
97+ <>
98+ (if null superclasses then empty
99+ else line <$> nest 4 (text "Default superclass instances:" <$>
100+ vsep (map dumpInstance superclasses)))
101+ where
102+ params' = zip pNames (repeat False)
103+
104+ pNames = map fst params
105+
106+ ppo = ppOptionIst ist
107+ infixes = idris_infixes ist
108+
109+ dumpInstance :: PTerm -> Doc OutputAnnotation
110+ dumpInstance = pprintPTerm ppo params' [] infixes
111+
112+ prettifySubclasses (PPi (Constraint _ _) _ tm _) = prettifySubclasses tm
113+ prettifySubclasses (PPi plcity nm t1 t2) = PPi plcity (safeHead nm pNames) (prettifySubclasses t1) (prettifySubclasses t2)
114+ prettifySubclasses (PApp fc ref args) = PApp fc ref $ updateArgs pNames args
115+ prettifySubclasses tm = tm
116+
117+ safeHead _ (y:_) = y
118+ safeHead x [] = x
119+
120+ updateArgs (p:ps) ((PExp prty opts _ ref):as) = (PExp prty opts p (updateRef p ref)) : updateArgs ps as
121+ updateArgs ps (a:as) = a : updateArgs ps as
122+ updateArgs _ _ = []
123+
124+ updateRef nm (PRef fc _) = PRef fc nm
125+ updateRef _ pt = pt
126+
127+ isSubclass (PPi (Constraint _ _) _ (PApp _ _ args) (PApp _ (PRef _ nm) args')) = nm == n && map getTm args == map getTm args'
128+ isSubclass (PPi _ _ _ pt) = isSubclass pt
129+ isSubclass _ = False
130+
131+ (subclasses, instances') = partition isSubclass instances
132+
133+ prettyParameters = if any (isJust . snd) params
134+ then vsep (map (\(nm,md) -> prettyName False params' nm <+> maybe empty showDoc md) params)
135+ else hsep (punctuate comma (map (prettyName False params' . fst) params))
79
136
80getDocs :: Name -> Idris Docs
137getDocs :: Name -> Idris Docs
81getDocs n
138getDocs n
@@ -96,11 +153,16 @@ docData n ti
96docClass :: Name -> ClassInfo -> Idris Docs
153docClass :: Name -> ClassInfo -> Idris Docs
97docClass n ci
154docClass n ci
98 = do i <- getIState
155 = do i <- getIState
99− let docstr = case lookupCtxt n (idris_docstrings i) of
156+ let docStrings = listToMaybe $ lookupCtxt n $ idris_docstrings i
100− [str] -> fst str
101− _ -> emptyDocstring
157+ docstr = maybe emptyDocstring fst docStrings
158+ params = map (\pn -> (pn, docStrings >>= (lookup pn . snd))) (class_params ci)
159+ instances = map (delabTy i) (class_instances ci)
160+ superclasses = catMaybes $ map getDInst (class_default_superclasses ci)
102− mdocs <- mapM docFun (map fst (class_methods ci))
161+ mdocs <- mapM (docFun . fst) (class_methods ci)
103− return (ClassDoc n docstr mdocs)
162+ return $ ClassDoc n docstr mdocs params instances superclasses
163+ where
164+ getDInst (PInstance _ _ _ _ _ t _ _) = Just t
165+ getDInst _ = Nothing
104
166
105docFun :: Name -> Idris FunDoc
167docFun :: Name -> Idris FunDoc
106docFun n
168docFun n
@@ -120,8 +182,22 @@ docFun n
120 where funName :: Name -> String
182 where funName :: Name -> String
121 funName (UN n) = str n
183 funName (UN n) = str n
122 funName (NS n _) = funName n
184 funName (NS n _) = funName n
185+ funName n
186+ | n == falseTy = "_|_"
123
187
124getPArgNames :: PTerm -> [(Name, Docstring)] -> [(Name, PTerm, Plicity, Maybe Docstring)]
188getPArgNames :: PTerm -> [(Name, Docstring)] -> [(Name, PTerm, Plicity, Maybe Docstring)]
125getPArgNames (PPi plicity name ty body) ds =
189getPArgNames (PPi plicity name ty body) ds =
126 (name, ty, plicity, lookup name ds) : getPArgNames body ds
190 (name, ty, plicity, lookup name ds) : getPArgNames body ds
127getPArgNames _ _ = []
191getPArgNames _ _ = []
192+
193+pprintConstDocs :: IState -> Const -> String -> Doc OutputAnnotation
194+pprintConstDocs ist c str = text "Primitive" <+> text (if constIsType c then "type" else "value") <+>
195+ pprintPTerm (ppOptionIst ist) [] [] [] (PConstant c) <+> colon <+>
196+ pprintPTerm (ppOptionIst ist) [] [] [] (t c) <>
197+ nest 4 (line <> text str)
198+
199+ where t (Fl _) = PConstant $ AType ATFloat
200+ t (BI _) = PConstant $ AType (ATInt ITBig)
201+ t (Str _) = PConstant StrType
202+ t (Ch c) = PConstant $ AType (ATInt ITChar)
203+ t _ = PType
src/Idris/Docstrings.hs+1−1
@@ -68,7 +68,7 @@ renderInlines = F.foldr (<>) empty . fmap renderInline
68
68
69renderInline :: CT.Inline -> Doc OutputAnnotation
69renderInline :: CT.Inline -> Doc OutputAnnotation
70renderInline (CT.Str s) = text $ T.unpack s
70renderInline (CT.Str s) = text $ T.unpack s
71−renderInline CT.Space = space
71+renderInline CT.Space = softline
72renderInline CT.SoftBreak = softline
72renderInline CT.SoftBreak = softline
73renderInline CT.LineBreak = line
73renderInline CT.LineBreak = line
74renderInline (CT.Emph txt) = annotate (AnnTextFmt ItalicText) $ renderInlines txt -- TODO
74renderInline (CT.Emph txt) = annotate (AnnTextFmt ItalicText) $ renderInlines txt -- TODO
src/Idris/ElabDecls.hs+210−102
@@ -4,6 +4,7 @@
4module Idris.ElabDecls where
4module Idris.ElabDecls where
5
5
6import Idris.AbsSyntax
6import Idris.AbsSyntax
7+import Idris.ASTUtils
7import Idris.DSL
8import Idris.DSL
8import Idris.Error
9import Idris.Error
9import Idris.Delaborate
10import Idris.Delaborate
@@ -29,6 +30,10 @@ import Idris.Core.CaseTree
29
30
30import Idris.Docstrings
31import Idris.Docstrings
31
32
33+import Prelude hiding (id, (.))
34+import Control.Category
35+
36+import Control.Applicative hiding (Const)
32import Control.DeepSeq
37import Control.DeepSeq
33import Control.Monad
38import Control.Monad
34import Control.Monad.State.Strict as State
39import Control.Monad.State.Strict as State
@@ -81,14 +86,15 @@ elabType' norm info syn doc argDocs fc opts n ty' = {- let ty' = piBind (params
81 ctxt <- getContext
86 ctxt <- getContext
82 i <- getIState
87 i <- getIState
83
88
84− logLvl 3 $ show n ++ " pre-type " ++ showTmImpls ty'
89+ logLvl 5 $ show n ++ " pre-type " ++ showTmImpls ty'
85 ty' <- addUsingConstraints syn fc ty'
90 ty' <- addUsingConstraints syn fc ty'
86 ty' <- implicit info syn n ty'
91 ty' <- implicit info syn n ty'
87
92
88 let ty = addImpl i ty'
93 let ty = addImpl i ty'
89 inacc = inaccessibleArgs 0 ty
94 inacc = inaccessibleArgs 0 ty
90− logLvl 3 $ show n ++ " type " ++ showTmImpls ty
95+ logLvl 5 $ show n ++ " type pre-addimpl " ++ showTmImpls ty'
96+ logLvl 5 $ show n ++ " type " ++ showTmImpls ty
91− logLvl 5 $ "Inaccessible arguments: " ++ show inacc
97+ logLvl 3 $ show n ++ ": inaccessible arguments: " ++ show inacc
92
98
93 ((tyT, defer, is), log) <-
99 ((tyT, defer, is), log) <-
94 tclift $ elaborate ctxt n (TType (UVal 0)) []
100 tclift $ elaborate ctxt n (TType (UVal 0)) []
@@ -119,7 +125,7 @@ elabType' norm info syn doc argDocs fc opts n ty' = {- let ty' = piBind (params
119 let (t, _) = unApply (getRetTy nty')
125 let (t, _) = unApply (getRetTy nty')
120 let corec = case t of
126 let corec = case t of
121 P _ rcty _ -> case lookupCtxt rcty (idris_datatypes i) of
127 P _ rcty _ -> case lookupCtxt rcty (idris_datatypes i) of
122− [TI _ True _ _] -> True
128+ [TI _ True _ _ _] -> True
123 _ -> False
129 _ -> False
124 _ -> False
130 _ -> False
125 -- Productivity checking now via checking for guarded 'Delay'
131 -- Productivity checking now via checking for guarded 'Delay'
@@ -134,7 +140,8 @@ elabType' norm info syn doc argDocs fc opts n ty' = {- let ty' = piBind (params
134 addDocStr n doc argDocs
140 addDocStr n doc argDocs
135 addIBC (IBCDoc n)
141 addIBC (IBCDoc n)
136 addIBC (IBCFlags n opts')
142 addIBC (IBCFlags n opts')
137− saveInaccArgs n inacc
143+ fputState (opt_inaccessible . ist_optimisation n) inacc
144+ addIBC (IBCOpt n)
138 when (Implicit `elem` opts') $ do addCoercion n
145 when (Implicit `elem` opts') $ do addCoercion n
139 addIBC (IBCCoercion n)
146 addIBC (IBCCoercion n)
140
147
@@ -178,24 +185,10 @@ elabType' norm info syn doc argDocs fc opts n ty' = {- let ty' = piBind (params
178 , ns4 == map txt ["Errors","Reflection","Language"] = True
185 , ns4 == map txt ["Errors","Reflection","Language"] = True
179 tyIsHandler _ = False
186 tyIsHandler _ = False
180
187
181−-- Store the list of inaccessible arguments in the internal state.
182−saveInaccArgs :: Name -> [(Int,Name)] -> Idris ()
183−saveInaccArgs n is = do
184− ist <- getIState
185− case lookupCtxt n (idris_optimisation ist) of
186− [oi] -> do
187− putIState ist{ idris_optimisation =
188− addDef n oi{ inaccessible = is } (idris_optimisation ist) }
189−
190− _ -> do
191− putIState ist{ idris_optimisation =
192− addDef n (Optimise is False) (idris_optimisation ist) }
193− addIBC (IBCOpt n)
194−
195-- Get the list of (index, name) of inaccessible arguments from the type.
188-- Get the list of (index, name) of inaccessible arguments from the type.
196inaccessibleArgs :: Int -> PTerm -> [(Int, Name)]
189inaccessibleArgs :: Int -> PTerm -> [(Int, Name)]
197inaccessibleArgs i (PPi (Imp _ _ _) n Placeholder t)
190inaccessibleArgs i (PPi (Imp _ _ _) n Placeholder t)
198− = (i,n) : inaccessibleArgs (i+1) t -- unbound implicit
191+ = (i,n) : inaccessibleArgs (i+1) t -- unbound implicit
199inaccessibleArgs i (PPi plicity n ty t)
192inaccessibleArgs i (PPi plicity n ty t)
200 | InaccessibleArg `elem` pargopts plicity
193 | InaccessibleArg `elem` pargopts plicity
201 = (i,n) : inaccessibleArgs (i+1) t -- an .{erased : Implicit}
194 = (i,n) : inaccessibleArgs (i+1) t -- an .{erased : Implicit}
@@ -263,8 +256,10 @@ elabData info syn doc argDocs fc opts (PDatadecl n t_in dcons)
263 let as = map (const Nothing) (getArgTys cty)
256 let as = map (const Nothing) (getArgTys cty)
264 let params = findParams (map snd cons)
257 let params = findParams (map snd cons)
265 logLvl 2 $ "Parameters : " ++ show params
258 logLvl 2 $ "Parameters : " ++ show params
259+ -- TI contains information about mutually declared types - this will
260+ -- be updated when the mutual block is complete
266 putIState (i { idris_datatypes =
261 putIState (i { idris_datatypes =
267− addDef n (TI (map fst cons) codata opts params)
262+ addDef n (TI (map fst cons) codata opts params [n])
268 (idris_datatypes i) })
263 (idris_datatypes i) })
269 addIBC (IBCDef n)
264 addIBC (IBCDef n)
270 addIBC (IBCData n)
265 addIBC (IBCData n)
@@ -276,7 +271,8 @@ elabData info syn doc argDocs fc opts (PDatadecl n t_in dcons)
276 -- TMP HACK! Make this a data option
271 -- TMP HACK! Make this a data option
277 updateContext (addDatatype (Data n ttag cty cons))
272 updateContext (addDatatype (Data n ttag cty cons))
278 updateContext (setMetaInformation n metainf)
273 updateContext (setMetaInformation n metainf)
274+ mapM_ totcheck (zip (repeat fc) (map fst cons))
279− mapM_ (checkPositive n) cons
275+-- mapM_ (checkPositive n) cons
280
276
281 -- if there's exactly one constructor,
277 -- if there's exactly one constructor,
282 -- mark both the type and the constructor as detaggable
278 -- mark both the type and the constructor as detaggable
@@ -372,12 +368,13 @@ elabData info syn doc argDocs fc opts (PDatadecl n t_in dcons)
372
368
373type EliminatorState = StateT (Map.Map String Int) Idris
369type EliminatorState = StateT (Map.Map String Int) Idris
374
370
375−-- TODO: Use uniqueName for generating names, rewrite everything to use idris_implicits instead of manual splitting, generally just rewrite
371+-- TODO: Rewrite everything to use idris_implicits instead of manual splitting (or in TT)
376elabEliminator :: [Int] -> Name -> PTerm ->
372elabEliminator :: [Int] -> Name -> PTerm ->
377 [(Docstring, [(Name, Docstring)], Name, PTerm, FC, [Name])] ->
373 [(Docstring, [(Name, Docstring)], Name, PTerm, FC, [Name])] ->
378 ElabInfo -> EliminatorState ()
374 ElabInfo -> EliminatorState ()
379elabEliminator paramPos n ty cons info = do
375elabEliminator paramPos n ty cons info = do
380 elimLog $ "Elaborating eliminator"
376 elimLog $ "Elaborating eliminator"
377+ put (Map.fromList $ zip (concatMap (\(_, p, _, ty, _, _) -> (map show $ boundNamesIn ty) ++ map (show . fst) p) cons ++ (map show $ boundNamesIn ty)) (repeat 0))
381 let (cnstrs, _) = splitPi ty
378 let (cnstrs, _) = splitPi ty
382 let (splittedTy@(pms, idxs)) = splitPms cnstrs
379 let (splittedTy@(pms, idxs)) = splitPms cnstrs
383 generalParams <- namePis False pms
380 generalParams <- namePis False pms
@@ -396,13 +393,14 @@ elabEliminator paramPos n ty cons info = do
396 let clauseGeneralArgs' = map getPiName generalParams ++ [motiveName] ++ clauseConsElimArgs
393 let clauseGeneralArgs' = map getPiName generalParams ++ [motiveName] ++ clauseConsElimArgs
397 let clauseGeneralArgs = map (\arg -> pexp (PRef elimFC arg)) clauseGeneralArgs'
394 let clauseGeneralArgs = map (\arg -> pexp (PRef elimFC arg)) clauseGeneralArgs'
398 let elimSig = "-- eliminator signature: " ++ showTmImpls eliminatorTy
395 let elimSig = "-- eliminator signature: " ++ showTmImpls eliminatorTy
396+ elimLog elimSig
399 eliminatorClauses <- mapM (\(cns, cnsElim) -> generateEliminatorClauses cns cnsElim clauseGeneralArgs generalParams) (zip cons clauseConsElimArgs)
397 eliminatorClauses <- mapM (\(cns, cnsElim) -> generateEliminatorClauses cns cnsElim clauseGeneralArgs generalParams) (zip cons clauseConsElimArgs)
400 let eliminatorDef = PClauses emptyFC [TotalFn] elimDeclName eliminatorClauses
398 let eliminatorDef = PClauses emptyFC [TotalFn] elimDeclName eliminatorClauses
401− elimLog $ "-- eliminator definition: " ++ (show . showDeclImp True) eliminatorDef
399+ elimLog $ "-- eliminator definition: " ++ (show . showDeclImp verbosePPOption) eliminatorDef
402 State.lift $ idrisCatch (elabDecl EAll info eliminatorTyDecl) (\err -> return ())
400 State.lift $ idrisCatch (elabDecl EAll info eliminatorTyDecl) (\err -> return ())
403 -- Do not elaborate clauses if there aren't any
401 -- Do not elaborate clauses if there aren't any
404 case eliminatorClauses of
402 case eliminatorClauses of
405− [] -> return ()
403+ [] -> State.lift $ solveDeferred elimDeclName -- Remove meta-variable for type
406 _ -> State.lift $ idrisCatch (elabDecl EAll info eliminatorDef) (\err -> return ())
404 _ -> State.lift $ idrisCatch (elabDecl EAll info eliminatorDef) (\err -> return ())
407 where elimLog :: String -> EliminatorState ()
405 where elimLog :: String -> EliminatorState ()
408 elimLog s = State.lift (logLvl 2 s)
406 elimLog s = State.lift (logLvl 2 s)
@@ -465,9 +463,9 @@ elabEliminator paramPos n ty cons info = do
465 freshName key = do
463 freshName key = do
466 nameMap <- get
464 nameMap <- get
467 let i = fromMaybe 0 (Map.lookup key nameMap)
465 let i = fromMaybe 0 (Map.lookup key nameMap)
468− let name = key ++ show i
466+ let name = uniqueName (sUN (key ++ show i)) (map (\(nm, nb) -> sUN (nm ++ show nb)) $ Map.toList nameMap)
469 put $ Map.insert key (i+1) nameMap
467 put $ Map.insert key (i+1) nameMap
470− return (sUN name)
468+ return name
471
469
472 scrutineeName :: Name
470 scrutineeName :: Name
473 scrutineeName = sUN "scrutinee"
471 scrutineeName = sUN "scrutinee"
@@ -560,7 +558,7 @@ elabEliminator paramPos n ty cons info = do
560 let cons' = replaceParams paramPos generalParameters ty
558 let cons' = replaceParams paramPos generalParameters ty
561 let (args, resTy) = splitPi cons'
559 let (args, resTy) = splitPi cons'
562 implidxs <- implicitIndexes (doc, cnm, ty, fc, fs)
560 implidxs <- implicitIndexes (doc, cnm, ty, fc, fs)
563− consArgs <- namePis True args
561+ consArgs <- namePis False args
564 let recArgs = findRecArgs consArgs
562 let recArgs = findRecArgs consArgs
565 let recMotives = map applyRecMotive recArgs
563 let recMotives = map applyRecMotive recArgs
566 let (_, consIdxs) = splitArgPms resTy
564 let (_, consIdxs) = splitArgPms resTy
@@ -599,7 +597,7 @@ elabEliminator paramPos n ty cons info = do
599 implidxs <- implicitIndexes (doc, cnm, ty, fc, fs)
597 implidxs <- implicitIndexes (doc, cnm, ty, fc, fs)
600 let (_, generalIdxs') = splitArgPms resTy
598 let (_, generalIdxs') = splitArgPms resTy
601 let generalIdxs = map pexp generalIdxs'
599 let generalIdxs = map pexp generalIdxs'
602− consArgs <- namePis True args
600+ consArgs <- namePis False args
603 let lhsPattern = PApp elimFC (PRef elimFC elimDeclName) (generalArgs ++ generalIdxs ++ [pexp $ applyCons cnm consArgs])
601 let lhsPattern = PApp elimFC (PRef elimFC elimDeclName) (generalArgs ++ generalIdxs ++ [pexp $ applyCons cnm consArgs])
604 let recArgs = findRecArgs consArgs
602 let recArgs = findRecArgs consArgs
605 let recElims = map applyRecElim recArgs
603 let recElims = map applyRecElim recArgs
@@ -613,10 +611,12 @@ elabEliminator paramPos n ty cons info = do
613
611
614elabPrims :: Idris ()
612elabPrims :: Idris ()
615elabPrims = do mapM_ (elabDecl EAll toplevel)
613elabPrims = do mapM_ (elabDecl EAll toplevel)
616− (map (\(opt, decl) -> PData emptyDocstring [] defaultSyntax (fileFC "builtin") opt decl)
614+ (map (\(opt, decl, docs, argdocs) -> PData docs argdocs defaultSyntax (fileFC "builtin") opt decl)
617− (zip
615+ (zip4
618 [inferOpts, unitOpts, falseOpts, pairOpts, eqOpts]
616 [inferOpts, unitOpts, falseOpts, pairOpts, eqOpts]
619− [inferDecl, unitDecl, falseDecl, pairDecl, eqDecl]))
617+ [inferDecl, unitDecl, falseDecl, pairDecl, eqDecl]
618+ [emptyDocstring, unitDoc, falseDoc, pairDoc, eqDoc]
619+ [[], [], [], pairParamDoc, eqParamDoc]))
620 addNameHint eqTy (sUN "prf")
620 addNameHint eqTy (sUN "prf")
621 elabDecl EAll toplevel elimDecl
621 elabDecl EAll toplevel elimDecl
622 mapM_ elabPrim primitives
622 mapM_ elabPrim primitives
@@ -681,8 +681,8 @@ elabPrims = do mapM_ (elabDecl EAll toplevel)
681
681
682
682
683-- | Elaborate a type provider
683-- | Elaborate a type provider
684−elabProvider :: ElabInfo -> SyntaxInfo -> FC -> ProvideWhat -> Name -> PTerm -> PTerm -> Idris ()
684+elabProvider :: ElabInfo -> SyntaxInfo -> FC -> ProvideWhat -> Name -> Idris ()
685−elabProvider info syn fc what n ty tm
685+elabProvider info syn fc what n
686 = do i <- getIState
686 = do i <- getIState
687 -- Ensure that the experimental extension is enabled
687 -- Ensure that the experimental extension is enabled
688 unless (TypeProviders `elem` idris_language_extensions i) $
688 unless (TypeProviders `elem` idris_language_extensions i) $
@@ -692,12 +692,17 @@ elabProvider info syn fc what n ty tm
692 ctxt <- getContext
692 ctxt <- getContext
693
693
694 -- First elaborate the expected type (and check that it's a type)
694 -- First elaborate the expected type (and check that it's a type)
695+ -- The goal type for a postulate is always Type.
696+ (ty', typ) <- case what of
695− (ty', typ) <- elabVal toplevel False ty
697+ ProvTerm ty p -> elabVal toplevel False ty
698+ ProvPostulate _ -> elabVal toplevel False PType
696 unless (isTType typ) $
699 unless (isTType typ) $
697 ifail ("Expected a type, got " ++ show ty' ++ " : " ++ show typ)
700 ifail ("Expected a type, got " ++ show ty' ++ " : " ++ show typ)
698
701
699 -- Elaborate the provider term to TT and check that the type matches
702 -- Elaborate the provider term to TT and check that the type matches
703+ (e, et) <- case what of
704+ ProvTerm _ tm -> elabVal toplevel False tm
700− (e, et) <- elabVal toplevel False tm
705+ ProvPostulate tm -> elabVal toplevel False tm
701 unless (isProviderOf (normalise ctxt [] ty') et) $
706 unless (isProviderOf (normalise ctxt [] ty') et) $
702 ifail $ "Expected provider type IO (Provider (" ++
707 ifail $ "Expected provider type IO (Provider (" ++
703 show ty' ++ "))" ++ ", got " ++ show et ++ " instead."
708 show ty' ++ "))" ++ ", got " ++ show et ++ " instead."
@@ -715,17 +720,14 @@ elabProvider info syn fc what n ty tm
715
720
716 case provided of
721 case provided of
717 Provide tm
722 Provide tm
718− | what `elem` [ProvTerm, ProvAny] ->
723+ | ProvTerm ty _ <- what ->
719 do -- Finally add a top-level definition of the provided term
724 do -- Finally add a top-level definition of the provided term
720 elabType info syn emptyDocstring [] fc [] n ty
725 elabType info syn emptyDocstring [] fc [] n ty
721 elabClauses info fc [] n [PClause fc n (PApp fc (PRef fc n) []) [] (delab i tm) []]
726 elabClauses info fc [] n [PClause fc n (PApp fc (PRef fc n) []) [] (delab i tm) []]
722 logLvl 3 $ "Elaborated provider " ++ show n ++ " as: " ++ show tm
727 logLvl 3 $ "Elaborated provider " ++ show n ++ " as: " ++ show tm
723− | otherwise ->
724− ierror . Msg $ "Attempted to provide a term where a postulate was expected."
725− Postulate
726− | what `elem` [ProvPostulate, ProvAny] ->
728+ | ProvPostulate _ <- what ->
727 do -- Add the postulate
729 do -- Add the postulate
728− elabPostulate info syn (parseDocstring $ T.pack "Provided postulate") fc [] n ty
730+ elabPostulate info syn (parseDocstring $ T.pack "Provided postulate") fc [] n (delab i tm)
729 logLvl 3 $ "Elaborated provided postulate " ++ show n
731 logLvl 3 $ "Elaborated provided postulate " ++ show n
730 | otherwise ->
732 | otherwise ->
731 ierror . Msg $ "Attempted to provide a postulate where a term was expected."
733 ierror . Msg $ "Attempted to provide a postulate where a term was expected."
@@ -776,12 +778,17 @@ elabTransform info fc safe lhs_in rhs_in
776
778
777
779
778elabRecord :: ElabInfo -> SyntaxInfo -> Docstring -> FC -> Name ->
780elabRecord :: ElabInfo -> SyntaxInfo -> Docstring -> FC -> Name ->
779− PTerm -> Docstring -> Name -> PTerm -> Idris ()
781+ PTerm -> DataOpts -> Docstring -> Name -> PTerm -> Idris ()
780−elabRecord info syn doc fc tyn ty cdoc cn cty
782+elabRecord info syn doc fc tyn ty opts cdoc cn cty_in
781− = do elabData info syn doc [] fc [] (PDatadecl tyn ty [(cdoc, [], cn, cty, fc, [])])
783+ = do elabData info syn doc [] fc opts (PDatadecl tyn ty [(cdoc, [], cn, cty_in, fc, [])])
782 -- TODO think: something more in info?
784 -- TODO think: something more in info?
783− cty' <- implicit info syn cn cty
785+ cty' <- implicit info syn cn cty_in
784 i <- getIState
786 i <- getIState
787+
788+ -- get bound implicits and propagate to setters (in case they
789+ -- provide useful information for inference)
790+ let extraImpls = getBoundImpls cty'
791+
785 cty <- case lookupTy cn (tt_ctxt i) of
792 cty <- case lookupTy cn (tt_ctxt i) of
786 [t] -> return (delab i t)
793 [t] -> return (delab i t)
787 _ -> ifail "Something went inexplicably wrong"
794 _ -> ifail "Something went inexplicably wrong"
@@ -790,14 +797,29 @@ elabRecord info syn doc fc tyn ty cdoc cn cty
790 let ptys = getProjs [] (renameBs cimp cty)
797 let ptys = getProjs [] (renameBs cimp cty)
791 let ptys_u = getProjs [] cty
798 let ptys_u = getProjs [] cty
792 let recty = getRecTy cty
799 let recty = getRecTy cty
800+
801+ -- rename indices when we generate the getter/setter types, so
802+ -- that they don't clash with the names of the projections
803+ -- we're generating
804+ let index_names_in = getRecNameMap "_in" recty
805+ let recty_in = substMatches index_names_in recty
806+
793− logLvl 6 $ show (recty, ptys)
807+ logLvl 1 $ show (recty, ptys)
794 let substs = map (\ (n, _) -> (n, PApp fc (PRef fc n)
808 let substs = map (\ (n, _) -> (n, PApp fc (PRef fc n)
795 [pexp (PRef fc rec)])) ptys
809 [pexp (PRef fc rec)])) ptys
810+
811+ -- Generate projection functions
796− proj_decls <- mapM (mkProj recty substs cimp) (zip ptys [0..])
812+ proj_decls <- mapM (mkProj recty_in substs cimp) (zip ptys [0..])
813+ logLvl 3 $ show proj_decls
797 let nonImp = mapMaybe isNonImp (zip cimp ptys_u)
814 let nonImp = mapMaybe isNonImp (zip cimp ptys_u)
798 let implBinds = getImplB id cty'
815 let implBinds = getImplB id cty'
816+
817+ -- Generate update functions
818+ update_decls <- mapM (mkUpdate recty index_names_in extraImpls
819+ (getFieldNames cty')
799− update_decls <- mapM (mkUpdate recty implBinds (length nonImp)) (zip nonImp [0..])
820+ implBinds (length nonImp)) (zip nonImp [0..])
800 mapM_ (elabDecl EAll info) (concat proj_decls)
821 mapM_ (elabDecl EAll info) (concat proj_decls)
822+ logLvl 3 $ show update_decls
801 mapM_ (tryElabDecl info) (update_decls)
823 mapM_ (tryElabDecl info) (update_decls)
802 where
824 where
803-- syn = syn_in { syn_namespace = show (nsroot tyn) : syn_namespace syn_in }
825-- syn = syn_in { syn_namespace = show (nsroot tyn) : syn_namespace syn_in }
@@ -812,8 +834,12 @@ elabRecord info syn doc fc tyn ty cdoc cn cty
812 (\v -> do iputStrLn $ show fc ++
834 (\v -> do iputStrLn $ show fc ++
813 ":Warning - can't generate setter for " ++
835 ":Warning - can't generate setter for " ++
814 show fn ++ " (" ++ show ty ++ ")"
836 show fn ++ " (" ++ show ty ++ ")"
837+-- ++ "\n" ++ pshow i v
815 putIState i)
838 putIState i)
816
839
840+ getBoundImpls (PPi (Imp _ _ _) n ty sc) = (n, ty) : getBoundImpls sc
841+ getBoundImpls _ = []
842+
817 getImplB k (PPi (Imp l s _) n Placeholder sc)
843 getImplB k (PPi (Imp l s _) n Placeholder sc)
818 = getImplB k sc
844 = getImplB k sc
819 getImplB k (PPi (Imp l s p) n ty sc)
845 getImplB k (PPi (Imp l s p) n ty sc)
@@ -830,9 +856,19 @@ elabRecord info syn doc fc tyn ty cdoc cn cty
830 getProjs acc (PPi _ n ty s) = getProjs ((n, ty) : acc) s
856 getProjs acc (PPi _ n ty s) = getProjs ((n, ty) : acc) s
831 getProjs acc r = reverse acc
857 getProjs acc r = reverse acc
832
858
859+ getFieldNames (PPi (Exp _ _ _) n _ s) = n : getFieldNames s
860+ getFieldNames (PPi _ _ _ s) = getFieldNames s
861+ getFieldNames _ = []
862+
833 getRecTy (PPi _ n ty s) = getRecTy s
863 getRecTy (PPi _ n ty s) = getRecTy s
834 getRecTy t = t
864 getRecTy t = t
835
865
866+ getRecNameMap x (PApp fc t args) = mapMaybe (toMN . getTm) args
867+ where
868+ toMN (PRef fc n) = Just (n, PRef fc (sMN 0 (show n ++ x)))
869+ toMN _ = Nothing
870+ getRecNameMap x _ = []
871+
836 rec = sMN 0 "rec"
872 rec = sMN 0 "rec"
837
873
838 mkp (UN n) = sMN 0 ("p_" ++ str n)
874 mkp (UN n) = sMN 0 ("p_" ++ str n)
@@ -865,13 +901,23 @@ elabRecord info syn doc fc tyn ty cdoc cn cty
865
901
866 implicitise (pa, t) = pa { getTm = t }
902 implicitise (pa, t) = pa { getTm = t }
867
903
904+ -- If the 'pty' we're updating includes anything in 'substs', we're
905+ -- updating the type as well, so use recty', otherwise just use
906+ -- recty
868− mkUpdate recty k num ((pn, pty), pos)
907+ mkUpdate recty inames extras fnames k num ((pn, pty), pos)
869 = do let setname = expandNS syn $ mkType pn
908 = do let setname = expandNS syn $ mkType pn
870 let valname = sMN 0 "updateval"
909 let valname = sMN 0 "updateval"
871− let pt = k (PPi expl pn pty
910+ let pn_out = sMN 0 (show pn ++ "_out")
911+ let pn_in = sMN 0 (show pn ++ "_in")
912+ let recty_in = substMatches [(pn, PRef fc pn_in)] recty
913+ let recty_out = substMatches [(pn, PRef fc pn_out)] recty
914+ let pt = substMatches inames $
915+ k (implBindUp extras inames (PPi expl pn_out pty
872− (PPi expl rec recty recty))
916+ (PPi expl rec recty_in recty_out)))
873 let pfnTy = PTy emptyDocstring [] defaultSyntax fc [] setname pt
917 let pfnTy = PTy emptyDocstring [] defaultSyntax fc [] setname pt
874− let pls = map (\x -> PRef fc (sMN x "field")) [0..num-1]
918+-- let pls = map (\x -> PRef fc (sMN x ("field" ++ show x))) [0..num-1]
919+ let inames_imp = map (\ (x,_) -> (x, Placeholder)) inames
920+ let pls = map (\x -> substMatches inames_imp (PRef fc x)) fnames
875 let lhsArgs = pls
921 let lhsArgs = pls
876 let rhsArgs = take pos pls ++ (PRef fc valname) :
922 let rhsArgs = take pos pls ++ (PRef fc valname) :
877 drop (pos + 1) pls
923 drop (pos + 1) pls
@@ -885,6 +931,15 @@ elabRecord info syn doc fc tyn ty cdoc cn cty
885 (map pexp rhsArgs)) []
931 (map pexp rhsArgs)) []
886 return (pn, pfnTy, PClauses fc [] setname [pclause])
932 return (pn, pfnTy, PClauses fc [] setname [pclause])
887
933
934+ implBindUp [] is t = t
935+ implBindUp ((n, ty):ns) is t
936+ = let n' = case lookup n is of
937+ Just (PRef _ x) -> x
938+ _ -> n in
939+ if n `elem` allNamesIn t
940+ then PPi impl n' ty (implBindUp ns is t)
941+ else implBindUp ns is t
942+
888-- FIXME: 'forcenames' is an almighty hack! Need a better way of
943-- FIXME: 'forcenames' is an almighty hack! Need a better way of
889-- erasing non-forceable things
944-- erasing non-forceable things
890-- ^^^
945-- ^^^
@@ -918,7 +973,7 @@ elabCon info syn tn codata (doc, argDocs, n, t_in, fc, forcenames)
918 checkDocs fc argDocs t_in
973 checkDocs fc argDocs t_in
919 addDocStr n doc argDocs
974 addDocStr n doc argDocs
920 addIBC (IBCDoc n)
975 addIBC (IBCDoc n)
921− saveInaccArgs n inacc
976+ fputState (opt_inaccessible . ist_optimisation n) inacc
922 addIBC (IBCOpt n)
977 addIBC (IBCOpt n)
923 return (n, cty')
978 return (n, cty')
924 where
979 where
@@ -953,9 +1008,8 @@ elabClauses :: ElabInfo -> FC -> FnOpts -> Name -> [PClause] -> Idris ()
953elabClauses info fc opts n_in cs = let n = liftname info n_in in
1008elabClauses info fc opts n_in cs = let n = liftname info n_in in
954 do ctxt <- getContext
1009 do ctxt <- getContext
955 ist <- getIState
1010 ist <- getIState
956− let inacc = case lookupCtxt n (idris_optimisation ist) of
1011+ inacc <- map fst <$> fgetState (opt_inaccessible . ist_optimisation n)
957− [Optimise inacc _] -> map fst inacc
1012+
958− _ -> []
959 -- Check n actually exists, with no definition yet
1013 -- Check n actually exists, with no definition yet
960 let tys = lookupTy n ctxt
1014 let tys = lookupTy n ctxt
961 let reflect = Reflection `elem` opts
1015 let reflect = Reflection `elem` opts
@@ -975,9 +1029,8 @@ elabClauses info fc opts n_in cs = let n = liftname info n_in in
975
1029
976 solveDeferred n
1030 solveDeferred n
977
1031
978− ist <- getIState
1032+ -- just ensure that the structure exists
979− let opts = addDef n (Optimise [] False) (idris_optimisation ist)
1033+ fmodifyState (ist_optimisation n) id
980− in putIState (ist { idris_optimisation = opts })
981 addIBC (IBCOpt n)
1034 addIBC (IBCOpt n)
982
1035
983 ist <- getIState
1036 ist <- getIState
@@ -1147,7 +1200,8 @@ elabClauses info fc opts n_in cs = let n = liftname info n_in in
1147 force (normalisePats ctxt [] y))
1200 force (normalisePats ctxt [] y))
1148 simple_lhs ctxt t = t
1201 simple_lhs ctxt t = t
1149
1202
1150− simple_rt ctxt (p, x, y) = (p, x, force (rt_simplify ctxt [] y))
1203+ simple_rt ctxt (p, x, y) = (p, x, force (uniqueBinders p
1204+ (rt_simplify ctxt [] y)))
1151
1205
1152 -- this is so pattern types are in the right form for erasure
1206 -- this is so pattern types are in the right form for erasure
1153 normalisePats ctxt env (Bind n (PVar t) sc)
1207 normalisePats ctxt env (Bind n (PVar t) sc)
@@ -1259,8 +1313,8 @@ elabPE info fc caller r =
1259
1313
1260-- Elaborate a value, returning any new bindings created (this will only
1314-- Elaborate a value, returning any new bindings created (this will only
1261-- happen if elaborating as a pattern clause)
1315-- happen if elaborating as a pattern clause)
1262−elabValBind :: ElabInfo -> Bool -> PTerm -> Idris (Term, Type, [(Name, Type)])
1316+elabValBind :: ElabInfo -> Bool -> Bool -> PTerm -> Idris (Term, Type, [(Name, Type)])
1263−elabValBind info aspat tm_in
1317+elabValBind info aspat norm tm_in
1264 = do ctxt <- getContext
1318 = do ctxt <- getContext
1265 i <- getIState
1319 i <- getIState
1266 let tm = addImpl i tm_in
1320 let tm = addImpl i tm_in
@@ -1285,14 +1339,17 @@ elabValBind info aspat tm_in
1285 logLvl 3 ("Value: " ++ show vtm)
1339 logLvl 3 ("Value: " ++ show vtm)
1286-- recheckC (fileFC "(input)") [] tm'
1340-- recheckC (fileFC "(input)") [] tm'
1287-- logLvl 2 (show vtm)
1341-- logLvl 2 (show vtm)
1288− (vtm, vty) <- recheckC (fileFC "(input)") [] vtm
1342+ (vtm_in, vty) <- recheckC (fileFC "(input)") [] vtm
1343+
1344+ let vtm = if norm then normalise (tt_ctxt i) [] vtm_in
1345+ else vtm_in
1289 let bargs = getPBtys vtm
1346 let bargs = getPBtys vtm
1290
1347
1291 return (vtm, vty, bargs)
1348 return (vtm, vty, bargs)
1292
1349
1293elabVal :: ElabInfo -> Bool -> PTerm -> Idris (Term, Type)
1350elabVal :: ElabInfo -> Bool -> PTerm -> Idris (Term, Type)
1294elabVal info aspat tm_in
1351elabVal info aspat tm_in
1295− = do (tm, ty, _) <- elabValBind info aspat tm_in
1352+ = do (tm, ty, _) <- elabValBind info aspat False tm_in
1296 return (tm, ty)
1353 return (tm, ty)
1297
1354
1298-- checks if the clause is a possible left hand side. Returns the term if
1355-- checks if the clause is a possible left hand side. Returns the term if
@@ -1302,7 +1359,7 @@ checkPossible :: ElabInfo -> FC -> Bool -> Name -> PTerm -> Idris Bool
1302checkPossible info fc tcgen fname lhs_in
1359checkPossible info fc tcgen fname lhs_in
1303 = do ctxt <- getContext
1360 = do ctxt <- getContext
1304 i <- getIState
1361 i <- getIState
1305− let lhs = addImpl i lhs_in
1362+ let lhs = addImplPat i lhs_in
1306 -- if the LHS type checks, it is possible
1363 -- if the LHS type checks, it is possible
1307 case elaborate ctxt (sMN 0 "patLHS") infP []
1364 case elaborate ctxt (sMN 0 "patLHS") infP []
1308 (erun fc (buildTC i info True [] fname (infTerm lhs))) of
1365 (erun fc (buildTC i info True [] fname (infTerm lhs))) of
@@ -1311,21 +1368,53 @@ checkPossible info fc tcgen fname lhs_in
1311 case recheck ctxt [] (forget lhs_tm) lhs_tm of
1368 case recheck ctxt [] (forget lhs_tm) lhs_tm of
1312 OK _ -> return True
1369 OK _ -> return True
1313 err -> return False
1370 err -> return False
1371+ -- if it's a recoverable error, the case may become possible
1314− Error err -> if tcgen then return False
1372+ Error err -> if tcgen then return (recoverable ctxt err)
1315− else return (impossibleError err)
1373+ else return (validCase ctxt err ||
1374+ recoverable ctxt err)
1316− where impossibleError (CantUnify _ topx topy e _ _)
1375+ where validCase ctxt (CantUnify _ topx topy e _ _)
1376+ = let topx' = normalise ctxt [] topx
1377+ topy' = normalise ctxt [] topy in
1317− = not (sameFam topx topy || not (impossibleError e))
1378+ not (sameFam topx' topy' || not (validCase ctxt e))
1318− impossibleError (CantConvert _ _ _) = False
1379+ validCase ctxt (CantConvert _ _ _) = False
1319− impossibleError (At _ e) = impossibleError e
1380+ validCase ctxt (At _ e) = validCase ctxt e
1320− impossibleError (Elaborating _ _ e) = impossibleError e
1381+ validCase ctxt (Elaborating _ _ e) = validCase ctxt e
1321− impossibleError (ElaboratingArg _ _ _ e) = impossibleError e
1382+ validCase ctxt (ElaboratingArg _ _ _ e) = validCase ctxt e
1322− impossibleError _ = True
1383+ validCase ctxt _ = True
1384+
1385+ recoverable ctxt (CantUnify r topx topy e _ _)
1386+ = let topx' = normalise ctxt [] topx
1387+ topy' = normalise ctxt [] topy in
1388+ checkRec topx' topy'
1389+ recoverable ctxt (At _ e) = recoverable ctxt e
1390+ recoverable ctxt (Elaborating _ _ e) = recoverable ctxt e
1391+ recoverable ctxt (ElaboratingArg _ _ _ e) = recoverable ctxt e
1392+ recoverable _ _ = False
1323
1393
1324 sameFam topx topy
1394 sameFam topx topy
1325 = case (unApply topx, unApply topy) of
1395 = case (unApply topx, unApply topy) of
1326 ((P _ x _, _), (P _ y _, _)) -> x == y
1396 ((P _ x _, _), (P _ y _, _)) -> x == y
1327 _ -> False
1397 _ -> False
1328
1398
1399+ -- different notion of recoverable than in unification, since we
1400+ -- have no metavars -- just looking to see if a constructor is failing
1401+ -- to unify with a function that may be reduced later
1402+
1403+ checkRec (App f a) p@(P _ _ _) = checkRec f p
1404+ checkRec p@(P _ _ _) (App f a) = checkRec p f
1405+ checkRec fa@(App _ _) fa'@(App _ _)
1406+ | (f, as) <- unApply fa,
1407+ (f', as') <- unApply fa'
1408+ = if (length as /= length as')
1409+ then checkRec f f'
1410+ else checkRec f f' && and (zipWith checkRec as as')
1411+ checkRec (P xt x _) (P yt y _) = x == y || ntRec xt yt
1412+ checkRec _ _ = False
1413+
1414+ ntRec x y | Ref <- x = True
1415+ | Ref <- y = True
1416+ | otherwise = False -- name is different, unrecoverable
1417+
1329getFixedInType i env (PExp _ _ _ _ : is) (Bind n (Pi t) sc)
1418getFixedInType i env (PExp _ _ _ _ : is) (Bind n (Pi t) sc)
1330 = getFixedInType i (n : env) is (instantiate (P Bound n t) sc)
1419 = getFixedInType i (n : env) is (instantiate (P Bound n t) sc)
1331getFixedInType i env (_ : is) (Bind n (Pi t) sc)
1420getFixedInType i env (_ : is) (Bind n (Pi t) sc)
@@ -1533,7 +1622,7 @@ elabClause info opts (cnum, PClause fc fname lhs_in withs rhs_in whereblock)
1533 rev <- case ret_fam of
1622 rev <- case ret_fam of
1534 P _ rfamn _ ->
1623 P _ rfamn _ ->
1535 case lookupCtxt rfamn (idris_datatypes i) of
1624 case lookupCtxt rfamn (idris_datatypes i) of
1536− [TI _ _ dopts _] ->
1625+ [TI _ _ dopts _ _] ->
1537 return (DataErrRev `elem` dopts)
1626 return (DataErrRev `elem` dopts)
1538 _ -> return False
1627 _ -> return False
1539 _ -> return False
1628 _ -> return False
@@ -1644,6 +1733,7 @@ elabClause info opts (_, PWith fc fname lhs_in withs wval_in withblock)
1644 let def'' = map (\(n, (i, top, t)) -> (n, (i, top, t, False))) def'
1733 let def'' = map (\(n, (i, top, t)) -> (n, (i, top, t, False))) def'
1645 addDeferred def''
1734 addDeferred def''
1646 mapM_ (elabCaseBlock info opts) is
1735 mapM_ (elabCaseBlock info opts) is
1736+ logLvl 5 ("Checked wval " ++ show wval')
1647 (cwval, cwvalty) <- recheckC fc [] (getInferTerm wval')
1737 (cwval, cwvalty) <- recheckC fc [] (getInferTerm wval')
1648 let cwvaltyN = explicitNames cwvalty
1738 let cwvaltyN = explicitNames cwvalty
1649 let cwvalN = explicitNames cwval
1739 let cwvalN = explicitNames cwval
@@ -1742,7 +1832,7 @@ elabClause info opts (_, PWith fc fname lhs_in withs wval_in withblock)
1742 do lhs <- updateLHS n wname mvars ns ns' (fullApp tm) w
1832 do lhs <- updateLHS n wname mvars ns ns' (fullApp tm) w
1743 return $ PWith fc wname lhs ws wval withs'
1833 return $ PWith fc wname lhs ws wval withs'
1744 mkAux wname toplhs ns ns' c
1834 mkAux wname toplhs ns ns' c
1745− = ifail $ show fc ++ "badly formed with clause"
1835+ = ifail $ show fc ++ ":badly formed with clause"
1746
1836
1747 addArg (PApp fc f args) w = PApp fc f (args ++ [pexp w])
1837 addArg (PApp fc f args) w = PApp fc f (args ++ [pexp w])
1748 addArg (PRef fc f) w = PApp fc (PRef fc f) [pexp w]
1838 addArg (PRef fc f) w = PApp fc (PRef fc f) [pexp w]
@@ -1753,8 +1843,8 @@ elabClause info opts (_, PWith fc fname lhs_in withs wval_in withblock)
1753 return $ substMatches mvars $
1843 return $ substMatches mvars $
1754 PApp fc (PRef fc' wname)
1844 PApp fc (PRef fc' wname)
1755 (map pexp ns ++ pexp w : (map pexp ns'))
1845 (map pexp ns ++ pexp w : (map pexp ns'))
1756− updateLHS n wname mvars ns ns' tm w
1846+ updateLHS n wname mvars ns_in ns_in' tm w
1757− = ifail $ "Not implemented match " ++ show tm
1847+ = updateLHS n wname mvars ns_in ns_in' (PApp fc tm []) w
1758
1848
1759 keepMvar mvs fc v | v `elem` mvs = PRef fc v
1849 keepMvar mvs fc v | v `elem` mvs = PRef fc v
1760 | otherwise = Placeholder
1850 | otherwise = Placeholder
@@ -1774,8 +1864,8 @@ data MArgTy = IA | EA | CA deriving Show
1774
1864
1775elabClass :: ElabInfo -> SyntaxInfo -> Docstring ->
1865elabClass :: ElabInfo -> SyntaxInfo -> Docstring ->
1776 FC -> [PTerm] ->
1866 FC -> [PTerm] ->
1777− Name -> [(Name, PTerm)] -> [PDecl] -> Idris ()
1867+ Name -> [(Name, PTerm)] -> [(Name, Docstring)] -> [PDecl] -> Idris ()
1778−elabClass info syn doc fc constraints tn ps ds
1868+elabClass info syn doc fc constraints tn ps pDocs ds
1779 = do let cn = SN (InstanceCtorN tn) -- sUN ("instance" ++ show tn) -- MN 0 ("instance" ++ show tn)
1869 = do let cn = SN (InstanceCtorN tn) -- sUN ("instance" ++ show tn) -- MN 0 ("instance" ++ show tn)
1780 let tty = pibind ps PType
1870 let tty = pibind ps PType
1781 let constraint = PApp fc (PRef fc tn)
1871 let constraint = PApp fc (PRef fc tn)
@@ -1801,8 +1891,8 @@ elabClass info syn doc fc constraints tn ps ds
1801 constraint
1891 constraint
1802 let cons = [(emptyDocstring, [], cn, cty, fc, [])]
1892 let cons = [(emptyDocstring, [], cn, cty, fc, [])]
1803 let ddecl = PDatadecl tn tty cons
1893 let ddecl = PDatadecl tn tty cons
1804− logLvl 5 $ "Class data " ++ show (showDImp True ddecl)
1894+ logLvl 5 $ "Class data " ++ show (showDImp verbosePPOption ddecl)
1805− elabData info (syn { no_imp = no_imp syn ++ mnames }) doc [] fc [] ddecl
1895+ elabData info (syn { no_imp = no_imp syn ++ mnames }) doc pDocs fc [] ddecl
1806 -- for each constraint, build a top level function to chase it
1896 -- for each constraint, build a top level function to chase it
1807 logLvl 5 $ "Building functions"
1897 logLvl 5 $ "Building functions"
1808 let usyn = syn { using = map (\ (x,y) -> UImplicit x y) ps
1898 let usyn = syn { using = map (\ (x,y) -> UImplicit x y) ps
@@ -1919,12 +2009,12 @@ elabClass info syn doc fc constraints tn ps ds
1919 getMeth (m:ms) (a:as) x | x == a = PRef fc m
2009 getMeth (m:ms) (a:as) x | x == a = PRef fc m
1920 | otherwise = getMeth ms as x
2010 | otherwise = getMeth ms as x
1921
2011
1922− lhsArgs (EA : xs) (n : ns) = pexp (PRef fc n) : lhsArgs xs ns
2012+ lhsArgs (EA : xs) (n : ns) = [] -- pexp (PRef fc n) : lhsArgs xs ns
1923 lhsArgs (IA : xs) ns = lhsArgs xs ns
2013 lhsArgs (IA : xs) ns = lhsArgs xs ns
1924 lhsArgs (CA : xs) ns = lhsArgs xs ns
2014 lhsArgs (CA : xs) ns = lhsArgs xs ns
1925 lhsArgs [] _ = []
2015 lhsArgs [] _ = []
1926
2016
1927− rhsArgs (EA : xs) (n : ns) = pexp (PRef fc n) : rhsArgs xs ns
2017+ rhsArgs (EA : xs) (n : ns) = [] -- pexp (PRef fc n) : rhsArgs xs ns
1928 rhsArgs (IA : xs) ns = pexp Placeholder : rhsArgs xs ns
2018 rhsArgs (IA : xs) ns = pexp Placeholder : rhsArgs xs ns
1929 rhsArgs (CA : xs) ns = pconst (PResolveTC fc) : rhsArgs xs ns
2019 rhsArgs (CA : xs) ns = pconst (PResolveTC fc) : rhsArgs xs ns
1930 rhsArgs [] _ = []
2020 rhsArgs [] _ = []
@@ -1952,10 +2042,13 @@ elabInstance info syn what fc cs n ps t expn ds = do
1952 i <- getIState
2042 i <- getIState
1953 (n, ci) <- case lookupCtxtName n (idris_classes i) of
2043 (n, ci) <- case lookupCtxtName n (idris_classes i) of
1954 [c] -> return c
2044 [c] -> return c
1955− _ -> ifail $ show fc ++ ":" ++ show n ++ " is not a type class"
2045+ [] -> ifail $ show fc ++ ":" ++ show n ++ " is not a type class"
2046+ cs -> tclift $ tfail $ At fc
2047+ (CantResolveAlts (map fst cs))
1956 let constraint = PApp fc (PRef fc n) (map pexp ps)
2048 let constraint = PApp fc (PRef fc n) (map pexp ps)
1957 let iname = mkiname n ps expn
2049 let iname = mkiname n ps expn
2050+ let emptyclass = null (class_methods ci)
1958− when (what /= EDefns) $ do
2051+ when (what /= EDefns || (null ds && not emptyclass)) $ do
1959 nty <- elabType' True info syn emptyDocstring [] fc [] iname t
2052 nty <- elabType' True info syn emptyDocstring [] fc [] iname t
1960 -- if the instance type matches any of the instances we have already,
2053 -- if the instance type matches any of the instances we have already,
1961 -- and it's not a named instance, then it's overlapping, so report an error
2054 -- and it's not a named instance, then it's overlapping, so report an error
@@ -1964,7 +2057,7 @@ elabInstance info syn what fc cs n ps t expn ds = do
1964 (class_instances ci)
2057 (class_instances ci)
1965 addInstance intInst n iname
2058 addInstance intInst n iname
1966 Just _ -> addInstance intInst n iname
2059 Just _ -> addInstance intInst n iname
1967− when (what /= ETypes) $ do
2060+ when (what /= ETypes && (not (null ds && not emptyclass))) $ do
1968 let ips = zip (class_params ci) ps
2061 let ips = zip (class_params ci) ps
1969 let ns = case n of
2062 let ns = case n of
1970 NS n ns' -> ns'
2063 NS n ns' -> ns'
@@ -1995,25 +2088,25 @@ elabInstance info syn what fc cs n ps t expn ds = do
1995 let wbTys = map mkTyDecl mtys
2088 let wbTys = map mkTyDecl mtys
1996 let wbVals = map (decorateid (decorate ns iname)) ds'
2089 let wbVals = map (decorateid (decorate ns iname)) ds'
1997 let wb = wbTys ++ wbVals
2090 let wb = wbTys ++ wbVals
1998− logLvl 3 $ "Method types " ++ showSep "\n" (map (show . showDeclImp True . mkTyDecl) mtys)
2091+ logLvl 3 $ "Method types " ++ showSep "\n" (map (show . showDeclImp verbosePPOption . mkTyDecl) mtys)
1999 logLvl 3 $ "Instance is " ++ show ps ++ " implicits " ++
2092 logLvl 3 $ "Instance is " ++ show ps ++ " implicits " ++
2000 show (concat (nub wparams))
2093 show (concat (nub wparams))
2001
2094
2002 -- Bring variables in instance head into scope
2095 -- Bring variables in instance head into scope
2003 ist <- getIState
2096 ist <- getIState
2004− let headVars = mapMaybe (\p -> case p of
2097+ let headVars = nub $ mapMaybe (\p -> case p of
2005− PRef _ n ->
2098+ PRef _ n ->
2006− case lookupTy n (tt_ctxt ist) of
2099+ case lookupTy n (tt_ctxt ist) of
2007− [] -> Just n
2100+ [] -> Just n
2008− _ -> Nothing
2101+ _ -> Nothing
2009− _ -> Nothing) ps
2102+ _ -> Nothing) ps
2010-- let lhs = PRef fc iname
2103-- let lhs = PRef fc iname
2011 let lhs = PApp fc (PRef fc iname)
2104 let lhs = PApp fc (PRef fc iname)
2012 (map (\n -> pimp n (PRef fc n) True) headVars)
2105 (map (\n -> pimp n (PRef fc n) True) headVars)
2013 let rhs = PApp fc (PRef fc (instanceName ci))
2106 let rhs = PApp fc (PRef fc (instanceName ci))
2014 (map (pexp . mkMethApp) mtys)
2107 (map (pexp . mkMethApp) mtys)
2015
2108
2016− logLvl 5 $ "Instance LHS " ++ show lhs
2109+ logLvl 5 $ "Instance LHS " ++ show lhs ++ " " ++ show headVars
2017 logLvl 5 $ "Instance RHS " ++ show rhs
2110 logLvl 5 $ "Instance RHS " ++ show rhs
2018
2111
2019 let idecls = [PClauses fc [Dictionary] iname
2112 let idecls = [PClauses fc [Dictionary] iname
@@ -2252,6 +2345,11 @@ elabDecl' what info (PMutual f ps)
2252 [p] -> elabDecl what info p
2345 [p] -> elabDecl what info p
2253 _ -> do mapM_ (elabDecl ETypes info) ps
2346 _ -> do mapM_ (elabDecl ETypes info) ps
2254 mapM_ (elabDecl EDefns info) ps
2347 mapM_ (elabDecl EDefns info) ps
2348+ -- record mutually defined data definitions
2349+ let datans = concatMap declared (filter isDataDecl ps)
2350+ mapM_ (setMutData datans) datans
2351+ iLOG $ "Rechecking for positivity " ++ show datans
2352+ mapM_ (\x -> do setTotality x Unchecked) datans
2255 -- Do totality checking after entire mutual block
2353 -- Do totality checking after entire mutual block
2256 i <- get
2354 i <- get
2257 mapM_ (\n -> do logLvl 5 $ "Simplifying " ++ show n
2355 mapM_ (\n -> do logLvl 5 $ "Simplifying " ++ show n
@@ -2260,6 +2358,16 @@ elabDecl' what info (PMutual f ps)
2260 mapM_ buildSCG (idris_totcheck i)
2358 mapM_ buildSCG (idris_totcheck i)
2261 mapM_ checkDeclTotality (idris_totcheck i)
2359 mapM_ checkDeclTotality (idris_totcheck i)
2262 clear_totcheck
2360 clear_totcheck
2361+ where isDataDecl (PData _ _ _ _ _ _) = True
2362+ isDataDecl _ = False
2363+
2364+ setMutData ns n
2365+ = do i <- getIState
2366+ case lookupCtxt n (idris_datatypes i) of
2367+ [x] -> do let x' = x { mutual_types = ns }
2368+ putIState $ i { idris_datatypes
2369+ = addDef n x' (idris_datatypes i) }
2370+ _ -> return ()
2263
2371
2264elabDecl' what info (PParams f ns ps)
2372elabDecl' what info (PParams f ns ps)
2265 = do i <- getIState
2373 = do i <- getIState
@@ -2282,17 +2390,17 @@ elabDecl' what info (PNamespace n ps) = mapM_ (elabDecl' what ninfo) ps
2282 ninfo = case namespace info of
2390 ninfo = case namespace info of
2283 Nothing -> info { namespace = Just [n] }
2391 Nothing -> info { namespace = Just [n] }
2284 Just ns -> info { namespace = Just (n:ns) }
2392 Just ns -> info { namespace = Just (n:ns) }
2285−elabDecl' what info (PClass doc s f cs n ps ds)
2393+elabDecl' what info (PClass doc s f cs n ps pdocs ds)
2286 | what /= EDefns
2394 | what /= EDefns
2287 = do iLOG $ "Elaborating class " ++ show n
2395 = do iLOG $ "Elaborating class " ++ show n
2288− elabClass info (s { syn_params = [] }) doc f cs n ps ds
2396+ elabClass info (s { syn_params = [] }) doc f cs n ps pdocs ds
2289elabDecl' what info (PInstance s f cs n ps t expn ds)
2397elabDecl' what info (PInstance s f cs n ps t expn ds)
2290 = do iLOG $ "Elaborating instance " ++ show n
2398 = do iLOG $ "Elaborating instance " ++ show n
2291 elabInstance info s what f cs n ps t expn ds
2399 elabInstance info s what f cs n ps t expn ds
2292−elabDecl' what info (PRecord doc s f tyn ty cdoc cn cty)
2400+elabDecl' what info (PRecord doc s f tyn ty opts cdoc cn cty)
2293 | what /= ETypes
2401 | what /= ETypes
2294 = do iLOG $ "Elaborating record " ++ show tyn
2402 = do iLOG $ "Elaborating record " ++ show tyn
2295− elabRecord info s doc f tyn ty cdoc cn cty
2403+ elabRecord info s doc f tyn ty opts cdoc cn cty
2296 | otherwise
2404 | otherwise
2297 = do iLOG $ "Elaborating [type of] " ++ show tyn
2405 = do iLOG $ "Elaborating [type of] " ++ show tyn
2298 elabData info s doc [] f [] (PLaterdecl tyn ty)
2406 elabData info s doc [] f [] (PLaterdecl tyn ty)
@@ -2302,10 +2410,10 @@ elabDecl' _ info (PDSL n dsl)
2302 addIBC (IBCDSL n)
2410 addIBC (IBCDSL n)
2303elabDecl' what info (PDirective i)
2411elabDecl' what info (PDirective i)
2304 | what /= EDefns = i
2412 | what /= EDefns = i
2305−elabDecl' what info (PProvider syn fc provWhat n tp tm)
2413+elabDecl' what info (PProvider syn fc provWhat n)
2306 | what /= EDefns
2414 | what /= EDefns
2307 = do iLOG $ "Elaborating type provider " ++ show n
2415 = do iLOG $ "Elaborating type provider " ++ show n
2308− elabProvider info syn fc provWhat n tp tm
2416+ elabProvider info syn fc provWhat n
2309elabDecl' what info (PTransform fc safety old new)
2417elabDecl' what info (PTransform fc safety old new)
2310 = elabTransform info fc safety old new
2418 = elabTransform info fc safety old new
2311elabDecl' _ _ _ = return () -- skipped this time
2419elabDecl' _ _ _ = return () -- skipped this time
src/Idris/ElabTerm.hs+55−24
@@ -66,15 +66,19 @@ build ist info pattern opts fn tm
66 ctxt <- get_context
66 ctxt <- get_context
67 probs <- get_probs
67 probs <- get_probs
68 u <- getUnifyLog
68 u <- getUnifyLog
69+ hs <- get_holes
69
70
70 when (not pattern) $
71 when (not pattern) $
71− traceWhen u ("Remaining problems:\n" ++ show probs) $
72+ traceWhen u ("Remaining holes:\n" ++ show hs ++ "\n" ++
73+ "Remaining problems:\n" ++ qshow probs) $
72− do matchProblems True; unifyProblems
74+ do unify_all; matchProblems True; unifyProblems
75+
73 probs <- get_probs
76 probs <- get_probs
74 case probs of
77 case probs of
75 [] -> return ()
78 [] -> return ()
79+ ((_,_,_,e,_,_):es) -> traceWhen u ("Final problems:\n" ++ show probs) $
76− ((_,_,_,e,_,_):es) -> if inf then return ()
80+ if inf then return ()
77− else lift (Error e)
81+ else lift (Error e)
78 is <- getAux
82 is <- getAux
79 tt <- get_term
83 tt <- get_term
80 let (tm, ds) = runState (collectDeferred (Just fn) tt) []
84 let (tm, ds) = runState (collectDeferred (Just fn) tt) []
@@ -123,6 +127,7 @@ elab ist info pattern opts fn tm
123 end_unify
127 end_unify
124 when pattern -- convert remaining holes to pattern vars
128 when pattern -- convert remaining holes to pattern vars
125 (do update_term orderPats
129 (do update_term orderPats
130+ unify_all
126 matchProblems False -- only the ones we matched earlier
131 matchProblems False -- only the ones we matched earlier
127 unifyProblems
132 unifyProblems
128 mkPat)
133 mkPat)
@@ -262,13 +267,14 @@ elab ist info pattern opts fn tm
262 ty <- goal
267 ty <- goal
263 ctxt <- get_context
268 ctxt <- get_context
264 let (tc, _) = unApply ty
269 let (tc, _) = unApply ty
270+ env <- get_env
265− let as' = pruneByType tc ctxt as
271+ let as' = pruneByType (map fst env) tc ctxt as
266-- trace (show as ++ "\n ==> " ++ showSep ", " (map showTmImpls as')) $
272-- trace (show as ++ "\n ==> " ++ showSep ", " (map showTmImpls as')) $
267 tryAll (zip (map (elab' ina) as') (map showHd as'))
273 tryAll (zip (map (elab' ina) as') (map showHd as'))
268− where showHd (PApp _ (PRef _ n) _) = show n
274+ where showHd (PApp _ (PRef _ n) _) = n
269− showHd (PRef _ n) = show n
275+ showHd (PRef _ n) = n
270− showHd (PApp _ h _) = show h
276+ showHd (PApp _ h _) = showHd h
271− showHd x = show x
277+ showHd x = NErased -- We probably should do something better than this here
272 elab' ina (PAlternative False as)
278 elab' ina (PAlternative False as)
273 = trySeq as
279 = trySeq as
274 where -- if none work, take the error from the first
280 where -- if none work, take the error from the first
@@ -494,6 +500,7 @@ elab ist info pattern opts fn tm
494 where alt t = case getTm t of
500 where alt t = case getTm t of
495 PAlternative False _ -> 5
501 PAlternative False _ -> 5
496 PAlternative True _ -> 1
502 PAlternative True _ -> 1
503+ PTactics _ -> 150
497 PLam _ _ _ -> 2
504 PLam _ _ _ -> 2
498 PRewrite _ _ _ _ -> 3
505 PRewrite _ _ _ _ -> 3
499 _ -> 0
506 _ -> 0
@@ -559,7 +566,7 @@ elab ist info pattern opts fn tm
559 claim tyn RType
566 claim tyn RType
560 valn <- getNameFrom (sMN 0 "rval")
567 valn <- getNameFrom (sMN 0 "rval")
561 claim valn (Var tyn)
568 claim valn (Var tyn)
562− letn <- getNameFrom (sMN 0 "rewrite_rule")
569+ letn <- getNameFrom (sMN 0 "_rewrite_rule")
563 letbind letn (Var tyn) (Var valn)
570 letbind letn (Var tyn) (Var valn)
564 focus valn
571 focus valn
565 elab' ina r
572 elab' ina r
@@ -691,6 +698,9 @@ elab ist info pattern opts fn tm
691 addImpl ist (PApp fc (PRef fc (sUN "Delay"))
698 addImpl ist (PApp fc (PRef fc (sUN "Delay"))
692 [pexp t])
699 [pexp t])
693
700
701+ -- case is tricky enough without implicit coercions! If they are needed,
702+ -- they can go in the branches separately.
703+ insertCoerce ina t@(PCase _ _ _) = return t
694 insertCoerce ina t =
704 insertCoerce ina t =
695 do ty <- goal
705 do ty <- goal
696 -- Check for possible coercions to get to the goal
706 -- Check for possible coercions to get to the goal
@@ -781,8 +791,21 @@ pruneAlt xs = map prune xs
781
791
782-- Rule out alternatives that don't return the same type as the head of the goal
792-- Rule out alternatives that don't return the same type as the head of the goal
783-- (If there are none left as a result, do nothing)
793-- (If there are none left as a result, do nothing)
784−pruneByType :: Term -> Context -> [PTerm] -> [PTerm]
794+pruneByType :: [Name] -> Term -> Context -> [PTerm] -> [PTerm]
795+-- if an alternative has a locally bound name at the head, take it
785−pruneByType (P _ n _) c as
796+pruneByType env t c as
797+ | Just a <- locallyBound as = [a]
798+ where
799+ locallyBound [] = Nothing
800+ locallyBound (t:ts)
801+ | Just n <- getName t,
802+ n `elem` env = Just t
803+ | otherwise = locallyBound ts
804+ getName (PRef _ n) = Just n
805+ getName (PApp _ f _) = getName f
806+ getName _ = Nothing
807+
808+pruneByType env (P _ n _) c as
786-- if the goal type is polymorphic, keep e
809-- if the goal type is polymorphic, keep e
787 | [] <- lookupTy n c = as
810 | [] <- lookupTy n c = as
788 | otherwise
811 | otherwise
@@ -808,7 +831,7 @@ pruneByType (P _ n _) c as
808 _ -> False
831 _ -> False
809 _ -> False
832 _ -> False
810
833
811−pruneByType t _ as = as
834+pruneByType _ t _ as = as
812
835
813findInstances :: IState -> Term -> [Name]
836findInstances :: IState -> Term -> [Name]
814findInstances ist t
837findInstances ist t
@@ -820,9 +843,10 @@ findInstances ist t
820
843
821trivial' ist
844trivial' ist
822 = trivial (elab ist toplevel False [] (sMN 0 "tac")) ist
845 = trivial (elab ist toplevel False [] (sMN 0 "tac")) ist
823−proofSearch' ist top n hints
846+proofSearch' ist rec depth prv top n hints
847+ = do unifyProblems
848+ proofSearch rec prv depth
824− = proofSearch (elab ist toplevel False [] (sMN 0 "tac")) top n hints ist
849+ (elab ist toplevel False [] (sMN 0 "tac")) top n hints ist
825−
826
850
827resolveTC :: Int -> Term -> Name -> IState -> ElabD ()
851resolveTC :: Int -> Term -> Name -> IState -> ElabD ()
828resolveTC = resTC' []
852resolveTC = resTC' []
@@ -967,7 +991,7 @@ runTac autoSolve ist fn tac
967 ns -> return (map (\ (n, a) -> (n, map (const True) a)) ns)
991 ns -> return (map (\ (n, a) -> (n, map (const True) a)) ns)
968 let tacs = map (\ (fn', imps) ->
992 let tacs = map (\ (fn', imps) ->
969 (match_apply (Var fn') (map (\x -> (x, 0)) imps),
993 (match_apply (Var fn') (map (\x -> (x, 0)) imps),
970− show fn')) fnimps
994+ fn')) fnimps
971 tryAll tacs
995 tryAll tacs
972 when autoSolve solveAll
996 when autoSolve solveAll
973 where envArgs n = do e <- get_env
997 where envArgs n = do e <- get_env
@@ -983,7 +1007,7 @@ runTac autoSolve ist fn tac
983 ns -> return (map (\ (n, a) -> (n, map isImp a)) ns)
1007 ns -> return (map (\ (n, a) -> (n, map isImp a)) ns)
984 let tacs = map (\ (fn', imps) ->
1008 let tacs = map (\ (fn', imps) ->
985 (apply (Var fn') (map (\x -> (x, 0)) imps),
1009 (apply (Var fn') (map (\x -> (x, 0)) imps),
986− show fn')) fnimps
1010+ fn')) fnimps
987 tryAll tacs
1011 tryAll tacs
988 when autoSolve solveAll
1012 when autoSolve solveAll
989 where isImp (PImp _ _ _ _ _) = True
1013 where isImp (PImp _ _ _ _ _) = True
@@ -995,6 +1019,8 @@ runTac autoSolve ist fn tac
995 _ -> return []
1019 _ -> return []
996 runT (Refine fn imps) = do ns <- apply (Var fn) (map (\x -> (x,0)) imps)
1020 runT (Refine fn imps) = do ns <- apply (Var fn) (map (\x -> (x,0)) imps)
997 when autoSolve solveAll
1021 when autoSolve solveAll
1022+ runT DoUnify = do unify_all
1023+ when autoSolve solveAll
998 runT (Equiv tm) -- let bind tm, then
1024 runT (Equiv tm) -- let bind tm, then
999 = do attack
1025 = do attack
1000 tyn <- getNameFrom (sMN 0 "ety")
1026 tyn <- getNameFrom (sMN 0 "ety")
@@ -1050,8 +1076,9 @@ runTac autoSolve ist fn tac
1050 runT Compute = compute
1076 runT Compute = compute
1051 runT Trivial = do trivial' ist; when autoSolve solveAll
1077 runT Trivial = do trivial' ist; when autoSolve solveAll
1052 runT TCInstance = runT (Exact (PResolveTC emptyFC))
1078 runT TCInstance = runT (Exact (PResolveTC emptyFC))
1053− runT (ProofSearch top hints)
1079+ runT (ProofSearch rec prover depth top hints)
1080+ = do proofSearch' ist rec depth prover top fn hints
1054− = do proofSearch' ist top fn hints; when autoSolve solveAll
1081+ when autoSolve solveAll
1055 runT (Focus n) = focus n
1082 runT (Focus n) = focus n
1056 runT Solve = solve
1083 runT Solve = solve
1057 runT (Try l r) = do try' (runT l) (runT r) True
1084 runT (Try l r) = do try' (runT l) (runT r) True
@@ -1178,14 +1205,16 @@ reify _ t = fail ("Unknown tactic " ++ show t)
1178
1205
1179reifyApp :: IState -> Name -> [Term] -> ElabD PTactic
1206reifyApp :: IState -> Name -> [Term] -> ElabD PTactic
1180reifyApp ist t [l, r] | t == reflm "Try" = liftM2 Try (reify ist l) (reify ist r)
1207reifyApp ist t [l, r] | t == reflm "Try" = liftM2 Try (reify ist l) (reify ist r)
1208+reifyApp _ t [Constant (I i)]
1209+ | t == reflm "Search" = return (ProofSearch True True i Nothing [])
1181reifyApp _ t [x]
1210reifyApp _ t [x]
1182 | t == reflm "Refine" = do n <- reifyTTName x
1211 | t == reflm "Refine" = do n <- reifyTTName x
1183 return $ Refine n []
1212 return $ Refine n []
1184reifyApp ist t [l, r] | t == reflm "Seq" = liftM2 TSeq (reify ist l) (reify ist r)
1213reifyApp ist t [l, r] | t == reflm "Seq" = liftM2 TSeq (reify ist l) (reify ist r)
1185reifyApp ist t [Constant (Str n), x]
1214reifyApp ist t [Constant (Str n), x]
1186 | t == reflm "GoalType" = liftM (GoalType n) (reify ist x)
1215 | t == reflm "GoalType" = liftM (GoalType n) (reify ist x)
1187−reifyApp _ t [Constant (Str n)]
1216+reifyApp _ t [n] | t == reflm "Intro" = liftM (Intro . (:[])) (reifyTTName n)
1188− | t == reflm "Intro" = return $ Intro [sUN n]
1217+reifyApp _ t [n] | t == reflm "Induction" = liftM Induction (reifyTTName n)
1189reifyApp ist t [t']
1218reifyApp ist t [t']
1190 | t == reflm "ApplyTactic" = liftM (ApplyTactic . delab ist) (reifyTT t')
1219 | t == reflm "ApplyTactic" = liftM (ApplyTactic . delab ist) (reifyTT t')
1191reifyApp ist t [t']
1220reifyApp ist t [t']
@@ -1580,8 +1609,8 @@ reflectErr (NotInjective t1 t2 t3) =
1580 ]
1609 ]
1581reflectErr (CantResolve t) = raw_apply (Var $ reflErrName "CantResolve") [reflect t]
1610reflectErr (CantResolve t) = raw_apply (Var $ reflErrName "CantResolve") [reflect t]
1582reflectErr (CantResolveAlts ss) =
1611reflectErr (CantResolveAlts ss) =
1583− raw_apply (Var $ reflErrName "CantResolve")
1612+ raw_apply (Var $ reflErrName "CantResolveAlts")
1584− [rawList (Var $ (sUN "String")) (map (RConstant . Str) ss)]
1613+ [rawList (Var $ (sUN "String")) (map Var ss)]
1585reflectErr (IncompleteTerm t) = raw_apply (Var $ reflErrName "IncompleteTerm") [reflect t]
1614reflectErr (IncompleteTerm t) = raw_apply (Var $ reflErrName "IncompleteTerm") [reflect t]
1586reflectErr UniverseError = Var $ reflErrName "UniverseError"
1615reflectErr UniverseError = Var $ reflErrName "UniverseError"
1587reflectErr ProgramLineComment = Var $ reflErrName "ProgramLineComment"
1616reflectErr ProgramLineComment = Var $ reflErrName "ProgramLineComment"
@@ -1625,6 +1654,8 @@ withErrorReflection x = idrisCatch x (\ e -> handle e >>= ierror)
1625 then handle err
1654 then handle err
1626 else applyHandlers err hs
1655 else applyHandlers err hs
1627 return (ElaboratingArg f a prev err')
1656 return (ElaboratingArg f a prev err')
1657+ -- ProofSearchFail is an internal detail - so don't expose it
1658+ handle (ProofSearchFail e) = handle e
1628 -- TODO: argument-specific error handlers go here for ElaboratingArg
1659 -- TODO: argument-specific error handlers go here for ElaboratingArg
1629 handle e = do ist <- getIState
1660 handle e = do ist <- getIState
1630 logLvl 2 "Starting error reflection"
1661 logLvl 2 "Starting error reflection"
src/Idris/Erasure.hs+27−19
@@ -3,6 +3,7 @@
3module Idris.Erasure (performUsageAnalysis, mkFieldName) where
3module Idris.Erasure (performUsageAnalysis, mkFieldName) where
4
4
5import Idris.AbsSyntax
5import Idris.AbsSyntax
6+import Idris.ASTUtils
6import Idris.Core.CaseTree
7import Idris.Core.CaseTree
7import Idris.Core.TT
8import Idris.Core.TT
8import Idris.Core.Evaluate
9import Idris.Core.Evaluate
@@ -12,6 +13,9 @@ import Idris.Error
12import Debug.Trace
13import Debug.Trace
13import System.IO.Unsafe
14import System.IO.Unsafe
14
15
16+import Control.Category
17+import Prelude hiding (id, (.))
18+
15import Control.Arrow
19import Control.Arrow
16import Control.Applicative
20import Control.Applicative
17import Control.Monad.State
21import Control.Monad.State
@@ -97,7 +101,7 @@ performUsageAnalysis = do
97 $ ifail ("reachable postulates:\n" ++ intercalate "\n" [" " ++ show n | n <- S.toList reachablePostulates])
101 $ ifail ("reachable postulates:\n" ++ intercalate "\n" [" " ++ show n | n <- S.toList reachablePostulates])
98
102
99 -- Store the usage info in the internal state.
103 -- Store the usage info in the internal state.
100− mapM_ (storeUsage cg) usage
104+ mapM_ storeUsage usage
101
105
102 return $ S.toList reachableNames
106 return $ S.toList reachableNames
103 where
107 where
@@ -105,7 +109,7 @@ performUsageAnalysis = do
105 getMainName ist = case lookupCtxtName n (idris_implicits ist) of
109 getMainName ist = case lookupCtxtName n (idris_implicits ist) of
106 [(n', _)] -> Right n'
110 [(n', _)] -> Right n'
107 [] -> Left (NoSuchVariable n)
111 [] -> Left (NoSuchVariable n)
108− more -> Left (CantResolveAlts (map (show . fst) more))
112+ more -> Left (CantResolveAlts (map fst more))
109 where
113 where
110 n = sNS (sUN "main") ["Main"]
114 n = sNS (sUN "main") ["Main"]
111
115
@@ -124,13 +128,8 @@ performUsageAnalysis = do
124 | S.null rs = show i
128 | S.null rs = show i
125 | otherwise = show i ++ " from " ++ intercalate ", " (map show $ S.toList rs)
129 | otherwise = show i ++ " from " ++ intercalate ", " (map show $ S.toList rs)
126
130
127− storeUsage :: Ctxt CGInfo -> (Name, IntMap (Set Reason)) -> Idris ()
131+ storeUsage :: (Name, IntMap (Set Reason)) -> Idris ()
128− storeUsage cg (n, args)
132+ storeUsage (n, args) = fputState (cg_usedpos . ist_callgraph n) flat
129− | Just x <- lookupCtxtExact n cg
130− = addToCG n x{ usedpos = flat } -- functions
131−
132− | otherwise
133− = addToCG n (CGInfo [] [] [] [] flat) -- data ctors
134 where
133 where
135 flat = [(i, S.toList rs) | (i,rs) <- IM.toList args]
134 flat = [(i, S.toList rs) | (i,rs) <- IM.toList args]
136
135
@@ -204,6 +203,7 @@ buildDepMap ci ctx mainName = addPostulates $ dfs S.empty M.empty [mainName]
204 -- among Idris.Primitives.primitives
203 -- among Idris.Primitives.primitives
205 , mn "__MkPair" [2,3]
204 , mn "__MkPair" [2,3]
206 , it "prim_fork" [0]
205 , it "prim_fork" [0]
206+ , it "unsafePerformPrimIO" [1]
207
207
208 -- believe_me is a primitive but it only uses its third argument
208 -- believe_me is a primitive but it only uses its third argument
209 -- it is special-cased in usedNames above
209 -- it is special-cased in usedNames above
@@ -294,7 +294,6 @@ buildDepMap ci ctx mainName = addPostulates $ dfs S.empty M.empty [mainName]
294 -- that the result of this function is used at all
294 -- that the result of this function is used at all
295 = addTagDep $ unionMap (getDepsAlt fn es vs casedVar) alts -- coming from the whole subtree
295 = addTagDep $ unionMap (getDepsAlt fn es vs casedVar) alts -- coming from the whole subtree
296 where
296 where
297−
298 addTagDep = case alts of
297 addTagDep = case alts of
299 [_] -> id -- single branch, tag not used
298 [_] -> id -- single branch, tag not used
300 _ -> M.insertWith (M.unionWith S.union) (S.singleton (fn, Result)) (viDeps casedVar)
299 _ -> M.insertWith (M.unionWith S.union) (S.singleton (fn, Result)) (viDeps casedVar)
@@ -329,11 +328,15 @@ buildDepMap ci ctx mainName = addPostulates $ dfs S.empty M.empty [mainName]
329 | otherwise = \j -> Nothing
328 | otherwise = \j -> Nothing
330
329
331 -- Named variables -> DeBruijn variables -> Conds/guards -> Term -> Deps
330 -- Named variables -> DeBruijn variables -> Conds/guards -> Term -> Deps
332− getDepsTerm :: Vars -> [Cond -> Deps] -> Cond -> Term -> Deps
331+ getDepsTerm :: Vars -> [(Name, Cond -> Deps)] -> Cond -> Term -> Deps
333
332
334 -- named variables introduce dependencies as described in `vs'
333 -- named variables introduce dependencies as described in `vs'
335 getDepsTerm vs bs cd (P _ n _)
334 getDepsTerm vs bs cd (P _ n _)
335+ -- de bruijns (lambda-bound, let-bound vars)
336+ | Just deps <- lookup n bs
337+ = deps cd
338+
336− -- local variables
339+ -- ctor-bound/arg-bound variables
337 | Just var <- M.lookup n vs
340 | Just var <- M.lookup n vs
338 = M.singleton cd (viDeps var)
341 = M.singleton cd (viDeps var)
339
342
@@ -348,18 +351,18 @@ buildDepMap ci ctx mainName = addPostulates $ dfs S.empty M.empty [mainName]
348 specialMNs = map (sMN 0 . ("__" ++)) $ words "Unit True False II"
351 specialMNs = map (sMN 0 . ("__" ++)) $ words "Unit True False II"
349
352
350 -- dependencies of de bruijn variables are described in `bs'
353 -- dependencies of de bruijn variables are described in `bs'
351− getDepsTerm vs bs cd (V i) = (bs !! i) cd
354+ getDepsTerm vs bs cd (V i) = snd (bs !! i) cd
352
355
353 getDepsTerm vs bs cd (Bind n bdr t)
356 getDepsTerm vs bs cd (Bind n bdr t)
354 -- here we just push IM.empty on the de bruijn stack
357 -- here we just push IM.empty on the de bruijn stack
355 -- the args will be marked as used at the usage site
358 -- the args will be marked as used at the usage site
356− | Lam ty <- bdr = getDepsTerm vs (const M.empty : bs) cd t
359+ | Lam ty <- bdr = getDepsTerm vs ((n, const M.empty) : bs) cd t
357− | Pi ty <- bdr = getDepsTerm vs (const M.empty : bs) cd t
360+ | Pi ty <- bdr = getDepsTerm vs ((n, const M.empty) : bs) cd t
358
361
359 -- let-bound variables can get partially evaluated
362 -- let-bound variables can get partially evaluated
360 -- it is sufficient just to plug the Cond in when the bound names are used
363 -- it is sufficient just to plug the Cond in when the bound names are used
361− | Let ty t <- bdr = getDepsTerm vs (var t : bs) cd t
364+ | Let ty t <- bdr = getDepsTerm vs ((n, var t) : bs) cd t
362− | NLet ty t <- bdr = getDepsTerm vs (var t : bs) cd t
365+ | NLet ty t <- bdr = getDepsTerm vs ((n, var t) : bs) cd t
363 where
366 where
364 var t cd = getDepsTerm vs bs cd t
367 var t cd = getDepsTerm vs bs cd t
365
368
@@ -386,6 +389,10 @@ buildDepMap ci ctx mainName = addPostulates $ dfs S.empty M.empty [mainName]
386 -- a bound variable might draw in additional dependencies,
389 -- a bound variable might draw in additional dependencies,
387 -- think: f x = x 0 <-- here, `x' _is_ used
390 -- think: f x = x 0 <-- here, `x' _is_ used
388 P _ n _
391 P _ n _
392+ -- debruijn-bound name
393+ | Just deps <- lookup n bs
394+ -> deps cd `union` unconditionalDeps args
395+
389 -- local name that refers to a method
396 -- local name that refers to a method
390 | Just var <- M.lookup n vs
397 | Just var <- M.lookup n vs
391 , Just meth <- viMethod var
398 , Just meth <- viMethod var
@@ -402,7 +409,7 @@ buildDepMap ci ctx mainName = addPostulates $ dfs S.empty M.empty [mainName]
402 -> conditionalDeps n args
409 -> conditionalDeps n args
403
410
404 -- TODO: could we somehow infer how bound variables use their arguments?
411 -- TODO: could we somehow infer how bound variables use their arguments?
405− V i -> M.unionWith (M.unionWith S.union) ((bs !! i) cd) (unconditionalDeps args)
412+ V i -> snd (bs !! i) cd `union` unconditionalDeps args
406
413
407 -- we interpret applied lambdas as lets in order to reuse code here
414 -- we interpret applied lambdas as lets in order to reuse code here
408 Bind n (Lam ty) t -> getDepsTerm vs bs cd (lamToLet [] app)
415 Bind n (Lam ty) t -> getDepsTerm vs bs cd (lamToLet [] app)
@@ -418,6 +425,7 @@ buildDepMap ci ctx mainName = addPostulates $ dfs S.empty M.empty [mainName]
418
425
419 _ -> error $ "cannot analyse application of " ++ show fun ++ " to " ++ show args
426 _ -> error $ "cannot analyse application of " ++ show fun ++ " to " ++ show args
420 where
427 where
428+ union = M.unionWith $ M.unionWith S.union
421 ins = M.insertWith (M.unionWith S.union) cd
429 ins = M.insertWith (M.unionWith S.union) cd
422
430
423 unconditionalDeps :: [Term] -> Deps
431 unconditionalDeps :: [Term] -> Deps
@@ -441,7 +449,7 @@ buildDepMap ci ctx mainName = addPostulates $ dfs S.empty M.empty [mainName]
441 , viMethod = Nothing
449 , viMethod = Nothing
442 }) | (v, i) <- zip args [0..]]
450 }) | (v, i) <- zip args [0..]]
443 deps i = M.singleton (metameth, Arg i) S.empty
451 deps i = M.singleton (metameth, Arg i) S.empty
444− bruijns = reverse [\cd -> M.singleton cd (deps i) | i <- [0 .. length args - 1]]
452+ bruijns = reverse [(n, \cd -> M.singleton cd (deps i)) | (i, n) <- zip [0..] args]
445 cond = S.singleton (metameth, Result)
453 cond = S.singleton (metameth, Result)
446 metameth = mkFieldName ctorName methNo
454 metameth = mkFieldName ctorName methNo
447 (args, body) = unfoldLams t
455 (args, body) = unfoldLams t
src/Idris/Error.hs+4−2
@@ -43,11 +43,13 @@ idrisCatch = catchError
43setAndReport :: Err -> Idris ()
43setAndReport :: Err -> Idris ()
44setAndReport e = do ist <- getIState
44setAndReport e = do ist <- getIState
45 let h = idris_outh ist
45 let h = idris_outh ist
46− case e of
46+ case (unwrap e) of
47 At fc e -> do setErrSpan fc
47 At fc e -> do setErrSpan fc
48 ihWarn h fc $ pprintErr ist e
48 ihWarn h fc $ pprintErr ist e
49 _ -> do setErrSpan (getErrSpan e)
49 _ -> do setErrSpan (getErrSpan e)
50− ihputStrLn h $ pshow ist e
50+ ihWarn h emptyFC $ pprintErr ist e
51+ where unwrap (ProofSearchFail e) = e -- remove bookkeeping constructor
52+ unwrap e = e
51
53
52ifail :: String -> Idris a
54ifail :: String -> Idris a
53ifail = throwError . Msg
55ifail = throwError . Msg
src/Idris/Help.hs+11−6
@@ -4,6 +4,7 @@ data CmdArg = ExprArg -- ^ The command takes an expression
4 | NameArg -- ^ The command takes a name
4 | NameArg -- ^ The command takes a name
5 | FileArg -- ^ The command takes a file
5 | FileArg -- ^ The command takes a file
6 | ModuleArg -- ^ The command takes a module name
6 | ModuleArg -- ^ The command takes a module name
7+ | NamespaceArg -- ^ The command takes a namespace name
7 | OptionArg -- ^ The command takes an option
8 | OptionArg -- ^ The command takes an option
8 | MetaVarArg -- ^ The command takes a metavariable
9 | MetaVarArg -- ^ The command takes a metavariable
9 | ColourArg -- ^ The command is the colour-setting command
10 | ColourArg -- ^ The command is the colour-setting command
@@ -16,6 +17,7 @@ instance Show CmdArg where
16 show NameArg = "<name>"
17 show NameArg = "<name>"
17 show FileArg = "<filename>"
18 show FileArg = "<filename>"
18 show ModuleArg = "<module>"
19 show ModuleArg = "<module>"
20+ show NamespaceArg = "<namespace>"
19 show OptionArg = "<option>"
21 show OptionArg = "<option>"
20 show MetaVarArg = "<metavar>"
22 show MetaVarArg = "<metavar>"
21 show ColourArg = "<option>"
23 show ColourArg = "<option>"
@@ -29,23 +31,25 @@ help =
29 ([":t"], ExprArg, "Check the type of an expression"),
31 ([":t"], ExprArg, "Check the type of an expression"),
30 ([":miss", ":missing"], NameArg, "Show missing clauses"),
32 ([":miss", ":missing"], NameArg, "Show missing clauses"),
31 ([":doc"], NameArg, "Show internal documentation"),
33 ([":doc"], NameArg, "Show internal documentation"),
34+ ([":mkdoc"], NamespaceArg, "Generate IdrisDoc for namespace(s) and dependencies"),
32 ([":apropos"], NoArg, "Search names, types, and documentation"),
35 ([":apropos"], NoArg, "Search names, types, and documentation"),
33− ([":i", ":info"], NameArg, "Display information about a type class"),
36+ ([":search", ":s"], ExprArg, "Search for values by type"),
37+ ([":whocalls", ":wc"], NameArg, "List the callers of some name"),
38+ ([":callswho", ":cw"], NameArg, "List the callees of some name"),
34 ([":total"], NameArg, "Check the totality of a name"),
39 ([":total"], NameArg, "Check the totality of a name"),
35 ([":r",":reload"], NoArg, "Reload current file"),
40 ([":r",":reload"], NoArg, "Reload current file"),
36 ([":l",":load"], FileArg, "Load a new file"),
41 ([":l",":load"], FileArg, "Load a new file"),
37 ([":cd"], FileArg, "Change working directory"),
42 ([":cd"], FileArg, "Change working directory"),
38− ([":m",":module"], ModuleArg, "Import an extra module"), -- NOTE: dragons
43+ ([":module"], ModuleArg, "Import an extra module"), -- NOTE: dragons
39 ([":e",":edit"], NoArg, "Edit current file using $EDITOR or $VISUAL"),
44 ([":e",":edit"], NoArg, "Edit current file using $EDITOR or $VISUAL"),
40− ([":m",":metavars"], MetaVarArg, "Show remaining proof obligations (metavariables)"),
45+ ([":m",":metavars"], NoArg, "Show remaining proof obligations (metavariables)"),
41 ([":p",":prove"], MetaVarArg, "Prove a metavariable"),
46 ([":p",":prove"], MetaVarArg, "Prove a metavariable"),
42 ([":a",":addproof"], NameArg, "Add proof to source file"),
47 ([":a",":addproof"], NameArg, "Add proof to source file"),
43 ([":rmproof"], NameArg, "Remove proof from proof stack"),
48 ([":rmproof"], NameArg, "Remove proof from proof stack"),
44 ([":showproof"], NameArg, "Show proof"),
49 ([":showproof"], NameArg, "Show proof"),
45 ([":proofs"], NoArg, "Show available proofs"),
50 ([":proofs"], NoArg, "Show available proofs"),
46 ([":x"], ExprArg, "Execute IO actions resulting from an expression using the interpreter"),
51 ([":x"], ExprArg, "Execute IO actions resulting from an expression using the interpreter"),
47− ([":c",":compile"], FileArg, "Compile to an executable <filename>"),
52+ ([":c",":compile"], FileArg, "Compile to an executable [codegen] <filename>"),
48− ([":js", ":javascript"], FileArg, "Compile to JavaScript <filename>"),
49 ([":exec",":execute"], NoArg, "Compile to an executable and run"),
53 ([":exec",":execute"], NoArg, "Compile to an executable and run"),
50 ([":dynamic"], FileArg, "Dynamically load a C library (similar to %dynamic)"),
54 ([":dynamic"], FileArg, "Dynamically load a C library (similar to %dynamic)"),
51 ([":dynamic"], NoArg, "List dynamically loaded C libraries"),
55 ([":dynamic"], NoArg, "List dynamically loaded C libraries"),
@@ -54,7 +58,8 @@ help =
54 ([":unset"], OptionArg, "Unset an option"),
58 ([":unset"], OptionArg, "Unset an option"),
55 ([":colour", ":color"], ColourArg, "Turn REPL colours on or off; set a specific colour"),
59 ([":colour", ":color"], ColourArg, "Turn REPL colours on or off; set a specific colour"),
56 ([":consolewidth"], ConsoleWidthArg, "Set the width of the console"),
60 ([":consolewidth"], ConsoleWidthArg, "Set the width of the console"),
57− ([":q",":quit"], NoArg, "Exit the Idris system")
61+ ([":q",":quit"], NoArg, "Exit the Idris system"),
62+ ([":w", ":warranty"], NoArg, "Displays warranty information")
58 ]
63 ]
59
64
60-- | Use these for completion, but don't show them in :help
65-- | Use these for completion, but don't show them in :help
src/Idris/IBC.hs+61−23
@@ -30,7 +30,7 @@ import Codec.Compression.Zlib (compress)
30import Util.Zlib (decompressEither)
30import Util.Zlib (decompressEither)
31
31
32ibcVersion :: Word8
32ibcVersion :: Word8
33−ibcVersion = 67
33+ibcVersion = 74
34
34
35data IBCFile = IBCFile { ver :: Word8,
35data IBCFile = IBCFile { ver :: Word8,
36 sourcefile :: FilePath,
36 sourcefile :: FilePath,
@@ -53,6 +53,7 @@ data IBCFile = IBCFile { ver :: Word8,
53 ibc_hdrs :: [(Codegen, String)],
53 ibc_hdrs :: [(Codegen, String)],
54 ibc_access :: [(Name, Accessibility)],
54 ibc_access :: [(Name, Accessibility)],
55 ibc_total :: [(Name, Totality)],
55 ibc_total :: [(Name, Totality)],
56+ ibc_totcheckfail :: [(FC, String)],
56 ibc_flags :: [(Name, [FnOpt])],
57 ibc_flags :: [(Name, [FnOpt])],
57 ibc_cg :: [(Name, CGInfo)],
58 ibc_cg :: [(Name, CGInfo)],
58 ibc_defs :: [(Name, Def)],
59 ibc_defs :: [(Name, Def)],
@@ -67,7 +68,8 @@ data IBCFile = IBCFile { ver :: Word8,
67 ibc_function_errorhandlers :: [(Name, Name, Name)], -- fn, arg, handler
68 ibc_function_errorhandlers :: [(Name, Name, Name)], -- fn, arg, handler
68 ibc_metavars :: [(Name, (Maybe Name, Int, Bool))],
69 ibc_metavars :: [(Name, (Maybe Name, Int, Bool))],
69 ibc_patdefs :: [(Name, ([([Name], Term, Term)], [PTerm]))],
70 ibc_patdefs :: [(Name, ([([Name], Term, Term)], [PTerm]))],
70− ibc_postulates :: [Name]
71+ ibc_postulates :: [Name],
72+ ibc_parsedSpan :: Maybe FC
71 }
73 }
72 deriving Show
74 deriving Show
73{-!
75{-!
@@ -75,7 +77,7 @@ deriving instance Binary IBCFile
75!-}
77!-}
76
78
77initIBC :: IBCFile
79initIBC :: IBCFile
78−initIBC = IBCFile ibcVersion "" [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] []
80+initIBC = IBCFile ibcVersion "" [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] Nothing
79
81
80loadIBC :: FilePath -> Idris ()
82loadIBC :: FilePath -> Idris ()
81loadIBC fp = do imps <- getImported
83loadIBC fp = do imps <- getImported
@@ -234,11 +236,13 @@ ibc i (IBCMetaInformation n m) f = return f { ibc_metainformation = (n,m) : ibc_
234ibc i (IBCErrorHandler n) f = return f { ibc_errorhandlers = n : ibc_errorhandlers f }
236ibc i (IBCErrorHandler n) f = return f { ibc_errorhandlers = n : ibc_errorhandlers f }
235ibc i (IBCFunctionErrorHandler fn a n) f =
237ibc i (IBCFunctionErrorHandler fn a n) f =
236 return f { ibc_function_errorhandlers = (fn, a, n) : ibc_function_errorhandlers f }
238 return f { ibc_function_errorhandlers = (fn, a, n) : ibc_function_errorhandlers f }
237−ibc i (IBCMetavar n) f =
239+ibc i (IBCMetavar n) f =
238 case lookup n (idris_metavars i) of
240 case lookup n (idris_metavars i) of
239 Nothing -> return f
241 Nothing -> return f
240 Just t -> return f { ibc_metavars = (n, t) : ibc_metavars f }
242 Just t -> return f { ibc_metavars = (n, t) : ibc_metavars f }
241ibc i (IBCPostulate n) f = return f { ibc_postulates = n : ibc_postulates f }
243ibc i (IBCPostulate n) f = return f { ibc_postulates = n : ibc_postulates f }
244+ibc i (IBCTotCheckErr fc err) f = return f { ibc_totcheckfail = (fc, err) : ibc_totcheckfail f }
245+ibc i (IBCParsedRegion fc) f = return f { ibc_parsedSpan = Just fc }
242
246
243process :: IBCFile -> FilePath -> Idris ()
247process :: IBCFile -> FilePath -> Idris ()
244process i fn
248process i fn
@@ -246,7 +250,7 @@ process i fn
246 ifail "Incorrect ibc version --- please rebuild"
250 ifail "Incorrect ibc version --- please rebuild"
247 | otherwise =
251 | otherwise =
248 do srcok <- runIO $ doesFileExist (sourcefile i)
252 do srcok <- runIO $ doesFileExist (sourcefile i)
249− when srcok $ runIO $ timestampOlder (sourcefile i) fn
253+ when srcok $ timestampOlder (sourcefile i) fn
250 v <- verbose
254 v <- verbose
251 quiet <- getQuiet
255 quiet <- getQuiet
252-- when (v && srcok && not quiet) $ iputStrLn $ "Skipping " ++ sourcefile i
256-- when (v && srcok && not quiet) $ iputStrLn $ "Skipping " ++ sourcefile i
@@ -270,6 +274,7 @@ process i fn
270 pPatdefs (ibc_patdefs i)
274 pPatdefs (ibc_patdefs i)
271 pAccess (ibc_access i)
275 pAccess (ibc_access i)
272 pTotal (ibc_total i)
276 pTotal (ibc_total i)
277+ pTotCheckErr (ibc_totcheckfail i)
273 pCG (ibc_cg i)
278 pCG (ibc_cg i)
274 pDocs (ibc_docstrings i)
279 pDocs (ibc_docstrings i)
275 pCoercions (ibc_coercions i)
280 pCoercions (ibc_coercions i)
@@ -282,12 +287,13 @@ process i fn
282 pFunctionErrorHandlers (ibc_function_errorhandlers i)
287 pFunctionErrorHandlers (ibc_function_errorhandlers i)
283 pMetavars (ibc_metavars i)
288 pMetavars (ibc_metavars i)
284 pPostulates (ibc_postulates i)
289 pPostulates (ibc_postulates i)
290+ pParsedSpan (ibc_parsedSpan i)
285
291
286−timestampOlder :: FilePath -> FilePath -> IO ()
292+timestampOlder :: FilePath -> FilePath -> Idris ()
287−timestampOlder src ibc = do srct <- getModificationTime src
293+timestampOlder src ibc = do srct <- runIO $ getModificationTime src
288− ibct <- getModificationTime ibc
294+ ibct <- runIO $ getModificationTime ibc
289 if (srct > ibct)
295 if (srct > ibct)
290− then fail "Needs reloading"
296+ then ifail "Needs reloading"
291 else return ()
297 else return ()
292
298
293pPostulates :: [Name] -> Idris ()
299pPostulates :: [Name] -> Idris ()
@@ -295,12 +301,16 @@ pPostulates ns = do
295 i <- getIState
301 i <- getIState
296 putIState i{ idris_postulates = idris_postulates i `S.union` S.fromList ns }
302 putIState i{ idris_postulates = idris_postulates i `S.union` S.fromList ns }
297
303
304+pParsedSpan :: Maybe FC -> Idris ()
305+pParsedSpan fc = do ist <- getIState
306+ putIState ist { idris_parsedSpan = fc }
307+
298pImports :: [FilePath] -> Idris ()
308pImports :: [FilePath] -> Idris ()
299pImports fs
309pImports fs
300 = do mapM_ (\f -> do i <- getIState
310 = do mapM_ (\f -> do i <- getIState
301 ibcsd <- valIBCSubDir i
311 ibcsd <- valIBCSubDir i
302 ids <- allImportDirs
312 ids <- allImportDirs
303− fp <- runIO $ findImport ids ibcsd f
313+ fp <- findImport ids ibcsd f
304 if (f `elem` imported i)
314 if (f `elem` imported i)
305 then iLOG $ "Already read " ++ f
315 then iLOG $ "Already read " ++ f
306 else do putIState (i { imported = f : imported i })
316 else do putIState (i { imported = f : imported i })
@@ -454,6 +464,10 @@ pTotal ds = mapM_ (\ (n, a) ->
454 putIState (i { tt_ctxt = setTotal n a (tt_ctxt i) }))
464 putIState (i { tt_ctxt = setTotal n a (tt_ctxt i) }))
455 ds
465 ds
456
466
467+pTotCheckErr :: [(FC, String)] -> Idris ()
468+pTotCheckErr es = do ist <- getIState
469+ putIState ist { idris_totcheckfail = idris_totcheckfail ist ++ es }
470+
457pCG :: [(Name, CGInfo)] -> Idris ()
471pCG :: [(Name, CGInfo)] -> Idris ()
458pCG ds = mapM_ (\ (n, a) -> addToCG n a) ds
472pCG ds = mapM_ (\ (n, a) -> addToCG n a) ds
459
473
@@ -1161,7 +1175,7 @@ instance Binary MetaInformation where
1161 return (DataMI x1)
1175 return (DataMI x1)
1162
1176
1163instance Binary IBCFile where
1177instance Binary IBCFile where
1164− put x@(IBCFile x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 x19 x20 x21 x22 x23 x24 x25 x26 x27 x28 x29 x30 x31 x32 x33 x34 x35 x36)
1178+ put x@(IBCFile x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 x19 x20 x21 x22 x23 x24 x25 x26 x27 x28 x29 x30 x31 x32 x33 x34 x35 x36 x37 x38)
1165 = {-# SCC "putIBCFile" #-}
1179 = {-# SCC "putIBCFile" #-}
1166 do put x1
1180 do put x1
1167 put x2
1181 put x2
@@ -1199,6 +1213,8 @@ instance Binary IBCFile where
1199 put x34
1213 put x34
1200 put x35
1214 put x35
1201 put x36
1215 put x36
1216+ put x37
1217+ put x38
1202
1218
1203 get
1219 get
1204 = do x1 <- get
1220 = do x1 <- get
@@ -1238,7 +1254,9 @@ instance Binary IBCFile where
1238 x34 <- get
1254 x34 <- get
1239 x35 <- get
1255 x35 <- get
1240 x36 <- get
1256 x36 <- get
1257+ x37 <- get
1258+ x38 <- get
1241− return (IBCFile x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 x19 x20 x21 x22 x23 x24 x25 x26 x27 x28 x29 x30 x31 x32 x33 x34 x35 x36)
1259+ return (IBCFile x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 x19 x20 x21 x22 x23 x24 x25 x26 x27 x28 x29 x30 x31 x32 x33 x34 x35 x36 x37 x38)
1242 else return (initIBC { ver = x1 })
1260 else return (initIBC { ver = x1 })
1243
1261
1244instance Binary DataOpt where
1262instance Binary DataOpt where
@@ -1425,7 +1443,7 @@ instance (Binary t) => Binary (PDecl' t) where
1425 PNamespace x1 x2 -> do putWord8 5
1443 PNamespace x1 x2 -> do putWord8 5
1426 put x1
1444 put x1
1427 put x2
1445 put x2
1428− PRecord x1 x2 x3 x4 x5 x6 x7 x8 ->
1446+ PRecord x1 x2 x3 x4 x5 x6 x7 x8 x9 ->
1429 do putWord8 6
1447 do putWord8 6
1430 put x1
1448 put x1
1431 put x2
1449 put x2
@@ -1435,7 +1453,8 @@ instance (Binary t) => Binary (PDecl' t) where
1435 put x6
1453 put x6
1436 put x7
1454 put x7
1437 put x8
1455 put x8
1456+ put x9
1438− PClass x1 x2 x3 x4 x5 x6 x7
1457+ PClass x1 x2 x3 x4 x5 x6 x7 x8
1439 -> do putWord8 7
1458 -> do putWord8 7
1440 put x1
1459 put x1
1441 put x2
1460 put x2
@@ -1444,6 +1463,7 @@ instance (Binary t) => Binary (PDecl' t) where
1444 put x5
1463 put x5
1445 put x6
1464 put x6
1446 put x7
1465 put x7
1466+ put x8
1447 PInstance x1 x2 x3 x4 x5 x6 x7 x8 -> do putWord8 8
1467 PInstance x1 x2 x3 x4 x5 x6 x7 x8 -> do putWord8 8
1448 put x1
1468 put x1
1449 put x2
1469 put x2
@@ -1513,7 +1533,8 @@ instance (Binary t) => Binary (PDecl' t) where
1513 x6 <- get
1533 x6 <- get
1514 x7 <- get
1534 x7 <- get
1515 x8 <- get
1535 x8 <- get
1536+ x9 <- get
1516− return (PRecord x1 x2 x3 x4 x5 x6 x7 x8)
1537+ return (PRecord x1 x2 x3 x4 x5 x6 x7 x8 x9)
1517 7 -> do x1 <- get
1538 7 -> do x1 <- get
1518 x2 <- get
1539 x2 <- get
1519 x3 <- get
1540 x3 <- get
@@ -1521,7 +1542,8 @@ instance (Binary t) => Binary (PDecl' t) where
1521 x5 <- get
1542 x5 <- get
1522 x6 <- get
1543 x6 <- get
1523 x7 <- get
1544 x7 <- get
1545+ x8 <- get
1524− return (PClass x1 x2 x3 x4 x5 x6 x7)
1546+ return (PClass x1 x2 x3 x4 x5 x6 x7 x8)
1525 8 -> do x1 <- get
1547 8 -> do x1 <- get
1526 x2 <- get
1548 x2 <- get
1527 x3 <- get
1549 x3 <- get
@@ -1560,7 +1582,7 @@ instance Binary Using where
1560 1 -> do x1 <- get; x2 <- get; return (UConstraint x1 x2)
1582 1 -> do x1 <- get; x2 <- get; return (UConstraint x1 x2)
1561
1583
1562instance Binary SyntaxInfo where
1584instance Binary SyntaxInfo where
1563− put (Syn x1 x2 x3 x4 _ x5 x6 x7)
1585+ put (Syn x1 x2 x3 x4 _ x5 x6 _ _ x7)
1564 = do put x1
1586 = do put x1
1565 put x2
1587 put x2
1566 put x3
1588 put x3
@@ -1576,7 +1598,7 @@ instance Binary SyntaxInfo where
1576 x5 <- get
1598 x5 <- get
1577 x6 <- get
1599 x6 <- get
1578 x7 <- get
1600 x7 <- get
1579− return (Syn x1 x2 x3 x4 id x5 x6 x7)
1601+ return (Syn x1 x2 x3 x4 id x5 x6 Nothing 0 x7)
1580
1602
1581instance (Binary t) => Binary (PClause' t) where
1603instance (Binary t) => Binary (PClause' t) where
1582 put x
1604 put x
@@ -1939,6 +1961,13 @@ instance (Binary t) => Binary (PTactic' t) where
1939 put x1
1961 put x1
1940 ByReflection x1 -> do putWord8 20
1962 ByReflection x1 -> do putWord8 20
1941 put x1
1963 put x1
1964+ ProofSearch x1 x2 x3 x4 x5 -> do putWord8 21
1965+ put x1
1966+ put x2
1967+ put x3
1968+ put x4
1969+ put x5
1970+ DoUnify -> putWord8 22
1942 get
1971 get
1943 = do i <- getWord8
1972 = do i <- getWord8
1944 case i of
1973 case i of
@@ -1980,6 +2009,13 @@ instance (Binary t) => Binary (PTactic' t) where
1980 return (Induction x1)
2009 return (Induction x1)
1981 20 -> do x1 <- get
2010 20 -> do x1 <- get
1982 return (ByReflection x1)
2011 return (ByReflection x1)
2012+ 21 -> do x1 <- get
2013+ x2 <- get
2014+ x3 <- get
2015+ x4 <- get
2016+ x5 <- get
2017+ return (ProofSearch x1 x2 x3 x4 x5)
2018+ 22 -> return DoUnify
1983 _ -> error "Corrupted binary data for PTactic'"
2019 _ -> error "Corrupted binary data for PTactic'"
1984
2020
1985
2021
@@ -2116,15 +2152,17 @@ instance Binary OptInfo where
2116 return (Optimise x1 x2)
2152 return (Optimise x1 x2)
2117
2153
2118instance Binary TypeInfo where
2154instance Binary TypeInfo where
2119− put (TI x1 x2 x3 x4) = do put x1
2155+ put (TI x1 x2 x3 x4 x5) = do put x1
2120− put x2
2156+ put x2
2121− put x3
2157+ put x3
2122− put x4
2158+ put x4
2159+ put x5
2123 get = do x1 <- get
2160 get = do x1 <- get
2124 x2 <- get
2161 x2 <- get
2125 x3 <- get
2162 x3 <- get
2126 x4 <- get
2163 x4 <- get
2164+ x5 <- get
2127− return (TI x1 x2 x3 x4)
2165+ return (TI x1 x2 x3 x4 x5)
2128
2166
2129instance Binary SynContext where
2167instance Binary SynContext where
2130 put x
2168 put x
src/Idris/IdeSlave.hs+64−19
@@ -12,7 +12,7 @@ import Text.Trifecta.Delta
12
12
13import Idris.Core.TT
13import Idris.Core.TT
14
14
15−import Control.Applicative
15+import Control.Applicative hiding (Const)
16
16
17data SExp = SexpList [SExp]
17data SExp = SexpList [SExp]
18 | StringAtom String
18 | StringAtom String
@@ -74,16 +74,33 @@ instance (SExpable a, SExpable b, SExpable c, SExpable d, SExpable e) =>
74 toSExp (l, m, n, o, p) = SexpList [toSExp l, toSExp m, toSExp n, toSExp o, toSExp p]
74 toSExp (l, m, n, o, p) = SexpList [toSExp l, toSExp m, toSExp n, toSExp o, toSExp p]
75
75
76instance SExpable NameOutput where
76instance SExpable NameOutput where
77− toSExp TypeOutput = SymbolAtom "type"
77+ toSExp TypeOutput = SymbolAtom "type"
78− toSExp FunOutput = SymbolAtom "function"
78+ toSExp FunOutput = SymbolAtom "function"
79− toSExp DataOutput = SymbolAtom "data"
79+ toSExp DataOutput = SymbolAtom "data"
80− toSExp MetavarOutput = SymbolAtom "metavar"
80+ toSExp MetavarOutput = SymbolAtom "metavar"
81+ toSExp PostulateOutput = SymbolAtom "postulate"
81
82
82maybeProps :: SExpable a => [(String, Maybe a)] -> [(SExp, SExp)]
83maybeProps :: SExpable a => [(String, Maybe a)] -> [(SExp, SExp)]
83maybeProps [] = []
84maybeProps [] = []
84maybeProps ((n, Just p):ps) = (SymbolAtom n, toSExp p) : maybeProps ps
85maybeProps ((n, Just p):ps) = (SymbolAtom n, toSExp p) : maybeProps ps
85maybeProps ((n, Nothing):ps) = maybeProps ps
86maybeProps ((n, Nothing):ps) = maybeProps ps
86
87
88+constTy :: Const -> String
89+constTy (I _) = "Int"
90+constTy (BI _) = "Integer"
91+constTy (Fl _) = "Float"
92+constTy (Ch _) = "Char"
93+constTy (Str _) = "String"
94+constTy (B8 _) = "Bits8"
95+constTy (B16 _) = "Bits16"
96+constTy (B32 _) = "Bits32"
97+constTy (B64 _) = "Bits64"
98+constTy (B8V _) = "Bits8x16"
99+constTy (B16V _) = "Bits16x8"
100+constTy (B32V _) = "Bits32x4"
101+constTy (B64V _) = "Bits64x2"
102+constTy _ = "Type"
103+
87instance SExpable OutputAnnotation where
104instance SExpable OutputAnnotation where
88 toSExp (AnnName n ty d t) = toSExp $ [(SymbolAtom "name", StringAtom (show n)),
105 toSExp (AnnName n ty d t) = toSExp $ [(SymbolAtom "name", StringAtom (show n)),
89 (SymbolAtom "implicit", BoolAtom False)] ++
106 (SymbolAtom "implicit", BoolAtom False)] ++
@@ -92,19 +109,32 @@ instance SExpable OutputAnnotation where
92 toSExp (AnnBoundName n imp) = toSExp [(SymbolAtom "name", StringAtom (show n)),
109 toSExp (AnnBoundName n imp) = toSExp [(SymbolAtom "name", StringAtom (show n)),
93 (SymbolAtom "decor", SymbolAtom "bound"),
110 (SymbolAtom "decor", SymbolAtom "bound"),
94 (SymbolAtom "implicit", BoolAtom imp)]
111 (SymbolAtom "implicit", BoolAtom imp)]
95− toSExp AnnConstData = toSExp [(SymbolAtom "decor", SymbolAtom "data")]
112+ toSExp (AnnConst c) = toSExp [(SymbolAtom "decor",
113+ SymbolAtom (if constIsType c then "type" else "data")),
114+ (SymbolAtom "type", StringAtom (constTy c)),
115+ (SymbolAtom "doc-overview", StringAtom (constDocs c)),
116+ (SymbolAtom "name", StringAtom (show c))]
117+ toSExp (AnnData ty doc) = toSExp [(SymbolAtom "decor", SymbolAtom "data"),
118+ (SymbolAtom "type", StringAtom ty),
119+ (SymbolAtom "doc-overview", StringAtom doc)]
96− toSExp AnnConstType = toSExp [(SymbolAtom "decor", SymbolAtom "type")]
120+ toSExp (AnnType name doc) = toSExp $ [(SymbolAtom "decor", SymbolAtom "type"),
121+ (SymbolAtom "type", StringAtom "Type"),
122+ (SymbolAtom "doc-overview", StringAtom doc)] ++
123+ if not (null name) then [(SymbolAtom "name", StringAtom name)] else []
97 toSExp AnnKeyword = toSExp [(SymbolAtom "decor", SymbolAtom "keyword")]
124 toSExp AnnKeyword = toSExp [(SymbolAtom "decor", SymbolAtom "keyword")]
98− toSExp (AnnFC (FC f (sl, sc) (el, ec))) = toSExp [(SymbolAtom "source-loc",
125+ toSExp (AnnFC fc) = toSExp [(SymbolAtom "source-loc", toSExp fc)]
99− ((SymbolAtom "filename", StringAtom f),
100− (SymbolAtom "start", IntegerAtom (toInteger sl), IntegerAtom (toInteger sc)),
101− (SymbolAtom "end", IntegerAtom (toInteger el), IntegerAtom (toInteger ec))))]
102 toSExp (AnnTextFmt fmt) = toSExp [(SymbolAtom "text-formatting", SymbolAtom format)]
126 toSExp (AnnTextFmt fmt) = toSExp [(SymbolAtom "text-formatting", SymbolAtom format)]
103 where format = case fmt of
127 where format = case fmt of
104 BoldText -> "bold"
128 BoldText -> "bold"
105 ItalicText -> "italic"
129 ItalicText -> "italic"
106 UnderlineText -> "underline"
130 UnderlineText -> "underline"
107
131
132+instance SExpable FC where
133+ toSExp (FC f (sl, sc) (el, ec)) =
134+ toSExp ((SymbolAtom "filename", StringAtom f),
135+ (SymbolAtom "start", IntegerAtom (toInteger sl), IntegerAtom (toInteger sc)),
136+ (SymbolAtom "end", IntegerAtom (toInteger el), IntegerAtom (toInteger ec)))
137+
108escape :: String -> String
138escape :: String -> String
109escape = concatMap escapeChar
139escape = concatMap escapeChar
110 where
140 where
@@ -145,30 +175,43 @@ data IdeSlaveCommand = REPLCompletions String
145 | AddProofClause Int String
175 | AddProofClause Int String
146 | AddMissing Int String
176 | AddMissing Int String
147 | MakeWithBlock Int String
177 | MakeWithBlock Int String
148− | ProofSearch Int String [String]
178+ | ProofSearch Bool Int String [String] (Maybe Int) -- ^^ Recursive?, line, name, hints, depth
179+ | MakeLemma Int String
149− | LoadFile String
180+ | LoadFile String (Maybe Int)
150 | DocsFor String
181 | DocsFor String
151 | Apropos String
182 | Apropos String
152 | GetOpts
183 | GetOpts
153 | SetOpt Opt Bool
184 | SetOpt Opt Bool
154 | Metavariables Int -- ^^ the Int is the column count for pretty-printing
185 | Metavariables Int -- ^^ the Int is the column count for pretty-printing
155− deriving Show
186+ | WhoCalls String
187+ | CallsWho String
156
188
157sexpToCommand :: SExp -> Maybe IdeSlaveCommand
189sexpToCommand :: SExp -> Maybe IdeSlaveCommand
158sexpToCommand (SexpList (x:[])) = sexpToCommand x
190sexpToCommand (SexpList (x:[])) = sexpToCommand x
159sexpToCommand (SexpList [SymbolAtom "interpret", StringAtom cmd]) = Just (Interpret cmd)
191sexpToCommand (SexpList [SymbolAtom "interpret", StringAtom cmd]) = Just (Interpret cmd)
160sexpToCommand (SexpList [SymbolAtom "repl-completions", StringAtom prefix]) = Just (REPLCompletions prefix)
192sexpToCommand (SexpList [SymbolAtom "repl-completions", StringAtom prefix]) = Just (REPLCompletions prefix)
161−sexpToCommand (SexpList [SymbolAtom "load-file", StringAtom filename]) = Just (LoadFile filename)
193+sexpToCommand (SexpList [SymbolAtom "load-file", StringAtom filename, IntegerAtom line]) = Just (LoadFile filename (Just (fromInteger line)))
194+sexpToCommand (SexpList [SymbolAtom "load-file", StringAtom filename]) = Just (LoadFile filename Nothing)
162sexpToCommand (SexpList [SymbolAtom "type-of", StringAtom name]) = Just (TypeOf name)
195sexpToCommand (SexpList [SymbolAtom "type-of", StringAtom name]) = Just (TypeOf name)
163sexpToCommand (SexpList [SymbolAtom "case-split", IntegerAtom line, StringAtom name]) = Just (CaseSplit (fromInteger line) name)
196sexpToCommand (SexpList [SymbolAtom "case-split", IntegerAtom line, StringAtom name]) = Just (CaseSplit (fromInteger line) name)
164sexpToCommand (SexpList [SymbolAtom "add-clause", IntegerAtom line, StringAtom name]) = Just (AddClause (fromInteger line) name)
197sexpToCommand (SexpList [SymbolAtom "add-clause", IntegerAtom line, StringAtom name]) = Just (AddClause (fromInteger line) name)
165sexpToCommand (SexpList [SymbolAtom "add-proof-clause", IntegerAtom line, StringAtom name]) = Just (AddProofClause (fromInteger line) name)
198sexpToCommand (SexpList [SymbolAtom "add-proof-clause", IntegerAtom line, StringAtom name]) = Just (AddProofClause (fromInteger line) name)
166sexpToCommand (SexpList [SymbolAtom "add-missing", IntegerAtom line, StringAtom name]) = Just (AddMissing (fromInteger line) name)
199sexpToCommand (SexpList [SymbolAtom "add-missing", IntegerAtom line, StringAtom name]) = Just (AddMissing (fromInteger line) name)
167sexpToCommand (SexpList [SymbolAtom "make-with", IntegerAtom line, StringAtom name]) = Just (MakeWithBlock (fromInteger line) name)
200sexpToCommand (SexpList [SymbolAtom "make-with", IntegerAtom line, StringAtom name]) = Just (MakeWithBlock (fromInteger line) name)
201+-- The Boolean in ProofSearch means "search recursively"
202+-- If it's False, that means "refine", i.e. apply the name and fill in any
203+-- arguments which can be done by unification.
168−sexpToCommand (SexpList [SymbolAtom "proof-search", IntegerAtom line, StringAtom name, SexpList hintexp]) | Just hints <- getHints hintexp = Just (ProofSearch (fromInteger line) name hints)
204+sexpToCommand (SexpList (SymbolAtom "proof-search" : IntegerAtom line : StringAtom name : rest))
205+ | [] <- rest = Just (ProofSearch True (fromInteger line) name [] Nothing)
206+ | [SexpList hintexp] <- rest
207+ , Just hints <- getHints hintexp = Just (ProofSearch True (fromInteger line) name hints Nothing)
208+ | [SexpList hintexp, IntegerAtom depth] <- rest
209+ , Just hints <- getHints hintexp = Just (ProofSearch True (fromInteger line) name hints (Just (fromInteger depth)))
169− where getHints = mapM (\h -> case h of
210+ where getHints = mapM (\h -> case h of
170− StringAtom s -> Just s
211+ StringAtom s -> Just s
171− _ -> Nothing)
212+ _ -> Nothing)
213+sexpToCommand (SexpList [SymbolAtom "make-lemma", IntegerAtom line, StringAtom name]) = Just (MakeLemma (fromInteger line) name)
214+sexpToCommand (SexpList [SymbolAtom "refine", IntegerAtom line, StringAtom name, StringAtom hint]) = Just (ProofSearch False (fromInteger line) name [hint] Nothing)
172sexpToCommand (SexpList [SymbolAtom "docs-for", StringAtom name]) = Just (DocsFor name)
215sexpToCommand (SexpList [SymbolAtom "docs-for", StringAtom name]) = Just (DocsFor name)
173sexpToCommand (SexpList [SymbolAtom "apropos", StringAtom search]) = Just (Apropos search)
216sexpToCommand (SexpList [SymbolAtom "apropos", StringAtom search]) = Just (Apropos search)
174sexpToCommand (SymbolAtom "get-options") = Just GetOpts
217sexpToCommand (SymbolAtom "get-options") = Just GetOpts
@@ -176,6 +219,8 @@ sexpToCommand (SexpList [SymbolAtom "set-option", SymbolAtom s, BoolAtom b])
176 | Just opt <- lookup s opts = Just (SetOpt opt b)
219 | Just opt <- lookup s opts = Just (SetOpt opt b)
177 where opts = [("show-implicits", ShowImpl), ("error-context", ErrContext)] --TODO support more
220 where opts = [("show-implicits", ShowImpl), ("error-context", ErrContext)] --TODO support more
178sexpToCommand (SexpList [SymbolAtom "metavariables", IntegerAtom cols]) = Just (Metavariables (fromIntegral cols))
221sexpToCommand (SexpList [SymbolAtom "metavariables", IntegerAtom cols]) = Just (Metavariables (fromIntegral cols))
222+sexpToCommand (SexpList [SymbolAtom "who-calls", StringAtom name]) = Just (WhoCalls name)
223+sexpToCommand (SexpList [SymbolAtom "calls-who", StringAtom name]) = Just (CallsWho name)
179sexpToCommand _ = Nothing
224sexpToCommand _ = Nothing
180
225
181parseMessage :: String -> Either Err (SExp, Integer)
226parseMessage :: String -> Either Err (SExp, Integer)
src/Idris/IdrisDoc.hsnew file+661
@@ -0,0 +1,661 @@
1+{-# LANGUAGE PatternGuards #-}
2+{-# LANGUAGE OverloadedStrings #-}
3+
4+-- | Generation of HTML documentation for Idris code
5+module Idris.IdrisDoc (generateDocs) where
6+
7+import Idris.Core.TT (Name (..), sUN, SpecialName (..), OutputAnnotation (..),
8+ TextFormatting (..), txt, str, nsroot, constIsType)
9+import Idris.Core.Evaluate (ctxtAlist, Def (..), lookupDefAcc,
10+ Accessibility (..), isDConName, isFnName,
11+ isTConName)
12+import Idris.ParseHelpers (opChars)
13+import Idris.AbsSyntax
14+import Idris.Docs
15+import Idris.Docstrings (nullDocstring)
16+
17+import Paths_idris (getDataFileName)
18+
19+import Control.Monad (forM_)
20+import Control.Monad.Trans.Error
21+import Control.Monad.Trans.State.Strict
22+
23+import Data.Maybe
24+
25+import qualified Data.ByteString as BS
26+import qualified Data.ByteString.Lazy as BS2
27+import qualified Data.Text.Encoding as E
28+import qualified Data.List as L
29+import qualified Data.List.Split as LS
30+import qualified Data.Map as M hiding ((!))
31+import qualified Data.Ord (compare)
32+import qualified Data.Set as S
33+import qualified Data.Text as T
34+
35+import System.IO
36+import System.IO.Error
37+import System.FilePath
38+import System.Directory
39+
40+import Cheapskate.Html (renderDoc)
41+import Text.PrettyPrint.Annotated.Leijen (displayDecorated, renderCompact)
42+
43+import Text.Blaze (toValue, contents)
44+import Text.Blaze.Internal (MarkupM (Empty))
45+import Text.Blaze.Html5 ((!), toHtml, preEscapedToHtml)
46+import qualified Text.Blaze.Html5 as H
47+import Text.Blaze.Html5.Attributes as A
48+import Text.Blaze.Html.Renderer.Utf8 (renderHtml)
49+import qualified Text.Blaze.Html.Renderer.String as R
50+import Text.Blaze.Renderer.String (renderMarkup)
51+
52+-- ---------------------------------------------------------------- [ Public ]
53+
54+-- | Generates HTML documentation for a series of loaded namespaces
55+-- and their dependencies.
56+generateDocs :: IState -- ^ IState where all necessary information is
57+ -- extracted from.
58+ -> [Name] -- ^ List of namespaces to generate
59+ -- documentation for.
60+ -> FilePath -- ^ The directory to which documentation will
61+ -- be written.
62+ -> IO (Either String ())
63+generateDocs ist nss' out =
64+ do let nss = map toNsName nss'
65+ docs <- fetchInfo ist nss
66+ let (c, io) = foldl (checker docs) (0, return ()) nss
67+ io
68+ if c < length nss
69+ then catchIOError (createDocs ist docs out) (err . show)
70+ else err "No namespaces to generate documentation for"
71+
72+ where checker docs st ns | M.member ns docs = st
73+ checker docs (c, io) ns = (c+1, do prev <- io; warnMissing ns)
74+ warnMissing ns =
75+ putStrLn $ "Warning: Ignoring empty or non-existing namespace '" ++
76+ (nsName2Str ns) ++ "'"
77+
78+-- ----------------------------------------------------------------- [ Types ]
79+
80+-- | Either an error message or a result
81+type Failable = Either String
82+
83+-- | Internal representation of a fully qualified namespace name
84+type NsName = [T.Text]
85+
86+-- | All information to be documented about a single namespace member
87+type NsItem = (Name, Maybe Docs, Accessibility)
88+
89+-- | All information to be documented about a namespace
90+type NsInfo = [NsItem]
91+
92+-- | A map from namespace names to information about them
93+type NsDict = M.Map NsName NsInfo
94+
95+-- --------------------------------------------------------------- [ Utility ]
96+
97+-- | Make an error message
98+err :: String -> IO (Failable ())
99+err s = return $ Left s
100+
101+-- | IdrisDoc version
102+version :: String
103+version = "1.0"
104+
105+-- | Converts a Name into a [Text] corresponding to the namespace
106+-- part of a NS Name.
107+toNsName :: Name -- ^ Name to convert
108+ -> NsName
109+toNsName (UN n) = [n]
110+toNsName (NS n ns) = (toNsName n) ++ ns
111+toNsName _ = []
112+
113+
114+-- | Retrieves the namespace part of a Name
115+getNs :: Name -- ^ Name to retrieve namespace for
116+ -> NsName
117+getNs (NS _ ns) = ns
118+getNs _ = []
119+
120+
121+-- | String to replace for the root namespace
122+rootNsStr :: String
123+rootNsStr = "[builtins]"
124+
125+
126+-- | Converts a NsName to string form
127+nsName2Str :: NsName -- ^ NsName to convert
128+ -> String
129+nsName2Str n = if null n then rootNsStr else name n
130+
131+ where name [] = []
132+ name [ns] = str ns
133+ name (ns:nss) = (name nss) ++ ('.' : str ns)
134+
135+-- --------------------------------------------------------- [ Info Fetching ]
136+
137+-- | Fetch info about namespaces and their contents
138+fetchInfo :: IState -- ^ IState to fetch info from
139+ -> [NsName] -- ^ List of namespaces to fetch info for
140+ -> IO NsDict -- ^ Mapping from namespace name to
141+ -- info about its contents
142+fetchInfo ist nss =
143+ do let originNss = S.fromList nss
144+ info <- nsDict ist
145+ let info' = M.map (filter filterInclude) info
146+ info'' = M.map removeOrphans info'
147+ info''' = M.filter (not . null) info''
148+ reachedNss = traceNss info''' originNss S.empty
149+ return $ M.filterWithKey (\k _ -> S.member k reachedNss) info'''
150+
151+
152+-- | Removes loose class methods and data constructors,
153+-- leaving them documented only under their parent.
154+removeOrphans :: [NsItem] -- ^ List to remove orphans from
155+ -> [NsItem] -- ^ Orphan-free list
156+removeOrphans list =
157+ let children = S.fromList $ concatMap (names . (\(_, d, _) -> d)) list
158+ in filter ((`S.notMember` children) . (\(n, _, _) -> n)) list
159+
160+ where names (Just (DataDoc _ fds)) = map (\(FD n _ _ _ _) -> n) fds
161+ names (Just (ClassDoc _ _ fds _ _ _)) = map (\(FD n _ _ _ _) -> n) fds
162+ names _ = []
163+
164+-- | Whether a Name names something which should be documented
165+filterName :: Name -- ^ Name to check
166+ -> Bool -- ^ Predicate result
167+filterName (UN n) | '@':'@':_ <- str n = False
168+filterName (UN _) = True
169+filterName (NS n _) = filterName n
170+filterName _ = False
171+
172+
173+-- | Whether a NsItem should be included in the documentation.
174+-- It must not be Hidden and filterName must return True for the name.
175+-- Also it must have Docs -- without Docs, nothing can be done.
176+filterInclude :: NsItem -- ^ Accessibility to check
177+ -> Bool -- ^ Predicate result
178+filterInclude (name, Just _, Public) | filterName name = True
179+filterInclude (name, Just _, Frozen) | filterName name = True
180+filterInclude _ = False
181+
182+
183+-- | Finds all namespaces indirectly referred by a set of namespaces.
184+-- The NsItems of the namespaces are searched for references.
185+traceNss :: NsDict -- ^ Mappings of namespaces and their contents
186+ -> S.Set NsName -- ^ Set of namespaces to trace
187+ -> S.Set NsName -- ^ Set of namespaces which has been traced
188+ -> S.Set NsName -- ^ Set of namespaces to trace and all traced one
189+traceNss nsd sT sD =
190+ let nsTracer ns | Just nsis <- M.lookup ns nsd = map referredNss nsis
191+ nsTracer _ = [S.empty] -- Ignore
192+ reached = S.unions $ concatMap nsTracer (S.toList sT)
193+ processed = S.union sT sD
194+ untraced = S.difference reached processed
195+ in if S.null untraced then processed
196+ else traceNss nsd untraced processed
197+
198+
199+-- | Gets all namespaces directly referred by a NsItem
200+referredNss :: NsItem -- ^ The name to get all directly
201+ -- referred namespaces for
202+ -> S.Set NsName
203+referredNss (_, Nothing, _) = S.empty
204+referredNss (n, Just d, _) =
205+ let fds = getFunDocs d
206+ ts = concatMap types fds
207+ names = concatMap (extractPTermNames) ts
208+ in S.map getNs $ S.fromList names
209+
210+ where getFunDocs (FunDoc f) = [f]
211+ getFunDocs (DataDoc f fs) = f:fs
212+ getFunDocs (ClassDoc _ _ fs _ _ _) = fs
213+ types (FD _ _ args t _) = t:(map second args)
214+ second (_, x, _, _) = x
215+
216+
217+-- | Returns an NsDict of containing all known namespaces and their contents
218+nsDict :: IState
219+ -> IO NsDict
220+nsDict ist =
221+ let nameDefList = ctxtAlist $ tt_ctxt ist
222+ adder m (n, _) = do map <- m
223+ doc <- loadDocs ist n
224+ let acc = getAccess ist n
225+ c = [(n, doc, acc)]
226+ return $ M.insertWith (++) (getNs n) c map
227+ in foldl adder (return M.empty) nameDefList
228+
229+
230+-- | Gets the Accessibility for a Name
231+getAccess :: IState -- ^ IState containing accessibility information
232+ -> Name -- ^ The Name to retrieve access for
233+ -> Accessibility
234+getAccess ist n =
235+ let res = lookupDefAcc n False (tt_ctxt ist)
236+ in case res of
237+ [(_, acc)] -> acc
238+ _ -> Hidden
239+
240+-- | Simple predicate for whether an NsItem has Docs
241+hasDoc :: NsItem -- ^ The NsItem to test
242+ -> Bool -- ^ The result
243+hasDoc (_, Just _, _) = True
244+hasDoc _ = False
245+
246+
247+-- | Predicate saying whether a Name possibly may have docs defined
248+-- Without this, getDocs from Idris.Docs may fail a pattern match.
249+mayHaveDocs :: Name -- ^ The Name to test
250+ -> Bool -- ^ The result
251+mayHaveDocs (UN _) = True
252+mayHaveDocs (NS n _) = mayHaveDocs n
253+mayHaveDocs _ = False
254+
255+
256+-- | Retrieves the Docs for a Name
257+loadDocs :: IState -- ^ IState to extract infomation from
258+ -> Name -- ^ Name to load Docs for
259+ -> IO (Maybe Docs)
260+loadDocs ist n
261+ | mayHaveDocs n = do docs <- runErrorT $ evalStateT (getDocs n) ist
262+ case docs of Right d -> return (Just d)
263+ Left _ -> return Nothing
264+ | otherwise = return Nothing
265+
266+
267+-- | Extracts names referred from a type.
268+-- The covering of all PTerms ensures that we avoid unanticipated cases,
269+-- though all of them are not needed. The author just did not know which!
270+-- TODO: Remove unnecessary cases
271+extractPTermNames :: PTerm -- ^ Where to extract names from
272+ -> [Name] -- ^ Extracted names
273+extractPTermNames (PRef _ n) = [n]
274+extractPTermNames (PInferRef _ n) = [n]
275+extractPTermNames (PPatvar _ n) = [n]
276+extractPTermNames (PLam n p1 p2) = n : concatMap extract [p1, p2]
277+extractPTermNames (PPi _ n p1 p2) = n : concatMap extract [p1, p2]
278+extractPTermNames (PLet n p1 p2 p3) = n : concatMap extract [p1, p2, p3]
279+extractPTermNames (PTyped p1 p2) = concatMap extract [p1, p2]
280+extractPTermNames (PApp _ p pas) = let names = concatMap extractPArg pas
281+ in (extract p) ++ names
282+extractPTermNames (PAppBind _ p pas) = let names = concatMap extractPArg pas
283+ in (extract p) ++ names
284+extractPTermNames (PMatchApp _ n) = [n]
285+extractPTermNames (PCase _ p ps) = let (ps1, ps2) = unzip ps
286+ in concatMap extract (p:(ps1 ++ ps2))
287+extractPTermNames (PRefl _ p) = extract p
288+extractPTermNames (PEq _ p1 p2) = concatMap extract [p1, p2]
289+extractPTermNames (PRewrite _ a b m) | Just c <- m =
290+ concatMap extract [a, b, c]
291+extractPTermNames (PRewrite _ a b _) = concatMap extract [a, b]
292+extractPTermNames (PPair _ _ p1 p2) = concatMap extract [p1, p2]
293+extractPTermNames (PDPair _ _ a b c) = concatMap extract [a, b, c]
294+extractPTermNames (PAlternative _ l) = concatMap extract l
295+extractPTermNames (PHidden p) = extract p
296+extractPTermNames (PGoal _ p1 n p2) = n : concatMap extract [p1, p2]
297+extractPTermNames (PDoBlock pdos) = concatMap extractPDo pdos
298+extractPTermNames (PIdiom _ p) = extract p
299+extractPTermNames (PMetavar n) = [n]
300+extractPTermNames (PProof tacts) = concatMap extractPTactic tacts
301+extractPTermNames (PTactics tacts) = concatMap extractPTactic tacts
302+extractPTermNames (PCoerced p) = extract p
303+extractPTermNames (PDisamb _ p) = extract p
304+extractPTermNames (PUnifyLog p) = extract p
305+extractPTermNames (PNoImplicits p) = extract p
306+extractPTermNames _ = []
307+
308+-- | Shorter name for extractPTermNames
309+extract :: PTerm -- ^ Where to extract names from
310+ -> [Name] -- ^ Extracted names
311+extract = extractPTermNames
312+
313+-- | Helper function for extractPTermNames
314+extractPArg :: PArg -> [Name]
315+extractPArg (PImp {pname=n, getTm=p}) = n : extract p
316+extractPArg (PExp {getTm=p}) = extract p
317+extractPArg (PConstraint {getTm=p}) = extract p
318+extractPArg (PTacImplicit {pname=n, getScript=p1, getTm=p2})
319+ = n : (concatMap extract [p1, p2])
320+
321+-- | Helper function for extractPTermNames
322+extractPDo :: PDo -> [Name]
323+extractPDo (DoExp _ p) = extract p
324+extractPDo (DoBind _ n p) = n : extract p
325+extractPDo (DoBindP _ p1 p2 ps) = let (ps1, ps2) = unzip ps
326+ ps' = ps1 ++ ps2
327+ in concatMap extract (p1 : p2 : ps')
328+extractPDo (DoLet _ n p1 p2) = n : concatMap extract [p1, p2]
329+extractPDo (DoLetP _ p1 p2) = concatMap extract [p1, p2]
330+
331+-- | Helper function for extractPTermNames
332+extractPTactic :: PTactic -> [Name]
333+extractPTactic (Intro ns) = ns
334+extractPTactic (Focus n) = [n]
335+extractPTactic (Refine n _) = [n]
336+extractPTactic (Rewrite p) = extract p
337+extractPTactic (Induction n) = [n]
338+extractPTactic (Equiv p) = extract p
339+extractPTactic (MatchRefine n) = [n]
340+extractPTactic (LetTac n p) = n : extract p
341+extractPTactic (LetTacTy n p1 p2) = n : concatMap extract [p1, p2]
342+extractPTactic (Exact p) = extract p
343+extractPTactic (ProofSearch _ _ _ m ns) | Just n <- m = n : ns
344+extractPTactic (ProofSearch _ _ _ _ ns) = ns
345+extractPTactic (Try t1 t2) = concatMap extractPTactic [t1, t2]
346+extractPTactic (TSeq t1 t2) = concatMap extractPTactic [t1, t2]
347+extractPTactic (ApplyTactic p) = extract p
348+extractPTactic (ByReflection p) = extract p
349+extractPTactic (Reflect p) = extract p
350+extractPTactic (Fill p) = extract p
351+extractPTactic (GoalType _ t) = extractPTactic t
352+extractPTactic (TCheck p) = extract p
353+extractPTactic (TEval p) = extract p
354+extractPTactic _ = []
355+
356+-- ------------------------------------------------------- [ HTML Generation ]
357+
358+-- | Generates the actual HTML output based on info from a NsDict
359+-- A merge of the new docs and any existing docs located in the output dir
360+-- is attempted.
361+-- TODO: Ensure the merge always succeeds.
362+-- Currently the content of 'docs/<builtins>.html' may change between
363+-- runs, thus not always containing all items referred from other
364+-- namespace .html files.
365+createDocs :: IState -- ^ Needed to determine the types of names
366+ -> NsDict -- ^ All info from which to generate docs
367+ -> FilePath -- ^ The base directory to which
368+ -- documentation will be written.
369+ -> IO (Failable ())
370+createDocs ist nsd out =
371+ do new <- not `fmap` (doesFileExist $ out </> "IdrisDoc")
372+ existing_nss <- existingNamespaces out
373+ let nss = S.union (M.keysSet nsd) existing_nss
374+ dExists <- doesDirectoryExist out
375+ if new && dExists then err $ "Output directory (" ++ out ++ ") is" ++
376+ " already in use for other than IdrisDoc."
377+ else do
378+ createDirectoryIfMissing True out
379+ foldl docGen (return ()) (M.toList nsd)
380+ createIndex nss out
381+ -- Create an empty IdrisDoc file to signal 'out' is used for IdrisDoc
382+ if new -- But only if it not already existed...
383+ then withFile (out </> "IdrisDoc") WriteMode ((flip hPutStr) "")
384+ else return ()
385+ copyDependencies out
386+ return $ Right ()
387+
388+ where docGen io (n, c) = do io; createNsDoc ist n c out
389+
390+
391+-- | (Over)writes the 'index.html' file in the given directory with
392+-- an (updated) index of namespaces in the documentation
393+createIndex :: S.Set NsName -- ^ Set of namespace names to
394+ -- include in the index
395+ -> FilePath -- ^ The base directory to which
396+ -- documentation will be written.
397+ -> IO ()
398+createIndex nss out =
399+ do (path, h) <- openTempFile out "index.html"
400+ BS2.hPut h $ renderHtml $ wrapper Nothing $ do
401+ H.h1 $ "Namespaces"
402+ H.ul ! class_ "names" $ do
403+ let path ns = "docs" </> genRelNsPath ns "html"
404+ item ns = do let n = toHtml $ nsName2Str ns
405+ link = toValue $ path ns
406+ H.li $ H.a ! href link ! class_ "code" $ n
407+ sort = L.sortBy (\n1 n2 -> reverse n1 `compare` reverse n2)
408+ forM_ (sort $ S.toList nss) item
409+ hClose h
410+ renameFile path (out </> "index.html")
411+
412+
413+-- | Generates a HTML file for a namespace and its contents.
414+-- The location for e.g. Prelude.Algebra is <base>/Prelude/Algebra.html
415+createNsDoc :: IState -- ^ Needed to determine the types of names
416+ -> NsName -- ^ The name of the namespace to
417+ -- create documentation for
418+ -> NsInfo -- ^ The contents of the namespace
419+ -> FilePath -- ^ The base directory to which
420+ -- documentation will be written.
421+ -> IO ()
422+createNsDoc ist ns content out =
423+ do let tpath = out </> "docs" </> (genRelNsPath ns "html")
424+ dir = takeDirectory tpath
425+ file = takeFileName tpath
426+ haveDocs (_, Just d, _) = [d]
427+ haveDocs _ = []
428+ -- We cannot do anything without a Doc
429+ content' = concatMap haveDocs content
430+ createDirectoryIfMissing True dir
431+ (path, h) <- openTempFile dir file
432+ BS2.hPut h $ renderHtml $ wrapper (Just ns) $ do
433+ H.h1 $ toHtml (nsName2Str ns)
434+ H.dl ! class_ "decls" $ forM_ content' (createOtherDoc ist)
435+ hClose h
436+ renameFile path tpath
437+
438+
439+-- | Generates a relative filepath for a namespace, appending an extension
440+genRelNsPath :: NsName -- ^ Namespace to generate a path for
441+ -> String -- ^ Extension suffix
442+ -> FilePath
443+genRelNsPath ns suffix = nsName2Str ns <.> suffix
444+
445+
446+-- | Generates a HTML type signature with proper tags
447+-- TODO: Turn docstrings into title attributes more robustly
448+genTypeHeader :: IState -- ^ Needed to determine the types of names
449+ -> FunDoc -- ^ Type to generate type declaration for
450+ -> H.Html -- ^ Resulting HTML
451+genTypeHeader ist (FD n _ args ftype _) = do
452+ H.span ! class_ (toValue $ "name " ++ getType n)
453+ ! title (toValue $ show n)
454+ $ toHtml $ name $ nsroot n
455+ H.span ! class_ "word" $ do nbsp; ":"; nbsp
456+ H.span ! class_ "signature" $ preEscapedToHtml htmlSignature
457+
458+ where
459+ htmlSignature = displayDecorated decorator $ renderCompact signature
460+ signature = pprintPTerm defaultPPOption [] names (idris_infixes ist) ftype
461+ names = [ n | (n@(UN n'), _, _, _) <- args,
462+ not (T.isPrefixOf (txt "__") n') ]
463+
464+ decorator (AnnConst c) str | constIsType c = htmlSpan str "type" str
465+ | otherwise = htmlSpan str "data" str
466+ decorator (AnnData _ _) str = htmlSpan str "data" str
467+ decorator (AnnType _ _) str = htmlSpan str "type" str
468+ decorator AnnKeyword str = htmlSpan "" "keyword" str
469+ decorator (AnnBoundName n i) str | Just t <- M.lookup n docs =
470+ let cs = (if i then "implicit " else "") ++ "documented boundvar"
471+ in htmlSpan t cs str
472+ decorator (AnnBoundName _ i) str =
473+ let cs = (if i then "implicit " else "") ++ "boundvar"
474+ in htmlSpan "" cs str
475+ decorator (AnnName n _ _ _) str
476+ | filterName n = htmlLink (show n) (getType n) (link n) str
477+ | otherwise = htmlSpan "" (getType n) str
478+ decorator (AnnTextFmt BoldText) str = "<b>" ++ str ++ "</b>"
479+ decorator (AnnTextFmt UnderlineText) str = "<u>" ++ str ++ "</u>"
480+ decorator (AnnTextFmt ItalicText) str = "<i>" ++ str ++ "</i>"
481+ decorator _ str = str
482+
483+ htmlSpan :: String -> String -> String -> String
484+ htmlSpan t cs str = do
485+ R.renderHtml $ H.span ! class_ (toValue cs)
486+ ! title (toValue t)
487+ $ toHtml str
488+ htmlLink :: String -> String -> String -> String -> String
489+ htmlLink t cs a str = do
490+ R.renderHtml $ H.a ! class_ (toValue cs)
491+ ! title (toValue t) ! href (toValue a)
492+ $ toHtml str
493+
494+ docs = M.fromList $ mapMaybe docExtractor args
495+ docExtractor (_, _, _, Nothing) = Nothing
496+ docExtractor (n, _, _, Just d) = Just (n, doc2Str d)
497+ -- TODO: Remove <p> tags more robustly
498+ doc2Str d = let dirty = renderMarkup $ contents $ renderDoc $ d
499+ in take (length dirty - 8) $ drop 3 dirty
500+
501+ name (NS n ns) = show (NS (sUN $ name n) ns)
502+ name n = let n' = show n
503+ in if (head n') `elem` opChars
504+ then '(':(n' ++ ")")
505+ else n'
506+
507+ link n = let path = genRelNsPath (getNs n) "html"
508+ in path ++ "#" ++ (show n)
509+
510+ getType :: Name -> String
511+ getType n = let ctxt = tt_ctxt ist
512+ in case () of
513+ _ | isDConName n ctxt -> "constructor"
514+ _ | isFnName n ctxt -> "function"
515+ _ | isTConName n ctxt -> "type"
516+ _ | otherwise -> ""
517+
518+-- | Generates HTML documentation for a function.
519+createFunDoc :: IState -- ^ Needed to determine the types of names
520+ -> FunDoc -- ^ Function to generate block for
521+ -> H.Html -- ^ Resulting HTML
522+createFunDoc ist fd@(FD name docstring args ftype fixity) = do
523+ H.dt ! (A.id $ toValue $ show name) $ genTypeHeader ist fd
524+ H.dd $ do
525+ (if nullDocstring docstring then Empty else renderDoc docstring)
526+ let args' = filter (\(_, _, _, d) -> isJust d) args
527+ if (not $ null args') || (isJust fixity)
528+ then H.dl $ do
529+ if (isJust fixity) then do
530+ H.dt ! class_ "fixity" $ "Fixity"
531+ let f = fromJust fixity
532+ H.dd ! class_ "fixity" ! title (toValue $ show f) $ genFix f
533+ else Empty
534+ forM_ args' genArg
535+ else Empty
536+
537+ where genFix (Infixl {prec=p}) =
538+ toHtml $ "Left associative, precedence " ++ show p
539+ genFix (Infixr {prec=p}) =
540+ toHtml $ "Left associative, precedence " ++ show p
541+ genFix (InfixN {prec=p}) =
542+ toHtml $ "Non-associative, precedence " ++ show p
543+ genFix (PrefixN {prec=p}) =
544+ toHtml $ "Prefix, precedence " ++ show p
545+ genArg (_, _, _, Nothing) = Empty
546+ genArg (name, _, _, Just docstring) = do
547+ H.dt $ toHtml $ show name
548+ H.dd $ renderDoc docstring
549+
550+
551+-- | Generates HTML documentation for any Docs type
552+-- TODO: Generate actual signatures for typeclasses
553+createOtherDoc :: IState -- ^ Needed to determine the types of names
554+ -> Docs -- ^ Namespace item to generate HTML block for
555+ -> H.Html -- ^ Resulting HTML
556+createOtherDoc ist (FunDoc fd) = createFunDoc ist fd
557+
558+createOtherDoc ist (ClassDoc n docstring fds _ _ _) = do
559+ H.dt ! (A.id $ toValue $ show n) $ do
560+ H.span ! class_ "word" $ do "class"; nbsp
561+ H.span ! class_ "name type"
562+ ! title (toValue $ show n)
563+ $ toHtml $ name $ nsroot n
564+ H.span ! class_ "signature" $ nbsp
565+ H.dd $ do
566+ (if nullDocstring docstring then Empty else renderDoc docstring)
567+ H.dl ! class_ "decls" $ forM_ fds (createFunDoc ist)
568+
569+ where name (NS n ns) = show (NS (sUN $ name n) ns)
570+ name n = let n' = show n
571+ in if (head n') `elem` opChars
572+ then '(':(n' ++ ")")
573+ else n'
574+
575+createOtherDoc ist (DataDoc fd@(FD n docstring args _ _) fds) = do
576+ H.dt ! (A.id $ toValue $ show n) $ do
577+ H.span ! class_ "word" $ do "data"; nbsp
578+ genTypeHeader ist fd
579+ H.dd $ do
580+ (if nullDocstring docstring then Empty else renderDoc docstring)
581+ let args' = filter (\(_, _, _, d) -> isJust d) args
582+ if not $ null args'
583+ then H.dl $ forM_ args' genArg
584+ else Empty
585+ H.dl ! class_ "decls" $ forM_ fds (createFunDoc ist)
586+
587+ where genArg (_, _, _, Nothing) = Empty
588+ genArg (name, _, _, Just docstring) = do
589+ H.dt $ toHtml $ show name
590+ H.dd $ renderDoc docstring
591+
592+
593+-- | Generates everything but the actual content of the page
594+wrapper :: Maybe NsName -- ^ Namespace name, unless it is the index
595+ -> H.Html -- ^ Inner HTML
596+ -> H.Html
597+wrapper ns inner =
598+ let (index, str) = extract ns
599+ base = if index then "" else "../"
600+ styles = base ++ "styles.css" :: String
601+ indexPage = base ++ "index.html" :: String
602+ in H.docTypeHtml $ do
603+ H.head $ do
604+ H.title $ do
605+ "IdrisDoc"
606+ if index then " Index" else do
607+ ": "
608+ toHtml str
609+ H.link ! type_ "text/css" ! rel "stylesheet"
610+ ! href (toValue styles)
611+ H.body ! class_ (if index then "index" else "namespace") $ do
612+ H.div ! class_ "wrapper" $ do
613+ H.header $ do
614+ H.strong "IdrisDoc"
615+ if index then Empty else do
616+ ": "
617+ toHtml str
618+ H.nav $ H.a ! href (toValue indexPage) $ "Index"
619+ H.div ! class_ "container" $ inner
620+ H.footer $ do
621+ "Produced by IdrisDoc version "
622+ toHtml version
623+
624+ where extract (Just ns) = (False, nsName2Str ns)
625+ extract _ = (True, "")
626+
627+
628+-- | Non-break space character
629+nbsp :: H.Html
630+nbsp = preEscapedToHtml ("&nbsp;" :: String)
631+
632+
633+-- | Returns a list of namespaces already documented in a IdrisDoc directory
634+existingNamespaces :: FilePath -- ^ The base directory containing the
635+ -- 'docs' directory with existing
636+ -- namespace pages
637+ -> IO (S.Set NsName)
638+existingNamespaces out = do
639+ let docs = out </> "docs"
640+ str2Ns s | s == rootNsStr = []
641+ str2Ns s = reverse $ T.splitOn (T.singleton '.') (txt s)
642+ toNs fp = do isFile <- doesFileExist $ docs </> fp
643+ let isHtml = ".html" == takeExtension fp
644+ name = dropExtension fp
645+ ns = str2Ns name
646+ return $ if isFile && isHtml then Just ns else Nothing
647+ docsExists <- doesDirectoryExist docs
648+ if not docsExists
649+ then return S.empty
650+ else do contents <- getDirectoryContents docs
651+ namespaces <- catMaybes `fmap` (sequence $ map toNs contents)
652+ return $ S.fromList namespaces
653+
654+
655+-- | Copies IdrisDoc dependencies such as stylesheets to a directory
656+copyDependencies :: FilePath -- ^ The base directory to which
657+ -- dependencies should be written
658+ -> IO ()
659+copyDependencies dir =
660+ do styles <- getDataFileName $ "idrisdoc" </> "styles.css"
661+ copyFile styles (dir </> "styles.css")
src/Idris/Imports.hs+7−6
@@ -1,6 +1,7 @@
1module Idris.Imports where
1module Idris.Imports where
2
2
3import Idris.AbsSyntax
3import Idris.AbsSyntax
4+import Idris.Error
4
5
5import Idris.Core.TT
6import Idris.Core.TT
6import Paths_idris
7import Paths_idris
@@ -43,15 +44,15 @@ ibcPathWithFallback ibcsd fp = do let ibcp = ibcPath ibcsd True fp
43ibcPathNoFallback :: FilePath -> FilePath -> FilePath
44ibcPathNoFallback :: FilePath -> FilePath -> FilePath
44ibcPathNoFallback ibcsd fp = ibcPath ibcsd True fp
45ibcPathNoFallback ibcsd fp = ibcPath ibcsd True fp
45
46
46−findImport :: [FilePath] -> FilePath -> FilePath -> IO IFileType
47+findImport :: [FilePath] -> FilePath -> FilePath -> Idris IFileType
47−findImport [] ibcsd fp = fail $ "Can't find import " ++ fp
48+findImport [] ibcsd fp = ierror . Msg $ "Can't find import " ++ fp
48findImport (d:ds) ibcsd fp = do let fp_full = d </> fp
49findImport (d:ds) ibcsd fp = do let fp_full = d </> fp
49− ibcp <- ibcPathWithFallback ibcsd fp_full
50+ ibcp <- runIO $ ibcPathWithFallback ibcsd fp_full
50 let idrp = srcPath fp_full
51 let idrp = srcPath fp_full
51 let lidrp = lsrcPath fp_full
52 let lidrp = lsrcPath fp_full
52− ibc <- doesFileExist ibcp
53+ ibc <- runIO $ doesFileExist ibcp
53− idr <- doesFileExist idrp
54+ idr <- runIO $ doesFileExist idrp
54− lidr <- doesFileExist lidrp
55+ lidr <- runIO $ doesFileExist lidrp
55-- when idr $ putStrLn $ idrp ++ " ok"
56-- when idr $ putStrLn $ idrp ++ " ok"
56-- when lidr $ putStrLn $ lidrp ++ " ok"
57-- when lidr $ putStrLn $ lidrp ++ " ok"
57-- when ibc $ putStrLn $ ibcp ++ " ok"
58-- when ibc $ putStrLn $ ibcp ++ " ok"
src/Idris/Interactive.hsnew file+341
@@ -0,0 +1,341 @@
1+{-# LANGUAGE PatternGuards #-}
2+
3+module Idris.Interactive(caseSplitAt, addClauseFrom, addProofClauseFrom,
4+ addMissing, makeWith, doProofSearch,
5+ makeLemma) where
6+
7+{- Bits and pieces for editing source files interactively, called from
8+ the REPL -}
9+
10+import Idris.Core.TT
11+import Idris.Core.Evaluate
12+import Idris.CaseSplit
13+import Idris.AbsSyntax
14+import Idris.ElabDecls
15+import Idris.Error
16+import Idris.Delaborate
17+import Idris.Output
18+import Idris.IdeSlave hiding (IdeSlaveCommand(..))
19+
20+import Util.Pretty
21+import Util.System
22+
23+import System.FilePath
24+import System.Directory
25+import System.IO
26+import Data.Char
27+import Data.Maybe (fromMaybe)
28+
29+
30+caseSplitAt :: Handle -> FilePath -> Bool -> Int -> Name -> Idris ()
31+caseSplitAt h fn updatefile l n
32+ = do src <- runIO $ readFile fn
33+ res <- splitOnLine l n fn
34+ iLOG (showSep "\n" (map show res))
35+ let (before, (ap : later)) = splitAt (l-1) (lines src)
36+ res' <- replaceSplits ap res
37+ let new = concat res'
38+ if updatefile
39+ then do let fb = fn ++ "~" -- make a backup!
40+ runIO $ writeFile fb (unlines before ++ new ++ unlines later)
41+ runIO $ copyFile fb fn
42+ else -- do ihputStrLn h (show res)
43+ ihPrintResult h new
44+
45+addClauseFrom :: Handle -> FilePath -> Bool -> Int -> Name -> Idris ()
46+addClauseFrom h fn updatefile l n
47+ = do src <- runIO $ readFile fn
48+ let (before, tyline : later) = splitAt (l-1) (lines src)
49+ let indent = getIndent 0 (show n) tyline
50+ cl <- getClause l n fn
51+ -- add clause before first blank line in 'later'
52+ let (nonblank, rest) = span (not . all isSpace) (tyline:later)
53+ if updatefile
54+ then do let fb = fn ++ "~"
55+ runIO $ writeFile fb (unlines (before ++ nonblank) ++
56+ replicate indent ' ' ++
57+ cl ++ "\n" ++
58+ unlines rest)
59+ runIO $ copyFile fb fn
60+ else ihPrintResult h cl
61+ where
62+ getIndent i n [] = 0
63+ getIndent i n xs | take 9 xs == "instance " = i
64+ getIndent i n xs | take (length n) xs == n = i
65+ getIndent i n (x : xs) = getIndent (i + 1) n xs
66+
67+addProofClauseFrom :: Handle -> FilePath -> Bool -> Int -> Name -> Idris ()
68+addProofClauseFrom h fn updatefile l n
69+ = do src <- runIO $ readFile fn
70+ let (before, tyline : later) = splitAt (l-1) (lines src)
71+ let indent = getIndent 0 (show n) tyline
72+ cl <- getProofClause l n fn
73+ -- add clause before first blank line in 'later'
74+ let (nonblank, rest) = span (not . all isSpace) (tyline:later)
75+ if updatefile
76+ then do let fb = fn ++ "~"
77+ runIO $ writeFile fb (unlines (before ++ nonblank) ++
78+ replicate indent ' ' ++
79+ cl ++ "\n" ++
80+ unlines rest)
81+ runIO $ copyFile fb fn
82+ else ihPrintResult h cl
83+ where
84+ getIndent i n [] = 0
85+ getIndent i n xs | take (length n) xs == n = i
86+ getIndent i n (x : xs) = getIndent (i + 1) n xs
87+
88+addMissing :: Handle -> FilePath -> Bool -> Int -> Name -> Idris ()
89+addMissing h fn updatefile l n
90+ = do src <- runIO $ readFile fn
91+ let (before, tyline : later) = splitAt (l-1) (lines src)
92+ let indent = getIndent 0 (show n) tyline
93+ i <- getIState
94+ cl <- getInternalApp fn l
95+ let n' = getAppName cl
96+
97+ extras <- case lookupCtxt n' (idris_patdefs i) of
98+ [] -> return ""
99+ [(_, tms)] -> do tms' <- nameMissing tms
100+ showNew (show n ++ "_rhs") 1 indent tms'
101+ let (nonblank, rest) = span (not . all isSpace) (tyline:later)
102+ if updatefile
103+ then do let fb = fn ++ "~"
104+ runIO $ writeFile fb (unlines (before ++ nonblank)
105+ ++ extras ++ unlines rest)
106+ runIO $ copyFile fb fn
107+ else ihPrintResult h extras
108+ where showPat = show . stripNS
109+ stripNS tm = mapPT dens tm where
110+ dens (PRef fc n) = PRef fc (nsroot n)
111+ dens t = t
112+
113+ nsroot (NS n _) = nsroot n
114+ nsroot (SN (WhereN _ _ n)) = nsroot n
115+ nsroot n = n
116+
117+ getAppName (PApp _ r _) = getAppName r
118+ getAppName (PRef _ r) = r
119+ getAppName _ = n
120+
121+ showNew nm i ind (tm : tms)
122+ = do (nm', i') <- getUniq nm i
123+ rest <- showNew nm i' ind tms
124+ return (replicate ind ' ' ++
125+ showPat tm ++ " = ?" ++ nm' ++
126+ "\n" ++ rest)
127+ showNew nm i _ [] = return ""
128+
129+ getIndent i n [] = 0
130+ getIndent i n xs | take (length n) xs == n = i
131+ getIndent i n (x : xs) = getIndent (i + 1) n xs
132+
133+
134+makeWith :: Handle -> FilePath -> Bool -> Int -> Name -> Idris ()
135+makeWith h fn updatefile l n
136+ = do src <- runIO $ readFile fn
137+ let (before, tyline : later) = splitAt (l-1) (lines src)
138+ let ind = getIndent tyline
139+ let with = mkWith tyline n
140+ -- add clause before first blank line in 'later',
141+ -- or (TODO) before first line with same indentation as tyline
142+ let (nonblank, rest) = span (\x -> not (all isSpace x) &&
143+ not (ind == getIndent x)) later
144+ if updatefile then
145+ do let fb = fn ++ "~"
146+ runIO $ writeFile fb (unlines (before ++ nonblank)
147+ ++ with ++ "\n" ++
148+ unlines rest)
149+ runIO $ copyFile fb fn
150+ else ihPrintResult h with
151+ where getIndent s = length (takeWhile isSpace s)
152+
153+
154+doProofSearch :: Handle -> FilePath -> Bool -> Bool ->
155+ Int -> Name -> [Name] -> Maybe Int -> Idris ()
156+doProofSearch h fn updatefile rec l n hints Nothing
157+ = doProofSearch h fn updatefile rec l n hints (Just 10)
158+doProofSearch h fn updatefile rec l n hints (Just depth)
159+ = do src <- runIO $ readFile fn
160+ let (before, tyline : later) = splitAt (l-1) (lines src)
161+ ctxt <- getContext
162+ mn <- case lookupNames n ctxt of
163+ [x] -> return x
164+ [] -> return n
165+ ns -> ierror (CantResolveAlts ns)
166+ i <- getIState
167+ let (top, envlen, _) = case lookup mn (idris_metavars i) of
168+ Just (t, e, False) -> (t, e, False)
169+ _ -> (Nothing, 0, True)
170+ let fc = fileFC fn
171+ let body t = PProof [Try (TSeq Intros (ProofSearch rec False depth t hints))
172+ (ProofSearch rec False depth t hints)]
173+ let def = PClause fc mn (PRef fc mn) [] (body top) []
174+ newmv <- idrisCatch
175+ (do elabDecl' EAll toplevel (PClauses fc [] mn [def])
176+ (tm, ty) <- elabVal toplevel False (PRef fc mn)
177+ ctxt <- getContext
178+ i <- getIState
179+ return . flip displayS "" . renderPretty 1.0 80 $
180+ pprintPTerm defaultPPOption [] [] (idris_infixes i)
181+ (stripNS
182+ (dropCtxt envlen
183+ (delab i (specialise ctxt [] [(mn, 1)] tm)))))
184+ (\e -> return ("?" ++ show n))
185+ if updatefile then
186+ do let fb = fn ++ "~"
187+ runIO $ writeFile fb (unlines before ++
188+ updateMeta False tyline (show n) newmv ++ "\n"
189+ ++ unlines later)
190+ runIO $ copyFile fb fn
191+ else ihPrintResult h newmv
192+ where dropCtxt 0 sc = sc
193+ dropCtxt i (PPi _ _ _ sc) = dropCtxt (i - 1) sc
194+ dropCtxt i (PLet _ _ _ sc) = dropCtxt (i - 1) sc
195+ dropCtxt i (PLam _ _ sc) = dropCtxt (i - 1) sc
196+ dropCtxt _ t = t
197+
198+ stripNS tm = mapPT dens tm where
199+ dens (PRef fc n) = PRef fc (nsroot n)
200+ dens t = t
201+
202+ nsroot (NS n _) = nsroot n
203+ nsroot (SN (WhereN _ _ n)) = nsroot n
204+ nsroot n = n
205+
206+updateMeta brack ('?':cs) n new
207+ | length cs >= length n
208+ = case splitAt (length n) cs of
209+ (mv, c:cs) ->
210+ if ((isSpace c || c == ')' || c == '}') && mv == n)
211+ then addBracket brack new ++ (c : cs)
212+ else '?' : mv ++ c : updateMeta True cs n new
213+ (mv, []) -> if (mv == n) then addBracket brack new else '?' : mv
214+updateMeta brack ('=':cs) n new = '=':updateMeta False cs n new
215+updateMeta brack (c:cs) n new
216+ = c : updateMeta (brack || not (isSpace c)) cs n new
217+updateMeta brack [] n new = ""
218+
219+checkProv line n = isProv' False line n
220+ where
221+ isProv' p cs n | take (length n) cs == n = p
222+ isProv' _ ('?':cs) n = isProv' False cs n
223+ isProv' _ ('{':cs) n = isProv' True cs n
224+ isProv' _ ('}':cs) n = isProv' True cs n
225+ isProv' p (_:cs) n = isProv' p cs n
226+ isProv' _ [] n = False
227+
228+addBracket False new = new
229+addBracket True new@('(':xs) | last xs == ')' = new
230+addBracket True new | any isSpace new = '(' : new ++ ")"
231+ | otherwise = new
232+
233+
234+makeLemma :: Handle -> FilePath -> Bool -> Int -> Name -> Idris ()
235+makeLemma h fn updatefile l n
236+ = do src <- runIO $ readFile fn
237+ let (before, tyline : later) = splitAt (l-1) (lines src)
238+
239+ -- if the name is in braces, rather than preceded by a ?, treat it
240+ -- as a lemma in a provisional definition
241+
242+ let isProv = checkProv tyline (show n)
243+
244+ ctxt <- getContext
245+ mty <- case lookupTyName n ctxt of
246+ [(_,t)] -> return t
247+ [] -> ierror (NoSuchVariable n)
248+ ns -> ierror (CantResolveAlts (map fst ns))
249+ i <- getIState
250+
251+ if (not isProv) then do
252+ let skip = guessImps (tt_ctxt i) mty
253+
254+ let lem = show n ++ " : " ++ show (stripMNBind skip (delab i mty))
255+ let lem_app = show n ++ appArgs skip mty
256+
257+ if updatefile then
258+ do let fb = fn ++ "~"
259+ runIO $ writeFile fb (addLem before tyline lem lem_app later)
260+ runIO $ copyFile fb fn
261+ else case idris_outputmode i of
262+ RawOutput -> ihPrintResult h $ lem ++ "\n" ++ lem_app
263+ IdeSlave n ->
264+ let good = SexpList [SymbolAtom "ok",
265+ SexpList [SymbolAtom "metavariable-lemma",
266+ SexpList [SymbolAtom "replace-metavariable",
267+ StringAtom lem_app],
268+ SexpList [SymbolAtom "definition-type",
269+ StringAtom lem]]]
270+ in runIO . hPutStrLn h $ convSExp "return" good n
271+
272+ else do -- provisional definition
273+ let lem_app = show n ++ appArgs [] mty ++
274+ " = ?" ++ show n ++ "_rhs"
275+ if updatefile then
276+ do let fb = fn ++ "~"
277+ runIO $ writeFile fb (addProv before tyline lem_app later)
278+ runIO $ copyFile fb fn
279+ else case idris_outputmode i of
280+ RawOutput -> ihPrintResult h $ lem_app
281+ IdeSlave n ->
282+ let good = SexpList [SymbolAtom "ok",
283+ SexpList [SymbolAtom "provisional-definition-lemma",
284+ SexpList [SymbolAtom "definition-clause",
285+ StringAtom lem_app]]]
286+ in runIO . hPutStrLn h $ convSExp "return" good n
287+
288+ where getIndent s = length (takeWhile isSpace s)
289+
290+ appArgs skip (Bind n@(UN c) (Pi _) sc)
291+ | thead c /= '_' && n `notElem` skip
292+ = " " ++ show n ++ appArgs skip sc
293+ appArgs skip (Bind _ (Pi _) sc) = appArgs skip sc
294+ appArgs skip _ = ""
295+
296+ stripMNBind skip (PPi b n@(UN c) ty sc)
297+ | thead c /= '_' &&
298+ n `notElem` skip = PPi b n ty (stripMNBind skip sc)
299+ stripMNBind skip (PPi b _ ty sc) = stripMNBind skip sc
300+ stripMNBind skip t = t
301+
302+ -- Guess which binders should be implicits in the generated lemma.
303+ -- Make them implicit if they appear guarded by a top level constructor,
304+ -- or at the top level themselves.
305+ guessImps :: Context -> Term -> [Name]
306+ guessImps ctxt (Bind n (Pi _) sc)
307+ | guarded ctxt n (substV (P Bound n Erased) sc)
308+ = n : guessImps ctxt sc
309+ | otherwise = guessImps ctxt sc
310+ guessImps ctxt _ = []
311+
312+ guarded ctxt n (P _ n' _) | n == n' = True
313+ guarded ctxt n ap@(App _ _)
314+ | (P _ f _, args) <- unApply ap,
315+ isConName f ctxt = any (guarded ctxt n) args
316+-- guarded ctxt n (Bind (UN cn) (Pi t) sc) -- ignore shadows
317+-- | thead cn /= '_' = guarded ctxt n t || guarded ctxt n sc
318+ guarded ctxt n (Bind _ (Pi t) sc)
319+ = guarded ctxt n t || guarded ctxt n sc
320+ guarded ctxt n _ = False
321+
322+ blank = all isSpace
323+
324+ addLem before tyline lem lem_app later
325+ = let (bef_end, blankline : bef_start)
326+ = case span (not . blank) (reverse before) of
327+ (bef, []) -> (bef, "" : [])
328+ x -> x
329+ mvline = updateMeta False tyline (show n) lem_app in
330+ unlines $ reverse bef_start ++
331+ [blankline, lem, blankline] ++
332+ reverse bef_end ++ mvline : later
333+
334+ addProv before tyline lem_app later
335+ = let (later_bef, blankline : later_end)
336+ = case span (not . blank) later of
337+ (bef, []) -> (bef, "" : [])
338+ x -> x in
339+ unlines $ before ++ tyline :
340+ (later_bef ++ [blankline, lem_app, blankline] ++
341+ later_end)
src/Idris/Output.hs+53−71
@@ -11,8 +11,13 @@ import Idris.IdeSlave
11import Util.Pretty
11import Util.Pretty
12import Util.ScreenSize (getScreenWidth)
12import Util.ScreenSize (getScreenWidth)
13
13
14+import Debug.Trace
15+
14import System.IO (stdout, Handle, hPutStrLn)
16import System.IO (stdout, Handle, hPutStrLn)
15
17
18+import Data.List (nub)
19+import Data.Maybe (fromMaybe)
20+
16pshow :: IState -> Err -> String
21pshow :: IState -> Err -> String
17pshow ist err = displayDecorated (consoleDecorate ist) .
22pshow ist err = displayDecorated (consoleDecorate ist) .
18 renderPretty 1.0 80 .
23 renderPretty 1.0 80 .
@@ -23,7 +28,9 @@ ihWarn h fc err = do i <- getIState
23 case idris_outputmode i of
28 case idris_outputmode i of
24 RawOutput ->
29 RawOutput ->
25 do err' <- iRender . fmap (fancifyAnnots i) $
30 do err' <- iRender . fmap (fancifyAnnots i) $
31+ if fc_fname fc /= ""
26− text (show fc) <> colon <//> err
32+ then text (show fc) <> colon <//> err
33+ else err
27 runIO . hPutStrLn h $ displayDecorated (consoleDecorate i) err'
34 runIO . hPutStrLn h $ displayDecorated (consoleDecorate i) err'
28 IdeSlave n ->
35 IdeSlave n ->
29 do err' <- iRender . fmap (fancifyAnnots i) $ err
36 do err' <- iRender . fmap (fancifyAnnots i) $ err
@@ -47,16 +54,6 @@ iRender d = do w <- getWidth
47 | otherwise -> do width <- runIO getScreenWidth
54 | otherwise -> do width <- runIO getScreenWidth
48 return $ renderPretty 0.8 width d
55 return $ renderPretty 0.8 width d
49
56
50−ihPrintResult :: Handle -> String -> Idris ()
51−ihPrintResult h s = do i <- getIState
52− case idris_outputmode i of
53− RawOutput -> case s of
54− "" -> return ()
55− s -> runIO $ hPutStrLn h s
56− IdeSlave n ->
57− let good = SexpList [SymbolAtom "ok", toSExp s] in
58− runIO $ hPutStrLn h $ convSExp "return" good n
59−
60-- | Write a pretty-printed term to the console with semantic coloring
57-- | Write a pretty-printed term to the console with semantic coloring
61consoleDisplayAnnotated :: Handle -> Doc OutputAnnotation -> Idris ()
58consoleDisplayAnnotated :: Handle -> Doc OutputAnnotation -> Idris ()
62consoleDisplayAnnotated h output = do ist <- getIState
59consoleDisplayAnnotated h output = do ist <- getIState
@@ -65,35 +62,20 @@ consoleDisplayAnnotated h output = do ist <- getIState
65 displayDecorated (consoleDecorate ist) $
62 displayDecorated (consoleDecorate ist) $
66 rendered
63 rendered
67
64
68−
69−-- | Write pretty-printed output to IDESlave with semantic annotations
70−ideSlaveReturnAnnotated :: Integer -> Handle -> Doc OutputAnnotation -> Idris ()
71−ideSlaveReturnAnnotated n h out = do ist <- getIState
72− (str, spans) <- fmap displaySpans .
73− iRender .
74− fmap (fancifyAnnots ist) $
75− out
76− let good = [SymbolAtom "ok", toSExp str, toSExp spans]
77− runIO . hPutStrLn h $ convSExp "return" good n
78−
79ihPrintTermWithType :: Handle -> Doc OutputAnnotation -> Doc OutputAnnotation -> Idris ()
65ihPrintTermWithType :: Handle -> Doc OutputAnnotation -> Doc OutputAnnotation -> Idris ()
80−ihPrintTermWithType h tm ty = do ist <- getIState
66+ihPrintTermWithType h tm ty = ihRenderResult h (tm <+> colon <+> align ty)
81− let output = tm <+> colon <+> ty
82− case idris_outputmode ist of
83− RawOutput -> consoleDisplayAnnotated h output
84− IdeSlave n -> ideSlaveReturnAnnotated n h output
85
67
86-- | Pretty-print a collection of overloadings to REPL or IDESlave - corresponds to :t name
68-- | Pretty-print a collection of overloadings to REPL or IDESlave - corresponds to :t name
87ihPrintFunTypes :: Handle -> [(Name, Bool)] -> Name -> [(Name, PTerm)] -> Idris ()
69ihPrintFunTypes :: Handle -> [(Name, Bool)] -> Name -> [(Name, PTerm)] -> Idris ()
88ihPrintFunTypes h bnd n [] = ihPrintError h $ "No such variable " ++ show n
70ihPrintFunTypes h bnd n [] = ihPrintError h $ "No such variable " ++ show n
89−ihPrintFunTypes h bnd n overloads = do imp <- impShow
71+ihPrintFunTypes h bnd n overloads = do ist <- getIState
90− ist <- getIState
72+ let ppo = ppOptionIst ist
73+ let infixes = idris_infixes ist
91− let output = vsep (map (uncurry (ppOverload imp)) overloads)
74+ let output = vsep (map (uncurry (ppOverload ppo infixes)) overloads)
92− case idris_outputmode ist of
75+ ihRenderResult h output
93− RawOutput -> consoleDisplayAnnotated h output
94− IdeSlave n -> ideSlaveReturnAnnotated n h output
95 where fullName n = prettyName True bnd n
76 where fullName n = prettyName True bnd n
77+ ppOverload ppo infixes n tm =
96− ppOverload imp n tm = fullName n <+> colon <+> align (pprintPTerm imp bnd [] tm)
78+ fullName n <+> colon <+> align (pprintPTerm ppo bnd [] infixes tm)
97
79
98ihRenderResult :: Handle -> Doc OutputAnnotation -> Idris ()
80ihRenderResult :: Handle -> Doc OutputAnnotation -> Idris ()
99ihRenderResult h d = do ist <- getIState
81ihRenderResult h d = do ist <- getIState
@@ -101,51 +83,45 @@ ihRenderResult h d = do ist <- getIState
101 RawOutput -> consoleDisplayAnnotated h d
83 RawOutput -> consoleDisplayAnnotated h d
102 IdeSlave n -> ideSlaveReturnAnnotated n h d
84 IdeSlave n -> ideSlaveReturnAnnotated n h d
103
85
104−fancifyAnnots :: IState -> OutputAnnotation -> OutputAnnotation
86+ideSlaveReturnWithStatus :: String -> Integer -> Handle -> Doc OutputAnnotation -> Idris ()
105−fancifyAnnots ist annot@(AnnName n _ _ _) =
87+ideSlaveReturnWithStatus status n h out = do
106− do let ctxt = tt_ctxt ist
88+ ist <- getIState
107− docs = docOverview ist n
89+ (str, spans) <- fmap displaySpans .
108− ty = Just (getTy ist n)
90+ iRender .
109− case () of
91+ fmap (fancifyAnnots ist) $
110− _ | isDConName n ctxt -> AnnName n (Just DataOutput) docs ty
92+ out
111− _ | isFnName n ctxt -> AnnName n (Just FunOutput) docs ty
93+ let good = [SymbolAtom status, toSExp str, toSExp spans]
112− _ | isTConName n ctxt -> AnnName n (Just TypeOutput) docs ty
94+ runIO . hPutStrLn h $ convSExp "return" good n
113− _ | isMetavarName n ist -> AnnName n (Just MetavarOutput) docs ty
95+
114− _ | otherwise -> annot
96+
115− where docOverview :: IState -> Name -> Maybe String -- pretty-print first paragraph of docs
97+-- | Write pretty-printed output to IDESlave with semantic annotations
116− docOverview ist n = do docs <- lookupCtxtExact n (idris_docstrings ist)
98+ideSlaveReturnAnnotated :: Integer -> Handle -> Doc OutputAnnotation -> Idris ()
117− let o = overview (fst docs)
99+ideSlaveReturnAnnotated = ideSlaveReturnWithStatus "ok"
118− -- TODO make width configurable
119− out = displayS . renderPretty 1.0 50 $ renderDocstring o
120− return (out "")
121− getTy :: IState -> Name -> String -- fails if name not already extant!
122− getTy ist n = let theTy = pprintPTerm (opt_showimp (idris_options ist)) [] [] $
123− delabTy ist n
124− in (displayS . renderPretty 1.0 50 $ theTy) ""
125−fancifyAnnots _ annot = annot
126
100
127-- | Show an error with semantic highlighting
101-- | Show an error with semantic highlighting
128ihRenderError :: Handle -> Doc OutputAnnotation -> Idris ()
102ihRenderError :: Handle -> Doc OutputAnnotation -> Idris ()
129ihRenderError h e = do ist <- getIState
103ihRenderError h e = do ist <- getIState
130 case idris_outputmode ist of
104 case idris_outputmode ist of
131 RawOutput -> consoleDisplayAnnotated h e
105 RawOutput -> consoleDisplayAnnotated h e
132− IdeSlave n -> do
106+ IdeSlave n -> ideSlaveReturnWithStatus "error" n h e
133− (str, spans) <- fmap displaySpans .
107+
134− iRender .
108+ihPrintWithStatus :: String -> Handle -> String -> Idris ()
135− fmap (fancifyAnnots ist) $
109+ihPrintWithStatus status h s = do
136− e
110+ i <- getIState
111+ case idris_outputmode i of
112+ RawOutput -> case s of
113+ "" -> return ()
114+ s -> runIO $ hPutStrLn h s
115+ IdeSlave n ->
137− let good = [SymbolAtom "error", toSExp str, toSExp spans]
116+ let good = SexpList [SymbolAtom status, toSExp s] in
138− runIO . hPutStrLn h $ convSExp "return" good n
117+ runIO $ hPutStrLn h $ convSExp "return" good n
118+
119+
120+ihPrintResult :: Handle -> String -> Idris ()
121+ihPrintResult = ihPrintWithStatus "ok"
139
122
140ihPrintError :: Handle -> String -> Idris ()
123ihPrintError :: Handle -> String -> Idris ()
141−ihPrintError h s = do i <- getIState
124+ihPrintError = ihPrintWithStatus "error"
142− case idris_outputmode i of
143− RawOutput -> case s of
144− "" -> return ()
145− s -> runIO $ hPutStrLn h s
146− IdeSlave n ->
147− let good = SexpList [SymbolAtom "error", toSExp s] in
148− runIO . hPutStrLn h $ convSExp "return" good n
149
125
150ihputStrLn :: Handle -> String -> Idris ()
126ihputStrLn :: Handle -> String -> Idris ()
151ihputStrLn h s = do i <- getIState
127ihputStrLn h s = do i <- getIState
@@ -171,3 +147,9 @@ iputGoal g = do i <- getIState
171 RawOutput -> runIO $ putStrLn (displayDecorated (consoleDecorate i) g)
147 RawOutput -> runIO $ putStrLn (displayDecorated (consoleDecorate i) g)
172 IdeSlave n -> runIO . putStrLn $
148 IdeSlave n -> runIO . putStrLn $
173 convSExp "write-goal" (displayS (fmap (fancifyAnnots i) g) "") n
149 convSExp "write-goal" (displayS (fmap (fancifyAnnots i) g) "") n
150+
151+-- | Warn about totality problems without failing to compile
152+warnTotality :: Idris ()
153+warnTotality = do ist <- getIState
154+ mapM_ (warn ist) (nub (idris_totcheckfail ist))
155+ where warn ist (fc, e) = iWarn fc (pprintErr ist (Msg e))
src/Idris/ParseData.hs+4−3
@@ -42,11 +42,12 @@ Record ::=
42 DocComment Accessibility? 'record' FnName TypeSig 'where' OpenBlock Constructor KeepTerminator CloseBlock;
42 DocComment Accessibility? 'record' FnName TypeSig 'where' OpenBlock Constructor KeepTerminator CloseBlock;
43-}
43-}
44record :: SyntaxInfo -> IdrisParser PDecl
44record :: SyntaxInfo -> IdrisParser PDecl
45−record syn = do (doc, acc) <- try (do
45+record syn = do (doc, acc, opts) <- try (do
46 doc <- option noDocs docComment
46 doc <- option noDocs docComment
47 acc <- optional accessibility
47 acc <- optional accessibility
48+ opts <- dataOpts []
48 reserved "record"
49 reserved "record"
49− return (doc, acc))
50+ return (doc, acc, opts))
50 fc <- getFC
51 fc <- getFC
51 tyn_in <- fnName
52 tyn_in <- fnName
52 lchar ':'
53 lchar ':'
@@ -59,7 +60,7 @@ record syn = do (doc, acc) <- try (do
59 syn_namespace syn }
60 syn_namespace syn }
60 let fns = getRecNames rsyn cty
61 let fns = getRecNames rsyn cty
61 mapM_ (\n -> addAcc n acc) fns
62 mapM_ (\n -> addAcc n acc) fns
62− return $ PRecord (fst doc) rsyn fc tyn ty cdoc cn cty
63+ return $ PRecord (fst doc) rsyn fc tyn ty opts cdoc cn cty
63 <?> "record type declaration"
64 <?> "record type declaration"
64 where
65 where
65 getRecNames :: SyntaxInfo -> PTerm -> [Name]
66 getRecNames :: SyntaxInfo -> PTerm -> [Name]
src/Idris/ParseExpr.hs+200−171
@@ -54,14 +54,22 @@ fullExpr syn = do x <- expr syn
54 return $ debindApp syn (desugar syn i x)
54 return $ debindApp syn (desugar syn i x)
55
55
56
56
57−{- |Parses an expression
57+{- | Parses an expression
58@
58@
59− Expr ::= Expr';
59+ Expr ::= Pi
60@
60@
61−-}
61+ -}
62expr :: SyntaxInfo -> IdrisParser PTerm
62expr :: SyntaxInfo -> IdrisParser PTerm
63+expr = pi
64+
65+{- | Parses an expression with possible operator applied
66+@
67+ OpExpr ::= {- Expression Parser with Operators based on Expr' -};
68+@
69+-}
70+opExpr :: SyntaxInfo -> IdrisParser PTerm
63−expr syn = do i <- get
71+opExpr syn = do i <- get
64− buildExpressionParser (table (idris_infixes i)) (expr' syn)
72+ buildExpressionParser (table (idris_infixes i)) (expr' syn)
65
73
66{- | Parses either an internally defined expression or
74{- | Parses either an internally defined expression or
67 a user-defined one
75 a user-defined one
@@ -70,16 +78,10 @@ Expr' ::= "External (User-defined) Syntax"
70 | InternalExpr;
78 | InternalExpr;
71@
79@
72 -}
80 -}
73−expr' syn = doexpr' syn
74−-- = do l <- restOfLine
75−-- f <- getFC
76−-- e <- trace (show (f, l)) $ doexpr' syn
77−-- return e
78−
79−doexpr' :: SyntaxInfo -> IdrisParser PTerm
81+expr' :: SyntaxInfo -> IdrisParser PTerm
80−doexpr' syn = try (externalExpr syn)
82+expr' syn = try (externalExpr syn)
81− <|> internalExpr syn
83+ <|> internalExpr syn
82− <?> "expression"
84+ <?> "expression"
83
85
84{- | Parses a user-defined expression -}
86{- | Parses a user-defined expression -}
85externalExpr :: SyntaxInfo -> IdrisParser PTerm
87externalExpr :: SyntaxInfo -> IdrisParser PTerm
@@ -190,37 +192,32 @@ extension syn (Rule ssym ptm _)
190{- | Parses a (normal) built-in expression
192{- | Parses a (normal) built-in expression
191@
193@
192InternalExpr ::=
194InternalExpr ::=
193− App
194− | MatchApp
195− | UnifyLog
195+ UnifyLog
196 | RecordType
196 | RecordType
197 | SimpleExpr
197 | SimpleExpr
198 | Lambda
198 | Lambda
199 | QuoteGoal
199 | QuoteGoal
200 | Let
200 | Let
201 | RewriteTerm
201 | RewriteTerm
202− | Pi
203 | CaseExpr
202 | CaseExpr
204 | DoBlock
203 | DoBlock
204+ | App
205 ;
205 ;
206@
206@
207-}
207-}
208internalExpr :: SyntaxInfo -> IdrisParser PTerm
208internalExpr :: SyntaxInfo -> IdrisParser PTerm
209internalExpr syn =
209internalExpr syn =
210− try (app syn)
211− <|> try (matchApp syn)
212− <|> try (unifyLog syn)
210+ unifyLog syn
213− <|> try (disamb syn)
211+ <|> disamb syn
214− <|> try (noImplicits syn)
212+ <|> noImplicits syn
215 <|> recordType syn
213 <|> recordType syn
216 <|> lambda syn
214 <|> lambda syn
217 <|> quoteGoal syn
215 <|> quoteGoal syn
218 <|> let_ syn
216 <|> let_ syn
219 <|> rewriteTerm syn
217 <|> rewriteTerm syn
220− <|> try (pi syn)
221 <|> doBlock syn
218 <|> doBlock syn
222 <|> caseExpr syn
219 <|> caseExpr syn
223− <|> simpleExpr syn
220+ <|> app syn
224 <?> "expression"
221 <?> "expression"
225
222
226{- | Parses a case expression
223{- | Parses a case expression
@@ -278,30 +275,28 @@ tacticsExpr syn = do reserved "tactics"
278{- | Parses a simple expression
275{- | Parses a simple expression
279@
276@
280SimpleExpr ::=
277SimpleExpr ::=
281− '![' Term ']'
278+ {- External (User-defined) Simple Expression -}
282 | '?' Name
279 | '?' Name
283 | % 'instance'
280 | % 'instance'
284 | 'refl' ('{' Expr '}')?
281 | 'refl' ('{' Expr '}')?
285 | ProofExpr
282 | ProofExpr
286 | TacticsExpr
283 | TacticsExpr
287 | FnName
284 | FnName
285+ | Idiom
288 | List
286 | List
289− | Comprehension
290 | Alt
287 | Alt
291− | Idiom
292− | '(' Bracketed
288+ | Bracketed
293 | Constant
289 | Constant
294 | Type
290 | Type
295 | '_|_'
291 | '_|_'
296 | '_'
292 | '_'
297− | {- External (User-defined) Simple Expression -}
298 ;
293 ;
299@
294@
300-}
295-}
301simpleExpr :: SyntaxInfo -> IdrisParser PTerm
296simpleExpr :: SyntaxInfo -> IdrisParser PTerm
302simpleExpr syn =
297simpleExpr syn =
303− {-try (do symbol "!["; t <- term; lchar ']'; return $ PQuote t)
298+ try (simpleExternalExpr syn)
304− <|>-} do x <- try (lchar '?' *> name); return (PMetavar x)
299+ <|> do x <- try (lchar '?' *> name); return (PMetavar x)
305 <|> do lchar '%'; fc <- getFC; reserved "instance"; return (PResolveTC fc)
300 <|> do lchar '%'; fc <- getFC; reserved "instance"; return (PResolveTC fc)
306 <|> do reserved "refl"; fc <- getFC;
301 <|> do reserved "refl"; fc <- getFC;
307 tm <- option Placeholder (do lchar '{'; t <- expr syn; lchar '}';
302 tm <- option Placeholder (do lchar '{'; t <- expr syn; lchar '}';
@@ -311,36 +306,40 @@ simpleExpr syn =
311 <|> proofExpr syn
306 <|> proofExpr syn
312 <|> tacticsExpr syn
307 <|> tacticsExpr syn
313 <|> do reserved "Type"; return PType
308 <|> do reserved "Type"; return PType
314− <|> try (do c <- constant
309+ <|> do c <- constant
315− fc <- getFC
310+ fc <- getFC
316− return (modifyConst syn fc (PConstant c)))
311+ return (modifyConst syn fc (PConstant c))
317− <|> try (do symbol "'"; fc <- getFC; str <- name
312+ <|> do symbol "'"; fc <- getFC; str <- name
318− return (PApp fc (PRef fc (sUN "Symbol_"))
313+ return (PApp fc (PRef fc (sUN "Symbol_"))
319− [pexp (PConstant (Str (show str)))]))
314+ [pexp (PConstant (Str (show str)))])
320 <|> do fc <- getFC
315 <|> do fc <- getFC
321 x <- fnName
316 x <- fnName
322 return (PRef fc x)
317 return (PRef fc x)
323− <|> try (listExpr syn)
324− <|> try (comprehension syn)
325− <|> alt syn
326 <|> idiom syn
318 <|> idiom syn
319+ <|> listExpr syn
320+ <|> alt syn
327 <|> do lchar '!'
321 <|> do lchar '!'
328 s <- simpleExpr syn
322 s <- simpleExpr syn
329 fc <- getFC
323 fc <- getFC
330 return (PAppBind fc s [])
324 return (PAppBind fc s [])
331− <|> do lchar '('
332− bracketed (disallowImp syn)
325+ <|> bracketed (disallowImp syn)
333 <|> do symbol "_|_"
326 <|> do symbol "_|_"
334 fc <- getFC
327 fc <- getFC
335 return (PFalse fc)
328 return (PFalse fc)
336 <|> do lchar '_'; return Placeholder
329 <|> do lchar '_'; return Placeholder
337− <|> simpleExternalExpr syn
338 <?> "expression"
330 <?> "expression"
339
331
340−
332+{- |Parses an expression in braces
333+@
334+Bracketed ::= '(' Bracketed'
335+@
336+ -}
337+bracketed :: SyntaxInfo -> IdrisParser PTerm
338+bracketed syn = do lchar '(' <?> "parenthesized expression"
339+ bracketed' syn
341{- |Parses the rest of an expression in braces
340{- |Parses the rest of an expression in braces
342@
341@
343−Bracketed ::=
342+Bracketed' ::=
344 ')'
343 ')'
345 | Expr ')'
344 | Expr ')'
346 | ExprList ')'
345 | ExprList ')'
@@ -351,8 +350,8 @@ Bracketed ::=
351 ;
350 ;
352@
351@
353-}
352-}
354−bracketed :: SyntaxInfo -> IdrisParser PTerm
353+bracketed' :: SyntaxInfo -> IdrisParser PTerm
355−bracketed syn =
354+bracketed' syn =
356 do lchar ')'
355 do lchar ')'
357 fc <- getFC
356 fc <- getFC
358 return $ PTrue fc TypeOrTerm
357 return $ PTrue fc TypeOrTerm
@@ -365,7 +364,7 @@ bracketed syn =
365 return (PDPair fc TypeOrTerm (PRef fc ln) lty r))
364 return (PDPair fc TypeOrTerm (PRef fc ln) lty r))
366 <|> try (do fc <- getFC; o <- operator; e <- expr syn; lchar ')'
365 <|> try (do fc <- getFC; o <- operator; e <- expr syn; lchar ')'
367 -- No prefix operators! (bit of a hack here...)
366 -- No prefix operators! (bit of a hack here...)
368− if (o == "-" || o == "!")
367+ if (o == "-" || o == "!")
369 then fail "minus not allowed in section"
368 then fail "minus not allowed in section"
370 else return $ PLam (sMN 1000 "ARG") Placeholder
369 else return $ PLam (sMN 1000 "ARG") Placeholder
371 (PApp fc (PRef fc (sUN o)) [pexp (PRef fc (sMN 1000 "ARG")),
370 (PApp fc (PRef fc (sUN o)) [pexp (PRef fc (sMN 1000 "ARG")),
@@ -425,29 +424,6 @@ modifyConst syn fc (PConstant (BI x))
425 ]
424 ]
426modifyConst syn fc x = x
425modifyConst syn fc x = x
427
426
428−{- | Parses a list literal expression e.g. [1,2,3]
429−@
430−ListExpr ::=
431− '[' ExprList? ']'
432−;
433−@
434−@
435−ExprList ::=
436− Expr
437− | Expr ',' ExprList
438− ;
439−@
440− -}
441−listExpr :: SyntaxInfo -> IdrisParser PTerm
442−listExpr syn = do lchar '['; fc <- getFC; xs <- sepBy (expr syn) (lchar ','); lchar ']'
443− return (mkList fc xs)
444− <?> "list expression"
445− where
446− mkList :: FC -> [PTerm] -> PTerm
447− mkList fc [] = PRef fc (sUN "Nil")
448− mkList fc (x : xs) = PApp fc (PRef fc (sUN "::")) [pexp x, pexp (mkList fc xs)]
449−
450−
451{- | Parses an alternative expression
427{- | Parses an alternative expression
452@
428@
453 Alt ::= '(|' Expr_List '|)';
429 Alt ::= '(|' Expr_List '|)';
@@ -478,31 +454,13 @@ hsimpleExpr syn =
478 <|> simpleExpr syn
454 <|> simpleExpr syn
479 <?> "expression"
455 <?> "expression"
480
456
481−{- | Parses a matching application expression
482−@
483−MatchApp ::=
484− SimpleExpr '<==' FnName
485− ;
486−@
487−-}
488−matchApp :: SyntaxInfo -> IdrisParser PTerm
489−matchApp syn = do ty <- simpleExpr syn
490− symbol "<=="
491− fc <- getFC
492− f <- fnName
493− return (PLet (sMN 0 "match")
494− ty
495− (PMatchApp fc f)
496− (PRef fc (sMN 0 "match")))
497− <?> "matching application expression"
498−
499{- | Parses a unification log expression
457{- | Parses a unification log expression
500UnifyLog ::=
458UnifyLog ::=
501 '%' 'unifyLog' SimpleExpr
459 '%' 'unifyLog' SimpleExpr
502 ;
460 ;
503-}
461-}
504unifyLog :: SyntaxInfo -> IdrisParser PTerm
462unifyLog :: SyntaxInfo -> IdrisParser PTerm
505−unifyLog syn = do lchar '%'; reserved "unifyLog";
463+unifyLog syn = do try (lchar '%' *> reserved "unifyLog")
506 tm <- simpleExpr syn
464 tm <- simpleExpr syn
507 return (PUnifyLog tm)
465 return (PUnifyLog tm)
508 <?> "unification log expression"
466 <?> "unification log expression"
@@ -528,7 +486,7 @@ NoImplicits ::=
528@
486@
529-}
487-}
530noImplicits :: SyntaxInfo -> IdrisParser PTerm
488noImplicits :: SyntaxInfo -> IdrisParser PTerm
531−noImplicits syn = do lchar '%'; reserved "noImplicits";
489+noImplicits syn = do try (lchar '%' *> reserved "noImplicits")
532 tm <- simpleExpr syn
490 tm <- simpleExpr syn
533 return (PNoImplicits tm)
491 return (PNoImplicits tm)
534 <?> "no implicits expression"
492 <?> "no implicits expression"
@@ -537,7 +495,11 @@ noImplicits syn = do lchar '%'; reserved "noImplicits";
537@
495@
538App ::=
496App ::=
539 'mkForeign' Arg Arg*
497 'mkForeign' Arg Arg*
498+ | MatchApp
540− | SimpleExpr Arg+
499+ | SimpleExpr Arg*
500+ ;
501+MatchApp ::=
502+ SimpleExpr '<==' FnName
541 ;
503 ;
542@
504@
543-}
505-}
@@ -547,8 +509,6 @@ app syn = do f <- reserved "mkForeign"
547 fn <- arg syn
509 fn <- arg syn
548 args <- many (do notEndApp; arg syn)
510 args <- many (do notEndApp; arg syn)
549 i <- get
511 i <- get
550− -- mkForeign f args ==>
551− -- liftPrimIO (\w => mkForeignPrim f args w)
552 let ap = PApp fc (PRef fc (sUN "liftPrimIO"))
512 let ap = PApp fc (PRef fc (sUN "liftPrimIO"))
553 [pexp (PLam (sMN 0 "w")
513 [pexp (PLam (sMN 0 "w")
554 Placeholder
514 Placeholder
@@ -558,13 +518,20 @@ app syn = do f <- reserved "mkForeign"
558 return (dslify i ap)
518 return (dslify i ap)
559
519
560 <|> do f <- simpleExpr syn
520 <|> do f <- simpleExpr syn
521+ (do try $ symbol "<=="
522+ fc <- getFC
523+ ff <- fnName
524+ return (PLet (sMN 0 "match")
525+ f
526+ (PMatchApp fc ff)
527+ (PRef fc (sMN 0 "match")))
528+ <?> "matching application expression") <|> (do
561 fc <- getFC
529 fc <- getFC
562− args <- some (do notEndApp; arg syn)
563 i <- get
530 i <- get
531+ args <- many (do notEndApp; arg syn)
564−-- case f of
532+ case args of
565−-- PAppBind fc ref [] ->
533+ [] -> return f
566−-- return (dslify i (PAppBind fc ref args))
567− return (dslify i (PApp fc f args))
534+ _ -> return (dslify i (PApp fc f args)))
568 <?> "function application"
535 <?> "function application"
569 where
536 where
570 dslify :: IState -> PTerm -> PTerm
537 dslify :: IState -> PTerm -> PTerm
@@ -639,29 +606,61 @@ FieldType ::=
639@
606@
640-}
607-}
641recordType :: SyntaxInfo -> IdrisParser PTerm
608recordType :: SyntaxInfo -> IdrisParser PTerm
642−recordType syn
609+recordType syn =
643− = do reserved "record"
610+ do reserved "record"
644 lchar '{'
611 lchar '{'
645− fields <- sepBy1 fieldType (lchar ',')
612+ fgs <- fieldGetOrSet
646 lchar '}'
613 lchar '}'
647 fc <- getFC
614 fc <- getFC
648 rec <- optional (simpleExpr syn)
615 rec <- optional (simpleExpr syn)
616+ case fgs of
617+ Left fields ->
649− case rec of
618+ case rec of
650− Nothing ->
619+ Nothing ->
651− return (PLam (sMN 0 "fldx") Placeholder
620+ return (PLam (sMN 0 "fldx") Placeholder
652− (applyAll fc fields (PRef fc (sMN 0 "fldx"))))
621+ (applyAll fc fields (PRef fc (sMN 0 "fldx"))))
653− Just v -> return (applyAll fc fields v)
622+ Just v -> return (applyAll fc fields v)
623+ Right fields ->
624+ case rec of
625+ Nothing ->
626+ return (PLam (sMN 0 "fldx") Placeholder
627+ (getAll fc (reverse fields)
628+ (PRef fc (sMN 0 "fldx"))))
629+ Just v -> return (getAll fc (reverse fields) v)
630+
654 <?> "record setting expression"
631 <?> "record setting expression"
655− where fieldType :: IdrisParser (Name, PTerm)
632+ where fieldSet :: IdrisParser ([Name], PTerm)
656− fieldType = do n <- fnName
633+ fieldSet = do ns <- fieldGet
657− lchar '='
634+ lchar '='
658− e <- expr syn
635+ e <- expr syn
659− return (n, e)
636+ return (ns, e)
660− <?> "field setter"
637+ <?> "field setter"
638+
639+ fieldGet :: IdrisParser [Name]
640+ fieldGet = sepBy1 fnName (symbol "->")
641+
642+ fieldGetOrSet :: IdrisParser (Either [([Name], PTerm)] [Name])
643+ fieldGetOrSet = try (do fs <- sepBy1 fieldSet (lchar ',')
644+ return (Left fs))
645+ <|> do f <- fieldGet
646+ return (Right f)
647+
661− applyAll :: FC -> [(Name, PTerm)] -> PTerm -> PTerm
648+ applyAll :: FC -> [([Name], PTerm)] -> PTerm -> PTerm
662 applyAll fc [] x = x
649 applyAll fc [] x = x
663− applyAll fc ((n, e) : es) x
650+ applyAll fc ((ns, e) : es) x
651+ = applyAll fc es (doUpdate fc ns e x)
652+
653+ doUpdate fc [n] e get
664− = applyAll fc es (PApp fc (PRef fc (mkType n)) [pexp e, pexp x])
654+ = PApp fc (PRef fc (mkType n)) [pexp e, pexp get]
655+ doUpdate fc (n : ns) e get
656+ = PApp fc (PRef fc (mkType n))
657+ [pexp (doUpdate fc ns e (PApp fc (PRef fc n) [pexp get])),
658+ pexp get]
659+
660+ getAll :: FC -> [Name] -> PTerm -> PTerm
661+ getAll fc [n] e = PApp fc (PRef fc n) [pexp e]
662+ getAll fc (n:ns) e = PApp fc (PRef fc n) [pexp (getAll fc ns e)]
663+
665
664
666-- | Creates setters for record types on necessary functions
665-- | Creates setters for record types on necessary functions
667mkType :: Name -> Name
666mkType :: Name -> Name
@@ -700,17 +699,17 @@ SimpleExprList ::=
700@
699@
701-}
700-}
702lambda :: SyntaxInfo -> IdrisParser PTerm
701lambda :: SyntaxInfo -> IdrisParser PTerm
703−lambda syn = do lchar '\\'
702+lambda syn = do lchar '\\' <?> "lambda expression"
704− try (do xt <- tyOptDeclList syn
703+ (do xt <- try $ tyOptDeclList syn
705− symbol "=>"
704+ symbol "=>"
706− sc <- expr syn
705+ sc <- expr syn
707− return (bindList PLam xt sc)
706+ return (bindList PLam xt sc)) <|> do
708− <|> (do ps <- sepBy (do fc <- getFC
707+ ps <- sepBy (do fc <- getFC
709− e <- simpleExpr syn
708+ e <- simpleExpr syn
710− return (fc, e)) (lchar ',')
709+ return (fc, e)) (lchar ',')
711− symbol "=>"
710+ symbol "=>"
712− sc <- expr syn
711+ sc <- expr syn
713− return (pmList (zip [0..] ps) sc)))
712+ return (pmList (zip [0..] ps) sc)
714 <?> "lambda expression"
713 <?> "lambda expression"
715 where pmList :: [(Int, (FC, PTerm))] -> PTerm -> PTerm
714 where pmList :: [(Int, (FC, PTerm))] -> PTerm -> PTerm
716 pmList [] sc = sc
715 pmList [] sc = sc
@@ -788,11 +787,16 @@ quoteGoal syn = do reserved "quoteGoal"; n <- name;
788{- | Parses a dependent type signature
787{- | Parses a dependent type signature
789
788
790@
789@
791−Pi ::=
790+Pi ::= PiOpts Static? Pi'
792− '|'? Static? '(' TypeDeclList ')' DocComment '->' Expr
791+@
793− | '|'? Static? '{' TypeDeclList '}' '->' Expr
792+
793+@
794+Pi' ::=
795+ OpExpr ('->' Pi)?
796+ | '(' TypeDeclList ')' '->' Pi
797+ | '{' TypeDeclList '}' '->' Pi
794− | '{' 'auto' TypeDeclList '}' '->' Expr
798+ | '{' 'auto' TypeDeclList '}' '->' Pi
795− | '{' 'default' TypeDeclList '}' '->' Expr
799+ | '{' 'default' SimpleExpr TypeDeclList '}' '->' Pi
796 ;
800 ;
797@
801@
798 -}
802 -}
@@ -801,37 +805,44 @@ pi :: SyntaxInfo -> IdrisParser PTerm
801pi syn =
805pi syn =
802 do opts <- piOpts syn
806 do opts <- piOpts syn
803 st <- static
807 st <- static
804− (do try (lchar '('); xt <- typeDeclList syn; lchar ')'
808+ (do xt <- try (lchar '(' *> typeDeclList syn <* lchar ')')
805 symbol "->"
809 symbol "->"
806 sc <- expr syn
810 sc <- expr syn
807 return (bindList (PPi (Exp opts st False)) xt sc)) <|> (do
811 return (bindList (PPi (Exp opts st False)) xt sc)) <|> (do
808− lchar '{'
809− (do reserved "auto"
812+ (do try (lchar '{' *> reserved "auto")
810 when (st == Static) $ fail "auto type constraints can not be lazy or static"
813 when (st == Static) $ fail "auto type constraints can not be lazy or static"
811 xt <- typeDeclList syn
814 xt <- typeDeclList syn
812 lchar '}'
815 lchar '}'
813 symbol "->"
816 symbol "->"
814 sc <- expr syn
817 sc <- expr syn
815 return (bindList (PPi
818 return (bindList (PPi
816− (TacImp [] Dynamic (PTactics [Trivial]))) xt sc))
819+ (TacImp [] Dynamic (PTactics [Trivial]))) xt sc)) <|> (do
817− <|> (do
818− reserved "default"
820+ try (lchar '{' *> reserved "default")
819 when (st == Static) $ fail "default tactic constraints can not be lazy or static"
821 when (st == Static) $ fail "default tactic constraints can not be lazy or static"
820 script <- simpleExpr syn
822 script <- simpleExpr syn
821 xt <- typeDeclList syn
823 xt <- typeDeclList syn
822 lchar '}'
824 lchar '}'
823 symbol "->"
825 symbol "->"
824 sc <- expr syn
826 sc <- expr syn
825− return (bindList (PPi (TacImp [] Dynamic script)) xt sc))
827+ return (bindList (PPi (TacImp [] Dynamic script)) xt sc))
826 <|> (if implicitAllowed syn then do
828 <|> (if implicitAllowed syn then do
827− xt <- typeDeclList syn
829+ xt <- try (lchar '{' *> typeDeclList syn <* lchar '}')
828− lchar '}'
829 symbol "->"
830 symbol "->"
830 sc <- expr syn
831 sc <- expr syn
831 return (bindList (PPi (Imp opts st False)) xt sc)
832 return (bindList (PPi (Imp opts st False)) xt sc)
832 else do fail "no implicit arguments allowed here"))
833 else do fail "no implicit arguments allowed here"))
834+ <|> (do x <- opExpr syn
835+ (do symbol "->"
836+ sc <- expr syn
837+ return (PPi (Exp opts st False) (sUN "__pi_arg") x sc))
838+ <|> return x)
833 <?> "dependent type signature"
839 <?> "dependent type signature"
834
840
841+{- | Parses Possible Options for Pi Expressions
842+@
843+ PiOpts ::= '.'?
844+@
845+-}
835piOpts :: SyntaxInfo -> IdrisParser [ArgOpt]
846piOpts :: SyntaxInfo -> IdrisParser [ArgOpt]
836piOpts syn | implicitAllowed syn =
847piOpts syn | implicitAllowed syn =
837 lchar '.' *> return [InaccessibleArg]
848 lchar '.' *> return [InaccessibleArg]
@@ -911,34 +922,49 @@ tyOptDeclList syn = sepBy1 (do x <- nameOrPlaceholder
911 return (sMN 0 "underscore")
922 return (sMN 0 "underscore")
912 <?> "name or placeholder"
923 <?> "name or placeholder"
913
924
914−{- | Parses a list comprehension
925+{- | Parses a list literal expression e.g. [1,2,3] or a comprehension [ (x, y) | x <- xs , y <- ys ]
915@
926@
927+ListExpr ::=
928+ '[' ']'
916−Comprehension ::= '[' Expr '|' DoList ']';
929+ | '[' Expr '|' DoList ']'
930+ | '[' ExprList ']'
931+;
917@
932@
918−
919@
933@
920DoList ::=
934DoList ::=
921 Do
935 Do
922 | Do ',' DoList
936 | Do ',' DoList
923 ;
937 ;
924@
938@
939+@
940+ExprList ::=
941+ Expr
942+ | Expr ',' ExprList
943+ ;
944+@
925−-}
945+ -}
926−comprehension :: SyntaxInfo -> IdrisParser PTerm
946+listExpr :: SyntaxInfo -> IdrisParser PTerm
927−comprehension syn
928− = do lchar '['
947+listExpr syn = do lchar '['; fc <- getFC;
929− fc <- getFC
948+ try ((lchar ']' <?> "end of list expression") *> return (mkList fc [])) <|> (do
930− pat <- expr syn
949+ x <- expr syn <?> "expression"
931− lchar '|'
950+ (do try (lchar '|') <?> "list comprehension"
932− qs <- sepBy1 (do_ syn) (lchar ',')
951+ qs <- sepBy1 (do_ syn) (lchar ',')
933− lchar ']'
952+ lchar ']'
934− return (PDoBlock (map addGuard qs ++
953+ return (PDoBlock (map addGuard qs ++
935− [DoExp fc (PApp fc (PRef fc (sUN "return"))
954+ [DoExp fc (PApp fc (PRef fc (sUN "return"))
936− [pexp pat])]))
955+ [pexp x])]))) <|> (do
937− <?> "list comprehension"
956+ xs <- many ((lchar ',' <?> "list element") *> expr syn)
957+ lchar ']' <?> "end of list expression"
958+ return (mkList fc (x:xs))))
959+ <?> "list expression"
960+ where
961+ mkList :: FC -> [PTerm] -> PTerm
962+ mkList fc [] = PRef fc (sUN "Nil")
963+ mkList fc (x : xs) = PApp fc (PRef fc (sUN "::")) [pexp x, pexp (mkList fc xs)]
938− where addGuard :: PDo -> PDo
964+ addGuard :: PDo -> PDo
939− addGuard (DoExp fc e) = DoExp fc (PApp fc (PRef fc (sUN "guard"))
965+ addGuard (DoExp fc e) = DoExp fc (PApp fc (PRef fc (sUN "guard"))
940− [pexp e])
966+ [pexp e])
941− addGuard x = x
967+ addGuard x = x
942
968
943{- | Parses a do-block
969{- | Parses a do-block
944@
970@
@@ -1070,11 +1096,11 @@ constant = do reserved "Integer"; return (AType (ATInt ITBig))
1070 <|> do reserved "Bits16x8"; return (AType (ATInt (ITVec IT16 8)))
1096 <|> do reserved "Bits16x8"; return (AType (ATInt (ITVec IT16 8)))
1071 <|> do reserved "Bits32x4"; return (AType (ATInt (ITVec IT32 4)))
1097 <|> do reserved "Bits32x4"; return (AType (ATInt (ITVec IT32 4)))
1072 <|> do reserved "Bits64x2"; return (AType (ATInt (ITVec IT64 2)))
1098 <|> do reserved "Bits64x2"; return (AType (ATInt (ITVec IT64 2)))
1073− <|> try (do f <- float; return $ Fl f)
1099+ <|> do f <- try float; return $ Fl f
1074− <|> try (do i <- natural; return $ BI i)
1100+ <|> do i <- natural; return $ BI i
1075− <|> try (do s <- verbatimStringLiteral; return $ Str s)
1101+ <|> do s <- verbatimStringLiteral; return $ Str s
1076− <|> try (do s <- stringLiteral; return $ Str s)
1102+ <|> do s <- stringLiteral; return $ Str s
1077− <|> try (do c <- charLiteral; return $ Ch c)
1103+ <|> do c <- try charLiteral; return $ Ch c --Currently ambigous with symbols
1078 <?> "constant or literal"
1104 <?> "constant or literal"
1079
1105
1080{- | Parses a verbatim multi-line string literal (triple-quoted)
1106{- | Parses a verbatim multi-line string literal (triple-quoted)
@@ -1086,7 +1112,7 @@ VerbatimString_t ::=
1086@
1112@
1087 -}
1113 -}
1088verbatimStringLiteral :: MonadicParsing m => m String
1114verbatimStringLiteral :: MonadicParsing m => m String
1089−verbatimStringLiteral = token $ do string "\"\"\""
1115+verbatimStringLiteral = token $ do try $ string "\"\"\""
1090 manyTill anyChar $ try (string "\"\"\"")
1116 manyTill anyChar $ try (string "\"\"\"")
1091
1117
1092{- | Parses a static modifier
1118{- | Parses a static modifier
@@ -1098,7 +1124,7 @@ Static ::=
1098@
1124@
1099-}
1125-}
1100static :: IdrisParser Static
1126static :: IdrisParser Static
1101−static = do lchar '['; reserved "static"; lchar ']'; return Static
1127+static = do reserved "[static]"; return Static
1102 <|> return Dynamic
1128 <|> return Dynamic
1103 <?> "static modifier"
1129 <?> "static modifier"
1104
1130
@@ -1199,7 +1225,10 @@ tactic syn = do reserved "intro"; ns <- sepBy (indentPropHolds gtProp *> name) (
1199 return $ TSeq t (mergeSeq ts)
1225 return $ TSeq t (mergeSeq ts)
1200 <|> do reserved "compute"; return Compute
1226 <|> do reserved "compute"; return Compute
1201 <|> do reserved "trivial"; return Trivial
1227 <|> do reserved "trivial"; return Trivial
1228+ <|> do reserved "unify"; return DoUnify
1229+ <|> do reserved "search"
1230+ depth <- option 10 natural
1202− <|> do reserved "search"; return (ProofSearch Nothing [])
1231+ return (ProofSearch True True (fromInteger depth) Nothing [])
1203 <|> do reserved "instance"; return TCInstance
1232 <|> do reserved "instance"; return TCInstance
1204 <|> do reserved "solve"; return Solve
1233 <|> do reserved "solve"; return Solve
1205 <|> do reserved "attack"; return Attack
1234 <|> do reserved "attack"; return Attack
src/Idris/ParseHelpers.hs+9−6
@@ -156,9 +156,11 @@ multiLineComment = try (string "{-" *> (string "-}") *> pure ())
156docComment :: IdrisParser (Docstring, [(Name, Docstring)])
156docComment :: IdrisParser (Docstring, [(Name, Docstring)])
157docComment = do dc <- pushIndent *> docCommentLine
157docComment = do dc <- pushIndent *> docCommentLine
158 rest <- many (indented docCommentLine)
158 rest <- many (indented docCommentLine)
159− args <- many (indented argDocCommentLine)
159+ args <- many $ do (name, first) <- indented argDocCommentLine
160+ rest <- many (indented docCommentLine)
161+ return (name, concat (intersperse "\n" (first:rest)))
160 popIndent
162 popIndent
161− return (parseDocstring $ T.pack (concat . intersperse "\n" $ dc:rest),
163+ return (parseDocstring $ T.pack (concat (intersperse "\n" (dc:rest))),
162 map (\(n, d) -> (n, parseDocstring (T.pack d))) args)
164 map (\(n, d) -> (n, parseDocstring (T.pack d))) args)
163
165
164 where docCommentLine :: MonadicParsing m => m String
166 where docCommentLine :: MonadicParsing m => m String
@@ -170,6 +172,7 @@ docComment = do dc <- pushIndent *> docCommentLine
170 eol ; someSpace
172 eol ; someSpace
171 return contents)-- ++ concat rest))
173 return contents)-- ++ concat rest))
172 <?> ""
174 <?> ""
175+
173 argDocCommentLine = do string "|||"
176 argDocCommentLine = do string "|||"
174 many (satisfy isSpace)
177 many (satisfy isSpace)
175 char '@'
178 char '@'
@@ -214,7 +217,7 @@ idrisStyle :: MonadicParsing m => IdentifierStyle m
214idrisStyle = IdentifierStyle _styleName _styleStart _styleLetter _styleReserved Hi.Identifier Hi.ReservedIdentifier
217idrisStyle = IdentifierStyle _styleName _styleStart _styleLetter _styleReserved Hi.Identifier Hi.ReservedIdentifier
215 where _styleName = "Idris"
218 where _styleName = "Idris"
216 _styleStart = satisfy isAlpha
219 _styleStart = satisfy isAlpha
217− _styleLetter = satisfy isAlphaNum <|> oneOf "_'" <|> (lchar '.')
220+ _styleLetter = satisfy isAlphaNum <|> oneOf "_'."
218 _styleReserved = HS.fromList ["let", "in", "data", "codata", "record", "Type",
221 _styleReserved = HS.fromList ["let", "in", "data", "codata", "record", "Type",
219 "do", "dsl", "import", "impossible",
222 "do", "dsl", "import", "impossible",
220 "case", "of", "total", "partial", "mutual",
223 "case", "of", "total", "partial", "mutual",
@@ -313,7 +316,7 @@ operatorLetter = oneOf opChars
313-- | Parses an operator
316-- | Parses an operator
314operator :: MonadicParsing m => m String
317operator :: MonadicParsing m => m String
315operator = do op <- token . some $ operatorLetter
318operator = do op <- token . some $ operatorLetter
316− when (op `elem` [":", "=>", "->", "<-", "=", "?="]) $
319+ when (op `elem` [":", "=>", "->", "<-", "=", "?=", "|"]) $
317 fail $ op ++ " is not a valid operator"
320 fail $ op ++ " is not a valid operator"
318 return op
321 return op
319
322
@@ -563,8 +566,8 @@ collect (c@(PClauses _ o _ _) : ds)
563collect (PParams f ns ps : ds) = PParams f ns (collect ps) : collect ds
566collect (PParams f ns ps : ds) = PParams f ns (collect ps) : collect ds
564collect (PMutual f ms : ds) = PMutual f (collect ms) : collect ds
567collect (PMutual f ms : ds) = PMutual f (collect ms) : collect ds
565collect (PNamespace ns ps : ds) = PNamespace ns (collect ps) : collect ds
568collect (PNamespace ns ps : ds) = PNamespace ns (collect ps) : collect ds
566−collect (PClass doc f s cs n ps ds : ds')
569+collect (PClass doc f s cs n ps pdocs ds : ds')
567− = PClass doc f s cs n ps (collect ds) : collect ds'
570+ = PClass doc f s cs n ps pdocs (collect ds) : collect ds'
568collect (PInstance f s cs n ps t en ds : ds')
571collect (PInstance f s cs n ps t en ds : ds')
569 = PInstance f s cs n ps t en (collect ds) : collect ds'
572 = PInstance f s cs n ps t en (collect ds) : collect ds'
570collect (d : ds) = d : collect ds
573collect (d : ds) = d : collect ds
src/Idris/ParseOps.hs+1−2
@@ -38,8 +38,7 @@ table fixes
38 ++ toTable (reverse fixes) ++
38 ++ toTable (reverse fixes) ++
39 [[backtick],
39 [[backtick],
40 [binary "$" (\fc x y -> flatten $ PApp fc x [pexp y]) AssocRight],
40 [binary "$" (\fc x y -> flatten $ PApp fc x [pexp y]) AssocRight],
41− [binary "=" PEq AssocLeft],
41+ [binary "=" PEq AssocLeft]]
42− [binary "->" (\fc x y -> PPi expl (sUN "__pi_arg") x y) AssocRight]]
43 where
42 where
44 flatten :: PTerm -> PTerm -- flatten application
43 flatten :: PTerm -> PTerm -- flatten application
45 flatten (PApp fc (PApp _ f as) bs) = flatten (PApp fc f (as ++ bs))
44 flatten (PApp fc (PApp _ f as) bs) = flatten (PApp fc f (as ++ bs))
src/Idris/Parser.hs+63−46
@@ -47,7 +47,7 @@ import qualified Util.Pretty as P
47import Idris.Core.TT
47import Idris.Core.TT
48import Idris.Core.Evaluate
48import Idris.Core.Evaluate
49
49
50−import Control.Applicative
50+import Control.Applicative hiding (Const)
51import Control.Monad
51import Control.Monad
52import Control.Monad.Error (throwError, catchError)
52import Control.Monad.Error (throwError, catchError)
53import Control.Monad.State.Strict
53import Control.Monad.State.Strict
@@ -128,9 +128,14 @@ import_ = do fc <- getFC
128prog :: SyntaxInfo -> IdrisParser [PDecl]
128prog :: SyntaxInfo -> IdrisParser [PDecl]
129prog syn = do whiteSpace
129prog syn = do whiteSpace
130 decls <- many (decl syn)
130 decls <- many (decl syn)
131− notOpenBraces
132− eof
133 let c = (concat decls)
131 let c = (concat decls)
132+ case maxline syn of
133+ Nothing -> do notOpenBraces; eof
134+ _ -> return ()
135+ ist <- get
136+ fc <- getFC
137+ put ist { idris_parsedSpan = Just (FC (fc_fname fc) (0,0) (fc_end fc)),
138+ ibc_write = IBCParsedRegion fc : ibc_write ist }
134 return c
139 return c
135
140
136{-| Parses a top-level declaration
141{-| Parses a top-level declaration
@@ -153,8 +158,16 @@ Decl ::=
153@
158@
154-}
159-}
155decl :: SyntaxInfo -> IdrisParser [PDecl]
160decl :: SyntaxInfo -> IdrisParser [PDecl]
156−decl syn = do notEndBlock
161+decl syn = do fc <- getFC
162+ -- if we're after maxline, stop here
163+ let continue = case maxline syn of
164+ Nothing -> True
165+ Just l -> if fst (fc_end fc) > l
166+ then mut_nesting syn /= 0
167+ else True
168+ if continue then do notEndBlock
157− declBody
169+ declBody
170+ else fail "End of readable input"
158 where declBody :: IdrisParser [PDecl]
171 where declBody :: IdrisParser [PDecl]
159 declBody = declBody'
172 declBody = declBody'
160 <|> using_ syn
173 <|> using_ syn
@@ -489,7 +502,7 @@ mutual syn =
489 do reserved "mutual"
502 do reserved "mutual"
490 openBlock
503 openBlock
491 let pvars = syn_params syn
504 let pvars = syn_params syn
492− ds <- many (decl syn)
505+ ds <- many (decl (syn { mut_nesting = mut_nesting syn + 1 } ))
493 closeBlock
506 closeBlock
494 fc <- getFC
507 fc <- getFC
495 return [PMutual fc (concat ds)]
508 return [PMutual fc (concat ds)]
@@ -574,7 +587,7 @@ class_ syn = do (doc, acc) <- try (do
574 cs <- many carg
587 cs <- many carg
575 ds <- option [] (classBlock syn)
588 ds <- option [] (classBlock syn)
576 accData acc n (concatMap declared ds)
589 accData acc n (concatMap declared ds)
577− return [PClass (fst doc) syn fc cons n cs ds]
590+ return [PClass (fst doc) syn fc cons n cs (snd doc) ds]
578 <?> "type-class declaration"
591 <?> "type-class declaration"
579 where
592 where
580 carg :: IdrisParser (Name, PTerm)
593 carg :: IdrisParser (Name, PTerm)
@@ -831,7 +844,6 @@ clause syn
831 return $ PClause fc n capp wargs rs wheres) <|> (do
844 return $ PClause fc n capp wargs rs wheres) <|> (do
832 popIndent
845 popIndent
833 reserved "with"
846 reserved "with"
834− lchar '(' <?> "parenthesized expression"
835 wval <- bracketed syn
847 wval <- bracketed syn
836 openBlock
848 openBlock
837 ds <- some $ fnDecl syn
849 ds <- some $ fnDecl syn
@@ -865,7 +877,6 @@ clause syn
865 reserved "with"
877 reserved "with"
866 ist <- get
878 ist <- get
867 put (ist { lastParse = Just n })
879 put (ist { lastParse = Just n })
868− lchar '(' <?> "parenthesized expression"
869 wval <- bracketed syn
880 wval <- bracketed syn
870 openBlock
881 openBlock
871 ds <- some $ fnDecl syn
882 ds <- some $ fnDecl syn
@@ -1002,7 +1013,7 @@ directive syn = do try (lchar '%' *> reserved "lib"); cgn <- codegen_; lib <- st
1002 Right msg ->
1013 Right msg ->
1003 fail $ msg)]
1014 fail $ msg)]
1004 <|> do try (lchar '%' *> reserved "name")
1015 <|> do try (lchar '%' *> reserved "name")
1005− ty <- iName []
1016+ ty <- fnName
1006 ns <- sepBy1 name (lchar ',')
1017 ns <- sepBy1 name (lchar ',')
1007 return [PDirective (do ty' <- disambiguate ty
1018 return [PDirective (do ty' <- disambiguate ty
1008 mapM_ (addNameHint ty') ns
1019 mapM_ (addNameHint ty') ns
@@ -1023,7 +1034,7 @@ directive syn = do try (lchar '%' *> reserved "lib"); cgn <- codegen_; lib <- st
1023 case lookupCtxtName n (idris_implicits i) of
1034 case lookupCtxtName n (idris_implicits i) of
1024 [(n', _)] -> return n'
1035 [(n', _)] -> return n'
1025 [] -> throwError (NoSuchVariable n)
1036 [] -> throwError (NoSuchVariable n)
1026− more -> throwError (CantResolveAlts (map (show . fst) more))
1037+ more -> throwError (CantResolveAlts (map fst more))
1027
1038
1028pLangExt :: IdrisParser LanguageExt
1039pLangExt :: IdrisParser LanguageExt
1029pLangExt = (reserved "TypeProviders" >> return TypeProviders)
1040pLangExt = (reserved "TypeProviders" >> return TypeProviders)
@@ -1050,19 +1061,20 @@ ProviderWhat ::= 'proof' | 'term' | 'type' | 'postulate'
1050 -}
1061 -}
1051provider :: SyntaxInfo -> IdrisParser [PDecl]
1062provider :: SyntaxInfo -> IdrisParser [PDecl]
1052provider syn = do try (lchar '%' *> reserved "provide");
1063provider syn = do try (lchar '%' *> reserved "provide");
1053− what <- provideWhat
1064+ provideTerm <|> providePostulate
1054− lchar '('; n <- fnName; lchar ':'; t <- typeExpr syn; lchar ')'
1055− fc <- getFC
1056− reserved "with"
1057− e <- expr syn
1058− return [PProvider syn fc what n t e]
1059 <?> "type provider"
1065 <?> "type provider"
1060− where provideWhat :: IdrisParser ProvideWhat
1066+ where provideTerm = do lchar '('; n <- fnName; lchar ':'; t <- typeExpr syn; lchar ')'
1061− provideWhat = option ProvAny
1067+ fc <- getFC
1062− ( ((reserved "proof" <|> reserved "term" <|> reserved "type") *>
1068+ reserved "with"
1063− pure ProvTerm)
1069+ e <- expr syn <?> "provider expression"
1070+ return [PProvider syn fc (ProvTerm t e) n]
1064− <|> (reserved "postulate" *> pure ProvPostulate)
1071+ providePostulate = do reserved "postulate"
1065− <?> "provider variety")
1072+ n <- fnName
1073+ fc <- getFC
1074+ reserved "with"
1075+ e <- expr syn <?> "provider expression"
1076+ return [PProvider syn fc (ProvPostulate e) n]
1077+
1066{- | Parses a transform
1078{- | Parses a transform
1067
1079
1068@
1080@
@@ -1088,6 +1100,10 @@ transform syn = do try (lchar '%' *> reserved "transform")
1088parseExpr :: IState -> String -> Result PTerm
1100parseExpr :: IState -> String -> Result PTerm
1089parseExpr st = runparser (fullExpr defaultSyntax) st "(input)"
1101parseExpr st = runparser (fullExpr defaultSyntax) st "(input)"
1090
1102
1103+{- | Parses a constant form input -}
1104+parseConst :: IState -> String -> Result Const
1105+parseConst st = runparser constant st "(input)"
1106+
1091{- | Parses a tactic from input -}
1107{- | Parses a tactic from input -}
1092parseTactic :: IState -> String -> Result PTactic
1108parseTactic :: IState -> String -> Result PTactic
1093parseTactic st = runparser (fullTactic defaultSyntax) st "(input)"
1109parseTactic st = runparser (fullTactic defaultSyntax) st "(input)"
@@ -1160,8 +1176,7 @@ loadModule outh f
1160 = idrisCatch (loadModule' outh f)
1176 = idrisCatch (loadModule' outh f)
1161 (\e -> do setErrSpan (getErrSpan e)
1177 (\e -> do setErrSpan (getErrSpan e)
1162 ist <- getIState
1178 ist <- getIState
1163− msg <- showErr e
1179+ ihWarn outh (getErrSpan e) $ pprintErr ist e
1164− ihputStrLn outh msg
1165 return "")
1180 return "")
1166
1181
1167{- | Load idris module -}
1182{- | Load idris module -}
@@ -1171,26 +1186,26 @@ loadModule' outh f
1171 let file = takeWhile (/= ' ') f
1186 let file = takeWhile (/= ' ') f
1172 ibcsd <- valIBCSubDir i
1187 ibcsd <- valIBCSubDir i
1173 ids <- allImportDirs
1188 ids <- allImportDirs
1174− fp <- liftIO $ findImport ids ibcsd file
1189+ fp <- findImport ids ibcsd file
1175 if file `elem` imported i
1190 if file `elem` imported i
1176 then iLOG $ "Already read " ++ file
1191 then iLOG $ "Already read " ++ file
1177 else do putIState (i { imported = file : imported i })
1192 else do putIState (i { imported = file : imported i })
1178 case fp of
1193 case fp of
1179− IDR fn -> loadSource outh False fn
1194+ IDR fn -> loadSource outh False fn Nothing
1180− LIDR fn -> loadSource outh True fn
1195+ LIDR fn -> loadSource outh True fn Nothing
1181 IBC fn src ->
1196 IBC fn src ->
1182 idrisCatch (loadIBC fn)
1197 idrisCatch (loadIBC fn)
1183 (\c -> do iLOG $ fn ++ " failed " ++ pshow i c
1198 (\c -> do iLOG $ fn ++ " failed " ++ pshow i c
1184 case src of
1199 case src of
1185− IDR sfn -> loadSource outh False sfn
1200+ IDR sfn -> loadSource outh False sfn Nothing
1186− LIDR sfn -> loadSource outh True sfn)
1201+ LIDR sfn -> loadSource outh True sfn Nothing)
1187 let (dir, fh) = splitFileName file
1202 let (dir, fh) = splitFileName file
1188 return (dropExtension fh)
1203 return (dropExtension fh)
1189
1204
1190
1205
1191{- | Load idris code from file -}
1206{- | Load idris code from file -}
1192−loadFromIFile :: Handle -> IFileType -> Idris ()
1207+loadFromIFile :: Handle -> IFileType -> Maybe Int -> Idris ()
1193−loadFromIFile h i@(IBC fn src)
1208+loadFromIFile h i@(IBC fn src) maxline
1194 = do iLOG $ "Skipping " ++ getSrcFile i
1209 = do iLOG $ "Skipping " ++ getSrcFile i
1195 idrisCatch (loadIBC fn)
1210 idrisCatch (loadIBC fn)
1196 (\err -> ierror $ LoadingFailed fn err)
1211 (\err -> ierror $ LoadingFailed fn err)
@@ -1199,20 +1214,22 @@ loadFromIFile h i@(IBC fn src)
1199 getSrcFile (LIDR fn) = fn
1214 getSrcFile (LIDR fn) = fn
1200 getSrcFile (IBC f src) = getSrcFile src
1215 getSrcFile (IBC f src) = getSrcFile src
1201
1216
1202−loadFromIFile h (IDR fn) = loadSource' h False fn
1217+loadFromIFile h (IDR fn) maxline = loadSource' h False fn maxline
1203−loadFromIFile h (LIDR fn) = loadSource' h True fn
1218+loadFromIFile h (LIDR fn) maxline = loadSource' h True fn maxline
1204
1219
1205{-| Load idris source code and show error if something wrong happens -}
1220{-| Load idris source code and show error if something wrong happens -}
1206−loadSource' :: Handle -> Bool -> FilePath -> Idris ()
1221+loadSource' :: Handle -> Bool -> FilePath -> Maybe Int -> Idris ()
1207−loadSource' h lidr r
1222+loadSource' h lidr r maxline
1208− = idrisCatch (loadSource h lidr r)
1223+ = idrisCatch (loadSource h lidr r maxline)
1209 (\e -> do setErrSpan (getErrSpan e)
1224 (\e -> do setErrSpan (getErrSpan e)
1210 ist <- getIState
1225 ist <- getIState
1226+ case e of
1227+ At f e' -> ihWarn h f (pprintErr ist e')
1211− ihRenderError h (pprintErr ist e))
1228+ _ -> ihWarn h (getErrSpan e) (pprintErr ist e))
1212
1229
1213{- | Load Idris source code-}
1230{- | Load Idris source code-}
1214−loadSource :: Handle -> Bool -> FilePath -> Idris ()
1231+loadSource :: Handle -> Bool -> FilePath -> Maybe Int -> Idris ()
1215−loadSource h lidr f
1232+loadSource h lidr f toline
1216 = do iLOG ("Reading " ++ f)
1233 = do iLOG ("Reading " ++ f)
1217 i <- getIState
1234 i <- getIState
1218 let def_total = default_total i
1235 let def_total = default_total i
@@ -1221,11 +1238,11 @@ loadSource h lidr f
1221 (mname, imports, pos) <- parseImports f file
1238 (mname, imports, pos) <- parseImports f file
1222 ids <- allImportDirs
1239 ids <- allImportDirs
1223 ibcsd <- valIBCSubDir i
1240 ibcsd <- valIBCSubDir i
1224− mapM_ (\f -> do fp <- runIO $ findImport ids ibcsd f
1241+ mapM_ (\f -> do fp <- findImport ids ibcsd f
1225 case fp of
1242 case fp of
1226 LIDR fn -> ifail $ "No ibc for " ++ f
1243 LIDR fn -> ifail $ "No ibc for " ++ f
1227 IDR fn -> ifail $ "No ibc for " ++ f
1244 IDR fn -> ifail $ "No ibc for " ++ f
1228− IBC fn src -> loadIBC fn)
1245+ IBC fn src -> loadIBC fn)
1229 [fn | (fn, _, _) <- imports]
1246 [fn | (fn, _, _) <- imports]
1230 reportParserWarnings
1247 reportParserWarnings
1231
1248
@@ -1243,13 +1260,14 @@ loadSource h lidr f
1243 putIState (i { default_access = Hidden, module_aliases = modAliases })
1260 putIState (i { default_access = Hidden, module_aliases = modAliases })
1244 clearIBC -- start a new .ibc file
1261 clearIBC -- start a new .ibc file
1245 mapM_ (addIBC . IBCImport) [realName | (realName, alias, fc) <- imports]
1262 mapM_ (addIBC . IBCImport) [realName | (realName, alias, fc) <- imports]
1246− let syntax = defaultSyntax{ syn_namespace = reverse mname }
1263+ let syntax = defaultSyntax{ syn_namespace = reverse mname,
1264+ maxline = toline }
1247 ds' <- parseProg syntax f file pos
1265 ds' <- parseProg syntax f file pos
1248
1266
1249 -- Parsing done, now process declarations
1267 -- Parsing done, now process declarations
1250
1268
1251 let ds = namespaces mname ds'
1269 let ds = namespaces mname ds'
1252− logLvl 3 (show $ showDecls True ds)
1270+ logLvl 3 (show $ showDecls verbosePPOption ds)
1253 i <- getIState
1271 i <- getIState
1254 logLvl 10 (show (toAlist (idris_implicits i)))
1272 logLvl 10 (show (toAlist (idris_implicits i)))
1255 logLvl 3 (show (idris_infixes i))
1273 logLvl 3 (show (idris_infixes i))
@@ -1291,7 +1309,6 @@ loadSource h lidr f
1291 addHides (hide_list i)
1309 addHides (hide_list i)
1292
1310
1293 -- Finally, write an ibc if checking was successful
1311 -- Finally, write an ibc if checking was successful
1294−
1295 ok <- noErrors
1312 ok <- noErrors
1296 when ok $
1313 when ok $
1297 idrisCatch (do writeIBC f ibc; clearIBC)
1314 idrisCatch (do writeIBC f ibc; clearIBC)
@@ -1311,7 +1328,7 @@ loadSource h lidr f
1311 toMutual x = let r = PMutual (fileFC "single mutual") [x] in
1328 toMutual x = let r = PMutual (fileFC "single mutual") [x] in
1312 case x of
1329 case x of
1313 PClauses _ _ _ _ -> r
1330 PClauses _ _ _ _ -> r
1314− PClass _ _ _ _ _ _ _ -> r
1331+ PClass _ _ _ _ _ _ _ _ -> r
1315 PInstance _ _ _ _ _ _ _ _ -> r
1332 PInstance _ _ _ _ _ _ _ _ -> r
1316 _ -> x
1333 _ -> x
1317
1334
src/Idris/Primitives.hs+63−9
@@ -28,9 +28,10 @@ ty :: [Const] -> Const -> Type
28ty [] x = Constant x
28ty [] x = Constant x
29ty (t:ts) x = Bind (sMN 0 "T") (Pi (Constant t)) (ty ts x)
29ty (t:ts) x = Bind (sMN 0 "T") (Pi (Constant t)) (ty ts x)
30
30
31−total, partial :: Totality
31+total, partial, iopartial :: Totality
32total = Total []
32total = Total []
33partial = Partial NotCovering
33partial = Partial NotCovering
34+iopartial = Partial ExternalIO
34
35
35primitives :: [Prim]
36primitives :: [Prim]
36primitives =
37primitives =
@@ -164,22 +165,28 @@ primitives =
164 Prim (sUN "prim__strRev") (ty [StrType] StrType) 1 (p_strRev)
165 Prim (sUN "prim__strRev") (ty [StrType] StrType) 1 (p_strRev)
165 (1, LStrRev) total,
166 (1, LStrRev) total,
166 Prim (sUN "prim__readString") (ty [PtrType] StrType) 1 (p_cantreduce)
167 Prim (sUN "prim__readString") (ty [PtrType] StrType) 1 (p_cantreduce)
167− (1, LReadStr) partial,
168+ (1, LReadStr) iopartial,
168 Prim (sUN "prim__vm") (ty [] PtrType) 0 (p_cantreduce)
169 Prim (sUN "prim__vm") (ty [] PtrType) 0 (p_cantreduce)
169 (0, LVMPtr) total,
170 (0, LVMPtr) total,
170 -- Streams
171 -- Streams
171 Prim (sUN "prim__stdin") (ty [] PtrType) 0 (p_cantreduce)
172 Prim (sUN "prim__stdin") (ty [] PtrType) 0 (p_cantreduce)
172− (0, LStdIn) partial,
173+ (0, LStdIn) iopartial,
174+ Prim (sUN "prim__stdout") (ty [] PtrType) 0 (p_cantreduce)
175+ (0, LStdOut) iopartial,
176+ Prim (sUN "prim__stderr") (ty [] PtrType) 0 (p_cantreduce)
177+ (0, LStdErr) iopartial,
173 Prim (sUN "prim__null") (ty [] PtrType) 0 (p_cantreduce)
178 Prim (sUN "prim__null") (ty [] PtrType) 0 (p_cantreduce)
174 (0, LNullPtr) total,
179 (0, LNullPtr) total,
175 -- Managed pointer registration
180 -- Managed pointer registration
176 Prim (sUN "prim__registerPtr") (ty [PtrType, AType (ATInt ITNative)] ManagedPtrType) 2 (p_cantreduce)
181 Prim (sUN "prim__registerPtr") (ty [PtrType, AType (ATInt ITNative)] ManagedPtrType) 2 (p_cantreduce)
177 (2, LRegisterPtr) total,
182 (2, LRegisterPtr) total,
178 -- Buffers
183 -- Buffers
179− Prim (sUN "prim__allocate") (ty [AType (ATInt (ITFixed IT64))] BufferType) 1 (p_cantreduce)
184+ Prim (sUN "prim__allocate") (ty [AType (ATInt (ITFixed IT64))] BufferType) 1 (p_allocate)
180 (1, LAllocate) total,
185 (1, LAllocate) total,
181− Prim (sUN "prim__appendBuffer") (ty [BufferType, AType (ATInt (ITFixed IT64)), AType (ATInt (ITFixed IT64)), AType (ATInt (ITFixed IT64)), AType (ATInt (ITFixed IT64)), BufferType] BufferType) 6 (p_cantreduce)
186+ Prim (sUN "prim__appendBuffer") (ty [BufferType, AType (ATInt (ITFixed IT64)), AType (ATInt (ITFixed IT64)), AType (ATInt (ITFixed IT64)), AType (ATInt (ITFixed IT64)), BufferType] BufferType) 6 (p_appendBuffer)
182− (6, LAppendBuffer) partial
187+ (6, LAppendBuffer) partial,
188+ Prim (sUN "prim__systemInfo") (ty [AType (ATInt ITNative)] StrType) 1 (p_cantreduce)
189+ (1, LSystemInfo) total
183 ] ++ concatMap intOps [ITFixed IT8, ITFixed IT16, ITFixed IT32, ITFixed IT64, ITBig, ITNative, ITChar]
190 ] ++ concatMap intOps [ITFixed IT8, ITFixed IT16, ITFixed IT32, ITFixed IT64, ITBig, ITNative, ITChar]
184 ++ concatMap vecOps vecTypes
191 ++ concatMap vecOps vecTypes
185 ++ concatMap fixedOps [ITFixed IT8, ITFixed IT16, ITFixed IT32, ITFixed IT64] -- ITNative, ITChar, ATFloat ] ++ vecTypes
192 ++ concatMap fixedOps [ITFixed IT8, ITFixed IT16, ITFixed IT32, ITFixed IT64] -- ITNative, ITChar, ATFloat ] ++ vecTypes
@@ -287,10 +294,10 @@ fixedOps ity@(ITFixed _) =
287 thisTy = AType $ ATInt ity
294 thisTy = AType $ ATInt ity
288 appendFun en = Prim (sUN $ "prim__append" ++ tyName ++ show en)
295 appendFun en = Prim (sUN $ "prim__append" ++ tyName ++ show en)
289 (ty [BufferType, b64, b64, thisTy] BufferType)
296 (ty [BufferType, b64, b64, thisTy] BufferType)
290− 4 (p_cantreduce) (4, LAppend ity en) partial
297+ 4 (p_append en) (4, LAppend ity en) partial
291 peekFun en = Prim (sUN $ "prim__peek" ++ tyName ++ show en)
298 peekFun en = Prim (sUN $ "prim__peek" ++ tyName ++ show en)
292 (ty [BufferType, b64] thisTy)
299 (ty [BufferType, b64] thisTy)
293− 2 (p_cantreduce) (2, LPeek ity en) partial
300+ 2 (p_peek ity en) (2, LPeek ity en) partial
294
301
295mapHalf :: (V.Unbox a, V.Unbox b) => ((a, a) -> b) -> Vector a -> Vector b
302mapHalf :: (V.Unbox a, V.Unbox b) => ((a, a) -> b) -> Vector a -> Vector b
296mapHalf f xs = V.generate (V.length xs `div` 2) (\i -> f (xs V.! (i*2), xs V.! (i*2+1)))
303mapHalf f xs = V.generate (V.length xs `div` 2) (\i -> f (xs V.! (i*2), xs V.! (i*2+1)))
@@ -693,6 +700,53 @@ p_strCons _ = Nothing
693p_strRev [Str xs] = Just $ Str (reverse xs)
700p_strRev [Str xs] = Just $ Str (reverse xs)
694p_strRev _ = Nothing
701p_strRev _ = Nothing
695
702
703+p_allocate, p_appendBuffer :: [Const] -> Maybe Const
704+p_allocate [B64 _] = Just $ B8V V.empty
705+p_allocate n = Nothing
706+p_appendBuffer [B8V vect1, B64 size1, B64 count, B64 size2, B64 off, B8V vect2] =
707+ Just $ B8V (foldl (V.++)
708+ (V.slice 0 (fromIntegral size1) vect1)
709+ (replicate (fromIntegral count) (V.slice (fromIntegral off) (fromIntegral size2) vect2)))
710+p_appendBuffer n = Nothing
711+p_append :: Endianness -> [Const] -> Maybe Const
712+p_append en [B8V vect, B64 size, B64 count, val] =
713+ let bytes = case val of
714+ B8 x -> [x]
715+ B16 x -> [fromIntegral x, fromIntegral (shiftR x 8)]
716+ B32 x -> map (fromIntegral . shiftR x) [0,8..24]
717+ B64 x -> map (fromIntegral . shiftR x) [0,8..56]
718+ in Just $ B8V (foldl V.snoc
719+ (V.slice 0 (fromIntegral size) vect)
720+ (concat (replicate (fromIntegral count)
721+ (case en of
722+ BE -> reverse bytes
723+ _ -> bytes))))
724+p_append _ _ = Nothing
725+
726+p_peek :: IntTy -> Endianness -> [Const] -> Maybe Const
727+p_peek (ITFixed IT8) _ [B8V vect, B64 offset] = Just $ B8 (vect V.! fromIntegral offset)
728+p_peek (ITFixed IT16) en [B8V vect, B64 offset] =
729+ let bytes = [0..1]
730+ in Just $ B16 (foldl (\full byte -> shiftL full 8 .|. fromIntegral (vect V.! (fromIntegral offset+byte)))
731+ 0
732+ (case en of
733+ BE -> bytes
734+ _ -> reverse bytes))
735+p_peek (ITFixed IT32) en [B8V vect, B64 offset] =
736+ let bytes = [0..1]
737+ in Just $ B32 (foldl (\full byte -> shiftL full 8 .|. fromIntegral (vect V.! (fromIntegral offset+byte)))
738+ 0
739+ (case en of
740+ BE -> bytes
741+ _ -> reverse bytes))
742+p_peek (ITFixed IT64) en [B8V vect, B64 offset] =
743+ let bytes = [0..1]
744+ in Just $ B64 (foldl (\full byte -> shiftL full 8 .|. fromIntegral (vect V.! (fromIntegral offset+byte)))
745+ 0
746+ (case en of
747+ BE -> bytes
748+ _ -> reverse bytes))
749+p_peek _ _ _ = Nothing
750+
696p_cantreduce :: a -> Maybe b
751p_cantreduce :: a -> Maybe b
697p_cantreduce _ = Nothing
752p_cantreduce _ = Nothing
698−
src/Idris/ProofSearch.hs+61−13
@@ -14,6 +14,8 @@ import Idris.Error
14
14
15import Control.Applicative ((<$>))
15import Control.Applicative ((<$>))
16import Control.Monad
16import Control.Monad
17+import Control.Monad.State.Strict
18+import Data.List
17import Debug.Trace
19import Debug.Trace
18
20
19-- Pass in a term elaborator to avoid a cyclic dependency with ElabTerm
21-- Pass in a term elaborator to avoid a cyclic dependency with ElabTerm
@@ -36,15 +38,55 @@ trivial elab ist = try' (do elab (PRefl (fileFC "prf") Placeholder)
36 (tryAll xs) True
38 (tryAll xs) True
37 else tryAll xs
39 else tryAll xs
38
40
41+cantSolveGoal :: ElabD ()
42+cantSolveGoal = do g <- goal
43+ env <- get_env
44+ lift $ tfail $
45+ CantSolveGoal g (map (\(n,b) -> (n, binderTy b)) env)
46+
47+proofSearch :: Bool ->
48+ Bool -> -- invoked from a tactic proof. If so, making
49+ -- new metavariables is meaningless, and there shoudl
50+ -- be an error reported instead.
51+ Int -> -- maximum depth
39−proofSearch :: (PTerm -> ElabD ()) -> Maybe Name -> Name -> [Name] ->
52+ (PTerm -> ElabD ()) -> Maybe Name -> Name -> [Name] ->
40 IState -> ElabD ()
53 IState -> ElabD ()
54+proofSearch False fromProver depth elab _ nroot [fn] ist
55+ = do -- get all possible versions of the name, take the first one that
56+ -- works
57+ let all_imps = lookupCtxtName fn (idris_implicits ist)
58+ tryAllFns all_imps
59+ where
60+ -- if nothing worked, make a new metavariable
61+ tryAllFns [] | fromProver = cantSolveGoal
62+ tryAllFns [] = do attack; defer nroot; solve
63+ tryAllFns (f : fs) = try' (tryFn f) (tryAllFns fs) True
64+
65+ tryFn (f, args) = do let imps = map isImp args
66+ ps <- get_probs
67+ hs <- get_holes
68+ args <- map snd <$> try' (apply (Var f) imps)
69+ (match_apply (Var f) imps) True
70+ ps' <- get_probs
71+-- when (length ps < length ps') $ fail "Can't apply constructor"
72+ -- Make metavariables for new holes
73+ hs' <- get_holes
74+ ptm <- get_term
75+ if fromProver then cantSolveGoal
76+ else do
77+ mapM_ (\ h -> do focus h
78+ attack; defer nroot; solve)
79+ (hs' \\ hs)
80+-- (filter (\ (x, y) -> not x) (zip (map fst imps) args))
81+ solve
82+
83+ isImp (PImp p _ _ _ _) = (True, p)
84+ isImp arg = (True, priority arg) -- try to get all of them by unification
41−proofSearch elab fn nroot hints ist
85+proofSearch rec fromProver maxDepth elab fn nroot hints ist
42 = case lookupCtxt nroot (idris_tyinfodata ist) of
86 = case lookupCtxt nroot (idris_tyinfodata ist) of
43 [TISolution ts] -> findInferredTy ts
87 [TISolution ts] -> findInferredTy ts
44− _ -> psRec maxDepth
88+ _ -> psRec rec maxDepth
45 where
89 where
46− maxDepth = 6
47−
48 findInferredTy (t : _) = elab (delab ist (toUN t))
90 findInferredTy (t : _) = elab (delab ist (toUN t))
49
91
50 toUN t@(P nt (MN i n) ty)
92 toUN t@(P nt (MN i n) ty)
@@ -53,12 +95,16 @@ proofSearch elab fn nroot hints ist
53 toUN (App f a) = App (toUN f) (toUN a)
95 toUN (App f a) = App (toUN f) (toUN a)
54 toUN t = t
96 toUN t = t
55
97
98+ psRec _ 0 | fromProver = cantSolveGoal
56− psRec 0 = do attack; defer nroot; solve --fail "Maximum depth reached"
99+ psRec rec 0 = do attack; defer nroot; solve --fail "Maximum depth reached"
100+ psRec False d = tryCons d hints
57− psRec d = try' (trivial elab ist)
101+ psRec True d = try' (trivial elab ist)
58− (try' (try' (resolveByCon (d - 1)) (resolveByLocals (d - 1))
102+ (try' (try' (resolveByCon (d - 1)) (resolveByLocals (d - 1))
59− True)
103+ True)
60 -- if all else fails, make a new metavariable
104 -- if all else fails, make a new metavariable
105+ (if fromProver
106+ then cantSolveGoal
61− (do attack; defer nroot; solve) True) True
107+ else do attack; defer nroot; solve) True) True
62
108
63 getFn d Nothing = []
109 getFn d Nothing = []
64 getFn d (Just f) | d < maxDepth-1 = [f]
110 getFn d (Just f) | d < maxDepth-1 = [f]
@@ -91,7 +137,7 @@ proofSearch elab fn nroot hints ist
91
137
92 tryLocalArg d n 0 = elab (PRef (fileFC "prf") n)
138 tryLocalArg d n 0 = elab (PRef (fileFC "prf") n)
93 tryLocalArg d n i = simple_app (tryLocalArg d n (i - 1))
139 tryLocalArg d n i = simple_app (tryLocalArg d n (i - 1))
94− (psRec d) "proof search local apply"
140+ (psRec True d) "proof search local apply"
95
141
96 -- Like type class resolution, but searching with constructors
142 -- Like type class resolution, but searching with constructors
97 tryCon d n =
143 tryCon d n =
@@ -100,15 +146,17 @@ proofSearch elab fn nroot hints ist
100 [args] -> map isImp (snd args)
146 [args] -> map isImp (snd args)
101 _ -> fail "Ambiguous name"
147 _ -> fail "Ambiguous name"
102 ps <- get_probs
148 ps <- get_probs
149+ hs <- get_holes
103 args <- map snd <$> try' (apply (Var n) imps)
150 args <- map snd <$> try' (apply (Var n) imps)
104 (match_apply (Var n) imps) True
151 (match_apply (Var n) imps) True
105 ps' <- get_probs
152 ps' <- get_probs
153+ hs' <- get_holes
106 when (length ps < length ps') $ fail "Can't apply constructor"
154 when (length ps < length ps') $ fail "Can't apply constructor"
107 mapM_ (\ (_, h) -> do focus h
155 mapM_ (\ (_, h) -> do focus h
108− psRec d)
156+ psRec True d)
109 (filter (\ (x, y) -> not x) (zip (map fst imps) args))
157 (filter (\ (x, y) -> not x) (zip (map fst imps) args))
110 solve
158 solve
111
159
112 isImp (PImp p _ _ _ _) = (True, p)
160 isImp (PImp p _ _ _ _) = (True, p)
113− isImp arg = (False, priority arg)
161+ isImp arg = (False, priority arg)
114
162
src/Idris/Prover.hs+29−17
@@ -85,10 +85,19 @@ prove opt ctxt lit n ty
85 [([], P Ref n ty, ptm)]
85 [([], P Ref n ty, ptm)]
86 [([], P Ref n ty, ptm')] ty)
86 [([], P Ref n ty, ptm')] ty)
87 solveDeferred n
87 solveDeferred n
88+
88elabStep :: ElabState [PDecl] -> ElabD a -> Idris (a, ElabState [PDecl])
89elabStep :: ElabState [PDecl] -> ElabD a -> Idris (a, ElabState [PDecl])
89−elabStep st e = do case runStateT e st of
90+elabStep st e = case runStateT eCheck st of
90 OK (a, st') -> return (a, st')
91 OK (a, st') -> return (a, st')
91 Error a -> ierror a
92 Error a -> ierror a
93+ where eCheck = do res <- e
94+ probs' <- get_probs
95+ case probs' of
96+ [] -> do tm <- get_term
97+ ctxt <- get_context
98+ lift $ check ctxt [] (forget tm)
99+ return res
100+ ((_,_,_,e,_,_):_) -> lift $ Error e
92
101
93dumpState :: IState -> ProofState -> Idris ()
102dumpState :: IState -> ProofState -> Idris ()
94dumpState ist (PS nm [] _ _ tm _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) =
103dumpState ist (PS nm [] _ _ tm _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) =
@@ -104,9 +113,9 @@ dumpState ist ps@(PS nm (h:hs) _ _ tm _ _ _ _ _ _ problems i _ _ ctxy _ _ _ _) =
104 iputGoal rendered
113 iputGoal rendered
105
114
106 where
115 where
107− showImplicits = opt_showimp (idris_options ist)
116+ ppo = ppOptionIst ist
108
117
109− tPretty bnd t = pprintPTerm showImplicits bnd [] $ delab ist t
118+ tPretty bnd t = pprintPTerm ppo bnd [] (idris_infixes ist) $ delab ist t
110
119
111 assumptionNames :: Env -> [Name]
120 assumptionNames :: Env -> [Name]
112 assumptionNames = map fst
121 assumptionNames = map fst
@@ -116,10 +125,11 @@ dumpState ist ps@(PS nm (h:hs) _ _ tm _ _ _ _ _ _ problems i _ _ ctxy _ _ _ _) =
116 prettyPs bnd ((n@(MN _ r), _) : bs)
125 prettyPs bnd ((n@(MN _ r), _) : bs)
117 | r == txt "rewrite_rule" = prettyPs ((n, False):bnd) bs
126 | r == txt "rewrite_rule" = prettyPs ((n, False):bnd) bs
118 prettyPs bnd ((n, Let t v) : bs) =
127 prettyPs bnd ((n, Let t v) : bs) =
119− nest nestingSize (bindingOf n False <+> text "=" <+> tPretty bnd v <> colon <+>
128+ line <> bindingOf n False <+> text "=" <+> tPretty bnd v <+> colon <+>
120− tPretty ((n, False):bnd) t <> line <> prettyPs ((n, False):bnd) bs)
129+ align (tPretty bnd t) <> prettyPs ((n, False):bnd) bs
121 prettyPs bnd ((n, b) : bs) =
130 prettyPs bnd ((n, b) : bs) =
131+ line <> bindingOf n False <+> colon <+>
122− line <> bindingOf n False <+> colon <+> align (tPretty bnd (binderTy b)) <> prettyPs ((n, False):bnd) bs
132+ align (tPretty bnd (binderTy b)) <> prettyPs ((n, False):bnd) bs
123
133
124 prettyG bnd (Guess t v) = tPretty bnd t <+> text "=?=" <+> tPretty bnd v
134 prettyG bnd (Guess t v) = tPretty bnd t <+> text "=?=" <+> tPretty bnd v
125 prettyG bnd b = tPretty bnd $ binderTy b
135 prettyG bnd b = tPretty bnd $ binderTy b
@@ -231,15 +241,16 @@ ploop fn d prompt prf e h
231 ctxt' = envCtxt env ctxt
241 ctxt' = envCtxt env ctxt
232 putIState ist { tt_ctxt = ctxt' }
242 putIState ist { tt_ctxt = ctxt' }
233 (tm, ty) <- elabVal toplevel False t
243 (tm, ty) <- elabVal toplevel False t
234− let imp = opt_showimp (idris_options ist)
244+ let ppo = ppOptionIst ist
235− ty' = normaliseC ctxt [] ty
245+ ty' = normaliseC ctxt [] ty
236− h = idris_outh ist
246+ h = idris_outh ist
247+ infixes = idris_infixes ist
237 case tm of
248 case tm of
238 TType _ ->
249 TType _ ->
239− ihPrintTermWithType h (prettyImp imp PType) type1Doc
250+ ihPrintTermWithType h (prettyImp ppo PType) type1Doc
240 _ -> let bnd = map (\x -> (fst x, False)) env in
251 _ -> let bnd = map (\x -> (fst x, False)) env in
241− ihPrintTermWithType h (pprintPTerm imp bnd [] (delab ist tm))
252+ ihPrintTermWithType h (pprintPTerm ppo bnd [] infixes (delab ist tm))
242− (pprintPTerm imp bnd [] (delab ist ty))
253+ (pprintPTerm ppo bnd [] infixes (delab ist ty))
243 putIState ist
254 putIState ist
244 return (False, e, False, prf))
255 return (False, e, False, prf))
245 (\err -> do putIState ist { tt_ctxt = ctxt } ; ierror err)
256 (\err -> do putIState ist { tt_ctxt = ctxt } ; ierror err)
@@ -253,11 +264,12 @@ ploop fn d prompt prf e h
253 bnd = map (\x -> (fst x, False)) env
264 bnd = map (\x -> (fst x, False)) env
254 putIState ist'
265 putIState ist'
255 (tm, ty) <- elabVal toplevel False t
266 (tm, ty) <- elabVal toplevel False t
256− let tm' = force (normaliseAll ctxt' env tm)
267+ let tm' = force (normaliseAll ctxt' env tm)
257− ty' = force (normaliseAll ctxt' env ty)
268+ ty' = force (normaliseAll ctxt' env ty)
258− imp = opt_showimp (idris_options ist')
269+ ppo = ppOption (idris_options ist')
270+ infixes = idris_infixes ist
259− tmDoc = pprintPTerm imp bnd [] (delab ist' tm')
271+ tmDoc = pprintPTerm ppo bnd [] infixes (delab ist' tm')
260− tyDoc = pprintPTerm imp bnd [] (delab ist' ty')
272+ tyDoc = pprintPTerm ppo bnd [] infixes (delab ist' ty')
261 ihPrintTermWithType (idris_outh ist') tmDoc tyDoc
273 ihPrintTermWithType (idris_outh ist') tmDoc tyDoc
262 putIState ist
274 putIState ist
263 return (False, e, False, prf))
275 return (False, e, False, prf))
src/Idris/Providers.hs+1−7
@@ -11,16 +11,14 @@ import Debug.Trace
11
11
12-- | Wrap a type provider in the type of type providers
12-- | Wrap a type provider in the type of type providers
13providerTy :: FC -> PTerm -> PTerm
13providerTy :: FC -> PTerm -> PTerm
14−providerTy fc tm
14+providerTy fc tm
15 = PApp fc (PRef fc $ sUN "Provider") [PExp 0 [] (sMN 0 "pvarg") tm]
15 = PApp fc (PRef fc $ sUN "Provider") [PExp 0 [] (sMN 0 "pvarg") tm]
16
16
17ioret = sUN "prim_io_return"
17ioret = sUN "prim_io_return"
18ermod = sNS (sUN "Error") ["Providers"]
18ermod = sNS (sUN "Error") ["Providers"]
19prmod = sNS (sUN "Provide") ["Providers"]
19prmod = sNS (sUN "Provide") ["Providers"]
20−posmod = sNS (sUN "Postulate") ["Providers"]
21
20
22data Provided a = Provide a
21data Provided a = Provide a
23− | Postulate
24 deriving (Show, Eq, Functor)
22 deriving (Show, Eq, Functor)
25
23
26-- | Handle an error, if the type provider returned an error. Otherwise return the provided term.
24-- | Handle an error, if the type provider returned an error. Otherwise return the provided term.
@@ -35,10 +33,6 @@ getProvided fc tm | (P _ pioret _, [tp, result]) <- unApply tm
35 , (P _ nm _, [_, res]) <- unApply result
33 , (P _ nm _, [_, res]) <- unApply result
36 , pioret == ioret && nm == prmod
34 , pioret == ioret && nm == prmod
37 = return . Provide $ res
35 = return . Provide $ res
38− | (P _ pioret _, [tp, result]) <- unApply tm
39− , (P _ nm _, [_]) <- unApply result
40− , pioret == ioret && nm == posmod
41− = return Postulate
42 | otherwise = ifail $ "Internal type provider error: result was not " ++
36 | otherwise = ifail $ "Internal type provider error: result was not " ++
43 "IO (Provider a), or perhaps missing normalisation."
37 "IO (Provider a), or perhaps missing normalisation."
44
38
src/Idris/REPL.hs+296−404
@@ -4,6 +4,7 @@
4module Idris.REPL where
4module Idris.REPL where
5
5
6import Idris.AbsSyntax
6import Idris.AbsSyntax
7+import Idris.ASTUtils
7import Idris.Apropos (apropos)
8import Idris.Apropos (apropos)
8import Idris.REPLParser
9import Idris.REPLParser
9import Idris.ElabDecls
10import Idris.ElabDecls
@@ -13,6 +14,7 @@ import Idris.Error
13import Idris.ErrReverse
14import Idris.ErrReverse
14import Idris.Delaborate
15import Idris.Delaborate
15import Idris.Docstrings (Docstring, overview, renderDocstring)
16import Idris.Docstrings (Docstring, overview, renderDocstring)
17+import Idris.IdrisDoc
16import Idris.Prover
18import Idris.Prover
17import Idris.Parser hiding (indent)
19import Idris.Parser hiding (indent)
18import Idris.Primitives
20import Idris.Primitives
@@ -28,6 +30,9 @@ import Idris.Inliner
28import Idris.CaseSplit
30import Idris.CaseSplit
29import Idris.DeepSeq
31import Idris.DeepSeq
30import Idris.Output
32import Idris.Output
33+import Idris.Interactive
34+import Idris.WhoCalls
35+import Idris.TypeSearch (searchByType)
31
36
32import Paths_idris
37import Paths_idris
33import Version_idris (gitHash)
38import Version_idris (gitHash)
@@ -77,6 +82,7 @@ import Data.List
77import Data.Char
82import Data.Char
78import Data.Version
83import Data.Version
79import Data.Word (Word)
84import Data.Word (Word)
85+import Data.Either (partitionEithers)
80import Control.DeepSeq
86import Control.DeepSeq
81
87
82import Debug.Trace
88import Debug.Trace
@@ -104,7 +110,7 @@ repl orig mods
104 return ()
110 return ()
105 Just input -> -- H.catch
111 Just input -> -- H.catch
106 do ms <- H.catch (lift $ processInput input orig mods)
112 do ms <- H.catch (lift $ processInput input orig mods)
107− (ctrlC (return (Just mods)))
113+ (ctrlC (return (Just mods)))
108 case ms of
114 case ms of
109 Just mods -> repl orig mods
115 Just mods -> repl orig mods
110 Nothing -> return ()
116 Nothing -> return ()
@@ -115,7 +121,7 @@ repl orig mods
115 act -- repl orig mods
121 act -- repl orig mods
116
122
117 showMVs c thm [] = ""
123 showMVs c thm [] = ""
118− showMVs c thm ms = "Metavariables: " ++
124+ showMVs c thm ms = "Metavariables: " ++
119 show' 4 c thm (map fst ms) ++ "\n"
125 show' 4 c thm (map fst ms) ++ "\n"
120
126
121 show' 0 c thm ms = let l = length ms in
127 show' 0 c thm ms = let l = length ms in
@@ -123,7 +129,7 @@ repl orig mods
123 ++ " other"
129 ++ " other"
124 ++ if l == 1 then ")" else "s)"
130 ++ if l == 1 then ")" else "s)"
125 show' n c thm [m] = showM c thm m
131 show' n c thm [m] = showM c thm m
126− show' n c thm (m : ms) = showM c thm m ++ ", " ++
132+ show' n c thm (m : ms) = showM c thm m ++ ", " ++
127 show' (n - 1) c thm ms
133 show' (n - 1) c thm ms
128
134
129 showM c thm n = if c then colouriseFun thm (show n)
135 showM c thm n = if c then colouriseFun thm (show n)
@@ -161,8 +167,8 @@ processNetCmd orig i h fn cmd
161 Left err -> do hPutStrLn h (show err)
167 Left err -> do hPutStrLn h (show err)
162 return (i, fn)
168 return (i, fn)
163 where
169 where
164− processNet fn Reload = processNet fn (Load fn)
170+ processNet fn Reload = processNet fn (Load fn Nothing)
165− processNet fn (Load f) =
171+ processNet fn (Load f toline) =
166 do let ist = orig { idris_options = idris_options i
172 do let ist = orig { idris_options = idris_options i
167 , idris_colourTheme = idris_colourTheme i
173 , idris_colourTheme = idris_colourTheme i
168 , idris_colourRepl = False
174 , idris_colourRepl = False
@@ -172,7 +178,7 @@ processNetCmd orig i h fn cmd
172 setOutH h
178 setOutH h
173 setQuiet True
179 setQuiet True
174 setVerbose False
180 setVerbose False
175− mods <- loadInputs h [f]
181+ mods <- loadInputs h [f] toline
176 ist <- getIState
182 ist <- getIState
177 return (ist, f)
183 return (ist, f)
178 processNet fn c = do process h fn c
184 processNet fn c = do process h fn c
@@ -248,17 +254,22 @@ runIdeSlaveCommand id orig fn mods (IdeSlave.REPLCompletions str) =
248 IdeSlave.toSExp (map replacement compls,
254 IdeSlave.toSExp (map replacement compls,
249 reverse unused)]
255 reverse unused)]
250 runIO $ putStrLn $ IdeSlave.convSExp "return" good id
256 runIO $ putStrLn $ IdeSlave.convSExp "return" good id
251−runIdeSlaveCommand id orig fn mods (IdeSlave.LoadFile filename) =
257+runIdeSlaveCommand id orig fn mods (IdeSlave.LoadFile filename toline) =
252 do i <- getIState
258 do i <- getIState
253 clearErr
259 clearErr
254 putIState (orig { idris_options = idris_options i,
260 putIState (orig { idris_options = idris_options i,
255 idris_outputmode = (IdeSlave id) })
261 idris_outputmode = (IdeSlave id) })
256− loadInputs stdout [filename]
262+ loadInputs stdout [filename] toline
257 isetPrompt (mkPrompt [filename])
263 isetPrompt (mkPrompt [filename])
258 -- Report either success or failure
264 -- Report either success or failure
259 i <- getIState
265 i <- getIState
260 case (errSpan i) of
266 case (errSpan i) of
261− Nothing -> iPrintResult $ "loaded " ++ filename
267+ Nothing -> let msg = maybe (IdeSlave.SexpList [IdeSlave.SymbolAtom "ok",
268+ IdeSlave.SexpList []])
269+ (\fc -> IdeSlave.SexpList [IdeSlave.SymbolAtom "ok",
270+ IdeSlave.toSExp fc])
271+ (idris_parsedSpan i)
272+ in runIO . putStrLn $ IdeSlave.convSExp "return" msg id
262 Just x -> iPrintError $ "didn't load " ++ filename
273 Just x -> iPrintError $ "didn't load " ++ filename
263 ideslave orig [filename]
274 ideslave orig [filename]
264runIdeSlaveCommand id orig fn mods (IdeSlave.TypeOf name) =
275runIdeSlaveCommand id orig fn mods (IdeSlave.TypeOf name) =
@@ -272,14 +283,12 @@ runIdeSlaveCommand id orig fn mods (IdeSlave.TypeOf name) =
272 [n] -> Right $ sUN n
283 [n] -> Right $ sUN n
273 (n:ns) -> Right $ sNS (sUN n) ns
284 (n:ns) -> Right $ sNS (sUN n) ns
274runIdeSlaveCommand id orig fn mods (IdeSlave.DocsFor name) =
285runIdeSlaveCommand id orig fn mods (IdeSlave.DocsFor name) =
275− case splitName name of
286+ case parseConst orig name of
287+ Success c -> process stdout "(ideslave)" (DocStr (Right c))
288+ Failure _ ->
289+ case splitName name of
276− Left err -> iPrintError err
290+ Left err -> iPrintError err
277− Right n -> process stdout "(ideslave)" (DocStr n)
291+ Right n -> process stdout "(ideslave)" (DocStr (Left n))
278− where splitName :: String -> Either String Name
279− splitName s = case reverse $ splitOn "." s of
280− [] -> Left ("Didn't understand name '" ++ s ++ "'")
281− [n] -> Right $ sUN n
282− (n:ns) -> Right $ sNS (sUN n) ns
283runIdeSlaveCommand id orig fn mods (IdeSlave.CaseSplit line name) =
292runIdeSlaveCommand id orig fn mods (IdeSlave.CaseSplit line name) =
284 process stdout fn (CaseSplitAt False line (sUN name))
293 process stdout fn (CaseSplitAt False line (sUN name))
285runIdeSlaveCommand id orig fn mods (IdeSlave.AddClause line name) =
294runIdeSlaveCommand id orig fn mods (IdeSlave.AddClause line name) =
@@ -290,8 +299,12 @@ runIdeSlaveCommand id orig fn mods (IdeSlave.AddMissing line name) =
290 process stdout fn (AddMissing False line (sUN name))
299 process stdout fn (AddMissing False line (sUN name))
291runIdeSlaveCommand id orig fn mods (IdeSlave.MakeWithBlock line name) =
300runIdeSlaveCommand id orig fn mods (IdeSlave.MakeWithBlock line name) =
292 process stdout fn (MakeWith False line (sUN name))
301 process stdout fn (MakeWith False line (sUN name))
293−runIdeSlaveCommand id orig fn mods (IdeSlave.ProofSearch line name hints) =
302+runIdeSlaveCommand id orig fn mods (IdeSlave.ProofSearch r line name hints depth) =
294− process stdout fn (DoProofSearch False line (sUN name) (map sUN hints))
303+ doProofSearch stdout fn False r line (sUN name) (map sUN hints) depth
304+runIdeSlaveCommand id orig fn mods (IdeSlave.MakeLemma line name) =
305+ case splitName name of
306+ Left err -> iPrintError err
307+ Right n -> process stdout fn (MakeLemma False line n)
295runIdeSlaveCommand id orig fn mods (IdeSlave.Apropos a) =
308runIdeSlaveCommand id orig fn mods (IdeSlave.Apropos a) =
296 process stdout fn (Apropos a)
309 process stdout fn (Apropos a)
297runIdeSlaveCommand id orig fn mods (IdeSlave.GetOpts) =
310runIdeSlaveCommand id orig fn mods (IdeSlave.GetOpts) =
@@ -314,37 +327,68 @@ runIdeSlaveCommand id orig fn mods (IdeSlave.SetOpt IdeSlave.ErrContext b) =
314runIdeSlaveCommand id orig fn mods (IdeSlave.Metavariables cols) =
327runIdeSlaveCommand id orig fn mods (IdeSlave.Metavariables cols) =
315 do ist <- getIState
328 do ist <- getIState
316 let mvs = reverse $ map fst (idris_metavars ist) \\ primDefs
329 let mvs = reverse $ map fst (idris_metavars ist) \\ primDefs
317− imp <- impShow
330+ let ppo = ppOptionIst ist
318 let mvarTys = map (delabTy ist) mvs
331 let mvarTys = map (delabTy ist) mvs
319 let res = (IdeSlave.SymbolAtom "ok",
332 let res = (IdeSlave.SymbolAtom "ok",
320 zipWith (\ n (prems, concl) -> (n, prems, concl))
333 zipWith (\ n (prems, concl) -> (n, prems, concl))
321 (map (IdeSlave.StringAtom . show) mvs)
334 (map (IdeSlave.StringAtom . show) mvs)
322− (map (sexpGoal ist cols imp [] . getGoal) mvarTys))
335+ (map (sexpGoal ist cols ppo [] . getGoal) mvarTys))
323 runIO . putStrLn $ IdeSlave.convSExp "return" res id
336 runIO . putStrLn $ IdeSlave.convSExp "return" res id
324 where getGoal :: PTerm -> ([(Name, PTerm)], PTerm)
337 where getGoal :: PTerm -> ([(Name, PTerm)], PTerm)
325 getGoal (PPi _ n t sc) = let (prems, conc) = getGoal sc
338 getGoal (PPi _ n t sc) = let (prems, conc) = getGoal sc
326 in ((n, t):prems, conc)
339 in ((n, t):prems, conc)
327 getGoal tm = ([], tm)
340 getGoal tm = ([], tm)
328− sexpGoal :: IState -> Int -> Bool -> [Name] -> ([(Name, PTerm)], PTerm)
341+ sexpGoal :: IState -> Int -> PPOption -> [Name] -> ([(Name, PTerm)], PTerm)
329 -> ([(String, String, SpanList OutputAnnotation)],
342 -> ([(String, String, SpanList OutputAnnotation)],
330 (String, SpanList OutputAnnotation))
343 (String, SpanList OutputAnnotation))
331− sexpGoal ist cols imp ns ([], concl) =
344+ sexpGoal ist cols ppo ns ([], concl) =
345+ let infixes = idris_infixes ist
332− let concl' = displaySpans . renderPretty 0.9 cols . fmap (fancifyAnnots ist) $
346+ concl' = displaySpans . renderPretty 0.9 cols . fmap (fancifyAnnots ist) $
333− pprintPTerm imp (zip ns (repeat False)) [] concl
347+ pprintPTerm ppo (zip ns (repeat False)) [] infixes concl
334 in ([], concl')
348 in ([], concl')
335− sexpGoal ist cols imp ns ((n, t):ps, concl) =
349+ sexpGoal ist cols ppo ns ((n, t):ps, concl) =
336 let n' = case n of
350 let n' = case n of
337 NS (UN nm) ns -> str nm
351 NS (UN nm) ns -> str nm
338 UN nm | ('_':'_':_) <- str nm -> "_"
352 UN nm | ('_':'_':_) <- str nm -> "_"
339 | otherwise -> str nm
353 | otherwise -> str nm
340 _ -> "_"
354 _ -> "_"
341 (t', spans) = displaySpans . renderPretty 0.9 cols . fmap (fancifyAnnots ist) $
355 (t', spans) = displaySpans . renderPretty 0.9 cols . fmap (fancifyAnnots ist) $
342− pprintPTerm imp (zip ns (repeat False)) [] t
356+ pprintPTerm ppo (zip ns (repeat False)) [] (idris_infixes ist) t
343− rest = sexpGoal ist cols imp (n:ns) (ps, concl)
357+ rest = sexpGoal ist cols ppo (n:ns) (ps, concl)
344 in ((n', t', spans) : fst rest, snd rest)
358 in ((n', t', spans) : fst rest, snd rest)
345−
359+runIdeSlaveCommand id orig fn mods (IdeSlave.WhoCalls n) =
360+ case splitName n of
361+ Left err -> iPrintError err
362+ Right n -> do calls <- whoCalls n
363+ ist <- getIState
364+ let msg = (IdeSlave.SymbolAtom "ok",
365+ map (\ (n,ns) -> (pn ist n, map (pn ist) ns)) calls)
366+ runIO . putStrLn $ IdeSlave.convSExp "return" msg id
367+ where pn ist = displaySpans .
368+ renderPretty 0.9 1000 .
369+ fmap (fancifyAnnots ist) .
370+ prettyName True []
371+runIdeSlaveCommand id orig fn mods (IdeSlave.CallsWho n) =
372+ case splitName n of
373+ Left err -> iPrintError err
374+ Right n -> do calls <- callsWho n
375+ ist <- getIState
376+ let msg = (IdeSlave.SymbolAtom "ok",
377+ map (\ (n,ns) -> (pn ist n, map (pn ist) ns)) calls)
378+ runIO . putStrLn $ IdeSlave.convSExp "return" msg id
379+ where pn ist = displaySpans .
380+ renderPretty 0.9 1000 .
381+ fmap (fancifyAnnots ist) .
382+ prettyName True []
383+
384+splitName :: String -> Either String Name
385+splitName s = case reverse $ splitOn "." s of
386+ [] -> Left ("Didn't understand name '" ++ s ++ "'")
387+ [n] -> Right $ sUN n
388+ (n:ns) -> Right $ sNS (sUN n) ns
346
389
347ideslaveProcess :: FilePath -> Command -> Idris ()
390ideslaveProcess :: FilePath -> Command -> Idris ()
391+ideslaveProcess fn Warranty = process stdout fn Warranty
348ideslaveProcess fn Help = process stdout fn Help
392ideslaveProcess fn Help = process stdout fn Help
349ideslaveProcess fn (ChangeDirectory f) = do process stdout fn (ChangeDirectory f)
393ideslaveProcess fn (ChangeDirectory f) = do process stdout fn (ChangeDirectory f)
350 iPrintResult "changed directory to"
394 iPrintResult "changed directory to"
@@ -359,7 +403,6 @@ ideslaveProcess fn (Defn n) = do process stdout fn (Defn n)
359ideslaveProcess fn (TotCheck n) = process stdout fn (TotCheck n)
403ideslaveProcess fn (TotCheck n) = process stdout fn (TotCheck n)
360ideslaveProcess fn (DebugInfo n) = do process stdout fn (DebugInfo n)
404ideslaveProcess fn (DebugInfo n) = do process stdout fn (DebugInfo n)
361 iPrintResult ""
405 iPrintResult ""
362−ideslaveProcess fn (Info n) = process stdout fn (Info n)
363ideslaveProcess fn (Search t) = process stdout fn (Search t)
406ideslaveProcess fn (Search t) = process stdout fn (Search t)
364ideslaveProcess fn (Spec t) = process stdout fn (Spec t)
407ideslaveProcess fn (Spec t) = process stdout fn (Spec t)
365-- RmProof and AddProof not supported!
408-- RmProof and AddProof not supported!
@@ -400,11 +443,13 @@ ideslaveProcess fn (AddProofClauseFrom False pos str) = process stdout fn (AddPr
400ideslaveProcess fn (AddClauseFrom False pos str) = process stdout fn (AddClauseFrom False pos str)
443ideslaveProcess fn (AddClauseFrom False pos str) = process stdout fn (AddClauseFrom False pos str)
401ideslaveProcess fn (AddMissing False pos str) = process stdout fn (AddMissing False pos str)
444ideslaveProcess fn (AddMissing False pos str) = process stdout fn (AddMissing False pos str)
402ideslaveProcess fn (MakeWith False pos str) = process stdout fn (MakeWith False pos str)
445ideslaveProcess fn (MakeWith False pos str) = process stdout fn (MakeWith False pos str)
403−ideslaveProcess fn (DoProofSearch False pos str xs) = process stdout fn (DoProofSearch False pos str xs)
446+ideslaveProcess fn (DoProofSearch False r pos str xs) = process stdout fn (DoProofSearch False r pos str xs)
404ideslaveProcess fn (SetConsoleWidth w) = do process stdout fn (SetConsoleWidth w)
447ideslaveProcess fn (SetConsoleWidth w) = do process stdout fn (SetConsoleWidth w)
405 iPrintResult ""
448 iPrintResult ""
406ideslaveProcess fn (Apropos a) = do process stdout fn (Apropos a)
449ideslaveProcess fn (Apropos a) = do process stdout fn (Apropos a)
407 iPrintResult ""
450 iPrintResult ""
451+ideslaveProcess fn (WhoCalls n) = process stdout fn (WhoCalls n)
452+ideslaveProcess fn (CallsWho n) = process stdout fn (CallsWho n)
408ideslaveProcess fn _ = iPrintError "command not recognized or not supported"
453ideslaveProcess fn _ = iPrintError "command not recognized or not supported"
409
454
410
455
@@ -436,14 +481,14 @@ processInput cmd orig inputs
436 , idris_colourTheme = idris_colourTheme i
481 , idris_colourTheme = idris_colourTheme i
437 }
482 }
438 clearErr
483 clearErr
439− mods <- loadInputs stdout inputs
484+ mods <- loadInputs stdout inputs Nothing
440 return (Just inputs)
485 return (Just inputs)
441− Success (Load f) ->
486+ Success (Load f toline) ->
442 do putIState orig { idris_options = idris_options i
487 do putIState orig { idris_options = idris_options i
443 , idris_colourTheme = idris_colourTheme i
488 , idris_colourTheme = idris_colourTheme i
444 }
489 }
445 clearErr
490 clearErr
446− mod <- loadInputs stdout [f]
491+ mod <- loadInputs stdout [f] toline
447 return (Just [f])
492 return (Just [f])
448 Success (ModImport f) ->
493 Success (ModImport f) ->
449 do clearErr
494 do clearErr
@@ -467,7 +512,7 @@ resolveProof n'
467 n <- case lookupNames n' ctxt of
512 n <- case lookupNames n' ctxt of
468 [x] -> return x
513 [x] -> return x
469 [] -> return n'
514 [] -> return n'
470− ns -> ierror (CantResolveAlts (map show ns))
515+ ns -> ierror (CantResolveAlts ns)
471 return n
516 return n
472
517
473removeProof :: Name -> Idris ()
518removeProof :: Name -> Idris ()
@@ -492,7 +537,7 @@ edit f orig
492 putIState $ orig { idris_options = idris_options i
537 putIState $ orig { idris_options = idris_options i
493 , idris_colourTheme = idris_colourTheme i
538 , idris_colourTheme = idris_colourTheme i
494 }
539 }
495− loadInputs stdout [f]
540+ loadInputs stdout [f] Nothing
496-- clearOrigPats
541-- clearOrigPats
497 iucheck
542 iucheck
498 return ()
543 return ()
@@ -520,11 +565,13 @@ insertScript prf (x : xs) = x : insertScript prf xs
520
565
521process :: Handle -> FilePath -> Command -> Idris ()
566process :: Handle -> FilePath -> Command -> Idris ()
522process h fn Help = iPrintResult displayHelp
567process h fn Help = iPrintResult displayHelp
568+process h fn Warranty = iPrintResult warranty
523process h fn (ChangeDirectory f)
569process h fn (ChangeDirectory f)
524 = do runIO $ setCurrentDirectory f
570 = do runIO $ setCurrentDirectory f
525 return ()
571 return ()
526process h fn (Eval t)
572process h fn (Eval t)
573+ = withErrorReflection $ do logLvl 5 $ show t
527− = withErrorReflection $ do (tm, ty) <- elabVal toplevel False t
574+ (tm, ty) <- elabVal toplevel False t
528 ctxt <- getContext
575 ctxt <- getContext
529 let tm' = force (normaliseAll ctxt [] tm)
576 let tm' = force (normaliseAll ctxt [] tm)
530 let ty' = force (normaliseAll ctxt [] ty)
577 let ty' = force (normaliseAll ctxt [] ty)
@@ -533,41 +580,39 @@ process h fn (Eval t)
533 ist <- getIState
580 ist <- getIState
534 logLvl 3 $ "Raw: " ++ show (tm', ty')
581 logLvl 3 $ "Raw: " ++ show (tm', ty')
535 logLvl 10 $ "Debug: " ++ showEnvDbg [] tm'
582 logLvl 10 $ "Debug: " ++ showEnvDbg [] tm'
536− let imp = opt_showimp (idris_options ist)
537− tmDoc = prettyImp imp (delab ist tm')
583+ let tmDoc = prettyIst ist (delab ist tm')
538− tyDoc = prettyImp imp (delab ist ty')
584+ tyDoc = prettyIst ist (delab ist ty')
539 ihPrintTermWithType h tmDoc tyDoc
585 ihPrintTermWithType h tmDoc tyDoc
540
586
541process h fn (ExecVal t)
587process h fn (ExecVal t)
542 = do ctxt <- getContext
588 = do ctxt <- getContext
543 ist <- getIState
589 ist <- getIState
544− let imp = opt_showimp (idris_options ist)
545 (tm, ty) <- elabVal toplevel False t
590 (tm, ty) <- elabVal toplevel False t
546-- let tm' = normaliseAll ctxt [] tm
591-- let tm' = normaliseAll ctxt [] tm
547 let ty' = normaliseAll ctxt [] ty
592 let ty' = normaliseAll ctxt [] ty
548 res <- execute tm
593 res <- execute tm
549− let (resOut, tyOut) = (prettyImp imp (delab ist res),
594+ let (resOut, tyOut) = (prettyIst ist (delab ist res),
550− prettyImp imp (delab ist ty'))
595+ prettyIst ist (delab ist ty'))
551 ihPrintTermWithType h resOut tyOut
596 ihPrintTermWithType h resOut tyOut
552
597
553process h fn (Check (PRef _ n))
598process h fn (Check (PRef _ n))
554 = do ctxt <- getContext
599 = do ctxt <- getContext
555 ist <- getIState
600 ist <- getIState
556− imp <- impShow
601+ let ppo = ppOptionIst ist
557 case lookupNames n ctxt of
602 case lookupNames n ctxt of
558 ts@(t:_) ->
603 ts@(t:_) ->
559 case lookup t (idris_metavars ist) of
604 case lookup t (idris_metavars ist) of
560 Just (_, i, _) -> ihRenderResult h . fmap (fancifyAnnots ist) $
605 Just (_, i, _) -> ihRenderResult h . fmap (fancifyAnnots ist) $
561− showMetavarInfo imp ist n i
606+ showMetavarInfo ppo ist n i
562 Nothing -> ihPrintFunTypes h [] n (map (\n -> (n, delabTy ist n)) ts)
607 Nothing -> ihPrintFunTypes h [] n (map (\n -> (n, delabTy ist n)) ts)
563 [] -> ihPrintError h $ "No such variable " ++ show n
608 [] -> ihPrintError h $ "No such variable " ++ show n
564 where
609 where
565− showMetavarInfo imp ist n i
610+ showMetavarInfo ppo ist n i
566 = case lookupTy n (tt_ctxt ist) of
611 = case lookupTy n (tt_ctxt ist) of
567− (ty:_) -> putTy imp ist i [] (delab ist (errReverse ist ty))
612+ (ty:_) -> putTy ppo ist i [] (delab ist (errReverse ist ty))
568− putTy :: Bool -> IState -> Int -> [(Name, Bool)] -> PTerm -> Doc OutputAnnotation
613+ putTy :: PPOption -> IState -> Int -> [(Name, Bool)] -> PTerm -> Doc OutputAnnotation
569− putTy imp ist 0 bnd sc = putGoal imp ist bnd sc
614+ putTy ppo ist 0 bnd sc = putGoal ppo ist bnd sc
570− putTy imp ist i bnd (PPi _ n t sc)
615+ putTy ppo ist i bnd (PPi _ n t sc)
571 = let current = text " " <>
616 = let current = text " " <>
572 (case n of
617 (case n of
573 MN _ _ -> text "_"
618 MN _ _ -> text "_"
@@ -575,37 +620,41 @@ process h fn (Check (PRef _ n))
575 _ -> bindingOf n False) <+>
620 _ -> bindingOf n False) <+>
576 colon <+> align (tPretty bnd ist t) <> line
621 colon <+> align (tPretty bnd ist t) <> line
577 in
622 in
578− current <> putTy imp ist (i-1) ((n,False):bnd) sc
623+ current <> putTy ppo ist (i-1) ((n,False):bnd) sc
579− putTy imp ist _ bnd sc = putGoal imp ist ((n,False):bnd) sc
624+ putTy ppo ist _ bnd sc = putGoal ppo ist ((n,False):bnd) sc
580− putGoal imp ist bnd g
625+ putGoal ppo ist bnd g
581 = text "--------------------------------------" <$>
626 = text "--------------------------------------" <$>
582 annotate (AnnName n Nothing Nothing Nothing) (text $ show n) <+> colon <+>
627 annotate (AnnName n Nothing Nothing Nothing) (text $ show n) <+> colon <+>
583 align (tPretty bnd ist g)
628 align (tPretty bnd ist g)
584
629
585− tPretty bnd ist t = pprintPTerm (opt_showimp (idris_options ist)) bnd [] t
630+ tPretty bnd ist t = pprintPTerm (ppOptionIst ist) bnd [] (idris_infixes ist) t
586
631
587
632
588process h fn (Check t)
633process h fn (Check t)
589 = do (tm, ty) <- elabVal toplevel False t
634 = do (tm, ty) <- elabVal toplevel False t
590 ctxt <- getContext
635 ctxt <- getContext
591 ist <- getIState
636 ist <- getIState
592− let imp = opt_showimp (idris_options ist)
637+ let ppo = ppOptionIst ist
593 ty' = normaliseC ctxt [] ty
638 ty' = normaliseC ctxt [] ty
594 case tm of
639 case tm of
595 TType _ ->
640 TType _ ->
596− ihPrintTermWithType h (prettyImp imp PType) type1Doc
641+ ihPrintTermWithType h (prettyIst ist PType) type1Doc
597− _ -> ihPrintTermWithType h (prettyImp imp (delab ist tm))
642+ _ -> ihPrintTermWithType h (prettyIst ist (delab ist tm))
598− (prettyImp imp (delab ist ty))
643+ (prettyIst ist (delab ist ty))
599
644
600−process h fn (DocStr n)
645+process h fn (DocStr (Left n))
601− = do i <- getIState
646+ = do ist <- getIState
602− let imp = opt_showimp (idris_options i)
603− case lookupCtxtName n (idris_docstrings i) of
647+ case lookupCtxtName n (idris_docstrings ist) of
604 [] -> iPrintError $ "No documentation for " ++ show n
648 [] -> iPrintError $ "No documentation for " ++ show n
605− ns -> do toShow <- mapM (showDoc imp) ns
649+ ns -> do toShow <- mapM (showDoc ist) ns
606 ihRenderResult h (vsep toShow)
650 ihRenderResult h (vsep toShow)
607− where showDoc imp (n, d) = do doc <- getDocs n
651+ where showDoc ist (n, d) = do doc <- getDocs n
608− return $ pprintDocs imp doc
652+ return $ pprintDocs ist doc
653+
654+process h fn (DocStr (Right c))
655+ = do ist <- getIState
656+ ihRenderResult h $ pprintConstDocs ist c (constDocs c)
657+
609process h fn Universes
658process h fn Universes
610 = do i <- getIState
659 = do i <- getIState
611 let cs = idris_constraints i
660 let cs = idris_constraints i
@@ -637,8 +686,8 @@ process h fn (TotCheck n)
637 [] -> ihPrintError h $ "Unknown operator " ++ show n
686 [] -> ihPrintError h $ "Unknown operator " ++ show n
638 ts -> do ist <- getIState
687 ts -> do ist <- getIState
639 c <- colourise
688 c <- colourise
640− imp <- impShow
689+ let ppo = ppOptionIst ist
641− let showN = showName (Just ist) [] imp c
690+ let showN = showName (Just ist) [] ppo c
642 ihPrintResult h . concat . intersperse "\n" .
691 ihPrintResult h . concat . intersperse "\n" .
643 map (\(n, t) -> showN n ++ " is " ++ showTotal t i) $
692 map (\(n, t) -> showN n ++ " is " ++ showTotal t i) $
644 ts
693 ts
@@ -661,191 +710,21 @@ process h fn (DebugInfo n)
661 iputStrLn $ "Size change: " ++ show sc
710 iputStrLn $ "Size change: " ++ show sc
662 when (not (null cg')) $ do iputStrLn "Call graph:\n"
711 when (not (null cg')) $ do iputStrLn "Call graph:\n"
663 iputStrLn (show cg')
712 iputStrLn (show cg')
664−process h fn (Info n)
713+process h fn (Search t) = searchByType h t
665− = do i <- getIState
666− case lookupCtxt n (idris_classes i) of
667− [c] -> do info <- classInfo c
668− ihRenderResult h info
669− _ -> iPrintError "Not a class"
670−process h fn (Search t) = iPrintError "Not implemented"
671−-- FIXME: There is far too much repetition in the cases below!
672process h fn (CaseSplitAt updatefile l n)
714process h fn (CaseSplitAt updatefile l n)
673− = do src <- runIO $ readFile fn
674− res <- splitOnLine l n fn
675− iLOG (showSep "\n" (map show res))
676− let (before, (ap : later)) = splitAt (l-1) (lines src)
677− res' <- replaceSplits ap res
678− let new = concat res'
679− if updatefile
715+ = caseSplitAt h fn updatefile l n
680− then do let fb = fn ++ "~" -- make a backup!
681− runIO $ writeFile fb (unlines before ++ new ++ unlines later)
682− runIO $ copyFile fb fn
683− else -- do ihputStrLn h (show res)
684− ihPrintResult h new
685process h fn (AddClauseFrom updatefile l n)
716process h fn (AddClauseFrom updatefile l n)
686− = do src <- runIO $ readFile fn
687− let (before, tyline : later) = splitAt (l-1) (lines src)
688− let indent = getIndent 0 (show n) tyline
689− cl <- getClause l n fn
690− -- add clause before first blank line in 'later'
691− let (nonblank, rest) = span (not . all isSpace) (tyline:later)
692− if updatefile
717+ = addClauseFrom h fn updatefile l n
693− then do let fb = fn ++ "~"
694− runIO $ writeFile fb (unlines (before ++ nonblank) ++
695− replicate indent ' ' ++
696− cl ++ "\n" ++
697− unlines rest)
698− runIO $ copyFile fb fn
699− else ihPrintResult h cl
700− where
701− getIndent i n [] = 0
702− getIndent i n xs | take (length n) xs == n = i
703− getIndent i n (x : xs) = getIndent (i + 1) n xs
704process h fn (AddProofClauseFrom updatefile l n)
718process h fn (AddProofClauseFrom updatefile l n)
705− = do src <- runIO $ readFile fn
706− let (before, tyline : later) = splitAt (l-1) (lines src)
707− let indent = getIndent 0 (show n) tyline
708− cl <- getProofClause l n fn
709− -- add clause before first blank line in 'later'
710− let (nonblank, rest) = span (not . all isSpace) (tyline:later)
711− if updatefile
719+ = addProofClauseFrom h fn updatefile l n
712− then do let fb = fn ++ "~"
713− runIO $ writeFile fb (unlines (before ++ nonblank) ++
714− replicate indent ' ' ++
715− cl ++ "\n" ++
716− unlines rest)
717− runIO $ copyFile fb fn
718− else ihPrintResult h cl
719− where
720− getIndent i n [] = 0
721− getIndent i n xs | take (length n) xs == n = i
722− getIndent i n (x : xs) = getIndent (i + 1) n xs
723process h fn (AddMissing updatefile l n)
720process h fn (AddMissing updatefile l n)
724− = do src <- runIO $ readFile fn
721+ = addMissing h fn updatefile l n
725− let (before, tyline : later) = splitAt (l-1) (lines src)
726− let indent = getIndent 0 (show n) tyline
727− i <- getIState
728− cl <- getInternalApp fn l
729− let n' = getAppName cl
730−
731− extras <- case lookupCtxt n' (idris_patdefs i) of
732− [] -> return ""
733− [(_, tms)] -> do tms' <- nameMissing tms
734− showNew (show n ++ "_rhs") 1 indent tms'
735− let (nonblank, rest) = span (not . all isSpace) (tyline:later)
736− if updatefile
737− then do let fb = fn ++ "~"
738− runIO $ writeFile fb (unlines (before ++ nonblank)
739− ++ extras ++ unlines rest)
740− runIO $ copyFile fb fn
741− else ihPrintResult h extras
742− where showPat = show . stripNS
743− stripNS tm = mapPT dens tm where
744− dens (PRef fc n) = PRef fc (nsroot n)
745− dens t = t
746−
747− nsroot (NS n _) = nsroot n
748− nsroot (SN (WhereN _ _ n)) = nsroot n
749− nsroot n = n
750−
751− getAppName (PApp _ r _) = getAppName r
752− getAppName (PRef _ r) = r
753− getAppName _ = n
754−
755− showNew nm i ind (tm : tms)
756− = do (nm', i') <- getUniq nm i
757− rest <- showNew nm i' ind tms
758− return (replicate ind ' ' ++
759− showPat tm ++ " = ?" ++ nm' ++
760− "\n" ++ rest)
761− showNew nm i _ [] = return ""
762−
763− getIndent i n [] = 0
764− getIndent i n xs | take (length n) xs == n = i
765− getIndent i n (x : xs) = getIndent (i + 1) n xs
766−
767process h fn (MakeWith updatefile l n)
722process h fn (MakeWith updatefile l n)
768− = do src <- runIO $ readFile fn
723+ = makeWith h fn updatefile l n
769− let (before, tyline : later) = splitAt (l-1) (lines src)
770− let ind = getIndent tyline
771− let with = mkWith tyline n
772− -- add clause before first blank line in 'later',
773− -- or (TODO) before first line with same indentation as tyline
774− let (nonblank, rest) = span (\x -> not (all isSpace x) &&
775− not (ind == getIndent x)) later
776− if updatefile then
724+process h fn (MakeLemma updatefile l n)
777− do let fb = fn ++ "~"
725+ = makeLemma h fn updatefile l n
778− runIO $ writeFile fb (unlines (before ++ nonblank)
779− ++ with ++ "\n" ++
780− unlines rest)
781− runIO $ copyFile fb fn
782− else ihPrintResult h with
783− where getIndent s = length (takeWhile isSpace s)
784−
785−process h fn (DoProofSearch updatefile l n hints)
726+process h fn (DoProofSearch updatefile rec l n hints)
786− = do src <- runIO $ readFile fn
727+ = doProofSearch h fn updatefile rec l n hints Nothing
787− let (before, tyline : later) = splitAt (l-1) (lines src)
788− ctxt <- getContext
789− mn <- case lookupNames n ctxt of
790− [x] -> return x
791− [] -> return n
792− ns -> ierror (CantResolveAlts (map show ns))
793− i <- getIState
794− let (top, envlen, _) = case lookup mn (idris_metavars i) of
795− Just (t, e, False) -> (t, e, False)
796− _ -> (Nothing, 0, True)
797− let fc = fileFC fn
798− let body t = PProof [Try (TSeq Intros (ProofSearch t hints))
799− (ProofSearch t hints)]
800− let def = PClause fc mn (PRef fc mn) [] (body top) []
801− newmv <- idrisCatch
802− (do elabDecl' EAll toplevel (PClauses fc [] mn [def])
803− (tm, ty) <- elabVal toplevel False (PRef fc mn)
804− ctxt <- getContext
805− i <- getIState
806− return $ show (stripNS
807− (dropCtxt envlen
808− (delab i (specialise ctxt [] [(mn, 1)] tm)))))
809− (\e -> return ("?" ++ show n))
810− if updatefile then
811− do let fb = fn ++ "~"
812− runIO $ writeFile fb (unlines before ++
813− updateMeta False tyline (show n) newmv ++ "\n"
814− ++ unlines later)
815− runIO $ copyFile fb fn
816− else ihPrintResult h newmv
817− where dropCtxt 0 sc = sc
818− dropCtxt i (PPi _ _ _ sc) = dropCtxt (i - 1) sc
819− dropCtxt i (PLet _ _ _ sc) = dropCtxt (i - 1) sc
820− dropCtxt i (PLam _ _ sc) = dropCtxt (i - 1) sc
821− dropCtxt _ t = t
822−
823− stripNS tm = mapPT dens tm where
824− dens (PRef fc n) = PRef fc (nsroot n)
825− dens t = t
826−
827− nsroot (NS n _) = nsroot n
828− nsroot (SN (WhereN _ _ n)) = nsroot n
829− nsroot n = n
830−
831− updateMeta brack ('?':cs) n new
832− | length cs >= length n
833− = case splitAt (length n) cs of
834− (mv, c:cs) ->
835− if ((isSpace c || c == ')' || c == '}') && mv == n)
836− then addBracket brack new ++ (c : cs)
837− else '?' : mv ++ c : updateMeta True cs n new
838− (mv, []) -> if (mv == n) then addBracket brack new else '?' : mv
839− updateMeta brack ('=':cs) n new = '=':updateMeta False cs n new
840− updateMeta brack (c:cs) n new
841− = c : updateMeta (brack || not (isSpace c)) cs n new
842− updateMeta brack [] n new = ""
843−
844− addBracket False new = new
845− addBracket True new@('(':xs) | last xs == ')' = new
846− addBracket True new | any isSpace new = '(' : new ++ ")"
847− | otherwise = new
848−
849process h fn (Spec t)
728process h fn (Spec t)
850 = do (tm, ty) <- elabVal toplevel False t
729 = do (tm, ty) <- elabVal toplevel False t
851 ctxt <- getContext
730 ctxt <- getContext
@@ -871,14 +750,15 @@ process h fn (RmProof n')
871
750
872process h fn' (AddProof prf)
751process h fn' (AddProof prf)
873 = do fn <- do
752 = do fn <- do
753+ let fn'' = takeWhile (/= ' ') fn'
874− ex <- runIO $ doesFileExist fn'
754+ ex <- runIO $ doesFileExist fn''
875− let fnExt = fn' <.> "idr"
755+ let fnExt = fn'' <.> "idr"
876 exExt <- runIO $ doesFileExist fnExt
756 exExt <- runIO $ doesFileExist fnExt
877 if ex
757 if ex
878− then return fn'
758+ then return fn''
879 else if exExt
759 else if exExt
880 then return fnExt
760 then return fnExt
881− else ifail $ "Neither \""++fn'++"\" nor \""++fnExt++"\" exist"
761+ else ifail $ "Neither \""++fn''++"\" nor \""++fnExt++"\" exist"
882 let fb = fn ++ "~"
762 let fb = fn ++ "~"
883 runIO $ copyFile fn fb -- make a backup in case something goes wrong!
763 runIO $ copyFile fn fb -- make a backup in case something goes wrong!
884 prog <- runIO $ readFile fb
764 prog <- runIO $ readFile fb
@@ -915,13 +795,14 @@ process h fn (Prove n')
915 [] -> ierror (Msg $ "Cannot find metavariable " ++ show n')
795 [] -> ierror (Msg $ "Cannot find metavariable " ++ show n')
916 [(n, (_,_,False))] -> return n
796 [(n, (_,_,False))] -> return n
917 [(_, (_,_,True))] -> ierror (Msg $ "Declarations not solvable using prover")
797 [(_, (_,_,True))] -> ierror (Msg $ "Declarations not solvable using prover")
918− ns -> ierror (CantResolveAlts (map show ns))
798+ ns -> ierror (CantResolveAlts (map fst ns))
919 prover (lit fn) n
799 prover (lit fn) n
920 -- recheck totality
800 -- recheck totality
921 i <- getIState
801 i <- getIState
922 totcheck (fileFC "(input)", n)
802 totcheck (fileFC "(input)", n)
923 mapM_ (\ (f,n) -> setTotality n Unchecked) (idris_totcheck i)
803 mapM_ (\ (f,n) -> setTotality n Unchecked) (idris_totcheck i)
924 mapM_ checkDeclTotality (idris_totcheck i)
804 mapM_ checkDeclTotality (idris_totcheck i)
805+ warnTotality
925
806
926process h fn (HNF t)
807process h fn (HNF t)
927 = do (tm, ty) <- elabVal toplevel False t
808 = do (tm, ty) <- elabVal toplevel False t
@@ -934,23 +815,25 @@ process h fn (TestInline t)
934 ctxt <- getContext
815 ctxt <- getContext
935 ist <- getIState
816 ist <- getIState
936 let tm' = inlineTerm ist tm
817 let tm' = inlineTerm ist tm
937− imp <- impShow
938 c <- colourise
818 c <- colourise
939 iPrintResult (showTm ist (delab ist tm'))
819 iPrintResult (showTm ist (delab ist tm'))
940process h fn Execute
820process h fn Execute
821+ = idrisCatch
941− = do ist <- getIState
822+ (do ist <- getIState
942− (m, _) <- elabVal toplevel False
823+ (m, _) <- elabVal toplevel False
943− (PApp fc
824+ (PApp fc
944− (PRef fc (sUN "run__IO"))
825+ (PRef fc (sUN "run__IO"))
945− [pexp $ PRef fc (sNS (sUN "main") ["Main"])])
826+ [pexp $ PRef fc (sNS (sUN "main") ["Main"])])
946− (tmpn, tmph) <- runIO tempfile
827+ (tmpn, tmph) <- runIO tempfile
947− runIO $ hClose tmph
828+ runIO $ hClose tmph
948− t <- codegen
829+ t <- codegen
949− compile t tmpn m
830+ compile t tmpn m
950− case idris_outputmode ist of
831+ case idris_outputmode ist of
951− RawOutput -> do runIO $ system tmpn
832+ RawOutput -> do runIO $ system tmpn
952− return ()
833+ return ()
834+ IdeSlave n -> runIO . hPutStrLn h $
953− IdeSlave n -> do runIO . hPutStrLn h $ IdeSlave.convSExp "run-program" tmpn n
835+ IdeSlave.convSExp "run-program" tmpn n)
836+ (\e -> getIState >>= ihRenderError stdout . flip pprintErr e)
954 where fc = fileFC "main"
837 where fc = fileFC "main"
955process h fn (Compile codegen f)
838process h fn (Compile codegen f)
956 = do (m, _) <- elabVal toplevel False
839 = do (m, _) <- elabVal toplevel False
@@ -968,7 +851,7 @@ process h fn (Missing n)
968 = do i <- getIState
851 = do i <- getIState
969 let i' = i { idris_options = (idris_options i) { opt_showimp = True } }
852 let i' = i { idris_options = (idris_options i) { opt_showimp = True } }
970 case lookupCtxt n (idris_patdefs i) of
853 case lookupCtxt n (idris_patdefs i) of
971− [] -> return ()
854+ [] -> ihPrintError h $ "Unknown operator " ++ show n
972 [(_, tms)] ->
855 [(_, tms)] ->
973 iPrintResult (showSep "\n" (map (showTm i') tms))
856 iPrintResult (showSep "\n" (map (showTm i') tms))
974 _ -> iPrintError $ "Ambiguous name"
857 _ -> iPrintError $ "Ambiguous name"
@@ -1007,6 +890,10 @@ process h fn (SetOpt ShowOrigErr) = setShowOrigErr True
1007process h fn (UnsetOpt ShowOrigErr) = setShowOrigErr False
890process h fn (UnsetOpt ShowOrigErr) = setShowOrigErr False
1008process h fn (SetOpt AutoSolve) = setAutoSolve True
891process h fn (SetOpt AutoSolve) = setAutoSolve True
1009process h fn (UnsetOpt AutoSolve) = setAutoSolve False
892process h fn (UnsetOpt AutoSolve) = setAutoSolve False
893+process h fn (SetOpt NoBanner) = setNoBanner True
894+process h fn (UnsetOpt NoBanner) = setNoBanner False
895+process h fn (SetOpt WarnReach) = fmodifyState opts_idrisCmdline $ nub . (WarnReach:)
896+process h fn (UnsetOpt WarnReach) = fmodifyState opts_idrisCmdline $ delete WarnReach
1010
897
1011process h fn (SetOpt _) = iPrintError "Not a valid option"
898process h fn (SetOpt _) = iPrintError "Not a valid option"
1012process h fn (UnsetOpt _) = iPrintError "Not a valid option"
899process h fn (UnsetOpt _) = iPrintError "Not a valid option"
@@ -1019,52 +906,54 @@ process h fn ColourOff
1019 putIState $ ist { idris_colourRepl = False }
906 putIState $ ist { idris_colourRepl = False }
1020process h fn ListErrorHandlers =
907process h fn ListErrorHandlers =
1021 do ist <- getIState
908 do ist <- getIState
1022− case idris_errorhandlers ist of
909+ iPrintResult $ case idris_errorhandlers ist of
1023− [] -> iPrintResult "No registered error handlers"
910+ [] -> "No registered error handlers"
1024− handlers ->
1025− iPrintResult $ "Registered error handlers: " ++ (concat . intersperse ", " . map show) handlers
911+ handlers -> "Registered error handlers: " ++ (concat . intersperse ", " . map show) handlers
1026process h fn (SetConsoleWidth w) = setWidth w
912process h fn (SetConsoleWidth w) = setWidth w
1027
913
1028process h fn (Apropos a) =
914process h fn (Apropos a) =
1029 do ist <- getIState
915 do ist <- getIState
1030− let impl = opt_showimp (idris_options ist)
1031 let names = apropos ist (T.pack a)
916 let names = apropos ist (T.pack a)
1032 let aproposInfo = [ (n,
917 let aproposInfo = [ (n,
1033 delabTy ist n,
918 delabTy ist n,
1034 fmap (overview . fst) (lookupCtxtExact n (idris_docstrings ist)))
919 fmap (overview . fst) (lookupCtxtExact n (idris_docstrings ist)))
1035 | n <- sort names, isUN n ]
920 | n <- sort names, isUN n ]
1036− ihRenderResult h $ vsep (map (renderApropos impl) aproposInfo)
921+ ihRenderResult h $ vsep (map (prettyDocumentedIst ist) aproposInfo)
1037− where renderApropos impl (name, ty, docs) =
1038− prettyName True [] name <+> colon <+> align (prettyImp impl ty) <$>
1039− fromMaybe empty (fmap (\d -> renderDocstring d <> line) docs)
1040− isUN (UN _) = True
922+ where isUN (UN _) = True
1041 isUN (NS n _) = isUN n
923 isUN (NS n _) = isUN n
1042 isUN _ = False
924 isUN _ = False
1043
925
1044−classInfo :: ClassInfo -> Idris (Doc OutputAnnotation)
926+process h fn (WhoCalls n) =
927+ do calls <- whoCalls n
928+ ist <- getIState
929+ ihRenderResult h . vsep $
930+ map (\(n, ns) ->
931+ text "Callers of" <+> prettyName True [] n <$>
932+ indent 1 (vsep (map ((text "*" <+>) . align . prettyName True []) ns)))
933+ calls
934+
935+process h fn (CallsWho n) =
936+ do calls <- callsWho n
1045−classInfo ci = do ist <- getIState
937+ ist <- getIState
1046− ctxt <- getContext
938+ ihRenderResult h . vsep $
1047− return $
939+ map (\(n, ns) ->
1048− text "Parameters:" <+>
940+ prettyName True [] n <+> text "calls:" <$>
1049− hsep (punctuate comma (map (prettyName False params') params)) <>
941+ indent 1 (vsep (map ((text "*" <+>) . align . prettyName True []) ns)))
1050− line <> line <>
942+ calls
1051− text "Methods:" <> line <>
943+-- IdrisDoc
1052− indent 2 (vsep (map (dumpMethod ist) (class_methods ci))) <> line <> line <>
944+process h fn (MakeDoc s) =
1053− text "Default superclass instances:" <>
945+ do istate <- getIState
1054− line <>
946+ let names = words s
1055− indent 2 (vsep (map (dumpDefaultInstance ist) (class_default_superclasses ci))) <>
947+ parse n | Success x <- runparser name istate fn n = Right x
1056− line <>
948+ parse n = Left n
1057− text "Instances:" <> line <>
949+ (bad, nss) = partitionEithers $ map parse names
1058− indent 2 (vsep (map (dumpInstance ist ctxt) (class_instances ci)))
950+ cd <- runIO $ getCurrentDirectory
1059− where dumpMethod :: IState -> (Name, (FnOpts, PTerm)) -> Doc OutputAnnotation
951+ let outputDir = cd </> "doc"
1060− dumpMethod ist (n, (_, t)) = prettyName False [] n <+> colon <+> pp ist t
952+ result <- if null bad then runIO $ generateDocs istate nss outputDir
1061− dumpDefaultInstance :: IState -> PDecl -> Doc OutputAnnotation
953+ else return . Left $ "Illegal name: " ++ head bad
1062− dumpDefaultInstance ist (PInstance _ _ _ _ _ t _ _) = pp ist t
954+ case result of Right _ -> iputStrLn "IdrisDoc generated"
1063− dumpInstance :: IState -> Context -> Name -> Doc OutputAnnotation
955+ Left err -> iPrintError err
1064− dumpInstance ist ctxt n = pp ist $ delabTy ist n
956+
1065− params = class_params ci
1066− params' = zip params (repeat False)
1067− pp ist = pprintPTerm (opt_showimp (idris_options ist)) params' []
1068
957
1069showTotal :: Totality -> IState -> String
958showTotal :: Totality -> IState -> String
1070showTotal t@(Partial (Other ns)) i
959showTotal t@(Partial (Other ns)) i
@@ -1084,80 +973,6 @@ displayHelp = let vstr = showVersion version in
1084 l ++ take (c1 - length l) (repeat ' ') ++
973 l ++ take (c1 - length l) (repeat ' ') ++
1085 m ++ take (c2 - length m) (repeat ' ') ++ r ++ "\n"
974 m ++ take (c2 - length m) (repeat ' ') ++ r ++ "\n"
1086
975
1087−parseCodegen :: String -> Codegen
1088−parseCodegen "C" = ViaC
1089−parseCodegen "Java" = ViaJava
1090−parseCodegen "bytecode" = Bytecode
1091−parseCodegen "javascript" = ViaJavaScript
1092−parseCodegen "node" = ViaNode
1093−parseCodegen "llvm" = ViaLLVM
1094−parseCodegen _ = error "unknown codegen" -- FIXME: partial function
1095−
1096−parseArgs :: [String] -> [Opt]
1097−parseArgs [] = []
1098−parseArgs ("--nobanner":ns) = NoBanner : (parseArgs ns)
1099−parseArgs ("--quiet":ns) = Quiet : (parseArgs ns)
1100−parseArgs ("--ideslave":ns) = Ideslave : (parseArgs ns)
1101−parseArgs ("--client":ns) = [Client (showSep " " ns)]
1102−parseArgs ("--log":lvl:ns) = OLogging (read lvl) : (parseArgs ns)
1103−parseArgs ("--nobasepkgs":ns) = NoBasePkgs : (parseArgs ns)
1104−parseArgs ("--noprelude":ns) = NoPrelude : (parseArgs ns)
1105−parseArgs ("--nobuiltins":ns) = NoBuiltins : NoPrelude : (parseArgs ns)
1106−parseArgs ("--check":ns) = NoREPL : (parseArgs ns)
1107−parseArgs ("-o":n:ns) = NoREPL : Output n : (parseArgs ns)
1108−parseArgs ("--typecase":ns) = TypeCase : (parseArgs ns)
1109−parseArgs ("--typeintype":ns) = TypeInType : (parseArgs ns)
1110−parseArgs ("--total":ns) = DefaultTotal : (parseArgs ns)
1111−parseArgs ("--partial":ns) = DefaultPartial : (parseArgs ns)
1112−parseArgs ("--warnpartial":ns) = WarnPartial : (parseArgs ns)
1113−parseArgs ("--warnreach":ns) = WarnReach : (parseArgs ns)
1114−parseArgs ("--nocoverage":ns) = NoCoverage : (parseArgs ns)
1115−parseArgs ("--errorcontext":ns) = ErrContext : (parseArgs ns)
1116−parseArgs ("--help":ns) = Usage : (parseArgs ns)
1117−parseArgs ("--link":ns) = ShowLibs : (parseArgs ns)
1118−parseArgs ("--libdir":ns) = ShowLibdir : (parseArgs ns)
1119−parseArgs ("--include":ns) = ShowIncs : (parseArgs ns)
1120−parseArgs ("--version":ns) = Ver : (parseArgs ns)
1121−parseArgs ("--verbose":ns) = Verbose : (parseArgs ns)
1122−parseArgs ("--ibcsubdir":n:ns) = IBCSubDir n : (parseArgs ns)
1123−parseArgs ("-i":n:ns) = ImportDir n : (parseArgs ns)
1124−parseArgs ("--warn":ns) = WarnOnly : (parseArgs ns)
1125−-- Package Related options
1126−parseArgs ("--package":n:ns) = Pkg n : (parseArgs ns)
1127−parseArgs ("-p":n:ns) = Pkg n : (parseArgs ns)
1128−parseArgs ("--build":n:ns) = PkgBuild n : (parseArgs ns)
1129−parseArgs ("--install":n:ns) = PkgInstall n : (parseArgs ns)
1130−parseArgs ("--repl":n:ns) = PkgREPL n : (parseArgs ns)
1131−parseArgs ("--clean":n:ns) = PkgClean n : (parseArgs ns)
1132−parseArgs ("--checkpkg":n:ns) = PkgCheck n : (parseArgs ns)
1133−-- Misc Options
1134−parseArgs ("--bytecode":n:ns) = NoREPL : BCAsm n : (parseArgs ns)
1135−parseArgs ("-S":ns) = OutputTy Raw : (parseArgs ns)
1136−parseArgs ("-c":ns) = OutputTy Object : (parseArgs ns)
1137−parseArgs ("--mvn":ns) = OutputTy MavenProject : (parseArgs ns)
1138−parseArgs ("--dumpdefuns":n:ns) = DumpDefun n : (parseArgs ns)
1139−parseArgs ("--dumpcases":n:ns) = DumpCases n : (parseArgs ns)
1140−parseArgs ("--codegen":n:ns) = UseCodegen (parseCodegen n) : (parseArgs ns)
1141−parseArgs ["--exec"] = InterpretScript "Main.main" : []
1142−parseArgs ("--exec":expr:ns) = InterpretScript expr : parseArgs ns
1143−parseArgs (('-':'X':extName):ns) = case maybeRead extName of
1144− Just ext -> Extension ext : parseArgs ns
1145− -- Not sure what to do for the Nothing case
1146− Nothing -> error ("Unknown extension " ++ extName)
1147− where maybeRead = fmap fst . listToMaybe . reads
1148−parseArgs ("-O3":ns) = OptLevel 3 : parseArgs ns
1149−parseArgs ("-O2":ns) = OptLevel 2 : parseArgs ns
1150−parseArgs ("-O1":ns) = OptLevel 1 : parseArgs ns
1151−parseArgs ("-O0":ns) = OptLevel 0 : parseArgs ns
1152−parseArgs ("-O":n:ns) = OptLevel (read n) : parseArgs ns
1153−parseArgs ("--target":n:ns) = TargetTriple n : parseArgs ns
1154−parseArgs ("--cpu":n:ns) = TargetCPU n : parseArgs ns
1155−parseArgs ("--colour":ns) = ColourREPL True : parseArgs ns
1156−parseArgs ("--color":ns) = ColourREPL True : parseArgs ns
1157−parseArgs ("--nocolour":ns) = ColourREPL False : parseArgs ns
1158−parseArgs ("--nocolor":ns) = ColourREPL False : parseArgs ns
1159−parseArgs (n:ns) = Filename n : (parseArgs ns)
1160−
1161helphead =
976helphead =
1162 [ (["Command"], SpecialHeaderArg, "Purpose"),
977 [ (["Command"], SpecialHeaderArg, "Purpose"),
1163 ([""], NoArg, "")
978 ([""], NoArg, "")
@@ -1169,17 +984,22 @@ replSettings hFile = setComplete replCompletion $ defaultSettings {
1169 historyFile = hFile
984 historyFile = hFile
1170 }
985 }
1171
986
1172−-- invoke as if from command line
987+-- | Invoke as if from command line. It is an error if there are unresolved totality problems.
1173idris :: [Opt] -> IO (Maybe IState)
988idris :: [Opt] -> IO (Maybe IState)
1174−idris opts = do res <- runErrorT $ execStateT (idrisMain opts) idrisInit
989+idris opts = do res <- runErrorT $ execStateT totalMain idrisInit
1175 case res of
990 case res of
1176 Left err -> do putStrLn $ pshow idrisInit err
991 Left err -> do putStrLn $ pshow idrisInit err
1177 return Nothing
992 return Nothing
1178 Right ist -> return (Just ist)
993 Right ist -> return (Just ist)
994+ where totalMain = do idrisMain opts
995+ ist <- getIState
996+ case idris_totcheckfail ist of
997+ ((fc, msg):_) -> ierror . At fc . Msg $ "Could not build: "++ msg
998+ [] -> return ()
1179
999
1180
1000
1181−loadInputs :: Handle -> [FilePath] -> Idris ()
1001+loadInputs :: Handle -> [FilePath] -> Maybe Int -> Idris ()
1182−loadInputs h inputs
1002+loadInputs h inputs toline -- furthest line to read in input source files
1183 = idrisCatch
1003 = idrisCatch
1184 (do ist <- getIState
1004 (do ist <- getIState
1185 -- if we're in --check and not outputting anything, don't bother
1005 -- if we're in --check and not outputting anything, don't bother
@@ -1204,14 +1024,13 @@ loadInputs h inputs
1204 let ifiles = getModuleFiles modTree
1024 let ifiles = getModuleFiles modTree
1205 iLOG ("MODULE TREE : " ++ show modTree)
1025 iLOG ("MODULE TREE : " ++ show modTree)
1206 iLOG ("RELOAD: " ++ show ifiles)
1026 iLOG ("RELOAD: " ++ show ifiles)
1207− when (not (all ibc ifiles) || loadCode) $
1027+ when (not (all ibc ifiles) || loadCode) $
1208 tryLoad False (filter (not . ibc) ifiles)
1028 tryLoad False (filter (not . ibc) ifiles)
1209 -- return the files that need rechecking
1029 -- return the files that need rechecking
1210− return ifiles)
1030+ return ifiles)
1211 ninputs
1031 ninputs
1212 inew <- getIState
1032 inew <- getIState
1213 let tidata = idris_tyinfodata inew
1033 let tidata = idris_tyinfodata inew
1214− let lineapps = idris_lineapps inew
1215 let patdefs = idris_patdefs inew
1034 let patdefs = idris_patdefs inew
1216 -- If it worked, load the whole thing from all the ibcs together
1035 -- If it worked, load the whole thing from all the ibcs together
1217 case errSpan inew of
1036 case errSpan inew of
@@ -1222,38 +1041,56 @@ loadInputs h inputs
1222 _ -> return ()
1041 _ -> return ()
1223 ist <- getIState
1042 ist <- getIState
1224 putIState (ist { idris_tyinfodata = tidata,
1043 putIState (ist { idris_tyinfodata = tidata,
1225− idris_lineapps = lineapps,
1226− idris_patdefs = patdefs }))
1044+ idris_patdefs = patdefs })
1045+
1046+ case opt getOutput opts of
1047+ [] -> performUsageAnalysis -- interactive
1048+ _ -> return [] -- batch, will be checked by the compiler
1049+
1050+ return ())
1227 (\e -> do i <- getIState
1051 (\e -> do i <- getIState
1228 case e of
1052 case e of
1229− At f _ -> do setErrSpan f
1053+ At f e' -> do setErrSpan f
1230− ihRenderError stdout $ pprintErr i e
1054+ ihWarn stdout f $ pprintErr i e'
1231 ProgramLineComment -> return () -- fail elsewhere
1055 ProgramLineComment -> return () -- fail elsewhere
1232 _ -> do setErrSpan emptyFC -- FIXME! Propagate it
1056 _ -> do setErrSpan emptyFC -- FIXME! Propagate it
1233− iputStrLn (pshow i e))
1057+ ihWarn stdout emptyFC $ pprintErr i e)
1234 where -- load all files, stop if any fail
1058 where -- load all files, stop if any fail
1235 tryLoad :: Bool -> [IFileType] -> Idris ()
1059 tryLoad :: Bool -> [IFileType] -> Idris ()
1236− tryLoad keepstate [] = return ()
1060+ tryLoad keepstate [] = warnTotality >> return ()
1237− tryLoad keepstate (f : fs)
1061+ tryLoad keepstate (f : fs)
1238 = do ist <- getIState
1062 = do ist <- getIState
1063+ let maxline
1064+ = case toline of
1065+ Nothing -> Nothing
1066+ Just l -> case f of
1067+ IDR fn -> if any (fmatch fn) inputs
1068+ then Just l
1069+ else Nothing
1070+ LIDR fn -> if any (fmatch fn) inputs
1071+ then Just l
1072+ else Nothing
1073+ _ -> Nothing
1239− loadFromIFile h f
1074+ loadFromIFile h f maxline
1240 inew <- getIState
1075 inew <- getIState
1241 -- FIXME: Save these in IBC to avoid this hack! Need to
1076 -- FIXME: Save these in IBC to avoid this hack! Need to
1242 -- preserve it all from source inputs
1077 -- preserve it all from source inputs
1243 let tidata = idris_tyinfodata inew
1078 let tidata = idris_tyinfodata inew
1244− let lineapps = idris_lineapps inew
1245 let patdefs = idris_patdefs inew
1079 let patdefs = idris_patdefs inew
1246 ok <- noErrors
1080 ok <- noErrors
1247 when ok $ do when (not keepstate) $ putIState ist
1081 when ok $ do when (not keepstate) $ putIState ist
1248 ist <- getIState
1082 ist <- getIState
1249 putIState (ist { idris_tyinfodata = tidata,
1083 putIState (ist { idris_tyinfodata = tidata,
1250− idris_lineapps = lineapps,
1251 idris_patdefs = patdefs })
1084 idris_patdefs = patdefs })
1252 tryLoad keepstate fs
1085 tryLoad keepstate fs
1253
1086
1254 ibc (IBC _ _) = True
1087 ibc (IBC _ _) = True
1255 ibc _ = False
1088 ibc _ = False
1256
1089
1090+ fmatch ('.':'/':xs) ys = fmatch xs ys
1091+ fmatch xs ('.':'/':ys) = fmatch xs ys
1092+ fmatch xs ys = xs == ys
1093+
1257 findNewIBC :: IFileType -> Idris (Maybe IFileType)
1094 findNewIBC :: IFileType -> Idris (Maybe IFileType)
1258 findNewIBC i@(IBC _ _) = return (Just i)
1095 findNewIBC i@(IBC _ _) = return (Just i)
1259 findNewIBC s@(IDR f) = do ist <- get
1096 findNewIBC s@(IDR f) = do ist <- get
@@ -1310,17 +1147,20 @@ idrisMain opts =
1310 x:y:xs -> do iputStrLn "More than one interpreter expression found."
1147 x:y:xs -> do iputStrLn "More than one interpreter expression found."
1311 runIO $ exitWith (ExitFailure 1)
1148 runIO $ exitWith (ExitFailure 1)
1312 [expr] -> return (Just expr)
1149 [expr] -> return (Just expr)
1150+ let immediate = opt getEvalExpr opts
1151+
1313 when (DefaultTotal `elem` opts) $ do i <- getIState
1152 when (DefaultTotal `elem` opts) $ do i <- getIState
1314 putIState (i { default_total = True })
1153 putIState (i { default_total = True })
1315 setColourise $ not quiet && last (True : opt getColour opts)
1154 setColourise $ not quiet && last (True : opt getColour opts)
1316 when (not runrepl) $ setWidth InfinitelyWide
1155 when (not runrepl) $ setWidth InfinitelyWide
1317 mapM_ addLangExt (opt getLanguageExt opts)
1156 mapM_ addLangExt (opt getLanguageExt opts)
1318 setREPL runrepl
1157 setREPL runrepl
1319− setQuiet (quiet || isJust script)
1158+ setQuiet (quiet || isJust script || not (null immediate))
1320 setIdeSlave idesl
1159 setIdeSlave idesl
1321 setVerbose verbose
1160 setVerbose verbose
1322 setCmdLine opts
1161 setCmdLine opts
1323 setOutputTy outty
1162 setOutputTy outty
1163+ setNoBanner nobanner
1324 setCodegen cgn
1164 setCodegen cgn
1325 setTargetTriple trpl
1165 setTargetTriple trpl
1326 setTargetCPU tcpu
1166 setTargetCPU tcpu
@@ -1335,6 +1175,8 @@ idrisMain opts =
1335 (d:_) -> setIBCSubDir d
1175 (d:_) -> setIBCSubDir d
1336 setImportDirs importdirs
1176 setImportDirs importdirs
1337
1177
1178+ setNoBanner nobanner
1179+
1338 when (not (NoBasePkgs `elem` opts)) $ do
1180 when (not (NoBasePkgs `elem` opts)) $ do
1339 addPkgDir "prelude"
1181 addPkgDir "prelude"
1340 addPkgDir "base"
1182 addPkgDir "base"
@@ -1344,22 +1186,43 @@ idrisMain opts =
1344 return ()
1186 return ()
1345 when (not (NoPrelude `elem` opts)) $ do x <- loadModule stdout "Prelude"
1187 when (not (NoPrelude `elem` opts)) $ do x <- loadModule stdout "Prelude"
1346 return ()
1188 return ()
1347− when (runrepl && not quiet && not idesl && not (isJust script) && not nobanner) $ iputStrLn banner
1189+
1190+ when (runrepl && not idesl) initScript
1191+
1192+ nobanner <- getNoBanner
1193+
1194+ when (runrepl &&
1195+ not quiet &&
1196+ not idesl &&
1197+ not (isJust script) &&
1198+ not nobanner &&
1199+ null immediate) $
1200+ iputStrLn banner
1348
1201
1349 orig <- getIState
1202 orig <- getIState
1350− loadInputs stdout inputs
1203+ loadInputs stdout inputs Nothing
1351
1204
1352 runIO $ hSetBuffering stdout LineBuffering
1205 runIO $ hSetBuffering stdout LineBuffering
1353
1206
1354 ok <- noErrors
1207 ok <- noErrors
1355 when ok $ case output of
1208 when ok $ case output of
1356− -- just do the checks
1209+ [] -> return ()
1357− [] -> performUsageAnalysis >> return ()
1358−
1359− -- the compiler will run usage analysis itself
1360 (o:_) -> idrisCatch (process stdout "" (Compile cgn o))
1210 (o:_) -> idrisCatch (process stdout "" (Compile cgn o))
1361 (\e -> do ist <- getIState ; iputStrLn $ pshow ist e)
1211 (\e -> do ist <- getIState ; iputStrLn $ pshow ist e)
1362
1212
1213+ case immediate of
1214+ [] -> return ()
1215+ exprs -> do setWidth InfinitelyWide
1216+ mapM_ (\str -> do ist <- getIState
1217+ c <- colourise
1218+ case parseExpr ist str of
1219+ Failure err -> do iputStrLn $ show (fixColour c err)
1220+ runIO $ exitWith (ExitFailure 1)
1221+ Success e -> process stdout "" (Eval e))
1222+ exprs
1223+ runIO $ exitWith ExitSuccess
1224+
1225+
1363 case script of
1226 case script of
1364 Nothing -> return ()
1227 Nothing -> return ()
1365 Just expr -> execScript expr
1228 Just expr -> execScript expr
@@ -1375,7 +1238,6 @@ idrisMain opts =
1375
1238
1376 when (runrepl && not idesl) $ do
1239 when (runrepl && not idesl) $ do
1377-- clearOrigPats
1240-- clearOrigPats
1378− initScript
1379 startServer orig inputs
1241 startServer orig inputs
1380 runInputT (replSettings (Just historyFile)) $ repl orig inputs
1242 runInputT (replSettings (Just historyFile)) $ repl orig inputs
1381 when (idesl) $ ideslaveStart orig inputs
1243 when (idesl) $ ideslaveStart orig inputs
@@ -1435,7 +1297,7 @@ initScript = do script <- getInitScript
1435 case parseCmd i input cmd of
1297 case parseCmd i input cmd of
1436 Failure err -> runIO $ print (fixColour clr err)
1298 Failure err -> runIO $ print (fixColour clr err)
1437 Success Reload -> iPrintError "Init scripts cannot reload the file"
1299 Success Reload -> iPrintError "Init scripts cannot reload the file"
1438− Success (Load f) -> iPrintError "Init scripts cannot load files"
1300+ Success (Load f _) -> iPrintError "Init scripts cannot load files"
1439 Success (ModImport f) -> iPrintError "Init scripts cannot import modules"
1301 Success (ModImport f) -> iPrintError "Init scripts cannot import modules"
1440 Success Edit -> iPrintError "Init scripts cannot invoke the editor"
1302 Success Edit -> iPrintError "Init scripts cannot invoke the editor"
1441 Success Proofs -> proofs i
1303 Success Proofs -> proofs i
@@ -1483,6 +1345,18 @@ getPkgCheck :: Opt -> Maybe String
1483getPkgCheck (PkgCheck str) = Just str
1345getPkgCheck (PkgCheck str) = Just str
1484getPkgCheck _ = Nothing
1346getPkgCheck _ = Nothing
1485
1347
1348+-- | Returns None if given an Opt which is not PkgMkDoc
1349+-- Otherwise returns Just x, where x is the contents of PkgMkDoc
1350+getPkgMkDoc :: Opt -- ^ Opt to extract
1351+ -> Maybe String -- ^ Result
1352+getPkgMkDoc (PkgMkDoc str) = Just str
1353+getPkgMkDoc _ = Nothing
1354+
1355+getPkgTest :: Opt -- ^ the option to extract
1356+ -> Maybe String -- ^ the package file to test
1357+getPkgTest (PkgTest f) = Just f
1358+getPkgTest _ = Nothing
1359+
1486getCodegen :: Opt -> Maybe Codegen
1360getCodegen :: Opt -> Maybe Codegen
1487getCodegen (UseCodegen x) = Just x
1361getCodegen (UseCodegen x) = Just x
1488getCodegen _ = Nothing
1362getCodegen _ = Nothing
@@ -1491,6 +1365,10 @@ getExecScript :: Opt -> Maybe String
1491getExecScript (InterpretScript expr) = Just expr
1365getExecScript (InterpretScript expr) = Just expr
1492getExecScript _ = Nothing
1366getExecScript _ = Nothing
1493
1367
1368+getEvalExpr :: Opt -> Maybe String
1369+getEvalExpr (EvalExpr expr) = Just expr
1370+getEvalExpr _ = Nothing
1371+
1494getOutputTy :: Opt -> Maybe OutputType
1372getOutputTy :: Opt -> Maybe OutputType
1495getOutputTy (OutputTy t) = Just t
1373getOutputTy (OutputTy t) = Just t
1496getOutputTy _ = Nothing
1374getOutputTy _ = Nothing
@@ -1524,6 +1402,20 @@ banner = " ____ __ _ \n" ++
1524 " / _/___/ /____(_)____ \n" ++
1402 " / _/___/ /____(_)____ \n" ++
1525 " / // __ / ___/ / ___/ Version " ++ ver ++ "\n" ++
1403 " / // __ / ___/ / ___/ Version " ++ ver ++ "\n" ++
1526 " _/ // /_/ / / / (__ ) http://www.idris-lang.org/ \n" ++
1404 " _/ // /_/ / / / (__ ) http://www.idris-lang.org/ \n" ++
1527− " /___/\\__,_/_/ /_/____/ Type :? for help \n"
1405+ " /___/\\__,_/_/ /_/____/ Type :? for help \n" ++
1528−
1406+ "\n" ++
1529−
1407+ "Idris is free software with ABSOLUTELY NO WARRANTY. \n" ++
1408+ "For details type :warranty."
1409+
1410+warranty = "\n" ++
1411+ "\t THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY \n" ++
1412+ "\t EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE \n" ++
1413+ "\t IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR \n" ++
1414+ "\t PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE \n" ++
1415+ "\t LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR \n" ++
1416+ "\t CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF \n" ++
1417+ "\t SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR \n" ++
1418+ "\t BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \n" ++
1419+ "\t WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE \n" ++
1420+ "\t OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN\n" ++
1421+ "\t IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
src/Idris/REPLParser.hs+42−10
@@ -33,37 +33,47 @@ cmd xs = do P.lchar ':'; docmd (sortBy (\x y -> compare (length y) (length x)) x
33pCmd :: P.IdrisParser Command
33pCmd :: P.IdrisParser Command
34pCmd = do P.whiteSpace; try (do cmd ["q", "quit"]; eof; return Quit)
34pCmd = do P.whiteSpace; try (do cmd ["q", "quit"]; eof; return Quit)
35 <|> try (do cmd ["h", "?", "help"]; eof; return Help)
35 <|> try (do cmd ["h", "?", "help"]; eof; return Help)
36+ <|> try (do cmd ["w", "warranty"]; eof; return Warranty)
36 <|> try (do cmd ["r", "reload"]; eof; return Reload)
37 <|> try (do cmd ["r", "reload"]; eof; return Reload)
37 <|> try (do cmd ["module"]; f <- P.identifier; eof;
38 <|> try (do cmd ["module"]; f <- P.identifier; eof;
38 return (ModImport (toPath f)))
39 return (ModImport (toPath f)))
39 <|> try (do cmd ["e", "edit"]; eof; return Edit)
40 <|> try (do cmd ["e", "edit"]; eof; return Edit)
40 <|> try (do cmd ["exec", "execute"]; eof; return Execute)
41 <|> try (do cmd ["exec", "execute"]; eof; return Execute)
41− <|> try (do cmd ["c", "compile"]; f <- P.identifier; eof; return (Compile ViaC f))
42+ <|> try (do cmd ["c", "compile"]
42− <|> try (do cmd ["jc", "newcompile"]; f <- P.identifier; eof; return (Compile ViaJava f))
43+ i <- get
43− <|> try (do cmd ["js", "javascript"]; f <- P.identifier; eof; return (Compile ViaJavaScript f))
44+ c <- option (opt_codegen $ idris_options i) codegenOption
45+ f <- P.identifier
46+ eof
47+ return (Compile c f))
44 <|> try (do cmd ["proofs"]; eof; return Proofs)
48 <|> try (do cmd ["proofs"]; eof; return Proofs)
45 <|> try (do cmd ["rmproof"]; n <- P.name; eof; return (RmProof n))
49 <|> try (do cmd ["rmproof"]; n <- P.name; eof; return (RmProof n))
46 <|> try (do cmd ["showproof"]; n <- P.name; eof; return (ShowProof n))
50 <|> try (do cmd ["showproof"]; n <- P.name; eof; return (ShowProof n))
47 <|> try (do cmd ["log"]; i <- P.natural; eof; return (LogLvl (fromIntegral i)))
51 <|> try (do cmd ["log"]; i <- P.natural; eof; return (LogLvl (fromIntegral i)))
52+ <|> try (do cmd ["lto", "loadto"];
53+ toline <- P.natural
54+ f <- many anyChar;
55+ return (Load f (Just (fromInteger toline))))
48− <|> try (do cmd ["l", "load"]; f <- many anyChar; return (Load f))
56+ <|> try (do cmd ["l", "load"]; f <- many anyChar;
57+ return (Load f Nothing))
49 <|> try (do cmd ["cd"]; f <- many anyChar; return (ChangeDirectory f))
58 <|> try (do cmd ["cd"]; f <- many anyChar; return (ChangeDirectory f))
50 <|> try (do cmd ["spec"]; P.whiteSpace; t <- P.fullExpr defaultSyntax; return (Spec t))
59 <|> try (do cmd ["spec"]; P.whiteSpace; t <- P.fullExpr defaultSyntax; return (Spec t))
51 <|> try (do cmd ["hnf"]; P.whiteSpace; t <- P.fullExpr defaultSyntax; return (HNF t))
60 <|> try (do cmd ["hnf"]; P.whiteSpace; t <- P.fullExpr defaultSyntax; return (HNF t))
52 <|> try (do cmd ["inline"]; P.whiteSpace; t <- P.fullExpr defaultSyntax; return (TestInline t))
61 <|> try (do cmd ["inline"]; P.whiteSpace; t <- P.fullExpr defaultSyntax; return (TestInline t))
62+ <|> try (do cmd ["doc"]; c <- P.constant; eof; return (DocStr (Right c)))
53− <|> try (do cmd ["doc"]; n <- P.fnName; eof; return (DocStr n))
63+ <|> try (do cmd ["doc"]; n <- (P.fnName <|> (P.string "_|_" >> return falseTy)); eof; return (DocStr (Left n)))
54 <|> try (do cmd ["d", "def"]; some (P.char ' ') ; n <- P.fnName; eof; return (Defn n))
64 <|> try (do cmd ["d", "def"]; some (P.char ' ') ; n <- P.fnName; eof; return (Defn n))
55 <|> try (do cmd ["total"]; do n <- P.fnName; eof; return (TotCheck n))
65 <|> try (do cmd ["total"]; do n <- P.fnName; eof; return (TotCheck n))
56 <|> try (do cmd ["t", "type"]; do P.whiteSpace; t <- P.fullExpr defaultSyntax; return (Check t))
66 <|> try (do cmd ["t", "type"]; do P.whiteSpace; t <- P.fullExpr defaultSyntax; return (Check t))
57 <|> try (do cmd ["u", "universes"]; eof; return Universes)
67 <|> try (do cmd ["u", "universes"]; eof; return Universes)
58 <|> try (do cmd ["di", "dbginfo"]; n <- P.fnName; eof; return (DebugInfo n))
68 <|> try (do cmd ["di", "dbginfo"]; n <- P.fnName; eof; return (DebugInfo n))
59− <|> try (do cmd ["i", "info"]; n <- P.fnName; eof; return (Info n))
60 <|> try (do cmd ["miss", "missing"]; n <- P.fnName; eof; return (Missing n))
69 <|> try (do cmd ["miss", "missing"]; n <- P.fnName; eof; return (Missing n))
61 <|> try (do cmd ["dynamic"]; eof; return ListDynamic)
70 <|> try (do cmd ["dynamic"]; eof; return ListDynamic)
62 <|> try (do cmd ["dynamic"]; l <- many anyChar; return (DynamicLink l))
71 <|> try (do cmd ["dynamic"]; l <- many anyChar; return (DynamicLink l))
63 <|> try (do cmd ["color", "colour"]; pSetColourCmd)
72 <|> try (do cmd ["color", "colour"]; pSetColourCmd)
64 <|> try (do cmd ["set"]; o <- pOption; return (SetOpt o))
73 <|> try (do cmd ["set"]; o <- pOption; return (SetOpt o))
65 <|> try (do cmd ["unset"]; o <- pOption; return (UnsetOpt o))
74 <|> try (do cmd ["unset"]; o <- pOption; return (UnsetOpt o))
66− <|> try (do cmd ["s", "search"]; P.whiteSpace; t <- P.fullExpr defaultSyntax; return (Search t))
75+ <|> try (do cmd ["s", "search"]; P.whiteSpace;
76+ t <- P.typeExpr (defaultSyntax { implicitAllowed = True }); return (Search t))
67 <|> try (do cmd ["cs", "casesplit"]; P.whiteSpace;
77 <|> try (do cmd ["cs", "casesplit"]; P.whiteSpace;
68 upd <- option False (do P.lchar '!'; return True)
78 upd <- option False (do P.lchar '!'; return True)
69 l <- P.natural; n <- P.name;
79 l <- P.natural; n <- P.name;
@@ -84,11 +94,20 @@ pCmd = do P.whiteSpace; try (do cmd ["q", "quit"]; eof; return Quit)
84 upd <- option False (do P.lchar '!'; return True)
94 upd <- option False (do P.lchar '!'; return True)
85 l <- P.natural; n <- P.name;
95 l <- P.natural; n <- P.name;
86 return (MakeWith upd (fromInteger l) n))
96 return (MakeWith upd (fromInteger l) n))
97+ <|> try (do cmd ["ml", "makelemma"]; P.whiteSpace;
98+ upd <- option False (do P.lchar '!'; return True)
99+ l <- P.natural; n <- P.name;
100+ return (MakeLemma upd (fromInteger l) n))
87 <|> try (do cmd ["ps", "proofsearch"]; P.whiteSpace;
101 <|> try (do cmd ["ps", "proofsearch"]; P.whiteSpace;
88 upd <- option False (do P.lchar '!'; return True)
102 upd <- option False (do P.lchar '!'; return True)
89 l <- P.natural; n <- P.name;
103 l <- P.natural; n <- P.name;
90− hints <- many P.name
104+ hints <- many P.fnName
105+ return (DoProofSearch upd True (fromInteger l) n hints))
106+ <|> try (do cmd ["ref", "refine"]; P.whiteSpace;
107+ upd <- option False (do P.lchar '!'; return True)
108+ l <- P.natural; n <- P.name;
109+ hint <- P.fnName
91− return (DoProofSearch upd (fromInteger l) n hints))
110+ return (DoProofSearch upd False (fromInteger l) n [hint]))
92 <|> try (do cmd ["p", "prove"]; n <- P.name; eof; return (Prove n))
111 <|> try (do cmd ["p", "prove"]; n <- P.name; eof; return (Prove n))
93 <|> try (do cmd ["m", "metavars"]; eof; return Metavars)
112 <|> try (do cmd ["m", "metavars"]; eof; return Metavars)
94 <|> try (do cmd ["a", "addproof"]; do n <- option Nothing (do x <- P.name;
113 <|> try (do cmd ["a", "addproof"]; do n <- option Nothing (do x <- P.name;
@@ -99,6 +118,9 @@ pCmd = do P.whiteSpace; try (do cmd ["q", "quit"]; eof; return Quit)
99 <|> try (do cmd ["errorhandlers"]; eof ; return ListErrorHandlers)
118 <|> try (do cmd ["errorhandlers"]; eof ; return ListErrorHandlers)
100 <|> try (do cmd ["consolewidth"]; w <- pConsoleWidth ; return (SetConsoleWidth w))
119 <|> try (do cmd ["consolewidth"]; w <- pConsoleWidth ; return (SetConsoleWidth w))
101 <|> try (do cmd ["apropos"]; str <- many anyChar ; return (Apropos str))
120 <|> try (do cmd ["apropos"]; str <- many anyChar ; return (Apropos str))
121+ <|> try (do cmd ["wc", "whocalls"]; P.whiteSpace; n <- P.fnName ; return (WhoCalls n))
122+ <|> try (do cmd ["cw", "callswho"]; P.whiteSpace; n <- P.fnName ; return (CallsWho n))
123+ <|> try (do cmd ["mkdoc"]; str <- many anyChar; return (MakeDoc str))
102 <|> do P.whiteSpace; do eof; return NOP
124 <|> do P.whiteSpace; do eof; return NOP
103 <|> do t <- P.fullExpr defaultSyntax; return (Eval t)
125 <|> do t <- P.fullExpr defaultSyntax; return (Eval t)
104
126
@@ -109,6 +131,16 @@ pOption = do discard (P.symbol "errorcontext"); return ErrContext
109 <|> do discard (P.symbol "showimplicits"); return ShowImpl
131 <|> do discard (P.symbol "showimplicits"); return ShowImpl
110 <|> do discard (P.symbol "originalerrors"); return ShowOrigErr
132 <|> do discard (P.symbol "originalerrors"); return ShowOrigErr
111 <|> do discard (P.symbol "autosolve"); return AutoSolve
133 <|> do discard (P.symbol "autosolve"); return AutoSolve
134+ <|> do discard (P.symbol "nobanner") ; return NoBanner
135+ <|> do discard (P.symbol "warnreach"); return WarnReach
136+
137+codegenOption :: P.IdrisParser Codegen
138+codegenOption = do discard (P.symbol "javascript"); return ViaJavaScript
139+ <|> do discard (P.symbol "node"); return ViaNode
140+ <|> do discard (P.symbol "Java"); return ViaJava
141+ <|> do discard (P.symbol "llvm"); return ViaLLVM
142+ <|> do discard (P.symbol "bytecode"); return Bytecode
143+ <|> do discard (P.symbol "C"); return ViaC
112
144
113pConsoleWidth :: P.IdrisParser ConsoleWidth
145pConsoleWidth :: P.IdrisParser ConsoleWidth
114pConsoleWidth = do discard (P.symbol "auto"); return AutomaticWidth
146pConsoleWidth = do discard (P.symbol "auto"); return AutomaticWidth
@@ -152,7 +184,7 @@ pColourMod = try (P.symbol "vivid" >> return doVivid)
152 doNoItalic i = i { italic = False }
184 doNoItalic i = i { italic = False }
153 doSetColour c i = i { colour = c }
185 doSetColour c i = i { colour = c }
154
186
155−
187+-- | Generate the colour type names using the default Show instance.
156colourTypes :: [(String, ColourType)]
188colourTypes :: [(String, ColourType)]
157colourTypes = map (\x -> ((map toLower . reverse . drop 6 . reverse . show) x, x)) $
189colourTypes = map (\x -> ((map toLower . reverse . drop 6 . reverse . show) x, x)) $
158 enumFromTo minBound maxBound
190 enumFromTo minBound maxBound
src/Idris/TypeSearch.hsnew file+303
@@ -0,0 +1,303 @@
1+module Idris.TypeSearch (
2+ searchByType, searchPred, defaultScoreFunction
3+) where
4+
5+import Control.Applicative ((<$>), (<*>), (<|>))
6+import Control.Arrow (first, second, (&&&))
7+import Control.Monad (forM_, guard)
8+
9+import Data.Function (on)
10+import Data.List (find, minimumBy, sortBy, (\\))
11+import Data.Map (Map)
12+import qualified Data.Map as M
13+import Data.Maybe (catMaybes, fromMaybe, isJust)
14+import Data.Monoid (Monoid (mempty, mappend))
15+import Data.Set (Set)
16+import qualified Data.Set as S
17+
18+import Idris.AbsSyntax (addUsingConstraints, addImpl, getContext, getIState, putIState, implicit)
19+import Idris.AbsSyntaxTree (class_instances, defaultSyntax, Idris,
20+ IState (idris_classes, idris_docstrings, tt_ctxt),
21+ implicitAllowed, prettyDocumentedIst, prettyIst, PTerm, toplevel)
22+import Idris.Core.Evaluate (Context (definitions), Def (Function, TyDecl, CaseOp), normaliseC)
23+import Idris.Core.TT
24+import Idris.Core.Unify (match_unify)
25+import Idris.Delaborate (delab, delabTy)
26+import Idris.Docstrings (noDocs, overview)
27+import Idris.ElabDecls (elabType')
28+import Idris.Output (ihRenderResult, ihPrintResult, ihPrintFunTypes)
29+
30+import System.IO (Handle)
31+
32+import Util.Pretty (text, vsep, char, (<>), Doc)
33+
34+searchByType :: Handle -> PTerm -> Idris ()
35+searchByType h pterm = do
36+ pterm' <- addUsingConstraints syn emptyFC pterm
37+ pterm'' <- implicit toplevel syn n pterm'
38+ i <- getIState
39+ let pterm''' = addImpl i pterm''
40+ ty <- elabType' False toplevel syn (fst noDocs) (snd noDocs) emptyFC [] n pterm'
41+ putIState i -- don't actually make any changes
42+ let names = searchUsing searchPred i ty
43+ let names' = take numLimit . takeWhile ((< scoreLimit) . getScore) $
44+ sortBy (compare `on` getScore) names
45+ let docs =
46+ [ let docInfo = (n, delabTy i n, fmap (overview . fst) (lookupCtxtExact n (idris_docstrings i))) in
47+ displayScore score <> char ' ' <> prettyDocumentedIst i docInfo
48+ | (n, (_,score)) <- names']
49+ ihRenderResult h $ vsep docs
50+ where
51+ getScore = defaultScoreFunction . snd . snd
52+ numLimit = 50
53+ scoreLimit = 100
54+ syn = defaultSyntax { implicitAllowed = True } -- syntax
55+ n = sMN 0 "searchType" -- name
56+
57+
58+searchUsing :: (IState -> Type -> Type -> Maybe a) -> IState -> Type -> [(Name, (Type, a))]
59+searchUsing pred istate ty =
60+ concat . M.elems $ M.mapWithKey (\key -> M.toAscList . M.mapMaybe (f key)) (definitions ctxt)
61+ where
62+ ctxt = tt_ctxt istate
63+ f k x = do
64+ guard $ not (special k)
65+ y <- get (fst4 x)
66+ let ny = normaliseC ctxt [] y
67+ -- traceShow k False `seq` return ()
68+ val <- pred istate nty ny
69+ return (y, val)
70+ nty = normaliseC ctxt [] ty
71+ fst4 :: (a,b,c,d) -> a
72+ fst4 (w,x,y,z) = w
73+ get :: Def -> Maybe Type
74+ get (Function ty tm) = Just ty
75+ get (TyDecl _ ty) = Just ty
76+ -- get (Operator ty _ _) = Just ty
77+ get (CaseOp _ ty _ _ _ _) = Just ty
78+ get _ = Nothing
79+ special :: Name -> Bool
80+ special (SN _) = True
81+ special _ = False
82+
83+
84+tcToMaybe :: TC' e a -> Maybe a
85+tcToMaybe (OK x) = Just x
86+tcToMaybe (Error _) = Nothing
87+
88+
89+
90+searchPred :: IState -> Type -> Type -> Maybe Score
91+searchPred istate ty1 = \ty2 -> case matcher ty2 of
92+ Nothing -> Nothing
93+ Just xs -> guard (not (null xs)) >> return (minimumBy (compare `on` defaultScoreFunction) xs)
94+ where
95+ matcher = unifyWithHoles True istate ty1
96+
97+
98+
99+
100+reverseDag :: Ord k => [((k, a), Set k)] -> [((k, a), Set k)]
101+reverseDag xs = map f xs where
102+ f ((k, v), _) = ((k, v), S.fromList . map (fst . fst) $ filter (S.member k . snd) xs)
103+
104+-- run vToP first!
105+-- returns [(the name and type of the bound variable
106+-- the names in the type of the bound variable)]
107+computeDagP :: Ord n => TT n -> ([((n, TT n), Set n)], TT n)
108+computeDagP t = (reverse (map f args), retTy) where
109+
110+ f (n, t) = ((n, t), M.keysSet (usedVars t))
111+
112+ (numArgs, args, retTy) = go 0 [] t
113+
114+ -- NOTE : args are in reverse order
115+ go k args (Bind n (Pi t) sc) = go (succ k) ( (n, t) : args ) sc
116+ go k args retTy = (k, args, retTy)
117+
118+
119+usedVars :: Ord n => TT n -> Map n (TT n)
120+usedVars (V j) = error "unexpected! run vToP first"
121+usedVars (P Bound n t) = M.singleton n t `M.union` usedVars t
122+usedVars (Bind n binder t2) = (M.delete n (usedVars t2) `M.union`) $ case binder of
123+ Let t v -> usedVars t `M.union` usedVars v
124+ Guess t v -> usedVars t `M.union` usedVars v
125+ b -> usedVars (binderTy b)
126+usedVars (App t1 t2) = usedVars t1 `M.union` usedVars t2
127+usedVars (Proj t _) = usedVars t
128+usedVars _ = M.empty
129+
130+deleteFromDag :: Ord n => n -> [((n, TT n), (a, Set n))] -> [((n, TT n), (a, Set n))]
131+deleteFromDag name [] = []
132+deleteFromDag name (((name2, ty), (ix, set)) : xs) = (if name == name2
133+ then id
134+ else (((name2, ty) , (ix, S.delete name set)) :) ) (deleteFromDag name xs)
135+
136+
137+data Score = Score
138+ { transposition :: Int
139+ , leftApplied :: Int
140+ , rightApplied :: Int
141+ , leftTypeClass :: Int
142+ , rightTypeClass :: Int } deriving (Eq, Show)
143+
144+displayScore :: Score -> Doc a
145+displayScore (Score trans lapp rapp lclass rclass) = text $ case (lt, gt) of
146+ (True , True ) -> "="
147+ (True , False) -> "<"
148+ (False, True ) -> ">"
149+ (False, False) -> " "
150+ where lt = lapp + lclass == 0
151+ gt = rapp + rclass == 0
152+
153+
154+scoreCriterion :: Score -> Bool
155+scoreCriterion (Score a b c d e) = True {- not
156+ ( (b > 0 && c > 0) || (b + c) > 2 ) -}
157+
158+defaultScoreFunction :: Score -> Int
159+defaultScoreFunction (Score a b c d e) = a + 9*b + 3*c + 12*d + 4*e + 100*(2*b + d)*(2*c + e)
160+ -- it's very bad to have *both* upcasting and downcasting
161+
162+instance Monoid Score where
163+ mempty = Score 0 0 0 0 0
164+ (Score a b c d e) `mappend` (Score a' b' c' d' e') = Score (a + a') (b + b') (c + c') (d + d') (e + e')
165+
166+
167+type ArgsDAG = [((Name, Type), (Int, Set Name))]
168+type ResType = ( [Name] , ArgsDAG , ArgsDAG )
169+
170+data State = State
171+ { holes :: ![Name]
172+ , args1 :: !ArgsDAG
173+ , args2 :: !ArgsDAG
174+ , score :: !Score
175+ }
176+
177+
178+--DONT run vToP first!
179+unifyWithHoles :: Bool -> IState -> Type -> Type -> Maybe [Score]
180+unifyWithHoles debugParam istate type1 = \type2 -> let
181+ (dag2, retTy2) = makeDag (uniqueBinders argNames1 type2)
182+ argNames2 = map (fst . fst) dag2
183+ startingHoles = argNames1 ++ argNames2
184+
185+ startingTypes = (retTy1, retTy2) : []
186+ in do
187+ state <- go (State startingHoles dag1 dag2 mempty) startingTypes
188+ return $ processDags state
189+ where
190+ ctxt = tt_ctxt istate
191+ classInfo = idris_classes istate
192+ (dag1, retTy1) = makeDag type1
193+ argNames1 = map (fst . fst) dag1
194+ makeDag = first (zipWith (\i (ty, deps) -> (ty, (i, deps))) [0..] . reverseDag) . computeDagP . vToP
195+
196+ matchf :: (Name, Term) -> Maybe (Name, Name)
197+ matchf (name, P Bound name2 _) = Just (name, name2)
198+ matchf _ = Nothing
199+
200+ -- update our state with the unification resolutions
201+ updateDags :: [(Name, Type)] -> ResType -> Maybe (ResType, [(Type, Type)], Score)
202+ updateDags [] res = Just (res, [], mempty)
203+ updateDags ((name, term@(P Bound name2 _)) : xs) (holes, args1, args2) | isJust findArgs = do
204+ ((ty1, ix1), (ty2, ix2)) <- findArgs
205+
206+ (res, queue, score) <- updateDags xs (holes', args1'', args2'')
207+ --traceShow (ty1, ty2) False `seq` return ()
208+ return $ (res, (ty1, ty2) : queue , score { transposition = transposition score + abs (ix2 - ix1) })
209+ where
210+ findArgs = ((,) <$> mgetType name args1 <*> mgetType name2 args2) <|>
211+ ((,) <$> mgetType name2 args1 <*> mgetType name args2)
212+ matchnames = [name, name2]
213+ holes' = holes \\ matchnames
214+ substf = deleteFromDag name . deleteFromDag name2
215+ args1' = substf args1
216+ args2' = substf args2
217+ args1'' = map (first . second $ subst name term) args1'
218+ args2'' = map (first . second $ subst name term) args2'
219+ mgetType name xs = fmap ((snd . fst) &&& (fst . snd)) . find ((name ==) . fst . fst) $ xs
220+
221+ updateDags ((name, term) : xs) (holes, args1, args2) = case (mgetType name args1, mgetType name args2) of
222+ (Just (_,ix), Nothing) -> thrd (\score -> score { leftApplied = succ (leftApplied score) }) <$> nextStep
223+ (Nothing, Just (_, ix)) -> thrd (\score -> score { rightApplied = succ (rightApplied score) }) <$> nextStep
224+ (Nothing, Nothing) -> nextStep
225+ _ -> error ("Shouldn't happen. Watch the alpha conversion!\n" ++ show args1 ++ "\n\n" ++ show args2)
226+ where
227+ varsInTy = map fst $ M.toList (usedVars term)
228+ deleteMany = foldr (.) id $ map deleteFromDag (name : varsInTy)
229+ thrd f (a,b,c) = (a,b,f c)
230+ nextStep = updateDags xs (holes \\ [name], updatef args1, updatef args2 )
231+ updatef = map (first . second $ subst name term) . deleteMany
232+ mgetType name xs = fmap ((snd . fst) &&& (fst . snd)) . find ((name ==) . fst . fst) $ xs
233+
234+
235+ go :: State -> [(Type, Type)] -> Maybe State
236+ --go (State holes args1 args2 score) queue | trace ("go\n\t" ++ show holes ++ "\n\t" ++ show args1 ++ "\n\t" ++ show args2 ++ "\n\t" ++ show queue) False = undefined
237+ go state [] = return state
238+ go (State holes args1 args2 score) ((ty1, ty2) : queue) = do
239+ res <- tcToMaybe $ match_unify ctxt [] ty1 ty2 [] holes []
240+ --trace ("UnifyResult: " ++ show (ty1, ty2, res, errors)) False `seq` return ()
241+ --guard (null errors)
242+ ((holes', args1', args2'), queueAdditions, scoreAdditions) <- updateDags res (holes, args1, args2)
243+ let newScore = score `mappend` scoreAdditions
244+ guard $ scoreCriterion newScore
245+ go (State holes' args1' args2' newScore) (queue ++ queueAdditions)
246+
247+
248+ processDags :: State -> [Score]
249+ processDags (State [] [] [] scoreAcc) = [scoreAcc]
250+ --processDags (State holes (_:_) [] scoreAcc) = []
251+ --processDags (State holes [] (_:_) scoreAcc) = []
252+ processDags (State holes dag1 dag2 scoreAcc) = concat [ processDags state | state <- allResults ] where
253+
254+ results = catMaybes [ go (State (holes \\ (map nameOf [ty1, ty2])) (deleteFromDag (nameOf ty1) dag1)
255+ (inArgTys (psubst (nameOf ty2) (P Bound (nameOf ty1) (typeOf ty1))) $ deleteFromDag (nameOf ty2) dag2) scoreAcc) [(typeOf ty1, typeOf ty2)]
256+ | ty1 <- canBeFirst dag1, ty2 <- canBeFirst dag2 {-, exactTypeEquality ctxt (typeOf ty1) (typeOf ty2) -} ]
257+
258+ results2 = [ State (holes \\ [nameOf ty])
259+ (deleteFromDag (nameOf ty) dag1) dag2
260+ (scoreAcc `mappend` (mempty { leftTypeClass = 1 }))
261+ | ty <- typeClassArgs1 ]
262+
263+ typeClassArgs1 = filter (isSaturatedClass . typeOf) dag1
264+ typeClassArgs2 = filter (isSaturatedClass . typeOf) dag2
265+
266+
267+ results3 = [ State (holes \\ [nameOf ty])
268+ dag1 (deleteFromDag (nameOf ty) dag2)
269+ (scoreAcc `mappend` (mempty { rightTypeClass = 1 }))
270+ | ty <- typeClassArgs2 ]
271+
272+ allResults :: [State]
273+ allResults = {- (if not (null typeClasses) then (traceShow typeClasses False `seq` id) else id ) -}
274+ (results ++ results2 ++ results3)
275+ where
276+ typeClasses = filter (isSaturatedClass . typeOf) (dag1 ++ dag2)
277+
278+
279+ -- check if the canBeFirst thing is losing any possibilities
280+
281+
282+ inArgTys = map . first . second
283+ typeOf ((name, ty), set) = ty
284+ nameOf ((name, ty), set) = name
285+
286+ -- XXX : debug stuff
287+ canBeFirst = if debugParam then filter (S.null . snd . snd) else id
288+ holes = map (fst . fst) dag1 ++ map (fst . fst) dag2
289+
290+ deleteIdx _ [] = []
291+ deleteIdx idx l@(x@(i,_,_) : xs) = if i == idx then xs else x : deleteIdx idx xs
292+
293+ isSaturatedClass :: Type -> Bool
294+ isSaturatedClass ty = fromMaybe False $ do
295+ className <- getClassName clss
296+ let possInstances = concatMap class_instances $ lookupCtxt className classInfo
297+ return $ (SN (sInstanceN className (map argToName args))) `elem` possInstances
298+ where
299+ (clss, args) = unApply ty
300+ getClassName (P (TCon _ _) className _) = Just className
301+ getClassName _ = Nothing
302+ argToName arg = show (delab istate arg)
303+
src/Idris/WhoCalls.hsnew file+93
@@ -0,0 +1,93 @@
1+module Idris.WhoCalls (whoCalls, callsWho) where
2+
3+import Idris.AbsSyntax
4+
5+import Idris.Core.CaseTree
6+import Idris.Core.Evaluate
7+import Idris.Core.TT
8+
9+import Data.List (nub)
10+
11+
12+occurs :: Name -> Term -> Bool
13+occurs n (P Bound _ _) = False
14+occurs n (P _ n' _) = n == n'
15+occurs n (Bind _ b sc) = occursBinder n b || occurs n sc
16+occurs n (App t1 t2) = occurs n t1 || occurs n t2
17+occurs n (Proj t _) = occurs n t
18+occurs n _ = False
19+
20+names :: Term -> [Name]
21+names (P Bound _ _) = []
22+names (P _ n _) = [n]
23+names (Bind _ b sc) = namesBinder b ++ names sc
24+names (App t1 t2) = names t1 ++ names t2
25+names (Proj t _) = names t
26+names _ = []
27+
28+occursBinder :: Name -> Binder Term -> Bool
29+occursBinder n (Let ty val) = occurs n ty || occurs n val
30+occursBinder n (NLet ty val) = occurs n ty || occurs n val
31+occursBinder n b = occurs n (binderTy b)
32+
33+namesBinder :: Binder Term -> [Name]
34+namesBinder (Let ty val) = names ty ++ names val
35+namesBinder (NLet ty val) = names ty ++ names val
36+namesBinder b = names (binderTy b)
37+
38+occursSC :: Name -> SC -> Bool
39+occursSC n (Case _ alts) = any (occursCaseAlt n) alts
40+occursSC n (ProjCase t alts) = occurs n t || any (occursCaseAlt n) alts
41+occursSC n (STerm t) = occurs n t
42+occursSC n _ = False
43+
44+namesSC :: SC -> [Name]
45+namesSC (Case _ alts) = concatMap namesCaseAlt alts
46+namesSC (ProjCase t alts) = names t ++ concatMap namesCaseAlt alts
47+namesSC (STerm t) = names t
48+namesSC _ = []
49+
50+occursCaseAlt :: Name -> CaseAlt -> Bool
51+occursCaseAlt n (ConCase n' _ _ sc) = n == n' || occursSC n sc
52+occursCaseAlt n (FnCase n' _ sc) = n == n' || occursSC n sc
53+occursCaseAlt n (ConstCase _ sc) = occursSC n sc
54+occursCaseAlt n (SucCase _ sc) = occursSC n sc
55+occursCaseAlt n (DefaultCase sc) = occursSC n sc
56+
57+namesCaseAlt :: CaseAlt -> [Name]
58+namesCaseAlt (ConCase n' _ _ sc) = n' : namesSC sc
59+namesCaseAlt (FnCase n' _ sc) = n' : namesSC sc
60+namesCaseAlt (ConstCase _ sc) = namesSC sc
61+namesCaseAlt (SucCase _ sc) = namesSC sc
62+namesCaseAlt (DefaultCase sc) = namesSC sc
63+
64+occursDef :: Name -> Def -> Bool
65+occursDef n (Function ty tm) = occurs n ty || occurs n tm
66+occursDef n (TyDecl _ ty) = occurs n ty
67+occursDef n (Operator ty _ _) = occurs n ty
68+occursDef n (CaseOp _ ty _ _ _ defs) = occurs n ty || occursSC n (snd (cases_compiletime defs))
69+
70+namesDef :: Def -> [Name]
71+namesDef (Function ty tm) = names ty ++ names tm
72+namesDef (TyDecl _ ty) = names ty
73+namesDef (Operator ty _ _) = names ty
74+namesDef (CaseOp _ ty _ _ _ defs) = names ty ++ namesSC (snd (cases_compiletime defs))
75+
76+findOccurs :: Name -> Idris [Name]
77+findOccurs n = do ctxt <- getContext
78+ -- A definition calls a function if the function is in the type or RHS of the definition
79+ let defs = (map fst . filter (\(n', def) -> n /= n' && occursDef n def) . ctxtAlist) ctxt
80+ -- A datatype calls its
81+ return defs
82+
83+whoCalls :: Name -> Idris [(Name, [Name])]
84+whoCalls n = do ctxt <- getContext
85+ let names = lookupNames n ctxt
86+ find nm = do ns <- findOccurs nm
87+ return (nm, nub ns)
88+ mapM find names
89+
90+callsWho :: Name -> Idris [(Name, [Name])]
91+callsWho n = do ctxt <- getContext
92+ let defs = lookupNameDef n ctxt
93+ return $ map (\ (n, def) -> (n, nub $ namesDef def)) defs
src/Pkg/PParser.hs+15−3
@@ -1,3 +1,5 @@
1+{-# LANGUAGE OverlappingInstances #-}
2+
1module Pkg.PParser where
3module Pkg.PParser where
2
4
3import Text.Trifecta hiding (span, stringLiteral, charLiteral, natural, symbol, char, string, whiteSpace)
5import Text.Trifecta hiding (span, stringLiteral, charLiteral, natural, symbol, char, string, whiteSpace)
@@ -6,6 +8,7 @@ import Idris.Core.TT
6import Idris.REPL
8import Idris.REPL
7import Idris.AbsSyntaxTree
9import Idris.AbsSyntaxTree
8import Idris.ParseHelpers
10import Idris.ParseHelpers
11+import Idris.CmdOptions
9
12
10import Paths_idris
13import Paths_idris
11
14
@@ -23,11 +26,16 @@ data PkgDesc = PkgDesc { pkgname :: String,
23 sourcedir :: String,
26 sourcedir :: String,
24 modules :: [Name],
27 modules :: [Name],
25 idris_main :: Name,
28 idris_main :: Name,
26− execout :: Maybe String
29+ execout :: Maybe String,
30+ idris_tests :: [Name]
27 }
31 }
28 deriving Show
32 deriving Show
29
33
34+instance TokenParsing PParser where
35+ someSpace = many (simpleWhiteSpace <|> singleLineComment <|> multiLineComment) *> pure ()
36+
37+
30−defaultPkg = PkgDesc "" [] [] Nothing [] "" [] (sUN "") Nothing
38+defaultPkg = PkgDesc "" [] [] Nothing [] "" [] (sUN "") Nothing []
31
39
32parseDesc :: FilePath -> IO PkgDesc
40parseDesc :: FilePath -> IO PkgDesc
33parseDesc fp = do p <- readFile fp
41parseDesc fp = do p <- readFile fp
@@ -60,7 +68,7 @@ pClause = do reserved "executable"; lchar '=';
60 <|> do reserved "opts"; lchar '=';
68 <|> do reserved "opts"; lchar '=';
61 opts <- stringLiteral
69 opts <- stringLiteral
62 st <- get
70 st <- get
63− let args = parseArgs (words opts)
71+ let args = pureArgParser (words opts)
64 put (st { idris_opts = args })
72 put (st { idris_opts = args })
65 <|> do reserved "modules"; lchar '=';
73 <|> do reserved "modules"; lchar '=';
66 ms <- sepBy1 (iName []) (lchar ',')
74 ms <- sepBy1 (iName []) (lchar ',')
@@ -78,4 +86,8 @@ pClause = do reserved "executable"; lchar '=';
78 mk <- iName []
86 mk <- iName []
79 st <- get
87 st <- get
80 put (st { makefile = Just (show mk) })
88 put (st { makefile = Just (show mk) })
89+ <|> do reserved "tests"; lchar '=';
90+ ts <- sepBy1 (iName []) (lchar ',')
91+ st <- get
92+ put st { idris_tests = idris_tests st ++ ts }
81
93
src/Pkg/Package.hs+76−3
@@ -5,18 +5,24 @@ import System.Process
5import System.Directory
5import System.Directory
6import System.Exit
6import System.Exit
7import System.IO
7import System.IO
8−import System.FilePath ((</>), addTrailingPathSeparator, takeFileName)
8+import System.FilePath ((</>), addTrailingPathSeparator, takeFileName, takeDirectory, normalise)
9import System.Directory (createDirectoryIfMissing, copyFile)
9import System.Directory (createDirectoryIfMissing, copyFile)
10
10
11import Util.System
11import Util.System
12
12
13import Control.Monad
13import Control.Monad
14+import Control.Monad.Trans.State.Strict (execStateT)
15+import Control.Monad.Error (runErrorT)
16+
14import Data.List
17import Data.List
15import Data.List.Split(splitOn)
18import Data.List.Split(splitOn)
16
19
17import Idris.Core.TT
20import Idris.Core.TT
18import Idris.REPL
21import Idris.REPL
22+import Idris.Parser (loadModule)
23+import Idris.Output (pshow)
19import Idris.AbsSyntax
24import Idris.AbsSyntax
25+import Idris.IdrisDoc
20import Idris.Output
26import Idris.Output
21
27
22import IRTS.System
28import IRTS.System
@@ -74,7 +80,7 @@ checkPkg :: Bool -- ^ Show Warnings
74 -> FilePath -- ^ Path to ipkg file.
80 -> FilePath -- ^ Path to ipkg file.
75 -> IO ()
81 -> IO ()
76checkPkg warnonly quit fpath
82checkPkg warnonly quit fpath
77− = do pkgdesc <-parseDesc fpath
83+ = do pkgdesc <- parseDesc fpath
78 ok <- mapM (testLib warnonly (pkgname pkgdesc)) (libdeps pkgdesc)
84 ok <- mapM (testLib warnonly (pkgname pkgdesc)) (libdeps pkgdesc)
79 when (and ok) $
85 when (and ok) $
80 do dir <- getCurrentDirectory
86 do dir <- getCurrentDirectory
@@ -122,6 +128,74 @@ cleanPkg fp
122 Nothing -> return ()
128 Nothing -> return ()
123 Just s -> rmFile $ dir </> s
129 Just s -> rmFile $ dir </> s
124
130
131+-- | Generate IdrisDoc for package
132+-- TODO: Handle case where module does not contain a matching namespace
133+-- E.g. from prelude.ipkg: IO, Prelude.Chars, Builtins
134+documentPkg :: FilePath -- ^ Path to .ipkg file.
135+ -> IO ()
136+documentPkg fp =
137+ do pkgdesc <- parseDesc fp
138+ cd <- getCurrentDirectory
139+ let pkgDir = cd </> takeDirectory fp
140+ outputDir = cd </> (pkgname pkgdesc) ++ "_doc"
141+ opts = NoREPL : Verbose : idris_opts pkgdesc
142+ mods = modules pkgdesc
143+ fs = map (foldl1' (</>) . splitOn "." . showCG) mods
144+ setCurrentDirectory $ pkgDir </> sourcedir pkgdesc
145+ make (makefile pkgdesc)
146+ setCurrentDirectory $ pkgDir
147+ let run l = runErrorT . (execStateT l)
148+ load [] = return ()
149+ load (f:fs) = do loadModule stdout f; load fs
150+ loader = do idrisMain opts; load fs
151+ idrisInstance <- run loader idrisInit
152+ setCurrentDirectory cd
153+ case idrisInstance of
154+ Left err -> do putStrLn $ pshow idrisInit err; exitWith (ExitFailure 1)
155+ Right ist ->
156+ do docRes <- generateDocs ist mods outputDir
157+ case docRes of
158+ Right _ -> return ()
159+ Left msg -> do putStrLn msg
160+ exitWith (ExitFailure 1)
161+
162+-- | Build a package with a sythesized main function that runs the tests
163+testPkg :: FilePath -> IO ()
164+testPkg fp
165+ = do pkgdesc <- parseDesc fp
166+ ok <- mapM (testLib True (pkgname pkgdesc)) (libdeps pkgdesc)
167+ when (and ok) $
168+ do dir <- getCurrentDirectory
169+ setCurrentDirectory $ dir </> sourcedir pkgdesc
170+ make (makefile pkgdesc)
171+ -- Get a temporary file to save the tests' source in
172+ (tmpn, tmph) <- tempIdr
173+ hPutStrLn tmph $
174+ "module Test_______\n" ++
175+ concat ["import " ++ show m ++ "\n"
176+ | m <- modules pkgdesc] ++
177+ "namespace Main\n" ++
178+ " main : IO ()\n" ++
179+ " main = do " ++
180+ concat [show t ++ "\n "
181+ | t <- idris_tests pkgdesc]
182+ hClose tmph
183+ (tmpn', tmph') <- tempfile
184+ hClose tmph'
185+ m_ist <- idris (Filename tmpn : NoREPL : Verbose : Output tmpn' : idris_opts pkgdesc)
186+ system tmpn'
187+ setCurrentDirectory dir
188+ case m_ist of
189+ Nothing -> exitWith (ExitFailure 1)
190+ Just ist -> do
191+ -- Quit with error code if problem building
192+ case errSpan ist of
193+ Just _ -> exitWith (ExitFailure 1)
194+ _ -> return ()
195+ where tempIdr :: IO (FilePath, Handle)
196+ tempIdr = do dir <- getTemporaryDirectory
197+ openTempFile (normalise dir) "idristests.idr"
198+
125-- | Install package
199-- | Install package
126installPkg :: PkgDesc -> IO ()
200installPkg :: PkgDesc -> IO ()
127installPkg pkgdesc
201installPkg pkgdesc
@@ -132,7 +206,6 @@ installPkg pkgdesc
132 Just o -> return () -- do nothing, keep executable locally, for noe
206 Just o -> return () -- do nothing, keep executable locally, for noe
133 mapM_ (installObj (pkgname pkgdesc)) (objs pkgdesc)
207 mapM_ (installObj (pkgname pkgdesc)) (objs pkgdesc)
134
208
135−
136-- ---------------------------------------------------------- [ Helper Methods ]
209-- ---------------------------------------------------------- [ Helper Methods ]
137-- Methods for building, testing, installing, and removal of idris
210-- Methods for building, testing, installing, and removal of idris
138-- packages.
211-- packages.
test/Makefile+1−1
@@ -11,7 +11,7 @@ test_java:
11 perl ./runtest.pl without buffer001 reg039 --codegen Java
11 perl ./runtest.pl without buffer001 reg039 --codegen Java
12
12
13test_js:
13test_js:
14− @perl ./runtest.pl without sugar004 reg029 io001 dsl002 io003 effects001 effects002 buffer001 bounded001 folding002 --codegen node
14+ @perl ./runtest.pl without sugar004 reg029 io001 dsl002 io003 effects001 effects002 buffer001 --codegen node
15
15
16test_llvm:
16test_llvm:
17 @perl ./runtest.pl without sugar004 io003 buffer001 --codegen llvm
17 @perl ./runtest.pl without sugar004 io003 buffer001 --codegen llvm
test/README+1
@@ -5,6 +5,7 @@ dsl: Embedded DSLs and features to support DSL development
5effects: Effects package
5effects: Effects package
6error: Error messages and error reflection
6error: Error messages and error reflection
7ffi: FFI calls, including type providers
7ffi: FFI calls, including type providers
8+idrisdoc: Documentation tool functionality
8interactive: Interactive editing, proof search
9interactive: Interactive editing, proof search
9io: IO monad
10io: IO monad
10literate: .lidr files; literate programming
11literate: .lidr files; literate programming
test/basic006/expected+2−2
@@ -1,5 +1,5 @@
1−When elaborating right hand side of foo:
1+test020a.idr:14:18:When elaborating right hand side of foo:
2−test020a.idr:14:18:When elaborating an application of function Prelude.List.reverse:
2+When elaborating an application of function Prelude.List.reverse:
3 Can't unify
3 Can't unify
4 Vect n a
4 Vect n a
5 with
5 with
test/basic010/Main.idrnew file+43
@@ -0,0 +1,43 @@
1+module Main
2+
3+%default total
4+
5+-- An expensive function.
6+qib : Nat -> Nat
7+qib Z = 1
8+qib (S Z) = 2
9+qib (S (S n)) = qib n * qib (S n)
10+
11+-- An equality whose size reflects the size of numbers.
12+data equals : Nat -> Nat -> Type where
13+ eqZ : Z `equals` Z
14+ eqS : m `equals` n -> S m `equals` S n
15+
16+eq_refl : {n : Nat} -> n `equals` n
17+eq_refl {n = Z} = eqZ
18+eq_refl {n = S n} = eqS eq_refl
19+
20+-- Here, the proof is very expensive to compute.
21+-- We add a recursive argument to prevent Idris from inlining the function.
22+f : (r, n : Nat) -> Subset Nat (\k => qib n `equals` qib k)
23+f Z n = element n eq_refl
24+f (S r) n = f r n
25+
26+-- A (contrived) relation, just to have something to show.
27+data represents : Nat -> Nat -> Type where
28+ axiom : (n : Nat) -> qib n `represents` n
29+
30+-- Here, the witness is very expensive to compute.
31+-- We add a recursive argument to prevent Idris from inlining the function.
32+g : (r, n : Nat) -> Exists (\k : Nat => k `represents` n)
33+g Z n = evidence (qib n) (axiom n)
34+g (S r) n = g r n
35+
36+fmt : qib n `represents` n -> String
37+fmt (axiom n) = "axiom " ++ show n
38+
39+main : IO ()
40+main = do
41+ n <- map (const 10000) (putStrLn "*oink*")
42+ putStrLn . show $ getWitness (f 4 n)
43+ putStrLn . fmt $ getProof (g 4 n)
test/basic010/expectednew file+3
@@ -0,0 +1,3 @@
1+*oink*
2+10000
3+axiom 10000
test/basic010/runnew file+35
@@ -0,0 +1,35 @@
1+#!/usr/bin/env bash
2+
3+# From http://unix.stackexchange.com/questions/43340/how-to-introduce-timeout-for-shell-scripting
4+# Here copied from reg039.
5+#
6+# Executes command with a timeout
7+# Params:
8+# $1 timeout in seconds
9+# $2 command
10+# Returns 1 if timed out 0 otherwise
11+timeout() {
12+
13+ time=$1
14+
15+ # start the command in a subshell to avoid problem with pipes
16+ # (spawn accepts one command)
17+ command="/bin/sh -c \"$2\""
18+
19+ expect -c "set echo \"-noecho\"; set timeout $time; spawn -noecho $command; expect timeout { exit 1 } eof { exit 0 }"
20+
21+ if [ $? = 1 ] ; then
22+ echo "Timeout after ${time} seconds"
23+ fi
24+
25+}
26+
27+declare -a extraargs
28+for arg in "$@"
29+do
30+ extraargs=("${extraargs[@]}" "'$arg'")
31+done
32+
33+timeout 10 "idris ${extraargs[*]} Main.idr --nocolour --check --warnreach -o basic010"
34+timeout 5 "./basic010"
35+rm -f *.ibc basic010
test/ffi005/Postulate.idr+3−3
@@ -4,10 +4,10 @@ import Providers
4
4
5%language TypeProviders
5%language TypeProviders
6
6
7−bad : IO (Provider _|_)
7+bad : IO (Provider Type)
8−bad = pure Postulate
8+bad = return $ pure _|_
9
9
10−%provide (oops : _|_) with bad
10+%provide postulate oops with bad
11
11
12main : IO ()
12main : IO ()
13main = putStrLn "oops"
13main = putStrLn "oops"
test/ffi005/Postulate2.idrdeleted−13
@@ -1,13 +0,0 @@
1−module Main
2−
3−import Providers
4−
5−%language TypeProviders
6−
7−bad : IO (Provider _|_)
8−bad = pure Postulate
9−
10−%provide postulate (oops : _|_) with bad
11−
12−main : IO ()
13−main = putStrLn "oops"
test/ffi005/Postulate3.idrdeleted−13
@@ -1,13 +0,0 @@
1−module Main
2−
3−import Providers
4−
5−%language TypeProviders
6−
7−bad : IO (Provider _|_)
8−bad = pure Postulate
9−
10−%provide term (oops : _|_) with bad
11−
12−main : IO ()
13−main = putStrLn "oops"
test/ffi005/expected−2
@@ -1,3 +1 @@
1oops
1oops
2−oops
3−Attempted to provide a postulate where a term was expected.
test/ffi005/run−7
@@ -3,10 +3,3 @@
3idris $@ Postulate.idr -o postulate
3idris $@ Postulate.idr -o postulate
4./postulate
4./postulate
5rm -f postulate *.ibc
5rm -f postulate *.ibc
6−
7−idris $@ Postulate2.idr -o postulate
8−./postulate
9−rm -f postulate *.ibc
10−
11−idris $@ Postulate3.idr -o postulate
12−rm -f postulate *.ibc
test/folding002/folding002.idr+5−5
@@ -5,19 +5,19 @@ addAll = foldr (+) 0
5n : Integer
5n : Integer
6n = 1000000
6n = 1000000
7
7
8−numbersList : List Bits64
8+numbersList : List Integer
9numbersList = numbersList' n []
9numbersList = numbersList' n []
10 where
10 where
11− numbersList' : Integer -> List Bits64 -> List Bits64
11+ numbersList' : Integer -> List Integer -> List Integer
12 numbersList' 0 xs = xs
12 numbersList' 0 xs = xs
13 numbersList' k xs = numbersList' (k - 1) (fromInteger k :: xs)
13 numbersList' k xs = numbersList' (k - 1) (fromInteger k :: xs)
14
14
15−numbersVect : Vect (length numbersList) Bits64
15+numbersVect : Vect (length numbersList) Integer
16numbersVect = fromList numbersList
16numbersVect = fromList numbersList
17
17
18main : IO ()
18main : IO ()
19main = do
19main = do
20− putStrLn . show . prim__zextB64_BigInt $ addAll numbersVect
20+ putStrLn . show . addAll $ numbersVect
21− putStrLn . show . prim__zextB64_BigInt $ addAll numbersList
21+ putStrLn . show . addAll $ numbersList
22
22
23
23
test/idrisdoc001/TestEmpty.idrnew file+1
@@ -0,0 +1 @@
1+module TestEmpty
test/idrisdoc001/TestPrivate.idrnew file+5
@@ -0,0 +1,5 @@
1+module TestPrivate
2+
3+private
4+iAmPrivate : ()
5+iAmPrivate = ()
test/idrisdoc001/expectednew file+5
@@ -0,0 +1,5 @@
1+Type checking ./TestEmpty.idr
2+Type checking ./TestPrivate.idr
3+Warning: Ignoring empty or non-existing namespace 'TestEmpty'
4+Warning: Ignoring empty or non-existing namespace 'TestPrivate'
5+No namespaces to generate documentation for
test/idrisdoc001/runnew file+4
@@ -0,0 +1,4 @@
1+#!/usr/bin/env bash
2+# Tests that no documentation is built for empty and/or private-only namespaces
3+idris --mkdoc test_empty.ipkg
4+rm -rf *.ibc *_doc
test/idrisdoc001/test_empty.ipkgnew file+4
@@ -0,0 +1,4 @@
1+package test_empty
2+
3+modules = TestEmpty, TestPrivate
4+
test/idrisdoc002/TestFunctions.idrnew file+5
@@ -0,0 +1,5 @@
1+module TestFunctions
2+
3+||| Test function
4+test : ()
5+test = ()
test/idrisdoc002/expectednew file+2
@@ -0,0 +1,2 @@
1+Type checking ./TestFunctions.idr
2+Functions are documented
test/idrisdoc002/runnew file+5
@@ -0,0 +1,5 @@
1+#!/usr/bin/env bash
2+# Tests that documentation is generated for functions
3+idris --mkdoc test_functions.ipkg
4+[ -d test_functions_doc ] && echo "Functions are documented"
5+rm -rf *.ibc *_doc
test/idrisdoc002/test_functions.ipkgnew file+4
@@ -0,0 +1,4 @@
1+package test_functions
2+
3+modules = TestFunctions
4+
test/idrisdoc003/TestDatatypes.idrnew file+6
@@ -0,0 +1,6 @@
1+module TestDatatypes
2+
3+||| This is another test
4+data Test : Type where
5+ ||| Test constructor
6+ ATest : Test
test/idrisdoc003/expectednew file+2
@@ -0,0 +1,2 @@
1+Type checking ./TestDatatypes.idr
2+Data types are documented
test/idrisdoc003/runnew file+5
@@ -0,0 +1,5 @@
1+#!/usr/bin/env bash
2+# Tests that documentation is generated for data types
3+idris --mkdoc test_datatypes.ipkg
4+[ -d test_datatypes_doc ] && echo "Data types are documented"
5+rm -rf *.ibc *_doc
test/idrisdoc003/test_datatypes.ipkgnew file+4
@@ -0,0 +1,4 @@
1+package test_datatypes
2+
3+modules = TestDatatypes
4+
test/idrisdoc004/TestTypeclasses.idrnew file+8
@@ -0,0 +1,8 @@
1+module TestTypeclasses
2+
3+||| This is a test
4+|||
5+||| @ a Test arg
6+class Test a where
7+ ||| Test function
8+ test : a -> Int
test/idrisdoc004/expectednew file+2
@@ -0,0 +1,2 @@
1+Type checking ./TestTypeclasses.idr
2+Typeclasses are documented
test/idrisdoc004/runnew file+5
@@ -0,0 +1,5 @@
1+#!/usr/bin/env bash
2+# Tests that documentation is generated for typeclasses
3+idris --mkdoc test_typeclasses.ipkg
4+[ -d test_typeclasses_doc ] && echo "Typeclasses are documented"
5+rm -rf *.ibc *_doc
test/idrisdoc004/test_typeclasses.ipkgnew file+4
@@ -0,0 +1,4 @@
1+package test_typeclasses
2+
3+modules = TestTypeclasses
4+
test/idrisdoc005/TestTracing.idrnew file+4
@@ -0,0 +1,4 @@
1+module TestTracing
2+
3+test : Bool
4+test = True
test/idrisdoc005/expectednew file+3
@@ -0,0 +1,3 @@
1+Type checking ./TestTracing.idr
2+TestTracing: Check
3+Prelude.Bool: Check
test/idrisdoc005/runnew file+6
@@ -0,0 +1,6 @@
1+#!/usr/bin/env bash
2+# Tests that references to other namespaces are traced
3+idris --mkdoc test_tracing.ipkg
4+[ -f test_tracing_doc/docs/TestTracing.html ] && echo "TestTracing: Check"
5+[ -f test_tracing_doc/docs/Prelude.Bool.html ] && echo "Prelude.Bool: Check"
6+rm -rf *.ibc *_doc
test/idrisdoc005/test_tracing.ipkgnew file+4
@@ -0,0 +1,4 @@
1+package test_tracing
2+
3+modules = TestTracing
4+
test/idrisdoc006/A/fully/Qualified/NAME.idrnew file+6
@@ -0,0 +1,6 @@
1+module A.fully.Qualified.NAME
2+
3+||| This is another test
4+data Test : Type where
5+ ||| Test constructor
6+ ATest : Test
test/idrisdoc006/B.idrnew file+5
@@ -0,0 +1,5 @@
1+module B
2+
3+||| Test function
4+test : ()
5+test = ()
test/idrisdoc006/expectednew file+7
@@ -0,0 +1,7 @@
1+Type checking ./A/fully/Qualified/NAME.idr
2+IdrisDoc file written
3+Type checking ./B.idr
4+A.fully.Qualified.NAME.html
5+B.html
6+A.fully.Qualified.NAME is in the index
7+B is in the index
test/idrisdoc006/package_a.ipkgnew file+4
@@ -0,0 +1,4 @@
1+package test_merge
2+
3+modules = A.fully.Qualified.NAME
4+
test/idrisdoc006/package_b.ipkgnew file+4
@@ -0,0 +1,4 @@
1+package test_merge
2+
3+modules = B
4+
test/idrisdoc006/runnew file+17
@@ -0,0 +1,17 @@
1+#!/usr/bin/env bash
2+# Tests that documentation properly is merged with existent.
3+idris --mkdoc package_a.ipkg
4+[ -f test_merge_doc/IdrisDoc ] && echo "IdrisDoc file written"
5+idris --mkdoc package_b.ipkg
6+ls -1p test_merge_doc/docs
7+if grep -q "href\\=\"docs/A.fully.Qualified.NAME\\.html\"" test_merge_doc/index.html; then
8+ echo A.fully.Qualified.NAME is in the index
9+else
10+ echo A.fully.Qualified.NAME is NOT in the index
11+fi
12+if grep -q "href\\=\"docs/B\\.html\"" test_merge_doc/index.html; then
13+ echo B is in the index
14+else
15+ echo B is NOT in the index
16+fi
17+rm -rf *.ibc *_doc A/fully/Qualified/NAME.ibc
test/idrisdoc007/A.idrnew file+6
@@ -0,0 +1,6 @@
1+module A
2+
3+||| This is a test
4+data Test : Type where
5+ ||| Test constructor
6+ ATest : Test
test/idrisdoc007/expectednew file+1
@@ -0,0 +1 @@
1+Exit status (expects 1): 1
test/idrisdoc007/package.ipkgnew file+4
@@ -0,0 +1,4 @@
1+package do_not_delete
2+
3+modules = A
4+
test/idrisdoc007/runnew file+6
@@ -0,0 +1,6 @@
1+#!/usr/bin/env bash
2+# Tests that documentation only is written when safe
3+mkdir do_not_delete_doc
4+idris --mkdoc package.ipkg > nowhere
5+echo Exit status \(expects 1\): $?
6+rm -rf do_not_delete_doc *.ibc nowhere
test/idrisdoc008/Abstract.idrnew file+5
@@ -0,0 +1,5 @@
1+module Abstract
2+
3+abstract
4+frozen : ()
5+frozen = ()
test/idrisdoc008/Visible.idrnew file+5
@@ -0,0 +1,5 @@
1+module Visible
2+
3+public
4+visible : ()
5+visible = ()
test/idrisdoc008/expectednew file+4
@@ -0,0 +1,4 @@
1+Type checking ./Abstract.idr
2+Type checking ./Visible.idr
3+Abstract members are documented
4+Public members are documented
test/idrisdoc008/runnew file+6
@@ -0,0 +1,6 @@
1+#!/usr/bin/env bash
2+# Tests that documentation is generated for both public and abstract members.
3+idris --mkdoc visibility.ipkg
4+[ -f visibility_doc/docs/Abstract.html ] && echo "Abstract members are documented"
5+[ -f visibility_doc/docs/Visible.html ] && echo "Public members are documented"
6+rm -rf *.ibc *_doc
test/idrisdoc008/visibility.ipkgnew file+4
@@ -0,0 +1,4 @@
1+package visibility
2+
3+modules = Abstract, Visible
4+
test/interactive001/expected+1−1
@@ -4,7 +4,7 @@ isElem x (y :: xs) = ?isElem_rhs_3
4
4
5 localZipWith f (_ :: _) (x :: ys) = ?localZipWith_rhs_1
5 localZipWith f (_ :: _) (x :: ys) = ?localZipWith_rhs_1
6
6
7−f x :: (map f xs)
7+f x :: map f xs
8isElem2 x (y :: ys) with (_)
8isElem2 x (y :: ys) with (_)
9 isElem2 x (y :: ys) | with_pat = ?isElem2_rhs
9 isElem2 x (y :: ys) | with_pat = ?isElem2_rhs
10 isElem3 x (x :: ys) | (Yes refl) = ?isElem3_rhs_3
10 isElem3 x (x :: ys) | (Yes refl) = ?isElem3_rhs_3
test/interactive003/expected+2−2
@@ -1,5 +1,5 @@
1Type checking ./interactive003.idr
1Type checking ./interactive003.idr
2ys
2ys
3−x :: (app xs ys)
3+x :: app xs ys
4[]
4[]
5−f x y :: (vzipWith f xs ys)
5+f x y :: vzipWith f xs ys
test/interactive004/expectednew file+3
@@ -0,0 +1,3 @@
1+Type checking ./interactive004.idr
2+plus ?foo_rhs2 ?foo_rhs3
3+append k m ?append_rhs2 ?append_rhs3
test/interactive004/inputnew file+2
@@ -0,0 +1,2 @@
1+:ref 2 foo_rhs1 plus
2+:ref 6 append_rhs1 append
test/interactive004/interactive004.idrnew file+7
@@ -0,0 +1,7 @@
1+foo : Nat -> Nat -> Nat
2+foo k j = ?foo_rhs1
3+
4+append : (n : Nat) -> (m : Nat) -> Vect n a -> Vect m a -> Vect (n + m) a
5+append Z m [] ys = ys
6+append (S k) m (x :: xs) ys = x :: ?append_rhs1
7+
test/interactive004/runnew file+3
@@ -0,0 +1,3 @@
1+#!/usr/bin/env bash
2+idris --quiet interactive004.idr < input
3+rm -f *.ibc
test/records002/expectednew file+2
@@ -0,0 +1,2 @@
1+42, 20
2+10, 42
test/records002/record002.idrnew file+11
@@ -0,0 +1,11 @@
1+
2+record Foo : Nat -> Type where
3+ MkFoo : (param : Nat) -> (num : Int) -> Foo param
4+
5+instance Show (Foo n) where
6+ show f = show (param f) ++ ", " ++ show (num f)
7+
8+main : IO ()
9+main = do let x = MkFoo 10 20
10+ putStrLn (show (record { param = 42 } x))
11+ putStrLn (show (record { num = 42 } x))
test/records002/runnew file+4
@@ -0,0 +1,4 @@
1+#!/usr/bin/env bash
2+idris $@ record002.idr -o record002
3+./record002
4+rm -f record002 *.ibc
test/records003/expectednew file+6
@@ -0,0 +1,6 @@
1+"Fred"
2+21
3+20
4+30
5+29
6+2014
test/records003/records003.idrnew file+48
@@ -0,0 +1,48 @@
1+record Person : Nat -> Type where
2+ MkPerson : (name : String) ->
3+ (age : Nat) ->
4+ Person age
5+
6+record Event : Type where
7+ MkEvent : (name : String) -> (organiser : Person a) -> Event
8+
9+record Meeting : Int -> Type where
10+ MkMeeting : (event : Event) ->
11+ (organiser : Person a) ->
12+ (year : Int) ->
13+ Meeting year
14+
15+new_organiser : String -> List (Meeting x) -> List (Meeting x)
16+new_organiser n = map (record { event->organiser->name = n })
17+
18+next_year : Meeting x -> Meeting (x+1)
19+next_year m = record { organiser->age
20+ = record { organiser->age } m + 1,
21+ event->organiser->age
22+ = record { event->organiser->age } m + 1,
23+ year = _ } m
24+
25+fred : Person 20
26+fred = MkPerson "Fred" _
27+
28+jim : Person 29
29+jim = MkPerson "Jim" 29
30+
31+idm : Event
32+idm = MkEvent "Idris Developers Meeting" fred
33+
34+idm_gbg : Meeting 2014
35+idm_gbg = MkMeeting idm jim _
36+
37+test : Meeting 2015
38+test = next_year idm_gbg
39+
40+main : IO ()
41+main = do print (record { event->organiser->name } test)
42+ print (record { event->organiser->age } test)
43+ print (record { event->organiser->age } idm_gbg)
44+ print (record { organiser->age } test)
45+ print (record { organiser->age } idm_gbg)
46+ print (record { year } idm_gbg)
47+
48+
test/records003/runnew file+4
@@ -0,0 +1,4 @@
1+#!/usr/bin/env bash
2+idris $@ records003.idr -o records003
3+./records003
4+rm -f records003 *.ibc
test/reg014/reg014.idr+6−6
@@ -3,10 +3,10 @@ module reg014
3Matrix : Type -> Nat -> Nat -> Type
3Matrix : Type -> Nat -> Nat -> Type
4Matrix a n m = Vect n (Vect m a)
4Matrix a n m = Vect n (Vect m a)
5
5
6−transpose : Matrix a (S n) (S m) -> Matrix a (S m) (S n)
6+mytranspose : Matrix a (S n) (S m) -> Matrix a (S m) (S n)
7−transpose ((x:: []) :: []) = [[x]]
7+mytranspose ((x:: []) :: []) = [[x]]
8−transpose [x :: y :: xs] = [x] :: (transpose [y :: xs])
8+mytranspose [x :: y :: xs] = [x] :: (mytranspose [y :: xs])
9−transpose (x :: y :: xs)
9+mytranspose (x :: y :: xs)
10− = let tx = transpose [x] in
10+ = let tx = mytranspose [x] in
11− let ux = transpose (y :: xs) in zipWith (++) tx ux
11+ let ux = mytranspose (y :: xs) in zipWith (++) tx ux
12
12
test/reg018/expected+1
@@ -1,4 +1,5 @@
1reg018a.idr:16:1:conat.minusCoNat is possibly not total due to recursive path conat.minusCoNat
1reg018a.idr:16:1:conat.minusCoNat is possibly not total due to recursive path conat.minusCoNat
2+reg018a.idr:21:1:conat.loopForever is possibly not total due to: conat.minusCoNat
2reg018b.idr:8:1:A.showB is possibly not total due to recursive path A.showB
3reg018b.idr:8:1:A.showB is possibly not total due to recursive path A.showB
3reg018c.idr:19:1:CodataTest.inf is possibly not total due to: {CodataTest.inf19}
4reg018c.idr:19:1:CodataTest.inf is possibly not total due to: {CodataTest.inf19}
4reg018d.idr:5:1:Main.pull is not total as there are missing cases
5reg018d.idr:5:1:Main.pull is not total as there are missing cases
test/reg018/run+1
@@ -3,3 +3,4 @@ idris $@ reg018a.idr --check
3idris $@ reg018b.idr --check
3idris $@ reg018b.idr --check
4idris $@ reg018c.idr --check
4idris $@ reg018c.idr --check
5idris $@ reg018d.idr --check
5idris $@ reg018d.idr --check
6+rm *.ibc
test/reg029/run+3−10
@@ -2,13 +2,6 @@
2idris $@ reg029.idr -o reg029
2idris $@ reg029.idr -o reg029
3unset IDRIS_REG029_NONEXISTENT_VAR
3unset IDRIS_REG029_NONEXISTENT_VAR
4export IDRIS_REG029_EXISTENT_VAR='exists!'
4export IDRIS_REG029_EXISTENT_VAR='exists!'
5−case "$@" in
6−*\-\-codegen\ Java*)
7− javac -cp reg029 Reg029Wrapper.java
8− java -cp .:reg029 Reg029Wrapper
9− ;;
10−*)
11− ./reg029
5+./reg029
12−esac
13−idris $@ reg029.idr --exec
6+idris $@ reg029.idr --execute
14−rm -f reg029 *.ibc *.class
7+rm -f reg029 *.ibc
test/reg030/reg030.idr+1−1
@@ -8,7 +8,7 @@ isSubsetOf {univ} a b = (c : univ) -> (member c a) -> (member c b)
8
8
9class Set univ => HasPower univ where
9class Set univ => HasPower univ where
10 Powerset : (a : univ) ->
10 Powerset : (a : univ) ->
11− Exists univ (\Pa => (c : univ) ->
11+ Sigma univ (\Pa => (c : univ) ->
12 (isSubsetOf c a) -> member c Pa)
12 (isSubsetOf c a) -> member c Pa)
13
13
14powerset : HasPower univ => univ -> univ
14powerset : HasPower univ => univ -> univ
test/reg034/expected+2−2
@@ -1,7 +1,7 @@
1reg034.idr:6:5:When elaborating left hand side of bar:
1reg034.idr:6:5:When elaborating left hand side of bar:
2When elaborating an application of main.bar:
2When elaborating an application of main.bar:
3 Can't unify
3 Can't unify
4− x = x
4+ length ys = length ys
5 with
5 with
6 length xs = length ys
6 length xs = length ys
7
7
@@ -13,7 +13,7 @@ When elaborating an application of main.bar:
13reg034.idr:9:5:When elaborating left hand side of foo:
13reg034.idr:9:5:When elaborating left hand side of foo:
14When elaborating an application of main.foo:
14When elaborating an application of main.foo:
15 Can't unify
15 Can't unify
16− x = x
16+ f y = f y
17 with
17 with
18 f x = f y
18 f x = f y
19
19
test/reg039/run+7−1
@@ -22,5 +22,11 @@ timeout() {
22
22
23}
23}
24
24
25+declare -a extraargs
26+for arg in "$@"
27+do
28+ extraargs=("${extraargs[@]}" "'$arg'")
29+done
30+
25−timeout 60 "idris $@ --nocolour reg039.idr --exec go"
31+timeout 60 "idris ${extraargs[*]} --nocolour reg039.idr --exec go"
26rm -f reg039 *.ibc
32rm -f reg039 *.ibc
test/reg040/expectednew file+1
@@ -0,0 +1 @@
1+42
test/reg040/reg040.idrnew file+7
@@ -0,0 +1,7 @@
1+-- The regression that this tests for is defunct unsafePerformIO
2+
3+io : IO Int
4+io = return 42
5+
6+main : IO ()
7+main = print $ unsafePerformIO io
test/reg040/runnew file+6
@@ -0,0 +1,6 @@
1+#!/usr/bin/env bash
2+
3+idris --warnreach reg040.idr -o reg040
4+./reg040
5+
6+rm -f reg040 *.ibc
test/reg041/expectednew file+3
@@ -0,0 +1,3 @@
1+Type checking ./ott.idr
2+?prf : (x : Bool) -> (x1 : Bool) -> El (EQ two x two x1) -> El (EQ two x two x1)
3+Z
test/reg041/ott.idrnew file+42
@@ -0,0 +1,42 @@
1+module OTT
2+
3+mutual
4+
5+ data U : Type where
6+ u : U
7+ zero : U
8+ one : U
9+ two : U
10+ pi : (s : U) -> (t : El s -> U) -> U
11+
12+ El : U -> Type
13+ El u = U
14+ El zero = _|_
15+ El one = ()
16+ El two = Bool
17+ El (pi s t) = (x : El s) -> El (t x)
18+
19+infixr 10 ~>
20+(~>) : U -> U -> U
21+s ~> t = pi s $ const t
22+
23+syntax "<|" [s] "|>" = El s
24+syntax [x] "==" [y] "in" [s] = EQ s x s y
25+
26+%assert_total
27+EQ : (s : U) -> <| s |> -> (t : U) -> <| t |> -> U
28+EQ u u u u = one
29+EQ u zero u zero = one
30+EQ u one u one = one
31+EQ u two u two = one
32+EQ u (pi s t) u (pi s' t') = pi s $ \x => pi s' $ \y => EQ s x s' y ~> EQ u (t x) u (t' y)
33+EQ zero x zero y = one
34+EQ one x one y = one
35+EQ two True two True = one
36+EQ two False two False = one
37+EQ (pi s t) f (pi s' t') g = pi s $ \x => pi s' $ \y => EQ s x s' y ~> EQ (t x) (f x) (t' y) (g y)
38+EQ _ _ _ _ = zero
39+
40+example : <| id == id in (two ~> two) |>
41+example = ?prf
42+
test/reg041/runnew file+5
@@ -0,0 +1,5 @@
1+#!/usr/bin/env bash
2+idris $@ --quiet ott.idr -e example
3+idris $@ showu.idr -o reg040
4+./reg040
5+rm -f reg040 *.ibc
test/reg041/showu.idrnew file+23
@@ -0,0 +1,23 @@
1+module Main
2+
3+%default total
4+
5+data U : Type where
6+ BOOL : U
7+ NAT : U
8+ PAIR : U -> U -> U
9+
10+interpU : U -> Type
11+interpU BOOL = Bool
12+interpU NAT = Nat
13+interpU (PAIR x y) = (interpU x, interpU y)
14+
15+showU : (u : U) -> interpU u -> String
16+showU BOOL True = "Yes"
17+showU BOOL False = "No"
18+showU NAT Z = "Z"
19+showU NAT (S x) = "S of " ++ showU NAT x
20+showU (PAIR tx ty) (x , y) = "(" ++ showU tx x ++ "," ++ showU ty y ++ ")"
21+
22+main : IO ()
23+main = putStrLn $ showU NAT 0
test/reg042/expectednew file+1
@@ -0,0 +1 @@
1+7
test/reg042/reg042.idrnew file+24
@@ -0,0 +1,24 @@
1+-- This regtest tests for incorrect erasure from underapplied data constructors.
2+
3+data T : Type where
4+ C : Nat -> Nat -> Nat -> T
5+
6+data Q : Type where
7+ D : (Nat -> T) -> Q
8+
9+-- The bug was here: (C 3 4) would compile to plain data,
10+-- not to a function that would expect another (albeit erased) argument.
11+f : Q
12+f = D (C 3 4)
13+
14+proj : Nat -> Q -> Nat -> T
15+proj Z (D f) = f
16+proj (S n) q = proj n q
17+
18+g : T -> Nat
19+g (C x y z) = x + y
20+
21+-- Here, we'd apply the not-a-function to the erased argument 4,
22+-- which would make the program go wrong.
23+main : IO ()
24+main = print $ g (proj 3 f 4)
test/reg042/runnew file+4
@@ -0,0 +1,4 @@
1+#!/usr/bin/env bash
2+idris $@ reg042 -o reg042 --warnreach
3+./reg042
4+rm -f reg042 *.ibc
test/reg043/expectednew file+1
@@ -0,0 +1 @@
1+take : (m : Fin 3) -> Vect 2 Nat -> Vect (finToNat m) Nat
test/reg043/runnew file+3
@@ -0,0 +1,3 @@
1+#!/usr/bin/env bash
2+idris $@ --nocolour -e "Vect.take {n=2} {a=Nat}"
3+
test/reg044/expectednew file+11
@@ -0,0 +1,11 @@
1+reg044.idr:4:4:When elaborating right hand side of Main.pf:
2+Can't unify
3+ b = b
4+with
5+ a = b
6+
7+Specifically:
8+ Can't unify
9+ b
10+ with
11+ a
test/reg044/reg044.idrnew file+6
@@ -0,0 +1,6 @@
1+exjection : S a = S b -> a = b
2+exjection = ?pf
3+
4+pf = proof
5+ intros
6+ refine refl
test/reg044/runnew file+3
@@ -0,0 +1,3 @@
1+#!/usr/bin/env bash
2+idris reg044.idr --check
3+rm -f *.ibc
test/totality001/run+3−3
@@ -1,6 +1,6 @@
1#!/usr/bin/env bash
1#!/usr/bin/env bash
2−idris $@ test010.idr -o test010
2+idris $@ --check test010.idr
3−idris $@ test010a.idr -o test010
3+idris $@ --check test010a.idr
4−idris $@ test010b.idr -o test010
4+idris $@ --check test010b.idr
5
5
6rm -f *.ibc
6rm -f *.ibc
test/totality004/expected+1
@@ -1,2 +1,3 @@
1[1, 2, 2, 4, 3, 6, 4, 8, 5, 10]
1[1, 2, 2, 4, 3, 6, 4, 8, 5, 10]
2totality004a.idr:13:1:Main.process is possibly not total due to recursive path Main.process --> Main.process --> Main.process
2totality004a.idr:13:1:Main.process is possibly not total due to recursive path Main.process --> Main.process --> Main.process
3+totality004a.idr:24:1:Main.main is possibly not total due to: Main.process
test/totality005/expected−1
@@ -1,2 +1 @@
1−totality005.idr:6:1:Main.fib is possibly not total due to recursive path Main.fib
2[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377]
1[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377]
test/totality005/totality005.idr+2−1
@@ -2,8 +2,9 @@
2zipWithS : (f : a -> b -> c) -> Stream a -> Stream b -> Stream c
2zipWithS : (f : a -> b -> c) -> Stream a -> Stream b -> Stream c
3zipWithS f (x :: xs) (y :: ys) = f x y :: zipWithS f xs ys
3zipWithS f (x :: xs) (y :: ys) = f x y :: zipWithS f xs ys
4
4
5+partial
5fib : Stream Nat
6fib : Stream Nat
6fib = 0 :: zipWithS (+) fib (1 :: fib)
7fib = 0 :: zipWithS (+) fib (1 :: fib)
7
8
8−main : IO ()
9+partial main : IO ()
9main = print (take 15 fib)
10main = print (take 15 fib)
test/totality006/expectednew file+2
@@ -0,0 +1,2 @@
1+totality006.idr:6:1:Main.prf is not total as there are missing cases
2+totality006a.idr:9:6:prf' (S _) (S _) oh is a valid case
test/totality006/runnew file+4
@@ -0,0 +1,4 @@
1+#!/usr/bin/env bash
2+idris $@ totality006.idr --check
3+idris $@ totality006a.idr --check
4+rm -f *.ibc
test/totality006/totality006.idrnew file+11
@@ -0,0 +1,11 @@
1+antitrue : so False -> a
2+antitrue oh impossible
3+
4+total
5+prf : (a:Nat) -> (b:Nat) -> so (a > b) -> GT a b
6+prf Z Z oh impossible
7+prf Z (S k) um = antitrue um
8+prf (S k) Z um = lteSucc lteZero
9+-- prf (S _) (S _) oh impossible
10+
11+
test/totality006/totality006a.idrnew file+10
@@ -0,0 +1,10 @@
1+antitrue : so False -> a
2+antitrue oh impossible
3+
4+total
5+prf' : (a:Nat) -> (b:Nat) -> so (a > b) -> GT a b
6+prf' Z Z oh impossible
7+prf' Z (S k) um = antitrue um
8+prf' (S k) Z um = lteSucc lteZero
9+prf' (S _) (S _) oh impossible
10+
test/totality007/expectednew file+3
@@ -0,0 +1,3 @@
1+Type checking ./Totality.idr
2+Totality.idr:4:1:Totality.foo is not total as there are missing cases
3+Totality.idr:4:1:Could not build: Totality.foo is not total as there are missing cases
test/totality007/runnew file+3
@@ -0,0 +1,3 @@
1+#!/usr/bin/env bash
2+idris $@ --build totality.ipkg
3+rm -f src/*.ibc
test/totality007/src/Totality.idrnew file+4
@@ -0,0 +1,4 @@
1+module Totality
2+
3+total foo : Nat -> Nat
4+foo Z = Z
test/totality007/totality.ipkgnew file+7
@@ -0,0 +1,7 @@
1+package totality
2+
3+-- totality007
4+-- Test that the package builder doesn't allow totality errors in a build
5+opts = ""
6+sourcedir = src
7+modules = Totality
test/totality008/expectednew file+1
@@ -0,0 +1 @@
1+totality008.idr:7:1:Main.ElimT is possibly not total due to: Main.c2
test/totality008/runnew file+3
@@ -0,0 +1,3 @@
1+#!/usr/bin/env bash
2+idris $@ totality008.idr --check
3+rm -f *.ibc
test/totality008/totality008.idrnew file+8
@@ -0,0 +1,8 @@
1+ data T : Type -> Type where
2+ c1 : T Nat
3+ c2 : T (T Nat)
4+
5+total
6+ElimT : (A : Type) -> T A -> A
7+ElimT _ c1 = 3
8+ElimT _ c2 = c1
test/tutorial006/expected+2−2
@@ -1,13 +1,13 @@
1tutorial006a.idr:3:23:When elaborating right hand side of vapp:
1tutorial006a.idr:3:23:When elaborating right hand side of vapp:
2When elaborating argument xs to constructor Prelude.Vect.:::
2When elaborating argument xs to constructor Prelude.Vect.:::
3 Can't unify
3 Can't unify
4− Vect (n + m) a
4+ Vect (n + n) a
5 with
5 with
6 Vect (plus n m) a
6 Vect (plus n m) a
7
7
8 Specifically:
8 Specifically:
9 Can't unify
9 Can't unify
10− plus n m
10+ plus n n
11 with
11 with
12 plus n m
12 plus n m
13tutorial006b.idr:10:10:When elaborating right hand side of Main.parity:
13tutorial006b.idr:10:10:When elaborating right hand side of Main.parity: