1{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, DeriveFunctor,
2 TypeSynonymInstances, PatternGuards #-}
4module Idris.AbsSyntax where
11import System.Console.Haskeline
12import Control.Monad.State
18import qualified Epic.Epic as E
20data IOption = IOption { opt_logLevel :: Int,
22 opt_typeintype :: Bool,
30defaultOpts = IOption 0 False False True False True True
32-- TODO: Add 'module data' to IState, which can be saved out and reloaded quickly (i.e
33-- without typechecking).
34-- This will include all the functions and data declarations, plus fixity declarations
37data IState = IState { tt_ctxt :: Context,
38 idris_constraints :: [(UConstraint, FC)],
39 idris_infixes :: [FixDecl],
40 idris_implicits :: Ctxt [PArg],
41 idris_statics :: Ctxt [Bool],
42 idris_classes :: Ctxt ClassInfo,
43 idris_dsls :: Ctxt DSL,
44 idris_optimisation :: Ctxt OptInfo,
45 idris_datatypes :: Ctxt TypeInfo,
46 idris_patdefs :: Ctxt [(Term, Term)], -- not exported
47 idris_flags :: Ctxt [FnOpt],
48 idris_callgraph :: Ctxt [Name],
49 idris_totcheck :: [(FC, Name)],
51 idris_options :: IOption,
53 idris_metavars :: [Name],
54 syntax_rules :: [Syntax],
55 syntax_keywords :: [String],
56 imported :: [FilePath],
57 idris_prims :: [(Name, ([E.Name], E.Term))],
58 idris_objs :: [FilePath],
59 idris_libs :: [String],
60 idris_hdrs :: [String],
61 last_proof :: Maybe (Name, [String]),
63 lastParse :: Maybe Name,
64 indent_stack :: [Int],
65 brace_stack :: [Maybe Int],
66 hide_list :: [(Name, Maybe Accessibility)],
67 default_access :: Accessibility,
68 ibc_write :: [IBCWrite],
69 compiled_so :: Maybe String
72-- information that needs writing for the current module's .ibc file
73data IBCWrite = IBCFix FixDecl
77 | IBCInstance Bool Name Name
87 | IBCAccess Name Accessibility
88 | IBCTotal Name Totality
89 | IBCFlags Name [FnOpt]
91 | IBCDef Name -- i.e. main context
94idrisInit = IState initContext [] [] emptyContext emptyContext emptyContext
95 emptyContext emptyContext emptyContext emptyContext
96 emptyContext emptyContext
97 [] "" defaultOpts 6 [] [] [] [] [] [] [] []
98 Nothing Nothing Nothing [] [] [] Hidden [] Nothing
100-- The monad for the main REPL - reading and processing files and updating
101-- global state (hence the IO inner monad).
102type Idris = StateT IState (InputT IO)
104getContext :: Idris Context
105getContext = do i <- get; return (tt_ctxt i)
107getObjectFiles :: Idris [FilePath]
108getObjectFiles = do i <- get; return (idris_objs i)
110addObjectFile :: FilePath -> Idris ()
111addObjectFile f = do i <- get; put (i { idris_objs = f : idris_objs i })
113getLibs :: Idris [String]
114getLibs = do i <- get; return (idris_libs i)
116addLib :: String -> Idris ()
117addLib f = do i <- get; put (i { idris_libs = f : idris_libs i })
119addHdr :: String -> Idris ()
120addHdr f = do i <- get; put (i { idris_hdrs = f : idris_hdrs i })
122totcheck :: (FC, Name) -> Idris ()
123totcheck n = do i <- get; put (i { idris_totcheck = n : idris_totcheck i })
125setFlags :: Name -> [FnOpt] -> Idris ()
126setFlags n fs = do i <- get; put (i { idris_flags = addDef n fs (idris_flags i) })
128setAccessibility :: Name -> Accessibility -> Idris ()
131 let ctxt = setAccess n a (tt_ctxt i)
132 put (i { tt_ctxt = ctxt })
134setTotality :: Name -> Totality -> Idris ()
137 let ctxt = setTotal n a (tt_ctxt i)
138 put (i { tt_ctxt = ctxt })
140getTotality :: Name -> Idris Totality
143 case lookupTotal n (tt_ctxt i) of
145 _ -> return (Total [])
147addToCG :: Name -> [Name] -> Idris ()
148addToCG n ns = do i <- get
149 put (i { idris_callgraph = addDef n ns (idris_callgraph i) })
151-- Add a class instance function. Dodgy hack: Put integer instances first in the
152-- list so they are resolved by default.
154addInstance :: Bool -> Name -> Name -> Idris ()
157 case lookupCtxt Nothing n (idris_classes ist) of
159 do let cs = addDef n (CI a b c d (addI i ins)) (idris_classes ist)
160 put (ist { idris_classes = cs })
161 _ -> do let cs = addDef n (CI (MN 0 "none") [] [] [] [i]) (idris_classes ist)
162 put (ist { idris_classes = cs })
163 where addI i ins | int = i : ins
164 | otherwise = ins ++ [i]
166addClass :: Name -> ClassInfo -> Idris ()
169 let i' = case lookupCtxt Nothing n (idris_classes ist) of
170 [c] -> c { class_instances = class_instances i }
172 put (ist { idris_classes = addDef n i' (idris_classes ist) })
174addIBC :: IBCWrite -> Idris ()
177 when (notDef (ibc_write i)) $
178 put (i { ibc_write = ibc : ibc_write i })
179 where notDef [] = True
180 notDef (IBCDef n': is) | n == n' = False
181 notDef (_ : is) = notDef is
182addIBC ibc = do i <- get; put (i { ibc_write = ibc : ibc_write i })
185clearIBC = do i <- get; put (i { ibc_write = [] })
187getHdrs :: Idris [String]
188getHdrs = do i <- get; return (idris_hdrs i)
190setErrLine :: Int -> Idris ()
191setErrLine x = do i <- get;
193 Nothing -> put (i { errLine = Just x })
197clearErr = do i <- get
198 put (i { errLine = Nothing })
200getSO :: Idris (Maybe String)
202 return (compiled_so i)
204setSO :: Maybe String -> Idris ()
206 put (i { compiled_so = s })
208getIState :: Idris IState
211putIState :: IState -> Idris ()
215getName = do i <- get;
216 let idx = idris_name i;
217 put (i { idris_name = idx + 1 })
220checkUndefined :: FC -> Name -> Idris ()
223 case lookupTy Nothing n i of
224 (_:_) -> fail $ show fc ++ ":" ++
225 show n ++ " already defined"
228setContext :: Context -> Idris ()
229setContext ctxt = do i <- get; put (i { tt_ctxt = ctxt } )
231updateContext :: (Context -> Context) -> Idris ()
232updateContext f = do i <- get; put (i { tt_ctxt = f (tt_ctxt i) } )
234addConstraints :: FC -> (Int, [UConstraint]) -> Idris ()
235addConstraints fc (v, cs)
238 let ctxt' = ctxt { uconstraints = cs ++ uconstraints ctxt,
240 let ics = zip cs (repeat fc) ++ idris_constraints i
241 put (i { tt_ctxt = ctxt', idris_constraints = ics })
243addDeferred :: [(Name, Type)] -> Idris ()
244addDeferred ns = do mapM_ (\(n, t) -> updateContext (addTyDecl n (tidyNames [] t))) ns
246 put (i { idris_metavars = map fst ns ++ idris_metavars i })
247 where tidyNames used (Bind (MN i x) b sc)
248 = let n' = uniqueName (UN x) used in
249 Bind n' b $ tidyNames (n':used) sc
250 tidyNames used (Bind n b sc)
251 = let n' = uniqueName n used in
252 Bind n' b $ tidyNames (n':used) sc
255solveDeferred :: Name -> Idris ()
256solveDeferred n = do i <- get
257 put (i { idris_metavars = idris_metavars i \\ [n] })
259iputStrLn :: String -> Idris ()
260iputStrLn = liftIO . putStrLn
262iWarn :: FC -> String -> Idris ()
263iWarn fc err = liftIO $ putStrLn (show fc ++ ":" ++ err)
265setLogLevel :: Int -> Idris ()
266setLogLevel l = do i <- get
267 let opts = idris_options i
268 let opt' = opts { opt_logLevel = l }
269 put (i { idris_options = opt' } )
272logLevel = do i <- get
273 return (opt_logLevel (idris_options i))
277 return (opt_repl (idris_options i))
279setREPL :: Bool -> Idris ()
280setREPL t = do i <- get
281 let opts = idris_options i
282 let opt' = opts { opt_repl = t }
283 put (i { idris_options = opt' })
287 return (opt_verbose (idris_options i))
289setVerbose :: Bool -> Idris ()
290setVerbose t = do i <- get
291 let opts = idris_options i
292 let opt' = opts { opt_verbose = t }
293 put (i { idris_options = opt' })
295typeInType :: Idris Bool
296typeInType = do i <- get
297 return (opt_typeintype (idris_options i))
299setTypeInType :: Bool -> Idris ()
300setTypeInType t = do i <- get
301 let opts = idris_options i
302 let opt' = opts { opt_typeintype = t }
303 put (i { idris_options = opt' })
305coverage :: Idris Bool
306coverage = do i <- get
307 return (opt_coverage (idris_options i))
309setCoverage :: Bool -> Idris ()
310setCoverage t = do i <- get
311 let opts = idris_options i
312 let opt' = opts { opt_coverage = t }
313 put (i { idris_options = opt' })
317 return (opt_showimp (idris_options i))
319setImpShow :: Bool -> Idris ()
320setImpShow t = do i <- get
321 let opts = idris_options i
322 let opt' = opts { opt_showimp = t }
323 put (i { idris_options = opt' })
325logLvl :: Int -> String -> Idris ()
326logLvl l str = do i <- get
327 let lvl = opt_logLevel (idris_options i)
329 $ do liftIO (putStrLn str)
330 put (i { idris_log = idris_log i ++ str ++ "\n" } )
332iLOG :: String -> Idris ()
335noErrors :: Idris Bool
336noErrors = do i <- get
338 Nothing -> return True
341setTypeCase :: Bool -> Idris ()
342setTypeCase t = do i <- get
343 let opts = idris_options i
344 let opt' = opts { opt_typecase = t }
345 put (i { idris_options = opt' })
347-- Commands in the REPL
349data Command = Quit | Help | Eval PTerm | Check PTerm | TotCheck Name
351 | Compile String | Execute | ExecVal PTerm
352 | Metavars | Prove Name | AddProof | Universes
354 | LogLvl Int | Spec PTerm | HNF PTerm | Defn Name | Info Name
357-- Parsed declarations
359data Fixity = Infixl { prec :: Int }
360 | Infixr { prec :: Int }
361 | InfixN { prec :: Int }
362 | PrefixN { prec :: Int }
365deriving instance Binary Fixity
368instance Show Fixity where
369 show (Infixl i) = "infixl " ++ show i
370 show (Infixr i) = "infixr " ++ show i
371 show (InfixN i) = "infix " ++ show i
372 show (PrefixN i) = "prefix " ++ show i
374data FixDecl = Fix Fixity String
377deriving instance Binary FixDecl
380instance Ord FixDecl where
381 compare (Fix x _) (Fix y _) = compare (prec x) (prec y)
384data Static = Static | Dynamic
387deriving instance Binary Static
390-- Mark bindings with their explicitness, and laziness
391data Plicity = Imp { plazy :: Bool,
393 | Exp { plazy :: Bool,
395 | Constraint { plazy :: Bool,
397 | TacImp { plazy :: Bool,
403deriving instance Binary Plicity
406impl = Imp False Dynamic
407expl = Exp False Dynamic
408constraint = Constraint False Dynamic
409tacimpl = TacImp False Dynamic
411data FnOpt = Inlinable | TotalFn | AssertTotal | TCGen
412 | Specialise [Name] -- specialise it, freeze these names
415deriving instance Binary FnOpt
420inlinable :: FnOpts -> Bool
421inlinable = elem Inlinable
423data PDecl' t = PFix FC Fixity [String] -- fixity declaration
424 | PTy SyntaxInfo FC FnOpts Name t -- type declaration
425 | PClauses FC FnOpts Name [PClause' t] -- pattern clause
426 | PData SyntaxInfo FC (PData' t) -- data declaration
427 | PParams FC [(Name, t)] [PDecl' t] -- params block
428 | PNamespace String [PDecl' t] -- new namespace
429 | PRecord SyntaxInfo FC Name t Name t -- record declaration
430 | PClass SyntaxInfo FC
433 [(Name, t)] -- parameters
434 [PDecl' t] -- declarations
435 | PInstance SyntaxInfo FC [t] -- constraints
438 t -- full instance type
442 | PDirective (Idris ())
445data PClause' t = PClause FC Name t [t] t [PDecl' t]
446 | PWith FC Name t [t] t [PDecl' t]
447 | PClauseR FC [t] t [PDecl' t]
448 | PWithR FC [t] t [PDecl' t]
451data PData' t = PDatadecl { d_name :: Name,
453 d_cons :: [(Name, t, FC)] }
456-- Handy to get a free function for applying PTerm -> PTerm functions
457-- across a program, by deriving Functor
459type PDecl = PDecl' PTerm
460type PData = PData' PTerm
461type PClause = PClause' PTerm
463-- get all the names declared in a decl
465declared :: PDecl -> [Name]
466declared (PFix _ _ _) = []
467declared (PTy _ _ _ n t) = [n]
468declared (PClauses _ _ n _) = [] -- not a declaration
469declared (PData _ _ (PDatadecl n _ ts)) = n : map fstt ts
470 where fstt (a, _, _) = a
471declared (PParams _ _ ds) = concatMap declared ds
472declared (PNamespace _ ds) = concatMap declared ds
473-- declared (PImport _) = []
475defined :: PDecl -> [Name]
476defined (PFix _ _ _) = []
477defined (PTy _ _ _ n t) = []
478defined (PClauses _ _ n _) = [n] -- not a declaration
479defined (PData _ _ (PDatadecl n _ ts)) = n : map fstt ts
480 where fstt (a, _, _) = a
481defined (PParams _ _ ds) = concatMap defined ds
482defined (PNamespace _ ds) = concatMap defined ds
483-- declared (PImport _) = []
485updateN :: [(Name, Name)] -> Name -> Name
486updateN ns n | Just n' <- lookup n ns = n'
489updateNs :: [(Name, Name)] -> PTerm -> PTerm
491updateNs ns t = mapPT updateRef t
492 where updateRef (PRef fc f) = PRef fc (updateN ns f)
495-- updateDNs :: [(Name, Name)] -> PDecl -> PDecl
497-- updateDNs ns (PTy s f n t) | Just n' <- lookup n ns = PTy s f n' t
498-- updateDNs ns (PClauses f n c) | Just n' <- lookup n ns = PClauses f n' (map updateCNs c)
499-- where updateCNs ns (PClause n l ts r ds)
500-- = PClause (updateN ns n) (fmap (updateNs ns) l)
501-- (map (fmap (updateNs ns)) ts)
502-- (fmap (updateNs ns) r)
503-- (map (updateDNs ns) ds)
506-- High level language terms
508data PTerm = PQuote Raw
510 | PLam Name PTerm PTerm
511 | PPi Plicity Name PTerm PTerm
512 | PLet Name PTerm PTerm PTerm
513 | PTyped PTerm PTerm -- term with explicit type
514 | PApp FC PTerm [PArg]
515 | PCase FC PTerm [(PTerm, PTerm)]
521 | PPair FC PTerm PTerm
522 | PDPair FC PTerm PTerm PTerm
523 | PAlternative [PTerm]
524 | PHidden PTerm -- irrelevant or hidden pattern
533 | PTactics [PTactic] -- as PProof, but no auto solving
534 | PElabError Err -- error to report on elaboration
535 | PImpossible -- special case for declaring when an LHS can't typecheck
538deriving instance Binary PTerm
541mapPT :: (PTerm -> PTerm) -> PTerm -> PTerm
542mapPT f t = f (mpt t) where
543 mpt (PLam n t s) = PLam n (mapPT f t) (mapPT f s)
544 mpt (PPi p n t s) = PPi p n (mapPT f t) (mapPT f s)
545 mpt (PLet n ty v s) = PLet n (mapPT f ty) (mapPT f v) (mapPT f s)
546 mpt (PApp fc t as) = PApp fc (mapPT f t) (map (fmap (mapPT f)) as)
547 mpt (PCase fc c os) = PCase fc (mapPT f c) (map (pmap (mapPT f)) os)
548 mpt (PEq fc l r) = PEq fc (mapPT f l) (mapPT f r)
549 mpt (PTyped l r) = PTyped (mapPT f l) (mapPT f r)
550 mpt (PPair fc l r) = PPair fc (mapPT f l) (mapPT f r)
551 mpt (PDPair fc l t r) = PDPair fc (mapPT f l) (mapPT f t) (mapPT f r)
552 mpt (PAlternative as) = PAlternative (map (mapPT f) as)
553 mpt (PHidden t) = PHidden (mapPT f t)
554 mpt (PDoBlock ds) = PDoBlock (map (fmap (mapPT f)) ds)
555 mpt (PProof ts) = PProof (map (fmap (mapPT f)) ts)
556 mpt (PTactics ts) = PTactics (map (fmap (mapPT f)) ts)
560data PTactic' t = Intro [Name] | Intros | Focus Name
561 | Refine Name [Bool] | Rewrite t | LetTac Name t
562 | Exact t | Compute | Trivial
565 | ProofState | ProofTerm | Undo
566 | Try (PTactic' t) (PTactic' t)
567 | TSeq (PTactic' t) (PTactic' t)
569 deriving (Show, Eq, Functor)
571deriving instance Binary PTactic'
574type PTactic = PTactic' PTerm
576data PDo' t = DoExp FC t
581 deriving (Eq, Functor)
583deriving instance Binary PDo'
588-- The priority gives a hint as to elaboration order. Best to elaborate
589-- things early which will help give a more concrete type to other
590-- variables, e.g. a before (interpTy a).
592data PArg' t = PImp { priority :: Int,
593 lazyarg :: Bool, pname :: Name, getTm :: t }
594 | PExp { priority :: Int,
595 lazyarg :: Bool, getTm :: t }
596 | PConstraint { priority :: Int,
597 lazyarg :: Bool, getTm :: t }
598 | PTacImplicit { priority :: Int,
599 lazyarg :: Bool, pname :: Name,
602 deriving (Show, Eq, Functor)
604deriving instance Binary PArg'
609pconst = PConstraint 0 False
610ptacimp = PTacImplicit 0 True
612type PArg = PArg' PTerm
616data ClassInfo = CI { instanceName :: Name,
617 class_methods :: [(Name, (FnOpts, PTerm))],
618 class_defaults :: [(Name, Name)], -- method name -> default impl
619 class_params :: [Name],
620 class_instances :: [Name] }
623deriving instance Binary ClassInfo
626data OptInfo = Optimise { collapsible :: Bool,
627 forceable :: [Int], -- argument positions
631deriving instance Binary OptInfo
635data TypeInfo = TI { con_names :: [Name] }
638deriving instance Binary TypeInfo
641-- Syntactic sugar info
643data DSL' t = DSL { dsl_bind :: t,
648 index_first :: Maybe t,
649 index_next :: Maybe t,
650 dsl_lambda :: Maybe t,
653 deriving (Show, Functor)
655deriving instance Binary DSL'
660data SynContext = PatternSyntax | TermSyntax | AnySyntax
663deriving instance Binary SynContext
666data Syntax = Rule [SSymbol] PTerm SynContext
669deriving instance Binary Syntax
672data SSymbol = Keyword Name
678deriving instance Binary SSymbol
681initDSL = DSL (PRef f (UN ">>="))
682 (PRef f (UN "return"))
690 where f = FC "(builtin)" 0
692data SyntaxInfo = Syn { using :: [(Name, PTerm)],
693 syn_params :: [(Name, PTerm)],
694 syn_namespace :: [String],
696 decoration :: Name -> Name,
701defaultSyntax = Syn [] [] [] [] id False initDSL
703expandNS :: SyntaxInfo -> Name -> Name
704expandNS syn n@(NS _ _) = n
705expandNS syn n = case syn_namespace syn of
710--- Pretty printing declarations and terms
712instance Show PTerm where
713 show tm = showImp False tm
715instance Show PDecl where
716 show d = showDeclImp False d
718instance Show PClause where
719 show c = showCImp True c
721instance Show PData where
722 show d = showDImp False d
724showDeclImp _ (PFix _ f ops) = show f ++ " " ++ showSep ", " ops
725showDeclImp t (PTy _ _ _ n ty) = show n ++ " : " ++ showImp t ty
726showDeclImp _ (PClauses _ _ n c) = showSep "\n" (map show c)
727showDeclImp _ (PData _ _ d) = show d
729showCImp :: Bool -> PClause -> String
730showCImp impl (PClause _ n l ws r w)
731 = showImp impl l ++ showWs ws ++ " = " ++ showImp impl r
732 ++ " where " ++ show w
735 showWs (x : xs) = " | " ++ showImp impl x ++ showWs xs
736showCImp impl (PWith _ n l ws r w)
737 = showImp impl l ++ showWs ws ++ " with " ++ showImp impl r
738 ++ " { " ++ show w ++ " } "
741 showWs (x : xs) = " | " ++ showImp impl x ++ showWs xs
744showDImp :: Bool -> PData -> String
745showDImp impl (PDatadecl n ty cons)
746 = "data " ++ show n ++ " : " ++ showImp impl ty ++ " where\n\t"
748 (map (\ (n, t, _) -> show n ++ " : " ++ showImp impl t) cons)
750getImps :: [PArg] -> [(Name, PTerm)]
752getImps (PImp _ _ n tm : xs) = (n, tm) : getImps xs
753getImps (_ : xs) = getImps xs
755getExps :: [PArg] -> [PTerm]
757getExps (PExp _ _ tm : xs) = tm : getExps xs
758getExps (_ : xs) = getExps xs
760getConsts :: [PArg] -> [PTerm]
762getConsts (PConstraint _ _ tm : xs) = tm : getConsts xs
763getConsts (_ : xs) = getConsts xs
765getAll :: [PArg] -> [PTerm]
768showImp :: Bool -> PTerm -> String
769showImp impl tm = se 10 tm where
770 se p (PQuote r) = "![" ++ show r ++ "]"
771 se p (PRef fc n) = if impl then show n -- ++ "[" ++ show fc ++ "]"
773 where showbasic n@(UN _) = show n
774 showbasic (MN _ s) = s
775 showbasic (NS n s) = showSep "." (reverse s) ++ "." ++ showbasic n
776 se p (PLam n ty sc) = bracket p 2 $ "\\ " ++ show n ++ " => " ++ show sc
777 se p (PLet n ty v sc) = bracket p 2 $ "let " ++ show n ++ " = " ++ se 10 v ++
779 se p (PPi (Exp l s) n ty sc)
780 | n `elem` allNamesIn sc || impl
782 if l then "|(" else "(" ++
783 show n ++ " : " ++ se 10 ty ++
786 | otherwise = bracket p 2 $ se 0 ty ++ " " ++ st ++ "-> " ++ se 10 sc
788 Static -> "[static] "
790 se p (PPi (Imp l s) n ty sc)
791 | impl = bracket p 2 $ if l then "|{" else "{" ++
792 show n ++ " : " ++ se 10 ty ++
793 "} " ++ st ++ "-> " ++ se 10 sc
794 | otherwise = se 10 sc
796 Static -> "[static] "
798 se p (PPi (Constraint _ _) n ty sc)
799 = bracket p 2 $ se 10 ty ++ " => " ++ se 10 sc
800 se p (PPi (TacImp _ _ s) n ty sc)
801 = bracket p 2 $ "{tacimp " ++ show n ++ " : " ++ se 10 ty ++ "} -> " ++ se 10 sc
802 se p (PApp _ (PRef _ f) [])
804 se p (PApp _ (PRef _ op@(UN (f:_))) args)
805 | length (getExps args) == 2 && not impl && not (isAlpha f)
806 = let [l, r] = getExps args in
807 bracket p 1 $ se 1 l ++ " " ++ show op ++ " " ++ se 0 r
809 = let args = getExps as in
810 bracket p 1 $ se 1 f ++ if impl then concatMap sArg as
811 else concatMap seArg args
812 se p (PCase _ scr opts) = "case " ++ se 10 scr ++ " of " ++ showSep " | " (map sc opts)
813 where sc (l, r) = se 10 l ++ " => " ++ se 10 r
814 se p (PHidden tm) = "." ++ se 0 tm
815 se p (PRefl _) = "refl"
816 se p (PResolveTC _) = "resolvetc"
817 se p (PTrue _) = "()"
818 se p (PFalse _) = "_|_"
819 se p (PEq _ l r) = bracket p 2 $ se 10 l ++ " = " ++ se 10 r
820 se p (PTyped l r) = "(" ++ se 10 l ++ " : " ++ se 10 r ++ ")"
821 se p (PPair _ l r) = "(" ++ se 10 l ++ ", " ++ se 10 r ++ ")"
822 se p (PDPair _ l t r) = "(" ++ se 10 l ++ " ** " ++ se 10 r ++ ")"
823 se p (PAlternative as) = "(|" ++ showSep " , " (map (se 10) as) ++ "|)"
825 se p (PConstant c) = show c
826 se p (PProof ts) = "proof { " ++ show ts ++ "}"
827 se p (PTactics ts) = "tactics { " ++ show ts ++ "}"
828 se p (PMetavar n) = "?" ++ show n
829 se p (PReturn f) = "return"
830 se p PImpossible = "impossible"
831 se p Placeholder = "_"
832 se p (PDoBlock _) = "do block show not implemented"
833 se p (PElabError s) = show s
834-- se p x = "Not implemented"
836 sArg (PImp _ _ n tm) = siArg (n, tm)
837 sArg (PExp _ _ tm) = seArg tm
838 sArg (PConstraint _ _ tm) = scArg tm
839 sArg (PTacImplicit _ _ n _ tm) = stiArg (n, tm)
841 seArg arg = " " ++ se 0 arg
842 siArg (n, val) = " {" ++ show n ++ " = " ++ se 10 val ++ "}"
843 scArg val = " {{" ++ se 10 val ++ "}}"
844 stiArg (n, val) = " {auto " ++ show n ++ " = " ++ se 10 val ++ "}"
846 bracket outer inner str | inner > outer = "(" ++ str ++ ")"
849allNamesIn :: PTerm -> [Name]
850allNamesIn tm = nub $ ni [] tm
853 | not (n `elem` env) = [n]
854 ni env (PApp _ f as) = ni env f ++ concatMap (ni env) (map getTm as)
855 ni env (PCase _ c os) = ni env c ++ concatMap (ni env) (map snd os)
856 ni env (PLam n ty sc) = ni env ty ++ ni (n:env) sc
857 ni env (PPi _ n ty sc) = ni env ty ++ ni (n:env) sc
858 ni env (PHidden tm) = ni env tm
859 ni env (PEq _ l r) = ni env l ++ ni env r
860 ni env (PTyped l r) = ni env l ++ ni env r
861 ni env (PPair _ l r) = ni env l ++ ni env r
862 ni env (PDPair _ (PRef _ n) t r) = ni env t ++ ni (n:env) r
863 ni env (PDPair _ l t r) = ni env l ++ ni env t ++ ni env r
864 ni env (PAlternative ls) = concatMap (ni env) ls
867namesIn :: [(Name, PTerm)] -> IState -> PTerm -> [Name]
868namesIn uvars ist tm = nub $ ni [] tm
872 = case lookupTy Nothing n (tt_ctxt ist) of
874 _ -> if n `elem` (map fst uvars) then [n] else []
875 ni env (PApp _ f as) = ni env f ++ concatMap (ni env) (map getTm as)
876 ni env (PCase _ c os) = ni env c ++ concatMap (ni env) (map snd os)
877 ni env (PLam n ty sc) = ni env ty ++ ni (n:env) sc
878 ni env (PPi _ n ty sc) = ni env ty ++ ni (n:env) sc
879 ni env (PEq _ l r) = ni env l ++ ni env r
880 ni env (PTyped l r) = ni env l ++ ni env r
881 ni env (PPair _ l r) = ni env l ++ ni env r
882 ni env (PDPair _ (PRef _ n) t r) = ni env t ++ ni (n:env) r
883 ni env (PDPair _ l t r) = ni env l ++ ni env t ++ ni env r
884 ni env (PAlternative as) = concatMap (ni env) as
885 ni env (PHidden tm) = ni env tm
888-- For inferring types of things
892inferTy = MN 0 "__Infer"
893inferCon = MN 0 "__infer"
894inferDecl = PDatadecl inferTy
896 [(inferCon, PPi impl (MN 0 "A") PSet (
897 PPi expl (MN 0 "a") (PRef bi (MN 0 "A"))
898 (PRef bi inferTy)), bi)]
900infTerm t = PApp bi (PRef bi inferCon) [pimp (MN 0 "A") Placeholder, pexp t]
901infP = P (TCon 6 0) inferTy (Set (UVal 0))
903getInferTerm, getInferType :: Term -> Term
904getInferTerm (Bind n b sc) = Bind n b $ getInferTerm sc
905getInferTerm (App (App _ _) tm) = tm
906getInferTerm tm = error ("getInferTerm " ++ show tm)
908getInferType (Bind n b sc) = Bind n b $ getInferType sc
909getInferType (App (App _ ty) _) = ty
911-- Handy primitives: Unit, False, Pair, MkPair, =, mkForeign
913primNames = [unitTy, unitCon,
914 falseTy, pairTy, pairCon,
915 eqTy, eqCon, inferTy, inferCon]
917unitTy = MN 0 "__Unit"
919unitDecl = PDatadecl unitTy PSet
920 [(unitCon, PRef bi unitTy, bi)]
922falseTy = MN 0 "__False"
923falseDecl = PDatadecl falseTy PSet []
925pairTy = MN 0 "__Pair"
926pairCon = MN 0 "__MkPair"
927pairDecl = PDatadecl pairTy (piBind [(n "A", PSet), (n "B", PSet)] PSet)
928 [(pairCon, PPi impl (n "A") PSet (
929 PPi impl (n "B") PSet (
930 PPi expl (n "a") (PRef bi (n "A")) (
931 PPi expl (n "b") (PRef bi (n "B"))
932 (PApp bi (PRef bi pairTy) [pexp (PRef bi (n "A")),
933 pexp (PRef bi (n "B"))])))), bi)]
938eqDecl = PDatadecl eqTy (piBind [(n "a", PSet), (n "b", PSet),
939 (n "x", PRef bi (n "a")), (n "y", PRef bi (n "b"))]
941 [(eqCon, PPi impl (n "a") PSet (
942 PPi impl (n "x") (PRef bi (n "a"))
943 (PApp bi (PRef bi eqTy) [pimp (n "a") Placeholder,
944 pimp (n "b") Placeholder,
945 pexp (PRef bi (n "x")),
946 pexp (PRef bi (n "x"))])), bi)]
949-- Defined in builtins.idr
951existsCon = UN "Ex_intro"
953piBind :: [(Name, PTerm)] -> PTerm -> PTerm
955piBind ((n, ty):ns) t = PPi expl n ty (piBind ns t)
957tcname (UN ('@':_)) = True
958tcname (NS n _) = tcname n
961-- Dealing with parameters
963expandParams :: (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PTerm -> PTerm
964expandParams dec ps ns tm = en tm
966 -- if we shadow a name (say in a lambda binding) that is used in a call to
967 -- a lifted function, we need access to both names - once in the scope of the
968 -- binding and once to call the lifted functions. So we'll explicitly shadow
969 -- it. (Yes, it's a hack. The alternative would be to resolve names earlier
972 mkShadow (UN n) = MN 0 n
973 mkShadow (MN i n) = MN (i+1) n
974 mkShadow (NS x s) = NS (mkShadow x) s
977 | n `elem` map fst ps
978 = let n' = mkShadow n in
979 PLam n' (en t) (en (shadow n n' s))
980 | otherwise = PLam n (en t) (en s)
982 | n `elem` map fst ps
983 = let n' = mkShadow n in
984 PPi p n' (en t) (en (shadow n n' s))
985 | otherwise = PPi p n (en t) (en s)
987 | n `elem` map fst ps
988 = let n' = mkShadow n in
989 PLet n' (en ty) (en v) (en (shadow n n' s))
990 | otherwise = PLet n (en ty) (en v) (en s)
991 en (PEq f l r) = PEq f (en l) (en r)
992 en (PTyped l r) = PTyped (en l) (en r)
993 en (PPair f l r) = PPair f (en l) (en r)
994 en (PDPair f l t r) = PDPair f (en l) (en t) (en r)
995 en (PAlternative as) = PAlternative (map en as)
996 en (PHidden t) = PHidden (en t)
997 en (PDoBlock ds) = PDoBlock (map (fmap en) ds)
998 en (PProof ts) = PProof (map (fmap en) ts)
999 en (PTactics ts) = PTactics (map (fmap en) ts)
1002 | n `elem` ns = PQuote (Var (dec n))
1003 en (PApp fc (PRef fc' n) as)
1004 | n `elem` ns = PApp fc (PRef fc' (dec n))
1005 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
1007 | n `elem` ns = PApp fc (PRef fc (dec n))
1008 (map (pexp . (PRef fc)) (map fst ps))
1009 en (PApp fc f as) = PApp fc (en f) (map (fmap en) as)
1010 en (PCase fc c os) = PCase fc (en c) (map (pmap en) os)
1013expandParamsD :: IState ->
1014 (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PDecl -> PDecl
1015expandParamsD ist dec ps ns (PTy syn fc o n ty)
1017 then PTy syn fc o (dec n) (piBind ps (expandParams dec ps ns ty))
1018 else PTy syn fc o n (expandParams dec ps ns ty)
1019expandParamsD ist dec ps ns (PClauses fc opts n cs)
1020 = let n' = if n `elem` ns then dec n else n in
1021 PClauses fc opts n' (map expandParamsC cs)
1023 expandParamsC (PClause fc n lhs ws rhs ds)
1024 = let -- ps' = updateps True (namesIn ist rhs) (zip ps [0..])
1025 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
1026 n' = if n `elem` ns then dec n else n in
1027 PClause fc n' (expandParams dec ps'' ns lhs)
1028 (map (expandParams dec ps'' ns) ws)
1029 (expandParams dec ps'' ns rhs)
1030 (map (expandParamsD ist dec ps'' ns) ds)
1031 expandParamsC (PWith fc n lhs ws wval ds)
1032 = let -- ps' = updateps True (namesIn ist wval) (zip ps [0..])
1033 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
1034 n' = if n `elem` ns then dec n else n in
1035 PWith fc n' (expandParams dec ps'' ns lhs)
1036 (map (expandParams dec ps'' ns) ws)
1037 (expandParams dec ps'' ns wval)
1038 (map (expandParamsD ist dec ps'' ns) ds)
1039 updateps yn nm [] = []
1040 updateps yn nm (((a, t), i):as)
1041 | (a `elem` nm) == yn = (a, t) : updateps yn nm as
1042 | otherwise = (MN i (show n ++ "_u"), t) : updateps yn nm as
1044expandParamsD ist dec ps ns d = d
1046-- Calculate a priority for a type, for deciding elaboration order
1047-- * if it's just a type variable or concrete type, do it early (0)
1048-- * if there's only type variables and injective constructors, do it next (1)
1049-- * if there's a function type, next (2)
1050-- * finally, everything else (3)
1052getPriority :: IState -> PTerm -> Int
1053getPriority i tm = pri tm
1056 case lookupP Nothing n (tt_ctxt i) of
1057 ((P (DCon _ _) _ _):_) -> 1
1058 ((P (TCon _ _) _ _):_) -> 1
1059 ((P Ref _ _):_) -> 4
1060 [] -> 0 -- must be locally bound, if it's not an error...
1061 pri (PPi _ _ x y) = max 5 (max (pri x) (pri y))
1065 pri (PEq _ l r) = max 1 (max (pri l) (pri r))
1066 pri (PApp _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.getTm) as)))
1067 pri (PCase _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.snd) as)))
1068 pri (PTyped l r) = pri l
1069 pri (PPair _ l r) = max 1 (max (pri l) (pri r))
1070 pri (PDPair _ l t r) = max 1 (max (pri l) (max (pri t) (pri r)))
1071 pri (PAlternative as) = maximum (map pri as)
1072 pri (PConstant _) = 0
1076addStatics :: Name -> Term -> PTerm -> Idris ()
1077addStatics n tm ptm =
1078 do let (statics, dynamics) = initStatics tm ptm
1079 let stnames = nub $ concatMap freeNames (map snd statics)
1080 let dnames = nub $ concatMap freeNames (map snd dynamics)
1081 when (not (null statics)) $
1082 logLvl 7 $ show n ++ " " ++ show statics ++ "\n" ++ show dynamics
1083 ++ "\n" ++ show stnames ++ "\n" ++ show dnames
1084 let statics' = nub $ map fst statics ++
1085 filter (\x -> not (elem x dnames)) stnames
1086 let stpos = staticList statics' tm
1088 put (i { idris_statics = addDef n stpos (idris_statics i) })
1089 addIBC (IBCStatic n)
1091 initStatics (Bind n (Pi ty) sc) (PPi p _ _ s)
1092 = let (static, dynamic) = initStatics (instantiate (P Bound n ty) sc) s in
1093 if pstatic p == Static then ((n, ty) : static, dynamic)
1094 else (static, (n, ty) : dynamic)
1095 initStatics t pt = ([], [])
1097 staticList sts (Bind n (Pi _) sc) = (n `elem` sts) : staticList sts sc
1100-- Dealing with implicit arguments
1102-- Add implicit Pi bindings for any names in the term which appear in an
1103-- argument position.
1105-- This has become a right mess already. Better redo it some time...
1107implicit :: SyntaxInfo -> Name -> PTerm -> Idris PTerm
1110 let (tm', impdata) = implicitise syn i ptm
1111-- let (tm'', spos) = findStatics i tm'
1112 put (i { idris_implicits = addDef n impdata (idris_implicits i) })
1114 logLvl 5 ("Implicit " ++ show n ++ " " ++ show impdata)
1116-- put (i { idris_statics = addDef n spos (idris_statics i) })
1119implicitise :: SyntaxInfo -> IState -> PTerm -> (PTerm, [PArg])
1120implicitise syn ist tm
1121 = let (declimps, ns') = execState (imps True [] tm) ([], [])
1122 ns = ns' \\ (map fst pvars ++ no_imp syn) in
1124 then (tm, reverse declimps)
1125 else implicitise syn ist (pibind uvars ns tm)
1128 pvars = syn_params syn
1130 dropAll (x:xs) ys | x `elem` ys = dropAll xs ys
1131 | otherwise = x : dropAll xs ys
1134 imps top env (PApp _ f as)
1135 = do (decls, ns) <- get
1136 let isn = concatMap (namesIn uvars ist) (map getTm as)
1137 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1138 imps top env (PPi (Imp l _) n ty sc)
1139 = do let isn = nub (namesIn uvars ist ty) `dropAll` [n]
1141 put (PImp (getPriority ist ty) l n ty : decls,
1142 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1143 imps True (n:env) sc
1144 imps top env (PPi (Exp l _) n ty sc)
1145 = do let isn = nub (namesIn uvars ist ty ++ case sc of
1146 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1148 (decls, ns) <- get -- ignore decls in HO types
1149 put (PExp (getPriority ist ty) l ty : decls,
1150 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1151 imps True (n:env) sc
1152 imps top env (PPi (Constraint l _) n ty sc)
1153 = do let isn = nub (namesIn uvars ist ty ++ case sc of
1154 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1156 (decls, ns) <- get -- ignore decls in HO types
1157 put (PConstraint 10 l ty : decls,
1158 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1159 imps True (n:env) sc
1160 imps top env (PPi (TacImp l _ scr) n ty sc)
1161 = do let isn = nub (namesIn uvars ist ty ++ case sc of
1162 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1164 (decls, ns) <- get -- ignore decls in HO types
1165 put (PTacImplicit 10 l n scr ty : decls,
1166 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1167 imps True (n:env) sc
1168 imps top env (PEq _ l r)
1169 = do (decls, ns) <- get
1170 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1171 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1172 imps top env (PTyped l r)
1174 imps top env (PPair _ l r)
1175 = do (decls, ns) <- get
1176 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1177 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1178 imps top env (PDPair _ (PRef _ n) t r)
1179 = do (decls, ns) <- get
1180 let isn = nub (namesIn uvars ist t ++ namesIn uvars ist r) \\ [n]
1181 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1182 imps top env (PDPair _ l t r)
1183 = do (decls, ns) <- get
1184 let isn = namesIn uvars ist l ++ namesIn uvars ist t ++
1186 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1187 imps top env (PAlternative as)
1188 = do (decls, ns) <- get
1189 let isn = concatMap (namesIn uvars ist) as
1190 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1191 imps top env (PLam n ty sc)
1192 = do imps False env ty
1193 imps False (n:env) sc
1194 imps top env (PHidden tm) = imps False env tm
1195 imps top env _ = return ()
1197 pibind using [] sc = sc
1198 pibind using (n:ns) sc
1199 = case lookup n using of
1200 Just ty -> PPi (Imp False Dynamic) n ty (pibind using ns sc)
1201 Nothing -> PPi (Imp False Dynamic) n Placeholder (pibind using ns sc)
1203-- Add implicit arguments in function calls
1204addImplPat :: IState -> PTerm -> PTerm
1205addImplPat = addImpl' True []
1207addImplBound :: IState -> [Name] -> PTerm -> PTerm
1208addImplBound ist ns = addImpl' False ns ist
1210addImpl :: IState -> PTerm -> PTerm
1211addImpl = addImpl' False []
1213-- TODO: in patterns, don't add implicits to function names guarded by constructors
1214-- and *not* inside a PHidden
1216addImpl' :: Bool -> [Name] -> IState -> PTerm -> PTerm
1217addImpl' inpat env ist ptm = ai env ptm
1220 | not (f `elem` env) = handleErr $ aiFn inpat ist fc f []
1221 ai env (PHidden (PRef fc f))
1222 | not (f `elem` env) = handleErr $ aiFn False ist fc f []
1223 ai env (PEq fc l r) = let l' = ai env l
1226 ai env (PTyped l r) = let l' = ai env l
1229 ai env (PPair fc l r) = let l' = ai env l
1232 ai env (PDPair fc l t r) = let l' = ai env l
1236 ai env (PAlternative as) = let as' = map (ai env) as in
1238 ai env (PApp fc (PRef _ f) as)
1239 | not (f `elem` env)
1240 = let as' = map (fmap (ai env)) as in
1241 handleErr $ aiFn False ist fc f as'
1242 ai env (PApp fc f as) = let f' = ai env f
1243 as' = map (fmap (ai env)) as in
1245 ai env (PCase fc c os) = let c' = ai env c
1246 os' = map (pmap (ai env)) os in
1248 ai env (PLam n ty sc) = let ty' = ai env ty
1249 sc' = ai (n:env) sc in
1251 ai env (PLet n ty val sc)
1252 = let ty' = ai env ty
1254 sc' = ai (n:env) sc in
1256 ai env (PPi p n ty sc) = let ty' = ai env ty
1257 sc' = ai (n:env) sc in
1259 ai env (PHidden tm) = PHidden (ai env tm)
1260 ai env (PProof ts) = PProof (map (fmap (ai env)) ts)
1261 ai env (PTactics ts) = PTactics (map (fmap (ai env)) ts)
1264 handleErr (Left err) = PElabError err
1265 handleErr (Right x) = x
1267-- if in a pattern, and there are no arguments, and there's no possible
1268-- names with zero explicit arguments, don't add implicits.
1270aiFn :: Bool -> IState -> FC -> Name -> [PArg] -> Either Err PTerm
1271aiFn True ist fc f []
1272 = case lookupCtxt Nothing f (idris_implicits ist) of
1273 [] -> Right $ PRef fc f
1274 alts -> if (any (all imp) alts)
1275 then aiFn False ist fc f [] -- use it as a constructor
1276 else Right $ PRef fc f
1277 where imp (PExp _ _ _) = False
1279aiFn inpat ist fc f as
1280 | f `elem` primNames = Right $ PApp fc (PRef fc f) as
1281aiFn inpat ist fc f as
1282 -- This is where namespaces get resolved by adding PAlternative
1283 = case lookupCtxtName Nothing f (idris_implicits ist) of
1284 [(f',ns)] -> Right $ mkPApp fc (length ns) (PRef fc f') (insertImpl ns as)
1285 [] -> if f `elem` idris_metavars ist
1286 then Right $ PApp fc (PRef fc f) as
1287 else Right $ mkPApp fc (length as) (PRef fc f) as
1290 map (\(f', ns) -> mkPApp fc (length ns) (PRef fc f')
1291 (insertImpl ns as)) alts
1293 insertImpl :: [PArg] -> [PArg] -> [PArg]
1294 insertImpl (PExp p l ty : ps) (PExp _ _ tm : given) =
1295 PExp p l tm : insertImpl ps given
1296 insertImpl (PConstraint p l ty : ps) (PConstraint _ _ tm : given) =
1297 PConstraint p l tm : insertImpl ps given
1298 insertImpl (PConstraint p l ty : ps) given =
1299 PConstraint p l (PResolveTC fc) : insertImpl ps given
1300 insertImpl (PImp p l n ty : ps) given =
1301 case find n given [] of
1302 Just (tm, given') -> PImp p l n tm : insertImpl ps given'
1303 Nothing -> PImp p l n Placeholder : insertImpl ps given
1304 insertImpl (PTacImplicit p l n sc ty : ps) given =
1305 case find n given [] of
1306 Just (tm, given') -> PTacImplicit p l n sc tm : insertImpl ps given'
1307 Nothing -> PTacImplicit p l n sc sc
1308 : insertImpl ps given
1309 insertImpl expected [] = []
1310 insertImpl _ given = given
1312 find n [] acc = Nothing
1313 find n (PImp _ _ n' t : gs) acc
1314 | n == n' = Just (t, reverse acc ++ gs)
1315 find n (g : gs) acc = find n gs (g : acc)
1318mkPApp fc a f as = let rest = drop a as in
1319 appRest fc (PApp fc f (take a as)) rest
1322 appRest fc f (a : as) = appRest fc (PApp fc f [a]) as
1324-- Find 'static' argument positions
1325-- (the declared ones, plus any names in argument position in the declared
1327-- FIXME: It's possible that this really has to happen after elaboration
1329findStatics :: IState -> PTerm -> (PTerm, [Bool])
1330findStatics ist tm = trace (showImp True tm) $
1331 let (ns, ss) = fs tm in
1332 runState (pos ns ss tm) []
1333 where fs (PPi p n t sc)
1334 | Static <- pstatic p
1335 = let (ns, ss) = fs sc in
1336 (namesIn [] ist t : ns, n : ss)
1337 | otherwise = let (ns, ss) = fs sc in
1341 inOne n ns = length (filter id (map (elem n) ns)) == 1
1343 pos ns ss (PPi p n t sc)
1344 | elem n ss = do sc' <- pos ns ss sc
1347 return (PPi (p { pstatic = Static }) n t sc')
1348 | otherwise = do sc' <- pos ns ss sc
1351 return (PPi p n t sc')
1352 pos ns ss t = return t
1354-- Debugging/logging stuff
1356dumpDecls :: [PDecl] -> String
1358dumpDecls (d:ds) = dumpDecl d ++ "\n" ++ dumpDecls ds
1360dumpDecl (PFix _ f ops) = show f ++ " " ++ showSep ", " ops
1361dumpDecl (PTy _ _ _ n t) = "tydecl " ++ show n ++ " : " ++ showImp True t
1362dumpDecl (PClauses _ _ n cs) = "pat " ++ show n ++ "\t" ++ showSep "\n\t" (map (showCImp True) cs)
1363dumpDecl (PData _ _ d) = showDImp True d
1364dumpDecl (PParams _ ns ps) = "params {" ++ show ns ++ "\n" ++ dumpDecls ps ++ "}\n"
1365dumpDecl (PNamespace n ps) = "namespace {" ++ n ++ "\n" ++ dumpDecls ps ++ "}\n"
1366dumpDecl (PSyntax _ syn) = "syntax " ++ show syn
1367dumpDecl (PClass _ _ cs n ps ds)
1368 = "class " ++ show cs ++ " " ++ show n ++ " " ++ show ps ++ "\n" ++ dumpDecls ds
1369dumpDecl (PInstance _ _ cs n _ t ds)
1370 = "instance " ++ show cs ++ " " ++ show n ++ " " ++ show t ++ "\n" ++ dumpDecls ds
1372-- dumpDecl (PImport i) = "import " ++ i
1374-- for 6.12/7 compatibility
1375data EitherErr a b = LeftErr a | RightOK b
1377instance Monad (EitherErr a) where
1380 (LeftErr e) >>= k = LeftErr e
1381 RightOK v >>= k = k v
1383toEither (LeftErr e) = Left e
1384toEither (RightOK ho) = Right ho
1386-- syntactic match of a against b, returning pair of variables in a
1387-- and what they match. Returns the pair that failed if not a match.
1389matchClause :: IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
1390matchClause = matchClause' False
1392matchClause' :: Bool -> IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
1393matchClause' names i x y = checkRpts $ match (fullApp x) (fullApp y) where
1394 matchArg x y = match (fullApp (getTm x)) (fullApp (getTm y))
1396 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
1399 match' x y = match (fullApp x) (fullApp y)
1400 match (PApp _ (PRef _ (NS (UN "fromInteger") ["builtins"])) [_,_,x]) x'
1401 | PConstant (I _) <- getTm x = match (getTm x) x'
1402 match x' (PApp _ (PRef _ (NS (UN "fromInteger") ["builtins"])) [_,_,x])
1403 | PConstant (I _) <- getTm x = match (getTm x) x'
1404 match (PApp _ (PRef _ (UN "lazy")) [_,x]) x' = match (getTm x) x'
1405 match x (PApp _ (PRef _ (UN "lazy")) [_,x']) = match x (getTm x')
1406 match (PApp _ f args) (PApp _ f' args')
1407 | length args == length args'
1408 = do mf <- match' f f'
1409 ms <- zipWithM matchArg args args'
1410 return (mf ++ concat ms)
1411-- match (PRef _ n) (PRef _ n') | n == n' = return []
1412-- | otherwise = Nothing
1413 match (PRef f n) (PApp _ x []) = match (PRef f n) x
1414 match (PApp _ x []) (PRef f n) = match x (PRef f n)
1415 match (PRef _ n) (PRef _ n') | n == n' = return []
1417 | not names && (not (isConName Nothing n (tt_ctxt i)) || tm == Placeholder)
1419 match (PEq _ l r) (PEq _ l' r') = do ml <- match' l l'
1422 match (PTyped l r) (PTyped l' r') = do ml <- match l l'
1425 match (PTyped l r) x = match l x
1426 match x (PTyped l r) = match x l
1427 match (PPair _ l r) (PPair _ l' r') = do ml <- match' l l'
1430 match (PDPair _ l t r) (PDPair _ l' t' r') = do ml <- match' l l'
1433 return (ml ++ mt ++ mr)
1434 match (PAlternative as) (PAlternative as')
1435 = do ms <- zipWithM match' as as'
1437 match a@(PAlternative as) b
1438 = do let ms = zipWith match' as (repeat b)
1439 case (rights (map toEither ms)) of
1442 match (PCase _ _ _) _ = return [] -- lifted out
1443 match (PMetavar _) _ = return [] -- modified
1444 match (PQuote _) _ = return []
1445 match (PProof _) _ = return []
1446 match (PTactics _) _ = return []
1447 match (PRefl _) (PRefl _) = return []
1448 match (PResolveTC _) (PResolveTC _) = return []
1449 match (PTrue _) (PTrue _) = return []
1450 match (PFalse _) (PFalse _) = return []
1451 match (PReturn _) (PReturn _) = return []
1452 match (PPi _ _ t s) (PPi _ _ t' s') = do mt <- match' t t'
1455 match (PLam _ t s) (PLam _ t' s') = do mt <- match' t t'
1458 match (PLet _ t ty s) (PLet _ t' ty' s') = do mt <- match' t t'
1459 mty <- match' ty ty'
1461 return (mt ++ mty ++ ms)
1462 match (PHidden x) (PHidden y) = match' x y
1463 match Placeholder _ = return []
1464-- match _ Placeholder = return []
1465 match (PResolveTC _) _ = return []
1466 match a b | a == b = return []
1467 | otherwise = LeftErr (a, b)
1469 checkRpts (RightOK ms) = check ms where
1471 | Just t' <- lookup n xs = if t/=t' && t/=Placeholder && t'/=Placeholder
1474 check (_:xs) = check xs
1476 checkRpts (LeftErr x) = Left x
1478substMatches :: [(Name, PTerm)] -> PTerm -> PTerm
1479substMatches [] t = t
1480substMatches ((n,tm):ns) t = substMatch n tm (substMatches ns t)
1482substMatch :: Name -> PTerm -> PTerm -> PTerm
1483substMatch n tm t = sm t where
1484 sm (PRef _ n') | n == n' = tm
1485 sm (PLam x t sc) = PLam x (sm t) (sm sc)
1486 sm (PPi p x t sc) = PPi p x (sm t) (sm sc)
1487 sm (PApp f x as) = PApp f (sm x) (map (fmap sm) as)
1488 sm (PCase f x as) = PCase f (sm x) (map (pmap sm) as)
1489 sm (PEq f x y) = PEq f (sm x) (sm y)
1490 sm (PTyped x y) = PTyped (sm x) (sm y)
1491 sm (PPair f x y) = PPair f (sm x) (sm y)
1492 sm (PDPair f x t y) = PDPair f (sm x) (sm t) (sm y)
1493 sm (PAlternative as) = PAlternative (map sm as)
1494 sm (PHidden x) = PHidden (sm x)
1497shadow :: Name -> Name -> PTerm -> PTerm
1498shadow n n' t = sm t where
1499 sm (PRef fc x) | n == x = PRef fc n'
1500 sm (PLam x t sc) = PLam x (sm t) (sm sc)
1501 sm (PPi p x t sc) = PPi p x (sm t) (sm sc)
1502 sm (PApp f x as) = PApp f (sm x) (map (fmap sm) as)
1503 sm (PCase f x as) = PCase f (sm x) (map (pmap sm) as)
1504 sm (PEq f x y) = PEq f (sm x) (sm y)
1505 sm (PTyped x y) = PTyped (sm x) (sm y)
1506 sm (PPair f x y) = PPair f (sm x) (sm y)
1507 sm (PDPair f x t y) = PDPair f (sm x) (sm t) (sm y)
1508 sm (PAlternative as) = PAlternative (map sm as)
1509 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