2Module : Idris.AbsSyntax
3Description : Provides Idris' core data definitions and utility code.
6Maintainer : The Idris Community.
9{-# LANGUAGE DeriveFunctor, PatternGuards #-}
11module Idris.AbsSyntax(
12 module Idris.AbsSyntax
13 , module Idris.AbsSyntaxTree
16import Idris.AbsSyntaxTree
18import Idris.Core.Evaluate
20import Idris.Docstrings
21import Idris.IdeMode hiding (Opt(..))
22import IRTS.CodegenCommon
24import System.Directory (canonicalizePath, doesFileExist)
27import Control.Applicative
28import Control.Monad.State
29import Prelude hiding (Applicative, Foldable, Traversable, (<$>))
32import Data.List hiding (insert, union)
33import qualified Data.Map as M
35import qualified Data.Set as S
36import qualified Data.Text as T
37import System.IO.Error (tryIOError)
39import Data.Generics.Uniplate.Data (descend, descendM)
42import Util.DynamicLinker
46getContext :: Idris Context
47getContext = do i <- getIState; return (tt_ctxt i)
49forCodegen :: Codegen -> [(Codegen, a)] -> [a]
50forCodegen tgt xs = [x | (tgt', x) <- xs, eqLang tgt tgt']
52 eqLang (Via _ x) (Via _ y) = x == y
53 eqLang Bytecode Bytecode = True
56getObjectFiles :: Codegen -> Idris [FilePath]
57getObjectFiles tgt = do i <- getIState; return (forCodegen tgt $ idris_objs i)
59addObjectFile :: Codegen -> FilePath -> Idris ()
60addObjectFile tgt f = do i <- getIState; putIState $ i { idris_objs = nub $ (tgt, f) : idris_objs i }
62getLibs :: Codegen -> Idris [String]
63getLibs tgt = do i <- getIState; return (forCodegen tgt $ idris_libs i)
65addLib :: Codegen -> String -> Idris ()
66addLib tgt f = do i <- getIState; putIState $ i { idris_libs = nub $ (tgt, f) : idris_libs i }
68getFlags :: Codegen -> Idris [String]
69getFlags tgt = do i <- getIState; return (forCodegen tgt $ idris_cgflags i)
71addFlag :: Codegen -> String -> Idris ()
72addFlag tgt f = do i <- getIState; putIState $ i { idris_cgflags = nub $ (tgt, f) : idris_cgflags i }
74addDyLib :: [String] -> Idris (Either DynamicLib String)
75addDyLib libs = do i <- getIState
76 let ls = idris_dynamic_libs i
77 let importdirs = opt_importdirs (idris_options i)
78 case mapMaybe (findDyLib ls) libs of
79 x:_ -> return (Left x)
81 handle <- lift . lift .
82 mapM (\l -> catchIO (tryLoadLib importdirs l)
83 (\_ -> return Nothing)) $ libs
85 Nothing -> return (Right $ "Could not load dynamic alternatives \"" ++
86 intercalate "," libs ++ "\"")
87 Just x -> do putIState $ i { idris_dynamic_libs = x:ls }
89 where findDyLib :: [DynamicLib] -> String -> Maybe DynamicLib
90 findDyLib [] _ = Nothing
91 findDyLib (lib:libs') l | l == lib_name lib = Just lib
92 | otherwise = findDyLib libs' l
94getAutoImports :: Idris [FilePath]
95getAutoImports = do i <- getIState
96 return (opt_autoImport (idris_options i))
98addAutoImport :: FilePath -> Idris ()
99addAutoImport fp = do i <- getIState
100 let opts = idris_options i
101 put (i { idris_options = opts { opt_autoImport =
102 fp : opt_autoImport opts } } )
104addDefinedName :: Name -> Idris ()
105addDefinedName n = do ist <- getIState
106 putIState $ ist { idris_inmodule = S.insert n (idris_inmodule ist) }
108getDefinedNames :: Idris [Name]
109getDefinedNames = do ist <- getIState
110 return (S.toList (idris_inmodule ist))
112addTT :: Term -> Idris (Maybe Term)
113addTT t = do ist <- getIState
114 case M.lookup t (idris_ttstats ist) of
115 Nothing -> do let tt' = M.insert t (1, t) (idris_ttstats ist)
116 putIState $ ist { idris_ttstats = tt' }
118 Just (i, t') -> do let tt' = M.insert t' (i + 1, t') (idris_ttstats ist)
119 putIState $ ist { idris_ttstats = tt' }
123dumpTT = do ist <- get
124 let sts = sortBy count (M.toList (idris_ttstats ist))
128 count (_,x) (_,y) = compare y x
129 dump (tm, val) = runIO $ putStrLn (show val ++ ": " ++ show tm)
131addHdr :: Codegen -> String -> Idris ()
132addHdr tgt f = do i <- getIState; putIState $ i { idris_hdrs = nub $ (tgt, f) : idris_hdrs i }
134addImported :: Bool -> FilePath -> Idris ()
137 putIState $ i { idris_imported = nub $ (f, pub) : idris_imported i }
139addLangExt :: LanguageExt -> Idris ()
140addLangExt e = do i <- getIState
142 idris_language_extensions = e : idris_language_extensions i
145-- | Transforms are organised by the function being applied on the lhs
146-- of the transform, to make looking up appropriate transforms quicker
147addTrans :: Name -> (Term, Term) -> Idris ()
150 let t' = case lookupCtxtExact basefn (idris_transforms i) of
151 Just def -> (t : def)
153 putIState $ i { idris_transforms = addDef basefn t'
154 (idris_transforms i) }
156addErrRev :: (Term, Term) -> Idris ()
157addErrRev t = do i <- getIState
158 putIState $ i { idris_errRev = t : idris_errRev i }
160addErasureUsage :: Name -> Int -> Idris ()
161addErasureUsage n i = do ist <- getIState
162 putIState $ ist { idris_erasureUsed = (n, i) : idris_erasureUsed ist }
164addExport :: Name -> Idris ()
165addExport n = do ist <- getIState
166 putIState $ ist { idris_exports = n : idris_exports ist }
168addUsedName :: FC -> Name -> Name -> Idris ()
170 = do ist <- getIState
171 case lookupTyName n (tt_ctxt ist) of
172 [(n', ty)] -> addUsage n' 0 ty
173 [] -> throwError (At fc (NoSuchVariable n))
174 xs -> throwError (At fc (CantResolveAlts (map fst xs)))
175 where addUsage n i (Bind x _ sc) | x == arg = do addIBC (IBCUsage (n, i))
177 | otherwise = addUsage n (i + 1) sc
178 addUsage _ _ _ = throwError (At fc (Msg ("No such argument name " ++ show arg)))
180getErasureUsage :: Idris [(Name, Int)]
181getErasureUsage = do ist <- getIState;
182 return (idris_erasureUsed ist)
184getExports :: Idris [Name]
185getExports = do ist <- getIState
186 return (idris_exports ist)
188totcheck :: (FC, Name) -> Idris ()
189totcheck n = do i <- getIState; putIState $ i { idris_totcheck = idris_totcheck i ++ [n] }
191defer_totcheck :: (FC, Name) -> Idris ()
194 putIState $ i { idris_defertotcheck = nub (idris_defertotcheck i ++ [n]) }
196clear_totcheck :: Idris ()
197clear_totcheck = do i <- getIState; putIState $ i { idris_totcheck = [] }
199setFlags :: Name -> [FnOpt] -> Idris ()
200setFlags n fs = do i <- getIState; putIState $ i { idris_flags = addDef n fs (idris_flags i) }
202addFnOpt :: Name -> FnOpt -> Idris ()
203addFnOpt n f = do i <- getIState
204 let fls = case lookupCtxtExact n (idris_flags i) of
209setFnInfo :: Name -> FnInfo -> Idris ()
210setFnInfo n fs = do i <- getIState; putIState $ i { idris_fninfo = addDef n fs (idris_fninfo i) }
212setAccessibility :: Name -> Accessibility -> Idris ()
215 let ctxt = setAccess n a (tt_ctxt i)
216 putIState $ i { tt_ctxt = ctxt }
218-- | get the accessibility of a name outside this module
219getFromHideList :: Name -> Idris (Maybe Accessibility)
220getFromHideList n = do i <- getIState
221 return $ lookupCtxtExact n (hide_list i)
223setTotality :: Name -> Totality -> Idris ()
226 let ctxt = setTotal n a (tt_ctxt i)
227 putIState $ i { tt_ctxt = ctxt }
229setInjectivity :: Name -> Injectivity -> Idris ()
232 let ctxt = setInjective n a (tt_ctxt i)
233 putIState $ i { tt_ctxt = ctxt }
235getTotality :: Name -> Idris Totality
238 case lookupTotal n (tt_ctxt i) of
240 _ -> return (Total [])
242-- Get coercions which might return the required type
243getCoercionsTo :: IState -> Type -> [Name]
245 let cs = idris_coercions i
246 (fn,_) = unApply (getRetTy ty) in
248 where findCoercions _ [] = []
249 findCoercions t (n : ns) =
250 let ps = case lookupTy n (tt_ctxt i) of
251 [ty'] -> case unApply (getRetTy (normalise (tt_ctxt i) [] ty')) of
252 (t', _) -> [n | t == t']
254 ps ++ findCoercions t ns
256addToCG :: Name -> CGInfo -> Idris ()
259 putIState $ i { idris_callgraph = addDef n cg (idris_callgraph i) }
261addCalls :: Name -> [Name] -> Idris ()
264 case lookupCtxtExact n (idris_callgraph i) of
265 Nothing -> addToCG n (CGInfo calls Nothing [] [])
266 Just (CGInfo cs ans scg used) ->
267 addToCG n (CGInfo (nub (calls ++ cs)) ans scg used)
269addTyInferred :: Name -> Idris ()
272 putIState $ i { idris_tyinfodata =
273 addDef n TIPartial (idris_tyinfodata i) }
275addTyInfConstraints :: FC -> [(Term, Term)] -> Idris ()
276addTyInfConstraints fc ts = do logLvl 2 $ "TI missing: " ++ show ts
277 mapM_ addConstraint ts
279 where addConstraint (x, y) = findMVApps x y
282 = do let (fx, argsx) = unApply x
283 let (fy, argsy) = unApply y
288 else mapM_ addConstraint (zip argsx argsy)
290 tryAddMV (P _ mv _) y =
292 case lookup mv (idris_metavars ist) of
293 Just _ -> addConstraintRule mv y
295 tryAddMV _ _ = return ()
297 addConstraintRule :: Name -> Term -> Idris ()
298 addConstraintRule n t
300 logLvl 1 $ "TI constraint: " ++ show (n, t)
301 case lookupCtxt n (idris_tyinfodata ist) of
303 do mapM_ (checkConsistent t) ts
304 let ti' = addDef n (TISolution (t : ts))
305 (idris_tyinfodata ist)
306 put $ ist { idris_tyinfodata = ti' }
308 do let ti' = addDef n (TISolution [t])
309 (idris_tyinfodata ist)
310 put $ ist { idris_tyinfodata = ti' }
312 -- Check a solution is consistent with previous solutions
313 -- Meaning: If heads are both data types, they had better be the
315 checkConsistent :: Term -> Term -> Idris ()
316 checkConsistent x y =
317 do let (fx, _) = unApply x
318 let (fy, _) = unApply y
320 (P (TCon _ _) n _, P (TCon _ _) n' _) -> errWhen (n/=n')
321 (P (TCon _ _) n _, Constant _) -> errWhen True
322 (Constant _, P (TCon _ _) n' _) -> errWhen True
323 (P (DCon _ _ _) n _, P (DCon _ _ _) n' _) -> errWhen (n/=n')
328 (CantUnify False (x, Nothing) (y, Nothing) (Msg "") [] 0))
329 errWhen False = return ()
331isTyInferred :: Name -> Idris Bool
334 case lookupCtxt n (idris_tyinfodata i) of
335 [TIPartial] -> return True
338-- | Adds error handlers for a particular function and argument. If
339-- names are ambiguous, all matching handlers are updated.
340addFunctionErrorHandlers :: Name -> Name -> [Name] -> Idris ()
341addFunctionErrorHandlers f arg hs =
343 let oldHandlers = idris_function_errorhandlers i
344 let newHandlers = flip (addDef f) oldHandlers $
345 case lookupCtxtExact f oldHandlers of
346 Nothing -> M.singleton arg (S.fromList hs)
347 Just (oldHandlers) -> M.insertWith S.union arg (S.fromList hs) oldHandlers
348 -- will always be one of those two, thus no extra case
349 putIState $ i { idris_function_errorhandlers = newHandlers }
351-- | Trace all the names in a call graph starting at the given name
352getAllNames :: Name -> Idris [Name]
353getAllNames n = do i <- getIState
354 case getCGAllNames i n of
356 Nothing -> do ns <- allNames [] n
360getCGAllNames :: IState -> Name -> Maybe [Name]
361getCGAllNames i n = case lookupCtxtExact n (idris_callgraph i) of
362 Just ci -> allCalls ci
365addCGAllNames :: IState -> Name -> [Name] -> Idris ()
367 = case lookupCtxtExact n (idris_callgraph i) of
368 Just ci -> addToCG n (ci { allCalls = Just ns })
369 _ -> addToCG n (CGInfo [] (Just ns) [] [])
371allNames :: [Name] -> Name -> Idris [Name]
372allNames ns n | n `elem` ns = return []
373allNames ns n = do i <- getIState
374 case getCGAllNames i n of
376 Nothing -> case lookupCtxtExact n (idris_callgraph i) of
378 do more <- mapM (allNames (n:ns)) (calls ci)
379 let ns' = nub (n : concat more)
380 addCGAllNames i n ns'
384addCoercion :: Name -> Idris ()
385addCoercion n = do i <- getIState
386 putIState $ i { idris_coercions = nub $ n : idris_coercions i }
388addDocStr :: Name -> Docstring DocTerm -> [(Name, Docstring DocTerm)] -> Idris ()
391 putIState $ i { idris_docstrings = addDef n (doc, args) (idris_docstrings i) }
393addNameHint :: Name -> Name -> Idris ()
396 ty' <- case lookupCtxtName ty (idris_implicits i) of
397 [(tyn, _)] -> return tyn
398 [] -> throwError (NoSuchVariable ty)
399 tyns -> throwError (CantResolveAlts (map fst tyns))
400 let ns' = case lookupCtxt ty' (idris_namehints i) of
403 putIState $ i { idris_namehints = addDef ty' ns' (idris_namehints i) }
405getNameHints :: IState -> Name -> [Name]
406getNameHints _ (UN arr) | arr == txt "->" = [sUN "f",sUN "g"]
408 case lookupCtxt n (idris_namehints i) of
412addDeprecated :: Name -> String -> Idris ()
413addDeprecated n reason = do
415 putIState $ i { idris_deprecated = addDef n reason (idris_deprecated i) }
417getDeprecated :: Name -> Idris (Maybe String)
420 return $ lookupCtxtExact n (idris_deprecated i)
422addFragile :: Name -> String -> Idris ()
423addFragile n reason = do
425 putIState $ i { idris_fragile = addDef n reason (idris_fragile i) }
427getFragile :: Name -> Idris (Maybe String)
430 return $ lookupCtxtExact n (idris_fragile i)
432push_estack :: Name -> Bool -> Idris ()
433push_estack n implementation
435 putIState (i { elab_stack = (n, implementation) : elab_stack i })
437pop_estack :: Idris ()
438pop_estack = do i <- getIState
439 putIState (i { elab_stack = ptail (elab_stack i) })
443-- | Add an interface implementation function.
445-- Precondition: the implementation should have the correct type.
447-- Dodgy hack 1: Put integer implementations first in the list so they are
448-- resolved by default.
450-- Dodgy hack 2: put constraint chasers (ParentN) last
451addImplementation :: Bool -- ^ whether the name is an Integer implementation
452 -> Bool -- ^ whether to include the implementation in implementation search
453 -> Name -- ^ the name of the interface
454 -> Name -- ^ the name of the implementation
456addImplementation int res n i
457 = do ist <- getIState
458 case lookupCtxt n (idris_interfaces ist) of
459 [CI a b c d e f g ins fds] ->
460 do let cs = addDef n (CI a b c d e f g (addI i ins) fds) (idris_interfaces ist)
461 putIState $ ist { idris_interfaces = cs }
462 _ -> do let cs = addDef n (CI (sMN 0 "none") [] [] [] [] [] [] [(i, res)] []) (idris_interfaces ist)
463 putIState $ ist { idris_interfaces = cs }
464 where addI, insI :: Name -> [(Name, Bool)] -> [(Name, Bool)]
465 addI i ins | int = (i, res) : ins
466 | chaser n = ins ++ [(i, res)]
467 | otherwise = insI i ins
468 insI i [] = [(i, res)]
469 insI i (n : ns) | chaser (fst n) = (i, res) : n : ns
470 | otherwise = n : insI i ns
472 chaser (SN (ParentN _ _)) = True
473 chaser (NS n _) = chaser n
476-- | Add a privileged implementation - one which implementation search will
477-- happily resolve immediately if it is type correct This is used for
478-- naming parent implementations when defining an implementation with
479-- constraints. Returns the old list, so we can revert easily at the
481addOpenImpl :: [Name] -> Idris [Name]
482addOpenImpl ns = do ist <- getIState
483 ns' <- mapM (checkValid ist) ns
484 let open = idris_openimpls ist
485 putIState $ ist { idris_openimpls = nub (ns' ++ open) }
489 = case lookupCtxtName n (idris_implicits ist) of
490 [(n', _)] -> return n'
491 [] -> throwError (NoSuchVariable n)
492 more -> throwError (CantResolveAlts (map fst more))
494setOpenImpl :: [Name] -> Idris ()
495setOpenImpl ns = do ist <- getIState
496 putIState $ ist { idris_openimpls = ns }
498getOpenImpl :: Idris [Name]
499getOpenImpl = do ist <- getIState
500 return (idris_openimpls ist)
502addInterface :: Name -> InterfaceInfo -> Idris ()
504 = do ist <- getIState
505 let i' = case lookupCtxt n (idris_interfaces ist) of
506 [c] -> i { interface_implementations = interface_implementations c ++
507 interface_implementations i }
509 putIState $ ist { idris_interfaces = addDef n i' (idris_interfaces ist) }
511updateIMethods :: Name -> [(Name, PTerm)] -> Idris ()
512updateIMethods n meths
513 = do ist <- getIState
514 let i = case lookupCtxtExact n (idris_interfaces ist) of
515 Just c -> c { interface_methods = update (interface_methods c) }
516 Nothing -> error "Can't happen updateIMethods"
517 putIState $ ist { idris_interfaces = addDef n i (idris_interfaces ist) }
520 update (m@(n, (b, opts, t)) : rest)
521 | Just ty <- lookup n meths
522 = (n, (b, opts, ty)) : update rest
523 | otherwise = m : update rest
525addRecord :: Name -> RecordInfo -> Idris ()
526addRecord n ri = do ist <- getIState
527 putIState $ ist { idris_records = addDef n ri (idris_records ist) }
529addAutoHint :: Name -> Name -> Idris ()
532 case lookupCtxtExact n (idris_autohints ist) of
534 do let hs = addDef n [hint] (idris_autohints ist)
535 putIState $ ist { idris_autohints = hs }
537 do let hs = addDef n (hint : nhints) (idris_autohints ist)
538 putIState $ ist { idris_autohints = hs }
540getAutoHints :: Name -> Idris [Name]
541getAutoHints n = do ist <- getIState
542 case lookupCtxtExact n (idris_autohints ist) of
546addIBC :: IBCWrite -> Idris ()
549 when (notDef (ibc_write i)) $
550 putIState $ i { ibc_write = ibc : ibc_write i }
551 where notDef [] = True
552 notDef (IBCDef n': _) | n == n' = False
553 notDef (_ : is) = notDef is
554addIBC ibc = do i <- getIState; putIState $ i { ibc_write = ibc : ibc_write i }
557clearIBC = do i <- getIState; putIState $ i { ibc_write = [],
558 idris_inmodule = S.empty }
560resetNameIdx :: Idris ()
561resetNameIdx = do i <- getIState
562 put (i { idris_nameIdx = (0, emptyContext) })
564-- | Used to preserve sharing of names
565addNameIdx :: Name -> Idris (Int, Name)
566addNameIdx n = do i <- getIState
567 let (i', x) = addNameIdx' i n
571addNameIdx' :: IState -> Name -> (IState, (Int, Name))
573 = let idxs = snd (idris_nameIdx i) in
574 case lookupCtxt n idxs of
576 _ -> let i' = fst (idris_nameIdx i) + 1 in
577 (i { idris_nameIdx = (i', addDef n (i', n) idxs) }, (i', n))
579getSymbol :: Name -> Idris Name
580getSymbol n = do i <- getIState
581 case M.lookup n (idris_symbols i) of
583 Nothing -> do let sym' = M.insert n n (idris_symbols i)
584 put (i { idris_symbols = sym' })
587getHdrs :: Codegen -> Idris [String]
588getHdrs tgt = do i <- getIState; return (forCodegen tgt $ idris_hdrs i)
590getImported :: Idris [(FilePath, Bool)]
591getImported = do i <- getIState; return (idris_imported i)
593setErrSpan :: FC -> Idris ()
594setErrSpan x = do i <- getIState;
596 Nothing -> putIState $ i { errSpan = Just x }
600clearErr = do i <- getIState
601 putIState $ i { errSpan = Nothing }
603getSO :: Idris (Maybe String)
604getSO = do i <- getIState
605 return (compiled_so i)
607setSO :: Maybe String -> Idris ()
608setSO s = do i <- getIState
609 putIState (i { compiled_so = s })
611getIState :: Idris IState
614putIState :: IState -> Idris ()
617updateIState :: (IState -> IState) -> Idris ()
618updateIState f = do i <- getIState
621withContext :: (IState -> Ctxt a) -> Name -> b -> (a -> Idris b) -> Idris b
622withContext ctx name dflt action = do
624 case lookupCtxt name (ctx ist) of
628withContext_ :: (IState -> Ctxt a) -> Name -> (a -> Idris ()) -> Idris ()
629withContext_ ctx name action = withContext ctx name () action
631-- | A version of liftIO that puts errors into the exception type of
633runIO :: IO a -> Idris a
634runIO x = liftIO (tryIOError x) >>= either (throwError . Msg . show) return
635-- TODO: create specific Idris exceptions for specific IO errors such as "openFile: does not exist"
637-- Issue #1738 on the issue tracker.
638-- https://github.com/idris-lang/Idris-dev/issues/1738
641getName = do i <- getIState;
642 let idx = idris_name i;
643 putIState (i { idris_name = idx + 1 })
646-- | InternalApp keeps track of the real function application for
647-- making case splits from, not the application the programmer wrote,
648-- which doesn't have the whole context in any case other than top
650addInternalApp :: FilePath -> Int -> PTerm -> Idris ()
653 -- We canonicalise the path to make "./Test/Module.idr" equal
654 -- to "Test/Module.idr"
655 exists <- runIO $ doesFileExist fp
657 do fp' <- runIO $ canonicalizePath fp
658 putIState (i { idris_lineapps = ((fp', l), t) : idris_lineapps i })
660getInternalApp :: FilePath -> Int -> Idris PTerm
661getInternalApp fp l = do i <- getIState
662 -- We canonicalise the path to make
663 -- "./Test/Module.idr" equal to
665 exists <- runIO $ doesFileExist fp
667 then do fp' <- runIO $ canonicalizePath fp
668 case lookup (fp', l) (idris_lineapps i) of
670 Nothing -> return Placeholder
671 -- TODO: What if it's not there?
672 else return Placeholder
674-- | Pattern definitions are only used for coverage checking, so erase
675-- them when we're done
676clearOrigPats :: Idris ()
677clearOrigPats = do i <- get
678 let ps = idris_patdefs i
679 let ps' = mapCtxt (\ (_,miss) -> ([], miss)) ps
680 put (i { idris_patdefs = ps' })
682-- | Erase types from Ps in the context (basically ending up with
683-- what's in the .ibc, which is all we need after all the analysis is
685clearPTypes :: Idris ()
686clearPTypes = do i <- get
688 put (i { tt_ctxt = mapDefCtxt pErase ctxt })
689 where pErase (CaseOp c t tys orig _ cds)
690 = CaseOp c t tys orig [] (pErase' cds)
692 pErase' (CaseDefs (cs, c) rs)
693 = let c' = (cs, fmap pEraseType c) in
696checkUndefined :: FC -> Name -> Idris ()
700 (_:_) -> throwError . Msg $ show fc ++ ":" ++
701 show n ++ " already defined"
704isUndefined :: FC -> Name -> Idris Bool
707 case lookupTyExact n i of
708 Just _ -> return False
711setContext :: Context -> Idris ()
712setContext ctxt = do i <- getIState; putIState (i { tt_ctxt = ctxt } )
714updateContext :: (Context -> Context) -> Idris ()
715updateContext f = do i <- getIState; putIState (i { tt_ctxt = f (tt_ctxt i) } )
717addConstraints :: FC -> (Int, [UConstraint]) -> Idris ()
718addConstraints fc (v, cs)
719 = do tit <- typeInType
723 let ctxt' = ctxt { next_tvar = v }
724 let ics = insertAll (zip cs (repeat fc)) (idris_constraints i)
725 putIState $ i { tt_ctxt = ctxt', idris_constraints = ics }
728 insertAll ((ULE (UVal 0) _, fc) : cs) ics = insertAll cs ics
729 insertAll ((ULE x y, fc) : cs) ics | x == y = insertAll cs ics
730 insertAll ((c, fc) : cs) ics
731 = insertAll cs $ S.insert (ConstraintFC c fc) ics
733addDeferred = addDeferred' Ref
734addDeferredTyCon = addDeferred' (TCon 0 0)
736-- | Save information about a name that is not yet defined
737addDeferred' :: NameType
738 -> [(Name, (Int, Maybe Name, Type, [Name], Bool, Bool))]
739 -- ^ The Name is the name being made into a metavar,
740 -- the Int is the number of vars that are part of a
741 -- putative proof context, the Maybe Name is the
742 -- top-level function containing the new metavariable,
743 -- the Type is its type, and the Bool is whether :p is
747 = do mapM_ (\(n, (i, _, t, _, _, _)) -> updateContext (addTyDecl n nt (tidyNames S.empty t))) ns
748 mapM_ (\(n, _) -> when (not (n `elem` primDefs)) $ addIBC (IBCMetavar n)) ns
750 putIState $ i { idris_metavars = map (\(n, (i, top, _, ns, isTopLevel, isDefinable)) ->
751 (n, (top, i, ns, isTopLevel, isDefinable))) ns ++
754 -- 'tidyNames' is to generate user accessible names in case they are
755 -- needed in tactic scripts
756 tidyNames used (Bind (MN i x) b sc)
757 = let n' = uniqueNameSet (UN x) used in
758 Bind n' b $ tidyNames (S.insert n' used) sc
759 tidyNames used (Bind n b sc)
760 = let n' = uniqueNameSet n used in
761 Bind n' b $ tidyNames (S.insert n' used) sc
764solveDeferred :: FC -> Name -> Idris ()
767 case lookup n (idris_metavars i) of
768 Just (_, _, _, _, False) ->
769 throwError $ At fc $ Msg ("Can't define hole " ++ show n ++ " as it depends on other holes")
770 _ -> putIState $ i { idris_metavars =
771 filter (\(n', _) -> n/=n')
774 filter (notMV n) (ibc_write i)
776 where notMV n (IBCMetavar n') = not (n == n')
779getUndefined :: Idris [Name]
780getUndefined = do i <- getIState
781 return (map fst (idris_metavars i) \\ primDefs)
783isMetavarName :: Name -> IState -> Bool
785 = case lookupNames n (tt_ctxt ist) of
786 (t:_) -> isJust $ lookup t (idris_metavars ist)
789getWidth :: Idris ConsoleWidth
790getWidth = fmap idris_consolewidth getIState
792setWidth :: ConsoleWidth -> Idris ()
793setWidth w = do ist <- getIState
794 put ist { idris_consolewidth = w }
796setDepth :: Maybe Int -> Idris ()
797setDepth d = do ist <- getIState
798 put ist { idris_options = (idris_options ist) { opt_printdepth = d } }
800typeDescription :: String
801typeDescription = "The type of types"
804type1Doc :: Doc OutputAnnotation
805type1Doc = (annotate (AnnType "Type" "The type of types, one level up") $ text "Type 1")
808isetPrompt :: String -> Idris ()
809isetPrompt p = do i <- getIState
810 case idris_outputmode i of
811 IdeMode n h -> runIO . hPutStrLn h $ convSExp "set-prompt" p n
813-- | Tell clients how much was parsed and loaded
814isetLoadedRegion :: Idris ()
815isetLoadedRegion = do i <- getIState
816 let span = idris_parsedSpan i
819 case idris_outputmode i of
821 runIO . hPutStrLn h $
822 convSExp "set-loaded-region" fc n
825setLogLevel :: Int -> Idris ()
826setLogLevel l = do i <- getIState
827 let opts = idris_options i
828 let opt' = opts { opt_logLevel = l }
829 putIState $ i { idris_options = opt' }
831setLogCats :: [LogCat] -> Idris ()
834 let opts = idris_options i
835 let opt' = opts { opt_logcats = cs }
836 putIState $ i { idris_options = opt' }
838setCmdLine :: [Opt] -> Idris ()
839setCmdLine opts = do i <- getIState
840 let iopts = idris_options i
841 putIState $ i { idris_options = iopts { opt_cmdline = opts } }
843getCmdLine :: Idris [Opt]
844getCmdLine = do i <- getIState
845 return (opt_cmdline (idris_options i))
847getDumpHighlighting :: Idris Bool
848getDumpHighlighting = do ist <- getIState
849 return (findC (opt_cmdline (idris_options ist)))
850 where findC = elem DumpHighlights
852getDumpDefun :: Idris (Maybe FilePath)
853getDumpDefun = do i <- getIState
854 return $ findC (opt_cmdline (idris_options i))
855 where findC [] = Nothing
856 findC (DumpDefun x : _) = Just x
857 findC (_ : xs) = findC xs
859getDumpCases :: Idris (Maybe FilePath)
860getDumpCases = do i <- getIState
861 return $ findC (opt_cmdline (idris_options i))
862 where findC [] = Nothing
863 findC (DumpCases x : _) = Just x
864 findC (_ : xs) = findC xs
867logLevel = do i <- getIState
868 return (opt_logLevel (idris_options i))
870setAutoImpls :: Bool -> Idris ()
871setAutoImpls b = do i <- getIState
872 let opts = idris_options i
873 let opt' = opts { opt_autoimpls = b }
874 putIState $ i { idris_options = opt' }
876getAutoImpls :: Idris Bool
877getAutoImpls = do i <- getIState
878 return (opt_autoimpls (idris_options i))
880setErrContext :: Bool -> Idris ()
881setErrContext t = do i <- getIState
882 let opts = idris_options i
883 let opts' = opts { opt_errContext = t }
884 putIState $ i { idris_options = opts' }
886errContext :: Idris Bool
887errContext = do i <- getIState
888 return (opt_errContext (idris_options i))
890getOptimise :: Idris [Optimisation]
891getOptimise = do i <- getIState
892 return (opt_optimise (idris_options i))
894setOptimise :: [Optimisation] -> Idris ()
895setOptimise newopts = do i <- getIState
896 let opts = idris_options i
897 let opts' = opts { opt_optimise = newopts }
898 putIState $ i { idris_options = opts' }
900addOptimise :: Optimisation -> Idris ()
901addOptimise opt = do opts <- getOptimise
902 setOptimise (nub (opt : opts))
904removeOptimise :: Optimisation -> Idris ()
905removeOptimise opt = do opts <- getOptimise
906 setOptimise ((nub opts) \\ [opt])
908-- | Set appropriate optimisation set for the given level. We only
909-- have one optimisation that is configurable at the moment, however!
910setOptLevel :: Int -> Idris ()
911setOptLevel n | n <= 0 = setOptimise []
912setOptLevel 1 = setOptimise []
913setOptLevel 2 = setOptimise [PETransform]
914setOptLevel n | n >= 3 = setOptimise [PETransform]
917useREPL = do i <- getIState
918 return (opt_repl (idris_options i))
920setREPL :: Bool -> Idris ()
921setREPL t = do i <- getIState
922 let opts = idris_options i
923 let opt' = opts { opt_repl = t }
924 putIState $ i { idris_options = opt' }
926showOrigErr :: Idris Bool
927showOrigErr = do i <- getIState
928 return (opt_origerr (idris_options i))
930setShowOrigErr :: Bool -> Idris ()
931setShowOrigErr b = do i <- getIState
932 let opts = idris_options i
933 let opt' = opts { opt_origerr = b }
934 putIState $ i { idris_options = opt' }
936setAutoSolve :: Bool -> Idris ()
937setAutoSolve b = do i <- getIState
938 let opts = idris_options i
939 let opt' = opts { opt_autoSolve = b }
940 putIState $ i { idris_options = opt' }
942setNoBanner :: Bool -> Idris ()
943setNoBanner n = do i <- getIState
944 let opts = idris_options i
945 let opt' = opts { opt_nobanner = n }
946 putIState $ i { idris_options = opt' }
948getNoBanner :: Idris Bool
949getNoBanner = do i <- getIState
950 let opts = idris_options i
951 return (opt_nobanner opts)
953setEvalTypes :: Bool -> Idris ()
954setEvalTypes n = do i <- getIState
955 let opts = idris_options i
956 let opt' = opts { opt_evaltypes = n }
957 putIState $ i { idris_options = opt' }
959getDesugarNats :: Idris Bool
960getDesugarNats = do i <- getIState
961 let opts = idris_options i
962 return (opt_desugarnats opts)
965setDesugarNats :: Bool -> Idris ()
966setDesugarNats n = do i <- getIState
967 let opts = idris_options i
968 let opt' = opts { opt_desugarnats = n }
969 putIState $ i { idris_options = opt' }
971setQuiet :: Bool -> Idris ()
972setQuiet q = do i <- getIState
973 let opts = idris_options i
974 let opt' = opts { opt_quiet = q }
975 putIState $ i { idris_options = opt' }
977getQuiet :: Idris Bool
978getQuiet = do i <- getIState
979 let opts = idris_options i
980 return (opt_quiet opts)
982setCodegen :: Codegen -> Idris ()
983setCodegen t = do i <- getIState
984 let opts = idris_options i
985 let opt' = opts { opt_codegen = t }
986 putIState $ i { idris_options = opt' }
988codegen :: Idris Codegen
989codegen = do i <- getIState
990 return (opt_codegen (idris_options i))
993setOutputTy :: OutputType -> Idris ()
994setOutputTy t = do i <- getIState
995 let opts = idris_options i
996 let opt' = opts { opt_outputTy = t }
997 putIState $ i { idris_options = opt' }
999outputTy :: Idris OutputType
1000outputTy = do i <- getIState
1001 return $ opt_outputTy $ idris_options i
1003setIdeMode :: Bool -> Handle -> Idris ()
1004setIdeMode True h = do i <- getIState
1005 putIState $ i { idris_outputmode = IdeMode 0 h
1006 , idris_colourRepl = False
1008setIdeMode False _ = return ()
1010setTargetTriple :: String -> Idris ()
1011setTargetTriple t = do i <- getIState
1012 let opts = idris_options i
1013 opt' = opts { opt_triple = t }
1014 putIState $ i { idris_options = opt' }
1016targetTriple :: Idris String
1017targetTriple = do i <- getIState
1018 return (opt_triple (idris_options i))
1020setTargetCPU :: String -> Idris ()
1021setTargetCPU t = do i <- getIState
1022 let opts = idris_options i
1023 opt' = opts { opt_cpu = t }
1024 putIState $ i { idris_options = opt' }
1026targetCPU :: Idris String
1027targetCPU = do i <- getIState
1028 return (opt_cpu (idris_options i))
1033 -- Quietness overrides verbosity
1034 let quiet = opt_quiet $ idris_options i
1037 else return $ (opt_verbose $ idris_options i)
1039setVerbose :: Int -> Idris ()
1042 let opts = idris_options i
1043 let opt' = opts { opt_verbose = t }
1044 putIState $ i { idris_options = opt' }
1046iReport :: Int -> String -> Idris ()
1047iReport level msg = do
1048 verbosity <- verbose
1050 when (level <= verbosity) $
1051 case idris_outputmode i of
1052 RawOutput h -> runIO $ hPutStrLn h msg
1053 IdeMode n h -> runIO . hPutStrLn h $ convSExp "write-string" msg n
1056typeInType :: Idris Bool
1057typeInType = do i <- getIState
1058 return (opt_typeintype (idris_options i))
1060setTypeInType :: Bool -> Idris ()
1061setTypeInType t = do i <- getIState
1062 let opts = idris_options i
1063 let opt' = opts { opt_typeintype = t }
1064 putIState $ i { idris_options = opt' }
1066coverage :: Idris Bool
1067coverage = do i <- getIState
1068 return (opt_coverage (idris_options i))
1070setCoverage :: Bool -> Idris ()
1071setCoverage t = do i <- getIState
1072 let opts = idris_options i
1073 let opt' = opts { opt_coverage = t }
1074 putIState $ i { idris_options = opt' }
1076setIBCSubDir :: FilePath -> Idris ()
1077setIBCSubDir fp = do i <- getIState
1078 let opts = idris_options i
1079 let opt' = opts { opt_ibcsubdir = fp }
1080 putIState $ i { idris_options = opt' }
1082valIBCSubDir :: IState -> Idris FilePath
1083valIBCSubDir i = return (opt_ibcsubdir (idris_options i))
1085addImportDir :: FilePath -> Idris ()
1086addImportDir fp = do i <- getIState
1087 let opts = idris_options i
1088 let opt' = opts { opt_importdirs = nub $ fp : opt_importdirs opts }
1089 putIState $ i { idris_options = opt' }
1091setImportDirs :: [FilePath] -> Idris ()
1092setImportDirs fps = do i <- getIState
1093 let opts = idris_options i
1094 let opt' = opts { opt_importdirs = fps }
1095 putIState $ i { idris_options = opt' }
1097allImportDirs :: Idris [FilePath]
1098allImportDirs = do i <- getIState
1099 let optdirs = opt_importdirs (idris_options i)
1100 return ("." : reverse optdirs)
1102addSourceDir :: FilePath -> Idris ()
1103addSourceDir fp = do i <- getIState
1104 let opts = idris_options i
1105 let opts' = opts { opt_sourcedirs = nub $ fp : opt_sourcedirs opts }
1106 putIState $ i { idris_options = opts' }
1108setSourceDirs :: [FilePath] -> Idris ()
1109setSourceDirs fps = do i <- getIState
1110 let opts = idris_options i
1111 let opts' = opts { opt_sourcedirs = nub $ fps }
1112 putIState $ i { idris_options = opts' }
1114allSourceDirs :: Idris [FilePath]
1115allSourceDirs = do i <- getIState
1116 let optdirs = opt_sourcedirs (idris_options i)
1117 return ("." : reverse optdirs)
1119colourise :: Idris Bool
1120colourise = do i <- getIState
1121 return $ idris_colourRepl i
1123setColourise :: Bool -> Idris ()
1124setColourise b = do i <- getIState
1125 putIState $ i { idris_colourRepl = b }
1127impShow :: Idris Bool
1128impShow = do i <- getIState
1129 return (opt_showimp (idris_options i))
1131setImpShow :: Bool -> Idris ()
1132setImpShow t = do i <- getIState
1133 let opts = idris_options i
1134 let opt' = opts { opt_showimp = t }
1135 putIState $ i { idris_options = opt' }
1137setColour :: ColourType -> IdrisColour -> Idris ()
1138setColour ct c = do i <- getIState
1139 let newTheme = setColour' ct c (idris_colourTheme i)
1140 putIState $ i { idris_colourTheme = newTheme }
1141 where setColour' KeywordColour c t = t { keywordColour = c }
1142 setColour' BoundVarColour c t = t { boundVarColour = c }
1143 setColour' ImplicitColour c t = t { implicitColour = c }
1144 setColour' FunctionColour c t = t { functionColour = c }
1145 setColour' TypeColour c t = t { typeColour = c }
1146 setColour' DataColour c t = t { dataColour = c }
1147 setColour' PromptColour c t = t { promptColour = c }
1148 setColour' PostulateColour c t = t { postulateColour = c }
1150logLvl :: Int -> String -> Idris ()
1151logLvl = logLvlCats []
1153logCoverage :: Int -> String -> Idris ()
1154logCoverage = logLvlCats [ICoverage]
1156logErasure :: Int -> String -> Idris ()
1157logErasure = logLvlCats [IErasure]
1159-- | Log an action of the parser
1160logParser :: Int -> String -> Idris ()
1161logParser = logLvlCats parserCats
1163-- | Log an action of the elaborator.
1164logElab :: Int -> String -> Idris ()
1165logElab = logLvlCats elabCats
1167-- | Log an action of the compiler.
1168logCodeGen :: Int -> String -> Idris ()
1169logCodeGen = logLvlCats codegenCats
1171logIBC :: Int -> String -> Idris ()
1172logIBC = logLvlCats [IIBC]
1174-- | Log aspect of Idris execution
1176-- An empty set of logging levels is used to denote all categories.
1178-- @TODO update IDE protocol
1179logLvlCats :: [LogCat] -- ^ The categories that the message should appear under.
1180 -> Int -- ^ The Logging level the message should appear.
1181 -> String -- ^ The message to show the developer.
1183logLvlCats cs l msg = do
1185 let lvl = opt_logLevel (idris_options i)
1186 let cats = opt_logcats (idris_options i)
1188 when (inCat cs cats || null cats) $
1189 case idris_outputmode i of
1191 runIO $ hPutStrLn h msg
1193 let good = SexpList [IntegerAtom (toInteger l), toSExp msg]
1194 runIO . hPutStrLn h $ convSExp "log" good n
1196 inCat :: [LogCat] -> [LogCat] -> Bool
1197 inCat cs cats = any (`elem` cats) cs
1199cmdOptType :: Opt -> Idris Bool
1200cmdOptType x = do i <- getIState
1201 return $ x `elem` opt_cmdline (idris_options i)
1203noErrors :: Idris Bool
1204noErrors = do i <- getIState
1206 Nothing -> return True
1209setTypeCase :: Bool -> Idris ()
1210setTypeCase t = do i <- getIState
1211 let opts = idris_options i
1212 let opt' = opts { opt_typecase = t }
1213 putIState $ i { idris_options = opt' }
1215getIndentWith :: Idris Int
1218 return $ interactiveOpts_indentWith (idris_interactiveOpts i)
1220setIndentWith :: Int -> Idris ()
1221setIndentWith indentWith = do
1223 let opts = idris_interactiveOpts i
1224 let opts' = opts { interactiveOpts_indentWith = indentWith }
1225 putIState $ i { idris_interactiveOpts = opts' }
1227getIndentClause :: Idris Int
1230 return $ interactiveOpts_indentClause (idris_interactiveOpts i)
1232setIndentClause :: Int -> Idris ()
1233setIndentClause indentClause = do
1235 let opts = idris_interactiveOpts i
1236 let opts' = opts { interactiveOpts_indentClause = indentClause }
1237 putIState $ i { idris_interactiveOpts = opts' }
1239-- Dealing with parameters
1241expandParams :: (Name -> Name) -> [(Name, PTerm)] ->
1242 [Name] -> -- all names
1243 [Name] -> -- names with no declaration
1245expandParams dec ps ns infs tm = en 0 tm
1247 -- if we shadow a name (say in a lambda binding) that is used in a call to
1248 -- a lifted function, we need access to both names - once in the scope of the
1249 -- binding and once to call the lifted functions. So we'll explicitly shadow
1250 -- it. (Yes, it's a hack. The alternative would be to resolve names earlier
1251 -- but we didn't...)
1253 mkShadow (UN n) = MN 0 n
1254 mkShadow (MN i n) = MN (i+1) n
1255 mkShadow (NS x s) = NS (mkShadow x) s
1257 en :: Int -- ^ The quotation level - only transform terms that are used, not terms
1258 -- that are merely mentioned.
1260 en 0 (PLam fc n nfc t s)
1261 | n `elem` (map fst ps ++ ns)
1262 = let n' = mkShadow n in
1263 PLam fc n' nfc (en 0 t) (en 0 (shadow n n' s))
1264 | otherwise = PLam fc n nfc (en 0 t) (en 0 s)
1265 en 0 (PPi p n nfc t s)
1266 | n `elem` (map fst ps ++ ns)
1267 = let n' = mkShadow n in -- TODO THINK SHADOWING TacImp?
1268 PPi (enTacImp 0 p) n' nfc (en 0 t) (en 0 (shadow n n' s))
1269 | otherwise = PPi (enTacImp 0 p) n nfc (en 0 t) (en 0 s)
1270 en 0 (PLet fc n nfc ty v s)
1271 | n `elem` (map fst ps ++ ns)
1272 = let n' = mkShadow n in
1273 PLet fc n' nfc (en 0 ty) (en 0 v) (en 0 (shadow n n' s))
1274 | otherwise = PLet fc n nfc (en 0 ty) (en 0 v) (en 0 s)
1275 -- FIXME: Should only do this in a type signature!
1276 en 0 (PDPair f hls p (PRef f' fcs n) t r)
1277 | n `elem` (map fst ps ++ ns) && t /= Placeholder
1278 = let n' = mkShadow n in
1279 PDPair f hls p (PRef f' fcs n') (en 0 t) (en 0 (shadow n n' r))
1280 en 0 (PRewrite f by l r g) = PRewrite f by (en 0 l) (en 0 r) (fmap (en 0) g)
1281 en 0 (PTyped l r) = PTyped (en 0 l) (en 0 r)
1282 en 0 (PPair f hls p l r) = PPair f hls p (en 0 l) (en 0 r)
1283 en 0 (PDPair f hls p l t r) = PDPair f hls p (en 0 l) (en 0 t) (en 0 r)
1284 en 0 (PAlternative ns a as) = PAlternative ns a (map (en 0) as)
1285 en 0 (PHidden t) = PHidden (en 0 t)
1286 en 0 (PUnifyLog t) = PUnifyLog (en 0 t)
1287 en 0 (PDisamb ds t) = PDisamb ds (en 0 t)
1288 en 0 (PNoImplicits t) = PNoImplicits (en 0 t)
1289 en 0 (PDoBlock ds) = PDoBlock (map (fmap (en 0)) ds)
1290 en 0 (PProof ts) = PProof (map (fmap (en 0)) ts)
1291 en 0 (PTactics ts) = PTactics (map (fmap (en 0)) ts)
1293 en 0 (PQuote (Var n))
1294 | n `nselem` ns = PQuote (Var (dec n))
1295 en 0 (PApp fc (PInferRef fc' hl n) as)
1296 | n `nselem` ns = PApp fc (PInferRef fc' hl (dec n))
1297 (map ((pexp . (PRef fc hl)) . fst) ps ++ (map (fmap (en 0)) as))
1298 en 0 (PApp fc (PRef fc' hl n) as)
1299 | n `elem` infs = PApp fc (PInferRef fc' hl (dec n))
1300 (map ((pexp . (PRef fc hl)) . fst) ps ++ (map (fmap (en 0)) as))
1301 | n `nselem` ns = PApp fc (PRef fc' hl (dec n))
1302 (map ((pexp . (PRef fc hl)) . fst) ps ++ (map (fmap (en 0)) as))
1303 en 0 (PAppBind fc (PRef fc' hl n) as)
1304 | n `elem` infs = PAppBind fc (PInferRef fc' hl (dec n))
1305 (map ((pexp . (PRef fc hl)) . fst) ps ++ (map (fmap (en 0)) as))
1306 | n `nselem` ns = PAppBind fc (PRef fc' hl (dec n))
1307 (map ((pexp . (PRef fc hl)) . fst) ps ++ (map (fmap (en 0)) as))
1309 | n `elem` infs = PApp fc (PInferRef fc hl (dec n))
1310 (map ((pexp . (PRef fc hl)) . fst) ps)
1311 | n `nselem` ns = PApp fc (PRef fc hl (dec n))
1312 (map ((pexp . (PRef fc hl)) . fst) ps)
1313 en 0 (PInferRef fc hl n)
1314 | n `nselem` ns = PApp fc (PInferRef fc hl (dec n))
1315 (map ((pexp . (PRef fc hl)) . fst) ps)
1316 en 0 (PApp fc f as) = PApp fc (en 0 f) (map (fmap (en 0)) as)
1317 en 0 (PAppBind fc f as) = PAppBind fc (en 0 f) (map (fmap (en 0)) as)
1318 en 0 (PCase fc c os) = PCase fc (en 0 c) (map (pmap (en 0)) os)
1319 en 0 (PIfThenElse fc c t f) = PIfThenElse fc (en 0 c) (en 0 t) (en 0 f)
1320 en 0 (PRunElab fc tm ns) = PRunElab fc (en 0 tm) ns
1321 en 0 (PConstSugar fc tm) = PConstSugar fc (en 0 tm)
1323 en ql (PQuasiquote tm ty) = PQuasiquote (en (ql + 1) tm) (fmap (en ql) ty)
1324 en ql (PUnquote tm) = PUnquote (en (ql - 1) tm)
1326 en ql t = descend (en ql) t
1329 nselem x (y : xs) | nseq x y = True
1330 | otherwise = nselem x xs
1332 nseq x y = nsroot x == nsroot y
1334 enTacImp ql (TacImp aos st scr rig) = TacImp aos st (en ql scr) rig
1335 enTacImp ql other = other
1337expandParamsD :: Bool -> -- True = RHS only
1339 (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PDecl -> PDecl
1340expandParamsD rhsonly ist dec ps ns (PTy doc argdocs syn fc o n nfc ty)
1341 = if n `elem` ns && (not rhsonly)
1342 then -- trace (show (n, expandParams dec ps ns ty)) $
1343 PTy doc argdocs syn fc o (dec n) nfc (piBindp expl_param ps (expandParams dec ps ns [] ty))
1344 else --trace (show (n, expandParams dec ps ns ty)) $
1345 PTy doc argdocs syn fc o n nfc (expandParams dec ps ns [] ty)
1346expandParamsD rhsonly ist dec ps ns (PPostulate e doc syn fc nfc o n ty)
1347 = if n `elem` ns && (not rhsonly)
1348 then -- trace (show (n, expandParams dec ps ns ty)) $
1349 PPostulate e doc syn fc nfc o (dec n)
1350 (piBind ps (expandParams dec ps ns [] ty))
1351 else --trace (show (n, expandParams dec ps ns ty)) $
1352 PPostulate e doc syn fc nfc o n (expandParams dec ps ns [] ty)
1353expandParamsD rhsonly ist dec ps ns (PClauses fc opts n cs)
1354 = let n' = if n `elem` ns then dec n else n in
1355 PClauses fc opts n' (map expandParamsC cs)
1357 expandParamsC (PClause fc n lhs ws rhs ds)
1358 = let -- ps' = updateps True (namesIn ist rhs) (zip ps [0..])
1359 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
1360 lhs' = if rhsonly then lhs else (expandParams dec ps'' ns [] lhs)
1361 n' = if n `elem` ns then dec n else n
1362 -- names bound on the lhs should not be expanded on the rhs
1363 ns' = removeBound lhs ns in
1365 (map (expandParams dec ps'' ns' []) ws)
1366 (expandParams dec ps'' ns' [] rhs)
1367 (map (expandParamsD True ist dec ps'' ns') ds)
1368 expandParamsC (PWith fc n lhs ws wval pn ds)
1369 = let -- ps' = updateps True (namesIn ist wval) (zip ps [0..])
1370 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
1371 lhs' = if rhsonly then lhs else (expandParams dec ps'' ns [] lhs)
1372 n' = if n `elem` ns then dec n else n
1373 ns' = removeBound lhs ns in
1375 (map (expandParams dec ps'' ns' []) ws)
1376 (expandParams dec ps'' ns' [] wval)
1378 (map (expandParamsD rhsonly ist dec ps'' ns') ds)
1379 updateps yn nm [] = []
1380 updateps yn nm (((a, t), i):as)
1381 | (a `elem` nm) == yn = (a, t) : updateps yn nm as
1382 | otherwise = (sMN i (show a ++ "_shadow"), t) : updateps yn nm as
1384 removeBound lhs ns = ns \\ nub (bnames lhs)
1386 bnames (PRef _ _ n) = [n]
1387 bnames (PApp _ _ args) = concatMap (bnames . getTm) args
1388 bnames (PPair _ _ _ l r) = bnames l ++ bnames r
1389 bnames (PDPair _ _ _ l Placeholder r) = bnames l ++ bnames r
1392-- | Expands parameters defined in parameter and where blocks inside of declarations
1393expandParamsD rhs ist dec ps ns (PData doc argDocs syn fc co pd)
1394 = PData doc argDocs syn fc co (expandPData pd)
1396 -- just do the type decl, leave constructors alone (parameters will be
1397 -- added implicitly)
1398 expandPData (PDatadecl n nfc ty cons)
1400 then PDatadecl (dec n) nfc (piBind ps (expandParams dec ps ns [] ty))
1402 else PDatadecl n nfc (expandParams dec ps ns [] ty) (map econ cons)
1403 econ (doc, argDocs, n, nfc, t, fc, fs)
1404 = (doc, argDocs, dec n, nfc, piBindp expl ps (expandParams dec ps ns [] t), fc, fs)
1405expandParamsD rhs ist dec ps ns d@(PRecord doc rsyn fc opts name nfc prs pdocs fls cn cdoc csyn)
1407expandParamsD rhs ist dec ps ns (PParams f params pds)
1408 = PParams f (ps ++ map (mapsnd (expandParams dec ps ns [])) params)
1409 (map (expandParamsD True ist dec ps ns) pds)
1410-- (map (expandParamsD ist dec ps ns) pds)
1411expandParamsD rhs ist dec ps ns (PMutual f pds)
1412 = PMutual f (map (expandParamsD rhs ist dec ps ns) pds)
1413expandParamsD rhs ist dec ps ns (PInterface doc info f cs n nfc params pDocs fds decls cn cd)
1414 = PInterface doc info f
1415 (map (\ (n, t) -> (n, expandParams dec ps ns [] t)) cs)
1417 (map (\(n, fc, t) -> (n, fc, expandParams dec ps ns [] t)) params)
1420 (map (expandParamsD rhs ist dec ps ns) decls)
1423expandParamsD rhs ist dec ps ns (PImplementation doc argDocs info f cs pnames acc opts n nfc params pextra ty cn decls)
1424 = let cn' = case cn of
1425 Just n -> if n `elem` ns then Just (dec n) else Just n
1426 Nothing -> Nothing in
1427 PImplementation doc argDocs info f
1428 (map (\ (n, t) -> (n, expandParams dec ps ns [] t)) cs)
1431 (map (expandParams dec ps ns []) params)
1432 (map (\ (n, t) -> (n, expandParams dec ps ns [] t)) pextra)
1433 (expandParams dec ps ns [] ty)
1435 (map (expandParamsD True ist dec ps ns) decls)
1436expandParamsD rhs ist dec ps ns d = d
1438mapsnd f (x, t) = (x, f t)
1440expandImplementationScope ist dec ps ns (PImplementation doc argDocs info f cs pnames acc opts n nfc params pextra ty cn decls)
1441 = PImplementation doc argDocs info f cs pnames acc opts n nfc params (ps ++ pextra)
1443expandImplementationScope ist dec ps ns d = d
1445-- | Calculate a priority for a type, for deciding elaboration order
1446-- * if it's just a type variable or concrete type, do it early (0)
1447-- * if there's only type variables and injective constructors, do it next (1)
1448-- * if there's a function type, next (2)
1449-- * finally, everything else (3)
1450getPriority :: IState -> PTerm -> Int
1451getPriority i tm = 1 -- pri tm
1454 case lookupP n (tt_ctxt i) of
1455 ((P (DCon _ _ _) _ _):_) -> 1
1456 ((P (TCon _ _) _ _):_) -> 1
1457 ((P Ref _ _):_) -> 1
1458 [] -> 0 -- must be locally bound, if it's not an error...
1459 pri (PPi _ _ _ x y) = max 5 (max (pri x) (pri y))
1461 pri (PRewrite _ _ l r _) = max 1 (max (pri l) (pri r))
1462 pri (PApp _ f as) = max 1 (max (pri f) (foldr (max . pri . getTm) 0 as))
1463 pri (PAppBind _ f as) = max 1 (max (pri f) (foldr (max . pri . getTm) 0 as))
1464 pri (PCase _ f as) = max 1 (max (pri f) (foldr (max . pri . snd) 0 as))
1465 pri (PTyped l r) = pri l
1466 pri (PPair _ _ _ l r) = max 1 (max (pri l) (pri r))
1467 pri (PDPair _ _ _ l t r) = max 1 (max (pri l) (max (pri t) (pri r)))
1468 pri (PAlternative _ a as) = maximum (map pri as)
1469 pri (PConstant _ _) = 0
1474addStatics :: Name -> Term -> PTerm -> Idris ()
1475addStatics n tm ptm =
1476 do let (statics, dynamics) = initStatics tm ptm
1479 = nub $ case lookupCtxtExact n (idris_fninfo ist) of
1480 Just p -> getNamesFrom 0 (fn_params p) tm ++
1481 concatMap (getParamNames ist . snd) statics
1482 _ -> concatMap (getParamNames ist . snd) statics
1484 let stnames = nub $ concatMap (freeArgNames . snd) statics
1485 let dnames = (nub $ concatMap (freeArgNames . snd) dynamics)
1487 -- also get the arguments which are 'uniquely inferrable' from
1488 -- statics (see sec 4.2 of "Scrapping Your Inefficient Engine")
1489 -- or parameters to the type of a static
1490 let statics' = nub $ map fst statics ++
1491 filter (\x -> not (elem x dnames)) stnames
1492 let stpos = staticList statics' tm
1494 unless (null statics) $
1495 logLvl 3 $ "Statics for " ++ show n ++ " " ++ show tm ++ "\n"
1496 ++ showTmImpls ptm ++ "\n"
1497 ++ show statics ++ "\n" ++ show dynamics
1498 ++ "\n" ++ show paramnames
1499 ++ "\n" ++ show stpos
1500 putIState $ i { idris_statics = addDef n stpos (idris_statics i) }
1501 addIBC (IBCStatic n)
1503 initStatics (Bind n (Pi _ _ ty _) sc) (PPi p n' fc t s)
1504 | n /= n' = let (static, dynamic) = initStatics sc (PPi p n' fc t s) in
1505 (static, (n, ty) : dynamic)
1506 initStatics (Bind n (Pi _ _ ty _) sc) (PPi p n' fc _ s)
1507 = let (static, dynamic) = initStatics (instantiate (P Bound n ty) sc) s in
1508 if pstatic p == Static then ((n, ty) : static, dynamic)
1509 else if (not (searchArg p))
1510 then (static, (n, ty) : dynamic)
1511 else (static, dynamic)
1512 initStatics t pt = ([], [])
1514 getParamNames ist tm | (P _ n _ , args) <- unApply tm
1515 = case lookupCtxtExact n (idris_datatypes ist) of
1516 Just ti -> getNamePos 0 (param_pos ti) args
1518 where getNamePos i ps [] = []
1519 getNamePos i ps (P _ n _ : as)
1520 | i `elem` ps = n : getNamePos (i + 1) ps as
1521 getNamePos i ps (_ : as) = getNamePos (i + 1) ps as
1522 getParamNames ist (Bind t (Pi _ _ (P _ n _) _) sc)
1523 = n : getParamNames ist sc
1524 getParamNames ist _ = []
1526 getNamesFrom i ps (Bind n (Pi _ _ _ _) sc)
1527 | i `elem` ps = n : getNamesFrom (i + 1) ps sc
1528 | otherwise = getNamesFrom (i + 1) ps sc
1529 getNamesFrom i ps sc = []
1531 freeArgNames (Bind n (Pi _ _ ty _) sc)
1532 = nub $ freeNames ty ++ freeNames sc -- treat '->' as fn here
1533 freeArgNames tm = let (_, args) = unApply tm in
1534 concatMap freeNames args
1536 -- if a name appears in an interface or tactic implicit index, it doesn't
1537 -- affect its 'uniquely inferrable' from a static status since these are
1538 -- resolved by searching.
1539 searchArg (Constraint _ _ _) = True
1540 searchArg (TacImp _ _ _ _) = True
1543 staticList sts (Bind n (Pi _ _ _ _) sc) = (n `elem` sts) : staticList sts sc
1546-- Dealing with implicit arguments
1548-- Add some bound implicits to the using block if they aren't there already
1550addToUsing :: [Using] -> [(Name, PTerm)] -> [Using]
1551addToUsing us [] = us
1552addToUsing us ((n, t) : ns)
1553 | n `notElem` mapMaybe impName us = addToUsing (us ++ [UImplicit n t]) ns
1554 | otherwise = addToUsing us ns
1555 where impName (UImplicit n _) = Just n
1558-- Add constraint bindings from using block
1560addUsingConstraints :: SyntaxInfo -> FC -> PTerm -> Idris PTerm
1561addUsingConstraints syn fc t
1563 let ns = namesIn [] ist t
1564 let cs = getConstraints t -- check declared constraints
1565 let addconsts = uconsts \\ cs
1566 return (doAdd addconsts ns t)
1567 where uconsts = filter uconst (using syn)
1568 uconst (UConstraint _ _) = True
1572 -- if all of args in ns, then add it
1573 doAdd (UConstraint c args : cs) ns t
1574 | all (\n -> elem n ns) args
1575 = PPi (Constraint [] Dynamic RigW) (sMN 0 "cu") NoFC
1576 (mkConst c args) (doAdd cs ns t)
1577 | otherwise = doAdd cs ns t
1579 mkConst c args = PApp fc (PRef fc [] c)
1580 (map (PExp 0 [] (sMN 0 "carg") . PRef fc []) args)
1582 getConstraints (PPi (Constraint _ _ _) _ _ c sc)
1583 = getcapp c ++ getConstraints sc
1584 getConstraints (PPi _ _ _ c sc) = getConstraints sc
1585 getConstraints _ = []
1587 getcapp (PApp _ (PRef _ _ c) args)
1588 = do ns <- mapM getName args
1589 return (UConstraint c ns)
1592 getName (PExp _ _ _ (PRef _ _ n)) = return n
1595-- | Add implicit bindings from using block, and bind any missing names
1596addUsingImpls :: SyntaxInfo -> Name -> FC -> PTerm -> Idris PTerm
1597addUsingImpls syn n fc t
1598 = do ist <- getIState
1599 autoimpl <- getAutoImpls
1600 let ns_in = implicitNamesIn (map iname uimpls) ist t
1601 let ns = if autoimpl then ns_in
1602 else filter (\n -> n `elem` (map iname uimpls)) ns_in
1604 let badnames = filter (\n -> not (implicitable n) &&
1605 n `notElem` (map iname uimpls)) ns
1606 unless (null badnames) $
1607 throwError (At fc (Elaborating "type of " n Nothing
1608 (NoSuchVariable (head badnames))))
1609 let cs = getArgnames t -- get already bound names
1610 let addimpls = filter (\n -> iname n `notElem` cs) uimpls
1611 -- if all names in the arguments of addconsts appear in ns,
1612 -- add the constraint implicitly
1613 return (bindFree ns (doAdd addimpls ns t))
1614 where uimpls = filter uimpl (using syn)
1615 uimpl (UImplicit _ _) = True
1618 iname (UImplicit n _) = n
1619 iname (UConstraint _ _) = error "Can't happen addUsingImpls"
1622 -- if all of args in ns, then add it
1623 doAdd (UImplicit n ty : cs) ns t
1625 = PPi impl_gen n NoFC ty (doAdd cs ns t)
1626 | otherwise = doAdd cs ns t
1628 -- bind the free names which weren't in the using block
1631 | elem n (map iname uimpls) = bindFree ns tm
1633 = PPi (impl_gen { pargopts = [InaccessibleArg] }) n NoFC Placeholder (bindFree ns tm)
1635 getArgnames (PPi _ n _ c sc)
1636 = n : getArgnames sc
1639-- Given the original type and the elaborated type, return the implicitness
1640-- status of each pi-bound argument, and whether it's inaccessible (True) or not.
1642getUnboundImplicits :: IState -> Type -> PTerm -> [(Bool, PArg)]
1643getUnboundImplicits i t tm = getImps t (collectImps tm)
1644 where collectImps (PPi p n _ t sc)
1645 = (n, (p, t)) : collectImps sc
1648 scopedimpl (Just i) = not (toplevel_imp i)
1649 scopedimpl _ = False
1651 getImps (Bind n (Pi _ i _ _) sc) imps
1652 | scopedimpl i = getImps sc imps
1653 getImps (Bind n (Pi _ _ t _) sc) imps
1654 | Just (p, t') <- lookup n imps = argInfo n p t' : getImps sc imps
1656 argInfo n (Imp opt _ _ _ _ _) Placeholder
1657 = (True, PImp 0 True opt n Placeholder)
1658 argInfo n (Imp opt _ _ _ _ _) t'
1659 = (False, PImp (getPriority i t') True opt n t')
1660 argInfo n (Exp opt _ _ _) t'
1661 = (InaccessibleArg `elem` opt,
1662 PExp (getPriority i t') opt n t')
1663 argInfo n (Constraint opt _ _) t'
1664 = (InaccessibleArg `elem` opt,
1665 PConstraint 10 opt n t')
1666 argInfo n (TacImp opt _ scr _) t'
1667 = (InaccessibleArg `elem` opt,
1668 PTacImplicit 10 opt n scr t')
1669 getImps (Bind n (Pi _ _ t _) sc) imps = impBind n t : getImps sc imps
1670 where impBind n t = (True, PImp 1 True [] n Placeholder)
1673-- Add implicit Pi bindings for any names in the term which appear in an
1674-- argument position.
1676-- This has become a right mess already. Better redo it some time...
1677-- TODO: This is obsoleted by the new way of elaborating types, (which
1678-- calls addUsingImpls) but there's still a couple of places which use
1679-- it. Clean them up!
1681-- Issue 1739 in the issue tracker
1682-- https://github.com/idris-lang/Idris-dev/issues/1739
1683implicit :: ElabInfo -> SyntaxInfo -> Name -> PTerm -> Idris PTerm
1684implicit info syn n ptm = implicit' info syn [] n ptm
1686implicit' :: ElabInfo -> SyntaxInfo -> [Name] -> Name -> PTerm -> Idris PTerm
1687implicit' info syn ignore n ptm
1689 auto <- getAutoImpls
1690 let (tm', impdata) = implicitise auto syn ignore i ptm
1691 defaultArgCheck (eInfoNames info ++ M.keys (idris_implicits i)) impdata
1692-- let (tm'', spos) = findStatics i tm'
1693 putIState $ i { idris_implicits = addDef n impdata (idris_implicits i) }
1695 logLvl 5 ("Implicit " ++ show n ++ " " ++ show impdata)
1697-- putIState $ i { idris_statics = addDef n spos (idris_statics i) }
1700 -- Detect unknown names in default arguments and throw error if found.
1701 defaultArgCheck :: [Name] -> [PArg] -> Idris ()
1702 defaultArgCheck knowns params = foldM_ notFoundInDefault knowns params
1704 notFoundInDefault :: [Name] -> PArg -> Idris [Name]
1705 notFoundInDefault kns (PTacImplicit _ _ n script _)
1707 case notFound kns (namesIn [] i script) of
1708 Nothing -> return (n:kns)
1709 Just name -> throwError (NoSuchVariable name)
1710 notFoundInDefault kns p = return ((pname p):kns)
1712 notFound :: [Name] -> [Name] -> Maybe Name
1713 notFound kns [] = Nothing
1714 notFound kns (SN (WhereN _ _ _) : ns) = notFound kns ns -- Known already
1715 notFound kns (n:ns) = if elem n kns then notFound kns ns else Just n
1717-- | Even if auto_implicits is off, we need to call this so we record
1718-- which arguments are implicit
1719implicitise :: Bool -> SyntaxInfo -> [Name] -> IState -> PTerm -> (PTerm, [PArg])
1720implicitise auto syn ignore ist tm = -- trace ("INCOMING " ++ showImp True tm) $
1721 let (declimps, ns') = execState (imps True [] tm) ([], [])
1722 ns = filter (\n -> auto && implicitable n || elem n (map fst uvars)) $
1723 ns' \\ (map fst pvars ++ no_imp syn ++ ignore)
1724 nsOrder = filter (not . inUsing) ns ++ filter inUsing ns in
1726 then (tm, reverse declimps)
1727 else implicitise auto syn ignore ist (pibind uvars nsOrder tm)
1729 uvars = map ipair (filter uimplicit (using syn))
1730 pvars = syn_params syn
1732 inUsing n = n `elem` map fst uvars
1734 ipair (UImplicit x y) = (x, y)
1735 uimplicit (UImplicit _ _) = True
1738 dropAll (x:xs) ys | x `elem` ys = dropAll xs ys
1739 | otherwise = x : dropAll xs ys
1742 -- Find names in argument position in a type, suitable for implicit
1744 -- Not the function position, but do everything else...
1745 implNamesIn uv (PApp fc f args) = concatMap (implNamesIn uv . getTm) args
1746 implNamesIn uv t = implicitNamesIn (map fst uv) ist t
1748 imps top env ty@(PApp _ f as)
1749 = do (decls, ns) <- get
1750 let isn = nub (implNamesIn uvars ty)
1751 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1752 imps top env (PPi (Imp l _ _ _ _ _) n _ ty sc)
1753 = do let isn = nub (implNamesIn uvars ty) `dropAll` [n]
1755 put (PImp (getPriority ist ty) True l n Placeholder : decls,
1756 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1757 imps True (n:env) sc
1758 imps top env (PPi (Exp l _ _ _) n _ ty sc)
1759 = do let isn = nub (implNamesIn uvars ty ++ case sc of
1760 (PRef _ _ x) -> namesIn uvars ist sc `dropAll` [n]
1762 (decls, ns) <- get -- ignore decls in HO types
1763 put (PExp (getPriority ist ty) l n Placeholder : decls,
1764 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1765 imps True (n:env) sc
1766 imps top env (PPi (Constraint l _ _) n _ ty sc)
1767 = do let isn = nub (implNamesIn uvars ty ++ case sc of
1768 (PRef _ _ x) -> namesIn uvars ist sc `dropAll` [n]
1770 (decls, ns) <- get -- ignore decls in HO types
1771 put (PConstraint 10 l n Placeholder : decls,
1772 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1773 imps True (n:env) sc
1774 imps top env (PPi (TacImp l _ scr _) n _ ty sc)
1775 = do let isn = nub (implNamesIn uvars ty ++ case sc of
1776 (PRef _ _ x) -> namesIn uvars ist sc `dropAll` [n]
1778 (decls, ns) <- get -- ignore decls in HO types
1779 put (PTacImplicit 10 l n scr Placeholder : decls,
1780 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1781 imps True (n:env) sc
1782 imps top env (PRewrite _ _ l r _)
1783 = do (decls, ns) <- get
1784 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1785 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1786 imps top env (PTyped l r)
1788 imps top env (PPair _ _ _ l r)
1789 = do (decls, ns) <- get
1790 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1791 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1792 imps top env (PDPair _ _ _ (PRef _ _ n) t r)
1793 = do (decls, ns) <- get
1794 let isn = nub (namesIn uvars ist t ++ namesIn uvars ist r) \\ [n]
1795 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1796 imps top env (PDPair _ _ _ l t r)
1797 = do (decls, ns) <- get
1798 let isn = namesIn uvars ist l ++ namesIn uvars ist t ++
1800 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1801 imps top env (PAlternative ms a as)
1802 = do (decls, ns) <- get
1803 let isn = concatMap (namesIn uvars ist) as
1804 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1805 imps top env (PLam fc n _ ty sc)
1806 = do imps False env ty
1807 imps False (n:env) sc
1808 imps top env (PHidden tm) = imps False env tm
1809 imps top env (PUnifyLog tm) = imps False env tm
1810 imps top env (PNoImplicits tm) = imps False env tm
1811 imps top env (PRunElab fc tm ns) = imps False env tm
1812 imps top env (PConstSugar fc tm) = imps top env tm -- ignore PConstSugar - it's for highlighting only!
1813 imps top env _ = return ()
1815 pibind using [] sc = sc
1816 pibind using (n:ns) sc
1817 = case lookup n using of
1818 Just ty -> PPi impl_gen
1819 n NoFC ty (pibind using ns sc)
1820 Nothing -> PPi (impl_gen { pargopts = [InaccessibleArg] })
1821 n NoFC Placeholder (pibind using ns sc)
1823-- | Add implicit arguments in function calls
1824addImplPat :: IState -> PTerm -> PTerm
1825addImplPat = addImpl' True [] [] []
1827addImplBound :: IState -> [Name] -> PTerm -> PTerm
1828addImplBound ist ns = addImpl' False ns [] [] ist
1830addImplBoundInf :: IState -> [Name] -> [Name] -> PTerm -> PTerm
1831addImplBoundInf ist ns inf = addImpl' False ns inf [] ist
1833-- | Add the implicit arguments to applications in the term [Name]
1834-- gives the names to always expend, even when under a binder of that
1835-- name (this is to expand methods with implicit arguments in
1836-- dependent interfaces).
1837addImpl :: [Name] -> IState -> PTerm -> PTerm
1838addImpl = addImpl' False [] []
1840-- TODO: in patterns, don't add implicits to function names guarded by constructors
1841-- and *not* inside a PHidden
1843addImpl' :: Bool -> [Name] -> [Name] -> [Name] -> IState -> PTerm -> PTerm
1844addImpl' inpat env infns imp_meths ist ptm
1845 = ai inpat False (zip env (repeat Nothing)) [] (mkUniqueNames env [] ptm)
1847 topname = case ptm of
1849 PApp _ (PRef _ _ n) _ -> n
1850 _ -> sUN "" -- doesn't matter then
1852 ai :: Bool -> Bool -> [(Name, Maybe PTerm)] -> [[T.Text]] -> PTerm -> PTerm
1853 ai inpat qq env ds (PRef fc fcs f)
1854 | f `elem` infns = PInferRef fc fcs f
1855 | not (f `elem` map fst env) = handleErr $ aiFn topname inpat inpat qq imp_meths ist fc f fc ds []
1856 ai inpat qq env ds (PHidden (PRef fc hl f))
1857 | not (f `elem` map fst env) = PHidden (handleErr $ aiFn topname inpat False qq imp_meths ist fc f fc ds [])
1858 ai inpat qq env ds (PRewrite fc by l r g)
1859 = let l' = ai inpat qq env ds l
1860 r' = ai inpat qq env ds r
1861 g' = fmap (ai inpat qq env ds) g in
1862 PRewrite fc by l' r' g'
1863 ai inpat qq env ds (PTyped l r)
1864 = let l' = ai inpat qq env ds l
1865 r' = ai inpat qq env ds r in
1867 ai inpat qq env ds (PPair fc hls p l r)
1868 = let l' = ai inpat qq env ds l
1869 r' = ai inpat qq env ds r in
1870 PPair fc hls p l' r'
1871 ai inpat qq env ds (PDPair fc hls p l t r)
1872 = let l' = ai inpat qq env ds l
1873 t' = ai inpat qq env ds t
1874 r' = ai inpat qq env ds r in
1875 PDPair fc hls p l' t' r'
1876 ai inpat qq env ds (PAlternative ms a as)
1877 = let as' = map (ai inpat qq env ds) as in
1878 PAlternative ms a as'
1879 ai inpat qq env _ (PDisamb ds' as) = ai inpat qq env ds' as
1880 ai inpat qq env ds (PApp fc (PInferRef ffc hl f) as)
1881 = let as' = map (fmap (ai inpat qq env ds)) as in
1882 PApp fc (PInferRef ffc hl f) as'
1883 ai inpat qq env ds (PApp fc ftm@(PRef ffc hl f) as)
1884 | f `elem` infns = ai inpat qq env ds (PApp fc (PInferRef ffc hl f) as)
1885 | not (f `elem` map fst env)
1886 = let as' = map (fmap (ai inpat qq env ds)) as in
1887 handleErr $ aiFn topname inpat False qq imp_meths ist fc f ffc ds as'
1888 | Just (Just ty) <- lookup f env =
1889 let as' = map (fmap (ai inpat qq env ds)) as
1890 arity = getPArity ty in
1891 mkPApp fc arity ftm as'
1892 ai inpat qq env ds (PApp fc f as)
1893 = let f' = ai inpat qq env ds f
1894 as' = map (fmap (ai inpat qq env ds)) as in
1896 ai inpat qq env ds (PWithApp fc f a)
1897 = PWithApp fc (ai inpat qq env ds f) (ai inpat qq env ds a)
1898 ai inpat qq env ds (PCase fc c os)
1899 = let c' = ai inpat qq env ds c in
1900 -- leave lhs alone, because they get lifted into a new pattern match
1901 -- definition which is passed through addImpl again
1902 PCase fc c' (map aiCase os)
1905 = (lhs, ai inpat qq (env ++ patnames lhs) ds rhs)
1907 -- Anything beginning with a lower case letter, not applied,
1908 -- and no namespace is a pattern variable
1909 patnames (PApp _ (PRef _ _ f) [])
1910 | implicitable f = [(f, Nothing)]
1911 patnames (PRef _ _ f)
1912 | implicitable f = [(f, Nothing)]
1913 patnames (PApp _ (PRef _ _ _) args)
1914 = concatMap patnames (map getTm args)
1915 patnames (PPair _ _ _ l r) = patnames l ++ patnames r
1916 patnames (PDPair _ _ _ l t r) = patnames l ++ patnames t ++ patnames r
1917 patnames (PAs _ _ t) = patnames t
1918 patnames (PAlternative _ _ ts) = concatMap patnames ts
1922 ai inpat qq env ds (PIfThenElse fc c t f) = PIfThenElse fc (ai inpat qq env ds c)
1923 (ai inpat qq env ds t)
1924 (ai inpat qq env ds f)
1926 -- If the name in a lambda is an unapplied data constructor name, do this
1927 -- as a 'case' instead because we'll expect to match on it
1928 ai inpat qq env ds (PLam fc n nfc ty sc)
1929 = if canBeDConName n (tt_ctxt ist)
1930 then ai inpat qq env ds (PLam fc (sMN 0 "lamp") NoFC ty
1931 (PCase fc (PRef fc [] (sMN 0 "lamp") )
1932 [(PRef fc [] n, sc)]))
1933 else let ty' = ai inpat qq env ds ty
1934 sc' = ai inpat qq ((n, Just ty):env) ds sc in
1935 PLam fc n nfc ty' sc'
1936 ai inpat qq env ds (PLet fc n nfc ty val sc)
1937 = if canBeDConName n (tt_ctxt ist)
1938 then ai inpat qq env ds (PCase fc val [(PRef fc [] n, sc)])
1939 else let ty' = ai inpat qq env ds ty
1940 val' = ai inpat qq env ds val
1941 sc' = ai inpat qq ((n, Just ty):env) ds sc in
1942 PLet fc n nfc ty' val' sc'
1943 ai inpat qq env ds (PPi p n nfc ty sc)
1944 = let ty' = ai inpat qq env ds ty
1945 env' = if n `elem` imp_meths then env
1947 ((n, Just ty) : env)
1948 sc' = ai inpat qq env' ds sc in
1950 ai inpat qq env ds (PGoal fc r n sc)
1951 = let r' = ai inpat qq env ds r
1952 sc' = ai inpat qq ((n, Nothing):env) ds sc in
1954 ai inpat qq env ds (PHidden tm) = PHidden (ai inpat qq env ds tm)
1955 -- Don't do PProof or PTactics since implicits get added when scope is
1956 -- properly known in ElabTerm.runTac
1957 ai inpat qq env ds (PUnifyLog tm) = PUnifyLog (ai inpat qq env ds tm)
1958 ai inpat qq env ds (PNoImplicits tm) = PNoImplicits (ai inpat qq env ds tm)
1959 ai inpat qq env ds (PQuasiquote tm g) = PQuasiquote (ai inpat True env ds tm)
1960 (fmap (ai inpat True env ds) g)
1961 ai inpat qq env ds (PUnquote tm) = PUnquote (ai inpat False env ds tm)
1962 ai inpat qq env ds (PRunElab fc tm ns) = PRunElab fc (ai inpat False env ds tm) ns
1963 ai inpat qq env ds (PConstSugar fc tm) = PConstSugar fc (ai inpat qq env ds tm)
1964 ai inpat qq env ds tm = tm
1966 handleErr (Left err) = PElabError err
1967 handleErr (Right x) = x
1969-- if in a pattern, and there are no arguments, and there's no possible
1970-- names with zero explicit arguments, don't add implicits.
1972aiFn :: Name -> Bool -> Bool -> Bool
1975 -> Name -- ^ function being applied
1977 -> [PArg] -- ^ initial arguments (if in a pattern)
1979aiFn topname inpat True qq imp_meths ist fc f ffc ds []
1980 | inpat && implicitable f && unqualified f = Right $ PPatvar ffc f
1982 = case lookupDef f (tt_ctxt ist) of
1983 [] -> Right $ PPatvar ffc f
1984 alts -> let ialts = lookupCtxtName f (idris_implicits ist) in
1985 -- trace (show f ++ " " ++ show (fc, any (all imp) ialts, ialts, any constructor alts)) $
1986 if (not (vname f) || tcname f
1987 || any (conCaf (tt_ctxt ist)) ialts)
1988-- any constructor alts || any allImp ialts))
1989 then aiFn topname inpat False qq imp_meths ist fc f ffc ds [] -- use it as a constructor
1990 else Right $ PPatvar ffc f
1991 where imp (PExp _ _ _ _) = False
1994 allImp xs = all imp xs
1996 unqualified (NS _ _) = False
1997 unqualified _ = True
1999 constructor (TyDecl (DCon _ _ _) _) = True
2000 constructor _ = False
2002 conCaf ctxt (n, cia) = (isDConName n ctxt || (qq && isTConName n ctxt)) && allImp cia
2004 vname (UN n) = True -- non qualified
2007aiFn topname inpat expat qq imp_meths ist fc f ffc ds as
2008 | f `elem` primNames = Right $ PApp fc (PRef ffc [ffc] f) as
2009aiFn topname inpat expat qq imp_meths ist fc f ffc ds as
2010 -- This is where namespaces get resolved by adding PAlternative
2011 = do let ns = lookupCtxtName f (idris_implicits ist)
2012 let nh = filter (\(n, _) -> notHidden n) ns
2013 let ns' = case trimAlts ds nh of
2017 [(f',ns)] -> Right $ mkPApp fc (length ns) (PRef ffc [ffc] (isImpName f f'))
2019 [] -> case metaVar f (map fst (idris_metavars ist)) of
2020 Just f' -> Right $ PApp fc (PRef ffc [ffc] f') as
2021 Nothing -> Right $ mkPApp fc (length as) (PRef ffc [ffc] f) as
2023 PAlternative [] (ExactlyOne True) $
2024 map (\(f', ns) -> mkPApp fc (length ns) (PRef ffc [ffc] (isImpName f f'))
2025 (insertImpl ns as)) alts
2027 -- if the name is in imp_meths, we should actually refer to the bound
2028 -- name rather than the global one after expanding implicits
2029 isImpName f f' | f `elem` imp_meths = f
2032 -- If it's a metavariable name, try to qualify it from the list of
2033 -- unsolved metavariables
2034 metaVar f (mvn : ns) | f == nsroot mvn = Just mvn
2035 metaVar f (_ : ns) = metaVar f ns
2036 metaVar f [] = Nothing
2038 trimAlts [] alts = alts
2040 = filter (\(x, _) -> any (\d -> d `isPrefixOf` nspace x) ns) alts
2045 notHidden n = case getAccessibility n of
2051 = case lookupDefAccExact n False (tt_ctxt ist) of
2055 insertImpl :: [PArg] -- ^ expected argument types (from idris_implicits)
2056 -> [PArg] -- ^ given arguments
2059 = let (as', badimpls) = partition (impIn ps) as in
2060 map addUnknownImp badimpls ++
2061 insImpAcc M.empty ps (filter expArg as') (filter (not . expArg) as')
2063 insImpAcc :: M.Map Name PTerm -- accumulated param names & arg terms
2064 -> [PArg] -- parameters
2065 -> [PArg] -- explicit arguments
2066 -> [PArg] -- implicits given
2068 insImpAcc pnas (PExp p l n ty : ps) (PExp _ _ _ tm : given) imps =
2069 PExp p l n tm : insImpAcc (M.insert n tm pnas) ps given imps
2070 insImpAcc pnas (PConstraint p l n ty : ps) (PConstraint _ _ _ tm : given) imps =
2071 PConstraint p l n tm : insImpAcc (M.insert n tm pnas) ps given imps
2072 insImpAcc pnas (PConstraint p l n ty : ps) given imps =
2073 let rtc = PResolveTC fc in
2074 PConstraint p l n rtc : insImpAcc (M.insert n rtc pnas) ps given imps
2075 insImpAcc pnas (PImp p _ l n ty : ps) given imps =
2076 case find n imps [] of
2078 PImp p False l n tm : insImpAcc (M.insert n tm pnas) ps given imps'
2080 PImp p True l n Placeholder :
2081 insImpAcc (M.insert n Placeholder pnas) ps given imps
2082 insImpAcc pnas (PTacImplicit p l n sc' ty : ps) given imps =
2083 let sc = addImpl imp_meths ist (substMatches (M.toList pnas) sc') in
2084 case find n imps [] of
2086 PTacImplicit p l n sc tm :
2087 insImpAcc (M.insert n tm pnas) ps given imps'
2090 then PTacImplicit p l n sc Placeholder :
2091 insImpAcc (M.insert n Placeholder pnas) ps given imps
2092 else PTacImplicit p l n sc sc :
2093 insImpAcc (M.insert n sc pnas) ps given imps
2094 insImpAcc _ expected [] imps = map addUnknownImp imps -- so that unused implicits give error
2095 insImpAcc _ _ given imps = given ++ imps
2097 addUnknownImp arg = arg { argopts = UnknownImp : argopts arg }
2099 find n [] acc = Nothing
2100 find n (PImp _ _ _ n' t : gs) acc
2101 | n == n' = Just (t, reverse acc ++ gs)
2102 find n (PTacImplicit _ _ n' _ t : gs) acc
2103 | n == n' = Just (t, reverse acc ++ gs)
2104 find n (g : gs) acc = find n gs (g : acc)
2106-- | return True if the second argument is an implicit argument which
2107-- is expected in the implicits, or if it's not an implicit
2108impIn :: [PArg] -> PArg -> Bool
2109impIn ps (PExp _ _ _ _) = True
2110impIn ps (PConstraint _ _ _ _) = True
2111impIn ps arg = any (\p -> not (expArg arg) && pname arg == pname p) ps
2113expArg (PExp _ _ _ _) = True
2114expArg (PConstraint _ _ _ _) = True
2117-- replace non-linear occurrences with _
2119stripLinear :: IState -> PTerm -> PTerm
2120stripLinear i tm = evalState (sl tm) [] where
2121 sl :: PTerm -> State [Name] PTerm
2123 | (_:_) <- lookupTy f (tt_ctxt i)
2124 = return $ PRef fc hl f
2125 | otherwise = do ns <- get
2127 then return $ PHidden (PRef fc hl f) -- Placeholder
2128 else do put (f : ns)
2129 return (PRef fc hl f)
2133 then return $ PHidden (PPatvar fc f) -- Placeholder
2134 else do put (f : ns)
2135 return (PPatvar fc f)
2136 -- Assumption is that variables are all the same in each alternative
2137 sl t@(PAlternative ms b as) = do ns <- get
2139 return (PAlternative ms b as')
2140 where slAlts ns (a : as) = do put ns
2144 slAlts ns [] = return []
2145 sl (PPair fc hls p l r) = do l' <- sl l; r' <- sl r; return (PPair fc hls p l' r')
2146 sl (PDPair fc hls p l t r) = do l' <- sl l
2149 return (PDPair fc hls p l' t' r')
2150 sl (PApp fc fn args) = do fn' <- case fn of
2151 -- Just the args, fn isn't matchable as a var
2152 PRef _ _ _ -> return fn
2154 args' <- mapM slA args
2155 return $ PApp fc fn' args'
2156 where slA (PImp p m l n t) = do t' <- sl t
2157 return $ PImp p m l n t'
2158 slA (PExp p l n t) = do t' <- sl t
2159 return $ PExp p l n t'
2160 slA (PConstraint p l n t)
2162 return $ PConstraint p l n t'
2163 slA (PTacImplicit p l n sc t)
2165 return $ PTacImplicit p l n sc t'
2168-- | Remove functions which aren't applied to anything, which must then
2169-- be resolved by unification. Assume names resolved and alternatives
2170-- filled in (so no ambiguity).
2171stripUnmatchable :: IState -> PTerm -> PTerm
2172stripUnmatchable i (PApp fc fn args) = PApp fc fn (fmap (fmap su) args) where
2173 su :: PTerm -> PTerm
2174 su tm@(PRef fc hl f)
2175 | (Bind n (Pi _ _ t _) sc :_) <- lookupTy f (tt_ctxt i)
2177 | (TType _ : _) <- lookupTy f (tt_ctxt i),
2178 not (implicitable f)
2180 | (UType _ : _) <- lookupTy f (tt_ctxt i),
2181 not (implicitable f)
2183 su (PApp fc f@(PRef _ _ fn) args)
2184 -- here we use canBeDConName because the impossible pattern
2185 -- check will not necessarily fully resolve constructor names,
2186 -- and these bare names will otherwise get in the way of
2187 -- impossbility checking.
2188 | -- Just fn <- getFn f,
2189 canBeDConName fn ctxt
2190 = PApp fc f (fmap (fmap su) args)
2191 where getFn (PRef _ _ fn) = Just fn
2192 getFn (PApp _ f args) = getFn f
2195 = PHidden (PApp fc f args)
2196 su (PAlternative ms b alts)
2197 = let alts' = filter (/= Placeholder) (map su alts) in
2198 if null alts' then Placeholder
2199 else PAlternative ms b alts'
2200 su (PPair fc hls p l r) = PPair fc hls p (su l) (su r)
2201 su (PDPair fc hls p l t r) = PDPair fc hls p (su l) (su t) (su r)
2202 su t@(PLam fc _ _ _ _) = PHidden t
2203 su t@(PPi _ _ _ _ _) = PHidden t
2204 su t@(PConstant _ c) | isTypeConst c = PHidden t
2209stripUnmatchable i tm = tm
2212mkPApp fc a f as = let rest = drop a as in
2213 if a == 0 then appRest fc f rest
2214 else appRest fc (PApp fc f (take a as)) rest
2217 appRest fc f (a : as) = appRest fc (PApp fc f [a]) as
2221-- | Find 'static' argument positions
2222-- (the declared ones, plus any names in argument position in the declared
2224-- FIXME: It's possible that this really has to happen after elaboration
2225findStatics :: IState -> PTerm -> (PTerm, [Bool])
2226findStatics ist tm = let (ns, ss) = fs tm
2227 in runState (pos ns ss tm) []
2228 where fs (PPi p n fc t sc)
2229 | Static <- pstatic p
2230 = let (ns, ss) = fs sc in
2231 (namesIn [] ist t : ns, n : ss)
2232 | otherwise = let (ns, ss) = fs sc in
2236 inOne n ns = length (filter id (map (elem n) ns)) == 1
2238 pos ns ss (PPi p n fc t sc)
2239 | elem n ss = do sc' <- pos ns ss sc
2242 return (PPi (p { pstatic = Static }) n fc t sc')
2243 | otherwise = do sc' <- pos ns ss sc
2246 return (PPi p n fc t sc')
2247 pos ns ss t = return t
2249-- for 6.12/7 compatibility
2250data EitherErr a b = LeftErr a | RightOK b deriving ( Functor )
2252instance Applicative (EitherErr a) where
2256instance Monad (EitherErr a) where
2259 (LeftErr e) >>= _ = LeftErr e
2260 RightOK v >>= k = k v
2262toEither :: EitherErr a b -> Either a b
2263toEither (LeftErr e) = Left e
2264toEither (RightOK ho) = Right ho
2266-- | Syntactic match of a against b, returning pair of variables in a
2267-- and what they match. Returns the pair that failed if not a match.
2268matchClause :: IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
2269matchClause = matchClause' False
2271matchClause' :: Bool -> IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
2272matchClause' names i x y = checkRpts $ match (fullApp x) (fullApp y) where
2273 matchArg x y = match (fullApp (getTm x)) (fullApp (getTm y))
2275 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
2278 match' x y = match (fullApp x) (fullApp y)
2279 match (PApp _ (PRef _ _ (NS (UN fi) [b])) [_,_,x]) x'
2280 | fi == txt "fromInteger" && b == txt "builtins",
2281 PConstant _ (I _) <- getTm x = match (getTm x) x'
2282 match x' (PApp _ (PRef _ _ (NS (UN fi) [b])) [_,_,x])
2283 | fi == txt "fromInteger" && b == txt "builtins",
2284 PConstant _ (I _) <- getTm x = match (getTm x) x'
2285 match (PApp _ (PRef _ _ (UN l)) [_,x]) x' | l == txt "lazy" = match (getTm x) x'
2286 match x (PApp _ (PRef _ _ (UN l)) [_,x']) | l == txt "lazy" = match x (getTm x')
2287 match (PApp _ f args) (PApp _ f' args')
2288 | length args == length args'
2289 = do mf <- match' f f'
2290 ms <- zipWithM matchArg args args'
2291 return (mf ++ concat ms)
2292 match (PRef f hl n) (PApp _ x []) = match (PRef f hl n) x
2293 match (PPatvar f n) xr = match (PRef f [f] n) xr
2294 match xr (PPatvar f n) = match xr (PRef f [f] n)
2295 match (PApp _ x []) (PRef f hl n) = match x (PRef f hl n)
2296 match (PRef _ _ n) tm@(PRef _ _ n')
2297 | n == n' && not names &&
2298 (not (isConName n (tt_ctxt i) || isFnName n (tt_ctxt i))
2299 || tm == Placeholder)
2301 -- if one namespace is missing, drop the other
2302 | n == n' || n == dropNS n' || dropNS n == n' = return []
2303 where dropNS (NS n _) = n
2305 match (PRef _ _ n) tm
2306 | not names && (not (isConName n (tt_ctxt i) ||
2307 isFnName n (tt_ctxt i)) || tm == Placeholder)
2309 match (PRewrite _ by l r _) (PRewrite _ by' l' r' _) | by == by'
2310 = do ml <- match' l l'
2313 match (PTyped l r) (PTyped l' r') = do ml <- match l l'
2316 match (PTyped l r) x = match l x
2317 match x (PTyped l r) = match x l
2318 match (PPair _ _ _ l r) (PPair _ _ _ l' r') = do ml <- match' l l'
2321 match (PDPair _ _ _ l t r) (PDPair _ _ _ l' t' r') = do ml <- match' l l'
2324 return (ml ++ mt ++ mr)
2325 match (PAlternative _ a as) (PAlternative _ a' as')
2326 = do ms <- zipWithM match' as as'
2328 match a@(PAlternative _ _ as) b
2329 = do let ms = zipWith match' as (repeat b)
2330 case (rights (map toEither ms)) of
2333 match (PCase _ _ _) _ = return [] -- lifted out
2334 match (PMetavar _ _) _ = return [] -- modified
2335 match (PInferRef _ _ _) _ = return [] -- modified
2336 match (PQuote _) _ = return []
2337 match (PProof _) _ = return []
2338 match (PTactics _) _ = return []
2339 match (PResolveTC _) (PResolveTC _) = return []
2340 match (PTrue _ _) (PTrue _ _) = return []
2341 match (PPi _ _ _ t s) (PPi _ _ _ t' s') = do mt <- match' t t'
2344 match (PLam _ _ _ t s) (PLam _ _ _ t' s') = do mt <- match' t t'
2347 match (PLet _ _ _ t ty s) (PLet _ _ _ t' ty' s') = do mt <- match' t t'
2348 mty <- match' ty ty'
2350 return (mt ++ mty ++ ms)
2351 match (PHidden x) (PHidden y)
2352 | RightOK xs <- match x y = return xs -- to collect variables
2353 | otherwise = return [] -- Otherwise hidden things are unmatchable
2355 | RightOK xs <- match x y = return xs
2356 | otherwise = return []
2358 | RightOK xs <- match x y = return xs
2359 | otherwise = return []
2360 match (PUnifyLog x) y = match' x y
2361 match x (PUnifyLog y) = match' x y
2362 match (PNoImplicits x) y = match' x y
2363 match x (PNoImplicits y) = match' x y
2364 match Placeholder _ = return []
2365 match _ Placeholder = return []
2366 match (PResolveTC _) _ = return []
2367 match a b | a == b = return []
2368 | otherwise = LeftErr (a, b)
2370 checkRpts (RightOK ms) = check ms where
2372 | Just t' <- lookup n xs = if t/=t' && t/=Placeholder && t'/=Placeholder
2375 check (_:xs) = check xs
2377 checkRpts (LeftErr x) = Left x
2379substMatches :: [(Name, PTerm)] -> PTerm -> PTerm
2380substMatches ms = substMatchesShadow ms []
2382-- substMatchesShadow :: [(Name, PTerm)] -> [Name] -> PTerm -> PTerm
2383-- substMatchesShadow [] shs t = t
2384-- substMatchesShadow ((n,tm):ns) shs t
2385-- = substMatchShadow n shs tm (substMatchesShadow ns shs t)
2387substMatch :: Name -> PTerm -> PTerm -> PTerm
2388substMatch n = substMatchShadow n []
2390substMatchShadow :: Name -> [Name] -> PTerm -> PTerm -> PTerm
2391substMatchShadow n shs tm t = substMatchesShadow [(n, tm)] shs t
2393substMatchesShadow :: [(Name, PTerm)] -> [Name] -> PTerm -> PTerm
2394substMatchesShadow nmap shs t = sm shs t where
2395 sm xs (PRef _ _ n) | Just tm <- lookup n nmap = tm
2396 sm xs (PLam fc x xfc t sc) = PLam fc x xfc (sm xs t) (sm xs sc)
2397 sm xs (PPi p x fc t sc)
2399 = let x' = nextName x in
2400 PPi p x' fc (sm (x':xs) (substMatch x (PRef emptyFC [] x') t))
2401 (sm (x':xs) (substMatch x (PRef emptyFC [] x') sc))
2402 | otherwise = PPi p x fc (sm xs t) (sm (x : xs) sc)
2403 sm xs (PLet fc x xfc val t sc)
2404 = PLet fc x xfc (sm xs val) (sm xs t) (sm xs sc)
2405 sm xs (PApp f x as) = fullApp $ PApp f (sm xs x) (map (fmap (sm xs)) as)
2406 sm xs (PCase f x as) = PCase f (sm xs x) (map (pmap (sm xs)) as)
2407 sm xs (PIfThenElse fc c t f) = PIfThenElse fc (sm xs c) (sm xs t) (sm xs f)
2408 sm xs (PRewrite f by x y tm) = PRewrite f by (sm xs x) (sm xs y)
2410 sm xs (PTyped x y) = PTyped (sm xs x) (sm xs y)
2411 sm xs (PPair f hls p x y) = PPair f hls p (sm xs x) (sm xs y)
2412 sm xs (PDPair f hls p x t y) = PDPair f hls p (sm xs x) (sm xs t) (sm xs y)
2413 sm xs (PAlternative ms a as) = PAlternative ms a (map (sm xs) as)
2414 sm xs (PHidden x) = PHidden (sm xs x)
2415 sm xs (PUnifyLog x) = PUnifyLog (sm xs x)
2416 sm xs (PNoImplicits x) = PNoImplicits (sm xs x)
2417 sm xs (PRunElab fc script ns) = PRunElab fc (sm xs script) ns
2418 sm xs (PConstSugar fc tm) = PConstSugar fc (sm xs tm)
2421 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
2424shadow :: Name -> Name -> PTerm -> PTerm
2425shadow n n' t = sm 0 t where
2426 sm 0 (PRef fc hl x) | n == x = PRef fc hl n'
2427 sm 0 (PLam fc x xfc t sc) | n /= x = PLam fc x xfc (sm 0 t) (sm 0 sc)
2428 | otherwise = PLam fc x xfc (sm 0 t) sc
2429 sm 0 (PPi p x fc t sc) | n /= x = PPi p x fc (sm 0 t) (sm 0 sc)
2430 | otherwise = PPi p x fc (sm 0 t) sc
2431 sm 0 (PLet fc x xfc t v sc) | n /= x = PLet fc x xfc (sm 0 t) (sm 0 v) (sm 0 sc)
2432 | otherwise = PLet fc x xfc (sm 0 t) (sm 0 v) sc
2433 sm 0 (PApp f x as) = PApp f (sm 0 x) (map (fmap (sm 0)) as)
2434 sm 0 (PAppBind f x as) = PAppBind f (sm 0 x) (map (fmap (sm 0)) as)
2435 sm 0 (PCase f x as) = PCase f (sm 0 x) (map (pmap (sm 0)) as)
2436 sm 0 (PIfThenElse fc c t f) = PIfThenElse fc (sm 0 c) (sm 0 t) (sm 0 f)
2437 sm 0 (PRewrite f by x y tm) = PRewrite f by (sm 0 x) (sm 0 y) (fmap (sm 0) tm)
2438 sm 0 (PTyped x y) = PTyped (sm 0 x) (sm 0 y)
2439 sm 0 (PPair f hls p x y) = PPair f hls p (sm 0 x) (sm 0 y)
2440 sm 0 (PDPair f hls p x t y) = PDPair f hls p (sm 0 x) (sm 0 t) (sm 0 y)
2441 sm 0 (PAlternative ms a as)
2442 = PAlternative (map shadowAlt ms) a (map (sm 0) as)
2443 sm 0 (PTactics ts) = PTactics (map (fmap (sm 0)) ts)
2444 sm 0 (PProof ts) = PProof (map (fmap (sm 0)) ts)
2445 sm 0 (PHidden x) = PHidden (sm 0 x)
2446 sm 0 (PUnifyLog x) = PUnifyLog (sm 0 x)
2447 sm 0 (PNoImplicits x) = PNoImplicits (sm 0 x)
2448 sm 0 (PCoerced t) = PCoerced (sm 0 t)
2449 sm ql (PQuasiquote tm ty) = PQuasiquote (sm (ql + 1) tm) (fmap (sm ql) ty)
2450 sm ql (PUnquote tm) = PUnquote (sm (ql - 1) tm)
2451 sm ql x = descend (sm ql) x
2453 shadowAlt p@(x, oldn) = (update x, update oldn)
2454 update oldn | n == oldn = n'
2457-- | Rename any binders which are repeated (so that we don't have to
2458-- mess about with shadowing anywhere else).
2459mkUniqueNames :: [Name] -> [(Name, Name)] -> PTerm -> PTerm
2460mkUniqueNames env shadows tm
2461 = evalState (mkUniq 0 initMap tm) (S.fromList env) where
2463 initMap = M.fromList shadows
2465 inScope :: S.Set Name
2466 inScope = S.fromList $ boundNamesIn tm
2468 mkUniqA ql nmap arg = do t' <- mkUniq ql nmap (getTm arg)
2469 return (arg { getTm = t' })
2471 -- Initialise the unique name with the environment length (so we're not
2472 -- looking for too long...)
2473 initN (UN n) l = UN $ txt (str n ++ show l)
2474 initN (MN i s) l = MN (i+l) s
2477 -- FIXME: Probably ought to do this for completeness! It's fine as
2478 -- long as there are no bindings inside tactics though.
2479 mkUniqT _ nmap tac = return tac
2481 mkUniq :: Int -- ^ The number of quotations that we're under
2482 -> M.Map Name Name -> PTerm -> State (S.Set Name) PTerm
2483 mkUniq 0 nmap (PLam fc n nfc ty sc)
2487 then do let n' = uniqueNameSet (initN n (S.size env))
2488 (S.union env inScope)
2489 return (n', sc) -- shadow n n' sc)
2491 put (S.insert n' env)
2492 let nmap' = M.insert n n' nmap
2493 ty' <- mkUniq 0 nmap ty
2494 sc'' <- mkUniq 0 nmap' sc'
2495 return $! PLam fc n' nfc ty' sc''
2496 mkUniq 0 nmap (PPi p n fc ty sc)
2500 then do let n' = uniqueNameSet (initN n (S.size env))
2501 (S.union env inScope)
2502 return (n', sc) -- shadow n n' sc)
2504 put (S.insert n' env)
2505 let nmap' = M.insert n n' nmap
2506 ty' <- mkUniq 0 nmap ty
2507 sc'' <- mkUniq 0 nmap' sc'
2508 return $! PPi p n' fc ty' sc''
2509 mkUniq 0 nmap (PLet fc n nfc ty val sc)
2513 then do let n' = uniqueNameSet (initN n (S.size env))
2514 (S.union env inScope)
2515 return (n', sc) -- shadow n n' sc)
2517 put (S.insert n' env)
2518 let nmap' = M.insert n n' nmap
2519 ty' <- mkUniq 0 nmap ty; val' <- mkUniq 0 nmap val
2520 sc'' <- mkUniq 0 nmap' sc'
2521 return $! PLet fc n' nfc ty' val' sc''
2522 mkUniq 0 nmap (PApp fc t args)
2523 = do t' <- mkUniq 0 nmap t
2524 args' <- mapM (mkUniqA 0 nmap) args
2525 return $! PApp fc t' args'
2526 mkUniq 0 nmap (PAppBind fc t args)
2527 = do t' <- mkUniq 0 nmap t
2528 args' <- mapM (mkUniqA 0 nmap) args
2529 return $! PAppBind fc t' args'
2530 mkUniq 0 nmap (PCase fc t alts)
2531 = do t' <- mkUniq 0 nmap t
2532 alts' <- mapM (\(x,y)-> do x' <- mkUniq 0 nmap x; y' <- mkUniq 0 nmap y
2533 return (x', y')) alts
2534 return $! PCase fc t' alts'
2535 mkUniq 0 nmap (PIfThenElse fc c t f)
2536 = liftM3 (PIfThenElse fc) (mkUniq 0 nmap c) (mkUniq 0 nmap t) (mkUniq 0 nmap f)
2537 mkUniq 0 nmap (PPair fc hls p l r)
2538 = do l' <- mkUniq 0 nmap l; r' <- mkUniq 0 nmap r
2539 return $! PPair fc hls p l' r'
2540 mkUniq 0 nmap (PDPair fc hls p (PRef fc' hls' n) t sc)
2543 (n', sc') <- if n `S.member` env
2544 then do let n' = uniqueNameSet n (S.union env inScope)
2545 return (n', sc) -- shadow n n' sc)
2547 put (S.insert n' env)
2548 let nmap' = M.insert n n' nmap
2549 t' <- mkUniq 0 nmap t
2550 sc'' <- mkUniq 0 nmap' sc'
2551 return $! PDPair fc hls p (PRef fc' hls' n') t' sc''
2552 mkUniq 0 nmap (PDPair fc hls p l t r)
2553 = do l' <- mkUniq 0 nmap l; t' <- mkUniq 0 nmap t; r' <- mkUniq 0 nmap r
2554 return $! PDPair fc hls p l' t' r'
2555 mkUniq 0 nmap (PAlternative ns b as)
2556 -- store the nmap and defer the rest until we've pruned the set
2557 -- during elaboration
2558 = return $ PAlternative (ns ++ M.toList nmap) b as
2559 mkUniq 0 nmap (PHidden t) = liftM PHidden (mkUniq 0 nmap t)
2560 mkUniq 0 nmap (PUnifyLog t) = liftM PUnifyLog (mkUniq 0 nmap t)
2561 mkUniq 0 nmap (PDisamb n t) = liftM (PDisamb n) (mkUniq 0 nmap t)
2562 mkUniq 0 nmap (PNoImplicits t) = liftM PNoImplicits (mkUniq 0 nmap t)
2563 mkUniq 0 nmap (PProof ts) = liftM PProof (mapM (mkUniqT 0 nmap) ts)
2564 mkUniq 0 nmap (PTactics ts) = liftM PTactics (mapM (mkUniqT 0 nmap) ts)
2565 mkUniq 0 nmap (PRunElab fc ts ns) = liftM (\tm -> PRunElab fc tm ns) (mkUniq 0 nmap ts)
2566 mkUniq 0 nmap (PConstSugar fc tm) = liftM (PConstSugar fc) (mkUniq 0 nmap tm)
2567 mkUniq 0 nmap (PCoerced tm) = liftM PCoerced (mkUniq 0 nmap tm)
2568 mkUniq 0 nmap t = return $ shadowAll (M.toList nmap) t
2571 shadowAll ((n, n') : ns) t = shadow n n' (shadowAll ns t)
2573 mkUniq ql nmap (PQuasiquote tm ty) =
2574 do tm' <- mkUniq (ql + 1) nmap tm
2576 Nothing -> return Nothing
2577 Just t -> fmap Just $ mkUniq ql nmap t
2578 return $! PQuasiquote tm' ty'
2579 mkUniq ql nmap (PUnquote tm) = fmap PUnquote (mkUniq (ql - 1) nmap tm)
2581 mkUniq ql nmap tm = descendM (mkUniq ql nmap) tm
2583getFile :: Opt -> Maybe String
2584getFile (Filename s) = Just s
2587getBC :: Opt -> Maybe String
2588getBC (BCAsm s) = Just s
2591getOutput :: Opt -> Maybe String
2592getOutput (Output s) = Just s
2593getOutput _ = Nothing
2595getIBCSubDir :: Opt -> Maybe String
2596getIBCSubDir (IBCSubDir s) = Just s
2597getIBCSubDir _ = Nothing
2599getImportDir :: Opt -> Maybe String
2600getImportDir (ImportDir s) = Just s
2601getImportDir _ = Nothing
2603getSourceDir :: Opt -> Maybe String
2604getSourceDir (SourceDir s) = Just s
2605getSourceDir _ = Nothing
2607getPkgDir :: Opt -> Maybe String
2608getPkgDir (Pkg s) = Just s
2609getPkgDir _ = Nothing
2611getPkg :: Opt -> Maybe (Bool, String)
2612getPkg (PkgBuild s) = Just (False, s)
2613getPkg (PkgInstall s) = Just (True, s)
2616getPkgClean :: Opt -> Maybe String
2617getPkgClean (PkgClean s) = Just s
2618getPkgClean _ = Nothing
2620getPkgREPL :: Opt -> Maybe String
2621getPkgREPL (PkgREPL s) = Just s
2622getPkgREPL _ = Nothing
2624getPkgCheck :: Opt -> Maybe String
2625getPkgCheck (PkgCheck s) = Just s
2626getPkgCheck _ = Nothing
2628-- | Returns None if given an Opt which is not PkgMkDoc
2629-- Otherwise returns Just x, where x is the contents of PkgMkDoc
2630getPkgMkDoc :: Opt -- ^ Opt to extract
2631 -> Maybe (Bool, String) -- ^ Result
2632getPkgMkDoc (PkgDocBuild str) = Just (False,str)
2633getPkgMkDoc (PkgDocInstall str) = Just (True,str)
2634getPkgMkDoc _ = Nothing
2636getPkgTest :: Opt -- ^ the option to extract
2637 -> Maybe String -- ^ the package file to test
2638getPkgTest (PkgTest f) = Just f
2639getPkgTest _ = Nothing
2641getCodegen :: Opt -> Maybe Codegen
2642getCodegen (UseCodegen x) = Just x
2643getCodegen _ = Nothing
2645getCodegenArgs :: Opt -> Maybe String
2646getCodegenArgs (CodegenArgs args) = Just args
2647getCodegenArgs _ = Nothing
2649getConsoleWidth :: Opt -> Maybe ConsoleWidth
2650getConsoleWidth (UseConsoleWidth x) = Just x
2651getConsoleWidth _ = Nothing
2653getExecScript :: Opt -> Maybe String
2654getExecScript (InterpretScript expr) = Just expr
2655getExecScript _ = Nothing
2657getPkgIndex :: Opt -> Maybe FilePath
2658getPkgIndex (PkgIndex file) = Just file
2659getPkgIndex _ = Nothing
2661getEvalExpr :: Opt -> Maybe String
2662getEvalExpr (EvalExpr expr) = Just expr
2663getEvalExpr _ = Nothing
2665getOutputTy :: Opt -> Maybe OutputType
2666getOutputTy (OutputTy t) = Just t
2667getOutputTy _ = Nothing
2669getLanguageExt :: Opt -> Maybe LanguageExt
2670getLanguageExt (Extension e) = Just e
2671getLanguageExt _ = Nothing
2673getTriple :: Opt -> Maybe String
2674getTriple (TargetTriple x) = Just x
2675getTriple _ = Nothing
2677getCPU :: Opt -> Maybe String
2678getCPU (TargetCPU x) = Just x
2681getOptLevel :: Opt -> Maybe Int
2682getOptLevel (OptLevel x) = Just x
2683getOptLevel _ = Nothing
2685getOptimisation :: Opt -> Maybe (Bool,Optimisation)
2686getOptimisation (AddOpt p) = Just (True, p)
2687getOptimisation (RemoveOpt p) = Just (False, p)
2688getOptimisation _ = Nothing
2690getColour :: Opt -> Maybe Bool
2691getColour (ColourREPL b) = Just b
2692getColour _ = Nothing
2694getClient :: Opt -> Maybe String
2695getClient (Client x) = Just x
2696getClient _ = Nothing
2698-- Get the first valid port
2699getPort :: [Opt] -> Maybe REPLPort
2701getPort (Port p : _ ) = Just p
2702getPort (_ : xs) = getPort xs
2704opt :: (Opt -> Maybe a) -> [Opt] -> [a]
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