on master help sign in
Merge branch 'master' of https://github.com/idris-lang/Idris-dev into feature/deppairparsing
commitd77753dda1477ec1b00c3ec697ed929b7c146bcb authorAhmad Salim Al-Sibahi <asal@itu.dk> dateWed 30 Dec 2015, 19:18 (11 years ago) parente10d854504f706
253 files changed+5304−11868
.travis.yml+99−29 CHANGELOG+33−5 CONTRIBUTING.md+1−1 CONTRIBUTORS+2 INSTALL.md+99 Makefile+4−1 README.md+8−42 docs/conf.py+2−2 docs/effects/depeff.rst+2−2 docs/effects/hangman.rst+8−9 docs/effects/impleff.rst+1−1 docs/effects/simpleeff.rst+23−22 docs/faq/faq.rst+53 docs/index.rst+5−108 docs/reference/compilation.rst+21−2 docs/reference/elaborator-reflection.rst+47−11 docs/reference/repl.rst+2−1 docs/reference/syntax-guide.rst+4−1 docs/reference/tactics.rst+2−2 docs/tutorial/interp.rst+9−6 docs/tutorial/introduction.rst+1−1 docs/tutorial/modules.rst+12−2 docs/tutorial/provisional.rst+12−12 docs/tutorial/syntax.rst+3−3 docs/tutorial/typesfuns.rst+29−17 idris.cabal+28−3 iif/adder.iif−30 iif/big.iif−7 iif/ctest.c−106 iif/lazy.iif−21 iif/testmap.iif−30 iif/testvm.iif−32 libs/base/Control/Catchable.idr+4−4 libs/base/Control/IOExcept.idr+10−19 libs/base/Data/Complex.idr+8−8 libs/base/Data/HVect.idr+9−9 libs/base/Data/List/Quantifiers.idr+75 libs/base/Data/String.idr+110 libs/base/Data/Vect.idr+5−5 libs/base/Data/Vect/Quantifiers.idr+1 libs/base/Language/Reflection/Utils.idr+21−21 libs/base/System.idr+1−1 libs/base/base.ipkg+2−1 libs/contrib/Control/Algebra/NumericInstances.idr+7−7 libs/contrib/Network/Socket.idr−4 libs/effects/Effect/Default.idr+1−1 libs/effects/Effect/Exception.idr+2−1 libs/effects/Effect/File.idr+76−31 libs/effects/Effect/Logging/Category.idr−3 libs/effects/Effect/Perf.idr+230 libs/effects/Effect/Random.idr+7−7 libs/effects/Effects.idr+31−19 libs/effects/effects.ipkg+1 libs/oldeffects/Effect/Default.idr+1−1 libs/prelude/Builtins.idr+17−2 libs/prelude/Decidable/Equality.idr+1−1 libs/prelude/IO.idr+17−8 libs/prelude/Language/Reflection.idr+99−64 libs/prelude/Language/Reflection/Elab.idr+204−157 libs/prelude/Prelude.idr+10 libs/prelude/Prelude/Classes.idr+6−6 libs/prelude/Prelude/Either.idr+7−3 libs/prelude/Prelude/File.idr+114−49 libs/prelude/Prelude/Functor.idr+10−8 libs/prelude/Prelude/Interactive.idr+43−16 libs/prelude/Prelude/List.idr+7−3 libs/prelude/Prelude/Maybe.idr+8−5 libs/prelude/Prelude/Monad.idr+1−1 libs/prelude/Prelude/Nat.idr+13−10 libs/prelude/Prelude/Show.idr+5 libs/prelude/Prelude/Stream.idr+4−1 libs/pruviloj/Pruviloj.idr+5 libs/pruviloj/Pruviloj/Core.idr+135−11 libs/pruviloj/Pruviloj/Derive/DecEq.idr+196 libs/pruviloj/Pruviloj/Derive/Eliminators.idr+32−41 libs/pruviloj/Pruviloj/Disjoint.idr+85 libs/pruviloj/Pruviloj/Induction.idr+8−13 libs/pruviloj/Pruviloj/Injective.idr+122 libs/pruviloj/Pruviloj/Internals.idr+15−19 libs/pruviloj/Pruviloj/Internals/TyConInfo.idr+11−11 libs/pruviloj/Pruviloj/Renamers.idr+5−2 libs/pruviloj/pruviloj.ipkg+3 main/Main.hs+6 rts/Makefile+4−3 rts/idris_gmp.c+106 rts/idris_gmp.h+5 rts/idris_heap.c+12−12 rts/idris_heap.h+2−2 rts/idris_main.c+1 rts/idris_net.c+21−24 rts/idris_rts.c+16 rts/idris_rts.h+8 rts/idris_stdfgn.c+36−6 rts/idris_stdfgn.h+2 rts/windows/idris_net.c+6−7 rts/windows/idris_stdfgn.c−82 src/IRTS/CodegenC.hs+8−3 src/IRTS/CodegenJavaScript.hs+1−2 src/IRTS/Compiler.hs+20−20 src/IRTS/Exports.hs+8−11 src/IRTS/JavaScript/AST.hs+4−1 src/Idris/AbsSyntax.hs+85−19 src/Idris/AbsSyntaxTree.hs+90−43 src/Idris/CaseSplit.hs+83−60 src/Idris/Chaser.hs+81−38 src/Idris/CmdOptions.hs+43−13 src/Idris/Completion.hs+2−8 src/Idris/Core/Binary.hs+27−22 src/Idris/Core/Constraints.hs+5−7 src/Idris/Core/DeepSeq.hs+9−6 src/Idris/Core/Elaborate.hs+58−9 src/Idris/Core/Evaluate.hs+10−1 src/Idris/Core/Execute.hs+11 src/Idris/Core/ProofState.hs+20−2 src/Idris/Core/TT.hs+52−25 src/Idris/Core/Typecheck.hs−3 src/Idris/Core/Unify.hs+1−1 src/Idris/Core/WHNF.hs+8−8 src/Idris/Coverage.hs+26−76 src/Idris/DSL.hs+7−4 src/Idris/DataOpts.hs−1 src/Idris/DeepSeq.hs+12−5 src/Idris/Delaborate.hs+20−6 src/Idris/Directives.hs+4−1 src/Idris/Elab/Class.hs+11−13 src/Idris/Elab/Clause.hs+153−156 src/Idris/Elab/Data.hs+30−20 src/Idris/Elab/Instance.hs+15−16 src/Idris/Elab/Provider.hs+3−3 src/Idris/Elab/Record.hs+36−37 src/Idris/Elab/Term.hs+293−203 src/Idris/Elab/Transform.hs+8−9 src/Idris/Elab/Type.hs+23−25 src/Idris/Elab/Utils.hs+32−19 src/Idris/Elab/Value.hs+5−4 src/Idris/ElabDecls.hs+14−14 src/Idris/Erasure.hs+15−18 src/Idris/IBC.hs+33−24 src/Idris/Interactive.hs+34−17 src/Idris/ParseExpr.hs+3−3 src/Idris/Parser.hs+44−24 src/Idris/ProofSearch.hs+16−9 src/Idris/REPL.hs+65−42 src/Idris/REPLParser.hs+60−24 src/Idris/Reflection.hs+80−56 src/Pkg/PParser.hs+49−3 src/Pkg/Package.hs+3−6 src/Util/System.hs+17−10 stack.yaml+9−2 test/Makefile+4−1 test/basic002/test006.idr+9−9 test/basic006/expected+4−1 test/basic009/expected+4−1 test/basic010/Main.idr+13−13 test/basic010/expected+1−1 test/basic016/CycleA.idr+4 test/basic016/CycleB.idr+5 test/basic016/CycleC.idr+4 test/basic016/expected+1 test/basic016/run+3 test/docs003/expected+4−3 test/dsl001/test001.idr+10−10 test/dsl002/Resimp.idr+15−15 test/dsl002/test014.idr+7−6 test/effects003/foo−9236 test/effects003/hangman.idr+1−1 test/error003/expected+4−1 test/error004/expected+8−2 test/error005/expected+20−5 test/error006/WithPatsNoWith.idr+6 test/error006/expected+2 test/error006/run+3 test/ffi001/test022.idr+2−2 test/ffi004/test026.idr+2−1 test/interactive001/expected+6 test/interactive001/input+2 test/interactive001/test032.idr+9 test/interactive010/expected+22 test/interactive010/input+10 test/interactive010/run+2 test/interactive011/expected+3 test/interactive011/input+2 test/interactive011/interactive011.idr+11 test/interactive011/run+3 test/interactive012/expected+33 test/interactive012/input+9 test/interactive012/interactive012.idr+26 test/interactive012/run+3 test/io001/test004.idr+6−6 test/meta001/Finite.idr+13−13 test/meta002/AgdaStyleReflection.idr+247 test/meta002/Deriving.idr+33 test/meta002/Tacs.idr+12−4 test/meta002/expected+9−2 test/meta002/run+4−1 test/meta004/expected+3 test/meta004/meta004.idr+48 test/meta004/run+3 test/pkg001/expected−1 test/pkg001/test.ipkg+1−1 test/pkg002/Main.idr+4 test/pkg002/expected test/pkg002/run+5 test/pkg002/test.ipkg+8 test/pkg003/Main.idr+4 test/pkg003/expected test/pkg003/run+6 test/pkg003/test.ipkg+7 test/pkg004/Main.idr+4 test/pkg004/expected+5 test/pkg004/run+6 test/pkg004/test.ipkg+9 test/proof002/expected+3−1 test/proof003/Parity.idr+6−6 test/proof003/test015.idr+12−12 test/proof005/DefaultArgSubstitutionSuccess.idr+4−4 test/proof006/DefaultArgSubstitutionSyntax.idr+4−4 test/proof007/expected+3−1 test/proofsearch002/Process.idr+3−3 test/proofsearch002/proofsearch002.idr−3 test/pruviloj001/pruviloj001.idr+1−9 test/quasiquote001/expected+2−2 test/quasiquote003/expected+4−1 test/quasiquote004/expected+3−1 test/quasiquote006/expected+9−3 test/reg001/reg001.idr+31 test/reg006/expected+1−1 test/reg007/expected+4−1 test/reg023/expected+4−1 test/reg035/reg035a.lidr+5−5 test/reg041/expected+1−1 test/reg041/ott.idr+24−24 test/reg044/expected+4−1 test/reg046/reg046.idr+7−7 test/reg047/reg047.idr+2−2 test/reg047/reg047a.idr+3−3 test/reg049/expected+4−1 test/reg067/expected+1 test/reg067/reg067.idr+23 test/reg067/run+5 test/runtest.pl+60−6 test/syntax001/expected+8−2 test/totality002/test017.idr+6−6 test/totality004/totality004.idr+7−7 test/totality004/totality004a.idr+7−7 test/totality008/expected+1−1 test/totality008/totality008.idr+4−4 test/totality009/expected+8−8 test/tutorial002/tutorial002.idr+15−15 test/tutorial006/expected+8−3 test/tutorial006/run+1 test/tutorial006/tutorial006b.idr+6−6 test/tutorial006/tutorial006c.idr+20
.travis.yml+99−29
@@ -1,23 +1,95 @@
1−language: haskell
2−ghc:
3− # Idris won't build on 7.4 and earlier due to dependency
4− # problems. 7.10 isn't yet supported on Travis.
5− - 7.6
6− - 7.8
1+sudo: false
2+
3+language: c
4+
5+addons:
6+ apt:
7+ sources:
8+ - hvr-ghc
9+ packages:
10+ - ghc-7.6.3
11+ - ghc-7.8.4
12+ - ghc-7.10.2
13+ - cabal-install-1.20
14+ - cabal-install-1.22
15+ # test dependencies
16+ - expect
17+ - cppcheck
18+ - hscolour
19+
20+matrix:
21+ include:
22+ - env: CABALVER="1.20" GHCVER="7.6.3" TESTS="test_c"
23+ # separate caches for different compiler versions
24+ # until https://github.com/travis-ci/travis-ci/issues/4393 is resolved
25+ compiler: ": #GHC 7.6.3"
26+ - env: CABALVER="1.20" GHCVER="7.8.4" TESTS="lib_doc doc"
27+ compiler: ": #GHC 7.8.4"
28+ - env: CABALVER="1.20" GHCVER="7.8.4" TESTS="test_js"
29+ compiler: ": #GHC 7.8.4"
30+ - env: CABALVER="1.20" GHCVER="7.8.4" TESTS="test_c"
31+ compiler: ": #GHC 7.8.4"
32+ - env: CABALVER="1.22" GHCVER="7.10.2" TESTS="lib_doc doc"
33+ compiler: ": #GHC 7.10.2"
34+ - env: CABALVER="1.22" GHCVER="7.10.2" TESTS="test_js"
35+ compiler: ": #GHC 7.10.2"
36+ - env: CABALVER="1.22" GHCVER="7.10.2" TESTS="test_c"
37+ compiler: ": #GHC 7.10.2"
38+
39+cache:
40+ directories:
41+ - $HOME/.cabsnap
42+ - $HOME/.cabal/packages
43+
44+before_cache:
45+ - rm -fv $HOME/.cabal/packages/hackage.haskell.org/build-reports.log
46+ - rm -fv $HOME/.cabal/packages/hackage.haskell.org/00-index.tar
747
848before_install:
9− - sudo apt-get update -qq
10− - sudo apt-get install -qq libghc-unordered-containers-dev libghc-mtl-dev libghc-network-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
11− # trifecta dependencies
12− - sudo apt-get install -qq libghc-blaze-builder-dev libghc-blaze-html-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
13− # Haddock dependencies
14− - sudo apt-get install hscolour
15− # test dependency
16− - sudo apt-get install -qq expect
17− - sudo apt-get install -qq cppcheck
49+ - unset CC
50+ - export PATH=/opt/ghc/$GHCVER/bin:/opt/cabal/$CABALVER/bin:$HOME/.cabal/bin:$PATH
51+ - env
52+
1853install:
19− - cabal install -f FFI --enable-tests --dependencies-only --max-backjumps=-1
20− - ghc-pkg list
54+ - cabal --version
55+ - echo "$(ghc --version) [$(ghc --print-project-git-commit-id 2> /dev/null || echo '?')]"
56+ - if [ -f $HOME/.cabal/packages/hackage.haskell.org/00-index.tar.gz ];
57+ then
58+ zcat $HOME/.cabal/packages/hackage.haskell.org/00-index.tar.gz >
59+ $HOME/.cabal/packages/hackage.haskell.org/00-index.tar;
60+ fi
61+ - travis_retry cabal update -v
62+ # Run build with 2 parallel jobs
63+ # The container environment reports 16 cores,
64+ # causing cabal's default configuration (jobs: $ncpus)
65+ # to run into the GHC #9221 bug which can result in longer build-times.
66+ - sed -i -r 's/(^jobs:).*/\1 2/' $HOME/.cabal/config
67+ - cabal install -f FFI --only-dependencies --enable-tests --dry -v > installplan.txt
68+ - sed -i -e '1,/^Resolving /d' installplan.txt; cat installplan.txt
69+
70+ # check whether current requested install-plan matches cached package-db snapshot
71+ - if diff -u installplan.txt $HOME/.cabsnap/installplan.txt;
72+ then
73+ echo "cabal build-cache HIT";
74+ rm -rfv .ghc;
75+ cp -a $HOME/.cabsnap/ghc $HOME/.ghc;
76+ cp -a $HOME/.cabsnap/lib $HOME/.cabsnap/share $HOME/.cabsnap/bin $HOME/.cabal/;
77+ else
78+ echo "cabal build-cache MISS";
79+ rm -rf $HOME/.cabsnap;
80+ mkdir -p $HOME/.ghc $HOME/.cabal/lib $HOME/.cabal/share $HOME/.cabal/bin;
81+ cabal install -f FFI --only-dependencies --enable-tests;
82+ fi
83+
84+ # snapshot package-db on cache miss
85+ - if [ ! -d $HOME/.cabsnap ];
86+ then
87+ echo "snapshotting package-db to build-cache";
88+ mkdir $HOME/.cabsnap;
89+ cp -a $HOME/.ghc $HOME/.cabsnap/ghc;
90+ cp -a $HOME/.cabal/lib $HOME/.cabal/share $HOME/.cabal/bin installplan.txt $HOME/.cabsnap/;
91+ fi
92+
2193before_script:
2294 - cabal sdist
2395 - cd ..
@@ -25,15 +97,13 @@ before_script:
2597 - cd idris*
2698script:
2799 - cabal configure -f FFI -f CI
28− - if [[ "$TESTS" != "doc" ]]; then cabal build; fi
29− - if [[ "$TESTS" != "doc" ]]; then cabal copy; fi
30− - if [[ "$TESTS" != "doc" ]]; then cabal register; fi
31− - if [[ "$TESTS" == "test_c" ]]; then cppcheck -j 2 --error-exitcode=1 ./rts/idris_bitstring.c ./rts/idris_bitstring.h ./rts/idris_gc.h ./rts/idris_gc.c ./rts/idris_gmp.h ./rts/idris_gmp.c ./rts/idris_heap.h ./rts/idris_heap.c ./rts/idris_main.c ./rts/idris_net.h ./rts/idris_net.c ./rts/idris_opts.h ./rts/idris_opts.c ./rts/idris_rts.h ./rts/idris_rts.c ./rts/idris_stats.h ./rts/idris_stats.c ./rts/idris_stdfgn.h ./rts/idris_stdfgn.c ./rts/libtest.c ; fi
32− - if [[ "$TESTS" == "test_llvm" ]]; then git clone --depth 1 https://github.com/idris-hackers/idris-llvm.git ; cd idris-llvm ; cabal install ; cd .. ; fi
33− - make -j2 $TESTS
34−env:
35− - TESTS="doc"
36− - TESTS="lib_doc"
37− - TESTS="test_c"
38− #- TESTS="test_llvm"
39− - TESTS="test_js"
100+ - cabal build
101+ - cabal copy
102+ - cabal register
103+ - if [[ "$TESTS" == "test_c" ]]; then
104+ cppcheck -i 'mini-gmp.c' rts;
105+ fi
106+ - for test in $TESTS; do
107+ echo "make -j2 $test";
108+ make -j2 $test;
109+ done
CHANGELOG+33−5
@@ -1,3 +1,17 @@
1+New in 0.9.21:
2+==============
3+
4+* Idris' logging infrastructure has been categorised. Command line and repl
5+ are available. For command line the option `--logging-categories CATS`
6+ is used to pass in the categories. Here `CATS` is a colon separated quoted
7+ string containing the categories to log. The REPL command is `logcats CATS`.
8+ Where `CATS` is a whitespace separated list of categoriese. Default is for
9+ all categories to be logged.
10+* New flag `--listlogcats` to list logging categories.`
11+* Dependent pairs now can be specified using a telescope-style syntax, without
12+ requirement of nesting, e.g. it is possible to now write the following:
13+ (a : Type ** n : Nat ** Vect n a)
14+
115New in 0.9.20:
216==============
317
@@ -16,10 +30,11 @@ Language updates
1630 valid unbound implicit is now *always* an unbound implicit. This is much
1731 more resilient to changes in inputs, but does require that function names
1832 be explicitly qualified when in argument position.
19−* Dependent pairs now can be specified using a telescope-style syntax, without
20− requirement of nesting, e.g. it is possible to now write the following:
21− (a : Type ** n : Nat ** Vect n a)
22−
33+* Name binding in patterns follows the same rule as name binding for implicits
34+ in types: names which begin with lower case letters, not applied to any
35+ arguments, are treated as bound pattern variables.
36+* Added %deprecate directive, which gives a warning and a message when a
37+ deprecated name is referenced.
2338
2439Library updates
2540---------------
@@ -34,6 +49,13 @@ Library updates
3449 programmes.
3550* Elaborator reflection is now a part of the prelude. It is no longer
3651 necessary to import Language.Reflection.Elab.
52+* The `PERF` effect allows for simple performance metrics to be collected
53+ from Effectful programs.
54+* Some constructors that never actually occurred have been removed from
55+ the TT and Raw reflection datatypes in Language.Reflection.
56+* File IO operations (for example openFile/fread/fwrite) now return
57+ 'Either FileError ty' where the return type was previously 'ty' to indicate
58+ that they may fail.
3759
3860Tool updates
3961------------
@@ -41,7 +63,13 @@ Tool updates
4163 datatype
4264* iPKG files have a new option `pkgs` which takes a comma-separated list
4365 of package names that the idris project depends on. This reduces bloat
44− in the `opts` option with mutliple package declarations.
66+ in the `opts` option with multiple package declarations.
67+* iPKG files now allow `executable = "your filename here"` in addition to
68+ the existing `executable = yourFilenameHere` style. While the unquoted
69+ version is limited to filenames that look like namespaced Idris identifiers
70+ (`your.filename.here`), the quoted version accepts any valid filename.
71+* Add definition command (\d in Vim, Ctrl-Alt-A in Atom, C-c C-s in Emacs) now
72+ adds missing clauses if there is already a definition.
4573
4674Miscellaneous updates
4775---------------------
CONTRIBUTING.md+1−1
@@ -166,4 +166,4 @@ To help increase the chance of your pull request being accepted:
166166* [General GitHub Documentation](https://help.github.com/).
167167
168168
169−Adapted from the most excellent contributing files from the [Puppet project](https://github.com/puppetlabs/puppet) and [Factroy Girl Rails](https://github.com/thoughtbot/factory_girl_rails/blob/master/CONTRIBUTING.md)
169+Adapted from the most excellent contributing files from the [Puppet project](https://github.com/puppetlabs/puppet) and [Factory Girl Rails](https://github.com/thoughtbot/factory_girl_rails/blob/master/CONTRIBUTING.md)
CONTRIBUTORS+2
@@ -15,6 +15,7 @@ Jason Dagit
1515Guglielmo Fachini
1616Simon Fowler
1717Google
18+Zack Grannan
1819Cezar Ionescu
1920Heath Johns
2021Irene Knapp
@@ -35,6 +36,7 @@ Adam Sandberg Eriksson
3536Seo Sanghyeon
3637Benjamin Saunders
3738Alexander Shabalin
39+Jeremy W. Sherman
3840Timo Petteri Sinnemäki
3941JP Smith
4042startling
INSTALL.mdnew file+99
@@ -0,0 +1,99 @@
1+# Idris Installation Guide
2+
3+Copyright (C) 2015, The Idris Community
4+
5+## Installing Idris from Hackage
6+
7+This repository represents the latest development version of the
8+language, and may contain bugs that are being actively worked on. For
9+those who wish to use a more stable version of Idris please consider
10+installing the latest version that has been released on Hackage.
11+Installation instructions for various platforms can be
12+[found on the Idris Wiki](https://github.com/idris-lang/Idris-dev/wiki/Installation-Instructions).
13+
14+## Installing Development Versions
15+
16+If you like to work against the latest development version, please
17+consider using Cabal Sandboxes to minimise disruption to your local
18+Haskell setup. Instructions for installing Idris HEAD within a cabal
19+sandbox are
20+[available on the Idris Wiki](https://github.com/idris-lang/Idris-dev/wiki/Installing-an-Idris-Development-version-in-a-sandbox).
21+
22+To configure, edit config.mk. The default values should work for most
23+people.
24+
25+Idris is built using a Makefile common targets include:
26+
27+* `make` This will install everything using cabal and typecheck the
28+ libraries.
29+* `make test` This target execute the test suite.
30+* `make relib` This target will typecheck and recompile the standard
31+ library.
32+
33+Idris has an optional dependency on the `C` library `libffi`. If you
34+would like to use the features that it enables, make sure that it is
35+compiled for the same architecture as your Haskell compiler (e.g. 64
36+bit libraries for 64 bit ghc). By default, Idris builds without it. To
37+build with it, pass the flag `-f FFI`.
38+
39+A secondary optional dependency is on `libGMP`, this allows better
40+support for numeric operations. As with `libFFI` Idris builds with out
41+it, to enable `GMP` support use the flag `-f GMP`
42+
43+To build with `libffi` and `libGMP` by default, create a `custom.mk`
44+file and add the following line to it:
45+
46+`CABALFLAGS += -f FFI -f GMP`
47+
48+The file `custom.mk-alldeps` is a suitable example.
49+
50+The continuous integration builds on travis-ci.org are built using the
51+ghc-flag -Werror. To enable this behaviour locally also, please
52+compile using `make CI=true` or adding the following line into
53+`custom.mk`:
54+
55+`CI = true`
56+
57+If you are only compiling for installing the most current version, you
58+can omit the CI flag, but please make sure you use it if you want to
59+contribute.
60+
61+## Experimental Support for Building with Stack
62+
63+[Stack](https://github.com/commercialhaskell/stack) is a new
64+cross-platform program for developing Haskell projects, that enhances
65+the functionality provided by Cabal. There is experimental support for
66+building Idris from source using with stack, that uses the LTS 3.16
67+resolver. This installation has been tested on Ubuntu 14.04.2 LTS,
68+only.
69+
70+To build Idris with stack the following commands are recommended:
71+
72+* `stack build`
73+
74+This will install Idris (and related executables) into `./local/bin/`
75+on Unix based systems and an appropriate place on Windows. If you
76+haven't used stack before this will also setup the related
77+infrastructure. For more information about Stack please visit the
78+[Stack website](https://github.com/commercialhaskell/stack).
79+
80+### System GHC
81+
82+The flag `--system-ghc` can be added to enforce use of your system's
83+version of GHC.
84+
85+### `libGMP` and `libFFI`
86+
87+By default the stack configuration in `stack.yaml` will build with
88+support for `libGMP` and `libFFI`. To turn this support off, the
89+option flags needs to be fully commented out.
90+
91+There have been reports in the past over building Idris on Mac OS X,
92+using stack, and linking to a HomeBrew installation of `libFFI`. The
93+build has failed to find the correct `libFFI` installation. If you
94+encounter this then the fix is to augment the `PKG_CONFIG_PATH` when
95+running the stack build:
96+
97+```
98+PKG_CONFIG_PATH=/usr/local/Cellar/libffi/3.0.13/lib/pkgconfig stack build
99+```
Makefile+4−1
@@ -36,6 +36,9 @@ test_all:
3636 $(MAKE) test_llvm
3737 $(MAKE) test_java
3838
39+test_timed:
40+ $(MAKE) -C test IDRIS=../dist/build/idris time
41+
3942lib_clean:
4043 $(MAKE) -C libs IDRIS=../../dist/build/idris/idris RTS=../../dist/build/rts/libidris_rts clean
4144
@@ -43,7 +46,7 @@ relib: lib_clean
4346 $(CABAL) install $(CABALFLAGS)
4447
4548linecount:
46− wc -l src/Idris/*.hs src/Idris/Core/*.hs src/IRTS/*.hs src/Pkg/*.hs
49+ wc -l src/Idris/*.hs src/Idris/Elab/*.hs src/Idris/Core/*.hs src/IRTS/*.hs src/Pkg/*.hs src/Util/*.hs
4750
4851#Note: this doesn't yet link to Hackage properly
4952doc: dist/setup-config
README.md+8−42
@@ -7,50 +7,16 @@
77Idris (http://idris-lang.org/) is a general-purpose functional programming
88language with dependent types.
99
10−## Standard Installation Instructions
11−This repository represents the latest development version of the language,
12−and may contain bugs that are being actively worked on.
13−For those who wish to use a more stable version of Idris please consider
14−installing the latest version that has been released on Hackage.
15−Installation instructions for various platforms can be [found on the Idris Wiki](https://github.com/idris-lang/Idris-dev/wiki/Installation-Instructions).
16−
17−## Installing Development Versions
18−
19−If you like to work against the latest development version, please consider
20−using Cabal Sandboxes to minimise disruption to your local Haskell setup.
21−Instructions for installing Idris HEAD within a cabal sandbox are
22−[available on the Idris Wiki](https://github.com/idris-lang/Idris-dev/wiki/Installing-an-Idris-Development-version-in-a-sandbox).
23−
24−To configure, edit config.mk. The default values should work for most people.
25−
26−Idris is built using a Makefile common targets include:
27−
28−* `make` This will install everything using cabal and
29−typecheck the libraries.
30−* `make test` This target execute the test suite.
31−* `make relib` This target will typecheck and recompile the standard library.
10+## Installation Guides.
3211
33−Idris has an optional buildtime dependency on the C library `libffi`. If you
34−would like to use the features that it enables, make sure that it is compiled
35−for the same architecture as your Haskell compiler (e.g. 64 bit libraries
36−for 64 bit ghc). By default, Idris builds without it. To build with it, pass
37−the flag `-f FFI`.
38−
39−To build with `libffi` by default, create a `custom.mk` file and add the
40−following line to it:
41−
42−`CABALFLAGS += -f FFI`
43−
44−The file custom.mk-alldeps is a suitable example.
45−
46−The continuous integration builds on travis-ci.org are built using the
47−ghc-flag -Werror. To enable this behaviour locally also, please compile
48−using `make CI=true` or adding the following line into `custom.mk`:
49−
50−`CI = true`
12+This repository represents the latest development version of the
13+language, and may contain bugs that are being actively worked on. For
14+those who wish to use a more stable version of Idris please consider
15+installing the latest version that has been released on Hackage.
16+Installation instructions for various platforms can be
17+[found on the Idris Wiki](https://github.com/idris-lang/Idris-dev/wiki/Installation-Instructions).
5118
52−If you are only compiling for installing the most current version, you can
53−omit the CI flag, but please make sure you use it if you want to contribute.
19+More information about building Idris from source has been detailed in the [Installation Guide](INSTALL.md)
5420
5521## Code Generation
5622
docs/conf.py+2−2
@@ -59,9 +59,9 @@ author = u'The Idris Community'
5959# built documents.
6060#
6161# The short X.Y version.
62−version = '0.9.18'
62+version = '0.9.19'
6363# The full version, including alpha/beta/rc tags.
64−release = '0.9.18'
64+release = '0.9.19.1'
6565
6666# The language for content autogenerated by Sphinx. Refer to documentation
6767# for a list of supported languages.
docs/effects/depeff.rst+2−2
@@ -48,7 +48,7 @@ express this as follows:
4848 readInt = do let x = trim !getStr
4949 putM (cast x :: !get)
5050
51−The notation ``{ xs ==> xs’ } Eff a`` in a type means that the operation
51+The type ``Eff a xs xs'`` means that the operation
5252begins with effects ``xs`` available, and ends with effects ``xs’``
5353available. We have used ``putM`` to update the state, where the ``M``
5454suffix indicates that the *type* is being updated as well as the value.
@@ -96,7 +96,7 @@ value read from the user was valid. We can express this in the type:
9696 else [STATE (Vect n Int), STDIO])
9797 readInt = do let x = trim !getStr
9898 case all isDigit (unpack x) of
99− False => pure False
99+ False => pureM False
100100 True => do putM (cast x :: !get)
101101 pureM True
102102
docs/effects/hangman.rst+8−9
@@ -108,16 +108,15 @@ effect signature:
108108 Guess : (x : Char) ->
109109 sig MysteryRules Bool
110110 (Mystery (Running (S g) (S w)))
111− (\inword =>
112− Mystery (case inword of
113− True => (Running (S g) w)
114− False => (Running g (S w))))
111+ (\inword => if inword
112+ then Mystery (Running (S g) w)
113+ else Mystery (Running g (S w)))
115114 Won : sig MysteryRules () (Mystery (Running g 0))
116115 (Mystery NotRunning)
117116 Lost : sig MysteryRules () (Mystery (Running 0 g))
118117 (Mystery NotRunning)
119118 NewWord : (w : String) ->
120− sig MysteryRules () h (Mystery (Running 6 (length (letters w))))
119+ sig MysteryRules () (Mystery NotRunning) (Mystery (Running 6 (length (letters w))))
121120 Get : sig MysteryRules String (Mystery h)
122121
123122This description says nothing about how the rules are implemented. In
@@ -243,11 +242,11 @@ running ``game``:
243242.. code-block:: idris
244243
245244 runGame : Eff () [MYSTERY NotRunning, RND, SYSTEM, STDIO]
246− runGame = do srand (cast !time)
247− let w = index !(rndFin WEWEWE) words
248− NewWord w
245+ runGame = do srand !time
246+ let w = index !(rndFin _) words
247+ call $ NewWord w
249248 game
250− putStrLn !Get
249+ putStrLn !(call Get)
251250
252251We use the system time (``time`` from the ``SYSTEM`` effect; see
253252Appendix :ref:`sect-appendix`) to initialise the random number
docs/effects/impleff.rst+1−1
@@ -282,7 +282,7 @@ value.
282282Here, the continuation is called multiple times in each handler, for
283283each value in the list of possible values. In the ``List`` handler, we
284284accumulate all successful results, and in the ``Maybe`` handler we try
285−the first value in the last, and try later values only if that fails.
285+the first value in the list, and try later values only if that fails.
286286
287287File Management
288288===============
docs/effects/simpleeff.rst+23−22
@@ -382,7 +382,7 @@ definition:
382382
383383 vadd : Vect n Int -> Vect n Int -> Vect n Int
384384 vadd [] [] = []
385− vadd (x :: idris xs) (y :: ys) = x + y :: vadd xs ys
385+ vadd (x :: xs) (y :: ys) = x + y :: vadd xs ys
386386
387387Using , we can set up a program so that it reads input from a user,
388388checks that the input is valid (i.e both vectors contain integers, and
@@ -410,10 +410,28 @@ following type:
410410
411411This returns a dependent pair of a length, and a vector of that
412412length, because we cannot know in advance how many integers the user
413−is going to input. One way to implement this function, using ``-1`` to
414−indicate the end of input, is shown in Listing [readvec]. This uses a
415−variation on ``parseNumber`` which does not require a number to be
416−within range.
413+is going to input. We can use ``-1`` to indicate the end of input:
414+
415+.. code-block:: idris
416+
417+ read_vec : Eff (p ** Vect p Int) [STDIO]
418+ read_vec = do putStr "Number (-1 when done): "
419+ case run (parseNumber (trim !getStr)) of
420+ Nothing => do putStrLn "Input error"
421+ read_vec
422+ Just v => if (v /= -1)
423+ then do (_ ** xs) <- read_vec
424+ pure (_ ** v :: xs)
425+ else pure (_ ** [])
426+ where
427+ parseNumber : String -> Eff Int [EXCEPTION String]
428+ parseNumber str
429+ = if all (\x => isDigit x || x == '-') (unpack str)
430+ then pure (cast str)
431+ else raise "Not a number"
432+
433+This uses a variation on ``parseNumber`` which does not require a
434+number to be within range.
417435
418436Finally, we write a program which reads two vectors and prints the
419437result of pairwise addition of them, throwing an exception if the
@@ -434,23 +452,6 @@ equal. This does not stop us reading vectors from user input, but it
434452does require that the lengths are checked and any discrepancy is dealt
435453with gracefully.
436454
437−.. code-block:: idris
438−
439− read_vec : Eff (p ** Vect p Int) [STDIO]
440− read_vec = do putStr "Number (-1 when done): "
441− case run (parseNumber (trim !getStr)) of
442− Nothing => do putStrLn "Input error"
443− read_vec
444− Just v => if (v /= -1)
445− then do (_ ** xs) <- read_vec
446− pure (_ ** v :: xs)
447− else pure (_ ** [])
448− where
449− parseNumber : String -> Eff Int [EXCEPTION String]
450− parseNumber str
451− = if all (\x => isDigit x || x == '-') (unpack str)
452− then pure (cast str)
453− else raise "Not a number"
454455
455456Example: An Expression Calculator
456457=================================
docs/faq/faq.rst+53
@@ -103,6 +103,59 @@ the difference between:
103103 Idris> \n, m => n + (S m)
104104 \n => \m => plus n (S m) : Nat -> Nat -> Nat
105105
106+
107+Why can't I use a function with no arguments in a type?
108+=======================================================
109+
110+If you use a name in a type which begins with a lower case letter, and which is
111+not applied to any arguments, then Idris will treat it as an implicitly
112+bound argument. For example:
113+
114+.. code-block:: idris
115+
116+ append : Vect n ty -> Vect m ty -> Vect (n + m) ty
117+
118+Here, ``n``, ``m``, and ``ty`` are implicitly bound. This rule applies even
119+if there are functions defined elsewhere with any of these names. For example,
120+you may also have:
121+
122+.. code-block:: idris
123+
124+ ty : Type
125+ ty = String
126+
127+Even in this case, ``ty`` is still considered implicitly bound in the definition
128+of ``append``, rather than making the type of ``append`` equivalent to...
129+
130+.. code-block:: idris
131+
132+ append : Vect n String -> Vect m String -> Vect (n + m) String
133+
134+...which is probably not what was intended! The reason for this rule is so
135+that it is clear just from looking at the type of ``append``, and no other
136+context, what the implicitly bound names are.
137+
138+If you want to use an unapplied name in a type, you have two options. You
139+can either explicitly qualify it, for example, if ``ty`` is defined in the
140+namespace ``Main`` you can do the following:
141+
142+.. code-block:: idris
143+
144+ append : Vect n Main.ty -> Vect m Main.ty -> Vect (n + m) Main.ty
145+
146+Alternatively, you can use a name which does not begin with a lower case
147+letter, which will never be implicitly bound:
148+
149+.. code-block:: idris
150+
151+ Ty : Type
152+ Ty = String
153+
154+ append : Vect n Ty -> Vect m Ty -> Vect (n + m) Ty
155+
156+As a convention, if a name is intended to be used as a type synonym, it is
157+best for it to begin with a capital letter to avoid this restriction.
158+
106159I have an obviously terminating program, but Idris says it possibly isn't total. Why is that?
107160=============================================================================================
108161
docs/index.rst+5−108
@@ -16,115 +16,12 @@ Documentation for the Idris Language
1616 More information concerning the CC0 can be found online at: http://creativecommons.org/publicdomain/zero/1.0/
1717
1818
19−* :ref:`tutorial-index`
20−* :ref:`eff-tutorial-index`
21−* :ref:`faq-index`
22−* :ref:`proofs-index`
23−* :ref:`reference-index`
24−* :ref:`guides-index`
25−
26−
27−.. _tutorial:
28−
29−###################
30−The Idris Tutorial
31−###################
32−
33−.. toctree::
34− :maxdepth: 1
35−
36− tutorial/introduction
37− tutorial/starting
38− tutorial/typesfuns
39− tutorial/classes
40− tutorial/modules
41− tutorial/packages
42− tutorial/testing
43− tutorial/interp
44− tutorial/views
45− tutorial/theorems
46− tutorial/provisional
47− tutorial/interactive
48− tutorial/syntax
49− tutorial/miscellany
50− tutorial/conclusions
51−
52−.. _faq:
53−
54−##########################
55−Frequently Asked Questions
56−##########################
57−
5819.. toctree::
5920 :maxdepth: 1
6021
22+ tutorial/index
6123 faq/faq
62−
63−.. _effects:
64−
65−################
66−Learning Effects
67−################
68−
69−.. toctree::
70− :maxdepth: 1
71−
72− effects/introduction
73− effects/state
74− effects/simpleeff
75− effects/depeff
76− effects/impleff
77− effects/hangman
78− effects/conclusions
79− effects/summary
80−
81−.. _proofs:
82−
83−###############
84−Theorem Proving
85−###############
86−
87−.. toctree::
88− :maxdepth: 1
89−
90− proofs/pluscomm
91− proofs/inductive
92− proofs/patterns
93− proofs/interactive
94−
95−.. _reference:
96−
97−##################
98−Language Reference
99−##################
100−
101−.. toctree::
102− :maxdepth: 1
103−
104− reference/documenting
105− reference/packages
106− reference/uniqueness-types
107− reference/ffi
108− reference/syntax-guide
109− reference/erasure
110− reference/ide-protocol
111− reference/semantic-highlighting
112− reference/repl
113− reference/tactics
114− reference/compilation
115− reference/language-features
116− reference/language-extensions
117− reference/elaborator-reflection
118− reference/misc
119−
120−.. _guides:
121−
122−############
123−Short Guides
124−############
125−
126−.. toctree::
127− :maxdepth: 1
128−
129− guides/type-providers-ffi
130− guides/theorem-prover
24+ effects/index
25+ proofs/index
26+ reference/index
27+ guides/index
docs/reference/compilation.rst+21−2
@@ -45,8 +45,27 @@ Use of this option will still result in the generation of the Idris binary ``.ib
4545Logging Output
4646==============
4747
48−Logging of the Idris output can be used to diagnose problems with the compilation of your program.
49−Idris supports the logging at various different levels of verbosity: 1 to 10.
48+The internal operation of Idris is captured using a category based logger.
49+Currently, the logging infrastructure has support for the following categories:
50+
51++ Parser
52++ Elaborator
53++ Code generation
54++ Erasure
55++ Coverage Checking
56++ IBC generation
57+
58+
59+These categories are specified using the command-line option:
60+``--logging-categories CATS``, where ``CATS`` is a quoted colon
61+seperated string of the categories you want to see. By default if this
62+option is not specified all categories are allowed. Sub-categories
63+have yet to be defined but will be in the future, especially for the
64+elaborator.
65+
66+Further, the verbosity of logging can be controlled by specifying a
67+logging level between: 1 to 10 using the command-line option: ``--log
68+<level>``.
5069
5170+ Level 0: Show no logging output. Default level
5271+ Level 1: High level details of the compilation process.
docs/reference/elaborator-reflection.rst+47−11
@@ -74,17 +74,53 @@ We can generate identity functions at any concrete type using the same script:
7474Interactively Building Elab Scripts
7575===================================
7676
77−To build an ``Elab`` script interactively, use the ``:elab`` command at the REPL.
78−It takes the name of a hole as an argument.
79−To list all available holes, use the command ``:m``.
77+You can build an ``Elab`` script interactively at the REPL.
78+Use the command ``:metavars``, or ``:m`` for short, to list the available holes.
79+Then, issue the ``:elab <hole>`` command at the REPL
80+to enter the elaboration shell.
8081
81−In interactive elaboration shell, the following commands are available:
82−- ``:q`` - Quits the elaboration shell (gives up on proving current lemma).
83−- ``:abandon`` - Same as :q
84−- ``:state`` - Displays the current state of the term being constructed.
85−- ``:term`` - Displays the current proof term complete with its yet-to-be-filled holes.
86−- ``:undo`` - Undoes the last tactic.
87−- ``:qed`` - Once the elaboration shell tells you "No more goals," you get to type this in celebration! (Completes the construction and exits the shell)
82+At the shell, you can enter proof tactics to alter the proof state.
83+You can view the system-provided tactics prior to entering the shell
84+by issuing the REPL command ``:browse Language.Reflection.Elab.Tactics``.
85+When you have discharged all goals, you can complete the proof
86+using the ``:qed`` command and receive in return an elaboration script
87+that fills the hole.
88+
89+The interactive elaboration shell accepts a limited number of commands,
90+including a subset of the commands understood by the normal Idris REPL
91+as well as some elaboration-specific commands.
92+
93+General-purpose commands:
94+
95+- ``:eval <EXPR>``, or ``:e <EXPR>`` for short, evaluates the provided expression
96+ and prints the result.
97+
98+- ``:type <EXPR>``, or ``:t <EXPR>`` for short, prints the provided expression
99+ together with its type.
100+
101+- ``:search <TYPE>`` searches for definitions having the provided type.
102+
103+- ``:doc <NAME>`` searches for definitions with the provided name and prints their
104+ documentation.
105+
106+
107+Commands for viewing the proof state:
108+
109+- ``:state`` displays the current state of the term being constructed. It lists both
110+ other goals and the current goal.
111+
112+- ``:term`` displays the current proof term as well as its yet-to-be-filled holes.
113+
114+
115+Commands for manipulating the proof state:
116+
117+- ``:undo`` undoes the effects of the last tactic.
118+
119+- ``:abandon`` gives up on proving the current lemma and quits the elaboration shell.
120+
121+- ``:qed`` finishes the script and exits the elaboration shell. The shell will only accept
122+ this command once it reports, "No more goals." On exit, it will print out the finished
123+ elaboration script for you to copy into your program.
88124
89125
90126Failure
@@ -127,7 +163,7 @@ If the goal type turns out to have been the unit type, we fill using the unit co
127163Otherwise, we fail with an error message informing the user that the current goal is not trivial.
128164
129165Additionally, the elaboration state can be dumped into an error message with the ``debug`` tactic.
130−A variant, ``debugMessage``, allows arbitrary messages to be included with the state, allowing for a kind of "``printf`` debuggging" of elaboration scripts.
166+A variant, ``debugMessage``, allows arbitrary messages to be included with the state, allowing for a kind of "``printf`` debugging" of elaboration scripts.
131167The message format used by ``debugMessage`` is the same for errors produced by the error reflection mechanism, allowing the re-use of the Idris pretty-printer when rendering messages.
132168
133169Changing the Global Context
docs/reference/repl.rst+2−1
@@ -128,7 +128,8 @@ The current set of supported commands are:
128128+----------------+------------------------------+----------------------------------------------------------------------------------------------------------+
129129|:? :h :help | | Display this help text |
130130+----------------+------------------------------+----------------------------------------------------------------------------------------------------------+
131−|:set | <option> | Set an option (errorcontext, showimplicits) |
131+|:set | <option> | Set an option (errorcontext, showimplicits, originalerrors, autosolve, nobanner, warnreach, evaltypes, |
132+| | | desugarnats) |
132133+----------------+------------------------------+----------------------------------------------------------------------------------------------------------+
133134|:unset | <option> | Unset an option |
134135+----------------+------------------------------+----------------------------------------------------------------------------------------------------------+
docs/reference/syntax-guide.rst+4−1
@@ -112,7 +112,7 @@ Types
112112
113113In Idris, types are first class values. So a type declaration is the
114114same as just declaration of a variable whose type is ``Type``. In Idris,
115−variables that denote a type must begin with a capital letter. Example:
115+variables that denote a type need not be capitalised. Example:
116116
117117.. code:: idris
118118
@@ -126,6 +126,9 @@ a more interesting example:
126126 MyListType : Type
127127 MyListType = List Int
128128
129+While capitalising types is not required, the rules for generating implicit
130+arguments mean it is often a good idea.
131+
129132.. _syntax-data-types:
130133
131134Data types
docs/reference/tactics.rst+2−2
@@ -1,6 +1,6 @@
1−***************************
1+****************************************
22DEPRECATED: Tactics and Theorem Proving
3−***************************
3+****************************************
44
55.. warning::
66 The interactive theorem-proving interface documented here has been
docs/tutorial/interp.rst+9−6
@@ -32,11 +32,14 @@ calculated just like any other value:
3232 interpTy TyBool = Bool
3333 interpTy (TyFun A T) = interpTy A -> interpTy T
3434
35−We’re going to define a representation of our language in such a way
36−that only well-typed programs can be represented. We’ll index the
37−representations of expressions by their type and the types of local
38−variables (the context), which we’ll be using regularly as an implicit
39−argument, so we define everything in a ``using`` block:
35+We're going to define a representation of our language in such a way
36+that only well-typed programs can be represented. We'll index the
37+representations of expressions by their type, **and** the types of
38+local variables (the context). The context can be represented using
39+the ``Vect`` data type, and as it will be used regularly it will be
40+represented as an implicit argument. To do so we define everything in
41+a ``using`` block (keep in mind that everything after this point needs
42+to be indented so as to be inside the ``using`` block):
4043
4144.. code-block:: idris
4245
@@ -151,7 +154,7 @@ that only the branch which is taken need be evaluated:
151154Writing the Interpreter
152155=======================
153156
154−When we evaluate an ``Expr``, we’ll need to know the values in scope,
157+When we evaluate an ``Expr``, we'll need to know the values in scope,
155158as well as their types. ``Env`` is an environment, indexed over the
156159types in scope. Since an environment is just another form of list,
157160albeit with a strongly specified connection to the vector of local
docs/tutorial/introduction.rst+1−1
@@ -15,7 +15,7 @@ respectively:
1515Correspondingly, the following values are examples of inhabitants of
1616those types:
1717
18−- ``42``, ``’a’``, ``Hello world!``, ``[2,3,4,5,6]``
18+- ``42``, ``’a’``, ``"Hello world!"``, ``[2,3,4,5,6]``
1919
2020In a language with *dependent types*, however, the distinction is less
2121clear. Dependent types allow types to “depend” on values — in other
docs/tutorial/modules.rst+12−2
@@ -212,14 +212,24 @@ using a ``parameters`` declaration, for example:
212212 addAll z = x + y + z
213213
214214The effect of a ``parameters`` block is to add the declared parameters
215−to every function, type and data constructor within the block. Outside
216−the block, the parameters must be given explicitly:
215+to every function, type and data constructor within the
216+block. Specifically, adding the parameters to the front of the
217+argument list. Outside the block, the parameters must be given
218+explicitly. The ``addAll`` function, when called from the REPL, will
219+thus have the following type signature.
217220
218221::
219222
220223 *params> :t addAll
221224 addAll : Nat -> Nat -> Nat -> Nat
222225
226+and the following definition.
227+
228+.. code-block:: idris
229+
230+ addAll : (x : Nat) -> (y : Nat) -> (z : Nat) -> Nat
231+ addAll x y z = x + y + z
232+
223233Parameters blocks can be nested, and can also include data declarations,
224234in which case the parameters are added explicitly to all type and data
225235constructors. They may also be dependent types with implicit arguments:
docs/tutorial/provisional.rst+12−12
@@ -213,11 +213,11 @@ representation (in this case ``Binary``) with a meaning (in this case
213213.. code-block:: idris
214214
215215 data Binary : Nat -> Type where
216− bEnd : Binary Z
217− bO : Binary n -> Binary (n + n)
218− bI : Binary n -> Binary (S (n + n))
216+ BEnd : Binary Z
217+ BO : Binary n -> Binary (n + n)
218+ BI : Binary n -> Binary (S (n + n))
219219
220−``bO`` and ``bI`` take a binary number as an argument and effectively
220+``BO`` and ``BI`` take a binary number as an argument and effectively
221221shift it one bit left, adding either a zero or one as the new least
222222significant bit. The index, ``n + n`` or ``S (n + n)`` states the result
223223that this left shift then add will have to the meaning of the number.
@@ -234,17 +234,17 @@ original Nat:
234234
235235The ``Parity`` view makes the definition fairly simple — halving the
236236number is effectively a right shift after all — although we need to use
237−a provisional definition in the odd case:
237+a provisional definition in the Odd case:
238238
239239.. code-block:: idris
240240
241241 natToBin : (n:Nat) -> Binary n
242− natToBin Z = bEnd
242+ natToBin Z = BEnd
243243 natToBin (S k) with (parity k)
244− natToBin (S (j + j)) | even = bI (natToBin j)
245− natToBin (S (S (j + j))) | odd ?= bO (natToBin (S j))
244+ natToBin (S (j + j)) | Even = BI (natToBin j)
245+ natToBin (S (S (j + j))) | Odd ?= BO (natToBin (S j))
246246
247−The problem with the odd case is the same as in the definition of
247+The problem with the Odd case is the same as in the definition of
248248``parity``, and the proof proceeds in the same way:
249249
250250.. code-block:: idris
@@ -272,6 +272,6 @@ For this to work, of course, we need a ``Show`` instance for
272272.. code-block:: idris
273273
274274 instance Show (Binary n) where
275− show (bO x) = show x ++ "0"
276− show (bI x) = show x ++ "1"
277− show bEnd = ""
275+ show (BO x) = show x ++ "0"
276+ show (BI x) = show x ++ "1"
277+ show BEnd = ""
docs/tutorial/syntax.rst+3−3
@@ -122,7 +122,7 @@ hard to program this way in practice. Recall the factorial program in
122122
123123 fact : Expr G (TyFun TyInt TyInt)
124124 fact = Lam (If (Op (==) (Var Stop) (Val 0))
125− (Val 1) (Op (*) (app fact (Op (-) (Var Stop) (Val 1)))
125+ (Val 1) (Op (*) (App fact (Op (-) (Var Stop) (Val 1)))
126126 (Var Stop)))
127127
128128Since this is a particularly useful pattern, Idris provides syntax
@@ -162,8 +162,8 @@ declaring:
162162
163163.. code-block:: idris
164164
165− (<$>) : (f : Lazy (Expr G (TyFun a t))) -> Expr G a -> Expr G t
166− (<$>) f a = App f a
165+ (<*>) : (f : Lazy (Expr G (TyFun a t))) -> Expr G a -> Expr G t
166+ (<*>) f a = App f a
167167
168168 pure : Expr G a -> Expr G a
169169 pure = id
docs/tutorial/typesfuns.rst+29−17
@@ -56,7 +56,7 @@ answer. For example:
5656::
5757
5858 *prims> 6*6+6
59− 42 : Int
59+ 42 : Integer
6060 *prims> x == 6*6+6
6161 True : Bool
6262
@@ -445,7 +445,8 @@ are not given in applications of ``index``; their values can be
445445inferred from the types of the ``Fin n`` and ``Vect n a``
446446arguments. Any name beginning with a lower case letter which appears
447447as a parameter or index in a
448−type declaration, but which is otherwise unbound, will be automatically
448+type declaration, which is not applied to any arguments, will
449+*always* be automatically
449450bound as an implicit argument. Implicit arguments can still be given
450451explicitly in applications, using ``{a=value}`` and ``{n=value}``, for
451452example:
@@ -791,12 +792,12 @@ providing a default value:
791792
792793.. code-block:: idris
793794
794− maybe : Lazy b -> (a -> b) -> Maybe a -> b
795+ maybe : Lazy b -> Lazy (a -> b) -> Maybe a -> b
795796
796−Note that the type of the first argument is ``Lazy b`` rather than
797−simply ``b``. Since the default value might not be used, we mark it as
798−``Lazy`` in case it is a large expression where evaluating it then
799−discarding it would be wasteful.
797+Note that the types of the first two arguments are wrapped in
798+``Lazy``. Since only one of the two arguments will actually be used,
799+we mark them as ``Lazy`` in case they are large expressions where it
800+would be wasteful to compute and then discard them.
800801
801802Tuples
802803------
@@ -819,6 +820,15 @@ contain an arbitrary number of values, represented as nested pairs:
819820 jim : (String, Int, String)
820821 jim = ("Jim", 25, "Cambridge")
821822
823+::
824+
825+ *usefultypes> fst jim
826+ "Jim" : String
827+ *usefultypes> snd jim
828+ (25, "Cambridge") : (Int, String)
829+ *usefultypes> jim == ("Jim", (25, "Cambridge"))
830+ True : Bool
831+
822832Dependent Pairs
823833---------------
824834
@@ -1013,7 +1023,7 @@ name. For example, a pair type could be defined as follows:
10131023Using the class record from the original introduction to records. The
10141024size of the class can be restricted using a ``Vect`` and the size
10151025promoted to the type level by parameterising the record with the size.
1016−Foe example:
1026+For example:
10171027
10181028
10191029.. code-block:: idris
@@ -1024,7 +1034,11 @@ Foe example:
10241034 className : String
10251035
10261036**Note** that it is no longer possible to use the ``addStudent``
1027−method from earlier as that would change the size of the class. To provide an add student the function must specify in the type that the size of the class has been increased by one. As the size if specified using natural numbers, the new value can be incremented using the successor constructor.
1037+function from earlier, since that would change the size of the class. A
1038+function to add a student must now specify in the type that the
1039+size of the class has been increased by one. As the size is specified
1040+using natural numbers, the new value can be incremented using the
1041+``S`` constructor.
10281042
10291043.. code-block:: idris
10301044
@@ -1043,11 +1057,9 @@ Intermediate values can be calculated using ``let`` bindings:
10431057
10441058.. code-block:: idris
10451059
1046− data Person = MkPerson String Int
1047−
1048− showPerson : Person -> String
1049− showPerson p = let MkPerson name age = p in
1050− name ++ " is " ++ show age ++ " years old"
1060+ mirror : List a -> List a
1061+ mirror xs = let xs' = reverse xs in
1062+ xs ++ xs'
10511063
10521064We can do simple pattern matching in ``let`` bindings too. For
10531065example, we can extract fields from a record as follows, as well as by
@@ -1136,8 +1148,8 @@ auxiliary functions, and is also used internally to implement pattern
11361148matching ``let`` and lambda bindings. It will *only* work if:
11371149
11381150- Each branch *matches* a value of the same type, and *returns* a
1139− value of the same type.
1151+ value of the same type.
11401152
11411153- The type of the result is "known". i.e. the type of the expression
1142− can be determined *without* type checking the ``case``-expression
1143− itself.
1154+ can be determined *without* type checking the ``case``-expression
1155+ itself.
idris.cabal+28−3
@@ -1,5 +1,5 @@
11Name: idris
2−Version: 0.9.19.1
2+Version: 0.9.20.2
33License: BSD3
44License-file: LICENSE
55Author: Edwin Brady
@@ -115,6 +115,7 @@ Extra-source-files:
115115 libs/base/Control/*.idr
116116 libs/base/Control/Monad/*.idr
117117 libs/base/Data/*.idr
118+ libs/base/Data/List/*.idr
118119 libs/base/Data/Vect/*.idr
119120 libs/base/Debug/*.idr
120121 libs/base/Language/Reflection/*.idr
@@ -309,6 +310,9 @@ Extra-source-files:
309310 test/reg066/run
310311 test/reg066/*.idr
311312 test/reg066/expected
313+ test/reg067/run
314+ test/reg067/*.idr
315+ test/reg067/expected
312316
313317 test/basic001/run
314318 test/basic001/*.idr
@@ -356,6 +360,9 @@ Extra-source-files:
356360 test/basic015/run
357361 test/basic015/*.idr
358362 test/basic015/expected
363+ test/basic016/run
364+ test/basic016/*.idr
365+ test/basic016/expected
359366
360367 test/bignum001/run
361368 test/bignum001/*.idr
@@ -535,6 +542,17 @@ Extra-source-files:
535542 test/interactive009/input
536543 test/interactive009/*.idr
537544 test/interactive009/expected
545+ test/interactive010/expected
546+ test/interactive010/input
547+ test/interactive010/run
548+ test/interactive011/expected
549+ test/interactive011/input
550+ test/interactive011/run
551+ test/interactive011/*.idr
552+ test/interactive012/expected
553+ test/interactive012/input
554+ test/interactive012/run
555+ test/interactive012/*.idr
538556
539557 test/io001/run
540558 test/io001/*.idr
@@ -556,6 +574,9 @@ Extra-source-files:
556574 test/meta002/run
557575 test/meta002/*.idr
558576 test/meta002/expected
577+ test/meta004/run
578+ test/meta004/*.idr
579+ test/meta004/expected
559580
560581 test/primitives001/run
561582 test/primitives001/*.idr
@@ -954,11 +975,14 @@ Library
954975 , uniplate >=1.6 && < 1.7
955976 , unordered-containers < 0.3
956977 , utf8-string < 1.1
957− , vector < 0.11
978+ , vector < 0.12
958979 , vector-binary-instances < 0.3
959980 , zip-archive > 0.2.3.5 && < 0.2.4
960− , zlib < 0.6
961981 , safe
982+ -- zlib >= 0.6.1 is broken with GHC < 7.10.3
983+ if impl(ghc < 7.10.3)
984+ build-depends: zlib < 0.6.1
985+
962986 Extensions: MultiParamTypeClasses
963987 , DeriveFoldable
964988 , DeriveTraversable
@@ -990,6 +1014,7 @@ Library
9901014 cpp-options: -DIDRIS_FFI
9911015 if flag(GMP)
9921016 build-depends: libffi < 0.2
1017+ extra-libraries: gmp
9931018 cpp-options: -DIDRIS_GMP
9941019 if flag(curses)
9951020 build-depends: hscurses < 1.5
iif/adder.iifdeleted−30
@@ -1,30 +0,0 @@
1−data O 0
2−data S 1
3−
4−fun plus(x, y) = case x of {
5− O => y
6− | S(k) => S (plus(k, y))
7− }
8−
9−fun natToInt(x) = case x of {
10− O => 0
11− | S(k) => let y = natToInt(k) in y + 1
12− }
13−
14−fun adder(arity, acc) = case arity of {
15− O => acc
16− | S(k) => adderAux(k, acc)
17− }
18−
19−fun adderAux(k, acc, n) = adder(k, plus(acc, n))
20−
21−fun zero() = O
22−fun one() = S(zero)
23−fun two() = S(one)
24−fun three() = S(two)
25−fun four() = S(three)
26−fun five() = S(four)
27−
28−fun main() = %WriteInt(natToInt(adder(three, two, three, four, five)))
29−
30−
iif/big.iifdeleted−7
@@ -1,7 +0,0 @@
1−fun fact(x) = case (x ==: 0:) of {
2− 0 => x *: fact(x - 1)
3− | _ => 1:
4− }
5−
6−fun main() = let f = fact(200:) in
7− %WriteString(%BigString(f) ++ "\n")
iif/ctest.cdeleted−106
@@ -1,106 +0,0 @@
1−#include <idris_rts.h>
2−
3−void plus(VM* vm, VAL* oldbase) {
4− INITFRAME;
5− RESERVE(2);
6− ADDTOP(2);
7−
8− switch(TAG(LOC(0))) {
9− case 0:
10− PROJECT(vm, LOC(0), 2, 0);
11− RVAL = LOC(1);
12− TOPBASE(0);
13− REBASE;
14− break;
15− case 1:
16− PROJECT(vm, LOC(0), 2, 1);
17− RESERVE(2);
18− TOP(0) = LOC(2);
19− TOP(1) = LOC(1);
20− STOREOLD;
21− BASETOP(0);
22− ADDTOP(2);
23− CALL(plus);
24− LOC(3) = RVAL;
25− RVAL = MKCON(vm, 1, 1, LOC(3));
26− TOPBASE(0);
27− REBASE;
28− break;
29− }
30−}
31−
32−void natToInt(VM* vm, VAL* oldbase) {
33− INITFRAME;
34− RESERVE(3);
35− ADDTOP(3);
36−
37− switch(TAG(LOC(0))) {
38− case 0:
39− PROJECT(vm, LOC(0), 2, 0);
40− RVAL = MKINT(0);
41− TOPBASE(0);
42− REBASE;
43− break;
44− case 1:
45− PROJECT(vm, LOC(0), 1, 1);
46− RESERVE(1);
47− TOP(0) = LOC(1);
48− STOREOLD;
49− BASETOP(0);
50− ADDTOP(1);
51− CALL(natToInt);
52− LOC(2) = RVAL;
53− RVAL = ADD(LOC(2), MKINT(1));
54− TOPBASE(0);
55− REBASE;
56− break;
57− }
58−}
59−
60−int do_main(VM* vm, VAL* oldbase) {
61− INITFRAME;
62− RESERVE(2);
63− ADDTOP(2);
64−
65− LOC(0) = MKCON(vm, 0, 0);
66− LOC(0) = MKCON(vm, 1, 1, LOC(0));
67− LOC(0) = MKCON(vm, 1, 1, LOC(0));
68−
69− dumpVal(LOC(0));
70− printf("\n");
71−
72− LOC(1) = MKCON(vm, 0, 0);
73− LOC(1) = MKCON(vm, 1, 1, LOC(1));
74− LOC(1) = MKCON(vm, 1, 1, LOC(1));
75−
76− RESERVE(2);
77− TOP(0) = LOC(0);
78− TOP(1) = LOC(1);
79−
80− STOREOLD;
81− BASETOP(0);
82− ADDTOP(2);
83− CALL(plus);
84− LOC(0) = RVAL;
85−
86− RESERVE(1);
87− TOP(0) = LOC(0);
88− SLIDE(vm, 1);
89− TOPBASE(1);
90− TAILCALL(natToInt);
91−/* STOREOLD;
92− BASETOP(0);
93− ADDTOP(1);
94− CALL(natToInt);
95− TOPBASE(0);
96− REBASE; */
97−}
98−
99−int main() {
100− VM* vm = init_vm(100,100);
101−
102− do_main(vm, NULL);
103− printf("%ld\n", GETINT(RVAL));
104−
105− printf("%d %d %d\n", vm->valstack, vm->valstack_base, vm->valstack_top);
106−}
iif/lazy.iifdeleted−21
@@ -1,21 +0,0 @@
1−data Nil 0
2−data Cons 2
3−
4−fun countFrom(x) = Cons(x, countFrom@(x+1))
5−
6−fun take(n, xs) = case n of {
7− 0 => Nil
8− | _ => case xs of {
9− Nil => Nil
10− | Cons(y, ys) => Cons(y, take(n-1, ys))
11− }
12− }
13−
14−fun dumpList(xs) = case xs of {
15− Nil => "END"
16− | Cons(y, ys) => %IntString(y) ++ ", " ++ dumpList(ys)
17− }
18−
19−fun double(x) = x + x
20−
21−fun main() = %WriteString(dumpList(take(5, countFrom(10))))
iif/testmap.iifdeleted−30
@@ -1,30 +0,0 @@
1−data Nil 0
2−data Cons 2
3−
4−fun twice(f, x) = f(f(x))
5−
6−fun map(f, xs) = case xs of {
7− Nil => Nil
8− | Cons(y, ys) => Cons(f(y), map(f, ys))
9− }
10−
11−fun dumpList(xs) = case xs of {
12− Nil => "END"
13− | Cons(y, ys) => %IntString(y) ++ ", " ++ dumpList(ys)
14− }
15−
16−fun countFrom(x) = Cons(x, countFrom@(x+1))
17−
18−fun take(n, xs) = case n of {
19− 0 => Nil
20− | _ => case xs of {
21− Nil => Nil
22− | Cons(y, ys) => Cons(y, take(n-1, ys))
23− }
24− }
25−
26−fun double(x) = x + x
27−
28−fun main() = let mult = 2 in
29− %WriteString(dumpList(map(twice(\ x => x*mult), take(1010, countFrom(10)))))
30−
iif/testvm.iifdeleted−32
@@ -1,32 +0,0 @@
1−data O 0
2−data S 1
3−
4−fun plus(x, y) = case x of {
5− O => y
6− | S(k) => S (plus(k, y))
7− }
8−
9−fun fact(x) = factAux(x, 1)
10−
11−fun factAux(x, acc) = case (x == 1) of {
12− 0 => factAux(x-1, acc * x)
13− | 1 => acc
14− }
15−
16−fun natToInt(x) = case x of {
17− O => 0
18− | S(k) => let y = natToInt(k) in y + 1
19− }
20−
21−fun intToNat(x) = case x of {
22− 0 => O
23− | _ => S (intToNat (x - 1))
24− }
25−
26−fun sin(x) = foreign C Float "sin" (Float x)
27−
28−fun main() = let val = natToInt(plus(intToNat(fact(6)), S(S(O)))) in
29− let sval = sin(1.0) in
30− %WriteString("Answer: " ++ %IntString(val)
31− ++ " " ++ %FloatString(sval))
32−
libs/base/Control/Catchable.idr+4−4
@@ -16,14 +16,14 @@ instance Catchable (Either a) a where
1616 catch (Left err) h = h err
1717 catch (Right x) h = (Right x)
1818
19− throw x = Left x
19+ throw = Left
2020
2121instance Catchable (IOExcept err) err where
22− catch (ioM prog) h = ioM (do p' <- prog
22+ catch (IOM prog) h = IOM (do p' <- prog
2323 case p' of
24− Left e => let ioM he = h e in he
24+ Left e => let IOM he = h e in he
2525 Right val => return (Right val))
26− throw x = ioM (return (Left x))
26+ throw = ioe_fail
2727
2828instance Catchable List () where
2929 catch [] h = h ()
libs/base/Control/IOExcept.idr+10−19
@@ -2,34 +2,25 @@ module Control.IOExcept
22
33-- An IO monad with exception handling
44
5−data IOExcept : Type -> Type -> Type where
6− ioM : IO (Either err a) -> IOExcept err a
5+record IOExcept err a where
6+ constructor IOM
7+ runIOExcept : IO (Either err a)
78
89instance Functor (IOExcept e) where
9− map f (ioM fn) = ioM (map (map f) fn)
10+ map f (IOM fn) = IOM (map (map f) fn)
1011
1112instance Applicative (IOExcept e) where
12− pure x = ioM (pure (pure x))
13− (ioM f) <*> (ioM a) = ioM (do f' <- f; a' <- a
14− return (f' <*> a'))
13+ pure x = IOM (pure (pure x))
14+ (IOM f) <*> (IOM a) = IOM [| f <*> a |]
1515
1616instance Monad (IOExcept e) where
17− (ioM x) >>= k = ioM (do x' <- x;
18− case x' of
19− Right a => let (ioM ka) = k a in
20− ka
21− Left err => return (Left err))
17+ (IOM x) >>= f = IOM $ x >>= either (pure . Left) (runIOExcept . f)
2218
2319ioe_lift : IO a -> IOExcept err a
24−ioe_lift op = ioM (do op' <- op
25− return (Right op'))
20+ioe_lift op = IOM $ map Right op
2621
2722ioe_fail : err -> IOExcept err a
28−ioe_fail e = ioM (return (Left e))
23+ioe_fail e = IOM $ pure (Left e)
2924
3025ioe_run : IOExcept err a -> (err -> IO b) -> (a -> IO b) -> IO b
31−ioe_run (ioM act) err ok = do act' <- act
32− case act' of
33− Left e => err e
34− Right v => ok v
35−
26+ioe_run (IOM act) err ok = either err ok !act
libs/base/Data/Complex.idr+8−8
@@ -25,7 +25,7 @@ instance Show a => Show (Complex a) where
2525 plus_i = User 6
2626
2727
28−-- when we have a type class 'Fractional' (which contains Float and Double),
28+-- when we have a type class 'Fractional' (which contains Double),
2929-- we can do:
3030{-
3131instance Fractional a => Fractional (Complex a) where
@@ -40,16 +40,16 @@ instance Fractional a => Fractional (Complex a) where
4040
4141------------------------------ Polarform
4242
43−mkPolar : Float -> Float -> Complex Float
43+mkPolar : Double -> Double -> Complex Double
4444mkPolar radius angle = radius * cos angle :+ radius * sin angle
4545
46−cis : Float -> Complex Float
46+cis : Double -> Complex Double
4747cis angle = cos angle :+ sin angle
4848
49−magnitude : Complex Float -> Float
49+magnitude : Complex Double -> Double
5050magnitude (r:+i) = sqrt (r*r+i*i)
5151
52−phase : Complex Float -> Float
52+phase : Complex Double -> Double
5353phase (x:+y) = atan2 y x
5454
5555
@@ -62,13 +62,13 @@ instance Functor Complex where
6262 map f (r :+ i) = f r :+ f i
6363
6464-- We can't do "instance Num a => Num (Complex a)" because
65−-- we need "abs" which needs "magnitude" which needs "sqrt" which needs Float
66−instance Num (Complex Float) where
65+-- we need "abs" which needs "magnitude" which needs "sqrt" which needs Double
66+instance Num (Complex Double) where
6767 (+) (a:+b) (c:+d) = ((a+c):+(b+d))
6868 (*) (a:+b) (c:+d) = ((a*c-b*d):+(b*c+a*d))
6969 fromInteger x = (fromInteger x:+0)
7070
71−instance Neg (Complex Float) where
71+instance Neg (Complex Double) where
7272 negate = map negate
7373 (-) (a:+b) (c:+d) = ((a-c):+(b-d))
7474 abs (a:+b) = (magnitude (a:+b):+0)
libs/base/Data/HVect.idr+9−9
@@ -73,17 +73,17 @@ instance (Shows k ts) => Show (HVect ts) where
7373
7474||| Extract an arbitrary element of the correct type.
7575||| @ t the goal type
76−get : {auto p : Elem t ts} -> HVect ts -> t
77−get {p = Here} (x::xs) = x
78−get {p = There p'} (x::xs) = get {p = p'} xs
76+get : HVect ts -> {auto p : Elem t ts} -> t
77+get (x :: xs) {p = Here} = x
78+get (x :: xs) {p = There p'} = get {p = p'} xs
7979
8080||| Replace an element with the correct type.
81−put : {auto p : Elem t ts} -> t -> HVect ts -> HVect ts
82−put {p = Here} y (x::xs) = y :: xs
83−put {p = There p'} y (x::xs) = x :: put {p = p'} y xs
81+put : t -> HVect ts -> {auto p : Elem t ts} -> HVect ts
82+put y (x::xs) {p = Here} = y :: xs
83+put y (x::xs) {p = There p'} = x :: put {p = p'} y xs
8484
8585||| Update an element with the correct type.
86−update : {auto p : Elem t ts} -> (t -> u) -> HVect ts -> HVect (replaceByElem ts p u)
87−update {p = Here} f (x::xs) = f x :: xs
88−update {p = There p'} f (x::xs) = x :: update {p = p'} f xs
86+update : (t -> u) -> HVect ts -> {auto p : Elem t ts} -> HVect (replaceByElem ts p u)
87+update f (x::xs) {p = Here} = f x :: xs
88+update f (x::xs) {p = There p'} = x :: update {p = p'} f xs
8989
libs/base/Data/List/Quantifiers.idrnew file+75
@@ -0,0 +1,75 @@
1+module Data.List.Quantifiers
2+
3+import Data.List
4+
5+||| A proof that some element of a list satisfies some property
6+|||
7+||| @ P the property to be satsified
8+data Any : (P : a -> Type) -> List a -> Type where
9+ ||| A proof that the satisfying element is the first one in the `List`
10+ Here : {P : a -> Type} -> {xs : List a} -> P x -> Any P (x :: xs)
11+ ||| A proof that the satsifying element is in the tail of the `List`
12+ There : {P : a -> Type} -> {xs : List a} -> Any P xs -> Any P (x :: xs)
13+
14+||| No element of an empty list satisfies any property
15+anyNilAbsurd : {P : a -> Type} -> Any P Nil -> Void
16+anyNilAbsurd (Here _) impossible
17+anyNilAbsurd (There _) impossible
18+
19+instance Uninhabited (Any p Nil) where
20+ uninhabited = anyNilAbsurd
21+
22+||| Eliminator for `Any`
23+anyElim : {xs : List a} -> {P : a -> Type} -> (Any P xs -> b) -> (P x -> b) -> Any P (x :: xs) -> b
24+anyElim _ f (Here p) = f p
25+anyElim f _ (There p) = f p
26+
27+||| Given a decision procedure for a property, determine if an element of a
28+||| list satisfies it.
29+|||
30+||| @ P the property to be satisfied
31+||| @ dec the decision procedure
32+||| @ xs the list to examine
33+any : {P : a -> Type} -> (dec : (x : a) -> Dec (P x)) -> (xs : List a) -> Dec (Any P xs)
34+any _ Nil = No anyNilAbsurd
35+any p (x::xs) with (p x)
36+ | Yes prf = Yes (Here prf)
37+ | No prf =
38+ case any p xs of
39+ Yes prf' => Yes (There prf')
40+ No prf' => No (anyElim prf' prf)
41+
42+||| A proof that all elements of a list satisfy a property. It is a list of
43+||| proofs, corresponding element-wise to the `List`.
44+data All : (P : a -> Type) -> List a -> Type where
45+ Nil : {P : a -> Type} -> All P Nil
46+ (::) : {P : a -> Type} -> {xs : List a} -> P x -> All P xs -> All P (x :: xs)
47+
48+||| If there does not exist an element that satifies the property, then it is
49+||| the case that all elements do not satisfy.
50+negAnyAll : {P : a -> Type} -> {xs : List a} -> Not (Any P xs) -> All (\x => Not (P x)) xs
51+negAnyAll {xs=Nil} _ = Nil
52+negAnyAll {xs=(x::xs)} f = (\x => f (Here x)) :: negAnyAll (\x => f (There x))
53+
54+notAllHere : {P : a -> Type} -> {xs : List a} -> Not (P x) -> All P (x :: xs) -> Void
55+notAllHere _ Nil impossible
56+notAllHere np (p :: _) = np p
57+
58+notAllThere : {P : a -> Type} -> {xs : List a} -> Not (All P xs) -> All P (x :: xs) -> Void
59+notAllThere _ Nil impossible
60+notAllThere np (_ :: ps) = np ps
61+
62+||| Given a decision procedure for a property, decide whether all elements of
63+||| a list satisfy it.
64+|||
65+||| @ P the property
66+||| @ dec the decision procedure
67+||| @ xs the list to examine
68+all : {P : a -> Type} -> (dec : (x : a) -> Dec (P x)) -> (xs : List a) -> Dec (All P xs)
69+all _ Nil = Yes Nil
70+all d (x::xs) with (d x)
71+ | No prf = No (notAllHere prf)
72+ | Yes prf =
73+ case all d xs of
74+ Yes prf' => Yes (prf :: prf')
75+ No prf' => No (notAllThere prf')
libs/base/Data/String.idrnew file+110
@@ -0,0 +1,110 @@
1+module Data.String
2+
3+private
4+parseNumWithoutSign : List Char -> Integer -> Maybe Integer
5+parseNumWithoutSign [] acc = Just acc
6+parseNumWithoutSign (c :: cs) acc =
7+ if (c >= '0' && c <= '9')
8+ then parseNumWithoutSign cs ((acc * 10) + (cast ((ord c) - (ord '0'))))
9+ else Nothing
10+
11+
12+||| Convert a positive number string to a Num.
13+|||
14+||| ```idris example
15+||| parsePositive "123"
16+||| ```
17+||| ```idris example
18+||| parsePositive {a=Int} " +123"
19+||| ```
20+parsePositive : Num a => String -> Maybe a
21+parsePositive s = parsePosTrimmed (trim s)
22+ where
23+ parsePosTrimmed s with (strM s)
24+ parsePosTrimmed "" | StrNil = Nothing
25+ parsePosTrimmed (strCons x xs) | (StrCons x xs) =
26+ if (x == '+')
27+ then map fromInteger (parseNumWithoutSign (unpack xs) 0)
28+ else map fromInteger (parseNumWithoutSign (unpack xs) (cast (ord x - ord '0')))
29+
30+
31+||| Convert a number string to a Num.
32+|||
33+||| ```idris example
34+||| parseInteger " 123"
35+||| ```
36+||| ```idris example
37+||| parseInteger {a=Int} " -123"
38+||| ```
39+parseInteger : (Num a, Neg a) => String -> Maybe a
40+parseInteger s = parseIntTrimmed (trim s)
41+ where
42+ parseIntTrimmed s with (strM s)
43+ parseIntTrimmed "" | StrNil = Nothing
44+ parseIntTrimmed (strCons x xs) | (StrCons x xs) =
45+ if (x == '-')
46+ then map (\y => negate (fromInteger y)) (parseNumWithoutSign (unpack xs) 0)
47+ else if (x == '+')
48+ then map fromInteger (parseNumWithoutSign (unpack xs) (cast {from=Int} 0))
49+ else map fromInteger (parseNumWithoutSign (unpack xs) (cast (ord x - ord '0')))
50+
51+
52+||| Convert a number string to a Double.
53+|||
54+||| ```idris example
55+||| parseDouble "+123.123e-2"
56+||| ```
57+||| ```idris example
58+||| parseDouble {a=Int} " -123.123E+2"
59+||| ```
60+||| ```idris example
61+||| parseDouble {a=Int} " +123.123"
62+||| ```
63+parseDouble : String -> Maybe Double
64+parseDouble = mkDouble . wfe . trim
65+ where
66+ mkDouble (Just (w, f, e)) = let ex = intPow 10 e in
67+ Just $ (w * ex + f * ex)
68+ mkDouble Nothing = Nothing
69+
70+ %assert_total
71+ intPow : Integer -> Integer -> Double
72+ intPow base exp = if exp > 0 then (num base exp) else 1 / (num base exp)
73+ where
74+ num base 0 = 1
75+ num base e = if e < 0
76+ then cast base * num base (e + 1)
77+ else cast base * num base (e - 1)
78+
79+ wfe : String -> Maybe (Double, Double, Integer)
80+ wfe cs = case split (== '.') cs of
81+ (wholeAndExp :: []) =>
82+ case split (\c => c == 'e' || c == 'E') wholeAndExp of
83+ (whole::exp::[]) =>
84+ do
85+ w <- cast <$> parseInteger whole
86+ e <- parseInteger exp
87+ return (w, 0, e)
88+ (whole::[]) =>
89+ do
90+ w <- cast <$> parseInteger whole
91+ return (w, 0, 0)
92+ _ => Nothing
93+ (whole::fracAndExp::[]) =>
94+ case split (\c => c == 'e' || c == 'E') fracAndExp of
95+ (""::exp::[]) => Nothing
96+ (frac::exp::[]) =>
97+ do
98+ w <- cast <$> parseInteger whole
99+ f <- (/ (pow 10 (length frac))) <$>
100+ (cast <$> parseNumWithoutSign (unpack frac) 0)
101+ e <- parseInteger exp
102+ return (w, if w < 0 then (-f) else f, e)
103+ (frac::[]) =>
104+ do
105+ w <- cast <$> parseInteger whole
106+ f <- (/ (pow 10 (length frac))) <$>
107+ (cast <$> parseNumWithoutSign (unpack frac) 0)
108+ return (w, if w < 0 then (-f) else f, 0)
109+ _ => Nothing
110+ _ => Nothing
libs/base/Data/Vect.idr+5−5
@@ -614,11 +614,11 @@ mapElem (There e) = There (mapElem e)
614614||| @xs the vector with the desired length
615615-- Needs to be Maybe rather than Dec, because if 'n' is unequal to m, we
616616-- only know we don't know how to make a Vect n a, not that one can't exist.
617−isLength : {m : Nat} -> -- expected at run-time
618− (len : Nat) -> (xs : Vect m a) -> Maybe (Vect len a)
619−isLength {m} len xs with (decEq m len)
620− isLength {m = m} m xs | (Yes Refl) = Just xs
621− isLength {m = m} len xs | (No contra) = Nothing
617+exactLength : {m : Nat} -> -- expected at run-time
618+ (len : Nat) -> (xs : Vect m a) -> Maybe (Vect len a)
619+exactLength {m} len xs with (decEq m len)
620+ exactLength {m = m} m xs | (Yes Refl) = Just xs
621+ exactLength {m = m} len xs | (No contra) = Nothing
622622
623623||| If the given Vect is at least the required length, return a Vect with
624624||| at least that length in its type, otherwise return Nothing
libs/base/Data/Vect/Quantifiers.idr+1
@@ -19,6 +19,7 @@ anyNilAbsurd (There _) impossible
1919instance Uninhabited (Any p Nil) where
2020 uninhabited = anyNilAbsurd
2121
22+||| Eliminator for `Any`
2223anyElim : {xs : Vect n a} -> {P : a -> Type} -> (Any P xs -> b) -> (P x -> b) -> Any P (x :: xs) -> b
2324anyElim _ f (Here p) = f p
2425anyElim f _ (There p) = f p
libs/base/Language/Reflection/Utils.idr+21−21
@@ -55,13 +55,18 @@ binderTy : Binder t -> t
5555binderTy (Lam t) = t
5656binderTy (Pi t _) = t
5757binderTy (Let t1 t2) = t1
58−binderTy (NLet t1 t2) = t1
5958binderTy (Hole t) = t
6059binderTy (GHole t) = t
6160binderTy (Guess t1 t2) = t1
6261binderTy (PVar t) = t
6362binderTy (PVTy t) = t
6463
64+instance Show SourceLocation where
65+ showPrec d (FileLoc filename line col) = showCon d "FileLoc" $ showArg filename ++ showArg line ++ showArg col
66+
67+instance Eq SourceLocation where
68+ (FileLoc fn s e) == (FileLoc fn' s' e') = fn == fn' && s == s' && e == e'
69+
6570mutual
6671 instance Show SpecialName where
6772 showPrec d (WhereN i n1 n2) = showCon d "WhereN" $ showArg i ++
@@ -70,7 +75,7 @@ mutual
7075 showPrec d (InstanceN i ss) = showCon d "InstanceN" $ showArg i ++ showArg ss
7176 showPrec d (ParentN n s) = showCon d "ParentN" $ showArg n ++ showArg s
7277 showPrec d (MethodN n) = showCon d "MethodN" $ showArg n
73− showPrec d (CaseN n) = showCon d "CaseN" $ showArg n
78+ showPrec d (CaseN fc n) = showCon d "CaseN" $ showArg fc ++ showArg n
7479 showPrec d (ElimN n) = showCon d "ElimN" $ showArg n
7580 showPrec d (InstanceCtorN n) = showCon d "InstanceCtorN" $ showArg n
7681 showPrec d (MetaN parent meta) = showCon d "MetaN" $ showArg parent ++ showArg meta
@@ -80,14 +85,12 @@ mutual
8085 showPrec d (NS n ns) = showCon d "NS" $ showArg n ++ showArg ns
8186 showPrec d (MN i str) = showCon d "MN" $ showArg i ++ showArg str
8287 showPrec d (SN sn) = showCon d "SN" $ assert_total (showArg sn)
83− showPrec d NErased = "NErased"
8488
8589mutual
8690 instance Eq TTName where
8791 (UN str1) == (UN str2) = str1 == str2
8892 (NS n ns) == (NS n' ns') = n == n' && ns == ns'
8993 (MN i str) == (MN i' str') = i == i' && str == str'
90− NErased == NErased = True
9194 (SN sn) == (SN sn') = assert_total $ sn == sn'
9295 x == y = False
9396
@@ -97,7 +100,7 @@ mutual
97100 (InstanceN i ss) == (InstanceN i' ss') = i == i' && ss == ss'
98101 (ParentN n s) == (ParentN n' s') = n == n' && s == s'
99102 (MethodN n) == (MethodN n') = n == n'
100− (CaseN n) == (CaseN n') = n == n'
103+ (CaseN fc n) == (CaseN fc' n') = fc == fc' && n == n'
101104 (ElimN n) == (ElimN n') = n == n'
102105 (InstanceCtorN n) == (InstanceCtorN n') = n == n'
103106 (MetaN parent meta) == (MetaN parent' meta') = parent == parent' && meta == meta'
@@ -126,7 +129,7 @@ instance Show IntTy where
126129
127130instance Show ArithTy where
128131 showPrec d (ATInt t) = showCon d "ATInt" $ showArg t
129− showPrec d ATFloat = "ATFloat"
132+ showPrec d ATDouble = "ATDouble"
130133
131134instance Show Const where
132135 showPrec d (I i) = showCon d "I" $ showArg i
@@ -159,7 +162,7 @@ instance Eq Reflection.IntTy where
159162
160163instance Eq ArithTy where
161164 (ATInt x) == (ATInt y) = x == y
162− ATFloat == ATFloat = True
165+ ATDouble == ATDouble = True
163166 _ == _ = False
164167
165168instance Eq Const where
@@ -196,7 +199,6 @@ instance (Show a) => Show (Binder a) where
196199 showPrec d (Lam t) = showCon d "Lam" $ showArg t
197200 showPrec d (Pi t1 t2) = showCon d "Pi" $ showArg t1 ++ showArg t2
198201 showPrec d (Let t1 t2) = showCon d "Let" $ showArg t1 ++ showArg t2
199− showPrec d (NLet t1 t2) = showCon d "NLet" $ showArg t1 ++ showArg t2
200202 showPrec d (Hole t) = showCon d "Hole" $ showArg t
201203 showPrec d (GHole t) = showCon d "GHole" $ showArg t
202204 showPrec d (Guess t1 t2) = showCon d "Guess" $ showArg t1 ++ showArg t2
@@ -207,7 +209,6 @@ instance (Eq a) => Eq (Binder a) where
207209 (Lam t) == (Lam t') = t == t'
208210 (Pi t k) == (Pi t' k') = t == t' && k == k'
209211 (Let t1 t2) == (Let t1' t2') = t1 == t1' && t2 == t2'
210− (NLet t1 t2) == (NLet t1' t2') = t1 == t1' && t2 == t2'
211212 (Hole t) == (Hole t') = t == t'
212213 (GHole t) == (GHole t') = t == t'
213214 (Guess t1 t2) == (Guess t1' t2') = t1 == t1' && t2 == t2'
@@ -223,9 +224,7 @@ instance Show TT where
223224 my_show d (Bind n b t) = showCon d "Bind" $ showArg n ++ showArg b ++ showArg t
224225 my_show d (App t1 t2) = showCon d "App" $ showArg t1 ++ showArg t2
225226 my_show d (TConst c) = showCon d "TConst" $ showArg c
226− my_show d (Proj tm i) = showCon d "Proj" $ showArg tm ++ showArg i
227227 my_show d Erased = "Erased"
228− my_show d Impossible = "Impossible"
229228 my_show d (TType u) = showCon d "TType" $ showArg u
230229
231230instance Eq TT where
@@ -236,9 +235,7 @@ instance Eq TT where
236235 equalp (Bind n b t) (Bind n' b' t') = n == n' && b == b' && t == t'
237236 equalp (App t1 t2) (App t1' t2') = t1 == t1' && t2 == t2'
238237 equalp (TConst c) (TConst c') = c == c'
239− equalp (Proj tm i) (Proj tm' i') = tm == tm' && i == i'
240238 equalp Erased Erased = True
241− equalp Impossible Impossible = True
242239 equalp (TType u) (TType u') = u == u'
243240 equalp x y = False
244241
@@ -260,17 +257,17 @@ forget tm = fe [] tm
260257 LT => Nothing
261258 GT => atIndex xs (n-1)
262259
263− %assert_total
264260 fe : List TTName -> TT -> Maybe Raw
265261 fe env (P _ n _) = Just $ Var n
266− fe env (V i) = map Var (atIndex env i)
267− fe env (Bind n b sc) = [| RBind (pure n) (traverse (fe env) b) (fe (n::env) sc) |]
262+ fe env (V i) = [| Var (atIndex env i) |]
263+ fe env (Bind n b sc) = [| RBind (pure n)
264+ (assert_total $ traverse (fe env) b)
265+ (fe (n::env) sc) |]
268266 fe env (App f a) = [| RApp (fe env f) (fe env a) |]
269267 fe env (TConst c) = Just $ RConstant c
270− fe env (Proj tm i) = Nothing -- runtime only, not useful for metaprogramming
271268 fe env (TType i) = Just RType
269+ fe env (UType uni) = Just (RUType uni)
272270 fe env Erased = Just $ RConstant Forgot
273− fe env Impossible = Nothing
274271
275272instance Show Raw where
276273 showPrec = my_show
@@ -279,11 +276,8 @@ instance Show Raw where
279276 my_show d (RBind n b tm) = showCon d "RBind" $ showArg n ++ showArg b ++ " " ++ my_show App tm
280277 my_show d (RApp tm tm') = showCon d "RApp" $ " " ++ my_show App tm ++ " " ++ my_show App tm'
281278 my_show d RType = "RType"
282− my_show d (RForce tm) = showCon d "RForce" $ " " ++ my_show App tm
283279 my_show d (RConstant c) = showCon d "RConstant" $ showArg c
284280
285−instance Show SourceLocation where
286− showPrec d (FileLoc filename line col) = showCon d "FileLoc" $ showArg filename ++ showArg line ++ showArg col
287281
288282instance Show Err where
289283 showPrec d (Msg x) = showCon d "Msg" $ showArg x
@@ -355,3 +349,9 @@ instance Show CtorArg where
355349instance Show TyDecl where
356350 showPrec d (Declare fn args ret) = showCon d "Declare" $ showArg fn ++
357351 showArg args ++ showArg ret
352+
353+instance Show tm => Show (FunClause tm) where
354+ showPrec d (MkFunClause lhs rhs) =
355+ showCon d "MkFunClause" $ showArg lhs ++ showArg rhs
356+ showPrec d (MkImpossibleClause lhs) =
357+ showCon d "MkImpossibleClause" $ showArg lhs
libs/base/System.idr+1−1
@@ -56,7 +56,7 @@ getEnvironment = getAllPairs 0 []
5656exit : Int -> IO ()
5757exit code = foreign FFI_C "exit" (Int -> IO ()) code
5858
59−||| Get the Unix time
59+||| Get the numbers of sections since 1st January 1970, 00:00 UTC
6060time : IO Integer
6161time = do MkRaw t <- foreign FFI_C "idris_time" (IO (Raw Integer))
6262 return t
libs/base/base.ipkg+2−1
@@ -17,7 +17,8 @@ modules = System,
1717 Data.HVect, Data.Vect.Quantifiers,
1818 Data.Complex,
1919 Data.Erased, Data.List,
20− Data.So,
20+ Data.List.Quantifiers,
21+ Data.So, Data.String,
2122
2223 Control.Isomorphism,
2324 Control.Monad.Identity,
libs/contrib/Control/Algebra/NumericInstances.idr+7−7
@@ -44,24 +44,24 @@ instance RingWithUnity Int where
4444 unity = 1
4545
4646
47−instance Semigroup Float where
47+instance Semigroup Double where
4848 (<+>) = (+)
4949
50−instance Monoid Float where
50+instance Monoid Double where
5151 neutral = 0
5252
53−instance Group Float where
53+instance Group Double where
5454 inverse = (* -1)
5555
56−instance AbelianGroup Float
56+instance AbelianGroup Double
5757
58−instance Ring Float where
58+instance Ring Double where
5959 (<.>) = (*)
6060
61−instance RingWithUnity Float where
61+instance RingWithUnity Double where
6262 unity = 1
6363
64−instance Field Float where
64+instance Field Double where
6565 inverseM f _ = 1 / f
6666
6767
libs/contrib/Network/Socket.idr−4
@@ -143,10 +143,6 @@ record Socket where
143143 socketType : SocketType
144144 protocalNumber : ProtocolNumber
145145
146−||| Get the C error number
147−getErrno : IO Int
148−getErrno = foreign FFI_C "idrnet_errno" (IO Int)
149−
150146||| Creates a UNIX socket with the given family, socket type and protocol
151147||| number. Returns either a socket or an error.
152148socket : SocketFamily -> SocketType -> ProtocolNumber -> IO (Either SocketError Socket)
libs/effects/Effect/Default.idr+1−1
@@ -11,7 +11,7 @@ instance Default Int where
1111instance Default Integer where
1212 default = 0
1313
14−instance Default Float where
14+instance Default Double where
1515 default = 0
1616
1717instance Default Nat where
libs/effects/Effect/Exception.idr+2−1
@@ -18,7 +18,7 @@ instance Show a => Handler (Exception a) IO where
1818 believe_me (exit 1)
1919
2020instance Handler (Exception a) (IOExcept a) where
21− handle _ (Raise e) k = ioM (return (Left e))
21+ handle _ (Raise e) k = ioe_fail e
2222
2323instance Handler (Exception a) (Either a) where
2424 handle _ (Raise e) k = Left e
@@ -28,3 +28,4 @@ EXCEPTION t = MkEff () (Exception t)
2828
2929raise : a -> Eff b [EXCEPTION a]
3030raise err = call $ Raise err
31+
libs/effects/Effect/File.idr+76−31
@@ -8,8 +8,8 @@ import Control.IOExcept
88||| A Dependent type to describe File Handles. File handles are
99||| parameterised with the current state of the file: Closed; Open for
1010||| reading; and Open for writing.
11−|||
12−||| @ m The file mode.
11+|||
12+||| @ m The file mode.
1313data OpenFile : (m : Mode) -> Type where
1414 FH : File -> OpenFile m
1515
@@ -21,27 +21,27 @@ openOK m False = ()
2121
2222||| Here the protocol for resource access is defined as an effect.
2323||| The state transitions diagram for the protocol is as follows:
24−|||
24+|||
2525||| digraph G {
26−|||
26+|||
2727||| empty; read; write; // States
28−|||
28+|||
2929||| empty -> read [label="Open R"];
3030||| read -> empty [label="Close"];
3131||| read -> read [label="ReadLine"];
3232||| read -> read [label="EOF"];
33−|||
33+|||
3434||| empty -> write [label="Open W"];
3535||| write -> empty [label="Close"];
3636||| write -> write [label="WriteLine"];
37−|||
37+|||
3838||| }
3939data FileIO : Effect where
4040 ||| Open a file with the specified mode.
41− |||
41+ |||
4242 ||| Opening a file successful moves the state from 'empty' to the
4343 ||| specified mode. If not successful the state is still 'empty'.
44− |||
44+ |||
4545 ||| @ fname The file name to be opened.
4646 ||| @ m The file mode.
4747 Open : (fname: String)
@@ -51,22 +51,22 @@ data FileIO : Effect where
5151 False => ())
5252
5353 ||| Close a file.
54− |||
54+ |||
5555 ||| Closing a file moves the state from Open to closed.
56− Close : sig FileIO () (OpenFile m) ()
56+ Close : sig FileIO () (OpenFile m) ()
5757
5858 ||| Read a line from the file.
59− |||
59+ |||
6060 ||| Only files that are open for reading can be read.
6161 ReadLine : sig FileIO String (OpenFile Read)
62−
62+
6363 ||| Write a string to a file.
64− |||
64+ |||
6565 ||| Only file that are open for writing can be written to.
6666 WriteString : String -> sig FileIO () (OpenFile Write)
6767
6868 ||| End of file?
69− |||
69+ |||
7070 ||| Only files open for reading can be tested for EOF
7171 EOF : sig FileIO Bool (OpenFile Read)
7272
@@ -74,31 +74,35 @@ data FileIO : Effect where
7474
7575--- An implementation of the resource access protocol for the IO Context.
7676instance Handler FileIO IO where
77− handle () (Open fname m) k = do h <- openFile fname m
78− valid <- validFile h
79− if valid then k True (FH h)
80− else k False ()
77+ handle () (Open fname m) k = do Right h <- openFile fname m
78+ | Left err => k False ()
79+ k True (FH h)
8180 handle (FH h) Close k = do closeFile h
8281 k () ()
83− handle (FH h) ReadLine k = do str <- fread h
82+ handle (FH h) ReadLine k = do Right str <- fGetLine h
83+ -- Need proper error handling!
84+ | Left err => k "" (FH h)
8485 k str (FH h)
85− handle (FH h) (WriteString str) k = do fwrite h str
86+ handle (FH h) (WriteString str) k = do Right () <- fPutStr h str
87+ | Left err => k () (FH h)
8688 k () (FH h)
87− handle (FH h) EOF k = do e <- feof h
89+ handle (FH h) EOF k = do e <- fEOF h
8890 k e (FH h)
8991
9092instance Handler FileIO (IOExcept a) where
91− handle () (Open fname m) k = do h <- ioe_lift $ openFile fname m
92− valid <- ioe_lift $ validFile h
93− if valid then k True (FH h)
94− else k False ()
93+ handle () (Open fname m) k = do Right h <- ioe_lift $ openFile fname m
94+ | Left err => k False ()
95+ k True (FH h)
9596 handle (FH h) Close k = do ioe_lift $ closeFile h
9697 k () ()
97− handle (FH h) ReadLine k = do str <- ioe_lift $ fread h
98+ handle (FH h) ReadLine k = do Right str <- ioe_lift $ fGetLine h
99+ -- Need proper error handling!
100+ | Left err => k "" (FH h)
98101 k str (FH h)
99− handle (FH h) (WriteString str) k = do ioe_lift $ fwrite h str
102+ handle (FH h) (WriteString str) k = do Right () <- ioe_lift $ fPutStr h str
103+ | Left err => k () (FH h)
100104 k () (FH h)
101− handle (FH h) EOF k = do e <- ioe_lift $ feof h
105+ handle (FH h) EOF k = do e <- ioe_lift $ fEOF h
102106 k e (FH h)
103107
104108-- -------------------------------------------------------------- [ The Effect ]
@@ -112,12 +116,12 @@ FILE_IO t = MkEff t FileIO
112116--
113117
114118||| Open a file with the specified mode.
115−|||
119+|||
116120||| @ fname The file name to be opened.
117121||| @ m The file mode.
118122open : (fname : String)
119123 -> (m : Mode)
120− -> Eff Bool [FILE_IO ()]
124+ -> Eff Bool [FILE_IO ()]
121125 (\res => [FILE_IO (case res of
122126 True => OpenFile m
123127 False => ())])
@@ -144,4 +148,45 @@ writeLine str = call $ WriteString (str ++ "\n")
144148eof : Eff Bool [FILE_IO (OpenFile Read)]
145149eof = call $ EOF
146150
151+||| Read a complete file, returning a user defined error if
152+||| unsuccesful.
153+|||
154+readFile : (errFunc : String -> e)
155+ -> (fname : String)
156+ -> Eff (Either e String) [FILE_IO ()]
157+readFile errFunc fname = do
158+ case !(open fname Read) of
159+ False => pure $ Left (errFunc fname)
160+ True => do
161+ src <- readAcc ""
162+ close
163+ pure $ Right src
164+ where
165+ readAcc : String -> Eff String [FILE_IO (OpenFile Read)]
166+ readAcc acc = if (not !(eof))
167+ then readAcc (acc ++ !(readLine))
168+ else pure acc
169+
170+||| Write a file containing the provided string, returning a user
171+||| defined error if unsuccesful.
172+|||
173+writeFile : (errFunc : String -> e)
174+ -> (fname : String)
175+ -> (content : String)
176+ -> Eff (Either e ()) [FILE_IO ()]
177+writeFile errFunc fname content = do
178+ case !(open fname Write) of
179+ True => do
180+ writeString content
181+ close
182+ pure $ Right ()
183+ False => pure $ Left (errFunc fname)
184+
185+
186+namespace Default
187+ readFile : String -> Eff (Either String String) [FILE_IO ()]
188+ readFile = File.readFile id
189+
190+ writeFile : String -> String -> Eff (Either String ()) [FILE_IO ()]
191+ writeFile = File.writeFile id
147192-- --------------------------------------------------------------------- [ EOF ]
libs/effects/Effect/Logging/Category.idr−3
@@ -25,9 +25,6 @@ record LogRes (a : Type) where
2525 getLevel : LogLevel n
2626 getCategories : List a
2727
28−instance (Show a) => Show (LogRes a) where
29− show (MkLogRes l cs) = unwords ["Log Settings:", show l, show cs]
30−
3128instance Default (LogRes a) where
3229 default = MkLogRes OFF Nil
3330
libs/effects/Effect/Perf.idrnew file+230
@@ -0,0 +1,230 @@
1+-- ---------------------------------------------------------------- [ Perf.idr ]
2+-- Module : Perf.idr
3+-- Copyright : (c) Jan de Muijnck-Hughes
4+-- License : see LICENSE
5+-- --------------------------------------------------------------------- [ EOH ]
6+||| A naive performance effect for gathering data about the
7+||| performance of effectful programmes.
8+module Effect.Perf
9+
10+import System
11+
12+import Effects
13+import Effect.Default
14+
15+%access public
16+
17+-- ---------------------------------------------------- [ Timer Data Structure ]
18+
19+||| A Simple timer.
20+record Timer where
21+ constructor MkTimer
22+ desc : String
23+ start : Integer
24+ stop : Integer
25+ splits : List (Integer, Maybe String)
26+
27+displayTimer : Timer -> String
28+displayTimer (MkTimer d a z bcd) = unlines
29+ [ unwords ["Timer:", d]
30+ , unwords ["\tStart:\t", show a, (displaySplits bcd)]
31+ , unwords ["\tStop:\t", show z]
32+ , unwords ["\tDifference:\t", show (z - a)]
33+ ]
34+ where
35+ displaySplit : (Integer, Maybe String) -> String
36+ displaySplit (v, Nothing) = with List unwords ["\tSplit:\t",show v]
37+ displaySplit (v, Just msg) = with List unwords ["\tSplit:\t",show v, show msg]
38+
39+ displaySplits : List (Integer, Maybe String) -> String
40+ displaySplits Nil = ""
41+ displaySplits ss = "\n" ++ unlines (map displaySplit $ reverse ss)
42+
43+
44+defaultTimer : String -> Timer
45+defaultTimer n = MkTimer n 0 0 Nil
46+
47+-- ---------------------------------------------------------------- [ Resource ]
48+
49+||| Performance Metrics to keep during program lifetime.
50+record PMetrics where
51+ constructor MkPMetrics
52+ canPerf : Bool
53+ livePerf : Bool
54+ counters : List (String, Nat)
55+ timers : List (String, Timer)
56+ stime : Integer
57+ stamps : List (String, Integer)
58+
59+
60+instance Default PMetrics where
61+ default = MkPMetrics False False Nil Nil 0 Nil
62+
63+displayPerfMetrics : PMetrics -> String
64+displayPerfMetrics (MkPMetrics c l cs ts _ ss) =
65+ unlines [ "Perf Data:"
66+ , unlines $ map displayMarker cs
67+ , unlines $ map (\(x,y) => displayTimer y) ts
68+ , unlines $ map displayMarker ss]
69+ where
70+ displayMarker : Show a => Pair String a -> String
71+ displayMarker (d,v) = unwords [show v, "\t<==\t", show d]
72+
73+-- ------------------------------------------------------- [ Utility functions ]
74+
75+incCounter' : String -> PMetrics -> PMetrics
76+incCounter' x st = record {counters = cs} st
77+ where
78+ cs : List (String, Nat)
79+ cs = map (\(y,c) => if x == y then (y,S c) else (y,c)) (counters st)
80+
81+
82+data TOpt = START | STOP | SPLIT
83+
84+displayTimerOpt : TOpt -> String
85+displayTimerOpt START = "Starting"
86+displayTimerOpt STOP = "Stopping"
87+displayTimerOpt SPLIT = "Splitting"
88+
89+timerStuff' : TOpt -> Integer -> String -> Maybe String -> PMetrics -> PMetrics
90+timerStuff' opt val x msg st = record {timers = ts} st
91+ where
92+ doThing : (String,Timer) -> (String,Timer)
93+ doThing (y,t) =
94+ if not (x == y)
95+ then (y, t)
96+ else case opt of
97+ START => MkPair y $ record {start = val} t
98+ STOP => MkPair y $ record {stop = val} t
99+ SPLIT => MkPair y $ record {splits = (val, msg) :: splits t} t
100+
101+ ts : List (String, Timer)
102+ ts = map doThing (timers st)
103+
104+
105+perfLog : PMetrics -> String -> IO ()
106+perfLog res msg =
107+ if livePerf res
108+ then putStrLn $ unwords ["PERF:", msg]
109+ else return ()
110+
111+-- ------------------------------------------------------- [ Effect Definition ]
112+
113+data Perf : Effect where
114+ GetMetrics : sig Perf (PMetrics) (PMetrics)
115+ TurnOn : Bool -> sig Perf () (PMetrics) (PMetrics)
116+ MkCounter : String -> sig Perf () (PMetrics) (PMetrics)
117+ IncCounter : String -> sig Perf () (PMetrics) (PMetrics)
118+ Timestamp : String -> sig Perf () (PMetrics) (PMetrics)
119+ MkStopWatch : String -> sig Perf () (PMetrics) (PMetrics)
120+ TimerStuff : TOpt -> String -> Maybe String -> sig Perf () (PMetrics) (PMetrics)
121+
122+-- ---------------------------------------------------------- [ Handler for IO ]
123+
124+instance Handler Perf IO where
125+ handle res (TurnOn b) k = do
126+ v <- time
127+ let res' = record {canPerf = True, livePerf = b, stime = v} res
128+ perfLog res' $ unwords [ "Turning on Perf with at", show v]
129+ k () (res')
130+
131+ handle res (GetMetrics) k = k res res
132+
133+ handle res (MkCounter n) k = do
134+ if not (canPerf res)
135+ then k () res
136+ else do
137+ let res' = record {counters = (n,Z) :: counters res} res
138+ perfLog res' $ unwords ["Creating counter:", show n]
139+ k () (res')
140+
141+ handle res (IncCounter n) k = do
142+ if not (canPerf res)
143+ then k () res
144+ else do
145+ let res' = incCounter' n res
146+ perfLog res' $ unwords ["Incriminating counter:", show n]
147+ k () (res')
148+
149+ handle res (MkStopWatch n) k = do
150+ if not (canPerf res)
151+ then k () res
152+ else do
153+ let res' = record {timers = (n, defaultTimer n) :: timers res} res
154+ perfLog res' $ unwords ["Creating Timer:", show n]
155+ k () (res')
156+
157+ handle res (TimerStuff opt n msg) k = do
158+ v <- time
159+ if not (canPerf res)
160+ then k () res
161+ else do
162+ let res' = timerStuff' opt v n msg res
163+ perfLog res' $ unwords [displayTimerOpt opt, "timer", show n, "at", show v, fromMaybe "" msg]
164+ k () (res')
165+
166+ handle res (Timestamp s) k = do
167+ v <- time
168+ let stamp = v - (stime res)
169+ if not (canPerf res)
170+ then k () res
171+ else do
172+ let res' = record {stamps = (s,stamp) :: stamps res} res
173+ perfLog res' $ unlines [ "Creating Timestamp:"
174+ , "\tTIMESTAMP:", show v
175+ , "\tMESSAGE:", show s]
176+ k () (res')
177+
178+-- ------------------------------------------------------- [ Effect Descriptor ]
179+
180+PERF : EFFECT
181+PERF = MkEff PMetrics Perf
182+
183+-- --------------------------------------------------------------------- [ API ]
184+
185+||| Turn on performance metrics.
186+collectPMetricsOnly : Eff () [PERF]
187+collectPMetricsOnly = call $ TurnOn False
188+
189+collectPMetrics : Bool -> Eff () [PERF]
190+collectPMetrics b = call $ TurnOn b
191+
192+||| Turn on performance metrics and show during operation
193+collectPMetricsAndShow : Eff () [PERF]
194+collectPMetricsAndShow = call $ TurnOn True
195+
196+||| Return gatheres metrics
197+getPerfMetrics : Eff PMetrics [PERF]
198+getPerfMetrics = call $ GetMetrics
199+
200+||| Create a counter
201+mkCounter : String -> Eff () [PERF]
202+mkCounter n = call $ MkCounter n
203+
204+||| Increment the counter
205+incCounter : String -> Eff () [PERF]
206+incCounter n = call $ IncCounter n
207+
208+mkTimer : String -> Eff () [PERF]
209+mkTimer n = call $ MkStopWatch n
210+
211+||| Stop a timer
212+stopTimer : String -> Eff () [PERF]
213+stopTimer n = call $ TimerStuff STOP n Nothing
214+
215+||| Start a timer
216+startTimer : String -> Eff () [PERF]
217+startTimer n = call $ TimerStuff START n Nothing
218+
219+||| Split a timer
220+splitTimer : String -> Eff () [PERF]
221+splitTimer n = call $ TimerStuff SPLIT n Nothing
222+
223+splitTimerMsg : String -> String -> Eff () [PERF]
224+splitTimerMsg n msg = call $ TimerStuff SPLIT n (Just msg)
225+
226+||| Create a time stamp.
227+timestamp : String -> Eff () [PERF]
228+timestamp msg = call $ Timestamp msg
229+
230+-- --------------------------------------------------------------------- [ EOF ]
libs/effects/Effect/Random.idr+7−7
@@ -4,28 +4,28 @@ import Effects
44import Data.Vect
55
66data Random : Effect where
7− getRandom : sig Random Integer Integer
8− setSeed : Integer -> sig Random () Integer
7+ GetRandom : sig Random Integer Integer
8+ SetSeed : Integer -> sig Random () Integer
99
1010instance Handler Random m where
11− handle seed getRandom k
11+ handle seed GetRandom k
1212 = let seed' = assert_total ((1664525 * seed + 1013904223) `prim__sremBigInt` (pow 2 32)) in
1313 k seed' seed'
14− handle seed (setSeed n) k = k () n
14+ handle seed (SetSeed n) k = k () n
1515
1616RND : EFFECT
1717RND = MkEff Integer Random
1818
1919||| Generates a random Integer in a given range
2020rndInt : Integer -> Integer -> Eff Integer [RND]
21−rndInt lower upper = do v <- call $ getRandom
21+rndInt lower upper = do v <- call $ GetRandom
2222 return ((v `prim__sremBigInt` (upper - lower)) + lower)
2323
2424||| Generate a random number in Fin (S `k`)
2525|||
2626||| Note that rndFin k takes values 0, 1, ..., k.
2727rndFin : (k : Nat) -> Eff (Fin (S k)) [RND]
28−rndFin k = do let v = assert_total $ !(call getRandom) `prim__sremBigInt` (cast (S k))
28+rndFin k = do let v = assert_total $ !(call GetRandom) `prim__sremBigInt` (cast (S k))
2929 return (toFin v)
3030 where toFin : Integer -> Fin (S k)
3131 toFin x = case integerToFin x (S k) of
@@ -43,5 +43,5 @@ rndSelect (x::xs) = return (Just !(rndSelect' (x::(fromList xs))))
4343
4444||| Sets the random seed
4545srand : Integer -> Eff () [RND]
46−srand n = call $ setSeed n
46+srand n = call $ SetSeed n
4747
libs/effects/Effects.idr+31−19
@@ -12,9 +12,9 @@ import Data.Vect
1212||| The Effect type describes effectful computations.
1313|||
1414||| This type is parameterised by:
15−||| + The input resource.
1615||| + The return type of the computation.
17−||| + The computation to run on the resource.
16+||| + The input resource.
17+||| + The computation to run on the resource given the return value.
1818Effect : Type
1919Effect = (x : Type) -> Type -> (x -> Type) -> Type
2020
@@ -159,17 +159,17 @@ relabel {xs = (MkEff a e :: xs)} l (v :: vs) = (l := v) :: relabel l vs
159159data EffM : (m : Type -> Type) -> (x : Type)
160160 -> (es : List EFFECT)
161161 -> (ce : x -> List EFFECT) -> Type where
162− value : (val : a) -> EffM m a (xs val) xs
163− ebind : EffM m a xs xs' ->
162+ Value : (val : a) -> EffM m a (xs val) xs
163+ EBind : EffM m a xs xs' ->
164164 ((val : a) -> EffM m b (xs' val) xs'') -> EffM m b xs xs''
165− callP : (prf : EffElem e a xs) ->
165+ CallP : (prf : EffElem e a xs) ->
166166 (eff : e t a b) ->
167167 EffM m t xs (\v => updateResTy v xs prf eff)
168168
169− liftP : (prf : SubList ys xs) ->
169+ LiftP : (prf : SubList ys xs) ->
170170 EffM m t ys ys' -> EffM m t xs (\v => updateWith (ys' v) xs prf)
171171
172− new : Handler e' m => (e : EFFECT) -> resTy ->
172+ New : Handler e' m => (e : EFFECT) -> resTy ->
173173 {auto prf : e = MkEff resTy e'} ->
174174 EffM m t (e :: es) (\v => e :: es) ->
175175 EffM m t es (\v => es)
@@ -211,12 +211,12 @@ namespace DepEff
211211%no_implicit
212212(>>=) : EffM m a xs xs' ->
213213 ((val : a) -> EffM m b (xs' val) xs'') -> EffM m b xs xs''
214−(>>=) = ebind
214+(>>=) = EBind
215215
216216-- namespace SimpleBind
217217-- (>>=) : Eff m a xs (\v => xs) ->
218218-- ((val : a) -> Eff m b xs xs') -> Eff m b xs xs'
219−-- (>>=) = ebind
219+-- (>>=) = EBind
220220
221221||| Run a subprogram which results in an effect state the same as the input.
222222staticEff : EffM m a xs (\v => xs) -> EffM m a xs (\v => xs)
@@ -228,17 +228,17 @@ toEff : .(xs' : List EFFECT) -> EffM m a xs (\v => xs') -> EffM m a xs (\v => xs
228228toEff xs' = id
229229
230230return : a -> EffM m a xs (\v => xs)
231−return x = value x
231+return x = Value x
232232
233233-- ------------------------------------------------------ [ for idiom brackets ]
234234
235235infixl 2 <*>
236236
237237pure : a -> EffM m a xs (\v => xs)
238−pure = value
238+pure = Value
239239
240240pureM : (val : a) -> EffM m a (xs val) xs
241−pureM = value
241+pureM = Value
242242
243243(<*>) : EffM m (a -> b) xs (\v => xs) ->
244244 EffM m a xs (\v => xs) -> EffM m b xs (\v => xs)
@@ -246,6 +246,17 @@ pureM = value
246246 arg <- v
247247 return (fn arg)
248248
249+(*>) : EffM m a xs (\v => xs) ->
250+ EffM m b xs (\v => xs) -> EffM m b xs (\v => xs)
251+a *> b = do a
252+ b
253+
254+new : Handler e' m => (e : EFFECT) -> resTy ->
255+ {auto prf : e = MkEff resTy e'} ->
256+ EffM m t (e :: es) (\v => e :: es) ->
257+ EffM m t es (\v => es)
258+new = New
259+
249260-- ---------------------------------------------------------- [ an interpreter ]
250261
251262private
@@ -261,14 +272,14 @@ execEff (val :: env) (There p) eff k
261272-- updates can be propagated even through failing computations?
262273
263274eff : Env m xs -> EffM m a xs xs' -> ((x : a) -> Env m (xs' x) -> m b) -> m b
264−eff env (value x) k = k x env
265−eff env (prog `ebind` c) k
275+eff env (Value x) k = k x env
276+eff env (prog `EBind` c) k
266277 = eff env prog (\p', env' => eff env' (c p') k)
267−eff env (callP prf effP) k = execEff env prf effP k
268−eff env (liftP prf effP) k
278+eff env (CallP prf effP) k = execEff env prf effP k
279+eff env (LiftP prf effP) k
269280 = let env' = dropEnv env prf in
270281 eff env' effP (\p', envk => k p' (rebuildEnv envk prf env))
271−eff env (new (MkEff resTy newEff) res {prf=Refl} effP) k
282+eff env (New (MkEff resTy newEff) res {prf=Refl} effP) k
272283 = eff (res :: env) effP (\p', (val :: envk) => k p' envk)
273284eff env (l :- prog) k
274285 = let env' = unlabel env in
@@ -286,17 +297,18 @@ syntax MkDefaultEnv = with Env
286297 [default, default, default, default, default, default, default],
287298 [default, default, default, default, default, default, default, default] |)
288299
300+%no_implicit
289301call : {a, b: _} -> {e : Effect} ->
290302 (eff : e t a b) ->
291303 {auto prf : EffElem e a xs} ->
292304 EffM m t xs (\v => updateResTy v xs prf eff)
293−call e {prf} = callP prf e
305+call e {prf} = CallP prf e
294306
295307implicit
296308lift : EffM m t ys ys' ->
297309 {auto prf : SubList ys xs} ->
298310 EffM m t xs (\v => updateWith (ys' v) xs prf)
299−lift e {prf} = liftP prf e
311+lift e {prf} = LiftP prf e
300312
301313
302314-- --------------------------------------------------------- [ Running Effects ]
libs/effects/effects.ipkg+1
@@ -18,3 +18,4 @@ modules = Effects
1818 , Effect.Logging.Level
1919 , Effect.Logging.Default
2020 , Effect.Logging.Category
21+ , Effect.Perf
libs/oldeffects/Effect/Default.idr+1−1
@@ -9,7 +9,7 @@ instance Default Int where
99instance Default Integer where
1010 default = 0
1111
12−instance Default Float where
12+instance Default Double where
1313 default = 0
1414
1515instance Default Nat where
libs/prelude/Builtins.idr+17−2
@@ -19,6 +19,10 @@ namespace Builtins
1919 ||| @b the right element of the pair
2020 MkPair : {A, B : Type} -> (a : A) -> (b : B) -> Pair A B
2121
22+ -- Usage hints for erasure analysis
23+ %used MkPair a
24+ %used MkPair b
25+
2226 ||| The non-dependent pair type, also known as conjunction, usable with
2327 ||| UniqueTypes.
2428 ||| @A the type of the left elements in the pair
@@ -29,6 +33,10 @@ namespace Builtins
2933 ||| @b the right element of the pair
3034 MkUPair : {A, B : AnyType} -> (a : A) -> (b : B) -> UPair A B
3135
36+ -- Usage hints for erasure analysis
37+ %used MkUPair a
38+ %used MkUPair b
39+
3240 ||| Dependent pairs
3341 |||
3442 ||| Dependent pairs represent existential quantification - they consist of a
@@ -48,7 +56,12 @@ namespace Builtins
4856
4957||| The eliminator for the `Void` type.
5058void : Void -> a
51−void {a} v = elim_for Void (\_ => a) v
59+-- We can't define void yet. We can't define a function with no clauses without
60+-- elaborator reflection, and we can't do elaborator reflection without
61+-- Language.Reflection.Elab, and Language.Reflection.Elab depends on Builtins.
62+-- We can't delay the declaration of void, because Prelude.Uninhabited depends on
63+-- it, Prelude.Nat depends on Prelude.Uninhabited, and Language.Reflection.Elab
64+-- depends on Prelude.Nat. Instead, void is defined in Prelude.idr
5265
5366||| For 'symbol syntax. 'foo becomes Symbol_ "foo"
5467data Symbol_ : String -> Type where
@@ -152,9 +165,11 @@ public %assert_total
152165really_believe_me : a -> b
153166really_believe_me x = prim__believe_me _ _ x
154167
155−-- Deprecated - for backward compatibility
168+||| Deprecated alias for `Double`, for the purpose of backwards
169+||| compatibility. Idris does not support 32 bit floats at present.
156170Float : Type
157171Float = Double
172+%deprecate Float
158173
159174-- Pointers as external primitive; there's no literals for these, so no
160175-- need for them to be part of the compiler.
libs/prelude/Decidable/Equality.idr+1−1
@@ -178,7 +178,7 @@ instance DecEq Char where
178178instance DecEq Integer where
179179 decEq x y = if x == y then Yes primitiveEq else No primitiveNotEq
180180 where primitiveEq : x = y
181− primitiveEq = believe_me (Refl {x})
181+ primitiveEq = really_believe_me (Refl {x})
182182 postulate primitiveNotEq : x = y -> Void
183183
184184
libs/prelude/IO.idr+17−8
@@ -8,7 +8,7 @@ import Prelude.List
88||| Idris's primitive IO, for building abstractions on top of
99abstract
1010data PrimIO : Type -> Type where
11− prim__IO : a -> PrimIO a
11+ Prim__IO : a -> PrimIO a
1212
1313||| A token representing the world, for use in `IO`
1414abstract data World = TheWorld prim__WorldType
@@ -93,14 +93,14 @@ foreign ffi fname ty {fty} = foreign_prim ffi fname fty []
9393
9494abstract
9595prim_io_bind : PrimIO a -> (a -> PrimIO b) -> PrimIO b
96−prim_io_bind (prim__IO v) k = k v
96+prim_io_bind (Prim__IO v) k = k v
9797
9898unsafePerformPrimIO : PrimIO a -> a
9999-- compiled as primitive
100100
101101abstract
102102prim_io_return : a -> PrimIO a
103−prim_io_return x = prim__IO x
103+prim_io_return x = Prim__IO x
104104
105105abstract
106106io_bind : IO' l a -> (a -> IO' l b) -> IO' l b
@@ -116,11 +116,11 @@ io_return x = MkIO (\w => prim_io_return x)
116116liftPrimIO : (World -> PrimIO a) -> IO' l a
117117liftPrimIO = MkIO
118118
119−call__IO : IO' l a -> PrimIO a
119+call__IO : IO' ffi a -> PrimIO a
120120call__IO (MkIO f) = f (TheWorld prim__TheWorld)
121121
122122-- Concrete type makes it easier to elaborate at top level
123−run__IO : IO' l () -> PrimIO ()
123+run__IO : IO' ffi () -> PrimIO ()
124124run__IO f = call__IO f
125125
126126unsafePerformIO : IO' ffi a -> a
@@ -162,7 +162,7 @@ namespace FFI_C
162162 ||| Supported C foreign types
163163 data C_Types : Type -> Type where
164164 C_Str : C_Types String
165− C_Float : C_Types Float
165+ C_Float : C_Types Double
166166 C_Ptr : C_Types Ptr
167167 C_MPtr : C_Types ManagedPtr
168168 C_Unit : C_Types ()
@@ -171,10 +171,14 @@ namespace FFI_C
171171
172172 ||| A descriptor for the C FFI. See the constructors of `C_Types`
173173 ||| and `C_IntTypes` for the concrete types that are available.
174+ %error_reverse
174175 FFI_C : FFI
175176 FFI_C = MkFFI C_Types String String
176177
177−IO : Type -> Type
178+||| Interactive programs, describing I/O actions and returning a value.
179+||| @res The result type of the program
180+%error_reverse
181+IO : (res : Type) -> Type
178182IO = IO' FFI_C
179183
180184-- Cannot be relaxed as is used by type providers and they expect IO a
@@ -195,6 +199,9 @@ namespace IO
195199 forceGC : IO ()
196200 forceGC = foreign FFI_C "idris_forceGC" (Ptr -> IO ()) prim__vm
197201
202+ getErrno : IO Int
203+ getErrno = foreign FFI_C "idris_errno" (IO Int)
204+
198205--------- The Javascript/Node FFI
199206
200207
@@ -214,7 +221,7 @@ mutual
214221
215222 data JS_Types : Type -> Type where
216223 JS_Str : JS_Types String
217− JS_Float : JS_Types Float
224+ JS_Float : JS_Types Double
218225 JS_Ptr : JS_Types Ptr
219226 JS_Unit : JS_Types ()
220227 JS_FnT : JS_FnTypes a -> JS_Types (JsFn a)
@@ -228,9 +235,11 @@ mutual
228235||| The JavaScript FFI. The strings naming functions in this API are
229236||| JavaScript code snippets, into which the arguments are substituted
230237||| for the placeholders `%0`, `%1`, etc.
238+%error_reverse
231239FFI_JS : FFI
232240FFI_JS = MkFFI JS_Types String String
233241
242+%error_reverse
234243JS_IO : Type -> Type
235244JS_IO = IO' FFI_JS
236245
libs/prelude/Language/Reflection.idr+99−64
@@ -11,6 +11,22 @@ import Prelude.Traversable
1111
1212%access public
1313
14+||| A source location in an Idris file
15+record SourceLocation where
16+ ||| Either a source span or a source location. `start` and `end`
17+ ||| will be the same if it's a point location.
18+ constructor FileLoc
19+
20+ ||| The file name of the source location
21+ filename : String
22+ ||| The line and column of the beginning of the source span
23+ start : (Int, Int)
24+ ||| The line and column of the end of the source span
25+ end : (Int, Int)
26+
27+%name SourceLocation loc
28+
29+
1430mutual
1531 data TTName =
1632 ||| A user-provided name
@@ -24,9 +40,7 @@ mutual
2440 MN Int String |
2541 ||| Special names, to make conflicts impossible and language features
2642 ||| predictable
27− SN SpecialName |
28− ||| Name of something which is never used in scope
29− NErased
43+ SN SpecialName
3044 %name TTName n, n'
3145
3246 data SpecialName = WhereN Int TTName TTName
@@ -34,7 +48,7 @@ mutual
3448 | InstanceN TTName (List String)
3549 | ParentN TTName String
3650 | MethodN TTName
37− | CaseN TTName
51+ | CaseN SourceLocation TTName
3852 | ElimN TTName
3953 | InstanceCtorN TTName
4054 | MetaN TTName TTName
@@ -56,10 +70,10 @@ data NativeTy = IT8 | IT16 | IT32 | IT64
5670
5771data IntTy = ITFixed NativeTy | ITNative | ITBig | ITChar
5872
59−data ArithTy = ATInt Language.Reflection.IntTy | ATFloat
73+data ArithTy = ATInt Language.Reflection.IntTy | ATDouble
6074
6175||| Primitive constants
62−data Const = I Int | BI Integer | Fl Float | Ch Char | Str String
76+data Const = I Int | BI Integer | Fl Double | Ch Char | Str String
6377 | B8 Bits8 | B16 Bits16 | B32 Bits32 | B64 Bits64
6478 | AType ArithTy | StrType
6579 | VoidType | Forgot
@@ -75,7 +89,7 @@ instance ReflConst Int where
7589instance ReflConst Integer where
7690 toConst = BI
7791
78−instance ReflConst Float where
92+instance ReflConst Double where
7993 toConst = Fl
8094
8195instance ReflConst Char where
@@ -116,22 +130,62 @@ data NameType =
116130
117131||| Types annotations for bound variables in different
118132||| binding contexts
119−data Binder a = Lam a
120− | Pi a a
121− | Let a a
122− | NLet a a
123− | Hole a
124− | GHole a
125− | Guess a a
126− | PVar a
127− | PVTy a
133+|||
134+||| @ tmTy the terms that can occur inside the binder, as type
135+||| annotations or bound values
136+data Binder : (tmTy : Type) -> Type where
137+ ||| Lambdas
138+ |||
139+ ||| @ ty the type of the argument
140+ Lam : (ty : a) -> Binder a
141+
142+ ||| Function types.
143+ |||
144+ ||| @ kind The kind of arrow. Only relevant when dealing with
145+ ||| uniqueness, so you can usually pretend that this
146+ ||| field doesn't exist. For ordinary functions, use the
147+ ||| type of types here.
148+ Pi : (ty, kind : a) -> Binder a
149+
150+ ||| A let binder
151+ |||
152+ ||| @ ty the type of the bound variable
153+ ||| @ val the bound value
154+ Let : (ty, val : a) -> Binder a
155+
156+ ||| A hole that can occur during elaboration, and must be filled
157+ |||
158+ ||| @ ty the type of the value that will eventually be put into the hole
159+ Hole : (ty : a) -> Binder a
160+
161+ ||| A hole that will later become a top-level metavariable
162+ GHole : (ty : a) -> Binder a
163+
164+ ||| A hole with a solution in it. Computationally inert.
165+ |||
166+ ||| @ ty the type of the value in the hole
167+ ||| @ val the value in the hole
168+ Guess : (ty, val : a) -> Binder a
169+
170+ ||| A pattern variable. These bindings surround the terms that make
171+ ||| up the left and right sides of pattern-matching definition
172+ ||| clauses.
173+ |||
174+ ||| @ ty the type of the pattern variable
175+ PVar : (ty : a) -> Binder a
176+
177+ ||| The type of a pattern binding. This is to `PVar` as `Pi` is to
178+ ||| `Lam`.
179+ |||
180+ ||| @ ty the type of the pattern variable
181+ PVTy : (ty : a) -> Binder a
182+
128183%name Binder b, b'
129184
130185instance Functor Binder where
131186 map f (Lam x) = Lam (f x)
132187 map f (Pi x k) = Pi (f x) (f k)
133188 map f (Let x y) = Let (f x) (f y)
134− map f (NLet x y) = NLet (f x) (f y)
135189 map f (Hole x) = Hole (f x)
136190 map f (GHole x) = GHole (f x)
137191 map f (Guess x y) = Guess (f x) (f y)
@@ -142,7 +196,6 @@ instance Foldable Binder where
142196 foldr f z (Lam x) = f x z
143197 foldr f z (Pi x k) = f x (f k z)
144198 foldr f z (Let x y) = f x (f y z)
145− foldr f z (NLet x y) = f x (f y z)
146199 foldr f z (Hole x) = f x z
147200 foldr f z (GHole x) = f x z
148201 foldr f z (Guess x y) = f x (f y z)
@@ -153,14 +206,13 @@ instance Traversable Binder where
153206 traverse f (Lam x) = [| Lam (f x) |]
154207 traverse f (Pi x k) = [| Pi (f x) (f k) |]
155208 traverse f (Let x y) = [| Let (f x) (f y) |]
156− traverse f (NLet x y) = [| NLet (f x) (f y) |]
157209 traverse f (Hole x) = [| Hole (f x) |]
158210 traverse f (GHole x) = [| GHole (f x) |]
159211 traverse f (Guess x y) = [| Guess (f x) (f y) |]
160212 traverse f (PVar x) = [| PVar (f x) |]
161213 traverse f (PVTy x) = [| PVTy (f x) |]
162214
163−||| Universes
215+||| The various universes involved in the uniqueness mechanism
164216data Universe = NullType | UniqueType | AllTypes
165217
166218||| Reflection of the well typed core language
@@ -175,14 +227,11 @@ data TT =
175227 App TT TT |
176228 ||| Embed a constant
177229 TConst Const |
178− ||| Argument projection; runtime only
179− Proj TT Int |
180230 ||| Erased terms
181231 Erased |
182− ||| Impossible terms
183− Impossible |
184232 ||| The type of types along (with universe constraints)
185233 TType TTUExp |
234+ ||| Alternative universes for dealing with uniqueness
186235 UType Universe
187236%name TT tm, tm'
188237
@@ -196,17 +245,12 @@ data Raw =
196245 RApp Raw Raw |
197246 ||| The type of types
198247 RType |
248+ ||| Alternative universes for dealing with uniqueness
199249 RUType Universe |
200− RForce Raw |
201250 ||| Embed a constant
202251 RConstant Const
203252%name Raw tm, tm'
204253
205−data SourceLocation : Type where
206− FileLoc : (filename : String) -> (start : (Int, Int)) -> (end : (Int, Int)) -> SourceLocation
207−
208−%name SourceLocation loc
209−
210254||| Error reports are a list of report parts
211255data ErrorReportPart =
212256 ||| A human-readable string
@@ -221,7 +265,7 @@ data ErrorReportPart =
221265 SubReport (List ErrorReportPart)
222266%name ErrorReportPart part, p
223267
224−||| A representation of Idris's tactics that can be returned from custom
268+||| A representation of Idris's old tactics that can be returned from custom
225269||| tactic implementations. Generate these using `applyTactic`.
226270data Tactic =
227271 ||| Try the first tactic and resort to the second one on failure
@@ -280,6 +324,7 @@ data Tactic =
280324 Fail (List ErrorReportPart) |
281325 ||| Attempt to fill the hole with source code information
282326 SourceFC
327+
283328%name Tactic tac, tac'
284329
285330
@@ -321,12 +366,12 @@ instance Quotable Int Raw where
321366 quotedTy = `(Int)
322367 quote x = RConstant (I x)
323368
324−instance Quotable Float TT where
325− quotedTy = `(Float)
369+instance Quotable Double TT where
370+ quotedTy = `(Double)
326371 quote x = TConst (Fl x)
327372
328−instance Quotable Float Raw where
329− quotedTy = `(Float)
373+instance Quotable Double Raw where
374+ quotedTy = `(Double)
330375 quote x = RConstant (Fl x)
331376
332377instance Quotable Char TT where
@@ -409,6 +454,21 @@ instance Quotable a Raw => Quotable (List a) Raw where
409454 quote [] = `(List.Nil {elem=~(quotedTy {a})})
410455 quote (x :: xs) = `(List.(::) {elem=~(quotedTy {a})} ~(quote x) ~(quote xs))
411456
457+instance Quotable SourceLocation TT where
458+ quotedTy = `(SourceLocation)
459+ quote (FileLoc fn (sl, sc) (el, ec)) =
460+ `(FileLoc ~(quote fn)
461+ (~(quote sl), ~(quote sc))
462+ (~(quote el), ~(quote ec)))
463+
464+instance Quotable SourceLocation Raw where
465+ quotedTy = `(SourceLocation)
466+ quote (FileLoc fn (sl, sc) (el, ec)) =
467+ `(FileLoc ~(quote {t=Raw} fn)
468+ (~(quote {t=Raw} sl), ~(quote {t=Raw} sc))
469+ (~(quote {t=Raw} el), ~(quote {t=Raw} ec)))
470+
471+
412472mutual
413473 instance Quotable TTName TT where
414474 quotedTy = `(TTName)
@@ -416,7 +476,6 @@ mutual
416476 quote (NS n xs) = `(NS ~(quote n) ~(quote xs))
417477 quote (MN x y) = `(MN ~(quote x) ~(quote y))
418478 quote (SN sn) = `(SN ~(assert_total $ quote sn))
419− quote NErased = `(NErased)
420479
421480 instance Quotable SpecialName TT where
422481 quotedTy = `(SpecialName)
@@ -425,7 +484,7 @@ mutual
425484 quote (InstanceN i ss) = `(InstanceN ~(quote i) ~(quote ss))
426485 quote (ParentN n s) = `(ParentN ~(quote n) ~(quote s))
427486 quote (MethodN n) = `(MethodN ~(quote n))
428− quote (CaseN n) = `(CaseN ~(quote n))
487+ quote (CaseN fc n) = `(CaseN ~(quote fc) ~(quote n))
429488 quote (ElimN n) = `(ElimN ~(quote n))
430489 quote (InstanceCtorN n) = `(InstanceCtorN ~(quote n))
431490 quote (MetaN parent meta) = `(MetaN ~(quote parent) ~(quote meta))
@@ -437,7 +496,6 @@ mutual
437496 quote (NS n xs) = `(NS ~(quote {t=Raw} n) ~(quote {t=Raw} xs))
438497 quote (MN x y) = `(MN ~(quote {t=Raw} x) ~(quote {t=Raw} y))
439498 quote (SN sn) = `(SN ~(assert_total $ quote sn))
440− quote NErased = `(NErased)
441499
442500 instance Quotable SpecialName Raw where
443501 quotedTy = `(SpecialName)
@@ -446,7 +504,7 @@ mutual
446504 quote (InstanceN i ss) = `(InstanceN ~(quote i) ~(quote ss))
447505 quote (ParentN n s) = `(ParentN ~(quote n) ~(quote s))
448506 quote (MethodN n) = `(MethodN ~(quote n))
449− quote (CaseN n) = `(CaseN ~(quote n))
507+ quote (CaseN fc n) = `(CaseN ~(quote fc) ~(quote n))
450508 quote (ElimN n) = `(ElimN ~(quote n))
451509 quote (InstanceCtorN n) = `(InstanceCtorN ~(quote n))
452510 quote (MetaN parent meta) = `(MetaN ~(quote parent) ~(quote meta))
@@ -483,12 +541,12 @@ instance Quotable Reflection.IntTy Raw where
483541instance Quotable ArithTy TT where
484542 quotedTy = `(ArithTy)
485543 quote (ATInt x) = `(ATInt ~(quote x))
486− quote ATFloat = `(ATFloat)
544+ quote ATDouble = `(ATDouble)
487545
488546instance Quotable ArithTy Raw where
489547 quotedTy = `(ArithTy)
490548 quote (ATInt x) = `(ATInt ~(quote {t=Raw} x))
491− quote ATFloat = `(ATFloat)
549+ quote ATDouble = `(ATDouble)
492550
493551instance Quotable Const TT where
494552 quotedTy = `(Const)
@@ -556,9 +614,7 @@ mutual
556614 quote (Bind n b tm) = `(Bind ~(quote n) ~(assert_total (quote b)) ~(quote tm))
557615 quote (App f x) = `(App ~(quote f) ~(quote x))
558616 quote (TConst c) = `(TConst ~(quote c))
559− quote (Proj tm x) = `(Proj ~(quote tm) ~(quote x))
560617 quote Erased = `(Erased)
561− quote Impossible = `(Impossible)
562618 quote (TType uexp) = `(TType ~(quote uexp))
563619 quote (UType u) = `(UType ~(quote u))
564620
@@ -569,8 +625,6 @@ mutual
569625 ~(assert_total (quote k)))
570626 quote (Let x y) = `(Let {a=TT} ~(assert_total (quote x))
571627 ~(assert_total (quote y)))
572− quote (NLet x y) = `(NLet {a=TT} ~(assert_total (quote x))
573− ~(assert_total (quote y)))
574628 quote (Hole x) = `(Hole {a=TT} ~(assert_total (quote x)))
575629 quote (GHole x) = `(GHole {a=TT} ~(assert_total (quote x)))
576630 quote (Guess x y) = `(Guess {a=TT} ~(assert_total (quote x))
@@ -585,14 +639,12 @@ mutual
585639 quoteRawTT (RApp tm tm') = `(RApp ~(quoteRawTT tm) ~(quoteRawTT tm'))
586640 quoteRawTT RType = `(RType)
587641 quoteRawTT (RUType u) = `(RUType ~(quote u))
588− quoteRawTT (RForce tm) = `(RForce ~(quoteRawTT tm))
589642 quoteRawTT (RConstant c) = `(RConstant ~(quote c))
590643
591644 quoteRawBinderTT : Binder Raw -> TT
592645 quoteRawBinderTT (Lam x) = `(Lam {a=Raw} ~(quoteRawTT x))
593646 quoteRawBinderTT (Pi x k) = `(Pi {a=Raw} ~(quoteRawTT x) ~(quoteRawTT k))
594647 quoteRawBinderTT (Let x y) = `(Let {a=Raw} ~(quoteRawTT x) ~(quoteRawTT y))
595− quoteRawBinderTT (NLet x y) = `(NLet {a=Raw} ~(quoteRawTT x) ~(quoteRawTT y))
596648 quoteRawBinderTT (Hole x) = `(Hole {a=Raw} ~(quoteRawTT x))
597649 quoteRawBinderTT (GHole x) = `(GHole {a=Raw} ~(quoteRawTT x))
598650 quoteRawBinderTT (Guess x y) = `(Guess {a=Raw} ~(quoteRawTT x) ~(quoteRawTT y))
@@ -614,14 +666,12 @@ mutual
614666 quoteRawRaw (RApp tm tm') = `(RApp ~(quoteRawRaw tm) ~(quoteRawRaw tm'))
615667 quoteRawRaw RType = `(RType)
616668 quoteRawRaw (RUType u) = `(RUType ~(quote u))
617− quoteRawRaw (RForce tm) = `(RForce ~(quoteRawRaw tm))
618669 quoteRawRaw (RConstant c) = `(RConstant ~(quote c))
619670
620671 quoteRawBinderRaw : Binder Raw -> Raw
621672 quoteRawBinderRaw (Lam x) = `(Lam {a=Raw} ~(quoteRawRaw x))
622673 quoteRawBinderRaw (Pi x k) = `(Pi {a=Raw} ~(quoteRawRaw x) ~(quoteRawRaw k))
623674 quoteRawBinderRaw (Let x y) = `(Let {a=Raw} ~(quoteRawRaw x) ~(quoteRawRaw y))
624− quoteRawBinderRaw (NLet x y) = `(NLet {a=Raw} ~(quoteRawRaw x) ~(quoteRawRaw y))
625675 quoteRawBinderRaw (Hole x) = `(Hole {a=Raw} ~(quoteRawRaw x))
626676 quoteRawBinderRaw (GHole x) = `(GHole {a=Raw} ~(quoteRawRaw x))
627677 quoteRawBinderRaw (Guess x y) = `(Guess {a=Raw} ~(quoteRawRaw x) ~(quoteRawRaw y))
@@ -673,18 +723,3 @@ instance Quotable Tactic TT where
673723 quote Skip = `(Skip)
674724 quote (Fail xs) = `(Fail ~(quote xs))
675725 quote SourceFC = `(SourceFC)
676−
677−
678−instance Quotable SourceLocation TT where
679− quotedTy = `(SourceLocation)
680− quote (FileLoc fn (sl, sc) (el, ec)) =
681− `(FileLoc ~(quote fn)
682− (~(quote sl), ~(quote sc))
683− (~(quote el), ~(quote ec)))
684−
685−instance Quotable SourceLocation Raw where
686− quotedTy = `(SourceLocation)
687− quote (FileLoc fn (sl, sc) (el, ec)) =
688− `(FileLoc ~(quote {t=Raw} fn)
689− (~(quote {t=Raw} sl), ~(quote {t=Raw} sc))
690− (~(quote {t=Raw} el), ~(quote {t=Raw} ec)))
libs/prelude/Language/Reflection/Elab.idr+204−157
@@ -34,11 +34,13 @@ data Plicity =
3434||| Function arguments
3535|||
3636||| These are the simplest representation of argument lists, and are
37−||| used for functions.
37+||| used for functions. Additionally, because a FunArg provides enough
38+||| information to build an application, a generic type lookup of a
39+||| top-level identifier will return its FunArgs, if applicable.
3840record FunArg where
3941 constructor MkFunArg
40− argName : TTName
41− argTy : Raw
42+ name : TTName
43+ type : Raw
4244 plicity : Plicity
4345 erasure : Erasure
4446
@@ -54,25 +56,29 @@ data TyConArg =
5456 TyConIndex FunArg
5557
5658||| A type declaration
57−data TyDecl : Type where
58− ||| A type declaration.
59− |||
60− ||| Each argument is in the scope of the names of previous
61− ||| arguments, and the return type is in the scope of all the
62− ||| argument names.
63− |||
64− ||| @ fn the name to be declared, fully-qualified
65− ||| @ args the arguments to the function
66− ||| @ ret the final return type
67− Declare : (fn : TTName) -> (args : List FunArg) -> (ret : Raw) -> TyDecl
59+record TyDecl where
60+ constructor Declare
61+
62+ ||| The name of the function being declared.
63+ name : TTName
64+
65+ ||| Each argument is in the scope of the names of previous arguments.
66+ arguments : List FunArg
67+
68+ ||| The return type is in the scope of all the argument names.
69+ returnType : Raw
70+
6871
6972||| A single pattern-matching clause
70−data FunClause : Type where
71− MkFunClause : (lhs, rhs : Raw) -> FunClause
73+data FunClause : Type -> Type where
74+ MkFunClause : (lhs, rhs : a) -> FunClause a
75+ MkImpossibleClause : (lhs : a) -> FunClause a
7276
7377||| A reflected function definition.
74−data FunDefn : Type where
75− DefineFun : TTName -> List FunClause -> FunDefn
78+record FunDefn a where
79+ constructor DefineFun
80+ name : TTName
81+ clauses : List (FunClause a)
7682
7783
7884data CtorArg = CtorParameter FunArg | CtorField FunArg
@@ -82,7 +88,7 @@ record Datatype where
8288 constructor MkDatatype
8389
8490 ||| The name of the type constructor
85− familyName : TTName
91+ name : TTName
8692
8793 ||| The arguments to the type constructor
8894 tyConArgs : List TyConArg
@@ -97,62 +103,63 @@ record Datatype where
97103abstract
98104data Elab : Type -> Type where
99105 -- obligatory control stuff
100− prim__PureElab : a -> Elab a
101− prim__BindElab : {a, b : Type} -> Elab a -> (a -> Elab b) -> Elab b
102−
103− prim__Try : {a : Type} -> Elab a -> Elab a -> Elab a
104− prim__Fail : {a : Type} -> List ErrorReportPart -> Elab a
106+ Prim__PureElab : a -> Elab a
107+ Prim__BindElab : {a, b : Type} -> Elab a -> (a -> Elab b) -> Elab b
105108
106− prim__Env : Elab (List (TTName, Binder TT))
107− prim__Goal : Elab (TTName, TT)
108− prim__Holes : Elab (List TTName)
109− prim__Guess : Elab (Maybe TT)
110− prim__LookupTy : TTName -> Elab (List (TTName, NameType, TT))
111− prim__LookupDatatype : TTName -> Elab (List Datatype)
109+ Prim__Try : {a : Type} -> Elab a -> Elab a -> Elab a
110+ Prim__Fail : {a : Type} -> List ErrorReportPart -> Elab a
112111
113− prim__Check : Raw -> Elab (TT, TT)
112+ Prim__Env : Elab (List (TTName, Binder TT))
113+ Prim__Goal : Elab (TTName, TT)
114+ Prim__Holes : Elab (List TTName)
115+ Prim__Guess : Elab TT
116+ Prim__LookupTy : TTName -> Elab (List (TTName, NameType, TT))
117+ Prim__LookupDatatype : TTName -> Elab (List Datatype)
118+ Prim__LookupFunDefn : TTName -> Elab (List (FunDefn TT))
119+ Prim__LookupArgs : TTName -> Elab (List (TTName, List FunArg, Raw))
114120
115− prim__SourceLocation : Elab SourceLocation
116− prim__Namespace : Elab (List String)
121+ Prim__Check : List (TTName, Binder TT) -> Raw -> Elab (TT, TT)
117122
118− prim__Forget : TT -> Elab Raw
123+ Prim__SourceLocation : Elab SourceLocation
124+ Prim__Namespace : Elab (List String)
119125
120− prim__Gensym : String -> Elab TTName
126+ Prim__Gensym : String -> Elab TTName
121127
122− prim__Solve : Elab ()
123− prim__Fill : Raw -> Elab ()
124− prim__Apply : Raw -> List (Bool, Int) -> Elab (List (TTName, TTName))
125− prim__MatchApply : Raw -> List (Bool, Int) -> Elab (List (TTName, TTName))
126− prim__Focus : TTName -> Elab ()
127− prim__Unfocus : TTName -> Elab ()
128− prim__Attack : Elab ()
128+ Prim__Solve : Elab ()
129+ Prim__Fill : Raw -> Elab ()
130+ Prim__Apply : Raw -> List Bool -> Elab (List (TTName, TTName))
131+ Prim__MatchApply : Raw -> List Bool -> Elab (List (TTName, TTName))
132+ Prim__Focus : TTName -> Elab ()
133+ Prim__Unfocus : TTName -> Elab ()
134+ Prim__Attack : Elab ()
129135
130− prim__Rewrite : Raw -> Elab ()
136+ Prim__Rewrite : Raw -> Elab ()
131137
132− prim__Claim : TTName -> Raw -> Elab ()
133− prim__Intro : Maybe TTName -> Elab ()
134− prim__Forall : TTName -> Raw -> Elab ()
135− prim__PatVar : TTName -> Elab ()
136− prim__PatBind : TTName -> Elab ()
137− prim__LetBind : TTName -> Raw -> Raw -> Elab ()
138+ Prim__Claim : TTName -> Raw -> Elab ()
139+ Prim__Intro : Maybe TTName -> Elab ()
140+ Prim__Forall : TTName -> Raw -> Elab ()
141+ Prim__PatVar : TTName -> Elab ()
142+ Prim__PatBind : TTName -> Elab ()
143+ Prim__LetBind : TTName -> Raw -> Raw -> Elab ()
138144
139− prim__Compute : Elab ()
140− prim__Normalise : (List (TTName, Binder TT)) -> TT -> Elab TT
141− prim__Whnf : TT -> Elab TT
142− prim__Converts : (List (TTName, Binder TT)) -> TT -> TT -> Elab ()
145+ Prim__Compute : Elab ()
146+ Prim__Normalise : (List (TTName, Binder TT)) -> TT -> Elab TT
147+ Prim__Whnf : TT -> Elab TT
148+ Prim__Converts : (List (TTName, Binder TT)) -> TT -> TT -> Elab ()
143149
144− prim__DeclareType : TyDecl -> Elab ()
145− prim__DefineFunction : FunDefn -> Elab ()
146− prim__AddInstance : TTName -> TTName -> Elab ()
150+ Prim__DeclareType : TyDecl -> Elab ()
151+ Prim__DefineFunction : FunDefn Raw -> Elab ()
152+ Prim__AddInstance : TTName -> TTName -> Elab ()
153+ Prim__IsTCName : TTName -> Elab Bool
147154
148− prim__ResolveTC : TTName -> Elab ()
149− prim__Search : Int -> List TTName -> Elab ()
150− prim__RecursiveElab : Raw -> Elab () -> Elab (TT, TT)
155+ Prim__ResolveTC : TTName -> Elab ()
156+ Prim__Search : Int -> List TTName -> Elab ()
157+ Prim__RecursiveElab : Raw -> Elab () -> Elab (TT, TT)
151158
152− prim__Fixity : String -> Elab Fixity
159+ Prim__Fixity : String -> Elab Fixity
153160
154− prim__Debug : {a : Type} -> List ErrorReportPart -> Elab a
155− prim__Metavar : TTName -> Elab ()
161+ Prim__Debug : {a : Type} -> List ErrorReportPart -> Elab a
162+ Prim__Metavar : TTName -> Elab ()
156163
157164-------------
158165-- Public API
@@ -160,49 +167,50 @@ data Elab : Type -> Type where
160167%access public
161168namespace Tactics
162169 instance Functor Elab where
163− map f t = prim__BindElab t (\x => prim__PureElab (f x))
170+ map f t = Prim__BindElab t (\x => Prim__PureElab (f x))
164171
165172 instance Applicative Elab where
166− pure x = prim__PureElab x
167− f <*> x = prim__BindElab f $ \g =>
168− prim__BindElab x $ \y =>
169− prim__PureElab $ g y
173+ pure x = Prim__PureElab x
174+ f <*> x = Prim__BindElab f $ \g =>
175+ Prim__BindElab x $ \y =>
176+ Prim__PureElab $ g y
170177
171178 ||| The Alternative instance on Elab represents left-biased error
172179 ||| handling. In other words, `t <|> t'` will run `t`, and if it
173180 ||| fails, roll back the elaboration state and run `t'`.
174181 instance Alternative Elab where
175− empty = prim__Fail [TextPart "empty"]
176− x <|> y = prim__Try x y
182+ empty = Prim__Fail [TextPart "empty"]
183+ x <|> y = Prim__Try x y
177184
178185 instance Monad Elab where
179− x >>= f = prim__BindElab x f
186+ x >>= f = Prim__BindElab x f
180187
181188 ||| Halt elaboration with an error
182189 fail : List ErrorReportPart -> Elab a
183− fail err = prim__Fail err
190+ fail err = Prim__Fail err
184191
185− ||| Look up the lexical binding at the focused hole
192+ ||| Look up the lexical binding at the focused hole. Fails if no holes are present.
186193 getEnv : Elab (List (TTName, Binder TT))
187− getEnv = prim__Env
194+ getEnv = Prim__Env
188195
189− ||| Get the name and type of the focused hole
196+ ||| Get the name and type of the focused hole. Fails if not holes are present.
190197 getGoal : Elab (TTName, TT)
191− getGoal = prim__Goal
198+ getGoal = Prim__Goal
192199
193− ||| Get the hole queue, in order
200+ ||| Get the hole queue, in order.
194201 getHoles : Elab (List TTName)
195− getHoles = prim__Holes
202+ getHoles = Prim__Holes
196203
197− ||| If the current hole contains a guess, return it
198− getGuess : Elab (Maybe TT)
199− getGuess = prim__Guess
204+ ||| If the current hole contains a guess, return it. Otherwise, fail.
205+ getGuess : Elab TT
206+ getGuess = Prim__Guess
200207
201− ||| Look up the types of every overloading of a name
208+ ||| Look up the types of every overloading of a name.
202209 lookupTy : TTName -> Elab (List (TTName, NameType, TT))
203− lookupTy n = prim__LookupTy n
210+ lookupTy n = Prim__LookupTy n
204211
205− ||| Get the type of a fully-qualified name
212+ ||| Get the type of a fully-qualified name. Fail if it doesn not
213+ ||| resolve uniquely.
206214 lookupTyExact : TTName -> Elab (TTName, NameType, TT)
207215 lookupTyExact n = case !(lookupTy n) of
208216 [res] => return res
@@ -210,31 +218,51 @@ namespace Tactics
210218 xs => fail [NamePart n, TextPart "is ambiguous."]
211219
212220 ||| Find the reflected representation of all datatypes whose names
213− ||| are overloadings of some name
221+ ||| are overloadings of some name.
214222 lookupDatatype : TTName -> Elab (List Datatype)
215− lookupDatatype n = prim__LookupDatatype n
223+ lookupDatatype n = Prim__LookupDatatype n
216224
217225 ||| Find the reflected representation of a datatype, given its
218− ||| fully-qualified name.
226+ ||| fully-qualified name. Fail if the name does not uniquely resolve
227+ ||| to a datatype.
219228 lookupDatatypeExact : TTName -> Elab Datatype
220229 lookupDatatypeExact n = case !(lookupDatatype n) of
221230 [res] => return res
222231 [] => fail [TextPart "No datatype named", NamePart n]
223232 xs => fail [TextPart "More than one datatype named", NamePart n]
224233
225− ||| Attempt to type-check a term, getting back itself and its type
226− check : (tm : Raw) -> Elab (TT, TT)
227− check tm = prim__Check tm
234+ ||| Find the reflected function definition of all functions whose names
235+ ||| are overloadings of some name.
236+ lookupFunDefn : TTName -> Elab (List (FunDefn TT))
237+ lookupFunDefn n = Prim__LookupFunDefn n
238+
239+ ||| Find the reflected function definition of a function, given its
240+ ||| fully-qualified name. Fail if the name does not uniquely resolve
241+ ||| to a function.
242+ lookupFunDefnExact : TTName -> Elab (FunDefn TT)
243+ lookupFunDefnExact n = case !(lookupFunDefn n) of
244+ [res] => return res
245+ [] => fail [TextPart "No function named", NamePart n]
246+ xs => fail [TextPart "More than one function named", NamePart n]
247+
248+ ||| Get the argument specification for each overloading of a name.
249+ lookupArgs : TTName -> Elab (List (TTName, List FunArg, Raw))
250+ lookupArgs n = Prim__LookupArgs n
228251
229− ||| Convert a type-annotated reflected term to its untyped
230− ||| equivalent
231− forgetTypes : TT -> Elab Raw
232− forgetTypes tt = prim__Forget tt
252+ ||| Get the argument specification for a name. Fail if the name does
253+ ||| not uniquely resolve.
254+ lookupArgsExact : TTName -> Elab (TTName, List FunArg, Raw)
255+ lookupArgsExact n = case !(lookupArgs n) of
256+ [res] => return res
257+ [] => fail [NamePart n, TextPart "is not defined."]
258+ xs => fail [NamePart n, TextPart "is ambiguous."]
233259
234− ||| Get the goal type as a Raw term
235− goalType : Elab Raw
236− goalType = do g <- getGoal
237− forgetTypes (snd g)
260+ ||| Attempt to type-check a term, getting back itself and its type.
261+ |||
262+ ||| @ env the environment within which to check the type
263+ ||| @ tm the term to check
264+ check : (env : List (TTName, Binder TT)) -> (tm : Raw) -> Elab (TT, TT)
265+ check env tm = Prim__Check env tm
238266
239267
240268 ||| Generate a unique name based on some hint.
@@ -242,23 +270,22 @@ namespace Tactics
242270 ||| **NB**: the generated name is unique _for this run of the
243271 ||| elaborator_. Do not assume that they are globally unique.
244272 gensym : (hint : String) -> Elab TTName
245− gensym hint = prim__Gensym hint
273+ gensym hint = Prim__Gensym hint
246274
247275 ||| Substitute a guess into a hole.
248276 solve : Elab ()
249− solve = prim__Solve
277+ solve = Prim__Solve
250278
251− ||| Place a term into a hole, unifying its type
279+ ||| Place a term into a hole, unifying its type. Fails if the focus
280+ ||| is not a hole.
252281 fill : Raw -> Elab ()
253− fill tm = prim__Fill tm
282+ fill tm = Prim__Fill tm
254283
255284 ||| Attempt to apply an operator to fill the current hole,
256285 ||| potentially solving arguments by unification.
257286 |||
258− ||| The return value is a list of pairs of names, one for each input
259− ||| argument. The first projection of these pairs is the original
260− ||| name of the argument, from the type declaration, and the second
261− ||| projection is the hole into which it is placed.
287+ ||| The return value is the list of holes established for the
288+ ||| arguments to the function.
262289 |||
263290 ||| Note that not all of the returned hole names still exist, as
264291 ||| they may have been solved.
@@ -267,20 +294,15 @@ namespace Tactics
267294 |||
268295 ||| @ argSpec instructions for finding the arguments to the term,
269296 ||| where the Boolean states whether or not to attempt to solve
270− ||| the argument and the Int gives the priority in which to do
271− ||| so
272− apply : (op : Raw) ->
273− (argSpec : List (Bool, Int)) ->
274− Elab (List (TTName, TTName))
275− apply tm argSpec = prim__Apply tm argSpec
297+ ||| the argument by unification.
298+ apply : (op : Raw) -> (argSpec : List Bool) -> Elab (List TTName)
299+ apply tm argSpec = map snd <$> Prim__Apply tm argSpec
276300
277301 ||| Attempt to apply an operator to fill the current hole,
278− ||| potentially solving arugments by matching.
302+ ||| potentially solving arguments by matching.
279303 |||
280− ||| The return value is a list of pairs of names, one for each input
281− ||| argument. The first projection of these pairs is the original
282− ||| name of the argument, from the type declaration, and the second
283− ||| projection is the hole into which it is placed.
304+ ||| The return value is the list of holes established for the
305+ ||| arguments to the function.
284306 |||
285307 ||| Note that not all of the returned hole names still exist, as
286308 ||| they may have been solved.
@@ -289,39 +311,41 @@ namespace Tactics
289311 |||
290312 ||| @ argSpec instructions for finding the arguments to the term,
291313 ||| where the Boolean states whether or not to attempt to solve
292− ||| the argument and the Int gives the priority in which to do
293− ||| so
294− matchApply : (op : Raw) ->
295− (argSpec : List (Bool, Int)) ->
296− Elab (List (TTName, TTName))
297− matchApply tm argSpec = prim__Apply tm argSpec
314+ ||| the argument by matching.
315+
316+ matchApply : (op : Raw) -> (argSpec : List Bool) -> Elab (List TTName)
317+ matchApply tm argSpec = map snd <$> Prim__Apply tm argSpec
298318
299− ||| Move the focus to the specified hole
319+ ||| Move the focus to the specified hole. Fails if the hole does not
320+ ||| exist.
300321 |||
301322 ||| @ hole the hole to focus on
302323 focus : (hole : TTName) -> Elab ()
303− focus hole = prim__Focus hole
324+ focus hole = Prim__Focus hole
304325
305326 ||| Send the currently-focused hole to the end of the hole queue and
306327 ||| focus on the next hole.
307328 unfocus : TTName -> Elab ()
308− unfocus hole = prim__Unfocus hole
329+ unfocus hole = Prim__Unfocus hole
309330
310− ||| Convert a hole to make it suitable for bindings.
331+ ||| Convert a hole to make it suitable for bindings - that is,
332+ ||| transform it such that it has the form `?h : t . h` as opposed to
333+ ||| `?h : t . f h`.
311334 |||
312335 ||| The binding tactics require that a hole be directly under its
313336 ||| binding, or else the scopes of the generated terms won't make
314337 ||| sense. This tactic creates a new hole of the proper form, and
315338 ||| points the old hole at it.
316339 attack : Elab ()
317− attack = prim__Attack
340+ attack = Prim__Attack
318341
319342 ||| Introduce a new hole with a specified name and type.
320343 |||
321344 ||| The new hole will be focused, and the previously-focused hole
322− ||| will be immediately after it in the hole queue.
345+ ||| will be immediately after it in the hole queue. Because this
346+ ||| tactic introduces a new binding, you may need to `attack` first.
323347 claim : TTName -> Raw -> Elab ()
324− claim n ty = prim__Claim n ty
348+ claim n ty = Prim__Claim n ty
325349
326350 ||| Introduce a lambda binding around the current hole and focus on
327351 ||| the body. Requires that the hole be in binding form (use
@@ -329,50 +353,63 @@ namespace Tactics
329353 |||
330354 ||| @ n the name to use for the argument
331355 intro : (n : TTName) -> Elab ()
332− intro n = prim__Intro (Just n)
356+ intro n = Prim__Intro (Just n)
333357
334358 ||| Introduce a lambda binding around the current hole and focus on
335− ||| the body, using the name provided by the type of the hole.
359+ ||| the body, using the name provided by the type of the
360+ ||| hole.
361+ |||
362+ ||| Requires that the hole be immediately under its binder (use
363+ ||| `attack` if it might not be).
336364 intro' : Elab ()
337− intro' = prim__Intro Nothing
365+ intro' = Prim__Intro Nothing
338366
339367 ||| Introduce a dependent function type binding into the current hole,
340368 ||| and focus on the body.
369+ |||
370+ ||| Requires that the hole be immediately under its binder (use
371+ ||| `attack` if it might not be).
341372 forall : TTName -> Raw -> Elab ()
342− forall n ty = prim__Forall n ty
373+ forall n ty = Prim__Forall n ty
343374
344375 ||| Convert a hole into a pattern variable.
345376 patvar : TTName -> Elab ()
346− patvar n = prim__PatVar n
377+ patvar n = Prim__PatVar n
347378
348379 ||| Introduce a new pattern binding.
380+ |||
381+ ||| Requires that the hole be immediately under its binder (use
382+ ||| `attack` if it might not be).
349383 patbind : TTName -> Elab ()
350− patbind n = prim__PatBind n
384+ patbind n = Prim__PatBind n
351385
352− ||| Introduce a new let binding
386+ ||| Introduce a new let binding.
387+ |||
388+ ||| Requires that the hole be immediately under its binder (use
389+ ||| `attack` if it might not be).
353390 |||
354391 ||| @ n the name to let bind
355392 ||| @ ty the type of the term to be let-bound
356393 ||| @ tm the term to be bound
357394 letbind : (n : TTName) -> (ty, tm : Raw) -> Elab ()
358− letbind n ty tm = prim__LetBind n ty tm
395+ letbind n ty tm = Prim__LetBind n ty tm
359396
360397 ||| Normalise the goal.
361398 compute : Elab ()
362− compute = prim__Compute
399+ compute = Prim__Compute
363400
364401 ||| Normalise a term in some lexical environment
365402 |||
366403 ||| @ env the environment in which to compute (get one of these from `getEnv`)
367404 ||| @ term the term to normalise
368405 normalise : (env : List (TTName, Binder TT)) -> (term : TT) -> Elab TT
369− normalise env term = prim__Normalise env term
406+ normalise env term = Prim__Normalise env term
370407
371408 ||| Reduce a closed term to weak-head normal form
372409 |||
373410 ||| @ term the term to reduce
374411 whnf : (term : TT) -> Elab TT
375− whnf term = prim__Whnf term
412+ whnf term = Prim__Whnf term
376413
377414 ||| Check that two terms are convertable in the current context and
378415 ||| in some environment.
@@ -381,7 +418,7 @@ namespace Tactics
381418 ||| @ term1 the first term to convert
382419 ||| @ term2 the second term to convert
383420 convertsInEnv : (env : List (TTName, Binder TT)) -> (term1, term2 : TT) -> Elab ()
384− convertsInEnv env term1 term2 = prim__Converts env term1 term2
421+ convertsInEnv env term1 term2 = Prim__Converts env term1 term2
385422
386423 ||| Check that two terms are convertable in the current context and environment
387424 |||
@@ -392,7 +429,7 @@ namespace Tactics
392429
393430 ||| Find the source context for the elaboration script
394431 getSourceLocation : Elab SourceLocation
395− getSourceLocation = prim__SourceLocation
432+ getSourceLocation = Prim__SourceLocation
396433
397434 ||| Attempt to solve the current goal with the source code location
398435 sourceLocation : Elab ()
@@ -406,7 +443,7 @@ namespace Tactics
406443 ||| The namespace is represented as a reverse-order list of strings,
407444 ||| just as in the representation of names.
408445 currentNamespace : Elab (List String)
409− currentNamespace = prim__Namespace
446+ currentNamespace = Prim__Namespace
410447
411448 ||| Attempt to rewrite the goal using an equality.
412449 |||
@@ -414,43 +451,53 @@ namespace Tactics
414451 ||| constructs a context for `replace` using them. In some cases,
415452 ||| this is not possible, and `replace` must be called manually with
416453 ||| an appropriate context.
454+ |||
455+ ||| Because this tactic internally introduces a `let` binding, it
456+ ||| requires that the hole be immediately under its binder (use
457+ ||| `attack` if it might not be).
417458 rewriteWith : Raw -> Elab ()
418− rewriteWith rule = prim__Rewrite rule
459+ rewriteWith rule = Prim__Rewrite rule
419460
420461 ||| Add a type declaration to the global context.
421462 declareType : TyDecl -> Elab ()
422− declareType decl = prim__DeclareType decl
463+ declareType decl = Prim__DeclareType decl
423464
424465 ||| Define a function in the global context. The function must have
425466 ||| already been declared, either in ordinary Idris code or using
426467 ||| `declareType`.
427− defineFunction : FunDefn -> Elab ()
428− defineFunction defun = prim__DefineFunction defun
468+ defineFunction : FunDefn Raw -> Elab ()
469+ defineFunction defun = Prim__DefineFunction defun
429470
430− ||| Register a new instance for type class resolution
471+ ||| Register a new instance for type class resolution.
431472 |||
432473 ||| @ className the name of the class for which an instance is being registered
433474 ||| @ instName the name of the definition to use in instance search
434475 addInstance : (className, instName : TTName) -> Elab ()
435− addInstance className instName = prim__AddInstance className instName
476+ addInstance className instName = Prim__AddInstance className instName
477+
478+ ||| Determine whether a name denotes a class.
479+ |||
480+ ||| @ name a name that might denote a class.
481+ isTCName : (name : TTName) -> Elab Bool
482+ isTCName name = Prim__IsTCName name
436483
437484 ||| Attempt to solve the current goal with a type class dictionary
438485 |||
439486 ||| @ fn the name of the definition being elaborated (to prevent Idris
440487 ||| from looping)
441488 resolveTC : (fn : TTName) -> Elab ()
442− resolveTC fn = prim__ResolveTC fn
489+ resolveTC fn = Prim__ResolveTC fn
443490
444491 ||| Use Idris's internal proof search.
445492 search : Elab ()
446− search = prim__Search 100 []
493+ search = Prim__Search 100 []
447494
448495 ||| Use Idris's internal proof search, with more control.
449496 |||
450497 ||| @ depth the search depth
451498 ||| @ hints additional names to try
452499 search' : (depth : Int) -> (hints : List TTName) -> Elab ()
453− search' depth hints = prim__Search depth hints
500+ search' depth hints = Prim__Search depth hints
454501
455502 ||| Look up the declared fixity for an operator.
456503 |||
@@ -459,14 +506,14 @@ namespace Tactics
459506 |||
460507 ||| @ operator the operator string to look up
461508 operatorFixity : (operator : String) -> Elab Fixity
462− operatorFixity operator = prim__Fixity operator
509+ operatorFixity operator = Prim__Fixity operator
463510
464511 ||| Halt elaboration, dumping the internal state for inspection.
465512 |||
466513 ||| This is intended for elaboration script developers, not for
467514 ||| end-users. Use `fail` for final scripts.
468515 debug : Elab a
469− debug = prim__Debug []
516+ debug = Prim__Debug []
470517
471518 ||| Halt elaboration, dumping the internal state and displaying a
472519 ||| message.
@@ -476,17 +523,17 @@ namespace Tactics
476523 |||
477524 ||| @ msg the message to display
478525 debugMessage : (msg : List ErrorReportPart) -> Elab a
479− debugMessage msg = prim__Debug msg
526+ debugMessage msg = Prim__Debug msg
480527
481528 ||| Create a new top-level metavariable to solve the current hole.
482529 |||
483530 ||| @ name the name for the top-level variable
484531 metavar : (name : TTName) -> Elab ()
485− metavar name = prim__Metavar name
532+ metavar name = Prim__Metavar name
486533
487534 ||| Recursively invoke the reflected elaborator with some goal.
488535 |||
489536 ||| The result is the final term and its type.
490537 runElab : Raw -> Elab () -> Elab (TT, TT)
491− runElab goal script = prim__RecursiveElab goal script
538+ runElab goal script = Prim__RecursiveElab goal script
492539
libs/prelude/Prelude.idr+10
@@ -37,6 +37,10 @@ import public Language.Reflection.Errors
3737%default total
3838
3939-- Things that can't be elsewhere for import cycle reasons
40+-- See comment after declaration of void in Builtins.idr
41+-- for explanation of this definition's location
42+%runElab (defineFunction $ DefineFun `{void} [])
43+
4044decAsBool : Dec p -> Bool
4145decAsBool (Yes _) = True
4246decAsBool (No _) = False
@@ -203,6 +207,12 @@ instance Enum Int where
203207 go [] = []
204208 go (x :: xs) = n + (cast x * inc) :: go xs
205209
210+instance Enum Char where
211+ toNat c = toNat (ord c)
212+ fromNat n = chr (fromNat n)
213+
214+ pred c = fromNat (pred (toNat c))
215+
206216syntax "[" [start] ".." [end] "]"
207217 = enumFromTo start end
208218syntax "[" [start] "," [next] ".." [end] "]"
libs/prelude/Prelude/Classes.idr+6−6
@@ -37,7 +37,7 @@ instance Eq Int where
3737instance Eq Integer where
3838 (==) = boolOp prim__eqBigInt
3939
40−instance Eq Float where
40+instance Eq Double where
4141 (==) = boolOp prim__eqFloat
4242
4343instance Eq Char where
@@ -118,7 +118,7 @@ instance Ord Integer where
118118 GT
119119
120120
121−instance Ord Float where
121+instance Ord Double where
122122 compare x y = if (x == y) then EQ else
123123 if (boolOp prim__sltFloat x y) then LT else
124124 GT
@@ -170,7 +170,7 @@ instance Num Int where
170170 fromInteger = prim__truncBigInt_Int
171171
172172
173−instance Num Float where
173+instance Num Double where
174174 (+) = prim__addFloat
175175 (*) = prim__mulFloat
176176
@@ -215,7 +215,7 @@ instance Neg Int where
215215 (-) = prim__subInt
216216 abs x = if x < (prim__truncBigInt_Int 0) then -x else x
217217
218−instance Neg Float where
218+instance Neg Double where
219219 negate x = prim__negFloat x
220220 (-) = prim__subFloat
221221 abs x = if x < (prim__toFloatBigInt 0) then -x else x
@@ -306,8 +306,8 @@ instance MaxBound Bits64 where
306306
307307-- ------------------------------------------------------------- [ Fractionals ]
308308
309−||| Fractional division of two Floats.
310−(/) : Float -> Float -> Float
309+||| Fractional division of two Doubles.
310+(/) : Double -> Double -> Double
311311(/) = prim__divFloat
312312
313313
libs/prelude/Prelude/Either.idr+7−3
@@ -9,11 +9,15 @@ import Prelude.Maybe
99import Prelude.List
1010
1111||| A sum type
12−%elim data Either a b =
12+%elim data Either : (a, b : Type) -> Type where
1313 ||| One possibility of the sum, conventionally used to represent errors
14− Left a |
14+ Left : (l : a) -> Either a b
1515 ||| The other possibility, conventionally used to represent success
16− Right b
16+ Right : (r : b) -> Either a b
17+
18+-- Usage hints for erasure analysis
19+%used Left l
20+%used Right r
1721
1822--------------------------------------------------------------------------------
1923-- Syntactic tests
libs/prelude/Prelude/File.idr+114−49
@@ -10,14 +10,43 @@ import Prelude.Cast
1010import Prelude.Bool
1111import Prelude.Basics
1212import Prelude.Classes
13−import Prelude.Monad
13+import Prelude.Either
14+import Prelude.Show
1415import IO
1516
1617%access public
1718
1819||| A file handle
1920abstract
20−data File = FHandle Ptr
21+data File : Type where
22+ FHandle : (p : Ptr) -> File
23+
24+-- Usage hints for erasure analysis
25+%used FHandle p
26+
27+||| An error from a file operation
28+-- This is built in idris_mkFileError() in rts/idris_stdfgn.c. Make sure
29+-- the values correspond!
30+data FileError = FileReadError
31+ | FileWriteError
32+ | FileNotFound
33+ | PermissionDenied
34+ | GenericFileError Int -- errno
35+
36+private
37+strError : Int -> String
38+strError err = unsafePerformIO -- yeah, yeah...
39+ (foreign FFI_C "idris_showerror" (Int -> IO String) err)
40+
41+getFileError : IO FileError
42+getFileError = do MkRaw err <- foreign FFI_C "idris_mkFileError"
43+ (Ptr -> IO (Raw FileError)) prim__vm
44+ return err
45+
46+instance Show FileError where
47+ show FileNotFound = "File Not Found"
48+ show PermissionDenied = "Permission Denied"
49+ show (GenericFileError errno) = strError errno
2150
2251||| Standard input
2352stdin : File
@@ -31,6 +60,13 @@ stdout = FHandle prim__stdout
3160stderr : File
3261stderr = FHandle prim__stderr
3362
63+do_ferror : Ptr -> IO Int
64+do_ferror h = foreign FFI_C "fileError" (Ptr -> IO Int) h
65+
66+ferror : File -> IO Bool
67+ferror (FHandle h) = do err <- do_ferror h
68+ return (not (err == 0))
69+
3470||| Call the RTS's file opening function
3571do_fopen : String -> String -> IO Ptr
3672do_fopen f m
@@ -39,12 +75,14 @@ do_fopen f m
3975||| Open a file
4076||| @ f the filename
4177||| @ m the mode as a String (`"r"`, `"w"`, or `"r+"`)
42−fopen : (f : String) -> (m : String) -> IO File
78+fopen : (f : String) -> (m : String) -> IO (Either FileError File)
4379fopen f m = do h <- do_fopen f m
44− return (FHandle h)
80+ if !(nullPtr h)
81+ then do err <- getFileError
82+ return (Left err)
83+ else return (Right (FHandle h))
4584
4685||| Check whether a file handle is actually a null pointer
47−partial
4886validFile : File -> IO Bool
4987validFile (FHandle h) = do x <- nullPtr h
5088 return (not x)
@@ -54,34 +92,27 @@ data Mode = Read | Write | ReadWrite
5492
5593||| Open a file
5694||| @ f the filename
57−||| @ m the mode
58−partial
59−openFile : (f : String) -> (m : Mode) -> IO File
95+||| @ m the mode; either Read, Write, or ReadWrite
96+openFile : (f : String) -> (m : Mode) -> IO (Either FileError File)
6097openFile f m = fopen f (modeStr m) where
6198 modeStr Read = "r"
6299 modeStr Write = "w"
63100 modeStr ReadWrite = "r+"
64101
65−partial
66102do_fclose : Ptr -> IO ()
67103do_fclose h = foreign FFI_C "fileClose" (Ptr -> IO ()) h
68104
69−partial
70105closeFile : File -> IO ()
71106closeFile (FHandle h) = do_fclose h
72107
73−partial
74108do_fread : Ptr -> IO' l String
75109do_fread h = prim_fread h
76110
77−fgetc : File -> IO Char
78−fgetc (FHandle h) = return (cast !(foreign FFI_C "fgetc" (Ptr -> IO Int) h))
79−
80−fgetc' : File -> IO (Maybe Char)
81−fgetc' (FHandle h)
82− = do x <- foreign FFI_C "fgetc" (Ptr -> IO Int) h
83− if (x < 0) then return Nothing
84− else return (Just (cast x))
111+fgetc : File -> IO (Either FileError Char)
112+fgetc (FHandle h) = do let c = cast !(foreign FFI_C "fgetc" (Ptr -> IO Int) h)
113+ if !(ferror (FHandle h))
114+ then return (Left FileReadError)
115+ else return (Right c)
85116
86117fflush : File -> IO ()
87118fflush (FHandle h) = foreign FFI_C "fflush" (Ptr -> IO ()) h
@@ -89,9 +120,12 @@ fflush (FHandle h) = foreign FFI_C "fflush" (Ptr -> IO ()) h
89120do_popen : String -> String -> IO Ptr
90121do_popen f m = foreign FFI_C "do_popen" (String -> String -> IO Ptr) f m
91122
92−popen : String -> Mode -> IO File
123+popen : String -> Mode -> IO (Either FileError File)
93124popen f m = do ptr <- do_popen f (modeStr m)
94− return (FHandle ptr)
125+ if !(nullPtr ptr)
126+ then do err <- getFileError
127+ return (Left err)
128+ else return (Right (FHandle ptr))
95129 where
96130 modeStr Read = "r"
97131 modeStr Write = "w"
@@ -103,54 +137,85 @@ pclose (FHandle h) = foreign FFI_C "pclose" (Ptr -> IO ()) h
103137-- mkForeign (FFun "idris_readStr" [FPtr, FPtr] (FAny String))
104138-- prim__vm h
105139
106−partial
107−fread : File -> IO' l String
108−fread (FHandle h) = do_fread h
140+fread : File -> IO (Either FileError String)
141+fread (FHandle h) = do str <- do_fread h
142+ if !(ferror (FHandle h))
143+ then return (Left FileReadError)
144+ else return (Right str)
145+
146+||| Read a line from a file
147+||| @h a file handle which must be open for reading
148+fGetLine : (h : File) -> IO (Either FileError String)
149+fGetLine = fread
150+
151+%deprecate fread "Use fGetLine instead"
152+
153+do_fwrite : Ptr -> String -> IO (Either FileError ())
154+do_fwrite h s = do res <- prim_fwrite h s
155+ if (res /= 0)
156+ then do errno <- getErrno
157+ if errno == 0
158+ then return (Left FileWriteError)
159+ else do err <- getFileError
160+ return (Left err)
161+ else return (Right ())
162+
163+fwrite : File -> String -> IO (Either FileError ())
164+fwrite (FHandle h) s = do_fwrite h s
109165
110−partial
111−do_fwrite : Ptr -> String -> IO ()
112−do_fwrite h s = do prim_fwrite h s
113− return ()
166+||| Write a line to a file
167+||| @h a file handle which must be open for writing
168+||| @str the line to write to the file
169+fPutStr : (h : File) -> (str : String) -> IO (Either FileError ())
170+fPutStr (FHandle h) s = do_fwrite h s
114171
115−partial
116−fwrite : File -> String -> IO ()
117−fwrite (FHandle h) s = do_fwrite h s
172+fPutStrLn : File -> String -> IO (Either FileError ())
173+fPutStrLn (FHandle h) s = do_fwrite h (s ++ "\n")
174+
175+%deprecate fwrite "Use fPutStr instead"
118176
119−partial
120177do_feof : Ptr -> IO Int
121178do_feof h = foreign FFI_C "fileEOF" (Ptr -> IO Int) h
122179
123180||| Check if a file handle has reached the end
124−feof : File -> IO Bool
125−feof (FHandle h) = do eof <- do_feof h
181+fEOF : File -> IO Bool
182+fEOF (FHandle h) = do eof <- do_feof h
126183 return (not (eof == 0))
127184
128−partial
129−do_ferror : Ptr -> IO Int
130−do_ferror h = foreign FFI_C "fileError" (Ptr -> IO Int) h
185+||| Check if a file handle has reached the end
186+feof : File -> IO Bool
187+feof = fEOF
131188
132−ferror : File -> IO Bool
133−ferror (FHandle h) = do err <- do_ferror h
134− return (not (err == 0))
189+%deprecate feof "Use fEOF instead"
135190
136191fpoll : File -> IO Bool
137192fpoll (FHandle h) = do p <- foreign FFI_C "fpoll" (Ptr -> IO Int) h
138193 return (p > 0)
139194
140195||| Read the contents of a file into a string
141−partial -- no error checking!
142−readFile : String -> IO String
143−readFile fn = do h <- openFile fn Read
196+partial -- might be reading something infinitely long like /dev/null ...
197+covering
198+readFile : String -> IO (Either FileError String)
199+readFile fn = do Right h <- openFile fn Read
200+ | Left err => return (Left err)
144201 c <- readFile' h ""
145202 closeFile h
146203 return c
147204 where
148205 partial
149− readFile' : File -> String -> IO String
206+ readFile' : File -> String -> IO (Either FileError String)
150207 readFile' h contents =
151− do x <- feof h
152− if not x then do l <- fread h
208+ do x <- fEOF h
209+ if not x then do Right l <- fGetLine h
210+ | Left err => return (Left err)
153211 readFile' h (contents ++ l)
154− else return contents
155−
156−
212+ else return (Right contents)
213+
214+||| Write a string to a file
215+writeFile : (filepath : String) -> (contents : String) ->
216+ IO (Either FileError ())
217+writeFile fn contents = do
218+ Right h <- openFile fn Write | Left err => return (Left err)
219+ Right () <- fPutStr h contents | Left err => return (Left err)
220+ closeFile h
221+ return (Right ())
libs/prelude/Prelude/Functor.idr+10−8
@@ -2,19 +2,21 @@ module Prelude.Functor
22
33import Prelude.Basics
44
5−||| Functors
6−||| @ f the action of the functor on objects
5+||| Functors allow a uniform action over a parameterised type.
6+||| @ f a parameterised type
77class Functor (f : Type -> Type) where
8− ||| The action of the functor on morphisms
9− ||| @ f the functor
10− ||| @ m the morphism
8+ ||| Apply a function across everything of type 'a' in a
9+ ||| parameterised type
10+ ||| @ f the parameterised type
11+ ||| @ m the function to apply
1112 map : (m : a -> b) -> f a -> f b
1213
1314infixl 4 <$>
1415
15−||| An infix alias for `map`: the action of a functor on morphisms.
16−||| @ f the functor
17−||| @ m the morphism
16+||| An infix alias for `map`, applying a function across everything of
17+||| type 'a' in a parameterised type
18+||| @ f the parameterised type
19+||| @ m the function to apply
1820(<$>) : Functor f => (m : a -> b) -> f a -> f b
1921m <$> x = map m x
2022
libs/prelude/Prelude/Interactive.idr+43−16
@@ -17,6 +17,7 @@ import Prelude.Show
1717import Prelude.Cast
1818import Prelude.Maybe
1919import Prelude.Functor
20+import Prelude.Either
2021import Prelude.Monad
2122import IO
2223
@@ -24,33 +25,58 @@ import IO
2425
2526---- some basic io
2627
28+||| Output a string to stdout without a trailing newline, for any FFI
29+||| descriptor
30+putStr' : String -> IO' ffi ()
31+putStr' x = do prim_write x
32+ return ()
33+
2734||| Output a string to stdout without a trailing newline
28−putStr : String -> IO' ffi ()
29−putStr x = do prim_write x
30− return ()
35+putStr : String -> IO ()
36+putStr = putStr'
37+
38+||| Output a string to stdout with a trailing newline, for any FFI
39+||| descriptor
40+putStrLn' : String -> IO' ffi ()
41+putStrLn' x = putStr' (x ++ "\n")
3142
3243||| Output a string to stdout with a trailing newline
33−putStrLn : String -> IO' ffi ()
34−putStrLn x = putStr (x ++ "\n")
44+putStrLn : String -> IO ()
45+putStrLn = putStrLn'
46+
47+||| Output something showable to stdout, without a trailing newline, for any FFI
48+||| descriptor
49+print' : Show a => a -> IO' ffi ()
50+print' x = putStr' (show x)
3551
3652||| Output something showable to stdout, without a trailing newline
37−print : Show a => a -> IO' ffi ()
38−print x = putStr (show x)
53+print : Show a => a -> IO ()
54+print = print'
3955
40−||| Output something showable to stdout, with a trailing newline
41−printLn : Show a => a -> IO' ffi ()
42−printLn x = putStrLn (show x)
56+||| Output something showable to stdout, with a trailing newline, for any FFI
57+||| descriptor
58+printLn' : Show a => a -> IO' ffi ()
59+printLn' x = putStrLn' (show x)
4360
44−||| Read one line of input from stdin, without the trailing newline
45−getLine : IO' ffi String
46−getLine = do x <- prim_read
47− return (reverse (trimNL (reverse x)))
61+||| Output something showable to stdout, with a trailing newline
62+printLn : Show a => a -> IO ()
63+printLn = printLn'
64+
65+||| Read one line of input from stdin, without the trailing newline, for any FFI
66+||| descriptor
67+getLine' : IO' ffi String
68+getLine' = do x <- prim_read
69+ return (reverse (trimNL (reverse x)))
4870 where trimNL : String -> String
4971 trimNL str with (strM str)
5072 trimNL "" | StrNil = ""
5173 trimNL (strCons '\n' xs) | StrCons _ _ = xs
5274 trimNL (strCons x xs) | StrCons _ _ = strCons x xs
5375
76+||| Read one line of input from stdin, without the trailing newline
77+getLine : IO String
78+getLine = getLine'
79+
5480||| Write a single character to stdout
5581putChar : Char -> IO ()
5682putChar c = foreign FFI_C "putchar" (Int -> IO ()) (cast c)
@@ -95,9 +121,10 @@ processHandle : File ->
95121 (onEOF : a -> String) ->
96122 IO ()
97123processHandle h acc onRead onEOF
98− = if !(feof h)
124+ = if !(fEOF h)
99125 then putStr (onEOF acc)
100− else do x <- fread h
126+ else do Right x <- fGetLine h
127+ | Left err => putStr (onEOF acc)
101128 let (out, acc') = onRead acc x
102129 putStr out
103130 processHandle h acc' onRead onEOF
libs/prelude/Prelude/List.idr+7−3
@@ -19,16 +19,20 @@ infix 5 \\
1919infixr 7 ::,++
2020
2121||| Generic lists
22−%elim data List elem =
22+%elim data List : (elem : Type) -> Type where
2323 ||| Empty list
24− Nil |
24+ Nil : List elem
2525 ||| A non-empty list, consisting of a head element and the rest of
2626 ||| the list.
27− (::) elem (List elem)
27+ (::) : (x : elem) -> (xs : List elem) -> List elem
2828
2929-- Name hints for interactive editing
3030%name List xs, ys, zs, ws
3131
32+-- Usage hints for erasure analysis
33+%used List.(::) x
34+%used List.(::) xs
35+
3236--------------------------------------------------------------------------------
3337-- Syntactic tests
3438--------------------------------------------------------------------------------
libs/prelude/Prelude/Maybe.idr+8−5
@@ -13,11 +13,14 @@ import Prelude.Foldable
1313
1414||| An optional value. This can be used to represent the possibility of
1515||| failure, where a function may return a value, or not.
16−data Maybe a
17− = ||| No value stored
18− Nothing
19− | ||| A value of type `a` is stored
20− Just a
16+data Maybe : (a : Type) -> Type where
17+ ||| No value stored
18+ Nothing : Maybe a
19+ ||| A value of type `a` is stored
20+ Just : (x : a) -> Maybe a
21+
22+-- Used hints for erasure analysis
23+%used Just x
2124
2225--------------------------------------------------------------------------------
2326-- Syntactic tests
libs/prelude/Prelude/Monad.idr+1−1
@@ -13,7 +13,7 @@ import IO
1313infixl 5 >>=
1414
1515class Applicative m => Monad (m : Type -> Type) where
16− (>>=) : m a -> (a -> m b) -> m b
16+ (>>=) : m a -> ((result : a) -> m b) -> m b
1717
1818||| Also called `join` or mu
1919flatten : Monad m => m (m a) -> m a
libs/prelude/Prelude/Nat.idr+13−10
@@ -214,47 +214,50 @@ instance MinBound Nat where
214214instance Cast Integer Nat where
215215 cast = fromInteger
216216
217+instance Cast String Nat where
218+ cast str = cast (the Integer (cast str))
219+
217220||| A wrapper for Nat that specifies the semigroup and monad instances that use (*)
218221record Multiplicative where
219− constructor getMultiplicative
222+ constructor GetMultiplicative
220223 _ : Nat
221224
222225||| A wrapper for Nat that specifies the semigroup and monad instances that use (+)
223226record Additive where
224− constructor getAdditive
227+ constructor GetAdditive
225228 _ : Nat
226229
227230instance Semigroup Multiplicative where
228− (<+>) left right = getMultiplicative $ left' * right'
231+ (<+>) left right = GetMultiplicative $ left' * right'
229232 where
230233 left' : Nat
231234 left' =
232235 case left of
233− getMultiplicative m => m
236+ GetMultiplicative m => m
234237
235238 right' : Nat
236239 right' =
237240 case right of
238− getMultiplicative m => m
241+ GetMultiplicative m => m
239242
240243instance Semigroup Additive where
241− left <+> right = getAdditive $ left' + right'
244+ left <+> right = GetAdditive $ left' + right'
242245 where
243246 left' : Nat
244247 left' =
245248 case left of
246− getAdditive m => m
249+ GetAdditive m => m
247250
248251 right' : Nat
249252 right' =
250253 case right of
251− getAdditive m => m
254+ GetAdditive m => m
252255
253256instance Monoid Multiplicative where
254− neutral = getMultiplicative $ S Z
257+ neutral = GetMultiplicative $ S Z
255258
256259instance Monoid Additive where
257− neutral = getAdditive Z
260+ neutral = GetAdditive Z
258261
259262||| Casts negative `Ints` to 0.
260263instance Cast Int Nat where
libs/prelude/Prelude/Show.idr+5
@@ -10,6 +10,7 @@ import Prelude.Chars
1010import Prelude.Classes
1111import Prelude.List
1212import Prelude.Maybe
13+import Prelude.Either
1314import Prelude.Nat
1415import Prelude.Strings
1516
@@ -185,6 +186,10 @@ instance Show a => Show (Maybe a) where
185186 showPrec d Nothing = "Nothing"
186187 showPrec d (Just x) = showCon d "Just" $ showArg x
187188
189+instance (Show a, Show b) => Show (Either a b) where
190+ showPrec d (Left x) = showCon d "Left" $ showArg x
191+ showPrec d (Right x) = showCon d "Right" $ showArg x
192+
188193instance (Show a, {y : a} -> Show (p y)) => Show (Sigma a p) where
189194 show (y ** prf) = "(" ++ show y ++ " ** " ++ show prf ++ ")"
190195
libs/prelude/Prelude/Stream.idr+4−1
@@ -14,11 +14,14 @@ import Prelude.List
1414
1515||| An infinite stream
1616codata Stream : Type -> Type where
17− (::) : a -> Stream a -> Stream a
17+ (::) : (e : a) -> Stream a -> Stream a
1818
1919-- Hints for interactive editing
2020%name Stream xs,ys,zs,ws
2121
22+-- Usage hints for erasure analysis
23+%used Stream.(::) e
24+
2225instance Functor Stream where
2326 map f (x::xs) = f x :: map f xs
2427
libs/pruviloj/Pruviloj.idr+5
@@ -1,3 +1,8 @@
1+||| Provides the whole public interface of the proof tools. Import
2+||| `Pruviloj.Core` for just the simplest tactics.
13module Pruviloj
24
35import public Pruviloj.Core
6+import public Pruviloj.Disjoint
7+import public Pruviloj.Induction
8+import public Pruviloj.Injective
libs/pruviloj/Pruviloj/Core.idr+135−11
@@ -3,13 +3,8 @@
33||| eventual Prelude inclusion.
44module Pruviloj.Core
55
6−
7−import Language.Reflection.Elab
86import Language.Reflection.Utils
97
10−data Infer : Type where
11− MkInfer : (a : Type) -> a -> Infer
12−
138||| Run something for effects, throwing away the return value
149ignore : Functor f => f a -> f ()
1510ignore x = map (const ()) x
@@ -22,6 +17,34 @@ skip = pure ()
2217try : Alternative f => f a -> f ()
2318try tac = ignore tac <|> pure ()
2419
20+||| Remove type information from a `TT` term, in a context. Fails if
21+||| de Bruijn indices are out of scope.
22+forget' : List TTName -> TT -> Elab Raw
23+forget' env (P nt n tm) = pure (Var n)
24+forget' env (V x) = Var <$> getName x env
25+ where getName : Int -> List a -> Elab a
26+ getName _ [] = fail [TextPart "Scope error when forget'ting types"]
27+ getName i (n::ns) = if i <= 0 then pure n else getName (i-1) ns
28+forget' env (Bind n b tm) =
29+ [| (RBind n)
30+ (assert_total $ traverse (forget' env) b)
31+ (forget' (n::env) tm) |]
32+forget' env (App tm tm') = [| RApp (forget' env tm) (forget' env tm') |]
33+forget' env (TConst c) = pure (RConstant c)
34+forget' env Erased = pure (RConstant Forgot)
35+forget' env (TType uexp) = pure RType
36+forget' env (UType uni) = pure (RUType uni)
37+
38+||| Remove type information from a `TT` term. Fails if de Bruijn
39+||| indices are out of scope.
40+forget : TT -> Elab Raw
41+forget tm = forget' [] tm
42+
43+||| Get the goal type as a Raw term. Fails if there are no holes.
44+goalType : Elab Raw
45+goalType = do g <- getGoal
46+ forget (snd g)
47+
2548||| Solve the goal using the most recent applicable hypothesis
2649hypothesis : Elab ()
2750hypothesis =
@@ -46,7 +69,6 @@ nameFrom (MN x n) =
4669 then "n"
4770 else n
4871nameFrom (SN x) = gensym "SN"
49−nameFrom NErased = gensym "wasErased"
5072
5173||| Get the name at the head of the term, if it exists.
5274headName : Raw -> Maybe TTName
@@ -69,7 +91,7 @@ newHole hint ty =
6991|||
7092||| @ tm the term that has the right type for the hole
7193exact : (tm : Raw) -> Elab ()
72−exact tm = do apply tm []
94+exact tm = do fill tm
7395 solve
7496
7597||| Introduce as many names as possible, returning them.
@@ -85,11 +107,11 @@ intros = do g <- snd <$> getGoal
85107
86108||| Run a tactic inside of a particular hole, if it still exists. If
87109||| it has been solved, do nothing.
88−inHole : TTName -> Elab () -> Elab ()
110+inHole : TTName -> Elab a -> Elab (Maybe a)
89111inHole h todo =
90− when (h `elem` !getHoles) $
91− do focus h
92− todo
112+ if (h `elem` !getHoles)
113+ then do focus h; Just <$> todo
114+ else return Nothing
93115
94116||| Restrict a polymorphic type to () for contexts where it doesn't
95117||| matter. This is nice for sticking `debug` in a context where
@@ -142,3 +164,105 @@ bindPat = do compute
142164 case g of
143165 Bind n (PVTy _) _ => patbind n
144166 _ => fail [TermPart g, TextPart "isn't looking for a pattern."]
167+
168+||| The underlying implementation type for the inferType operator.
169+data Infer : Type where
170+ MkInfer : (a : Type) -> a -> Infer
171+
172+||| Run a tactic script in a context where the type of the resulting
173+||| expression must be solvable via unification. Return the term and
174+||| its type.
175+|||
176+||| @ tac a tactic script that will be run with focus on the hole
177+||| whose type is to be inferred.
178+total
179+inferType : (tac : Elab ()) -> Elab (TT, TT)
180+inferType tac =
181+ case fst !(runElab `(Infer) (do startInfer; tac)) of
182+ `(MkInfer ~ty ~tm) => return (tm, ty)
183+ _ => fail [TextPart "Not infer"]
184+ where
185+ startInfer : Elab ()
186+ startInfer = do [_, tmH] <- apply (Var `{MkInfer}) [True, False]
187+ | err => fail [TextPart "Type inference failure"]
188+ solve
189+ focus tmH
190+
191+||| Given one tactic that produces a list of subgoal names and another
192+||| that produces some result, run the second tactic in each hole
193+||| produced by the first and return the resulting values.
194+|||
195+||| Elab has no built-in notion of "subgoals", so this simulates the
196+||| Coq or JonPRL semicolon operators.
197+|||
198+||| @ first run this tactic to produce subgoals
199+||| @ after run this tactic in each subgoal
200+andThen : (first : Elab (List TTName)) -> (after : Elab a) -> Elab (List a)
201+andThen first after =
202+ do hs <- first
203+ catMaybes <$> for hs (flip inHole after)
204+
205+||| Refine the current goal using some term, constructing holes for
206+||| all arguments that can't be inferred. Return the list of generated
207+||| holes.
208+|||
209+||| @ tm the term to apply to some number of goals
210+refine : (tm : Raw) -> Elab (List TTName)
211+refine tm =
212+ do ty <- (snd <$> check !getEnv tm) >>= forget
213+ g <- goalType
214+
215+ -- we don't care about negative results because it'll just fail anyway
216+ let argCount = minus (countPi ty) (countPi g)
217+ newHoles <- apply tm (replicate argCount True)
218+ solve
219+ actualHoles <- getHoles
220+ return (filter (flip elem actualHoles) newHoles)
221+
222+ where countPi : Raw -> Nat
223+ countPi (RBind _ (Pi _ _) body) = S (countPi body)
224+ countPi _ = Z
225+
226+
227+||| Split a pair into its projections, binding them in the context
228+||| with the supplied names. A special case of Coq's `inversion`.
229+both : Raw -> TTName -> TTName -> Elab ()
230+both tm n1 n2 =
231+ do -- We don't know that the term is canonical, so let-bind projections applied to it
232+ (A, B) <- isPairTy (snd !(check !getEnv tm))
233+ remember n1 A; apply `(fst {a=~A} {b=~B} ~tm) []; solve
234+ remember n2 B; apply `(snd {a=~A} {b=~B} ~tm) []; solve
235+ where
236+ isPairTy : TT -> Elab (Raw, Raw)
237+ isPairTy `((~A, ~B) : Type) = [| MkPair (forget A) (forget B) |]
238+ isPairTy tm = fail [TermPart tm, TextPart "is not a pair"]
239+
240+||| Let-bind all results of completely destructuring nested tuples.
241+|||
242+||| This makes them available to the `hypothesis` tactic, among others.
243+|||
244+||| @ tm the nested tuple to destructure
245+covering
246+unproduct : (tm : Raw) -> Elab ()
247+unproduct tm =
248+ do n1 <- gensym "left"
249+ n2 <- gensym "right"
250+ both tm n1 n2
251+ try (unproduct (Var n1))
252+ try (unproduct (Var n2))
253+
254+
255+||| A special-purpose tactic that attempts to solve a goal using
256+||| `Refl`. This is useful for ensuring that goals in fact are trivial
257+||| when developing or testing other tactics; otherwise, consider
258+||| using `search`.
259+reflexivity : Elab ()
260+reflexivity =
261+ case !goalType of
262+ `((=) {A=~A} {B=~_} ~x ~_) =>
263+ do fill `(Refl {A=~A} {x=~x})
264+ solve
265+ _ => fail [ TextPart "The goal is not an equality, so"
266+ , NamePart `{reflexivity}
267+ , TextPart "is not applicable."
268+ ]
libs/pruviloj/Pruviloj/Derive/DecEq.idrnew file+196
@@ -0,0 +1,196 @@
1+||| Derive implementations of decidable equality.
2+module Pruviloj.Derive.DecEq
3+
4+import Data.Fin
5+import Data.Vect
6+
7+import Language.Reflection.Utils
8+
9+import Pruviloj.Core
10+
11+import Pruviloj.Renamers
12+import Pruviloj.Internals
13+
14+import Pruviloj.Derive.Eliminators
15+
16+import Pruviloj.Disjoint
17+import Pruviloj.Induction
18+import Pruviloj.Injective
19+
20+%default total
21+%access private
22+
23+
24+covering
25+noCase : TTName -> Elab ()
26+noCase contra =
27+ do [_, nope] <- apply (Var `{No}) [True, False]
28+ | _ => fail [TextPart "Bad holes from", NamePart `{Tactics.apply}]
29+ solve
30+ focus nope
31+
32+ -- Construct a lambda binding an assumption from which we can
33+ -- derive the contradiction
34+ h <- gensym "h"
35+ inj <- gensym "inj"
36+ attack
37+ intro h
38+ injective (Var h) inj
39+ unproduct (Var inj)
40+ ignore $ refine (Var contra) `andThen` hypothesis
41+ solve -- attack
42+
43+partial -- TODO make covering/total
44+matchCase : List Raw -> Elab ()
45+matchCase [] = search
46+matchCase (tm :: tms) =
47+ do (y :: n :: _) <- induction tm
48+
49+ focus n; compute
50+ contra <- gensym "contra"
51+ attack; intro contra
52+ noCase contra; solve
53+
54+ focus y; compute
55+ prf <- gensym "prf"
56+ attack; intro prf
57+ rewriteWith (Var prf)
58+ matchCase tms
59+ solve
60+
61+spanM : (Monad m) => (a -> m Bool) -> List a -> m (List a, List a)
62+spanM p [] = pure ([], [])
63+spanM p (x::xs) =
64+ if !(p x)
65+ then do (yes, no) <- spanM p xs
66+ pure (x :: yes, no)
67+ else pure ([], x::xs)
68+
69+partitionM : Monad m => (a -> m Bool) -> List a -> m (List a, List a)
70+partitionM p [] = pure ([], [])
71+partitionM p (x :: xs) =
72+ do (y, n) <- partitionM p xs
73+ if !(p x) then pure (x :: y, n) else pure (y, x :: n)
74+
75+perhaps : (Alternative f) => (f a) -> (f (Maybe a))
76+perhaps x = (Just <$> x) <|> pure Nothing
77+
78+headIs : Raw -> TTName -> Bool
79+headIs tm n = maybe False (==n) (headName tm)
80+
81+partial
82+mkRhs : (fn, fam : TTName) -> Nat -> Elab ()
83+mkRhs fn fam k =
84+ case snd !getGoal of
85+ `(Dec ((=) {A=~A} {B=~_} ~x ~y)) =>
86+ let (c1, args1) = unApply x
87+ (c2, args2) = unApply y
88+ in if c1 /= c2
89+ then do (h :: _) <- refine (Var `{No})
90+ | _ => empty
91+ focus h
92+ disjoint
93+ else do let toMakeEqual = List.filter (uncurry (/=)) (zip args1 args2)
94+ tms <- for {b=Raw} toMakeEqual $ \(tm1, tm2) =>
95+ do env <- getEnv
96+ (tm1', ty1') <- forget tm1 >>= check env
97+ (tm2', ty2') <- forget tm2 >>= check env
98+ -- assume they have the same type here -
99+ -- reasonable due to same constructor, but
100+ -- this means order is important when
101+ -- traversing
102+ eq <- gensym "eq"
103+ rTy <- forget ty1'
104+ rTm1 <- forget tm1'
105+ rTm2 <- forget tm2'
106+ remember eq `(Dec ((=) {A=~rTy} {B=~rTy} ~rTm1 ~rTm2))
107+ simple $
108+ if headIs rTy fam
109+ then do (a2::a1::hs) <- reverse <$> apply (Var fn) (replicate k True ++ [False, False])
110+ solve
111+ focus a1; fill rTm1; solve
112+ focus a2; fill rTm2; solve
113+ for_ hs $ \h => inHole h (resolveTC fn)
114+ else do [_, dH, a1, a2] <- apply (Var `{decEq}) [True, False, False, False]
115+ solve
116+ focus a1; fill rTm1; solve
117+ focus a2; fill rTm2; solve
118+ focus dH; resolveTC fn
119+ return (Var eq)
120+ matchCase tms
121+ _ => fail [TextPart "Inapplicable"]
122+
123+||| Attempt to derive the body of an implementation of decidable
124+||| equality based on an existing type signature.
125+|||
126+||| The function signature must provide enough information for the
127+||| deriving to occur. It must consist of zero or more non-constraint
128+||| arguments followed by zero or more constraint arguments, followed
129+||| by the two values to compare. The constraint arguments must
130+||| provide sufficient instances of `DecEq` to decide the equality of
131+||| each constructor field. The final two arguments to the function
132+||| declaration must be the two values that will be compared for
133+||| equality.
134+|||
135+||| @ fn the name of the function whose type has been declared
136+abstract partial -- because of mkRhs
137+deriveDecEq : (fn : TTName) -> Elab ()
138+deriveDecEq fn =
139+ do (_, Ref, sig') <- lookupTyExact fn
140+ sig <- forget sig'
141+ (args, `(Dec ((=) {A=~A} {B=~_} ~(Var x) ~(Var y)))) <- stealBindings sig noRenames
142+ | other => fail [ TextPart "Return type"
143+ , RawPart (snd other)
144+ , TextPart "isn't decidable equality"
145+ ]
146+
147+ datatype <- maybe (fail [ RawPart A
148+ , TextPart "is not an application of a TC"
149+ ])
150+ lookupDatatypeExact
151+ (headName A)
152+
153+ -- the signature must be like this:
154+ -- 1. a collection of variable bindings (will be implicit)
155+ -- 2. a collection of constraints
156+ -- 3. the arguments x and y from the return type
157+ (bindings, constrs, arg1, arg2) <-
158+ the (Elab (List (TTName, Binder Raw),
159+ List (TTName, Binder Raw),
160+ (TTName, Binder Raw),
161+ (TTName, Binder Raw))) $
162+ case reverse args of
163+ [] => fail [TextPart "Invalid signature"]
164+ [_] => fail [TextPart "Invalid signaure"]
165+ (a2 :: a1 :: rest) =>
166+ do (constrs, bindings) <- partitionM (\x => isConstr (binderTy (snd x)))
167+ (reverse rest)
168+ return (bindings, constrs, a1, a2)
169+ let todo = [(c1, c2) | c1 <- constructors datatype
170+ , c2 <- constructors datatype]
171+ clauses <- for todo
172+ (uncurry $ mkCase (length bindings + length constrs)
173+ (name datatype))
174+ defineFunction $ DefineFun fn (catMaybes clauses)
175+ skip
176+
177+ where
178+ isConstr : Raw -> Elab Bool
179+ isConstr tm = case headName tm of
180+ Just n => isTCName n
181+ Nothing => return False
182+
183+ partial -- mkRhs
184+ mkCase : Nat -> TTName -> (x, y : (TTName, List CtorArg, Raw)) -> Elab (Maybe (FunClause Raw))
185+ mkCase k fam (cn1, args1, _) (cn2, args2, _) =
186+ perhaps $ elabPatternClause
187+ (do (h2 :: h1 :: _) <- reverse <$>
188+ apply (Var fn) (replicate k True ++ [False, False])
189+ solve
190+ focus h1
191+ apply (Var cn1) (replicate (length args1) True)
192+ solve
193+ focus h2
194+ apply (Var cn2) (replicate (length args2) True)
195+ solve)
196+ (mkRhs fn fam k)
libs/pruviloj/Pruviloj/Derive/Eliminators.idr+32−41
@@ -18,7 +18,7 @@ bindParams info = traverse_ (uncurry forall) (getParams info)
1818||| rewrite an application of something to their designated global
1919||| names
2020bindIndices : TyConInfo -> Elab Renamer
21−bindIndices info = bind' (getIndices info) (const Nothing)
21+bindIndices info = bind' (getIndices info) noRenames
2222 where bind' : List (TTName, Raw) -> Renamer -> Elab Renamer
2323 bind' [] ren = return ren
2424 bind' ((n, t) :: ixs) ren = do n' <- nameFrom n
@@ -54,7 +54,7 @@ headsMatch x y =
5454||| Make an induction hypothesis if one is called for
5555mkIh : TyConInfo -> (motiveName : TTName) -> (recArg : TTName) -> (argty, fam : Raw) -> Elab ()
5656mkIh info motiveName recArg argty fam =
57− case !(stealBindings argty (const Nothing)) of
57+ case !(stealBindings argty noRenames) of
5858 (argArgs, argRes) =>
5959 if headsMatch argRes fam
6060 then do ih <- gensym "ih"
@@ -65,12 +65,12 @@ mkIh info motiveName recArg argty fam =
6565 for_ {b=()} argArgs $ \(n, b) =>
6666 forall n (getBinderTy b)
6767 let argTm : Raw = mkApp (Var recArg) (map (Var . fst) argArgs)
68− argTmTy <- forgetTypes (snd !(check argTm))
68+ argTmTy <- forget (snd !(check !getEnv argTm))
6969 argHoles <- apply (Var motiveName)
7070 (replicate (length (getIndices info))
71− (True, 0) ++
72− [(False,1)])
73− argH <- snd <$> last argHoles
71+ True ++
72+ [False])
73+ argH <- last argHoles
7474 focus argH
7575 fill argTm; solve
7676 solve -- attack
@@ -80,35 +80,29 @@ mkIh info motiveName recArg argty fam =
8080elabMethodTy : TyConInfo -> TTName -> List CtorArg -> Raw -> Raw -> Elab ()
8181elabMethodTy info motiveName [] res ctorApp =
8282 do argHoles <- apply (Var motiveName)
83− (replicate (length (getIndices info)) (True, 0) ++
84− [(False, 1)])
85− argH <- snd <$> last argHoles
83+ (replicate (length (getIndices info)) True ++
84+ [False])
85+ argH <- last argHoles
8686 focus argH; fill ctorApp; solve
8787 solve
8888elabMethodTy info motiveName (CtorParameter arg :: args) res ctorApp =
89− elabMethodTy info motiveName args res (RApp ctorApp (Var (argName arg)))
89+ elabMethodTy info motiveName args res (RApp ctorApp (Var (name arg)))
9090elabMethodTy info motiveName (CtorField arg :: args) res ctorApp =
91− do let n = argName arg
92− let t = argTy arg
91+ do let n = name arg
92+ let t = type arg
9393 attack; forall n t
9494 mkIh info motiveName n t (result info)
9595 elabMethodTy info motiveName args res (RApp ctorApp (Var n))
9696 solve
9797
9898
99−
100−elabMethod : TyConInfo -> (motiveName, ctorN : TTName) -> List CtorArg -> Raw -> Elab ()
101−elabMethod info motiveName ctorN ctorArgs resTy =
102− do elabMethodTy info motiveName ctorArgs resTy (Var ctorN)
103−
104−
10599||| Bind a method for a constructor
106100bindMethod : TyConInfo -> (motiveName, cn : TTName) -> List CtorArg -> Raw -> Elab ()
107101bindMethod info motiveName cn cargs cty =
108102 do n <- nameFrom cn
109103 h <- newHole "methTy" `(Type)
110104 forall n (Var h)
111− focus h; elabMethod info motiveName cn cargs cty
105+ focus h; elabMethodTy info motiveName cargs cty (Var cn)
112106
113107getElimTy : TyConInfo -> List (TTName, List CtorArg, Raw) -> Elab Raw
114108getElimTy info ctors =
@@ -129,7 +123,7 @@ getElimTy info ctors =
129123 [Var scrut])
130124 apply (alphaRaw iren ret) []
131125 solve
132− forgetTypes (fst ty)
126+ forget (fst ty)
133127
134128
135129
@@ -140,7 +134,7 @@ instance Show ElimArg where
140134 show (NormalArgument x) = "NormalArgument " ++ show x
141135
142136getElimClause : TyConInfo -> (elimn : TTName) -> (methCount : Nat) ->
143− (TTName, List CtorArg, Raw) -> Nat -> Elab FunClause
137+ (TTName, List CtorArg, Raw) -> Nat -> Elab (FunClause Raw)
144138getElimClause info elimn methCount (cn, args, resTy) whichCon =
145139 elabPatternClause
146140 (do -- Establish a hole for each parameter
@@ -153,8 +147,8 @@ getElimClause info elimn methCount (cn, args, resTy) whichCon =
153147 for {b=()} args $ \arg =>
154148 case arg of
155149 CtorParameter _ => return ()
156− CtorField arg => do claim (argName arg) (argTy arg)
157− unfocus (argName arg)
150+ CtorField arg => do claim (name arg) (type arg)
151+ unfocus (name arg)
158152
159153 -- Establish a hole for the scrutinee (infer type)
160154 scrutinee <- newHole "scrutinee" resTy
@@ -167,9 +161,9 @@ getElimClause info elimn methCount (cn, args, resTy) whichCon =
167161 -- We leave the RHS with a function type: motive -> method* -> res
168162 -- to make it easier to map methods to constructors
169163 holes <- apply paramApp (replicate (length (getIndices info))
170− (True, 0) ++
171− [(False, 1)])
172− scr <- snd <$> last holes
164+ True ++
165+ [False])
166+ scr <- last holes
173167 focus scr; fill (Var scrutinee); solve
174168 solve
175169
@@ -177,8 +171,8 @@ getElimClause info elimn methCount (cn, args, resTy) whichCon =
177171 focus scrutinee
178172 apply (mkApp (Var cn) $
179173 map (\x => case x of
180− CtorParameter param => Var (argName param)
181− CtorField arg => Var (argName arg))
174+ CtorParameter param => Var (name param)
175+ CtorField arg => Var (name arg))
182176 args)
183177 []
184178 solve)
@@ -195,21 +189,21 @@ getElimClause info elimn methCount (cn, args, resTy) whichCon =
195189 case x of
196190 CtorParameter _ => return List.Nil
197191 CtorField arg =>
198− do let n = argName arg
199− let t = argTy arg
200− (argArgs, argRes) <- stealBindings t (const Nothing)
192+ do let n = name arg
193+ let t = type arg
194+ (argArgs, argRes) <- stealBindings t noRenames
201195 if headsMatch argRes (result info) --recursive
202196 then return [ NormalArgument n
203197 , IHArgument n
204198 ]
205199 else return [NormalArgument n])
206200
207− argHs <- apply (Var methN) (replicate (List.length argSpec) (True, 0))
201+ argHs <- apply (Var methN) (replicate (List.length argSpec) True)
208202 solve
209203
210204 -- Now build the recursive calls for the induction hypotheses
211205 for_ {a=(ElimArg, TTName)} {b=()}
212− !(zipH argSpec (map snd argHs))
206+ !(zipH argSpec argHs)
213207 (\(spec, nh) =>
214208 case spec of
215209 NormalArgument n => do focus nh
@@ -220,12 +214,12 @@ getElimClause info elimn methCount (cn, args, resTy) whichCon =
220214 attack
221215 local <- intros
222216 ihHs <- apply (Var elimn) $
223− replicate (length (TyConInfo.args info)) (True, 0) ++
224− [(False, 1)] ++
225− replicate (S methCount) (True, 0)
217+ replicate (length (TyConInfo.args info)) True ++
218+ [False] ++
219+ replicate (S methCount) True
226220 solve -- application
227221
228− let (arg::motive::methods) = map snd $ drop (length (TyConInfo.args info)) ihHs
222+ let (arg::motive::methods) = drop (length (TyConInfo.args info)) ihHs
229223 focus arg
230224
231225 apply (mkApp (Var n) (map Var local)) []; solve
@@ -248,15 +242,12 @@ getElimClause info elimn methCount (cn, args, resTy) whichCon =
248242 bindLam ((n, b)::rest) x = RBind n (Lam (getBinderTy b)) $ bindLam rest x
249243
250244getElimClauses : TyConInfo -> (elimn : TTName) ->
251− List (TTName, List CtorArg, Raw) -> Elab (List FunClause)
245+ List (TTName, List CtorArg, Raw) -> Elab (List (FunClause Raw))
252246getElimClauses info elimn ctors =
253247 let methodCount = length ctors
254248 in traverse (\(i, con) => getElimClause info elimn methodCount con i)
255249 (enumerate ctors)
256250
257−instance Show FunClause where
258− show (MkFunClause x y) = "(MkFunClause " ++ show x ++ " " ++ show y ++ ")"
259−
260251abstract
261252deriveElim : (tyn, elimn : TTName) -> Elab ()
262253deriveElim tyn elimn =
libs/pruviloj/Pruviloj/Disjoint.idrnew file+85
@@ -0,0 +1,85 @@
1+||| Provides a tactic for solving constructor disjointness goals.
2+module Pruviloj.Disjoint
3+
4+import Language.Reflection.Utils
5+
6+import Pruviloj.Core
7+import Pruviloj.Internals
8+import Pruviloj.Renamers
9+
10+%default total
11+%access private
12+
13+-------------------
14+-- PRIVATE GUTS --
15+-------------------
16+
17+||| Compute the name to use for a disjointness lemma.
18+disjointName : TTName -> TTName -> TTName
19+disjointName l r = NS (SN (MetaN (UN "disjoint") (SN (MetaN l r))))
20+ ["Disjoint", "Pruviloj"]
21+
22+||| Return the name of the disjointness lemma for two constructors,
23+||| defining it if necessary.
24+|||
25+||| @ l one of the constructor names
26+||| @ r the other constructor name
27+covering
28+getDisjointness : (l, r : TTName) -> Elab TTName
29+getDisjointness l r = exists <|> declare
30+
31+ where exists : Elab TTName
32+ exists = do (yep, _, _) <- lookupTyExact (disjointName l r)
33+ return yep
34+
35+ notConstructor : TTName -> Elab a
36+ notConstructor c = fail [NamePart c, TextPart "is not a constructor"]
37+
38+ covering
39+ declare : Elab TTName
40+ declare = do (l', DCon _ _, lty) <- lookupTyExact l
41+ | _ => notConstructor l
42+ (r', DCon _ _, rty) <- lookupTyExact r
43+ | _ => notConstructor r
44+ let fn = disjointName l' r'
45+ when (l' == r') $
46+ fail [ NamePart l', TextPart "and"
47+ , NamePart r', TextPart "are clearly not disjoint!"
48+ ]
49+ (argsl, resl) <- stealBindings !(forget lty) noRenames
50+ (argsr, resr) <- stealBindings !(forget rty) noRenames
51+ let args = map {b=FunArg}
52+ (\(n, b) => MkFunArg n (binderTy b) Implicit NotErased)
53+ (argsl ++ argsr)
54+ let eq : Raw = `((=) {A=~resl}
55+ {B=~resr}
56+ ~(mkApp (Var l') (map (Var . fst) argsl))
57+ ~(mkApp (Var r') (map (Var . fst) argsr)))
58+ h <- gensym "h"
59+ declareType $ Declare fn (args ++ [MkFunArg h eq Explicit NotErased]) `(Void)
60+ defineFunction $ DefineFun fn []
61+ return fn
62+
63+----------------------
64+-- PUBLIC INTERFACE --
65+----------------------
66+
67+
68+||| Solve a goal of the form `(C1 x1 x2 ... xn = C2 x1 x2 ... xn) ->
69+||| Void` for disjoint constructors `C1` and `C2`.
70+public covering
71+disjoint : Elab ()
72+disjoint =
73+ do compute
74+ g <- snd <$> getGoal
75+ case g of
76+ `(((=) {A=~A} {B=~B} ~a ~b) -> Void) =>
77+ do Just lHead <- headName <$> forget a
78+ | Nothing => fail [TermPart a, TextPart "doesn't have a name at the head"]
79+ Just rHead <- headName <$> forget b
80+ | Nothing => fail [TermPart b, TextPart "doesn't have a name at the head"]
81+ [] <- refine (Var !(getDisjointness lHead rHead))
82+ | _ => fail [TextPart "Didn't solve argument to disjointness lemma"]
83+ skip
84+ ty =>
85+ fail [NamePart `{disjoint}, TextPart "is not applicable to goal", TermPart ty]
libs/pruviloj/Pruviloj/Induction.idr+8−13
@@ -36,7 +36,6 @@ mutual
3636 alphaEqual subst f g && alphaEqual subst x y
3737 alphaEqual subst RType RType = True
3838 alphaEqual subst (RUType u) (RUType u') = u == u'
39− alphaEqual subst (RForce tm) (RForce tm') = alphaEqual subst tm tm'
4039 alphaEqual subst (RConstant c) (RConstant c') = c == c'
4140 alphaEqual subst _ _ = False
4241
@@ -49,9 +48,6 @@ mutual
4948 alphaEqualBinders subst (Let tm1 tm2) (Let tm1' tm2') =
5049 alphaEqual subst tm1 tm1' &&
5150 alphaEqual subst tm2 tm2'
52− alphaEqualBinders subst (NLet tm1 tm2) (NLet tm1' tm2') =
53− alphaEqual subst tm1 tm1' &&
54− alphaEqual subst tm2 tm2'
5551 alphaEqualBinders subst (Hole tm) (Hole tm') =
5652 alphaEqual subst tm tm'
5753 alphaEqualBinders subst (GHole tm) (GHole tm') =
@@ -79,7 +75,6 @@ generalize hint ctxt subj = do n <- gensym hint
7975 genB n (Lam ty) inner = [| Lam (gen' n ty inner) |]
8076 genB n (Pi ty ty') inner = [| Pi (gen' n ty inner) (gen' n ty' inner) |]
8177 genB n (Let ty val) inner = [| Let (gen' n ty inner) (gen' n val inner) |]
82− genB n (NLet ty val) inner = [| NLet (gen' n ty inner) (gen' n val inner) |]
8378 genB n (Hole ty) inner = [| Hole (gen' n ty inner) |]
8479 genB n (GHole ty) inner = [| GHole (gen' n ty inner) |]
8580 genB n (Guess ty val) inner = [| Guess (gen' n ty inner) (gen' n val inner) |]
@@ -134,8 +129,8 @@ public
134129induction : Raw -> Elab (List TTName)
135130induction subj =
136131 do g <- goalType
137− (_, ty) <- check subj
138− ty' <- forgetTypes ty
132+ (_, ty) <- check !getEnv subj
133+ ty' <- forget ty
139134 case headName ty' of
140135 Nothing => fail [TermPart ty, TextPart "is not an inductive family"]
141136 Just fam =>
@@ -145,18 +140,18 @@ induction subj =
145140 tydef <- lookupDatatypeExact fam
146141 info <- getTyConInfo (tyConArgs tydef) (tyConRes tydef)
147142 argHoles <- apply (Var elim)
148− (replicate (length (args info)) (True, 0) ++
149− [(False, 0), (False, 0)] ++ -- scrutinee, motive
150− replicate (length (constructors tydef)) (False, 1))
143+ (replicate (length (args info)) True ++
144+ [False, False] ++ -- scrutinee, motive
145+ replicate (length (constructors tydef)) False)
151146 solve
152147
153148 -- Apply the eliminator to our scrutinee
154− scrutH <- snd <$> unsafeNth (length (args info)) argHoles
149+ scrutH <- unsafeNth (length (args info)) argHoles
155150 focus scrutH
156151 apply subj []
157152 solve
158153
159− motiveH <- snd <$> unsafeNth (length (args info) + 1) argHoles
154+ motiveH <- unsafeNth (length (args info) + 1) argHoles
160155 focus motiveH; makeMotive info subj ty' g
161156
162− return (map snd (drop (2 + length (tyConArgs tydef)) argHoles))
157+ return (drop (2 + length (tyConArgs tydef)) argHoles)
libs/pruviloj/Pruviloj/Injective.idrnew file+122
@@ -0,0 +1,122 @@
1+module Pruviloj.Injective
2+
3+import Language.Reflection.Utils
4+
5+import Pruviloj.Core
6+import Pruviloj.Internals
7+import Pruviloj.Renamers
8+
9+%default total
10+%access private
11+
12+-------------------
13+-- PRIVATE GUTS --
14+-------------------
15+
16+||| Compute the name for a constructor's injectivity lemma
17+injName : TTName -> TTName
18+injName cn = NS (SN (MetaN `{{injectivity}} cn)) ["Injective", "Pruviloj"]
19+
20+||| Provide an error message for when non-constructor names are passed
21+notConstructor : TTName -> Elab a
22+notConstructor c = fail [NamePart c, TextPart "is not a constructor"]
23+
24+covering
25+getInjectivity : (cn : TTName) -> Elab TTName
26+getInjectivity cn = exists <|> declare
27+ where exists : Elab TTName
28+ exists = do (fn, Ref, _) <- lookupTyExact (injName cn)
29+ | (fn, _, _) => fail [TextPart "Bad earlier declaration of", NamePart fn]
30+ return fn
31+
32+ covering
33+ declare : Elab TTName
34+ declare = do (cn', DCon _ _, cty) <- lookupTyExact cn
35+ | _ => notConstructor cn
36+ let fn = injName cn'
37+ (args1, res1) <- stealBindings !(forget cty) noRenames
38+ (args2, res2) <- stealBindings !(forget cty) noRenames
39+ let impls1 = map (\(n, b) => MkFunArg n (binderTy b) Implicit NotErased)
40+ args1
41+ let impls2 = map (\(n, b) => MkFunArg n (binderTy b) Implicit NotErased)
42+ args2
43+ let res = foldr (\t1, t2 => RApp (RApp (Var `{Pair}) t1) t2)
44+ `(() : Type)
45+ (map (\(a1, a2) =>
46+ `((=) {A=~(type a1)}
47+ {B=~(type a2)}
48+ ~(Var (name a1))
49+ ~(Var (name a2))))
50+ (zip impls1 impls2))
51+
52+ declareType $ Declare fn (impls1 ++ impls2 ++
53+ [ MkFunArg !(gensym "arg")
54+ `((=) {A=~res1}
55+ {B=~res2}
56+ ~(mkApp (Var cn)
57+ (map (Var . fst) args1))
58+ ~(mkApp (Var cn)
59+ (map (Var . fst) args2)))
60+ Explicit
61+ NotErased])
62+
63+ res
64+ clause <- elabPatternClause
65+ (do (h::_) <- reverse <$>
66+ apply (Var fn)
67+ (replicate (2 * length args1)
68+ True ++
69+ [False])
70+ | _ => fail [TextPart "Missing hole"]
71+ solve
72+ focus h; search)
73+ search -- rhs is conjunction of Refls
74+ defineFunction $
75+ DefineFun fn [clause]
76+ return fn
77+
78+countBinders : TT -> Nat
79+countBinders (Bind _ _ body) = S (countBinders body)
80+countBinders _ = Z
81+
82+
83+----------------------
84+-- PUBLIC INTERFACE --
85+----------------------
86+
87+
88+||| Given an equality of the form `(C x1 ... xn = C y1 ... yn)`,
89+||| generate an product of the equalities `(x1 = y1)` ... `(xn = yn)`.
90+|||
91+||| The equalities are let-bound to the provided name.
92+|||
93+||| @ tm the equality to exploit injectivity on
94+||| @ n the name at which to bind the result
95+covering public
96+injective : (tm : Raw) -> (n : TTName) -> Elab ()
97+injective tm n =
98+ do (_, ty) <- check !getEnv tm
99+ case !(forget ty) of
100+ `((=) {A=~A} {B=~B} ~x ~y) =>
101+ case (headName x, headName y) of
102+ (Just xHd, Just yHd) =>
103+ if xHd /= yHd
104+ then fail [ TextPart "Mismatch between", NamePart xHd
105+ , TextPart "and", NamePart yHd
106+ ]
107+ else do fn <- getInjectivity xHd
108+ tyH <- newHole "ty" `(Type)
109+ tmH <- newHole "tm" (Var tyH)
110+
111+ letbind n (Var tyH) (Var tmH)
112+ focus tmH
113+ (_, _, fnTy) <- lookupTyExact fn
114+
115+ (arg :: _) <- reverse <$> apply (Var fn) (replicate (pred (countBinders fnTy)) True ++ [False])
116+ | _ => fail [TextPart "No hole for argument"]
117+ solve
118+
119+ focus arg; apply tm []; solve
120+ _ => fail [TextPart "oops"]
121+
122+ _ => fail [TextPart "can't use injectivity on non-equality"]
libs/pruviloj/Pruviloj/Internals.idr+15−19
@@ -9,20 +9,20 @@ import Data.Vect
99
1010||| Get the name of a reflected type constructor argument.
1111tyConArgName : TyConArg -> TTName
12−tyConArgName (TyConParameter a) = argName a
13−tyConArgName (TyConIndex a) = argName a
12+tyConArgName (TyConParameter a) = name a
13+tyConArgName (TyConIndex a) = name a
1414
1515||| Modify the name of a reflected type constructor argument.
1616setTyConArgName : TyConArg -> TTName -> TyConArg
17−setTyConArgName (TyConParameter a) n = TyConParameter (record {argName = n} a)
18−setTyConArgName (TyConIndex a) n = TyConIndex (record {argName = n} a)
17+setTyConArgName (TyConParameter a) n = TyConParameter (record {name = n} a)
18+setTyConArgName (TyConIndex a) n = TyConIndex (record {name = n} a)
1919
2020||| Modify the type of a reflected type constructor argument using some function.
2121updateTyConArgTy : (Raw -> Raw) -> TyConArg -> TyConArg
2222updateTyConArgTy f (TyConParameter a) =
23− TyConParameter (record {argTy = f (argTy a) } a)
23+ TyConParameter (record {type = f (type a) } a)
2424updateTyConArgTy f (TyConIndex a) =
25− TyConIndex (record {argTy = f (argTy a) } a)
25+ TyConIndex (record {type = f (type a) } a)
2626
2727unApply : Raw -> (Raw, List Raw)
2828unApply tm = unApply' tm []
@@ -63,7 +63,6 @@ getBinderTy : Binder t -> t
6363getBinderTy (Lam t) = t
6464getBinderTy (Pi t _) = t
6565getBinderTy (Let t _) = t
66−getBinderTy (NLet t _) = t
6766getBinderTy (Hole t) = t
6867getBinderTy (GHole t) = t
6968getBinderTy (Guess t _) = t
@@ -77,10 +76,6 @@ enumerate xs = enumerate' xs 0
7776 enumerate' [] _ = []
7877 enumerate' (x::xs) n = (n, x) :: enumerate' xs (S n)
7978
80−getSigmaArgs : Raw -> Elab (Raw, Raw)
81−getSigmaArgs `(MkSigma {a=~_} {P=~_} ~rhsTy ~lhs) = return (rhsTy, lhs)
82−getSigmaArgs arg = fail [TextPart "Not a sigma constructor"]
83−
8479bindPats : List (TTName, Binder Raw) -> Raw -> Raw
8580bindPats [] res = res
8681bindPats ((n, b)::bs) res = RBind n (PVar (getBinderTy b)) $ bindPats bs res
@@ -106,25 +101,26 @@ bindPatTys ((n, b)::bs) res = RBind n (PVTy (getBinderTy b)) $ bindPatTys bs res
106101||| It will be run in a context where the pattern variables are
107102||| already bound, and should leave behind no holes.
108103partial
109−elabPatternClause : (lhs, rhs : Elab ()) -> Elab FunClause
104+elabPatternClause : (lhs, rhs : Elab ()) -> Elab (FunClause Raw)
110105elabPatternClause lhs rhs =
111106 do -- Elaborate the LHS in a context where its type will be solved via unification
112− (pat, _) <- runElab `(Sigma Type id) $
107+ (pat, _) <- runElab `(Infer) $
113108 do th <- newHole "finalTy" `(Type)
114109 patH <- newHole "pattern" (Var th)
115− fill `(MkSigma ~(Var th) ~(Var patH) : Sigma Type id)
110+ fill `(MkInfer ~(Var th) ~(Var patH))
116111 solve
117112 focus patH
118113 lhs
119114 -- Convert all remaining holes to pattern variables
120− traverse_ {b=()} (\h => focus h *> patvar h) !getHoles
121− let (pvars, sigma) = extractBinders !(forgetTypes pat)
122− (rhsTy, lhsTm) <- getSigmaArgs sigma
115+ for_ {b=()} !getHoles $ \h =>
116+ do focus h; patvar h
117+ (pvars, `(MkInfer ~rhsTy ~lhsTm)) <- extractBinders <$> forget pat
118+ | fail [TextPart "Couldn't infer type of left-hand pattern"]
123119 rhsTm <- runElab (bindPatTys pvars rhsTy) $
124− do -- Introduce all the pattern variables from the LHS
120+ do -- Introduce all the pattern variables from the LHS
125121 repeatUntilFail bindPat <|> return ()
126122 rhs
127− realRhs <- forgetTypes (fst rhsTm)
123+ realRhs <- forget (fst rhsTm)
128124 return $ MkFunClause (bindPats pvars lhsTm) realRhs
129125
130126||| Introduce a unique binder name, returning it
libs/pruviloj/Pruviloj/Internals/TyConInfo.idr+11−11
@@ -23,13 +23,13 @@ record TyConInfo where
2323getParams : TyConInfo -> List (TTName, Raw)
2424getParams info = mapMaybe param (args info)
2525 where param : TyConArg -> Maybe (TTName, Raw)
26− param (TyConParameter a) = Just (argName a, argTy a)
26+ param (TyConParameter a) = Just (name a, type a)
2727 param _ = Nothing
2828
2929getIndices : TyConInfo -> List (TTName, Raw)
3030getIndices info = mapMaybe index (args info)
3131 where index : TyConArg -> Maybe (TTName, Raw)
32− index (TyConIndex a) = Just (argName a, argTy a)
32+ index (TyConIndex a) = Just (name a, type a)
3333 index _ = Nothing
3434
3535||| Rename a bound variable across a telescope
@@ -75,7 +75,7 @@ processCtorArgs info (cn, cargs, resTy) =
7575 findParam : TTName -> List Raw -> List TyConArg -> Elab TTName
7676 findParam paramN (Var n :: args) (TyConParameter a :: tcArgs) =
7777 if n == paramN
78− then return (argName a)
78+ then return (name a)
7979 else findParam paramN args tcArgs
8080 findParam paramN (_ :: args) (_ :: tcArgs) =
8181 findParam paramN args tcArgs
@@ -89,20 +89,20 @@ processCtorArgs info (cn, cargs, resTy) =
8989 TyConInfo -> Elab (List CtorArg, Raw)
9090 convert' subst [] ty info = return ([], alphaRaw subst ty)
9191 convert' subst (CtorField a :: args) ty info =
92− do n' <- nameFrom (argName a)
92+ do n' <- nameFrom (name a)
9393 let a' = record {
94− argName = n'
95− , argTy = alphaRaw subst (argTy a)
94+ name = n'
95+ , type = alphaRaw subst (type a)
9696 } a
97− let subst' = extend subst (argName a) n'
97+ let subst' = extend subst (name a) n'
9898 (args', ty') <- convert' subst' args ty info
9999 return (CtorField a' :: args', ty')
100100 convert' subst (CtorParameter a :: ctorArgs) ty info =
101− do n' <- findParam (argName a) (snd (unApply ty)) (args info)
101+ do n' <- findParam (name a) (snd (unApply ty)) (args info)
102102 let a' = record {
103− argName = n'
104− , argTy = alphaRaw subst (argTy a)
103+ name = n'
104+ , type = alphaRaw subst (type a)
105105 } a
106− let subst' = extend subst (argName a) n'
106+ let subst' = extend subst (name a) n'
107107 (args', ty') <- convert' subst' ctorArgs ty info
108108 return (CtorParameter a' :: args', ty')
libs/pruviloj/Pruviloj/Renamers.idr+5−2
@@ -6,6 +6,10 @@ import Language.Reflection.Utils
66Renamer : Type
77Renamer = TTName -> Maybe TTName
88
9+||| A renamer that renames nothing
10+noRenames : Renamer
11+noRenames = const Nothing
12+
913||| Cause a renamer to forget a renaming
1014restrict : Renamer -> TTName -> Renamer
1115restrict f n n' = if n == n' then Nothing else f n'
@@ -19,7 +23,7 @@ extend f n n' n'' = if n'' == n then Just n' else f n''
1923||| @ from the old name
2024||| @ to the new name
2125rename : (from, to : TTName) -> Renamer
22−rename from to = extend (const Nothing) from to
26+rename from to = extend noRenames from to
2327
2428||| Alpha-convert `Raw` terms
2529||| @ subst a renamer
@@ -35,5 +39,4 @@ alphaRaw subst (RBind n b tm) =
3539alphaRaw subst (RApp tm tm') = RApp (alphaRaw subst tm) (alphaRaw subst tm')
3640alphaRaw subst RType = RType
3741alphaRaw subst (RUType x) = RUType x
38−alphaRaw subst (RForce tm) = RForce (alphaRaw subst tm)
3942alphaRaw subst (RConstant c) = RConstant c
libs/pruviloj/pruviloj.ipkg+3
@@ -3,8 +3,11 @@ package pruviloj
33opts = "--nobasepkgs -i ../prelude -i ../base"
44modules = Pruviloj
55 , Pruviloj.Core
6+ , Pruviloj.Derive.DecEq
67 , Pruviloj.Derive.Eliminators
8+ , Pruviloj.Disjoint
79 , Pruviloj.Induction
10+ , Pruviloj.Injective
811 , Pruviloj.Internals
912 , Pruviloj.Internals.TyConInfo
1013 , Pruviloj.Renamers
main/Main.hs+6
@@ -45,6 +45,7 @@ main = do opts <- runArgParser
4545runIdris :: [Opt] -> Idris ()
4646runIdris opts = do
4747 runIO setupBundledCC
48+ when (ShowLoggingCats `elem` opts) $ runIO showLoggingCats
4849 when (ShowIncs `elem` opts) $ runIO showIncs
4950 when (ShowLibs `elem` opts) $ runIO showLibs
5051 when (ShowLibdir `elem` opts) $ runIO showLibdir
@@ -101,3 +102,8 @@ showIncs = do incFlags <- getIncFlags
101102showPkgs :: IO b
102103showPkgs = do mapM putStrLn =<< installedPackages
103104 exitWith ExitSuccess
105+
106+showLoggingCats :: IO b
107+showLoggingCats = do
108+ putStrLn loggingCatsStr
109+ exitWith ExitSuccess
rts/Makefile+4−3
@@ -1,7 +1,8 @@
11include ../config.mk
22
33OBJS = idris_rts.o idris_heap.o idris_gc.o idris_gmp.o idris_bitstring.o \
4− idris_opts.o idris_stats.o idris_utf8.o mini-gmp.o getline.o
4+ idris_opts.o idris_stats.o idris_utf8.o idris_stdfgn.o mini-gmp.o \
5+ getline.o
56HDRS = idris_rts.h idris_heap.h idris_gc.h idris_gmp.h idris_bitstring.h \
67 idris_opts.h idris_stats.h mini-gmp.h idris_stdfgn.h idris_net.h \
78 idris_utf8.h getline.h
@@ -19,10 +20,10 @@ endif
1920endif
2021
2122ifeq ($(OS), windows)
22− OBJS += windows/idris_stdfgn.o windows/idris_net.o windows/win_utils.o
23+ OBJS += windows/idris_net.o windows/win_utils.o
2324else
2425 CFLAGS += -fPIC
25− OBJS += idris_stdfgn.o idris_net.o
26+ OBJS += idris_net.o
2627endif
2728
2829LIBTARGET = libidris_rts.a
rts/idris_gmp.c+106
@@ -196,6 +196,88 @@ VAL bigMod(VM* vm, VAL x, VAL y) {
196196 return cl;
197197}
198198
199+VAL bigAnd(VM* vm, VAL x, VAL y) {
200+ idris_requireAlloc(IDRIS_MAXGMP);
201+
202+ mpz_t* bigint;
203+ VAL cl = allocate(sizeof(Closure) + sizeof(mpz_t), 0);
204+ idris_doneAlloc();
205+ bigint = (mpz_t*)(((char*)cl) + sizeof(Closure));
206+ mpz_and(*bigint, GETMPZ(GETBIG(vm,x)), GETMPZ(GETBIG(vm,y)));
207+ SETTY(cl, BIGINT);
208+ cl -> info.ptr = (void*)bigint;
209+ return cl;
210+}
211+
212+VAL bigOr(VM* vm, VAL x, VAL y) {
213+ idris_requireAlloc(IDRIS_MAXGMP);
214+
215+ mpz_t* bigint;
216+ VAL cl = allocate(sizeof(Closure) + sizeof(mpz_t), 0);
217+ idris_doneAlloc();
218+ bigint = (mpz_t*)(((char*)cl) + sizeof(Closure));
219+ mpz_ior(*bigint, GETMPZ(GETBIG(vm,x)), GETMPZ(GETBIG(vm,y)));
220+ SETTY(cl, BIGINT);
221+ cl -> info.ptr = (void*)bigint;
222+ return cl;
223+}
224+
225+VAL bigShiftLeft(VM* vm, VAL x, VAL y) {
226+ idris_requireAlloc(IDRIS_MAXGMP);
227+
228+ mpz_t* bigint;
229+ VAL cl = allocate(sizeof(Closure) + sizeof(mpz_t), 0);
230+ idris_doneAlloc();
231+ bigint = (mpz_t*)(((char*)cl) + sizeof(Closure));
232+ mpz_mul_2exp(*bigint, GETMPZ(GETBIG(vm,x)), GETINT(y));
233+ SETTY(cl, BIGINT);
234+ cl -> info.ptr = (void*)bigint;
235+ return cl;
236+}
237+
238+
239+VAL bigLShiftRight(VM* vm, VAL x, VAL y) {
240+ idris_requireAlloc(IDRIS_MAXGMP);
241+
242+ mpz_t* bigint;
243+ VAL cl = allocate(sizeof(Closure) + sizeof(mpz_t), 0);
244+ idris_doneAlloc();
245+ bigint = (mpz_t*)(((char*)cl) + sizeof(Closure));
246+ mpz_fdiv_q_2exp(*bigint, GETMPZ(GETBIG(vm,x)), GETINT(y));
247+ SETTY(cl, BIGINT);
248+ cl -> info.ptr = (void*)bigint;
249+ return cl;
250+}
251+
252+VAL bigAShiftRight(VM* vm, VAL x, VAL y) {
253+ idris_requireAlloc(IDRIS_MAXGMP);
254+
255+ mpz_t* bigint;
256+ VAL cl = allocate(sizeof(Closure) + sizeof(mpz_t), 0);
257+ idris_doneAlloc();
258+ bigint = (mpz_t*)(((char*)cl) + sizeof(Closure));
259+ mpz_fdiv_q_2exp(*bigint, GETMPZ(GETBIG(vm,x)), GETINT(y));
260+ SETTY(cl, BIGINT);
261+ cl -> info.ptr = (void*)bigint;
262+ return cl;
263+}
264+
265+VAL idris_bigAnd(VM* vm, VAL x, VAL y) {
266+ if (ISINT(x) && ISINT(y)) {
267+ return INTOP(&, x, y);
268+ } else {
269+ return bigAnd(vm, GETBIG(vm, x), GETBIG(vm, y));
270+ }
271+}
272+
273+VAL idris_bigOr(VM* vm, VAL x, VAL y) {
274+ if (ISINT(x) && ISINT(y)) {
275+ return INTOP(|, x, y);
276+ } else {
277+ return bigOr(vm, GETBIG(vm, x), GETBIG(vm, y));
278+ }
279+}
280+
199281VAL idris_bigPlus(VM* vm, VAL x, VAL y) {
200282 if (ISINT(x) && ISINT(y)) {
201283 i_int vx = GETINT(x);
@@ -253,6 +335,30 @@ VAL idris_bigTimes(VM* vm, VAL x, VAL y) {
253335 }
254336}
255337
338+VAL idris_bigShiftLeft(VM* vm, VAL x, VAL y) {
339+ if (ISINT(x) && ISINT(y)) {
340+ return INTOP(<<, x, y);
341+ } else {
342+ return bigShiftLeft(vm, GETBIG(vm, x), GETBIG(vm, y));
343+ }
344+}
345+
346+VAL idris_bigAShiftRight(VM* vm, VAL x, VAL y) {
347+ if (ISINT(x) && ISINT(y)) {
348+ return INTOP(>>, x, y);
349+ } else {
350+ return bigAShiftRight(vm, GETBIG(vm, x), GETBIG(vm, y));
351+ }
352+}
353+
354+VAL idris_bigLShiftRight(VM* vm, VAL x, VAL y) {
355+ if (ISINT(x) && ISINT(y)) {
356+ return INTOP(>>, x, y);
357+ } else {
358+ return bigLShiftRight(vm, GETBIG(vm, x), GETBIG(vm, y));
359+ }
360+}
361+
256362VAL idris_bigDivide(VM* vm, VAL x, VAL y) {
257363 if (ISINT(x) && ISINT(y)) {
258364 return INTOP(/, x, y);
rts/idris_gmp.h+5
@@ -38,6 +38,11 @@ VAL idris_castBigFloat(VM* vm, VAL i);
3838VAL idris_castStrBig(VM* vm, VAL i);
3939VAL idris_castBigStr(VM* vm, VAL i);
4040
41+VAL idris_bigAnd(VM* vm, VAL x, VAL y);
42+VAL idris_bigOr(VM* vm, VAL x, VAL y);
43+VAL idris_bigShiftLeft(VM* vm, VAL x, VAL y);
44+VAL idris_bigShiftRight(VM* vm, VAL x, VAL y);
45+
4146#define GETMPZ(x) *((mpz_t*)((x)->info.ptr))
4247
4348#endif
rts/idris_heap.c+12−12
@@ -7,11 +7,11 @@
77
88
99/* Used for initializing the heap. */
10−void alloc_heap(Heap * h, size_t heap_size, size_t growth, char * old)
10+void alloc_heap(Heap * h, size_t heap_size, size_t growth, char * old)
1111{
12− char * mem = malloc(heap_size);
12+ char * mem = malloc(heap_size);
1313 if (mem == NULL) {
14− fprintf(stderr,
14+ fprintf(stderr,
1515 "RTS ERROR: Unable to allocate heap. Requested %zd bytes.\n",
1616 heap_size);
1717 exit(EXIT_FAILURE);
@@ -37,8 +37,8 @@ void alloc_heap(Heap * h, size_t heap_size, size_t growth, char * old)
3737void free_heap(Heap * h) {
3838 free(h->heap);
3939
40− if (h->old != NULL) {
41− free(h->old);
40+ if (h->old != NULL) {
41+ free(h->old);
4242 }
4343}
4444
@@ -47,7 +47,7 @@ void free_heap(Heap * h) {
4747/******************** Heap testing ********************************************/
4848void heap_check_underflow(Heap * heap) {
4949 if (!(heap->heap <= heap->next)) {
50− fprintf(stderr, "RTS ERROR: HEAP UNDERFLOW <bot %p> <cur %p>\n",
50+ fprintf(stderr, "RTS ERROR: HEAP UNDERFLOW <bot %p> <cur %p>\n",
5151 heap->heap, heap->next);
5252 exit(EXIT_FAILURE);
5353 }
@@ -55,7 +55,7 @@ void heap_check_underflow(Heap * heap) {
5555
5656void heap_check_overflow(Heap * heap) {
5757 if (!(heap->next <= heap->end)) {
58− fprintf(stderr, "RTS ERROR: HEAP OVERFLOW <cur %p> <end %p>\n",
58+ fprintf(stderr, "RTS ERROR: HEAP OVERFLOW <cur %p> <end %p>\n",
5959 heap->next, heap->end);
6060 exit(EXIT_FAILURE);
6161 }
@@ -65,13 +65,13 @@ int is_valid_ref(VAL v) {
6565 return (v != NULL) && !(ISINT(v));
6666}
6767
68−int ref_in_heap(Heap * heap, VAL v) {
68+int ref_in_heap(Heap * heap, VAL v) {
6969 return ((VAL)heap->heap <= v) && (v < (VAL)heap->next);
7070}
7171
7272// Checks three important properties:
7373// 1. Closure.
74−// Check if all pointers in the _heap_ points only to heap.
74+// Check if all pointers in the _heap_ points only to heap.
7575// 2. Unidirectionality. (if compact gc)
7676// All references in the heap should be are unidirectional. In other words,
7777// more recently allocated closure can point only to earlier allocated one.
@@ -79,7 +79,7 @@ int ref_in_heap(Heap * heap, VAL v) {
7979//
8080void heap_check_pointers(Heap * heap) {
8181 char* scan = NULL;
82−
82+
8383 size_t item_size = 0;
8484 for(scan = heap->heap; scan < heap->next; scan += item_size) {
8585 item_size = *((size_t*)scan);
@@ -96,7 +96,7 @@ void heap_check_pointers(Heap * heap) {
9696 if (is_valid_ref(ptr)) {
9797 // Check for closure.
9898 if (!ref_in_heap(heap, ptr)) {
99− fprintf(stderr,
99+ fprintf(stderr,
100100 "RTS ERROR: heap closure broken. "\
101101 "<HEAP %p %p %p> <REF %p>\n",
102102 heap->heap, heap->next, heap->end, ptr);
@@ -105,7 +105,7 @@ void heap_check_pointers(Heap * heap) {
105105#if 0 // TODO macro
106106 // Check for unidirectionality.
107107 if (!(ptr < heap_item)) {
108− fprintf(stderr,
108+ fprintf(stderr,
109109 "RTS ERROR: heap unidirectionality broken:" \
110110 "<CON %p> <FIELD %p>\n",
111111 heap_item, ptr);
rts/idris_heap.h+2−2
@@ -8,7 +8,7 @@ typedef struct {
88 char* heap; // Point to bottom of heap
99 char* end; // Point to top of heap
1010 size_t size; // Size of _next_ heap. Size of current heap is /end - heap/.
11− size_t growth; // Quantity of heap growth in bytes.
11+ size_t growth; // Quantity of heap growth in bytes.
1212
1313 char* old;
1414} Heap;
@@ -23,7 +23,7 @@ void heap_check_all(Heap * heap);
2323// Should be used _between_ gc's.
2424#define HEAP_CHECK(vm) heap_check_all(&(vm->heap));
2525#else
26−#define HEAP_CHECK(vm)
26+#define HEAP_CHECK(vm)
2727#endif // IDRIS_DEBUG
2828
2929#endif // _IDRIS_HEAP_H
rts/idris_main.c+1
@@ -21,6 +21,7 @@ int main(int argc, char* argv[]) {
2121 init_gmpalloc();
2222
2323 init_nullaries();
24+ init_signals();
2425
2526 _idris__123_runMain0_125_(vm, NULL);
2627
rts/idris_net.c+21−24
@@ -38,15 +38,15 @@ void idrnet_free(void* ptr) {
3838}
3939
4040// We call this from quite a few functions. Given a textual host and an int port,
41−// populates a struct addrinfo.
42−int idrnet_getaddrinfo(struct addrinfo** address_res, char* host, int port,
41+// populates a struct addrinfo.
42+int idrnet_getaddrinfo(struct addrinfo** address_res, char* host, int port,
4343 int family, int socket_type) {
4444
4545 struct addrinfo hints;
4646 // Convert port into string
4747 char str_port[8];
4848 sprintf(str_port, "%d", port);
49−
49+
5050 // Set up hints structure
5151 memset(&hints, 0, sizeof(hints)); // zero out hints
5252 hints.ai_family = family;
@@ -57,7 +57,7 @@ int idrnet_getaddrinfo(struct addrinfo** address_res, char* host, int port,
5757 if (strlen(host) == 0) {
5858 hints.ai_flags = AI_PASSIVE; // fill in IP automatically
5959 return getaddrinfo(NULL, str_port, &hints, address_res);
60− }
60+ }
6161 return getaddrinfo(host, str_port, &hints, address_res);
6262
6363}
@@ -75,7 +75,7 @@ int idrnet_bind(int sockfd, int family, int socket_type, char* host, int port) {
7575 //freeaddrinfo(address_res);
7676 //printf("Lib err: bind\n");
7777 return -1;
78− }
78+ }
7979 return 0;
8080}
8181
@@ -111,7 +111,7 @@ char* idrnet_sockaddr_ipv4(void* sockaddr) {
111111
112112int idrnet_sockaddr_ipv4_port(void* sockaddr) {
113113 struct sockaddr_in* addr = (struct sockaddr_in*) sockaddr;
114− return ((int) ntohs(addr->sin_port));
114+ return ((int) ntohs(addr->sin_port));
115115}
116116
117117void* idrnet_create_sockaddr() {
@@ -141,13 +141,13 @@ int idrnet_send_buf(int sockfd, void* data, int len) {
141141}
142142
143143void* idrnet_recv(int sockfd, int len) {
144− idrnet_recv_result* res_struct =
144+ idrnet_recv_result* res_struct =
145145 (idrnet_recv_result*) malloc(sizeof(idrnet_recv_result));
146146 char* buf = malloc(len + 1);
147147 memset(buf, 0, len + 1);
148148 int recv_res = recv(sockfd, buf, len, 0);
149149 res_struct->result = recv_res;
150−
150+
151151 if (recv_res > 0) { // Data was received
152152 buf[recv_res + 1] = 0x00; // Null-term, so Idris can interpret it
153153 }
@@ -172,7 +172,7 @@ char* idrnet_get_recv_payload(void* res_struct) {
172172}
173173
174174void idrnet_free_recv_struct(void* res_struct) {
175− idrnet_recv_result* i_res_struct =
175+ idrnet_recv_result* i_res_struct =
176176 (idrnet_recv_result*) res_struct;
177177 if (i_res_struct->payload != NULL) {
178178 free(i_res_struct->payload);
@@ -191,9 +191,9 @@ int idrnet_sendto(int sockfd, char* data, char* host, int port, int family) {
191191 int addr_res = idrnet_getaddrinfo(&remote_host, host, port, family, SOCK_DGRAM);
192192 if (addr_res == -1) {
193193 return -1;
194− }
194+ }
195195
196− int send_res = sendto(sockfd, data, strlen(data), 0,
196+ int send_res = sendto(sockfd, data, strlen(data), 0,
197197 remote_host->ai_addr, remote_host->ai_addrlen);
198198 freeaddrinfo(remote_host);
199199 return send_res;
@@ -206,11 +206,11 @@ int idrnet_sendto_buf(int sockfd, void* buf, int buf_len, char* host, int port,
206206 if (addr_res == -1) {
207207 //printf("lib err: sendto getaddrinfo \n");
208208 return -1;
209− }
209+ }
210210
211211 buf_htonl(buf, buf_len);
212212
213− int send_res = sendto(sockfd, buf, buf_len, 0,
213+ int send_res = sendto(sockfd, buf, buf_len, 0,
214214 remote_host->ai_addr, remote_host->ai_addrlen);
215215 if (send_res == -1) {
216216 perror("lib err: sendto \n");
@@ -224,13 +224,13 @@ int idrnet_sendto_buf(int sockfd, void* buf, int buf_len, char* host, int port,
224224void* idrnet_recvfrom(int sockfd, int len) {
225225/*
226226 * int recvfrom(int sockfd, void *buf, int len, unsigned int flags,
227− struct sockaddr *from, int *fromlen);
227+ struct sockaddr *from, int *fromlen);
228228*/
229229 // Allocate the required structures, and nuke them
230− struct sockaddr_storage* remote_addr =
230+ struct sockaddr_storage* remote_addr =
231231 (struct sockaddr_storage*) malloc(sizeof(struct sockaddr_storage));
232232 char* buf = (char*) malloc(len + 1);
233− idrnet_recvfrom_result* ret =
233+ idrnet_recvfrom_result* ret =
234234 (idrnet_recvfrom_result*) malloc(sizeof(idrnet_recvfrom_result));
235235 memset(remote_addr, 0, sizeof(struct sockaddr_storage));
236236 memset(buf, 0, len + 1);
@@ -240,7 +240,7 @@ void* idrnet_recvfrom(int sockfd, int len) {
240240 int recv_res = recvfrom(sockfd, buf, len, 0, (struct sockaddr*) remote_addr, &fromlen);
241241 ret->result = recv_res;
242242 // Check for failure...
243− if (recv_res == -1) {
243+ if (recv_res == -1) {
244244 free(buf);
245245 free(remote_addr);
246246 } else {
@@ -255,12 +255,11 @@ void* idrnet_recvfrom(int sockfd, int len) {
255255 return ret;
256256}
257257
258−
259258void* idrnet_recvfrom_buf(int sockfd, void* buf, int len) {
260259 // Allocate the required structures, and nuke them
261− struct sockaddr_storage* remote_addr =
260+ struct sockaddr_storage* remote_addr =
262261 (struct sockaddr_storage*) malloc(sizeof(struct sockaddr_storage));
263− idrnet_recvfrom_result* ret =
262+ idrnet_recvfrom_result* ret =
264263 (idrnet_recvfrom_result*) malloc(sizeof(idrnet_recvfrom_result));
265264 memset(remote_addr, 0, sizeof(struct sockaddr_storage));
266265 memset(ret, 0, sizeof(idrnet_recvfrom_result));
@@ -269,7 +268,7 @@ void* idrnet_recvfrom_buf(int sockfd, void* buf, int len) {
269268 int recv_res = recvfrom(sockfd, buf, len, 0, (struct sockaddr*) remote_addr, &fromlen);
270269 // Check for failure... But don't free the buffer! Not our job.
271270 ret->result = recv_res;
272− if (recv_res == -1) {
271+ if (recv_res == -1) {
273272 free(remote_addr);
274273 }
275274 // Payload will be NULL -- since it's been put into the user-specified buffer. We
@@ -298,7 +297,7 @@ void* idrnet_get_recvfrom_sockaddr(void* res_struct) {
298297int idrnet_get_recvfrom_port(void* res_struct) {
299298 idrnet_recvfrom_result* recv_struct = (idrnet_recvfrom_result*) res_struct;
300299 if (recv_struct->remote_addr != NULL) {
301− struct sockaddr_in* remote_addr_in =
300+ struct sockaddr_in* remote_addr_in =
302301 (struct sockaddr_in*) recv_struct->remote_addr;
303302 return ((int) ntohs(remote_addr_in->sin_port));
304303 }
@@ -316,5 +315,3 @@ void idrnet_free_recvfrom_struct(void* res_struct) {
316315 }
317316 }
318317}
319−
320−
rts/idris_rts.c+16
@@ -1,4 +1,5 @@
11#include <assert.h>
2+#include <errno.h>
23
34#include "idris_rts.h"
45#include "idris_gc.h"
@@ -72,6 +73,7 @@ VM* idris_vm() {
7273 init_threaddata(vm);
7374 init_gmpalloc();
7475 init_nullaries();
76+ init_signals();
7577
7678 return vm;
7779}
@@ -92,6 +94,12 @@ void init_threaddata(VM *vm) {
9294#endif
9395}
9496
97+void init_signals() {
98+#if (__linux__ || __APPLE__ || __FreeBSD__)
99+ signal(SIGPIPE, SIG_IGN);
100+#endif
101+}
102+
95103Stats terminate(VM* vm) {
96104 Stats stats = vm->stats;
97105 STATS_ENTER_EXIT(stats)
@@ -927,6 +935,14 @@ void idris_freeMsg(Msg* msg) {
927935 free(msg);
928936}
929937
938+int idris_errno() {
939+ return errno;
940+}
941+
942+char* idris_showerror(int err) {
943+ return strerror(err);
944+}
945+
930946VAL* nullary_cons;
931947
932948void init_nullaries() {
rts/idris_rts.h+8
@@ -9,6 +9,9 @@
99#include <pthread.h>
1010#endif
1111#include <stdint.h>
12+#if (__linux__ || __APPLE__ || __FreeBSD__)
13+#include <signal.h>
14+#endif
1215
1316#include "idris_heap.h"
1417#include "idris_stats.h"
@@ -252,10 +255,15 @@ void idris_free(void* ptr, size_t size);
252255
253256#define NULL_CON(x) nullary_cons[x]
254257
258+int idris_errno();
259+char* idris_showerror(int err);
260+
255261extern VAL* nullary_cons;
256262void init_nullaries();
257263void free_nullaries();
258264
265+void init_signals();
266+
259267void* vmThread(VM* callvm, func f, VAL arg);
260268
261269// Copy a structure to another vm's heap
rts/idris_stdfgn.c+36−6
@@ -2,11 +2,18 @@
22#include "idris_rts.h"
33#include "idris_gmp.h"
44#include "idris_gc.h"
5−#include <sys/select.h>
5+
66#include <fcntl.h>
7+#include <errno.h>
78#include <stdio.h>
89#include <time.h>
910
11+#if defined(WIN32) || defined(__WIN32) || defined(__WIN32__)
12+int win_fpoll(void* h);
13+#else
14+#include <sys/select.h>
15+#endif
16+
1017extern char** environ;
1118
1219void putStr(char* str) {
@@ -24,13 +31,13 @@ void fileClose(void* h) {
2431}
2532
2633int fileEOF(void* h) {
27− FILE* f = (FILE*)h;
28− return feof(f);
34+ FILE* f = (FILE*)h;
35+ return feof(f);
2936}
3037
3138int fileError(void* h) {
32− FILE* f = (FILE*)h;
33− return ferror(f);
39+ FILE* f = (FILE*)h;
40+ return ferror(f);
3441}
3542
3643int idris_writeStr(void* h, char* str) {
@@ -44,6 +51,9 @@ int idris_writeStr(void* h, char* str) {
4451
4552int fpoll(void* h)
4653{
54+#if defined(WIN32) || defined(__WIN32) || defined(__WIN32__)
55+ return win_fpoll(h);
56+#else
4757 FILE* f = (FILE*)h;
4858 fd_set x;
4959 struct timeval timeout;
@@ -56,6 +66,7 @@ int fpoll(void* h)
5666
5767 int r = select(fd+1, &x, 0, 0, &timeout);
5868 return r;
69+#endif
5970}
6071
6172void* do_popen(const char* cmd, const char* mode) {
@@ -86,6 +97,25 @@ VAL idris_time() {
8697 return MKBIGI(t);
8798}
8899
100+VAL idris_mkFileError(VM* vm) {
101+ VAL result;
102+ switch(errno) {
103+ // Make sure this corresponds to the FileError structure in
104+ // Prelude.File
105+ case ENOENT:
106+ idris_constructor(result, vm, 2, 0, 0);
107+ break;
108+ case EACCES:
109+ idris_constructor(result, vm, 3, 0, 0);
110+ break;
111+ default:
112+ idris_constructor(result, vm, 4, 1, 0);
113+ idris_setConArg(result, 0, MKINT((intptr_t)errno));
114+ break;
115+ }
116+ return result;
117+}
118+
89119void idris_forceGC(void* vm) {
90− idris_gc((VM*)vm);
120+ idris_gc((VM*)vm);
91121}
rts/idris_stdfgn.h+2
@@ -14,6 +14,8 @@ int fileEOF(void* h);
1414int fileError(void* h);
1515// return 0 on success
1616int idris_writeStr(void*h, char* str);
17+// construct a file error structure (see Prelude.File) from errno
18+VAL idris_mkFileError(VM* vm);
1719
1820void* do_popen(const char* cmd, const char* mode);
1921int fpoll(void* h);
rts/windows/idris_net.c+6−7
@@ -12,7 +12,7 @@
1212#include <Ws2tcpip.h>
1313
1414
15−// inet_ntop isn't defined in the old mingw delivered with GHC,
15+// inet_ntop isn't defined in the old mingw delivered with GHC,
1616// so put the prototype here, cribbed from a newer version of it
1717WINSOCK_API_LINKAGE LPCSTR WSAAPI InetNtopA(INT Family, PVOID pAddr,
1818 LPSTR pStringBuf, size_t StringBufSize);
@@ -50,7 +50,7 @@ int idrnet_bind(int sockfd, int family, int socket_type, char* host, int port) {
5050 // Convert port into string
5151 char str_port[8];
5252 sprintf(str_port, "%d", port);
53−
53+
5454 if (!check_init()) {
5555 return -1;
5656 }
@@ -73,7 +73,7 @@ int idrnet_bind(int sockfd, int family, int socket_type, char* host, int port) {
7373 int bind_res = bind(sockfd, address_res->ai_addr, address_res->ai_addrlen);
7474 if (bind_res == -1) {
7575 return -1;
76− }
76+ }
7777
7878 return 0;
7979}
@@ -152,13 +152,13 @@ void* idrnet_recv(int sockfd, int len) {
152152 if (!check_init()) {
153153 return NULL;
154154 }
155− idrnet_recv_result* res_struct =
155+ idrnet_recv_result* res_struct =
156156 (idrnet_recv_result*) malloc(sizeof(idrnet_recv_result));
157157
158158 char* buf = malloc(len + 1);
159159 int recv_res = recv(sockfd, buf, len, 0);
160160 res_struct->result = recv_res;
161−
161+
162162 if (recv_res > 0) { // Data was received
163163 buf[recv_res + 1] = 0x00; // Null-term, so Idris can interpret it
164164 }
@@ -182,7 +182,7 @@ char* idrnet_get_recv_payload(void* res_struct) {
182182}
183183
184184void idrnet_free_recv_struct(void* res_struct) {
185− idrnet_recv_result* i_res_struct =
185+ idrnet_recv_result* i_res_struct =
186186 (idrnet_recv_result*) res_struct;
187187 if (i_res_struct->payload != NULL) {
188188 free(i_res_struct->payload);
@@ -193,4 +193,3 @@ void idrnet_free_recv_struct(void* res_struct) {
193193int idrnet_errno() {
194194 return errno;
195195}
196−
rts/windows/idris_stdfgn.cdeleted−82
@@ -1,82 +0,0 @@
1−#include "../idris_stdfgn.h"
2−#include "../idris_rts.h"
3−#include "../idris_gc.h"
4−
5−#include <fcntl.h>
6−#include <stdio.h>
7−#include <time.h>
8−#include <io.h>
9−
10−extern char** environ;
11−
12−int win_fpoll(void* h);
13−
14−void putStr(char* str) {
15− printf("%s", str);
16−}
17−
18−void* fileOpen(char* name, char* mode) {
19− FILE* f = fopen(name, mode);
20− return (void*)f;
21−}
22−
23−void fileClose(void* h) {
24− FILE* f = (FILE*)h;
25− fclose(f);
26−}
27−
28−int fileEOF(void* h) {
29− FILE* f = (FILE*)h;
30− return feof(f);
31−}
32−
33−int fileError(void* h) {
34− FILE* f = (FILE*)h;
35− return ferror(f);
36−}
37−
38−int idris_writeStr(void* h, char* str) {
39− FILE* f = (FILE*)h;
40− if (fputs(str, f)) {
41− return 0;
42− } else {
43− return -1;
44− }
45−}
46−
47−int fpoll(void* h)
48−{
49− return win_fpoll(h);
50−}
51−
52−void* do_popen(const char* cmd, const char* mode) {
53− FILE* f = _popen(cmd, mode);
54−// int d = fileno(f);
55−// fcntl(d, F_SETFL, O_NONBLOCK);
56− return f;
57−}
58−
59−int isNull(void* ptr) {
60− return ptr==NULL;
61−}
62−
63−int idris_eqPtr(void* x, void* y) {
64− return x==y;
65−}
66−
67−void* idris_stdin() {
68− return (void*)stdin;
69−}
70−
71−char* getEnvPair(int i) {
72− return *(environ + i);
73−}
74−
75−VAL idris_time() {
76− time_t t = time(NULL);
77− return MKBIGI(t);
78−}
79−
80−void idris_forceGC(void* vm) {
81− idris_gc((VM*)vm);
82−}
src/IRTS/CodegenC.hs+8−3
@@ -66,7 +66,7 @@ codegenC' defs out exec incs objs libs flags exports iface dbg
6666 MavenProject -> putStrLn ("FAILURE: output type not supported")
6767 Raw -> writeSource out cout
6868 _ -> do
69− (tmpn, tmph) <- tempfile
69+ (tmpn, tmph) <- tempfile ".c"
7070 hPutStr tmph cout
7171 hFlush tmph
7272 hClose tmph
@@ -78,7 +78,7 @@ codegenC' defs out exec incs objs libs flags exports iface dbg
7878 gccFlags iface ++
7979 -- # Any flags defined here which alter the RTS API must also be added to config.mk
8080 ["-DHAS_PTHREAD", "-DIDRIS_ENABLE_STATS",
81− "-I."] ++ objs ++ ["-x", "c"] ++ envFlags ++
81+ "-I."] ++ objs ++ envFlags ++
8282 (if (exec == Executable) then [] else ["-c"]) ++
8383 [tmpn] ++
8484 (if not iface then concatMap words libFlags else []) ++
@@ -95,7 +95,7 @@ codegenC' defs out exec incs objs libs flags exports iface dbg
9595
9696headers xs =
9797 concatMap
98− (\h -> "#include <" ++ h ++ ">\n")
98+ (\h -> "#include \"" ++ h ++ "\"\n")
9999 (xs ++ ["idris_rts.h", "idris_bitstring.h", "idris_stdfgn.h"])
100100
101101debug TRACE = "#define IDRIS_TRACE\n\n"
@@ -444,6 +444,11 @@ doOp v (LMinus (ATInt ITBig)) [l, r] = v ++ "idris_bigMinus(vm, " ++ creg l ++ "
444444doOp v (LTimes (ATInt ITBig)) [l, r] = v ++ "idris_bigTimes(vm, " ++ creg l ++ ", " ++ creg r ++ ")"
445445doOp v (LSDiv (ATInt ITBig)) [l, r] = v ++ "idris_bigDivide(vm, " ++ creg l ++ ", " ++ creg r ++ ")"
446446doOp v (LSRem (ATInt ITBig)) [l, r] = v ++ "idris_bigMod(vm, " ++ creg l ++ ", " ++ creg r ++ ")"
447+doOp v (LAnd ITBig) [l, r] = v ++ "idris_bigAnd(vm, " ++ creg l ++ ", " ++ creg r ++ ")"
448+doOp v (LOr ITBig) [l, r] = v ++ "idris_bigOr(vm, " ++ creg l ++ ", " ++ creg r ++ ")"
449+doOp v (LSHL ITBig) [l, r] = v ++ "idris_bigShiftLeft(vm, " ++ creg l ++ ", " ++ creg r ++ ")"
450+doOp v (LLSHR ITBig) [l, r] = v ++ "idris_bigLShiftRight(vm, " ++ creg l ++ ", " ++ creg r ++ ")"
451+doOp v (LASHR ITBig) [l, r] = v ++ "idris_bigAShiftRight(vm, " ++ creg l ++ ", " ++ creg r ++ ")"
447452doOp v (LEq (ATInt ITBig)) [l, r] = v ++ "idris_bigEq(vm, " ++ creg l ++ ", " ++ creg r ++ ")"
448453doOp v (LSLt (ATInt ITBig)) [l, r] = v ++ "idris_bigLt(vm, " ++ creg l ++ ", " ++ creg r ++ ")"
449454doOp v (LSLe (ATInt ITBig)) [l, r] = v ++ "idris_bigLe(vm, " ++ creg l ++ ", " ++ creg r ++ ")"
src/IRTS/CodegenJavaScript.hs+1−2
@@ -604,7 +604,7 @@ jsBASETOP _ 0 = JSAssign jsSTACKBASE jsSTACKTOP
604604jsBASETOP _ n = JSAssign jsSTACKBASE (JSBinOp "+" jsSTACKTOP (JSNum (JSInt n)))
605605
606606jsNULL :: CompileInfo -> Reg -> JS
607−jsNULL _ r = JSDelete (translateReg r)
607+jsNULL _ r = JSClear (translateReg r)
608608
609609jsERROR :: CompileInfo -> String -> JS
610610jsERROR _ = JSError
@@ -1277,4 +1277,3 @@ toFType (FApp c [_,ity])
12771277toFType (FApp c [_,fty])
12781278 | c == sUN "JS_FnT" = toFnType fty
12791279toFType t = error (show t ++ " not yet defined in toFType")
1280−
src/IRTS/Compiler.hs+20−20
@@ -54,12 +54,12 @@ compile codegen f mtm
5454 Nothing -> []
5555 Just t -> freeNames t
5656
57− reachableNames <- performUsageAnalysis
57+ reachableNames <- performUsageAnalysis
5858 (rootNames ++ getExpNames exports)
5959 maindef <- case mtm of
6060 Nothing -> return []
6161 Just tm -> do md <- irMain tm
62− logLvl 1 $ "MAIN: " ++ show md
62+ logCodeGen 1 $ "MAIN: " ++ show md
6363 return [(sMN 0 "runMain", md)]
6464 objs <- getObjectFiles codegen
6565 libs <- getLibs codegen
@@ -82,13 +82,13 @@ compile codegen f mtm
8282 let (nexttag, tagged) = addTags 65536 (liftAll defsUniq)
8383 let ctxtIn = addAlist tagged emptyContext
8484
85− logLvl 1 "Defunctionalising"
85+ logCodeGen 1 "Defunctionalising"
8686 let defuns_in = defunctionalise nexttag ctxtIn
87− logLvl 5 $ show defuns_in
88− logLvl 1 "Inlining"
87+ logCodeGen 5 $ show defuns_in
88+ logCodeGen 1 "Inlining"
8989 let defuns = inline defuns_in
90− logLvl 5 $ show defuns
91− logLvl 1 "Resolving variables for CG"
90+ logCodeGen 5 $ show defuns
91+ logCodeGen 1 "Resolving variables for CG"
9292
9393 let checked = simplifyDefs defuns (toAlist defuns)
9494 outty <- outputTy
@@ -102,7 +102,7 @@ compile codegen f mtm
102102 Just f -> runIO $ writeFile f (dumpDefuns defuns)
103103 triple <- Idris.AbsSyntax.targetTriple
104104 cpu <- Idris.AbsSyntax.targetCPU
105− logLvl 1 "Building output"
105+ logCodeGen 1 "Building output"
106106 case checked of
107107 OK c -> do return $ CodegenInfo f outty triple cpu
108108 hdrs impdirs objs libs flags
@@ -167,7 +167,7 @@ showCaseTrees = showSep "\n\n" . map showCT . sortBy (comparing defnRank)
167167 snRank (InstanceN n args) = "2" ++ nameRank n ++ concatMap show args
168168 snRank (ParentN n s) = "3" ++ nameRank n ++ show s
169169 snRank (MethodN n) = "4" ++ nameRank n
170− snRank (CaseN n) = "5" ++ nameRank n
170+ snRank (CaseN _ n) = "5" ++ nameRank n
171171 snRank (ElimN n) = "6" ++ nameRank n
172172 snRank (InstanceCtorN n) = "7" ++ nameRank n
173173 snRank (WithN i n) = "8" ++ nameRank n ++ show i
@@ -184,10 +184,10 @@ build (n, d)
184184 return (n, (LFun [] n (take ar args)
185185 (LOp op (map (LV . Glob) (take ar args)))))
186186 _ -> do def <- mkLDecl n d
187− logLvl 3 $ "Compiled " ++ show n ++ " =\n\t" ++ show def
187+ logCodeGen 3 $ "Compiled " ++ show n ++ " =\n\t" ++ show def
188188 return (n, def)
189− where getPrim n i
190− | Just (ar, op) <- lookup n (idris_scprims i)
189+ where getPrim n i
190+ | Just (ar, op) <- lookup n (idris_scprims i)
191191 = Just (ar, op)
192192 | Just ar <- lookup n (S.toList (idris_externs i))
193193 = Just (ar, LExternal n)
@@ -205,7 +205,7 @@ mkLDecl n (CaseOp ci _ _ _ pats cd)
205205 (args, sc) = cases_runtime cd
206206
207207 -- Always attempt to inline functions arising from 'case' expressions
208− caseName (SN (CaseN _)) = True
208+ caseName (SN (CaseN _ _)) = True
209209 caseName (SN (WithN _ _)) = True
210210 caseName (NS n _) = caseName n
211211 caseName _ = False
@@ -224,7 +224,7 @@ data VarInfo = VI
224224type Vars = M.Map Name VarInfo
225225
226226irTerm :: Vars -> [Name] -> Term -> Idris LExp
227−irTerm vs env tm@(App _ f a) = do
227+irTerm vs env tm@(App _ f a) = do
228228 ist <- getIState
229229 case unApply tm of
230230 (P _ (UN m) _, args)
@@ -454,19 +454,19 @@ irTerm vs env Impossible = return $ LNothing
454454doForeign :: Vars -> [Name] -> [Term] -> Idris LExp
455455doForeign vs env (ret : fname : world : args)
456456 = do args' <- mapM splitArg args
457− let fname' = toFDesc fname
457+ let fname' = toFDesc fname
458458 let ret' = toFDesc ret
459459 return $ LForeign ret' fname' args'
460460 where
461461 splitArg tm | (_, [_,_,l,r]) <- unApply tm -- pair, two implicits
462− = do let l' = toFDesc l
462+ = do let l' = toFDesc l
463463 r' <- irTerm vs env r
464464 return (l', r')
465465 splitArg _ = ifail "Badly formed foreign function call"
466466
467− toFDesc (Constant (Str str)) = FStr str
468− toFDesc tm
469− | (P _ n _, []) <- unApply tm = FCon (deNS n)
467+ toFDesc (Constant (Str str)) = FStr str
468+ toFDesc tm
469+ | (P _ n _, []) <- unApply tm = FCon (deNS n)
470470 | (P _ n _, as) <- unApply tm = FApp (deNS n) (map toFDesc as)
471471 toFDesc _ = FUnknown
472472
@@ -476,7 +476,7 @@ doForeign vs env xs = ifail "Badly formed foreign function call"
476476
477477irTree :: [Name] -> SC -> Idris LExp
478478irTree args tree = do
479− logLvl 3 $ "Compiling " ++ show args ++ "\n" ++ show tree
479+ logCodeGen 3 $ "Compiling " ++ show args ++ "\n" ++ show tree
480480 LLam args <$> irSC M.empty tree
481481
482482irSC :: Vars -> SC -> Idris LExp
src/IRTS/Exports.hs+8−11
@@ -13,7 +13,7 @@ import Data.Maybe
1313findExports :: Idris [ExportIFace]
1414findExports = do exps <- getExports
1515 es <- mapM toIFace exps
16− logLvl 2 $ "Exporting " ++ show es
16+ logCodeGen 2 $ "Exporting " ++ show es
1717 return es
1818
1919getExpNames :: [ExportIFace] -> [Name]
@@ -39,7 +39,7 @@ toIFace n = do i <- getIState
3939 getExpList _ = ifail "Badly formed export list"
4040
4141toIFaceTyVal :: Type -> Term -> Idris ExportIFace
42−toIFaceTyVal ty tm
42+toIFaceTyVal ty tm
4343 | (P _ exp _, [P _ ffi _, Constant (Str hdr), _]) <- unApply ty
4444 = do tm' <- toIFaceVal tm
4545 return $ Export ffi hdr tm'
@@ -51,7 +51,7 @@ toIFaceVal tm
5151 | (P _ fun _, [_,_,_,_,(P _ fn _),extnm,prf,rest]) <- unApply tm,
5252 fun == sNS (sUN "Fun") ["FFI_Export"]
5353 = do rest' <- toIFaceVal rest
54− return $
54+ return $
5555 ExportFun fn (toFDesc extnm) (toFDescRet prf) (toFDescArgs prf)
5656 : rest'
5757 | (P _ dat _, [_,_,_,_,d,rest]) <- unApply tm,
@@ -63,7 +63,7 @@ toIFaceVal tm
6363toFDesc :: Term -> FDesc
6464toFDesc (Constant (Str str)) = FStr str
6565toFDesc tm
66− | (P _ n _, []) <- unApply tm = FCon (deNS n)
66+ | (P _ n _, []) <- unApply tm = FCon (deNS n)
6767 | (P _ n _, as) <- unApply tm = FApp (deNS n) (map toFDesc as)
6868toFDesc _ = FUnknown
6969
@@ -91,20 +91,17 @@ toFDescBase tm
9191 | otherwise = error "Badly formed export type"
9292
9393toFDescArgs :: Term -> [FDesc]
94−toFDescArgs tm
94+toFDescArgs tm
9595 | (P _ fun _, [_,_,_,_,b,t]) <- unApply tm,
9696 fun == sNS (sUN "FFI_Fun") ["FFI_Export"]
9797 = toFDescBase b : toFDescArgs t
9898 | otherwise = []
9999
100−toFDescPrim (Constant (Str str)) = FStr str
101−toFDescPrim tm
102− | (P _ n _, []) <- unApply tm = FCon (deNS n)
100+toFDescPrim (Constant (Str str)) = FStr str
101+toFDescPrim tm
102+ | (P _ n _, []) <- unApply tm = FCon (deNS n)
103103 | (P _ n _, as) <- unApply tm = FApp (deNS n) (map toFDescPrim as)
104104toFDescPrim _ = FUnknown
105105
106106deNS (NS n _) = n
107107deNS n = n
108−
109−
110−
src/IRTS/JavaScript/AST.hs+4−1
@@ -77,6 +77,7 @@ data JS = JSRaw String
7777 | JSFFI String [JS]
7878 | JSAnnotation JSAnnotation JS
7979 | JSDelete JS
80+ | JSClear JS
8081 | JSNoop
8182 deriving Eq
8283
@@ -133,6 +134,9 @@ compileJS' indent (JSAnnotation annotation js) =
133134compileJS' indent (JSDelete js) =
134135 "delete " `T.append` compileJS' 0 js
135136
137+compileJS' indent (JSClear js) =
138+ compileJS' 0 js `T.append` " = undefined"
139+
136140compileJS' indent (JSFFI raw args) =
137141 ffi raw (map (T.unpack . compileJS' indent) args)
138142
@@ -398,4 +402,3 @@ jsPackSBits16 js = JSNew "Int16Array" [JSArray [js]]
398402
399403jsPackSBits32 :: JS -> JS
400404jsPackSBits32 js = JSNew "Int32Array" [JSArray [js]]
401−
src/Idris/AbsSyntax.hs+85−19
@@ -346,6 +346,14 @@ getNameHints i n =
346346addToCalledG :: Name -> [Name] -> Idris ()
347347addToCalledG n ns = return () -- TODO
348348
349+addDeprecated :: Name -> String -> Idris ()
350+addDeprecated n reason = do i <- getIState
351+ putIState $ i { idris_deprecated = addDef n reason (idris_deprecated i) }
352+
353+getDeprecated :: Name -> Idris (Maybe String)
354+getDeprecated n = do i <- getIState
355+ return $ lookupCtxtExact n (idris_deprecated i)
356+
349357push_estack :: Name -> Bool -> Idris ()
350358push_estack n inst
351359 = do i <- getIState
@@ -691,6 +699,13 @@ setLogLevel l = do i <- getIState
691699 let opt' = opts { opt_logLevel = l }
692700 putIState $ i { idris_options = opt' }
693701
702+setLogCats :: [LogCat] -> Idris ()
703+setLogCats cs = do
704+ i <- getIState
705+ let opts = idris_options i
706+ let opt' = opts { opt_logcats = cs }
707+ putIState $ i { idris_options = opt' }
708+
694709setCmdLine :: [Opt] -> Idris ()
695710setCmdLine opts = do i <- getIState
696711 let iopts = idris_options i
@@ -961,15 +976,55 @@ setColour ct c = do i <- getIState
961976 setColour' PromptColour c t = t { promptColour = c }
962977 setColour' PostulateColour c t = t { postulateColour = c }
963978
979+
964980logLvl :: Int -> String -> Idris ()
965−logLvl l str = do i <- getIState
966− let lvl = opt_logLevel (idris_options i)
967− when (lvl >= l) $
968− case idris_outputmode i of
969− RawOutput h -> do runIO $ hPutStrLn h str
970− IdeMode n h ->
971− do let good = SexpList [IntegerAtom (toInteger l), toSExp str]
972− runIO . hPutStrLn h $ convSExp "log" good n
981+logLvl = logLvlCats []
982+
983+logCoverage :: Int -> String -> Idris ()
984+logCoverage = logLvlCats [ICoverage]
985+
986+logErasure :: Int -> String -> Idris ()
987+logErasure = logLvlCats [IErasure]
988+
989+-- | Log an action of the parser
990+logParser :: Int -> String -> Idris ()
991+logParser = logLvlCats parserCats
992+
993+-- | Log an action of the elaborator.
994+logElab :: Int -> String -> Idris ()
995+logElab = logLvlCats elabCats
996+
997+-- | Log an action of the compiler.
998+logCodeGen :: Int -> String -> Idris ()
999+logCodeGen = logLvlCats codegenCats
1000+
1001+logIBC :: Int -> String -> Idris ()
1002+logIBC = logLvlCats [IIBC]
1003+
1004+-- | Log aspect of Idris execution
1005+--
1006+-- An empty set of logging levels is used to denote all categories.
1007+--
1008+-- @TODO update IDE protocol
1009+logLvlCats :: [LogCat] -- ^ The categories that the message should appear under.
1010+ -> Int -- ^ The Logging level the message should appear.
1011+ -> String -- ^ The message to show the developer.
1012+ -> Idris ()
1013+logLvlCats cs l str = do
1014+ i <- getIState
1015+ let lvl = opt_logLevel (idris_options i)
1016+ let cats = opt_logcats (idris_options i)
1017+ when (lvl >= l) $
1018+ when (inCat cs cats || null cats) $
1019+ case idris_outputmode i of
1020+ RawOutput h -> do
1021+ runIO $ hPutStrLn h str
1022+ IdeMode n h -> do
1023+ let good = SexpList [IntegerAtom (toInteger l), toSExp str]
1024+ runIO . hPutStrLn h $ convSExp "log" good n
1025+ where
1026+ inCat :: [LogCat] -> [LogCat] -> Bool
1027+ inCat cs cats = or $ map (\x -> elem x cats) cs
9731028
9741029cmdOptType :: Opt -> Idris Bool
9751030cmdOptType x = do i <- getIState
@@ -1344,7 +1399,7 @@ addUsingImpls syn n fc t
13441399 let badnames = filter (\n -> not (implicitable n) &&
13451400 n `notElem` (map iname uimpls)) ns
13461401 when (not (null badnames)) $
1347− throwError (At fc (Elaborating "type of " n
1402+ throwError (At fc (Elaborating "type of " n Nothing
13481403 (NoSuchVariable (head badnames))))
13491404 let cs = getArgnames t -- get already bound names
13501405 let addimpls = filter (\n -> iname n `notElem` cs) uimpls
@@ -1385,7 +1440,11 @@ getUnboundImplicits i t tm = getImps t (collectImps tm)
13851440 = (n, (p, t)) : collectImps sc
13861441 collectImps _ = []
13871442
1388− getImps (Bind n (Pi (Just _) _ _) sc) imps = getImps sc imps
1443+ scopedimpl (Just i) = not (toplevel_imp i)
1444+ scopedimpl _ = False
1445+
1446+ getImps (Bind n (Pi i _ _) sc) imps
1447+ | scopedimpl i = getImps sc imps
13891448 getImps (Bind n (Pi _ t _) sc) imps
13901449 | Just (p, t') <- lookup n imps = argInfo n p t' : getImps sc imps
13911450 where
@@ -1548,9 +1607,9 @@ implicitise syn ignore ist tm = -- trace ("INCOMING " ++ showImp True tm) $
15481607 pibind using [] sc = sc
15491608 pibind using (n:ns) sc
15501609 = case lookup n using of
1551− Just ty -> PPi (Imp [] Dynamic False Nothing)
1610+ Just ty -> PPi (Imp [] Dynamic False (Just (Impl False True)))
15521611 n NoFC ty (pibind using ns sc)
1553− Nothing -> PPi (Imp [InaccessibleArg] Dynamic False Nothing)
1612+ Nothing -> PPi (Imp [InaccessibleArg] Dynamic False (Just (Impl False True)))
15541613 n NoFC Placeholder (pibind using ns sc)
15551614
15561615-- Add implicit arguments in function calls
@@ -1616,7 +1675,7 @@ addImpl' inpat env infns imp_meths ist ptm
16161675 ai inpat qq env ds (PApp fc ftm@(PRef ffc hl f) as)
16171676 | f `elem` infns = ai inpat qq env ds (PApp fc (PInferRef ffc hl f) as)
16181677 | not (f `elem` map fst env)
1619− = let as' = map (fmap (ai inpat qq env ds)) as
1678+ = let as' = map (fmap (ai inpat qq env ds)) as
16201679 asdotted' = map (fmap (ai False qq env ds)) as in
16211680 handleErr $ aiFn topname inpat False qq imp_meths ist fc f ffc ds as' asdotted'
16221681 | Just (Just ty) <- lookup f env =
@@ -1694,7 +1753,9 @@ aiFn :: Name -> Bool -> Bool -> Bool
16941753 -> [PArg] -- ^ initial arguments (if in an expression)
16951754 -> Either Err PTerm
16961755aiFn topname inpat True qq imp_meths ist fc f ffc ds [] _
1697− = case lookupDef f (tt_ctxt ist) of
1756+ | inpat && implicitable f && unqualified f = Right $ PPatvar ffc f
1757+ | otherwise
1758+ = case lookupDef f (tt_ctxt ist) of
16981759 [] -> Right $ PPatvar ffc f
16991760 alts -> let ialts = lookupCtxtName f (idris_implicits ist) in
17001761 -- trace (show f ++ " " ++ show (fc, any (all imp) ialts, ialts, any constructor alts)) $
@@ -1707,6 +1768,10 @@ aiFn topname inpat True qq imp_meths ist fc f ffc ds [] _
17071768 imp _ = True
17081769-- allImp [] = False
17091770 allImp xs = all imp xs
1771+
1772+ unqualified (NS _ _) = False
1773+ unqualified _ = True
1774+
17101775 constructor (TyDecl (DCon _ _ _) _) = True
17111776 constructor _ = False
17121777
@@ -1725,7 +1790,7 @@ aiFn topname inpat expat qq imp_meths ist fc f ffc ds as asexp
17251790 [] -> nh
17261791 x -> x
17271792 case ns' of
1728− [(f',ns)] -> Right $ mkPApp fc (length ns) (PRef ffc [ffc] (isImpName f f'))
1793+ [(f',ns)] -> Right $ mkPApp fc (length ns) (PRef ffc [ffc] (isImpName f f'))
17291794 (insertImpl ns (chooseArgs f' as asexp))
17301795 [] -> if f `elem` (map fst (idris_metavars ist))
17311796 then Right $ PApp fc (PRef ffc [ffc] f) as
@@ -1887,9 +1952,11 @@ stripUnmatchable i (PApp fc fn args) = PApp fc fn (fmap (fmap su) args) where
18871952 su tm@(PRef fc hl f)
18881953 | (Bind n (Pi _ t _) sc :_) <- lookupTy f (tt_ctxt i)
18891954 = Placeholder
1890− | (TType _ : _) <- lookupTy f (tt_ctxt i)
1955+ | (TType _ : _) <- lookupTy f (tt_ctxt i),
1956+ not (implicitable f)
18911957 = PHidden tm
1892− | (UType _ : _) <- lookupTy f (tt_ctxt i)
1958+ | (UType _ : _) <- lookupTy f (tt_ctxt i),
1959+ not (implicitable f)
18931960 = PHidden tm
18941961 su (PApp fc f@(PRef _ _ fn) args)
18951962 -- here we use canBeDConName because the impossible pattern
@@ -2153,7 +2220,7 @@ shadow n n' t = sm 0 t where
21532220-- | Rename any binders which are repeated (so that we don't have to mess
21542221-- about with shadowing anywhere else).
21552222mkUniqueNames :: [Name] -> [(Name, Name)] -> PTerm -> PTerm
2156−mkUniqueNames env shadows tm
2223+mkUniqueNames env shadows tm
21572224 = evalState (mkUniq 0 initMap tm) (S.fromList env) where
21582225
21592226 initMap = M.fromList shadows
@@ -2275,4 +2342,3 @@ mkUniqueNames env shadows tm
22752342 mkUniq ql nmap (PUnquote tm) = fmap PUnquote (mkUniq (ql - 1) nmap tm)
22762343
22772344 mkUniq ql nmap tm = descendM (mkUniq ql nmap) tm
2278−
src/Idris/AbsSyntaxTree.hs+90−43
@@ -68,34 +68,36 @@ toplevel = EInfo [] emptyContext id Nothing Nothing (\_ _ _ -> fail "Not impleme
6868eInfoNames :: ElabInfo -> [Name]
6969eInfoNames info = map fst (params info) ++ M.keys (inblock info)
7070
71−data IOption = IOption { opt_logLevel :: Int,
72− opt_typecase :: Bool,
73− opt_typeintype :: Bool,
74− opt_coverage :: Bool,
75− opt_showimp :: Bool, -- ^^ show implicits
76− opt_errContext :: Bool,
77− opt_repl :: Bool,
78− opt_verbose :: Bool,
79− opt_nobanner :: Bool,
80− opt_quiet :: Bool,
81− opt_codegen :: Codegen,
82− opt_outputTy :: OutputType,
83− opt_ibcsubdir :: FilePath,
84− opt_importdirs :: [FilePath],
85− opt_triple :: String,
86− opt_cpu :: String,
87− opt_cmdline :: [Opt], -- remember whole command line
88− opt_origerr :: Bool,
89− opt_autoSolve :: Bool, -- ^ automatically apply "solve" tactic in prover
90− opt_autoImport :: [FilePath], -- ^ e.g. Builtins+Prelude
91− opt_optimise :: [Optimisation],
92− opt_printdepth :: Maybe Int,
93− opt_evaltypes :: Bool, -- ^ normalise types in :t
94− opt_desugarnats :: Bool
95− }
96− deriving (Show, Eq)
71+data IOption = IOption {
72+ opt_logLevel :: Int
73+ , opt_logcats :: [LogCat] -- ^ List of logging categories.
74+ , opt_typecase :: Bool
75+ , opt_typeintype :: Bool
76+ , opt_coverage :: Bool
77+ , opt_showimp :: Bool -- ^ show implicits
78+ , opt_errContext :: Bool
79+ , opt_repl :: Bool
80+ , opt_verbose :: Bool
81+ , opt_nobanner :: Bool
82+ , opt_quiet :: Bool
83+ , opt_codegen :: Codegen
84+ , opt_outputTy :: OutputType
85+ , opt_ibcsubdir :: FilePath
86+ , opt_importdirs :: [FilePath]
87+ , opt_triple :: String
88+ , opt_cpu :: String
89+ , opt_cmdline :: [Opt] -- remember whole command line
90+ , opt_origerr :: Bool
91+ , opt_autoSolve :: Bool -- ^ automatically apply "solve" tactic in prover
92+ , opt_autoImport :: [FilePath] -- ^ e.g. Builtins+Prelude
93+ , opt_optimise :: [Optimisation]
94+ , opt_printdepth :: Maybe Int
95+ , opt_evaltypes :: Bool -- ^ normalise types in :t
96+ , opt_desugarnats :: Bool
97+ } deriving (Show, Eq)
9798
9899defaultOpts = IOption { opt_logLevel = 0
100+ , opt_logcats = []
99101 , opt_typecase = False
100102 , opt_typeintype = False
101103 , opt_coverage = True
@@ -135,7 +137,7 @@ defaultOptimise = [PETransform]
135137
136138-- | Pretty printing options with default verbosity.
137139defaultPPOption :: PPOption
138−defaultPPOption = PPOption { ppopt_impl = False,
140+defaultPPOption = PPOption { ppopt_impl = False,
139141 ppopt_desugarnats = False,
140142 ppopt_pinames = False,
141143 ppopt_depth = Just 200 }
@@ -188,7 +190,7 @@ data IState = IState {
188190 idris_optimisation :: Ctxt OptInfo,
189191 idris_datatypes :: Ctxt TypeInfo,
190192 idris_namehints :: Ctxt [Name],
191− idris_patdefs :: Ctxt ([([Name], Term, Term)], [PTerm]), -- not exported
193+ idris_patdefs :: Ctxt ([([(Name, Term)], Term, Term)], [PTerm]), -- not exported
192194 -- ^ list of lhs/rhs, and a list of missing clauses
193195 idris_flags :: Ctxt [FnOpt],
194196 idris_callgraph :: Ctxt CGInfo, -- name, args used in each pos
@@ -259,7 +261,8 @@ data IState = IState {
259261 idris_symbols :: M.Map Name Name, -- ^ Symbol table (preserves sharing of names)
260262 idris_exports :: [Name], -- ^ Functions with ExportList
261263 idris_highlightedRegions :: [(FC, OutputAnnotation)], -- ^ Highlighting information to output
262− idris_parserHighlights :: [(FC, OutputAnnotation)] -- ^ Highlighting information from the parser
264+ idris_parserHighlights :: [(FC, OutputAnnotation)], -- ^ Highlighting information from the parser
265+ idris_deprecated :: Ctxt String -- ^ Deprecated names and explanation
263266 }
264267
265268-- Required for parsers library, and therefore trifecta
@@ -335,6 +338,7 @@ data IBCWrite = IBCFix FixDecl
335338 | IBCUsage (Name, Int)
336339 | IBCExport Name
337340 | IBCAutoHint Name Name
341+ | IBCDeprecate Name String
338342 deriving Show
339343
340344-- | The initial state for the compiler
@@ -349,6 +353,7 @@ idrisInit = IState initContext S.empty []
349353 [] [] Nothing [] Nothing [] [] Nothing Nothing [] Hidden False [] Nothing [] []
350354 (RawOutput stdout) True defaultTheme [] (0, emptyContext) emptyContext M.empty
351355 AutomaticWidth S.empty S.empty [] Nothing Nothing [] [] M.empty [] [] []
356+ emptyContext
352357
353358-- | The monad for the main REPL - reading and processing files and updating
354359-- global state (hence the IO inner monad).
@@ -403,6 +408,7 @@ data Command = Quit
403408 | Proofs
404409 | Universes
405410 | LogLvl Int
411+ | LogCategory [LogCat]
406412 | Spec PTerm
407413 | WHNF PTerm
408414 | TestInline PTerm
@@ -448,6 +454,44 @@ data Command = Quit
448454
449455data OutputFmt = HTMLOutput | LaTeXOutput
450456
457+-- | Recognised logging categories for the Idris compiler.
458+--
459+-- @TODO add in sub categories.
460+data LogCat = IParse
461+ | IElab
462+ | ICodeGen
463+ | IErasure
464+ | ICoverage
465+ | IIBC
466+ deriving (Show, Eq, Ord)
467+
468+strLogCat :: LogCat -> String
469+strLogCat IParse = "parser"
470+strLogCat IElab = "elab"
471+strLogCat ICodeGen = "codegen"
472+strLogCat IErasure = "erasure"
473+strLogCat ICoverage = "coverage"
474+strLogCat IIBC = "ibc"
475+
476+codegenCats :: [LogCat]
477+codegenCats = [ICodeGen]
478+
479+parserCats :: [LogCat]
480+parserCats = [IParse]
481+
482+elabCats :: [LogCat]
483+elabCats = [IElab]
484+
485+loggingCatsStr :: String
486+loggingCatsStr = unlines
487+ [ (strLogCat IParse)
488+ , (strLogCat IElab)
489+ , (strLogCat ICodeGen)
490+ , (strLogCat IErasure)
491+ , (strLogCat ICoverage)
492+ , (strLogCat IIBC)
493+ ]
494+
451495data Opt = Filename String
452496 | Quiet
453497 | NoBanner
@@ -458,11 +502,13 @@ data Opt = Filename String
458502 | ShowLibdir
459503 | ShowIncs
460504 | ShowPkgs
505+ | ShowLoggingCats
461506 | NoBasePkgs
462507 | NoPrelude
463508 | NoBuiltins -- only for the really primitive stuff!
464509 | NoREPL
465510 | OLogging Int
511+ | OLogCats [LogCat]
466512 | Output String
467513 | Interface
468514 | TypeCase
@@ -584,9 +630,9 @@ is_scoped :: Plicity -> Maybe ImplicitInfo
584630is_scoped (Imp _ _ _ s) = s
585631is_scoped _ = Nothing
586632
587−impl = Imp [] Dynamic False Nothing
588−forall_imp = Imp [] Dynamic False (Just (Impl False))
589−forall_constraint = Imp [] Dynamic False (Just (Impl True))
633+impl = Imp [] Dynamic False (Just (Impl False True))
634+forall_imp = Imp [] Dynamic False (Just (Impl False False))
635+forall_constraint = Imp [] Dynamic False (Just (Impl True False))
590636expl = Exp [] Dynamic False
591637expl_param = Exp [] Dynamic True
592638constraint = Constraint [] Static
@@ -708,12 +754,13 @@ data Directive = DLib Codegen String |
708754 DNameHint Name FC [(Name, FC)] |
709755 DErrorHandlers Name FC Name FC [(Name, FC)] |
710756 DLanguage LanguageExt |
757+ DDeprecate Name String |
711758 DUsed FC Name Name
712759
713760-- | A set of instructions for things that need to happen in IState
714761-- after a term elaboration when there's been reflected elaboration.
715762data RDeclInstructions = RTyDeclInstrs Name FC [PArg] Type
716− | RClausesInstrs Name [([Name], Term, Term)]
763+ | RClausesInstrs Name [([(Name, Term)], Term, Term)]
717764 | RAddInstance Name Name
718765
719766-- | For elaborator state
@@ -763,7 +810,7 @@ data PData' t = PDatadecl { d_name :: Name, -- ^ The name of the datatype
763810 | PLaterdecl { d_name :: Name, d_name_fc :: FC, d_tcon :: t }
764811 -- ^ "Placeholder" for data whose constructors are defined later
765812 deriving Functor
766−
813+
767814-- | Transform the FCs in a PData and its associated terms. The first
768815-- function transforms the general-purpose FCs, and the second transforms
769816-- those that are used for semantic source highlighting, so they can be
@@ -1084,7 +1131,7 @@ data PTactic' t = Intro [Name] | Intros | Focus Name
10841131 | MatchRefine Name
10851132 | LetTac Name t | LetTacTy Name t t
10861133 | Exact t | Compute | Trivial | TCInstance
1087− | ProofSearch Bool Bool Int (Maybe Name)
1134+ | ProofSearch Bool Bool Int (Maybe Name)
10881135 [Name] -- allowed local names
10891136 [Name] -- hints
10901137 -- ^ the bool is whether to search recursively
@@ -1175,7 +1222,7 @@ type PDo = PDo' PTerm
11751222data PArg' t = PImp { priority :: Int,
11761223 machine_inf :: Bool, -- true if the machine inferred it
11771224 argopts :: [ArgOpt],
1178− pname :: Name,
1225+ pname :: Name,
11791226 getTm :: t }
11801227 | PExp { priority :: Int,
11811228 argopts :: [ArgOpt],
@@ -1901,7 +1948,7 @@ pprintPTerm ppo bnd docArgs infixes = prettySe (ppopt_depth ppo) startPrec bnd
19011948 bracket p funcAppPrec . group . align . hang 2 $
19021949 text "%runElab" <$>
19031950 prettySe (decD d) funcAppPrec bnd tm
1904− prettySe d p bnd (PConstSugar fc tm) = prettySe d p bnd tm -- should never occur, but harmless
1951+ prettySe d p bnd (PConstSugar fc tm) = prettySe d p bnd tm -- should never occur, but harmless
19051952
19061953 prettySe d p bnd _ = text "missing pretty-printer for term"
19071954
@@ -2153,7 +2200,7 @@ showTm ist = displayDecorated (consoleDecorate ist) .
21532200showTmImpls :: PTerm -> String
21542201showTmImpls = flip (displayS . renderCompact . prettyImp verbosePPOption) ""
21552202
2156−-- | Show a term with specific options
2203+-- | Show a term with specific options
21572204showTmOpts :: PPOption -> PTerm -> String
21582205showTmOpts opt = flip (displayS . renderPretty 1.0 10000000 . prettyImp opt) ""
21592206
@@ -2269,7 +2316,7 @@ boundNamesIn tm = S.toList (ni 0 S.empty tm)
22692316
22702317-- Return names which are valid implicits in the given term (type).
22712318implicitNamesIn :: [Name] -> IState -> PTerm -> [Name]
2272−implicitNamesIn uvars ist tm
2319+implicitNamesIn uvars ist tm
22732320 = let (imps, fns) = execState (ni 0 [] tm) ([], []) in
22742321 nub imps \\ nub fns
22752322 where
@@ -2298,15 +2345,15 @@ implicitNamesIn uvars ist tm
22982345 ni 0 env (PRef _ _ n)
22992346 | not (n `elem` env) && implicitable n || n `elem` uvars = addImp n
23002347 ni 0 env (PApp _ f@(PRef _ _ n) as)
2301− | n `elem` uvars = do ni 0 env f
2348+ | n `elem` uvars = do ni 0 env f
23022349 mapM_ (ni 0 env) (map getTm as)
23032350 | otherwise = do case lookupTy n (tt_ctxt ist) of
23042351 [] -> return ()
23052352 _ -> addFn n
23062353 mapM_ (ni 0 env) (map getTm as)
2307− ni 0 env (PApp _ f as) = do ni 0 env f
2354+ ni 0 env (PApp _ f as) = do ni 0 env f
23082355 mapM_ (ni 0 env) (map getTm as)
2309− ni 0 env (PAppBind _ f as) = do ni 0 env f
2356+ ni 0 env (PAppBind _ f as) = do ni 0 env f
23102357 mapM_ (ni 0 env) (map getTm as)
23112358 ni 0 env (PCase _ c os) = do ni 0 env c
23122359 -- names in 'os', not counting the names bound in the cases
@@ -2323,7 +2370,7 @@ implicitNamesIn uvars ist tm
23232370 ni 0 env (PTyped l r) = do ni 0 env l; ni 0 env r
23242371 ni 0 env (PPair _ _ _ l r) = do ni 0 env l; ni 0 env r
23252372 ni 0 env (PDPair _ _ _ (PRef _ _ n) t r) = do ni 0 env t; ni 0 (n:env) r
2326− ni 0 env (PDPair _ _ _ l t r) = do ni 0 env l
2373+ ni 0 env (PDPair _ _ _ l t r) = do ni 0 env l
23272374 ni 0 env t
23282375 ni 0 env r
23292376 ni 0 env (PAlternative ns a as) = mapM_ (ni 0 env) as
src/Idris/CaseSplit.hs+83−60
@@ -50,8 +50,11 @@ names over '_', patterns over names, etc.
5050-}
5151
5252-- Given a variable to split, and a term application, return a list of
53−-- variable updates
54−split :: Name -> PTerm -> Idris [[(Name, PTerm)]]
53+-- variable updates, paired with a flag to say whether the given update
54+-- typechecks (False = impossible)
55+-- if the flag is 'False' the splits should be output with the 'impossible'
56+-- flag, otherwise they should be output as normal
57+split :: Name -> PTerm -> Idris (Bool, [[(Name, PTerm)]])
5558split n t'
5659 = do ist <- getIState
5760 -- Make sure all the names in the term are accessible
@@ -62,30 +65,41 @@ split n t'
6265 -- ASSUMPTION: tm is in normal form after elabValBind, so we don't
6366 -- need to do anything special to find out what family each argument
6467 -- is in
65− logLvl 4 ("Elaborated:\n" ++ show tm ++ " : " ++ show ty ++ "\n" ++ show pats)
68+ logElab 4 ("Elaborated:\n" ++ show tm ++ " : " ++ show ty ++ "\n" ++ show pats)
6669-- iputStrLn (show (delab ist tm) ++ " : " ++ show (delab ist ty))
6770-- iputStrLn (show pats)
68− let t = mergeUserImpl (addImplPat ist t') (delab ist tm)
71+ let t = mergeUserImpl (addImplPat ist t') (delab ist tm)
6972 let ctxt = tt_ctxt ist
7073 case lookup n pats of
7174 Nothing -> ifail $ show n ++ " is not a pattern variable"
7275 Just ty ->
7376 do let splits = findPats ist ty
74− logLvl 1 ("New patterns " ++ showSep ", "
77+ logElab 1 ("New patterns " ++ showSep ", "
7578 (map showTmImpls splits))
7679 let newPats_in = zipWith (replaceVar ctxt n) splits (repeat t)
77− logLvl 4 ("Working from " ++ show t)
78− logLvl 4 ("Trying " ++ showSep "\n"
80+ logElab 4 ("Working from " ++ show t)
81+ logElab 4 ("Trying " ++ showSep "\n"
7982 (map (showTmImpls) newPats_in))
80− newPats <- mapM elabNewPat newPats_in
81− logLvl 3 ("Original:\n" ++ show t)
82− logLvl 3 ("Split:\n" ++
83− (showSep "\n" (map show (mapMaybe id newPats))))
84− logLvl 3 "----"
85− let newPats' = mergeAllPats ist n t (mapMaybe id newPats)
86− logLvl 1 ("Name updates " ++ showSep "\n"
87− (map (\ (p, u) -> show u ++ " " ++ show p) newPats'))
88− return (map snd newPats')
83+ newPats_in <- mapM elabNewPat newPats_in
84+ case anyValid [] [] newPats_in of
85+ Left fails -> do
86+ let fails' = mergeAllPats ist n t fails
87+ return (False, (map snd fails'))
88+ Right newPats -> do
89+ logElab 3 ("Original:\n" ++ show t)
90+ logElab 3 ("Split:\n" ++
91+ (showSep "\n" (map show newPats)))
92+ logElab 3 "----"
93+ let newPats' = mergeAllPats ist n t newPats
94+ logElab 1 ("Name updates " ++ showSep "\n"
95+ (map (\ (p, u) -> show u ++ " " ++ show p) newPats'))
96+ return (True, (map snd newPats'))
97+ where
98+ anyValid ok bad [] = if null ok then Left (reverse bad)
99+ else Right (reverse ok)
100+ anyValid ok bad ((tc, p) : ps)
101+ | tc = anyValid (p : ok) bad ps
102+ | otherwise = anyValid ok (p : bad) ps
89103
90104data MergeState = MS { namemap :: [(Name, Name)],
91105 invented :: [(Name, Name)],
@@ -97,7 +111,7 @@ addUpdate n tm = do ms <- get
97111 put (ms { updates = ((n, stripNS tm) : updates ms) } )
98112
99113inventName :: Idris.AbsSyntaxTree.IState -> Maybe Name -> Name -> State MergeState Name
100−inventName ist ty n =
114+inventName ist ty n =
101115 do ms <- get
102116 let supp = case ty of
103117 Nothing -> []
@@ -117,11 +131,11 @@ inventName ist ty n =
117131 do let n' = uniqueNameFrom nsupp badnames
118132 put (ms { invented = (n, n') : invented ms })
119133 return n'
120−
134+
121135mkSupply :: [Name] -> [Name]
122136mkSupply ns = mkSupply' ns (map nextName ns)
123137 where mkSupply' xs ns' = xs ++ mkSupply ns'
124−
138+
125139varlist :: [Name]
126140varlist = map (sUN . (:[])) "xyzwstuv" -- EB's personal preference :)
127141
@@ -133,7 +147,7 @@ stripNS tm = mapPT dens tm where
133147mergeAllPats :: IState -> Name -> PTerm -> [PTerm] -> [(PTerm, [(Name, PTerm)])]
134148mergeAllPats ist cv t [] = []
135149mergeAllPats ist cv t (p : ps)
136− = let (p', MS _ _ _ u) = runState (mergePat ist t p Nothing)
150+ = let (p', MS _ _ _ u) = runState (mergePat ist t p Nothing)
137151 (MS [] [] (filter (/=cv) (patvars t)) [])
138152 ps' = mergeAllPats ist cv t ps in
139153 ((p', u) : ps')
@@ -178,7 +192,7 @@ mergeUserImpl :: PTerm -> PTerm -> PTerm
178192mergeUserImpl x y = x
179193
180194argTys :: IState -> PTerm -> [Maybe Name]
181−argTys ist (PRef fc hls n)
195+argTys ist (PRef fc hls n)
182196 = case lookupTy n (tt_ctxt ist) of
183197 [ty] -> map (tyName . snd) (getArgTys ty) ++ repeat Nothing
184198 _ -> repeat Nothing
@@ -208,13 +222,13 @@ tidy ist tm ty = return tm
208222-- where tidyVar (PRef _ _) = Placeholder
209223-- tidyVar t = t
210224
211−elabNewPat :: PTerm -> Idris (Maybe PTerm)
225+elabNewPat :: PTerm -> Idris (Bool, PTerm)
212226elabNewPat t = idrisCatch (do (tm, ty) <- elabVal recinfo ELHS t
213227 i <- getIState
214− return (Just (delab i tm)))
228+ return (True, delab i tm))
215229 (\e -> do i <- getIState
216− logLvl 5 $ "Not a valid split:\n" ++ pshow i e
217− return Nothing)
230+ logElab 5 $ "Not a valid split:\n" ++ pshow i e
231+ return (False, t))
218232
219233findPats :: IState -> Type -> [PTerm]
220234findPats ist t | (P _ n _, _) <- unApply t
@@ -236,7 +250,7 @@ replaceVar ctxt n t (PApp fc f pats) = PApp fc f (map substArg pats)
236250 subst orig@(PRef _ _ v) | v == n = t
237251 | isDConName v ctxt = orig
238252 subst (PRef _ _ _) = Placeholder
239− subst (PApp fc (PRef _ _ t) pats)
253+ subst (PApp fc (PRef _ _ t) pats)
240254 | isTConName t ctxt = Placeholder -- infer types
241255 subst (PApp fc f pats) = PApp fc f (map substArg pats)
242256 subst x = x
@@ -248,30 +262,31 @@ replaceVar ctxt n t pat = pat
248262splitOnLine :: Int -- ^ line number
249263 -> Name -- ^ variable
250264 -> FilePath -- ^ name of file
251− -> Idris [[(Name, PTerm)]]
265+ -> Idris (Bool, [[(Name, PTerm)]])
252266splitOnLine l n fn = do
253−-- let (before, later) = splitAt (l-1) (lines inp)
254−-- i <- getIState
255267 cl <- getInternalApp fn l
256− logLvl 3 ("Working with " ++ showTmImpls cl)
268+ logElab 3 ("Working with " ++ showTmImpls cl)
257269 tms <- split n cl
258−-- iputStrLn (showSep "\n" (map show tms))
259− return tms -- "" -- not yet done...
270+ return tms
260271
261−replaceSplits :: String -> [[(Name, PTerm)]] -> Idris [String]
262−replaceSplits l ups = updateRHSs 1 (map (rep (expandBraces l)) ups)
272+replaceSplits :: String -> [[(Name, PTerm)]] -> Bool -> Idris [String]
273+replaceSplits l ups impossible
274+ = updateRHSs 1 (map (rep (expandBraces l)) ups)
263275 where
264276 rep str [] = str ++ "\n"
265277 rep str ((n, tm) : ups) = rep (updatePat False (show n) (nshow tm) str) ups
266278
267279 updateRHSs i [] = return []
268− updateRHSs i (x : xs) = do (x', i') <- updateRHS (null xs) i x
269− xs' <- updateRHSs i' xs
270− return (x' : xs')
280+ updateRHSs i (x : xs)
281+ | impossible = do xs' <- updateRHSs i xs
282+ return (setImpossible False x : xs')
283+ | otherwise = do (x', i') <- updateRHS (null xs) i x
284+ xs' <- updateRHSs i' xs
285+ return (x' : xs')
271286
272287 updateRHS last i ('?':'=':xs) = do (xs', i') <- updateRHS last i xs
273288 return ("?=" ++ xs', i')
274− updateRHS last i ('?':xs)
289+ updateRHS last i ('?':xs)
275290 = do let (nm, rest_in) = span (not . (\x -> isSpace x || x == ')'
276291 || x == '(')) xs
277292 let rest = if last then rest_in else
@@ -283,6 +298,11 @@ replaceSplits l ups = updateRHSs 1 (map (rep (expandBraces l)) ups)
283298 return (x : xs', i')
284299 updateRHS last i [] = return ("", i)
285300
301+ setImpossible brace ('}':xs) = '}' : setImpossible False xs
302+ setImpossible brace ('{':xs) = '{' : setImpossible True xs
303+ setImpossible False ('=':xs) = "impossible\n"
304+ setImpossible brace (x : xs) = x : setImpossible brace xs
305+ setImpossible brace [] = ""
286306
287307 -- TMP HACK: If there are Nats, we don't want to show as numerals since
288308 -- this isn't supported in a pattern, so special case here
@@ -321,7 +341,7 @@ replaceSplits l ups = updateRHSs 1 (map (rep (expandBraces l)) ups)
321341 | otherwise = tm
322342
323343
324−getUniq :: (Show t, Num t) => [Char] -> t -> Idris ([Char], t)
344+getUniq :: (Show t, Num t) => [Char] -> t -> Idris ([Char], t)
325345getUniq nm i
326346 = do ist <- getIState
327347 let n = nameRoot [] nm ++ "_" ++ show i
@@ -337,27 +357,31 @@ nameRoot acc nm =
337357
338358getClause :: Int -- ^ line number that the type is declared on
339359 -> Name -- ^ Function name
360+ -> Name -- ^ User given name
340361 -> FilePath -- ^ Source file name
341362 -> Idris String
342−getClause l fn fp
363+getClause l fn un fp
343364 = do i <- getIState
344− case lookupCtxt fn (idris_classes i) of
365+ case lookupCtxt un (idris_classes i) of
345366 [c] -> return (mkClassBodies i (class_methods c))
346− _ -> do ty <- getInternalApp fp l
367+ _ -> do ty_in <- getInternalApp fp l
368+ let ty = case ty_in of
369+ PTyped n t -> t
370+ x -> x
347371 ist <- get
348372 let ap = mkApp ist ty []
349− return (show fn ++ " " ++ ap ++ "= ?"
350− ++ show fn ++ "_rhs")
373+ return (show un ++ " " ++ ap ++ "= ?"
374+ ++ show un ++ "_rhs")
351375 where mkApp :: IState -> PTerm -> [Name] -> String
352376 mkApp i (PPi (Exp _ _ False) (MN _ _) _ ty sc) used
353377 = let n = getNameFrom i used ty in
354− show n ++ " " ++ mkApp i sc (n : used)
378+ show n ++ " " ++ mkApp i sc (n : used)
355379 mkApp i (PPi (Exp _ _ False) (UN n) _ ty sc) used
356380 | thead n == '_'
357381 = let n = getNameFrom i used ty in
358− show n ++ " " ++ mkApp i sc (n : used)
359− mkApp i (PPi (Exp _ _ False) n _ _ sc) used
360− = show n ++ " " ++ mkApp i sc (n : used)
382+ show n ++ " " ++ mkApp i sc (n : used)
383+ mkApp i (PPi (Exp _ _ False) n _ _ sc) used
384+ = show n ++ " " ++ mkApp i sc (n : used)
361385 mkApp i (PPi _ _ _ _ sc) used = mkApp i sc used
362386 mkApp i _ _ = ""
363387
@@ -370,17 +394,17 @@ getClause l fn fp
370394 sUN "z"]) used
371395 ns -> uniqueNameFrom (mkSupply ns) used
372396 getNameFrom i used _ = uniqueNameFrom (mkSupply [sUN "x", sUN "y",
373− sUN "z"]) used
397+ sUN "z"]) used
374398
375399 -- write method declarations, indent with 4 spaces
376400 mkClassBodies :: IState -> [(Name, (FnOpts, PTerm))] -> String
377− mkClassBodies i ns
401+ mkClassBodies i ns
378402 = showSep "\n"
379− (zipWith (\(n, (_, ty)) m -> " " ++
403+ (zipWith (\(n, (_, ty)) m -> " " ++
380404 def (show (nsroot n)) ++ " "
381405 ++ mkApp i ty []
382− ++ "= ?"
383− ++ show fn ++ "_rhs_" ++ show m) ns [1..])
406+ ++ "= ?"
407+ ++ show un ++ "_rhs_" ++ show m) ns [1..])
384408
385409 def n@(x:xs) | not (isAlphaNum x) = "(" ++ n ++ ")"
386410 def n = n
@@ -390,7 +414,10 @@ getProofClause :: Int -- ^ line number that the type is declared
390414 -> FilePath -- ^ Source file name
391415 -> Idris String
392416getProofClause l fn fp
393− = do ty <- getInternalApp fp l
417+ = do ty_in <- getInternalApp fp l
418+ let ty = case ty_in of
419+ PTyped n t -> t
420+ x -> x
394421 return (mkApp ty ++ " = ?" ++ show fn ++ "_rhs")
395422 where mkApp (PPi _ _ _ _ sc) = mkApp sc
396423 mkApp rt = "(" ++ show rt ++ ") <== " ++ show fn
@@ -427,9 +454,5 @@ nameMissing ps = do ist <- get
427454
428455 nm ptm = do mptm <- elabNewPat ptm
429456 case mptm of
430− Nothing -> return ptm
431− Just ptm' -> return ptm'
432−
433−
434−
435−
457+ (False, _) -> return ptm
458+ (True, ptm') -> return ptm'
src/Idris/Chaser.hs+81−38
@@ -1,5 +1,6 @@
1−module Idris.Chaser(buildTree, getModuleFiles, ModuleTree(..)) where
1+module Idris.Chaser(buildTree, getImports, getModuleFiles, ModuleTree(..)) where
22
3+import Idris.Core.TT
34import Idris.Parser
45import Idris.AbsSyntax
56import Idris.Imports
@@ -79,42 +80,86 @@ getIModTime (IBC i _) = getModificationTime i
7980getIModTime (IDR i) = getModificationTime i
8081getIModTime (LIDR i) = getModificationTime i
8182
83+getImports :: [(FilePath, [ImportInfo])] -> [FilePath] ->
84+ Idris [(FilePath, [ImportInfo])]
85+getImports acc [] = return acc
86+getImports acc (f : fs) = do
87+ i <- getIState
88+ let file = extractFileName f
89+ ibcsd <- valIBCSubDir i
90+ ids <- allImportDirs
91+ idrisCatch (do
92+ fp <- findImport ["."] ibcsd file
93+ let parsef = fname fp
94+ case lookup parsef acc of
95+ Just _ -> getImports acc fs
96+ _ -> do
97+ exist <- runIO $ doesFileExist parsef
98+ if exist then do
99+ src_in <- runIO $ readSource parsef
100+ src <- if lit fp then tclift $ unlit parsef src_in
101+ else return src_in
102+ (_, _, modules, _) <- parseImports parsef src
103+ clearParserWarnings
104+ getImports ((parsef, modules) : acc)
105+ (fs ++ map import_path modules)
106+ else getImports ((parsef, []) : acc) fs)
107+ (\_ -> getImports acc fs) -- not in current soure tree, ignore
108+ where
109+ lit (LIDR _) = True
110+ lit _ = False
111+
112+ fname (IDR fn) = fn
113+ fname (LIDR fn) = fn
114+ fname (IBC _ src) = fname src
115+
82116buildTree :: [FilePath] -> -- already guaranteed built
117+ [(FilePath, [ImportInfo])] -> -- import lists (don't reparse)
83118 FilePath -> Idris [ModuleTree]
84−buildTree built fp = btree [] fp
85−-- = idrisCatch (btree [] fp)
86−-- (\e -> do now <- runIO $ getCurrentTime
87−-- iputStrLn (show e)
88−-- return [MTree (IDR fp) True now []])
119+buildTree built importlists fp = evalStateT (btree [] fp) []
89120 where
90− btree done f =
91− do i <- getIState
121+ addFile :: FilePath -> [ModuleTree] ->
122+ StateT [(FilePath, [ModuleTree])] Idris [ModuleTree]
123+ addFile f m = do fs <- get
124+ put ((f, m) : fs)
125+ return m
126+
127+ btree :: [FilePath] -> FilePath ->
128+ StateT [(FilePath, [ModuleTree])] Idris [ModuleTree]
129+ btree stk f =
130+ do i <- lift getIState
92131 let file = extractFileName f
93− logLvl 1 $ "CHASING " ++ show file
94− ibcsd <- valIBCSubDir i
95− ids <- allImportDirs
96− fp <- findImport ids ibcsd file
97− logLvl 1 $ "Found " ++ show fp
98− mt <- runIO $ getIModTime fp
132+ lift $ logLvl 1 $ "CHASING " ++ show file ++ " (" ++ show fp ++ ")"
133+ ibcsd <- lift $ valIBCSubDir i
134+ ids <- lift $ allImportDirs
135+ fp <- lift $ findImport ids ibcsd file
136+ lift $ logLvl 1 $ "Found " ++ show fp
137+ mt <- lift $ runIO $ getIModTime fp
99138 if (file `elem` built)
100139 then return [MTree fp False mt []]
101− else if file `elem` done
102− then return []
103− else mkChildren fp
104−
105− where mkChildren (LIDR fn) = do ms <- children True fn (f:done)
106− mt <- runIO $ getModificationTime fn
107− return [MTree (LIDR fn) True mt ms]
108− mkChildren (IDR fn) = do ms <- children False fn (f:done)
109− mt <- runIO $ getModificationTime fn
110− return [MTree (IDR fn) True mt ms]
111− mkChildren (IBC fn src)
112− = do srcexist <- runIO $ doesFileExist (getSrcFile src)
140+ else if file `elem` stk then
141+ do lift $ tclift $ tfail
142+ (Msg $ "Cycle detected in imports: "
143+ ++ showSep " -> " (reverse (file : stk)))
144+ else do donetree <- get
145+ case lookup file donetree of
146+ Just t -> return t
147+ _ -> do ms <- mkChildren file fp
148+ addFile file ms
149+
150+ where mkChildren file (LIDR fn) = do ms <- children True fn (file : stk)
151+ mt <- lift $ runIO $ getModificationTime fn
152+ return [MTree (LIDR fn) True mt ms]
153+ mkChildren file (IDR fn) = do ms <- children False fn (file : stk)
154+ mt <- lift $ runIO $ getModificationTime fn
155+ return [MTree (IDR fn) True mt ms]
156+ mkChildren file (IBC fn src)
157+ = do srcexist <- lift $ runIO $ doesFileExist (getSrcFile src)
113158 ms <- if srcexist then
114− do [MTree _ _ _ ms'] <- mkChildren src
159+ do [MTree _ _ _ ms'] <- mkChildren file src
115160 return ms'
116161 else return []
117− mt <- idrisCatch (runIO $ getModificationTime fn)
162+ mt <- lift $ idrisCatch (runIO $ getModificationTime fn)
118163 (\c -> runIO $ getIModTime src)
119164 -- FIXME: It's also not up to date if anything it imports has
120165 -- been modified since its own ibc has.
@@ -122,7 +167,7 @@ buildTree built fp = btree [] fp
122167 -- Issue #1592 on the issue tracker.
123168 --
124169 -- https://github.com/idris-lang/Idris-dev/issues/1592
125− ibcOutdated <- fn `younger` (getSrcFile src)
170+ ibcOutdated <- lift $ fn `younger` (getSrcFile src)
126171 -- FIXME (EB): The below 'hasValidIBCVersion' that's
127172 -- commented out appears to be breaking reloading in vim
128173 -- mode. Until we know why, I've commented it out.
@@ -140,16 +185,14 @@ buildTree built fp = btree [] fp
140185 return (srct > ibct)
141186 else return False
142187
143− children :: Bool -> FilePath -> [FilePath] -> Idris [ModuleTree]
144− children lit f done = -- idrisCatch
145− do exist <- runIO $ doesFileExist f
188+ children :: Bool -> FilePath -> [FilePath] ->
189+ StateT [(FilePath, [ModuleTree])] Idris [ModuleTree]
190+ children lit f stk = -- idrisCatch
191+ do exist <- lift $ runIO $ doesFileExist f
146192 if exist then do
147− file_in <- runIO $ readSource f
148− file <- if lit then tclift $ unlit f file_in else return file_in
149− (_, _, modules, _) <- parseImports f file
150− -- The chaser should never report warnings from sub-modules
151− clearParserWarnings
152− ms <- mapM (btree done . import_path) modules
193+ lift $ logLvl 1 $ "Reading source " ++ show f
194+ let modules = maybe [] id (lookup f importlists)
195+ ms <- mapM (btree stk . import_path) modules
153196 return (concat ms)
154197 else return [] -- IBC with no source available
155198-- (\c -> return []) -- error, can't chase modules here
src/Idris/CmdOptions.hs+43−13
@@ -86,6 +86,11 @@ parseFlags = many $
8686 <|> (Client <$> strOption (long "client"))
8787 -- Logging Flags
8888 <|> (OLogging <$> option auto (long "log" <> metavar "LEVEL" <> help "Debugging log level"))
89+ <|> (OLogCats <$> option (str >>= parseLogCats)
90+ (long "logging-categories"
91+ <> metavar "CATS"
92+ <> help "Colon separated logging categories. Use --listlogcats to see list."))
93+
8994 -- Turn off Certain libraries.
9095 <|> flag' NoBasePkgs (long "nobasepkgs" <> help "Do not use the given base package")
9196 <|> flag' NoPrelude (long "noprelude" <> help "Do not use the given prelude")
@@ -101,11 +106,13 @@ parseFlags = many $
101106 <|> flag' WarnReach (long "warnreach" <> help "Warn about reachable but inaccessible arguments")
102107 <|> flag' NoCoverage (long "nocoverage")
103108 <|> flag' ErrContext (long "errorcontext")
104− <|> flag' ShowLibs (long "link" <> help "Display link flags")
105− <|> flag' ShowPkgs (long "listlibs" <> help "Display installed libraries")
106− <|> flag' ShowLibdir (long "libdir" <> help "Display library directory")
107− <|> flag' ShowIncs (long "include" <> help "Display the includes flags")
108− <|> flag' Verbose (short 'V' <> long "verbose" <> help "Loud verbosity")
109+ -- Show things
110+ <|> flag' ShowLoggingCats (long "listlogcats" <> help "Display logging categories")
111+ <|> flag' ShowLibs (long "link" <> help "Display link flags")
112+ <|> flag' ShowPkgs (long "listlibs" <> help "Display installed libraries")
113+ <|> flag' ShowLibdir (long "libdir" <> help "Display library directory")
114+ <|> flag' ShowIncs (long "include" <> help "Display the includes flags")
115+ <|> flag' Verbose (short 'V' <> long "verbose" <> help "Loud verbosity")
109116 <|> (IBCSubDir <$> strOption (long "ibcsubdir" <> metavar "FILE" <> help "Write IBC files into sub directory"))
110117 <|> (ImportDir <$> strOption (short 'i' <> long "idrispath" <> help "Add directory to the list of import paths"))
111118 <|> flag' WarnOnly (long "warn")
@@ -161,21 +168,44 @@ parseVersion :: Parser (a -> a)
161168parseVersion = infoOption ver (short 'v' <> long "version" <> help "Print version information")
162169
163170preProcOpts :: [Opt] -> [Opt] -> [Opt]
164−preProcOpts [] ys = ys
171+preProcOpts [] ys = ys
165172preProcOpts (NoBuiltins:xs) ys = NoBuiltins : NoPrelude : preProcOpts xs ys
166−preProcOpts (Output s:xs) ys = Output s : NoREPL : preProcOpts xs ys
167−preProcOpts (BCAsm s:xs) ys = BCAsm s : NoREPL : preProcOpts xs ys
168−preProcOpts (x:xs) ys = preProcOpts xs (x:ys)
173+preProcOpts (Output s:xs) ys = Output s : NoREPL : preProcOpts xs ys
174+preProcOpts (BCAsm s:xs) ys = BCAsm s : NoREPL : preProcOpts xs ys
175+preProcOpts (x:xs) ys = preProcOpts xs (x:ys)
169176
170177parseCodegen :: String -> Codegen
171178parseCodegen "bytecode" = Bytecode
172−parseCodegen cg = Via (map toLower cg)
173−
174−
179+parseCodegen cg = Via (map toLower cg)
175180
181+parseLogCats :: Monad m => String -> m [LogCat]
182+parseLogCats s =
183+ case lastMay (readP_to_S (doParse) s) of
184+ Just (xs, _) -> return xs
185+ _ -> fail $ "Incorrect categories specified"
186+ where
187+ doParse :: ReadP [LogCat]
188+ doParse = do
189+ cs <- sepBy1 parseLogCat (char ':')
190+ eof
191+ return (concat cs)
192+
193+ parseLogCat :: ReadP [LogCat]
194+ parseLogCat = (string (strLogCat IParse) *> return parserCats)
195+ <|> (string (strLogCat IElab) *> return elabCats)
196+ <|> (string (strLogCat ICodeGen) *> return codegenCats)
197+ <|> (string (strLogCat ICoverage) *> return [ICoverage])
198+ <|> (string (strLogCat IIBC) *> return [IIBC])
199+ <|> (string (strLogCat IErasure) *> return [IErasure])
200+ <|> parseLogCatBad
201+
202+ parseLogCatBad :: ReadP [LogCat]
203+ parseLogCatBad = do
204+ s <- look
205+ fail $ "Category: " ++ s ++ " is not recognised."
176206
177207parseConsoleWidth :: Monad m => String -> m ConsoleWidth
178−parseConsoleWidth "auto" = return AutomaticWidth
208+parseConsoleWidth "auto" = return AutomaticWidth
179209parseConsoleWidth "infinite" = return InfinitelyWide
180210parseConsoleWidth s =
181211 case lastMay (readP_to_S (integerReader) s) of
src/Idris/Completion.hs+2−8
@@ -12,7 +12,7 @@ import Idris.Colours
1212import Idris.ParseHelpers(opChars)
1313import qualified Idris.ParseExpr (constants, tactics)
1414import Idris.ParseExpr (TacticArg (..))
15−import Idris.REPLParser (allHelp)
15+import Idris.REPLParser (allHelp, setOptions)
1616import Control.Monad.State.Strict
1717
1818import Data.List
@@ -82,13 +82,7 @@ completeMetaVar = completeWord Nothing (" \t(){}:" ++ opChars) completeM
8282
8383completeOption :: CompletionFunc Idris
8484completeOption = completeWord Nothing " \t" completeOpt
85− where completeOpt = return . completeWith [ "errorcontext"
86− , "showimplicits"
87− , "originalerrors"
88− , "autosolve"
89− , "nobanner"
90− , "desugarnats"
91− ]
85+ where completeOpt = return . completeWith (map fst setOptions)
9286
9387completeConsoleWidth :: CompletionFunc Idris
9488completeConsoleWidth = completeWord Nothing " \t" completeW
src/Idris/Core/Binary.hs+27−22
@@ -145,10 +145,11 @@ instance Binary a => Binary (Err' a) where
145145 put (At fc e) = do putWord8 27
146146 put fc
147147 put e
148− put (Elaborating str n e) = do putWord8 28
149− put str
150− put n
151− put e
148+ put (Elaborating str n ty e) = do putWord8 28
149+ put str
150+ put n
151+ put ty
152+ put e
152153 put (ElaboratingArg n1 n2 ns e) = do putWord8 29
153154 put n1
154155 put n2
@@ -188,7 +189,10 @@ instance Binary a => Binary (Err' a) where
188189 put ns
189190 put (RunningElabScript e) = do putWord8 42
190191 put e
191−
192+ put (ElabScriptStaging n) = do putWord8 43
193+ put n
194+ put (FancyMsg xs) = do putWord8 44
195+ put xs
192196 get = do i <- getWord8
193197 case i of
194198 0 -> fmap Msg get
@@ -230,8 +234,8 @@ instance Binary a => Binary (Err' a) where
230234 26 -> fmap NoRewriting get
231235 27 -> do x <- get ; y <- get
232236 return $ At x y
233− 28 -> do x <- get ; y <- get ; z <- get
234− return $ Elaborating x y z
237+ 28 -> do w <- get; x <- get ; y <- get ; z <- get
238+ return $ Elaborating w x y z
235239 29 -> do w <- get ; x <- get ; y <- get ; z <- get
236240 return $ ElaboratingArg w x y z
237241 30 -> fmap ProviderError get
@@ -259,6 +263,8 @@ instance Binary a => Binary (Err' a) where
259263 return $ UnknownImplicit x y
260264 41 -> fmap NoValidAlts get
261265 42 -> fmap RunningElabScript get
266+ 43 -> fmap ElabScriptStaging get
267+ 44 -> fmap FancyMsg get
262268 _ -> error "Corrupted binary data for Err'"
263269----- Generated by 'derive'
264270
@@ -284,6 +290,9 @@ instance Binary FC where
284290 return (FileFC x1)
285291 _ -> error "Corrupted binary data for FC"
286292
293+instance Binary FC' where
294+ put (FC' fc) = put fc
295+ get = fmap FC' get
287296
288297instance Binary Name where
289298 put x
@@ -296,10 +305,9 @@ instance Binary Name where
296305 MN x1 x2 -> do putWord8 2
297306 put x1
298307 put x2
299− NErased -> putWord8 3
300− SN x1 -> do putWord8 4
308+ SN x1 -> do putWord8 3
301309 put x1
302− SymRef x1 -> do putWord8 5
310+ SymRef x1 -> do putWord8 4
303311 put x1
304312 get
305313 = do i <- getWord8
@@ -312,10 +320,9 @@ instance Binary Name where
312320 2 -> do x1 <- get
313321 x2 <- get
314322 return (MN x1 x2)
315− 3 -> return NErased
316− 4 -> do x1 <- get
323+ 3 -> do x1 <- get
317324 return (SN x1)
318− 5 -> do x1 <- get
325+ 4 -> do x1 <- get
319326 return (SymRef x1)
320327 _ -> error "Corrupted binary data for Name"
321328
@@ -334,7 +341,7 @@ instance Binary SpecialName where
334341 put x2
335342 MethodN x1 -> do putWord8 3
336343 put x1
337− CaseN x1 -> do putWord8 4; put x1
344+ CaseN x1 x2 -> do putWord8 4; put x1; put x2
338345 ElimN x1 -> do putWord8 5; put x1
339346 InstanceCtorN x1 -> do putWord8 6; put x1
340347 WithN x1 x2 -> do putWord8 7
@@ -359,7 +366,8 @@ instance Binary SpecialName where
359366 3 -> do x1 <- get
360367 return (MethodN x1)
361368 4 -> do x1 <- get
362− return (CaseN x1)
369+ x2 <- get
370+ return (CaseN x1 x2)
363371 5 -> do x1 <- get
364372 return (ElimN x1)
365373 6 -> do x1 <- get
@@ -452,9 +460,7 @@ instance Binary Raw where
452460 RType -> putWord8 3
453461 RConstant x1 -> do putWord8 4
454462 put x1
455− RForce x1 -> do putWord8 5
456− put x1
457− RUType x1 -> do putWord8 6
463+ RUType x1 -> do putWord8 5
458464 put x1
459465 get
460466 = do i <- getWord8
@@ -472,18 +478,17 @@ instance Binary Raw where
472478 4 -> do x1 <- get
473479 return (RConstant x1)
474480 5 -> do x1 <- get
475− return (RForce x1)
476− 6 -> do x1 <- get
477481 return (RUType x1)
478482 _ -> error "Corrupted binary data for Raw"
479483
480484instance Binary ImplicitInfo where
481485 put x
482486 = case x of
483− Impl x1 -> put x1
487+ Impl x1 x2 -> do put x1; put x2
484488 get
485489 = do x1 <- get
486− return (Impl x1)
490+ x2 <- get
491+ return (Impl x1 x2)
487492
488493instance (Binary b) => Binary (Binder b) where
489494 put x
src/Idris/Core/Constraints.hs+5−7
@@ -167,13 +167,11 @@ solve maxUniverseLevel ucs =
167167 doms <- gets domainStore
168168 let (oldDom@(Domain _ upper), suspects) = doms M.! Var var
169169 let newDom = Domain lower upper
170− when (wipeOut newDom) $ lift $ Error $ At (ufc suspect) $ Msg $ unlines
171− $ "Universe inconsistency."
172− : ("Working on: " ++ show (UVar var))
173− : ("Old domain: " ++ show oldDom)
174− : ("New domain: " ++ show newDom)
175− : "Involved constraints: "
176− : map (("\t"++) . show) (suspect : S.toList suspects)
170+ when (wipeOut newDom) $
171+ lift $ Error $
172+ UniverseError (ufc suspect) (UVar var)
173+ (asPair oldDom) (asPair newDom)
174+ (suspect : S.toList suspects)
177175 modify $ \ st -> st { domainStore = M.insert (Var var) (newDom, S.insert suspect suspects) doms }
178176 addToQueueLHS (uconstraint suspect) (Var var)
179177 updateLowerBoundOf _ UVal{} _ = return ()
src/Idris/Core/DeepSeq.hs+9−6
@@ -13,7 +13,6 @@ instance NFData Name where
1313 rnf (UN x1) = rnf x1 `seq` ()
1414 rnf (NS x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
1515 rnf (MN x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
16− rnf NErased = ()
1716 rnf (SN x1) = rnf x1 `seq` ()
1817 rnf (SymRef x1) = rnf x1 `seq` ()
1918
@@ -65,7 +64,7 @@ instance NFData SpecialName where
6564 rnf (InstanceN x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
6665 rnf (ParentN x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
6766 rnf (MethodN x1) = rnf x1 `seq` ()
68− rnf (CaseN x1) = rnf x1 `seq` ()
67+ rnf (CaseN x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
6968 rnf (ElimN x1) = rnf x1 `seq` ()
7069 rnf (InstanceCtorN x1) = rnf x1 `seq` ()
7170 rnf (MetaN x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
@@ -81,7 +80,6 @@ instance NFData Raw where
8180 rnf (RApp x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
8281 rnf RType = ()
8382 rnf (RUType x1) = rnf x1 `seq` ()
84− rnf (RForce x1) = rnf x1 `seq` ()
8583 rnf (RConstant x1) = x1 `seq` ()
8684
8785instance NFData FC where
@@ -89,6 +87,9 @@ instance NFData FC where
8987 rnf NoFC = ()
9088 rnf (FileFC f) = rnf f `seq` ()
9189
90+instance NFData FC' where
91+ rnf (FC' fc) = rnf fc `seq` ()
92+
9293instance NFData Provenance where
9394 rnf ExpectedType = ()
9495 rnf InferredVal = ()
@@ -148,13 +149,15 @@ instance NFData Err where
148149 rnf (ProofSearchFail x1) = rnf x1 `seq` ()
149150 rnf (NoRewriting x1) = rnf x1 `seq` ()
150151 rnf (At x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
151− rnf (Elaborating x1 x2 x3)
152− = rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` ()
152+ rnf (Elaborating x1 x2 x3 x4)
153+ = rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` rnf x4 `seq` ()
153154 rnf (ProviderError x1) = rnf x1 `seq` ()
154155 rnf (LoadingFailed x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
155156 rnf (ElabScriptDebug x1 x2 x3) = rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` ()
156157 rnf (ElabScriptStuck x1) = rnf x1 `seq` ()
157158 rnf (RunningElabScript x1) = rnf x1 `seq` ()
159+ rnf (ElabScriptStaging x1) = rnf x1 `seq` ()
160+ rnf (FancyMsg x1) = rnf x1 `seq` ()
158161
159162instance NFData ErrorReportPart where
160163 rnf (TextPart x1) = rnf x1 `seq` ()
@@ -164,7 +167,7 @@ instance NFData ErrorReportPart where
164167 rnf (SubReport x1) = rnf x1 `seq` ()
165168
166169instance NFData ImplicitInfo where
167− rnf (Impl x1) = rnf x1 `seq` ()
170+ rnf (Impl x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
168171
169172instance (NFData b) => NFData (Binder b) where
170173 rnf (Lam x1) = rnf x1 `seq` ()
src/Idris/Core/Elaborate.hs+58−9
@@ -119,8 +119,8 @@ transformErr f elab = do s <- get
119119 rewriteErr (ProofSearchFail e) = ProofSearchFail (rewriteErr e)
120120 rewriteErr e = f e
121121
122−errAt :: String -> Name -> Elab' aux a -> Elab' aux a
123−errAt thing n = transformErr (Elaborating thing n)
122+errAt :: String -> Name -> Maybe Type -> Elab' aux a -> Elab' aux a
123+errAt thing n ty = transformErr (Elaborating thing n ty)
124124
125125
126126erun :: FC -> Elab' aux a -> Elab' aux a
@@ -353,6 +353,9 @@ claimFn n bn t = processTactic' (ClaimFn n bn t)
353353unifyGoal :: Raw -> Elab' aux ()
354354unifyGoal t = processTactic' (UnifyGoal t)
355355
356+unifyTerms :: Raw -> Raw -> Elab' aux ()
357+unifyTerms t1 t2 = processTactic' (UnifyTerms t1 t2)
358+
356359exact :: Raw -> Elab' aux ()
357360exact t = processTactic' (Exact t)
358361
@@ -711,8 +714,8 @@ checkPiGoal n
711714 = do g <- goal
712715 case g of
713716 Bind _ (Pi _ _ _) _ -> return ()
714− _ -> do a <- getNameFrom (sMN 0 "pargTy")
715− b <- getNameFrom (sMN 0 "pretTy")
717+ _ -> do a <- getNameFrom (sMN 0 "__pargTy")
718+ b <- getNameFrom (sMN 0 "__pretTy")
716719 f <- getNameFrom (sMN 0 "pf")
717720 claim a RType
718721 claim b RType
@@ -724,9 +727,14 @@ checkPiGoal n
724727 focus f
725728
726729simple_app :: Bool -> Elab' aux () -> Elab' aux () -> String -> Elab' aux ()
727−simple_app infer fun arg str =
728− do a <- getNameFrom (sMN 0 "argTy")
729− b <- getNameFrom (sMN 0 "retTy")
730+simple_app infer fun arg str =
731+ try (dep_app fun arg str)
732+ (infer_app infer fun arg str)
733+
734+infer_app :: Bool -> Elab' aux () -> Elab' aux () -> String -> Elab' aux ()
735+infer_app infer fun arg str =
736+ do a <- getNameFrom (sMN 0 "__argTy")
737+ b <- getNameFrom (sMN 0 "__retTy")
730738 f <- getNameFrom (sMN 0 "f")
731739 s <- getNameFrom (sMN 0 "s")
732740 claim a RType
@@ -755,8 +763,49 @@ simple_app infer fun arg str =
755763 when (a `elem` hs) $ do movelast a
756764 when (b `elem` hs) $ do movelast b
757765 end_unify
758− where
759− regretWith err = try regret (lift $ tfail err)
766+
767+dep_app :: Elab' aux () -> Elab' aux () -> String -> Elab' aux ()
768+dep_app fun arg str =
769+ do a <- getNameFrom (sMN 0 "__argTy")
770+ b <- getNameFrom (sMN 0 "__retTy")
771+ fty <- getNameFrom (sMN 0 "__fnTy")
772+ f <- getNameFrom (sMN 0 "f")
773+ s <- getNameFrom (sMN 0 "s")
774+ claim a RType
775+ claim fty RType
776+ claim f (Var fty)
777+ tm <- get_term
778+ g <- goal
779+ start_unify s
780+ claim s (Var a)
781+
782+ prep_fill f [s]
783+ focus f; attack; fun
784+ end_unify
785+ fty <- goal
786+ solve
787+ focus s; attack;
788+ ctxt <- get_context
789+ env <- get_env
790+ case normalise ctxt env fty of
791+ -- if f gives a function type, unify our argument type with
792+ -- f's expected argument type
793+ Bind _ (Pi _ argty _) _ -> unifyGoal (forget argty)
794+ -- Can't infer a type for 'f', so fail here (and drop back to
795+ -- simply typed application where we infer the type for f)
796+ _ -> fail "Can't make type"
797+ end_unify
798+ arg
799+ solve
800+ complete_fill
801+
802+ -- We don't need a and b in the hole queue any more since they were
803+ -- just for checking f, so move them to the end. If they never end up
804+ -- getting solved, we'll get an 'Incomplete term' error.
805+ hs <- get_holes
806+ when (a `elem` hs) $ do movelast a
807+ when (b `elem` hs) $ do movelast b
808+ end_unify
760809
761810-- Abstract over an argument of unknown type, giving a name for the hole
762811-- which we'll fill with the argument type too.
src/Idris/Core/Evaluate.hs+10−1
@@ -2,7 +2,8 @@
22 PatternGuards #-}
33{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
44
5−module Idris.Core.Evaluate(normalise, normaliseTrace, normaliseC, normaliseAll, toValue, quoteTerm,
5+module Idris.Core.Evaluate(normalise, normaliseTrace, normaliseC,
6+ normaliseAll, normaliseBlocking, toValue, quoteTerm,
67 rt_simplify, simplify, specialise, hnf, convEq, convEq',
78 Def(..), CaseInfo(..), CaseDefs(..),
89 Accessibility(..), Totality(..), PReason(..), MetaInformation(..),
@@ -79,11 +80,19 @@ normaliseC ctxt env t
7980 = evalState (do val <- eval False ctxt [] (map finalEntry env) t []
8081 quote 0 val) initEval
8182
83+-- | Normalise everything, whether abstract, private or public
8284normaliseAll :: Context -> Env -> TT Name -> TT Name
8385normaliseAll ctxt env t
8486 = evalState (do val <- eval False ctxt [] (map finalEntry env) t [AtREPL]
8587 quote 0 val) initEval
8688
89+-- | As normaliseAll, but with an explicit list of names *not* to reduce
90+normaliseBlocking :: Context -> Env -> [Name] -> TT Name -> TT Name
91+normaliseBlocking ctxt env blocked t
92+ = evalState (do val <- eval False ctxt (map (\n -> (n, 0)) blocked)
93+ (map finalEntry env) t [AtREPL]
94+ quote 0 val) initEval
95+
8796normalise :: Context -> Env -> TT Name -> TT Name
8897normalise = normaliseTrace False
8998
src/Idris/Core/Execute.hs+11
@@ -349,6 +349,17 @@ execForeign env ctxt arity ty fn xs onfail
349349 "The argument to fileEOF should be a file handle, but it was " ++
350350 show handle ++
351351 ". Are all cases covered?"
352+ | Just (FFun "fileError" [(_,handle)] _) <- foreignFromTT arity ty fn xs
353+ = case handle of
354+ -- errors handled differently in Haskell than in C, so if
355+ -- there's been an error we'll have had an exception already.
356+ -- Therefore, assume we're okay.
357+ EHandle h -> do let res = ioWrap (EConstant (I 0))
358+ execApp env ctxt res (drop arity xs)
359+ _ -> execFail . Msg $
360+ "The argument to fileError should be a file handle, but it was " ++
361+ show handle ++
362+ ". Are all cases covered?"
352363 | Just (FFun "fileClose" [(_,handle)] _) <- foreignFromTT arity ty fn xs
353364 = case handle of
354365 EHandle h -> do execIO $ hClose h
src/Idris/Core/ProofState.hs+20−2
@@ -91,6 +91,7 @@ data Tactic = Attack
9191 | MatchProblems Bool
9292 | UnifyProblems
9393 | UnifyGoal Raw
94+ | UnifyTerms Raw Raw
9495 | ProofState
9596 | Undo
9697 | QED
@@ -408,6 +409,8 @@ instanceArg n ctxt env (Bind x (Hole t) sc)
408409 ps { holes = (hs \\ [x]) ++ [x],
409410 instances = x:is })
410411 return (Bind x (Hole t) sc)
412+instanceArg n ctxt env _
413+ = fail "The current focus is not a hole."
411414
412415autoArg :: Name -> RunTactic
413416autoArg n ctxt env (Bind x (Hole t) sc)
@@ -418,6 +421,8 @@ autoArg n ctxt env (Bind x (Hole t) sc)
418421 autos = (x, (while_elaborating ps, refsIn t)) : autos ps }
419422 Just _ -> ps)
420423 return (Bind x (Hole t) sc)
424+autoArg n ctxt env _
425+ = fail "The current focus not a hole."
421426
422427setinj :: Name -> RunTactic
423428setinj n ctxt env (Bind x b sc)
@@ -439,6 +444,7 @@ defer dropped n ctxt env (Bind x (Hole t) (P nt x' ty)) | x == x' =
439444 mkTy ((n,b) : bs) t = Bind n (Pi Nothing (binderTy b) (TType (UVar 0))) (mkTy bs t)
440445
441446 getP (n, b) = P Bound n (binderTy b)
447+defer dropped n ctxt env _ = fail "Can't defer a non-hole focus."
442448
443449-- as defer, but build the type and application explicitly
444450deferType :: Name -> Raw -> [Name] -> RunTactic
@@ -454,6 +460,7 @@ deferType n fty_in args ctxt env (Bind x (Hole t) (P nt x' ty)) | x == x' =
454460 getP n = case lookup n env of
455461 Just b -> P Bound n (binderTy b)
456462 Nothing -> error ("deferType can't find " ++ show n)
463+deferType _ _ _ _ _ _ = fail "Can't defer a non-hole focus."
457464
458465regret :: RunTactic
459466regret ctxt env (Bind x (Hole t) sc) | noOccurrence x sc =
@@ -462,12 +469,21 @@ regret ctxt env (Bind x (Hole t) sc) | noOccurrence x sc =
462469 return sc
463470regret ctxt env (Bind x (Hole t) _)
464471 = fail $ show x ++ " : " ++ show t ++ " is not solved..."
472+regret _ _ _ = fail "The current focus is not a hole."
465473
466474unifyGoal :: Raw -> RunTactic
467475unifyGoal tm ctxt env h@(Bind x b sc) =
468476 do (tmv, _) <- lift $ check ctxt env tm
469477 ns' <- unify' ctxt env (binderTy b, Nothing) (tmv, Nothing)
470478 return h
479+unifyGoal _ _ _ _ = fail "The focus is not a binder."
480+
481+unifyTerms :: Raw -> Raw -> RunTactic
482+unifyTerms tm1 tm2 ctxt env h =
483+ do (tm1v, _) <- lift $ check ctxt env tm1
484+ (tm2v, _) <- lift $ check ctxt env tm2
485+ ns' <- unify' ctxt env (tm1v, Nothing) (tm2v, Nothing)
486+ return h
471487
472488exact :: Raw -> RunTactic
473489exact guess ctxt env (Bind x (Hole ty) sc) =
@@ -714,7 +730,7 @@ casetac tm induction ctxt env (Bind x (Hole t) (P _ x' _)) | x == x' = do
714730 let tmt' = normalise ctxt env tmt
715731 let (tacn, tacstr, tactt) = if induction
716732 then (ElimN, "eliminator", "Induction")
717− else (CaseN, "case analysis", "Case analysis")
733+ else (CaseN (FC' emptyFC), "case analysis", "Case analysis")
718734 case unApply tmt' of
719735 (P _ tnm _, tyargs) -> do
720736 case lookupTy (SN (tacn tnm)) ctxt of
@@ -870,7 +886,7 @@ updateProv ns p = p
870886
871887updateError [] err = err
872888updateError ns (At f e) = At f (updateError ns e)
873−updateError ns (Elaborating s n e) = Elaborating s n (updateError ns e)
889+updateError ns (Elaborating s n ty e) = Elaborating s n ty (updateError ns e)
874890updateError ns (ElaboratingArg f a env e)
875891 = ElaboratingArg f a env (updateError ns e)
876892updateError ns (CantUnify b (l,lp) (r,rp) e xs sc)
@@ -1105,3 +1121,5 @@ process t h = tactic (Just h) (mktac t)
11051121 mktac (SetInjective n) = setinj n
11061122 mktac (MoveLast n) = movelast n
11071123 mktac (UnifyGoal r) = unifyGoal r
1124+ mktac (UnifyTerms x y) = unifyTerms x y
1125+
src/Idris/Core/TT.hs+52−25
@@ -58,6 +58,7 @@ import Debug.Trace
5858import qualified Data.Map.Strict as Map
5959import Data.Char
6060import Data.Data (Data)
61+import Data.Monoid (mconcat)
6162import Numeric (showIntAtBase)
6263import qualified Data.Text as T
6364import Data.List hiding (group, insert)
@@ -148,7 +149,7 @@ instance Eq FC where
148149 _ == _ = True
149150
150151-- | FC with equality
151−newtype FC' = FC' { unwrapFC :: FC }
152+newtype FC' = FC' { unwrapFC :: FC } deriving (Data, Typeable, Ord)
152153
153154instance Eq FC' where
154155 FC' fc == FC' fc' = fcEq fc fc'
@@ -157,6 +158,9 @@ instance Eq FC' where
157158 fcEq (FileFC f) (FileFC f') = f == f'
158159 fcEq _ _ = False
159160
161+instance Show FC' where
162+ showsPrec d (FC' fc) = showsPrec d fc
163+
160164-- | Empty source location
161165emptyFC :: FC
162166emptyFC = NoFC
@@ -283,7 +287,7 @@ data Err' t
283287 | ProofSearchFail (Err' t)
284288 | NoRewriting t
285289 | At FC (Err' t)
286− | Elaborating String Name (Err' t)
290+ | Elaborating String Name (Maybe t) (Err' t)
287291 | ElaboratingArg Name Name [(Name, Name)] (Err' t)
288292 | ProviderError String
289293 | LoadingFailed String (Err' t)
@@ -293,6 +297,8 @@ data Err' t
293297 -- ^ User-specified message, proof term, goals with context (first goal is focused)
294298 | ElabScriptStuck t
295299 | RunningElabScript (Err' t) -- ^ The error occurred during a top-level elaboration script
300+ | ElabScriptStaging Name
301+ | FancyMsg [ErrorReportPart]
296302 deriving (Eq, Functor, Data, Typeable)
297303
298304type Err = Err' Term
@@ -354,7 +360,7 @@ instance Sized Err where
354360 size (IncompleteTerm trm) = size trm
355361 size ProgramLineComment = 1
356362 size (At fc err) = size fc + size err
357− size (Elaborating _ n err) = size err
363+ size (Elaborating _ _ _ err) = size err
358364 size (ElaboratingArg _ _ _ err) = size err
359365 size (ProviderError msg) = length msg
360366 size (LoadingFailed fn e) = 1 + length fn + size e
@@ -375,7 +381,11 @@ instance Show Err where
375381 show (At f e) = show f ++ ":" ++ show e
376382 show (ElaboratingArg f x prev e) = "Elaborating " ++ show f ++ " arg " ++
377383 show x ++ ": " ++ show e
378− show (Elaborating what n e) = "Elaborating " ++ what ++ show n ++ ":" ++ show e
384+ show (Elaborating what n ty e) = "Elaborating " ++ what ++ show n ++
385+ showType ty ++ ":" ++ show e
386+ where
387+ showType Nothing = ""
388+ showType (Just ty) = " with expected type " ++ show ty
379389 show (ProofSearchFail e) = "Proof search fail: " ++ show e
380390 show (InfiniteUnify _ _ _) = "InfiniteUnify"
381391 show (UnifyScope _ _ _ _) = "UnifyScope"
@@ -442,7 +452,6 @@ traceWhen False _ a = a
442452data Name = UN !T.Text -- ^ User-provided name
443453 | NS !Name [T.Text] -- ^ Root, namespaces
444454 | MN !Int !T.Text -- ^ Machine chosen names
445− | NErased -- ^ Name of something which is never used in scope
446455 | SN !SpecialName -- ^ Decorated function names
447456 | SymRef Int -- ^ Reference to IBC file symbol table (used during serialisation)
448457 deriving (Eq, Ord, Data, Typeable)
@@ -479,7 +488,7 @@ data SpecialName = WhereN !Int !Name !Name
479488 | InstanceN !Name [T.Text]
480489 | ParentN !Name !T.Text
481490 | MethodN !Name
482− | CaseN !Name
491+ | CaseN !FC' !Name
483492 | ElimN !Name
484493 | InstanceCtorN !Name
485494 | MetaN !Name !Name
@@ -509,7 +518,6 @@ instance Pretty Name OutputAnnotation where
509518 pretty n@(SN s) = annotate (AnnName n Nothing Nothing Nothing) $ text (show s)
510519 pretty n@(SymRef i) = annotate (AnnName n Nothing Nothing Nothing) $
511520 text $ "##symbol" ++ show i ++ "##"
512− pretty NErased = annotate (AnnName NErased Nothing Nothing Nothing) $ text "_"
513521
514522instance Pretty [Name] OutputAnnotation where
515523 pretty = encloseSep empty empty comma . map pretty
@@ -521,7 +529,6 @@ instance Show Name where
521529 show (MN i s) = "{" ++ str s ++ show i ++ "}"
522530 show (SN s) = show s
523531 show (SymRef i) = "##symbol" ++ show i ++ "##"
524− show NErased = "_"
525532
526533instance Show SpecialName where
527534 show (WhereN i p c) = show p ++ ", " ++ show c
@@ -529,7 +536,8 @@ instance Show SpecialName where
529536 show (InstanceN cl inst) = showSep ", " (map T.unpack inst) ++ " instance of " ++ show cl
530537 show (MethodN m) = "method " ++ show m
531538 show (ParentN p c) = show p ++ "#" ++ T.unpack c
532− show (CaseN n) = "case block in " ++ show n
539+ show (CaseN fc n) = "case block in " ++ show n ++
540+ if fc == FC' emptyFC then "" else " at " ++ show fc
533541 show (ElimN n) = "<<" ++ show n ++ " eliminator>>"
534542 show (InstanceCtorN n) = "constructor of " ++ show n
535543 show (MetaN parent meta) = "<<" ++ show parent ++ " " ++ show meta ++ ">>"
@@ -546,12 +554,20 @@ showCG (SN s) = showCG' s
546554 showCG' (InstanceN cl inst) = '@':showCG cl ++ '$':showSep ":" (map T.unpack inst)
547555 showCG' (MethodN m) = '!':showCG m
548556 showCG' (ParentN p c) = showCG p ++ "#" ++ show c
549− showCG' (CaseN c) = showCG c ++ "_case"
557+ showCG' (CaseN fc c) = showCG c ++ showFC' fc ++ "_case"
550558 showCG' (ElimN sn) = showCG sn ++ "_elim"
551559 showCG' (InstanceCtorN n) = showCG n ++ "_ictor"
552560 showCG' (MetaN parent meta) = showCG parent ++ "_meta_" ++ showCG meta
561+ showFC' (FC' NoFC) = ""
562+ showFC' (FC' (FileFC f)) = "_" ++ cgFN f
563+ showFC' (FC' (FC f s e))
564+ | s == e = "_" ++ cgFN f ++
565+ "_" ++ show (fst s) ++ "_" ++ show (snd s)
566+ | otherwise = "_" ++ cgFN f ++
567+ "_" ++ show (fst s) ++ "_" ++ show (snd s) ++
568+ "_" ++ show (fst e) ++ "_" ++ show (snd e)
569+ cgFN = concatMap (\c -> if not (isDigit c || isLetter c) then "__" else [c])
553570showCG (SymRef i) = error "can't do codegen for a symbol reference"
554−showCG NErased = "_"
555571
556572
557573-- |Contexts allow us to map names to things. A root name maps to a collection
@@ -776,7 +792,6 @@ data Raw = Var Name
776792 | RApp Raw Raw
777793 | RType
778794 | RUType Universe
779− | RForce Raw
780795 | RConstant Const
781796 deriving (Show, Eq, Data, Typeable)
782797
@@ -786,7 +801,6 @@ instance Sized Raw where
786801 size (RApp left right) = 1 + size left + size right
787802 size RType = 1
788803 size (RUType _) = 1
789− size (RForce raw) = 1 + size raw
790804 size (RConstant const) = size const
791805
792806instance Pretty Raw OutputAnnotation where
@@ -797,7 +811,7 @@ deriving instance Binary Raw
797811deriving instance NFData Raw
798812!-}
799813
800−data ImplicitInfo = Impl { tcinstance :: Bool }
814+data ImplicitInfo = Impl { tcinstance :: Bool, toplevel_imp :: Bool }
801815 deriving (Show, Eq, Ord, Data, Typeable)
802816
803817{-!
@@ -812,27 +826,44 @@ deriving instance NFData ImplicitInfo
812826-- the types of bindings (and their values, if any); the attached identifiers are part
813827-- of the 'Bind' constructor for the 'TT' type.
814828data Binder b = Lam { binderTy :: !b {-^ type annotation for bound variable-}}
829+ -- ^ A function binding
815830 | Pi { binderImpl :: Maybe ImplicitInfo,
816831 binderTy :: !b,
817832 binderKind :: !b }
818− {-^ A binding that occurs in a function type expression, e.g. @(x:Int) -> ...@
819− The 'binderImpl' flag says whether it was a scoped implicit
820− (i.e. forall bound) in the high level Idris, but otherwise
821− has no relevance in TT. -}
833+ -- ^ A binding that occurs in a function type
834+ -- expression, e.g. @(x:Int) -> ...@ The 'binderImpl'
835+ -- flag says whether it was a scoped implicit
836+ -- (i.e. forall bound) in the high level Idris, but
837+ -- otherwise has no relevance in TT.
822838 | Let { binderTy :: !b,
823839 binderVal :: b {-^ value for bound variable-}}
824840 -- ^ A binding that occurs in a @let@ expression
825841 | NLet { binderTy :: !b,
826842 binderVal :: b }
843+ -- ^ NLet is an intermediate product in the evaluator
844+ -- that's used for temporarily naming locals during
845+ -- reduction. It won't occur outside the evaluator.
827846 | Hole { binderTy :: !b}
847+ -- ^ A hole in a term under construction in the
848+ -- elaborator. If this is not filled during
849+ -- elaboration, it is an error.
828850 | GHole { envlen :: Int,
829851 localnames :: [Name],
830852 binderTy :: !b}
853+ -- ^ A saved TT hole that will later be converted to a
854+ -- top-level Idris metavariable applied to all
855+ -- elements of its local environment.
831856 | Guess { binderTy :: !b,
832857 binderVal :: b }
858+ -- ^ A provided value for a hole. It will later be
859+ -- substituted - the guess is to keep it
860+ -- computationally inert while working on other things
861+ -- if necessary.
833862 | PVar { binderTy :: !b }
834− -- ^ A pattern variable
863+ -- ^ A pattern variable (these are bound around terms
864+ -- that make up pattern-match clauses)
835865 | PVTy { binderTy :: !b }
866+ -- ^ The type of a pattern binding
836867 deriving (Show, Eq, Ord, Functor, Foldable, Traversable, Data, Typeable)
837868{-!
838869deriving instance Binary Binder
@@ -1420,12 +1451,11 @@ nextName (SN x) = SN (nextName' x)
14201451 nextName' (WithN i n) = WithN i (nextName n)
14211452 nextName' (InstanceN n ns) = InstanceN (nextName n) ns
14221453 nextName' (ParentN n ns) = ParentN (nextName n) ns
1423− nextName' (CaseN n) = CaseN (nextName n)
1454+ nextName' (CaseN fc n) = CaseN fc (nextName n)
14241455 nextName' (ElimN n) = ElimN (nextName n)
14251456 nextName' (MethodN n) = MethodN (nextName n)
14261457 nextName' (InstanceCtorN n) = InstanceCtorN (nextName n)
14271458 nextName' (MetaN parent meta) = MetaN parent (nextName meta)
1428−nextName NErased = NErased
14291459nextName (SymRef i) = error "Can't generate a name from a symbol reference"
14301460
14311461type Term = TT Name
@@ -1582,7 +1612,7 @@ pureTerm (Bind n b sc) = notClassName n && pureBinder b && pureTerm sc where
15821612 pureBinder (Let t v) = pureTerm t && pureTerm v
15831613 pureBinder t = pureTerm (binderTy t)
15841614
1585− notClassName (MN _ c) | c == txt "class" = False
1615+ notClassName (MN _ c) | c == txt "__class" = False
15861616 notClassName _ = True
15871617
15881618pureTerm _ = True
@@ -1823,9 +1853,6 @@ pprintRaw bound (RApp f x) =
18231853pprintRaw bound RType = text "RType"
18241854pprintRaw bound (RUType u) = enclose lparen rparen . group . align . hang 2 $
18251855 text "RUType" <$> text (show u)
1826−pprintRaw bound (RForce r) =
1827− enclose lparen rparen . group . align . hang 2 $
1828− vsep [text "RForce", pprintRaw bound r]
18291856pprintRaw bound (RConstant c) =
18301857 enclose lparen rparen . group . align . hang 2 $
18311858 vsep [text "RConstant", annotate (AnnConst c) (text (show c))]
src/Idris/Core/Typecheck.hs−3
@@ -160,9 +160,6 @@ check' holes ctxt env top = chk (TType (UVar (-5))) env top where
160160 constType TheWorld = Constant WorldType
161161 constType Forgot = Erased
162162 constType _ = TType (UVal 0)
163− chk u env (RForce t)
164− = do (_, ty) <- chk u env t
165− return (Erased, ty)
166163 chk u env (RBind n (Pi i s k) t)
167164 = do (sv, st) <- chk u env s
168165 (v, cs) <- get
src/Idris/Core/Unify.hs+1−1
@@ -40,7 +40,7 @@ unrecoverable = any bad
4040
4141 unrec (CantUnify r _ _ _ _ _) = not r
4242 unrec (At _ e) = unrec e
43− unrec (Elaborating _ _ e) = unrec e
43+ unrec (Elaborating _ _ _ e) = unrec e
4444 unrec (ElaboratingArg _ _ _ e) = unrec e
4545 unrec _ = False
4646
src/Idris/Core/WHNF.hs+8−8
@@ -1,7 +1,7 @@
11{-# LANGUAGE PatternGuards #-}
22{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
33
4−-- Reduction to Weak Head Normal Form
4+-- | Reduction to Weak Head Normal Form
55module Idris.Core.WHNF(whnf, WEnv) where
66
77import Idris.Core.TT
@@ -11,7 +11,7 @@ import qualified Idris.Core.Evaluate as Evaluate
1111
1212import Debug.Trace
1313
14−-- A stack entry consists of a term and the environment it is to be
14+-- | A stack entry consists of a term and the environment it is to be
1515-- evaluated in (i.e. it's a thunk)
1616type StackEntry = (Term, WEnv)
1717data WEnv = WEnv Int -- number of free variables
@@ -20,17 +20,17 @@ data WEnv = WEnv Int -- number of free variables
2020
2121type Stack = [StackEntry]
2222
23−-- A WHNF is a top level term evaluated in the empty environment. It is
23+-- | A WHNF is a top level term evaluated in the empty environment. It is
2424-- always headed by either an irreducible expression, i.e. a constructor,
2525-- a lambda, a constant, or a postulate
26−
26+--
2727-- Every 'Term' or 'Type' in this structure is associated with the
2828-- environment it was encountered in, so that when we quote back to a term
2929-- we get the substitutions right.
3030
31−data WHNF = WDCon Int Int Bool Name (Type, WEnv) -- data constructor
32− | WTCon Int Int Name (Type, WEnv) -- type constructor
33− | WPRef Name (Type, WEnv) -- irreducible global (e.g. a postulate)
31+data WHNF = WDCon Int Int Bool Name (Type, WEnv) -- ^ data constructor
32+ | WTCon Int Int Name (Type, WEnv) -- ^ type constructor
33+ | WPRef Name (Type, WEnv) -- ^irreducible global (e.g. a postulate)
3434 | WBind Name (Binder Term) (Term, WEnv)
3535 | WApp WHNF (Term, WEnv)
3636 | WConstant Const
@@ -40,7 +40,7 @@ data WHNF = WDCon Int Int Bool Name (Type, WEnv) -- data constructor
4040 | WErased
4141 | WImpossible
4242
43−-- Reduce a *closed* term to weak head normal form.
43+-- | Reduce a *closed* term to weak head normal form.
4444whnf :: Context -> Term -> Term
4545whnf ctxt tm = quote (do_whnf ctxt (WEnv 0 []) tm)
4646
src/Idris/Coverage.hs+26−76
@@ -56,17 +56,17 @@ genClauses fc n xs given
5656 = do i <- getIState
5757 let lhs_tms = map (\x -> flattenArgs $ delab' i x True True) xs
5858 -- if a placeholder was given, don't bother generating cases for it
59− let lhs_tms' = zipWith mergePlaceholders lhs_tms
59+ let lhs_tms' = zipWith mergePlaceholders lhs_tms
6060 (map (stripUnmatchable i) (map flattenArgs given))
6161 let lhss = map pUnApply lhs_tms'
6262
6363 let argss = transpose lhss
6464 let all_args = map (genAll i) argss
65− logLvl 5 $ "COVERAGE of " ++ show n
66− logLvl 5 $ show (lhs_tms, lhss)
67− logLvl 5 $ show (map length argss) ++ "\n" ++ show (map length all_args)
68− logLvl 10 $ show argss ++ "\n" ++ show all_args
69− logLvl 3 $ "Original: \n" ++
65+ logCoverage 5 $ "COVERAGE of " ++ show n
66+ logCoverage 5 $ show (lhs_tms, lhss)
67+ logCoverage 5 $ show (map length argss) ++ "\n" ++ show (map length all_args)
68+ logCoverage 10 $ show argss ++ "\n" ++ show all_args
69+ logCoverage 3 $ "Original: \n" ++
7070 showSep "\n" (map (\t -> showTm i (delab' i t True True)) xs)
7171 -- add an infinite supply of explicit arguments to update the possible
7272 -- cases for (the return type may be variadic, or function type, so
@@ -77,11 +77,11 @@ genClauses fc n xs given
7777 p ++ repeat (PExp 0 [] (sMN 0 "gcarg") Placeholder)
7878 _ -> repeat (pexp Placeholder)
7979 let tryclauses = mkClauses parg all_args
80− logLvl 3 $ show (length tryclauses) ++ " initially to check"
81− logLvl 2 $ showSep "\n" (map (showTm i) tryclauses)
80+ logCoverage 3 $ show (length tryclauses) ++ " initially to check"
81+ logCoverage 2 $ showSep "\n" (map (showTm i) tryclauses)
8282 let new = filter (noMatch i) (nub tryclauses)
83− logLvl 2 $ show (length new) ++ " clauses to check for impossibility"
84− logLvl 4 $ "New clauses: \n" ++ showSep "\n" (map (showTm i) new)
83+ logCoverage 2 $ show (length new) ++ " clauses to check for impossibility"
84+ logCoverage 4 $ "New clauses: \n" ++ showSep "\n" (map (showTm i) new)
8585-- ++ " from:\n" ++ showSep "\n" (map (showImp True) tryclauses)
8686 return new
8787-- return (map (\t -> PClause n t [] PImpossible []) new)
@@ -92,7 +92,7 @@ genClauses fc n xs given
9292 pUnApply (PApp _ f args) = map getTm args
9393 pUnApply _ = []
9494
95− flattenArgs (PApp fc (PApp _ f as) as')
95+ flattenArgs (PApp fc (PApp _ f as) as')
9696 = flattenArgs (PApp fc f (as ++ as'))
9797 flattenArgs t = t
9898
@@ -137,7 +137,7 @@ validCoverageCase ctxt (CantUnify _ (topx, _) (topy, _) e _ _)
137137 _ -> False
138138validCoverageCase ctxt (CantConvert _ _ _) = False
139139validCoverageCase ctxt (At _ e) = validCoverageCase ctxt e
140−validCoverageCase ctxt (Elaborating _ _ e) = validCoverageCase ctxt e
140+validCoverageCase ctxt (Elaborating _ _ _ e) = validCoverageCase ctxt e
141141validCoverageCase ctxt (ElaboratingArg _ _ _ e) = validCoverageCase ctxt e
142142validCoverageCase ctxt _ = True
143143
@@ -167,7 +167,7 @@ recoverableCoverage ctxt (CantUnify r (topx, _) (topy, _) e _ _)
167167 | (Bound, Bound) <- (x, y) = True
168168 | otherwise = False -- name is different, unrecoverable
169169recoverableCoverage ctxt (At _ e) = recoverableCoverage ctxt e
170−recoverableCoverage ctxt (Elaborating _ _ e) = recoverableCoverage ctxt e
170+recoverableCoverage ctxt (Elaborating _ _ _ e) = recoverableCoverage ctxt e
171171recoverableCoverage ctxt (ElaboratingArg _ _ _ e) = recoverableCoverage ctxt e
172172recoverableCoverage _ _ = False
173173
@@ -248,7 +248,7 @@ genAll i args
248248
249249 -- put it back to its original form
250250 resugar (PApp _ (PRef fc hl n) [_,_,t,v])
251− | n == sigmaCon
251+ | n == sigmaCon
252252 = PDPair fc [] TypeOrTerm (getTm t) Placeholder (getTm v)
253253 resugar (PApp _ (PRef fc hl n) [_,_,l,r])
254254 | n == pairCon
@@ -330,7 +330,7 @@ checkPositive mut_ns (cn, ty')
330330 let tot = if p then Total (args ty) else Partial NotPositive
331331 let ctxt' = setTotal cn tot (tt_ctxt i)
332332 putIState (i { tt_ctxt = ctxt' })
333− logLvl 5 $ "Constructor " ++ show cn ++ " is " ++ show tot ++ " with " ++ show mut_ns
333+ logCoverage 5 $ "Constructor " ++ show cn ++ " is " ++ show tot ++ " with " ++ show mut_ns
334334 addIBC (IBCTotal cn tot)
335335 return tot
336336 where
@@ -351,56 +351,6 @@ checkPositive mut_ns (cn, ty')
351351 noRec arg = all (\x -> x `notElem` mut_ns) (allTTNames arg)
352352
353353
354−calcProd :: IState -> FC -> Name -> [([Name], Term, Term)] -> Idris Totality
355−calcProd i fc topn pats
356− = cp topn pats []
357− where
358− -- every application of n must be in an argument of a coinductive
359− -- constructor, in every function reachable from here in the
360− -- call graph.
361− cp n pats done = do patsprod <- mapM (prodRec n done) pats
362− if (and patsprod)
363− then return Productive
364− else return (Partial NotProductive)
365−
366− prodRec :: Name -> [Name] -> ([Name], Term, Term) -> Idris Bool
367− prodRec n done _ | n `elem` done = return True
368− prodRec n done (_, _, tm) = prod n done False (delazy' True tm)
369−
370− prod :: Name -> [Name] -> Bool -> Term -> Idris Bool
371− prod n done ok ap@(App _ _ _)
372− | (P nt f _, args) <- unApply ap
373− = do recOK <- checkProdRec (n:done) f
374− let ctxt = tt_ctxt i
375− let [ty] = lookupTy f ctxt -- must exist!
376− let co = cotype nt f ty in
377− if (not recOK) then return False else
378− if f == topn
379− then do argsprod <- mapM (prod n done co) args
380− return (and (ok : argsprod) )
381− else do argsprod <- mapM (prod n done co) args
382− return (and argsprod)
383− prod n done ok (App _ f a) = liftM2 (&&) (prod n done False f)
384− (prod n done False a)
385− prod n done ok (Bind _ (Let t v) sc)
386− = liftM2 (&&) (prod n done False v) (prod n done False v)
387− prod n done ok (Bind _ b sc) = prod n done ok sc
388− prod n done ok t = return True
389−
390− checkProdRec :: [Name] -> Name -> Idris Bool
391− checkProdRec done f
392− = case lookupCtxt f (idris_patdefs i) of
393− [(def, _)] -> do ok <- mapM (prodRec f done) def
394− return (and ok)
395− _ -> return True -- defined elsewhere, can't call topn
396−
397− cotype (DCon _ _ _) n ty
398− | (P _ t _, _) <- unApply (getRetTy ty)
399− = case lookupCtxt t (idris_datatypes i) of
400− [TI _ True _ _ _] -> True
401− _ -> False
402− cotype nt n ty = False
403−
404354-- | Calculate the totality of a function from its patterns.
405355-- Either follow the size change graph (if inductive) or check for
406356-- productivity (if coinductive)
@@ -482,9 +432,9 @@ checkTotality path fc n
482432
483433checkDeclTotality :: (FC, Name) -> Idris Totality
484434checkDeclTotality (fc, n)
485− = do logLvl 2 $ "Checking " ++ show n ++ " for totality"
435+ = do logCoverage 2 $ "Checking " ++ show n ++ " for totality"
486436-- buildSCG (fc, n)
487−-- logLvl 2 $ "Built SCG"
437+-- logCoverage 2 $ "Built SCG"
488438 i <- getIState
489439 let opts = case lookupCtxt n (idris_flags i) of
490440 [fs] -> fs
@@ -496,7 +446,7 @@ checkDeclTotality (fc, n)
496446 -- typechecking decidable
497447 p@(Partial _) -> do setAccessibility n Frozen
498448 addIBC (IBCAccess n Frozen)
499− logLvl 5 $ "HIDDEN: "
449+ logCoverage 5 $ "HIDDEN: "
500450 ++ show n ++ show p
501451 _ -> return ()
502452 return t
@@ -519,12 +469,12 @@ buildSCG (_, n) = do
519469 [cg] -> case lookupDefExact n (tt_ctxt ist) of
520470 Just (CaseOp _ _ _ pats _ cd) ->
521471 let (args, sc) = cases_totcheck cd in
522− do logLvl 2 $ "Building SCG for " ++ show n ++ " from\n"
472+ do logCoverage 2 $ "Building SCG for " ++ show n ++ " from\n"
523473 ++ show pats ++ "\n" ++ show sc
524474 let newscg = buildSCG' ist (rights pats) args
525− logLvl 5 $ "SCG is: " ++ show newscg
475+ logCoverage 5 $ "SCG is: " ++ show newscg
526476 addToCG n ( cg { scg = newscg } )
527− [] -> logLvl 5 $ "Could not build SCG for " ++ show n ++ "\n"
477+ [] -> logCoverage 5 $ "Could not build SCG for " ++ show n ++ "\n"
528478 x -> error $ "buildSCG: " ++ show (n, x)
529479
530480delazy = delazy' False -- not lazy codata
@@ -644,20 +594,20 @@ checkSizeChange n = do
644594 ist <- getIState
645595 case lookupCtxt n (idris_callgraph ist) of
646596 [cg] -> do let ms = mkMultiPaths ist [] (scg cg)
647− logLvl 5 ("Multipath for " ++ show n ++ ":\n" ++
597+ logCoverage 5 ("Multipath for " ++ show n ++ ":\n" ++
648598 "from " ++ show (scg cg) ++ "\n" ++
649599 show (length ms) ++ "\n" ++
650600 showSep "\n" (map show ms))
651− logLvl 6 (show cg)
601+ logCoverage 6 (show cg)
652602 -- every multipath must have an infinitely descending
653603 -- thread, then the function terminates
654604 -- also need to checks functions called are all total
655605 -- (Unchecked is okay as we'll spot problems here)
656606 let tot = map (checkMP ist (getArity ist n)) ms
657− logLvl 4 $ "Generated " ++ show (length tot) ++ " paths"
658− logLvl 6 $ "Paths for " ++ show n ++ " yield " ++ (show tot)
607+ logCoverage 4 $ "Generated " ++ show (length tot) ++ " paths"
608+ logCoverage 6 $ "Paths for " ++ show n ++ " yield " ++ (show tot)
659609 return (noPartial tot)
660− [] -> do logLvl 5 $ "No paths for " ++ show n
610+ [] -> do logCoverage 5 $ "No paths for " ++ show n
661611 return Unchecked
662612 where getArity ist n
663613 = case lookupTy n (tt_ctxt ist) of
src/Idris/DSL.hs+7−4
@@ -42,7 +42,7 @@ mkTTName fc n =
4242 , pexp (mkList fc ns)]
4343 MN i nm -> PApp fc (PRef fc [] (reflm "MN")) [ pexp (intC i)
4444 , pexp (stringC nm)]
45− otherwise -> PRef fc [] $ reflm "NErased"
45+ _ -> error "Invalid name from user syntax for DSL name"
4646
4747expandSugar :: DSL -> PTerm -> PTerm
4848expandSugar dsl (PLam fc n nfc ty tm)
@@ -98,8 +98,8 @@ expandSugar dsl (PDoBlock ds)
9898 block b (DoBind fc n nfc tm : rest)
9999 = PApp fc b [pexp tm, pexp (PLam fc n nfc Placeholder (block b rest))]
100100 block b (DoBindP fc p tm alts : rest)
101− = PApp fc b [pexp tm, pexp (PLam fc (sMN 0 "bpat") NoFC Placeholder
102− (PCase fc (PRef fc [] (sMN 0 "bpat"))
101+ = PApp fc b [pexp tm, pexp (PLam fc (sMN 0 "__bpat") NoFC Placeholder
102+ (PCase fc (PRef fc [] (sMN 0 "__bpat"))
103103 ((p, block b rest) : alts)))]
104104 block b (DoLet fc n nfc ty tm : rest)
105105 = PLet fc n nfc ty tm (block b rest)
@@ -108,7 +108,10 @@ expandSugar dsl (PDoBlock ds)
108108 block b (DoExp fc tm : rest)
109109 = PApp fc b
110110 [pexp tm,
111− pexp (PLam fc (sMN 0 "bindx") NoFC Placeholder (block b rest))]
111+ pexp (PLam fc (sMN 0 "__bindx") NoFC (mkTy tm) (block b rest))]
112+ where mkTy (PCase _ _ _) = PRef fc [] unitTy
113+ mkTy (PMetavar _ _) = PRef fc [] unitTy
114+ mkTy _ = Placeholder
112115 block b _ = PElabError (Msg "Invalid statement in do block")
113116
114117expandSugar dsl (PIdiom fc e) = expandSugar dsl $ unIdiom (dsl_apply dsl) (dsl_pure dsl) fc e
src/Idris/DataOpts.hs−1
@@ -40,7 +40,6 @@ instance Optimisable Raw where
4040 | otherwise = RApp <$> applyOpts f <*> applyOpts a
4141
4242 applyOpts (RBind n b t) = RBind n <$> applyOpts b <*> applyOpts t
43− applyOpts (RForce t) = applyOpts t
4443 applyOpts t = return t
4544
4645-- Erase types (makes ibc smaller, and we don't need them)
src/Idris/DeepSeq.hs+12−5
@@ -107,6 +107,7 @@ instance NFData Opt where
107107 rnf (ColourREPL bool) = rnf bool `seq` ()
108108 rnf (Idemode) = ()
109109 rnf (IdemodeSocket) = ()
110+ rnf (ShowLoggingCats) = ()
110111 rnf (ShowLibs) = ()
111112 rnf (ShowLibdir) = ()
112113 rnf (ShowIncs) = ()
@@ -116,6 +117,7 @@ instance NFData Opt where
116117 rnf (NoBuiltins) = ()
117118 rnf (NoREPL) = ()
118119 rnf (OLogging i) = rnf i `seq` ()
120+ rnf (OLogCats cs) = rnf cs `seq` ()
119121 rnf (Output str) = rnf str `seq` ()
120122 rnf (Interface) = ()
121123 rnf (TypeCase) = ()
@@ -174,6 +176,7 @@ instance NFData TIData where
174176instance NFData IOption where
175177 rnf (IOption
176178 opt_logLevel
179+ opt_logcats
177180 opt_typecase
178181 opt_typeintype
179182 opt_coverage
@@ -226,7 +229,7 @@ instance NFData IOption where
226229instance NFData LanguageExt where
227230 rnf TypeProviders = ()
228231 rnf ErrorReflection = ()
229−
232+
230233instance NFData Optimisation where
231234 rnf PETransform = ()
232235
@@ -300,6 +303,7 @@ instance NFData IBCWrite where
300303 rnf (IBCUsage usage) = rnf usage `seq` ()
301304 rnf (IBCExport name) = rnf name `seq` ()
302305 rnf (IBCAutoHint n1 n2) = rnf n1 `seq` rnf n2 `seq` ()
306+ rnf (IBCDeprecate n1 n2) = rnf n1 `seq` rnf n2 `seq` ()
303307 rnf (IBCRecord x) = rnf x `seq` ()
304308
305309
@@ -357,6 +361,9 @@ instance NFData Codegen where
357361 rnf (Via x1) = rnf x1 `seq` ()
358362 rnf Bytecode = ()
359363
364+instance NFData LogCat where
365+ rnf _ = ()
366+
360367instance NFData CGInfo where
361368 rnf (CGInfo x1 x2 x3 x4 x5)
362369 = rnf x1 `seq`
@@ -562,7 +569,7 @@ instance NFData PTerm where
562569instance NFData PAltType where
563570 rnf (ExactlyOne x1) = rnf x1 `seq` ()
564571 rnf FirstSuccess = ()
565− rnf TryImplicit = ()
572+ rnf TryImplicit = ()
566573
567574instance (NFData t) => NFData (PTactic' t) where
568575 rnf (Intro x1) = rnf x1 `seq` ()
@@ -686,11 +693,11 @@ instance NFData OutputMode where
686693
687694
688695instance NFData IState where
689− rnf (IState x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 x19 x20
696+ rnf (IState x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 x19 x20
690697 x21 x22 x23 x24 x25 x26 x27 x28 x29 x30 x31 x32 x33 x34 x35 x36 x37 x38 x39 x40
691698 x41 x42 x43 x44 x45 x46 x47 x48 x49 x50 x51 x52 x53 x54 x55 x56 x57 x58 x59 x60
692− x61 x62 x63 x64 x65 x66 x67 x68 x69 x70 x71 x72 x73)
699+ x61 x62 x63 x64 x65 x66 x67 x68 x69 x70 x71 x72 x73 x74)
693700 = rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` rnf x4 `seq` rnf x5 `seq` rnf x6 `seq` rnf x7 `seq` rnf x8 `seq` rnf x9 `seq` rnf x10 `seq` () `seq` rnf x11 `seq` rnf x12 `seq` rnf x13 `seq` rnf x14 `seq` rnf x15 `seq` rnf x16 `seq` rnf x17 `seq` rnf x18 `seq` rnf x19 `seq` rnf x20 `seq`
694701 rnf x21 `seq` rnf x22 `seq` rnf x23 `seq` rnf x24 `seq` rnf x25 `seq` rnf x26 `seq` rnf x27 `seq` rnf x28 `seq` rnf x29 `seq` rnf x30 `seq` rnf x31 `seq` rnf x32 `seq` rnf x33 `seq` rnf x34 `seq` rnf x35 `seq` rnf x36 `seq` rnf x37 `seq` rnf x38 `seq` rnf x39 `seq` rnf x40 `seq`
695702 rnf x41 `seq` rnf x42 `seq` rnf x43 `seq` rnf x44 `seq` rnf x45 `seq` rnf x46 `seq` rnf x47 `seq` rnf x48 `seq` rnf x49 `seq` rnf x50 `seq` rnf x51 `seq` rnf x52 `seq` rnf x53 `seq` rnf x54 `seq` rnf x55 `seq` rnf x56 `seq` rnf x57 `seq` rnf x58 `seq` rnf x59 `seq` rnf x60 `seq`
696− rnf x61 `seq` rnf x62 `seq` rnf x63 `seq` rnf x64 `seq` rnf x65 `seq` rnf x66 `seq` rnf x67 `seq` rnf x68 `seq` rnf x69 `seq` rnf x70 `seq` rnf x71 `seq` rnf x72 `seq` rnf x73 `seq` ()
703+ rnf x61 `seq` rnf x62 `seq` rnf x63 `seq` rnf x64 `seq` rnf x65 `seq` rnf x66 `seq` rnf x67 `seq` rnf x68 `seq` rnf x69 `seq` rnf x70 `seq` rnf x71 `seq` rnf x72 `seq` rnf x73 `seq` rnf x74 `seq` ()
src/Idris/Delaborate.hs+20−6
@@ -110,6 +110,9 @@ delabTy' ist imps tm fullname mvs = de [] imps tm
110110 _ -> PRef un [] n
111111 de env _ (Bind n (Lam ty) sc)
112112 = PLam un n NoFC (de env [] ty) (de ((n,n):env) [] sc)
113+ de env (_ : is) (Bind n (Pi (Just impl) ty _) sc)
114+ | toplevel_imp impl -- information in 'imps' repeated
115+ = PPi (Imp [] Dynamic False (Just impl)) n NoFC (de env [] ty) (de ((n,n):env) is sc)
113116 de env is (Bind n (Pi (Just impl) ty _) sc)
114117 | tcinstance impl
115118 = PPi constraint n NoFC (de env [] ty) (de ((n,n):env) is sc)
@@ -192,7 +195,7 @@ delabTy' ist imps tm fullname mvs = de [] imps tm
192195 isCaseApp tm | P _ n _ <- fst (unApply tm) = isCN n
193196 | otherwise = False
194197 where isCN (NS n _) = isCN n
195− isCN (SN (CaseN _)) = True
198+ isCN (SN (CaseN _ _)) = True
196199 isCN _ = False
197200
198201 delabCase :: [(Name, Name)] -> [PArg] -> Name -> Term -> Name -> [Term] -> Maybe PTerm
@@ -201,8 +204,8 @@ delabTy' ist imps tm fullname mvs = de [] imps tm
201204 [(cases, _)] -> return cases
202205 _ -> Nothing
203206 return $ PCase un (de env imps scrutinee)
204− [ (de (env ++ map (\n -> (n, n)) vars) imps (splitArg lhs),
205− de (env ++ map (\n -> (n, n)) vars) imps rhs)
207+ [ (de (env ++ map (\(n, _) -> (n, n)) vars) imps (splitArg lhs),
208+ de (env ++ map (\(n, _) -> (n, n)) vars) imps rhs)
206209 | (vars, lhs, rhs) <- cases
207210 ]
208211 where splitArg tm | (_, args) <- unApply tm = nonVar (reverse args)
@@ -437,9 +440,14 @@ pprintErr' i (AlreadyDefined n) = annName n<+>
437440pprintErr' i (ProofSearchFail e) = pprintErr' i e
438441pprintErr' i (NoRewriting tm) = text "rewrite did not change type" <+> annTm tm (pprintTerm i (delabSugared i tm))
439442pprintErr' i (At f e) = annotate (AnnFC f) (text (show f)) <> colon <> pprintErr' i e
440−pprintErr' i (Elaborating s n e) = text "When checking" <+> text s <>
441− annName' n (showqual i n) <> colon <$>
442− pprintErr' i e
443+pprintErr' i (Elaborating s n ty e) = text "When checking" <+> text s <>
444+ annName' n (showqual i n) <>
445+ pprintTy ty <$>
446+ pprintErr' i e
447+ where pprintTy Nothing = colon
448+ pprintTy (Just ty) = text " with expected type" <>
449+ indented (annTm ty (pprintTerm i (delabSugared i ty)))
450+ <> line
443451pprintErr' i (ElaboratingArg f x _ e)
444452 | isInternal f = pprintErr' i e
445453 | isUN x =
@@ -503,6 +511,12 @@ pprintErr' i (ElabScriptStuck tm) =
503511 text "Is it a stuck term?"
504512pprintErr' i (RunningElabScript e) =
505513 text "While running an elaboration script, the following error occurred" <> colon <$> pprintErr' i e
514+pprintErr' i (ElabScriptStaging n) =
515+ text "Can't run elaboration script because it contains pattern matching that has not yet been elaborated." <$>
516+ text "Try lifting the script to a top-level definition." <$>
517+ text "In particular, the problem is caused by:" <+> annName n
518+pprintErr' i (FancyMsg parts) =
519+ fillSep (map (showPart i) parts)
506520
507521showPart :: IState -> ErrorReportPart -> Doc OutputAnnotation
508522showPart ist (TextPart str) = fillSep . map text . words $ str
src/Idris/Directives.hs+4−1
@@ -64,7 +64,10 @@ directiveAction (DErrorHandlers fn nfc arg afc ns) =
6464 map (\(n, fc) -> (fc, AnnName n Nothing Nothing Nothing)) ns'
6565
6666directiveAction (DLanguage ext) = addLangExt ext
67−
67+directiveAction (DDeprecate n reason)
68+ = do n' <- disambiguate n
69+ addDeprecated n' reason
70+ addIBC (IBCDeprecate n' reason)
6871directiveAction (DUsed fc fn arg) = addUsedName fc fn arg
6972
7073disambiguate :: Name -> Idris Name
src/Idris/Elab/Class.hs+11−13
@@ -78,7 +78,7 @@ elabClass info syn_in doc fc constraints tn tnfc ps pDocs fds ds mcn cd
7878 let idecls = filter instdecl ds -- default superclass instance declarations
7979 mapM_ checkDefaultSuperclassInstance idecls
8080 let mnames = map getMName mdecls
81− logLvl 1 $ "Building methods " ++ show mnames
81+ logElab 1 $ "Building methods " ++ show mnames
8282 ims <- mapM (tdecl mnames) mdecls
8383 defs <- mapM (defdecl (map (\ (x,y,z) -> z) ims) constraint)
8484 (filter clause ds)
@@ -94,7 +94,7 @@ elabClass info syn_in doc fc constraints tn tnfc ps pDocs fds ds mcn cd
9494 let cons = [(cd, pDocs ++ mapMaybe memberDocs ds, cn, NoFC, cty, fc, [])]
9595 let ddecl = PDatadecl tn NoFC tty cons
9696
97− logLvl 5 $ "Class data " ++ show (showDImp verbosePPOption ddecl)
97+ logElab 5 $ "Class data " ++ show (showDImp verbosePPOption ddecl)
9898
9999 -- Elaborate the data declaration
100100 elabData info (syn { no_imp = no_imp syn ++ mnames,
@@ -109,7 +109,7 @@ elabClass info syn_in doc fc constraints tn tnfc ps pDocs fds ds mcn cd
109109 -- for each method, build a top level function
110110 fns <- mapM (tfun cn constraint (syn { imp_methods = mnames })
111111 (map fst imethods)) imethods
112− logLvl 5 $ "Functions " ++ show fns
112+ logElab 5 $ "Functions " ++ show fns
113113 -- Elaborate the the top level methods
114114 mapM_ (rec_elabDecl info EAll info) (concat fns)
115115
@@ -159,7 +159,7 @@ elabClass info syn_in doc fc constraints tn tnfc ps pDocs fds ds mcn cd
159159 getMName (PTy _ _ _ _ _ n nfc _) = nsroot n
160160 tdecl allmeths (PTy doc _ syn _ o n nfc t)
161161 = do t' <- implicit' info syn (map (\(n, _, _) -> n) ps ++ allmeths) n t
162− logLvl 2 $ "Method " ++ show n ++ " : " ++ showTmImpls t'
162+ logElab 2 $ "Method " ++ show n ++ " : " ++ showTmImpls t'
163163 return ( (n, (toExp (map (\(pn, _, _) -> pn) ps) Exp t')),
164164 (n, (nfc, doc, o, (toExp (map (\(pn, _, _) -> pn) ps)
165165 (\ l s p -> Imp l s p Nothing) t'))),
@@ -174,7 +174,7 @@ elabClass info syn_in doc fc constraints tn tnfc ps pDocs fds ds mcn cd
174174 let ds = map (decorateid defaultdec)
175175 [PTy emptyDocstring [] syn fc [] n nfc ty',
176176 PClauses fc (o ++ opts) n cs]
177− logLvl 1 (show ds)
177+ logElab 1 (show ds)
178178 return (n, ((defaultdec n, ds!!1), ds))
179179 _ -> ifail $ show n ++ " is not a method"
180180 defdecl _ _ _ = ifail "Can't happen (defdecl)"
@@ -199,8 +199,8 @@ elabClass info syn_in doc fc constraints tn tnfc ps pDocs fds ds mcn cd
199199 let lhs = PApp fc (PRef fc [] cfn) [pconst capp]
200200 let rhs = PResolveTC (fileFC "HACK")
201201 let ty = PPi constraint cnm NoFC c con
202− logLvl 2 ("Dictionary constraint: " ++ showTmImpls ty)
203− logLvl 2 (showTmImpls lhs ++ " = " ++ showTmImpls rhs)
202+ logElab 2 ("Dictionary constraint: " ++ showTmImpls ty)
203+ logElab 2 (showTmImpls lhs ++ " = " ++ showTmImpls rhs)
204204 i <- getIState
205205 let conn = case con of
206206 PRef _ _ n -> n
@@ -230,9 +230,9 @@ elabClass info syn_in doc fc constraints tn tnfc ps pDocs fds ds mcn cd
230230 let anames = map (\x -> sMN x "arg") [0..]
231231 let lhs = PApp fc (PRef fc [] m) (pconst capp : lhsArgs margs anames)
232232 let rhs = PApp fc (getMeth mnames all m) (rhsArgs margs anames)
233− logLvl 2 ("Top level type: " ++ showTmImpls ty')
234− logLvl 1 (show (m, ty', capp, margs))
235− logLvl 2 ("Definition: " ++ showTmImpls lhs ++ " = " ++ showTmImpls rhs)
233+ logElab 2 ("Top level type: " ++ showTmImpls ty')
234+ logElab 1 (show (m, ty', capp, margs))
235+ logElab 2 ("Definition: " ++ showTmImpls lhs ++ " = " ++ showTmImpls rhs)
236236 return [PTy doc [] syn fc o m mfc ty',
237237 PClauses fc [Inlinable] m [PClause fc m lhs [] rhs []]]
238238
@@ -258,7 +258,7 @@ elabClass info syn_in doc fc constraints tn tnfc ps pDocs fds ds mcn cd
258258 insertConstraint :: PTerm -> [Name] -> PTerm -> PTerm
259259 insertConstraint c all (PPi p@(Imp _ _ _ _) n fc ty sc)
260260 = PPi p n fc ty (insertConstraint c all sc)
261− insertConstraint c all sc = let dictN = sMN 0 "class"
261+ insertConstraint c all sc = let dictN = sMN 0 "__class"
262262 in PPi (constraint { pstatic = Static })
263263 dictN NoFC c
264264 (constrainMeths (map basename all)
@@ -318,5 +318,3 @@ findDets n ns =
318318 | n `elem` ns = i : getDetPos (i + 1) ns sc
319319 | otherwise = getDetPos (i + 1) ns sc
320320 getDetPos _ _ _ = []
321−
322−
src/Idris/Elab/Clause.hs+153−156
@@ -84,7 +84,7 @@ elabClauses info' fc opts n_in cs =
8484 -- no simplification or PE
8585 let (pats_in, cs_full) = unzip cs_elab
8686 let pats_raw = map (simple_lhs (tt_ctxt ist)) pats_in
87− logLvl 3 $ "Elaborated patterns:\n" ++ show pats_raw
87+ logElab 3 $ "Elaborated patterns:\n" ++ show pats_raw
8888
8989 solveDeferred n
9090
@@ -102,7 +102,7 @@ elabClauses info' fc opts n_in cs =
102102 -- If the definition is specialisable, this reduces the
103103 -- RHS
104104 pe_tm <- doPartialEval ist tpats
105− let pats_pe = if petrans
105+ let pats_pe = if petrans
106106 then map (simple_lhs (tt_ctxt ist)) pe_tm
107107 else pats_raw
108108
@@ -111,7 +111,7 @@ elabClauses info' fc opts n_in cs =
111111 -- Look for 'static' names and generate new specialised
112112 -- definitions for them, as well as generating rewrite rules
113113 -- for partially evaluated definitions
114− newrules <- if petrans
114+ newrules <- if petrans
115115 then mapM (\ e -> case e of
116116 Left _ -> return []
117117 Right (l, r) -> elabPE info fc n r) pats_pe
@@ -133,13 +133,13 @@ elabClauses info' fc opts n_in cs =
133133
134134 -- pdef is the compile-time pattern definition.
135135 -- This will get further inlined to help with totality checking.
136− let pdef = map debind pats_raw
137− -- pdef_pe is the one which will get further optimised
136+ let pdef = map (\(ns, lhs, rhs) -> (map fst ns, lhs, rhs)) $ map debind pats_raw
137+ -- pdef_pe is the one which will get further optimised
138138 -- for run-time, and, partially evaluated
139139 let pdef_pe = map debind pats_transformed
140140
141− logLvl 5 $ "Initial typechecked patterns:\n" ++ show pats_raw
142− logLvl 5 $ "Initial typechecked pattern def:\n" ++ show pdef
141+ logElab 5 $ "Initial typechecked patterns:\n" ++ show pats_raw
142+ logElab 5 $ "Initial typechecked pattern def:\n" ++ show pdef
143143
144144 -- NOTE: Need to store original definition so that proofs which
145145 -- rely on its structure aren't affected by any changes to the
@@ -152,10 +152,10 @@ elabClauses info' fc opts n_in cs =
152152 numArgs <- tclift $ sameLength pdef
153153
154154 case specNames opts of
155− Just _ ->
156− do logLvl 3 $ "Partially evaluated:\n" ++ show pats_pe
155+ Just _ ->
156+ do logElab 3 $ "Partially evaluated:\n" ++ show pats_pe
157157 _ -> return ()
158− logLvl 3 $ "Transformed:\n" ++ show pats_transformed
158+ logElab 3 $ "Transformed:\n" ++ show pats_transformed
159159
160160 erInfo <- getErasureInfo <$> getIState
161161 tree@(CaseDef scargs sc _) <- tclift $
@@ -167,7 +167,7 @@ elabClauses info' fc opts n_in cs =
167167 -- missing <- genMissing n scargs sc
168168 missing' <- filterM (checkPossible info fc True n) missing
169169 let clhs = map getLHS pdef
170− logLvl 2 $ "Must be unreachable:\n" ++
170+ logElab 2 $ "Must be unreachable:\n" ++
171171 showSep "\n" (map showTmImpls missing') ++
172172 "\nAgainst: " ++
173173 showSep "\n" (map (\t -> showTmImpls (delab ist t)) (map getLHS pdef))
@@ -182,15 +182,15 @@ elabClauses info' fc opts n_in cs =
182182
183183 -- pdef' is the version that gets compiled for run-time,
184184 -- so we start from the partially evaluated version
185− pdef_in' <- applyOpts pdef_pe
185+ pdef_in' <- applyOpts $ map (\(ns, lhs, rhs) -> (map fst ns, lhs, rhs)) pdef_pe
186186 let pdef' = map (simple_rt (tt_ctxt ist)) pdef_in'
187187
188− logLvl 5 $ "After data structure transformations:\n" ++ show pdef'
188+ logElab 5 $ "After data structure transformations:\n" ++ show pdef'
189189
190190 ist <- getIState
191191 -- let wf = wellFounded ist n sc
192192 let tot | pcover || AssertTotal `elem` opts = Unchecked -- finish later
193− | PEGenerated `elem` opts = Generated
193+ | PEGenerated `elem` opts = Generated
194194 | otherwise = Partial NotCovering -- already know it's not total
195195
196196 -- case lookupCtxt (namespace info) n (idris_flags ist) of
@@ -206,63 +206,64 @@ elabClauses info' fc opts n_in cs =
206206 ":warning - Unreachable case: " ++
207207 show (delab ist x)) xs
208208 let knowncovering = (pcover && cov) || AssertTotal `elem` opts
209− let defaultcase = if knowncovering
209+ let defaultcase = if knowncovering
210210 then STerm Erased
211− else UnmatchedCase $ "*** " ++
212− show fc ++
213− ":unmatched case in " ++ show n ++
211+ else UnmatchedCase $ "*** " ++
212+ show fc ++
213+ ":unmatched case in " ++ show n ++
214214 " ***"
215215
216216 tree' <- tclift $ simpleCase tcase defaultcase reflect
217217 RunTime fc inacc atys pdef' erInfo
218− logLvl 3 $ "Unoptimised " ++ show n ++ ": " ++ show tree
219− logLvl 3 $ "Optimised: " ++ show tree'
218+ logElab 3 $ "Unoptimised " ++ show n ++ ": " ++ show tree
219+ logElab 3 $ "Optimised: " ++ show tree'
220220 ctxt <- getContext
221221 ist <- getIState
222222 let opt = idris_optimisation ist
223223 putIState (ist { idris_patdefs = addDef n (force pdef_pe, force pmissing)
224224 (idris_patdefs ist) })
225225 let caseInfo = CaseInfo (inlinable opts) (inlinable opts) (dictionary opts)
226− case lookupTy n ctxt of
227− [ty] -> do ctxt' <- do ctxt <- getContext
228− tclift $
229− addCasedef n erInfo caseInfo
230− tcase defaultcase
231− reflect
232− (AssertTotal `elem` opts)
233− atys
234− inacc
235− pats_pe
236− pdef
237− pdef -- compile time
238− pdef_inl -- inlined
239− pdef' ty
240− ctxt
241− setContext ctxt'
242− addIBC (IBCDef n)
243− setTotality n tot
244− when (not reflect && PEGenerated `notElem` opts) $
245− do totcheck (fc, n)
246− defer_totcheck (fc, n)
247− when (tot /= Unchecked) $ addIBC (IBCTotal n tot)
248− i <- getIState
249− case lookupDef n (tt_ctxt i) of
250− (CaseOp _ _ _ _ _ cd : _) ->
251− let (scargs, sc) = cases_compiletime cd
252− (scargs', sc') = cases_runtime cd in
253− do let calls = findCalls sc' scargs'
254− let used = findUsedArgs sc' scargs'
255− -- let scg = buildSCG i sc scargs
256− -- add SCG later, when checking totality
257− let cg = CGInfo scargs' calls [] used [] -- TODO: remove this, not needed anymore
258− logLvl 2 $ "Called names: " ++ show cg
259− addToCG n cg
260− addToCalledG n (nub (map fst calls)) -- plus names in type!
261− addIBC (IBCCG n)
262− _ -> return ()
263− return ()
226+ case lookupTyExact n ctxt of
227+ Just ty ->
228+ do ctxt' <- do ctxt <- getContext
229+ tclift $
230+ addCasedef n erInfo caseInfo
231+ tcase defaultcase
232+ reflect
233+ (AssertTotal `elem` opts)
234+ atys
235+ inacc
236+ pats_pe
237+ pdef
238+ pdef -- compile time
239+ pdef_inl -- inlined
240+ pdef' ty
241+ ctxt
242+ setContext ctxt'
243+ addIBC (IBCDef n)
244+ setTotality n tot
245+ when (not reflect && PEGenerated `notElem` opts) $
246+ do totcheck (fc, n)
247+ defer_totcheck (fc, n)
248+ when (tot /= Unchecked) $ addIBC (IBCTotal n tot)
249+ i <- getIState
250+ case lookupDef n (tt_ctxt i) of
251+ (CaseOp _ _ _ _ _ cd : _) ->
252+ let (scargs, sc) = cases_compiletime cd
253+ (scargs', sc') = cases_runtime cd in
254+ do let calls = findCalls sc' scargs'
255+ let used = findUsedArgs sc' scargs'
256+ -- let scg = buildSCG i sc scargs
257+ -- add SCG later, when checking totality
258+ let cg = CGInfo scargs' calls [] used [] -- TODO: remove this, not needed anymore
259+ logElab 2 $ "Called names: " ++ show cg
260+ addToCG n cg
261+ addToCalledG n (nub (map fst calls)) -- plus names in type!
262+ addIBC (IBCCG n)
263+ _ -> return ()
264+ return ()
264265 -- addIBC (IBCTotal n tot)
265− [] -> return ()
266+ _ -> return ()
266267 -- Check it's covering, if 'covering' option is used. Chase
267268 -- all called functions, and fail if any of them are also
268269 -- 'Partial NotCovering'
@@ -288,7 +289,7 @@ elabClauses info' fc opts n_in cs =
288289 debind (Left x) = let (vs, x') = depat [] x in
289290 (vs, x', Impossible)
290291
291− depat acc (Bind n (PVar t) sc) = depat (n : acc) (instantiate (P Bound n t) sc)
292+ depat acc (Bind n (PVar t) sc) = depat ((n, t) : acc) (instantiate (P Bound n t) sc)
292293 depat acc x = (acc, x)
293294
294295
@@ -359,7 +360,7 @@ elabPE info fc caller r =
359360 let undef = case lookupDefExact newnm (tt_ctxt ist) of
360361 Nothing -> True
361362 _ -> False
362− logLvl 5 $ show (newnm, undef, map (concreteArg ist) (snd specapp))
363+ logElab 5 $ show (newnm, undef, map (concreteArg ist) (snd specapp))
363364 idrisCatch
364365 (if (undef && all (concreteArg ist) (snd specapp)) then do
365366 cgns <- getAllNames n
@@ -373,32 +374,32 @@ elabPE info fc caller r =
373374 [Total _] -> 65536
374375 [Productive] -> 16
375376 _ -> 1
376− let opts = [Specialise ((if pe_simple specdecl
377− then map (\x -> (x, Nothing)) cgns'
377+ let opts = [Specialise ((if pe_simple specdecl
378+ then map (\x -> (x, Nothing)) cgns'
378379 else []) ++
379− (n, Just maxred) :
380+ (n, Just maxred) :
380381 mapMaybe (specName (pe_simple specdecl))
381382 (snd specapp))]
382− logLvl 3 $ "Specialising application: " ++ show specapp
383+ logElab 3 $ "Specialising application: " ++ show specapp
383384 ++ " in " ++ show caller ++
384385 " with " ++ show opts
385− logLvl 3 $ "New name: " ++ show newnm
386− logLvl 3 $ "PE definition type : " ++ (show specTy)
386+ logElab 3 $ "New name: " ++ show newnm
387+ logElab 3 $ "PE definition type : " ++ (show specTy)
387388 ++ "\n" ++ show opts
388− logLvl 3 $ "PE definition " ++ show newnm ++ ":\n" ++
389+ logElab 3 $ "PE definition " ++ show newnm ++ ":\n" ++
389390 showSep "\n"
390391 (map (\ (lhs, rhs) ->
391392 (showTmImpls lhs ++ " = " ++
392393 showTmImpls rhs)) (pe_clauses specdecl))
393394
394− logLvl 2 $ show n ++ " transformation rule: " ++
395+ logElab 2 $ show n ++ " transformation rule: " ++
395396 showTmImpls rhs ++ " ==> " ++ showTmImpls lhs
396397
397398 elabType info defaultSyntax emptyDocstring [] fc opts newnm NoFC specTy
398399 let def = map (\(lhs, rhs) ->
399400 let lhs' = mapPT hiddenToPH $ stripUnmatchable ist lhs in
400− PClause fc newnm lhs' [] rhs [])
401− (pe_clauses specdecl)
401+ PClause fc newnm lhs' [] rhs [])
402+ (pe_clauses specdecl)
402403 trans <- elabTransform info fc False rhs lhs
403404 elabClauses info fc (PEGenerated:opts) newnm def
404405 return [trans]
@@ -406,7 +407,7 @@ elabPE info fc caller r =
406407 -- if it doesn't work, just don't specialise. Could happen for lots
407408 -- of valid reasons (e.g. local variables in scope which can't be
408409 -- lifted out).
409− (\e -> do logLvl 3 $ "Couldn't specialise: " ++ (pshow ist e)
410+ (\e -> do logElab 3 $ "Couldn't specialise: " ++ (pshow ist e)
410411 return [])
411412
412413 hiddenToPH (PHidden _) = Placeholder
@@ -449,7 +450,7 @@ elabPE info fc caller r =
449450 -- get the clause of a specialised application
450451 getSpecClause ist (n, args)
451452 = let newnm = sUN ("PE_" ++ show (nsroot n) ++ "_" ++
452− qhash 5381 (showSep "_" (map showArg args))) in
453+ qhash 5381 (showSep "_" (map showArg args))) in
453454 -- UN (show n ++ show (map snd args)) in
454455 (n, newnm, mkPE_TermDecl ist newnm n args)
455456 where showArg (ExplicitS, n) = qshow n
@@ -476,7 +477,9 @@ checkPossible info fc tcgen fname lhs_in
476477 let lhs = addImplPat i lhs_in
477478 -- if the LHS type checks, it is possible
478479 case elaborate ctxt (idris_datatypes i) (sMN 0 "patLHS") infP initEState
479− (erun fc (buildTC i info ELHS [] fname (infTerm lhs))) of
480+ (erun fc (buildTC i info ELHS [] fname
481+ (allNamesIn lhs_in)
482+ (infTerm lhs))) of
480483 OK (ElabResult lhs' _ _ ctxt' newDecls highlights, _) ->
481484 do setContext ctxt'
482485 processTacticDecls info newDecls
@@ -491,19 +494,19 @@ checkPossible info fc tcgen fname lhs_in
491494 recoverableCoverage ctxt err)
492495
493496
494−propagateParams :: IState -> [Name] -> Type -> PTerm -> PTerm
495−propagateParams i ps t tm@(PApp _ (PRef fc hls n) args)
497+propagateParams :: IState -> [Name] -> Type -> [Name] -> PTerm -> PTerm
498+propagateParams i ps t bound tm@(PApp _ (PRef fc hls n) args)
496499 = PApp fc (PRef fc hls n) (addP t args)
497500 where addP (Bind n _ sc) (t : ts)
498501 | Placeholder <- getTm t,
499502 n `elem` ps,
500− not (n `elem` allNamesIn tm)
501− = t { getTm = PRef NoFC [] n } : addP sc ts
503+ not (n `elem` bound)
504+ = t { getTm = PPatvar NoFC n } : addP sc ts
502505 addP (Bind n _ sc) (t : ts) = t : addP sc ts
503506 addP _ ts = ts
504−propagateParams i ps t tm@(PApp fc ap args)
505− = PApp fc (propagateParams i ps t ap) args
506−propagateParams i ps t (PRef fc hls n)
507+propagateParams i ps t bound (PApp fc ap args)
508+ = PApp fc (propagateParams i ps t bound ap) args
509+propagateParams i ps t bound (PRef fc hls n)
507510 = case lookupCtxt n (idris_implicits i) of
508511 [is] -> let ps' = filter (isImplicit is) ps in
509512 PApp fc (PRef fc hls n) (map (\x -> pimp x (PRef fc [] x) True) ps')
@@ -511,7 +514,7 @@ propagateParams i ps t (PRef fc hls n)
511514 where isImplicit [] n = False
512515 isImplicit (PImp _ _ _ x _ : is) n | x == n = True
513516 isImplicit (_ : is) n = isImplicit is n
514−propagateParams i ps t x = x
517+propagateParams i ps t bound x = x
515518
516519findUnique :: Context -> Env -> Term -> [Name]
517520findUnique ctxt env (Bind n b sc)
@@ -548,6 +551,12 @@ elabClause info opts (cnum, PClause fc fname lhs_in_as withs rhs_in_as wherebloc
548551 -- pattern bindings
549552 i <- getIState
550553 inf <- isTyInferred fname
554+
555+ -- Check if we have "with" patterns outside of "with" block
556+ when (isOutsideWith lhs_in && (not $ null withs)) $
557+ ierror $ (At fc (Elaborating "left hand side of " fname Nothing
558+ (Msg "unexpected patterns outside of \"with\" block")))
559+
551560 -- get the parameters first, to pass through to any where block
552561 let fn_ty = case lookupTy fname (tt_ctxt i) of
553562 [t] -> t
@@ -560,34 +569,36 @@ elabClause info opts (cnum, PClause fc fname lhs_in_as withs rhs_in_as wherebloc
560569 let tcparams = getTCParamsInType i [] fn_is norm_ty
561570
562571 let lhs = mkLHSapp $ stripLinear i $ stripUnmatchable i $
563− propagateParams i params norm_ty (addImplPat i lhs_in)
564−-- let lhs = mkLHSapp $
572+ propagateParams i params norm_ty (allNamesIn lhs_in) (addImplPat i lhs_in)
573+-- let lhs = mkLHSapp $
565574-- propagateParams i params fn_ty (addImplPat i lhs_in)
566− logLvl 10 (show (params, fn_ty) ++ " " ++ showTmImpls (addImplPat i lhs_in))
567− logLvl 5 ("LHS: " ++ show fc ++ " " ++ showTmImpls lhs)
568− logLvl 4 ("Fixed parameters: " ++ show params ++ " from " ++ show lhs_in ++
575+ logElab 10 (show (params, fn_ty) ++ " " ++ showTmImpls (addImplPat i lhs_in))
576+ logElab 5 ("LHS: " ++ show fc ++ " " ++ showTmImpls lhs)
577+ logElab 4 ("Fixed parameters: " ++ show params ++ " from " ++ show lhs_in ++
569578 "\n" ++ show (fn_ty, fn_is))
570579
571580 ((ElabResult lhs' dlhs [] ctxt' newDecls highlights, probs, inj), _) <-
572581 tclift $ elaborate ctxt (idris_datatypes i) (sMN 0 "patLHS") infP initEState
573− (do res <- errAt "left hand side of " fname
574− (erun fc (buildTC i info ELHS opts fname (infTerm lhs)))
582+ (do res <- errAt "left hand side of " fname Nothing
583+ (erun fc (buildTC i info ELHS opts fname
584+ (allNamesIn lhs_in)
585+ (infTerm lhs)))
575586 probs <- get_probs
576587 inj <- get_inj
577588 return (res, probs, inj))
578589 setContext ctxt'
579590 processTacticDecls info newDecls
580591 sendHighlighting highlights
581−
592+
582593 when inf $ addTyInfConstraints fc (map (\(x,y,_,_,_,_,_) -> (x,y)) probs)
583594
584595 let lhs_tm = orderPats (getInferTerm lhs')
585596 let lhs_ty = getInferType lhs'
586597 let static_names = getStaticNames i lhs_tm
587598
588− logLvl 3 ("Elaborated: " ++ show lhs_tm)
589− logLvl 3 ("Elaborated type: " ++ show lhs_ty)
590− logLvl 5 ("Injective: " ++ show fname ++ " " ++ show inj)
599+ logElab 3 ("Elaborated: " ++ show lhs_tm)
600+ logElab 3 ("Elaborated type: " ++ show lhs_ty)
601+ logElab 5 ("Injective: " ++ show fname ++ " " ++ show inj)
591602
592603 -- If we're inferring metavariables in the type, don't recheck,
593604 -- because we're only doing this to try to work out those metavariables
@@ -604,16 +615,16 @@ elabClause info opts (cnum, PClause fc fname lhs_in_as withs rhs_in_as wherebloc
604615 -- Issue #1615 on the Issue Tracker.
605616 -- https://github.com/idris-lang/Idris-dev/issues/1615
606617 when (not (null borrowed)) $
607− logLvl 5 ("Borrowed names on LHS: " ++ show borrowed)
618+ logElab 5 ("Borrowed names on LHS: " ++ show borrowed)
608619
609− logLvl 3 ("Normalised LHS: " ++ showTmImpls (delabMV i clhs))
620+ logElab 3 ("Normalised LHS: " ++ showTmImpls (delabMV i clhs))
610621
611622 rep <- useREPL
612623 when rep $ do
613624 addInternalApp (fc_fname fc) (fst . fc_start $ fc) (delabMV i clhs) -- TODO: Should use span instead of line and filename?
614625 addIBC (IBCLineApp (fc_fname fc) (fst . fc_start $ fc) (delabMV i clhs))
615626
616− logLvl 5 ("Checked " ++ show clhs ++ "\n" ++ show clhsty)
627+ logElab 5 ("Checked " ++ show clhs ++ "\n" ++ show clhsty)
617628 -- Elaborate where block
618629 ist <- getIState
619630 windex <- getName
@@ -636,16 +647,16 @@ elabClause info opts (cnum, PClause fc fname lhs_in_as withs rhs_in_as wherebloc
636647 -- Elaborate those with a type *before* RHS, those without *after*
637648 let (wbefore, wafter) = sepBlocks wb
638649
639− logLvl 2 $ "Where block:\n " ++ show wbefore ++ "\n" ++ show wafter
650+ logElab 2 $ "Where block:\n " ++ show wbefore ++ "\n" ++ show wafter
640651 mapM_ (rec_elabDecl info EAll winfo) wbefore
641652 -- Now build the RHS, using the type of the LHS as the goal.
642653 i <- getIState -- new implicits from where block
643− logLvl 5 (showTmImpls (expandParams decorate newargs defs (defs \\ decls) rhs_in))
654+ logElab 5 (showTmImpls (expandParams decorate newargs defs (defs \\ decls) rhs_in))
644655 let rhs = addImplBoundInf i (map fst newargs_all) (defs \\ decls)
645656 (expandParams decorate newargs defs (defs \\ decls) rhs_in)
646− logLvl 2 $ "RHS: " ++ show (map fst newargs_all) ++ " " ++ showTmImpls rhs
657+ logElab 2 $ "RHS: " ++ show (map fst newargs_all) ++ " " ++ showTmImpls rhs
647658 ctxt <- getContext -- new context with where block added
648− logLvl 5 "STARTING CHECK"
659+ logElab 5 "STARTING CHECK"
649660 ((rhs', defer, is, probs, ctxt', newDecls, highlights), _) <-
650661 tclift $ elaborate ctxt (idris_datatypes i) (sMN 0 "patRHS") clhsty initEState
651662 (do pbinds ist lhs_tm
@@ -654,15 +665,13 @@ elabClause info opts (cnum, PClause fc fname lhs_in_as withs rhs_in_as wherebloc
654665 mapM_ setinj (nub (tcparams ++ inj))
655666 setNextName
656667 (ElabResult _ _ is ctxt' newDecls highlights) <-
657− errAt "right hand side of " fname
668+ errAt "right hand side of " fname (Just clhsty)
658669 (erun fc (build i winfo ERHS opts fname rhs))
659− errAt "right hand side of " fname
670+ errAt "right hand side of " fname (Just clhsty)
660671 (erun fc $ psolve lhs_tm)
661− hs <- get_holes
662− mapM_ (elabCaseHole is) hs
663672 tt <- get_term
664673 aux <- getAux
665− let (tm, ds) = runState (collectDeferred (Just fname)
674+ let (tm, ds) = runState (collectDeferred (Just fname)
666675 (map fst $ case_decls aux) ctxt tt) []
667676 probs <- get_probs
668677 return (tm, ds, is, probs, ctxt', newDecls, highlights))
@@ -672,11 +681,11 @@ elabClause info opts (cnum, PClause fc fname lhs_in_as withs rhs_in_as wherebloc
672681
673682 when inf $ addTyInfConstraints fc (map (\(x,y,_,_,_,_,_) -> (x,y)) probs)
674683
675− logLvl 5 "DONE CHECK"
676− logLvl 4 $ "---> " ++ show rhs'
677− when (not (null defer)) $ logLvl 1 $ "DEFERRED " ++
684+ logElab 5 "DONE CHECK"
685+ logElab 4 $ "---> " ++ show rhs'
686+ when (not (null defer)) $ logElab 1 $ "DEFERRED " ++
678687 show (map (\ (n, (_,_,t,_)) -> (n, t)) defer)
679− def' <- checkDef fc (Elaborating "deferred type of ") defer
688+ def' <- checkDef fc (\n -> Elaborating "deferred type of " n Nothing) defer
680689 let def'' = map (\(n, (i, top, t, ns)) -> (n, (i, top, t, ns, False))) def'
681690 addDeferred def''
682691 mapM_ (\(n, _) -> addIBC (IBCDef n)) def''
@@ -691,20 +700,20 @@ elabClause info opts (cnum, PClause fc fname lhs_in_as withs rhs_in_as wherebloc
691700 mapM_ (elabCaseBlock winfo opts) is
692701
693702 ctxt <- getContext
694− logLvl 5 $ "Rechecking"
695− logLvl 6 $ " ==> " ++ show (forget rhs')
703+ logElab 5 $ "Rechecking"
704+ logElab 6 $ " ==> " ++ show (forget rhs')
696705
697706 (crhs, crhsty) <- if not inf
698707 then recheckC_borrowing True (PEGenerated `notElem` opts)
699708 borrowed fc id [] rhs'
700709 else return (rhs', clhsty)
701− logLvl 6 $ " ==> " ++ showEnvDbg [] crhsty ++ " against " ++ showEnvDbg [] clhsty
710+ logElab 6 $ " ==> " ++ showEnvDbg [] crhsty ++ " against " ++ showEnvDbg [] clhsty
702711 ctxt <- getContext
703712 let constv = next_tvar ctxt
704713 case LState.runStateT (convertsC ctxt [] crhsty clhsty) (constv, []) of
705714 OK (_, cs) -> when (PEGenerated `notElem` opts) $ do
706− addConstraints fc cs
707− logLvl 6 $ "CONSTRAINTS ADDED: " ++ show cs ++ "\n" ++ show (clhsty, crhsty)
715+ addConstraints fc cs
716+ logElab 6 $ "CONSTRAINTS ADDED: " ++ show cs ++ "\n" ++ show (clhsty, crhsty)
708717 return ()
709718 Error e -> ierror (At fc (CantUnify False (clhsty, Nothing) (crhsty, Nothing) e [] 0))
710719 i <- getIState
@@ -777,26 +786,10 @@ elabClause info opts (cnum, PClause fc fname lhs_in_as withs rhs_in_as wherebloc
777786 (b : bf, af)
778787 sepBlocks' ns [] = ([], [])
779788
780−
781− -- if a hole is just an argument/result of a case block, treat it as
782− -- the unit type. Hack to help elaborate case in do blocks.
783− elabCaseHole aux h = do
784− focus h
785− g <- goal
786− case g of
787− TType _ -> when (any (isArg h) aux) $ do apply (Var unitTy) []; solve
788− _ -> return ()
789−
790− -- Is the name a pattern argument in the declaration
791− isArg :: Name -> PDecl -> Bool
792− isArg n (PClauses _ _ _ cs) = any isArg' cs
793− where
794− isArg' (PClause _ _ (PApp _ _ args) _ _ _)
795− = any (\x -> case x of
796− PRef _ _ n' -> n == n'
797− _ -> False) (map getTm args)
798− isArg' _ = False
799− isArg _ _ = False
789+ -- term is not within "with" block
790+ isOutsideWith :: PTerm -> Bool
791+ isOutsideWith (PApp _ (PRef _ _ (SN (WithN _ _))) _) = False
792+ isOutsideWith _ = True
800793
801794elabClause info opts (_, PWith fc fname lhs_in withs wval_in pn_in withblock)
802795 = do let tcgen = Dictionary `elem` opts
@@ -812,12 +805,16 @@ elabClause info opts (_, PWith fc fname lhs_in withs wval_in pn_in withblock)
812805 [t] -> t
813806 _ -> []
814807 let params = getParamsInType i [] fn_is (normalise ctxt [] fn_ty)
815− let lhs = stripLinear i $ stripUnmatchable i $ propagateParams i params fn_ty (addImplPat i lhs_in)
816− logLvl 2 ("LHS: " ++ show lhs)
808+ let lhs = stripLinear i $ stripUnmatchable i $
809+ propagateParams i params fn_ty (allNamesIn lhs_in)
810+ (addImplPat i lhs_in)
811+ logElab 2 ("LHS: " ++ show lhs)
817812 (ElabResult lhs' dlhs [] ctxt' newDecls highlights, _) <-
818813 tclift $ elaborate ctxt (idris_datatypes i) (sMN 0 "patLHS") infP initEState
819− (errAt "left hand side of with in " fname
820− (erun fc (buildTC i info ELHS opts fname (infTerm lhs))) )
814+ (errAt "left hand side of with in " fname Nothing
815+ (erun fc (buildTC i info ELHS opts fname
816+ (allNamesIn lhs_in)
817+ (infTerm lhs))) )
821818 setContext ctxt'
822819 processTacticDecls info newDecls
823820 sendHighlighting highlights
@@ -826,12 +823,12 @@ elabClause info opts (_, PWith fc fname lhs_in withs wval_in pn_in withblock)
826823 let lhs_ty = getInferType lhs'
827824 let ret_ty = getRetTy (explicitNames (normalise ctxt [] lhs_ty))
828825 let static_names = getStaticNames i lhs_tm
829− logLvl 5 (show lhs_tm ++ "\n" ++ show static_names)
826+ logElab 5 (show lhs_tm ++ "\n" ++ show static_names)
830827 (clhs, clhsty) <- recheckC fc id [] lhs_tm
831− logLvl 5 ("Checked " ++ show clhs)
828+ logElab 5 ("Checked " ++ show clhs)
832829 let bargs = getPBtys (explicitNames (normalise ctxt [] lhs_tm))
833830 let wval = addImplBound i (map fst bargs) wval_in
834− logLvl 5 ("Checking " ++ showTmImpls wval)
831+ logElab 5 ("Checking " ++ showTmImpls wval)
835832 -- Elaborate wval in this context
836833 ((wval', defer, is, ctxt', newDecls, highlights), _) <-
837834 tclift $ elaborate ctxt (idris_datatypes i) (sMN 0 "withRHS")
@@ -841,7 +838,7 @@ elabClause info opts (_, PWith fc fname lhs_in withs wval_in pn_in withblock)
841838 mapM_ addPSname (allNamesIn lhs_in)
842839 setNextName
843840 -- TODO: may want where here - see winfo abpve
844− (ElabResult _ d is ctxt' newDecls highlights) <- errAt "with value in " fname
841+ (ElabResult _ d is ctxt' newDecls highlights) <- errAt "with value in " fname Nothing
845842 (erun fc (build i info ERHS opts fname (infTerm wval)))
846843 erun fc $ psolve lhs_tm
847844 tt <- get_term
@@ -854,11 +851,11 @@ elabClause info opts (_, PWith fc fname lhs_in withs wval_in pn_in withblock)
854851 let def'' = map (\(n, (i, top, t, ns)) -> (n, (i, top, t, ns, False))) def'
855852 addDeferred def''
856853 mapM_ (elabCaseBlock info opts) is
857− logLvl 5 ("Checked wval " ++ show wval')
854+ logElab 5 ("Checked wval " ++ show wval')
858855 (cwval, cwvalty) <- recheckC fc id [] (getInferTerm wval')
859856 let cwvaltyN = explicitNames (normalise ctxt [] cwvalty)
860857 let cwvalN = explicitNames (normalise ctxt [] cwval)
861− logLvl 3 ("With type " ++ show cwvalty ++ "\nRet type " ++ show ret_ty)
858+ logElab 3 ("With type " ++ show cwvalty ++ "\nRet type " ++ show ret_ty)
862859 -- We're going to assume the with type is not a function shortly,
863860 -- so report an error if it is (you can't match on a function anyway
864861 -- so this doesn't lose anything)
@@ -879,9 +876,9 @@ elabClause info opts (_, PWith fc fname lhs_in withs wval_in pn_in withblock)
879876 -- Highlight explicit proofs
880877 sendHighlighting $ [(fc, AnnBoundName n False) | (n, fc) <- maybeToList pn_in]
881878
882− logLvl 10 ("With type " ++ show (getRetTy cwvaltyN) ++
879+ logElab 10 ("With type " ++ show (getRetTy cwvaltyN) ++
883880 " depends on " ++ show pdeps ++ " from " ++ show pvars)
884− logLvl 10 ("Pre " ++ show bargs_pre ++ "\nPost " ++ show bargs_post)
881+ logElab 10 ("Pre " ++ show bargs_pre ++ "\nPost " ++ show bargs_post)
885882 windex <- getName
886883 -- build a type declaration for the new function:
887884 -- (ps : Xs) -> (withval : cwvalty) -> (ps' : Xs') -> ret_ty
@@ -889,7 +886,7 @@ elabClause info opts (_, PWith fc fname lhs_in withs wval_in pn_in withblock)
889886 let wargtype = getRetTy cwvaltyN
890887 let wargname = sMN windex "warg"
891888
892− logLvl 5 ("Abstract over " ++ show wargval ++ " in " ++ show wargtype)
889+ logElab 5 ("Abstract over " ++ show wargval ++ " in " ++ show wargtype)
893890 let wtype = bindTyArgs (flip (Pi Nothing) (TType (UVar 0))) (bargs_pre ++
894891 (wargname, wargtype) :
895892 map (abstract wargname wargval wargtype) bargs_post ++
@@ -899,13 +896,13 @@ elabClause info opts (_, PWith fc fname lhs_in withs wval_in pn_in withblock)
899896 P Bound wargname Erased, wargval])]
900897 Nothing -> [])
901898 (substTerm wargval (P Bound wargname wargtype) ret_ty)
902− logLvl 3 ("New function type " ++ show wtype)
899+ logElab 3 ("New function type " ++ show wtype)
903900 let wname = SN (WithN windex fname)
904901
905902 let imps = getImps wtype -- add to implicits context
906903 putIState (i { idris_implicits = addDef wname imps (idris_implicits i) })
907904 let statics = getStatics static_names wtype
908− logLvl 5 ("Static positions " ++ show statics)
905+ logElab 5 ("Static positions " ++ show statics)
909906 i <- getIState
910907 putIState (i { idris_statics = addDef wname statics (idris_statics i) })
911908
@@ -922,7 +919,7 @@ elabClause info opts (_, PWith fc fname lhs_in withs wval_in pn_in withblock)
922919 -- ==> fname' ps wpat [rest], match pats against toplevel for ps
923920 wb <- mapM (mkAuxC mpn wname lhs (map fst bargs_pre) (map fst bargs_post))
924921 withblock
925− logLvl 3 ("with block " ++ show wb)
922+ logElab 3 ("with block " ++ show wb)
926923 -- propagate totality assertion to the new definitions
927924 when (AssertTotal `elem` opts) $ setFlags wname [AssertTotal]
928925 mapM_ (rec_elabDecl info EAll info) wb
@@ -938,7 +935,7 @@ elabClause info opts (_, PWith fc fname lhs_in withs wval_in pn_in withblock)
938935 [ pimp (sUN "A") Placeholder False
939936 , pimp (sUN "x") Placeholder False
940937 ])])
941− logLvl 5 ("New RHS " ++ showTmImpls rhs)
938+ logElab 5 ("New RHS " ++ showTmImpls rhs)
942939 ctxt <- getContext -- New context with block added
943940 i <- getIState
944941 ((rhs', defer, is, ctxt', newDecls, highlights), _) <-
@@ -958,7 +955,7 @@ elabClause info opts (_, PWith fc fname lhs_in withs wval_in pn_in withblock)
958955 let def'' = map (\(n, (i, top, t, ns)) -> (n, (i, top, t, ns, False))) def'
959956 addDeferred def''
960957 mapM_ (elabCaseBlock info opts) is
961− logLvl 5 ("Checked RHS " ++ show rhs')
958+ logElab 5 ("Checked RHS " ++ show rhs')
962959 (crhs, crhsty) <- recheckC fc id [] rhs'
963960 return $ (Right (clhs, crhs), lhs)
964961 where
@@ -974,18 +971,18 @@ elabClause info opts (_, PWith fc fname lhs_in withs wval_in pn_in withblock)
974971 mkAux pn wname toplhs ns ns' (PClause fc n tm_in (w:ws) rhs wheres)
975972 = do i <- getIState
976973 let tm = addImplPat i tm_in
977− logLvl 2 ("Matching " ++ showTmImpls tm ++ " against " ++
974+ logElab 2 ("Matching " ++ showTmImpls tm ++ " against " ++
978975 showTmImpls toplhs)
979976 case matchClause i toplhs tm of
980977 Left (a,b) -> ifail $ show fc ++ ":with clause does not match top level"
981978 Right mvars ->
982− do logLvl 3 ("Match vars : " ++ show mvars)
979+ do logElab 3 ("Match vars : " ++ show mvars)
983980 lhs <- updateLHS n pn wname mvars ns ns' (fullApp tm) w
984981 return $ PClause fc wname lhs ws rhs wheres
985982 mkAux pn wname toplhs ns ns' (PWith fc n tm_in (w:ws) wval pn' withs)
986983 = do i <- getIState
987984 let tm = addImplPat i tm_in
988− logLvl 2 ("Matching " ++ showTmImpls tm ++ " against " ++
985+ logElab 2 ("Matching " ++ showTmImpls tm ++ " against " ++
989986 showTmImpls toplhs)
990987 withs' <- mapM (mkAuxC pn wname toplhs ns ns') withs
991988 case matchClause i toplhs tm of
@@ -1004,7 +1001,7 @@ elabClause info opts (_, PWith fc fname lhs_in withs wval_in pn_in withblock)
10041001 ns' = map (keepMvar (map fst mvars) fc') ns_in' in
10051002 return $ substMatches mvars $
10061003 PApp fc (PRef fc' [] wname)
1007− (map pexp ns ++ pexp w : (map pexp ns') ++
1004+ (map pexp ns ++ pexp w : (map pexp ns') ++
10081005 case pn of
10091006 Nothing -> []
10101007 Just pnm -> [pexp (PRef fc [] pnm)])
src/Idris/Elab/Data.hs+30−20
@@ -48,13 +48,19 @@ import qualified Data.Text as T
4848import Data.Char(isLetter, toLower)
4949import Data.List.Split (splitOn)
5050
51−import Util.Pretty(pretty, text)
51+import Util.Pretty
52+
53+warnLC :: FC -> Name -> Idris ()
54+warnLC fc n
55+ = iWarn fc $ annName n <+> text "has a name which may be implicitly bound."
56+ <> line <> text "This is likely to lead to problems!"
5257
5358elabData :: ElabInfo -> SyntaxInfo -> Docstring (Either Err PTerm)-> [(Name, Docstring (Either Err PTerm))] -> FC -> DataOpts -> PData -> Idris ()
5459elabData info syn doc argDocs fc opts (PLaterdecl n nfc t_in)
5560 = do let codata = Codata `elem` opts
56− logLvl 1 (show (fc, doc))
61+ logElab 1 (show (fc, doc))
5762 checkUndefined fc n
63+ when (implicitable n) $ warnLC fc n
5864 (cty, _, t, inacc) <- buildType info syn fc [] n t_in
5965
6066 addIBC (IBCDef n)
@@ -63,8 +69,9 @@ elabData info syn doc argDocs fc opts (PLaterdecl n nfc t_in)
6369
6470elabData info syn doc argDocs fc opts (PDatadecl n nfc t_in dcons)
6571 = do let codata = Codata `elem` opts
66− logLvl 1 (show fc)
72+ logElab 1 (show fc)
6773 undef <- isUndefined fc n
74+ when (implicitable n) $ warnLC fc n
6875 (cty, ckind, t, inacc) <- buildType info syn fc [] n t_in
6976 -- if n is defined already, make sure it is just a type declaration
7077 -- with the same type we've just elaborated, and no constructors
@@ -74,15 +81,17 @@ elabData info syn doc argDocs fc opts (PDatadecl n nfc t_in dcons)
7481 -- temporary, to check cons
7582 when undef $ updateContext (addTyDecl n (TCon 0 0) cty)
7683 let cnameinfo = cinfo info (map cname dcons)
77− let unique = case getRetTy cty of
78− UType UniqueType -> True
79− _ -> False
84+ unique <- case getRetTy (normalise (tt_ctxt i) [] cty) of
85+ UType UniqueType -> return True
86+ UType _ -> return False
87+ TType _ -> return False
88+ rt -> tclift $ tfail (At fc (Elaborating "type constructor " n Nothing (Msg "Not a valid type constructor")))
8089 cons <- mapM (elabCon cnameinfo syn n codata (getRetTy cty) ckind) dcons
8190 ttag <- getName
8291 i <- getIState
8392 let as = map (const (Left (Msg ""))) (getArgTys cty)
8493 let params = findParams (map snd cons)
85− logLvl 2 $ "Parameters : " ++ show params
94+ logElab 2 $ "Parameters : " ++ show params
8695 -- TI contains information about mutually declared types - this will
8796 -- be updated when the mutual block is complete
8897 putIState (i { idris_datatypes =
@@ -222,7 +231,8 @@ elabCon :: ElabInfo -> SyntaxInfo -> Name -> Bool ->
222231 Idris (Name, Type)
223232elabCon info syn tn codata expkind dkind (doc, argDocs, n, nfc, t_in, fc, forcenames)
224233 = do checkUndefined fc n
225− logLvl 2 $ show fc ++ ":Constructor " ++ show n ++ " : " ++ show t_in
234+ when (implicitable n) $ warnLC fc n
235+ logElab 2 $ show fc ++ ":Constructor " ++ show n ++ " : " ++ show t_in
226236 (cty, ckind, t, inacc) <- buildType info syn fc [Constructor] n (if codata then mkLazy t_in else t_in)
227237 ctxt <- getContext
228238 let cty' = normalise ctxt [] cty
@@ -232,13 +242,13 @@ elabCon info syn tn codata expkind dkind (doc, argDocs, n, nfc, t_in, fc, forcen
232242 -- Check that the constructor type is, in fact, a part of the family being defined
233243 tyIs n cty'
234244
235− logLvl 5 $ show fc ++ ":Constructor " ++ show n ++ " elaborated : " ++ show t
236− logLvl 5 $ "Inaccessible args: " ++ show inacc
237− logLvl 2 $ "---> " ++ show n ++ " : " ++ show cty'
245+ logElab 5 $ show fc ++ ":Constructor " ++ show n ++ " elaborated : " ++ show t
246+ logElab 5 $ "Inaccessible args: " ++ show inacc
247+ logElab 2 $ "---> " ++ show n ++ " : " ++ show cty'
238248
239249 -- Add to the context (this is temporary, so that later constructors
240250 -- can be indexed by it)
241− updateContext (addTyDecl n (DCon 0 0 False) cty)
251+ updateContext (addTyDecl n (DCon 0 0 False) cty)
242252
243253 addIBC (IBCDef n)
244254 checkDocs fc argDocs t
@@ -253,9 +263,9 @@ elabCon info syn tn codata expkind dkind (doc, argDocs, n, nfc, t_in, fc, forcen
253263 where
254264 tyIs con (Bind n b sc) = tyIs con sc
255265 tyIs con t | (P _ n' _, _) <- unApply t
256− = if n' /= tn then tclift $ tfail (At fc (Elaborating "constructor " con (Msg (show n' ++ " is not " ++ show tn))))
266+ = if n' /= tn then tclift $ tfail (At fc (Elaborating "constructor " con Nothing (Msg (show n' ++ " is not " ++ show tn))))
257267 else return ()
258− tyIs con t = tclift $ tfail (At fc (Elaborating "constructor " con (Msg (show t ++ " is not " ++ show tn))))
268+ tyIs con t = tclift $ tfail (At fc (Elaborating "constructor " con Nothing (Msg (show t ++ " is not " ++ show tn))))
259269
260270 mkLazy (PPi pl n nfc ty sc)
261271 = let ty' = if getTyName ty
@@ -288,12 +298,12 @@ elabCon info syn tn codata expkind dkind (doc, argDocs, n, nfc, t_in, fc, forcen
288298 = tclift $ tfail (At fc (UniqueKindError UniqueType n))
289299 checkUniqueKind (UType AllTypes) (UType AllTypes) = return ()
290300 checkUniqueKind (UType AllTypes) (UType UniqueType) = return ()
291− checkUniqueKind (UType AllTypes) _
301+ checkUniqueKind (UType AllTypes) _
292302 = tclift $ tfail (At fc (UniqueKindError AllTypes n))
293303 checkUniqueKind _ _ = return ()
294304
295305 -- Constructor's kind must be <= expected kind
296− addDataConstraint (TType con) (TType exp)
306+ addDataConstraint (TType con) (TType exp)
297307 = do ctxt <- getContext
298308 let v = next_tvar ctxt
299309 addConstraints fc (v, [ULT con exp])
@@ -337,20 +347,20 @@ elabCaseFun ind paramPos n ty cons info = do
337347 let eliminatorDef = PClauses emptyFC [TotalFn] elimDeclName eliminatorClauses
338348 elimLog $ "-- case function definition: " ++ (show . showDeclImp verbosePPOption) eliminatorDef
339349 State.lift $ idrisCatch (rec_elabDecl info EAll info eliminatorTyDecl)
340− (ierror . Elaborating "type declaration of " elimDeclName)
350+ (ierror . Elaborating "type declaration of " elimDeclName Nothing)
341351 -- Do not elaborate clauses if there aren't any
342352 case eliminatorClauses of
343353 [] -> State.lift $ solveDeferred elimDeclName -- Remove meta-variable for type
344354 _ -> State.lift $ idrisCatch (rec_elabDecl info EAll info eliminatorDef)
345− (ierror . Elaborating "clauses of " elimDeclName)
355+ (ierror . Elaborating "clauses of " elimDeclName Nothing)
346356 where elimLog :: String -> EliminatorState ()
347− elimLog s = State.lift (logLvl 2 s)
357+ elimLog s = State.lift (logElab 2 s)
348358
349359 elimFC :: FC
350360 elimFC = fileFC "(casefun)"
351361
352362 elimDeclName :: Name
353− elimDeclName = if ind then SN . ElimN $ n else SN . CaseN $ n
363+ elimDeclName = if ind then SN . ElimN $ n else SN . CaseN (FC' emptyFC) $ n
354364
355365 applyNS :: Name -> [String] -> Name
356366 applyNS n [] = n
src/Idris/Elab/Instance.hs+15−16
@@ -71,7 +71,7 @@ elabInstance info syn doc argDocs what fc cs n nfc ps t expn ds = do
7171 let constraint = PApp fc (PRef fc [] n) (map pexp ps)
7272 let iname = mkiname n (namespace info) ps expn
7373 let emptyclass = null (class_methods ci)
74− when (what /= EDefns) $ do
74+ when (what /= EDefns) $ do
7575 nty <- elabType' True info syn doc argDocs fc [] iname NoFC t
7676 -- if the instance type matches any of the instances we have already,
7777 -- and it's not a named instance, then it's overlapping, so report an error
@@ -106,19 +106,19 @@ elabInstance info syn doc argDocs what fc cs n nfc ps t expn ds = do
106106 (decorate ns iname n,
107107 op, coninsert cs t', t'))
108108 (class_methods ci)
109− logLvl 3 (show (mtys, ips))
110− logLvl 5 ("Before defaults: " ++ show ds ++ "\n" ++ show (map fst (class_methods ci)))
109+ logElab 3 (show (mtys, ips))
110+ logElab 5 ("Before defaults: " ++ show ds ++ "\n" ++ show (map fst (class_methods ci)))
111111 let ds_defs = insertDefaults i iname (class_defaults ci) ns ds
112− logLvl 3 ("After defaults: " ++ show ds_defs ++ "\n")
112+ logElab 3 ("After defaults: " ++ show ds_defs ++ "\n")
113113 let ds' = reorderDefs (map fst (class_methods ci)) $ ds_defs
114− logLvl 1 ("Reordered: " ++ show ds' ++ "\n")
114+ logElab 1 ("Reordered: " ++ show ds' ++ "\n")
115115 mapM_ (warnMissing ds' ns iname) (map fst (class_methods ci))
116116 mapM_ (checkInClass (map fst (class_methods ci))) (concatMap defined ds')
117117 let wbTys = map mkTyDecl mtys
118118 let wbVals = map (decorateid (decorate ns iname)) ds'
119119 let wb = wbTys ++ wbVals
120− logLvl 3 $ "Method types " ++ showSep "\n" (map (show . showDeclImp verbosePPOption . mkTyDecl) mtys)
121− logLvl 3 $ "Instance is " ++ show ps ++ " implicits " ++
120+ logElab 3 $ "Method types " ++ showSep "\n" (map (show . showDeclImp verbosePPOption . mkTyDecl) mtys)
121+ logElab 3 $ "Instance is " ++ show ps ++ " implicits " ++
122122 show (concat (nub wparams))
123123
124124 -- Bring variables in instance head into scope
@@ -134,12 +134,12 @@ elabInstance info syn doc argDocs what fc cs n nfc ps t expn ds = do
134134 let rhs = PApp fc (PRef fc [] (instanceCtorName ci))
135135 (map (pexp . mkMethApp) mtys)
136136
137− logLvl 5 $ "Instance LHS " ++ show lhs ++ " " ++ show headVars
138− logLvl 5 $ "Instance RHS " ++ show rhs
137+ logElab 5 $ "Instance LHS " ++ show lhs ++ " " ++ show headVars
138+ logElab 5 $ "Instance RHS " ++ show rhs
139139
140140 let idecls = [PClauses fc [Dictionary] iname
141141 [PClause fc iname lhs [] rhs wb]]
142− logLvl 1 (show idecls)
142+ logElab 1 (show idecls)
143143 push_estack iname True
144144 mapM_ (rec_elabDecl info EAll info) idecls
145145 pop_estack
@@ -181,7 +181,7 @@ elabInstance info syn doc argDocs what fc cs n nfc ps t expn ds = do
181181 ctxt <- getContext
182182 (ElabResult tyT _ _ ctxt' newDecls highlights, _) <-
183183 tclift $ elaborate ctxt (idris_datatypes i) iname (TType (UVal 0)) initEState
184− (errAt "type of " iname (erun fc (build i info ERHS [] iname ty)))
184+ (errAt "type of " iname Nothing (erun fc (build i info ERHS [] iname ty)))
185185 setContext ctxt'
186186 processTacticDecls info newDecls
187187 sendHighlighting highlights
@@ -267,11 +267,11 @@ elabInstance info syn doc argDocs what fc cs n nfc ps t expn ds = do
267267 reorderDefs :: [Name] -> [PDecl] -> [PDecl]
268268 reorderDefs ns [] = []
269269 reorderDefs [] ds = ds
270− reorderDefs (n : ns) ds = case pick n [] ds of
270+ reorderDefs (n : ns) ds = case pick n [] ds of
271271 Just (def, ds') -> def : reorderDefs ns ds'
272272 Nothing -> reorderDefs ns ds
273273
274− pick n acc [] = Nothing
274+ pick n acc [] = Nothing
275275 pick n acc (def@(PClauses _ _ cn cs) : ds)
276276 | nsroot n == nsroot cn = Just (def, acc ++ ds)
277277 pick n acc (d : ds) = pick n (acc ++ [d]) ds
@@ -313,13 +313,13 @@ checkInjectiveArgs fc n ds (Just ty)
313313 let (_, args) = unApply (instantiateRetTy ty)
314314 ci 0 ist args
315315 where
316− ci i ist (a : as) | i `elem` ds
316+ ci i ist (a : as) | i `elem` ds
317317 = if isInj ist a then ci (i + 1) ist as
318318 else tclift $ tfail (At fc (InvalidTCArg n a))
319319 ci i ist (a : as) = ci (i + 1) ist as
320320 ci i ist [] = return ()
321321
322− isInj i (P Bound n _) = True
322+ isInj i (P Bound n _) = True
323323 isInj i (P _ n _) = isConName n (tt_ctxt i)
324324 isInj i (App _ f a) = isInj i f && isInj i a
325325 isInj i (V _) = True
@@ -329,4 +329,3 @@ checkInjectiveArgs fc n ds (Just ty)
329329 instantiateRetTy (Bind n (Pi _ _ _) sc)
330330 = substV (P Bound n Erased) (instantiateRetTy sc)
331331 instantiateRetTy t = t
332−
src/Idris/Elab/Provider.hs+3−3
@@ -84,7 +84,7 @@ elabProvider doc info syn fc nfc what n
8484 rhs <- execute (mkApp (P Ref (sUN "run__provider") Erased)
8585 [Erased, e])
8686 let rhs' = normalise ctxt [] rhs
87− logLvl 3 $ "Normalised " ++ show n ++ "'s RHS to " ++ show rhs
87+ logElab 3 $ "Normalised " ++ show n ++ "'s RHS to " ++ show rhs
8888
8989 -- Extract the provided term or postulate from the type provider
9090 provided <- getProvided fc rhs'
@@ -95,11 +95,11 @@ elabProvider doc info syn fc nfc what n
9595 do -- Finally add a top-level definition of the provided term
9696 elabType info syn doc [] fc [] n NoFC ty
9797 elabClauses info fc [] n [PClause fc n (PApp fc (PRef fc [] n) []) [] (delab i tm) []]
98− logLvl 3 $ "Elaborated provider " ++ show n ++ " as: " ++ show tm
98+ logElab 3 $ "Elaborated provider " ++ show n ++ " as: " ++ show tm
9999 | ProvPostulate _ <- what ->
100100 do -- Add the postulate
101101 elabPostulate info syn doc fc nfc [] n (delab i tm)
102− logLvl 3 $ "Elaborated provided postulate " ++ show n
102+ logElab 3 $ "Elaborated provided postulate " ++ show n
103103 | otherwise ->
104104 ierror . Msg $ "Attempted to provide a postulate where a term was expected."
105105
src/Idris/Elab/Record.hs+36−37
@@ -47,18 +47,18 @@ elabRecord :: ElabInfo
4747 -> SyntaxInfo -- ^ Constructor SyntaxInfo
4848 -> Idris ()
4949elabRecord info what doc rsyn fc opts tyn nfc params paramDocs fields cname cdoc csyn
50− = do logLvl 1 $ "Building data declaration for " ++ show tyn
50+ = do logElab 1 $ "Building data declaration for " ++ show tyn
5151 -- Type constructor
5252 let tycon = generateTyConType params
53− logLvl 1 $ "Type constructor " ++ showTmImpls tycon
54−
53+ logElab 1 $ "Type constructor " ++ showTmImpls tycon
54+
5555 -- Data constructor
5656 dconName <- generateDConName (fmap fst cname)
5757 let dconTy = generateDConType params fieldsWithNameAndDoc
58− logLvl 1 $ "Data constructor: " ++ showTmImpls dconTy
58+ logElab 1 $ "Data constructor: " ++ showTmImpls dconTy
5959
6060 -- Build data declaration for elaboration
61− logLvl 1 $ foldr (++) "" $ intersperse "\n" (map show dconsArgDocs)
61+ logElab 1 $ foldr (++) "" $ intersperse "\n" (map show dconsArgDocs)
6262 let datadecl = case what of
6363 ETypes -> PLaterdecl tyn NoFC tycon
6464 _ -> PDatadecl tyn NoFC tycon [(cdoc, dconsArgDocs, dconName, NoFC, dconTy, fc, [])]
@@ -71,8 +71,8 @@ elabRecord info what doc rsyn fc opts tyn nfc params paramDocs fields cname cdoc
7171 addIBC (IBCRecord tyn)
7272
7373 when (what /= ETypes) $ do
74− logLvl 1 $ "fieldsWithName " ++ show fieldsWithName
75− logLvl 1 $ "fieldsWIthNameAndDoc " ++ show fieldsWithNameAndDoc
74+ logElab 1 $ "fieldsWithName " ++ show fieldsWithName
75+ logElab 1 $ "fieldsWIthNameAndDoc " ++ show fieldsWithNameAndDoc
7676 elabRecordFunctions info rsyn fc tyn paramsAndDoc fieldsWithNameAndDoc dconName target
7777
7878 sendHighlighting $
@@ -162,24 +162,24 @@ elabRecordFunctions :: ElabInfo -> SyntaxInfo -> FC
162162 -> PTerm -- ^ Target type
163163 -> Idris ()
164164elabRecordFunctions info rsyn fc tyn params fields dconName target
165− = do logLvl 1 $ "Elaborating helper functions for record " ++ show tyn
165+ = do logElab 1 $ "Elaborating helper functions for record " ++ show tyn
166166
167− logLvl 1 $ "Fields: " ++ show fieldNames
168− logLvl 1 $ "Params: " ++ show paramNames
167+ logElab 1 $ "Fields: " ++ show fieldNames
168+ logElab 1 $ "Params: " ++ show paramNames
169169 -- The elaborated constructor type for the data declaration
170170 i <- getIState
171171 ttConsTy <-
172172 case lookupTyExact dconName (tt_ctxt i) of
173173 Just as -> return as
174− Nothing -> tclift $ tfail $ At fc (Elaborating "record " tyn (InternalMsg "It seems like the constructor for this record has disappeared. :( \n This is a bug. Please report."))
174+ Nothing -> tclift $ tfail $ At fc (Elaborating "record " tyn Nothing (InternalMsg "It seems like the constructor for this record has disappeared. :( \n This is a bug. Please report."))
175175
176176 -- The arguments to the constructor
177177 let constructorArgs = getArgTys ttConsTy
178− logLvl 1 $ "Cons args: " ++ show constructorArgs
179− logLvl 1 $ "Free fields: " ++ show (filter (not . isFieldOrParam') constructorArgs)
178+ logElab 1 $ "Cons args: " ++ show constructorArgs
179+ logElab 1 $ "Free fields: " ++ show (filter (not . isFieldOrParam') constructorArgs)
180180 -- If elaborating the constructor has resulted in some new implicit fields we make projection functions for them.
181181 let freeFieldsForElab = map (freeField i) (filter (not . isFieldOrParam') constructorArgs)
182−
182+
183183 -- The parameters for elaboration with their documentation
184184 -- Parameter functions are all prefixed with "param_".
185185 let paramsForElab = [((nsroot n), (paramName n), impl, t, d) | (n, _, _, t, d) <- params] -- zipParams i params paramDocs]
@@ -187,14 +187,14 @@ elabRecordFunctions info rsyn fc tyn params fields dconName target
187187 -- The fields (written by the user) with their documentation.
188188 let userFieldsForElab = [((nsroot n), n, p, t, d) | (n, nfc, p, t, d) <- fields]
189189
190− -- All things we need to elaborate projection functions for, together with a number denoting their position in the constructor.
191− let projectors = [(n, n', p, t, d, i) | ((n, n', p, t, d), i) <- zip (freeFieldsForElab ++ paramsForElab ++ userFieldsForElab) [0..]]
190+ -- All things we need to elaborate projection functions for, together with a number denoting their position in the constructor.
191+ let projectors = [(n, n', p, t, d, i) | ((n, n', p, t, d), i) <- zip (freeFieldsForElab ++ paramsForElab ++ userFieldsForElab) [0..]]
192192 -- Build and elaborate projection functions
193193 elabProj dconName projectors
194194
195− logLvl 1 $ "Dependencies: " ++ show fieldDependencies
195+ logElab 1 $ "Dependencies: " ++ show fieldDependencies
196196
197− logLvl 1 $ "Depended on: " ++ show dependedOn
197+ logElab 1 $ "Depended on: " ++ show dependedOn
198198
199199 -- All things we need to elaborate update functions for, together with a number denoting their position in the constructor.
200200 let updaters = [(n, n', p, t, d, i) | ((n, n', p, t, d), i) <- zip (paramsForElab ++ userFieldsForElab) [0..]]
@@ -237,7 +237,7 @@ elabRecordFunctions info rsyn fc tyn params fields dconName target
237237 plicity = impl -- All free fields are implicit as they are machine generated
238238 fieldType = delab i (snd arg) -- The type of the field
239239 doc = emptyDocstring -- No docmentation for machine generated fields
240− in (nameInCons, nameFree, plicity, fieldType, doc)
240+ in (nameInCons, nameFree, plicity, fieldType, doc)
241241
242242 freeName :: Name -> Name
243243 freeName (UN n) = sUN ("free_" ++ str n)
@@ -278,7 +278,7 @@ elabRecordFunctions info rsyn fc tyn params fields dconName target
278278 -- | Decides whether a setter should be generated for a field or not.
279279 optionalSetter :: Name -> Bool
280280 optionalSetter n = n `elem` dependedOn
281−
281+
282282 -- | A map from a field name to the other fields it depends on.
283283 fieldDependencies :: [(Name, [Name])]
284284 fieldDependencies = map (uncurry fieldDep) [(n, t) | (n, _, _, t, _) <- fields ++ params]
@@ -314,15 +314,15 @@ elabProjection :: ElabInfo
314314 -> Int -- ^ Argument Index
315315 -> Idris ()
316316elabProjection info cname pname plicity projTy pdoc psyn fc targetTy cn phArgs fnames index
317− = do logLvl 1 $ "Generating Projection for " ++ show pname
318−
317+ = do logElab 1 $ "Generating Projection for " ++ show pname
318+
319319 let ty = generateTy
320− logLvl 1 $ "Type of " ++ show pname ++ ": " ++ show ty
321−
320+ logElab 1 $ "Type of " ++ show pname ++ ": " ++ show ty
321+
322322 let lhs = generateLhs
323− logLvl 1 $ "LHS of " ++ show pname ++ ": " ++ showTmImpls lhs
323+ logElab 1 $ "LHS of " ++ show pname ++ ": " ++ showTmImpls lhs
324324 let rhs = generateRhs
325− logLvl 1 $ "RHS of " ++ show pname ++ ": " ++ showTmImpls rhs
325+ logElab 1 $ "RHS of " ++ show pname ++ ": " ++ showTmImpls rhs
326326
327327 rec_elabDecl info EAll info ty
328328
@@ -372,24 +372,24 @@ elabUpdate :: ElabInfo
372372 -> Bool -- ^ Optional
373373 -> Idris ()
374374elabUpdate info cname pname plicity pty pdoc psyn fc sty cn args fnames i optional
375− = do logLvl 1 $ "Generating Update for " ++ show pname
376−
375+ = do logElab 1 $ "Generating Update for " ++ show pname
376+
377377 let ty = generateTy
378− logLvl 1 $ "Type of " ++ show set_pname ++ ": " ++ show ty
379−
378+ logElab 1 $ "Type of " ++ show set_pname ++ ": " ++ show ty
379+
380380 let lhs = generateLhs
381− logLvl 1 $ "LHS of " ++ show set_pname ++ ": " ++ showTmImpls lhs
382−
381+ logElab 1 $ "LHS of " ++ show set_pname ++ ": " ++ showTmImpls lhs
382+
383383 let rhs = generateRhs
384− logLvl 1 $ "RHS of " ++ show set_pname ++ ": " ++ showTmImpls rhs
384+ logElab 1 $ "RHS of " ++ show set_pname ++ ": " ++ showTmImpls rhs
385385
386− let clause = PClause fc set_pname lhs [] rhs []
386+ let clause = PClause fc set_pname lhs [] rhs []
387387
388388 idrisCatch (do rec_elabDecl info EAll info ty
389389 rec_elabDecl info EAll info $ PClauses fc [] set_pname [clause])
390− (\err -> logLvl 1 $ "Could not generate update function for " ++ show pname)
390+ (\err -> logElab 1 $ "Could not generate update function for " ++ show pname)
391391 {-if optional
392− then logLvl 1 $ "Could not generate update function for " ++ show pname
392+ then logElab 1 $ "Could not generate update function for " ++ show pname
393393 else tclift $ tfail $ At fc (Elaborating "record update function " pname err)) -}
394394 where
395395 -- | The type of the update function.
@@ -463,4 +463,3 @@ projectInType xs = mapPT st
463463-- | Creates an PArg from a plicity and a name where the term is a PRef.
464464asPRefArg :: Plicity -> Name -> PArg
465465asPRefArg p n = asArg p (nsroot n) $ PRef emptyFC [] (nsroot n)
466−
src/Idris/Elab/Term.hs+293−203
@@ -28,9 +28,10 @@ import qualified Util.Pretty as U
2828import Control.Applicative ((<$>))
2929import Control.Monad
3030import Control.Monad.State.Strict
31+import Data.Foldable (for_)
3132import Data.List
3233import qualified Data.Map as M
33−import Data.Maybe (mapMaybe, fromMaybe, catMaybes)
34+import Data.Maybe (mapMaybe, fromMaybe, catMaybes, maybeToList)
3435import qualified Data.Set as S
3536import qualified Data.Text as T
3637
@@ -90,7 +91,7 @@ build ist info emode opts fn tm
9091 g <- goal
9192 ptm <- get_term
9293 resolveTC' True True 10 g fn ist) ivs
93−
94+
9495 when (not pattern) $ solveAutos ist fn False
9596
9697 tm <- get_term
@@ -137,15 +138,16 @@ build ist info emode opts fn tm
137138-- (Separate, so we don't go overboard resolving things that we don't
138139-- know about yet on the LHS of a pattern def)
139140
140−buildTC :: IState -> ElabInfo -> ElabMode -> FnOpts -> Name -> PTerm ->
141+buildTC :: IState -> ElabInfo -> ElabMode -> FnOpts -> Name ->
142+ [Name] -> -- Cached names in the PTerm, before adding PAlternatives
143+ PTerm ->
141144 ElabD ElabResult
142−buildTC ist info emode opts fn tm
143− = do -- set name supply to begin after highest index in tm
144− let ns = allNamesIn tm
145− let tmIn = tm
145+buildTC ist info emode opts fn ns tm
146+ = do let tmIn = tm
146147 let inf = case lookupCtxt fn (idris_tyinfodata ist) of
147148 [TIPartial] -> True
148149 _ -> False
150+ -- set name supply to begin after highest index in tm
149151 initNextNameFrom ns
150152 elab ist info emode opts fn tm
151153 probs <- get_probs
@@ -169,7 +171,7 @@ buildTC ist info emode opts fn tm
169171 else return (ElabResult tm ds (map snd is) ctxt impls highlights)
170172 where pattern = emode == ELHS
171173
172−-- return whether arguments of the given constructor name can be
174+-- return whether arguments of the given constructor name can be
173175-- matched on. If they're polymorphic, no, unless the type has beed made
174176-- concrete by the time we get around to elaborating the argument.
175177getUnmatchable :: Context -> Name -> [Bool]
@@ -178,11 +180,11 @@ getUnmatchable ctxt n | isDConName n ctxt && n /= inferCon
178180 Nothing -> []
179181 Just ty -> checkArgs [] [] ty
180182 where checkArgs :: [Name] -> [[Name]] -> Type -> [Bool]
181− checkArgs env ns (Bind n (Pi _ t _) sc)
183+ checkArgs env ns (Bind n (Pi _ t _) sc)
182184 = let env' = case t of
183185 TType _ -> n : env
184186 _ -> env in
185− checkArgs env' (intersect env (refsIn t) : ns)
187+ checkArgs env' (intersect env (refsIn t) : ns)
186188 (instantiate (P Bound n t) sc)
187189 checkArgs env ns t
188190 = map (not . null) (reverse ns)
@@ -191,7 +193,7 @@ getUnmatchable ctxt n = []
191193
192194data ElabCtxt = ElabCtxt { e_inarg :: Bool,
193195 e_isfn :: Bool, -- ^ Function part of application
194− e_guarded :: Bool,
196+ e_guarded :: Bool,
195197 e_intype :: Bool,
196198 e_qq :: Bool,
197199 e_nomatching :: Bool -- ^ can't pattern match
@@ -265,17 +267,17 @@ elab ist info emode opts fn tm
265267 -- normally correct to call elabE - the ones that don't are desugarings
266268 -- typically
267269 elabE :: ElabCtxt -> Maybe FC -> PTerm -> ElabD ()
268− elabE ina fc' t =
270+ elabE ina fc' t =
269271 do solved <- get_recents
270272 as <- get_autos
271273 hs <- get_holes
272274 -- If any of the autos use variables which have recently been solved,
273275 -- have another go at solving them now.
274− mapM_ (\(a, (failc, ns)) ->
276+ mapM_ (\(a, (failc, ns)) ->
275277 if any (\n -> n `elem` solved) ns && head hs /= a
276278 then solveAuto ist fn False (a, failc)
277279 else return ()) as
278−
280+
279281 itm <- if not pattern then insertImpLam ina t else return t
280282 ct <- insertCoerce ina itm
281283 t' <- insertLazy ct
@@ -308,7 +310,7 @@ elab ist info emode opts fn tm
308310 forceErr orig env (InfiniteUnify _ t _)
309311 | (P _ (UN ht) _, _) <- unApply (normalise (tt_ctxt ist) env t),
310312 ht == txt "Lazy'" = notDelay orig
311− forceErr orig env (Elaborating _ _ t) = forceErr orig env t
313+ forceErr orig env (Elaborating _ _ _ t) = forceErr orig env t
312314 forceErr orig env (ElaboratingArg _ _ _ t) = forceErr orig env t
313315 forceErr orig env (At _ t) = forceErr orig env t
314316 forceErr orig env t = False
@@ -341,7 +343,7 @@ elab ist info emode opts fn tm
341343-- elab' (_,_,inty) (PConstant c)
342344-- | constType c && pattern && not reflection && not inty
343345-- = lift $ tfail (Msg "Typecase is not allowed")
344− elab' ina fc tm@(PConstant fc' c)
346+ elab' ina fc tm@(PConstant fc' c)
345347 | pattern && not reflection && not (e_qq ina) && not (e_intype ina)
346348 && isTypeConst c
347349 = lift $ tfail $ Msg ("No explicit types on left hand side: " ++ show tm)
@@ -361,7 +363,7 @@ elab ist info emode opts fn tm
361363 elab' ina fc (PResolveTC (FC "HACK" _ _)) -- for chasing parent classes
362364 = do g <- goal; resolveTC' False False 5 g fn ist
363365 elab' ina fc (PResolveTC fc')
364− = do c <- getNameFrom (sMN 0 "class")
366+ = do c <- getNameFrom (sMN 0 "__class")
365367 instanceArg c
366368 -- Elaborate the equality type first homogeneously, then
367369 -- heterogeneously as a fallback
@@ -395,7 +397,7 @@ elab ist info emode opts fn tm
395397 UType _ -> elab' ina (Just fc) (PApp fc (PRef fc hls upairTy)
396398 [pexp l,pexp r])
397399 _ -> case tc of
398− P _ n _ | n == upairTy
400+ P _ n _ | n == upairTy
399401 -> elab' ina (Just fc) (PApp fc (PRef fc hls upairCon)
400402 [pimp (sUN "A") Placeholder False,
401403 pimp (sUN "B") Placeholder False,
@@ -442,16 +444,17 @@ elab ist info emode opts fn tm
442444 uns <- get_usedns
443445 let as' = map (mkUniqueNames (uns ++ map snd ms) ms) as_pruned
444446 (h : hs) <- get_holes
445−-- trace (show (map showHd as')) $
446447 ty <- goal
447448 case as' of
448− [] -> lift $ tfail $ NoValidAlts (map showHd as)
449+ [] -> do hds <- mapM showHd as
450+ lift $ tfail $ NoValidAlts hds
449451 [x] -> elab' ina fc x
450452 -- If there's options, try now, and if that fails, postpone
451453 -- to later.
452454 _ -> handleError isAmbiguous
453− (tryAll (zip (map (elab' ina fc) as')
454− (map showHd as')))
455+ (do hds <- mapM showHd as'
456+ tryAll (zip (map (elab' ina fc) as')
457+ hds))
455458 (do movelast h
456459 delayElab 5 $ do
457460 hs <- get_holes
@@ -460,16 +463,17 @@ elab ist info emode opts fn tm
460463 as'' <- doPrune as'
461464 case as'' of
462465 [x] -> elab' ina fc x
463− _ -> tryAll (zip (map (elab' ina fc) as'')
464− (map showHd as'')))
466+ _ -> do hds <- mapM showHd as''
467+ tryAll (zip (map (elab' ina fc) as'')
468+ hds))
465469 where showHd (PApp _ (PRef _ _ (UN l)) [_, _, arg])
466470 | l == txt "Delay" = showHd (getTm arg)
467− showHd (PApp _ (PRef _ _ n) _) = n
468− showHd (PRef _ _ n) = n
471+ showHd (PApp _ (PRef _ _ n) _) = return n
472+ showHd (PRef _ _ n) = return n
469473 showHd (PApp _ h _) = showHd h
470− showHd x = NErased -- We probably should do something better than this here
474+ showHd x = getNameFrom (sMN 0 "_") -- We probably should do something better than this here
471475
472− doPrune as =
476+ doPrune as =
473477 do compute
474478 ty <- goal
475479 let (tc, _) = unApply (unDelay ty)
@@ -479,10 +483,9 @@ elab ist info emode opts fn tm
479483 unDelay t | (P _ (UN l) _, [_, arg]) <- unApply t,
480484 l == txt "Lazy'" = unDelay arg
481485 | otherwise = t
482−
483486
484487 isAmbiguous (CantResolveAlts _) = delayok
485− isAmbiguous (Elaborating _ _ e) = isAmbiguous e
488+ isAmbiguous (Elaborating _ _ _ e) = isAmbiguous e
486489 isAmbiguous (ElaboratingArg _ _ _ e) = isAmbiguous e
487490 isAmbiguous (At _ e) = isAmbiguous e
488491 isAmbiguous _ = False
@@ -506,7 +509,7 @@ elab ist info emode opts fn tm
506509 ty <- goal
507510 let doelab = elab' ina fc orig
508511 tryCatch doelab
509− (\err ->
512+ (\err ->
510513 if recoverableErr err
511514 then -- trace ("NEED IMPLICIT! " ++ show orig ++ "\n" ++
512515 -- show alts ++ "\n" ++
@@ -544,7 +547,7 @@ elab ist info emode opts fn tm
544547 pruneAlts err alts _ = filter isLend alts
545548
546549 hasArg n env ap | isLend ap = True -- special case hack for 'Borrowed'
547− hasArg n env (PApp _ (PRef _ _ a) _)
550+ hasArg n env (PApp _ (PRef _ _ a) _)
548551 = case lookupTyExact a (tt_ctxt ist) of
549552 Just ty -> let args = map snd (getArgTys (normalise (tt_ctxt ist) env ty)) in
550553 any (fnIs n) args
@@ -659,7 +662,7 @@ elab ist info emode opts fn tm
659662 introTy (Var tyn) (Just n)
660663 addPSname n -- okay for proof search
661664 focus tyn
662−
665+
663666 elabE (ec { e_inarg = True, e_intype = True }) (Just fc) ty
664667 elabE (ec { e_inarg = True }) (Just fc) sc
665668 solve
@@ -698,10 +701,10 @@ elab ist info emode opts fn tm
698701 Placeholder -> return ()
699702 _ -> do focus tyn
700703 explicit tyn
701− elabE (ina { e_inarg = True, e_intype = True })
704+ elabE (ina { e_inarg = True, e_intype = True })
702705 (Just fc) ty
703706 focus valn
704− elabE (ina { e_inarg = True, e_intype = True })
707+ elabE (ina { e_inarg = True, e_intype = True })
705708 (Just fc) val
706709 ivs' <- get_instances
707710 env <- get_env
@@ -711,8 +714,9 @@ elab ist info emode opts fn tm
711714 g <- goal
712715 hs <- get_holes
713716 if all (\n -> n == tyn || not (n `elem` hs)) (freeNames g)
714− then try (resolveTC' True False 10 g fn ist)
715− (movelast n)
717+ then handleError (tcRecoverable emode)
718+ (resolveTC' True False 10 g fn ist)
719+ (movelast n)
716720 else movelast n)
717721 (ivs' \\ ivs)
718722 -- HACK: If the name leaks into its type, it may leak out of
@@ -804,14 +808,14 @@ elab ist info emode opts fn tm
804808 annot <- findHighlight f
805809 mapM_ checkKnownImplicit args_in
806810 let args = insertScopedImps fc (normalise ctxt env fty) args_in
807− let unmatchableArgs = if pattern
811+ let unmatchableArgs = if pattern
808812 then getUnmatchable (tt_ctxt ist) f
809813 else []
810−-- trace ("BEFORE " ++ show f ++ ": " ++ show ty) $
814+-- trace ("BEFORE " ++ show f ++ ": " ++ show ty) $
811815 when (pattern && not reflection && not (e_qq ina) && not (e_intype ina)
812816 && isTConName f (tt_ctxt ist)) $
813817 lift $ tfail $ Msg ("No explicit types on left hand side: " ++ show tm)
814−-- trace (show (f, args_in, args)) $
818+-- trace (show (f, args_in, args)) $
815819 if (f `elem` map fst env && length args == 1 && length args_in == 1)
816820 then -- simple app, as below
817821 do simple_app False
@@ -849,7 +853,7 @@ elab ist info emode opts fn tm
849853 mapM (uncurry highlightSource) $
850854 (ffc, annot) : map (\f -> (f, annot)) hls
851855
852− elabArgs ist (ina { e_inarg = e_inarg ina || not isinf })
856+ elabArgs ist (ina { e_inarg = e_inarg ina || not isinf })
853857 [] fc False f
854858 (zip ns (unmatchableArgs ++ repeat False))
855859 (f == sUN "Force")
@@ -876,26 +880,27 @@ elab ist info emode opts fn tm
876880 ivs' <- get_instances
877881 -- Attempt to resolve any type classes which have 'complete' types,
878882 -- i.e. no holes in them
879− when (not pattern || (e_inarg ina && not tcgen &&
883+ when (not pattern || (e_inarg ina && not tcgen &&
880884 not (e_guarded ina))) $
881885 mapM_ (\n -> do focus n
882886 g <- goal
883887 env <- get_env
884888 hs <- get_holes
885889 if all (\n -> not (n `elem` hs)) (freeNames g)
886− then try (resolveTC' False False 10 g fn ist)
890+ then handleError (tcRecoverable emode)
891+ (resolveTC' False False 10 g fn ist)
887892 (movelast n)
888893 else movelast n)
889894 (ivs' \\ ivs)
890895 return []
891− where
896+ where
892897 -- Run the elaborator, which returns how many implicit
893898 -- args were needed, then run it again with those args. We need
894899 -- this because we have to elaborate the whole application to
895900 -- find out whether any computations have caused more implicits
896901 -- to be needed.
897902 implicitApp :: ElabD [ImplicitInfo] -> ElabD ()
898− implicitApp elab
903+ implicitApp elab
899904 | pattern || intransform = do elab; return ()
900905 | otherwise
901906 = do s <- get
@@ -904,7 +909,7 @@ elab ist info emode opts fn tm
904909 [] -> return ()
905910 es -> do put s
906911 elab' ina topfc (PAppImpl tm es)
907−
912+
908913 checkKnownImplicit imp
909914 | UnknownImp `elem` argopts imp
910915 = lift $ tfail $ UnknownImplicit (pname imp) f
@@ -961,7 +966,7 @@ elab ist info emode opts fn tm
961966 headRef (PAlternative _ _ as) = all headRef as
962967 headRef _ = False
963968
964− elab' ina fc (PAppImpl f es) = do appImpl (reverse es) -- not that we look...
969+ elab' ina fc (PAppImpl f es) = do appImpl (reverse es) -- not that we look...
965970 solve
966971 where appImpl [] = elab' (ina { e_isfn = False }) fc f -- e_isfn not set, so no recursive expansion of implicits
967972 appImpl (e : es) = simple_app False
@@ -1023,12 +1028,22 @@ elab ist info emode opts fn tm
10231028 solve
10241029 elab' ina _ c@(PCase fc scr opts)
10251030 = do attack
1031+
10261032 tyn <- getNameFrom (sMN 0 "scty")
10271033 claim tyn RType
10281034 valn <- getNameFrom (sMN 0 "scval")
10291035 scvn <- getNameFrom (sMN 0 "scvar")
10301036 claim valn (Var tyn)
10311037 letbind scvn (Var tyn) (Var valn)
1038+
1039+ -- Start filling in the scrutinee type, if we can work one
1040+ -- out from the case options
1041+ let scrTy = getScrType (map fst opts)
1042+ case scrTy of
1043+ Nothing -> return ()
1044+ Just ty -> do focus tyn
1045+ elabE ina (Just fc) ty
1046+
10321047 focus valn
10331048 elabE (ina { e_inarg = True }) (Just fc) scr
10341049 -- Solve any remaining implicits - we need to solve as many
@@ -1041,7 +1056,7 @@ elab ist info emode opts fn tm
10411056
10421057 -- Drop the unique arguments used in the term already
10431058 -- and in the scrutinee (since it's
1044− -- not valid to use them again anyway)
1059+ -- not valid to use them again anyway)
10451060 --
10461061 -- Also drop unique arguments which don't appear explicitly
10471062 -- in either case branch so they don't count as used
@@ -1050,14 +1065,14 @@ elab ist info emode opts fn tm
10501065 ptm <- get_term
10511066 let inOpts = (filter (/= scvn) (map fst args)) \\ (concatMap (\x -> allNamesIn (snd x)) opts)
10521067
1053− let argsDropped = filter (isUnique envU)
1068+ let argsDropped = filter (isUnique envU)
10541069 (nub $ allNamesIn scr ++ inApp ptm ++
10551070 inOpts)
10561071
10571072 let args' = filter (\(n, _) -> n `notElem` argsDropped) args
10581073
10591074 attack
1060− cname' <- defer argsDropped (mkN (mkCaseName fn))
1075+ cname' <- defer argsDropped (mkN (mkCaseName fc fn))
10611076 solve
10621077
10631078 -- if the scrutinee is one of the 'args' in env, we should
@@ -1070,8 +1085,8 @@ elab ist info emode opts fn tm
10701085 -- if we haven't got the type yet, hopefully we'll get it later!
10711086 movelast tyn
10721087 solve
1073− where mkCaseName (NS n ns) = NS (mkCaseName n) ns
1074− mkCaseName n = SN (CaseN n)
1088+ where mkCaseName fc (NS n ns) = NS (mkCaseName fc n) ns
1089+ mkCaseName fc n = SN (CaseN (FC' fc) n)
10751090-- mkCaseName (UN x) = UN (x ++ "_case")
10761091-- mkCaseName (MN i x) = MN i (x ++ "_case")
10771092 mkN n@(NS _ _) = n
@@ -1079,6 +1094,21 @@ elab ist info emode opts fn tm
10791094 Just xs@(_:_) -> sNS n xs
10801095 _ -> n
10811096
1097+ getScrType [] = Nothing
1098+ getScrType (f : os) = maybe (getScrType os) Just (getAppType f)
1099+
1100+ getAppType (PRef _ _ n) =
1101+ case lookupTyName n (tt_ctxt ist) of
1102+ [(n', ty)] | isDConName n' (tt_ctxt ist) ->
1103+ case unApply (getRetTy ty) of
1104+ (P _ tyn _, args) ->
1105+ Just (PApp fc (PRef fc [] tyn)
1106+ (map pexp (map (const Placeholder) args)))
1107+ _ -> Nothing
1108+ _ -> Nothing -- ambiguity is no help to us!
1109+ getAppType (PApp _ t as) = getAppType t
1110+ getAppType _ = Nothing
1111+
10821112 inApp (P _ n _) = [n]
10831113 inApp (App _ f a) = inApp f ++ inApp a
10841114 inApp (Bind n (Let _ v) sc) = inApp v ++ inApp sc
@@ -1220,12 +1250,12 @@ elab ist info emode opts fn tm
12201250 [] -> lift . tfail . NoSuchVariable $ n
12211251 more -> lift . tfail . CantResolveAlts $ map fst more
12221252 elab' ina fc (PAs _ n t) = lift . tfail . Msg $ "@-pattern not allowed here"
1223− elab' ina fc (PHidden t)
1253+ elab' ina fc (PHidden t)
12241254 | reflection = elab' ina fc t
12251255 | otherwise
12261256 = do (h : hs) <- get_holes
12271257 -- Dotting a hole means that either the hole or any outer
1228− -- hole (a hole outside any occurrence of it)
1258+ -- hole (a hole outside any occurrence of it)
12291259 -- must be solvable by unification as well as being filled
12301260 -- in directly.
12311261 -- Delay dotted things to the end, then when we elaborate them
@@ -1237,17 +1267,18 @@ elab ist info emode opts fn tm
12371267 elab' ina fc (PRunElab fc' tm ns) =
12381268 do attack
12391269 n <- getNameFrom (sMN 0 "tacticScript")
1240− n' <- getNameFrom (sMN 0 "tacticExpr")
12411270 let scriptTy = RApp (Var (sNS (sUN "Elab")
12421271 ["Elab", "Reflection", "Language"]))
12431272 (Var unitTy)
12441273 claim n scriptTy
1245− movelast n
1246− letbind n' scriptTy (Var n)
12471274 focus n
1275+ attack -- to get an extra hole
12481276 elab' ina (Just fc') tm
1277+ script <- get_guess
1278+ fullyElaborated script
1279+ solve -- eliminate the hole. Becuase there are no references, the script is only in the binding
12491280 env <- get_env
1250− runElabAction ist (maybe fc' id fc) env (P Bound n' Erased) ns
1281+ runElabAction ist (maybe fc' id fc) env script ns
12511282 solve
12521283 elab' ina fc (PConstSugar constFC tm) =
12531284 -- Here we elaborate the contained term, then calculate
@@ -1292,7 +1323,7 @@ elab ist info emode opts fn tm
12921323 -- The delayed things with lower numbered priority will be elaborated
12931324 -- first. (In practice, this means delayed alternatives, then PHidden
12941325 -- things.)
1295− delayElab pri t
1326+ delayElab pri t
12961327 = updateAux (\e -> e { delayed_elab = delayed_elab e ++ [(pri, t)] })
12971328
12981329 isScr :: PTerm -> (Name, Binder Term) -> (Name, (Bool, Binder Term))
@@ -1360,6 +1391,19 @@ elab ist info emode opts fn tm
13601391 getFC d (PAlternative _ _ (x:_)) = getFC d x
13611392 getFC d x = d
13621393
1394+ -- Fail if a term is not yet fully elaborated (e.g. if it contains
1395+ -- case block functions that don't yet exist)
1396+ fullyElaborated :: Term -> ElabD ()
1397+ fullyElaborated (P _ n _) =
1398+ do EState cases _ _ _ <- getAux
1399+ case lookup n cases of
1400+ Nothing -> return ()
1401+ Just _ -> lift . tfail $ ElabScriptStaging n
1402+ fullyElaborated (Bind n b body) = fullyElaborated body >> for_ b fullyElaborated
1403+ fullyElaborated (App _ l r) = fullyElaborated l >> fullyElaborated r
1404+ fullyElaborated (Proj t _) = fullyElaborated t
1405+ fullyElaborated _ = return ()
1406+
13631407 insertLazy :: PTerm -> ElabD PTerm
13641408 insertLazy t@(PApp _ (PRef _ _ (UN l)) _) | l == txt "Delay" = return t
13651409 insertLazy t@(PApp _ (PRef _ _ (UN l)) _) | l == txt "Force" = return t
@@ -1396,9 +1440,9 @@ elab ist info emode opts fn tm
13961440 notImplicitable _ = False
13971441
13981442 insertScopedImps fc (Bind n (Pi im@(Just i) _ _) sc) xs
1399− | tcinstance i
1443+ | tcinstance i && not (toplevel_imp i)
14001444 = pimp n (PResolveTC fc) True : insertScopedImps fc sc xs
1401− | otherwise
1445+ | not (toplevel_imp i)
14021446 = pimp n Placeholder True : insertScopedImps fc sc xs
14031447 insertScopedImps fc (Bind n (Pi _ _ _) sc) (x : xs)
14041448 = x : insertScopedImps fc sc xs
@@ -1432,7 +1476,7 @@ elab ist info emode opts fn tm
14321476 let t' = case (t, cs) of
14331477 (PCoerced tm, _) -> tm
14341478 (_, []) -> t
1435− (_, cs) -> PAlternative [] TryImplicit
1479+ (_, cs) -> PAlternative [] TryImplicit
14361480 (t : map (mkCoerce env t) cs)
14371481 return t'
14381482 where
@@ -1554,7 +1598,7 @@ pruneByType env (P _ n _) ist as
15541598 [] -> asV
15551599 _ -> as'
15561600 where
1557− ctxt = tt_ctxt ist
1601+ ctxt = tt_ctxt ist
15581602
15591603 headIs var f (PRef _ _ f') = typeHead var f f'
15601604 headIs var f (PApp _ (PRef _ _ (UN l)) [_, _, arg])
@@ -1573,7 +1617,7 @@ pruneByType env (P _ n _) ist as
15731617 _ -> let ty' = normalise ctxt [] ty in
15741618 case unApply (getRetTy ty') of
15751619 (P _ ftyn _, _) -> ftyn == f
1576− (V _, _) ->
1620+ (V _, _) ->
15771621 -- keep, variable
15781622-- trace ("Keeping " ++ show (f', ty')
15791623-- ++ " for " ++ show n) $
@@ -1590,22 +1634,22 @@ pruneByType _ t _ as = as
15901634-- (FIXME: This isn't complete, but I'm leaving it here and coming back
15911635-- to it later - just returns 'var' for now. EB)
15921636isPlausible :: IState -> Bool -> Env -> Name -> Type -> Bool
1593−isPlausible ist var env n ty
1637+isPlausible ist var env n ty
15941638 = let (hvar, classes) = collectConstraints [] [] ty in
15951639 case hvar of
15961640 Nothing -> True
15971641 Just rth -> var -- trace (show (rth, classes)) var
15981642 where
1599− collectConstraints :: [Name] -> [(Term, [Name])] -> Type ->
1643+ collectConstraints :: [Name] -> [(Term, [Name])] -> Type ->
16001644 (Maybe Name, [(Term, [Name])])
16011645 collectConstraints env tcs (Bind n (Pi _ ty _) sc)
16021646 = let tcs' = case unApply ty of
1603− (P _ c _, _) ->
1647+ (P _ c _, _) ->
16041648 case lookupCtxtExact c (idris_classes ist) of
1605− Just tc -> ((ty, map fst (class_instances tc))
1606− : tcs)
1649+ Just tc -> ((ty, map fst (class_instances tc))
1650+ : tcs)
16071651 Nothing -> tcs
1608− _ -> tcs
1652+ _ -> tcs
16091653 in
16101654 collectConstraints (n : env) tcs' sc
16111655 collectConstraints env tcs t
@@ -1625,7 +1669,7 @@ findHighlight n = do ctxt <- get_context
16251669
16261670-- Try again to solve auto implicits
16271671solveAuto :: IState -> Name -> Bool -> (Name, [FailContext]) -> ElabD ()
1628−solveAuto ist fn ambigok (n, failc)
1672+solveAuto ist fn ambigok (n, failc)
16291673 = do hs <- get_holes
16301674 when (not (null hs)) $ do
16311675 env <- get_env
@@ -1638,15 +1682,15 @@ solveAuto ist fn ambigok (n, failc)
16381682 (lift $ Error (addLoc failc
16391683 (CantSolveGoal g (map (\(n, b) -> (n, binderTy b)) env))))
16401684 return ()
1641− where addLoc (FailContext fc f x : prev) err
1642− = At fc (ElaboratingArg f x
1685+ where addLoc (FailContext fc f x : prev) err
1686+ = At fc (ElaboratingArg f x
16431687 (map (\(FailContext _ f' x') -> (f', x')) prev) err)
16441688 addLoc _ err = err
16451689
16461690 cantsolve (CantSolveGoal _ _) = True
16471691 cantsolve (InternalMsg _) = True
16481692 cantsolve (At _ e) = cantsolve e
1649− cantsolve (Elaborating _ _ e) = cantsolve e
1693+ cantsolve (Elaborating _ _ _ e) = cantsolve e
16501694 cantsolve (ElaboratingArg _ _ _ e) = cantsolve e
16511695 cantsolve _ = False
16521696
@@ -1655,6 +1699,15 @@ solveAutos ist fn ambigok
16551699 = do autos <- get_autos
16561700 mapM_ (solveAuto ist fn ambigok) (map (\(n, (fc, _)) -> (n, fc)) autos)
16571701
1702+-- Return true if the given error suggests a type class failure is
1703+-- recoverable
1704+tcRecoverable :: ElabMode -> Err -> Bool
1705+tcRecoverable ERHS (CantResolve f g) = f
1706+tcRecoverable ETyDecl (CantResolve f g) = f
1707+tcRecoverable e (ElaboratingArg _ _ _ err) = tcRecoverable e err
1708+tcRecoverable e (At _ err) = tcRecoverable e err
1709+tcRecoverable _ _ = True
1710+
16581711trivial' ist
16591712 = trivial (elab ist toplevel ERHS [] (sMN 0 "tac")) ist
16601713trivialHoles' psn h ist
@@ -1668,38 +1721,25 @@ resolveTC' di mv depth tm n ist
16681721
16691722collectDeferred :: Maybe Name -> [Name] -> Context ->
16701723 Term -> State [(Name, (Int, Maybe Name, Type, [Name]))] Term
1671−collectDeferred top casenames ctxt (Bind n (GHole i psns t) app) =
1672− do ds <- get
1673− t' <- collectDeferred top casenames ctxt t
1674− when (not (n `elem` map fst ds)) $ put (ds ++ [(n, (i, top, tidyArg [] t', psns))])
1675− collectDeferred top casenames ctxt app
1724+collectDeferred top casenames ctxt tm = cd [] tm
16761725 where
1677− -- Evaluate the top level functions in arguments, if possible, and if it's
1678− -- not a name we're immediately going to define in a case block, so that
1679− -- any immediate specialisation of the function applied to constructors
1680− -- can be done
1681− tidyArg env (Bind n b@(Pi im t k) sc)
1682− = Bind n (Pi im (tidy ctxt env t) k)
1683− (tidyArg ((n, b) : env) sc)
1684− tidyArg env t = tidy ctxt env t
1685−
1686− tidy ctxt env t = normalise ctxt env t
1687−
1688− getFn (Bind n (Lam _) t) = getFn t
1689− getFn t | (f, a) <- unApply t = f
1690−
1691−collectDeferred top ns ctxt (Bind n b t)
1692− = do b' <- cdb b
1693− t' <- collectDeferred top ns ctxt t
1694− return (Bind n b' t')
1695− where
1696− cdb (Let t v) = liftM2 Let (collectDeferred top ns ctxt t) (collectDeferred top ns ctxt v)
1697− cdb (Guess t v) = liftM2 Guess (collectDeferred top ns ctxt t) (collectDeferred top ns ctxt v)
1698− cdb b = do ty' <- collectDeferred top ns ctxt (binderTy b)
1699− return (b { binderTy = ty' })
1700−collectDeferred top ns ctxt (App s f a) = liftM2 (App s) (collectDeferred top ns ctxt f)
1701− (collectDeferred top ns ctxt a)
1702−collectDeferred top ns ctxt t = return t
1726+ cd env (Bind n (GHole i psns t) app) =
1727+ do ds <- get
1728+ t' <- collectDeferred top casenames ctxt t
1729+ when (not (n `elem` map fst ds)) $ put (ds ++ [(n, (i, top, t', psns))])
1730+ cd env app
1731+ cd env (Bind n b t)
1732+ = do b' <- cdb b
1733+ t' <- cd ((n, b) : env) t
1734+ return (Bind n b' t')
1735+ where
1736+ cdb (Let t v) = liftM2 Let (cd env t) (cd env v)
1737+ cdb (Guess t v) = liftM2 Guess (cd env t) (cd env v)
1738+ cdb b = do ty' <- cd env (binderTy b)
1739+ return (b { binderTy = ty' })
1740+ cd env (App s f a) = liftM2 (App s) (cd env f)
1741+ (cd env a)
1742+ cd env t = return t
17031743
17041744case_ :: Bool -> Bool -> IState -> Name -> PTerm -> ElabD ()
17051745case_ ind autoSolve ist fn tm = do
@@ -1735,14 +1775,33 @@ runElabAction ist fc env tm ns = do tm' <- eval tm
17351775
17361776 returnUnit = return $ P (DCon 0 0 False) unitCon (P (TCon 0 0) unitTy Erased)
17371777
1738− patvars :: [Name] -> Term -> ([Name], Term)
1739− patvars ns (Bind n (PVar t) sc) = patvars (n : ns) (instantiate (P Bound n t) sc)
1778+ patvars :: [(Name, Term)] -> Term -> ([(Name, Term)], Term)
1779+ patvars ns (Bind n (PVar t) sc) = patvars ((n, t) : ns) (instantiate (P Bound n t) sc)
17401780 patvars ns tm = (ns, tm)
17411781
1742− pullVars :: (Term, Term) -> ([Name], Term, Term)
1782+ pullVars :: (Term, Term) -> ([(Name, Term)], Term, Term)
17431783 pullVars (lhs, rhs) = (fst (patvars [] lhs), snd (patvars [] lhs), snd (patvars [] rhs)) -- TODO alpha-convert rhs
17441784
1745− defineFunction :: RFunDefn -> ElabD ()
1785+ requireError :: Err -> ElabD a -> ElabD ()
1786+ requireError orErr elab =
1787+ do state <- get
1788+ case runStateT elab state of
1789+ OK (_, state') -> lift (tfail orErr)
1790+ Error e -> return ()
1791+
1792+ -- create a fake TT term for the LHS of an impossible case
1793+ fakeTT :: Raw -> Term
1794+ fakeTT (Var n) =
1795+ case lookupNameDef n (tt_ctxt ist) of
1796+ [(n', TyDecl nt _)] -> P nt n' Erased
1797+ _ -> P Ref n Erased
1798+ fakeTT (RBind n b body) = Bind n (fmap fakeTT b) (fakeTT body)
1799+ fakeTT (RApp f a) = App Complete (fakeTT f) (fakeTT a)
1800+ fakeTT RType = TType (UVar (-1))
1801+ fakeTT (RUType u) = UType u
1802+ fakeTT (RConstant c) = Constant c
1803+
1804+ defineFunction :: RFunDefn Raw -> ElabD ()
17461805 defineFunction (RDefineFun n clauses) =
17471806 do ctxt <- get_context
17481807 ty <- maybe (fail "no type decl") return $ lookupTyExact n ctxt
@@ -1754,22 +1813,24 @@ runElabAction ist fc env tm ns = do tm' <- eval tm
17541813 lift $ converts ctxt [] lty rty
17551814 return $ Right (lhs', rhs')
17561815 RMkImpossibleClause lhs ->
1757− do lhs' <- fmap fst . lift $ check ctxt [] lhs
1758− return $ Left lhs')
1816+ do requireError (Msg "Not an impossible case") . lift $
1817+ check ctxt [] lhs
1818+ return $ Left (fakeTT lhs))
17591819 let clauses'' = map (\case Right c -> pullVars c
1760− Left lhs -> let (ns, lhs') = patvars [] lhs'
1820+ Left lhs -> let (ns, lhs') = patvars [] lhs
17611821 in (ns, lhs', Impossible))
17621822 clauses'
1823+ let clauses''' = map (\(ns, lhs, rhs) -> (map fst ns, lhs, rhs)) clauses''
17631824 ctxt'<- lift $
17641825 addCasedef n (const [])
17651826 info False (STerm Erased)
17661827 True False -- TODO what are these?
17671828 (map snd $ getArgTys ty) [] -- TODO inaccessible types
17681829 clauses'
1769− clauses''
1770− clauses''
1771− clauses''
1772− clauses''
1830+ clauses'''
1831+ clauses'''
1832+ clauses'''
1833+ clauses'''
17731834 ty
17741835 ctxt
17751836 set_context ctxt'
@@ -1785,10 +1846,10 @@ runElabAction ist fc env tm ns = do tm' <- eval tm
17851846 -- step, the output is the (reflected) term returned.
17861847 runTacTm :: Term -> ElabD Term
17871848 runTacTm (unApply -> tac@(P _ n _, args))
1788− | n == tacN "prim__Solve", [] <- args
1849+ | n == tacN "Prim__Solve", [] <- args
17891850 = do solve
17901851 returnUnit
1791− | n == tacN "prim__Goal", [] <- args
1852+ | n == tacN "Prim__Goal", [] <- args
17921853 = do hs <- get_holes
17931854 case hs of
17941855 (h : _) -> do t <- goal
@@ -1798,27 +1859,19 @@ runElabAction ist fc env tm ns = do tm' <- eval tm
17981859 [] -> lift . tfail . Msg $
17991860 "Elaboration is complete. There are no goals."
18001861
1801− | n == tacN "prim__Holes", [] <- args
1862+ | n == tacN "Prim__Holes", [] <- args
18021863 = do hs <- get_holes
18031864 fmap fst . checkClosed $
18041865 mkList (Var $ reflm "TTName") (map reflectName hs)
1805− | n == tacN "prim__Guess", [] <- args
1806− = do ok <- is_guess
1807− if ok
1808− then do guess <- fmap forget get_guess
1809− fmap fst . get_type_val $
1810− RApp (RApp (Var (sNS (sUN "Just") ["Maybe", "Prelude"]))
1811− (Var (reflm "TT")))
1812− guess
1813− else fmap fst . checkClosed $
1814− RApp (Var (sNS (sUN "Nothing") ["Maybe", "Prelude"]))
1815− (Var (reflm "TT"))
1816− | n == tacN "prim__LookupTy", [n] <- args
1866+ | n == tacN "Prim__Guess", [] <- args
1867+ = do g <- get_guess
1868+ fmap fst . checkClosed $ reflect g
1869+ | n == tacN "Prim__LookupTy", [n] <- args
18171870 = do n' <- reifyTTName n
18181871 ctxt <- get_context
1819− let getNameTypeAndType = \case Function ty _ -> (Ref, ty)
1820− TyDecl nt ty -> (nt, ty)
1821− Operator ty _ _ -> (Ref, ty)
1872+ let getNameTypeAndType = \case Function ty _ -> (Ref, ty)
1873+ TyDecl nt ty -> (nt, ty)
1874+ Operator ty _ _ -> (Ref, ty)
18221875 CaseOp _ ty _ _ _ _ -> (Ref, ty)
18231876 -- Idris tuples nest to the right
18241877 reflectTriple (x, y, z) =
@@ -1835,46 +1888,75 @@ runElabAction ist fc env tm ns = do tm' <- eval tm
18351888 , raw_apply (Var pairTy) [ Var (reflm "NameType")
18361889 , Var (reflm "TT")]])
18371890 defs
1838− | n == tacN "prim__LookupDatatype", [name] <- args
1891+ | n == tacN "Prim__LookupDatatype", [name] <- args
18391892 = do n' <- reifyTTName name
18401893 datatypes <- get_datatypes
18411894 ctxt <- get_context
18421895 fmap fst . checkClosed $
18431896 rawList (Var (tacN "Datatype"))
18441897 (map reflectDatatype (buildDatatypes ist n'))
1845− | n == tacN "prim__SourceLocation", [] <- args
1898+ | n == tacN "Prim__LookupFunDefn", [name] <- args
1899+ = do n' <- reifyTTName name
1900+ fmap fst . checkClosed $
1901+ rawList (RApp (Var $ tacN "FunDefn") (Var $ reflm "TT"))
1902+ (map reflectFunDefn (buildFunDefns ist n'))
1903+ | n == tacN "Prim__LookupArgs", [name] <- args
1904+ = do n' <- reifyTTName name
1905+ let listTy = Var (sNS (sUN "List") ["List", "Prelude"])
1906+ listFunArg = RApp listTy (Var (tacN "FunArg"))
1907+ -- Idris tuples nest to the right
1908+ let reflectTriple (x, y, z) =
1909+ raw_apply (Var pairCon) [ Var (reflm "TTName")
1910+ , raw_apply (Var pairTy) [listFunArg, Var (reflm "Raw")]
1911+ , x
1912+ , raw_apply (Var pairCon) [listFunArg, Var (reflm "Raw")
1913+ , y, z]]
1914+ let out =
1915+ [ reflectTriple (reflectName fn, reflectList (Var (tacN "FunArg")) (map reflectArg args), reflectRaw res)
1916+ | (fn, pargs) <- lookupCtxtName n' (idris_implicits ist)
1917+ , (args, res) <- getArgs pargs . forget <$>
1918+ maybeToList (lookupTyExact fn (tt_ctxt ist))
1919+ ]
1920+
1921+ fmap fst . checkClosed $
1922+ rawList (raw_apply (Var pairTy) [Var (reflm "TTName")
1923+ , raw_apply (Var pairTy) [ RApp listTy
1924+ (Var (tacN "FunArg"))
1925+ , Var (reflm "Raw")]])
1926+ out
1927+ | n == tacN "Prim__SourceLocation", [] <- args
18461928 = fmap fst . checkClosed $
18471929 reflectFC fc
1848− | n == tacN "prim__Namespace", [] <- args
1930+ | n == tacN "Prim__Namespace", [] <- args
18491931 = fmap fst . checkClosed $
18501932 rawList (RConstant StrType) (map (RConstant . Str) ns)
1851− | n == tacN "prim__Env", [] <- args
1933+ | n == tacN "Prim__Env", [] <- args
18521934 = do env <- get_env
18531935 fmap fst . checkClosed $ reflectEnv env
1854− | n == tacN "prim__Fail", [_a, errs] <- args
1936+ | n == tacN "Prim__Fail", [_a, errs] <- args
18551937 = do errs' <- eval errs
18561938 parts <- reifyReportParts errs'
18571939 lift . tfail $ ReflectionError [parts] (Msg "")
1858− | n == tacN "prim__PureElab", [_a, tm] <- args
1940+ | n == tacN "Prim__PureElab", [_a, tm] <- args
18591941 = return tm
1860− | n == tacN "prim__BindElab", [_a, _b, first, andThen] <- args
1942+ | n == tacN "Prim__BindElab", [_a, _b, first, andThen] <- args
18611943 = do first' <- eval first
18621944 res <- eval =<< runTacTm first'
18631945 next <- eval (App Complete andThen res)
18641946 runTacTm next
1865− | n == tacN "prim__Try", [_a, first, alt] <- args
1947+ | n == tacN "Prim__Try", [_a, first, alt] <- args
18661948 = do first' <- eval first
18671949 alt' <- eval alt
18681950 try' (runTacTm first') (runTacTm alt') True
1869− | n == tacN "prim__Fill", [raw] <- args
1951+ | n == tacN "Prim__Fill", [raw] <- args
18701952 = do raw' <- reifyRaw =<< eval raw
1871− fill raw'
1953+ apply raw' []
18721954 returnUnit
1873− | n == tacN "prim__Apply" || n == tacN "prim__MatchApply"
1955+ | n == tacN "Prim__Apply" || n == tacN "Prim__MatchApply"
18741956 , [raw, argSpec] <- args
18751957 = do raw' <- reifyRaw =<< eval raw
1876− argSpec' <- reifyList (reifyPair reifyBool reifyInt) argSpec
1877− let op = if n == tacN "prim__Apply"
1958+ argSpec' <- map (\b -> (b, 0)) <$> reifyList reifyBool argSpec
1959+ let op = if n == tacN "Prim__Apply"
18781960 then apply
18791961 else match_apply
18801962 ns <- op raw' argSpec'
@@ -1884,91 +1966,88 @@ runElabAction ist fc env tm ns = do tm' <- eval tm
18841966 (reflectName n1, reflectName n2)
18851967 | (n1, n2) <- ns
18861968 ]
1887− | n == tacN "prim__Gensym", [hint] <- args
1969+ | n == tacN "Prim__Gensym", [hint] <- args
18881970 = do hintStr <- eval hint
18891971 case hintStr of
18901972 Constant (Str h) -> do
18911973 n <- getNameFrom (sMN 0 h)
18921974 fmap fst $ get_type_val (reflectName n)
18931975 _ -> fail "no hint"
1894− | n == tacN "prim__Claim", [n, ty] <- args
1976+ | n == tacN "Prim__Claim", [n, ty] <- args
18951977 = do n' <- reifyTTName n
18961978 ty' <- reifyRaw ty
18971979 claim n' ty'
18981980 returnUnit
1899− | n == tacN "prim__Check", [raw] <- args
1900− = do raw' <- reifyRaw =<< eval raw
1981+ | n == tacN "Prim__Check", [env', raw] <- args
1982+ = do env <- reifyEnv env'
1983+ raw' <- reifyRaw =<< eval raw
19011984 ctxt <- get_context
1902− env <- get_env
19031985 (tm, ty) <- lift $ check ctxt env raw'
19041986 fmap fst . checkClosed $
19051987 rawPair (Var (reflm "TT"), Var (reflm "TT"))
19061988 (reflect tm, reflect ty)
1907− | n == tacN "prim__Forget", [tt] <- args
1908− = do tt' <- reifyTT tt
1909− fmap fst . checkClosed . reflectRaw $ forget tt'
1910− | n == tacN "prim__Attack", [] <- args
1989+ | n == tacN "Prim__Attack", [] <- args
19111990 = do attack
19121991 returnUnit
1913− | n == tacN "prim__Rewrite", [rule] <- args
1992+ | n == tacN "Prim__Rewrite", [rule] <- args
19141993 = do r <- reifyRaw rule
19151994 rewrite r
19161995 returnUnit
1917− | n == tacN "prim__Focus", [what] <- args
1996+ | n == tacN "Prim__Focus", [what] <- args
19181997 = do n' <- reifyTTName what
19191998 hs <- get_holes
19201999 if elem n' hs
19212000 then focus n' >> returnUnit
19222001 else lift . tfail . Msg $ "The name " ++ show n' ++ " does not denote a hole"
1923− | n == tacN "prim__Unfocus", [what] <- args
2002+ | n == tacN "Prim__Unfocus", [what] <- args
19242003 = do n' <- reifyTTName what
19252004 movelast n'
19262005 returnUnit
1927− | n == tacN "prim__Intro", [mn] <- args
2006+ | n == tacN "Prim__Intro", [mn] <- args
19282007 = do n <- case fromTTMaybe mn of
19292008 Nothing -> return Nothing
19302009 Just name -> fmap Just $ reifyTTName name
19312010 intro n
19322011 returnUnit
1933− | n == tacN "prim__Forall", [n, ty] <- args
2012+ | n == tacN "Prim__Forall", [n, ty] <- args
19342013 = do n' <- reifyTTName n
19352014 ty' <- reifyRaw ty
19362015 forall n' Nothing ty'
19372016 returnUnit
1938− | n == tacN "prim__PatVar", [n] <- args
2017+ | n == tacN "Prim__PatVar", [n] <- args
19392018 = do n' <- reifyTTName n
19402019 patvar' n'
19412020 returnUnit
1942− | n == tacN "prim__PatBind", [n] <- args
2021+ | n == tacN "Prim__PatBind", [n] <- args
19432022 = do n' <- reifyTTName n
19442023 patbind n'
19452024 returnUnit
1946− | n == tacN "prim__LetBind", [n, ty, tm] <- args
2025+ | n == tacN "Prim__LetBind", [n, ty, tm] <- args
19472026 = do n' <- reifyTTName n
19482027 ty' <- reifyRaw ty
19492028 tm' <- reifyRaw tm
19502029 letbind n' ty' tm'
19512030 returnUnit
1952− | n == tacN "prim__Compute", [] <- args
2031+ | n == tacN "Prim__Compute", [] <- args
19532032 = do compute ; returnUnit
1954− | n == tacN "prim__Normalise", [env, tm] <- args
2033+ | n == tacN "Prim__Normalise", [env, tm] <- args
19552034 = do env' <- reifyEnv env
19562035 tm' <- reifyTT tm
19572036 ctxt <- get_context
19582037 let out = normaliseAll ctxt env' (finalise tm')
19592038 fmap fst . checkClosed $ reflect out
1960− | n == tacN "prim__Whnf", [tm] <- args
2039+ | n == tacN "Prim__Whnf", [tm] <- args
19612040 = do tm' <- reifyTT tm
19622041 ctxt <- get_context
19632042 fmap fst . checkClosed . reflect $ whnf ctxt tm'
1964− | n == tacN "prim__Converts", [env, tm1, tm2] <- args
2043+ | n == tacN "Prim__Converts", [env, tm1, tm2] <- args
19652044 = do env' <- reifyEnv env
19662045 tm1' <- reifyTT tm1
19672046 tm2' <- reifyTT tm2
19682047 ctxt <- get_context
19692048 lift $ converts ctxt env' tm1' tm2'
19702049 returnUnit
1971− | n == tacN "prim__DeclareType", [decl] <- args
2050+ | n == tacN "Prim__DeclareType", [decl] <- args
19722051 = do (RDeclare n args res) <- reifyTyDecl decl
19732052 ctxt <- get_context
19742053 let mkPi arg res = RBind (argName arg)
@@ -1990,24 +2069,28 @@ runElabAction ist fc env tm ns = do tm' <- eval tm
19902069 set_context ctxt'
19912070 updateAux $ \e -> e { new_tyDecls = (RTyDeclInstrs n fc (map rFunArgToPArg args) checked) :
19922071 new_tyDecls e }
1993− aux <- getAux
19942072 returnUnit
1995− | n == tacN "prim__DefineFunction", [decl] <- args
2073+ | n == tacN "Prim__DefineFunction", [decl] <- args
19962074 = do defn <- reifyFunDefn decl
19972075 defineFunction defn
19982076 returnUnit
1999− | n == tacN "prim__AddInstance", [cls, inst] <- args
2077+ | n == tacN "Prim__AddInstance", [cls, inst] <- args
20002078 = do className <- reifyTTName cls
20012079 instName <- reifyTTName inst
20022080 updateAux $ \e -> e { new_tyDecls = RAddInstance className instName :
20032081 new_tyDecls e}
20042082 returnUnit
2005− | n == tacN "prim__ResolveTC", [fn] <- args
2083+ | n == tacN "Prim__IsTCName", [n] <- args
2084+ = do n' <- reifyTTName n
2085+ case lookupCtxtExact n' (idris_classes ist) of
2086+ Just _ -> fmap fst . checkClosed $ Var (sNS (sUN "True") ["Bool", "Prelude"])
2087+ Nothing -> fmap fst . checkClosed $ Var (sNS (sUN "False") ["Bool", "Prelude"])
2088+ | n == tacN "Prim__ResolveTC", [fn] <- args
20062089 = do g <- goal
20072090 fn <- reifyTTName fn
20082091 resolveTC' False True 100 g fn ist
20092092 returnUnit
2010− | n == tacN "prim__Search", [depth, hints] <- args
2093+ | n == tacN "Prim__Search", [depth, hints] <- args
20112094 = do d <- eval depth
20122095 hints' <- eval hints
20132096 case (d, unList hints') of
@@ -2020,7 +2103,7 @@ runElabAction ist fc env tm ns = do tm' <- eval tm
20202103 (Constant (I _), Nothing ) ->
20212104 lift . tfail . InternalMsg $ "Not a list: " ++ show hints'
20222105 (_, _) -> lift . tfail . InternalMsg $ "Can't reify int " ++ show d
2023− | n == tacN "prim__RecursiveElab", [goal, script] <- args
2106+ | n == tacN "Prim__RecursiveElab", [goal, script] <- args
20242107 = do goal' <- reifyRaw goal
20252108 ctxt <- get_context
20262109 script <- eval script
@@ -2030,22 +2113,28 @@ runElabAction ist fc env tm ns = do tm' <- eval tm
20302113 aux <- getAux
20312114 datatypes <- get_datatypes
20322115 env <- get_env
2033− (_, ES (p, aux') _ _) <-
2116+
2117+ (ctxt', ES (p, aux') _ _) <-
20342118 do (ES (current_p, _) _ _) <- get
2035− lift $ runElab aux (runElabAction ist fc [] script ns)
2036− ((newProof recH ctxt datatypes goalTT)
2037− { nextname = nextname current_p})
2119+ lift $ runElab aux
2120+ (do runElabAction ist fc [] script ns
2121+ ctxt' <- get_context
2122+ return ctxt')
2123+ ((newProof recH ctxt datatypes goalTT)
2124+ { nextname = nextname current_p })
2125+ set_context ctxt'
2126+
20382127 let tm_out = getProofTerm (pterm p)
20392128 do (ES (prf, _) s e) <- get
20402129 let p' = prf { nextname = nextname p }
20412130 put (ES (p', aux') s e)
20422131 env' <- get_env
2043− (tm, ty, _) <- lift $ recheck ctxt env (forget tm_out) tm_out
2132+ (tm, ty, _) <- lift $ recheck ctxt' env (forget tm_out) tm_out
20442133 let (tm', ty') = (reflect tm, reflect ty)
20452134 fmap fst . checkClosed $
20462135 rawPair (Var $ reflm "TT", Var $ reflm "TT")
20472136 (tm', ty')
2048− | n == tacN "prim__Metavar", [n] <- args
2137+ | n == tacN "Prim__Metavar", [n] <- args
20492138 = do n' <- reifyTTName n
20502139 ctxt <- get_context
20512140 ptm <- get_term
@@ -2056,10 +2145,10 @@ runElabAction ist fc env tm ns = do tm' <- eval tm
20562145 defer unique_used mvn
20572146 solve
20582147 returnUnit
2059− | n == tacN "prim__Fixity", [op'] <- args
2148+ | n == tacN "Prim__Fixity", [op'] <- args
20602149 = do opTm <- eval op'
20612150 case opTm of
2062− Constant (Str op) ->
2151+ Constant (Str op) ->
20632152 let opChars = ":!#$%&*+./<=>?@\\^|-~"
20642153 invalidOperators = [":", "=>", "->", "<-", "=", "?=", "|", "**", "==>", "\\", "%", "~", "?", "!"]
20652154 fixities = idris_infixes ist
@@ -2070,7 +2159,7 @@ runElabAction ist fc env tm ns = do tm' <- eval tm
20702159 [f] -> fmap fst . checkClosed $ reflectFixity f
20712160 many -> lift . tfail . InternalMsg $ "Ambiguous fixity for '" ++ op ++ "'! Found " ++ show many
20722161 _ -> lift . tfail . Msg $ "Not a constant string for an operator name: " ++ show opTm
2073− | n == tacN "prim__Debug", [ty, msg] <- args
2162+ | n == tacN "Prim__Debug", [ty, msg] <- args
20742163 = do msg' <- eval msg
20752164 parts <- reifyReportParts msg
20762165 debugElaborator parts
@@ -2096,7 +2185,7 @@ runTac autoSolve ist perhapsFC fn tac
20962185 bname _ = Nothing
20972186 runT (Intro xs) = mapM_ (\x -> do attack; intro (Just x)) xs
20982187 runT Intros = do g <- goal
2099− attack;
2188+ attack;
21002189 intro (bname g)
21012190 try' (runT Intros)
21022191 (return ()) True
@@ -2341,18 +2430,18 @@ elaboratingArgErr ((f,x):during) err = fromMaybe err (rewrite err)
23412430withErrorReflection :: Idris a -> Idris a
23422431withErrorReflection x = idrisCatch x (\ e -> handle e >>= ierror)
23432432 where handle :: Err -> Idris Err
2344− handle e@(ReflectionError _ _) = do logLvl 3 "Skipping reflection of error reflection result"
2433+ handle e@(ReflectionError _ _) = do logElab 3 "Skipping reflection of error reflection result"
23452434 return e -- Don't do meta-reflection of errors
2346− handle e@(ReflectionFailed _ _) = do logLvl 3 "Skipping reflection of reflection failure"
2435+ handle e@(ReflectionFailed _ _) = do logElab 3 "Skipping reflection of reflection failure"
23472436 return e
23482437 -- At and Elaborating are just plumbing - error reflection shouldn't rewrite them
2349− handle e@(At fc err) = do logLvl 3 "Reflecting body of At"
2438+ handle e@(At fc err) = do logElab 3 "Reflecting body of At"
23502439 err' <- handle err
23512440 return (At fc err')
2352− handle e@(Elaborating what n err) = do logLvl 3 "Reflecting body of Elaborating"
2353− err' <- handle err
2354− return (Elaborating what n err')
2355− handle e@(ElaboratingArg f a prev err) = do logLvl 3 "Reflecting body of ElaboratingArg"
2441+ handle e@(Elaborating what n ty err) = do logElab 3 "Reflecting body of Elaborating"
2442+ err' <- handle err
2443+ return (Elaborating what n ty err')
2444+ handle e@(ElaboratingArg f a prev err) = do logElab 3 "Reflecting body of ElaboratingArg"
23562445 hs <- getFnHandlers f a
23572446 err' <- if null hs
23582447 then handle err
@@ -2362,8 +2451,8 @@ withErrorReflection x = idrisCatch x (\ e -> handle e >>= ierror)
23622451 handle (ProofSearchFail e) = handle e
23632452 -- TODO: argument-specific error handlers go here for ElaboratingArg
23642453 handle e = do ist <- getIState
2365− logLvl 2 "Starting error reflection"
2366− logLvl 5 (show e)
2454+ logElab 2 "Starting error reflection"
2455+ logElab 5 (show e)
23672456 let handlers = idris_errorhandlers ist
23682457 applyHandlers e handlers
23692458 getFnHandlers :: Name -> Name -> Idris [Name]
@@ -2377,7 +2466,7 @@ withErrorReflection x = idrisCatch x (\ e -> handle e >>= ierror)
23772466 applyHandlers e handlers =
23782467 do ist <- getIState
23792468 let err = fmap (errReverse ist) e
2380− logLvl 3 $ "Using reflection handlers " ++
2469+ logElab 3 $ "Using reflection handlers " ++
23812470 concat (intersperse ", " (map show handlers))
23822471 let reports = map (\n -> RApp (Var n) (reflectErr err)) handlers
23832472
@@ -2389,7 +2478,7 @@ withErrorReflection x = idrisCatch x (\ e -> handle e >>= ierror)
23892478 -- Normalize error handler terms to produce the new messages
23902479 ctxt <- getContext
23912480 let results = map (normalise ctxt []) (map fst handlers)
2392− logLvl 3 $ "New error message info: " ++ concat (intersperse " and " (map show results))
2481+ logElab 3 $ "New error message info: " ++ concat (intersperse " and " (map show results))
23932482
23942483 -- For each handler term output, either discard it if it is Nothing or reify it the Haskell equivalent
23952484 let errorpartsTT = mapMaybe unList (mapMaybe fromTTMaybe results)
@@ -2410,8 +2499,8 @@ processTacticDecls info steps =
24102499 -- establish metavars that later function bodies resolve.
24112500 forM_ (reverse steps) $ \case
24122501 RTyDeclInstrs n fc impls ty ->
2413− do logLvl 3 $ "Declaration from tactics: " ++ show n ++ " : " ++ show ty
2414− logLvl 3 $ " It has impls " ++ show impls
2502+ do logElab 3 $ "Declaration from tactics: " ++ show n ++ " : " ++ show ty
2503+ logElab 3 $ " It has impls " ++ show impls
24152504 updateIState $ \i -> i { idris_implicits =
24162505 addDef n impls (idris_implicits i) }
24172506 addIBC (IBCImp n)
@@ -2428,13 +2517,13 @@ processTacticDecls info steps =
24282517 in addDeferred ds'
24292518 _ -> return ()
24302519 RAddInstance className instName ->
2431− do -- The type class resolution machinery relies on a special
2432− logLvl 2 $ "Adding elab script instance " ++ show instName ++
2520+ do -- The type class resolution machinery relies on a special
2521+ logElab 2 $ "Adding elab script instance " ++ show instName ++
24332522 " for " ++ show className
24342523 addInstance False True className instName
24352524 addIBC (IBCInstance False True className instName)
24362525 RClausesInstrs n cs ->
2437− do logLvl 3 $ "Pattern-matching definition from tactics: " ++ show n
2526+ do logElab 3 $ "Pattern-matching definition from tactics: " ++ show n
24382527 solveDeferred n
24392528 let lhss = map (\(_, lhs, _) -> lhs) cs
24402529 let fc = fileFC "elab_reflected"
@@ -2464,7 +2553,7 @@ processTacticDecls info steps =
24642553 calls = findCalls sc' scargs
24652554 used = findUsedArgs sc' scargs'
24662555 cg = CGInfo scargs' calls [] used []
2467− in do logLvl 2 $ "Called names in reflected elab: " ++ show cg
2556+ in do logElab 2 $ "Called names in reflected elab: " ++ show cg
24682557 addToCG n cg
24692558 addToCalledG n (nub (map fst calls))
24702559 addIBC $ IBCCG n
@@ -2493,7 +2582,8 @@ processTacticDecls info steps =
24932582 let fc = fileFC "elab_reflected_totality"
24942583 let tcgen = False -- TODO: later we may support dictionary generation
24952584 case elaborate ctxt (idris_datatypes ist) (sMN 0 "refPatLHS") infP initEState
2496− (erun fc (buildTC ist info ELHS [] fname (infTerm lhs))) of
2585+ (erun fc (buildTC ist info ELHS [] fname (allNamesIn lhs_in)
2586+ (infTerm lhs))) of
24972587 OK (ElabResult lhs' _ _ _ _ _, _) ->
24982588 do -- not recursively calling here, because we don't
24992589 -- want to run infinitely many times
src/Idris/Elab/Transform.hs+8−9
@@ -53,11 +53,11 @@ elabTransform info fc safe lhs_in@(PApp _ (PRef _ _ tf) _) rhs_in
5353 = do ctxt <- getContext
5454 i <- getIState
5555 let lhs = addImplPat i lhs_in
56− logLvl 5 ("Transform LHS input: " ++ showTmImpls lhs)
56+ logElab 5 ("Transform LHS input: " ++ showTmImpls lhs)
5757 (ElabResult lhs' dlhs [] ctxt' newDecls highlights, _) <-
5858 tclift $ elaborate ctxt (idris_datatypes i) (sMN 0 "transLHS") infP initEState
5959 (erun fc (buildTC i info ETransLHS [] (sUN "transform")
60− (infTerm lhs)))
60+ (allNamesIn lhs_in) (infTerm lhs)))
6161 setContext ctxt'
6262 processTacticDecls info newDecls
6363 sendHighlighting highlights
@@ -67,11 +67,11 @@ elabTransform info fc safe lhs_in@(PApp _ (PRef _ _ tf) _) rhs_in
6767
6868 (clhs_tm_in, clhs_ty) <- recheckC_borrowing False False [] fc id [] lhs_tm
6969 let clhs_tm = renamepats pnames clhs_tm_in
70− logLvl 3 ("Transform LHS " ++ show clhs_tm)
71− logLvl 3 ("Transform type " ++ show clhs_ty)
72−
70+ logElab 3 ("Transform LHS " ++ show clhs_tm)
71+ logElab 3 ("Transform type " ++ show clhs_ty)
72+
7373 let rhs = addImplBound i (map fst newargs) rhs_in
74− logLvl 5 ("Transform RHS input: " ++ showTmImpls rhs)
74+ logElab 5 ("Transform RHS input: " ++ showTmImpls rhs)
7575
7676 ((rhs', defer, ctxt', newDecls), _) <-
7777 tclift $ elaborate ctxt (idris_datatypes i) (sMN 0 "transRHS") clhs_ty initEState
@@ -88,7 +88,7 @@ elabTransform info fc safe lhs_in@(PApp _ (PRef _ _ tf) _) rhs_in
8888
8989 (crhs_tm_in, crhs_ty) <- recheckC_borrowing False False [] fc id [] rhs'
9090 let crhs_tm = renamepats pnames crhs_tm_in
91− logLvl 3 ("Transform RHS " ++ show crhs_tm)
91+ logElab 3 ("Transform RHS " ++ show crhs_tm)
9292
9393 -- Types must always convert
9494 case converts ctxt [] clhs_ty crhs_ty of
@@ -118,6 +118,5 @@ elabTransform info fc safe lhs_in@(PApp _ (PRef _ _ tf) _) rhs_in
118118 -- with any other names when applying rules, so rename here.
119119 pnames = map (\i -> sMN i ("tvar" ++ show i)) [0..]
120120
121−elabTransform info fc safe lhs_in rhs_in
121+elabTransform info fc safe lhs_in rhs_in
122122 = ierror (At fc (Msg "Invalid transformation rule (must be function application)"))
123−
src/Idris/Elab/Type.hs+23−25
@@ -1,5 +1,5 @@
11{-# LANGUAGE PatternGuards #-}
2−module Idris.Elab.Type (buildType, elabType, elabType',
2+module Idris.Elab.Type (buildType, elabType, elabType',
33 elabPostulate, elabExtern) where
44
55import Idris.AbsSyntax
@@ -52,31 +52,31 @@ import Data.List.Split (splitOn)
5252
5353import Util.Pretty(pretty, text)
5454
55−buildType :: ElabInfo -> SyntaxInfo -> FC -> FnOpts -> Name -> PTerm ->
55+buildType :: ElabInfo -> SyntaxInfo -> FC -> FnOpts -> Name -> PTerm ->
5656 Idris (Type, Type, PTerm, [(Int, Name)])
5757buildType info syn fc opts n ty' = do
5858 ctxt <- getContext
5959 i <- getIState
6060
61− logLvl 2 $ show n ++ " pre-type " ++ showTmImpls ty' ++ show (no_imp syn)
61+ logElab 2 $ show n ++ " pre-type " ++ showTmImpls ty' ++ show (no_imp syn)
6262 ty' <- addUsingConstraints syn fc ty'
6363 ty' <- addUsingImpls syn n fc ty'
6464 let ty = addImpl (imp_methods syn) i ty'
6565
66− logLvl 5 $ show n ++ " type pre-addimpl " ++ showTmImpls ty'
67− logLvl 5 $ show "with methods " ++ show (imp_methods syn)
68− logLvl 2 $ show n ++ " type " ++ show (using syn) ++ "\n" ++ showTmImpls ty
66+ logElab 5 $ show n ++ " type pre-addimpl " ++ showTmImpls ty'
67+ logElab 5 $ show "with methods " ++ show (imp_methods syn)
68+ logElab 2 $ show n ++ " type " ++ show (using syn) ++ "\n" ++ showTmImpls ty
6969
7070 (ElabResult tyT' defer is ctxt' newDecls highlights, log) <-
7171 tclift $ elaborate ctxt (idris_datatypes i) n (TType (UVal 0)) initEState
72− (errAt "type of " n (erun fc (build i info ETyDecl [] n ty)))
72+ (errAt "type of " n Nothing (erun fc (build i info ETyDecl [] n ty)))
7373 setContext ctxt'
7474 processTacticDecls info newDecls
7575 sendHighlighting highlights
7676
7777 let tyT = patToImp tyT'
7878
79− logLvl 3 $ show ty ++ "\nElaborated: " ++ show tyT'
79+ logElab 3 $ show ty ++ "\nElaborated: " ++ show tyT'
8080
8181 ds <- checkAddDef True False fc iderr defer
8282 -- if the type is not complete, note that we'll need to infer
@@ -86,20 +86,20 @@ buildType info syn fc opts n ty' = do
8686
8787 mapM_ (elabCaseBlock info opts) is
8888 ctxt <- getContext
89− logLvl 5 $ "Rechecking"
90− logLvl 6 $ show tyT
91− logLvl 10 $ "Elaborated to " ++ showEnvDbg [] tyT
89+ logElab 5 $ "Rechecking"
90+ logElab 6 $ show tyT
91+ logElab 10 $ "Elaborated to " ++ showEnvDbg [] tyT
9292 (cty, ckind) <- recheckC fc id [] tyT
9393
9494 -- record the implicit and inaccessible arguments
9595 i <- getIState
9696 let (inaccData, impls) = unzip $ getUnboundImplicits i cty ty
9797 let inacc = inaccessibleImps 0 cty inaccData
98− logLvl 3 $ show n ++ ": inaccessible arguments: " ++ show inacc ++
98+ logElab 3 $ show n ++ ": inaccessible arguments: " ++ show inacc ++
9999 " from " ++ show cty ++ "\n" ++ showTmImpls ty
100100
101101 putIState $ i { idris_implicits = addDef n impls (idris_implicits i) }
102− logLvl 3 ("Implicit " ++ show n ++ " " ++ show impls)
102+ logElab 3 ("Implicit " ++ show n ++ " " ++ show impls)
103103 addIBC (IBCImp n)
104104
105105 when (Constructor `notElem` opts) $ do
@@ -114,7 +114,7 @@ buildType info syn fc opts n ty' = do
114114 patToImp (Bind n b sc) = Bind n b (patToImp sc)
115115 patToImp t = t
116116
117− param_pos i ns (Bind n (Pi _ t _) sc)
117+ param_pos i ns (Bind n (Pi _ t _) sc)
118118 | n `elem` ns = i : param_pos (i + 1) ns sc
119119 | otherwise = param_pos (i + 1) ns sc
120120 param_pos i ns t = []
@@ -140,16 +140,17 @@ elabType' norm info syn doc argDocs fc opts n nfc ty' = {- let ty' = piBind (par
140140 let nty = cty -- normalise ctxt [] cty
141141 -- if the return type is something coinductive, freeze the definition
142142 ctxt <- getContext
143− logLvl 2 $ "Rechecked to " ++ show nty
143+ logElab 2 $ "Rechecked to " ++ show nty
144144 let nty' = normalise ctxt [] nty
145− logLvl 2 $ "Rechecked to " ++ show nty'
145+ logElab 2 $ "Rechecked to " ++ show nty'
146146
147− -- Add normalised type to internals
147+ -- Add function name to internals (used for making :addclause know
148+ -- the name unambiguously)
148149 i <- getIState
149150 rep <- useREPL
150151 when rep $ do
151− addInternalApp (fc_fname fc) (fst . fc_start $ fc) ty' -- (mergeTy ty' (delab i nty')) -- TODO: Should use span instead of line and filename?
152− addIBC (IBCLineApp (fc_fname fc) (fst . fc_start $ fc) ty') -- (mergeTy ty' (delab i nty')))
152+ addInternalApp (fc_fname fc) (fst . fc_start $ fc) (PTyped (PRef fc [] n) ty') -- (mergeTy ty' (delab i nty')) -- TODO: Should use span instead of line and filename?
153+ addIBC (IBCLineApp (fc_fname fc) (fst . fc_start $ fc) (PTyped (PRef fc [] n) ty')) -- (mergeTy ty' (delab i nty')))
153154
154155 let (fam, _) = unApply (getRetTy nty')
155156 let corec = case fam of
@@ -157,7 +158,7 @@ elabType' norm info syn doc argDocs fc opts n nfc ty' = {- let ty' = piBind (par
157158 [TI _ True _ _ _] -> True
158159 _ -> False
159160 _ -> False
160− -- Productivity checking now via checking for guarded 'Delay'
161+ -- Productivity checking now via checking for guarded 'Delay'
161162 let opts' = opts -- if corec then (Coinductive : opts) else opts
162163 let usety = if norm then nty' else nty
163164 ds <- checkDef fc iderr [(n, (-1, Nothing, usety, []))]
@@ -176,7 +177,7 @@ elabType' norm info syn doc argDocs fc opts n nfc ty' = {- let ty' = piBind (par
176177 addIBC (IBCOpt n)
177178 when (Implicit `elem` opts') $ do addCoercion n
178179 addIBC (IBCCoercion n)
179− when (AutoHint `elem` opts') $
180+ when (AutoHint `elem` opts') $
180181 case fam of
181182 P _ tyn _ -> do addAutoHint tyn n
182183 addIBC (IBCAutoHint tyn n)
@@ -200,7 +201,7 @@ elabType' norm info syn doc argDocs fc opts n nfc ty' = {- let ty' = piBind (par
200201 sendHighlighting [(nfc, AnnName n Nothing Nothing Nothing)]
201202 -- if it's an export list type, make a note of it
202203 case (unApply usety) of
203− (P _ ut _, _)
204+ (P _ ut _, _)
204205 | ut == ffiexport -> do addIBC (IBCExport n)
205206 addExport n
206207 _ -> return ()
@@ -255,6 +256,3 @@ elabExtern info syn doc fc nfc opts n ty = do
255256
256257 -- remove it from the deferred definitions list
257258 solveDeferred n
258−
259−
260−
src/Idris/Elab/Utils.hs+32−19
@@ -6,12 +6,15 @@ import Idris.Error
66import Idris.DeepSeq
77import Idris.Delaborate
88import Idris.Docstrings
9+import Idris.Output
910
1011import Idris.Core.TT
1112import Idris.Core.Elaborate hiding (Tactic(..))
1213import Idris.Core.Evaluate
1314import Idris.Core.Typecheck
1415
16+import Util.Pretty
17+
1518import Control.Applicative hiding (Const)
1619import Control.Monad.State
1720import Control.Monad
@@ -34,10 +37,22 @@ recheckC_borrowing uniq_check addConstrs bs fc mkerr env t
3437 (tm, ty, cs) <- tclift $ case recheck_borrowing uniq_check bs ctxt env t' t of
3538 Error e -> tfail (At fc (mkerr e))
3639 OK x -> return x
37− logLvl 6 $ "CONSTRAINTS ADDED: " ++ show (tm, ty, cs)
40+ logElab 6 $ "CONSTRAINTS ADDED: " ++ show (tm, ty, cs)
3841 when addConstrs $ addConstraints fc cs
42+ mapM_ (checkDeprecated fc) (allTTNames tm)
43+ mapM_ (checkDeprecated fc) (allTTNames ty)
3944 return (tm, ty)
4045
46+checkDeprecated :: FC -> Name -> Idris ()
47+checkDeprecated fc n
48+ = do r <- getDeprecated n
49+ case r of
50+ Nothing -> return ()
51+ Just r -> do iWarn fc $ text "Use of deprecated name " <> annName n
52+ <> case r of
53+ "" -> Util.Pretty.empty
54+ _ -> line <> text r
55+
4156iderr :: Name -> Err -> Err
4257iderr _ e = e
4358
@@ -49,8 +64,9 @@ checkAddDef :: Bool -> Bool -> FC -> (Name -> Err -> Err)
4964 -> [(Name, (Int, Maybe Name, Type, [Name]))]
5065 -> Idris [(Name, (Int, Maybe Name, Type, [Name]))]
5166checkAddDef add toplvl fc mkerr [] = return []
52−checkAddDef add toplvl fc mkerr ((n, (i, top, t, psns)) : ns)
67+checkAddDef add toplvl fc mkerr ((n, (i, top, t, psns)) : ns)
5368 = do ctxt <- getContext
69+ logElab 5 $ "Rechecking deferred name " ++ show (n, t)
5470 (t', _) <- recheckC fc (mkerr n) [] t
5571 when add $ do addDeferred [(n, (i, top, t, psns, toplvl))]
5672 addIBC (IBCDef n)
@@ -77,7 +93,7 @@ inaccessibleArgs _ _ = []
7793elabCaseBlock :: ElabInfo -> FnOpts -> PDecl -> Idris ()
7894elabCaseBlock info opts d@(PClauses f o n ps)
7995 = do addIBC (IBCDef n)
80− logLvl 5 $ "CASE BLOCK: " ++ show (n, d)
96+ logElab 5 $ "CASE BLOCK: " ++ show (n, d)
8197 let opts' = nub (o ++ opts)
8298 -- propagate totality assertion to the new definitions
8399 when (AssertTotal `elem` opts) $ setFlags n [AssertTotal]
@@ -88,16 +104,16 @@ elabCaseBlock info opts d@(PClauses f o n ps)
88104-- they are the same!)
89105checkInferred :: FC -> PTerm -> PTerm -> Idris ()
90106checkInferred fc inf user =
91− do logLvl 6 $ "Checked to\n" ++ showTmImpls inf ++ "\n\nFROM\n\n" ++
107+ do logElab 6 $ "Checked to\n" ++ showTmImpls inf ++ "\n\nFROM\n\n" ++
92108 showTmImpls user
93− logLvl 10 $ "Checking match"
109+ logElab 10 $ "Checking match"
94110 i <- getIState
95111 tclift $ case matchClause' True i user inf of
96112 _ -> return ()
97113-- Left (x, y) -> tfail $ At fc
98114-- (Msg $ "The type-checked term and given term do not match: "
99115-- ++ show x ++ " and " ++ show y)
100− logLvl 10 $ "Checked match"
116+ logElab 10 $ "Checked match"
101117-- ++ "\n" ++ showImp True inf ++ "\n" ++ showImp True user)
102118
103119-- | Return whether inferred term is different from given term
@@ -105,7 +121,7 @@ checkInferred fc inf user =
105121inferredDiff :: FC -> PTerm -> PTerm -> Idris Bool
106122inferredDiff fc inf user =
107123 do i <- getIState
108− logLvl 6 $ "Checked to\n" ++ showTmImpls inf ++ "\n" ++
124+ logElab 6 $ "Checked to\n" ++ showTmImpls inf ++ "\n" ++
109125 showTmImpls user
110126 tclift $ case matchClause' True i user inf of
111127 Right vs -> return False
@@ -136,7 +152,7 @@ decorateid decorate (PClauses f o n cs)
136152
137153-- if 't' is a type class application, assume its arguments are injective
138154pbinds :: IState -> Term -> ElabD ()
139−pbinds i (Bind n (PVar t) sc)
155+pbinds i (Bind n (PVar t) sc)
140156 = do attack; patbind n
141157 env <- get_env
142158 case unApply (normalise (tt_ctxt i) env t) of
@@ -191,14 +207,14 @@ getFlexInType i env ps tm@(App _ f a)
191207 | (P nt tn _, args) <- unApply tm, nt /= Bound
192208 = case lookupCtxtExact tn (idris_datatypes i) of
193209 Just t -> nub $ paramNames args env [x | x <- [0..length args],
194− not (x `elem` param_pos t)]
210+ not (x `elem` param_pos t)]
195211 ++ getFlexInType i env ps f ++
196212 getFlexInType i env ps a
197213 Nothing -> let ppos = case lookupCtxtExact tn (idris_fninfo i) of
198214 Just fi -> fn_params fi
199215 Nothing -> []
200216 in nub $ paramNames args env [x | x <- [0..length args],
201− not (x `elem` ppos)]
217+ not (x `elem` ppos)]
202218 ++ getFlexInType i env ps f ++
203219 getFlexInType i env ps a
204220 | otherwise = nub $ getFlexInType i env ps f ++
@@ -212,7 +228,7 @@ getParamsInType i env ps t = let fix = getFixedInType i env ps t
212228 flex = getFlexInType i env fix t in
213229 [x | x <- fix, not (x `elem` flex)]
214230
215−getTCinj i (Bind n (Pi _ t _) sc)
231+getTCinj i (Bind n (Pi _ t _) sc)
216232 = getTCinj i t ++ getTCinj i (instantiate (P Bound n t) sc)
217233getTCinj i ap@(App _ f a)
218234 | (P _ n _, args) <- unApply ap,
@@ -242,7 +258,7 @@ paramNames args env (p : ps)
242258getUniqueUsed :: Context -> Term -> [Name]
243259getUniqueUsed ctxt tm = execState (getUniq [] [] tm) []
244260 where
245− getUniq :: Env -> [(Name, Bool)] -> Term -> State [Name] ()
261+ getUniq :: Env -> [(Name, Bool)] -> Term -> State [Name] ()
246262 getUniq env us (Bind n b sc)
247263 = let uniq = case check ctxt env (forgetEnv (map fst env) (binderTy b)) of
248264 OK (_, UType UniqueType) -> True
@@ -269,9 +285,9 @@ getUniqueUsed ctxt tm = execState (getUniq [] [] tm) []
269285-- In a functional application, return the names which are used
270286-- directly in a static position
271287getStaticNames :: IState -> Term -> [Name]
272−getStaticNames ist (Bind n (PVar _) sc)
288+getStaticNames ist (Bind n (PVar _) sc)
273289 = getStaticNames ist (instantiate (P Bound n Erased) sc)
274−getStaticNames ist tm
290+getStaticNames ist tm
275291 | (P _ fn _, args) <- unApply tm
276292 = case lookupCtxtExact fn (idris_statics ist) of
277293 Just stpos -> getStatics args stpos
@@ -289,15 +305,12 @@ getStatics ns (Bind n (Pi _ _ _) t)
289305getStatics _ _ = []
290306
291307mkStatic :: [Name] -> PDecl -> PDecl
292−mkStatic ns (PTy doc argdocs syn fc o n nfc ty)
308+mkStatic ns (PTy doc argdocs syn fc o n nfc ty)
293309 = PTy doc argdocs syn fc o n nfc (mkStaticTy ns ty)
294310mkStatic ns t = t
295311
296312mkStaticTy :: [Name] -> PTerm -> PTerm
297−mkStaticTy ns (PPi p n fc ty sc)
313+mkStaticTy ns (PPi p n fc ty sc)
298314 | n `elem` ns = PPi (p { pstatic = Static }) n fc ty (mkStaticTy ns sc)
299315 | otherwise = PPi p n fc ty (mkStaticTy ns sc)
300316mkStaticTy ns t = t
301−
302−
303−
src/Idris/Elab/Value.hs+5−4
@@ -1,6 +1,6 @@
11{-# LANGUAGE PatternGuards #-}
22{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
3−module Idris.Elab.Value(elabVal, elabValBind, elabDocTerms,
3+module Idris.Elab.Value(elabVal, elabValBind, elabDocTerms,
44 elabExec, elabREPL) where
55
66import Idris.AbsSyntax
@@ -58,7 +58,7 @@ elabValBind info aspat norm tm_in
5858 = do ctxt <- getContext
5959 i <- getIState
6060 let tm = addImpl [] i tm_in
61− logLvl 10 (showTmImpls tm)
61+ logElab 10 (showTmImpls tm)
6262 -- try:
6363 -- * ordinary elaboration
6464 -- * elaboration as a Type
@@ -80,7 +80,7 @@ elabValBind info aspat norm tm_in
8080 addDeferred def''
8181 mapM_ (elabCaseBlock info []) is
8282
83− logLvl 3 ("Value: " ++ show vtm)
83+ logElab 3 ("Value: " ++ show vtm)
8484 (vtm_in, vty) <- recheckC (fileFC "(input)") id [] vtm
8585
8686 let vtm = if norm then normalise (tt_ctxt i) [] vtm_in
@@ -127,7 +127,8 @@ elabExec fc tm = runtm (PAlternative [] FirstSuccess
127127 printtm tm
128128 ])
129129 where
130− runtm t = PApp fc (PRef fc [] (sUN "run__IO")) [pexp t]
130+ runtm t = PApp fc (PRef fc [] (sUN "run__IO"))
131+ [pimp (sUN "ffi") (PRef fc [] (sUN "FFI_C")) False, pexp t]
131132 printtm t = PApp fc (PRef fc [] (sUN "printLn"))
132133 [pimp (sUN "ffi") (PRef fc [] (sUN "FFI_C")) False, pexp t]
133134
src/Idris/ElabDecls.hs+14−14
@@ -159,25 +159,25 @@ elabDecl' _ info (PSyntax _ p)
159159 = return () -- nothing to elaborate
160160elabDecl' what info (PTy doc argdocs s f o n nfc ty)
161161 | what /= EDefns
162− = do logLvl 1 $ "Elaborating type decl " ++ show n ++ show o
162+ = do logElab 1 $ "Elaborating type decl " ++ show n ++ show o
163163 elabType info s doc argdocs f o n nfc ty
164164 return ()
165165elabDecl' what info (PPostulate b doc s f nfc o n ty)
166166 | what /= EDefns
167− = do logLvl 1 $ "Elaborating postulate " ++ show n ++ show o
168− if b
167+ = do logElab 1 $ "Elaborating postulate " ++ show n ++ show o
168+ if b
169169 then elabExtern info s doc f nfc o n ty
170170 else elabPostulate info s doc f nfc o n ty
171171elabDecl' what info (PData doc argDocs s f co d)
172172 | what /= ETypes
173− = do logLvl 1 $ "Elaborating " ++ show (d_name d)
173+ = do logElab 1 $ "Elaborating " ++ show (d_name d)
174174 elabData info s doc argDocs f co d
175175 | otherwise
176− = do logLvl 1 $ "Elaborating [type of] " ++ show (d_name d)
176+ = do logElab 1 $ "Elaborating [type of] " ++ show (d_name d)
177177 elabData info s doc argDocs f co (PLaterdecl (d_name d) (d_name_fc d) (d_tcon d))
178178elabDecl' what info d@(PClauses f o n ps)
179179 | what /= ETypes
180− = do logLvl 1 $ "Elaborating clause " ++ show n
180+ = do logElab 1 $ "Elaborating clause " ++ show n
181181 i <- getIState -- get the type options too
182182 let o' = case lookupCtxt n (idris_flags i) of
183183 [fs] -> fs
@@ -191,11 +191,11 @@ elabDecl' what info (PMutual f ps)
191191 -- record mutually defined data definitions
192192 let datans = concatMap declared (filter isDataDecl ps)
193193 mapM_ (setMutData datans) datans
194− logLvl 1 $ "Rechecking for positivity " ++ show datans
194+ logElab 1 $ "Rechecking for positivity " ++ show datans
195195 mapM_ (\x -> do setTotality x Unchecked) datans
196196 -- Do totality checking after entire mutual block
197197 i <- get
198− mapM_ (\n -> do logLvl 5 $ "Simplifying " ++ show n
198+ mapM_ (\n -> do logElab 5 $ "Simplifying " ++ show n
199199 ctxt' <- do ctxt <- getContext
200200 tclift $ simplifyCasedef n (getErasureInfo i) ctxt
201201 setContext ctxt')
@@ -216,7 +216,7 @@ elabDecl' what info (PMutual f ps)
216216
217217elabDecl' what info (PParams f ns ps)
218218 = do i <- getIState
219− logLvl 1 $ "Expanding params block with " ++ show ns ++ " decls " ++
219+ logElab 1 $ "Expanding params block with " ++ show ns ++ " decls " ++
220220 show (concatMap tldeclared ps)
221221 let nblock = pblock i
222222 mapM_ (elabDecl' what info) nblock
@@ -240,17 +240,17 @@ elabDecl' what info (PNamespace n nfc ps) =
240240
241241elabDecl' what info (PClass doc s f cs n nfc ps pdocs fds ds cn cd)
242242 | what /= EDefns
243− = do logLvl 1 $ "Elaborating class " ++ show n
243+ = do logElab 1 $ "Elaborating class " ++ show n
244244 elabClass info (s { syn_params = [] }) doc f cs n nfc ps pdocs fds ds cn cd
245245elabDecl' what info (PInstance doc argDocs s f cs n nfc ps t expn ds)
246− = do logLvl 1 $ "Elaborating instance " ++ show n
246+ = do logElab 1 $ "Elaborating instance " ++ show n
247247 elabInstance info s doc argDocs what f cs n nfc ps t expn ds
248248elabDecl' what info (PRecord doc rsyn fc opts name nfc ps pdocs fs cname cdoc csyn)
249− = do logLvl 1 $ "Elaborating record " ++ show name
249+ = do logElab 1 $ "Elaborating record " ++ show name
250250 elabRecord info what doc rsyn fc opts name nfc ps pdocs fs cname cdoc csyn
251251{-
252252 | otherwise
253− = do logLvl 1 $ "Elaborating [type of] " ++ show tyn
253+ = do logElab 1 $ "Elaborating [type of] " ++ show tyn
254254 elabData info s doc [] f [] (PLaterdecl tyn ty)
255255-}
256256elabDecl' _ info (PDSL n dsl)
@@ -261,7 +261,7 @@ elabDecl' what info (PDirective i)
261261 | what /= EDefns = directiveAction i
262262elabDecl' what info (PProvider doc syn fc nfc provWhat n)
263263 | what /= EDefns
264− = do logLvl 1 $ "Elaborating type provider " ++ show n
264+ = do logElab 1 $ "Elaborating type provider " ++ show n
265265 elabProvider doc info syn fc nfc provWhat n
266266elabDecl' what info (PTransform fc safety old new)
267267 = do elabTransform info fc safety old new
src/Idris/Erasure.hs+15−18
@@ -85,10 +85,10 @@ performUsageAnalysis startNames = do
8585 usage = M.toList minUse
8686
8787 -- Print some debug info.
88− logLvl 5 $ "Original deps:\n" ++ unlines (map fmtItem . M.toList $ depMap)
89− logLvl 3 $ "Reachable names:\n" ++ unlines (map (indent . show) . S.toList $ reachableNames)
90− logLvl 4 $ "Minimal usage:\n" ++ fmtUseMap usage
91− logLvl 5 $ "Residual deps:\n" ++ unlines (map fmtItem . M.toList $ residDeps)
88+ logErasure 5 $ "Original deps:\n" ++ unlines (map fmtItem . M.toList $ depMap)
89+ logErasure 3 $ "Reachable names:\n" ++ unlines (map (indent . show) . S.toList $ reachableNames)
90+ logErasure 4 $ "Minimal usage:\n" ++ fmtUseMap usage
91+ logErasure 5 $ "Residual deps:\n" ++ unlines (map fmtItem . M.toList $ residDeps)
9292
9393 -- Check that everything reachable is accessible.
9494 checkEnabled <- (WarnReach `elem`) . opt_cmdline . idris_options <$> getIState
@@ -135,7 +135,7 @@ performUsageAnalysis startNames = do
135135 where
136136 fmt n [] = show n ++ " (no more information available)"
137137 fmt n rs = show n ++ " from " ++ intercalate ", " [show rn ++ " arg# " ++ show ri | (rn,ri) <- rs]
138− warn = logLvl 0
138+ warn = logErasure 0
139139
140140-- Find the minimal consistent usage by forward chaining.
141141minimalUsage :: Deps -> (Deps, (Set Name, UseMap))
@@ -150,7 +150,7 @@ minimalUsage = second gather . forwardChain
150150
151151forwardChain :: Deps -> (Deps, DepSet)
152152forwardChain deps
153− | Just trivials <- M.lookup S.empty deps
153+ | Just trivials <- M.lookup S.empty deps
154154 = (M.unionWith S.union trivials)
155155 `second` forwardChain (remove trivials . M.delete S.empty $ deps)
156156 | otherwise = (deps, M.empty)
@@ -164,7 +164,7 @@ forwardChain deps
164164-- starting the depth-first search from a list of Names.
165165buildDepMap :: Ctxt ClassInfo -> [(Name, Int)] -> [(Name, Int)] ->
166166 Context -> [Name] -> Deps
167−buildDepMap ci used externs ctx startNames
167+buildDepMap ci used externs ctx startNames
168168 = addPostulates used $ dfs S.empty M.empty startNames
169169 where
170170 -- mark the result of Main.main as used with the empty assumption
@@ -181,7 +181,7 @@ buildDepMap ci used externs ctx startNames
181181 usedNames = allNames deps S.\\ specialPrims
182182 usedPrims = [(p_name p, p_arity p) | p <- primitives, p_name p `S.member` usedNames]
183183
184− postulates used =
184+ postulates used =
185185 [ [] ==> concat
186186 -- Main.main ( + export lists) and run__IO, are always evaluated
187187 -- but they elude analysis since they come from the seed term.
@@ -190,7 +190,7 @@ buildDepMap ci used externs ctx startNames
190190 ,[(sUN "call__IO", Result), (sUN "call__IO", Arg 2)]
191191
192192 -- Explicit usage declarations from a %used pragma
193− , map (\(n, i) -> (n, Arg i)) used
193+ , map (\(n, i) -> (n, Arg i)) used
194194
195195 -- MkIO is read by run__IO,
196196 -- but this cannot be observed in the source code of programs.
@@ -200,7 +200,7 @@ buildDepMap ci used externs ctx startNames
200200 -- Foreign calls are built with pairs, but mkForeign doesn't
201201 -- have an implementation so analysis won't see them
202202 , [(pairCon, Arg 2),
203− (pairCon, Arg 3)] -- Used in foreign calls
203+ (pairCon, Arg 3)] -- Used in foreign calls
204204
205205 -- these have been discovered as builtins but are not listed
206206 -- among Idris.Primitives.primitives
@@ -211,7 +211,7 @@ buildDepMap ci used externs ctx startNames
211211 -- believe_me is a primitive but it only uses its third argument
212212 -- it is special-cased in usedNames above
213213 , it "prim__believe_me" [2]
214−
214+
215215 -- in general, all other primitives use all their arguments
216216 , [(n, Arg i) | (n,arity) <- usedPrims, i <- [0..arity-1]]
217217
@@ -324,7 +324,7 @@ buildDepMap ci used externs ctx startNames
324324 , viMethod = meth j
325325 })
326326 | (v, j) <- zip ns [0..]]
327−
327+
328328 -- this is safe because it's certainly a patvar
329329 varIdx = fromJust (viFunArg var)
330330
@@ -414,7 +414,7 @@ buildDepMap ci used externs ctx startNames
414414 V i -> snd (bs !! i) cd `union` unconditionalDeps args
415415
416416 -- we interpret applied lambdas as lets in order to reuse code here
417− Bind n (Lam ty) t -> getDepsTerm vs bs cd (lamToLet [] app)
417+ Bind n (Lam ty) t -> getDepsTerm vs bs cd (lamToLet app)
418418
419419 -- and we interpret applied lets as lambdas
420420 Bind n ( Let ty t') t -> getDepsTerm vs bs cd (App Complete (Bind n (Lam ty) t) t')
@@ -491,11 +491,8 @@ buildDepMap ci used externs ctx startNames
491491
492492 -- convert applications of lambdas to lets
493493 -- Note that this transformation preserves de bruijn numbering
494− lamToLet :: [Term] -> Term -> Term
495− lamToLet xs (App _ f x) = lamToLet (x:xs) f
496− lamToLet (x:xs) (Bind n (Lam ty) t) = Bind n (Let ty x) (lamToLet xs t)
497− lamToLet (x:xs) t = App Complete (lamToLet xs t) x
498− lamToLet [] t = t
494+ lamToLet :: Term -> Term
495+ lamToLet (App _ (Bind n (Lam ty) tm) val) = Bind n (Let ty val) tm
499496
500497 -- split "\x_i -> T(x_i)" into [x_i] and T
501498 unfoldLams :: Term -> ([Name], Term)
src/Idris/IBC.hs+33−24
@@ -40,7 +40,7 @@ import System.Directory
4040import Codec.Archive.Zip
4141
4242ibcVersion :: Word16
43−ibcVersion = 120
43+ibcVersion = 128
4444
4545data IBCFile = IBCFile { ver :: Word16,
4646 sourcefile :: FilePath,
@@ -80,13 +80,14 @@ data IBCFile = IBCFile { ver :: Word16,
8080 ibc_errorhandlers :: ![Name],
8181 ibc_function_errorhandlers :: ![(Name, Name, Name)], -- fn, arg, handler
8282 ibc_metavars :: ![(Name, (Maybe Name, Int, [Name], Bool))],
83− ibc_patdefs :: ![(Name, ([([Name], Term, Term)], [PTerm]))],
83+ ibc_patdefs :: ![(Name, ([([(Name, Term)], Term, Term)], [PTerm]))],
8484 ibc_postulates :: ![Name],
8585 ibc_externs :: ![(Name, Int)],
8686 ibc_parsedSpan :: !(Maybe FC),
8787 ibc_usage :: ![(Name, Int)],
8888 ibc_exports :: ![Name],
89− ibc_autohints :: ![(Name, Name)]
89+ ibc_autohints :: ![(Name, Name)],
90+ ibc_deprecated :: ![(Name, String)]
9091 }
9192 deriving Show
9293{-!
@@ -94,7 +95,7 @@ deriving instance Binary IBCFile
9495!-}
9596
9697initIBC :: IBCFile
97−initIBC = IBCFile ibcVersion "" [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] Nothing [] [] []
98+initIBC = IBCFile ibcVersion "" [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] Nothing [] [] [] []
9899
99100hasValidIBCVersion :: FilePath -> Idris Bool
100101hasValidIBCVersion fp = do
@@ -112,7 +113,7 @@ loadIBC reexport fp
112113 Nothing -> True
113114 Just p -> not p && reexport
114115 when redo $
115− do logLvl 1 $ "Loading ibc " ++ fp ++ " " ++ show reexport
116+ do logIBC 1 $ "Loading ibc " ++ fp ++ " " ++ show reexport
116117 archiveFile <- runIO $ B.readFile fp
117118 case toArchiveOrFail archiveFile of
118119 Left _ -> ifail $ fp ++ " isn't loadable, it may have an old ibc format.\n"
@@ -179,7 +180,8 @@ entries i = catMaybes [Just $ toEntry "ver" 0 (encode $ ver i),
179180 toEntry "ibc_parsedSpan" 0 . encode <$> ibc_parsedSpan i,
180181 makeEntry "ibc_usage" (ibc_usage i),
181182 makeEntry "ibc_exports" (ibc_exports i),
182− makeEntry "ibc_autohints" (ibc_autohints i)]
183+ makeEntry "ibc_autohints" (ibc_autohints i),
184+ makeEntry "ibc_deprecated" (ibc_deprecated i)]
183185
184186writeArchive :: FilePath -> IBCFile -> Idris ()
185187writeArchive fp i = do let a = L.foldl (\x y -> addEntryToArchive y x) emptyArchive (entries i)
@@ -187,7 +189,7 @@ writeArchive fp i = do let a = L.foldl (\x y -> addEntryToArchive y x) emptyArch
187189
188190writeIBC :: FilePath -> FilePath -> Idris ()
189191writeIBC src f
190− = do logLvl 1 $ "Writing ibc " ++ show f
192+ = do logIBC 1 $ "Writing ibc " ++ show f
191193 i <- getIState
192194-- case (Data.List.map fst (idris_metavars i)) \\ primDefs of
193195-- (_:_) -> ifail "Can't write ibc when there are unsolved metavariables"
@@ -196,8 +198,8 @@ writeIBC src f
196198 ibcf <- mkIBC (ibc_write i) (initIBC { sourcefile = src })
197199 idrisCatch (do runIO $ createDirectoryIfMissing True (dropFileName f)
198200 writeArchive f ibcf
199− logLvl 1 "Written")
200− (\c -> do logLvl 1 $ "Failed " ++ pshow i c)
201+ logIBC 1 "Written")
202+ (\c -> do logIBC 1 $ "Failed " ++ pshow i c)
201203 return ()
202204
203205-- Write a package index containing all the imports in the current IState
@@ -206,20 +208,20 @@ writePkgIndex :: FilePath -> Idris ()
206208writePkgIndex f
207209 = do i <- getIState
208210 let imps = map (\ (x, y) -> (True, x)) $ idris_imported i
209− logLvl 1 $ "Writing package index " ++ show f ++ " including\n" ++
211+ logIBC 1 $ "Writing package index " ++ show f ++ " including\n" ++
210212 show (map snd imps)
211213 resetNameIdx
212214 let ibcf = initIBC { ibc_imports = imps }
213215 idrisCatch (do runIO $ createDirectoryIfMissing True (dropFileName f)
214216 writeArchive f ibcf
215− logLvl 1 "Written")
216− (\c -> do logLvl 1 $ "Failed " ++ pshow i c)
217+ logIBC 1 "Written")
218+ (\c -> do logIBC 1 $ "Failed " ++ pshow i c)
217219 return ()
218220
219221mkIBC :: [IBCWrite] -> IBCFile -> Idris IBCFile
220222mkIBC [] f = return f
221223mkIBC (i:is) f = do ist <- getIState
222− logLvl 5 $ show i ++ " " ++ show (L.length is)
224+ logIBC 5 $ show i ++ " " ++ show (L.length is)
223225 f' <- ibc ist i f
224226 mkIBC is f'
225227
@@ -305,6 +307,7 @@ ibc i (IBCModDocs n) f = case lookupCtxtExact n (idris_moduledocs i) of
305307ibc i (IBCUsage n) f = return f { ibc_usage = n : ibc_usage f }
306308ibc i (IBCExport n) f = return f { ibc_exports = n : ibc_exports f }
307309ibc i (IBCAutoHint n h) f = return f { ibc_autohints = (n, h) : ibc_autohints f }
310+ibc i (IBCDeprecate n r) f = return f { ibc_deprecated = (n, r) : ibc_deprecated f }
308311
309312getEntry :: (Binary b, NFData b) => b -> FilePath -> Archive -> Idris b
310313getEntry alt f a = case findEntryByPath f a of
@@ -316,7 +319,7 @@ process :: Bool -- ^ Reexporting
316319process reexp i fn = do
317320 ver <- getEntry 0 "ver" i
318321 when (ver /= ibcVersion) $ do
319− logLvl 1 "ibc out of date"
322+ logIBC 1 "ibc out of date"
320323 let e = if ver < ibcVersion
321324 then " an earlier " else " a later "
322325 ifail $ "Incompatible ibc version.\nThis library was built with"
@@ -367,6 +370,7 @@ process reexp i fn = do
367370 pUsage =<< getEntry [] "ibc_usage" i
368371 pExports =<< getEntry [] "ibc_exports" i
369372 pAutoHints =<< getEntry [] "ibc_autohints" i
373+ pDeprecate =<< getEntry [] "ibc_deprecated" i
370374
371375timestampOlder :: FilePath -> FilePath -> Idris ()
372376timestampOlder src ibc = do srct <- runIO $ getModificationTime src
@@ -394,6 +398,9 @@ pExports ns = updateIState (\i -> i { idris_exports = ns ++ idris_exports i })
394398pAutoHints :: [(Name, Name)] -> Idris ()
395399pAutoHints ns = mapM_ (\(n,h) -> addAutoHint n h) ns
396400
401+pDeprecate :: [(Name, String)] -> Idris ()
402+pDeprecate ns = mapM_ (\(n,reason) -> addDeprecated n reason) ns
403+
397404pImportDirs :: [FilePath] -> Idris ()
398405pImportDirs fs = mapM_ addImportDir fs
399406
@@ -408,10 +415,12 @@ pImports reexp fs
408415-- then logLvl 1 $ "Already read " ++ f
409416 putIState (i { imported = f : imported i })
410417 case fp of
411− LIDR fn -> do logLvl 1 $ "Failed at " ++ fn
412− ifail "Must be an ibc"
413− IDR fn -> do logLvl 1 $ "Failed at " ++ fn
414− ifail "Must be an ibc"
418+ LIDR fn -> do
419+ logIBC 1 $ "Failed at " ++ fn
420+ ifail "Must be an ibc"
421+ IDR fn -> do
422+ logIBC 1 $ "Failed at " ++ fn
423+ ifail "Must be an ibc"
415424 IBC fn src -> loadIBC (reexp && re) fn)
416425 fs
417426
@@ -498,7 +507,7 @@ pDyLibs ls = do res <- mapM (addDyLib . return) ls
498507pHdrs :: [(Codegen, String)] -> Idris ()
499508pHdrs hs = mapM_ (uncurry addHdr) hs
500509
501−pPatdefs :: [(Name, ([([Name], Term, Term)], [PTerm]))] -> Idris ()
510+pPatdefs :: [(Name, ([([(Name, Term)], Term, Term)], [PTerm]))] -> Idris ()
502511pPatdefs ds = mapM_ (\ (n, d) -> updateIState (\i ->
503512 i { idris_patdefs = addDef n (force d) (idris_patdefs i) })) ds
504513
@@ -508,13 +517,13 @@ pDefs reexp ds
508517 do d' <- updateDef d
509518 case d' of
510519 TyDecl _ _ -> return ()
511− _ -> do logLvl 1 $ "SOLVING " ++ show n
520+ _ -> do logIBC 1 $ "SOLVING " ++ show n
512521 solveDeferred n
513522 updateIState (\i -> i { tt_ctxt = addCtxtDef n d' (tt_ctxt i) })
514523-- logLvl 1 $ "Added " ++ show (n, d')
515− if (not reexp) then do logLvl 1 $ "Not exporting " ++ show n
524+ if (not reexp) then do logIBC 1 $ "Not exporting " ++ show n
516525 setAccessibility n Hidden
517− else logLvl 1 $ "Exporting " ++ show n) ds
526+ else logIBC 1 $ "Exporting " ++ show n) ds
518527 where
519528 updateDef (CaseOp c t args o s cd)
520529 = do o' <- mapM updateOrig o
@@ -579,7 +588,7 @@ pAccess :: Bool -- ^ Reexporting?
579588pAccess reexp ds
580589 = mapM_ (\ (n, a_in) ->
581590 do let a = if reexp then a_in else Hidden
582− logLvl 3 $ "Setting " ++ show (a, n) ++ " to " ++ show a
591+ logIBC 3 $ "Setting " ++ show (a, n) ++ " to " ++ show a
583592 updateIState (\i -> i { tt_ctxt = setAccess n a (tt_ctxt i) })) ds
584593
585594pFlags :: [(Name, [FnOpt])] -> Idris ()
@@ -1836,7 +1845,7 @@ instance Binary PTerm where
18361845 _ -> error "Corrupted binary data for PTerm"
18371846
18381847instance Binary PAltType where
1839− put x
1848+ put x
18401849 = case x of
18411850 ExactlyOne x1 -> do putWord8 0
18421851 put x1
src/Idris/Interactive.hs+34−17
@@ -34,10 +34,10 @@ import Debug.Trace
3434caseSplitAt :: FilePath -> Bool -> Int -> Name -> Idris ()
3535caseSplitAt fn updatefile l n
3636 = do src <- runIO $ readSource fn
37− res <- splitOnLine l n fn
37+ (ok, res) <- splitOnLine l n fn
3838 logLvl 1 (showSep "\n" (map show res))
3939 let (before, (ap : later)) = splitAt (l-1) (lines src)
40− res' <- replaceSplits ap res
40+ res' <- replaceSplits ap res (not ok)
4141 let new = concat res'
4242 if updatefile
4343 then do let fb = fn ++ "~" -- make a backup!
@@ -47,11 +47,20 @@ caseSplitAt fn updatefile l n
4747 iPrintResult new
4848
4949addClauseFrom :: FilePath -> Bool -> Int -> Name -> Idris ()
50−addClauseFrom fn updatefile l n
51− = do src <- runIO $ readSource fn
50+addClauseFrom fn updatefile l n = do
51+ -- if a definition already exists, add missing cases rather than
52+ -- adding a new definition.
53+ ist <- getIState
54+ cl <- getInternalApp fn l
55+ let fulln = getAppName cl
56+
57+ case lookup fulln (idris_metavars ist) of
58+ Nothing -> addMissing fn updatefile l n
59+ Just _ -> do
60+ src <- runIO $ readSource fn
5261 let (before, tyline : later) = splitAt (l-1) (lines src)
5362 let indent = getIndent 0 (show n) tyline
54− cl <- getClause l n fn
63+ cl <- getClause l fulln n fn
5564 -- add clause before first blank line in 'later'
5665 let (nonblank, rest) = span (not . all isSpace) (tyline:later)
5766 if updatefile
@@ -62,11 +71,16 @@ addClauseFrom fn updatefile l n
6271 unlines rest)
6372 runIO $ copyFile fb fn
6473 else iPrintResult cl
65− where
66− getIndent i n [] = 0
67− getIndent i n xs | take 9 xs == "instance " = i
68− getIndent i n xs | take (length n) xs == n = i
69− getIndent i n (x : xs) = getIndent (i + 1) n xs
74+ where
75+ getIndent i n [] = 0
76+ getIndent i n xs | take 9 xs == "instance " = i
77+ getIndent i n xs | take (length n) xs == n = i
78+ getIndent i n (x : xs) = getIndent (i + 1) n xs
79+
80+ getAppName (PApp _ r _) = getAppName r
81+ getAppName (PRef _ _ r) = r
82+ getAppName (PTyped n _) = getAppName n
83+ getAppName _ = n
7084
7185addProofClauseFrom :: FilePath -> Bool -> Int -> Name -> Idris ()
7286addProofClauseFrom fn updatefile l n
@@ -98,16 +112,17 @@ addMissing fn updatefile l n
98112 cl <- getInternalApp fn l
99113 let n' = getAppName cl
100114
101− extras <- case lookupCtxt n' (idris_patdefs i) of
102− [] -> return ""
103− [(_, tms)] -> do tms' <- nameMissing tms
104− showNew (show n ++ "_rhs") 1 indent tms'
105− other -> return "" -- happens if called on a metavar, or with no clauses
115+ extras <- case lookupCtxtExact n' (idris_patdefs i) of
116+ Nothing -> return ""
117+ Just (_, tms) -> do tms' <- nameMissing tms
118+ showNew (show n ++ "_rhs") 1 indent tms'
106119 let (nonblank, rest) = span (not . all isSpace) (tyline:later)
107120 if updatefile
108121 then do let fb = fn ++ "~"
109122 runIO $ writeSource fb (unlines (before ++ nonblank)
110− ++ extras ++ unlines rest)
123+ ++ extras ++
124+ (if null extras then ""
125+ else "\n" ++ unlines rest))
111126 runIO $ copyFile fb fn
112127 else iPrintResult extras
113128 where showPat = show . stripNS
@@ -121,6 +136,7 @@ addMissing fn updatefile l n
121136
122137 getAppName (PApp _ r _) = getAppName r
123138 getAppName (PRef _ _ r) = r
139+ getAppName (PTyped n _) = getAppName n
124140 getAppName _ = n
125141
126142 makeIndent ind | ".lidr" `isSuffixOf` fn = '>' : ' ' : replicate (ind-2) ' '
@@ -131,7 +147,8 @@ addMissing fn updatefile l n
131147 rest <- showNew nm i' ind tms
132148 return (makeIndent ind ++
133149 showPat tm ++ " = ?" ++ nm' ++
134− "\n" ++ rest)
150+ (if null rest then "" else
151+ "\n" ++ rest))
135152 showNew nm i _ [] = return ""
136153
137154 getIndent i n [] = 0
src/Idris/ParseExpr.hs+3−3
@@ -1084,10 +1084,10 @@ normalImplicit opts st syn = do
10841084 sc <- expr syn
10851085 let (im,cl)
10861086 = if implicitAllowed syn
1087− then (Imp opts st False Nothing,
1087+ then (Imp opts st False (Just (Impl False True)),
10881088 constraint)
1089− else (Imp opts st False (Just (Impl False)),
1090− Imp opts st False (Just (Impl True)))
1089+ else (Imp opts st False (Just (Impl False False)),
1090+ Imp opts st False (Just (Impl True False)))
10911091 return (bindList (PPi im) xt
10921092 (bindList (PPi cl) cs sc))
10931093
src/Idris/Parser.hs+44−24
@@ -153,7 +153,7 @@ import_ = do fc <- getFC
153153prog :: SyntaxInfo -> IdrisParser [PDecl]
154154prog syn = do whiteSpace
155155 decls <- many (decl syn)
156− let c = (concat decls)
156+ let c = concat decls
157157 case maxline syn of
158158 Nothing -> do notOpenBraces; eof
159159 _ -> return ()
@@ -189,19 +189,29 @@ decl syn = try (externalDecl syn)
189189 <?> "declaration"
190190
191191internalDecl :: SyntaxInfo -> IdrisParser [PDecl]
192−internalDecl syn
192+internalDecl syn
193193 = do fc <- getFC
194− -- if we're after maxline, stop here
194+ -- if we're after maxline, stop at the next type declaration
195+ -- (so we get all cases of a definition to preserve totality
196+ -- results, in particular).
195197 let continue = case maxline syn of
196198 Nothing -> True
197199 Just l -> if fst (fc_end fc) > l
198200 then mut_nesting syn /= 0
199201 else True
200− if continue then do notEndBlock
201− declBody
202− else fail "End of readable input"
203− where declBody :: IdrisParser [PDecl]
204− declBody = declBody'
202+ -- What I'd really like to do here is explicitly save the
203+ -- current state, then if reading ahead finds we've passed
204+ -- the end of the definition, reset the state. But I've lost
205+ -- patience with trying to find out how to do that from the
206+ -- trifecta docs, so this does the job instead.
207+ if continue then
208+ do notEndBlock
209+ declBody continue
210+ else try (do notEndBlock
211+ declBody continue)
212+ <|> fail "End of readable input"
213+ where declBody :: Bool -> IdrisParser [PDecl]
214+ declBody b = declBody' b
205215 <|> using_ syn
206216 <|> params syn
207217 <|> mutual syn
@@ -214,11 +224,17 @@ internalDecl syn
214224 <|> transform syn
215225 <|> do import_; fail "imports must be at top of file"
216226 <?> "declaration"
217− declBody' :: IdrisParser [PDecl]
218− declBody' = do d <- decl' syn
219− i <- get
220− let d' = fmap (debindApp syn . (desugar syn i)) d
221− return [d']
227+ declBody' :: Bool -> IdrisParser [PDecl]
228+ declBody' cont = do d <- decl' syn
229+ i <- get
230+ let d' = fmap (debindApp syn . (desugar syn i)) d
231+ if continue cont d'
232+ then return [d']
233+ else fail "End of readable input"
234+
235+ -- Keep going while we're still parsing clauses
236+ continue False (PClauses _ _ _ _) = True
237+ continue c _ = c
222238
223239{- | Parses a top-level declaration with possible syntax sugar
224240
@@ -267,7 +283,7 @@ declExtensions syn rules = declExtension syn [] (filter isDeclRule rules)
267283 isDeclRule (DeclRule _ _) = True
268284 isDeclRule _ = False
269285
270−declExtension :: SyntaxInfo -> [Maybe (Name, SynMatch)] -> [Syntax]
286+declExtension :: SyntaxInfo -> [Maybe (Name, SynMatch)] -> [Syntax]
271287 -> IdrisParser [PDecl]
272288declExtension syn ns rules =
273289 choice $ flip map (groupBy (ruleGroup `on` syntaxSymbols) rules) $ \rs ->
@@ -302,7 +318,7 @@ declExtension syn ns rules =
302318 updateNs :: [(Name, SynMatch)] -> PDecl -> PDecl
303319 updateNs ns (PTy doc argdoc s fc o n fc' t)
304320 = PTy doc argdoc s fc o (updateB ns n) fc' t
305− updateNs ns (PClauses fc o n cs)
321+ updateNs ns (PClauses fc o n cs)
306322 = PClauses fc o (updateB ns n) (map (updateClause ns) cs)
307323 updateNs ns (PCAF fc n t) = PCAF fc (updateB ns n) t
308324 updateNs ns (PData ds cds s fc o dat)
@@ -322,10 +338,10 @@ declExtension syn ns rules =
322338 cdocs
323339 updateNs ns (PInstance docs pdocs s fc cs cn fc' ps ity ni ds)
324340 = PInstance docs pdocs s fc cs (updateB ns cn) fc'
325− ps ity (fmap (updateB ns) ni)
341+ ps ity (fmap (updateB ns) ni)
326342 (map (updateNs ns) ds)
327343 updateNs ns (PMutual fc ds) = PMutual fc (map (updateNs ns) ds)
328− updateNs ns (PProvider docs s fc fc' pw n)
344+ updateNs ns (PProvider docs s fc fc' pw n)
329345 = PProvider docs s fc fc' pw (updateB ns n)
330346 updateNs ns d = d
331347
@@ -466,7 +482,7 @@ syntaxRule syn
466482 where ts = dropWhile isSpace . dropWhileEnd isSpace $ s
467483 mkSimple' (e : es) = e : mkSimple' es
468484 mkSimple' [] = []
469−
485+
470486 -- Prevent syntax variable capture by making all binders under syntax unique
471487 -- (the ol' Common Lisp GENSYM approach)
472488 uniquifyBinders :: [Name] -> PTerm -> IdrisParser PTerm
@@ -1307,6 +1323,10 @@ directive syn = do try (lchar '%' *> reserved "lib")
13071323 return [PDirective (DErrorHandlers fn nfc arg afc ns) ]
13081324 <|> do try (lchar '%' *> reserved "language"); ext <- pLangExt;
13091325 return [PDirective (DLanguage ext)]
1326+ <|> do try (lchar '%' *> reserved "deprecate")
1327+ n <- fst <$> fnName
1328+ alt <- option "" (fst <$> stringLiteral)
1329+ return [PDirective (DDeprecate n alt)]
13101330 <|> do fc <- getFC
13111331 try (lchar '%' *> reserved "used")
13121332 fn <- fst <$> fnName
@@ -1532,7 +1552,7 @@ loadModule' f
15321552 ids <- allImportDirs
15331553 fp <- findImport ids ibcsd file
15341554 if file `elem` imported i
1535− then do logLvl 1 $ "Already read " ++ file
1555+ then do logParser 1 $ "Already read " ++ file
15361556 return Nothing
15371557 else do putIState (i { imported = file : imported i })
15381558 case fp of
@@ -1540,7 +1560,7 @@ loadModule' f
15401560 LIDR fn -> loadSource True fn Nothing
15411561 IBC fn src ->
15421562 idrisCatch (loadIBC True fn)
1543− (\c -> do logLvl 1 $ fn ++ " failed " ++ pshow i c
1563+ (\c -> do logParser 1 $ fn ++ " failed " ++ pshow i c
15441564 case src of
15451565 IDR sfn -> loadSource False sfn Nothing
15461566 LIDR sfn -> loadSource True sfn Nothing)
@@ -1549,7 +1569,7 @@ loadModule' f
15491569{- | Load idris code from file -}
15501570loadFromIFile :: Bool -> IFileType -> Maybe Int -> Idris ()
15511571loadFromIFile reexp i@(IBC fn src) maxline
1552− = do logLvl 1 $ "Skipping " ++ getSrcFile i
1572+ = do logParser 1 $ "Skipping " ++ getSrcFile i
15531573 idrisCatch (loadIBC reexp fn)
15541574 (\err -> ierror $ LoadingFailed fn err)
15551575 where
@@ -1573,7 +1593,7 @@ loadSource' lidr r maxline
15731593{- | Load Idris source code-}
15741594loadSource :: Bool -> FilePath -> Maybe Int -> Idris ()
15751595loadSource lidr f toline
1576− = do logLvl 1 ("Reading " ++ f)
1596+ = do logParser 1 ("Reading " ++ f)
15771597 i <- getIState
15781598 let def_total = default_total i
15791599 file_in <- runIO $ readSource f
@@ -1617,7 +1637,7 @@ loadSource lidr f toline
16171637 ]
16181638 histogram = groupBy ((==) `on` fst) . sortBy (comparing fst) $ aliasNames
16191639 case map head . filter ((/= 1) . length) $ histogram of
1620− [] -> logLvl 3 $ "Module aliases: " ++ show (M.toList modAliases)
1640+ [] -> logParser 3 $ "Module aliases: " ++ show (M.toList modAliases)
16211641 (n,fc):_ -> throwError . At fc . Msg $ "import alias not unique: " ++ show n
16221642
16231643 i <- getIState
@@ -1656,7 +1676,7 @@ loadSource lidr f toline
16561676 -- Parsing done, now process declarations
16571677
16581678 let ds = namespaces mname ds'
1659− logLvl 3 (show $ showDecls verbosePPOption ds)
1679+ logParser 3 (show $ showDecls verbosePPOption ds)
16601680 i <- getIState
16611681 logLvl 10 (show (toAlist (idris_implicits i)))
16621682 logLvl 3 (show (idris_infixes i))
src/Idris/ProofSearch.hs+16−9
@@ -178,7 +178,7 @@ proofSearch rec fromProver ambigok deferonfail maxDepth elab fn nroot psnames hi
178178 cantsolve (CantSolveGoal _ _) = True
179179 cantsolve (IncompleteTerm _) = True
180180 cantsolve (At _ e) = cantsolve e
181− cantsolve (Elaborating _ _ e) = cantsolve e
181+ cantsolve (Elaborating _ _ _ e) = cantsolve e
182182 cantsolve (ElaboratingArg _ _ _ e) = cantsolve e
183183 cantsolve err = False
184184
@@ -196,7 +196,7 @@ proofSearch rec fromProver ambigok deferonfail maxDepth elab fn nroot psnames hi
196196 Nothing -> -- local variable, go for it
197197 return True
198198 TType _ -> return True
199− _ -> fail "Not a data type"
199+ _ -> typeNotSearchable ty
200200
201201 conReady :: [Term] -> Name -> ElabD Bool
202202 conReady as n
@@ -282,8 +282,8 @@ proofSearch rec fromProver ambigok deferonfail maxDepth elab fn nroot psnames hi
282282 -- since that's part of the point...)
283283 $ checkConstructor ist others
284284 tryCons d locs tys (others ++ getFn d fn)
285− Nothing -> fail "Not a data type"
286− _ -> fail "Not a data type"
285+ Nothing -> typeNotSearchable t
286+ _ -> typeNotSearchable t
287287
288288 -- if there are local variables which have a function type, try
289289 -- applying them too
@@ -326,11 +326,20 @@ proofSearch rec fromProver ambigok deferonfail maxDepth elab fn nroot psnames hi
326326 let newhs = filter (\ (x, y) -> not x) (zip (map fst imps) args)
327327 mapM_ (\ (_, h) -> do focus h
328328 aty <- goal
329− psRec True d locs tys) newhs
329+ psRec True d locs tys) newhs
330330 solve
331331
332332 isImp (PImp p _ _ _ _) = (True, p)
333− isImp arg = (False, priority arg)
333+ isImp arg = (False, priority arg)
334+
335+ typeNotSearchable ty =
336+ lift $ tfail $ FancyMsg $
337+ [TextPart "Attempted to find an element of type",
338+ TermPart ty,
339+ TextPart "using proof search, but proof search only works on datatypes with constructors."] ++
340+ case ty of
341+ (Bind _ (Pi _ _ _) _) -> [TextPart "In particular, function types are not supported."]
342+ _ -> []
334343
335344-- In interactive mode, only search for things if there is some
336345-- index to help pick a relevant constructor
@@ -453,9 +462,7 @@ resTC' tcs defaultOn topholes depth topg fn elab ist
453462 boundVar (P Bound _ _) = True
454463 boundVar _ = False
455464
456− blunderbuss t d stk [] = do -- c <- get_env
457− -- ps <- get_probs
458− lift $ tfail $ CantResolve False topg
465+ blunderbuss t d stk [] = lift $ tfail $ CantResolve False topg
459466 blunderbuss t d stk (n:ns)
460467 | n /= fn -- && (n `elem` stk)
461468 = tryCatch (resolve n d)
src/Idris/REPL.hs+65−42
@@ -189,11 +189,13 @@ processNetCmd orig i h fn cmd
189189 where
190190 processNet fn Reload = processNet fn (Load fn Nothing)
191191 processNet fn (Load f toline) =
192− do let ist = orig { idris_options = idris_options i
193− , idris_colourTheme = idris_colourTheme i
194− , idris_colourRepl = False
195− }
196− putIState ist
192+ -- The $!! here prevents a space leak on reloading.
193+ -- This isn't a solution - but it's a temporary stopgap.
194+ -- See issue #2386
195+ do putIState $!! orig { idris_options = idris_options i
196+ , idris_colourTheme = idris_colourTheme i
197+ , idris_colourRepl = False
198+ }
197199 setErrContext True
198200 setOutH h
199201 setQuiet True
@@ -755,6 +757,9 @@ edit f orig
755757 let args = line ++ [fixName f]
756758 runIO $ rawSystem editor args
757759 clearErr
760+ -- The $!! here prevents a space leak on reloading.
761+ -- This isn't a solution - but it's a temporary stopgap.
762+ -- See issue #2386
758763 putIState $!! orig { idris_options = idris_options i
759764 , idris_colourTheme = idris_colourTheme i
760765 }
@@ -796,25 +801,30 @@ process fn (ModImport f) = do fmod <- loadModule f
796801 Nothing -> iPrintError $ "Can't find import " ++ f
797802process fn (Eval t)
798803 = withErrorReflection $
799− do logLvl 5 $ show t
804+ do logParser 5 $ show t
800805 getIState >>= flip warnDisamb t
801806 (tm, ty) <- elabREPL recinfo ERHS t
802807 ctxt <- getContext
803− let tm' = perhapsForce $ normaliseAll ctxt [] tm
808+ let tm' = perhapsForce $ normaliseBlocking ctxt []
809+ [sUN "foreign",
810+ sUN "prim_read",
811+ sUN "prim_write"]
812+ tm
804813 let ty' = perhapsForce $ normaliseAll ctxt [] ty
805814 -- Add value to context, call it "it"
806815 updateContext (addCtxtDef (sUN "it") (Function ty' tm'))
807816 ist <- getIState
808− logLvl 3 $ "Raw: " ++ show (tm', ty')
809− logLvl 10 $ "Debug: " ++ showEnvDbg [] tm'
817+ logParser 3 $ "Raw: " ++ show (tm', ty')
818+ logParser 10 $ "Debug: " ++ showEnvDbg [] tm'
810819 let tmDoc = pprintDelab ist tm'
811− tyDoc = pprintDelab ist ty'
820+ -- errReverse to make type more readable
821+ tyDoc = pprintDelab ist (errReverse ist ty')
812822 iPrintTermWithType tmDoc tyDoc
813823 where perhapsForce tm | termSmallerThan 100 tm = force tm
814824 | otherwise = tm
815825
816826process fn (NewDefn decls) = do
817− logLvl 3 ("Defining names using these decls: " ++ show (showDecls verbosePPOption decls))
827+ logParser 3 ("Defining names using these decls: " ++ show (showDecls verbosePPOption decls))
818828 mapM_ defineName namedGroups where
819829 namedGroups = groupBy (\d1 d2 -> getName d1 == getName d2) decls
820830 getName :: PDecl -> Maybe Name
@@ -933,16 +943,19 @@ process fn (Check (PRef _ _ n))
933943 where
934944 showMetavarInfo ppo ist n i
935945 = case lookupTy n (tt_ctxt ist) of
936− (ty:_) -> putTy ppo ist i [] (delab ist (errReverse ist ty))
946+ (ty:_) -> let ty' = normaliseC (tt_ctxt ist) [] ty in
947+ putTy ppo ist i [] (delab ist (errReverse ist ty'))
937948 putTy :: PPOption -> IState -> Int -> [(Name, Bool)] -> PTerm -> Doc OutputAnnotation
938949 putTy ppo ist 0 bnd sc = putGoal ppo ist bnd sc
939950 putTy ppo ist i bnd (PPi _ n _ t sc)
940− = let current = text " " <>
941− (case n of
942− MN _ _ -> text "_"
943− UN nm | ('_':'_':_) <- str nm -> text "_"
944− _ -> bindingOf n False) <+>
945− colon <+> align (tPretty bnd ist t) <> line
951+ = let current = case n of
952+ MN _ _ -> text ""
953+ UN nm | ('_':'_':_) <- str nm -> text ""
954+ _ -> text " " <>
955+ bindingOf n False
956+ <+> colon
957+ <+> align (tPretty bnd ist t)
958+ <> line
946959 in
947960 current <> putTy ppo ist (i-1) ((n,False):bnd) sc
948961 putTy ppo ist _ bnd sc = putGoal ppo ist ((n,False):bnd) sc
@@ -973,8 +986,8 @@ process fn (Core t)
973986 iPrintTermWithType (pprintTT [] tm) (pprintTT [] ty)
974987
975988process fn (DocStr (Left n) w)
976− | UN ty <- n, ty == T.pack "Type" = getIState >>= iRenderResult . pprintTypeDoc
977− | otherwise = do
989+ | UN ty <- n, ty == T.pack "Type" = getIState >>= iRenderResult . pprintTypeDoc
990+ | otherwise = do
978991 ist <- getIState
979992 let docs = lookupCtxtName n (idris_docstrings ist) ++
980993 map (\(n,d)-> (n, (d, [])))
@@ -997,7 +1010,7 @@ process fn (DocStr (Right c) _) -- constants only have overviews
9971010process fn Universes
9981011 = do i <- getIState
9991012 let cs = idris_constraints i
1000− let cslist = S.toAscList cs
1013+ let cslist = S.toAscList cs
10011014-- iputStrLn $ showSep "\n" (map show cs)
10021015 iputStrLn $ show (map uconstraint cslist)
10031016 let n = length cslist
@@ -1052,6 +1065,8 @@ process fn (DebugInfo n)
10521065 when (not (null si)) $ iputStrLn (show si)
10531066 let di = lookupCtxt n (idris_datatypes i)
10541067 when (not (null di)) $ iputStrLn (show di)
1068+ let imps = lookupCtxt n (idris_implicits i)
1069+ when (not (null imps)) $ iputStrLn (show imps)
10551070 let d = lookupDef n (tt_ctxt i)
10561071 when (not (null d)) $ iputStrLn $ "Definition: " ++ (show (head d))
10571072 let cg = lookupCtxtName n (idris_callgraph i)
@@ -1182,7 +1197,7 @@ process fn (Execute tm)
11821197 = idrisCatch
11831198 (do ist <- getIState
11841199 (m, _) <- elabVal recinfo ERHS (elabExec fc tm)
1185− (tmpn, tmph) <- runIO tempfile
1200+ (tmpn, tmph) <- runIO $ tempfile ""
11861201 runIO $ hClose tmph
11871202 t <- codegen
11881203 -- gcc adds .exe when it builds windows programs
@@ -1211,6 +1226,7 @@ process fn (Compile codegen f)
12111226 runIO $ generate codegen (fst (head (idris_imported i))) ir
12121227 where fc = fileFC "main"
12131228process fn (LogLvl i) = setLogLevel i
1229+process fn (LogCategory cs) = setLogCats cs
12141230-- Elaborate as if LHS of a pattern (debug command)
12151231process fn (Pattelab t)
12161232 = do (tm, ty) <- elabVal recinfo ELHS t
@@ -1218,12 +1234,16 @@ process fn (Pattelab t)
12181234
12191235process fn (Missing n)
12201236 = do i <- getIState
1221− let i' = i { idris_options = (idris_options i) { opt_showimp = True } }
1237+ ppOpts <- fmap ppOptionIst getIState
12221238 case lookupCtxt n (idris_patdefs i) of
1223− [] -> iPrintError $ "Unknown operator " ++ show n
1224− [(_, tms)] ->
1225− iPrintResult (showSep "\n" (map (showTm i') tms))
1226− _ -> iPrintError $ "Ambiguous name"
1239+ [] -> iPrintError $ "Unknown name " ++ show n
1240+ [(_, tms)] ->
1241+ iRenderResult (vsep (map (pprintPTerm ppOpts {ppopt_impl = True}
1242+ []
1243+ []
1244+ (idris_infixes i))
1245+ tms))
1246+ _ -> iPrintError $ "Ambiguous name"
12271247process fn (DynamicLink l)
12281248 = do i <- getIState
12291249 let importdirs = opt_importdirs (idris_options i)
@@ -1233,7 +1253,7 @@ process fn (DynamicLink l)
12331253 Nothing -> iPrintError $ "Could not load dynamic lib \"" ++ l ++ "\""
12341254 Just x -> do let libs = idris_dynamic_libs i
12351255 if x `elem` libs
1236− then do logLvl 1 ("Tried to load duplicate library " ++ lib_name x)
1256+ then do logParser 1 ("Tried to load duplicate library " ++ lib_name x)
12371257 return ()
12381258 else putIState $ i { idris_dynamic_libs = x:libs }
12391259 where trim = reverse . dropWhile isSpace . reverse . dropWhile isSpace
@@ -1431,11 +1451,11 @@ pprintDef n =
14311451 return $ map (ppDef ambiguous ist) (lookupCtxtName n patdefs) ++
14321452 map (ppTy ambiguous ist) (lookupCtxtName n tyinfo) ++
14331453 map (ppCon ambiguous ist) (filter (flip isDConName ctxt) (lookupNames n ctxt))
1434− where ppDef :: Bool -> IState -> (Name, ([([Name], Term, Term)], [PTerm])) -> Doc OutputAnnotation
1454+ where ppDef :: Bool -> IState -> (Name, ([([(Name, Term)], Term, Term)], [PTerm])) -> Doc OutputAnnotation
14351455 ppDef amb ist (n, (clauses, missing)) =
14361456 prettyName True amb [] n <+> colon <+>
14371457 align (pprintDelabTy ist n) <$>
1438− ppClauses ist clauses <> ppMissing missing
1458+ ppClauses ist (map (\(ns, lhs, rhs) -> (map fst ns, lhs, rhs)) clauses) <> ppMissing missing
14391459 ppClauses ist [] = text "No clauses."
14401460 ppClauses ist cs = vsep (map pp cs)
14411461 where pp (vars, lhs, rhs) =
@@ -1502,15 +1522,20 @@ loadInputs inputs toline -- furthest line to read in input source files
15021522 -- For each ifile list, check it and build ibcs in the same clean IState
15031523 -- so that they don't interfere with each other when checking
15041524
1525+ importlists <- getImports [] inputs
1526+
1527+ logParser 1 (show (map (\(i,m) -> (i, map import_path m)) importlists))
1528+
15051529 let ninputs = zip [1..] inputs
15061530 ifiles <- mapWhileOK (\(num, input) ->
15071531 do putIState ist
15081532 modTree <- buildTree
15091533 (map snd (take (num-1) ninputs))
1534+ importlists
15101535 input
15111536 let ifiles = getModuleFiles modTree
1512− logLvl 1 ("MODULE TREE : " ++ show modTree)
1513− logLvl 1 ("RELOAD: " ++ show ifiles)
1537+ logParser 1 ("MODULE TREE : " ++ show modTree)
1538+ logParser 1 ("RELOAD: " ++ show ifiles)
15141539 when (not (all ibc ifiles) || loadCode) $
15151540 tryLoad False (filter (not . ibc) ifiles)
15161541 -- return the files that need rechecking
@@ -1518,7 +1543,6 @@ loadInputs inputs toline -- furthest line to read in input source files
15181543 ninputs
15191544 inew <- getIState
15201545 let tidata = idris_tyinfodata inew
1521− let patdefs = idris_patdefs inew
15221546 -- If it worked, load the whole thing from all the ibcs together
15231547 case errSpan inew of
15241548 Nothing ->
@@ -1526,9 +1550,6 @@ loadInputs inputs toline -- furthest line to read in input source files
15261550 ibcfiles <- mapM findNewIBC (nub (concat (map snd ifiles)))
15271551 tryLoad True (mapMaybe id ibcfiles)
15281552 _ -> return ()
1529− ist <- getIState
1530− putIState $! ist { idris_tyinfodata = tidata,
1531− idris_patdefs = patdefs }
15321553 exports <- findExports
15331554
15341555 case opt getOutput opts of
@@ -1704,6 +1725,7 @@ idrisMain opts =
17041725 iputStrLn banner
17051726
17061727 orig <- getIState
1728+
17071729 mods <- if idesl then return [] else loadInputs inputs Nothing
17081730 let efile = case inputs of
17091731 [] -> ""
@@ -1756,12 +1778,13 @@ idrisMain opts =
17561778 ok <- noErrors
17571779 when (not ok) $ runIO (exitWith (ExitFailure 1))
17581780 where
1759− makeOption (OLogging i) = setLogLevel i
1760− makeOption TypeCase = setTypeCase True
1761− makeOption TypeInType = setTypeInType True
1762− makeOption NoCoverage = setCoverage False
1763− makeOption ErrContext = setErrContext True
1764− makeOption _ = return ()
1781+ makeOption (OLogging i) = setLogLevel i
1782+ makeOption (OLogCats cs) = setLogCats cs
1783+ makeOption TypeCase = setTypeCase True
1784+ makeOption TypeInType = setTypeInType True
1785+ makeOption NoCoverage = setCoverage False
1786+ makeOption ErrContext = setErrContext True
1787+ makeOption _ = return ()
17651788
17661789 addPkgDir :: String -> Idris ()
17671790 addPkgDir p = do ddir <- runIO $ getIdrisLibDir
src/Idris/REPLParser.hs+60−24
@@ -1,5 +1,5 @@
11
2−module Idris.REPLParser (parseCmd, help, allHelp) where
2+module Idris.REPLParser (parseCmd, help, allHelp, setOptions) where
33
44import System.FilePath ((</>))
55import System.Console.ANSI (Color(..))
@@ -32,12 +32,22 @@ parseCmd i inputname = P.runparser pCmd i inputname . trim
3232type CommandTable = [ ( [String], CmdArg, String
3333 , String -> P.IdrisParser (Either String Command) ) ]
3434
35+setOptions :: [(String, Opt)]
36+setOptions = [("errorcontext", ErrContext),
37+ ("showimplicits", ShowImpl),
38+ ("originalerrors", ShowOrigErr),
39+ ("autosolve", AutoSolve),
40+ ("nobanner", NoBanner),
41+ ("warnreach", WarnReach),
42+ ("evaltypes", EvalTypes),
43+ ("desugarnats", DesugarNats)]
44+
3545help :: [([String], CmdArg, String)]
36−help = (["<expr>"], NoArg, "Evaluate an expression") :
46+help = (["<expr>"], NoArg, "Evaluate an expression") :
3747 [ (map (':' :) names, args, text) | (names, args, text, _) <- parserCommandsForHelp ]
3848
3949allHelp :: [([String], CmdArg, String)]
40−allHelp = [ (map (':' :) names, args, text)
50+allHelp = [ (map (':' :) names, args, text)
4151 | (names, args, text, _) <- parserCommandsForHelp ++ parserCommands ]
4252
4353parserCommandsForHelp :: CommandTable
@@ -80,7 +90,7 @@ parserCommandsForHelp =
8090 , (["dynamic"], FileArg, "Dynamically load a C library (similar to %dynamic)", cmd_dynamic)
8191 , (["dynamic"], NoArg, "List dynamically loaded C libraries", cmd_dynamic)
8292 , noArgCmd ["?", "h", "help"] Help "Display this help text"
83− , optArgCmd ["set"] SetOpt "Set an option (errorcontext, showimplicits)"
93+ , optArgCmd ["set"] SetOpt $ "Set an option (" ++ optionsList ++ ")"
8494 , optArgCmd ["unset"] UnsetOpt "Unset an option"
8595 , (["color", "colour"], ColourArg
8696 , "Turn REPL colours on or off; set a specific colour"
@@ -100,6 +110,7 @@ parserCommandsForHelp =
100110 , "Pretty prints an Idris function in either LaTeX or HTML and for a specified width."
101111 , cmd_pprint)
102112 ]
113+ where optionsList = intercalate ", " $ map fst setOptions
103114
104115parserCommands =
105116 [ noArgCmd ["u", "universes"] Universes "Display universe constraints"
@@ -113,7 +124,7 @@ parserCommands =
113124 , exprArgCmd ["spec"] Spec "?"
114125 , exprArgCmd ["whnf"] WHNF "(Debugging) Show weak head normal form of an expression"
115126 , exprArgCmd ["inline"] TestInline "?"
116− , proofArgCmd ["cs", "casesplit"] CaseSplitAt
127+ , proofArgCmd ["cs", "casesplit"] CaseSplitAt
117128 ":cs <line> <name> splits the pattern variable on the line"
118129 , proofArgCmd ["apc", "addproofclause"] AddProofClauseFrom
119130 ":apc <line> <name> adds a pattern-matching proof clause to name on line"
@@ -127,6 +138,10 @@ parserCommands =
127138 ":mc <line> <name> adds a case block for the definition of the metavariable on the line"
128139 , proofArgCmd ["ml", "makelemma"] MakeLemma "?"
129140 , (["log"], NumberArg, "Set logging verbosity level", cmd_log)
141+ , ( ["logcats"]
142+ , ManyArgs NameArg
143+ , "Set logging categories"
144+ , cmd_cats)
130145 , (["lto", "loadto"], SeqArgs NumberArg FileArg
131146 , "Load file up to line number", cmd_loadto)
132147 , (["ps", "proofsearch"], NoArg
@@ -137,8 +152,8 @@ parserCommands =
137152 , cmd_refine)
138153 , (["debugunify"], SeqArgs ExprArg ExprArg
139154 , "(Debugging) Try to unify two expressions", const $ do
140− l <- P.simpleExpr defaultSyntax
141− r <- P.simpleExpr defaultSyntax
155+ l <- P.simpleExpr defaultSyntax
156+ r <- P.simpleExpr defaultSyntax
142157 eof
143158 return (Right (DebugUnify l r))
144159 )
@@ -160,13 +175,12 @@ proofArgCmd names command doc =
160175 (names, NoArg, doc, proofArg command)
161176
162177pCmd :: P.IdrisParser (Either String Command)
163−pCmd = choice [ do c <- cmd names; parser c
178+pCmd = choice [ do c <- cmd names; parser c
164179 | (names, _, _, parser) <- parserCommandsForHelp ++ parserCommands ]
165− <|> unrecognized
166− <|> nop
180+ <|> unrecognized
181+ <|> nop
167182 <|> eval
168183 where nop = do eof; return (Right NOP)
169− eval = exprArg Eval ""
170184 unrecognized = do
171185 P.lchar ':'
172186 cmd <- many anyChar
@@ -194,20 +208,30 @@ noArgs cmd name = do
194208
195209 emptyArgs <|> failure
196210
211+eval :: P.IdrisParser (Either String Command)
212+eval = do
213+ t <- P.fullExpr defaultSyntax
214+ return $ Right (Eval t)
215+
197216exprArg :: (PTerm -> Command) -> String -> P.IdrisParser (Either String Command)
198217exprArg cmd name = do
199218 let noArg = do
200219 eof
201220 return $ Left ("Usage is :" ++ name ++ " <expression>")
202221
222+ let justOperator = do
223+ (op, fc) <- P.operatorFC
224+ eof
225+ return $ Right $ cmd (PRef fc [] (sUN op))
226+
203227 let properArg = do
204228 t <- P.fullExpr defaultSyntax
205229 return $ Right (cmd t)
206− try noArg <|> properArg
230+ try noArg <|> try justOperator <|> properArg
207231
208232
209233
210−genArg :: String -> P.IdrisParser a -> (a -> Command)
234+genArg :: String -> P.IdrisParser a -> (a -> Command)
211235 -> String -> P.IdrisParser (Either String Command)
212236genArg argName argParser cmd name = do
213237 let emptyArgs = do eof; failure
@@ -226,12 +250,12 @@ strArg :: (String -> Command) -> String -> P.IdrisParser (Either String Command)
226250strArg = genArg "string" (many anyChar)
227251
228252moduleArg :: (FilePath -> Command) -> String -> P.IdrisParser (Either String Command)
229−moduleArg = genArg "module" (fmap (toPath . fst) P.identifier)
253+moduleArg = genArg "module" (fmap (toPath . fst) P.identifier)
230254 where
231255 toPath n = foldl1' (</>) $ splitOn "." n
232256
233257namespaceArg :: ([String] -> Command) -> String -> P.IdrisParser (Either String Command)
234−namespaceArg = genArg "namespace" (fmap (toNS . fst) P.identifier)
258+namespaceArg = genArg "namespace" (fmap (toNS . fst) P.identifier)
235259 where
236260 toNS = splitOn "."
237261
@@ -253,14 +277,7 @@ optArg cmd name = do
253277
254278 where
255279 pOption :: P.IdrisParser Opt
256− pOption = do discard (P.symbol "errorcontext"); return ErrContext
257− <|> do discard (P.symbol "showimplicits"); return ShowImpl
258− <|> do discard (P.symbol "originalerrors"); return ShowOrigErr
259− <|> do discard (P.symbol "autosolve"); return AutoSolve
260− <|> do discard (P.symbol "nobanner") ; return NoBanner
261− <|> do discard (P.symbol "warnreach"); return WarnReach
262− <|> do discard (P.symbol "evaltypes"); return EvalTypes
263− <|> do discard (P.symbol "desugarnats"); return DesugarNats
280+ pOption = foldl (<|>) empty $ map (\(a, b) -> do discard (P.symbol a); return b) setOptions
264281
265282proofArg :: (Bool -> Int -> Name -> Command) -> String -> P.IdrisParser (Either String Command)
266283proofArg cmd name = do
@@ -277,7 +294,7 @@ cmd_doc name = do
277294 c <- fmap fst P.constant
278295 eof
279296 return $ Right (DocStr (Right c) FullDocs)
280−
297+
281298 let pType = do
282299 P.reserved "Type"
283300 eof
@@ -379,6 +396,25 @@ cmd_log name = do
379396 eof
380397 return (Right (LogLvl i))
381398
399+cmd_cats :: String -> P.IdrisParser (Either String Command)
400+cmd_cats name = do
401+ cs <- sepBy pLogCats (P.whiteSpace)
402+ eof
403+ return $ Right $ LogCategory (concat cs)
404+ where
405+ badCat = do
406+ c <- fst <$> P.identifier
407+ fail $ "Category: " ++ c ++ " is not recognised."
408+
409+ pLogCats :: P.IdrisParser [LogCat]
410+ pLogCats = try (P.symbol (strLogCat IParse) >> return parserCats)
411+ <|> try (P.symbol (strLogCat IElab) >> return elabCats)
412+ <|> try (P.symbol (strLogCat ICodeGen) >> return codegenCats)
413+ <|> try (P.symbol (strLogCat ICoverage) >> return [ICoverage])
414+ <|> try (P.symbol (strLogCat IIBC) >> return [IIBC])
415+ <|> try (P.symbol (strLogCat IErasure) >> return [IErasure])
416+ <|> badCat
417+
382418cmd_let :: String -> P.IdrisParser (Either String Command)
383419cmd_let name = do
384420 defn <- concat <$> many (P.decl defaultSyntax)
src/Idris/Reflection.hs+80−56
@@ -1,11 +1,15 @@
11{-| Code related to Idris's reflection system. This module contains
22quoters and unquoters along with some supporting datatypes.
33-}
4−{-# LANGUAGE PatternGuards #-}
4+{-# LANGUAGE PatternGuards, CPP #-}
55{-# OPTIONS_GHC -fwarn-incomplete-patterns -fwarn-unused-imports #-}
66module Idris.Reflection where
77
8+#if __GLASGOW_HASKELL__ < 710
89import Control.Applicative ((<$>), (<*>), pure)
10+import Prelude hiding (mapM)
11+import Data.Traversable (mapM)
12+#endif
913import Control.Monad (liftM, liftM2, liftM4)
1014import Control.Monad.State.Strict (lift)
1115import Data.Maybe (catMaybes)
@@ -17,7 +21,7 @@ import Idris.Core.Elaborate (claim, fill, focus, getNameFrom, initElaborator,
1721import Idris.Core.Evaluate (Def(TyDecl), initContext, lookupDefExact, lookupTyExact)
1822import Idris.Core.TT
1923
20−import Idris.AbsSyntaxTree (ArgOpt(..),ElabD, IState(tt_ctxt, idris_implicits,idris_datatypes),
24+import Idris.AbsSyntaxTree (ArgOpt(..),ElabD, IState(tt_ctxt, idris_implicits,idris_datatypes, idris_patdefs),
2125 PArg'(..), PArg, PTactic, PTactic'(..), PTerm(..), Fixity (..),
2226 initEState, pairCon, pairTy)
2327import Idris.Delaborate (delab)
@@ -53,11 +57,11 @@ rFunArgToPArg (RFunArg n _ RExplicit e) = PExp 0 (rArgOpts e) n Placeholder
5357rFunArgToPArg (RFunArg n _ RImplicit e) = PImp 0 False (rArgOpts e) n Placeholder
5458rFunArgToPArg (RFunArg n _ RConstraint e) = PConstraint 0 (rArgOpts e) n Placeholder
5559
56−data RFunClause = RMkFunClause Raw Raw
57− | RMkImpossibleClause Raw
58− deriving Show
60+data RFunClause a = RMkFunClause a a
61+ | RMkImpossibleClause a
62+ deriving Show
5963
60−data RFunDefn = RDefineFun Name [RFunClause] deriving Show
64+data RFunDefn a = RDefineFun Name [RFunClause a] deriving Show
6165
6266-- | Prefix a name with the "Language.Reflection" namespace
6367reflm :: String -> Name
@@ -217,8 +221,6 @@ reifyRawApp t [n, b, x]
217221 return $ RBind n' b' x'
218222reifyRawApp t [f, x]
219223 | t == reflm "RApp" = liftM2 RApp (reifyRaw f) (reifyRaw x)
220−reifyRawApp t [t']
221− | t == reflm "RForce" = liftM RForce (reifyRaw t')
222224reifyRawApp t [c]
223225 | t == reflm "RConstant" = liftM RConstant (reifyTTConst c)
224226reifyRawApp t args = fail ("Unknown reflection raw term in reifyRawApp: " ++ show (t, args))
@@ -257,9 +259,9 @@ reifyTTNameApp t [sn]
257259 reifySN t [n]
258260 | t == reflm "MethodN" =
259261 MethodN <$> reifyTTName n
260− reifySN t [n]
262+ reifySN t [fc, n]
261263 | t == reflm "CaseN" =
262− CaseN <$> reifyTTName n
264+ CaseN <$> (FC' <$> reifyFC fc) <*> reifyTTName n
263265 reifySN t [n]
264266 | t == reflm "ElimN" =
265267 ElimN <$> reifyTTName n
@@ -270,8 +272,6 @@ reifyTTNameApp t [sn]
270272 | t == reflm "MetaN" =
271273 MetaN <$> reifyTTName n1 <*> reifyTTName n2
272274 reifySN t args = fail $ "Can't reify special name " ++ show t ++ show args
273−reifyTTNameApp t []
274− | t == reflm "NErased" = return NErased
275275reifyTTNameApp t args = fail ("Unknown reflection term name: " ++ show (t, args))
276276
277277reifyTTNamespace :: Term -> ElabD [String]
@@ -310,8 +310,6 @@ reifyTTBinderApp reif f [t, k]
310310 | f == reflm "Pi" = liftM2 (Pi Nothing) (reif t) (reif k)
311311reifyTTBinderApp reif f [x, y]
312312 | f == reflm "Let" = liftM2 Let (reif x) (reif y)
313−reifyTTBinderApp reif f [x, y]
314− | f == reflm "NLet" = liftM2 NLet (reif x) (reif y)
315313reifyTTBinderApp reif f [t]
316314 | f == reflm "Hole" = liftM Hole (reif t)
317315reifyTTBinderApp reif f [t]
@@ -361,8 +359,8 @@ reifyTTConstApp f v@(P _ _ _) =
361359reifyTTConstApp f arg = fail ("Unknown reflection constant: " ++ show (f, arg))
362360
363361reifyArithTy :: Term -> ElabD ArithTy
364−reifyArithTy (App _ (P _ n _) intTy) | n == reflm "ATInt" = fmap ATInt (reifyIntTy intTy)
365−reifyArithTy (P _ n _) | n == reflm "ATFloat" = return ATFloat
362+reifyArithTy (App _ (P _ n _) intTy) | n == reflm "ATInt" = fmap ATInt (reifyIntTy intTy)
363+reifyArithTy (P _ n _) | n == reflm "ATDouble" = return ATFloat
366364reifyArithTy x = fail ("Couldn't reify reflected ArithTy: " ++ show x)
367365
368366reifyNativeTy :: Term -> ElabD NativeTy
@@ -473,18 +471,15 @@ reflectTTQuotePattern unq (Constant c)
473471 = do fill $ reflCall "TConst" [reflectConstant c]
474472 solve
475473reflectTTQuotePattern unq (Proj t i)
476− = do t' <- claimTy (sMN 0 "t") (Var (reflm "TT")) ; movelast t'
477− fill $ reflCall "Proj" [Var t', RConstant (I i)]
478− solve
479− focus t'; reflectTTQuotePattern unq t
480−reflectTTQuotePattern unq (Erased)
474+ = lift . tfail . InternalMsg $
475+ "Phase error! The Proj constructor is for optimization only and should not have been reflected during elaboration."
476+reflectTTQuotePattern unq Erased
481477 = do erased <- claimTy (sMN 0 "erased") (Var (reflm "TT"))
482478 movelast erased
483479 fill $ (Var erased)
484− solve
485−reflectTTQuotePattern unq (Impossible)
486− = do fill $ Var (reflm "Impossible")
487− solve
480+reflectTTQuotePattern unq Impossible
481+ = lift . tfail . InternalMsg $
482+ "Phase error! The Impossible constructor is for optimization only and should not have been reflected during elaboration."
488483reflectTTQuotePattern unq (TType exp)
489484 = do ue <- getNameFrom (sMN 0 "uexp")
490485 claim ue (Var (sNS (sUN "TTUExp") ["Reflection", "Language"]))
@@ -537,7 +532,6 @@ reflectRawQuotePattern unq (RBind n b sc) =
537532 freeNamesR (RApp f x) = freeNamesR f ++ freeNamesR x
538533 freeNamesR RType = []
539534 freeNamesR (RUType _) = []
540− freeNamesR (RForce r) = freeNamesR r
541535 freeNamesR (RConstant _) = []
542536reflectRawQuotePattern unq (RApp f x) =
543537 do fH <- getNameFrom (sMN 0 "f")
@@ -560,13 +554,6 @@ reflectRawQuotePattern unq (RUType univ) =
560554 fill $ reflCall "RUType" [Var uH]
561555 solve
562556 focus uH; fill (reflectUniverse univ); solve
563−reflectRawQuotePattern unq (RForce r) =
564− do rH <- getNameFrom (sMN 0 "raw")
565− claim rH (Var (reflm "Raw"))
566− movelast rH
567− fill $ reflCall "RForce" [Var rH]
568− solve
569− focus rH; reflectRawQuotePattern unq r
570557reflectRawQuotePattern unq (RConstant c) =
571558 do cH <- getNameFrom (sMN 0 "const")
572559 claim cH (Var (reflm "Constant"))
@@ -597,7 +584,7 @@ reflectBinderQuotePattern q ty unq (Let x y)
597584reflectBinderQuotePattern q ty unq (NLet x y)
598585 = do x' <- claimTy (sMN 0 "ty") ty; movelast x'
599586 y' <- claimTy (sMN 0 "v") ty; movelast y'
600− fill $ reflCall "NLet" [ty, Var x', Var y']
587+ fill $ reflCall "Let" [ty, Var x', Var y']
601588 solve
602589 focus x'; q unq x
603590 focus y'; q unq y
@@ -649,12 +636,13 @@ reflectTTQuote unq (App _ f x)
649636 = reflCall "App" [reflectTTQuote unq f, reflectTTQuote unq x]
650637reflectTTQuote unq (Constant c)
651638 = reflCall "TConst" [reflectConstant c]
652−reflectTTQuote unq (Proj t i)
653− = reflCall "Proj" [reflectTTQuote unq t, RConstant (I i)]
654−reflectTTQuote unq (Erased) = Var (reflm "Erased")
655−reflectTTQuote unq (Impossible) = Var (reflm "Impossible")
656639reflectTTQuote unq (TType exp) = reflCall "TType" [reflectUExp exp]
657640reflectTTQuote unq (UType u) = reflCall "UType" [reflectUniverse u]
641+reflectTTQuote _ (Proj _ _) =
642+ error "Phase error! The Proj constructor is for optimization only and should not have been reflected during elaboration."
643+reflectTTQuote unq Erased = Var (reflm "Erased")
644+reflectTTQuote _ Impossible =
645+ error "Phase error! The Impossible constructor is for optimization only and should not have been reflected during elaboration."
658646
659647reflectRawQuote :: [Name] -> Raw -> Raw
660648reflectRawQuote unq (Var n)
@@ -667,7 +655,6 @@ reflectRawQuote unq (RApp f x) =
667655reflectRawQuote unq RType = Var (reflm "RType")
668656reflectRawQuote unq (RUType u) =
669657 reflCall "RUType" [reflectUniverse u]
670−reflectRawQuote unq (RForce r) = reflCall "RForce" [reflectRawQuote unq r]
671658reflectRawQuote unq (RConstant cst) = reflCall "RConstant" [reflectConstant cst]
672659
673660reflectNameType :: NameType -> Raw
@@ -692,7 +679,6 @@ reflectName (NS n ns)
692679 ]
693680reflectName (MN i n)
694681 = reflCall "MN" [RConstant (I i), RConstant (Str (str n))]
695−reflectName NErased = Var (reflm "NErased")
696682reflectName (SN sn) = raw_apply (Var (reflm "SN")) [reflectSpecialName sn]
697683reflectName (SymRef _) = error "The impossible happened: symbol table ref survived IBC loading"
698684
@@ -711,8 +697,8 @@ reflectSpecialName (ParentN n s) =
711697 reflCall "ParentN" [reflectName n, RConstant (Str (T.unpack s))]
712698reflectSpecialName (MethodN n) =
713699 reflCall "MethodN" [reflectName n]
714−reflectSpecialName (CaseN n) =
715− reflCall "CaseN" [reflectName n]
700+reflectSpecialName (CaseN fc n) =
701+ reflCall "CaseN" [reflectFC (unwrapFC fc), reflectName n]
716702reflectSpecialName (ElimN n) =
717703 reflCall "ElimN" [reflectName n]
718704reflectSpecialName (InstanceCtorN n) =
@@ -754,7 +740,7 @@ reflectBinderQuote q ty unq (Pi _ t k)
754740reflectBinderQuote q ty unq (Let x y)
755741 = reflCall "Let" [Var ty, q unq x, q unq y]
756742reflectBinderQuote q ty unq (NLet x y)
757− = reflCall "NLet" [Var ty, q unq x, q unq y]
743+ = reflCall "Let" [Var ty, q unq x, q unq y]
758744reflectBinderQuote q ty unq (Hole t)
759745 = reflCall "Hole" [Var ty, q unq t]
760746reflectBinderQuote q ty unq (GHole _ _ t)
@@ -784,7 +770,7 @@ reflectConstant c@(B32 _) = reflCall "B32" [RConstant c]
784770reflectConstant c@(B64 _) = reflCall "B64" [RConstant c]
785771reflectConstant (AType (ATInt ITNative)) = reflCall "AType" [reflCall "ATInt" [Var (reflm "ITNative")]]
786772reflectConstant (AType (ATInt ITBig)) = reflCall "AType" [reflCall "ATInt" [Var (reflm "ITBig")]]
787−reflectConstant (AType ATFloat) = reflCall "AType" [Var (reflm "ATFloat")]
773+reflectConstant (AType ATFloat) = reflCall "AType" [Var (reflm "ATDouble")]
788774reflectConstant (AType (ATInt ITChar)) = reflCall "AType" [reflCall "ATInt" [Var (reflm "ITChar")]]
789775reflectConstant StrType = Var (reflm "StrType")
790776reflectConstant (AType (ATInt (ITFixed IT8))) = reflCall "AType" [reflCall "ATInt" [reflCall "ITFixed" [Var (reflm "IT8")]]]
@@ -916,7 +902,7 @@ reflectErr (CantResolveAlts ss) =
916902 raw_apply (Var $ reflErrName "CantResolveAlts")
917903 [rawList (Var $ reflm "TTName") (map reflectName ss)]
918904reflectErr (IncompleteTerm t) = raw_apply (Var $ reflErrName "IncompleteTerm") [reflect t]
919−reflectErr (NoEliminator str t)
905+reflectErr (NoEliminator str t)
920906 = raw_apply (Var $ reflErrName "NoEliminator") [RConstant (Str str),
921907 reflect t]
922908reflectErr (UniverseError fc ue old new tys) =
@@ -954,6 +940,12 @@ reflectFC fc = raw_apply (Var (reflm "FileLoc"))
954940 ]
955941 where intTy = RConstant (AType (ATInt ITNative))
956942
943+reifyFC :: Term -> ElabD FC
944+reifyFC tm
945+ | (P (DCon _ _ _) cn _, [Constant (Str fn), st, end]) <- unApply tm
946+ , cn == reflm "FileLoc" = FC fn <$> reifyPair reifyInt reifyInt st <*> reifyPair reifyInt reifyInt end
947+ | otherwise = fail $ "Not a source location: " ++ show tm
948+
957949fromTTMaybe :: Term -> Maybe Term -- WARNING: Assumes the term has type Maybe a
958950fromTTMaybe (App _ (App _ (P (DCon _ _ _) (NS (UN just) _) _) ty) tm)
959951 | just == txt "Just" = Just tm
@@ -970,7 +962,7 @@ reifyReportPart (App _ (P (DCon _ _ _) n _) (Constant (Str msg))) | n == reflm "
970962 Right (TextPart msg)
971963reifyReportPart (App _ (P (DCon _ _ _) n _) ttn)
972964 | n == reflm "NamePart" =
973− case runElab initEState (reifyTTName ttn) (initElaborator NErased initContext emptyContext Erased) of
965+ case runElab initEState (reifyTTName ttn) (initElaborator (sMN 0 "hole") initContext emptyContext Erased) of
974966 Error e -> Left . InternalMsg $
975967 "could not reify name term " ++
976968 show ttn ++
@@ -978,7 +970,7 @@ reifyReportPart (App _ (P (DCon _ _ _) n _) ttn)
978970 OK (n', _)-> Right $ NamePart n'
979971reifyReportPart (App _ (P (DCon _ _ _) n _) tm)
980972 | n == reflm "TermPart" =
981− case runElab initEState (reifyTT tm) (initElaborator NErased initContext emptyContext Erased) of
973+ case runElab initEState (reifyTT tm) (initElaborator (sMN 0 "hole") initContext emptyContext Erased) of
982974 Error e -> Left . InternalMsg $
983975 "could not reify reflected term " ++
984976 show tm ++
@@ -986,7 +978,7 @@ reifyReportPart (App _ (P (DCon _ _ _) n _) tm)
986978 OK (tm', _) -> Right $ TermPart tm'
987979reifyReportPart (App _ (P (DCon _ _ _) n _) tm)
988980 | n == reflm "RawPart" =
989− case runElab initEState (reifyRaw tm) (initElaborator NErased initContext emptyContext Erased) of
981+ case runElab initEState (reifyRaw tm) (initElaborator (sMN 0 "hole") initContext emptyContext Erased) of
990982 Error e -> Left . InternalMsg $
991983 "could not reify reflected raw term " ++
992984 show tm ++
@@ -1033,21 +1025,21 @@ reifyTyDecl (App _ (App _ (App _ (P (DCon _ _ _) n _) tyN) args) ret)
10331025 return $ RDeclare tyN' args' ret'
10341026reifyTyDecl tm = fail $ "Couldn't reify " ++ show tm ++ " as a type declaration."
10351027
1036−reifyFunDefn :: Term -> ElabD RFunDefn
1037−reifyFunDefn (App _ (App _ (P _ n _) fnN) clauses)
1038− | n == tacN "DefineFun" =
1028+reifyFunDefn :: Term -> ElabD (RFunDefn Raw)
1029+reifyFunDefn (App _ (App _ (App _ (P _ n _) (P _ t _)) fnN) clauses)
1030+ | n == tacN "DefineFun" && t == reflm "Raw" =
10391031 do fnN' <- reifyTTName fnN
10401032 clauses' <- case unList clauses of
10411033 Nothing -> fail $ "Couldn't reify " ++ show clauses ++ " as a clause list"
10421034 Just cs -> mapM reifyC cs
10431035 return $ RDefineFun fnN' clauses'
1044− where reifyC :: Term -> ElabD RFunClause
1045− reifyC (App _ (App _ (P (DCon _ _ _) n _) lhs) rhs)
1046− | n == tacN "MkFunClause" = liftM2 RMkFunClause
1036+ where reifyC :: Term -> ElabD (RFunClause Raw)
1037+ reifyC (App _ (App _ (App _ (P (DCon _ _ _) n _) (P _ t _)) lhs) rhs)
1038+ | n == tacN "MkFunClause" && t == reflm "Raw" = liftM2 RMkFunClause
10471039 (reifyRaw lhs)
10481040 (reifyRaw rhs)
1049− reifyC (App _ (P (DCon _ _ _) n _) lhs)
1050− | n == tacN "MkImpossibleClause" = fmap RMkImpossibleClause $ reifyRaw lhs
1041+ reifyC (App _ (App _ (P (DCon _ _ _) n _) (P _ t _)) lhs)
1042+ | n == tacN "MkImpossibleClause" && t == reflm "Raw" = fmap RMkImpossibleClause $ reifyRaw lhs
10511043 reifyC tm = fail $ "Couldn't reify " ++ show tm ++ " as a clause."
10521044reifyFunDefn tm = fail $ "Couldn't reify " ++ show tm ++ " as a function declaration."
10531045
@@ -1057,6 +1049,12 @@ envTupleType
10571049 , (RApp (Var $ reflm "Binder") (Var $ reflm "TT"))
10581050 ]
10591051
1052+reflectList :: Raw -> [Raw] -> Raw
1053+reflectList ty [] = RApp (Var (sNS (sUN "Nil") ["List", "Prelude"])) ty
1054+reflectList ty (x:xs) = RApp (RApp (RApp (Var (sNS (sUN "::") ["List", "Prelude"])) ty)
1055+ x)
1056+ (reflectList ty xs)
1057+
10601058-- | Apply Idris's implicit info to get a signature. The [PArg] should
10611059-- come from a lookup in idris_implicits on IState.
10621060getArgs :: [PArg] -> Raw -> ([RFunArg], Raw)
@@ -1078,6 +1076,22 @@ unApplyRaw tm = ua [] tm
10781076 ua args (RApp f a) = ua (a:args) f
10791077 ua args t = (t, args)
10801078
1079+-- | Build the reflected function definition(s) that correspond(s) to
1080+-- a provided unqualifed name
1081+buildFunDefns :: IState -> Name -> [RFunDefn Term]
1082+buildFunDefns ist n =
1083+ [ mkFunDefn name clauses
1084+ | (name, (clauses, _)) <- lookupCtxtName n $ idris_patdefs ist
1085+ ]
1086+
1087+ where mkFunDefn name clauses = RDefineFun name (map mkFunClause clauses)
1088+
1089+ mkFunClause ([], lhs, Impossible) = RMkImpossibleClause lhs
1090+ mkFunClause ([], lhs, rhs) = RMkFunClause lhs rhs
1091+ mkFunClause (((n, ty) : ns), lhs, rhs) = mkFunClause (ns, bind lhs, bind rhs) where
1092+ bind Impossible = Impossible
1093+ bind tm = Bind n (PVar ty) tm
1094+
10811095-- | Build the reflected datatype definition(s) that correspond(s) to
10821096-- a provided unqualified name
10831097buildDatatypes :: IState -> Name -> [RDatatype]
@@ -1167,3 +1181,13 @@ reflectDatatype (RDatatype tyn tyConArgs tyConRes constrs) =
11671181 RApp (Var $ tacN "TyConParameter") (reflectArg a)
11681182 reflectConArg (RIndex a) =
11691183 RApp (Var $ tacN "TyConIndex") (reflectArg a)
1184+
1185+reflectFunClause :: RFunClause Term -> Raw
1186+reflectFunClause (RMkFunClause lhs rhs) = raw_apply (Var $ tacN "MkFunClause") $ (Var $ reflm "TT") : map reflect [ lhs, rhs ]
1187+reflectFunClause (RMkImpossibleClause lhs) = raw_apply (Var $ tacN "MkImpossibleClause") $ [ Var $ reflm "TT", reflect lhs ]
1188+
1189+reflectFunDefn :: RFunDefn Term -> Raw
1190+reflectFunDefn (RDefineFun name clauses) = raw_apply (Var $ tacN "DefineFun") [ Var $ reflm "TT"
1191+ , reflectName name
1192+ , rawList (RApp (Var $ tacN "FunClause") (Var $ reflm "TT")) (map reflectFunClause clauses)
1193+ ]
src/Pkg/PParser.hs+49−3
@@ -1,4 +1,4 @@
1−{-# LANGUAGE CPP #-}
1+{-# LANGUAGE CPP, ConstraintKinds #-}
22#if !(MIN_VERSION_base(4,8,0))
33{-# LANGUAGE OverlappingInstances #-}
44#endif
@@ -14,6 +14,8 @@ import Idris.CmdOptions
1414
1515import Control.Monad.State.Strict
1616import Control.Applicative
17+import System.FilePath (takeFileName, isValid)
18+import Data.Maybe (isNothing, fromJust)
1719
1820import Util.System
1921
@@ -62,11 +64,55 @@ pPkg = do
6264 eof
6365 return st
6466
67+
68+-- | Parses a filename.
69+-- |
70+-- | Treated for now as an identifier or a double-quoted string.
71+filename :: (MonadicParsing m, HasLastTokenSpan m) => m String
72+filename = (do
73+ filename <- token $
74+ -- Treat a double-quoted string as a filename to support spaces.
75+ -- This also moves away from tying filenames to identifiers, so
76+ -- it will also accept hyphens
77+ -- (https://github.com/idris-lang/Idris-dev/issues/2721)
78+ stringLiteral
79+ <|>
80+ -- Through at least version 0.9.19.1, IPKG executable values were
81+ -- possibly namespaced identifiers, like foo.bar.baz.
82+ show <$> fst <$> iName []
83+ case filenameErrorMessage filename of
84+ Just errorMessage -> fail errorMessage
85+ Nothing -> return filename)
86+ <?> "filename"
87+ where
88+ -- TODO: Report failing span better! We could lookAhead,
89+ -- or do something with DeltaParsing?
90+ filenameErrorMessage :: FilePath -> Maybe String
91+ filenameErrorMessage path = either Just (const Nothing) $ do
92+ checkEmpty path
93+ checkValid path
94+ checkNoDirectoryComponent path
95+ where
96+ checkThat ok message =
97+ if ok then Right () else Left message
98+
99+ checkEmpty path =
100+ checkThat (path /= "") "filename must not be empty"
101+
102+ checkValid path =
103+ checkThat (System.FilePath.isValid path)
104+ "filename must contain only valid characters"
105+
106+ checkNoDirectoryComponent path =
107+ checkThat (path == takeFileName path)
108+ "filename must contain no directory component"
109+
110+
65111pClause :: PParser ()
66112pClause = do reserved "executable"; lchar '=';
67− exec <- fst <$> iName []
113+ exec <- filename
68114 st <- get
69− put (st { execout = Just (show exec) })
115+ put (st { execout = Just exec })
70116 <|> do reserved "main"; lchar '=';
71117 main <- fst <$> iName []
72118 st <- get
src/Pkg/Package.hs+3−6
@@ -164,7 +164,7 @@ testPkg fp
164164 do m_ist <- inPkgDir pkgdesc $
165165 do make (makefile pkgdesc)
166166 -- Get a temporary file to save the tests' source in
167− (tmpn, tmph) <- tempIdr
167+ (tmpn, tmph) <- tempfile ".idr"
168168 hPutStrLn tmph $
169169 "module Test_______\n" ++
170170 concat ["import " ++ show m ++ "\n"
@@ -175,7 +175,7 @@ testPkg fp
175175 concat [show t ++ "\n "
176176 | t <- idris_tests pkgdesc]
177177 hClose tmph
178− (tmpn', tmph') <- tempfile
178+ (tmpn', tmph') <- tempfile ""
179179 hClose tmph'
180180 m_ist <- idris (Filename tmpn : NoREPL : Verbose : Output tmpn' : idris_opts pkgdesc)
181181 rawSystem tmpn' []
@@ -187,9 +187,6 @@ testPkg fp
187187 case errSpan ist of
188188 Just _ -> exitWith (ExitFailure 1)
189189 _ -> return ()
190− where tempIdr :: IO (FilePath, Handle)
191− tempIdr = do dir <- getTemporaryDirectory
192− openTempFile (normalise dir) "idristests.idr"
193190
194191-- | Install package
195192installPkg :: PkgDesc -> IO ()
@@ -214,7 +211,7 @@ testLib :: Bool -> String -> String -> IO Bool
214211testLib warn p f
215212 = do d <- getDataDir
216213 gcc <- getCC
217− (tmpf, tmph) <- tempfile
214+ (tmpf, tmph) <- tempfile ""
218215 hClose tmph
219216 let libtest = d </> "rts" </> "libtest.c"
220217 e <- rawSystem gcc [libtest, "-l" ++ f, "-o", tmpf]
src/Util/System.hs+17−10
@@ -16,15 +16,16 @@ import System.Directory (getTemporaryDirectory
1616 , removeFile
1717 , removeDirectoryRecursive
1818 , createDirectoryIfMissing
19− , doesDirectoryExist
2019 )
21−import System.FilePath ((</>), normalise, isAbsolute, dropFileName)
20+import System.FilePath ((</>), normalise)
2221import System.IO
2322import System.Info
2423import System.IO.Error
2524
2625#ifdef FREESTANDING
2726import Tools_idris
27+import System.FilePath (isAbsolute, dropFileName)
28+import System.Directory (doesDirectoryExist)
2829import System.Environment (getEnv, setEnv, getExecutablePath)
2930#endif
3031
@@ -37,9 +38,10 @@ throwIO = CE.throw
3738isWindows :: Bool
3839isWindows = os `elem` ["win32", "mingw32", "cygwin32"]
3940
40−tempfile :: IO (FilePath, Handle)
41−tempfile = do dir <- getTemporaryDirectory
42− openTempFile (normalise dir) "idris"
41+-- | Create a temp file with the extensiom ext (in the format ".xxx")
42+tempfile :: String -> IO (FilePath, Handle)
43+tempfile ext = do dir <- getTemporaryDirectory
44+ openTempFile (normalise dir) $ "idris" ++ ext
4345
4446-- | Read a source file, same as readFile but make sure the encoding is utf-8.
4547readSource :: FilePath -> IO String
@@ -65,7 +67,7 @@ isATTY = do
6567withTempdir :: String -> (FilePath -> IO a) -> IO a
6668withTempdir subdir callback
6769 = do dir <- getTemporaryDirectory
68− let tmpDir = (normalise dir) </> subdir
70+ let tmpDir = normalise dir </> subdir
6971 removeLater <- catchIO (createDirectoryIfMissing True tmpDir >> return True)
7072 (\ ioError -> if isAlreadyExistsError ioError then return False
7173 else throw ioError
@@ -75,10 +77,15 @@ withTempdir subdir callback
7577 return result
7678
7779rmFile :: FilePath -> IO ()
78−rmFile f = do putStrLn $ "Removing " ++ f
79− catchIO (removeFile f)
80− (\ioerr -> putStrLn $ "WARNING: Cannot remove file "
81− ++ f ++ ", Error msg:" ++ show ioerr)
80+rmFile f = do
81+ result <- try (removeFile f)
82+ case result of
83+ Right _ -> putStrLn $ "Removed: " ++ f
84+ Left err -> handleExists err
85+ where handleExists e
86+ | isDoesNotExistError e = return ()
87+ | otherwise = putStrLn $ "WARNING: Cannot remove file "
88+ ++ f ++ ", Error msg:" ++ show e
8289
8390setupBundledCC :: IO()
8491#ifdef FREESTANDING
stack.yaml+9−2
@@ -1,6 +1,13 @@
1−flags: {}
1+resolver: lts-3.16
22packages:
33- '.'
4+flags:
5+ idris:
6+ FFI: true
7+ GMP: True
8+ curses: True
49extra-deps:
10+- annotated-wl-pprint-0.7.0
511- cheapskate-0.1.0.4
6−resolver: nightly-2015-07-24
12+- hscurses-1.4.2.0
13+- libffi-0.1
test/Makefile+4−1
@@ -1,4 +1,4 @@
1−.PHONY: test test_java test_js update diff distclean $(TESTS)
1+.PHONY: test test_java test_js time update diff distclean $(TESTS)
22
33TESTS = $(sort $(patsubst %/,%.test,$(wildcard */)))
44
@@ -16,6 +16,9 @@ update:
1616diff:
1717 /usr/bin/env perl ./runtest.pl all -d
1818
19+time:
20+ /usr/bin/env perl ./runtest.pl all -t
21+
1922distclean:
2023 rm -f *~
2124 rm -f */output
test/basic002/test006.idr+9−9
@@ -1,21 +1,21 @@
11module Main
22
33data Parity : Nat -> Type where
4− even : {n : Nat} -> Parity (n + n)
5− odd : {n : Nat} -> Parity (S (n + n))
4+ Even : {n : Nat} -> Parity (n + n)
5+ Odd : {n : Nat} -> Parity (S (n + n))
66
77parity : (n:Nat) -> Parity n
8−parity Z = even {n=Z}
9−parity (S Z) = odd {n=Z}
8+parity Z = Even {n=Z}
9+parity (S Z) = Odd {n=Z}
1010parity (S (S k)) with (parity k)
11− parity (S (S (j + j))) | (even {n = j}) ?= even {n=S j}
12− parity (S (S (S (j + j)))) | (odd {n = j}) ?= odd {n=S j}
11+ parity (S (S (j + j))) | (Even {n = j}) ?= Even {n=S j}
12+ parity (S (S (S (j + j)))) | (Odd {n = j}) ?= Odd {n=S j}
1313
1414natToBin : Nat -> List Bool
1515natToBin Z = Nil
1616natToBin k with (parity k)
17− natToBin (j + j) | even {n = j} = False :: natToBin j
18− natToBin (S (j + j)) | odd {n = j} = True :: natToBin j
17+ natToBin (j + j) | Even {n = j} = False :: natToBin j
18+ natToBin (S (j + j)) | Odd {n = j} = True :: natToBin j
1919
2020main : IO ()
2121main = do printLn (natToBin 42)
@@ -23,7 +23,7 @@ main = do printLn (natToBin 42)
2323---------- Proofs ----------
2424
2525Main.parity_lemma_2 = proof {
26− intro;
26+ intro j;
2727 intro;
2828 rewrite sym (plusSuccRightSucc j j);
2929 trivial;
test/basic006/expected+4−1
@@ -1,4 +1,7 @@
1−test020a.idr:16:18:When checking right hand side of foo:
1+test020a.idr:16:18:
2+When checking right hand side of foo with expected type
3+ List a
4+
25When checking an application of function Prelude.List.reverse:
36 Type mismatch between
47 Vect n a (Type of xs)
test/basic009/expected+4−1
@@ -1,5 +1,8 @@
11MAIN-PASS
2−Faulty.idr:7:7:When checking right hand side of fault:
2+Faulty.idr:7:7:
3+When checking right hand side of fault with expected type
4+ num = 0
5+
36Type mismatch between
47 0 = 0 (Type of Refl)
58and
test/basic010/Main.idr+13−13
@@ -9,32 +9,32 @@ qib (S Z) = 2
99qib (S (S n)) = qib n * qib (S n)
1010
1111-- 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
12+data Equals : Nat -> Nat -> Type where
13+ EqZ : Z `Equals` Z
14+ EqS : m `Equals` n -> S m `Equals` S n
1515
16−eq_refl : {n : Nat} -> n `equals` n
17−eq_refl {n = Z} = eqZ
18−eq_refl {n = S n} = eqS eq_refl
16+eq_refl : {n : Nat} -> n `Equals` n
17+eq_refl {n = Z} = EqZ
18+eq_refl {n = S n} = EqS eq_refl
1919
2020-- Here, the proof is very expensive to compute.
2121-- 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)
22+f : (r, n : Nat) -> Subset Nat (\k => qib n `Equals` qib k)
2323f Z n = Element n eq_refl
2424f (S r) n = f r n
2525
2626-- A (contrived) relation, just to have something to show.
27−data represents : Nat -> Nat -> Type where
28− axiom : (n : Nat) -> qib n `represents` n
27+data Represents : Nat -> Nat -> Type where
28+ Axiom : (n : Nat) -> qib n `Represents` n
2929
3030-- Here, the witness is very expensive to compute.
3131-- 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)
32+g : (r, n : Nat) -> Exists (\k : Nat => k `Represents` n)
33+g Z n = Evidence (qib n) (Axiom n)
3434g (S r) n = g r n
3535
36−fmt : qib n `represents` n -> String
37−fmt (axiom n) = "axiom " ++ show n
36+fmt : qib n `Represents` n -> String
37+fmt (Axiom n) = "Axiom " ++ show n
3838
3939main : IO ()
4040main = do
test/basic010/expected+1−1
@@ -1,3 +1,3 @@
11*oink*
2210000
3−axiom 10000
3+Axiom 10000
test/basic016/CycleA.idrnew file+4
@@ -0,0 +1,4 @@
1+module CycleA
2+
3+import CycleB
4+
test/basic016/CycleB.idrnew file+5
@@ -0,0 +1,5 @@
1+module CycleB
2+
3+import CycleC
4+
5+
test/basic016/CycleC.idrnew file+4
@@ -0,0 +1,4 @@
1+module CycleC
2+
3+import CycleA
4+
test/basic016/expectednew file+1
@@ -0,0 +1 @@
1+Cycle detected in imports: CycleA.idr -> CycleB -> CycleC -> CycleA -> CycleB
test/basic016/runnew file+3
@@ -0,0 +1,3 @@
1+#!/usr/bin/env bash
2+idris $@ CycleA.idr --consolewidth 80 --nocolour --check
3+rm -f *.ibc
test/docs003/expected+4−3
@@ -1,12 +1,13 @@
11Type class Functor
2− Functors
2+ Functors allow a uniform action over a parameterised type.
33
44Parameters:
5− f -- the action of the functor on objects
5+ f -- a parameterised type
66
77Methods:
88 map : Functor f => (m : a -> b) -> f a -> f b
9− The action of the functor on morphisms
9+ Apply a function across everything of type 'a' in a
10+ parameterised type
1011
1112 The function is Total
1213Instances:
test/dsl001/test001.idr+10−10
@@ -17,13 +17,13 @@ using (G : Vect n Ty)
1717 (::) : interpTy a -> Env G -> Env (a :: G)
1818
1919 data HasType : (i : Fin n) -> Vect n Ty -> Ty -> Type where
20− stop : HasType FZ (t :: G) t
21− pop : HasType k G t -> HasType (FS k) (u :: G) t
20+ Stop : HasType FZ (t :: G) t
21+ Pop : HasType k G t -> HasType (FS k) (u :: G) t
2222
2323 lookup : HasType i G t -> Env G -> interpTy t
24− lookup stop (x :: xs) = x
25− lookup (pop k) (x :: xs) = lookup k xs
26− lookup stop [] impossible
24+ lookup Stop (x :: xs) = x
25+ lookup (Pop k) (x :: xs) = lookup k xs
26+ lookup Stop [] impossible
2727
2828 data Expr : Vect n Ty -> Ty -> Type where
2929 Var : HasType i G t -> Expr G t
@@ -41,8 +41,8 @@ using (G : Vect n Ty)
4141 dsl expr
4242 lambda = lam_
4343 variable = Var
44− index_first = stop
45− index_next = pop
44+ index_first = Stop
45+ index_next = Pop
4646
4747 total
4848 interp : Env G -> [static] (e : Expr G t) -> interpTy t
@@ -67,7 +67,7 @@ using (G : Vect n Ty)
6767-- eDouble = Lam (App (App (Lam (Lam (Op' (+) (Var FZ) (Var (FS FZ))))) (Var FZ)) (Var FZ))
6868
6969 eDouble : Expr G (TyFun TyInt TyInt)
70− eDouble = expr (\x => App (App eAdd x) (Var stop))
70+ eDouble = expr (\x => App (App eAdd x) (Var Stop))
7171
7272-- app : Lazy (Expr G (TyFun a t)) -> Expr G a -> Expr G t
7373-- app = \f, a => App (Force f) a
@@ -81,8 +81,8 @@ using (G : Vect n Ty)
8181
8282 eProg : Expr G (TyFun TyInt (TyFun TyInt TyInt))
8383 eProg = Lam (Lam
84− (Bind (App eDouble (Var (pop stop)))
85− (\x => Bind (App eDouble (Var stop))
84+ (Bind (App eDouble (Var (Pop Stop)))
85+ (\x => Bind (App eDouble (Var Stop))
8686 (\y => Bind (App eDouble (Val x))
8787 (\z => App (App eAdd (Val y)) (Val z))))))
8888
test/dsl002/Resimp.idr+15−15
@@ -49,35 +49,35 @@ using (i: Fin n, gam : Vect n Ty, gam' : Vect n Ty, gam'' : Vect n Ty)
4949 interpTy (a :-> b) = a -> interpTy b
5050
5151 data HasType : Vect n Ty -> Fin n -> Ty -> Type where
52− stop : HasType (a :: gam) FZ a
53− pop : HasType gam i b -> HasType (a :: gam) (FS i) b
52+ Stop : HasType (a :: gam) FZ a
53+ Pop : HasType gam i b -> HasType (a :: gam) (FS i) b
5454
5555 data Env : Vect n Ty -> Type where
5656 Nil : Env Nil
5757 (::) : interpTy a -> Env gam -> Env (a :: gam)
5858
5959 envLookup : HasType gam i a -> Env gam -> interpTy a
60− envLookup stop (x :: xs) = x
61− envLookup (pop k) (x :: xs) = envLookup k xs
60+ envLookup Stop (x :: xs) = x
61+ envLookup (Pop k) (x :: xs) = envLookup k xs
6262
6363 update : (gam : Vect n Ty) -> HasType gam i b -> Ty -> Vect n Ty
64− update (x :: xs) stop y = y :: xs
65− update (x :: xs) (pop k) y = x :: update xs k y
66− update Nil stop _ impossible
64+ update (x :: xs) Stop y = y :: xs
65+ update (x :: xs) (Pop k) y = x :: update xs k y
66+ update Nil Stop _ impossible
6767
6868 total
6969 envUpdate : (p:HasType gam i a) -> (val:interpTy b) ->
7070 Env gam -> Env (update gam p b)
71− envUpdate stop val (x :: xs) = val :: xs
72− envUpdate (pop k) val (x :: xs) = x :: envUpdate k val xs
73− envUpdate stop _ Nil impossible
71+ envUpdate Stop val (x :: xs) = val :: xs
72+ envUpdate (Pop k) val (x :: xs) = x :: envUpdate k val xs
73+ envUpdate Stop _ Nil impossible
7474
7575 total
7676 envUpdateVal : (p:HasType gam i a) -> (val:b) ->
7777 Env gam -> Env (update gam p (Val b))
78− envUpdateVal stop val (x :: xs) = val :: xs
79− envUpdateVal (pop k) val (x :: xs) = x :: envUpdateVal k val xs
80− envUpdateVal stop _ Nil impossible
78+ envUpdateVal Stop val (x :: xs) = val :: xs
79+ envUpdateVal (Pop k) val (x :: xs) = x :: envUpdateVal k val xs
80+ envUpdateVal Stop _ Nil impossible
8181
8282 envTail : Env (a :: gam) -> Env gam
8383 envTail (x :: xs) = xs
@@ -169,8 +169,8 @@ syntax run [prog] = interp [] prog (\env, res => res)
169169dsl res
170170 variable = id
171171 let = let_
172− index_first = stop
173− index_next = pop
172+ index_first = Stop
173+ index_next = Pop
174174
175175syntax RES [x] = {gam:Vect n Ty} -> Res gam gam (R x)
176176
test/dsl002/test014.idr+7−6
@@ -15,19 +15,20 @@ syntax "ifM" [test] "then" [t] "else" [e]
1515 = test >>= (\b => if b then t else e)
1616
1717open : String -> (p:Purpose) -> Creator (Either () (FILE p))
18−open fn p = ioc (do h <- fopen fn (pstring p)
19− ifM validFile h
20− then return (Right (OpenH h))
21− else return (Left ()))
18+open fn p = ioc (do Right h <- fopen fn (pstring p)
19+ | Left err => return (Left ())
20+ return (Right (OpenH h)))
2221
2322close : FILE p -> Updater ()
2423close (OpenH h) = iou (closeFile h)
2524
2625readLine : FILE Reading -> Reader String
27−readLine (OpenH h) = ior (fread h)
26+readLine (OpenH h) = ior (do Right str <- fGetLine h
27+ | return ""
28+ return str)
2829
2930eof : FILE Reading -> Reader Bool
30−eof (OpenH h) = ior (feof h)
31+eof (OpenH h) = ior (fEOF h)
3132
3233syntax rclose [h] = Update close h
3334syntax rreadLine [h] = Use readLine h
test/effects003/foodeleted−9236

This diff is too big to show here.

test/effects003/hangman.idr+1−1

This diff is too big to show here.

test/error003/expected+4−1

This diff is too big to show here.

test/error004/expected+8−2

This diff is too big to show here.

test/error005/expected+20−5

This diff is too big to show here.

test/error006/WithPatsNoWith.idrnew file+6

This diff is too big to show here.

test/error006/expectednew file+2

This diff is too big to show here.

test/error006/runnew file+3

This diff is too big to show here.

test/ffi001/test022.idr+2−2

This diff is too big to show here.

test/ffi004/test026.idr+2−1

This diff is too big to show here.

test/interactive001/expected+6

This diff is too big to show here.

test/interactive001/input+2

This diff is too big to show here.

test/interactive001/test032.idr+9

This diff is too big to show here.

test/interactive010/expectednew file+22

This diff is too big to show here.

test/interactive010/inputnew file+10

This diff is too big to show here.

test/interactive010/runnew file+2

This diff is too big to show here.

test/interactive011/expectednew file+3

This diff is too big to show here.

test/interactive011/inputnew file+2

This diff is too big to show here.

test/interactive011/interactive011.idrnew file+11

This diff is too big to show here.

test/interactive011/runnew file+3

This diff is too big to show here.

test/interactive012/expectednew file+33

This diff is too big to show here.

test/interactive012/inputnew file+9

This diff is too big to show here.

test/interactive012/interactive012.idrnew file+26

This diff is too big to show here.

test/interactive012/runnew file+3

This diff is too big to show here.

test/io001/test004.idr+6−6

This diff is too big to show here.

test/meta001/Finite.idr+13−13

This diff is too big to show here.

test/meta002/AgdaStyleReflection.idrnew file+247

This diff is too big to show here.

test/meta002/Deriving.idrnew file+33

This diff is too big to show here.

test/meta002/Tacs.idr+12−4

This diff is too big to show here.

test/meta002/expected+9−2

This diff is too big to show here.

test/meta002/run+4−1

This diff is too big to show here.

test/meta004/expectednew file+3

This diff is too big to show here.

test/meta004/meta004.idrnew file+48

This diff is too big to show here.

test/meta004/runnew file+3

This diff is too big to show here.

test/pkg001/expected−1

This diff is too big to show here.

test/pkg001/test.ipkg+1−1

This diff is too big to show here.

test/pkg002/Main.idrnew file+4

This diff is too big to show here.

test/pkg002/expectednew file

No changes to the content.

test/pkg002/runnew file+5

This diff is too big to show here.

test/pkg002/test.ipkgnew file+8

This diff is too big to show here.

test/pkg003/Main.idrnew file+4

This diff is too big to show here.

test/pkg003/expectednew file

No changes to the content.

test/pkg003/runnew file+6

This diff is too big to show here.

test/pkg003/test.ipkgnew file+7

This diff is too big to show here.

test/pkg004/Main.idrnew file+4

This diff is too big to show here.

test/pkg004/expectednew file+5

This diff is too big to show here.

test/pkg004/runnew file+6

This diff is too big to show here.

test/pkg004/test.ipkgnew file+9

This diff is too big to show here.

test/proof002/expected+3−1

This diff is too big to show here.

test/proof003/Parity.idr+6−6

This diff is too big to show here.

test/proof003/test015.idr+12−12

This diff is too big to show here.

test/proof005/DefaultArgSubstitutionSuccess.idr+4−4

This diff is too big to show here.

test/proof006/DefaultArgSubstitutionSyntax.idr+4−4

This diff is too big to show here.

test/proof007/expected+3−1

This diff is too big to show here.

test/proofsearch002/Process.idr+3−3

This diff is too big to show here.

test/proofsearch002/proofsearch002.idr−3

This diff is too big to show here.

test/pruviloj001/pruviloj001.idr+1−9

This diff is too big to show here.

test/quasiquote001/expected+2−2

This diff is too big to show here.

test/quasiquote003/expected+4−1

This diff is too big to show here.

test/quasiquote004/expected+3−1

This diff is too big to show here.

test/quasiquote006/expected+9−3

This diff is too big to show here.

test/reg001/reg001.idr+31

This diff is too big to show here.

test/reg006/expected+1−1

This diff is too big to show here.

test/reg007/expected+4−1

This diff is too big to show here.

test/reg023/expected+4−1

This diff is too big to show here.

test/reg035/reg035a.lidr+5−5

This diff is too big to show here.

test/reg041/expected+1−1

This diff is too big to show here.

test/reg041/ott.idr+24−24

This diff is too big to show here.

test/reg044/expected+4−1

This diff is too big to show here.

test/reg046/reg046.idr+7−7

This diff is too big to show here.

test/reg047/reg047.idr+2−2

This diff is too big to show here.

test/reg047/reg047a.idr+3−3

This diff is too big to show here.

test/reg049/expected+4−1

This diff is too big to show here.

test/reg067/expectednew file+1

This diff is too big to show here.

test/reg067/reg067.idrnew file+23

This diff is too big to show here.

test/reg067/runnew file+5

This diff is too big to show here.

test/runtest.pl+60−6

This diff is too big to show here.

test/syntax001/expected+8−2

This diff is too big to show here.

test/totality002/test017.idr+6−6

This diff is too big to show here.

test/totality004/totality004.idr+7−7

This diff is too big to show here.

test/totality004/totality004a.idr+7−7

This diff is too big to show here.

test/totality008/expected+1−1

This diff is too big to show here.

test/totality008/totality008.idr+4−4

This diff is too big to show here.

test/totality009/expected+8−8

This diff is too big to show here.

test/tutorial002/tutorial002.idr+15−15

This diff is too big to show here.

test/tutorial006/expected+8−3

This diff is too big to show here.

test/tutorial006/run+1

This diff is too big to show here.

test/tutorial006/tutorial006b.idr+6−6

This diff is too big to show here.

test/tutorial006/tutorial006c.idrnew file+20

This diff is too big to show here.