1{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, DeriveFunctor,
2 TypeSynonymInstances, PatternGuards #-}
4module Idris.AbsSyntax where
8import Core.Elaborate hiding (Tactic(..))
13import System.Console.Haskeline
15import Control.Monad.State
23import qualified Epic.Epic as E
27data IOption = IOption { opt_logLevel :: Int,
29 opt_typeintype :: Bool,
34 opt_ibcsubdir :: FilePath,
35 opt_importdirs :: [FilePath]
39defaultOpts = IOption 0 False False True False True True "" []
41-- TODO: Add 'module data' to IState, which can be saved out and reloaded quickly (i.e
42-- without typechecking).
43-- This will include all the functions and data declarations, plus fixity declarations
46data IState = IState { tt_ctxt :: Context,
47 idris_constraints :: [(UConstraint, FC)],
48 idris_infixes :: [FixDecl],
49 idris_implicits :: Ctxt [PArg],
50 idris_statics :: Ctxt [Bool],
51 idris_classes :: Ctxt ClassInfo,
52 idris_dsls :: Ctxt DSL,
53 idris_optimisation :: Ctxt OptInfo,
54 idris_datatypes :: Ctxt TypeInfo,
55 idris_patdefs :: Ctxt [([Name], Term, Term)], -- not exported
56 idris_flags :: Ctxt [FnOpt],
57 idris_callgraph :: Ctxt [Name],
58 idris_totcheck :: [(FC, Name)],
60 idris_options :: IOption,
62 idris_metavars :: [Name],
63 syntax_rules :: [Syntax],
64 syntax_keywords :: [String],
65 imported :: [FilePath],
66 idris_prims :: [(Name, ([E.Name], E.Term))],
67 idris_objs :: [FilePath],
68 idris_libs :: [String],
69 idris_hdrs :: [String],
70 last_proof :: Maybe (Name, [String]),
72 lastParse :: Maybe Name,
73 indent_stack :: [Int],
74 brace_stack :: [Maybe Int],
75 hide_list :: [(Name, Maybe Accessibility)],
76 default_access :: Accessibility,
77 ibc_write :: [IBCWrite],
78 compiled_so :: Maybe String
81-- information that needs writing for the current module's .ibc file
82data IBCWrite = IBCFix FixDecl
86 | IBCInstance Bool Name Name
96 | IBCAccess Name Accessibility
97 | IBCTotal Name Totality
98 | IBCFlags Name [FnOpt]
100 | IBCDef Name -- i.e. main context
103idrisInit = IState initContext [] [] emptyContext emptyContext emptyContext
104 emptyContext emptyContext emptyContext emptyContext
105 emptyContext emptyContext
106 [] "" defaultOpts 6 [] [] [] [] [] [] [] []
107 Nothing Nothing Nothing [] [] [] Hidden [] Nothing
109-- The monad for the main REPL - reading and processing files and updating
110-- global state (hence the IO inner monad).
111type Idris = StateT IState (InputT IO)
113getContext :: Idris Context
114getContext = do i <- get; return (tt_ctxt i)
116getObjectFiles :: Idris [FilePath]
117getObjectFiles = do i <- get; return (idris_objs i)
119addObjectFile :: FilePath -> Idris ()
120addObjectFile f = do i <- get; put (i { idris_objs = f : idris_objs i })
122getLibs :: Idris [String]
123getLibs = do i <- get; return (idris_libs i)
125addLib :: String -> Idris ()
126addLib f = do i <- get; put (i { idris_libs = f : idris_libs i })
128addHdr :: String -> Idris ()
129addHdr f = do i <- get; put (i { idris_hdrs = f : idris_hdrs i })
131totcheck :: (FC, Name) -> Idris ()
132totcheck n = do i <- get; put (i { idris_totcheck = n : idris_totcheck i })
134setFlags :: Name -> [FnOpt] -> Idris ()
135setFlags n fs = do i <- get; put (i { idris_flags = addDef n fs (idris_flags i) })
137setAccessibility :: Name -> Accessibility -> Idris ()
140 let ctxt = setAccess n a (tt_ctxt i)
141 put (i { tt_ctxt = ctxt })
143setTotality :: Name -> Totality -> Idris ()
146 let ctxt = setTotal n a (tt_ctxt i)
147 put (i { tt_ctxt = ctxt })
149getTotality :: Name -> Idris Totality
152 case lookupTotal n (tt_ctxt i) of
154 _ -> return (Total [])
156addToCG :: Name -> [Name] -> Idris ()
157addToCG n ns = do i <- get
158 put (i { idris_callgraph = addDef n ns (idris_callgraph i) })
160-- Add a class instance function. Dodgy hack: Put integer instances first in the
161-- list so they are resolved by default.
163addInstance :: Bool -> Name -> Name -> Idris ()
166 case lookupCtxt Nothing n (idris_classes ist) of
168 do let cs = addDef n (CI a b c d (addI i ins)) (idris_classes ist)
169 put (ist { idris_classes = cs })
170 _ -> do let cs = addDef n (CI (MN 0 "none") [] [] [] [i]) (idris_classes ist)
171 put (ist { idris_classes = cs })
172 where addI i ins | int = i : ins
173 | otherwise = ins ++ [i]
175addClass :: Name -> ClassInfo -> Idris ()
178 let i' = case lookupCtxt Nothing n (idris_classes ist) of
179 [c] -> c { class_instances = class_instances i }
181 put (ist { idris_classes = addDef n i' (idris_classes ist) })
183addIBC :: IBCWrite -> Idris ()
186 when (notDef (ibc_write i)) $
187 put (i { ibc_write = ibc : ibc_write i })
188 where notDef [] = True
189 notDef (IBCDef n': is) | n == n' = False
190 notDef (_ : is) = notDef is
191addIBC ibc = do i <- get; put (i { ibc_write = ibc : ibc_write i })
194clearIBC = do i <- get; put (i { ibc_write = [] })
196getHdrs :: Idris [String]
197getHdrs = do i <- get; return (idris_hdrs i)
199setErrLine :: Int -> Idris ()
200setErrLine x = do i <- get;
202 Nothing -> put (i { errLine = Just x })
206clearErr = do i <- get
207 put (i { errLine = Nothing })
209getSO :: Idris (Maybe String)
211 return (compiled_so i)
213setSO :: Maybe String -> Idris ()
215 put (i { compiled_so = s })
217getIState :: Idris IState
220putIState :: IState -> Idris ()
224getName = do i <- get;
225 let idx = idris_name i;
226 put (i { idris_name = idx + 1 })
229checkUndefined :: FC -> Name -> Idris ()
232 case lookupTy Nothing n i of
233 (_:_) -> fail $ show fc ++ ":" ++
234 show n ++ " already defined"
237setContext :: Context -> Idris ()
238setContext ctxt = do i <- get; put (i { tt_ctxt = ctxt } )
240updateContext :: (Context -> Context) -> Idris ()
241updateContext f = do i <- get; put (i { tt_ctxt = f (tt_ctxt i) } )
243addConstraints :: FC -> (Int, [UConstraint]) -> Idris ()
244addConstraints fc (v, cs)
247 let ctxt' = ctxt { uconstraints = cs ++ uconstraints ctxt,
249 let ics = zip cs (repeat fc) ++ idris_constraints i
250 put (i { tt_ctxt = ctxt', idris_constraints = ics })
252addDeferred :: [(Name, Type)] -> Idris ()
253addDeferred ns = do mapM_ (\(n, t) -> updateContext (addTyDecl n (tidyNames [] t))) ns
255 put (i { idris_metavars = map fst ns ++ idris_metavars i })
256 where tidyNames used (Bind (MN i x) b sc)
257 = let n' = uniqueName (UN x) used in
258 Bind n' b $ tidyNames (n':used) sc
259 tidyNames used (Bind n b sc)
260 = let n' = uniqueName n used in
261 Bind n' b $ tidyNames (n':used) sc
264solveDeferred :: Name -> Idris ()
265solveDeferred n = do i <- get
266 put (i { idris_metavars = idris_metavars i \\ [n] })
268iputStrLn :: String -> Idris ()
269iputStrLn = liftIO . putStrLn
271iWarn :: FC -> String -> Idris ()
272iWarn fc err = liftIO $ putStrLn (show fc ++ ":" ++ err)
274setLogLevel :: Int -> Idris ()
275setLogLevel l = do i <- get
276 let opts = idris_options i
277 let opt' = opts { opt_logLevel = l }
278 put (i { idris_options = opt' } )
281logLevel = do i <- get
282 return (opt_logLevel (idris_options i))
286 return (opt_repl (idris_options i))
288setREPL :: Bool -> Idris ()
289setREPL t = do i <- get
290 let opts = idris_options i
291 let opt' = opts { opt_repl = t }
292 put (i { idris_options = opt' })
296 return (opt_verbose (idris_options i))
298setVerbose :: Bool -> Idris ()
299setVerbose t = do i <- get
300 let opts = idris_options i
301 let opt' = opts { opt_verbose = t }
302 put (i { idris_options = opt' })
304typeInType :: Idris Bool
305typeInType = do i <- get
306 return (opt_typeintype (idris_options i))
308setTypeInType :: Bool -> Idris ()
309setTypeInType t = do i <- get
310 let opts = idris_options i
311 let opt' = opts { opt_typeintype = t }
312 put (i { idris_options = opt' })
314coverage :: Idris Bool
315coverage = do i <- get
316 return (opt_coverage (idris_options i))
318setCoverage :: Bool -> Idris ()
319setCoverage t = do i <- get
320 let opts = idris_options i
321 let opt' = opts { opt_coverage = t }
322 put (i { idris_options = opt' })
324setIBCSubDir :: FilePath -> Idris ()
325setIBCSubDir fp = do i <- get
326 let opts = idris_options i
327 let opt' = opts { opt_ibcsubdir = fp }
328 put (i { idris_options = opt' })
330valIBCSubDir :: IState -> Idris FilePath
331valIBCSubDir i = return (opt_ibcsubdir (idris_options i))
333setImportDirs :: [FilePath] -> Idris ()
334setImportDirs fps = do i <- get
335 let opts = idris_options i
336 let opt' = opts { opt_importdirs = fps }
337 put (i { idris_options = opt' })
339allImportDirs :: IState -> Idris [FilePath]
340allImportDirs i = do datadir <- liftIO $ getDataDir
341 let optdirs = opt_importdirs (idris_options i)
342 return ("." : (optdirs ++ [datadir]))
346 return (opt_showimp (idris_options i))
348setImpShow :: Bool -> Idris ()
349setImpShow t = do i <- get
350 let opts = idris_options i
351 let opt' = opts { opt_showimp = t }
352 put (i { idris_options = opt' })
354logLvl :: Int -> String -> Idris ()
355logLvl l str = do i <- get
356 let lvl = opt_logLevel (idris_options i)
358 $ do liftIO (putStrLn str)
359 put (i { idris_log = idris_log i ++ str ++ "\n" } )
361iLOG :: String -> Idris ()
364noErrors :: Idris Bool
365noErrors = do i <- get
367 Nothing -> return True
370setTypeCase :: Bool -> Idris ()
371setTypeCase t = do i <- get
372 let opts = idris_options i
373 let opt' = opts { opt_typecase = t }
374 put (i { idris_options = opt' })
376-- Commands in the REPL
378data Command = Quit | Help | Eval PTerm | Check PTerm | TotCheck Name
380 | Compile String | Execute | ExecVal PTerm
381 | Metavars | Prove Name | AddProof | Universes
383 | LogLvl Int | Spec PTerm | HNF PTerm | Defn Name
384 | Info Name | DebugInfo Name
388-- Parsed declarations
390data Fixity = Infixl { prec :: Int }
391 | Infixr { prec :: Int }
392 | InfixN { prec :: Int }
393 | PrefixN { prec :: Int }
396deriving instance Binary Fixity
399instance Show Fixity where
400 show (Infixl i) = "infixl " ++ show i
401 show (Infixr i) = "infixr " ++ show i
402 show (InfixN i) = "infix " ++ show i
403 show (PrefixN i) = "prefix " ++ show i
405data FixDecl = Fix Fixity String
408deriving instance Binary FixDecl
411instance Ord FixDecl where
412 compare (Fix x _) (Fix y _) = compare (prec x) (prec y)
415data Static = Static | Dynamic
418deriving instance Binary Static
421-- Mark bindings with their explicitness, and laziness
422data Plicity = Imp { plazy :: Bool,
424 | Exp { plazy :: Bool,
426 | Constraint { plazy :: Bool,
428 | TacImp { plazy :: Bool,
434deriving instance Binary Plicity
437impl = Imp False Dynamic
438expl = Exp False Dynamic
439constraint = Constraint False Dynamic
440tacimpl = TacImp False Dynamic
442data FnOpt = Inlinable | TotalFn | AssertTotal | TCGen
443 | Specialise [Name] -- specialise it, freeze these names
446deriving instance Binary FnOpt
451inlinable :: FnOpts -> Bool
452inlinable = elem Inlinable
454data PDecl' t = PFix FC Fixity [String] -- fixity declaration
455 | PTy SyntaxInfo FC FnOpts Name t -- type declaration
456 | PClauses FC FnOpts Name [PClause' t] -- pattern clause
457 | PData SyntaxInfo FC (PData' t) -- data declaration
458 | PParams FC [(Name, t)] [PDecl' t] -- params block
459 | PNamespace String [PDecl' t] -- new namespace
460 | PRecord SyntaxInfo FC Name t Name t -- record declaration
461 | PClass SyntaxInfo FC
464 [(Name, t)] -- parameters
465 [PDecl' t] -- declarations
466 | PInstance SyntaxInfo FC [t] -- constraints
469 t -- full instance type
473 | PDirective (Idris ())
476data PClause' t = PClause FC Name t [t] t [PDecl' t]
477 | PWith FC Name t [t] t [PDecl' t]
478 | PClauseR FC [t] t [PDecl' t]
479 | PWithR FC [t] t [PDecl' t]
482data PData' t = PDatadecl { d_name :: Name,
484 d_cons :: [(Name, t, FC)] }
487-- Handy to get a free function for applying PTerm -> PTerm functions
488-- across a program, by deriving Functor
490type PDecl = PDecl' PTerm
491type PData = PData' PTerm
492type PClause = PClause' PTerm
494-- get all the names declared in a decl
496declared :: PDecl -> [Name]
497declared (PFix _ _ _) = []
498declared (PTy _ _ _ n t) = [n]
499declared (PClauses _ _ n _) = [] -- not a declaration
500declared (PData _ _ (PDatadecl n _ ts)) = n : map fstt ts
501 where fstt (a, _, _) = a
502declared (PParams _ _ ds) = concatMap declared ds
503declared (PNamespace _ ds) = concatMap declared ds
504-- declared (PImport _) = []
506defined :: PDecl -> [Name]
507defined (PFix _ _ _) = []
508defined (PTy _ _ _ n t) = []
509defined (PClauses _ _ n _) = [n] -- not a declaration
510defined (PData _ _ (PDatadecl n _ ts)) = n : map fstt ts
511 where fstt (a, _, _) = a
512defined (PParams _ _ ds) = concatMap defined ds
513defined (PNamespace _ ds) = concatMap defined ds
514-- declared (PImport _) = []
516updateN :: [(Name, Name)] -> Name -> Name
517updateN ns n | Just n' <- lookup n ns = n'
520updateNs :: [(Name, Name)] -> PTerm -> PTerm
522updateNs ns t = mapPT updateRef t
523 where updateRef (PRef fc f) = PRef fc (updateN ns f)
526-- updateDNs :: [(Name, Name)] -> PDecl -> PDecl
528-- updateDNs ns (PTy s f n t) | Just n' <- lookup n ns = PTy s f n' t
529-- updateDNs ns (PClauses f n c) | Just n' <- lookup n ns = PClauses f n' (map updateCNs c)
530-- where updateCNs ns (PClause n l ts r ds)
531-- = PClause (updateN ns n) (fmap (updateNs ns) l)
532-- (map (fmap (updateNs ns)) ts)
533-- (fmap (updateNs ns) r)
534-- (map (updateDNs ns) ds)
537-- High level language terms
539data PTerm = PQuote Raw
541 | PLam Name PTerm PTerm
542 | PPi Plicity Name PTerm PTerm
543 | PLet Name PTerm PTerm PTerm
544 | PTyped PTerm PTerm -- term with explicit type
545 | PApp FC PTerm [PArg]
546 | PCase FC PTerm [(PTerm, PTerm)]
552 | PPair FC PTerm PTerm
553 | PDPair FC PTerm PTerm PTerm
554 | PAlternative Bool [PTerm] -- True if only one may work
555 | PHidden PTerm -- irrelevant or hidden pattern
564 | PTactics [PTactic] -- as PProof, but no auto solving
565 | PElabError Err -- error to report on elaboration
566 | PImpossible -- special case for declaring when an LHS can't typecheck
569deriving instance Binary PTerm
572mapPT :: (PTerm -> PTerm) -> PTerm -> PTerm
573mapPT f t = f (mpt t) where
574 mpt (PLam n t s) = PLam n (mapPT f t) (mapPT f s)
575 mpt (PPi p n t s) = PPi p n (mapPT f t) (mapPT f s)
576 mpt (PLet n ty v s) = PLet n (mapPT f ty) (mapPT f v) (mapPT f s)
577 mpt (PApp fc t as) = PApp fc (mapPT f t) (map (fmap (mapPT f)) as)
578 mpt (PCase fc c os) = PCase fc (mapPT f c) (map (pmap (mapPT f)) os)
579 mpt (PEq fc l r) = PEq fc (mapPT f l) (mapPT f r)
580 mpt (PTyped l r) = PTyped (mapPT f l) (mapPT f r)
581 mpt (PPair fc l r) = PPair fc (mapPT f l) (mapPT f r)
582 mpt (PDPair fc l t r) = PDPair fc (mapPT f l) (mapPT f t) (mapPT f r)
583 mpt (PAlternative a as) = PAlternative a (map (mapPT f) as)
584 mpt (PHidden t) = PHidden (mapPT f t)
585 mpt (PDoBlock ds) = PDoBlock (map (fmap (mapPT f)) ds)
586 mpt (PProof ts) = PProof (map (fmap (mapPT f)) ts)
587 mpt (PTactics ts) = PTactics (map (fmap (mapPT f)) ts)
591data PTactic' t = Intro [Name] | Intros | Focus Name
592 | Refine Name [Bool] | Rewrite t | LetTac Name t
593 | Exact t | Compute | Trivial
596 | ProofState | ProofTerm | Undo
597 | Try (PTactic' t) (PTactic' t)
598 | TSeq (PTactic' t) (PTactic' t)
600 deriving (Show, Eq, Functor)
602deriving instance Binary PTactic'
605instance Sized a => Sized (PTactic' a) where
606 size (Intro nms) = 1 + size nms
608 size (Focus nm) = 1 + size nm
609 size (Refine nm bs) = 1 + size nm + length bs
610 size (Rewrite t) = 1 + size t
611 size (LetTac nm t) = 1 + size nm + size t
612 size (Exact t) = 1 + size t
620 size (Try l r) = 1 + size l + size r
621 size (TSeq l r) = 1 + size l + size r
625type PTactic = PTactic' PTerm
627data PDo' t = DoExp FC t
632 deriving (Eq, Functor)
634deriving instance Binary PDo'
637instance Sized a => Sized (PDo' a) where
638 size (DoExp fc t) = 1 + size fc + size t
639 size (DoBind fc nm t) = 1 + size fc + size nm + size t
640 size (DoBindP fc l r) = 1 + size fc + size l + size r
641 size (DoLet fc nm l r) = 1 + size fc + size nm + size l + size r
642 size (DoLetP fc l r) = 1 + size fc + size l + size r
646-- The priority gives a hint as to elaboration order. Best to elaborate
647-- things early which will help give a more concrete type to other
648-- variables, e.g. a before (interpTy a).
650data PArg' t = PImp { priority :: Int,
651 lazyarg :: Bool, pname :: Name, getTm :: t }
652 | PExp { priority :: Int,
653 lazyarg :: Bool, getTm :: t }
654 | PConstraint { priority :: Int,
655 lazyarg :: Bool, getTm :: t }
656 | PTacImplicit { priority :: Int,
657 lazyarg :: Bool, pname :: Name,
660 deriving (Show, Eq, Functor)
662instance Sized a => Sized (PArg' a) where
663 size (PImp p l nm trm) = 1 + size nm + size trm
664 size (PExp p l trm) = 1 + size trm
665 size (PConstraint p l trm) = 1 + size trm
666 size (PTacImplicit p l nm scr trm) = 1 + size nm + size scr + size trm
669deriving instance Binary PArg'
674pconst = PConstraint 0 False
675ptacimp = PTacImplicit 0 True
677type PArg = PArg' PTerm
681data ClassInfo = CI { instanceName :: Name,
682 class_methods :: [(Name, (FnOpts, PTerm))],
683 class_defaults :: [(Name, Name)], -- method name -> default impl
684 class_params :: [Name],
685 class_instances :: [Name] }
688deriving instance Binary ClassInfo
691data OptInfo = Optimise { collapsible :: Bool,
692 forceable :: [Int], -- argument positions
696deriving instance Binary OptInfo
700data TypeInfo = TI { con_names :: [Name] }
703deriving instance Binary TypeInfo
706-- Syntactic sugar info
708data DSL' t = DSL { dsl_bind :: t,
713 index_first :: Maybe t,
714 index_next :: Maybe t,
715 dsl_lambda :: Maybe t,
718 deriving (Show, Functor)
720deriving instance Binary DSL'
725data SynContext = PatternSyntax | TermSyntax | AnySyntax
728deriving instance Binary SynContext
731data Syntax = Rule [SSymbol] PTerm SynContext
734deriving instance Binary Syntax
737data SSymbol = Keyword Name
743deriving instance Binary SSymbol
746initDSL = DSL (PRef f (UN ">>="))
747 (PRef f (UN "return"))
755 where f = FC "(builtin)" 0
757data SyntaxInfo = Syn { using :: [(Name, PTerm)],
758 syn_params :: [(Name, PTerm)],
759 syn_namespace :: [String],
761 decoration :: Name -> Name,
766defaultSyntax = Syn [] [] [] [] id False initDSL
768expandNS :: SyntaxInfo -> Name -> Name
769expandNS syn n@(NS _ _) = n
770expandNS syn n = case syn_namespace syn of
775--- Pretty printing declarations and terms
777instance Show PTerm where
778 show tm = showImp False tm
780instance Pretty PTerm where
781 pretty = prettyImp False
783instance Show PDecl where
784 show d = showDeclImp False d
786instance Show PClause where
787 show c = showCImp True c
789instance Show PData where
790 show d = showDImp False d
792showDeclImp _ (PFix _ f ops) = show f ++ " " ++ showSep ", " ops
793showDeclImp t (PTy _ _ _ n ty) = show n ++ " : " ++ showImp t ty
794showDeclImp _ (PClauses _ _ n c) = showSep "\n" (map show c)
795showDeclImp _ (PData _ _ d) = show d
797showCImp :: Bool -> PClause -> String
798showCImp impl (PClause _ n l ws r w)
799 = showImp impl l ++ showWs ws ++ " = " ++ showImp impl r
800 ++ " where " ++ show w
803 showWs (x : xs) = " | " ++ showImp impl x ++ showWs xs
804showCImp impl (PWith _ n l ws r w)
805 = showImp impl l ++ showWs ws ++ " with " ++ showImp impl r
806 ++ " { " ++ show w ++ " } "
809 showWs (x : xs) = " | " ++ showImp impl x ++ showWs xs
812showDImp :: Bool -> PData -> String
813showDImp impl (PDatadecl n ty cons)
814 = "data " ++ show n ++ " : " ++ showImp impl ty ++ " where\n\t"
816 (map (\ (n, t, _) -> show n ++ " : " ++ showImp impl t) cons)
818getImps :: [PArg] -> [(Name, PTerm)]
820getImps (PImp _ _ n tm : xs) = (n, tm) : getImps xs
821getImps (_ : xs) = getImps xs
823getExps :: [PArg] -> [PTerm]
825getExps (PExp _ _ tm : xs) = tm : getExps xs
826getExps (_ : xs) = getExps xs
828getConsts :: [PArg] -> [PTerm]
830getConsts (PConstraint _ _ tm : xs) = tm : getConsts xs
831getConsts (_ : xs) = getConsts xs
833getAll :: [PArg] -> [PTerm]
836prettyImp :: Bool -> PTerm -> Doc
837prettyImp impl = prettySe 10
839 prettySe p (PQuote r) =
840 if size r > breakingSize then
841 text "![" $$ pretty r <> text "]"
843 text "![" <> pretty r <> text "]"
844 prettySe p (PRef fc n) =
850 prettyBasic n@(UN _) = pretty n
851 prettyBasic (MN _ s) = text s
852 prettyBasic (NS n s) = (foldr (<>) empty (intersperse (text ".") (map text $ reverse s))) <> prettyBasic n
853 prettySe p (PLam n ty sc) =
855 if size sc > breakingSize then
856 text "λ" <> pretty n <+> text "=>" $+$ pretty sc
858 text "λ" <> pretty n <+> text "=>" <+> pretty sc
859 prettySe p (PLet n ty v sc) =
861 if size sc > breakingSize then
862 text "let" <+> pretty n <+> text "=" <+> prettySe 10 v <+> text "in" $+$
863 nest nestingSize (prettySe 10 sc)
865 text "let" <+> pretty n <+> text "=" <+> prettySe 10 v <+> text "in" <+>
867 prettySe p (PPi (Exp l s) n ty sc)
868 | n `elem` allNamesIn sc || impl =
869 let open = if l then text "|" <> lparen else lparen in
871 if size sc > breakingSize then
872 open <> pretty n <+> colon <+> prettySe 10 ty <> rparen <+>
873 st <+> text "->" $+$ prettySe 10 sc
875 open <> pretty n <+> colon <+> prettySe 10 ty <> rparen <+>
876 st <+> text "->" <+> prettySe 10 sc
879 if size sc > breakingSize then
880 prettySe 0 ty <+> st <+> text "->" $+$ prettySe 10 sc
882 prettySe 0 ty <+> st <+> text "->" <+> prettySe 10 sc
886 Static -> text "[static]"
888 prettySe p (PPi (Imp l s) n ty sc)
890 let open = if l then text "|" <> lbrace else lbrace in
892 if size sc > breakingSize then
893 open <> pretty n <+> colon <+> prettySe 10 ty <> rbrace <+>
894 st <+> text "->" <+> prettySe 10 sc
896 open <> pretty n <+> colon <+> prettySe 10 ty <> rbrace <+>
897 st <+> text "->" <+> prettySe 10 sc
898 | otherwise = prettySe 10 sc
902 Static -> text $ "[static]"
904 prettySe p (PPi (Constraint _ _) n ty sc) =
906 if size sc > breakingSize then
907 prettySe 10 ty <+> text "=>" <+> prettySe 10 sc
909 prettySe 10 ty <+> text "=>" $+$ prettySe 10 sc
910 prettySe p (PPi (TacImp _ _ s) n ty sc) =
912 if size sc > breakingSize then
913 lbrace <> text "tacimp" <+> pretty n <+> colon <+> prettySe 10 ty <>
914 rbrace <+> text "->" $+$ prettySe 10 sc
916 lbrace <> text "tacimp" <+> pretty n <+> colon <+> prettySe 10 ty <>
917 rbrace <+> text "->" <+> prettySe 10 sc
918 prettySe p (PApp _ (PRef _ f) [])
919 | not impl = pretty f
920 prettySe p (PApp _ (PRef _ op@(UN (f:_))) args)
921 | length (getExps args) == 2 && (not impl) && (not $ isAlpha f) =
922 let [l, r] = getExps args in
924 if size r > breakingSize then
925 prettySe 1 l <+> pretty op $+$ prettySe 0 r
927 prettySe 1 l <+> pretty op <+> prettySe 0 r
928 prettySe p (PApp _ f as) =
929 let args = getExps as in
934 -- foldr (<+>) empty $ map prettyArgS as
937 -- foldr (<+>) empty $ map prettyArgSe args
940 if size r > breakingSize then
941 l $+$ nest nestingSize (prettyArgS r)
946 if size r > breakingSize then
947 l $+$ nest nestingSize (prettyArgSe r)
950 prettySe p (PCase _ scr opts) =
951 text "case" <+> prettySe 10 scr <+> text "of" $+$ nest nestingSize prettyBody
953 prettyBody = foldr ($$) empty $ intersperse (text "|") $ map sc opts
955 sc (l, r) = prettySe 10 l <+> text "=>" <+> prettySe 10 r
956 prettySe p (PHidden tm) = text "." <> prettySe 0 tm
957 prettySe p (PRefl _) = text "refl"
958 prettySe p (PResolveTC _) = text "resolvetc"
959 prettySe p (PTrue _) = text "()"
960 prettySe p (PFalse _) = text "_|_"
961 prettySe p (PEq _ l r) =
963 if size r > breakingSize then
964 prettySe 10 l <+> text "=" $$ nest nestingSize (prettySe 10 r)
966 prettySe 10 l <+> text "=" <+> prettySe 10 r
967 prettySe p (PTyped l r) =
968 lparen <> prettySe 10 l <+> colon <+> prettySe 10 r <> rparen
969 prettySe p (PPair _ l r) =
970 if size r > breakingSize then
971 lparen <> prettySe 10 l <> text "," $+$
972 prettySe 10 r <> rparen
974 lparen <> prettySe 10 l <> text "," <+> prettySe 10 r <> rparen
975 prettySe p (PDPair _ l t r) =
976 if size r > breakingSize then
977 lparen <> prettySe 10 l <+> text "**" $+$
978 prettySe 10 r <> rparen
980 lparen <> prettySe 10 l <+> text "**" <+> prettySe 10 r <> rparen
981 prettySe p (PAlternative a as) =
982 lparen <> text "|" <> prettyAs <> text "|" <> rparen
985 foldr (\l -> \r -> l <+> text "," <+> r) empty $ map (prettySe 10) as
986 prettySe p PSet = text "Set"
987 prettySe p (PConstant c) = pretty c
988 -- XXX: add pretty for tactics
989 prettySe p (PProof ts) =
990 text "proof" <+> lbrace $+$ nest nestingSize (text . show $ ts) $+$ rbrace
991 prettySe p (PTactics ts) =
992 text "tactics" <+> lbrace $+$ nest nestingSize (text . show $ ts) $+$ rbrace
993 prettySe p (PMetavar n) = text "?" <> pretty n
994 prettySe p (PReturn f) = text "return"
995 prettySe p PImpossible = text "impossible"
996 prettySe p Placeholder = text "_"
997 prettySe p (PDoBlock _) = text "do block pretty not implemented"
998 prettySe p (PElabError s) = pretty s
1000 prettySe p _ = text "test"
1002 prettyArgS (PImp _ _ n tm) = prettyArgSi (n, tm)
1003 prettyArgS (PExp _ _ tm) = prettyArgSe tm
1004 prettyArgS (PConstraint _ _ tm) = prettyArgSc tm
1005 prettyArgS (PTacImplicit _ _ n _ tm) = prettyArgSti (n, tm)
1007 prettyArgSe arg = prettySe 0 arg
1008 prettyArgSi (n, val) = lbrace <> pretty n <+> text "=" <+> prettySe 10 val <> rbrace
1009 prettyArgSc val = lbrace <> lbrace <> prettySe 10 val <> rbrace <> rbrace
1010 prettyArgSti (n, val) = lbrace <> text "auto" <+> pretty n <+> text "=" <+> prettySe 10 val <> rbrace
1012 bracket outer inner doc
1013 | inner > outer = lparen <> doc <> rparen
1016showImp :: Bool -> PTerm -> String
1017showImp impl tm = se 10 tm where
1018 se p (PQuote r) = "![" ++ show r ++ "]"
1019 se p (PRef fc n) = if impl then show n -- ++ "[" ++ show fc ++ "]"
1021 where showbasic n@(UN _) = show n
1022 showbasic (MN _ s) = s
1023 showbasic (NS n s) = showSep "." (reverse s) ++ "." ++ showbasic n
1024 se p (PLam n ty sc) = bracket p 2 $ "\\ " ++ show n ++
1025 (if impl then " : " ++ se 10 ty else "") ++ " => "
1027 se p (PLet n ty v sc) = bracket p 2 $ "let " ++ show n ++ " = " ++ se 10 v ++
1029 se p (PPi (Exp l s) n ty sc)
1030 | n `elem` allNamesIn sc || impl
1032 if l then "|(" else "(" ++
1033 show n ++ " : " ++ se 10 ty ++
1036 | otherwise = bracket p 2 $ se 0 ty ++ " " ++ st ++ "-> " ++ se 10 sc
1037 where st = case s of
1038 Static -> "[static] "
1040 se p (PPi (Imp l s) n ty sc)
1041 | impl = bracket p 2 $ if l then "|{" else "{" ++
1042 show n ++ " : " ++ se 10 ty ++
1043 "} " ++ st ++ "-> " ++ se 10 sc
1044 | otherwise = se 10 sc
1045 where st = case s of
1046 Static -> "[static] "
1048 se p (PPi (Constraint _ _) n ty sc)
1049 = bracket p 2 $ se 10 ty ++ " => " ++ se 10 sc
1050 se p (PPi (TacImp _ _ s) n ty sc)
1051 = bracket p 2 $ "{tacimp " ++ show n ++ " : " ++ se 10 ty ++ "} -> " ++ se 10 sc
1052 se p (PApp _ (PRef _ f) [])
1054 se p (PApp _ (PRef _ op@(UN (f:_))) args)
1055 | length (getExps args) == 2 && not impl && not (isAlpha f)
1056 = let [l, r] = getExps args in
1057 bracket p 1 $ se 1 l ++ " " ++ show op ++ " " ++ se 0 r
1059 = let args = getExps as in
1060 bracket p 1 $ se 1 f ++ if impl then concatMap sArg as
1061 else concatMap seArg args
1062 se p (PCase _ scr opts) = "case " ++ se 10 scr ++ " of " ++ showSep " | " (map sc opts)
1063 where sc (l, r) = se 10 l ++ " => " ++ se 10 r
1064 se p (PHidden tm) = "." ++ se 0 tm
1065 se p (PRefl _) = "refl"
1066 se p (PResolveTC _) = "resolvetc"
1067 se p (PTrue _) = "()"
1068 se p (PFalse _) = "_|_"
1069 se p (PEq _ l r) = bracket p 2 $ se 10 l ++ " = " ++ se 10 r
1070 se p (PTyped l r) = "(" ++ se 10 l ++ " : " ++ se 10 r ++ ")"
1071 se p (PPair _ l r) = "(" ++ se 10 l ++ ", " ++ se 10 r ++ ")"
1072 se p (PDPair _ l t r) = "(" ++ se 10 l ++ " ** " ++ se 10 r ++ ")"
1073 se p (PAlternative a as) = "(|" ++ showSep " , " (map (se 10) as) ++ "|)"
1075 se p (PConstant c) = show c
1076 se p (PProof ts) = "proof { " ++ show ts ++ "}"
1077 se p (PTactics ts) = "tactics { " ++ show ts ++ "}"
1078 se p (PMetavar n) = "?" ++ show n
1079 se p (PReturn f) = "return"
1080 se p PImpossible = "impossible"
1081 se p Placeholder = "_"
1082 se p (PDoBlock _) = "do block show not implemented"
1083 se p (PElabError s) = show s
1084-- se p x = "Not implemented"
1086 sArg (PImp _ _ n tm) = siArg (n, tm)
1087 sArg (PExp _ _ tm) = seArg tm
1088 sArg (PConstraint _ _ tm) = scArg tm
1089 sArg (PTacImplicit _ _ n _ tm) = stiArg (n, tm)
1091 seArg arg = " " ++ se 0 arg
1092 siArg (n, val) = " {" ++ show n ++ " = " ++ se 10 val ++ "}"
1093 scArg val = " {{" ++ se 10 val ++ "}}"
1094 stiArg (n, val) = " {auto " ++ show n ++ " = " ++ se 10 val ++ "}"
1096 bracket outer inner str | inner > outer = "(" ++ str ++ ")"
1102 | PLam Name PTerm PTerm
1103 | PPi Plicity Name PTerm PTerm
1104 | PLet Name PTerm PTerm PTerm
1105 | PTyped PTerm PTerm -- term with explicit type
1106 | PApp FC PTerm [PArg]
1107 | PCase FC PTerm [(PTerm, PTerm)]
1112 | PEq FC PTerm PTerm
1113 | PPair FC PTerm PTerm
1114 | PDPair FC PTerm PTerm PTerm
1115 | PAlternative [PTerm]
1116 | PHidden PTerm -- irrelevant or hidden pattern
1125 | PTactics [PTactic] -- as PProof, but no auto solving
1126 | PElabError Err -- error to report on elaboration
1127 | PImpossible -- special case for declaring when an LHS can't typecheck
1130instance Sized PTerm where
1131 size (PQuote rawTerm) = size rawTerm
1132 size (PRef fc name) = size name
1133 size (PLam name ty bdy) = 1 + size ty + size bdy
1134 size (PPi plicity name ty bdy) = 1 + size ty + size bdy
1135 size (PLet name ty def bdy) = 1 + size ty + size def + size bdy
1136 size (PTyped trm ty) = 1 + size trm + size ty
1137 size (PApp fc name args) = 1 + size args
1138 size (PCase fc trm bdy) = 1 + size trm + size bdy
1140 size (PFalse fc) = 1
1142 size (PResolveTC fc) = 1
1143 size (PEq fc left right) = 1 + size left + size right
1144 size (PPair fc left right) = 1 + size left + size right
1145 size (PDPair fs left ty right) = 1 + size left + size ty + size right
1146 size (PAlternative a alts) = 1 + size alts
1147 size (PHidden hidden) = size hidden
1149 size (PConstant const) = 1 + size const
1150 size Placeholder = 1
1151 size (PDoBlock dos) = 1 + size dos
1152 size (PIdiom fc term) = 1 + size term
1153 size (PReturn fc) = 1
1154 size (PMetavar name) = 1
1155 size (PProof tactics) = size tactics
1156 size (PElabError err) = size err
1157 size PImpossible = 1
1159allNamesIn :: PTerm -> [Name]
1160allNamesIn tm = nub $ ni [] tm
1163 | not (n `elem` env) = [n]
1164 ni env (PApp _ f as) = ni env f ++ concatMap (ni env) (map getTm as)
1165 ni env (PCase _ c os) = ni env c ++ concatMap (ni env) (map snd os)
1166 ni env (PLam n ty sc) = ni env ty ++ ni (n:env) sc
1167 ni env (PPi _ n ty sc) = ni env ty ++ ni (n:env) sc
1168 ni env (PHidden tm) = ni env tm
1169 ni env (PEq _ l r) = ni env l ++ ni env r
1170 ni env (PTyped l r) = ni env l ++ ni env r
1171 ni env (PPair _ l r) = ni env l ++ ni env r
1172 ni env (PDPair _ (PRef _ n) t r) = ni env t ++ ni (n:env) r
1173 ni env (PDPair _ l t r) = ni env l ++ ni env t ++ ni env r
1174 ni env (PAlternative a ls) = concatMap (ni env) ls
1177namesIn :: [(Name, PTerm)] -> IState -> PTerm -> [Name]
1178namesIn uvars ist tm = nub $ ni [] tm
1181 | not (n `elem` env)
1182 = case lookupTy Nothing n (tt_ctxt ist) of
1184 _ -> if n `elem` (map fst uvars) then [n] else []
1185 ni env (PApp _ f as) = ni env f ++ concatMap (ni env) (map getTm as)
1186 ni env (PCase _ c os) = ni env c ++ concatMap (ni env) (map snd os)
1187 ni env (PLam n ty sc) = ni env ty ++ ni (n:env) sc
1188 ni env (PPi _ n ty sc) = ni env ty ++ ni (n:env) sc
1189 ni env (PEq _ l r) = ni env l ++ ni env r
1190 ni env (PTyped l r) = ni env l ++ ni env r
1191 ni env (PPair _ l r) = ni env l ++ ni env r
1192 ni env (PDPair _ (PRef _ n) t r) = ni env t ++ ni (n:env) r
1193 ni env (PDPair _ l t r) = ni env l ++ ni env t ++ ni env r
1194 ni env (PAlternative a as) = concatMap (ni env) as
1195 ni env (PHidden tm) = ni env tm
1198-- For inferring types of things
1202inferTy = MN 0 "__Infer"
1203inferCon = MN 0 "__infer"
1204inferDecl = PDatadecl inferTy
1206 [(inferCon, PPi impl (MN 0 "A") PSet (
1207 PPi expl (MN 0 "a") (PRef bi (MN 0 "A"))
1208 (PRef bi inferTy)), bi)]
1210infTerm t = PApp bi (PRef bi inferCon) [pimp (MN 0 "A") Placeholder, pexp t]
1211infP = P (TCon 6 0) inferTy (Set (UVal 0))
1213getInferTerm, getInferType :: Term -> Term
1214getInferTerm (Bind n b sc) = Bind n b $ getInferTerm sc
1215getInferTerm (App (App _ _) tm) = tm
1216getInferTerm tm = error ("getInferTerm " ++ show tm)
1218getInferType (Bind n b sc) = Bind n b $ getInferType sc
1219getInferType (App (App _ ty) _) = ty
1221-- Handy primitives: Unit, False, Pair, MkPair, =, mkForeign
1223primNames = [unitTy, unitCon,
1224 falseTy, pairTy, pairCon,
1225 eqTy, eqCon, inferTy, inferCon]
1227unitTy = MN 0 "__Unit"
1228unitCon = MN 0 "__II"
1229unitDecl = PDatadecl unitTy PSet
1230 [(unitCon, PRef bi unitTy, bi)]
1232falseTy = MN 0 "__False"
1233falseDecl = PDatadecl falseTy PSet []
1235pairTy = MN 0 "__Pair"
1236pairCon = MN 0 "__MkPair"
1237pairDecl = PDatadecl pairTy (piBind [(n "A", PSet), (n "B", PSet)] PSet)
1238 [(pairCon, PPi impl (n "A") PSet (
1239 PPi impl (n "B") PSet (
1240 PPi expl (n "a") (PRef bi (n "A")) (
1241 PPi expl (n "b") (PRef bi (n "B"))
1242 (PApp bi (PRef bi pairTy) [pexp (PRef bi (n "A")),
1243 pexp (PRef bi (n "B"))])))), bi)]
1248eqDecl = PDatadecl eqTy (piBind [(n "a", PSet), (n "b", PSet),
1249 (n "x", PRef bi (n "a")), (n "y", PRef bi (n "b"))]
1251 [(eqCon, PPi impl (n "a") PSet (
1252 PPi impl (n "x") (PRef bi (n "a"))
1253 (PApp bi (PRef bi eqTy) [pimp (n "a") Placeholder,
1254 pimp (n "b") Placeholder,
1255 pexp (PRef bi (n "x")),
1256 pexp (PRef bi (n "x"))])), bi)]
1259-- Defined in builtins.idr
1260sigmaTy = UN "Exists"
1261existsCon = UN "Ex_intro"
1263piBind :: [(Name, PTerm)] -> PTerm -> PTerm
1265piBind ((n, ty):ns) t = PPi expl n ty (piBind ns t)
1267tcname (UN ('@':_)) = True
1268tcname (NS n _) = tcname n
1271-- Dealing with parameters
1273expandParams :: (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PTerm -> PTerm
1274expandParams dec ps ns tm = en tm
1276 -- if we shadow a name (say in a lambda binding) that is used in a call to
1277 -- a lifted function, we need access to both names - once in the scope of the
1278 -- binding and once to call the lifted functions. So we'll explicitly shadow
1279 -- it. (Yes, it's a hack. The alternative would be to resolve names earlier
1280 -- but we didn't...)
1282 mkShadow (UN n) = MN 0 n
1283 mkShadow (MN i n) = MN (i+1) n
1284 mkShadow (NS x s) = NS (mkShadow x) s
1287 | n `elem` map fst ps
1288 = let n' = mkShadow n in
1289 PLam n' (en t) (en (shadow n n' s))
1290 | otherwise = PLam n (en t) (en s)
1292 | n `elem` map fst ps
1293 = let n' = mkShadow n in
1294 PPi p n' (en t) (en (shadow n n' s))
1295 | otherwise = PPi p n (en t) (en s)
1297 | n `elem` map fst ps
1298 = let n' = mkShadow n in
1299 PLet n' (en ty) (en v) (en (shadow n n' s))
1300 | otherwise = PLet n (en ty) (en v) (en s)
1301 en (PEq f l r) = PEq f (en l) (en r)
1302 en (PTyped l r) = PTyped (en l) (en r)
1303 en (PPair f l r) = PPair f (en l) (en r)
1304 en (PDPair f l t r) = PDPair f (en l) (en t) (en r)
1305 en (PAlternative a as) = PAlternative a (map en as)
1306 en (PHidden t) = PHidden (en t)
1307 en (PDoBlock ds) = PDoBlock (map (fmap en) ds)
1308 en (PProof ts) = PProof (map (fmap en) ts)
1309 en (PTactics ts) = PTactics (map (fmap en) ts)
1312 | n `elem` ns = PQuote (Var (dec n))
1313 en (PApp fc (PRef fc' n) as)
1314 | n `elem` ns = PApp fc (PRef fc' (dec n))
1315 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
1317 | n `elem` ns = PApp fc (PRef fc (dec n))
1318 (map (pexp . (PRef fc)) (map fst ps))
1319 en (PApp fc f as) = PApp fc (en f) (map (fmap en) as)
1320 en (PCase fc c os) = PCase fc (en c) (map (pmap en) os)
1323expandParamsD :: IState ->
1324 (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PDecl -> PDecl
1325expandParamsD ist dec ps ns (PTy syn fc o n ty)
1327 then PTy syn fc o (dec n) (piBind ps (expandParams dec ps ns ty))
1328 else PTy syn fc o n (expandParams dec ps ns ty)
1329expandParamsD ist dec ps ns (PClauses fc opts n cs)
1330 = let n' = if n `elem` ns then dec n else n in
1331 PClauses fc opts n' (map expandParamsC cs)
1333 expandParamsC (PClause fc n lhs ws rhs ds)
1334 = let -- ps' = updateps True (namesIn ist rhs) (zip ps [0..])
1335 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
1336 n' = if n `elem` ns then dec n else n in
1337 PClause fc n' (expandParams dec ps'' ns lhs)
1338 (map (expandParams dec ps'' ns) ws)
1339 (expandParams dec ps'' ns rhs)
1340 (map (expandParamsD ist dec ps'' ns) ds)
1341 expandParamsC (PWith fc n lhs ws wval ds)
1342 = let -- ps' = updateps True (namesIn ist wval) (zip ps [0..])
1343 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
1344 n' = if n `elem` ns then dec n else n in
1345 PWith fc n' (expandParams dec ps'' ns lhs)
1346 (map (expandParams dec ps'' ns) ws)
1347 (expandParams dec ps'' ns wval)
1348 (map (expandParamsD ist dec ps'' ns) ds)
1349 updateps yn nm [] = []
1350 updateps yn nm (((a, t), i):as)
1351 | (a `elem` nm) == yn = (a, t) : updateps yn nm as
1352 | otherwise = (MN i (show n ++ "_u"), t) : updateps yn nm as
1354expandParamsD ist dec ps ns d = d
1356-- Calculate a priority for a type, for deciding elaboration order
1357-- * if it's just a type variable or concrete type, do it early (0)
1358-- * if there's only type variables and injective constructors, do it next (1)
1359-- * if there's a function type, next (2)
1360-- * finally, everything else (3)
1362getPriority :: IState -> PTerm -> Int
1363getPriority i tm = pri tm
1366 case lookupP Nothing n (tt_ctxt i) of
1367 ((P (DCon _ _) _ _):_) -> 1
1368 ((P (TCon _ _) _ _):_) -> 1
1369 ((P Ref _ _):_) -> 4
1370 [] -> 0 -- must be locally bound, if it's not an error...
1371 pri (PPi _ _ x y) = max 5 (max (pri x) (pri y))
1375 pri (PEq _ l r) = max 1 (max (pri l) (pri r))
1376 pri (PApp _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.getTm) as)))
1377 pri (PCase _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.snd) as)))
1378 pri (PTyped l r) = pri l
1379 pri (PPair _ l r) = max 1 (max (pri l) (pri r))
1380 pri (PDPair _ l t r) = max 1 (max (pri l) (max (pri t) (pri r)))
1381 pri (PAlternative a as) = maximum (map pri as)
1382 pri (PConstant _) = 0
1386addStatics :: Name -> Term -> PTerm -> Idris ()
1387addStatics n tm ptm =
1388 do let (statics, dynamics) = initStatics tm ptm
1389 let stnames = nub $ concatMap freeNames (map snd statics)
1390 let dnames = nub $ concatMap freeNames (map snd dynamics)
1391 when (not (null statics)) $
1392 logLvl 7 $ show n ++ " " ++ show statics ++ "\n" ++ show dynamics
1393 ++ "\n" ++ show stnames ++ "\n" ++ show dnames
1394 let statics' = nub $ map fst statics ++
1395 filter (\x -> not (elem x dnames)) stnames
1396 let stpos = staticList statics' tm
1398 put (i { idris_statics = addDef n stpos (idris_statics i) })
1399 addIBC (IBCStatic n)
1401 initStatics (Bind n (Pi ty) sc) (PPi p _ _ s)
1402 = let (static, dynamic) = initStatics (instantiate (P Bound n ty) sc) s in
1403 if pstatic p == Static then ((n, ty) : static, dynamic)
1404 else (static, (n, ty) : dynamic)
1405 initStatics t pt = ([], [])
1407 staticList sts (Bind n (Pi _) sc) = (n `elem` sts) : staticList sts sc
1410-- Dealing with implicit arguments
1412-- Add implicit Pi bindings for any names in the term which appear in an
1413-- argument position.
1415-- This has become a right mess already. Better redo it some time...
1417implicit :: SyntaxInfo -> Name -> PTerm -> Idris PTerm
1420 let (tm', impdata) = implicitise syn i ptm
1421-- let (tm'', spos) = findStatics i tm'
1422 put (i { idris_implicits = addDef n impdata (idris_implicits i) })
1424 logLvl 5 ("Implicit " ++ show n ++ " " ++ show impdata)
1426-- put (i { idris_statics = addDef n spos (idris_statics i) })
1429implicitise :: SyntaxInfo -> IState -> PTerm -> (PTerm, [PArg])
1430implicitise syn ist tm
1431 = let (declimps, ns') = execState (imps True [] tm) ([], [])
1432 ns = ns' \\ (map fst pvars ++ no_imp syn) in
1434 then (tm, reverse declimps)
1435 else implicitise syn ist (pibind uvars ns tm)
1438 pvars = syn_params syn
1440 dropAll (x:xs) ys | x `elem` ys = dropAll xs ys
1441 | otherwise = x : dropAll xs ys
1444 imps top env (PApp _ f as)
1445 = do (decls, ns) <- get
1446 let isn = concatMap (namesIn uvars ist) (map getTm as)
1447 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1448 imps top env (PPi (Imp l _) n ty sc)
1449 = do let isn = nub (namesIn uvars ist ty) `dropAll` [n]
1451 put (PImp (getPriority ist ty) l n ty : decls,
1452 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1453 imps True (n:env) sc
1454 imps top env (PPi (Exp l _) n ty sc)
1455 = do let isn = nub (namesIn uvars ist ty ++ case sc of
1456 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1458 (decls, ns) <- get -- ignore decls in HO types
1459 put (PExp (getPriority ist ty) l ty : decls,
1460 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1461 imps True (n:env) sc
1462 imps top env (PPi (Constraint l _) n ty sc)
1463 = do let isn = nub (namesIn uvars ist ty ++ case sc of
1464 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1466 (decls, ns) <- get -- ignore decls in HO types
1467 put (PConstraint 10 l ty : decls,
1468 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1469 imps True (n:env) sc
1470 imps top env (PPi (TacImp l _ scr) n ty sc)
1471 = do let isn = nub (namesIn uvars ist ty ++ case sc of
1472 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1474 (decls, ns) <- get -- ignore decls in HO types
1475 put (PTacImplicit 10 l n scr ty : decls,
1476 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1477 imps True (n:env) sc
1478 imps top env (PEq _ l r)
1479 = do (decls, ns) <- get
1480 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1481 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1482 imps top env (PTyped l r)
1484 imps top env (PPair _ l r)
1485 = do (decls, ns) <- get
1486 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1487 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1488 imps top env (PDPair _ (PRef _ n) t r)
1489 = do (decls, ns) <- get
1490 let isn = nub (namesIn uvars ist t ++ namesIn uvars ist r) \\ [n]
1491 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1492 imps top env (PDPair _ l t r)
1493 = do (decls, ns) <- get
1494 let isn = namesIn uvars ist l ++ namesIn uvars ist t ++
1496 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1497 imps top env (PAlternative a as)
1498 = do (decls, ns) <- get
1499 let isn = concatMap (namesIn uvars ist) as
1500 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1501 imps top env (PLam n ty sc)
1502 = do imps False env ty
1503 imps False (n:env) sc
1504 imps top env (PHidden tm) = imps False env tm
1505 imps top env _ = return ()
1507 pibind using [] sc = sc
1508 pibind using (n:ns) sc
1509 = case lookup n using of
1510 Just ty -> PPi (Imp False Dynamic) n ty (pibind using ns sc)
1511 Nothing -> PPi (Imp False Dynamic) n Placeholder (pibind using ns sc)
1513-- Add implicit arguments in function calls
1514addImplPat :: IState -> PTerm -> PTerm
1515addImplPat = addImpl' True []
1517addImplBound :: IState -> [Name] -> PTerm -> PTerm
1518addImplBound ist ns = addImpl' False ns ist
1520addImpl :: IState -> PTerm -> PTerm
1521addImpl = addImpl' False []
1523-- TODO: in patterns, don't add implicits to function names guarded by constructors
1524-- and *not* inside a PHidden
1526addImpl' :: Bool -> [Name] -> IState -> PTerm -> PTerm
1527addImpl' inpat env ist ptm = ai env ptm
1530 | not (f `elem` env) = handleErr $ aiFn inpat ist fc f []
1531 ai env (PHidden (PRef fc f))
1532 | not (f `elem` env) = handleErr $ aiFn False ist fc f []
1533 ai env (PEq fc l r) = let l' = ai env l
1536 ai env (PTyped l r) = let l' = ai env l
1539 ai env (PPair fc l r) = let l' = ai env l
1542 ai env (PDPair fc l t r) = let l' = ai env l
1546 ai env (PAlternative a as) = let as' = map (ai env) as in
1548 ai env (PApp fc (PRef _ f) as)
1549 | not (f `elem` env)
1550 = let as' = map (fmap (ai env)) as in
1551 handleErr $ aiFn False ist fc f as'
1552 ai env (PApp fc f as) = let f' = ai env f
1553 as' = map (fmap (ai env)) as in
1555 ai env (PCase fc c os) = let c' = ai env c
1556 os' = map (pmap (ai env)) os in
1558 ai env (PLam n ty sc) = let ty' = ai env ty
1559 sc' = ai (n:env) sc in
1561 ai env (PLet n ty val sc)
1562 = let ty' = ai env ty
1564 sc' = ai (n:env) sc in
1566 ai env (PPi p n ty sc) = let ty' = ai env ty
1567 sc' = ai (n:env) sc in
1569 ai env (PHidden tm) = PHidden (ai env tm)
1570 ai env (PProof ts) = PProof (map (fmap (ai env)) ts)
1571 ai env (PTactics ts) = PTactics (map (fmap (ai env)) ts)
1574 handleErr (Left err) = PElabError err
1575 handleErr (Right x) = x
1577-- if in a pattern, and there are no arguments, and there's no possible
1578-- names with zero explicit arguments, don't add implicits.
1580aiFn :: Bool -> IState -> FC -> Name -> [PArg] -> Either Err PTerm
1581aiFn True ist fc f []
1582 = case lookupCtxt Nothing f (idris_implicits ist) of
1583 [] -> Right $ PRef fc f
1584 alts -> if (any (all imp) alts)
1585 then aiFn False ist fc f [] -- use it as a constructor
1586 else Right $ PRef fc f
1587 where imp (PExp _ _ _) = False
1589aiFn inpat ist fc f as
1590 | f `elem` primNames = Right $ PApp fc (PRef fc f) as
1591aiFn inpat ist fc f as
1592 -- This is where namespaces get resolved by adding PAlternative
1593 = case lookupCtxtName Nothing f (idris_implicits ist) of
1594 [(f',ns)] -> Right $ mkPApp fc (length ns) (PRef fc f') (insertImpl ns as)
1595 [] -> if f `elem` idris_metavars ist
1596 then Right $ PApp fc (PRef fc f) as
1597 else Right $ mkPApp fc (length as) (PRef fc f) as
1600 map (\(f', ns) -> mkPApp fc (length ns) (PRef fc f')
1601 (insertImpl ns as)) alts
1603 insertImpl :: [PArg] -> [PArg] -> [PArg]
1604 insertImpl (PExp p l ty : ps) (PExp _ _ tm : given) =
1605 PExp p l tm : insertImpl ps given
1606 insertImpl (PConstraint p l ty : ps) (PConstraint _ _ tm : given) =
1607 PConstraint p l tm : insertImpl ps given
1608 insertImpl (PConstraint p l ty : ps) given =
1609 PConstraint p l (PResolveTC fc) : insertImpl ps given
1610 insertImpl (PImp p l n ty : ps) given =
1611 case find n given [] of
1612 Just (tm, given') -> PImp p l n tm : insertImpl ps given'
1613 Nothing -> PImp p l n Placeholder : insertImpl ps given
1614 insertImpl (PTacImplicit p l n sc ty : ps) given =
1615 case find n given [] of
1616 Just (tm, given') -> PTacImplicit p l n sc tm : insertImpl ps given'
1617 Nothing -> PTacImplicit p l n sc sc
1618 : insertImpl ps given
1619 insertImpl expected [] = []
1620 insertImpl _ given = given
1622 find n [] acc = Nothing
1623 find n (PImp _ _ n' t : gs) acc
1624 | n == n' = Just (t, reverse acc ++ gs)
1625 find n (g : gs) acc = find n gs (g : acc)
1628mkPApp fc a f as = let rest = drop a as in
1629 appRest fc (PApp fc f (take a as)) rest
1632 appRest fc f (a : as) = appRest fc (PApp fc f [a]) as
1634-- Find 'static' argument positions
1635-- (the declared ones, plus any names in argument position in the declared
1637-- FIXME: It's possible that this really has to happen after elaboration
1639findStatics :: IState -> PTerm -> (PTerm, [Bool])
1640findStatics ist tm = trace (showImp True tm) $
1641 let (ns, ss) = fs tm in
1642 runState (pos ns ss tm) []
1643 where fs (PPi p n t sc)
1644 | Static <- pstatic p
1645 = let (ns, ss) = fs sc in
1646 (namesIn [] ist t : ns, n : ss)
1647 | otherwise = let (ns, ss) = fs sc in
1651 inOne n ns = length (filter id (map (elem n) ns)) == 1
1653 pos ns ss (PPi p n t sc)
1654 | elem n ss = do sc' <- pos ns ss sc
1657 return (PPi (p { pstatic = Static }) n t sc')
1658 | otherwise = do sc' <- pos ns ss sc
1661 return (PPi p n t sc')
1662 pos ns ss t = return t
1664-- Debugging/logging stuff
1666dumpDecls :: [PDecl] -> String
1668dumpDecls (d:ds) = dumpDecl d ++ "\n" ++ dumpDecls ds
1670dumpDecl (PFix _ f ops) = show f ++ " " ++ showSep ", " ops
1671dumpDecl (PTy _ _ _ n t) = "tydecl " ++ show n ++ " : " ++ showImp True t
1672dumpDecl (PClauses _ _ n cs) = "pat " ++ show n ++ "\t" ++ showSep "\n\t" (map (showCImp True) cs)
1673dumpDecl (PData _ _ d) = showDImp True d
1674dumpDecl (PParams _ ns ps) = "params {" ++ show ns ++ "\n" ++ dumpDecls ps ++ "}\n"
1675dumpDecl (PNamespace n ps) = "namespace {" ++ n ++ "\n" ++ dumpDecls ps ++ "}\n"
1676dumpDecl (PSyntax _ syn) = "syntax " ++ show syn
1677dumpDecl (PClass _ _ cs n ps ds)
1678 = "class " ++ show cs ++ " " ++ show n ++ " " ++ show ps ++ "\n" ++ dumpDecls ds
1679dumpDecl (PInstance _ _ cs n _ t ds)
1680 = "instance " ++ show cs ++ " " ++ show n ++ " " ++ show t ++ "\n" ++ dumpDecls ds
1682-- dumpDecl (PImport i) = "import " ++ i
1684-- for 6.12/7 compatibility
1685data EitherErr a b = LeftErr a | RightOK b
1687instance Monad (EitherErr a) where
1690 (LeftErr e) >>= k = LeftErr e
1691 RightOK v >>= k = k v
1693toEither (LeftErr e) = Left e
1694toEither (RightOK ho) = Right ho
1696-- syntactic match of a against b, returning pair of variables in a
1697-- and what they match. Returns the pair that failed if not a match.
1699matchClause :: IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
1700matchClause = matchClause' False
1702matchClause' :: Bool -> IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
1703matchClause' names i x y = checkRpts $ match (fullApp x) (fullApp y) where
1704 matchArg x y = match (fullApp (getTm x)) (fullApp (getTm y))
1706 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
1709 match' x y = match (fullApp x) (fullApp y)
1710 match (PApp _ (PRef _ (NS (UN "fromInteger") ["builtins"])) [_,_,x]) x'
1711 | PConstant (I _) <- getTm x = match (getTm x) x'
1712 match x' (PApp _ (PRef _ (NS (UN "fromInteger") ["builtins"])) [_,_,x])
1713 | PConstant (I _) <- getTm x = match (getTm x) x'
1714 match (PApp _ (PRef _ (UN "lazy")) [_,x]) x' = match (getTm x) x'
1715 match x (PApp _ (PRef _ (UN "lazy")) [_,x']) = match x (getTm x')
1716 match (PApp _ f args) (PApp _ f' args')
1717 | length args == length args'
1718 = do mf <- match' f f'
1719 ms <- zipWithM matchArg args args'
1720 return (mf ++ concat ms)
1721-- match (PRef _ n) (PRef _ n') | n == n' = return []
1722-- | otherwise = Nothing
1723 match (PRef f n) (PApp _ x []) = match (PRef f n) x
1724 match (PApp _ x []) (PRef f n) = match x (PRef f n)
1725 match (PRef _ n) (PRef _ n') | n == n' = return []
1727 | not names && (not (isConName Nothing n (tt_ctxt i)) || tm == Placeholder)
1729 match (PEq _ l r) (PEq _ l' r') = do ml <- match' l l'
1732 match (PTyped l r) (PTyped l' r') = do ml <- match l l'
1735 match (PTyped l r) x = match l x
1736 match x (PTyped l r) = match x l
1737 match (PPair _ l r) (PPair _ l' r') = do ml <- match' l l'
1740 match (PDPair _ l t r) (PDPair _ l' t' r') = do ml <- match' l l'
1743 return (ml ++ mt ++ mr)
1744 match (PAlternative a as) (PAlternative a' as')
1745 = do ms <- zipWithM match' as as'
1747 match a@(PAlternative _ as) b
1748 = do let ms = zipWith match' as (repeat b)
1749 case (rights (map toEither ms)) of
1752 match (PCase _ _ _) _ = return [] -- lifted out
1753 match (PMetavar _) _ = return [] -- modified
1754 match (PQuote _) _ = return []
1755 match (PProof _) _ = return []
1756 match (PTactics _) _ = return []
1757 match (PRefl _) (PRefl _) = return []
1758 match (PResolveTC _) (PResolveTC _) = return []
1759 match (PTrue _) (PTrue _) = return []
1760 match (PFalse _) (PFalse _) = return []
1761 match (PReturn _) (PReturn _) = return []
1762 match (PPi _ _ t s) (PPi _ _ t' s') = do mt <- match' t t'
1765 match (PLam _ t s) (PLam _ t' s') = do mt <- match' t t'
1768 match (PLet _ t ty s) (PLet _ t' ty' s') = do mt <- match' t t'
1769 mty <- match' ty ty'
1771 return (mt ++ mty ++ ms)
1772 match (PHidden x) (PHidden y) = match' x y
1773 match Placeholder _ = return []
1774-- match _ Placeholder = return []
1775 match (PResolveTC _) _ = return []
1776 match a b | a == b = return []
1777 | otherwise = LeftErr (a, b)
1779 checkRpts (RightOK ms) = check ms where
1781 | Just t' <- lookup n xs = if t/=t' && t/=Placeholder && t'/=Placeholder
1784 check (_:xs) = check xs
1786 checkRpts (LeftErr x) = Left x
1788substMatches :: [(Name, PTerm)] -> PTerm -> PTerm
1789substMatches [] t = t
1790substMatches ((n,tm):ns) t = substMatch n tm (substMatches ns t)
1792substMatch :: Name -> PTerm -> PTerm -> PTerm
1793substMatch n tm t = sm t where
1794 sm (PRef _ n') | n == n' = tm
1795 sm (PLam x t sc) = PLam x (sm t) (sm sc)
1796 sm (PPi p x t sc) = PPi p x (sm t) (sm sc)
1797 sm (PApp f x as) = PApp f (sm x) (map (fmap sm) as)
1798 sm (PCase f x as) = PCase f (sm x) (map (pmap sm) as)
1799 sm (PEq f x y) = PEq f (sm x) (sm y)
1800 sm (PTyped x y) = PTyped (sm x) (sm y)
1801 sm (PPair f x y) = PPair f (sm x) (sm y)
1802 sm (PDPair f x t y) = PDPair f (sm x) (sm t) (sm y)
1803 sm (PAlternative a as) = PAlternative a (map sm as)
1804 sm (PHidden x) = PHidden (sm x)
1807shadow :: Name -> Name -> PTerm -> PTerm
1808shadow n n' t = sm t where
1809 sm (PRef fc x) | n == x = PRef fc n'
1810 sm (PLam x t sc) = PLam x (sm t) (sm sc)
1811 sm (PPi p x t sc) = PPi p x (sm t) (sm sc)
1812 sm (PApp f x as) = PApp f (sm x) (map (fmap sm) as)
1813 sm (PCase f x as) = PCase f (sm x) (map (pmap sm) as)
1814 sm (PEq f x y) = PEq f (sm x) (sm y)
1815 sm (PTyped x y) = PTyped (sm x) (sm y)
1816 sm (PPair f x y) = PPair f (sm x) (sm y)
1817 sm (PDPair f x t y) = PDPair f (sm x) (sm t) (sm y)
1818 sm (PAlternative a as) = PAlternative a (map sm as)
1819 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