on master help sign in
Merge remote-tracking branch 'refs/remotes/upstream/master' into issue/1318
40d07c4David Raymond Christiansen
CHANGELOG+1
@@ -2,6 +2,7 @@ New in 0.9.15:
2--------------
2--------------
3* Two new tactics: skip and fail. Skip does nothing, and fail takes a string as an argument and produces it as an error.
3* Two new tactics: skip and fail. Skip does nothing, and fail takes a string as an argument and produces it as an error.
4* Corresponding reflected tactics Skip and Fail. Reflected Fail takes a list of ErrorReportParts as an argument, like error handlers produce, allowing access to the pretty-printer.
4* Corresponding reflected tactics Skip and Fail. Reflected Fail takes a list of ErrorReportParts as an argument, like error handlers produce, allowing access to the pretty-printer.
5+* Stop showing irrelevant and inaccessible internal names in the interactive prover
5* The proof arguments in the List library functions are now implicit and solved automatically
6* The proof arguments in the List library functions are now implicit and solved automatically
6
7
7New in 0.9.14:
8New in 0.9.14:
idris.cabal+22−2
@@ -1,5 +1,5 @@
1Name: idris
1Name: idris
2−Version: 0.9.14
2+Version: 0.9.14.1
3License: BSD3
3License: BSD3
4License-file: LICENSE
4License-file: LICENSE
5Author: Edwin Brady
5Author: Edwin Brady
@@ -241,6 +241,15 @@ Extra-source-files:
241 test/reg047/run
241 test/reg047/run
242 test/reg047/*.idr
242 test/reg047/*.idr
243 test/reg047/expected
243 test/reg047/expected
244+ test/reg048/run
245+ test/reg048/*.idr
246+ test/reg048/expected
247+ test/reg049/run
248+ test/reg049/*.idr
249+ test/reg049/expected
250+ test/reg050/run
251+ test/reg050/*.idr
252+ test/reg050/expected
244
253
245 test/basic001/run
254 test/basic001/run
246 test/basic001/*.idr
255 test/basic001/*.idr
@@ -542,11 +551,22 @@ Library
542 , Idris.Core.Evaluate
551 , Idris.Core.Evaluate
543 , Idris.Core.Execute
552 , Idris.Core.Execute
544 , Idris.Core.ProofState
553 , Idris.Core.ProofState
554+ , Idris.Core.ProofTerm
545 , Idris.Core.TC
555 , Idris.Core.TC
546 , Idris.Core.TT
556 , Idris.Core.TT
547 , Idris.Core.Typecheck
557 , Idris.Core.Typecheck
548 , Idris.Core.Unify
558 , Idris.Core.Unify
549
559
560+ , Idris.Elab.Utils
561+ , Idris.Elab.Type
562+ , Idris.Elab.Clause
563+ , Idris.Elab.Data
564+ , Idris.Elab.Record
565+ , Idris.Elab.Class
566+ , Idris.Elab.Instance
567+ , Idris.Elab.Provider
568+ , Idris.Elab.Value
569+
550 , Idris.AbsSyntax
570 , Idris.AbsSyntax
551 , Idris.AbsSyntaxTree
571 , Idris.AbsSyntaxTree
552 , Idris.Apropos
572 , Idris.Apropos
@@ -649,7 +669,7 @@ Library
649 , language-java >= 0.2.6
669 , language-java >= 0.2.6
650 , lens >= 4.1.1
670 , lens >= 4.1.1
651 , mtl
671 , mtl
652− , parsers >= 0.9 && < 0.11.0.2
672+ , parsers >= 0.9 && < 0.13
653 , pretty
673 , pretty
654 , process
674 , process
655 , split
675 , split
libs/base/Language/Reflection.idr+355−94
@@ -2,32 +2,44 @@ module Language.Reflection
2
2
3%access public
3%access public
4
4
5−data TTName = UN String
5+data TTName =
6− -- ^ User-provided name
6+ ||| A user-provided name
7+ UN String |
8+ ||| A name in some namespace.
9+ |||
10+ ||| The namespace is in reverse order, so `(NS (UN "foo") ["B", "A"])` represents the name `A.B.foo`
7− | NS TTName (List String)
11+ NS TTName (List String) |
8− -- ^ Root, namespaces
9− | MN Int String
10− -- ^ Machine chosen names
12+ ||| Machine-chosen names
11− | NErased
13+ MN Int String |
12− -- ^ Name of somethng which is never used in scope
14+ ||| Name of something which is never used in scope
15+ NErased
13%name TTName n, n'
16%name TTName n, n'
14
17
15implicit
18implicit
16userSuppliedName : String -> TTName
19userSuppliedName : String -> TTName
17userSuppliedName = UN
20userSuppliedName = UN
18
21
19−data TTUExp = UVar Int
22+data TTUExp =
20− -- ^ universe variable
23+ ||| Universe variable
24+ UVar Int |
25+ ||| Explicit universe level
21− | UVal Int
26+ UVal Int
22− -- ^ explicit universe variable
23%name TTUExp uexp
27%name TTUExp uexp
24
28
29+data NativeTy = IT8 | IT16 | IT32 | IT64
30+
31+data IntTy = ITFixed NativeTy | ITNative | ITBig | ITChar
32+ | ITVec NativeTy Int
33+
34+data ArithTy = ATInt Language.Reflection.IntTy | ATFloat
35+
25||| Primitive constants
36||| Primitive constants
26data Const = I Int | BI Integer | Fl Float | Ch Char | Str String
37data Const = I Int | BI Integer | Fl Float | Ch Char | Str String
27− | IType | BIType | FlType | ChType | StrType
28 | B8 Bits8 | B16 Bits16 | B32 Bits32 | B64 Bits64
38 | B8 Bits8 | B16 Bits16 | B32 Bits32 | B64 Bits64
29− | B8Type | B16Type | B32Type | B64Type
39+ | B8V Bits8x16 | B16V Bits16x8
40+ | B32V Bits32x4 | B64V Bits64x2
41+ | AType ArithTy | StrType
30− | PtrType | VoidType | Forgot
42+ | PtrType | ManagedPtrType | BufferType | VoidType | Forgot
31
43
32%name Const c, c'
44%name Const c, c'
33
45
@@ -125,91 +137,340 @@ instance Traversable Binder where
125
137
126
138
127||| Reflection of the well typed core language
139||| Reflection of the well typed core language
140+data TT =
141+ ||| A reference to some name (P for Parameter)
128−data TT = P NameType TTName TT
142+ P NameType TTName TT |
129− -- ^ named binders
130− | V Int
131− -- ^ variables
143+ ||| de Bruijn variables
144+ V Int |
145+ ||| Bind a variable
132− | Bind TTName (Binder TT) TT
146+ Bind TTName (Binder TT) TT |
133− -- ^ type annotated named bindings
147+ ||| Apply one term to another
134− | App TT TT
148+ App TT TT |
135− -- ^ (named) application of a function to a value
149+ ||| Embed a constant
136− | TConst Const
150+ TConst Const |
137− -- ^ constants
138− | Proj TT Int
139− -- ^ argument projection; runtime only
151+ ||| Argument projection; runtime only
152+ Proj TT Int |
140− | Erased
153+ ||| Erased terms
141− -- ^ erased terms
154+ Erased |
142− | Impossible
155+ ||| Impossible terms
143− -- ^ impossible terms
156+ Impossible |
157+ ||| The type of types along (with universe constraints)
144− | TType TTUExp
158+ TType TTUExp
145− -- ^ types
146−
147%name TT tm, tm'
159%name TT tm, tm'
148
160
149||| Raw terms without types
161||| Raw terms without types
162+data Raw =
163+ ||| Variables, global or local
150−data Raw = Var TTName
164+ Var TTName |
165+ ||| Bind a variable
151− | RBind TTName (Binder Raw) Raw
166+ RBind TTName (Binder Raw) Raw |
167+ ||| Application
152− | RApp Raw Raw
168+ RApp Raw Raw |
169+ ||| The type of types
153− | RType
170+ RType |
154− | RForce Raw
171+ RForce Raw |
172+ ||| Embed a constant
155− | RConstant Const
173+ RConstant Const
156−
157%name Raw tm, tm'
174%name Raw tm, tm'
158
175
159||| Error reports are a list of report parts
176||| Error reports are a list of report parts
160−data ErrorReportPart = TextPart String
177+data ErrorReportPart =
178+ ||| A human-readable string
179+ TextPart String |
180+ ||| An Idris name (to be semantically coloured)
161− | NamePart TTName
181+ NamePart TTName |
182+ ||| An Idris term, to be pretty printed
162− | TermPart TT
183+ TermPart TT |
184+ ||| An indented sub-report, to provide more details
163− | SubReport (List ErrorReportPart)
185+ SubReport (List ErrorReportPart)
164%name ErrorReportPart part, p
186%name ErrorReportPart part, p
165
187
188+||| A representation of Idris's tactics that can be returned from custom
189+||| tactic implementations. Generate these using `applyTactic`.
166−data Tactic = Try Tactic Tactic
190+data Tactic =
167− -- ^ try the first tactic and resort to the second one on failure
191+ ||| Try the first tactic and resort to the second one on failure
168− | GoalType String Tactic
192+ Try Tactic Tactic |
169− -- ^ only run if the goal has the right type
193+ ||| Only run if the goal has the right type
170− | Refine TTName
194+ GoalType String Tactic |
171− -- ^ resolve function name, find matching arguments in the
195+ ||| Resolve function name, find matching arguments in the
172− -- context and compute the proof target
196+ ||| context and compute the proof target
173− | Seq Tactic Tactic
197+ Refine TTName |
174− -- ^ apply both tactics in sequence
198+ ||| Apply both tactics in sequence
199+ Seq Tactic Tactic |
200+ ||| Intelligently construct the proof target from the context
175− | Trivial
201+ Trivial |
176− -- ^ intelligently construct the proof target from the context
177− | Search Int
178− -- ^ build a proof by applying contructors up to a maximum depth
202+ ||| Build a proof by applying contructors up to a maximum depth
179− | Instance
203+ Search Int |
180− -- ^ resolve a type class
204+ ||| Resolve a type class
205+ Instance |
206+ ||| Infer the proof target from the context
181− | Solve
207+ Solve |
182− -- ^ infer the proof target from the context
183− | Intros
184− -- ^ introduce all variables into the context
208+ ||| introduce all variables into the context
185− | Intro TTName
209+ Intros |
186− -- ^ introduce a named variable into the context, use the
210+ ||| Introduce a named variable into the context, use the
187− -- first one if the given name is not found
211+ ||| first one if the given name is not found
212+ Intro TTName |
213+ ||| Invoke the reflected rep. of another tactic
188− | ApplyTactic TT
214+ ApplyTactic TT |
189− -- ^ invoke the reflected rep. of another tactic
215+ ||| Turn a value into its reflected representation
190− | Reflect TT
216+ Reflect TT |
191− -- ^ turn a value into its reflected representation
192− | ByReflection TT
193− -- ^ use a %reflection function
217+ ||| Use a `%reflection` function
194− | Fill Raw
218+ ByReflection TT |
195− -- ^ turn a raw value back into a term
219+ ||| Turn a raw value back into a term
196− | Exact TT
220+ Fill Raw |
197− -- ^ use the given value to conclude the proof
221+ ||| Use the given value to conclude the proof
198− | Focus TTName
222+ Exact TT |
199− -- ^ focus a named hole
223+ ||| Focus on a particular hole
200− | Rewrite TT
224+ Focus TTName |
201− -- ^ rewrite using the reflected rep. of a equality proof
225+ ||| Rewrite with an equality
202− | Induction TT
226+ Rewrite TT |
203− -- ^ do induction on the particular expression
227+ ||| Perform induction on a particular expression
204− | Case TT
228+ Induction TT |
205− -- ^ do case analysis on particular expression
229+ ||| Perform case analysis on a particular expression
230+ Case TT |
231+ ||| Name a reflected term
206− | LetTac TTName TT
232+ LetTac TTName TT |
207− -- ^ name a reflected term
233+ ||| Name a reflected term and type it
208− | LetTacTy TTName TT TT
234+ LetTacTy TTName TT TT |
209− -- ^ name a reflected term and type it
235+ ||| Normalise the goal
210− | Compute
236+ Compute |
211− -- ^ normalise the context
237+ ||| Do nothing
212− | Skip
238+ Skip |
213− -- ^ do nothing
239+ ||| Fail with an error message
214− | Fail (List ErrorReportPart)
240+ Fail (List ErrorReportPart)
215%name Tactic tac, tac'
241%name Tactic tac, tac'
242+
243+
244+||| Things with a canonical representation in the TT datatype.
245+|||
246+||| This type class is intended to be used during proof automation and the
247+||| construction of custom tactics.
248+|||
249+||| @ a the type to be quoted
250+class Quotable a where
251+ ||| A representation of the type `a`.
252+ |||
253+ ||| This is to enable quoting polymorphic datatypes
254+ quotedTy : TT
255+
256+ ||| Quote a particular element of `a`.
257+ |||
258+ ||| Each equation should look something like ```quote (Foo x y) = `(Foo ~(quote x) ~(quote y))```
259+ quote : a -> TT
260+
261+instance Quotable Nat where
262+ quotedTy = `(Nat)
263+
264+ quote Z = `(Z)
265+ quote (S k) = `(S ~(quote k))
266+
267+instance Quotable Int where
268+ quotedTy = `(Int)
269+ quote x = TConst (I x)
270+
271+instance Quotable Float where
272+ quotedTy = `(Float)
273+ quote x = TConst (Fl x)
274+
275+instance Quotable Char where
276+ quotedTy = `(Char)
277+ quote x = TConst (Ch x)
278+
279+instance Quotable Bits8 where
280+ quotedTy = `(Bits8)
281+ quote x = TConst (B8 x)
282+
283+instance Quotable Bits16 where
284+ quotedTy = `(Bits16)
285+ quote x = TConst (B16 x)
286+
287+instance Quotable Bits32 where
288+ quotedTy = `(Bits32)
289+ quote x = TConst (B32 x)
290+
291+instance Quotable Bits64 where
292+ quotedTy = `(Bits64)
293+ quote x = TConst (B64 x)
294+
295+instance Quotable Integer where
296+ quotedTy = `(Integer)
297+ quote x = TConst (BI x)
298+
299+instance Quotable Bits8x16 where
300+ quotedTy = `(Bits8x16)
301+ quote x = TConst (B8V x)
302+
303+instance Quotable Bits16x8 where
304+ quotedTy = `(Bits16x8)
305+ quote x = TConst (B16V x)
306+
307+instance Quotable Bits32x4 where
308+ quotedTy = `(Bits32x4)
309+ quote x = TConst (B32V x)
310+
311+instance Quotable Bits64x2 where
312+ quotedTy = `(Bits64x2)
313+ quote x = TConst (B64V x)
314+
315+instance Quotable String where
316+ quotedTy = `(String)
317+ quote x = TConst (Str x)
318+
319+instance Quotable NameType where
320+ quotedTy = `(NameType)
321+ quote Bound = `(Bound)
322+ quote Ref = `(Ref)
323+ quote (DCon x y) = `(DCon ~(quote x) ~(quote y))
324+ quote (TCon x y) = `(TCon ~(quote x) ~(quote y))
325+
326+instance Quotable a => Quotable (List a) where
327+ quotedTy = `(List ~(quotedTy {a=a}))
328+ quote [] = `(List.Nil {a=~quotedTy})
329+ quote (x :: xs) = `(List.(::) {a=~quotedTy} ~(quote x) ~(quote xs))
330+
331+instance Quotable TTName where
332+ quotedTy = `(TTName)
333+ quote (UN x) = `(UN ~(quote x))
334+ quote (NS n xs) = `(NS ~(quote n) ~(quote xs))
335+ quote (MN x y) = `(MN ~(quote x) ~(quote y))
336+ quote NErased = `(NErased)
337+
338+instance Quotable NativeTy where
339+ quotedTy = `(NativeTy)
340+ quote IT8 = `(Reflection.IT8)
341+ quote IT16 = `(Reflection.IT16)
342+ quote IT32 = `(Reflection.IT32)
343+ quote IT64 = `(Reflection.IT64)
344+
345+instance Quotable Reflection.IntTy where
346+ quotedTy = `(Reflection.IntTy)
347+ quote (ITFixed x) = `(ITFixed ~(quote x))
348+ quote ITNative = `(Reflection.ITNative)
349+ quote ITBig = `(ITBig)
350+ quote ITChar = `(Reflection.ITChar)
351+ quote (ITVec x y) = `(ITVec ~(quote x) ~(quote y))
352+
353+instance Quotable ArithTy where
354+ quotedTy = `(ArithTy)
355+ quote (ATInt x) = `(ATInt ~(quote x))
356+ quote ATFloat = `(ATFloat)
357+
358+instance Quotable Const where
359+ quotedTy = `(Const)
360+ quote (I x) = `(I ~(quote x))
361+ quote (BI x) = `(BI ~(quote x))
362+ quote (Fl x) = `(Fl ~(quote x))
363+ quote (Ch x) = `(Ch ~(quote x))
364+ quote (Str x) = `(Str ~(quote x))
365+ quote (B8 x) = `(B8 ~(quote x))
366+ quote (B16 x) = `(B16 ~(quote x))
367+ quote (B32 x) = `(B32 ~(quote x))
368+ quote (B64 x) = `(B64 ~(quote x))
369+ quote (B8V xs) = `(B8V ~(quote xs))
370+ quote (B16V xs) = `(B16V ~(quote xs))
371+ quote (B32V xs) = `(B32V ~(quote xs))
372+ quote (B64V xs) = `(B64V ~(quote xs))
373+ quote (AType x) = `(AType ~(quote x))
374+ quote StrType = `(StrType)
375+ quote PtrType = `(PtrType)
376+ quote ManagedPtrType = `(ManagedPtrType)
377+ quote BufferType = `(BufferType)
378+ quote VoidType = `(VoidType)
379+ quote Forgot = `(Forgot)
380+
381+
382+instance Quotable TTUExp where
383+ quotedTy = `(TTUExp)
384+ quote (UVar x) = `(UVar ~(quote x))
385+ quote (UVal x) = `(UVal ~(quote x))
386+
387+mutual
388+ instance Quotable TT where
389+ quotedTy = `(TT)
390+ quote (P nt n tm) = `(P ~(quote nt) ~(quote n) ~(quote tm))
391+ quote (V x) = `(V ~(quote x))
392+ quote (Bind n b tm) = `(Bind ~(quote n) ~(assert_total (quote b)) ~(quote tm))
393+ quote (App f x) = `(App ~(quote f) ~(quote x))
394+ quote (TConst c) = `(TConst ~(quote c))
395+ quote (Proj tm x) = `(Proj ~(quote tm) ~(quote x))
396+ quote Erased = `(Erased)
397+ quote Impossible = `(Impossible)
398+ quote (TType uexp) = `(TType ~(quote uexp))
399+
400+ instance Quotable (Binder TT) where
401+ quotedTy = `(Binder TT)
402+ quote (Lam x) = `(Lam {a=TT} ~(assert_total (quote x)))
403+ quote (Pi x) = `(Pi {a=TT} ~(assert_total (quote x)))
404+ quote (Let x y) = `(Let {a=TT} ~(assert_total (quote x))
405+ ~(assert_total (quote y)))
406+ quote (NLet x y) = `(NLet {a=TT} ~(assert_total (quote x))
407+ ~(assert_total (quote y)))
408+ quote (Hole x) = `(Hole {a=TT} ~(assert_total (quote x)))
409+ quote (GHole x) = `(GHole {a=TT} ~(assert_total (quote x)))
410+ quote (Guess x y) = `(Guess {a=TT} ~(assert_total (quote x))
411+ ~(assert_total (quote y)))
412+ quote (PVar x) = `(PVar {a=TT} ~(assert_total (quote x)))
413+ quote (PVTy x) = `(PVTy {a=TT} ~(assert_total (quote x)))
414+
415+
416+instance Quotable ErrorReportPart where
417+ quotedTy = `(ErrorReportPart)
418+ quote (TextPart x) = `(TextPart ~(quote x))
419+ quote (NamePart n) = `(NamePart ~(quote n))
420+ quote (TermPart tm) = `(TermPart ~(quote tm))
421+ quote (SubReport xs) = `(SubReport ~(assert_total $ quote xs))
422+
423+mutual
424+ quoteRaw : Raw -> TT
425+ quoteRaw (Var n) = `(Var ~(quote n))
426+ quoteRaw (RBind n b tm) = `(RBind ~(quote n) ~(assert_total $ quoteRawBinder b) ~(quoteRaw tm))
427+ quoteRaw (RApp tm tm') = `(RApp ~(quoteRaw tm) ~(quoteRaw tm'))
428+ quoteRaw RType = `(RType)
429+ quoteRaw (RForce tm) = `(RForce ~(quoteRaw tm))
430+ quoteRaw (RConstant c) = `(RConstant ~(quote c))
431+
432+ quoteRawBinder : Binder Raw -> TT
433+ quoteRawBinder (Lam x) = `(Lam {a=Raw} ~(quoteRaw x))
434+ quoteRawBinder (Pi x) = `(Pi {a=Raw} ~(quoteRaw x))
435+ quoteRawBinder (Let x y) = `(Let {a=Raw} ~(quoteRaw x) ~(quoteRaw y))
436+ quoteRawBinder (NLet x y) = `(NLet {a=Raw} ~(quoteRaw x) ~(quoteRaw y))
437+ quoteRawBinder (Hole x) = `(Hole {a=Raw} ~(quoteRaw x))
438+ quoteRawBinder (GHole x) = `(GHole {a=Raw} ~(quoteRaw x))
439+ quoteRawBinder (Guess x y) = `(Guess {a=Raw} ~(quoteRaw x) ~(quoteRaw y))
440+ quoteRawBinder (PVar x) = `(PVar {a=Raw} ~(quoteRaw x))
441+ quoteRawBinder (PVTy x) = `(PVTy {a=Raw} ~(quoteRaw x))
442+
443+instance Quotable Raw where
444+ quotedTy = `(Raw)
445+ quote = quoteRaw
446+
447+instance Quotable (Binder Raw) where
448+ quotedTy = `(Binder Raw)
449+ quote = quoteRawBinder
450+
451+instance Quotable Tactic where
452+ quotedTy = `(Tactic)
453+ quote (Try tac tac') = `(Try ~(quote tac) ~(quote tac'))
454+ quote (GoalType x tac) = `(GoalType ~(quote x) ~(quote tac))
455+ quote (Refine n) = `(Refine ~(quote n))
456+ quote (Seq tac tac') = `(Seq ~(quote tac) ~(quote tac'))
457+ quote Trivial = `(Trivial)
458+ quote (Search x) = `(Search ~(quote x))
459+ quote Instance = `(Instance)
460+ quote Solve = `(Solve)
461+ quote Intros = `(Intros)
462+ quote (Intro n) = `(Intro ~(quote n))
463+ quote (ApplyTactic tm) = `(ApplyTactic ~(quote tm))
464+ quote (Reflect tm) = `(Reflect ~(quote tm))
465+ quote (ByReflection tm) = `(ByReflection ~(quote tm))
466+ quote (Fill tm) = `(Fill ~(quote tm))
467+ quote (Exact tm) = `(Exact ~(quote tm))
468+ quote (Focus n) = `(Focus ~(quote n))
469+ quote (Rewrite tm) = `(Rewrite ~(quote tm))
470+ quote (Induction tm) = `(Induction ~(quote tm))
471+ quote (Case tm) = `(Case ~(quote tm))
472+ quote (LetTac n tm) = `(LetTac ~(quote n) ~(quote tm))
473+ quote (LetTacTy n tm tm') = `(LetTacTy ~(quote n) ~(quote tm) ~(quote tm'))
474+ quote Compute = `(Compute)
475+ quote Skip = `(Skip)
476+ quote (Fail xs) = `(Fail ~(quote xs))
libs/base/Language/Reflection/Utils.idr+55−34
@@ -3,6 +3,8 @@ module Language.Reflection.Utils
3import Language.Reflection
3import Language.Reflection
4import Language.Reflection.Errors
4import Language.Reflection.Errors
5
5
6+%default total
7+
6--------------------------------------------------------
8--------------------------------------------------------
7-- Tactic construction conveniences
9-- Tactic construction conveniences
8--------------------------------------------------------
10--------------------------------------------------------
@@ -83,46 +85,65 @@ instance Show Const where
83 show (Fl f) = "(Fl " ++ show f ++ ")"
85 show (Fl f) = "(Fl " ++ show f ++ ")"
84 show (Ch c) = "(Ch " ++ show c ++ ")"
86 show (Ch c) = "(Ch " ++ show c ++ ")"
85 show (Str str) = "(Str " ++ show str ++ ")"
87 show (Str str) = "(Str " ++ show str ++ ")"
86− show IType = "IType"
87− show BIType = "BIType"
88− show FlType = "FlType"
89− show ChType = "ChType"
90− show StrType = "StrType"
91 show (B8 b) = "(B8 ...)"
88 show (B8 b) = "(B8 ...)"
92 show (B16 b) = "(B16 ...)"
89 show (B16 b) = "(B16 ...)"
93 show (B32 b) = "(B32 ...)"
90 show (B32 b) = "(B32 ...)"
94 show (B64 b) = "(B64 ...)"
91 show (B64 b) = "(B64 ...)"
95− show B8Type = "B8Type"
92+ show (B8V xs) = "(B8V ...)"
96− show B16Type = "B16Type"
93+ show (B16V xs) = "(B16V ...)"
97− show B32Type = "B32Type"
94+ show (B32V xs) = "(B32V ...)"
98− show B64Type = "B64Type"
95+ show (B64V xs) = "(B64V ...)"
96+ show (AType x) = "(AType ...)"
97+ show StrType = "StrType"
99− show PtrType = "PtrType"
98+ show PtrType = "PtrType"
99+ show ManagedPtrType = "ManagedPtrType"
100+ show BufferType = "BufferType"
100− show VoidType = "VoidType"
101+ show VoidType = "VoidType"
101− show Forgot = "Forgot"
102+ show Forgot = "Forgot"
103+
104+instance Eq NativeTy where
105+ IT8 == IT8 = True
106+ IT16 == IT16 = True
107+ IT32 == IT32 = True
108+ IT64 == IT64 = True
109+ _ == _ = False
110+
111+instance Eq Reflection.IntTy where
112+ (ITFixed x) == (ITFixed y) = x == y
113+ ITNative == ITNative = True
114+ ITBig == ITBig = True
115+ ITChar == ITChar = True
116+ (ITVec x i) == (ITVec y j) = x == y && i == j
117+ _ == _ = False
118+
119+instance Eq ArithTy where
120+ (ATInt x) == (ATInt y) = x == y
121+ ATFloat == ATFloat = True
122+ _ == _ = False
102
123
103instance Eq Const where
124instance Eq Const where
104− (I i) == (I i') = i == i'
125+ (I x) == (I y) = x == y
105− (BI n) == (BI n') = n == n'
126+ (BI x) == (BI y) = x == y
106− (Fl f) == (Fl f') = f == f'
127+ (Fl x) == (Fl y) = x == y
107− (Ch c) == (Ch c') = c == c'
128+ (Ch x) == (Ch y) = x == y
108− (Str str) == (Str str') = str == str'
129+ (Str x) == (Str y) = x == y
109− IType == IType = True
130+ (B8 x) == (B8 y) = x == y
110− BIType == BIType = True
131+ (B16 x) == (B16 y) = x == y
111− FlType == FlType = True
132+ (B32 x) == (B32 y) = x == y
112− ChType == ChType = True
133+ (B64 x) == (B64 y) = x == y
113− StrType == StrType = True
134+ (B8V xs) == (B8V ys) = False -- TODO
114− (B8 b) == (B8 b') = False -- FIXME: b == b'
135+ (B16V xs) == (B16V ys) = False -- TODO
115− (B16 b) == (B16 b') = False -- FIXME: b == b'
136+ (B32V xs) == (B32V ys) = False -- TODO
116− (B32 b) == (B32 b') = False -- FIXME: b == b'
137+ (B64V xs) == (B64V ys) = False -- TODO
117− (B64 b) == (B64 b') = False -- FIXME: b == b'
138+ (AType x) == (AType y) = x == y
118− B8Type == B8Type = True
139+ StrType == StrType = True
119− B16Type == B16Type = True
140+ PtrType == PtrType = True
120− B32Type == B32Type = True
141+ ManagedPtrType == ManagedPtrType = True
121− B64Type == B64Type = True
142+ BufferType == BufferType = True
122− PtrType == PtrType = True
143+ VoidType == VoidType = True
123− VoidType == VoidType = True
144+ Forgot == Forgot = True
124− Forgot == Forgot = True
125− x == y = False
145+ _ == _ = False
146+
126
147
127instance Show NameType where
148instance Show NameType where
128 show Bound = "Bound"
149 show Bound = "Bound"
libs/effects/Effect/File.idr+9−5
@@ -60,10 +60,10 @@ data FileIO : Effect where
60 ||| Only files that are open for reading can be read.
60 ||| Only files that are open for reading can be read.
61 ReadLine : {OpenFile Read} FileIO String
61 ReadLine : {OpenFile Read} FileIO String
62
62
63− ||| Write a line to a file.
63+ ||| Write a string to a file.
64 |||
64 |||
65 ||| Only file that are open for writing can be written to.
65 ||| Only file that are open for writing can be written to.
66− WriteLine : String -> {OpenFile Write} FileIO ()
66+ WriteString : String -> {OpenFile Write} FileIO ()
67
67
68 ||| End of file?
68 ||| End of file?
69 |||
69 |||
@@ -82,8 +82,8 @@ instance Handler FileIO IO where
82 k () ()
82 k () ()
83 handle (FH h) ReadLine k = do str <- fread h
83 handle (FH h) ReadLine k = do str <- fread h
84 k str (FH h)
84 k str (FH h)
85− handle (FH h) (WriteLine str) k = do fwrite h str
85+ handle (FH h) (WriteString str) k = do fwrite h str
86− k () (FH h)
86+ k () (FH h)
87 handle (FH h) EOF k = do e <- feof h
87 handle (FH h) EOF k = do e <- feof h
88 k e (FH h)
88 k e (FH h)
89
89
@@ -117,9 +117,13 @@ close = call $ Close
117readLine : { [FILE_IO (OpenFile Read)] } Eff String
117readLine : { [FILE_IO (OpenFile Read)] } Eff String
118readLine = call $ ReadLine
118readLine = call $ ReadLine
119
119
120+||| Write a string to a file.
121+writeString : String -> { [FILE_IO (OpenFile Write)] } Eff ()
122+writeString str = call $ WriteString str
123+
120||| Write a line to a file.
124||| Write a line to a file.
121writeLine : String -> { [FILE_IO (OpenFile Write)] } Eff ()
125writeLine : String -> { [FILE_IO (OpenFile Write)] } Eff ()
122−writeLine str = call $ WriteLine str
126+writeLine str = call $ WriteString (str ++ "\n")
123
127
124||| End of file?
128||| End of file?
125eof : { [FILE_IO (OpenFile Read)] } Eff Bool
129eof : { [FILE_IO (OpenFile Read)] } Eff Bool
libs/effects/Effects.idr+1
@@ -152,6 +152,7 @@ data Eff : (x : Type)
152 Eff t [x] xs' -> -- [x] (\v => xs) ->
152 Eff t [x] xs' -> -- [x] (\v => xs) ->
153 Eff t [l ::: x] (\v => map (l :::) (xs' v))
153 Eff t [l ::: x] (\v => map (l :::) (xs' v))
154
154
155+%no_implicit
155(>>=) : Eff a xs xs' ->
156(>>=) : Eff a xs xs' ->
156 ((val : a) -> Eff b (xs' val) xs'') -> Eff b xs xs''
157 ((val : a) -> Eff b (xs' val) xs'') -> Eff b xs xs''
157(>>=) = ebind
158(>>=) = ebind
libs/effects/Makefile+11−4
@@ -1,14 +1,21 @@
1IDRIS := idris
1IDRIS := idris
2+PKG := effects
2
3
3build:
4build:
4− $(IDRIS) --build effects.ipkg
5+ $(IDRIS) --build ${PKG}.ipkg
5
6
6clean:
7clean:
7− $(IDRIS) --clean effects.ipkg
8+ $(IDRIS) --clean ${PKG}.ipkg
8
9
9install:
10install:
10− $(IDRIS) --install effects.ipkg
11+ $(IDRIS) --install ${PKG}.ipkg
11
12
12rebuild: clean build
13rebuild: clean build
13
14
15+doc:
16+ $(IDRIS) --mkdoc ${PKG}.ipkg
17+
18+doc_clean:
19+ rm -rf ${PKG}_doc
20+
14−.PHONY: build clean install rebuild
21+.PHONY: build clean install rebuild doc doc_clean
src/Idris/AbsSyntax.hs+10−14
@@ -537,7 +537,7 @@ type1Doc = (annotate (AnnType "Type" "The type of types, one level up") $ text "
537isetPrompt :: String -> Idris ()
537isetPrompt :: String -> Idris ()
538isetPrompt p = do i <- getIState
538isetPrompt p = do i <- getIState
539 case idris_outputmode i of
539 case idris_outputmode i of
540− IdeSlave n -> runIO . putStrLn $ convSExp "set-prompt" p n
540+ IdeSlave n h -> runIO . hPutStrLn h $ convSExp "set-prompt" p n
541
541
542-- | Tell clients how much was parsed and loaded
542-- | Tell clients how much was parsed and loaded
543isetLoadedRegion :: Idris ()
543isetLoadedRegion :: Idris ()
@@ -546,8 +546,8 @@ isetLoadedRegion = do i <- getIState
546 case span of
546 case span of
547 Just fc ->
547 Just fc ->
548 case idris_outputmode i of
548 case idris_outputmode i of
549− IdeSlave n ->
549+ IdeSlave n h ->
550− runIO . putStrLn $
550+ runIO . hPutStrLn h $
551 convSExp "set-loaded-region" fc n
551 convSExp "set-loaded-region" fc n
552 Nothing -> return ()
552 Nothing -> return ()
553
553
@@ -662,10 +662,10 @@ outputTy :: Idris OutputType
662outputTy = do i <- getIState
662outputTy = do i <- getIState
663 return $ opt_outputTy $ idris_options i
663 return $ opt_outputTy $ idris_options i
664
664
665−setIdeSlave :: Bool -> Idris ()
665+setIdeSlave :: Bool -> Handle -> Idris ()
666−setIdeSlave True = do i <- getIState
666+setIdeSlave True h = do i <- getIState
667− putIState $ i { idris_outputmode = (IdeSlave 0), idris_colourRepl = False }
667+ putIState $ i { idris_outputmode = (IdeSlave 0 h), idris_colourRepl = False }
668−setIdeSlave False = return ()
668+setIdeSlave False _ = return ()
669
669
670setTargetTriple :: String -> Idris ()
670setTargetTriple :: String -> Idris ()
671setTargetTriple t = do i <- getIState
671setTargetTriple t = do i <- getIState
@@ -761,10 +761,6 @@ setColourise :: Bool -> Idris ()
761setColourise b = do i <- getIState
761setColourise b = do i <- getIState
762 putIState $ i { idris_colourRepl = b }
762 putIState $ i { idris_colourRepl = b }
763
763
764−setOutH :: Handle -> Idris ()
765−setOutH h = do i <- getIState
766− putIState $ i { idris_outh = h }
767−
768impShow :: Idris Bool
764impShow :: Idris Bool
769impShow = do i <- getIState
765impShow = do i <- getIState
770 return (opt_showimp (idris_options i))
766 return (opt_showimp (idris_options i))
@@ -793,10 +789,10 @@ logLvl l str = do i <- getIState
793 let lvl = opt_logLevel (idris_options i)
789 let lvl = opt_logLevel (idris_options i)
794 when (lvl >= l) $
790 when (lvl >= l) $
795 case idris_outputmode i of
791 case idris_outputmode i of
796− RawOutput -> do runIO $ putStrLn str
792+ RawOutput h -> do runIO $ hPutStrLn h str
797− IdeSlave n ->
793+ IdeSlave n h ->
798 do let good = SexpList [IntegerAtom (toInteger l), toSExp str]
794 do let good = SexpList [IntegerAtom (toInteger l), toSExp str]
799− runIO $ putStrLn $ convSExp "log" good n
795+ runIO . hPutStrLn h $ convSExp "log" good n
800
796
801cmdOptType :: Opt -> Idris Bool
797cmdOptType :: Opt -> Idris Bool
802cmdOptType x = do i <- getIState
798cmdOptType x = do i <- getIState
src/Idris/AbsSyntaxTree.hs+20−10
@@ -35,15 +35,24 @@ import Debug.Trace
35
35
36import Text.PrettyPrint.Annotated.Leijen
36import Text.PrettyPrint.Annotated.Leijen
37
37
38+data ElabWhat = ETypes | EDefns | EAll
39+ deriving (Show, Eq)
40+
38-- Data to pass to recursively called elaborators; e.g. for where blocks,
41-- Data to pass to recursively called elaborators; e.g. for where blocks,
39-- paramaterised declarations, etc.
42-- paramaterised declarations, etc.
40
43
44+-- rec_elabDecl is used to pass the top level elaborator into other elaborators,
45+-- so that we can have mutually recursive elaborators in separate modules without
46+-- having to much about with cyclic modules.
41data ElabInfo = EInfo { params :: [(Name, PTerm)],
47data ElabInfo = EInfo { params :: [(Name, PTerm)],
42 inblock :: Ctxt [Name], -- names in the block, and their params
48 inblock :: Ctxt [Name], -- names in the block, and their params
43 liftname :: Name -> Name,
49 liftname :: Name -> Name,
44− namespace :: Maybe [String] }
50+ namespace :: Maybe [String],
51+ rec_elabDecl :: ElabWhat -> ElabInfo -> PDecl ->
52+ Idris () }
45
53
54+toplevel :: ElabInfo
46−toplevel = EInfo [] emptyContext id Nothing
55+toplevel = EInfo [] emptyContext id Nothing (\_ _ _ -> fail "Not implemented")
47
56
48eInfoNames :: ElabInfo -> [Name]
57eInfoNames :: ElabInfo -> [Name]
49eInfoNames info = map fst (params info) ++ M.keys (inblock info)
58eInfoNames info = map fst (params info) ++ M.keys (inblock info)
@@ -118,7 +127,9 @@ ppOptionIst = ppOption . idris_options
118data LanguageExt = TypeProviders | ErrorReflection deriving (Show, Eq, Read, Ord)
127data LanguageExt = TypeProviders | ErrorReflection deriving (Show, Eq, Read, Ord)
119
128
120-- | The output mode in use
129-- | The output mode in use
121−data OutputMode = RawOutput | IdeSlave Integer deriving Show
130+data OutputMode = RawOutput Handle -- ^ Print user output directly to the handle
131+ | IdeSlave Integer Handle -- ^ Send IDE output for some request ID to the handle
132+ deriving Show
122
133
123-- | How wide is the console?
134-- | How wide is the console?
124data ConsoleWidth = InfinitelyWide -- ^ Have pretty-printer assume that lines should not be broken
135data ConsoleWidth = InfinitelyWide -- ^ Have pretty-printer assume that lines should not be broken
@@ -183,7 +194,6 @@ data IState = IState {
183 idris_outputmode :: OutputMode,
194 idris_outputmode :: OutputMode,
184 idris_colourRepl :: Bool,
195 idris_colourRepl :: Bool,
185 idris_colourTheme :: ColourTheme,
196 idris_colourTheme :: ColourTheme,
186− idris_outh :: Handle,
187 idris_errorhandlers :: [Name], -- ^ Global error handlers
197 idris_errorhandlers :: [Name], -- ^ Global error handlers
188 idris_nameIdx :: (Int, Ctxt (Int, Name)),
198 idris_nameIdx :: (Int, Ctxt (Int, Name)),
189 idris_function_errorhandlers :: Ctxt (M.Map Name (S.Set Name)), -- ^ Specific error handlers
199 idris_function_errorhandlers :: Ctxt (M.Map Name (S.Set Name)), -- ^ Specific error handlers
@@ -268,8 +278,8 @@ idrisInit = IState initContext [] [] emptyContext emptyContext emptyContext
268 emptyContext emptyContext emptyContext emptyContext
278 emptyContext emptyContext emptyContext emptyContext
269 emptyContext emptyContext
279 emptyContext emptyContext
270 [] [] [] defaultOpts 6 [] [] [] [] [] [] [] [] [] [] [] [] []
280 [] [] [] defaultOpts 6 [] [] [] [] [] [] [] [] [] [] [] [] []
271− [] [] Nothing [] Nothing [] [] Nothing Nothing [] Hidden False [] Nothing [] [] RawOutput
281+ [] [] Nothing [] Nothing [] [] Nothing Nothing [] Hidden False [] Nothing [] []
272− True defaultTheme stdout [] (0, emptyContext) emptyContext M.empty
282+ (RawOutput stdout) True defaultTheme [] (0, emptyContext) emptyContext M.empty
273 AutomaticWidth S.empty Nothing Nothing
283 AutomaticWidth S.empty Nothing Nothing
274
284
275-- | The monad for the main REPL - reading and processing files and updating
285-- | The monad for the main REPL - reading and processing files and updating
@@ -349,6 +359,7 @@ data Opt = Filename String
349 | NoBanner
359 | NoBanner
350 | ColourREPL Bool
360 | ColourREPL Bool
351 | Ideslave
361 | Ideslave
362+ | IdeslaveSocket
352 | ShowLibs
363 | ShowLibs
353 | ShowLibdir
364 | ShowLibdir
354 | ShowIncs
365 | ShowIncs
@@ -467,6 +478,7 @@ data FnOpt = Inlinable -- always evaluate when simplifying
467 | Dictionary -- type class dictionary, eval only when
478 | Dictionary -- type class dictionary, eval only when
468 -- a function argument, and further evaluation resutls
479 -- a function argument, and further evaluation resutls
469 | Implicit -- implicit coercion
480 | Implicit -- implicit coercion
481+ | NoImplicit -- do not apply implicit coercions
470 | CExport String -- export, with a C name
482 | CExport String -- export, with a C name
471 | ErrorHandler -- ^^ an error handler for use with the ErrorReflection extension
483 | ErrorHandler -- ^^ an error handler for use with the ErrorReflection extension
472 | ErrorReverse -- ^^ attempt to reverse normalise before showing in error
484 | ErrorReverse -- ^^ attempt to reverse normalise before showing in error
@@ -1625,6 +1637,7 @@ instance Sized PTerm where
1625 size (PProof tactics) = size tactics
1637 size (PProof tactics) = size tactics
1626 size (PElabError err) = size err
1638 size (PElabError err) = size err
1627 size PImpossible = 1
1639 size PImpossible = 1
1640+ size _ = 0
1628
1641
1629getPArity :: PTerm -> Int
1642getPArity :: PTerm -> Int
1630getPArity (PPi _ _ _ sc) = 1 + getPArity sc
1643getPArity (PPi _ _ _ sc) = 1 + getPArity sc
@@ -1704,7 +1717,7 @@ implicitNamesIn uvars ist tm = nub $ ni [] tm
1704 (nub (concatMap (ni env) (map snd os))
1717 (nub (concatMap (ni env) (map snd os))
1705 \\ nub (concatMap (ni env) (map fst os)))
1718 \\ nub (concatMap (ni env) (map fst os)))
1706 ni env (PLam n ty sc) = ni env ty ++ ni (n:env) sc
1719 ni env (PLam n ty sc) = ni env ty ++ ni (n:env) sc
1707− ni env (PPi p n ty sc) = niTacImp env p ++ ni env ty ++ ni (n:env) sc
1720+ ni env (PPi p n ty sc) = ni env ty ++ ni (n:env) sc
1708 ni env (PEq _ _ _ l r) = ni env l ++ ni env r
1721 ni env (PEq _ _ _ l r) = ni env l ++ ni env r
1709 ni env (PRewrite _ l r _) = ni env l ++ ni env r
1722 ni env (PRewrite _ l r _) = ni env l ++ ni env r
1710 ni env (PTyped l r) = ni env l ++ ni env r
1723 ni env (PTyped l r) = ni env l ++ ni env r
@@ -1718,9 +1731,6 @@ implicitNamesIn uvars ist tm = nub $ ni [] tm
1718 ni env (PNoImplicits tm) = ni env tm
1731 ni env (PNoImplicits tm) = ni env tm
1719 ni env _ = []
1732 ni env _ = []
1720
1733
1721− niTacImp env (TacImp _ _ scr) = ni env scr
1722− niTacImp _ _ = []
1723−
1724-- Return names which are free in the given term.
1734-- Return names which are free in the given term.
1725namesIn :: [(Name, PTerm)] -> IState -> PTerm -> [Name]
1735namesIn :: [(Name, PTerm)] -> IState -> PTerm -> [Name]
1726namesIn uvars ist tm = nub $ ni [] tm
1736namesIn uvars ist tm = nub $ ni [] tm
src/Idris/CaseSplit.hs+4−2
@@ -16,6 +16,8 @@ import Idris.Parser
16import Idris.Error
16import Idris.Error
17import Idris.Output
17import Idris.Output
18
18
19+import Idris.Elab.Value
20+
19import Idris.Core.TT
21import Idris.Core.TT
20import Idris.Core.Typecheck
22import Idris.Core.Typecheck
21import Idris.Core.Evaluate
23import Idris.Core.Evaluate
@@ -55,7 +57,7 @@ split n t'
55 = do ist <- getIState
57 = do ist <- getIState
56 -- Make sure all the names in the term are accessible
58 -- Make sure all the names in the term are accessible
57 mapM_ (\n -> setAccessibility n Public) (allNamesIn t')
59 mapM_ (\n -> setAccessibility n Public) (allNamesIn t')
58− (tm, ty, pats) <- elabValBind toplevel ELHS True (addImplPat ist t')
60+ (tm, ty, pats) <- elabValBind recinfo ELHS True (addImplPat ist t')
59 -- ASSUMPTION: tm is in normal form after elabValBind, so we don't
61 -- ASSUMPTION: tm is in normal form after elabValBind, so we don't
60 -- need to do anything special to find out what family each argument
62 -- need to do anything special to find out what family each argument
61 -- is in
63 -- is in
@@ -201,7 +203,7 @@ tidy ist tm ty = return tm
201-- tidyVar t = t
203-- tidyVar t = t
202
204
203elabNewPat :: PTerm -> Idris (Maybe PTerm)
205elabNewPat :: PTerm -> Idris (Maybe PTerm)
204−elabNewPat t = idrisCatch (do (tm, ty) <- elabVal toplevel ELHS t
206+elabNewPat t = idrisCatch (do (tm, ty) <- elabVal recinfo ELHS t
205 i <- getIState
207 i <- getIState
206 return (Just (delab i tm)))
208 return (Just (delab i tm)))
207 (\e -> do i <- getIState
209 (\e -> do i <- getIState
src/Idris/CmdOptions.hs+1
@@ -71,6 +71,7 @@ parseFlags = many $
71 flag' NoBanner (long "nobanner" <> help "Suppress the banner")
71 flag' NoBanner (long "nobanner" <> help "Suppress the banner")
72 <|> flag' Quiet (short 'q' <> long "quiet" <> help "Quiet verbosity")
72 <|> flag' Quiet (short 'q' <> long "quiet" <> help "Quiet verbosity")
73 <|> flag' Ideslave (long "ideslave")
73 <|> flag' Ideslave (long "ideslave")
74+ <|> flag' IdeslaveSocket (long "ideslave-socket")
74 <|> (Client <$> strOption (long "client"))
75 <|> (Client <$> strOption (long "client"))
75 <|> (OLogging <$> option (long "log" <> metavar "LEVEL" <> help "Debugging log level"))
76 <|> (OLogging <$> option (long "log" <> metavar "LEVEL" <> help "Debugging log level"))
76 <|> flag' NoBasePkgs (long "nobasepkgs")
77 <|> flag' NoBasePkgs (long "nobasepkgs")
src/Idris/Core/Elaborate.hs+14−16
@@ -12,6 +12,8 @@ module Idris.Core.Elaborate(module Idris.Core.Elaborate,
12 module Idris.Core.ProofState) where
12 module Idris.Core.ProofState) where
13
13
14import Idris.Core.ProofState
14import Idris.Core.ProofState
15+import Idris.Core.ProofTerm(bound_in, getProofTerm, mkProofTerm, bound_in_term,
16+ refocus)
15import Idris.Core.TT
17import Idris.Core.TT
16import Idris.Core.Evaluate
18import Idris.Core.Evaluate
17import Idris.Core.Typecheck
19import Idris.Core.Typecheck
@@ -128,10 +130,6 @@ elaborate ctxt n ty d elab = do let ps = initElaborator n ctxt ty
128 (a, ES ps' str _) <- runElab d elab ps
130 (a, ES ps' str _) <- runElab d elab ps
129 return $! (a, str)
131 return $! (a, str)
130
132
131−force_term :: Elab' aux ()
132−force_term = do ES (ps, a) l p <- get
133− put (ES (ps { pterm = force (pterm ps) }, a) l p)
134−
135-- | Modify the auxiliary state
133-- | Modify the auxiliary state
136updateAux :: (aux -> aux) -> Elab' aux ()
134updateAux :: (aux -> aux) -> Elab' aux ()
137updateAux f = do ES (ps, a) l p <- get
135updateAux f = do ES (ps, a) l p <- get
@@ -190,12 +188,12 @@ set_context ctxt = do ES (p, a) logs prev <- get
190-- get the proof term
188-- get the proof term
191get_term :: Elab' aux Term
189get_term :: Elab' aux Term
192get_term = do ES p _ _ <- get
190get_term = do ES p _ _ <- get
193− return $! (pterm (fst p))
191+ return $! (getProofTerm (pterm (fst p)))
194
192
195-- get the proof term
193-- get the proof term
196update_term :: (Term -> Term) -> Elab' aux ()
194update_term :: (Term -> Term) -> Elab' aux ()
197update_term f = do ES (p,a) logs prev <- get
195update_term f = do ES (p,a) logs prev <- get
198− let p' = p { pterm = f (pterm p) }
196+ let p' = p { pterm = mkProofTerm (f (getProofTerm (pterm p))) }
199 put (ES (p', a) logs prev)
197 put (ES (p', a) logs prev)
200
198
201-- get the local context at the currently in focus hole
199-- get the local context at the currently in focus hole
@@ -271,7 +269,7 @@ unique_hole' :: Bool -> Name -> Elab' aux Name
271unique_hole' reusable n
269unique_hole' reusable n
272 = do ES p _ _ <- get
270 = do ES p _ _ <- get
273 let bs = bound_in (pterm (fst p)) ++
271 let bs = bound_in (pterm (fst p)) ++
274− bound_in (ptype (fst p))
272+ bound_in_term (ptype (fst p))
275 let nouse = holes (fst p) ++ bs ++ dontunify (fst p) ++ usedns (fst p)
273 let nouse = holes (fst p) ++ bs ++ dontunify (fst p) ++ usedns (fst p)
276 n' <- return $! uniqueNameCtxt (context (fst p)) n nouse
274 n' <- return $! uniqueNameCtxt (context (fst p)) n nouse
277 ES (p, a) s u <- get
275 ES (p, a) s u <- get
@@ -280,14 +278,6 @@ unique_hole' reusable n
280 put (ES (p { nextname = i + 1 }, a) s u)
278 put (ES (p { nextname = i + 1 }, a) s u)
281 _ -> return $! ()
279 _ -> return $! ()
282 return $! n'
280 return $! n'
283− where
284− bound_in (Bind n b sc) = n : bi b ++ bound_in sc
285− where
286− bi (Let t v) = bound_in t ++ bound_in v
287− bi (Guess t v) = bound_in t ++ bound_in v
288− bi b = bound_in (binderTy b)
289− bound_in (App f a) = bound_in f ++ bound_in a
290− bound_in _ = []
291
281
292elog :: String -> Elab' aux ()
282elog :: String -> Elab' aux ()
293elog str = do ES p logs prev <- get
283elog str = do ES p logs prev <- get
@@ -401,6 +391,13 @@ focus n = processTactic' (Focus n)
401movelast :: Name -> Elab' aux ()
391movelast :: Name -> Elab' aux ()
402movelast n = processTactic' (MoveLast n)
392movelast n = processTactic' (MoveLast n)
403
393
394+-- | Set the zipper in the proof state to point at the current sub term
395+-- (This currently happens automatically, so this will have no effect...)
396+zipHere :: Elab' aux ()
397+zipHere = do ES (ps, a) s m <- get
398+ let pt' = refocus (Just (head (holes ps))) (pterm ps)
399+ put (ES (ps { pterm = pt' }, a) s m)
400+
404matchProblems :: Bool -> Elab' aux ()
401matchProblems :: Bool -> Elab' aux ()
405matchProblems all = processTactic' (MatchProblems all)
402matchProblems all = processTactic' (MatchProblems all)
406
403
@@ -429,7 +426,7 @@ reorder_claims n = processTactic' (Reorder n)
429qed :: Elab' aux Term
426qed :: Elab' aux Term
430qed = do processTactic' QED
427qed = do processTactic' QED
431 ES p _ _ <- get
428 ES p _ _ <- get
432− return $! (pterm (fst p))
429+ return $! (getProofTerm (pterm (fst p)))
433
430
434undo :: Elab' aux ()
431undo :: Elab' aux ()
435undo = processTactic' Undo
432undo = processTactic' Undo
@@ -639,6 +636,7 @@ simple_app fun arg appstr =
639arg :: Name -> Name -> Elab' aux ()
636arg :: Name -> Name -> Elab' aux ()
640arg n tyhole = do ty <- unique_hole tyhole
637arg n tyhole = do ty <- unique_hole tyhole
641 claim ty RType
638 claim ty RType
639+ movelast ty
642 forall n (Var ty)
640 forall n (Var ty)
643
641
644-- try a tactic, if it adds any unification problem, return an error
642-- try a tactic, if it adds any unification problem, return an error
src/Idris/Core/ProofState.hs+30−105
@@ -12,6 +12,7 @@ import Idris.Core.Typecheck
12import Idris.Core.Evaluate
12import Idris.Core.Evaluate
13import Idris.Core.TT
13import Idris.Core.TT
14import Idris.Core.Unify
14import Idris.Core.Unify
15+import Idris.Core.ProofTerm
15
16
16import Control.Monad.State.Strict
17import Control.Monad.State.Strict
17import Control.Applicative hiding (empty)
18import Control.Applicative hiding (empty)
@@ -25,7 +26,7 @@ data ProofState = PS { thname :: Name,
25 holes :: [Name], -- holes still to be solved
26 holes :: [Name], -- holes still to be solved
26 usedns :: [Name], -- used names, don't use again
27 usedns :: [Name], -- used names, don't use again
27 nextname :: Int, -- name supply
28 nextname :: Int, -- name supply
28− pterm :: Term, -- current proof term
29+ pterm :: ProofTerm, -- current proof term
29 ptype :: Type, -- original goal
30 ptype :: Type, -- original goal
30 dontunify :: [Name], -- explicitly given by programmer, leave it
31 dontunify :: [Name], -- explicitly given by programmer, leave it
31 unified :: (Name, [(Name, Term)]),
32 unified :: (Name, [(Name, Term)]),
@@ -43,10 +44,6 @@ data ProofState = PS { thname :: Name,
43 while_elaborating :: [FailContext]
44 while_elaborating :: [FailContext]
44 }
45 }
45
46
46−data Goal = GD { premises :: Env,
47− goalType :: Binder Term
48− }
49−
50data Tactic = Attack
47data Tactic = Attack
51 | Claim Name Raw
48 | Claim Name Raw
52 | Reorder Name
49 | Reorder Name
@@ -141,13 +138,6 @@ instance Pretty ProofState OutputAnnotation where
141 nest nestingSize (pretty n <+> colon <+> prettyEnv env (binderTy b) <+>
138 nest nestingSize (pretty n <+> colon <+> prettyEnv env (binderTy b) <+>
142 nest nestingSize (prettyPs env bs))
139 nest nestingSize (prettyPs env bs))
143
140
144−same Nothing n = True
145−same (Just x) n = x == n
146−
147−hole (Hole _) = True
148−hole (Guess _ _) = True
149−hole _ = False
150−
151holeName i = sMN i "hole"
141holeName i = sMN i "hole"
152
142
153qshow :: Fails -> String
143qshow :: Fails -> String
@@ -165,7 +155,7 @@ match_unify' ctxt env topx topy =
165 " in " ++ show env ++
155 " in " ++ show env ++
166 "\nHoles: " ++ show (holes ps)
156 "\nHoles: " ++ show (holes ps)
167 ++ "\n"
157 ++ "\n"
168− ++ "\n" ++ show (pterm ps) ++ "\n\n"
158+ ++ "\n" ++ show (getProofTerm (pterm ps)) ++ "\n\n"
169 ) $
159 ) $
170 case match_unify ctxt env topx topy inj (holes ps) while of
160 case match_unify ctxt env topx topy inj (holes ps) while of
171 OK u -> traceWhen (unifylog ps)
161 OK u -> traceWhen (unifylog ps)
@@ -226,9 +216,11 @@ unify' ctxt env topx topy =
226-- ++ show (pterm ps)
216-- ++ show (pterm ps)
227 ++ "\n----------") $
217 ++ "\n----------") $
228 do let (h, ns) = unified ps
218 do let (h, ns) = unified ps
219+ -- solve in results (maybe unify should do this itself...)
220+ let u' = map (\(n, sol) -> (n, updateSolvedTerm u sol)) u
229 -- if a metavar has multiple solutions, make a new unification
221 -- if a metavar has multiple solutions, make a new unification
230 -- problem for each.
222 -- problem for each.
231− uns <- mergeSolutions env (u ++ ns)
223+ uns <- mergeSolutions env (u' ++ ns)
232 ps <- get
224 ps <- get
233 let (ns', probs') = updateProblems (context ps) uns
225 let (ns', probs') = updateProblems (context ps) uns
234 (fails ++ problems ps)
226 (fails ++ problems ps)
@@ -290,15 +282,14 @@ addLog str = action (\ps -> ps { plog = plog ps ++ str ++ "\n" })
290newProof :: Name -> Context -> Type -> ProofState
282newProof :: Name -> Context -> Type -> ProofState
291newProof n ctxt ty = let h = holeName 0
283newProof n ctxt ty = let h = holeName 0
292 ty' = vToP ty in
284 ty' = vToP ty in
293− PS n [h] [] 1 (Bind h (Hole ty')
285+ PS n [h] [] 1 (mkProofTerm (Bind h (Hole ty')
294− (P Bound h ty')) ty [] (h, []) []
286+ (P Bound h ty'))) ty [] (h, []) []
295 Nothing [] []
287 Nothing [] []
296 [] []
288 [] []
297 Nothing ctxt "" False False []
289 Nothing ctxt "" False False []
298
290
299type TState = ProofState -- [TacticAction])
291type TState = ProofState -- [TacticAction])
300−type RunTactic = Context -> Env -> Term -> StateT TState TC Term
292+type RunTactic = RunTactic' TState
301−type Hole = Maybe Name -- Nothing = default hole, first in list in proof state
302
293
303envAtFocus :: ProofState -> TC Env
294envAtFocus :: ProofState -> TC Env
304envAtFocus ps
295envAtFocus ps
@@ -310,64 +301,13 @@ goalAtFocus :: ProofState -> TC (Binder Type)
310goalAtFocus ps
301goalAtFocus ps
311 | not $ null (holes ps) = do g <- goal (Just (head (holes ps))) (pterm ps)
302 | not $ null (holes ps) = do g <- goal (Just (head (holes ps))) (pterm ps)
312 return (goalType g)
303 return (goalType g)
313− | otherwise = Error . Msg $ "No goal in " ++ show (holes ps) ++ show (pterm ps)
304+ | otherwise = Error . Msg $ "No goal in " ++ show (holes ps) ++ show (getProofTerm (pterm ps))
314−
315−goal :: Hole -> Term -> TC Goal
316−goal h tm = g [] tm where
317− g env (Bind n b@(Guess _ _) sc)
318− | same h n = return $ GD env b
319− | otherwise
320− = gb env b `mplus` g ((n, b):env) sc
321− g env (Bind n b sc) | hole b && same h n = return $ GD env b
322− | otherwise
323− = g ((n, b):env) sc `mplus` gb env b
324− g env (App f a) = g env f `mplus` g env a
325− g env t = fail "Can't find hole"
326−
327− gb env (Let t v) = g env v `mplus` g env t
328− gb env (Guess t v) = g env v `mplus` g env t
329− gb env t = g env (binderTy t)
330
305
331tactic :: Hole -> RunTactic -> StateT TState TC ()
306tactic :: Hole -> RunTactic -> StateT TState TC ()
332tactic h f = do ps <- get
307tactic h f = do ps <- get
333− (tm', _) <- atH (context ps) [] (pterm ps)
308+ (tm', _) <- atHole h f (context ps) [] (pterm ps)
334 ps <- get -- might have changed while processing
309 ps <- get -- might have changed while processing
335 put (ps { pterm = tm' })
310 put (ps { pterm = tm' })
336− where
337− updated o = do o' <- o
338− return (o', True)
339−
340− ulift2 c env op a b
341− = do (b', u) <- atH c env b
342− if u then return (op a b', True)
343− else do (a', u) <- atH c env a
344− return (op a' b', u)
345−
346− -- Search the things most likely to contain the binding first!
347−
348− atH :: Context -> Env -> Term -> StateT TState TC (Term, Bool)
349− atH c env binder@(Bind n b@(Guess t v) sc)
350− | same h n = updated (f c env binder)
351− | otherwise
352− = do -- binder first
353− (b', u) <- ulift2 c env Guess t v
354− if u then return (Bind n b' sc, True)
355− else do (sc', u) <- atH c ((n, b) : env) sc
356− return (Bind n b' sc', u)
357− atH c env binder@(Bind n b sc)
358− | hole b && same h n = updated (f c env binder)
359− | otherwise -- scope first
360− = do (sc', u) <- atH c ((n, b) : env) sc
361− if u then return (Bind n b sc', True)
362− else do (b', u) <- atHb c env b
363− return (Bind n b' sc', u)
364− atH c env (App f a) = ulift2 c env App f a
365− atH c env t = return (t, False)
366−
367− atHb c env (Let t v) = ulift2 c env Let t v
368− atHb c env (Guess t v) = ulift2 c env Guess t v
369− atHb c env t = do (ty', u) <- atH c env (binderTy t)
370− return (t { binderTy = ty' }, u)
371
311
372computeLet :: Context -> Name -> Term -> Term
312computeLet :: Context -> Name -> Term -> Term
373computeLet ctxt n tm = cl [] tm where
313computeLet ctxt n tm = cl [] tm where
@@ -612,7 +552,7 @@ forall n ty ctxt env (Bind x (Hole t) (P _ x' _)) | x == x' =
612forall n ty ctxt env _ = fail "Can't pi bind here"
552forall n ty ctxt env _ = fail "Can't pi bind here"
613
553
614patvar :: Name -> RunTactic
554patvar :: Name -> RunTactic
615−patvar n ctxt env (Bind x (Hole t) sc) =
555+patvar n ctxt env (Bind x (Hole t) sc) =
616 do action (\ps -> ps { holes = traceWhen (unifylog ps) ("Dropping pattern hole " ++ show x) $
556 do action (\ps -> ps { holes = traceWhen (unifylog ps) ("Dropping pattern hole " ++ show x) $
617 holes ps \\ [x],
557 holes ps \\ [x],
618 solved = Just (x, P Bound n t),
558 solved = Just (x, P Bound n t),
@@ -697,13 +637,13 @@ casetac tm induction ctxt env (Bind x (Hole t) (P _ x' _)) | x == x' = do
697 let indxargs = drop (length restargs - length indicies) $ restargs
637 let indxargs = drop (length restargs - length indicies) $ restargs
698 let scr = last $ tail args'
638 let scr = last $ tail args'
699 let indxnames = makeIndexNames indicies
639 let indxnames = makeIndexNames indicies
700− currentNames <- query $ allTTNames . pterm
640+ currentNames <- query $ allTTNames . getProofTerm . pterm
701 let tmnm = case tm of
641 let tmnm = case tm of
702 Var nm -> uniqueNameCtxt ctxt nm currentNames
642 Var nm -> uniqueNameCtxt ctxt nm currentNames
703 _ -> uniqueNameCtxt ctxt (sMN 0 "iv") currentNames
643 _ -> uniqueNameCtxt ctxt (sMN 0 "iv") currentNames
704 let tmvar = P Bound tmnm tmt'
644 let tmvar = P Bound tmnm tmt'
705 prop <- replaceIndicies indxnames indicies $ Bind tmnm (Lam tmt') (mkP tmvar tmv tmvar t)
645 prop <- replaceIndicies indxnames indicies $ Bind tmnm (Lam tmt') (mkP tmvar tmv tmvar t)
706− consargs' <- query (\ps -> map (flip (uniqueNameCtxt (context ps)) (holes ps ++ allTTNames (pterm ps)) *** uniqueBindersCtxt (context ps) (holes ps ++ allTTNames (pterm ps))) consargs)
646+ consargs' <- query (\ps -> map (flip (uniqueNameCtxt (context ps)) (holes ps ++ allTTNames (getProofTerm (pterm ps))) *** uniqueBindersCtxt (context ps) (holes ps ++ allTTNames (getProofTerm (pterm ps)))) consargs)
707 let res = flip (foldr substV) params $ (substV prop $ bindConsArgs consargs' (mkApp (P Ref (SN (tacn tnm)) (TType (UVal 0)))
647 let res = flip (foldr substV) params $ (substV prop $ bindConsArgs consargs' (mkApp (P Ref (SN (tacn tnm)) (TType (UVal 0)))
708 (params ++ [prop] ++ map makeConsArg consargs' ++ indicies ++ [tmv])))
648 (params ++ [prop] ++ map makeConsArg consargs' ++ indicies ++ [tmv])))
709 action (\ps -> ps {holes = holes ps \\ [x]})
649 action (\ps -> ps {holes = holes ps \\ [x]})
@@ -800,7 +740,7 @@ solve_unified ctxt env tm =
800 action (\ps -> ps { holes = traceWhen (unifylog ps) ("Dropping holes " ++ show (map fst unify)) $
740 action (\ps -> ps { holes = traceWhen (unifylog ps) ("Dropping holes " ++ show (map fst unify)) $
801 holes ps \\ map fst unify })
741 holes ps \\ map fst unify })
802 action (\ps -> ps { pterm = updateSolved unify (pterm ps) })
742 action (\ps -> ps { pterm = updateSolved unify (pterm ps) })
803− return (updateSolved unify tm)
743+ return (updateSolvedTerm unify tm)
804
744
805dropGiven du [] hs = []
745dropGiven du [] hs = []
806dropGiven du ((n, P Bound t ty) : us) hs
746dropGiven du ((n, P Bound t ty) : us) hs
@@ -821,26 +761,9 @@ keepGiven du (u@(n, _) : us) hs
821 | n `elem` du = u : keepGiven du us hs
761 | n `elem` du = u : keepGiven du us hs
822keepGiven du (u : us) hs = keepGiven du us hs
762keepGiven du (u : us) hs = keepGiven du us hs
823
763
824−updateSolved :: [(Name, Term)] -> Term -> Term
825−updateSolved xs x = updateSolved' xs x
826−updateSolved' [] x = x
827−updateSolved' xs (Bind n (Hole ty) t)
828− | Just v <- lookup n xs
829− = case xs of
830− [_] -> substV v $ psubst n v t -- some may be Vs! Can't assume
831− -- explicit names
832− _ -> substV v $ psubst n v (updateSolved' xs t)
833−updateSolved' xs (Bind n b t)
834− | otherwise = Bind n (fmap (updateSolved' xs) b) (updateSolved' xs t)
835−updateSolved' xs (App f a)
836− = App (updateSolved' xs f) (updateSolved' xs a)
837−updateSolved' xs (P _ n@(MN _ _) _)
838− | Just v <- lookup n xs = v
839−updateSolved' xs t = t
840−
841updateEnv [] e = e
764updateEnv [] e = e
842updateEnv ns [] = []
765updateEnv ns [] = []
843−updateEnv ns ((n, b) : env) = (n, fmap (updateSolved ns) b) : updateEnv ns env
766+updateEnv ns ((n, b) : env) = (n, fmap (updateSolvedTerm ns) b) : updateEnv ns env
844
767
845updateError [] err = err
768updateError [] err = err
846updateError ns (At f e) = At f (updateError ns e)
769updateError ns (At f e) = At f (updateError ns e)
@@ -848,7 +771,7 @@ updateError ns (Elaborating s n e) = Elaborating s n (updateError ns e)
848updateError ns (ElaboratingArg f a env e)
771updateError ns (ElaboratingArg f a env e)
849 = ElaboratingArg f a env (updateError ns e)
772 = ElaboratingArg f a env (updateError ns e)
850updateError ns (CantUnify b l r e xs sc)
773updateError ns (CantUnify b l r e xs sc)
851− = CantUnify b (updateSolved ns l) (updateSolved ns r) (updateError ns e) xs sc
774+ = CantUnify b (updateSolvedTerm ns l) (updateSolvedTerm ns r) (updateError ns e) xs sc
852updateError ns e = e
775updateError ns e = e
853
776
854solveInProblems x val [] = []
777solveInProblems x val [] = []
@@ -868,7 +791,7 @@ mergeNotunified env ns = mnu ns [] [] where
868updateNotunified [] nu = nu
791updateNotunified [] nu = nu
869updateNotunified ns nu = up nu where
792updateNotunified ns nu = up nu where
870 up [] = []
793 up [] = []
871− up ((n, t) : nus) = let t' = updateSolved ns t in
794+ up ((n, t) : nus) = let t' = updateSolvedTerm ns t in
872 ((n, t') : up nus)
795 ((n, t') : up nus)
873
796
874-- FIXME: Why not just pass the whole proof state?
797-- FIXME: Why not just pass the whole proof state?
@@ -878,8 +801,8 @@ updateProblems :: Context -> [(Name, TT Name)] -> Fails -> [Name] -> [Name] -> [
878updateProblems ctxt ns ps inj holes usupp = up ns ps where
801updateProblems ctxt ns ps inj holes usupp = up ns ps where
879 up ns [] = (ns, [])
802 up ns [] = (ns, [])
880 up ns ((x, y, env, err, while, um) : ps) =
803 up ns ((x, y, env, err, while, um) : ps) =
881− let x' = updateSolved ns x
804+ let x' = updateSolvedTerm ns x
882− y' = updateSolved ns y
805+ y' = updateSolvedTerm ns y
883 err' = updateError ns err
806 err' = updateError ns err
884 env' = updateEnv ns env in
807 env' = updateEnv ns env in
885-- trace ("Updating " ++ show (x',y')) $
808-- trace ("Updating " ++ show (x',y')) $
@@ -895,8 +818,8 @@ matchProblems all ns ctxt ps inj holes = up ns ps where
895 up ns [] = (ns, [])
818 up ns [] = (ns, [])
896 up ns ((x, y, env, err, while, um) : ps)
819 up ns ((x, y, env, err, while, um) : ps)
897 | all || um == Match =
820 | all || um == Match =
898− let x' = updateSolved ns x
821+ let x' = updateSolvedTerm ns x
899− y' = updateSolved ns y
822+ y' = updateSolvedTerm ns y
900 err' = updateError ns err
823 err' = updateError ns err
901 env' = updateEnv ns env in
824 env' = updateEnv ns env in
902 case match_unify ctxt env' x' y' inj holes while of
825 case match_unify ctxt env' x' y' inj holes while of
@@ -909,19 +832,19 @@ matchProblems all ns ctxt ps inj holes = up ns ps where
909
832
910processTactic :: Tactic -> ProofState -> TC (ProofState, String)
833processTactic :: Tactic -> ProofState -> TC (ProofState, String)
911processTactic QED ps = case holes ps of
834processTactic QED ps = case holes ps of
912− [] -> do let tm = {- normalise (context ps) [] -} (pterm ps)
835+ [] -> do let tm = {- normalise (context ps) [] -} getProofTerm (pterm ps)
913 (tm', ty', _) <- recheck (context ps) [] (forget tm) tm
836 (tm', ty', _) <- recheck (context ps) [] (forget tm) tm
914− return (ps { done = True, pterm = tm' },
837+ return (ps { done = True, pterm = mkProofTerm tm' },
915 "Proof complete: " ++ showEnv [] tm')
838 "Proof complete: " ++ showEnv [] tm')
916 _ -> fail "Still holes to fill."
839 _ -> fail "Still holes to fill."
917−processTactic ProofState ps = return (ps, showEnv [] (pterm ps))
840+processTactic ProofState ps = return (ps, showEnv [] (getProofTerm (pterm ps)))
918processTactic Undo ps = case previous ps of
841processTactic Undo ps = case previous ps of
919 Nothing -> Error . Msg $ "Nothing to undo."
842 Nothing -> Error . Msg $ "Nothing to undo."
920 Just pold -> return (pold, "")
843 Just pold -> return (pold, "")
921processTactic EndUnify ps
844processTactic EndUnify ps
922 = let (h, ns_in) = unified ps
845 = let (h, ns_in) = unified ps
923 ns = dropGiven (dontunify ps) ns_in (holes ps)
846 ns = dropGiven (dontunify ps) ns_in (holes ps)
924− ns' = map (\ (n, t) -> (n, updateSolved ns t)) ns
847+ ns' = map (\ (n, t) -> (n, updateSolvedTerm ns t)) ns
925 (ns'', probs') = updateProblems (context ps) ns' (problems ps)
848 (ns'', probs') = updateProblems (context ps) ns' (problems ps)
926 (injective ps) (holes ps)
849 (injective ps) (holes ps)
927 (map fst (notunified ps))
850 (map fst (notunified ps))
@@ -941,7 +864,9 @@ processTactic (Reorder n) ps
941 = do ps' <- execStateT (tactic (Just n) reorder_claims) ps
864 = do ps' <- execStateT (tactic (Just n) reorder_claims) ps
942 return (ps' { previous = Just ps, plog = "" }, plog ps')
865 return (ps' { previous = Just ps, plog = "" }, plog ps')
943processTactic (ComputeLet n) ps
866processTactic (ComputeLet n) ps
867+ = return (ps { pterm = mkProofTerm $
944− = return (ps { pterm = computeLet (context ps) n (pterm ps) }, "")
868+ computeLet (context ps) n
869+ (getProofTerm (pterm ps)) }, "")
945processTactic UnifyProblems ps
870processTactic UnifyProblems ps
946 = let (ns', probs') = updateProblems (context ps) []
871 = let (ns', probs') = updateProblems (context ps) []
947 (problems ps)
872 (problems ps)
@@ -977,7 +902,7 @@ processTactic t ps
977 = case solved ps' of
902 = case solved ps' of
978 Just s -> traceWhen (unifylog ps')
903 Just s -> traceWhen (unifylog ps')
979 ("SOLVED " ++ show s) $
904 ("SOLVED " ++ show s) $
980− updateProblems (context ps')
905+ updateProblems (context ps')
981 [s] (problems ps')
906 [s] (problems ps')
982 (injective ps')
907 (injective ps')
983 (holes ps')
908 (holes ps')
src/Idris/Core/ProofTerm.hsnew file+266
@@ -0,0 +1,266 @@
1+{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, PatternGuards #-}
2+
3+{- Implements a proof state, some primitive tactics for manipulating
4+ proofs, and some high level commands for introducing new theorems,
5+ evaluation/checking inside the proof system, etc. --}
6+
7+module Idris.Core.ProofTerm(ProofTerm, Goal(..), mkProofTerm, getProofTerm,
8+ updateSolved, updateSolvedTerm,
9+ bound_in, bound_in_term, refocus,
10+ Hole, RunTactic',
11+ goal, atHole) where
12+
13+import Idris.Core.Typecheck
14+import Idris.Core.Evaluate
15+import Idris.Core.TT
16+
17+import Control.Monad.State.Strict
18+import Data.List
19+import Debug.Trace
20+
21+data TermPath = Top
22+ | AppL TermPath Term
23+ | AppR Term TermPath
24+ | InBind Name BinderPath Term
25+ | InScope Name (Binder Term) TermPath
26+ deriving Show
27+
28+data BinderPath = Binder (Binder TermPath)
29+ | LetT TermPath Term
30+ | LetV Term TermPath
31+ | GuessT TermPath Term
32+ | GuessV Term TermPath
33+ deriving Show
34+
35+replaceTop :: TermPath -> TermPath -> TermPath
36+replaceTop p Top = p
37+replaceTop p (AppL l t) = AppL (replaceTop p l) t
38+replaceTop p (AppR t r) = AppR t (replaceTop p r)
39+replaceTop p (InBind n bp sc) = InBind n (replaceTopB p bp) sc
40+ where
41+ replaceTopB p (Binder b) = Binder (fmap (replaceTop p) b)
42+ replaceTopB p (LetT t v) = LetT (replaceTop p t) v
43+ replaceTopB p (LetV t v) = LetV t (replaceTop p v)
44+ replaceTopB p (GuessT t v) = GuessT (replaceTop p t) v
45+ replaceTopB p (GuessV t v) = GuessV t (replaceTop p v)
46+replaceTop p (InScope n b sc) = InScope n b (replaceTop p sc)
47+
48+rebuildTerm :: Term -> TermPath -> Term
49+rebuildTerm tm Top = tm
50+rebuildTerm tm (AppL p a) = App (rebuildTerm tm p) a
51+rebuildTerm tm (AppR f p) = App f (rebuildTerm tm p)
52+rebuildTerm tm (InScope n b p) = Bind n b (rebuildTerm tm p)
53+rebuildTerm tm (InBind n bp sc) = Bind n (rebuildBinder tm bp) sc
54+
55+rebuildBinder :: Term -> BinderPath -> Binder Term
56+rebuildBinder tm (Binder p) = fmap (rebuildTerm tm) p
57+rebuildBinder tm (LetT p t) = Let (rebuildTerm tm p) t
58+rebuildBinder tm (LetV v p) = Let v (rebuildTerm tm p)
59+rebuildBinder tm (GuessT p t) = Guess (rebuildTerm tm p) t
60+rebuildBinder tm (GuessV v p) = Guess v (rebuildTerm tm p)
61+
62+findHole :: Name -> Env -> Term -> Maybe (TermPath, Env, Term)
63+findHole n env t = fh' env Top t where
64+ fh' env path tm@(Bind x h sc)
65+ | hole h && n == x = Just (path, env, tm)
66+ fh' env path (App f a)
67+ | Just (p, env', tm) <- fh' env path a = Just (AppR f p, env', tm)
68+ | Just (p, env', tm) <- fh' env path f = Just (AppL p a, env', tm)
69+ fh' env path (Bind x b sc)
70+ | Just (bp, env', tm) <- fhB env path b = Just (InBind x bp sc, env', tm)
71+ | Just (p, env', tm) <- fh' ((x,b):env) path sc = Just (InScope x b p, env', tm)
72+ fh' _ _ _ = Nothing
73+
74+ fhB env path (Let t v)
75+ | Just (p, env', tm) <- fh' env path t = Just (LetT p v, env', tm)
76+ | Just (p, env', tm) <- fh' env path v = Just (LetV t p, env', tm)
77+ fhB env path (Guess t v)
78+ | Just (p, env', tm) <- fh' env path t = Just (GuessT p v, env', tm)
79+ | Just (p, env', tm) <- fh' env path v = Just (GuessV t p, env', tm)
80+ fhB env path b
81+ | Just (p, env', tm) <- fh' env path (binderTy b)
82+ = Just (Binder (fmap (\_ -> p) b), env', tm)
83+ fhB _ _ _ = Nothing
84+
85+data ProofTerm = PT { -- wholeterm :: Term,
86+ path :: TermPath,
87+ subterm_env :: Env,
88+ subterm :: Term,
89+ updates :: [(Name, Term)] }
90+ deriving Show
91+
92+type RunTactic' a = Context -> Env -> Term -> StateT a TC Term
93+type Hole = Maybe Name -- Nothing = default hole, first in list in proof state
94+
95+refocus :: Hole -> ProofTerm -> ProofTerm
96+refocus h t = let res = refocus' h t in res
97+-- trace ("OLD: " ++ show t ++ "\n" ++
98+-- "REFOCUSSED " ++ show h ++ ": " ++ show res) res
99+refocus' (Just n) pt@(PT path env tm ups)
100+ | Just (p', env', tm') <- findHole n env tm
101+ = PT (replaceTop p' path) env' tm' ups
102+ | Just (p', env', tm') <- findHole n [] (rebuildTerm tm (updateSolvedPath ups path))
103+ = PT p' env' tm' []
104+ | otherwise = pt
105+refocus' _ pt = pt
106+
107+data Goal = GD { premises :: Env,
108+ goalType :: Binder Term
109+ }
110+
111+mkProofTerm :: Term -> ProofTerm
112+mkProofTerm tm = PT Top [] tm []
113+
114+getProofTerm :: ProofTerm -> Term
115+getProofTerm (PT path _ sub ups) = rebuildTerm sub (updateSolvedPath ups path)
116+
117+same Nothing n = True
118+same (Just x) n = x == n
119+
120+hole (Hole _) = True
121+hole (Guess _ _) = True
122+hole _ = False
123+
124+updateSolvedTerm :: [(Name, Term)] -> Term -> Term
125+updateSolvedTerm [] x = x
126+updateSolvedTerm xs x = -- updateSolved' xs x where
127+-- This version below saves allocations, because it doesn't need to reallocate
128+-- the term if there are no updates to do, but costs an extra pass. Below
129+-- version works better on larger terms...
130+ if noneOf (map fst xs) x
131+ then x
132+ else updateSolved' xs x where
133+ updateSolved' [] x = x
134+ updateSolved' xs (Bind n (Hole ty) t)
135+ | Just v <- lookup n xs
136+ = case xs of
137+ [_] -> substV v $ psubst n v t -- some may be Vs! Can't assume
138+ -- explicit names
139+ _ -> substV v $ psubst n v (updateSolved' xs t)
140+ updateSolved' xs (Bind n b t)
141+ | otherwise = Bind n (fmap (updateSolved' xs) b) (updateSolved' xs t)
142+ updateSolved' xs (App f a)
143+ = App (updateSolved' xs f) (updateSolved' xs a)
144+ updateSolved' xs (P _ n@(MN _ _) _)
145+ | Just v <- lookup n xs = v
146+ updateSolved' xs t = t
147+
148+ noneOf ns (P _ n _) | n `elem` ns = False
149+ noneOf ns (App f a) = noneOf ns a && noneOf ns f
150+ noneOf ns (Bind n (Hole ty) t) = n `notElem` ns && noneOf ns ty && noneOf ns t
151+ noneOf ns (Bind n b t) = noneOf ns t && noneOfB ns b
152+ where
153+ noneOfB ns (Let t v) = noneOf ns t && noneOf ns v
154+ noneOfB ns (Guess t v) = noneOf ns t && noneOf ns v
155+ noneOfB ns b = noneOf ns (binderTy b)
156+ noneOf ns _ = True
157+
158+updateEnv [] e = e
159+updateEnv ns [] = []
160+updateEnv ns ((n, b) : env) = (n, fmap (updateSolvedTerm ns) b) : updateEnv ns env
161+
162+updateSolvedPath [] t = t
163+updateSolvedPath ns Top = Top
164+updateSolvedPath ns (AppL p r) = AppL p (updateSolvedTerm ns r)
165+updateSolvedPath ns (AppR l p) = AppR (updateSolvedTerm ns l) p
166+updateSolvedPath ns (InBind n b sc)
167+ = InBind n (updateSolvedPathB b) (updateSolvedTerm ns sc)
168+ where
169+ updateSolvedPathB (Binder b) = Binder (fmap (updateSolvedPath ns) b)
170+ updateSolvedPathB (LetT p v) = LetT (updateSolvedPath ns p) (updateSolvedTerm ns v)
171+ updateSolvedPathB (LetV v p) = LetV (updateSolvedTerm ns v) (updateSolvedPath ns p)
172+ updateSolvedPathB (GuessT p v) = GuessT (updateSolvedPath ns p) (updateSolvedTerm ns v)
173+ updateSolvedPathB (GuessV v p) = GuessV (updateSolvedTerm ns v) (updateSolvedPath ns p)
174+updateSolvedPath ns (InScope n (Hole ty) t)
175+ | Just v <- lookup n ns = case ns of
176+ [_] -> updateSolvedPath [(n,v)] t
177+ _ -> updateSolvedPath ns $
178+ updateSolvedPath [(n,v)] t
179+updateSolvedPath ns (InScope n b sc)
180+ = InScope n (fmap (updateSolvedTerm ns) b) (updateSolvedPath ns sc)
181+
182+updateSolved :: [(Name, Term)] -> ProofTerm -> ProofTerm
183+updateSolved xs pt@(PT path env sub ups)
184+ = PT path -- (updateSolvedPath xs path)
185+ (updateEnv xs (filter (\(n, t) -> n `notElem` map fst xs) env))
186+ (updateSolvedTerm xs sub)
187+ (ups ++ xs)
188+
189+goal :: Hole -> ProofTerm -> TC Goal
190+goal h pt@(PT path env sub ups)
191+-- | OK ginf <- g env sub = return ginf
192+ | otherwise = g [] (rebuildTerm sub (updateSolvedPath ups path))
193+ where
194+ g :: Env -> Term -> TC Goal
195+ g env (Bind n b@(Guess _ _) sc)
196+ | same h n = return $ GD env b
197+ | otherwise
198+ = gb env b `mplus` g ((n, b):env) sc
199+ g env (Bind n b sc) | hole b && same h n = return $ GD env b
200+ | otherwise
201+ = g ((n, b):env) sc `mplus` gb env b
202+ g env (App f a) = g env a `mplus` g env f
203+ g env t = fail "Can't find hole"
204+
205+ gb env (Let t v) = g env v `mplus` g env t
206+ gb env (Guess t v) = g env v `mplus` g env t
207+ gb env t = g env (binderTy t)
208+
209+atHole :: Hole -> RunTactic' a -> Context -> Env -> ProofTerm ->
210+ StateT a TC (ProofTerm, Bool)
211+atHole h f c e pt -- @(PT path env sub)
212+ = do let PT path env sub ups = refocus h pt
213+ (tm, u) <- atH f c env sub
214+ return (PT path env tm ups, u)
215+-- if u then return (PT path env tm ups, u)
216+-- else do let PT path env sub ups = refocus h pt
217+-- (tm, u) <- atH f c env sub
218+-- return (PT path env tm ups, u)
219+ where
220+ updated o = do o' <- o
221+ return (o', True)
222+
223+ ulift2 f c env op a b
224+ = do (b', u) <- atH f c env b
225+ if u then return (op a b', True)
226+ else do (a', u) <- atH f c env a
227+ return (op a' b', u)
228+
229+ -- Search the things most likely to contain the binding first!
230+
231+ atH :: RunTactic' a -> Context -> Env -> Term -> StateT a TC (Term, Bool)
232+ atH f c env binder@(Bind n b@(Guess t v) sc)
233+ | same h n = updated (f c env binder)
234+ | otherwise
235+ = do -- binder first
236+ (b', u) <- ulift2 f c env Guess t v
237+ if u then return (Bind n b' sc, True)
238+ else do (sc', u) <- atH f c ((n, b) : env) sc
239+ return (Bind n b' sc', u)
240+ atH f c env binder@(Bind n b sc)
241+ | hole b && same h n = updated (f c env binder)
242+ | otherwise -- scope first
243+ = do (sc', u) <- atH f c ((n, b) : env) sc
244+ if u then return (Bind n b sc', True)
245+ else do (b', u) <- atHb f c env b
246+ return (Bind n b' sc', u)
247+ atH tac c env (App f a) = ulift2 tac c env App f a
248+ atH tac c env t = return (t, False)
249+
250+ atHb f c env (Let t v) = ulift2 f c env Let t v
251+ atHb f c env (Guess t v) = ulift2 f c env Guess t v
252+ atHb f c env t = do (ty', u) <- atH f c env (binderTy t)
253+ return (t { binderTy = ty' }, u)
254+
255+bound_in :: ProofTerm -> [Name]
256+bound_in (PT path _ tm ups) = bound_in_term (rebuildTerm tm (updateSolvedPath ups path))
257+
258+bound_in_term :: Term -> [Name]
259+bound_in_term (Bind n b sc) = n : bi b ++ bound_in_term sc
260+ where
261+ bi (Let t v) = bound_in_term t ++ bound_in_term v
262+ bi (Guess t v) = bound_in_term t ++ bound_in_term v
263+ bi b = bound_in_term (binderTy b)
264+bound_in_term (App f a) = bound_in_term f ++ bound_in_term a
265+bound_in_term _ = []
266+
src/Idris/Core/Unify.hs+9
@@ -333,6 +333,15 @@ unify ctxt env topx topy inj holes usersupp from =
333 = unifyTmpFail tx ty
333 = unifyTmpFail tx ty
334 | injective ty && not (holeIn env x || x `elem` holes)
334 | injective ty && not (holeIn env x || x `elem` holes)
335 = unifyTmpFail tx ty
335 = unifyTmpFail tx ty
336+ -- pick the one bound earliest if both are holes
337+ | tx /= ty && (holeIn env x || x `elem` holes)
338+ && (holeIn env y || y `elem` holes)
339+ = case compare (envPos 0 x env) (envPos 0 y env) of
340+ LT -> do sc 1; checkCycle bnames (x, ty)
341+ _ -> do sc 1; checkCycle bnames (y, tx)
342+ where envPos i n ((n',_):env) | n == n' = i
343+ envPos i n (_:env) = envPos (i+1) n env
344+ envPos _ _ _ = 100000
336 un' fn bnames xtm@(P _ x _) tm
345 un' fn bnames xtm@(P _ x _) tm
337 | pureTerm tm, holeIn env x || x `elem` holes
346 | pureTerm tm, holeIn env x || x `elem` holes
338 = do UI s f <- get
347 = do UI s f <- get
src/Idris/Elab/Class.hsnew file+226
@@ -0,0 +1,226 @@
1+{-# LANGUAGE PatternGuards #-}
2+module Idris.Elab.Class(elabClass) where
3+
4+import Idris.AbsSyntax
5+import Idris.ASTUtils
6+import Idris.DSL
7+import Idris.Error
8+import Idris.Delaborate
9+import Idris.Imports
10+import Idris.ElabTerm
11+import Idris.Coverage
12+import Idris.DataOpts
13+import Idris.Providers
14+import Idris.Primitives
15+import Idris.Inliner
16+import Idris.PartialEval
17+import Idris.DeepSeq
18+import Idris.Output (iputStrLn, pshow, iWarn)
19+import IRTS.Lang
20+
21+import Idris.Elab.Type
22+import Idris.Elab.Data
23+import Idris.Elab.Utils
24+
25+import Idris.Core.TT
26+import Idris.Core.Elaborate hiding (Tactic(..))
27+import Idris.Core.Evaluate
28+import Idris.Core.Execute
29+import Idris.Core.Typecheck
30+import Idris.Core.CaseTree
31+
32+import Idris.Docstrings
33+
34+import Prelude hiding (id, (.))
35+import Control.Category
36+
37+import Control.Applicative hiding (Const)
38+import Control.DeepSeq
39+import Control.Monad
40+import Control.Monad.State.Strict as State
41+import Data.List
42+import Data.Maybe
43+import Debug.Trace
44+
45+import qualified Data.Map as Map
46+import qualified Data.Set as S
47+import qualified Data.Text as T
48+import Data.Char(isLetter, toLower)
49+import Data.List.Split (splitOn)
50+
51+import Util.Pretty(pretty, text)
52+
53+data MArgTy = IA | EA | CA deriving Show
54+
55+elabClass :: ElabInfo -> SyntaxInfo -> Docstring ->
56+ FC -> [PTerm] ->
57+ Name -> [(Name, PTerm)] -> [(Name, Docstring)] -> [PDecl] -> Idris ()
58+elabClass info syn_in doc fc constraints tn ps pDocs ds
59+ = do let cn = SN (InstanceCtorN tn) -- sUN ("instance" ++ show tn) -- MN 0 ("instance" ++ show tn)
60+ let tty = pibind ps PType
61+ let constraint = PApp fc (PRef fc tn)
62+ (map (pexp . PRef fc) (map fst ps))
63+
64+ let syn = syn_in { using = addToUsing (using syn_in) ps }
65+
66+ -- build data declaration
67+ let mdecls = filter tydecl ds -- method declarations
68+ let idecls = filter instdecl ds -- default superclass instance declarations
69+ mapM_ checkDefaultSuperclassInstance idecls
70+ let mnames = map getMName mdecls
71+ logLvl 2 $ "Building methods " ++ show mnames
72+ ims <- mapM (tdecl mnames) mdecls
73+ defs <- mapM (defdecl (map (\ (x,y,z) -> z) ims) constraint)
74+ (filter clause ds)
75+ let (methods, imethods)
76+ = unzip (map (\ ( x,y,z) -> (x, y)) ims)
77+ let defaults = map (\ (x, (y, z)) -> (x,y)) defs
78+ addClass tn (CI cn (map nodoc imethods) defaults idecls (map fst ps) [])
79+ -- build instance constructor type
80+ -- decorate names of functions to ensure they can't be referred
81+ -- to elsewhere in the class declaration
82+ let cty = impbind ps $ conbind constraints
83+ $ pibind (map (\ (n, ty) -> (nsroot n, ty)) methods)
84+ constraint
85+ let cons = [(emptyDocstring, [], cn, cty, fc, [])]
86+ let ddecl = PDatadecl tn tty cons
87+ logLvl 5 $ "Class data " ++ show (showDImp verbosePPOption ddecl)
88+ elabData info (syn { no_imp = no_imp syn ++ mnames }) doc pDocs fc [] ddecl
89+ -- for each constraint, build a top level function to chase it
90+ logLvl 5 $ "Building functions"
91+-- let usyn = syn { using = map (\ (x,y) -> UImplicit x y) ps
92+-- ++ using syn }
93+ fns <- mapM (cfun cn constraint syn (map fst imethods)) constraints
94+ mapM_ (rec_elabDecl info EAll info) (concat fns)
95+ -- for each method, build a top level function
96+ fns <- mapM (tfun cn constraint syn (map fst imethods)) imethods
97+ mapM_ (rec_elabDecl info EAll info) (concat fns)
98+ -- add the default definitions
99+ mapM_ (rec_elabDecl info EAll info) (concat (map (snd.snd) defs))
100+ addIBC (IBCClass tn)
101+ where
102+ nodoc (n, (_, o, t)) = (n, (o, t))
103+ pibind [] x = x
104+ pibind ((n, ty): ns) x = PPi expl n ty (pibind ns x)
105+
106+ mdec (UN n) = SN (MethodN (UN n))
107+ mdec (NS x n) = NS (mdec x) n
108+ mdec x = x
109+
110+ -- TODO: probably should normalise
111+ checkDefaultSuperclassInstance (PInstance _ fc cs n ps _ _ _)
112+ = do when (not $ null cs) . tclift
113+ $ tfail (At fc (Msg $ "Default superclass instances can't have constraints."))
114+ i <- getIState
115+ let t = PApp fc (PRef fc n) (map pexp ps)
116+ let isConstrained = any (== t) constraints
117+ when (not isConstrained) . tclift
118+ $ tfail (At fc (Msg $ "Default instances must be for a superclass constraint on the containing class."))
119+ return ()
120+
121+ impbind [] x = x
122+ impbind ((n, ty): ns) x = PPi impl n ty (impbind ns x)
123+ conbind (ty : ns) x = PPi constraint (sMN 0 "class") ty (conbind ns x)
124+ conbind [] x = x
125+
126+ getMName (PTy _ _ _ _ _ n _) = nsroot n
127+ tdecl allmeths (PTy doc _ syn _ o n t)
128+ = do t' <- implicit' info syn allmeths n t
129+ logLvl 5 $ "Method " ++ show n ++ " : " ++ showTmImpls t'
130+ return ( (n, (toExp (map fst ps) Exp t')),
131+ (n, (doc, o, (toExp (map fst ps) Imp t'))),
132+ (n, (syn, o, t) ) )
133+ tdecl _ _ = ifail "Not allowed in a class declaration"
134+
135+ -- Create default definitions
136+ defdecl mtys c d@(PClauses fc opts n cs) =
137+ case lookup n mtys of
138+ Just (syn, o, ty) -> do let ty' = insertConstraint c ty
139+ let ds = map (decorateid defaultdec)
140+ [PTy emptyDocstring [] syn fc [] n ty',
141+ PClauses fc (o ++ opts) n cs]
142+ iLOG (show ds)
143+ return (n, ((defaultdec n, ds!!1), ds))
144+ _ -> ifail $ show n ++ " is not a method"
145+ defdecl _ _ _ = ifail "Can't happen (defdecl)"
146+
147+ defaultdec (UN n) = sUN ("default#" ++ str n)
148+ defaultdec (NS n ns) = NS (defaultdec n) ns
149+
150+ tydecl (PTy _ _ _ _ _ _ _) = True
151+ tydecl _ = False
152+ instdecl (PInstance _ _ _ _ _ _ _ _) = True
153+ instdecl _ = False
154+ clause (PClauses _ _ _ _) = True
155+ clause _ = False
156+
157+ -- Generate a function for chasing a dictionary constraint
158+ cfun cn c syn all con
159+ = do let cfn = sUN ('@':'@':show cn ++ "#" ++ show con)
160+ -- SN (ParentN cn (show con))
161+ let mnames = take (length all) $ map (\x -> sMN x "meth") [0..]
162+ let capp = PApp fc (PRef fc cn) (map (pexp . PRef fc) mnames)
163+ let lhs = PApp fc (PRef fc cfn) [pconst capp]
164+ let rhs = PResolveTC (fileFC "HACK")
165+ let ty = PPi constraint (sMN 0 "pc") c con
166+ iLOG (showTmImpls ty)
167+ iLOG (showTmImpls lhs ++ " = " ++ showTmImpls rhs)
168+ i <- getIState
169+ let conn = case con of
170+ PRef _ n -> n
171+ PApp _ (PRef _ n) _ -> n
172+ let conn' = case lookupCtxtName conn (idris_classes i) of
173+ [(n, _)] -> n
174+ _ -> conn
175+ addInstance False conn' cfn
176+ addIBC (IBCInstance False conn' cfn)
177+-- iputStrLn ("Added " ++ show (conn, cfn, ty))
178+ return [PTy emptyDocstring [] syn fc [] cfn ty,
179+ PClauses fc [Dictionary] cfn [PClause fc cfn lhs [] rhs []]]
180+
181+ -- Generate a top level function which looks up a method in a given
182+ -- dictionary (this is inlinable, always)
183+ tfun cn c syn all (m, (doc, o, ty))
184+ = do let ty' = insertConstraint c ty
185+ let mnames = take (length all) $ map (\x -> sMN x "meth") [0..]
186+ let capp = PApp fc (PRef fc cn) (map (pexp . PRef fc) mnames)
187+ let margs = getMArgs ty
188+ let anames = map (\x -> sMN x "arg") [0..]
189+ let lhs = PApp fc (PRef fc m) (pconst capp : lhsArgs margs anames)
190+ let rhs = PApp fc (getMeth mnames all m) (rhsArgs margs anames)
191+ iLOG (showTmImpls ty)
192+ iLOG (show (m, ty', capp, margs))
193+ iLOG (showTmImpls lhs ++ " = " ++ showTmImpls rhs)
194+ return [PTy doc [] syn fc o m ty',
195+ PClauses fc [Inlinable] m [PClause fc m lhs [] rhs []]]
196+
197+ getMArgs (PPi (Imp _ _ _) n ty sc) = IA : getMArgs sc
198+ getMArgs (PPi (Exp _ _ _) n ty sc) = EA : getMArgs sc
199+ getMArgs (PPi (Constraint _ _) n ty sc) = CA : getMArgs sc
200+ getMArgs _ = []
201+
202+ getMeth (m:ms) (a:as) x | x == a = PRef fc m
203+ | otherwise = getMeth ms as x
204+
205+ lhsArgs (EA : xs) (n : ns) = [] -- pexp (PRef fc n) : lhsArgs xs ns
206+ lhsArgs (IA : xs) ns = lhsArgs xs ns
207+ lhsArgs (CA : xs) ns = lhsArgs xs ns
208+ lhsArgs [] _ = []
209+
210+ rhsArgs (EA : xs) (n : ns) = [] -- pexp (PRef fc n) : rhsArgs xs ns
211+ rhsArgs (IA : xs) ns = pexp Placeholder : rhsArgs xs ns
212+ rhsArgs (CA : xs) ns = pconst (PResolveTC fc) : rhsArgs xs ns
213+ rhsArgs [] _ = []
214+
215+ insertConstraint c (PPi p@(Imp _ _ _) n ty sc)
216+ = PPi p n ty (insertConstraint c sc)
217+ insertConstraint c sc = PPi constraint (sMN 0 "class") c sc
218+
219+ -- make arguments explicit and don't bind class parameters
220+ toExp ns e (PPi (Imp l s p) n ty sc)
221+ | n `elem` ns = toExp ns e sc
222+ | otherwise = PPi (e l s p) n ty (toExp ns e sc)
223+ toExp ns e (PPi p n ty sc) = PPi p n ty (toExp ns e sc)
224+ toExp ns e sc = sc
225+
226+
src/Idris/Elab/Clause.hsnew file+877
@@ -0,0 +1,877 @@
1+{-# LANGUAGE PatternGuards #-}
2+module Idris.Elab.Clause where
3+
4+import Idris.AbsSyntax
5+import Idris.ASTUtils
6+import Idris.DSL
7+import Idris.Error
8+import Idris.Delaborate
9+import Idris.Imports
10+import Idris.ElabTerm
11+import Idris.Coverage
12+import Idris.DataOpts
13+import Idris.Providers
14+import Idris.Primitives
15+import Idris.Inliner
16+import Idris.PartialEval
17+import Idris.DeepSeq
18+import Idris.Output (iputStrLn, pshow, iWarn)
19+import IRTS.Lang
20+
21+import Idris.Elab.Type
22+import Idris.Elab.Utils
23+
24+import Idris.Core.TT
25+import Idris.Core.Elaborate hiding (Tactic(..))
26+import Idris.Core.Evaluate
27+import Idris.Core.Execute
28+import Idris.Core.Typecheck
29+import Idris.Core.CaseTree
30+
31+import Idris.Docstrings
32+
33+import Prelude hiding (id, (.))
34+import Control.Category
35+
36+import Control.Applicative hiding (Const)
37+import Control.DeepSeq
38+import Control.Monad
39+import Control.Monad.State.Strict as State
40+import Data.List
41+import Data.Maybe
42+import Debug.Trace
43+
44+import qualified Data.Map as Map
45+import qualified Data.Set as S
46+import qualified Data.Text as T
47+import Data.Char(isLetter, toLower)
48+import Data.List.Split (splitOn)
49+
50+import Util.Pretty(pretty, text)
51+
52+-- | Elaborate a collection of left-hand and right-hand pairs - that is, a
53+-- top-level definition.
54+elabClauses :: ElabInfo -> FC -> FnOpts -> Name -> [PClause] -> Idris ()
55+elabClauses info fc opts n_in cs = let n = liftname info n_in in
56+ do ctxt <- getContext
57+ ist <- getIState
58+ inacc <- map fst <$> fgetState (opt_inaccessible . ist_optimisation n)
59+
60+ -- Check n actually exists, with no definition yet
61+ let tys = lookupTy n ctxt
62+ let reflect = Reflection `elem` opts
63+ checkUndefined n ctxt
64+ unless (length tys > 1) $ do
65+ fty <- case tys of
66+ [] -> -- TODO: turn into a CAF if there's no arguments
67+ -- question: CAFs in where blocks?
68+ tclift $ tfail $ At fc (NoTypeDecl n)
69+ [ty] -> return ty
70+ let atys = map snd (getArgTys fty)
71+ cs_elab <- mapM (elabClause info opts)
72+ (zip [0..] cs)
73+ let (pats_in, cs_full) = unzip cs_elab
74+
75+ logLvl 3 $ "Elaborated patterns:\n" ++ show pats_in
76+
77+ solveDeferred n
78+
79+ -- just ensure that the structure exists
80+ fmodifyState (ist_optimisation n) id
81+ addIBC (IBCOpt n)
82+
83+ ist <- getIState
84+ let pats = map (simple_lhs (tt_ctxt ist)) $ doTransforms ist pats_in
85+
86+ -- logLvl 3 (showSep "\n" (map (\ (l,r) ->
87+ -- show l ++ " = " ++
88+ -- show r) pats))
89+ let tcase = opt_typecase (idris_options ist)
90+
91+ -- Summary of what's about to happen: Definitions go:
92+ --
93+ -- pats_in -> pats -> pdef -> pdef'
94+
95+ -- addCaseDef builds case trees from <pdef> and <pdef'>
96+
97+ -- pdef is the compile-time pattern definition.
98+ -- This will get further optimised for run-time, and, separately,
99+ -- further inlined to help with totality checking.
100+ let pdef = map debind pats
101+
102+ logLvl 5 $ "Initial typechecked patterns:\n" ++ show pats
103+ logLvl 5 $ "Initial typechecked pattern def:\n" ++ show pdef
104+
105+ -- Look for 'static' names and generate new specialised
106+ -- definitions for them
107+
108+ mapM_ (\ e -> case e of
109+ Left _ -> return ()
110+ Right (l, r) -> elabPE info fc n r) pats
111+
112+ -- NOTE: Need to store original definition so that proofs which
113+ -- rely on its structure aren't affected by any changes to the
114+ -- inliner. Just use the inlined version to generate pdef' and to
115+ -- help with later inlinings.
116+
117+ ist <- getIState
118+ let pdef_inl = inlineDef ist pdef
119+
120+ numArgs <- tclift $ sameLength pdef
121+
122+ case specNames opts of
123+ Just _ -> logLvl 5 $ "Partially evaluated:\n" ++ show pats
124+ _ -> return ()
125+
126+ erInfo <- getErasureInfo <$> getIState
127+ tree@(CaseDef scargs sc _) <- tclift $
128+ simpleCase tcase False reflect CompileTime fc inacc atys pdef erInfo
129+ cov <- coverage
130+ pmissing <-
131+ if cov && not (hasDefault cs)
132+ then do missing <- genClauses fc n (map getLHS pdef) cs_full
133+ -- missing <- genMissing n scargs sc
134+ missing' <- filterM (checkPossible info fc True n) missing
135+ let clhs = map getLHS pdef
136+ logLvl 2 $ "Must be unreachable:\n" ++
137+ showSep "\n" (map showTmImpls missing') ++
138+ "\nAgainst: " ++
139+ showSep "\n" (map (\t -> showTmImpls (delab ist t)) (map getLHS pdef))
140+ -- filter out anything in missing' which is
141+ -- matched by any of clhs. This might happen since
142+ -- unification may force a variable to take a
143+ -- particular form, rather than force a case
144+ -- to be impossible.
145+ return (filter (noMatch ist clhs) missing')
146+ else return []
147+ let pcover = null pmissing
148+
149+ -- pdef' is the version that gets compiled for run-time
150+ pdef_in' <- applyOpts pdef
151+ let pdef' = map (simple_rt (tt_ctxt ist)) pdef_in'
152+
153+ logLvl 5 $ "After data structure transformations:\n" ++ show pdef'
154+
155+ ist <- getIState
156+ -- let wf = wellFounded ist n sc
157+ let tot = if pcover || AssertTotal `elem` opts
158+ then Unchecked -- finish checking later
159+ else Partial NotCovering -- already know it's not total
160+
161+ -- case lookupCtxt (namespace info) n (idris_flags ist) of
162+ -- [fs] -> if TotalFn `elem` fs
163+ -- then case tot of
164+ -- Total _ -> return ()
165+ -- t -> tclift $ tfail (At fc (Msg (show n ++ " is " ++ show t)))
166+ -- else return ()
167+ -- _ -> return ()
168+ case tree of
169+ CaseDef _ _ [] -> return ()
170+ CaseDef _ _ xs -> mapM_ (\x ->
171+ iputStrLn $ show fc ++
172+ ":warning - Unreachable case: " ++
173+ show (delab ist x)) xs
174+ let knowncovering = (pcover && cov) || AssertTotal `elem` opts
175+
176+ tree' <- tclift $ simpleCase tcase knowncovering reflect
177+ RunTime fc inacc atys pdef' erInfo
178+ logLvl 3 $ "Unoptimised " ++ show n ++ ": " ++ show tree
179+ logLvl 3 $ "Optimised: " ++ show tree'
180+ ctxt <- getContext
181+ ist <- getIState
182+ let opt = idris_optimisation ist
183+ putIState (ist { idris_patdefs = addDef n (force pdef', force pmissing)
184+ (idris_patdefs ist) })
185+ let caseInfo = CaseInfo (inlinable opts) (dictionary opts)
186+ case lookupTy n ctxt of
187+ [ty] -> do updateContext (addCasedef n erInfo caseInfo
188+ tcase knowncovering
189+ reflect
190+ (AssertTotal `elem` opts)
191+ atys
192+ inacc
193+ pats
194+ pdef pdef pdef_inl pdef' ty)
195+ addIBC (IBCDef n)
196+ setTotality n tot
197+ when (not reflect) $ do totcheck (fc, n)
198+ defer_totcheck (fc, n)
199+ when (tot /= Unchecked) $ addIBC (IBCTotal n tot)
200+ i <- getIState
201+ case lookupDef n (tt_ctxt i) of
202+ (CaseOp _ _ _ _ _ cd : _) ->
203+ let (scargs, sc) = cases_compiletime cd
204+ (scargs', sc') = cases_runtime cd in
205+ do let calls = findCalls sc' scargs'
206+ let used = findUsedArgs sc' scargs'
207+ -- let scg = buildSCG i sc scargs
208+ -- add SCG later, when checking totality
209+ let cg = CGInfo scargs' calls [] used [] -- TODO: remove this, not needed anymore
210+ logLvl 2 $ "Called names: " ++ show cg
211+ addToCG n cg
212+ addToCalledG n (nub (map fst calls)) -- plus names in type!
213+ addIBC (IBCCG n)
214+ _ -> return ()
215+ return ()
216+ -- addIBC (IBCTotal n tot)
217+ [] -> return ()
218+ -- Check it's covering, if 'covering' option is used. Chase
219+ -- all called functions, and fail if any of them are also
220+ -- 'Partial NotCovering'
221+ when (CoveringFn `elem` opts) $ checkAllCovering fc [] n n
222+ where
223+ noMatch i cs tm = all (\x -> case matchClause i (delab' i x True True) tm of
224+ Right _ -> False
225+ Left miss -> True) cs
226+
227+ checkUndefined n ctxt = case lookupDef n ctxt of
228+ [] -> return ()
229+ [TyDecl _ _] -> return ()
230+ _ -> tclift $ tfail (At fc (AlreadyDefined n))
231+
232+ debind (Right (x, y)) = let (vs, x') = depat [] x
233+ (_, y') = depat [] y in
234+ (vs, x', y')
235+ debind (Left x) = let (vs, x') = depat [] x in
236+ (vs, x', Impossible)
237+
238+ depat acc (Bind n (PVar t) sc) = depat (n : acc) (instantiate (P Bound n t) sc)
239+ depat acc x = (acc, x)
240+
241+ hasDefault cs | (PClause _ _ last _ _ _ :_) <- reverse cs
242+ , (PApp fn s args) <- last = all ((==Placeholder) . getTm) args
243+ hasDefault _ = False
244+
245+ getLHS (_, l, _) = l
246+
247+ simple_lhs ctxt (Right (x, y)) = Right (normalise ctxt [] x,
248+ force (normalisePats ctxt [] y))
249+ simple_lhs ctxt t = t
250+
251+ simple_rt ctxt (p, x, y) = (p, x, force (uniqueBinders p
252+ (rt_simplify ctxt [] y)))
253+
254+ -- this is so pattern types are in the right form for erasure
255+ normalisePats ctxt env (Bind n (PVar t) sc)
256+ = let t' = normalise ctxt env t in
257+ Bind n (PVar t') (normalisePats ctxt ((n, PVar t') : env) sc)
258+ normalisePats ctxt env (Bind n (PVTy t) sc)
259+ = let t' = normalise ctxt env t in
260+ Bind n (PVTy t') (normalisePats ctxt ((n, PVar t') : env) sc)
261+ normalisePats ctxt env t = t
262+
263+ specNames [] = Nothing
264+ specNames (Specialise ns : _) = Just ns
265+ specNames (_ : xs) = specNames xs
266+
267+ sameLength ((_, x, _) : xs)
268+ = do l <- sameLength xs
269+ let (f, as) = unApply x
270+ if (null xs || l == length as) then return (length as)
271+ else tfail (At fc (Msg "Clauses have differing numbers of arguments "))
272+ sameLength [] = return 0
273+
274+ -- apply all transformations (just specialisation for now, add
275+ -- user defined transformation rules later)
276+ doTransforms ist pats =
277+ case specNames opts of
278+ Nothing -> pats
279+ Just ns -> partial_eval (tt_ctxt ist) ns pats
280+
281+-- | Find 'static' applications in a term and partially evaluate them
282+elabPE :: ElabInfo -> FC -> Name -> Term -> Idris ()
283+elabPE info fc caller r =
284+ do ist <- getIState
285+ let sa = getSpecApps ist [] r
286+ mapM_ (mkSpecialised ist) sa
287+ where
288+ -- TODO: Add a PTerm level transformation rule, which is basically the
289+ -- new definition in reverse (before specialising it).
290+ -- RHS => LHS where implicit arguments are left blank in the
291+ -- transformation.
292+
293+ -- Apply that transformation after every PClauses elaboration
294+
295+ mkSpecialised ist specapp_in = do
296+ let (specTy, specapp) = getSpecTy ist specapp_in
297+ let (n, newnm, pats) = getSpecClause ist specapp
298+ let undef = case lookupDef newnm (tt_ctxt ist) of
299+ [] -> True
300+ _ -> False
301+ logLvl 5 $ show (newnm, map (concreteArg ist) (snd specapp))
302+ idrisCatch
303+ (when (undef && all (concreteArg ist) (snd specapp)) $ do
304+ cgns <- getAllNames n
305+ let opts = [Specialise (map (\x -> (x, Nothing)) cgns ++
306+ mapMaybe specName (snd specapp))]
307+ logLvl 3 $ "Specialising application: " ++ show specapp
308+ logLvl 2 $ "New name: " ++ show newnm
309+ iLOG $ "PE definition type : " ++ (show specTy)
310+ ++ "\n" ++ show opts
311+ logLvl 2 $ "PE definition " ++ show newnm ++ ":\n" ++
312+ showSep "\n"
313+ (map (\ (lhs, rhs) ->
314+ (showTmImpls lhs ++ " = " ++
315+ showTmImpls rhs)) pats)
316+ elabType info defaultSyntax emptyDocstring [] fc opts newnm specTy
317+ let def = map (\ (lhs, rhs) -> PClause fc newnm lhs [] rhs []) pats
318+ elabClauses info fc opts newnm def
319+ logLvl 2 $ "Specialised " ++ show newnm)
320+ -- if it doesn't work, just don't specialise. Could happen for lots
321+ -- of valid reasons (e.g. local variables in scope which can't be
322+ -- lifted out).
323+ (\e -> logLvl 4 $ "Couldn't specialise: " ++ (pshow ist e))
324+
325+ specName (ImplicitS, tm)
326+ | (P Ref n _, _) <- unApply tm = Just (n, Just 1)
327+ specName (ExplicitS, tm)
328+ | (P Ref n _, _) <- unApply tm = Just (n, Just 1)
329+ specName _ = Nothing
330+
331+ concreteArg ist (ImplicitS, tm) = concreteTm ist tm
332+ concreteArg ist (ExplicitS, tm) = concreteTm ist tm
333+ concreteArg ist _ = True
334+
335+ concreteTm ist tm | (P _ n _, _) <- unApply tm =
336+ case lookupTy n (tt_ctxt ist) of
337+ [] -> False
338+ _ -> True
339+ concreteTm ist (Constant _) = True
340+ concreteTm ist _ = False
341+
342+ -- get the type of a specialised application
343+ getSpecTy ist (n, args)
344+ = case lookupTy n (tt_ctxt ist) of
345+ [ty] -> let (specty_in, args') = specType args (explicitNames ty)
346+ specty = normalise (tt_ctxt ist) [] (finalise specty_in)
347+ t = mkPE_TyDecl ist args' (explicitNames specty) in
348+ (t, (n, args'))
349+-- (normalise (tt_ctxt ist) [] (specType args ty))
350+ _ -> error "Can't happen (getSpecTy)"
351+
352+ -- get the clause of a specialised application
353+ getSpecClause ist (n, args)
354+ = let newnm = sUN ("__"++show (nsroot n) ++ "_" ++
355+ showSep "_" (map showArg args)) in
356+ -- UN (show n ++ show (map snd args)) in
357+ (n, newnm, mkPE_TermDecl ist newnm n args)
358+ where showArg (ExplicitS, n) = show n
359+ showArg (ImplicitS, n) = show n
360+ showArg _ = ""
361+
362+-- checks if the clause is a possible left hand side. Returns the term if
363+-- possible, otherwise Nothing.
364+
365+checkPossible :: ElabInfo -> FC -> Bool -> Name -> PTerm -> Idris Bool
366+checkPossible info fc tcgen fname lhs_in
367+ = do ctxt <- getContext
368+ i <- getIState
369+ let lhs = addImplPat i lhs_in
370+ -- if the LHS type checks, it is possible
371+ case elaborate ctxt (sMN 0 "patLHS") infP []
372+ (erun fc (buildTC i info ELHS [] fname (infTerm lhs))) of
373+ OK ((lhs', _, _), _) ->
374+ do let lhs_tm = orderPats (getInferTerm lhs')
375+ case recheck ctxt [] (forget lhs_tm) lhs_tm of
376+ OK _ -> return True
377+ err -> return False
378+ -- if it's a recoverable error, the case may become possible
379+ Error err -> if tcgen then return (recoverable ctxt err)
380+ else return (validCase ctxt err ||
381+ recoverable ctxt err)
382+ where validCase ctxt (CantUnify _ topx topy e _ _)
383+ = let topx' = normalise ctxt [] topx
384+ topy' = normalise ctxt [] topy in
385+ not (sameFam topx' topy' || not (validCase ctxt e))
386+ validCase ctxt (CantConvert _ _ _) = False
387+ validCase ctxt (At _ e) = validCase ctxt e
388+ validCase ctxt (Elaborating _ _ e) = validCase ctxt e
389+ validCase ctxt (ElaboratingArg _ _ _ e) = validCase ctxt e
390+ validCase ctxt _ = True
391+
392+ recoverable ctxt (CantUnify r topx topy e _ _)
393+ = let topx' = normalise ctxt [] topx
394+ topy' = normalise ctxt [] topy in
395+ checkRec topx' topy'
396+ recoverable ctxt (At _ e) = recoverable ctxt e
397+ recoverable ctxt (Elaborating _ _ e) = recoverable ctxt e
398+ recoverable ctxt (ElaboratingArg _ _ _ e) = recoverable ctxt e
399+ recoverable _ _ = False
400+
401+ sameFam topx topy
402+ = case (unApply topx, unApply topy) of
403+ ((P _ x _, _), (P _ y _, _)) -> x == y
404+ _ -> False
405+
406+ -- different notion of recoverable than in unification, since we
407+ -- have no metavars -- just looking to see if a constructor is failing
408+ -- to unify with a function that may be reduced later
409+
410+ checkRec (App f a) p@(P _ _ _) = checkRec f p
411+ checkRec p@(P _ _ _) (App f a) = checkRec p f
412+ checkRec fa@(App _ _) fa'@(App _ _)
413+ | (f, as) <- unApply fa,
414+ (f', as') <- unApply fa'
415+ = if (length as /= length as')
416+ then checkRec f f'
417+ else checkRec f f' && and (zipWith checkRec as as')
418+ checkRec (P xt x _) (P yt y _) = x == y || ntRec xt yt
419+ checkRec _ _ = False
420+
421+ ntRec x y | Ref <- x = True
422+ | Ref <- y = True
423+ | otherwise = False -- name is different, unrecoverable
424+
425+getFixedInType i env (PExp _ _ _ _ : is) (Bind n (Pi t) sc)
426+ = nub $ getFixedInType i env [] t ++
427+ getFixedInType i (n : env) is (instantiate (P Bound n t) sc)
428+getFixedInType i env (_ : is) (Bind n (Pi t) sc)
429+ = getFixedInType i (n : env) is (instantiate (P Bound n t) sc)
430+getFixedInType i env is tm@(App f a)
431+ | (P _ tn _, args) <- unApply tm
432+ = case lookupCtxt tn (idris_datatypes i) of
433+ [t] -> nub $ paramNames args env (param_pos t) ++
434+ getFixedInType i env is f ++
435+ getFixedInType i env is a
436+ [] -> nub $ getFixedInType i env is f ++
437+ getFixedInType i env is a
438+ | otherwise = nub $ getFixedInType i env is f ++
439+ getFixedInType i env is a
440+getFixedInType i _ _ _ = []
441+
442+getFlexInType i env ps (Bind n (Pi t) sc)
443+ = nub $ (if (not (n `elem` ps)) then getFlexInType i env ps t else []) ++
444+ getFlexInType i (n : env) ps (instantiate (P Bound n t) sc)
445+getFlexInType i env ps tm@(App f a)
446+ | (P _ tn _, args) <- unApply tm
447+ = case lookupCtxt tn (idris_datatypes i) of
448+ [t] -> nub $ paramNames args env [x | x <- [0..length args],
449+ not (x `elem` param_pos t)]
450+ ++ getFlexInType i env ps f ++
451+ getFlexInType i env ps a
452+ [] -> nub $ getFlexInType i env ps f ++
453+ getFlexInType i env ps a
454+ | otherwise = nub $ getFlexInType i env ps f ++
455+ getFlexInType i env ps a
456+getFlexInType i _ _ _ = []
457+
458+-- Treat a name as a parameter if it appears in parameter positions in
459+-- types, and never in a non-parameter position in a (non-param) argument type.
460+
461+getParamsInType i env ps t = let fix = getFixedInType i env ps t
462+ flex = getFlexInType i env fix t in
463+ [x | x <- fix, not (x `elem` flex)]
464+
465+paramNames args env [] = []
466+paramNames args env (p : ps)
467+ | length args > p = case args!!p of
468+ P _ n _ -> if n `elem` env
469+ then n : paramNames args env ps
470+ else paramNames args env ps
471+ _ -> paramNames args env ps
472+ | otherwise = paramNames args env ps
473+
474+propagateParams :: IState -> [Name] -> Type -> PTerm -> PTerm
475+propagateParams i ps t tm@(PApp _ (PRef fc n) args)
476+ = PApp fc (PRef fc n) (addP t args)
477+ where addP (Bind n _ sc) (t : ts)
478+ | Placeholder <- getTm t,
479+ n `elem` ps,
480+ not (n `elem` allNamesIn tm)
481+ = t { getTm = PRef fc n } : addP sc ts
482+ addP (Bind n _ sc) (t : ts) = t : addP sc ts
483+ addP _ ts = ts
484+propagateParams i ps t (PRef fc n)
485+ = case lookupCtxt n (idris_implicits i) of
486+ [is] -> let ps' = filter (isImplicit is) ps in
487+ PApp fc (PRef fc n) (map (\x -> pimp x (PRef fc x) True) ps')
488+ _ -> PRef fc n
489+ where isImplicit [] n = False
490+ isImplicit (PImp _ _ _ x _ : is) n | x == n = True
491+ isImplicit (_ : is) n = isImplicit is n
492+propagateParams i ps t x = x
493+
494+-- Return the elaborated LHS/RHS, and the original LHS with implicits added
495+elabClause :: ElabInfo -> FnOpts -> (Int, PClause) ->
496+ Idris (Either Term (Term, Term), PTerm)
497+elabClause info opts (_, PClause fc fname lhs_in [] PImpossible [])
498+ = do let tcgen = Dictionary `elem` opts
499+ i <- get
500+ let lhs = addImpl i lhs_in
501+ b <- checkPossible info fc tcgen fname lhs_in
502+ case b of
503+ True -> tclift $ tfail (At fc
504+ (Msg $ show lhs_in ++ " is a valid case"))
505+ False -> do ptm <- mkPatTm lhs_in
506+ return (Left ptm, lhs)
507+elabClause info opts (cnum, PClause fc fname lhs_in withs rhs_in whereblock)
508+ = do let tcgen = Dictionary `elem` opts
509+ ctxt <- getContext
510+
511+ -- Build the LHS as an "Infer", and pull out its type and
512+ -- pattern bindings
513+ i <- getIState
514+ inf <- isTyInferred fname
515+ -- get the parameters first, to pass through to any where block
516+ let fn_ty = case lookupTy fname (tt_ctxt i) of
517+ [t] -> t
518+ _ -> error "Can't happen (elabClause function type)"
519+ let fn_is = case lookupCtxt fname (idris_implicits i) of
520+ [t] -> t
521+ _ -> []
522+ let params = getParamsInType i [] fn_is fn_ty
523+ let lhs = mkLHSapp $ stripUnmatchable i $
524+ propagateParams i params fn_ty (addImplPat i (stripLinear i lhs_in))
525+ logLvl 5 ("LHS: " ++ show fc ++ " " ++ showTmImpls lhs)
526+ logLvl 4 ("Fixed parameters: " ++ show params ++ " from " ++ show lhs_in ++
527+ "\n" ++ show (fn_ty, fn_is))
528+
529+ (((lhs', dlhs, []), probs, inj), _) <-
530+ tclift $ elaborate ctxt (sMN 0 "patLHS") infP []
531+ (do res <- errAt "left hand side of " fname
532+ (erun fc (buildTC i info ELHS opts fname (infTerm lhs)))
533+ probs <- get_probs
534+ inj <- get_inj
535+ return (res, probs, inj))
536+
537+ when inf $ addTyInfConstraints fc (map (\(x,y,_,_,_,_) -> (x,y)) probs)
538+
539+ let lhs_tm = orderPats (getInferTerm lhs')
540+ let lhs_ty = getInferType lhs'
541+ logLvl 3 ("Elaborated: " ++ show lhs_tm)
542+ logLvl 3 ("Elaborated type: " ++ show lhs_ty)
543+ logLvl 5 ("Injective: " ++ show fname ++ " " ++ show inj)
544+
545+ -- If we're inferring metavariables in the type, don't recheck,
546+ -- because we're only doing this to try to work out those metavariables
547+ (clhs_c, clhsty) <- if not inf
548+ then recheckC fc [] lhs_tm
549+ else return (lhs_tm, lhs_ty)
550+ let clhs = normalise ctxt [] clhs_c
551+
552+ logLvl 3 ("Normalised LHS: " ++ showTmImpls (delabMV i clhs))
553+
554+ rep <- useREPL
555+ when rep $ do
556+ addInternalApp (fc_fname fc) (fst . fc_start $ fc) (delabMV i clhs) -- TODO: Should use span instead of line and filename?
557+ addIBC (IBCLineApp (fc_fname fc) (fst . fc_start $ fc) (delabMV i clhs))
558+
559+ logLvl 5 ("Checked " ++ show clhs ++ "\n" ++ show clhsty)
560+ -- Elaborate where block
561+ ist <- getIState
562+ windex <- getName
563+ let decls = nub (concatMap declared whereblock)
564+ let defs = nub (decls ++ concatMap defined whereblock)
565+ let newargs = pvars ist lhs_tm
566+ let winfo = pinfo info newargs defs windex
567+ let wb = map (expandParamsD False ist decorate newargs defs) whereblock
568+
569+ -- Split the where block into declarations with a type, and those
570+ -- without
571+ -- Elaborate those with a type *before* RHS, those without *after*
572+ let (wbefore, wafter) = sepBlocks wb
573+
574+ logLvl 2 $ "Where block:\n " ++ show wbefore ++ "\n" ++ show wafter
575+ mapM_ (rec_elabDecl info EAll winfo) wbefore
576+ -- Now build the RHS, using the type of the LHS as the goal.
577+ i <- getIState -- new implicits from where block
578+ logLvl 5 (showTmImpls (expandParams decorate newargs defs (defs \\ decls) rhs_in))
579+ let rhs = addImplBoundInf i (map fst newargs) (defs \\ decls)
580+ (expandParams decorate newargs defs (defs \\ decls) rhs_in)
581+ logLvl 2 $ "RHS: " ++ showTmImpls rhs
582+ ctxt <- getContext -- new context with where block added
583+ logLvl 5 "STARTING CHECK"
584+ ((rhs', defer, is, probs), _) <-
585+ tclift $ elaborate ctxt (sMN 0 "patRHS") clhsty []
586+ (do pbinds ist lhs_tm
587+ mapM_ setinj (nub (params ++ inj))
588+ setNextName
589+ (_, _, is) <- errAt "right hand side of " fname
590+ (erun fc (build i winfo ERHS opts fname rhs))
591+ errAt "right hand side of " fname
592+ (erun fc $ psolve lhs_tm)
593+ hs <- get_holes
594+ aux <- getAux
595+ mapM_ (elabCaseHole aux) hs
596+ tt <- get_term
597+ let (tm, ds) = runState (collectDeferred (Just fname) tt) []
598+ probs <- get_probs
599+ return (tm, ds, is, probs))
600+
601+ when inf $ addTyInfConstraints fc (map (\(x,y,_,_,_,_) -> (x,y)) probs)
602+
603+ logLvl 5 "DONE CHECK"
604+ logLvl 2 $ "---> " ++ show rhs'
605+ when (not (null defer)) $ iLOG $ "DEFERRED " ++
606+ show (map (\ (n, (_,_,t)) -> (n, t)) defer)
607+ def' <- checkDef fc defer
608+ let def'' = map (\(n, (i, top, t)) -> (n, (i, top, t, False))) def'
609+ addDeferred def''
610+ mapM_ (\(n, _) -> addIBC (IBCDef n)) def''
611+
612+ when (not (null def')) $ do
613+ mapM_ defer_totcheck (map (\x -> (fc, fst x)) def'')
614+
615+ -- Now the remaining deferred (i.e. no type declarations) clauses
616+ -- from the where block
617+
618+ mapM_ (rec_elabDecl info EAll winfo) wafter
619+ mapM_ (elabCaseBlock winfo opts) is
620+
621+ ctxt <- getContext
622+ logLvl 5 $ "Rechecking"
623+ logLvl 6 $ " ==> " ++ show (forget rhs')
624+ (crhs, crhsty) <- if not inf
625+ then recheckC fc [] rhs'
626+ else return (rhs', clhsty)
627+ logLvl 6 $ " ==> " ++ show crhsty ++ " against " ++ show clhsty
628+ case converts ctxt [] clhsty crhsty of
629+ OK _ -> return ()
630+ Error e -> ierror (At fc (CantUnify False clhsty crhsty e [] 0))
631+ i <- getIState
632+ checkInferred fc (delab' i crhs True True) rhs
633+ -- if the function is declared '%error_reverse', or its type,
634+ -- then we'll try running it in reverse to improve error messages
635+ let (ret_fam, _) = unApply (getRetTy crhsty)
636+ rev <- case ret_fam of
637+ P _ rfamn _ ->
638+ case lookupCtxt rfamn (idris_datatypes i) of
639+ [TI _ _ dopts _ _] ->
640+ return (DataErrRev `elem` dopts)
641+ _ -> return False
642+ _ -> return False
643+
644+ when (rev || ErrorReverse `elem` opts) $ do
645+ addIBC (IBCErrRev (crhs, clhs))
646+ addErrRev (crhs, clhs)
647+ return $ (Right (clhs, crhs), lhs)
648+ where
649+ pinfo :: ElabInfo -> [(Name, PTerm)] -> [Name] -> Int -> ElabInfo
650+ pinfo info ns ds i
651+ = let newps = params info ++ ns
652+ dsParams = map (\n -> (n, map fst newps)) ds
653+ newb = addAlist dsParams (inblock info)
654+ l = liftname info in
655+ info { params = newps,
656+ inblock = newb,
657+ liftname = id -- (\n -> case lookupCtxt n newb of
658+ -- Nothing -> n
659+ -- _ -> MN i (show n)) . l
660+ }
661+
662+ mkLHSapp t@(PRef _ _) = trace ("APP " ++ show t) $ PApp fc t []
663+ mkLHSapp t = t
664+
665+ decorate (NS x ns)
666+ = NS (SN (WhereN cnum fname x)) ns -- ++ [show cnum])
667+-- = NS (UN ('#':show x)) (ns ++ [show cnum, show fname])
668+ decorate x
669+ = SN (WhereN cnum fname x)
670+-- = NS (SN (WhereN cnum fname x)) [show cnum]
671+-- = NS (UN ('#':show x)) [show cnum, show fname]
672+
673+ sepBlocks bs = sepBlocks' [] bs where
674+ sepBlocks' ns (d@(PTy _ _ _ _ _ n t) : bs)
675+ = let (bf, af) = sepBlocks' (n : ns) bs in
676+ (d : bf, af)
677+ sepBlocks' ns (d@(PClauses _ _ n _) : bs)
678+ | not (n `elem` ns) = let (bf, af) = sepBlocks' ns bs in
679+ (bf, d : af)
680+ sepBlocks' ns (b : bs) = let (bf, af) = sepBlocks' ns bs in
681+ (b : bf, af)
682+ sepBlocks' ns [] = ([], [])
683+
684+
685+ -- if a hole is just an argument/result of a case block, treat it as
686+ -- the unit type. Hack to help elaborate case in do blocks.
687+ elabCaseHole aux h = do
688+ focus h
689+ g <- goal
690+ case g of
691+ TType _ -> when (any (isArg h) aux) $ do apply (Var unitTy) []; solve
692+ _ -> return ()
693+
694+ -- Is the name a pattern argument in the declaration
695+ isArg :: Name -> PDecl -> Bool
696+ isArg n (PClauses _ _ _ cs) = any isArg' cs
697+ where
698+ isArg' (PClause _ _ (PApp _ _ args) _ _ _)
699+ = any (\x -> case x of
700+ PRef _ n' -> n == n'
701+ _ -> False) (map getTm args)
702+ isArg' _ = False
703+ isArg _ _ = False
704+
705+elabClause info opts (_, PWith fc fname lhs_in withs wval_in withblock)
706+ = do let tcgen = Dictionary `elem` opts
707+ ctxt <- getContext
708+ -- Build the LHS as an "Infer", and pull out its type and
709+ -- pattern bindings
710+ i <- getIState
711+ -- get the parameters first, to pass through to any where block
712+ let fn_ty = case lookupTy fname (tt_ctxt i) of
713+ [t] -> t
714+ _ -> error "Can't happen (elabClause function type)"
715+ let fn_is = case lookupCtxt fname (idris_implicits i) of
716+ [t] -> t
717+ _ -> []
718+ let params = getParamsInType i [] fn_is fn_ty
719+ let lhs = propagateParams i params fn_ty (addImplPat i (stripLinear i lhs_in))
720+ logLvl 2 ("LHS: " ++ show lhs)
721+ ((lhs', dlhs, []), _) <-
722+ tclift $ elaborate ctxt (sMN 0 "patLHS") infP []
723+ (errAt "left hand side of with in " fname
724+ (erun fc (buildTC i info ELHS opts fname (infTerm lhs))) )
725+ let lhs_tm = orderPats (getInferTerm lhs')
726+ let lhs_ty = getInferType lhs'
727+ let ret_ty = getRetTy (explicitNames (normalise ctxt [] lhs_ty))
728+ logLvl 3 (show lhs_tm)
729+ (clhs, clhsty) <- recheckC fc [] lhs_tm
730+ logLvl 5 ("Checked " ++ show clhs)
731+ let bargs = getPBtys (explicitNames (normalise ctxt [] lhs_tm))
732+ let wval = addImplBound i (map fst bargs) wval_in
733+ logLvl 5 ("Checking " ++ showTmImpls wval)
734+ -- Elaborate wval in this context
735+ ((wval', defer, is), _) <-
736+ tclift $ elaborate ctxt (sMN 0 "withRHS")
737+ (bindTyArgs PVTy bargs infP) []
738+ (do pbinds i lhs_tm
739+ setNextName
740+ -- TODO: may want where here - see winfo abpve
741+ (_', d, is) <- errAt "with value in " fname
742+ (erun fc (build i info ERHS opts fname (infTerm wval)))
743+ erun fc $ psolve lhs_tm
744+ tt <- get_term
745+ return (tt, d, is))
746+ def' <- checkDef fc defer
747+ let def'' = map (\(n, (i, top, t)) -> (n, (i, top, t, False))) def'
748+ addDeferred def''
749+ mapM_ (elabCaseBlock info opts) is
750+ logLvl 5 ("Checked wval " ++ show wval')
751+ (cwval, cwvalty) <- recheckC fc [] (getInferTerm wval')
752+ let cwvaltyN = explicitNames (normalise ctxt [] cwvalty)
753+ let cwvalN = explicitNames (normalise ctxt [] cwval)
754+ logLvl 5 ("With type " ++ show cwvalty ++ "\nRet type " ++ show ret_ty)
755+ let pvars = map fst (getPBtys cwvalty)
756+ -- we need the unelaborated term to get the names it depends on
757+ -- rather than a de Bruijn index.
758+ let pdeps = usedNamesIn pvars i (delab i cwvalty)
759+ let (bargs_pre, bargs_post) = split pdeps bargs []
760+ logLvl 10 ("With type " ++ show (getRetTy cwvaltyN) ++
761+ " depends on " ++ show pdeps ++ " from " ++ show pvars)
762+ logLvl 10 ("Pre " ++ show bargs_pre ++ "\nPost " ++ show bargs_post)
763+ windex <- getName
764+ -- build a type declaration for the new function:
765+ -- (ps : Xs) -> (withval : cwvalty) -> (ps' : Xs') -> ret_ty
766+ let wargval = getRetTy cwvalN
767+ let wargtype = getRetTy cwvaltyN
768+ logLvl 5 ("Abstract over " ++ show wargval ++ " in " ++ show wargtype)
769+ let wtype = bindTyArgs Pi (bargs_pre ++
770+ (sMN 0 "warg", wargtype) :
771+ map (abstract (sMN 0 "warg") wargval wargtype) bargs_post)
772+ (substTerm wargval (P Bound (sMN 0 "warg") wargtype) ret_ty)
773+ logLvl 5 ("New function type " ++ show wtype)
774+ let wname = sMN windex (show fname)
775+
776+ let imps = getImps wtype -- add to implicits context
777+ putIState (i { idris_implicits = addDef wname imps (idris_implicits i) })
778+ addIBC (IBCDef wname)
779+ def' <- checkDef fc [(wname, (-1, Nothing, wtype))]
780+ let def'' = map (\(n, (i, top, t)) -> (n, (i, top, t, False))) def'
781+ addDeferred def''
782+
783+ -- in the subdecls, lhs becomes:
784+ -- fname pats | wpat [rest]
785+ -- ==> fname' ps wpat [rest], match pats against toplevel for ps
786+ wb <- mapM (mkAuxC wname lhs (map fst bargs_pre) (map fst bargs_post))
787+ withblock
788+ logLvl 3 ("with block " ++ show wb)
789+ -- propagate totality assertion to the new definitions
790+ when (AssertTotal `elem` opts) $ setFlags wname [AssertTotal]
791+ mapM_ (rec_elabDecl info EAll info) wb
792+
793+ -- rhs becomes: fname' ps wval
794+ let rhs = PApp fc (PRef fc wname)
795+ (map (pexp . (PRef fc) . fst) bargs_pre ++
796+ pexp wval :
797+ (map (pexp . (PRef fc) . fst) bargs_post))
798+ logLvl 5 ("New RHS " ++ showTmImpls rhs)
799+ ctxt <- getContext -- New context with block added
800+ i <- getIState
801+ ((rhs', defer, is), _) <-
802+ tclift $ elaborate ctxt (sMN 0 "wpatRHS") clhsty []
803+ (do pbinds i lhs_tm
804+ setNextName
805+ (_, d, is) <- erun fc (build i info ERHS opts fname rhs)
806+ psolve lhs_tm
807+ tt <- get_term
808+ return (tt, d, is))
809+ def' <- checkDef fc defer
810+ let def'' = map (\(n, (i, top, t)) -> (n, (i, top, t, False))) def'
811+ addDeferred def''
812+ mapM_ (elabCaseBlock info opts) is
813+ logLvl 5 ("Checked RHS " ++ show rhs')
814+ (crhs, crhsty) <- recheckC fc [] rhs'
815+ return $ (Right (clhs, crhs), lhs)
816+ where
817+ getImps (Bind n (Pi _) t) = pexp Placeholder : getImps t
818+ getImps _ = []
819+
820+ mkAuxC wname lhs ns ns' (PClauses fc o n cs)
821+ | True = do cs' <- mapM (mkAux wname lhs ns ns') cs
822+ return $ PClauses fc o wname cs'
823+ | otherwise = ifail $ show fc ++ "with clause uses wrong function name " ++ show n
824+ mkAuxC wname lhs ns ns' d = return $ d
825+
826+ mkAux wname toplhs ns ns' (PClause fc n tm_in (w:ws) rhs wheres)
827+ = do i <- getIState
828+ let tm = addImplPat i tm_in
829+ logLvl 2 ("Matching " ++ showTmImpls tm ++ " against " ++
830+ showTmImpls toplhs)
831+ case matchClause i toplhs tm of
832+ Left (a,b) -> ifail $ show fc ++ ":with clause does not match top level"
833+ Right mvars ->
834+ do logLvl 3 ("Match vars : " ++ show mvars)
835+ lhs <- updateLHS n wname mvars ns ns' (fullApp tm) w
836+ return $ PClause fc wname lhs ws rhs wheres
837+ mkAux wname toplhs ns ns' (PWith fc n tm_in (w:ws) wval withs)
838+ = do i <- getIState
839+ let tm = addImplPat i tm_in
840+ logLvl 2 ("Matching " ++ showTmImpls tm ++ " against " ++
841+ showTmImpls toplhs)
842+ withs' <- mapM (mkAuxC wname toplhs ns ns') withs
843+ case matchClause i toplhs tm of
844+ Left (a,b) -> trace ("matchClause: " ++ show a ++ " =/= " ++ show b) (ifail $ show fc ++ "with clause does not match top level")
845+ Right mvars ->
846+ do lhs <- updateLHS n wname mvars ns ns' (fullApp tm) w
847+ return $ PWith fc wname lhs ws wval withs'
848+ mkAux wname toplhs ns ns' c
849+ = ifail $ show fc ++ ":badly formed with clause"
850+
851+ addArg (PApp fc f args) w = PApp fc f (args ++ [pexp w])
852+ addArg (PRef fc f) w = PApp fc (PRef fc f) [pexp w]
853+
854+ updateLHS n wname mvars ns_in ns_in' (PApp fc (PRef fc' n') args) w
855+ = let ns = map (keepMvar (map fst mvars) fc') ns_in
856+ ns' = map (keepMvar (map fst mvars) fc') ns_in' in
857+ return $ substMatches mvars $
858+ PApp fc (PRef fc' wname)
859+ (map pexp ns ++ pexp w : (map pexp ns'))
860+ updateLHS n wname mvars ns_in ns_in' tm w
861+ = updateLHS n wname mvars ns_in ns_in' (PApp fc tm []) w
862+
863+ keepMvar mvs fc v | v `elem` mvs = PRef fc v
864+ | otherwise = Placeholder
865+
866+ fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
867+ fullApp x = x
868+
869+ split [] rest pre = (reverse pre, rest)
870+ split deps ((n, ty) : rest) pre
871+ | n `elem` deps = split (deps \\ [n]) rest ((n, ty) : pre)
872+ | otherwise = split deps rest ((n, ty) : pre)
873+ split deps [] pre = (reverse pre, [])
874+
875+ abstract wn wv wty (n, argty) = (n, substTerm wv (P Bound wn wty) argty)
876+
877+
src/Idris/Elab/Data.hsnew file+489
@@ -0,0 +1,489 @@
1+{-# LANGUAGE PatternGuards #-}
2+module Idris.Elab.Data(elabData) where
3+
4+import Idris.AbsSyntax
5+import Idris.ASTUtils
6+import Idris.DSL
7+import Idris.Error
8+import Idris.Delaborate
9+import Idris.Imports
10+import Idris.ElabTerm
11+import Idris.Coverage
12+import Idris.DataOpts
13+import Idris.Providers
14+import Idris.Primitives
15+import Idris.Inliner
16+import Idris.PartialEval
17+import Idris.DeepSeq
18+import Idris.Output (iputStrLn, pshow, iWarn)
19+import IRTS.Lang
20+
21+import Idris.Elab.Type
22+import Idris.Elab.Utils
23+
24+import Idris.Core.TT
25+import Idris.Core.Elaborate hiding (Tactic(..))
26+import Idris.Core.Evaluate
27+import Idris.Core.Execute
28+import Idris.Core.Typecheck
29+import Idris.Core.CaseTree
30+
31+import Idris.Docstrings
32+
33+import Prelude hiding (id, (.))
34+import Control.Category
35+
36+import Control.Applicative hiding (Const)
37+import Control.DeepSeq
38+import Control.Monad
39+import Control.Monad.State.Strict as State
40+import Data.List
41+import Data.Maybe
42+import Debug.Trace
43+
44+import qualified Data.Map as Map
45+import qualified Data.Set as S
46+import qualified Data.Text as T
47+import Data.Char(isLetter, toLower)
48+import Data.List.Split (splitOn)
49+
50+import Util.Pretty(pretty, text)
51+
52+elabData :: ElabInfo -> SyntaxInfo -> Docstring -> [(Name, Docstring)] -> FC -> DataOpts -> PData -> Idris ()
53+elabData info syn doc argDocs fc opts (PLaterdecl n t_in)
54+ = do let codata = Codata `elem` opts
55+ iLOG (show (fc, doc))
56+ checkUndefined fc n
57+ (cty, t, inacc) <- buildType info syn fc [] n t_in
58+
59+ addIBC (IBCDef n)
60+ updateContext (addTyDecl n (TCon 0 0) cty) -- temporary, to check cons
61+
62+elabData info syn doc argDocs fc opts (PDatadecl n t_in dcons)
63+ = do let codata = Codata `elem` opts
64+ iLOG (show fc)
65+ undef <- isUndefined fc n
66+ (cty, t, inacc) <- buildType info syn fc [] n t_in
67+ -- if n is defined already, make sure it is just a type declaration
68+ -- with the same type we've just elaborated
69+ i <- getIState
70+ checkDefinedAs fc n cty (tt_ctxt i)
71+ -- temporary, to check cons
72+ when undef $ updateContext (addTyDecl n (TCon 0 0) cty)
73+ let cnameinfo = cinfo info (map cname dcons)
74+ cons <- mapM (elabCon cnameinfo syn n codata) dcons
75+ ttag <- getName
76+ i <- getIState
77+ let as = map (const Nothing) (getArgTys cty)
78+ let params = findParams (map snd cons)
79+ logLvl 2 $ "Parameters : " ++ show params
80+ -- TI contains information about mutually declared types - this will
81+ -- be updated when the mutual block is complete
82+ putIState (i { idris_datatypes =
83+ addDef n (TI (map fst cons) codata opts params [n])
84+ (idris_datatypes i) })
85+ addIBC (IBCDef n)
86+ addIBC (IBCData n)
87+ checkDocs fc argDocs t
88+ addDocStr n doc argDocs
89+ addIBC (IBCDoc n)
90+ let metainf = DataMI params
91+ addIBC (IBCMetaInformation n metainf)
92+ -- TMP HACK! Make this a data option
93+ updateContext (addDatatype (Data n ttag cty cons))
94+ updateContext (setMetaInformation n metainf)
95+ mapM_ totcheck (zip (repeat fc) (map fst cons))
96+-- mapM_ (checkPositive n) cons
97+
98+ -- if there's exactly one constructor,
99+ -- mark both the type and the constructor as detaggable
100+ case cons of
101+ [(cn,ct)] -> setDetaggable cn >> setDetaggable n
102+ >> addIBC (IBCOpt cn) >> addIBC (IBCOpt n)
103+ _ -> return ()
104+
105+ -- create an eliminator
106+ when (DefaultEliminator `elem` opts) $
107+ evalStateT (elabCaseFun True params n t dcons info) Map.empty
108+ -- create a case function
109+ when (DefaultCaseFun `elem` opts) $
110+ evalStateT (elabCaseFun False params n t dcons info) Map.empty
111+ where
112+ setDetaggable :: Name -> Idris ()
113+ setDetaggable n = do
114+ ist <- getIState
115+ let opt = idris_optimisation ist
116+ case lookupCtxt n opt of
117+ [oi] -> putIState ist{ idris_optimisation = addDef n oi{ detaggable = True } opt }
118+ _ -> putIState ist{ idris_optimisation = addDef n (Optimise [] True) opt }
119+
120+ checkDefinedAs fc n t ctxt
121+ = case lookupDef n ctxt of
122+ [] -> return ()
123+ [TyDecl _ ty] ->
124+ case converts ctxt [] t ty of
125+ OK () -> return ()
126+ _ -> tclift $ tfail (At fc (AlreadyDefined n))
127+ _ -> tclift $ tfail (At fc (AlreadyDefined n))
128+ -- parameters are names which are unchanged across the structure,
129+ -- which appear exactly once in the return type of a constructor
130+
131+ -- First, find all applications of the constructor, then check over
132+ -- them for repeated arguments
133+
134+ findParams :: [Type] -> [Int]
135+ findParams ts = let allapps = concatMap getDataApp ts in
136+ paramPos allapps
137+
138+ paramPos [] = []
139+ paramPos (args : rest)
140+ = dropNothing $ keepSame (zip [0..] args) rest
141+
142+ dropNothing [] = []
143+ dropNothing ((x, Nothing) : ts) = dropNothing ts
144+ dropNothing ((x, _) : ts) = x : dropNothing ts
145+
146+ keepSame :: [(Int, Maybe Name)] -> [[Maybe Name]] ->
147+ [(Int, Maybe Name)]
148+ keepSame as [] = as
149+ keepSame as (args : rest) = keepSame (update as args) rest
150+ where
151+ update [] _ = []
152+ update _ [] = []
153+ update ((n, Just x) : as) (Just x' : args)
154+ | x == x' = (n, Just x) : update as args
155+ update ((n, _) : as) (_ : args) = (n, Nothing) : update as args
156+
157+ getDataApp :: Type -> [[Maybe Name]]
158+ getDataApp f@(App _ _)
159+ | (P _ d _, args) <- unApply f
160+ = if (d == n) then [mParam args args] else []
161+ getDataApp (Bind n (Pi t) sc)
162+ = getDataApp t ++ getDataApp (instantiate (P Bound n t) sc)
163+ getDataApp _ = []
164+
165+ -- keep the arguments which are single names, which don't appear
166+ -- elsewhere
167+
168+ mParam args [] = []
169+ mParam args (P Bound n _ : rest)
170+ | count n args == 1
171+ = Just n : mParam args rest
172+ where count n [] = 0
173+ count n (t : ts)
174+ | n `elem` freeNames t = 1 + count n ts
175+ | otherwise = count n ts
176+ mParam args (_ : rest) = Nothing : mParam args rest
177+
178+ cname (_, _, n, _, _, _) = n
179+
180+ -- Abuse of ElabInfo.
181+ -- TODO Contemplate whether the ElabInfo type needs modification.
182+ cinfo :: ElabInfo -> [Name] -> ElabInfo
183+ cinfo info ds
184+ = let newps = params info
185+ dsParams = map (\n -> (n, [])) ds
186+ newb = addAlist dsParams (inblock info)
187+ l = liftname info in
188+ info { params = newps,
189+ inblock = newb,
190+ liftname = id -- Is this appropriate?
191+ }
192+
193+-- FIXME: 'forcenames' is an almighty hack! Need a better way of
194+-- erasing non-forceable things
195+-- ^^^
196+-- TODO: the above is a comment from the past;
197+-- forcenames is probably no longer needed
198+elabCon :: ElabInfo -> SyntaxInfo -> Name -> Bool ->
199+ (Docstring, [(Name, Docstring)], Name, PTerm, FC, [Name]) -> Idris (Name, Type)
200+elabCon info syn tn codata (doc, argDocs, n, t_in, fc, forcenames)
201+ = do checkUndefined fc n
202+ (cty, t, inacc) <- buildType info syn fc [] n (if codata then mkLazy t_in else t_in)
203+ ctxt <- getContext
204+ let cty' = normalise ctxt [] cty
205+
206+ -- Check that the constructor type is, in fact, a part of the family being defined
207+ tyIs n cty'
208+
209+ logLvl 2 $ show fc ++ ":Constructor " ++ show n ++ " : " ++ show t
210+ logLvl 5 $ "Inaccessible args: " ++ show inacc
211+ logLvl 2 $ "---> " ++ show n ++ " : " ++ show cty'
212+
213+ addIBC (IBCDef n)
214+ checkDocs fc argDocs t
215+ addDocStr n doc argDocs
216+ addIBC (IBCDoc n)
217+ fputState (opt_inaccessible . ist_optimisation n) inacc
218+ addIBC (IBCOpt n)
219+ return (n, cty')
220+ where
221+ tyIs con (Bind n b sc) = tyIs con sc
222+ tyIs con t | (P _ n' _, _) <- unApply t
223+ = if n' /= tn then tclift $ tfail (At fc (Elaborating "constructor " con (Msg (show n' ++ " is not " ++ show tn))))
224+ else return ()
225+ tyIs con t = tclift $ tfail (At fc (Elaborating "constructor " con (Msg (show t ++ " is not " ++ show tn))))
226+
227+ mkLazy (PPi pl n ty sc)
228+ = let ty' = if getTyName ty
229+ then PApp fc (PRef fc (sUN "Lazy'"))
230+ [pexp (PRef fc (sUN "LazyCodata")),
231+ pexp ty]
232+ else ty in
233+ PPi pl n ty' (mkLazy sc)
234+ mkLazy t = t
235+
236+ getTyName (PApp _ (PRef _ n) _) = n == nsroot tn
237+ getTyName (PRef _ n) = n == nsroot tn
238+ getTyName _ = False
239+
240+
241+ getNamePos :: Int -> PTerm -> Name -> Maybe Int
242+ getNamePos i (PPi _ n _ sc) x | n == x = Just i
243+ | otherwise = getNamePos (i + 1) sc x
244+ getNamePos _ _ _ = Nothing
245+
246+type EliminatorState = StateT (Map.Map String Int) Idris
247+
248+-- TODO: Rewrite everything to use idris_implicits instead of manual splitting (or in TT)
249+-- FIXME: Many things have name starting with elim internally since this was the only purpose in the first edition of the function
250+-- rename to caseFun to match updated intend
251+elabCaseFun :: Bool -> [Int] -> Name -> PTerm ->
252+ [(Docstring, [(Name, Docstring)], Name, PTerm, FC, [Name])] ->
253+ ElabInfo -> EliminatorState ()
254+elabCaseFun ind paramPos n ty cons info = do
255+ elimLog $ "Elaborating case function"
256+ put (Map.fromList $ zip (concatMap (\(_, p, _, ty, _, _) -> (map show $ boundNamesIn ty) ++ map (show . fst) p) cons ++ (map show $ boundNamesIn ty)) (repeat 0))
257+ let (cnstrs, _) = splitPi ty
258+ let (splittedTy@(pms, idxs)) = splitPms cnstrs
259+ generalParams <- namePis False pms
260+ motiveIdxs <- namePis False idxs
261+ let motive = mkMotive n paramPos generalParams motiveIdxs
262+ consTerms <- mapM (\(c@(_, _, cnm, _, _, _)) -> do
263+ let casefunt = if ind then "elim_" else "case_"
264+ name <- freshName $ casefunt ++ simpleName cnm
265+ consTerm <- extractConsTerm c generalParams
266+ return (name, expl, consTerm)) cons
267+ scrutineeIdxs <- namePis False idxs
268+ let motiveConstr = [(motiveName, expl, motive)]
269+ let scrutinee = (scrutineeName, expl, applyCons n (interlievePos paramPos generalParams scrutineeIdxs 0))
270+ let eliminatorTy = piConstr (generalParams ++ motiveConstr ++ consTerms ++ scrutineeIdxs ++ [scrutinee]) (applyMotive (map (\(n,_,_) -> PRef elimFC n) scrutineeIdxs) (PRef elimFC scrutineeName))
271+ let eliminatorTyDecl = PTy (parseDocstring . T.pack $ show n) [] defaultSyntax elimFC [TotalFn] elimDeclName eliminatorTy
272+ let clauseConsElimArgs = map getPiName consTerms
273+ let clauseGeneralArgs' = map getPiName generalParams ++ [motiveName] ++ clauseConsElimArgs
274+ let clauseGeneralArgs = map (\arg -> pexp (PRef elimFC arg)) clauseGeneralArgs'
275+ let elimSig = "-- case function signature: " ++ showTmImpls eliminatorTy
276+ elimLog elimSig
277+ eliminatorClauses <- mapM (\(cns, cnsElim) -> generateEliminatorClauses cns cnsElim clauseGeneralArgs generalParams) (zip cons clauseConsElimArgs)
278+ let eliminatorDef = PClauses emptyFC [TotalFn] elimDeclName eliminatorClauses
279+ elimLog $ "-- case function definition: " ++ (show . showDeclImp verbosePPOption) eliminatorDef
280+ State.lift $ idrisCatch (rec_elabDecl info EAll info eliminatorTyDecl) (\err -> return ())
281+ -- Do not elaborate clauses if there aren't any
282+ case eliminatorClauses of
283+ [] -> State.lift $ solveDeferred elimDeclName -- Remove meta-variable for type
284+ _ -> State.lift $ idrisCatch (rec_elabDecl info EAll info eliminatorDef) (\err -> return ())
285+ where elimLog :: String -> EliminatorState ()
286+ elimLog s = State.lift (logLvl 2 s)
287+
288+ elimFC :: FC
289+ elimFC = fileFC "(casefun)"
290+
291+ elimDeclName :: Name
292+ elimDeclName = if ind then SN . ElimN $ n else SN . CaseN $ n
293+
294+ applyNS :: Name -> [String] -> Name
295+ applyNS n [] = n
296+ applyNS n ns = sNS n ns
297+
298+ splitPi :: PTerm -> ([(Name, Plicity, PTerm)], PTerm)
299+ splitPi = splitPi' []
300+ where splitPi' :: [(Name, Plicity, PTerm)] -> PTerm -> ([(Name, Plicity, PTerm)], PTerm)
301+ splitPi' acc (PPi pl n tyl tyr) = splitPi' ((n, pl, tyl):acc) tyr
302+ splitPi' acc t = (reverse acc, t)
303+
304+ splitPms :: [(Name, Plicity, PTerm)] -> ([(Name, Plicity, PTerm)], [(Name, Plicity, PTerm)])
305+ splitPms cnstrs = (map fst pms, map fst idxs)
306+ where (pms, idxs) = partition (\c -> snd c `elem` paramPos) (zip cnstrs [0..])
307+
308+ isMachineGenerated :: Name -> Bool
309+ isMachineGenerated (MN _ _) = True
310+ isMachineGenerated _ = False
311+
312+ namePis :: Bool -> [(Name, Plicity, PTerm)] -> EliminatorState [(Name, Plicity, PTerm)]
313+ namePis keepOld pms = do names <- mapM (mkPiName keepOld) pms
314+ let oldNames = map fst names
315+ let params = map snd names
316+ return $ map (\(n, pl, ty) -> (n, pl, removeParamPis oldNames params ty)) params
317+
318+ mkPiName :: Bool -> (Name, Plicity, PTerm) -> EliminatorState (Name, (Name, Plicity, PTerm))
319+ mkPiName keepOld (n, pl, piarg) | not (isMachineGenerated n) && keepOld = do return (n, (n, pl, piarg))
320+ mkPiName _ (oldName, pl, piarg) = do name <- freshName $ keyOf piarg
321+ return (oldName, (name, pl, piarg))
322+ where keyOf :: PTerm -> String
323+ keyOf (PRef _ name) | isLetter (nameStart name) = (toLower $ nameStart name):"__"
324+ keyOf (PApp _ tyf _) = keyOf tyf
325+ keyOf PType = "ty__"
326+ keyOf _ = "carg__"
327+ nameStart :: Name -> Char
328+ nameStart n = nameStart' (simpleName n)
329+ where nameStart' :: String -> Char
330+ nameStart' "" = ' '
331+ nameStart' ns = head ns
332+
333+ simpleName :: Name -> String
334+ simpleName (NS n _) = simpleName n
335+ simpleName (MN i n) = str n ++ show i
336+ simpleName n = show n
337+
338+ nameSpaces :: Name -> [String]
339+ nameSpaces (NS _ ns) = map str ns
340+ nameSpaces _ = []
341+
342+ freshName :: String -> EliminatorState Name
343+ freshName key = do
344+ nameMap <- get
345+ let i = fromMaybe 0 (Map.lookup key nameMap)
346+ let name = uniqueName (sUN (key ++ show i)) (map (\(nm, nb) -> sUN (nm ++ show nb)) $ Map.toList nameMap)
347+ put $ Map.insert key (i+1) nameMap
348+ return name
349+
350+ scrutineeName :: Name
351+ scrutineeName = sUN "scrutinee"
352+
353+ scrutineeArgName :: Name
354+ scrutineeArgName = sUN "scrutineeArg"
355+
356+ motiveName :: Name
357+ motiveName = sUN "prop"
358+
359+ mkMotive :: Name -> [Int] -> [(Name, Plicity, PTerm)] -> [(Name, Plicity, PTerm)] -> PTerm
360+ mkMotive n paramPos params indicies =
361+ let scrutineeTy = (scrutineeArgName, expl, applyCons n (interlievePos paramPos params indicies 0))
362+ in piConstr (indicies ++ [scrutineeTy]) PType
363+
364+ piConstr :: [(Name, Plicity, PTerm)] -> PTerm -> PTerm
365+ piConstr [] ty = ty
366+ piConstr ((n, pl, tyb):tyr) ty = PPi pl n tyb (piConstr tyr ty)
367+
368+ interlievePos :: [Int] -> [a] -> [a] -> Int -> [a]
369+ interlievePos idxs [] l2 i = l2
370+ interlievePos idxs l1 [] i = l1
371+ interlievePos idxs (x:xs) l2 i | i `elem` idxs = x:(interlievePos idxs xs l2 (i+1))
372+ interlievePos idxs l1 (y:ys) i = y:(interlievePos idxs l1 ys (i+1))
373+
374+ replaceParams :: [Int] -> [(Name, Plicity, PTerm)] -> PTerm -> PTerm
375+ replaceParams paramPos params cns =
376+ let (_, cnsResTy) = splitPi cns
377+ in case cnsResTy of
378+ PApp _ _ args ->
379+ let oldParams = paramNamesOf 0 paramPos args
380+ in removeParamPis oldParams params cns
381+ _ -> cns
382+
383+ removeParamPis :: [Name] -> [(Name, Plicity, PTerm)] -> PTerm -> PTerm
384+ removeParamPis oldParams params (PPi pl n tyb tyr) =
385+ case findIndex (== n) oldParams of
386+ Nothing -> (PPi pl n (removeParamPis oldParams params tyb) (removeParamPis oldParams params tyr))
387+ Just i -> (removeParamPis oldParams params tyr)
388+ removeParamPis oldParams params (PRef _ n) =
389+ case findIndex (== n) oldParams of
390+ Nothing -> (PRef elimFC n)
391+ Just i -> let (newname,_,_) = params !! i in (PRef elimFC (newname))
392+ removeParamPis oldParams params (PApp _ cns args) =
393+ PApp elimFC (removeParamPis oldParams params cns) $ replaceParamArgs args
394+ where replaceParamArgs :: [PArg] -> [PArg]
395+ replaceParamArgs [] = []
396+ replaceParamArgs (arg:args) =
397+ case extractName (getTm arg) of
398+ [] -> arg:replaceParamArgs args
399+ [n] ->
400+ case findIndex (== n) oldParams of
401+ Nothing -> arg:replaceParamArgs args
402+ Just i -> let (newname,_,_) = params !! i in arg {getTm = PRef elimFC newname}:replaceParamArgs args
403+ removeParamPis oldParams params t = t
404+
405+ paramNamesOf :: Int -> [Int] -> [PArg] -> [Name]
406+ paramNamesOf i paramPos [] = []
407+ paramNamesOf i paramPos (arg:args) = (if i `elem` paramPos then extractName (getTm arg) else []) ++ paramNamesOf (i+1) paramPos args
408+
409+ extractName :: PTerm -> [Name]
410+ extractName (PRef _ n) = [n]
411+ extractName _ = []
412+
413+ splitArgPms :: PTerm -> ([PTerm], [PTerm])
414+ splitArgPms (PApp _ f args) = splitArgPms' args
415+ where splitArgPms' :: [PArg] -> ([PTerm], [PTerm])
416+ splitArgPms' cnstrs = (map (getTm . fst) pms, map (getTm . fst) idxs)
417+ where (pms, idxs) = partition (\c -> snd c `elem` paramPos) (zip cnstrs [0..])
418+ splitArgPms _ = ([],[])
419+
420+
421+ implicitIndexes :: (Docstring, Name, PTerm, FC, [Name]) -> EliminatorState [(Name, Plicity, PTerm)]
422+ implicitIndexes (cns@(doc, cnm, ty, fc, fs)) = do
423+ i <- State.lift getIState
424+ implargs' <- case lookupCtxt cnm (idris_implicits i) of
425+ [] -> do fail $ "Error while showing implicits for " ++ show cnm
426+ [args] -> do return args
427+ _ -> do fail $ "Ambigous name for " ++ show cnm
428+ let implargs = mapMaybe convertImplPi implargs'
429+ let (_, cnsResTy) = splitPi ty
430+ case cnsResTy of
431+ PApp _ _ args ->
432+ let oldParams = paramNamesOf 0 paramPos args
433+ in return $ filter (\(n,_,_) -> not (n `elem` oldParams))implargs
434+ _ -> return implargs
435+
436+ extractConsTerm :: (Docstring, [(Name, Docstring)], Name, PTerm, FC, [Name]) -> [(Name, Plicity, PTerm)] -> EliminatorState PTerm
437+ extractConsTerm (doc, argDocs, cnm, ty, fc, fs) generalParameters = do
438+ let cons' = replaceParams paramPos generalParameters ty
439+ let (args, resTy) = splitPi cons'
440+ implidxs <- implicitIndexes (doc, cnm, ty, fc, fs)
441+ consArgs <- namePis False args
442+ let recArgs = findRecArgs consArgs
443+ let recMotives = if ind then map applyRecMotive recArgs else []
444+ let (_, consIdxs) = splitArgPms resTy
445+ return $ piConstr (implidxs ++ consArgs ++ recMotives) (applyMotive consIdxs (applyCons cnm consArgs))
446+ where applyRecMotive :: (Name, Plicity, PTerm) -> (Name, Plicity, PTerm)
447+ applyRecMotive (n,_,ty) = (sUN $ "ih" ++ simpleName n, expl, applyMotive idxs (PRef elimFC n))
448+ where (_, idxs) = splitArgPms ty
449+
450+ findRecArgs :: [(Name, Plicity, PTerm)] -> [(Name, Plicity, PTerm)]
451+ findRecArgs [] = []
452+ findRecArgs (ty@(_,_,PRef _ tn):rs) | simpleName tn == simpleName n = ty:findRecArgs rs
453+ findRecArgs (ty@(_,_,PApp _ (PRef _ tn) _):rs) | simpleName tn == simpleName n = ty:findRecArgs rs
454+ findRecArgs (ty:rs) = findRecArgs rs
455+
456+ applyCons :: Name -> [(Name, Plicity, PTerm)] -> PTerm
457+ applyCons tn targs = PApp elimFC (PRef elimFC tn) (map convertArg targs)
458+
459+ convertArg :: (Name, Plicity, PTerm) -> PArg
460+ convertArg (n, _, _) = pexp (PRef elimFC n)
461+
462+ applyMotive :: [PTerm] -> PTerm -> PTerm
463+ applyMotive idxs t = PApp elimFC (PRef elimFC motiveName) (map pexp idxs ++ [pexp t])
464+
465+ getPiName :: (Name, Plicity, PTerm) -> Name
466+ getPiName (name,_,_) = name
467+
468+ convertImplPi :: PArg -> Maybe (Name, Plicity, PTerm)
469+ convertImplPi (PImp {getTm = t, pname = n}) = Just (n, expl, t)
470+ convertImplPi _ = Nothing
471+
472+ generateEliminatorClauses :: (Docstring, [(Name, Docstring)], Name, PTerm, FC, [Name]) -> Name -> [PArg] -> [(Name, Plicity, PTerm)] -> EliminatorState PClause
473+ generateEliminatorClauses (doc, _, cnm, ty, fc, fs) cnsElim generalArgs generalParameters = do
474+ let cons' = replaceParams paramPos generalParameters ty
475+ let (args, resTy) = splitPi cons'
476+ i <- State.lift getIState
477+ implidxs <- implicitIndexes (doc, cnm, ty, fc, fs)
478+ let (_, generalIdxs') = splitArgPms resTy
479+ let generalIdxs = map pexp generalIdxs'
480+ consArgs <- namePis False args
481+ let lhsPattern = PApp elimFC (PRef elimFC elimDeclName) (generalArgs ++ generalIdxs ++ [pexp $ applyCons cnm consArgs])
482+ let recArgs = findRecArgs consArgs
483+ let recElims = if ind then map applyRecElim recArgs else []
484+ let rhsExpr = PApp elimFC (PRef elimFC cnsElim) (map convertArg implidxs ++ map convertArg consArgs ++ recElims)
485+ return $ PClause elimFC elimDeclName lhsPattern [] rhsExpr []
486+ where applyRecElim :: (Name, Plicity, PTerm) -> PArg
487+ applyRecElim (constr@(recCnm,_,recTy)) = pexp $ PApp elimFC (PRef elimFC elimDeclName) (generalArgs ++ map pexp idxs ++ [pexp $ PRef elimFC recCnm])
488+ where (_, idxs) = splitArgPms recTy
489+
src/Idris/Elab/Instance.hsnew file+260
@@ -0,0 +1,260 @@
1+{-# LANGUAGE PatternGuards #-}
2+module Idris.Elab.Instance(elabInstance) where
3+
4+import Idris.AbsSyntax
5+import Idris.ASTUtils
6+import Idris.DSL
7+import Idris.Error
8+import Idris.Delaborate
9+import Idris.Imports
10+import Idris.ElabTerm
11+import Idris.Coverage
12+import Idris.DataOpts
13+import Idris.Providers
14+import Idris.Primitives
15+import Idris.Inliner
16+import Idris.PartialEval
17+import Idris.DeepSeq
18+import Idris.Output (iputStrLn, pshow, iWarn)
19+import IRTS.Lang
20+
21+import Idris.Elab.Type
22+import Idris.Elab.Data
23+import Idris.Elab.Utils
24+
25+import Idris.Core.TT
26+import Idris.Core.Elaborate hiding (Tactic(..))
27+import Idris.Core.Evaluate
28+import Idris.Core.Execute
29+import Idris.Core.Typecheck
30+import Idris.Core.CaseTree
31+
32+import Idris.Docstrings
33+
34+import Prelude hiding (id, (.))
35+import Control.Category
36+
37+import Control.Applicative hiding (Const)
38+import Control.DeepSeq
39+import Control.Monad
40+import Control.Monad.State.Strict as State
41+import Data.List
42+import Data.Maybe
43+import Debug.Trace
44+
45+import qualified Data.Map as Map
46+import qualified Data.Set as S
47+import qualified Data.Text as T
48+import Data.Char(isLetter, toLower)
49+import Data.List.Split (splitOn)
50+
51+import Util.Pretty(pretty, text)
52+
53+elabInstance :: ElabInfo -> SyntaxInfo ->
54+ ElabWhat -> -- phase
55+ FC -> [PTerm] -> -- constraints
56+ Name -> -- the class
57+ [PTerm] -> -- class parameters (i.e. instance)
58+ PTerm -> -- full instance type
59+ Maybe Name -> -- explicit name
60+ [PDecl] -> Idris ()
61+elabInstance info syn what fc cs n ps t expn ds = do
62+ i <- getIState
63+ (n, ci) <- case lookupCtxtName n (idris_classes i) of
64+ [c] -> return c
65+ [] -> ifail $ show fc ++ ":" ++ show n ++ " is not a type class"
66+ cs -> tclift $ tfail $ At fc
67+ (CantResolveAlts (map fst cs))
68+ let constraint = PApp fc (PRef fc n) (map pexp ps)
69+ let iname = mkiname n ps expn
70+ let emptyclass = null (class_methods ci)
71+ when (what /= EDefns || (null ds && not emptyclass)) $ do
72+ nty <- elabType' True info syn emptyDocstring [] fc [] iname t
73+ -- if the instance type matches any of the instances we have already,
74+ -- and it's not a named instance, then it's overlapping, so report an error
75+ case expn of
76+ Nothing -> do mapM_ (maybe (return ()) overlapping . findOverlapping i (delab i nty))
77+ (class_instances ci)
78+ addInstance intInst n iname
79+ Just _ -> addInstance intInst n iname
80+ when (what /= ETypes && (not (null ds && not emptyclass))) $ do
81+ let ips = zip (class_params ci) ps
82+ let ns = case n of
83+ NS n ns' -> ns'
84+ _ -> []
85+ -- get the implicit parameters that need passing through to the
86+ -- where block
87+ wparams <- mapM (\p -> case p of
88+ PApp _ _ args -> getWParams (map getTm args)
89+ _ -> return []) ps
90+ let pnames = map pname (concat (nub wparams))
91+ let superclassInstances = map (substInstance ips pnames) (class_default_superclasses ci)
92+ undefinedSuperclassInstances <- filterM (fmap not . isOverlapping i) superclassInstances
93+ mapM_ (rec_elabDecl info EAll info) undefinedSuperclassInstances
94+ let all_meths = map (nsroot . fst) (class_methods ci)
95+ let mtys = map (\ (n, (op, t)) ->
96+ let t_in = substMatchesShadow ips pnames t
97+ mnamemap = map (\n -> (n, PRef fc (decorate ns iname n)))
98+ all_meths
99+ t' = substMatchesShadow mnamemap pnames t_in in
100+ (decorate ns iname n,
101+ op, coninsert cs t', t'))
102+ (class_methods ci)
103+ logLvl 3 (show (mtys, ips))
104+ let ds' = insertDefaults i iname (class_defaults ci) ns ds
105+ iLOG ("Defaults inserted: " ++ show ds' ++ "\n" ++ show ci)
106+ mapM_ (warnMissing ds' ns iname) (map fst (class_methods ci))
107+ mapM_ (checkInClass (map fst (class_methods ci))) (concatMap defined ds')
108+ let wbTys = map mkTyDecl mtys
109+ let wbVals = map (decorateid (decorate ns iname)) ds'
110+ let wb = wbTys ++ wbVals
111+ logLvl 3 $ "Method types " ++ showSep "\n" (map (show . showDeclImp verbosePPOption . mkTyDecl) mtys)
112+ logLvl 3 $ "Instance is " ++ show ps ++ " implicits " ++
113+ show (concat (nub wparams))
114+
115+ -- Bring variables in instance head into scope
116+ ist <- getIState
117+ let headVars = nub $ mapMaybe (\p -> case p of
118+ PRef _ n ->
119+ case lookupTy n (tt_ctxt ist) of
120+ [] -> Just n
121+ _ -> Nothing
122+ _ -> Nothing) ps
123+-- let lhs = PRef fc iname
124+ let lhs = PApp fc (PRef fc iname)
125+ (map (\n -> pimp n (PRef fc n) True) headVars)
126+ let rhs = PApp fc (PRef fc (instanceName ci))
127+ (map (pexp . mkMethApp) mtys)
128+
129+ logLvl 5 $ "Instance LHS " ++ show lhs ++ " " ++ show headVars
130+ logLvl 5 $ "Instance RHS " ++ show rhs
131+
132+ let idecls = [PClauses fc [Dictionary] iname
133+ [PClause fc iname lhs [] rhs wb]]
134+ iLOG (show idecls)
135+ mapM_ (rec_elabDecl info EAll info) idecls
136+ addIBC (IBCInstance intInst n iname)
137+
138+ where
139+ intInst = case ps of
140+ [PConstant (AType (ATInt ITNative))] -> True
141+ _ -> False
142+
143+ mkiname n' ps' expn' =
144+ case expn' of
145+ Nothing -> SN (sInstanceN n' (map show ps'))
146+ Just nm -> nm
147+
148+ substInstance ips pnames (PInstance syn _ cs n ps t expn ds)
149+ = PInstance syn fc cs n (map (substMatchesShadow ips pnames) ps) (substMatchesShadow ips pnames t) expn ds
150+
151+ isOverlapping i (PInstance syn _ _ n ps t expn _)
152+ = case lookupCtxtName n (idris_classes i) of
153+ [(n, ci)] -> let iname = (mkiname n ps expn) in
154+ case lookupTy iname (tt_ctxt i) of
155+ [] -> elabFindOverlapping i ci iname syn t
156+ (_:_) -> return True
157+ _ -> return False -- couldn't find class, just let elabInstance fail later
158+
159+ -- TODO: largely based upon elabType' - should try to abstract
160+ elabFindOverlapping i ci iname syn t
161+ = do ty' <- addUsingConstraints syn fc t
162+ -- TODO think: something more in info?
163+ ty' <- implicit info syn iname ty'
164+ let ty = addImpl i ty'
165+ ctxt <- getContext
166+ ((tyT, _, _), _) <-
167+ tclift $ elaborate ctxt iname (TType (UVal 0)) []
168+ (errAt "type of " iname (erun fc (build i info ERHS [] iname ty)))
169+ ctxt <- getContext
170+ (cty, _) <- recheckC fc [] tyT
171+ let nty = normalise ctxt [] cty
172+ return $ any (isJust . findOverlapping i (delab i nty)) (class_instances ci)
173+
174+ findOverlapping i t n
175+ | take 2 (show n) == "@@" = Nothing
176+ | otherwise
177+ = case lookupTy n (tt_ctxt i) of
178+ [t'] -> let tret = getRetType t
179+ tret' = getRetType (delab i t') in
180+ case matchClause i tret' tret of
181+ Right ms -> Just tret'
182+ Left _ -> case matchClause i tret tret' of
183+ Right ms -> Just tret'
184+ Left _ -> Nothing
185+ _ -> Nothing
186+ overlapping t' = tclift $ tfail (At fc (Msg $
187+ "Overlapping instance: " ++ show t' ++ " already defined"))
188+ getRetType (PPi _ _ _ sc) = getRetType sc
189+ getRetType t = t
190+
191+ mkMethApp (n, _, _, ty)
192+ = lamBind 0 ty (papp fc (PRef fc n) (methArgs 0 ty))
193+ lamBind i (PPi (Constraint _ _) _ _ sc) sc'
194+ = PLam (sMN i "meth") Placeholder (lamBind (i+1) sc sc')
195+ lamBind i (PPi _ n ty sc) sc'
196+ = PLam (sMN i "meth") Placeholder (lamBind (i+1) sc sc')
197+ lamBind i _ sc = sc
198+ methArgs i (PPi (Imp _ _ _) n ty sc)
199+ = PImp 0 True [] n (PRef fc (sMN i "meth")) : methArgs (i+1) sc
200+ methArgs i (PPi (Exp _ _ _) n ty sc)
201+ = PExp 0 [] (sMN 0 "marg") (PRef fc (sMN i "meth")) : methArgs (i+1) sc
202+ methArgs i (PPi (Constraint _ _) n ty sc)
203+ = PConstraint 0 [] (sMN 0 "marg") (PResolveTC fc) : methArgs (i+1) sc
204+ methArgs i _ = []
205+
206+ papp fc f [] = f
207+ papp fc f as = PApp fc f as
208+
209+ getWParams [] = return []
210+ getWParams (p : ps)
211+ | PRef _ n <- p
212+ = do ps' <- getWParams ps
213+ ctxt <- getContext
214+ case lookupP n ctxt of
215+ [] -> return (pimp n (PRef fc n) True : ps')
216+ _ -> return ps'
217+ getWParams (_ : ps) = getWParams ps
218+
219+ decorate ns iname (UN n) = NS (SN (MethodN (UN n))) ns
220+ decorate ns iname (NS (UN n) s) = NS (SN (MethodN (UN n))) ns
221+
222+ mkTyDecl (n, op, t, _) = PTy emptyDocstring [] syn fc op n t
223+
224+ conbind (ty : ns) x = PPi constraint (sMN 0 "class") ty (conbind ns x)
225+ conbind [] x = x
226+
227+ coninsert cs (PPi p@(Imp _ _ _) n t sc) = PPi p n t (coninsert cs sc)
228+ coninsert cs sc = conbind cs sc
229+
230+ insertDefaults :: IState -> Name ->
231+ [(Name, (Name, PDecl))] -> [T.Text] ->
232+ [PDecl] -> [PDecl]
233+ insertDefaults i iname [] ns ds = ds
234+ insertDefaults i iname ((n,(dn, clauses)) : defs) ns ds
235+ = insertDefaults i iname defs ns (insertDef i n dn clauses ns iname ds)
236+
237+ insertDef i meth def clauses ns iname decls
238+ | null $ filter (clauseFor meth iname ns) decls
239+ = let newd = expandParamsD False i (\n -> meth) [] [def] clauses in
240+ -- trace (show newd) $
241+ decls ++ [newd]
242+ | otherwise = decls
243+
244+ warnMissing decls ns iname meth
245+ | null $ filter (clauseFor meth iname ns) decls
246+ = iWarn fc . text $ "method " ++ show meth ++ " not defined"
247+ | otherwise = return ()
248+
249+ checkInClass ns meth
250+ | not (null (filter (eqRoot meth) ns)) = return ()
251+ | otherwise = tclift $ tfail (At fc (Msg $
252+ show meth ++ " not a method of class " ++ show n))
253+
254+ eqRoot x y = nsroot x == nsroot y
255+
256+ clauseFor m iname ns (PClauses _ _ m' _)
257+ = decorate ns iname m == decorate ns iname m'
258+ clauseFor m iname ns _ = False
259+
260+
src/Idris/Elab/Provider.hsnew file+117
@@ -0,0 +1,117 @@
1+{-# LANGUAGE PatternGuards #-}
2+module Idris.Elab.Provider(elabProvider) where
3+
4+import Idris.AbsSyntax
5+import Idris.ASTUtils
6+import Idris.DSL
7+import Idris.Error
8+import Idris.Delaborate
9+import Idris.Imports
10+import Idris.ElabTerm
11+import Idris.Coverage
12+import Idris.DataOpts
13+import Idris.Providers
14+import Idris.Primitives
15+import Idris.Inliner
16+import Idris.PartialEval
17+import Idris.DeepSeq
18+import Idris.Output (iputStrLn, pshow, iWarn)
19+import IRTS.Lang
20+
21+import Idris.Elab.Type
22+import Idris.Elab.Clause
23+import Idris.Elab.Value
24+import Idris.Elab.Utils
25+
26+import Idris.Core.TT
27+import Idris.Core.Elaborate hiding (Tactic(..))
28+import Idris.Core.Evaluate
29+import Idris.Core.Execute
30+import Idris.Core.Typecheck
31+import Idris.Core.CaseTree
32+
33+import Idris.Docstrings
34+
35+import Prelude hiding (id, (.))
36+import Control.Category
37+
38+import Control.Applicative hiding (Const)
39+import Control.DeepSeq
40+import Control.Monad
41+import Control.Monad.State.Strict as State
42+import Data.List
43+import Data.Maybe
44+import Debug.Trace
45+
46+import qualified Data.Map as Map
47+import qualified Data.Set as S
48+import qualified Data.Text as T
49+import Data.Char(isLetter, toLower)
50+import Data.List.Split (splitOn)
51+
52+import Util.Pretty(pretty, text)
53+
54+-- | Elaborate a type provider
55+elabProvider :: ElabInfo -> SyntaxInfo -> FC -> ProvideWhat -> Name -> Idris ()
56+elabProvider info syn fc what n
57+ = do i <- getIState
58+ -- Ensure that the experimental extension is enabled
59+ unless (TypeProviders `elem` idris_language_extensions i) $
60+ ifail $ "Failed to define type provider \"" ++ show n ++
61+ "\".\nYou must turn on the TypeProviders extension."
62+
63+ ctxt <- getContext
64+
65+ -- First elaborate the expected type (and check that it's a type)
66+ -- The goal type for a postulate is always Type.
67+ (ty', typ) <- case what of
68+ ProvTerm ty p -> elabVal info ERHS ty
69+ ProvPostulate _ -> elabVal info ERHS PType
70+ unless (isTType typ) $
71+ ifail ("Expected a type, got " ++ show ty' ++ " : " ++ show typ)
72+
73+ -- Elaborate the provider term to TT and check that the type matches
74+ (e, et) <- case what of
75+ ProvTerm _ tm -> elabVal info ERHS tm
76+ ProvPostulate tm -> elabVal info ERHS tm
77+ unless (isProviderOf (normalise ctxt [] ty') et) $
78+ ifail $ "Expected provider type IO (Provider (" ++
79+ show ty' ++ "))" ++ ", got " ++ show et ++ " instead."
80+
81+ -- Execute the type provider and normalise the result
82+ -- use 'run__provider' to convert to a primitive IO action
83+
84+ rhs <- execute (mkApp (P Ref (sUN "run__provider") Erased)
85+ [Erased, e])
86+ let rhs' = normalise ctxt [] rhs
87+ logLvl 3 $ "Normalised " ++ show n ++ "'s RHS to " ++ show rhs
88+
89+ -- Extract the provided term or postulate from the type provider
90+ provided <- getProvided fc rhs'
91+
92+ case provided of
93+ Provide tm
94+ | ProvTerm ty _ <- what ->
95+ do -- Finally add a top-level definition of the provided term
96+ elabType info syn emptyDocstring [] fc [] n ty
97+ elabClauses info fc [] n [PClause fc n (PApp fc (PRef fc n) []) [] (delab i tm) []]
98+ logLvl 3 $ "Elaborated provider " ++ show n ++ " as: " ++ show tm
99+ | ProvPostulate _ <- what ->
100+ do -- Add the postulate
101+ elabPostulate info syn (parseDocstring $ T.pack "Provided postulate") fc [] n (delab i tm)
102+ logLvl 3 $ "Elaborated provided postulate " ++ show n
103+ | otherwise ->
104+ ierror . Msg $ "Attempted to provide a postulate where a term was expected."
105+
106+ where isTType :: TT Name -> Bool
107+ isTType (TType _) = True
108+ isTType _ = False
109+
110+ isProviderOf :: TT Name -> TT Name -> Bool
111+ isProviderOf tp prov
112+ | (P _ (UN io) _, [prov']) <- unApply prov
113+ , (P _ (NS (UN prov) [provs]) _, [tp']) <- unApply prov'
114+ , tp == tp', io == txt "IO"
115+ , prov == txt "Provider" && provs == txt "Providers" = True
116+ isProviderOf _ _ = False
117+
src/Idris/Elab/Record.hsnew file+242
@@ -0,0 +1,242 @@
1+{-# LANGUAGE PatternGuards #-}
2+module Idris.Elab.Record(elabRecord) where
3+
4+import Idris.AbsSyntax
5+import Idris.ASTUtils
6+import Idris.DSL
7+import Idris.Error
8+import Idris.Delaborate
9+import Idris.Imports
10+import Idris.ElabTerm
11+import Idris.Coverage
12+import Idris.DataOpts
13+import Idris.Providers
14+import Idris.Primitives
15+import Idris.Inliner
16+import Idris.PartialEval
17+import Idris.DeepSeq
18+import Idris.Output (iputStrLn, pshow, iWarn)
19+import IRTS.Lang
20+
21+import Idris.Elab.Type
22+import Idris.Elab.Data
23+import Idris.Elab.Utils
24+
25+import Idris.Core.TT
26+import Idris.Core.Elaborate hiding (Tactic(..))
27+import Idris.Core.Evaluate
28+import Idris.Core.Execute
29+import Idris.Core.Typecheck
30+import Idris.Core.CaseTree
31+
32+import Idris.Docstrings
33+
34+import Prelude hiding (id, (.))
35+import Control.Category
36+
37+import Control.Applicative hiding (Const)
38+import Control.DeepSeq
39+import Control.Monad
40+import Control.Monad.State.Strict as State
41+import Data.List
42+import Data.Maybe
43+import Debug.Trace
44+
45+import qualified Data.Map as Map
46+import qualified Data.Set as S
47+import qualified Data.Text as T
48+import Data.Char(isLetter, toLower)
49+import Data.List.Split (splitOn)
50+
51+import Util.Pretty(pretty, text)
52+
53+elabRecord :: ElabInfo -> SyntaxInfo -> Docstring -> FC -> Name ->
54+ PTerm -> DataOpts -> Docstring -> Name -> PTerm -> Idris ()
55+elabRecord info syn doc fc tyn ty opts cdoc cn cty_in
56+ = do elabData info syn doc [] fc opts (PDatadecl tyn ty [(cdoc, [], cn, cty_in, fc, [])])
57+ -- TODO think: something more in info?
58+ cty' <- implicit info syn cn cty_in
59+ i <- getIState
60+
61+ -- get bound implicits and propagate to setters (in case they
62+ -- provide useful information for inference)
63+ let extraImpls = getBoundImpls cty'
64+
65+ cty <- case lookupTy cn (tt_ctxt i) of
66+ [t] -> return (delab i t)
67+ _ -> ifail "Something went inexplicably wrong"
68+ cimp <- case lookupCtxt cn (idris_implicits i) of
69+ [imps] -> return imps
70+ ppos <- case lookupCtxt tyn (idris_datatypes i) of
71+ [ti] -> return $ param_pos ti
72+ let cty_imp = renameBs cimp cty
73+ let ptys = getProjs [] cty_imp
74+ let ptys_u = getProjs [] cty
75+ let recty = getRecTy cty_imp
76+ let recty_u = getRecTy cty
77+
78+ let paramNames = getPNames recty ppos
79+
80+ -- rename indices when we generate the getter/setter types, so
81+ -- that they don't clash with the names of the projections
82+ -- we're generating
83+ let index_names_in = getRecNameMap "_in" ppos recty
84+ let recty_in = substMatches index_names_in recty
85+
86+ logLvl 3 $ show (recty, recty_u, ppos, paramNames, ptys)
87+ -- Substitute indices with projection functions, and parameters with
88+ -- the updated parameter name
89+ let substs = map (\ (n, _) ->
90+ if n `elem` paramNames
91+ then (n, PRef fc (mkp n))
92+ else (n, PApp fc (PRef fc n)
93+ [pexp (PRef fc rec)]))
94+ ptys
95+
96+ -- Generate projection functions
97+ proj_decls <- mapM (mkProj recty_in substs cimp) (zip ptys [0..])
98+ logLvl 3 $ show proj_decls
99+ let nonImp = mapMaybe isNonImp (zip cimp ptys_u)
100+ let implBinds = getImplB id cty'
101+
102+ -- Generate update functions
103+ update_decls <- mapM (mkUpdate recty_u index_names_in extraImpls
104+ (getFieldNames cty')
105+ implBinds (length nonImp)) (zip nonImp [0..])
106+ mapM_ (rec_elabDecl info EAll info) (concat proj_decls)
107+ logLvl 3 $ show update_decls
108+ mapM_ (tryElabDecl info) (update_decls)
109+ where
110+-- syn = syn_in { syn_namespace = show (nsroot tyn) : syn_namespace syn_in }
111+
112+ isNonImp (PExp _ _ _ _, a) = Just a
113+ isNonImp _ = Nothing
114+
115+ getPNames (PApp _ _ as) ppos = getpn as ppos
116+ where
117+ getpn as [] = []
118+ getpn as (i:is) | length as > i,
119+ PRef _ n <- getTm (as!!i) = n : getpn as is
120+ | otherwise = getpn as is
121+ getPNames _ _ = []
122+
123+ tryElabDecl info (fn, ty, val)
124+ = do i <- getIState
125+ idrisCatch (do rec_elabDecl info EAll info ty
126+ rec_elabDecl info EAll info val)
127+ (\v -> do iputStrLn $ show fc ++
128+ ":Warning - can't generate setter for " ++
129+ show fn ++ " (" ++ show ty ++ ")"
130+-- ++ "\n" ++ pshow i v
131+ putIState i)
132+
133+ getBoundImpls (PPi (Imp _ _ _) n ty sc) = (n, ty) : getBoundImpls sc
134+ getBoundImpls _ = []
135+
136+ getImplB k (PPi (Imp l s _) n Placeholder sc)
137+ = getImplB k sc
138+ getImplB k (PPi (Imp l s p) n ty sc)
139+ = getImplB (\x -> k (PPi (Imp l s p) n ty x)) sc
140+ getImplB k (PPi _ n ty sc)
141+ = getImplB k sc
142+ getImplB k _ = k
143+
144+ renameBs (PImp _ _ _ _ _ : ps) (PPi p n ty s)
145+ = PPi p (mkImp n) ty (renameBs ps (substMatch n (PRef fc (mkImp n)) s))
146+ renameBs (_:ps) (PPi p n ty s) = PPi p n ty (renameBs ps s)
147+ renameBs _ t = t
148+
149+ getProjs acc (PPi _ n ty s) = getProjs ((n, ty) : acc) s
150+ getProjs acc r = reverse acc
151+
152+ getFieldNames (PPi (Exp _ _ _) n _ s) = n : getFieldNames s
153+ getFieldNames (PPi _ _ _ s) = getFieldNames s
154+ getFieldNames _ = []
155+
156+ getRecTy (PPi _ n ty s) = getRecTy s
157+ getRecTy t = t
158+
159+ -- make sure we pick a consistent name for parameters; any name will do
160+ -- otherwise
161+ getRecNameMap x ppos (PApp fc t args)
162+ = mapMaybe toMN (zip [0..] (map getTm args))
163+ where
164+ toMN (i, PRef fc n)
165+ | i `elem` ppos = Just (n, PRef fc (mkp n))
166+ | otherwise = Just (n, PRef fc (sMN 0 (show n ++ x)))
167+ toMN _ = Nothing
168+ getRecNameMap x _ _ = []
169+
170+ rec = sMN 0 "rec"
171+
172+ -- only UNs propagate properly as parameters (bit of a hack then...)
173+ mkp (UN n) = sUN ("_p_" ++ str n)
174+ mkp (MN i n) = sMN i ("p_" ++ str n)
175+ mkp (NS n s) = NS (mkp n) s
176+
177+ mkImp (UN n) = sUN ("implicit_" ++ str n)
178+ mkImp (MN i n) = sMN i ("implicit_" ++ str n)
179+ mkImp (NS n s) = NS (mkImp n) s
180+
181+ mkType (UN n) = sUN ("set_" ++ str n)
182+ mkType (MN i n) = sMN i ("set_" ++ str n)
183+ mkType (NS n s) = NS (mkType n) s
184+
185+ mkProj recty substs cimp ((pn_in, pty), pos)
186+ = do let pn = expandNS syn pn_in -- projection name
187+ -- use pn_in in the indices, consistently, to avoid clash
188+ let pfnTy = PTy emptyDocstring [] defaultSyntax fc [] pn
189+ (PPi expl rec recty
190+ (substMatches substs pty))
191+ let pls = repeat Placeholder
192+ let before = pos
193+ let after = length substs - (pos + 1)
194+ let args = take before pls ++ PRef fc (mkp pn_in) : take after pls
195+ let iargs = map implicitise (zip cimp args)
196+ let lhs = PApp fc (PRef fc pn)
197+ [pexp (PApp fc (PRef fc cn) iargs)]
198+ let rhs = PRef fc (mkp pn_in)
199+ let pclause = PClause fc pn lhs [] rhs []
200+ return [pfnTy, PClauses fc [] pn [pclause]]
201+
202+ implicitise (pa, t) = pa { getTm = t }
203+
204+ -- If the 'pty' we're updating includes anything in 'substs', we're
205+ -- updating the type as well, so use recty', otherwise just use
206+ -- recty
207+ mkUpdate recty inames extras fnames k num ((pn, pty), pos)
208+ = do let setname = expandNS syn $ mkType pn
209+ let valname = sMN 0 "updateval"
210+ let pn_out = sMN 0 (show pn ++ "_out")
211+ let pn_in = sMN 0 (show pn ++ "_in")
212+ let recty_in = substMatches [(pn, PRef fc pn_in)] recty
213+ let recty_out = substMatches [(pn, PRef fc pn_out)] recty
214+ let pt = substMatches inames $
215+ k (implBindUp extras inames (PPi expl pn_out pty
216+ (PPi expl rec recty_in recty_out)))
217+ let pfnTy = PTy emptyDocstring [] defaultSyntax fc [] setname pt
218+-- let pls = map (\x -> PRef fc (sMN x ("field" ++ show x))) [0..num-1]
219+ let inames_imp = map (\ (x,_) -> (x, Placeholder)) inames
220+ let pls = map (\x -> substMatches inames_imp (PRef fc x)) fnames
221+ let lhsArgs = pls
222+ let rhsArgs = take pos pls ++ (PRef fc valname) :
223+ drop (pos + 1) pls
224+ let before = pos
225+ let pclause = PClause fc setname (PApp fc (PRef fc setname)
226+ [pexp (PRef fc valname),
227+ pexp (PApp fc (PRef fc cn)
228+ (map pexp lhsArgs))])
229+ []
230+ (PApp fc (PRef fc cn)
231+ (map pexp rhsArgs)) []
232+ return (pn, pfnTy, PClauses fc [] setname [pclause])
233+
234+ implBindUp [] is t = t
235+ implBindUp ((n, ty):ns) is t
236+ = let n' = case lookup n is of
237+ Just (PRef _ x) -> x
238+ _ -> n in
239+ if n `elem` allNamesIn t
240+ then PPi impl n' ty (implBindUp ns is t)
241+ else implBindUp ns is t
242+
src/Idris/Elab/Type.hsnew file+200
@@ -0,0 +1,200 @@
1+{-# LANGUAGE PatternGuards #-}
2+module Idris.Elab.Type(buildType, elabType, elabType', elabPostulate) where
3+
4+import Idris.AbsSyntax
5+import Idris.ASTUtils
6+import Idris.DSL
7+import Idris.Error
8+import Idris.Delaborate
9+import Idris.Imports
10+import Idris.ElabTerm
11+import Idris.Coverage
12+import Idris.DataOpts
13+import Idris.Providers
14+import Idris.Primitives
15+import Idris.Inliner
16+import Idris.PartialEval
17+import Idris.DeepSeq
18+import Idris.Output (iputStrLn, pshow, iWarn)
19+import IRTS.Lang
20+
21+import Idris.Elab.Utils
22+
23+import Idris.Core.TT
24+import Idris.Core.Elaborate hiding (Tactic(..))
25+import Idris.Core.Evaluate
26+import Idris.Core.Execute
27+import Idris.Core.Typecheck
28+import Idris.Core.CaseTree
29+
30+import Idris.Docstrings
31+
32+import Prelude hiding (id, (.))
33+import Control.Category
34+
35+import Control.Applicative hiding (Const)
36+import Control.DeepSeq
37+import Control.Monad
38+import Control.Monad.State.Strict as State
39+import Data.List
40+import Data.Maybe
41+import Debug.Trace
42+
43+import qualified Data.Map as Map
44+import qualified Data.Set as S
45+import qualified Data.Text as T
46+import Data.Char(isLetter, toLower)
47+import Data.List.Split (splitOn)
48+
49+import Util.Pretty(pretty, text)
50+
51+buildType :: ElabInfo -> SyntaxInfo -> FC -> FnOpts -> Name -> PTerm ->
52+ Idris (Type, PTerm, [(Int, Name)])
53+buildType info syn fc opts n ty' = do
54+ ctxt <- getContext
55+ i <- getIState
56+
57+ logLvl 3 $ show n ++ " pre-type " ++ showTmImpls ty'
58+ ty' <- addUsingConstraints syn fc ty'
59+ ty' <- addUsingImpls syn n fc ty'
60+ let ty = addImpl i ty'
61+
62+ logLvl 3 $ show n ++ " type pre-addimpl " ++ showTmImpls ty'
63+ logLvl 3 $ show n ++ " type " ++ show (using syn) ++ "\n" ++ showTmImpls ty
64+
65+ ((tyT', defer, is), log) <-
66+ tclift $ elaborate ctxt n (TType (UVal 0)) []
67+ (errAt "type of " n (erun fc (build i info ETyDecl [] n ty)))
68+
69+ let tyT = patToImp tyT'
70+
71+ logLvl 3 $ show ty ++ "\nElaborated: " ++ show tyT'
72+
73+ ds <- checkAddDef True False fc defer
74+ -- if the type is not complete, note that we'll need to infer
75+ -- things later (for solving metavariables)
76+ when (not (null ds)) $ addTyInferred n
77+
78+ mapM_ (elabCaseBlock info opts) is
79+ ctxt <- getContext
80+ logLvl 5 $ "Rechecking"
81+ logLvl 6 $ show tyT
82+ logLvl 10 $ "Elaborated to " ++ showEnvDbg [] tyT
83+ (cty, _) <- recheckC fc [] tyT
84+
85+ -- record the implicit and inaccessible arguments
86+ i <- getIState
87+ let (inaccData, impls) = unzip $ getUnboundImplicits i cty ty
88+ let inacc = inaccessibleImps 0 cty inaccData
89+ logLvl 3 $ show n ++ ": inaccessible arguments: " ++ show inacc
90+
91+ putIState $ i { idris_implicits = addDef n impls (idris_implicits i) }
92+ logLvl 3 ("Implicit " ++ show n ++ " " ++ show impls)
93+ addIBC (IBCImp n)
94+
95+ return (cty, ty, inacc)
96+ where
97+ patToImp (Bind n (PVar t) sc) = Bind n (Pi t) (patToImp sc)
98+ patToImp (Bind n b sc) = Bind n b (patToImp sc)
99+ patToImp t = t
100+
101+
102+-- | Elaborate a top-level type declaration - for example, "foo : Int -> Int".
103+elabType :: ElabInfo -> SyntaxInfo -> Docstring -> [(Name, Docstring)] ->
104+ FC -> FnOpts -> Name -> PTerm -> Idris Type
105+elabType = elabType' False
106+
107+elabType' :: Bool -> -- normalise it
108+ ElabInfo -> SyntaxInfo -> Docstring -> [(Name, Docstring)] ->
109+ FC -> FnOpts -> Name -> PTerm -> Idris Type
110+elabType' norm info syn doc argDocs fc opts n ty' = {- let ty' = piBind (params info) ty_in
111+ n = liftname info n_in in -}
112+ do checkUndefined fc n
113+ (cty, ty, inacc) <- buildType info syn fc opts n ty'
114+
115+ addStatics n cty ty
116+ let nty = cty -- normalise ctxt [] cty
117+ -- if the return type is something coinductive, freeze the definition
118+ ctxt <- getContext
119+ let nty' = normalise ctxt [] nty
120+ logLvl 2 $ "Rechecked to " ++ show nty'
121+
122+ -- Add normalised type to internals
123+ i <- getIState
124+ rep <- useREPL
125+ when rep $ do
126+ addInternalApp (fc_fname fc) (fst . fc_start $ fc) ty' -- (mergeTy ty' (delab i nty')) -- TODO: Should use span instead of line and filename?
127+ addIBC (IBCLineApp (fc_fname fc) (fst . fc_start $ fc) ty') -- (mergeTy ty' (delab i nty')))
128+
129+ let (t, _) = unApply (getRetTy nty')
130+ let corec = case t of
131+ P _ rcty _ -> case lookupCtxt rcty (idris_datatypes i) of
132+ [TI _ True _ _ _] -> True
133+ _ -> False
134+ _ -> False
135+ -- Productivity checking now via checking for guarded 'Delay'
136+ let opts' = opts -- if corec then (Coinductive : opts) else opts
137+ let usety = if norm then nty' else nty
138+ ds <- checkDef fc [(n, (-1, Nothing, usety))]
139+ addIBC (IBCDef n)
140+ let ds' = map (\(n, (i, top, t)) -> (n, (i, top, t, True))) ds
141+ addDeferred ds'
142+ setFlags n opts'
143+ checkDocs fc argDocs ty
144+ addDocStr n doc argDocs
145+ addIBC (IBCDoc n)
146+ addIBC (IBCFlags n opts')
147+ fputState (opt_inaccessible . ist_optimisation n) inacc
148+ addIBC (IBCOpt n)
149+ when (Implicit `elem` opts') $ do addCoercion n
150+ addIBC (IBCCoercion n)
151+
152+ -- If the function is declared as an error handler and the language
153+ -- extension is enabled, then add it to the list of error handlers.
154+ errorReflection <- fmap (elem ErrorReflection . idris_language_extensions) getIState
155+ when (ErrorHandler `elem` opts) $ do
156+ if errorReflection
157+ then
158+ -- TODO: Check that the declared type is the correct type for an error handler:
159+ -- handler : List (TTName, TT) -> Err -> ErrorReport - for now no ctxt
160+ if tyIsHandler nty'
161+ then do i <- getIState
162+ putIState $ i { idris_errorhandlers = idris_errorhandlers i ++ [n] }
163+ addIBC (IBCErrorHandler n)
164+ else ifail $ "The type " ++ show nty' ++ " is invalid for an error handler"
165+ else ifail "Error handlers can only be defined when the ErrorReflection language extension is enabled."
166+ return usety
167+ where
168+ -- for making an internalapp, we only want the explicit ones, and don't
169+ -- want the parameters, so just take the arguments which correspond to the
170+ -- user declared explicit ones
171+ mergeTy (PPi e n ty sc) (PPi e' n' _ sc')
172+ | e == e' = PPi e n ty (mergeTy sc sc')
173+ | otherwise = mergeTy sc sc'
174+ mergeTy _ sc = sc
175+
176+ err = txt "Err"
177+ maybe = txt "Maybe"
178+ lst = txt "List"
179+ errrep = txt "ErrorReportPart"
180+
181+ tyIsHandler (Bind _ (Pi (P _ (NS (UN e) ns1) _))
182+ (App (P _ (NS (UN m) ns2) _)
183+ (App (P _ (NS (UN l) ns3) _)
184+ (P _ (NS (UN r) ns4) _))))
185+ | e == err && m == maybe && l == lst && r == errrep
186+ , ns1 == map txt ["Errors","Reflection","Language"]
187+ , ns2 == map txt ["Maybe", "Prelude"]
188+ , ns3 == map txt ["List", "Prelude"]
189+ , ns4 == map txt ["Reflection","Language"] = True
190+ tyIsHandler _ = False
191+
192+elabPostulate :: ElabInfo -> SyntaxInfo -> Docstring ->
193+ FC -> FnOpts -> Name -> PTerm -> Idris ()
194+elabPostulate info syn doc fc opts n ty = do
195+ elabType info syn doc [] fc opts n ty
196+ putIState . (\ist -> ist{ idris_postulates = S.insert n (idris_postulates ist) }) =<< getIState
197+ addIBC (IBCPostulate n)
198+
199+ -- remove it from the deferred definitions list
200+ solveDeferred n
src/Idris/Elab/Utils.hsnew file+151
@@ -0,0 +1,151 @@
1+module Idris.Elab.Utils where
2+
3+import Idris.AbsSyntax
4+import Idris.Error
5+import Idris.DeepSeq
6+import Idris.Delaborate
7+import Idris.Docstrings
8+
9+import Idris.Core.TT
10+import Idris.Core.Elaborate hiding (Tactic(..))
11+import Idris.Core.Evaluate
12+import Idris.Core.Typecheck
13+
14+import Control.Applicative hiding (Const)
15+import Control.Monad
16+import Data.List
17+
18+import Debug.Trace
19+
20+import qualified Data.Map as Map
21+
22+recheckC fc env t
23+ = do -- t' <- applyOpts (forget t) (doesn't work, or speed things up...)
24+ ctxt <- getContext
25+ (tm, ty, cs) <- tclift $ case recheck ctxt env (forget t) t of
26+ Error e -> tfail (At fc e)
27+ OK x -> return x
28+ addConstraints fc cs
29+ return (tm, ty)
30+
31+
32+checkDef fc ns = checkAddDef False True fc ns
33+
34+checkAddDef add toplvl fc [] = return []
35+checkAddDef add toplvl fc ((n, (i, top, t)) : ns)
36+ = do ctxt <- getContext
37+ (t', _) <- recheckC fc [] t
38+ when add $ do addDeferred [(n, (i, top, t, toplvl))]
39+ addIBC (IBCDef n)
40+ ns' <- checkAddDef add toplvl fc ns
41+ return ((n, (i, top, t')) : ns')
42+
43+-- Get the list of (index, name) of inaccessible arguments from an elaborated
44+-- type
45+inaccessibleImps :: Int -> Type -> [Bool] -> [(Int, Name)]
46+inaccessibleImps i (Bind n (Pi t) sc) (inacc : ins)
47+ | inacc = (i, n) : inaccessibleImps (i + 1) sc ins
48+ | otherwise = inaccessibleImps (i + 1) sc ins
49+inaccessibleImps _ _ _ = []
50+
51+-- Get the list of (index, name) of inaccessible arguments from the type.
52+inaccessibleArgs :: Int -> PTerm -> [(Int, Name)]
53+inaccessibleArgs i (PPi (Imp _ _ _) n Placeholder t)
54+ = (i,n) : inaccessibleArgs (i+1) t -- unbound implicit
55+inaccessibleArgs i (PPi plicity n ty t)
56+ | InaccessibleArg `elem` pargopts plicity
57+ = (i,n) : inaccessibleArgs (i+1) t -- an .{erased : Implicit}
58+ | otherwise
59+ = inaccessibleArgs (i+1) t -- a {regular : Implicit}
60+inaccessibleArgs _ _ = []
61+
62+elabCaseBlock :: ElabInfo -> FnOpts -> PDecl -> Idris ()
63+elabCaseBlock info opts d@(PClauses f o n ps)
64+ = do addIBC (IBCDef n)
65+ logLvl 5 $ "CASE BLOCK: " ++ show (n, d)
66+ let opts' = nub (o ++ opts)
67+ -- propagate totality assertion to the new definitions
68+ when (AssertTotal `elem` opts) $ setFlags n [AssertTotal]
69+ rec_elabDecl info EAll info (PClauses f opts' n ps )
70+
71+-- Check that the result of type checking matches what the programmer wrote
72+-- (i.e. - if we inferred any arguments that the user provided, make sure
73+-- they are the same!)
74+
75+checkInferred :: FC -> PTerm -> PTerm -> Idris ()
76+checkInferred fc inf user =
77+ do logLvl 6 $ "Checked to\n" ++ showTmImpls inf ++ "\n\nFROM\n\n" ++
78+ showTmImpls user
79+ logLvl 10 $ "Checking match"
80+ i <- getIState
81+ tclift $ case matchClause' True i user inf of
82+ _ -> return ()
83+-- Left (x, y) -> tfail $ At fc
84+-- (Msg $ "The type-checked term and given term do not match: "
85+-- ++ show x ++ " and " ++ show y)
86+ logLvl 10 $ "Checked match"
87+-- ++ "\n" ++ showImp True inf ++ "\n" ++ showImp True user)
88+
89+-- Return whether inferred term is different from given term
90+-- (as above, but return a Bool)
91+
92+inferredDiff :: FC -> PTerm -> PTerm -> Idris Bool
93+inferredDiff fc inf user =
94+ do i <- getIState
95+ logLvl 6 $ "Checked to\n" ++ showTmImpls inf ++ "\n" ++
96+ showTmImpls user
97+ tclift $ case matchClause' True i user inf of
98+ Right vs -> return False
99+ Left (x, y) -> return True
100+
101+-- | Check a PTerm against documentation and ensure that every documented
102+-- argument actually exists. This must be run _after_ implicits have been
103+-- found, or it will give spurious errors.
104+checkDocs :: FC -> [(Name, Docstring)] -> PTerm -> Idris ()
105+checkDocs fc args tm = cd (Map.fromList args) tm
106+ where cd as (PPi _ n _ sc) = cd (Map.delete n as) sc
107+ cd as _ | Map.null as = return ()
108+ | otherwise = ierror . At fc . Msg $
109+ "There is documentation for argument(s) "
110+ ++ (concat . intersperse ", " . map show . Map.keys) as
111+ ++ " but they were not found."
112+
113+decorateid decorate (PTy doc argdocs s f o n t) = PTy doc argdocs s f o (decorate n) t
114+decorateid decorate (PClauses f o n cs)
115+ = PClauses f o (decorate n) (map dc cs)
116+ where dc (PClause fc n t as w ds) = PClause fc (decorate n) (dappname t) as w ds
117+ dc (PWith fc n t as w ds)
118+ = PWith fc (decorate n) (dappname t) as w
119+ (map (decorateid decorate) ds)
120+ dappname (PApp fc (PRef fc' n) as) = PApp fc (PRef fc' (decorate n)) as
121+ dappname t = t
122+
123+
124+-- if 't' is a type class application, assume its arguments are injective
125+pbinds :: IState -> Term -> ElabD ()
126+pbinds i (Bind n (PVar t) sc)
127+ = do attack; patbind n
128+ case unApply t of
129+ (P _ c _, args) -> case lookupCtxt c (idris_classes i) of
130+ [] -> return ()
131+ _ -> -- type class, set as injective
132+ mapM_ setinjArg args
133+ _ -> return ()
134+ pbinds i sc
135+ where setinjArg (P _ n _) = setinj n
136+ setinjArg _ = return ()
137+pbinds i tm = return ()
138+
139+pbty (Bind n (PVar t) sc) tm = Bind n (PVTy t) (pbty sc tm)
140+pbty _ tm = tm
141+
142+getPBtys (Bind n (PVar t) sc) = (n, t) : getPBtys sc
143+getPBtys (Bind n (PVTy t) sc) = (n, t) : getPBtys sc
144+getPBtys _ = []
145+
146+psolve (Bind n (PVar t) sc) = do solve; psolve sc
147+psolve tm = return ()
148+
149+pvars ist (Bind n (PVar t) sc) = (n, delab ist t) : pvars ist sc
150+pvars ist _ = []
151+
src/Idris/Elab/Value.hsnew file+88
@@ -0,0 +1,88 @@
1+{-# LANGUAGE PatternGuards #-}
2+module Idris.Elab.Value(elabVal, elabValBind) where
3+
4+import Idris.AbsSyntax
5+import Idris.ASTUtils
6+import Idris.DSL
7+import Idris.Error
8+import Idris.Delaborate
9+import Idris.Imports
10+import Idris.ElabTerm
11+import Idris.Coverage
12+import Idris.DataOpts
13+import Idris.Providers
14+import Idris.Primitives
15+import Idris.Inliner
16+import Idris.PartialEval
17+import Idris.DeepSeq
18+import Idris.Output (iputStrLn, pshow, iWarn)
19+import IRTS.Lang
20+
21+import Idris.Elab.Utils
22+
23+import Idris.Core.TT
24+import Idris.Core.Elaborate hiding (Tactic(..))
25+import Idris.Core.Evaluate
26+import Idris.Core.Execute
27+import Idris.Core.Typecheck
28+import Idris.Core.CaseTree
29+
30+import Idris.Docstrings
31+
32+import Prelude hiding (id, (.))
33+import Control.Category
34+
35+import Control.Applicative hiding (Const)
36+import Control.DeepSeq
37+import Control.Monad
38+import Control.Monad.State.Strict as State
39+import Data.List
40+import Data.Maybe
41+import Debug.Trace
42+
43+import qualified Data.Map as Map
44+import qualified Data.Set as S
45+import qualified Data.Text as T
46+import Data.Char(isLetter, toLower)
47+import Data.List.Split (splitOn)
48+
49+import Util.Pretty(pretty, text)
50+
51+-- Elaborate a value, returning any new bindings created (this will only
52+-- happen if elaborating as a pattern clause)
53+elabValBind :: ElabInfo -> ElabMode -> Bool -> PTerm -> Idris (Term, Type, [(Name, Type)])
54+elabValBind info aspat norm tm_in
55+ = do ctxt <- getContext
56+ i <- getIState
57+ let tm = addImpl i tm_in
58+ logLvl 10 (showTmImpls tm)
59+ -- try:
60+ -- * ordinary elaboration
61+ -- * elaboration as a Type
62+ -- * elaboration as a function a -> b
63+
64+ ((tm', defer, is), _) <-
65+ tclift (elaborate ctxt (sMN 0 "val") infP []
66+ (build i info aspat [Reflection] (sMN 0 "val") (infTerm tm)))
67+ let vtm = orderPats (getInferTerm tm')
68+
69+ def' <- checkDef (fileFC "(input)") defer
70+ let def'' = map (\(n, (i, top, t)) -> (n, (i, top, t, True))) def'
71+ addDeferred def''
72+ mapM_ (elabCaseBlock info []) is
73+
74+ logLvl 3 ("Value: " ++ show vtm)
75+ (vtm_in, vty) <- recheckC (fileFC "(input)") [] vtm
76+
77+ let vtm = if norm then normalise (tt_ctxt i) [] vtm_in
78+ else vtm_in
79+ let bargs = getPBtys vtm
80+
81+ return (vtm, vty, bargs)
82+
83+elabVal :: ElabInfo -> ElabMode -> PTerm -> Idris (Term, Type)
84+elabVal info aspat tm_in
85+ = do (tm, ty, _) <- elabValBind info aspat False tm_in
86+ return (tm, ty)
87+
88+
src/Idris/ElabDecls.hs+17−2252
@@ -20,6 +20,16 @@ import Idris.DeepSeq
20import Idris.Output (iputStrLn, pshow, iWarn)
20import Idris.Output (iputStrLn, pshow, iWarn)
21import IRTS.Lang
21import IRTS.Lang
22
22
23+import Idris.Elab.Utils
24+import Idris.Elab.Type
25+import Idris.Elab.Clause
26+import Idris.Elab.Data
27+import Idris.Elab.Record
28+import Idris.Elab.Class
29+import Idris.Elab.Instance
30+import Idris.Elab.Provider
31+import Idris.Elab.Value
32+
23import Idris.Core.TT
33import Idris.Core.TT
24import Idris.Core.Elaborate hiding (Tactic(..))
34import Idris.Core.Elaborate hiding (Tactic(..))
25import Idris.Core.Evaluate
35import Idris.Core.Evaluate
@@ -48,638 +58,14 @@ import Data.List.Split (splitOn)
48
58
49import Util.Pretty(pretty, text)
59import Util.Pretty(pretty, text)
50
60
51−recheckC fc env t
52− = do -- t' <- applyOpts (forget t) (doesn't work, or speed things up...)
53− ctxt <- getContext
54− (tm, ty, cs) <- tclift $ case recheck ctxt env (forget t) t of
55− Error e -> tfail (At fc e)
56− OK x -> return x
57− addConstraints fc cs
58− return (tm, ty)
59−
60−
61−checkDef fc ns = checkAddDef False True fc ns
62−
63−checkAddDef add toplvl fc [] = return []
64−checkAddDef add toplvl fc ((n, (i, top, t)) : ns)
65− = do ctxt <- getContext
66− (t', _) <- recheckC fc [] t
67− when add $ do addDeferred [(n, (i, top, t, toplvl))]
68− addIBC (IBCDef n)
69− ns' <- checkAddDef add toplvl fc ns
70− return ((n, (i, top, t')) : ns')
71−-- mapM (\(n, (i, top, t)) -> do (t', _) <- recheckC fc [] t
72−-- return (n, (i, top, t'))) ns
73−
74−buildType :: ElabInfo -> SyntaxInfo -> FC -> FnOpts -> Name -> PTerm ->
75− Idris (Type, PTerm, [(Int, Name)])
76−buildType info syn fc opts n ty' = do
77− ctxt <- getContext
78− i <- getIState
79−
80− logLvl 3 $ show n ++ " pre-type " ++ showTmImpls ty'
81− ty' <- addUsingConstraints syn fc ty'
82− ty' <- addUsingImpls syn n fc ty'
83− let ty = addImpl i ty'
84−
85− logLvl 3 $ show n ++ " type pre-addimpl " ++ showTmImpls ty'
86− logLvl 3 $ show n ++ " type " ++ show (using syn) ++ "\n" ++ showTmImpls ty
87−
88− ((tyT', defer, is), log) <-
89− tclift $ elaborate ctxt n (TType (UVal 0)) []
90− (errAt "type of " n (erun fc (build i info ETyDecl [] n ty)))
91−
92− let tyT = patToImp tyT'
93−
94− logLvl 3 $ show ty ++ "\nElaborated: " ++ show tyT'
95−
96− ds <- checkAddDef True False fc defer
97− -- if the type is not complete, note that we'll need to infer
98− -- things later (for solving metavariables)
99− when (not (null ds)) $ addTyInferred n
100−
101− mapM_ (elabCaseBlock info opts) is
102− ctxt <- getContext
103− logLvl 5 $ "Rechecking"
104− logLvl 6 $ show tyT
105− logLvl 10 $ "Elaborated to " ++ showEnvDbg [] tyT
106− (cty, _) <- recheckC fc [] tyT
107−
108− -- record the implicit and inaccessible arguments
109− i <- getIState
110− let (inaccData, impls) = unzip $ getUnboundImplicits i cty ty
111− let inacc = inaccessibleImps 0 cty inaccData
112− logLvl 3 $ show n ++ ": inaccessible arguments: " ++ show inacc
113−
114− putIState $ i { idris_implicits = addDef n impls (idris_implicits i) }
115− logLvl 3 ("Implicit " ++ show n ++ " " ++ show impls)
116− addIBC (IBCImp n)
117−
118− return (cty, ty, inacc)
119− where
120− patToImp (Bind n (PVar t) sc) = Bind n (Pi t) (patToImp sc)
121− patToImp (Bind n b sc) = Bind n b (patToImp sc)
122− patToImp t = t
123−
124−
125−-- | Elaborate a top-level type declaration - for example, "foo : Int -> Int".
126−elabType :: ElabInfo -> SyntaxInfo -> Docstring -> [(Name, Docstring)] ->
127− FC -> FnOpts -> Name -> PTerm -> Idris Type
128−elabType = elabType' False
129−
130−elabType' :: Bool -> -- normalise it
131− ElabInfo -> SyntaxInfo -> Docstring -> [(Name, Docstring)] ->
132− FC -> FnOpts -> Name -> PTerm -> Idris Type
133−elabType' norm info syn doc argDocs fc opts n ty' = {- let ty' = piBind (params info) ty_in
134− n = liftname info n_in in -}
135− do checkUndefined fc n
136− (cty, ty, inacc) <- buildType info syn fc opts n ty'
137−
138− addStatics n cty ty
139− let nty = cty -- normalise ctxt [] cty
140− -- if the return type is something coinductive, freeze the definition
141− ctxt <- getContext
142− let nty' = normalise ctxt [] nty
143− logLvl 2 $ "Rechecked to " ++ show nty'
144−
145− -- Add normalised type to internals
146− i <- getIState
147− rep <- useREPL
148− when rep $ do
149− addInternalApp (fc_fname fc) (fst . fc_start $ fc) ty' -- (mergeTy ty' (delab i nty')) -- TODO: Should use span instead of line and filename?
150− addIBC (IBCLineApp (fc_fname fc) (fst . fc_start $ fc) ty') -- (mergeTy ty' (delab i nty')))
151−
152− let (t, _) = unApply (getRetTy nty')
153− let corec = case t of
154− P _ rcty _ -> case lookupCtxt rcty (idris_datatypes i) of
155− [TI _ True _ _ _] -> True
156− _ -> False
157− _ -> False
158− -- Productivity checking now via checking for guarded 'Delay'
159− let opts' = opts -- if corec then (Coinductive : opts) else opts
160− let usety = if norm then nty' else nty
161− ds <- checkDef fc [(n, (-1, Nothing, usety))]
162− addIBC (IBCDef n)
163− let ds' = map (\(n, (i, top, t)) -> (n, (i, top, t, True))) ds
164− addDeferred ds'
165− setFlags n opts'
166− checkDocs fc argDocs ty
167− addDocStr n doc argDocs
168− addIBC (IBCDoc n)
169− addIBC (IBCFlags n opts')
170− fputState (opt_inaccessible . ist_optimisation n) inacc
171− addIBC (IBCOpt n)
172− when (Implicit `elem` opts') $ do addCoercion n
173− addIBC (IBCCoercion n)
174−
175− -- If the function is declared as an error handler and the language
176− -- extension is enabled, then add it to the list of error handlers.
177− errorReflection <- fmap (elem ErrorReflection . idris_language_extensions) getIState
178− when (ErrorHandler `elem` opts) $ do
179− if errorReflection
180− then
181− -- TODO: Check that the declared type is the correct type for an error handler:
182− -- handler : List (TTName, TT) -> Err -> ErrorReport - for now no ctxt
183− if tyIsHandler nty'
184− then do i <- getIState
185− putIState $ i { idris_errorhandlers = idris_errorhandlers i ++ [n] }
186− addIBC (IBCErrorHandler n)
187− else ifail $ "The type " ++ show nty' ++ " is invalid for an error handler"
188− else ifail "Error handlers can only be defined when the ErrorReflection language extension is enabled."
189− return usety
190− where
191− -- for making an internalapp, we only want the explicit ones, and don't
192− -- want the parameters, so just take the arguments which correspond to the
193− -- user declared explicit ones
194− mergeTy (PPi e n ty sc) (PPi e' n' _ sc')
195− | e == e' = PPi e n ty (mergeTy sc sc')
196− | otherwise = mergeTy sc sc'
197− mergeTy _ sc = sc
198−
199− err = txt "Err"
200− maybe = txt "Maybe"
201− lst = txt "List"
202− errrep = txt "ErrorReportPart"
203−
204− tyIsHandler (Bind _ (Pi (P _ (NS (UN e) ns1) _))
205− (App (P _ (NS (UN m) ns2) _)
206− (App (P _ (NS (UN l) ns3) _)
207− (P _ (NS (UN r) ns4) _))))
208− | e == err && m == maybe && l == lst && r == errrep
209− , ns1 == map txt ["Errors","Reflection","Language"]
210− , ns2 == map txt ["Maybe", "Prelude"]
211− , ns3 == map txt ["List", "Prelude"]
212− , ns4 == map txt ["Reflection","Language"] = True
213− tyIsHandler _ = False
214−
215−-- Get the list of (index, name) of inaccessible arguments from an elaborated
216−-- type
217−inaccessibleImps :: Int -> Type -> [Bool] -> [(Int, Name)]
218−inaccessibleImps i (Bind n (Pi t) sc) (inacc : ins)
219− | inacc = (i, n) : inaccessibleImps (i + 1) sc ins
220− | otherwise = inaccessibleImps (i + 1) sc ins
221−inaccessibleImps _ _ _ = []
222−
223−-- Get the list of (index, name) of inaccessible arguments from the type.
224−inaccessibleArgs :: Int -> PTerm -> [(Int, Name)]
225−inaccessibleArgs i (PPi (Imp _ _ _) n Placeholder t)
226− = (i,n) : inaccessibleArgs (i+1) t -- unbound implicit
227−inaccessibleArgs i (PPi plicity n ty t)
228− | InaccessibleArg `elem` pargopts plicity
229− = (i,n) : inaccessibleArgs (i+1) t -- an .{erased : Implicit}
230− | otherwise
231− = inaccessibleArgs (i+1) t -- a {regular : Implicit}
232−inaccessibleArgs _ _ = []
233−
234−elabPostulate :: ElabInfo -> SyntaxInfo -> Docstring ->
235− FC -> FnOpts -> Name -> PTerm -> Idris ()
236−elabPostulate info syn doc fc opts n ty = do
237− elabType info syn doc [] fc opts n ty
238− putIState . (\ist -> ist{ idris_postulates = S.insert n (idris_postulates ist) }) =<< getIState
239− addIBC (IBCPostulate n)
240−
241− -- remove it from the deferred definitions list
242− solveDeferred n
243−
244−elabData :: ElabInfo -> SyntaxInfo -> Docstring -> [(Name, Docstring)] -> FC -> DataOpts -> PData -> Idris ()
245−elabData info syn doc argDocs fc opts (PLaterdecl n t_in)
246− = do let codata = Codata `elem` opts
247− iLOG (show (fc, doc))
248− checkUndefined fc n
249− (cty, t, inacc) <- buildType info syn fc [] n t_in
250−
251− addIBC (IBCDef n)
252− updateContext (addTyDecl n (TCon 0 0) cty) -- temporary, to check cons
253−
254−elabData info syn doc argDocs fc opts (PDatadecl n t_in dcons)
255− = do let codata = Codata `elem` opts
256− iLOG (show fc)
257− undef <- isUndefined fc n
258− (cty, t, inacc) <- buildType info syn fc [] n t_in
259− -- if n is defined already, make sure it is just a type declaration
260− -- with the same type we've just elaborated
261− i <- getIState
262− checkDefinedAs fc n cty (tt_ctxt i)
263− -- temporary, to check cons
264− when undef $ updateContext (addTyDecl n (TCon 0 0) cty)
265− let cnameinfo = cinfo info (map cname dcons)
266− cons <- mapM (elabCon cnameinfo syn n codata) dcons
267− ttag <- getName
268− i <- getIState
269− let as = map (const Nothing) (getArgTys cty)
270− let params = findParams (map snd cons)
271− logLvl 2 $ "Parameters : " ++ show params
272− -- TI contains information about mutually declared types - this will
273− -- be updated when the mutual block is complete
274− putIState (i { idris_datatypes =
275− addDef n (TI (map fst cons) codata opts params [n])
276− (idris_datatypes i) })
277− addIBC (IBCDef n)
278− addIBC (IBCData n)
279− checkDocs fc argDocs t
280− addDocStr n doc argDocs
281− addIBC (IBCDoc n)
282− let metainf = DataMI params
283− addIBC (IBCMetaInformation n metainf)
284− -- TMP HACK! Make this a data option
285− updateContext (addDatatype (Data n ttag cty cons))
286− updateContext (setMetaInformation n metainf)
287− mapM_ totcheck (zip (repeat fc) (map fst cons))
288−-- mapM_ (checkPositive n) cons
289−
290− -- if there's exactly one constructor,
291− -- mark both the type and the constructor as detaggable
292− case cons of
293− [(cn,ct)] -> setDetaggable cn >> setDetaggable n
294− >> addIBC (IBCOpt cn) >> addIBC (IBCOpt n)
295− _ -> return ()
296−
297− -- create an eliminator
298− when (DefaultEliminator `elem` opts) $
299− evalStateT (elabCaseFun True params n t dcons info) Map.empty
300− -- create a case function
301− when (DefaultCaseFun `elem` opts) $
302− evalStateT (elabCaseFun False params n t dcons info) Map.empty
303− where
304− setDetaggable :: Name -> Idris ()
305− setDetaggable n = do
306− ist <- getIState
307− let opt = idris_optimisation ist
308− case lookupCtxt n opt of
309− [oi] -> putIState ist{ idris_optimisation = addDef n oi{ detaggable = True } opt }
310− _ -> putIState ist{ idris_optimisation = addDef n (Optimise [] True) opt }
311−
312− checkDefinedAs fc n t ctxt
313− = case lookupDef n ctxt of
314− [] -> return ()
315− [TyDecl _ ty] ->
316− case converts ctxt [] t ty of
317− OK () -> return ()
318− _ -> tclift $ tfail (At fc (AlreadyDefined n))
319− _ -> tclift $ tfail (At fc (AlreadyDefined n))
320− -- parameters are names which are unchanged across the structure,
321− -- which appear exactly once in the return type of a constructor
322−
323− -- First, find all applications of the constructor, then check over
324− -- them for repeated arguments
325−
326− findParams :: [Type] -> [Int]
327− findParams ts = let allapps = concatMap getDataApp ts in
328− paramPos allapps
329−
330− paramPos [] = []
331− paramPos (args : rest)
332− = dropNothing $ keepSame (zip [0..] args) rest
333−
334− dropNothing [] = []
335− dropNothing ((x, Nothing) : ts) = dropNothing ts
336− dropNothing ((x, _) : ts) = x : dropNothing ts
337−
338− keepSame :: [(Int, Maybe Name)] -> [[Maybe Name]] ->
339− [(Int, Maybe Name)]
340− keepSame as [] = as
341− keepSame as (args : rest) = keepSame (update as args) rest
342− where
343− update [] _ = []
344− update _ [] = []
345− update ((n, Just x) : as) (Just x' : args)
346− | x == x' = (n, Just x) : update as args
347− update ((n, _) : as) (_ : args) = (n, Nothing) : update as args
348−
349− getDataApp :: Type -> [[Maybe Name]]
350− getDataApp f@(App _ _)
351− | (P _ d _, args) <- unApply f
352− = if (d == n) then [mParam args args] else []
353− getDataApp (Bind n (Pi t) sc)
354− = getDataApp t ++ getDataApp (instantiate (P Bound n t) sc)
355− getDataApp _ = []
356−
357− -- keep the arguments which are single names, which don't appear
358− -- elsewhere
359−
360− mParam args [] = []
361− mParam args (P Bound n _ : rest)
362− | count n args == 1
363− = Just n : mParam args rest
364− where count n [] = 0
365− count n (t : ts)
366− | n `elem` freeNames t = 1 + count n ts
367− | otherwise = count n ts
368− mParam args (_ : rest) = Nothing : mParam args rest
369−
370− cname (_, _, n, _, _, _) = n
371−
372− -- Abuse of ElabInfo.
373− -- TODO Contemplate whether the ElabInfo type needs modification.
374− cinfo :: ElabInfo -> [Name] -> ElabInfo
375− cinfo info ds
376− = let newps = params info
377− dsParams = map (\n -> (n, [])) ds
378− newb = addAlist dsParams (inblock info)
379− l = liftname info in
380− info { params = newps,
381− inblock = newb,
382− liftname = id -- Is this appropriate?
383− }
384−
385−-- FIXME: 'forcenames' is an almighty hack! Need a better way of
386−-- erasing non-forceable things
387−-- ^^^
388−-- TODO: the above is a comment from the past;
389−-- forcenames is probably no longer needed
390−elabCon :: ElabInfo -> SyntaxInfo -> Name -> Bool ->
391− (Docstring, [(Name, Docstring)], Name, PTerm, FC, [Name]) -> Idris (Name, Type)
392−elabCon info syn tn codata (doc, argDocs, n, t_in, fc, forcenames)
393− = do checkUndefined fc n
394− (cty, t, inacc) <- buildType info syn fc [] n (if codata then mkLazy t_in else t_in)
395− ctxt <- getContext
396− let cty' = normalise ctxt [] cty
397−
398− logLvl 2 $ show fc ++ ":Constructor " ++ show n ++ " : " ++ show t
399− logLvl 5 $ "Inaccessible args: " ++ show inacc
400− logLvl 2 $ "---> " ++ show n ++ " : " ++ show cty'
401−
402− addIBC (IBCDef n)
403− checkDocs fc argDocs t
404− addDocStr n doc argDocs
405− addIBC (IBCDoc n)
406− fputState (opt_inaccessible . ist_optimisation n) inacc
407− addIBC (IBCOpt n)
408− return (n, cty')
409− where
410− tyIs (Bind n b sc) = tyIs sc
411− tyIs t | (P _ n' _, _) <- unApply t
412− = if n' /= tn then tclift $ tfail (At fc (Msg (show n' ++ " is not " ++ show tn)))
413− else return ()
414− tyIs t = tclift $ tfail (At fc (Msg (show t ++ " is not " ++ show tn)))
415−
416− mkLazy (PPi pl n ty sc)
417− = let ty' = if getTyName ty
418− then PApp fc (PRef fc (sUN "Lazy'"))
419− [pexp (PRef fc (sUN "LazyCodata")),
420− pexp ty]
421− else ty in
422− PPi pl n ty' (mkLazy sc)
423− mkLazy t = t
424−
425− getTyName (PApp _ (PRef _ n) _) = n == nsroot tn
426− getTyName (PRef _ n) = n == nsroot tn
427− getTyName _ = False
428−
429−
430− getNamePos :: Int -> PTerm -> Name -> Maybe Int
431− getNamePos i (PPi _ n _ sc) x | n == x = Just i
432− | otherwise = getNamePos (i + 1) sc x
433− getNamePos _ _ _ = Nothing
434−
435−type EliminatorState = StateT (Map.Map String Int) Idris
436−
437−-- TODO: Rewrite everything to use idris_implicits instead of manual splitting (or in TT)
438−-- FIXME: Many things have name starting with elim internally since this was the only purpose in the first edition of the function
439−-- rename to caseFun to match updated intend
440−elabCaseFun :: Bool -> [Int] -> Name -> PTerm ->
441− [(Docstring, [(Name, Docstring)], Name, PTerm, FC, [Name])] ->
442− ElabInfo -> EliminatorState ()
443−elabCaseFun ind paramPos n ty cons info = do
444− elimLog $ "Elaborating case function"
445− put (Map.fromList $ zip (concatMap (\(_, p, _, ty, _, _) -> (map show $ boundNamesIn ty) ++ map (show . fst) p) cons ++ (map show $ boundNamesIn ty)) (repeat 0))
446− let (cnstrs, _) = splitPi ty
447− let (splittedTy@(pms, idxs)) = splitPms cnstrs
448− generalParams <- namePis False pms
449− motiveIdxs <- namePis False idxs
450− let motive = mkMotive n paramPos generalParams motiveIdxs
451− consTerms <- mapM (\(c@(_, _, cnm, _, _, _)) -> do
452− let casefunt = if ind then "elim_" else "case_"
453− name <- freshName $ casefunt ++ simpleName cnm
454− consTerm <- extractConsTerm c generalParams
455− return (name, expl, consTerm)) cons
456− scrutineeIdxs <- namePis False idxs
457− let motiveConstr = [(motiveName, expl, motive)]
458− let scrutinee = (scrutineeName, expl, applyCons n (interlievePos paramPos generalParams scrutineeIdxs 0))
459− let eliminatorTy = piConstr (generalParams ++ motiveConstr ++ consTerms ++ scrutineeIdxs ++ [scrutinee]) (applyMotive (map (\(n,_,_) -> PRef elimFC n) scrutineeIdxs) (PRef elimFC scrutineeName))
460− let eliminatorTyDecl = PTy (parseDocstring . T.pack $ show n) [] defaultSyntax elimFC [TotalFn] elimDeclName eliminatorTy
461− let clauseConsElimArgs = map getPiName consTerms
462− let clauseGeneralArgs' = map getPiName generalParams ++ [motiveName] ++ clauseConsElimArgs
463− let clauseGeneralArgs = map (\arg -> pexp (PRef elimFC arg)) clauseGeneralArgs'
464− let elimSig = "-- case function signature: " ++ showTmImpls eliminatorTy
465− elimLog elimSig
466− eliminatorClauses <- mapM (\(cns, cnsElim) -> generateEliminatorClauses cns cnsElim clauseGeneralArgs generalParams) (zip cons clauseConsElimArgs)
467− let eliminatorDef = PClauses emptyFC [TotalFn] elimDeclName eliminatorClauses
468− elimLog $ "-- case function definition: " ++ (show . showDeclImp verbosePPOption) eliminatorDef
469− State.lift $ idrisCatch (elabDecl EAll info eliminatorTyDecl) (\err -> return ())
470− -- Do not elaborate clauses if there aren't any
471− case eliminatorClauses of
472− [] -> State.lift $ solveDeferred elimDeclName -- Remove meta-variable for type
473− _ -> State.lift $ idrisCatch (elabDecl EAll info eliminatorDef) (\err -> return ())
474− where elimLog :: String -> EliminatorState ()
475− elimLog s = State.lift (logLvl 2 s)
476−
477− elimFC :: FC
478− elimFC = fileFC "(casefun)"
479−
480− elimDeclName :: Name
481− elimDeclName = if ind then SN . ElimN $ n else SN . CaseN $ n
482−
483− applyNS :: Name -> [String] -> Name
484− applyNS n [] = n
485− applyNS n ns = sNS n ns
486−
487− splitPi :: PTerm -> ([(Name, Plicity, PTerm)], PTerm)
488− splitPi = splitPi' []
489− where splitPi' :: [(Name, Plicity, PTerm)] -> PTerm -> ([(Name, Plicity, PTerm)], PTerm)
490− splitPi' acc (PPi pl n tyl tyr) = splitPi' ((n, pl, tyl):acc) tyr
491− splitPi' acc t = (reverse acc, t)
492−
493− splitPms :: [(Name, Plicity, PTerm)] -> ([(Name, Plicity, PTerm)], [(Name, Plicity, PTerm)])
494− splitPms cnstrs = (map fst pms, map fst idxs)
495− where (pms, idxs) = partition (\c -> snd c `elem` paramPos) (zip cnstrs [0..])
496−
497− isMachineGenerated :: Name -> Bool
498− isMachineGenerated (MN _ _) = True
499− isMachineGenerated _ = False
500−
501− namePis :: Bool -> [(Name, Plicity, PTerm)] -> EliminatorState [(Name, Plicity, PTerm)]
502− namePis keepOld pms = do names <- mapM (mkPiName keepOld) pms
503− let oldNames = map fst names
504− let params = map snd names
505− return $ map (\(n, pl, ty) -> (n, pl, removeParamPis oldNames params ty)) params
506−
507− mkPiName :: Bool -> (Name, Plicity, PTerm) -> EliminatorState (Name, (Name, Plicity, PTerm))
508− mkPiName keepOld (n, pl, piarg) | not (isMachineGenerated n) && keepOld = do return (n, (n, pl, piarg))
509− mkPiName _ (oldName, pl, piarg) = do name <- freshName $ keyOf piarg
510− return (oldName, (name, pl, piarg))
511− where keyOf :: PTerm -> String
512− keyOf (PRef _ name) | isLetter (nameStart name) = (toLower $ nameStart name):"__"
513− keyOf (PApp _ tyf _) = keyOf tyf
514− keyOf PType = "ty__"
515− keyOf _ = "carg__"
516− nameStart :: Name -> Char
517− nameStart n = nameStart' (simpleName n)
518− where nameStart' :: String -> Char
519− nameStart' "" = ' '
520− nameStart' ns = head ns
521−
522− simpleName :: Name -> String
523− simpleName (NS n _) = simpleName n
524− simpleName (MN i n) = str n ++ show i
525− simpleName n = show n
526−
527− nameSpaces :: Name -> [String]
528− nameSpaces (NS _ ns) = map str ns
529− nameSpaces _ = []
530−
531− freshName :: String -> EliminatorState Name
532− freshName key = do
533− nameMap <- get
534− let i = fromMaybe 0 (Map.lookup key nameMap)
535− let name = uniqueName (sUN (key ++ show i)) (map (\(nm, nb) -> sUN (nm ++ show nb)) $ Map.toList nameMap)
536− put $ Map.insert key (i+1) nameMap
537− return name
538−
539− scrutineeName :: Name
540− scrutineeName = sUN "scrutinee"
541
61
542− scrutineeArgName :: Name
62+-- Top level elaborator info, supporting recursive elaboration
543− scrutineeArgName = sUN "scrutineeArg"
63+recinfo :: ElabInfo
544−
64+recinfo = EInfo [] emptyContext id Nothing elabDecl'
545− motiveName :: Name
546− motiveName = sUN "prop"
547−
548− mkMotive :: Name -> [Int] -> [(Name, Plicity, PTerm)] -> [(Name, Plicity, PTerm)] -> PTerm
549− mkMotive n paramPos params indicies =
550− let scrutineeTy = (scrutineeArgName, expl, applyCons n (interlievePos paramPos params indicies 0))
551− in piConstr (indicies ++ [scrutineeTy]) PType
552−
553− piConstr :: [(Name, Plicity, PTerm)] -> PTerm -> PTerm
554− piConstr [] ty = ty
555− piConstr ((n, pl, tyb):tyr) ty = PPi pl n tyb (piConstr tyr ty)
556−
557− interlievePos :: [Int] -> [a] -> [a] -> Int -> [a]
558− interlievePos idxs [] l2 i = l2
559− interlievePos idxs l1 [] i = l1
560− interlievePos idxs (x:xs) l2 i | i `elem` idxs = x:(interlievePos idxs xs l2 (i+1))
561− interlievePos idxs l1 (y:ys) i = y:(interlievePos idxs l1 ys (i+1))
562−
563− replaceParams :: [Int] -> [(Name, Plicity, PTerm)] -> PTerm -> PTerm
564− replaceParams paramPos params cns =
565− let (_, cnsResTy) = splitPi cns
566− in case cnsResTy of
567− PApp _ _ args ->
568− let oldParams = paramNamesOf 0 paramPos args
569− in removeParamPis oldParams params cns
570− _ -> cns
571−
572− removeParamPis :: [Name] -> [(Name, Plicity, PTerm)] -> PTerm -> PTerm
573− removeParamPis oldParams params (PPi pl n tyb tyr) =
574− case findIndex (== n) oldParams of
575− Nothing -> (PPi pl n (removeParamPis oldParams params tyb) (removeParamPis oldParams params tyr))
576− Just i -> (removeParamPis oldParams params tyr)
577− removeParamPis oldParams params (PRef _ n) =
578− case findIndex (== n) oldParams of
579− Nothing -> (PRef elimFC n)
580− Just i -> let (newname,_,_) = params !! i in (PRef elimFC (newname))
581− removeParamPis oldParams params (PApp _ cns args) =
582− PApp elimFC (removeParamPis oldParams params cns) $ replaceParamArgs args
583− where replaceParamArgs :: [PArg] -> [PArg]
584− replaceParamArgs [] = []
585− replaceParamArgs (arg:args) =
586− case extractName (getTm arg) of
587− [] -> arg:replaceParamArgs args
588− [n] ->
589− case findIndex (== n) oldParams of
590− Nothing -> arg:replaceParamArgs args
591− Just i -> let (newname,_,_) = params !! i in arg {getTm = PRef elimFC newname}:replaceParamArgs args
592− removeParamPis oldParams params t = t
593−
594− paramNamesOf :: Int -> [Int] -> [PArg] -> [Name]
595− paramNamesOf i paramPos [] = []
596− paramNamesOf i paramPos (arg:args) = (if i `elem` paramPos then extractName (getTm arg) else []) ++ paramNamesOf (i+1) paramPos args
597−
598− extractName :: PTerm -> [Name]
599− extractName (PRef _ n) = [n]
600− extractName _ = []
601−
602− splitArgPms :: PTerm -> ([PTerm], [PTerm])
603− splitArgPms (PApp _ f args) = splitArgPms' args
604− where splitArgPms' :: [PArg] -> ([PTerm], [PTerm])
605− splitArgPms' cnstrs = (map (getTm . fst) pms, map (getTm . fst) idxs)
606− where (pms, idxs) = partition (\c -> snd c `elem` paramPos) (zip cnstrs [0..])
607− splitArgPms _ = ([],[])
608−
609−
610− implicitIndexes :: (Docstring, Name, PTerm, FC, [Name]) -> EliminatorState [(Name, Plicity, PTerm)]
611− implicitIndexes (cns@(doc, cnm, ty, fc, fs)) = do
612− i <- State.lift getIState
613− implargs' <- case lookupCtxt cnm (idris_implicits i) of
614− [] -> do fail $ "Error while showing implicits for " ++ show cnm
615− [args] -> do return args
616− _ -> do fail $ "Ambigous name for " ++ show cnm
617− let implargs = mapMaybe convertImplPi implargs'
618− let (_, cnsResTy) = splitPi ty
619− case cnsResTy of
620− PApp _ _ args ->
621− let oldParams = paramNamesOf 0 paramPos args
622− in return $ filter (\(n,_,_) -> not (n `elem` oldParams))implargs
623− _ -> return implargs
624−
625− extractConsTerm :: (Docstring, [(Name, Docstring)], Name, PTerm, FC, [Name]) -> [(Name, Plicity, PTerm)] -> EliminatorState PTerm
626− extractConsTerm (doc, argDocs, cnm, ty, fc, fs) generalParameters = do
627− let cons' = replaceParams paramPos generalParameters ty
628− let (args, resTy) = splitPi cons'
629− implidxs <- implicitIndexes (doc, cnm, ty, fc, fs)
630− consArgs <- namePis False args
631− let recArgs = findRecArgs consArgs
632− let recMotives = if ind then map applyRecMotive recArgs else []
633− let (_, consIdxs) = splitArgPms resTy
634− return $ piConstr (implidxs ++ consArgs ++ recMotives) (applyMotive consIdxs (applyCons cnm consArgs))
635− where applyRecMotive :: (Name, Plicity, PTerm) -> (Name, Plicity, PTerm)
636− applyRecMotive (n,_,ty) = (sUN $ "ih" ++ simpleName n, expl, applyMotive idxs (PRef elimFC n))
637− where (_, idxs) = splitArgPms ty
638−
639− findRecArgs :: [(Name, Plicity, PTerm)] -> [(Name, Plicity, PTerm)]
640− findRecArgs [] = []
641− findRecArgs (ty@(_,_,PRef _ tn):rs) | simpleName tn == simpleName n = ty:findRecArgs rs
642− findRecArgs (ty@(_,_,PApp _ (PRef _ tn) _):rs) | simpleName tn == simpleName n = ty:findRecArgs rs
643− findRecArgs (ty:rs) = findRecArgs rs
644−
645− applyCons :: Name -> [(Name, Plicity, PTerm)] -> PTerm
646− applyCons tn targs = PApp elimFC (PRef elimFC tn) (map convertArg targs)
647−
648− convertArg :: (Name, Plicity, PTerm) -> PArg
649− convertArg (n, _, _) = pexp (PRef elimFC n)
650−
651− applyMotive :: [PTerm] -> PTerm -> PTerm
652− applyMotive idxs t = PApp elimFC (PRef elimFC motiveName) (map pexp idxs ++ [pexp t])
653−
654− getPiName :: (Name, Plicity, PTerm) -> Name
655− getPiName (name,_,_) = name
656−
657− convertImplPi :: PArg -> Maybe (Name, Plicity, PTerm)
658− convertImplPi (PImp {getTm = t, pname = n}) = Just (n, expl, t)
659− convertImplPi _ = Nothing
660−
661− generateEliminatorClauses :: (Docstring, [(Name, Docstring)], Name, PTerm, FC, [Name]) -> Name -> [PArg] -> [(Name, Plicity, PTerm)] -> EliminatorState PClause
662− generateEliminatorClauses (doc, _, cnm, ty, fc, fs) cnsElim generalArgs generalParameters = do
663− let cons' = replaceParams paramPos generalParameters ty
664− let (args, resTy) = splitPi cons'
665− i <- State.lift getIState
666− implidxs <- implicitIndexes (doc, cnm, ty, fc, fs)
667− let (_, generalIdxs') = splitArgPms resTy
668− let generalIdxs = map pexp generalIdxs'
669− consArgs <- namePis False args
670− let lhsPattern = PApp elimFC (PRef elimFC elimDeclName) (generalArgs ++ generalIdxs ++ [pexp $ applyCons cnm consArgs])
671− let recArgs = findRecArgs consArgs
672− let recElims = if ind then map applyRecElim recArgs else []
673− let rhsExpr = PApp elimFC (PRef elimFC cnsElim) (map convertArg implidxs ++ map convertArg consArgs ++ recElims)
674− return $ PClause elimFC elimDeclName lhsPattern [] rhsExpr []
675− where applyRecElim :: (Name, Plicity, PTerm) -> PArg
676− applyRecElim (constr@(recCnm,_,recTy)) = pexp $ PApp elimFC (PRef elimFC elimDeclName) (generalArgs ++ map pexp idxs ++ [pexp $ PRef elimFC recCnm])
677− where (_, idxs) = splitArgPms recTy
678
65
679-- | Elaborate primitives
66-- | Elaborate primitives
680−
681elabPrims :: Idris ()
67elabPrims :: Idris ()
682−elabPrims = do mapM_ (elabDecl EAll toplevel)
68+elabPrims = do mapM_ (elabDecl' EAll recinfo)
683 (map (\(opt, decl, docs, argdocs) -> PData docs argdocs defaultSyntax (fileFC "builtin") opt decl)
69 (map (\(opt, decl, docs, argdocs) -> PData docs argdocs defaultSyntax (fileFC "builtin") opt decl)
684 (zip4
70 (zip4
685 [inferOpts, unitOpts, falseOpts, pairOpts, eqOpts]
71 [inferOpts, unitOpts, falseOpts, pairOpts, eqOpts]
@@ -687,7 +73,7 @@ elabPrims = do mapM_ (elabDecl EAll toplevel)
687 [emptyDocstring, unitDoc, falseDoc, pairDoc, eqDoc]
73 [emptyDocstring, unitDoc, falseDoc, pairDoc, eqDoc]
688 [[], [], [], pairParamDoc, eqParamDoc]))
74 [[], [], [], pairParamDoc, eqParamDoc]))
689 addNameHint eqTy (sUN "prf")
75 addNameHint eqTy (sUN "prf")
690− elabDecl EAll toplevel elimDecl
76+ elabDecl' EAll recinfo elimDecl
691 mapM_ elabPrim primitives
77 mapM_ elabPrim primitives
692 -- Special case prim__believe_me because it doesn't work on just constants
78 -- Special case prim__believe_me because it doesn't work on just constants
693 elabBelieveMe
79 elabBelieveMe
@@ -748,71 +134,6 @@ elabPrims = do mapM_ (elabDecl EAll toplevel)
748 idris_scprims = (synEq, (4, LNoOp)) : idris_scprims i
134 idris_scprims = (synEq, (4, LNoOp)) : idris_scprims i
749 }
135 }
750
136
751−
752−-- | Elaborate a type provider
753−elabProvider :: ElabInfo -> SyntaxInfo -> FC -> ProvideWhat -> Name -> Idris ()
754−elabProvider info syn fc what n
755− = do i <- getIState
756− -- Ensure that the experimental extension is enabled
757− unless (TypeProviders `elem` idris_language_extensions i) $
758− ifail $ "Failed to define type provider \"" ++ show n ++
759− "\".\nYou must turn on the TypeProviders extension."
760−
761− ctxt <- getContext
762−
763− -- First elaborate the expected type (and check that it's a type)
764− -- The goal type for a postulate is always Type.
765− (ty', typ) <- case what of
766− ProvTerm ty p -> elabVal toplevel ERHS ty
767− ProvPostulate _ -> elabVal toplevel ERHS PType
768− unless (isTType typ) $
769− ifail ("Expected a type, got " ++ show ty' ++ " : " ++ show typ)
770−
771− -- Elaborate the provider term to TT and check that the type matches
772− (e, et) <- case what of
773− ProvTerm _ tm -> elabVal toplevel ERHS tm
774− ProvPostulate tm -> elabVal toplevel ERHS tm
775− unless (isProviderOf (normalise ctxt [] ty') et) $
776− ifail $ "Expected provider type IO (Provider (" ++
777− show ty' ++ "))" ++ ", got " ++ show et ++ " instead."
778−
779− -- Execute the type provider and normalise the result
780− -- use 'run__provider' to convert to a primitive IO action
781−
782− rhs <- execute (mkApp (P Ref (sUN "run__provider") Erased)
783− [Erased, e])
784− let rhs' = normalise ctxt [] rhs
785− logLvl 3 $ "Normalised " ++ show n ++ "'s RHS to " ++ show rhs
786−
787− -- Extract the provided term or postulate from the type provider
788− provided <- getProvided fc rhs'
789−
790− case provided of
791− Provide tm
792− | ProvTerm ty _ <- what ->
793− do -- Finally add a top-level definition of the provided term
794− elabType info syn emptyDocstring [] fc [] n ty
795− elabClauses info fc [] n [PClause fc n (PApp fc (PRef fc n) []) [] (delab i tm) []]
796− logLvl 3 $ "Elaborated provider " ++ show n ++ " as: " ++ show tm
797− | ProvPostulate _ <- what ->
798− do -- Add the postulate
799− elabPostulate info syn (parseDocstring $ T.pack "Provided postulate") fc [] n (delab i tm)
800− logLvl 3 $ "Elaborated provided postulate " ++ show n
801− | otherwise ->
802− ierror . Msg $ "Attempted to provide a postulate where a term was expected."
803−
804− where isTType :: TT Name -> Bool
805− isTType (TType _) = True
806− isTType _ = False
807−
808− isProviderOf :: TT Name -> TT Name -> Bool
809− isProviderOf tp prov
810− | (P _ (UN io) _, [prov']) <- unApply prov
811− , (P _ (NS (UN prov) [provs]) _, [tp']) <- unApply prov'
812− , tp == tp', io == txt "IO"
813− , prov == txt "Provider" && provs == txt "Providers" = True
814− isProviderOf _ _ = False
815−
816elabTransform :: ElabInfo -> FC -> Bool -> PTerm -> PTerm -> Idris ()
137elabTransform :: ElabInfo -> FC -> Bool -> PTerm -> PTerm -> Idris ()
817elabTransform info fc safe lhs_in rhs_in
138elabTransform info fc safe lhs_in rhs_in
818 = do ctxt <- getContext
139 = do ctxt <- getContext
@@ -845,1518 +166,13 @@ elabTransform info fc safe lhs_in rhs_in
845 addTrans (clhs_tm, crhs_tm)
166 addTrans (clhs_tm, crhs_tm)
846 addIBC (IBCTrans (clhs_tm, crhs_tm))
167 addIBC (IBCTrans (clhs_tm, crhs_tm))
847
168
848−
849−elabRecord :: ElabInfo -> SyntaxInfo -> Docstring -> FC -> Name ->
850− PTerm -> DataOpts -> Docstring -> Name -> PTerm -> Idris ()
851−elabRecord info syn doc fc tyn ty opts cdoc cn cty_in
852− = do elabData info syn doc [] fc opts (PDatadecl tyn ty [(cdoc, [], cn, cty_in, fc, [])])
853− -- TODO think: something more in info?
854− cty' <- implicit info syn cn cty_in
855− i <- getIState
856−
857− -- get bound implicits and propagate to setters (in case they
858− -- provide useful information for inference)
859− let extraImpls = getBoundImpls cty'
860−
861− cty <- case lookupTy cn (tt_ctxt i) of
862− [t] -> return (delab i t)
863− _ -> ifail "Something went inexplicably wrong"
864− cimp <- case lookupCtxt cn (idris_implicits i) of
865− [imps] -> return imps
866− ppos <- case lookupCtxt tyn (idris_datatypes i) of
867− [ti] -> return $ param_pos ti
868− let cty_imp = renameBs cimp cty
869− let ptys = getProjs [] cty_imp
870− let ptys_u = getProjs [] cty
871− let recty = getRecTy cty_imp
872− let recty_u = getRecTy cty
873−
874− let paramNames = getPNames recty ppos
875−
876− -- rename indices when we generate the getter/setter types, so
877− -- that they don't clash with the names of the projections
878− -- we're generating
879− let index_names_in = getRecNameMap "_in" ppos recty
880− let recty_in = substMatches index_names_in recty
881−
882− logLvl 3 $ show (recty, recty_u, ppos, paramNames, ptys)
883− -- Substitute indices with projection functions, and parameters with
884− -- the updated parameter name
885− let substs = map (\ (n, _) ->
886− if n `elem` paramNames
887− then (n, PRef fc (mkp n))
888− else (n, PApp fc (PRef fc n)
889− [pexp (PRef fc rec)]))
890− ptys
891−
892− -- Generate projection functions
893− proj_decls <- mapM (mkProj recty_in substs cimp) (zip ptys [0..])
894− logLvl 3 $ show proj_decls
895− let nonImp = mapMaybe isNonImp (zip cimp ptys_u)
896− let implBinds = getImplB id cty'
897−
898− -- Generate update functions
899− update_decls <- mapM (mkUpdate recty_u index_names_in extraImpls
900− (getFieldNames cty')
901− implBinds (length nonImp)) (zip nonImp [0..])
902− mapM_ (elabDecl EAll info) (concat proj_decls)
903− logLvl 3 $ show update_decls
904− mapM_ (tryElabDecl info) (update_decls)
905− where
906−-- syn = syn_in { syn_namespace = show (nsroot tyn) : syn_namespace syn_in }
907−
908− isNonImp (PExp _ _ _ _, a) = Just a
909− isNonImp _ = Nothing
910−
911− getPNames (PApp _ _ as) ppos = getpn as ppos
912− where
913− getpn as [] = []
914− getpn as (i:is) | length as > i,
915− PRef _ n <- getTm (as!!i) = n : getpn as is
916− | otherwise = getpn as is
917− getPNames _ _ = []
918−
919− tryElabDecl info (fn, ty, val)
920− = do i <- getIState
921− idrisCatch (do elabDecl' EAll info ty
922− elabDecl' EAll info val)
923− (\v -> do iputStrLn $ show fc ++
924− ":Warning - can't generate setter for " ++
925− show fn ++ " (" ++ show ty ++ ")"
926−-- ++ "\n" ++ pshow i v
927− putIState i)
928−
929− getBoundImpls (PPi (Imp _ _ _) n ty sc) = (n, ty) : getBoundImpls sc
930− getBoundImpls _ = []
931−
932− getImplB k (PPi (Imp l s _) n Placeholder sc)
933− = getImplB k sc
934− getImplB k (PPi (Imp l s p) n ty sc)
935− = getImplB (\x -> k (PPi (Imp l s p) n ty x)) sc
936− getImplB k (PPi _ n ty sc)
937− = getImplB k sc
938− getImplB k _ = k
939−
940− renameBs (PImp _ _ _ _ _ : ps) (PPi p n ty s)
941− = PPi p (mkImp n) ty (renameBs ps (substMatch n (PRef fc (mkImp n)) s))
942− renameBs (_:ps) (PPi p n ty s) = PPi p n ty (renameBs ps s)
943− renameBs _ t = t
944−
945− getProjs acc (PPi _ n ty s) = getProjs ((n, ty) : acc) s
946− getProjs acc r = reverse acc
947−
948− getFieldNames (PPi (Exp _ _ _) n _ s) = n : getFieldNames s
949− getFieldNames (PPi _ _ _ s) = getFieldNames s
950− getFieldNames _ = []
951−
952− getRecTy (PPi _ n ty s) = getRecTy s
953− getRecTy t = t
954−
955− -- make sure we pick a consistent name for parameters; any name will do
956− -- otherwise
957− getRecNameMap x ppos (PApp fc t args)
958− = mapMaybe toMN (zip [0..] (map getTm args))
959− where
960− toMN (i, PRef fc n)
961− | i `elem` ppos = Just (n, PRef fc (mkp n))
962− | otherwise = Just (n, PRef fc (sMN 0 (show n ++ x)))
963− toMN _ = Nothing
964− getRecNameMap x _ _ = []
965−
966− rec = sMN 0 "rec"
967−
968− -- only UNs propagate properly as parameters (bit of a hack then...)
969− mkp (UN n) = sUN ("_p_" ++ str n)
970− mkp (MN i n) = sMN i ("p_" ++ str n)
971− mkp (NS n s) = NS (mkp n) s
972−
973− mkImp (UN n) = sUN ("implicit_" ++ str n)
974− mkImp (MN i n) = sMN i ("implicit_" ++ str n)
975− mkImp (NS n s) = NS (mkImp n) s
976−
977− mkType (UN n) = sUN ("set_" ++ str n)
978− mkType (MN i n) = sMN i ("set_" ++ str n)
979− mkType (NS n s) = NS (mkType n) s
980−
981− mkProj recty substs cimp ((pn_in, pty), pos)
982− = do let pn = expandNS syn pn_in -- projection name
983− -- use pn_in in the indices, consistently, to avoid clash
984− let pfnTy = PTy emptyDocstring [] defaultSyntax fc [] pn
985− (PPi expl rec recty
986− (substMatches substs pty))
987− let pls = repeat Placeholder
988− let before = pos
989− let after = length substs - (pos + 1)
990− let args = take before pls ++ PRef fc (mkp pn_in) : take after pls
991− let iargs = map implicitise (zip cimp args)
992− let lhs = PApp fc (PRef fc pn)
993− [pexp (PApp fc (PRef fc cn) iargs)]
994− let rhs = PRef fc (mkp pn_in)
995− let pclause = PClause fc pn lhs [] rhs []
996− return [pfnTy, PClauses fc [] pn [pclause]]
997−
998− implicitise (pa, t) = pa { getTm = t }
999−
1000− -- If the 'pty' we're updating includes anything in 'substs', we're
1001− -- updating the type as well, so use recty', otherwise just use
1002− -- recty
1003− mkUpdate recty inames extras fnames k num ((pn, pty), pos)
1004− = do let setname = expandNS syn $ mkType pn
1005− let valname = sMN 0 "updateval"
1006− let pn_out = sMN 0 (show pn ++ "_out")
1007− let pn_in = sMN 0 (show pn ++ "_in")
1008− let recty_in = substMatches [(pn, PRef fc pn_in)] recty
1009− let recty_out = substMatches [(pn, PRef fc pn_out)] recty
1010− let pt = substMatches inames $
1011− k (implBindUp extras inames (PPi expl pn_out pty
1012− (PPi expl rec recty_in recty_out)))
1013− let pfnTy = PTy emptyDocstring [] defaultSyntax fc [] setname pt
1014−-- let pls = map (\x -> PRef fc (sMN x ("field" ++ show x))) [0..num-1]
1015− let inames_imp = map (\ (x,_) -> (x, Placeholder)) inames
1016− let pls = map (\x -> substMatches inames_imp (PRef fc x)) fnames
1017− let lhsArgs = pls
1018− let rhsArgs = take pos pls ++ (PRef fc valname) :
1019− drop (pos + 1) pls
1020− let before = pos
1021− let pclause = PClause fc setname (PApp fc (PRef fc setname)
1022− [pexp (PRef fc valname),
1023− pexp (PApp fc (PRef fc cn)
1024− (map pexp lhsArgs))])
1025− []
1026− (PApp fc (PRef fc cn)
1027− (map pexp rhsArgs)) []
1028− return (pn, pfnTy, PClauses fc [] setname [pclause])
1029−
1030− implBindUp [] is t = t
1031− implBindUp ((n, ty):ns) is t
1032− = let n' = case lookup n is of
1033− Just (PRef _ x) -> x
1034− _ -> n in
1035− if n `elem` allNamesIn t
1036− then PPi impl n' ty (implBindUp ns is t)
1037− else implBindUp ns is t
1038−
1039−-- | Elaborate a collection of left-hand and right-hand pairs - that is, a
1040−-- top-level definition.
1041−elabClauses :: ElabInfo -> FC -> FnOpts -> Name -> [PClause] -> Idris ()
1042−elabClauses info fc opts n_in cs = let n = liftname info n_in in
1043− do ctxt <- getContext
1044− ist <- getIState
1045− inacc <- map fst <$> fgetState (opt_inaccessible . ist_optimisation n)
1046−
1047− -- Check n actually exists, with no definition yet
1048− let tys = lookupTy n ctxt
1049− let reflect = Reflection `elem` opts
1050− checkUndefined n ctxt
1051− unless (length tys > 1) $ do
1052− fty <- case tys of
1053− [] -> -- TODO: turn into a CAF if there's no arguments
1054− -- question: CAFs in where blocks?
1055− tclift $ tfail $ At fc (NoTypeDecl n)
1056− [ty] -> return ty
1057− let atys = map snd (getArgTys fty)
1058− cs_elab <- mapM (elabClause info opts)
1059− (zip [0..] cs)
1060− let (pats_in, cs_full) = unzip cs_elab
1061−
1062− logLvl 3 $ "Elaborated patterns:\n" ++ show pats_in
1063−
1064− solveDeferred n
1065−
1066− -- just ensure that the structure exists
1067− fmodifyState (ist_optimisation n) id
1068− addIBC (IBCOpt n)
1069−
1070− ist <- getIState
1071− let pats = map (simple_lhs (tt_ctxt ist)) $ doTransforms ist pats_in
1072−
1073− -- logLvl 3 (showSep "\n" (map (\ (l,r) ->
1074− -- show l ++ " = " ++
1075− -- show r) pats))
1076− let tcase = opt_typecase (idris_options ist)
1077−
1078− -- Summary of what's about to happen: Definitions go:
1079− --
1080− -- pats_in -> pats -> pdef -> pdef'
1081−
1082− -- addCaseDef builds case trees from <pdef> and <pdef'>
1083−
1084− -- pdef is the compile-time pattern definition.
1085− -- This will get further optimised for run-time, and, separately,
1086− -- further inlined to help with totality checking.
1087− let pdef = map debind pats
1088−
1089− logLvl 5 $ "Initial typechecked patterns:\n" ++ show pats
1090− logLvl 5 $ "Initial typechecked pattern def:\n" ++ show pdef
1091−
1092− -- Look for 'static' names and generate new specialised
1093− -- definitions for them
1094−
1095− mapM_ (\ e -> case e of
1096− Left _ -> return ()
1097− Right (l, r) -> elabPE info fc n r) pats
1098−
1099− -- NOTE: Need to store original definition so that proofs which
1100− -- rely on its structure aren't affected by any changes to the
1101− -- inliner. Just use the inlined version to generate pdef' and to
1102− -- help with later inlinings.
1103−
1104− ist <- getIState
1105− let pdef_inl = inlineDef ist pdef
1106−
1107− numArgs <- tclift $ sameLength pdef
1108−
1109− case specNames opts of
1110− Just _ -> logLvl 5 $ "Partially evaluated:\n" ++ show pats
1111− _ -> return ()
1112−
1113− erInfo <- getErasureInfo <$> getIState
1114− tree@(CaseDef scargs sc _) <- tclift $
1115− simpleCase tcase False reflect CompileTime fc inacc atys pdef erInfo
1116− cov <- coverage
1117− pmissing <-
1118− if cov && not (hasDefault cs)
1119− then do missing <- genClauses fc n (map getLHS pdef) cs_full
1120− -- missing <- genMissing n scargs sc
1121− missing' <- filterM (checkPossible info fc True n) missing
1122− let clhs = map getLHS pdef
1123− logLvl 2 $ "Must be unreachable:\n" ++
1124− showSep "\n" (map showTmImpls missing') ++
1125− "\nAgainst: " ++
1126− showSep "\n" (map (\t -> showTmImpls (delab ist t)) (map getLHS pdef))
1127− -- filter out anything in missing' which is
1128− -- matched by any of clhs. This might happen since
1129− -- unification may force a variable to take a
1130− -- particular form, rather than force a case
1131− -- to be impossible.
1132− return (filter (noMatch ist clhs) missing')
1133− else return []
1134− let pcover = null pmissing
1135−
1136− -- pdef' is the version that gets compiled for run-time
1137− pdef_in' <- applyOpts pdef
1138− let pdef' = map (simple_rt (tt_ctxt ist)) pdef_in'
1139−
1140− logLvl 5 $ "After data structure transformations:\n" ++ show pdef'
1141−
1142− ist <- getIState
1143− -- let wf = wellFounded ist n sc
1144− let tot = if pcover || AssertTotal `elem` opts
1145− then Unchecked -- finish checking later
1146− else Partial NotCovering -- already know it's not total
1147−
1148− -- case lookupCtxt (namespace info) n (idris_flags ist) of
1149− -- [fs] -> if TotalFn `elem` fs
1150− -- then case tot of
1151− -- Total _ -> return ()
1152− -- t -> tclift $ tfail (At fc (Msg (show n ++ " is " ++ show t)))
1153− -- else return ()
1154− -- _ -> return ()
1155− case tree of
1156− CaseDef _ _ [] -> return ()
1157− CaseDef _ _ xs -> mapM_ (\x ->
1158− iputStrLn $ show fc ++
1159− ":warning - Unreachable case: " ++
1160− show (delab ist x)) xs
1161− let knowncovering = (pcover && cov) || AssertTotal `elem` opts
1162−
1163− tree' <- tclift $ simpleCase tcase knowncovering reflect
1164− RunTime fc inacc atys pdef' erInfo
1165− logLvl 3 $ "Unoptimised " ++ show n ++ ": " ++ show tree
1166− logLvl 3 $ "Optimised: " ++ show tree'
1167− ctxt <- getContext
1168− ist <- getIState
1169− let opt = idris_optimisation ist
1170− putIState (ist { idris_patdefs = addDef n (force pdef', force pmissing)
1171− (idris_patdefs ist) })
1172− let caseInfo = CaseInfo (inlinable opts) (dictionary opts)
1173− case lookupTy n ctxt of
1174− [ty] -> do updateContext (addCasedef n erInfo caseInfo
1175− tcase knowncovering
1176− reflect
1177− (AssertTotal `elem` opts)
1178− atys
1179− inacc
1180− pats
1181− pdef pdef pdef_inl pdef' ty)
1182− addIBC (IBCDef n)
1183− setTotality n tot
1184− when (not reflect) $ do totcheck (fc, n)
1185− defer_totcheck (fc, n)
1186− when (tot /= Unchecked) $ addIBC (IBCTotal n tot)
1187− i <- getIState
1188− case lookupDef n (tt_ctxt i) of
1189− (CaseOp _ _ _ _ _ cd : _) ->
1190− let (scargs, sc) = cases_compiletime cd
1191− (scargs', sc') = cases_runtime cd in
1192− do let calls = findCalls sc' scargs'
1193− let used = findUsedArgs sc' scargs'
1194− -- let scg = buildSCG i sc scargs
1195− -- add SCG later, when checking totality
1196− let cg = CGInfo scargs' calls [] used [] -- TODO: remove this, not needed anymore
1197− logLvl 2 $ "Called names: " ++ show cg
1198− addToCG n cg
1199− addToCalledG n (nub (map fst calls)) -- plus names in type!
1200− addIBC (IBCCG n)
1201− _ -> return ()
1202− return ()
1203− -- addIBC (IBCTotal n tot)
1204− [] -> return ()
1205− -- Check it's covering, if 'covering' option is used. Chase
1206− -- all called functions, and fail if any of them are also
1207− -- 'Partial NotCovering'
1208− when (CoveringFn `elem` opts) $ checkAllCovering fc [] n n
1209− where
1210− noMatch i cs tm = all (\x -> case matchClause i (delab' i x True True) tm of
1211− Right _ -> False
1212− Left miss -> True) cs
1213−
1214− checkUndefined n ctxt = case lookupDef n ctxt of
1215− [] -> return ()
1216− [TyDecl _ _] -> return ()
1217− _ -> tclift $ tfail (At fc (AlreadyDefined n))
1218−
1219− debind (Right (x, y)) = let (vs, x') = depat [] x
1220− (_, y') = depat [] y in
1221− (vs, x', y')
1222− debind (Left x) = let (vs, x') = depat [] x in
1223− (vs, x', Impossible)
1224−
1225− depat acc (Bind n (PVar t) sc) = depat (n : acc) (instantiate (P Bound n t) sc)
1226− depat acc x = (acc, x)
1227−
1228− hasDefault cs | (PClause _ _ last _ _ _ :_) <- reverse cs
1229− , (PApp fn s args) <- last = all ((==Placeholder) . getTm) args
1230− hasDefault _ = False
1231−
1232− getLHS (_, l, _) = l
1233−
1234− simple_lhs ctxt (Right (x, y)) = Right (normalise ctxt [] x,
1235− force (normalisePats ctxt [] y))
1236− simple_lhs ctxt t = t
1237−
1238− simple_rt ctxt (p, x, y) = (p, x, force (uniqueBinders p
1239− (rt_simplify ctxt [] y)))
1240−
1241− -- this is so pattern types are in the right form for erasure
1242− normalisePats ctxt env (Bind n (PVar t) sc)
1243− = let t' = normalise ctxt env t in
1244− Bind n (PVar t') (normalisePats ctxt ((n, PVar t') : env) sc)
1245− normalisePats ctxt env (Bind n (PVTy t) sc)
1246− = let t' = normalise ctxt env t in
1247− Bind n (PVTy t') (normalisePats ctxt ((n, PVar t') : env) sc)
1248− normalisePats ctxt env t = t
1249−
1250− specNames [] = Nothing
1251− specNames (Specialise ns : _) = Just ns
1252− specNames (_ : xs) = specNames xs
1253−
1254− sameLength ((_, x, _) : xs)
1255− = do l <- sameLength xs
1256− let (f, as) = unApply x
1257− if (null xs || l == length as) then return (length as)
1258− else tfail (At fc (Msg "Clauses have differing numbers of arguments "))
1259− sameLength [] = return 0
1260−
1261− -- apply all transformations (just specialisation for now, add
1262− -- user defined transformation rules later)
1263− doTransforms ist pats =
1264− case specNames opts of
1265− Nothing -> pats
1266− Just ns -> partial_eval (tt_ctxt ist) ns pats
1267−
1268−-- | Find 'static' applications in a term and partially evaluate them
1269−elabPE :: ElabInfo -> FC -> Name -> Term -> Idris ()
1270−elabPE info fc caller r =
1271− do ist <- getIState
1272− let sa = getSpecApps ist [] r
1273− mapM_ (mkSpecialised ist) sa
1274− where
1275− -- TODO: Add a PTerm level transformation rule, which is basically the
1276− -- new definition in reverse (before specialising it).
1277− -- RHS => LHS where implicit arguments are left blank in the
1278− -- transformation.
1279−
1280− -- Apply that transformation after every PClauses elaboration
1281−
1282− mkSpecialised ist specapp_in = do
1283− let (specTy, specapp) = getSpecTy ist specapp_in
1284− let (n, newnm, pats) = getSpecClause ist specapp
1285− let undef = case lookupDef newnm (tt_ctxt ist) of
1286− [] -> True
1287− _ -> False
1288− logLvl 5 $ show (newnm, map (concreteArg ist) (snd specapp))
1289− idrisCatch
1290− (when (undef && all (concreteArg ist) (snd specapp)) $ do
1291− cgns <- getAllNames n
1292− let opts = [Specialise (map (\x -> (x, Nothing)) cgns ++
1293− mapMaybe specName (snd specapp))]
1294− logLvl 3 $ "Specialising application: " ++ show specapp
1295− logLvl 2 $ "New name: " ++ show newnm
1296− iLOG $ "PE definition type : " ++ (show specTy)
1297− ++ "\n" ++ show opts
1298− logLvl 2 $ "PE definition " ++ show newnm ++ ":\n" ++
1299− showSep "\n"
1300− (map (\ (lhs, rhs) ->
1301− (showTmImpls lhs ++ " = " ++
1302− showTmImpls rhs)) pats)
1303− elabType info defaultSyntax emptyDocstring [] fc opts newnm specTy
1304− let def = map (\ (lhs, rhs) -> PClause fc newnm lhs [] rhs []) pats
1305− elabClauses info fc opts newnm def
1306− logLvl 2 $ "Specialised " ++ show newnm)
1307− -- if it doesn't work, just don't specialise. Could happen for lots
1308− -- of valid reasons (e.g. local variables in scope which can't be
1309− -- lifted out).
1310− (\e -> logLvl 4 $ "Couldn't specialise: " ++ (pshow ist e))
1311−
1312− specName (ImplicitS, tm)
1313− | (P Ref n _, _) <- unApply tm = Just (n, Just 1)
1314− specName (ExplicitS, tm)
1315− | (P Ref n _, _) <- unApply tm = Just (n, Just 1)
1316− specName _ = Nothing
1317−
1318− concreteArg ist (ImplicitS, tm) = concreteTm ist tm
1319− concreteArg ist (ExplicitS, tm) = concreteTm ist tm
1320− concreteArg ist _ = True
1321−
1322− concreteTm ist tm | (P _ n _, _) <- unApply tm =
1323− case lookupTy n (tt_ctxt ist) of
1324− [] -> False
1325− _ -> True
1326− concreteTm ist (Constant _) = True
1327− concreteTm ist _ = False
1328−
1329− -- get the type of a specialised application
1330− getSpecTy ist (n, args)
1331− = case lookupTy n (tt_ctxt ist) of
1332− [ty] -> let (specty_in, args') = specType args (explicitNames ty)
1333− specty = normalise (tt_ctxt ist) [] (finalise specty_in)
1334− t = mkPE_TyDecl ist args' (explicitNames specty) in
1335− (t, (n, args'))
1336−-- (normalise (tt_ctxt ist) [] (specType args ty))
1337− _ -> error "Can't happen (getSpecTy)"
1338−
1339− -- get the clause of a specialised application
1340− getSpecClause ist (n, args)
1341− = let newnm = sUN ("__"++show (nsroot n) ++ "_" ++
1342− showSep "_" (map showArg args)) in
1343− -- UN (show n ++ show (map snd args)) in
1344− (n, newnm, mkPE_TermDecl ist newnm n args)
1345− where showArg (ExplicitS, n) = show n
1346− showArg (ImplicitS, n) = show n
1347− showArg _ = ""
1348−
1349−
1350−-- Elaborate a value, returning any new bindings created (this will only
1351−-- happen if elaborating as a pattern clause)
1352−elabValBind :: ElabInfo -> ElabMode -> Bool -> PTerm -> Idris (Term, Type, [(Name, Type)])
1353−elabValBind info aspat norm tm_in
1354− = do ctxt <- getContext
1355− i <- getIState
1356− let tm = addImpl i tm_in
1357− logLvl 10 (showTmImpls tm)
1358− -- try:
1359− -- * ordinary elaboration
1360− -- * elaboration as a Type
1361− -- * elaboration as a function a -> b
1362−
1363− ((tm', defer, is), _) <-
1364−-- tctry (elaborate ctxt (MN 0 "val") (TType (UVal 0)) []
1365−-- (build i info aspat (MN 0 "val") tm))
1366− tclift (elaborate ctxt (sMN 0 "val") infP []
1367− (build i info aspat [Reflection] (sMN 0 "val") (infTerm tm)))
1368− let vtm = orderPats (getInferTerm tm')
1369−
1370− def' <- checkDef (fileFC "(input)") defer
1371− let def'' = map (\(n, (i, top, t)) -> (n, (i, top, t, True))) def'
1372− addDeferred def''
1373− mapM_ (elabCaseBlock info []) is
1374−
1375− logLvl 3 ("Value: " ++ show vtm)
1376−-- recheckC (fileFC "(input)") [] tm'
1377−-- logLvl 2 (show vtm)
1378− (vtm_in, vty) <- recheckC (fileFC "(input)") [] vtm
1379−
1380− let vtm = if norm then normalise (tt_ctxt i) [] vtm_in
1381− else vtm_in
1382− let bargs = getPBtys vtm
1383−
1384− return (vtm, vty, bargs)
1385−
1386−elabVal :: ElabInfo -> ElabMode -> PTerm -> Idris (Term, Type)
1387−elabVal info aspat tm_in
1388− = do (tm, ty, _) <- elabValBind info aspat False tm_in
1389− return (tm, ty)
1390−
1391−-- checks if the clause is a possible left hand side. Returns the term if
1392−-- possible, otherwise Nothing.
1393−
1394−checkPossible :: ElabInfo -> FC -> Bool -> Name -> PTerm -> Idris Bool
1395−checkPossible info fc tcgen fname lhs_in
1396− = do ctxt <- getContext
1397− i <- getIState
1398− let lhs = addImplPat i lhs_in
1399− -- if the LHS type checks, it is possible
1400− case elaborate ctxt (sMN 0 "patLHS") infP []
1401− (erun fc (buildTC i info ELHS [] fname (infTerm lhs))) of
1402− OK ((lhs', _, _), _) ->
1403− do let lhs_tm = orderPats (getInferTerm lhs')
1404− case recheck ctxt [] (forget lhs_tm) lhs_tm of
1405− OK _ -> return True
1406− err -> return False
1407− -- if it's a recoverable error, the case may become possible
1408− Error err -> if tcgen then return (recoverable ctxt err)
1409− else return (validCase ctxt err ||
1410− recoverable ctxt err)
1411− where validCase ctxt (CantUnify _ topx topy e _ _)
1412− = let topx' = normalise ctxt [] topx
1413− topy' = normalise ctxt [] topy in
1414− not (sameFam topx' topy' || not (validCase ctxt e))
1415− validCase ctxt (CantConvert _ _ _) = False
1416− validCase ctxt (At _ e) = validCase ctxt e
1417− validCase ctxt (Elaborating _ _ e) = validCase ctxt e
1418− validCase ctxt (ElaboratingArg _ _ _ e) = validCase ctxt e
1419− validCase ctxt _ = True
1420−
1421− recoverable ctxt (CantUnify r topx topy e _ _)
1422− = let topx' = normalise ctxt [] topx
1423− topy' = normalise ctxt [] topy in
1424− checkRec topx' topy'
1425− recoverable ctxt (At _ e) = recoverable ctxt e
1426− recoverable ctxt (Elaborating _ _ e) = recoverable ctxt e
1427− recoverable ctxt (ElaboratingArg _ _ _ e) = recoverable ctxt e
1428− recoverable _ _ = False
1429−
1430− sameFam topx topy
1431− = case (unApply topx, unApply topy) of
1432− ((P _ x _, _), (P _ y _, _)) -> x == y
1433− _ -> False
1434−
1435− -- different notion of recoverable than in unification, since we
1436− -- have no metavars -- just looking to see if a constructor is failing
1437− -- to unify with a function that may be reduced later
1438−
1439− checkRec (App f a) p@(P _ _ _) = checkRec f p
1440− checkRec p@(P _ _ _) (App f a) = checkRec p f
1441− checkRec fa@(App _ _) fa'@(App _ _)
1442− | (f, as) <- unApply fa,
1443− (f', as') <- unApply fa'
1444− = if (length as /= length as')
1445− then checkRec f f'
1446− else checkRec f f' && and (zipWith checkRec as as')
1447− checkRec (P xt x _) (P yt y _) = x == y || ntRec xt yt
1448− checkRec _ _ = False
1449−
1450− ntRec x y | Ref <- x = True
1451− | Ref <- y = True
1452− | otherwise = False -- name is different, unrecoverable
1453−
1454−getFixedInType i env (PExp _ _ _ _ : is) (Bind n (Pi t) sc)
1455− = nub $ getFixedInType i env [] t ++
1456− getFixedInType i (n : env) is (instantiate (P Bound n t) sc)
1457−getFixedInType i env (_ : is) (Bind n (Pi t) sc)
1458− = getFixedInType i (n : env) is (instantiate (P Bound n t) sc)
1459−getFixedInType i env is tm@(App f a)
1460− | (P _ tn _, args) <- unApply tm
1461− = case lookupCtxt tn (idris_datatypes i) of
1462− [t] -> nub $ paramNames args env (param_pos t) ++
1463− getFixedInType i env is f ++
1464− getFixedInType i env is a
1465− [] -> nub $ getFixedInType i env is f ++
1466− getFixedInType i env is a
1467− | otherwise = nub $ getFixedInType i env is f ++
1468− getFixedInType i env is a
1469−getFixedInType i _ _ _ = []
1470−
1471−getFlexInType i env ps (Bind n (Pi t) sc)
1472− = nub $ (if (not (n `elem` ps)) then getFlexInType i env ps t else []) ++
1473− getFlexInType i (n : env) ps (instantiate (P Bound n t) sc)
1474−getFlexInType i env ps tm@(App f a)
1475− | (P _ tn _, args) <- unApply tm
1476− = case lookupCtxt tn (idris_datatypes i) of
1477− [t] -> nub $ paramNames args env [x | x <- [0..length args],
1478− not (x `elem` param_pos t)]
1479− ++ getFlexInType i env ps f ++
1480− getFlexInType i env ps a
1481− [] -> nub $ getFlexInType i env ps f ++
1482− getFlexInType i env ps a
1483− | otherwise = nub $ getFlexInType i env ps f ++
1484− getFlexInType i env ps a
1485−getFlexInType i _ _ _ = []
1486−
1487−-- Treat a name as a parameter if it appears in parameter positions in
1488−-- types, and never in a non-parameter position in a (non-param) argument type.
1489−
1490−getParamsInType i env ps t = let fix = getFixedInType i env ps t
1491− flex = getFlexInType i env fix t in
1492− [x | x <- fix, not (x `elem` flex)]
1493−
1494−paramNames args env [] = []
1495−paramNames args env (p : ps)
1496− | length args > p = case args!!p of
1497− P _ n _ -> if n `elem` env
1498− then n : paramNames args env ps
1499− else paramNames args env ps
1500− _ -> paramNames args env ps
1501− | otherwise = paramNames args env ps
1502−
1503−propagateParams :: IState -> [Name] -> Type -> PTerm -> PTerm
1504−propagateParams i ps t tm@(PApp _ (PRef fc n) args)
1505− = PApp fc (PRef fc n) (addP t args)
1506− where addP (Bind n _ sc) (t : ts)
1507− | Placeholder <- getTm t,
1508− n `elem` ps,
1509− not (n `elem` allNamesIn tm)
1510− = t { getTm = PRef fc n } : addP sc ts
1511− addP (Bind n _ sc) (t : ts) = t : addP sc ts
1512− addP _ ts = ts
1513−propagateParams i ps t (PRef fc n)
1514− = case lookupCtxt n (idris_implicits i) of
1515− [is] -> let ps' = filter (isImplicit is) ps in
1516− PApp fc (PRef fc n) (map (\x -> pimp x (PRef fc x) True) ps')
1517− _ -> PRef fc n
1518− where isImplicit [] n = False
1519− isImplicit (PImp _ _ _ x _ : is) n | x == n = True
1520− isImplicit (_ : is) n = isImplicit is n
1521−propagateParams i ps t x = x
1522−
1523−-- Return the elaborated LHS/RHS, and the original LHS with implicits added
1524−elabClause :: ElabInfo -> FnOpts -> (Int, PClause) ->
1525− Idris (Either Term (Term, Term), PTerm)
1526−elabClause info opts (_, PClause fc fname lhs_in [] PImpossible [])
1527− = do let tcgen = Dictionary `elem` opts
1528− i <- get
1529− let lhs = addImpl i lhs_in
1530− b <- checkPossible info fc tcgen fname lhs_in
1531− case b of
1532− True -> tclift $ tfail (At fc
1533− (Msg $ show lhs_in ++ " is a valid case"))
1534− False -> do ptm <- mkPatTm lhs_in
1535− return (Left ptm, lhs)
1536−elabClause info opts (cnum, PClause fc fname lhs_in withs rhs_in whereblock)
1537− = do let tcgen = Dictionary `elem` opts
1538− ctxt <- getContext
1539−
1540− -- Build the LHS as an "Infer", and pull out its type and
1541− -- pattern bindings
1542− i <- getIState
1543− inf <- isTyInferred fname
1544− -- get the parameters first, to pass through to any where block
1545− let fn_ty = case lookupTy fname (tt_ctxt i) of
1546− [t] -> t
1547− _ -> error "Can't happen (elabClause function type)"
1548− let fn_is = case lookupCtxt fname (idris_implicits i) of
1549− [t] -> t
1550− _ -> []
1551− let params = getParamsInType i [] fn_is fn_ty
1552− let lhs = mkLHSapp $ stripUnmatchable i $
1553− propagateParams i params fn_ty (addImplPat i (stripLinear i lhs_in))
1554− logLvl 5 ("LHS: " ++ show fc ++ " " ++ showTmImpls lhs)
1555− logLvl 4 ("Fixed parameters: " ++ show params ++ " from " ++ show lhs_in ++
1556− "\n" ++ show (fn_ty, fn_is))
1557−
1558− (((lhs', dlhs, []), probs, inj), _) <-
1559− tclift $ elaborate ctxt (sMN 0 "patLHS") infP []
1560− (do res <- errAt "left hand side of " fname
1561− (erun fc (buildTC i info ELHS opts fname (infTerm lhs)))
1562− probs <- get_probs
1563− inj <- get_inj
1564− return (res, probs, inj))
1565−
1566− when inf $ addTyInfConstraints fc (map (\(x,y,_,_,_,_) -> (x,y)) probs)
1567−
1568− let lhs_tm = orderPats (getInferTerm lhs')
1569− let lhs_ty = getInferType lhs'
1570− logLvl 3 ("Elaborated: " ++ show lhs_tm)
1571− logLvl 3 ("Elaborated type: " ++ show lhs_ty)
1572− logLvl 5 ("Injective: " ++ show fname ++ " " ++ show inj)
1573−
1574− -- If we're inferring metavariables in the type, don't recheck,
1575− -- because we're only doing this to try to work out those metavariables
1576− (clhs_c, clhsty) <- if not inf
1577− then recheckC fc [] lhs_tm
1578− else return (lhs_tm, lhs_ty)
1579− let clhs = normalise ctxt [] clhs_c
1580−
1581− logLvl 3 ("Normalised LHS: " ++ showTmImpls (delabMV i clhs))
1582−
1583− rep <- useREPL
1584− when rep $ do
1585− addInternalApp (fc_fname fc) (fst . fc_start $ fc) (delabMV i clhs) -- TODO: Should use span instead of line and filename?
1586− addIBC (IBCLineApp (fc_fname fc) (fst . fc_start $ fc) (delabMV i clhs))
1587−
1588− logLvl 5 ("Checked " ++ show clhs ++ "\n" ++ show clhsty)
1589− -- Elaborate where block
1590− ist <- getIState
1591− windex <- getName
1592− let decls = nub (concatMap declared whereblock)
1593− let defs = nub (decls ++ concatMap defined whereblock)
1594− let newargs = pvars ist lhs_tm
1595− let winfo = pinfo info newargs defs windex
1596− let wb = map (expandParamsD False ist decorate newargs defs) whereblock
1597−
1598− -- Split the where block into declarations with a type, and those
1599− -- without
1600− -- Elaborate those with a type *before* RHS, those without *after*
1601− let (wbefore, wafter) = sepBlocks wb
1602−
1603− logLvl 2 $ "Where block:\n " ++ show wbefore ++ "\n" ++ show wafter
1604− mapM_ (elabDecl' EAll winfo) wbefore
1605− -- Now build the RHS, using the type of the LHS as the goal.
1606− i <- getIState -- new implicits from where block
1607− logLvl 5 (showTmImpls (expandParams decorate newargs defs (defs \\ decls) rhs_in))
1608− let rhs = addImplBoundInf i (map fst newargs) (defs \\ decls)
1609− (expandParams decorate newargs defs (defs \\ decls) rhs_in)
1610− logLvl 2 $ "RHS: " ++ showTmImpls rhs
1611− ctxt <- getContext -- new context with where block added
1612− logLvl 5 "STARTING CHECK"
1613− ((rhs', defer, is, probs), _) <-
1614− tclift $ elaborate ctxt (sMN 0 "patRHS") clhsty []
1615− (do pbinds ist lhs_tm
1616− mapM_ setinj (nub (params ++ inj))
1617− setNextName
1618− (_, _, is) <- errAt "right hand side of " fname
1619− (erun fc (build i winfo ERHS opts fname rhs))
1620− errAt "right hand side of " fname
1621− (erun fc $ psolve lhs_tm)
1622− hs <- get_holes
1623− aux <- getAux
1624− mapM_ (elabCaseHole aux) hs
1625− tt <- get_term
1626− let (tm, ds) = runState (collectDeferred (Just fname) tt) []
1627− probs <- get_probs
1628− return (tm, ds, is, probs))
1629−
1630− when inf $ addTyInfConstraints fc (map (\(x,y,_,_,_,_) -> (x,y)) probs)
1631−
1632− logLvl 5 "DONE CHECK"
1633− logLvl 2 $ "---> " ++ show rhs'
1634− when (not (null defer)) $ iLOG $ "DEFERRED " ++
1635− show (map (\ (n, (_,_,t)) -> (n, t)) defer)
1636− def' <- checkDef fc defer
1637− let def'' = map (\(n, (i, top, t)) -> (n, (i, top, t, False))) def'
1638− addDeferred def''
1639− mapM_ (\(n, _) -> addIBC (IBCDef n)) def''
1640−
1641− when (not (null def')) $ do
1642− mapM_ defer_totcheck (map (\x -> (fc, fst x)) def'')
1643−
1644− -- Now the remaining deferred (i.e. no type declarations) clauses
1645− -- from the where block
1646−
1647− mapM_ (elabDecl' EAll winfo) wafter
1648− mapM_ (elabCaseBlock winfo opts) is
1649−
1650− ctxt <- getContext
1651− logLvl 5 $ "Rechecking"
1652− logLvl 6 $ " ==> " ++ show (forget rhs')
1653− (crhs, crhsty) <- if not inf
1654− then recheckC fc [] rhs'
1655− else return (rhs', clhsty)
1656− logLvl 6 $ " ==> " ++ show crhsty ++ " against " ++ show clhsty
1657− case converts ctxt [] clhsty crhsty of
1658− OK _ -> return ()
1659− Error e -> ierror (At fc (CantUnify False clhsty crhsty e [] 0))
1660− i <- getIState
1661− checkInferred fc (delab' i crhs True True) rhs
1662− -- if the function is declared '%error_reverse', or its type,
1663− -- then we'll try running it in reverse to improve error messages
1664− let (ret_fam, _) = unApply (getRetTy crhsty)
1665− rev <- case ret_fam of
1666− P _ rfamn _ ->
1667− case lookupCtxt rfamn (idris_datatypes i) of
1668− [TI _ _ dopts _ _] ->
1669− return (DataErrRev `elem` dopts)
1670− _ -> return False
1671− _ -> return False
1672−
1673− when (rev || ErrorReverse `elem` opts) $ do
1674− addIBC (IBCErrRev (crhs, clhs))
1675− addErrRev (crhs, clhs)
1676− return $ (Right (clhs, crhs), lhs)
1677− where
1678− pinfo :: ElabInfo -> [(Name, PTerm)] -> [Name] -> Int -> ElabInfo
1679− pinfo info ns ds i
1680− = let newps = params info ++ ns
1681− dsParams = map (\n -> (n, map fst newps)) ds
1682− newb = addAlist dsParams (inblock info)
1683− l = liftname info in
1684− info { params = newps,
1685− inblock = newb,
1686− liftname = id -- (\n -> case lookupCtxt n newb of
1687− -- Nothing -> n
1688− -- _ -> MN i (show n)) . l
1689− }
1690−
1691− mkLHSapp t@(PRef _ _) = trace ("APP " ++ show t) $ PApp fc t []
1692− mkLHSapp t = t
1693−
1694− decorate (NS x ns)
1695− = NS (SN (WhereN cnum fname x)) ns -- ++ [show cnum])
1696−-- = NS (UN ('#':show x)) (ns ++ [show cnum, show fname])
1697− decorate x
1698− = SN (WhereN cnum fname x)
1699−-- = NS (SN (WhereN cnum fname x)) [show cnum]
1700−-- = NS (UN ('#':show x)) [show cnum, show fname]
1701−
1702− sepBlocks bs = sepBlocks' [] bs where
1703− sepBlocks' ns (d@(PTy _ _ _ _ _ n t) : bs)
1704− = let (bf, af) = sepBlocks' (n : ns) bs in
1705− (d : bf, af)
1706− sepBlocks' ns (d@(PClauses _ _ n _) : bs)
1707− | not (n `elem` ns) = let (bf, af) = sepBlocks' ns bs in
1708− (bf, d : af)
1709− sepBlocks' ns (b : bs) = let (bf, af) = sepBlocks' ns bs in
1710− (b : bf, af)
1711− sepBlocks' ns [] = ([], [])
1712−
1713−
1714− -- if a hole is just an argument/result of a case block, treat it as
1715− -- the unit type. Hack to help elaborate case in do blocks.
1716− elabCaseHole aux h = do
1717− focus h
1718− g <- goal
1719− case g of
1720− TType _ -> when (any (isArg h) aux) $ do apply (Var unitTy) []; solve
1721− _ -> return ()
1722−
1723− -- Is the name a pattern argument in the declaration
1724− isArg :: Name -> PDecl -> Bool
1725− isArg n (PClauses _ _ _ cs) = any isArg' cs
1726− where
1727− isArg' (PClause _ _ (PApp _ _ args) _ _ _)
1728− = any (\x -> case x of
1729− PRef _ n' -> n == n'
1730− _ -> False) (map getTm args)
1731− isArg' _ = False
1732− isArg _ _ = False
1733−
1734−elabClause info opts (_, PWith fc fname lhs_in withs wval_in withblock)
1735− = do let tcgen = Dictionary `elem` opts
1736− ctxt <- getContext
1737− -- Build the LHS as an "Infer", and pull out its type and
1738− -- pattern bindings
1739− i <- getIState
1740− -- get the parameters first, to pass through to any where block
1741− let fn_ty = case lookupTy fname (tt_ctxt i) of
1742− [t] -> t
1743− _ -> error "Can't happen (elabClause function type)"
1744− let fn_is = case lookupCtxt fname (idris_implicits i) of
1745− [t] -> t
1746− _ -> []
1747− let params = getParamsInType i [] fn_is fn_ty
1748− let lhs = propagateParams i params fn_ty (addImplPat i (stripLinear i lhs_in))
1749− logLvl 2 ("LHS: " ++ show lhs)
1750− ((lhs', dlhs, []), _) <-
1751− tclift $ elaborate ctxt (sMN 0 "patLHS") infP []
1752− (errAt "left hand side of with in " fname
1753− (erun fc (buildTC i info ELHS opts fname (infTerm lhs))) )
1754− let lhs_tm = orderPats (getInferTerm lhs')
1755− let lhs_ty = getInferType lhs'
1756− let ret_ty = getRetTy (explicitNames (normalise ctxt [] lhs_ty))
1757− logLvl 3 (show lhs_tm)
1758− (clhs, clhsty) <- recheckC fc [] lhs_tm
1759− logLvl 5 ("Checked " ++ show clhs)
1760− let bargs = getPBtys (explicitNames (normalise ctxt [] lhs_tm))
1761− let wval = addImplBound i (map fst bargs) wval_in
1762− logLvl 5 ("Checking " ++ showTmImpls wval)
1763− -- Elaborate wval in this context
1764− ((wval', defer, is), _) <-
1765− tclift $ elaborate ctxt (sMN 0 "withRHS")
1766− (bindTyArgs PVTy bargs infP) []
1767− (do pbinds i lhs_tm
1768− setNextName
1769− -- TODO: may want where here - see winfo abpve
1770− (_', d, is) <- errAt "with value in " fname
1771− (erun fc (build i info ERHS opts fname (infTerm wval)))
1772− erun fc $ psolve lhs_tm
1773− tt <- get_term
1774− return (tt, d, is))
1775− def' <- checkDef fc defer
1776− let def'' = map (\(n, (i, top, t)) -> (n, (i, top, t, False))) def'
1777− addDeferred def''
1778− mapM_ (elabCaseBlock info opts) is
1779− logLvl 5 ("Checked wval " ++ show wval')
1780− (cwval, cwvalty) <- recheckC fc [] (getInferTerm wval')
1781− let cwvaltyN = explicitNames (normalise ctxt [] cwvalty)
1782− let cwvalN = explicitNames (normalise ctxt [] cwval)
1783− logLvl 5 ("With type " ++ show cwvalty ++ "\nRet type " ++ show ret_ty)
1784− let pvars = map fst (getPBtys cwvalty)
1785− -- we need the unelaborated term to get the names it depends on
1786− -- rather than a de Bruijn index.
1787− let pdeps = usedNamesIn pvars i (delab i cwvalty)
1788− let (bargs_pre, bargs_post) = split pdeps bargs []
1789− logLvl 10 ("With type " ++ show (getRetTy cwvaltyN) ++
1790− " depends on " ++ show pdeps ++ " from " ++ show pvars)
1791− logLvl 10 ("Pre " ++ show bargs_pre ++ "\nPost " ++ show bargs_post)
1792− windex <- getName
1793− -- build a type declaration for the new function:
1794− -- (ps : Xs) -> (withval : cwvalty) -> (ps' : Xs') -> ret_ty
1795− let wargval = getRetTy cwvalN
1796− let wargtype = getRetTy cwvaltyN
1797− logLvl 5 ("Abstract over " ++ show wargval ++ " in " ++ show wargtype)
1798− let wtype = bindTyArgs Pi (bargs_pre ++
1799− (sMN 0 "warg", wargtype) :
1800− map (abstract (sMN 0 "warg") wargval wargtype) bargs_post)
1801− (substTerm wargval (P Bound (sMN 0 "warg") wargtype) ret_ty)
1802− logLvl 5 ("New function type " ++ show wtype)
1803− let wname = sMN windex (show fname)
1804−
1805− let imps = getImps wtype -- add to implicits context
1806− putIState (i { idris_implicits = addDef wname imps (idris_implicits i) })
1807− addIBC (IBCDef wname)
1808− def' <- checkDef fc [(wname, (-1, Nothing, wtype))]
1809− let def'' = map (\(n, (i, top, t)) -> (n, (i, top, t, False))) def'
1810− addDeferred def''
1811−
1812− -- in the subdecls, lhs becomes:
1813− -- fname pats | wpat [rest]
1814− -- ==> fname' ps wpat [rest], match pats against toplevel for ps
1815− wb <- mapM (mkAuxC wname lhs (map fst bargs_pre) (map fst bargs_post))
1816− withblock
1817− logLvl 3 ("with block " ++ show wb)
1818− -- propagate totality assertion to the new definitions
1819− when (AssertTotal `elem` opts) $ setFlags wname [AssertTotal]
1820− mapM_ (elabDecl EAll info) wb
1821−
1822− -- rhs becomes: fname' ps wval
1823− let rhs = PApp fc (PRef fc wname)
1824− (map (pexp . (PRef fc) . fst) bargs_pre ++
1825− pexp wval :
1826− (map (pexp . (PRef fc) . fst) bargs_post))
1827− logLvl 5 ("New RHS " ++ showTmImpls rhs)
1828− ctxt <- getContext -- New context with block added
1829− i <- getIState
1830− ((rhs', defer, is), _) <-
1831− tclift $ elaborate ctxt (sMN 0 "wpatRHS") clhsty []
1832− (do pbinds i lhs_tm
1833− setNextName
1834− (_, d, is) <- erun fc (build i info ERHS opts fname rhs)
1835− psolve lhs_tm
1836− tt <- get_term
1837− return (tt, d, is))
1838− def' <- checkDef fc defer
1839− let def'' = map (\(n, (i, top, t)) -> (n, (i, top, t, False))) def'
1840− addDeferred def''
1841− mapM_ (elabCaseBlock info opts) is
1842− logLvl 5 ("Checked RHS " ++ show rhs')
1843− (crhs, crhsty) <- recheckC fc [] rhs'
1844− return $ (Right (clhs, crhs), lhs)
1845− where
1846− getImps (Bind n (Pi _) t) = pexp Placeholder : getImps t
1847− getImps _ = []
1848−
1849− mkAuxC wname lhs ns ns' (PClauses fc o n cs)
1850− | True = do cs' <- mapM (mkAux wname lhs ns ns') cs
1851− return $ PClauses fc o wname cs'
1852− | otherwise = ifail $ show fc ++ "with clause uses wrong function name " ++ show n
1853− mkAuxC wname lhs ns ns' d = return $ d
1854−
1855− mkAux wname toplhs ns ns' (PClause fc n tm_in (w:ws) rhs wheres)
1856− = do i <- getIState
1857− let tm = addImplPat i tm_in
1858− logLvl 2 ("Matching " ++ showTmImpls tm ++ " against " ++
1859− showTmImpls toplhs)
1860− case matchClause i toplhs tm of
1861− Left (a,b) -> ifail $ show fc ++ ":with clause does not match top level"
1862− Right mvars ->
1863− do logLvl 3 ("Match vars : " ++ show mvars)
1864− lhs <- updateLHS n wname mvars ns ns' (fullApp tm) w
1865− return $ PClause fc wname lhs ws rhs wheres
1866− mkAux wname toplhs ns ns' (PWith fc n tm_in (w:ws) wval withs)
1867− = do i <- getIState
1868− let tm = addImplPat i tm_in
1869− logLvl 2 ("Matching " ++ showTmImpls tm ++ " against " ++
1870− showTmImpls toplhs)
1871− withs' <- mapM (mkAuxC wname toplhs ns ns') withs
1872− case matchClause i toplhs tm of
1873− Left (a,b) -> trace ("matchClause: " ++ show a ++ " =/= " ++ show b) (ifail $ show fc ++ "with clause does not match top level")
1874− Right mvars ->
1875− do lhs <- updateLHS n wname mvars ns ns' (fullApp tm) w
1876− return $ PWith fc wname lhs ws wval withs'
1877− mkAux wname toplhs ns ns' c
1878− = ifail $ show fc ++ ":badly formed with clause"
1879−
1880− addArg (PApp fc f args) w = PApp fc f (args ++ [pexp w])
1881− addArg (PRef fc f) w = PApp fc (PRef fc f) [pexp w]
1882−
1883− updateLHS n wname mvars ns_in ns_in' (PApp fc (PRef fc' n') args) w
1884− = let ns = map (keepMvar (map fst mvars) fc') ns_in
1885− ns' = map (keepMvar (map fst mvars) fc') ns_in' in
1886− return $ substMatches mvars $
1887− PApp fc (PRef fc' wname)
1888− (map pexp ns ++ pexp w : (map pexp ns'))
1889− updateLHS n wname mvars ns_in ns_in' tm w
1890− = updateLHS n wname mvars ns_in ns_in' (PApp fc tm []) w
1891−
1892− keepMvar mvs fc v | v `elem` mvs = PRef fc v
1893− | otherwise = Placeholder
1894−
1895− fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
1896− fullApp x = x
1897−
1898− split [] rest pre = (reverse pre, rest)
1899− split deps ((n, ty) : rest) pre
1900− | n `elem` deps = split (deps \\ [n]) rest ((n, ty) : pre)
1901− | otherwise = split deps rest ((n, ty) : pre)
1902− split deps [] pre = (reverse pre, [])
1903−
1904− abstract wn wv wty (n, argty) = (n, substTerm wv (P Bound wn wty) argty)
1905−
1906−data MArgTy = IA | EA | CA deriving Show
1907−
1908−elabClass :: ElabInfo -> SyntaxInfo -> Docstring ->
1909− FC -> [PTerm] ->
1910− Name -> [(Name, PTerm)] -> [(Name, Docstring)] -> [PDecl] -> Idris ()
1911−elabClass info syn_in doc fc constraints tn ps pDocs ds
1912− = do let cn = SN (InstanceCtorN tn) -- sUN ("instance" ++ show tn) -- MN 0 ("instance" ++ show tn)
1913− let tty = pibind ps PType
1914− let constraint = PApp fc (PRef fc tn)
1915− (map (pexp . PRef fc) (map fst ps))
1916−
1917− let syn = syn_in { using = addToUsing (using syn_in) ps }
1918−
1919− -- build data declaration
1920− let mdecls = filter tydecl ds -- method declarations
1921− let idecls = filter instdecl ds -- default superclass instance declarations
1922− mapM_ checkDefaultSuperclassInstance idecls
1923− let mnames = map getMName mdecls
1924− logLvl 2 $ "Building methods " ++ show mnames
1925− ims <- mapM (tdecl mnames) mdecls
1926− defs <- mapM (defdecl (map (\ (x,y,z) -> z) ims) constraint)
1927− (filter clause ds)
1928− let (methods, imethods)
1929− = unzip (map (\ ( x,y,z) -> (x, y)) ims)
1930− let defaults = map (\ (x, (y, z)) -> (x,y)) defs
1931− addClass tn (CI cn (map nodoc imethods) defaults idecls (map fst ps) [])
1932− -- build instance constructor type
1933− -- decorate names of functions to ensure they can't be referred
1934− -- to elsewhere in the class declaration
1935− let cty = impbind ps $ conbind constraints
1936− $ pibind (map (\ (n, ty) -> (nsroot n, ty)) methods)
1937− constraint
1938− let cons = [(emptyDocstring, [], cn, cty, fc, [])]
1939− let ddecl = PDatadecl tn tty cons
1940− logLvl 5 $ "Class data " ++ show (showDImp verbosePPOption ddecl)
1941− elabData info (syn { no_imp = no_imp syn ++ mnames }) doc pDocs fc [] ddecl
1942− -- for each constraint, build a top level function to chase it
1943− logLvl 5 $ "Building functions"
1944−-- let usyn = syn { using = map (\ (x,y) -> UImplicit x y) ps
1945−-- ++ using syn }
1946− fns <- mapM (cfun cn constraint syn (map fst imethods)) constraints
1947− mapM_ (elabDecl EAll info) (concat fns)
1948− -- for each method, build a top level function
1949− fns <- mapM (tfun cn constraint syn (map fst imethods)) imethods
1950− mapM_ (elabDecl EAll info) (concat fns)
1951− -- add the default definitions
1952− mapM_ (elabDecl EAll info) (concat (map (snd.snd) defs))
1953− addIBC (IBCClass tn)
1954− where
1955− nodoc (n, (_, o, t)) = (n, (o, t))
1956− pibind [] x = x
1957− pibind ((n, ty): ns) x = PPi expl n ty (pibind ns x)
1958−
1959− mdec (UN n) = SN (MethodN (UN n))
1960− mdec (NS x n) = NS (mdec x) n
1961− mdec x = x
1962−
1963− -- TODO: probably should normalise
1964− checkDefaultSuperclassInstance (PInstance _ fc cs n ps _ _ _)
1965− = do when (not $ null cs) . tclift
1966− $ tfail (At fc (Msg $ "Default superclass instances can't have constraints."))
1967− i <- getIState
1968− let t = PApp fc (PRef fc n) (map pexp ps)
1969− let isConstrained = any (== t) constraints
1970− when (not isConstrained) . tclift
1971− $ tfail (At fc (Msg $ "Default instances must be for a superclass constraint on the containing class."))
1972− return ()
1973−
1974− impbind [] x = x
1975− impbind ((n, ty): ns) x = PPi impl n ty (impbind ns x)
1976− conbind (ty : ns) x = PPi constraint (sMN 0 "class") ty (conbind ns x)
1977− conbind [] x = x
1978−
1979− getMName (PTy _ _ _ _ _ n _) = nsroot n
1980− tdecl allmeths (PTy doc _ syn _ o n t)
1981− = do t' <- implicit' info syn allmeths n t
1982− logLvl 5 $ "Method " ++ show n ++ " : " ++ showTmImpls t'
1983− return ( (n, (toExp (map fst ps) Exp t')),
1984− (n, (doc, o, (toExp (map fst ps) Imp t'))),
1985− (n, (syn, o, t) ) )
1986− tdecl _ _ = ifail "Not allowed in a class declaration"
1987−
1988− -- Create default definitions
1989− defdecl mtys c d@(PClauses fc opts n cs) =
1990− case lookup n mtys of
1991− Just (syn, o, ty) -> do let ty' = insertConstraint c ty
1992− let ds = map (decorateid defaultdec)
1993− [PTy emptyDocstring [] syn fc [] n ty',
1994− PClauses fc (o ++ opts) n cs]
1995− iLOG (show ds)
1996− return (n, ((defaultdec n, ds!!1), ds))
1997− _ -> ifail $ show n ++ " is not a method"
1998− defdecl _ _ _ = ifail "Can't happen (defdecl)"
1999−
2000− defaultdec (UN n) = sUN ("default#" ++ str n)
2001− defaultdec (NS n ns) = NS (defaultdec n) ns
2002−
2003− tydecl (PTy _ _ _ _ _ _ _) = True
2004− tydecl _ = False
2005− instdecl (PInstance _ _ _ _ _ _ _ _) = True
2006− instdecl _ = False
2007− clause (PClauses _ _ _ _) = True
2008− clause _ = False
2009−
2010− -- Generate a function for chasing a dictionary constraint
2011− cfun cn c syn all con
2012− = do let cfn = sUN ('@':'@':show cn ++ "#" ++ show con)
2013− -- SN (ParentN cn (show con))
2014− let mnames = take (length all) $ map (\x -> sMN x "meth") [0..]
2015− let capp = PApp fc (PRef fc cn) (map (pexp . PRef fc) mnames)
2016− let lhs = PApp fc (PRef fc cfn) [pconst capp]
2017− let rhs = PResolveTC (fileFC "HACK")
2018− let ty = PPi constraint (sMN 0 "pc") c con
2019− iLOG (showTmImpls ty)
2020− iLOG (showTmImpls lhs ++ " = " ++ showTmImpls rhs)
2021− i <- getIState
2022− let conn = case con of
2023− PRef _ n -> n
2024− PApp _ (PRef _ n) _ -> n
2025− let conn' = case lookupCtxtName conn (idris_classes i) of
2026− [(n, _)] -> n
2027− _ -> conn
2028− addInstance False conn' cfn
2029− addIBC (IBCInstance False conn' cfn)
2030−-- iputStrLn ("Added " ++ show (conn, cfn, ty))
2031− return [PTy emptyDocstring [] syn fc [] cfn ty,
2032− PClauses fc [Dictionary] cfn [PClause fc cfn lhs [] rhs []]]
2033−
2034− -- Generate a top level function which looks up a method in a given
2035− -- dictionary (this is inlinable, always)
2036− tfun cn c syn all (m, (doc, o, ty))
2037− = do let ty' = insertConstraint c ty
2038− let mnames = take (length all) $ map (\x -> sMN x "meth") [0..]
2039− let capp = PApp fc (PRef fc cn) (map (pexp . PRef fc) mnames)
2040− let margs = getMArgs ty
2041− let anames = map (\x -> sMN x "arg") [0..]
2042− let lhs = PApp fc (PRef fc m) (pconst capp : lhsArgs margs anames)
2043− let rhs = PApp fc (getMeth mnames all m) (rhsArgs margs anames)
2044− iLOG (showTmImpls ty)
2045− iLOG (show (m, ty', capp, margs))
2046− iLOG (showTmImpls lhs ++ " = " ++ showTmImpls rhs)
2047− return [PTy doc [] syn fc o m ty',
2048− PClauses fc [Inlinable] m [PClause fc m lhs [] rhs []]]
2049−
2050− getMArgs (PPi (Imp _ _ _) n ty sc) = IA : getMArgs sc
2051− getMArgs (PPi (Exp _ _ _) n ty sc) = EA : getMArgs sc
2052− getMArgs (PPi (Constraint _ _) n ty sc) = CA : getMArgs sc
2053− getMArgs _ = []
2054−
2055− getMeth (m:ms) (a:as) x | x == a = PRef fc m
2056− | otherwise = getMeth ms as x
2057−
2058− lhsArgs (EA : xs) (n : ns) = [] -- pexp (PRef fc n) : lhsArgs xs ns
2059− lhsArgs (IA : xs) ns = lhsArgs xs ns
2060− lhsArgs (CA : xs) ns = lhsArgs xs ns
2061− lhsArgs [] _ = []
2062−
2063− rhsArgs (EA : xs) (n : ns) = [] -- pexp (PRef fc n) : rhsArgs xs ns
2064− rhsArgs (IA : xs) ns = pexp Placeholder : rhsArgs xs ns
2065− rhsArgs (CA : xs) ns = pconst (PResolveTC fc) : rhsArgs xs ns
2066− rhsArgs [] _ = []
2067−
2068− insertConstraint c (PPi p@(Imp _ _ _) n ty sc)
2069− = PPi p n ty (insertConstraint c sc)
2070− insertConstraint c sc = PPi constraint (sMN 0 "class") c sc
2071−
2072− -- make arguments explicit and don't bind class parameters
2073− toExp ns e (PPi (Imp l s p) n ty sc)
2074− | n `elem` ns = toExp ns e sc
2075− | otherwise = PPi (e l s p) n ty (toExp ns e sc)
2076− toExp ns e (PPi p n ty sc) = PPi p n ty (toExp ns e sc)
2077− toExp ns e sc = sc
2078−
2079−elabInstance :: ElabInfo -> SyntaxInfo ->
2080− ElabWhat -> -- phase
2081− FC -> [PTerm] -> -- constraints
2082− Name -> -- the class
2083− [PTerm] -> -- class parameters (i.e. instance)
2084− PTerm -> -- full instance type
2085− Maybe Name -> -- explicit name
2086− [PDecl] -> Idris ()
2087−elabInstance info syn what fc cs n ps t expn ds = do
2088− i <- getIState
2089− (n, ci) <- case lookupCtxtName n (idris_classes i) of
2090− [c] -> return c
2091− [] -> ifail $ show fc ++ ":" ++ show n ++ " is not a type class"
2092− cs -> tclift $ tfail $ At fc
2093− (CantResolveAlts (map fst cs))
2094− let constraint = PApp fc (PRef fc n) (map pexp ps)
2095− let iname = mkiname n ps expn
2096− let emptyclass = null (class_methods ci)
2097− when (what /= EDefns || (null ds && not emptyclass)) $ do
2098− nty <- elabType' True info syn emptyDocstring [] fc [] iname t
2099− -- if the instance type matches any of the instances we have already,
2100− -- and it's not a named instance, then it's overlapping, so report an error
2101− case expn of
2102− Nothing -> do mapM_ (maybe (return ()) overlapping . findOverlapping i (delab i nty))
2103− (class_instances ci)
2104− addInstance intInst n iname
2105− Just _ -> addInstance intInst n iname
2106− when (what /= ETypes && (not (null ds && not emptyclass))) $ do
2107− let ips = zip (class_params ci) ps
2108− let ns = case n of
2109− NS n ns' -> ns'
2110− _ -> []
2111− -- get the implicit parameters that need passing through to the
2112− -- where block
2113− wparams <- mapM (\p -> case p of
2114− PApp _ _ args -> getWParams (map getTm args)
2115− _ -> return []) ps
2116− let pnames = map pname (concat (nub wparams))
2117− let superclassInstances = map (substInstance ips pnames) (class_default_superclasses ci)
2118− undefinedSuperclassInstances <- filterM (fmap not . isOverlapping i) superclassInstances
2119− mapM_ (elabDecl EAll info) undefinedSuperclassInstances
2120− let all_meths = map (nsroot . fst) (class_methods ci)
2121− let mtys = map (\ (n, (op, t)) ->
2122− let t_in = substMatchesShadow ips pnames t
2123− mnamemap = map (\n -> (n, PRef fc (decorate ns iname n)))
2124− all_meths
2125− t' = substMatchesShadow mnamemap pnames t_in in
2126− (decorate ns iname n,
2127− op, coninsert cs t', t'))
2128− (class_methods ci)
2129− logLvl 3 (show (mtys, ips))
2130− let ds' = insertDefaults i iname (class_defaults ci) ns ds
2131− iLOG ("Defaults inserted: " ++ show ds' ++ "\n" ++ show ci)
2132− mapM_ (warnMissing ds' ns iname) (map fst (class_methods ci))
2133− mapM_ (checkInClass (map fst (class_methods ci))) (concatMap defined ds')
2134− let wbTys = map mkTyDecl mtys
2135− let wbVals = map (decorateid (decorate ns iname)) ds'
2136− let wb = wbTys ++ wbVals
2137− logLvl 3 $ "Method types " ++ showSep "\n" (map (show . showDeclImp verbosePPOption . mkTyDecl) mtys)
2138− logLvl 3 $ "Instance is " ++ show ps ++ " implicits " ++
2139− show (concat (nub wparams))
2140−
2141− -- Bring variables in instance head into scope
2142− ist <- getIState
2143− let headVars = nub $ mapMaybe (\p -> case p of
2144− PRef _ n ->
2145− case lookupTy n (tt_ctxt ist) of
2146− [] -> Just n
2147− _ -> Nothing
2148− _ -> Nothing) ps
2149−-- let lhs = PRef fc iname
2150− let lhs = PApp fc (PRef fc iname)
2151− (map (\n -> pimp n (PRef fc n) True) headVars)
2152− let rhs = PApp fc (PRef fc (instanceName ci))
2153− (map (pexp . mkMethApp) mtys)
2154−
2155− logLvl 5 $ "Instance LHS " ++ show lhs ++ " " ++ show headVars
2156− logLvl 5 $ "Instance RHS " ++ show rhs
2157−
2158− let idecls = [PClauses fc [Dictionary] iname
2159− [PClause fc iname lhs [] rhs wb]]
2160− iLOG (show idecls)
2161− mapM_ (elabDecl EAll info) idecls
2162− addIBC (IBCInstance intInst n iname)
2163−
2164− where
2165− intInst = case ps of
2166− [PConstant (AType (ATInt ITNative))] -> True
2167− _ -> False
2168−
2169− mkiname n' ps' expn' =
2170− case expn' of
2171− Nothing -> SN (sInstanceN n' (map show ps'))
2172− Just nm -> nm
2173−
2174− substInstance ips pnames (PInstance syn _ cs n ps t expn ds)
2175− = PInstance syn fc cs n (map (substMatchesShadow ips pnames) ps) (substMatchesShadow ips pnames t) expn ds
2176−
2177− isOverlapping i (PInstance syn _ _ n ps t expn _)
2178− = case lookupCtxtName n (idris_classes i) of
2179− [(n, ci)] -> let iname = (mkiname n ps expn) in
2180− case lookupTy iname (tt_ctxt i) of
2181− [] -> elabFindOverlapping i ci iname syn t
2182− (_:_) -> return True
2183− _ -> return False -- couldn't find class, just let elabInstance fail later
2184−
2185− -- TODO: largely based upon elabType' - should try to abstract
2186− elabFindOverlapping i ci iname syn t
2187− = do ty' <- addUsingConstraints syn fc t
2188− -- TODO think: something more in info?
2189− ty' <- implicit info syn iname ty'
2190− let ty = addImpl i ty'
2191− ctxt <- getContext
2192− ((tyT, _, _), _) <-
2193− tclift $ elaborate ctxt iname (TType (UVal 0)) []
2194− (errAt "type of " iname (erun fc (build i info ERHS [] iname ty)))
2195− ctxt <- getContext
2196− (cty, _) <- recheckC fc [] tyT
2197− let nty = normalise ctxt [] cty
2198− return $ any (isJust . findOverlapping i (delab i nty)) (class_instances ci)
2199−
2200− findOverlapping i t n
2201− | take 2 (show n) == "@@" = Nothing
2202− | otherwise
2203− = case lookupTy n (tt_ctxt i) of
2204− [t'] -> let tret = getRetType t
2205− tret' = getRetType (delab i t') in
2206− case matchClause i tret' tret of
2207− Right ms -> Just tret'
2208− Left _ -> case matchClause i tret tret' of
2209− Right ms -> Just tret'
2210− Left _ -> Nothing
2211− _ -> Nothing
2212− overlapping t' = tclift $ tfail (At fc (Msg $
2213− "Overlapping instance: " ++ show t' ++ " already defined"))
2214− getRetType (PPi _ _ _ sc) = getRetType sc
2215− getRetType t = t
2216−
2217− mkMethApp (n, _, _, ty)
2218− = lamBind 0 ty (papp fc (PRef fc n) (methArgs 0 ty))
2219− lamBind i (PPi (Constraint _ _) _ _ sc) sc'
2220− = PLam (sMN i "meth") Placeholder (lamBind (i+1) sc sc')
2221− lamBind i (PPi _ n ty sc) sc'
2222− = PLam (sMN i "meth") Placeholder (lamBind (i+1) sc sc')
2223− lamBind i _ sc = sc
2224− methArgs i (PPi (Imp _ _ _) n ty sc)
2225− = PImp 0 True [] n (PRef fc (sMN i "meth")) : methArgs (i+1) sc
2226− methArgs i (PPi (Exp _ _ _) n ty sc)
2227− = PExp 0 [] (sMN 0 "marg") (PRef fc (sMN i "meth")) : methArgs (i+1) sc
2228− methArgs i (PPi (Constraint _ _) n ty sc)
2229− = PConstraint 0 [] (sMN 0 "marg") (PResolveTC fc) : methArgs (i+1) sc
2230− methArgs i _ = []
2231−
2232− papp fc f [] = f
2233− papp fc f as = PApp fc f as
2234−
2235− getWParams [] = return []
2236− getWParams (p : ps)
2237− | PRef _ n <- p
2238− = do ps' <- getWParams ps
2239− ctxt <- getContext
2240− case lookupP n ctxt of
2241− [] -> return (pimp n (PRef fc n) True : ps')
2242− _ -> return ps'
2243− getWParams (_ : ps) = getWParams ps
2244−
2245− decorate ns iname (UN n) = NS (SN (MethodN (UN n))) ns
2246− decorate ns iname (NS (UN n) s) = NS (SN (MethodN (UN n))) ns
2247−
2248− mkTyDecl (n, op, t, _) = PTy emptyDocstring [] syn fc op n t
2249−
2250− conbind (ty : ns) x = PPi constraint (sMN 0 "class") ty (conbind ns x)
2251− conbind [] x = x
2252−
2253− coninsert cs (PPi p@(Imp _ _ _) n t sc) = PPi p n t (coninsert cs sc)
2254− coninsert cs sc = conbind cs sc
2255−
2256− insertDefaults :: IState -> Name ->
2257− [(Name, (Name, PDecl))] -> [T.Text] ->
2258− [PDecl] -> [PDecl]
2259− insertDefaults i iname [] ns ds = ds
2260− insertDefaults i iname ((n,(dn, clauses)) : defs) ns ds
2261− = insertDefaults i iname defs ns (insertDef i n dn clauses ns iname ds)
2262−
2263− insertDef i meth def clauses ns iname decls
2264− | null $ filter (clauseFor meth iname ns) decls
2265− = let newd = expandParamsD False i (\n -> meth) [] [def] clauses in
2266− -- trace (show newd) $
2267− decls ++ [newd]
2268− | otherwise = decls
2269−
2270− warnMissing decls ns iname meth
2271− | null $ filter (clauseFor meth iname ns) decls
2272− = iWarn fc . text $ "method " ++ show meth ++ " not defined"
2273− | otherwise = return ()
2274−
2275− checkInClass ns meth
2276− | not (null (filter (eqRoot meth) ns)) = return ()
2277− | otherwise = tclift $ tfail (At fc (Msg $
2278− show meth ++ " not a method of class " ++ show n))
2279−
2280− eqRoot x y = nsroot x == nsroot y
2281−
2282− clauseFor m iname ns (PClauses _ _ m' _)
2283− = decorate ns iname m == decorate ns iname m'
2284− clauseFor m iname ns _ = False
2285−
2286−{- This won't work yet. Can it ever, in this form?
2287−
2288− cfun cn c syn all con
2289− = do let cfn = UN ('@':'@':show cn ++ "#" ++ show con)
2290− let mnames = take (length all) $ map (\x -> MN x "meth") [0..]
2291− let capp = PApp fc (PRef fc cn) (map (pexp . PRef fc) mnames)
2292− let lhs = PApp fc (PRef fc cfn) [pconst capp]
2293− let rhs = PResolveTC (FC "HACK" 0)
2294− let ty = PPi constraint (MN 0 "pc") c con
2295− iLOG (showImp True ty)
2296− iLOG (showImp True lhs ++ " = " ++ showImp True rhs)
2297− i <- getIState
2298− let conn = case con of
2299− PRef _ n -> n
2300− PApp _ (PRef _ n) _ -> n
2301− let conn' = case lookupCtxtName Nothing conn (idris_classes i) of
2302− [(n, _)] -> n
2303− _ -> conn
2304− addInstance False conn' cfn
2305− addIBC (IBCInstance False conn' cfn)
2306− iputStrLn ("Added " ++ show (conn, cfn, ty) ++ "\n" ++ show (lhs, rhs))
2307− return [PTy "" syn fc [] cfn ty,
2308− PClauses fc [Dictionary] cfn [PClause fc cfn lhs [] rhs []]]
2309−-}
2310−
2311−decorateid decorate (PTy doc argdocs s f o n t) = PTy doc argdocs s f o (decorate n) t
2312−decorateid decorate (PClauses f o n cs)
2313− = PClauses f o (decorate n) (map dc cs)
2314− where dc (PClause fc n t as w ds) = PClause fc (decorate n) (dappname t) as w ds
2315− dc (PWith fc n t as w ds)
2316− = PWith fc (decorate n) (dappname t) as w
2317− (map (decorateid decorate) ds)
2318− dappname (PApp fc (PRef fc' n) as) = PApp fc (PRef fc' (decorate n)) as
2319− dappname t = t
2320−
2321−
2322−-- if 't' is a type class application, assume its arguments are injective
2323−pbinds :: IState -> Term -> ElabD ()
2324−pbinds i (Bind n (PVar t) sc)
2325− = do attack; patbind n
2326− case unApply t of
2327− (P _ c _, args) -> case lookupCtxt c (idris_classes i) of
2328− [] -> return ()
2329− _ -> -- type class, set as injective
2330− mapM_ setinjArg args
2331− _ -> return ()
2332− pbinds i sc
2333− where setinjArg (P _ n _) = setinj n
2334− setinjArg _ = return ()
2335−pbinds i tm = return ()
2336−
2337−pbty (Bind n (PVar t) sc) tm = Bind n (PVTy t) (pbty sc tm)
2338−pbty _ tm = tm
2339−
2340−getPBtys (Bind n (PVar t) sc) = (n, t) : getPBtys sc
2341−getPBtys (Bind n (PVTy t) sc) = (n, t) : getPBtys sc
2342−getPBtys _ = []
2343−
2344−psolve (Bind n (PVar t) sc) = do solve; psolve sc
2345−psolve tm = return ()
2346−
2347−pvars ist (Bind n (PVar t) sc) = (n, delab ist t) : pvars ist sc
2348−pvars ist _ = []
2349−
2350−data ElabWhat = ETypes | EDefns | EAll
2351− deriving (Show, Eq)
2352−
2353elabDecls :: ElabInfo -> [PDecl] -> Idris ()
169elabDecls :: ElabInfo -> [PDecl] -> Idris ()
2354elabDecls info ds = do mapM_ (elabDecl EAll info) ds
170elabDecls info ds = do mapM_ (elabDecl EAll info) ds
2355−-- mapM_ (elabDecl EDefns info) ds
2356
171
2357elabDecl :: ElabWhat -> ElabInfo -> PDecl -> Idris ()
172elabDecl :: ElabWhat -> ElabInfo -> PDecl -> Idris ()
2358elabDecl what info d
173elabDecl what info d
174+ = let info' = info { rec_elabDecl = elabDecl' } in
2359− = idrisCatch (withErrorReflection $ elabDecl' what info d) (setAndReport)
175+ idrisCatch (withErrorReflection $ elabDecl' what info' d) (setAndReport)
2360
176
2361elabDecl' _ info (PFix _ _ _)
177elabDecl' _ info (PFix _ _ _)
2362 = return () -- nothing to elaborate
178 = return () -- nothing to elaborate
@@ -2464,54 +280,3 @@ elabDecl' what info (PTransform fc safety old new)
2464 = elabTransform info fc safety old new
280 = elabTransform info fc safety old new
2465elabDecl' _ _ _ = return () -- skipped this time
281elabDecl' _ _ _ = return () -- skipped this time
2466
282
2467−elabCaseBlock info opts d@(PClauses f o n ps)
2468− = do addIBC (IBCDef n)
2469− logLvl 5 $ "CASE BLOCK: " ++ show (n, d)
2470− let opts' = nub (o ++ opts)
2471− -- propagate totality assertion to the new definitions
2472− when (AssertTotal `elem` opts) $ setFlags n [AssertTotal]
2473− elabDecl' EAll info (PClauses f opts' n ps )
2474−
2475−-- elabDecl' info (PImport i) = loadModule i
2476−
2477−-- Check that the result of type checking matches what the programmer wrote
2478−-- (i.e. - if we inferred any arguments that the user provided, make sure
2479−-- they are the same!)
2480−
2481−checkInferred :: FC -> PTerm -> PTerm -> Idris ()
2482−checkInferred fc inf user =
2483− do logLvl 6 $ "Checked to\n" ++ showTmImpls inf ++ "\n\nFROM\n\n" ++
2484− showTmImpls user
2485− logLvl 10 $ "Checking match"
2486− i <- getIState
2487− tclift $ case matchClause' True i user inf of
2488− _ -> return ()
2489−-- Left (x, y) -> tfail $ At fc
2490−-- (Msg $ "The type-checked term and given term do not match: "
2491−-- ++ show x ++ " and " ++ show y)
2492− logLvl 10 $ "Checked match"
2493−-- ++ "\n" ++ showImp True inf ++ "\n" ++ showImp True user)
2494−
2495−-- Return whether inferred term is different from given term
2496−-- (as above, but return a Bool)
2497−
2498−inferredDiff :: FC -> PTerm -> PTerm -> Idris Bool
2499−inferredDiff fc inf user =
2500− do i <- getIState
2501− logLvl 6 $ "Checked to\n" ++ showTmImpls inf ++ "\n" ++
2502− showTmImpls user
2503− tclift $ case matchClause' True i user inf of
2504− Right vs -> return False
2505− Left (x, y) -> return True
2506−
2507−-- | Check a PTerm against documentation and ensure that every documented
2508−-- argument actually exists. This must be run _after_ implicits have been
2509−-- found, or it will give spurious errors.
2510−checkDocs :: FC -> [(Name, Docstring)] -> PTerm -> Idris ()
2511−checkDocs fc args tm = cd (Map.fromList args) tm
2512− where cd as (PPi _ n _ sc) = cd (Map.delete n as) sc
2513− cd as _ | Map.null as = return ()
2514− | otherwise = ierror . At fc . Msg $
2515− "There is documentation for argument(s) "
2516− ++ (concat . intersperse ", " . map show . Map.keys) as
2517− ++ " but they were not found."
src/Idris/ElabTerm.hs+79−24
@@ -17,6 +17,7 @@ import Idris.Core.Unify
17import Idris.Core.Typecheck (check, recheck)
17import Idris.Core.Typecheck (check, recheck)
18import Idris.ErrReverse (errReverse)
18import Idris.ErrReverse (errReverse)
19import Idris.ElabQuasiquote (extractUnquotes)
19import Idris.ElabQuasiquote (extractUnquotes)
20+import qualified Util.Pretty as U
20
21
21import Control.Applicative ((<$>))
22import Control.Applicative ((<$>))
22import Control.Monad
23import Control.Monad
@@ -26,6 +27,8 @@ import qualified Data.Map as M
26import Data.Maybe (mapMaybe, fromMaybe)
27import Data.Maybe (mapMaybe, fromMaybe)
27import qualified Data.Set as S
28import qualified Data.Set as S
28import qualified Data.Text as T
29import qualified Data.Text as T
30+import Data.Vector.Unboxed (Vector)
31+import qualified Data.Vector.Unboxed as V
29
32
30import Debug.Trace
33import Debug.Trace
31
34
@@ -142,6 +145,7 @@ elab ist info emode opts fn tm
142 compute -- expand type synonyms, etc
145 compute -- expand type synonyms, etc
143 elabE (False, False, False, False) tm -- (in argument, guarded, in type, in qquote)
146 elabE (False, False, False, False) tm -- (in argument, guarded, in type, in qquote)
144 end_unify
147 end_unify
148+ ptm <- get_term
145 when pattern -- convert remaining holes to pattern vars
149 when pattern -- convert remaining holes to pattern vars
146 (do update_term orderPats
150 (do update_term orderPats
147 unify_all
151 unify_all
@@ -688,7 +692,6 @@ elab ist info emode opts fn tm
688 (caseBlock fc cname'
692 (caseBlock fc cname'
689 (map (isScr scr) (reverse args)) opts)
693 (map (isScr scr) (reverse args)) opts)
690 -- elaborate case
694 -- elaborate case
691− env <- get_env
692 updateAux (newdef : )
695 updateAux (newdef : )
693 -- if we haven't got the type yet, hopefully we'll get it later!
696 -- if we haven't got the type yet, hopefully we'll get it later!
694 movelast tyn
697 movelast tyn
@@ -853,9 +856,23 @@ elab ist info emode opts fn tm
853 addImplBound ist (map fst env) (PApp fc (PRef fc (sUN "Delay"))
856 addImplBound ist (map fst env) (PApp fc (PRef fc (sUN "Delay"))
854 [pexp t])
857 [pexp t])
855
858
859+
860+ -- Don't put implicit coercions around applications which are marked
861+ -- as '%noImplicit', or around case blocks, otherwise we get exponential
862+ -- blowup especially where there are errors deep in large expressions.
863+ notImplicitable (PApp _ f _) = notImplicitable f
864+ -- TMP HACK no coercing on bind (make this configurable)
865+ notImplicitable (PRef _ n)
866+ | [opts] <- lookupCtxt n (idris_flags ist)
867+ = NoImplicit `elem` opts
868+ notImplicitable (PAlternative True as) = any notImplicitable as
856 -- case is tricky enough without implicit coercions! If they are needed,
869 -- case is tricky enough without implicit coercions! If they are needed,
857 -- they can go in the branches separately.
870 -- they can go in the branches separately.
871+ notImplicitable (PCase _ _ _) = True
872+ notImplicitable _ = False
873+
858 insertCoerce ina t@(PCase _ _ _) = return t
874 insertCoerce ina t@(PCase _ _ _) = return t
875+ insertCoerce ina t | notImplicitable t = return t
859 insertCoerce ina t =
876 insertCoerce ina t =
860 do ty <- goal
877 do ty <- goal
861 -- Check for possible coercions to get to the goal
878 -- Check for possible coercions to get to the goal
@@ -889,7 +906,7 @@ elab ist info emode opts fn tm
889 elabArgs ist ina failed fc r f (n:ns) force (Placeholder : args)
906 elabArgs ist ina failed fc r f (n:ns) force (Placeholder : args)
890 = elabArgs ist ina failed fc r f ns force args
907 = elabArgs ist ina failed fc r f ns force args
891 elabArgs ist ina failed fc r f ((argName, holeName):ns) force (t : args)
908 elabArgs ist ina failed fc r f ((argName, holeName):ns) force (t : args)
892− = do elabArg argName holeName t
909+ = elabArg argName holeName t
893 where elabArg argName holeName t =
910 where elabArg argName holeName t =
894 do now_elaborating fc f argName
911 do now_elaborating fc f argName
895 wrapErr f argName $ do
912 wrapErr f argName $ do
@@ -1559,15 +1576,7 @@ reifyTTBinderApp reif f [t]
1559reifyTTBinderApp _ f args = fail ("Unknown reflection binder: " ++ show (f, args))
1576reifyTTBinderApp _ f args = fail ("Unknown reflection binder: " ++ show (f, args))
1560
1577
1561reifyTTConst :: Term -> ElabD Const
1578reifyTTConst :: Term -> ElabD Const
1562−reifyTTConst (P _ n _) | n == reflm "IType" = return (AType (ATInt ITNative))
1563−reifyTTConst (P _ n _) | n == reflm "BIType" = return (AType (ATInt ITBig))
1564−reifyTTConst (P _ n _) | n == reflm "FlType" = return (AType ATFloat)
1565−reifyTTConst (P _ n _) | n == reflm "ChType" = return (AType (ATInt ITChar))
1566reifyTTConst (P _ n _) | n == reflm "StrType" = return $ StrType
1579reifyTTConst (P _ n _) | n == reflm "StrType" = return $ StrType
1567−reifyTTConst (P _ n _) | n == reflm "B8Type" = return (AType (ATInt (ITFixed IT8)))
1568−reifyTTConst (P _ n _) | n == reflm "B16Type" = return (AType (ATInt (ITFixed IT16)))
1569−reifyTTConst (P _ n _) | n == reflm "B32Type" = return (AType (ATInt (ITFixed IT32)))
1570−reifyTTConst (P _ n _) | n == reflm "B64Type" = return (AType (ATInt (ITFixed IT64)))
1571reifyTTConst (P _ n _) | n == reflm "PtrType" = return $ PtrType
1580reifyTTConst (P _ n _) | n == reflm "PtrType" = return $ PtrType
1572reifyTTConst (P _ n _) | n == reflm "VoidType" = return $ VoidType
1581reifyTTConst (P _ n _) | n == reflm "VoidType" = return $ VoidType
1573reifyTTConst (P _ n _) | n == reflm "Forgot" = return $ Forgot
1582reifyTTConst (P _ n _) | n == reflm "Forgot" = return $ Forgot
@@ -1576,6 +1585,8 @@ reifyTTConst t@(App _ _)
1576reifyTTConst t = fail ("Unknown reflection constant: " ++ show t)
1585reifyTTConst t = fail ("Unknown reflection constant: " ++ show t)
1577
1586
1578reifyTTConstApp :: Name -> Term -> ElabD Const
1587reifyTTConstApp :: Name -> Term -> ElabD Const
1588+reifyTTConstApp f aty
1589+ | f == reflm "AType" = fmap AType (reifyArithTy aty)
1579reifyTTConstApp f (Constant c@(I _))
1590reifyTTConstApp f (Constant c@(I _))
1580 | f == reflm "I" = return $ c
1591 | f == reflm "I" = return $ c
1581reifyTTConstApp f (Constant c@(BI _))
1592reifyTTConstApp f (Constant c@(BI _))
@@ -1596,6 +1607,26 @@ reifyTTConstApp f (Constant c@(B64 _))
1596 | f == reflm "B64" = return $ c
1607 | f == reflm "B64" = return $ c
1597reifyTTConstApp f arg = fail ("Unknown reflection constant: " ++ show (f, arg))
1608reifyTTConstApp f arg = fail ("Unknown reflection constant: " ++ show (f, arg))
1598
1609
1610+reifyArithTy :: Term -> ElabD ArithTy
1611+reifyArithTy (App (P _ n _) intTy) | n == reflm "ATInt" = fmap ATInt (reifyIntTy intTy)
1612+reifyArithTy (P _ n _) | n == reflm "ATFloat" = return ATFloat
1613+reifyArithTy x = fail ("Couldn't reify reflected ArithTy: " ++ show x)
1614+
1615+reifyNativeTy :: Term -> ElabD NativeTy
1616+reifyNativeTy (P _ n _) | n == reflm "IT8" = return IT8
1617+reifyNativeTy (P _ n _) | n == reflm "IT8" = return IT8
1618+reifyNativeTy (P _ n _) | n == reflm "IT8" = return IT8
1619+reifyNativeTy (P _ n _) | n == reflm "IT8" = return IT8
1620+reifyNativeTy x = fail $ "Couldn't reify reflected NativeTy " ++ show x
1621+
1622+reifyIntTy :: Term -> ElabD IntTy
1623+reifyIntTy (App (P _ n _) nt) | n == reflm "ITFixed" = fmap ITFixed (reifyNativeTy nt)
1624+reifyIntTy (P _ n _) | n == reflm "ITNative" = return ITNative
1625+reifyIntTy (P _ n _) | n == reflm "ITBig" = return ITBig
1626+reifyIntTy (P _ n _) | n == reflm "ITChar" = return ITChar
1627+reifyIntTy (App (App (P _ n _) nt) (Constant (I i))) | n == reflm "ITVec" = fmap (flip ITVec i)
1628+ (reifyNativeTy nt)
1629+
1599reifyTTUExp :: Term -> ElabD UExp
1630reifyTTUExp :: Term -> ElabD UExp
1600reifyTTUExp t@(App _ _)
1631reifyTTUExp t@(App _ _)
1601 = case unApply t of
1632 = case unApply t of
@@ -1790,8 +1821,9 @@ reflectName (MN i n)
1790reflectName (NErased) = Var (reflm "NErased")
1821reflectName (NErased) = Var (reflm "NErased")
1791reflectName n = Var (reflm "NErased") -- special name, not yet implemented
1822reflectName n = Var (reflm "NErased") -- special name, not yet implemented
1792
1823
1793−-- | Elaborate a name to a pattern. This means that NS and UN will be intact,
1824+-- | Elaborate a name to a pattern. This means that NS and UN will be intact.
1825+-- MNs corresponding to will care about the string but not the number. All
1794−-- while all others become _
1826+-- others become _.
1795reflectNameQuotePattern :: Name -> ElabD ()
1827reflectNameQuotePattern :: Name -> ElabD ()
1796reflectNameQuotePattern n@(UN s)
1828reflectNameQuotePattern n@(UN s)
1797 = do fill $ reflectName n
1829 = do fill $ reflectName n
@@ -1799,6 +1831,12 @@ reflectNameQuotePattern n@(UN s)
1799reflectNameQuotePattern n@(NS _ _)
1831reflectNameQuotePattern n@(NS _ _)
1800 = do fill $ reflectName n
1832 = do fill $ reflectName n
1801 solve
1833 solve
1834+reflectNameQuotePattern (MN _ n)
1835+ = do i <- getNameFrom (sMN 0 "mnCounter")
1836+ claim i (RConstant (AType (ATInt ITNative)))
1837+ movelast i
1838+ fill $ reflCall "MN" [Var i, RConstant (Str $ T.unpack n)]
1839+ solve
1802reflectNameQuotePattern _ -- for all other names, match any
1840reflectNameQuotePattern _ -- for all other names, match any
1803 = do nameHole <- getNameFrom (sMN 0 "name")
1841 = do nameHole <- getNameFrom (sMN 0 "name")
1804 claim nameHole (Var (reflm "TTName"))
1842 claim nameHole (Var (reflm "TTName"))
@@ -1829,28 +1867,45 @@ reflectBinderQuote unq (PVar t)
1829reflectBinderQuote unq (PVTy t)
1867reflectBinderQuote unq (PVTy t)
1830 = reflCall "PVTy" [Var (reflm "TT"), reflectQuote unq t]
1868 = reflCall "PVTy" [Var (reflm "TT"), reflectQuote unq t]
1831
1869
1870+mkList :: Raw -> [Raw] -> Raw
1871+mkList ty [] = RApp (Var (sNS (sUN "Nil") ["List", "Prelude"])) ty
1872+mkList ty (x:xs) = RApp (RApp (RApp (Var (sNS (sUN "::") ["List", "Prelude"])) ty)
1873+ x)
1874+ (mkList ty xs)
1875+
1832reflectConstant :: Const -> Raw
1876reflectConstant :: Const -> Raw
1833reflectConstant c@(I _) = reflCall "I" [RConstant c]
1877reflectConstant c@(I _) = reflCall "I" [RConstant c]
1834reflectConstant c@(BI _) = reflCall "BI" [RConstant c]
1878reflectConstant c@(BI _) = reflCall "BI" [RConstant c]
1835reflectConstant c@(Fl _) = reflCall "Fl" [RConstant c]
1879reflectConstant c@(Fl _) = reflCall "Fl" [RConstant c]
1836reflectConstant c@(Ch _) = reflCall "Ch" [RConstant c]
1880reflectConstant c@(Ch _) = reflCall "Ch" [RConstant c]
1837reflectConstant c@(Str _) = reflCall "Str" [RConstant c]
1881reflectConstant c@(Str _) = reflCall "Str" [RConstant c]
1838−reflectConstant (AType (ATInt ITNative)) = Var (reflm "IType")
1839−reflectConstant (AType (ATInt ITBig)) = Var (reflm "BIType")
1840−reflectConstant (AType ATFloat) = Var (reflm "FlType")
1841−reflectConstant (AType (ATInt ITChar)) = Var (reflm "ChType")
1842−reflectConstant (StrType) = Var (reflm "StrType")
1843reflectConstant c@(B8 _) = reflCall "B8" [RConstant c]
1882reflectConstant c@(B8 _) = reflCall "B8" [RConstant c]
1844reflectConstant c@(B16 _) = reflCall "B16" [RConstant c]
1883reflectConstant c@(B16 _) = reflCall "B16" [RConstant c]
1845reflectConstant c@(B32 _) = reflCall "B32" [RConstant c]
1884reflectConstant c@(B32 _) = reflCall "B32" [RConstant c]
1846reflectConstant c@(B64 _) = reflCall "B64" [RConstant c]
1885reflectConstant c@(B64 _) = reflCall "B64" [RConstant c]
1886+reflectConstant (B8V ws) = reflCall "B8V" [mkList (Var (sUN "Bits8")) . map (RConstant . B8) . V.toList $ ws]
1887+reflectConstant (B16V ws) = reflCall "B8V" [mkList (Var (sUN "Bits16")) . map (RConstant . B16) . V.toList $ ws]
1888+reflectConstant (B32V ws) = reflCall "B8V" [mkList (Var (sUN "Bits32")) . map (RConstant . B32) . V.toList $ ws]
1889+reflectConstant (B64V ws) = reflCall "B8V" [mkList (Var (sUN "Bits64")) . map (RConstant . B64) . V.toList $ ws]
1890+reflectConstant (AType (ATInt ITNative)) = reflCall "AType" [reflCall "ATInt" [Var (reflm "ITNative")]]
1891+reflectConstant (AType (ATInt ITBig)) = reflCall "AType" [reflCall "ATInt" [Var (reflm "ITBig")]]
1892+reflectConstant (AType ATFloat) = reflCall "AType" [Var (reflm "ATFloat")]
1893+reflectConstant (AType (ATInt ITChar)) = reflCall "AType" [reflCall "ATInt" [Var (reflm "ITChar")]]
1894+reflectConstant StrType = Var (reflm "StrType")
1847−reflectConstant (AType (ATInt (ITFixed IT8))) = Var (reflm "B8Type")
1895+reflectConstant (AType (ATInt (ITFixed IT8))) = reflCall "AType" [reflCall "ATInt" [reflCall "ITFixed" [Var (reflm "IT8")]]]
1848−reflectConstant (AType (ATInt (ITFixed IT16))) = Var (reflm "B16Type")
1896+reflectConstant (AType (ATInt (ITFixed IT16))) = reflCall "AType" [reflCall "ATInt" [reflCall "ITFixed" [Var (reflm "IT16")]]]
1849−reflectConstant (AType (ATInt (ITFixed IT32))) = Var (reflm "B32Type")
1897+reflectConstant (AType (ATInt (ITFixed IT32))) = reflCall "AType" [reflCall "ATInt" [reflCall "ITFixed" [Var (reflm "IT32")]]]
1850−reflectConstant (AType (ATInt (ITFixed IT64))) = Var (reflm "B64Type")
1898+reflectConstant (AType (ATInt (ITFixed IT64))) = reflCall "AType" [reflCall "ATInt" [reflCall "ITFixed" [Var (reflm "IT64")]]]
1851−reflectConstant (PtrType) = Var (reflm "PtrType")
1899+reflectConstant (AType (ATInt (ITVec IT8 c))) = reflCall "AType" [reflCall "ATInt" [reflCall "ITVec" [Var (reflm "IT8"), RConstant (I c)]]]
1900+reflectConstant (AType (ATInt (ITVec IT16 c))) = reflCall "AType" [reflCall "ATInt" [reflCall "ITVec" [Var (reflm "IT16"), RConstant (I c)]]]
1901+reflectConstant (AType (ATInt (ITVec IT32 c))) = reflCall "AType" [reflCall "ATInt" [reflCall "ITVec" [Var (reflm "IT32"), RConstant (I c)]]]
1902+reflectConstant (AType (ATInt (ITVec IT64 c))) = reflCall "AType" [reflCall "ATInt" [reflCall "ITVec" [Var (reflm "IT64"), RConstant (I c)]]]
1903+reflectConstant PtrType = Var (reflm "PtrType")
1904+reflectConstant ManagedPtrType = Var (reflm "ManagedPtrType")
1905+reflectConstant BufferType = Var (reflm "BufferType")
1852−reflectConstant (VoidType) = Var (reflm "VoidType")
1906+reflectConstant VoidType = Var (reflm "VoidType")
1853−reflectConstant (Forgot) = Var (reflm "Forgot")
1907+reflectConstant Forgot = Var (reflm "Forgot")
1908+
1854
1909
1855reflectUExp :: UExp -> Raw
1910reflectUExp :: UExp -> Raw
1856reflectUExp (UVar i) = reflCall "UVar" [RConstant (I i)]
1911reflectUExp (UVar i) = reflCall "UVar" [RConstant (I i)]
src/Idris/Error.hs+2−3
@@ -42,12 +42,11 @@ idrisCatch = catchError
42
42
43setAndReport :: Err -> Idris ()
43setAndReport :: Err -> Idris ()
44setAndReport e = do ist <- getIState
44setAndReport e = do ist <- getIState
45− let h = idris_outh ist
46 case (unwrap e) of
45 case (unwrap e) of
47 At fc e -> do setErrSpan fc
46 At fc e -> do setErrSpan fc
48− ihWarn h fc $ pprintErr ist e
47+ iWarn fc $ pprintErr ist e
49 _ -> do setErrSpan (getErrSpan e)
48 _ -> do setErrSpan (getErrSpan e)
50− ihWarn h emptyFC $ pprintErr ist e
49+ iWarn emptyFC $ pprintErr ist e
51 where unwrap (ProofSearchFail e) = e -- remove bookkeeping constructor
50 where unwrap (ProofSearchFail e) = e -- remove bookkeeping constructor
52 unwrap e = e
51 unwrap e = e
53
52
src/Idris/IBC.hs+3
@@ -274,6 +274,7 @@ process i fn
274 pDefs (symbols i) (ibc_defs i)
274 pDefs (symbols i) (ibc_defs i)
275 pPatdefs (ibc_patdefs i)
275 pPatdefs (ibc_patdefs i)
276 pAccess (ibc_access i)
276 pAccess (ibc_access i)
277+ pFlags (ibc_flags i)
277 pTotal (ibc_total i)
278 pTotal (ibc_total i)
278 pTotCheckErr (ibc_totcheckfail i)
279 pTotCheckErr (ibc_totcheckfail i)
279 pCG (ibc_cg i)
280 pCG (ibc_cg i)
@@ -943,6 +944,7 @@ instance Binary FnOpt where
943 ErrorHandler -> putWord8 9
944 ErrorHandler -> putWord8 9
944 ErrorReverse -> putWord8 10
945 ErrorReverse -> putWord8 10
945 CoveringFn -> putWord8 11
946 CoveringFn -> putWord8 11
947+ NoImplicit -> putWord8 12
946 get
948 get
947 = do i <- getWord8
949 = do i <- getWord8
948 case i of
950 case i of
@@ -959,6 +961,7 @@ instance Binary FnOpt where
959 9 -> return ErrorHandler
961 9 -> return ErrorHandler
960 10 -> return ErrorReverse
962 10 -> return ErrorReverse
961 11 -> return CoveringFn
963 11 -> return CoveringFn
964+ 12 -> return NoImplicit
962 _ -> error "Corrupted binary data for FnOpt"
965 _ -> error "Corrupted binary data for FnOpt"
963
966
964instance Binary Fixity where
967instance Binary Fixity where
src/Idris/IdeSlave.hs+20−10
@@ -1,6 +1,6 @@
1{-# LANGUAGE FlexibleInstances, IncoherentInstances, PatternGuards #-}
1{-# LANGUAGE FlexibleInstances, IncoherentInstances, PatternGuards #-}
2
2
3−module Idris.IdeSlave(parseMessage, convSExp, IdeSlaveCommand(..), sexpToCommand, toSExp, SExp(..), SExpable, Opt(..)) where
3+module Idris.IdeSlave(parseMessage, convSExp, IdeSlaveCommand(..), sexpToCommand, toSExp, SExp(..), SExpable, Opt(..), ideSlaveEpoch, getLen, getNChar) where
4
4
5import Text.Printf
5import Text.Printf
6import Numeric
6import Numeric
@@ -12,12 +12,24 @@ import qualified Data.ByteString.UTF8 as UTF8
12-- import qualified Data.Text as T
12-- import qualified Data.Text as T
13import Text.Trifecta hiding (Err)
13import Text.Trifecta hiding (Err)
14import Text.Trifecta.Delta
14import Text.Trifecta.Delta
15+import System.IO
15
16
16import Idris.Core.TT
17import Idris.Core.TT
17import Idris.Core.Binary
18import Idris.Core.Binary
18
19
19import Control.Applicative hiding (Const)
20import Control.Applicative hiding (Const)
20
21
22+getNChar :: Handle -> Int -> String -> IO (String)
23+getNChar _ 0 s = return (reverse s)
24+getNChar h n s = do c <- hGetChar h
25+ getNChar h (n - 1) (c : s)
26+
27+getLen :: Handle -> IO (Either Err Int)
28+getLen h = do s <- getNChar h 6 ""
29+ case readHex s of
30+ ((num, ""):_) -> return $ Right num
31+ _ -> return $ Left . Msg $ "Couldn't read length " ++ s
32+
21data SExp = SexpList [SExp]
33data SExp = SexpList [SExp]
22 | StringAtom String
34 | StringAtom String
23 | BoolAtom Bool
35 | BoolAtom Bool
@@ -247,19 +259,14 @@ sexpToCommand _
247parseMessage :: String -> Either Err (SExp, Integer)
259parseMessage :: String -> Either Err (SExp, Integer)
248parseMessage x = case receiveString x of
260parseMessage x = case receiveString x of
249 Right (SexpList [cmd, (IntegerAtom id)]) -> Right (cmd, id)
261 Right (SexpList [cmd, (IntegerAtom id)]) -> Right (cmd, id)
262+ Right x -> Left . Msg $ "Invalid message " ++ show x
250 Left err -> Left err
263 Left err -> Left err
251
264
252receiveString :: String -> Either Err SExp
265receiveString :: String -> Either Err SExp
253receiveString x =
266receiveString x =
254− case readHex (take 6 x) of
255− ((num, ""):_) ->
256− let msg = drop 6 x in
257− if (length msg) /= (num - 1)
258− then Left . Msg $ "bad input length"
259− else (case parseSExp msg of
267+ case parseSExp x of
260− Failure _ -> Left . Msg $ "parse failure"
268+ Failure _ -> Left . Msg $ "parse failure"
261− Success r -> Right r)
269+ Success r -> Right r
262− _ -> Left . Msg $ "readHex failed"
263
270
264convSExp :: SExpable a => String -> a -> Integer -> String
271convSExp :: SExpable a => String -> a -> Integer -> String
265convSExp pre s id =
272convSExp pre s id =
@@ -269,3 +276,6 @@ convSExp pre s id =
269
276
270getHexLength :: String -> String
277getHexLength :: String -> String
271getHexLength s = printf "%06x" (1 + (length s))
278getHexLength s = printf "%06x" (1 + (length s))
279+
280+ideSlaveEpoch :: Int
281+ideSlaveEpoch = 1
src/Idris/Interactive.hs+31−29
@@ -18,6 +18,8 @@ import Idris.Delaborate
18import Idris.Output
18import Idris.Output
19import Idris.IdeSlave hiding (IdeSlaveCommand(..))
19import Idris.IdeSlave hiding (IdeSlaveCommand(..))
20
20
21+import Idris.Elab.Value
22+
21import Util.Pretty
23import Util.Pretty
22import Util.System
24import Util.System
23
25
@@ -29,8 +31,8 @@ import Data.Maybe (fromMaybe)
29
31
30import Debug.Trace
32import Debug.Trace
31
33
32−caseSplitAt :: Handle -> FilePath -> Bool -> Int -> Name -> Idris ()
34+caseSplitAt :: FilePath -> Bool -> Int -> Name -> Idris ()
33−caseSplitAt h fn updatefile l n
35+caseSplitAt fn updatefile l n
34 = do src <- runIO $ readFile fn
36 = do src <- runIO $ readFile fn
35 res <- splitOnLine l n fn
37 res <- splitOnLine l n fn
36 iLOG (showSep "\n" (map show res))
38 iLOG (showSep "\n" (map show res))
@@ -41,11 +43,11 @@ caseSplitAt h fn updatefile l n
41 then do let fb = fn ++ "~" -- make a backup!
43 then do let fb = fn ++ "~" -- make a backup!
42 runIO $ writeFile fb (unlines before ++ new ++ unlines later)
44 runIO $ writeFile fb (unlines before ++ new ++ unlines later)
43 runIO $ copyFile fb fn
45 runIO $ copyFile fb fn
44− else -- do ihputStrLn h (show res)
46+ else -- do iputStrLn (show res)
45− ihPrintResult h new
47+ iPrintResult new
46
48
47−addClauseFrom :: Handle -> FilePath -> Bool -> Int -> Name -> Idris ()
49+addClauseFrom :: FilePath -> Bool -> Int -> Name -> Idris ()
48−addClauseFrom h fn updatefile l n
50+addClauseFrom fn updatefile l n
49 = do src <- runIO $ readFile fn
51 = do src <- runIO $ readFile fn
50 let (before, tyline : later) = splitAt (l-1) (lines src)
52 let (before, tyline : later) = splitAt (l-1) (lines src)
51 let indent = getIndent 0 (show n) tyline
53 let indent = getIndent 0 (show n) tyline
@@ -59,15 +61,15 @@ addClauseFrom h fn updatefile l n
59 cl ++ "\n" ++
61 cl ++ "\n" ++
60 unlines rest)
62 unlines rest)
61 runIO $ copyFile fb fn
63 runIO $ copyFile fb fn
62− else ihPrintResult h cl
64+ else iPrintResult cl
63 where
65 where
64 getIndent i n [] = 0
66 getIndent i n [] = 0
65 getIndent i n xs | take 9 xs == "instance " = i
67 getIndent i n xs | take 9 xs == "instance " = i
66 getIndent i n xs | take (length n) xs == n = i
68 getIndent i n xs | take (length n) xs == n = i
67 getIndent i n (x : xs) = getIndent (i + 1) n xs
69 getIndent i n (x : xs) = getIndent (i + 1) n xs
68
70
69−addProofClauseFrom :: Handle -> FilePath -> Bool -> Int -> Name -> Idris ()
71+addProofClauseFrom :: FilePath -> Bool -> Int -> Name -> Idris ()
70−addProofClauseFrom h fn updatefile l n
72+addProofClauseFrom fn updatefile l n
71 = do src <- runIO $ readFile fn
73 = do src <- runIO $ readFile fn
72 let (before, tyline : later) = splitAt (l-1) (lines src)
74 let (before, tyline : later) = splitAt (l-1) (lines src)
73 let indent = getIndent 0 (show n) tyline
75 let indent = getIndent 0 (show n) tyline
@@ -81,14 +83,14 @@ addProofClauseFrom h fn updatefile l n
81 cl ++ "\n" ++
83 cl ++ "\n" ++
82 unlines rest)
84 unlines rest)
83 runIO $ copyFile fb fn
85 runIO $ copyFile fb fn
84− else ihPrintResult h cl
86+ else iPrintResult cl
85 where
87 where
86 getIndent i n [] = 0
88 getIndent i n [] = 0
87 getIndent i n xs | take (length n) xs == n = i
89 getIndent i n xs | take (length n) xs == n = i
88 getIndent i n (x : xs) = getIndent (i + 1) n xs
90 getIndent i n (x : xs) = getIndent (i + 1) n xs
89
91
90−addMissing :: Handle -> FilePath -> Bool -> Int -> Name -> Idris ()
92+addMissing :: FilePath -> Bool -> Int -> Name -> Idris ()
91−addMissing h fn updatefile l n
93+addMissing fn updatefile l n
92 = do src <- runIO $ readFile fn
94 = do src <- runIO $ readFile fn
93 let (before, tyline : later) = splitAt (l-1) (lines src)
95 let (before, tyline : later) = splitAt (l-1) (lines src)
94 let indent = getIndent 0 (show n) tyline
96 let indent = getIndent 0 (show n) tyline
@@ -106,7 +108,7 @@ addMissing h fn updatefile l n
106 runIO $ writeFile fb (unlines (before ++ nonblank)
108 runIO $ writeFile fb (unlines (before ++ nonblank)
107 ++ extras ++ unlines rest)
109 ++ extras ++ unlines rest)
108 runIO $ copyFile fb fn
110 runIO $ copyFile fb fn
109− else ihPrintResult h extras
111+ else iPrintResult extras
110 where showPat = show . stripNS
112 where showPat = show . stripNS
111 stripNS tm = mapPT dens tm where
113 stripNS tm = mapPT dens tm where
112 dens (PRef fc n) = PRef fc (nsroot n)
114 dens (PRef fc n) = PRef fc (nsroot n)
@@ -133,8 +135,8 @@ addMissing h fn updatefile l n
133 getIndent i n (x : xs) = getIndent (i + 1) n xs
135 getIndent i n (x : xs) = getIndent (i + 1) n xs
134
136
135
137
136−makeWith :: Handle -> FilePath -> Bool -> Int -> Name -> Idris ()
138+makeWith :: FilePath -> Bool -> Int -> Name -> Idris ()
137−makeWith h fn updatefile l n
139+makeWith fn updatefile l n
138 = do src <- runIO $ readFile fn
140 = do src <- runIO $ readFile fn
139 let (before, tyline : later) = splitAt (l-1) (lines src)
141 let (before, tyline : later) = splitAt (l-1) (lines src)
140 let ind = getIndent tyline
142 let ind = getIndent tyline
@@ -149,15 +151,15 @@ makeWith h fn updatefile l n
149 ++ with ++ "\n" ++
151 ++ with ++ "\n" ++
150 unlines rest)
152 unlines rest)
151 runIO $ copyFile fb fn
153 runIO $ copyFile fb fn
152− else ihPrintResult h with
154+ else iPrintResult with
153 where getIndent s = length (takeWhile isSpace s)
155 where getIndent s = length (takeWhile isSpace s)
154
156
155
157
156−doProofSearch :: Handle -> FilePath -> Bool -> Bool ->
158+doProofSearch :: FilePath -> Bool -> Bool ->
157 Int -> Name -> [Name] -> Maybe Int -> Idris ()
159 Int -> Name -> [Name] -> Maybe Int -> Idris ()
158−doProofSearch h fn updatefile rec l n hints Nothing
160+doProofSearch fn updatefile rec l n hints Nothing
159− = doProofSearch h fn updatefile rec l n hints (Just 10)
161+ = doProofSearch fn updatefile rec l n hints (Just 10)
160−doProofSearch h fn updatefile rec l n hints (Just depth)
162+doProofSearch fn updatefile rec l n hints (Just depth)
161 = do src <- runIO $ readFile fn
163 = do src <- runIO $ readFile fn
162 let (before, tyline : later) = splitAt (l-1) (lines src)
164 let (before, tyline : later) = splitAt (l-1) (lines src)
163 ctxt <- getContext
165 ctxt <- getContext
@@ -174,8 +176,8 @@ doProofSearch h fn updatefile rec l n hints (Just depth)
174 (ProofSearch rec False depth t hints)]
176 (ProofSearch rec False depth t hints)]
175 let def = PClause fc mn (PRef fc mn) [] (body top) []
177 let def = PClause fc mn (PRef fc mn) [] (body top) []
176 newmv <- idrisCatch
178 newmv <- idrisCatch
177− (do elabDecl' EAll toplevel (PClauses fc [] mn [def])
179+ (do elabDecl' EAll recinfo (PClauses fc [] mn [def])
178− (tm, ty) <- elabVal toplevel ERHS (PRef fc mn)
180+ (tm, ty) <- elabVal recinfo ERHS (PRef fc mn)
179 ctxt <- getContext
181 ctxt <- getContext
180 i <- getIState
182 i <- getIState
181 return . flip displayS "" . renderPretty 1.0 80 $
183 return . flip displayS "" . renderPretty 1.0 80 $
@@ -190,7 +192,7 @@ doProofSearch h fn updatefile rec l n hints (Just depth)
190 updateMeta False tyline (show n) newmv ++ "\n"
192 updateMeta False tyline (show n) newmv ++ "\n"
191 ++ unlines later)
193 ++ unlines later)
192 runIO $ copyFile fb fn
194 runIO $ copyFile fb fn
193− else ihPrintResult h newmv
195+ else iPrintResult newmv
194 where dropCtxt 0 sc = sc
196 where dropCtxt 0 sc = sc
195 dropCtxt i (PPi _ _ _ sc) = dropCtxt (i - 1) sc
197 dropCtxt i (PPi _ _ _ sc) = dropCtxt (i - 1) sc
196 dropCtxt i (PLet _ _ _ sc) = dropCtxt (i - 1) sc
198 dropCtxt i (PLet _ _ _ sc) = dropCtxt (i - 1) sc
@@ -233,8 +235,8 @@ addBracket True new | any isSpace new = '(' : new ++ ")"
233 | otherwise = new
235 | otherwise = new
234
236
235
237
236−makeLemma :: Handle -> FilePath -> Bool -> Int -> Name -> Idris ()
238+makeLemma :: FilePath -> Bool -> Int -> Name -> Idris ()
237−makeLemma h fn updatefile l n
239+makeLemma fn updatefile l n
238 = do src <- runIO $ readFile fn
240 = do src <- runIO $ readFile fn
239 let (before, tyline : later) = splitAt (l-1) (lines src)
241 let (before, tyline : later) = splitAt (l-1) (lines src)
240
242
@@ -264,8 +266,8 @@ makeLemma h fn updatefile l n
264 runIO $ writeFile fb (addLem before tyline lem lem_app later)
266 runIO $ writeFile fb (addLem before tyline lem lem_app later)
265 runIO $ copyFile fb fn
267 runIO $ copyFile fb fn
266 else case idris_outputmode i of
268 else case idris_outputmode i of
267− RawOutput -> ihPrintResult h $ lem ++ "\n" ++ lem_app
269+ RawOutput _ -> iPrintResult $ lem ++ "\n" ++ lem_app
268− IdeSlave n ->
270+ IdeSlave n h ->
269 let good = SexpList [SymbolAtom "ok",
271 let good = SexpList [SymbolAtom "ok",
270 SexpList [SymbolAtom "metavariable-lemma",
272 SexpList [SymbolAtom "metavariable-lemma",
271 SexpList [SymbolAtom "replace-metavariable",
273 SexpList [SymbolAtom "replace-metavariable",
@@ -282,8 +284,8 @@ makeLemma h fn updatefile l n
282 runIO $ writeFile fb (addProv before tyline lem_app later)
284 runIO $ writeFile fb (addProv before tyline lem_app later)
283 runIO $ copyFile fb fn
285 runIO $ copyFile fb fn
284 else case idris_outputmode i of
286 else case idris_outputmode i of
285− RawOutput -> ihPrintResult h $ lem_app
287+ RawOutput _ -> iPrintResult $ lem_app
286− IdeSlave n ->
288+ IdeSlave n h ->
287 let good = SexpList [SymbolAtom "ok",
289 let good = SexpList [SymbolAtom "ok",
288 SexpList [SymbolAtom "provisional-definition-lemma",
290 SexpList [SymbolAtom "provisional-definition-lemma",
289 SexpList [SymbolAtom "definition-clause",
291 SexpList [SymbolAtom "definition-clause",
src/Idris/Output.hs+60−63
@@ -24,27 +24,28 @@ pshow ist err = displayDecorated (consoleDecorate ist) .
24 renderPretty 1.0 80 .
24 renderPretty 1.0 80 .
25 fmap (fancifyAnnots ist) $ pprintErr ist err
25 fmap (fancifyAnnots ist) $ pprintErr ist err
26
26
27−ihWarn :: Handle -> FC -> Doc OutputAnnotation -> Idris ()
27+iWarn :: FC -> Doc OutputAnnotation -> Idris ()
28+iWarn fc err =
28−ihWarn h fc err = do i <- getIState
29+ do i <- getIState
29− case idris_outputmode i of
30+ case idris_outputmode i of
30− RawOutput ->
31+ RawOutput h ->
31− do err' <- iRender . fmap (fancifyAnnots i) $
32+ do err' <- iRender . fmap (fancifyAnnots i) $
32− if fc_fname fc /= ""
33+ if fc_fname fc /= ""
33− then text (show fc) <> colon <//> err
34+ then text (show fc) <> colon <//> err
34− else err
35+ else err
35− runIO . hPutStrLn h $ displayDecorated (consoleDecorate i) err'
36+ runIO . hPutStrLn h $ displayDecorated (consoleDecorate i) err'
36− IdeSlave n ->
37+ IdeSlave n h ->
37− do err' <- iRender . fmap (fancifyAnnots i) $ err
38+ do err' <- iRender . fmap (fancifyAnnots i) $ err
38− let (str, spans) = displaySpans err'
39+ let (str, spans) = displaySpans err'
39− runIO . hPutStrLn h $
40+ runIO . hPutStrLn h $
40− convSExp "warning" (fc_fname fc, fc_start fc, fc_end fc, str, spans) n
41+ convSExp "warning" (fc_fname fc, fc_start fc, fc_end fc, str, spans) n
41
42
42iRender :: Doc a -> Idris (SimpleDoc a)
43iRender :: Doc a -> Idris (SimpleDoc a)
43iRender d = do w <- getWidth
44iRender d = do w <- getWidth
44 ist <- getIState
45 ist <- getIState
45 let ideSlave = case idris_outputmode ist of
46 let ideSlave = case idris_outputmode ist of
46− IdeSlave _ -> True
47+ IdeSlave _ _ -> True
47− _ -> False
48+ _ -> False
48 case w of
49 case w of
49 InfinitelyWide -> return $ renderPretty 1.0 1000000000 d
50 InfinitelyWide -> return $ renderPretty 1.0 1000000000 d
50 ColsWide n -> return $
51 ColsWide n -> return $
@@ -63,37 +64,37 @@ consoleDisplayAnnotated h output = do ist <- getIState
63 displayDecorated (consoleDecorate ist) $
64 displayDecorated (consoleDecorate ist) $
64 rendered
65 rendered
65
66
66−ihPrintTermWithType :: Handle -> Doc OutputAnnotation -> Doc OutputAnnotation -> Idris ()
67+iPrintTermWithType :: Doc OutputAnnotation -> Doc OutputAnnotation -> Idris ()
67−ihPrintTermWithType h tm ty = ihRenderResult h (tm <+> colon <+> align ty)
68+iPrintTermWithType tm ty = iRenderResult (tm <+> colon <+> align ty)
68
69
69-- | Pretty-print a collection of overloadings to REPL or IDESlave - corresponds to :t name
70-- | Pretty-print a collection of overloadings to REPL or IDESlave - corresponds to :t name
70−ihPrintFunTypes :: Handle -> [(Name, Bool)] -> Name -> [(Name, PTerm)] -> Idris ()
71+iPrintFunTypes :: [(Name, Bool)] -> Name -> [(Name, PTerm)] -> Idris ()
71−ihPrintFunTypes h bnd n [] = ihPrintError h $ "No such variable " ++ show n
72+iPrintFunTypes bnd n [] = iPrintError $ "No such variable " ++ show n
72−ihPrintFunTypes h bnd n overloads = do ist <- getIState
73+iPrintFunTypes bnd n overloads = do ist <- getIState
73− let ppo = ppOptionIst ist
74+ let ppo = ppOptionIst ist
74− let infixes = idris_infixes ist
75+ let infixes = idris_infixes ist
75− let output = vsep (map (uncurry (ppOverload ppo infixes)) overloads)
76+ let output = vsep (map (uncurry (ppOverload ppo infixes)) overloads)
76− ihRenderResult h output
77+ iRenderResult output
77 where fullName n = prettyName True True bnd n
78 where fullName n = prettyName True True bnd n
78 ppOverload ppo infixes n tm =
79 ppOverload ppo infixes n tm =
79 fullName n <+> colon <+> align (pprintPTerm ppo bnd [] infixes tm)
80 fullName n <+> colon <+> align (pprintPTerm ppo bnd [] infixes tm)
80
81
81−ihRenderOutput :: Handle -> Doc OutputAnnotation -> Idris ()
82+iRenderOutput :: Doc OutputAnnotation -> Idris ()
82−ihRenderOutput h doc =
83+iRenderOutput doc =
83 do i <- getIState
84 do i <- getIState
84 case idris_outputmode i of
85 case idris_outputmode i of
85− RawOutput -> do out <- iRender doc
86+ RawOutput h -> do out <- iRender doc
86− runIO $ putStrLn (displayDecorated (consoleDecorate i) out)
87+ runIO $ putStrLn (displayDecorated (consoleDecorate i) out)
87− IdeSlave n ->
88+ IdeSlave n h ->
88 do (str, spans) <- fmap displaySpans . iRender . fmap (fancifyAnnots i) $ doc
89 do (str, spans) <- fmap displaySpans . iRender . fmap (fancifyAnnots i) $ doc
89 let out = [toSExp str, toSExp spans]
90 let out = [toSExp str, toSExp spans]
90− runIO . putStrLn $ convSExp "write-decorated" out n
91+ runIO . hPutStrLn h $ convSExp "write-decorated" out n
91
92
92−ihRenderResult :: Handle -> Doc OutputAnnotation -> Idris ()
93+iRenderResult :: Doc OutputAnnotation -> Idris ()
93−ihRenderResult h d = do ist <- getIState
94+iRenderResult d = do ist <- getIState
94− case idris_outputmode ist of
95+ case idris_outputmode ist of
95− RawOutput -> consoleDisplayAnnotated h d
96+ RawOutput h -> consoleDisplayAnnotated h d
96− IdeSlave n -> ideSlaveReturnAnnotated n h d
97+ IdeSlave n h -> ideSlaveReturnAnnotated n h d
97
98
98ideSlaveReturnWithStatus :: String -> Integer -> Handle -> Doc OutputAnnotation -> Idris ()
99ideSlaveReturnWithStatus :: String -> Integer -> Handle -> Doc OutputAnnotation -> Idris ()
99ideSlaveReturnWithStatus status n h out = do
100ideSlaveReturnWithStatus status n h out = do
@@ -111,56 +112,52 @@ ideSlaveReturnAnnotated :: Integer -> Handle -> Doc OutputAnnotation -> Idris ()
111ideSlaveReturnAnnotated = ideSlaveReturnWithStatus "ok"
112ideSlaveReturnAnnotated = ideSlaveReturnWithStatus "ok"
112
113
113-- | Show an error with semantic highlighting
114-- | Show an error with semantic highlighting
114−ihRenderError :: Handle -> Doc OutputAnnotation -> Idris ()
115+iRenderError :: Doc OutputAnnotation -> Idris ()
115−ihRenderError h e = do ist <- getIState
116+iRenderError e = do ist <- getIState
116− case idris_outputmode ist of
117+ case idris_outputmode ist of
117− RawOutput -> consoleDisplayAnnotated h e
118+ RawOutput h -> consoleDisplayAnnotated h e
118− IdeSlave n -> ideSlaveReturnWithStatus "error" n h e
119+ IdeSlave n h -> ideSlaveReturnWithStatus "error" n h e
119−
120+
120−ihPrintWithStatus :: String -> Handle -> String -> Idris ()
121+iPrintWithStatus :: String -> String -> Idris ()
121−ihPrintWithStatus status h s = do
122+iPrintWithStatus status s = do
122 i <- getIState
123 i <- getIState
123 case idris_outputmode i of
124 case idris_outputmode i of
124− RawOutput -> case s of
125+ RawOutput h -> case s of
125 "" -> return ()
126 "" -> return ()
126 s -> runIO $ hPutStrLn h s
127 s -> runIO $ hPutStrLn h s
127− IdeSlave n ->
128+ IdeSlave n h ->
128 let good = SexpList [SymbolAtom status, toSExp s] in
129 let good = SexpList [SymbolAtom status, toSExp s] in
129 runIO $ hPutStrLn h $ convSExp "return" good n
130 runIO $ hPutStrLn h $ convSExp "return" good n
130
131
131
132
132−ihPrintResult :: Handle -> String -> Idris ()
133+iPrintResult :: String -> Idris ()
133−ihPrintResult = ihPrintWithStatus "ok"
134+iPrintResult = iPrintWithStatus "ok"
134
135
135−ihPrintError :: Handle -> String -> Idris ()
136+iPrintError :: String -> Idris ()
136−ihPrintError = ihPrintWithStatus "error"
137+iPrintError = iPrintWithStatus "error"
137
138
138−ihputStrLn :: Handle -> String -> Idris ()
139+iputStrLn :: String -> Idris ()
139−ihputStrLn h s = do i <- getIState
140+iputStrLn s = do i <- getIState
140− case idris_outputmode i of
141+ case idris_outputmode i of
141− RawOutput -> runIO $ hPutStrLn h s
142+ RawOutput h -> runIO $ hPutStrLn h s
142− IdeSlave n -> runIO . hPutStrLn h $ convSExp "write-string" s n
143+ IdeSlave n h -> runIO . hPutStrLn h $ convSExp "write-string" s n
143
144
144−iputStrLn = ihputStrLn stdout
145−iPrintError = ihPrintError stdout
146−iPrintResult = ihPrintResult stdout
147−iWarn = ihWarn stdout
148
145
149ideslavePutSExp :: SExpable a => String -> a -> Idris ()
146ideslavePutSExp :: SExpable a => String -> a -> Idris ()
150ideslavePutSExp cmd info = do i <- getIState
147ideslavePutSExp cmd info = do i <- getIState
151 case idris_outputmode i of
148 case idris_outputmode i of
152− IdeSlave n -> runIO . putStrLn $ convSExp cmd info n
149+ IdeSlave n h -> runIO . hPutStrLn h $ convSExp cmd info n
153 _ -> return ()
150 _ -> return ()
154
151
155-- TODO: send structured output similar to the metavariable list
152-- TODO: send structured output similar to the metavariable list
156iputGoal :: SimpleDoc OutputAnnotation -> Idris ()
153iputGoal :: SimpleDoc OutputAnnotation -> Idris ()
157iputGoal g = do i <- getIState
154iputGoal g = do i <- getIState
158 case idris_outputmode i of
155 case idris_outputmode i of
159− RawOutput -> runIO $ putStrLn (displayDecorated (consoleDecorate i) g)
156+ RawOutput h -> runIO $ hPutStrLn h (displayDecorated (consoleDecorate i) g)
160− IdeSlave n ->
157+ IdeSlave n h ->
161 let (str, spans) = displaySpans . fmap (fancifyAnnots i) $ g
158 let (str, spans) = displaySpans . fmap (fancifyAnnots i) $ g
162 goal = [toSExp str, toSExp spans]
159 goal = [toSExp str, toSExp spans]
163− in runIO . putStrLn $ convSExp "write-goal" goal n
160+ in runIO . hPutStrLn h $ convSExp "write-goal" goal n
164
161
165-- | Warn about totality problems without failing to compile
162-- | Warn about totality problems without failing to compile
166warnTotality :: Idris ()
163warnTotality :: Idris ()
src/Idris/ParseExpr.hs+1−1
@@ -320,7 +320,7 @@ simpleExpr syn =
320 <|> idiom syn
320 <|> idiom syn
321 <|> listExpr syn
321 <|> listExpr syn
322 <|> alt syn
322 <|> alt syn
323− <|> do lchar '!'
323+ <|> do reservedOp "!"
324 s <- simpleExpr syn
324 s <- simpleExpr syn
325 fc <- getFC
325 fc <- getFC
326 return (PAppBind fc s [])
326 return (PAppBind fc s [])
src/Idris/ParseHelpers.hs+2−2
@@ -17,7 +17,7 @@ import Idris.Core.TT
17import Idris.Core.Evaluate
17import Idris.Core.Evaluate
18import Idris.Delaborate (pprintErr)
18import Idris.Delaborate (pprintErr)
19import Idris.Docstrings
19import Idris.Docstrings
20−import Idris.Output (ihWarn)
20+import Idris.Output (iWarn)
21
21
22import qualified Util.Pretty as Pretty (text)
22import qualified Util.Pretty as Pretty (text)
23
23
@@ -79,7 +79,7 @@ clearParserWarnings = do ist <- getIState
79
79
80reportParserWarnings :: Idris ()
80reportParserWarnings :: Idris ()
81reportParserWarnings = do ist <- getIState
81reportParserWarnings = do ist <- getIState
82− mapM_ (uncurry $ ihWarn (idris_outh ist))
82+ mapM_ (uncurry iWarn)
83 (map (\ (fc, err) -> (fc, pprintErr ist err)) .
83 (map (\ (fc, err) -> (fc, pprintErr ist err)) .
84 reverse .
84 reverse .
85 nub $
85 nub $
src/Idris/Parser.hs+27−24
@@ -376,6 +376,7 @@ fnDecl' syn = checkFixity $
376FnOpts ::= 'total'
376FnOpts ::= 'total'
377 | 'partial'
377 | 'partial'
378 | 'implicit'
378 | 'implicit'
379+ | '%' 'no_implicit'
379 | '%' 'assert_total'
380 | '%' 'assert_total'
380 | '%' 'error_handler'
381 | '%' 'error_handler'
381 | '%' 'reflection'
382 | '%' 'reflection'
@@ -402,6 +403,8 @@ fnOpts opts
402 <|> do reserved "covering"; fnOpts (CoveringFn : (opts \\ [TotalFn]))
403 <|> do reserved "covering"; fnOpts (CoveringFn : (opts \\ [TotalFn]))
403 <|> do try (lchar '%' *> reserved "export"); c <- stringLiteral;
404 <|> do try (lchar '%' *> reserved "export"); c <- stringLiteral;
404 fnOpts (CExport c : opts)
405 fnOpts (CExport c : opts)
406+ <|> do try (lchar '%' *> reserved "no_implicit");
407+ fnOpts (NoImplicit : opts)
405 <|> do try (lchar '%' *> reserved "assert_total");
408 <|> do try (lchar '%' *> reserved "assert_total");
406 fnOpts (AssertTotal : opts)
409 fnOpts (AssertTotal : opts)
407 <|> do try (lchar '%' *> reserved "error_handler");
410 <|> do try (lchar '%' *> reserved "error_handler");
@@ -1156,8 +1159,8 @@ parseProg syn fname input mrk
1156 let (fc, msg) = findFC doc
1159 let (fc, msg) = findFC doc
1157 i <- getIState
1160 i <- getIState
1158 case idris_outputmode i of
1161 case idris_outputmode i of
1159− RawOutput -> ihputStrLn (idris_outh i) (show $ fixColour (idris_colourRepl i) doc)
1162+ RawOutput h -> iputStrLn (show $ fixColour (idris_colourRepl i) doc)
1160− IdeSlave n -> ihWarn (idris_outh i) fc (P.text msg)
1163+ IdeSlave n h -> iWarn fc (P.text msg)
1161 putIState (i { errSpan = Just fc })
1164 putIState (i { errSpan = Just fc })
1162 return []
1165 return []
1163 Success (x, i) -> do putIState i
1166 Success (x, i) -> do putIState i
@@ -1173,17 +1176,17 @@ parseProg syn fname input mrk
1173 return (ds, i')
1176 return (ds, i')
1174
1177
1175{- | Load idris module and show error if something wrong happens -}
1178{- | Load idris module and show error if something wrong happens -}
1176−loadModule :: Handle -> FilePath -> Idris String
1179+loadModule :: FilePath -> Idris String
1177−loadModule outh f
1180+loadModule f
1178− = idrisCatch (loadModule' outh f)
1181+ = idrisCatch (loadModule' f)
1179 (\e -> do setErrSpan (getErrSpan e)
1182 (\e -> do setErrSpan (getErrSpan e)
1180 ist <- getIState
1183 ist <- getIState
1181− ihWarn outh (getErrSpan e) $ pprintErr ist e
1184+ iWarn (getErrSpan e) $ pprintErr ist e
1182 return "")
1185 return "")
1183
1186
1184{- | Load idris module -}
1187{- | Load idris module -}
1185−loadModule' :: Handle -> FilePath -> Idris String
1188+loadModule' :: FilePath -> Idris String
1186−loadModule' outh f
1189+loadModule' f
1187 = do i <- getIState
1190 = do i <- getIState
1188 let file = takeWhile (/= ' ') f
1191 let file = takeWhile (/= ' ') f
1189 ibcsd <- valIBCSubDir i
1192 ibcsd <- valIBCSubDir i
@@ -1193,21 +1196,21 @@ loadModule' outh f
1193 then iLOG $ "Already read " ++ file
1196 then iLOG $ "Already read " ++ file
1194 else do putIState (i { imported = file : imported i })
1197 else do putIState (i { imported = file : imported i })
1195 case fp of
1198 case fp of
1196− IDR fn -> loadSource outh False fn Nothing
1199+ IDR fn -> loadSource False fn Nothing
1197− LIDR fn -> loadSource outh True fn Nothing
1200+ LIDR fn -> loadSource True fn Nothing
1198 IBC fn src ->
1201 IBC fn src ->
1199 idrisCatch (loadIBC fn)
1202 idrisCatch (loadIBC fn)
1200 (\c -> do iLOG $ fn ++ " failed " ++ pshow i c
1203 (\c -> do iLOG $ fn ++ " failed " ++ pshow i c
1201 case src of
1204 case src of
1202− IDR sfn -> loadSource outh False sfn Nothing
1205+ IDR sfn -> loadSource False sfn Nothing
1203− LIDR sfn -> loadSource outh True sfn Nothing)
1206+ LIDR sfn -> loadSource True sfn Nothing)
1204 let (dir, fh) = splitFileName file
1207 let (dir, fh) = splitFileName file
1205 return (dropExtension fh)
1208 return (dropExtension fh)
1206
1209
1207
1210
1208{- | Load idris code from file -}
1211{- | Load idris code from file -}
1209−loadFromIFile :: Handle -> IFileType -> Maybe Int -> Idris ()
1212+loadFromIFile :: IFileType -> Maybe Int -> Idris ()
1210−loadFromIFile h i@(IBC fn src) maxline
1213+loadFromIFile i@(IBC fn src) maxline
1211 = do iLOG $ "Skipping " ++ getSrcFile i
1214 = do iLOG $ "Skipping " ++ getSrcFile i
1212 idrisCatch (loadIBC fn)
1215 idrisCatch (loadIBC fn)
1213 (\err -> ierror $ LoadingFailed fn err)
1216 (\err -> ierror $ LoadingFailed fn err)
@@ -1216,22 +1219,22 @@ loadFromIFile h i@(IBC fn src) maxline
1216 getSrcFile (LIDR fn) = fn
1219 getSrcFile (LIDR fn) = fn
1217 getSrcFile (IBC f src) = getSrcFile src
1220 getSrcFile (IBC f src) = getSrcFile src
1218
1221
1219−loadFromIFile h (IDR fn) maxline = loadSource' h False fn maxline
1222+loadFromIFile (IDR fn) maxline = loadSource' False fn maxline
1220−loadFromIFile h (LIDR fn) maxline = loadSource' h True fn maxline
1223+loadFromIFile (LIDR fn) maxline = loadSource' True fn maxline
1221
1224
1222{-| Load idris source code and show error if something wrong happens -}
1225{-| Load idris source code and show error if something wrong happens -}
1223−loadSource' :: Handle -> Bool -> FilePath -> Maybe Int -> Idris ()
1226+loadSource' :: Bool -> FilePath -> Maybe Int -> Idris ()
1224−loadSource' h lidr r maxline
1227+loadSource' lidr r maxline
1225− = idrisCatch (loadSource h lidr r maxline)
1228+ = idrisCatch (loadSource lidr r maxline)
1226 (\e -> do setErrSpan (getErrSpan e)
1229 (\e -> do setErrSpan (getErrSpan e)
1227 ist <- getIState
1230 ist <- getIState
1228 case e of
1231 case e of
1229− At f e' -> ihWarn h f (pprintErr ist e')
1232+ At f e' -> iWarn f (pprintErr ist e')
1230− _ -> ihWarn h (getErrSpan e) (pprintErr ist e))
1233+ _ -> iWarn (getErrSpan e) (pprintErr ist e))
1231
1234
1232{- | Load Idris source code-}
1235{- | Load Idris source code-}
1233−loadSource :: Handle -> Bool -> FilePath -> Maybe Int -> Idris ()
1236+loadSource :: Bool -> FilePath -> Maybe Int -> Idris ()
1234−loadSource h lidr f toline
1237+loadSource lidr f toline
1235 = do iLOG ("Reading " ++ f)
1238 = do iLOG ("Reading " ++ f)
1236 i <- getIState
1239 i <- getIState
1237 let def_total = default_total i
1240 let def_total = default_total i
@@ -1275,7 +1278,7 @@ loadSource h lidr f toline
1275 logLvl 3 (show (idris_infixes i))
1278 logLvl 3 (show (idris_infixes i))
1276 -- Now add all the declarations to the context
1279 -- Now add all the declarations to the context
1277 v <- verbose
1280 v <- verbose
1278− when v $ ihputStrLn h $ "Type checking " ++ f
1281+ when v $ iputStrLn $ "Type checking " ++ f
1279 -- we totality check after every Mutual block, so if
1282 -- we totality check after every Mutual block, so if
1280 -- anything is a single definition, wrap it in a
1283 -- anything is a single definition, wrap it in a
1281 -- mutual block on its own
1284 -- mutual block on its own
src/Idris/Prover.hs+56−47
@@ -6,6 +6,9 @@ import Idris.Core.Evaluate
6import Idris.Core.CaseTree
6import Idris.Core.CaseTree
7import Idris.Core.Typecheck
7import Idris.Core.Typecheck
8
8
9+import Idris.Elab.Utils
10+import Idris.Elab.Value
11+
9import Idris.AbsSyntax
12import Idris.AbsSyntax
10import Idris.AbsSyntaxTree
13import Idris.AbsSyntaxTree
11import Idris.Delaborate
14import Idris.Delaborate
@@ -16,12 +19,13 @@ import Idris.Parser hiding (params)
16import Idris.Error
19import Idris.Error
17import Idris.DataOpts
20import Idris.DataOpts
18import Idris.Completion
21import Idris.Completion
19−import Idris.IdeSlave
22+import qualified Idris.IdeSlave as IdeSlave
20import Idris.Output
23import Idris.Output
21import Idris.TypeSearch (searchByType)
24import Idris.TypeSearch (searchByType)
22
25
23import Text.Trifecta.Result(Result(..))
26import Text.Trifecta.Result(Result(..))
24
27
28+import System.IO (Handle, stdin, stdout, hPutStrLn)
25import System.Console.Haskeline
29import System.Console.Haskeline
26import System.Console.Haskeline.History
30import System.Console.Haskeline.History
27import Control.Monad.State.Strict
31import Control.Monad.State.Strict
@@ -67,8 +71,8 @@ prove opt ctxt lit n ty
67 iLOG $ "Adding " ++ show tm
71 iLOG $ "Adding " ++ show tm
68 i <- getIState
72 i <- getIState
69 case idris_outputmode i of
73 case idris_outputmode i of
70− IdeSlave _ -> ideslavePutSExp "end-proof-mode" (n, showProof lit n prf)
74+ IdeSlave _ _ -> ideslavePutSExp "end-proof-mode" (n, showProof lit n prf)
71− _ -> iputStrLn $ showProof lit n prf
75+ _ -> iputStrLn $ showProof lit n prf
72 let proofs = proof_list i
76 let proofs = proof_list i
73 putIState (i { proof_list = (n, prf) : proofs })
77 putIState (i { proof_list = (n, prf) : proofs })
74 let tree = simpleCase False True False CompileTime (fileFC "proof") [] [] [([], P Ref n ty, tm)]
78 let tree = simpleCase False True False CompileTime (fileFC "proof") [] [] [([], P Ref n ty, tm)]
@@ -90,9 +94,8 @@ prove opt ctxt lit n ty
90 [([], P Ref n ty, ptm')] ty)
94 [([], P Ref n ty, ptm')] ty)
91 solveDeferred n
95 solveDeferred n
92 case idris_outputmode i of
96 case idris_outputmode i of
93− IdeSlave n ->
97+ IdeSlave n h ->
94− runIO . putStrLn $
95− convSExp "return" (SymbolAtom "ok", "") n
98+ runIO . hPutStrLn h $ IdeSlave.convSExp "return" (IdeSlave.SymbolAtom "ok", "") n
96 _ -> return ()
99 _ -> return ()
97
100
98elabStep :: ElabState [PDecl] -> ElabD a -> Idris (a, ElabState [PDecl])
101elabStep :: ElabState [PDecl] -> ElabD a -> Idris (a, ElabState [PDecl])
@@ -137,6 +140,8 @@ dumpState ist ps@(PS nm (h:hs) _ _ tm _ _ _ _ _ _ problems i _ _ ctxy _ _ _ _) =
137 prettyPs bnd [] = empty
140 prettyPs bnd [] = empty
138 prettyPs bnd ((n@(MN _ r), _) : bs)
141 prettyPs bnd ((n@(MN _ r), _) : bs)
139 | r == txt "rewrite_rule" = prettyPs ((n, False):bnd) bs
142 | r == txt "rewrite_rule" = prettyPs ((n, False):bnd) bs
143+ prettyPs bnd ((n@(MN _ _), _) : bs)
144+ | not (n `elem` freeEnvNames bs) = prettyPs bnd bs
140 prettyPs bnd ((n, Let t v) : bs) =
145 prettyPs bnd ((n, Let t v) : bs) =
141 line <> bindingOf n False <+> text "=" <+> tPretty bnd v <+> colon <+>
146 line <> bindingOf n False <+> text "=" <+> tPretty bnd v <+> colon <+>
142 align (tPretty bnd t) <> prettyPs ((n, False):bnd) bs
147 align (tPretty bnd t) <> prettyPs ((n, False):bnd) bs
@@ -165,27 +170,35 @@ dumpState ist ps@(PS nm (h:hs) _ _ tm _ _ _ _ _ _ problems i _ _ ctxy _ _ _ _) =
165 text "---------- Other goals: ----------" <$$>
170 text "---------- Other goals: ----------" <$$>
166 nest nestingSize (align . cat . punctuate (text ",") . map (flip bindingOf False) $ hs)
171 nest nestingSize (align . cat . punctuate (text ",") . map (flip bindingOf False) $ hs)
167
172
173+ freeEnvNames :: Env -> [Name]
174+ freeEnvNames = foldl (++) [] . map (\(n, b) -> freeNames (Bind n b Erased))
175+
168lifte :: ElabState [PDecl] -> ElabD a -> Idris a
176lifte :: ElabState [PDecl] -> ElabD a -> Idris a
169lifte st e = do (v, _) <- elabStep st e
177lifte st e = do (v, _) <- elabStep st e
170 return v
178 return v
171
179
172−receiveInput :: ElabState [PDecl] -> Idris (Maybe String)
180+receiveInput :: Handle -> ElabState [PDecl] -> Idris (Maybe String)
173−receiveInput e =
181+receiveInput h e =
174 do i <- getIState
182 do i <- getIState
175− l <- runIO $ getLine
183+ let inh = if h == stdout then stdin else h
184+ len' <- runIO $ IdeSlave.getLen inh
185+ len <- case len' of
186+ Left err -> ierror err
187+ Right n -> return n
188+ l <- runIO $ IdeSlave.getNChar inh len ""
176− (sexp, id) <- case parseMessage l of
189+ (sexp, id) <- case IdeSlave.parseMessage l of
177 Left err -> ierror err
190 Left err -> ierror err
178 Right (sexp, id) -> return (sexp, id)
191 Right (sexp, id) -> return (sexp, id)
179− putIState $ i { idris_outputmode = (IdeSlave id) }
192+ putIState $ i { idris_outputmode = (IdeSlave id h) }
180− case sexpToCommand sexp of
193+ case IdeSlave.sexpToCommand sexp of
181− Just (REPLCompletions prefix) ->
194+ Just (IdeSlave.REPLCompletions prefix) ->
182 do (unused, compls) <- proverCompletion (assumptionNames e) (reverse prefix, "")
195 do (unused, compls) <- proverCompletion (assumptionNames e) (reverse prefix, "")
183− let good = SexpList [SymbolAtom "ok", toSExp (map replacement compls, reverse unused)]
196+ let good = IdeSlave.SexpList [IdeSlave.SymbolAtom "ok", IdeSlave.toSExp (map replacement compls, reverse unused)]
184 ideslavePutSExp "return" good
197 ideslavePutSExp "return" good
185− receiveInput e
198+ receiveInput h e
186− Just (Interpret cmd) -> return (Just cmd)
199+ Just (IdeSlave.Interpret cmd) -> return (Just cmd)
187− Just (TypeOf str) -> return (Just (":t " ++ str))
200+ Just (IdeSlave.TypeOf str) -> return (Just (":t " ++ str))
188− Just (DocsFor str) -> return (Just (":doc " ++ str))
201+ Just (IdeSlave.DocsFor str) -> return (Just (":doc " ++ str))
189 _ -> return Nothing
202 _ -> return Nothing
190
203
191ploop :: Name -> Bool -> String -> [String] -> ElabState [PDecl] -> Maybe History -> Idris (Term, [String])
204ploop :: Name -> Bool -> String -> [String] -> ElabState [PDecl] -> Maybe History -> Idris (Term, [String])
@@ -195,17 +208,18 @@ ploop fn d prompt prf e h
195 when d $ dumpState i (proof e)
208 when d $ dumpState i (proof e)
196 (x, h') <-
209 (x, h') <-
197 case idris_outputmode i of
210 case idris_outputmode i of
211+ RawOutput _ ->
198− RawOutput -> runInputT (proverSettings e) $
212+ runInputT (proverSettings e) $
199− -- Manually track the history so that we can use the proof state
213+ -- Manually track the history so that we can use the proof state
200− do _ <- case h of
214+ do case h of
201− Just history -> putHistory history
215+ Just history -> putHistory history
202− Nothing -> return ()
216+ Nothing -> return ()
203− l <- getInputLine (prompt ++ "> ")
217+ l <- getInputLine (prompt ++ "> ")
204− h' <- getHistory
218+ h' <- getHistory
205− return (l, Just h')
219+ return (l, Just h')
206− IdeSlave n ->
220+ IdeSlave _ handle ->
207 do isetPrompt prompt
221 do isetPrompt prompt
208− i <- receiveInput e
222+ i <- receiveInput handle e
209 return (i, h)
223 return (i, h)
210 (cmd, step) <- case x of
224 (cmd, step) <- case x of
211 Nothing -> do iPrintError ""; ifail "Abandoned"
225 Nothing -> do iPrintError ""; ifail "Abandoned"
@@ -237,7 +251,8 @@ ploop fn d prompt prf e h
237 (\err -> return (False, e, False, prf, Left err))
251 (\err -> return (False, e, False, prf, Left err))
238 ideslavePutSExp "write-proof-state" (prf', length prf')
252 ideslavePutSExp "write-proof-state" (prf', length prf')
239 case res of
253 case res of
240− Left err -> do iPrintError (pshow i err)
254+ Left err -> do ist <- getIState
255+ iRenderError $ pprintErr ist err
241 ploop fn d prompt prf' st h'
256 ploop fn d prompt prf' st h'
242 Right ok ->
257 Right ok ->
243 if done then do (tm, _) <- elabStep st get_term
258 if done then do (tm, _) <- elabStep st get_term
@@ -250,8 +265,7 @@ ploop fn d prompt prf e h
250 ist <- getIState
265 ist <- getIState
251 imp <- impShow
266 imp <- impShow
252 idrisCatch (do
267 idrisCatch (do
253− let h = idris_outh ist
254− OK env = envAtFocus (proof e)
268+ let OK env = envAtFocus (proof e)
255 ctxt' = envCtxt env ctxt
269 ctxt' = envCtxt env ctxt
256 bnd = map (\x -> (fst x, False)) env
270 bnd = map (\x -> (fst x, False)) env
257 ist' = ist { tt_ctxt = ctxt' }
271 ist' = ist { tt_ctxt = ctxt' }
@@ -259,8 +273,8 @@ ploop fn d prompt prf e h
259 -- Unlike the REPL, metavars have no special treatment, to
273 -- Unlike the REPL, metavars have no special treatment, to
260 -- make it easier to see how to prove with them.
274 -- make it easier to see how to prove with them.
261 let action = case lookupNames n ctxt' of
275 let action = case lookupNames n ctxt' of
262− [] -> ihPrintError h $ "No such variable " ++ show n
276+ [] -> iPrintError $ "No such variable " ++ show n
263− ts -> ihPrintFunTypes h bnd n (map (\n -> (n, delabTy ist' n)) ts)
277+ ts -> iPrintFunTypes bnd n (map (\n -> (n, delabTy ist' n)) ts)
264 putIState ist
278 putIState ist
265 return (False, e, False, prf, Right action))
279 return (False, e, False, prf, Right action))
266 (\err -> do putIState ist ; ierror err)
280 (\err -> do putIState ist ; ierror err)
@@ -272,17 +286,16 @@ ploop fn d prompt prf e h
272 let OK env = envAtFocus (proof e)
286 let OK env = envAtFocus (proof e)
273 ctxt' = envCtxt env ctxt
287 ctxt' = envCtxt env ctxt
274 putIState ist { tt_ctxt = ctxt' }
288 putIState ist { tt_ctxt = ctxt' }
275− (tm, ty) <- elabVal toplevel ERHS t
289+ (tm, ty) <- elabVal recinfo ERHS t
276 let ppo = ppOptionIst ist
290 let ppo = ppOptionIst ist
277 ty' = normaliseC ctxt [] ty
291 ty' = normaliseC ctxt [] ty
278− h = idris_outh ist
279 infixes = idris_infixes ist
292 infixes = idris_infixes ist
280 action = case tm of
293 action = case tm of
281 TType _ ->
294 TType _ ->
282− ihPrintTermWithType h (prettyImp ppo PType) type1Doc
295+ iPrintTermWithType (prettyImp ppo PType) type1Doc
283 _ -> let bnd = map (\x -> (fst x, False)) env in
296 _ -> let bnd = map (\x -> (fst x, False)) env in
284− ihPrintTermWithType h (pprintPTerm ppo bnd [] infixes (delab ist tm))
297+ iPrintTermWithType (pprintPTerm ppo bnd [] infixes (delab ist tm))
285− (pprintPTerm ppo bnd [] infixes (delab ist ty))
298+ (pprintPTerm ppo bnd [] infixes (delab ist ty))
286 putIState ist
299 putIState ist
287 return (False, e, False, prf, Right action))
300 return (False, e, False, prf, Right action))
288 (\err -> do putIState ist { tt_ctxt = ctxt } ; ierror err)
301 (\err -> do putIState ist { tt_ctxt = ctxt } ; ierror err)
@@ -296,32 +309,28 @@ ploop fn d prompt prf e h
296 ist' = ist { tt_ctxt = ctxt' }
309 ist' = ist { tt_ctxt = ctxt' }
297 bnd = map (\x -> (fst x, False)) env
310 bnd = map (\x -> (fst x, False)) env
298 putIState ist'
311 putIState ist'
299− (tm, ty) <- elabVal toplevel ERHS t
312+ (tm, ty) <- elabVal recinfo ERHS t
300 let tm' = force (normaliseAll ctxt' env tm)
313 let tm' = force (normaliseAll ctxt' env tm)
301 ty' = force (normaliseAll ctxt' env ty)
314 ty' = force (normaliseAll ctxt' env ty)
302 ppo = ppOption (idris_options ist')
315 ppo = ppOption (idris_options ist')
303 infixes = idris_infixes ist
316 infixes = idris_infixes ist
304 tmDoc = pprintPTerm ppo bnd [] infixes (delab ist' tm')
317 tmDoc = pprintPTerm ppo bnd [] infixes (delab ist' tm')
305 tyDoc = pprintPTerm ppo bnd [] infixes (delab ist' ty')
318 tyDoc = pprintPTerm ppo bnd [] infixes (delab ist' ty')
306− action = ihPrintTermWithType (idris_outh ist') tmDoc tyDoc
319+ action = iPrintTermWithType tmDoc tyDoc
307 putIState ist
320 putIState ist
308 return (False, e, False, prf, Right action))
321 return (False, e, False, prf, Right action))
309 (\err -> do putIState ist ; ierror err)
322 (\err -> do putIState ist ; ierror err)
310 docStr :: Either Name Const -> Idris (Bool, ElabState [PDecl], Bool, [String], Either Err (Idris ()))
323 docStr :: Either Name Const -> Idris (Bool, ElabState [PDecl], Bool, [String], Either Err (Idris ()))
311 docStr (Left n) = do ist <- getIState
324 docStr (Left n) = do ist <- getIState
312− let h = idris_outh ist
313 idrisCatch (case lookupCtxtName n (idris_docstrings ist) of
325 idrisCatch (case lookupCtxtName n (idris_docstrings ist) of
314 [] -> return (False, e, False, prf,
326 [] -> return (False, e, False, prf,
315 Left . Msg $ "No documentation for " ++ show n)
327 Left . Msg $ "No documentation for " ++ show n)
316 ns -> do toShow <- mapM (showDoc ist) ns
328 ns -> do toShow <- mapM (showDoc ist) ns
317 return (False, e, False, prf,
329 return (False, e, False, prf,
318− Right $ ihRenderResult h (vsep toShow)))
330+ Right $ iRenderResult (vsep toShow)))
319 (\err -> do putIState ist ; ierror err)
331 (\err -> do putIState ist ; ierror err)
320 where showDoc ist (n, d) = do doc <- getDocs n
332 where showDoc ist (n, d) = do doc <- getDocs n
321 return $ pprintDocs ist doc
333 return $ pprintDocs ist doc
322 docStr (Right c) = do ist <- getIState
334 docStr (Right c) = do ist <- getIState
323− let h = idris_outh ist
324− return (False, e, False, prf, Right . ihRenderResult h $ pprintConstDocs ist c (constDocs c))
335+ return (False, e, False, prf, Right . iRenderResult $ pprintConstDocs ist c (constDocs c))
325− search t = do ist <- getIState
326− let h = idris_outh ist
327− return (False, e, False, prf, Right $ searchByType h t)
336+ search t = return (False, e, False, prf, Right $ searchByType t)
src/Idris/REPL.hs+282−248
@@ -34,10 +34,15 @@ import Idris.Interactive
34import Idris.WhoCalls
34import Idris.WhoCalls
35import Idris.TypeSearch (searchByType)
35import Idris.TypeSearch (searchByType)
36
36
37+import Idris.Elab.Type
38+import Idris.Elab.Clause
39+import Idris.Elab.Data
40+import Idris.Elab.Value
41+
37import Version_idris (gitHash)
42import Version_idris (gitHash)
38import Util.System
43import Util.System
39import Util.DynamicLinker
44import Util.DynamicLinker
40−import Util.Net (listenOnLocalhost)
45+import Util.Net (listenOnLocalhost, listenOnLocalhostAnyPort)
41import Util.Pretty hiding ((</>))
46import Util.Pretty hiding ((</>))
42
47
43import Idris.Core.Evaluate
48import Idris.Core.Evaluate
@@ -86,6 +91,8 @@ import Data.Word (Word)
86import Data.Either (partitionEithers)
91import Data.Either (partitionEithers)
87import Control.DeepSeq
92import Control.DeepSeq
88
93
94+import Numeric ( readHex )
95+
89import Debug.Trace
96import Debug.Trace
90
97
91-- | Run the REPL
98-- | Run the REPL
@@ -144,7 +151,7 @@ startServer orig fn_in = do tid <- runIO $ forkOS serverLoop
144 -- TODO: option for port number
151 -- TODO: option for port number
145 serverLoop = withSocketsDo $
152 serverLoop = withSocketsDo $
146 do sock <- listenOnLocalhost $ PortNumber 4294
153 do sock <- listenOnLocalhost $ PortNumber 4294
147− loop fn orig sock
154+ loop fn orig { idris_colourRepl = False } sock
148
155
149 fn = case fn_in of
156 fn = case fn_in of
150 (f:_) -> f
157 (f:_) -> f
@@ -154,7 +161,10 @@ startServer orig fn_in = do tid <- runIO $ forkOS serverLoop
154 = do (h,_,_) <- accept sock
161 = do (h,_,_) <- accept sock
155 hSetEncoding h utf8
162 hSetEncoding h utf8
156 cmd <- hGetLine h
163 cmd <- hGetLine h
164+ let isth = case idris_outputmode ist of
165+ RawOutput _ -> ist {idris_outputmode = RawOutput h}
166+ IdeSlave n _ -> ist {idris_outputmode = IdeSlave n h}
157− (ist', fn) <- processNetCmd orig ist h fn cmd
167+ (ist', fn) <- processNetCmd orig isth h fn cmd
158 hClose h
168 hClose h
159 loop fn ist' sock
169 loop fn ist' sock
160
170
@@ -180,12 +190,18 @@ processNetCmd orig i h fn cmd
180 setOutH h
190 setOutH h
181 setQuiet True
191 setQuiet True
182 setVerbose False
192 setVerbose False
183− mods <- loadInputs h [f] toline
193+ mods <- loadInputs [f] toline
184 ist <- getIState
194 ist <- getIState
185 return (ist, f)
195 return (ist, f)
186− processNet fn c = do process h fn c
196+ processNet fn c = do process fn c
187 ist <- getIState
197 ist <- getIState
188 return (ist, fn)
198 return (ist, fn)
199+ setOutH :: Handle -> Idris ()
200+ setOutH h =
201+ do ist <- getIState
202+ putIState $ case idris_outputmode ist of
203+ RawOutput _ -> ist {idris_outputmode = RawOutput h}
204+ IdeSlave n _ -> ist {idris_outputmode = IdeSlave n h}
189
205
190-- | Run a command on the server on localhost
206-- | Run a command on the server on localhost
191runClient :: String -> IO ()
207runClient :: String -> IO ()
@@ -201,55 +217,73 @@ runClient str = withSocketsDo $ do
201 else do l <- hGetLine h
217 else do l <- hGetLine h
202 hGetResp (acc ++ l ++ "\n") h
218 hGetResp (acc ++ l ++ "\n") h
203
219
220+initIdeslaveSocket :: IO Handle
221+initIdeslaveSocket = do
222+ (sock, port) <- listenOnLocalhostAnyPort
223+ putStrLn $ show port
224+ (h, _, _) <- accept sock
225+ hSetEncoding h utf8
226+ return h
227+
204-- | Run the IdeSlave
228-- | Run the IdeSlave
205−ideslaveStart :: IState -> [FilePath] -> Idris ()
229+ideslaveStart :: Bool -> IState -> [FilePath] -> Idris ()
206−ideslaveStart orig mods
230+ideslaveStart s orig mods
231+ = do h <- runIO $ if s then initIdeslaveSocket else return stdout
232+ setIdeSlave True h
207− = do i <- getIState
233+ i <- getIState
208 case idris_outputmode i of
234 case idris_outputmode i of
209− IdeSlave n ->
235+ IdeSlave n h ->
210− when (mods /= []) (do isetPrompt (mkPrompt mods))
236+ do runIO $ hPutStrLn h $ IdeSlave.convSExp "protocol-version" IdeSlave.ideSlaveEpoch n
237+ case mods of
238+ a:_ -> runIdeSlaveCommand h n i "" [] (IdeSlave.LoadFile a Nothing)
239+ _ -> return ()
211− ideslave orig mods
240+ ideslave h orig mods
212−
241+
213−
214−ideslave :: IState -> [FilePath] -> Idris ()
242+ideslave :: Handle -> IState -> [FilePath] -> Idris ()
215−ideslave orig mods
243+ideslave h orig mods
216 = do idrisCatch
244 = do idrisCatch
217− (do l <- runIO $ getLine
245+ (do let inh = if h == stdout then stdin else h
246+ len' <- runIO $ IdeSlave.getLen inh
247+ len <- case len' of
248+ Left err -> ierror err
249+ Right n -> return n
250+ l <- runIO $ IdeSlave.getNChar inh len ""
218 (sexp, id) <- case IdeSlave.parseMessage l of
251 (sexp, id) <- case IdeSlave.parseMessage l of
219 Left err -> ierror err
252 Left err -> ierror err
220 Right (sexp, id) -> return (sexp, id)
253 Right (sexp, id) -> return (sexp, id)
221 i <- getIState
254 i <- getIState
222− putIState $ i { idris_outputmode = (IdeSlave id) }
255+ putIState $ i { idris_outputmode = (IdeSlave id h) }
223 idrisCatch -- to report correct id back!
256 idrisCatch -- to report correct id back!
224 (do let fn = case mods of
257 (do let fn = case mods of
225 (f:_) -> f
258 (f:_) -> f
226− _ -> ""
259+ _ -> ""
227 case IdeSlave.sexpToCommand sexp of
260 case IdeSlave.sexpToCommand sexp of
228− Just cmd -> runIdeSlaveCommand id orig fn mods cmd
261+ Just cmd -> runIdeSlaveCommand h id orig fn mods cmd
229 Nothing -> iPrintError "did not understand" )
262 Nothing -> iPrintError "did not understand" )
230 (\e -> do iPrintError $ show e))
263 (\e -> do iPrintError $ show e))
231 (\e -> do iPrintError $ show e)
264 (\e -> do iPrintError $ show e)
232− ideslave orig mods
265+ ideslave h orig mods
233
266
234-- | Run IDESlave commands
267-- | Run IDESlave commands
268+runIdeSlaveCommand :: Handle -- ^^ The handle for communication
235−runIdeSlaveCommand :: Integer -- ^^ The continuation ID for the client
269+ -> Integer -- ^^ The continuation ID for the client
236 -> IState -- ^^ The original IState
270 -> IState -- ^^ The original IState
237 -> FilePath -- ^^ The current open file
271 -> FilePath -- ^^ The current open file
238 -> [FilePath] -- ^^ The currently loaded modules
272 -> [FilePath] -- ^^ The currently loaded modules
239 -> IdeSlave.IdeSlaveCommand -- ^^ The command to process
273 -> IdeSlave.IdeSlaveCommand -- ^^ The command to process
240 -> Idris ()
274 -> Idris ()
241−runIdeSlaveCommand id orig fn mods (IdeSlave.Interpret cmd) =
275+runIdeSlaveCommand h id orig fn mods (IdeSlave.Interpret cmd) =
242 do c <- colourise
276 do c <- colourise
243 i <- getIState
277 i <- getIState
244 case parseCmd i "(input)" cmd of
278 case parseCmd i "(input)" cmd of
245 Failure err -> iPrintError $ show (fixColour c err)
279 Failure err -> iPrintError $ show (fixColour c err)
246 Success (Prove n') ->
280 Success (Prove n') ->
247 idrisCatch
281 idrisCatch
248− (do process stdout fn (Prove n')
282+ (do process fn (Prove n')
249 isetPrompt (mkPrompt mods)
283 isetPrompt (mkPrompt mods)
250 case idris_outputmode i of
284 case idris_outputmode i of
251− IdeSlave n -> -- signal completion of proof to ide
285+ IdeSlave n h -> -- signal completion of proof to ide
252− runIO . hPutStrLn stdout $
286+ runIO . hPutStrLn h $
253 IdeSlave.convSExp "return"
287 IdeSlave.convSExp "return"
254 (IdeSlave.SymbolAtom "ok", "")
288 (IdeSlave.SymbolAtom "ok", "")
255 n
289 n
@@ -257,26 +291,26 @@ runIdeSlaveCommand id orig fn mods (IdeSlave.Interpret cmd) =
257 (\e -> do ist <- getIState
291 (\e -> do ist <- getIState
258 isetPrompt (mkPrompt mods)
292 isetPrompt (mkPrompt mods)
259 case idris_outputmode i of
293 case idris_outputmode i of
260− IdeSlave n ->
294+ IdeSlave n h ->
261− runIO . hPutStrLn stdout $
295+ runIO . hPutStrLn h $
262 IdeSlave.convSExp "abandon-proof" "Abandoned" n
296 IdeSlave.convSExp "abandon-proof" "Abandoned" n
263 _ -> return ()
297 _ -> return ()
264− ihRenderError stdout $ pprintErr ist e)
298+ iRenderError $ pprintErr ist e)
265 Success cmd -> idrisCatch
299 Success cmd -> idrisCatch
266 (ideslaveProcess fn cmd)
300 (ideslaveProcess fn cmd)
267− (\e -> getIState >>= ihRenderError stdout . flip pprintErr e)
301+ (\e -> getIState >>= iRenderError . flip pprintErr e)
268−runIdeSlaveCommand id orig fn mods (IdeSlave.REPLCompletions str) =
302+runIdeSlaveCommand h id orig fn mods (IdeSlave.REPLCompletions str) =
269 do (unused, compls) <- replCompletion (reverse str, "")
303 do (unused, compls) <- replCompletion (reverse str, "")
270 let good = IdeSlave.SexpList [IdeSlave.SymbolAtom "ok",
304 let good = IdeSlave.SexpList [IdeSlave.SymbolAtom "ok",
271 IdeSlave.toSExp (map replacement compls,
305 IdeSlave.toSExp (map replacement compls,
272 reverse unused)]
306 reverse unused)]
273− runIO $ putStrLn $ IdeSlave.convSExp "return" good id
307+ runIO . hPutStrLn h $ IdeSlave.convSExp "return" good id
274−runIdeSlaveCommand id orig fn mods (IdeSlave.LoadFile filename toline) =
308+runIdeSlaveCommand h id orig fn mods (IdeSlave.LoadFile filename toline) =
275 do i <- getIState
309 do i <- getIState
276 clearErr
310 clearErr
277 putIState (orig { idris_options = idris_options i,
311 putIState (orig { idris_options = idris_options i,
278− idris_outputmode = (IdeSlave id) })
312+ idris_outputmode = (IdeSlave id h) })
279− loadInputs stdout [filename] toline
313+ loadInputs [filename] toline
280 isetPrompt (mkPrompt [filename])
314 isetPrompt (mkPrompt [filename])
281 -- Report either success or failure
315 -- Report either success or failure
282 i <- getIState
316 i <- getIState
@@ -286,45 +320,45 @@ runIdeSlaveCommand id orig fn mods (IdeSlave.LoadFile filename toline) =
286 (\fc -> IdeSlave.SexpList [IdeSlave.SymbolAtom "ok",
320 (\fc -> IdeSlave.SexpList [IdeSlave.SymbolAtom "ok",
287 IdeSlave.toSExp fc])
321 IdeSlave.toSExp fc])
288 (idris_parsedSpan i)
322 (idris_parsedSpan i)
289− in runIO . putStrLn $ IdeSlave.convSExp "return" msg id
323+ in runIO . hPutStrLn h $ IdeSlave.convSExp "return" msg id
290 Just x -> iPrintError $ "didn't load " ++ filename
324 Just x -> iPrintError $ "didn't load " ++ filename
291− ideslave orig [filename]
325+ ideslave h orig [filename]
292−runIdeSlaveCommand id orig fn mods (IdeSlave.TypeOf name) =
326+runIdeSlaveCommand h id orig fn mods (IdeSlave.TypeOf name) =
293 case splitName name of
327 case splitName name of
294 Left err -> iPrintError err
328 Left err -> iPrintError err
295− Right n -> process stdout "(ideslave)"
329+ Right n -> process "(ideslave)"
296 (Check (PRef (FC "(ideslave)" (0,0) (0,0)) n))
330 (Check (PRef (FC "(ideslave)" (0,0) (0,0)) n))
297 where splitName :: String -> Either String Name
331 where splitName :: String -> Either String Name
298 splitName s = case reverse $ splitOn "." s of
332 splitName s = case reverse $ splitOn "." s of
299 [] -> Left ("Didn't understand name '" ++ s ++ "'")
333 [] -> Left ("Didn't understand name '" ++ s ++ "'")
300 [n] -> Right $ sUN n
334 [n] -> Right $ sUN n
301 (n:ns) -> Right $ sNS (sUN n) ns
335 (n:ns) -> Right $ sNS (sUN n) ns
302−runIdeSlaveCommand id orig fn mods (IdeSlave.DocsFor name) =
336+runIdeSlaveCommand h id orig fn mods (IdeSlave.DocsFor name) =
303 case parseConst orig name of
337 case parseConst orig name of
304− Success c -> process stdout "(ideslave)" (DocStr (Right c))
338+ Success c -> process "(ideslave)" (DocStr (Right c))
305 Failure _ ->
339 Failure _ ->
306 case splitName name of
340 case splitName name of
307 Left err -> iPrintError err
341 Left err -> iPrintError err
308− Right n -> process stdout "(ideslave)" (DocStr (Left n))
342+ Right n -> process "(ideslave)" (DocStr (Left n))
309−runIdeSlaveCommand id orig fn mods (IdeSlave.CaseSplit line name) =
343+runIdeSlaveCommand h id orig fn mods (IdeSlave.CaseSplit line name) =
310− process stdout fn (CaseSplitAt False line (sUN name))
344+ process fn (CaseSplitAt False line (sUN name))
311−runIdeSlaveCommand id orig fn mods (IdeSlave.AddClause line name) =
345+runIdeSlaveCommand h id orig fn mods (IdeSlave.AddClause line name) =
312− process stdout fn (AddClauseFrom False line (sUN name))
346+ process fn (AddClauseFrom False line (sUN name))
313−runIdeSlaveCommand id orig fn mods (IdeSlave.AddProofClause line name) =
347+runIdeSlaveCommand h id orig fn mods (IdeSlave.AddProofClause line name) =
314− process stdout fn (AddProofClauseFrom False line (sUN name))
348+ process fn (AddProofClauseFrom False line (sUN name))
315−runIdeSlaveCommand id orig fn mods (IdeSlave.AddMissing line name) =
349+runIdeSlaveCommand h id orig fn mods (IdeSlave.AddMissing line name) =
316− process stdout fn (AddMissing False line (sUN name))
350+ process fn (AddMissing False line (sUN name))
317−runIdeSlaveCommand id orig fn mods (IdeSlave.MakeWithBlock line name) =
351+runIdeSlaveCommand h id orig fn mods (IdeSlave.MakeWithBlock line name) =
318− process stdout fn (MakeWith False line (sUN name))
352+ process fn (MakeWith False line (sUN name))
319−runIdeSlaveCommand id orig fn mods (IdeSlave.ProofSearch r line name hints depth) =
353+runIdeSlaveCommand h id orig fn mods (IdeSlave.ProofSearch r line name hints depth) =
320− doProofSearch stdout fn False r line (sUN name) (map sUN hints) depth
354+ doProofSearch fn False r line (sUN name) (map sUN hints) depth
321−runIdeSlaveCommand id orig fn mods (IdeSlave.MakeLemma line name) =
355+runIdeSlaveCommand h id orig fn mods (IdeSlave.MakeLemma line name) =
322 case splitName name of
356 case splitName name of
323 Left err -> iPrintError err
357 Left err -> iPrintError err
324− Right n -> process stdout fn (MakeLemma False line n)
358+ Right n -> process fn (MakeLemma False line n)
325−runIdeSlaveCommand id orig fn mods (IdeSlave.Apropos a) =
359+runIdeSlaveCommand h id orig fn mods (IdeSlave.Apropos a) =
326− process stdout fn (Apropos a)
360+ process fn (Apropos a)
327−runIdeSlaveCommand id orig fn mods (IdeSlave.GetOpts) =
361+runIdeSlaveCommand h id orig fn mods (IdeSlave.GetOpts) =
328 do ist <- getIState
362 do ist <- getIState
329 let opts = idris_options ist
363 let opts = idris_options ist
330 let impshow = opt_showimp opts
364 let impshow = opt_showimp opts
@@ -332,16 +366,16 @@ runIdeSlaveCommand id orig fn mods (IdeSlave.GetOpts) =
332 let options = (IdeSlave.SymbolAtom "ok",
366 let options = (IdeSlave.SymbolAtom "ok",
333 [(IdeSlave.SymbolAtom "show-implicits", impshow),
367 [(IdeSlave.SymbolAtom "show-implicits", impshow),
334 (IdeSlave.SymbolAtom "error-context", errCtxt)])
368 (IdeSlave.SymbolAtom "error-context", errCtxt)])
335− runIO . putStrLn $ IdeSlave.convSExp "return" options id
369+ runIO . hPutStrLn h $ IdeSlave.convSExp "return" options id
336−runIdeSlaveCommand id orig fn mods (IdeSlave.SetOpt IdeSlave.ShowImpl b) =
370+runIdeSlaveCommand h id orig fn mods (IdeSlave.SetOpt IdeSlave.ShowImpl b) =
337 do setImpShow b
371 do setImpShow b
338 let msg = (IdeSlave.SymbolAtom "ok", b)
372 let msg = (IdeSlave.SymbolAtom "ok", b)
339− runIO . putStrLn $ IdeSlave.convSExp "return" msg id
373+ runIO . hPutStrLn h $ IdeSlave.convSExp "return" msg id
340−runIdeSlaveCommand id orig fn mods (IdeSlave.SetOpt IdeSlave.ErrContext b) =
374+runIdeSlaveCommand h id orig fn mods (IdeSlave.SetOpt IdeSlave.ErrContext b) =
341 do setErrContext b
375 do setErrContext b
342 let msg = (IdeSlave.SymbolAtom "ok", b)
376 let msg = (IdeSlave.SymbolAtom "ok", b)
343− runIO . putStrLn $ IdeSlave.convSExp "return" msg id
377+ runIO . hPutStrLn h $ IdeSlave.convSExp "return" msg id
344−runIdeSlaveCommand id orig fn mods (IdeSlave.Metavariables cols) =
378+runIdeSlaveCommand h id orig fn mods (IdeSlave.Metavariables cols) =
345 do ist <- getIState
379 do ist <- getIState
346 let mvs = reverse $ map fst (idris_metavars ist) \\ primDefs
380 let mvs = reverse $ map fst (idris_metavars ist) \\ primDefs
347 let ppo = ppOptionIst ist
381 let ppo = ppOptionIst ist
@@ -357,7 +391,7 @@ runIdeSlaveCommand id orig fn mods (IdeSlave.Metavariables cols) =
357 (zip bnds hs),
391 (zip bnds hs),
358 render ist bnd c pc))
392 render ist bnd c pc))
359 splitMvs
393 splitMvs
360− runIO . putStrLn $
394+ runIO . hPutStrLn h $
361 IdeSlave.convSExp "return" (IdeSlave.SymbolAtom "ok", mvOutput) id
395 IdeSlave.convSExp "return" (IdeSlave.SymbolAtom "ok", mvOutput) id
362 where mapPair f g xs = zip (map (f . fst) xs) (map (g . snd) xs)
396 where mapPair f g xs = zip (map (f . fst) xs) (map (g . snd) xs)
363 mapSnd f xs = zip (map fst xs) (map (f . snd) xs)
397 mapSnd f xs = zip (map fst xs) (map (f . snd) xs)
@@ -402,32 +436,32 @@ runIdeSlaveCommand id orig fn mods (IdeSlave.Metavariables cols) =
402 let (out, spans) = render ist bnd t pt in
436 let (out, spans) = render ist bnd t pt in
403 (show n , out, spans)
437 (show n , out, spans)
404
438
405−runIdeSlaveCommand id orig fn mods (IdeSlave.WhoCalls n) =
439+runIdeSlaveCommand h id orig fn mods (IdeSlave.WhoCalls n) =
406 case splitName n of
440 case splitName n of
407 Left err -> iPrintError err
441 Left err -> iPrintError err
408 Right n -> do calls <- whoCalls n
442 Right n -> do calls <- whoCalls n
409 ist <- getIState
443 ist <- getIState
410 let msg = (IdeSlave.SymbolAtom "ok",
444 let msg = (IdeSlave.SymbolAtom "ok",
411 map (\ (n,ns) -> (pn ist n, map (pn ist) ns)) calls)
445 map (\ (n,ns) -> (pn ist n, map (pn ist) ns)) calls)
412− runIO . putStrLn $ IdeSlave.convSExp "return" msg id
446+ runIO . hPutStrLn h $ IdeSlave.convSExp "return" msg id
413 where pn ist = displaySpans .
447 where pn ist = displaySpans .
414 renderPretty 0.9 1000 .
448 renderPretty 0.9 1000 .
415 fmap (fancifyAnnots ist) .
449 fmap (fancifyAnnots ist) .
416 prettyName True True []
450 prettyName True True []
417−runIdeSlaveCommand id orig fn mods (IdeSlave.CallsWho n) =
451+runIdeSlaveCommand h id orig fn mods (IdeSlave.CallsWho n) =
418 case splitName n of
452 case splitName n of
419 Left err -> iPrintError err
453 Left err -> iPrintError err
420 Right n -> do calls <- callsWho n
454 Right n -> do calls <- callsWho n
421 ist <- getIState
455 ist <- getIState
422 let msg = (IdeSlave.SymbolAtom "ok",
456 let msg = (IdeSlave.SymbolAtom "ok",
423 map (\ (n,ns) -> (pn ist n, map (pn ist) ns)) calls)
457 map (\ (n,ns) -> (pn ist n, map (pn ist) ns)) calls)
424− runIO . putStrLn $ IdeSlave.convSExp "return" msg id
458+ runIO . hPutStrLn h $ IdeSlave.convSExp "return" msg id
425 where pn ist = displaySpans .
459 where pn ist = displaySpans .
426 renderPretty 0.9 1000 .
460 renderPretty 0.9 1000 .
427 fmap (fancifyAnnots ist) .
461 fmap (fancifyAnnots ist) .
428 prettyName True True []
462 prettyName True True []
429
463
430−runIdeSlaveCommand id orig fn modes (IdeSlave.TermNormalise bnd tm) =
464+runIdeSlaveCommand h id orig fn modes (IdeSlave.TermNormalise bnd tm) =
431 do ctxt <- getContext
465 do ctxt <- getContext
432 ist <- getIState
466 ist <- getIState
433 let tm' = force (normaliseAll ctxt [] tm)
467 let tm' = force (normaliseAll ctxt [] tm)
@@ -441,15 +475,15 @@ runIdeSlaveCommand id orig fn modes (IdeSlave.TermNormalise bnd tm) =
441 displaySpans .
475 displaySpans .
442 renderPretty 0.9 80 .
476 renderPretty 0.9 80 .
443 fmap (fancifyAnnots ist) $ ptm)
477 fmap (fancifyAnnots ist) $ ptm)
444− runIO . putStrLn $ IdeSlave.convSExp "return" msg id
478+ runIO . hPutStrLn h $ IdeSlave.convSExp "return" msg id
445−runIdeSlaveCommand id orig fn modes (IdeSlave.TermShowImplicits bnd tm) =
479+runIdeSlaveCommand h id orig fn modes (IdeSlave.TermShowImplicits bnd tm) =
446− ideSlaveForceTermImplicits id bnd True tm
480+ ideSlaveForceTermImplicits h id bnd True tm
447−runIdeSlaveCommand id orig fn modes (IdeSlave.TermNoImplicits bnd tm) =
481+runIdeSlaveCommand h id orig fn modes (IdeSlave.TermNoImplicits bnd tm) =
448− ideSlaveForceTermImplicits id bnd False tm
482+ ideSlaveForceTermImplicits h id bnd False tm
449
483
450-- | Show a term for IDESlave with the specified implicitness
484-- | Show a term for IDESlave with the specified implicitness
451−ideSlaveForceTermImplicits :: Integer -> [(Name, Bool)] -> Bool -> Term -> Idris ()
485+ideSlaveForceTermImplicits :: Handle -> Integer -> [(Name, Bool)] -> Bool -> Term -> Idris ()
452−ideSlaveForceTermImplicits id bnd impl tm =
486+ideSlaveForceTermImplicits h id bnd impl tm =
453 do ist <- getIState
487 do ist <- getIState
454 let expl = annotate (AnnTerm bnd tm)
488 let expl = annotate (AnnTerm bnd tm)
455 (pprintPTerm ((ppOptionIst ist) { ppopt_impl = impl })
489 (pprintPTerm ((ppOptionIst ist) { ppopt_impl = impl })
@@ -459,7 +493,7 @@ ideSlaveForceTermImplicits id bnd impl tm =
459 displaySpans .
493 displaySpans .
460 renderPretty 0.9 80 .
494 renderPretty 0.9 80 .
461 fmap (fancifyAnnots ist) $ expl)
495 fmap (fancifyAnnots ist) $ expl)
462− runIO . putStrLn $ IdeSlave.convSExp "return" msg id
496+ runIO . hPutStrLn h $ IdeSlave.convSExp "return" msg id
463
497
464splitName :: String -> Either String Name
498splitName :: String -> Either String Name
465splitName s = case reverse $ splitOn "." s of
499splitName s = case reverse $ splitOn "." s of
@@ -468,70 +502,70 @@ splitName s = case reverse $ splitOn "." s of
468 (n:ns) -> Right $ sNS (sUN n) ns
502 (n:ns) -> Right $ sNS (sUN n) ns
469
503
470ideslaveProcess :: FilePath -> Command -> Idris ()
504ideslaveProcess :: FilePath -> Command -> Idris ()
471−ideslaveProcess fn Warranty = process stdout fn Warranty
505+ideslaveProcess fn Warranty = process fn Warranty
472−ideslaveProcess fn Help = process stdout fn Help
506+ideslaveProcess fn Help = process fn Help
473−ideslaveProcess fn (ChangeDirectory f) = do process stdout fn (ChangeDirectory f)
507+ideslaveProcess fn (ChangeDirectory f) = do process fn (ChangeDirectory f)
474 iPrintResult "changed directory to"
508 iPrintResult "changed directory to"
475−ideslaveProcess fn (Eval t) = process stdout fn (Eval t)
509+ideslaveProcess fn (Eval t) = process fn (Eval t)
476−ideslaveProcess fn (NewDefn decls) = do process stdout fn (NewDefn decls)
510+ideslaveProcess fn (NewDefn decls) = do process fn (NewDefn decls)
477 iPrintResult "defined"
511 iPrintResult "defined"
478−ideslaveProcess fn (ExecVal t) = process stdout fn (ExecVal t)
512+ideslaveProcess fn (ExecVal t) = process fn (ExecVal t)
479−ideslaveProcess fn (Check (PRef x n)) = process stdout fn (Check (PRef x n))
513+ideslaveProcess fn (Check (PRef x n)) = process fn (Check (PRef x n))
480−ideslaveProcess fn (Check t) = process stdout fn (Check t)
514+ideslaveProcess fn (Check t) = process fn (Check t)
481−ideslaveProcess fn (DocStr n) = process stdout fn (DocStr n)
515+ideslaveProcess fn (DocStr n) = process fn (DocStr n)
482−ideslaveProcess fn Universes = process stdout fn Universes
516+ideslaveProcess fn Universes = process fn Universes
483−ideslaveProcess fn (Defn n) = do process stdout fn (Defn n)
517+ideslaveProcess fn (Defn n) = do process fn (Defn n)
484 iPrintResult ""
518 iPrintResult ""
485−ideslaveProcess fn (TotCheck n) = process stdout fn (TotCheck n)
519+ideslaveProcess fn (TotCheck n) = process fn (TotCheck n)
486−ideslaveProcess fn (DebugInfo n) = do process stdout fn (DebugInfo n)
520+ideslaveProcess fn (DebugInfo n) = do process fn (DebugInfo n)
487 iPrintResult ""
521 iPrintResult ""
488−ideslaveProcess fn (Search t) = process stdout fn (Search t)
522+ideslaveProcess fn (Search t) = process fn (Search t)
489−ideslaveProcess fn (Spec t) = process stdout fn (Spec t)
523+ideslaveProcess fn (Spec t) = process fn (Spec t)
490-- RmProof and AddProof not supported!
524-- RmProof and AddProof not supported!
491−ideslaveProcess fn (ShowProof n') = process stdout fn (ShowProof n')
525+ideslaveProcess fn (ShowProof n') = process fn (ShowProof n')
492−ideslaveProcess fn (HNF t) = process stdout fn (HNF t)
526+ideslaveProcess fn (HNF t) = process fn (HNF t)
493−--ideslaveProcess fn TTShell = process stdout fn TTShell -- need some prove mode!
527+--ideslaveProcess fn TTShell = process fn TTShell -- need some prove mode!
494−ideslaveProcess fn (TestInline t) = process stdout fn (TestInline t)
528+ideslaveProcess fn (TestInline t) = process fn (TestInline t)
495
529
496−ideslaveProcess fn Execute = do process stdout fn Execute
530+ideslaveProcess fn Execute = do process fn Execute
497 iPrintResult ""
531 iPrintResult ""
498−ideslaveProcess fn (Compile codegen f) = do process stdout fn (Compile codegen f)
532+ideslaveProcess fn (Compile codegen f) = do process fn (Compile codegen f)
499 iPrintResult ""
533 iPrintResult ""
500−ideslaveProcess fn (LogLvl i) = do process stdout fn (LogLvl i)
534+ideslaveProcess fn (LogLvl i) = do process fn (LogLvl i)
501 iPrintResult ""
535 iPrintResult ""
502−ideslaveProcess fn (Pattelab t) = process stdout fn (Pattelab t)
536+ideslaveProcess fn (Pattelab t) = process fn (Pattelab t)
503−ideslaveProcess fn (Missing n) = process stdout fn (Missing n)
537+ideslaveProcess fn (Missing n) = process fn (Missing n)
504−ideslaveProcess fn (DynamicLink l) = do process stdout fn (DynamicLink l)
538+ideslaveProcess fn (DynamicLink l) = do process fn (DynamicLink l)
505 iPrintResult ""
539 iPrintResult ""
506−ideslaveProcess fn ListDynamic = do process stdout fn ListDynamic
540+ideslaveProcess fn ListDynamic = do process fn ListDynamic
507 iPrintResult ""
541 iPrintResult ""
508−ideslaveProcess fn Metavars = process stdout fn Metavars
542+ideslaveProcess fn Metavars = process fn Metavars
509−ideslaveProcess fn (SetOpt ErrContext) = do process stdout fn (SetOpt ErrContext)
543+ideslaveProcess fn (SetOpt ErrContext) = do process fn (SetOpt ErrContext)
510 iPrintResult ""
544 iPrintResult ""
511−ideslaveProcess fn (UnsetOpt ErrContext) = do process stdout fn (UnsetOpt ErrContext)
545+ideslaveProcess fn (UnsetOpt ErrContext) = do process fn (UnsetOpt ErrContext)
512 iPrintResult ""
546 iPrintResult ""
513−ideslaveProcess fn (SetOpt ShowImpl) = do process stdout fn (SetOpt ShowImpl)
547+ideslaveProcess fn (SetOpt ShowImpl) = do process fn (SetOpt ShowImpl)
514 iPrintResult ""
548 iPrintResult ""
515−ideslaveProcess fn (UnsetOpt ShowImpl) = do process stdout fn (UnsetOpt ShowImpl)
549+ideslaveProcess fn (UnsetOpt ShowImpl) = do process fn (UnsetOpt ShowImpl)
516 iPrintResult ""
550 iPrintResult ""
517−ideslaveProcess fn (SetOpt ShowOrigErr) = do process stdout fn (SetOpt ShowOrigErr)
551+ideslaveProcess fn (SetOpt ShowOrigErr) = do process fn (SetOpt ShowOrigErr)
518 iPrintResult ""
552 iPrintResult ""
519−ideslaveProcess fn (UnsetOpt ShowOrigErr) = do process stdout fn (UnsetOpt ShowOrigErr)
553+ideslaveProcess fn (UnsetOpt ShowOrigErr) = do process fn (UnsetOpt ShowOrigErr)
520 iPrintResult ""
554 iPrintResult ""
521−ideslaveProcess fn (SetOpt x) = process stdout fn (SetOpt x)
555+ideslaveProcess fn (SetOpt x) = process fn (SetOpt x)
522−ideslaveProcess fn (UnsetOpt x) = process stdout fn (UnsetOpt x)
556+ideslaveProcess fn (UnsetOpt x) = process fn (UnsetOpt x)
523−ideslaveProcess fn (CaseSplitAt False pos str) = process stdout fn (CaseSplitAt False pos str)
557+ideslaveProcess fn (CaseSplitAt False pos str) = process fn (CaseSplitAt False pos str)
524−ideslaveProcess fn (AddProofClauseFrom False pos str) = process stdout fn (AddProofClauseFrom False pos str)
558+ideslaveProcess fn (AddProofClauseFrom False pos str) = process fn (AddProofClauseFrom False pos str)
525−ideslaveProcess fn (AddClauseFrom False pos str) = process stdout fn (AddClauseFrom False pos str)
559+ideslaveProcess fn (AddClauseFrom False pos str) = process fn (AddClauseFrom False pos str)
526−ideslaveProcess fn (AddMissing False pos str) = process stdout fn (AddMissing False pos str)
560+ideslaveProcess fn (AddMissing False pos str) = process fn (AddMissing False pos str)
527−ideslaveProcess fn (MakeWith False pos str) = process stdout fn (MakeWith False pos str)
561+ideslaveProcess fn (MakeWith False pos str) = process fn (MakeWith False pos str)
528−ideslaveProcess fn (DoProofSearch False r pos str xs) = process stdout fn (DoProofSearch False r pos str xs)
562+ideslaveProcess fn (DoProofSearch False r pos str xs) = process fn (DoProofSearch False r pos str xs)
529−ideslaveProcess fn (SetConsoleWidth w) = do process stdout fn (SetConsoleWidth w)
563+ideslaveProcess fn (SetConsoleWidth w) = do process fn (SetConsoleWidth w)
530 iPrintResult ""
564 iPrintResult ""
531−ideslaveProcess fn (Apropos a) = do process stdout fn (Apropos a)
565+ideslaveProcess fn (Apropos a) = do process fn (Apropos a)
532 iPrintResult ""
566 iPrintResult ""
533−ideslaveProcess fn (WhoCalls n) = process stdout fn (WhoCalls n)
567+ideslaveProcess fn (WhoCalls n) = process fn (WhoCalls n)
534−ideslaveProcess fn (CallsWho n) = process stdout fn (CallsWho n)
568+ideslaveProcess fn (CallsWho n) = process fn (CallsWho n)
535ideslaveProcess fn _ = iPrintError "command not recognized or not supported"
569ideslaveProcess fn _ = iPrintError "command not recognized or not supported"
536
570
537
571
@@ -563,18 +597,18 @@ processInput cmd orig inputs
563 , idris_colourTheme = idris_colourTheme i
597 , idris_colourTheme = idris_colourTheme i
564 }
598 }
565 clearErr
599 clearErr
566− mods <- loadInputs stdout inputs Nothing
600+ mods <- loadInputs inputs Nothing
567 return (Just inputs)
601 return (Just inputs)
568 Success (Load f toline) ->
602 Success (Load f toline) ->
569 do putIState orig { idris_options = idris_options i
603 do putIState orig { idris_options = idris_options i
570 , idris_colourTheme = idris_colourTheme i
604 , idris_colourTheme = idris_colourTheme i
571 }
605 }
572 clearErr
606 clearErr
573− mod <- loadInputs stdout [f] toline
607+ mod <- loadInputs [f] toline
574 return (Just [f])
608 return (Just [f])
575 Success (ModImport f) ->
609 Success (ModImport f) ->
576 do clearErr
610 do clearErr
577− fmod <- loadModule stdout f
611+ fmod <- loadModule f
578 return (Just (inputs ++ [fmod]))
612 return (Just (inputs ++ [fmod]))
579 Success Edit -> do -- takeMVar stvar
613 Success Edit -> do -- takeMVar stvar
580 edit fn orig
614 edit fn orig
@@ -583,7 +617,7 @@ processInput cmd orig inputs
583 return (Just inputs)
617 return (Just inputs)
584 Success Quit -> do when (not quiet) (iputStrLn "Bye bye")
618 Success Quit -> do when (not quiet) (iputStrLn "Bye bye")
585 return Nothing
619 return Nothing
586− Success cmd -> do idrisCatch (process stdout fn cmd)
620+ Success cmd -> do idrisCatch (process fn cmd)
587 (\e -> do msg <- showErr e ; iputStrLn msg)
621 (\e -> do msg <- showErr e ; iputStrLn msg)
588 return (Just inputs)
622 return (Just inputs)
589
623
@@ -619,7 +653,7 @@ edit f orig
619 putIState $ orig { idris_options = idris_options i
653 putIState $ orig { idris_options = idris_options i
620 , idris_colourTheme = idris_colourTheme i
654 , idris_colourTheme = idris_colourTheme i
621 }
655 }
622− loadInputs stdout [f] Nothing
656+ loadInputs [f] Nothing
623-- clearOrigPats
657-- clearOrigPats
624 iucheck
658 iucheck
625 return ()
659 return ()
@@ -645,15 +679,15 @@ insertScript prf (p@"---------- Proofs ----------" : "" : xs)
645 = p : "" : prf : xs
679 = p : "" : prf : xs
646insertScript prf (x : xs) = x : insertScript prf xs
680insertScript prf (x : xs) = x : insertScript prf xs
647
681
648−process :: Handle -> FilePath -> Command -> Idris ()
682+process :: FilePath -> Command -> Idris ()
649−process h fn Help = iPrintResult displayHelp
683+process fn Help = iPrintResult displayHelp
650−process h fn Warranty = iPrintResult warranty
684+process fn Warranty = iPrintResult warranty
651−process h fn (ChangeDirectory f)
685+process fn (ChangeDirectory f)
652 = do runIO $ setCurrentDirectory f
686 = do runIO $ setCurrentDirectory f
653 return ()
687 return ()
654−process h fn (Eval t)
688+process fn (Eval t)
655 = withErrorReflection $ do logLvl 5 $ show t
689 = withErrorReflection $ do logLvl 5 $ show t
656− (tm, ty) <- elabVal toplevel ERHS t
690+ (tm, ty) <- elabVal recinfo ERHS t
657 ctxt <- getContext
691 ctxt <- getContext
658 let tm' = force (normaliseAll ctxt [] tm)
692 let tm' = force (normaliseAll ctxt [] tm)
659 let ty' = force (normaliseAll ctxt [] ty)
693 let ty' = force (normaliseAll ctxt [] ty)
@@ -664,10 +698,10 @@ process h fn (Eval t)
664 logLvl 10 $ "Debug: " ++ showEnvDbg [] tm'
698 logLvl 10 $ "Debug: " ++ showEnvDbg [] tm'
665 let tmDoc = pprintDelab ist tm'
699 let tmDoc = pprintDelab ist tm'
666 tyDoc = pprintDelab ist ty'
700 tyDoc = pprintDelab ist ty'
667− ihPrintTermWithType h tmDoc tyDoc
701+ iPrintTermWithType tmDoc tyDoc
668
702
669
703
670−process h fn (NewDefn decls) = logLvl 3 ("Defining names using these decls: " ++ show namedGroups) >> mapM_ defineName namedGroups where
704+process fn (NewDefn decls) = logLvl 3 ("Defining names using these decls: " ++ show namedGroups) >> mapM_ defineName namedGroups where
671 namedGroups = groupBy (\d1 d2 -> getName d1 == getName d2) decls
705 namedGroups = groupBy (\d1 d2 -> getName d1 == getName d2) decls
672 getName :: PDecl -> Maybe Name
706 getName :: PDecl -> Maybe Name
673 getName (PTy docs argdocs syn fc opts name ty) = Just name
707 getName (PTy docs argdocs syn fc opts name ty) = Just name
@@ -679,17 +713,17 @@ process h fn (NewDefn decls) = logLvl 3 ("Defining names using these decls: " ++
679 getClauseName (PWith fc name whole with rhs whereBlock) = name
713 getClauseName (PWith fc name whole with rhs whereBlock) = name
680 defineName :: [PDecl] -> Idris ()
714 defineName :: [PDecl] -> Idris ()
681 defineName (tyDecl@(PTy docs argdocs syn fc opts name ty) : decls) = do
715 defineName (tyDecl@(PTy docs argdocs syn fc opts name ty) : decls) = do
682− elabDecl EAll toplevel tyDecl
716+ elabDecl EAll recinfo tyDecl
683− elabClauses toplevel fc opts name (concatMap getClauses decls)
717+ elabClauses recinfo fc opts name (concatMap getClauses decls)
684 defineName [PClauses fc opts _ [clause]] = do
718 defineName [PClauses fc opts _ [clause]] = do
685 let pterm = getRHS clause
719 let pterm = getRHS clause
686− (tm,ty) <- elabVal toplevel ERHS pterm
720+ (tm,ty) <- elabVal recinfo ERHS pterm
687 ctxt <- getContext
721 ctxt <- getContext
688 let tm' = force (normaliseAll ctxt [] tm)
722 let tm' = force (normaliseAll ctxt [] tm)
689 let ty' = force (normaliseAll ctxt [] ty)
723 let ty' = force (normaliseAll ctxt [] ty)
690 updateContext (addCtxtDef (getClauseName clause) (Function ty' tm'))
724 updateContext (addCtxtDef (getClauseName clause) (Function ty' tm'))
691 defineName [PData doc argdocs syn fc opts decl] = do
725 defineName [PData doc argdocs syn fc opts decl] = do
692− elabData toplevel syn doc argdocs fc opts decl
726+ elabData recinfo syn doc argdocs fc opts decl
693 getClauses (PClauses fc opts name clauses) = clauses
727 getClauses (PClauses fc opts name clauses) = clauses
694 getClauses _ = []
728 getClauses _ = []
695 getRHS :: PClause -> PTerm
729 getRHS :: PClause -> PTerm
@@ -698,28 +732,28 @@ process h fn (NewDefn decls) = logLvl 3 ("Defining names using these decls: " ++
698 getRHS (PClauseR fc with rhs whereBlock) = rhs
732 getRHS (PClauseR fc with rhs whereBlock) = rhs
699 getRHS (PWithR fc with rhs whereBlock) = rhs
733 getRHS (PWithR fc with rhs whereBlock) = rhs
700
734
701−process h fn (ExecVal t)
735+process fn (ExecVal t)
702 = do ctxt <- getContext
736 = do ctxt <- getContext
703 ist <- getIState
737 ist <- getIState
704− (tm, ty) <- elabVal toplevel ERHS t
738+ (tm, ty) <- elabVal recinfo ERHS t
705-- let tm' = normaliseAll ctxt [] tm
739-- let tm' = normaliseAll ctxt [] tm
706 let ty' = normaliseAll ctxt [] ty
740 let ty' = normaliseAll ctxt [] ty
707 res <- execute tm
741 res <- execute tm
708 let (resOut, tyOut) = (prettyIst ist (delab ist res),
742 let (resOut, tyOut) = (prettyIst ist (delab ist res),
709 prettyIst ist (delab ist ty'))
743 prettyIst ist (delab ist ty'))
710− ihPrintTermWithType h resOut tyOut
744+ iPrintTermWithType resOut tyOut
711
745
712−process h fn (Check (PRef _ n))
746+process fn (Check (PRef _ n))
713 = do ctxt <- getContext
747 = do ctxt <- getContext
714 ist <- getIState
748 ist <- getIState
715 let ppo = ppOptionIst ist
749 let ppo = ppOptionIst ist
716 case lookupNames n ctxt of
750 case lookupNames n ctxt of
717 ts@(t:_) ->
751 ts@(t:_) ->
718 case lookup t (idris_metavars ist) of
752 case lookup t (idris_metavars ist) of
719− Just (_, i, _) -> ihRenderResult h . fmap (fancifyAnnots ist) $
753+ Just (_, i, _) -> iRenderResult . fmap (fancifyAnnots ist) $
720 showMetavarInfo ppo ist n i
754 showMetavarInfo ppo ist n i
721− Nothing -> ihPrintFunTypes h [] n (map (\n -> (n, delabTy ist n)) ts)
755+ Nothing -> iPrintFunTypes [] n (map (\n -> (n, delabTy ist n)) ts)
722− [] -> ihPrintError h $ "No such variable " ++ show n
756+ [] -> iPrintError $ "No such variable " ++ show n
723 where
757 where
724 showMetavarInfo ppo ist n i
758 showMetavarInfo ppo ist n i
725 = case lookupTy n (tt_ctxt ist) of
759 = case lookupTy n (tt_ctxt ist) of
@@ -744,32 +778,32 @@ process h fn (Check (PRef _ n))
744 tPretty bnd ist t = pprintPTerm (ppOptionIst ist) bnd [] (idris_infixes ist) t
778 tPretty bnd ist t = pprintPTerm (ppOptionIst ist) bnd [] (idris_infixes ist) t
745
779
746
780
747−process h fn (Check t)
781+process fn (Check t)
748− = do (tm, ty) <- elabVal toplevel ERHS t
782+ = do (tm, ty) <- elabVal recinfo ERHS t
749 ctxt <- getContext
783 ctxt <- getContext
750 ist <- getIState
784 ist <- getIState
751 let ppo = ppOptionIst ist
785 let ppo = ppOptionIst ist
752 ty' = normaliseC ctxt [] ty
786 ty' = normaliseC ctxt [] ty
753 case tm of
787 case tm of
754 TType _ ->
788 TType _ ->
755− ihPrintTermWithType h (prettyIst ist PType) type1Doc
789+ iPrintTermWithType (prettyIst ist PType) type1Doc
756− _ -> ihPrintTermWithType h (pprintDelab ist tm)
790+ _ -> iPrintTermWithType (pprintDelab ist tm)
757− (pprintDelab ist ty)
791+ (pprintDelab ist ty)
758
792
759−process h fn (DocStr (Left n))
793+process fn (DocStr (Left n))
760 = do ist <- getIState
794 = do ist <- getIState
761 case lookupCtxtName n (idris_docstrings ist) of
795 case lookupCtxtName n (idris_docstrings ist) of
762 [] -> iPrintError $ "No documentation for " ++ show n
796 [] -> iPrintError $ "No documentation for " ++ show n
763 ns -> do toShow <- mapM (showDoc ist) ns
797 ns -> do toShow <- mapM (showDoc ist) ns
764− ihRenderResult h (vsep toShow)
798+ iRenderResult (vsep toShow)
765 where showDoc ist (n, d) = do doc <- getDocs n
799 where showDoc ist (n, d) = do doc <- getDocs n
766 return $ pprintDocs ist doc
800 return $ pprintDocs ist doc
767
801
768−process h fn (DocStr (Right c))
802+process fn (DocStr (Right c))
769 = do ist <- getIState
803 = do ist <- getIState
770− ihRenderResult h $ pprintConstDocs ist c (constDocs c)
804+ iRenderResult $ pprintConstDocs ist c (constDocs c)
771
805
772−process h fn Universes
806+process fn Universes
773 = do i <- getIState
807 = do i <- getIState
774 let cs = idris_constraints i
808 let cs = idris_constraints i
775-- iputStrLn $ showSep "\n" (map show cs)
809-- iputStrLn $ showSep "\n" (map show cs)
@@ -779,7 +813,7 @@ process h fn Universes
779 case ucheck cs of
813 case ucheck cs of
780 Error e -> iPrintError $ pshow i e
814 Error e -> iPrintError $ pshow i e
781 OK _ -> iPrintResult "Universes OK"
815 OK _ -> iPrintResult "Universes OK"
782−process h fn (Defn n)
816+process fn (Defn n)
783 = do i <- getIState
817 = do i <- getIState
784 iputStrLn "Compiled patterns:\n"
818 iputStrLn "Compiled patterns:\n"
785 iputStrLn $ show (lookupDef n (tt_ctxt i))
819 iputStrLn $ show (lookupDef n (tt_ctxt i))
@@ -794,20 +828,20 @@ process h fn (Defn n)
794 = let i' = i { idris_options = (idris_options i) { opt_showimp = True } }
828 = let i' = i { idris_options = (idris_options i) { opt_showimp = True } }
795 in iputStrLn (showTm i' (delab i lhs) ++ " = " ++
829 in iputStrLn (showTm i' (delab i lhs) ++ " = " ++
796 showTm i' (delab i rhs))
830 showTm i' (delab i rhs))
797−process h fn (TotCheck n)
831+process fn (TotCheck n)
798 = do i <- getIState
832 = do i <- getIState
799 case lookupNameTotal n (tt_ctxt i) of
833 case lookupNameTotal n (tt_ctxt i) of
800− [] -> ihPrintError h $ "Unknown operator " ++ show n
834+ [] -> iPrintError $ "Unknown operator " ++ show n
801 ts -> do ist <- getIState
835 ts -> do ist <- getIState
802 c <- colourise
836 c <- colourise
803 let ppo = ppOptionIst ist
837 let ppo = ppOptionIst ist
804 let showN = showName (Just ist) [] ppo c
838 let showN = showName (Just ist) [] ppo c
805− ihPrintResult h . concat . intersperse "\n" .
839+ iPrintResult . concat . intersperse "\n" .
806 map (\(n, t) -> showN n ++ " is " ++ showTotal t i) $
840 map (\(n, t) -> showN n ++ " is " ++ showTotal t i) $
807 ts
841 ts
808
842
809
843
810−process h fn (DebugInfo n)
844+process fn (DebugInfo n)
811 = do i <- getIState
845 = do i <- getIState
812 let oi = lookupCtxtName n (idris_optimisation i)
846 let oi = lookupCtxtName n (idris_optimisation i)
813 when (not (null oi)) $ iputStrLn (show oi)
847 when (not (null oi)) $ iputStrLn (show oi)
@@ -824,29 +858,29 @@ process h fn (DebugInfo n)
824 iputStrLn $ "Size change: " ++ show sc
858 iputStrLn $ "Size change: " ++ show sc
825 when (not (null cg')) $ do iputStrLn "Call graph:\n"
859 when (not (null cg')) $ do iputStrLn "Call graph:\n"
826 iputStrLn (show cg')
860 iputStrLn (show cg')
827−process h fn (Search t) = searchByType h t
861+process fn (Search t) = searchByType t
828−process h fn (CaseSplitAt updatefile l n)
862+process fn (CaseSplitAt updatefile l n)
829− = caseSplitAt h fn updatefile l n
863+ = caseSplitAt fn updatefile l n
830−process h fn (AddClauseFrom updatefile l n)
864+process fn (AddClauseFrom updatefile l n)
831− = addClauseFrom h fn updatefile l n
865+ = addClauseFrom fn updatefile l n
832−process h fn (AddProofClauseFrom updatefile l n)
866+process fn (AddProofClauseFrom updatefile l n)
833− = addProofClauseFrom h fn updatefile l n
867+ = addProofClauseFrom fn updatefile l n
834−process h fn (AddMissing updatefile l n)
868+process fn (AddMissing updatefile l n)
835− = addMissing h fn updatefile l n
869+ = addMissing fn updatefile l n
836−process h fn (MakeWith updatefile l n)
870+process fn (MakeWith updatefile l n)
837− = makeWith h fn updatefile l n
871+ = makeWith fn updatefile l n
838−process h fn (MakeLemma updatefile l n)
872+process fn (MakeLemma updatefile l n)
839− = makeLemma h fn updatefile l n
873+ = makeLemma fn updatefile l n
840−process h fn (DoProofSearch updatefile rec l n hints)
874+process fn (DoProofSearch updatefile rec l n hints)
841− = doProofSearch h fn updatefile rec l n hints Nothing
875+ = doProofSearch fn updatefile rec l n hints Nothing
842−process h fn (Spec t)
876+process fn (Spec t)
843− = do (tm, ty) <- elabVal toplevel ERHS t
877+ = do (tm, ty) <- elabVal recinfo ERHS t
844 ctxt <- getContext
878 ctxt <- getContext
845 ist <- getIState
879 ist <- getIState
846 let tm' = simplify ctxt [] {- (idris_statics ist) -} tm
880 let tm' = simplify ctxt [] {- (idris_statics ist) -} tm
847 iPrintResult (show (delab ist tm'))
881 iPrintResult (show (delab ist tm'))
848
882
849−process h fn (RmProof n')
883+process fn (RmProof n')
850 = do i <- getIState
884 = do i <- getIState
851 n <- resolveProof n'
885 n <- resolveProof n'
852 let proofs = proof_list i
886 let proofs = proof_list i
@@ -862,7 +896,7 @@ process h fn (RmProof n')
862 let ms = idris_metavars i
896 let ms = idris_metavars i
863 putIState $ i { idris_metavars = (n, (Nothing, 0, False)) : ms }
897 putIState $ i { idris_metavars = (n, (Nothing, 0, False)) : ms }
864
898
865−process h fn' (AddProof prf)
899+process fn' (AddProof prf)
866 = do fn <- do
900 = do fn <- do
867 let fn'' = takeWhile (/= ' ') fn'
901 let fn'' = takeWhile (/= ' ') fn'
868 ex <- runIO $ doesFileExist fn''
902 ex <- runIO $ doesFileExist fn''
@@ -892,7 +926,7 @@ process h fn' (AddProof prf)
892 iputStrLn $ "Added proof " ++ show n
926 iputStrLn $ "Added proof " ++ show n
893 where ls = (lines prog)
927 where ls = (lines prog)
894
928
895−process h fn (ShowProof n')
929+process fn (ShowProof n')
896 = do i <- getIState
930 = do i <- getIState
897 n <- resolveProof n'
931 n <- resolveProof n'
898 let proofs = proof_list i
932 let proofs = proof_list i
@@ -900,7 +934,7 @@ process h fn (ShowProof n')
900 Nothing -> iPrintError "No proof to show"
934 Nothing -> iPrintError "No proof to show"
901 Just p -> iPrintResult $ showProof False n p
935 Just p -> iPrintResult $ showProof False n p
902
936
903−process h fn (Prove n')
937+process fn (Prove n')
904 = do ctxt <- getContext
938 = do ctxt <- getContext
905 ist <- getIState
939 ist <- getIState
906 let ns = lookupNames n' ctxt
940 let ns = lookupNames n' ctxt
@@ -918,23 +952,23 @@ process h fn (Prove n')
918 mapM_ checkDeclTotality (idris_totcheck i)
952 mapM_ checkDeclTotality (idris_totcheck i)
919 warnTotality
953 warnTotality
920
954
921−process h fn (HNF t)
955+process fn (HNF t)
922− = do (tm, ty) <- elabVal toplevel ERHS t
956+ = do (tm, ty) <- elabVal recinfo ERHS t
923 ctxt <- getContext
957 ctxt <- getContext
924 ist <- getIState
958 ist <- getIState
925 let tm' = hnf ctxt [] tm
959 let tm' = hnf ctxt [] tm
926 iPrintResult (show (delab ist tm'))
960 iPrintResult (show (delab ist tm'))
927−process h fn (TestInline t)
961+process fn (TestInline t)
928− = do (tm, ty) <- elabVal toplevel ERHS t
962+ = do (tm, ty) <- elabVal recinfo ERHS t
929 ctxt <- getContext
963 ctxt <- getContext
930 ist <- getIState
964 ist <- getIState
931 let tm' = inlineTerm ist tm
965 let tm' = inlineTerm ist tm
932 c <- colourise
966 c <- colourise
933 iPrintResult (showTm ist (delab ist tm'))
967 iPrintResult (showTm ist (delab ist tm'))
934−process h fn Execute
968+process fn Execute
935 = idrisCatch
969 = idrisCatch
936 (do ist <- getIState
970 (do ist <- getIState
937− (m, _) <- elabVal toplevel ERHS
971+ (m, _) <- elabVal recinfo ERHS
938 (PApp fc
972 (PApp fc
939 (PRef fc (sUN "run__IO"))
973 (PRef fc (sUN "run__IO"))
940 [pexp $ PRef fc (sNS (sUN "main") ["Main"])])
974 [pexp $ PRef fc (sNS (sUN "main") ["Main"])])
@@ -943,33 +977,33 @@ process h fn Execute
943 t <- codegen
977 t <- codegen
944 compile t tmpn m
978 compile t tmpn m
945 case idris_outputmode ist of
979 case idris_outputmode ist of
946− RawOutput -> do runIO $ system tmpn
980+ RawOutput h -> do runIO $ system tmpn
947− return ()
981+ return ()
948− IdeSlave n -> runIO . hPutStrLn h $
982+ IdeSlave n h -> runIO . hPutStrLn h $
949− IdeSlave.convSExp "run-program" tmpn n)
983+ IdeSlave.convSExp "run-program" tmpn n)
950− (\e -> getIState >>= ihRenderError stdout . flip pprintErr e)
984+ (\e -> getIState >>= iRenderError . flip pprintErr e)
951 where fc = fileFC "main"
985 where fc = fileFC "main"
952−process h fn (Compile codegen f)
986+process fn (Compile codegen f)
953− = do (m, _) <- elabVal toplevel ERHS
987+ = do (m, _) <- elabVal recinfo ERHS
954 (PApp fc (PRef fc (sUN "run__IO"))
988 (PApp fc (PRef fc (sUN "run__IO"))
955 [pexp $ PRef fc (sNS (sUN "main") ["Main"])])
989 [pexp $ PRef fc (sNS (sUN "main") ["Main"])])
956 compile codegen f m
990 compile codegen f m
957 where fc = fileFC "main"
991 where fc = fileFC "main"
958−process h fn (LogLvl i) = setLogLevel i
992+process fn (LogLvl i) = setLogLevel i
959-- Elaborate as if LHS of a pattern (debug command)
993-- Elaborate as if LHS of a pattern (debug command)
960−process h fn (Pattelab t)
994+process fn (Pattelab t)
961− = do (tm, ty) <- elabVal toplevel ELHS t
995+ = do (tm, ty) <- elabVal recinfo ELHS t
962 iPrintResult $ show tm ++ "\n\n : " ++ show ty
996 iPrintResult $ show tm ++ "\n\n : " ++ show ty
963
997
964−process h fn (Missing n)
998+process fn (Missing n)
965 = do i <- getIState
999 = do i <- getIState
966 let i' = i { idris_options = (idris_options i) { opt_showimp = True } }
1000 let i' = i { idris_options = (idris_options i) { opt_showimp = True } }
967 case lookupCtxt n (idris_patdefs i) of
1001 case lookupCtxt n (idris_patdefs i) of
968− [] -> ihPrintError h $ "Unknown operator " ++ show n
1002+ [] -> iPrintError $ "Unknown operator " ++ show n
969 [(_, tms)] ->
1003 [(_, tms)] ->
970 iPrintResult (showSep "\n" (map (showTm i') tms))
1004 iPrintResult (showSep "\n" (map (showTm i') tms))
971 _ -> iPrintError $ "Ambiguous name"
1005 _ -> iPrintError $ "Ambiguous name"
972−process h fn (DynamicLink l)
1006+process fn (DynamicLink l)
973 = do i <- getIState
1007 = do i <- getIState
974 let importdirs = opt_importdirs (idris_options i)
1008 let importdirs = opt_importdirs (idris_options i)
975 lib = trim l
1009 lib = trim l
@@ -982,80 +1016,80 @@ process h fn (DynamicLink l)
982 return ()
1016 return ()
983 else putIState $ i { idris_dynamic_libs = x:libs }
1017 else putIState $ i { idris_dynamic_libs = x:libs }
984 where trim = reverse . dropWhile isSpace . reverse . dropWhile isSpace
1018 where trim = reverse . dropWhile isSpace . reverse . dropWhile isSpace
985−process h fn ListDynamic
1019+process fn ListDynamic
986 = do i <- getIState
1020 = do i <- getIState
987 iputStrLn "Dynamic libraries:"
1021 iputStrLn "Dynamic libraries:"
988 showLibs $ idris_dynamic_libs i
1022 showLibs $ idris_dynamic_libs i
989 where showLibs [] = return ()
1023 where showLibs [] = return ()
990 showLibs ((Lib name _):ls) = do iputStrLn $ "\t" ++ name; showLibs ls
1024 showLibs ((Lib name _):ls) = do iputStrLn $ "\t" ++ name; showLibs ls
991−process h fn Metavars
1025+process fn Metavars
992 = do ist <- getIState
1026 = do ist <- getIState
993 let mvs = map fst (idris_metavars ist) \\ primDefs
1027 let mvs = map fst (idris_metavars ist) \\ primDefs
994 case mvs of
1028 case mvs of
995 [] -> iPrintError "No global metavariables to solve"
1029 [] -> iPrintError "No global metavariables to solve"
996 _ -> iPrintResult $ "Global metavariables:\n\t" ++ show mvs
1030 _ -> iPrintResult $ "Global metavariables:\n\t" ++ show mvs
997−process h fn NOP = return ()
1031+process fn NOP = return ()
998−
1032+
999−process h fn (SetOpt ErrContext) = setErrContext True
1033+process fn (SetOpt ErrContext) = setErrContext True
1000−process h fn (UnsetOpt ErrContext) = setErrContext False
1034+process fn (UnsetOpt ErrContext) = setErrContext False
1001−process h fn (SetOpt ShowImpl) = setImpShow True
1035+process fn (SetOpt ShowImpl) = setImpShow True
1002−process h fn (UnsetOpt ShowImpl) = setImpShow False
1036+process fn (UnsetOpt ShowImpl) = setImpShow False
1003−process h fn (SetOpt ShowOrigErr) = setShowOrigErr True
1037+process fn (SetOpt ShowOrigErr) = setShowOrigErr True
1004−process h fn (UnsetOpt ShowOrigErr) = setShowOrigErr False
1038+process fn (UnsetOpt ShowOrigErr) = setShowOrigErr False
1005−process h fn (SetOpt AutoSolve) = setAutoSolve True
1039+process fn (SetOpt AutoSolve) = setAutoSolve True
1006−process h fn (UnsetOpt AutoSolve) = setAutoSolve False
1040+process fn (UnsetOpt AutoSolve) = setAutoSolve False
1007−process h fn (SetOpt NoBanner) = setNoBanner True
1041+process fn (SetOpt NoBanner) = setNoBanner True
1008−process h fn (UnsetOpt NoBanner) = setNoBanner False
1042+process fn (UnsetOpt NoBanner) = setNoBanner False
1009−process h fn (SetOpt WarnReach) = fmodifyState opts_idrisCmdline $ nub . (WarnReach:)
1043+process fn (SetOpt WarnReach) = fmodifyState opts_idrisCmdline $ nub . (WarnReach:)
1010−process h fn (UnsetOpt WarnReach) = fmodifyState opts_idrisCmdline $ delete WarnReach
1044+process fn (UnsetOpt WarnReach) = fmodifyState opts_idrisCmdline $ delete WarnReach
1011−
1045+
1012−process h fn (SetOpt _) = iPrintError "Not a valid option"
1046+process fn (SetOpt _) = iPrintError "Not a valid option"
1013−process h fn (UnsetOpt _) = iPrintError "Not a valid option"
1047+process fn (UnsetOpt _) = iPrintError "Not a valid option"
1014−process h fn (SetColour ty c) = setColour ty c
1048+process fn (SetColour ty c) = setColour ty c
1015−process h fn ColourOn
1049+process fn ColourOn
1016 = do ist <- getIState
1050 = do ist <- getIState
1017 putIState $ ist { idris_colourRepl = True }
1051 putIState $ ist { idris_colourRepl = True }
1018−process h fn ColourOff
1052+process fn ColourOff
1019 = do ist <- getIState
1053 = do ist <- getIState
1020 putIState $ ist { idris_colourRepl = False }
1054 putIState $ ist { idris_colourRepl = False }
1021−process h fn ListErrorHandlers =
1055+process fn ListErrorHandlers =
1022 do ist <- getIState
1056 do ist <- getIState
1023 iPrintResult $ case idris_errorhandlers ist of
1057 iPrintResult $ case idris_errorhandlers ist of
1024 [] -> "No registered error handlers"
1058 [] -> "No registered error handlers"
1025 handlers -> "Registered error handlers: " ++ (concat . intersperse ", " . map show) handlers
1059 handlers -> "Registered error handlers: " ++ (concat . intersperse ", " . map show) handlers
1026−process h fn (SetConsoleWidth w) = setWidth w
1060+process fn (SetConsoleWidth w) = setWidth w
1027
1061
1028−process h fn (Apropos a) =
1062+process fn (Apropos a) =
1029 do ist <- getIState
1063 do ist <- getIState
1030 let names = apropos ist (T.pack a)
1064 let names = apropos ist (T.pack a)
1031 let aproposInfo = [ (n,
1065 let aproposInfo = [ (n,
1032 delabTy ist n,
1066 delabTy ist n,
1033 fmap (overview . fst) (lookupCtxtExact n (idris_docstrings ist)))
1067 fmap (overview . fst) (lookupCtxtExact n (idris_docstrings ist)))
1034 | n <- sort names, isUN n ]
1068 | n <- sort names, isUN n ]
1035− ihRenderResult h $ vsep (map (prettyDocumentedIst ist) aproposInfo)
1069+ iRenderResult $ vsep (map (prettyDocumentedIst ist) aproposInfo)
1036 where isUN (UN _) = True
1070 where isUN (UN _) = True
1037 isUN (NS n _) = isUN n
1071 isUN (NS n _) = isUN n
1038 isUN _ = False
1072 isUN _ = False
1039
1073
1040−process h fn (WhoCalls n) =
1074+process fn (WhoCalls n) =
1041 do calls <- whoCalls n
1075 do calls <- whoCalls n
1042 ist <- getIState
1076 ist <- getIState
1043− ihRenderResult h . vsep $
1077+ iRenderResult . vsep $
1044 map (\(n, ns) ->
1078 map (\(n, ns) ->
1045 text "Callers of" <+> prettyName True True [] n <$>
1079 text "Callers of" <+> prettyName True True [] n <$>
1046 indent 1 (vsep (map ((text "*" <+>) . align . prettyName True True []) ns)))
1080 indent 1 (vsep (map ((text "*" <+>) . align . prettyName True True []) ns)))
1047 calls
1081 calls
1048
1082
1049−process h fn (CallsWho n) =
1083+process fn (CallsWho n) =
1050 do calls <- callsWho n
1084 do calls <- callsWho n
1051 ist <- getIState
1085 ist <- getIState
1052− ihRenderResult h . vsep $
1086+ iRenderResult . vsep $
1053 map (\(n, ns) ->
1087 map (\(n, ns) ->
1054 prettyName True True [] n <+> text "calls:" <$>
1088 prettyName True True [] n <+> text "calls:" <$>
1055 indent 1 (vsep (map ((text "*" <+>) . align . prettyName True True []) ns)))
1089 indent 1 (vsep (map ((text "*" <+>) . align . prettyName True True []) ns)))
1056 calls
1090 calls
1057-- IdrisDoc
1091-- IdrisDoc
1058−process h fn (MakeDoc s) =
1092+process fn (MakeDoc s) =
1059 do istate <- getIState
1093 do istate <- getIState
1060 let names = words s
1094 let names = words s
1061 parse n | Success x <- runparser name istate fn n = Right x
1095 parse n | Success x <- runparser name istate fn n = Right x
@@ -1112,8 +1146,8 @@ idris opts = do res <- runErrorT $ execStateT totalMain idrisInit
1112 [] -> return ()
1146 [] -> return ()
1113
1147
1114
1148
1115−loadInputs :: Handle -> [FilePath] -> Maybe Int -> Idris ()
1149+loadInputs :: [FilePath] -> Maybe Int -> Idris ()
1116−loadInputs h inputs toline -- furthest line to read in input source files
1150+loadInputs inputs toline -- furthest line to read in input source files
1117 = idrisCatch
1151 = idrisCatch
1118 (do ist <- getIState
1152 (do ist <- getIState
1119 -- if we're in --check and not outputting anything, don't bother
1153 -- if we're in --check and not outputting anything, don't bother
@@ -1165,10 +1199,10 @@ loadInputs h inputs toline -- furthest line to read in input source files
1165 (\e -> do i <- getIState
1199 (\e -> do i <- getIState
1166 case e of
1200 case e of
1167 At f e' -> do setErrSpan f
1201 At f e' -> do setErrSpan f
1168− ihWarn stdout f $ pprintErr i e'
1202+ iWarn f $ pprintErr i e'
1169 ProgramLineComment -> return () -- fail elsewhere
1203 ProgramLineComment -> return () -- fail elsewhere
1170 _ -> do setErrSpan emptyFC -- FIXME! Propagate it
1204 _ -> do setErrSpan emptyFC -- FIXME! Propagate it
1171− ihWarn stdout emptyFC $ pprintErr i e)
1205+ iWarn emptyFC $ pprintErr i e)
1172 where -- load all files, stop if any fail
1206 where -- load all files, stop if any fail
1173 tryLoad :: Bool -> [IFileType] -> Idris ()
1207 tryLoad :: Bool -> [IFileType] -> Idris ()
1174 tryLoad keepstate [] = warnTotality >> return ()
1208 tryLoad keepstate [] = warnTotality >> return ()
@@ -1185,7 +1219,7 @@ loadInputs h inputs toline -- furthest line to read in input source files
1185 then Just l
1219 then Just l
1186 else Nothing
1220 else Nothing
1187 _ -> Nothing
1221 _ -> Nothing
1188− loadFromIFile h f maxline
1222+ loadFromIFile f maxline
1189 inew <- getIState
1223 inew <- getIState
1190 -- FIXME: Save these in IBC to avoid this hack! Need to
1224 -- FIXME: Save these in IBC to avoid this hack! Need to
1191 -- preserve it all from source inputs
1225 -- preserve it all from source inputs
@@ -1233,7 +1267,7 @@ idrisMain opts =
1233 do let inputs = opt getFile opts
1267 do let inputs = opt getFile opts
1234 let quiet = Quiet `elem` opts
1268 let quiet = Quiet `elem` opts
1235 let nobanner = NoBanner `elem` opts
1269 let nobanner = NoBanner `elem` opts
1236− let idesl = Ideslave `elem` opts
1270+ let idesl = Ideslave `elem` opts || IdeslaveSocket `elem` opts
1237 let runrepl = not (NoREPL `elem` opts)
1271 let runrepl = not (NoREPL `elem` opts)
1238 let verbose = runrepl || Verbose `elem` opts
1272 let verbose = runrepl || Verbose `elem` opts
1239 let output = opt getOutput opts
1273 let output = opt getOutput opts
@@ -1270,7 +1304,6 @@ idrisMain opts =
1270 mapM_ addLangExt (opt getLanguageExt opts)
1304 mapM_ addLangExt (opt getLanguageExt opts)
1271 setREPL runrepl
1305 setREPL runrepl
1272 setQuiet (quiet || isJust script || not (null immediate))
1306 setQuiet (quiet || isJust script || not (null immediate))
1273− setIdeSlave idesl
1274 setVerbose verbose
1307 setVerbose verbose
1275 setCmdLine opts
1308 setCmdLine opts
1276 setOutputTy outty
1309 setOutputTy outty
@@ -1296,9 +1329,9 @@ idrisMain opts =
1296 addPkgDir "base"
1329 addPkgDir "base"
1297 mapM_ addPkgDir pkgdirs
1330 mapM_ addPkgDir pkgdirs
1298 elabPrims
1331 elabPrims
1299− when (not (NoBuiltins `elem` opts)) $ do x <- loadModule stdout "Builtins"
1332+ when (not (NoBuiltins `elem` opts)) $ do x <- loadModule "Builtins"
1300 return ()
1333 return ()
1301− when (not (NoPrelude `elem` opts)) $ do x <- loadModule stdout "Prelude"
1334+ when (not (NoPrelude `elem` opts)) $ do x <- loadModule "Prelude"
1302 return ()
1335 return ()
1303
1336
1304 when (runrepl && not idesl) initScript
1337 when (runrepl && not idesl) initScript
@@ -1314,14 +1347,14 @@ idrisMain opts =
1314 iputStrLn banner
1347 iputStrLn banner
1315
1348
1316 orig <- getIState
1349 orig <- getIState
1317− loadInputs stdout inputs Nothing
1350+ when (not idesl) $ loadInputs inputs Nothing
1318
1351
1319 runIO $ hSetBuffering stdout LineBuffering
1352 runIO $ hSetBuffering stdout LineBuffering
1320
1353
1321 ok <- noErrors
1354 ok <- noErrors
1322 when ok $ case output of
1355 when ok $ case output of
1323 [] -> return ()
1356 [] -> return ()
1324− (o:_) -> idrisCatch (process stdout "" (Compile cgn o))
1357+ (o:_) -> idrisCatch (process "" (Compile cgn o))
1325 (\e -> do ist <- getIState ; iputStrLn $ pshow ist e)
1358 (\e -> do ist <- getIState ; iputStrLn $ pshow ist e)
1326
1359
1327 case immediate of
1360 case immediate of
@@ -1332,7 +1365,7 @@ idrisMain opts =
1332 case parseExpr ist str of
1365 case parseExpr ist str of
1333 Failure err -> do iputStrLn $ show (fixColour c err)
1366 Failure err -> do iputStrLn $ show (fixColour c err)
1334 runIO $ exitWith (ExitFailure 1)
1367 runIO $ exitWith (ExitFailure 1)
1335− Success e -> process stdout "" (Eval e))
1368+ Success e -> process "" (Eval e))
1336 exprs
1369 exprs
1337 runIO $ exitWith ExitSuccess
1370 runIO $ exitWith ExitSuccess
1338
1371
@@ -1354,7 +1387,8 @@ idrisMain opts =
1354-- clearOrigPats
1387-- clearOrigPats
1355 startServer orig inputs
1388 startServer orig inputs
1356 runInputT (replSettings (Just historyFile)) $ repl orig inputs
1389 runInputT (replSettings (Just historyFile)) $ repl orig inputs
1390+ let idesock = IdeslaveSocket `elem` opts
1357− when (idesl) $ ideslaveStart orig inputs
1391+ when (idesl) $ ideslaveStart idesock orig inputs
1358 ok <- noErrors
1392 ok <- noErrors
1359 when (not ok) $ runIO (exitWith (ExitFailure 1))
1393 when (not ok) $ runIO (exitWith (ExitFailure 1))
1360 where
1394 where
@@ -1376,7 +1410,7 @@ execScript expr = do i <- getIState
1376 Failure err -> do iputStrLn $ show (fixColour c err)
1410 Failure err -> do iputStrLn $ show (fixColour c err)
1377 runIO $ exitWith (ExitFailure 1)
1411 runIO $ exitWith (ExitFailure 1)
1378 Success term -> do ctxt <- getContext
1412 Success term -> do ctxt <- getContext
1379− (tm, _) <- elabVal toplevel ERHS term
1413+ (tm, _) <- elabVal recinfo ERHS term
1380 res <- execute tm
1414 res <- execute tm
1381 runIO $ exitWith ExitSuccess
1415 runIO $ exitWith ExitSuccess
1382
1416
@@ -1416,7 +1450,7 @@ initScript = do script <- getInitScript
1416 Success Edit -> iPrintError "Init scripts cannot invoke the editor"
1450 Success Edit -> iPrintError "Init scripts cannot invoke the editor"
1417 Success Proofs -> proofs i
1451 Success Proofs -> proofs i
1418 Success Quit -> iPrintError "Init scripts cannot quit Idris"
1452 Success Quit -> iPrintError "Init scripts cannot quit Idris"
1419− Success cmd -> process stdout [] cmd
1453+ Success cmd -> process [] cmd
1420
1454
1421getFile :: Opt -> Maybe String
1455getFile :: Opt -> Maybe String
1422getFile (Filename str) = Just str
1456getFile (Filename str) = Just str
src/Idris/TypeSearch.hs+8−10
@@ -28,20 +28,18 @@ import Idris.Core.TT hiding (score)
28import Idris.Core.Unify (match_unify)
28import Idris.Core.Unify (match_unify)
29import Idris.Delaborate (delabTy)
29import Idris.Delaborate (delabTy)
30import Idris.Docstrings (noDocs, overview)
30import Idris.Docstrings (noDocs, overview)
31−import Idris.ElabDecls (elabType')
31+import Idris.Elab.Type (elabType)
32−import Idris.Output (ihRenderOutput, ihPrintResult, ihRenderResult)
32+import Idris.Output (iRenderOutput, iPrintResult, iRenderResult)
33−
34−import System.IO (Handle)
35
33
36import Util.Pretty (text, char, vsep, (<>), Doc)
34import Util.Pretty (text, char, vsep, (<>), Doc)
37
35
38−searchByType :: Handle -> PTerm -> Idris ()
36+searchByType :: PTerm -> Idris ()
39−searchByType h pterm = do
37+searchByType pterm = do
40 pterm' <- addUsingConstraints syn emptyFC pterm
38 pterm' <- addUsingConstraints syn emptyFC pterm
41 pterm'' <- implicit toplevel syn n pterm'
39 pterm'' <- implicit toplevel syn n pterm'
42 i <- getIState
40 i <- getIState
43 let pterm''' = addImpl i pterm''
41 let pterm''' = addImpl i pterm''
44− ty <- elabType' False toplevel syn (fst noDocs) (snd noDocs) emptyFC [] n pterm'
42+ ty <- elabType toplevel syn (fst noDocs) (snd noDocs) emptyFC [] n pterm'
45 putIState i -- don't actually make any changes
43 putIState i -- don't actually make any changes
46 let names = searchUsing searchPred i ty
44 let names = searchUsing searchPred i ty
47 let names' = take numLimit $ names
45 let names' = take numLimit $ names
@@ -50,9 +48,9 @@ searchByType h pterm = do
50 displayScore score <> char ' ' <> prettyDocumentedIst i docInfo
48 displayScore score <> char ' ' <> prettyDocumentedIst i docInfo
51 | (n, score) <- names']
49 | (n, score) <- names']
52 case idris_outputmode i of
50 case idris_outputmode i of
53− RawOutput -> do mapM_ (ihRenderOutput h) docs
51+ RawOutput _ -> do mapM_ iRenderOutput docs
54− ihPrintResult h ""
52+ iPrintResult ""
55− IdeSlave n -> ihRenderResult h (vsep docs)
53+ IdeSlave n h -> iRenderResult (vsep docs)
56 where
54 where
57 numLimit = 50
55 numLimit = 50
58 syn = defaultSyntax { implicitAllowed = True } -- syntax
56 syn = defaultSyntax { implicitAllowed = True } -- syntax
src/Pkg/Package.hs+1−1
@@ -144,7 +144,7 @@ documentPkg fp =
144 setCurrentDirectory $ pkgDir
144 setCurrentDirectory $ pkgDir
145 let run l = runErrorT . (execStateT l)
145 let run l = runErrorT . (execStateT l)
146 load [] = return ()
146 load [] = return ()
147− load (f:fs) = do loadModule stdout f; load fs
147+ load (f:fs) = do loadModule f; load fs
148 loader = do idrisMain opts; load fs
148 loader = do idrisMain opts; load fs
149 idrisInstance <- run loader idrisInit
149 idrisInstance <- run loader idrisInit
150 setCurrentDirectory cd
150 setCurrentDirectory cd
src/Util/Net.hs+15−2
@@ -1,6 +1,6 @@
1−module Util.Net (listenOnLocalhost) where
1+module Util.Net (listenOnLocalhost, listenOnLocalhostAnyPort) where
2
2
3−import Network
3+import Network hiding (socketPort)
4import Network.Socket hiding (sClose, PortNumber)
4import Network.Socket hiding (sClose, PortNumber)
5import Network.BSD (getProtocolNumber)
5import Network.BSD (getProtocolNumber)
6import Control.Exception (bracketOnError)
6import Control.Exception (bracketOnError)
@@ -20,3 +20,16 @@ listenOnLocalhost (PortNumber port) = do
20 return sock
20 return sock
21 )
21 )
22
22
23+listenOnLocalhostAnyPort = do
24+ proto <- getProtocolNumber "tcp"
25+ localhost <- inet_addr "127.0.0.1"
26+ bracketOnError
27+ (socket AF_INET Stream proto)
28+ (sClose)
29+ (\sock -> do
30+ setSocketOption sock ReuseAddr 1
31+ bindSocket sock (SockAddrInet aNY_PORT localhost)
32+ listen sock maxListenQueue
33+ port <- socketPort sock
34+ return (sock, port)
35+ )
test/proof007/DefaultArgUnknownName.idr+7−1
@@ -1,4 +1,10 @@
1module DefaultArgUnknownName
1module DefaultArgUnknownName
2
2
3+-- FIXME: What is the expected behaviour here? Should the type declaration
4+-- not compile?
3funWithBadDefArg : { default sadgjhsag arg : () } -> ()
5funWithBadDefArg : { default sadgjhsag arg : () } -> ()
4−funWithBadDefArg : _ = ()
6+funWithBadDefArg = ()
7+
8+test : ()
9+test = funWithBadDefArg
10+
test/proof007/expected+3−2
@@ -1,2 +1,3 @@
1−DefaultArgUnknownName.idr:3:18:When elaborating type of DefaultArgUnknownName.funWithBadDefArg:
1+DefaultArgUnknownName.idr:5:30:When elaborating right hand side of test:
2−Can't infer type for sadgjhsag
2+When elaborating argument arg to function DefaultArgUnknownName.funWithBadDefArg:
3+ No such variable sadgjhsag
test/reg049/expectednew file+2
@@ -0,0 +1,2 @@
1+reg049.idr:2:9:When elaborating constructor Main.Bogus:
2+{__False0} is not Main.Foo
test/reg049/reg049.idrnew file+5
@@ -0,0 +1,5 @@
1+data Foo : Type where
2+ Bogus : _|_
3+
4+uhOh : _|_
5+uhOh = Bogus
test/reg049/runnew file+3
@@ -0,0 +1,3 @@
1+#!/usr/bin/env bash
2+idris --nocolour --check $@ reg049.idr
3+rm -f *.ibc
test/reg050/badbangop.idrnew file+15
@@ -0,0 +1,15 @@
1+module badbangop
2+
3+-- Check that using "!" by itself as an operator does not work
4+
5+infixl 2 !
6+
7+(!) : List a -> Nat -> Maybe a
8+xs ! n = index' n xs
9+
10+aList : List Integer
11+aList = [1,2,3,4,5]
12+
13+opUse : Maybe Integer
14+opUse = aList ! 2
15+
test/reg050/baddoublebang.idrnew file+7
@@ -0,0 +1,7 @@
1+module baddoublebang
2+
3+-- Check that two bang bindings running together don't work
4+
5+doubleBang : Maybe (Maybe Nat) -> Maybe Nat
6+doubleBang mmn = do pure !!mmn
7+
test/reg050/expectednew file+27
@@ -0,0 +1,27 @@
1+badbangop.idr:16:1:When elaborating right hand side of opUse:
2+When elaborating an application of function Prelude.Monad.>>=:
3+ Can't unify
4+ List Integer
5+ with
6+ argTy -> retTy
7+
8+ Specifically:
9+ Can't unify
10+ List
11+ with
12+ \{uv0} => argTy -> uv
13+./baddoublebang.idr:6:26: error: not
14+ a terminator, expected: "$",
15+ "$>", "&&", "*", "+", "++", "-",
16+ "->", ".", "/", "/=", "::", ";",
17+ "<", "<$", "<$>", "<*>", "<+>",
18+ "<->", "<<", "<=", "<|>", "=",
19+ "==", ">", ">=", ">>", ">>=",
20+ "\\\\", "`", "in", "||", "~=~",
21+ ambiguous use of a left-associative operator,
22+ ambiguous use of a non-associative operator,
23+ ambiguous use of a right-associative operator,
24+ end of input, function argument,
25+ matching application expression
26+doubleBang mmn = do pure !!mmn
27+ ^
test/reg050/runnew file+5
@@ -0,0 +1,5 @@
1+#!/usr/bin/env bash
2+idris --nocolour --check $@ working.idr
3+idris --nocolour --check $@ badbangop.idr
4+idris --nocolour --check $@ baddoublebang.idr
5+rm -f *.ibc
test/reg050/working.idrnew file+21
@@ -0,0 +1,21 @@
1+module working
2+
3+-- Check that using an operator beginning with "!" works
4+
5+infixl 2 !!
6+
7+(!!) : List a -> Nat -> Maybe a
8+xs !! n = index' n xs
9+
10+aList : List Integer
11+aList = [1,2,3,4,5]
12+
13+opUse : Maybe Integer
14+opUse = aList !! 2
15+
16+opUseWithBang : Maybe Nat -> Maybe Integer
17+opUseWithBang mn = do aList !! !mn
18+
19+doubleBang : Maybe (Maybe Nat) -> Maybe Nat
20+doubleBang mmn = do pure ! !mmn
21+