1{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, DeriveFunctor,
2 TypeSynonymInstances #-}
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],
35 idris_options :: IOption,
37 idris_metavars :: [Name],
38 syntax_rules :: [Syntax],
39 syntax_keywords :: [String],
40 imported :: [FilePath],
41 idris_prims :: [(Name, ([E.Name], E.Term))],
45idrisInit = IState emptyContext [] emptyContext emptyContext
46 "" defaultOpts 6 [] [] [] [] [] Nothing
48-- The monad for the main REPL - reading and processing files and updating
49-- global state (hence the IO inner monad).
50type Idris a = StateT IState IO a
52getContext :: Idris Context
53getContext = do i <- get; return (tt_ctxt i)
55setErrLine :: Int -> Idris ()
56setErrLine x = do i <- get;
58 Nothing -> put (i { errLine = Just x })
63 put (i { errLine = Nothing })
65getIState :: Idris IState
68putIState :: IState -> Idris ()
73 let idx = idris_name i;
74 put (i { idris_name = idx + 1 })
77checkUndefined :: FC -> Name -> Idris ()
80 case lookupCtxt n i of
81 Just _ -> fail $ show fc ++ ":" ++
82 show n ++ " already defined"
85setContext :: Context -> Idris ()
86setContext ctxt = do i <- get; put (i { tt_ctxt = ctxt } )
88updateContext :: (Context -> Context) -> Idris ()
89updateContext f = do i <- get; put (i { tt_ctxt = f (tt_ctxt i) } )
91addDeferred :: [(Name, Type)] -> Idris ()
92addDeferred ns = do mapM_ (\(n, t) -> updateContext (addTyDecl n (tidyNames [] t))) ns
94 put (i { idris_metavars = map fst ns ++ idris_metavars i })
95 where tidyNames used (Bind (MN i x) b sc)
96 = let n' = uniqueName (UN [x]) used in
97 Bind n' b $ tidyNames (n':used) sc
98 tidyNames used (Bind n b sc)
99 = let n' = uniqueName n used in
100 Bind n' b $ tidyNames (n':used) sc
103solveDeferred :: Name -> Idris ()
104solveDeferred n = do i <- get
105 put (i { idris_metavars = idris_metavars i \\ [n] })
107iputStrLn :: String -> Idris ()
108iputStrLn = lift.putStrLn
110setLogLevel :: Int -> Idris ()
111setLogLevel l = do i <- get
112 let opts = idris_options i
113 let opt' = opts { opt_logLevel = l }
114 put (i { idris_options = opt' } )
117logLevel = do i <- get
118 return (opt_logLevel (idris_options i))
120logLvl :: Int -> String -> Idris ()
121logLvl l str = do i <- get
122 let lvl = opt_logLevel (idris_options i)
124 $ do lift (putStrLn str)
125 put (i { idris_log = idris_log i ++ str ++ "\n" } )
127iLOG :: String -> Idris ()
130setTypeCase :: Bool -> Idris ()
131setTypeCase t = do i <- get
132 let opts = idris_options i
133 let opt' = opts { opt_typecase = t }
134 put (i { idris_options = opt' })
136-- Commands in the REPL
138data Command = Quit | Help | Eval PTerm | Reload | Edit
140 | Metavars | Prove Name
142 | LogLvl Int | Spec PTerm | HNF PTerm
145-- Parsed declarations
147data Fixity = Infixl { prec :: Int }
148 | Infixr { prec :: Int }
149 | InfixN { prec :: Int }
150 | PrefixN { prec :: Int }
153instance Show Fixity where
154 show (Infixl i) = "infixl " ++ show i
155 show (Infixr i) = "infixr " ++ show i
156 show (InfixN i) = "infix " ++ show i
157 show (PrefixN i) = "prefix " ++ show i
159data FixDecl = Fix Fixity String
162instance Ord FixDecl where
163 compare (Fix x _) (Fix y _) = compare (prec x) (prec y)
166data Static = Static | Dynamic
169-- Mark bindings with their explicitness, and laziness
170data Plicity = Imp { plazy :: Bool,
172 | Exp { plazy :: Bool,
174 | Constraint { plazy :: Bool,
178impl = Imp False Dynamic
179expl = Exp False Dynamic
180constraint = Constraint False Static
182data PDecl' t = PFix FC Fixity [String] -- fixity declaration
183 | PTy SyntaxInfo FC Name t -- type declaration
184 | PClauses FC Name [PClause' t] -- pattern clause
185 | PData SyntaxInfo FC (PData' t) -- data declaration
186 | PParams FC [(Name, t)] [PDecl' t] -- params block
190data PClause' t = PClause Name t [t] t [PDecl' t]
191 | PWith Name t [t] t [PDecl' t]
194data PData' t = PDatadecl { d_name :: Name,
196 d_cons :: [(Name, t, FC)] }
199-- Handy to get a free function for applying PTerm -> PTerm functions
200-- across a program, by deriving Functor
202type PDecl = PDecl' PTerm
203type PData = PData' PTerm
204type PClause = PClause' PTerm
206-- get all the names declared in a decl
208declared :: PDecl -> [Name]
209declared (PFix _ _ _) = []
210declared (PTy _ _ n t) = [n]
211declared (PClauses _ n _) = [] -- not a declaration
212declared (PData _ _ (PDatadecl n _ ts)) = n : map fstt ts
213 where fstt (a, _, _) = a
214declared (PParams _ _ ds) = concatMap declared ds
215-- declared (PImport _) = []
217updateN :: [(Name, Name)] -> Name -> Name
218updateN ns n | Just n' <- lookup n ns = n'
221updateNs :: [(Name, Name)] -> PTerm -> PTerm
223updateNs ns t = mapPT updateRef t
224 where updateRef (PRef fc f) = PRef fc (updateN ns f)
227-- updateDNs :: [(Name, Name)] -> PDecl -> PDecl
229-- updateDNs ns (PTy s f n t) | Just n' <- lookup n ns = PTy s f n' t
230-- updateDNs ns (PClauses f n c) | Just n' <- lookup n ns = PClauses f n' (map updateCNs c)
231-- where updateCNs ns (PClause n l ts r ds)
232-- = PClause (updateN ns n) (fmap (updateNs ns) l)
233-- (map (fmap (updateNs ns)) ts)
234-- (fmap (updateNs ns) r)
235-- (map (updateDNs ns) ds)
238-- High level language terms
240data PTerm = PQuote Raw
242 | PLam Name PTerm PTerm
243 | PPi Plicity Name PTerm PTerm
244 | PLet Name PTerm PTerm PTerm
245 | PApp FC PTerm [PArg]
251 | PPair FC PTerm PTerm
252 | PDPair FC PTerm PTerm
253 | PHidden PTerm -- irrelevant or hidden pattern
261 | PElabError String -- error to report on elaboration
264mapPT :: (PTerm -> PTerm) -> PTerm -> PTerm
265mapPT f t = f (mpt t) where
266 mpt (PLam n t s) = PLam n (mapPT f t) (mapPT f s)
267 mpt (PPi p n t s) = PPi p n (mapPT f t) (mapPT f s)
268 mpt (PLet n ty v s) = PLet n (mapPT f ty) (mapPT f v) (mapPT f s)
269 mpt (PApp fc t as) = PApp fc (mapPT f t) (map (fmap (mapPT f)) as)
270 mpt (PEq fc l r) = PEq fc (mapPT f l) (mapPT f r)
271 mpt (PPair fc l r) = PPair fc (mapPT f l) (mapPT f r)
272 mpt (PDPair fc l r) = PDPair fc (mapPT f l) (mapPT f r)
273 mpt (PHidden t) = PHidden (mapPT f t)
274 mpt (PDoBlock ds) = PDoBlock (map (fmap (mapPT f)) ds)
275 mpt (PProof ts) = PProof (map (fmap (mapPT f)) ts)
279data PTactic' t = Intro [Name] | Focus Name
280 | Refine Name [Bool] | Rewrite t
281 | Exact t | Compute | Trivial
284 | ProofState | ProofTerm | Undo
286 deriving (Show, Eq, Functor)
288type PTactic = PTactic' PTerm
290data PDo' t = DoExp FC t
293 deriving (Eq, Functor)
297data PArg' t = PImp { lazyarg :: Bool, pname :: Name, getTm :: t }
298 | PExp { lazyarg :: Bool, getTm :: t }
299 | PConstraint { lazyarg :: Bool, getTm :: t }
300 deriving (Show, Eq, Functor)
304pconst = PConstraint False
306type PArg = PArg' PTerm
308-- Syntactic sugar info (TODO: namespaces, modules)
310data DSL = DSL { dsl_bind :: Name,
314data Syntax = Rule [SSymbol] PTerm
317data SSymbol = Keyword Name
322initDSL = DSL (UN ["io_bind"]) (UN ["io_return"])
324data SyntaxInfo = Syn { using :: [(Name, PTerm)],
325 syn_params :: [(Name, PTerm)],
327 decoration :: Name -> Name,
331defaultSyntax = Syn [] [] [] id initDSL
333--- Pretty printing declarations and terms
335instance Show PTerm where
336 show tm = showImp False tm
338instance Show PDecl where
339 show (PFix _ f ops) = show f ++ " " ++ showSep ", " ops
340 show (PTy _ _ n ty) = show n ++ " : " ++ show ty
341 show (PClauses _ n c) = showSep "\n" (map show c)
342 show (PData _ _ d) = show d
344instance Show PClause where
345 show c = showCImp True c
347instance Show PData where
348 show d = showDImp False d
350showCImp :: Bool -> PClause -> String
351showCImp impl (PClause n l ws r w)
352 = showImp impl l ++ showWs ws ++ " = " ++ showImp impl r
353 ++ " where " ++ show w
356 showWs (x : xs) = " | " ++ showImp impl x ++ showWs xs
357showCImp impl (PWith n l ws r w)
358 = showImp impl l ++ showWs ws ++ " with " ++ showImp impl r
359 ++ " { " ++ show w ++ " } "
362 showWs (x : xs) = " | " ++ showImp impl x ++ showWs xs
365showDImp :: Bool -> PData -> String
366showDImp impl (PDatadecl n ty cons)
367 = "data " ++ show n ++ " : " ++ showImp impl ty ++ " where\n\t"
369 (map (\ (n, t, _) -> show n ++ " : " ++ showImp impl t) cons)
371getImps :: [PArg] -> [(Name, PTerm)]
373getImps (PImp _ n tm : xs) = (n, tm) : getImps xs
374getImps (_ : xs) = getImps xs
376getExps :: [PArg] -> [PTerm]
378getExps (PExp _ tm : xs) = tm : getExps xs
379getExps (_ : xs) = getExps xs
381getConsts :: [PArg] -> [PTerm]
383getConsts (PConstraint _ tm : xs) = tm : getConsts xs
384getConsts (_ : xs) = getConsts xs
386getAll :: [PArg] -> [PTerm]
389showImp :: Bool -> PTerm -> String
390showImp impl tm = se 10 tm where
391 se p (PQuote r) = "![" ++ show r ++ "]"
392 se p (PRef _ n) = show n
393 se p (PLam n ty sc) = bracket p 2 $ "\\ " ++ show n ++ " => " ++ show sc
394 se p (PLet n ty v sc) = bracket p 2 $ "let " ++ show n ++ " = " ++ se 10 v ++
396 se p (PPi (Exp l s) n ty sc)
397 | n `elem` allNamesIn sc = bracket p 2 $
398 if l then "|(" else "(" ++
399 show n ++ " : " ++ se 10 ty ++
402 | otherwise = bracket p 2 $ se 0 ty ++ " " ++ st ++ "-> " ++ se 10 sc
404 Static -> "[static] "
406 se p (PPi (Imp l s) n ty sc)
407 | impl = bracket p 2 $ if l then "|{" else "{" ++
408 show n ++ " : " ++ se 10 ty ++
409 "} " ++ st ++ "-> " ++ se 10 sc
410 | otherwise = se 10 sc
412 Static -> "[static] "
414 se p (PPi (Constraint _ _) n ty sc)
415 = bracket p 2 $ se 10 ty ++ " => " ++ se 10 sc
416 se p (PApp _ (PRef _ f) [])
418 se p (PApp _ (PRef _ op@(UN [f:_])) args)
419 | length (getExps args) == 2 && not impl && not (isAlpha f)
420 = let [l, r] = getExps args in
421 bracket p 1 $ se 1 l ++ " " ++ show op ++ " " ++ se 0 r
423 = let (imps, cs, args) = (getImps as, getConsts as, getExps as) in
424 bracket p 1 $ se 1 f ++ concatMap scArg cs
425 ++ (if impl then concatMap siArg imps else "")
426 ++ concatMap seArg args
427 se p (PHidden tm) = "." ++ se 0 tm
428 se p (PRefl _) = "refl"
429 se p (PResolveTC _) = "resolvetc"
430 se p (PTrue _) = "()"
431 se p (PFalse _) = "_|_"
432 se p (PEq _ l r) = bracket p 2 $ se 10 l ++ " = " ++ se 10 r
433 se p (PPair _ l r) = "(" ++ se 10 l ++ ", " ++ se 10 r ++ ")"
434 se p (PDPair _ l r) = "(" ++ se 10 l ++ " ** " ++ se 10 r ++ ")"
436 se p (PConstant c) = show c
437 se p (PProof ts) = "proof { " ++ show ts ++ "}"
438 se p (PMetavar n) = "?" ++ show n
439 se p Placeholder = "_"
441 seArg arg = " " ++ se 0 arg
442 siArg (n, val) = " {" ++ show n ++ " = " ++ se 10 val ++ "}"
443 scArg val = " {{" ++ se 10 val ++ "}}"
445 bracket outer inner str | inner > outer = "(" ++ str ++ ")"
448allNamesIn :: PTerm -> [Name]
449allNamesIn tm = nub $ ni [] tm
452 | not (n `elem` env) = [n]
453 ni env (PApp _ f as) = ni env f ++ concatMap (ni env) (map getTm as)
454 ni env (PLam n ty sc) = ni env ty ++ ni (n:env) sc
455 ni env (PPi _ n ty sc) = ni env ty ++ ni (n:env) sc
456 ni env (PHidden tm) = ni env tm
457 ni env (PEq _ l r) = ni env l ++ ni env r
458 ni env (PPair _ l r) = ni env l ++ ni env r
459 ni env (PDPair _ l r) = ni env l ++ ni env r
462namesIn :: IState -> PTerm -> [Name]
463namesIn ist tm = nub $ ni [] tm
467 = case lookupCtxt n (idris_implicits ist) of
470 ni env (PApp _ f as) = ni env f ++ concatMap (ni env) (map getTm as)
471 ni env (PLam n ty sc) = ni env ty ++ ni (n:env) sc
472 ni env (PPi _ n ty sc) = ni env ty ++ ni (n:env) sc
473 ni env (PEq _ l r) = ni env l ++ ni env r
474 ni env (PPair _ l r) = ni env l ++ ni env r
475 ni env (PDPair _ l r) = ni env l ++ ni env r
476 ni env (PHidden tm) = ni env tm
479-- For inferring types of things
483inferTy = MN 0 "__Infer"
484inferCon = MN 0 "__infer"
485inferDecl = PDatadecl inferTy
487 [(inferCon, PPi impl (MN 0 "A") PSet (
488 PPi expl (MN 0 "a") (PRef bi (MN 0 "A"))
489 (PRef bi inferTy)), bi)]
491infTerm t = PApp bi (PRef bi inferCon) [pimp (MN 0 "A") Placeholder, pexp t]
492infP = P (TCon 6 0) inferTy (Set 0)
494getInferTerm, getInferType :: Term -> Term
495getInferTerm (Bind n b sc) = Bind n b $ getInferTerm sc
496getInferTerm (App (App _ _) tm) = tm
497getInferTerm tm = error ("getInferTerm " ++ show tm)
499getInferType (Bind n b sc) = Bind n b $ getInferType sc
500getInferType (App (App _ ty) _) = ty
502-- Handy primitives: Unit, False, Pair, MkPair, =, mkForeign
504primNames = [unitTy, unitCon,
505 falseTy, pairTy, pairCon,
506 eqTy, eqCon, inferTy, inferCon]
508unitTy = MN 0 "__Unit"
510unitDecl = PDatadecl unitTy PSet
511 [(unitCon, PRef bi unitTy, bi)]
513falseTy = MN 0 "__False"
514falseDecl = PDatadecl falseTy PSet []
516pairTy = MN 0 "__Pair"
517pairCon = MN 0 "__MkPair"
518pairDecl = PDatadecl pairTy (piBind [(n "A", PSet), (n "B", PSet)] PSet)
519 [(pairCon, PPi impl (n "A") PSet (
520 PPi impl (n "B") PSet (
521 PPi expl (n "a") (PRef bi (n "A")) (
522 PPi expl (n "b") (PRef bi (n "B"))
523 (PApp bi (PRef bi pairTy) [pexp (PRef bi (n "A")),
524 pexp (PRef bi (n "B"))])))), bi)]
529eqDecl = PDatadecl eqTy (piBind [(n "a", PSet), (n "b", PSet),
530 (n "x", PRef bi (n "a")), (n "y", PRef bi (n "b"))]
532 [(eqCon, PPi impl (n "a") PSet (
533 PPi impl (n "x") (PRef bi (n "a"))
534 (PApp bi (PRef bi eqTy) [pimp (n "a") Placeholder,
535 pimp (n "b") Placeholder,
536 pexp (PRef bi (n "x")),
537 pexp (PRef bi (n "x"))])), bi)]
540-- Defined in builtins.idr
541sigmaTy = UN ["Sigma"]
542existsCon = UN ["Exists"]
544piBind :: [(Name, PTerm)] -> PTerm -> PTerm
546piBind ((n, ty):ns) t = PPi expl n ty (piBind ns t)
548-- Dealing with parameters
550expandParams :: (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PTerm -> PTerm
551expandParams dec ps ns tm = en tm
553 en (PLam n t s) = PLam n (en t) (en s)
554 en (PPi p n t s) = PPi p n (en t) (en s)
555 en (PLet n ty v s) = PLet n (en ty) (en v) (en s)
556 en (PEq f l r) = PEq f (en l) (en r)
557 en (PPair f l r) = PPair f (en l) (en r)
558 en (PDPair f l r) = PDPair f (en l) (en r)
559 en (PHidden t) = PHidden (en t)
560 en (PDoBlock ds) = PDoBlock (map (fmap en) ds)
561 en (PProof ts) = PProof (map (fmap en) ts)
563 en (PApp fc (PRef fc' n) as)
564 | n `elem` ns = PApp fc (PRef fc' (dec n))
565 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
567 | n `elem` ns = PApp fc (PRef fc (dec n))
568 (map (pexp . (PRef fc)) (map fst ps))
569 en (PApp fc f as) = PApp fc (en f) (map (fmap en) as)
572expandParamsD :: (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PDecl -> PDecl
573expandParamsD dec ps ns (PTy syn fc n ty)
575 then PTy syn fc (dec n) (piBind ps (expandParams dec ps ns ty))
576 else PTy syn fc n (expandParams dec ps ns ty)
577expandParamsD dec ps ns (PClauses fc n cs)
578 = let n' = if n `elem` ns then dec n else n in
579 PClauses fc n' (map expandParamsC cs)
581 expandParamsC (PClause n lhs ws rhs ds)
582 = let n' = if n `elem` ns then dec n else n in
583 PClause n' (expandParams dec ps ns lhs)
584 (map (expandParams dec ps ns) ws)
585 (expandParams dec ps ns rhs)
586 (map (expandParamsD dec ps ns) ds)
587 expandParamsC (PWith n lhs ws wval ds)
588 = let n' = if n `elem` ns then dec n else n in
589 PWith n' (expandParams dec ps ns lhs)
590 (map (expandParams dec ps ns) ws)
591 (expandParams dec ps ns wval)
592 (map (expandParamsD dec ps ns) ds)
593expandParamsD dec ps ns d = d
595-- Dealing with implicit arguments
597-- Add implicit Pi bindings for any names in the term which appear in an
600-- This has become a right mess already. Better redo it some time...
602implicit :: SyntaxInfo -> Name -> PTerm -> Idris PTerm
605 let (tm', impdata) = implicitise syn i ptm
606 let (tm'', spos) = findStatics i tm'
607 put (i { idris_implicits = addDef n impdata (idris_implicits i) })
608 logLvl 5 ("Implicit " ++ show n ++ " " ++ show impdata)
610 put (i { idris_statics = addDef n spos (idris_statics i) })
613implicitise :: SyntaxInfo -> IState -> PTerm -> (PTerm, [PArg])
614implicitise syn ist tm
615 = let uvars = using syn
616 pvars = syn_params syn
617 (declimps, ns') = execState (imps True [] tm) ([], [])
618 ns = ns' \\ (map fst pvars ++ no_imp syn) in
620 then (tm, reverse declimps)
621 else implicitise syn ist (pibind uvars ns tm)
623 dropAll (x:xs) ys | x `elem` ys = dropAll xs ys
624 | otherwise = x : dropAll xs ys
627 imps top env (PApp _ f as)
628 = do (decls, ns) <- get
629 let isn = concatMap (namesIn ist) (map getTm as)
630 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
631 imps top env (PPi (Imp l _) n ty sc)
632 = do let isn = nub (namesIn ist ty) `dropAll` [n]
634 put (PImp l n ty : decls,
635 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
637 imps top env (PPi (Exp l _) n ty sc)
638 = do let isn = nub (namesIn ist ty ++ case sc of
639 (PRef _ x) -> namesIn ist sc `dropAll` [n]
641 (decls, ns) <- get -- ignore decls in HO types
642 put (PExp l ty : decls,
643 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
645 imps top env (PPi (Constraint l _) n ty sc)
646 = do let isn = nub (namesIn ist ty ++ case sc of
647 (PRef _ x) -> namesIn ist sc `dropAll` [n]
649 (decls, ns) <- get -- ignore decls in HO types
650 put (PConstraint l ty : decls,
651 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
653 imps top env (PEq _ l r)
654 = do (decls, ns) <- get
655 let isn = namesIn ist l ++ namesIn ist r
656 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
657 imps top env (PPair _ l r)
658 = do (decls, ns) <- get
659 let isn = namesIn ist l ++ namesIn ist r
660 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
661 imps top env (PDPair _ (PRef _ n) r)
662 = do (decls, ns) <- get
663 let isn = nub (namesIn ist r) \\ [n]
664 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
665 imps top env (PDPair _ l r)
666 = do (decls, ns) <- get
667 let isn = namesIn ist l ++ namesIn ist r
668 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
669 imps top env (PLam n ty sc)
670 = do imps False env ty
671 imps False (n:env) sc
672 imps top env (PHidden tm) = imps False env tm
673 imps top env _ = return ()
675 pibind using [] sc = sc
676 pibind using (n:ns) sc
677 = case lookup n using of
678 Just ty -> PPi (Imp False Dynamic) n ty (pibind using ns sc)
679 Nothing -> PPi (Imp False Dynamic) n Placeholder (pibind using ns sc)
681-- Add implicit arguments in function calls
683addImpl :: IState -> PTerm -> PTerm
684addImpl ist ptm = ai [] ptm
686 ai env (PRef fc f) = aiFn ist fc f []
687 ai env (PEq fc l r) = let l' = ai env l
690 ai env (PPair fc l r) = let l' = ai env l
693 ai env (PDPair fc l r) = let l' = ai env l
696 ai env (PApp fc (PRef _ f) as)
697 = let as' = map (fmap (ai env)) as in
699 ai env (PApp fc f as) = let f' = ai env f
700 as' = map (fmap (ai env)) as in
702 ai env (PLam n ty sc) = let ty' = ai env ty
703 sc' = ai (n:env) sc in
705 ai env (PLet n ty val sc)
706 = let ty' = ai env ty
708 sc' = ai (n:env) sc in
710 ai env (PPi p n ty sc) = let ty' = ai env ty
711 sc' = ai (n:env) sc in
713 ai env (PHidden tm) = PHidden (ai env tm)
714 ai env (PProof ts) = PProof (map (fmap (ai env)) ts)
717aiFn :: IState -> FC -> Name -> [PArg] -> PTerm
719 | f `elem` primNames = PApp fc (PRef fc f) as
721 = case lookupCtxt f (idris_implicits ist) of
722 Just ns -> mkPApp fc (length ns) (PRef fc f) (insertImpl ns as)
723 Nothing -> mkPApp fc 1 (PRef fc f) as
725 insertImpl :: [PArg] -> [PArg] -> [PArg]
726 insertImpl (PExp l ty : ps) (PExp _ tm : given) =
727 PExp l tm : insertImpl ps given
728 insertImpl (PConstraint l ty : ps) (PConstraint _ tm : given) =
729 PConstraint l tm : insertImpl ps given
730 insertImpl (PConstraint l ty : ps) given =
731 PConstraint l (PResolveTC fc) : insertImpl ps given
732 insertImpl (PImp l n ty : ps) given =
733 case find n given [] of
734 Just (tm, given') -> PImp l n tm : insertImpl ps given'
735 Nothing -> PImp l n Placeholder : insertImpl ps given
736 insertImpl expected [] = []
737 insertImpl [] given = given
739 find n [] acc = Nothing
740 find n (PImp _ n' t : gs) acc
741 | n == n' = Just (t, reverse acc ++ gs)
742 find n (g : gs) acc = find n gs (g : acc)
745mkPApp fc a f as = let rest = drop a as in
746 appRest fc (PApp fc f (take a as)) rest
749 appRest fc f (a : as) = appRest fc (PApp fc f [a]) as
751-- Find 'static' argument positions
752-- (the declared ones, plus any names in argument position in the declared
754-- FIXME: It's possible that this really has to happen after elaboration
756findStatics :: IState -> PTerm -> (PTerm, [Bool])
757findStatics ist tm = let (ns, ss) = fs tm in
758 runState (pos ns ss tm) []
759 where fs (PPi p n t sc)
760 | Static <- pstatic p
761 = let (ns, ss) = fs sc in
762 (namesIn ist t : ns, namesIn ist t ++ n : ss)
763 | otherwise = let (ns, ss) = fs sc in
764 (namesIn ist t : ns, ss)
767 inOne n ns = length (filter id (map (elem n) ns)) == 1
769 pos ns ss (PPi p n t sc)
770 | n `inOne` ns && elem n ss
771 = do sc' <- pos ns ss sc
774 return (PPi (p { pstatic = Static }) n t sc')
775 | otherwise = do sc' <- pos ns ss sc
778 return (PPi p n t sc')
779 pos ns ss t = return t
781-- Debugging/logging stuff
783dumpDecls :: [PDecl] -> String
785dumpDecls (d:ds) = dumpDecl d ++ "\n" ++ dumpDecls ds
787dumpDecl (PFix _ f ops) = show f ++ " " ++ showSep ", " ops
788dumpDecl (PTy _ _ n t) = "tydecl " ++ show n ++ " : " ++ showImp True t
789dumpDecl (PClauses _ n cs) = "pat " ++ show n ++ "\t" ++ showSep "\n\t" (map (showCImp True) cs)
790dumpDecl (PData _ _ d) = showDImp True d
791dumpDecl (PParams _ ns ps) = "params {" ++ show ns ++ "\n" ++ dumpDecls ps ++ "}\n"
792dumpDecl (PSyntax _ syn) = "syntax " ++ show syn
793-- dumpDecl (PImport i) = "import " ++ i
795-- syntactic match of a against b, returning pair of variables in a
796-- and what they match. Returns 'Nothing' if not a match.
798matchClause :: PTerm -> PTerm -> Maybe [(Name, PTerm)]
799matchClause x y = match x y where
800 matchArg x y = match (getTm x) (getTm y)
802 match (PApp _ f args) (PApp _ f' args')
803 | length args == length args'
804 = do mf <- match f f'
805 ms <- zipWithM matchArg args args'
806 return (mf ++ concat ms)
807 match (PRef _ n) (PRef _ n') | n == n' = return []
808 | otherwise = Nothing
809 match (PRef _ n) tm = return [(n, tm)]
810 match (PEq _ l r) (PEq _ l' r') = do ml <- match l l'
813 match (PPair _ l r) (PPair _ l' r') = do ml <- match l l'
816 match (PDPair _ l r) (PDPair _ l' r') = do ml <- match l l'
819 match (PRefl _) (PRefl _) = return []
820 match (PResolveTC _) (PResolveTC _) = return []
821 match (PTrue _) (PTrue _) = return []
822 match (PFalse _) (PFalse _) = return []
823 match (PReturn _) (PReturn _) = return []
824 match (PPi _ _ t s) (PPi _ _ t' s') = do mt <- match t t'
827 match (PLam _ t s) (PLam _ t' s') = do mt <- match t t'
830 match (PHidden x) (PHidden y) = match x y
831 match a b | a == b = return []
832 | otherwise = Nothing
834substMatches :: [(Name, PTerm)] -> PTerm -> PTerm
836substMatches ((n,tm):ns) t = substMatch n tm (substMatches ns t)
838substMatch :: Name -> PTerm -> PTerm -> PTerm
839substMatch n tm t = sm t where
840 sm (PRef _ n') | n == n' = tm
841 sm (PLam x t sc) = PLam x (sm t) (sm sc)
842 sm (PPi p x t sc) = PPi p x (sm t) (sm sc)
843 sm (PApp f x as) = PApp f (sm x) (map (fmap sm) as)
844 sm (PEq f x y) = PEq f (sm x) (sm y)
845 sm (PPair f x y) = PPair f (sm x) (sm y)
846 sm (PDPair f x y) = PDPair f (sm x) (sm y)
847 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