2Module : Idris.Reflection
3Description : Code related to Idris's reflection system. This module contains quoters and unquoters along with some supporting datatypes.
6Maintainer : The Idris Community.
9{-# LANGUAGE CPP, PatternGuards #-}
10{-# OPTIONS_GHC -fwarn-incomplete-patterns -fwarn-unused-imports #-}
11module Idris.Reflection (RConstructorDefn(..), RDataDefn(..),RFunArg(..),
12 RFunClause(..), RFunDefn(..), RTyDecl(..),
13 buildDatatypes, buildFunDefns, envTupleType, fromTTMaybe,
14 getArgs, mkList, rawList, rawPair, rawPairTy, reflect,
15 reflectArg, reflectDatatype, reflectEnv, reflectErr,
16 reflectFC, reflectFixity, reflectFunDefn, reflectList,
17 reflectName, reflectNameType, reflectRaw,
18 reflectRawQuotePattern, reflectRawQuote, reflectTTQuote,
19 reflectTTQuotePattern, reflm, reify, reifyBool, reifyEnv,
20 reifyFunDefn, reifyList, reifyRDataDefn, reifyRaw,
21 reifyReportPart, reifyReportParts, reifyTT, reifyTTName,
22 reifyTyDecl, rFunArgToPArg, tacN
25import Idris.Core.Elaborate (claim, fill, focus, getNameFrom, initElaborator,
26 movelast, runElab, solve)
27import Idris.Core.Evaluate (Def(TyDecl), initContext, lookupDefExact,
31import Idris.AbsSyntaxTree (ArgOpt(..), ElabD, Fixity(..), IState(idris_datatypes, idris_implicits, idris_patdefs, tt_ctxt),
32 PArg, PArg'(..), PTactic, PTactic'(..), PTerm(..),
33 initEState, pairCon, pairTy)
34import Idris.Delaborate (delab)
36import Control.Monad (liftM, liftM2, liftM4)
37import Control.Monad.State.Strict (lift)
38import Data.List (findIndex, (\\))
39import Data.Maybe (catMaybes)
40import qualified Data.Text as T
42data RErasure = RErased | RNotErased deriving Show
44data RPlicity = RExplicit | RImplicit | RConstraint deriving Show
46data RFunArg = RFunArg { argName :: Name
48 , argPlicity :: RPlicity
53data RTyDecl = RDeclare Name [RFunArg] Raw deriving Show
55data RTyConArg = RParameter RFunArg
59data RCtorArg = RCtorParameter RFunArg | RCtorField RFunArg deriving Show
61data RDatatype = RDatatype Name [RTyConArg] Raw [(Name, [RCtorArg], Raw)] deriving Show
63data RConstructorDefn = RConstructor Name [RFunArg] Raw
65data RDataDefn = RDefineDatatype Name [RConstructorDefn]
67rArgOpts :: RErasure -> [ArgOpt]
68rArgOpts RErased = [InaccessibleArg]
71rFunArgToPArg :: RFunArg -> PArg
72rFunArgToPArg (RFunArg n _ RExplicit e) = PExp 0 (rArgOpts e) n Placeholder
73rFunArgToPArg (RFunArg n _ RImplicit e) = PImp 0 False (rArgOpts e) n Placeholder
74rFunArgToPArg (RFunArg n _ RConstraint e) = PConstraint 0 (rArgOpts e) n Placeholder
76data RFunClause a = RMkFunClause a a
77 | RMkImpossibleClause a
80data RFunDefn a = RDefineFun Name [RFunClause a] deriving Show
82-- | Prefix a name with the "Language.Reflection" namespace
83reflm :: String -> Name
84reflm n = sNS (sUN n) ["Reflection", "Language"]
86-- | Prefix a name with the "Language.Reflection.Elab" namespace
88tacN str = sNS (sUN str) ["Elab", "Reflection", "Language"]
90-- | Reify tactics from their reflected representation
91reify :: IState -> Term -> ElabD PTactic
92reify _ (P _ n _) | n == reflm "Intros" = return Intros
93reify _ (P _ n _) | n == reflm "Trivial" = return Trivial
94reify _ (P _ n _) | n == reflm "Implementation" = return TCImplementation
95reify _ (P _ n _) | n == reflm "Solve" = return Solve
96reify _ (P _ n _) | n == reflm "Compute" = return Compute
97reify _ (P _ n _) | n == reflm "Skip" = return Skip
98reify _ (P _ n _) | n == reflm "SourceFC" = return SourceFC
99reify _ (P _ n _) | n == reflm "Unfocus" = return Unfocus
100reify ist t@(App _ _ _)
101 | (P _ f _, args) <- unApply t = reifyApp ist f args
102reify _ t = fail ("Unknown tactic " ++ show t)
104reifyApp :: IState -> Name -> [Term] -> ElabD PTactic
105reifyApp ist t [l, r] | t == reflm "Try" = liftM2 Try (reify ist l) (reify ist r)
106reifyApp _ t [Constant (I i)]
107 | t == reflm "Search" = return (ProofSearch True True i Nothing [] [])
109 | t == reflm "Refine" = do n <- reifyTTName x
111reifyApp ist t [n, ty] | t == reflm "Claim" = do n' <- reifyTTName n
113 return $ Claim n' (delab ist goal)
114reifyApp ist t [l, r] | t == reflm "Seq" = liftM2 TSeq (reify ist l) (reify ist r)
115reifyApp ist t [Constant (Str n), x]
116 | t == reflm "GoalType" = liftM (GoalType n) (reify ist x)
117reifyApp _ t [n] | t == reflm "Intro" = liftM (Intro . (:[])) (reifyTTName n)
118reifyApp ist t [t'] | t == reflm "Induction" = liftM (Induction . delab ist) (reifyTT t')
119reifyApp ist t [t'] | t == reflm "Case" = liftM (CaseTac . delab ist) (reifyTT t')
121 | t == reflm "ApplyTactic" = liftM (ApplyTactic . delab ist) (reifyTT t')
123 | t == reflm "Reflect" = liftM (Reflect . delab ist) (reifyTT t')
125 | t == reflm "ByReflection" = liftM (ByReflection . delab ist) (reifyTT t')
127 | t == reflm "Fill" = liftM (Fill . PQuote) (reifyRaw t')
129 | t == reflm "Exact" = liftM (Exact . delab ist) (reifyTT t')
131 | t == reflm "Focus" = liftM Focus (reifyTTName x)
133 | t == reflm "Rewrite" = liftM (Rewrite . delab ist) (reifyTT t')
134reifyApp ist t [n, t']
135 | t == reflm "LetTac" = do n' <- reifyTTName n
137 return $ LetTac n' (delab ist t')
138reifyApp ist t [n, tt', t']
139 | t == reflm "LetTacTy" = do n' <- reifyTTName n
142 return $ LetTacTy n' (delab ist tt'') (delab ist t'')
144 | t == reflm "Fail" = fmap TFail (reifyReportParts errs)
145reifyApp _ f args = fail ("Unknown tactic " ++ show (f, args)) -- shouldn't happen
147reifyBool :: Term -> ElabD Bool
148reifyBool (P _ n _) | n == sNS (sUN "True") ["Bool", "Prelude"] = return True
149 | n == sNS (sUN "False") ["Bool", "Prelude"] = return False
150reifyBool tm = fail $ "Not a Boolean: " ++ show tm
152reifyInt :: Term -> ElabD Int
153reifyInt (Constant (I i)) = return i
154reifyInt tm = fail $ "Not an Int: " ++ show tm
156reifyPair :: (Term -> ElabD a) -> (Term -> ElabD b) -> Term -> ElabD (a, b)
157reifyPair left right (App _ (App _ (App _ (App _ (P _ n _) _) _) x) y)
158 | n == pairCon = liftM2 (,) (left x) (right y)
159reifyPair left right tm = fail $ "Not a pair: " ++ show tm
161reifyList :: (Term -> ElabD a) -> Term -> ElabD [a]
162reifyList getElt lst =
164 Nothing -> fail "Couldn't reify a list"
165 Just xs -> mapM getElt xs
167reifyReportParts :: Term -> ElabD [ErrorReportPart]
168reifyReportParts errs =
170 Nothing -> fail "Failed to reify errors"
172 let parts = mapM reifyReportPart errs' in
174 Left err -> fail $ "Couldn't reify \"Fail\" tactic - " ++ show err
178-- | Reify terms from their reflected representation
179reifyTT :: Term -> ElabD Term
181 | (P _ f _, args) <- unApply t = reifyTTApp f args
183 | n == reflm "Erased" = return Erased
185 | n == reflm "Impossible" = return Impossible
186reifyTT t = fail ("Unknown reflection term: " ++ show t)
188reifyTTApp :: Name -> [Term] -> ElabD Term
189reifyTTApp t [nt, n, x]
190 | t == reflm "P" = do nt' <- reifyTTNameType nt
194reifyTTApp t [Constant (I i)]
195 | t == reflm "V" = return $ V i
196reifyTTApp t [n, b, x]
197 | t == reflm "Bind" = do n' <- reifyTTName n
198 b' <- reifyTTBinder reifyTT (reflm "TT") b
200 return $ Bind n' b' x'
202 | t == reflm "App" = do f' <- reifyTT f
204 return $ App Complete f' x'
206 | t == reflm "TConst" = liftM Constant (reifyTTConst c)
207reifyTTApp t [t', Constant (I i)]
208 | t == reflm "Proj" = do t'' <- reifyTT t'
211 | t == reflm "TType" = liftM TType (reifyTTUExp tt)
213 | t == reflm "UType" = liftM UType (reifyUniverse tt)
214reifyTTApp t args = fail ("Unknown reflection term: " ++ show (t, args))
216reifyUniverse :: Term -> ElabD Universe
217reifyUniverse (P _ n _) | n == reflm "AllTypes" = return AllTypes
218 | n == reflm "UniqueType" = return UniqueType
219 | n == reflm "NullType" = return NullType
220reifyUniverse tm = fail ("Unknown reflection universe: " ++ show tm)
222-- | Reify raw terms from their reflected representation
223reifyRaw :: Term -> ElabD Raw
224reifyRaw t@(App _ _ _)
225 | (P _ f _, args) <- unApply t = reifyRawApp f args
227 | n == reflm "RType" = return RType
228reifyRaw t = fail ("Unknown reflection raw term in reifyRaw: " ++ show t)
230reifyRawApp :: Name -> [Term] -> ElabD Raw
232 | t == reflm "Var" = liftM Var (reifyTTName n)
233reifyRawApp t [n, b, x]
234 | t == reflm "RBind" = do n' <- reifyTTName n
235 b' <- reifyTTBinder reifyRaw (reflm "Raw") b
237 return $ RBind n' b' x'
239 | t == reflm "RApp" = liftM2 RApp (reifyRaw f) (reifyRaw x)
241 | t == reflm "RConstant" = liftM RConstant (reifyTTConst c)
242reifyRawApp t args = fail ("Unknown reflection raw term in reifyRawApp: " ++ show (t, args))
244reifyTTName :: Term -> ElabD Name
246 | (P _ f _, args) <- unApply t = reifyTTNameApp f args
247reifyTTName t = fail ("Unknown reflection term name: " ++ show t)
249reifyTTNameApp :: Name -> [Term] -> ElabD Name
250reifyTTNameApp t [Constant (Str n)]
251 | t == reflm "UN" = return $ sUN n
252reifyTTNameApp t [n, ns]
253 | t == reflm "NS" = do n' <- reifyTTName n
254 ns' <- reifyTTNamespace ns
256reifyTTNameApp t [Constant (I i), Constant (Str n)]
257 | t == reflm "MN" = return $ sMN i n
260 , (P _ f _, args) <- unApply sn = SN <$> reifySN f args
261 where reifySN :: Name -> [Term] -> ElabD SpecialName
262 reifySN t [Constant (I i), n1, n2]
263 | t == reflm "WhereN" = WhereN i <$> reifyTTName n1 <*> reifyTTName n2
264 reifySN t [Constant (I i), n]
265 | t == reflm "WithN" = WithN i <$> reifyTTName n
267 | t == reflm "ImplementationN" =
269 Nothing -> fail "Can't reify ImplementationN strings"
270 Just ss' -> ImplementationN <$> reifyTTName n <*>
271 pure [T.pack s | Constant (Str s) <- ss']
272 reifySN t [n, Constant (Str s)]
273 | t == reflm "ParentN" =
274 ParentN <$> reifyTTName n <*> pure (T.pack s)
276 | t == reflm "MethodN" =
277 MethodN <$> reifyTTName n
279 | t == reflm "CaseN" =
280 CaseN <$> (FC' <$> reifyFC fc) <*> reifyTTName n
282 | t == reflm "ElimN" =
283 ElimN <$> reifyTTName n
285 | t == reflm "ImplementationCtorN" =
286 ImplementationCtorN <$> reifyTTName n
288 | t == reflm "MetaN" =
289 MetaN <$> reifyTTName n1 <*> reifyTTName n2
290 reifySN t args = fail $ "Can't reify special name " ++ show t ++ show args
291reifyTTNameApp t args = fail ("Unknown reflection term name: " ++ show (t, args))
293reifyTTNamespace :: Term -> ElabD [String]
294reifyTTNamespace t@(App _ _ _)
296 (P _ f _, [Constant StrType])
297 | f == sNS (sUN "Nil") ["List", "Prelude"] -> return []
298 (P _ f _, [Constant StrType, Constant (Str n), ns])
299 | f == sNS (sUN "::") ["List", "Prelude"] -> liftM (n:) (reifyTTNamespace ns)
300 _ -> fail ("Unknown reflection namespace arg: " ++ show t)
301reifyTTNamespace t = fail ("Unknown reflection namespace arg: " ++ show t)
303reifyTTNameType :: Term -> ElabD NameType
304reifyTTNameType t@(P _ n _) | n == reflm "Bound" = return $ Bound
305reifyTTNameType t@(P _ n _) | n == reflm "Ref" = return $ Ref
306reifyTTNameType t@(App _ _ _)
308 (P _ f _, [Constant (I tag), Constant (I num)])
309 | f == reflm "DCon" -> return $ DCon tag num False -- FIXME: Uniqueness!
310 | f == reflm "TCon" -> return $ TCon tag num
311 _ -> fail ("Unknown reflection name type: " ++ show t)
312reifyTTNameType t = fail ("Unknown reflection name type: " ++ show t)
314reifyTTBinder :: (Term -> ElabD a) -> Name -> Term -> ElabD (Binder a)
315reifyTTBinder reificator binderType t@(App _ _ _)
317 (P _ f _, bt:args) | forget bt == Var binderType
318 -> reifyTTBinderApp reificator f args
319 _ -> fail ("Mismatching binder reflection: " ++ show t)
320reifyTTBinder _ _ t = fail ("Unknown reflection binder: " ++ show t)
322reifyTTBinderApp :: (Term -> ElabD a) -> Name -> [Term] -> ElabD (Binder a)
323reifyTTBinderApp reif f [t]
324 | f == reflm "Lam" = liftM (Lam RigW) (reif t)
325reifyTTBinderApp reif f [t, k]
326 | f == reflm "Pi" = liftM2 (Pi RigW Nothing) (reif t) (reif k)
327reifyTTBinderApp reif f [x, y]
328 | f == reflm "Let" = liftM2 (Let RigW) (reif x) (reif y)
329reifyTTBinderApp reif f [t]
330 | f == reflm "Hole" = liftM Hole (reif t)
331reifyTTBinderApp reif f [t]
332 | f == reflm "GHole" = liftM (GHole 0 []) (reif t)
333reifyTTBinderApp reif f [x, y]
334 | f == reflm "Guess" = liftM2 Guess (reif x) (reif y)
335reifyTTBinderApp reif f [t]
336 | f == reflm "PVar" = liftM (PVar RigW) (reif t)
337reifyTTBinderApp reif f [t]
338 | f == reflm "PVTy" = liftM PVTy (reif t)
339reifyTTBinderApp _ f args = fail ("Unknown reflection binder: " ++ show (f, args))
341reifyTTConst :: Term -> ElabD Const
342reifyTTConst (P _ n _) | n == reflm "StrType" = return StrType
343reifyTTConst (P _ n _) | n == reflm "VoidType" = return VoidType
344reifyTTConst (P _ n _) | n == reflm "Forgot" = return Forgot
345reifyTTConst t@(App _ _ _)
346 | (P _ f _, [arg]) <- unApply t = reifyTTConstApp f arg
347reifyTTConst t = fail ("Unknown reflection constant: " ++ show t)
349reifyTTConstApp :: Name -> Term -> ElabD Const
351 | f == reflm "AType" = fmap AType (reifyArithTy aty)
352reifyTTConstApp f (Constant c@(I _))
353 | f == reflm "I" = return c
354reifyTTConstApp f (Constant c@(BI _))
355 | f == reflm "BI" = return c
356reifyTTConstApp f (Constant c@(Fl _))
357 | f == reflm "Fl" = return c
358reifyTTConstApp f (Constant c@(Ch _))
359 | f == reflm "Ch" = return c
360reifyTTConstApp f (Constant c@(Str _))
361 | f == reflm "Str" = return c
362reifyTTConstApp f (Constant c@(B8 _))
363 | f == reflm "B8" = return c
364reifyTTConstApp f (Constant c@(B16 _))
365 | f == reflm "B16" = return c
366reifyTTConstApp f (Constant c@(B32 _))
367 | f == reflm "B32" = return c
368reifyTTConstApp f (Constant c@(B64 _))
369 | f == reflm "B64" = return c
370reifyTTConstApp f v@(P _ _ _) =
372 "Can't reify the variable " ++
374 " as a constant, because its value is not statically known."
375reifyTTConstApp f arg = fail ("Unknown reflection constant: " ++ show (f, arg))
377reifyArithTy :: Term -> ElabD ArithTy
378reifyArithTy (App _ (P _ n _) intTy) | n == reflm "ATInt" = fmap ATInt (reifyIntTy intTy)
379reifyArithTy (P _ n _) | n == reflm "ATDouble" = return ATFloat
380reifyArithTy x = fail ("Couldn't reify reflected ArithTy: " ++ show x)
382reifyNativeTy :: Term -> ElabD NativeTy
383reifyNativeTy (P _ n _) | n == reflm "IT8" = return IT8
384reifyNativeTy (P _ n _) | n == reflm "IT16" = return IT16
385reifyNativeTy (P _ n _) | n == reflm "IT32" = return IT32
386reifyNativeTy (P _ n _) | n == reflm "IT64" = return IT64
387reifyNativeTy x = fail $ "Couldn't reify reflected NativeTy " ++ show x
389reifyIntTy :: Term -> ElabD IntTy
390reifyIntTy (App _ (P _ n _) nt) | n == reflm "ITFixed" = fmap ITFixed (reifyNativeTy nt)
391reifyIntTy (P _ n _) | n == reflm "ITNative" = return ITNative
392reifyIntTy (P _ n _) | n == reflm "ITBig" = return ITBig
393reifyIntTy (P _ n _) | n == reflm "ITChar" = return ITChar
394reifyIntTy tm = fail $ "The term " ++ show tm ++ " is not a reflected IntTy"
396reifyTTUExp :: Term -> ElabD UExp
397reifyTTUExp t@(App _ _ _)
399 (P _ f _, [Constant (Str str), Constant (I i)])
400 | f == reflm "UVar" -> return $ UVar str i
401 (P _ f _, [Constant (I i)])
402 | f == reflm "UVal" -> return $ UVal i
403 _ -> fail ("Unknown reflection type universe expression: " ++ show t)
404reifyTTUExp t = fail ("Unknown reflection type universe expression: " ++ show t)
406-- | Create a reflected call to a named function/constructor
407reflCall :: String -> [Raw] -> Raw
409 = raw_apply (Var (reflm funName)) args
411-- | Lift a term into its Language.Reflection.TT representation
412reflect :: Term -> Raw
413reflect = reflectTTQuote []
415-- | Lift a term into its Language.Reflection.Raw representation
416reflectRaw :: Raw -> Raw
417reflectRaw = reflectRawQuote []
419claimTy :: Name -> Raw -> ElabD Name
420claimTy n ty = do n' <- getNameFrom n
424intToReflectedNat :: Int -> Raw
425intToReflectedNat i = if i <= 0
427 else RApp (Var (natN "S")) (intToReflectedNat (i - 1))
428 where natN :: String -> Name
429 natN n = sNS (sUN n) ["Nat", "Prelude"]
431reflectFixity :: Fixity -> Raw
432reflectFixity (Infixl p) = RApp (Var (tacN "Infixl")) (intToReflectedNat p)
433reflectFixity (Infixr p) = RApp (Var (tacN "Infixr")) (intToReflectedNat p)
434reflectFixity (InfixN p) = RApp (Var (tacN "InfixN")) (intToReflectedNat p)
435reflectFixity (PrefixN p) = RApp (Var (tacN "PrefixN")) (intToReflectedNat p)
437-- | Convert a reflected term to a more suitable form for pattern-matching.
438-- In particular, the less-interesting bits are elaborated to _ patterns. This
439-- happens to NameTypes, universe levels, names that are bound but not used,
440-- and the type annotation field of the P constructor.
441reflectTTQuotePattern :: [Name] -> Term -> ElabD ()
442reflectTTQuotePattern unq (P _ n _)
443 | n `elem` unq = -- the unquoted names have been claimed as TT already - just use them
444 do fill (Var n) ; solve
446 do tyannot <- claimTy (sMN 0 "pTyAnnot") (Var (reflm "TT"))
447 movelast tyannot -- use a _ pattern here
448 nt <- getNameFrom (sMN 0 "nt")
449 claim nt (Var (reflm "NameType"))
450 movelast nt -- use a _ pattern here
451 n' <- getNameFrom (sMN 0 "n")
452 claim n' (Var (reflm "TTName"))
453 fill $ reflCall "P" [Var nt, Var n', Var tyannot]
455 focus n'; reflectNameQuotePattern n
456reflectTTQuotePattern unq (V n)
457 = do fill $ reflCall "V" [RConstant (I n)]
459reflectTTQuotePattern unq (Bind n b x)
460 = do x' <- claimTy (sMN 0 "sc") (Var (reflm "TT"))
462 b' <- getNameFrom (sMN 0 "binder")
463 claim b' (RApp (Var (sNS (sUN "Binder") ["Reflection", "Language"]))
464 (Var (sNS (sUN "TT") ["Reflection", "Language"])))
465 if n `elem` freeNames x
466 then do fill $ reflCall "Bind"
471 else do any <- getNameFrom (sMN 0 "anyName")
472 claim any (Var (reflm "TTName"))
474 fill $ reflCall "Bind"
479 focus x'; reflectTTQuotePattern unq x
480 focus b'; reflectBinderQuotePattern reflectTTQuotePattern (Var $ reflm "TT") unq b
481reflectTTQuotePattern unq (App _ f x)
482 = do f' <- claimTy (sMN 0 "f") (Var (reflm "TT")) ; movelast f'
483 x' <- claimTy (sMN 0 "x") (Var (reflm "TT")) ; movelast x'
484 fill $ reflCall "App" [Var f', Var x']
486 focus f'; reflectTTQuotePattern unq f
487 focus x'; reflectTTQuotePattern unq x
488reflectTTQuotePattern unq (Constant c)
489 = do fill $ reflCall "TConst" [reflectConstant c]
491reflectTTQuotePattern unq (Proj t i)
492 = lift . tfail . InternalMsg $
493 "Phase error! The Proj constructor is for optimization only and should not have been reflected during elaboration."
494reflectTTQuotePattern unq Erased
495 = do erased <- claimTy (sMN 0 "erased") (Var (reflm "TT"))
498reflectTTQuotePattern unq Impossible
499 = lift . tfail . InternalMsg $
500 "Phase error! The Impossible constructor is for optimization only and should not have been reflected during elaboration."
501reflectTTQuotePattern unq (Inferred t)
502 = lift . tfail . InternalMsg $
503 "Phase error! The Inferred constructor is for coverage checking only and should not have been reflected during elaboration."
504reflectTTQuotePattern unq (TType exp)
505 = do ue <- getNameFrom (sMN 0 "uexp")
506 claim ue (Var (sNS (sUN "TTUExp") ["Reflection", "Language"]))
508 fill $ reflCall "TType" [Var ue]
510reflectTTQuotePattern unq (UType u)
511 = do uH <- getNameFrom (sMN 0 "someUniv")
512 claim uH (Var (reflm "Universe"))
514 fill $ reflCall "UType" [Var uH]
517 fill (Var (reflm (case u of
518 NullType -> "NullType"
519 UniqueType -> "UniqueType"
520 AllTypes -> "AllTypes")))
523reflectRawQuotePattern :: [Name] -> Raw -> ElabD ()
524reflectRawQuotePattern unq (Var n)
525 -- the unquoted names already have types, just use them
526 | n `elem` unq = do fill (Var n); solve
527 | otherwise = do fill (reflCall "Var" [reflectName n]); solve
528reflectRawQuotePattern unq (RBind n b sc) =
529 do scH <- getNameFrom (sMN 0 "sc")
530 claim scH (Var (reflm "Raw"))
532 bH <- getNameFrom (sMN 0 "binder")
533 claim bH (RApp (Var (reflm "Binder"))
535 if n `elem` freeNamesR sc
536 then do fill $ reflCall "RBind" [reflectName n,
540 else do any <- getNameFrom (sMN 0 "anyName")
541 claim any (Var (reflm "TTName"))
543 fill $ reflCall "RBind" [Var any, Var bH, Var scH]
545 focus scH; reflectRawQuotePattern unq sc
546 focus bH; reflectBinderQuotePattern reflectRawQuotePattern (Var $ reflm "Raw") unq b
547 where freeNamesR (Var n) = [n]
548 freeNamesR (RBind n (Let rc t v) body) = concat [freeNamesR v,
549 freeNamesR body \\ [n],
551 freeNamesR (RBind n b body) = freeNamesR (binderTy b) ++
552 (freeNamesR body \\ [n])
553 freeNamesR (RApp f x) = freeNamesR f ++ freeNamesR x
554 freeNamesR RType = []
555 freeNamesR (RUType _) = []
556 freeNamesR (RConstant _) = []
557reflectRawQuotePattern unq (RApp f x) =
558 do fH <- getNameFrom (sMN 0 "f")
559 claim fH (Var (reflm "Raw"))
561 xH <- getNameFrom (sMN 0 "x")
562 claim xH (Var (reflm "Raw"))
564 fill $ reflCall "RApp" [Var fH, Var xH]
566 focus fH; reflectRawQuotePattern unq f
567 focus xH; reflectRawQuotePattern unq x
568reflectRawQuotePattern unq RType =
569 do fill (Var (reflm "RType"))
571reflectRawQuotePattern unq (RUType univ) =
572 do uH <- getNameFrom (sMN 0 "universe")
573 claim uH (Var (reflm "Universe"))
575 fill $ reflCall "RUType" [Var uH]
577 focus uH; fill (reflectUniverse univ); solve
578reflectRawQuotePattern unq (RConstant c) =
579 do cH <- getNameFrom (sMN 0 "const")
580 claim cH (Var (reflm "Constant"))
582 fill (reflCall "RConstant" [Var cH]); solve
584 fill (reflectConstant c); solve
586reflectBinderQuotePattern :: ([Name] -> a -> ElabD ()) -> Raw -> [Name] -> Binder a -> ElabD ()
587reflectBinderQuotePattern q ty unq (Lam _ t)
588 = do t' <- claimTy (sMN 0 "ty") ty; movelast t'
589 fill $ reflCall "Lam" [ty, Var t']
592reflectBinderQuotePattern q ty unq (Pi _ _ t k)
593 = do t' <- claimTy (sMN 0 "ty") ty; movelast t'
594 k' <- claimTy (sMN 0 "k") ty; movelast k';
595 fill $ reflCall "Pi" [ty, Var t', Var k']
598reflectBinderQuotePattern q ty unq (Let rc x y)
599 = do x' <- claimTy (sMN 0 "ty") ty; movelast x';
600 y' <- claimTy (sMN 0 "v")ty; movelast y';
601 fill $ reflCall "Let" [ty, Var x', Var y']
605reflectBinderQuotePattern q ty unq (NLet x y)
606 = do x' <- claimTy (sMN 0 "ty") ty; movelast x'
607 y' <- claimTy (sMN 0 "v") ty; movelast y'
608 fill $ reflCall "Let" [ty, Var x', Var y']
612reflectBinderQuotePattern q ty unq (Hole t)
613 = do t' <- claimTy (sMN 0 "ty") ty; movelast t'
614 fill $ reflCall "Hole" [ty, Var t']
617reflectBinderQuotePattern q ty unq (GHole _ _ t)
618 = do t' <- claimTy (sMN 0 "ty") ty; movelast t'
619 fill $ reflCall "GHole" [ty, Var t']
622reflectBinderQuotePattern q ty unq (Guess x y)
623 = do x' <- claimTy (sMN 0 "ty") ty; movelast x'
624 y' <- claimTy (sMN 0 "v") ty; movelast y'
625 fill $ reflCall "Guess" [ty, Var x', Var y']
629reflectBinderQuotePattern q ty unq (PVar _ t)
630 = do t' <- claimTy (sMN 0 "ty") ty; movelast t'
631 fill $ reflCall "PVar" [ty, Var t']
634reflectBinderQuotePattern q ty unq (PVTy t)
635 = do t' <- claimTy (sMN 0 "ty") ty; movelast t'
636 fill $ reflCall "PVTy" [ty, Var t']
640reflectUniverse :: Universe -> Raw
642 (Var (reflm (case u of
643 NullType -> "NullType"
644 UniqueType -> "UniqueType"
645 AllTypes -> "AllTypes")))
647-- | Create a reflected TT term, but leave refs to the provided name intact
648reflectTTQuote :: [Name] -> Term -> Raw
649reflectTTQuote unq (P nt n t)
650 | n `elem` unq = Var n
651 | otherwise = reflCall "P" [reflectNameType nt, reflectName n, reflectTTQuote unq t]
652reflectTTQuote unq (V n)
653 = reflCall "V" [RConstant (I n)]
654reflectTTQuote unq (Bind n b x)
655 = reflCall "Bind" [reflectName n, reflectBinderQuote reflectTTQuote (reflm "TT") unq b, reflectTTQuote unq x]
656reflectTTQuote unq (App _ f x)
657 = reflCall "App" [reflectTTQuote unq f, reflectTTQuote unq x]
658reflectTTQuote unq (Constant c)
659 = reflCall "TConst" [reflectConstant c]
660reflectTTQuote unq (TType exp) = reflCall "TType" [reflectUExp exp]
661reflectTTQuote unq (UType u) = reflCall "UType" [reflectUniverse u]
662reflectTTQuote _ (Proj _ _) =
663 error "Phase error! The Proj constructor is for optimization only and should not have been reflected during elaboration."
664reflectTTQuote unq Erased = Var (reflm "Erased")
665reflectTTQuote _ Impossible =
666 error "Phase error! The Impossible constructor is for optimization only and should not have been reflected during elaboration."
667reflectTTQuote _ (Inferred tm) =
668 error "Phase error! The Inferred constructor is for coverage checking only and should not have been reflected during elaboration."
670reflectRawQuote :: [Name] -> Raw -> Raw
671reflectRawQuote unq (Var n)
672 | n `elem` unq = Var n
673 | otherwise = reflCall "Var" [reflectName n]
674reflectRawQuote unq (RBind n b r) =
675 reflCall "RBind" [reflectName n, reflectBinderQuote reflectRawQuote (reflm "Raw") unq b, reflectRawQuote unq r]
676reflectRawQuote unq (RApp f x) =
677 reflCall "RApp" [reflectRawQuote unq f, reflectRawQuote unq x]
678reflectRawQuote unq RType = Var (reflm "RType")
679reflectRawQuote unq (RUType u) =
680 reflCall "RUType" [reflectUniverse u]
681reflectRawQuote unq (RConstant cst) = reflCall "RConstant" [reflectConstant cst]
683reflectNameType :: NameType -> Raw
684reflectNameType (Bound) = Var (reflm "Bound")
685reflectNameType (Ref) = Var (reflm "Ref")
686reflectNameType (DCon x y _)
687 = reflCall "DCon" [RConstant (I x), RConstant (I y)] -- FIXME: Uniqueness!
688reflectNameType (TCon x y)
689 = reflCall "TCon" [RConstant (I x), RConstant (I y)]
691reflectName :: Name -> Raw
693 = reflCall "UN" [RConstant (Str (str s))]
695 = reflCall "NS" [ reflectName n
697 raw_apply ( Var $ sNS (sUN "::") ["List", "Prelude"] )
698 [ RConstant StrType, RConstant (Str n), s ])
699 ( raw_apply ( Var $ sNS (sUN "Nil") ["List", "Prelude"] )
700 [ RConstant StrType ])
704 = reflCall "MN" [RConstant (I i), RConstant (Str (str n))]
705reflectName (SN sn) = raw_apply (Var (reflm "SN")) [reflectSpecialName sn]
706reflectName (SymRef _) = error "The impossible happened: symbol table ref survived IBC loading"
708reflectSpecialName :: SpecialName -> Raw
709reflectSpecialName (WhereN i n1 n2) =
710 reflCall "WhereN" [RConstant (I i), reflectName n1, reflectName n2]
711reflectSpecialName (WithN i n) = reflCall "WithN" [ RConstant (I i)
714reflectSpecialName (ImplementationN impl ss) =
715 reflCall "ImplementationN" [ reflectName impl
716 , mkList (RConstant StrType) $
717 map (RConstant . Str . T.unpack) ss
719reflectSpecialName (ParentN n s) =
720 reflCall "ParentN" [reflectName n, RConstant (Str (T.unpack s))]
721reflectSpecialName (MethodN n) =
722 reflCall "MethodN" [reflectName n]
723reflectSpecialName (CaseN fc n) =
724 reflCall "CaseN" [reflectFC (unwrapFC fc), reflectName n]
725reflectSpecialName (ElimN n) =
726 reflCall "ElimN" [reflectName n]
727reflectSpecialName (ImplementationCtorN n) =
728 reflCall "ImplementationCtorN" [reflectName n]
729reflectSpecialName (MetaN parent meta) =
730 reflCall "MetaN" [reflectName parent, reflectName meta]
732-- | Elaborate a name to a pattern. This means that NS and UN will be intact.
733-- MNs corresponding to will care about the string but not the number. All
735reflectNameQuotePattern :: Name -> ElabD ()
736reflectNameQuotePattern n@(UN s)
737 = do fill $ reflectName n
739reflectNameQuotePattern n@(NS _ _)
740 = do fill $ reflectName n
742reflectNameQuotePattern (MN _ n)
743 = do i <- getNameFrom (sMN 0 "mnCounter")
744 claim i (RConstant (AType (ATInt ITNative)))
746 fill $ reflCall "MN" [Var i, RConstant (Str $ T.unpack n)]
748reflectNameQuotePattern _ -- for all other names, match any
749 = do nameHole <- getNameFrom (sMN 0 "name")
750 claim nameHole (Var (reflm "TTName"))
755reflectBinder :: Binder Term -> Raw
756reflectBinder = reflectBinderQuote reflectTTQuote (reflm "TT") []
758reflectBinderQuote :: ([Name] -> a -> Raw) -> Name -> [Name] -> Binder a -> Raw
759reflectBinderQuote q ty unq (Lam _ t)
760 = reflCall "Lam" [Var ty, q unq t]
761reflectBinderQuote q ty unq (Pi _ _ t k)
762 = reflCall "Pi" [Var ty, q unq t, q unq k]
763reflectBinderQuote q ty unq (Let rc x y)
764 = reflCall "Let" [Var ty, q unq x, q unq y]
765reflectBinderQuote q ty unq (NLet x y)
766 = reflCall "Let" [Var ty, q unq x, q unq y]
767reflectBinderQuote q ty unq (Hole t)
768 = reflCall "Hole" [Var ty, q unq t]
769reflectBinderQuote q ty unq (GHole _ _ t)
770 = reflCall "GHole" [Var ty, q unq t]
771reflectBinderQuote q ty unq (Guess x y)
772 = reflCall "Guess" [Var ty, q unq x, q unq y]
773reflectBinderQuote q ty unq (PVar _ t)
774 = reflCall "PVar" [Var ty, q unq t]
775reflectBinderQuote q ty unq (PVTy t)
776 = reflCall "PVTy" [Var ty, q unq t]
778mkList :: Raw -> [Raw] -> Raw
779mkList ty [] = RApp (Var (sNS (sUN "Nil") ["List", "Prelude"])) ty
780mkList ty (x:xs) = RApp (RApp (RApp (Var (sNS (sUN "::") ["List", "Prelude"])) ty)
784reflectConstant :: Const -> Raw
785reflectConstant c@(I _) = reflCall "I" [RConstant c]
786reflectConstant c@(BI _) = reflCall "BI" [RConstant c]
787reflectConstant c@(Fl _) = reflCall "Fl" [RConstant c]
788reflectConstant c@(Ch _) = reflCall "Ch" [RConstant c]
789reflectConstant c@(Str _) = reflCall "Str" [RConstant c]
790reflectConstant c@(B8 _) = reflCall "B8" [RConstant c]
791reflectConstant c@(B16 _) = reflCall "B16" [RConstant c]
792reflectConstant c@(B32 _) = reflCall "B32" [RConstant c]
793reflectConstant c@(B64 _) = reflCall "B64" [RConstant c]
794reflectConstant (AType (ATInt ITNative)) = reflCall "AType" [reflCall "ATInt" [Var (reflm "ITNative")]]
795reflectConstant (AType (ATInt ITBig)) = reflCall "AType" [reflCall "ATInt" [Var (reflm "ITBig")]]
796reflectConstant (AType ATFloat) = reflCall "AType" [Var (reflm "ATDouble")]
797reflectConstant (AType (ATInt ITChar)) = reflCall "AType" [reflCall "ATInt" [Var (reflm "ITChar")]]
798reflectConstant StrType = Var (reflm "StrType")
799reflectConstant (AType (ATInt (ITFixed IT8))) = reflCall "AType" [reflCall "ATInt" [reflCall "ITFixed" [Var (reflm "IT8")]]]
800reflectConstant (AType (ATInt (ITFixed IT16))) = reflCall "AType" [reflCall "ATInt" [reflCall "ITFixed" [Var (reflm "IT16")]]]
801reflectConstant (AType (ATInt (ITFixed IT32))) = reflCall "AType" [reflCall "ATInt" [reflCall "ITFixed" [Var (reflm "IT32")]]]
802reflectConstant (AType (ATInt (ITFixed IT64))) = reflCall "AType" [reflCall "ATInt" [reflCall "ITFixed" [Var (reflm "IT64")]]]
803reflectConstant VoidType = Var (reflm "VoidType")
804reflectConstant Forgot = Var (reflm "Forgot")
805reflectConstant WorldType = Var (reflm "WorldType")
806reflectConstant TheWorld = Var (reflm "TheWorld")
808reflectUExp :: UExp -> Raw
809reflectUExp (UVar ns i) = reflCall "UVar" [RConstant (Str ns), RConstant (I i)]
810reflectUExp (UVal i) = reflCall "UVal" [RConstant (I i)]
812-- | Reflect the environment of a proof into a List (TTName, Binder TT)
813reflectEnv :: Env -> Raw
814reflectEnv = foldr consToEnvList emptyEnvList . envBinders
816 consToEnvList :: (Name, Binder Term) -> Raw -> Raw
817 consToEnvList (n, b) l
818 = raw_apply (Var (sNS (sUN "::") ["List", "Prelude"]))
820 , raw_apply (Var pairCon) [ (Var $ reflm "TTName")
821 , (RApp (Var $ reflm "Binder")
830 emptyEnvList = raw_apply (Var (sNS (sUN "Nil") ["List", "Prelude"]))
833-- Reflected environments don't get the RigCount (for the moment, at least)
834reifyEnv :: Term -> ElabD Env
835reifyEnv tm = do preEnv <- reifyList (reifyPair reifyTTName (reifyTTBinder reifyTT (reflm "TT"))) tm
836 return $ map (\(n, b) -> (n, RigW, b)) preEnv
838-- | Reflect an error into the internal datatype of Idris -- TODO
839rawBool :: Bool -> Raw
840rawBool True = Var (sNS (sUN "True") ["Bool", "Prelude"])
841rawBool False = Var (sNS (sUN "False") ["Bool", "Prelude"])
844rawNil ty = raw_apply (Var (sNS (sUN "Nil") ["List", "Prelude"])) [ty]
846rawCons :: Raw -> Raw -> Raw -> Raw
847rawCons ty hd tl = raw_apply (Var (sNS (sUN "::") ["List", "Prelude"])) [ty, hd, tl]
849rawList :: Raw -> [Raw] -> Raw
850rawList ty = foldr (rawCons ty) (rawNil ty)
852rawPairTy :: Raw -> Raw -> Raw
853rawPairTy t1 t2 = raw_apply (Var pairTy) [t1, t2]
855rawPair :: (Raw, Raw) -> (Raw, Raw) -> Raw
856rawPair (a, b) (x, y) = raw_apply (Var pairCon) [a, b, x, y]
858-- | Idris tuples nest to the right
859rawTripleTy :: Raw -> Raw -> Raw -> Raw
860rawTripleTy a b c = rawPairTy a (rawPairTy b c)
862rawTriple :: (Raw, Raw, Raw) -> (Raw, Raw, Raw) -> Raw
863rawTriple (a, b, c) (x, y, z) = rawPair (a, rawPairTy b c) (x, rawPair (b, c) (y, z))
865reflectCtxt :: [(Name, Type)] -> Raw
866reflectCtxt ctxt = rawList (rawPairTy (Var $ reflm "TTName") (Var $ reflm "TT"))
867 (map (\ (n, t) -> (rawPair (Var $ reflm "TTName", Var $ reflm "TT")
868 (reflectName n, reflect t)))
871reflectErr :: Err -> Raw
872reflectErr (Msg msg) = raw_apply (Var $ reflErrName "Msg") [RConstant (Str msg)]
873reflectErr (InternalMsg msg) = raw_apply (Var $ reflErrName "InternalMsg") [RConstant (Str msg)]
874reflectErr (CantUnify b (t1,_) (t2,_) e ctxt i) =
875 raw_apply (Var $ reflErrName "CantUnify")
882reflectErr (InfiniteUnify n tm ctxt) =
883 raw_apply (Var $ reflErrName "InfiniteUnify")
888reflectErr (CantConvert t t' ctxt) =
889 raw_apply (Var $ reflErrName "CantConvert")
894reflectErr (CantSolveGoal t ctxt) =
895 raw_apply (Var $ reflErrName "CantSolveGoal")
899reflectErr (UnifyScope n n' t ctxt) =
900 raw_apply (Var $ reflErrName "UnifyScope")
906reflectErr (CantInferType str) =
907 raw_apply (Var $ reflErrName "CantInferType") [RConstant (Str str)]
908reflectErr (NonFunctionType t t') =
909 raw_apply (Var $ reflErrName "NonFunctionType") [reflect t, reflect t']
910reflectErr (NotEquality t t') =
911 raw_apply (Var $ reflErrName "NotEquality") [reflect t, reflect t']
912reflectErr (TooManyArguments n) = raw_apply (Var $ reflErrName "TooManyArguments") [reflectName n]
913reflectErr (CantIntroduce t) = raw_apply (Var $ reflErrName "CantIntroduce") [reflect t]
914reflectErr (NoSuchVariable n) = raw_apply (Var $ reflErrName "NoSuchVariable") [reflectName n]
915reflectErr (WithFnType t) = raw_apply (Var $ reflErrName "WithFnType") [reflect t]
916reflectErr (CantMatch t) = raw_apply (Var $ reflErrName "CantMatch") [reflect t]
917reflectErr (NoTypeDecl n) = raw_apply (Var $ reflErrName "NoTypeDecl") [reflectName n]
918reflectErr (NotInjective t1 t2 t3) =
919 raw_apply (Var $ reflErrName "NotInjective")
924reflectErr (CantResolve _ t more)
925 = raw_apply (Var $ reflErrName "CantResolve") [reflect t, reflectErr more]
926reflectErr (InvalidTCArg n t) = raw_apply (Var $ reflErrName "InvalidTCArg") [reflectName n, reflect t]
927reflectErr (CantResolveAlts ss) =
928 raw_apply (Var $ reflErrName "CantResolveAlts")
929 [rawList (Var $ reflm "TTName") (map reflectName ss)]
930reflectErr (IncompleteTerm t) = raw_apply (Var $ reflErrName "IncompleteTerm") [reflect t]
931reflectErr (NoEliminator str t)
932 = raw_apply (Var $ reflErrName "NoEliminator") [RConstant (Str str),
934reflectErr (UniverseError fc ue old new tys) =
935 -- NB: loses information, but OK because this is not likely to be rewritten
936 Var $ reflErrName "UniverseError"
937reflectErr ProgramLineComment = Var $ reflErrName "ProgramLineComment"
938reflectErr (Inaccessible n) = raw_apply (Var $ reflErrName "Inaccessible") [reflectName n]
939reflectErr (UnknownImplicit n f) = raw_apply (Var $ reflErrName "UnknownImplicit") [reflectName n, reflectName f]
940reflectErr (NonCollapsiblePostulate n) = raw_apply (Var $ reflErrName "NonCollabsiblePostulate") [reflectName n]
941reflectErr (AlreadyDefined n) = raw_apply (Var $ reflErrName "AlreadyDefined") [reflectName n]
942reflectErr (ProofSearchFail e) = raw_apply (Var $ reflErrName "ProofSearchFail") [reflectErr e]
943reflectErr (NoRewriting l r tm) = raw_apply (Var $ reflErrName "NoRewriting") [reflect l, reflect r, reflect tm]
944reflectErr (ProviderError str) =
945 raw_apply (Var $ reflErrName "ProviderError") [RConstant (Str str)]
946reflectErr (LoadingFailed str err) =
947 raw_apply (Var $ reflErrName "LoadingFailed") [RConstant (Str str)]
948reflectErr x = raw_apply (Var (sNS (sUN "Msg") ["Errors", "Reflection", "Language"])) [RConstant . Str $ "Default reflection: " ++ show x]
950-- | Reflect a file context
951reflectFC :: FC -> Raw
952reflectFC fc = raw_apply (Var (reflm "FileLoc"))
953 [ RConstant (Str (fc_fname fc))
954 , raw_apply (Var pairCon) $
960 , raw_apply (Var pairCon) $
967 where intTy = RConstant (AType (ATInt ITNative))
969reifyFC :: Term -> ElabD FC
971 | (P (DCon _ _ _) cn _, [Constant (Str fn), st, end]) <- unApply tm
972 , cn == reflm "FileLoc" = FC fn <$> reifyPair reifyInt reifyInt st <*> reifyPair reifyInt reifyInt end
973 | otherwise = fail $ "Not a source location: " ++ show tm
975fromTTMaybe :: Term -> Maybe Term -- WARNING: Assumes the term has type Maybe a
976fromTTMaybe (App _ (App _ (P (DCon _ _ _) (NS (UN just) _) _) ty) tm)
977 | just == txt "Just" = Just tm
978fromTTMaybe x = Nothing
980reflErrName :: String -> Name
981reflErrName n = sNS (sUN n) ["Errors", "Reflection", "Language"]
983-- | Attempt to reify a report part from TT to the internal
984-- representation. Not in Idris or ElabD monads because it should be usable
986reifyReportPart :: Term -> Either Err ErrorReportPart
987reifyReportPart (App _ (P (DCon _ _ _) n _) (Constant (Str msg))) | n == reflm "TextPart" =
989reifyReportPart (App _ (P (DCon _ _ _) n _) ttn)
990 | n == reflm "NamePart" =
991 case runElab initEState (reifyTTName ttn) (initElaborator (sMN 0 "hole") internalNS initContext emptyContext 0 Erased) of
992 Error e -> Left . InternalMsg $
993 "could not reify name term " ++
995 " when reflecting an error:" ++ show e
996 OK (n', _)-> Right $ NamePart n'
997reifyReportPart (App _ (P (DCon _ _ _) n _) tm)
998 | n == reflm "TermPart" =
999 case runElab initEState (reifyTT tm) (initElaborator (sMN 0 "hole") internalNS initContext emptyContext 0 Erased) of
1000 Error e -> Left . InternalMsg $
1001 "could not reify reflected term " ++
1003 " when reflecting an error:" ++ show e
1004 OK (tm', _) -> Right $ TermPart tm'
1005reifyReportPart (App _ (P (DCon _ _ _) n _) tm)
1006 | n == reflm "RawPart" =
1007 case runElab initEState (reifyRaw tm) (initElaborator (sMN 0 "hole") internalNS initContext emptyContext 0 Erased) of
1008 Error e -> Left . InternalMsg $
1009 "could not reify reflected raw term " ++
1011 " when reflecting an error: " ++ show e
1012 OK (tm', _) -> Right $ RawPart tm'
1013reifyReportPart (App _ (P (DCon _ _ _) n _) tm)
1014 | n == reflm "SubReport" =
1016 Just xs -> do subParts <- mapM reifyReportPart xs
1017 Right (SubReport subParts)
1018 Nothing -> Left . InternalMsg $ "could not reify subreport " ++ show tm
1019reifyReportPart x = Left . InternalMsg $ "could not reify " ++ show x
1021reifyErasure :: Term -> ElabD RErasure
1022reifyErasure (P (DCon _ _ _) n _)
1023 | n == tacN "Erased" = return RErased
1024 | n == tacN "NotErased" = return RNotErased
1025reifyErasure tm = fail $ "Can't reify " ++ show tm ++ " as erasure info."
1027reifyPlicity :: Term -> ElabD RPlicity
1028reifyPlicity (P (DCon _ _ _) n _)
1029 | n == tacN "Explicit" = return RExplicit
1030 | n == tacN "Implicit" = return RImplicit
1031 | n == tacN "Constraint" = return RConstraint
1032reifyPlicity tm = fail $ "Couldn't reify " ++ show tm ++ " as RPlicity."
1034reifyRFunArg :: Term -> ElabD RFunArg
1035reifyRFunArg (App _ (App _ (App _ (App _ (P (DCon _ _ _) n _) argN) argTy) argPl) argE)
1036 | n == tacN "MkFunArg" = liftM4 RFunArg
1039 (reifyPlicity argPl)
1041reifyRFunArg aTm = fail $ "Couldn't reify " ++ show aTm ++ " as an RArg."
1043reifyTyDecl :: Term -> ElabD RTyDecl
1044reifyTyDecl (App _ (App _ (App _ (P (DCon _ _ _) n _) tyN) args) ret)
1045 | n == tacN "Declare" =
1046 do tyN' <- reifyTTName tyN
1047 args' <- case unList args of
1048 Nothing -> fail $ "Couldn't reify " ++ show args ++ " as an arglist."
1049 Just xs -> mapM reifyRFunArg xs
1050 ret' <- reifyRaw ret
1051 return $ RDeclare tyN' args' ret'
1052reifyTyDecl tm = fail $ "Couldn't reify " ++ show tm ++ " as a type declaration."
1054reifyFunDefn :: Term -> ElabD (RFunDefn Raw)
1055reifyFunDefn (App _ (App _ (App _ (P _ n _) (P _ t _)) fnN) clauses)
1056 | n == tacN "DefineFun" && t == reflm "Raw" =
1057 do fnN' <- reifyTTName fnN
1058 clauses' <- case unList clauses of
1059 Nothing -> fail $ "Couldn't reify " ++ show clauses ++ " as a clause list"
1060 Just cs -> mapM reifyC cs
1061 return $ RDefineFun fnN' clauses'
1062 where reifyC :: Term -> ElabD (RFunClause Raw)
1063 reifyC (App _ (App _ (App _ (P (DCon _ _ _) n _) (P _ t _)) lhs) rhs)
1064 | n == tacN "MkFunClause" && t == reflm "Raw" = liftM2 RMkFunClause
1067 reifyC (App _ (App _ (P (DCon _ _ _) n _) (P _ t _)) lhs)
1068 | n == tacN "MkImpossibleClause" && t == reflm "Raw" = fmap RMkImpossibleClause $ reifyRaw lhs
1069 reifyC tm = fail $ "Couldn't reify " ++ show tm ++ " as a clause."
1070reifyFunDefn tm = fail $ "Couldn't reify " ++ show tm ++ " as a function declaration."
1072reifyRConstructorDefn :: Term -> ElabD RConstructorDefn
1073reifyRConstructorDefn (App _ (App _ (App _ (P _ n _) cn) args) retTy)
1074 | n == tacN "Constructor", Just args' <- unList args
1075 = RConstructor <$> reifyTTName cn <*> mapM reifyRFunArg args' <*> reifyRaw retTy
1076reifyRConstructorDefn aTm = fail $ "Couldn't reify " ++ show aTm ++ " as an RConstructorDefn"
1078reifyRDataDefn :: Term -> ElabD RDataDefn
1079reifyRDataDefn (App _ (App _ (P _ n _) tyn) ctors)
1080 | n == tacN "DefineDatatype", Just ctors' <- unList ctors
1081 = RDefineDatatype <$> reifyTTName tyn <*> mapM reifyRConstructorDefn ctors'
1082reifyRDataDefn aTm = fail $ "Couldn't reify " ++ show aTm ++ " as an RDataDefn"
1086 = raw_apply (Var pairTy) [ (Var $ reflm "TTName")
1087 , (RApp (Var $ reflm "Binder") (Var $ reflm "TT"))
1090reflectList :: Raw -> [Raw] -> Raw
1091reflectList ty [] = RApp (Var (sNS (sUN "Nil") ["List", "Prelude"])) ty
1092reflectList ty (x:xs) = RApp (RApp (RApp (Var (sNS (sUN "::") ["List", "Prelude"])) ty)
1096-- | Apply Idris's implicit info to get a signature. The [PArg] should
1097-- come from a lookup in idris_implicits on IState.
1098getArgs :: [PArg] -> Raw -> ([RFunArg], Raw)
1099getArgs [] r = ([], r)
1100getArgs (a:as) (RBind n (Pi _ _ ty _) sc) =
1101 let (args, res) = getArgs as sc
1102 erased = if InaccessibleArg `elem` argopts a then RErased else RNotErased
1104 PImp {} -> RFunArg n ty RImplicit erased
1105 PExp {} -> RFunArg n ty RExplicit erased
1106 PConstraint {} -> RFunArg n ty RConstraint erased
1107 PTacImplicit {} -> RFunArg n ty RImplicit erased
1109getArgs _ r = ([], r)
1111unApplyRaw :: Raw -> (Raw, [Raw])
1112unApplyRaw tm = ua [] tm
1114 ua args (RApp f a) = ua (a:args) f
1115 ua args t = (t, args)
1117-- | Build the reflected function definition(s) that correspond(s) to
1118-- a provided unqualifed name
1119buildFunDefns :: IState -> Name -> [RFunDefn Term]
1120buildFunDefns ist n =
1121 [ mkFunDefn name clauses
1122 | (name, (clauses, _)) <- lookupCtxtName n $ idris_patdefs ist
1125 where mkFunDefn name clauses = RDefineFun name (map mkFunClause clauses)
1127 mkFunClause ([], lhs, Impossible) = RMkImpossibleClause lhs
1128 mkFunClause ([], lhs, rhs) = RMkFunClause lhs rhs
1129 mkFunClause (((n, ty) : ns), lhs, rhs) = mkFunClause (ns, bind lhs, bind rhs) where
1130 bind Impossible = Impossible
1131 bind tm = Bind n (PVar RigW ty) tm
1133-- | Build the reflected datatype definition(s) that correspond(s) to
1134-- a provided unqualified name
1135buildDatatypes :: IState -> Name -> [RDatatype]
1136buildDatatypes ist n =
1137 catMaybes [ mkDataType dn ti
1138 | (dn, ti) <- lookupCtxtName n datatypes
1140 where datatypes = idris_datatypes ist
1142 impls = idris_implicits ist
1144 ctorSig params cn = do cty <- fmap forget (lookupTyExact cn ctxt)
1145 argInfo <- lookupCtxtExact cn impls
1146 let (args, res) = getArgs argInfo cty
1147 return (cn, ctorArgsStatus args res params, res)
1149 argPos n [] res = findPos n res
1150 where findPos n app = case unApplyRaw app of
1151 (_, argL) -> findIndex (== Var n) argL
1152 argPos n (arg:args) res = if n == argName arg
1154 else argPos n args res
1156 ctorArgsStatus :: [RFunArg] -> Raw -> [Int] -> [RCtorArg]
1157 ctorArgsStatus [] _ _ = []
1158 ctorArgsStatus (arg:args) res params =
1159 case argPos (argName arg) args res of
1160 Nothing -> RCtorField arg : ctorArgsStatus args res params
1161 Just i -> if i `elem` params
1162 then RCtorParameter arg : ctorArgsStatus args res params
1163 else RCtorField arg : ctorArgsStatus args res params
1165 mkDataType name (TI {param_pos = params, con_names = constrs}) =
1166 do (TyDecl (TCon _ _) ty) <- lookupDefExact name ctxt
1167 implInfo <- lookupCtxtExact name impls
1168 let (tcargs, tcres) = getTCArgs params implInfo (forget ty)
1169 ctors <- mapM (ctorSig params) constrs
1170 return $ RDatatype name tcargs tcres ctors
1172 getTCArgs :: [Int] -> [PArg] -> Raw -> ([RTyConArg], Raw)
1173 getTCArgs params implInfo tcTy =
1174 let (args, res) = getArgs implInfo tcTy
1175 in (tcArg args 0, res)
1176 where tcArg [] _ = []
1177 tcArg (arg:args) i | i `elem` params = RParameter arg : tcArg args (i+1)
1178 | otherwise = RIndex arg : tcArg args (i+1)
1181reflectErasure :: RErasure -> Raw
1182reflectErasure RErased = Var (tacN "Erased")
1183reflectErasure RNotErased = Var (tacN "NotErased")
1185reflectPlicity :: RPlicity -> Raw
1186reflectPlicity RExplicit = Var (tacN "Explicit")
1187reflectPlicity RImplicit = Var (tacN "Implicit")
1188reflectPlicity RConstraint = Var (tacN "Constraint")
1190reflectArg :: RFunArg -> Raw
1191reflectArg (RFunArg n ty plic erasure) =
1192 RApp (RApp (RApp (RApp (Var $ tacN "MkFunArg") (reflectName n))
1194 (reflectPlicity plic))
1195 (reflectErasure erasure)
1197reflectCtorArg :: RCtorArg -> Raw
1198reflectCtorArg (RCtorParameter arg) = RApp (Var $ tacN "CtorParameter") (reflectArg arg)
1199reflectCtorArg (RCtorField arg) = RApp (Var $ tacN "CtorField") (reflectArg arg)
1201reflectDatatype :: RDatatype -> Raw
1202reflectDatatype (RDatatype tyn tyConArgs tyConRes constrs) =
1203 raw_apply (Var $ tacN "MkDatatype") [ reflectName tyn
1204 , rawList (Var $ tacN "TyConArg") (map reflectConArg tyConArgs)
1205 , reflectRaw tyConRes
1206 , rawList (rawTripleTy (Var $ reflm "TTName")
1207 (RApp (Var (sNS (sUN "List") ["List", "Prelude"]))
1208 (Var $ tacN "CtorArg"))
1209 (Var $ reflm "Raw"))
1210 [ rawTriple ((Var $ reflm "TTName")
1211 ,(RApp (Var (sNS (sUN "List") ["List", "Prelude"]))
1212 (Var $ tacN "CtorArg"))
1213 ,(Var $ reflm "Raw"))
1215 ,rawList (Var $ tacN "CtorArg")
1216 (map reflectCtorArg cargs)
1218 | (cn, cargs, cty) <- constrs
1221 where reflectConArg (RParameter a) =
1222 RApp (Var $ tacN "TyConParameter") (reflectArg a)
1223 reflectConArg (RIndex a) =
1224 RApp (Var $ tacN "TyConIndex") (reflectArg a)
1226reflectFunClause :: RFunClause Term -> Raw
1227reflectFunClause (RMkFunClause lhs rhs) = raw_apply (Var $ tacN "MkFunClause")
1228 $ (Var $ reflm "TT") : map reflect [ lhs, rhs ]
1230reflectFunClause (RMkImpossibleClause lhs) = raw_apply (Var $ tacN "MkImpossibleClause")
1231 [ Var $ reflm "TT", reflect lhs ]
1233reflectFunDefn :: RFunDefn Term -> Raw
1234reflectFunDefn (RDefineFun name clauses) = raw_apply (Var $ tacN "DefineFun")
1237 , rawList (RApp (Var $ tacN "FunClause")
1239 (map reflectFunClause clauses)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list