on master help sign in
Merge remote-tracking branch 'upstream/master' into semantic-pprint

Conflicts: src/Idris/AbsSyntaxTree.hs src/Idris/Delaborate.hs

commitc0cc1ddde44420929d59a9fac79bbedcc2b70625 authorDavid Raymond Christiansen <david@davidchristiansen.dk> dateMon 27 Jan 2014, 04:06 (13 years ago) parentdc4ce0cfe3f03f
49 files changed+1453−213
CHANGELOG+4 CONTRIBUTING.md+37−13 CONTRIBUTORS+2 idris.cabal+13 libs/Makefile+3 libs/base/Data/Fun.idr+8 libs/base/Data/Rel.idr+13 libs/base/Decidable/Decidable.idr+9−5 libs/base/Decidable/Order.idr+2−6 libs/base/Language/Reflection/Errors.idr+1 libs/base/base.ipkg+2−1 libs/effects/Effects.idr+1 libs/neweffects/Effect/Default.idr+44 libs/neweffects/Effect/Exception.idr+39 libs/neweffects/Effect/File.idr+62 libs/neweffects/Effect/Memory.idr+175 libs/neweffects/Effect/Monad.idr+21 libs/neweffects/Effect/Random.idr+25 libs/neweffects/Effect/Select.idr+23 libs/neweffects/Effect/State.idr+40 libs/neweffects/Effect/StdIO.idr+63 libs/neweffects/Effects.idr+269 libs/neweffects/Makefile+14 libs/neweffects/neweffects.ipkg+9 libs/prelude/Prelude.idr+6−2 rts/idris_stdfgn.c+4 rts/idris_stdfgn.h+1 src/IRTS/CodegenJavaScript.hs+119−20 src/Idris/AbsSyntax.hs+8−4 src/Idris/AbsSyntaxTree.hs+41−20 src/Idris/Core/Elaborate.hs+19−11 src/Idris/Core/Evaluate.hs+9−8 src/Idris/Core/TT.hs+105−32 src/Idris/Core/Unify.hs+25−5 src/Idris/Coverage.hs+5−5 src/Idris/DeepSeq.hs+4−1 src/Idris/Delaborate.hs+37−35 src/Idris/ElabDecls.hs+24−8 src/Idris/ElabTerm.hs+8−7 src/Idris/ErrReverse.hs+72 src/Idris/IBC.hs+43−13 src/Idris/ParseData.hs+10−4 src/Idris/ParseExpr.hs+9−9 src/Idris/Parser.hs+2 src/Idris/Providers.hs+1−1 src/Idris/REPL.hs+1−1 src/Util/Zlib.hs+15 test/reg031/expected+1−1 test/reg031/reg031.idr+5−1
CHANGELOG+4
@@ -7,12 +7,16 @@ New in 0.9.11:
77 This is intended for field/effect disambiguation. "name" can be any
88 valid identifier. Two labels are definitionally equal if they have the
99 same name.
10+* General improvements in error messages, especially %error_reverse
11+ annotation, which allows a hint as to how to display a term in error
12+ messages
1013
1114Internal changes
1215
1316* Faster elaboration
1417* Smaller .ibc files
1518
19+
1620New in 0.9.10:
1721--------------
1822
CONTRIBUTING.md+37−13
@@ -30,34 +30,54 @@ Please clean up any messes that you find, and don't leave behind new messes for
3030Idris developers and hackers try to adhere to something similar to the [successful git branching model](http://nvie.com/posts/a-successful-git-branching-model/).
3131The steps are straightforward.
3232
33+### New contributors
34+
3335For those new to the project:
3436
35−1. Fork the `idris-dev` repo e.g.
37+1. Fork our [main development repository](https://github.com/idris-lang/Idris-dev) `idris-dev` on github e.g.
38+2. Clone your fork to your local machine:
39+
40+```
41+$ git clone git@github.com/<your github user name>/Idris-dev.git
42+```
43+
44+3. Add `idris-lang/Idris-dev` as a remote upstream
3645
37− $ git clone git@github.com/<your github user name>/Idris-dev.git
38− $ git remote add upstream git@github.com:idris-lang/Idris-dev.git
46+```
47+$ git remote add upstream git@github.com:idris-lang/Idris-dev.git
48+```
49+
50+### Existing Contributors
3951
4052For those already contributing to the project:
4153
42−1. Ensure your existing clone is up-to-date with current HEAD e.g.
54+1. Ensure your existing clone is up-to-date with current `HEAD` e.g.
55+
56+```
57+$ git fetch upstream
58+$ git merge upstream/master
59+```
4360
44− $ git fetch upstream
45− $ git merge upstream/master
61+### Remaining Steps
4662
47−The remaining steps are the same:
63+The remaining steps are the same for both new and existing contributors:
4864
49651. Create, and checkout onto, a topic branch on which to base you work.
5066 * This is typically the master branch.
5167 * For your own sanity, please avoid working on the `master` branch.
5268
53− $ git branch fix/master/my_contrib master
54− $ git checkout fix/master/my_contrib
69+```
70+$ git branch fix/master/my_contrib master
71+$ git checkout fix/master/my_contrib
72+```
5573
56741. Make commits of logical units.
57751. Check for unnecessary whitespace with
5876
59− $ git diff --check
60−
77+```
78+$ git diff --check
79+```
80+
61811. Make sure your commit messages are along the lines of:
6282
6383 Short (50 chars or less) summary of changes
@@ -79,11 +99,15 @@ The remaining steps are the same:
79991. Make sure you have added any necessary tests for your changes.
801001. Run all the tests to assure nothing else was accidentally broken.
81101
82− $ make test
102+```
103+$ make test
104+```
83105
841061. Push your changes to a topic branch in your fork of the repository.
85107
86− $ git push origin fix/master/my_contrib
108+```
109+$ git push origin fix/master/my_contrib
110+```
87111
881121. Go to GitHub and submit a pull request to `idris-dev`
89113
CONTRIBUTORS+2
@@ -15,6 +15,7 @@ Hannes Mehnert
1515Mekeor Melire
1616Melissa Mozifian
1717Dominic Mulligan
18+Jan de Muijnck-Hughes
1819raichoo
1920Tom Prince
2021Seo Sanghyeon
@@ -26,3 +27,4 @@ Leif Warner
2627Daniel Waterworth
2728Jonas Westerlund
2829Reynir Reynisson
30+
idris.cabal+13
@@ -95,6 +95,11 @@ Extra-source-files:
9595 libs/effects/Effect/*.idr
9696 libs/effects/*.idr
9797
98+ libs/neweffects/Makefile
99+ libs/neweffects/neweffects.ipkg
100+ libs/neweffects/Effect/*.idr
101+ libs/neweffects/*.idr
102+
98103 libs/javascript/*.idr
99104 libs/javascript/JavaScript/*.idr
100105 libs/javascript/Makefile
@@ -192,6 +197,12 @@ Extra-source-files:
192197 test/reg029/run
193198 test/reg029/*.idr
194199 test/reg029/expected
200+ test/reg030/run
201+ test/reg030/*.idr
202+ test/reg030/expected
203+ test/reg031/run
204+ test/reg031/*.idr
205+ test/reg031/expected
195206 test/test001/run
196207 test/test001/*.idr
197208 test/test001/expected
@@ -366,6 +377,7 @@ Library
366377 , Idris.ElabDecls
367378 , Idris.ElabTerm
368379 , Idris.Error
380+ , Idris.ErrReverse
369381 , Idris.Help
370382 , Idris.IBC
371383 , Idris.IdeSlave
@@ -412,6 +424,7 @@ Library
412424 Util.Pretty
413425 , Util.System
414426 , Util.Net
427+ , Util.Zlib
415428
416429 , Pkg.PParser
417430
libs/Makefile+3
@@ -2,6 +2,7 @@ build:
22 $(MAKE) -C prelude build
33 $(MAKE) -C base build
44 $(MAKE) -C effects build
5+ $(MAKE) -C neweffects build
56 $(MAKE) -C javascript build
67
78
@@ -9,12 +10,14 @@ install:
910 $(MAKE) -C prelude install
1011 $(MAKE) -C base install
1112 $(MAKE) -C effects install
13+ $(MAKE) -C neweffects install
1214 $(MAKE) -C javascript install
1315
1416clean:
1517 $(MAKE) -C prelude clean
1618 $(MAKE) -C base clean
1719 $(MAKE) -C effects clean
20+ $(MAKE) -C neweffects clean
1821 $(MAKE) -C javascript clean
1922
2023.PHONY: build install clean
libs/base/Data/Fun.idrnew file+8
@@ -0,0 +1,8 @@
1+module Data.Fun
2+
3+--------------------------------------------------------------------------------
4+-- Build an n-ary function type from a Vect of Types and a result type
5+--------------------------------------------------------------------------------
6+Fun : Vect n Type -> Type -> Type
7+Fun [] r = r
8+Fun (t::ts) r = t -> Fun ts r
libs/base/Data/Rel.idrnew file+13
@@ -0,0 +1,13 @@
1+module Data.Rel
2+
3+import Data.Fun
4+
5+--------------------------------------------------------------------------------
6+-- Build an n-ary relation type from a Vect of Types
7+--------------------------------------------------------------------------------
8+Rel : Vect n Type -> Type
9+Rel ts = Fun ts Type
10+
11+liftRel : (ts : Vect n Type) -> (p : Rel ts) -> (Type -> Type) -> Type
12+liftRel [] p f = f p
13+liftRel (t :: ts) p f = (x : t) -> liftRel ts (p x) f
libs/base/Decidable/Decidable.idr+9−5
@@ -1,17 +1,21 @@
11module Decidable.Decidable
22
3+import Data.Rel
4+
35%access public
46
57--------------------------------------------------------------------------------
68-- Typeclass for decidable n-ary Relations
79--------------------------------------------------------------------------------
810
9−using (t : Type)
10− class Rel (p : t) where
11− total liftRel : (Type -> Type) -> Type
11+-- Note: Instance resolution for Decidable is likely to not work in the REPL
12+-- at the moment.
13+class Decidable (ts : Vect k Type) (p : Rel ts) where
14+ total decide : liftRel ts p Dec
1215
13− class (Rel p) => Decidable (p : t) where
14− total decide : liftRel {p} Dec
16+-- 'No such variable {k506}'
17+--decision : Decidable ts p => (ts : Vect k Type) -> (p : Rel ts) -> liftRel ts p Dec
18+--decision ts p = decide {ts} {p}
1519
1620using (P : Type, p : P)
1721 data Given : Dec P -> Type where
libs/base/Decidable/Order.idr+2−6
@@ -71,12 +71,8 @@ decideNatLTE x (S y) with (decEq x (S y))
7171 | Yes nLTEm = Yes (nLTESm nLTEm)
7272 | No nGTm = No (nGTSm nGTm)
7373
74−instance Rel NatLTE where
75− liftRel P = (n : Nat) -> (m : Nat) -> P (NatLTE n m)
76−
77−instance Decidable NatLTE where
74+instance Decidable [Nat,Nat] NatLTE where
7875 decide = decideNatLTE
7976
8077lte : (m : Nat) -> (n : Nat) -> Dec (NatLTE m n)
81−lte m n = decide {p = NatLTE} m n
82−
78+lte m n = decide {ts = [Nat,Nat]} {p = NatLTE} m n
libs/base/Language/Reflection/Errors.idr+1
@@ -15,6 +15,7 @@ data Err = Msg String
1515 -- unification succeed
1616 | InfiniteUnify TTName TT (List (TTName, TT))
1717 | CantConvert TT TT (List (TTName, TT))
18+ | CantSolveGoal TT (List (TTName, TT))
1819 | UnifyScope TTName TTName TT (List (TTName, TT))
1920 | CantInferType String
2021 | NonFunctionType TT TT
libs/base/base.ipkg+2−1
@@ -23,7 +23,8 @@ modules = System,
2323 Data.ZZ, Data.Sign,
2424 Data.SortedMap, Data.SortedSet, Data.BoundedList,
2525 Data.Vect, Data.HVect, Data.Vect.Quantifiers,
26− Data.Floats, Data.Complex, Data.Heap,
26+ Data.Floats, Data.Complex, Data.Heap, Data.Fun,
27+ Data.Rel,
2728
2829 Control.Isomorphism,
2930 Control.Monad.Identity,
libs/effects/Effects.idr+1
@@ -10,6 +10,7 @@ import Control.Catchable
1010Effect : Type
1111Effect = Type -> Type -> Type -> Type
1212
13+%error_reverse
1314data EFFECT : Type where
1415 MkEff : Type -> Effect -> EFFECT
1516
libs/neweffects/Effect/Default.idrnew file+44
@@ -0,0 +1,44 @@
1+module Default
2+
3+class Default a where
4+ default : a
5+
6+instance Default Int where
7+ default = 0
8+
9+instance Default Integer where
10+ default = 0
11+
12+instance Default Float where
13+ default = 0
14+
15+instance Default Nat where
16+ default = 0
17+
18+instance Default Char where
19+ default = '\0'
20+
21+instance Default String where
22+ default = ""
23+
24+instance Default Bool where
25+ default = False
26+
27+instance Default () where
28+ default = ()
29+
30+instance (Default a, Default b) => Default (a, b) where
31+ default = (default, default)
32+
33+instance Default (Maybe a) where
34+ default = Nothing
35+
36+instance Default (List a) where
37+ default = []
38+
39+instance Default a => Default (Vect n a) where
40+ default = mkDef _ where
41+ mkDef : (n : Nat) -> Vect n a
42+ mkDef Z = []
43+ mkDef (S k) = default :: mkDef k
44+
libs/neweffects/Effect/Exception.idrnew file+39
@@ -0,0 +1,39 @@
1+module Effect.Exception
2+
3+import Effects
4+import System
5+import Control.IOExcept
6+
7+data Exception : Type -> Effect where
8+ Raise : a -> { () } Exception a b
9+
10+instance Handler (Exception a) Maybe where
11+ handle _ (Raise e) k = Nothing
12+
13+instance Show a => Handler (Exception a) IO where
14+ handle _ (Raise e) k = do print e
15+ believe_me (exit 1)
16+
17+instance Handler (Exception a) (IOExcept a) where
18+ handle _ (Raise e) k = ioM (return (Left e))
19+
20+instance Handler (Exception a) (Either a) where
21+ handle _ (Raise e) k = Left e
22+
23+EXCEPTION : Type -> EFFECT
24+EXCEPTION t = MkEff () (Exception t)
25+
26+raise : a -> { [EXCEPTION a ] } Eff m b
27+raise err = Raise err
28+
29+
30+
31+
32+
33+
34+-- TODO: Catching exceptions mid program?
35+-- probably need to invoke a new interpreter
36+
37+-- possibly add a 'handle' to the Eff language so that an alternative
38+-- handler can be introduced mid interpretation?
39+
libs/neweffects/Effect/File.idrnew file+62
@@ -0,0 +1,62 @@
1+module Effect.File
2+
3+import Effects
4+import Control.IOExcept
5+
6+data OpenFile : Mode -> Type where
7+ FH : File -> OpenFile m
8+
9+openOK : Mode -> Bool -> Type
10+openOK m True = OpenFile m
11+openOK m False = ()
12+
13+data FileIO : Effect where
14+ Open : String -> (m : Mode) ->
15+ {() ==> if result then OpenFile m else ()} FileIO Bool
16+ Close : {OpenFile m ==> ()} FileIO ()
17+
18+ ReadLine : {OpenFile Read} FileIO String
19+ WriteLine : String -> {OpenFile Write} FileIO ()
20+ EOF : {OpenFile Read} FileIO Bool
21+
22+instance Handler FileIO IO where
23+ handle () (Open fname m) k = do h <- openFile fname m
24+ valid <- validFile h
25+ if valid then k True (FH h)
26+ else k False ()
27+ handle (FH h) Close k = do closeFile h
28+ k () ()
29+ handle (FH h) ReadLine k = do str <- fread h
30+ k str (FH h)
31+ handle (FH h) (WriteLine str) k = do fwrite h str
32+ k () (FH h)
33+ handle (FH h) EOF k = do e <- feof h
34+ k e (FH h)
35+
36+FILE_IO : Type -> EFFECT
37+FILE_IO t = MkEff t FileIO
38+
39+open : Handler FileIO e =>
40+ String -> (m : Mode) ->
41+ { [FILE_IO ()] ==> [FILE_IO (if result then OpenFile m else ())] } Eff e Bool
42+open f m = Open f m
43+
44+close : Handler FileIO e =>
45+ { [FILE_IO (OpenFile m)] ==> [FILE_IO ()] } Eff e ()
46+close = Close
47+
48+readLine : Handler FileIO e =>
49+ { [FILE_IO (OpenFile Read)] } Eff e String
50+readLine = ReadLine
51+
52+writeLine : Handler FileIO e =>
53+ String -> { [FILE_IO (OpenFile Write)] } Eff e ()
54+writeLine str = WriteLine str
55+
56+eof : Handler FileIO e =>
57+ { [FILE_IO (OpenFile Read)] } Eff e Bool
58+eof = EOF
59+
60+
61+
62+
libs/neweffects/Effect/Memory.idrnew file+175
@@ -0,0 +1,175 @@
1+module Effect.Memory
2+
3+import Effects
4+import Control.IOExcept
5+
6+%access public
7+
8+abstract
9+data MemoryChunk : Nat -> Nat -> Type where
10+ CH : Ptr -> MemoryChunk size initialized
11+
12+abstract
13+data RawMemory : Effect where
14+ Allocate : (n : Nat) ->
15+ RawMemory () () (\v => MemoryChunk n 0)
16+ Free : RawMemory () (MemoryChunk n i) (\v => ())
17+ Initialize : Bits8 ->
18+ (size : Nat) ->
19+ so (i + size <= n) ->
20+ RawMemory () (MemoryChunk n i) (\v => MemoryChunk n (i + size))
21+ Peek : (offset : Nat) ->
22+ (size : Nat) ->
23+ so (offset + size <= i) ->
24+ RawMemory (Vect size Bits8)
25+ (MemoryChunk n i) (\v => MemoryChunk n i)
26+ Poke : (offset : Nat) ->
27+ (Vect size Bits8) ->
28+ so (offset <= i && offset + size <= n) ->
29+ RawMemory () (MemoryChunk n i) (\v => MemoryChunk n (max i (offset + size)))
30+ Move : (src : MemoryChunk src_size src_init) ->
31+ (dst_offset : Nat) ->
32+ (src_offset : Nat) ->
33+ (size : Nat) ->
34+ so (dst_offset <= dst_init && dst_offset + size <= dst_size) ->
35+ so (src_offset + size <= src_init) ->
36+ RawMemory () (MemoryChunk dst_size dst_init)
37+ (\v => MemoryChunk dst_size (max dst_init (dst_offset + size)))
38+ GetRawPtr : RawMemory (MemoryChunk n i) (MemoryChunk n i) (\v => MemoryChunk n i)
39+
40+private
41+do_malloc : Nat -> IOExcept String Ptr
42+do_malloc size with (fromInteger (cast size) == size)
43+ | True = do ptr <- ioe_lift $ mkForeign (FFun "malloc" [FInt] FPtr) (fromInteger $ cast size)
44+ fail <- ioe_lift $ nullPtr ptr
45+ if fail then ioe_fail "Cannot allocate memory"
46+ else return ptr
47+ | False = ioe_fail "The target architecture does not support adressing enough memory"
48+
49+private
50+do_memset : Ptr -> Nat -> Bits8 -> Nat -> IO ()
51+do_memset ptr offset c size
52+ = mkForeign (FFun "idris_memset" [FPtr, FInt, FByte, FInt] FUnit)
53+ ptr (fromInteger $ cast offset) c (fromInteger $ cast size)
54+
55+private
56+do_free : Ptr -> IO ()
57+do_free ptr = mkForeign (FFun "free" [FPtr] FUnit) ptr
58+
59+private
60+do_memmove : Ptr -> Ptr -> Nat -> Nat -> Nat -> IO ()
61+do_memmove dest src dest_offset src_offset size
62+ = mkForeign (FFun "idris_memmove" [FPtr, FPtr, FInt, FInt, FInt] FUnit)
63+ dest src (fromInteger $ cast dest_offset) (fromInteger $ cast src_offset) (fromInteger $ cast size)
64+
65+private
66+do_peek : Ptr -> Nat -> (size : Nat) -> IO (Vect size Bits8)
67+do_peek _ _ Z = return (Prelude.Vect.Nil)
68+do_peek ptr offset (S n)
69+ = do b <- mkForeign (FFun "idris_peek" [FPtr, FInt] FByte) ptr (fromInteger $ cast offset)
70+ bs <- do_peek ptr (S offset) n
71+ Prelude.Monad.return (Prelude.Vect.(::) b bs)
72+
73+private
74+do_poke : Ptr -> Nat -> Vect size Bits8 -> IO ()
75+do_poke _ _ [] = return ()
76+do_poke ptr offset (b::bs)
77+ = do mkForeign (FFun "idris_poke" [FPtr, FInt, FByte] FUnit) ptr (fromInteger $ cast offset) b
78+ do_poke ptr (S offset) bs
79+
80+instance Handler RawMemory (IOExcept String) where
81+ handle () (Allocate n) k
82+ = do ptr <- do_malloc n
83+ k () (CH ptr)
84+ handle {-{res = MemoryChunk _ offset}-} (CH ptr) (Initialize {i} c size _) k
85+ = ioe_lift (do_memset ptr i c size) $> k () (CH ptr)
86+ handle (CH ptr) (Free) k
87+ = ioe_lift (do_free ptr) $> k () ()
88+ handle (CH ptr) (Peek offset size _) k
89+ = do res <- ioe_lift (do_peek ptr offset size)
90+ k res (CH ptr)
91+ handle (CH ptr) (Poke offset content _) k
92+ = do ioe_lift (do_poke ptr offset content)
93+ k () (CH ptr)
94+ handle (CH dest_ptr) (Move (CH src_ptr) dest_offset src_offset size _ _) k
95+ = do ioe_lift (do_memmove dest_ptr src_ptr dest_offset src_offset size)
96+ k () (CH dest_ptr)
97+ handle chunk (GetRawPtr) k
98+ = k chunk chunk
99+
100+RAW_MEMORY : Type -> EFFECT
101+RAW_MEMORY t = MkEff t RawMemory
102+
103+allocate : (n : Nat) ->
104+ Eff m () [RAW_MEMORY ()] (\v => [RAW_MEMORY (MemoryChunk n 0)])
105+allocate size = Allocate size
106+
107+initialize : {i : Nat} ->
108+ {n : Nat} ->
109+ Bits8 ->
110+ (size : Nat) ->
111+ so (i + size <= n) ->
112+ Eff m () [RAW_MEMORY (MemoryChunk n i)]
113+ (\v => [RAW_MEMORY (MemoryChunk n (i + size))])
114+initialize c size prf = Initialize c size prf
115+
116+free : Eff m () [RAW_MEMORY (MemoryChunk n i)] (\v => [RAW_MEMORY ()])
117+free = Free
118+
119+peek : {i : Nat} ->
120+ (offset : Nat) ->
121+ (size : Nat) ->
122+ so (offset + size <= i) ->
123+ { [RAW_MEMORY (MemoryChunk n i)] } Eff m (Vect size Bits8)
124+peek offset size prf = Peek offset size prf
125+
126+poke : {n : Nat} ->
127+ {i : Nat} ->
128+ (offset : Nat) ->
129+ Vect size Bits8 ->
130+ so (offset <= i && offset + size <= n) ->
131+ Eff m () [RAW_MEMORY (MemoryChunk n i)]
132+ (\v => [RAW_MEMORY (MemoryChunk n (max i (offset + size)))])
133+poke offset content prf = Poke offset content prf
134+
135+private
136+getRawPtr : { [RAW_MEMORY (MemoryChunk n i)] } Eff m (MemoryChunk n i)
137+getRawPtr = GetRawPtr
138+
139+private
140+move' : {dst_size : Nat} ->
141+ {dst_init : Nat} ->
142+ {src_init : Nat} ->
143+ (src_ptr : MemoryChunk src_size src_init) ->
144+ (dst_offset : Nat) ->
145+ (src_offset : Nat) ->
146+ (size : Nat) ->
147+ so (dst_offset <= dst_init && dst_offset + size <= dst_size) ->
148+ so (src_offset + size <= src_init) ->
149+ Eff m () [RAW_MEMORY (MemoryChunk dst_size dst_init)]
150+ (\v => [RAW_MEMORY (MemoryChunk dst_size (max dst_init (dst_offset + size)))])
151+move' src_ptr dst_offset src_offset size dst_bounds src_bounds
152+ = Move src_ptr dst_offset src_offset size dst_bounds src_bounds
153+
154+data MoveDescriptor = Dst | Src
155+
156+move : {dst_size : Nat} ->
157+ {dst_init : Nat} ->
158+ {src_size : Nat} ->
159+ {src_init : Nat} ->
160+ (dst_offset : Nat) ->
161+ (src_offset : Nat) ->
162+ (size : Nat) ->
163+ so (dst_offset <= dst_init && dst_offset + size <= dst_size) ->
164+ so (src_offset + size <= src_init) ->
165+ Eff m ()
166+ [ Dst ::: RAW_MEMORY (MemoryChunk dst_size dst_init)
167+ , Src ::: RAW_MEMORY (MemoryChunk src_size src_init)]
168+ (\v =>
169+ [ Dst ::: RAW_MEMORY (MemoryChunk dst_size (max dst_init (dst_offset + size)))
170+ , Src ::: RAW_MEMORY (MemoryChunk src_size src_init)])
171+move dst_offset src_offset size dst_bounds src_bounds
172+ = do src_ptr <- Src :- getRawPtr
173+ Dst :- move' src_ptr dst_offset src_offset size dst_bounds src_bounds
174+ return ()
175+
libs/neweffects/Effect/Monad.idrnew file+21
@@ -0,0 +1,21 @@
1+module Effect.Monad
2+
3+import Effects
4+
5+-- Eff is a monad too, so we can happily use it in a monad transformer.
6+
7+using (xs : List EFFECT, m : Type -> Type)
8+ instance Functor (\a => EffM m a xs (\v => xs)) where
9+ map f prog = do t <- prog
10+ value (f t)
11+
12+ instance Applicative (\a => EffM m a xs (\v => xs)) where
13+ pure = value
14+ (<$>) f a = do f' <- f
15+ a' <- a
16+ value (f' a')
17+
18+ instance Monad (\a => Eff m a xs (\v => xs)) where
19+ (>>=) = Effects.(>>=)
20+
21+
libs/neweffects/Effect/Random.idrnew file+25
@@ -0,0 +1,25 @@
1+module Effect.Random
2+
3+import Effects
4+
5+data Random : Effect where
6+ getRandom : { Integer } Random Integer
7+ setSeed : Integer -> { Integer } Random ()
8+
9+using (m : Type -> Type)
10+ instance Handler Random m where
11+ handle seed getRandom k
12+ = let seed' = (1664525 * seed + 1013904223) `prim__sremBigInt` (pow 2 32) in
13+ k seed' seed'
14+ handle seed (setSeed n) k = k () n
15+
16+RND : EFFECT
17+RND = MkEff Integer Random
18+
19+rndInt : Integer -> Integer -> { [RND] } Eff m Integer
20+rndInt lower upper = do v <- getRandom
21+ return (v `prim__sremBigInt` (upper - lower) + lower)
22+
23+srand : Integer -> { [RND] } Eff m ()
24+srand n = setSeed n
25+
libs/neweffects/Effect/Select.idrnew file+23
@@ -0,0 +1,23 @@
1+module Effect.Select
2+
3+import Effects
4+
5+data Selection : Effect where
6+ Select : List a -> { () } Selection a
7+
8+instance Handler Selection Maybe where
9+ handle _ (Select xs) k = tryAll xs where
10+ tryAll [] = Nothing
11+ tryAll (x :: xs) = case k x () of
12+ Nothing => tryAll xs
13+ Just v => Just v
14+
15+instance Handler Selection List where
16+ handle r (Select xs) k = concatMap (\x => k x r) xs
17+
18+SELECT : EFFECT
19+SELECT = MkEff () Selection
20+
21+select : List a -> { [SELECT] } Eff m a
22+select xs = Select xs
23+
libs/neweffects/Effect/State.idrnew file+40
@@ -0,0 +1,40 @@
1+module Effect.State
2+
3+import Effects
4+
5+%access public
6+
7+data State : Effect where
8+ Get : { a } State a
9+ Put : b -> { a ==> b } State ()
10+
11+using (m : Type -> Type)
12+ instance Handler State m where
13+ handle st Get k = k st st
14+ handle st (Put n) k = k () n
15+
16+STATE : Type -> EFFECT
17+STATE t = MkEff t State
18+
19+get : { [STATE x] } Eff m x
20+get = Get
21+
22+put : x -> { [STATE x] } Eff m ()
23+put val = Put val
24+
25+putM : y -> { [STATE x] ==> [STATE y] } Eff m ()
26+putM val = Put val
27+
28+update : (x -> x) -> { [STATE x] } Eff m ()
29+update f = put (f !get)
30+
31+updateM : (x -> y) -> { [STATE x] ==> [STATE y] } Eff m ()
32+updateM f = putM (f !get)
33+
34+locally : x -> ({ [STATE x] } Eff m t) -> { [STATE y] } Eff m t
35+locally newst prog = do st <- get
36+ putM newst
37+ val <- prog
38+ putM st
39+ return val
40+
libs/neweffects/Effect/StdIO.idrnew file+63
@@ -0,0 +1,63 @@
1+module Effect.StdIO
2+
3+import Effects
4+import Control.IOExcept
5+
6+data StdIO : Effect where
7+ PutStr : String -> { () } StdIO ()
8+ GetStr : { () } StdIO String
9+
10+instance Handler StdIO IO where
11+ handle () (PutStr s) k = do putStr s; k () ()
12+ handle () GetStr k = do x <- getLine; k x ()
13+
14+{-
15+instance Handler StdIO (IOExcept a) where
16+ handle () (PutStr s) k = do ioe_lift (putStr s); k () ()
17+ handle () GetStr k = do x <- ioe_lift getLine; k () x
18+
19+-- Handle effects in a pure way, for simulating IO for unit testing/proof
20+
21+data IOStream a = MkStream (List String -> (a, List String))
22+
23+instance Handler StdIO IOStream where
24+ handle () (PutStr s) k
25+ = MkStream (\x => case k () () of
26+ MkStream f => let (res, str) = f x in
27+ (res, s :: str))
28+ handle {a} () GetStr k
29+ = MkStream (\x => case x of
30+ [] => cont "" []
31+ (t :: ts) => cont t ts)
32+ where
33+ cont : String -> List String -> (a, List String)
34+ cont t ts = case k () t of
35+ MkStream f => f ts
36+
37+-}
38+
39+--- The Effect and associated functions
40+
41+STDIO : EFFECT
42+STDIO = MkEff () StdIO
43+
44+putStr : Handler StdIO e => String -> { [STDIO] } Eff e ()
45+putStr s = PutStr s
46+
47+putStrLn : Handler StdIO e => String -> { [STDIO] } Eff e ()
48+putStrLn s = putStr (s ++ "\n")
49+
50+getStr : Handler StdIO e => { [STDIO] } Eff e String
51+getStr = GetStr
52+
53+-- mkStrFn : Env IOStream xs ->
54+-- Eff IOStream xs a ->
55+-- List String -> (a, List String)
56+-- mkStrFn {a} env p input = case mkStrFn' of
57+-- MkStream f => f input
58+-- where injStream : a -> IOStream a
59+-- injStream v = MkStream (\x => (v, []))
60+-- mkStrFn' : IOStream a
61+-- mkStrFn' = runWith injStream env p
62+--
63+--
libs/neweffects/Effects.idrnew file+269
@@ -0,0 +1,269 @@
1+module Effects
2+
3+import Language.Reflection
4+import Control.Catchable
5+import Effect.Default
6+
7+%access public
8+
9+---- Effects
10+
11+Effect : Type
12+Effect = (x : Type) -> Type -> (x -> Type) -> Type
13+
14+%error_reverse
15+data EFFECT : Type where
16+ MkEff : Type -> Effect -> EFFECT
17+
18+class Handler (e : Effect) (m : Type -> Type) where
19+ handle : res -> (eff : e t res resk) ->
20+ ((x : t) -> resk x -> m a) -> m a
21+
22+-- A bit of syntactic sugar ('syntax' is not very flexible so we only go
23+-- up to a small number of parameters...)
24+
25+syntax "{" [inst] "==>" [outst] "}" [eff] = eff inst (\result => outst)
26+syntax "{" [inst] "}" [eff] = eff inst (\result => inst)
27+
28+---- Properties and proof construction
29+
30+using (xs : List a, ys : List a)
31+ data SubList : List a -> List a -> Type where
32+ SubNil : SubList {a} [] []
33+ Keep : SubList xs ys -> SubList (x :: xs) (x :: ys)
34+ Drop : SubList xs ys -> SubList xs (x :: ys)
35+
36+ subListId : SubList xs xs
37+ subListId {xs = Nil} = SubNil
38+ subListId {xs = x :: xs} = Keep subListId
39+
40+namespace Env
41+ data Env : (m : Type -> Type) -> List EFFECT -> Type where
42+ Nil : Env m Nil
43+ (::) : Handler eff m => a -> Env m xs -> Env m (MkEff a eff :: xs)
44+
45+data EffElem : Effect -> Type ->
46+ List EFFECT -> Type where
47+ Here : EffElem x a (MkEff a x :: xs)
48+ There : EffElem x a xs -> EffElem x a (y :: xs)
49+
50+-- make an environment corresponding to a sub-list
51+dropEnv : Env m ys -> SubList xs ys -> Env m xs
52+dropEnv [] SubNil = []
53+dropEnv (v :: vs) (Keep rest) = v :: dropEnv vs rest
54+dropEnv (v :: vs) (Drop rest) = dropEnv vs rest
55+
56+updateWith : (ys' : List a) -> (xs : List a) ->
57+ SubList ys xs -> List a
58+updateWith (y :: ys) (x :: xs) (Keep rest) = y :: updateWith ys xs rest
59+updateWith ys (x :: xs) (Drop rest) = x :: updateWith ys xs rest
60+updateWith [] [] SubNil = []
61+updateWith (y :: ys) [] SubNil = y :: ys
62+updateWith [] (x :: xs) (Keep rest) = []
63+
64+-- put things back, replacing old with new in the sub-environment
65+rebuildEnv : Env m ys' -> (prf : SubList ys xs) ->
66+ Env m xs -> Env m (updateWith ys' xs prf)
67+rebuildEnv [] SubNil env = env
68+rebuildEnv (x :: xs) (Keep rest) (y :: env) = x :: rebuildEnv xs rest env
69+rebuildEnv xs (Drop rest) (y :: env) = y :: rebuildEnv xs rest env
70+rebuildEnv (x :: xs) SubNil [] = x :: xs
71+
72+---- The Effect EDSL itself ----
73+
74+-- some proof automation
75+
76+%reflection
77+reflectListEffElem : List a -> Tactic
78+reflectListEffElem [] = Refine "Here" `Seq` Solve
79+reflectListEffElem (x :: xs)
80+ = Try (Refine "Here" `Seq` Solve)
81+ (Refine "There" `Seq` (Solve `Seq` reflectListEffElem xs))
82+-- TMP HACK! FIXME!
83+-- The evaluator needs a 'function case' to know its a reflection function
84+-- until we propagate that information! Without this, the _ case won't get
85+-- matched.
86+reflectListEffElem (x ++ y) = Refine "Here" `Seq` Solve
87+reflectListEffElem _ = Refine "Here" `Seq` Solve
88+
89+%reflection
90+reflectSubList : List a -> Tactic
91+reflectSubList [] = Refine "subListId" `Seq` Solve
92+reflectSubList (x :: xs)
93+ = Try (Refine "subListId" `Seq` Solve)
94+ (Try (Refine "Keep" `Seq` (Solve `Seq` reflectSubList xs))
95+ (Refine "Drop" `Seq` (Solve `Seq` reflectSubList xs)))
96+reflectSubList (x ++ y) = Refine "subListId" `Seq` Solve
97+reflectSubList _ = Refine "subListId" `Seq` Solve
98+
99+%reflection
100+reflectEff : (P : Type) -> Tactic
101+reflectEff (EffElem m a xs)
102+ = reflectListEffElem xs `Seq` Solve
103+reflectEff (SubList xs ys)
104+ = reflectSubList ys `Seq` Solve
105+
106+updateResTy : (val : t) ->
107+ (xs : List EFFECT) -> EffElem e a xs -> e t a b ->
108+ List EFFECT
109+updateResTy {b} val (MkEff a e :: xs) Here n = (MkEff (b val) e) :: xs
110+updateResTy val (x :: xs) (There p) n = x :: updateResTy val xs p n
111+
112+-- updateResTyImm : (xs : List EFFECT) -> EffElem e a xs -> Type ->
113+-- List EFFECT
114+-- updateResTyImm (MkEff a e :: xs) Here b = (MkEff b e) :: xs
115+-- updateResTyImm (x :: xs) (There p) b = x :: updateResTyImm xs p b
116+
117+infix 5 :::, :-, :=
118+
119+data LRes : lbl -> Type -> Type where
120+ (:=) : (x : lbl) -> res -> LRes x res
121+
122+(:::) : lbl -> EFFECT -> EFFECT
123+(:::) {lbl} x (MkEff r e) = MkEff (LRes x r) e
124+
125+using (lbl : Type)
126+ instance Default a => Default (LRes lbl a) where
127+ default = lbl := default
128+
129+private
130+unlabel : {l : ty} -> Env m [l ::: x] -> Env m [x]
131+unlabel {m} {x = MkEff a eff} [l := v] = [v]
132+
133+private
134+relabel : (l : ty) -> Env m xs -> Env m (map (\x => l ::: x) xs)
135+relabel {xs = []} l [] = []
136+relabel {xs = (MkEff a e :: xs)} l (v :: vs) = (l := v) :: relabel l vs
137+
138+-- the language of Effects
139+
140+data Eff : (m : Type -> Type) ->
141+ (x : Type) ->
142+ List EFFECT -> (x -> List EFFECT) -> Type where
143+ value : a -> Eff m a xs (\v => xs)
144+ ebind : Eff m a xs xs' ->
145+ ((val : a) -> Eff m b (xs' val) xs'') -> Eff m b xs xs''
146+ effect : (prf : EffElem e a xs) ->
147+ (eff : e t a b) ->
148+ Eff m t xs (\v => updateResTy v xs prf eff)
149+
150+ lift : (prf : SubList ys xs) ->
151+ Eff m t ys ys' -> Eff m t xs (\v => updateWith (ys' v) xs prf)
152+ new : Handler e m =>
153+ res ->
154+ Eff m a (MkEff res e :: xs) (\v => (MkEff res' e :: xs')) ->
155+ Eff m a xs (\v => xs')
156+ catch : Catchable m err =>
157+ Eff m a xs xs' -> (err -> Eff m a xs xs') ->
158+ Eff m a xs xs'
159+
160+ (:-) : (l : ty) ->
161+ Eff m t [x] xs' -> -- [x] (\v => xs) ->
162+ Eff m t [l ::: x] (\v => map (l :::) (xs' v))
163+
164+(>>=) : Eff m a xs xs' ->
165+ ((val : a) -> Eff m b (xs' val) xs'') -> Eff m b xs xs''
166+(>>=) = ebind
167+
168+implicit
169+lift' : Eff m t ys ys' ->
170+ {default tactics { byReflection reflectEff; }
171+ prf : SubList ys xs} ->
172+ Eff m t xs (\v => updateWith (ys' v) xs prf)
173+lift' e {prf} = lift prf e
174+
175+implicit
176+effect' : {a, b: _} -> {e : Effect} ->
177+ (eff : e t a b) ->
178+ {default tactics { byReflection reflectEff; }
179+ prf : EffElem e a xs} ->
180+ Eff m t xs (\v => updateResTy v xs prf eff)
181+effect' e {prf} = effect prf e
182+
183+return : a -> Eff m a xs (\v => xs)
184+return x = value x
185+
186+-- for idiom brackets
187+
188+infixl 2 <$>
189+
190+pure : a -> Eff m a xs (\v => xs)
191+pure = value
192+
193+(<$>) : Eff m (a -> b) xs (\v => xs) ->
194+ Eff m a xs (\v => xs) -> Eff m b xs (\v => xs)
195+(<$>) prog v = do fn <- prog
196+ arg <- v
197+ return (fn arg)
198+
199+-- an interpreter
200+
201+private
202+execEff : Env m xs -> (p : EffElem e res xs) ->
203+ (eff : e a res resk) ->
204+ ((v : a) -> Env m (updateResTy v xs p eff) -> m t) -> m t
205+execEff (val :: env) Here eff' k
206+ = handle val eff' (\v, res => k v (res :: env))
207+execEff (val :: env) (There p) eff k
208+ = execEff env p eff (\v, env' => k v (val :: env'))
209+
210+-- Q: Instead of m b, implement as StateT (Env m xs') m b, so that state
211+-- updates can be propagated even through failing computations?
212+
213+eff : Env m xs -> Eff m a xs xs' -> ((x : a) -> Env m (xs' x) -> m b) -> m b
214+eff env (value x) k = k x env
215+eff env (prog `ebind` c) k
216+ = eff env prog (\p', env' => eff env' (c p') k)
217+eff env (effect prf effP) k = execEff env prf effP k
218+eff env (lift prf effP) k
219+ = let env' = dropEnv env prf in
220+ eff env' effP (\p', envk => k p' (rebuildEnv envk prf env))
221+eff env (new r prog) k
222+ = let env' = r :: env in
223+ eff env' prog (\p' => \ (v :: envk) => k p' envk)
224+eff env (catch prog handler) k
225+ = catch (eff env prog k)
226+ (\e => eff env (handler e) k)
227+-- FIXME:
228+-- xs is needed explicitly because otherwise the pattern binding for
229+-- 'l' appears too late. Solution seems to be to reorder patterns at the
230+-- end so that everything is in scope when it needs to be.
231+eff {xs = [l ::: x]} env (l :- prog) k
232+ = let env' = unlabel env in
233+ eff env' prog (\p', envk => k p' (relabel l envk))
234+
235+run : Applicative m => Env m xs -> Eff m a xs xs' -> m a
236+run env prog = eff env prog (\r, env => pure r)
237+
238+-- yuck :)
239+syntax MkDefaultEnv = (| [], [default], [default, default],
240+ [default, default, default],
241+ [default, default, default, default],
242+ [default, default, default, default, default],
243+ [default, default, default, default, default, default],
244+ [default, default, default, default, default, default, default],
245+ [default, default, default, default, default, default, default, default] |)
246+
247+run' : Applicative m => {default MkDefaultEnv env : Env m xs} -> Eff m a xs xs' -> m a
248+run' {env} prog = eff env prog (\r, env => pure r)
249+
250+runEnv : Applicative m => Env m xs -> Eff m a xs xs' ->
251+ m (x : a ** Env m (xs' x))
252+runEnv env prog = eff env prog (\r, env => pure (r ** env))
253+
254+runPure : Env id xs -> Eff id a xs xs' -> a
255+runPure env prog = eff env prog (\r, env => r)
256+
257+runWith : (a -> m a) -> Env m xs -> Eff m a xs xs' -> m a
258+runWith inj env prog = eff env prog (\r, env => inj r)
259+
260+-- some higher order things
261+
262+mapE : Applicative m => (a -> {xs} Eff m b) -> List a -> {xs} Eff m (List b)
263+mapE f [] = pure []
264+mapE f (x :: xs) = [| f x :: mapE f xs |]
265+
266+when : Applicative m => Bool -> ({xs} Eff m ()) -> {xs} Eff m ()
267+when True e = e
268+when False e = pure ()
269+
libs/neweffects/Makefilenew file+14
@@ -0,0 +1,14 @@
1+IDRIS := idris
2+
3+build:
4+ $(IDRIS) --build neweffects.ipkg
5+
6+clean:
7+ $(IDRIS) --clean neweffects.ipkg
8+
9+install:
10+ $(IDRIS) --install neweffects.ipkg
11+
12+rebuild: clean build
13+
14+.PHONY: build clean install rebuild
libs/neweffects/neweffects.ipkgnew file+9
@@ -0,0 +1,9 @@
1+package neweffects
2+
3+opts = "--nobasepkgs -i ../prelude -i ../base"
4+modules = Effects, Effect.Default,
5+
6+ Effect.Exception, Effect.File, Effect.State,
7+ Effect.Random, Effect.StdIO, Effect.Select,
8+ Effect.Memory
9+
libs/prelude/Prelude.idr+6−2
@@ -532,12 +532,16 @@ ferror (FHandle h) = do err <- do_ferror h
532532partial
533533nullPtr : Ptr -> IO Bool
534534nullPtr p = do ok <- mkForeign (FFun "isNull" [FPtr] FInt) p
535− return (ok /= 0);
535+ return (ok /= 0)
536536
537537partial
538538nullStr : String -> IO Bool
539539nullStr p = do ok <- mkForeign (FFun "isNull" [FString] FInt) p
540− return (ok /= 0);
540+ return (ok /= 0)
541+
542+eqPtr : Ptr -> Ptr -> IO Bool
543+eqPtr x y = do eq <- mkForeign (FFun "idris_eqPtr" [FPtr, FPtr] FInt) x y
544+ return (eq /= 0)
541545
542546partial
543547validFile : File -> IO Bool
rts/idris_stdfgn.c+4
@@ -36,6 +36,10 @@ int isNull(void* ptr) {
3636 return ptr==NULL;
3737}
3838
39+int idris_eqPtr(void* x, void* y) {
40+ return x==y;
41+}
42+
3943void* idris_stdin() {
4044 return (void*)stdin;
4145}
rts/idris_stdfgn.h+1
@@ -12,6 +12,7 @@ int fileEOF(void* h);
1212int fileError(void* h);
1313void fputStr(void*h, char* str);
1414
15+int idris_eqPtr(void* x, void* y);
1516int isNull(void* ptr);
1617void* idris_stdin();
1718
src/IRTS/CodegenJavaScript.hs+119−20
@@ -314,6 +314,9 @@ jsSubst var new (JSIndex obj field) =
314314jsSubst var new (JSCond conds) =
315315 JSCond (map ((jsSubst var new) *** (jsSubst var new)) conds)
316316
317+jsSubst var new (JSAssign lhs rhs) =
318+ JSAssign (jsSubst var new lhs) (jsSubst var new rhs)
319+
317320jsSubst _ _ js = js
318321
319322
@@ -328,16 +331,24 @@ isJSConstant js
328331 | otherwise = False
329332
330333inlineJS :: JS -> JS
334+inlineJS (JSReturn (JSApp (JSFunction ["cse"] body) [val@(JSVar _)])) =
335+ inlineJS $ jsSubst "cse" val body
336+
337+inlineJS (JSReturn (JSApp (JSFunction [arg] cond@(JSCond _)) [val])) =
338+ JSSeq [ JSAlloc arg (Just (inlineJS val))
339+ , inlineJS cond
340+ ]
341+
331342inlineJS (JSApp (JSProj (JSFunction args (JSReturn body)) "apply") [
332− JSThis,JSProj (JSIdent var) "vars"
343+ JSThis,JSProj var "vars"
333344 ])
334− | var /= "cse" =
335− inlineApply args body 0
345+ | var /= JSIdent "cse" =
346+ inlineApply args body 0
336347 where
337− inlineApply [] body _ = body
348+ inlineApply [] body _ = inlineJS body
338349 inlineApply (a:as) body n =
339350 inlineApply as (
340− jsSubst a (JSIndex (JSProj (JSIdent var) "vars") (JSNum (JSInt n))) body
351+ jsSubst a (JSIndex (JSProj var "vars") (JSNum (JSInt n))) body
341352 ) (n + 1)
342353
343354inlineJS (JSApp (JSIdent "__IDR__mEVAL0") [val])
@@ -348,9 +359,6 @@ inlineJS (JSApp (JSIdent "__IDRRT__tailcall") [
348359 ])
349360 | isJSConstant val = val
350361
351−inlineJS (JSApp (JSFunction [] (JSSeq ret)) []) =
352− JSApp (JSFunction [] (JSSeq (map inlineJS ret))) []
353−
354362inlineJS (JSApp (JSFunction [arg] (JSReturn ret)) [val])
355363 | JSNew con [tag, vals] <- ret
356364 , opt <- inlineJS val =
@@ -430,6 +438,96 @@ reduceJS js = reduceLoop [] ([], js)
430438funName :: JS -> String
431439funName (JSAlloc fun _) = fun
432440
441+initConstructors :: [JS] -> [JS]
442+initConstructors js =
443+ let tags = nub $ sort $ concat (map getTags js) in
444+ map createConstant tags ++ replaceConstructors tags js
445+ where
446+ getTags :: JS -> [Int]
447+ getTags (JSNew "__IDRRT__Con" [JSNum (JSInt tag), JSArray []]) = [tag]
448+
449+ getTags (JSNew _ args) = concatMap getTags args
450+
451+ getTags (JSFunction _ body) = getTags body
452+
453+ getTags (JSReturn ret) = getTags ret
454+
455+ getTags (JSApp lhs rhs) = getTags lhs ++ concatMap getTags rhs
456+
457+ getTags (JSSeq seq) = concatMap getTags seq
458+
459+ getTags (JSOp _ lhs rhs) = getTags lhs ++ getTags rhs
460+
461+ getTags (JSProj obj _) = getTags obj
462+
463+ getTags (JSArray vals) = concatMap getTags vals
464+
465+ getTags (JSAssign lhs rhs) = getTags lhs ++ getTags rhs
466+
467+ getTags (JSAlloc _ (Just val)) = getTags val
468+
469+ getTags (JSCond conds) =
470+ concatMap (uncurry (++)) $ map (getTags *** getTags) conds
471+
472+ getTags (JSTernary c t f) = getTags c ++ getTags t ++ getTags f
473+
474+ getTags js = []
475+
476+ replaceConstructors :: [Int] -> [JS] -> [JS]
477+ replaceConstructors tags js = map (replaceHelper tags) js
478+ where
479+ replaceHelper :: [Int] -> JS -> JS
480+ replaceHelper tags (JSNew "__IDRRT__Con" [JSNum (JSInt tag), JSArray []])
481+ | tag `elem` tags = JSIdent ("__IDRCTR__" ++ show tag)
482+
483+ replaceHelper tags (JSNew con args) =
484+ JSNew con $ map (replaceHelper tags) args
485+
486+ replaceHelper tags (JSFunction fun body) =
487+ JSFunction fun (replaceHelper tags body)
488+
489+ replaceHelper tags (JSReturn ret) =
490+ JSReturn (replaceHelper tags ret)
491+
492+ replaceHelper tags (JSApp lhs rhs) =
493+ JSApp (replaceHelper tags lhs) (map (replaceHelper tags) rhs)
494+
495+ replaceHelper tags (JSSeq seq) =
496+ JSSeq $ map (replaceHelper tags) seq
497+
498+ replaceHelper tags (JSOp op lhs rhs) =
499+ JSOp op (replaceHelper tags lhs) (replaceHelper tags rhs)
500+
501+ replaceHelper tags (JSProj obj field) =
502+ JSProj (replaceHelper tags obj) field
503+
504+ replaceHelper tags (JSArray vals) =
505+ JSArray $ map (replaceHelper tags) vals
506+
507+ replaceHelper tags (JSAssign lhs rhs) =
508+ JSAssign (replaceHelper tags lhs) (replaceHelper tags rhs)
509+
510+ replaceHelper tags (JSAlloc var (Just val)) =
511+ JSAlloc var $ Just (replaceHelper tags val)
512+
513+ replaceHelper tags (JSCond conds) =
514+ JSCond (map ((replaceHelper tags) *** (replaceHelper tags)) conds)
515+
516+ replaceHelper tags (JSTernary c t f) =
517+ JSTernary (replaceHelper tags c) (
518+ replaceHelper tags t
519+ ) (
520+ replaceHelper tags f
521+ )
522+
523+ replaceHelper tags js = js
524+
525+ createConstant :: Int -> JS
526+ createConstant tag =
527+ JSAlloc ("__IDRCTR__" ++ show tag) (Just (
528+ JSNew (idrRTNamespace ++ "Con") [JSNum (JSInt tag), JSArray []]
529+ ))
530+
433531removeIDs :: [JS] -> [JS]
434532removeIDs js =
435533 case partition isID js of
@@ -651,7 +749,7 @@ codegenJavaScript target definitions filename outputType = do
651749
652750 functions :: [String]
653751 functions =
654− map (compileJS . reduceConstants) ((reduceJS . removeIDs) $ map (optimizeJS . translateDeclaration) def)
752+ map compileJS $ initConstructors (map reduceConstants ((reduceJS . removeIDs) $ map (optimizeJS . translateDeclaration) def))
655753
656754 mainLoop :: String
657755 mainLoop = compileJS $
@@ -780,7 +878,7 @@ translateConstant c =
780878
781879translateDeclaration :: (String, SDecl) -> JS
782880translateDeclaration (path, SFun name params stackSize body)
783− | (MN _ ap) <- name
881+ | (MN _ ap) <- name
784882 , (SLet var val next) <- body
785883 , (SChkCase cvar cases) <- next
786884 , ap == txt "APPLY" =
@@ -789,20 +887,21 @@ translateDeclaration (path, SFun name params stackSize body)
789887 JSSeq [ lookupTable [(var, "chk")] var cases
790888 , jsDecl $ JSFunction ["fn0", "arg0"] (
791889 JSSeq [ JSAlloc "__var_0" (Just $ JSIdent "fn0")
792− , JSReturn $ jsLet (translateVariableName var) (
793− translateExpression val
794− ) (JSTernary (
795− (JSVar var `jsInstanceOf` jsCon) `jsAnd`
796− (hasProp lookupTableName (translateVariableName var))
797− ) (JSIdent $
798− lookupTableName ++ lookup
799− ) JSNull
800− )
890+ , JSAlloc (translateVariableName var) (
891+ Just $ translateExpression val
892+ )
893+ , JSReturn $ (JSTernary (
894+ (JSVar var `jsInstanceOf` jsCon) `jsAnd`
895+ (hasProp lookupTableName (translateVariableName var))
896+ ) (JSIdent $
897+ lookupTableName ++ lookup
898+ ) JSNull
899+ )
801900 ]
802901 )
803902 ]
804903
805− | (MN _ ev) <- name
904+ | (MN _ ev) <- name
806905 , (SChkCase var cases) <- body
807906 , ev == txt "EVAL" =
808907 JSSeq [ lookupTable [] var cases
src/Idris/AbsSyntax.hs+8−4
@@ -95,6 +95,10 @@ addTrans :: (Term, Term) -> Idris ()
9595addTrans t = do i <- getIState
9696 putIState $ i { idris_transforms = t : idris_transforms i }
9797
98+addErrRev :: (Term, Term) -> Idris ()
99+addErrRev t = do i <- getIState
100+ putIState $ i { idris_errRev = t : idris_errRev i }
101+
98102totcheck :: (FC, Name) -> Idris ()
99103totcheck n = do i <- getIState; putIState $ i { idris_totcheck = idris_totcheck i ++ [n] }
100104
@@ -956,12 +960,12 @@ addUsingConstraints syn fc t
956960 -- if all of args in ns, then add it
957961 doAdd (UConstraint c args : cs) ns t
958962 | all (\n -> elem n ns) args
959− = PPi (Constraint False Dynamic "") (sMN 0 "cu")
963+ = PPi (Constraint [] Dynamic "") (sMN 0 "cu")
960964 (mkConst c args) (doAdd cs ns t)
961965 | otherwise = doAdd cs ns t
962966
963967 mkConst c args = PApp fc (PRef fc c)
964− (map (\n -> PExp 0 False (PRef fc n) "") args)
968+ (map (\n -> PExp 0 [] (PRef fc n) "") args)
965969
966970 getConstraints (PPi (Constraint _ _ _) _ c sc)
967971 = getcapp c ++ getConstraints sc
@@ -1091,8 +1095,8 @@ implicitise syn ignore ist tm = -- trace ("INCOMING " ++ showImp True tm) $
10911095 pibind using [] sc = sc
10921096 pibind using (n:ns) sc
10931097 = case lookup n using of
1094− Just ty -> PPi (Imp False Dynamic "" False) n ty (pibind using ns sc)
1095− Nothing -> PPi (Imp False Dynamic "" False) n Placeholder
1098+ Just ty -> PPi (Imp [] Dynamic "" False) n ty (pibind using ns sc)
1099+ Nothing -> PPi (Imp [] Dynamic "" False) n Placeholder
10961100 (pibind using ns sc)
10971101
10981102-- Add implicit arguments in function calls
src/Idris/AbsSyntaxTree.hs+41−20
@@ -111,6 +111,7 @@ data IState = IState {
111111 idris_metavars :: [(Name, (Maybe Name, Int, Bool))], -- ^ The currently defined but not proven metavariables
112112 idris_coercions :: [Name],
113113 idris_transforms :: [(Term, Term)],
114+ idris_errRev :: [(Term, Term)],
114115 syntax_rules :: [Syntax],
115116 syntax_keywords :: [String],
116117 imported :: [FilePath], -- ^ The imported modules
@@ -186,6 +187,7 @@ data IBCWrite = IBCFix FixDecl
186187 | IBCTotal Name Totality
187188 | IBCFlags Name [FnOpt]
188189 | IBCTrans (Term, Term)
190+ | IBCErrRev (Term, Term)
189191 | IBCCG Name
190192 | IBCDoc Name
191193 | IBCCoercion Name
@@ -200,7 +202,7 @@ idrisInit = IState initContext [] [] emptyContext emptyContext emptyContext
200202 emptyContext emptyContext emptyContext emptyContext
201203 emptyContext emptyContext emptyContext emptyContext
202204 emptyContext
203− [] [] defaultOpts 6 [] [] [] [] [] [] [] [] [] [] [] []
205+ [] [] defaultOpts 6 [] [] [] [] [] [] [] [] [] [] [] [] []
204206 [] Nothing Nothing [] [] [] Hidden False [] Nothing [] [] RawOutput
205207 True defaultTheme stdout [] (0, emptyContext)
206208
@@ -354,33 +356,36 @@ deriving instance NFData Static
354356!-}
355357
356358-- Mark bindings with their explicitness, and laziness
357−data Plicity = Imp { plazy :: Bool,
359+data Plicity = Imp { pargopts :: [ArgOpt],
358360 pstatic :: Static,
359361 pdocstr :: String,
360362 pparam :: Bool }
361− | Exp { plazy :: Bool,
363+ | Exp { pargopts :: [ArgOpt],
362364 pstatic :: Static,
363365 pdocstr :: String,
364366 pparam :: Bool }
365− | Constraint { plazy :: Bool,
367+ | Constraint { pargopts :: [ArgOpt],
366368 pstatic :: Static,
367369 pdocstr :: String }
368− | TacImp { plazy :: Bool,
370+ | TacImp { pargopts :: [ArgOpt],
369371 pstatic :: Static,
370372 pscript :: PTerm,
371373 pdocstr :: String }
372374 deriving (Show, Eq)
373375
376+plazy :: Plicity -> Bool
377+plazy tm = Lazy `elem` pargopts tm
378+
374379{-!
375380deriving instance Binary Plicity
376381deriving instance NFData Plicity
377382!-}
378383
379−impl = Imp False Dynamic "" False
380−expl = Exp False Dynamic "" False
381−expl_param = Exp False Dynamic "" True
382−constraint = Constraint False Dynamic ""
383−tacimpl t = TacImp False Dynamic t ""
384+impl = Imp [Lazy] Dynamic "" False
385+expl = Exp [] Dynamic "" False
386+expl_param = Exp [] Dynamic "" True
387+constraint = Constraint [] Dynamic ""
388+tacimpl t = TacImp [] Dynamic t ""
384389
385390data FnOpt = Inlinable -- always evaluate when simplifying
386391 | TotalFn | PartialFn
@@ -390,6 +395,7 @@ data FnOpt = Inlinable -- always evaluate when simplifying
390395 | Implicit -- implicit coercion
391396 | CExport String -- export, with a C name
392397 | ErrorHandler -- ^^ an error handler for use with the ErrorReflection extension
398+ | ErrorReverse -- ^^ attempt to reverse normalise before showing in error
393399 | Reflection -- a reflecting function, compile-time only
394400 | Specialise [(Name, Maybe Int)] -- specialise it, freeze these names
395401 deriving (Show, Eq)
@@ -410,6 +416,7 @@ dictionary = elem Dictionary
410416-- | Data declaration options
411417data DataOpt = Codata -- Set if the the data-type is coinductive
412418 | DefaultEliminator -- Set if an eliminator should be generated for data type
419+ | DataErrRev
413420 deriving (Show, Eq)
414421
415422type DataOpts = [DataOpt]
@@ -726,21 +733,31 @@ type PDo = PDo' PTerm
726733
727734data PArg' t = PImp { priority :: Int,
728735 machine_inf :: Bool, -- true if the machine inferred it
729− lazyarg :: Bool, pname :: Name, getTm :: t,
736+ argopts :: [ArgOpt],
737+ pname :: Name, getTm :: t,
730738 pargdoc :: String }
731739 | PExp { priority :: Int,
732− lazyarg :: Bool, getTm :: t,
740+ argopts :: [ArgOpt],
741+ getTm :: t,
733742 pargdoc :: String }
734743 | PConstraint { priority :: Int,
735− lazyarg :: Bool, getTm :: t,
744+ argopts :: [ArgOpt],
745+ getTm :: t,
736746 pargdoc :: String }
737747 | PTacImplicit { priority :: Int,
738− lazyarg :: Bool, pname :: Name,
748+ argopts :: [ArgOpt],
749+ pname :: Name,
739750 getScript :: t,
740751 getTm :: t,
741752 pargdoc :: String }
742753 deriving (Show, Eq, Functor)
743754
755+data ArgOpt = Lazy | HideDisplay
756+ deriving (Show, Eq)
757+
758+lazyarg :: PArg' t -> Bool
759+lazyarg tm = Lazy `elem` argopts tm
760+
744761instance Sized a => Sized (PArg' a) where
745762 size (PImp p _ l nm trm _) = 1 + size nm + size trm
746763 size (PExp p l trm _) = 1 + size trm
@@ -752,10 +769,10 @@ deriving instance Binary PArg'
752769deriving instance NFData PArg'
753770!-}
754771
755−pimp n t mach = PImp 1 mach True n t ""
756−pexp t = PExp 1 False t ""
757−pconst t = PConstraint 1 False t ""
758−ptacimp n s t = PTacImplicit 2 True n s t ""
772+pimp n t mach = PImp 1 mach [Lazy] n t ""
773+pexp t = PExp 1 [] t ""
774+pconst t = PConstraint 1 [] t ""
775+ptacimp n s t = PTacImplicit 2 [Lazy] n s t ""
759776
760777type PArg = PArg' PTerm
761778
@@ -798,6 +815,7 @@ deriving instance NFData OptInfo
798815
799816data TypeInfo = TI { con_names :: [Name],
800817 codata :: Bool,
818+ data_opts :: DataOpts,
801819 param_pos :: [Int] }
802820 deriving Show
803821{-!
@@ -1055,7 +1073,7 @@ pprintPTerm impl bnd = prettySe 10 bnd
10551073 prettySe 10 ((n, False):bnd) sc
10561074 prettySe p bnd (PPi (Exp l s _ _) n ty sc)
10571075 | n `elem` allNamesIn sc || impl =
1058− let open = (if l then text "|" else empty) <> lparen in
1076+ let open = if Lazy `elem` l then text "|" <> lparen else lparen in
10591077 bracket p 2 $
10601078 if size sc > breakingSize then
10611079 enclose open rparen (bindingOf n False <+> colon <+> prettySe 10 bnd ty) <+>
@@ -1076,7 +1094,7 @@ pprintPTerm impl bnd = prettySe 10 bnd
10761094 _ -> empty
10771095 prettySe p bnd (PPi (Imp l s _ _) n ty sc)
10781096 | impl =
1079− let open = if l then text "|" <> lbrace else lbrace in
1097+ let open = if Lazy `elem` l then text "|" <> lbrace else lbrace in
10801098 bracket p 2 $
10811099 if size sc > breakingSize then
10821100 open <> bindingOf n True <+> colon <+> prettySe 10 bnd ty <> rbrace <+>
@@ -1117,6 +1135,9 @@ pprintPTerm impl bnd = prettySe 10 bnd
11171135 prettySe 1 bnd l <+> prettyName impl bnd op <> line <> prettySe 0 bnd r
11181136 else
11191137 prettySe 1 bnd l <+> prettyName impl bnd op <+> prettySe 0 bnd r
1138+ prettySe p bnd (PApp _ hd@(PRef fc f) [tm])
1139+ | PConstant (Idris.Core.TT.Str str) <- getTm tm,
1140+ f == sUN "Symbol_" = char '\'' <> prettySe 10 bnd (PRef fc (sUN str))
11201141 prettySe p bnd (PApp _ f as) =
11211142 let args = getExps as
11221143 fp = prettySe 1 bnd f
src/Idris/Core/Elaborate.hs+19−11
@@ -604,17 +604,24 @@ arg n tyhole = do ty <- unique_hole tyhole
604604 forall n (Var ty)
605605
606606-- try a tactic, if it adds any unification problem, return an error
607−no_errors :: Elab' aux () -> Elab' aux ()
608−no_errors tac
609− = do ps <- get_probs
610− tac
611− ps' <- get_probs
612− if (length ps' > length ps) then
613− case reverse ps' of
614− ((x,y,env,err) : _) ->
615− let env' = map (\(x, b) -> (x, binderTy b)) env in
616− lift $ tfail $ CantUnify False x y err env' 0
617− else return $! ()
607+no_errors :: Elab' aux () -> Maybe Err -> Elab' aux ()
608+no_errors tac err
609+ = do ps <- get_probs
610+ s <- get
611+ case err of
612+ Nothing -> tac
613+ Just e -> -- update the error, if there is one.
614+ case runStateT tac s of
615+ Error _ -> lift $ Error e
616+ OK (a, s') -> do put s'
617+ return a
618+ ps' <- get_probs
619+ if (length ps' > length ps) then
620+ case reverse ps' of
621+ ((x,y,env,err) : _) ->
622+ let env' = map (\(x, b) -> (x, binderTy b)) env in
623+ lift $ tfail $ CantUnify False x y err env' 0
624+ else return $! ()
618625
619626-- Try a tactic, if it fails, try another
620627try :: Elab' aux a -> Elab' aux a -> Elab' aux a
@@ -637,6 +644,7 @@ try' t1 t2 proofSearch
637644 where recoverableErr err@(CantUnify r x y _ _ _)
638645 = -- traceWhen r (show err) $
639646 r || proofSearch
647+ recoverableErr (CantSolveGoal _ _) = False
640648 recoverableErr (ProofSearchFail _) = False
641649 recoverableErr _ = True
642650
src/Idris/Core/Evaluate.hs+9−8
@@ -228,11 +228,11 @@ eval traceon ctxt ntimes genv tm opts = ev ntimes [] True [] tm where
228228 ev ntimes stk top env (P nt n ty)
229229 = liftM (VP nt n) (ev ntimes stk top env ty)
230230 ev ntimes stk top env (V i)
231− | i < length env && i >= 0 = return $ env !! i
231+ | i < length env && i >= 0 = return $ snd (env !! i)
232232 | otherwise = return $ VV i
233233 ev ntimes stk top env (Bind n (Let t v) sc)
234234 = do v' <- ev ntimes stk top env v --(finalise v)
235− sc' <- ev ntimes stk top (v' : env) sc
235+ sc' <- ev ntimes stk top ((n, v') : env) sc
236236 wknV (-1) sc'
237237-- | otherwise
238238-- = do t' <- ev ntimes stk top env t
@@ -247,12 +247,13 @@ eval traceon ctxt ntimes genv tm opts = ev ntimes [] True [] tm where
247247 ev ntimes stk top env (Bind n (NLet t v) sc)
248248 = do t' <- ev ntimes stk top env (finalise t)
249249 v' <- ev ntimes stk top env (finalise v)
250− sc' <- ev ntimes stk top (v' : env) sc
250+ sc' <- ev ntimes stk top ((n, v') : env) sc
251251 return $ VBind True n (Let t' v') (\x -> return sc')
252252 ev ntimes stk top env (Bind n b sc)
253253 = do b' <- vbind env b
254+ let n' = uniqueName n (map fst env)
254255 return $ VBind True -- (vinstances 0 sc < 2)
255− n b' (\x -> ev ntimes stk False (x:env) sc)
256+ n' b' (\x -> ev ntimes stk False ((n, x):env) sc)
256257 where vbind env t
257258-- | simpl
258259-- = fmapMB (\tm -> ev ((MN 0 "STOP", 0) : ntimes)
@@ -345,7 +346,7 @@ eval traceon ctxt ntimes genv tm opts = ev ntimes [] True [] tm where
345346-- _ -> return $ unload env f args
346347-- specApply stk env f args = return $ unload env f args
347348
348− unload :: [Value] -> Value -> [Value] -> Value
349+ unload :: [(Name, Value)] -> Value -> [Value] -> Value
349350 unload env f [] = f
350351 unload env f (a:as) = unload env (VApp f a) as
351352
@@ -360,12 +361,12 @@ eval traceon ctxt ntimes genv tm opts = ev ntimes [] True [] tm where
360361 | otherwise = return (Nothing, args)
361362
362363 evTree :: [(Name, Int)] -> [Name] -> Bool ->
363− [Value] -> [(Name, Value)] -> SC -> Eval (Maybe Value)
364+ [(Name, Value)] -> [(Name, Value)] -> SC -> Eval (Maybe Value)
364365 evTree ntimes stk top env amap (UnmatchedCase str) = return Nothing
365366 evTree ntimes stk top env amap (STerm tm)
366367 = do let etm = pToVs (map fst amap) tm
367368 etm' <- ev ntimes stk (not (conHeaded tm))
368− (map snd amap ++ env) etm
369+ (amap ++ env) etm
369370 return $ Just etm'
370371 evTree ntimes stk top env amap (ProjCase t alts)
371372 = do t' <- ev ntimes stk top env t
@@ -394,7 +395,7 @@ eval traceon ctxt ntimes genv tm opts = ev ntimes [] True [] tm where
394395 chooseAlt env f' (getValArgs f')
395396 alts amap
396397
397− chooseAlt :: [Value] -> Value -> (Value, [Value]) -> [CaseAlt] ->
398+ chooseAlt :: [(Name, Value)] -> Value -> (Value, [Value]) -> [CaseAlt] ->
398399 [(Name, Value)] ->
399400 Eval (Maybe ([(Name, Value)], SC))
400401 chooseAlt env _ (VP (DCon i a) _ _, args) alts amap
src/Idris/Core/TT.hs+105−32
@@ -99,40 +99,45 @@ data ErrorReportPart = TextPart String
9999
100100-- | Idris errors. Used as exceptions in the compiler, but reported to users
101101-- if they reach the top level.
102−data Err = Msg String
102+data Err' t
103+ = Msg String
103104 | InternalMsg String
104− | CantUnify Bool Term Term Err [(Name, Type)] Int
105+ | CantUnify Bool t t (Err' t) [(Name, t)] Int
105106 -- Int is 'score' - how much we did unify
106107 -- Bool indicates recoverability, True indicates more info may make
107108 -- unification succeed
108− | InfiniteUnify Name Term [(Name, Type)]
109− | CantConvert Term Term [(Name, Type)]
110− | UnifyScope Name Name Term [(Name, Type)]
109+ | InfiniteUnify Name t [(Name, t)]
110+ | CantConvert t t [(Name, t)]
111+ | CantSolveGoal t [(Name, t)]
112+ | UnifyScope Name Name t [(Name, t)]
111113 | CantInferType String
112− | NonFunctionType Term Term
113− | NotEquality Term Term
114+ | NonFunctionType t t
115+ | NotEquality t t
114116 | TooManyArguments Name
115− | CantIntroduce Term
117+ | CantIntroduce t
116118 | NoSuchVariable Name
117119 | NoTypeDecl Name
118− | NotInjective Term Term Term
119− | CantResolve Term
120+ | NotInjective t t t
121+ | CantResolve t
120122 | CantResolveAlts [String]
121− | IncompleteTerm Term
123+ | IncompleteTerm t
122124 | UniverseError
123125 | ProgramLineComment
124126 | Inaccessible Name
125127 | NonCollapsiblePostulate Name
126128 | AlreadyDefined Name
127− | ProofSearchFail Err
128− | NoRewriting Term
129− | At FC Err
130− | Elaborating String Name Err
129+ | ProofSearchFail (Err' t)
130+ | NoRewriting t
131+ | At FC (Err' t)
132+ | Elaborating String Name (Err' t)
131133 | ProviderError String
132− | LoadingFailed String Err
133− | ReflectionError [[ErrorReportPart]] Err
134− | ReflectionFailed String Err
135− deriving Eq
134+ | LoadingFailed String (Err' t)
135+ | ReflectionError [[ErrorReportPart]] (Err' t)
136+ | ReflectionFailed String (Err' t)
137+ deriving (Eq, Functor)
138+
139+type Err = Err' Term
140+
136141{-!
137142deriving instance NFData Err
138143!-}
@@ -164,6 +169,7 @@ score (CantUnify _ _ _ m _ s) = s + score m
164169score (CantResolve _) = 20
165170score (NoSuchVariable _) = 1000
166171score (ProofSearchFail _) = 10000
172+score (CantSolveGoal _ _) = 10000
167173score (InternalMsg _) = -1
168174score _ = 0
169175
@@ -172,6 +178,7 @@ instance Show Err where
172178 show (InternalMsg s) = "Internal error: " ++ show s
173179 show (CantUnify _ l r e sc i) = "CantUnify " ++ show l ++ " " ++ show r ++ " "
174180 ++ show e ++ " in " ++ show sc ++ " " ++ show i
181+ show (CantSolveGoal g _) = "CantSolve " ++ show g
175182 show (Inaccessible n) = show n ++ " is not an accessible pattern variable"
176183 show (ProviderError msg) = "Type provider error: " ++ msg
177184 show (LoadingFailed fn e) = "Loading " ++ fn ++ " failed: (TT) " ++ show e
@@ -346,6 +353,8 @@ emptyContext = Map.empty
346353mapCtxt :: (a -> b) -> Ctxt a -> Ctxt b
347354mapCtxt = fmap . fmap
348355
356+-- |Return True if the argument 'Name' should be interpreted as the name of a
357+-- typeclass.
349358tcname (UN xs) | T.null xs = False
350359 | otherwise = T.head xs == '@'
351360tcname (NS n _) = tcname n
@@ -515,11 +524,18 @@ deriving instance Binary Raw
515524deriving instance NFData Raw
516525!-}
517526
518−-- | All binding forms are represented in a unform fashion.
527+-- The type parameter `b` will normally be something like `TT Name` or just
528+-- `Raw`. We do not make a type-level distinction between TT terms that happen
529+-- to be TT types and TT terms that are not TT types.
530+-- | All binding forms are represented in a uniform fashion. This type only represents
531+-- the types of bindings (and their values, if any); the attached identifiers are part
532+-- of the 'Bind' constructor for the 'TT' type.
519533data Binder b = Lam { binderTy :: !b {-^ type annotation for bound variable-}}
520534 | Pi { binderTy :: !b }
535+ {-^ A binding that occurs in a function type expression, e.g. @(x:Int) -> ...@ -}
521536 | Let { binderTy :: !b,
522537 binderVal :: b {-^ value for bound variable-}}
538+ -- ^ A binding that occurs in a @let@ expression
523539 | NLet { binderTy :: !b,
524540 binderVal :: b }
525541 | Hole { binderTy :: !b}
@@ -528,6 +544,7 @@ data Binder b = Lam { binderTy :: !b {-^ type annotation for bound variable-}
528544 | Guess { binderTy :: !b,
529545 binderVal :: b }
530546 | PVar { binderTy :: !b }
547+ -- ^ A pattern variable
531548 | PVTy { binderTy :: !b }
532549 deriving (Show, Eq, Ord, Functor)
533550{-!
@@ -606,8 +623,8 @@ type UCs = (Int, [UConstraint])
606623
607624data NameType = Bound
608625 | Ref
609− | DCon Int Int -- ^ Data constructor; Ints are tag and arity
610− | TCon Int Int -- ^ Type constructor; Ints are tag and arity
626+ | DCon {nt_tag :: Int, nt_arity :: Int} -- ^ Data constructor
627+ | TCon {nt_tag :: Int, nt_arity :: Int} -- ^ Type constructor
611628 deriving (Show, Ord)
612629{-!
613630deriving instance Binary NameType
@@ -627,8 +644,12 @@ instance Eq NameType where
627644 TCon _ a == TCon _ b = (a == b) -- ignore tag
628645 _ == _ = False
629646
630−-- | Terms in the core language
631−data TT n = P NameType n (TT n) -- ^ named references
647+-- | Terms in the core language. The type parameter is the type of
648+-- identifiers used for bindings and explicit named references;
649+-- usually we use @TT 'Name'@.
650+data TT n = P NameType n (TT n) -- ^ named references with type
651+ -- (P for "Parameter", motivated by McKinna and Pollack's
652+ -- Pure Type Systems Formalized)
632653 | V !Int -- ^ a resolved de Bruijn-indexed variable
633654 | Bind n !(Binder (TT n)) (TT n) -- ^ a binding
634655 | App !(TT n) (TT n) -- ^ function, function type, arg
@@ -652,10 +673,14 @@ instance TermSize a => TermSize [a] where
652673 termsize n (x : xs) = termsize n x + termsize n xs
653674
654675instance TermSize (TT Name) where
655− termsize n (P _ x _)
656− | x == n = 1000000 -- recursive => really big
676+ termsize n (P _ n' _)
677+ | n' == n = 1000000 -- recursive => really big
657678 | otherwise = 1
658679 termsize n (V _) = 1
680+ -- for `Bind` terms, we can erroneously declare a term
681+ -- "recursive => really big" if the name of the bound
682+ -- variable is the same as the name we're using
683+ -- So generate a different name in that case.
659684 termsize n (Bind n' (Let t v) sc)
660685 = let rn = if n == n' then sMN 0 "noname" else n in
661686 termsize rn v + termsize rn sc
@@ -721,6 +746,7 @@ vinstances i (Bind x b sc) = instancesB b + vinstances (i + 1) sc
721746 instancesB _ = 0
722747vinstances i t = 0
723748
749+-- | Replace the outermost (index 0) de Bruijn variable with the given term
724750instantiate :: TT n -> TT n -> TT n
725751instantiate e = subst 0 where
726752 subst i (V x) | i == x = e
@@ -729,6 +755,9 @@ instantiate e = subst 0 where
729755 subst i (Proj x idx) = Proj (subst i x) idx
730756 subst i t = t
731757
758+-- | As 'instantiate', but also decrement the indices of all de Bruijn variables
759+-- remaining in the term, so that there are no more references to the variable
760+-- that has been substituted.
732761substV :: TT n -> TT n -> TT n
733762substV x tm = dropV 0 (instantiate x tm) where
734763 dropV i (V x) | x > i = V (x - 1)
@@ -738,6 +767,8 @@ substV x tm = dropV 0 (instantiate x tm) where
738767 dropV i (Proj x idx) = Proj (dropV i x) idx
739768 dropV i t = t
740769
770+-- | Replace all non-free de Bruijn references in the given term with references
771+-- to the name of their binding.
741772explicitNames :: TT n -> TT n
742773explicitNames (Bind x b sc) = let b' = fmap explicitNames b in
743774 Bind x b'
@@ -747,6 +778,8 @@ explicitNames (App f a) = App (explicitNames f) (explicitNames a)
747778explicitNames (Proj x idx) = Proj (explicitNames x) idx
748779explicitNames t = t
749780
781+-- | Replace references to the given 'Name'-like id with references to
782+-- de Bruijn index 0.
750783pToV :: Eq n => n -> TT n -> TT n
751784pToV n = pToV' n 0
752785pToV' n i (P _ x _) | n == x = V i
@@ -776,6 +809,9 @@ pToVs ns tm = pToVs' ns tm 0 where
776809 pToVs' [] tm i = tm
777810 pToVs' (n:ns) tm i = pToV' n i (pToVs' ns tm (i+1))
778811
812+-- | Replace de Bruijn indices in the given term with explicit references to
813+-- the names of the bindings they refer to. It is an error if the given term
814+-- contains free de Bruijn indices.
779815vToP :: TT n -> TT n
780816vToP = vToP' [] where
781817 vToP' env (V i) = let (n, b) = (env !! i) in
@@ -785,6 +821,8 @@ vToP = vToP' [] where
785821 vToP' env (App f a) = App (vToP' env f) (vToP' env a)
786822 vToP' env t = t
787823
824+-- | Replace every non-free reference to the name of a binding in
825+-- the given term with a de Bruijn index.
788826finalise :: Eq n => TT n -> TT n
789827finalise (Bind x b sc) = Bind x (fmap finalise b) (pToV x (finalise sc))
790828finalise (App f a) = App (finalise f) (finalise a)
@@ -799,7 +837,12 @@ pEraseType (App f a) = App (pEraseType f) (pEraseType a)
799837pEraseType (Bind n b sc) = Bind n (fmap pEraseType b) (pEraseType sc)
800838pEraseType t = t
801839
802−subst :: Eq n => n -> TT n -> TT n -> TT n
840+-- | As 'instantiate', but in addition to replacing @'V' 0@,
841+-- replace references to the given 'Name'-like id.
842+subst :: Eq n => n {-^ The id to replace -} ->
843+ TT n {-^ The replacement term -} ->
844+ TT n {-^ The term to replace in -} ->
845+ TT n
803846subst n v tm = instantiate v (pToV n tm)
804847
805848-- If there are no Vs in the term (i.e. in proof state)
@@ -812,19 +855,25 @@ psubst n v tm = s' tm where
812855 s' (Proj t idx) = Proj (s' t) idx
813856 s' t = t
814857
858+-- | As 'subst', but takes a list of (name, substitution) pairs instead
859+-- of a single name and substitution
815860substNames :: Eq n => [(n, TT n)] -> TT n -> TT n
816861substNames [] t = t
817862substNames ((n, tm) : xs) t = subst n tm (substNames xs t)
818863
819−substTerm :: Eq n => TT n -> TT n -> TT n -> TT n
864+-- | Replaces all terms equal (in the sense of @(==)@) to
865+-- the old term with the new term.
866+substTerm :: Eq n => TT n {-^ Old term -} ->
867+ TT n {-^ New term -} ->
868+ TT n {-^ template term -}
869+ -> TT n
820870substTerm old new = st where
821871 st t | t == old = new
822872 st (App f a) = App (st f) (st a)
823873 st (Bind x b sc) = Bind x (fmap st b) (st sc)
824874 st t = t
825875
826−-- Returns true if V 0 and bound name n do not occur in the term
827−
876+-- | Returns true if V 0 and bound name n do not occur in the term
828877noOccurrence :: Eq n => n -> TT n -> Bool
829878noOccurrence n t = no' 0 t
830879 where
@@ -859,6 +908,8 @@ unApply t = ua [] t where
859908 ua args (App f a) = ua (a:args) f
860909 ua args t = (t, args)
861910
911+-- | Returns a term representing the application of the first argument
912+-- (a function) to every element of the second argument.
862913mkApp :: TT n -> [TT n] -> TT n
863914mkApp f [] = f
864915mkApp f (a:as) = mkApp (App f a) as
@@ -871,6 +922,10 @@ unList tm = case unApply tm of
871922 return $ x:rest
872923 (f, args) -> Nothing
873924
925+-- | Cast a 'TT' term to a 'Raw' value, discarding universe information and
926+-- the types of named references and replacing all de Bruijn indices
927+-- with the corresponding name. It is an error if there are free de
928+-- Bruijn indices.
874929forget :: TT Name -> Raw
875930forget tm = fe [] tm
876931 where
@@ -885,13 +940,21 @@ forget tm = fe [] tm
885940 fe env (TType i) = RType
886941 fe env Erased = RConstant Forgot
887942
943+-- | Introduce a 'Bind' into the given term for each element of the
944+-- given list of (name, binder) pairs.
888945bindAll :: [(n, Binder (TT n))] -> TT n -> TT n
889−bindAll [] t =t
946+bindAll [] t = t
890947bindAll ((n, b) : bs) t = Bind n b (bindAll bs t)
891948
949+-- | Like 'bindAll', but the 'Binder's are 'TT' terms instead.
950+-- The first argument is a function to map @TT@ terms to @Binder@s.
951+-- This function might often be something like 'Lam', which directly
952+-- constructs a @Binder@ from a @TT@ term.
892953bindTyArgs :: (TT n -> Binder (TT n)) -> [(n, TT n)] -> TT n -> TT n
893954bindTyArgs b xs = bindAll (map (\ (n, ty) -> (n, b ty)) xs)
894955
956+-- | Return a list of pairs of the names of the outermost 'Pi'-bound
957+-- variables in the given term, together with their types.
895958getArgTys :: TT n -> [(n, TT n)]
896959getArgTys (Bind n (Pi t) sc) = (n, t) : getArgTys sc
897960getArgTys _ = []
@@ -939,7 +1002,7 @@ type Type = Term
9391002
9401003type Env = EnvTT Name
9411004
942−-- an environment with de Bruijn indices 'normalised' so that they all refer to
1005+-- | an environment with de Bruijn indices 'normalised' so that they all refer to
9431006-- this environment
9441007
9451008newtype WkEnvTT n = Wk (EnvTT n)
@@ -977,6 +1040,7 @@ instance Show Const where
9771040 show PtrType = "Ptr"
9781041 show VoidType = "Void"
9791042
1043+showEnv :: (Eq n, Show n) => EnvTT n -> TT n -> String
9801044showEnv env t = showEnv' env t False
9811045showEnvDbg env t = showEnv' env t True
9821046
@@ -1014,6 +1078,7 @@ prettyEnv env t = prettyEnv' env t False
10141078 prettySe p env Erased debug = text "[_]"
10151079 prettySe p env (TType i) debug = text "Type" <+> (text . show $ i)
10161080
1081+ -- Render a `Binder` and its name
10171082 prettySb env n (Lam t) = prettyB env "λ" "=>" n t
10181083 prettySb env n (Hole t) = prettyB env "?defer" "." n t
10191084 prettySb env n (Pi t) = prettyB env "(" ") ->" n t
@@ -1022,9 +1087,14 @@ prettyEnv env t = prettyEnv' env t False
10221087 prettySb env n (Let t v) = prettyBv env "let" "in" n t v
10231088 prettySb env n (Guess t v) = prettyBv env "??" "in" n t v
10241089
1090+ -- Use `op` and `sc` to delimit `n` (a binding name) and its type
1091+ -- declaration
1092+ -- e.g. "λx : Int =>" for the Lam case
10251093 prettyB env op sc n t debug =
10261094 text op <> pretty n <+> colon <+> prettySe 10 env t debug <> text sc
10271095
1096+ -- Like `prettyB`, but handle the bindings that have values in addition
1097+ -- to names and types
10281098 prettyBv env op sc n t v debug =
10291099 text op <> pretty n <+> colon <+> prettySe 10 env t debug <+> text "=" <+>
10301100 prettySe 10 env v debug <> text sc
@@ -1097,9 +1167,12 @@ weakenEnv env = wk (length env - 1) env
10971167 weakenTmB i (Guess t v) = Guess (weakenTm i t) (weakenTm i v)
10981168 weakenTmB i t = t { binderTy = weakenTm i (binderTy t) }
10991169
1170+-- | Weaken every term in the environment by the given amount
11001171weakenTmEnv :: Int -> EnvTT n -> EnvTT n
11011172weakenTmEnv i = map (\ (n, b) -> (n, fmap (weakenTm i) b))
11021173
1174+-- | Gather up all the outer 'PVar's and 'Hole's in an expression and reintroduce
1175+-- them in a canonical order
11031176orderPats :: Term -> Term
11041177orderPats tm = op [] tm
11051178 where
src/Idris/Core/Unify.hs+25−5
@@ -35,22 +35,24 @@ match_unify :: Context -> Env -> TT Name -> TT Name -> [Name] -> [Name] ->
3535 TC [(Name, TT Name)]
3636match_unify ctxt env topx topy dont holes =
3737 case runStateT (un [] topx topy) (UI 0 []) of
38− OK (v, UI _ []) -> return (trimSolutions v)
38+ OK (v, UI _ []) -> return (map (renameBinders env) (trimSolutions v))
3939 res ->
4040 let topxn = normalise ctxt env topx
4141 topyn = normalise ctxt env topy in
4242 case runStateT (un [] topxn topyn)
4343 (UI 0 []) of
4444 OK (v, UI _ fails) ->
45− return (trimSolutions v)
45+ return (map (renameBinders env) (trimSolutions v))
4646 Error e ->
4747 -- just normalise the term we're matching against
4848 case runStateT (un [] topxn topy)
4949 (UI 0 []) of
5050 OK (v, UI _ fails) ->
51− return (trimSolutions v)
51+ return (map (renameBinders env) (trimSolutions v))
5252 _ -> tfail e
5353 where
54+
55+
5456 un names (P _ x _) tm
5557 | holeIn env x || x `elem` holes
5658 = do sc 1; checkCycle names (x, tm)
@@ -127,6 +129,23 @@ match_unify ctxt env topx topy dont holes =
127129 (inst ns tm) (errEnv env))
128130 where inst [] tm = tm
129131 inst ((n, _) : ns) tm = inst ns (substV (P Bound n Erased) tm)
132+
133+renameBinders :: Env -> (Name, TT Name) -> (Name, TT Name)
134+renameBinders env (x, tm) = (x, uniqueBinders tm)
135+ where
136+ uniqueBinders (Bind n b sc)
137+ | n `elem` map fst env
138+ = let n' = uniqueName n (map fst env) in
139+ Bind n' (fmap uniqueBinders b)
140+ (uniqueBinders (rename n n' sc))
141+ | otherwise = Bind n (fmap uniqueBinders b) (uniqueBinders sc)
142+ uniqueBinders (App f a) = App (uniqueBinders f) (uniqueBinders a)
143+ uniqueBinders t = t
144+
145+ rename n n' (P nt x ty) | n == x = P nt n' ty
146+ rename n n' (Bind x b sc) = Bind x (fmap (rename n n') b) (rename n n' sc)
147+ rename n n' (App f a) = App (rename n n' f) (rename n n' a)
148+ rename n n' t = t
130149
131150trimSolutions ns = dropPairs ns
132151 where dropPairs [] = []
@@ -154,7 +173,7 @@ unify ctxt env topx topy dont holes =
154173-- trace ("Unifying " ++ show (topx, topy)) $
155174 -- don't bother if topx and topy are different at the head
156175 case runStateT (un False [] topx topy) (UI 0 []) of
157− OK (v, UI _ []) -> return (trimSolutions v,
176+ OK (v, UI _ []) -> return (map (renameBinders env) (trimSolutions v),
158177 [])
159178 res ->
160179 let topxn = normalise ctxt env topx
@@ -163,7 +182,8 @@ unify ctxt env topx topy dont holes =
163182 case runStateT (un False [] topxn topyn)
164183 (UI 0 []) of
165184 OK (v, UI _ fails) ->
166− return (trimSolutions v, reverse fails)
185+ return (map (renameBinders env) (trimSolutions v),
186+ reverse fails)
167187-- Error e@(CantUnify False _ _ _ _ _) -> tfail e
168188 Error e -> tfail e
169189 where
src/Idris/Coverage.hs+5−5
@@ -56,7 +56,7 @@ genClauses fc n xs given
5656 -- there may be more case splitting that the idris_implicits record
5757 -- suggests)
5858 let parg = case lookupCtxt n (idris_implicits i) of
59− (p : _) -> p ++ repeat (PExp 0 False Placeholder "")
59+ (p : _) -> p ++ repeat (PExp 0 [] Placeholder "")
6060 _ -> repeat (pexp Placeholder)
6161 let tryclauses = mkClauses parg all_args
6262 logLvl 2 $ show (length tryclauses) ++ " initially to check"
@@ -183,7 +183,7 @@ genAll i args
183183 let p = resugar (PApp fc (PRef fc n) (zipWith upd xs' xs))
184184 let tyn = getTy n (tt_ctxt i)
185185 case lookupCtxt tyn (idris_datatypes i) of
186− (TI ns _ _ : _) -> p : map (mkPat fc) (ns \\ [n])
186+ (TI ns _ _ _ : _) -> p : map (mkPat fc) (ns \\ [n])
187187 _ -> [p]
188188 ops fc n arg o = return Placeholder
189189
@@ -289,7 +289,7 @@ calcProd i fc topn pats
289289 cotype (DCon _ _) n ty
290290 | (P _ t _, _) <- unApply (getRetTy ty)
291291 = case lookupCtxt t (idris_datatypes i) of
292− [TI _ True _] -> True
292+ [TI _ True _ _] -> True
293293 _ -> False
294294 cotype nt n ty = False
295295
@@ -466,7 +466,7 @@ buildSCG' ist pats args = nub $ concatMap scgPat pats where
466466
467467 isInductive (P _ nty _) (P _ nty' _) =
468468 let co = case lookupCtxt nty (idris_datatypes ist) of
469− [TI _ x _] -> x
469+ [TI _ x _ _] -> x
470470 _ -> False in
471471 nty == nty' && not co
472472 isInductive _ _ = False
@@ -507,7 +507,7 @@ buildSCG' ist sc args = -- trace ("Building SCG for " ++ show sc) $
507507 [ty] = lookupTy n ctxt -- must exist!
508508 P _ nty _ = fst (unApply (getRetTy ty))
509509 co = case lookupCtxt nty (idris_datatypes ist) of
510− [TI _ x _] -> x
510+ [TI _ x _ _] -> x
511511 _ -> False
512512 args = map snd (getArgTys ty) in
513513 map (getRel co nty) (map (fst . unApply . getRetTy) args)
src/Idris/DeepSeq.hs+4−1
@@ -53,6 +53,9 @@ instance NFData Static where
5353 rnf Static = ()
5454 rnf Dynamic = ()
5555
56+instance NFData ArgOpt where
57+ rnf _ = ()
58+
5659instance NFData Plicity where
5760 rnf (Imp x1 x2 x3 x4)
5861 = rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` rnf x4 `seq` ()
@@ -240,7 +243,7 @@ instance NFData OptInfo where
240243 = rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` rnf x4 `seq` ()
241244
242245instance NFData TypeInfo where
243− rnf (TI x1 x2 x3) = rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` ()
246+ rnf (TI x1 x2 x3 x4) = rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` rnf x4 `seq` ()
244247
245248instance (NFData t) => NFData (DSL' t) where
246249 rnf (DSL x1 x2 x3 x4 x5 x6 x7 x8 x9)
src/Idris/Delaborate.hs+37−35
@@ -8,6 +8,7 @@ module Idris.Delaborate where
88import Idris.AbsSyntax
99import Idris.Core.TT
1010import Idris.Core.Evaluate
11+import Idris.ErrReverse
1112
1213import Data.List (intersperse)
1314
@@ -121,76 +122,77 @@ indented text = boxIt '\n' $ unlines $ map ('\t':) $ lines text where
121122 else [c]
122123
123124pshow :: IState -> Err -> String
124−pshow i (Msg s) = s
125−pshow i (InternalMsg s) = "INTERNAL ERROR: " ++ show s ++
125+pshow i err = pshow' i (fmap (errReverse i) err)
126+
127+pshow' i (Msg s) = s
128+pshow' i (InternalMsg s) = "INTERNAL ERROR: " ++ show s ++
126129 "\nThis is probably a bug, or a missing error message.\n" ++
127130 "Please consider reporting at " ++ bugaddr
128−pshow i (CantUnify _ x y e sc s) =
131+pshow' i (CantUnify _ x y e sc s) =
129132 "Can't unify" ++ indented (showTm i (delab i x)) ++
130133 "with" ++ indented (showTm i (delab i y)) ++
131134 case e of
132135 Msg "" -> ""
133136 _ -> "\nSpecifically:" ++
134− indented (pshow i e) ++
137+ indented (pshow' i e) ++
135138 if (opt_errContext (idris_options i)) then showSc i sc else ""
136−pshow i (CantConvert x y env) =
139+pshow' i (CantConvert x y env) =
137140 "Can't convert" ++ indented (showTm i (delab i x)) ++
138141 "with" ++ indented (showTm i (delab i y)) ++
139142 if (opt_errContext (idris_options i)) then showSc i env else ""
140−pshow i (UnifyScope n out tm env) =
143+pshow' i (UnifyScope n out tm env) =
141144 "Can't unify" ++ indented (show n) ++
142145 "with" ++ indented (showTm i (delab i tm)) ++
143146 "as" ++ indented (show out) ++ "is not in scope" ++
144147 if (opt_errContext (idris_options i)) then showSc i env else ""
145−pshow i (CantInferType t) = "Can't infer type for " ++ t
146−pshow i (NonFunctionType f ty) =
148+pshow' i (CantInferType t) = "Can't infer type for " ++ t
149+pshow' i (NonFunctionType f ty) =
147150 showTm i (delab i f) ++
148151 " does not have a function type (" ++
149152 showTm i (delab i ty) ++ ")"
150−pshow i (NotEquality tm ty) =
153+pshow' i (NotEquality tm ty) =
151154 showTm i (delab i tm) ++
152155 " does not have an equality type (" ++
153156 showTm i (delab i ty) ++ ")"
154−pshow i (TooManyArguments f) = "Too many arguments for " ++ show f
155−pshow i (CantIntroduce ty) =
157+pshow' i (TooManyArguments f) = "Too many arguments for " ++ show f
158+pshow' i (CantIntroduce ty) =
156159 "Can't use lambda here: type is " ++ showTm i (delab i ty)
157−pshow i (InfiniteUnify x tm env)
160+pshow' i (InfiniteUnify x tm env)
158161 = "Unifying " ++ showbasic x ++ " and " ++ showTm i (delab i tm) ++
159162 " would lead to infinite value" ++
160163 if (opt_errContext (idris_options i)) then showSc i env else ""
161−pshow i (NotInjective p x y) =
164+pshow' i (NotInjective p x y) =
162165 "Can't verify injectivity of " ++ showTm i (delab i p) ++
163166 " when unifying " ++ showTm i (delab i x) ++ " and " ++
164167 showTm i (delab i y)
165−pshow i (CantResolve c) = "Can't resolve type class " ++ show (delab i c)
166−pshow i (CantResolveAlts as) = "Can't disambiguate name: " ++ showSep ", " as
167−pshow i (NoTypeDecl n) = "No type declaration for " ++ show n
168−pshow i (NoSuchVariable n) = "No such variable " ++ show n
169−pshow i (IncompleteTerm t) = "Incomplete term " ++ showTm i (delab i t)
170−pshow i UniverseError = "Universe inconsistency"
171−pshow i ProgramLineComment = "Program line next to comment"
172−pshow i (Inaccessible n) = show n ++ " is not an accessible pattern variable"
173−pshow i (NonCollapsiblePostulate n)
174− = "The return type of postulate " ++ show n ++ " is not collapsible"
175−pshow i (AlreadyDefined n) = show n ++ " is already defined"
176−pshow i (ProofSearchFail e) = pshow i e
177−pshow i (NoRewriting tm) = "rewrite did not change type " ++ show (delab i tm)
178−pshow i (At f e) = show f ++ ":" ++ pshow i e
179−pshow i (Elaborating s n e) = "When elaborating " ++ s ++
180− showqual i n ++ ":\n" ++ pshow i e
181−pshow i (ProviderError msg) = "Type provider error: " ++ msg
182−pshow i (LoadingFailed fn e) = "Loading " ++ fn ++ " failed: " ++ pshow i e
183−pshow i (ReflectionError parts orig) = let parts' = map (concat . intersperse " " . map showPart) parts in
168+pshow' i (CantResolve c) = "Can't resolve type class " ++ show (delab i c)
169+pshow' i (CantResolveAlts as) = "Can't disambiguate name: " ++ showSep ", " as
170+pshow' i (NoTypeDecl n) = "No type declaration for " ++ show n
171+pshow' i (NoSuchVariable n) = "No such variable " ++ show n
172+pshow' i (IncompleteTerm t) = "Incomplete term " ++ showTm i (delab i t)
173+pshow' i UniverseError = "Universe inconsistency"
174+pshow' i ProgramLineComment = "Program line next to comment"
175+pshow' i (Inaccessible n) = show n ++ " is not an accessible pattern variable"
176+pshow' i (NonCollapsiblePostulate n) = "The return type of postulate " ++ show n ++ " is not collapsible"
177+pshow' i (AlreadyDefined n) = show n ++ " is already defined"
178+pshow' i (ProofSearchFail e) = pshow' i e
179+pshow' i (NoRewriting tm) = "rewrite did not change type " ++ show (delab i tm)
180+pshow' i (At f e) = show f ++ ":" ++ pshow' i e
181+pshow' i (Elaborating s n e) = "When elaborating " ++ s ++
182+ showqual i n ++ ":\n" ++ pshow' i e
183+pshow' i (ProviderError msg) = "Type provider error: " ++ msg
184+pshow' i (LoadingFailed fn e) = "Loading " ++ fn ++ " failed: " ++ pshow' i e
185+pshow' i (ReflectionError parts orig) = let parts' = map (concat . intersperse " " . map showPart) parts in
184186 concat (intersperse "\n" parts') ++
185− "\nOriginal error:\n" ++ indented (pshow i orig)
187+ "\nOriginal error:\n" ++ indented (pshow' i orig)
186188 where showPart :: ErrorReportPart -> String
187189 showPart (TextPart str) = str
188190 showPart (NamePart n) = let colour = idris_colourRepl i in
189191 showName (Just i) [] False colour n
190192 showPart (TermPart tm) = showTm i (delab i tm)
191193 showPart (SubReport rs) = indented . concat . intersperse " " . map showPart $ rs
192−pshow i (ReflectionFailed msg err) = "When attempting to perform error reflection, the following internal error occurred:\n" ++
193− indented (pshow i err) ++
194+pshow' i (ReflectionFailed msg err) = "When attempting to perform error reflection, the following internal error occurred:\n" ++
195+ indented (pshow' i err) ++
194196 "\nThis is probably a bug. Please consider reporting it at " ++ bugaddr
195197
196198
src/Idris/ElabDecls.hs+24−8
@@ -100,7 +100,7 @@ elabType' norm info syn doc fc opts n ty' = {- let ty' = piBind (params info) ty
100100 let (t, _) = unApply (getRetTy nty')
101101 let corec = case t of
102102 P _ rcty _ -> case lookupCtxt rcty (idris_datatypes i) of
103− [TI _ True _] -> True
103+ [TI _ True _ _] -> True
104104 _ -> False
105105 _ -> False
106106 let opts' = if corec then (Coinductive : opts) else opts
@@ -228,7 +228,8 @@ elabData info syn doc fc opts (PDatadecl n t_in dcons)
228228 let as = map (const Nothing) (getArgTys cty)
229229 let params = findParams (map snd cons)
230230 logLvl 2 $ "Parameters : " ++ show params
231− putIState (i { idris_datatypes = addDef n (TI (map fst cons) codata params)
231+ putIState (i { idris_datatypes =
232+ addDef n (TI (map fst cons) codata opts params)
232233 (idris_datatypes i) })
233234 addIBC (IBCDef n)
234235 addIBC (IBCData n)
@@ -842,7 +843,8 @@ elabCon info syn tn codata (doc, n, t_in, fc, forcenames)
842843 else return ()
843844 tyIs t = tclift $ tfail (At fc (Msg (show t ++ " is not " ++ show tn)))
844845
845− mkLazy (PPi pl n ty sc) = PPi (pl { plazy = True }) n ty (mkLazy sc)
846+ mkLazy (PPi pl n ty sc)
847+ = PPi (pl { pargopts = nub (Lazy : pargopts pl) }) n ty (mkLazy sc)
846848 mkLazy t = t
847849
848850 getNamePos :: Int -> PTerm -> Name -> Maybe Int
@@ -1332,7 +1334,7 @@ elabClause info opts (cnum, PClause fc fname lhs_in withs rhs_in whereblock)
13321334 return (tm, ds, is))
13331335 logLvl 5 "DONE CHECK"
13341336 logLvl 2 $ "---> " ++ show rhs'
1335− when (not (null defer)) $ iLOG $ "DEFERRED " ++ show defer
1337+ when (not (null defer)) $ iLOG $ "DEFERRED " ++ show (map fst defer)
13361338 def' <- checkDef fc defer
13371339 let def'' = map (\(n, (i, top, t)) -> (n, (i, top, t, False))) def'
13381340 addDeferred def''
@@ -1356,6 +1358,20 @@ elabClause info opts (cnum, PClause fc fname lhs_in withs rhs_in whereblock)
13561358 Error e -> ierror (At fc (CantUnify False clhsty crhsty e [] 0))
13571359 i <- getIState
13581360 checkInferred fc (delab' i crhs True True) rhs
1361+ -- if the function is declared '%error_reverse', or its type,
1362+ -- then we'll try running it in reverse to improve error messages
1363+ let (ret_fam, _) = unApply (getRetTy crhsty)
1364+ rev <- case ret_fam of
1365+ P _ rfamn _ ->
1366+ case lookupCtxt rfamn (idris_datatypes i) of
1367+ [TI _ _ dopts _] ->
1368+ return (DataErrRev `elem` dopts)
1369+ _ -> return False
1370+ _ -> return False
1371+
1372+ when (rev || ErrorReverse `elem` opts) $ do
1373+ addIBC (IBCErrRev (crhs, clhs))
1374+ addErrRev (crhs, clhs)
13591375 return $ Right (clhs, crhs)
13601376 where
13611377 decorate (NS x ns)
@@ -1908,11 +1924,11 @@ elabInstance info syn what fc cs n ps t expn ds = do
19081924 = PLam (sMN i "meth") Placeholder (lamBind (i+1) sc sc')
19091925 lamBind i _ sc = sc
19101926 methArgs i (PPi (Imp _ _ _ _) n ty sc)
1911− = PImp 0 True False n (PRef fc (sMN i "meth")) "" : methArgs (i+1) sc
1927+ = PImp 0 True [] n (PRef fc (sMN i "meth")) "" : methArgs (i+1) sc
19121928 methArgs i (PPi (Exp _ _ _ _) n ty sc)
1913− = PExp 0 False (PRef fc (sMN i "meth")) "" : methArgs (i+1) sc
1929+ = PExp 0 [] (PRef fc (sMN i "meth")) "" : methArgs (i+1) sc
19141930 methArgs i (PPi (Constraint _ _ _) n ty sc)
1915− = PConstraint 0 False (PResolveTC fc) "" : methArgs (i+1) sc
1931+ = PConstraint 0 [] (PResolveTC fc) "" : methArgs (i+1) sc
19161932 methArgs i _ = []
19171933
19181934 papp fc f [] = f
@@ -2126,7 +2142,7 @@ elabDecl' _ _ _ = return () -- skipped this time
21262142
21272143elabCaseBlock info opts d@(PClauses f o n ps)
21282144 = do addIBC (IBCDef n)
2129− logLvl 6 $ "CASE BLOCK: " ++ show (n, d)
2145+ logLvl 5 $ "CASE BLOCK: " ++ show (n, d)
21302146 let opts' = nub (o ++ opts)
21312147 -- propagate totality assertion to the new definitions
21322148 when (AssertTotal `elem` opts) $ setFlags n [AssertTotal]
src/Idris/ElabTerm.hs+8−7
@@ -222,12 +222,6 @@ elab ist info pattern opts fn tm
222222 ctxt <- get_context
223223 let (tc, _) = unApply ty
224224 let as' = pruneByType tc ctxt as
225−-- case as' of
226−-- [a] -> elab' ina a
227−-- as -> lift $ tfail $ CantResolveAlts (map showHd as)
228−-- trace ("Original " ++ show (length as, as) ++ "\n" ++
229−-- "New " ++ show (length as', as)) $
230−-- traceWhen (length as' > 1) (show as') $
231225 tryAll (zip (map (elab' ina) as') (map showHd as'))
232226 where showHd (PApp _ h _) = show h
233227 showHd x = show x
@@ -810,7 +804,9 @@ collectDeferred top t = return t
810804runTac :: Bool -> IState -> PTactic -> ElabD ()
811805runTac autoSolve ist tac
812806 = do env <- get_env
813− no_errors $ runT (fmap (addImplBound ist (map fst env)) tac)
807+ g <- goal
808+ no_errors (runT (fmap (addImplBound ist (map fst env)) tac))
809+ (Just (CantSolveGoal g (map (\(n, b) -> (n, binderTy b)) env)))
814810 where
815811 runT (Intro []) = do g <- goal
816812 attack; intro (bname g)
@@ -1414,6 +1410,11 @@ reflectErr (CantConvert t t' ctxt) =
14141410 , reflect t'
14151411 , reflectCtxt ctxt
14161412 ]
1413+reflectErr (CantSolveGoal t ctxt) =
1414+ raw_apply (Var $ reflErrName "CantSolveGoal")
1415+ [ reflect t
1416+ , reflectCtxt ctxt
1417+ ]
14171418reflectErr (UnifyScope n n' t ctxt) =
14181419 raw_apply (Var $ reflErrName "UnifyScope")
14191420 [ reflectName n
src/Idris/ErrReverse.hsnew file+72
@@ -0,0 +1,72 @@
1+{-# LANGUAGE PatternGuards #-}
2+
3+module Idris.ErrReverse where
4+
5+import Idris.AbsSyntax
6+import Idris.Core.TT
7+import Util.Pretty
8+
9+import Data.List
10+import Debug.Trace
11+
12+-- For display purposes, apply any 'error reversal' transformations so that
13+-- errors will be more readable
14+
15+errReverse :: IState -> Term -> Term
16+errReverse ist t = rewrite 5 (elideLambdas t)
17+ where
18+
19+ rewrite 0 t = t
20+ rewrite n t = let t' = foldl applyRule t (reverse (idris_errRev ist)) in
21+ if t == t' then t
22+ else rewrite (n - 1) t'
23+
24+ applyRule :: Term -> (Term, Term) -> Term
25+ applyRule t (l, r) = applyNames [] t l r
26+
27+ -- Assume pattern bindings match in l and r (if they don't just treat
28+ -- the rule as invalid and return t)
29+
30+ applyNames ns t (Bind n (PVar ty) scl) (Bind n' (PVar ty') scr)
31+ | n == n' = applyNames (n : ns) t (instantiate (P Ref n ty) scl)
32+ (instantiate (P Ref n' ty') scr)
33+ | otherwise = t
34+ applyNames ns t l r = matchTerm ns l r t
35+
36+ matchTerm ns l r t
37+ | Just nmap <- match ns l t = substNames nmap r
38+ matchTerm ns l r (App f a) = let f' = matchTerm ns l r f
39+ a' = matchTerm ns l r a in
40+ App f' a'
41+ matchTerm ns l r (Bind n b sc) = let b' = fmap (matchTerm ns l r) b
42+ sc' = matchTerm ns l r sc in
43+ Bind n b' sc'
44+ matchTerm ns l r t = t
45+
46+ match ns l t = do ms <- match' ns l t
47+ combine (nub ms)
48+
49+ -- If any duplicate mappings, it's a failure
50+ combine [] = Just []
51+ combine ((x, t) : xs)
52+ | Just _ <- lookup x xs = Nothing
53+ | otherwise = do xs' <- combine xs
54+ Just ((x, t) : xs')
55+
56+ match' ns (P Ref n _) t | n `elem` ns = Just [(n, t)]
57+ match' ns (App f a) (App f' a') = do fs <- match' ns f f'
58+ as <- match' ns a a'
59+ Just (fs ++ as)
60+ -- no matching Binds, for now...
61+ match' ns x y = if x == y then Just [] else Nothing
62+
63+ -- if the term under a lambda is huge, there's no much point in showing
64+ -- it as it won't be very enlightening.
65+
66+ elideLambdas (App f a) = App (elideLambdas f) (elideLambdas a)
67+ elideLambdas (Bind n (Lam t) sc)
68+ | size sc > 100 = P Ref (sUN "...") Erased
69+ elideLambdas (Bind n b sc)
70+ = Bind n (fmap elideLambdas b) (elideLambdas sc)
71+ elideLambdas t = t
72+
src/Idris/IBC.hs+43−13
@@ -21,14 +21,12 @@ import Control.Monad.State.Strict hiding (get, put)
2121import qualified Control.Monad.State.Strict as ST
2222import System.FilePath
2323import System.Directory
24−import Codec.Compression.Zlib
24+import Codec.Compression.Zlib (compress)
25+import Util.Zlib (decompressEither)
2526
26−import Debug.Trace
27−
28−import Paths_idris
2927
3028ibcVersion :: Word8
31−ibcVersion = 54
29+ibcVersion = 56
3230
3331data IBCFile = IBCFile { ver :: Word8,
3432 sourcefile :: FilePath,
@@ -56,6 +54,7 @@ data IBCFile = IBCFile { ver :: Word8,
5654 ibc_defs :: [(Name, Def)],
5755 ibc_docstrings :: [(Name, String)],
5856 ibc_transforms :: [(Term, Term)],
57+ ibc_errRev :: [(Term, Term)],
5958 ibc_coercions :: [Name],
6059 ibc_lineapps :: [(FilePath, Int, PTerm)],
6160 ibc_namehints :: [(Name, Name)],
@@ -67,16 +66,22 @@ deriving instance Binary IBCFile
6766!-}
6867
6968initIBC :: IBCFile
70−initIBC = IBCFile ibcVersion "" [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] []
69+initIBC = IBCFile ibcVersion "" [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] []
7170
7271loadIBC :: FilePath -> Idris ()
7372loadIBC fp = do iLOG $ "Loading ibc " ++ fp
7473 ibcf <- runIO $ (bdecode fp :: IO IBCFile)
7574 process ibcf fp
7675
76+bencode :: Binary a => FilePath -> a -> IO ()
7777bencode f d = B.writeFile f (compress (encode d))
78+
79+bdecode :: Binary b => FilePath -> IO b
7880bdecode f = do d' <- B.readFile f
79− return (decode (decompress d'))
81+ either
82+ (\(_, e) -> error $ "Invalid / corrupted zip format on " ++ show f ++ ": " ++ e)
83+ (return . decode)
84+ (decompressEither d')
8085
8186writeIBC :: FilePath -> FilePath -> Idris ()
8287writeIBC src f
@@ -204,6 +209,7 @@ ibc i (IBCAccess n a) f = return f { ibc_access = (n,a) : ibc_access f }
204209ibc i (IBCFlags n a) f = return f { ibc_flags = (n,a) : ibc_flags f }
205210ibc i (IBCTotal n a) f = return f { ibc_total = (n,a) : ibc_total f }
206211ibc i (IBCTrans t) f = return f { ibc_transforms = t : ibc_transforms f }
212+ibc i (IBCErrRev t) f = return f { ibc_errRev = t : ibc_errRev f }
207213ibc i (IBCLineApp fp l t) f
208214 = return f { ibc_lineapps = (fp,l,t) : ibc_lineapps f }
209215ibc i (IBCNameHint (n, ty)) f
@@ -243,6 +249,7 @@ process i fn
243249 pDocs (ibc_docstrings i)
244250 pCoercions (ibc_coercions i)
245251 pTrans (ibc_transforms i)
252+ pErrRev (ibc_errRev i)
246253 pLineApps (ibc_lineapps i)
247254 pNameHints (ibc_namehints i)
248255 pMetaInformation (ibc_metainformation i)
@@ -412,6 +419,9 @@ pCoercions ns = mapM_ (\ n -> addCoercion n) ns
412419pTrans :: [(Term, Term)] -> Idris ()
413420pTrans ts = mapM_ addTrans ts
414421
422+pErrRev :: [(Term, Term)] -> Idris ()
423+pErrRev ts = mapM_ addErrRev ts
424+
415425pLineApps :: [(FilePath, Int, PTerm)] -> Idris ()
416426pLineApps ls = mapM_ (\ (f, i, t) -> addInternalApp f i t) ls
417427
@@ -1008,7 +1018,7 @@ instance Binary MetaInformation where
10081018 return (DataMI x1)
10091019
10101020instance Binary IBCFile where
1011− put x@(IBCFile x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 x19 x20 x21 x22 x23 x24 x25 x26 x27 x28 x29 x30)
1021+ put x@(IBCFile x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 x19 x20 x21 x22 x23 x24 x25 x26 x27 x28 x29 x30 x31)
10121022 = {-# SCC "putIBCFile" #-}
10131023 do put x1
10141024 put x2
@@ -1040,6 +1050,7 @@ instance Binary IBCFile where
10401050 put x28
10411051 put x29
10421052 put x30
1053+ put x31
10431054 get
10441055 = do x1 <- get
10451056 if x1 == ibcVersion then
@@ -1072,17 +1083,20 @@ instance Binary IBCFile where
10721083 x28 <- get
10731084 x29 <- get
10741085 x30 <- get
1075− return (IBCFile x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 x19 x20 x21 x22 x23 x24 x25 x26 x27 x28 x29 x30)
1086+ x31 <- get
1087+ return (IBCFile x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 x19 x20 x21 x22 x23 x24 x25 x26 x27 x28 x29 x30 x31)
10761088 else return (initIBC { ver = x1 })
10771089
10781090instance Binary DataOpt where
10791091 put x = case x of
10801092 Codata -> putWord8 0
10811093 DefaultEliminator -> putWord8 1
1094+ DataErrRev -> putWord8 2
10821095 get = do i <- getWord8
10831096 case i of
10841097 0 -> return Codata
10851098 1 -> return DefaultEliminator
1099+ 2 -> return DataErrRev
10861100
10871101instance Binary FnOpt where
10881102 put x
@@ -1098,6 +1112,7 @@ instance Binary FnOpt where
10981112 Implicit -> putWord8 7
10991113 Reflection -> putWord8 8
11001114 ErrorHandler -> putWord8 9
1115+ ErrorReverse -> putWord8 10
11011116 get
11021117 = do i <- getWord8
11031118 case i of
@@ -1112,6 +1127,7 @@ instance Binary FnOpt where
11121127 7 -> return Implicit
11131128 8 -> return Reflection
11141129 9 -> return ErrorHandler
1130+ 10 -> return ErrorReverse
11151131 _ -> error "Corrupted binary data for FnOpt"
11161132
11171133instance Binary Fixity where
@@ -1149,6 +1165,18 @@ instance Binary FixDecl where
11491165 return (Fix x1 x2)
11501166
11511167
1168+instance Binary ArgOpt where
1169+ put x
1170+ = case x of
1171+ Lazy -> putWord8 0
1172+ HideDisplay -> putWord8 1
1173+ get
1174+ = do i <- getWord8
1175+ case i of
1176+ 0 -> return Lazy
1177+ 1 -> return HideDisplay
1178+ _ -> error "Corrupted binary data for Static"
1179+
11521180instance Binary Static where
11531181 put x
11541182 = case x of
@@ -1916,13 +1944,15 @@ instance Binary OptInfo where
19161944 return (Optimise x1 x2 x3 x4)
19171945
19181946instance Binary TypeInfo where
1919− put (TI x1 x2 x3) = do put x1
1920− put x2
1921− put x3
1947+ put (TI x1 x2 x3 x4) = do put x1
1948+ put x2
1949+ put x3
1950+ put x4
19221951 get = do x1 <- get
19231952 x2 <- get
19241953 x3 <- get
1925− return (TI x1 x2 x3)
1954+ x4 <- get
1955+ return (TI x1 x2 x3 x4)
19261956
19271957instance Binary SynContext where
19281958 put x
src/Idris/ParseData.hs+10−4
@@ -77,8 +77,12 @@ dataI = do reserved "data"; return []
7777{- | Parses if a data should not have a default eliminator
7878DefaultEliminator ::= 'noelim'?
7979 -}
80−defaultEliminator :: IdrisParser DataOpts
81−defaultEliminator = do option [] (do reserved "%elim"; return [DefaultEliminator])
80+dataOpts :: DataOpts -> IdrisParser DataOpts
81+dataOpts opts
82+ = do reserved "%elim"; dataOpts (DefaultEliminator : opts)
83+ <|> do reserved "%error_reverse"; dataOpts (DataErrRev : opts)
84+ <|> return opts
85+ <?> "data options"
8286
8387{- | Parses a data type declaration
8488Data ::= DocComment? Accessibility? DataI DefaultEliminator FnName TypeSig ExplicitTypeDataRest?
@@ -100,7 +104,7 @@ data_ syn = do (doc, acc, dataOpts) <- try (do
100104 doc <- option "" (docComment '|')
101105 pushIndent
102106 acc <- optional accessibility
103− elim <- defaultEliminator
107+ elim <- dataOpts []
104108 co <- dataI
105109 let dataOpts = combineDataOpts(elim ++ co)
106110 return (doc, acc, dataOpts))
@@ -146,7 +150,9 @@ data_ syn = do (doc, acc, dataOpts) <- try (do
146150 bindArgs :: [PTerm] -> PTerm -> PTerm
147151 bindArgs xs t = foldr (PPi expl (sMN 0 "_t")) t xs
148152 combineDataOpts :: DataOpts -> DataOpts
149− combineDataOpts opts = if Codata `elem` opts then delete DefaultEliminator opts else opts
153+ combineDataOpts opts = if Codata `elem` opts
154+ then delete DefaultEliminator opts
155+ else opts
150156
151157
152158{- | Parses a type constructor declaration
src/Idris/ParseExpr.hs+9−9
@@ -769,39 +769,39 @@ Pi ::=
769769
770770pi :: SyntaxInfo -> IdrisParser PTerm
771771pi syn =
772− do lazy <- if implicitAllowed syn -- laziness is top level only
773− then option False (do lchar '|'; return True)
774− else return False
772+ do opts <- if implicitAllowed syn -- laziness is top level only
773+ then option [] (do lchar '|'; return [Lazy])
774+ else return []
775775 st <- static
776776 (do try(lchar '('); xt <- typeDeclList syn; lchar ')'
777777 doc <- option "" (docComment '^')
778778 symbol "->"
779779 sc <- expr syn
780− return (bindList (PPi (Exp lazy st doc False)) xt sc)) <|> (do
780+ return (bindList (PPi (Exp opts st doc False)) xt sc)) <|> (do
781781 lchar '{'
782782 (do reserved "auto"
783− when (lazy || (st == Static)) $ fail "auto type constraints can not be lazy or static"
783+ when (Lazy `elem` opts || (st == Static)) $ fail "auto type constraints can not be lazy or static"
784784 xt <- typeDeclList syn
785785 lchar '}'
786786 symbol "->"
787787 sc <- expr syn
788788 return (bindList (PPi
789− (TacImp False Dynamic (PTactics [Trivial]) "")) xt sc))
789+ (TacImp [] Dynamic (PTactics [Trivial]) "")) xt sc))
790790 <|> (do
791791 reserved "default"
792− when (lazy || (st == Static)) $ fail "default tactic constraints can not be lazy or static"
792+ when (Lazy `elem` opts || (st == Static)) $ fail "default tactic constraints can not be lazy or static"
793793 script <- simpleExpr syn
794794 xt <- typeDeclList syn
795795 lchar '}'
796796 symbol "->"
797797 sc <- expr syn
798− return (bindList (PPi (TacImp False Dynamic script "")) xt sc))
798+ return (bindList (PPi (TacImp [] Dynamic script "")) xt sc))
799799 <|> (if implicitAllowed syn then do
800800 xt <- typeDeclList syn
801801 lchar '}'
802802 symbol "->"
803803 sc <- expr syn
804− return (bindList (PPi (Imp lazy st "" False)) xt sc)
804+ return (bindList (PPi (Imp opts st "" False)) xt sc)
805805 else do fail "no implicit arguments allowed here"))
806806 <?> "dependent type signature"
807807
src/Idris/Parser.hs+2
@@ -337,6 +337,8 @@ fnOpts opts
337337 fnOpts (AssertTotal : opts)
338338 <|> do try (lchar '%' *> reserved "error_handler");
339339 fnOpts (ErrorHandler : opts)
340+ <|> do try (lchar '%' *> reserved "error_reverse");
341+ fnOpts (ErrorReverse : opts)
340342 <|> do try (lchar '%' *> reserved "reflection");
341343 fnOpts (Reflection : opts)
342344 <|> do lchar '%'; reserved "specialise";
src/Idris/Providers.hs+1−1
@@ -11,7 +11,7 @@ import Debug.Trace
1111
1212-- | Wrap a type provider in the type of type providers
1313providerTy :: FC -> PTerm -> PTerm
14−providerTy fc tm = PApp fc (PRef fc $ sUN "Provider") [PExp 0 False tm ""]
14+providerTy fc tm = PApp fc (PRef fc $ sUN "Provider") [PExp 0 [] tm ""]
1515
1616ioret = sUN "prim_io_return"
1717ermod = sNS (sUN "Error") ["Providers"]
src/Idris/REPL.hs+1−1
@@ -738,7 +738,7 @@ process h fn (DoProofSearch updatefile l n hints)
738738 | length cs >= length n
739739 = case splitAt (length n) cs of
740740 (mv, c:cs) ->
741− if (isSpace c && mv == n)
741+ if ((isSpace c || c == ')' || c == '}') && mv == n)
742742 then addBracket brack new ++ (c : cs)
743743 else '?' : mv ++ c : updateMeta True cs n new
744744 (mv, []) -> if (mv == n) then addBracket brack new else '?' : mv
src/Util/Zlib.hsnew file+15
@@ -0,0 +1,15 @@
1+module Util.Zlib (decompressEither) where
2+
3+-- From http://stackoverflow.com/questions/10043102/how-to-catch-the-decompress-ioerror/10045963#10045963
4+import Codec.Compression.Zlib.Internal
5+import Data.ByteString.Lazy (ByteString, fromChunks)
6+import Control.Arrow (right)
7+
8+decompressEither :: ByteString -> Either (DecompressError, String) ByteString
9+decompressEither = finalise
10+ . foldDecompressStream cons nil err
11+ . decompressWithErrors zlibFormat defaultDecompressParams
12+ where err errorCode errorString = Left (errorCode, errorString)
13+ nil = Right []
14+ cons chunk = right (chunk :)
15+ finalise = right fromChunks
test/reg031/expected+1−1
@@ -1 +1 @@
1−[10, -128, -55, -1, 10, 51, 10, 52]
1+[10, 128, 201, 255, 10, 51, 10, 52]
test/reg031/reg031.idr+5−1
@@ -1,4 +1,8 @@
11module Main
22
33main : IO ()
4−main = print . map ord . unpack $ "\x0a\x80\xC9\xFF\n3\n4"
4+main = print . map val . unpack $ "\x0a\x80\xC9\xFF\n3\n4"
5+ where
6+ -- make the values positive if the backend has signed chars
7+ val : Char -> Int
8+ val = flip mod 256 . (+256) . ord