1{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, DeriveFunctor,
2 TypeSynonymInstances, PatternGuards #-}
4module Idris.AbsSyntax(module Idris.AbsSyntax, module Idris.AbsSyntaxTree) where
7import Idris.Core.Evaluate
8import Idris.Core.Elaborate hiding (Tactic(..))
9import Idris.Core.Typecheck
10import Idris.AbsSyntaxTree
12import Idris.Docstrings
14import IRTS.CodegenCommon
15import Util.DynamicLinker
19import System.Console.Haskeline
22import Control.Monad.State
23import Control.Monad.Error(throwError)
27import qualified Data.Text as T
29import qualified Data.Map as M
31import qualified Data.Set as S
32import Data.Word (Word)
36import Control.Monad.Error (throwError, catchError)
37import System.IO.Error(isUserError, ioeGetErrorString, tryIOError)
43getContext :: Idris Context
44getContext = do i <- getIState; return (tt_ctxt i)
46forCodegen :: Codegen -> [(Codegen, a)] -> [a]
47forCodegen tgt xs = [x | (tgt', x) <- xs, tgt == tgt']
49getObjectFiles :: Codegen -> Idris [FilePath]
50getObjectFiles tgt = do i <- getIState; return (forCodegen tgt $ idris_objs i)
52addObjectFile :: Codegen -> FilePath -> Idris ()
53addObjectFile tgt f = do i <- getIState; putIState $ i { idris_objs = nub $ (tgt, f) : idris_objs i }
55getLibs :: Codegen -> Idris [String]
56getLibs tgt = do i <- getIState; return (forCodegen tgt $ idris_libs i)
58addLib :: Codegen -> String -> Idris ()
59addLib tgt f = do i <- getIState; putIState $ i { idris_libs = nub $ (tgt, f) : idris_libs i }
61getFlags :: Codegen -> Idris [String]
62getFlags tgt = do i <- getIState; return (forCodegen tgt $ idris_cgflags i)
64addFlag :: Codegen -> String -> Idris ()
65addFlag tgt f = do i <- getIState; putIState $ i { idris_cgflags = nub $ (tgt, f) : idris_cgflags i }
67addDyLib :: [String] -> Idris (Either DynamicLib String)
68addDyLib libs = do i <- getIState
69 let ls = idris_dynamic_libs i
70 let importdirs = opt_importdirs (idris_options i)
71 case mapMaybe (findDyLib ls) libs of
72 x:_ -> return (Left x)
74 handle <- lift . lift .
75 mapM (\l -> catchIO (tryLoadLib importdirs l)
76 (\_ -> return Nothing)) $ libs
78 Nothing -> return (Right $ "Could not load dynamic alternatives \"" ++
79 concat (intersperse "," libs) ++ "\"")
80 Just x -> do putIState $ i { idris_dynamic_libs = x:ls }
82 where findDyLib :: [DynamicLib] -> String -> Maybe DynamicLib
83 findDyLib [] l = Nothing
84 findDyLib (lib:libs) l | l == lib_name lib = Just lib
85 | otherwise = findDyLib libs l
88addHdr :: Codegen -> String -> Idris ()
89addHdr tgt f = do i <- getIState; putIState $ i { idris_hdrs = nub $ (tgt, f) : idris_hdrs i }
91addLangExt :: LanguageExt -> Idris ()
92addLangExt TypeProviders = do i <- getIState
94 idris_language_extensions = TypeProviders : idris_language_extensions i
96addLangExt ErrorReflection = do i <- getIState
98 idris_language_extensions = ErrorReflection : idris_language_extensions i
101addTrans :: (Term, Term) -> Idris ()
102addTrans t = do i <- getIState
103 putIState $ i { idris_transforms = t : idris_transforms i }
105addErrRev :: (Term, Term) -> Idris ()
106addErrRev t = do i <- getIState
107 putIState $ i { idris_errRev = t : idris_errRev i }
109totcheck :: (FC, Name) -> Idris ()
110totcheck n = do i <- getIState; putIState $ i { idris_totcheck = idris_totcheck i ++ [n] }
112defer_totcheck :: (FC, Name) -> Idris ()
115 putIState $ i { idris_defertotcheck = nub (idris_defertotcheck i ++ [n]) }
117clear_totcheck :: Idris ()
118clear_totcheck = do i <- getIState; putIState $ i { idris_totcheck = [] }
120setFlags :: Name -> [FnOpt] -> Idris ()
121setFlags n fs = do i <- getIState; putIState $ i { idris_flags = addDef n fs (idris_flags i) }
123setAccessibility :: Name -> Accessibility -> Idris ()
126 let ctxt = setAccess n a (tt_ctxt i)
127 putIState $ i { tt_ctxt = ctxt }
129setTotality :: Name -> Totality -> Idris ()
132 let ctxt = setTotal n a (tt_ctxt i)
133 putIState $ i { tt_ctxt = ctxt }
135getTotality :: Name -> Idris Totality
138 case lookupTotal n (tt_ctxt i) of
140 _ -> return (Total [])
142-- Get coercions which might return the required type
143getCoercionsTo :: IState -> Type -> [Name]
145 let cs = idris_coercions i
146 (fn,_) = unApply (getRetTy ty) in
148 where findCoercions t [] = []
149 findCoercions t (n : ns) =
150 let ps = case lookupTy n (tt_ctxt i) of
151 [ty'] -> case unApply (getRetTy ty') of
153 if t == t' then [n] else []
155 ps ++ findCoercions t ns
157addToCG :: Name -> CGInfo -> Idris ()
160 putIState $ i { idris_callgraph = addDef n cg (idris_callgraph i) }
162addTyInferred :: Name -> Idris ()
165 putIState $ i { idris_tyinfodata =
166 addDef n TIPartial (idris_tyinfodata i) }
168addTyInfConstraints :: FC -> [(Term, Term)] -> Idris ()
169addTyInfConstraints fc ts = do logLvl 2 $ "TI missing: " ++ show ts
170 mapM_ addConstraint ts
172 where addConstraint (x, y) = findMVApps x y
175 = do let (fx, argsx) = unApply x
176 let (fy, argsy) = unApply y
181 else mapM_ addConstraint (zip argsx argsy)
183 tryAddMV (P _ mv _) y =
185 case lookup mv (idris_metavars ist) of
186 Just _ -> addConstraintRule mv y
188 tryAddMV _ _ = return ()
190 addConstraintRule :: Name -> Term -> Idris ()
191 addConstraintRule n t
193 logLvl 1 $ "TI constraint: " ++ show (n, t)
194 case lookupCtxt n (idris_tyinfodata ist) of
196 do mapM_ (checkConsistent t) ts
197 let ti' = addDef n (TISolution (t : ts))
198 (idris_tyinfodata ist)
199 put $ ist { idris_tyinfodata = ti' }
201 do let ti' = addDef n (TISolution [t])
202 (idris_tyinfodata ist)
203 put $ ist { idris_tyinfodata = ti' }
205 -- Check a solution is consistent with previous solutions
206 -- Meaning: If heads are both data types, they had better be the
208 checkConsistent :: Term -> Term -> Idris ()
209 checkConsistent x y =
210 do let (fx, _) = unApply x
211 let (fy, _) = unApply y
213 (P (TCon _ _) n _, P (TCon _ _) n' _) -> errWhen (n/=n)
214 (P (TCon _ _) n _, Constant _) -> errWhen True
215 (Constant _, P (TCon _ _) n' _) -> errWhen True
216 (P (DCon _ _) n _, P (DCon _ _) n' _) -> errWhen (n/=n)
221 (CantUnify False x y (Msg "") [] 0))
222 errWhen False = return ()
224isTyInferred :: Name -> Idris Bool
227 case lookupCtxt n (idris_tyinfodata i) of
228 [TIPartial] -> return True
231-- | Adds error handlers for a particular function and argument. If names are
232-- ambiguous, all matching handlers are updated.
233addFunctionErrorHandlers :: Name -> Name -> [Name] -> Idris ()
234addFunctionErrorHandlers f arg hs =
236 let oldHandlers = idris_function_errorhandlers i
237 let newHandlers = flip (addDef f) oldHandlers $
238 case lookupCtxtExact f oldHandlers of
239 Nothing -> M.singleton arg (S.fromList hs)
240 Just (oldHandlers) -> M.insertWith S.union arg (S.fromList hs) oldHandlers
241 -- will always be one of those two, thus no extra case
242 putIState $ i { idris_function_errorhandlers = newHandlers }
244getFunctionErrorHandlers :: Name -> Name -> Idris [Name]
245getFunctionErrorHandlers f arg = do i <- getIState
246 return . maybe [] S.toList $
247 undefined --lookup arg =<< lookupCtxtExact f (idris_function_errorhandlers i)
250-- Trace all the names in a call graph starting at the given name
251getAllNames :: Name -> Idris [Name]
252getAllNames n = allNames [] n
254allNames :: [Name] -> Name -> Idris [Name]
255allNames ns n | n `elem` ns = return []
256allNames ns n = do i <- getIState
257 case lookupCtxtExact n (idris_callgraph i) of
258 Just ns' -> do more <- mapM (allNames (n:ns)) (map fst (calls ns'))
259 return (nub (n : concat more))
262addCoercion :: Name -> Idris ()
263addCoercion n = do i <- getIState
264 putIState $ i { idris_coercions = nub $ n : idris_coercions i }
266addDocStr :: Name -> Docstring -> [(Name, Docstring)] -> Idris ()
269 putIState $ i { idris_docstrings = addDef n (doc, args) (idris_docstrings i) }
271addNameHint :: Name -> Name -> Idris ()
274 ty' <- case lookupCtxtName ty (idris_implicits i) of
275 [(tyn, _)] -> return tyn
276 [] -> throwError (NoSuchVariable ty)
277 tyns -> throwError (CantResolveAlts (map show (map fst tyns)))
278 let ns' = case lookupCtxt ty' (idris_namehints i) of
281 putIState $ i { idris_namehints = addDef ty' ns' (idris_namehints i) }
283getNameHints :: IState -> Name -> [Name]
284getNameHints i (UN arr) | arr == txt "->" = [sUN "f",sUN "g"]
286 case lookupCtxt n (idris_namehints i) of
290addToCalledG :: Name -> [Name] -> Idris ()
291addToCalledG n ns = return () -- TODO
293-- Add a class instance function. Dodgy hack: Put integer instances first in the
294-- list so they are resolved by default.
295-- Dodgy hack 2: put constraint chasers (@@) last
297addInstance :: Bool -> Name -> Name -> Idris ()
299 = do ist <- getIState
300 case lookupCtxt n (idris_classes ist) of
301 [CI a b c d e ins] ->
302 do let cs = addDef n (CI a b c d e (addI i ins)) (idris_classes ist)
303 putIState $ ist { idris_classes = cs }
304 _ -> do let cs = addDef n (CI (sMN 0 "none") [] [] [] [] [i]) (idris_classes ist)
305 putIState $ ist { idris_classes = cs }
306 where addI i ins | int = i : ins
307 | chaser n = ins ++ [i]
308 | otherwise = insI i ins
310 insI i (n : ns) | chaser n = i : n : ns
311 | otherwise = n : insI i ns
314 | ('@':'@':_) <- str nm = True
315 chaser (NS n _) = chaser n
318addClass :: Name -> ClassInfo -> Idris ()
320 = do ist <- getIState
321 let i' = case lookupCtxt n (idris_classes ist) of
322 [c] -> c { class_instances = class_instances i }
324 putIState $ ist { idris_classes = addDef n i' (idris_classes ist) }
326addIBC :: IBCWrite -> Idris ()
329 when (notDef (ibc_write i)) $
330 putIState $ i { ibc_write = ibc : ibc_write i }
331 where notDef [] = True
332 notDef (IBCDef n': is) | n == n' = False
333 notDef (_ : is) = notDef is
334addIBC ibc = do i <- getIState; putIState $ i { ibc_write = ibc : ibc_write i }
337clearIBC = do i <- getIState; putIState $ i { ibc_write = [] }
339resetNameIdx :: Idris ()
340resetNameIdx = do i <- getIState
341 put (i { idris_nameIdx = (0, emptyContext) })
343-- Used to preserve sharing of names
344addNameIdx :: Name -> Idris (Int, Name)
345addNameIdx n = do i <- getIState
346 let (i', x) = addNameIdx' i n
349addNameIdx' :: IState -> Name -> (IState, (Int, Name))
351 = let idxs = snd (idris_nameIdx i) in
352 case lookupCtxt n idxs of
354 _ -> let i' = fst (idris_nameIdx i) + 1 in
355 (i { idris_nameIdx = (i', addDef n (i', n) idxs) }, (i', n))
357getHdrs :: Codegen -> Idris [String]
358getHdrs tgt = do i <- getIState; return (forCodegen tgt $ idris_hdrs i)
360setErrSpan :: FC -> Idris ()
361setErrSpan x = do i <- getIState;
363 Nothing -> putIState $ i { errSpan = Just x }
367clearErr = do i <- getIState
368 putIState $ i { errSpan = Nothing }
370getSO :: Idris (Maybe String)
371getSO = do i <- getIState
372 return (compiled_so i)
374setSO :: Maybe String -> Idris ()
375setSO s = do i <- getIState
376 putIState $ (i { compiled_so = s })
378getIState :: Idris IState
381putIState :: IState -> Idris ()
384-- | A version of liftIO that puts errors into the exception type of the Idris monad
385runIO :: IO a -> Idris a
386runIO x = liftIO (tryIOError x) >>= either (throwError . Msg . show) return
387-- TODO: create specific Idris exceptions for specific IO errors such as "openFile: does not exist"
390getName = do i <- getIState;
391 let idx = idris_name i;
392 putIState $ (i { idris_name = idx + 1 })
395-- InternalApp keeps track of the real function application for making case splits from, not the application the
396-- programmer wrote, which doesn't have the whole context in any case other than top level definitions
397addInternalApp :: FilePath -> Int -> PTerm -> Idris ()
400 putIState (i { idris_lineapps = ((fp, l), t) : idris_lineapps i })
402getInternalApp :: FilePath -> Int -> Idris PTerm
403getInternalApp fp l = do i <- getIState
404 case lookup (fp, l) (idris_lineapps i) of
406 Nothing -> return Placeholder
407 -- TODO: What if it's not there?
409-- Pattern definitions are only used for coverage checking, so erase them
411clearOrigPats :: Idris ()
412clearOrigPats = do i <- get
413 let ps = idris_patdefs i
414 let ps' = mapCtxt (\ (_,miss) -> ([], miss)) ps
415 put (i { idris_patdefs = ps' })
417-- Erase types from Ps in the context (basically ending up with what's in
418-- the .ibc, which is all we need after all the analysis is done)
419clearPTypes :: Idris ()
420clearPTypes = do i <- get
422 put (i { tt_ctxt = mapDefCtxt pErase ctxt })
423 where pErase (CaseOp c t tys orig tot cds)
424 = CaseOp c t tys orig [] (pErase' cds)
426 pErase' (CaseDefs _ (cs, c) _ rs)
427 = let c' = (cs, fmap pEraseType c) in
430checkUndefined :: FC -> Name -> Idris ()
434 (_:_) -> throwError . Msg $ show fc ++ ":" ++
435 show n ++ " already defined"
438isUndefined :: FC -> Name -> Idris Bool
442 (_:_) -> return False
445setContext :: Context -> Idris ()
446setContext ctxt = do i <- getIState; putIState $ (i { tt_ctxt = ctxt } )
448updateContext :: (Context -> Context) -> Idris ()
449updateContext f = do i <- getIState; putIState $ (i { tt_ctxt = f (tt_ctxt i) } )
451addConstraints :: FC -> (Int, [UConstraint]) -> Idris ()
452addConstraints fc (v, cs)
455 let ctxt' = ctxt { uconstraints = cs ++ uconstraints ctxt,
457 let ics = zip cs (repeat fc) ++ idris_constraints i
458 putIState $ i { tt_ctxt = ctxt', idris_constraints = ics }
460addDeferred = addDeferred' Ref
461addDeferredTyCon = addDeferred' (TCon 0 0)
463addDeferred' :: NameType -> [(Name, (Int, Maybe Name, Type, Bool))] -> Idris ()
465 = do mapM_ (\(n, (i, _, t, _)) -> updateContext (addTyDecl n nt (tidyNames [] t))) ns
466 mapM_ (\(n, _) -> when (not (n `elem` primDefs)) $ addIBC (IBCMetavar n)) ns
468 putIState $ i { idris_metavars = map (\(n, (i, top, _, isTopLevel)) -> (n, (top, i, isTopLevel))) ns ++
470 where tidyNames used (Bind (MN i x) b sc)
471 = let n' = uniqueName (UN x) used in
472 Bind n' b $ tidyNames (n':used) sc
473 tidyNames used (Bind n b sc)
474 = let n' = uniqueName n used in
475 Bind n' b $ tidyNames (n':used) sc
478solveDeferred :: Name -> Idris ()
479solveDeferred n = do i <- getIState
480 putIState $ i { idris_metavars =
481 filter (\(n', _) -> n/=n')
484 filter (notMV n) (ibc_write i)
486 where notMV n (IBCMetavar n') = not (n == n')
489getUndefined :: Idris [Name]
490getUndefined = do i <- getIState
491 return (map fst (idris_metavars i) \\ primDefs)
493getWidth :: Idris ConsoleWidth
494getWidth = fmap idris_consolewidth getIState
496setWidth :: ConsoleWidth -> Idris ()
497setWidth w = do ist <- getIState
498 put ist { idris_consolewidth = w }
500renderWidth :: Idris Int
501renderWidth = do iw <- getWidth
503 InfinitelyWide -> return 100000000
504 ColsWide n -> return (max n 1)
505 AutomaticWidth -> runIO getScreenWidth
508iRender :: Doc a -> Idris (SimpleDoc a)
509iRender d = do w <- getWidth
511 let ideSlave = case idris_outputmode ist of
515 InfinitelyWide -> return $ renderPretty 1.0 1000000000 d
516 ColsWide n -> return $
518 then renderPretty 1.0 1000000000 d
519 else renderPretty 0.8 n d
520 AutomaticWidth | ideSlave -> return $ renderPretty 1.0 1000000000 d
521 | otherwise -> do width <- runIO getScreenWidth
522 return $ renderPretty 0.8 width d
524ihPrintResult :: Handle -> String -> Idris ()
525ihPrintResult h s = do i <- getIState
526 case idris_outputmode i of
527 RawOutput -> case s of
529 s -> runIO $ hPutStrLn h s
531 let good = SexpList [SymbolAtom "ok", toSExp s] in
532 runIO $ hPutStrLn h $ convSExp "return" good n
534-- | Write a pretty-printed term to the console with semantic coloring
535consoleDisplayAnnotated :: Handle -> Doc OutputAnnotation -> Idris ()
536consoleDisplayAnnotated h output = do ist <- getIState
537 rendered <- iRender $ output
538 runIO . hPutStrLn h .
539 displayDecorated (consoleDecorate ist) $
543-- | Write pretty-printed output to IDESlave with semantic annotations
544ideSlaveReturnAnnotated :: Integer -> Handle -> Doc OutputAnnotation -> Idris ()
545ideSlaveReturnAnnotated n h out = do ist <- getIState
546 (str, spans) <- fmap displaySpans .
548 fmap (fancifyAnnots ist) $
550 let good = [SymbolAtom "ok", toSExp str, toSExp spans]
551 runIO . hPutStrLn h $ convSExp "return" good n
553ihPrintTermWithType :: Handle -> Doc OutputAnnotation -> Doc OutputAnnotation -> Idris ()
554ihPrintTermWithType h tm ty = do ist <- getIState
555 let output = tm <+> colon <+> ty
556 case idris_outputmode ist of
557 RawOutput -> consoleDisplayAnnotated h output
558 IdeSlave n -> ideSlaveReturnAnnotated n h output
560-- | Pretty-print a collection of overloadings to REPL or IDESlave - corresponds to :t name
561ihPrintFunTypes :: Handle -> [(Name, Bool)] -> Name -> [(Name, PTerm)] -> Idris ()
562ihPrintFunTypes h bnd n [] = ihPrintError h $ "No such variable " ++ show n
563ihPrintFunTypes h bnd n overloads = do imp <- impShow
565 let output = vsep (map (uncurry (ppOverload imp)) overloads)
566 case idris_outputmode ist of
567 RawOutput -> consoleDisplayAnnotated h output
568 IdeSlave n -> ideSlaveReturnAnnotated n h output
569 where fullName n = prettyName True bnd n
570 ppOverload imp n tm = fullName n <+> colon <+> align (pprintPTerm imp bnd tm)
572ihRenderResult :: Handle -> Doc OutputAnnotation -> Idris ()
573ihRenderResult h d = do ist <- getIState
574 case idris_outputmode ist of
575 RawOutput -> consoleDisplayAnnotated h d
576 IdeSlave n -> ideSlaveReturnAnnotated n h d
578fancifyAnnots :: IState -> OutputAnnotation -> OutputAnnotation
579fancifyAnnots ist annot@(AnnName n _ _) =
580 do let ctxt = tt_ctxt ist
582 _ | isDConName n ctxt -> AnnName n (Just DataOutput) Nothing
583 _ | isFnName n ctxt -> AnnName n (Just FunOutput) Nothing
584 _ | isTConName n ctxt -> AnnName n (Just TypeOutput) Nothing
585 _ | otherwise -> annot
586fancifyAnnots _ annot = annot
588type1Doc :: Doc OutputAnnotation
589type1Doc = (annotate AnnConstType $ text "Type 1")
591-- | Show an error with semantic highlighting
592ihRenderError :: Handle -> Doc OutputAnnotation -> Idris ()
593ihRenderError h e = do ist <- getIState
594 case idris_outputmode ist of
595 RawOutput -> consoleDisplayAnnotated h e
597 (str, spans) <- fmap displaySpans .
599 fmap (fancifyAnnots ist) $
601 let good = [SymbolAtom "error", toSExp str, toSExp spans]
602 runIO . hPutStrLn h $ convSExp "return" good n
604ihPrintError :: Handle -> String -> Idris ()
605ihPrintError h s = do i <- getIState
606 case idris_outputmode i of
607 RawOutput -> case s of
609 s -> runIO $ hPutStrLn h s
611 let good = SexpList [SymbolAtom "error", toSExp s] in
612 runIO . hPutStrLn h $ convSExp "return" good n
614ihputStrLn :: Handle -> String -> Idris ()
615ihputStrLn h s = do i <- getIState
616 case idris_outputmode i of
617 RawOutput -> runIO $ hPutStrLn h s
618 IdeSlave n -> runIO . hPutStrLn h $ convSExp "write-string" s n
620iputStrLn = ihputStrLn stdout
621iPrintError = ihPrintError stdout
622iPrintResult = ihPrintResult stdout
625ideslavePutSExp :: SExpable a => String -> a -> Idris ()
626ideslavePutSExp cmd info = do i <- getIState
627 case idris_outputmode i of
628 IdeSlave n -> runIO . putStrLn $ convSExp cmd info n
631-- this needs some typing magic and more structured output towards emacs
632iputGoal :: SimpleDoc OutputAnnotation -> Idris ()
633iputGoal g = do i <- getIState
634 case idris_outputmode i of
635 RawOutput -> runIO $ putStrLn (displayDecorated (consoleDecorate i) g)
636 IdeSlave n -> runIO . putStrLn $
637 convSExp "write-goal" (displayS (fmap (fancifyAnnots i) g) "") n
639isetPrompt :: String -> Idris ()
640isetPrompt p = do i <- getIState
641 case idris_outputmode i of
642 IdeSlave n -> runIO . putStrLn $ convSExp "set-prompt" p n
644ihWarn :: Handle -> FC -> Doc OutputAnnotation -> Idris ()
645ihWarn h fc err = do i <- getIState
646 err' <- iRender . fmap (fancifyAnnots i) $ err
647 case idris_outputmode i of
650 hPutStrLn h (show fc ++ ":" ++ displayDecorated (consoleDecorate i) err')
652 do let (str, spans) = displaySpans err'
653 runIO . hPutStrLn h $
654 convSExp "warning" (fc_fname fc, fc_start fc, fc_end fc, str, spans) n
656setLogLevel :: Int -> Idris ()
657setLogLevel l = do i <- getIState
658 let opts = idris_options i
659 let opt' = opts { opt_logLevel = l }
660 putIState $ i { idris_options = opt' }
662setCmdLine :: [Opt] -> Idris ()
663setCmdLine opts = do i <- getIState
664 let iopts = idris_options i
665 putIState $ i { idris_options = iopts { opt_cmdline = opts } }
667getCmdLine :: Idris [Opt]
668getCmdLine = do i <- getIState
669 return (opt_cmdline (idris_options i))
671getDumpDefun :: Idris (Maybe FilePath)
672getDumpDefun = do i <- getIState
673 return $ findC (opt_cmdline (idris_options i))
674 where findC [] = Nothing
675 findC (DumpDefun x : _) = Just x
676 findC (_ : xs) = findC xs
678getDumpCases :: Idris (Maybe FilePath)
679getDumpCases = do i <- getIState
680 return $ findC (opt_cmdline (idris_options i))
681 where findC [] = Nothing
682 findC (DumpCases x : _) = Just x
683 findC (_ : xs) = findC xs
686logLevel = do i <- getIState
687 return (opt_logLevel (idris_options i))
689setErrContext :: Bool -> Idris ()
690setErrContext t = do i <- getIState
691 let opts = idris_options i
692 let opt' = opts { opt_errContext = t }
693 putIState $ i { idris_options = opt' }
695errContext :: Idris Bool
696errContext = do i <- getIState
697 return (opt_errContext (idris_options i))
700useREPL = do i <- getIState
701 return (opt_repl (idris_options i))
703setREPL :: Bool -> Idris ()
704setREPL t = do i <- getIState
705 let opts = idris_options i
706 let opt' = opts { opt_repl = t }
707 putIState $ i { idris_options = opt' }
709showOrigErr :: Idris Bool
710showOrigErr = do i <- getIState
711 return (opt_origerr (idris_options i))
713setShowOrigErr :: Bool -> Idris ()
714setShowOrigErr b = do i <- getIState
715 let opts = idris_options i
716 let opt' = opts { opt_origerr = b }
717 putIState $ i { idris_options = opt' }
719setAutoSolve :: Bool -> Idris ()
720setAutoSolve b = do i <- getIState
721 let opts = idris_options i
722 let opt' = opts { opt_autoSolve = b }
723 putIState $ i { idris_options = opt' }
725setNoBanner :: Bool -> Idris ()
726setNoBanner n = do i <- getIState
727 let opts = idris_options i
728 let opt' = opts { opt_nobanner = n }
729 putIState $ i { idris_options = opt' }
731getNoBanner :: Idris Bool
732getNoBanner = do i <- getIState
733 let opts = idris_options i
734 return (opt_nobanner opts)
736setQuiet :: Bool -> Idris ()
737setQuiet q = do i <- getIState
738 let opts = idris_options i
739 let opt' = opts { opt_quiet = q }
740 putIState $ i { idris_options = opt' }
742getQuiet :: Idris Bool
743getQuiet = do i <- getIState
744 let opts = idris_options i
745 return (opt_quiet opts)
747setCodegen :: Codegen -> Idris ()
748setCodegen t = do i <- getIState
749 let opts = idris_options i
750 let opt' = opts { opt_codegen = t }
751 putIState $ i { idris_options = opt' }
753codegen :: Idris Codegen
754codegen = do i <- getIState
755 return (opt_codegen (idris_options i))
757setOutputTy :: OutputType -> Idris ()
758setOutputTy t = do i <- getIState
759 let opts = idris_options i
760 let opt' = opts { opt_outputTy = t }
761 putIState $ i { idris_options = opt' }
763outputTy :: Idris OutputType
764outputTy = do i <- getIState
765 return $ opt_outputTy $ idris_options i
767setIdeSlave :: Bool -> Idris ()
768setIdeSlave True = do i <- getIState
769 putIState $ i { idris_outputmode = (IdeSlave 0), idris_colourRepl = False }
770setIdeSlave False = return ()
772setTargetTriple :: String -> Idris ()
773setTargetTriple t = do i <- getIState
774 let opts = idris_options i
775 opt' = opts { opt_triple = t }
776 putIState $ i { idris_options = opt' }
778targetTriple :: Idris String
779targetTriple = do i <- getIState
780 return (opt_triple (idris_options i))
782setTargetCPU :: String -> Idris ()
783setTargetCPU t = do i <- getIState
784 let opts = idris_options i
785 opt' = opts { opt_cpu = t }
786 putIState $ i { idris_options = opt' }
788targetCPU :: Idris String
789targetCPU = do i <- getIState
790 return (opt_cpu (idris_options i))
792setOptLevel :: Word -> Idris ()
793setOptLevel t = do i <- getIState
794 let opts = idris_options i
795 opt' = opts { opt_optLevel = t }
796 putIState $ i { idris_options = opt' }
798optLevel :: Idris Word
799optLevel = do i <- getIState
800 return (opt_optLevel (idris_options i))
803verbose = do i <- getIState
804 return (opt_verbose (idris_options i))
806setVerbose :: Bool -> Idris ()
807setVerbose t = do i <- getIState
808 let opts = idris_options i
809 let opt' = opts { opt_verbose = t }
810 putIState $ i { idris_options = opt' }
812typeInType :: Idris Bool
813typeInType = do i <- getIState
814 return (opt_typeintype (idris_options i))
816setTypeInType :: Bool -> Idris ()
817setTypeInType t = do i <- getIState
818 let opts = idris_options i
819 let opt' = opts { opt_typeintype = t }
820 putIState $ i { idris_options = opt' }
822coverage :: Idris Bool
823coverage = do i <- getIState
824 return (opt_coverage (idris_options i))
826setCoverage :: Bool -> Idris ()
827setCoverage t = do i <- getIState
828 let opts = idris_options i
829 let opt' = opts { opt_coverage = t }
830 putIState $ i { idris_options = opt' }
832setIBCSubDir :: FilePath -> Idris ()
833setIBCSubDir fp = do i <- getIState
834 let opts = idris_options i
835 let opt' = opts { opt_ibcsubdir = fp }
836 putIState $ i { idris_options = opt' }
838valIBCSubDir :: IState -> Idris FilePath
839valIBCSubDir i = return (opt_ibcsubdir (idris_options i))
841addImportDir :: FilePath -> Idris ()
842addImportDir fp = do i <- getIState
843 let opts = idris_options i
844 let opt' = opts { opt_importdirs = fp : opt_importdirs opts }
845 putIState $ i { idris_options = opt' }
847setImportDirs :: [FilePath] -> Idris ()
848setImportDirs fps = do i <- getIState
849 let opts = idris_options i
850 let opt' = opts { opt_importdirs = fps }
851 putIState $ i { idris_options = opt' }
853allImportDirs :: Idris [FilePath]
854allImportDirs = do i <- getIState
855 let optdirs = opt_importdirs (idris_options i)
856 return ("." : reverse optdirs)
858colourise :: Idris Bool
859colourise = do i <- getIState
860 return $ idris_colourRepl i
862setColourise :: Bool -> Idris ()
863setColourise b = do i <- getIState
864 putIState $ i { idris_colourRepl = b }
866setOutH :: Handle -> Idris ()
867setOutH h = do i <- getIState
868 putIState $ i { idris_outh = h }
871impShow = do i <- getIState
872 return (opt_showimp (idris_options i))
874setImpShow :: Bool -> Idris ()
875setImpShow t = do i <- getIState
876 let opts = idris_options i
877 let opt' = opts { opt_showimp = t }
878 putIState $ i { idris_options = opt' }
880setColour :: ColourType -> IdrisColour -> Idris ()
881setColour ct c = do i <- getIState
882 let newTheme = setColour' ct c (idris_colourTheme i)
883 putIState $ i { idris_colourTheme = newTheme }
884 where setColour' KeywordColour c t = t { keywordColour = c }
885 setColour' BoundVarColour c t = t { boundVarColour = c }
886 setColour' ImplicitColour c t = t { implicitColour = c }
887 setColour' FunctionColour c t = t { functionColour = c }
888 setColour' TypeColour c t = t { typeColour = c }
889 setColour' DataColour c t = t { dataColour = c }
890 setColour' PromptColour c t = t { promptColour = c }
892logLvl :: Int -> String -> Idris ()
893logLvl l str = do i <- getIState
894 let lvl = opt_logLevel (idris_options i)
896 case idris_outputmode i of
897 RawOutput -> do runIO $ putStrLn str
899 do let good = SexpList [IntegerAtom (toInteger l), toSExp str]
900 runIO $ putStrLn $ convSExp "log" good n
902cmdOptType :: Opt -> Idris Bool
903cmdOptType x = do i <- getIState
904 return $ x `elem` opt_cmdline (idris_options i)
906iLOG :: String -> Idris ()
909noErrors :: Idris Bool
910noErrors = do i <- getIState
912 Nothing -> return True
915setTypeCase :: Bool -> Idris ()
916setTypeCase t = do i <- getIState
917 let opts = idris_options i
918 let opt' = opts { opt_typecase = t }
919 putIState $ i { idris_options = opt' }
922-- Dealing with parameters
924expandParams :: (Name -> Name) -> [(Name, PTerm)] ->
925 [Name] -> -- all names
926 [Name] -> -- names with no declaration
928expandParams dec ps ns infs tm = en tm
930 -- if we shadow a name (say in a lambda binding) that is used in a call to
931 -- a lifted function, we need access to both names - once in the scope of the
932 -- binding and once to call the lifted functions. So we'll explicitly shadow
933 -- it. (Yes, it's a hack. The alternative would be to resolve names earlier
936 mkShadow (UN n) = MN 0 n
937 mkShadow (MN i n) = MN (i+1) n
938 mkShadow (NS x s) = NS (mkShadow x) s
941 | n `elem` (map fst ps ++ ns)
942 = let n' = mkShadow n in
943 PLam n' (en t) (en (shadow n n' s))
944 | otherwise = PLam n (en t) (en s)
946 | n `elem` (map fst ps ++ ns)
947 = let n' = mkShadow n in
948 PPi p n' (en t) (en (shadow n n' s))
949 | otherwise = PPi p n (en t) (en s)
951 | n `elem` (map fst ps ++ ns)
952 = let n' = mkShadow n in
953 PLet n' (en ty) (en v) (en (shadow n n' s))
954 | otherwise = PLet n (en ty) (en v) (en s)
955 -- FIXME: Should only do this in a type signature!
956 en (PDPair f p (PRef f' n) t r)
957 | n `elem` (map fst ps ++ ns) && t /= Placeholder
958 = let n' = mkShadow n in
959 PDPair f p (PRef f' n') (en t) (en (shadow n n' r))
960 en (PEq f l r) = PEq f (en l) (en r)
961 en (PRewrite f l r g) = PRewrite f (en l) (en r) (fmap en g)
962 en (PTyped l r) = PTyped (en l) (en r)
963 en (PPair f p l r) = PPair f p (en l) (en r)
964 en (PDPair f p l t r) = PDPair f p (en l) (en t) (en r)
965 en (PAlternative a as) = PAlternative a (map en as)
966 en (PHidden t) = PHidden (en t)
967 en (PUnifyLog t) = PUnifyLog (en t)
968 en (PDisamb ds t) = PDisamb ds (en t)
969 en (PNoImplicits t) = PNoImplicits (en t)
970 en (PDoBlock ds) = PDoBlock (map (fmap en) ds)
971 en (PProof ts) = PProof (map (fmap en) ts)
972 en (PTactics ts) = PTactics (map (fmap en) ts)
975 | n `nselem` ns = PQuote (Var (dec n))
976 en (PApp fc (PInferRef fc' n) as)
977 | n `nselem` ns = PApp fc (PInferRef fc' (dec n))
978 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
979 en (PApp fc (PRef fc' n) as)
980 | n `elem` infs = PApp fc (PInferRef fc' (dec n))
981 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
982 | n `nselem` ns = PApp fc (PRef fc' (dec n))
983 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
984 en (PAppBind fc (PRef fc' n) as)
985 | n `elem` infs = PAppBind fc (PInferRef fc' (dec n))
986 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
987 | n `nselem` ns = PAppBind fc (PRef fc' (dec n))
988 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
990 | n `elem` infs = PApp fc (PInferRef fc (dec n))
991 (map (pexp . (PRef fc)) (map fst ps))
992 | n `nselem` ns = PApp fc (PRef fc (dec n))
993 (map (pexp . (PRef fc)) (map fst ps))
995 | n `nselem` ns = PApp fc (PInferRef fc (dec n))
996 (map (pexp . (PRef fc)) (map fst ps))
997 en (PApp fc f as) = PApp fc (en f) (map (fmap en) as)
998 en (PAppBind fc f as) = PAppBind fc (en f) (map (fmap en) as)
999 en (PCase fc c os) = PCase fc (en c) (map (pmap en) os)
1003 nselem x (y : xs) | nseq x y = True
1004 | otherwise = nselem x xs
1006 nseq x y = nsroot x == nsroot y
1008expandParamsD :: Bool -> -- True = RHS only
1010 (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PDecl -> PDecl
1011expandParamsD rhsonly ist dec ps ns (PTy doc argdocs syn fc o n ty)
1012 = if n `elem` ns && (not rhsonly)
1013 then -- trace (show (n, expandParams dec ps ns ty)) $
1014 PTy doc argdocs syn fc o (dec n) (piBindp expl_param ps (expandParams dec ps ns [] ty))
1015 else --trace (show (n, expandParams dec ps ns ty)) $
1016 PTy doc argdocs syn fc o n (expandParams dec ps ns [] ty)
1017expandParamsD rhsonly ist dec ps ns (PPostulate doc syn fc o n ty)
1018 = if n `elem` ns && (not rhsonly)
1019 then -- trace (show (n, expandParams dec ps ns ty)) $
1020 PPostulate doc syn fc o (dec n) (piBind ps
1021 (expandParams dec ps ns [] ty))
1022 else --trace (show (n, expandParams dec ps ns ty)) $
1023 PPostulate doc syn fc o n (expandParams dec ps ns [] ty)
1024expandParamsD rhsonly ist dec ps ns (PClauses fc opts n cs)
1025 = let n' = if n `elem` ns then dec n else n in
1026 PClauses fc opts n' (map expandParamsC cs)
1028 expandParamsC (PClause fc n lhs ws rhs ds)
1029 = let -- ps' = updateps True (namesIn ist rhs) (zip ps [0..])
1030 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
1031 lhs' = if rhsonly then lhs else (expandParams dec ps'' ns [] lhs)
1032 n' = if n `elem` ns then dec n else n
1033 -- names bound on the lhs should not be expanded on the rhs
1034 ns' = removeBound lhs ns in
1036 (map (expandParams dec ps'' ns' []) ws)
1037 (expandParams dec ps'' ns' [] rhs)
1038 (map (expandParamsD True ist dec ps'' ns') ds)
1039 expandParamsC (PWith fc n lhs ws wval ds)
1040 = let -- ps' = updateps True (namesIn ist wval) (zip ps [0..])
1041 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
1042 lhs' = if rhsonly then lhs else (expandParams dec ps'' ns [] lhs)
1043 n' = if n `elem` ns then dec n else n
1044 ns' = removeBound lhs ns in
1046 (map (expandParams dec ps'' ns' []) ws)
1047 (expandParams dec ps'' ns' [] wval)
1048 (map (expandParamsD rhsonly ist dec ps'' ns') ds)
1049 updateps yn nm [] = []
1050 updateps yn nm (((a, t), i):as)
1051 | (a `elem` nm) == yn = (a, t) : updateps yn nm as
1052 | otherwise = (sMN i (show n ++ "_u"), t) : updateps yn nm as
1054 removeBound lhs ns = ns \\ nub (bnames lhs)
1056 bnames (PRef _ n) = [n]
1057 bnames (PApp _ _ args) = concatMap bnames (map getTm args)
1058 bnames (PPair _ _ l r) = bnames l ++ bnames r
1059 bnames (PDPair _ _ l Placeholder r) = bnames l ++ bnames r
1062expandParamsD rhs ist dec ps ns (PData doc argDocs syn fc co pd)
1063 = PData doc argDocs syn fc co (expandPData pd)
1065 -- just do the type decl, leave constructors alone (parameters will be
1066 -- added implicitly)
1067 expandPData (PDatadecl n ty cons)
1069 then PDatadecl (dec n) (piBind ps (expandParams dec ps ns [] ty))
1071 else PDatadecl n (expandParams dec ps ns [] ty) (map econ cons)
1072 econ (doc, argDocs, n, t, fc, fs)
1073 = (doc, argDocs, dec n, piBindp impl ps (expandParams dec ps ns [] t), fc, fs)
1074expandParamsD rhs ist dec ps ns (PRecord doc syn fc tn tty cdoc cn cty)
1076 then PRecord doc syn fc (dec tn) (piBind ps (expandParams dec ps ns [] tty))
1078 else PRecord doc syn fc (dec tn) (expandParams dec ps ns [] tty)
1080 where conty = piBindp impl ps (expandParams dec ps ns [] cty)
1081expandParamsD rhs ist dec ps ns (PParams f params pds)
1082 = PParams f (ps ++ map (mapsnd (expandParams dec ps ns [])) params)
1083 (map (expandParamsD True ist dec ps ns) pds)
1084-- (map (expandParamsD ist dec ps ns) pds)
1085expandParamsD rhs ist dec ps ns (PMutual f pds)
1086 = PMutual f (map (expandParamsD rhs ist dec ps ns) pds)
1087expandParamsD rhs ist dec ps ns (PClass doc info f cs n params decls)
1089 (map (expandParams dec ps ns []) cs)
1091 (map (mapsnd (expandParams dec ps ns [])) params)
1092 (map (expandParamsD rhs ist dec ps ns) decls)
1093expandParamsD rhs ist dec ps ns (PInstance info f cs n params ty cn decls)
1095 (map (expandParams dec ps ns []) cs)
1097 (map (expandParams dec ps ns []) params)
1098 (expandParams dec ps ns [] ty)
1100 (map (expandParamsD rhs ist dec ps ns) decls)
1101expandParamsD rhs ist dec ps ns d = d
1103mapsnd f (x, t) = (x, f t)
1105-- Calculate a priority for a type, for deciding elaboration order
1106-- * if it's just a type variable or concrete type, do it early (0)
1107-- * if there's only type variables and injective constructors, do it next (1)
1108-- * if there's a function type, next (2)
1109-- * finally, everything else (3)
1111getPriority :: IState -> PTerm -> Int
1112getPriority i tm = 1 -- pri tm
1115 case lookupP n (tt_ctxt i) of
1116 ((P (DCon _ _) _ _):_) -> 1
1117 ((P (TCon _ _) _ _):_) -> 1
1118 ((P Ref _ _):_) -> 1
1119 [] -> 0 -- must be locally bound, if it's not an error...
1120 pri (PPi _ _ x y) = max 5 (max (pri x) (pri y))
1124 pri (PEq _ l r) = max 1 (max (pri l) (pri r))
1125 pri (PRewrite _ l r _) = max 1 (max (pri l) (pri r))
1126 pri (PApp _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.getTm) as)))
1127 pri (PAppBind _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.getTm) as)))
1128 pri (PCase _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.snd) as)))
1129 pri (PTyped l r) = pri l
1130 pri (PPair _ _ l r) = max 1 (max (pri l) (pri r))
1131 pri (PDPair _ _ l t r) = max 1 (max (pri l) (max (pri t) (pri r)))
1132 pri (PAlternative a as) = maximum (map pri as)
1133 pri (PConstant _) = 0
1138addStatics :: Name -> Term -> PTerm -> Idris ()
1139addStatics n tm ptm =
1140 do let (statics, dynamics) = initStatics tm ptm
1141 let stnames = nub $ concatMap freeArgNames (map snd statics)
1142 let dnames = nub $ concatMap freeArgNames (map snd dynamics)
1143 -- also get the arguments which are 'uniquely inferrable' from
1144 -- statics (see sec 4.2 of "Scrapping Your Inefficient Engine")
1145 let statics' = nub $ map fst statics ++
1146 filter (\x -> not (elem x dnames)) stnames
1147 let stpos = staticList statics' tm
1149 when (not (null statics)) $
1150 logLvl 5 $ show n ++ " " ++ show statics' ++ "\n" ++ show dynamics
1151 ++ "\n" ++ show stnames ++ "\n" ++ show dnames
1152 putIState $ i { idris_statics = addDef n stpos (idris_statics i) }
1153 addIBC (IBCStatic n)
1155 initStatics (Bind n (Pi ty) sc) (PPi p _ _ s)
1156 = let (static, dynamic) = initStatics (instantiate (P Bound n ty) sc) s in
1157 if pstatic p == Static then ((n, ty) : static, dynamic)
1158 else if (not (searchArg p))
1159 then (static, (n, ty) : dynamic)
1160 else (static, dynamic)
1161 initStatics t pt = ([], [])
1163 freeArgNames (Bind n (Pi ty) sc)
1164 = nub $ freeArgNames ty
1165 freeArgNames tm = let (_, args) = unApply tm in
1166 concatMap freeNames args
1168 -- if a name appears in a type class or tactic implicit index, it doesn't
1169 -- affect its 'uniquely inferrable' from a static status since these are
1170 -- resolved by searching.
1171 searchArg (Constraint _ _) = True
1172 searchArg (TacImp _ _ _) = True
1175 staticList sts (Bind n (Pi _) sc) = (n `elem` sts) : staticList sts sc
1178-- Dealing with implicit arguments
1180-- Add constraint bindings from using block
1182addUsingConstraints :: SyntaxInfo -> FC -> PTerm -> Idris PTerm
1183addUsingConstraints syn fc t
1185 let ns = namesIn [] ist t
1186 let cs = getConstraints t -- check declared constraints
1187 let addconsts = uconsts \\ cs
1188 -- if all names in the arguments of addconsts appear in ns,
1189 -- add the constraint implicitly
1190 return (doAdd addconsts ns t)
1191 where uconsts = filter uconst (using syn)
1192 uconst (UConstraint _ _) = True
1196 -- if all of args in ns, then add it
1197 doAdd (UConstraint c args : cs) ns t
1198 | all (\n -> elem n ns) args
1199 = PPi (Constraint [] Dynamic) (sMN 0 "cu")
1200 (mkConst c args) (doAdd cs ns t)
1201 | otherwise = doAdd cs ns t
1203 mkConst c args = PApp fc (PRef fc c)
1204 (map (\n -> PExp 0 [] (PRef fc n)) args)
1206 getConstraints (PPi (Constraint _ _) _ c sc)
1207 = getcapp c ++ getConstraints sc
1208 getConstraints (PPi _ _ c sc) = getConstraints sc
1209 getConstraints _ = []
1211 getcapp (PApp _ (PRef _ c) args)
1212 = do ns <- mapM getName args
1213 return (UConstraint c ns)
1216 getName (PExp _ _ (PRef _ n)) = return n
1219-- Add implicit Pi bindings for any names in the term which appear in an
1220-- argument position.
1222-- This has become a right mess already. Better redo it some time...
1224implicit :: SyntaxInfo -> Name -> PTerm -> Idris PTerm
1225implicit syn n ptm = implicit' syn [] n ptm
1227implicit' :: SyntaxInfo -> [Name] -> Name -> PTerm -> Idris PTerm
1228implicit' syn ignore n ptm
1230 let (tm', impdata) = implicitise syn ignore i ptm
1231-- let (tm'', spos) = findStatics i tm'
1232 putIState $ i { idris_implicits = addDef n impdata (idris_implicits i) }
1234 logLvl 5 ("Implicit " ++ show n ++ " " ++ show impdata)
1236-- putIState $ i { idris_statics = addDef n spos (idris_statics i) }
1239implicitise :: SyntaxInfo -> [Name] -> IState -> PTerm -> (PTerm, [PArg])
1240implicitise syn ignore ist tm = -- trace ("INCOMING " ++ showImp True tm) $
1241 let (declimps, ns') = execState (imps True [] tm) ([], [])
1242 ns = filter (\n -> implicitable n || elem n (map fst uvars)) $
1243 ns' \\ (map fst pvars ++ no_imp syn ++ ignore)
1244 nsOrder = filter (not . inUsing) ns ++ filter inUsing ns in
1246 then (tm, reverse declimps)
1247 else implicitise syn ignore ist (pibind uvars nsOrder tm)
1249 uvars = map ipair (filter uimplicit (using syn))
1250 pvars = syn_params syn
1252 inUsing n = n `elem` map fst uvars
1254 ipair (UImplicit x y) = (x, y)
1255 uimplicit (UImplicit _ _) = True
1258 dropAll (x:xs) ys | x `elem` ys = dropAll xs ys
1259 | otherwise = x : dropAll xs ys
1262 -- Find names in argument position in a type, suitable for implicit
1264 -- Not the function position, but do everything else...
1265 implNamesIn uv (PApp fc f args) = concatMap (implNamesIn uv) (map getTm args)
1266 implNamesIn uv t = namesIn uv ist t
1268 imps top env (PApp _ f as)
1269 = do (decls, ns) <- get
1270 let isn = concatMap (namesIn uvars ist) (map getTm as)
1271 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1272 imps top env (PPi (Imp l _ _) n ty sc)
1273 = do let isn = nub (implNamesIn uvars ty) `dropAll` [n]
1275 put (PImp (getPriority ist ty) True l n Placeholder : decls,
1276 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1277 imps True (n:env) sc
1278 imps top env (PPi (Exp l _ _) n ty sc)
1279 = do let isn = nub (implNamesIn uvars ty ++ case sc of
1280 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1282 (decls, ns) <- get -- ignore decls in HO types
1283 put (PExp (getPriority ist ty) l Placeholder : decls,
1284 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1285 imps True (n:env) sc
1286 imps top env (PPi (Constraint l _) n ty sc)
1287 = do let isn = nub (implNamesIn uvars ty ++ case sc of
1288 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1290 (decls, ns) <- get -- ignore decls in HO types
1291 put (PConstraint 10 l Placeholder : decls,
1292 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1293 imps True (n:env) sc
1294 imps top env (PPi (TacImp l _ scr) n ty sc)
1295 = do let isn = nub (implNamesIn uvars ty ++ case sc of
1296 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1298 (decls, ns) <- get -- ignore decls in HO types
1299 put (PTacImplicit 10 l n scr Placeholder : decls,
1300 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1301 imps True (n:env) sc
1302 imps top env (PEq _ l r)
1303 = do (decls, ns) <- get
1304 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1305 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1306 imps top env (PRewrite _ l r _)
1307 = do (decls, ns) <- get
1308 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1309 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1310 imps top env (PTyped l r)
1312 imps top env (PPair _ _ l r)
1313 = do (decls, ns) <- get
1314 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1315 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1316 imps top env (PDPair _ _ (PRef _ n) t r)
1317 = do (decls, ns) <- get
1318 let isn = nub (namesIn uvars ist t ++ namesIn uvars ist r) \\ [n]
1319 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1320 imps top env (PDPair _ _ l t r)
1321 = do (decls, ns) <- get
1322 let isn = namesIn uvars ist l ++ namesIn uvars ist t ++
1324 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1325 imps top env (PAlternative a as)
1326 = do (decls, ns) <- get
1327 let isn = concatMap (namesIn uvars ist) as
1328 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1329 imps top env (PLam n ty sc)
1330 = do imps False env ty
1331 imps False (n:env) sc
1332 imps top env (PHidden tm) = imps False env tm
1333 imps top env (PUnifyLog tm) = imps False env tm
1334 imps top env (PNoImplicits tm) = imps False env tm
1335 imps top env _ = return ()
1337 pibind using [] sc = sc
1338 pibind using (n:ns) sc
1339 = case lookup n using of
1340 Just ty -> PPi (Imp [] Dynamic False) n ty (pibind using ns sc)
1341 Nothing -> PPi (Imp [] Dynamic False) n Placeholder
1342 (pibind using ns sc)
1344-- Add implicit arguments in function calls
1345addImplPat :: IState -> PTerm -> PTerm
1346addImplPat = addImpl' True [] []
1348addImplBound :: IState -> [Name] -> PTerm -> PTerm
1349addImplBound ist ns = addImpl' False ns [] ist
1351addImplBoundInf :: IState -> [Name] -> [Name] -> PTerm -> PTerm
1352addImplBoundInf ist ns inf = addImpl' False ns inf ist
1354addImpl :: IState -> PTerm -> PTerm
1355addImpl = addImpl' False [] []
1357-- TODO: in patterns, don't add implicits to function names guarded by constructors
1358-- and *not* inside a PHidden
1360addImpl' :: Bool -> [Name] -> [Name] -> IState -> PTerm -> PTerm
1361addImpl' inpat env infns ist ptm
1362 = mkUniqueNames env (ai (zip env (repeat Nothing)) [] ptm)
1364 ai env ds (PRef fc f)
1365 | f `elem` infns = PInferRef fc f
1366 | not (f `elem` map fst env) = handleErr $ aiFn inpat inpat ist fc f ds []
1367 ai env ds (PHidden (PRef fc f))
1368 | not (f `elem` map fst env) = handleErr $ aiFn inpat False ist fc f ds []
1369 ai env ds (PEq fc l r)
1370 = let l' = ai env ds l
1373 ai env ds (PRewrite fc l r g)
1374 = let l' = ai env ds l
1376 g' = fmap (ai env ds) g in
1377 PRewrite fc l' r' g'
1378 ai env ds (PTyped l r)
1379 = let l' = ai env ds l
1382 ai env ds (PPair fc p l r)
1383 = let l' = ai env ds l
1386 ai env ds (PDPair fc p l t r)
1387 = let l' = ai env ds l
1390 PDPair fc p l' t' r'
1391 ai env ds (PAlternative a as)
1392 = let as' = map (ai env ds) as in
1394 ai env _ (PDisamb ds' as) = ai env ds' as
1395 ai env ds (PApp fc (PInferRef _ f) as)
1396 = let as' = map (fmap (ai env ds)) as in
1397 PApp fc (PInferRef fc f) as'
1398 ai env ds (PApp fc ftm@(PRef _ f) as)
1399 | f `elem` infns = ai env ds (PApp fc (PInferRef fc f) as)
1400 | not (f `elem` map fst env)
1401 = let as' = map (fmap (ai env ds)) as in
1402 handleErr $ aiFn inpat False ist fc f ds as'
1403 | Just (Just ty) <- lookup f env =
1404 let as' = map (fmap (ai env ds)) as
1405 arity = getPArity ty in
1406 mkPApp fc arity ftm as'
1407 ai env ds (PApp fc f as)
1408 = let f' = ai env ds f
1409 as' = map (fmap (ai env ds)) as in
1411 ai env ds (PCase fc c os)
1412 = let c' = ai env ds c
1413 os' = map (pmap (ai env ds)) os in
1415 ai env ds (PLam n ty sc)
1416 = let ty' = ai env ds ty
1417 sc' = ai ((n, Just ty):env) ds sc in
1419 ai env ds (PLet n ty val sc)
1420 = let ty' = ai env ds ty
1421 val' = ai env ds val
1422 sc' = ai ((n, Just ty):env) ds sc in
1424 ai env ds (PPi p n ty sc)
1425 = let ty' = ai env ds ty
1426 sc' = ai ((n, Just ty):env) ds sc in
1428 ai env ds (PGoal fc r n sc)
1429 = let r' = ai env ds r
1430 sc' = ai ((n, Nothing):env) ds sc in
1432 ai env ds (PHidden tm) = PHidden (ai env ds tm)
1433 ai env ds (PProof ts) = PProof (map (fmap (ai env ds)) ts)
1434 ai env ds (PTactics ts) = PTactics (map (fmap (ai env ds)) ts)
1435 ai env ds (PRefl fc tm) = PRefl fc (ai env ds tm)
1436 ai env ds (PUnifyLog tm) = PUnifyLog (ai env ds tm)
1437 ai env ds (PNoImplicits tm) = PNoImplicits (ai env ds tm)
1440 handleErr (Left err) = PElabError err
1441 handleErr (Right x) = x
1443-- if in a pattern, and there are no arguments, and there's no possible
1444-- names with zero explicit arguments, don't add implicits.
1446aiFn :: Bool -> Bool -> IState -> FC -> Name -> [[T.Text]] -> [PArg] -> Either Err PTerm
1447aiFn inpat True ist fc f ds []
1448 = case lookupDef f (tt_ctxt ist) of
1449 [] -> Right $ PPatvar fc f
1450 alts -> let ialts = lookupCtxtName f (idris_implicits ist) in
1451 -- trace (show f ++ " " ++ show (fc, any (all imp) ialts, ialts, any constructor alts)) $
1452 if (not (vname f) || tcname f
1453 || any (conCaf (tt_ctxt ist)) ialts)
1454-- any constructor alts || any allImp ialts))
1455 then aiFn inpat False ist fc f ds [] -- use it as a constructor
1456 else Right $ PPatvar fc f
1457 where imp (PExp _ _ _) = False
1460 allImp xs = all imp xs
1461 constructor (TyDecl (DCon _ _) _) = True
1462 constructor _ = False
1464 conCaf ctxt (n, cia) = isDConName n ctxt && allImp cia
1466 vname (UN n) = True -- non qualified
1469aiFn inpat expat ist fc f ds as
1470 | f `elem` primNames = Right $ PApp fc (PRef fc f) as
1471aiFn inpat expat ist fc f ds as
1472 -- This is where namespaces get resolved by adding PAlternative
1473 = do let ns = lookupCtxtName f (idris_implicits ist)
1474 let nh = filter (\(n, _) -> notHidden n) ns
1475 let ns' = case trimAlts ds nh of
1479 [(f',ns)] -> Right $ mkPApp fc (length ns) (PRef fc f') (insertImpl ns as)
1480 [] -> if f `elem` (map fst (idris_metavars ist))
1481 then Right $ PApp fc (PRef fc f) as
1482 else Right $ mkPApp fc (length as) (PRef fc f) as
1485 map (\(f', ns) -> mkPApp fc (length ns) (PRef fc f')
1486 (insertImpl ns as)) alts
1488 trimAlts [] alts = alts
1490 = filter (\(x, _) -> any (\d -> d `isPrefixOf` nspace x) ns) alts
1495 notHidden n = case getAccessibility n of
1500 = case lookupDefAcc n False (tt_ctxt ist) of
1505 insertImpl :: [PArg] -> [PArg] -> [PArg]
1506 insertImpl (PExp p l ty : ps) (PExp _ _ tm : given) =
1507 PExp p l tm : insertImpl ps given
1508 insertImpl (PConstraint p l ty : ps) (PConstraint _ _ tm : given) =
1509 PConstraint p l tm : insertImpl ps given
1510 insertImpl (PConstraint p l ty : ps) given =
1511 PConstraint p l (PResolveTC fc) : insertImpl ps given
1512 insertImpl (PImp p _ l n ty : ps) given =
1513 case find n given [] of
1514 Just (tm, given') -> PImp p False l n tm : insertImpl ps given'
1515 Nothing -> PImp p True l n Placeholder : insertImpl ps given
1516 insertImpl (PTacImplicit p l n sc' ty : ps) given =
1517 let sc = addImpl ist sc' in
1518 case find n given [] of
1519 Just (tm, given') -> PTacImplicit p l n sc tm : insertImpl ps given'
1521 then PTacImplicit p l n sc Placeholder : insertImpl ps given
1522 else PTacImplicit p l n sc sc : insertImpl ps given
1523 insertImpl expected [] = []
1524 insertImpl _ given = given
1526 find n [] acc = Nothing
1527 find n (PImp _ _ _ n' t : gs) acc
1528 | n == n' = Just (t, reverse acc ++ gs)
1529 find n (PTacImplicit _ _ n' _ t : gs) acc
1530 | n == n' = Just (t, reverse acc ++ gs)
1531 find n (g : gs) acc = find n gs (g : acc)
1533-- replace non-linear occurrences with _
1534-- ASSUMPTION: This is called before adding 'alternatives' because otherwise
1535-- it is hard to get right!
1537stripLinear :: IState -> PTerm -> PTerm
1538stripLinear i tm = evalState (sl tm) [] where
1539 sl :: PTerm -> State [Name] PTerm
1541 | (_:_) <- lookupTy f (tt_ctxt i)
1542 = return $ PRef fc f
1543 | otherwise = do ns <- get
1545 then return Placeholder
1546 else do put (f : ns)
1551 then return Placeholder
1552 else do put (f : ns)
1553 return (PPatvar fc f)
1554 sl t@(PAlternative _ (a : as)) = do sl a
1556 sl (PApp fc fn args) = do fn' <- sl fn
1557 args' <- mapM slA args
1558 return $ PApp fc fn' args'
1559 where slA (PImp p m l n t) = do t' <- sl t
1560 return $ PImp p m l n t'
1561 slA (PExp p l t) = do t' <- sl t
1562 return $ PExp p l t'
1563 slA (PConstraint p l t)
1565 return $ PConstraint p l t'
1566 slA (PTacImplicit p l n sc t)
1568 return $ PTacImplicit p l n sc t'
1571-- Remove functions which aren't applied to anything, which must then
1572-- be resolved by unification. Assume names resolved and alternatives
1573-- filled in (so no ambiguity).
1575stripUnmatchable :: IState -> PTerm -> PTerm
1576stripUnmatchable i (PApp fc fn args) = PApp fc fn (fmap (fmap su) args) where
1577 su :: PTerm -> PTerm
1579 | (Bind n (Pi t) sc :_) <- lookupTy f (tt_ctxt i)
1581 su (PApp fc fn args)
1582 = PApp fc fn (fmap (fmap su) args)
1583 su (PAlternative b alts)
1584 = let alts' = filter (/= Placeholder) (map su alts) in
1585 if null alts' then Placeholder
1586 else PAlternative b alts'
1587 su (PPair fc p l r) = PPair fc p (su l) (su r)
1588 su (PDPair fc p l t r) = PDPair fc p (su l) (su t) (su r)
1590stripUnmatchable i tm = tm
1593mkPApp fc a f as = let rest = drop a as in
1594 appRest fc (PApp fc f (take a as)) rest
1597 appRest fc f (a : as) = appRest fc (PApp fc f [a]) as
1599-- Find 'static' argument positions
1600-- (the declared ones, plus any names in argument position in the declared
1602-- FIXME: It's possible that this really has to happen after elaboration
1604findStatics :: IState -> PTerm -> (PTerm, [Bool])
1605findStatics ist tm = trace (show tm) $
1606 let (ns, ss) = fs tm in
1607 runState (pos ns ss tm) []
1608 where fs (PPi p n t sc)
1609 | Static <- pstatic p
1610 = let (ns, ss) = fs sc in
1611 (namesIn [] ist t : ns, n : ss)
1612 | otherwise = let (ns, ss) = fs sc in
1616 inOne n ns = length (filter id (map (elem n) ns)) == 1
1618 pos ns ss (PPi p n t sc)
1619 | elem n ss = do sc' <- pos ns ss sc
1622 return (PPi (p { pstatic = Static }) n t sc')
1623 | otherwise = do sc' <- pos ns ss sc
1626 return (PPi p n t sc')
1627 pos ns ss t = return t
1629-- for 6.12/7 compatibility
1630data EitherErr a b = LeftErr a | RightOK b
1632instance Monad (EitherErr a) where
1635 (LeftErr e) >>= k = LeftErr e
1636 RightOK v >>= k = k v
1638toEither (LeftErr e) = Left e
1639toEither (RightOK ho) = Right ho
1641-- syntactic match of a against b, returning pair of variables in a
1642-- and what they match. Returns the pair that failed if not a match.
1644matchClause :: IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
1645matchClause = matchClause' False
1647matchClause' :: Bool -> IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
1648matchClause' names i x y = checkRpts $ match (fullApp x) (fullApp y) where
1649 matchArg x y = match (fullApp (getTm x)) (fullApp (getTm y))
1651 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
1654 match' x y = match (fullApp x) (fullApp y)
1655 match (PApp _ (PRef _ (NS (UN fi) [b])) [_,_,x]) x'
1656 | fi == txt "fromInteger" && b == txt "builtins",
1657 PConstant (I _) <- getTm x = match (getTm x) x'
1658 match x' (PApp _ (PRef _ (NS (UN fi) [b])) [_,_,x])
1659 | fi == txt "fromInteger" && b == txt "builtins",
1660 PConstant (I _) <- getTm x = match (getTm x) x'
1661 match (PApp _ (PRef _ (UN l)) [_,x]) x' | l == txt "lazy" = match (getTm x) x'
1662 match x (PApp _ (PRef _ (UN l)) [_,x']) | l == txt "lazy" = match x (getTm x')
1663 match (PApp _ f args) (PApp _ f' args')
1664 | length args == length args'
1665 = do mf <- match' f f'
1666 ms <- zipWithM matchArg args args'
1667 return (mf ++ concat ms)
1668-- match (PRef _ n) (PRef _ n') | n == n' = return []
1669-- | otherwise = Nothing
1670 match (PRef f n) (PApp _ x []) = match (PRef f n) x
1671 match (PPatvar f n) xr = match (PRef f n) xr
1672 match xr (PPatvar f n) = match xr (PRef f n)
1673 match (PApp _ x []) (PRef f n) = match x (PRef f n)
1674 match (PRef _ n) tm@(PRef _ n')
1675 | n == n' && not names &&
1676 (not (isConName n (tt_ctxt i) || isFnName n (tt_ctxt i))
1677 || tm == Placeholder)
1679 | n == n' = return []
1681 | not names && (not (isConName n (tt_ctxt i) ||
1682 isFnName n (tt_ctxt i)) || tm == Placeholder)
1684 match (PEq _ l r) (PEq _ l' r') = do ml <- match' l l'
1687 match (PRewrite _ l r _) (PRewrite _ l' r' _)
1688 = do ml <- match' l l'
1691 match (PTyped l r) (PTyped l' r') = do ml <- match l l'
1694 match (PTyped l r) x = match l x
1695 match x (PTyped l r) = match x l
1696 match (PPair _ _ l r) (PPair _ _ l' r') = do ml <- match' l l'
1699 match (PDPair _ _ l t r) (PDPair _ _ l' t' r') = do ml <- match' l l'
1702 return (ml ++ mt ++ mr)
1703 match (PAlternative a as) (PAlternative a' as')
1704 = do ms <- zipWithM match' as as'
1706 match a@(PAlternative _ as) b
1707 = do let ms = zipWith match' as (repeat b)
1708 case (rights (map toEither ms)) of
1711 match (PCase _ _ _) _ = return [] -- lifted out
1712 match (PMetavar _) _ = return [] -- modified
1713 match (PInferRef _ _) _ = return [] -- modified
1714 match (PQuote _) _ = return []
1715 match (PProof _) _ = return []
1716 match (PTactics _) _ = return []
1717 match (PRefl _ _) (PRefl _ _) = return []
1718 match (PResolveTC _) (PResolveTC _) = return []
1719 match (PTrue _ _) (PTrue _ _) = return []
1720 match (PFalse _) (PFalse _) = return []
1721 match (PReturn _) (PReturn _) = return []
1722 match (PPi _ _ t s) (PPi _ _ t' s') = do mt <- match' t t'
1725 match (PLam _ t s) (PLam _ t' s') = do mt <- match' t t'
1728 match (PLet _ t ty s) (PLet _ t' ty' s') = do mt <- match' t t'
1729 mty <- match' ty ty'
1731 return (mt ++ mty ++ ms)
1732 match (PHidden x) (PHidden y) = match' x y
1733 match (PUnifyLog x) y = match' x y
1734 match x (PUnifyLog y) = match' x y
1735 match (PNoImplicits x) y = match' x y
1736 match x (PNoImplicits y) = match' x y
1737 match Placeholder _ = return []
1738 match _ Placeholder = return []
1739 match (PResolveTC _) _ = return []
1740 match a b | a == b = return []
1741 | otherwise = LeftErr (a, b)
1743 checkRpts (RightOK ms) = check ms where
1745 | Just t' <- lookup n xs = if t/=t' && t/=Placeholder && t'/=Placeholder
1748 check (_:xs) = check xs
1750 checkRpts (LeftErr x) = Left x
1752substMatches :: [(Name, PTerm)] -> PTerm -> PTerm
1753substMatches ms = substMatchesShadow ms []
1755substMatchesShadow :: [(Name, PTerm)] -> [Name] -> PTerm -> PTerm
1756substMatchesShadow [] shs t = t
1757substMatchesShadow ((n,tm):ns) shs t
1758 = substMatchShadow n shs tm (substMatchesShadow ns shs t)
1760substMatch :: Name -> PTerm -> PTerm -> PTerm
1761substMatch n = substMatchShadow n []
1763substMatchShadow :: Name -> [Name] -> PTerm -> PTerm -> PTerm
1764substMatchShadow n shs tm t = sm shs t where
1765 sm xs (PRef _ n') | n == n' = tm
1766 sm xs (PLam x t sc) = PLam x (sm xs t) (sm xs sc)
1767 sm xs (PPi p x t sc)
1769 = let x' = nextName x in
1770 PPi p x' (sm (x':xs) (substMatch x (PRef emptyFC x') t))
1771 (sm (x':xs) (substMatch x (PRef emptyFC x') sc))
1772 | otherwise = PPi p x (sm xs t) (sm (x : xs) sc)
1773 sm xs (PApp f x as) = fullApp $ PApp f (sm xs x) (map (fmap (sm xs)) as)
1774 sm xs (PCase f x as) = PCase f (sm xs x) (map (pmap (sm xs)) as)
1775 sm xs (PEq f x y) = PEq f (sm xs x) (sm xs y)
1776 sm xs (PRewrite f x y tm) = PRewrite f (sm xs x) (sm xs y)
1778 sm xs (PTyped x y) = PTyped (sm xs x) (sm xs y)
1779 sm xs (PPair f p x y) = PPair f p (sm xs x) (sm xs y)
1780 sm xs (PDPair f p x t y) = PDPair f p (sm xs x) (sm xs t) (sm xs y)
1781 sm xs (PAlternative a as) = PAlternative a (map (sm xs) as)
1782 sm xs (PHidden x) = PHidden (sm xs x)
1783 sm xs (PUnifyLog x) = PUnifyLog (sm xs x)
1784 sm xs (PNoImplicits x) = PNoImplicits (sm xs x)
1787 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
1790shadow :: Name -> Name -> PTerm -> PTerm
1791shadow n n' t = sm t where
1792 sm (PRef fc x) | n == x = PRef fc n'
1793 sm (PLam x t sc) | n /= x = PLam x (sm t) (sm sc)
1794 sm (PPi p x t sc) | n /=x = PPi p x (sm t) (sm sc)
1795 sm (PLet x t v sc) | n /= x = PLet x (sm t) (sm v) (sm sc)
1796 sm (PApp f x as) = PApp f (sm x) (map (fmap sm) as)
1797 sm (PAppBind f x as) = PAppBind f (sm x) (map (fmap sm) as)
1798 sm (PCase f x as) = PCase f (sm x) (map (pmap sm) as)
1799 sm (PEq f x y) = PEq f (sm x) (sm y)
1800 sm (PRewrite f x y tm) = PRewrite f (sm x) (sm y) (fmap sm tm)
1801 sm (PTyped x y) = PTyped (sm x) (sm y)
1802 sm (PPair f p x y) = PPair f p (sm x) (sm y)
1803 sm (PDPair f p x t y) = PDPair f p (sm x) (sm t) (sm y)
1804 sm (PAlternative a as) = PAlternative a (map sm as)
1805 sm (PTactics ts) = PTactics (map (fmap sm) ts)
1806 sm (PProof ts) = PProof (map (fmap sm) ts)
1807 sm (PHidden x) = PHidden (sm x)
1808 sm (PUnifyLog x) = PUnifyLog (sm x)
1809 sm (PNoImplicits x) = PNoImplicits (sm x)
1812-- Rename any binders which are repeated (so that we don't have to mess
1813-- about with shadowing anywhere else).
1815mkUniqueNames :: [Name] -> PTerm -> PTerm
1816mkUniqueNames env tm = evalState (mkUniq tm) env where
1817 inScope = boundNamesIn tm
1819 mkUniqA arg = do t' <- mkUniq (getTm arg)
1820 return (arg { getTm = t' })
1822 -- FIXME: Probably ought to do this for completeness! It's fine as
1823 -- long as there are no bindings inside tactics though.
1824 mkUniqT tac = return tac
1826 mkUniq :: PTerm -> State [Name] PTerm
1827 mkUniq (PLam n ty sc)
1831 then do let n' = uniqueName n (env ++ inScope)
1832 return (n', shadow n n' sc)
1837 return $! PLam n' ty' sc''
1838 mkUniq (PPi p n ty sc)
1842 then do let n' = uniqueName n (env ++ inScope)
1843 return (n', shadow n n' sc)
1848 return $! PPi p n' ty' sc''
1849 mkUniq (PLet n ty val sc)
1853 then do let n' = uniqueName n (env ++ inScope)
1854 return (n', shadow n n' sc)
1857 ty' <- mkUniq ty; val' <- mkUniq val
1859 return $! PLet n' ty' val' sc''
1860 mkUniq (PApp fc t args)
1862 args' <- mapM mkUniqA args
1863 return $! PApp fc t' args'
1864 mkUniq (PAppBind fc t args)
1866 args' <- mapM mkUniqA args
1867 return $! PAppBind fc t' args'
1868 mkUniq (PCase fc t alts)
1870 alts' <- mapM (\(x,y)-> do x' <- mkUniq x; y' <- mkUniq y
1871 return (x', y')) alts
1872 return $! PCase fc t' alts'
1873 mkUniq (PPair fc p l r)
1874 = do l' <- mkUniq l; r' <- mkUniq r
1875 return $! PPair fc p l' r'
1876 mkUniq (PDPair fc p (PRef fc' n) t sc)
1879 (n', sc') <- if n `elem` env
1880 then do let n' = uniqueName n (env ++ inScope)
1881 return (n', shadow n n' sc)
1886 return $! PDPair fc p (PRef fc' n') t' sc''
1887 mkUniq (PDPair fc p l t r)
1888 = do l' <- mkUniq l; t' <- mkUniq t; r' <- mkUniq r
1889 return $! PDPair fc p l' t' r'
1890 mkUniq (PAlternative b as)
1891 = liftM (PAlternative b) (mapM mkUniq as)
1892 mkUniq (PHidden t) = liftM PHidden (mkUniq t)
1893 mkUniq (PUnifyLog t) = liftM PUnifyLog (mkUniq t)
1894 mkUniq (PDisamb n t) = liftM (PDisamb n) (mkUniq t)
1895 mkUniq (PNoImplicits t) = liftM PNoImplicits (mkUniq t)
1896 mkUniq (PProof ts) = liftM PProof (mapM mkUniqT ts)
1897 mkUniq (PTactics ts) = liftM PTactics (mapM mkUniqT ts)
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