1{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, DeriveFunctor,
2 TypeSynonymInstances, PatternGuards #-}
4module Idris.AbsSyntax where
11import Control.Monad.State
16import qualified Epic.Epic as E
18data IOption = IOption { opt_logLevel :: Int,
24defaultOpts = IOption 0 False False
26-- TODO: Add 'module data' to IState, which can be saved out and reloaded quickly (i.e
27-- without typechecking).
28-- This will include all the functions and data declarations, plus fixity declarations
31data IState = IState { tt_ctxt :: Context,
32 idris_constraints :: [(UConstraint, FC)],
33 idris_infixes :: [FixDecl],
34 idris_implicits :: Ctxt [PArg],
35 idris_statics :: Ctxt [Bool],
36 idris_classes :: Ctxt ClassInfo,
38 idris_options :: IOption,
40 idris_metavars :: [Name],
41 syntax_rules :: [Syntax],
42 syntax_keywords :: [String],
43 imported :: [FilePath],
44 idris_prims :: [(Name, ([E.Name], E.Term))],
45 idris_objs :: [FilePath],
46 idris_libs :: [String],
47 idris_hdrs :: [String],
48 last_proof :: Maybe (Name, [String]),
52idrisInit = IState initContext [] [] emptyContext emptyContext emptyContext
53 "" defaultOpts 6 [] [] [] [] [] [] [] [] Nothing Nothing
55-- The monad for the main REPL - reading and processing files and updating
56-- global state (hence the IO inner monad).
57type Idris a = StateT IState IO a
59getContext :: Idris Context
60getContext = do i <- get; return (tt_ctxt i)
62getObjectFiles :: Idris [FilePath]
63getObjectFiles = do i <- get; return (idris_objs i)
65addObjectFile :: FilePath -> Idris ()
66addObjectFile f = do i <- get; put (i { idris_objs = f : idris_objs i })
68getLibs :: Idris [String]
69getLibs = do i <- get; return (idris_libs i)
71addLib :: String -> Idris ()
72addLib f = do i <- get; put (i { idris_libs = f : idris_libs i })
74addHdr :: String -> Idris ()
75addHdr f = do i <- get; put (i { idris_hdrs = f : idris_hdrs i })
77getHdrs :: Idris [String]
78getHdrs = do i <- get; return (idris_hdrs i)
80setErrLine :: Int -> Idris ()
81setErrLine x = do i <- get;
83 Nothing -> put (i { errLine = Just x })
88 put (i { errLine = Nothing })
90getIState :: Idris IState
93putIState :: IState -> Idris ()
98 let idx = idris_name i;
99 put (i { idris_name = idx + 1 })
102checkUndefined :: FC -> Name -> Idris ()
105 case lookupTy Nothing n i of
106 (_:_) -> fail $ show fc ++ ":" ++
107 show n ++ " already defined"
110setContext :: Context -> Idris ()
111setContext ctxt = do i <- get; put (i { tt_ctxt = ctxt } )
113updateContext :: (Context -> Context) -> Idris ()
114updateContext f = do i <- get; put (i { tt_ctxt = f (tt_ctxt i) } )
116addConstraints :: FC -> (Int, [UConstraint]) -> Idris ()
117addConstraints fc (v, cs)
120 let ctxt' = ctxt { uconstraints = cs ++ uconstraints ctxt,
122 let ics = zip cs (repeat fc) ++ idris_constraints i
123 put (i { tt_ctxt = ctxt', idris_constraints = ics })
125addDeferred :: [(Name, Type)] -> Idris ()
126addDeferred ns = do mapM_ (\(n, t) -> updateContext (addTyDecl n (tidyNames [] t))) ns
128 put (i { idris_metavars = map fst ns ++ idris_metavars i })
129 where tidyNames used (Bind (MN i x) b sc)
130 = let n' = uniqueName (UN x) used in
131 Bind n' b $ tidyNames (n':used) sc
132 tidyNames used (Bind n b sc)
133 = let n' = uniqueName n used in
134 Bind n' b $ tidyNames (n':used) sc
137solveDeferred :: Name -> Idris ()
138solveDeferred n = do i <- get
139 put (i { idris_metavars = idris_metavars i \\ [n] })
141iputStrLn :: String -> Idris ()
142iputStrLn = lift.putStrLn
144iWarn :: FC -> String -> Idris ()
145iWarn fc err = do lift $ putStrLn (show fc ++ ":" ++ err)
147setLogLevel :: Int -> Idris ()
148setLogLevel l = do i <- get
149 let opts = idris_options i
150 let opt' = opts { opt_logLevel = l }
151 put (i { idris_options = opt' } )
154logLevel = do i <- get
155 return (opt_logLevel (idris_options i))
159 return (opt_showimp (idris_options i))
161setImpShow :: Bool -> Idris ()
162setImpShow t = do i <- get
163 let opts = idris_options i
164 let opt' = opts { opt_showimp = t }
165 put (i { idris_options = opt' })
167logLvl :: Int -> String -> Idris ()
168logLvl l str = do i <- get
169 let lvl = opt_logLevel (idris_options i)
171 $ do lift (putStrLn str)
172 put (i { idris_log = idris_log i ++ str ++ "\n" } )
174iLOG :: String -> Idris ()
177noErrors :: Idris Bool
178noErrors = do i <- get
180 Nothing -> return True
183setTypeCase :: Bool -> Idris ()
184setTypeCase t = do i <- get
185 let opts = idris_options i
186 let opt' = opts { opt_typecase = t }
187 put (i { idris_options = opt' })
189-- Commands in the REPL
191data Command = Quit | Help | Eval PTerm | Check PTerm | Reload | Edit
192 | Compile String | Execute String
193 | Metavars | Prove Name | AddProof | Universes
195 | LogLvl Int | Spec PTerm | HNF PTerm | Defn Name
198-- Parsed declarations
200data Fixity = Infixl { prec :: Int }
201 | Infixr { prec :: Int }
202 | InfixN { prec :: Int }
203 | PrefixN { prec :: Int }
206instance Show Fixity where
207 show (Infixl i) = "infixl " ++ show i
208 show (Infixr i) = "infixr " ++ show i
209 show (InfixN i) = "infix " ++ show i
210 show (PrefixN i) = "prefix " ++ show i
212data FixDecl = Fix Fixity String
215instance Ord FixDecl where
216 compare (Fix x _) (Fix y _) = compare (prec x) (prec y)
219data Static = Static | Dynamic
222-- Mark bindings with their explicitness, and laziness
223data Plicity = Imp { plazy :: Bool,
225 | Exp { plazy :: Bool,
227 | Constraint { plazy :: Bool,
231impl = Imp False Dynamic
232expl = Exp False Dynamic
233constraint = Constraint False Static
235type FnOpts = Bool -- just inlinable, for now
237inlinable :: FnOpts -> Bool
240data PDecl' t = PFix FC Fixity [String] -- fixity declaration
241 | PTy SyntaxInfo FC Name t -- type declaration
242 | PClauses FC FnOpts Name [PClause' t] -- pattern clause
243 | PData SyntaxInfo FC (PData' t) -- data declaration
244 | PParams FC [(Name, t)] [PDecl' t] -- params block
245 | PNamespace String [PDecl' t] -- new namespace
246 | PClass SyntaxInfo FC
249 [(Name, t)] -- parameters
250 [PDecl' t] -- declarations
251 | PInstance SyntaxInfo FC [t] -- constraints
254 t -- full instance type
257 | PDirective (Idris ())
260data PClause' t = PClause Name t [t] t [PDecl' t]
261 | PWith Name t [t] t [PDecl' t]
264data PData' t = PDatadecl { d_name :: Name,
266 d_cons :: [(Name, t, FC)] }
269-- Handy to get a free function for applying PTerm -> PTerm functions
270-- across a program, by deriving Functor
272type PDecl = PDecl' PTerm
273type PData = PData' PTerm
274type PClause = PClause' PTerm
276-- get all the names declared in a decl
278declared :: PDecl -> [Name]
279declared (PFix _ _ _) = []
280declared (PTy _ _ n t) = [n]
281declared (PClauses _ _ n _) = [] -- not a declaration
282declared (PData _ _ (PDatadecl n _ ts)) = n : map fstt ts
283 where fstt (a, _, _) = a
284declared (PParams _ _ ds) = concatMap declared ds
285declared (PNamespace _ ds) = concatMap declared ds
286-- declared (PImport _) = []
288updateN :: [(Name, Name)] -> Name -> Name
289updateN ns n | Just n' <- lookup n ns = n'
292updateNs :: [(Name, Name)] -> PTerm -> PTerm
294updateNs ns t = mapPT updateRef t
295 where updateRef (PRef fc f) = PRef fc (updateN ns f)
298-- updateDNs :: [(Name, Name)] -> PDecl -> PDecl
300-- updateDNs ns (PTy s f n t) | Just n' <- lookup n ns = PTy s f n' t
301-- updateDNs ns (PClauses f n c) | Just n' <- lookup n ns = PClauses f n' (map updateCNs c)
302-- where updateCNs ns (PClause n l ts r ds)
303-- = PClause (updateN ns n) (fmap (updateNs ns) l)
304-- (map (fmap (updateNs ns)) ts)
305-- (fmap (updateNs ns) r)
306-- (map (updateDNs ns) ds)
309-- High level language terms
311data PTerm = PQuote Raw
313 | PLam Name PTerm PTerm
314 | PPi Plicity Name PTerm PTerm
315 | PLet Name PTerm PTerm PTerm
316 | PApp FC PTerm [PArg]
322 | PPair FC PTerm PTerm
323 | PDPair FC PTerm PTerm PTerm
324 | PAlternative [PTerm]
325 | PHidden PTerm -- irrelevant or hidden pattern
333 | PTactics [PTactic] -- as PProof, but no auto solving
334 | PElabError String -- error to report on elaboration
337mapPT :: (PTerm -> PTerm) -> PTerm -> PTerm
338mapPT f t = f (mpt t) where
339 mpt (PLam n t s) = PLam n (mapPT f t) (mapPT f s)
340 mpt (PPi p n t s) = PPi p n (mapPT f t) (mapPT f s)
341 mpt (PLet n ty v s) = PLet n (mapPT f ty) (mapPT f v) (mapPT f s)
342 mpt (PApp fc t as) = PApp fc (mapPT f t) (map (fmap (mapPT f)) as)
343 mpt (PEq fc l r) = PEq fc (mapPT f l) (mapPT f r)
344 mpt (PPair fc l r) = PPair fc (mapPT f l) (mapPT f r)
345 mpt (PDPair fc l t r) = PDPair fc (mapPT f l) (mapPT f t) (mapPT f r)
346 mpt (PAlternative as) = PAlternative (map (mapPT f) as)
347 mpt (PHidden t) = PHidden (mapPT f t)
348 mpt (PDoBlock ds) = PDoBlock (map (fmap (mapPT f)) ds)
349 mpt (PProof ts) = PProof (map (fmap (mapPT f)) ts)
350 mpt (PTactics ts) = PTactics (map (fmap (mapPT f)) ts)
354data PTactic' t = Intro [Name] | Focus Name
355 | Refine Name [Bool] | Rewrite t | LetTac Name t
356 | Exact t | Compute | Trivial
359 | ProofState | ProofTerm | Undo
360 | Try (PTactic' t) (PTactic' t)
361 | TSeq (PTactic' t) (PTactic' t)
363 deriving (Show, Eq, Functor)
365type PTactic = PTactic' PTerm
367data PDo' t = DoExp FC t
370 deriving (Eq, Functor)
374-- The priority gives a hint as to elaboration order. Best to elaborate
375-- things early which will help give a more concrete type to other
376-- variables, e.g. a before (interpTy a).
378data PArg' t = PImp { priority :: Int,
379 lazyarg :: Bool, pname :: Name, getTm :: t }
380 | PExp { priority :: Int,
381 lazyarg :: Bool, getTm :: t }
382 | PConstraint { priority :: Int,
383 lazyarg :: Bool, getTm :: t }
384 deriving (Show, Eq, Functor)
388pconst = PConstraint 0 False
390type PArg = PArg' PTerm
394data ClassInfo = CI { instanceName :: Name,
395 class_methods :: [(Name, PTerm)],
396 class_defaults :: [(Name, Name)], -- method name -> default impl
397 class_params :: [Name] }
400-- Syntactic sugar info
402data DSL = DSL { dsl_bind :: Name,
406data SynContext = PatternSyntax | TermSyntax | AnySyntax
409data Syntax = Rule [SSymbol] PTerm SynContext
412data SSymbol = Keyword Name
417initDSL = DSL (UN ">>=") (UN "return")
419data SyntaxInfo = Syn { using :: [(Name, PTerm)],
420 syn_params :: [(Name, PTerm)],
421 syn_namespace :: [String],
423 decoration :: Name -> Name,
428defaultSyntax = Syn [] [] [] [] id False initDSL
430--- Pretty printing declarations and terms
432instance Show PTerm where
433 show tm = showImp False tm
435instance Show PDecl where
436 show (PFix _ f ops) = show f ++ " " ++ showSep ", " ops
437 show (PTy _ _ n ty) = show n ++ " : " ++ show ty
438 show (PClauses _ _ n c) = showSep "\n" (map show c)
439 show (PData _ _ d) = show d
441instance Show PClause where
442 show c = showCImp True c
444instance Show PData where
445 show d = showDImp False d
447showCImp :: Bool -> PClause -> String
448showCImp impl (PClause n l ws r w)
449 = showImp impl l ++ showWs ws ++ " = " ++ showImp impl r
450 ++ " where " ++ show w
453 showWs (x : xs) = " | " ++ showImp impl x ++ showWs xs
454showCImp impl (PWith n l ws r w)
455 = showImp impl l ++ showWs ws ++ " with " ++ showImp impl r
456 ++ " { " ++ show w ++ " } "
459 showWs (x : xs) = " | " ++ showImp impl x ++ showWs xs
462showDImp :: Bool -> PData -> String
463showDImp impl (PDatadecl n ty cons)
464 = "data " ++ show n ++ " : " ++ showImp impl ty ++ " where\n\t"
466 (map (\ (n, t, _) -> show n ++ " : " ++ showImp impl t) cons)
468getImps :: [PArg] -> [(Name, PTerm)]
470getImps (PImp _ _ n tm : xs) = (n, tm) : getImps xs
471getImps (_ : xs) = getImps xs
473getExps :: [PArg] -> [PTerm]
475getExps (PExp _ _ tm : xs) = tm : getExps xs
476getExps (_ : xs) = getExps xs
478getConsts :: [PArg] -> [PTerm]
480getConsts (PConstraint _ _ tm : xs) = tm : getConsts xs
481getConsts (_ : xs) = getConsts xs
483getAll :: [PArg] -> [PTerm]
486showImp :: Bool -> PTerm -> String
487showImp impl tm = se 10 tm where
488 se p (PQuote r) = "![" ++ show r ++ "]"
489 se p (PRef _ n) = show n
490 se p (PLam n ty sc) = bracket p 2 $ "\\ " ++ show n ++ " => " ++ show sc
491 se p (PLet n ty v sc) = bracket p 2 $ "let " ++ show n ++ " = " ++ se 10 v ++
493 se p (PPi (Exp l s) n ty sc)
494 | n `elem` allNamesIn sc = bracket p 2 $
495 if l then "|(" else "(" ++
496 show n ++ " : " ++ se 10 ty ++
499 | otherwise = bracket p 2 $ se 0 ty ++ " " ++ st ++ "-> " ++ se 10 sc
501 Static -> "[static] "
503 se p (PPi (Imp l s) n ty sc)
504 | impl = bracket p 2 $ if l then "|{" else "{" ++
505 show n ++ " : " ++ se 10 ty ++
506 "} " ++ st ++ "-> " ++ se 10 sc
507 | otherwise = se 10 sc
509 Static -> "[static] "
511 se p (PPi (Constraint _ _) n ty sc)
512 = bracket p 2 $ se 10 ty ++ " => " ++ se 10 sc
513 se p (PApp _ (PRef _ f) [])
515 se p (PApp _ (PRef _ op@(UN (f:_))) args)
516 | length (getExps args) == 2 && not impl && not (isAlpha f)
517 = let [l, r] = getExps args in
518 bracket p 1 $ se 1 l ++ " " ++ show op ++ " " ++ se 0 r
520 = let args = getExps as in
521 bracket p 1 $ se 1 f ++ if impl then concatMap sArg as
522 else concatMap seArg args
523 se p (PHidden tm) = "." ++ se 0 tm
524 se p (PRefl _) = "refl"
525 se p (PResolveTC _) = "resolvetc"
526 se p (PTrue _) = "()"
527 se p (PFalse _) = "_|_"
528 se p (PEq _ l r) = bracket p 2 $ se 10 l ++ " = " ++ se 10 r
529 se p (PPair _ l r) = "(" ++ se 10 l ++ ", " ++ se 10 r ++ ")"
530 se p (PDPair _ l t r) = "(" ++ se 10 l ++ " ** " ++ se 10 r ++ ")"
531 se p (PAlternative as) = "(|" ++ showSep " , " (map (se 10) as) ++ "|)"
533 se p (PConstant c) = show c
534 se p (PProof ts) = "proof { " ++ show ts ++ "}"
535 se p (PTactics ts) = "tactics { " ++ show ts ++ "}"
536 se p (PMetavar n) = "?" ++ show n
537 se p Placeholder = "_"
539 sArg (PImp _ _ n tm) = siArg (n, tm)
540 sArg (PExp _ _ tm) = seArg tm
541 sArg (PConstraint _ _ tm) = scArg tm
543 seArg arg = " " ++ se 0 arg
544 siArg (n, val) = " {" ++ show n ++ " = " ++ se 10 val ++ "}"
545 scArg val = " {{" ++ se 10 val ++ "}}"
547 bracket outer inner str | inner > outer = "(" ++ str ++ ")"
550allNamesIn :: PTerm -> [Name]
551allNamesIn tm = nub $ ni [] tm
554 | not (n `elem` env) = [n]
555 ni env (PApp _ f as) = ni env f ++ concatMap (ni env) (map getTm as)
556 ni env (PLam n ty sc) = ni env ty ++ ni (n:env) sc
557 ni env (PPi _ n ty sc) = ni env ty ++ ni (n:env) sc
558 ni env (PHidden tm) = ni env tm
559 ni env (PEq _ l r) = ni env l ++ ni env r
560 ni env (PPair _ l r) = ni env l ++ ni env r
561 ni env (PDPair _ (PRef _ n) t r) = ni env t ++ ni (n:env) r
562 ni env (PDPair _ l t r) = ni env l ++ ni env t ++ ni env r
563 ni env (PAlternative ls) = concatMap (ni env) ls
566namesIn :: IState -> PTerm -> [Name]
567namesIn ist tm = nub $ ni [] tm
571 = case lookupTy Nothing n (tt_ctxt ist) of
574 ni env (PApp _ f as) = ni env f ++ concatMap (ni env) (map getTm as)
575 ni env (PLam n ty sc) = ni env ty ++ ni (n:env) sc
576 ni env (PPi _ n ty sc) = ni env ty ++ ni (n:env) sc
577 ni env (PEq _ l r) = ni env l ++ ni env r
578 ni env (PPair _ l r) = ni env l ++ ni env r
579 ni env (PDPair _ (PRef _ n) t r) = ni env t ++ ni (n:env) r
580 ni env (PDPair _ l t r) = ni env l ++ ni env t ++ ni env r
581 ni env (PAlternative as) = concatMap (ni env) as
582 ni env (PHidden tm) = ni env tm
585-- For inferring types of things
589inferTy = MN 0 "__Infer"
590inferCon = MN 0 "__infer"
591inferDecl = PDatadecl inferTy
593 [(inferCon, PPi impl (MN 0 "A") PSet (
594 PPi expl (MN 0 "a") (PRef bi (MN 0 "A"))
595 (PRef bi inferTy)), bi)]
597infTerm t = PApp bi (PRef bi inferCon) [pimp (MN 0 "A") Placeholder, pexp t]
598infP = P (TCon 6 0) inferTy (Set (UVal 0))
600getInferTerm, getInferType :: Term -> Term
601getInferTerm (Bind n b sc) = Bind n b $ getInferTerm sc
602getInferTerm (App (App _ _) tm) = tm
603getInferTerm tm = error ("getInferTerm " ++ show tm)
605getInferType (Bind n b sc) = Bind n b $ getInferType sc
606getInferType (App (App _ ty) _) = ty
608-- Handy primitives: Unit, False, Pair, MkPair, =, mkForeign
610primNames = [unitTy, unitCon,
611 falseTy, pairTy, pairCon,
612 eqTy, eqCon, inferTy, inferCon]
614unitTy = MN 0 "__Unit"
616unitDecl = PDatadecl unitTy PSet
617 [(unitCon, PRef bi unitTy, bi)]
619falseTy = MN 0 "__False"
620falseDecl = PDatadecl falseTy PSet []
622pairTy = MN 0 "__Pair"
623pairCon = MN 0 "__MkPair"
624pairDecl = PDatadecl pairTy (piBind [(n "A", PSet), (n "B", PSet)] PSet)
625 [(pairCon, PPi impl (n "A") PSet (
626 PPi impl (n "B") PSet (
627 PPi expl (n "a") (PRef bi (n "A")) (
628 PPi expl (n "b") (PRef bi (n "B"))
629 (PApp bi (PRef bi pairTy) [pexp (PRef bi (n "A")),
630 pexp (PRef bi (n "B"))])))), bi)]
635eqDecl = PDatadecl eqTy (piBind [(n "a", PSet), (n "b", PSet),
636 (n "x", PRef bi (n "a")), (n "y", PRef bi (n "b"))]
638 [(eqCon, PPi impl (n "a") PSet (
639 PPi impl (n "x") (PRef bi (n "a"))
640 (PApp bi (PRef bi eqTy) [pimp (n "a") Placeholder,
641 pimp (n "b") Placeholder,
642 pexp (PRef bi (n "x")),
643 pexp (PRef bi (n "x"))])), bi)]
646-- Defined in builtins.idr
648existsCon = UN "Ex_intro"
650piBind :: [(Name, PTerm)] -> PTerm -> PTerm
652piBind ((n, ty):ns) t = PPi expl n ty (piBind ns t)
654-- Dealing with parameters
656expandParams :: (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PTerm -> PTerm
657expandParams dec ps ns tm = en tm
659 en (PLam n t s) = PLam n (en t) (en s)
660 en (PPi p n t s) = PPi p n (en t) (en s)
661 en (PLet n ty v s) = PLet n (en ty) (en v) (en s)
662 en (PEq f l r) = PEq f (en l) (en r)
663 en (PPair f l r) = PPair f (en l) (en r)
664 en (PDPair f l t r) = PDPair f (en l) (en t) (en r)
665 en (PAlternative as) = PAlternative (map en as)
666 en (PHidden t) = PHidden (en t)
667 en (PDoBlock ds) = PDoBlock (map (fmap en) ds)
668 en (PProof ts) = PProof (map (fmap en) ts)
669 en (PTactics ts) = PTactics (map (fmap en) ts)
672 | n `elem` ns = PQuote (Var (dec n))
673 en (PApp fc (PRef fc' n) as)
674 | n `elem` ns = PApp fc (PRef fc' (dec n))
675 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
677 | n `elem` ns = PApp fc (PRef fc (dec n))
678 (map (pexp . (PRef fc)) (map fst ps))
679 en (PApp fc f as) = PApp fc (en f) (map (fmap en) as)
682expandParamsD :: IState ->
683 (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PDecl -> PDecl
684expandParamsD ist dec ps ns (PTy syn fc n ty)
686 then PTy syn fc (dec n) (piBind ps (expandParams dec ps ns ty))
687 else PTy syn fc n (expandParams dec ps ns ty)
688expandParamsD ist dec ps ns (PClauses fc opts n cs)
689 = let n' = if n `elem` ns then dec n else n in
690 PClauses fc opts n' (map expandParamsC cs)
692 expandParamsC (PClause n lhs ws rhs ds)
693 = let -- ps' = updateps True (namesIn ist rhs) (zip ps [0..])
694 ps'' = updateps False (namesIn ist lhs) (zip ps [0..])
695 n' = if n `elem` ns then dec n else n in
696 PClause n' (expandParams dec ps'' ns lhs)
697 (map (expandParams dec ps'' ns) ws)
698 (expandParams dec ps'' ns rhs)
699 (map (expandParamsD ist dec ps'' ns) ds)
700 expandParamsC (PWith n lhs ws wval ds)
701 = let -- ps' = updateps True (namesIn ist wval) (zip ps [0..])
702 ps'' = updateps False (namesIn ist lhs) (zip ps [0..])
703 n' = if n `elem` ns then dec n else n in
704 PWith n' (expandParams dec ps'' ns lhs)
705 (map (expandParams dec ps'' ns) ws)
706 (expandParams dec ps'' ns wval)
707 (map (expandParamsD ist dec ps'' ns) ds)
708 updateps yn nm [] = []
709 updateps yn nm (((a, t), i):as)
710 | (a `elem` nm) == yn = (a, t) : updateps yn nm as
711 | otherwise = (MN i (show n ++ "_u"), t) : updateps yn nm as
713expandParamsD ist dec ps ns d = d
715-- Calculate a priority for a type, for deciding elaboration order
716-- * if it's just a type variable or concrete type, do it early (0)
717-- * if there's only type variables and injective constructors, do it next (1)
718-- * if there's a function type, next (2)
719-- * finally, everything else (3)
721getPriority :: IState -> PTerm -> Int
722getPriority i tm = pri tm
725 case lookupP Nothing n (tt_ctxt i) of
726 ((P (DCon _ _) _ _):_) -> 1
727 ((P (TCon _ _) _ _):_) -> 1
729 [] -> 0 -- must be locally bound, if it's not an error...
730 pri (PPi _ _ x y) = max 4 (max (pri x) (pri y))
734 pri (PEq _ l r) = max 1 (max (pri l) (pri r))
735 pri (PApp _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.getTm) as)))
736 pri (PPair _ l r) = max 1 (max (pri l) (pri r))
737 pri (PDPair _ l t r) = max 1 (max (pri l) (max (pri t) (pri r)))
738 pri (PAlternative as) = maximum (map pri as)
739 pri (PConstant _) = 0
743-- Dealing with implicit arguments
745-- Add implicit Pi bindings for any names in the term which appear in an
748-- This has become a right mess already. Better redo it some time...
750implicit :: SyntaxInfo -> Name -> PTerm -> Idris PTerm
753 let (tm', impdata) = implicitise syn i ptm
754 let (tm'', spos) = findStatics i tm'
755 put (i { idris_implicits = addDef n impdata (idris_implicits i) })
756 logLvl 5 ("Implicit " ++ show n ++ " " ++ show impdata)
758 put (i { idris_statics = addDef n spos (idris_statics i) })
761implicitise :: SyntaxInfo -> IState -> PTerm -> (PTerm, [PArg])
762implicitise syn ist tm
763 = let uvars = using syn
764 pvars = syn_params syn
765 (declimps, ns') = execState (imps True [] tm) ([], [])
766 ns = ns' \\ (map fst pvars ++ no_imp syn) in
768 then (tm, reverse declimps)
769 else implicitise syn ist (pibind uvars ns tm)
771 dropAll (x:xs) ys | x `elem` ys = dropAll xs ys
772 | otherwise = x : dropAll xs ys
775 imps top env (PApp _ f as)
776 = do (decls, ns) <- get
777 let isn = concatMap (namesIn ist) (map getTm as)
778 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
779 imps top env (PPi (Imp l _) n ty sc)
780 = do let isn = nub (namesIn ist ty) `dropAll` [n]
782 put (PImp (getPriority ist ty) l n ty : decls,
783 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
785 imps top env (PPi (Exp l _) n ty sc)
786 = do let isn = nub (namesIn ist ty ++ case sc of
787 (PRef _ x) -> namesIn ist sc `dropAll` [n]
789 (decls, ns) <- get -- ignore decls in HO types
790 put (PExp (getPriority ist ty) l ty : decls,
791 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
793 imps top env (PPi (Constraint l _) n ty sc)
794 = do let isn = nub (namesIn ist ty ++ case sc of
795 (PRef _ x) -> namesIn ist sc `dropAll` [n]
797 (decls, ns) <- get -- ignore decls in HO types
798 put (PConstraint 10 l ty : decls,
799 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
801 imps top env (PEq _ l r)
802 = do (decls, ns) <- get
803 let isn = namesIn ist l ++ namesIn ist r
804 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
805 imps top env (PPair _ l r)
806 = do (decls, ns) <- get
807 let isn = namesIn ist l ++ namesIn ist r
808 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
809 imps top env (PDPair _ (PRef _ n) t r)
810 = do (decls, ns) <- get
811 let isn = nub (namesIn ist t ++ namesIn ist r) \\ [n]
812 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
813 imps top env (PDPair _ l t r)
814 = do (decls, ns) <- get
815 let isn = namesIn ist l ++ namesIn ist t ++ namesIn ist r
816 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
817 imps top env (PAlternative as)
818 = do (decls, ns) <- get
819 let isn = concatMap (namesIn ist) as
820 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
821 imps top env (PLam n ty sc)
822 = do imps False env ty
823 imps False (n:env) sc
824 imps top env (PHidden tm) = imps False env tm
825 imps top env _ = return ()
827 pibind using [] sc = sc
828 pibind using (n:ns) sc
829 = case lookup n using of
830 Just ty -> PPi (Imp False Dynamic) n ty (pibind using ns sc)
831 Nothing -> PPi (Imp False Dynamic) n Placeholder (pibind using ns sc)
833-- Add implicit arguments in function calls
835addImpl :: IState -> PTerm -> PTerm
836addImpl ist ptm = ai [] ptm
838 ai env (PRef fc f) = aiFn ist fc f []
839 ai env (PEq fc l r) = let l' = ai env l
842 ai env (PPair fc l r) = let l' = ai env l
845 ai env (PDPair fc l t r) = let l' = ai env l
849 ai env (PAlternative as) = let as' = map (ai env) as in
851 ai env (PApp fc (PRef _ f) as)
852 = let as' = map (fmap (ai env)) as in
854 ai env (PApp fc f as) = let f' = ai env f
855 as' = map (fmap (ai env)) as in
857 ai env (PLam n ty sc) = let ty' = ai env ty
858 sc' = ai (n:env) sc in
860 ai env (PLet n ty val sc)
861 = let ty' = ai env ty
863 sc' = ai (n:env) sc in
865 ai env (PPi p n ty sc) = let ty' = ai env ty
866 sc' = ai (n:env) sc in
868 ai env (PHidden tm) = PHidden (ai env tm)
869 ai env (PProof ts) = PProof (map (fmap (ai env)) ts)
870 ai env (PTactics ts) = PTactics (map (fmap (ai env)) ts)
873aiFn :: IState -> FC -> Name -> [PArg] -> PTerm
875 | f `elem` primNames = PApp fc (PRef fc f) as
877 -- This is where namespaces get resolved by adding PAlternative
878 = case lookupCtxtName Nothing f (idris_implicits ist) of
879 [(f',ns)] -> mkPApp fc (length ns) (PRef fc f') (insertImpl ns as)
880 [] -> mkPApp fc 1 (PRef fc f) as
881 alts -> PAlternative $
882 map (\(f', ns) -> mkPApp fc (length ns) (PRef fc f')
883 (insertImpl ns as)) alts
885 insertImpl :: [PArg] -> [PArg] -> [PArg]
886 insertImpl (PExp p l ty : ps) (PExp _ _ tm : given) =
887 PExp p l tm : insertImpl ps given
888 insertImpl (PConstraint p l ty : ps) (PConstraint _ _ tm : given) =
889 PConstraint p l tm : insertImpl ps given
890 insertImpl (PConstraint p l ty : ps) given =
891 PConstraint p l (PResolveTC fc) : insertImpl ps given
892 insertImpl (PImp p l n ty : ps) given =
893 case find n given [] of
894 Just (tm, given') -> PImp p l n tm : insertImpl ps given'
895 Nothing -> PImp p l n Placeholder : insertImpl ps given
896 insertImpl expected [] = []
897 insertImpl _ given = given
899 find n [] acc = Nothing
900 find n (PImp _ _ n' t : gs) acc
901 | n == n' = Just (t, reverse acc ++ gs)
902 find n (g : gs) acc = find n gs (g : acc)
905mkPApp fc a f as = let rest = drop a as in
906 appRest fc (PApp fc f (take a as)) rest
909 appRest fc f (a : as) = appRest fc (PApp fc f [a]) as
911-- Find 'static' argument positions
912-- (the declared ones, plus any names in argument position in the declared
914-- FIXME: It's possible that this really has to happen after elaboration
916findStatics :: IState -> PTerm -> (PTerm, [Bool])
917findStatics ist tm = let (ns, ss) = fs tm in
918 runState (pos ns ss tm) []
919 where fs (PPi p n t sc)
920 | Static <- pstatic p
921 = let (ns, ss) = fs sc in
922 (namesIn ist t : ns, namesIn ist t ++ n : ss)
923 | otherwise = let (ns, ss) = fs sc in
924 (namesIn ist t : ns, ss)
927 inOne n ns = length (filter id (map (elem n) ns)) == 1
929 pos ns ss (PPi p n t sc)
930 | n `inOne` ns && elem n ss
931 = do sc' <- pos ns ss sc
934 return (PPi (p { pstatic = Static }) n t sc')
935 | otherwise = do sc' <- pos ns ss sc
938 return (PPi p n t sc')
939 pos ns ss t = return t
941-- Debugging/logging stuff
943dumpDecls :: [PDecl] -> String
945dumpDecls (d:ds) = dumpDecl d ++ "\n" ++ dumpDecls ds
947dumpDecl (PFix _ f ops) = show f ++ " " ++ showSep ", " ops
948dumpDecl (PTy _ _ n t) = "tydecl " ++ show n ++ " : " ++ showImp True t
949dumpDecl (PClauses _ _ n cs) = "pat " ++ show n ++ "\t" ++ showSep "\n\t" (map (showCImp True) cs)
950dumpDecl (PData _ _ d) = showDImp True d
951dumpDecl (PParams _ ns ps) = "params {" ++ show ns ++ "\n" ++ dumpDecls ps ++ "}\n"
952dumpDecl (PNamespace n ps) = "namespace {" ++ n ++ "\n" ++ dumpDecls ps ++ "}\n"
953dumpDecl (PSyntax _ syn) = "syntax " ++ show syn
954dumpDecl (PClass _ _ cs n ps ds)
955 = "class " ++ show cs ++ " " ++ show n ++ " " ++ show ps ++ "\n" ++ dumpDecls ds
956dumpDecl (PInstance _ _ cs n _ t ds)
957 = "instance " ++ show cs ++ " " ++ show n ++ " " ++ show t ++ "\n" ++ dumpDecls ds
959-- dumpDecl (PImport i) = "import " ++ i
961-- syntactic match of a against b, returning pair of variables in a
962-- and what they match. Returns 'Nothing' if not a match.
964matchClause :: PTerm -> PTerm -> Maybe [(Name, PTerm)]
965matchClause x y = match x y where
966 matchArg x y = match (getTm x) (getTm y)
968 match (PApp _ f args) (PApp _ f' args')
969 | length args == length args'
970 = do mf <- match f f'
971 ms <- zipWithM matchArg args args'
972 return (mf ++ concat ms)
973-- match (PRef _ n) (PRef _ n') | n == n' = return []
974-- | otherwise = Nothing
975 match (PRef _ n) tm = return [(n, tm)]
976 match (PEq _ l r) (PEq _ l' r') = do ml <- match l l'
979 match (PPair _ l r) (PPair _ l' r') = do ml <- match l l'
982 match (PDPair _ l t r) (PDPair _ l' t' r') = do ml <- match l l'
985 return (ml ++ mt ++ mr)
986 match (PAlternative as) (PAlternative as')
987 = do ms <- zipWithM match as as'
989 match (PRefl _) (PRefl _) = return []
990 match (PResolveTC _) (PResolveTC _) = return []
991 match (PTrue _) (PTrue _) = return []
992 match (PFalse _) (PFalse _) = return []
993 match (PReturn _) (PReturn _) = return []
994 match (PPi _ _ t s) (PPi _ _ t' s') = do mt <- match t t'
997 match (PLam _ t s) (PLam _ t' s') = do mt <- match t t'
1000 match (PHidden x) (PHidden y) = match x y
1001 match a b | a == b = return []
1002 | otherwise = Nothing
1004substMatches :: [(Name, PTerm)] -> PTerm -> PTerm
1005substMatches [] t = t
1006substMatches ((n,tm):ns) t = substMatch n tm (substMatches ns t)
1008substMatch :: Name -> PTerm -> PTerm -> PTerm
1009substMatch n tm t = sm t where
1010 sm (PRef _ n') | n == n' = tm
1011 sm (PLam x t sc) = PLam x (sm t) (sm sc)
1012 sm (PPi p x t sc) = PPi p x (sm t) (sm sc)
1013 sm (PApp f x as) = PApp f (sm x) (map (fmap sm) as)
1014 sm (PEq f x y) = PEq f (sm x) (sm y)
1015 sm (PPair f x y) = PPair f (sm x) (sm y)
1016 sm (PDPair f x t y) = PDPair f (sm x) (sm t) (sm y)
1017 sm (PAlternative as) = PAlternative (map sm as)
1018 sm (PHidden x) = PHidden (sm x)
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