1{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, DeriveFunctor,
2 TypeSynonymInstances, PatternGuards #-}
4module Idris.AbsSyntax(module Idris.AbsSyntax, module Idris.AbsSyntaxTree) where
7import Idris.Core.Evaluate
8import Idris.Core.Elaborate hiding (Tactic(..))
9import Idris.Core.Typecheck
10import Idris.AbsSyntaxTree
12import Idris.Docstrings
13import Idris.IdeMode hiding (Opt(..))
14import IRTS.CodegenCommon
15import Util.DynamicLinker
17import System.Console.Haskeline
19import System.Directory (canonicalizePath, doesFileExist)
21import Control.Applicative
22import Control.Monad (liftM3)
23import Control.Monad.State
25import Data.List hiding (insert,union)
27import qualified Data.Text as T
29import qualified Data.Map as M
31import qualified Data.Set as S
32import Data.Word (Word)
34import Data.Generics.Uniplate.Data (descend, descendM)
38import System.IO.Error(isUserError, ioeGetErrorString, tryIOError)
44getContext :: Idris Context
45getContext = do i <- getIState; return (tt_ctxt i)
47forCodegen :: Codegen -> [(Codegen, a)] -> [a]
48forCodegen tgt xs = [x | (tgt', x) <- xs, tgt == tgt']
50getObjectFiles :: Codegen -> Idris [FilePath]
51getObjectFiles tgt = do i <- getIState; return (forCodegen tgt $ idris_objs i)
53addObjectFile :: Codegen -> FilePath -> Idris ()
54addObjectFile tgt f = do i <- getIState; putIState $ i { idris_objs = nub $ (tgt, f) : idris_objs i }
56getLibs :: Codegen -> Idris [String]
57getLibs tgt = do i <- getIState; return (forCodegen tgt $ idris_libs i)
59addLib :: Codegen -> String -> Idris ()
60addLib tgt f = do i <- getIState; putIState $ i { idris_libs = nub $ (tgt, f) : idris_libs i }
62getFlags :: Codegen -> Idris [String]
63getFlags tgt = do i <- getIState; return (forCodegen tgt $ idris_cgflags i)
65addFlag :: Codegen -> String -> Idris ()
66addFlag tgt f = do i <- getIState; putIState $ i { idris_cgflags = nub $ (tgt, f) : idris_cgflags i }
68addDyLib :: [String] -> Idris (Either DynamicLib String)
69addDyLib libs = do i <- getIState
70 let ls = idris_dynamic_libs i
71 let importdirs = opt_importdirs (idris_options i)
72 case mapMaybe (findDyLib ls) libs of
73 x:_ -> return (Left x)
75 handle <- lift . lift .
76 mapM (\l -> catchIO (tryLoadLib importdirs l)
77 (\_ -> return Nothing)) $ libs
79 Nothing -> return (Right $ "Could not load dynamic alternatives \"" ++
80 concat (intersperse "," libs) ++ "\"")
81 Just x -> do putIState $ i { idris_dynamic_libs = x:ls }
83 where findDyLib :: [DynamicLib] -> String -> Maybe DynamicLib
84 findDyLib [] l = Nothing
85 findDyLib (lib:libs) l | l == lib_name lib = Just lib
86 | otherwise = findDyLib libs l
88getAutoImports :: Idris [FilePath]
89getAutoImports = do i <- getIState
90 return (opt_autoImport (idris_options i))
92addAutoImport :: FilePath -> Idris ()
93addAutoImport fp = do i <- getIState
94 let opts = idris_options i
95 let autoimps = opt_autoImport opts
96 put (i { idris_options = opts { opt_autoImport =
97 fp : opt_autoImport opts } } )
99addHdr :: Codegen -> String -> Idris ()
100addHdr tgt f = do i <- getIState; putIState $ i { idris_hdrs = nub $ (tgt, f) : idris_hdrs i }
102addImported :: Bool -> FilePath -> Idris ()
105 putIState $ i { idris_imported = nub $ (f, pub) : idris_imported i }
107addLangExt :: LanguageExt -> Idris ()
108addLangExt TypeProviders = do i <- getIState
110 idris_language_extensions = TypeProviders : idris_language_extensions i
112addLangExt ErrorReflection = do i <- getIState
114 idris_language_extensions = ErrorReflection : idris_language_extensions i
117-- Transforms are organised by the function being applied on the lhs of the
118-- transform, to make looking up appropriate transforms quicker
119addTrans :: Name -> (Term, Term) -> Idris ()
122 let t' = case lookupCtxtExact basefn (idris_transforms i) of
123 Just def -> (t : def)
125 putIState $ i { idris_transforms = addDef basefn t'
126 (idris_transforms i) }
128addErrRev :: (Term, Term) -> Idris ()
129addErrRev t = do i <- getIState
130 putIState $ i { idris_errRev = t : idris_errRev i }
132addErasureUsage :: Name -> Int -> Idris ()
133addErasureUsage n i = do ist <- getIState
134 putIState $ ist { idris_erasureUsed = (n, i) : idris_erasureUsed ist }
136addExport :: Name -> Idris ()
137addExport n = do ist <- getIState
138 putIState $ ist { idris_exports = n : idris_exports ist }
140addUsedName :: FC -> Name -> Name -> Idris ()
142 = do ist <- getIState
143 case lookupTyName n (tt_ctxt ist) of
144 [(n', ty)] -> addUsage n' 0 ty
145 [] -> throwError (At fc (NoSuchVariable n))
146 xs -> throwError (At fc (CantResolveAlts (map fst xs)))
147 where addUsage n i (Bind x _ sc) | x == arg = do addIBC (IBCUsage (n, i))
149 | otherwise = addUsage n (i + 1) sc
150 addUsage _ _ _ = throwError (At fc (Msg ("No such argument name " ++ show arg)))
152getErasureUsage :: Idris [(Name, Int)]
153getErasureUsage = do ist <- getIState;
154 return (idris_erasureUsed ist)
156getExports :: Idris [Name]
157getExports = do ist <- getIState
158 return (idris_exports ist)
160totcheck :: (FC, Name) -> Idris ()
161totcheck n = do i <- getIState; putIState $ i { idris_totcheck = idris_totcheck i ++ [n] }
163defer_totcheck :: (FC, Name) -> Idris ()
166 putIState $ i { idris_defertotcheck = nub (idris_defertotcheck i ++ [n]) }
168clear_totcheck :: Idris ()
169clear_totcheck = do i <- getIState; putIState $ i { idris_totcheck = [] }
171setFlags :: Name -> [FnOpt] -> Idris ()
172setFlags n fs = do i <- getIState; putIState $ i { idris_flags = addDef n fs (idris_flags i) }
174setFnInfo :: Name -> FnInfo -> Idris ()
175setFnInfo n fs = do i <- getIState; putIState $ i { idris_fninfo = addDef n fs (idris_fninfo i) }
177setAccessibility :: Name -> Accessibility -> Idris ()
180 let ctxt = setAccess n a (tt_ctxt i)
181 putIState $ i { tt_ctxt = ctxt }
183setTotality :: Name -> Totality -> Idris ()
186 let ctxt = setTotal n a (tt_ctxt i)
187 putIState $ i { tt_ctxt = ctxt }
189getTotality :: Name -> Idris Totality
192 case lookupTotal n (tt_ctxt i) of
194 _ -> return (Total [])
196-- Get coercions which might return the required type
197getCoercionsTo :: IState -> Type -> [Name]
199 let cs = idris_coercions i
200 (fn,_) = unApply (getRetTy ty) in
202 where findCoercions t [] = []
203 findCoercions t (n : ns) =
204 let ps = case lookupTy n (tt_ctxt i) of
205 [ty'] -> case unApply (getRetTy (normalise (tt_ctxt i) [] ty')) of
207 if t == t' then [n] else []
209 ps ++ findCoercions t ns
211addToCG :: Name -> CGInfo -> Idris ()
214 putIState $ i { idris_callgraph = addDef n cg (idris_callgraph i) }
216addTyInferred :: Name -> Idris ()
219 putIState $ i { idris_tyinfodata =
220 addDef n TIPartial (idris_tyinfodata i) }
222addTyInfConstraints :: FC -> [(Term, Term)] -> Idris ()
223addTyInfConstraints fc ts = do logLvl 2 $ "TI missing: " ++ show ts
224 mapM_ addConstraint ts
226 where addConstraint (x, y) = findMVApps x y
229 = do let (fx, argsx) = unApply x
230 let (fy, argsy) = unApply y
235 else mapM_ addConstraint (zip argsx argsy)
237 tryAddMV (P _ mv _) y =
239 case lookup mv (idris_metavars ist) of
240 Just _ -> addConstraintRule mv y
242 tryAddMV _ _ = return ()
244 addConstraintRule :: Name -> Term -> Idris ()
245 addConstraintRule n t
247 logLvl 1 $ "TI constraint: " ++ show (n, t)
248 case lookupCtxt n (idris_tyinfodata ist) of
250 do mapM_ (checkConsistent t) ts
251 let ti' = addDef n (TISolution (t : ts))
252 (idris_tyinfodata ist)
253 put $ ist { idris_tyinfodata = ti' }
255 do let ti' = addDef n (TISolution [t])
256 (idris_tyinfodata ist)
257 put $ ist { idris_tyinfodata = ti' }
259 -- Check a solution is consistent with previous solutions
260 -- Meaning: If heads are both data types, they had better be the
262 checkConsistent :: Term -> Term -> Idris ()
263 checkConsistent x y =
264 do let (fx, _) = unApply x
265 let (fy, _) = unApply y
267 (P (TCon _ _) n _, P (TCon _ _) n' _) -> errWhen (n/=n)
268 (P (TCon _ _) n _, Constant _) -> errWhen True
269 (Constant _, P (TCon _ _) n' _) -> errWhen True
270 (P (DCon _ _ _) n _, P (DCon _ _ _) n' _) -> errWhen (n/=n)
275 (CantUnify False (x, Nothing) (y, Nothing) (Msg "") [] 0))
276 errWhen False = return ()
278isTyInferred :: Name -> Idris Bool
281 case lookupCtxt n (idris_tyinfodata i) of
282 [TIPartial] -> return True
285-- | Adds error handlers for a particular function and argument. If names are
286-- ambiguous, all matching handlers are updated.
287addFunctionErrorHandlers :: Name -> Name -> [Name] -> Idris ()
288addFunctionErrorHandlers f arg hs =
290 let oldHandlers = idris_function_errorhandlers i
291 let newHandlers = flip (addDef f) oldHandlers $
292 case lookupCtxtExact f oldHandlers of
293 Nothing -> M.singleton arg (S.fromList hs)
294 Just (oldHandlers) -> M.insertWith S.union arg (S.fromList hs) oldHandlers
295 -- will always be one of those two, thus no extra case
296 putIState $ i { idris_function_errorhandlers = newHandlers }
298getFunctionErrorHandlers :: Name -> Name -> Idris [Name]
299getFunctionErrorHandlers f arg = do i <- getIState
300 return . maybe [] S.toList $
301 undefined --lookup arg =<< lookupCtxtExact f (idris_function_errorhandlers i)
304-- Trace all the names in a call graph starting at the given name
305getAllNames :: Name -> Idris [Name]
306getAllNames n = allNames [] n
308allNames :: [Name] -> Name -> Idris [Name]
309allNames ns n | n `elem` ns = return []
310allNames ns n = do i <- getIState
311 case lookupCtxtExact n (idris_callgraph i) of
312 Just ns' -> do more <- mapM (allNames (n:ns)) (map fst (calls ns'))
313 return (nub (n : concat more))
316addCoercion :: Name -> Idris ()
317addCoercion n = do i <- getIState
318 putIState $ i { idris_coercions = nub $ n : idris_coercions i }
320addDocStr :: Name -> Docstring DocTerm -> [(Name, Docstring DocTerm)] -> Idris ()
323 putIState $ i { idris_docstrings = addDef n (doc, args) (idris_docstrings i) }
325addNameHint :: Name -> Name -> Idris ()
328 ty' <- case lookupCtxtName ty (idris_implicits i) of
329 [(tyn, _)] -> return tyn
330 [] -> throwError (NoSuchVariable ty)
331 tyns -> throwError (CantResolveAlts (map fst tyns))
332 let ns' = case lookupCtxt ty' (idris_namehints i) of
335 putIState $ i { idris_namehints = addDef ty' ns' (idris_namehints i) }
337getNameHints :: IState -> Name -> [Name]
338getNameHints i (UN arr) | arr == txt "->" = [sUN "f",sUN "g"]
340 case lookupCtxt n (idris_namehints i) of
344-- Issue #1737 in the Issue Tracker.
345-- https://github.com/idris-lang/Idris-dev/issues/1737
346addToCalledG :: Name -> [Name] -> Idris ()
347addToCalledG n ns = return () -- TODO
349push_estack :: Name -> Bool -> Idris ()
352 putIState (i { elab_stack = (n, inst) : elab_stack i })
354pop_estack :: Idris ()
355pop_estack = do i <- getIState
356 putIState (i { elab_stack = ptail (elab_stack i) })
360-- | Add a class instance function.
362-- Precondition: the instance should have the correct type.
364-- Dodgy hack 1: Put integer instances first in the list so they are
365-- resolved by default.
367-- Dodgy hack 2: put constraint chasers (@@) last
368addInstance :: Bool -- ^ whether the name is an Integer instance
369 -> Bool -- ^ whether to include the instance in instance search
370 -> Name -- ^ the name of the class
371 -> Name -- ^ the name of the instance
373addInstance int res n i
374 = do ist <- getIState
375 case lookupCtxt n (idris_classes ist) of
376 [CI a b c d e ins fds] ->
377 do let cs = addDef n (CI a b c d e (addI i ins) fds) (idris_classes ist)
378 putIState $ ist { idris_classes = cs }
379 _ -> do let cs = addDef n (CI (sMN 0 "none") [] [] [] [] [(i, res)] []) (idris_classes ist)
380 putIState $ ist { idris_classes = cs }
381 where addI, insI :: Name -> [(Name, Bool)] -> [(Name, Bool)]
382 addI i ins | int = (i, res) : ins
383 | chaser n = ins ++ [(i, res)]
384 | otherwise = insI i ins
385 insI i [] = [(i, res)]
386 insI i (n : ns) | chaser (fst n) = (i, res) : n : ns
387 | otherwise = n : insI i ns
390 | ('@':'@':_) <- str nm = True
391 chaser (NS n _) = chaser n
394addClass :: Name -> ClassInfo -> Idris ()
396 = do ist <- getIState
397 let i' = case lookupCtxt n (idris_classes ist) of
398 [c] -> c { class_instances = class_instances i }
400 putIState $ ist { idris_classes = addDef n i' (idris_classes ist) }
402addRecord :: Name -> RecordInfo -> Idris ()
403addRecord n ri = do ist <- getIState
404 putIState $ ist { idris_records = addDef n ri (idris_records ist) }
406addAutoHint :: Name -> Name -> Idris ()
409 case lookupCtxtExact n (idris_autohints ist) of
411 do let hs = addDef n [hint] (idris_autohints ist)
412 putIState $ ist { idris_autohints = hs }
414 do let hs = addDef n (hint : nhints) (idris_autohints ist)
415 putIState $ ist { idris_autohints = hs }
417getAutoHints :: Name -> Idris [Name]
418getAutoHints n = do ist <- getIState
419 case lookupCtxtExact n (idris_autohints ist) of
423addIBC :: IBCWrite -> Idris ()
426 when (notDef (ibc_write i)) $
427 putIState $ i { ibc_write = ibc : ibc_write i }
428 where notDef [] = True
429 notDef (IBCDef n': is) | n == n' = False
430 notDef (_ : is) = notDef is
431addIBC ibc = do i <- getIState; putIState $ i { ibc_write = ibc : ibc_write i }
434clearIBC = do i <- getIState; putIState $ i { ibc_write = [] }
436resetNameIdx :: Idris ()
437resetNameIdx = do i <- getIState
438 put (i { idris_nameIdx = (0, emptyContext) })
440-- Used to preserve sharing of names
441addNameIdx :: Name -> Idris (Int, Name)
442addNameIdx n = do i <- getIState
443 let (i', x) = addNameIdx' i n
447addNameIdx' :: IState -> Name -> (IState, (Int, Name))
449 = let idxs = snd (idris_nameIdx i) in
450 case lookupCtxt n idxs of
452 _ -> let i' = fst (idris_nameIdx i) + 1 in
453 (i { idris_nameIdx = (i', addDef n (i', n) idxs) }, (i', n))
455getSymbol :: Name -> Idris Name
456getSymbol n = do i <- getIState
457 case M.lookup n (idris_symbols i) of
459 Nothing -> do let sym' = M.insert n n (idris_symbols i)
460 put (i { idris_symbols = sym' })
463getHdrs :: Codegen -> Idris [String]
464getHdrs tgt = do i <- getIState; return (forCodegen tgt $ idris_hdrs i)
466getImported :: Idris [(FilePath, Bool)]
467getImported = do i <- getIState; return (idris_imported i)
469setErrSpan :: FC -> Idris ()
470setErrSpan x = do i <- getIState;
472 Nothing -> putIState $ i { errSpan = Just x }
476clearErr = do i <- getIState
477 putIState $ i { errSpan = Nothing }
479getSO :: Idris (Maybe String)
480getSO = do i <- getIState
481 return (compiled_so i)
483setSO :: Maybe String -> Idris ()
484setSO s = do i <- getIState
485 putIState $ (i { compiled_so = s })
487getIState :: Idris IState
490putIState :: IState -> Idris ()
493updateIState :: (IState -> IState) -> Idris ()
494updateIState f = do i <- getIState
497withContext :: (IState -> Ctxt a) -> Name -> b -> (a -> Idris b) -> Idris b
498withContext ctx name dflt action = do
500 case lookupCtxt name (ctx ist) of
504withContext_ :: (IState -> Ctxt a) -> Name -> (a -> Idris ()) -> Idris ()
505withContext_ ctx name action = withContext ctx name () action
507-- | A version of liftIO that puts errors into the exception type of the Idris monad
508runIO :: IO a -> Idris a
509runIO x = liftIO (tryIOError x) >>= either (throwError . Msg . show) return
510-- TODO: create specific Idris exceptions for specific IO errors such as "openFile: does not exist"
512-- Issue #1738 on the issue tracker.
513-- https://github.com/idris-lang/Idris-dev/issues/1738
516getName = do i <- getIState;
517 let idx = idris_name i;
518 putIState $ (i { idris_name = idx + 1 })
521-- InternalApp keeps track of the real function application for making case splits from, not the application the
522-- programmer wrote, which doesn't have the whole context in any case other than top level definitions
523addInternalApp :: FilePath -> Int -> PTerm -> Idris ()
526 -- We canonicalise the path to make "./Test/Module.idr" equal
527 -- to "Test/Module.idr"
528 exists <- runIO $ doesFileExist fp
530 do fp' <- runIO $ canonicalizePath fp
531 putIState (i { idris_lineapps = ((fp', l), t) : idris_lineapps i })
533getInternalApp :: FilePath -> Int -> Idris PTerm
534getInternalApp fp l = do i <- getIState
535 -- We canonicalise the path to make
536 -- "./Test/Module.idr" equal to
538 exists <- runIO $ doesFileExist fp
540 then do fp' <- runIO $ canonicalizePath fp
541 case lookup (fp', l) (idris_lineapps i) of
543 Nothing -> return Placeholder
544 -- TODO: What if it's not there?
545 else return Placeholder
547-- Pattern definitions are only used for coverage checking, so erase them
549clearOrigPats :: Idris ()
550clearOrigPats = do i <- get
551 let ps = idris_patdefs i
552 let ps' = mapCtxt (\ (_,miss) -> ([], miss)) ps
553 put (i { idris_patdefs = ps' })
555-- Erase types from Ps in the context (basically ending up with what's in
556-- the .ibc, which is all we need after all the analysis is done)
557clearPTypes :: Idris ()
558clearPTypes = do i <- get
560 put (i { tt_ctxt = mapDefCtxt pErase ctxt })
561 where pErase (CaseOp c t tys orig tot cds)
562 = CaseOp c t tys orig [] (pErase' cds)
564 pErase' (CaseDefs _ (cs, c) _ rs)
565 = let c' = (cs, fmap pEraseType c) in
568checkUndefined :: FC -> Name -> Idris ()
572 (_:_) -> throwError . Msg $ show fc ++ ":" ++
573 show n ++ " already defined"
576isUndefined :: FC -> Name -> Idris Bool
579 case lookupTyExact n i of
580 Just _ -> return False
583setContext :: Context -> Idris ()
584setContext ctxt = do i <- getIState; putIState $ (i { tt_ctxt = ctxt } )
586updateContext :: (Context -> Context) -> Idris ()
587updateContext f = do i <- getIState; putIState $ (i { tt_ctxt = f (tt_ctxt i) } )
589addConstraints :: FC -> (Int, [UConstraint]) -> Idris ()
590addConstraints fc (v, cs)
593 let ctxt' = ctxt { next_tvar = v }
594 let ics = insertAll (zip cs (repeat fc)) (idris_constraints i)
595 putIState $ i { tt_ctxt = ctxt', idris_constraints = ics }
598 insertAll ((c, fc) : cs) ics
599 = insertAll cs $ S.insert (ConstraintFC c fc) ics
601addDeferred = addDeferred' Ref
602addDeferredTyCon = addDeferred' (TCon 0 0)
604-- | Save information about a name that is not yet defined
605addDeferred' :: NameType
606 -> [(Name, (Int, Maybe Name, Type, [Name], Bool))]
607 -- ^ The Name is the name being made into a metavar,
608 -- the Int is the number of vars that are part of a
609 -- putative proof context, the Maybe Name is the
610 -- top-level function containing the new metavariable,
611 -- the Type is its type, and the Bool is whether :p is
615 = do mapM_ (\(n, (i, _, t, _, _)) -> updateContext (addTyDecl n nt (tidyNames S.empty t))) ns
616 mapM_ (\(n, _) -> when (not (n `elem` primDefs)) $ addIBC (IBCMetavar n)) ns
618 putIState $ i { idris_metavars = map (\(n, (i, top, _, ns, isTopLevel)) -> (n, (top, i, ns, isTopLevel))) ns ++
621 -- 'tidyNames' is to generate user accessible names in case they are
622 -- needed in tactic scripts
623 tidyNames used (Bind (MN i x) b sc)
624 = let n' = uniqueNameSet (UN x) used in
625 Bind n' b $ tidyNames (S.insert n' used) sc
626 tidyNames used (Bind n b sc)
627 = let n' = uniqueNameSet n used in
628 Bind n' b $ tidyNames (S.insert n' used) sc
631solveDeferred :: Name -> Idris ()
632solveDeferred n = do i <- getIState
633 putIState $ i { idris_metavars =
634 filter (\(n', _) -> n/=n')
637 filter (notMV n) (ibc_write i)
639 where notMV n (IBCMetavar n') = not (n == n')
642getUndefined :: Idris [Name]
643getUndefined = do i <- getIState
644 return (map fst (idris_metavars i) \\ primDefs)
646isMetavarName :: Name -> IState -> Bool
648 = case lookupNames n (tt_ctxt ist) of
649 (t:_) -> isJust $ lookup t (idris_metavars ist)
652getWidth :: Idris ConsoleWidth
653getWidth = fmap idris_consolewidth getIState
655setWidth :: ConsoleWidth -> Idris ()
656setWidth w = do ist <- getIState
657 put ist { idris_consolewidth = w }
659setDepth :: Maybe Int -> Idris ()
660setDepth d = do ist <- getIState
661 put ist { idris_options = (idris_options ist) { opt_printdepth = d } }
663typeDescription :: String
664typeDescription = "The type of types"
667type1Doc :: Doc OutputAnnotation
668type1Doc = (annotate (AnnType "Type" "The type of types, one level up") $ text "Type 1")
671isetPrompt :: String -> Idris ()
672isetPrompt p = do i <- getIState
673 case idris_outputmode i of
674 IdeMode n h -> runIO . hPutStrLn h $ convSExp "set-prompt" p n
676-- | Tell clients how much was parsed and loaded
677isetLoadedRegion :: Idris ()
678isetLoadedRegion = do i <- getIState
679 let span = idris_parsedSpan i
682 case idris_outputmode i of
684 runIO . hPutStrLn h $
685 convSExp "set-loaded-region" fc n
688setLogLevel :: Int -> Idris ()
689setLogLevel l = do i <- getIState
690 let opts = idris_options i
691 let opt' = opts { opt_logLevel = l }
692 putIState $ i { idris_options = opt' }
694setCmdLine :: [Opt] -> Idris ()
695setCmdLine opts = do i <- getIState
696 let iopts = idris_options i
697 putIState $ i { idris_options = iopts { opt_cmdline = opts } }
699getCmdLine :: Idris [Opt]
700getCmdLine = do i <- getIState
701 return (opt_cmdline (idris_options i))
703getDumpHighlighting :: Idris Bool
704getDumpHighlighting = do ist <- getIState
705 return (findC (opt_cmdline (idris_options ist)))
706 where findC = elem DumpHighlights
708getDumpDefun :: Idris (Maybe FilePath)
709getDumpDefun = do i <- getIState
710 return $ findC (opt_cmdline (idris_options i))
711 where findC [] = Nothing
712 findC (DumpDefun x : _) = Just x
713 findC (_ : xs) = findC xs
715getDumpCases :: Idris (Maybe FilePath)
716getDumpCases = do i <- getIState
717 return $ findC (opt_cmdline (idris_options i))
718 where findC [] = Nothing
719 findC (DumpCases x : _) = Just x
720 findC (_ : xs) = findC xs
723logLevel = do i <- getIState
724 return (opt_logLevel (idris_options i))
726setErrContext :: Bool -> Idris ()
727setErrContext t = do i <- getIState
728 let opts = idris_options i
729 let opts' = opts { opt_errContext = t }
730 putIState $ i { idris_options = opts' }
732errContext :: Idris Bool
733errContext = do i <- getIState
734 return (opt_errContext (idris_options i))
736getOptimise :: Idris [Optimisation]
737getOptimise = do i <- getIState
738 return (opt_optimise (idris_options i))
740setOptimise :: [Optimisation] -> Idris ()
741setOptimise newopts = do i <- getIState
742 let opts = idris_options i
743 let opts' = opts { opt_optimise = newopts }
744 putIState $ i { idris_options = opts' }
746addOptimise :: Optimisation -> Idris ()
747addOptimise opt = do opts <- getOptimise
748 setOptimise (nub (opt : opts))
750removeOptimise :: Optimisation -> Idris ()
751removeOptimise opt = do opts <- getOptimise
752 setOptimise ((nub opts) \\ [opt])
754-- Set appropriate optimisation set for the given level. We only have
755-- one optimisation that is configurable at the moment, however!
756setOptLevel :: Int -> Idris ()
757setOptLevel n | n <= 0 = setOptimise []
758setOptLevel 1 = setOptimise []
759setOptLevel 2 = setOptimise [PETransform]
760setOptLevel n | n >= 3 = setOptimise [PETransform]
763useREPL = do i <- getIState
764 return (opt_repl (idris_options i))
766setREPL :: Bool -> Idris ()
767setREPL t = do i <- getIState
768 let opts = idris_options i
769 let opt' = opts { opt_repl = t }
770 putIState $ i { idris_options = opt' }
772showOrigErr :: Idris Bool
773showOrigErr = do i <- getIState
774 return (opt_origerr (idris_options i))
776setShowOrigErr :: Bool -> Idris ()
777setShowOrigErr b = do i <- getIState
778 let opts = idris_options i
779 let opt' = opts { opt_origerr = b }
780 putIState $ i { idris_options = opt' }
782setAutoSolve :: Bool -> Idris ()
783setAutoSolve b = do i <- getIState
784 let opts = idris_options i
785 let opt' = opts { opt_autoSolve = b }
786 putIState $ i { idris_options = opt' }
788setNoBanner :: Bool -> Idris ()
789setNoBanner n = do i <- getIState
790 let opts = idris_options i
791 let opt' = opts { opt_nobanner = n }
792 putIState $ i { idris_options = opt' }
794getNoBanner :: Idris Bool
795getNoBanner = do i <- getIState
796 let opts = idris_options i
797 return (opt_nobanner opts)
799setEvalTypes :: Bool -> Idris ()
800setEvalTypes n = do i <- getIState
801 let opts = idris_options i
802 let opt' = opts { opt_evaltypes = n }
803 putIState $ i { idris_options = opt' }
805getDesugarNats :: Idris Bool
806getDesugarNats = do i <- getIState
807 let opts = idris_options i
808 return (opt_desugarnats opts)
811setDesugarNats :: Bool -> Idris ()
812setDesugarNats n = do i <- getIState
813 let opts = idris_options i
814 let opt' = opts { opt_desugarnats = n }
815 putIState $ i { idris_options = opt' }
817setQuiet :: Bool -> Idris ()
818setQuiet q = do i <- getIState
819 let opts = idris_options i
820 let opt' = opts { opt_quiet = q }
821 putIState $ i { idris_options = opt' }
823getQuiet :: Idris Bool
824getQuiet = do i <- getIState
825 let opts = idris_options i
826 return (opt_quiet opts)
828setCodegen :: Codegen -> Idris ()
829setCodegen t = do i <- getIState
830 let opts = idris_options i
831 let opt' = opts { opt_codegen = t }
832 putIState $ i { idris_options = opt' }
834codegen :: Idris Codegen
835codegen = do i <- getIState
836 return (opt_codegen (idris_options i))
838setOutputTy :: OutputType -> Idris ()
839setOutputTy t = do i <- getIState
840 let opts = idris_options i
841 let opt' = opts { opt_outputTy = t }
842 putIState $ i { idris_options = opt' }
844outputTy :: Idris OutputType
845outputTy = do i <- getIState
846 return $ opt_outputTy $ idris_options i
848setIdeMode :: Bool -> Handle -> Idris ()
849setIdeMode True h = do i <- getIState
850 putIState $ i { idris_outputmode = IdeMode 0 h
851 , idris_colourRepl = False
853setIdeMode False _ = return ()
855setTargetTriple :: String -> Idris ()
856setTargetTriple t = do i <- getIState
857 let opts = idris_options i
858 opt' = opts { opt_triple = t }
859 putIState $ i { idris_options = opt' }
861targetTriple :: Idris String
862targetTriple = do i <- getIState
863 return (opt_triple (idris_options i))
865setTargetCPU :: String -> Idris ()
866setTargetCPU t = do i <- getIState
867 let opts = idris_options i
868 opt' = opts { opt_cpu = t }
869 putIState $ i { idris_options = opt' }
871targetCPU :: Idris String
872targetCPU = do i <- getIState
873 return (opt_cpu (idris_options i))
876verbose = do i <- getIState
877 -- Quietness overrides verbosity
878 return (not (opt_quiet (idris_options i)) &&
879 opt_verbose (idris_options i))
881setVerbose :: Bool -> Idris ()
882setVerbose t = do i <- getIState
883 let opts = idris_options i
884 let opt' = opts { opt_verbose = t }
885 putIState $ i { idris_options = opt' }
887typeInType :: Idris Bool
888typeInType = do i <- getIState
889 return (opt_typeintype (idris_options i))
891setTypeInType :: Bool -> Idris ()
892setTypeInType t = do i <- getIState
893 let opts = idris_options i
894 let opt' = opts { opt_typeintype = t }
895 putIState $ i { idris_options = opt' }
897coverage :: Idris Bool
898coverage = do i <- getIState
899 return (opt_coverage (idris_options i))
901setCoverage :: Bool -> Idris ()
902setCoverage t = do i <- getIState
903 let opts = idris_options i
904 let opt' = opts { opt_coverage = t }
905 putIState $ i { idris_options = opt' }
907setIBCSubDir :: FilePath -> Idris ()
908setIBCSubDir fp = do i <- getIState
909 let opts = idris_options i
910 let opt' = opts { opt_ibcsubdir = fp }
911 putIState $ i { idris_options = opt' }
913valIBCSubDir :: IState -> Idris FilePath
914valIBCSubDir i = return (opt_ibcsubdir (idris_options i))
916addImportDir :: FilePath -> Idris ()
917addImportDir fp = do i <- getIState
918 let opts = idris_options i
919 let opt' = opts { opt_importdirs = nub $ fp : opt_importdirs opts }
920 putIState $ i { idris_options = opt' }
922setImportDirs :: [FilePath] -> Idris ()
923setImportDirs fps = do i <- getIState
924 let opts = idris_options i
925 let opt' = opts { opt_importdirs = fps }
926 putIState $ i { idris_options = opt' }
928allImportDirs :: Idris [FilePath]
929allImportDirs = do i <- getIState
930 let optdirs = opt_importdirs (idris_options i)
931 return ("." : reverse optdirs)
933colourise :: Idris Bool
934colourise = do i <- getIState
935 return $ idris_colourRepl i
937setColourise :: Bool -> Idris ()
938setColourise b = do i <- getIState
939 putIState $ i { idris_colourRepl = b }
942impShow = do i <- getIState
943 return (opt_showimp (idris_options i))
945setImpShow :: Bool -> Idris ()
946setImpShow t = do i <- getIState
947 let opts = idris_options i
948 let opt' = opts { opt_showimp = t }
949 putIState $ i { idris_options = opt' }
951setColour :: ColourType -> IdrisColour -> Idris ()
952setColour ct c = do i <- getIState
953 let newTheme = setColour' ct c (idris_colourTheme i)
954 putIState $ i { idris_colourTheme = newTheme }
955 where setColour' KeywordColour c t = t { keywordColour = c }
956 setColour' BoundVarColour c t = t { boundVarColour = c }
957 setColour' ImplicitColour c t = t { implicitColour = c }
958 setColour' FunctionColour c t = t { functionColour = c }
959 setColour' TypeColour c t = t { typeColour = c }
960 setColour' DataColour c t = t { dataColour = c }
961 setColour' PromptColour c t = t { promptColour = c }
962 setColour' PostulateColour c t = t { postulateColour = c }
964logLvl :: Int -> String -> Idris ()
965logLvl l str = do i <- getIState
966 let lvl = opt_logLevel (idris_options i)
968 case idris_outputmode i of
969 RawOutput h -> do runIO $ hPutStrLn h str
971 do let good = SexpList [IntegerAtom (toInteger l), toSExp str]
972 runIO . hPutStrLn h $ convSExp "log" good n
974cmdOptType :: Opt -> Idris Bool
975cmdOptType x = do i <- getIState
976 return $ x `elem` opt_cmdline (idris_options i)
978noErrors :: Idris Bool
979noErrors = do i <- getIState
981 Nothing -> return True
984setTypeCase :: Bool -> Idris ()
985setTypeCase t = do i <- getIState
986 let opts = idris_options i
987 let opt' = opts { opt_typecase = t }
988 putIState $ i { idris_options = opt' }
991-- Dealing with parameters
993expandParams :: (Name -> Name) -> [(Name, PTerm)] ->
994 [Name] -> -- all names
995 [Name] -> -- names with no declaration
997expandParams dec ps ns infs tm = en 0 tm
999 -- if we shadow a name (say in a lambda binding) that is used in a call to
1000 -- a lifted function, we need access to both names - once in the scope of the
1001 -- binding and once to call the lifted functions. So we'll explicitly shadow
1002 -- it. (Yes, it's a hack. The alternative would be to resolve names earlier
1003 -- but we didn't...)
1005 mkShadow (UN n) = MN 0 n
1006 mkShadow (MN i n) = MN (i+1) n
1007 mkShadow (NS x s) = NS (mkShadow x) s
1009 en :: Int -- ^ The quotation level - only transform terms that are used, not terms
1010 -- that are merely mentioned.
1012 en 0 (PLam fc n nfc t s)
1013 | n `elem` (map fst ps ++ ns)
1014 = let n' = mkShadow n in
1015 PLam fc n' nfc (en 0 t) (en 0 (shadow n n' s))
1016 | otherwise = PLam fc n nfc (en 0 t) (en 0 s)
1017 en 0 (PPi p n nfc t s)
1018 | n `elem` (map fst ps ++ ns)
1019 = let n' = mkShadow n in -- TODO THINK SHADOWING TacImp?
1020 PPi (enTacImp 0 p) n' nfc (en 0 t) (en 0 (shadow n n' s))
1021 | otherwise = PPi (enTacImp 0 p) n nfc (en 0 t) (en 0 s)
1022 en 0 (PLet fc n nfc ty v s)
1023 | n `elem` (map fst ps ++ ns)
1024 = let n' = mkShadow n in
1025 PLet fc n' nfc (en 0 ty) (en 0 v) (en 0 (shadow n n' s))
1026 | otherwise = PLet fc n nfc (en 0 ty) (en 0 v) (en 0 s)
1027 -- FIXME: Should only do this in a type signature!
1028 en 0 (PDPair f hls p (PRef f' fcs n) t r)
1029 | n `elem` (map fst ps ++ ns) && t /= Placeholder
1030 = let n' = mkShadow n in
1031 PDPair f hls p (PRef f' fcs n') (en 0 t) (en 0 (shadow n n' r))
1032 en 0 (PRewrite f l r g) = PRewrite f (en 0 l) (en 0 r) (fmap (en 0) g)
1033 en 0 (PTyped l r) = PTyped (en 0 l) (en 0 r)
1034 en 0 (PPair f hls p l r) = PPair f hls p (en 0 l) (en 0 r)
1035 en 0 (PDPair f hls p l t r) = PDPair f hls p (en 0 l) (en 0 t) (en 0 r)
1036 en 0 (PAlternative ns a as) = PAlternative ns a (map (en 0) as)
1037 en 0 (PHidden t) = PHidden (en 0 t)
1038 en 0 (PUnifyLog t) = PUnifyLog (en 0 t)
1039 en 0 (PDisamb ds t) = PDisamb ds (en 0 t)
1040 en 0 (PNoImplicits t) = PNoImplicits (en 0 t)
1041 en 0 (PDoBlock ds) = PDoBlock (map (fmap (en 0)) ds)
1042 en 0 (PProof ts) = PProof (map (fmap (en 0)) ts)
1043 en 0 (PTactics ts) = PTactics (map (fmap (en 0)) ts)
1045 en 0 (PQuote (Var n))
1046 | n `nselem` ns = PQuote (Var (dec n))
1047 en 0 (PApp fc (PInferRef fc' hl n) as)
1048 | n `nselem` ns = PApp fc (PInferRef fc' hl (dec n))
1049 (map (pexp . (PRef fc hl)) (map fst ps) ++ (map (fmap (en 0)) as))
1050 en 0 (PApp fc (PRef fc' hl n) as)
1051 | n `elem` infs = PApp fc (PInferRef fc' hl (dec n))
1052 (map (pexp . (PRef fc hl)) (map fst ps) ++ (map (fmap (en 0)) as))
1053 | n `nselem` ns = PApp fc (PRef fc' hl (dec n))
1054 (map (pexp . (PRef fc hl)) (map fst ps) ++ (map (fmap (en 0)) as))
1055 en 0 (PAppBind fc (PRef fc' hl n) as)
1056 | n `elem` infs = PAppBind fc (PInferRef fc' hl (dec n))
1057 (map (pexp . (PRef fc hl)) (map fst ps) ++ (map (fmap (en 0)) as))
1058 | n `nselem` ns = PAppBind fc (PRef fc' hl (dec n))
1059 (map (pexp . (PRef fc hl)) (map fst ps) ++ (map (fmap (en 0)) as))
1061 | n `elem` infs = PApp fc (PInferRef fc hl (dec n))
1062 (map (pexp . (PRef fc hl)) (map fst ps))
1063 | n `nselem` ns = PApp fc (PRef fc hl (dec n))
1064 (map (pexp . (PRef fc hl)) (map fst ps))
1065 en 0 (PInferRef fc hl n)
1066 | n `nselem` ns = PApp fc (PInferRef fc hl (dec n))
1067 (map (pexp . (PRef fc hl)) (map fst ps))
1068 en 0 (PApp fc f as) = PApp fc (en 0 f) (map (fmap (en 0)) as)
1069 en 0 (PAppBind fc f as) = PAppBind fc (en 0 f) (map (fmap (en 0)) as)
1070 en 0 (PCase fc c os) = PCase fc (en 0 c) (map (pmap (en 0)) os)
1071 en 0 (PIfThenElse fc c t f) = PIfThenElse fc (en 0 c) (en 0 t) (en 0 f)
1072 en 0 (PRunElab fc tm ns) = PRunElab fc (en 0 tm) ns
1073 en 0 (PConstSugar fc tm) = PConstSugar fc (en 0 tm)
1075 en ql (PQuasiquote tm ty) = PQuasiquote (en (ql + 1) tm) (fmap (en ql) ty)
1076 en ql (PUnquote tm) = PUnquote (en (ql - 1) tm)
1078 en ql t = descend (en ql) t
1081 nselem x (y : xs) | nseq x y = True
1082 | otherwise = nselem x xs
1084 nseq x y = nsroot x == nsroot y
1086 enTacImp ql (TacImp aos st scr) = TacImp aos st (en ql scr)
1087 enTacImp ql other = other
1089expandParamsD :: Bool -> -- True = RHS only
1091 (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PDecl -> PDecl
1092expandParamsD rhsonly ist dec ps ns (PTy doc argdocs syn fc o n nfc ty)
1093 = if n `elem` ns && (not rhsonly)
1094 then -- trace (show (n, expandParams dec ps ns ty)) $
1095 PTy doc argdocs syn fc o (dec n) nfc (piBindp expl_param ps (expandParams dec ps ns [] ty))
1096 else --trace (show (n, expandParams dec ps ns ty)) $
1097 PTy doc argdocs syn fc o n nfc (expandParams dec ps ns [] ty)
1098expandParamsD rhsonly ist dec ps ns (PPostulate e doc syn fc nfc o n ty)
1099 = if n `elem` ns && (not rhsonly)
1100 then -- trace (show (n, expandParams dec ps ns ty)) $
1101 PPostulate e doc syn fc nfc o (dec n)
1102 (piBind ps (expandParams dec ps ns [] ty))
1103 else --trace (show (n, expandParams dec ps ns ty)) $
1104 PPostulate e doc syn fc nfc o n (expandParams dec ps ns [] ty)
1105expandParamsD rhsonly ist dec ps ns (PClauses fc opts n cs)
1106 = let n' = if n `elem` ns then dec n else n in
1107 PClauses fc opts n' (map expandParamsC cs)
1109 expandParamsC (PClause fc n lhs ws rhs ds)
1110 = let -- ps' = updateps True (namesIn ist rhs) (zip ps [0..])
1111 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
1112 lhs' = if rhsonly then lhs else (expandParams dec ps'' ns [] lhs)
1113 n' = if n `elem` ns then dec n else n
1114 -- names bound on the lhs should not be expanded on the rhs
1115 ns' = removeBound lhs ns in
1117 (map (expandParams dec ps'' ns' []) ws)
1118 (expandParams dec ps'' ns' [] rhs)
1119 (map (expandParamsD True ist dec ps'' ns') ds)
1120 expandParamsC (PWith fc n lhs ws wval pn ds)
1121 = let -- ps' = updateps True (namesIn ist wval) (zip ps [0..])
1122 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
1123 lhs' = if rhsonly then lhs else (expandParams dec ps'' ns [] lhs)
1124 n' = if n `elem` ns then dec n else n
1125 ns' = removeBound lhs ns in
1127 (map (expandParams dec ps'' ns' []) ws)
1128 (expandParams dec ps'' ns' [] wval)
1130 (map (expandParamsD rhsonly ist dec ps'' ns') ds)
1131 updateps yn nm [] = []
1132 updateps yn nm (((a, t), i):as)
1133 | (a `elem` nm) == yn = (a, t) : updateps yn nm as
1134 | otherwise = (sMN i ('_' : show n ++ "_u"), t) : updateps yn nm as
1136 removeBound lhs ns = ns \\ nub (bnames lhs)
1138 bnames (PRef _ _ n) = [n]
1139 bnames (PApp _ _ args) = concatMap bnames (map getTm args)
1140 bnames (PPair _ _ _ l r) = bnames l ++ bnames r
1141 bnames (PDPair _ _ _ l Placeholder r) = bnames l ++ bnames r
1144-- | Expands parameters defined in parameter and where blocks inside of declarations
1145expandParamsD rhs ist dec ps ns (PData doc argDocs syn fc co pd)
1146 = PData doc argDocs syn fc co (expandPData pd)
1148 -- just do the type decl, leave constructors alone (parameters will be
1149 -- added implicitly)
1150 expandPData (PDatadecl n nfc ty cons)
1152 then PDatadecl (dec n) nfc (piBind ps (expandParams dec ps ns [] ty))
1154 else PDatadecl n nfc (expandParams dec ps ns [] ty) (map econ cons)
1155 econ (doc, argDocs, n, nfc, t, fc, fs)
1156 = (doc, argDocs, dec n, nfc, piBindp expl ps (expandParams dec ps ns [] t), fc, fs)
1157expandParamsD rhs ist dec ps ns d@(PRecord doc rsyn fc opts name nfc prs pdocs fls cn cdoc csyn)
1159expandParamsD rhs ist dec ps ns (PParams f params pds)
1160 = PParams f (ps ++ map (mapsnd (expandParams dec ps ns [])) params)
1161 (map (expandParamsD True ist dec ps ns) pds)
1162-- (map (expandParamsD ist dec ps ns) pds)
1163expandParamsD rhs ist dec ps ns (PMutual f pds)
1164 = PMutual f (map (expandParamsD rhs ist dec ps ns) pds)
1165expandParamsD rhs ist dec ps ns (PClass doc info f cs n nfc params pDocs fds decls cn cd)
1167 (map (\ (n, t) -> (n, expandParams dec ps ns [] t)) cs)
1169 (map (\(n, fc, t) -> (n, fc, expandParams dec ps ns [] t)) params)
1172 (map (expandParamsD rhs ist dec ps ns) decls)
1175expandParamsD rhs ist dec ps ns (PInstance doc argDocs info f cs n nfc params ty cn decls)
1176 = PInstance doc argDocs info f
1177 (map (\ (n, t) -> (n, expandParams dec ps ns [] t)) cs)
1180 (map (expandParams dec ps ns []) params)
1181 (expandParams dec ps ns [] ty)
1183 (map (expandParamsD rhs ist dec ps ns) decls)
1184expandParamsD rhs ist dec ps ns d = d
1186mapsnd f (x, t) = (x, f t)
1188-- Calculate a priority for a type, for deciding elaboration order
1189-- * if it's just a type variable or concrete type, do it early (0)
1190-- * if there's only type variables and injective constructors, do it next (1)
1191-- * if there's a function type, next (2)
1192-- * finally, everything else (3)
1194getPriority :: IState -> PTerm -> Int
1195getPriority i tm = 1 -- pri tm
1198 case lookupP n (tt_ctxt i) of
1199 ((P (DCon _ _ _) _ _):_) -> 1
1200 ((P (TCon _ _) _ _):_) -> 1
1201 ((P Ref _ _):_) -> 1
1202 [] -> 0 -- must be locally bound, if it's not an error...
1203 pri (PPi _ _ _ x y) = max 5 (max (pri x) (pri y))
1205 pri (PRewrite _ l r _) = max 1 (max (pri l) (pri r))
1206 pri (PApp _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.getTm) as)))
1207 pri (PAppBind _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.getTm) as)))
1208 pri (PCase _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.snd) as)))
1209 pri (PTyped l r) = pri l
1210 pri (PPair _ _ _ l r) = max 1 (max (pri l) (pri r))
1211 pri (PDPair _ _ _ l t r) = max 1 (max (pri l) (max (pri t) (pri r)))
1212 pri (PAlternative _ a as) = maximum (map pri as)
1213 pri (PConstant _ _) = 0
1218addStatics :: Name -> Term -> PTerm -> Idris ()
1219addStatics n tm ptm =
1220 do let (statics, dynamics) = initStatics tm ptm
1223 = nub $ case lookupCtxtExact n (idris_fninfo ist) of
1224 Just p -> getNamesFrom 0 (fn_params p) tm ++
1225 concatMap (getParamNames ist) (map snd statics)
1226 _ -> concatMap (getParamNames ist) (map snd statics)
1228 let stnames = nub $ concatMap freeArgNames (map snd statics)
1229 let dnames = (nub $ concatMap freeArgNames (map snd dynamics))
1231 -- also get the arguments which are 'uniquely inferrable' from
1232 -- statics (see sec 4.2 of "Scrapping Your Inefficient Engine")
1233 -- or parameters to the type of a static
1234 let statics' = nub $ map fst statics ++
1235 filter (\x -> not (elem x dnames)) stnames
1236 let stpos = staticList statics' tm
1238 when (not (null statics)) $
1239 logLvl 3 $ "Statics for " ++ show n ++ " " ++ show tm ++ "\n"
1240 ++ showTmImpls ptm ++ "\n"
1241 ++ show statics ++ "\n" ++ show dynamics
1242 ++ "\n" ++ show paramnames
1243 ++ "\n" ++ show stpos
1244 putIState $ i { idris_statics = addDef n stpos (idris_statics i) }
1245 addIBC (IBCStatic n)
1247 initStatics (Bind n (Pi _ ty _) sc) (PPi p n' fc t s)
1248 | n /= n' = let (static, dynamic) = initStatics sc (PPi p n' fc t s) in
1249 (static, (n, ty) : dynamic)
1250 initStatics (Bind n (Pi _ ty _) sc) (PPi p n' fc _ s)
1251 = let (static, dynamic) = initStatics (instantiate (P Bound n ty) sc) s in
1252 if pstatic p == Static then ((n, ty) : static, dynamic)
1253 else if (not (searchArg p))
1254 then (static, (n, ty) : dynamic)
1255 else (static, dynamic)
1256 initStatics t pt = ([], [])
1258 getParamNames ist tm | (P _ n _ , args) <- unApply tm
1259 = case lookupCtxtExact n (idris_datatypes ist) of
1260 Just ti -> getNamePos 0 (param_pos ti) args
1262 where getNamePos i ps [] = []
1263 getNamePos i ps (P _ n _ : as)
1264 | i `elem` ps = n : getNamePos (i + 1) ps as
1265 getNamePos i ps (_ : as) = getNamePos (i + 1) ps as
1266 getParamNames ist (Bind t (Pi _ (P _ n _) _) sc)
1267 = n : getParamNames ist sc
1268 getParamNames ist _ = []
1270 getNamesFrom i ps (Bind n (Pi _ _ _) sc)
1271 | i `elem` ps = n : getNamesFrom (i + 1) ps sc
1272 | otherwise = getNamesFrom (i + 1) ps sc
1273 getNamesFrom i ps sc = []
1275 freeArgNames (Bind n (Pi _ ty _) sc)
1276 = nub $ freeNames ty ++ freeNames sc -- treat '->' as fn here
1277 freeArgNames tm = let (_, args) = unApply tm in
1278 concatMap freeNames args
1280 -- if a name appears in a type class or tactic implicit index, it doesn't
1281 -- affect its 'uniquely inferrable' from a static status since these are
1282 -- resolved by searching.
1283 searchArg (Constraint _ _) = True
1284 searchArg (TacImp _ _ _) = True
1287 staticList sts (Bind n (Pi _ _ _) sc) = (n `elem` sts) : staticList sts sc
1290-- Dealing with implicit arguments
1292-- Add some bound implicits to the using block if they aren't there already
1294addToUsing :: [Using] -> [(Name, PTerm)] -> [Using]
1295addToUsing us [] = us
1296addToUsing us ((n, t) : ns)
1297 | n `notElem` mapMaybe impName us = addToUsing (us ++ [UImplicit n t]) ns
1298 | otherwise = addToUsing us ns
1299 where impName (UImplicit n _) = Just n
1302-- Add constraint bindings from using block
1304addUsingConstraints :: SyntaxInfo -> FC -> PTerm -> Idris PTerm
1305addUsingConstraints syn fc t
1307 let ns = namesIn [] ist t
1308 let cs = getConstraints t -- check declared constraints
1309 let addconsts = uconsts \\ cs
1310 return (doAdd addconsts ns t)
1311 where uconsts = filter uconst (using syn)
1312 uconst (UConstraint _ _) = True
1316 -- if all of args in ns, then add it
1317 doAdd (UConstraint c args : cs) ns t
1318 | all (\n -> elem n ns) args
1319 = PPi (Constraint [] Dynamic) (sMN 0 "cu") NoFC
1320 (mkConst c args) (doAdd cs ns t)
1321 | otherwise = doAdd cs ns t
1323 mkConst c args = PApp fc (PRef fc [] c)
1324 (map (\n -> PExp 0 [] (sMN 0 "carg") (PRef fc [] n)) args)
1326 getConstraints (PPi (Constraint _ _) _ _ c sc)
1327 = getcapp c ++ getConstraints sc
1328 getConstraints (PPi _ _ _ c sc) = getConstraints sc
1329 getConstraints _ = []
1331 getcapp (PApp _ (PRef _ _ c) args)
1332 = do ns <- mapM getName args
1333 return (UConstraint c ns)
1336 getName (PExp _ _ _ (PRef _ _ n)) = return n
1339-- Add implicit bindings from using block, and bind any missing names
1340addUsingImpls :: SyntaxInfo -> Name -> FC -> PTerm -> Idris PTerm
1341addUsingImpls syn n fc t
1342 = do ist <- getIState
1343 let ns = implicitNamesIn (map iname uimpls) ist t
1344 let badnames = filter (\n -> not (implicitable n) &&
1345 n `notElem` (map iname uimpls)) ns
1346 when (not (null badnames)) $
1347 throwError (At fc (Elaborating "type of " n
1348 (NoSuchVariable (head badnames))))
1349 let cs = getArgnames t -- get already bound names
1350 let addimpls = filter (\n -> iname n `notElem` cs) uimpls
1351 -- if all names in the arguments of addconsts appear in ns,
1352 -- add the constraint implicitly
1353 return (bindFree ns (doAdd addimpls ns t))
1354 where uimpls = filter uimpl (using syn)
1355 uimpl (UImplicit _ _) = True
1358 iname (UImplicit n _) = n
1359 iname (UConstraint _ _) = error "Can't happen addUsingImpls"
1362 -- if all of args in ns, then add it
1363 doAdd (UImplicit n ty : cs) ns t
1365 = PPi (Imp [] Dynamic False Nothing) n NoFC ty (doAdd cs ns t)
1366 | otherwise = doAdd cs ns t
1368 -- bind the free names which weren't in the using block
1371 | elem n (map iname uimpls) = bindFree ns tm
1373 = PPi (Imp [InaccessibleArg] Dynamic False Nothing) n NoFC Placeholder (bindFree ns tm)
1375 getArgnames (PPi _ n _ c sc)
1376 = n : getArgnames sc
1379-- Given the original type and the elaborated type, return the implicitness
1380-- status of each pi-bound argument, and whether it's inaccessible (True) or not.
1382getUnboundImplicits :: IState -> Type -> PTerm -> [(Bool, PArg)]
1383getUnboundImplicits i t tm = getImps t (collectImps tm)
1384 where collectImps (PPi p n _ t sc)
1385 = (n, (p, t)) : collectImps sc
1388 getImps (Bind n (Pi (Just _) _ _) sc) imps = getImps sc imps
1389 getImps (Bind n (Pi _ t _) sc) imps
1390 | Just (p, t') <- lookup n imps = argInfo n p t' : getImps sc imps
1392 argInfo n (Imp opt _ _ _) Placeholder
1393 = (True, PImp 0 True opt n Placeholder)
1394 argInfo n (Imp opt _ _ _) t'
1395 = (False, PImp (getPriority i t') True opt n t')
1396 argInfo n (Exp opt _ _) t'
1397 = (InaccessibleArg `elem` opt,
1398 PExp (getPriority i t') opt n t')
1399 argInfo n (Constraint opt _) t'
1400 = (InaccessibleArg `elem` opt,
1401 PConstraint 10 opt n t')
1402 argInfo n (TacImp opt _ scr) t'
1403 = (InaccessibleArg `elem` opt,
1404 PTacImplicit 10 opt n scr t')
1405 getImps (Bind n (Pi _ t _) sc) imps = impBind n t : getImps sc imps
1406 where impBind n t = (True, PImp 1 True [] n Placeholder)
1409-- Add implicit Pi bindings for any names in the term which appear in an
1410-- argument position.
1412-- This has become a right mess already. Better redo it some time...
1413-- TODO: This is obsoleted by the new way of elaborating types, (which
1414-- calls addUsingImpls) but there's still a couple of places which use
1415-- it. Clean them up!
1417-- Issue 1739 in the issue tracker
1418-- https://github.com/idris-lang/Idris-dev/issues/1739
1419implicit :: ElabInfo -> SyntaxInfo -> Name -> PTerm -> Idris PTerm
1420implicit info syn n ptm = implicit' info syn [] n ptm
1422implicit' :: ElabInfo -> SyntaxInfo -> [Name] -> Name -> PTerm -> Idris PTerm
1423implicit' info syn ignore n ptm
1425 let (tm', impdata) = implicitise syn ignore i ptm
1426 defaultArgCheck (eInfoNames info ++ M.keys (idris_implicits i)) impdata
1427-- let (tm'', spos) = findStatics i tm'
1428 putIState $ i { idris_implicits = addDef n impdata (idris_implicits i) }
1430 logLvl 5 ("Implicit " ++ show n ++ " " ++ show impdata)
1432-- putIState $ i { idris_statics = addDef n spos (idris_statics i) }
1435 -- Detect unknown names in default arguments and throw error if found.
1436 defaultArgCheck :: [Name] -> [PArg] -> Idris ()
1437 defaultArgCheck knowns params = foldM_ notFoundInDefault knowns params
1439 notFoundInDefault :: [Name] -> PArg -> Idris [Name]
1440 notFoundInDefault kns (PTacImplicit _ _ n script _)
1442 case notFound kns (namesIn [] i script) of
1443 Nothing -> return (n:kns)
1444 Just name -> throwError (NoSuchVariable name)
1445 notFoundInDefault kns p = return ((pname p):kns)
1447 notFound :: [Name] -> [Name] -> Maybe Name
1448 notFound kns [] = Nothing
1449 notFound kns (SN (WhereN _ _ _) : ns) = notFound kns ns -- Known already
1450 notFound kns (n:ns) = if elem n kns then notFound kns ns else Just n
1452implicitise :: SyntaxInfo -> [Name] -> IState -> PTerm -> (PTerm, [PArg])
1453implicitise syn ignore ist tm = -- trace ("INCOMING " ++ showImp True tm) $
1454 let (declimps, ns') = execState (imps True [] tm) ([], [])
1455 ns = filter (\n -> implicitable n || elem n (map fst uvars)) $
1456 ns' \\ (map fst pvars ++ no_imp syn ++ ignore)
1457 nsOrder = filter (not . inUsing) ns ++ filter inUsing ns in
1459 then (tm, reverse declimps)
1460 else implicitise syn ignore ist (pibind uvars nsOrder tm)
1462 uvars = map ipair (filter uimplicit (using syn))
1463 pvars = syn_params syn
1465 inUsing n = n `elem` map fst uvars
1467 ipair (UImplicit x y) = (x, y)
1468 uimplicit (UImplicit _ _) = True
1471 dropAll (x:xs) ys | x `elem` ys = dropAll xs ys
1472 | otherwise = x : dropAll xs ys
1475 -- Find names in argument position in a type, suitable for implicit
1477 -- Not the function position, but do everything else...
1478 implNamesIn uv (PApp fc f args) = concatMap (implNamesIn uv) (map getTm args)
1479 implNamesIn uv t = namesIn uv ist t
1481 imps top env (PApp _ f as)
1482 = do (decls, ns) <- get
1483 let isn = concatMap (namesIn uvars ist) (map getTm as)
1484 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1485 imps top env (PPi (Imp l _ _ _) n _ ty sc)
1486 = do let isn = nub (implNamesIn uvars ty) `dropAll` [n]
1488 put (PImp (getPriority ist ty) True l n Placeholder : decls,
1489 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1490 imps True (n:env) sc
1491 imps top env (PPi (Exp l _ _) n _ ty sc)
1492 = do let isn = nub (implNamesIn uvars ty ++ case sc of
1493 (PRef _ _ x) -> namesIn uvars ist sc `dropAll` [n]
1495 (decls, ns) <- get -- ignore decls in HO types
1496 put (PExp (getPriority ist ty) l n Placeholder : decls,
1497 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1498 imps True (n:env) sc
1499 imps top env (PPi (Constraint l _) n _ ty sc)
1500 = do let isn = nub (implNamesIn uvars ty ++ case sc of
1501 (PRef _ _ x) -> namesIn uvars ist sc `dropAll` [n]
1503 (decls, ns) <- get -- ignore decls in HO types
1504 put (PConstraint 10 l n Placeholder : decls,
1505 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1506 imps True (n:env) sc
1507 imps top env (PPi (TacImp l _ scr) n _ ty sc)
1508 = do let isn = nub (implNamesIn uvars ty ++ case sc of
1509 (PRef _ _ x) -> namesIn uvars ist sc `dropAll` [n]
1511 (decls, ns) <- get -- ignore decls in HO types
1512 put (PTacImplicit 10 l n scr Placeholder : decls,
1513 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1514 imps True (n:env) sc
1515 imps top env (PRewrite _ l r _)
1516 = do (decls, ns) <- get
1517 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1518 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1519 imps top env (PTyped l r)
1521 imps top env (PPair _ _ _ l r)
1522 = do (decls, ns) <- get
1523 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1524 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1525 imps top env (PDPair _ _ _ (PRef _ _ n) t r)
1526 = do (decls, ns) <- get
1527 let isn = nub (namesIn uvars ist t ++ namesIn uvars ist r) \\ [n]
1528 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1529 imps top env (PDPair _ _ _ l t r)
1530 = do (decls, ns) <- get
1531 let isn = namesIn uvars ist l ++ namesIn uvars ist t ++
1533 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1534 imps top env (PAlternative ms a as)
1535 = do (decls, ns) <- get
1536 let isn = concatMap (namesIn uvars ist) as
1537 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1538 imps top env (PLam fc n _ ty sc)
1539 = do imps False env ty
1540 imps False (n:env) sc
1541 imps top env (PHidden tm) = imps False env tm
1542 imps top env (PUnifyLog tm) = imps False env tm
1543 imps top env (PNoImplicits tm) = imps False env tm
1544 imps top env (PRunElab fc tm ns) = imps False env tm
1545 imps top env (PConstSugar fc tm) = imps top env tm -- ignore PConstSugar - it's for highlighting only!
1546 imps top env _ = return ()
1548 pibind using [] sc = sc
1549 pibind using (n:ns) sc
1550 = case lookup n using of
1551 Just ty -> PPi (Imp [] Dynamic False Nothing)
1552 n NoFC ty (pibind using ns sc)
1553 Nothing -> PPi (Imp [InaccessibleArg] Dynamic False Nothing)
1554 n NoFC Placeholder (pibind using ns sc)
1556-- Add implicit arguments in function calls
1557addImplPat :: IState -> PTerm -> PTerm
1558addImplPat = addImpl' True [] [] []
1560addImplBound :: IState -> [Name] -> PTerm -> PTerm
1561addImplBound ist ns = addImpl' False ns [] [] ist
1563addImplBoundInf :: IState -> [Name] -> [Name] -> PTerm -> PTerm
1564addImplBoundInf ist ns inf = addImpl' False ns inf [] ist
1566-- | Add the implicit arguments to applications in the term
1567-- [Name] gives the names to always expend, even when under a binder of
1568-- that name (this is to expand methods with implicit arguments in dependent
1570addImpl :: [Name] -> IState -> PTerm -> PTerm
1571addImpl = addImpl' False [] []
1573-- TODO: in patterns, don't add implicits to function names guarded by constructors
1574-- and *not* inside a PHidden
1576addImpl' :: Bool -> [Name] -> [Name] -> [Name] -> IState -> PTerm -> PTerm
1577addImpl' inpat env infns imp_meths ist ptm
1578 = mkUniqueNames env [] (ai inpat False (zip env (repeat Nothing)) [] ptm)
1580 topname = case ptm of
1582 PApp _ (PRef _ _ n) _ -> n
1583 _ -> sUN "" -- doesn't matter then
1585 ai :: Bool -> Bool -> [(Name, Maybe PTerm)] -> [[T.Text]] -> PTerm -> PTerm
1586 ai inpat qq env ds (PRef fc fcs f)
1587 | f `elem` infns = PInferRef fc fcs f
1588 | not (f `elem` map fst env) = handleErr $ aiFn topname inpat inpat qq imp_meths ist fc f fc ds [] []
1589 ai inpat qq env ds (PHidden (PRef fc hl f))
1590 | not (f `elem` map fst env) = PHidden (handleErr $ aiFn topname inpat False qq imp_meths ist fc f fc ds [] [])
1591 ai inpat qq env ds (PRewrite fc l r g)
1592 = let l' = ai inpat qq env ds l
1593 r' = ai inpat qq env ds r
1594 g' = fmap (ai inpat qq env ds) g in
1595 PRewrite fc l' r' g'
1596 ai inpat qq env ds (PTyped l r)
1597 = let l' = ai inpat qq env ds l
1598 r' = ai inpat qq env ds r in
1600 ai inpat qq env ds (PPair fc hls p l r)
1601 = let l' = ai inpat qq env ds l
1602 r' = ai inpat qq env ds r in
1603 PPair fc hls p l' r'
1604 ai inpat qq env ds (PDPair fc hls p l t r)
1605 = let l' = ai inpat qq env ds l
1606 t' = ai inpat qq env ds t
1607 r' = ai inpat qq env ds r in
1608 PDPair fc hls p l' t' r'
1609 ai inpat qq env ds (PAlternative ms a as)
1610 = let as' = map (ai inpat qq env ds) as in
1611 PAlternative ms a as'
1612 ai inpat qq env _ (PDisamb ds' as) = ai inpat qq env ds' as
1613 ai inpat qq env ds (PApp fc (PInferRef ffc hl f) as)
1614 = let as' = map (fmap (ai inpat qq env ds)) as in
1615 PApp fc (PInferRef ffc hl f) as'
1616 ai inpat qq env ds (PApp fc ftm@(PRef ffc hl f) as)
1617 | f `elem` infns = ai inpat qq env ds (PApp fc (PInferRef ffc hl f) as)
1618 | not (f `elem` map fst env)
1619 = let as' = map (fmap (ai inpat qq env ds)) as
1620 asdotted' = map (fmap (ai False qq env ds)) as in
1621 handleErr $ aiFn topname inpat False qq imp_meths ist fc f ffc ds as' asdotted'
1622 | Just (Just ty) <- lookup f env =
1623 let as' = map (fmap (ai inpat qq env ds)) as
1624 arity = getPArity ty in
1625 mkPApp fc arity ftm as'
1626 ai inpat qq env ds (PApp fc f as)
1627 = let f' = ai inpat qq env ds f
1628 as' = map (fmap (ai inpat qq env ds)) as in
1630 ai inpat qq env ds (PCase fc c os)
1631 = let c' = ai inpat qq env ds c in
1632 -- leave os alone, because they get lifted into a new pattern match
1633 -- definition which is passed through addImpl agai inpatn with more scope
1637 ai inpat qq env ds (PIfThenElse fc c t f) = PIfThenElse fc (ai inpat qq env ds c)
1638 (ai inpat qq env ds t)
1639 (ai inpat qq env ds f)
1641 -- If the name in a lambda is a constructor name, do this as a 'case'
1642 -- instead (it is harmless to do so, especially since the lambda will
1643 -- be lifted anyway!)
1644 ai inpat qq env ds (PLam fc n nfc ty sc)
1645 = case lookupDef n (tt_ctxt ist) of
1646 [] -> let ty' = ai inpat qq env ds ty
1647 sc' = ai inpat qq ((n, Just ty):env) ds sc in
1648 PLam fc n nfc ty' sc'
1649 _ -> ai inpat qq env ds (PLam fc (sMN 0 "lamp") NoFC ty
1650 (PCase fc (PRef fc [] (sMN 0 "lamp") )
1651 [(PRef fc [] n, sc)]))
1652 ai inpat qq env ds (PLet fc n nfc ty val sc)
1653 = case lookupDef n (tt_ctxt ist) of
1654 [] -> let ty' = ai inpat qq env ds ty
1655 val' = ai inpat qq env ds val
1656 sc' = ai inpat qq ((n, Just ty):env) ds sc in
1657 PLet fc n nfc ty' val' sc'
1659 ai inpat qq env ds (PCase fc val [(PRef fc [] n, sc)])
1660 ai inpat qq env ds (PPi p n nfc ty sc)
1661 = let ty' = ai inpat qq env ds ty
1662 env' = if n `elem` imp_meths then env
1663 else ((n, Just ty) : env)
1664 sc' = ai inpat qq env' ds sc in
1666 ai inpat qq env ds (PGoal fc r n sc)
1667 = let r' = ai inpat qq env ds r
1668 sc' = ai inpat qq ((n, Nothing):env) ds sc in
1670 ai inpat qq env ds (PHidden tm) = PHidden (ai inpat qq env ds tm)
1671 -- Don't do PProof or PTactics since implicits get added when scope is
1672 -- properly known in ElabTerm.runTac
1673 ai inpat qq env ds (PUnifyLog tm) = PUnifyLog (ai inpat qq env ds tm)
1674 ai inpat qq env ds (PNoImplicits tm) = PNoImplicits (ai inpat qq env ds tm)
1675 ai inpat qq env ds (PQuasiquote tm g) = PQuasiquote (ai inpat True env ds tm)
1676 (fmap (ai inpat True env ds) g)
1677 ai inpat qq env ds (PUnquote tm) = PUnquote (ai inpat False env ds tm)
1678 ai inpat qq env ds (PRunElab fc tm ns) = PRunElab fc (ai inpat False env ds tm) ns
1679 ai inpat qq env ds (PConstSugar fc tm) = PConstSugar fc (ai inpat qq env ds tm)
1680 ai inpat qq env ds tm = tm
1682 handleErr (Left err) = PElabError err
1683 handleErr (Right x) = x
1685-- if in a pattern, and there are no arguments, and there's no possible
1686-- names with zero explicit arguments, don't add implicits.
1688aiFn :: Name -> Bool -> Bool -> Bool
1691 -> Name -- ^ function being applied
1693 -> [PArg] -- ^ initial arguments (if in a pattern)
1694 -> [PArg] -- ^ initial arguments (if in an expression)
1696aiFn topname inpat True qq imp_meths ist fc f ffc ds [] _
1697 = case lookupDef f (tt_ctxt ist) of
1698 [] -> Right $ PPatvar ffc f
1699 alts -> let ialts = lookupCtxtName f (idris_implicits ist) in
1700 -- trace (show f ++ " " ++ show (fc, any (all imp) ialts, ialts, any constructor alts)) $
1701 if (not (vname f) || tcname f
1702 || any (conCaf (tt_ctxt ist)) ialts)
1703-- any constructor alts || any allImp ialts))
1704 then aiFn topname inpat False qq imp_meths ist fc f ffc ds [] [] -- use it as a constructor
1705 else Right $ PPatvar ffc f
1706 where imp (PExp _ _ _ _) = False
1709 allImp xs = all imp xs
1710 constructor (TyDecl (DCon _ _ _) _) = True
1711 constructor _ = False
1713 conCaf ctxt (n, cia) = (isDConName n ctxt || (qq && isTConName n ctxt)) && allImp cia
1715 vname (UN n) = True -- non qualified
1718aiFn topname inpat expat qq imp_meths ist fc f ffc ds as asexp
1719 | f `elem` primNames = Right $ PApp fc (PRef ffc [ffc] f) as
1720aiFn topname inpat expat qq imp_meths ist fc f ffc ds as asexp
1721 -- This is where namespaces get resolved by adding PAlternative
1722 = do let ns = lookupCtxtName f (idris_implicits ist)
1723 let nh = filter (\(n, _) -> notHidden n) ns
1724 let ns' = case trimAlts ds nh of
1728 [(f',ns)] -> Right $ mkPApp fc (length ns) (PRef ffc [ffc] (isImpName f f'))
1729 (insertImpl ns (chooseArgs f' as asexp))
1730 [] -> if f `elem` (map fst (idris_metavars ist))
1731 then Right $ PApp fc (PRef ffc [ffc] f) as
1732 else Right $ mkPApp fc (length as) (PRef ffc [ffc] f) as
1734 PAlternative [] (ExactlyOne True) $
1735 map (\(f', ns) -> mkPApp fc (length ns) (PRef ffc [ffc] (isImpName f f'))
1736 (insertImpl ns (chooseArgs f' as asexp))) alts
1738 -- choose whether to treat the arguments as patterns or expressions
1739 -- if 'f' is a defined function, treat as expression, otherwise do the default.
1740 -- This is so any names which later go under a PHidden are treated
1741 -- as function names rather than bound pattern variables
1742 chooseArgs f as asexp | isConName f (tt_ctxt ist) = as
1744 | Nothing <- lookupDefExact f (tt_ctxt ist) = as
1747 -- if the name is in imp_meths, we should actually refer to the bound
1748 -- name rather than the global one after expanding implicits
1749 isImpName f f' | f `elem` imp_meths = f
1752 trimAlts [] alts = alts
1754 = filter (\(x, _) -> any (\d -> d `isPrefixOf` nspace x) ns) alts
1759 notHidden n = case getAccessibility n of
1764 = case lookupDefAccExact n False (tt_ctxt ist) of
1768 insertImpl :: [PArg] -- ^ expected argument types (from idris_implicits)
1769 -> [PArg] -- ^ given arguments
1772 = let (as', badimpls) = partition (impIn ps) as in
1773 map addUnknownImp badimpls ++
1774 insImpAcc M.empty ps (filter expArg as') (filter (not . expArg) as')
1776 insImpAcc :: M.Map Name PTerm -- accumulated param names & arg terms
1777 -> [PArg] -- parameters
1778 -> [PArg] -- explicit arguments
1779 -> [PArg] -- implicits given
1781 insImpAcc pnas (PExp p l n ty : ps) (PExp _ _ _ tm : given) imps =
1782 PExp p l n tm : insImpAcc (M.insert n tm pnas) ps given imps
1783 insImpAcc pnas (PConstraint p l n ty : ps) (PConstraint _ _ _ tm : given) imps =
1784 PConstraint p l n tm : insImpAcc (M.insert n tm pnas) ps given imps
1785 insImpAcc pnas (PConstraint p l n ty : ps) given imps =
1786 let rtc = PResolveTC fc in
1787 PConstraint p l n rtc : insImpAcc (M.insert n rtc pnas) ps given imps
1788 insImpAcc pnas (PImp p _ l n ty : ps) given imps =
1789 case find n imps [] of
1791 PImp p False l n tm : insImpAcc (M.insert n tm pnas) ps given imps'
1792 Nothing -> let ph = if f `elem` imp_meths then PRef fc [] n else Placeholder in
1793 PImp p True l n ph :
1794 insImpAcc (M.insert n ph pnas) ps given imps
1795 insImpAcc pnas (PTacImplicit p l n sc' ty : ps) given imps =
1796 let sc = addImpl imp_meths ist (substMatches (M.toList pnas) sc') in
1797 case find n imps [] of
1799 PTacImplicit p l n sc tm :
1800 insImpAcc (M.insert n tm pnas) ps given imps'
1803 then PTacImplicit p l n sc Placeholder :
1804 insImpAcc (M.insert n Placeholder pnas) ps given imps
1805 else PTacImplicit p l n sc sc :
1806 insImpAcc (M.insert n sc pnas) ps given imps
1807 insImpAcc _ expected [] imps = map addUnknownImp imps -- so that unused implicits give error
1808 insImpAcc _ _ given imps = given ++ imps
1810 addUnknownImp arg = arg { argopts = UnknownImp : argopts arg }
1812 find n [] acc = Nothing
1813 find n (PImp _ _ _ n' t : gs) acc
1814 | n == n' = Just (t, reverse acc ++ gs)
1815 find n (PTacImplicit _ _ n' _ t : gs) acc
1816 | n == n' = Just (t, reverse acc ++ gs)
1817 find n (g : gs) acc = find n gs (g : acc)
1819-- return True if the second argument is an implicit argument which is
1820-- expected in the implicits, or if it's not an implicit
1821impIn :: [PArg] -> PArg -> Bool
1822impIn ps (PExp _ _ _ _) = True
1823impIn ps (PConstraint _ _ _ _) = True
1824impIn ps arg = any (\p -> not (expArg arg) && pname arg == pname p) ps
1826expArg (PExp _ _ _ _) = True
1827expArg (PConstraint _ _ _ _) = True
1830-- replace non-linear occurrences with _
1832stripLinear :: IState -> PTerm -> PTerm
1833stripLinear i tm = evalState (sl tm) [] where
1834 sl :: PTerm -> State [Name] PTerm
1836 | (_:_) <- lookupTy f (tt_ctxt i)
1837 = return $ PRef fc hl f
1838 | otherwise = do ns <- get
1840 then return $ PHidden (PRef fc hl f) -- Placeholder
1841 else do put (f : ns)
1842 return (PRef fc hl f)
1846 then return $ PHidden (PPatvar fc f) -- Placeholder
1847 else do put (f : ns)
1848 return (PPatvar fc f)
1849 -- Assumption is that variables are all the same in each alternative
1850 sl t@(PAlternative ms b as) = do ns <- get
1852 return (PAlternative ms b as')
1853 where slAlts ns (a : as) = do put ns
1857 slAlts ns [] = return []
1858 sl (PPair fc hls p l r) = do l' <- sl l; r' <- sl r; return (PPair fc hls p l' r')
1859 sl (PDPair fc hls p l t r) = do l' <- sl l
1862 return (PDPair fc hls p l' t' r')
1863 sl (PApp fc fn args) = do fn' <- case fn of
1864 -- Just the args, fn isn't matchable as a var
1865 PRef _ _ _ -> return fn
1867 args' <- mapM slA args
1868 return $ PApp fc fn' args'
1869 where slA (PImp p m l n t) = do t' <- sl t
1870 return $ PImp p m l n t'
1871 slA (PExp p l n t) = do t' <- sl t
1872 return $ PExp p l n t'
1873 slA (PConstraint p l n t)
1875 return $ PConstraint p l n t'
1876 slA (PTacImplicit p l n sc t)
1878 return $ PTacImplicit p l n sc t'
1881-- | Remove functions which aren't applied to anything, which must then
1882-- be resolved by unification. Assume names resolved and alternatives
1883-- filled in (so no ambiguity).
1884stripUnmatchable :: IState -> PTerm -> PTerm
1885stripUnmatchable i (PApp fc fn args) = PApp fc fn (fmap (fmap su) args) where
1886 su :: PTerm -> PTerm
1887 su tm@(PRef fc hl f)
1888 | (Bind n (Pi _ t _) sc :_) <- lookupTy f (tt_ctxt i)
1890 | (TType _ : _) <- lookupTy f (tt_ctxt i)
1892 | (UType _ : _) <- lookupTy f (tt_ctxt i)
1894 su (PApp fc f@(PRef _ _ fn) args)
1895 -- here we use canBeDConName because the impossible pattern
1896 -- check will not necessarily fully resolve constructor names,
1897 -- and these bare names will otherwise get in the way of
1898 -- impossbility checking.
1899 | canBeDConName fn ctxt
1900 = PApp fc f (fmap (fmap su) args)
1902 = PHidden (PApp fc f args)
1903 su (PAlternative ms b alts)
1904 = let alts' = filter (/= Placeholder) (map su alts) in
1905 if null alts' then Placeholder
1906 else PAlternative ms b alts'
1907 su (PPair fc hls p l r) = PPair fc hls p (su l) (su r)
1908 su (PDPair fc hls p l t r) = PDPair fc hls p (su l) (su t) (su r)
1909 su t@(PLam fc _ _ _ _) = PHidden t
1910 su t@(PPi _ _ _ _ _) = PHidden t
1911 su t@(PConstant _ c) | isTypeConst c = PHidden t
1916stripUnmatchable i tm = tm
1919mkPApp fc a f as = let rest = drop a as in
1920 if a == 0 then appRest fc f rest
1921 else appRest fc (PApp fc f (take a as)) rest
1924 appRest fc f (a : as) = appRest fc (PApp fc f [a]) as
1926-- Find 'static' argument positions
1927-- (the declared ones, plus any names in argument position in the declared
1929-- FIXME: It's possible that this really has to happen after elaboration
1931findStatics :: IState -> PTerm -> (PTerm, [Bool])
1932findStatics ist tm = let (ns, ss) = fs tm
1933 in runState (pos ns ss tm) []
1934 where fs (PPi p n fc t sc)
1935 | Static <- pstatic p
1936 = let (ns, ss) = fs sc in
1937 (namesIn [] ist t : ns, n : ss)
1938 | otherwise = let (ns, ss) = fs sc in
1942 inOne n ns = length (filter id (map (elem n) ns)) == 1
1944 pos ns ss (PPi p n fc t sc)
1945 | elem n ss = do sc' <- pos ns ss sc
1948 return (PPi (p { pstatic = Static }) n fc t sc')
1949 | otherwise = do sc' <- pos ns ss sc
1952 return (PPi p n fc t sc')
1953 pos ns ss t = return t
1955-- for 6.12/7 compatibility
1956data EitherErr a b = LeftErr a | RightOK b deriving ( Functor )
1958instance Applicative (EitherErr a) where
1962instance Monad (EitherErr a) where
1965 (LeftErr e) >>= k = LeftErr e
1966 RightOK v >>= k = k v
1968toEither (LeftErr e) = Left e
1969toEither (RightOK ho) = Right ho
1971-- | Syntactic match of a against b, returning pair of variables in a
1972-- and what they match. Returns the pair that failed if not a match.
1973matchClause :: IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
1974matchClause = matchClause' False
1976matchClause' :: Bool -> IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
1977matchClause' names i x y = checkRpts $ match (fullApp x) (fullApp y) where
1978 matchArg x y = match (fullApp (getTm x)) (fullApp (getTm y))
1980 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
1983 match' x y = match (fullApp x) (fullApp y)
1984 match (PApp _ (PRef _ _ (NS (UN fi) [b])) [_,_,x]) x'
1985 | fi == txt "fromInteger" && b == txt "builtins",
1986 PConstant _ (I _) <- getTm x = match (getTm x) x'
1987 match x' (PApp _ (PRef _ _ (NS (UN fi) [b])) [_,_,x])
1988 | fi == txt "fromInteger" && b == txt "builtins",
1989 PConstant _ (I _) <- getTm x = match (getTm x) x'
1990 match (PApp _ (PRef _ _ (UN l)) [_,x]) x' | l == txt "lazy" = match (getTm x) x'
1991 match x (PApp _ (PRef _ _ (UN l)) [_,x']) | l == txt "lazy" = match x (getTm x')
1992 match (PApp _ f args) (PApp _ f' args')
1993 | length args == length args'
1994 = do mf <- match' f f'
1995 ms <- zipWithM matchArg args args'
1996 return (mf ++ concat ms)
1997 match (PRef f hl n) (PApp _ x []) = match (PRef f hl n) x
1998 match (PPatvar f n) xr = match (PRef f [f] n) xr
1999 match xr (PPatvar f n) = match xr (PRef f [f] n)
2000 match (PApp _ x []) (PRef f hl n) = match x (PRef f hl n)
2001 match (PRef _ _ n) tm@(PRef _ _ n')
2002 | n == n' && not names &&
2003 (not (isConName n (tt_ctxt i) || isFnName n (tt_ctxt i))
2004 || tm == Placeholder)
2006 -- if one namespace is missing, drop the other
2007 | n == n' || n == dropNS n' || dropNS n == n' = return []
2008 where dropNS (NS n _) = n
2010 match (PRef _ _ n) tm
2011 | not names && (not (isConName n (tt_ctxt i) ||
2012 isFnName n (tt_ctxt i)) || tm == Placeholder)
2014 match (PRewrite _ l r _) (PRewrite _ l' r' _)
2015 = do ml <- match' l l'
2018 match (PTyped l r) (PTyped l' r') = do ml <- match l l'
2021 match (PTyped l r) x = match l x
2022 match x (PTyped l r) = match x l
2023 match (PPair _ _ _ l r) (PPair _ _ _ l' r') = do ml <- match' l l'
2026 match (PDPair _ _ _ l t r) (PDPair _ _ _ l' t' r') = do ml <- match' l l'
2029 return (ml ++ mt ++ mr)
2030 match (PAlternative _ a as) (PAlternative _ a' as')
2031 = do ms <- zipWithM match' as as'
2033 match a@(PAlternative _ _ as) b
2034 = do let ms = zipWith match' as (repeat b)
2035 case (rights (map toEither ms)) of
2038 match (PCase _ _ _) _ = return [] -- lifted out
2039 match (PMetavar _ _) _ = return [] -- modified
2040 match (PInferRef _ _ _) _ = return [] -- modified
2041 match (PQuote _) _ = return []
2042 match (PProof _) _ = return []
2043 match (PTactics _) _ = return []
2044 match (PResolveTC _) (PResolveTC _) = return []
2045 match (PTrue _ _) (PTrue _ _) = return []
2046 match (PReturn _) (PReturn _) = return []
2047 match (PPi _ _ _ t s) (PPi _ _ _ t' s') = do mt <- match' t t'
2050 match (PLam _ _ _ t s) (PLam _ _ _ t' s') = do mt <- match' t t'
2053 match (PLet _ _ _ t ty s) (PLet _ _ _ t' ty' s') = do mt <- match' t t'
2054 mty <- match' ty ty'
2056 return (mt ++ mty ++ ms)
2057 match (PHidden x) (PHidden y)
2058 | RightOK xs <- match x y = return xs -- to collect variables
2059 | otherwise = return [] -- Otherwise hidden things are unmatchable
2061 | RightOK xs <- match x y = return xs
2062 | otherwise = return []
2064 | RightOK xs <- match x y = return xs
2065 | otherwise = return []
2066 match (PUnifyLog x) y = match' x y
2067 match x (PUnifyLog y) = match' x y
2068 match (PNoImplicits x) y = match' x y
2069 match x (PNoImplicits y) = match' x y
2070 match Placeholder _ = return []
2071 match _ Placeholder = return []
2072 match (PResolveTC _) _ = return []
2073 match a b | a == b = return []
2074 | otherwise = LeftErr (a, b)
2076 checkRpts (RightOK ms) = check ms where
2078 | Just t' <- lookup n xs = if t/=t' && t/=Placeholder && t'/=Placeholder
2081 check (_:xs) = check xs
2083 checkRpts (LeftErr x) = Left x
2085substMatches :: [(Name, PTerm)] -> PTerm -> PTerm
2086substMatches ms = substMatchesShadow ms []
2088substMatchesShadow :: [(Name, PTerm)] -> [Name] -> PTerm -> PTerm
2089substMatchesShadow [] shs t = t
2090substMatchesShadow ((n,tm):ns) shs t
2091 = substMatchShadow n shs tm (substMatchesShadow ns shs t)
2093substMatch :: Name -> PTerm -> PTerm -> PTerm
2094substMatch n = substMatchShadow n []
2096substMatchShadow :: Name -> [Name] -> PTerm -> PTerm -> PTerm
2097substMatchShadow n shs tm t = sm shs t where
2098 sm xs (PRef _ _ n') | n == n' = tm
2099 sm xs (PLam fc x xfc t sc) = PLam fc x xfc (sm xs t) (sm xs sc)
2100 sm xs (PPi p x fc t sc)
2102 = let x' = nextName x in
2103 PPi p x' fc (sm (x':xs) (substMatch x (PRef emptyFC [] x') t))
2104 (sm (x':xs) (substMatch x (PRef emptyFC [] x') sc))
2105 | otherwise = PPi p x fc (sm xs t) (sm (x : xs) sc)
2106 sm xs (PApp f x as) = fullApp $ PApp f (sm xs x) (map (fmap (sm xs)) as)
2107 sm xs (PCase f x as) = PCase f (sm xs x) (map (pmap (sm xs)) as)
2108 sm xs (PIfThenElse fc c t f) = PIfThenElse fc (sm xs c) (sm xs t) (sm xs f)
2109 sm xs (PRewrite f x y tm) = PRewrite f (sm xs x) (sm xs y)
2111 sm xs (PTyped x y) = PTyped (sm xs x) (sm xs y)
2112 sm xs (PPair f hls p x y) = PPair f hls p (sm xs x) (sm xs y)
2113 sm xs (PDPair f hls p x t y) = PDPair f hls p (sm xs x) (sm xs t) (sm xs y)
2114 sm xs (PAlternative ms a as) = PAlternative ms a (map (sm xs) as)
2115 sm xs (PHidden x) = PHidden (sm xs x)
2116 sm xs (PUnifyLog x) = PUnifyLog (sm xs x)
2117 sm xs (PNoImplicits x) = PNoImplicits (sm xs x)
2118 sm xs (PRunElab fc script ns) = PRunElab fc (sm xs script) ns
2119 sm xs (PConstSugar fc tm) = PConstSugar fc (sm xs tm)
2122 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
2125shadow :: Name -> Name -> PTerm -> PTerm
2126shadow n n' t = sm 0 t where
2127 sm 0 (PRef fc hl x) | n == x = PRef fc hl n'
2128 sm 0 (PLam fc x xfc t sc) | n /= x = PLam fc x xfc (sm 0 t) (sm 0 sc)
2129 | otherwise = PLam fc x xfc (sm 0 t) sc
2130 sm 0 (PPi p x fc t sc) | n /= x = PPi p x fc (sm 0 t) (sm 0 sc)
2131 | otherwise = PPi p x fc (sm 0 t) sc
2132 sm 0 (PLet fc x xfc t v sc) | n /= x = PLet fc x xfc (sm 0 t) (sm 0 v) (sm 0 sc)
2133 | otherwise = PLet fc x xfc (sm 0 t) (sm 0 v) sc
2134 sm 0 (PApp f x as) = PApp f (sm 0 x) (map (fmap (sm 0)) as)
2135 sm 0 (PAppBind f x as) = PAppBind f (sm 0 x) (map (fmap (sm 0)) as)
2136 sm 0 (PCase f x as) = PCase f (sm 0 x) (map (pmap (sm 0)) as)
2137 sm 0 (PIfThenElse fc c t f) = PIfThenElse fc (sm 0 c) (sm 0 t) (sm 0 f)
2138 sm 0 (PRewrite f x y tm) = PRewrite f (sm 0 x) (sm 0 y) (fmap (sm 0) tm)
2139 sm 0 (PTyped x y) = PTyped (sm 0 x) (sm 0 y)
2140 sm 0 (PPair f hls p x y) = PPair f hls p (sm 0 x) (sm 0 y)
2141 sm 0 (PDPair f hls p x t y) = PDPair f hls p (sm 0 x) (sm 0 t) (sm 0 y)
2142 sm 0 (PAlternative ms a as) = PAlternative ms a (map (sm 0) as)
2143 sm 0 (PTactics ts) = PTactics (map (fmap (sm 0)) ts)
2144 sm 0 (PProof ts) = PProof (map (fmap (sm 0)) ts)
2145 sm 0 (PHidden x) = PHidden (sm 0 x)
2146 sm 0 (PUnifyLog x) = PUnifyLog (sm 0 x)
2147 sm 0 (PNoImplicits x) = PNoImplicits (sm 0 x)
2148 sm 0 (PCoerced t) = PCoerced (sm 0 t)
2149 sm ql (PQuasiquote tm ty) = PQuasiquote (sm (ql + 1) tm) (fmap (sm ql) ty)
2150 sm ql (PUnquote tm) = PUnquote (sm (ql - 1) tm)
2151 sm ql x = descend (sm ql) x
2153-- | Rename any binders which are repeated (so that we don't have to mess
2154-- about with shadowing anywhere else).
2155mkUniqueNames :: [Name] -> [(Name, Name)] -> PTerm -> PTerm
2156mkUniqueNames env shadows tm
2157 = evalState (mkUniq 0 initMap tm) (S.fromList env) where
2159 initMap = M.fromList shadows
2161 inScope :: S.Set Name
2162 inScope = S.fromList $ boundNamesIn tm
2164 mkUniqA ql nmap arg = do t' <- mkUniq ql nmap (getTm arg)
2165 return (arg { getTm = t' })
2167 -- Initialise the unique name with the environment length (so we're not
2168 -- looking for too long...)
2169 initN (UN n) l = UN $ txt (str n ++ show l)
2170 initN (MN i s) l = MN (i+l) s
2173 -- FIXME: Probably ought to do this for completeness! It's fine as
2174 -- long as there are no bindings inside tactics though.
2175 mkUniqT _ nmap tac = return tac
2177 mkUniq :: Int -- ^ The number of quotations that we're under
2178 -> M.Map Name Name -> PTerm -> State (S.Set Name) PTerm
2179 mkUniq 0 nmap (PLam fc n nfc ty sc)
2183 then do let n' = uniqueNameSet (initN n (S.size env))
2184 (S.union env inScope)
2185 return (n', sc) -- shadow n n' sc)
2187 put (S.insert n' env)
2188 let nmap' = M.insert n n' nmap
2189 ty' <- mkUniq 0 nmap ty
2190 sc'' <- mkUniq 0 nmap' sc'
2191 return $! PLam fc n' nfc ty' sc''
2192 mkUniq 0 nmap (PPi p n fc ty sc)
2196 then do let n' = uniqueNameSet (initN n (S.size env))
2197 (S.union env inScope)
2198 return (n', sc) -- shadow n n' sc)
2200 put (S.insert n' env)
2201 let nmap' = M.insert n n' nmap
2202 ty' <- mkUniq 0 nmap ty
2203 sc'' <- mkUniq 0 nmap' sc'
2204 return $! PPi p n' fc ty' sc''
2205 mkUniq 0 nmap (PLet fc n nfc ty val sc)
2209 then do let n' = uniqueNameSet (initN n (S.size env))
2210 (S.union env inScope)
2211 return (n', sc) -- shadow n n' sc)
2213 put (S.insert n' env)
2214 let nmap' = M.insert n n' nmap
2215 ty' <- mkUniq 0 nmap ty; val' <- mkUniq 0 nmap val
2216 sc'' <- mkUniq 0 nmap' sc'
2217 return $! PLet fc n' nfc ty' val' sc''
2218 mkUniq 0 nmap (PApp fc t args)
2219 = do t' <- mkUniq 0 nmap t
2220 args' <- mapM (mkUniqA 0 nmap) args
2221 return $! PApp fc t' args'
2222 mkUniq 0 nmap (PAppBind fc t args)
2223 = do t' <- mkUniq 0 nmap t
2224 args' <- mapM (mkUniqA 0 nmap) args
2225 return $! PAppBind fc t' args'
2226 mkUniq 0 nmap (PCase fc t alts)
2227 = do t' <- mkUniq 0 nmap t
2228 alts' <- mapM (\(x,y)-> do x' <- mkUniq 0 nmap x; y' <- mkUniq 0 nmap y
2229 return (x', y')) alts
2230 return $! PCase fc t' alts'
2231 mkUniq 0 nmap (PIfThenElse fc c t f)
2232 = liftM3 (PIfThenElse fc) (mkUniq 0 nmap c) (mkUniq 0 nmap t) (mkUniq 0 nmap f)
2233 mkUniq 0 nmap (PPair fc hls p l r)
2234 = do l' <- mkUniq 0 nmap l; r' <- mkUniq 0 nmap r
2235 return $! PPair fc hls p l' r'
2236 mkUniq 0 nmap (PDPair fc hls p (PRef fc' hls' n) t sc)
2239 (n', sc') <- if n `S.member` env
2240 then do let n' = uniqueNameSet n (S.union env inScope)
2241 return (n', sc) -- shadow n n' sc)
2243 put (S.insert n' env)
2244 let nmap' = M.insert n n' nmap
2245 t' <- mkUniq 0 nmap t
2246 sc'' <- mkUniq 0 nmap' sc'
2247 return $! PDPair fc hls p (PRef fc' hls' n') t' sc''
2248 mkUniq 0 nmap (PDPair fc hls p l t r)
2249 = do l' <- mkUniq 0 nmap l; t' <- mkUniq 0 nmap t; r' <- mkUniq 0 nmap r
2250 return $! PDPair fc hls p l' t' r'
2251 mkUniq 0 nmap (PAlternative ns b as)
2252 -- store the nmap and defer the rest until we've pruned the set
2253 -- during elaboration
2254 = return $ PAlternative (M.toList nmap ++ ns) b as
2255 mkUniq 0 nmap (PHidden t) = liftM PHidden (mkUniq 0 nmap t)
2256 mkUniq 0 nmap (PUnifyLog t) = liftM PUnifyLog (mkUniq 0 nmap t)
2257 mkUniq 0 nmap (PDisamb n t) = liftM (PDisamb n) (mkUniq 0 nmap t)
2258 mkUniq 0 nmap (PNoImplicits t) = liftM PNoImplicits (mkUniq 0 nmap t)
2259 mkUniq 0 nmap (PProof ts) = liftM PProof (mapM (mkUniqT 0 nmap) ts)
2260 mkUniq 0 nmap (PTactics ts) = liftM PTactics (mapM (mkUniqT 0 nmap) ts)
2261 mkUniq 0 nmap (PRunElab fc ts ns) = liftM (\tm -> PRunElab fc tm ns) (mkUniq 0 nmap ts)
2262 mkUniq 0 nmap (PConstSugar fc tm) = liftM (PConstSugar fc) (mkUniq 0 nmap tm)
2263 mkUniq 0 nmap (PCoerced tm) = liftM PCoerced (mkUniq 0 nmap tm)
2264 mkUniq 0 nmap t = return $ shadowAll (M.toList nmap) t
2267 shadowAll ((n, n') : ns) t = shadow n n' (shadowAll ns t)
2269 mkUniq ql nmap (PQuasiquote tm ty) =
2270 do tm' <- mkUniq (ql + 1) nmap tm
2272 Nothing -> return Nothing
2273 Just t -> fmap Just $ mkUniq ql nmap t
2274 return $! PQuasiquote tm' ty'
2275 mkUniq ql nmap (PUnquote tm) = fmap PUnquote (mkUniq (ql - 1) nmap tm)
2277 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