2Module : Idris.AbsSyntax
3Description : Provides Idris' core data definitions and utility code.
6Maintainer : The Idris Community.
9{-# LANGUAGE DeriveFunctor, FlexibleContexts, PatternGuards #-}
10{-# OPTIONS_GHC -fwarn-unused-imports #-}
12module Idris.AbsSyntax(
13 module Idris.AbsSyntax
14 , module Idris.AbsSyntaxTree
17import Idris.AbsSyntaxTree
19import Idris.Core.Evaluate
21import Idris.Docstrings
22import Idris.IdeMode hiding (Opt(..))
24import IRTS.CodegenCommon
26import System.Directory (canonicalizePath, doesFileExist)
29import Control.Applicative
30import Control.Monad.State
31import Prelude hiding (Applicative, Foldable, Traversable, (<$>))
35import Data.List hiding (insert, union)
36import qualified Data.Map as M
38import qualified Data.Set as S
39import qualified Data.Text as T
40import System.IO.Error (tryIOError)
42import Data.Generics.Uniplate.Data (descend, descendM)
44import Util.DynamicLinker
48getContext :: Idris Context
49getContext = do i <- getIState; return (tt_ctxt i)
51forCodegen :: Codegen -> [(Codegen, a)] -> [a]
52forCodegen tgt xs = [x | (tgt', x) <- xs, eqLang tgt tgt']
54 eqLang (Via _ x) (Via _ y) = x == y
55 eqLang Bytecode Bytecode = True
58getObjectFiles :: Codegen -> Idris [FilePath]
59getObjectFiles tgt = do i <- getIState; return (forCodegen tgt $ idris_objs i)
61addObjectFile :: Codegen -> FilePath -> Idris ()
62addObjectFile tgt f = do i <- getIState; putIState $ i { idris_objs = nub $ idris_objs i ++ [(tgt, f)] }
64getLibs :: Codegen -> Idris [String]
65getLibs tgt = do i <- getIState; return (forCodegen tgt $ idris_libs i)
67addLib :: Codegen -> String -> Idris ()
68addLib tgt f = do i <- getIState; putIState $ i { idris_libs = nub $ idris_libs i ++ [(tgt, f)] }
70getFlags :: Codegen -> Idris [String]
71getFlags tgt = do i <- getIState; return (forCodegen tgt $ idris_cgflags i)
73addFlag :: Codegen -> String -> Idris ()
74addFlag tgt f = do i <- getIState; putIState $ i { idris_cgflags = nub $ idris_cgflags i ++ [(tgt, f)] }
76addDyLib :: [String] -> Idris (Either DynamicLib String)
77addDyLib libs = do i <- getIState
78 let ls = idris_dynamic_libs i
79 let importdirs = opt_importdirs (idris_options i)
80 case mapMaybe (findDyLib ls) libs of
81 x:_ -> return (Left x)
83 handle <- lift . lift .
84 mapM (\l -> catchIO (tryLoadLib importdirs l)
85 (\_ -> return Nothing)) $ libs
87 Nothing -> return (Right $ "Could not load dynamic alternatives \"" ++
88 intercalate "," libs ++ "\"")
89 Just x -> do putIState $ i { idris_dynamic_libs = x:ls }
91 where findDyLib :: [DynamicLib] -> String -> Maybe DynamicLib
92 findDyLib [] _ = Nothing
93 findDyLib (lib:libs') l | l == lib_name lib = Just lib
94 | otherwise = findDyLib libs' l
96getAutoImports :: Idris [FilePath]
97getAutoImports = do i <- getIState
98 return (opt_autoImport (idris_options i))
100addAutoImport :: FilePath -> Idris ()
101addAutoImport fp = do i <- getIState
102 let opts = idris_options i
103 put (i { idris_options = opts { opt_autoImport =
104 fp : opt_autoImport opts } } )
106addDefinedName :: Name -> Idris ()
107addDefinedName n = do ist <- getIState
108 putIState $ ist { idris_inmodule = S.insert n (idris_inmodule ist) }
110getDefinedNames :: Idris [Name]
111getDefinedNames = do ist <- getIState
112 return (S.toList (idris_inmodule ist))
114addTT :: Term -> Idris (Maybe Term)
115addTT t = do ist <- getIState
116 case M.lookup t (idris_ttstats ist) of
117 Nothing -> do let tt' = M.insert t (1, t) (idris_ttstats ist)
118 putIState $ ist { idris_ttstats = tt' }
120 Just (i, t') -> do let tt' = M.insert t' (i + 1, t') (idris_ttstats ist)
121 putIState $ ist { idris_ttstats = tt' }
125dumpTT = do ist <- get
126 let sts = sortBy count (M.toList (idris_ttstats ist))
130 count (_,x) (_,y) = compare y x
131 dump (tm, val) = runIO $ putStrLn (show val ++ ": " ++ show tm)
133addHdr :: Codegen -> String -> Idris ()
134addHdr tgt f = do i <- getIState; putIState $ i { idris_hdrs = nub $ (tgt, f) : idris_hdrs i }
136addImported :: Bool -> FilePath -> Idris ()
139 putIState $ i { idris_imported = nub $ (f, pub) : idris_imported i }
141addLangExt :: LanguageExt -> Idris ()
142addLangExt e = do i <- getIState
144 idris_language_extensions = e : idris_language_extensions i
147dropLangExt :: LanguageExt -> Idris ()
148dropLangExt e = do i <- getIState
150 idris_language_extensions = idris_language_extensions i \\ [e]
153-- | Transforms are organised by the function being applied on the lhs
154-- of the transform, to make looking up appropriate transforms quicker
155addTrans :: Name -> (Term, Term) -> Idris ()
158 let t' = case lookupCtxtExact basefn (idris_transforms i) of
159 Just def -> (t : def)
161 putIState $ i { idris_transforms = addDef basefn t'
162 (idris_transforms i) }
164-- | Add transformation rules from a definition, which will reverse the
165-- definition for an error to make it more readable
166addErrRev :: (Term, Term) -> Idris ()
167addErrRev t = do i <- getIState
168 putIState $ i { idris_errRev = t : idris_errRev i }
170-- | Say that the name should always be reduced in error messages, to
171-- help readability/error reflection
172addErrReduce :: Name -> Idris ()
173addErrReduce t = do i <- getIState
174 putIState $ i { idris_errReduce = t : idris_errReduce i }
176addErasureUsage :: Name -> Int -> Idris ()
177addErasureUsage n i = do ist <- getIState
178 putIState $ ist { idris_erasureUsed = (n, i) : idris_erasureUsed ist }
180addExport :: Name -> Idris ()
181addExport n = do ist <- getIState
182 putIState $ ist { idris_exports = n : idris_exports ist }
184addUsedName :: FC -> Name -> Name -> Idris ()
186 = do ist <- getIState
187 case lookupTyName n (tt_ctxt ist) of
188 [(n', ty)] -> addUsage n' 0 ty
189 [] -> throwError (At fc (NoSuchVariable n))
190 xs -> throwError (At fc (CantResolveAlts (map fst xs)))
191 where addUsage n i (Bind x _ sc) | x == arg = do addIBC (IBCUsage (n, i))
193 | otherwise = addUsage n (i + 1) sc
194 addUsage _ _ _ = throwError (At fc (Msg ("No such argument name " ++ show arg)))
196getErasureUsage :: Idris [(Name, Int)]
197getErasureUsage = do ist <- getIState;
198 return (idris_erasureUsed ist)
200getExports :: Idris [Name]
201getExports = do ist <- getIState
202 return (idris_exports ist)
204totcheck :: (FC, Name) -> Idris ()
205totcheck n = do i <- getIState; putIState $ i { idris_totcheck = idris_totcheck i ++ [n] }
207defer_totcheck :: (FC, Name) -> Idris ()
210 putIState $ i { idris_defertotcheck = nub (idris_defertotcheck i ++ [n]) }
212clear_totcheck :: Idris ()
213clear_totcheck = do i <- getIState; putIState $ i { idris_totcheck = [] }
215setFlags :: Name -> [FnOpt] -> Idris ()
216setFlags n fs = do i <- getIState; putIState $ i { idris_flags = addDef n fs (idris_flags i) }
218addFnOpt :: Name -> FnOpt -> Idris ()
219addFnOpt n f = do i <- getIState
220 let fls = case lookupCtxtExact n (idris_flags i) of
225setFnInfo :: Name -> FnInfo -> Idris ()
226setFnInfo n fs = do i <- getIState; putIState $ i { idris_fninfo = addDef n fs (idris_fninfo i) }
228setAccessibility :: Name -> Accessibility -> Idris ()
231 let ctxt = setAccess n a (tt_ctxt i)
232 putIState $ i { tt_ctxt = ctxt }
234-- | get the accessibility of a name outside this module
235getFromHideList :: Name -> Idris (Maybe Accessibility)
236getFromHideList n = do i <- getIState
237 return $ lookupCtxtExact n (hide_list i)
239setTotality :: Name -> Totality -> Idris ()
242 let ctxt = setTotal n a (tt_ctxt i)
243 putIState $ i { tt_ctxt = ctxt }
245setInjectivity :: Name -> Injectivity -> Idris ()
248 let ctxt = setInjective n a (tt_ctxt i)
249 putIState $ i { tt_ctxt = ctxt }
251getTotality :: Name -> Idris Totality
254 case lookupTotal n (tt_ctxt i) of
256 _ -> return (Total [])
258-- Get coercions which might return the required type
259getCoercionsTo :: IState -> Type -> [Name]
261 let cs = idris_coercions i
262 (fn,_) = unApply (getRetTy ty) in
264 where findCoercions _ [] = []
265 findCoercions t (n : ns) =
266 let ps = case lookupTy n (tt_ctxt i) of
267 [ty'] -> case unApply (getRetTy (normalise (tt_ctxt i) [] ty')) of
268 (t', _) -> [n | t == t']
270 ps ++ findCoercions t ns
272addToCG :: Name -> CGInfo -> Idris ()
275 putIState $ i { idris_callgraph = addDef n cg (idris_callgraph i) }
277addCalls :: Name -> [Name] -> Idris ()
280 case lookupCtxtExact n (idris_callgraph i) of
281 Nothing -> addToCG n (CGInfo calls Nothing [] [])
282 Just (CGInfo cs ans scg used) ->
283 addToCG n (CGInfo (nub (calls ++ cs)) ans scg used)
285addTyInferred :: Name -> Idris ()
288 putIState $ i { idris_tyinfodata =
289 addDef n TIPartial (idris_tyinfodata i) }
291addTyInfConstraints :: FC -> [(Term, Term)] -> Idris ()
292addTyInfConstraints fc ts = do logLvl 2 $ "TI missing: " ++ show ts
293 mapM_ addConstraint ts
295 where addConstraint (x, y) = findMVApps x y
298 = do let (fx, argsx) = unApply x
299 let (fy, argsy) = unApply y
304 else mapM_ addConstraint (zip argsx argsy)
306 tryAddMV (P _ mv _) y =
308 case lookup mv (idris_metavars ist) of
309 Just _ -> addConstraintRule mv y
311 tryAddMV _ _ = return ()
313 addConstraintRule :: Name -> Term -> Idris ()
314 addConstraintRule n t
316 logLvl 1 $ "TI constraint: " ++ show (n, t)
317 case lookupCtxt n (idris_tyinfodata ist) of
319 do mapM_ (checkConsistent t) ts
320 let ti' = addDef n (TISolution (t : ts))
321 (idris_tyinfodata ist)
322 put $ ist { idris_tyinfodata = ti' }
324 do let ti' = addDef n (TISolution [t])
325 (idris_tyinfodata ist)
326 put $ ist { idris_tyinfodata = ti' }
328 -- Check a solution is consistent with previous solutions
329 -- Meaning: If heads are both data types, they had better be the
331 checkConsistent :: Term -> Term -> Idris ()
332 checkConsistent x y =
333 do let (fx, _) = unApply x
334 let (fy, _) = unApply y
336 (P (TCon _ _) n _, P (TCon _ _) n' _) -> errWhen (n/=n')
337 (P (TCon _ _) n _, Constant _) -> errWhen True
338 (Constant _, P (TCon _ _) n' _) -> errWhen True
339 (P (DCon _ _ _) n _, P (DCon _ _ _) n' _) -> errWhen (n/=n')
344 (CantUnify False (x, Nothing) (y, Nothing) (Msg "") [] 0))
345 errWhen False = return ()
347isTyInferred :: Name -> Idris Bool
350 case lookupCtxt n (idris_tyinfodata i) of
351 [TIPartial] -> return True
354-- | Adds error handlers for a particular function and argument. If
355-- names are ambiguous, all matching handlers are updated.
356addFunctionErrorHandlers :: Name -> Name -> [Name] -> Idris ()
357addFunctionErrorHandlers f arg hs =
359 let oldHandlers = idris_function_errorhandlers i
360 let newHandlers = flip (addDef f) oldHandlers $
361 case lookupCtxtExact f oldHandlers of
362 Nothing -> M.singleton arg (S.fromList hs)
363 Just (oldHandlers) -> M.insertWith S.union arg (S.fromList hs) oldHandlers
364 -- will always be one of those two, thus no extra case
365 putIState $ i { idris_function_errorhandlers = newHandlers }
367-- | Trace all the names in a call graph starting at the given name
368getAllNames :: Name -> Idris [Name]
369getAllNames n = do i <- getIState
370 case getCGAllNames i n of
372 Nothing -> do ns <- allNames [] n
376getCGAllNames :: IState -> Name -> Maybe [Name]
377getCGAllNames i n = case lookupCtxtExact n (idris_callgraph i) of
378 Just ci -> allCalls ci
381addCGAllNames :: IState -> Name -> [Name] -> Idris ()
383 = case lookupCtxtExact n (idris_callgraph i) of
384 Just ci -> addToCG n (ci { allCalls = Just ns })
385 _ -> addToCG n (CGInfo [] (Just ns) [] [])
387allNames :: [Name] -> Name -> Idris [Name]
388allNames ns n | n `elem` ns = return []
389allNames ns n = do i <- getIState
390 case getCGAllNames i n of
392 Nothing -> case lookupCtxtExact n (idris_callgraph i) of
394 do more <- mapM (allNames (n:ns)) (calls ci)
395 let ns' = nub (n : concat more)
396 addCGAllNames i n ns'
400addCoercion :: Name -> Idris ()
401addCoercion n = do i <- getIState
402 putIState $ i { idris_coercions = nub $ n : idris_coercions i }
404addDocStr :: Name -> Docstring DocTerm -> [(Name, Docstring DocTerm)] -> Idris ()
407 putIState $ i { idris_docstrings = addDef n (doc, args) (idris_docstrings i) }
409addNameHint :: Name -> Name -> Idris ()
412 ty' <- case lookupCtxtName ty (idris_implicits i) of
413 [(tyn, _)] -> return tyn
414 [] -> throwError (NoSuchVariable ty)
415 tyns -> throwError (CantResolveAlts (map fst tyns))
416 let ns' = case lookupCtxt ty' (idris_namehints i) of
419 putIState $ i { idris_namehints = addDef ty' ns' (idris_namehints i) }
421getNameHints :: IState -> Name -> [Name]
422getNameHints _ (UN arr) | arr == txt "->" = [sUN "f",sUN "g"]
424 case lookupCtxt n (idris_namehints i) of
428addDeprecated :: Name -> String -> Idris ()
429addDeprecated n reason = do
431 putIState $ i { idris_deprecated = addDef n reason (idris_deprecated i) }
433getDeprecated :: Name -> Idris (Maybe String)
436 return $ lookupCtxtExact n (idris_deprecated i)
438addFragile :: Name -> String -> Idris ()
439addFragile n reason = do
441 putIState $ i { idris_fragile = addDef n reason (idris_fragile i) }
443getFragile :: Name -> Idris (Maybe String)
446 return $ lookupCtxtExact n (idris_fragile i)
448push_estack :: Name -> Bool -> Idris ()
449push_estack n implementation
451 putIState (i { elab_stack = (n, implementation) : elab_stack i })
453pop_estack :: Idris ()
454pop_estack = do i <- getIState
455 putIState (i { elab_stack = ptail (elab_stack i) })
459-- | Add an interface implementation function.
461-- Precondition: the implementation should have the correct type.
463-- Dodgy hack 1: Put integer implementations first in the list so they are
464-- resolved by default.
466-- Dodgy hack 2: put constraint chasers (ParentN) last
467addImplementation :: Bool -- ^ whether the name is an Integer implementation
468 -> Bool -- ^ whether to include the implementation in implementation search
469 -> Name -- ^ the name of the interface
470 -> Name -- ^ the name of the implementation
472addImplementation int res n i
473 = do ist <- getIState
474 case lookupCtxt n (idris_interfaces ist) of
475 [CI a b c d e f g ins fds] ->
476 do let cs = addDef n (CI a b c d e f g (addI i ins) fds) (idris_interfaces ist)
477 putIState $ ist { idris_interfaces = cs }
478 _ -> do let cs = addDef n (CI (sMN 0 "none") [] [] [] [] [] [] [(i, res)] []) (idris_interfaces ist)
479 putIState $ ist { idris_interfaces = cs }
480 where addI, insI :: Name -> [(Name, Bool)] -> [(Name, Bool)]
481 addI i ins | int = (i, res) : ins
482 | chaser n = ins ++ [(i, res)]
483 | otherwise = insI i ins
484 insI i [] = [(i, res)]
485 insI i (n : ns) | chaser (fst n) = (i, res) : n : ns
486 | otherwise = n : insI i ns
488 chaser (SN (ParentN _ _)) = True
489 chaser (NS n _) = chaser n
492-- | Add a privileged implementation - one which implementation search will
493-- happily resolve immediately if it is type correct This is used for
494-- naming parent implementations when defining an implementation with
495-- constraints. Returns the old list, so we can revert easily at the
497addOpenImpl :: [Name] -> Idris [Name]
498addOpenImpl ns = do ist <- getIState
499 ns' <- mapM (checkValid ist) ns
500 let open = idris_openimpls ist
501 putIState $ ist { idris_openimpls = nub (ns' ++ open) }
505 = case lookupCtxtName n (idris_implicits ist) of
506 [(n', _)] -> return n'
507 [] -> throwError (NoSuchVariable n)
508 more -> throwError (CantResolveAlts (map fst more))
510setOpenImpl :: [Name] -> Idris ()
511setOpenImpl ns = do ist <- getIState
512 putIState $ ist { idris_openimpls = ns }
514getOpenImpl :: Idris [Name]
515getOpenImpl = do ist <- getIState
516 return (idris_openimpls ist)
518addInterface :: Name -> InterfaceInfo -> Idris ()
520 = do ist <- getIState
521 let i' = case lookupCtxt n (idris_interfaces ist) of
522 [c] -> i { interface_implementations = interface_implementations c ++
523 interface_implementations i }
525 putIState $ ist { idris_interfaces = addDef n i' (idris_interfaces ist) }
527updateIMethods :: Name -> [(Name, PTerm)] -> Idris ()
528updateIMethods n meths
529 = do ist <- getIState
530 let i = case lookupCtxtExact n (idris_interfaces ist) of
531 Just c -> c { interface_methods = update (interface_methods c) }
532 Nothing -> error "Can't happen updateIMethods"
533 putIState $ ist { idris_interfaces = addDef n i (idris_interfaces ist) }
536 update (m@(n, (b, opts, t)) : rest)
537 | Just ty <- lookup n meths
538 = (n, (b, opts, ty)) : update rest
539 | otherwise = m : update rest
541addRecord :: Name -> RecordInfo -> Idris ()
542addRecord n ri = do ist <- getIState
543 putIState $ ist { idris_records = addDef n ri (idris_records ist) }
545addAutoHint :: Name -> Name -> Idris ()
548 case lookupCtxtExact n (idris_autohints ist) of
550 do let hs = addDef n [hint] (idris_autohints ist)
551 putIState $ ist { idris_autohints = hs }
553 do let hs = addDef n (hint : nhints) (idris_autohints ist)
554 putIState $ ist { idris_autohints = hs }
556getAutoHints :: Name -> Idris [Name]
557getAutoHints n = do ist <- getIState
558 case lookupCtxtExact n (idris_autohints ist) of
562addIBC :: IBCWrite -> Idris ()
565 when (notDef (ibc_write i)) $
566 putIState $ i { ibc_write = ibc : ibc_write i }
567 where notDef [] = True
568 notDef (IBCDef n': _) | n == n' = False
569 notDef (_ : is) = notDef is
570addIBC ibc = do i <- getIState; putIState $ i { ibc_write = ibc : ibc_write i }
573clearIBC = do i <- getIState; putIState $ i { ibc_write = [],
574 idris_inmodule = S.empty }
576resetNameIdx :: Idris ()
577resetNameIdx = do i <- getIState
578 put (i { idris_nameIdx = (0, emptyContext) })
580-- | Used to preserve sharing of names
581addNameIdx :: Name -> Idris (Int, Name)
582addNameIdx n = do i <- getIState
583 let (i', x) = addNameIdx' i n
587addNameIdx' :: IState -> Name -> (IState, (Int, Name))
589 = let idxs = snd (idris_nameIdx i) in
590 case lookupCtxt n idxs of
592 _ -> let i' = fst (idris_nameIdx i) + 1 in
593 (i { idris_nameIdx = (i', addDef n (i', n) idxs) }, (i', n))
595getSymbol :: Name -> Idris Name
596getSymbol n = do i <- getIState
597 case M.lookup n (idris_symbols i) of
599 Nothing -> do let sym' = M.insert n n (idris_symbols i)
600 put (i { idris_symbols = sym' })
603getHdrs :: Codegen -> Idris [String]
604getHdrs tgt = do i <- getIState; return (forCodegen tgt $ idris_hdrs i)
606getImported :: Idris [(FilePath, Bool)]
607getImported = idris_imported `fmap` getIState
609setErrSpan :: FC -> Idris ()
610setErrSpan x = do i <- getIState;
612 Nothing -> putIState $ i { errSpan = Just x }
616clearErr = do i <- getIState
617 putIState $ i { errSpan = Nothing }
619getSO :: Idris (Maybe String)
620getSO = do i <- getIState
621 return (compiled_so i)
623setSO :: Maybe String -> Idris ()
624setSO s = do i <- getIState
625 putIState (i { compiled_so = s })
627getIState :: Idris IState
630putIState :: IState -> Idris ()
633updateIState :: (IState -> IState) -> Idris ()
634updateIState f = do i <- getIState
637withContext :: (IState -> Ctxt a) -> Name -> b -> (a -> Idris b) -> Idris b
638withContext ctx name dflt action = do
640 case lookupCtxt name (ctx ist) of
644withContext_ :: (IState -> Ctxt a) -> Name -> (a -> Idris ()) -> Idris ()
645withContext_ ctx name action = withContext ctx name () action
647-- | A version of liftIO that puts errors into the exception type of
649runIO :: IO a -> Idris a
650runIO x = liftIO (tryIOError x) >>= either (throwError . Msg . show) return
651-- TODO: create specific Idris exceptions for specific IO errors such as "openFile: does not exist"
653-- Issue #1738 on the issue tracker.
654-- https://github.com/idris-lang/Idris-dev/issues/1738
657getName = do i <- getIState;
658 let idx = idris_name i;
659 putIState (i { idris_name = idx + 1 })
662-- | InternalApp keeps track of the real function application for
663-- making case splits from, not the application the programmer wrote,
664-- which doesn't have the whole context in any case other than top
666addInternalApp :: FilePath -> Int -> PTerm -> Idris ()
669 -- We canonicalise the path to make "./Test/Module.idr" equal
670 -- to "Test/Module.idr"
671 exists <- runIO $ doesFileExist fp
673 do fp' <- runIO $ canonicalizePath fp
674 putIState (i { idris_lineapps = ((fp', l), t) : idris_lineapps i })
676getInternalApp :: FilePath -> Int -> Idris PTerm
677getInternalApp fp l = do i <- getIState
678 -- We canonicalise the path to make
679 -- "./Test/Module.idr" equal to
681 exists <- runIO $ doesFileExist fp
683 then do fp' <- runIO $ canonicalizePath fp
684 case lookup (fp', l) (idris_lineapps i) of
686 Nothing -> return Placeholder
687 -- TODO: What if it's not there?
688 else return Placeholder
690-- | Pattern definitions are only used for coverage checking, so erase
691-- them when we're done
692clearOrigPats :: Idris ()
693clearOrigPats = do i <- get
694 let ps = idris_patdefs i
695 let ps' = mapCtxt (\ (_,miss) -> ([], miss)) ps
696 put (i { idris_patdefs = ps' })
698-- | Erase types from Ps in the context (basically ending up with
699-- what's in the .ibc, which is all we need after all the analysis is
701clearPTypes :: Idris ()
702clearPTypes = do i <- get
704 put (i { tt_ctxt = mapDefCtxt pErase ctxt })
705 where pErase (CaseOp c t tys orig _ cds)
706 = CaseOp c t tys orig [] (pErase' cds)
708 pErase' (CaseDefs (cs, c) rs)
709 = let c' = (cs, fmap pEraseType c) in
712checkUndefined :: FC -> Name -> Idris ()
716 (_:_) -> throwError . Msg $ show fc ++ ":" ++
717 show n ++ " already defined"
720isUndefined :: FC -> Name -> Idris Bool
723 case lookupTyExact n i of
724 Just _ -> return False
727setContext :: Context -> Idris ()
728setContext ctxt = do i <- getIState; putIState (i { tt_ctxt = ctxt } )
730updateContext :: (Context -> Context) -> Idris ()
731updateContext f = do i <- getIState; putIState (i { tt_ctxt = f (tt_ctxt i) } )
733addConstraints :: FC -> (Int, [UConstraint]) -> Idris ()
734addConstraints fc (v, cs)
735 = do tit <- typeInType
739 let ctxt' = ctxt { next_tvar = v }
740 let ics = insertAll (zip cs (repeat fc)) (idris_constraints i)
741 putIState $ i { tt_ctxt = ctxt', idris_constraints = ics }
744 insertAll ((ULE (UVal 0) _, fc) : cs) ics = insertAll cs ics
745 insertAll ((ULE x y, fc) : cs) ics | x == y = insertAll cs ics
746 insertAll ((c, fc) : cs) ics
747 = insertAll cs $ S.insert (ConstraintFC c fc) ics
749addDeferred = addDeferred' Ref
750addDeferredTyCon = addDeferred' (TCon 0 0)
752-- | Save information about a name that is not yet defined
753addDeferred' :: NameType
754 -> [(Name, (Int, Maybe Name, Type, [Name], Bool, Bool))]
755 -- ^ The Name is the name being made into a metavar,
756 -- the Int is the number of vars that are part of a
757 -- putative proof context, the Maybe Name is the
758 -- top-level function containing the new metavariable,
759 -- the Type is its type, and the Bool is whether :p is
763 = do mapM_ (\(n, (i, _, t, _, _, _)) -> updateContext (addTyDecl n nt (tidyNames S.empty t))) ns
764 mapM_ (\(n, _) -> when (not (n `elem` primDefs)) $ addIBC (IBCMetavar n)) ns
766 putIState $ i { idris_metavars = map (\(n, (i, top, _, ns, isTopLevel, isDefinable)) ->
767 (n, (top, i, ns, isTopLevel, isDefinable))) ns ++
770 -- 'tidyNames' is to generate user accessible names in case they are
771 -- needed in tactic scripts
772 tidyNames used (Bind (MN i x) b sc)
773 = let n' = uniqueNameSet (UN x) used in
774 Bind n' b $ tidyNames (S.insert n' used) sc
775 tidyNames used (Bind n b sc)
776 = let n' = uniqueNameSet n used in
777 Bind n' b $ tidyNames (S.insert n' used) sc
780solveDeferred :: FC -> Name -> Idris ()
783 case lookup n (idris_metavars i) of
784 Just (_, _, _, _, False) ->
785 throwError $ At fc $ Msg ("Can't define hole " ++ show n ++ " as it depends on other holes")
786 _ -> putIState $ i { idris_metavars =
787 filter (\(n', _) -> n/=n')
790 filter (notMV n) (ibc_write i)
792 where notMV n (IBCMetavar n') = not (n == n')
795getUndefined :: Idris [Name]
796getUndefined = do i <- getIState
797 return (map fst (idris_metavars i) \\ primDefs)
799isMetavarName :: Name -> IState -> Bool
801 = case lookupNames n (tt_ctxt ist) of
802 (t:_) -> isJust $ lookup t (idris_metavars ist)
805getWidth :: Idris ConsoleWidth
806getWidth = fmap idris_consolewidth getIState
808setWidth :: ConsoleWidth -> Idris ()
809setWidth w = do ist <- getIState
810 put ist { idris_consolewidth = w }
812setDepth :: Maybe Int -> Idris ()
813setDepth d = do ist <- getIState
814 put ist { idris_options = (idris_options ist) { opt_printdepth = d } }
816typeDescription :: String
817typeDescription = "The type of types"
820type1Doc :: Doc OutputAnnotation
821type1Doc = (annotate (AnnType "Type" "The type of types, one level up") $ text "Type 1")
824isetPrompt :: String -> Idris ()
825isetPrompt p = do i <- getIState
826 case idris_outputmode i of
827 IdeMode n h -> runIO . hPutStrLn h $ convSExp "set-prompt" p n
829-- | Tell clients how much was parsed and loaded
830isetLoadedRegion :: Idris ()
831isetLoadedRegion = do i <- getIState
832 let span = idris_parsedSpan i
835 case idris_outputmode i of
837 runIO . hPutStrLn h $
838 convSExp "set-loaded-region" fc n
841setLogLevel :: Int -> Idris ()
842setLogLevel l = do i <- getIState
843 let opts = idris_options i
844 let opt' = opts { opt_logLevel = l }
845 putIState $ i { idris_options = opt' }
847setLogCats :: [LogCat] -> Idris ()
850 let opts = idris_options i
851 let opt' = opts { opt_logcats = cs }
852 putIState $ i { idris_options = opt' }
854setCmdLine :: [Opt] -> Idris ()
855setCmdLine opts = do i <- getIState
856 let iopts = idris_options i
857 putIState $ i { idris_options = iopts { opt_cmdline = opts } }
859getCmdLine :: Idris [Opt]
860getCmdLine = do i <- getIState
861 return (opt_cmdline (idris_options i))
863getDumpHighlighting :: Idris Bool
864getDumpHighlighting = do ist <- getIState
865 return (findC (opt_cmdline (idris_options ist)))
866 where findC = elem DumpHighlights
868getDumpDefun :: Idris (Maybe FilePath)
869getDumpDefun = do i <- getIState
870 return $ findC (opt_cmdline (idris_options i))
871 where findC [] = Nothing
872 findC (DumpDefun x : _) = Just x
873 findC (_ : xs) = findC xs
875getDumpCases :: Idris (Maybe FilePath)
876getDumpCases = do i <- getIState
877 return $ findC (opt_cmdline (idris_options i))
878 where findC [] = Nothing
879 findC (DumpCases x : _) = Just x
880 findC (_ : xs) = findC xs
883logLevel = do i <- getIState
884 return (opt_logLevel (idris_options i))
886setAutoImpls :: Bool -> Idris ()
887setAutoImpls b = do i <- getIState
888 let opts = idris_options i
889 let opt' = opts { opt_autoimpls = b }
890 putIState $ i { idris_options = opt' }
892getAutoImpls :: Idris Bool
893getAutoImpls = do i <- getIState
894 return (opt_autoimpls (idris_options i))
896setErrContext :: Bool -> Idris ()
897setErrContext t = do i <- getIState
898 let opts = idris_options i
899 let opts' = opts { opt_errContext = t }
900 putIState $ i { idris_options = opts' }
902errContext :: Idris Bool
903errContext = do i <- getIState
904 return (opt_errContext (idris_options i))
906getOptimise :: Idris [Optimisation]
907getOptimise = do i <- getIState
908 return (opt_optimise (idris_options i))
910setOptimise :: [Optimisation] -> Idris ()
911setOptimise newopts = do i <- getIState
912 let opts = idris_options i
913 let opts' = opts { opt_optimise = newopts }
914 putIState $ i { idris_options = opts' }
916addOptimise :: Optimisation -> Idris ()
917addOptimise opt = do opts <- getOptimise
918 setOptimise (nub (opt : opts))
920removeOptimise :: Optimisation -> Idris ()
921removeOptimise opt = do opts <- getOptimise
922 setOptimise ((nub opts) \\ [opt])
924-- | Set appropriate optimisation set for the given level. We only
925-- have one optimisation that is configurable at the moment, however!
926setOptLevel :: Int -> Idris ()
927setOptLevel n | n <= 0 = setOptimise []
928setOptLevel 1 = setOptimise []
929setOptLevel 2 = setOptimise [PETransform]
930setOptLevel n | n >= 3 = setOptimise [PETransform]
933useREPL = do i <- getIState
934 return (opt_repl (idris_options i))
936setREPL :: Bool -> Idris ()
937setREPL t = do i <- getIState
938 let opts = idris_options i
939 let opt' = opts { opt_repl = t }
940 putIState $ i { idris_options = opt' }
942showOrigErr :: Idris Bool
943showOrigErr = do i <- getIState
944 return (opt_origerr (idris_options i))
946setShowOrigErr :: Bool -> Idris ()
947setShowOrigErr b = do i <- getIState
948 let opts = idris_options i
949 let opt' = opts { opt_origerr = b }
950 putIState $ i { idris_options = opt' }
952setAutoSolve :: Bool -> Idris ()
953setAutoSolve b = do i <- getIState
954 let opts = idris_options i
955 let opt' = opts { opt_autoSolve = b }
956 putIState $ i { idris_options = opt' }
958setNoBanner :: Bool -> Idris ()
959setNoBanner n = do i <- getIState
960 let opts = idris_options i
961 let opt' = opts { opt_nobanner = n }
962 putIState $ i { idris_options = opt' }
964getNoBanner :: Idris Bool
965getNoBanner = do i <- getIState
966 let opts = idris_options i
967 return (opt_nobanner opts)
969setEvalTypes :: Bool -> Idris ()
970setEvalTypes n = do i <- getIState
971 let opts = idris_options i
972 let opt' = opts { opt_evaltypes = n }
973 putIState $ i { idris_options = opt' }
975getDesugarNats :: Idris Bool
976getDesugarNats = do i <- getIState
977 let opts = idris_options i
978 return (opt_desugarnats opts)
981setDesugarNats :: Bool -> Idris ()
982setDesugarNats n = do i <- getIState
983 let opts = idris_options i
984 let opt' = opts { opt_desugarnats = n }
985 putIState $ i { idris_options = opt' }
987setQuiet :: Bool -> Idris ()
988setQuiet q = do i <- getIState
989 let opts = idris_options i
990 let opt' = opts { opt_quiet = q }
991 putIState $ i { idris_options = opt' }
993getQuiet :: Idris Bool
994getQuiet = do i <- getIState
995 let opts = idris_options i
996 return (opt_quiet opts)
998setCodegen :: Codegen -> Idris ()
999setCodegen t = do i <- getIState
1000 let opts = idris_options i
1001 let opt' = opts { opt_codegen = t }
1002 putIState $ i { idris_options = opt' }
1004codegen :: Idris Codegen
1005codegen = do i <- getIState
1006 return (opt_codegen (idris_options i))
1009setOutputTy :: OutputType -> Idris ()
1010setOutputTy t = do i <- getIState
1011 let opts = idris_options i
1012 let opt' = opts { opt_outputTy = t }
1013 putIState $ i { idris_options = opt' }
1015outputTy :: Idris OutputType
1016outputTy = do i <- getIState
1017 return $ opt_outputTy $ idris_options i
1019setIdeMode :: Bool -> Handle -> Idris ()
1020setIdeMode True h = do i <- getIState
1021 putIState $ i { idris_outputmode = IdeMode 0 h
1022 , idris_colourRepl = False
1024setIdeMode False _ = return ()
1026setTargetTriple :: String -> Idris ()
1027setTargetTriple t = do i <- getIState
1028 let opts = idris_options i
1029 opt' = opts { opt_triple = t }
1030 putIState $ i { idris_options = opt' }
1032targetTriple :: Idris String
1033targetTriple = do i <- getIState
1034 return (opt_triple (idris_options i))
1036setTargetCPU :: String -> Idris ()
1037setTargetCPU t = do i <- getIState
1038 let opts = idris_options i
1039 opt' = opts { opt_cpu = t }
1040 putIState $ i { idris_options = opt' }
1042targetCPU :: Idris String
1043targetCPU = do i <- getIState
1044 return (opt_cpu (idris_options i))
1049 -- Quietness overrides verbosity
1050 let quiet = opt_quiet $ idris_options i
1053 else return $ (opt_verbose $ idris_options i)
1055setVerbose :: Int -> Idris ()
1058 let opts = idris_options i
1059 let opt' = opts { opt_verbose = t }
1060 putIState $ i { idris_options = opt' }
1062iReport :: Int -> String -> Idris ()
1063iReport level msg = do
1064 verbosity <- verbose
1066 when (level <= verbosity) $
1067 case idris_outputmode i of
1068 RawOutput h -> runIO $ hPutStrLn h msg
1069 IdeMode n h -> runIO . hPutStrLn h $ convSExp "write-string" msg n
1072typeInType :: Idris Bool
1073typeInType = do i <- getIState
1074 return (opt_typeintype (idris_options i))
1076setTypeInType :: Bool -> Idris ()
1077setTypeInType t = do i <- getIState
1078 let opts = idris_options i
1079 let opt' = opts { opt_typeintype = t }
1080 putIState $ i { idris_options = opt' }
1082coverage :: Idris Bool
1083coverage = do i <- getIState
1084 return (opt_coverage (idris_options i))
1086setCoverage :: Bool -> Idris ()
1087setCoverage t = do i <- getIState
1088 let opts = idris_options i
1089 let opt' = opts { opt_coverage = t }
1090 putIState $ i { idris_options = opt' }
1092setIBCSubDir :: FilePath -> Idris ()
1093setIBCSubDir fp = do i <- getIState
1094 let opts = idris_options i
1095 let opt' = opts { opt_ibcsubdir = fp }
1096 putIState $ i { idris_options = opt' }
1098valIBCSubDir :: IState -> Idris FilePath
1099valIBCSubDir i = return (opt_ibcsubdir (idris_options i))
1101addImportDir :: FilePath -> Idris ()
1102addImportDir fp = do i <- getIState
1103 let opts = idris_options i
1104 let opt' = opts { opt_importdirs = nub $ fp : opt_importdirs opts }
1105 putIState $ i { idris_options = opt' }
1107setImportDirs :: [FilePath] -> Idris ()
1108setImportDirs fps = do i <- getIState
1109 let opts = idris_options i
1110 let opt' = opts { opt_importdirs = fps }
1111 putIState $ i { idris_options = opt' }
1113allImportDirs :: Idris [FilePath]
1114allImportDirs = do i <- getIState
1115 let optdirs = opt_importdirs (idris_options i)
1116 return ("." : reverse optdirs)
1118-- Like allImportDirs but the dirs that are a prefix of
1119-- the files path first. This makes it look in the current
1121rankedImportDirs :: FilePath -> Idris [FilePath]
1122rankedImportDirs fp = do ids <- allImportDirs
1123 let (prefixes, rest) = partition (`isPrefixOf`fp) ids
1124 return $ prefixes ++ rest
1126addSourceDir :: FilePath -> Idris ()
1127addSourceDir fp = do i <- getIState
1128 let opts = idris_options i
1129 let opts' = opts { opt_sourcedirs = nub $ fp : opt_sourcedirs opts }
1130 putIState $ i { idris_options = opts' }
1132setSourceDirs :: [FilePath] -> Idris ()
1133setSourceDirs fps = do i <- getIState
1134 let opts = idris_options i
1135 let opts' = opts { opt_sourcedirs = nub $ fps }
1136 putIState $ i { idris_options = opts' }
1138allSourceDirs :: Idris [FilePath]
1139allSourceDirs = do i <- getIState
1140 let optdirs = opt_sourcedirs (idris_options i)
1141 return ("." : reverse optdirs)
1143colourise :: Idris Bool
1144colourise = do i <- getIState
1145 return $ idris_colourRepl i
1147setColourise :: Bool -> Idris ()
1148setColourise b = do i <- getIState
1149 putIState $ i { idris_colourRepl = b }
1151impShow :: Idris Bool
1152impShow = do i <- getIState
1153 return (opt_showimp (idris_options i))
1155setImpShow :: Bool -> Idris ()
1156setImpShow t = do i <- getIState
1157 let opts = idris_options i
1158 let opt' = opts { opt_showimp = t }
1159 putIState $ i { idris_options = opt' }
1161setColour :: ColourType -> IdrisColour -> Idris ()
1162setColour ct c = do i <- getIState
1163 let newTheme = setColour' ct c (idris_colourTheme i)
1164 putIState $ i { idris_colourTheme = newTheme }
1165 where setColour' KeywordColour c t = t { keywordColour = c }
1166 setColour' BoundVarColour c t = t { boundVarColour = c }
1167 setColour' ImplicitColour c t = t { implicitColour = c }
1168 setColour' FunctionColour c t = t { functionColour = c }
1169 setColour' TypeColour c t = t { typeColour = c }
1170 setColour' DataColour c t = t { dataColour = c }
1171 setColour' PromptColour c t = t { promptColour = c }
1172 setColour' PostulateColour c t = t { postulateColour = c }
1174logLvl :: Int -> String -> Idris ()
1175logLvl = logLvlCats []
1177logCoverage :: Int -> String -> Idris ()
1178logCoverage = logLvlCats [ICoverage]
1180logErasure :: Int -> String -> Idris ()
1181logErasure = logLvlCats [IErasure]
1183-- | Log an action of the parser
1184logParser :: Int -> String -> Idris ()
1185logParser = logLvlCats parserCats
1187-- | Log an action of the elaborator.
1188logElab :: Int -> String -> Idris ()
1189logElab = logLvlCats elabCats
1191-- | Log an action of the compiler.
1192logCodeGen :: Int -> String -> Idris ()
1193logCodeGen = logLvlCats codegenCats
1195logIBC :: Int -> String -> Idris ()
1196logIBC = logLvlCats [IIBC]
1198-- | Log aspect of Idris execution
1200-- An empty set of logging levels is used to denote all categories.
1202-- @TODO update IDE protocol
1203logLvlCats :: [LogCat] -- ^ The categories that the message should appear under.
1204 -> Int -- ^ The Logging level the message should appear.
1205 -> String -- ^ The message to show the developer.
1207logLvlCats cs l msg = do
1209 let lvl = opt_logLevel (idris_options i)
1210 let cats = opt_logcats (idris_options i)
1212 when (inCat cs cats || null cats) $
1213 case idris_outputmode i of
1215 runIO $ hPutStrLn h msg
1217 let good = SexpList [IntegerAtom (toInteger l), toSExp msg]
1218 runIO . hPutStrLn h $ convSExp "log" good n
1220 inCat :: [LogCat] -> [LogCat] -> Bool
1221 inCat cs cats = any (`elem` cats) cs
1223cmdOptType :: Opt -> Idris Bool
1224cmdOptType x = do i <- getIState
1225 return $ x `elem` opt_cmdline (idris_options i)
1227noErrors :: Idris Bool
1228noErrors = do i <- getIState
1230 Nothing -> return True
1233setTypeCase :: Bool -> Idris ()
1234setTypeCase t = do i <- getIState
1235 let opts = idris_options i
1236 let opt' = opts { opt_typecase = t }
1237 putIState $ i { idris_options = opt' }
1239getIndentWith :: Idris Int
1242 return $ interactiveOpts_indentWith (idris_interactiveOpts i)
1244setIndentWith :: Int -> Idris ()
1245setIndentWith indentWith = do
1247 let opts = idris_interactiveOpts i
1248 let opts' = opts { interactiveOpts_indentWith = indentWith }
1249 putIState $ i { idris_interactiveOpts = opts' }
1251getIndentClause :: Idris Int
1254 return $ interactiveOpts_indentClause (idris_interactiveOpts i)
1256setIndentClause :: Int -> Idris ()
1257setIndentClause indentClause = do
1259 let opts = idris_interactiveOpts i
1260 let opts' = opts { interactiveOpts_indentClause = indentClause }
1261 putIState $ i { idris_interactiveOpts = opts' }
1263-- Dealing with parameters
1265expandParams :: (Name -> Name) -> [(Name, PTerm)] ->
1266 [Name] -> -- all names
1267 [Name] -> -- names with no declaration
1269expandParams dec ps ns infs tm = en 0 tm
1271 -- if we shadow a name (say in a lambda binding) that is used in a call to
1272 -- a lifted function, we need access to both names - once in the scope of the
1273 -- binding and once to call the lifted functions. So we'll explicitly shadow
1274 -- it. (Yes, it's a hack. The alternative would be to resolve names earlier
1275 -- but we didn't...)
1277 mkShadow (UN n) = MN 0 n
1278 mkShadow (MN i n) = MN (i+1) n
1279 mkShadow (NS x s) = NS (mkShadow x) s
1281 en :: Int -- ^ The quotation level - only transform terms that are used, not terms
1282 -- that are merely mentioned.
1284 en 0 (PLam fc n nfc t s)
1285 | n `elem` (map fst ps ++ ns)
1286 = let n' = mkShadow n in
1287 PLam fc n' nfc (en 0 t) (en 0 (shadow n n' s))
1288 | otherwise = PLam fc n nfc (en 0 t) (en 0 s)
1289 en 0 (PPi p n nfc t s)
1290 | n `elem` (map fst ps ++ ns)
1291 = let n' = mkShadow n in -- TODO THINK SHADOWING TacImp?
1292 PPi (enTacImp 0 p) n' nfc (en 0 t) (en 0 (shadow n n' s))
1293 | otherwise = PPi (enTacImp 0 p) n nfc (en 0 t) (en 0 s)
1294 en 0 (PLet fc rc n nfc ty v s)
1295 | n `elem` (map fst ps ++ ns)
1296 = let n' = mkShadow n in
1297 PLet fc rc n' nfc (en 0 ty) (en 0 v) (en 0 (shadow n n' s))
1298 | otherwise = PLet fc rc n nfc (en 0 ty) (en 0 v) (en 0 s)
1299 -- FIXME: Should only do this in a type signature!
1300 en 0 (PDPair f hls p (PRef f' fcs n) t r)
1301 | n `elem` (map fst ps ++ ns) && t /= Placeholder
1302 = let n' = mkShadow n in
1303 PDPair f hls p (PRef f' fcs n') (en 0 t) (en 0 (shadow n n' r))
1304 en 0 (PRewrite f by l r g) = PRewrite f by (en 0 l) (en 0 r) (fmap (en 0) g)
1305 en 0 (PTyped l r) = PTyped (en 0 l) (en 0 r)
1306 en 0 (PPair f hls p l r) = PPair f hls p (en 0 l) (en 0 r)
1307 en 0 (PDPair f hls p l t r) = PDPair f hls p (en 0 l) (en 0 t) (en 0 r)
1308 en 0 (PAlternative ns a as) = PAlternative ns a (map (en 0) as)
1309 en 0 (PHidden t) = PHidden (en 0 t)
1310 en 0 (PUnifyLog t) = PUnifyLog (en 0 t)
1311 en 0 (PDisamb ds t) = PDisamb ds (en 0 t)
1312 en 0 (PNoImplicits t) = PNoImplicits (en 0 t)
1313 en 0 (PDoBlock ds) = PDoBlock (map (fmap (en 0)) ds)
1314 en 0 (PProof ts) = PProof (map (fmap (en 0)) ts)
1315 en 0 (PTactics ts) = PTactics (map (fmap (en 0)) ts)
1317 en 0 (PQuote (Var n))
1318 | n `nselem` ns = PQuote (Var (dec n))
1319 en 0 (PApp fc (PInferRef fc' hl n) as)
1320 | n `nselem` ns = PApp fc (PInferRef fc' hl (dec n))
1321 (map ((pexp . (PRef fc hl)) . fst) ps ++ (map (fmap (en 0)) as))
1322 en 0 (PApp fc (PRef fc' hl n) as)
1323 | n `elem` infs = PApp fc (PInferRef fc' hl (dec n))
1324 (map ((pexp . (PRef fc hl)) . fst) ps ++ (map (fmap (en 0)) as))
1325 | n `nselem` ns = PApp fc (PRef fc' hl (dec n))
1326 (map ((pexp . (PRef fc hl)) . fst) ps ++ (map (fmap (en 0)) as))
1327 en 0 (PAppBind fc (PRef fc' hl n) as)
1328 | n `elem` infs = PAppBind fc (PInferRef fc' hl (dec n))
1329 (map ((pexp . (PRef fc hl)) . fst) ps ++ (map (fmap (en 0)) as))
1330 | n `nselem` ns = PAppBind fc (PRef fc' hl (dec n))
1331 (map ((pexp . (PRef fc hl)) . fst) ps ++ (map (fmap (en 0)) as))
1333 | n `elem` infs = PApp fc (PInferRef fc hl (dec n))
1334 (map ((pexp . (PRef fc hl)) . fst) ps)
1335 | n `nselem` ns = PApp fc (PRef fc hl (dec n))
1336 (map ((pexp . (PRef fc hl)) . fst) ps)
1337 en 0 (PInferRef fc hl n)
1338 | n `nselem` ns = PApp fc (PInferRef fc hl (dec n))
1339 (map ((pexp . (PRef fc hl)) . fst) ps)
1340 en 0 (PApp fc f as) = PApp fc (en 0 f) (map (fmap (en 0)) as)
1341 en 0 (PAppBind fc f as) = PAppBind fc (en 0 f) (map (fmap (en 0)) as)
1342 en 0 (PCase fc c os) = PCase fc (en 0 c) (map (pmap (en 0)) os)
1343 en 0 (PIfThenElse fc c t f) = PIfThenElse fc (en 0 c) (en 0 t) (en 0 f)
1344 en 0 (PRunElab fc tm ns) = PRunElab fc (en 0 tm) ns
1345 en 0 (PConstSugar fc tm) = PConstSugar fc (en 0 tm)
1347 en ql (PQuasiquote tm ty) = PQuasiquote (en (ql + 1) tm) (fmap (en ql) ty)
1348 en ql (PUnquote tm) = PUnquote (en (ql - 1) tm)
1350 en ql t = descend (en ql) t
1353 nselem x (y : xs) | nseq x y = True
1354 | otherwise = nselem x xs
1356 nseq x y = nsroot x == nsroot y
1358 enTacImp ql (TacImp aos st scr rig) = TacImp aos st (en ql scr) rig
1359 enTacImp ql other = other
1361expandParamsD :: Bool -> -- True = RHS only
1363 (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PDecl -> PDecl
1364expandParamsD rhsonly ist dec ps ns (PTy doc argdocs syn fc o n nfc ty)
1365 = if n `elem` ns && (not rhsonly)
1366 then -- trace (show (n, expandParams dec ps ns ty)) $
1367 PTy doc argdocs syn fc o (dec n) nfc (piBindp expl_param ps (expandParams dec ps ns [] ty))
1368 else --trace (show (n, expandParams dec ps ns ty)) $
1369 PTy doc argdocs syn fc o n nfc (expandParams dec ps ns [] ty)
1370expandParamsD rhsonly ist dec ps ns (PPostulate e doc syn fc nfc o n ty)
1371 = if n `elem` ns && (not rhsonly)
1372 then -- trace (show (n, expandParams dec ps ns ty)) $
1373 PPostulate e doc syn fc nfc o (dec n)
1374 (piBind ps (expandParams dec ps ns [] ty))
1375 else --trace (show (n, expandParams dec ps ns ty)) $
1376 PPostulate e doc syn fc nfc o n (expandParams dec ps ns [] ty)
1377expandParamsD rhsonly ist dec ps ns (PClauses fc opts n cs)
1378 = let n' = if n `elem` ns then dec n else n in
1379 PClauses fc opts n' (map expandParamsC cs)
1381 expandParamsC (PClause fc n lhs ws rhs ds)
1382 = let -- ps' = updateps True (namesIn ist rhs) (zip ps [0..])
1383 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
1384 lhs' = if rhsonly then lhs else (expandParams dec ps'' ns [] lhs)
1385 n' = if n `elem` ns then dec n else n
1386 -- names bound on the lhs should not be expanded on the rhs
1387 ns' = removeBound lhs ns in
1389 (map (expandParams dec ps'' ns' []) ws)
1390 (expandParams dec ps'' ns' [] rhs)
1391 (map (expandParamsD True ist dec ps'' ns') ds)
1392 expandParamsC (PWith fc n lhs ws wval pn ds)
1393 = let -- ps' = updateps True (namesIn ist wval) (zip ps [0..])
1394 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
1395 lhs' = if rhsonly then lhs else (expandParams dec ps'' ns [] lhs)
1396 n' = if n `elem` ns then dec n else n
1397 ns' = removeBound lhs ns in
1399 (map (expandParams dec ps'' ns' []) ws)
1400 (expandParams dec ps'' ns' [] wval)
1402 (map (expandParamsD rhsonly ist dec ps'' ns') ds)
1403 updateps yn nm [] = []
1404 updateps yn nm (((a, t), i):as)
1405 | (a `elem` nm) == yn = (a, t) : updateps yn nm as
1406 | otherwise = (sMN i (show a ++ "_shadow"), t) : updateps yn nm as
1408 removeBound lhs ns = ns \\ nub (bnames lhs)
1410 bnames (PRef _ _ n) = [n]
1411 bnames (PApp _ _ args) = concatMap (bnames . getTm) args
1412 bnames (PPair _ _ _ l r) = bnames l ++ bnames r
1413 bnames (PDPair _ _ _ l Placeholder r) = bnames l ++ bnames r
1416-- | Expands parameters defined in parameter and where blocks inside of declarations
1417expandParamsD rhs ist dec ps ns (PData doc argDocs syn fc co pd)
1418 = PData doc argDocs syn fc co (expandPData pd)
1420 -- just do the type decl, leave constructors alone (parameters will be
1421 -- added implicitly)
1422 expandPData (PDatadecl n nfc ty cons)
1424 then PDatadecl (dec n) nfc (piBind ps (expandParams dec ps ns [] ty))
1426 else PDatadecl n nfc (expandParams dec ps ns [] ty) (map econ cons)
1427 econ (doc, argDocs, n, nfc, t, fc, fs)
1428 = (doc, argDocs, dec n, nfc, piBindp expl ps (expandParams dec ps ns [] t), fc, fs)
1429expandParamsD rhs ist dec ps ns d@(PRecord doc rsyn fc opts name nfc prs pdocs fls cn cdoc csyn)
1431expandParamsD rhs ist dec ps ns (PParams f params pds)
1432 = PParams f (ps ++ map (mapsnd (expandParams dec ps ns [])) params)
1433 (map (expandParamsD True ist dec ps ns) pds)
1434-- (map (expandParamsD ist dec ps ns) pds)
1435expandParamsD rhs ist dec ps ns (PMutual f pds)
1436 = PMutual f (map (expandParamsD rhs ist dec ps ns) pds)
1437expandParamsD rhs ist dec ps ns (PInterface doc info f cs n nfc params pDocs fds decls cn cd)
1438 = PInterface doc info f
1439 (map (\ (n, t) -> (n, expandParams dec ps ns [] t)) cs)
1441 (map (\(n, fc, t) -> (n, fc, expandParams dec ps ns [] t)) params)
1444 (map (expandParamsD rhs ist dec ps ns) decls)
1447expandParamsD rhs ist dec ps ns (PImplementation doc argDocs info f cs pnames acc opts n nfc params pextra ty cn decls)
1448 = let cn' = case cn of
1449 Just n -> if n `elem` ns then Just (dec n) else Just n
1450 Nothing -> Nothing in
1451 PImplementation doc argDocs info f
1452 (map (\ (n, t) -> (n, expandParams dec ps ns [] t)) cs)
1455 (map (expandParams dec ps ns []) params)
1456 (map (\ (n, t) -> (n, expandParams dec ps ns [] t)) pextra)
1457 (expandParams dec ps ns [] ty)
1459 (map (expandParamsD True ist dec ps ns) decls)
1460expandParamsD rhs ist dec ps ns d = d
1462mapsnd f (x, t) = (x, f t)
1464expandImplementationScope ist dec ps ns (PImplementation doc argDocs info f cs pnames acc opts n nfc params pextra ty cn decls)
1465 = PImplementation doc argDocs info f cs pnames acc opts n nfc params (ps ++ pextra)
1467expandImplementationScope ist dec ps ns d = d
1469-- | Calculate a priority for a type, for deciding elaboration order
1470-- * if it's just a type variable or concrete type, do it early (0)
1471-- * if there's only type variables and injective constructors, do it next (1)
1472-- * if there's a function type, next (2)
1473-- * finally, everything else (3)
1474getPriority :: IState -> PTerm -> Int
1477addStatics :: Name -> Term -> PTerm -> Idris ()
1478addStatics n tm ptm =
1479 do let (statics, dynamics) = initStatics tm ptm
1482 = nub $ case lookupCtxtExact n (idris_fninfo ist) of
1483 Just p -> getNamesFrom 0 (fn_params p) tm ++
1484 concatMap (getParamNames ist . snd) statics
1485 _ -> concatMap (getParamNames ist . snd) statics
1487 let stnames = nub $ concatMap (freeArgNames . snd) statics
1488 let dnames = (nub $ concatMap (freeArgNames . snd) dynamics)
1490 -- also get the arguments which are 'uniquely inferrable' from
1491 -- statics (see sec 4.2 of "Scrapping Your Inefficient Engine")
1492 -- or parameters to the type of a static
1493 let statics' = nub $ map fst statics ++
1494 filter (\x -> not (elem x dnames)) stnames
1495 let stpos = staticList statics' tm
1497 unless (null statics) $
1498 logLvl 3 $ "Statics for " ++ show n ++ " " ++ show tm ++ "\n"
1499 ++ showTmImpls ptm ++ "\n"
1500 ++ show statics ++ "\n" ++ show dynamics
1501 ++ "\n" ++ show paramnames
1502 ++ "\n" ++ show stpos
1503 putIState $ i { idris_statics = addDef n stpos (idris_statics i) }
1504 addIBC (IBCStatic n)
1506 initStatics (Bind n (Pi _ _ ty _) sc) (PPi p n' fc t s)
1507 | n /= n' = let (static, dynamic) = initStatics sc (PPi p n' fc t s) in
1508 (static, (n, ty) : dynamic)
1509 initStatics (Bind n (Pi _ _ ty _) sc) (PPi p n' fc _ s)
1510 = let (static, dynamic) = initStatics (instantiate (P Bound n ty) sc) s in
1511 if pstatic p == Static then ((n, ty) : static, dynamic)
1512 else if (not (searchArg p))
1513 then (static, (n, ty) : dynamic)
1514 else (static, dynamic)
1515 initStatics t pt = ([], [])
1517 getParamNames ist tm | (P _ n _ , args) <- unApply tm
1518 = case lookupCtxtExact n (idris_datatypes ist) of
1519 Just ti -> getNamePos 0 (param_pos ti) args
1521 where getNamePos i ps [] = []
1522 getNamePos i ps (P _ n _ : as)
1523 | i `elem` ps = n : getNamePos (i + 1) ps as
1524 getNamePos i ps (_ : as) = getNamePos (i + 1) ps as
1525 getParamNames ist (Bind t (Pi _ _ (P _ n _) _) sc)
1526 = n : getParamNames ist sc
1527 getParamNames ist _ = []
1529 getNamesFrom i ps (Bind n (Pi _ _ _ _) sc)
1530 | i `elem` ps = n : getNamesFrom (i + 1) ps sc
1531 | otherwise = getNamesFrom (i + 1) ps sc
1532 getNamesFrom i ps sc = []
1534 freeArgNames (Bind n (Pi _ _ ty _) sc)
1535 = nub $ freeNames ty ++ freeNames sc -- treat '->' as fn here
1536 freeArgNames tm = let (_, args) = unApply tm in
1537 concatMap freeNames args
1539 -- if a name appears in an interface or tactic implicit index, it doesn't
1540 -- affect its 'uniquely inferrable' from a static status since these are
1541 -- resolved by searching.
1542 searchArg (Constraint _ _ _) = True
1543 searchArg (TacImp _ _ _ _) = True
1546 staticList sts (Bind n (Pi _ _ _ _) sc) = (n `elem` sts) : staticList sts sc
1549-- Dealing with implicit arguments
1551-- Add some bound implicits to the using block if they aren't there already
1553addToUsing :: [Using] -> [(Name, PTerm)] -> [Using]
1554addToUsing us [] = us
1555addToUsing us ((n, t) : ns)
1556 | n `notElem` mapMaybe impName us = addToUsing (us ++ [UImplicit n t]) ns
1557 | otherwise = addToUsing us ns
1558 where impName (UImplicit n _) = Just n
1561-- Add constraint bindings from using block
1563addUsingConstraints :: SyntaxInfo -> FC -> PTerm -> Idris PTerm
1564addUsingConstraints syn fc t
1566 let ns = namesIn [] ist t
1567 let cs = getConstraints t -- check declared constraints
1568 let addconsts = uconsts \\ cs
1569 return (doAdd addconsts ns t)
1570 where uconsts = filter uconst (using syn)
1571 uconst (UConstraint _ _) = True
1575 -- if all of args in ns, then add it
1576 doAdd (UConstraint c args : cs) ns t
1577 | all (\n -> elem n ns) args
1578 = PPi (Constraint [] Dynamic RigW) (sMN 0 "cu") NoFC
1579 (mkConst c args) (doAdd cs ns t)
1580 | otherwise = doAdd cs ns t
1582 mkConst c args = PApp fc (PRef fc [] c)
1583 (map (PExp 0 [] (sMN 0 "carg") . PRef fc []) args)
1585 getConstraints (PPi (Constraint _ _ _) _ _ c sc)
1586 = getcapp c ++ getConstraints sc
1587 getConstraints (PPi _ _ _ c sc) = getConstraints sc
1588 getConstraints _ = []
1590 getcapp (PApp _ (PRef _ _ c) args)
1591 = do ns <- mapM getName args
1592 return (UConstraint c ns)
1595 getName (PExp _ _ _ (PRef _ _ n)) = return n
1598-- | Add implicit bindings from using block, and bind any missing names
1599addUsingImpls :: SyntaxInfo -> Name -> FC -> PTerm -> Idris PTerm
1600addUsingImpls syn n fc t
1601 = do ist <- getIState
1602 autoimpl <- getAutoImpls
1603 let ns_in = implicitNamesIn (map iname uimpls) ist t
1604 let ns = if autoimpl then ns_in
1605 else filter (\n -> n `elem` (map iname uimpls)) ns_in
1607 let badnames = filter (\n -> not (implicitable n) &&
1608 n `notElem` (map iname uimpls)) ns
1609 unless (null badnames) $
1610 throwError (At fc (Elaborating "type of " n Nothing
1611 (NoSuchVariable (head badnames))))
1612 let cs = getArgnames t -- get already bound names
1613 let addimpls = filter (\n -> iname n `notElem` cs) uimpls
1614 -- if all names in the arguments of addconsts appear in ns,
1615 -- add the constraint implicitly
1616 return (bindFree ns (doAdd addimpls ns t))
1617 where uimpls = filter uimpl (using syn)
1618 uimpl (UImplicit _ _) = True
1621 iname (UImplicit n _) = n
1622 iname (UConstraint _ _) = error "Can't happen addUsingImpls"
1625 -- if all of args in ns, then add it
1626 doAdd (UImplicit n ty : cs) ns t
1628 = PPi impl_gen n NoFC ty (doAdd cs ns t)
1629 | otherwise = doAdd cs ns t
1631 -- bind the free names which weren't in the using block
1634 | elem n (map iname uimpls) = bindFree ns tm
1636 = PPi (impl_gen { pargopts = [InaccessibleArg] }) n NoFC Placeholder (bindFree ns tm)
1638 getArgnames (PPi _ n _ c sc)
1639 = n : getArgnames sc
1642-- Given the original type and the elaborated type, return the implicitness
1643-- status of each pi-bound argument, and whether it's inaccessible (True) or not.
1645getUnboundImplicits :: IState -> Type -> PTerm -> [(Bool, PArg)]
1646getUnboundImplicits i t tm = getImps t (collectImps tm)
1647 where collectImps (PPi p n _ t sc)
1648 = (n, (p, t)) : collectImps sc
1651 scopedimpl (Just i) = not (toplevel_imp i)
1652 scopedimpl _ = False
1654 getImps (Bind n (Pi _ i _ _) sc) imps
1655 | scopedimpl i = getImps sc imps
1656 getImps (Bind n (Pi _ _ t _) sc) imps
1657 | Just (p, t') <- lookup n imps = argInfo n p t' : getImps sc imps
1659 argInfo n (Imp opt _ _ _ _ _) Placeholder
1660 = (True, PImp 0 True opt n Placeholder)
1661 argInfo n (Imp opt _ _ _ _ _) t'
1662 = (InaccessibleArg `elem` opt,
1663 PImp (getPriority i t') True opt n t')
1664 argInfo n (Exp opt _ _ _) t'
1665 = (InaccessibleArg `elem` opt,
1666 PExp (getPriority i t') opt n t')
1667 argInfo n (Constraint opt _ _) t'
1668 = (InaccessibleArg `elem` opt,
1669 PConstraint 10 opt n t')
1670 argInfo n (TacImp opt _ scr _) t'
1671 = (InaccessibleArg `elem` opt,
1672 PTacImplicit 10 opt n scr t')
1673 getImps (Bind n (Pi _ _ t _) sc) imps = impBind n t : getImps sc imps
1674 where impBind n t = (True, PImp 1 True [] n Placeholder)
1677-- Add implicit Pi bindings for any names in the term which appear in an
1678-- argument position.
1680-- This has become a right mess already. Better redo it some time...
1681-- TODO: This is obsoleted by the new way of elaborating types, (which
1682-- calls addUsingImpls) but there's still a couple of places which use
1683-- it. Clean them up!
1685-- Issue 1739 in the issue tracker
1686-- https://github.com/idris-lang/Idris-dev/issues/1739
1687implicit :: ElabInfo -> SyntaxInfo -> Name -> PTerm -> Idris PTerm
1688implicit info syn n ptm = implicit' info syn [] n ptm
1690implicit' :: ElabInfo -> SyntaxInfo -> [Name] -> Name -> PTerm -> Idris PTerm
1691implicit' info syn ignore n ptm
1693 auto <- getAutoImpls
1694 let (tm', impdata) = implicitise auto syn ignore i ptm
1695 defaultArgCheck (eInfoNames info ++ M.keys (idris_implicits i)) impdata
1696-- let (tm'', spos) = findStatics i tm'
1697 putIState $ i { idris_implicits = addDef n impdata (idris_implicits i) }
1699 logLvl 5 ("Implicit " ++ show n ++ " " ++ show impdata)
1701-- putIState $ i { idris_statics = addDef n spos (idris_statics i) }
1704 -- Detect unknown names in default arguments and throw error if found.
1705 defaultArgCheck :: [Name] -> [PArg] -> Idris ()
1706 defaultArgCheck knowns params = foldM_ notFoundInDefault knowns params
1708 notFoundInDefault :: [Name] -> PArg -> Idris [Name]
1709 notFoundInDefault kns (PTacImplicit _ _ n script _)
1711 case notFound kns (namesIn [] i script) of
1712 Nothing -> return (n:kns)
1713 Just name -> throwError (NoSuchVariable name)
1714 notFoundInDefault kns p = return ((pname p):kns)
1716 notFound :: [Name] -> [Name] -> Maybe Name
1717 notFound kns [] = Nothing
1718 notFound kns (SN (WhereN _ _ _) : ns) = notFound kns ns -- Known already
1719 notFound kns (n:ns) = if elem n kns then notFound kns ns else Just n
1721-- | Even if auto_implicits is off, we need to call this so we record
1722-- which arguments are implicit
1723implicitise :: Bool -> SyntaxInfo -> [Name] -> IState -> PTerm -> (PTerm, [PArg])
1724implicitise auto syn ignore ist tm = -- trace ("INCOMING " ++ showImp True tm) $
1725 let (declimps, ns') = execState (imps True [] tm) ([], [])
1726 ns = filter (\n -> auto && implicitable n || elem n (map fst uvars)) $
1727 ns' \\ (map fst pvars ++ no_imp syn ++ ignore)
1728 nsOrder = filter (not . inUsing) ns ++ filter inUsing ns in
1730 then (tm, reverse declimps)
1731 else implicitise auto syn ignore ist (pibind uvars nsOrder tm)
1733 uvars = map ipair (filter uimplicit (using syn))
1734 pvars = syn_params syn
1736 inUsing n = n `elem` map fst uvars
1738 ipair (UImplicit x y) = (x, y)
1739 uimplicit (UImplicit _ _) = True
1742 dropAll (x:xs) ys | x `elem` ys = dropAll xs ys
1743 | otherwise = x : dropAll xs ys
1746 -- Find names in argument position in a type, suitable for implicit
1748 -- Not the function position, but do everything else...
1749 implNamesIn uv (PApp fc f args) = concatMap (implNamesIn uv . getTm) args
1750 implNamesIn uv t = implicitNamesIn (map fst uv) ist t
1752 imps top env ty@(PApp _ f as)
1753 = do (decls, ns) <- get
1754 let isn = nub (implNamesIn uvars ty)
1755 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1756 imps top env (PPi (Imp l _ _ _ _ _) n _ ty sc)
1757 = do let isn = nub (implNamesIn uvars ty) `dropAll` [n]
1759 put (PImp (getPriority ist ty) True l n Placeholder : decls,
1760 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1761 imps True (n:env) sc
1762 imps top env (PPi (Exp l _ _ _) n _ ty sc)
1763 = do let isn = nub (implNamesIn uvars ty ++ case sc of
1764 (PRef _ _ x) -> namesIn uvars ist sc `dropAll` [n]
1766 (decls, ns) <- get -- ignore decls in HO types
1767 put (PExp (getPriority ist ty) l n Placeholder : decls,
1768 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1769 imps True (n:env) sc
1770 imps top env (PPi (Constraint l _ _) n _ ty sc)
1771 = do let isn = nub (implNamesIn uvars ty ++ case sc of
1772 (PRef _ _ x) -> namesIn uvars ist sc `dropAll` [n]
1774 (decls, ns) <- get -- ignore decls in HO types
1775 put (PConstraint 10 l n Placeholder : decls,
1776 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1777 imps True (n:env) sc
1778 imps top env (PPi (TacImp l _ scr _) n _ ty sc)
1779 = do let isn = nub (implNamesIn uvars ty ++ case sc of
1780 (PRef _ _ x) -> namesIn uvars ist sc `dropAll` [n]
1782 (decls, ns) <- get -- ignore decls in HO types
1783 put (PTacImplicit 10 l n scr Placeholder : decls,
1784 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1785 imps True (n:env) sc
1786 imps top env (PRewrite _ _ l r _)
1787 = do (decls, ns) <- get
1788 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1789 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1790 imps top env (PTyped l r)
1792 imps top env (PPair _ _ _ l r)
1793 = do (decls, ns) <- get
1794 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1795 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1796 imps top env (PDPair _ _ _ (PRef _ _ n) t r)
1797 = do (decls, ns) <- get
1798 let isn = nub (namesIn uvars ist t ++ namesIn uvars ist r) \\ [n]
1799 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1800 imps top env (PDPair _ _ _ l t r)
1801 = do (decls, ns) <- get
1802 let isn = namesIn uvars ist l ++ namesIn uvars ist t ++
1804 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1805 imps top env (PAlternative ms a as)
1806 = do (decls, ns) <- get
1807 let isn = concatMap (namesIn uvars ist) as
1808 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1809 imps top env (PLam fc n _ ty sc)
1810 = do imps False env ty
1811 imps False (n:env) sc
1812 imps top env (PHidden tm) = imps False env tm
1813 imps top env (PUnifyLog tm) = imps False env tm
1814 imps top env (PNoImplicits tm) = imps False env tm
1815 imps top env (PRunElab fc tm ns) = imps False env tm
1816 imps top env (PConstSugar fc tm) = imps top env tm -- ignore PConstSugar - it's for highlighting only!
1817 imps top env _ = return ()
1819 pibind using [] sc = sc
1820 pibind using (n:ns) sc
1821 = case lookup n using of
1822 Just ty -> PPi impl_gen
1823 n NoFC ty (pibind using ns sc)
1824 Nothing -> PPi (impl_gen { pargopts = [InaccessibleArg] })
1825 n NoFC Placeholder (pibind using ns sc)
1827-- | Add implicit arguments in function calls
1828addImplPat :: IState -> PTerm -> PTerm
1829addImplPat = addImpl' True [] [] []
1831addImplBound :: IState -> [Name] -> PTerm -> PTerm
1832addImplBound ist ns = addImpl' False ns [] [] ist
1834addImplBoundInf :: IState -> [Name] -> [Name] -> PTerm -> PTerm
1835addImplBoundInf ist ns inf = addImpl' False ns inf [] ist
1837-- | Add the implicit arguments to applications in the term [Name]
1838-- gives the names to always expend, even when under a binder of that
1839-- name (this is to expand methods with implicit arguments in
1840-- dependent interfaces).
1841addImpl :: [Name] -> IState -> PTerm -> PTerm
1842addImpl = addImpl' False [] []
1844-- TODO: in patterns, don't add implicits to function names guarded by constructors
1845-- and *not* inside a PHidden
1847addImpl' :: Bool -> [Name] -> [Name] -> [Name] -> IState -> PTerm -> PTerm
1848addImpl' inpat env infns imp_meths ist ptm
1849 = ai inpat False (zip env (repeat Nothing)) [] (mkUniqueNames env [] ptm)
1851 allowcap = AllowCapitalizedPatternVariables `elem` opt_cmdline (idris_options ist)
1853 topname = case ptm of
1855 PApp _ (PRef _ _ n) _ -> n
1856 _ -> sUN "" -- doesn't matter then
1858 ai :: Bool -> Bool -> [(Name, Maybe PTerm)] -> [[T.Text]] -> PTerm -> PTerm
1859 ai inpat qq env ds (PRef fc fcs f)
1860 | f `elem` infns = PInferRef fc fcs f
1861 | not (f `elem` map fst env) = handleErr $ aiFn topname allowcap inpat inpat qq imp_meths ist fc f fc ds []
1862 ai inpat qq env ds (PHidden (PRef fc hl f))
1863 | not (f `elem` map fst env) = PHidden (handleErr $ aiFn topname allowcap inpat False qq imp_meths ist fc f fc ds [])
1864 ai inpat qq env ds (PRewrite fc by l r g)
1865 = let l' = ai inpat qq env ds l
1866 r' = ai inpat qq env ds r
1867 g' = fmap (ai inpat qq env ds) g in
1868 PRewrite fc by l' r' g'
1869 ai inpat qq env ds (PTyped l r)
1870 = let l' = ai inpat qq env ds l
1871 r' = ai inpat qq env ds r in
1873 ai inpat qq env ds (PPair fc hls p l r)
1874 = let l' = ai inpat qq env ds l
1875 r' = ai inpat qq env ds r in
1876 PPair fc hls p l' r'
1877 ai inpat qq env ds (PDPair fc hls p l t r)
1878 = let l' = ai inpat qq env ds l
1879 t' = ai inpat qq env ds t
1880 r' = ai inpat qq env ds r in
1881 PDPair fc hls p l' t' r'
1882 ai inpat qq env ds (PAlternative ms a as)
1883 = let as' = map (ai inpat qq env ds) as in
1884 PAlternative ms a as'
1885 ai inpat qq env _ (PDisamb ds' as) = ai inpat qq env ds' as
1886 ai inpat qq env ds (PApp fc (PInferRef ffc hl f) as)
1887 = let as' = map (fmap (ai inpat qq env ds)) as in
1888 PApp fc (PInferRef ffc hl f) as'
1889 ai inpat qq env ds (PApp fc ftm@(PRef ffc hl f) as)
1890 | f `elem` infns = ai inpat qq env ds (PApp fc (PInferRef ffc hl f) as)
1891 | not (f `elem` map fst env)
1892 = let as' = map (fmap (ai inpat qq env ds)) as in
1893 handleErr $ aiFn topname allowcap inpat False qq imp_meths ist fc f ffc ds as'
1894 | Just (Just ty) <- lookup f env =
1895 let as' = map (fmap (ai inpat qq env ds)) as
1896 arity = getPArity ty in
1897 mkPApp fc arity ftm as'
1898 ai inpat qq env ds (PApp fc f as)
1899 = let f' = ai inpat qq env ds f
1900 as' = map (fmap (ai inpat qq env ds)) as in
1902 ai inpat qq env ds (PWithApp fc f a)
1903 = PWithApp fc (ai inpat qq env ds f) (ai inpat qq env ds a)
1904 ai inpat qq env ds (PCase fc c os)
1905 = let c' = ai inpat qq env ds c in
1906 -- leave lhs alone, because they get lifted into a new pattern match
1907 -- definition which is passed through addImpl again
1908 PCase fc c' (map aiCase os)
1911 = (lhs, ai inpat qq (env ++ patnames lhs) ds rhs)
1913 -- Anything beginning with a lower case letter, not applied,
1914 -- and no namespace is a pattern variable
1915 patnames (PApp _ (PRef _ _ f) [])
1916 | implicitable f = [(f, Nothing)]
1917 patnames (PRef _ _ f)
1918 | implicitable f = [(f, Nothing)]
1919 patnames (PApp _ (PRef _ _ _) args)
1920 = concatMap patnames (map getTm args)
1921 patnames (PPair _ _ _ l r) = patnames l ++ patnames r
1922 patnames (PDPair _ _ _ l t r) = patnames l ++ patnames t ++ patnames r
1923 patnames (PAs _ _ t) = patnames t
1924 patnames (PAlternative _ _ ts) = concatMap patnames ts
1928 ai inpat qq env ds (PIfThenElse fc c t f) = PIfThenElse fc (ai inpat qq env ds c)
1929 (ai inpat qq env ds t)
1930 (ai inpat qq env ds f)
1932 -- If the name in a lambda is an unapplied data constructor name, do this
1933 -- as a 'case' instead because we'll expect to match on it
1934 ai inpat qq env ds (PLam fc n nfc ty sc)
1935 = if canBeDConName n (tt_ctxt ist)
1936 then ai inpat qq env ds (PLam fc (sMN 0 "lamp") NoFC ty
1937 (PCase fc (PRef fc [] (sMN 0 "lamp") )
1938 [(PRef fc [] n, sc)]))
1939 else let ty' = ai inpat qq env ds ty
1940 sc' = ai inpat qq ((n, Just ty):env) ds sc in
1941 PLam fc n nfc ty' sc'
1942 ai inpat qq env ds (PLet fc rc n nfc ty val sc)
1943 = if canBeDConName n (tt_ctxt ist)
1944 then ai inpat qq env ds (PCase fc val [(PRef fc [] n, sc)])
1945 else let ty' = ai inpat qq env ds ty
1946 val' = ai inpat qq env ds val
1947 sc' = ai inpat qq ((n, Just ty):env) ds sc in
1948 PLet fc rc n nfc ty' val' sc'
1949 ai inpat qq env ds (PPi p n nfc ty sc)
1950 = let ty' = ai inpat qq env ds ty
1951 env' = if n `elem` imp_meths then env
1953 ((n, Just ty) : env)
1954 sc' = ai inpat qq env' ds sc in
1956 ai inpat qq env ds (PGoal fc r n sc)
1957 = let r' = ai inpat qq env ds r
1958 sc' = ai inpat qq ((n, Nothing):env) ds sc in
1960 ai inpat qq env ds (PHidden tm) = PHidden (ai inpat qq env ds tm)
1961 -- Don't do PProof or PTactics since implicits get added when scope is
1962 -- properly known in ElabTerm.runTac
1963 ai inpat qq env ds (PUnifyLog tm) = PUnifyLog (ai inpat qq env ds tm)
1964 ai inpat qq env ds (PNoImplicits tm) = PNoImplicits (ai inpat qq env ds tm)
1965 ai inpat qq env ds (PQuasiquote tm g) = PQuasiquote (ai inpat True env ds tm)
1966 (fmap (ai inpat True env ds) g)
1967 ai inpat qq env ds (PUnquote tm) = PUnquote (ai inpat False env ds tm)
1968 ai inpat qq env ds (PRunElab fc tm ns) = PRunElab fc (ai inpat False env ds tm) ns
1969 ai inpat qq env ds (PConstSugar fc tm) = PConstSugar fc (ai inpat qq env ds tm)
1970 ai inpat qq env ds tm = tm
1972 handleErr (Left err) = PElabError err
1973 handleErr (Right x) = x
1975-- if in a pattern, and there are no arguments, and there's no possible
1976-- names with zero explicit arguments, don't add implicits.
1978aiFn :: Name -> Bool -- ^ Allow capitalization of pattern variables
1979 -> Bool -> Bool -> Bool
1982 -> Name -- ^ function being applied
1984 -> [PArg] -- ^ initial arguments (if in a pattern)
1986aiFn topname allowcap inpat True qq imp_meths ist fc f ffc ds []
1987 | inpat && implicitable f && unqualified f = Right $ PPatvar ffc f
1989 = case lookupDef f (tt_ctxt ist) of
1991 then Right $ PPatvar ffc f
1993 MN _ _ -> Right $ PPatvar ffc f
1994 UN xs | isDigit (T.head xs) -- for partial evaluation vars
1995 -> Right $ PPatvar ffc f
1996 _ -> Left $ Msg $ show f ++ " is not a valid name for a pattern variable"
1997 alts -> let ialts = lookupCtxtName f (idris_implicits ist) in
1998 -- trace (show f ++ " " ++ show (fc, any (all imp) ialts, ialts, any constructor alts)) $
1999 if (not (vname f) || tcname f
2000 || any (conCaf (tt_ctxt ist)) ialts)
2001-- any constructor alts || any allImp ialts))
2002 then aiFn topname allowcap inpat False qq imp_meths ist fc f ffc ds [] -- use it as a constructor
2003 else Right $ PPatvar ffc f
2004 where imp (PExp _ _ _ _) = False
2007 allImp xs = all imp xs
2009 unqualified (NS _ _) = False
2010 unqualified _ = True
2012 conCaf ctxt (n, cia) = (isDConName n ctxt || (qq && isTConName n ctxt)) && allImp cia
2014 vname (UN n) = True -- non qualified
2017aiFn topname allowcap inpat expat qq imp_meths ist fc f ffc ds as
2018 | f `elem` primNames = Right $ PApp fc (PRef ffc [ffc] f) as
2019aiFn topname allowcap inpat expat qq imp_meths ist fc f ffc ds as
2020 -- This is where namespaces get resolved by adding PAlternative
2021 = do let ns = lookupCtxtName f (idris_implicits ist)
2022 let nh = filter (\(n, _) -> notHidden n) ns
2023 let ns' = case trimAlts ds nh of
2027 [(f',ns)] -> Right $ mkPApp fc (length ns) (PRef ffc [ffc] (isImpName f f'))
2029 [] -> case metaVar f (map fst (idris_metavars ist)) of
2030 Just f' -> Right $ PApp fc (PRef ffc [ffc] f') as
2031 Nothing -> Right $ mkPApp fc (length as) (PRef ffc [ffc] f) as
2033 PAlternative [] (ExactlyOne True) $
2034 map (\(f', ns) -> mkPApp fc (length ns) (PRef ffc [ffc] (isImpName f f'))
2035 (insertImpl ns as)) alts
2037 -- if the name is in imp_meths, we should actually refer to the bound
2038 -- name rather than the global one after expanding implicits
2039 isImpName f f' | f `elem` imp_meths = f
2042 -- If it's a metavariable name, try to qualify it from the list of
2043 -- unsolved metavariables
2044 metaVar f (mvn : ns) | f == nsroot mvn = Just mvn
2045 metaVar f (_ : ns) = metaVar f ns
2046 metaVar f [] = Nothing
2048 trimAlts [] alts = alts
2050 = filter (\(x, _) -> any (\d -> d `isPrefixOf` nspace x) ns) alts
2055 notHidden n = case getAccessibility n of
2061 = case lookupDefAccExact n False (tt_ctxt ist) of
2065 insertImpl :: [PArg] -- ^ expected argument types (from idris_implicits)
2066 -> [PArg] -- ^ given arguments
2069 = let (as', badimpls) = partition (impIn ps) as in
2070 map addUnknownImp badimpls ++
2071 insImpAcc M.empty ps (filter expArg as') (filter (not . expArg) as')
2073 insImpAcc :: M.Map Name PTerm -- accumulated param names & arg terms
2074 -> [PArg] -- parameters
2075 -> [PArg] -- explicit arguments
2076 -> [PArg] -- implicits given
2078 insImpAcc pnas (PExp p l n ty : ps) (PExp _ _ _ tm : given) imps =
2079 PExp p l n tm : insImpAcc (M.insert n tm pnas) ps given imps
2080 insImpAcc pnas (PConstraint p l n ty : ps) (PConstraint _ _ _ tm : given) imps =
2081 PConstraint p l n tm : insImpAcc (M.insert n tm pnas) ps given imps
2082 insImpAcc pnas (PConstraint p l n ty : ps) given imps =
2083 let rtc = PResolveTC fc in
2084 PConstraint p l n rtc : insImpAcc (M.insert n rtc pnas) ps given imps
2085 insImpAcc pnas (PImp p _ l n ty : ps) given imps =
2086 case find n imps [] of
2088 PImp p False l n tm : insImpAcc (M.insert n tm pnas) ps given imps'
2090 PImp p True l n Placeholder :
2091 insImpAcc (M.insert n Placeholder pnas) ps given imps
2092 insImpAcc pnas (PTacImplicit p l n sc' ty : ps) given imps =
2093 let sc = addImpl imp_meths ist (substMatches (M.toList pnas) sc') in
2094 case find n imps [] of
2096 PTacImplicit p l n sc tm :
2097 insImpAcc (M.insert n tm pnas) ps given imps'
2100 then PTacImplicit p l n sc Placeholder :
2101 insImpAcc (M.insert n Placeholder pnas) ps given imps
2102 else PTacImplicit p l n sc sc :
2103 insImpAcc (M.insert n sc pnas) ps given imps
2104 insImpAcc _ expected [] imps = map addUnknownImp imps -- so that unused implicits give error
2105 insImpAcc _ _ given imps = given ++ imps
2107 addUnknownImp arg = arg { argopts = UnknownImp : argopts arg }
2109 find n [] acc = Nothing
2110 find n (PImp _ _ _ n' t : gs) acc
2111 | n == n' = Just (t, reverse acc ++ gs)
2112 find n (PTacImplicit _ _ n' _ t : gs) acc
2113 | n == n' = Just (t, reverse acc ++ gs)
2114 find n (g : gs) acc = find n gs (g : acc)
2116-- | return True if the second argument is an implicit argument which
2117-- is expected in the implicits, or if it's not an implicit
2118impIn :: [PArg] -> PArg -> Bool
2119impIn ps (PExp _ _ _ _) = True
2120impIn ps (PConstraint _ _ _ _) = True
2121impIn ps arg = any (\p -> not (expArg arg) && pname arg == pname p) ps
2123expArg (PExp _ _ _ _) = True
2124expArg (PConstraint _ _ _ _) = True
2127-- replace non-linear occurrences with _
2129stripLinear :: IState -> PTerm -> PTerm
2130stripLinear i tm = evalState (sl tm) [] where
2131 sl :: PTerm -> State [Name] PTerm
2133 | (_:_) <- lookupTy f (tt_ctxt i)
2134 = return $ PRef fc hl f
2135 | otherwise = do ns <- get
2137 then return $ PHidden (PRef fc hl f) -- Placeholder
2138 else do put (f : ns)
2139 return (PRef fc hl f)
2143 then return $ PHidden (PPatvar fc f) -- Placeholder
2144 else do put (f : ns)
2145 return (PPatvar fc f)
2146 -- Assumption is that variables are all the same in each alternative
2147 sl t@(PAlternative ms b as) = do ns <- get
2149 return (PAlternative ms b as')
2150 where slAlts ns (a : as) = do put ns
2154 slAlts ns [] = return []
2155 sl (PPair fc hls p l r) = do l' <- sl l; r' <- sl r; return (PPair fc hls p l' r')
2156 sl (PDPair fc hls p l t r) = do l' <- sl l
2159 return (PDPair fc hls p l' t' r')
2160 sl (PApp fc fn args) = do fn' <- case fn of
2161 -- Just the args, fn isn't matchable as a var
2162 PRef _ _ _ -> return fn
2164 args' <- mapM slA args
2165 return $ PApp fc fn' args'
2166 where slA (PImp p m l n t) = do t' <- sl t
2167 return $ PImp p m l n t'
2168 slA (PExp p l n t) = do t' <- sl t
2169 return $ PExp p l n t'
2170 slA (PConstraint p l n t)
2172 return $ PConstraint p l n t'
2173 slA (PTacImplicit p l n sc t)
2175 return $ PTacImplicit p l n sc t'
2178-- | Remove functions which aren't applied to anything, which must then
2179-- be resolved by unification. Assume names resolved and alternatives
2180-- filled in (so no ambiguity).
2181stripUnmatchable :: IState -> PTerm -> PTerm
2182stripUnmatchable i (PApp fc fn args) = PApp fc fn (fmap (fmap su) args) where
2183 su :: PTerm -> PTerm
2184 su tm@(PRef fc hl f)
2185 | (Bind n (Pi _ _ t _) sc :_) <- lookupTy f (tt_ctxt i)
2187 | (TType _ : _) <- lookupTy f (tt_ctxt i),
2188 not (implicitable f)
2190 | (UType _ : _) <- lookupTy f (tt_ctxt i),
2191 not (implicitable f)
2193 su (PApp fc f@(PRef _ _ fn) args)
2194 -- here we use canBeDConName because the impossible pattern
2195 -- check will not necessarily fully resolve constructor names,
2196 -- and these bare names will otherwise get in the way of
2197 -- impossbility checking.
2198 | canBeDConName fn ctxt
2199 = PApp fc f (fmap (fmap su) args)
2201 = PHidden (PApp fc f args)
2202 su (PAlternative ms b alts)
2203 = let alts' = filter (/= Placeholder) (map su alts) in
2204 if null alts' then Placeholder
2205 else liftHidden $ PAlternative ms b alts'
2206 su (PPair fc hls p l r) = PPair fc hls p (su l) (su r)
2207 su (PDPair fc hls p l t r) = PDPair fc hls p (su l) (su t) (su r)
2208 su t@(PLam fc _ _ _ _) = PHidden t
2209 su t@(PPi _ _ _ _ _) = PHidden t
2210 su t@(PConstant _ c) | isTypeConst c = PHidden t
2215 -- If the ambiguous terms are all hidden, the PHidden needs to be outside
2216 -- because elaboration of PHidden gets delayed, and we need the elaboration
2217 -- to resolve the ambiguity.
2218 liftHidden tm@(PAlternative ms b as)
2219 | allHidden as = PHidden (PAlternative ms b (map unHide as))
2223 allHidden (PHidden _ : xs) = allHidden xs
2224 allHidden (x : xs) = False
2226 unHide (PHidden t) = t
2229stripUnmatchable i tm = tm
2232mkPApp fc a f as = let rest = drop a as in
2233 if a == 0 then appRest fc f rest
2234 else appRest fc (PApp fc f (take a as)) rest
2237 appRest fc f (a : as) = appRest fc (PApp fc f [a]) as
2241-- | Find 'static' argument positions
2242-- (the declared ones, plus any names in argument position in the declared
2244-- FIXME: It's possible that this really has to happen after elaboration
2245findStatics :: IState -> PTerm -> (PTerm, [Bool])
2246findStatics ist tm = let (ns, ss) = fs tm
2247 in runState (pos ns ss tm) []
2248 where fs (PPi p n fc t sc)
2249 | Static <- pstatic p
2250 = let (ns, ss) = fs sc in
2251 (namesIn [] ist t : ns, n : ss)
2252 | otherwise = let (ns, ss) = fs sc in
2256 pos ns ss (PPi p n fc t sc)
2257 | elem n ss = do sc' <- pos ns ss sc
2260 return (PPi (p { pstatic = Static }) n fc t sc')
2261 | otherwise = do sc' <- pos ns ss sc
2264 return (PPi p n fc t sc')
2265 pos ns ss t = return t
2267-- for 6.12/7 compatibility
2268data EitherErr a b = LeftErr a | RightOK b deriving ( Functor )
2270instance Applicative (EitherErr a) where
2274instance Monad (EitherErr a) where
2277 (LeftErr e) >>= _ = LeftErr e
2278 RightOK v >>= k = k v
2280toEither :: EitherErr a b -> Either a b
2281toEither (LeftErr e) = Left e
2282toEither (RightOK ho) = Right ho
2284-- | Syntactic match of a against b, returning pair of variables in a
2285-- and what they match. Returns the pair that failed if not a match.
2286matchClause :: IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
2287matchClause = matchClause' False
2289matchClause' :: Bool -> IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
2290matchClause' names i x y = checkRpts $ match (fullApp x) (fullApp y) where
2291 matchArg x y = match (fullApp (getTm x)) (fullApp (getTm y))
2293 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
2296 match' x y = match (fullApp x) (fullApp y)
2297 match (PApp _ (PRef _ _ (NS (UN fi) [b])) [_,_,x]) x'
2298 | fi == txt "fromInteger" && b == txt "builtins",
2299 PConstant _ (I _) <- getTm x = match (getTm x) x'
2300 match x' (PApp _ (PRef _ _ (NS (UN fi) [b])) [_,_,x])
2301 | fi == txt "fromInteger" && b == txt "builtins",
2302 PConstant _ (I _) <- getTm x = match (getTm x) x'
2303 match (PApp _ (PRef _ _ (UN l)) [_,x]) x' | l == txt "lazy" = match (getTm x) x'
2304 match x (PApp _ (PRef _ _ (UN l)) [_,x']) | l == txt "lazy" = match x (getTm x')
2305 match (PApp _ f args) (PApp _ f' args')
2306 | length args == length args'
2307 = do mf <- match' f f'
2308 ms <- zipWithM matchArg args args'
2309 return (mf ++ concat ms)
2310 match (PRef f hl n) (PApp _ x []) = match (PRef f hl n) x
2311 match (PPatvar f n) xr = match (PRef f [f] n) xr
2312 match xr (PPatvar f n) = match xr (PRef f [f] n)
2313 match (PApp _ x []) (PRef f hl n) = match x (PRef f hl n)
2314 match (PRef _ _ n) tm@(PRef _ _ n')
2315 | n == n' && not names &&
2316 (not (isConName n (tt_ctxt i) || isFnName n (tt_ctxt i))
2317 || tm == Placeholder)
2319 -- if one namespace is missing, drop the other
2320 | n == n' || n == dropNS n' || dropNS n == n' = return []
2321 where dropNS (NS n _) = n
2323 match (PRef _ _ n) tm
2324 | not names && (not (isConName n (tt_ctxt i) ||
2325 isFnName n (tt_ctxt i)) || tm == Placeholder)
2327 match (PRewrite _ by l r _) (PRewrite _ by' l' r' _) | by == by'
2328 = do ml <- match' l l'
2331 match (PTyped l r) (PTyped l' r') = do ml <- match l l'
2334 match (PTyped l r) x = match l x
2335 match x (PTyped l r) = match x l
2336 match (PPair _ _ _ l r) (PPair _ _ _ l' r') = do ml <- match' l l'
2339 match (PDPair _ _ _ l t r) (PDPair _ _ _ l' t' r') = do ml <- match' l l'
2342 return (ml ++ mt ++ mr)
2343 match (PAlternative _ a as) (PAlternative _ a' as')
2344 = do ms <- zipWithM match' as as'
2346 match a@(PAlternative _ _ as) b
2347 = do let ms = zipWith match' as (repeat b)
2348 case (rights (map toEither ms)) of
2351 match (PCase _ _ _) _ = return [] -- lifted out
2352 match (PMetavar _ _) _ = return [] -- modified
2353 match (PInferRef _ _ _) _ = return [] -- modified
2354 match (PQuote _) _ = return []
2355 match (PProof _) _ = return []
2356 match (PTactics _) _ = return []
2357 match (PResolveTC _) (PResolveTC _) = return []
2358 match (PTrue _ _) (PTrue _ _) = return []
2359 match (PPi _ _ _ t s) (PPi _ _ _ t' s') = do mt <- match' t t'
2362 match (PLam _ _ _ t s) (PLam _ _ _ t' s') = do mt <- match' t t'
2365 match (PLet _ _ _ _ t ty s) (PLet _ _ _ _ t' ty' s')
2366 = do mt <- match' t t'
2367 mty <- match' ty ty'
2369 return (mt ++ mty ++ ms)
2370 match (PHidden x) (PHidden y)
2371 | RightOK xs <- match x y = return xs -- to collect variables
2372 | otherwise = return [] -- Otherwise hidden things are unmatchable
2374 | RightOK xs <- match x y = return xs
2375 | otherwise = return []
2377 | RightOK xs <- match x y = return xs
2378 | otherwise = return []
2379 match (PUnifyLog x) y = match' x y
2380 match x (PUnifyLog y) = match' x y
2381 match (PNoImplicits x) y = match' x y
2382 match x (PNoImplicits y) = match' x y
2383 match Placeholder _ = return []
2384 match _ Placeholder = return []
2385 match (PResolveTC _) _ = return []
2386 match a b | a == b = return []
2387 | otherwise = LeftErr (a, b)
2389 checkRpts (RightOK ms) = check ms where
2391 | Just t' <- lookup n xs = if t/=t' && t/=Placeholder && t'/=Placeholder
2394 check (_:xs) = check xs
2396 checkRpts (LeftErr x) = Left x
2398substMatches :: [(Name, PTerm)] -> PTerm -> PTerm
2399substMatches ms = substMatchesShadow ms []
2401-- substMatchesShadow :: [(Name, PTerm)] -> [Name] -> PTerm -> PTerm
2402-- substMatchesShadow [] shs t = t
2403-- substMatchesShadow ((n,tm):ns) shs t
2404-- = substMatchShadow n shs tm (substMatchesShadow ns shs t)
2406substMatch :: Name -> PTerm -> PTerm -> PTerm
2407substMatch n = substMatchShadow n []
2409substMatchShadow :: Name -> [Name] -> PTerm -> PTerm -> PTerm
2410substMatchShadow n shs tm t = substMatchesShadow [(n, tm)] shs t
2412substMatchesShadow :: [(Name, PTerm)] -> [Name] -> PTerm -> PTerm
2413substMatchesShadow nmap shs t = sm shs t where
2414 sm xs (PRef _ _ n) | Just tm <- lookup n nmap = tm
2415 sm xs (PLam fc x xfc t sc) = PLam fc x xfc (sm xs t) (sm xs sc)
2416 sm xs (PPi p x fc t sc)
2418 = let x' = nextName x in
2419 PPi p x' fc (sm (x':xs) (substMatch x (PRef emptyFC [] x') t))
2420 (sm (x':xs) (substMatch x (PRef emptyFC [] x') sc))
2421 | otherwise = PPi p x fc (sm xs t) (sm (x : xs) sc)
2422 sm xs (PLet fc rc x xfc val t sc)
2423 = PLet fc rc x xfc (sm xs val) (sm xs t) (sm xs sc)
2424 sm xs (PApp f x as) = fullApp $ PApp f (sm xs x) (map (fmap (sm xs)) as)
2425 sm xs (PCase f x as) = PCase f (sm xs x) (map (pmap (sm xs)) as)
2426 sm xs (PIfThenElse fc c t f) = PIfThenElse fc (sm xs c) (sm xs t) (sm xs f)
2427 sm xs (PRewrite f by x y tm) = PRewrite f by (sm xs x) (sm xs y)
2429 sm xs (PTyped x y) = PTyped (sm xs x) (sm xs y)
2430 sm xs (PPair f hls p x y) = PPair f hls p (sm xs x) (sm xs y)
2431 sm xs (PDPair f hls p x t y) = PDPair f hls p (sm xs x) (sm xs t) (sm xs y)
2432 sm xs (PAlternative ms a as) = PAlternative ms a (map (sm xs) as)
2433 sm xs (PHidden x) = PHidden (sm xs x)
2434 sm xs (PUnifyLog x) = PUnifyLog (sm xs x)
2435 sm xs (PNoImplicits x) = PNoImplicits (sm xs x)
2436 sm xs (PRunElab fc script ns) = PRunElab fc (sm xs script) ns
2437 sm xs (PConstSugar fc tm) = PConstSugar fc (sm xs tm)
2440 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
2443shadow :: Name -> Name -> PTerm -> PTerm
2444shadow n n' t = sm 0 t where
2445 sm 0 (PRef fc hl x) | n == x = PRef fc hl n'
2446 sm 0 (PLam fc x xfc t sc) | n /= x = PLam fc x xfc (sm 0 t) (sm 0 sc)
2447 | otherwise = PLam fc x xfc (sm 0 t) sc
2448 sm 0 (PPi p x fc t sc) | n /= x = PPi p x fc (sm 0 t) (sm 0 sc)
2449 | otherwise = PPi p x fc (sm 0 t) sc
2450 sm 0 (PLet fc rc x xfc t v sc) | n /= x = PLet fc rc x xfc (sm 0 t) (sm 0 v) (sm 0 sc)
2451 | otherwise = PLet fc rc x xfc (sm 0 t) (sm 0 v) sc
2452 sm 0 (PApp f x as) = PApp f (sm 0 x) (map (fmap (sm 0)) as)
2453 sm 0 (PAppBind f x as) = PAppBind f (sm 0 x) (map (fmap (sm 0)) as)
2454 sm 0 (PCase f x as) = PCase f (sm 0 x) (map (pmap (sm 0)) as)
2455 sm 0 (PIfThenElse fc c t f) = PIfThenElse fc (sm 0 c) (sm 0 t) (sm 0 f)
2456 sm 0 (PRewrite f by x y tm) = PRewrite f by (sm 0 x) (sm 0 y) (fmap (sm 0) tm)
2457 sm 0 (PTyped x y) = PTyped (sm 0 x) (sm 0 y)
2458 sm 0 (PPair f hls p x y) = PPair f hls p (sm 0 x) (sm 0 y)
2459 sm 0 (PDPair f hls p x t y) = PDPair f hls p (sm 0 x) (sm 0 t) (sm 0 y)
2460 sm 0 (PAlternative ms a as)
2461 = PAlternative (map shadowAlt ms) a (map (sm 0) as)
2462 sm 0 (PTactics ts) = PTactics (map (fmap (sm 0)) ts)
2463 sm 0 (PProof ts) = PProof (map (fmap (sm 0)) ts)
2464 sm 0 (PHidden x) = PHidden (sm 0 x)
2465 sm 0 (PUnifyLog x) = PUnifyLog (sm 0 x)
2466 sm 0 (PNoImplicits x) = PNoImplicits (sm 0 x)
2467 sm 0 (PCoerced t) = PCoerced (sm 0 t)
2468 sm ql (PQuasiquote tm ty) = PQuasiquote (sm (ql + 1) tm) (fmap (sm ql) ty)
2469 sm ql (PUnquote tm) = PUnquote (sm (ql - 1) tm)
2470 sm ql x = descend (sm ql) x
2472 shadowAlt p@(x, oldn) = (update x, update oldn)
2473 update oldn | n == oldn = n'
2476-- | Rename any binders which are repeated (so that we don't have to
2477-- mess about with shadowing anywhere else).
2478mkUniqueNames :: [Name] -> [(Name, Name)] -> PTerm -> PTerm
2479mkUniqueNames env shadows tm
2480 = evalState (mkUniq 0 initMap tm) (S.fromList env) where
2482 initMap = M.fromList shadows
2484 inScope :: S.Set Name
2485 inScope = S.fromList $ boundNamesIn tm
2487 mkUniqA ql nmap arg = do t' <- mkUniq ql nmap (getTm arg)
2488 return (arg { getTm = t' })
2490 -- Initialise the unique name with the environment length (so we're not
2491 -- looking for too long...)
2492 initN (UN n) l = UN $ txt (str n ++ show l)
2493 initN (MN i s) l = MN (i+l) s
2496 -- FIXME: Probably ought to do this for completeness! It's fine as
2497 -- long as there are no bindings inside tactics though.
2498 mkUniqT _ nmap tac = return tac
2500 mkUniq :: Int -- ^ The number of quotations that we're under
2501 -> M.Map Name Name -> PTerm -> State (S.Set Name) PTerm
2502 mkUniq 0 nmap (PLam fc n nfc ty sc)
2506 then do let n' = uniqueNameSet (initN n (S.size env))
2507 (S.union env inScope)
2508 return (n', sc) -- shadow n n' sc)
2510 put (S.insert n' env)
2511 let nmap' = M.insert n n' nmap
2512 ty' <- mkUniq 0 nmap ty
2513 sc'' <- mkUniq 0 nmap' sc'
2514 return $! PLam fc n' nfc ty' sc''
2515 mkUniq 0 nmap (PPi p n fc ty sc)
2519 then do let n' = uniqueNameSet (initN n (S.size env))
2520 (S.union env inScope)
2521 return (n', sc) -- shadow n n' sc)
2523 put (S.insert n' env)
2524 let nmap' = M.insert n n' nmap
2525 ty' <- mkUniq 0 nmap ty
2526 sc'' <- mkUniq 0 nmap' sc'
2527 return $! PPi p n' fc ty' sc''
2528 mkUniq 0 nmap (PLet fc rc n nfc ty val sc)
2532 then do let n' = uniqueNameSet (initN n (S.size env))
2533 (S.union env inScope)
2534 return (n', sc) -- shadow n n' sc)
2536 put (S.insert n' env)
2537 let nmap' = M.insert n n' nmap
2538 ty' <- mkUniq 0 nmap ty; val' <- mkUniq 0 nmap val
2539 sc'' <- mkUniq 0 nmap' sc'
2540 return $! PLet fc rc n' nfc ty' val' sc''
2541 mkUniq 0 nmap (PApp fc t args)
2542 = do t' <- mkUniq 0 nmap t
2543 args' <- mapM (mkUniqA 0 nmap) args
2544 return $! PApp fc t' args'
2545 mkUniq 0 nmap (PAppBind fc t args)
2546 = do t' <- mkUniq 0 nmap t
2547 args' <- mapM (mkUniqA 0 nmap) args
2548 return $! PAppBind fc t' args'
2549 mkUniq 0 nmap (PCase fc t alts)
2550 = do t' <- mkUniq 0 nmap t
2551 alts' <- mapM (\(x,y)-> do x' <- mkUniq 0 nmap x; y' <- mkUniq 0 nmap y
2552 return (x', y')) alts
2553 return $! PCase fc t' alts'
2554 mkUniq 0 nmap (PIfThenElse fc c t f)
2555 = liftM3 (PIfThenElse fc) (mkUniq 0 nmap c) (mkUniq 0 nmap t) (mkUniq 0 nmap f)
2556 mkUniq 0 nmap (PPair fc hls p l r)
2557 = do l' <- mkUniq 0 nmap l; r' <- mkUniq 0 nmap r
2558 return $! PPair fc hls p l' r'
2559 mkUniq 0 nmap (PDPair fc hls p (PRef fc' hls' n) t sc)
2562 (n', sc') <- if n `S.member` env
2563 then do let n' = uniqueNameSet n (S.union env inScope)
2564 return (n', sc) -- shadow n n' sc)
2566 put (S.insert n' env)
2567 let nmap' = M.insert n n' nmap
2568 t' <- mkUniq 0 nmap t
2569 sc'' <- mkUniq 0 nmap' sc'
2570 return $! PDPair fc hls p (PRef fc' hls' n') t' sc''
2571 mkUniq 0 nmap (PDPair fc hls p l t r)
2572 = do l' <- mkUniq 0 nmap l; t' <- mkUniq 0 nmap t; r' <- mkUniq 0 nmap r
2573 return $! PDPair fc hls p l' t' r'
2574 mkUniq 0 nmap (PAlternative ns b as)
2575 -- store the nmap and defer the rest until we've pruned the set
2576 -- during elaboration
2577 = return $ PAlternative (ns ++ M.toList nmap) b as
2578 mkUniq 0 nmap (PHidden t) = liftM PHidden (mkUniq 0 nmap t)
2579 mkUniq 0 nmap (PUnifyLog t) = liftM PUnifyLog (mkUniq 0 nmap t)
2580 mkUniq 0 nmap (PDisamb n t) = liftM (PDisamb n) (mkUniq 0 nmap t)
2581 mkUniq 0 nmap (PNoImplicits t) = liftM PNoImplicits (mkUniq 0 nmap t)
2582 mkUniq 0 nmap (PProof ts) = liftM PProof (mapM (mkUniqT 0 nmap) ts)
2583 mkUniq 0 nmap (PTactics ts) = liftM PTactics (mapM (mkUniqT 0 nmap) ts)
2584 mkUniq 0 nmap (PRunElab fc ts ns) = liftM (\tm -> PRunElab fc tm ns) (mkUniq 0 nmap ts)
2585 mkUniq 0 nmap (PConstSugar fc tm) = liftM (PConstSugar fc) (mkUniq 0 nmap tm)
2586 mkUniq 0 nmap (PCoerced tm) = liftM PCoerced (mkUniq 0 nmap tm)
2587 mkUniq 0 nmap t = return $ shadowAll (M.toList nmap) t
2590 shadowAll ((n, n') : ns) t = shadow n n' (shadowAll ns t)
2592 mkUniq ql nmap (PQuasiquote tm ty) =
2593 do tm' <- mkUniq (ql + 1) nmap tm
2595 Nothing -> return Nothing
2596 Just t -> fmap Just $ mkUniq ql nmap t
2597 return $! PQuasiquote tm' ty'
2598 mkUniq ql nmap (PUnquote tm) = fmap PUnquote (mkUniq (ql - 1) nmap tm)
2600 mkUniq ql nmap tm = descendM (mkUniq ql nmap) tm
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