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)
119 | t == reflm "ApplyTactic" = liftM (ApplyTactic . delab ist) (reifyTT t')
121 | t == reflm "Reflect" = liftM (Reflect . delab ist) (reifyTT t')
123 | t == reflm "ByReflection" = liftM (ByReflection . delab ist) (reifyTT t')
125 | t == reflm "Fill" = liftM (Fill . PQuote) (reifyRaw t')
127 | t == reflm "Exact" = liftM (Exact . delab ist) (reifyTT t')
129 | t == reflm "Focus" = liftM Focus (reifyTTName x)
131 | t == reflm "Rewrite" = liftM (Rewrite . delab ist) (reifyTT t')
132reifyApp ist t [n, t']
133 | t == reflm "LetTac" = do n' <- reifyTTName n
135 return $ LetTac n' (delab ist t')
136reifyApp ist t [n, tt', t']
137 | t == reflm "LetTacTy" = do n' <- reifyTTName n
140 return $ LetTacTy n' (delab ist tt'') (delab ist t'')
142 | t == reflm "Fail" = fmap TFail (reifyReportParts errs)
143reifyApp _ f args = fail ("Unknown tactic " ++ show (f, args)) -- shouldn't happen
145reifyBool :: Term -> ElabD Bool
146reifyBool (P _ n _) | n == sNS (sUN "True") ["Bool", "Prelude"] = return True
147 | n == sNS (sUN "False") ["Bool", "Prelude"] = return False
148reifyBool tm = fail $ "Not a Boolean: " ++ show tm
150reifyInt :: Term -> ElabD Int
151reifyInt (Constant (I i)) = return i
152reifyInt tm = fail $ "Not an Int: " ++ show tm
154reifyPair :: (Term -> ElabD a) -> (Term -> ElabD b) -> Term -> ElabD (a, b)
155reifyPair left right (App _ (App _ (App _ (App _ (P _ n _) _) _) x) y)
156 | n == pairCon = liftM2 (,) (left x) (right y)
157reifyPair left right tm = fail $ "Not a pair: " ++ show tm
159reifyList :: (Term -> ElabD a) -> Term -> ElabD [a]
160reifyList getElt lst =
162 Nothing -> fail "Couldn't reify a list"
163 Just xs -> mapM getElt xs
165reifyReportParts :: Term -> ElabD [ErrorReportPart]
166reifyReportParts errs =
168 Nothing -> fail "Failed to reify errors"
170 let parts = mapM reifyReportPart errs' in
172 Left err -> fail $ "Couldn't reify \"Fail\" tactic - " ++ show err
176-- | Reify terms from their reflected representation
177reifyTT :: Term -> ElabD Term
179 | (P _ f _, args) <- unApply t = reifyTTApp f args
181 | n == reflm "Erased" = return Erased
183 | n == reflm "Impossible" = return Impossible
184reifyTT t = fail ("Unknown reflection term: " ++ show t)
186reifyTTApp :: Name -> [Term] -> ElabD Term
187reifyTTApp t [nt, n, x]
188 | t == reflm "P" = do nt' <- reifyTTNameType nt
192reifyTTApp t [Constant (I i)]
193 | t == reflm "V" = return $ V i
194reifyTTApp t [n, b, x]
195 | t == reflm "Bind" = do n' <- reifyTTName n
196 b' <- reifyTTBinder reifyTT (reflm "TT") b
198 return $ Bind n' b' x'
200 | t == reflm "App" = do f' <- reifyTT f
202 return $ App Complete f' x'
204 | t == reflm "TConst" = liftM Constant (reifyTTConst c)
205reifyTTApp t [t', Constant (I i)]
206 | t == reflm "Proj" = do t'' <- reifyTT t'
209 | t == reflm "TType" = liftM TType (reifyTTUExp tt)
211 | t == reflm "UType" = liftM UType (reifyUniverse tt)
212reifyTTApp t args = fail ("Unknown reflection term: " ++ show (t, args))
214reifyUniverse :: Term -> ElabD Universe
215reifyUniverse (P _ n _) | n == reflm "AllTypes" = return AllTypes
216 | n == reflm "UniqueType" = return UniqueType
217 | n == reflm "NullType" = return NullType
218reifyUniverse tm = fail ("Unknown reflection universe: " ++ show tm)
220-- | Reify raw terms from their reflected representation
221reifyRaw :: Term -> ElabD Raw
222reifyRaw t@(App _ _ _)
223 | (P _ f _, args) <- unApply t = reifyRawApp f args
225 | n == reflm "RType" = return RType
226reifyRaw t = fail ("Unknown reflection raw term in reifyRaw: " ++ show t)
228reifyRawApp :: Name -> [Term] -> ElabD Raw
230 | t == reflm "Var" = liftM Var (reifyTTName n)
231reifyRawApp t [n, b, x]
232 | t == reflm "RBind" = do n' <- reifyTTName n
233 b' <- reifyTTBinder reifyRaw (reflm "Raw") b
235 return $ RBind n' b' x'
237 | t == reflm "RApp" = liftM2 RApp (reifyRaw f) (reifyRaw x)
239 | t == reflm "RConstant" = liftM RConstant (reifyTTConst c)
240reifyRawApp t args = fail ("Unknown reflection raw term in reifyRawApp: " ++ show (t, args))
242reifyTTName :: Term -> ElabD Name
244 | (P _ f _, args) <- unApply t = reifyTTNameApp f args
245reifyTTName t = fail ("Unknown reflection term name: " ++ show t)
247reifyTTNameApp :: Name -> [Term] -> ElabD Name
248reifyTTNameApp t [Constant (Str n)]
249 | t == reflm "UN" = return $ sUN n
250reifyTTNameApp t [n, ns]
251 | t == reflm "NS" = do n' <- reifyTTName n
252 ns' <- reifyTTNamespace ns
254reifyTTNameApp t [Constant (I i), Constant (Str n)]
255 | t == reflm "MN" = return $ sMN i n
258 , (P _ f _, args) <- unApply sn = SN <$> reifySN f args
259 where reifySN :: Name -> [Term] -> ElabD SpecialName
260 reifySN t [Constant (I i), n1, n2]
261 | t == reflm "WhereN" = WhereN i <$> reifyTTName n1 <*> reifyTTName n2
262 reifySN t [Constant (I i), n]
263 | t == reflm "WithN" = WithN i <$> reifyTTName n
265 | t == reflm "ImplementationN" =
267 Nothing -> fail "Can't reify ImplementationN strings"
268 Just ss' -> ImplementationN <$> reifyTTName n <*>
269 pure [T.pack s | Constant (Str s) <- ss']
270 reifySN t [n, Constant (Str s)]
271 | t == reflm "ParentN" =
272 ParentN <$> reifyTTName n <*> pure (T.pack s)
274 | t == reflm "MethodN" =
275 MethodN <$> reifyTTName n
277 | t == reflm "CaseN" =
278 CaseN <$> (FC' <$> reifyFC fc) <*> reifyTTName n
280 | t == reflm "ImplementationCtorN" =
281 ImplementationCtorN <$> reifyTTName n
283 | t == reflm "MetaN" =
284 MetaN <$> reifyTTName n1 <*> reifyTTName n2
285 reifySN t args = fail $ "Can't reify special name " ++ show t ++ show args
286reifyTTNameApp t args = fail ("Unknown reflection term name: " ++ show (t, args))
288reifyTTNamespace :: Term -> ElabD [String]
289reifyTTNamespace t@(App _ _ _)
291 (P _ f _, [Constant StrType])
292 | f == sNS (sUN "Nil") ["List", "Prelude"] -> return []
293 (P _ f _, [Constant StrType, Constant (Str n), ns])
294 | f == sNS (sUN "::") ["List", "Prelude"] -> liftM (n:) (reifyTTNamespace ns)
295 _ -> fail ("Unknown reflection namespace arg: " ++ show t)
296reifyTTNamespace t = fail ("Unknown reflection namespace arg: " ++ show t)
298reifyTTNameType :: Term -> ElabD NameType
299reifyTTNameType t@(P _ n _) | n == reflm "Bound" = return $ Bound
300reifyTTNameType t@(P _ n _) | n == reflm "Ref" = return $ Ref
301reifyTTNameType t@(App _ _ _)
303 (P _ f _, [Constant (I tag), Constant (I num)])
304 | f == reflm "DCon" -> return $ DCon tag num False -- FIXME: Uniqueness!
305 | f == reflm "TCon" -> return $ TCon tag num
306 _ -> fail ("Unknown reflection name type: " ++ show t)
307reifyTTNameType t = fail ("Unknown reflection name type: " ++ show t)
309reifyTTBinder :: (Term -> ElabD a) -> Name -> Term -> ElabD (Binder a)
310reifyTTBinder reificator binderType t@(App _ _ _)
312 (P _ f _, bt:args) | forget bt == Var binderType
313 -> reifyTTBinderApp reificator f args
314 _ -> fail ("Mismatching binder reflection: " ++ show t)
315reifyTTBinder _ _ t = fail ("Unknown reflection binder: " ++ show t)
317reifyTTBinderApp :: (Term -> ElabD a) -> Name -> [Term] -> ElabD (Binder a)
318reifyTTBinderApp reif f [t]
319 | f == reflm "Lam" = liftM (Lam RigW) (reif t)
320reifyTTBinderApp reif f [t, k]
321 | f == reflm "Pi" = liftM2 (Pi RigW Nothing) (reif t) (reif k)
322reifyTTBinderApp reif f [x, y]
323 | f == reflm "Let" = liftM2 (Let RigW) (reif x) (reif y)
324reifyTTBinderApp reif f [t]
325 | f == reflm "Hole" = liftM Hole (reif t)
326reifyTTBinderApp reif f [t]
327 | f == reflm "GHole" = liftM (GHole 0 []) (reif t)
328reifyTTBinderApp reif f [x, y]
329 | f == reflm "Guess" = liftM2 Guess (reif x) (reif y)
330reifyTTBinderApp reif f [t]
331 | f == reflm "PVar" = liftM (PVar RigW) (reif t)
332reifyTTBinderApp reif f [t]
333 | f == reflm "PVTy" = liftM PVTy (reif t)
334reifyTTBinderApp _ f args = fail ("Unknown reflection binder: " ++ show (f, args))
336reifyTTConst :: Term -> ElabD Const
337reifyTTConst (P _ n _) | n == reflm "StrType" = return StrType
338reifyTTConst (P _ n _) | n == reflm "VoidType" = return VoidType
339reifyTTConst (P _ n _) | n == reflm "Forgot" = return Forgot
340reifyTTConst t@(App _ _ _)
341 | (P _ f _, [arg]) <- unApply t = reifyTTConstApp f arg
342reifyTTConst t = fail ("Unknown reflection constant: " ++ show t)
344reifyTTConstApp :: Name -> Term -> ElabD Const
346 | f == reflm "AType" = fmap AType (reifyArithTy aty)
347reifyTTConstApp f (Constant c@(I _))
348 | f == reflm "I" = return c
349reifyTTConstApp f (Constant c@(BI _))
350 | f == reflm "BI" = return c
351reifyTTConstApp f (Constant c@(Fl _))
352 | f == reflm "Fl" = return c
353reifyTTConstApp f (Constant c@(Ch _))
354 | f == reflm "Ch" = return c
355reifyTTConstApp f (Constant c@(Str _))
356 | f == reflm "Str" = return c
357reifyTTConstApp f (Constant c@(B8 _))
358 | f == reflm "B8" = return c
359reifyTTConstApp f (Constant c@(B16 _))
360 | f == reflm "B16" = return c
361reifyTTConstApp f (Constant c@(B32 _))
362 | f == reflm "B32" = return c
363reifyTTConstApp f (Constant c@(B64 _))
364 | f == reflm "B64" = return c
365reifyTTConstApp f v@(P _ _ _) =
367 "Can't reify the variable " ++
369 " as a constant, because its value is not statically known."
370reifyTTConstApp f arg = fail ("Unknown reflection constant: " ++ show (f, arg))
372reifyArithTy :: Term -> ElabD ArithTy
373reifyArithTy (App _ (P _ n _) intTy) | n == reflm "ATInt" = fmap ATInt (reifyIntTy intTy)
374reifyArithTy (P _ n _) | n == reflm "ATDouble" = return ATFloat
375reifyArithTy x = fail ("Couldn't reify reflected ArithTy: " ++ show x)
377reifyNativeTy :: Term -> ElabD NativeTy
378reifyNativeTy (P _ n _) | n == reflm "IT8" = return IT8
379reifyNativeTy (P _ n _) | n == reflm "IT16" = return IT16
380reifyNativeTy (P _ n _) | n == reflm "IT32" = return IT32
381reifyNativeTy (P _ n _) | n == reflm "IT64" = return IT64
382reifyNativeTy x = fail $ "Couldn't reify reflected NativeTy " ++ show x
384reifyIntTy :: Term -> ElabD IntTy
385reifyIntTy (App _ (P _ n _) nt) | n == reflm "ITFixed" = fmap ITFixed (reifyNativeTy nt)
386reifyIntTy (P _ n _) | n == reflm "ITNative" = return ITNative
387reifyIntTy (P _ n _) | n == reflm "ITBig" = return ITBig
388reifyIntTy (P _ n _) | n == reflm "ITChar" = return ITChar
389reifyIntTy tm = fail $ "The term " ++ show tm ++ " is not a reflected IntTy"
391reifyTTUExp :: Term -> ElabD UExp
392reifyTTUExp t@(App _ _ _)
394 (P _ f _, [Constant (Str str), Constant (I i)])
395 | f == reflm "UVar" -> return $ UVar str i
396 (P _ f _, [Constant (I i)])
397 | f == reflm "UVal" -> return $ UVal i
398 _ -> fail ("Unknown reflection type universe expression: " ++ show t)
399reifyTTUExp t = fail ("Unknown reflection type universe expression: " ++ show t)
401-- | Create a reflected call to a named function/constructor
402reflCall :: String -> [Raw] -> Raw
404 = raw_apply (Var (reflm funName)) args
406-- | Lift a term into its Language.Reflection.TT representation
407reflect :: Term -> Raw
408reflect = reflectTTQuote []
410-- | Lift a term into its Language.Reflection.Raw representation
411reflectRaw :: Raw -> Raw
412reflectRaw = reflectRawQuote []
414claimTy :: Name -> Raw -> ElabD Name
415claimTy n ty = do n' <- getNameFrom n
419intToReflectedNat :: Int -> Raw
420intToReflectedNat i = if i <= 0
422 else RApp (Var (natN "S")) (intToReflectedNat (i - 1))
423 where natN :: String -> Name
424 natN n = sNS (sUN n) ["Nat", "Prelude"]
426reflectFixity :: Fixity -> Raw
427reflectFixity (Infixl p) = RApp (Var (tacN "Infixl")) (intToReflectedNat p)
428reflectFixity (Infixr p) = RApp (Var (tacN "Infixr")) (intToReflectedNat p)
429reflectFixity (InfixN p) = RApp (Var (tacN "InfixN")) (intToReflectedNat p)
430reflectFixity (PrefixN p) = RApp (Var (tacN "PrefixN")) (intToReflectedNat p)
432-- | Convert a reflected term to a more suitable form for pattern-matching.
433-- In particular, the less-interesting bits are elaborated to _ patterns. This
434-- happens to NameTypes, universe levels, names that are bound but not used,
435-- and the type annotation field of the P constructor.
436reflectTTQuotePattern :: [Name] -> Term -> ElabD ()
437reflectTTQuotePattern unq (P _ n _)
438 | n `elem` unq = -- the unquoted names have been claimed as TT already - just use them
439 do fill (Var n) ; solve
441 do tyannot <- claimTy (sMN 0 "pTyAnnot") (Var (reflm "TT"))
442 movelast tyannot -- use a _ pattern here
443 nt <- getNameFrom (sMN 0 "nt")
444 claim nt (Var (reflm "NameType"))
445 movelast nt -- use a _ pattern here
446 n' <- getNameFrom (sMN 0 "n")
447 claim n' (Var (reflm "TTName"))
448 fill $ reflCall "P" [Var nt, Var n', Var tyannot]
450 focus n'; reflectNameQuotePattern n
451reflectTTQuotePattern unq (V n)
452 = do fill $ reflCall "V" [RConstant (I n)]
454reflectTTQuotePattern unq (Bind n b x)
455 = do x' <- claimTy (sMN 0 "sc") (Var (reflm "TT"))
457 b' <- getNameFrom (sMN 0 "binder")
458 claim b' (RApp (Var (sNS (sUN "Binder") ["Reflection", "Language"]))
459 (Var (sNS (sUN "TT") ["Reflection", "Language"])))
460 if n `elem` freeNames x
461 then do fill $ reflCall "Bind"
466 else do any <- getNameFrom (sMN 0 "anyName")
467 claim any (Var (reflm "TTName"))
469 fill $ reflCall "Bind"
474 focus x'; reflectTTQuotePattern unq x
475 focus b'; reflectBinderQuotePattern reflectTTQuotePattern (Var $ reflm "TT") unq b
476reflectTTQuotePattern unq (App _ f x)
477 = do f' <- claimTy (sMN 0 "f") (Var (reflm "TT")) ; movelast f'
478 x' <- claimTy (sMN 0 "x") (Var (reflm "TT")) ; movelast x'
479 fill $ reflCall "App" [Var f', Var x']
481 focus f'; reflectTTQuotePattern unq f
482 focus x'; reflectTTQuotePattern unq x
483reflectTTQuotePattern unq (Constant c)
484 = do fill $ reflCall "TConst" [reflectConstant c]
486reflectTTQuotePattern unq (Proj t i)
487 = lift . tfail . InternalMsg $
488 "Phase error! The Proj constructor is for optimization only and should not have been reflected during elaboration."
489reflectTTQuotePattern unq Erased
490 = do erased <- claimTy (sMN 0 "erased") (Var (reflm "TT"))
493reflectTTQuotePattern unq Impossible
494 = lift . tfail . InternalMsg $
495 "Phase error! The Impossible constructor is for optimization only and should not have been reflected during elaboration."
496reflectTTQuotePattern unq (Inferred t)
497 = lift . tfail . InternalMsg $
498 "Phase error! The Inferred constructor is for coverage checking only and should not have been reflected during elaboration."
499reflectTTQuotePattern unq (TType exp)
500 = do ue <- getNameFrom (sMN 0 "uexp")
501 claim ue (Var (sNS (sUN "TTUExp") ["Reflection", "Language"]))
503 fill $ reflCall "TType" [Var ue]
505reflectTTQuotePattern unq (UType u)
506 = do uH <- getNameFrom (sMN 0 "someUniv")
507 claim uH (Var (reflm "Universe"))
509 fill $ reflCall "UType" [Var uH]
512 fill (Var (reflm (case u of
513 NullType -> "NullType"
514 UniqueType -> "UniqueType"
515 AllTypes -> "AllTypes")))
518reflectRawQuotePattern :: [Name] -> Raw -> ElabD ()
519reflectRawQuotePattern unq (Var n)
520 -- the unquoted names already have types, just use them
521 | n `elem` unq = do fill (Var n); solve
522 | otherwise = do fill (reflCall "Var" [reflectName n]); solve
523reflectRawQuotePattern unq (RBind n b sc) =
524 do scH <- getNameFrom (sMN 0 "sc")
525 claim scH (Var (reflm "Raw"))
527 bH <- getNameFrom (sMN 0 "binder")
528 claim bH (RApp (Var (reflm "Binder"))
530 if n `elem` freeNamesR sc
531 then do fill $ reflCall "RBind" [reflectName n,
535 else do any <- getNameFrom (sMN 0 "anyName")
536 claim any (Var (reflm "TTName"))
538 fill $ reflCall "RBind" [Var any, Var bH, Var scH]
540 focus scH; reflectRawQuotePattern unq sc
541 focus bH; reflectBinderQuotePattern reflectRawQuotePattern (Var $ reflm "Raw") unq b
542 where freeNamesR (Var n) = [n]
543 freeNamesR (RBind n (Let rc t v) body) = concat [freeNamesR v,
544 freeNamesR body \\ [n],
546 freeNamesR (RBind n b body) = freeNamesR (binderTy b) ++
547 (freeNamesR body \\ [n])
548 freeNamesR (RApp f x) = freeNamesR f ++ freeNamesR x
549 freeNamesR RType = []
550 freeNamesR (RUType _) = []
551 freeNamesR (RConstant _) = []
552reflectRawQuotePattern unq (RApp f x) =
553 do fH <- getNameFrom (sMN 0 "f")
554 claim fH (Var (reflm "Raw"))
556 xH <- getNameFrom (sMN 0 "x")
557 claim xH (Var (reflm "Raw"))
559 fill $ reflCall "RApp" [Var fH, Var xH]
561 focus fH; reflectRawQuotePattern unq f
562 focus xH; reflectRawQuotePattern unq x
563reflectRawQuotePattern unq RType =
564 do fill (Var (reflm "RType"))
566reflectRawQuotePattern unq (RUType univ) =
567 do uH <- getNameFrom (sMN 0 "universe")
568 claim uH (Var (reflm "Universe"))
570 fill $ reflCall "RUType" [Var uH]
572 focus uH; fill (reflectUniverse univ); solve
573reflectRawQuotePattern unq (RConstant c) =
574 do cH <- getNameFrom (sMN 0 "const")
575 claim cH (Var (reflm "Constant"))
577 fill (reflCall "RConstant" [Var cH]); solve
579 fill (reflectConstant c); solve
581reflectBinderQuotePattern :: ([Name] -> a -> ElabD ()) -> Raw -> [Name] -> Binder a -> ElabD ()
582reflectBinderQuotePattern q ty unq (Lam _ t)
583 = do t' <- claimTy (sMN 0 "ty") ty; movelast t'
584 fill $ reflCall "Lam" [ty, Var t']
587reflectBinderQuotePattern q ty unq (Pi _ _ t k)
588 = do t' <- claimTy (sMN 0 "ty") ty; movelast t'
589 k' <- claimTy (sMN 0 "k") ty; movelast k';
590 fill $ reflCall "Pi" [ty, Var t', Var k']
593reflectBinderQuotePattern q ty unq (Let rc x y)
594 = do x' <- claimTy (sMN 0 "ty") ty; movelast x';
595 y' <- claimTy (sMN 0 "v")ty; movelast y';
596 fill $ reflCall "Let" [ty, Var x', Var y']
600reflectBinderQuotePattern q ty unq (NLet x y)
601 = do x' <- claimTy (sMN 0 "ty") ty; movelast x'
602 y' <- claimTy (sMN 0 "v") ty; movelast y'
603 fill $ reflCall "Let" [ty, Var x', Var y']
607reflectBinderQuotePattern q ty unq (Hole t)
608 = do t' <- claimTy (sMN 0 "ty") ty; movelast t'
609 fill $ reflCall "Hole" [ty, Var t']
612reflectBinderQuotePattern q ty unq (GHole _ _ t)
613 = do t' <- claimTy (sMN 0 "ty") ty; movelast t'
614 fill $ reflCall "GHole" [ty, Var t']
617reflectBinderQuotePattern q ty unq (Guess x y)
618 = do x' <- claimTy (sMN 0 "ty") ty; movelast x'
619 y' <- claimTy (sMN 0 "v") ty; movelast y'
620 fill $ reflCall "Guess" [ty, Var x', Var y']
624reflectBinderQuotePattern q ty unq (PVar _ t)
625 = do t' <- claimTy (sMN 0 "ty") ty; movelast t'
626 fill $ reflCall "PVar" [ty, Var t']
629reflectBinderQuotePattern q ty unq (PVTy t)
630 = do t' <- claimTy (sMN 0 "ty") ty; movelast t'
631 fill $ reflCall "PVTy" [ty, Var t']
635reflectUniverse :: Universe -> Raw
637 (Var (reflm (case u of
638 NullType -> "NullType"
639 UniqueType -> "UniqueType"
640 AllTypes -> "AllTypes")))
642-- | Create a reflected TT term, but leave refs to the provided name intact
643reflectTTQuote :: [Name] -> Term -> Raw
644reflectTTQuote unq (P nt n t)
645 | n `elem` unq = Var n
646 | otherwise = reflCall "P" [reflectNameType nt, reflectName n, reflectTTQuote unq t]
647reflectTTQuote unq (V n)
648 = reflCall "V" [RConstant (I n)]
649reflectTTQuote unq (Bind n b x)
650 = reflCall "Bind" [reflectName n, reflectBinderQuote reflectTTQuote (reflm "TT") unq b, reflectTTQuote unq x]
651reflectTTQuote unq (App _ f x)
652 = reflCall "App" [reflectTTQuote unq f, reflectTTQuote unq x]
653reflectTTQuote unq (Constant c)
654 = reflCall "TConst" [reflectConstant c]
655reflectTTQuote unq (TType exp) = reflCall "TType" [reflectUExp exp]
656reflectTTQuote unq (UType u) = reflCall "UType" [reflectUniverse u]
657reflectTTQuote _ (Proj _ _) =
658 error "Phase error! The Proj constructor is for optimization only and should not have been reflected during elaboration."
659reflectTTQuote unq Erased = Var (reflm "Erased")
660reflectTTQuote _ Impossible =
661 error "Phase error! The Impossible constructor is for optimization only and should not have been reflected during elaboration."
662reflectTTQuote _ (Inferred tm) =
663 error "Phase error! The Inferred constructor is for coverage checking only and should not have been reflected during elaboration."
665reflectRawQuote :: [Name] -> Raw -> Raw
666reflectRawQuote unq (Var n)
667 | n `elem` unq = Var n
668 | otherwise = reflCall "Var" [reflectName n]
669reflectRawQuote unq (RBind n b r) =
670 reflCall "RBind" [reflectName n, reflectBinderQuote reflectRawQuote (reflm "Raw") unq b, reflectRawQuote unq r]
671reflectRawQuote unq (RApp f x) =
672 reflCall "RApp" [reflectRawQuote unq f, reflectRawQuote unq x]
673reflectRawQuote unq RType = Var (reflm "RType")
674reflectRawQuote unq (RUType u) =
675 reflCall "RUType" [reflectUniverse u]
676reflectRawQuote unq (RConstant cst) = reflCall "RConstant" [reflectConstant cst]
678reflectNameType :: NameType -> Raw
679reflectNameType (Bound) = Var (reflm "Bound")
680reflectNameType (Ref) = Var (reflm "Ref")
681reflectNameType (DCon x y _)
682 = reflCall "DCon" [RConstant (I x), RConstant (I y)] -- FIXME: Uniqueness!
683reflectNameType (TCon x y)
684 = reflCall "TCon" [RConstant (I x), RConstant (I y)]
686reflectName :: Name -> Raw
688 = reflCall "UN" [RConstant (Str (str s))]
690 = reflCall "NS" [ reflectName n
692 raw_apply ( Var $ sNS (sUN "::") ["List", "Prelude"] )
693 [ RConstant StrType, RConstant (Str n), s ])
694 ( raw_apply ( Var $ sNS (sUN "Nil") ["List", "Prelude"] )
695 [ RConstant StrType ])
699 = reflCall "MN" [RConstant (I i), RConstant (Str (str n))]
700reflectName (SN sn) = raw_apply (Var (reflm "SN")) [reflectSpecialName sn]
701reflectName (SymRef _) = error "The impossible happened: symbol table ref survived IBC loading"
703reflectSpecialName :: SpecialName -> Raw
704reflectSpecialName (WhereN i n1 n2) =
705 reflCall "WhereN" [RConstant (I i), reflectName n1, reflectName n2]
706reflectSpecialName (WithN i n) = reflCall "WithN" [ RConstant (I i)
709reflectSpecialName (ImplementationN impl ss) =
710 reflCall "ImplementationN" [ reflectName impl
711 , mkList (RConstant StrType) $
712 map (RConstant . Str . T.unpack) ss
714reflectSpecialName (ParentN n s) =
715 reflCall "ParentN" [reflectName n, RConstant (Str (T.unpack s))]
716reflectSpecialName (MethodN n) =
717 reflCall "MethodN" [reflectName n]
718reflectSpecialName (CaseN fc n) =
719 reflCall "CaseN" [reflectFC (unwrapFC fc), reflectName n]
720reflectSpecialName (ImplementationCtorN n) =
721 reflCall "ImplementationCtorN" [reflectName n]
722reflectSpecialName (MetaN parent meta) =
723 reflCall "MetaN" [reflectName parent, reflectName meta]
725-- | Elaborate a name to a pattern. This means that NS and UN will be intact.
726-- MNs corresponding to will care about the string but not the number. All
728reflectNameQuotePattern :: Name -> ElabD ()
729reflectNameQuotePattern n@(UN s)
730 = do fill $ reflectName n
732reflectNameQuotePattern n@(NS _ _)
733 = do fill $ reflectName n
735reflectNameQuotePattern (MN _ n)
736 = do i <- getNameFrom (sMN 0 "mnCounter")
737 claim i (RConstant (AType (ATInt ITNative)))
739 fill $ reflCall "MN" [Var i, RConstant (Str $ T.unpack n)]
741reflectNameQuotePattern _ -- for all other names, match any
742 = do nameHole <- getNameFrom (sMN 0 "name")
743 claim nameHole (Var (reflm "TTName"))
748reflectBinder :: Binder Term -> Raw
749reflectBinder = reflectBinderQuote reflectTTQuote (reflm "TT") []
751reflectBinderQuote :: ([Name] -> a -> Raw) -> Name -> [Name] -> Binder a -> Raw
752reflectBinderQuote q ty unq (Lam _ t)
753 = reflCall "Lam" [Var ty, q unq t]
754reflectBinderQuote q ty unq (Pi _ _ t k)
755 = reflCall "Pi" [Var ty, q unq t, q unq k]
756reflectBinderQuote q ty unq (Let rc x y)
757 = reflCall "Let" [Var ty, q unq x, q unq y]
758reflectBinderQuote q ty unq (NLet x y)
759 = reflCall "Let" [Var ty, q unq x, q unq y]
760reflectBinderQuote q ty unq (Hole t)
761 = reflCall "Hole" [Var ty, q unq t]
762reflectBinderQuote q ty unq (GHole _ _ t)
763 = reflCall "GHole" [Var ty, q unq t]
764reflectBinderQuote q ty unq (Guess x y)
765 = reflCall "Guess" [Var ty, q unq x, q unq y]
766reflectBinderQuote q ty unq (PVar _ t)
767 = reflCall "PVar" [Var ty, q unq t]
768reflectBinderQuote q ty unq (PVTy t)
769 = reflCall "PVTy" [Var ty, q unq t]
771mkList :: Raw -> [Raw] -> Raw
772mkList ty [] = RApp (Var (sNS (sUN "Nil") ["List", "Prelude"])) ty
773mkList ty (x:xs) = RApp (RApp (RApp (Var (sNS (sUN "::") ["List", "Prelude"])) ty)
777reflectConstant :: Const -> Raw
778reflectConstant c@(I _) = reflCall "I" [RConstant c]
779reflectConstant c@(BI _) = reflCall "BI" [RConstant c]
780reflectConstant c@(Fl _) = reflCall "Fl" [RConstant c]
781reflectConstant c@(Ch _) = reflCall "Ch" [RConstant c]
782reflectConstant c@(Str _) = reflCall "Str" [RConstant c]
783reflectConstant c@(B8 _) = reflCall "B8" [RConstant c]
784reflectConstant c@(B16 _) = reflCall "B16" [RConstant c]
785reflectConstant c@(B32 _) = reflCall "B32" [RConstant c]
786reflectConstant c@(B64 _) = reflCall "B64" [RConstant c]
787reflectConstant (AType (ATInt ITNative)) = reflCall "AType" [reflCall "ATInt" [Var (reflm "ITNative")]]
788reflectConstant (AType (ATInt ITBig)) = reflCall "AType" [reflCall "ATInt" [Var (reflm "ITBig")]]
789reflectConstant (AType ATFloat) = reflCall "AType" [Var (reflm "ATDouble")]
790reflectConstant (AType (ATInt ITChar)) = reflCall "AType" [reflCall "ATInt" [Var (reflm "ITChar")]]
791reflectConstant StrType = Var (reflm "StrType")
792reflectConstant (AType (ATInt (ITFixed IT8))) = reflCall "AType" [reflCall "ATInt" [reflCall "ITFixed" [Var (reflm "IT8")]]]
793reflectConstant (AType (ATInt (ITFixed IT16))) = reflCall "AType" [reflCall "ATInt" [reflCall "ITFixed" [Var (reflm "IT16")]]]
794reflectConstant (AType (ATInt (ITFixed IT32))) = reflCall "AType" [reflCall "ATInt" [reflCall "ITFixed" [Var (reflm "IT32")]]]
795reflectConstant (AType (ATInt (ITFixed IT64))) = reflCall "AType" [reflCall "ATInt" [reflCall "ITFixed" [Var (reflm "IT64")]]]
796reflectConstant VoidType = Var (reflm "VoidType")
797reflectConstant Forgot = Var (reflm "Forgot")
798reflectConstant WorldType = Var (reflm "WorldType")
799reflectConstant TheWorld = Var (reflm "TheWorld")
801reflectUExp :: UExp -> Raw
802reflectUExp (UVar ns i) = reflCall "UVar" [RConstant (Str ns), RConstant (I i)]
803reflectUExp (UVal i) = reflCall "UVal" [RConstant (I i)]
805-- | Reflect the environment of a proof into a List (TTName, Binder TT)
806reflectEnv :: Env -> Raw
807reflectEnv = foldr consToEnvList emptyEnvList . envBinders
809 consToEnvList :: (Name, Binder Term) -> Raw -> Raw
810 consToEnvList (n, b) l
811 = raw_apply (Var (sNS (sUN "::") ["List", "Prelude"]))
813 , raw_apply (Var pairCon) [ (Var $ reflm "TTName")
814 , (RApp (Var $ reflm "Binder")
823 emptyEnvList = raw_apply (Var (sNS (sUN "Nil") ["List", "Prelude"]))
826-- Reflected environments don't get the RigCount (for the moment, at least)
827reifyEnv :: Term -> ElabD Env
828reifyEnv tm = do preEnv <- reifyList (reifyPair reifyTTName (reifyTTBinder reifyTT (reflm "TT"))) tm
829 return $ map (\(n, b) -> (n, RigW, b)) preEnv
831-- | Reflect an error into the internal datatype of Idris -- TODO
832rawBool :: Bool -> Raw
833rawBool True = Var (sNS (sUN "True") ["Bool", "Prelude"])
834rawBool False = Var (sNS (sUN "False") ["Bool", "Prelude"])
837rawNil ty = raw_apply (Var (sNS (sUN "Nil") ["List", "Prelude"])) [ty]
839rawCons :: Raw -> Raw -> Raw -> Raw
840rawCons ty hd tl = raw_apply (Var (sNS (sUN "::") ["List", "Prelude"])) [ty, hd, tl]
842rawList :: Raw -> [Raw] -> Raw
843rawList ty = foldr (rawCons ty) (rawNil ty)
845rawPairTy :: Raw -> Raw -> Raw
846rawPairTy t1 t2 = raw_apply (Var pairTy) [t1, t2]
848rawPair :: (Raw, Raw) -> (Raw, Raw) -> Raw
849rawPair (a, b) (x, y) = raw_apply (Var pairCon) [a, b, x, y]
851-- | Idris tuples nest to the right
852rawTripleTy :: Raw -> Raw -> Raw -> Raw
853rawTripleTy a b c = rawPairTy a (rawPairTy b c)
855rawTriple :: (Raw, Raw, Raw) -> (Raw, Raw, Raw) -> Raw
856rawTriple (a, b, c) (x, y, z) = rawPair (a, rawPairTy b c) (x, rawPair (b, c) (y, z))
858reflectCtxt :: [(Name, Type)] -> Raw
859reflectCtxt ctxt = rawList (rawPairTy (Var $ reflm "TTName") (Var $ reflm "TT"))
860 (map (\ (n, t) -> (rawPair (Var $ reflm "TTName", Var $ reflm "TT")
861 (reflectName n, reflect t)))
864reflectErr :: Err -> Raw
865reflectErr (Msg msg) = raw_apply (Var $ reflErrName "Msg") [RConstant (Str msg)]
866reflectErr (InternalMsg msg) = raw_apply (Var $ reflErrName "InternalMsg") [RConstant (Str msg)]
867reflectErr (CantUnify b (t1,_) (t2,_) e ctxt i) =
868 raw_apply (Var $ reflErrName "CantUnify")
875reflectErr (InfiniteUnify n tm ctxt) =
876 raw_apply (Var $ reflErrName "InfiniteUnify")
881reflectErr (CantConvert t t' ctxt) =
882 raw_apply (Var $ reflErrName "CantConvert")
887reflectErr (CantSolveGoal t ctxt) =
888 raw_apply (Var $ reflErrName "CantSolveGoal")
892reflectErr (UnifyScope n n' t ctxt) =
893 raw_apply (Var $ reflErrName "UnifyScope")
899reflectErr (CantInferType str) =
900 raw_apply (Var $ reflErrName "CantInferType") [RConstant (Str str)]
901reflectErr (NonFunctionType t t') =
902 raw_apply (Var $ reflErrName "NonFunctionType") [reflect t, reflect t']
903reflectErr (NotEquality t t') =
904 raw_apply (Var $ reflErrName "NotEquality") [reflect t, reflect t']
905reflectErr (TooManyArguments n) = raw_apply (Var $ reflErrName "TooManyArguments") [reflectName n]
906reflectErr (CantIntroduce t) = raw_apply (Var $ reflErrName "CantIntroduce") [reflect t]
907reflectErr (NoSuchVariable n) = raw_apply (Var $ reflErrName "NoSuchVariable") [reflectName n]
908reflectErr (WithFnType t) = raw_apply (Var $ reflErrName "WithFnType") [reflect t]
909reflectErr (CantMatch t) = raw_apply (Var $ reflErrName "CantMatch") [reflect t]
910reflectErr (NoTypeDecl n) = raw_apply (Var $ reflErrName "NoTypeDecl") [reflectName n]
911reflectErr (NotInjective t1 t2 t3) =
912 raw_apply (Var $ reflErrName "NotInjective")
917reflectErr (CantResolve _ t more)
918 = raw_apply (Var $ reflErrName "CantResolve") [reflect t, reflectErr more]
919reflectErr (InvalidTCArg n t) = raw_apply (Var $ reflErrName "InvalidTCArg") [reflectName n, reflect t]
920reflectErr (CantResolveAlts ss) =
921 raw_apply (Var $ reflErrName "CantResolveAlts")
922 [rawList (Var $ reflm "TTName") (map reflectName ss)]
923reflectErr (IncompleteTerm t) = raw_apply (Var $ reflErrName "IncompleteTerm") [reflect t]
924reflectErr (UniverseError fc ue old new tys) =
925 -- NB: loses information, but OK because this is not likely to be rewritten
926 Var $ reflErrName "UniverseError"
927reflectErr ProgramLineComment = Var $ reflErrName "ProgramLineComment"
928reflectErr (Inaccessible n) = raw_apply (Var $ reflErrName "Inaccessible") [reflectName n]
929reflectErr (UnknownImplicit n f) = raw_apply (Var $ reflErrName "UnknownImplicit") [reflectName n, reflectName f]
930reflectErr (NonCollapsiblePostulate n) = raw_apply (Var $ reflErrName "NonCollabsiblePostulate") [reflectName n]
931reflectErr (AlreadyDefined n) = raw_apply (Var $ reflErrName "AlreadyDefined") [reflectName n]
932reflectErr (ProofSearchFail e) = raw_apply (Var $ reflErrName "ProofSearchFail") [reflectErr e]
933reflectErr (NoRewriting l r tm) = raw_apply (Var $ reflErrName "NoRewriting") [reflect l, reflect r, reflect tm]
934reflectErr (ProviderError str) =
935 raw_apply (Var $ reflErrName "ProviderError") [RConstant (Str str)]
936reflectErr (LoadingFailed str err) =
937 raw_apply (Var $ reflErrName "LoadingFailed") [RConstant (Str str)]
938reflectErr x = raw_apply (Var (sNS (sUN "Msg") ["Errors", "Reflection", "Language"])) [RConstant . Str $ "Default reflection: " ++ show x]
940-- | Reflect a file context
941reflectFC :: FC -> Raw
942reflectFC fc = raw_apply (Var (reflm "FileLoc"))
943 [ RConstant (Str (fc_fname fc))
944 , raw_apply (Var pairCon) $
950 , raw_apply (Var pairCon) $
957 where intTy = RConstant (AType (ATInt ITNative))
959reifyFC :: Term -> ElabD FC
961 | (P (DCon _ _ _) cn _, [Constant (Str fn), st, end]) <- unApply tm
962 , cn == reflm "FileLoc" = FC fn <$> reifyPair reifyInt reifyInt st <*> reifyPair reifyInt reifyInt end
963 | otherwise = fail $ "Not a source location: " ++ show tm
965fromTTMaybe :: Term -> Maybe Term -- WARNING: Assumes the term has type Maybe a
966fromTTMaybe (App _ (App _ (P (DCon _ _ _) (NS (UN just) _) _) ty) tm)
967 | just == txt "Just" = Just tm
968fromTTMaybe x = Nothing
970reflErrName :: String -> Name
971reflErrName n = sNS (sUN n) ["Errors", "Reflection", "Language"]
973-- | Attempt to reify a report part from TT to the internal
974-- representation. Not in Idris or ElabD monads because it should be usable
976reifyReportPart :: Term -> Either Err ErrorReportPart
977reifyReportPart (App _ (P (DCon _ _ _) n _) (Constant (Str msg))) | n == reflm "TextPart" =
979reifyReportPart (App _ (P (DCon _ _ _) n _) ttn)
980 | n == reflm "NamePart" =
981 case runElab initEState (reifyTTName ttn) (initElaborator (sMN 0 "hole") internalNS initContext emptyContext 0 Erased) of
982 Error e -> Left . InternalMsg $
983 "could not reify name term " ++
985 " when reflecting an error:" ++ show e
986 OK (n', _)-> Right $ NamePart n'
987reifyReportPart (App _ (P (DCon _ _ _) n _) tm)
988 | n == reflm "TermPart" =
989 case runElab initEState (reifyTT tm) (initElaborator (sMN 0 "hole") internalNS initContext emptyContext 0 Erased) of
990 Error e -> Left . InternalMsg $
991 "could not reify reflected term " ++
993 " when reflecting an error:" ++ show e
994 OK (tm', _) -> Right $ TermPart tm'
995reifyReportPart (App _ (P (DCon _ _ _) n _) tm)
996 | n == reflm "RawPart" =
997 case runElab initEState (reifyRaw tm) (initElaborator (sMN 0 "hole") internalNS initContext emptyContext 0 Erased) of
998 Error e -> Left . InternalMsg $
999 "could not reify reflected raw term " ++
1001 " when reflecting an error: " ++ show e
1002 OK (tm', _) -> Right $ RawPart tm'
1003reifyReportPart (App _ (P (DCon _ _ _) n _) tm)
1004 | n == reflm "SubReport" =
1006 Just xs -> do subParts <- mapM reifyReportPart xs
1007 Right (SubReport subParts)
1008 Nothing -> Left . InternalMsg $ "could not reify subreport " ++ show tm
1009reifyReportPart x = Left . InternalMsg $ "could not reify " ++ show x
1011reifyErasure :: Term -> ElabD RErasure
1012reifyErasure (P (DCon _ _ _) n _)
1013 | n == tacN "Erased" = return RErased
1014 | n == tacN "NotErased" = return RNotErased
1015reifyErasure tm = fail $ "Can't reify " ++ show tm ++ " as erasure info."
1017reifyPlicity :: Term -> ElabD RPlicity
1018reifyPlicity (P (DCon _ _ _) n _)
1019 | n == tacN "Explicit" = return RExplicit
1020 | n == tacN "Implicit" = return RImplicit
1021 | n == tacN "Constraint" = return RConstraint
1022reifyPlicity tm = fail $ "Couldn't reify " ++ show tm ++ " as RPlicity."
1024reifyRFunArg :: Term -> ElabD RFunArg
1025reifyRFunArg (App _ (App _ (App _ (App _ (P (DCon _ _ _) n _) argN) argTy) argPl) argE)
1026 | n == tacN "MkFunArg" = liftM4 RFunArg
1029 (reifyPlicity argPl)
1031reifyRFunArg aTm = fail $ "Couldn't reify " ++ show aTm ++ " as an RArg."
1033reifyTyDecl :: Term -> ElabD RTyDecl
1034reifyTyDecl (App _ (App _ (App _ (P (DCon _ _ _) n _) tyN) args) ret)
1035 | n == tacN "Declare" =
1036 do tyN' <- reifyTTName tyN
1037 args' <- case unList args of
1038 Nothing -> fail $ "Couldn't reify " ++ show args ++ " as an arglist."
1039 Just xs -> mapM reifyRFunArg xs
1040 ret' <- reifyRaw ret
1041 return $ RDeclare tyN' args' ret'
1042reifyTyDecl tm = fail $ "Couldn't reify " ++ show tm ++ " as a type declaration."
1044reifyFunDefn :: Term -> ElabD (RFunDefn Raw)
1045reifyFunDefn (App _ (App _ (App _ (P _ n _) (P _ t _)) fnN) clauses)
1046 | n == tacN "DefineFun" && t == reflm "Raw" =
1047 do fnN' <- reifyTTName fnN
1048 clauses' <- case unList clauses of
1049 Nothing -> fail $ "Couldn't reify " ++ show clauses ++ " as a clause list"
1050 Just cs -> mapM reifyC cs
1051 return $ RDefineFun fnN' clauses'
1052 where reifyC :: Term -> ElabD (RFunClause Raw)
1053 reifyC (App _ (App _ (App _ (P (DCon _ _ _) n _) (P _ t _)) lhs) rhs)
1054 | n == tacN "MkFunClause" && t == reflm "Raw" = liftM2 RMkFunClause
1057 reifyC (App _ (App _ (P (DCon _ _ _) n _) (P _ t _)) lhs)
1058 | n == tacN "MkImpossibleClause" && t == reflm "Raw" = fmap RMkImpossibleClause $ reifyRaw lhs
1059 reifyC tm = fail $ "Couldn't reify " ++ show tm ++ " as a clause."
1060reifyFunDefn tm = fail $ "Couldn't reify " ++ show tm ++ " as a function declaration."
1062reifyRConstructorDefn :: Term -> ElabD RConstructorDefn
1063reifyRConstructorDefn (App _ (App _ (App _ (P _ n _) cn) args) retTy)
1064 | n == tacN "Constructor", Just args' <- unList args
1065 = RConstructor <$> reifyTTName cn <*> mapM reifyRFunArg args' <*> reifyRaw retTy
1066reifyRConstructorDefn aTm = fail $ "Couldn't reify " ++ show aTm ++ " as an RConstructorDefn"
1068reifyRDataDefn :: Term -> ElabD RDataDefn
1069reifyRDataDefn (App _ (App _ (P _ n _) tyn) ctors)
1070 | n == tacN "DefineDatatype", Just ctors' <- unList ctors
1071 = RDefineDatatype <$> reifyTTName tyn <*> mapM reifyRConstructorDefn ctors'
1072reifyRDataDefn aTm = fail $ "Couldn't reify " ++ show aTm ++ " as an RDataDefn"
1076 = raw_apply (Var pairTy) [ (Var $ reflm "TTName")
1077 , (RApp (Var $ reflm "Binder") (Var $ reflm "TT"))
1080reflectList :: Raw -> [Raw] -> Raw
1081reflectList ty [] = RApp (Var (sNS (sUN "Nil") ["List", "Prelude"])) ty
1082reflectList ty (x:xs) = RApp (RApp (RApp (Var (sNS (sUN "::") ["List", "Prelude"])) ty)
1086-- | Apply Idris's implicit info to get a signature. The [PArg] should
1087-- come from a lookup in idris_implicits on IState.
1088getArgs :: [PArg] -> Raw -> ([RFunArg], Raw)
1089getArgs [] r = ([], r)
1090getArgs (a:as) (RBind n (Pi _ _ ty _) sc) =
1091 let (args, res) = getArgs as sc
1092 erased = if InaccessibleArg `elem` argopts a then RErased else RNotErased
1094 PImp {} -> RFunArg n ty RImplicit erased
1095 PExp {} -> RFunArg n ty RExplicit erased
1096 PConstraint {} -> RFunArg n ty RConstraint erased
1097 PTacImplicit {} -> RFunArg n ty RImplicit erased
1099getArgs _ r = ([], r)
1101unApplyRaw :: Raw -> (Raw, [Raw])
1102unApplyRaw tm = ua [] tm
1104 ua args (RApp f a) = ua (a:args) f
1105 ua args t = (t, args)
1107-- | Build the reflected function definition(s) that correspond(s) to
1108-- a provided unqualified name
1109buildFunDefns :: IState -> Name -> [RFunDefn Term]
1110buildFunDefns ist n =
1111 [ mkFunDefn name clauses
1112 | (name, (clauses, _)) <- lookupCtxtName n $ idris_patdefs ist
1115 where mkFunDefn name clauses = RDefineFun name (map mkFunClause clauses)
1117 mkFunClause ([], lhs, Impossible) = RMkImpossibleClause lhs
1118 mkFunClause ([], lhs, rhs) = RMkFunClause lhs rhs
1119 mkFunClause (((n, ty) : ns), lhs, rhs) = mkFunClause (ns, bind lhs, bind rhs) where
1120 bind Impossible = Impossible
1121 bind tm = Bind n (PVar RigW ty) tm
1123-- | Build the reflected datatype definition(s) that correspond(s) to
1124-- a provided unqualified name
1125buildDatatypes :: IState -> Name -> [RDatatype]
1126buildDatatypes ist n =
1127 catMaybes [ mkDataType dn ti
1128 | (dn, ti) <- lookupCtxtName n datatypes
1130 where datatypes = idris_datatypes ist
1132 impls = idris_implicits ist
1134 ctorSig params cn = do cty <- fmap forget (lookupTyExact cn ctxt)
1135 argInfo <- lookupCtxtExact cn impls
1136 let (args, res) = getArgs argInfo cty
1137 return (cn, ctorArgsStatus args res params, res)
1139 argPos n [] res = findPos n res
1140 where findPos n app = case unApplyRaw app of
1141 (_, argL) -> findIndex (== Var n) argL
1142 argPos n (arg:args) res = if n == argName arg
1144 else argPos n args res
1146 ctorArgsStatus :: [RFunArg] -> Raw -> [Int] -> [RCtorArg]
1147 ctorArgsStatus [] _ _ = []
1148 ctorArgsStatus (arg:args) res params =
1149 case argPos (argName arg) args res of
1150 Nothing -> RCtorField arg : ctorArgsStatus args res params
1151 Just i -> if i `elem` params
1152 then RCtorParameter arg : ctorArgsStatus args res params
1153 else RCtorField arg : ctorArgsStatus args res params
1155 mkDataType name (TI {param_pos = params, con_names = constrs}) =
1156 do (TyDecl (TCon _ _) ty) <- lookupDefExact name ctxt
1157 implInfo <- lookupCtxtExact name impls
1158 let (tcargs, tcres) = getTCArgs params implInfo (forget ty)
1159 ctors <- mapM (ctorSig params) constrs
1160 return $ RDatatype name tcargs tcres ctors
1162 getTCArgs :: [Int] -> [PArg] -> Raw -> ([RTyConArg], Raw)
1163 getTCArgs params implInfo tcTy =
1164 let (args, res) = getArgs implInfo tcTy
1165 in (tcArg args 0, res)
1166 where tcArg [] _ = []
1167 tcArg (arg:args) i | i `elem` params = RParameter arg : tcArg args (i+1)
1168 | otherwise = RIndex arg : tcArg args (i+1)
1171reflectErasure :: RErasure -> Raw
1172reflectErasure RErased = Var (tacN "Erased")
1173reflectErasure RNotErased = Var (tacN "NotErased")
1175reflectPlicity :: RPlicity -> Raw
1176reflectPlicity RExplicit = Var (tacN "Explicit")
1177reflectPlicity RImplicit = Var (tacN "Implicit")
1178reflectPlicity RConstraint = Var (tacN "Constraint")
1180reflectArg :: RFunArg -> Raw
1181reflectArg (RFunArg n ty plic erasure) =
1182 RApp (RApp (RApp (RApp (Var $ tacN "MkFunArg") (reflectName n))
1184 (reflectPlicity plic))
1185 (reflectErasure erasure)
1187reflectCtorArg :: RCtorArg -> Raw
1188reflectCtorArg (RCtorParameter arg) = RApp (Var $ tacN "CtorParameter") (reflectArg arg)
1189reflectCtorArg (RCtorField arg) = RApp (Var $ tacN "CtorField") (reflectArg arg)
1191reflectDatatype :: RDatatype -> Raw
1192reflectDatatype (RDatatype tyn tyConArgs tyConRes constrs) =
1193 raw_apply (Var $ tacN "MkDatatype") [ reflectName tyn
1194 , rawList (Var $ tacN "TyConArg") (map reflectConArg tyConArgs)
1195 , reflectRaw tyConRes
1196 , rawList (rawTripleTy (Var $ reflm "TTName")
1197 (RApp (Var (sNS (sUN "List") ["List", "Prelude"]))
1198 (Var $ tacN "CtorArg"))
1199 (Var $ reflm "Raw"))
1200 [ rawTriple ((Var $ reflm "TTName")
1201 ,(RApp (Var (sNS (sUN "List") ["List", "Prelude"]))
1202 (Var $ tacN "CtorArg"))
1203 ,(Var $ reflm "Raw"))
1205 ,rawList (Var $ tacN "CtorArg")
1206 (map reflectCtorArg cargs)
1208 | (cn, cargs, cty) <- constrs
1211 where reflectConArg (RParameter a) =
1212 RApp (Var $ tacN "TyConParameter") (reflectArg a)
1213 reflectConArg (RIndex a) =
1214 RApp (Var $ tacN "TyConIndex") (reflectArg a)
1216reflectFunClause :: RFunClause Term -> Raw
1217reflectFunClause (RMkFunClause lhs rhs) = raw_apply (Var $ tacN "MkFunClause")
1218 $ (Var $ reflm "TT") : map reflect [ lhs, rhs ]
1220reflectFunClause (RMkImpossibleClause lhs) = raw_apply (Var $ tacN "MkImpossibleClause")
1221 [ Var $ reflm "TT", reflect lhs ]
1223reflectFunDefn :: RFunDefn Term -> Raw
1224reflectFunDefn (RDefineFun name clauses) = raw_apply (Var $ tacN "DefineFun")
1227 , rawList (RApp (Var $ tacN "FunClause")
1229 (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