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,
23defaultOpts = IOption 0 False
25-- TODO: Add 'module data' to IState, which can be saved out and reloaded quickly (i.e
26-- without typechecking).
27-- This will include all the functions and data declarations, plus fixity declarations
30data IState = IState { tt_ctxt :: Context,
31 idris_infixes :: [FixDecl],
32 idris_implicits :: Ctxt [PArg],
33 idris_statics :: Ctxt [Bool],
34 idris_classes :: Ctxt ClassInfo,
36 idris_options :: IOption,
38 idris_metavars :: [Name],
39 syntax_rules :: [Syntax],
40 syntax_keywords :: [String],
41 imported :: [FilePath],
42 idris_prims :: [(Name, ([E.Name], E.Term))],
43 idris_objs :: [FilePath],
44 idris_libs :: [String],
48idrisInit = IState emptyContext [] emptyContext emptyContext emptyContext
49 "" defaultOpts 6 [] [] [] [] [] [] [] Nothing
51-- The monad for the main REPL - reading and processing files and updating
52-- global state (hence the IO inner monad).
53type Idris a = StateT IState IO a
55getContext :: Idris Context
56getContext = do i <- get; return (tt_ctxt i)
58getObjectFiles :: Idris [FilePath]
59getObjectFiles = do i <- get; return (idris_objs i)
61addObjectFile :: FilePath -> Idris ()
62addObjectFile f = do i <- get; put (i { idris_objs = f : idris_objs i })
64getLibs :: Idris [String]
65getLibs = do i <- get; return (idris_libs i)
67addLib :: String -> Idris ()
68addLib f = do i <- get; put (i { idris_libs = f : idris_libs i })
70setErrLine :: Int -> Idris ()
71setErrLine x = do i <- get;
73 Nothing -> put (i { errLine = Just x })
78 put (i { errLine = Nothing })
80getIState :: Idris IState
83putIState :: IState -> Idris ()
88 let idx = idris_name i;
89 put (i { idris_name = idx + 1 })
92checkUndefined :: FC -> Name -> Idris ()
95 case lookupCtxt n i of
96 Just _ -> fail $ show fc ++ ":" ++
97 show n ++ " already defined"
100setContext :: Context -> Idris ()
101setContext ctxt = do i <- get; put (i { tt_ctxt = ctxt } )
103updateContext :: (Context -> Context) -> Idris ()
104updateContext f = do i <- get; put (i { tt_ctxt = f (tt_ctxt i) } )
106addDeferred :: [(Name, Type)] -> Idris ()
107addDeferred ns = do mapM_ (\(n, t) -> updateContext (addTyDecl n (tidyNames [] t))) ns
109 put (i { idris_metavars = map fst ns ++ idris_metavars i })
110 where tidyNames used (Bind (MN i x) b sc)
111 = let n' = uniqueName (UN [x]) used in
112 Bind n' b $ tidyNames (n':used) sc
113 tidyNames used (Bind n b sc)
114 = let n' = uniqueName n used in
115 Bind n' b $ tidyNames (n':used) sc
118solveDeferred :: Name -> Idris ()
119solveDeferred n = do i <- get
120 put (i { idris_metavars = idris_metavars i \\ [n] })
122iputStrLn :: String -> Idris ()
123iputStrLn = lift.putStrLn
125setLogLevel :: Int -> Idris ()
126setLogLevel l = do i <- get
127 let opts = idris_options i
128 let opt' = opts { opt_logLevel = l }
129 put (i { idris_options = opt' } )
132logLevel = do i <- get
133 return (opt_logLevel (idris_options i))
135logLvl :: Int -> String -> Idris ()
136logLvl l str = do i <- get
137 let lvl = opt_logLevel (idris_options i)
139 $ do lift (putStrLn str)
140 put (i { idris_log = idris_log i ++ str ++ "\n" } )
142iLOG :: String -> Idris ()
145noErrors :: Idris Bool
146noErrors = do i <- get
148 Nothing -> return True
151setTypeCase :: Bool -> Idris ()
152setTypeCase t = do i <- get
153 let opts = idris_options i
154 let opt' = opts { opt_typecase = t }
155 put (i { idris_options = opt' })
157-- Commands in the REPL
159data Command = Quit | Help | Eval PTerm | Check PTerm | Reload | Edit
160 | Compile String | Execute String
161 | Metavars | Prove Name
163 | LogLvl Int | Spec PTerm | HNF PTerm | Defn Name
166-- Parsed declarations
168data Fixity = Infixl { prec :: Int }
169 | Infixr { prec :: Int }
170 | InfixN { prec :: Int }
171 | PrefixN { prec :: Int }
174instance Show Fixity where
175 show (Infixl i) = "infixl " ++ show i
176 show (Infixr i) = "infixr " ++ show i
177 show (InfixN i) = "infix " ++ show i
178 show (PrefixN i) = "prefix " ++ show i
180data FixDecl = Fix Fixity String
183instance Ord FixDecl where
184 compare (Fix x _) (Fix y _) = compare (prec x) (prec y)
187data Static = Static | Dynamic
190-- Mark bindings with their explicitness, and laziness
191data Plicity = Imp { plazy :: Bool,
193 | Exp { plazy :: Bool,
195 | Constraint { plazy :: Bool,
199impl = Imp False Dynamic
200expl = Exp False Dynamic
201constraint = Constraint False Static
203type FnOpts = Bool -- just inlinable, for now
205inlinable :: FnOpts -> Bool
208data PDecl' t = PFix FC Fixity [String] -- fixity declaration
209 | PTy SyntaxInfo FC Name t -- type declaration
210 | PClauses FC FnOpts Name [PClause' t] -- pattern clause
211 | PData SyntaxInfo FC (PData' t) -- data declaration
212 | PParams FC [(Name, t)] [PDecl' t] -- params block
213 | PClass SyntaxInfo FC
216 [(Name, t)] -- parameters
217 [PDecl' t] -- declarations
218 | PInstance SyntaxInfo FC [t] -- constraints
221 t -- full instance type
226data PClause' t = PClause Name t [t] t [PDecl' t]
227 | PWith Name t [t] t [PDecl' t]
230data PData' t = PDatadecl { d_name :: Name,
232 d_cons :: [(Name, t, FC)] }
235-- Handy to get a free function for applying PTerm -> PTerm functions
236-- across a program, by deriving Functor
238type PDecl = PDecl' PTerm
239type PData = PData' PTerm
240type PClause = PClause' PTerm
242-- get all the names declared in a decl
244declared :: PDecl -> [Name]
245declared (PFix _ _ _) = []
246declared (PTy _ _ n t) = [n]
247declared (PClauses _ _ n _) = [] -- not a declaration
248declared (PData _ _ (PDatadecl n _ ts)) = n : map fstt ts
249 where fstt (a, _, _) = a
250declared (PParams _ _ ds) = concatMap declared ds
251-- declared (PImport _) = []
253updateN :: [(Name, Name)] -> Name -> Name
254updateN ns n | Just n' <- lookup n ns = n'
257updateNs :: [(Name, Name)] -> PTerm -> PTerm
259updateNs ns t = mapPT updateRef t
260 where updateRef (PRef fc f) = PRef fc (updateN ns f)
263-- updateDNs :: [(Name, Name)] -> PDecl -> PDecl
265-- updateDNs ns (PTy s f n t) | Just n' <- lookup n ns = PTy s f n' t
266-- updateDNs ns (PClauses f n c) | Just n' <- lookup n ns = PClauses f n' (map updateCNs c)
267-- where updateCNs ns (PClause n l ts r ds)
268-- = PClause (updateN ns n) (fmap (updateNs ns) l)
269-- (map (fmap (updateNs ns)) ts)
270-- (fmap (updateNs ns) r)
271-- (map (updateDNs ns) ds)
274-- High level language terms
276data PTerm = PQuote Raw
278 | PLam Name PTerm PTerm
279 | PPi Plicity Name PTerm PTerm
280 | PLet Name PTerm PTerm PTerm
281 | PApp FC PTerm [PArg]
287 | PPair FC PTerm PTerm
288 | PDPair FC PTerm PTerm
289 | PHidden PTerm -- irrelevant or hidden pattern
297 | PElabError String -- error to report on elaboration
300mapPT :: (PTerm -> PTerm) -> PTerm -> PTerm
301mapPT f t = f (mpt t) where
302 mpt (PLam n t s) = PLam n (mapPT f t) (mapPT f s)
303 mpt (PPi p n t s) = PPi p n (mapPT f t) (mapPT f s)
304 mpt (PLet n ty v s) = PLet n (mapPT f ty) (mapPT f v) (mapPT f s)
305 mpt (PApp fc t as) = PApp fc (mapPT f t) (map (fmap (mapPT f)) as)
306 mpt (PEq fc l r) = PEq fc (mapPT f l) (mapPT f r)
307 mpt (PPair fc l r) = PPair fc (mapPT f l) (mapPT f r)
308 mpt (PDPair fc l r) = PDPair fc (mapPT f l) (mapPT f r)
309 mpt (PHidden t) = PHidden (mapPT f t)
310 mpt (PDoBlock ds) = PDoBlock (map (fmap (mapPT f)) ds)
311 mpt (PProof ts) = PProof (map (fmap (mapPT f)) ts)
315data PTactic' t = Intro [Name] | Focus Name
316 | Refine Name [Bool] | Rewrite t
317 | Exact t | Compute | Trivial
320 | ProofState | ProofTerm | Undo
322 deriving (Show, Eq, Functor)
324type PTactic = PTactic' PTerm
326data PDo' t = DoExp FC t
329 deriving (Eq, Functor)
333-- The priority gives a hint as to elaboration order. Best to elaborate
334-- things early which will help give a more concrete type to other
335-- variables, e.g. a before (interpTy a).
337data PArg' t = PImp { priority :: Int,
338 lazyarg :: Bool, pname :: Name, getTm :: t }
339 | PExp { priority :: Int,
340 lazyarg :: Bool, getTm :: t }
341 | PConstraint { priority :: Int,
342 lazyarg :: Bool, getTm :: t }
343 deriving (Show, Eq, Functor)
347pconst = PConstraint 0 False
349type PArg = PArg' PTerm
353data ClassInfo = CI { instanceName :: Name,
354 class_methods :: [(Name, PTerm)],
355 class_params :: [Name] }
358-- Syntactic sugar info (TODO: namespaces, modules)
360data DSL = DSL { dsl_bind :: Name,
364data Syntax = Rule [SSymbol] PTerm
367data SSymbol = Keyword Name
372initDSL = DSL (UN [">>="]) (UN ["return"])
374data SyntaxInfo = Syn { using :: [(Name, PTerm)],
375 syn_params :: [(Name, PTerm)],
377 decoration :: Name -> Name,
381defaultSyntax = Syn [] [] [] id initDSL
383--- Pretty printing declarations and terms
385instance Show PTerm where
386 show tm = showImp False tm
388instance Show PDecl where
389 show (PFix _ f ops) = show f ++ " " ++ showSep ", " ops
390 show (PTy _ _ n ty) = show n ++ " : " ++ show ty
391 show (PClauses _ _ n c) = showSep "\n" (map show c)
392 show (PData _ _ d) = show d
394instance Show PClause where
395 show c = showCImp True c
397instance Show PData where
398 show d = showDImp False d
400showCImp :: Bool -> PClause -> String
401showCImp impl (PClause n l ws r w)
402 = showImp impl l ++ showWs ws ++ " = " ++ showImp impl r
403 ++ " where " ++ show w
406 showWs (x : xs) = " | " ++ showImp impl x ++ showWs xs
407showCImp impl (PWith n l ws r w)
408 = showImp impl l ++ showWs ws ++ " with " ++ showImp impl r
409 ++ " { " ++ show w ++ " } "
412 showWs (x : xs) = " | " ++ showImp impl x ++ showWs xs
415showDImp :: Bool -> PData -> String
416showDImp impl (PDatadecl n ty cons)
417 = "data " ++ show n ++ " : " ++ showImp impl ty ++ " where\n\t"
419 (map (\ (n, t, _) -> show n ++ " : " ++ showImp impl t) cons)
421getImps :: [PArg] -> [(Name, PTerm)]
423getImps (PImp _ _ n tm : xs) = (n, tm) : getImps xs
424getImps (_ : xs) = getImps xs
426getExps :: [PArg] -> [PTerm]
428getExps (PExp _ _ tm : xs) = tm : getExps xs
429getExps (_ : xs) = getExps xs
431getConsts :: [PArg] -> [PTerm]
433getConsts (PConstraint _ _ tm : xs) = tm : getConsts xs
434getConsts (_ : xs) = getConsts xs
436getAll :: [PArg] -> [PTerm]
439showImp :: Bool -> PTerm -> String
440showImp impl tm = se 10 tm where
441 se p (PQuote r) = "![" ++ show r ++ "]"
442 se p (PRef _ n) = show n
443 se p (PLam n ty sc) = bracket p 2 $ "\\ " ++ show n ++ " => " ++ show sc
444 se p (PLet n ty v sc) = bracket p 2 $ "let " ++ show n ++ " = " ++ se 10 v ++
446 se p (PPi (Exp l s) n ty sc)
447 | n `elem` allNamesIn sc = bracket p 2 $
448 if l then "|(" else "(" ++
449 show n ++ " : " ++ se 10 ty ++
452 | otherwise = bracket p 2 $ se 0 ty ++ " " ++ st ++ "-> " ++ se 10 sc
454 Static -> "[static] "
456 se p (PPi (Imp l s) n ty sc)
457 | impl = bracket p 2 $ if l then "|{" else "{" ++
458 show n ++ " : " ++ se 10 ty ++
459 "} " ++ st ++ "-> " ++ se 10 sc
460 | otherwise = se 10 sc
462 Static -> "[static] "
464 se p (PPi (Constraint _ _) n ty sc)
465 = bracket p 2 $ se 10 ty ++ " => " ++ se 10 sc
466 se p (PApp _ (PRef _ f) [])
468 se p (PApp _ (PRef _ op@(UN [f:_])) args)
469 | length (getExps args) == 2 && not impl && not (isAlpha f)
470 = let [l, r] = getExps args in
471 bracket p 1 $ se 1 l ++ " " ++ show op ++ " " ++ se 0 r
473 = let args = getExps as in
474 bracket p 1 $ se 1 f ++ if impl then concatMap sArg as
475 else concatMap seArg args
476 se p (PHidden tm) = "." ++ se 0 tm
477 se p (PRefl _) = "refl"
478 se p (PResolveTC _) = "resolvetc"
479 se p (PTrue _) = "()"
480 se p (PFalse _) = "_|_"
481 se p (PEq _ l r) = bracket p 2 $ se 10 l ++ " = " ++ se 10 r
482 se p (PPair _ l r) = "(" ++ se 10 l ++ ", " ++ se 10 r ++ ")"
483 se p (PDPair _ l r) = "(" ++ se 10 l ++ " ** " ++ se 10 r ++ ")"
485 se p (PConstant c) = show c
486 se p (PProof ts) = "proof { " ++ show ts ++ "}"
487 se p (PMetavar n) = "?" ++ show n
488 se p Placeholder = "_"
490 sArg (PImp _ _ n tm) = siArg (n, tm)
491 sArg (PExp _ _ tm) = seArg tm
492 sArg (PConstraint _ _ tm) = scArg tm
494 seArg arg = " " ++ se 0 arg
495 siArg (n, val) = " {" ++ show n ++ " = " ++ se 10 val ++ "}"
496 scArg val = " {{" ++ se 10 val ++ "}}"
498 bracket outer inner str | inner > outer = "(" ++ str ++ ")"
501allNamesIn :: PTerm -> [Name]
502allNamesIn tm = nub $ ni [] tm
505 | not (n `elem` env) = [n]
506 ni env (PApp _ f as) = ni env f ++ concatMap (ni env) (map getTm as)
507 ni env (PLam n ty sc) = ni env ty ++ ni (n:env) sc
508 ni env (PPi _ n ty sc) = ni env ty ++ ni (n:env) sc
509 ni env (PHidden tm) = ni env tm
510 ni env (PEq _ l r) = ni env l ++ ni env r
511 ni env (PPair _ l r) = ni env l ++ ni env r
512 ni env (PDPair _ l r) = ni env l ++ ni env r
515namesIn :: IState -> PTerm -> [Name]
516namesIn ist tm = nub $ ni [] tm
520 = case lookupCtxt n (idris_implicits ist) of
523 ni env (PApp _ f as) = ni env f ++ concatMap (ni env) (map getTm as)
524 ni env (PLam n ty sc) = ni env ty ++ ni (n:env) sc
525 ni env (PPi _ n ty sc) = ni env ty ++ ni (n:env) sc
526 ni env (PEq _ l r) = ni env l ++ ni env r
527 ni env (PPair _ l r) = ni env l ++ ni env r
528 ni env (PDPair _ l r) = ni env l ++ ni env r
529 ni env (PHidden tm) = ni env tm
532-- For inferring types of things
536inferTy = MN 0 "__Infer"
537inferCon = MN 0 "__infer"
538inferDecl = PDatadecl inferTy
540 [(inferCon, PPi impl (MN 0 "A") PSet (
541 PPi expl (MN 0 "a") (PRef bi (MN 0 "A"))
542 (PRef bi inferTy)), bi)]
544infTerm t = PApp bi (PRef bi inferCon) [pimp (MN 0 "A") Placeholder, pexp t]
545infP = P (TCon 6 0) inferTy (Set 0)
547getInferTerm, getInferType :: Term -> Term
548getInferTerm (Bind n b sc) = Bind n b $ getInferTerm sc
549getInferTerm (App (App _ _) tm) = tm
550getInferTerm tm = error ("getInferTerm " ++ show tm)
552getInferType (Bind n b sc) = Bind n b $ getInferType sc
553getInferType (App (App _ ty) _) = ty
555-- Handy primitives: Unit, False, Pair, MkPair, =, mkForeign
557primNames = [unitTy, unitCon,
558 falseTy, pairTy, pairCon,
559 eqTy, eqCon, inferTy, inferCon]
561unitTy = MN 0 "__Unit"
563unitDecl = PDatadecl unitTy PSet
564 [(unitCon, PRef bi unitTy, bi)]
566falseTy = MN 0 "__False"
567falseDecl = PDatadecl falseTy PSet []
569pairTy = MN 0 "__Pair"
570pairCon = MN 0 "__MkPair"
571pairDecl = PDatadecl pairTy (piBind [(n "A", PSet), (n "B", PSet)] PSet)
572 [(pairCon, PPi impl (n "A") PSet (
573 PPi impl (n "B") PSet (
574 PPi expl (n "a") (PRef bi (n "A")) (
575 PPi expl (n "b") (PRef bi (n "B"))
576 (PApp bi (PRef bi pairTy) [pexp (PRef bi (n "A")),
577 pexp (PRef bi (n "B"))])))), bi)]
582eqDecl = PDatadecl eqTy (piBind [(n "a", PSet), (n "b", PSet),
583 (n "x", PRef bi (n "a")), (n "y", PRef bi (n "b"))]
585 [(eqCon, PPi impl (n "a") PSet (
586 PPi impl (n "x") (PRef bi (n "a"))
587 (PApp bi (PRef bi eqTy) [pimp (n "a") Placeholder,
588 pimp (n "b") Placeholder,
589 pexp (PRef bi (n "x")),
590 pexp (PRef bi (n "x"))])), bi)]
593-- Defined in builtins.idr
594sigmaTy = UN ["Sigma"]
595existsCon = UN ["Exists"]
597piBind :: [(Name, PTerm)] -> PTerm -> PTerm
599piBind ((n, ty):ns) t = PPi expl n ty (piBind ns t)
601-- Dealing with parameters
603expandParams :: (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PTerm -> PTerm
604expandParams dec ps ns tm = en tm
606 en (PLam n t s) = PLam n (en t) (en s)
607 en (PPi p n t s) = PPi p n (en t) (en s)
608 en (PLet n ty v s) = PLet n (en ty) (en v) (en s)
609 en (PEq f l r) = PEq f (en l) (en r)
610 en (PPair f l r) = PPair f (en l) (en r)
611 en (PDPair f l r) = PDPair f (en l) (en r)
612 en (PHidden t) = PHidden (en t)
613 en (PDoBlock ds) = PDoBlock (map (fmap en) ds)
614 en (PProof ts) = PProof (map (fmap en) ts)
617 | n `elem` ns = PQuote (Var (dec n))
618 en (PApp fc (PRef fc' n) as)
619 | n `elem` ns = PApp fc (PRef fc' (dec n))
620 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
622 | n `elem` ns = PApp fc (PRef fc (dec n))
623 (map (pexp . (PRef fc)) (map fst ps))
624 en (PApp fc f as) = PApp fc (en f) (map (fmap en) as)
627expandParamsD :: IState ->
628 (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PDecl -> PDecl
629expandParamsD ist dec ps ns (PTy syn fc n ty)
631 then PTy syn fc (dec n) (piBind ps (expandParams dec ps ns ty))
632 else PTy syn fc n (expandParams dec ps ns ty)
633expandParamsD ist dec ps ns (PClauses fc opts n cs)
634 = let n' = if n `elem` ns then dec n else n in
635 PClauses fc opts n' (map expandParamsC cs)
637 expandParamsC (PClause n lhs ws rhs ds)
638 = let -- ps' = updateps True (namesIn ist rhs) (zip ps [0..])
639 ps'' = updateps False (namesIn ist lhs) (zip ps [0..])
640 n' = if n `elem` ns then dec n else n in
641 PClause n' (expandParams dec ps'' ns lhs)
642 (map (expandParams dec ps'' ns) ws)
643 (expandParams dec ps'' ns rhs)
644 (map (expandParamsD ist dec ps'' ns) ds)
645 expandParamsC (PWith n lhs ws wval ds)
646 = let -- ps' = updateps True (namesIn ist wval) (zip ps [0..])
647 ps'' = updateps False (namesIn ist lhs) (zip ps [0..])
648 n' = if n `elem` ns then dec n else n in
649 PWith n' (expandParams dec ps'' ns lhs)
650 (map (expandParams dec ps'' ns) ws)
651 (expandParams dec ps'' ns wval)
652 (map (expandParamsD ist dec ps'' ns) ds)
653 updateps yn nm [] = []
654 updateps yn nm (((a, t), i):as)
655 | (a `elem` nm) == yn = (a, t) : updateps yn nm as
656 | otherwise = (MN i (show n ++ "_u"), t) : updateps yn nm as
658expandParamsD ist dec ps ns d = d
660-- Calculate a priority for a type, for deciding elaboration order
661-- * if it's just a type variable or concrete type, do it early (0)
662-- * if there's only type variables and injective constructors, do it next (1)
663-- * if there's a function type, next (2)
664-- * finally, everything else (3)
666getPriority :: IState -> PTerm -> Int
667getPriority i tm = pri tm
670 case lookupP n (tt_ctxt i) of
671 Just (P (DCon _ _) _ _) -> 1
672 Just (P (TCon _ _) _ _) -> 1
673 Just (P Ref _ _) -> 3
674 Nothing -> 0 -- must be locally bound, if it's not an error...
675 pri (PPi _ _ x y) = max 4 (max (pri x) (pri y))
679 pri (PEq _ l r) = max 1 (max (pri l) (pri r))
680 pri (PApp _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.getTm) as)))
681 pri (PPair _ l r) = max 1 (max (pri l) (pri r))
682 pri (PDPair _ l r) = max 1 (max (pri l) (pri r))
683 pri (PConstant _) = 0
687-- Dealing with implicit arguments
689-- Add implicit Pi bindings for any names in the term which appear in an
692-- This has become a right mess already. Better redo it some time...
694implicit :: SyntaxInfo -> Name -> PTerm -> Idris PTerm
697 let (tm', impdata) = implicitise syn i ptm
698 let (tm'', spos) = findStatics i tm'
699 put (i { idris_implicits = addDef n impdata (idris_implicits i) })
700 logLvl 5 ("Implicit " ++ show n ++ " " ++ show impdata)
702 put (i { idris_statics = addDef n spos (idris_statics i) })
705implicitise :: SyntaxInfo -> IState -> PTerm -> (PTerm, [PArg])
706implicitise syn ist tm
707 = let uvars = using syn
708 pvars = syn_params syn
709 (declimps, ns') = execState (imps True [] tm) ([], [])
710 ns = ns' \\ (map fst pvars ++ no_imp syn) in
712 then (tm, reverse declimps)
713 else implicitise syn ist (pibind uvars ns tm)
715 dropAll (x:xs) ys | x `elem` ys = dropAll xs ys
716 | otherwise = x : dropAll xs ys
719 imps top env (PApp _ f as)
720 = do (decls, ns) <- get
721 let isn = concatMap (namesIn ist) (map getTm as)
722 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
723 imps top env (PPi (Imp l _) n ty sc)
724 = do let isn = nub (namesIn ist ty) `dropAll` [n]
726 put (PImp (getPriority ist ty) l n ty : decls,
727 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
729 imps top env (PPi (Exp l _) n ty sc)
730 = do let isn = nub (namesIn ist ty ++ case sc of
731 (PRef _ x) -> namesIn ist sc `dropAll` [n]
733 (decls, ns) <- get -- ignore decls in HO types
734 put (PExp (getPriority ist ty) l ty : decls,
735 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
737 imps top env (PPi (Constraint l _) n ty sc)
738 = do let isn = nub (namesIn ist ty ++ case sc of
739 (PRef _ x) -> namesIn ist sc `dropAll` [n]
741 (decls, ns) <- get -- ignore decls in HO types
742 put (PConstraint 10 l ty : decls,
743 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
745 imps top env (PEq _ l r)
746 = do (decls, ns) <- get
747 let isn = namesIn ist l ++ namesIn ist r
748 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
749 imps top env (PPair _ l r)
750 = do (decls, ns) <- get
751 let isn = namesIn ist l ++ namesIn ist r
752 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
753 imps top env (PDPair _ (PRef _ n) r)
754 = do (decls, ns) <- get
755 let isn = nub (namesIn ist r) \\ [n]
756 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
757 imps top env (PDPair _ l r)
758 = do (decls, ns) <- get
759 let isn = namesIn ist l ++ namesIn ist r
760 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
761 imps top env (PLam n ty sc)
762 = do imps False env ty
763 imps False (n:env) sc
764 imps top env (PHidden tm) = imps False env tm
765 imps top env _ = return ()
767 pibind using [] sc = sc
768 pibind using (n:ns) sc
769 = case lookup n using of
770 Just ty -> PPi (Imp False Dynamic) n ty (pibind using ns sc)
771 Nothing -> PPi (Imp False Dynamic) n Placeholder (pibind using ns sc)
773-- Add implicit arguments in function calls
775addImpl :: IState -> PTerm -> PTerm
776addImpl ist ptm = ai [] ptm
778 ai env (PRef fc f) = aiFn ist fc f []
779 ai env (PEq fc l r) = let l' = ai env l
782 ai env (PPair fc l r) = let l' = ai env l
785 ai env (PDPair fc l r) = let l' = ai env l
788 ai env (PApp fc (PRef _ f) as)
789 = let as' = map (fmap (ai env)) as in
791 ai env (PApp fc f as) = let f' = ai env f
792 as' = map (fmap (ai env)) as in
794 ai env (PLam n ty sc) = let ty' = ai env ty
795 sc' = ai (n:env) sc in
797 ai env (PLet n ty val sc)
798 = let ty' = ai env ty
800 sc' = ai (n:env) sc in
802 ai env (PPi p n ty sc) = let ty' = ai env ty
803 sc' = ai (n:env) sc in
805 ai env (PHidden tm) = PHidden (ai env tm)
806 ai env (PProof ts) = PProof (map (fmap (ai env)) ts)
809aiFn :: IState -> FC -> Name -> [PArg] -> PTerm
811 | f `elem` primNames = PApp fc (PRef fc f) as
813 = case lookupCtxt f (idris_implicits ist) of
814 Just ns -> mkPApp fc (length ns) (PRef fc f) (insertImpl ns as)
815 Nothing -> mkPApp fc 1 (PRef fc f) as
817 insertImpl :: [PArg] -> [PArg] -> [PArg]
818 insertImpl (PExp p l ty : ps) (PExp _ _ tm : given) =
819 PExp p l tm : insertImpl ps given
820 insertImpl (PConstraint p l ty : ps) (PConstraint _ _ tm : given) =
821 PConstraint p l tm : insertImpl ps given
822 insertImpl (PConstraint p l ty : ps) given =
823 PConstraint p l (PResolveTC fc) : insertImpl ps given
824 insertImpl (PImp p l n ty : ps) given =
825 case find n given [] of
826 Just (tm, given') -> PImp p l n tm : insertImpl ps given'
827 Nothing -> PImp p l n Placeholder : insertImpl ps given
828 insertImpl expected [] = []
829 insertImpl [] given = given
831 find n [] acc = Nothing
832 find n (PImp _ _ n' t : gs) acc
833 | n == n' = Just (t, reverse acc ++ gs)
834 find n (g : gs) acc = find n gs (g : acc)
837mkPApp fc a f as = let rest = drop a as in
838 appRest fc (PApp fc f (take a as)) rest
841 appRest fc f (a : as) = appRest fc (PApp fc f [a]) as
843-- Find 'static' argument positions
844-- (the declared ones, plus any names in argument position in the declared
846-- FIXME: It's possible that this really has to happen after elaboration
848findStatics :: IState -> PTerm -> (PTerm, [Bool])
849findStatics ist tm = let (ns, ss) = fs tm in
850 runState (pos ns ss tm) []
851 where fs (PPi p n t sc)
852 | Static <- pstatic p
853 = let (ns, ss) = fs sc in
854 (namesIn ist t : ns, namesIn ist t ++ n : ss)
855 | otherwise = let (ns, ss) = fs sc in
856 (namesIn ist t : ns, ss)
859 inOne n ns = length (filter id (map (elem n) ns)) == 1
861 pos ns ss (PPi p n t sc)
862 | n `inOne` ns && elem n ss
863 = do sc' <- pos ns ss sc
866 return (PPi (p { pstatic = Static }) n t sc')
867 | otherwise = do sc' <- pos ns ss sc
870 return (PPi p n t sc')
871 pos ns ss t = return t
873-- Debugging/logging stuff
875dumpDecls :: [PDecl] -> String
877dumpDecls (d:ds) = dumpDecl d ++ "\n" ++ dumpDecls ds
879dumpDecl (PFix _ f ops) = show f ++ " " ++ showSep ", " ops
880dumpDecl (PTy _ _ n t) = "tydecl " ++ show n ++ " : " ++ showImp True t
881dumpDecl (PClauses _ _ n cs) = "pat " ++ show n ++ "\t" ++ showSep "\n\t" (map (showCImp True) cs)
882dumpDecl (PData _ _ d) = showDImp True d
883dumpDecl (PParams _ ns ps) = "params {" ++ show ns ++ "\n" ++ dumpDecls ps ++ "}\n"
884dumpDecl (PSyntax _ syn) = "syntax " ++ show syn
885dumpDecl (PClass _ _ cs n ps ds)
886 = "class " ++ show cs ++ " " ++ show n ++ " " ++ show ps ++ "\n" ++ dumpDecls ds
887dumpDecl (PInstance _ _ cs n _ t ds)
888 = "instance " ++ show cs ++ " " ++ show n ++ " " ++ show t ++ "\n" ++ dumpDecls ds
889-- dumpDecl (PImport i) = "import " ++ i
891-- syntactic match of a against b, returning pair of variables in a
892-- and what they match. Returns 'Nothing' if not a match.
894matchClause :: PTerm -> PTerm -> Maybe [(Name, PTerm)]
895matchClause x y = match x y where
896 matchArg x y = match (getTm x) (getTm y)
898 match (PApp _ f args) (PApp _ f' args')
899 | length args == length args'
900 = do mf <- match f f'
901 ms <- zipWithM matchArg args args'
902 return (mf ++ concat ms)
903 match (PRef _ n) (PRef _ n') | n == n' = return []
904 | otherwise = Nothing
905 match (PRef _ n) tm = return [(n, tm)]
906 match (PEq _ l r) (PEq _ l' r') = do ml <- match l l'
909 match (PPair _ l r) (PPair _ l' r') = do ml <- match l l'
912 match (PDPair _ l r) (PDPair _ l' r') = do ml <- match l l'
915 match (PRefl _) (PRefl _) = return []
916 match (PResolveTC _) (PResolveTC _) = return []
917 match (PTrue _) (PTrue _) = return []
918 match (PFalse _) (PFalse _) = return []
919 match (PReturn _) (PReturn _) = return []
920 match (PPi _ _ t s) (PPi _ _ t' s') = do mt <- match t t'
923 match (PLam _ t s) (PLam _ t' s') = do mt <- match t t'
926 match (PHidden x) (PHidden y) = match x y
927 match a b | a == b = return []
928 | otherwise = Nothing
930substMatches :: [(Name, PTerm)] -> PTerm -> PTerm
932substMatches ((n,tm):ns) t = substMatch n tm (substMatches ns t)
934substMatch :: Name -> PTerm -> PTerm -> PTerm
935substMatch n tm t = sm t where
936 sm (PRef _ n') | n == n' = tm
937 sm (PLam x t sc) = PLam x (sm t) (sm sc)
938 sm (PPi p x t sc) = PPi p x (sm t) (sm sc)
939 sm (PApp f x as) = PApp f (sm x) (map (fmap sm) as)
940 sm (PEq f x y) = PEq f (sm x) (sm y)
941 sm (PPair f x y) = PPair f (sm x) (sm y)
942 sm (PDPair f x y) = PDPair f (sm x) (sm y)
943 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