on master help sign in
Reflection for SN, plus an SN for meta-stuff
commit3592edbde0db06143d32330c388d6cb7bcde884b authorDavid Raymond Christiansen <david@davidchristiansen.dk> dateWed 22 Apr 2015, 15:15 (12 years ago) parentc56dee3
5 files changed+170−32
libs/prelude/Language/Reflection.idr+71−25 src/Idris/Core/Binary.hs+6 src/Idris/Core/DeepSeq.hs+1 src/Idris/Core/TT.hs+34−7 src/Idris/Reflection.hs+58
libs/prelude/Language/Reflection.idr+71−25
@@ -11,18 +11,35 @@ import Prelude.Traversable
1111
1212%access public
1313
14−data TTName =
15− ||| A user-provided name
16− UN String |
17− ||| A name in some namespace.
18− |||
19− ||| The namespace is in reverse order, so `(NS (UN "foo") ["B", "A"])` represents the name `A.B.foo`
20− NS TTName (List String) |
21− ||| Machine-chosen names
22− MN Int String |
23− ||| Name of something which is never used in scope
24− NErased
25−%name TTName n, n'
14+mutual
15+ data TTName =
16+ ||| A user-provided name
17+ UN String |
18+ ||| A name in some namespace.
19+ |||
20+ ||| The namespace is in reverse order, so `(NS (UN "foo") ["B", "A"])`
21+ ||| represents the name `A.B.foo`
22+ NS TTName (List String) |
23+ ||| Machine-chosen names
24+ MN Int String |
25+ ||| Special names, to make conflicts impossible and language features
26+ ||| predictable
27+ SN SpecialName |
28+ ||| Name of something which is never used in scope
29+ NErased
30+ %name TTName n, n'
31+
32+ data SpecialName = WhereN Int TTName TTName
33+ | WithN Int TTName
34+ | InstanceN TTName (List String)
35+ | ParentN TTName String
36+ | MethodN TTName
37+ | CaseN TTName
38+ | ElimN TTName
39+ | InstanceCtorN TTName
40+ | MetaN TTName TTName
41+
42+
2643
2744implicit
2845userSuppliedName : String -> TTName
@@ -390,19 +407,48 @@ instance Quotable a Raw => Quotable (List a) Raw where
390407 quote [] = `(List.Nil {a=~(quotedTy {a})})
391408 quote (x :: xs) = `(List.(::) {a=~(quotedTy {a})} ~(quote x) ~(quote xs))
392409
393−instance Quotable TTName TT where
394− quotedTy = `(TTName)
395− quote (UN x) = `(UN ~(quote x))
396− quote (NS n xs) = `(NS ~(quote n) ~(quote xs))
397− quote (MN x y) = `(MN ~(quote x) ~(quote y))
398− quote NErased = `(NErased)
399−
400−instance Quotable TTName Raw where
401− quotedTy = `(TTName)
402− quote (UN x) = `(UN ~(quote {t=Raw} x))
403− quote (NS n xs) = `(NS ~(quote {t=Raw} n) ~(quote {t=Raw} xs))
404− quote (MN x y) = `(MN ~(quote {t=Raw} x) ~(quote {t=Raw} y))
405− quote NErased = `(NErased)
410+mutual
411+ instance Quotable TTName TT where
412+ quotedTy = `(TTName)
413+ quote (UN x) = `(UN ~(quote x))
414+ quote (NS n xs) = `(NS ~(quote n) ~(quote xs))
415+ quote (MN x y) = `(MN ~(quote x) ~(quote y))
416+ quote (SN sn) = `(SN ~(assert_total $ quote sn))
417+ quote NErased = `(NErased)
418+
419+ instance Quotable SpecialName TT where
420+ quotedTy = `(SpecialName)
421+ quote (WhereN i n1 n2) = `(WhereN ~(quote i) ~(quote n1) ~(quote n2))
422+ quote (WithN i n) = `(WithN ~(quote i) ~(quote n))
423+ quote (InstanceN i ss) = `(InstanceN ~(quote i) ~(quote ss))
424+ quote (ParentN n s) = `(ParentN ~(quote n) ~(quote s))
425+ quote (MethodN n) = `(MethodN ~(quote n))
426+ quote (CaseN n) = `(CaseN ~(quote n))
427+ quote (ElimN n) = `(ElimN ~(quote n))
428+ quote (InstanceCtorN n) = `(InstanceCtorN ~(quote n))
429+ quote (MetaN parent meta) = `(MetaN ~(quote parent) ~(quote meta))
430+
431+mutual
432+ instance Quotable TTName Raw where
433+ quotedTy = `(TTName)
434+ quote (UN x) = `(UN ~(quote {t=Raw} x))
435+ quote (NS n xs) = `(NS ~(quote {t=Raw} n) ~(quote {t=Raw} xs))
436+ quote (MN x y) = `(MN ~(quote {t=Raw} x) ~(quote {t=Raw} y))
437+ quote (SN sn) = `(SN ~(assert_total $ quote sn))
438+ quote NErased = `(NErased)
439+
440+ instance Quotable SpecialName Raw where
441+ quotedTy = `(SpecialName)
442+ quote (WhereN i n1 n2) = `(WhereN ~(quote i) ~(quote n1) ~(quote n2))
443+ quote (WithN i n) = `(WithN ~(quote i) ~(quote n))
444+ quote (InstanceN i ss) = `(InstanceN ~(quote i) ~(quote ss))
445+ quote (ParentN n s) = `(ParentN ~(quote n) ~(quote s))
446+ quote (MethodN n) = `(MethodN ~(quote n))
447+ quote (CaseN n) = `(CaseN ~(quote n))
448+ quote (ElimN n) = `(ElimN ~(quote n))
449+ quote (InstanceCtorN n) = `(InstanceCtorN ~(quote n))
450+ quote (MetaN parent meta) = `(MetaN ~(quote parent) ~(quote meta))
451+
406452
407453instance Quotable NativeTy TT where
408454 quotedTy = `(NativeTy)
src/Idris/Core/Binary.hs+6
@@ -292,6 +292,9 @@ instance Binary SpecialName where
292292 WithN x1 x2 -> do putWord8 7
293293 put x1
294294 put x2
295+ MetaN x1 x2 -> do putWord8 8
296+ put x1
297+ put x2
295298 get
296299 = do i <- getWord8
297300 case i of
@@ -316,6 +319,9 @@ instance Binary SpecialName where
316319 7 -> do x1 <- get
317320 x2 <- get
318321 return (WithN x1 x2)
322+ 8 -> do x1 <- get
323+ x2 <- get
324+ return (MetaN x1 x2)
319325 _ -> error "Corrupted binary data for SpecialName"
320326
321327
src/Idris/Core/DeepSeq.hs+1
@@ -25,6 +25,7 @@ instance NFData SpecialName where
2525 rnf (CaseN x1) = rnf x1 `seq` ()
2626 rnf (ElimN x1) = rnf x1 `seq` ()
2727 rnf (InstanceCtorN x1) = rnf x1 `seq` ()
28+ rnf (MetaN x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
2829
2930instance NFData Universe where
3031 rnf NullType = ()
src/Idris/Core/TT.hs+34−7
@@ -1,5 +1,5 @@
11{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, DeriveFunctor, DeriveDataTypeable #-}
2−
2+{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
33{-| TT is the core language of Idris. The language has:
44
55 * Full dependent types
@@ -366,6 +366,7 @@ data SpecialName = WhereN Int Name Name
366366 | CaseN Name
367367 | ElimN Name
368368 | InstanceCtorN Name
369+ | MetaN Name Name
369370 deriving (Eq, Ord, Data, Typeable)
370371{-!
371372deriving instance Binary SpecialName
@@ -390,6 +391,9 @@ instance Pretty Name OutputAnnotation where
390391 pretty n@(MN i s) = annotate (AnnName n Nothing Nothing Nothing) $
391392 lbrace <+> text (T.unpack s) <+> (text . show $ i) <+> rbrace
392393 pretty n@(SN s) = annotate (AnnName n Nothing Nothing Nothing) $ text (show s)
394+ pretty n@(SymRef i) = annotate (AnnName n Nothing Nothing Nothing) $
395+ text $ "##symbol" ++ show i ++ "##"
396+ pretty NErased = annotate (AnnName NErased Nothing Nothing Nothing) $ text "_"
393397
394398instance Pretty [Name] OutputAnnotation where
395399 pretty = encloseSep empty empty comma . map pretty
@@ -400,6 +404,7 @@ instance Show Name where
400404 show (MN _ u) | u == txt "underscore" = "_"
401405 show (MN i s) = "{" ++ str s ++ show i ++ "}"
402406 show (SN s) = show s
407+ show (SymRef i) = "##symbol" ++ show i ++ "##"
403408 show NErased = "_"
404409
405410instance Show SpecialName where
@@ -411,6 +416,7 @@ instance Show SpecialName where
411416 show (CaseN n) = "case block in " ++ show n
412417 show (ElimN n) = "<<" ++ show n ++ " eliminator>>"
413418 show (InstanceCtorN n) = "constructor of " ++ show n
419+ show (MetaN parent meta) = "<<" ++ show parent ++ " " ++ show meta ++ ">>"
414420
415421-- Show a name in a way decorated for code generation, not human reading
416422showCG :: Name -> String
@@ -427,6 +433,8 @@ showCG (SN s) = showCG' s
427433 showCG' (CaseN c) = showCG c ++ "_case"
428434 showCG' (ElimN sn) = showCG sn ++ "_elim"
429435 showCG' (InstanceCtorN n) = showCG n ++ "_ictor"
436+ showCG' (MetaN parent meta) = showCG parent ++ "_meta_" ++ showCG meta
437+showCG (SymRef i) = error "can't do codegen for a symbol reference"
430438showCG NErased = "_"
431439
432440
@@ -861,6 +869,9 @@ instance TermSize (TT Name) where
861869 termsize n (Proj t i) = termsize n t
862870 termsize n _ = 1
863871
872+instance Sized Universe where
873+ size u = 1
874+
864875instance Sized a => Sized (TT a) where
865876 size (P name n trm) = 1 + size name + size n + size trm
866877 size (V v) = 1
@@ -869,6 +880,9 @@ instance Sized a => Sized (TT a) where
869880 size (Constant c) = size c
870881 size Erased = 1
871882 size (TType u) = 1 + size u
883+ size (Proj a _) = 1 + size a
884+ size Impossible = 1
885+ size (UType u) = 1 + size u
872886
873887instance Pretty a o => Pretty (TT a) o where
874888 pretty _ = text "test"
@@ -952,7 +966,7 @@ instantiate e = subst 0 where
952966-- that has been substituted.
953967substV :: TT n -> TT n -> TT n
954968substV x tm = dropV 0 (instantiate x tm) where
955− subst i (P nt x ty) = P nt x (subst i ty)
969+ dropV i (P nt x ty) = P nt x (dropV i ty)
956970 dropV i (V x) | x > i = V (x - 1)
957971 | otherwise = V x
958972 dropV i (Bind x b sc) = Bind x (fmap (dropV i) b) (dropV (i+1) sc)
@@ -1186,23 +1200,25 @@ forgetEnv env tm = case safeForgetEnv env tm of
11861200safeForgetEnv :: [Name] -> TT Name -> Maybe Raw
11871201safeForgetEnv env (P _ n _) = Just $ Var n
11881202safeForgetEnv env (V i) | i < length env = Just $ Var (env !! i)
1189− | otherwise = Nothing
1190−safeForgetEnv env (Bind n b sc)
1203+ | otherwise = Nothing
1204+safeForgetEnv env (Bind n b sc)
11911205 = do let n' = uniqueName n env
11921206 b' <- safeForgetEnvB env b
11931207 sc' <- safeForgetEnv (n':env) sc
11941208 Just $ RBind n' b' sc'
1195− where safeForgetEnvB env (Let t v) = liftM2 Let (safeForgetEnv env t)
1209+ where safeForgetEnvB env (Let t v) = liftM2 Let (safeForgetEnv env t)
11961210 (safeForgetEnv env v)
1197− safeForgetEnvB env (Guess t v) = liftM2 Guess (safeForgetEnv env t)
1211+ safeForgetEnvB env (Guess t v) = liftM2 Guess (safeForgetEnv env t)
11981212 (safeForgetEnv env v)
11991213 safeForgetEnvB env b = do ty' <- safeForgetEnv env (binderTy b)
1200− Just $ fmap (\_ -> ty') b
1214+ Just $ fmap (\_ -> ty') b
12011215safeForgetEnv env (App _ f a) = liftM2 RApp (safeForgetEnv env f) (safeForgetEnv env a)
12021216safeForgetEnv env (Constant c) = Just $ RConstant c
12031217safeForgetEnv env (TType i) = Just RType
12041218safeForgetEnv env (UType u) = Just $ RUType u
12051219safeForgetEnv env Erased = Just $ RConstant Forgot
1220+safeForgetEnv env (Proj tm i) = error "Don't know how to forget a projection"
1221+safeForgetEnv env Impossible = error "Don't know how to forget Impossible"
12061222
12071223-- | Introduce a 'Bind' into the given term for each element of the
12081224-- given list of (name, binder) pairs.
@@ -1255,6 +1271,7 @@ uniqueBinders ns = ubSet (fromList ns) where
12551271 ubSet ns t = t
12561272
12571273
1274+nextName :: Name -> Name
12581275nextName (NS x s) = NS (nextName x) s
12591276nextName (MN i n) = MN (i+1) n
12601277nextName (UN x) = let (num', nm') = T.span isDigit (T.reverse x)
@@ -1274,6 +1291,9 @@ nextName (SN x) = SN (nextName' x)
12741291 nextName' (ElimN n) = ElimN (nextName n)
12751292 nextName' (MethodN n) = MethodN (nextName n)
12761293 nextName' (InstanceCtorN n) = InstanceCtorN (nextName n)
1294+ nextName' (MetaN parent meta) = MetaN parent (nextName meta)
1295+nextName NErased = NErased
1296+nextName (SymRef i) = error "Can't generate a name from a symbol reference"
12771297
12781298type Term = TT Name
12791299type Type = Term
@@ -1313,11 +1333,13 @@ instance Show Const where
13131333 show WorldType = "prim__WorldType"
13141334 show StrType = "String"
13151335 show VoidType = "Void"
1336+ show Forgot = "Forgot"
13161337
13171338showEnv :: (Eq n, Show n) => EnvTT n -> TT n -> String
13181339showEnv env t = showEnv' env t False
13191340showEnvDbg env t = showEnv' env t True
13201341
1342+prettyEnv :: Env -> Term -> Doc OutputAnnotation
13211343prettyEnv env t = prettyEnv' env t False
13221344 where
13231345 prettyEnv' env t dbg = prettySe 10 env t dbg
@@ -1351,14 +1373,18 @@ prettyEnv env t = prettyEnv' env t False
13511373 prettySe p env (Constant c) debug = pretty c
13521374 prettySe p env Erased debug = text "[_]"
13531375 prettySe p env (TType i) debug = text "Type" <+> (text . show $ i)
1376+ prettySe p env Impossible debug = text "Impossible"
1377+ prettySe p env (UType u) debug = text (show u)
13541378
13551379 -- Render a `Binder` and its name
13561380 prettySb env n (Lam t) = prettyB env "λ" "=>" n t
13571381 prettySb env n (Hole t) = prettyB env "?defer" "." n t
1382+ prettySb env n (GHole _ t) = prettyB env "?gdefer" "." n t
13581383 prettySb env n (Pi _ t _) = prettyB env "(" ") ->" n t
13591384 prettySb env n (PVar t) = prettyB env "pat" "." n t
13601385 prettySb env n (PVTy t) = prettyB env "pty" "." n t
13611386 prettySb env n (Let t v) = prettyBv env "let" "in" n t v
1387+ prettySb env n (NLet t v) = prettyBv env "nlet" "in" n t v
13621388 prettySb env n (Guess t v) = prettyBv env "??" "in" n t v
13631389
13641390 -- Use `op` and `sc` to delimit `n` (a binding name) and its type
@@ -1404,6 +1430,7 @@ showEnv' env t dbg = se 10 env t where
14041430 sb env n (PVar t) = showb env "pat " ". " n t
14051431 sb env n (PVTy t) = showb env "pty " ". " n t
14061432 sb env n (Let t v) = showbv env "let " " in " n t v
1433+ sb env n (NLet t v) = showbv env "nlet " " in " n t v
14071434 sb env n (Guess t v) = showbv env "?? " " in " n t v
14081435
14091436 showb env op sc n t = op ++ show n ++ " : " ++ se 10 env t ++ sc
src/Idris/Reflection.hs+58
@@ -5,6 +5,7 @@ quoters and unquoters along with some supporting datatypes.
55{-# OPTIONS_GHC -fwarn-incomplete-patterns -fwarn-unused-imports #-}
66module Idris.Reflection where
77
8+import Control.Applicative ((<$>), (<*>), pure)
89import Control.Monad (liftM, liftM2)
910import Data.Maybe (catMaybes)
1011import Data.List ((\\))
@@ -193,6 +194,39 @@ reifyTTNameApp t [n, ns]
193194 return $ sNS n' ns'
194195reifyTTNameApp t [Constant (I i), Constant (Str n)]
195196 | t == reflm "MN" = return $ sMN i n
197+reifyTTNameApp t [sn]
198+ | t == reflm "SN"
199+ , (P _ f _, args) <- unApply sn = SN <$> reifySN f args
200+ where reifySN :: Name -> [Term] -> ElabD SpecialName
201+ reifySN t [Constant (I i), n1, n2]
202+ | t == reflm "WhereN" = WhereN i <$> reifyTTName n1 <*> reifyTTName n2
203+ reifySN t [Constant (I i), n]
204+ | t == reflm "WithN" = WithN i <$> reifyTTName n
205+ reifySN t [n, ss]
206+ | t == reflm "InstanceN" =
207+ case unList ss of
208+ Nothing -> fail "Can't reify InstanceN strings"
209+ Just ss' -> InstanceN <$> reifyTTName n <*>
210+ pure [T.pack s | Constant (Str s) <- ss']
211+ reifySN t [n, Constant (Str s)]
212+ | t == reflm "ParentN" =
213+ ParentN <$> reifyTTName n <*> pure (T.pack s)
214+ reifySN t [n]
215+ | t == reflm "MethodN" =
216+ MethodN <$> reifyTTName n
217+ reifySN t [n]
218+ | t == reflm "CaseN" =
219+ CaseN <$> reifyTTName n
220+ reifySN t [n]
221+ | t == reflm "ElimN" =
222+ ElimN <$> reifyTTName n
223+ reifySN t [n]
224+ | t == reflm "InstanceCtorN" =
225+ InstanceCtorN <$> reifyTTName n
226+ reifySN t [n1, n2]
227+ | t == reflm "MetaN" =
228+ MetaN <$> reifyTTName n1 <*> reifyTTName n2
229+ reifySN t args = fail $ "Can't reify special name " ++ show t ++ show args
196230reifyTTNameApp t []
197231 | t == reflm "NErased" = return NErased
198232reifyTTNameApp t args = fail ("Unknown reflection term name: " ++ show (t, args))
@@ -600,6 +634,30 @@ reflectName (MN i n)
600634reflectName (NErased) = Var (reflm "NErased")
601635reflectName n = Var (reflm "NErased") -- special name, not yet implemented
602636
637+reflectSpecialName :: SpecialName -> Raw
638+reflectSpecialName (WhereN i n1 n2) =
639+ reflCall "WhereN" [RConstant (I i), reflectName n1, reflectName n2]
640+reflectSpecialName (WithN i n) = reflCall "WithN" [ RConstant (I i)
641+ , reflectName n
642+ ]
643+reflectSpecialName (InstanceN inst ss) =
644+ reflCall "InstanceN" [ reflectName inst
645+ , mkList (RConstant StrType) $
646+ map (RConstant . Str . T.unpack) ss
647+ ]
648+reflectSpecialName (ParentN n s) =
649+ reflCall "ParentN" [reflectName n, RConstant (Str (T.unpack s))]
650+reflectSpecialName (MethodN n) =
651+ reflCall "MethodN" [reflectName n]
652+reflectSpecialName (CaseN n) =
653+ reflCall "CaseN" [reflectName n]
654+reflectSpecialName (ElimN n) =
655+ reflCall "ElimN" [reflectName n]
656+reflectSpecialName (InstanceCtorN n) =
657+ reflCall "InstanceCtorN" [reflectName n]
658+reflectSpecialName (MetaN parent meta) =
659+ reflCall "MetaN" [reflectName parent, reflectName meta]
660+
603661-- | Elaborate a name to a pattern. This means that NS and UN will be intact.
604662-- MNs corresponding to will care about the string but not the number. All
605663-- others become _.