on master help sign in
Merge branch 'master' into JavaBackendFixes

Conflicts: test/reg029/run

commit4aadf4ca0d6cfddc65dcc2cc0d04a287c2e61b18 authorJan Bessai <Jan.Bessai@tu-dortmund.de> dateSat 7 Jun 2014, 17:26 (12 years ago) parent822690abaaea97
227 files changed+6989−2376
.travis.yml+8−6 CHANGELOG+35 CONTRIBUTORS+7−4 Makefile+1−1 benchmarks/ALL+1 benchmarks/fasta/fasta.idr+84 benchmarks/fasta/fasta.ipkg+6 config.mk+1−1 idris.cabal+89−8 idrisdoc/styles.css+320 jsrts/Runtime-browser.js+11 jsrts/Runtime-common.js+16 jsrts/Runtime-node.js+11 libs/Makefile−3 libs/base/Data/Bits.idr+7−7 libs/base/Data/BoundedList.idr+25−23 libs/base/Data/Buffer.idr+28−28 libs/base/Data/Complex.idr+2−2 libs/base/Data/Erased.idr+29 libs/base/Data/Fun.idr+2−5 libs/base/Data/HVect.idr+6−2 libs/base/Data/List.idr+31 libs/base/Data/Mod2.idr+1−1 libs/base/Data/Rel.idr+2−3 libs/base/Data/SortedMap.idr+3−3 libs/base/Data/SortedSet.idr+4−1 libs/base/Data/Vect.idr+18 libs/base/Language/Reflection.idr+2 libs/base/Providers.idr−9 libs/base/System/Concurrency/Process.idr+7−14 libs/base/System/Concurrency/Raw.idr+3−6 libs/base/System/Info.idr+13 libs/base/base.ipkg+3−1 libs/effects/Effect/Exception.idr+1−1 libs/effects/Effect/File.idr+10−15 libs/effects/Effect/Memory.idr+7−7 libs/effects/Effect/Random.idr+18−4 libs/effects/Effect/Select.idr+1−1 libs/effects/Effect/State.idr+3−3 libs/effects/Effect/StdIO.idr+26−9 libs/effects/Effect/System.idr+3−3 libs/effects/Effects.idr+37−69 libs/javascript/JavaScript.idr−104 libs/javascript/JavaScript/JSON.idr−44 libs/javascript/Makefile−14 libs/javascript/javascript.ipkg−5 libs/oldeffects/Effects.idr+1−1 libs/prelude/Builtins.idr+24−18 libs/prelude/Prelude.idr+44−14 libs/prelude/Prelude/Algebra.idr+191−176 libs/prelude/Prelude/Applicative.idr+5−2 libs/prelude/Prelude/Bool.idr+18−5 libs/prelude/Prelude/Cast.idr+5−3 libs/prelude/Prelude/Classes.idr+8−2 libs/prelude/Prelude/Either.idr+4−4 libs/prelude/Prelude/Fin.idr+18−2 libs/prelude/Prelude/Foldable.idr+27−11 libs/prelude/Prelude/List.idr+157−32 libs/prelude/Prelude/Maybe.idr+10−3 libs/prelude/Prelude/Pairs.idr+42 libs/prelude/Prelude/Stream.idr+30−1 libs/prelude/Prelude/Strings.idr+111−1 libs/prelude/Prelude/Uninhabited.idr+3 libs/prelude/Prelude/Vect.idr+43 libs/prelude/prelude.ipkg+1−1 main/Main.hs+10−61 rts/Makefile+3−4 rts/idris_net.c+11−1 rts/idris_net.h−10 rts/idris_rts.c+13 rts/idris_rts.h+6 rts/windows/idris_net.c+15−4 rts/windows/idris_net.h−45 rts/windows/idris_stdfgn.c+13−1 rts/windows/idris_stdfgn.h−24 src/IRTS/CodegenC.hs+5−4 src/IRTS/CodegenJavaScript.hs+598−42 src/IRTS/Compiler.hs+145−64 src/IRTS/Defunctionalise.hs+1−1 src/IRTS/Lang.hs+2 src/IRTS/Simplified.hs+16−14 src/Idris/ASTUtils.hs+134 src/Idris/AbsSyntax.hs+34−17 src/Idris/AbsSyntaxTree.hs+256−139 src/Idris/Apropos.hs+12−8 src/Idris/CaseSplit.hs+42−13 src/Idris/Chaser.hs+1−1 src/Idris/CmdOptions.hs+149 src/Idris/Colours.hs+15−8 src/Idris/Completion.hs+3−1 src/Idris/Core/CaseTree.hs+21−1 src/Idris/Core/Elaborate.hs+14−6 src/Idris/Core/Evaluate.hs+32−10 src/Idris/Core/Execute.hs+98−61 src/Idris/Core/ProofState.hs+53−13 src/Idris/Core/TC.hs+9 src/Idris/Core/TT.hs+84−10 src/Idris/Core/Unify.hs+40−16 src/Idris/Coverage.hs+52−26 src/Idris/DeepSeq.hs+13−15 src/Idris/Delaborate.hs+31−6 src/Idris/Docs.hs+100−24 src/Idris/Docstrings.hs+1−1 src/Idris/ElabDecls.hs+210−102 src/Idris/ElabTerm.hs+55−24 src/Idris/Erasure.hs+27−19 src/Idris/Error.hs+4−2 src/Idris/Help.hs+11−6 src/Idris/IBC.hs+61−23 src/Idris/IdeSlave.hs+64−19 src/Idris/IdrisDoc.hs+661 src/Idris/Imports.hs+7−6 src/Idris/Interactive.hs+341 src/Idris/Output.hs+53−71 src/Idris/ParseData.hs+4−3 src/Idris/ParseExpr.hs+200−171 src/Idris/ParseHelpers.hs+9−6 src/Idris/ParseOps.hs+1−2 src/Idris/Parser.hs+63−46 src/Idris/Primitives.hs+63−9 src/Idris/ProofSearch.hs+61−13 src/Idris/Prover.hs+29−17 src/Idris/Providers.hs+1−7 src/Idris/REPL.hs+296−404 src/Idris/REPLParser.hs+42−10 src/Idris/TypeSearch.hs+303 src/Idris/WhoCalls.hs+93 src/Pkg/PParser.hs+15−3 src/Pkg/Package.hs+76−3 test/Makefile+1−1 test/README+1 test/basic006/expected+2−2 test/basic010/Main.idr+43 test/basic010/expected+3 test/basic010/run+35 test/ffi005/Postulate.idr+3−3 test/ffi005/Postulate2.idr−13 test/ffi005/Postulate3.idr−13 test/ffi005/expected−2 test/ffi005/run−7 test/folding002/folding002.idr+5−5 test/idrisdoc001/TestEmpty.idr+1 test/idrisdoc001/TestPrivate.idr+5 test/idrisdoc001/expected+5 test/idrisdoc001/run+4 test/idrisdoc001/test_empty.ipkg+4 test/idrisdoc002/TestFunctions.idr+5 test/idrisdoc002/expected+2 test/idrisdoc002/run+5 test/idrisdoc002/test_functions.ipkg+4 test/idrisdoc003/TestDatatypes.idr+6 test/idrisdoc003/expected+2 test/idrisdoc003/run+5 test/idrisdoc003/test_datatypes.ipkg+4 test/idrisdoc004/TestTypeclasses.idr+8 test/idrisdoc004/expected+2 test/idrisdoc004/run+5 test/idrisdoc004/test_typeclasses.ipkg+4 test/idrisdoc005/TestTracing.idr+4 test/idrisdoc005/expected+3 test/idrisdoc005/run+6 test/idrisdoc005/test_tracing.ipkg+4 test/idrisdoc006/A/fully/Qualified/NAME.idr+6 test/idrisdoc006/B.idr+5 test/idrisdoc006/expected+7 test/idrisdoc006/package_a.ipkg+4 test/idrisdoc006/package_b.ipkg+4 test/idrisdoc006/run+17 test/idrisdoc007/A.idr+6 test/idrisdoc007/expected+1 test/idrisdoc007/package.ipkg+4 test/idrisdoc007/run+6 test/idrisdoc008/Abstract.idr+5 test/idrisdoc008/Visible.idr+5 test/idrisdoc008/expected+4 test/idrisdoc008/run+6 test/idrisdoc008/visibility.ipkg+4 test/interactive001/expected+1−1 test/interactive003/expected+2−2 test/interactive004/expected+3 test/interactive004/input+2 test/interactive004/interactive004.idr+7 test/interactive004/run+3 test/records002/expected+2 test/records002/record002.idr+11 test/records002/run+4 test/records003/expected+6 test/records003/records003.idr+48 test/records003/run+4 test/reg014/reg014.idr+6−6 test/reg018/expected+1 test/reg018/run+1 test/reg029/run+3−10 test/reg030/reg030.idr+1−1 test/reg034/expected+2−2 test/reg039/run+7−1 test/reg040/expected+1 test/reg040/reg040.idr+7 test/reg040/run+6 test/reg041/expected+3 test/reg041/ott.idr+42 test/reg041/run+5 test/reg041/showu.idr+23 test/reg042/expected+1 test/reg042/reg042.idr+24 test/reg042/run+4 test/reg043/expected+1 test/reg043/run+3 test/reg044/expected+11 test/reg044/reg044.idr+6 test/reg044/run+3 test/totality001/run+3−3 test/totality004/expected+1 test/totality005/expected−1 test/totality005/totality005.idr+2−1 test/totality006/expected+2 test/totality006/run+4 test/totality006/totality006.idr+11 test/totality006/totality006a.idr+10 test/totality007/expected+3 test/totality007/run+3 test/totality007/src/Totality.idr+4 test/totality007/totality.ipkg+7 test/totality008/expected+1 test/totality008/run+3 test/totality008/totality008.idr+8 test/tutorial006/expected+2−2
.travis.yml+8−6
@@ -6,6 +6,8 @@ before_install:
66 - 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
77 # trifecta dependencies
88 - 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
911 # test dependency
1012 - sudo apt-get install -qq expect
1113install:
@@ -17,11 +19,11 @@ before_script:
1719 - cd idris*
1820script:
1921 - cabal configure -f FFI -f LLVM
20− - cabal build
21− - cabal copy
22+ - if [[ "$TESTS" != "doc" ]]; then cabal build; fi
23+ - if [[ "$TESTS" != "doc" ]]; then cabal copy; fi
2224 - make -j2 $TESTS
2325env:
24− # TESTS=doc
25− - TESTS=test_c
26− - TESTS=test_llvm
27− - TESTS=test_js
26+ - TESTS="doc"
27+ - TESTS="test_c"
28+ - TESTS="test_llvm"
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+
17New in 0.9.13:
28--------------
39* 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
439
540New in 0.9.12:
641--------------
CONTRIBUTORS+7−4
@@ -8,24 +8,27 @@ Edwin Brady
88David Raymond Christiansen
99Jason Dagit
1010Simon Fowler
11+Google
1112Cezar Ionescu
1213Irene Knapp
14+Paul Koerbitz
15+Shea Levy
1316Mathnerd314
1417Hannes Mehnert
1518Mekeor Melire
1619Melissa Mozifian
1720Dominic Mulligan
1821Jan de Muijnck-Hughes
19−raichoo
2022Tom Prince
23+raichoo
24+Philip Rasmussen
25+Reynir Reynisson
2126Seo Sanghyeon
2227Benjamin Saunders
2328startling
2429Chetan T
30+Matúš Tejiščák
2531Dirk Ullrich
2632Leif Warner
2733Daniel Waterworth
2834Jonas Westerlund
29−Reynir Reynisson
30−Shea Levy
31−
Makefile+1−1
@@ -43,7 +43,7 @@ linecount:
4343
4444#Note: this doesn't yet link to Hackage properly
4545doc: 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"
4747
4848
4949dist/setup-config:
benchmarks/ALL+1
@@ -1,2 +1,3 @@
11trivial/sortvec 2000
22quasigroups/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
22CABAL :=cabal
33CFLAGS :=-O2 -Wall $(CFLAGS)
44#CABALFLAGS :=
idris.cabal+89−8
@@ -1,5 +1,5 @@
11Name: idris
2−Version: 0.9.12
2+Version: 0.9.13
33License: BSD3
44License-file: LICENSE
55Author: Edwin Brady
@@ -46,7 +46,8 @@ Cabal-Version: >= 1.8
4646
4747Build-type: Custom
4848
49−Data-files: jsrts/Runtime-browser.js
49+Data-files: idrisdoc/styles.css
50+ jsrts/Runtime-browser.js
5051 jsrts/Runtime-common.js
5152 jsrts/Runtime-node.js
5253 jsrts/jsbn/jsbn.js
@@ -65,6 +66,7 @@ Extra-source-files:
6566
6667 rts/*.c
6768 rts/*.h
69+ rts/windows/*.c
6870 rts/Makefile
6971
7072 libs/Makefile
@@ -88,6 +90,7 @@ Extra-source-files:
8890 libs/base/Language/Reflection/*.idr
8991 libs/base/Makefile
9092 libs/base/Network/*.idr
93+ libs/base/System/*.idr
9194 libs/base/System/Concurrency/*.idr
9295 libs/base/Syntax/*.idr
9396
@@ -102,11 +105,6 @@ Extra-source-files:
102105 libs/oldeffects/Effect/*.idr
103106 libs/oldeffects/*.idr
104107
105− libs/javascript/*.idr
106− libs/javascript/JavaScript/*.idr
107− libs/javascript/Makefile
108− libs/javascript/javascript.ipkg
109−
110108 llvm/*.c
111109 llvm/Makefile
112110
@@ -227,6 +225,23 @@ Extra-source-files:
227225 test/reg038/run
228226 test/reg038/*.idr
229227 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
230245
231246 test/basic001/run
232247 test/basic001/*.idr
@@ -256,6 +271,9 @@ Extra-source-files:
256271 test/basic009/*.idr
257272 test/basic009/expected
258273 test/basic009/B/*.idr
274+ test/basic010/run
275+ test/basic010/*.idr
276+ test/basic010/expected
259277
260278 test/buffer001-disabled/*.idr
261279 test/buffer001-disabled/run
@@ -309,6 +327,40 @@ Extra-source-files:
309327 test/ffi005/run
310328 test/ffi005/expected
311329
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+
312364 test/interactive001/run
313365 test/interactive001/input
314366 test/interactive001/*.idr
@@ -321,6 +373,10 @@ Extra-source-files:
321373 test/interactive003/input
322374 test/interactive003/*.idr
323375 test/interactive003/expected
376+ test/interactive004/run
377+ test/interactive004/input
378+ test/interactive004/*.idr
379+ test/interactive004/expected
324380
325381 test/io001/run
326382 test/io001/*.idr
@@ -361,6 +417,12 @@ Extra-source-files:
361417 test/records001/run
362418 test/records001/*.idr
363419 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
364426
365427 test/sugar001/run
366428 test/sugar001/*.idr
@@ -387,6 +449,16 @@ Extra-source-files:
387449 test/totality005/run
388450 test/totality005/*.idr
389451 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
390462
391463 test/tutorial001/run
392464 test/tutorial001/*.idr
@@ -456,6 +528,7 @@ Library
456528 , Idris.AbsSyntax
457529 , Idris.AbsSyntaxTree
458530 , Idris.Apropos
531+ , Idris.ASTUtils
459532 , Idris.CaseSplit
460533 , Idris.Chaser
461534 , Idris.Colours
@@ -475,8 +548,10 @@ Library
475548 , Idris.Help
476549 , Idris.IBC
477550 , Idris.IdeSlave
551+ , Idris.IdrisDoc
478552 , Idris.Imports
479553 , Idris.Inliner
554+ , Idris.Interactive
480555 , Idris.Output
481556 , Idris.Parser
482557 , Idris.ParseHelpers
@@ -491,7 +566,10 @@ Library
491566 , Idris.REPL
492567 , Idris.REPLParser
493568 , Idris.Transforms
569+ , Idris.TypeSearch
494570 , Idris.Unlit
571+ , Idris.WhoCalls
572+ , Idris.CmdOptions
495573
496574 , IRTS.BCImp
497575 , IRTS.Bytecode
@@ -533,6 +611,8 @@ Library
533611 , ansi-terminal
534612 , ansi-wl-pprint
535613 , binary
614+ , blaze-html >= 0.6.1.3
615+ , blaze-markup >= 0.5.2.1 && < 0.7.0.0
536616 , bytestring
537617 , cheapskate
538618 , containers >= 0.5
@@ -543,7 +623,7 @@ Library
543623 , language-java >= 0.2.6
544624 , lens >= 4.1.1
545625 , mtl
546− , parsers >= 0.9
626+ , parsers >= 0.9 && < 0.11.0.2
547627 , pretty
548628 , process
549629 , split
@@ -559,6 +639,7 @@ Library
559639 , xml
560640 , deepseq
561641 , zlib
642+ , optparse-applicative
562643 Extensions: MultiParamTypeClasses
563644 , FunctionalDependencies
564645 , 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 @@
11var __IDRRT__print = function(s) {
22 console.log(s);
33};
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) {
3434
3535 return ret;
3636};
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() {
44 util.print(s);
55 };
66})();
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:
22 $(MAKE) -C prelude build
33 $(MAKE) -C base build
44 $(MAKE) -C effects build
5− $(MAKE) -C javascript build
65
76
87install:
98 $(MAKE) -C prelude install
109 $(MAKE) -C base install
1110 $(MAKE) -C effects install
12− $(MAKE) -C javascript install
1311
1412clean:
1513 $(MAKE) -C prelude clean
1614 $(MAKE) -C base clean
1715 $(MAKE) -C effects clean
18− $(MAKE) -C javascript clean
1916
2017.PHONY: build install clean
libs/base/Data/Bits.idr+7−7
@@ -356,8 +356,8 @@ bitsToInt : Bits n -> Integer
356356bitsToInt (MkBits x) = bitsToInt' x
357357
358358-- Zero out the high bits of a truncated bitstring
359−--zeroUnused : machineTy (nextBytes n) -> machineTy (nextBytes n)
360−--zeroUnused {n} x = x `and'` complement' (intToBits' {n=n} 0)
359+zeroUnused : machineTy (nextBytes n) -> machineTy (nextBytes n)
360+zeroUnused {n} x = x `and'` complement' (intToBits' {n=n} 0)
361361
362362--instance Cast Nat (Bits n) where
363363-- cast x = MkBits (zeroUnused (natToBits n))
@@ -399,8 +399,8 @@ sext' {n=n} {m=m} x with (nextBytes n, nextBytes (n+m))
399399
400400-- TODO: Prove
401401%assert_total -- can't verify coverage of with block
402−trunc' : machineTy (nextBytes (n+m)) -> machineTy (nextBytes n)
403−trunc' {n=n} {m=m} x with (nextBytes n, nextBytes (n+m))
402+trunc' : machineTy (nextBytes (m+n)) -> machineTy (nextBytes n)
403+trunc' {m=m} {n=n} x with (nextBytes n, nextBytes (m+n))
404404 | (Z, Z) = believe_me x
405405 | (Z, S Z) = believe_me (prim__truncB16_B8 (believe_me x))
406406 | (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))
412412 | (S (S Z), S (S (S _))) = believe_me (prim__truncB64_B32 (believe_me x))
413413 | (S (S (S _)), S (S (S _))) = believe_me x
414414
415−--public
416−--truncate : Bits (n+m) -> Bits n
417−--truncate (MkBits x) = MkBits (zeroUnused (trunc' x))
415+public
416+truncate : Bits (m+n) -> Bits n
417+truncate (MkBits x) = MkBits (zeroUnused (trunc' x))
418418
419419public
420420bitAt : Fin n -> Bits n
libs/base/Data/BoundedList.idr+25−23
@@ -3,11 +3,13 @@ module Data.BoundedList
33%access public
44%default total
55
6−data BoundedList : Type -> Nat -> Type where
7− Nil : BoundedList a n
8− (::) : a -> BoundedList a n -> BoundedList a (S n)
6+||| A list with an upper bound on its length.
7+data BoundedList : Nat -> Type -> Type where
8+ Nil : BoundedList n a
9+ (::) : a -> BoundedList n a -> BoundedList (S n) a
910
10−length : BoundedList a n -> Fin (S n)
11+||| Compute the length of a list.
12+length : BoundedList n a -> Fin (S n)
1113length [] = fZ
1214length (x :: xs) = fS (length xs)
1315
@@ -15,7 +17,7 @@ length (x :: xs) = fS (length xs)
1517-- Indexing into bounded lists
1618--------------------------------------------------------------------------------
1719
18−index : Fin (S n) -> BoundedList a n -> Maybe a
20+index : Fin (S n) -> BoundedList n a -> Maybe a
1921index _ [] = Nothing
2022index fZ (x :: _) = Just x
2123index (fS f) (_ :: xs) = index f xs
@@ -24,7 +26,8 @@ index (fS f) (_ :: xs) = index f xs
2426-- Adjusting bounds
2527--------------------------------------------------------------------------------
2628
27−weaken : BoundedList a n -> BoundedList a (n + m)
29+||| Loosen the bounds on a list's length.
30+weaken : BoundedList n a -> BoundedList (n + m) a
2831weaken [] = []
2932weaken (x :: xs) = x :: weaken xs
3033
@@ -32,16 +35,16 @@ weaken (x :: xs) = x :: weaken xs
3235-- Conversions to and from list
3336--------------------------------------------------------------------------------
3437
35−take : (n : Nat) -> List a -> BoundedList a n
38+take : (n : Nat) -> List a -> BoundedList n a
3639take _ [] = []
3740take Z _ = []
3841take (S n') (x :: xs) = x :: take n' xs
3942
40−toList : BoundedList a n -> List a
43+toList : BoundedList n a -> List a
4144toList [] = []
42−toList (x :: xs) = x :: toList xs
45+toList (x :: xs) = x :: Data.BoundedList.toList xs
4346
44−fromList : (xs : List a) -> BoundedList a (length xs)
47+fromList : (xs : List a) -> BoundedList (length xs) a
4548fromList [] = []
4649fromList (x :: xs) = x :: fromList xs
4750
@@ -49,7 +52,7 @@ fromList (x :: xs) = x :: fromList xs
4952-- Building (bigger) bounded lists
5053--------------------------------------------------------------------------------
5154
52−replicate : (n : Nat) -> a -> BoundedList a n
55+replicate : (n : Nat) -> a -> BoundedList n a
5356replicate Z _ = []
5457replicate (S n) x = x :: replicate n x
5558
@@ -57,27 +60,26 @@ replicate (S n) x = x :: replicate n x
5760-- Folds
5861--------------------------------------------------------------------------------
5962
60−foldl : (a -> b -> a) -> a -> BoundedList b n -> a
61−foldl f e [] = e
62−foldl f e (x::xs) = foldl f (f e x) xs
63−
64−foldr : (a -> b -> b) -> b -> BoundedList a n -> b
65−foldr f e [] = e
66−foldr f e (x::xs) = f x (foldr f e xs)
63+instance Foldable (BoundedList n) where
64+ foldr f e [] = e
65+ foldr f e (x::xs) = f x (foldr f e xs)
66+ foldl f e [] = e
67+ foldl f e (x::xs) = foldl f (f e x) xs
6768
6869--------------------------------------------------------------------------------
6970-- Maps
7071--------------------------------------------------------------------------------
7172
72−map : (a -> b) -> BoundedList a n -> BoundedList b n
73−map f [] = []
74−map f (x :: xs) = f x :: map f xs
73+instance Functor (BoundedList n) where
74+ map f [] = []
75+ map f (x :: xs) = f x :: map f xs
7576
7677--------------------------------------------------------------------------------
7778-- Misc
7879--------------------------------------------------------------------------------
7980
80−pad : (xs : BoundedList a n) -> (padding : a) -> BoundedList a n
81+||| Extend a bounded list to the maximum size by padding on the left.
82+pad : BoundedList n a -> a -> BoundedList n a
8183pad {n=Z} [] _ = []
8284pad {n=S n'} [] padding = padding :: (pad {n=n'} [] padding)
8385pad {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
8789-- Simple properties
8890--------------------------------------------------------------------------------
8991
90−zeroBoundIsEmpty : (xs : BoundedList a 0) -> xs = the (BoundedList a 0) []
92+zeroBoundIsEmpty : (xs : BoundedList 0 a) -> xs = the (BoundedList 0 a) []
9193zeroBoundIsEmpty [] = refl
9294zeroBoundIsEmpty (_ :: _) impossible
libs/base/Data/Buffer.idr+28−28
@@ -36,15 +36,15 @@ bitsFromFin : Fin n -> Bits64
3636bitsFromFin fZ = 0
3737bitsFromFin (fS k) = 1 + bitsFromFin k
3838
39−-- Allocate an empty Buffer. The size hint can be used to avoid
40−-- unnecessary reallocations and copies under the hood if the
41−-- approximate ultimate size of the Buffer is known. Users can assume
42−-- the new Buffer is word-aligned.
39+||| Allocate an empty Buffer. The size hint can be used to avoid
40+||| unnecessary reallocations and copies under the hood if the
41+||| approximate ultimate size of the Buffer is known. Users can assume
42+||| the new Buffer is word-aligned.
4343public
4444allocate : ( hint : Nat ) -> Buffer Z
4545allocate = MkBuffer Z . prim__allocate . bitsFromNat
4646
47−-- Append count repetitions of a Buffer to another Buffer
47+||| Append count repetitions of a Buffer to another Buffer
4848%assert_total
4949public
5050appendBuffer : Buffer n ->
@@ -63,13 +63,13 @@ appendBuffer { n } { m } ( MkBuffer o1 r1 ) c ( MkBuffer o2 r2 ) =
6363 off : Bits64
6464 off = bitsFromNat o2
6565
66−-- Copy a buffer, potentially allowing the (potentially large) space it
67−-- pointed to to be freed
66+||| Copy a buffer, potentially allowing the (potentially large) space it
67+||| pointed to to be freed
6868public
6969copy : Buffer n -> Buffer n
7070copy { n } = replace ( plusZeroRightNeutral n ) . appendBuffer ( allocate n ) 1
7171
72−-- Create a view over a buffer
72+||| Create a view over a buffer
7373public
7474peekBuffer : { n : Nat } -> { offset : Nat } -> Buffer ( n + offset ) -> ( offset : Nat ) -> Buffer n
7575peekBuffer ( MkBuffer o r ) off = MkBuffer ( o + off ) r
@@ -93,7 +93,7 @@ appendBits { n } prim ( MkBuffer o r ) count =
9393 MkBuffer o . prim r ( bitsFromNat $ n + o ) ( bitsFromNat count )
9494
9595
96−-- Read a Bits8 from a Buffer starting at offset
96+||| Read a Bits8 from a Buffer starting at offset
9797%assert_total
9898public
9999peekBits8 : Buffer ( 1 + n ) ->
@@ -101,7 +101,7 @@ peekBits8 : Buffer ( 1 + n ) ->
101101 Bits8
102102peekBits8 = peekBits { m = 1 } prim__peekB8Native
103103
104−-- Append count repetitions of a Bits8 to a Buffer
104+||| Append count repetitions of a Bits8 to a Buffer
105105%assert_total
106106public
107107appendBits8 : Buffer n ->
@@ -110,7 +110,7 @@ appendBits8 : Buffer n ->
110110 Buffer ( n + count * 1 )
111111appendBits8 = appendBits prim__appendB8Native
112112
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
114114%assert_total
115115public
116116peekBits16Native : Buffer ( 2 + n ) ->
@@ -118,19 +118,19 @@ peekBits16Native : Buffer ( 2 + n ) ->
118118 Bits16
119119peekBits16Native = peekBits { m = 2 } prim__peekB16Native
120120
121−-- Read a little-endian Bits16 from a Buffer starting at offset
121+||| Read a little-endian Bits16 from a Buffer starting at offset
122122%assert_total
123123public
124124peekBits16LE : Buffer ( 2 + n ) -> ( offset : Fin ( S n ) ) -> Bits16
125125peekBits16LE = peekBits { m = 2 } prim__peekB16LE
126126
127−-- Read a big-endian Bits16 from a Buffer starting at offset
127+||| Read a big-endian Bits16 from a Buffer starting at offset
128128%assert_total
129129public
130130peekBits16BE : Buffer ( 2 + n ) -> ( offset : Fin ( S n ) ) -> Bits16
131131peekBits16BE = peekBits { m = 2 } prim__peekB16BE
132132
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
134134%assert_total
135135public
136136appendBits16Native : Buffer n ->
@@ -139,7 +139,7 @@ appendBits16Native : Buffer n ->
139139 Buffer ( n + count * 2 )
140140appendBits16Native = appendBits prim__appendB16Native
141141
142−-- Append count repetitions of a little-endian Bits16 to a Buffer
142+||| Append count repetitions of a little-endian Bits16 to a Buffer
143143%assert_total
144144public
145145appendBits16LE : Buffer n ->
@@ -148,7 +148,7 @@ appendBits16LE : Buffer n ->
148148 Buffer ( n + count * 2 )
149149appendBits16LE = appendBits prim__appendB16LE
150150
151−-- Append count repetitions of a big-endian Bits16 to a Buffer
151+||| Append count repetitions of a big-endian Bits16 to a Buffer
152152%assert_total
153153public
154154appendBits16BE : Buffer n ->
@@ -157,7 +157,7 @@ appendBits16BE : Buffer n ->
157157 Buffer ( n + count * 2 )
158158appendBits16BE = appendBits prim__appendB16BE
159159
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
161161%assert_total
162162public
163163peekBits32Native : Buffer ( 4 + n ) ->
@@ -165,19 +165,19 @@ peekBits32Native : Buffer ( 4 + n ) ->
165165 Bits32
166166peekBits32Native = peekBits { m = 4 } prim__peekB32Native
167167
168−-- Read a little-endian Bits32 from a Buffer starting at offset
168+||| Read a little-endian Bits32 from a Buffer starting at offset
169169%assert_total
170170public
171171peekBits32LE : Buffer ( 4 + n ) -> ( offset : Fin ( S n ) ) -> Bits32
172172peekBits32LE = peekBits { m = 4 } prim__peekB32LE
173173
174−-- Read a big-endian Bits32 from a Buffer starting at offset
174+||| Read a big-endian Bits32 from a Buffer starting at offset
175175%assert_total
176176public
177177peekBits32BE : Buffer ( 4 + n ) -> ( offset : Fin ( S n ) ) -> Bits32
178178peekBits32BE = peekBits { m = 4 } prim__peekB32BE
179179
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
181181%assert_total
182182public
183183appendBits32Native : Buffer n ->
@@ -186,7 +186,7 @@ appendBits32Native : Buffer n ->
186186 Buffer ( n + count * 4 )
187187appendBits32Native = appendBits prim__appendB32Native
188188
189−-- Append count repetitions of a little-endian Bits32 to a Buffer
189+||| Append count repetitions of a little-endian Bits32 to a Buffer
190190%assert_total
191191public
192192appendBits32LE : Buffer n ->
@@ -195,7 +195,7 @@ appendBits32LE : Buffer n ->
195195 Buffer ( n + count * 4 )
196196appendBits32LE = appendBits prim__appendB32LE
197197
198−-- Append count repetitions of a big-endian Bits32 to a Buffer
198+||| Append count repetitions of a big-endian Bits32 to a Buffer
199199%assert_total
200200public
201201appendBits32BE : Buffer n ->
@@ -204,7 +204,7 @@ appendBits32BE : Buffer n ->
204204 Buffer ( n + count * 4 )
205205appendBits32BE = appendBits prim__appendB32BE
206206
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
208208%assert_total
209209public
210210peekBits64Native : Buffer ( 8 + n ) ->
@@ -212,19 +212,19 @@ peekBits64Native : Buffer ( 8 + n ) ->
212212 Bits64
213213peekBits64Native = peekBits { m = 8 } prim__peekB64Native
214214
215−-- Read a little-endian Bits64 from a Buffer starting at offset
215+||| Read a little-endian Bits64 from a Buffer starting at offset
216216%assert_total
217217public
218218peekBits64LE : Buffer ( 8 + n ) -> ( offset : Fin ( S n ) ) -> Bits64
219219peekBits64LE = peekBits { m = 8 } prim__peekB64LE
220220
221−-- Read a big-endian Bits64 from a Buffer starting at offset
221+||| Read a big-endian Bits64 from a Buffer starting at offset
222222%assert_total
223223public
224224peekBits64BE : Buffer ( 8 + n ) -> ( offset : Fin ( S n ) ) -> Bits64
225225peekBits64BE = peekBits { m = 8 } prim__peekB64BE
226226
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
228228%assert_total
229229public
230230appendBits64Native : Buffer n ->
@@ -233,7 +233,7 @@ appendBits64Native : Buffer n ->
233233 Buffer ( n + count * 8 )
234234appendBits64Native = appendBits prim__appendB64Native
235235
236−-- Append count repetitions of a little-endian Bits64 to a Buffer
236+||| Append count repetitions of a little-endian Bits64 to a Buffer
237237%assert_total
238238public
239239appendBits64LE : Buffer n ->
@@ -242,7 +242,7 @@ appendBits64LE : Buffer n ->
242242 Buffer ( n + count * 8 )
243243appendBits64LE = appendBits prim__appendB64LE
244244
245−-- Append count repetitions of a big-endian Bits64 to a Buffer
245+||| Append count repetitions of a big-endian Bits64 to a Buffer
246246%assert_total
247247public
248248appendBits64BE : Buffer n ->
libs/base/Data/Complex.idr+2−2
@@ -62,8 +62,8 @@ conjugate (r:+i) = (r :+ (0-i))
6262-- We can't do "instance Num a => Num (Complex a)" because
6363-- we need "abs" which needs "magnitude" which needs "sqrt" which needs Float
6464instance Num (Complex Float) where
65− (+) (a:+b) (c:+d) = ((a+b):+(c+d))
66− (-) (a:+b) (c:+d) = ((a-b):+(c-d))
65+ (+) (a:+b) (c:+d) = ((a+c):+(b+d))
66+ (-) (a:+b) (c:+d) = ((a-c):+(b-d))
6767 (*) (a:+b) (c:+d) = ((a*c-b*d):+(b*c+a*d))
6868 fromInteger x = (fromInteger x:+0)
6969 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
22
33%default total
44
5−--------------------------------------------------------------------------------
6−-- Build an n-ary function type from a Vect of Types and a result type
7−--------------------------------------------------------------------------------
5+||| Build an n-ary function type from a Vect of Types and a result type
86Fun : Vect n Type -> Type -> Type
97Fun [] r = r
108Fun (t::ts) r = t -> Fun ts r
@@ -14,5 +12,4 @@ chain {ts = []} g r = g r
1412chain {ts = (_::_)} g f = \ x => chain g (f x)
1513
1614target : {ts : Vect n Type} -> Fun ts r -> Type
17−target {r} _ = r
18−
15+target {r} _ = r
libs/base/Data/HVect.idr+6−2
@@ -6,7 +6,8 @@ import Data.Vect
66%default total
77
88using (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.
1011 data HVect : Vect k Type -> Type where
1112 Nil : HVect []
1213 (::) : t -> HVect ts -> HVect (t::ts)
@@ -30,6 +31,7 @@ using (k : Nat, ts : Vect k Type)
3031 updateAt fZ f (x::xs) = f x :: xs
3132 updateAt (fS j) f (x::xs) = x :: updateAt j f xs
3233
34+ ||| Append two `HVect`s.
3335 (++) : {us : Vect l Type} -> HVect ts -> HVect us -> HVect (ts ++ us)
3436 (++) [] ys = ys
3537 (++) (x::xs) ys = x :: (xs ++ ys)
@@ -52,16 +54,18 @@ using (k : Nat, ts : Vect k Type)
5254 instance (Shows k ts) => Show (HVect ts) where
5355 show xs = show (shows xs)
5456
55− ||| Extract an arbitrary element of the correct type
57+ ||| Extract an arbitrary element of the correct type.
5658 ||| @ t the goal type
5759 get : {default tactics { applyTactic findElem 100; solve; } p : Elem t ts} -> HVect ts -> t
5860 get {p = Here} (x::xs) = x
5961 get {p = There p'} (x::xs) = get {p = p'} xs
6062
63+ ||| Replace an element with the correct type.
6164 put : {default tactics { applyTactic findElem 100; solve; } p : Elem t ts} -> t -> HVect ts -> HVect ts
6265 put {p = Here} y (x::xs) = y :: xs
6366 put {p = There p'} y (x::xs) = x :: put {p = p'} y xs
6467
68+ ||| Replace an element with the correct type.
6569 update : {default tactics { applyTactic findElem 100; solve; } p : Elem t ts} -> (t -> u) -> HVect ts -> HVect (replaceByElem ts p u)
6670 update {p = Here} f (x::xs) = f x :: xs
6771 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
44
55%default total
66
7−-- Integers modulo 2^n
7+||| Integers modulo 2^n
88public
99data Mod2 : Nat -> Type where
1010 MkMod2 : {n : Nat} -> Bits n -> Mod2 n
libs/base/Data/Rel.idr+2−3
@@ -2,9 +2,8 @@ module Data.Rel
22
33import Data.Fun
44
5−--------------------------------------------------------------------------------
6−-- Build an n-ary relation type from a Vect of Types
7−--------------------------------------------------------------------------------
5+
6+||| Build an n-ary relation type from a Vect of Types
87Rel : Vect n Type -> Type
98Rel ts = Fun ts Type
109
libs/base/Data/SortedMap.idr+3−3
@@ -183,10 +183,10 @@ treeDelete {n=(S (S _))} k (Branch3 t1 k1 t2 k2 t3) =
183183 Left t3' => Left (Branch3 t1 k1 t2 k2 t3')
184184 Right t3' => Left (merge3 t1 k1 t2 k2 t3')
185185
186−treeToList : Ord k => Tree n k v -> List (k, v)
186+treeToList : Tree n k v -> List (k, v)
187187treeToList = treeToList' (:: [])
188188 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)
190190 treeToList' cont (Leaf k v) = cont (k, v)
191191 treeToList' cont (Branch2 t1 _ t2) = treeToList' (:: treeToList' cont t2) t1
192192 treeToList' cont (Branch3 t1 _ t2 _ t3) = treeToList' (:: treeToList' (:: treeToList' cont t3) t2) t1
@@ -223,7 +223,7 @@ delete k (M (S _) t) =
223223fromList : Ord k => List (k, v) -> SortedMap k v
224224fromList l = foldl (flip (uncurry insert)) empty l
225225
226−toList : Ord k => SortedMap k v -> List (k, v)
226+toList : SortedMap k v -> List (k, v)
227227toList Empty = []
228228toList (M _ t) = treeToList t
229229
libs/base/Data/SortedSet.idr+4−1
@@ -21,5 +21,8 @@ contains k (SetWrapper m) = isJust (Data.SortedMap.lookup k m)
2121fromList : Ord k => List k -> SortedSet k
2222fromList l = SetWrapper (Data.SortedMap.fromList (map (\i => (i, ())) l))
2323
24−toList : Ord k => SortedSet k -> List k
24+toList : SortedSet k -> List k
2525toList (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)
1515 Here : Elem x (x::xs)
1616 There : Elem x xs -> Elem x (y::xs)
1717
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+
1836||| A tactic for discovering where, if anywhere, an element is in a vector
1937||| @ n how many elements to search before giving up
2038findElem : (n : Nat) -> List (TTName, Binder TT) -> TT -> Tactic
libs/base/Language/Reflection.idr+2
@@ -167,6 +167,8 @@ data Tactic = Try Tactic Tactic
167167 -- ^ apply both tactics in sequence
168168 | Trivial
169169 -- ^ intelligently construct the proof target from the context
170+ | Search Int
171+ -- ^ build a proof by applying contructors up to a maximum depth
170172 | Instance
171173 -- ^ resolve a type class
172174 | Solve
libs/base/Providers.idr−9
@@ -11,26 +11,17 @@ data Provider : (a : Type) -> Type where
1111 ||| @ msg the error message
1212 Error : (msg : String) -> Provider a
1313
14− ||| Postulate the goal type
15− Postulate : Provider a
16−
1714-- instances
1815instance Functor Provider where
1916 map f (Provide a) = Provide (f a)
2017 map f (Error err) = Error err
21− map f Postulate = Postulate
2218
2319instance Applicative Provider where
2420 (Provide f) <$> (Provide x) = Provide (f x)
2521 (Provide f) <$> (Error err) = Error err
26− (Provide f) <$> Postulate = Postulate
2722 (Error err) <$> _ = Error err
28− Postulate <$> (Error err) = Error err
29− Postulate <$> _ = Postulate
3023 pure = Provide
3124
32−-- is this correct for Postulate?
3325instance Monad Provider where
3426 (Provide x) >>= f = f x
3527 (Error err) >>= _ = Error err
36− Postulate >>= f = Postulate
libs/base/System/Concurrency/Process.idr+7−14
@@ -9,9 +9,8 @@ import System.Concurrency.Raw
99abstract
1010data ProcID msg = MkPID Ptr
1111
12−-- Type safe message passing programs. Parameterised over the type of
13−-- message which can be send, and the return type.
14−
12+||| Type safe message passing programs. Parameterised over the type of
13+||| message which can be send, and the return type.
1514data Process : (msgType : Type) -> Type -> Type where
1615 lift : IO a -> Process msg a
1716
@@ -30,31 +29,26 @@ instance Monad (Process msg) where
3029run : Process msg x -> IO x
3130run (lift prog) = prog
3231
33−-- Get current process ID
34−
32+||| Get current process ID
3533myID : Process msg (ProcID msg)
3634myID = lift (return (MkPID prim__vm))
3735
38−-- Send a message to another process
39−
36+||| Send a message to another process
4037send : ProcID msg -> msg -> Process msg ()
4138send (MkPID p) m = lift (sendToThread p (prim__vm, m))
4239
43−-- Return whether a message is waiting in the queue
44−
40+||| Return whether a message is waiting in the queue
4541msgWaiting : Process msg Bool
4642msgWaiting = lift checkMsgs
4743
48−-- Receive a message - blocks if there is no message waiting
49−
44+||| Receive a message - blocks if there is no message waiting
5045recv : Process msg msg
5146recv {msg} = do (senderid, m) <- lift get
5247 return m
5348 where get : IO (Ptr, msg)
5449 get = getMsg
5550
56−-- receive a message, and return with the sender's process ID.
57−
51+||| receive a message, and return with the sender's process ID.
5852recvWithSender : Process msg (ProcID msg, msg)
5953recvWithSender {msg}
6054 = do (senderid, m) <- lift get
@@ -65,4 +59,3 @@ recvWithSender {msg}
6559create : Process msg () -> Process msg (ProcID msg)
6660create (lift p) = do ptr <- lift (fork p)
6761 return (MkPID ptr)
68−
libs/base/System/Concurrency/Raw.idr+3−6
@@ -6,8 +6,7 @@ module System.Concurrency.Raw
66
77import System
88
9−-- Send a message of any type to the thread with the given thread id
10−
9+||| Send a message of any type to the thread with the given thread id
1110sendToThread : (thread_id : Ptr) -> a -> IO ()
1211sendToThread {a} dest val
1312 = mkForeign (FFun "idris_sendMessage"
@@ -18,10 +17,8 @@ checkMsgs = do msgs <- mkForeign (FFun "idris_checkMessages"
1817 [FPtr] FInt) prim__vm
1918 return (intToBool msgs)
2019
21−-- Check inbox for messages. If there are none, blocks until a message
22−-- arrives.
23−
20+||| Check inbox for messages. If there are none, blocks until a message
21+||| arrives.
2422getMsg : IO a
2523getMsg {a} = mkForeign (FFun "idris_recvMessage"
2624 [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,
66 Network.Cgi, Network.Socket,
77 Debug.Trace,
88
9+ System.Info,
910 System.Concurrency.Raw, System.Concurrency.Process,
1011
1112 Decidable.Decidable, Decidable.Order,
@@ -22,7 +23,8 @@ modules = System,
2223 Data.SortedMap, Data.SortedSet, Data.BoundedList,
2324 Data.Vect, Data.HVect, Data.Vect.Quantifiers,
2425 Data.Floats, Data.Complex, Data.Heap, Data.Fun,
25− Data.Rel, Data.Buffer,
26+ Data.Rel, Data.Buffer, Data.Erased,
27+ Data.List,
2628
2729 Control.Isomorphism, Control.Isomorphism.Primitives,
2830 Control.Monad.Identity,
libs/effects/Effect/Exception.idr+1−1
@@ -27,7 +27,7 @@ EXCEPTION : Type -> EFFECT
2727EXCEPTION t = MkEff () (Exception t)
2828
2929raise : a -> { [EXCEPTION a ] } Eff m b
30−raise err = Raise err
30+raise err = call $ Raise err
3131
3232
3333
libs/effects/Effect/File.idr+10−15
@@ -101,33 +101,28 @@ FILE_IO t = MkEff t FileIO
101101|||
102102||| @ fname The file name to be opened.
103103||| @ m The file mode.
104−open : Handler FileIO e =>
105− (fname : String)
104+open : (fname : String)
106105 -> (m : Mode)
107106 -> { [FILE_IO ()] ==> [FILE_IO (if result
108107 then OpenFile m
109108 else ())] } Eff e Bool
110−open f m = Open f m
109+open f m = call $ Open f m
111110
112111
113112||| Close a file.
114−close : Handler FileIO e =>
115− { [FILE_IO (OpenFile m)] ==> [FILE_IO ()] } Eff e ()
116−close = Close
113+close : { [FILE_IO (OpenFile m)] ==> [FILE_IO ()] } Eff e ()
114+close = call $ Close
117115
118116||| Read a line from the file.
119−readLine : Handler FileIO e =>
120− { [FILE_IO (OpenFile Read)] } Eff e String
121−readLine = ReadLine
117+readLine : { [FILE_IO (OpenFile Read)] } Eff e String
118+readLine = call $ ReadLine
122119
123120||| Write a line to a file.
124−writeLine : Handler FileIO e =>
125− String -> { [FILE_IO (OpenFile Write)] } Eff e ()
126−writeLine str = WriteLine str
121+writeLine : String -> { [FILE_IO (OpenFile Write)] } Eff e ()
122+writeLine str = call $ WriteLine str
127123
128124||| End of file?
129−eof : Handler FileIO e =>
130− { [FILE_IO (OpenFile Read)] } Eff e Bool
131−eof = EOF
125+eof : { [FILE_IO (OpenFile Read)] } Eff e Bool
126+eof = call $ EOF
132127
133128-- --------------------------------------------------------------------- [ EOF ]
libs/effects/Effect/Memory.idr+7−7
@@ -102,7 +102,7 @@ RAW_MEMORY t = MkEff t RawMemory
102102
103103allocate : (n : Nat) ->
104104 Eff m () [RAW_MEMORY ()] (\v => [RAW_MEMORY (MemoryChunk n 0)])
105−allocate size = Allocate size
105+allocate size = call $ Allocate size
106106
107107initialize : {i : Nat} ->
108108 {n : Nat} ->
@@ -111,17 +111,17 @@ initialize : {i : Nat} ->
111111 so (i + size <= n) ->
112112 Eff m () [RAW_MEMORY (MemoryChunk n i)]
113113 (\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
115115
116116free : Eff m () [RAW_MEMORY (MemoryChunk n i)] (\v => [RAW_MEMORY ()])
117−free = Free
117+free = call Free
118118
119119peek : {i : Nat} ->
120120 (offset : Nat) ->
121121 (size : Nat) ->
122122 so (offset + size <= i) ->
123123 { [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
125125
126126poke : {n : Nat} ->
127127 {i : Nat} ->
@@ -130,11 +130,11 @@ poke : {n : Nat} ->
130130 so (offset <= i && offset + size <= n) ->
131131 Eff m () [RAW_MEMORY (MemoryChunk n i)]
132132 (\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
134134
135135private
136136getRawPtr : { [RAW_MEMORY (MemoryChunk n i)] } Eff m (MemoryChunk n i)
137−getRawPtr = GetRawPtr
137+getRawPtr = call $ GetRawPtr
138138
139139private
140140move' : {dst_size : Nat} ->
@@ -149,7 +149,7 @@ move' : {dst_size : Nat} ->
149149 Eff m () [RAW_MEMORY (MemoryChunk dst_size dst_init)]
150150 (\v => [RAW_MEMORY (MemoryChunk dst_size (max dst_init (dst_offset + size)))])
151151move' 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
153153
154154data MoveDescriptor = Dst | Src
155155
libs/effects/Effect/Random.idr+18−4
@@ -9,25 +9,39 @@ data Random : Effect where
99using (m : Type -> Type)
1010 instance Handler Random m where
1111 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
1313 k seed' seed'
1414 handle seed (setSeed n) k = k () n
1515
1616RND : EFFECT
1717RND = MkEff Integer Random
1818
19+||| Generates a random Integer in a given range
1920rndInt : Integer -> Integer -> { [RND] } Eff m Integer
20−rndInt lower upper = do v <- getRandom
21+rndInt lower upper = do v <- call $ getRandom
2122 return (v `prim__sremBigInt` (upper - lower) + lower)
2223
24+||| Generate a random number in Fin (S `k`)
25+|||
26+||| Note that rndFin k takes values 0, 1, ..., k.
2327rndFin : (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))
2529 return (toFin v)
2630 where toFin : Integer -> Fin (S k)
2731 toFin x = case integerToFin x (S k) of
2832 Just v => v
2933 Nothing => toFin (assert_smaller x (x - cast (S k)))
3034
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
3145srand : Integer -> { [RND] } Eff m ()
32−srand n = setSeed n
46+srand n = call $ setSeed n
3347
libs/effects/Effect/Select.idr+1−1
@@ -19,5 +19,5 @@ SELECT : EFFECT
1919SELECT = MkEff () Selection
2020
2121select : List a -> { [SELECT] } Eff m a
22−select xs = Select xs
22+select xs = call $ Select xs
2323
libs/effects/Effect/State.idr+3−3
@@ -17,13 +17,13 @@ STATE : Type -> EFFECT
1717STATE t = MkEff t State
1818
1919get : { [STATE x] } Eff m x
20−get = Get
20+get = call $ Get
2121
2222put : x -> { [STATE x] } Eff m ()
23−put val = Put val
23+put val = call $ Put val
2424
2525putM : y -> { [STATE x] ==> [STATE y] } Eff m ()
26−putM val = Put val
26+putM val = call $ Put val
2727
2828update : (x -> x) -> { [STATE x] } Eff m ()
2929update f = put (f !get)
libs/effects/Effect/StdIO.idr+26−9
@@ -3,12 +3,22 @@ module Effect.StdIO
33import Effects
44import Control.IOExcept
55
6+-------------------------------------------------------------
7+-- IO effects internals
8+-------------------------------------------------------------
9+
10+||| The internal representation of StdIO effects
611data StdIO : Effect where
712 PutStr : String -> { () } StdIO ()
813 GetStr : { () } StdIO String
914 PutCh : Char -> { () } StdIO ()
1015 GetCh : { () } StdIO Char
1116
17+
18+-------------------------------------------------------------
19+-- IO effects handlers
20+-------------------------------------------------------------
21+
1222instance Handler StdIO IO where
1323 handle () (PutStr s) k = do putStr s; k () ()
1424 handle () GetStr k = do x <- getLine; k x ()
@@ -21,23 +31,30 @@ instance Handler StdIO (IOExcept a) where
2131 handle () (PutCh c) k = do ioe_lift $ putChar c; k () ()
2232 handle () GetCh k = do x <- ioe_lift $ getChar; k x ()
2333
34+-------------------------------------------------------------
2435--- The Effect and associated functions
36+-------------------------------------------------------------
2537
2638STDIO : EFFECT
2739STDIO = MkEff () StdIO
2840
29−putStr : Handler StdIO e => String -> { [STDIO] } Eff e ()
30−putStr s = PutStr s
41+||| Write a string to standard output.
42+putStr : String -> { [STDIO] } Eff e ()
43+putStr s = call $ PutStr s
3144
32−putChar : Handler StdIO e => Char -> { [STDIO] } Eff e ()
33−putChar c = PutCh c
45+||| Write a character to standard output.
46+putChar : Char -> { [STDIO] } Eff e ()
47+putChar c = call $ PutCh c
3448
35−putStrLn : Handler StdIO e => String -> { [STDIO] } Eff e ()
49+||| Write a string to standard output, terminating with a newline.
50+putStrLn : String -> { [STDIO] } Eff e ()
3651putStrLn s = putStr (s ++ "\n")
3752
38−getStr : Handler StdIO e => { [STDIO] } Eff e String
39−getStr = GetStr
53+||| Read a string from standard input.
54+getStr : { [STDIO] } Eff e String
55+getStr = call $ GetStr
4056
41−getChar : Handler StdIO e => { [STDIO] } Eff e Char
42−getChar = GetCh
57+||| Read a character from standard input.
58+getChar : { [STDIO] } Eff e Char
59+getChar = call $ GetCh
4360
libs/effects/Effect/System.idr+3−3
@@ -28,11 +28,11 @@ SYSTEM : EFFECT
2828SYSTEM = MkEff () System
2929
3030getArgs : Handler System e => { [SYSTEM] } Eff e (List String)
31−getArgs = Args
31+getArgs = call Args
3232
3333time : Handler System e => { [SYSTEM] } Eff e Int
34−time = Time
34+time = call Time
3535
3636getEnv : Handler System e => String -> { [SYSTEM] } Eff e (Maybe String)
37−getEnv s = GetEnv s
37+getEnv s = call $ GetEnv s
3838
libs/effects/Effects.idr+37−69
@@ -31,9 +31,9 @@ class Handler (e : Effect) (m : Type -> Type) where
3131 |||
3232 ||| @ r The resource being handled.
3333 ||| @ eff The effect to be applied.
34− ||| @ ctxt The context in which to handle the effect.
35− handle : (r : res) -> (eff : e t res resk) ->
36− (ctxt : ((x : t) -> resk x -> m a)) -> m a
34+ ||| @ k The continuation to pass the result of the effect
35+ covering handle : (r : res) -> (eff : e t res resk) ->
36+ (k : ((x : t) -> resk x -> m a)) -> m a
3737
3838||| Get the resource type (handy at the REPL to find out about an effect)
3939resourceType : EFFECT -> Type
@@ -100,53 +100,6 @@ rebuildEnv xs (Drop rest) (y :: env) = y :: rebuildEnv xs rest env
100100
101101
102102-- -------------------------------------------------- [ 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
150103
151104updateResTy : (val : t) ->
152105 (xs : List EFFECT) -> EffElem e a xs -> e t a b ->
@@ -191,11 +144,11 @@ data Eff : (m : Type -> Type)
191144 Eff m a xs xs'
192145 ebind : Eff m a xs xs' ->
193146 ((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) ->
195148 (eff : e t a b) ->
196149 Eff m t xs (\v => updateResTy v xs prf eff)
197150
198− lift : (prf : SubList ys xs) ->
151+ liftP : (prf : SubList ys xs) ->
199152 Eff m t ys ys' -> Eff m t xs (\v => updateWith (ys' v) xs prf)
200153 newInit : Handler e m =>
201154 res ->
@@ -213,6 +166,20 @@ data Eff : (m : Type -> Type)
213166 ((val : a) -> Eff m b (xs' val) xs'') -> Eff m b xs xs''
214167(>>=) = ebind
215168
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+
216183return : a -> Eff m a xs (\v => xs)
217184return x = value x
218185
@@ -251,8 +218,8 @@ eff env (value x) k = k x env
251218eff env (with_val x prog) k = eff env prog (\p', env' => k x env')
252219eff env (prog `ebind` c) k
253220 = eff env prog (\p', env' => eff env' (c p') k)
254−eff env (effect prf effP) k = execEff env prf effP k
255−eff env (lift prf effP) k
221+eff env (callP prf effP) k = execEff env prf effP k
222+eff env (liftP prf effP) k
256223 = let env' = dropEnv env prf in
257224 eff env' effP (\p', envk => k p' (rebuildEnv envk prf env))
258225eff env (newInit r prog) k
@@ -269,7 +236,8 @@ eff {xs = [l ::: x]} env (l :- prog) k
269236 eff env' prog (\p', envk => k p' (relabel l envk))
270237
271238-- yuck :) Haven't got type class instances working nicely in tactic
272−-- proofs yet, so just brute force it.
239+-- proofs yet, and 'search' can't be told about any hints yet,
240+-- so just brute force it.
273241syntax MkDefaultEnv = with Env
274242 (| [], [default], [default, default],
275243 [default, default, default],
@@ -279,20 +247,20 @@ syntax MkDefaultEnv = with Env
279247 [default, default, default, default, default, default, default],
280248 [default, default, default, default, default, default, default, default] |)
281249
282−implicit
283−lift' : Eff m t ys ys' ->
284− {default tactics { byReflection reflectEff; }
285− prf : SubList ys xs} ->
286− Eff m t xs (\v => updateWith (ys' v) xs prf)
287−lift' e {prf} = lift prf e
250+call : {a, b: _} -> {e : Effect} ->
251+ (eff : e t a b) ->
252+ {default tactics { search 100; }
253+ prf : EffElem e a xs} ->
254+ Eff m t xs (\v => updateResTy v xs prf eff)
255+call e {prf} = callP prf e
288256
289257implicit
290−effect' : {a, b: _} -> {e : Effect} ->
291− (eff : e t a b) ->
292− {default tactics { byReflection reflectEff; }
293− prf : EffElem e a xs} ->
294− Eff m t xs (\v => updateResTy v xs prf eff)
295−effect' e {prf} = effect prf e
258+lift : Eff m t ys ys' ->
259+ {default tactics { search 100; }
260+ prf : SubList ys xs} ->
261+ Eff m t xs (\v => updateWith (ys' v) xs prf)
262+lift e {prf} = liftP prf e
263+
296264
297265new : Handler e m =>
298266 {default default r : res} ->
@@ -337,8 +305,8 @@ mapVE f [] = pure []
337305mapVE f (x :: xs) = [| f x :: mapVE f xs |]
338306
339307
340−when : Applicative m => Bool -> ({xs} Eff m ()) -> {xs} Eff m ()
341−when True e = e
308+when : Applicative m => Bool -> Lazy ({xs} Eff m ()) -> {xs} Eff m ()
309+when True e = Force e
342310when False e = pure ()
343311
344312-- --------------------------------------------------------------------- [ 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)
303303mapE f [] = pure []
304304mapE f (x :: xs) = [| f x :: mapE f xs |]
305305
306−when : Applicative m => Bool -> Eff m xs () -> Eff m xs ()
306+when : Applicative m => Bool -> Lazy (Eff m xs ()) -> Eff m xs ()
307307when True e = e
308308when False e = pure ()
libs/prelude/Builtins.idr+24−18
@@ -6,17 +6,10 @@
66||| Dependent pairs, in their internal representation
77||| @ a the type of the witness
88||| @ P the type of the proof
9−data Exists : (a : Type) -> (P : a -> Type) -> Type where
10− Ex_intro : {P : a -> Type} -> (x : a) -> P x -> Exists 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
9+data Sigma : (a : Type) -> (P : a -> Type) -> Type where
10+ Sg_intro : .{P : a -> Type} -> (x : a) -> (pf : P x) -> Sigma a P
1911
12+||| The eliminator for the empty type.
2013FalseElim : _|_ -> a
2114
2215||| For 'symbol syntax. 'foo becomes Symbol_ "foo"
@@ -34,26 +27,39 @@ sym : {l:a} -> {r:a} -> l = r -> r = l
3427sym refl = refl
3528
3629||| 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
3831trans refl refl = refl
3932
40−lazy : a -> a
41−lazy x = x -- compiled specially
42−
43−force : a -> a
44−force x = x -- compiled specially
45−
33+||| There are two types of laziness: that arising from lazy functions, and that
34+||| arising from codata. They differ in their totality condition.
4635data LazyType = LazyCodata | LazyEval
4736
37+||| The underlying implementation of Lazy and Inf.
38+%error_reverse
4839data 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
4948 Delay : {t, a : _} -> (val : a) -> Lazy' t a
5049
50+||| Compute a value from a delayed computation.
51+|||
52+||| Inserted by the elaborator where necessary.
5153Force : {t, a : _} -> Lazy' t a -> a
5254Force (Delay x) = x
5355
56+||| Lazily evaluated values. This has special evaluation semantics.
5457Lazy : Type -> Type
5558Lazy t = Lazy' LazyEval t
5659
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.
5763Inf : Type -> Type
5864Inf t = Lazy' LazyCodata t
5965
@@ -71,7 +77,7 @@ trace_malloc x = x -- compiled specially
7177||| x (which is typically a pattern argument)
7278||| @ x the larger value (typically a pattern argument)
7379||| @ 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
7581assert_smaller x y = y
7682
7783||| Assert to the totality checker than the given expression will always
libs/prelude/Prelude.idr+44−14
@@ -21,6 +21,7 @@ import Prelude.Traversable
2121import Prelude.Bits
2222import Prelude.Stream
2323import Prelude.Uninhabited
24+import Prelude.Pairs
2425
2526import Decidable.Equality
2627
@@ -347,27 +348,38 @@ natRange n = List.reverse (go n)
347348 where go Z = []
348349 go (S n) = n :: go n
349350
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+
350360class Enum a where
351361 total pred : a -> a
352362 total succ : a -> a
363+ succ e = fromNat (S (toNat e))
353364 total toNat : a -> Nat
354365 total fromNat : Nat -> a
355366 total enumFrom : a -> Stream a
356367 enumFrom n = n :: enumFrom (succ n)
357368 total enumFromThen : a -> a -> Stream a
369+ enumFromThen x y = map fromNat (natEnumFromThen (toNat x) (toNat y))
358370 total enumFromTo : a -> a -> List a
371+ enumFromTo x y = map fromNat (natEnumFromTo (toNat x) (toNat y))
359372 total enumFromThenTo : a -> a -> a -> List a
360−
373+ enumFromThenTo x1 x2 y = map fromNat (natEnumFromThenTo (toNat x1) (toNat x2) (toNat y))
361374
362375instance Enum Nat where
363− pred = Nat.pred
364− succ = S
365− toNat = id
366− fromNat = id
367− enumFromThen n inc = n :: enumFromThen (fromNat (plus (toNat inc) (toNat n))) inc
368− enumFromThenTo _ Z _ = []
369− enumFromThenTo n inc m = map (plus n . (* inc)) (natRange (S ((m - n) `div` inc)))
370− enumFromTo n m = map (plus n) (natRange ((S m) - n))
376+ pred n = Nat.pred n
377+ succ n = S n
378+ toNat x = id x
379+ fromNat x = id x
380+ enumFromThen x y = natEnumFromThen x y
381+ enumFromThenTo x y z = natEnumFromThenTo x y z
382+ enumFromTo x y = natEnumFromTo x y
371383
372384instance Enum Integer where
373385 pred n = n - 1
@@ -407,14 +419,25 @@ instance Enum Int where
407419 go [] = []
408420 go (x :: xs) = n + (cast x * inc) :: go xs
409421
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+
410433syntax "[" [start] ".." [end] "]"
411434 = enumFromTo start end
412435syntax "[" [start] "," [next] ".." [end] "]"
413436 = enumFromThenTo start (next - start) end
414437
415−syntax "[" [start] "..]"
438+syntax "[" [start] ".." "]"
416439 = enumFrom start
417−syntax "[" [start] "," [next] "..]"
440+syntax "[" [start] "," [next] ".." "]"
418441 = enumFromThen start (next - start)
419442
420443---- More utilities
@@ -478,6 +501,14 @@ data File = FHandle Ptr
478501partial stdin : File
479502stdin = FHandle prim__stdin
480503
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+
481512||| Call the RTS's file opening function
482513do_fopen : String -> String -> IO Ptr
483514do_fopen f m
@@ -519,9 +550,9 @@ fgetc : File -> IO Char
519550fgetc (FHandle h) = return (cast !(mkForeign (FFun "fgetc" [FPtr] FInt) h))
520551
521552fgetc' : File -> IO (Maybe Char)
522−fgetc' (FHandle h)
553+fgetc' (FHandle h)
523554 = do x <- mkForeign (FFun "fgetc" [FPtr] FInt) h
524− if (x < 0) then return Nothing
555+ if (x < 0) then return Nothing
525556 else return (Just (cast x))
526557
527558fflush : File -> IO ()
@@ -620,4 +651,3 @@ readFile fn = do h <- openFile fn Read
620651 if not x then do l <- fread h
621652 readFile' h (contents ++ l)
622653 else return contents
623−
libs/prelude/Prelude/Algebra.idr+191−176
@@ -13,238 +13,253 @@ infixl 6 <*>
1313-- A modest class hierarchy
1414--------------------------------------------------------------------------------
1515
16−-- Sets equipped with a single binary operation that is associative. Must
17−-- satisfy the following laws:
18−-- Associativity of <+>:
19−-- forall a b c, a <+> (b <+> c) == (a <+> b) <+> c
16+||| Sets equipped with a single binary operation that is associative. Must
17+||| satisfy the following laws:
18+|||
19+||| + Associativity of `<+>`:
20+||| forall a b c, a <+> (b <+> c) == (a <+> b) <+> c
2021class Semigroup a where
2122 (<+>) : a -> a -> a
2223
2324class 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
2526
26−-- 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−-- laws:
29−-- Associativity of <+>:
30−-- forall a b c, a <+> (b <+> c) == (a <+> b) <+> c
31−-- Neutral for <+>:
32−-- forall a, a <+> neutral == a
33−-- forall a, neutral <+> a == a
27+||| Sets equipped with a single binary operation that is associative, along with
28+||| a neutral element for that binary operation. Must satisfy the following
29+||| laws:
30+|||
31+||| + Associativity of `<+>`:
32+||| forall a b c, a <+> (b <+> c) == (a <+> b) <+> c
33+||| + Neutral for `<+>`:
34+||| forall a, a <+> neutral == a
35+||| forall a, neutral <+> a == a
3436class Semigroup a => Monoid a where
3537 neutral : a
3638
3739class (VerifiedSemigroup a, Monoid a) => VerifiedMonoid a where
38− monoidNeutralIsNeutralL : (l : a) -> l <+> neutral = l
39− monoidNeutralIsNeutralR : (r : a) -> neutral <+> r = r
40+ total monoidNeutralIsNeutralL : (l : a) -> l <+> neutral = l
41+ total monoidNeutralIsNeutralR : (r : a) -> neutral <+> r = r
4042
41−-- 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.
43−-- Must satisfy the following laws:
44−-- Associativity of <+>:
45−-- forall a b c, a <+> (b <+> c) == (a <+> b) <+> c
46−-- Neutral for <+>:
47−-- forall a, a <+> neutral == a
48−-- forall a, neutral <+> a == a
49−-- Inverse for <+>:
50−-- forall a, a <+> inverse a == neutral
51−-- forall a, inverse a <+> a == neutral
43+||| Sets equipped with a single binary operation that is associative, along with
44+||| a neutral element for that binary operation and inverses for all elements.
45+||| Must satisfy the following laws:
46+||| + Associativity of `<+>`:
47+||| forall a b c, a <+> (b <+> c) == (a <+> b) <+> c
48+||| + Neutral for `<+>`:
49+||| forall a, a <+> neutral == a
50+||| forall a, neutral <+> a == a
51+||| + Inverse for `<+>`:
52+||| forall a, a <+> inverse a == neutral
53+||| forall a, inverse a <+> a == neutral
5254class Monoid a => Group a where
5355 inverse : a -> a
5456
5557class (VerifiedMonoid a, Group a) => VerifiedGroup a where
56− groupInverseIsInverseL : (l : a) -> l <+> inverse l = neutral
57− groupInverseIsInverseR : (r : a) -> inverse r <+> r = neutral
58+ total groupInverseIsInverseL : (l : a) -> l <+> inverse l = neutral
59+ total groupInverseIsInverseR : (r : a) -> inverse r <+> r = neutral
5860
5961(<->) : Group a => a -> a -> a
6062(<->) left right = left <+> (inverse right)
6163
62−-- Sets equipped with a single binary operation that is associative and
63−-- commutative, along with a neutral element for that binary operation and
64−-- inverses for all elements. Must satisfy the following laws:
65−-- Associativity of <+>:
66−-- forall a b c, a <+> (b <+> c) == (a <+> b) <+> c
67−-- Commutativity of <+>:
68−-- forall a b, a <+> b == b <+> a
69−-- Neutral for <+>:
70−-- forall a, a <+> neutral == a
71−-- forall a, neutral <+> a == a
72−-- Inverse for <+>:
73−-- forall a, a <+> inverse a == neutral
74−-- forall a, inverse a <+> a == neutral
64+||| Sets equipped with a single binary operation that is associative and
65+||| commutative, along with a neutral element for that binary operation and
66+||| inverses for all elements. Must satisfy the following laws:
67+|||
68+||| + Associativity of `<+>`:
69+||| forall a b c, a <+> (b <+> c) == (a <+> b) <+> c
70+||| + Commutativity of `<+>`:
71+||| forall a b, a <+> b == b <+> a
72+||| + Neutral for `<+>`:
73+||| forall a, a <+> neutral == a
74+||| forall a, neutral <+> a == a
75+||| + Inverse for `<+>`:
76+||| forall a, a <+> inverse a == neutral
77+||| forall a, inverse a <+> a == neutral
7578class Group a => AbelianGroup a where { }
7679
7780class (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
7982
80−-- Sets equipped with two binary operations, one associative and commutative
81−-- supplied with a neutral element, and the other associative, with
82−-- distributivity laws relating the two operations. Must satisfy the following
83−-- laws:
84−-- Associativity of <+>:
85−-- forall a b c, a <+> (b <+> c) == (a <+> b) <+> c
86−-- Commutativity of <+>:
87−-- forall a b, a <+> b == b <+> a
88−-- Neutral for <+>:
89−-- forall a, a <+> neutral == a
90−-- forall a, neutral <+> a == a
91−-- Inverse for <+>:
92−-- forall a, a <+> inverse a == neutral
93−-- forall a, inverse a <+> a == neutral
94−-- Associativity of <*>:
95−-- forall a b c, a <*> (b <*> c) == (a <*> b) <*> c
96−-- Distributivity of <*> and <->:
97−-- forall a b c, a <*> (b <+> c) == (a <*> b) <+> (a <*> c)
98−-- forall a b c, (a <+> b) <*> c == (a <*> c) <+> (b <*> c)
83+||| Sets equipped with two binary operations, one associative and commutative
84+||| supplied with a neutral element, and the other associative, with
85+||| distributivity laws relating the two operations. Must satisfy the following
86+||| laws:
87+|||
88+||| + Associativity of `<+>`:
89+||| forall a b c, a <+> (b <+> c) == (a <+> b) <+> c
90+||| + Commutativity of `<+>`:
91+||| forall a b, a <+> b == b <+> a
92+||| + Neutral for `<+>`:
93+||| forall a, a <+> neutral == a
94+||| forall a, neutral <+> a == a
95+||| + Inverse for `<+>`:
96+||| forall a, a <+> inverse a == neutral
97+||| forall a, inverse a <+> a == neutral
98+||| + Associativity of `<*>`:
99+||| forall a b c, a <*> (b <*> c) == (a <*> b) <*> c
100+||| + Distributivity of `<*>` and `<->`:
101+||| forall a b c, a <*> (b <+> c) == (a <*> b) <+> (a <*> c)
102+||| forall a b c, (a <+> b) <*> c == (a <*> c) <+> (b <*> c)
99103class AbelianGroup a => Ring a where
100104 (<*>) : a -> a -> a
101105
102106class (VerifiedAbelianGroup a, Ring a) => VerifiedRing a where
103− ringOpIsAssociative : (l, c, r : a) -> l <*> (c <*> r) = (l <*> c) <*> r
104− 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)
107+ total ringOpIsAssociative : (l, c, r : a) -> l <*> (c <*> r) = (l <*> c) <*> r
108+ total ringOpIsDistributiveL : (l, c, r : a) -> l <*> (c <+> r) = (l <*> c) <+> (l <*> r)
109+ total ringOpIsDistributiveR : (l, c, r : a) -> (l <+> c) <*> r = (l <*> r) <+> (c <*> r)
106110
107−-- Sets equipped with two binary operations, one associative and commutative
108−-- supplied with a neutral element, and the other associative supplied with a
109−-- neutral element, with distributivity laws relating the two operations. Must
110−-- satisfy the following laws:
111−-- Associativity of <+>:
112−-- forall a b c, a <+> (b <+> c) == (a <+> b) <+> c
113−-- Commutativity of <+>:
114−-- forall a b, a <+> b == b <+> a
115−-- Neutral for <+>:
116−-- forall a, a <+> neutral == a
117−-- forall a, neutral <+> a == a
118−-- Inverse for <+>:
119−-- forall a, a <+> inverse a == neutral
120−-- forall a, inverse a <+> a == neutral
121−-- Associativity of <*>:
122−-- forall a b c, a <*> (b <*> c) == (a <*> b) <*> c
123−-- Neutral for <*>:
124−-- forall a, a <*> unity == a
125−-- forall a, unity <*> a == a
126−-- Distributivity of <*> and <->:
127−-- forall a b c, a <*> (b <+> c) == (a <*> b) <+> (a <*> c)
128−-- forall a b c, (a <+> b) <*> c == (a <*> c) <+> (b <*> c)
111+||| Sets equipped with two binary operations, one associative and commutative
112+||| supplied with a neutral element, and the other associative supplied with a
113+||| neutral element, with distributivity laws relating the two operations. Must
114+||| satisfy the following laws:
115+|||
116+||| + Associativity of `<+>`:
117+||| forall a b c, a <+> (b <+> c) == (a <+> b) <+> c
118+||| + Commutativity of `<+>`:
119+||| forall a b, a <+> b == b <+> a
120+||| + Neutral for `<+>`:
121+||| forall a, a <+> neutral == a
122+||| forall a, neutral <+> a == a
123+||| + Inverse for `<+>`:
124+||| forall a, a <+> inverse a == neutral
125+||| forall a, inverse a <+> a == neutral
126+||| + Associativity of `<*>a:
127+||| forall a b c, a <*> (b <*> c) == (a <*> b) <*> c
128+||| + Neutral for `<*>`:
129+||| forall a, a <*> unity == a
130+||| forall a, unity <*> a == a
131+||| + Distributivity of `<*>` and `<->`:
132+||| forall a b c, a <*> (b <+> c) == (a <*> b) <+> (a <*> c)
133+||| forall a b c, (a <+> b) <*> c == (a <*> c) <+> (b <*> c)
129134class Ring a => RingWithUnity a where
130135 unity : a
131136
132137class (VerifiedRing a, RingWithUnity a) => VerifiedRingWithUnity a where
133− ringWithUnityIsUnityL : (l : a) -> l <*> unity = l
134− ringWithUnityIsUnityR : (r : a) -> unity <*> r = r
138+ total ringWithUnityIsUnityL : (l : a) -> l <*> unity = l
139+ total ringWithUnityIsUnityR : (r : a) -> unity <*> r = r
135140
136−-- Sets equipped with a binary operation that is commutative, associative and
137−-- idempotent. Must satisfy the following laws:
138−-- Associativity of join:
139−-- forall a b c, join a (join b c) == join (join a b) c
140−-- Commutativity of join:
141−-- forall a b, join a b == join b a
142−-- Idempotency of join:
143−-- forall a, join a a == a
144−-- Join semilattices capture the notion of sets with a "least upper bound".
141+||| Sets equipped with a binary operation that is commutative, associative and
142+||| idempotent. Must satisfy the following laws:
143+|||
144+||| + Associativity of join:
145+||| forall a b c, join a (join b c) == join (join a b) c
146+||| + Commutativity of join:
147+||| forall a b, join a b == join b a
148+||| + Idempotency of join:
149+||| forall a, join a a == a
150+|||
151+||| Join semilattices capture the notion of sets with a "least upper bound".
145152class JoinSemilattice a where
146153 join : a -> a -> a
147154
148155class JoinSemilattice a => VerifiedJoinSemilattice a where
149− 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
151− joinSemilatticeJoinIsIdempotent : (e : a) -> join e e = e
156+ total joinSemilatticeJoinIsAssociative : (l, c, r : a) -> join l (join c r) = join (join l c) r
157+ total joinSemilatticeJoinIsCommutative : (l, r : a) -> join l r = join r l
158+ total joinSemilatticeJoinIsIdempotent : (e : a) -> join e e = e
152159
153−-- Sets equipped with a binary operation that is commutative, associative and
154−-- idempotent. Must satisfy the following laws:
155−-- Associativity of meet:
156−-- forall a b c, meet a (meet b c) == meet (meet a b) c
157−-- Commutativity of meet:
158−-- forall a b, meet a b == meet b a
159−-- Idempotency of meet:
160−-- forall a, meet a a == a
161−-- Meet semilattices capture the notion of sets with a "greatest lower bound".
160+||| Sets equipped with a binary operation that is commutative, associative and
161+||| idempotent. Must satisfy the following laws:
162+|||
163+||| + Associativity of meet:
164+||| forall a b c, meet a (meet b c) == meet (meet a b) c
165+||| + Commutativity of meet:
166+||| forall a b, meet a b == meet b a
167+||| + Idempotency of meet:
168+||| forall a, meet a a == a
169+|||
170+||| Meet semilattices capture the notion of sets with a "greatest lower bound".
162171class MeetSemilattice a where
163172 meet : a -> a -> a
164173
165174class MeetSemilattice a => VerifiedMeetSemilattice a where
166− 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
168− meetSemilatticeMeetIsIdempotent : (e : a) -> meet e e = e
175+ total meetSemilatticeMeetIsAssociative : (l, c, r : a) -> meet l (meet c r) = meet (meet l c) r
176+ total meetSemilatticeMeetIsCommutative : (l, r : a) -> meet l r = meet r l
177+ total meetSemilatticeMeetIsIdempotent : (e : a) -> meet e e = e
169178
170−-- Sets equipped with a binary operation that is commutative, associative and
171−-- idempotent and supplied with a neutral element. Must satisfy the following
172−-- laws:
173−-- Associativity of join:
174−-- forall a b c, join a (join b c) == join (join a b) c
175−-- Commutativity of join:
176−-- forall a b, join a b == join b a
177−-- Idempotency of join:
178−-- forall a, join a a == a
179−-- Bottom:
180−-- forall a, join a bottom == bottom
181−-- Join semilattices capture the notion of sets with a "least upper bound"
182−-- equipped with a "bottom" element.
179+||| Sets equipped with a binary operation that is commutative, associative and
180+||| idempotent and supplied with a neutral element. Must satisfy the following
181+||| laws:
182+|||
183+||| + Associativity of join:
184+||| forall a b c, join a (join b c) == join (join a b) c
185+||| + Commutativity of join:
186+||| forall a b, join a b == join b a
187+||| + Idempotency of join:
188+||| forall a, join a a == a
189+||| + Bottom:
190+||| forall a, join a bottom == bottom
191+|||
192+||| Join semilattices capture the notion of sets with a "least upper bound"
193+||| equipped with a "bottom" element.
183194class JoinSemilattice a => BoundedJoinSemilattice a where
184195 bottom : a
185196
186197class (VerifiedJoinSemilattice a, BoundedJoinSemilattice a) => VerifiedBoundedJoinSemilattice a where
187− boundedJoinSemilatticeBottomIsBottom : (e : a) -> join e bottom = bottom
198+ total boundedJoinSemilatticeBottomIsBottom : (e : a) -> join e bottom = bottom
188199
189−-- Sets equipped with a binary operation that is commutative, associative and
190−-- idempotent and supplied with a neutral element. Must satisfy the following
191−-- laws:
192−-- Associativity of meet:
193−-- forall a b c, meet a (meet b c) == meet (meet a b) c
194−-- Commutativity of meet:
195−-- forall a b, meet a b == meet b a
196−-- Idempotency of meet:
197−-- forall a, meet a a == a
198−-- Top:
199−-- forall a, meet a top == top
200−-- Meet semilattices capture the notion of sets with a "greatest lower bound"
201−-- equipped with a "top" element.
200+||| Sets equipped with a binary operation that is commutative, associative and
201+||| idempotent and supplied with a neutral element. Must satisfy the following
202+||| laws:
203+|||
204+||| + Associativity of meet:
205+||| forall a b c, meet a (meet b c) == meet (meet a b) c
206+||| + Commutativity of meet:
207+||| forall a b, meet a b == meet b a
208+||| + Idempotency of meet:
209+||| forall a, meet a a == a
210+||| + Top:
211+||| forall a, meet a top == top
212+|||
213+||| Meet semilattices capture the notion of sets with a "greatest lower bound"
214+||| equipped with a "top" element.
202215class MeetSemilattice a => BoundedMeetSemilattice a where
203216 top : a
204217
205218class (VerifiedMeetSemilattice a, BoundedMeetSemilattice a) => VerifiedBoundedMeetSemilattice a where
206− boundedMeetSemilatticeTopIsTop : (e : a) -> meet e top = top
219+ total boundedMeetSemilatticeTopIsTop : (e : a) -> meet e top = top
207220
208−-- Sets equipped with two binary operations that are both commutative,
209−-- associative and idempotent, along with absorbtion laws for relating the two
210−-- binary operations. Must satisfy the following:
211−-- Associativity of meet and join:
212−-- 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
214−-- Commutativity of meet and join:
215−-- forall a b, meet a b == meet b a
216−-- forall a b, join a b == join b a
217−-- Idempotency of meet and join:
218−-- forall a, meet a a == a
219−-- forall a, join a a == a
220−-- Absorbtion laws for meet and join:
221−-- forall a b, meet a (join a b) == a
222−-- forall a b, join a (meet a b) == a
221+||| Sets equipped with two binary operations that are both commutative,
222+||| associative and idempotent, along with absorbtion laws for relating the two
223+||| binary operations. Must satisfy the following:
224+|||
225+||| + Associativity of meet and join:
226+||| forall a b c, meet a (meet b c) == meet (meet a b) c
227+||| forall a b c, join a (join b c) == join (join a b) c
228+||| + Commutativity of meet and join:
229+||| forall a b, meet a b == meet b a
230+||| forall a b, join a b == join b a
231+||| + Idempotency of meet and join:
232+||| forall a, meet a a == a
233+||| forall a, join a a == a
234+||| + Absorbtion laws for meet and join:
235+||| forall a b, meet a (join a b) == a
236+||| forall a b, join a (meet a b) == a
223237class (JoinSemilattice a, MeetSemilattice a) => Lattice a where { }
224238
225239class (VerifiedJoinSemilattice a, VerifiedMeetSemilattice a) => VerifiedLattice a where
226− latticeMeetAbsorbsJoin : (l, r : a) -> meet l (join l r) = l
227− latticeJoinAbsorbsMeet : (l, r : a) -> join l (meet l r) = l
240+ total latticeMeetAbsorbsJoin : (l, r : a) -> meet l (join l r) = l
241+ total latticeJoinAbsorbsMeet : (l, r : a) -> join l (meet l r) = l
228242
229−-- Sets equipped with two binary operations that are both commutative,
230−-- associative and idempotent and supplied with neutral elements, along with
231−-- absorbtion laws for relating the two binary operations. Must satisfy the
232−-- following:
233−-- Associativity of meet and join:
234−-- 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
236−-- Commutativity of meet and join:
237−-- forall a b, meet a b == meet b a
238−-- forall a b, join a b == join b a
239−-- Idempotency of meet and join:
240−-- forall a, meet a a == a
241−-- forall a, join a a == a
242−-- Absorbtion laws for meet and join:
243−-- forall a b, meet a (join a b) == a
244−-- forall a b, join a (meet a b) == a
245−-- Neutral for meet and join:
246−-- forall a, meet a top == top
247−-- forall a, join a bottom == bottom
243+||| Sets equipped with two binary operations that are both commutative,
244+||| associative and idempotent and supplied with neutral elements, along with
245+||| absorbtion laws for relating the two binary operations. Must satisfy the
246+||| following:
247+|||
248+||| + Associativity of meet and join:
249+||| forall a b c, meet a (meet b c) == meet (meet a b) c
250+||| forall a b c, join a (join b c) == join (join a b) c
251+||| + Commutativity of meet and join:
252+||| forall a b, meet a b == meet b a
253+||| forall a b, join a b == join b a
254+||| + Idempotency of meet and join:
255+||| forall a, meet a a == a
256+||| forall a, join a a == a
257+||| + Absorbtion laws for meet and join:
258+||| forall a b, meet a (join a b) == a
259+||| forall a b, join a (meet a b) == a
260+||| + Neutral for meet and join:
261+||| forall a, meet a top == top
262+||| forall a, join a bottom == bottom
248263class (BoundedJoinSemilattice a, BoundedMeetSemilattice a) => BoundedLattice a where { }
249264
250265class (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
3838 empty : f a
3939 (<|>) : f a -> f a -> f a
4040
41+||| `guard a` is `pure ()` if `a` is `True` and `empty` if `a` is `False`
4142guard : Alternative f => Bool -> f ()
4243guard a = if a then pure () else empty
4344
44−when : Applicative f => Bool -> f () -> f ()
45−when a f = if a then f else pure ()
45+||| Conditionally execute an applicative expression
46+when : Applicative f => Bool -> Lazy (f ()) -> f ()
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
22
33import Builtins
44
5+import Prelude.Uninhabited
6+
57||| Boolean Data Type
68data Bool = False | True
79
@@ -13,22 +15,33 @@ boolElim : (b : Bool) -> (t : Lazy a) -> (e : Lazy a) -> a
1315boolElim True t e = t
1416boolElim False t e = e
1517
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.
1727data so : Bool -> Type where oh : so True
1828
29+instance Uninhabited (so False) where
30+ uninhabited oh impossible
31+
1932-- Syntactic sugar for boolean elimination.
2033syntax if [test] then [t] else [e] = boolElim test (Delay t) (Delay e)
2134
2235-- Boolean Operator Precedence
2336infixl 4 &&, ||
2437
25−||| Boolean OR
26−(||) : Bool -> Bool -> Bool
38+||| Boolean OR only evaluates the second argument if the first is `False`.
39+(||) : Bool -> Lazy Bool -> Bool
2740(||) False x = x
2841(||) True _ = True
2942
30−||| Boolean AND
31−(&&) : Bool -> Bool -> Bool
43+||| Boolean AND only evaluates the second argument if the first is `True`.
44+(&&) : Bool -> Lazy Bool -> Bool
3245(&&) True x = x
3346(&&) False _ = False
3447
libs/prelude/Prelude/Cast.idr+5−3
@@ -1,7 +1,11 @@
11module Prelude.Cast
22
3+||| Type class for transforming a instance of a data type to another type.
34class Cast from to where
4− cast : from -> to
5+ ||| Perform a cast operation.
6+ |||
7+ ||| @orig The original type.
8+ cast : (orig : from) -> to
59
610-- String casts
711
@@ -45,5 +49,3 @@ instance Cast Integer String where
4549
4650instance Cast Char Int where
4751 cast = prim__charToInt
48−
49−
libs/prelude/Prelude/Classes.idr+8−2
@@ -244,14 +244,20 @@ instance Ord Bits64 where
244244
245245-- ------------------------------------------------------------- [ Bounded ]
246246
247−class MinBound b where
247+class Ord b => MinBound b where
248248 ||| The lower bound for the type
249249 minBound : b
250250
251−class MaxBound b where
251+class Ord b => MaxBound b where
252252 ||| The upper bound for the type
253253 maxBound : b
254254
255+instance MinBound Bits8 where
256+ minBound = 0x0
257+
258+instance MaxBound Bits8 where
259+ maxBound = 0xff
260+
255261instance MinBound Bits16 where
256262 minBound = 0x0
257263
libs/prelude/Prelude/Either.idr+4−4
@@ -39,9 +39,9 @@ choose False = Right oh
3939||| @ f the action to take on Left
4040||| @ g the action to take on Right
4141||| @ e the sum to analyze
42−either : (f : a -> c) -> (g : b -> c) -> (e : Either a b) -> c
43−either l r (Left x) = l x
44−either l r (Right x) = r x
42+either : (f : Lazy (a -> c)) -> (g : Lazy (b -> c)) -> (e : Either a b) -> c
43+either l r (Left x) = (Force l) x
44+either l r (Right x) = (Force r) x
4545
4646||| Keep the payloads of all Left constructors in a list of Eithers
4747lefts : List (Either a b) -> List a
@@ -74,7 +74,7 @@ fromEither (Right r) = r
7474
7575||| Convert a Maybe to an Either by using a default value in case of Nothing
7676||| @ e the default value
77−maybeToEither : (def : e) -> Maybe a -> Either e a
77+maybeToEither : (def : Lazy e) -> Maybe a -> Either e a
7878maybeToEither def (Just j) = Right j
7979maybeToEither def Nothing = Left def
8080
libs/prelude/Prelude/Fin.idr+18−2
@@ -6,7 +6,10 @@ import Prelude.Uninhabited
66
77%default total
88
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.
1013||| @ n the upper bound
1114data Fin : (n : Nat) -> Type where
1215 fZ : Fin (S k)
@@ -24,16 +27,19 @@ instance Eq (Fin n) where
2427 (==) (fS k) (fS k') = k == k'
2528 (==) _ _ = False
2629
30+||| There are no elements of `Fin Z`
2731FinZAbsurd : Fin Z -> _|_
2832FinZAbsurd fZ impossible
2933
3034FinZElim : Fin Z -> a
3135FinZElim x = FalseElim (FinZAbsurd x)
3236
37+||| Convert a Fin to a Nat
3338finToNat : Fin n -> Nat
3439finToNat fZ = Z
3540finToNat (fS k) = S (finToNat k)
3641
42+||| `finToNat` is injective
3743finToNatInjective : (fm : Fin k) -> (fn : Fin k) -> (finToNat fm) = (finToNat fn) -> fm = fn
3844finToNatInjective fZ fZ refl = refl
3945finToNatInjective (fS m) fZ refl impossible
@@ -44,6 +50,7 @@ finToNatInjective (fS m) (fS n) prf =
4450instance Cast (Fin n) Nat where
4551 cast x = finToNat x
4652
53+||| Convert a Fin to an Integer
4754finToInteger : Fin n -> Integer
4855finToInteger fZ = 0
4956finToInteger (fS k) = 1 + finToInteger k
@@ -85,7 +92,12 @@ last {n=S _} = fS last
8592total fSinjective : {f : Fin n} -> {f' : Fin n} -> (fS f = fS f') -> f = f'
8693fSinjective refl = refl
8794
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+
89101instance MinBound (Fin (S n)) where
90102 minBound = fZ
91103
@@ -123,9 +135,13 @@ natToFin _ _ = Nothing
123135integerToFin : Integer -> (n : Nat) -> Maybe (Fin n)
124136integerToFin x n = if x >= 0 then natToFin (cast x) n else Nothing
125137
138+||| Proof that some `Maybe` is actually `Just`
126139data IsJust : Maybe a -> Type where
127140 ItIsJust : IsJust {a} (Just x)
128141
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
129145fromInteger : (x : Integer) ->
130146 {default ItIsJust
131147 prf : (IsJust (integerToFin x n))} ->
libs/prelude/Prelude/Foldable.idr+27−11
@@ -10,31 +10,47 @@ import Prelude.Algebra
1010
1111class Foldable (t : Type -> Type) where
1212 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
1315
14−foldl : Foldable t => (acc -> elt -> acc) -> acc -> t elt -> acc
15−foldl f z t = foldr (flip (.) . flip f) id t z
16−
16+||| Combine each element of a structure into a monoid
1717concat : (Foldable t, Monoid a) => t a -> a
1818concat = foldr (<+>) neutral
1919
20+||| Combine into a monoid the collective results of applying a function
21+||| to each element of a structure
2022concatMap : (Foldable t, Monoid m) => (a -> m) -> t a -> m
2123concatMap f = foldr ((<+>) . f) neutral
2224
23−and : Foldable t => t Bool -> Bool
24−and = foldr (&&) True
25−
26−or : Foldable t => t Bool -> Bool
27−or = foldr (||) False
28−
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.
28+and : Foldable t => t (Lazy Bool) -> Bool
29+and = foldl (&&) True
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.
34+or : Foldable t => t (Lazy Bool) -> Bool
35+or = foldl (||) False
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.
2940any : Foldable t => (a -> Bool) -> t a -> Bool
30−any p = foldr ((||) . p) False
41+any p = foldl (\x => \y => x || p y) False
3142
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.
3246all : Foldable t => (a -> Bool) -> t a -> Bool
33−all p = foldr ((&&) . p) True
47+all p = foldl (\x => \y => x && p y) True
3448
49+||| Add together all the elements of a structure
3550sum : (Foldable t, Num a) => t a -> a
3651sum = foldr (+) 0
3752
53+||| Multiply together all elements of a structure
3854product : (Foldable t, Num a) => t a -> a
3955product = foldr (*) 1
4056
libs/prelude/Prelude/List.idr+157−32
@@ -12,11 +12,15 @@ import Prelude.Nat
1212%access public
1313%default total
1414
15+infix 5 \\
1516infixr 7 ::,++
1617
17−%elim data List a
18− = Nil
19− | (::) a (List a)
18+||| Linked lists
19+%elim data List a =
20+ ||| The empty list
21+ Nil |
22+ ||| Cons cell
23+ (::) a (List a)
2024
2125-- Name hints for interactive editing
2226%name List xs, ys, zs, ws
@@ -25,10 +29,12 @@ infixr 7 ::,++
2529-- Syntactic tests
2630--------------------------------------------------------------------------------
2731
32+||| Returns `True` iff the argument is empty
2833isNil : List a -> Bool
2934isNil [] = True
3035isNil (x::xs) = False
3136
37+||| Returns `True` iff the argument is not empty
3238isCons : List a -> Bool
3339isCons [] = False
3440isCons (x::xs) = True
@@ -37,6 +43,9 @@ isCons (x::xs) = True
3743-- Length
3844--------------------------------------------------------------------------------
3945
46+||| Compute the length of a list.
47+|||
48+||| Runs in linear time
4049length : List a -> Nat
4150length [] = 0
4251length (x::xs) = 1 + length xs
@@ -45,49 +54,74 @@ length (x::xs) = 1 + length xs
4554-- Indexing into lists
4655--------------------------------------------------------------------------------
4756
48−index : (n : Nat) -> (l : List a) -> (lt n (length l) = True) -> a
57+||| Find a particular element of a list.
58+|||
59+||| @ ok a proof that the index is within bounds
60+index : (n : Nat) -> (l : List a) -> (ok : lt n (length l) = True) -> a
4961index Z (x::xs) p = x
5062index (S n) (x::xs) p = index n xs ?indexTailProof
5163index _ [] refl impossible
5264
65+||| Attempt to find a particular element of a list.
66+|||
67+||| If the provided index is out of bounds, return Nothing.
5368index' : (n : Nat) -> (l : List a) -> Maybe a
5469index' Z (x::xs) = Just x
5570index' (S n) (x::xs) = index' n xs
5671index' _ [] = Nothing
5772
58−head : (l : List a) -> (isCons l = True) -> a
73+||| Get the first element of a non-empty list
74+||| @ ok proof that the list is non-empty
75+head : (l : List a) -> (ok : isCons l = True) -> a
5976head [] refl impossible
6077head (x::xs) p = x
6178
79+||| Attempt to get the first element of a list. If the list is empty, return
80+||| `Nothing`.
6281head' : (l : List a) -> Maybe a
6382head' [] = Nothing
6483head' (x::xs) = Just x
6584
66−tail : (l : List a) -> (isCons l = True) -> List a
85+||| Get the tail of a non-empty list.
86+||| @ ok proof that the list is non-empty
87+tail : (l : List a) -> (ok : isCons l = True) -> List a
6788tail [] refl impossible
6889tail (x::xs) p = xs
6990
91+||| Attempt to get the tail of a list.
92+|||
93+||| If the list is empty, return `Nothing`.
7094tail' : (l : List a) -> Maybe (List a)
7195tail' [] = Nothing
7296tail' (x::xs) = Just xs
7397
74−last : (l : List a) -> (isCons l = True) -> a
98+||| Retrieve the last element of a non-empty list.
99+||| @ ok proof that the list is non-empty
100+last : (l : List a) -> (ok : isCons l = True) -> a
75101last [] refl impossible
76102last [x] p = x
77103last (x::y::ys) p = last (y::ys) refl
78104
105+||| Attempt to retrieve the last element of a non-empty list.
106+|||
107+||| If the list is empty, return `Nothing`.
79108last' : (l : List a) -> Maybe a
80109last' [] = Nothing
81−last' (x::xs) =
110+last' (x::xs) =
82111 case xs of
83112 [] => Just x
84113 y :: ys => last' xs
85114
86−init : (l : List a) -> (isCons l = True) -> List a
115+||| Return all but the last element of a non-empty list.
116+||| @ ok proof that the list is non-empty
117+init : (l : List a) -> (ok : isCons l = True) -> List a
87118init [] refl impossible
88119init [x] p = []
89120init (x::y::ys) p = x :: init (y::ys) refl
90121
122+||| Attempt to Return all but the last element of a list.
123+|||
124+||| If the list is empty, return `Nothing`.
91125init' : (l : List a) -> Maybe (List a)
92126init' [] = Nothing
93127init' (x::xs) =
@@ -103,21 +137,39 @@ init' (x::xs) =
103137-- Sublists
104138--------------------------------------------------------------------------------
105139
106−take : Nat -> List a -> List a
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
145+take : (n : Nat) -> (xs : List a) -> List a
107146take Z xs = []
108147take (S n) [] = []
109148take (S n) (x::xs) = x :: take n xs
110149
111−drop : Nat -> List a -> List a
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
155+drop : (n : Nat) -> (xs : List a) -> List a
112156drop Z xs = xs
113157drop (S n) [] = []
114158drop (S n) (x::xs) = drop n xs
115159
116−takeWhile : (a -> Bool) -> List a -> List a
160+||| Take the longest prefix of a list such that all elements satsify some
161+||| Boolean predicate.
162+|||
163+||| @ p the predicate
164+takeWhile : (p : a -> Bool) -> List a -> List a
117165takeWhile p [] = []
118166takeWhile p (x::xs) = if p x then x :: takeWhile p xs else []
119167
120−dropWhile : (a -> Bool) -> List a -> List a
168+||| Remove the longest prefix of a list such that all removed elements satsify some
169+||| Boolean predicate.
170+|||
171+||| @ p the predicate
172+dropWhile : (p : a -> Bool) -> List a -> List a
121173dropWhile p [] = []
122174dropWhile p (x::xs) = if p x then dropWhile p xs else x::xs
123175
@@ -125,24 +177,29 @@ dropWhile p (x::xs) = if p x then dropWhile p xs else x::xs
125177-- Misc.
126178--------------------------------------------------------------------------------
127179
128−list : a -> (a -> List a -> a) -> List a -> a
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
185+list : (nil : Lazy b) -> (cons : Lazy (a -> List a -> b)) -> (xs : List a) -> b
129186list nil cons [] = nil
130−list nil cons (x::xs) = cons x xs
187+list nil cons (x::xs) = (Force cons) x xs
131188
132189--------------------------------------------------------------------------------
133190-- Building (bigger) lists
134191--------------------------------------------------------------------------------
135192
193+||| Append two lists
136194(++) : List a -> List a -> List a
137−(++) [] right = right
195+(++) [] right = right
138196(++) (x::xs) right = x :: (xs ++ right)
139197
140−partial
141−repeat : a -> List a
142−repeat x = x :: lazy (repeat x)
143−
144−replicate : Nat -> a -> List a
145−replicate Z x = []
198+||| Construct a list with `n` copies of `x`
199+||| @ n how many copies
200+||| @ x the element to replicate
201+replicate : (n : Nat) -> (x : a) -> List a
202+replicate Z x = []
146203replicate (S n) x = x :: replicate n x
147204
148205--------------------------------------------------------------------------------
@@ -187,15 +244,27 @@ instance Functor List where
187244-- Zips and unzips
188245--------------------------------------------------------------------------------
189246
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
190252zipWith : (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
192254zipWith f [] (y::ys) refl impossible
193255zipWith f (x::xs) [] refl impossible
194256zipWith f [] [] p = []
195257zipWith f (x::xs) (y::ys) p = f x y :: (zipWith f xs ys ?zipWithTailProof)
196258
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
197266zipWith3 : (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
199268zipWith3 f _ [] (z::zs) p refl impossible
200269zipWith3 f _ (y::ys) [] p refl impossible
201270zipWith3 f [] (y::ys) _ refl q impossible
@@ -204,18 +273,22 @@ zipWith3 f [] [] [] p q = []
204273zipWith3 f (x::xs) (y::ys) (z::zs) p q =
205274 f x y z :: (zipWith3 f xs ys zs ?zipWith3TailProof ?zipWith3TailProof')
206275
276+||| Combine two lists elementwise into pairs
207277zip : (l : List a) -> (r : List b) -> (length l = length r) -> List (a, b)
208278zip = zipWith (\x => \y => (x, y))
209279
280+||| Combine three lists elementwise into tuples
210281zip3 : (x : List a) -> (y : List b) -> (z : List c) -> (length x = length y) ->
211282 (length y = length z) -> List (a, b, c)
212283zip3 = zipWith3 (\x => \y => \z => (x, y, z))
213284
285+||| Split a list of pairs into two lists
214286unzip : List (a, b) -> (List a, List b)
215287unzip [] = ([], [])
216288unzip ((l, r)::xs) with (unzip xs)
217289 | (lefts, rights) = (l::lefts, r::rights)
218290
291+||| Split a list of triples into three lists
219292unzip3 : List (a, b, c) -> (List a, List b, List c)
220293unzip3 [] = ([], [], [])
221294unzip3 ((l, c, r)::xs) with (unzip3 xs)
@@ -225,6 +298,8 @@ unzip3 ((l, c, r)::xs) with (unzip3 xs)
225298-- Maps
226299--------------------------------------------------------------------------------
227300
301+||| Apply a partial function to the elements of a list, keeping the ones at which
302+||| it is defined.
228303mapMaybe : (a -> Maybe b) -> List a -> List b
229304mapMaybe f [] = []
230305mapMaybe f (x::xs) =
@@ -236,6 +311,7 @@ mapMaybe f (x::xs) =
236311-- Folds
237312--------------------------------------------------------------------------------
238313
314+||| A tail recursive right fold on Lists.
239315total foldrImpl : (t -> acc -> acc) -> acc -> (acc -> acc) -> List t -> acc
240316foldrImpl f e go [] = go e
241317foldrImpl f e go (x::xs) = foldrImpl f e (go . (f x)) xs
@@ -247,6 +323,7 @@ instance Foldable List where
247323-- Special folds
248324--------------------------------------------------------------------------------
249325
326+||| Convert any Foldable structure to a list.
250327toList : Foldable t => t a -> List a
251328toList = foldr (::) []
252329
@@ -254,6 +331,7 @@ toList = foldr (::) []
254331-- Transformations
255332--------------------------------------------------------------------------------
256333
334+||| Return the elements of a list in reverse order.
257335reverse : List a -> List a
258336reverse = reverse' []
259337 where
@@ -261,6 +339,7 @@ reverse = reverse' []
261339 reverse' acc [] = acc
262340 reverse' acc (x::xs) = reverse' (x::acc) xs
263341
342+||| Insert some separator between the elements of a list.
264343intersperse : a -> List a -> List a
265344intersperse sep [] = []
266345intersperse sep (x::xs) = x :: intersperse' sep xs
@@ -274,13 +353,13 @@ intercalate sep l = concat $ intersperse sep l
274353
275354||| Transposes rows and columns of a list of lists.
276355|||
277−||| > transpose [[1, 2], [3, 4]] = [[1, 3], [2, 4]]
356+||| > transpose [[1, 2], [3, 4]] = [[1, 3], [2, 4]]
278357|||
279358||| This also works for non square scenarios, thus
280359||| involution does not always hold:
281360|||
282−||| > transpose [[], [1, 2]] = [[1], [2]]
283−||| > transpose (transpose [[], [1, 2]]) = [[1, 2]]
361+||| > transpose [[], [1, 2]] = [[1], [2]]
362+||| > transpose (transpose [[], [1, 2]]) = [[1, 2]]
284363|||
285364||| TODO: Solution which satisfies the totality checker?
286365%assert_total
@@ -293,6 +372,7 @@ transpose ((x::xs) :: xss) = (x :: (mapMaybe head' xss)) :: (transpose (xs :: (m
293372-- Membership tests
294373--------------------------------------------------------------------------------
295374
375+||| Check if something is a member of a list using a custom comparison.
296376elemBy : (a -> a -> Bool) -> a -> List a -> Bool
297377elemBy p e [] = False
298378elemBy p e (x::xs) =
@@ -301,9 +381,11 @@ elemBy p e (x::xs) =
301381 else
302382 elemBy p e xs
303383
384+||| Check if something is a member of a list using the default Boolean equality.
304385elem : Eq a => a -> List a -> Bool
305386elem = elemBy (==)
306387
388+||| Find associated information in a list using a custom comparison.
307389lookupBy : (a -> a -> Bool) -> a -> List (a, b) -> Maybe b
308390lookupBy p e [] = Nothing
309391lookupBy p e (x::xs) =
@@ -313,9 +395,12 @@ lookupBy p e (x::xs) =
313395 else
314396 lookupBy p e xs
315397
398+||| Find associated information in a list using Boolean equality.
316399lookup : Eq a => a -> List (a, b) -> Maybe b
317400lookup = lookupBy (==)
318401
402+||| Check if any elements of the first list are found in the second, using
403+||| a custom comparison.
319404hasAnyBy : (a -> a -> Bool) -> List a -> List a -> Bool
320405hasAnyBy p elems [] = False
321406hasAnyBy p elems (x::xs) =
@@ -324,6 +409,8 @@ hasAnyBy p elems (x::xs) =
324409 else
325410 hasAnyBy p elems xs
326411
412+||| Check if any elements of the first list are found in the second, using
413+||| Boolean equality.
327414hasAny : Eq a => List a -> List a -> Bool
328415hasAny = hasAnyBy (==)
329416
@@ -331,6 +418,7 @@ hasAny = hasAnyBy (==)
331418-- Searching with a predicate
332419--------------------------------------------------------------------------------
333420
421+||| Find the first element of a list that satisfies a predicate, or `Nothing` if none do.
334422find : (a -> Bool) -> List a -> Maybe a
335423find p [] = Nothing
336424find p (x::xs) =
@@ -339,6 +427,8 @@ find p (x::xs) =
339427 else
340428 find p xs
341429
430+||| Find the index of the first element of a list that satisfies a predicate, or
431+||| `Nothing` if none do.
342432findIndex : (a -> Bool) -> List a -> Maybe Nat
343433findIndex = findIndex' Z
344434 where
@@ -350,6 +440,7 @@ findIndex = findIndex' Z
350440 else
351441 findIndex' (S cnt) p xs
352442
443+||| Find the indices of all elements that satisfy some predicate.
353444findIndices : (a -> Bool) -> List a -> List Nat
354445findIndices = findIndices' Z
355446 where
@@ -399,10 +490,28 @@ nubBy = nubBy' []
399490nub : Eq a => List a -> List a
400491nub = nubBy (==)
401492
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+
402509--------------------------------------------------------------------------------
403510-- Splitting and breaking lists
404511--------------------------------------------------------------------------------
405512
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.
406515span : (a -> Bool) -> List a -> (List a, List a)
407516span p [] = ([], [])
408517span p (x::xs) =
@@ -416,7 +525,6 @@ break : (a -> Bool) -> List a -> (List a, List a)
416525break p = span (not . p)
417526
418527split : (a -> Bool) -> List a -> List (List a)
419−split p [] = []
420528split p xs =
421529 case break p xs of
422530 (chunk, []) => [chunk]
@@ -439,6 +547,16 @@ partition p (x::xs) =
439547 else
440548 (lefts, x::rights)
441549
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+
442560--------------------------------------------------------------------------------
443561-- Predicates
444562--------------------------------------------------------------------------------
@@ -501,6 +619,7 @@ sort xs = let (x, y) = split xs in
501619-- Conversions
502620--------------------------------------------------------------------------------
503621
622+||| Either return the head of a list, or `Nothing` if it is empty.
504623listToMaybe : List a -> Maybe a
505624listToMaybe [] = Nothing
506625listToMaybe (x::xs) = Just x
@@ -520,7 +639,7 @@ catMaybes (x::xs) =
520639-- Properties
521640--------------------------------------------------------------------------------
522641
523−-- append
642+||| The empty list is a right identity for append.
524643appendNilRightNeutral : (l : List a) ->
525644 l ++ [] = l
526645appendNilRightNeutral [] = refl
@@ -528,6 +647,7 @@ appendNilRightNeutral (x::xs) =
528647 let inductiveHypothesis = appendNilRightNeutral xs in
529648 ?appendNilRightNeutralStepCase
530649
650+||| Appending lists is associative.
531651appendAssociative : (l : List a) -> (c : List a) -> (r : List a) ->
532652 l ++ (c ++ r) = (l ++ c) ++ r
533653appendAssociative [] c r = refl
@@ -535,7 +655,8 @@ appendAssociative (x::xs) c r =
535655 let inductiveHypothesis = appendAssociative xs c r in
536656 ?appendAssociativeStepCase
537657
538−-- length
658+||| The length of two lists that are appended is the sum of the lengths
659+||| of the input lists.
539660lengthAppend : (left : List a) -> (right : List a) ->
540661 length (left ++ right) = length left + length right
541662lengthAppend [] right = refl
@@ -543,7 +664,7 @@ lengthAppend (x::xs) right =
543664 let inductiveHypothesis = lengthAppend xs right in
544665 ?lengthAppendStepCase
545666
546−-- map
667+||| Mapping a function over a list doesn't change its length.
547668mapPreservesLength : (f : a -> b) -> (l : List a) ->
548669 length (map f l) = length l
549670mapPreservesLength f [] = refl
@@ -551,6 +672,8 @@ mapPreservesLength f (x::xs) =
551672 let inductiveHypothesis = mapPreservesLength f xs in
552673 ?mapPreservesLengthStepCase
553674
675+||| Mapping a function over two lists and appending them is equivalent
676+||| to appending them and then mapping the function.
554677mapDistributesOverAppend : (f : a -> b) -> (l : List a) -> (r : List a) ->
555678 map f (l ++ r) = map f l ++ map f r
556679mapDistributesOverAppend f [] r = refl
@@ -558,6 +681,7 @@ mapDistributesOverAppend f (x::xs) r =
558681 let inductiveHypothesis = mapDistributesOverAppend f xs r in
559682 ?mapDistributesOverAppendStepCase
560683
684+||| Mapping two functions is the same as mapping their composition.
561685mapFusion : (f : b -> c) -> (g : a -> b) -> (l : List a) ->
562686 map f (map g l) = map (f . g) l
563687mapFusion f g [] = refl
@@ -565,7 +689,7 @@ mapFusion f g (x::xs) =
565689 let inductiveHypothesis = mapFusion f g xs in
566690 ?mapFusionStepCase
567691
568−-- hasAny
692+||| No list contains an element of the empty list by any predicate.
569693hasAnyByNilFalse : (p : a -> a -> Bool) -> (l : List a) ->
570694 hasAnyBy p [] l = False
571695hasAnyByNilFalse p [] = refl
@@ -573,6 +697,7 @@ hasAnyByNilFalse p (x::xs) =
573697 let inductiveHypothesis = hasAnyByNilFalse p xs in
574698 ?hasAnyByNilFalseStepCase
575699
700+||| No list contains an element of the empty list.
576701hasAnyNilFalse : Eq a => (l : List a) -> hasAny [] l = False
577702hasAnyNilFalse l = ?hasAnyNilFalseBody
578703
libs/prelude/Prelude/Maybe.idr+10−3
@@ -28,25 +28,32 @@ isJust (Just j) = True
2828-- Misc
2929--------------------------------------------------------------------------------
3030
31−maybe : Lazy b -> (a -> b) -> Maybe a -> b
31+maybe : Lazy b -> Lazy (a -> b) -> Maybe a -> b
3232maybe n j Nothing = n
33−maybe n j (Just x) = j x
33+maybe n j (Just x) = (Force j) x
3434
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`.
3537fromMaybe : (Lazy a) -> Maybe a -> a
3638fromMaybe def Nothing = def
3739fromMaybe def (Just j) = j
3840
39−toMaybe : Bool -> a -> Maybe a
41+||| Returns `Just` the given value if the conditional is `True`
42+||| and `Nothing` if the conditional is `False`.
43+toMaybe : Bool -> Lazy a -> Maybe a
4044toMaybe True j = Just j
4145toMaybe False j = Nothing
4246
4347justInjective : {x : t} -> {y : t} -> (Just x = Just y) -> x = y
4448justInjective refl = refl
4549
50+||| Convert a `Maybe a` value to an `a` value, using `neutral` in the case
51+||| that the `Maybe` value is `Nothing`.
4652lowerMaybe : Monoid a => Maybe a -> a
4753lowerMaybe Nothing = neutral
4854lowerMaybe (Just x) = x
4955
56+||| Returns `Nothing` when applied to `neutral`, and `Just` the value otherwise.
5057raiseToMaybe : (Monoid a, Eq a) => a -> Maybe a
5158raiseToMaybe x = if x == neutral then Nothing else Just x
5259
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
3131take Z _ = []
3232take (S n) (x :: xs) = x :: (take n xs)
3333
34+||| Drop the first n elements from the stream
35+||| @ n how many elements to drop
3436%assert_total
35−drop : Nat -> Stream a -> Stream a
37+drop : (n : Nat) -> Stream a -> Stream a
3638drop Z xs = xs
3739drop (S k) (x::xs) = drop k xs
3840
@@ -67,4 +69,31 @@ unzip xs = (map fst xs, map snd xs)
6769diag : Stream (Stream a) -> Stream a
6870diag ((x::xs)::xss) = x :: diag (map tail xss)
6971
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
7099
libs/prelude/Prelude/Strings.idr+111−1
@@ -8,29 +8,59 @@ import Prelude.Either
88import Prelude.Foldable
99
1010||| Appends two strings together.
11+|||
12+||| Idris> "AB" ++ "C"
13+||| "ABC" : String
1114(++) : String -> String -> String
1215(++) = prim__concat
1316
1417||| Returns the first character in the specified string.
18+|||
19+||| Doesn't work for empty strings.
20+|||
21+||| Idris> strHead "A"
22+||| 'A' : Char
1523partial
1624strHead : String -> Char
1725strHead = prim__strHead
1826
1927||| 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
2035partial
2136strTail : String -> String
2237strTail = prim__strTail
2338
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
2545strCons : Char -> String -> String
2646strCons = prim__strCons
2747
2848||| 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
2954partial
3055strIndex : String -> Int -> Char
3156strIndex = prim__strIndex
3257
3358||| Reverses the elements within a String.
59+|||
60+||| Idris> reverse "ABC"
61+||| "CBA" : String
62+||| Idris> reverse ""
63+||| "" : String
3464reverse : String -> String
3565reverse = prim__strRev
3666
@@ -43,9 +73,11 @@ data StrM : String -> Type where
4373 StrNil : StrM ""
4474 StrCons : (x : Char) -> (xs : String) -> StrM (strCons x xs)
4575
76+||| Version of 'strHead' that statically verifies that the string is not empty.
4677strHead' : (x : String) -> so (not (x == "")) -> Char
4778strHead' x p = assert_total $ prim__strHead x
4879
80+||| Version of 'strTail' that statically verifies that the string is not empty.
4981strTail' : (x : String) -> so (not (x == "")) -> String
5082strTail' x p = assert_total $ prim__strTail x
5183
@@ -61,14 +93,23 @@ strM x with (choose (not (x == "")))
6193-- a recursive argument, therefore the termination checker doesn't believe
6294-- the string is guaranteed smaller. It makes a good point.
6395
96+||| Turns a string into a list of characters.
97+|||
98+||| Idris> unpack "ABC"
99+||| ['A', 'B', 'C'] : List Char
64100unpack : String -> List Char
65101unpack s with (strM s)
66102 unpack "" | StrNil = []
67103 unpack (strCons x xs) | (StrCons x xs) = x :: assert_total (unpack xs)
68104
105+||| Turns a Foldable of characters into a string.
69106pack : (Foldable t) => t Char -> String
70107pack = foldr strCons ""
71108
109+||| Creates a string of a single character.
110+|||
111+||| Idris> singleton 'A'
112+||| "A" : String
72113singleton : Char -> String
73114singleton c = strCons c ""
74115
@@ -87,6 +128,13 @@ instance Semigroup String where
87128instance Monoid String where
88129 neutral = ""
89130
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)
90138span : (Char -> Bool) -> String -> (String, String)
91139span p xs with (strM xs)
92140 span p "" | StrNil = ("", "")
@@ -95,36 +143,76 @@ span p xs with (strM xs)
95143 | (ys, zs) = (strCons x ys, zs)
96144 | False = ("", strCons x xs)
97145
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)
98153break : (Char -> Bool) -> String -> (String, String)
99154break p = span (not . p)
100155
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
101161split : (Char -> Bool) -> String -> List String
102162split p xs = map pack (split p (unpack xs))
103163
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
104171ltrim : String -> String
105172ltrim xs with (strM xs)
106173 ltrim "" | StrNil = ""
107174 ltrim (strCons x xs) | StrCons _ _
108175 = if (isSpace x) then assert_total (ltrim xs) else (strCons x xs)
109176
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
110182trim : String -> String
111183trim xs = ltrim (reverse (ltrim (reverse xs)))
112184
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)
113189words' : List Char -> List (List Char)
114190words' s = case dropWhile isSpace s of
115191 [] => []
116192 s' => let (w, s'') = break isSpace s'
117193 in w :: words' (assert_smaller s s'')
118194
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
119199words : String -> List String
120200words s = map pack $ words' $ unpack s
121201
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)
122206lines' : List Char -> List (List Char)
123207lines' s = case dropWhile isNL s of
124208 [] => []
125209 s' => let (w, s'') = break isNL s'
126210 in w :: lines' (assert_smaller s s'')
127211
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
128216lines : String -> List String
129217lines s = map pack $ lines' $ unpack s
130218
@@ -133,6 +221,10 @@ foldr1 : (a -> a -> a) -> List a -> a
133221foldr1 f [x] = x
134222foldr1 f (x::xs) = f x (foldr1 f xs)
135223
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
136228unwords' : List (List Char) -> List Char
137229unwords' [] = []
138230unwords' ws = assert_total (foldr1 addSpace ws)
@@ -140,18 +232,36 @@ unwords' ws = assert_total (foldr1 addSpace ws)
140232 addSpace : List Char -> List Char -> List Char
141233 addSpace w s = w ++ (' ' :: s)
142234
235+||| Joins the strings by spaces into a single string.
236+|||
237+||| Idris> unwords ["A", "BC", "D", "E"]
238+||| "A BC D E" : String
143239unwords : List String -> String
144240unwords = pack . unwords' . map unpack
145241
242+||| Returns the length of the string.
243+|||
244+||| Idris> length ""
245+||| 0 : Nat
246+||| Idris> length "ABC"
247+||| 3 : Nat
146248length : String -> Nat
147249length = fromInteger . prim__zextInt_BigInt . prim_lenString
148250
251+||| Lowercases all characters in the string.
252+|||
253+||| Idris> toLower "aBc12!"
254+||| "abc12!" : String
149255toLower : String -> String
150256toLower x with (strM x)
151257 strToLower "" | StrNil = ""
152258 strToLower (strCons c cs) | (StrCons c cs) =
153259 strCons (toLower c) (toLower (assert_smaller (strCons c cs) cs))
154260
261+||| Uppercases all characters in the string.
262+|||
263+||| Idris> toLower "aBc12!"
264+||| "ABC12!" : String
155265toUpper : String -> String
156266toUpper x with (strM x)
157267 strToLower "" | StrNil = ""
libs/prelude/Prelude/Uninhabited.idr+3
@@ -8,6 +8,9 @@ class Uninhabited t where
88 ||| @ t the uninhabited type
99 total uninhabited : t -> _|_
1010
11+instance Uninhabited _|_ where
12+ uninhabited a = a
13+
1114||| Use an absurd assumption to discharge a proof obligation
1215||| @ t some empty type
1316||| @ a the goal type
libs/prelude/Prelude/Vect.idr+43
@@ -68,6 +68,12 @@ index fZ (x::xs) = x
6868index (fS k) (x::xs) = index k xs
6969index fZ [] impossible
7070
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+
7177||| Construct a new vector consisting of all but the indicated element
7278deleteAt : Fin (S n) -> Vect (S n) a -> Vect n a
7379deleteAt fZ (x::xs) = xs
@@ -254,6 +260,18 @@ concat : Vect m (Vect n a) -> Vect (m * n) a
254260concat [] = []
255261concat (v::vs) = v ++ concat vs
256262
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+
257275--------------------------------------------------------------------------------
258276-- Membership tests
259277--------------------------------------------------------------------------------
@@ -439,6 +457,31 @@ range : Vect n (Fin n)
439457range {n=Z} = []
440458range {n=S _} = fZ :: map fS range
441459
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+
442485--------------------------------------------------------------------------------
443486-- Proofs
444487--------------------------------------------------------------------------------
libs/prelude/prelude.ipkg+1−1
@@ -8,7 +8,7 @@ modules = Builtins, Prelude, IO,
88 Prelude.Maybe, Prelude.Monad, Prelude.Applicative, Prelude.Either,
99 Prelude.Vect, Prelude.Strings, Prelude.Chars, Prelude.Functor,
1010 Prelude.Foldable, Prelude.Traversable, Prelude.Bits, Prelude.Stream,
11− Prelude.Uninhabited,
11+ Prelude.Uninhabited, Prelude.Pairs,
1212
1313 Decidable.Equality
1414
main/Main.hs+10−61
@@ -24,6 +24,7 @@ import Idris.ElabDecls
2424import Idris.Primitives
2525import Idris.Imports
2626import Idris.Error
27+import Idris.CmdOptions
2728
2829import IRTS.System ( getLibFlags, getIdrisLibDir, getIncFlags )
2930
@@ -36,8 +37,7 @@ import Paths_idris
3637-- Main program reads command line options, parses the main program, and gets
3738-- on with the REPL.
3839
39−main = do xs <- getArgs
40− let opts = parseArgs xs
40+main = do opts <- runArgParser
4141 result <- runErrorT $ execStateT (runIdris opts) idrisInit
4242 case result of
4343 Left err -> putStrLn $ "Uncaught error: " ++ show err
@@ -48,8 +48,6 @@ runIdris [Client c] = do setVerbose False
4848 setQuiet True
4949 runIO $ runClient c
5050runIdris opts = do
51− when (Ver `elem` opts) $ runIO showver
52− when (Usage `elem` opts) $ runIO usage
5351 when (ShowIncs `elem` opts) $ runIO showIncs
5452 when (ShowLibs `elem` opts) $ runIO showLibs
5553 when (ShowLibdir `elem` opts) $ runIO showLibdir
@@ -61,6 +59,14 @@ runIdris opts = do
6159 [] -> return ()
6260 fs -> do runIO $ mapM_ cleanPkg fs
6361 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
6470 case opt getPkg opts of
6571 [] -> case opt getPkgREPL opts of
6672 [] -> idrisMain opts
@@ -68,9 +74,6 @@ runIdris opts = do
6874 _ -> ifail "Too many packages"
6975 fs -> runIO $ mapM_ (buildPkg (WarnOnly `elem` opts)) fs
7076
71−usage = do putStrLn usagemsg
72− exitWith ExitSuccess
73−
7477showver = do putStrLn $ "Idris version " ++ ver
7578 exitWith ExitSuccess
7679
@@ -85,57 +88,3 @@ showLibdir = do dir <- getIdrisLibDir
8588showIncs = do incFlags <- getIncFlags
8689 putStrLn incFlags
8790 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
33OBJS = idris_rts.o idris_heap.o idris_gc.o idris_gmp.o idris_bitstring.o \
44 idris_opts.o idris_stats.o mini-gmp.o
55HDRS = 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
77CFLAGS:=-fPIC $(CFLAGS)
8−CFLAGS += $(GMP_INCLUDE_DIR) $(GMP)
8+CFLAGS += $(GMP_INCLUDE_DIR) $(GMP) -DIDRIS_TARGET_OS="\"$(OS)\""
9+CFLAGS += -DIDRIS_TARGET_TRIPLE="\"$(MACHINE)\""
910
1011ifeq ($(OS), windows)
1112 OBJS += windows/idris_stdfgn.o windows/idris_net.o
12− HDRS += windows/idris_stdfgn.h windows/idris_net.h
1313else
1414 OBJS += idris_stdfgn.o idris_net.o
15− HDRS += idris_stdfgn.h idris_net.h
1615endif
1716
1817LIBTARGET = libidris_rts.a
rts/idris_net.c+11−1
@@ -1,9 +1,19 @@
11// C-Side of the Idris network library
22// (C) Simon Fowler, 2014
33// 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>
513#include <arpa/inet.h>
614
15+#include "idris_net.h"
16+
717void* idrnet_malloc(int size) {
818 return malloc(size);
919}
rts/idris_net.h−10
@@ -1,16 +1,6 @@
11#ifndef IDRISNET_H
22#define IDRISNET_H
33
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−
144typedef struct idrnet_recv_result {
155 int result;
166 void* payload;
rts/idris_rts.c+13
@@ -506,6 +506,19 @@ VAL idris_strRev(VM* vm, VAL str) {
506506 return cl;
507507}
508508
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+
509522VAL MKBUFFERc(VM* vm, Buffer* buf) {
510523 Closure* cl = allocate(vm, sizeof(Closure) + sizeof *buf + buf->cap, 1);
511524 SETTY(cl, BUFFER);
rts/idris_rts.h+6
@@ -279,6 +279,12 @@ VAL idris_peekB64Native(VM* vm, VAL buf, VAL off);
279279VAL idris_peekB64LE(VM* vm, VAL buf, VAL off);
280280VAL idris_peekB64BE(VM* vm, VAL buf, VAL off);
281281
282+// system infox
283+// used indices:
284+// 0 returns backend
285+// 1 returns OS
286+VAL idris_systemInfo(VM* vm, VAL index);
287+
282288// Command line args
283289
284290extern int __idris_argc;
rts/windows/idris_net.c+15−4
@@ -1,7 +1,7 @@
11// C-Side of the Idris network library
22// (C) Simon Fowler, 2014
33// MIT Licensed. Have fun!
4−#include "idris_net.h"
4+#include "../idris_net.h"
55
66#include <errno.h>
77#include <stdbool.h>
@@ -11,6 +11,12 @@
1111#include <Winsock2.h>
1212#include <Ws2tcpip.h>
1313
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+
1420static int socket_inited = 0;
1521static WSADATA wsa_data;
1622
@@ -22,12 +28,17 @@ void idrnet_free(void* ptr) {
2228 free(ptr);
2329}
2430
25−static int check_init()
31+static void clean_sockets(void) {
32+ WSACleanup();
33+}
34+
35+static int check_init(void)
2636{
2737 if (!socket_inited) {
2838 int result = WSAStartup(MAKEWORD(2, 2), &wsa_data);
2939 if (result == NO_ERROR) {
3040 socket_inited = 1;
41+ atexit(clean_sockets);
3142 }
3243 }
3344 return socket_inited;
@@ -104,7 +115,7 @@ int idrnet_sockaddr_family(void* sockaddr) {
104115char* idrnet_sockaddr_ipv4(void* sockaddr) {
105116 struct sockaddr_in* addr = (struct sockaddr_in*) sockaddr;
106117 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);
108119 return ip_addr;
109120}
110121
@@ -139,7 +150,7 @@ int idrnet_send_buf(int sockfd, void* data, int len) {
139150
140151void* idrnet_recv(int sockfd, int len) {
141152 if (!check_init()) {
142− return -1;
153+ return NULL;
143154 }
144155 idrnet_recv_result* res_struct =
145156 (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"
22#include "../idris_rts.h"
3+#include "../idris_gc.h"
4+
35#include <fcntl.h>
46#include <stdio.h>
7+#include <time.h>
58
69extern char** environ;
710
@@ -61,3 +64,12 @@ void* idris_stdin() {
6164char* getEnvPair(int i) {
6265 return *(environ + i);
6366}
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
6262 hPutStr tmph cout
6363 hFlush tmph
6464 hClose tmph
65− let useclang = False
6665 comp <- getCC
6766 libFlags <- getLibFlags
6867 incFlags <- getIncFlags
@@ -175,15 +174,15 @@ bcc i (CASE True r code def)
175174 | length code < 4 = showCase i def code
176175 where
177176 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 ++
179178 indent i ++ "}\n"
180179
181180 showCase :: Int -> Maybe [BC] -> [(Int, [BC])] -> String
182181 showCase i Nothing [(t, c)] = showCode i c
183182 showCase i (Just def) [] = showCode i def
184183 showCase i def ((t, c) : cs)
185− = "if (CTAG(" ++ creg r ++ ") == " ++ show t ++ ") " ++ showCode i c
186− ++ "else " ++ showCase i def cs
184+ = indent i ++ "if (CTAG(" ++ creg r ++ ") == " ++ show t ++ ") " ++ showCode i c
185+ ++ indent i ++ "else " ++ showCase i def cs
187186
188187bcc i (CASE safe r code def)
189188 = indent i ++ "switch(" ++ ctag safe ++ "(" ++ creg r ++ ")) {\n" ++
@@ -494,6 +493,8 @@ doOp v (LChInt ITNative) args = v ++ creg (last args)
494493doOp v (LChInt ITChar) args = doOp v (LChInt ITNative) args
495494doOp v (LIntCh ITNative) args = v ++ creg (last args)
496495doOp v (LIntCh ITChar) args = doOp v (LIntCh ITNative) args
496+
497+doOp v LSystemInfo [x] = v ++ "idris_systemInfo(vm, " ++ creg x ++ ")"
497498doOp v LNoOp args = v ++ creg (last args)
498499doOp _ op _ = "FAIL /* " ++ show op ++ " */"
499500
src/IRTS/CodegenJavaScript.hs+598−42
@@ -17,6 +17,7 @@ import Data.Char
1717import Numeric
1818import Data.List
1919import Data.Maybe
20+import Data.Word
2021import System.IO
2122import System.Directory
2223
@@ -53,6 +54,13 @@ data JSNum = JSInt Int
5354 deriving Eq
5455
5556
57+data JSWord = JSWord8 Word8
58+ | JSWord16 Word16
59+ | JSWord32 Word32
60+ | JSWord64 Word64
61+ deriving Eq
62+
63+
5664data JSAnnotation = JSConstructor deriving Eq
5765
5866
@@ -81,6 +89,7 @@ data JS = JSRaw String
8189 | JSArray [JS]
8290 | JSString String
8391 | JSNum JSNum
92+ | JSWord JSWord
8493 | JSAssign JS JS
8594 | JSAlloc String (Maybe JS)
8695 | JSIndex JS JS
@@ -257,6 +266,13 @@ compileJS (JSWhile cond body) =
257266 ++ compileJS body
258267 ++ "\n}"
259268
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+
260276jsTailcall :: JS -> JS
261277jsTailcall call =
262278 jsCall (idrRTNamespace ++ "tailcall") [
@@ -280,6 +296,8 @@ jsInstanceOf = JSBinOp "instanceof"
280296jsEq :: JS -> JS -> JS
281297jsEq = JSBinOp "=="
282298
299+jsNotEq :: JS -> JS -> JS
300+jsNotEq = JSBinOp "!="
283301
284302jsAnd :: JS -> JS -> JS
285303jsAnd = JSBinOp "&&"
@@ -327,6 +345,28 @@ jsLet name value body =
327345jsError :: String -> JS
328346jsError err = JSApp (JSFunction [] (JSError err)) []
329347
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+
330370
331371foldJS :: (JS -> a) -> (a -> a -> a) -> a -> JS -> a
332372foldJS tr add acc js =
@@ -702,21 +742,44 @@ removeIDs js =
702742 JSReturn (JSApp (JSIdent fun) args)
703743 )])
704744 | Just pos <- lookup fun ids
705− , pos < length args = args !! pos
745+ , pos < length args = removeIDCall ids (args !! pos)
706746
707747 removeIDCall ids (JSNew _ [JSFunction [] (
708748 JSReturn (JSApp (JSIdent fun) args)
709749 )])
710750 | Just pos <- lookup fun ids
711− , pos < length args = args !! pos
751+ , pos < length args = removeIDCall ids (args !! pos)
712752
713753 removeIDCall ids js@(JSApp id@(JSIdent fun) args)
714754 | Just pos <- lookup fun ids
715− , pos < length args = args !! pos
755+ , pos < length args = removeIDCall ids (args !! pos)
716756
717757 removeIDCall ids js = transformJS (removeIDCall ids) js
718758
719759
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+
720783inlineFunctions :: [JS] -> [JS]
721784inlineFunctions js =
722785 inlineHelper ([], js)
@@ -728,7 +791,7 @@ inlineFunctions js =
728791 | Just new <- inlineAble (
729792 countAll fun front + countAll fun back
730793 ) fun args body =
731− let f = map (inline fun args new) in
794+ let f = map (inlineFunction fun args new) in
732795 inlineHelper (f front, f back)
733796
734797 inlineHelper (front, next:back) = inlineHelper (front ++ [next], back)
@@ -745,29 +808,6 @@ inlineFunctions js =
745808 inlineAble _ _ _ _ = Nothing
746809
747810
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−
771811 nonRecur :: String -> JS -> Bool
772812 nonRecur name body = countInvokations name body == 0
773813
@@ -1378,6 +1418,67 @@ evalCons js =
13781418 match js = transformJS match js
13791419
13801420
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+
13811482getGlobalCons :: JS -> [(String, JS)]
13821483getGlobalCons js = foldJS match (++) [] js
13831484 where
@@ -1441,6 +1542,7 @@ codegenJS_all target definitions includes filename outputType = do
14411542
14421543 match :: JS -> Bool
14431544 match (JSIdent "__IDRRT__bigInt") = True
1545+ match (JSWord (JSWord64 _)) = True
14441546 match (JSNum (JSInteger _)) = True
14451547 match js = False
14461548
@@ -1478,6 +1580,8 @@ codegenJS_all target definitions includes filename outputType = do
14781580 , extractLocalConstructors
14791581 , unfoldLookupTable
14801582 , evalCons
1583+ , elimConds
1584+ , removeUselessCons
14811585 ]
14821586
14831587 functions :: [String]
@@ -1499,23 +1603,36 @@ codegenJS_all target definitions includes filename outputType = do
14991603
15001604 mainLoop :: JS
15011605 mainLoop =
1502− JSAlloc "main" $ Just $ JSFunction [] (
1503− case target of
1504− Node -> mainFun
1505− JavaScript -> JSCond [(isReady, mainFun), (JSTrue, jsMeth (JSIdent "window") "addEventListener" [
1506− JSString "DOMContentLoaded", JSFunction [] (
1507− mainFun
1508− ), JSFalse
1509− ])]
1606+ JSAlloc "main" $ Just $ JSFunction [] (
1607+ case target of
1608+ Node -> mainFun
1609+ JavaScript -> JSCond [ (exists document `jsAnd` isReady, mainFun)
1610+ , (exists window, windowMainFun)
1611+ , (JSTrue, mainFun)
1612+ ]
15101613 )
15111614 where
1615+ exists :: JS -> JS
1616+ exists js = (JSPreOp "typeof " js) `jsNotEq` JSString "undefined"
1617+
15121618 mainFun :: JS
15131619 mainFun = jsTailcall $ jsCall runMain []
15141620
1621+ window :: JS
1622+ window = JSIdent "window"
15151623
1516− isReady :: JS
1517− isReady = readyState `jsEq` JSString "complete" `jsOr` readyState `jsEq` JSString "loaded"
1624+ document :: JS
1625+ document = JSIdent "document"
15181626
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"
15191636
15201637 readyState :: JS
15211638 readyState = JSProj (JSIdent "document") "readyState"
@@ -1633,6 +1750,10 @@ translateConstant (AType (ATInt ITChar)) = JSType JSCharTy
16331750translateConstant PtrType = JSType JSPtrTy
16341751translateConstant Forgot = JSType JSForgotTy
16351752translateConstant (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)
16361757translateConstant c =
16371758 jsError $ "Unimplemented Constant: " ++ show c
16381759
@@ -1809,6 +1930,10 @@ translateExpression (SApp tc name vars)
18091930translateExpression (SOp op vars)
18101931 | LNoOp <- op = JSVar (last vars)
18111932
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+
18121937 | (LZExt _ ITBig) <- op = jsBigInt $ jsCall "String" [JSVar (last vars)]
18131938 | (LPlus (ATInt ITBig)) <- op
18141939 , (lhs:rhs:_) <- vars = invokeMeth lhs "add" [rhs]
@@ -1850,6 +1975,435 @@ translateExpression (SOp op vars)
18501975 | (LSGe ATFloat) <- op
18511976 , (lhs:rhs:_) <- vars = translateBinaryOp ">=" lhs rhs
18521977
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+
18532407 | (LPlus _) <- op
18542408 , (lhs:rhs:_) <- vars = translateBinaryOp "+" lhs rhs
18552409 | (LMinus _) <- op
@@ -1884,7 +2438,7 @@ translateExpression (SOp op vars)
18842438 , (arg:_) <- vars = JSPreOp "~" (JSVar arg)
18852439
18862440 | LStrConcat <- op
1887− , (lhs:rhs:_) <- vars = translateBinaryOp "+" lhs rhs
2441+ , (lhs:rhs:_) <- vars = invokeMeth lhs "concat" [rhs]
18882442 | LStrEq <- op
18892443 , (lhs:rhs:_) <- vars = translateBinaryOp "==" lhs rhs
18902444 | LStrLt <- op
@@ -1913,9 +2467,9 @@ translateExpression (SOp op vars)
19132467 | (LFloatInt ITNative) <- op
19142468 , (arg:_) <- vars = JSVar arg
19152469 | (LChInt ITNative) <- op
1916− , (arg:_) <- vars = JSProj (JSVar arg) "charCodeAt(0)"
2470+ , (arg:_) <- vars = jsCall "__IDRRT__charCode" [JSVar arg]
19172471 | (LIntCh ITNative) <- op
1918− , (arg:_) <- vars = jsCall "String.fromCharCode" [JSVar arg]
2472+ , (arg:_) <- vars = jsCall "__IDRRT__fromCharCode" [JSVar arg]
19192473
19202474 | LFExp <- op
19212475 , (arg:_) <- vars = jsCall "Math.exp" [JSVar arg]
@@ -1941,7 +2495,7 @@ translateExpression (SOp op vars)
19412495 , (arg:_) <- vars = jsCall "Math.ceil" [JSVar arg]
19422496
19432497 | LStrCons <- op
1944− , (lhs:rhs:_) <- vars = translateBinaryOp "+" lhs rhs
2498+ , (lhs:rhs:_) <- vars = invokeMeth lhs "concat" [rhs]
19452499 | LStrHead <- op
19462500 , (arg:_) <- vars = JSIndex (JSVar arg) (JSNum (JSInt 0))
19472501 | LStrRev <- op
@@ -1954,12 +2508,14 @@ translateExpression (SOp op vars)
19542508 JSNum (JSInt 1),
19552509 JSBinOp "-" (JSProj (JSIdent v) "length") (JSNum (JSInt 1))
19562510 ]
2511+ | LSystemInfo <- op
2512+ , (arg:_) <- vars = jsCall "__IDRRT__systemInfo" [JSVar arg]
19572513 | LNullPtr <- op
19582514 , (_) <- vars = JSNull
19592515
19602516 where
19612517 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)
19632519
19642520
19652521 invokeMeth :: LVar -> String -> [LVar] -> JS
src/IRTS/Compiler.hs+145−64
@@ -19,6 +19,7 @@ import IRTS.Inliner
1919
2020import Idris.AbsSyntax
2121import Idris.AbsSyntaxTree
22+import Idris.ASTUtils
2223import Idris.Erasure
2324import Idris.Error
2425
@@ -28,6 +29,9 @@ import Idris.Core.TT
2829import Idris.Core.Evaluate
2930import Idris.Core.CaseTree
3031
32+import Control.Category
33+import Prelude hiding (id, (.))
34+
3135import Control.Applicative
3236import Control.Monad.State
3337import Data.Maybe
@@ -48,6 +52,7 @@ import Paths_idris
4852compile :: Codegen -> FilePath -> Term -> Idris ()
4953compile codegen f tm
5054 = do checkMVs -- check for undefined metavariables
55+ checkTotality -- refuse to compile if there are totality problems
5156 reachableNames <- performUsageAnalysis
5257 maindef <- irMain tm
5358 iLOG $ "MAIN: " ++ show maindef
@@ -101,6 +106,10 @@ compile codegen f tm
101106 case map fst (idris_metavars i) \\ primDefs of
102107 [] -> return ()
103108 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
104113 inDir d h = do let f = d </> h
105114 ex <- doesFileExist f
106115 if ex then return f else return h
@@ -172,10 +181,7 @@ mkLDecl n (CaseOp ci _ _ _ pats cd)
172181 (args, sc) = cases_runtime cd
173182
174183mkLDecl n (TyDecl (DCon tag arity) _) =
175− LConstructor n tag . erasedArity . lookup n <$> getIState
176− where
177− lookup n = lookupCtxtExact n . idris_callgraph
178− erasedArity = maybe 0 (length . usedpos)
184+ LConstructor n tag . length <$> fgetState (cg_usedpos . ist_callgraph n)
179185
180186mkLDecl n (TyDecl (TCon t a) _) = return $ LConstructor n (-1) a
181187mkLDecl n _ = return $ (declArgs [] True n LNothing) -- postulate, never run
@@ -220,7 +226,7 @@ irTerm vs env tm@(App f a) = case unApply tm of
220226 | l == txt "Force"
221227 -> LForce <$> irTerm vs env arg
222228
223− (P _ (UN a) _, [_, _, arg])
229+ (P _ (UN a) _, [_, _, _, arg])
224230 | a == txt "assert_smaller"
225231 -> irTerm vs env arg
226232
@@ -248,8 +254,8 @@ irTerm vs env tm@(App f a) = case unApply tm of
248254
249255 -- This case is here until we get more general inlining. It's just
250256 -- a really common case, and the laziness hurts...
251− (P _ (NS (UN be) [b,p]) _, [_,x,(App (P _ (UN d) _) t),
252− (App (P _ (UN d') _) e)])
257+ (P _ (NS (UN be) [b,p]) _, [_,x,(App (App (App (P _ (UN d) _) _) _) t),
258+ (App (App (App (P _ (UN d') _) _) _) e)])
253259 | be == txt "boolElim"
254260 , d == txt "Delay"
255261 , d' == txt "Delay"
@@ -261,21 +267,67 @@ irTerm vs env tm@(App f a) = case unApply tm of
261267 ,LConCase 1 (sNS (sUN "True" ) ["Bool","Prelude"]) [] t'
262268 ])
263269
270+ -- data constructor
264271 (P (DCon t arity) n _, args) -> do
265− ist <- getIState
266− let detag = maybe False detaggable . lookupCtxtExact n $ idris_optimisation ist
267− used = maybe [] (map fst . usedpos) . lookupCtxtExact n $ idris_callgraph ist
268− args' = [a | (i,a) <- zip [0..] args, i `elem` used]
269−
270− when (length args > arity) $
271− ifail ("oversaturated data ctor: " ++ show tm)
272−
273− if length args' == 1 && detag -- detaggable
274− then irTerm vs env (head args') -- newtype
275− else irCon vs env (length used) n args'
276−
272+ detag <- fgetState (opt_detaggable . ist_optimisation n)
273+ used <- map fst <$> fgetState (cg_usedpos . ist_callgraph n)
274+
275+ let isNewtype = length used == 1 && detag
276+ let argsPruned = [a | (i,a) <- zip [0..] args, i `elem` used]
277+
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
305+ GT -> ifail ("overapplied data constructor: " ++ show tm)
306+
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
318+ <$> irTerm vs env (head argsPruned)
319+
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
277328 (P (TCon t a) n _, args) -> return LNothing
278329
330+ -- a name applied to arguments
279331 (P _ n _, args) -> do
280332 ist <- getIState
281333 case lookup n (idris_scprims ist) of
@@ -296,29 +348,44 @@ irTerm vs env tm@(App f a) = case unApply tm of
296348 <*> mapM (irTerm vs env) args
297349
298350 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+
299366 applyName :: Name -> IState -> [Term] -> Idris LExp
300367 applyName n ist args =
301368 LApp False (LV $ Glob n) <$> mapM (irTerm vs env . erase) (zip [0..] args)
302− where
303− erase (i, x)
304− | i >= arity || i `elem` used = x
305− | otherwise = Erased
306−
307− arity = case fst4 <$> lookupCtxtExact n (definitions . tt_ctxt $ ist) of
308− Just (CaseOp ci ty tys def tot cdefs) -> length tys
309− Just (TyDecl (DCon tag ar) _) -> ar
310− Just (TyDecl Ref ty) -> length $ getArgTys ty
311− Just (Operator ty ar op) -> ar
312− Just def -> error $ "unknown arity: " ++ show (n, def)
313− Nothing -> 0 -- no definition, probably local name => can't erase anything
314−
315− -- name for purposes of usage info lookup
316− uName
317− | Just n' <- viMethod =<< M.lookup n vs = n'
318− | otherwise = n
319−
320− used = maybe [] (map fst . usedpos) $ lookupCtxtExact uName (idris_callgraph ist)
321− fst4 (x,_,_,_) = x
369+ where
370+ erase (i, x)
371+ | i >= arity || i `elem` used = x
372+ | otherwise = Erased
373+
374+ arity = case fst4 <$> lookupCtxtExact n (definitions . tt_ctxt $ ist) of
375+ Just (CaseOp ci ty tys def tot cdefs) -> length tys
376+ Just (TyDecl (DCon tag ar) _) -> ar
377+ Just (TyDecl Ref ty) -> length $ getArgTys ty
378+ Just (Operator ty ar op) -> ar
379+ Just def -> error $ "unknown arity: " ++ show (n, def)
380+ Nothing -> 0 -- no definition, probably local name => can't erase anything
381+
382+ -- name for purposes of usage info lookup
383+ uName
384+ | Just n' <- viMethod =<< M.lookup n vs = n'
385+ | otherwise = n
386+
387+ used = maybe [] (map fst . usedpos) $ lookupCtxtExact uName (idris_callgraph ist)
388+ fst4 (x,_,_,_) = x
322389
323390irTerm vs env (P _ n _) = return $ LV (Glob n)
324391irTerm vs env (V i)
@@ -345,24 +412,6 @@ irTerm vs env (TType _) = return $ LNothing
345412irTerm vs env Erased = return $ LNothing
346413irTerm vs env Impossible = return $ LNothing
347414
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−
366415doForeign :: Vars -> [Name] -> [TT Name] -> Idris LExp
367416doForeign vs env (_ : fgn : args)
368417 | (_, (Constant (Str fgnName) : fgnArgTys : ret : [])) <- unApply fgn
@@ -470,11 +519,12 @@ irSC vs (Case n [ConCase (UN delay) i [_, _, n'] sc])
470519--
471520-- Hence, we check whether the variables are used at all
472521-- and erase the casesplit if they are not.
522+--
473523irSC vs (Case n [alt]) = do
474524 replacement <- case alt of
475525 ConCase cn a ns sc -> do
476− detag <- maybe False detaggable . lookupCtxtExact cn . idris_optimisation <$> getIState
477− used <- maybe [] (map fst . usedpos) . lookupCtxtExact cn . idris_callgraph <$> getIState
526+ detag <- fgetState (opt_detaggable . ist_optimisation cn)
527+ used <- map fst <$> fgetState (cg_usedpos . ist_callgraph cn)
478528 if detag && length used == 1
479529 then return . Just $ substSC (ns !! head used) n sc
480530 else return Nothing
@@ -498,20 +548,51 @@ irSC vs (Case n [alt]) = do
498548 subexpr (LConstCase _ e) = e
499549 subexpr (LDefaultCase e) = e
500550
501−irSC vs (Case n alts) = LCase (LV (Glob n)) <$> mapM (irAlt vs (LV (Glob n))) alts
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])
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+
502586irSC vs ImpossibleCase = return LNothing
503587
504588irAlt :: Vars -> LExp -> CaseAlt -> Idris LAlt
505589
506590-- this leaves out all unused arguments of the constructor
507591irAlt vs _ (ConCase n t args sc) = do
508− used <- getUsed . lookup n <$> getIState
592+ used <- map fst <$> fgetState (cg_usedpos . ist_callgraph n)
509593 let usedArgs = [a | (i,a) <- zip [0..] args, i `elem` used]
510594 LConCase (-1) n usedArgs <$> irSC (methodVars `M.union` vs) sc
511595 where
512− lookup n = lookupCtxtExact n . idris_callgraph
513− getUsed = maybe [] (map fst . usedpos)
514−
515596 methodVars = case n of
516597 SN (InstanceCtorN className)
517598 -> M.fromList [(v, VI
src/IRTS/Defunctionalise.hs+1−1
@@ -195,7 +195,7 @@ toCons ns (n, i)
195195 (DApp False n (map (DV . Glob) (take i (genArgs 0))))))))
196196 : [] -- mkApplyCase n 0 i
197197 | otherwise = []
198− where dupdate tlarg x = x
198+ where dupdate tlarg x = DUpdate tlarg x
199199
200200toConsA :: [(Name, Int)] -> (Name, Int) -> [(Name, Int, EvalApply DAlt)]
201201toConsA ns (n, i)
src/IRTS/Lang.hs+2
@@ -55,6 +55,8 @@ data PrimFn = LPlus ArithTy | LMinus ArithTy | LTimes ArithTy
5555 -- Buffers
5656 | LAllocate
5757 | LAppendBuffer
58+ -- system info
59+ | LSystemInfo
5860 -- Note that for Bits8 only Native endianness is actually used
5961 -- and the user-exposed interface for Bits8 doesn't mention
6062 -- endianness
src/IRTS/Simplified.hs+16−14
@@ -125,15 +125,17 @@ checkDefs ctxt (con@(n, DConstructor _ _ _) : xs)
125125 return xs'
126126checkDefs ctxt ((n, DFun n' args exp) : xs)
127127 = 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)
129129 xs' <- checkDefs ctxt xs
130130 return ((n, SFun n' args ((locs + 1) - length args) exp') : xs')
131131
132132lvar v = do i <- get
133133 put (max i v)
134134
135−scopecheck :: DDefs -> [(Name, Int)] -> SExp -> StateT Int TC SExp
136−scopecheck ctxt envTop tm = sc envTop tm where
135+scopecheck :: Name -> DDefs -> [(Name, Int)] -> SExp -> StateT Int TC SExp
136+scopecheck fn ctxt envTop tm = sc envTop tm where
137+ failsc err = fail $ "Codegen error in " ++ show fn ++ ":" ++ err
138+
137139 sc env (SV (Glob n)) =
138140 case lookup n (reverse env) of -- most recent first
139141 Just i -> do lvar i; return (SV (Loc i))
@@ -141,20 +143,20 @@ scopecheck ctxt envTop tm = sc envTop tm where
141143 Just (DConstructor _ i ar) ->
142144 if True -- ar == 0
143145 then return (SCon i n [])
144− else fail $ "Codegen error: Constructor " ++ show n ++
146+ else failsc $ "Constructor " ++ show n ++
145147 " has arity " ++ show ar
146148 Just _ -> return (SV (Glob n))
147− Nothing -> fail $ "Codegen error: No such variable " ++ show n
149+ Nothing -> failsc $ "No such variable " ++ show n
148150 sc env (SApp tc f args)
149151 = do args' <- mapM (scVar env) args
150152 case lookupCtxtExact f ctxt of
151153 Just (DConstructor n tag ar) ->
152154 if True -- (ar == length args)
153155 then return $ SCon tag n args'
154− else fail $ "Codegen error: Constructor " ++ show f ++
156+ else failsc $ "Constructor " ++ show f ++
155157 " has arity " ++ show ar
156158 Just _ -> return $ SApp tc f args'
157− Nothing -> fail $ "Codegen error: No such variable " ++ show f
159+ Nothing -> failsc $ "No such variable " ++ show f
158160 sc env (SForeign l ty f args)
159161 = do args' <- mapM (\ (t, a) -> do a' <- scVar env a
160162 return (t, a')) args
@@ -165,9 +167,9 @@ scopecheck ctxt envTop tm = sc envTop tm where
165167 Just (DConstructor n tag ar) ->
166168 if True -- (ar == length args)
167169 then return $ SCon tag n args'
168− else fail $ "Codegen error: Constructor " ++ show f ++
169− " has arity " ++ show ar
170− _ -> fail $ "Codegen error: No such constructor " ++ show f
170+ else failsc $ "Constructor " ++ show f ++
171+ " has arity " ++ show ar
172+ _ -> failsc $ "No such constructor " ++ show f
171173 sc env (SProj e i)
172174 = do e' <- scVar env e
173175 return (SProj e' i)
@@ -200,9 +202,9 @@ scopecheck ctxt envTop tm = sc envTop tm where
200202 Just i -> do lvar i; return (Loc i)
201203 Nothing -> case lookupCtxtExact n ctxt of
202204 Just (DConstructor _ i ar) ->
203− fail $ "Codegen error : can't pass constructor here"
205+ failsc $ "can't pass constructor here"
204206 Just _ -> return (Glob n)
205− Nothing -> fail $ "Codegen error: No such variable " ++ show n ++
207+ Nothing -> failsc $ "No such variable " ++ show n ++
206208 " in " ++ show tm ++ " " ++ show envTop
207209 scVar _ x = return x
208210
@@ -212,9 +214,9 @@ scopecheck ctxt envTop tm = sc envTop tm where
212214 Just (DConstructor _ i ar) ->
213215 if True -- (length args == ar)
214216 then return i
215− else fail $ "Codegen error: Constructor " ++ show n ++
217+ else failsc $ "Constructor " ++ show n ++
216218 " has arity " ++ show ar
217− _ -> fail $ "Codegen error: No constructor " ++ show n
219+ _ -> failsc $ "No constructor " ++ show n
218220 e' <- sc env' e
219221 return (SConCase (length env) tag n args e')
220222 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
278278 ty' <- case lookupCtxtName ty (idris_implicits i) of
279279 [(tyn, _)] -> return tyn
280280 [] -> throwError (NoSuchVariable ty)
281− tyns -> throwError (CantResolveAlts (map show (map fst tyns)))
281+ tyns -> throwError (CantResolveAlts (map fst tyns))
282282 let ns' = case lookupCtxt ty' (idris_namehints i) of
283283 [ns] -> ns ++ [n]
284284 _ -> [n]
@@ -530,7 +530,7 @@ renderWidth = do iw <- getWidth
530530
531531
532532type1Doc :: Doc OutputAnnotation
533−type1Doc = (annotate AnnConstType $ text "Type 1")
533+type1Doc = (annotate (AnnType "Type" "The type of types, one level up") $ text "Type 1")
534534
535535
536536isetPrompt :: String -> Idris ()
@@ -538,6 +538,18 @@ isetPrompt p = do i <- getIState
538538 case idris_outputmode i of
539539 IdeSlave n -> runIO . putStrLn $ convSExp "set-prompt" p n
540540
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+
541553setLogLevel :: Int -> Idris ()
542554setLogLevel l = do i <- getIState
543555 let opts = idris_options i
@@ -766,13 +778,14 @@ setColour :: ColourType -> IdrisColour -> Idris ()
766778setColour ct c = do i <- getIState
767779 let newTheme = setColour' ct c (idris_colourTheme i)
768780 putIState $ i { idris_colourTheme = newTheme }
769− where setColour' KeywordColour c t = t { keywordColour = c }
770− setColour' BoundVarColour c t = t { boundVarColour = c }
771− setColour' ImplicitColour c t = t { implicitColour = c }
772− setColour' FunctionColour c t = t { functionColour = c }
773− setColour' TypeColour c t = t { typeColour = c }
774− setColour' DataColour c t = t { dataColour = c }
775− setColour' PromptColour c t = t { promptColour = c }
781+ where setColour' KeywordColour c t = t { keywordColour = c }
782+ setColour' BoundVarColour c t = t { boundVarColour = c }
783+ setColour' ImplicitColour c t = t { implicitColour = c }
784+ setColour' FunctionColour c t = t { functionColour = c }
785+ setColour' TypeColour c t = t { typeColour = c }
786+ setColour' DataColour c t = t { dataColour = c }
787+ setColour' PromptColour c t = t { promptColour = c }
788+ setColour' PostulateColour c t = t { postulateColour = c }
776789
777790logLvl :: Int -> String -> Idris ()
778791logLvl l str = do i <- getIState
@@ -937,7 +950,7 @@ expandParamsD rhsonly ist dec ps ns (PClauses fc opts n cs)
937950 updateps yn nm [] = []
938951 updateps yn nm (((a, t), i):as)
939952 | (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
941954
942955 removeBound lhs ns = ns \\ nub (bnames lhs)
943956
@@ -947,6 +960,7 @@ expandParamsD rhsonly ist dec ps ns (PClauses fc opts n cs)
947960 bnames (PDPair _ _ l Placeholder r) = bnames l ++ bnames r
948961 bnames _ = []
949962
963+-- | Expands parameters defined in parameter and where blocks inside of declarations
950964expandParamsD rhs ist dec ps ns (PData doc argDocs syn fc co pd)
951965 = PData doc argDocs syn fc co (expandPData pd)
952966 where
@@ -959,12 +973,12 @@ expandParamsD rhs ist dec ps ns (PData doc argDocs syn fc co pd)
959973 else PDatadecl n (expandParams dec ps ns [] ty) (map econ cons)
960974 econ (doc, argDocs, n, t, fc, fs)
961975 = (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)
963977 = if tn `elem` ns
964978 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
966980 else PRecord doc syn fc (dec tn) (expandParams dec ps ns [] tty)
967− cdoc (dec cn) conty
981+ opts cdoc (dec cn) conty
968982 where conty = piBindp expl ps (expandParams dec ps ns [] cty)
969983expandParamsD rhs ist dec ps ns (PParams f params pds)
970984 = PParams f (ps ++ map (mapsnd (expandParams dec ps ns [])) params)
@@ -972,11 +986,12 @@ expandParamsD rhs ist dec ps ns (PParams f params pds)
972986-- (map (expandParamsD ist dec ps ns) pds)
973987expandParamsD rhs ist dec ps ns (PMutual f pds)
974988 = 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)
976990 = PClass doc info f
977991 (map (expandParams dec ps ns []) cs)
978992 n
979993 (map (mapsnd (expandParams dec ps ns [])) params)
994+ pDocs
980995 (map (expandParamsD rhs ist dec ps ns) decls)
981996expandParamsD rhs ist dec ps ns (PInstance info f cs n params ty cn decls)
982997 = PInstance info f
@@ -1315,9 +1330,11 @@ addImpl' inpat env infns ist ptm
13151330 as' = map (fmap (ai env ds)) as in
13161331 mkPApp fc 1 f' as'
13171332 ai env ds (PCase fc c os)
1318− = let c' = ai env ds c
1319− os' = map (pmap (ai env ds)) os in
1320− PCase fc c' os'
1333+ = let c' = ai env ds c 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
1337+ PCase fc c' os
13211338 ai env ds (PLam n ty sc)
13221339 = let ty' = ai env ds ty
13231340 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
3131import Data.Either
3232import qualified Data.Set as S
3333import Data.Word (Word)
34+import Data.Maybe (fromMaybe)
3435
3536import Debug.Trace
3637
@@ -94,6 +95,28 @@ defaultOpts = IOption { opt_logLevel = 0
9495 , opt_autoSolve = True
9596 }
9697
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+
97120data LanguageExt = TypeProviders | ErrorReflection deriving (Show, Eq, Read, Ord)
98121
99122-- | The output mode in use
@@ -124,8 +147,9 @@ data IState = IState {
124147 idris_calledgraph :: Ctxt [Name],
125148 idris_docstrings :: Ctxt (Docstring, [(Name, Docstring)]),
126149 idris_tyinfodata :: Ctxt TIData,
127− idris_totcheck :: [(FC, Name)], -- names to check totality on
150+ idris_totcheck :: [(FC, Name)], -- names to check totality on
128151 idris_defertotcheck :: [(FC, Name)], -- names to check at the end
152+ idris_totcheckfail :: [(FC, String)],
129153 idris_options :: IOption,
130154 idris_name :: Int,
131155 idris_lineapps :: [((FilePath, Int), PTerm)],
@@ -150,6 +174,7 @@ data IState = IState {
150174 indent_stack :: [Int],
151175 brace_stack :: [Maybe Int],
152176 lastTokenSpan :: Maybe FC, -- ^ What was the span of the latest token parsed?
177+ idris_parsedSpan :: Maybe FC,
153178 hide_list :: [(Name, Maybe Accessibility)],
154179 default_access :: Accessibility,
155180 default_total :: Bool,
@@ -166,7 +191,9 @@ data IState = IState {
166191 idris_function_errorhandlers :: Ctxt (M.Map Name (S.Set Name)), -- ^ Specific error handlers
167192 module_aliases :: M.Map [T.Text] [T.Text],
168193 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])
170197 }
171198
172199data SizeChange = Smaller | Same | Bigger | Unknown
@@ -177,12 +204,13 @@ deriving instance NFData SizeChange
177204!-}
178205
179206type SCGEntry = (Name, [Maybe (Int, SizeChange)])
207+type UsageReason = (Name, Int) -- fn_name, its_arg_number
180208
181209data CGInfo = CGInfo { argsdef :: [Name],
182210 calls :: [(Name, [[Name]])],
183211 scg :: [SCGEntry],
184212 argsused :: [Name],
185− usedpos :: [(Int, [(Name, Int)])] } -- (used_arg#, [(using_fn, its_arg#)])
213+ usedpos :: [(Int, [UsageReason])] }
186214 deriving Show
187215{-!
188216deriving instance Binary CGInfo
@@ -227,6 +255,8 @@ data IBCWrite = IBCFix FixDecl
227255 | IBCErrorHandler Name
228256 | IBCFunctionErrorHandler Name Name Name
229257 | IBCPostulate Name
258+ | IBCTotCheckErr FC String
259+ | IBCParsedRegion FC
230260 deriving Show
231261
232262-- | The initial state for the compiler
@@ -235,10 +265,10 @@ idrisInit = IState initContext [] [] emptyContext emptyContext emptyContext
235265 emptyContext emptyContext emptyContext emptyContext
236266 emptyContext emptyContext emptyContext emptyContext
237267 emptyContext emptyContext
238− [] [] defaultOpts 6 [] [] [] [] [] [] [] [] [] [] [] [] []
239− [] [] Nothing [] Nothing [] [] Nothing [] Hidden False [] Nothing [] [] RawOutput
268+ [] [] [] defaultOpts 6 [] [] [] [] [] [] [] [] [] [] [] [] []
269+ [] [] Nothing [] Nothing [] [] Nothing Nothing [] Hidden False [] Nothing [] [] RawOutput
240270 True defaultTheme stdout [] (0, emptyContext) emptyContext M.empty
241− AutomaticWidth S.empty
271+ AutomaticWidth S.empty Nothing Nothing
242272
243273-- | The monad for the main REPL - reading and processing files and updating
244274-- global state (hence the IO inner monad).
@@ -260,10 +290,10 @@ data Command = Quit
260290 | Help
261291 | Eval PTerm
262292 | Check PTerm
263− | DocStr Name
293+ | DocStr (Either Name Const)
264294 | TotCheck Name
265295 | Reload
266− | Load FilePath
296+ | Load FilePath (Maybe Int) -- up to maximum line number
267297 | ChangeDirectory FilePath
268298 | ModImport String
269299 | Edit
@@ -282,7 +312,6 @@ data Command = Quit
282312 | HNF PTerm
283313 | TestInline PTerm
284314 | Defn Name
285− | Info Name
286315 | Missing Name
287316 | DynamicLink FilePath
288317 | ListDynamic
@@ -294,7 +323,10 @@ data Command = Quit
294323 | AddProofClauseFrom Bool Int Name
295324 | AddMissing Bool Int Name
296325 | MakeWith Bool Int Name
297− | DoProofSearch Bool Int Name [Name]
326+ | MakeLemma Bool Int 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)
298330 | SetOpt Opt
299331 | UnsetOpt Opt
300332 | NOP
@@ -304,10 +336,12 @@ data Command = Quit
304336 | ListErrorHandlers
305337 | SetConsoleWidth ConsoleWidth
306338 | Apropos String
339+ | WhoCalls Name
340+ | CallsWho Name
341+ | MakeDoc String -- IdrisDoc
342+ | Warranty
307343
308344data Opt = Filename String
309− | Ver
310− | Usage
311345 | Quiet
312346 | NoBanner
313347 | ColourREPL Bool
@@ -338,6 +372,8 @@ data Opt = Filename String
338372 | PkgClean String
339373 | PkgCheck String
340374 | PkgREPL String
375+ | PkgMkDoc String -- IdrisDoc
376+ | PkgTest String
341377 | WarnOnly
342378 | Pkg String
343379 | BCAsm String
@@ -347,6 +383,7 @@ data Opt = Filename String
347383 | OutputTy OutputType
348384 | Extension LanguageExt
349385 | InterpretScript String
386+ | EvalExpr String
350387 | TargetTriple String
351388 | TargetCPU String
352389 | OptLevel Word
@@ -429,7 +466,7 @@ data FnOpt = Inlinable -- always evaluate when simplifying
429466 | Implicit -- implicit coercion
430467 | CExport String -- export, with a C name
431468 | 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
433470 | Reflection -- a reflecting function, compile-time only
434471 | Specialise [(Name, Maybe Int)] -- specialise it, freeze these names
435472 deriving (Show, Eq)
@@ -456,10 +493,11 @@ data DataOpt = Codata -- Set if the the data-type is coinductive
456493type DataOpts = [DataOpt]
457494
458495-- | Type provider - what to provide
459−data ProvideWhat = ProvTerm -- ^ only allow providing terms
460− | ProvPostulate -- ^ only allow postulates
461− | ProvAny -- ^ either is ok
462− deriving (Show, Eq)
496+data ProvideWhat' t = ProvTerm t t -- ^ the first is the goal type, the second is the term
497+ | ProvPostulate t -- ^ goal type must be Type, so only term
498+ deriving (Show, Eq, Functor)
499+
500+type ProvideWhat = ProvideWhat' PTerm
463501
464502-- | Top-level declarations such as compiler directives, definitions,
465503-- datatypes and typeclasses.
@@ -472,11 +510,12 @@ data PDecl' t
472510 | PData Docstring [(Name, Docstring)] SyntaxInfo FC DataOpts (PData' t) -- ^ Data declaration.
473511 | PParams FC [(Name, t)] [PDecl' t] -- ^ Params block
474512 | 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
476514 | PClass Docstring SyntaxInfo FC
477515 [t] -- constraints
478516 Name
479517 [(Name, t)] -- parameters
518+ [(Name, Docstring)] -- parameter docstrings
480519 [PDecl' t] -- declarations
481520 -- ^ Type class: arguments are documentation, syntax info, source location, constraints,
482521 -- class name, parameters, method declarations
@@ -492,7 +531,7 @@ data PDecl' t
492531 | PSyntax FC Syntax -- ^ Syntax definition
493532 | PMutual FC [PDecl' t] -- ^ Mutual block
494533 | 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
496535 | PTransform FC Bool t t -- ^ Source-to-source transformation rule. If
497536 -- bool is True, lhs and rhs must be convertible
498537 deriving Functor
@@ -558,8 +597,8 @@ declared (PData _ _ _ _ _ (PDatadecl n _ ts)) = n : map fstt ts
558597declared (PData _ _ _ _ _ (PLaterdecl n _)) = [n]
559598declared (PParams _ _ ds) = concatMap declared ds
560599declared (PNamespace _ ds) = concatMap declared ds
561−declared (PRecord _ _ _ n _ _ c _) = [n, c]
562−declared (PClass _ _ _ _ n _ ms) = n : concatMap declared ms
600+declared (PRecord _ _ _ n _ _ _ c _) = [n, c]
601+declared (PClass _ _ _ _ n _ _ ms) = n : concatMap declared ms
563602declared (PInstance _ _ _ _ _ _ _ _) = []
564603declared (PDSL n _) = [n]
565604declared (PSyntax _ _) = []
@@ -572,13 +611,13 @@ tldeclared (PFix _ _ _) = []
572611tldeclared (PTy _ _ _ _ _ n t) = [n]
573612tldeclared (PPostulate _ _ _ _ n t) = [n]
574613tldeclared (PClauses _ _ n _) = [] -- not a declaration
575−tldeclared (PRecord _ _ _ n _ _ c _) = [n, c]
614+tldeclared (PRecord _ _ _ n _ _ _ c _) = [n, c]
576615tldeclared (PData _ _ _ _ _ (PDatadecl n _ ts)) = n : map fstt ts
577616 where fstt (_, _, a, _, _, _) = a
578617tldeclared (PParams _ _ ds) = []
579618tldeclared (PMutual _ ds) = concatMap tldeclared ds
580619tldeclared (PNamespace _ ds) = concatMap tldeclared ds
581−tldeclared (PClass _ _ _ _ n _ ms) = concatMap tldeclared ms
620+tldeclared (PClass _ _ _ _ n _ _ ms) = concatMap tldeclared ms
582621tldeclared (PInstance _ _ _ _ _ _ _ _) = []
583622tldeclared _ = []
584623
@@ -593,8 +632,8 @@ defined (PData _ _ _ _ _ (PDatadecl n _ ts)) = n : map fstt ts
593632defined (PData _ _ _ _ _ (PLaterdecl n _)) = []
594633defined (PParams _ _ ds) = concatMap defined ds
595634defined (PNamespace _ ds) = concatMap defined ds
596−defined (PRecord _ _ _ n _ _ c _) = [n, c]
597−defined (PClass _ _ _ _ n _ ms) = n : concatMap defined ms
635+defined (PRecord _ _ _ n _ _ _ c _) = [n, c]
636+defined (PClass _ _ _ _ n _ _ ms) = n : concatMap defined ms
598637defined (PInstance _ _ _ _ _ _ _ _) = []
599638defined (PDSL n _) = [n]
600639defined (PSyntax _ _) = []
@@ -631,26 +670,26 @@ data PTerm = PQuote Raw
631670 | PInferRef FC Name -- ^ A name to be defined later
632671 | PPatvar FC Name
633672 | PLam Name PTerm PTerm
634− | PPi Plicity Name PTerm PTerm
673+ | PPi Plicity Name PTerm PTerm -- ^ (n : t1) -> t2
635674 | PLet Name PTerm PTerm PTerm
636675 | PTyped PTerm PTerm -- ^ Term with explicit type
637− | PApp FC PTerm [PArg]
676+ | PApp FC PTerm [PArg] -- ^ e.g. IO (), List Char, length x
638677 | PAppBind FC PTerm [PArg] -- ^ implicitly bound application
639678 | PMatchApp FC Name -- ^ Make an application by type matching
640679 | PCase FC PTerm [(PTerm, PTerm)]
641− | PTrue FC PunInfo
642− | PFalse FC
680+ | PTrue FC PunInfo -- ^ Unit type..?
681+ | PFalse FC -- ^ _|_
643682 | PRefl FC PTerm
644683 | PResolveTC FC
645− | PEq FC PTerm PTerm
684+ | PEq FC PTerm PTerm -- ^ Equality type: A = B
646685 | PRewrite FC PTerm PTerm (Maybe PTerm)
647686 | PPair FC PunInfo PTerm PTerm
648687 | PDPair FC PunInfo PTerm PTerm PTerm
649688 | PAlternative Bool [PTerm] -- True if only one may work
650689 | PHidden PTerm -- ^ Irrelevant or hidden pattern
651− | PType
690+ | PType -- ^ 'Type' type
652691 | PGoal FC PTerm Name PTerm
653− | PConstant Const
692+ | PConstant Const -- ^ Builtin types
654693 | Placeholder
655694 | PDoBlock [PDo]
656695 | PIdiom FC PTerm
@@ -699,13 +738,14 @@ mapPT f t = f (mpt t) where
699738
700739
701740data PTactic' t = Intro [Name] | Intros | Focus Name
702− | Refine Name [Bool] | Rewrite t
741+ | Refine Name [Bool] | Rewrite t | DoUnify
703742 | Induction Name
704743 | Equiv t
705744 | MatchRefine Name
706745 | LetTac Name t | LetTacTy Name t t
707746 | 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
709749 | Solve
710750 | Attack
711751 | ProofState | ProofTerm | Undo
@@ -831,10 +871,10 @@ deriving instance NFData ClassInfo
831871-- Type inference data
832872
833873data 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
835875 deriving Show
836876
837−data OptInfo = Optimise { inaccessible :: [(Int,Name)], -- includes names for error reporting
877+data OptInfo = Optimise { inaccessible :: [(Int,Name)], -- includes names for error reporting
838878 detaggable :: Bool }
839879 deriving Show
840880{-!
@@ -846,7 +886,8 @@ deriving instance NFData OptInfo
846886data TypeInfo = TI { con_names :: [Name],
847887 codata :: Bool,
848888 data_opts :: DataOpts,
849− param_pos :: [Int] }
889+ param_pos :: [Int],
890+ mutual_types :: [Name] }
850891 deriving Show
851892{-!
852893deriving instance Binary TypeInfo
@@ -924,6 +965,8 @@ data SyntaxInfo = Syn { using :: [Using],
924965 decoration :: Name -> Name,
925966 inPattern :: Bool,
926967 implicitAllowed :: Bool,
968+ maxline :: Maybe Int,
969+ mut_nesting :: Int,
927970 dsl_info :: DSL }
928971 deriving Show
929972{-!
@@ -931,7 +974,7 @@ deriving instance NFData SyntaxInfo
931974deriving instance Binary SyntaxInfo
932975!-}
933976
934−defaultSyntax = Syn [] [] [] [] id False False initDSL
977+defaultSyntax = Syn [] [] [] [] id False False Nothing 0 initDSL
935978
936979expandNS :: SyntaxInfo -> Name -> Name
937980expandNS syn n@(NS _ _) = n
@@ -975,52 +1018,92 @@ primNames = [unitTy, unitCon,
9751018 falseTy, pairTy, pairCon,
9761019 eqTy, eqCon, inferTy, inferCon]
9771020
1021+unitDoc = parseDocstring . T.pack $ "The canonical single-element type, also known as the trivially true proposition."
9781022unitTy = sMN 0 "__Unit"
9791023unitCon = sMN 0 "__II"
9801024unitDecl = PDatadecl unitTy PType
981− [(emptyDocstring, [], unitCon, PRef bi unitTy, bi, [])]
1025+ [(parseDocstring . T.pack $ "The trivial constructor for `()`. ", [], unitCon, PRef bi unitTy, bi, [])]
9821026unitOpts = [DefaultEliminator]
9831027
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."
9841033falseTy = sMN 0 "__False"
9851034falseDecl = PDatadecl falseTy PType []
9861035falseOpts = []
9871036
1037+pairDoc = parseDocstring . T.pack $ "The non-dependent pair type, also known as conjunction."
9881038pairTy = sMN 0 "__Pair"
9891039pairCon = sMN 0 "__MkPair"
9901040pairDecl = PDatadecl pairTy (piBind [(n "A", PType), (n "B", PType)] PType)
991− [(emptyDocstring, [], pairCon, PPi impl (n "A") PType (
992− PPi impl (n "B") PType (
993− PPi expl (n "a") (PRef bi (n "A")) (
994− PPi expl (n "b") (PRef bi (n "B"))
995− (PApp bi (PRef bi pairTy) [pexp (PRef bi (n "A")),
996− pexp (PRef bi (n "B"))])))), bi, [])]
1041+ [(pairConDoc, pairConParamDoc,
1042+ pairCon, PPi impl (n "A") PType (
1043+ PPi impl (n "B") PType (
1044+ PPi expl (n "a") (PRef bi (n "A")) (
1045+ PPi expl (n "b") (PRef bi (n "B"))
1046+ (PApp bi (PRef bi pairTy) [pexp (PRef bi (n "A")),
1047+ pexp (PRef bi (n "B"))])))), bi, [])]
9971048 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")]
9981052pairOpts = []
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
9991056
10001057eqTy = sUN "="
10011058eqCon = 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+
10021073eqDecl = PDatadecl eqTy (piBind [(n "A", PType), (n "B", PType),
10031074 (n "x", PRef bi (n "A")), (n "y", PRef bi (n "B"))]
10041075 PType)
1005− [(emptyDocstring, [], eqCon, PPi impl (n "A") PType (
1006− PPi impl (n "x") (PRef bi (n "A"))
1007− (PApp bi (PRef bi eqTy) [pimp (n "A") Placeholder False,
1008− pimp (n "B") Placeholder False,
1009− pexp (PRef bi (n "x")),
1010− pexp (PRef bi (n "x"))])), bi, [])]
1076+ [(reflDoc, reflParamDoc,
1077+ eqCon, PPi impl (n "A") PType (
1078+ PPi impl (n "x") (PRef bi (n "A"))
1079+ (PApp bi (PRef bi eqTy) [pimp (n "A") Placeholder False,
1080+ pimp (n "B") Placeholder False,
1081+ pexp (PRef bi (n "x")),
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+ ]
10111093 where n a = sMN 0 a
1094+
10121095eqOpts = []
10131096
10141097elimName = sUN "__Elim"
10151098elimMethElimTy = sUN "__elimTy"
10161099elimMethElim = 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)] []
10181101 [PTy emptyDocstring [] defaultSyntax bi [TotalFn] elimMethElimTy PType,
10191102 PTy emptyDocstring [] defaultSyntax bi [TotalFn] elimMethElim (PRef bi elimMethElimTy)]
10201103
10211104-- Defined in builtins.idr
1022−sigmaTy = sUN "Exists"
1023−existsCon = sUN "Ex_intro"
1105+sigmaTy = sUN "Sigma"
1106+existsCon = sUN "Sg_intro"
10241107
10251108piBind :: [(Name, PTerm)] -> PTerm -> PTerm
10261109piBind = piBindp expl
@@ -1036,58 +1119,69 @@ piBindp p ((n, ty):ns) t = PPi p n ty (piBindp p ns t)
10361119-- could interfere with interactive editing, which calls "show".
10371120
10381121instance 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
10401123
10411124instance 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
10431126
10441127instance 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
10461129
10471130instance 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
10491132
10501133instance Pretty PTerm OutputAnnotation where
1051− pretty = prettyImp False
1134+ pretty = prettyImp defaultPPOption
10521135
10531136-- | Colourise annotations according to an Idris state. It ignores the names
10541137-- in the annotation, as there's no good way to show extended information on a
10551138-- terminal.
10561139consoleDecorate :: IState -> OutputAnnotation -> String -> String
10571140consoleDecorate ist _ | not (idris_colourRepl ist) = id
1058−consoleDecorate ist AnnConstData = let theme = idris_colourTheme ist
1059− in colouriseData theme
1060−consoleDecorate ist AnnConstType = let theme = idris_colourTheme ist
1061− in colouriseType theme
1141+consoleDecorate ist (AnnConst c) = let theme = idris_colourTheme ist
1142+ in if constIsType c
1143+ then colouriseType theme
1144+ else colouriseData theme
1145+consoleDecorate ist (AnnData _ _) = colouriseData (idris_colourTheme ist)
1146+consoleDecorate ist (AnnType _ _) = colouriseType (idris_colourTheme ist)
10621147consoleDecorate ist (AnnBoundName _ True) = colouriseImplicit (idris_colourTheme ist)
10631148consoleDecorate ist (AnnBoundName _ False) = colouriseBound (idris_colourTheme ist)
10641149consoleDecorate ist AnnKeyword = colouriseKeyword (idris_colourTheme ist)
10651150consoleDecorate ist (AnnName n _ _ _) = let ctxt = tt_ctxt ist
10661151 theme = idris_colourTheme ist
10671152 in case () of
1068− _ | isDConName n ctxt -> colouriseData theme
1069− _ | isFnName n ctxt -> colouriseFun theme
1070− _ | isTConName n ctxt -> colouriseType theme
1071− _ | otherwise -> id -- don't colourise unknown names
1153+ _ | isDConName n ctxt -> colouriseData theme
1154+ _ | isFnName n ctxt -> colouriseFun theme
1155+ _ | isTConName n ctxt -> colouriseType theme
1156+ _ | isPostulateName n ist -> colourisePostulate theme
1157+ _ | otherwise -> id -- don't colourise unknown names
10721158consoleDecorate ist (AnnFC _) = id
10731159consoleDecorate ist (AnnTextFmt fmt) = Idris.Colours.colourise (colour fmt)
10741160 where colour BoldText = IdrisColour Nothing True False True False
10751161 colour UnderlineText = IdrisColour Nothing True True False False
10761162 colour ItalicText = IdrisColour Nothing True False False True
10771163
1078−-- | Pretty-print a high-level closed Idris term
1079−prettyImp :: Bool -- ^^ whether to show implicits
1164+isPostulateName :: Name -> IState -> Bool
1165+isPostulateName n ist = S.member n (idris_postulates ist)
1166+
1167+-- | Pretty-print a high-level closed Idris term with no information about precedence/associativity
1168+prettyImp :: PPOption -- ^^ pretty printing options
10801169 -> PTerm -- ^^ the term to pretty-print
10811170 -> 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)
10831176
1084−-- | Pretty-print a high-level Idris term in some bindings context
1085−pprintPTerm :: Bool -- ^^ whether to show implicits
1177+-- | Pretty-print a high-level Idris term in some bindings context with infix info
1178+pprintPTerm :: PPOption -- ^^ pretty printing options
10861179 -> [(Name, Bool)] -- ^^ the currently-bound names and whether they are implicit
10871180 -> [Name] -- ^^ names to always show in pi, even if not used
1181+ -> [FixDecl] -- ^^ Fixity declarations
10881182 -> PTerm -- ^^ the term to pretty-print
10891183 -> Doc OutputAnnotation
1090−pprintPTerm impl bnd docArgs = prettySe 10 bnd
1184+pprintPTerm ppo bnd docArgs infixes = prettySe 10 bnd
10911185 where
10921186 prettySe :: Int -> [(Name, Bool)] -> PTerm -> Doc OutputAnnotation
10931187 prettySe p bnd (PQuote r) =
@@ -1095,8 +1189,8 @@ pprintPTerm impl bnd docArgs = prettySe 10 bnd
10951189 prettySe p bnd (PPatvar fc n) = pretty n
10961190 prettySe p bnd e
10971191 | Just str <- slist p bnd e = str
1098− | Just n <- snat p e = annotate AnnConstData (text (show n))
1099− prettySe p bnd (PRef fc n) = prettyName impl bnd n
1192+ | Just n <- snat p e = annotate (AnnData "Nat" "") (text (show n))
1193+ prettySe p bnd (PRef fc n) = prettyName (ppopt_impl ppo) bnd n
11001194 prettySe p bnd (PLam n ty sc) =
11011195 bracket p 2 . group . align . hang 2 $
11021196 text "\\" <> bindingOf n False <+> text "=>" <$>
@@ -1107,22 +1201,22 @@ pprintPTerm impl bnd docArgs = prettySe 10 bnd
11071201 prettySe 10 bnd v <+> kwd "in" </>
11081202 prettySe 10 ((n, False):bnd) sc
11091203 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 =
11111205 bracket p 2 . group $
11121206 enclose lparen rparen (group . align $ bindingOf n False <+> colon <+> prettySe 10 bnd ty) <+>
11131207 st <> text "->" <$> prettySe 10 ((n, False):bnd) sc
11141208 | otherwise =
11151209 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)
11171211 where
11181212 st =
11191213 case s of
11201214 Static -> text "[static]" <> space
11211215 _ -> empty
11221216 prettySe p bnd (PPi (Imp l s _) n ty sc)
1123− | impl =
1217+ | ppopt_impl ppo =
11241218 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 <+>
11261220 st <> text "->" </> prettySe 10 ((n, True):bnd) sc
11271221 | otherwise = prettySe 10 ((n, True):bnd) sc
11281222 where
@@ -1139,35 +1233,46 @@ pprintPTerm impl bnd docArgs = prettySe 10 bnd
11391233 rbrace <+> text "->" </> prettySe 10 ((n, True):bnd) sc
11401234 prettySe p bnd (PApp _ (PRef _ f) args) -- normal names, no explicit args
11411235 | UN nm <- basename f
1142− , not impl && null (getExps args) = if isAlpha (thead nm)
1143− then prettyName impl bnd f
1144− else enclose lparen rparen $
1145− prettyName impl bnd f
1236+ , not (ppopt_impl ppo) && null (getExps args) =
1237+ if isAlpha (thead nm)
1238+ then prettyName (ppopt_impl ppo) bnd f
1239+ else enclose lparen rparen $ prettyName (ppopt_impl ppo) bnd f
11461240 prettySe p bnd (PAppBind _ (PRef _ f) [])
1147− | not impl = text "!" <> prettyName impl bnd f
1148− prettySe p bnd (PApp _ (PRef _ op) args)
1241+ | not (ppopt_impl ppo) = text "!" <> prettyName (ppopt_impl ppo) bnd f
1242+ prettySe p bnd (PApp _ (PRef _ op) args) -- infix operators
11491243 | UN nm <- basename op
11501244 , not (tnull nm) &&
1151− (not impl) && (not $ isAlpha (thead nm)) =
1245+ (not (ppopt_impl ppo)) && (not $ isAlpha (thead nm)) =
11521246 case getExps args of
11531247 [] -> enclose lparen rparen opName
11541248 [x] -> group (enclose lparen rparen opName <$> group (prettySe 0 bnd x))
1155− [l,r] -> bracket p 1 $ inFix l r
1249+ [l,r] -> let precedence = fromMaybe 20 (fmap prec f)
1250+ in bracket p precedence $ inFix l r
11561251 (l:r:rest) -> bracket p 1 $
11571252 enclose lparen rparen (inFix l r) <+>
11581253 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
11601264 inFix l r = align . group $
1161− (prettySe 1 bnd l <+> opName) <$> group (prettySe 0 bnd r)
1162− prettySe p bnd (PApp _ hd@(PRef fc f) [tm])
1265+ (left l <+> opName) <$> group (right r)
1266+ prettySe p bnd (PApp _ hd@(PRef fc f) [tm]) -- symbols, like 'foo
11631267 | PConstant (Idris.Core.TT.Str str) <- getTm tm,
1164− f == sUN "Symbol_" = char '\'' <> prettySe 10 bnd (PRef fc (sUN str))
1165− prettySe p bnd (PApp _ f as) =
1268+ f == sUN "Symbol_" = annotate (AnnType ("'" ++ str) ("The symbol " ++ str)) $
1269+ char '\'' <> prettySe 10 bnd (PRef fc (sUN str))
1270+ prettySe p bnd (PApp _ f as) = -- Normal prefix applications
11661271 let args = getExps as
11671272 fp = prettySe 1 bnd f
11681273 in
11691274 bracket p 1 . group $
1170− if impl
1275+ if ppopt_impl ppo
11711276 then if null as
11721277 then fp
11731278 else fp <+> align (vsep (map (prettyArgS bnd) as))
@@ -1229,13 +1334,8 @@ pprintPTerm impl bnd docArgs = prettySe 10 bnd
12291334 where
12301335 prettyAs =
12311336 foldr (\l -> \r -> l <+> text "," <+> r) empty $ map (prettySe 10 bnd) as
1232− prettySe p bnd PType = annotate AnnConstType $ text "Type"
1233− prettySe p bnd (PConstant c) = annotate (annot c) (text (show c))
1234− where annot (AType _) = AnnConstType
1235− annot StrType = AnnConstType
1236− annot PtrType = AnnConstType
1237− annot VoidType = AnnConstType
1238− annot _ = AnnConstData
1337+ prettySe p bnd PType = annotate (AnnType "Type" "The type of types") $ text "Type"
1338+ prettySe p bnd (PConstant c) = annotate (AnnConst c) (text (show c))
12391339 -- XXX: add pretty for tactics
12401340 prettySe p bnd (PProof ts) =
12411341 text "proof" <+> lbrace <> nest nestingSize (text . show $ ts) <> rbrace
@@ -1246,6 +1346,7 @@ pprintPTerm impl bnd docArgs = prettySe 10 bnd
12461346 prettySe p bnd PImpossible = kwd "impossible"
12471347 prettySe p bnd Placeholder = text "_"
12481348 prettySe p bnd (PDoBlock _) = text "do block pretty not implemented"
1349+ prettySe p bnd (PCoerced t) = prettySe p bnd t
12491350 prettySe p bnd (PElabError s) = pretty s
12501351
12511352 prettySe p bnd _ = text "test"
@@ -1263,14 +1364,18 @@ pprintPTerm impl bnd docArgs = prettySe 10 bnd
12631364 annName :: Name -> Doc OutputAnnotation -> Doc OutputAnnotation
12641365 annName n = annotate (AnnName n Nothing Nothing Nothing)
12651366
1367+ opStr :: Name -> String
1368+ opStr (NS n _) = opStr n
1369+ opStr (UN n) = T.unpack n
1370+
12661371 basename :: Name -> Name
12671372 basename (NS n _) = basename n
12681373 basename n = n
12691374
12701375 slist' p bnd (PApp _ (PRef _ nil) _)
1271− | not impl && nsroot nil == sUN "Nil" = Just []
1376+ | not (ppopt_impl ppo) && nsroot nil == sUN "Nil" = Just []
12721377 slist' p bnd (PRef _ nil)
1273− | not impl && nsroot nil == sUN "Nil" = Just []
1378+ | not (ppopt_impl ppo) && nsroot nil == sUN "Nil" = Just []
12741379 slist' p bnd (PApp _ (PRef _ cons) args)
12751380 | nsroot cons == sUN "::",
12761381 (PExp {getTm=tl}):(PExp {getTm=hd}):imps <- reverse args,
@@ -1283,16 +1388,16 @@ pprintPTerm impl bnd docArgs = prettySe 10 bnd
12831388 slist' _ _ tm = Nothing
12841389
12851390 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 "[]"
12871392 [x] -> enclose left right . group $
12881393 prettySe p bnd x
12891394 xs -> (enclose left right .
12901395 align . group . vsep .
12911396 punctuate comma .
12921397 map (prettySe p bnd)) xs
1293− where left = (annotate AnnConstData (text "["))
1294− right = (annotate AnnConstData (text "]"))
1295− comma = (annotate AnnConstData (text ","))
1398+ where left = (annotate (AnnData "" "") (text "["))
1399+ right = (annotate (AnnData "" "") (text "]"))
1400+ comma = (annotate (AnnData "" "") (text ","))
12961401 slist _ _ _ = Nothing
12971402
12981403 pairElts :: PTerm -> Maybe [PTerm]
@@ -1316,6 +1421,17 @@ pprintPTerm impl bnd docArgs = prettySe 10 bnd
13161421
13171422 kwd = annotate AnnKeyword . text
13181423
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+
13191435-- | Pretty-printer helper for the binding site of a name
13201436bindingOf :: Name -- ^^ the bound name
13211437 -> Bool -- ^^ whether the name is implicit
@@ -1332,47 +1448,48 @@ prettyName showNS bnd n | Just imp <- lookup n bnd = annotate (AnnBoundName n im
13321448 where strName (UN n) = T.unpack n
13331449 strName (NS n ns) | showNS = (concatMap (++ ".") . map T.unpack . reverse) ns ++ strName n
13341450 | otherwise = strName n
1335− strName (MN i s) = T.unpack s
1451+ strName n | n == falseTy = "_|_"
1452+ strName (MN i s) = T.unpack s
13361453 strName other = show other
13371454
13381455
1339−showCImp :: Bool -> PClause -> Doc OutputAnnotation
1340−showCImp impl (PClause _ n l ws r w)
1341− = prettyImp impl l <+> showWs ws <+> text "=" <+> prettyImp impl r
1456+showCImp :: PPOption -> PClause -> Doc OutputAnnotation
1457+showCImp ppo (PClause _ n l ws r w)
1458+ = prettyImp ppo l <+> showWs ws <+> text "=" <+> prettyImp ppo r
13421459 <+> text "where" <+> text (show w)
13431460 where
13441461 showWs [] = empty
1345− showWs (x : xs) = text "|" <+> prettyImp impl x <+> showWs xs
1346−showCImp impl (PWith _ n l ws r w)
1347− = prettyImp impl l <+> showWs ws <+> text "with" <+> prettyImp impl r
1462+ showWs (x : xs) = text "|" <+> prettyImp ppo x <+> showWs xs
1463+showCImp ppo (PWith _ n l ws r w)
1464+ = prettyImp ppo l <+> showWs ws <+> text "with" <+> prettyImp ppo r
13481465 <+> braces (text (show w))
13491466 where
13501467 showWs [] = empty
1351− showWs (x : xs) = text "|" <+> prettyImp impl x <+> showWs xs
1468+ showWs (x : xs) = text "|" <+> prettyImp ppo x <+> showWs xs
13521469
13531470
1354−showDImp :: Bool -> PData -> Doc OutputAnnotation
1355−showDImp impl (PDatadecl n ty cons)
1356− = text "data" <+> text (show n) <+> colon <+> prettyImp impl ty <+> text "where" <$>
1357− (indent 2 $ vsep (map (\ (_, _, n, t, _, _) -> pipe <+> prettyName False [] n <+> colon <+> prettyImp impl t) cons))
1471+showDImp :: PPOption -> PData -> Doc OutputAnnotation
1472+showDImp ppo (PDatadecl n ty cons)
1473+ = text "data" <+> text (show n) <+> colon <+> prettyImp ppo ty <+> text "where" <$>
1474+ (indent 2 $ vsep (map (\ (_, _, n, t, _, _) -> pipe <+> prettyName False [] n <+> colon <+> prettyImp ppo t) cons))
13581475
1359−showDecls :: Bool -> [PDecl] -> Doc OutputAnnotation
1360−showDecls i ds = vsep (map (showDeclImp i) ds)
1476+showDecls :: PPOption -> [PDecl] -> Doc OutputAnnotation
1477+showDecls o ds = vsep (map (showDeclImp o) ds)
13611478
13621479showDeclImp _ (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
1364−showDeclImp i (PClauses _ _ n cs) = text "pat" <+> text (showCG n) <+> text "\t" <+>
1365− indent 2 (vsep (map (showCImp i) cs))
1366−showDeclImp _ (PData _ _ _ _ _ d) = showDImp True d
1367−showDeclImp i (PParams _ ns ps) = text "params" <+> braces (text (show ns) <> line <> showDecls i ps <> line)
1368−showDeclImp i (PNamespace n ps) = text "namespace" <+> text n <> braces (line <> showDecls i ps <> line)
1480+showDeclImp o (PTy _ _ _ _ _ n t) = text "tydecl" <+> text (showCG n) <+> colon <+> prettyImp o t
1481+showDeclImp o (PClauses _ _ n cs) = text "pat" <+> text (showCG n) <+> text "\t" <+>
1482+ indent 2 (vsep (map (showCImp o) cs))
1483+showDeclImp o (PData _ _ _ _ _ d) = showDImp o { ppopt_impl = True } d
1484+showDeclImp o (PParams _ ns ps) = text "params" <+> braces (text (show ns) <> line <> showDecls o ps <> line)
1485+showDeclImp o (PNamespace n ps) = text "namespace" <+> text n <> braces (line <> showDecls o ps <> line)
13691486showDeclImp _ (PSyntax _ syn) = text "syntax" <+> text (show syn)
1370−showDeclImp i (PClass _ _ _ cs n ps ds)
1371− = text "class" <+> text (show cs) <+> text (show n) <+> text (show ps) <> line <> showDecls i ds
1372−showDeclImp i (PInstance _ _ cs n _ t _ ds)
1373− = text "instance" <+> text (show cs) <+> text (show n) <+> prettyImp i t <> line <> showDecls i ds
1487+showDeclImp o (PClass _ _ _ cs n ps _ ds)
1488+ = text "class" <+> text (show cs) <+> text (show n) <+> text (show ps) <> line <> showDecls o ds
1489+showDeclImp o (PInstance _ _ cs n _ t _ ds)
1490+ = text "instance" <+> text (show cs) <+> text (show n) <+> prettyImp o t <> line <> showDecls o ds
13741491showDeclImp _ _ = text "..."
1375−-- showDeclImp (PImport i) = "import " ++ i
1492+-- showDeclImp (PImport o) = "import " ++ o
13761493
13771494instance Show (Doc OutputAnnotation) where
13781495 show = flip (displayS . renderCompact) ""
@@ -1399,14 +1516,14 @@ getAll = map getTm
13991516-- | Show Idris name
14001517showName :: Maybe IState -- ^^ the Idris state, for information about names and colours
14011518 -> [(Name, Bool)] -- ^^ the bound variables and whether they're implicit
1402− -> Bool -- ^^ whether to show implicits
1519+ -> PPOption -- ^^ pretty printing options
14031520 -> Bool -- ^^ whether to colourise
14041521 -> Name -- ^^ the term to show
14051522 -> String
1406−showName ist bnd impl colour n = case ist of
1523+showName ist bnd ppo colour n = case ist of
14071524 Just i -> if colour then colourise n (idris_colourTheme i) else showbasic n
14081525 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
14101527 showbasic n@(UN _) = showCG n
14111528 showbasic (MN _ s) = str s
14121529 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
14301547 -> String
14311548showTm ist = displayDecorated (consoleDecorate ist) .
14321549 renderPretty 0.8 100000 .
1433− prettyImp (opt_showimp (idris_options ist))
1550+ prettyImp (ppOptionIst ist)
14341551
14351552-- | Show a term with implicits, no colours
14361553showTmImpls :: PTerm -> String
1437−showTmImpls = flip (displayS . renderCompact . prettyImp True) ""
1554+showTmImpls = flip (displayS . renderCompact . prettyImp verbosePPOption) ""
1555+
14381556
14391557
14401558instance Sized PTerm where
@@ -1567,8 +1685,8 @@ usedNamesIn vars ist tm = nub $ ni [] tm
15671685 where -- TODO THINK added niTacImp, but is it right?
15681686 ni env (PRef _ n)
15691687 | n `elem` vars && not (n `elem` env)
1570− = case lookupTy n (tt_ctxt ist) of
1571− [] -> [n]
1688+ = case lookupDefExact n (tt_ctxt ist) of
1689+ Nothing -> [n]
15721690 _ -> []
15731691 ni env (PApp _ f as) = ni env f ++ concatMap (ni env) (map getTm as)
15741692 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
15901708
15911709 niTacImp env (TacImp _ _ scr) = ni env scr
15921710 niTacImp _ _ = []
1593−
src/Idris/Apropos.hs+12−8
@@ -9,8 +9,8 @@ import Idris.Docstrings (Docstring, containsText)
99import Data.List (nub)
1010import qualified Data.Text as T
1111
12−-- | Find definitions that are relevant to some string. Relevance is one or
13−-- more of the following:
12+-- | Find definitions that are relevant to all space-delimited components of
13+-- some string. Relevance is one or more of the following:
1414--
1515-- * the string is a substring of the name
1616--
@@ -20,8 +20,12 @@ import qualified Data.Text as T
2020apropos :: IState -> T.Text -> [Name]
2121apropos ist what = let defs = ctxtAlist (tt_ctxt ist)
2222 docs = toAlist (idris_docstrings ist)
23− in nub (map fst (filter (isApropos what) defs) ++
24− map fst (filter (isApropos what) docs))
23+ in nub (map fst (isAproposAll parts defs) ++
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
2529
2630textIn :: T.Text -> T.Text -> Bool
2731textIn a b = T.isInfixOf (T.toLower a) (T.toLower b)
@@ -48,10 +52,10 @@ instance Apropos Def where
4852 isApropos str (CaseOp _ ty ty' _ _ _) = isApropos str ty
4953
5054instance Apropos (Binder (TT Name)) where
51− isApropos str (Lam ty) = isApropos str ty
52− isApropos str (Pi ty) = isApropos str ty
53− isApropos str (Let ty val) = isApropos str ty || isApropos str val
54− isApropos str (NLet ty val) = isApropos str ty || isApropos str val
55+ isApropos str (Lam ty) = str == T.pack "\\" || isApropos str ty
56+ isApropos str (Pi ty) = str == T.pack "->" || isApropos str ty
57+ isApropos str (Let ty val) = str == T.pack "let" || isApropos str ty || isApropos str val
58+ isApropos str (NLet ty val) = str == T.pack "let" || isApropos str ty || isApropos str val
5559 isApropos str _ = False -- these shouldn't occur in defined libraries
5660
5761instance Apropos (TT Name) where
src/Idris/CaseSplit.hs+42−13
@@ -22,6 +22,7 @@ import Idris.Core.Evaluate
2222
2323import Data.Maybe
2424import Data.Char
25+import Data.List (isPrefixOf, isSuffixOf)
2526import Control.Monad
2627import Control.Monad.State.Strict
2728
@@ -54,7 +55,10 @@ split n t'
5455 = do ist <- getIState
5556 -- Make sure all the names in the term are accessible
5657 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
5862 logLvl 4 ("Elaborated:\n" ++ show tm ++ " : " ++ show ty ++ "\n" ++ show pats)
5963-- iputStrLn (show (delab ist tm) ++ " : " ++ show (delab ist ty))
6064-- iputStrLn (show pats)
@@ -276,6 +280,8 @@ replaceSplits l ups = updateRHSs 1 (map (rep (expandBraces l)) ups)
276280 nshow t = show t
277281
278282 -- if there's any {n} replace with {n=n}
283+ -- but don't replace it in comments
284+ expandBraces ('{' : '-' : xs) = '{' : '-' : xs
279285 expandBraces ('{' : xs)
280286 = let (brace, (_:rest)) = span (/= '}') xs in
281287 if (not ('=' `elem` brace))
@@ -294,9 +300,11 @@ replaceSplits l ups = updateRHSs 1 (map (rep (expandBraces l)) ups)
294300 if (before == n && not (isAlphaNum next))
295301 then addBrackets tm ++ updatePat False n tm after
296302 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
298304
299− addBrackets tm | ' ' `elem` tm = "(" ++ tm ++ ")"
305+ addBrackets tm | ' ' `elem` tm
306+ , not (isPrefixOf "(" tm)
307+ , not (isSuffixOf ")" tm) = "(" ++ tm ++ ")"
300308 | otherwise = tm
301309
302310getUniq nm i
@@ -316,12 +324,17 @@ getClause :: Int -- ^ line number that the type is declared on
316324 -> Name -- ^ Function name
317325 -> FilePath -- ^ Source file name
318326 -> Idris String
319−getClause l fn fp = do ty <- getInternalApp fp l
320− ist <- get
321− let ap = mkApp ist ty []
322− return (show fn ++ " " ++ ap ++
323− "= ?" ++ show fn ++ "_rhs")
324− where mkApp i (PPi (Exp _ _ False) (MN _ _) ty sc) used
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))
331+ _ -> do ty <- getInternalApp fp l
332+ ist <- get
333+ let ap = mkApp ist ty []
334+ return (show fn ++ " " ++ ap ++ "= ?"
335+ ++ show fn ++ "_rhs")
336+ where mkApp :: IState -> PTerm -> [Name] -> String
337+ mkApp i (PPi (Exp _ _ False) (MN _ _) ty sc) used
325338 = let n = getNameFrom i used ty in
326339 show n ++ " " ++ mkApp i sc (n : used)
327340 mkApp i (PPi (Exp _ _ False) (UN n) ty sc) used
@@ -343,6 +356,19 @@ getClause l fn fp = do ty <- getInternalApp fp l
343356 ns -> uniqueNameFrom (mkSupply ns) used
344357 getNameFrom i used _ = uniqueName (sUN "x") used
345358
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+
346372getProofClause :: Int -- ^ line number that the type is declared
347373 -> Name -- ^ Function name
348374 -> FilePath -- ^ Source file name
@@ -358,16 +384,19 @@ getProofClause l fn fp
358384
359385mkWith :: String -> Name -> String
360386mkWith 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
364388
365389 where replaceRHS [] str = str
366390 replaceRHS ('?':'=': rest) str = str
367− replaceRHS ('=': rest) str
391+ replaceRHS ('=': rest) str
368392 | not ('=' `elem` rest) = str
369393 replaceRHS (x : rest) str = x : replaceRHS rest str
370394
395+ newpat ('>':patstr) = '>':newpat patstr
396+ newpat patstr =
397+ " " ++
398+ replaceRHS patstr "| with_pat = ?" ++ show n ++ "_rhs"
399+
371400-- Replace _ with names in missing clauses
372401
373402nameMissing :: [PTerm] -> Idris [PTerm]
src/Idris/Chaser.hs+1−1
@@ -82,7 +82,7 @@ buildTree built fp = btree [] fp
8282 iLOG $ "CHASING " ++ show file
8383 ibcsd <- valIBCSubDir i
8484 ids <- allImportDirs
85− fp <- runIO $ findImport ids ibcsd file
85+ fp <- findImport ids ibcsd file
8686 iLOG $ "Found " ++ show fp
8787 mt <- runIO $ getIModTime fp
8888 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 (
22 IdrisColour(..),
33 ColourTheme(..),
44 defaultTheme,
5− colouriseKwd, colouriseBound, colouriseImplicit,
5+ colouriseKwd, colouriseBound, colouriseImplicit, colourisePostulate,
66 colouriseType, colouriseFun, colouriseData, colouriseKeyword,
77 colourisePrompt, colourise, ColourType(..)) where
88
@@ -19,13 +19,14 @@ data IdrisColour = IdrisColour { colour :: Maybe Color
1919mkColour :: Color -> IdrisColour
2020mkColour c = IdrisColour (Just c) True False False False
2121
22−data ColourTheme = ColourTheme { keywordColour :: IdrisColour
23− , boundVarColour :: IdrisColour
24− , implicitColour :: IdrisColour
25− , functionColour :: IdrisColour
26− , typeColour :: IdrisColour
27− , dataColour :: IdrisColour
28− , promptColour :: IdrisColour
22+data ColourTheme = ColourTheme { keywordColour :: IdrisColour
23+ , boundVarColour :: IdrisColour
24+ , implicitColour :: IdrisColour
25+ , functionColour :: IdrisColour
26+ , typeColour :: IdrisColour
27+ , dataColour :: IdrisColour
28+ , promptColour :: IdrisColour
29+ , postulateColour :: IdrisColour
2930 }
3031 deriving (Eq, Show)
3132
@@ -38,6 +39,7 @@ defaultTheme = ColourTheme { keywordColour = IdrisColour Nothing True False True
3839 , typeColour = mkColour Blue
3940 , dataColour = mkColour Red
4041 , promptColour = IdrisColour Nothing True False True False
42+ , postulateColour = IdrisColour (Just Green) True False True False
4143 }
4244
4345-- | Set the colour of a string using POSIX escape codes
@@ -74,6 +76,10 @@ colourisePrompt t = colourise (promptColour t)
7476colouriseKeyword :: ColourTheme -> String -> String
7577colouriseKeyword t = colourise (keywordColour t)
7678
79+colourisePostulate :: ColourTheme -> String -> String
80+colourisePostulate t = colourise (postulateColour t)
81+
82+
7783data ColourType = KeywordColour
7884 | BoundVarColour
7985 | ImplicitColour
@@ -81,4 +87,5 @@ data ColourType = KeywordColour
8187 | TypeColour
8288 | DataColour
8389 | PromptColour
90+ | PostulateColour
8491 deriving (Eq, Show, Bounded, Enum)
src/Idris/Completion.hs+3−1
@@ -51,7 +51,7 @@ tacticArgs = [ ("intro", Nothing) -- FIXME syntax for intro (fresh name)
5151 , (":eval", Just ExprTArg)
5252 ] ++ map (\x -> (x, Nothing)) [
5353 "intros", "compute", "trivial", "search", "solve", "attack",
54− "state", "term", "undo", "qed", "abandon", ":q"
54+ "unify", "state", "term", "undo", "qed", "abandon", ":q"
5555 ]
5656tactics = map fst tacticArgs
5757
@@ -112,6 +112,7 @@ completeOption = completeWord Nothing " \t" completeOpt
112112 , "showimplicits"
113113 , "originalerrors"
114114 , "autosolve"
115+ , "nobanner"
115116 ]
116117
117118completeConsoleWidth :: CompletionFunc Idris
@@ -160,6 +161,7 @@ completeCmd cmd (prev, next) = fromMaybe completeCmdName $ fmap completeArg $ lo
160161 completeArg NameArg = completeExpr [] (prev, next) -- FIXME only complete one name
161162 completeArg OptionArg = completeOption (prev, next)
162163 completeArg ModuleArg = noCompletion (prev, next) -- FIXME do later
164+ completeArg NamespaceArg = noCompletion (prev, next) -- FIXME do later
163165 completeArg ExprArg = completeExpr [] (prev, next)
164166 completeArg MetaVarArg = completeMetaVar (prev, next) -- FIXME only complete one name
165167 completeArg ColourArg = completeColour (prev, next)
src/Idris/Core/CaseTree.hs+21−1
@@ -10,6 +10,7 @@ import Idris.Core.TT
1010import Control.Monad.State
1111import Data.Maybe
1212import Data.List hiding (partition)
13+import qualified Data.List(partition)
1314import Debug.Trace
1415
1516data CaseDef = CaseDef [Name] !SC [Term]
@@ -417,8 +418,15 @@ order :: [(Name, Bool)] -> [Clause] -> ([Name], [Clause])
417418order [] cs = ([], cs)
418419order ns' [] = (map fst ns', [])
419420order 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
420427 -- 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
422430 (getNOrder pats', zipWith rebuild pats' cs)
423431 where
424432 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))
426434
427435 rebuild patnames clause = (map snd patnames, snd clause)
428436
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+
429447 -- this compares (+isInaccessible, -numberOfCases)
430448 moreDistinct xs ys = compare (snd . fst . head $ xs, numNames [] (map snd ys))
431449 (snd . fst . head $ ys, numNames [] (map snd xs))
@@ -694,6 +712,8 @@ substSC n repl (Case n' alts)
694712 | n == n' = Case repl (map (substAlt n repl) alts)
695713 | otherwise = Case n' (map (substAlt n repl) alts)
696714substSC 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
697717substSC n repl sc = error $ "unsupported in substSC: " ++ show sc
698718
699719substAlt :: Name -> Name -> CaseAlt -> CaseAlt
src/Idris/Core/Elaborate.hs+14−6
@@ -64,7 +64,7 @@ loadState :: Elab' aux ()
6464loadState = do (ES p s e) <- get
6565 case e of
6666 Just st -> put st
67− _ -> fail "Nothing to undo"
67+ _ -> lift $ Error . Msg $ "Nothing to undo"
6868
6969getNameFrom :: Name -> Elab' aux Name
7070getNameFrom n = do (ES (p, a) s e) <- get
@@ -328,6 +328,10 @@ start_unify n = processTactic' (StartUnify n)
328328end_unify :: Elab' aux ()
329329end_unify = processTactic' EndUnify
330330
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+
331335regret :: Elab' aux ()
332336regret = processTactic' Regret
333337
@@ -642,6 +646,7 @@ no_errors tac err
642646 Error _ -> lift $ Error e
643647 OK (a, s') -> do put s'
644648 return a
649+ unifyProblems
645650 ps' <- get_probs
646651 if (length ps' > length ps) then
647652 case reverse ps' of
@@ -676,11 +681,13 @@ try' :: Elab' aux a -> Elab' aux a -> Bool -> Elab' aux a
676681try' t1 t2 proofSearch
677682 = do s <- get
678683 ps <- get_probs
684+ ulog <- getUnifyLog
679685 case prunStateT 999999 False ps t1 s of
680686 OK ((v, _, _), s') -> do put s'
681687 return $! v
682− Error e1 -> if recoverableErr e1 then
683− do case runStateT t2 s of
688+ Error e1 -> traceWhen ulog ("try failed " ++ show e1) $
689+ if recoverableErr e1 then
690+ do case runStateT t2 s of
684691 OK (v, s') -> do put s'; return $! v
685692 Error e2 -> if score e1 >= score e2
686693 then lift (tfail e1)
@@ -690,6 +697,7 @@ try' t1 t2 proofSearch
690697 = -- traceWhen r (show err) $
691698 r || proofSearch
692699 recoverableErr (CantSolveGoal _ _) = False
700+ recoverableErr (ProofSearchFail (Msg _)) = True
693701 recoverableErr (ProofSearchFail _) = False
694702 recoverableErr (ElaboratingArg _ _ _ e) = recoverableErr e
695703 recoverableErr (At _ e) = recoverableErr e
@@ -701,7 +709,7 @@ tryWhen False a b = a
701709
702710
703711-- 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
705713tryAll xs = tryAll' [] 999999 (cantResolve, 0) xs
706714 where
707715 cantResolve :: Elab' aux a
@@ -710,7 +718,7 @@ tryAll xs = tryAll' [] 999999 (cantResolve, 0) xs
710718 tryAll' :: [Elab' aux a] -> -- successes
711719 Int -> -- most problems
712720 (Elab' aux a, Int) -> -- smallest failure
713− [(Elab' aux a, String)] -> -- still to try
721+ [(Elab' aux a, Name)] -> -- still to try
714722 Elab' aux a
715723 tryAll' [res] pmax _ [] = res
716724 tryAll' (_:_) pmax _ [] = cantResolve
@@ -719,7 +727,7 @@ tryAll xs = tryAll' [] 999999 (cantResolve, 0) xs
719727 = do s <- get
720728 ps <- get_probs
721729 case prunStateT pmax True ps x s of
722− OK ((v, newps, probs), s') ->
730+ OK ((v, newps, probs), s') ->
723731 do let cs' = if (newps < pmax)
724732 then [do put s'; return $! v]
725733 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,
88 Context, initContext, ctxtAlist, uconstraints, next_tvar,
99 addToCtxt, setAccess, setTotal, setMetaInformation, addCtxtDef, addTyDecl,
1010 addDatatype, addCasedef, simplifyCasedef, addOperator,
11− lookupNames, lookupTy, lookupP, lookupDef, lookupDefExact, lookupDefAcc, lookupVal,
11+ lookupNames, lookupTyName, lookupTy, lookupP, lookupDef, lookupNameDef, lookupDefExact, lookupDefAcc, lookupVal,
1212 mapDefCtxt,
1313 lookupTotal, lookupNameTotal, lookupMetaInformation, lookupTyEnv, isDConName, isTConName, isConName, isFnName,
14− Value(..), Quote(..), initEval, uniqueNameCtxt, definitions) where
14+ Value(..), Quote(..), initEval, uniqueNameCtxt, uniqueBindersCtxt, definitions) where
1515
1616import Debug.Trace
1717import Control.Applicative hiding (Const)
@@ -537,7 +537,7 @@ wknV i t = return t
537537convEq' ctxt hs x y = evalStateT (convEq ctxt hs x y) (0, [])
538538
539539convEq :: 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
541541 ceq :: [(Name, Name)] -> TT Name -> TT Name -> StateT UCs (TC' Err) Bool
542542 ceq ps (P xt x _) (P yt y _)
543543 | x `elem` holes || y `elem` holes = return True
@@ -550,8 +550,12 @@ convEq ctxt holes = ceq [] where
550550 ceq ps (Bind n (Lam t) (App x (P Bound n' _))) y
551551 | n == n' = ceq ps x y
552552 ceq ps (V x) (V y) = return (x == y)
553− ceq ps (V x) (P _ y _) = return (fst (ps!!x) == y)
554− ceq ps (P _ x _) (V y) = return (x == snd (ps!!y))
553+ ceq ps (V x) (P _ y _)
554+ | x >= 0 && length ps > x = return (fst (ps!!x) == y)
555+ | otherwise = return False
556+ ceq ps (P _ x _) (V y)
557+ | y >= 0 && length ps > y = return (x == snd (ps!!y))
558+ | otherwise = return False
555559 ceq ps (Bind n xb xs) (Bind n' yb ys)
556560 = liftM2 (&&) (ceqB ps xb yb) (ceq ((n,n'):ps) xs ys)
557561 where
@@ -678,7 +682,7 @@ data Totality = Total [Int] -- ^ well-founded arguments
678682
679683-- | Reasons why a function may not be total
680684data PReason = Other [Name] | Itself | NotCovering | NotPositive | UseUndef Name
681− | BelieveMe | Mutual [Name] | NotProductive
685+ | ExternalIO | BelieveMe | Mutual [Name] | NotProductive
682686 deriving (Show, Eq)
683687
684688instance Show Totality where
@@ -688,6 +692,7 @@ instance Show Totality where
688692 show (Partial Itself) = "possibly not total as it is not well founded"
689693 show (Partial NotCovering) = "not total as there are missing cases"
690694 show (Partial NotPositive) = "not strictly positive"
695+ show (Partial ExternalIO) = "an external IO primitive"
691696 show (Partial NotProductive) = "not productive"
692697 show (Partial BelieveMe) = "not total due to use of believe_me in proof"
693698 show (Partial (Other ns)) = "possibly not total due to: " ++ showSep ", " (map show ns)
@@ -863,14 +868,19 @@ lookupNames n ctxt
863868 = let ns = lookupCtxtName n (definitions ctxt) in
864869 map fst ns
865870
866−lookupTy :: Name -> Context -> [Type]
867−lookupTy n ctxt
868− = do def <- lookupCtxt n (definitions ctxt)
869− case tfst def of
871+lookupTyName :: Name -> Context -> [(Name, Type)]
872+lookupTyName n ctxt = do
873+ (name, def) <- lookupCtxtName n (definitions ctxt)
874+ ty <- case tfst def of
870875 (Function ty _) -> return ty
871876 (TyDecl _ ty) -> return ty
872877 (Operator ty _ _) -> return ty
873878 (CaseOp _ ty _ _ _ _) -> return ty
879+ return (name, ty)
880+
881+
882+lookupTy :: Name -> Context -> [Type]
883+lookupTy n ctxt = map snd (lookupTyName n ctxt)
874884
875885isConName :: Name -> Context -> Bool
876886isConName n ctxt = isTConName n ctxt || isDConName n ctxt
@@ -916,6 +926,11 @@ lookupDefExact n ctxt = tfst <$> lookupCtxtExact n (definitions ctxt)
916926lookupDef :: Name -> Context -> [Def]
917927lookupDef n ctxt = tfst <$> lookupCtxt n (definitions ctxt)
918928
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+
919934lookupDefAcc :: Name -> Bool -> Context ->
920935 [(Def, Accessibility)]
921936lookupDefAcc n mkpublic ctxt
@@ -956,3 +971,10 @@ uniqueNameCtxt ctxt n hs
956971 | n `elem` hs = uniqueNameCtxt ctxt (nextName n) hs
957972 | [_] <- lookupTy n ctxt = uniqueNameCtxt ctxt (nextName n) hs
958973 | 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
1111import Idris.Core.Evaluate
1212import Idris.Core.CaseTree
1313
14+import Idris.Error
15+
1416import Debug.Trace
1517
1618import Util.DynamicLinker
@@ -113,9 +115,9 @@ initState :: Idris ExecState
113115initState = do ist <- getIState
114116 return $ ExecState (idris_dynamic_libs ist)
115117
116−type Exec = ErrorT String (StateT ExecState IO)
118+type Exec = ErrorT Err (StateT ExecState IO)
117119
118−runExec :: Exec a -> ExecState -> IO (Either String a)
120+runExec :: Exec a -> ExecState -> IO (Either Err a)
119121runExec ex st = fst <$> runStateT (runErrorT ex) st
120122
121123getExecState :: Exec ExecState
@@ -124,7 +126,7 @@ getExecState = lift get
124126putExecState :: ExecState -> Exec ()
125127putExecState = lift . put
126128
127−execFail :: String -> Exec a
129+execFail :: Err -> Exec a
128130execFail = throwError
129131
130132execIO :: IO a -> Exec a
@@ -138,7 +140,7 @@ execute tm = do est <- initState
138140 do res <- doExec [] ctxt tm
139141 toTT res
140142 case res of
141− Left err -> fail err
143+ Left err -> ierror err
142144 Right tm' -> return tm'
143145
144146ioWrap :: ExecVal -> ExecVal
@@ -160,16 +162,16 @@ doExec env ctxt p@(P Ref n ty) =
160162 [CaseOp _ _ _ _ _ (CaseDefs _ ([], STerm tm) _ _)] -> -- nullary fun
161163 doExec env ctxt tm
162164 [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."
164166 thing -> trace (take 200 $ "got to " ++ show thing ++ " lookup up " ++ show n) $ undefined
165167doExec env ctxt p@(P Bound n ty) =
166168 case lookup n env of
167− Nothing -> execFail "not found"
169+ Nothing -> execFail . Msg $ "not found"
168170 Just tm -> return tm
169171doExec env ctxt (P (DCon a b) n _) = return (EP (DCon a b) n EErased)
170172doExec env ctxt (P (TCon a b) n _) = return (EP (TCon a b) n EErased)
171173doExec 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"
173175doExec env ctxt (Bind n (Let t v) body) = do v' <- doExec env ctxt v
174176 doExec ((n, v'):env) ctxt body
175177doExec 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)
216218 | fp == pioret = execApp env ctxt (mkEApp con [tp, v]) rest
217219
218220-- 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)
220232 | fp == mkfprim,
221− Just (FFun "putStr" _ _) <- foreignFromTT fn
222− = do execIO (putStr arg)
223− execApp env ctxt ioUnit rest
224−execApp env ctxt (EP _ fp _) (_:fn:_:EHandle h:_:rest)
233+ Just (FFun "putchar" _ _) <- foreignFromTT fn
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))
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?"
243+execApp env ctxt (EP _ fp _) (_:fn:_:handle:_:rest)
225244 | fp == mkfprim,
226245 Just (FFun "idris_readStr" _ _) <- foreignFromTT fn
227− = do contents <- execIO $ hGetLine h
228− execApp env ctxt (EConstant (Str (contents ++ "\n"))) rest
229−execApp env ctxt (EP _ fp _) (_:fn:EConstant (Str f):EConstant (Str mode):rest)
246+ = case handle of
247+ EHandle h -> do contents <- execIO $ hGetLine h
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?"
253+execApp env ctxt (EP _ fp _) (_:fn:fileStr:modeStr:rest)
230254 | fp == mkfprim,
231255 Just (FFun "fileOpen" _ _) <- foreignFromTT fn
232− = do f <- execIO $
233− catch (do let m = case mode of
234− "r" -> Right ReadMode
235− "w" -> Right WriteMode
236− "a" -> Right AppendMode
237− "rw" -> Right ReadWriteMode
238− "wr" -> Right ReadWriteMode
239− "r+" -> Right ReadWriteMode
240− _ -> Left ("Invalid mode for " ++ f ++ ": " ++ mode)
241− case fmap (openFile f) m of
242− Right h -> do h' <- h; return $ Right (ioWrap (EHandle h'), tail rest)
243− Left err -> return $ Left err)
244− (\e -> let _ = ( e::SomeException)
245− in return $ Right (ioWrap (EPtr nullPtr), tail rest))
246− case f of
247− Left err -> execFail err
248− Right (res, rest) -> execApp env ctxt res rest
249−
250−execApp env ctxt (EP _ fp _) (_:fn:(EHandle h):rest)
256+ = case (fileStr, modeStr) of
257+ (EConstant (Str f), EConstant (Str mode)) ->
258+ do f <- execIO $
259+ catch (do let m = case mode of
260+ "r" -> Right ReadMode
261+ "w" -> Right WriteMode
262+ "a" -> Right AppendMode
263+ "rw" -> Right ReadWriteMode
264+ "wr" -> Right ReadWriteMode
265+ "r+" -> Right ReadWriteMode
266+ _ -> Left ("Invalid mode for " ++ f ++ ": " ++ mode)
267+ case fmap (openFile f) m of
268+ Right h -> do h' <- h; return $ Right (ioWrap (EHandle h'), tail rest)
269+ Left err -> return $ Left err)
270+ (\e -> let _ = ( e::SomeException)
271+ in return $ Right (ioWrap (EPtr nullPtr), tail rest))
272+ case f of
273+ Left err -> execFail . Msg $ err
274+ Right (res, rest) -> execApp env ctxt res rest
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+
280+execApp env ctxt (EP _ fp _) (_:fn:handle:rest)
251281 | fp == mkfprim,
252282 Just (FFun "fileEOF" _ _) <- foreignFromTT fn
253− = do eofp <- execIO $ hIsEOF h
254− let res = ioWrap (EConstant (I $ if eofp then 1 else 0))
255− execApp env ctxt res (tail rest)
256−
257−execApp env ctxt (EP _ fp _) (_:fn:(EHandle h):rest)
283+ = case handle of
284+ EHandle h -> do eofp <- execIO $ hIsEOF h
285+ let res = ioWrap (EConstant (I $ if eofp then 1 else 0))
286+ execApp env ctxt res (tail rest)
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+
292+execApp env ctxt (EP _ fp _) (_:fn:handle:rest)
258293 | fp == mkfprim,
259294 Just (FFun "fileClose" _ _) <- foreignFromTT fn
260− = do execIO $ hClose h
261− execApp env ctxt ioUnit (tail rest)
262−
263−execApp env ctxt (EP _ fp _) (_:fn:(EPtr p):rest)
295+ = case handle of
296+ EHandle h -> do execIO $ hClose h
297+ execApp env ctxt ioUnit (tail rest)
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+
303+execApp env ctxt (EP _ fp _) (_:fn:ptr:rest)
264304 | fp == mkfprim,
265305 Just (FFun "isNull" _ _) <- foreignFromTT fn
266− = let res = ioWrap . EConstant . I $
267− if p == nullPtr then 1 else 0
268− in execApp env ctxt res (tail rest)
306+ = case ptr of
307+ EPtr p -> let res = ioWrap . EConstant . I $
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
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?"
269321
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)
284322
285323-- Right now, there's no way to send command-line arguments to the executor,
286324-- so just return 0.
@@ -289,7 +327,6 @@ execApp env ctxt (EP _ fp _) (_:fn:rest)
289327 Just (FFun "idris_numArgs" _ _) <- foreignFromTT fn
290328 = let res = ioWrap . EConstant . I $ 0
291329 in execApp env ctxt res (tail rest)
292−-- Throw away the 'World' argument to the foreign function
293330
294331execApp env ctxt f@(EP _ fp _) args@(ty:fn:xs) | fp == mkfprim
295332 = case foreignFromTT fn of
src/Idris/Core/ProofState.hs+53−13
@@ -15,7 +15,7 @@ import Idris.Core.Unify
1515
1616import Control.Monad.State.Strict
1717import Control.Applicative hiding (empty)
18−import Control.Arrow (first)
18+import Control.Arrow ((***))
1919import Data.List
2020import Debug.Trace
2121
@@ -59,6 +59,7 @@ data Tactic = Attack
5959 | Solve
6060 | StartUnify Name
6161 | EndUnify
62+ | UnifyAll
6263 | Compute
6364 | ComputeLet Name
6465 | Simplify
@@ -179,6 +180,19 @@ match_unify' ctxt env topx topy =
179180-- -- ++ show (pterm ps)
180181-- ++ "\n----------") $
181182
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+
182196unify' :: Context -> Env -> TT Name -> TT Name ->
183197 StateT TState TC [(Name, TT Name)]
184198unify' ctxt env topx topy =
@@ -205,16 +219,22 @@ unify' ctxt env topx topy =
205219 ++ "\nCurrent problems:\n" ++ qshow (problems ps)
206220-- ++ show (pterm ps)
207221 ++ "\n----------") $
208− do ps <- get
209− let (h, ns) = unified ps
210− let (ns', probs') = updateProblems (context ps) (u ++ ns)
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
227+ let (ns', probs') = updateProblems (context ps) uns
211228 (fails ++ problems ps)
212229 (injective ps)
213230 (holes ps)
214− put (ps { problems = probs',
215− unified = (h, ns'),
216− injective = updateInj u (injective ps),
217− notunified = notu ++ notunified ps })
231+ let (notu', probs_notu) = mergeNotunified env (notu ++ notunified ps)
232+ traceWhen (unifylog ps)
233+ ("Now solved: " ++ show ns') $
234+ put (ps { problems = probs' ++ probs_notu,
235+ unified = (h, ns'),
236+ injective = updateInj u (injective ps),
237+ notunified = notu' })
218238 return u
219239 where updateInj ((n, a) : us) inj
220240 | (P _ n' _, _) <- unApply a,
@@ -664,7 +684,7 @@ induction nm ctxt env (Bind x (Hole t) (P _ x' _)) | x == x' = do
664684 let scr = last $ tail args'
665685 let indxnames = makeIndexNames indicies
666686 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)
668688 let res = flip (foldr substV) params $ (substV prop $ bindConsArgs consargs' (mkApp (P Ref (SN (ElimN tnm)) (TType (UVal 0)))
669689 (params ++ [prop] ++ map makeConsArg consargs' ++ indicies ++ [tmv])))
670690 action (\ps -> ps {holes = holes ps \\ [x]})
@@ -781,13 +801,15 @@ keepGiven du (u@(n, _) : us) hs
781801 | n `elem` du = u : keepGiven du us hs
782802keepGiven du (u : us) hs = keepGiven du us hs
783803
804+updateSolved :: [(Name, Term)] -> Term -> Term
784805updateSolved xs x = updateSolved' xs x
785806updateSolved' [] x = x
786807updateSolved' xs (Bind n (Hole ty) t)
787808 | Just v <- lookup n xs
788809 = case xs of
789− [_] -> psubst n v t
790− _ -> psubst n v (updateSolved' xs t)
810+ [_] -> substV v $ psubst n v t -- some may be Vs! Can't assume
811+ -- explicit names
812+ _ -> substV v $ psubst n v (updateSolved' xs t)
791813updateSolved' xs (Bind n b t)
792814 | otherwise = Bind n (fmap (updateSolved' xs) b) (updateSolved' xs t)
793815updateSolved' xs (App f a)
@@ -801,6 +823,10 @@ updateEnv ns [] = []
801823updateEnv ns ((n, b) : env) = (n, fmap (updateSolved ns) b) : updateEnv ns env
802824
803825updateError [] 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)
804830updateError ns (CantUnify b l r e xs sc)
805831 = CantUnify b (updateSolved ns l) (updateSolved ns r) (updateError ns e) xs sc
806832updateError ns e = e
@@ -810,6 +836,15 @@ solveInProblems x val ((l, r, env, err) : ps)
810836 = ((psubst x val l, psubst x val r,
811837 updateEnv [(x, val)] env, err) : solveInProblems x val ps)
812838
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+
813848updateNotunified [] nu = nu
814849updateNotunified ns nu = up nu where
815850 up [] = []
@@ -826,7 +861,7 @@ updateProblems ctxt ns ps inj holes = up ns ps where
826861 y' = updateSolved ns y
827862 err' = updateError ns err
828863 env' = updateEnv ns env in
829−-- trace ("Updating " ++ show (x',y')) $
864+-- trace ("Updating " ++ show (x',y')) $
830865 case unify ctxt env' x' y' inj holes while of
831866 OK (v, []) -> -- trace ("Added " ++ show v ++ " from " ++ show (x', y')) $
832867 up (ns ++ v) ps
@@ -860,7 +895,7 @@ processTactic QED ps = case holes ps of
860895 _ -> fail "Still holes to fill."
861896processTactic ProofState ps = return (ps, showEnv [] (pterm ps))
862897processTactic Undo ps = case previous ps of
863− Nothing -> fail "Nothing to undo."
898+ Nothing -> Error . Msg $ "Nothing to undo."
864899 Just pold -> return (pold, "")
865900processTactic EndUnify ps
866901 = let (h, ns_in) = unified ps
@@ -874,6 +909,11 @@ processTactic EndUnify ps
874909 problems = probs',
875910 notunified = updateNotunified ns'' (notunified ps),
876911 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) }, "")
877917processTactic (Reorder n) ps
878918 = do ps' <- execStateT (tactic (Just n) reorder_claims) ps
879919 return (ps' { previous = Just ps, plog = "" }, plog ps')
src/Idris/Core/TC.hs+9
@@ -2,6 +2,7 @@
22
33module Idris.Core.TC(TC'(..)) where
44
5+import Control.Applicative
56import Control.Monad
67import Control.Monad.Trans.Error(Error(..))
78
@@ -26,3 +27,11 @@ instance Error e => MonadPlus (TC' e) where
2627 _ `mplus` (OK y) = OK y
2728 err `mplus` _ = err
2829
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(..))
2727import Debug.Trace
2828import qualified Data.Map.Strict as Map
2929import Data.Char
30+import Numeric (showIntAtBase)
3031import qualified Data.Text as T
3132import Data.List
3233import Data.Maybe (listToMaybe)
@@ -82,7 +83,7 @@ instance Show FC where
8283 | otherwise = show sl ++ ":" ++ show sc ++ "-" ++ show el ++ ":" ++ show ec
8384
8485-- | Output annotation for pretty-printed name - decides colour
85−data NameOutput = TypeOutput | FunOutput | DataOutput | MetavarOutput
86+data NameOutput = TypeOutput | FunOutput | DataOutput | MetavarOutput | PostulateOutput
8687
8788-- | Text formatting output
8889data TextFormatting = BoldText | ItalicText | UnderlineText
@@ -92,8 +93,9 @@ data OutputAnnotation = AnnName Name (Maybe NameOutput) (Maybe String) (Maybe St
9293 -- ^^ The name, classification, docs overview, and pretty-printed type
9394 | AnnBoundName Name Bool
9495 -- ^^ The name and whether it is implicit
95− | AnnConstData
96− | AnnConstType
96+ | AnnConst Const
97+ | AnnData String String -- ^ type, doc overview
98+ | AnnType String String -- ^ name, doc overview
9799 | AnnKeyword
98100 | AnnFC FC
99101 | AnnTextFmt TextFormatting
@@ -131,7 +133,7 @@ data Err' t
131133 | NoTypeDecl Name
132134 | NotInjective t t t
133135 | CantResolve t
134− | CantResolveAlts [String]
136+ | CantResolveAlts [Name]
135137 | IncompleteTerm t
136138 | UniverseError
137139 | ProgramLineComment
@@ -182,9 +184,12 @@ score :: Err -> Int
182184score (CantUnify _ _ _ m _ s) = s + score m
183185score (CantResolve _) = 20
184186score (NoSuchVariable _) = 1000
185−score (ProofSearchFail _) = 10000
186−score (CantSolveGoal _ _) = 10000
187+score (ProofSearchFail e) = score e
188+score (CantSolveGoal _ _) = 100000
187189score (InternalMsg _) = -1
190+score (At _ e) = score e
191+score (ElaboratingArg _ _ _ e) = score e
192+score (Elaborating _ _ e) = score e
188193score _ = 0
189194
190195instance Show Err where
@@ -201,6 +206,7 @@ instance Show Err where
201206 show (ElaboratingArg f x prev e) = "Elaborating " ++ show f ++ " arg " ++
202207 show x ++ ": " ++ show e
203208 show (Elaborating what n e) = "Elaborating " ++ what ++ show n ++ ":" ++ show e
209+ show (ProofSearchFail e) = "Proof search fail: " ++ show e
204210 show _ = "Error"
205211
206212instance Pretty Err OutputAnnotation where
@@ -256,7 +262,7 @@ traceWhen False _ a = a
256262data Name = UN T.Text -- ^ User-provided name
257263 | NS Name [T.Text] -- ^ Root, namespaces
258264 | 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
260266 | SN SpecialName -- ^ Decorated function names
261267 | SymRef Int -- ^ Reference to IBC file symbol table (used during serialisation)
262268 deriving (Eq, Ord)
@@ -383,6 +389,7 @@ implicitable _ = False
383389nsroot (NS n _) = n
384390nsroot n = n
385391
392+-- this will overwrite already existing definitions
386393addDef :: Name -> a -> Ctxt a -> Ctxt a
387394addDef n v ctxt = case Map.lookup (nsroot n) ctxt of
388395 Nothing -> Map.insert (nsroot n)
@@ -425,6 +432,9 @@ lookupCtxt n ctxt = map snd (lookupCtxtName n ctxt)
425432lookupCtxtExact :: Name -> Ctxt a -> Maybe a
426433lookupCtxtExact n ctxt = listToMaybe [ v | (nm, v) <- lookupCtxtName n ctxt, nm == n]
427434
435+deleteDefExact :: Name -> Ctxt a -> Ctxt a
436+deleteDefExact n = Map.adjust (Map.delete n) (nsroot n)
437+
428438updateDef :: Name -> (a -> a) -> Ctxt a -> Ctxt a
429439updateDef n f ctxt
430440 = let ds = lookupCtxtName n ctxt in
@@ -432,7 +442,7 @@ updateDef n f ctxt
432442
433443toAlist :: Ctxt a -> [(Name, a)]
434444toAlist ctxt = let allns = map snd (Map.toList ctxt) in
435− concat (map (Map.toList) allns)
445+ concatMap (Map.toList) allns
436446
437447addAlist :: Show a => [(Name, a)] -> Ctxt a -> Ctxt a
438448addAlist [] ctxt = ctxt
@@ -520,6 +530,60 @@ instance Pretty Const OutputAnnotation where
520530 pretty (B32 w) = text . show $ w
521531 pretty (B64 w) = text . show $ w
522532
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+
523587data Raw = Var Name
524588 | RBind Name (Binder Raw) Raw
525589 | RApp Raw Raw
@@ -996,8 +1060,9 @@ uniqueName n hs | n `elem` hs = uniqueName (nextName n) hs
9961060
9971061uniqueBinders :: [Name] -> TT Name -> TT Name
9981062uniqueBinders ns (Bind n b sc)
999− = let n' = uniqueName n ns in
1000− Bind n' (fmap (uniqueBinders (n':ns)) b) (uniqueBinders ns sc)
1063+ = let n' = uniqueName n ns
1064+ ns' = n' : ns in
1065+ Bind n' (fmap (uniqueBinders ns') b) (uniqueBinders ns' sc)
10011066uniqueBinders ns (App f a) = App (uniqueBinders ns f) (uniqueBinders ns a)
10021067uniqueBinders ns t = t
10031068
@@ -1222,3 +1287,12 @@ orderPats tm = op [] tm
12221287 = (n', t') : insert n t ps
12231288 | otherwise = (n,t):(n',t'):ps
12241289
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 =
6969 return (map (renameBinders env) (trimSolutions v))
7070 _ -> tfail e
7171 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)
7386
7487 un names (P _ x _) tm
7588 | holeIn env x || x `elem` holes
@@ -85,7 +98,7 @@ match_unify ctxt env topx topy inj holes from =
8598 | length bnames > i,
8699 fst (fst (bnames!!i)) == x ||
87100 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
89102 = do h1 <- uB bnames bx by
90103 h2 <- un (((x, y), binderTy bx) : bnames) sx sy
91104 combine bnames h1 h2
@@ -119,6 +132,9 @@ match_unify ctxt env topx topy inj holes from =
119132 put (UI s ((binderTy x, binderTy y, env, err, from, Match) : f))
120133 return []
121134
135+ notHole (Hole _) = False
136+ notHole _ = True
137+
122138 -- TODO: there's an annoying amount of repetition between this and the
123139 -- main unification function. Consider lifting it out.
124140
@@ -173,7 +189,7 @@ renameBindersTm env tm = uniqueBinders (map fst env) tm
173189 uniqueBinders env (Bind n b sc)
174190 | n `elem` env
175191 = let n' = uniqueName n env in
176− Bind n' (fmap (uniqueBinders env) b)
192+ explicitHole $ Bind n' (fmap (uniqueBinders env) b)
177193 (uniqueBinders (n':env) (rename n n' sc))
178194 | otherwise = Bind n (fmap (uniqueBinders (n:env)) b)
179195 (uniqueBinders (n:env) sc)
@@ -185,6 +201,10 @@ renameBindersTm env tm = uniqueBinders (map fst env) tm
185201 rename n n' (App f a) = App (rename n n' f) (rename n n' a)
186202 rename n n' t = t
187203
204+ explicitHole (Bind n (Hole ty) sc)
205+ = Bind n (Hole ty) (instantiate (P Bound n ty) sc)
206+ explicitHole t = t
207+
188208trimSolutions ns = dropPairs ns
189209 where dropPairs [] = []
190210 dropPairs (n@(x, P _ x' _) : ns)
@@ -204,11 +224,16 @@ expandLets env (x, tm) = (x, doSubst (reverse env) tm)
204224 doSubst (_ : env) tm
205225 = doSubst env tm
206226
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
207231
208232unify :: Context -> Env -> TT Name -> TT Name -> [Name] -> [Name] -> [FailContext] ->
209233 TC ([(Name, TT Name)], Fails)
210234unify ctxt env topx topy inj holes from =
211−-- trace ("Unifying " ++ show (topx, topy)) $
235+-- traceWhen (hasv topx || hasv topy)
236+-- ("Unifying " ++ show topx ++ "\nAND\n" ++ show topy ++ "\n") $
212237 -- don't bother if topx and topy are different at the head
213238 case runStateT (un False [] (renameBindersTm env topx)
214239 (renameBindersTm env topy)) (UI 0 []) of
@@ -295,7 +320,7 @@ unify ctxt env topx topy inj holes from =
295320 | injective ty && not (holeIn env x || x `elem` holes)
296321 = unifyTmpFail tx ty
297322 un' fn bnames xtm@(P _ x _) tm
298− | holeIn env x || x `elem` holes
323+ | pureTerm tm, holeIn env x || x `elem` holes
299324 = do UI s f <- get
300325 -- injectivity check
301326 x <- checkCycle bnames (x, tm)
@@ -305,11 +330,11 @@ unify ctxt env topx topy inj holes from =
305330 then unifyTmpFail xtm tm
306331 else do sc 1
307332 return x
308− | not (injective xtm) && injective tm
333+ | pureTerm tm, not (injective xtm) && injective tm
309334 = do checkCycle bnames (x, tm)
310335 unifyTmpFail xtm tm
311336 un' fn bnames tm ytm@(P _ y _)
312− | holeIn env y || y `elem` holes
337+ | pureTerm tm, holeIn env y || y `elem` holes
313338 = do UI s f <- get
314339 -- injectivity check
315340 x <- checkCycle bnames (y, tm)
@@ -319,7 +344,7 @@ unify ctxt env topx topy inj holes from =
319344 then unifyTmpFail tm ytm
320345 else do sc 1
321346 return x
322− | not (injective ytm) && injective tm
347+ | pureTerm tm, not (injective ytm) && injective tm
323348 = do checkCycle bnames (y, tm)
324349 unifyTmpFail tm ytm
325350 un' fn bnames (V i) (P _ x _)
@@ -524,7 +549,7 @@ unify ctxt env topx topy inj holes from =
524549 | not (x `elem` freeNames tm) = checkScope ns (x, tm)
525550 | otherwise = lift $ tfail (InfiniteUnify x tm (errEnv env))
526551
527− checkScope ns (x, tm) =
552+ checkScope ns (x, tm) | pureTerm tm =
528553-- case boundVs (envPos x 0 env) tm of
529554-- [] -> return [(x, tm)]
530555-- (i:_) -> lift $ tfail (UnifyScope x (fst (fst (ns!!i)))
@@ -535,6 +560,7 @@ unify ctxt env topx topy inj holes from =
535560 else return [(x, bind v ns tm)]
536561 where inst [] tm = tm
537562 inst (((n, _), _) : ns) tm = inst ns (substV (P Bound n Erased) tm)
563+ checkScope ns (x, tm) = lift $ tfail (Msg "HOLE ERROR")
538564
539565 bind i ns tm
540566 | i < 0 = tm
@@ -588,12 +614,8 @@ recoverable t@(App _ _) _
588614 | (P _ (UN l) _, _) <- unApply t, l == txt "Lazy" = False
589615recoverable _ t@(App _ _)
590616 | (P _ (UN l) _, _) <- unApply t, l == txt "Lazy" = False
591−recoverable (P (DCon _ _) x _) (P (DCon _ _) y _)
592− | x == y = True
593− | otherwise = False
594−recoverable (P (TCon _ _) x _) (P (TCon _ _) y _)
595− | x == y = True
596− | otherwise = False
617+recoverable (P (DCon _ _) x _) (P (DCon _ _) y _) = x == y
618+recoverable (P (TCon _ _) x _) (P (TCon _ _) y _) = x == y
597619recoverable (Constant _) (P (DCon _ _) y _) = False
598620recoverable (P (DCon _ _) x _) (Constant _) = False
599621recoverable (Constant _) (P (TCon _ _) y _) = False
@@ -612,7 +634,9 @@ recoverable f (Bind _ (Pi _) sc)
612634recoverable (Bind _ (Pi _) sc) f
613635 | (P (DCon _ _) _ _, _) <- unApply f = False
614636 | (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
616640
617641errEnv = map (\(x, b) -> (x, binderTy b))
618642
src/Idris/Coverage.hs+52−26
@@ -9,7 +9,7 @@ import Idris.Core.CaseTree
99import Idris.AbsSyntax
1010import Idris.Delaborate
1111import Idris.Error
12−import Idris.Output (iputStrLn)
12+import Idris.Output (iWarn, iputStrLn)
1313
1414import Data.List
1515import Data.Either
@@ -211,7 +211,7 @@ genAll i args
211211 let p = resugar (PApp fc (PRef fc n) (zipWith upd xs' xs))
212212 let tyn = getTy n (tt_ctxt i)
213213 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])
215215 _ -> [p]
216216 ops fc n arg o = return Placeholder
217217
@@ -253,39 +253,50 @@ checkAllCovering :: FC -> [Name] -> Name -> Name -> Idris ()
253253checkAllCovering fc done top n | not (n `elem` done)
254254 = do i <- get
255255 case lookupTotal n (tt_ctxt i) of
256− [tot@(Partial NotCovering)] ->
257− tclift $ tfail (At fc (Msg (show top ++ " is " ++ show tot
258− ++ " due to " ++ show n)))
259− _ -> return ()
260− case lookupCtxt n (idris_callgraph i) of
261− [cg] -> mapM_ (checkAllCovering fc (n : done) top)
262− (map fst (calls cg))
263− _ -> return ()
256+ [tot@(Partial NotCovering)] ->
257+ do let msg = show top ++ " is " ++ show tot ++ " due to " ++ show n
258+ putIState i { idris_totcheckfail = (fc, msg) : idris_totcheckfail i }
259+ addIBC (IBCTotCheckErr fc msg)
260+ [Partial _] ->
261+ case lookupCtxt n (idris_callgraph i) of
262+ [cg] -> mapM_ (checkAllCovering fc (n : done) top)
263+ (map fst (calls cg))
264+ _ -> return ()
265+ x -> return () -- stop if total
264266checkAllCovering _ _ _ _ = return ()
265267
266−-- Check if, in a given type n, the constructor cn : ty is strictly positive,
268+-- Check if, in a given group of type declarations mut_ns,
269+-- the constructor cn : ty is strictly positive,
267270-- and update the context accordingly
268271
269−checkPositive :: Name -> (Name, Type) -> Idris ()
270−checkPositive n (cn, ty')
271− = do let ty = delazy ty'
272+checkPositive :: [Name] -> (Name, Type) -> Idris Totality
273+checkPositive mut_ns (cn, ty')
274+ = do let ty = delazy' True ty'
272275 let p = cp ty
273276 i <- getIState
274277 let tot = if p then Total (args ty) else Partial NotPositive
275278 let ctxt' = setTotal cn tot (tt_ctxt i)
276279 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
278281 addIBC (IBCTotal cn tot)
282+ return tot
279283 where
280284 args t = [0..length (getArgTys t)-1]
281285
282286 cp (Bind n (Pi aty) sc) = posArg aty && cp sc
283− cp t = True
287+ cp t | (P _ n' _, args) <- unApply t,
288+ n' `elem` mut_ns = all noRec args
289+ cp _ = True
284290
285291 posArg (Bind _ (Pi nty) sc)
286292 | (P _ n' _, args) <- unApply nty
287− = n /= n' && posArg sc
288− posArg t = True
293+ = n' `notElem` mut_ns && all noRec args && posArg sc
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+
289300
290301calcProd :: IState -> FC -> Name -> [([Name], Term, Term)] -> Idris Totality
291302calcProd i fc topn pats
@@ -333,7 +344,7 @@ calcProd i fc topn pats
333344 cotype (DCon _ _) n ty
334345 | (P _ t _, _) <- unApply (getRetTy ty)
335346 = case lookupCtxt t (idris_datatypes i) of
336− [TI _ True _ _] -> True
347+ [TI _ True _ _ _] -> True
337348 _ -> False
338349 cotype nt n ty = False
339350
@@ -381,6 +392,14 @@ checkTotality path fc n
381392 setTotality n t'
382393 addIBC (IBCTotal n t')
383394 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 []
384403 _ -> return $ Total []
385404 x -> return x
386405 case t' of
@@ -388,18 +407,21 @@ checkTotality path fc n
388407 Productive -> return t'
389408 e -> do w <- cmdOptType WarnPartial
390409 if TotalFn `elem` opts
391− then totalityError t'
410+ then do totalityError t'; return t'
392411 else do when (w && not (PartialFn `elem` opts)) $
393412 warnPartial n t'
394413 return t'
395414 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)
397419
398420 warnPartial n t
399421 = do i <- getIState
400422 case lookupDef n (tt_ctxt i) of
401423 [x] -> do
402− iputStrLn $ show fc ++ ":Warning - " ++ show n ++ " is " ++ show t
424+ iWarn fc . pprintErr i . Msg $ "Warning - " ++ show n ++ " is " ++ show t
403425-- ++ "\n" ++ show x
404426-- let cg = lookupCtxtName Nothing n (idris_callgraph i)
405427-- iputStrLn (show cg)
@@ -410,7 +432,11 @@ checkDeclTotality (fc, n)
410432 = do logLvl 2 $ "Checking " ++ show n ++ " for totality"
411433-- buildSCG (fc, n)
412434-- 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
414440 t <- checkTotality [] fc n
415441 case t of
416442 -- if it's not total, it can't reduce, to keep
@@ -517,7 +543,7 @@ buildSCG' ist pats args = nub $ concatMap scgPat pats where
517543 -- find which argument in pargs <a> is smaller than, if any
518544 checkSize a (p : ps) i
519545 | a == p = Just (i, Same)
520− | (P _ (UN as) _, [_,arg,_]) <- unApply a,
546+ | (P _ (UN as) _, [_,_,arg,_]) <- unApply a,
521547 as == txt "assert_smaller" && arg == p
522548 = Just (i, Smaller)
523549 | smaller Nothing a (p, Nothing) = Just (i, Smaller)
@@ -547,7 +573,7 @@ buildSCG' ist pats args = nub $ concatMap scgPat pats where
547573
548574 isInductive (P _ nty _) (P _ nty' _) =
549575 let co = case lookupCtxt nty (idris_datatypes ist) of
550− [TI _ x _ _] -> x
576+ [TI _ x _ _ _] -> x
551577 _ -> False in
552578 nty == nty' && not co
553579 isInductive _ _ = False
@@ -630,7 +656,7 @@ checkMP ist i mp = if i > 0
630656 = case lookupTotal f (tt_ctxt ist) of
631657 [Total _] -> Unchecked -- okay so far
632658 [Partial _] -> Partial (Other [f])
633− x -> error (show x)
659+ x -> error $ "CAN'T HAPPEN: " ++ (show x)
634660 | [TyDecl (TCon _ _) _] <- lookupDef f (tt_ctxt ist)
635661 = Total []
636662 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
138138 rnf x3 `seq` rnf x4 `seq` rnf x5 `seq` rnf x6 `seq` ()
139139 rnf (PParams x1 x2 x3) = rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` ()
140140 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)
142142 = rnf x1 `seq`
143143 rnf x2 `seq`
144144 rnf x3 `seq`
145− rnf x4 `seq` rnf x5 `seq` rnf x6 `seq` rnf x7 `seq` rnf x8 `seq` ()
146− rnf (PClass x1 x2 x3 x4 x5 x6 x7)
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 x8 x7)
147147 = rnf x1 `seq`
148148 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` ()
150150 rnf (PInstance x1 x2 x3 x4 x5 x6 x7 x8)
151151 = rnf x1 `seq`
152152 rnf x2 `seq`
@@ -156,16 +156,14 @@ instance (NFData t) => NFData (PDecl' t) where
156156 rnf (PSyntax x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
157157 rnf (PMutual x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
158158 rnf (PDirective x1) = ()
159− rnf (PProvider x1 x2 x3 x4 x5 x6)
160− = rnf x1 `seq`
161− rnf x2 `seq` rnf x3 `seq` rnf x4 `seq` rnf x5 `seq` rnf x6 `seq` ()
159+ rnf (PProvider x1 x2 x3 x4)
160+ = rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` rnf x4 `seq` ()
162161 rnf (PTransform x1 x2 x3 x4)
163162 = rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` rnf x4 `seq` ()
164163
165−instance NFData ProvideWhat where
166− rnf ProvAny = ()
167− rnf ProvTerm = ()
168− rnf ProvPostulate = ()
164+instance NFData t => NFData (ProvideWhat' t) where
165+ rnf (ProvTerm ty tm) = rnf ty `seq` rnf tm `seq` ()
166+ rnf (ProvPostulate tm) = rnf tm `seq` ()
169167
170168instance NFData PunInfo where
171169 rnf x = x `seq` ()
@@ -245,7 +243,7 @@ instance (NFData t) => NFData (PTactic' t) where
245243 rnf (Exact x1) = rnf x1 `seq` ()
246244 rnf Compute = ()
247245 rnf Trivial = ()
248− rnf (ProofSearch x1 x2)
246+ rnf (ProofSearch r r1 r2 x1 x2)
249247 = rnf x1 `seq` rnf x2 `seq` ()
250248 rnf Solve = ()
251249 rnf Attack = ()
@@ -290,7 +288,7 @@ instance NFData OptInfo where
290288 = rnf x1 `seq` rnf x2 `seq` ()
291289
292290instance 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` ()
294292
295293instance (NFData t) => NFData (DSL' t) where
296294 rnf (DSL x1 x2 x3 x4 x5 x6 x7 x8 x9)
@@ -321,11 +319,11 @@ instance NFData Using where
321319
322320
323321instance 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)
325323 = rnf x1 `seq`
326324 rnf x2 `seq`
327325 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` ()
329327
330328
331329
src/Idris/Delaborate.hs+31−6
@@ -1,5 +1,5 @@
11{-# 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
33
44-- Convert core TT back into high level syntax, primarily for display
55-- purposes.
@@ -9,6 +9,7 @@ import Util.Pretty
99import Idris.AbsSyntax
1010import Idris.Core.TT
1111import Idris.Core.Evaluate
12+import Idris.Docstrings (overview, renderDocstring)
1213import Idris.ErrReverse
1314
1415import Data.List (intersperse)
@@ -92,13 +93,13 @@ delabTy' ist imps tm fullname mvs = de [] imps tm
9293 | n == eqCon = PRefl un (de env [] r)
9394 | n == sUN "lazy" = de env [] r
9495 deFn env (P _ n _) [ty, Bind x (Lam _) r]
95− | n == sUN "Exists"
96+ | n == sUN "Sigma"
9697 = PDPair un IsType (PRef un x) (de env [] ty)
9798 (de ((x,x):env) [] (instantiate (P Bound x ty) r))
9899 deFn env (P _ n _) [_,_,l,r]
99100 | n == pairCon = PPair un IsTerm (de env [] l) (de env [] r)
100101 | 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
102103 (de env [] r)
103104 deFn env f@(P _ n _) args
104105 | n `elem` map snd env
@@ -138,7 +139,7 @@ pprintTerm :: IState -> PTerm -> Doc OutputAnnotation
138139pprintTerm ist = pprintTerm' ist []
139140
140141pprintTerm' :: 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
142143
143144pprintErr :: IState -> Err -> Doc OutputAnnotation
144145pprintErr i err = pprintErr' i (fmap (errReverse i) err)
@@ -195,7 +196,7 @@ pprintErr' i (NotInjective p x y) =
195196 pprintTerm i (delab i y)
196197pprintErr' i (CantResolve c) = text "Can't resolve type class" <+> pprintTerm i (delab i c)
197198pprintErr' 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)))
199200pprintErr' i (NoTypeDecl n) = text "No type declaration for" <+> annName n
200201pprintErr' i (NoSuchVariable n) = text "No such variable" <+> annName n
201202pprintErr' i (IncompleteTerm t) = text "Incomplete term" <+> pprintTerm i (delab i t)
@@ -258,6 +259,30 @@ annName n = annName' n (showbasic n)
258259annName' :: Name -> String -> Doc OutputAnnotation
259260annName' n str = annotate (AnnName n Nothing Nothing Nothing) (text str)
260261
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+
261286showSc :: IState -> [(Name, Term)] -> Doc OutputAnnotation
262287showSc i [] = empty
263288showSc i xs = line <> line <> text "In context:" <>
@@ -269,7 +294,7 @@ showSc i xs = line <> line <> text "In context:" <>
269294
270295
271296showqual :: 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)
273298 where
274299 dens ns@(NS n _) = case lookupCtxt n (idris_implicits i) of
275300 [_] -> n -- just one thing
src/Idris/Docs.hs+100−24
@@ -1,5 +1,5 @@
11{-# LANGUAGE PatternGuards #-}
2−module Idris.Docs where
2+module Idris.Docs (pprintDocs, getDocs, pprintConstDocs, FunDoc(..), Docs (..)) where
33
44import Idris.AbsSyntax
55import Idris.AbsSyntaxTree
@@ -27,16 +27,19 @@ data Docs = FunDoc FunDoc
2727 [FunDoc] -- data constructor docs
2828 | ClassDoc Name Docstring -- class docs
2929 [FunDoc] -- method docs
30+ [(Name, Maybe Docstring)] -- parameters and their docstrings
31+ [PTerm] -- instances
32+ [PTerm] -- superclasses
3033 deriving Show
3134
3235showDoc d | nullDocstring d = empty
3336 | otherwise = text " -- " <> renderDocstring d
3437
35−pprintFD :: Bool -> FunDoc -> Doc OutputAnnotation
36−pprintFD imp (FD n doc args ty f)
37− = nest 4 (prettyName imp [] n <+> colon <+>
38− pprintPTerm imp [] [ n | (n@(UN n'),_,_,_) <- args
39− , not (T.isPrefixOf (T.pack "__") n') ] ty <$>
38+pprintFD :: IState -> FunDoc -> Doc OutputAnnotation
39+pprintFD ist (FD n doc args ty f)
40+ = nest 4 (prettyName (ppopt_impl ppo) [] n <+> colon <+>
41+ pprintPTerm ppo [] [ n | (n@(UN n'),_,_,_) <- args
42+ , not (T.isPrefixOf (T.pack "__") n') ] infixes ty <$>
4043 renderDocstring doc <$>
4144 maybe empty (\f -> text (show f) <> line) f <>
4245 let argshow = showArgs args [] in
@@ -44,21 +47,23 @@ pprintFD imp (FD n doc args ty f)
4447 then nest 4 $ text "Arguments:" <$> vsep argshow
4548 else empty)
4649
47− where showArgs ((n, ty, Exp {}, Just d):args) bnd
50+ where ppo = ppOptionIst ist
51+ infixes = idris_infixes ist
52+ showArgs ((n, ty, Exp {}, Just d):args) bnd
4853 = bindingOf n False <+> colon <+>
49− pprintPTerm imp bnd [] ty <>
54+ pprintPTerm ppo bnd [] infixes ty <>
5055 showDoc d <> line
5156 :
5257 showArgs args ((n, False):bnd)
5358 showArgs ((n, ty, Constraint {}, Just d):args) bnd
5459 = text "Class constraint" <+>
55− pprintPTerm imp bnd [] ty <> showDoc d <> line
60+ pprintPTerm ppo bnd [] infixes ty <> showDoc d <> line
5661 :
5762 showArgs args ((n, True):bnd)
5863 showArgs ((n, ty, Imp {}, Just d):args) bnd
5964 = text "(implicit)" <+>
6065 bindingOf n True <+> colon <+>
61− pprintPTerm imp bnd [] ty <>
66+ pprintPTerm ppo bnd [] infixes ty <>
6267 showDoc d <> line
6368 :
6469 showArgs args ((n, True):bnd)
@@ -66,16 +71,68 @@ pprintFD imp (FD n doc args ty f)
6671 showArgs [] _ = []
6772
6873
69−
70−pprintDocs imp (FunDoc d) = pprintFD imp d
71−pprintDocs imp (DataDoc t args)
72− = text "Data type" <+> pprintFD imp t <$>
73− nest 4 (text "Constructors:" <> line <>
74− vsep (map (pprintFD imp) args))
75−pprintDocs imp (ClassDoc n doc meths)
76− = text "Type class" <+> prettyName imp [] n <$> -- parameters?
74+pprintDocs :: IState -> Docs -> Doc OutputAnnotation
75+pprintDocs ist (FunDoc d) = pprintFD ist d
76+pprintDocs ist (DataDoc t args)
77+ = text "Data type" <+> pprintFD ist t <$>
78+ if null args then text "No constructors."
79+ else nest 4 (text "Constructors:" <> line <>
80+ vsep (map (pprintFD ist) args))
81+pprintDocs ist (ClassDoc n doc meths params instances superclasses)
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 <$>
7787 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))
79136
80137getDocs :: Name -> Idris Docs
81138getDocs n
@@ -96,11 +153,16 @@ docData n ti
96153docClass :: Name -> ClassInfo -> Idris Docs
97154docClass n ci
98155 = do i <- getIState
99− let docstr = case lookupCtxt n (idris_docstrings i) of
100− [str] -> fst str
101− _ -> emptyDocstring
102− mdocs <- mapM docFun (map fst (class_methods ci))
103− return (ClassDoc n docstr mdocs)
156+ let docStrings = listToMaybe $ lookupCtxt n $ idris_docstrings i
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)
161+ mdocs <- mapM (docFun . fst) (class_methods ci)
162+ return $ ClassDoc n docstr mdocs params instances superclasses
163+ where
164+ getDInst (PInstance _ _ _ _ _ t _ _) = Just t
165+ getDInst _ = Nothing
104166
105167docFun :: Name -> Idris FunDoc
106168docFun n
@@ -120,8 +182,22 @@ docFun n
120182 where funName :: Name -> String
121183 funName (UN n) = str n
122184 funName (NS n _) = funName n
185+ funName n
186+ | n == falseTy = "_|_"
123187
124188getPArgNames :: PTerm -> [(Name, Docstring)] -> [(Name, PTerm, Plicity, Maybe Docstring)]
125189getPArgNames (PPi plicity name ty body) ds =
126190 (name, ty, plicity, lookup name ds) : getPArgNames body ds
127191getPArgNames _ _ = []
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
6868
6969renderInline :: CT.Inline -> Doc OutputAnnotation
7070renderInline (CT.Str s) = text $ T.unpack s
71−renderInline CT.Space = space
71+renderInline CT.Space = softline
7272renderInline CT.SoftBreak = softline
7373renderInline CT.LineBreak = line
7474renderInline (CT.Emph txt) = annotate (AnnTextFmt ItalicText) $ renderInlines txt -- TODO
src/Idris/ElabDecls.hs+210−102
@@ -4,6 +4,7 @@
44module Idris.ElabDecls where
55
66import Idris.AbsSyntax
7+import Idris.ASTUtils
78import Idris.DSL
89import Idris.Error
910import Idris.Delaborate
@@ -29,6 +30,10 @@ import Idris.Core.CaseTree
2930
3031import Idris.Docstrings
3132
33+import Prelude hiding (id, (.))
34+import Control.Category
35+
36+import Control.Applicative hiding (Const)
3237import Control.DeepSeq
3338import Control.Monad
3439import Control.Monad.State.Strict as State
@@ -81,14 +86,15 @@ elabType' norm info syn doc argDocs fc opts n ty' = {- let ty' = piBind (params
8186 ctxt <- getContext
8287 i <- getIState
8388
84− logLvl 3 $ show n ++ " pre-type " ++ showTmImpls ty'
89+ logLvl 5 $ show n ++ " pre-type " ++ showTmImpls ty'
8590 ty' <- addUsingConstraints syn fc ty'
8691 ty' <- implicit info syn n ty'
8792
8893 let ty = addImpl i ty'
8994 inacc = inaccessibleArgs 0 ty
90− logLvl 3 $ show n ++ " type " ++ showTmImpls ty
91− logLvl 5 $ "Inaccessible arguments: " ++ show inacc
95+ logLvl 5 $ show n ++ " type pre-addimpl " ++ showTmImpls ty'
96+ logLvl 5 $ show n ++ " type " ++ showTmImpls ty
97+ logLvl 3 $ show n ++ ": inaccessible arguments: " ++ show inacc
9298
9399 ((tyT, defer, is), log) <-
94100 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
119125 let (t, _) = unApply (getRetTy nty')
120126 let corec = case t of
121127 P _ rcty _ -> case lookupCtxt rcty (idris_datatypes i) of
122− [TI _ True _ _] -> True
128+ [TI _ True _ _ _] -> True
123129 _ -> False
124130 _ -> False
125131 -- 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
134140 addDocStr n doc argDocs
135141 addIBC (IBCDoc n)
136142 addIBC (IBCFlags n opts')
137− saveInaccArgs n inacc
143+ fputState (opt_inaccessible . ist_optimisation n) inacc
144+ addIBC (IBCOpt n)
138145 when (Implicit `elem` opts') $ do addCoercion n
139146 addIBC (IBCCoercion n)
140147
@@ -178,24 +185,10 @@ elabType' norm info syn doc argDocs fc opts n ty' = {- let ty' = piBind (params
178185 , ns4 == map txt ["Errors","Reflection","Language"] = True
179186 tyIsHandler _ = False
180187
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−
195188-- Get the list of (index, name) of inaccessible arguments from the type.
196189inaccessibleArgs :: Int -> PTerm -> [(Int, Name)]
197190inaccessibleArgs i (PPi (Imp _ _ _) n Placeholder t)
198− = (i,n) : inaccessibleArgs (i+1) t -- unbound implicit
191+ = (i,n) : inaccessibleArgs (i+1) t -- unbound implicit
199192inaccessibleArgs i (PPi plicity n ty t)
200193 | InaccessibleArg `elem` pargopts plicity
201194 = (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)
263256 let as = map (const Nothing) (getArgTys cty)
264257 let params = findParams (map snd cons)
265258 logLvl 2 $ "Parameters : " ++ show params
259+ -- TI contains information about mutually declared types - this will
260+ -- be updated when the mutual block is complete
266261 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])
268263 (idris_datatypes i) })
269264 addIBC (IBCDef n)
270265 addIBC (IBCData n)
@@ -276,7 +271,8 @@ elabData info syn doc argDocs fc opts (PDatadecl n t_in dcons)
276271 -- TMP HACK! Make this a data option
277272 updateContext (addDatatype (Data n ttag cty cons))
278273 updateContext (setMetaInformation n metainf)
279− mapM_ (checkPositive n) cons
274+ mapM_ totcheck (zip (repeat fc) (map fst cons))
275+-- mapM_ (checkPositive n) cons
280276
281277 -- if there's exactly one constructor,
282278 -- 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)
372368
373369type EliminatorState = StateT (Map.Map String Int) Idris
374370
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)
376372elabEliminator :: [Int] -> Name -> PTerm ->
377373 [(Docstring, [(Name, Docstring)], Name, PTerm, FC, [Name])] ->
378374 ElabInfo -> EliminatorState ()
379375elabEliminator paramPos n ty cons info = do
380376 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))
381378 let (cnstrs, _) = splitPi ty
382379 let (splittedTy@(pms, idxs)) = splitPms cnstrs
383380 generalParams <- namePis False pms
@@ -396,13 +393,14 @@ elabEliminator paramPos n ty cons info = do
396393 let clauseGeneralArgs' = map getPiName generalParams ++ [motiveName] ++ clauseConsElimArgs
397394 let clauseGeneralArgs = map (\arg -> pexp (PRef elimFC arg)) clauseGeneralArgs'
398395 let elimSig = "-- eliminator signature: " ++ showTmImpls eliminatorTy
396+ elimLog elimSig
399397 eliminatorClauses <- mapM (\(cns, cnsElim) -> generateEliminatorClauses cns cnsElim clauseGeneralArgs generalParams) (zip cons clauseConsElimArgs)
400398 let eliminatorDef = PClauses emptyFC [TotalFn] elimDeclName eliminatorClauses
401− elimLog $ "-- eliminator definition: " ++ (show . showDeclImp True) eliminatorDef
399+ elimLog $ "-- eliminator definition: " ++ (show . showDeclImp verbosePPOption) eliminatorDef
402400 State.lift $ idrisCatch (elabDecl EAll info eliminatorTyDecl) (\err -> return ())
403401 -- Do not elaborate clauses if there aren't any
404402 case eliminatorClauses of
405− [] -> return ()
403+ [] -> State.lift $ solveDeferred elimDeclName -- Remove meta-variable for type
406404 _ -> State.lift $ idrisCatch (elabDecl EAll info eliminatorDef) (\err -> return ())
407405 where elimLog :: String -> EliminatorState ()
408406 elimLog s = State.lift (logLvl 2 s)
@@ -465,9 +463,9 @@ elabEliminator paramPos n ty cons info = do
465463 freshName key = do
466464 nameMap <- get
467465 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)
469467 put $ Map.insert key (i+1) nameMap
470− return (sUN name)
468+ return name
471469
472470 scrutineeName :: Name
473471 scrutineeName = sUN "scrutinee"
@@ -560,7 +558,7 @@ elabEliminator paramPos n ty cons info = do
560558 let cons' = replaceParams paramPos generalParameters ty
561559 let (args, resTy) = splitPi cons'
562560 implidxs <- implicitIndexes (doc, cnm, ty, fc, fs)
563− consArgs <- namePis True args
561+ consArgs <- namePis False args
564562 let recArgs = findRecArgs consArgs
565563 let recMotives = map applyRecMotive recArgs
566564 let (_, consIdxs) = splitArgPms resTy
@@ -599,7 +597,7 @@ elabEliminator paramPos n ty cons info = do
599597 implidxs <- implicitIndexes (doc, cnm, ty, fc, fs)
600598 let (_, generalIdxs') = splitArgPms resTy
601599 let generalIdxs = map pexp generalIdxs'
602− consArgs <- namePis True args
600+ consArgs <- namePis False args
603601 let lhsPattern = PApp elimFC (PRef elimFC elimDeclName) (generalArgs ++ generalIdxs ++ [pexp $ applyCons cnm consArgs])
604602 let recArgs = findRecArgs consArgs
605603 let recElims = map applyRecElim recArgs
@@ -613,10 +611,12 @@ elabEliminator paramPos n ty cons info = do
613611
614612elabPrims :: Idris ()
615613elabPrims = do mapM_ (elabDecl EAll toplevel)
616− (map (\(opt, decl) -> PData emptyDocstring [] defaultSyntax (fileFC "builtin") opt decl)
617− (zip
614+ (map (\(opt, decl, docs, argdocs) -> PData docs argdocs defaultSyntax (fileFC "builtin") opt decl)
615+ (zip4
618616 [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]))
620620 addNameHint eqTy (sUN "prf")
621621 elabDecl EAll toplevel elimDecl
622622 mapM_ elabPrim primitives
@@ -681,8 +681,8 @@ elabPrims = do mapM_ (elabDecl EAll toplevel)
681681
682682
683683-- | Elaborate a type provider
684−elabProvider :: ElabInfo -> SyntaxInfo -> FC -> ProvideWhat -> Name -> PTerm -> PTerm -> Idris ()
685−elabProvider info syn fc what n ty tm
684+elabProvider :: ElabInfo -> SyntaxInfo -> FC -> ProvideWhat -> Name -> Idris ()
685+elabProvider info syn fc what n
686686 = do i <- getIState
687687 -- Ensure that the experimental extension is enabled
688688 unless (TypeProviders `elem` idris_language_extensions i) $
@@ -692,12 +692,17 @@ elabProvider info syn fc what n ty tm
692692 ctxt <- getContext
693693
694694 -- First elaborate the expected type (and check that it's a type)
695− (ty', typ) <- elabVal toplevel False ty
695+ -- The goal type for a postulate is always Type.
696+ (ty', typ) <- case what of
697+ ProvTerm ty p -> elabVal toplevel False ty
698+ ProvPostulate _ -> elabVal toplevel False PType
696699 unless (isTType typ) $
697700 ifail ("Expected a type, got " ++ show ty' ++ " : " ++ show typ)
698701
699702 -- Elaborate the provider term to TT and check that the type matches
700− (e, et) <- elabVal toplevel False tm
703+ (e, et) <- case what of
704+ ProvTerm _ tm -> elabVal toplevel False tm
705+ ProvPostulate tm -> elabVal toplevel False tm
701706 unless (isProviderOf (normalise ctxt [] ty') et) $
702707 ifail $ "Expected provider type IO (Provider (" ++
703708 show ty' ++ "))" ++ ", got " ++ show et ++ " instead."
@@ -715,17 +720,14 @@ elabProvider info syn fc what n ty tm
715720
716721 case provided of
717722 Provide tm
718− | what `elem` [ProvTerm, ProvAny] ->
723+ | ProvTerm ty _ <- what ->
719724 do -- Finally add a top-level definition of the provided term
720725 elabType info syn emptyDocstring [] fc [] n ty
721726 elabClauses info fc [] n [PClause fc n (PApp fc (PRef fc n) []) [] (delab i tm) []]
722727 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 ->
727729 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)
729731 logLvl 3 $ "Elaborated provided postulate " ++ show n
730732 | otherwise ->
731733 ierror . Msg $ "Attempted to provide a postulate where a term was expected."
@@ -776,12 +778,17 @@ elabTransform info fc safe lhs_in rhs_in
776778
777779
778780elabRecord :: ElabInfo -> SyntaxInfo -> Docstring -> FC -> Name ->
779− PTerm -> Docstring -> Name -> PTerm -> Idris ()
780−elabRecord info syn doc fc tyn ty cdoc cn cty
781− = do elabData info syn doc [] fc [] (PDatadecl tyn ty [(cdoc, [], cn, cty, fc, [])])
781+ PTerm -> DataOpts -> Docstring -> Name -> PTerm -> Idris ()
782+elabRecord info syn doc fc tyn ty opts cdoc cn cty_in
783+ = do elabData info syn doc [] fc opts (PDatadecl tyn ty [(cdoc, [], cn, cty_in, fc, [])])
782784 -- TODO think: something more in info?
783− cty' <- implicit info syn cn cty
785+ cty' <- implicit info syn cn cty_in
784786 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+
785792 cty <- case lookupTy cn (tt_ctxt i) of
786793 [t] -> return (delab i t)
787794 _ -> ifail "Something went inexplicably wrong"
@@ -790,14 +797,29 @@ elabRecord info syn doc fc tyn ty cdoc cn cty
790797 let ptys = getProjs [] (renameBs cimp cty)
791798 let ptys_u = getProjs [] cty
792799 let recty = getRecTy cty
793− logLvl 6 $ show (recty, ptys)
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+
807+ logLvl 1 $ show (recty, ptys)
794808 let substs = map (\ (n, _) -> (n, PApp fc (PRef fc n)
795809 [pexp (PRef fc rec)])) ptys
796− proj_decls <- mapM (mkProj recty substs cimp) (zip ptys [0..])
810+
811+ -- Generate projection functions
812+ proj_decls <- mapM (mkProj recty_in substs cimp) (zip ptys [0..])
813+ logLvl 3 $ show proj_decls
797814 let nonImp = mapMaybe isNonImp (zip cimp ptys_u)
798815 let implBinds = getImplB id cty'
799− update_decls <- mapM (mkUpdate recty implBinds (length nonImp)) (zip nonImp [0..])
816+
817+ -- Generate update functions
818+ update_decls <- mapM (mkUpdate recty index_names_in extraImpls
819+ (getFieldNames cty')
820+ implBinds (length nonImp)) (zip nonImp [0..])
800821 mapM_ (elabDecl EAll info) (concat proj_decls)
822+ logLvl 3 $ show update_decls
801823 mapM_ (tryElabDecl info) (update_decls)
802824 where
803825-- 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
812834 (\v -> do iputStrLn $ show fc ++
813835 ":Warning - can't generate setter for " ++
814836 show fn ++ " (" ++ show ty ++ ")"
837+-- ++ "\n" ++ pshow i v
815838 putIState i)
816839
840+ getBoundImpls (PPi (Imp _ _ _) n ty sc) = (n, ty) : getBoundImpls sc
841+ getBoundImpls _ = []
842+
817843 getImplB k (PPi (Imp l s _) n Placeholder sc)
818844 = getImplB k sc
819845 getImplB k (PPi (Imp l s p) n ty sc)
@@ -830,9 +856,19 @@ elabRecord info syn doc fc tyn ty cdoc cn cty
830856 getProjs acc (PPi _ n ty s) = getProjs ((n, ty) : acc) s
831857 getProjs acc r = reverse acc
832858
859+ getFieldNames (PPi (Exp _ _ _) n _ s) = n : getFieldNames s
860+ getFieldNames (PPi _ _ _ s) = getFieldNames s
861+ getFieldNames _ = []
862+
833863 getRecTy (PPi _ n ty s) = getRecTy s
834864 getRecTy t = t
835865
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+
836872 rec = sMN 0 "rec"
837873
838874 mkp (UN n) = sMN 0 ("p_" ++ str n)
@@ -865,13 +901,23 @@ elabRecord info syn doc fc tyn ty cdoc cn cty
865901
866902 implicitise (pa, t) = pa { getTm = t }
867903
868− mkUpdate recty k num ((pn, pty), pos)
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
907+ mkUpdate recty inames extras fnames k num ((pn, pty), pos)
869908 = do let setname = expandNS syn $ mkType pn
870909 let valname = sMN 0 "updateval"
871− let pt = k (PPi expl pn pty
872− (PPi expl rec recty recty))
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
916+ (PPi expl rec recty_in recty_out)))
873917 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
875921 let lhsArgs = pls
876922 let rhsArgs = take pos pls ++ (PRef fc valname) :
877923 drop (pos + 1) pls
@@ -885,6 +931,15 @@ elabRecord info syn doc fc tyn ty cdoc cn cty
885931 (map pexp rhsArgs)) []
886932 return (pn, pfnTy, PClauses fc [] setname [pclause])
887933
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+
888943-- FIXME: 'forcenames' is an almighty hack! Need a better way of
889944-- erasing non-forceable things
890945-- ^^^
@@ -918,7 +973,7 @@ elabCon info syn tn codata (doc, argDocs, n, t_in, fc, forcenames)
918973 checkDocs fc argDocs t_in
919974 addDocStr n doc argDocs
920975 addIBC (IBCDoc n)
921− saveInaccArgs n inacc
976+ fputState (opt_inaccessible . ist_optimisation n) inacc
922977 addIBC (IBCOpt n)
923978 return (n, cty')
924979 where
@@ -953,9 +1008,8 @@ elabClauses :: ElabInfo -> FC -> FnOpts -> Name -> [PClause] -> Idris ()
9531008elabClauses info fc opts n_in cs = let n = liftname info n_in in
9541009 do ctxt <- getContext
9551010 ist <- getIState
956− let inacc = case lookupCtxt n (idris_optimisation ist) of
957− [Optimise inacc _] -> map fst inacc
958− _ -> []
1011+ inacc <- map fst <$> fgetState (opt_inaccessible . ist_optimisation n)
1012+
9591013 -- Check n actually exists, with no definition yet
9601014 let tys = lookupTy n ctxt
9611015 let reflect = Reflection `elem` opts
@@ -975,9 +1029,8 @@ elabClauses info fc opts n_in cs = let n = liftname info n_in in
9751029
9761030 solveDeferred n
9771031
978− ist <- getIState
979− let opts = addDef n (Optimise [] False) (idris_optimisation ist)
980− in putIState (ist { idris_optimisation = opts })
1032+ -- just ensure that the structure exists
1033+ fmodifyState (ist_optimisation n) id
9811034 addIBC (IBCOpt n)
9821035
9831036 ist <- getIState
@@ -1147,7 +1200,8 @@ elabClauses info fc opts n_in cs = let n = liftname info n_in in
11471200 force (normalisePats ctxt [] y))
11481201 simple_lhs ctxt t = t
11491202
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)))
11511205
11521206 -- this is so pattern types are in the right form for erasure
11531207 normalisePats ctxt env (Bind n (PVar t) sc)
@@ -1259,8 +1313,8 @@ elabPE info fc caller r =
12591313
12601314-- Elaborate a value, returning any new bindings created (this will only
12611315-- happen if elaborating as a pattern clause)
1262−elabValBind :: ElabInfo -> Bool -> PTerm -> Idris (Term, Type, [(Name, Type)])
1263−elabValBind info aspat tm_in
1316+elabValBind :: ElabInfo -> Bool -> Bool -> PTerm -> Idris (Term, Type, [(Name, Type)])
1317+elabValBind info aspat norm tm_in
12641318 = do ctxt <- getContext
12651319 i <- getIState
12661320 let tm = addImpl i tm_in
@@ -1285,14 +1339,17 @@ elabValBind info aspat tm_in
12851339 logLvl 3 ("Value: " ++ show vtm)
12861340-- recheckC (fileFC "(input)") [] tm'
12871341-- 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
12891346 let bargs = getPBtys vtm
12901347
12911348 return (vtm, vty, bargs)
12921349
12931350elabVal :: ElabInfo -> Bool -> PTerm -> Idris (Term, Type)
12941351elabVal info aspat tm_in
1295− = do (tm, ty, _) <- elabValBind info aspat tm_in
1352+ = do (tm, ty, _) <- elabValBind info aspat False tm_in
12961353 return (tm, ty)
12971354
12981355-- 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
13021359checkPossible info fc tcgen fname lhs_in
13031360 = do ctxt <- getContext
13041361 i <- getIState
1305− let lhs = addImpl i lhs_in
1362+ let lhs = addImplPat i lhs_in
13061363 -- if the LHS type checks, it is possible
13071364 case elaborate ctxt (sMN 0 "patLHS") infP []
13081365 (erun fc (buildTC i info True [] fname (infTerm lhs))) of
@@ -1311,21 +1368,53 @@ checkPossible info fc tcgen fname lhs_in
13111368 case recheck ctxt [] (forget lhs_tm) lhs_tm of
13121369 OK _ -> return True
13131370 err -> return False
1314− Error err -> if tcgen then return False
1315− else return (impossibleError err)
1316− where impossibleError (CantUnify _ topx topy e _ _)
1317− = not (sameFam topx topy || not (impossibleError e))
1318− impossibleError (CantConvert _ _ _) = False
1319− impossibleError (At _ e) = impossibleError e
1320− impossibleError (Elaborating _ _ e) = impossibleError e
1321− impossibleError (ElaboratingArg _ _ _ e) = impossibleError e
1322− impossibleError _ = True
1371+ -- if it's a recoverable error, the case may become possible
1372+ Error err -> if tcgen then return (recoverable ctxt err)
1373+ else return (validCase ctxt err ||
1374+ recoverable ctxt err)
1375+ where validCase ctxt (CantUnify _ topx topy e _ _)
1376+ = let topx' = normalise ctxt [] topx
1377+ topy' = normalise ctxt [] topy in
1378+ not (sameFam topx' topy' || not (validCase ctxt e))
1379+ validCase ctxt (CantConvert _ _ _) = False
1380+ validCase ctxt (At _ e) = validCase ctxt e
1381+ validCase ctxt (Elaborating _ _ e) = validCase ctxt e
1382+ validCase ctxt (ElaboratingArg _ _ _ e) = validCase ctxt e
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
13231393
13241394 sameFam topx topy
13251395 = case (unApply topx, unApply topy) of
13261396 ((P _ x _, _), (P _ y _, _)) -> x == y
13271397 _ -> False
13281398
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+
13291418getFixedInType i env (PExp _ _ _ _ : is) (Bind n (Pi t) sc)
13301419 = getFixedInType i (n : env) is (instantiate (P Bound n t) sc)
13311420getFixedInType 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)
15331622 rev <- case ret_fam of
15341623 P _ rfamn _ ->
15351624 case lookupCtxt rfamn (idris_datatypes i) of
1536− [TI _ _ dopts _] ->
1625+ [TI _ _ dopts _ _] ->
15371626 return (DataErrRev `elem` dopts)
15381627 _ -> return False
15391628 _ -> return False
@@ -1644,6 +1733,7 @@ elabClause info opts (_, PWith fc fname lhs_in withs wval_in withblock)
16441733 let def'' = map (\(n, (i, top, t)) -> (n, (i, top, t, False))) def'
16451734 addDeferred def''
16461735 mapM_ (elabCaseBlock info opts) is
1736+ logLvl 5 ("Checked wval " ++ show wval')
16471737 (cwval, cwvalty) <- recheckC fc [] (getInferTerm wval')
16481738 let cwvaltyN = explicitNames cwvalty
16491739 let cwvalN = explicitNames cwval
@@ -1742,7 +1832,7 @@ elabClause info opts (_, PWith fc fname lhs_in withs wval_in withblock)
17421832 do lhs <- updateLHS n wname mvars ns ns' (fullApp tm) w
17431833 return $ PWith fc wname lhs ws wval withs'
17441834 mkAux wname toplhs ns ns' c
1745− = ifail $ show fc ++ "badly formed with clause"
1835+ = ifail $ show fc ++ ":badly formed with clause"
17461836
17471837 addArg (PApp fc f args) w = PApp fc f (args ++ [pexp w])
17481838 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)
17531843 return $ substMatches mvars $
17541844 PApp fc (PRef fc' wname)
17551845 (map pexp ns ++ pexp w : (map pexp ns'))
1756− updateLHS n wname mvars ns ns' tm w
1757− = ifail $ "Not implemented match " ++ show tm
1846+ updateLHS n wname mvars ns_in ns_in' tm w
1847+ = updateLHS n wname mvars ns_in ns_in' (PApp fc tm []) w
17581848
17591849 keepMvar mvs fc v | v `elem` mvs = PRef fc v
17601850 | otherwise = Placeholder
@@ -1774,8 +1864,8 @@ data MArgTy = IA | EA | CA deriving Show
17741864
17751865elabClass :: ElabInfo -> SyntaxInfo -> Docstring ->
17761866 FC -> [PTerm] ->
1777− Name -> [(Name, PTerm)] -> [PDecl] -> Idris ()
1778−elabClass info syn doc fc constraints tn ps ds
1867+ Name -> [(Name, PTerm)] -> [(Name, Docstring)] -> [PDecl] -> Idris ()
1868+elabClass info syn doc fc constraints tn ps pDocs ds
17791869 = do let cn = SN (InstanceCtorN tn) -- sUN ("instance" ++ show tn) -- MN 0 ("instance" ++ show tn)
17801870 let tty = pibind ps PType
17811871 let constraint = PApp fc (PRef fc tn)
@@ -1801,8 +1891,8 @@ elabClass info syn doc fc constraints tn ps ds
18011891 constraint
18021892 let cons = [(emptyDocstring, [], cn, cty, fc, [])]
18031893 let ddecl = PDatadecl tn tty cons
1804− logLvl 5 $ "Class data " ++ show (showDImp True ddecl)
1805− elabData info (syn { no_imp = no_imp syn ++ mnames }) doc [] fc [] ddecl
1894+ logLvl 5 $ "Class data " ++ show (showDImp verbosePPOption ddecl)
1895+ elabData info (syn { no_imp = no_imp syn ++ mnames }) doc pDocs fc [] ddecl
18061896 -- for each constraint, build a top level function to chase it
18071897 logLvl 5 $ "Building functions"
18081898 let usyn = syn { using = map (\ (x,y) -> UImplicit x y) ps
@@ -1919,12 +2009,12 @@ elabClass info syn doc fc constraints tn ps ds
19192009 getMeth (m:ms) (a:as) x | x == a = PRef fc m
19202010 | otherwise = getMeth ms as x
19212011
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
19232013 lhsArgs (IA : xs) ns = lhsArgs xs ns
19242014 lhsArgs (CA : xs) ns = lhsArgs xs ns
19252015 lhsArgs [] _ = []
19262016
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
19282018 rhsArgs (IA : xs) ns = pexp Placeholder : rhsArgs xs ns
19292019 rhsArgs (CA : xs) ns = pconst (PResolveTC fc) : rhsArgs xs ns
19302020 rhsArgs [] _ = []
@@ -1952,10 +2042,13 @@ elabInstance info syn what fc cs n ps t expn ds = do
19522042 i <- getIState
19532043 (n, ci) <- case lookupCtxtName n (idris_classes i) of
19542044 [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))
19562048 let constraint = PApp fc (PRef fc n) (map pexp ps)
19572049 let iname = mkiname n ps expn
1958− when (what /= EDefns) $ do
2050+ let emptyclass = null (class_methods ci)
2051+ when (what /= EDefns || (null ds && not emptyclass)) $ do
19592052 nty <- elabType' True info syn emptyDocstring [] fc [] iname t
19602053 -- if the instance type matches any of the instances we have already,
19612054 -- 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
19642057 (class_instances ci)
19652058 addInstance intInst n iname
19662059 Just _ -> addInstance intInst n iname
1967− when (what /= ETypes) $ do
2060+ when (what /= ETypes && (not (null ds && not emptyclass))) $ do
19682061 let ips = zip (class_params ci) ps
19692062 let ns = case n of
19702063 NS n ns' -> ns'
@@ -1995,25 +2088,25 @@ elabInstance info syn what fc cs n ps t expn ds = do
19952088 let wbTys = map mkTyDecl mtys
19962089 let wbVals = map (decorateid (decorate ns iname)) ds'
19972090 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)
19992092 logLvl 3 $ "Instance is " ++ show ps ++ " implicits " ++
20002093 show (concat (nub wparams))
20012094
20022095 -- Bring variables in instance head into scope
20032096 ist <- getIState
2004− let headVars = mapMaybe (\p -> case p of
2005− PRef _ n ->
2006− case lookupTy n (tt_ctxt ist) of
2007− [] -> Just n
2008− _ -> Nothing
2009− _ -> Nothing) ps
2097+ let headVars = nub $ mapMaybe (\p -> case p of
2098+ PRef _ n ->
2099+ case lookupTy n (tt_ctxt ist) of
2100+ [] -> Just n
2101+ _ -> Nothing
2102+ _ -> Nothing) ps
20102103-- let lhs = PRef fc iname
20112104 let lhs = PApp fc (PRef fc iname)
20122105 (map (\n -> pimp n (PRef fc n) True) headVars)
20132106 let rhs = PApp fc (PRef fc (instanceName ci))
20142107 (map (pexp . mkMethApp) mtys)
20152108
2016− logLvl 5 $ "Instance LHS " ++ show lhs
2109+ logLvl 5 $ "Instance LHS " ++ show lhs ++ " " ++ show headVars
20172110 logLvl 5 $ "Instance RHS " ++ show rhs
20182111
20192112 let idecls = [PClauses fc [Dictionary] iname
@@ -2252,6 +2345,11 @@ elabDecl' what info (PMutual f ps)
22522345 [p] -> elabDecl what info p
22532346 _ -> do mapM_ (elabDecl ETypes info) ps
22542347 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
22552353 -- Do totality checking after entire mutual block
22562354 i <- get
22572355 mapM_ (\n -> do logLvl 5 $ "Simplifying " ++ show n
@@ -2260,6 +2358,16 @@ elabDecl' what info (PMutual f ps)
22602358 mapM_ buildSCG (idris_totcheck i)
22612359 mapM_ checkDeclTotality (idris_totcheck i)
22622360 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 ()
22632371
22642372elabDecl' what info (PParams f ns ps)
22652373 = do i <- getIState
@@ -2282,17 +2390,17 @@ elabDecl' what info (PNamespace n ps) = mapM_ (elabDecl' what ninfo) ps
22822390 ninfo = case namespace info of
22832391 Nothing -> info { namespace = Just [n] }
22842392 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)
22862394 | what /= EDefns
22872395 = 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
22892397elabDecl' what info (PInstance s f cs n ps t expn ds)
22902398 = do iLOG $ "Elaborating instance " ++ show n
22912399 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)
22932401 | what /= ETypes
22942402 = 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
22962404 | otherwise
22972405 = do iLOG $ "Elaborating [type of] " ++ show tyn
22982406 elabData info s doc [] f [] (PLaterdecl tyn ty)
@@ -2302,10 +2410,10 @@ elabDecl' _ info (PDSL n dsl)
23022410 addIBC (IBCDSL n)
23032411elabDecl' what info (PDirective i)
23042412 | what /= EDefns = i
2305−elabDecl' what info (PProvider syn fc provWhat n tp tm)
2413+elabDecl' what info (PProvider syn fc provWhat n)
23062414 | what /= EDefns
23072415 = do iLOG $ "Elaborating type provider " ++ show n
2308− elabProvider info syn fc provWhat n tp tm
2416+ elabProvider info syn fc provWhat n
23092417elabDecl' what info (PTransform fc safety old new)
23102418 = elabTransform info fc safety old new
23112419elabDecl' _ _ _ = return () -- skipped this time
src/Idris/ElabTerm.hs+55−24
@@ -66,15 +66,19 @@ build ist info pattern opts fn tm
6666 ctxt <- get_context
6767 probs <- get_probs
6868 u <- getUnifyLog
69+ hs <- get_holes
6970
7071 when (not pattern) $
71− traceWhen u ("Remaining problems:\n" ++ show probs) $
72− do matchProblems True; unifyProblems
72+ traceWhen u ("Remaining holes:\n" ++ show hs ++ "\n" ++
73+ "Remaining problems:\n" ++ qshow probs) $
74+ do unify_all; matchProblems True; unifyProblems
75+
7376 probs <- get_probs
7477 case probs of
7578 [] -> return ()
76− ((_,_,_,e,_,_):es) -> if inf then return ()
77− else lift (Error e)
79+ ((_,_,_,e,_,_):es) -> traceWhen u ("Final problems:\n" ++ show probs) $
80+ if inf then return ()
81+ else lift (Error e)
7882 is <- getAux
7983 tt <- get_term
8084 let (tm, ds) = runState (collectDeferred (Just fn) tt) []
@@ -123,6 +127,7 @@ elab ist info pattern opts fn tm
123127 end_unify
124128 when pattern -- convert remaining holes to pattern vars
125129 (do update_term orderPats
130+ unify_all
126131 matchProblems False -- only the ones we matched earlier
127132 unifyProblems
128133 mkPat)
@@ -262,13 +267,14 @@ elab ist info pattern opts fn tm
262267 ty <- goal
263268 ctxt <- get_context
264269 let (tc, _) = unApply ty
265− let as' = pruneByType tc ctxt as
270+ env <- get_env
271+ let as' = pruneByType (map fst env) tc ctxt as
266272-- trace (show as ++ "\n ==> " ++ showSep ", " (map showTmImpls as')) $
267273 tryAll (zip (map (elab' ina) as') (map showHd as'))
268− where showHd (PApp _ (PRef _ n) _) = show n
269− showHd (PRef _ n) = show n
270− showHd (PApp _ h _) = show h
271− showHd x = show x
274+ where showHd (PApp _ (PRef _ n) _) = n
275+ showHd (PRef _ n) = n
276+ showHd (PApp _ h _) = showHd h
277+ showHd x = NErased -- We probably should do something better than this here
272278 elab' ina (PAlternative False as)
273279 = trySeq as
274280 where -- if none work, take the error from the first
@@ -494,6 +500,7 @@ elab ist info pattern opts fn tm
494500 where alt t = case getTm t of
495501 PAlternative False _ -> 5
496502 PAlternative True _ -> 1
503+ PTactics _ -> 150
497504 PLam _ _ _ -> 2
498505 PRewrite _ _ _ _ -> 3
499506 _ -> 0
@@ -559,7 +566,7 @@ elab ist info pattern opts fn tm
559566 claim tyn RType
560567 valn <- getNameFrom (sMN 0 "rval")
561568 claim valn (Var tyn)
562− letn <- getNameFrom (sMN 0 "rewrite_rule")
569+ letn <- getNameFrom (sMN 0 "_rewrite_rule")
563570 letbind letn (Var tyn) (Var valn)
564571 focus valn
565572 elab' ina r
@@ -691,6 +698,9 @@ elab ist info pattern opts fn tm
691698 addImpl ist (PApp fc (PRef fc (sUN "Delay"))
692699 [pexp t])
693700
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
694704 insertCoerce ina t =
695705 do ty <- goal
696706 -- Check for possible coercions to get to the goal
@@ -781,8 +791,21 @@ pruneAlt xs = map prune xs
781791
782792-- Rule out alternatives that don't return the same type as the head of the goal
783793-- (If there are none left as a result, do nothing)
784−pruneByType :: Term -> Context -> [PTerm] -> [PTerm]
785−pruneByType (P _ n _) c as
794+pruneByType :: [Name] -> Term -> Context -> [PTerm] -> [PTerm]
795+-- if an alternative has a locally bound name at the head, take it
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
786809-- if the goal type is polymorphic, keep e
787810 | [] <- lookupTy n c = as
788811 | otherwise
@@ -808,7 +831,7 @@ pruneByType (P _ n _) c as
808831 _ -> False
809832 _ -> False
810833
811−pruneByType t _ as = as
834+pruneByType _ t _ as = as
812835
813836findInstances :: IState -> Term -> [Name]
814837findInstances ist t
@@ -820,9 +843,10 @@ findInstances ist t
820843
821844trivial' ist
822845 = trivial (elab ist toplevel False [] (sMN 0 "tac")) ist
823−proofSearch' ist top n hints
824− = proofSearch (elab ist toplevel False [] (sMN 0 "tac")) top n hints ist
825−
846+proofSearch' ist rec depth prv top n hints
847+ = do unifyProblems
848+ proofSearch rec prv depth
849+ (elab ist toplevel False [] (sMN 0 "tac")) top n hints ist
826850
827851resolveTC :: Int -> Term -> Name -> IState -> ElabD ()
828852resolveTC = resTC' []
@@ -967,7 +991,7 @@ runTac autoSolve ist fn tac
967991 ns -> return (map (\ (n, a) -> (n, map (const True) a)) ns)
968992 let tacs = map (\ (fn', imps) ->
969993 (match_apply (Var fn') (map (\x -> (x, 0)) imps),
970− show fn')) fnimps
994+ fn')) fnimps
971995 tryAll tacs
972996 when autoSolve solveAll
973997 where envArgs n = do e <- get_env
@@ -983,7 +1007,7 @@ runTac autoSolve ist fn tac
9831007 ns -> return (map (\ (n, a) -> (n, map isImp a)) ns)
9841008 let tacs = map (\ (fn', imps) ->
9851009 (apply (Var fn') (map (\x -> (x, 0)) imps),
986− show fn')) fnimps
1010+ fn')) fnimps
9871011 tryAll tacs
9881012 when autoSolve solveAll
9891013 where isImp (PImp _ _ _ _ _) = True
@@ -995,6 +1019,8 @@ runTac autoSolve ist fn tac
9951019 _ -> return []
9961020 runT (Refine fn imps) = do ns <- apply (Var fn) (map (\x -> (x,0)) imps)
9971021 when autoSolve solveAll
1022+ runT DoUnify = do unify_all
1023+ when autoSolve solveAll
9981024 runT (Equiv tm) -- let bind tm, then
9991025 = do attack
10001026 tyn <- getNameFrom (sMN 0 "ety")
@@ -1050,8 +1076,9 @@ runTac autoSolve ist fn tac
10501076 runT Compute = compute
10511077 runT Trivial = do trivial' ist; when autoSolve solveAll
10521078 runT TCInstance = runT (Exact (PResolveTC emptyFC))
1053− runT (ProofSearch top hints)
1054− = do proofSearch' ist top fn hints; when autoSolve solveAll
1079+ runT (ProofSearch rec prover depth top hints)
1080+ = do proofSearch' ist rec depth prover top fn hints
1081+ when autoSolve solveAll
10551082 runT (Focus n) = focus n
10561083 runT Solve = solve
10571084 runT (Try l r) = do try' (runT l) (runT r) True
@@ -1178,14 +1205,16 @@ reify _ t = fail ("Unknown tactic " ++ show t)
11781205
11791206reifyApp :: IState -> Name -> [Term] -> ElabD PTactic
11801207reifyApp 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 [])
11811210reifyApp _ t [x]
11821211 | t == reflm "Refine" = do n <- reifyTTName x
11831212 return $ Refine n []
11841213reifyApp ist t [l, r] | t == reflm "Seq" = liftM2 TSeq (reify ist l) (reify ist r)
11851214reifyApp ist t [Constant (Str n), x]
11861215 | t == reflm "GoalType" = liftM (GoalType n) (reify ist x)
1187−reifyApp _ t [Constant (Str n)]
1188− | t == reflm "Intro" = return $ Intro [sUN n]
1216+reifyApp _ t [n] | t == reflm "Intro" = liftM (Intro . (:[])) (reifyTTName n)
1217+reifyApp _ t [n] | t == reflm "Induction" = liftM Induction (reifyTTName n)
11891218reifyApp ist t [t']
11901219 | t == reflm "ApplyTactic" = liftM (ApplyTactic . delab ist) (reifyTT t')
11911220reifyApp ist t [t']
@@ -1580,8 +1609,8 @@ reflectErr (NotInjective t1 t2 t3) =
15801609 ]
15811610reflectErr (CantResolve t) = raw_apply (Var $ reflErrName "CantResolve") [reflect t]
15821611reflectErr (CantResolveAlts ss) =
1583− raw_apply (Var $ reflErrName "CantResolve")
1584− [rawList (Var $ (sUN "String")) (map (RConstant . Str) ss)]
1612+ raw_apply (Var $ reflErrName "CantResolveAlts")
1613+ [rawList (Var $ (sUN "String")) (map Var ss)]
15851614reflectErr (IncompleteTerm t) = raw_apply (Var $ reflErrName "IncompleteTerm") [reflect t]
15861615reflectErr UniverseError = Var $ reflErrName "UniverseError"
15871616reflectErr ProgramLineComment = Var $ reflErrName "ProgramLineComment"
@@ -1625,6 +1654,8 @@ withErrorReflection x = idrisCatch x (\ e -> handle e >>= ierror)
16251654 then handle err
16261655 else applyHandlers err hs
16271656 return (ElaboratingArg f a prev err')
1657+ -- ProofSearchFail is an internal detail - so don't expose it
1658+ handle (ProofSearchFail e) = handle e
16281659 -- TODO: argument-specific error handlers go here for ElaboratingArg
16291660 handle e = do ist <- getIState
16301661 logLvl 2 "Starting error reflection"
src/Idris/Erasure.hs+27−19
@@ -3,6 +3,7 @@
33module Idris.Erasure (performUsageAnalysis, mkFieldName) where
44
55import Idris.AbsSyntax
6+import Idris.ASTUtils
67import Idris.Core.CaseTree
78import Idris.Core.TT
89import Idris.Core.Evaluate
@@ -12,6 +13,9 @@ import Idris.Error
1213import Debug.Trace
1314import System.IO.Unsafe
1415
16+import Control.Category
17+import Prelude hiding (id, (.))
18+
1519import Control.Arrow
1620import Control.Applicative
1721import Control.Monad.State
@@ -97,7 +101,7 @@ performUsageAnalysis = do
97101 $ ifail ("reachable postulates:\n" ++ intercalate "\n" [" " ++ show n | n <- S.toList reachablePostulates])
98102
99103 -- Store the usage info in the internal state.
100− mapM_ (storeUsage cg) usage
104+ mapM_ storeUsage usage
101105
102106 return $ S.toList reachableNames
103107 where
@@ -105,7 +109,7 @@ performUsageAnalysis = do
105109 getMainName ist = case lookupCtxtName n (idris_implicits ist) of
106110 [(n', _)] -> Right n'
107111 [] -> Left (NoSuchVariable n)
108− more -> Left (CantResolveAlts (map (show . fst) more))
112+ more -> Left (CantResolveAlts (map fst more))
109113 where
110114 n = sNS (sUN "main") ["Main"]
111115
@@ -124,13 +128,8 @@ performUsageAnalysis = do
124128 | S.null rs = show i
125129 | otherwise = show i ++ " from " ++ intercalate ", " (map show $ S.toList rs)
126130
127− storeUsage :: Ctxt CGInfo -> (Name, IntMap (Set Reason)) -> Idris ()
128− storeUsage cg (n, args)
129− | Just x <- lookupCtxtExact n cg
130− = addToCG n x{ usedpos = flat } -- functions
131−
132− | otherwise
133− = addToCG n (CGInfo [] [] [] [] flat) -- data ctors
131+ storeUsage :: (Name, IntMap (Set Reason)) -> Idris ()
132+ storeUsage (n, args) = fputState (cg_usedpos . ist_callgraph n) flat
134133 where
135134 flat = [(i, S.toList rs) | (i,rs) <- IM.toList args]
136135
@@ -204,6 +203,7 @@ buildDepMap ci ctx mainName = addPostulates $ dfs S.empty M.empty [mainName]
204203 -- among Idris.Primitives.primitives
205204 , mn "__MkPair" [2,3]
206205 , it "prim_fork" [0]
206+ , it "unsafePerformPrimIO" [1]
207207
208208 -- believe_me is a primitive but it only uses its third argument
209209 -- it is special-cased in usedNames above
@@ -294,7 +294,6 @@ buildDepMap ci ctx mainName = addPostulates $ dfs S.empty M.empty [mainName]
294294 -- that the result of this function is used at all
295295 = addTagDep $ unionMap (getDepsAlt fn es vs casedVar) alts -- coming from the whole subtree
296296 where
297−
298297 addTagDep = case alts of
299298 [_] -> id -- single branch, tag not used
300299 _ -> 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]
329328 | otherwise = \j -> Nothing
330329
331330 -- 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
333332
334333 -- named variables introduce dependencies as described in `vs'
335334 getDepsTerm vs bs cd (P _ n _)
336− -- local variables
335+ -- de bruijns (lambda-bound, let-bound vars)
336+ | Just deps <- lookup n bs
337+ = deps cd
338+
339+ -- ctor-bound/arg-bound variables
337340 | Just var <- M.lookup n vs
338341 = M.singleton cd (viDeps var)
339342
@@ -348,18 +351,18 @@ buildDepMap ci ctx mainName = addPostulates $ dfs S.empty M.empty [mainName]
348351 specialMNs = map (sMN 0 . ("__" ++)) $ words "Unit True False II"
349352
350353 -- 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
352355
353356 getDepsTerm vs bs cd (Bind n bdr t)
354357 -- here we just push IM.empty on the de bruijn stack
355358 -- the args will be marked as used at the usage site
356− | Lam ty <- bdr = getDepsTerm vs (const M.empty : bs) cd t
357− | Pi ty <- bdr = getDepsTerm vs (const M.empty : bs) cd t
359+ | Lam ty <- bdr = getDepsTerm vs ((n, const M.empty) : bs) cd t
360+ | Pi ty <- bdr = getDepsTerm vs ((n, const M.empty) : bs) cd t
358361
359362 -- let-bound variables can get partially evaluated
360363 -- 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
362− | NLet ty t <- bdr = getDepsTerm vs (var t : bs) cd t
364+ | Let ty t <- bdr = getDepsTerm vs ((n, var t) : bs) cd t
365+ | NLet ty t <- bdr = getDepsTerm vs ((n, var t) : bs) cd t
363366 where
364367 var t cd = getDepsTerm vs bs cd t
365368
@@ -386,6 +389,10 @@ buildDepMap ci ctx mainName = addPostulates $ dfs S.empty M.empty [mainName]
386389 -- a bound variable might draw in additional dependencies,
387390 -- think: f x = x 0 <-- here, `x' _is_ used
388391 P _ n _
392+ -- debruijn-bound name
393+ | Just deps <- lookup n bs
394+ -> deps cd `union` unconditionalDeps args
395+
389396 -- local name that refers to a method
390397 | Just var <- M.lookup n vs
391398 , Just meth <- viMethod var
@@ -402,7 +409,7 @@ buildDepMap ci ctx mainName = addPostulates $ dfs S.empty M.empty [mainName]
402409 -> conditionalDeps n args
403410
404411 -- 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
406413
407414 -- we interpret applied lambdas as lets in order to reuse code here
408415 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]
418425
419426 _ -> error $ "cannot analyse application of " ++ show fun ++ " to " ++ show args
420427 where
428+ union = M.unionWith $ M.unionWith S.union
421429 ins = M.insertWith (M.unionWith S.union) cd
422430
423431 unconditionalDeps :: [Term] -> Deps
@@ -441,7 +449,7 @@ buildDepMap ci ctx mainName = addPostulates $ dfs S.empty M.empty [mainName]
441449 , viMethod = Nothing
442450 }) | (v, i) <- zip args [0..]]
443451 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]
445453 cond = S.singleton (metameth, Result)
446454 metameth = mkFieldName ctorName methNo
447455 (args, body) = unfoldLams t
src/Idris/Error.hs+4−2
@@ -43,11 +43,13 @@ idrisCatch = catchError
4343setAndReport :: Err -> Idris ()
4444setAndReport e = do ist <- getIState
4545 let h = idris_outh ist
46− case e of
46+ case (unwrap e) of
4747 At fc e -> do setErrSpan fc
4848 ihWarn h fc $ pprintErr ist e
4949 _ -> 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
5153
5254ifail :: String -> Idris a
5355ifail = throwError . Msg
src/Idris/Help.hs+11−6
@@ -4,6 +4,7 @@ data CmdArg = ExprArg -- ^ The command takes an expression
44 | NameArg -- ^ The command takes a name
55 | FileArg -- ^ The command takes a file
66 | ModuleArg -- ^ The command takes a module name
7+ | NamespaceArg -- ^ The command takes a namespace name
78 | OptionArg -- ^ The command takes an option
89 | MetaVarArg -- ^ The command takes a metavariable
910 | ColourArg -- ^ The command is the colour-setting command
@@ -16,6 +17,7 @@ instance Show CmdArg where
1617 show NameArg = "<name>"
1718 show FileArg = "<filename>"
1819 show ModuleArg = "<module>"
20+ show NamespaceArg = "<namespace>"
1921 show OptionArg = "<option>"
2022 show MetaVarArg = "<metavar>"
2123 show ColourArg = "<option>"
@@ -29,23 +31,25 @@ help =
2931 ([":t"], ExprArg, "Check the type of an expression"),
3032 ([":miss", ":missing"], NameArg, "Show missing clauses"),
3133 ([":doc"], NameArg, "Show internal documentation"),
34+ ([":mkdoc"], NamespaceArg, "Generate IdrisDoc for namespace(s) and dependencies"),
3235 ([":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"),
3439 ([":total"], NameArg, "Check the totality of a name"),
3540 ([":r",":reload"], NoArg, "Reload current file"),
3641 ([":l",":load"], FileArg, "Load a new file"),
3742 ([":cd"], FileArg, "Change working directory"),
38− ([":m",":module"], ModuleArg, "Import an extra module"), -- NOTE: dragons
43+ ([":module"], ModuleArg, "Import an extra module"), -- NOTE: dragons
3944 ([":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)"),
4146 ([":p",":prove"], MetaVarArg, "Prove a metavariable"),
4247 ([":a",":addproof"], NameArg, "Add proof to source file"),
4348 ([":rmproof"], NameArg, "Remove proof from proof stack"),
4449 ([":showproof"], NameArg, "Show proof"),
4550 ([":proofs"], NoArg, "Show available proofs"),
4651 ([":x"], ExprArg, "Execute IO actions resulting from an expression using the interpreter"),
47− ([":c",":compile"], FileArg, "Compile to an executable <filename>"),
48− ([":js", ":javascript"], FileArg, "Compile to JavaScript <filename>"),
52+ ([":c",":compile"], FileArg, "Compile to an executable [codegen] <filename>"),
4953 ([":exec",":execute"], NoArg, "Compile to an executable and run"),
5054 ([":dynamic"], FileArg, "Dynamically load a C library (similar to %dynamic)"),
5155 ([":dynamic"], NoArg, "List dynamically loaded C libraries"),
@@ -54,7 +58,8 @@ help =
5458 ([":unset"], OptionArg, "Unset an option"),
5559 ([":colour", ":color"], ColourArg, "Turn REPL colours on or off; set a specific colour"),
5660 ([":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")
5863 ]
5964
6065-- | 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)
3030import Util.Zlib (decompressEither)
3131
3232ibcVersion :: Word8
33−ibcVersion = 67
33+ibcVersion = 74
3434
3535data IBCFile = IBCFile { ver :: Word8,
3636 sourcefile :: FilePath,
@@ -53,6 +53,7 @@ data IBCFile = IBCFile { ver :: Word8,
5353 ibc_hdrs :: [(Codegen, String)],
5454 ibc_access :: [(Name, Accessibility)],
5555 ibc_total :: [(Name, Totality)],
56+ ibc_totcheckfail :: [(FC, String)],
5657 ibc_flags :: [(Name, [FnOpt])],
5758 ibc_cg :: [(Name, CGInfo)],
5859 ibc_defs :: [(Name, Def)],
@@ -67,7 +68,8 @@ data IBCFile = IBCFile { ver :: Word8,
6768 ibc_function_errorhandlers :: [(Name, Name, Name)], -- fn, arg, handler
6869 ibc_metavars :: [(Name, (Maybe Name, Int, Bool))],
6970 ibc_patdefs :: [(Name, ([([Name], Term, Term)], [PTerm]))],
70− ibc_postulates :: [Name]
71+ ibc_postulates :: [Name],
72+ ibc_parsedSpan :: Maybe FC
7173 }
7274 deriving Show
7375{-!
@@ -75,7 +77,7 @@ deriving instance Binary IBCFile
7577!-}
7678
7779initIBC :: IBCFile
78−initIBC = IBCFile ibcVersion "" [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] []
80+initIBC = IBCFile ibcVersion "" [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] Nothing
7981
8082loadIBC :: FilePath -> Idris ()
8183loadIBC fp = do imps <- getImported
@@ -234,11 +236,13 @@ ibc i (IBCMetaInformation n m) f = return f { ibc_metainformation = (n,m) : ibc_
234236ibc i (IBCErrorHandler n) f = return f { ibc_errorhandlers = n : ibc_errorhandlers f }
235237ibc i (IBCFunctionErrorHandler fn a n) f =
236238 return f { ibc_function_errorhandlers = (fn, a, n) : ibc_function_errorhandlers f }
237−ibc i (IBCMetavar n) f =
239+ibc i (IBCMetavar n) f =
238240 case lookup n (idris_metavars i) of
239241 Nothing -> return f
240242 Just t -> return f { ibc_metavars = (n, t) : ibc_metavars f }
241243ibc 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 }
242246
243247process :: IBCFile -> FilePath -> Idris ()
244248process i fn
@@ -246,7 +250,7 @@ process i fn
246250 ifail "Incorrect ibc version --- please rebuild"
247251 | otherwise =
248252 do srcok <- runIO $ doesFileExist (sourcefile i)
249− when srcok $ runIO $ timestampOlder (sourcefile i) fn
253+ when srcok $ timestampOlder (sourcefile i) fn
250254 v <- verbose
251255 quiet <- getQuiet
252256-- when (v && srcok && not quiet) $ iputStrLn $ "Skipping " ++ sourcefile i
@@ -270,6 +274,7 @@ process i fn
270274 pPatdefs (ibc_patdefs i)
271275 pAccess (ibc_access i)
272276 pTotal (ibc_total i)
277+ pTotCheckErr (ibc_totcheckfail i)
273278 pCG (ibc_cg i)
274279 pDocs (ibc_docstrings i)
275280 pCoercions (ibc_coercions i)
@@ -282,12 +287,13 @@ process i fn
282287 pFunctionErrorHandlers (ibc_function_errorhandlers i)
283288 pMetavars (ibc_metavars i)
284289 pPostulates (ibc_postulates i)
290+ pParsedSpan (ibc_parsedSpan i)
285291
286−timestampOlder :: FilePath -> FilePath -> IO ()
287−timestampOlder src ibc = do srct <- getModificationTime src
288− ibct <- getModificationTime ibc
292+timestampOlder :: FilePath -> FilePath -> Idris ()
293+timestampOlder src ibc = do srct <- runIO $ getModificationTime src
294+ ibct <- runIO $ getModificationTime ibc
289295 if (srct > ibct)
290− then fail "Needs reloading"
296+ then ifail "Needs reloading"
291297 else return ()
292298
293299pPostulates :: [Name] -> Idris ()
@@ -295,12 +301,16 @@ pPostulates ns = do
295301 i <- getIState
296302 putIState i{ idris_postulates = idris_postulates i `S.union` S.fromList ns }
297303
304+pParsedSpan :: Maybe FC -> Idris ()
305+pParsedSpan fc = do ist <- getIState
306+ putIState ist { idris_parsedSpan = fc }
307+
298308pImports :: [FilePath] -> Idris ()
299309pImports fs
300310 = do mapM_ (\f -> do i <- getIState
301311 ibcsd <- valIBCSubDir i
302312 ids <- allImportDirs
303− fp <- runIO $ findImport ids ibcsd f
313+ fp <- findImport ids ibcsd f
304314 if (f `elem` imported i)
305315 then iLOG $ "Already read " ++ f
306316 else do putIState (i { imported = f : imported i })
@@ -454,6 +464,10 @@ pTotal ds = mapM_ (\ (n, a) ->
454464 putIState (i { tt_ctxt = setTotal n a (tt_ctxt i) }))
455465 ds
456466
467+pTotCheckErr :: [(FC, String)] -> Idris ()
468+pTotCheckErr es = do ist <- getIState
469+ putIState ist { idris_totcheckfail = idris_totcheckfail ist ++ es }
470+
457471pCG :: [(Name, CGInfo)] -> Idris ()
458472pCG ds = mapM_ (\ (n, a) -> addToCG n a) ds
459473
@@ -1161,7 +1175,7 @@ instance Binary MetaInformation where
11611175 return (DataMI x1)
11621176
11631177instance 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)
11651179 = {-# SCC "putIBCFile" #-}
11661180 do put x1
11671181 put x2
@@ -1199,6 +1213,8 @@ instance Binary IBCFile where
11991213 put x34
12001214 put x35
12011215 put x36
1216+ put x37
1217+ put x38
12021218
12031219 get
12041220 = do x1 <- get
@@ -1238,7 +1254,9 @@ instance Binary IBCFile where
12381254 x34 <- get
12391255 x35 <- get
12401256 x36 <- 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)
1257+ x37 <- get
1258+ x38 <- get
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)
12421260 else return (initIBC { ver = x1 })
12431261
12441262instance Binary DataOpt where
@@ -1425,7 +1443,7 @@ instance (Binary t) => Binary (PDecl' t) where
14251443 PNamespace x1 x2 -> do putWord8 5
14261444 put x1
14271445 put x2
1428− PRecord x1 x2 x3 x4 x5 x6 x7 x8 ->
1446+ PRecord x1 x2 x3 x4 x5 x6 x7 x8 x9 ->
14291447 do putWord8 6
14301448 put x1
14311449 put x2
@@ -1435,7 +1453,8 @@ instance (Binary t) => Binary (PDecl' t) where
14351453 put x6
14361454 put x7
14371455 put x8
1438− PClass x1 x2 x3 x4 x5 x6 x7
1456+ put x9
1457+ PClass x1 x2 x3 x4 x5 x6 x7 x8
14391458 -> do putWord8 7
14401459 put x1
14411460 put x2
@@ -1444,6 +1463,7 @@ instance (Binary t) => Binary (PDecl' t) where
14441463 put x5
14451464 put x6
14461465 put x7
1466+ put x8
14471467 PInstance x1 x2 x3 x4 x5 x6 x7 x8 -> do putWord8 8
14481468 put x1
14491469 put x2
@@ -1513,7 +1533,8 @@ instance (Binary t) => Binary (PDecl' t) where
15131533 x6 <- get
15141534 x7 <- get
15151535 x8 <- get
1516− return (PRecord x1 x2 x3 x4 x5 x6 x7 x8)
1536+ x9 <- get
1537+ return (PRecord x1 x2 x3 x4 x5 x6 x7 x8 x9)
15171538 7 -> do x1 <- get
15181539 x2 <- get
15191540 x3 <- get
@@ -1521,7 +1542,8 @@ instance (Binary t) => Binary (PDecl' t) where
15211542 x5 <- get
15221543 x6 <- get
15231544 x7 <- get
1524− return (PClass x1 x2 x3 x4 x5 x6 x7)
1545+ x8 <- get
1546+ return (PClass x1 x2 x3 x4 x5 x6 x7 x8)
15251547 8 -> do x1 <- get
15261548 x2 <- get
15271549 x3 <- get
@@ -1560,7 +1582,7 @@ instance Binary Using where
15601582 1 -> do x1 <- get; x2 <- get; return (UConstraint x1 x2)
15611583
15621584instance Binary SyntaxInfo where
1563− put (Syn x1 x2 x3 x4 _ x5 x6 x7)
1585+ put (Syn x1 x2 x3 x4 _ x5 x6 _ _ x7)
15641586 = do put x1
15651587 put x2
15661588 put x3
@@ -1576,7 +1598,7 @@ instance Binary SyntaxInfo where
15761598 x5 <- get
15771599 x6 <- get
15781600 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)
15801602
15811603instance (Binary t) => Binary (PClause' t) where
15821604 put x
@@ -1939,6 +1961,13 @@ instance (Binary t) => Binary (PTactic' t) where
19391961 put x1
19401962 ByReflection x1 -> do putWord8 20
19411963 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
19421971 get
19431972 = do i <- getWord8
19441973 case i of
@@ -1980,6 +2009,13 @@ instance (Binary t) => Binary (PTactic' t) where
19802009 return (Induction x1)
19812010 20 -> do x1 <- get
19822011 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
19832019 _ -> error "Corrupted binary data for PTactic'"
19842020
19852021
@@ -2116,15 +2152,17 @@ instance Binary OptInfo where
21162152 return (Optimise x1 x2)
21172153
21182154instance Binary TypeInfo where
2119− put (TI x1 x2 x3 x4) = do put x1
2120− put x2
2121− put x3
2122− put x4
2155+ put (TI x1 x2 x3 x4 x5) = do put x1
2156+ put x2
2157+ put x3
2158+ put x4
2159+ put x5
21232160 get = do x1 <- get
21242161 x2 <- get
21252162 x3 <- get
21262163 x4 <- get
2127− return (TI x1 x2 x3 x4)
2164+ x5 <- get
2165+ return (TI x1 x2 x3 x4 x5)
21282166
21292167instance Binary SynContext where
21302168 put x
src/Idris/IdeSlave.hs+64−19
@@ -12,7 +12,7 @@ import Text.Trifecta.Delta
1212
1313import Idris.Core.TT
1414
15−import Control.Applicative
15+import Control.Applicative hiding (Const)
1616
1717data SExp = SexpList [SExp]
1818 | StringAtom String
@@ -74,16 +74,33 @@ instance (SExpable a, SExpable b, SExpable c, SExpable d, SExpable e) =>
7474 toSExp (l, m, n, o, p) = SexpList [toSExp l, toSExp m, toSExp n, toSExp o, toSExp p]
7575
7676instance SExpable NameOutput where
77− toSExp TypeOutput = SymbolAtom "type"
78− toSExp FunOutput = SymbolAtom "function"
79− toSExp DataOutput = SymbolAtom "data"
80− toSExp MetavarOutput = SymbolAtom "metavar"
77+ toSExp TypeOutput = SymbolAtom "type"
78+ toSExp FunOutput = SymbolAtom "function"
79+ toSExp DataOutput = SymbolAtom "data"
80+ toSExp MetavarOutput = SymbolAtom "metavar"
81+ toSExp PostulateOutput = SymbolAtom "postulate"
8182
8283maybeProps :: SExpable a => [(String, Maybe a)] -> [(SExp, SExp)]
8384maybeProps [] = []
8485maybeProps ((n, Just p):ps) = (SymbolAtom n, toSExp p) : maybeProps ps
8586maybeProps ((n, Nothing):ps) = maybeProps ps
8687
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+
87104instance SExpable OutputAnnotation where
88105 toSExp (AnnName n ty d t) = toSExp $ [(SymbolAtom "name", StringAtom (show n)),
89106 (SymbolAtom "implicit", BoolAtom False)] ++
@@ -92,19 +109,32 @@ instance SExpable OutputAnnotation where
92109 toSExp (AnnBoundName n imp) = toSExp [(SymbolAtom "name", StringAtom (show n)),
93110 (SymbolAtom "decor", SymbolAtom "bound"),
94111 (SymbolAtom "implicit", BoolAtom imp)]
95− toSExp AnnConstData = toSExp [(SymbolAtom "decor", SymbolAtom "data")]
96− toSExp AnnConstType = toSExp [(SymbolAtom "decor", SymbolAtom "type")]
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)]
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 []
97124 toSExp AnnKeyword = toSExp [(SymbolAtom "decor", SymbolAtom "keyword")]
98− toSExp (AnnFC (FC f (sl, sc) (el, ec))) = toSExp [(SymbolAtom "source-loc",
99− ((SymbolAtom "filename", StringAtom f),
100− (SymbolAtom "start", IntegerAtom (toInteger sl), IntegerAtom (toInteger sc)),
101− (SymbolAtom "end", IntegerAtom (toInteger el), IntegerAtom (toInteger ec))))]
125+ toSExp (AnnFC fc) = toSExp [(SymbolAtom "source-loc", toSExp fc)]
102126 toSExp (AnnTextFmt fmt) = toSExp [(SymbolAtom "text-formatting", SymbolAtom format)]
103127 where format = case fmt of
104128 BoldText -> "bold"
105129 ItalicText -> "italic"
106130 UnderlineText -> "underline"
107131
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+
108138escape :: String -> String
109139escape = concatMap escapeChar
110140 where
@@ -145,30 +175,43 @@ data IdeSlaveCommand = REPLCompletions String
145175 | AddProofClause Int String
146176 | AddMissing Int String
147177 | MakeWithBlock Int String
148− | ProofSearch Int String [String]
149− | LoadFile String
178+ | ProofSearch Bool Int String [String] (Maybe Int) -- ^^ Recursive?, line, name, hints, depth
179+ | MakeLemma Int String
180+ | LoadFile String (Maybe Int)
150181 | DocsFor String
151182 | Apropos String
152183 | GetOpts
153184 | SetOpt Opt Bool
154185 | Metavariables Int -- ^^ the Int is the column count for pretty-printing
155− deriving Show
186+ | WhoCalls String
187+ | CallsWho String
156188
157189sexpToCommand :: SExp -> Maybe IdeSlaveCommand
158190sexpToCommand (SexpList (x:[])) = sexpToCommand x
159191sexpToCommand (SexpList [SymbolAtom "interpret", StringAtom cmd]) = Just (Interpret cmd)
160192sexpToCommand (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)
162195sexpToCommand (SexpList [SymbolAtom "type-of", StringAtom name]) = Just (TypeOf name)
163196sexpToCommand (SexpList [SymbolAtom "case-split", IntegerAtom line, StringAtom name]) = Just (CaseSplit (fromInteger line) name)
164197sexpToCommand (SexpList [SymbolAtom "add-clause", IntegerAtom line, StringAtom name]) = Just (AddClause (fromInteger line) name)
165198sexpToCommand (SexpList [SymbolAtom "add-proof-clause", IntegerAtom line, StringAtom name]) = Just (AddProofClause (fromInteger line) name)
166199sexpToCommand (SexpList [SymbolAtom "add-missing", IntegerAtom line, StringAtom name]) = Just (AddMissing (fromInteger line) name)
167200sexpToCommand (SexpList [SymbolAtom "make-with", IntegerAtom line, StringAtom name]) = Just (MakeWithBlock (fromInteger line) name)
168−sexpToCommand (SexpList [SymbolAtom "proof-search", IntegerAtom line, StringAtom name, SexpList hintexp]) | Just hints <- getHints hintexp = Just (ProofSearch (fromInteger line) name hints)
169− where getHints = mapM (\h -> case h of
170− StringAtom s -> Just s
171− _ -> Nothing)
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.
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)))
210+ where getHints = mapM (\h -> case h of
211+ StringAtom s -> Just s
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)
172215sexpToCommand (SexpList [SymbolAtom "docs-for", StringAtom name]) = Just (DocsFor name)
173216sexpToCommand (SexpList [SymbolAtom "apropos", StringAtom search]) = Just (Apropos search)
174217sexpToCommand (SymbolAtom "get-options") = Just GetOpts
@@ -176,6 +219,8 @@ sexpToCommand (SexpList [SymbolAtom "set-option", SymbolAtom s, BoolAtom b])
176219 | Just opt <- lookup s opts = Just (SetOpt opt b)
177220 where opts = [("show-implicits", ShowImpl), ("error-context", ErrContext)] --TODO support more
178221sexpToCommand (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)
179224sexpToCommand _ = Nothing
180225
181226parseMessage :: 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 @@
11module Idris.Imports where
22
33import Idris.AbsSyntax
4+import Idris.Error
45
56import Idris.Core.TT
67import Paths_idris
@@ -43,15 +44,15 @@ ibcPathWithFallback ibcsd fp = do let ibcp = ibcPath ibcsd True fp
4344ibcPathNoFallback :: FilePath -> FilePath -> FilePath
4445ibcPathNoFallback ibcsd fp = ibcPath ibcsd True fp
4546
46−findImport :: [FilePath] -> FilePath -> FilePath -> IO IFileType
47−findImport [] ibcsd fp = fail $ "Can't find import " ++ fp
47+findImport :: [FilePath] -> FilePath -> FilePath -> Idris IFileType
48+findImport [] ibcsd fp = ierror . Msg $ "Can't find import " ++ fp
4849findImport (d:ds) ibcsd fp = do let fp_full = d </> fp
49− ibcp <- ibcPathWithFallback ibcsd fp_full
50+ ibcp <- runIO $ ibcPathWithFallback ibcsd fp_full
5051 let idrp = srcPath fp_full
5152 let lidrp = lsrcPath fp_full
52− ibc <- doesFileExist ibcp
53− idr <- doesFileExist idrp
54− lidr <- doesFileExist lidrp
53+ ibc <- runIO $ doesFileExist ibcp
54+ idr <- runIO $ doesFileExist idrp
55+ lidr <- runIO $ doesFileExist lidrp
5556-- when idr $ putStrLn $ idrp ++ " ok"
5657-- when lidr $ putStrLn $ lidrp ++ " ok"
5758-- 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
1111import Util.Pretty
1212import Util.ScreenSize (getScreenWidth)
1313
14+import Debug.Trace
15+
1416import System.IO (stdout, Handle, hPutStrLn)
1517
18+import Data.List (nub)
19+import Data.Maybe (fromMaybe)
20+
1621pshow :: IState -> Err -> String
1722pshow ist err = displayDecorated (consoleDecorate ist) .
1823 renderPretty 1.0 80 .
@@ -23,7 +28,9 @@ ihWarn h fc err = do i <- getIState
2328 case idris_outputmode i of
2429 RawOutput ->
2530 do err' <- iRender . fmap (fancifyAnnots i) $
26− text (show fc) <> colon <//> err
31+ if fc_fname fc /= ""
32+ then text (show fc) <> colon <//> err
33+ else err
2734 runIO . hPutStrLn h $ displayDecorated (consoleDecorate i) err'
2835 IdeSlave n ->
2936 do err' <- iRender . fmap (fancifyAnnots i) $ err
@@ -47,16 +54,6 @@ iRender d = do w <- getWidth
4754 | otherwise -> do width <- runIO getScreenWidth
4855 return $ renderPretty 0.8 width d
4956
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−
6057-- | Write a pretty-printed term to the console with semantic coloring
6158consoleDisplayAnnotated :: Handle -> Doc OutputAnnotation -> Idris ()
6259consoleDisplayAnnotated h output = do ist <- getIState
@@ -65,35 +62,20 @@ consoleDisplayAnnotated h output = do ist <- getIState
6562 displayDecorated (consoleDecorate ist) $
6663 rendered
6764
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−
7965ihPrintTermWithType :: Handle -> Doc OutputAnnotation -> Doc OutputAnnotation -> Idris ()
80−ihPrintTermWithType h tm ty = do ist <- getIState
81− let output = tm <+> colon <+> ty
82− case idris_outputmode ist of
83− RawOutput -> consoleDisplayAnnotated h output
84− IdeSlave n -> ideSlaveReturnAnnotated n h output
66+ihPrintTermWithType h tm ty = ihRenderResult h (tm <+> colon <+> align ty)
8567
8668-- | Pretty-print a collection of overloadings to REPL or IDESlave - corresponds to :t name
8769ihPrintFunTypes :: Handle -> [(Name, Bool)] -> Name -> [(Name, PTerm)] -> Idris ()
8870ihPrintFunTypes h bnd n [] = ihPrintError h $ "No such variable " ++ show n
89−ihPrintFunTypes h bnd n overloads = do imp <- impShow
90− ist <- getIState
91− let output = vsep (map (uncurry (ppOverload imp)) overloads)
92− case idris_outputmode ist of
93− RawOutput -> consoleDisplayAnnotated h output
94− IdeSlave n -> ideSlaveReturnAnnotated n h output
71+ihPrintFunTypes h bnd n overloads = do ist <- getIState
72+ let ppo = ppOptionIst ist
73+ let infixes = idris_infixes ist
74+ let output = vsep (map (uncurry (ppOverload ppo infixes)) overloads)
75+ ihRenderResult h output
9576 where fullName n = prettyName True bnd n
96− ppOverload imp n tm = fullName n <+> colon <+> align (pprintPTerm imp bnd [] tm)
77+ ppOverload ppo infixes n tm =
78+ fullName n <+> colon <+> align (pprintPTerm ppo bnd [] infixes tm)
9779
9880ihRenderResult :: Handle -> Doc OutputAnnotation -> Idris ()
9981ihRenderResult h d = do ist <- getIState
@@ -101,51 +83,45 @@ ihRenderResult h d = do ist <- getIState
10183 RawOutput -> consoleDisplayAnnotated h d
10284 IdeSlave n -> ideSlaveReturnAnnotated n h d
10385
104−fancifyAnnots :: IState -> OutputAnnotation -> OutputAnnotation
105−fancifyAnnots ist annot@(AnnName n _ _ _) =
106− do let ctxt = tt_ctxt ist
107− docs = docOverview ist n
108− ty = Just (getTy ist n)
109− case () of
110− _ | isDConName n ctxt -> AnnName n (Just DataOutput) docs ty
111− _ | isFnName n ctxt -> AnnName n (Just FunOutput) docs ty
112− _ | isTConName n ctxt -> AnnName n (Just TypeOutput) docs ty
113− _ | isMetavarName n ist -> AnnName n (Just MetavarOutput) docs ty
114− _ | otherwise -> annot
115− where docOverview :: IState -> Name -> Maybe String -- pretty-print first paragraph of docs
116− docOverview ist n = do docs <- lookupCtxtExact n (idris_docstrings ist)
117− let o = overview (fst docs)
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
86+ideSlaveReturnWithStatus :: String -> Integer -> Handle -> Doc OutputAnnotation -> Idris ()
87+ideSlaveReturnWithStatus status n h out = do
88+ ist <- getIState
89+ (str, spans) <- fmap displaySpans .
90+ iRender .
91+ fmap (fancifyAnnots ist) $
92+ out
93+ let good = [SymbolAtom status, toSExp str, toSExp spans]
94+ runIO . hPutStrLn h $ convSExp "return" good n
95+
96+
97+-- | Write pretty-printed output to IDESlave with semantic annotations
98+ideSlaveReturnAnnotated :: Integer -> Handle -> Doc OutputAnnotation -> Idris ()
99+ideSlaveReturnAnnotated = ideSlaveReturnWithStatus "ok"
126100
127101-- | Show an error with semantic highlighting
128102ihRenderError :: Handle -> Doc OutputAnnotation -> Idris ()
129103ihRenderError h e = do ist <- getIState
130104 case idris_outputmode ist of
131105 RawOutput -> consoleDisplayAnnotated h e
132− IdeSlave n -> do
133− (str, spans) <- fmap displaySpans .
134− iRender .
135− fmap (fancifyAnnots ist) $
136− e
137− let good = [SymbolAtom "error", toSExp str, toSExp spans]
138− runIO . hPutStrLn h $ convSExp "return" good n
106+ IdeSlave n -> ideSlaveReturnWithStatus "error" n h e
107+
108+ihPrintWithStatus :: String -> Handle -> String -> Idris ()
109+ihPrintWithStatus status h s = do
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 ->
116+ let good = SexpList [SymbolAtom status, toSExp s] in
117+ runIO $ hPutStrLn h $ convSExp "return" good n
118+
119+
120+ihPrintResult :: Handle -> String -> Idris ()
121+ihPrintResult = ihPrintWithStatus "ok"
139122
140123ihPrintError :: Handle -> String -> Idris ()
141−ihPrintError h s = do i <- getIState
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
124+ihPrintError = ihPrintWithStatus "error"
149125
150126ihputStrLn :: Handle -> String -> Idris ()
151127ihputStrLn h s = do i <- getIState
@@ -171,3 +147,9 @@ iputGoal g = do i <- getIState
171147 RawOutput -> runIO $ putStrLn (displayDecorated (consoleDecorate i) g)
172148 IdeSlave n -> runIO . putStrLn $
173149 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 ::=
4242 DocComment Accessibility? 'record' FnName TypeSig 'where' OpenBlock Constructor KeepTerminator CloseBlock;
4343-}
4444record :: SyntaxInfo -> IdrisParser PDecl
45−record syn = do (doc, acc) <- try (do
45+record syn = do (doc, acc, opts) <- try (do
4646 doc <- option noDocs docComment
4747 acc <- optional accessibility
48+ opts <- dataOpts []
4849 reserved "record"
49− return (doc, acc))
50+ return (doc, acc, opts))
5051 fc <- getFC
5152 tyn_in <- fnName
5253 lchar ':'
@@ -59,7 +60,7 @@ record syn = do (doc, acc) <- try (do
5960 syn_namespace syn }
6061 let fns = getRecNames rsyn cty
6162 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
6364 <?> "record type declaration"
6465 where
6566 getRecNames :: SyntaxInfo -> PTerm -> [Name]
src/Idris/ParseExpr.hs+200−171
@@ -54,14 +54,22 @@ fullExpr syn = do x <- expr syn
5454 return $ debindApp syn (desugar syn i x)
5555
5656
57−{- |Parses an expression
57+{- | Parses an expression
5858@
59− Expr ::= Expr';
59+ Expr ::= Pi
6060@
61−-}
61+ -}
6262expr :: SyntaxInfo -> IdrisParser PTerm
63−expr syn = do i <- get
64− buildExpressionParser (table (idris_infixes i)) (expr' syn)
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
71+opExpr syn = do i <- get
72+ buildExpressionParser (table (idris_infixes i)) (expr' syn)
6573
6674{- | Parses either an internally defined expression or
6775 a user-defined one
@@ -70,16 +78,10 @@ Expr' ::= "External (User-defined) Syntax"
7078 | InternalExpr;
7179@
7280 -}
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
80−doexpr' syn = try (externalExpr syn)
81− <|> internalExpr syn
82− <?> "expression"
81+expr' :: SyntaxInfo -> IdrisParser PTerm
82+expr' syn = try (externalExpr syn)
83+ <|> internalExpr syn
84+ <?> "expression"
8385
8486{- | Parses a user-defined expression -}
8587externalExpr :: SyntaxInfo -> IdrisParser PTerm
@@ -190,37 +192,32 @@ extension syn (Rule ssym ptm _)
190192{- | Parses a (normal) built-in expression
191193@
192194InternalExpr ::=
193− App
194− | MatchApp
195− | UnifyLog
195+ UnifyLog
196196 | RecordType
197197 | SimpleExpr
198198 | Lambda
199199 | QuoteGoal
200200 | Let
201201 | RewriteTerm
202− | Pi
203202 | CaseExpr
204203 | DoBlock
204+ | App
205205 ;
206206@
207207-}
208208internalExpr :: SyntaxInfo -> IdrisParser PTerm
209209internalExpr syn =
210− try (app syn)
211− <|> try (matchApp syn)
212− <|> try (unifyLog syn)
213− <|> try (disamb syn)
214− <|> try (noImplicits syn)
210+ unifyLog syn
211+ <|> disamb syn
212+ <|> noImplicits syn
215213 <|> recordType syn
216214 <|> lambda syn
217215 <|> quoteGoal syn
218216 <|> let_ syn
219217 <|> rewriteTerm syn
220− <|> try (pi syn)
221218 <|> doBlock syn
222219 <|> caseExpr syn
223− <|> simpleExpr syn
220+ <|> app syn
224221 <?> "expression"
225222
226223{- | Parses a case expression
@@ -278,30 +275,28 @@ tacticsExpr syn = do reserved "tactics"
278275{- | Parses a simple expression
279276@
280277SimpleExpr ::=
281− '![' Term ']'
278+ {- External (User-defined) Simple Expression -}
282279 | '?' Name
283280 | % 'instance'
284281 | 'refl' ('{' Expr '}')?
285282 | ProofExpr
286283 | TacticsExpr
287284 | FnName
285+ | Idiom
288286 | List
289− | Comprehension
290287 | Alt
291− | Idiom
292− | '(' Bracketed
288+ | Bracketed
293289 | Constant
294290 | Type
295291 | '_|_'
296292 | '_'
297− | {- External (User-defined) Simple Expression -}
298293 ;
299294@
300295-}
301296simpleExpr :: SyntaxInfo -> IdrisParser PTerm
302297simpleExpr syn =
303− {-try (do symbol "!["; t <- term; lchar ']'; return $ PQuote t)
304− <|>-} do x <- try (lchar '?' *> name); return (PMetavar x)
298+ try (simpleExternalExpr syn)
299+ <|> do x <- try (lchar '?' *> name); return (PMetavar x)
305300 <|> do lchar '%'; fc <- getFC; reserved "instance"; return (PResolveTC fc)
306301 <|> do reserved "refl"; fc <- getFC;
307302 tm <- option Placeholder (do lchar '{'; t <- expr syn; lchar '}';
@@ -311,36 +306,40 @@ simpleExpr syn =
311306 <|> proofExpr syn
312307 <|> tacticsExpr syn
313308 <|> do reserved "Type"; return PType
314− <|> try (do c <- constant
315− fc <- getFC
316− return (modifyConst syn fc (PConstant c)))
317− <|> try (do symbol "'"; fc <- getFC; str <- name
318− return (PApp fc (PRef fc (sUN "Symbol_"))
319− [pexp (PConstant (Str (show str)))]))
309+ <|> do c <- constant
310+ fc <- getFC
311+ return (modifyConst syn fc (PConstant c))
312+ <|> do symbol "'"; fc <- getFC; str <- name
313+ return (PApp fc (PRef fc (sUN "Symbol_"))
314+ [pexp (PConstant (Str (show str)))])
320315 <|> do fc <- getFC
321316 x <- fnName
322317 return (PRef fc x)
323− <|> try (listExpr syn)
324− <|> try (comprehension syn)
325− <|> alt syn
326318 <|> idiom syn
319+ <|> listExpr syn
320+ <|> alt syn
327321 <|> do lchar '!'
328322 s <- simpleExpr syn
329323 fc <- getFC
330324 return (PAppBind fc s [])
331− <|> do lchar '('
332− bracketed (disallowImp syn)
325+ <|> bracketed (disallowImp syn)
333326 <|> do symbol "_|_"
334327 fc <- getFC
335328 return (PFalse fc)
336329 <|> do lchar '_'; return Placeholder
337− <|> simpleExternalExpr syn
338330 <?> "expression"
339331
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
341340{- |Parses the rest of an expression in braces
342341@
343−Bracketed ::=
342+Bracketed' ::=
344343 ')'
345344 | Expr ')'
346345 | ExprList ')'
@@ -351,8 +350,8 @@ Bracketed ::=
351350 ;
352351@
353352-}
354−bracketed :: SyntaxInfo -> IdrisParser PTerm
355−bracketed syn =
353+bracketed' :: SyntaxInfo -> IdrisParser PTerm
354+bracketed' syn =
356355 do lchar ')'
357356 fc <- getFC
358357 return $ PTrue fc TypeOrTerm
@@ -365,7 +364,7 @@ bracketed syn =
365364 return (PDPair fc TypeOrTerm (PRef fc ln) lty r))
366365 <|> try (do fc <- getFC; o <- operator; e <- expr syn; lchar ')'
367366 -- No prefix operators! (bit of a hack here...)
368− if (o == "-" || o == "!")
367+ if (o == "-" || o == "!")
369368 then fail "minus not allowed in section"
370369 else return $ PLam (sMN 1000 "ARG") Placeholder
371370 (PApp fc (PRef fc (sUN o)) [pexp (PRef fc (sMN 1000 "ARG")),
@@ -425,29 +424,6 @@ modifyConst syn fc (PConstant (BI x))
425424 ]
426425modifyConst syn fc x = x
427426
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−
451427{- | Parses an alternative expression
452428@
453429 Alt ::= '(|' Expr_List '|)';
@@ -478,31 +454,13 @@ hsimpleExpr syn =
478454 <|> simpleExpr syn
479455 <?> "expression"
480456
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−
499457{- | Parses a unification log expression
500458UnifyLog ::=
501459 '%' 'unifyLog' SimpleExpr
502460 ;
503461-}
504462unifyLog :: SyntaxInfo -> IdrisParser PTerm
505−unifyLog syn = do lchar '%'; reserved "unifyLog";
463+unifyLog syn = do try (lchar '%' *> reserved "unifyLog")
506464 tm <- simpleExpr syn
507465 return (PUnifyLog tm)
508466 <?> "unification log expression"
@@ -528,7 +486,7 @@ NoImplicits ::=
528486@
529487-}
530488noImplicits :: SyntaxInfo -> IdrisParser PTerm
531−noImplicits syn = do lchar '%'; reserved "noImplicits";
489+noImplicits syn = do try (lchar '%' *> reserved "noImplicits")
532490 tm <- simpleExpr syn
533491 return (PNoImplicits tm)
534492 <?> "no implicits expression"
@@ -537,7 +495,11 @@ noImplicits syn = do lchar '%'; reserved "noImplicits";
537495@
538496App ::=
539497 'mkForeign' Arg Arg*
540− | SimpleExpr Arg+
498+ | MatchApp
499+ | SimpleExpr Arg*
500+ ;
501+MatchApp ::=
502+ SimpleExpr '<==' FnName
541503 ;
542504@
543505-}
@@ -547,8 +509,6 @@ app syn = do f <- reserved "mkForeign"
547509 fn <- arg syn
548510 args <- many (do notEndApp; arg syn)
549511 i <- get
550− -- mkForeign f args ==>
551− -- liftPrimIO (\w => mkForeignPrim f args w)
552512 let ap = PApp fc (PRef fc (sUN "liftPrimIO"))
553513 [pexp (PLam (sMN 0 "w")
554514 Placeholder
@@ -558,13 +518,20 @@ app syn = do f <- reserved "mkForeign"
558518 return (dslify i ap)
559519
560520 <|> 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
561529 fc <- getFC
562− args <- some (do notEndApp; arg syn)
563530 i <- get
564−-- case f of
565−-- PAppBind fc ref [] ->
566−-- return (dslify i (PAppBind fc ref args))
567− return (dslify i (PApp fc f args))
531+ args <- many (do notEndApp; arg syn)
532+ case args of
533+ [] -> return f
534+ _ -> return (dslify i (PApp fc f args)))
568535 <?> "function application"
569536 where
570537 dslify :: IState -> PTerm -> PTerm
@@ -639,29 +606,61 @@ FieldType ::=
639606@
640607-}
641608recordType :: SyntaxInfo -> IdrisParser PTerm
642−recordType syn
643− = do reserved "record"
609+recordType syn =
610+ do reserved "record"
644611 lchar '{'
645− fields <- sepBy1 fieldType (lchar ',')
612+ fgs <- fieldGetOrSet
646613 lchar '}'
647614 fc <- getFC
648615 rec <- optional (simpleExpr syn)
649− case rec of
650− Nothing ->
651− return (PLam (sMN 0 "fldx") Placeholder
652− (applyAll fc fields (PRef fc (sMN 0 "fldx"))))
653− Just v -> return (applyAll fc fields v)
616+ case fgs of
617+ Left fields ->
618+ case rec of
619+ Nothing ->
620+ return (PLam (sMN 0 "fldx") Placeholder
621+ (applyAll fc fields (PRef fc (sMN 0 "fldx"))))
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+
654631 <?> "record setting expression"
655− where fieldType :: IdrisParser (Name, PTerm)
656− fieldType = do n <- fnName
657− lchar '='
658− e <- expr syn
659− return (n, e)
660− <?> "field setter"
661− applyAll :: FC -> [(Name, PTerm)] -> PTerm -> PTerm
632+ where fieldSet :: IdrisParser ([Name], PTerm)
633+ fieldSet = do ns <- fieldGet
634+ lchar '='
635+ e <- expr syn
636+ return (ns, e)
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+
648+ applyAll :: FC -> [([Name], PTerm)] -> PTerm -> PTerm
662649 applyAll fc [] x = x
663− applyAll fc ((n, e) : es) x
664− = applyAll fc es (PApp fc (PRef fc (mkType n)) [pexp e, pexp x])
650+ applyAll fc ((ns, e) : es) x
651+ = applyAll fc es (doUpdate fc ns e x)
652+
653+ doUpdate fc [n] e get
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+
665664
666665-- | Creates setters for record types on necessary functions
667666mkType :: Name -> Name
@@ -700,17 +699,17 @@ SimpleExprList ::=
700699@
701700-}
702701lambda :: SyntaxInfo -> IdrisParser PTerm
703−lambda syn = do lchar '\\'
704− try (do xt <- tyOptDeclList syn
705− symbol "=>"
706− sc <- expr syn
707− return (bindList PLam xt sc)
708− <|> (do ps <- sepBy (do fc <- getFC
709− e <- simpleExpr syn
710− return (fc, e)) (lchar ',')
711− symbol "=>"
712− sc <- expr syn
713− return (pmList (zip [0..] ps) sc)))
702+lambda syn = do lchar '\\' <?> "lambda expression"
703+ (do xt <- try $ tyOptDeclList syn
704+ symbol "=>"
705+ sc <- expr syn
706+ return (bindList PLam xt sc)) <|> do
707+ ps <- sepBy (do fc <- getFC
708+ e <- simpleExpr syn
709+ return (fc, e)) (lchar ',')
710+ symbol "=>"
711+ sc <- expr syn
712+ return (pmList (zip [0..] ps) sc)
714713 <?> "lambda expression"
715714 where pmList :: [(Int, (FC, PTerm))] -> PTerm -> PTerm
716715 pmList [] sc = sc
@@ -788,11 +787,16 @@ quoteGoal syn = do reserved "quoteGoal"; n <- name;
788787{- | Parses a dependent type signature
789788
790789@
791−Pi ::=
792− '|'? Static? '(' TypeDeclList ')' DocComment '->' Expr
793− | '|'? Static? '{' TypeDeclList '}' '->' Expr
794− | '{' 'auto' TypeDeclList '}' '->' Expr
795− | '{' 'default' TypeDeclList '}' '->' Expr
790+Pi ::= PiOpts Static? Pi'
791+@
792+
793+@
794+Pi' ::=
795+ OpExpr ('->' Pi)?
796+ | '(' TypeDeclList ')' '->' Pi
797+ | '{' TypeDeclList '}' '->' Pi
798+ | '{' 'auto' TypeDeclList '}' '->' Pi
799+ | '{' 'default' SimpleExpr TypeDeclList '}' '->' Pi
796800 ;
797801@
798802 -}
@@ -801,37 +805,44 @@ pi :: SyntaxInfo -> IdrisParser PTerm
801805pi syn =
802806 do opts <- piOpts syn
803807 st <- static
804− (do try (lchar '('); xt <- typeDeclList syn; lchar ')'
808+ (do xt <- try (lchar '(' *> typeDeclList syn <* lchar ')')
805809 symbol "->"
806810 sc <- expr syn
807811 return (bindList (PPi (Exp opts st False)) xt sc)) <|> (do
808− lchar '{'
809− (do reserved "auto"
812+ (do try (lchar '{' *> reserved "auto")
810813 when (st == Static) $ fail "auto type constraints can not be lazy or static"
811814 xt <- typeDeclList syn
812815 lchar '}'
813816 symbol "->"
814817 sc <- expr syn
815818 return (bindList (PPi
816− (TacImp [] Dynamic (PTactics [Trivial]))) xt sc))
817− <|> (do
818− reserved "default"
819+ (TacImp [] Dynamic (PTactics [Trivial]))) xt sc)) <|> (do
820+ try (lchar '{' *> reserved "default")
819821 when (st == Static) $ fail "default tactic constraints can not be lazy or static"
820822 script <- simpleExpr syn
821823 xt <- typeDeclList syn
822824 lchar '}'
823825 symbol "->"
824826 sc <- expr syn
825− return (bindList (PPi (TacImp [] Dynamic script)) xt sc))
827+ return (bindList (PPi (TacImp [] Dynamic script)) xt sc))
826828 <|> (if implicitAllowed syn then do
827− xt <- typeDeclList syn
828− lchar '}'
829+ xt <- try (lchar '{' *> typeDeclList syn <* lchar '}')
829830 symbol "->"
830831 sc <- expr syn
831832 return (bindList (PPi (Imp opts st False)) xt sc)
832833 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)
833839 <?> "dependent type signature"
834840
841+{- | Parses Possible Options for Pi Expressions
842+@
843+ PiOpts ::= '.'?
844+@
845+-}
835846piOpts :: SyntaxInfo -> IdrisParser [ArgOpt]
836847piOpts syn | implicitAllowed syn =
837848 lchar '.' *> return [InaccessibleArg]
@@ -911,34 +922,49 @@ tyOptDeclList syn = sepBy1 (do x <- nameOrPlaceholder
911922 return (sMN 0 "underscore")
912923 <?> "name or placeholder"
913924
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 ]
915926@
916−Comprehension ::= '[' Expr '|' DoList ']';
927+ListExpr ::=
928+ '[' ']'
929+ | '[' Expr '|' DoList ']'
930+ | '[' ExprList ']'
931+;
917932@
918−
919933@
920934DoList ::=
921935 Do
922936 | Do ',' DoList
923937 ;
924938@
925−-}
926−comprehension :: SyntaxInfo -> IdrisParser PTerm
927−comprehension syn
928− = do lchar '['
929− fc <- getFC
930− pat <- expr syn
931− lchar '|'
932− qs <- sepBy1 (do_ syn) (lchar ',')
933− lchar ']'
934− return (PDoBlock (map addGuard qs ++
935− [DoExp fc (PApp fc (PRef fc (sUN "return"))
936− [pexp pat])]))
937− <?> "list comprehension"
938− where addGuard :: PDo -> PDo
939− addGuard (DoExp fc e) = DoExp fc (PApp fc (PRef fc (sUN "guard"))
940− [pexp e])
941− addGuard x = x
939+@
940+ExprList ::=
941+ Expr
942+ | Expr ',' ExprList
943+ ;
944+@
945+ -}
946+listExpr :: SyntaxInfo -> IdrisParser PTerm
947+listExpr syn = do lchar '['; fc <- getFC;
948+ try ((lchar ']' <?> "end of list expression") *> return (mkList fc [])) <|> (do
949+ x <- expr syn <?> "expression"
950+ (do try (lchar '|') <?> "list comprehension"
951+ qs <- sepBy1 (do_ syn) (lchar ',')
952+ lchar ']'
953+ return (PDoBlock (map addGuard qs ++
954+ [DoExp fc (PApp fc (PRef fc (sUN "return"))
955+ [pexp x])]))) <|> (do
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)]
964+ addGuard :: PDo -> PDo
965+ addGuard (DoExp fc e) = DoExp fc (PApp fc (PRef fc (sUN "guard"))
966+ [pexp e])
967+ addGuard x = x
942968
943969{- | Parses a do-block
944970@
@@ -1070,11 +1096,11 @@ constant = do reserved "Integer"; return (AType (ATInt ITBig))
10701096 <|> do reserved "Bits16x8"; return (AType (ATInt (ITVec IT16 8)))
10711097 <|> do reserved "Bits32x4"; return (AType (ATInt (ITVec IT32 4)))
10721098 <|> do reserved "Bits64x2"; return (AType (ATInt (ITVec IT64 2)))
1073− <|> try (do f <- float; return $ Fl f)
1074− <|> try (do i <- natural; return $ BI i)
1075− <|> try (do s <- verbatimStringLiteral; return $ Str s)
1076− <|> try (do s <- stringLiteral; return $ Str s)
1077− <|> try (do c <- charLiteral; return $ Ch c)
1099+ <|> do f <- try float; return $ Fl f
1100+ <|> do i <- natural; return $ BI i
1101+ <|> do s <- verbatimStringLiteral; return $ Str s
1102+ <|> do s <- stringLiteral; return $ Str s
1103+ <|> do c <- try charLiteral; return $ Ch c --Currently ambigous with symbols
10781104 <?> "constant or literal"
10791105
10801106{- | Parses a verbatim multi-line string literal (triple-quoted)
@@ -1086,7 +1112,7 @@ VerbatimString_t ::=
10861112@
10871113 -}
10881114verbatimStringLiteral :: MonadicParsing m => m String
1089−verbatimStringLiteral = token $ do string "\"\"\""
1115+verbatimStringLiteral = token $ do try $ string "\"\"\""
10901116 manyTill anyChar $ try (string "\"\"\"")
10911117
10921118{- | Parses a static modifier
@@ -1098,7 +1124,7 @@ Static ::=
10981124@
10991125-}
11001126static :: IdrisParser Static
1101−static = do lchar '['; reserved "static"; lchar ']'; return Static
1127+static = do reserved "[static]"; return Static
11021128 <|> return Dynamic
11031129 <?> "static modifier"
11041130
@@ -1199,7 +1225,10 @@ tactic syn = do reserved "intro"; ns <- sepBy (indentPropHolds gtProp *> name) (
11991225 return $ TSeq t (mergeSeq ts)
12001226 <|> do reserved "compute"; return Compute
12011227 <|> do reserved "trivial"; return Trivial
1202− <|> do reserved "search"; return (ProofSearch Nothing [])
1228+ <|> do reserved "unify"; return DoUnify
1229+ <|> do reserved "search"
1230+ depth <- option 10 natural
1231+ return (ProofSearch True True (fromInteger depth) Nothing [])
12031232 <|> do reserved "instance"; return TCInstance
12041233 <|> do reserved "solve"; return Solve
12051234 <|> do reserved "attack"; return Attack
src/Idris/ParseHelpers.hs+9−6
@@ -156,9 +156,11 @@ multiLineComment = try (string "{-" *> (string "-}") *> pure ())
156156docComment :: IdrisParser (Docstring, [(Name, Docstring)])
157157docComment = do dc <- pushIndent *> docCommentLine
158158 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)))
160162 popIndent
161− return (parseDocstring $ T.pack (concat . intersperse "\n" $ dc:rest),
163+ return (parseDocstring $ T.pack (concat (intersperse "\n" (dc:rest))),
162164 map (\(n, d) -> (n, parseDocstring (T.pack d))) args)
163165
164166 where docCommentLine :: MonadicParsing m => m String
@@ -170,6 +172,7 @@ docComment = do dc <- pushIndent *> docCommentLine
170172 eol ; someSpace
171173 return contents)-- ++ concat rest))
172174 <?> ""
175+
173176 argDocCommentLine = do string "|||"
174177 many (satisfy isSpace)
175178 char '@'
@@ -214,7 +217,7 @@ idrisStyle :: MonadicParsing m => IdentifierStyle m
214217idrisStyle = IdentifierStyle _styleName _styleStart _styleLetter _styleReserved Hi.Identifier Hi.ReservedIdentifier
215218 where _styleName = "Idris"
216219 _styleStart = satisfy isAlpha
217− _styleLetter = satisfy isAlphaNum <|> oneOf "_'" <|> (lchar '.')
220+ _styleLetter = satisfy isAlphaNum <|> oneOf "_'."
218221 _styleReserved = HS.fromList ["let", "in", "data", "codata", "record", "Type",
219222 "do", "dsl", "import", "impossible",
220223 "case", "of", "total", "partial", "mutual",
@@ -313,7 +316,7 @@ operatorLetter = oneOf opChars
313316-- | Parses an operator
314317operator :: MonadicParsing m => m String
315318operator = do op <- token . some $ operatorLetter
316− when (op `elem` [":", "=>", "->", "<-", "=", "?="]) $
319+ when (op `elem` [":", "=>", "->", "<-", "=", "?=", "|"]) $
317320 fail $ op ++ " is not a valid operator"
318321 return op
319322
@@ -563,8 +566,8 @@ collect (c@(PClauses _ o _ _) : ds)
563566collect (PParams f ns ps : ds) = PParams f ns (collect ps) : collect ds
564567collect (PMutual f ms : ds) = PMutual f (collect ms) : collect ds
565568collect (PNamespace ns ps : ds) = PNamespace ns (collect ps) : collect ds
566−collect (PClass doc f s cs n ps ds : ds')
567− = PClass doc f s cs n ps (collect ds) : collect ds'
569+collect (PClass doc f s cs n ps pdocs ds : ds')
570+ = PClass doc f s cs n ps pdocs (collect ds) : collect ds'
568571collect (PInstance f s cs n ps t en ds : ds')
569572 = PInstance f s cs n ps t en (collect ds) : collect ds'
570573collect (d : ds) = d : collect ds
src/Idris/ParseOps.hs+1−2
@@ -38,8 +38,7 @@ table fixes
3838 ++ toTable (reverse fixes) ++
3939 [[backtick],
4040 [binary "$" (\fc x y -> flatten $ PApp fc x [pexp y]) AssocRight],
41− [binary "=" PEq AssocLeft],
42− [binary "->" (\fc x y -> PPi expl (sUN "__pi_arg") x y) AssocRight]]
41+ [binary "=" PEq AssocLeft]]
4342 where
4443 flatten :: PTerm -> PTerm -- flatten application
4544 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
4747import Idris.Core.TT
4848import Idris.Core.Evaluate
4949
50−import Control.Applicative
50+import Control.Applicative hiding (Const)
5151import Control.Monad
5252import Control.Monad.Error (throwError, catchError)
5353import Control.Monad.State.Strict
@@ -128,9 +128,14 @@ import_ = do fc <- getFC
128128prog :: SyntaxInfo -> IdrisParser [PDecl]
129129prog syn = do whiteSpace
130130 decls <- many (decl syn)
131− notOpenBraces
132− eof
133131 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 }
134139 return c
135140
136141{-| Parses a top-level declaration
@@ -153,8 +158,16 @@ Decl ::=
153158@
154159-}
155160decl :: SyntaxInfo -> IdrisParser [PDecl]
156−decl syn = do notEndBlock
157− declBody
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
169+ declBody
170+ else fail "End of readable input"
158171 where declBody :: IdrisParser [PDecl]
159172 declBody = declBody'
160173 <|> using_ syn
@@ -489,7 +502,7 @@ mutual syn =
489502 do reserved "mutual"
490503 openBlock
491504 let pvars = syn_params syn
492− ds <- many (decl syn)
505+ ds <- many (decl (syn { mut_nesting = mut_nesting syn + 1 } ))
493506 closeBlock
494507 fc <- getFC
495508 return [PMutual fc (concat ds)]
@@ -574,7 +587,7 @@ class_ syn = do (doc, acc) <- try (do
574587 cs <- many carg
575588 ds <- option [] (classBlock syn)
576589 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]
578591 <?> "type-class declaration"
579592 where
580593 carg :: IdrisParser (Name, PTerm)
@@ -831,7 +844,6 @@ clause syn
831844 return $ PClause fc n capp wargs rs wheres) <|> (do
832845 popIndent
833846 reserved "with"
834− lchar '(' <?> "parenthesized expression"
835847 wval <- bracketed syn
836848 openBlock
837849 ds <- some $ fnDecl syn
@@ -865,7 +877,6 @@ clause syn
865877 reserved "with"
866878 ist <- get
867879 put (ist { lastParse = Just n })
868− lchar '(' <?> "parenthesized expression"
869880 wval <- bracketed syn
870881 openBlock
871882 ds <- some $ fnDecl syn
@@ -1002,7 +1013,7 @@ directive syn = do try (lchar '%' *> reserved "lib"); cgn <- codegen_; lib <- st
10021013 Right msg ->
10031014 fail $ msg)]
10041015 <|> do try (lchar '%' *> reserved "name")
1005− ty <- iName []
1016+ ty <- fnName
10061017 ns <- sepBy1 name (lchar ',')
10071018 return [PDirective (do ty' <- disambiguate ty
10081019 mapM_ (addNameHint ty') ns
@@ -1023,7 +1034,7 @@ directive syn = do try (lchar '%' *> reserved "lib"); cgn <- codegen_; lib <- st
10231034 case lookupCtxtName n (idris_implicits i) of
10241035 [(n', _)] -> return n'
10251036 [] -> throwError (NoSuchVariable n)
1026− more -> throwError (CantResolveAlts (map (show . fst) more))
1037+ more -> throwError (CantResolveAlts (map fst more))
10271038
10281039pLangExt :: IdrisParser LanguageExt
10291040pLangExt = (reserved "TypeProviders" >> return TypeProviders)
@@ -1050,19 +1061,20 @@ ProviderWhat ::= 'proof' | 'term' | 'type' | 'postulate'
10501061 -}
10511062provider :: SyntaxInfo -> IdrisParser [PDecl]
10521063provider syn = do try (lchar '%' *> reserved "provide");
1053− what <- provideWhat
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]
1064+ provideTerm <|> providePostulate
10591065 <?> "type provider"
1060− where provideWhat :: IdrisParser ProvideWhat
1061− provideWhat = option ProvAny
1062− ( ((reserved "proof" <|> reserved "term" <|> reserved "type") *>
1063− pure ProvTerm)
1064− <|> (reserved "postulate" *> pure ProvPostulate)
1065− <?> "provider variety")
1066+ where provideTerm = do lchar '('; n <- fnName; lchar ':'; t <- typeExpr syn; lchar ')'
1067+ fc <- getFC
1068+ reserved "with"
1069+ e <- expr syn <?> "provider expression"
1070+ return [PProvider syn fc (ProvTerm t e) n]
1071+ providePostulate = do reserved "postulate"
1072+ n <- fnName
1073+ fc <- getFC
1074+ reserved "with"
1075+ e <- expr syn <?> "provider expression"
1076+ return [PProvider syn fc (ProvPostulate e) n]
1077+
10661078{- | Parses a transform
10671079
10681080@
@@ -1088,6 +1100,10 @@ transform syn = do try (lchar '%' *> reserved "transform")
10881100parseExpr :: IState -> String -> Result PTerm
10891101parseExpr st = runparser (fullExpr defaultSyntax) st "(input)"
10901102
1103+{- | Parses a constant form input -}
1104+parseConst :: IState -> String -> Result Const
1105+parseConst st = runparser constant st "(input)"
1106+
10911107{- | Parses a tactic from input -}
10921108parseTactic :: IState -> String -> Result PTactic
10931109parseTactic st = runparser (fullTactic defaultSyntax) st "(input)"
@@ -1160,8 +1176,7 @@ loadModule outh f
11601176 = idrisCatch (loadModule' outh f)
11611177 (\e -> do setErrSpan (getErrSpan e)
11621178 ist <- getIState
1163− msg <- showErr e
1164− ihputStrLn outh msg
1179+ ihWarn outh (getErrSpan e) $ pprintErr ist e
11651180 return "")
11661181
11671182{- | Load idris module -}
@@ -1171,26 +1186,26 @@ loadModule' outh f
11711186 let file = takeWhile (/= ' ') f
11721187 ibcsd <- valIBCSubDir i
11731188 ids <- allImportDirs
1174− fp <- liftIO $ findImport ids ibcsd file
1189+ fp <- findImport ids ibcsd file
11751190 if file `elem` imported i
11761191 then iLOG $ "Already read " ++ file
11771192 else do putIState (i { imported = file : imported i })
11781193 case fp of
1179− IDR fn -> loadSource outh False fn
1180− LIDR fn -> loadSource outh True fn
1194+ IDR fn -> loadSource outh False fn Nothing
1195+ LIDR fn -> loadSource outh True fn Nothing
11811196 IBC fn src ->
11821197 idrisCatch (loadIBC fn)
11831198 (\c -> do iLOG $ fn ++ " failed " ++ pshow i c
11841199 case src of
1185− IDR sfn -> loadSource outh False sfn
1186− LIDR sfn -> loadSource outh True sfn)
1200+ IDR sfn -> loadSource outh False sfn Nothing
1201+ LIDR sfn -> loadSource outh True sfn Nothing)
11871202 let (dir, fh) = splitFileName file
11881203 return (dropExtension fh)
11891204
11901205
11911206{- | Load idris code from file -}
1192−loadFromIFile :: Handle -> IFileType -> Idris ()
1193−loadFromIFile h i@(IBC fn src)
1207+loadFromIFile :: Handle -> IFileType -> Maybe Int -> Idris ()
1208+loadFromIFile h i@(IBC fn src) maxline
11941209 = do iLOG $ "Skipping " ++ getSrcFile i
11951210 idrisCatch (loadIBC fn)
11961211 (\err -> ierror $ LoadingFailed fn err)
@@ -1199,20 +1214,22 @@ loadFromIFile h i@(IBC fn src)
11991214 getSrcFile (LIDR fn) = fn
12001215 getSrcFile (IBC f src) = getSrcFile src
12011216
1202−loadFromIFile h (IDR fn) = loadSource' h False fn
1203−loadFromIFile h (LIDR fn) = loadSource' h True fn
1217+loadFromIFile h (IDR fn) maxline = loadSource' h False fn maxline
1218+loadFromIFile h (LIDR fn) maxline = loadSource' h True fn maxline
12041219
12051220{-| Load idris source code and show error if something wrong happens -}
1206−loadSource' :: Handle -> Bool -> FilePath -> Idris ()
1207−loadSource' h lidr r
1208− = idrisCatch (loadSource h lidr r)
1221+loadSource' :: Handle -> Bool -> FilePath -> Maybe Int -> Idris ()
1222+loadSource' h lidr r maxline
1223+ = idrisCatch (loadSource h lidr r maxline)
12091224 (\e -> do setErrSpan (getErrSpan e)
12101225 ist <- getIState
1211− ihRenderError h (pprintErr ist e))
1226+ case e of
1227+ At f e' -> ihWarn h f (pprintErr ist e')
1228+ _ -> ihWarn h (getErrSpan e) (pprintErr ist e))
12121229
12131230{- | Load Idris source code-}
1214−loadSource :: Handle -> Bool -> FilePath -> Idris ()
1215−loadSource h lidr f
1231+loadSource :: Handle -> Bool -> FilePath -> Maybe Int -> Idris ()
1232+loadSource h lidr f toline
12161233 = do iLOG ("Reading " ++ f)
12171234 i <- getIState
12181235 let def_total = default_total i
@@ -1221,11 +1238,11 @@ loadSource h lidr f
12211238 (mname, imports, pos) <- parseImports f file
12221239 ids <- allImportDirs
12231240 ibcsd <- valIBCSubDir i
1224− mapM_ (\f -> do fp <- runIO $ findImport ids ibcsd f
1241+ mapM_ (\f -> do fp <- findImport ids ibcsd f
12251242 case fp of
12261243 LIDR fn -> ifail $ "No ibc for " ++ f
12271244 IDR fn -> ifail $ "No ibc for " ++ f
1228− IBC fn src -> loadIBC fn)
1245+ IBC fn src -> loadIBC fn)
12291246 [fn | (fn, _, _) <- imports]
12301247 reportParserWarnings
12311248
@@ -1243,13 +1260,14 @@ loadSource h lidr f
12431260 putIState (i { default_access = Hidden, module_aliases = modAliases })
12441261 clearIBC -- start a new .ibc file
12451262 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 }
12471265 ds' <- parseProg syntax f file pos
12481266
12491267 -- Parsing done, now process declarations
12501268
12511269 let ds = namespaces mname ds'
1252− logLvl 3 (show $ showDecls True ds)
1270+ logLvl 3 (show $ showDecls verbosePPOption ds)
12531271 i <- getIState
12541272 logLvl 10 (show (toAlist (idris_implicits i)))
12551273 logLvl 3 (show (idris_infixes i))
@@ -1291,7 +1309,6 @@ loadSource h lidr f
12911309 addHides (hide_list i)
12921310
12931311 -- Finally, write an ibc if checking was successful
1294−
12951312 ok <- noErrors
12961313 when ok $
12971314 idrisCatch (do writeIBC f ibc; clearIBC)
@@ -1311,7 +1328,7 @@ loadSource h lidr f
13111328 toMutual x = let r = PMutual (fileFC "single mutual") [x] in
13121329 case x of
13131330 PClauses _ _ _ _ -> r
1314− PClass _ _ _ _ _ _ _ -> r
1331+ PClass _ _ _ _ _ _ _ _ -> r
13151332 PInstance _ _ _ _ _ _ _ _ -> r
13161333 _ -> x
13171334
src/Idris/Primitives.hs+63−9
@@ -28,9 +28,10 @@ ty :: [Const] -> Const -> Type
2828ty [] x = Constant x
2929ty (t:ts) x = Bind (sMN 0 "T") (Pi (Constant t)) (ty ts x)
3030
31−total, partial :: Totality
31+total, partial, iopartial :: Totality
3232total = Total []
3333partial = Partial NotCovering
34+iopartial = Partial ExternalIO
3435
3536primitives :: [Prim]
3637primitives =
@@ -164,22 +165,28 @@ primitives =
164165 Prim (sUN "prim__strRev") (ty [StrType] StrType) 1 (p_strRev)
165166 (1, LStrRev) total,
166167 Prim (sUN "prim__readString") (ty [PtrType] StrType) 1 (p_cantreduce)
167− (1, LReadStr) partial,
168+ (1, LReadStr) iopartial,
168169 Prim (sUN "prim__vm") (ty [] PtrType) 0 (p_cantreduce)
169170 (0, LVMPtr) total,
170171 -- Streams
171172 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,
173178 Prim (sUN "prim__null") (ty [] PtrType) 0 (p_cantreduce)
174179 (0, LNullPtr) total,
175180 -- Managed pointer registration
176181 Prim (sUN "prim__registerPtr") (ty [PtrType, AType (ATInt ITNative)] ManagedPtrType) 2 (p_cantreduce)
177182 (2, LRegisterPtr) total,
178183 -- 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)
180185 (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)
182− (6, LAppendBuffer) partial
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)
187+ (6, LAppendBuffer) partial,
188+ Prim (sUN "prim__systemInfo") (ty [AType (ATInt ITNative)] StrType) 1 (p_cantreduce)
189+ (1, LSystemInfo) total
183190 ] ++ concatMap intOps [ITFixed IT8, ITFixed IT16, ITFixed IT32, ITFixed IT64, ITBig, ITNative, ITChar]
184191 ++ concatMap vecOps vecTypes
185192 ++ concatMap fixedOps [ITFixed IT8, ITFixed IT16, ITFixed IT32, ITFixed IT64] -- ITNative, ITChar, ATFloat ] ++ vecTypes
@@ -287,10 +294,10 @@ fixedOps ity@(ITFixed _) =
287294 thisTy = AType $ ATInt ity
288295 appendFun en = Prim (sUN $ "prim__append" ++ tyName ++ show en)
289296 (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
291298 peekFun en = Prim (sUN $ "prim__peek" ++ tyName ++ show en)
292299 (ty [BufferType, b64] thisTy)
293− 2 (p_cantreduce) (2, LPeek ity en) partial
300+ 2 (p_peek ity en) (2, LPeek ity en) partial
294301
295302mapHalf :: (V.Unbox a, V.Unbox b) => ((a, a) -> b) -> Vector a -> Vector b
296303mapHalf 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
693700p_strRev [Str xs] = Just $ Str (reverse xs)
694701p_strRev _ = Nothing
695702
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+
696751p_cantreduce :: a -> Maybe b
697752p_cantreduce _ = Nothing
698−
src/Idris/ProofSearch.hs+61−13
@@ -14,6 +14,8 @@ import Idris.Error
1414
1515import Control.Applicative ((<$>))
1616import Control.Monad
17+import Control.Monad.State.Strict
18+import Data.List
1719import Debug.Trace
1820
1921-- 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)
3638 (tryAll xs) True
3739 else tryAll xs
3840
39−proofSearch :: (PTerm -> ElabD ()) -> Maybe Name -> Name -> [Name] ->
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
52+ (PTerm -> ElabD ()) -> Maybe Name -> Name -> [Name] ->
4053 IState -> ElabD ()
41−proofSearch elab fn nroot hints ist
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
85+proofSearch rec fromProver maxDepth elab fn nroot hints ist
4286 = case lookupCtxt nroot (idris_tyinfodata ist) of
4387 [TISolution ts] -> findInferredTy ts
44− _ -> psRec maxDepth
88+ _ -> psRec rec maxDepth
4589 where
46− maxDepth = 6
47−
4890 findInferredTy (t : _) = elab (delab ist (toUN t))
4991
5092 toUN t@(P nt (MN i n) ty)
@@ -53,12 +95,16 @@ proofSearch elab fn nroot hints ist
5395 toUN (App f a) = App (toUN f) (toUN a)
5496 toUN t = t
5597
56− psRec 0 = do attack; defer nroot; solve --fail "Maximum depth reached"
57− psRec d = try' (trivial elab ist)
58− (try' (try' (resolveByCon (d - 1)) (resolveByLocals (d - 1))
59− True)
98+ psRec _ 0 | fromProver = cantSolveGoal
99+ psRec rec 0 = do attack; defer nroot; solve --fail "Maximum depth reached"
100+ psRec False d = tryCons d hints
101+ psRec True d = try' (trivial elab ist)
102+ (try' (try' (resolveByCon (d - 1)) (resolveByLocals (d - 1))
103+ True)
60104 -- if all else fails, make a new metavariable
61− (do attack; defer nroot; solve) True) True
105+ (if fromProver
106+ then cantSolveGoal
107+ else do attack; defer nroot; solve) True) True
62108
63109 getFn d Nothing = []
64110 getFn d (Just f) | d < maxDepth-1 = [f]
@@ -91,7 +137,7 @@ proofSearch elab fn nroot hints ist
91137
92138 tryLocalArg d n 0 = elab (PRef (fileFC "prf") n)
93139 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"
95141
96142 -- Like type class resolution, but searching with constructors
97143 tryCon d n =
@@ -100,15 +146,17 @@ proofSearch elab fn nroot hints ist
100146 [args] -> map isImp (snd args)
101147 _ -> fail "Ambiguous name"
102148 ps <- get_probs
149+ hs <- get_holes
103150 args <- map snd <$> try' (apply (Var n) imps)
104151 (match_apply (Var n) imps) True
105152 ps' <- get_probs
153+ hs' <- get_holes
106154 when (length ps < length ps') $ fail "Can't apply constructor"
107155 mapM_ (\ (_, h) -> do focus h
108− psRec d)
156+ psRec True d)
109157 (filter (\ (x, y) -> not x) (zip (map fst imps) args))
110158 solve
111159
112160 isImp (PImp p _ _ _ _) = (True, p)
113− isImp arg = (False, priority arg)
161+ isImp arg = (False, priority arg)
114162
src/Idris/Prover.hs+29−17
@@ -85,10 +85,19 @@ prove opt ctxt lit n ty
8585 [([], P Ref n ty, ptm)]
8686 [([], P Ref n ty, ptm')] ty)
8787 solveDeferred n
88+
8889elabStep :: 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
9091 OK (a, st') -> return (a, st')
9192 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
92101
93102dumpState :: IState -> ProofState -> Idris ()
94103dumpState ist (PS nm [] _ _ tm _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) =
@@ -104,9 +113,9 @@ dumpState ist ps@(PS nm (h:hs) _ _ tm _ _ _ _ _ _ problems i _ _ ctxy _ _ _ _) =
104113 iputGoal rendered
105114
106115 where
107− showImplicits = opt_showimp (idris_options ist)
116+ ppo = ppOptionIst ist
108117
109− tPretty bnd t = pprintPTerm showImplicits bnd [] $ delab ist t
118+ tPretty bnd t = pprintPTerm ppo bnd [] (idris_infixes ist) $ delab ist t
110119
111120 assumptionNames :: Env -> [Name]
112121 assumptionNames = map fst
@@ -116,10 +125,11 @@ dumpState ist ps@(PS nm (h:hs) _ _ tm _ _ _ _ _ _ problems i _ _ ctxy _ _ _ _) =
116125 prettyPs bnd ((n@(MN _ r), _) : bs)
117126 | r == txt "rewrite_rule" = prettyPs ((n, False):bnd) bs
118127 prettyPs bnd ((n, Let t v) : bs) =
119− nest nestingSize (bindingOf n False <+> text "=" <+> tPretty bnd v <> colon <+>
120− tPretty ((n, False):bnd) t <> line <> prettyPs ((n, False):bnd) bs)
128+ line <> bindingOf n False <+> text "=" <+> tPretty bnd v <+> colon <+>
129+ align (tPretty bnd t) <> prettyPs ((n, False):bnd) bs
121130 prettyPs bnd ((n, b) : bs) =
122− line <> bindingOf n False <+> colon <+> align (tPretty bnd (binderTy b)) <> prettyPs ((n, False):bnd) bs
131+ line <> bindingOf n False <+> colon <+>
132+ align (tPretty bnd (binderTy b)) <> prettyPs ((n, False):bnd) bs
123133
124134 prettyG bnd (Guess t v) = tPretty bnd t <+> text "=?=" <+> tPretty bnd v
125135 prettyG bnd b = tPretty bnd $ binderTy b
@@ -231,15 +241,16 @@ ploop fn d prompt prf e h
231241 ctxt' = envCtxt env ctxt
232242 putIState ist { tt_ctxt = ctxt' }
233243 (tm, ty) <- elabVal toplevel False t
234− let imp = opt_showimp (idris_options ist)
235− ty' = normaliseC ctxt [] ty
236− h = idris_outh ist
244+ let ppo = ppOptionIst ist
245+ ty' = normaliseC ctxt [] ty
246+ h = idris_outh ist
247+ infixes = idris_infixes ist
237248 case tm of
238249 TType _ ->
239− ihPrintTermWithType h (prettyImp imp PType) type1Doc
250+ ihPrintTermWithType h (prettyImp ppo PType) type1Doc
240251 _ -> let bnd = map (\x -> (fst x, False)) env in
241− ihPrintTermWithType h (pprintPTerm imp bnd [] (delab ist tm))
242− (pprintPTerm imp bnd [] (delab ist ty))
252+ ihPrintTermWithType h (pprintPTerm ppo bnd [] infixes (delab ist tm))
253+ (pprintPTerm ppo bnd [] infixes (delab ist ty))
243254 putIState ist
244255 return (False, e, False, prf))
245256 (\err -> do putIState ist { tt_ctxt = ctxt } ; ierror err)
@@ -253,11 +264,12 @@ ploop fn d prompt prf e h
253264 bnd = map (\x -> (fst x, False)) env
254265 putIState ist'
255266 (tm, ty) <- elabVal toplevel False t
256− let tm' = force (normaliseAll ctxt' env tm)
257− ty' = force (normaliseAll ctxt' env ty)
258− imp = opt_showimp (idris_options ist')
259− tmDoc = pprintPTerm imp bnd [] (delab ist' tm')
260− tyDoc = pprintPTerm imp bnd [] (delab ist' ty')
267+ let tm' = force (normaliseAll ctxt' env tm)
268+ ty' = force (normaliseAll ctxt' env ty)
269+ ppo = ppOption (idris_options ist')
270+ infixes = idris_infixes ist
271+ tmDoc = pprintPTerm ppo bnd [] infixes (delab ist' tm')
272+ tyDoc = pprintPTerm ppo bnd [] infixes (delab ist' ty')
261273 ihPrintTermWithType (idris_outh ist') tmDoc tyDoc
262274 putIState ist
263275 return (False, e, False, prf))
src/Idris/Providers.hs+1−7
@@ -11,16 +11,14 @@ import Debug.Trace
1111
1212-- | Wrap a type provider in the type of type providers
1313providerTy :: FC -> PTerm -> PTerm
14−providerTy fc tm
14+providerTy fc tm
1515 = PApp fc (PRef fc $ sUN "Provider") [PExp 0 [] (sMN 0 "pvarg") tm]
1616
1717ioret = sUN "prim_io_return"
1818ermod = sNS (sUN "Error") ["Providers"]
1919prmod = sNS (sUN "Provide") ["Providers"]
20−posmod = sNS (sUN "Postulate") ["Providers"]
2120
2221data Provided a = Provide a
23− | Postulate
2422 deriving (Show, Eq, Functor)
2523
2624-- | 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
3533 , (P _ nm _, [_, res]) <- unApply result
3634 , pioret == ioret && nm == prmod
3735 = return . Provide $ res
38− | (P _ pioret _, [tp, result]) <- unApply tm
39− , (P _ nm _, [_]) <- unApply result
40− , pioret == ioret && nm == posmod
41− = return Postulate
4236 | otherwise = ifail $ "Internal type provider error: result was not " ++
4337 "IO (Provider a), or perhaps missing normalisation."
4438
src/Idris/REPL.hs+296−404
@@ -4,6 +4,7 @@
44module Idris.REPL where
55
66import Idris.AbsSyntax
7+import Idris.ASTUtils
78import Idris.Apropos (apropos)
89import Idris.REPLParser
910import Idris.ElabDecls
@@ -13,6 +14,7 @@ import Idris.Error
1314import Idris.ErrReverse
1415import Idris.Delaborate
1516import Idris.Docstrings (Docstring, overview, renderDocstring)
17+import Idris.IdrisDoc
1618import Idris.Prover
1719import Idris.Parser hiding (indent)
1820import Idris.Primitives
@@ -28,6 +30,9 @@ import Idris.Inliner
2830import Idris.CaseSplit
2931import Idris.DeepSeq
3032import Idris.Output
33+import Idris.Interactive
34+import Idris.WhoCalls
35+import Idris.TypeSearch (searchByType)
3136
3237import Paths_idris
3338import Version_idris (gitHash)
@@ -77,6 +82,7 @@ import Data.List
7782import Data.Char
7883import Data.Version
7984import Data.Word (Word)
85+import Data.Either (partitionEithers)
8086import Control.DeepSeq
8187
8288import Debug.Trace
@@ -104,7 +110,7 @@ repl orig mods
104110 return ()
105111 Just input -> -- H.catch
106112 do ms <- H.catch (lift $ processInput input orig mods)
107− (ctrlC (return (Just mods)))
113+ (ctrlC (return (Just mods)))
108114 case ms of
109115 Just mods -> repl orig mods
110116 Nothing -> return ()
@@ -115,7 +121,7 @@ repl orig mods
115121 act -- repl orig mods
116122
117123 showMVs c thm [] = ""
118− showMVs c thm ms = "Metavariables: " ++
124+ showMVs c thm ms = "Metavariables: " ++
119125 show' 4 c thm (map fst ms) ++ "\n"
120126
121127 show' 0 c thm ms = let l = length ms in
@@ -123,7 +129,7 @@ repl orig mods
123129 ++ " other"
124130 ++ if l == 1 then ")" else "s)"
125131 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 ++ ", " ++
127133 show' (n - 1) c thm ms
128134
129135 showM c thm n = if c then colouriseFun thm (show n)
@@ -161,8 +167,8 @@ processNetCmd orig i h fn cmd
161167 Left err -> do hPutStrLn h (show err)
162168 return (i, fn)
163169 where
164− processNet fn Reload = processNet fn (Load fn)
165− processNet fn (Load f) =
170+ processNet fn Reload = processNet fn (Load fn Nothing)
171+ processNet fn (Load f toline) =
166172 do let ist = orig { idris_options = idris_options i
167173 , idris_colourTheme = idris_colourTheme i
168174 , idris_colourRepl = False
@@ -172,7 +178,7 @@ processNetCmd orig i h fn cmd
172178 setOutH h
173179 setQuiet True
174180 setVerbose False
175− mods <- loadInputs h [f]
181+ mods <- loadInputs h [f] toline
176182 ist <- getIState
177183 return (ist, f)
178184 processNet fn c = do process h fn c
@@ -248,17 +254,22 @@ runIdeSlaveCommand id orig fn mods (IdeSlave.REPLCompletions str) =
248254 IdeSlave.toSExp (map replacement compls,
249255 reverse unused)]
250256 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) =
252258 do i <- getIState
253259 clearErr
254260 putIState (orig { idris_options = idris_options i,
255261 idris_outputmode = (IdeSlave id) })
256− loadInputs stdout [filename]
262+ loadInputs stdout [filename] toline
257263 isetPrompt (mkPrompt [filename])
258264 -- Report either success or failure
259265 i <- getIState
260266 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
262273 Just x -> iPrintError $ "didn't load " ++ filename
263274 ideslave orig [filename]
264275runIdeSlaveCommand id orig fn mods (IdeSlave.TypeOf name) =
@@ -272,14 +283,12 @@ runIdeSlaveCommand id orig fn mods (IdeSlave.TypeOf name) =
272283 [n] -> Right $ sUN n
273284 (n:ns) -> Right $ sNS (sUN n) ns
274285runIdeSlaveCommand id orig fn mods (IdeSlave.DocsFor name) =
275− case splitName name of
276− Left err -> iPrintError err
277− Right n -> process stdout "(ideslave)" (DocStr 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
286+ case parseConst orig name of
287+ Success c -> process stdout "(ideslave)" (DocStr (Right c))
288+ Failure _ ->
289+ case splitName name of
290+ Left err -> iPrintError err
291+ Right n -> process stdout "(ideslave)" (DocStr (Left n))
283292runIdeSlaveCommand id orig fn mods (IdeSlave.CaseSplit line name) =
284293 process stdout fn (CaseSplitAt False line (sUN name))
285294runIdeSlaveCommand id orig fn mods (IdeSlave.AddClause line name) =
@@ -290,8 +299,12 @@ runIdeSlaveCommand id orig fn mods (IdeSlave.AddMissing line name) =
290299 process stdout fn (AddMissing False line (sUN name))
291300runIdeSlaveCommand id orig fn mods (IdeSlave.MakeWithBlock line name) =
292301 process stdout fn (MakeWith False line (sUN name))
293−runIdeSlaveCommand id orig fn mods (IdeSlave.ProofSearch line name hints) =
294− process stdout fn (DoProofSearch False line (sUN name) (map sUN hints))
302+runIdeSlaveCommand id orig fn mods (IdeSlave.ProofSearch r line name hints depth) =
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)
295308runIdeSlaveCommand id orig fn mods (IdeSlave.Apropos a) =
296309 process stdout fn (Apropos a)
297310runIdeSlaveCommand id orig fn mods (IdeSlave.GetOpts) =
@@ -314,37 +327,68 @@ runIdeSlaveCommand id orig fn mods (IdeSlave.SetOpt IdeSlave.ErrContext b) =
314327runIdeSlaveCommand id orig fn mods (IdeSlave.Metavariables cols) =
315328 do ist <- getIState
316329 let mvs = reverse $ map fst (idris_metavars ist) \\ primDefs
317− imp <- impShow
330+ let ppo = ppOptionIst ist
318331 let mvarTys = map (delabTy ist) mvs
319332 let res = (IdeSlave.SymbolAtom "ok",
320333 zipWith (\ n (prems, concl) -> (n, prems, concl))
321334 (map (IdeSlave.StringAtom . show) mvs)
322− (map (sexpGoal ist cols imp [] . getGoal) mvarTys))
335+ (map (sexpGoal ist cols ppo [] . getGoal) mvarTys))
323336 runIO . putStrLn $ IdeSlave.convSExp "return" res id
324337 where getGoal :: PTerm -> ([(Name, PTerm)], PTerm)
325338 getGoal (PPi _ n t sc) = let (prems, conc) = getGoal sc
326339 in ((n, t):prems, conc)
327340 getGoal tm = ([], tm)
328− sexpGoal :: IState -> Int -> Bool -> [Name] -> ([(Name, PTerm)], PTerm)
341+ sexpGoal :: IState -> Int -> PPOption -> [Name] -> ([(Name, PTerm)], PTerm)
329342 -> ([(String, String, SpanList OutputAnnotation)],
330343 (String, SpanList OutputAnnotation))
331− sexpGoal ist cols imp ns ([], concl) =
332− let concl' = displaySpans . renderPretty 0.9 cols . fmap (fancifyAnnots ist) $
333− pprintPTerm imp (zip ns (repeat False)) [] concl
344+ sexpGoal ist cols ppo ns ([], concl) =
345+ let infixes = idris_infixes ist
346+ concl' = displaySpans . renderPretty 0.9 cols . fmap (fancifyAnnots ist) $
347+ pprintPTerm ppo (zip ns (repeat False)) [] infixes concl
334348 in ([], concl')
335− sexpGoal ist cols imp ns ((n, t):ps, concl) =
349+ sexpGoal ist cols ppo ns ((n, t):ps, concl) =
336350 let n' = case n of
337351 NS (UN nm) ns -> str nm
338352 UN nm | ('_':'_':_) <- str nm -> "_"
339353 | otherwise -> str nm
340354 _ -> "_"
341355 (t', spans) = displaySpans . renderPretty 0.9 cols . fmap (fancifyAnnots ist) $
342− pprintPTerm imp (zip ns (repeat False)) [] t
343− rest = sexpGoal ist cols imp (n:ns) (ps, concl)
356+ pprintPTerm ppo (zip ns (repeat False)) [] (idris_infixes ist) t
357+ rest = sexpGoal ist cols ppo (n:ns) (ps, concl)
344358 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
346389
347390ideslaveProcess :: FilePath -> Command -> Idris ()
391+ideslaveProcess fn Warranty = process stdout fn Warranty
348392ideslaveProcess fn Help = process stdout fn Help
349393ideslaveProcess fn (ChangeDirectory f) = do process stdout fn (ChangeDirectory f)
350394 iPrintResult "changed directory to"
@@ -359,7 +403,6 @@ ideslaveProcess fn (Defn n) = do process stdout fn (Defn n)
359403ideslaveProcess fn (TotCheck n) = process stdout fn (TotCheck n)
360404ideslaveProcess fn (DebugInfo n) = do process stdout fn (DebugInfo n)
361405 iPrintResult ""
362−ideslaveProcess fn (Info n) = process stdout fn (Info n)
363406ideslaveProcess fn (Search t) = process stdout fn (Search t)
364407ideslaveProcess fn (Spec t) = process stdout fn (Spec t)
365408-- RmProof and AddProof not supported!
@@ -400,11 +443,13 @@ ideslaveProcess fn (AddProofClauseFrom False pos str) = process stdout fn (AddPr
400443ideslaveProcess fn (AddClauseFrom False pos str) = process stdout fn (AddClauseFrom False pos str)
401444ideslaveProcess fn (AddMissing False pos str) = process stdout fn (AddMissing False pos str)
402445ideslaveProcess 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)
404447ideslaveProcess fn (SetConsoleWidth w) = do process stdout fn (SetConsoleWidth w)
405448 iPrintResult ""
406449ideslaveProcess fn (Apropos a) = do process stdout fn (Apropos a)
407450 iPrintResult ""
451+ideslaveProcess fn (WhoCalls n) = process stdout fn (WhoCalls n)
452+ideslaveProcess fn (CallsWho n) = process stdout fn (CallsWho n)
408453ideslaveProcess fn _ = iPrintError "command not recognized or not supported"
409454
410455
@@ -436,14 +481,14 @@ processInput cmd orig inputs
436481 , idris_colourTheme = idris_colourTheme i
437482 }
438483 clearErr
439− mods <- loadInputs stdout inputs
484+ mods <- loadInputs stdout inputs Nothing
440485 return (Just inputs)
441− Success (Load f) ->
486+ Success (Load f toline) ->
442487 do putIState orig { idris_options = idris_options i
443488 , idris_colourTheme = idris_colourTheme i
444489 }
445490 clearErr
446− mod <- loadInputs stdout [f]
491+ mod <- loadInputs stdout [f] toline
447492 return (Just [f])
448493 Success (ModImport f) ->
449494 do clearErr
@@ -467,7 +512,7 @@ resolveProof n'
467512 n <- case lookupNames n' ctxt of
468513 [x] -> return x
469514 [] -> return n'
470− ns -> ierror (CantResolveAlts (map show ns))
515+ ns -> ierror (CantResolveAlts ns)
471516 return n
472517
473518removeProof :: Name -> Idris ()
@@ -492,7 +537,7 @@ edit f orig
492537 putIState $ orig { idris_options = idris_options i
493538 , idris_colourTheme = idris_colourTheme i
494539 }
495− loadInputs stdout [f]
540+ loadInputs stdout [f] Nothing
496541-- clearOrigPats
497542 iucheck
498543 return ()
@@ -520,11 +565,13 @@ insertScript prf (x : xs) = x : insertScript prf xs
520565
521566process :: Handle -> FilePath -> Command -> Idris ()
522567process h fn Help = iPrintResult displayHelp
568+process h fn Warranty = iPrintResult warranty
523569process h fn (ChangeDirectory f)
524570 = do runIO $ setCurrentDirectory f
525571 return ()
526572process h fn (Eval t)
527− = withErrorReflection $ do (tm, ty) <- elabVal toplevel False t
573+ = withErrorReflection $ do logLvl 5 $ show t
574+ (tm, ty) <- elabVal toplevel False t
528575 ctxt <- getContext
529576 let tm' = force (normaliseAll ctxt [] tm)
530577 let ty' = force (normaliseAll ctxt [] ty)
@@ -533,41 +580,39 @@ process h fn (Eval t)
533580 ist <- getIState
534581 logLvl 3 $ "Raw: " ++ show (tm', ty')
535582 logLvl 10 $ "Debug: " ++ showEnvDbg [] tm'
536− let imp = opt_showimp (idris_options ist)
537− tmDoc = prettyImp imp (delab ist tm')
538− tyDoc = prettyImp imp (delab ist ty')
583+ let tmDoc = prettyIst ist (delab ist tm')
584+ tyDoc = prettyIst ist (delab ist ty')
539585 ihPrintTermWithType h tmDoc tyDoc
540586
541587process h fn (ExecVal t)
542588 = do ctxt <- getContext
543589 ist <- getIState
544− let imp = opt_showimp (idris_options ist)
545590 (tm, ty) <- elabVal toplevel False t
546591-- let tm' = normaliseAll ctxt [] tm
547592 let ty' = normaliseAll ctxt [] ty
548593 res <- execute tm
549− let (resOut, tyOut) = (prettyImp imp (delab ist res),
550− prettyImp imp (delab ist ty'))
594+ let (resOut, tyOut) = (prettyIst ist (delab ist res),
595+ prettyIst ist (delab ist ty'))
551596 ihPrintTermWithType h resOut tyOut
552597
553598process h fn (Check (PRef _ n))
554599 = do ctxt <- getContext
555600 ist <- getIState
556− imp <- impShow
601+ let ppo = ppOptionIst ist
557602 case lookupNames n ctxt of
558603 ts@(t:_) ->
559604 case lookup t (idris_metavars ist) of
560605 Just (_, i, _) -> ihRenderResult h . fmap (fancifyAnnots ist) $
561− showMetavarInfo imp ist n i
606+ showMetavarInfo ppo ist n i
562607 Nothing -> ihPrintFunTypes h [] n (map (\n -> (n, delabTy ist n)) ts)
563608 [] -> ihPrintError h $ "No such variable " ++ show n
564609 where
565− showMetavarInfo imp ist n i
610+ showMetavarInfo ppo ist n i
566611 = case lookupTy n (tt_ctxt ist) of
567− (ty:_) -> putTy imp ist i [] (delab ist (errReverse ist ty))
568− putTy :: Bool -> IState -> Int -> [(Name, Bool)] -> PTerm -> Doc OutputAnnotation
569− putTy imp ist 0 bnd sc = putGoal imp ist bnd sc
570− putTy imp ist i bnd (PPi _ n t sc)
612+ (ty:_) -> putTy ppo ist i [] (delab ist (errReverse ist ty))
613+ putTy :: PPOption -> IState -> Int -> [(Name, Bool)] -> PTerm -> Doc OutputAnnotation
614+ putTy ppo ist 0 bnd sc = putGoal ppo ist bnd sc
615+ putTy ppo ist i bnd (PPi _ n t sc)
571616 = let current = text " " <>
572617 (case n of
573618 MN _ _ -> text "_"
@@ -575,37 +620,41 @@ process h fn (Check (PRef _ n))
575620 _ -> bindingOf n False) <+>
576621 colon <+> align (tPretty bnd ist t) <> line
577622 in
578− current <> putTy imp ist (i-1) ((n,False):bnd) sc
579− putTy imp ist _ bnd sc = putGoal imp ist ((n,False):bnd) sc
580− putGoal imp ist bnd g
623+ current <> putTy ppo ist (i-1) ((n,False):bnd) sc
624+ putTy ppo ist _ bnd sc = putGoal ppo ist ((n,False):bnd) sc
625+ putGoal ppo ist bnd g
581626 = text "--------------------------------------" <$>
582627 annotate (AnnName n Nothing Nothing Nothing) (text $ show n) <+> colon <+>
583628 align (tPretty bnd ist g)
584629
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
586631
587632
588633process h fn (Check t)
589634 = do (tm, ty) <- elabVal toplevel False t
590635 ctxt <- getContext
591636 ist <- getIState
592− let imp = opt_showimp (idris_options ist)
637+ let ppo = ppOptionIst ist
593638 ty' = normaliseC ctxt [] ty
594639 case tm of
595640 TType _ ->
596− ihPrintTermWithType h (prettyImp imp PType) type1Doc
597− _ -> ihPrintTermWithType h (prettyImp imp (delab ist tm))
598− (prettyImp imp (delab ist ty))
641+ ihPrintTermWithType h (prettyIst ist PType) type1Doc
642+ _ -> ihPrintTermWithType h (prettyIst ist (delab ist tm))
643+ (prettyIst ist (delab ist ty))
599644
600−process h fn (DocStr n)
601− = do i <- getIState
602− let imp = opt_showimp (idris_options i)
603− case lookupCtxtName n (idris_docstrings i) of
645+process h fn (DocStr (Left n))
646+ = do ist <- getIState
647+ case lookupCtxtName n (idris_docstrings ist) of
604648 [] -> iPrintError $ "No documentation for " ++ show n
605− ns -> do toShow <- mapM (showDoc imp) ns
649+ ns -> do toShow <- mapM (showDoc ist) ns
606650 ihRenderResult h (vsep toShow)
607− where showDoc imp (n, d) = do doc <- getDocs n
608− return $ pprintDocs imp doc
651+ where showDoc ist (n, d) = do doc <- getDocs n
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+
609658process h fn Universes
610659 = do i <- getIState
611660 let cs = idris_constraints i
@@ -637,8 +686,8 @@ process h fn (TotCheck n)
637686 [] -> ihPrintError h $ "Unknown operator " ++ show n
638687 ts -> do ist <- getIState
639688 c <- colourise
640− imp <- impShow
641− let showN = showName (Just ist) [] imp c
689+ let ppo = ppOptionIst ist
690+ let showN = showName (Just ist) [] ppo c
642691 ihPrintResult h . concat . intersperse "\n" .
643692 map (\(n, t) -> showN n ++ " is " ++ showTotal t i) $
644693 ts
@@ -661,191 +710,21 @@ process h fn (DebugInfo n)
661710 iputStrLn $ "Size change: " ++ show sc
662711 when (not (null cg')) $ do iputStrLn "Call graph:\n"
663712 iputStrLn (show cg')
664−process h fn (Info n)
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!
713+process h fn (Search t) = searchByType h t
672714process 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
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
715+ = caseSplitAt h fn updatefile l n
685716process 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
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
717+ = addClauseFrom h fn updatefile l n
704718process 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
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
719+ = addProofClauseFrom h fn updatefile l n
723720process h fn (AddMissing updatefile l n)
724− = do src <- runIO $ readFile fn
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−
721+ = addMissing h fn updatefile l n
767722process h fn (MakeWith updatefile l n)
768− = do src <- runIO $ readFile fn
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
777− do let fb = fn ++ "~"
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)
786− = do src <- runIO $ readFile fn
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−
723+ = makeWith h fn updatefile l n
724+process h fn (MakeLemma updatefile l n)
725+ = makeLemma h fn updatefile l n
726+process h fn (DoProofSearch updatefile rec l n hints)
727+ = doProofSearch h fn updatefile rec l n hints Nothing
849728process h fn (Spec t)
850729 = do (tm, ty) <- elabVal toplevel False t
851730 ctxt <- getContext
@@ -871,14 +750,15 @@ process h fn (RmProof n')
871750
872751process h fn' (AddProof prf)
873752 = do fn <- do
874− ex <- runIO $ doesFileExist fn'
875− let fnExt = fn' <.> "idr"
753+ let fn'' = takeWhile (/= ' ') fn'
754+ ex <- runIO $ doesFileExist fn''
755+ let fnExt = fn'' <.> "idr"
876756 exExt <- runIO $ doesFileExist fnExt
877757 if ex
878− then return fn'
758+ then return fn''
879759 else if exExt
880760 then return fnExt
881− else ifail $ "Neither \""++fn'++"\" nor \""++fnExt++"\" exist"
761+ else ifail $ "Neither \""++fn''++"\" nor \""++fnExt++"\" exist"
882762 let fb = fn ++ "~"
883763 runIO $ copyFile fn fb -- make a backup in case something goes wrong!
884764 prog <- runIO $ readFile fb
@@ -915,13 +795,14 @@ process h fn (Prove n')
915795 [] -> ierror (Msg $ "Cannot find metavariable " ++ show n')
916796 [(n, (_,_,False))] -> return n
917797 [(_, (_,_,True))] -> ierror (Msg $ "Declarations not solvable using prover")
918− ns -> ierror (CantResolveAlts (map show ns))
798+ ns -> ierror (CantResolveAlts (map fst ns))
919799 prover (lit fn) n
920800 -- recheck totality
921801 i <- getIState
922802 totcheck (fileFC "(input)", n)
923803 mapM_ (\ (f,n) -> setTotality n Unchecked) (idris_totcheck i)
924804 mapM_ checkDeclTotality (idris_totcheck i)
805+ warnTotality
925806
926807process h fn (HNF t)
927808 = do (tm, ty) <- elabVal toplevel False t
@@ -934,23 +815,25 @@ process h fn (TestInline t)
934815 ctxt <- getContext
935816 ist <- getIState
936817 let tm' = inlineTerm ist tm
937− imp <- impShow
938818 c <- colourise
939819 iPrintResult (showTm ist (delab ist tm'))
940820process h fn Execute
941− = do ist <- getIState
942− (m, _) <- elabVal toplevel False
943− (PApp fc
944− (PRef fc (sUN "run__IO"))
945− [pexp $ PRef fc (sNS (sUN "main") ["Main"])])
946− (tmpn, tmph) <- runIO tempfile
947− runIO $ hClose tmph
948− t <- codegen
949− compile t tmpn m
950− case idris_outputmode ist of
951− RawOutput -> do runIO $ system tmpn
952− return ()
953− IdeSlave n -> do runIO . hPutStrLn h $ IdeSlave.convSExp "run-program" tmpn n
821+ = idrisCatch
822+ (do ist <- getIState
823+ (m, _) <- elabVal toplevel False
824+ (PApp fc
825+ (PRef fc (sUN "run__IO"))
826+ [pexp $ PRef fc (sNS (sUN "main") ["Main"])])
827+ (tmpn, tmph) <- runIO tempfile
828+ runIO $ hClose tmph
829+ t <- codegen
830+ compile t tmpn m
831+ case idris_outputmode ist of
832+ RawOutput -> do runIO $ system tmpn
833+ return ()
834+ IdeSlave n -> runIO . hPutStrLn h $
835+ IdeSlave.convSExp "run-program" tmpn n)
836+ (\e -> getIState >>= ihRenderError stdout . flip pprintErr e)
954837 where fc = fileFC "main"
955838process h fn (Compile codegen f)
956839 = do (m, _) <- elabVal toplevel False
@@ -968,7 +851,7 @@ process h fn (Missing n)
968851 = do i <- getIState
969852 let i' = i { idris_options = (idris_options i) { opt_showimp = True } }
970853 case lookupCtxt n (idris_patdefs i) of
971− [] -> return ()
854+ [] -> ihPrintError h $ "Unknown operator " ++ show n
972855 [(_, tms)] ->
973856 iPrintResult (showSep "\n" (map (showTm i') tms))
974857 _ -> iPrintError $ "Ambiguous name"
@@ -1007,6 +890,10 @@ process h fn (SetOpt ShowOrigErr) = setShowOrigErr True
1007890process h fn (UnsetOpt ShowOrigErr) = setShowOrigErr False
1008891process h fn (SetOpt AutoSolve) = setAutoSolve True
1009892process 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
1010897
1011898process h fn (SetOpt _) = iPrintError "Not a valid option"
1012899process h fn (UnsetOpt _) = iPrintError "Not a valid option"
@@ -1019,52 +906,54 @@ process h fn ColourOff
1019906 putIState $ ist { idris_colourRepl = False }
1020907process h fn ListErrorHandlers =
1021908 do ist <- getIState
1022− case idris_errorhandlers ist of
1023− [] -> iPrintResult "No registered error handlers"
1024− handlers ->
1025− iPrintResult $ "Registered error handlers: " ++ (concat . intersperse ", " . map show) handlers
909+ iPrintResult $ case idris_errorhandlers ist of
910+ [] -> "No registered error handlers"
911+ handlers -> "Registered error handlers: " ++ (concat . intersperse ", " . map show) handlers
1026912process h fn (SetConsoleWidth w) = setWidth w
1027913
1028914process h fn (Apropos a) =
1029915 do ist <- getIState
1030− let impl = opt_showimp (idris_options ist)
1031916 let names = apropos ist (T.pack a)
1032917 let aproposInfo = [ (n,
1033918 delabTy ist n,
1034919 fmap (overview . fst) (lookupCtxtExact n (idris_docstrings ist)))
1035920 | n <- sort names, isUN n ]
1036− ihRenderResult h $ vsep (map (renderApropos impl) 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
921+ ihRenderResult h $ vsep (map (prettyDocumentedIst ist) aproposInfo)
922+ where isUN (UN _) = True
1041923 isUN (NS n _) = isUN n
1042924 isUN _ = False
1043925
1044−classInfo :: ClassInfo -> Idris (Doc OutputAnnotation)
1045−classInfo ci = do ist <- getIState
1046− ctxt <- getContext
1047− return $
1048− text "Parameters:" <+>
1049− hsep (punctuate comma (map (prettyName False params') params)) <>
1050− line <> line <>
1051− text "Methods:" <> line <>
1052− indent 2 (vsep (map (dumpMethod ist) (class_methods ci))) <> line <> line <>
1053− text "Default superclass instances:" <>
1054− line <>
1055− indent 2 (vsep (map (dumpDefaultInstance ist) (class_default_superclasses ci))) <>
1056− line <>
1057− text "Instances:" <> line <>
1058− indent 2 (vsep (map (dumpInstance ist ctxt) (class_instances ci)))
1059− where dumpMethod :: IState -> (Name, (FnOpts, PTerm)) -> Doc OutputAnnotation
1060− dumpMethod ist (n, (_, t)) = prettyName False [] n <+> colon <+> pp ist t
1061− dumpDefaultInstance :: IState -> PDecl -> Doc OutputAnnotation
1062− dumpDefaultInstance ist (PInstance _ _ _ _ _ t _ _) = pp ist t
1063− dumpInstance :: IState -> Context -> Name -> Doc OutputAnnotation
1064− dumpInstance ist ctxt n = pp ist $ delabTy ist n
1065− params = class_params ci
1066− params' = zip params (repeat False)
1067− pp ist = pprintPTerm (opt_showimp (idris_options ist)) params' []
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
937+ ist <- getIState
938+ ihRenderResult h . vsep $
939+ map (\(n, ns) ->
940+ prettyName True [] n <+> text "calls:" <$>
941+ indent 1 (vsep (map ((text "*" <+>) . align . prettyName True []) ns)))
942+ calls
943+-- IdrisDoc
944+process h fn (MakeDoc s) =
945+ do istate <- getIState
946+ let names = words s
947+ parse n | Success x <- runparser name istate fn n = Right x
948+ parse n = Left n
949+ (bad, nss) = partitionEithers $ map parse names
950+ cd <- runIO $ getCurrentDirectory
951+ let outputDir = cd </> "doc"
952+ result <- if null bad then runIO $ generateDocs istate nss outputDir
953+ else return . Left $ "Illegal name: " ++ head bad
954+ case result of Right _ -> iputStrLn "IdrisDoc generated"
955+ Left err -> iPrintError err
956+
1068957
1069958showTotal :: Totality -> IState -> String
1070959showTotal t@(Partial (Other ns)) i
@@ -1084,80 +973,6 @@ displayHelp = let vstr = showVersion version in
1084973 l ++ take (c1 - length l) (repeat ' ') ++
1085974 m ++ take (c2 - length m) (repeat ' ') ++ r ++ "\n"
1086975
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−
1161976helphead =
1162977 [ (["Command"], SpecialHeaderArg, "Purpose"),
1163978 ([""], NoArg, "")
@@ -1169,17 +984,22 @@ replSettings hFile = setComplete replCompletion $ defaultSettings {
1169984 historyFile = hFile
1170985 }
1171986
1172−-- invoke as if from command line
987+-- | Invoke as if from command line. It is an error if there are unresolved totality problems.
1173988idris :: [Opt] -> IO (Maybe IState)
1174−idris opts = do res <- runErrorT $ execStateT (idrisMain opts) idrisInit
989+idris opts = do res <- runErrorT $ execStateT totalMain idrisInit
1175990 case res of
1176991 Left err -> do putStrLn $ pshow idrisInit err
1177992 return Nothing
1178993 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 ()
1179999
11801000
1181−loadInputs :: Handle -> [FilePath] -> Idris ()
1182−loadInputs h inputs
1001+loadInputs :: Handle -> [FilePath] -> Maybe Int -> Idris ()
1002+loadInputs h inputs toline -- furthest line to read in input source files
11831003 = idrisCatch
11841004 (do ist <- getIState
11851005 -- if we're in --check and not outputting anything, don't bother
@@ -1204,14 +1024,13 @@ loadInputs h inputs
12041024 let ifiles = getModuleFiles modTree
12051025 iLOG ("MODULE TREE : " ++ show modTree)
12061026 iLOG ("RELOAD: " ++ show ifiles)
1207− when (not (all ibc ifiles) || loadCode) $
1027+ when (not (all ibc ifiles) || loadCode) $
12081028 tryLoad False (filter (not . ibc) ifiles)
12091029 -- return the files that need rechecking
1210− return ifiles)
1030+ return ifiles)
12111031 ninputs
12121032 inew <- getIState
12131033 let tidata = idris_tyinfodata inew
1214− let lineapps = idris_lineapps inew
12151034 let patdefs = idris_patdefs inew
12161035 -- If it worked, load the whole thing from all the ibcs together
12171036 case errSpan inew of
@@ -1222,38 +1041,56 @@ loadInputs h inputs
12221041 _ -> return ()
12231042 ist <- getIState
12241043 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 ())
12271051 (\e -> do i <- getIState
12281052 case e of
1229− At f _ -> do setErrSpan f
1230− ihRenderError stdout $ pprintErr i e
1053+ At f e' -> do setErrSpan f
1054+ ihWarn stdout f $ pprintErr i e'
12311055 ProgramLineComment -> return () -- fail elsewhere
12321056 _ -> do setErrSpan emptyFC -- FIXME! Propagate it
1233− iputStrLn (pshow i e))
1057+ ihWarn stdout emptyFC $ pprintErr i e)
12341058 where -- load all files, stop if any fail
12351059 tryLoad :: Bool -> [IFileType] -> Idris ()
1236− tryLoad keepstate [] = return ()
1237− tryLoad keepstate (f : fs)
1060+ tryLoad keepstate [] = warnTotality >> return ()
1061+ tryLoad keepstate (f : fs)
12381062 = do ist <- getIState
1239− loadFromIFile h f
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
1074+ loadFromIFile h f maxline
12401075 inew <- getIState
12411076 -- FIXME: Save these in IBC to avoid this hack! Need to
12421077 -- preserve it all from source inputs
12431078 let tidata = idris_tyinfodata inew
1244− let lineapps = idris_lineapps inew
12451079 let patdefs = idris_patdefs inew
12461080 ok <- noErrors
12471081 when ok $ do when (not keepstate) $ putIState ist
12481082 ist <- getIState
12491083 putIState (ist { idris_tyinfodata = tidata,
1250− idris_lineapps = lineapps,
12511084 idris_patdefs = patdefs })
12521085 tryLoad keepstate fs
12531086
12541087 ibc (IBC _ _) = True
12551088 ibc _ = False
12561089
1090+ fmatch ('.':'/':xs) ys = fmatch xs ys
1091+ fmatch xs ('.':'/':ys) = fmatch xs ys
1092+ fmatch xs ys = xs == ys
1093+
12571094 findNewIBC :: IFileType -> Idris (Maybe IFileType)
12581095 findNewIBC i@(IBC _ _) = return (Just i)
12591096 findNewIBC s@(IDR f) = do ist <- get
@@ -1310,17 +1147,20 @@ idrisMain opts =
13101147 x:y:xs -> do iputStrLn "More than one interpreter expression found."
13111148 runIO $ exitWith (ExitFailure 1)
13121149 [expr] -> return (Just expr)
1150+ let immediate = opt getEvalExpr opts
1151+
13131152 when (DefaultTotal `elem` opts) $ do i <- getIState
13141153 putIState (i { default_total = True })
13151154 setColourise $ not quiet && last (True : opt getColour opts)
13161155 when (not runrepl) $ setWidth InfinitelyWide
13171156 mapM_ addLangExt (opt getLanguageExt opts)
13181157 setREPL runrepl
1319− setQuiet (quiet || isJust script)
1158+ setQuiet (quiet || isJust script || not (null immediate))
13201159 setIdeSlave idesl
13211160 setVerbose verbose
13221161 setCmdLine opts
13231162 setOutputTy outty
1163+ setNoBanner nobanner
13241164 setCodegen cgn
13251165 setTargetTriple trpl
13261166 setTargetCPU tcpu
@@ -1335,6 +1175,8 @@ idrisMain opts =
13351175 (d:_) -> setIBCSubDir d
13361176 setImportDirs importdirs
13371177
1178+ setNoBanner nobanner
1179+
13381180 when (not (NoBasePkgs `elem` opts)) $ do
13391181 addPkgDir "prelude"
13401182 addPkgDir "base"
@@ -1344,22 +1186,43 @@ idrisMain opts =
13441186 return ()
13451187 when (not (NoPrelude `elem` opts)) $ do x <- loadModule stdout "Prelude"
13461188 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
13481201
13491202 orig <- getIState
1350− loadInputs stdout inputs
1203+ loadInputs stdout inputs Nothing
13511204
13521205 runIO $ hSetBuffering stdout LineBuffering
13531206
13541207 ok <- noErrors
13551208 when ok $ case output of
1356− -- just do the checks
1357− [] -> performUsageAnalysis >> return ()
1358−
1359− -- the compiler will run usage analysis itself
1209+ [] -> return ()
13601210 (o:_) -> idrisCatch (process stdout "" (Compile cgn o))
13611211 (\e -> do ist <- getIState ; iputStrLn $ pshow ist e)
13621212
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+
13631226 case script of
13641227 Nothing -> return ()
13651228 Just expr -> execScript expr
@@ -1375,7 +1238,6 @@ idrisMain opts =
13751238
13761239 when (runrepl && not idesl) $ do
13771240-- clearOrigPats
1378− initScript
13791241 startServer orig inputs
13801242 runInputT (replSettings (Just historyFile)) $ repl orig inputs
13811243 when (idesl) $ ideslaveStart orig inputs
@@ -1435,7 +1297,7 @@ initScript = do script <- getInitScript
14351297 case parseCmd i input cmd of
14361298 Failure err -> runIO $ print (fixColour clr err)
14371299 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"
14391301 Success (ModImport f) -> iPrintError "Init scripts cannot import modules"
14401302 Success Edit -> iPrintError "Init scripts cannot invoke the editor"
14411303 Success Proofs -> proofs i
@@ -1483,6 +1345,18 @@ getPkgCheck :: Opt -> Maybe String
14831345getPkgCheck (PkgCheck str) = Just str
14841346getPkgCheck _ = Nothing
14851347
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+
14861360getCodegen :: Opt -> Maybe Codegen
14871361getCodegen (UseCodegen x) = Just x
14881362getCodegen _ = Nothing
@@ -1491,6 +1365,10 @@ getExecScript :: Opt -> Maybe String
14911365getExecScript (InterpretScript expr) = Just expr
14921366getExecScript _ = Nothing
14931367
1368+getEvalExpr :: Opt -> Maybe String
1369+getEvalExpr (EvalExpr expr) = Just expr
1370+getEvalExpr _ = Nothing
1371+
14941372getOutputTy :: Opt -> Maybe OutputType
14951373getOutputTy (OutputTy t) = Just t
14961374getOutputTy _ = Nothing
@@ -1524,6 +1402,20 @@ banner = " ____ __ _ \n" ++
15241402 " / _/___/ /____(_)____ \n" ++
15251403 " / // __ / ___/ / ___/ Version " ++ ver ++ "\n" ++
15261404 " _/ // /_/ / / / (__ ) http://www.idris-lang.org/ \n" ++
1527− " /___/\\__,_/_/ /_/____/ Type :? for help \n"
1528−
1529−
1405+ " /___/\\__,_/_/ /_/____/ Type :? for help \n" ++
1406+ "\n" ++
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
3333pCmd :: P.IdrisParser Command
3434pCmd = do P.whiteSpace; try (do cmd ["q", "quit"]; eof; return Quit)
3535 <|> try (do cmd ["h", "?", "help"]; eof; return Help)
36+ <|> try (do cmd ["w", "warranty"]; eof; return Warranty)
3637 <|> try (do cmd ["r", "reload"]; eof; return Reload)
3738 <|> try (do cmd ["module"]; f <- P.identifier; eof;
3839 return (ModImport (toPath f)))
3940 <|> try (do cmd ["e", "edit"]; eof; return Edit)
4041 <|> 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 ["jc", "newcompile"]; f <- P.identifier; eof; return (Compile ViaJava f))
43− <|> try (do cmd ["js", "javascript"]; f <- P.identifier; eof; return (Compile ViaJavaScript f))
42+ <|> try (do cmd ["c", "compile"]
43+ i <- get
44+ c <- option (opt_codegen $ idris_options i) codegenOption
45+ f <- P.identifier
46+ eof
47+ return (Compile c f))
4448 <|> try (do cmd ["proofs"]; eof; return Proofs)
4549 <|> try (do cmd ["rmproof"]; n <- P.name; eof; return (RmProof n))
4650 <|> try (do cmd ["showproof"]; n <- P.name; eof; return (ShowProof n))
4751 <|> try (do cmd ["log"]; i <- P.natural; eof; return (LogLvl (fromIntegral i)))
48− <|> try (do cmd ["l", "load"]; f <- many anyChar; return (Load f))
52+ <|> try (do cmd ["lto", "loadto"];
53+ toline <- P.natural
54+ f <- many anyChar;
55+ return (Load f (Just (fromInteger toline))))
56+ <|> try (do cmd ["l", "load"]; f <- many anyChar;
57+ return (Load f Nothing))
4958 <|> try (do cmd ["cd"]; f <- many anyChar; return (ChangeDirectory f))
5059 <|> try (do cmd ["spec"]; P.whiteSpace; t <- P.fullExpr defaultSyntax; return (Spec t))
5160 <|> try (do cmd ["hnf"]; P.whiteSpace; t <- P.fullExpr defaultSyntax; return (HNF t))
5261 <|> try (do cmd ["inline"]; P.whiteSpace; t <- P.fullExpr defaultSyntax; return (TestInline t))
53− <|> try (do cmd ["doc"]; n <- P.fnName; eof; return (DocStr n))
62+ <|> try (do cmd ["doc"]; c <- P.constant; eof; return (DocStr (Right c)))
63+ <|> try (do cmd ["doc"]; n <- (P.fnName <|> (P.string "_|_" >> return falseTy)); eof; return (DocStr (Left n)))
5464 <|> try (do cmd ["d", "def"]; some (P.char ' ') ; n <- P.fnName; eof; return (Defn n))
5565 <|> try (do cmd ["total"]; do n <- P.fnName; eof; return (TotCheck n))
5666 <|> try (do cmd ["t", "type"]; do P.whiteSpace; t <- P.fullExpr defaultSyntax; return (Check t))
5767 <|> try (do cmd ["u", "universes"]; eof; return Universes)
5868 <|> 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))
6069 <|> try (do cmd ["miss", "missing"]; n <- P.fnName; eof; return (Missing n))
6170 <|> try (do cmd ["dynamic"]; eof; return ListDynamic)
6271 <|> try (do cmd ["dynamic"]; l <- many anyChar; return (DynamicLink l))
6372 <|> try (do cmd ["color", "colour"]; pSetColourCmd)
6473 <|> try (do cmd ["set"]; o <- pOption; return (SetOpt o))
6574 <|> 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))
6777 <|> try (do cmd ["cs", "casesplit"]; P.whiteSpace;
6878 upd <- option False (do P.lchar '!'; return True)
6979 l <- P.natural; n <- P.name;
@@ -84,11 +94,20 @@ pCmd = do P.whiteSpace; try (do cmd ["q", "quit"]; eof; return Quit)
8494 upd <- option False (do P.lchar '!'; return True)
8595 l <- P.natural; n <- P.name;
8696 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))
87101 <|> try (do cmd ["ps", "proofsearch"]; P.whiteSpace;
88102 upd <- option False (do P.lchar '!'; return True)
89103 l <- P.natural; n <- P.name;
90− hints <- many P.name
91− return (DoProofSearch upd (fromInteger l) n hints))
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
110+ return (DoProofSearch upd False (fromInteger l) n [hint]))
92111 <|> try (do cmd ["p", "prove"]; n <- P.name; eof; return (Prove n))
93112 <|> try (do cmd ["m", "metavars"]; eof; return Metavars)
94113 <|> 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)
99118 <|> try (do cmd ["errorhandlers"]; eof ; return ListErrorHandlers)
100119 <|> try (do cmd ["consolewidth"]; w <- pConsoleWidth ; return (SetConsoleWidth w))
101120 <|> 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))
102124 <|> do P.whiteSpace; do eof; return NOP
103125 <|> do t <- P.fullExpr defaultSyntax; return (Eval t)
104126
@@ -109,6 +131,16 @@ pOption = do discard (P.symbol "errorcontext"); return ErrContext
109131 <|> do discard (P.symbol "showimplicits"); return ShowImpl
110132 <|> do discard (P.symbol "originalerrors"); return ShowOrigErr
111133 <|> 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
112144
113145pConsoleWidth :: P.IdrisParser ConsoleWidth
114146pConsoleWidth = do discard (P.symbol "auto"); return AutomaticWidth
@@ -152,7 +184,7 @@ pColourMod = try (P.symbol "vivid" >> return doVivid)
152184 doNoItalic i = i { italic = False }
153185 doSetColour c i = i { colour = c }
154186
155−
187+-- | Generate the colour type names using the default Show instance.
156188colourTypes :: [(String, ColourType)]
157189colourTypes = map (\x -> ((map toLower . reverse . drop 6 . reverse . show) x, x)) $
158190 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+
13module Pkg.PParser where
24
35import Text.Trifecta hiding (span, stringLiteral, charLiteral, natural, symbol, char, string, whiteSpace)
@@ -6,6 +8,7 @@ import Idris.Core.TT
68import Idris.REPL
79import Idris.AbsSyntaxTree
810import Idris.ParseHelpers
11+import Idris.CmdOptions
912
1013import Paths_idris
1114
@@ -23,11 +26,16 @@ data PkgDesc = PkgDesc { pkgname :: String,
2326 sourcedir :: String,
2427 modules :: [Name],
2528 idris_main :: Name,
26− execout :: Maybe String
29+ execout :: Maybe String,
30+ idris_tests :: [Name]
2731 }
2832 deriving Show
2933
30−defaultPkg = PkgDesc "" [] [] Nothing [] "" [] (sUN "") Nothing
34+instance TokenParsing PParser where
35+ someSpace = many (simpleWhiteSpace <|> singleLineComment <|> multiLineComment) *> pure ()
36+
37+
38+defaultPkg = PkgDesc "" [] [] Nothing [] "" [] (sUN "") Nothing []
3139
3240parseDesc :: FilePath -> IO PkgDesc
3341parseDesc fp = do p <- readFile fp
@@ -60,7 +68,7 @@ pClause = do reserved "executable"; lchar '=';
6068 <|> do reserved "opts"; lchar '=';
6169 opts <- stringLiteral
6270 st <- get
63− let args = parseArgs (words opts)
71+ let args = pureArgParser (words opts)
6472 put (st { idris_opts = args })
6573 <|> do reserved "modules"; lchar '=';
6674 ms <- sepBy1 (iName []) (lchar ',')
@@ -78,4 +86,8 @@ pClause = do reserved "executable"; lchar '=';
7886 mk <- iName []
7987 st <- get
8088 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 }
8193
src/Pkg/Package.hs+76−3
@@ -5,18 +5,24 @@ import System.Process
55import System.Directory
66import System.Exit
77import System.IO
8−import System.FilePath ((</>), addTrailingPathSeparator, takeFileName)
8+import System.FilePath ((</>), addTrailingPathSeparator, takeFileName, takeDirectory, normalise)
99import System.Directory (createDirectoryIfMissing, copyFile)
1010
1111import Util.System
1212
1313import Control.Monad
14+import Control.Monad.Trans.State.Strict (execStateT)
15+import Control.Monad.Error (runErrorT)
16+
1417import Data.List
1518import Data.List.Split(splitOn)
1619
1720import Idris.Core.TT
1821import Idris.REPL
22+import Idris.Parser (loadModule)
23+import Idris.Output (pshow)
1924import Idris.AbsSyntax
25+import Idris.IdrisDoc
2026import Idris.Output
2127
2228import IRTS.System
@@ -74,7 +80,7 @@ checkPkg :: Bool -- ^ Show Warnings
7480 -> FilePath -- ^ Path to ipkg file.
7581 -> IO ()
7682checkPkg warnonly quit fpath
77− = do pkgdesc <-parseDesc fpath
83+ = do pkgdesc <- parseDesc fpath
7884 ok <- mapM (testLib warnonly (pkgname pkgdesc)) (libdeps pkgdesc)
7985 when (and ok) $
8086 do dir <- getCurrentDirectory
@@ -122,6 +128,74 @@ cleanPkg fp
122128 Nothing -> return ()
123129 Just s -> rmFile $ dir </> s
124130
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+
125199-- | Install package
126200installPkg :: PkgDesc -> IO ()
127201installPkg pkgdesc
@@ -132,7 +206,6 @@ installPkg pkgdesc
132206 Just o -> return () -- do nothing, keep executable locally, for noe
133207 mapM_ (installObj (pkgname pkgdesc)) (objs pkgdesc)
134208
135−
136209-- ---------------------------------------------------------- [ Helper Methods ]
137210-- Methods for building, testing, installing, and removal of idris
138211-- packages.
test/Makefile+1−1
@@ -11,7 +11,7 @@ test_java:
1111 perl ./runtest.pl without buffer001 reg039 --codegen Java
1212
1313test_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
1515
1616test_llvm:
1717 @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
55effects: Effects package
66error: Error messages and error reflection
77ffi: FFI calls, including type providers
8+idrisdoc: Documentation tool functionality
89interactive: Interactive editing, proof search
910io: IO monad
1011literate: .lidr files; literate programming
test/basic006/expected+2−2
@@ -1,5 +1,5 @@
1−When elaborating right hand side of foo:
2−test020a.idr:14:18:When elaborating an application of function Prelude.List.reverse:
1+test020a.idr:14:18:When elaborating right hand side of foo:
2+When elaborating an application of function Prelude.List.reverse:
33 Can't unify
44 Vect n a
55 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
44
55%language TypeProviders
66
7−bad : IO (Provider _|_)
8−bad = pure Postulate
7+bad : IO (Provider Type)
8+bad = return $ pure _|_
99
10−%provide (oops : _|_) with bad
10+%provide postulate oops with bad
1111
1212main : IO ()
1313main = 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 @@
11oops
2−oops
3−Attempted to provide a postulate where a term was expected.
test/ffi005/run−7
@@ -3,10 +3,3 @@
33idris $@ Postulate.idr -o postulate
44./postulate
55rm -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
55n : Integer
66n = 1000000
77
8−numbersList : List Bits64
8+numbersList : List Integer
99numbersList = numbersList' n []
1010 where
11− numbersList' : Integer -> List Bits64 -> List Bits64
11+ numbersList' : Integer -> List Integer -> List Integer
1212 numbersList' 0 xs = xs
1313 numbersList' k xs = numbersList' (k - 1) (fromInteger k :: xs)
1414
15−numbersVect : Vect (length numbersList) Bits64
15+numbersVect : Vect (length numbersList) Integer
1616numbersVect = fromList numbersList
1717
1818main : IO ()
1919main = do
20− putStrLn . show . prim__zextB64_BigInt $ addAll numbersVect
21− putStrLn . show . prim__zextB64_BigInt $ addAll numbersList
20+ putStrLn . show . addAll $ numbersVect
21+ putStrLn . show . addAll $ numbersList
2222
2323
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
44
55 localZipWith f (_ :: _) (x :: ys) = ?localZipWith_rhs_1
66
7−f x :: (map f xs)
7+f x :: map f xs
88isElem2 x (y :: ys) with (_)
99 isElem2 x (y :: ys) | with_pat = ?isElem2_rhs
1010 isElem3 x (x :: ys) | (Yes refl) = ?isElem3_rhs_3
test/interactive003/expected+2−2
@@ -1,5 +1,5 @@
11Type checking ./interactive003.idr
22ys
3−x :: (app xs ys)
3+x :: app xs ys
44[]
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
33Matrix : Type -> Nat -> Nat -> Type
44Matrix a n m = Vect n (Vect m a)
55
6−transpose : Matrix a (S n) (S m) -> Matrix a (S m) (S n)
7−transpose ((x:: []) :: []) = [[x]]
8−transpose [x :: y :: xs] = [x] :: (transpose [y :: xs])
9−transpose (x :: y :: xs)
10− = let tx = transpose [x] in
11− let ux = transpose (y :: xs) in zipWith (++) tx ux
6+mytranspose : Matrix a (S n) (S m) -> Matrix a (S m) (S n)
7+mytranspose ((x:: []) :: []) = [[x]]
8+mytranspose [x :: y :: xs] = [x] :: (mytranspose [y :: xs])
9+mytranspose (x :: y :: xs)
10+ = let tx = mytranspose [x] in
11+ let ux = mytranspose (y :: xs) in zipWith (++) tx ux
1212
test/reg018/expected+1
@@ -1,4 +1,5 @@
11reg018a.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
23reg018b.idr:8:1:A.showB is possibly not total due to recursive path A.showB
34reg018c.idr:19:1:CodataTest.inf is possibly not total due to: {CodataTest.inf19}
45reg018d.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
33idris $@ reg018b.idr --check
44idris $@ reg018c.idr --check
55idris $@ reg018d.idr --check
6+rm *.ibc
test/reg029/run+3−10
@@ -2,13 +2,6 @@
22idris $@ reg029.idr -o reg029
33unset IDRIS_REG029_NONEXISTENT_VAR
44export 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
12−esac
13−idris $@ reg029.idr --exec
14−rm -f reg029 *.ibc *.class
5+./reg029
6+idris $@ reg029.idr --execute
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)
88
99class Set univ => HasPower univ where
1010 Powerset : (a : univ) ->
11− Exists univ (\Pa => (c : univ) ->
11+ Sigma univ (\Pa => (c : univ) ->
1212 (isSubsetOf c a) -> member c Pa)
1313
1414powerset : HasPower univ => univ -> univ
test/reg034/expected+2−2
@@ -1,7 +1,7 @@
11reg034.idr:6:5:When elaborating left hand side of bar:
22When elaborating an application of main.bar:
33 Can't unify
4− x = x
4+ length ys = length ys
55 with
66 length xs = length ys
77
@@ -13,7 +13,7 @@ When elaborating an application of main.bar:
1313reg034.idr:9:5:When elaborating left hand side of foo:
1414When elaborating an application of main.foo:
1515 Can't unify
16− x = x
16+ f y = f y
1717 with
1818 f x = f y
1919
test/reg039/run+7−1
@@ -22,5 +22,11 @@ timeout() {
2222
2323}
2424
25−timeout 60 "idris $@ --nocolour reg039.idr --exec go"
25+declare -a extraargs
26+for arg in "$@"
27+do
28+ extraargs=("${extraargs[@]}" "'$arg'")
29+done
30+
31+timeout 60 "idris ${extraargs[*]} --nocolour reg039.idr --exec go"
2632rm -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 @@
11#!/usr/bin/env bash
2−idris $@ test010.idr -o test010
3−idris $@ test010a.idr -o test010
4−idris $@ test010b.idr -o test010
2+idris $@ --check test010.idr
3+idris $@ --check test010a.idr
4+idris $@ --check test010b.idr
55
66rm -f *.ibc
test/totality004/expected+1
@@ -1,2 +1,3 @@
11[1, 2, 2, 4, 3, 6, 4, 8, 5, 10]
22totality004a.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
21[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 @@
22zipWithS : (f : a -> b -> c) -> Stream a -> Stream b -> Stream c
33zipWithS f (x :: xs) (y :: ys) = f x y :: zipWithS f xs ys
44
5+partial
56fib : Stream Nat
67fib = 0 :: zipWithS (+) fib (1 :: fib)
78
8−main : IO ()
9+partial main : IO ()
910main = 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 @@
11tutorial006a.idr:3:23:When elaborating right hand side of vapp:
22When elaborating argument xs to constructor Prelude.Vect.:::
33 Can't unify
4− Vect (n + m) a
4+ Vect (n + n) a
55 with
66 Vect (plus n m) a
77
88 Specifically:
99 Can't unify
10− plus n m
10+ plus n n
1111 with
1212 plus n m
1313tutorial006b.idr:10:10:When elaborating right hand side of Main.parity: