@@ -6,37 +6,44 @@ quoters and unquoters along with some supporting datatypes.
6module Idris.Reflection where
6module Idris.Reflection where
8import Control.Applicative ((<$>), (<*>), pure)
8import Control.Applicative ((<$>), (<*>), pure)
9−import Control.Monad (liftM, liftM2)
9+import Control.Monad (liftM, liftM2, liftM3)
10import Data.Maybe (catMaybes)
10import Data.Maybe (catMaybes)
11import Data.List ((\\))
11import Data.List ((\\))
12import qualified Data.Text as T
12import qualified Data.Text as T
14import Idris.Core.Elaborate (claim, fill, focus, getNameFrom, initElaborator,
14import Idris.Core.Elaborate (claim, fill, focus, getNameFrom, initElaborator,
15 movelast, runElab, solve)
15 movelast, runElab, solve)
16−import Idris.Core.Evaluate (Context, Def(TyDecl), initContext, lookupDefExact, lookupTyExact)
16+import Idris.Core.Evaluate (Def(TyDecl), initContext, lookupDefExact, lookupTyExact)
17import Idris.Core.TT
17import Idris.Core.TT
19+import Idris.AbsSyntaxTree (ArgOpt(..),ElabD, IState(tt_ctxt, idris_implicits,idris_datatypes),
19−import Idris.AbsSyntaxTree (ElabD, IState, PArg'(..), PArg, PTactic, PTactic'(..),
20+ PArg'(..), PArg, PTactic, PTactic'(..), PTerm(..),
20− PTerm(..), initEState, pairCon, pairTy)
21+ initEState, pairCon, pairTy)
21import Idris.Delaborate (delab)
22import Idris.Delaborate (delab)
24+data RErasure = RErased | RNotErased deriving Show
23−data RArg = RExplicit { argName :: Name, argTy :: Raw }
26+data RArg = RExplicit { argName :: Name, argErased :: RErasure, argTy :: Raw }
24− | RImplicit { argName :: Name, argTy :: Raw }
27+ | RImplicit { argName :: Name, argErased :: RErasure, argTy :: Raw }
25− | RConstraint { argName :: Name, argTy :: Raw }
28+ | RConstraint { argName :: Name, argErased :: RErasure, argTy :: Raw }
26 deriving Show
29 deriving Show
28data RTyDecl = RDeclare Name [RArg] Raw deriving Show
31data RTyDecl = RDeclare Name [RArg] Raw deriving Show
30−data RTyConArg = RParameter { tcArgName :: Name, tcArgTy :: Raw }
33+data RTyConArg = RParameter { tcArgName :: Name, tcArgErased :: RErasure, tcArgTy :: Raw }
31− | RIndex { tcArgName :: Name, tcArgTy :: Raw }
34+ | RIndex { tcArgName :: Name, tcArgErased :: RErasure, tcArgTy :: Raw }
32 deriving Show
35 deriving Show
34−data RDatatype = RDatatype Name [RTyConArg] Raw [(Name, Raw)] deriving Show
37+data RDatatype = RDatatype Name [RTyConArg] Raw [(Name, [RArg], Raw)] deriving Show
39+rArgOpts :: RErasure -> [ArgOpt]
40+rArgOpts RErased = [InaccessibleArg]
36rArgToPArg :: RArg -> PArg
43rArgToPArg :: RArg -> PArg
37−rArgToPArg (RExplicit n _) = PExp 0 [] n Placeholder
44+rArgToPArg (RExplicit n e _) = PExp 0 (rArgOpts e) n Placeholder
38−rArgToPArg (RImplicit n _) = PImp 0 False [] n Placeholder
45+rArgToPArg (RImplicit n e _) = PImp 0 False (rArgOpts e) n Placeholder
39−rArgToPArg (RConstraint n _) = PConstraint 0 [] n Placeholder
46+rArgToPArg (RConstraint n e _) = PConstraint 0 (rArgOpts e) n Placeholder
41data RFunClause = RMkFunClause Raw Raw
48data RFunClause = RMkFunClause Raw Raw
42 | RMkImpossibleClause Raw
49 | RMkImpossibleClause Raw
@@ -154,8 +161,16 @@ reifyTTApp t [t', Constant (I i)]
154 return $ Proj t'' i
161 return $ Proj t'' i
155reifyTTApp t [tt]
162reifyTTApp t [tt]
156 | t == reflm "TType" = liftM TType (reifyTTUExp tt)
163 | t == reflm "TType" = liftM TType (reifyTTUExp tt)
165+ | t == reflm "UType" = liftM UType (reifyUniverse tt)
157reifyTTApp t args = fail ("Unknown reflection term: " ++ show (t, args))
166reifyTTApp t args = fail ("Unknown reflection term: " ++ show (t, args))
168+reifyUniverse :: Term -> ElabD Universe
169+reifyUniverse (P _ n _) | n == reflm "AllTypes" = return AllTypes
170+ | n == reflm "UniqueType" = return UniqueType
171+ | n == reflm "NullType" = return NullType
172+reifyUniverse tm = fail ("Unknown reflection universe: " ++ show tm)
159-- | Reify raw terms from their reflected representation
174-- | Reify raw terms from their reflected representation
160reifyRaw :: Term -> ElabD Raw
175reifyRaw :: Term -> ElabD Raw
161reifyRaw t@(App _ _ _)
176reifyRaw t@(App _ _ _)
@@ -780,6 +795,13 @@ rawPairTy t1 t2 = raw_apply (Var pairTy) [t1, t2]
780rawPair :: (Raw, Raw) -> (Raw, Raw) -> Raw
795rawPair :: (Raw, Raw) -> (Raw, Raw) -> Raw
781rawPair (a, b) (x, y) = raw_apply (Var pairCon) [a, b, x, y]
796rawPair (a, b) (x, y) = raw_apply (Var pairCon) [a, b, x, y]
798+-- | Idris tuples nest to the right
799+rawTripleTy :: Raw -> Raw -> Raw -> Raw
800+rawTripleTy a b c = rawPairTy a (rawPairTy b c)
802+rawTriple :: (Raw, Raw, Raw) -> (Raw, Raw, Raw) -> Raw
803+rawTriple (a, b, c) (x, y, z) = rawPair (a, rawPairTy b c) (x, rawPair (b, c) (y, z))
783reflectCtxt :: [(Name, Type)] -> Raw
805reflectCtxt :: [(Name, Type)] -> Raw
784reflectCtxt ctxt = rawList (rawPairTy (Var $ reflm "TTName") (Var $ reflm "TT"))
806reflectCtxt ctxt = rawList (rawPairTy (Var $ reflm "TTName") (Var $ reflm "TT"))
785 (map (\ (n, t) -> (rawPair (Var $ reflm "TTName", Var $ reflm "TT")
807 (map (\ (n, t) -> (rawPair (Var $ reflm "TTName", Var $ reflm "TT")
@@ -929,6 +951,12 @@ reifyReportPart (App _ (P (DCon _ _ _) n _) tm)
929 Nothing -> Left . InternalMsg $ "could not reify subreport " ++ show tm
951 Nothing -> Left . InternalMsg $ "could not reify subreport " ++ show tm
930reifyReportPart x = Left . InternalMsg $ "could not reify " ++ show x
952reifyReportPart x = Left . InternalMsg $ "could not reify " ++ show x
954+reifyErasure :: Term -> ElabD RErasure
955+reifyErasure (P (DCon _ _ _) n _)
956+ | n == tacN "Erased" = return RErased
957+ | n == tacN "NotErased" = return RNotErased
958+reifyErasure tm = fail $ "Can't reify " ++ show tm ++ " as erasure info."
932reifyTyDecl :: Term -> ElabD RTyDecl
960reifyTyDecl :: Term -> ElabD RTyDecl
933reifyTyDecl (App _ (App _ (App _ (P (DCon _ _ _) n _) tyN) args) ret)
961reifyTyDecl (App _ (App _ (App _ (P (DCon _ _ _) n _) tyN) args) ret)
934 | n == tacN "Declare" =
962 | n == tacN "Declare" =
@@ -939,14 +967,17 @@ reifyTyDecl (App _ (App _ (App _ (P (DCon _ _ _) n _) tyN) args) ret)
939 ret' <- reifyRaw ret
967 ret' <- reifyRaw ret
940 return $ RDeclare tyN' args' ret'
968 return $ RDeclare tyN' args' ret'
941 where reifyRArg :: Term -> ElabD RArg
969 where reifyRArg :: Term -> ElabD RArg
942− reifyRArg (App _ (App _ (P (DCon _ _ _) n _) argN) argTy)
970+ reifyRArg (App _ (App _ (App _ (P (DCon _ _ _) n _) argN) argE) argTy)
943− | n == tacN "Explicit" = liftM2 RExplicit
971+ | n == tacN "Explicit" = liftM3 RExplicit
944 (reifyTTName argN)
972 (reifyTTName argN)
945 (reifyRaw argTy)
974 (reifyRaw argTy)
946− | n == tacN "Implicit" = liftM2 RImplicit
975+ | n == tacN "Implicit" = liftM3 RImplicit
947 (reifyTTName argN)
976 (reifyTTName argN)
948− (reifyRaw argTy) | n == tacN "Constraint" = liftM2 RConstraint
978+ (reifyRaw argTy) | n == tacN "Constraint" = liftM3 RConstraint
949 (reifyTTName argN)
979 (reifyTTName argN)
950 (reifyRaw argTy)
981 (reifyRaw argTy)
951 reifyRArg aTm = fail $ "Couldn't reify " ++ show aTm ++ " as an RArg."
982 reifyRArg aTm = fail $ "Couldn't reify " ++ show aTm ++ " as an RArg."
952reifyTyDecl tm = fail $ "Couldn't reify " ++ show tm ++ " as a type declaration."
983reifyTyDecl tm = fail $ "Couldn't reify " ++ show tm ++ " as a type declaration."
@@ -975,38 +1006,89 @@ envTupleType
975 , (RApp (Var $ reflm "Binder") (Var $ reflm "TT"))
1006 , (RApp (Var $ reflm "Binder") (Var $ reflm "TT"))
1009+-- | Apply Idris's implicit info to get a signature. The [PArg] should
1010+-- come from a lookup in idris_implicits on IState.
1011+getArgs :: [PArg] -> Raw -> ([RArg], Raw)
1012+getArgs [] r = ([], r)
1013+getArgs (a:as) (RBind n (Pi _ ty _) sc) =
1014+ let (args, res) = getArgs as sc
1015+ erased = if InaccessibleArg `elem` argopts a then RErased else RNotErased
1017+ PImp {} -> RImplicit n erased ty
1018+ PExp {} -> RExplicit n erased ty
1019+ PConstraint {} -> RConstraint n erased ty
1020+ PTacImplicit {} -> RImplicit n erased ty -- TODO?
1021+ in (arg':args, res)
1022+getArgs _ r = ([], r)
978-- | Build the reflected datatype definition(s) that correspond(s) to
1024-- | Build the reflected datatype definition(s) that correspond(s) to
979-- a provided unqualified name
1025-- a provided unqualified name
980−buildDatatypes :: Context -> Ctxt TypeInfo -> Name -> [RDatatype]
1026+buildDatatypes :: IState -> Name -> [RDatatype]
981−buildDatatypes ctxt datatypes n =
1027+buildDatatypes ist n =
982 catMaybes [ mkDataType dn ti
1028 catMaybes [ mkDataType dn ti
983 | (dn, ti) <- lookupCtxtName n datatypes
1029 | (dn, ti) <- lookupCtxtName n datatypes
985− where mkDataType name (TI {param_pos = params, con_names = constrs}) =
1031+ where datatypes = idris_datatypes ist
986− do (TyDecl (TCon _ _) ty) <- lookupDefExact name ctxt
1032+ ctxt = tt_ctxt ist
987− let (tcargs, tcres) = getArgs params (forget ty) 0
1033+ impls = idris_implicits ist
988− conTys <- mapM (fmap forget . flip lookupTyExact ctxt) constrs
989− return $ RDatatype name tcargs tcres $ zip constrs conTys
1035+ ctorSig cn = do cty <- fmap forget (lookupTyExact cn ctxt)
1036+ argInfo <- lookupCtxtExact cn impls
1037+ let (args, res) = getArgs argInfo cty
1038+ return (cn, args, res)
1040+ mkDataType name (TI {param_pos = params, con_names = constrs}) =
1041+ do (TyDecl (TCon _ _) ty) <- lookupDefExact name ctxt
1042+ implInfo <- lookupCtxtExact name impls
1043+ let (tcargs, tcres) = getTCArgs params implInfo (forget ty) 0
1044+ ctors <- mapM ctorSig constrs
1045+ return $ RDatatype name tcargs tcres ctors
991− getArgs params (RBind an (Pi _ ty _) body) i =
1047+ getTCArgs params implInfo (RBind an (Pi _ ty _) body) i =
1048+ let (erased, implInfo') = case implInfo of
1049+ [] -> (RNotErased, [])
1050+ (a:as) -> (if InaccessibleArg `elem` argopts a
992− let (args, res) = getArgs params body (i+1)
1054+ (args, res) = getTCArgs params implInfo' body (i+1)
993 in if i `elem` params
1055 in if i `elem` params
994− then (RParameter an ty : args, res )
1056+ then (RParameter an erased ty : args, res )
995− else (RIndex an ty : args, res)
1057+ else (RIndex an erased ty : args, res)
996− getArgs _ tm _ = ([], tm)
1058+ getTCArgs _ implInfo tm _ = ([], tm)
1060+reflectErasure :: RErasure -> Raw
1061+reflectErasure RErased = Var (tacN "Erased")
1062+reflectErasure RNotErased = Var (tacN "NotErased")
1064+reflectArg :: RArg -> Raw
1066+ RApp (RApp (RApp (Var con) (reflectName $ argName arg))
1067+ (reflectErasure $ argErased arg))
1068+ (reflectRaw $ argTy arg)
1069+ where con = case arg of
1070+ RExplicit{} -> tacN "Explicit"
1071+ RImplicit{} -> tacN "Implicit"
1072+ RConstraint{} -> tacN "Constraint"
998reflectDatatype :: RDatatype -> Raw
1074reflectDatatype :: RDatatype -> Raw
999reflectDatatype (RDatatype tyn tyConArgs tyConRes constrs) =
1075reflectDatatype (RDatatype tyn tyConArgs tyConRes constrs) =
1000 raw_apply (Var $ tacN "MkDatatype") [ reflectName tyn
1076 raw_apply (Var $ tacN "MkDatatype") [ reflectName tyn
1001 , rawList (Var $ tacN "TyConArg") (map reflectConArg tyConArgs)
1077 , rawList (Var $ tacN "TyConArg") (map reflectConArg tyConArgs)
1002 , reflectRaw tyConRes
1078 , reflectRaw tyConRes
1003− , rawList (rawPairTy (Var $ reflm "TTName") (Var $ reflm "Raw"))
1079+ , rawList (rawTripleTy (Var $ reflm "TTName")
1080+ (RApp (Var (sNS (sUN "List") ["List", "Prelude"])) (Var $ tacN "Arg"))
1081+ (Var $ reflm "Raw"))
1082+ [ rawTriple ((Var $ reflm "TTName"),
1083+ (RApp (Var (sNS (sUN "List") ["List", "Prelude"])) (Var $ tacN "Arg")),
1004− [ rawPair ((Var $ reflm "TTName"), (Var $ reflm "Raw"))
1084+ (Var $ reflm "Raw"))
1005− (reflectName cn, reflectRaw cty)
1085+ (reflectName cn,
1086+ rawList (Var $ tacN "Arg") (map reflectArg cargs),
1006− | (cn, cty) <- constrs
1088+ | (cn, cargs, cty) <- constrs
1009− where reflectConArg (RParameter n t) =
1091+ where reflectConArg (RParameter n e t) =
1010− raw_apply (Var $ tacN "Parameter") [reflectName n, reflectRaw t]
1092+ raw_apply (Var $ tacN "Parameter") [reflectName n, reflectErasure e, reflectRaw t]
1011− reflectConArg (RIndex n t) =
1093+ reflectConArg (RIndex n e t) =
1012− raw_apply (Var $ tacN "Index") [reflectName n, reflectRaw t]
1094+ raw_apply (Var $ tacN "Index") [reflectName n, reflectErasure e, reflectRaw t]