on master help sign in
Merge branch 'master' of github.com:idris-lang/Idris-dev
0c96d97Edwin Brady
idris.cabal+3
@@ -247,6 +247,9 @@ Extra-source-files:
247 test/reg049/run
247 test/reg049/run
248 test/reg049/*.idr
248 test/reg049/*.idr
249 test/reg049/expected
249 test/reg049/expected
250+ test/reg050/run
251+ test/reg050/*.idr
252+ test/reg050/expected
250
253
251 test/basic001/run
254 test/basic001/run
252 test/basic001/*.idr
255 test/basic001/*.idr
libs/base/Language/Reflection.idr+183−91
@@ -2,24 +2,28 @@ 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
25data NativeTy = IT8 | IT16 | IT32 | IT64
29data NativeTy = IT8 | IT16 | IT32 | IT64
@@ -133,98 +137,125 @@ instance Traversable Binder where
133
137
134
138
135||| 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)
136−data TT = P NameType TTName TT
142+ P NameType TTName TT |
137− -- ^ named binders
138− | V Int
139− -- ^ variables
143+ ||| de Bruijn variables
144+ V Int |
145+ ||| Bind a variable
140− | Bind TTName (Binder TT) TT
146+ Bind TTName (Binder TT) TT |
141− -- ^ type annotated named bindings
147+ ||| Apply one term to another
142− | App TT TT
148+ App TT TT |
143− -- ^ (named) application of a function to a value
149+ ||| Embed a constant
144− | TConst Const
150+ TConst Const |
145− -- ^ constants
146− | Proj TT Int
147− -- ^ argument projection; runtime only
151+ ||| Argument projection; runtime only
152+ Proj TT Int |
148− | Erased
153+ ||| Erased terms
149− -- ^ erased terms
154+ Erased |
150− | Impossible
155+ ||| Impossible terms
151− -- ^ impossible terms
156+ Impossible |
157+ ||| The type of types along (with universe constraints)
152− | TType TTUExp
158+ TType TTUExp
153− -- ^ types
154−
155%name TT tm, tm'
159%name TT tm, tm'
156
160
157||| Raw terms without types
161||| Raw terms without types
162+data Raw =
163+ ||| Variables, global or local
158−data Raw = Var TTName
164+ Var TTName |
165+ ||| Bind a variable
159− | RBind TTName (Binder Raw) Raw
166+ RBind TTName (Binder Raw) Raw |
167+ ||| Application
160− | RApp Raw Raw
168+ RApp Raw Raw |
169+ ||| The type of types
161− | RType
170+ RType |
162− | RForce Raw
171+ RForce Raw |
172+ ||| Embed a constant
163− | RConstant Const
173+ RConstant Const
164−
165%name Raw tm, tm'
174%name Raw tm, tm'
166
175
167||| Error reports are a list of report parts
176||| Error reports are a list of report parts
168−data ErrorReportPart = TextPart String
177+data ErrorReportPart =
178+ ||| A human-readable string
179+ TextPart String |
180+ ||| An Idris name (to be semantically coloured)
169− | NamePart TTName
181+ NamePart TTName |
182+ ||| An Idris term, to be pretty printed
170− | TermPart TT
183+ TermPart TT |
184+ ||| An indented sub-report, to provide more details
171− | SubReport (List ErrorReportPart)
185+ SubReport (List ErrorReportPart)
172%name ErrorReportPart part, p
186%name ErrorReportPart part, p
173
187
188+||| A representation of Idris's tactics that can be returned from custom
189+||| tactic implementations. Generate these using `applyTactic`.
174−data Tactic = Try Tactic Tactic
190+data Tactic =
175− -- ^ 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
176− | GoalType String Tactic
192+ Try Tactic Tactic |
177− -- ^ only run if the goal has the right type
193+ ||| Only run if the goal has the right type
178− | Refine TTName
194+ GoalType String Tactic |
179− -- ^ resolve function name, find matching arguments in the
195+ ||| Resolve function name, find matching arguments in the
180− -- context and compute the proof target
196+ ||| context and compute the proof target
181− | Seq Tactic Tactic
197+ Refine TTName |
182− -- ^ apply both tactics in sequence
198+ ||| Apply both tactics in sequence
199+ Seq Tactic Tactic |
200+ ||| Intelligently construct the proof target from the context
183− | Trivial
201+ Trivial |
184− -- ^ intelligently construct the proof target from the context
185− | Search Int
186− -- ^ build a proof by applying contructors up to a maximum depth
202+ ||| Build a proof by applying contructors up to a maximum depth
187− | Instance
203+ Search Int |
188− -- ^ resolve a type class
204+ ||| Resolve a type class
205+ Instance |
206+ ||| Infer the proof target from the context
189− | Solve
207+ Solve |
190− -- ^ infer the proof target from the context
191− | Intros
192− -- ^ introduce all variables into the context
208+ ||| introduce all variables into the context
193− | Intro TTName
209+ Intros |
194− -- ^ introduce a named variable into the context, use the
210+ ||| Introduce a named variable into the context, use the
195− -- 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
196− | ApplyTactic TT
214+ ApplyTactic TT |
197− -- ^ invoke the reflected rep. of another tactic
215+ ||| Turn a value into its reflected representation
198− | Reflect TT
216+ Reflect TT |
199− -- ^ turn a value into its reflected representation
200− | ByReflection TT
201− -- ^ use a %reflection function
217+ ||| Use a `%reflection` function
202− | Fill Raw
218+ ByReflection TT |
203− -- ^ turn a raw value back into a term
219+ ||| Turn a raw value back into a term
204− | Exact TT
220+ Fill Raw |
205− -- ^ use the given value to conclude the proof
221+ ||| Use the given value to conclude the proof
206− | Focus TTName
222+ Exact TT |
207− -- ^ focus a named hole
223+ ||| Focus on a particular hole
208− | Rewrite TT
224+ Focus TTName |
209− -- ^ rewrite using the reflected rep. of a equality proof
225+ ||| Rewrite with an equality
210− | Induction TT
226+ Rewrite TT |
211− -- ^ do induction on the particular expression
227+ ||| Perform induction on a particular expression
212− | Case TT
228+ Induction TT |
213− -- ^ do case analysis on particular expression
229+ ||| Perform case analysis on a particular expression
230+ Case TT |
231+ ||| Name a reflected term
214− | LetTac TTName TT
232+ LetTac TTName TT |
215− -- ^ name a reflected term
233+ ||| Name a reflected term and type it
216− | LetTacTy TTName TT TT
234+ LetTacTy TTName TT TT |
217− -- ^ name a reflected term and type it
235+ ||| Normalise the goal
218− | Compute
236+ Compute |
219− -- ^ normalise the context
237+ ||| Do nothing
220− | Skip
238+ Skip |
221− -- ^ do nothing
239+ ||| Fail with an error message
222− | Fail (List ErrorReportPart)
240+ Fail (List ErrorReportPart)
223%name Tactic tac, tac'
241%name Tactic tac, tac'
224
242
225
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
226class Quotable a where
250class Quotable a where
251+ ||| A representation of the type `a`.
252+ |||
253+ ||| This is to enable quoting polymorphic datatypes
227 quotedTy : TT
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))```
228 quote : a -> TT
259 quote : a -> TT
229
260
230instance Quotable Nat where
261instance Quotable Nat where
@@ -382,3 +413,64 @@ mutual
382 quote (PVTy x) = `(PVTy {a=TT} ~(assert_total (quote x)))
413 quote (PVTy x) = `(PVTy {a=TT} ~(assert_total (quote x)))
383
414
384
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))
src/Idris/ElabTerm.hs+9−2
@@ -1806,8 +1806,9 @@ reflectName (MN i n)
1806reflectName (NErased) = Var (reflm "NErased")
1806reflectName (NErased) = Var (reflm "NErased")
1807reflectName n = Var (reflm "NErased") -- special name, not yet implemented
1807reflectName n = Var (reflm "NErased") -- special name, not yet implemented
1808
1808
1809−-- | Elaborate a name to a pattern. This means that NS and UN will be intact,
1809+-- | Elaborate a name to a pattern. This means that NS and UN will be intact.
1810+-- MNs corresponding to will care about the string but not the number. All
1810−-- while all others become _
1811+-- others become _.
1811reflectNameQuotePattern :: Name -> ElabD ()
1812reflectNameQuotePattern :: Name -> ElabD ()
1812reflectNameQuotePattern n@(UN s)
1813reflectNameQuotePattern n@(UN s)
1813 = do fill $ reflectName n
1814 = do fill $ reflectName n
@@ -1815,6 +1816,12 @@ reflectNameQuotePattern n@(UN s)
1815reflectNameQuotePattern n@(NS _ _)
1816reflectNameQuotePattern n@(NS _ _)
1816 = do fill $ reflectName n
1817 = do fill $ reflectName n
1817 solve
1818 solve
1819+reflectNameQuotePattern (MN _ n)
1820+ = do i <- getNameFrom (sMN 0 "mnCounter")
1821+ claim i (RConstant (AType (ATInt ITNative)))
1822+ movelast i
1823+ fill $ reflCall "MN" [Var i, RConstant (Str $ T.unpack n)]
1824+ solve
1818reflectNameQuotePattern _ -- for all other names, match any
1825reflectNameQuotePattern _ -- for all other names, match any
1819 = do nameHole <- getNameFrom (sMN 0 "name")
1826 = do nameHole <- getNameFrom (sMN 0 "name")
1820 claim nameHole (Var (reflm "TTName"))
1827 claim nameHole (Var (reflm "TTName"))
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 [])
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+