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)
360setErrLine :: Int -> Idris ()
361setErrLine x = do i <- getIState;
363 Nothing -> putIState $ i { errLine = Just x }
367clearErr = do i <- getIState
368 putIState $ i { errLine = 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 })
395addInternalApp :: FilePath -> Int -> PTerm -> Idris ()
398 putIState (i { idris_lineapps = ((fp, l), t) : idris_lineapps i })
400getInternalApp :: FilePath -> Int -> Idris PTerm
401getInternalApp fp l = do i <- getIState
402 case lookup (fp, l) (idris_lineapps i) of
404 Nothing -> return Placeholder
405 -- TODO: What if it's not there?
407-- Pattern definitions are only used for coverage checking, so erase them
409clearOrigPats :: Idris ()
410clearOrigPats = do i <- get
411 let ps = idris_patdefs i
412 let ps' = mapCtxt (\ (_,miss) -> ([], miss)) ps
413 put (i { idris_patdefs = ps' })
415-- Erase types from Ps in the context (basically ending up with what's in
416-- the .ibc, which is all we need after all the analysis is done)
417clearPTypes :: Idris ()
418clearPTypes = do i <- get
420 put (i { tt_ctxt = mapDefCtxt pErase ctxt })
421 where pErase (CaseOp c t tys orig tot cds)
422 = CaseOp c t tys orig [] (pErase' cds)
424 pErase' (CaseDefs _ (cs, c) _ rs)
425 = let c' = (cs, fmap pEraseType c) in
428checkUndefined :: FC -> Name -> Idris ()
432 (_:_) -> throwError . Msg $ show fc ++ ":" ++
433 show n ++ " already defined"
436isUndefined :: FC -> Name -> Idris Bool
440 (_:_) -> return False
443setContext :: Context -> Idris ()
444setContext ctxt = do i <- getIState; putIState $ (i { tt_ctxt = ctxt } )
446updateContext :: (Context -> Context) -> Idris ()
447updateContext f = do i <- getIState; putIState $ (i { tt_ctxt = f (tt_ctxt i) } )
449addConstraints :: FC -> (Int, [UConstraint]) -> Idris ()
450addConstraints fc (v, cs)
453 let ctxt' = ctxt { uconstraints = cs ++ uconstraints ctxt,
455 let ics = zip cs (repeat fc) ++ idris_constraints i
456 putIState $ i { tt_ctxt = ctxt', idris_constraints = ics }
458addDeferred = addDeferred' Ref
459addDeferredTyCon = addDeferred' (TCon 0 0)
461addDeferred' :: NameType -> [(Name, (Int, Maybe Name, Type, Bool))] -> Idris ()
463 = do mapM_ (\(n, (i, _, t, _)) -> updateContext (addTyDecl n nt (tidyNames [] t))) ns
464 mapM_ (\(n, _) -> when (not (n `elem` primDefs)) $ addIBC (IBCMetavar n)) ns
466 putIState $ i { idris_metavars = map (\(n, (i, top, _, isTopLevel)) -> (n, (top, i, isTopLevel))) ns ++
468 where tidyNames used (Bind (MN i x) b sc)
469 = let n' = uniqueName (UN x) used in
470 Bind n' b $ tidyNames (n':used) sc
471 tidyNames used (Bind n b sc)
472 = let n' = uniqueName n used in
473 Bind n' b $ tidyNames (n':used) sc
476solveDeferred :: Name -> Idris ()
477solveDeferred n = do i <- getIState
478 putIState $ i { idris_metavars =
479 filter (\(n', _) -> n/=n')
482 filter (notMV n) (ibc_write i)
484 where notMV n (IBCMetavar n') = not (n == n')
487getUndefined :: Idris [Name]
488getUndefined = do i <- getIState
489 return (map fst (idris_metavars i) \\ primDefs)
491getWidth :: Idris ConsoleWidth
492getWidth = fmap idris_consolewidth getIState
494setWidth :: ConsoleWidth -> Idris ()
495setWidth w = do ist <- getIState
496 put ist { idris_consolewidth = w }
498renderWidth :: Idris Int
499renderWidth = do iw <- getWidth
501 InfinitelyWide -> return 100000000
502 ColsWide n -> return (max n 1)
503 AutomaticWidth -> runIO getScreenWidth
506iRender :: Doc a -> Idris (SimpleDoc a)
507iRender d = do w <- getWidth
509 let ideSlave = case idris_outputmode ist of
513 InfinitelyWide -> return $ renderPretty 1.0 1000000000 d
514 ColsWide n -> return $
516 then renderPretty 1.0 1000000000 d
517 else renderPretty 0.8 n d
518 AutomaticWidth | ideSlave -> return $ renderPretty 1.0 1000000000 d
519 | otherwise -> do width <- runIO getScreenWidth
520 return $ renderPretty 0.8 width d
522ihPrintResult :: Handle -> String -> Idris ()
523ihPrintResult h s = do i <- getIState
524 case idris_outputmode i of
525 RawOutput -> case s of
527 s -> runIO $ hPutStrLn h s
529 let good = SexpList [SymbolAtom "ok", toSExp s] in
530 runIO $ hPutStrLn h $ convSExp "return" good n
532-- | Write a pretty-printed term to the console with semantic coloring
533consoleDisplayAnnotated :: Handle -> Doc OutputAnnotation -> Idris ()
534consoleDisplayAnnotated h output = do ist <- getIState
535 rendered <- iRender $ output
536 runIO . hPutStrLn h .
537 displayDecorated (consoleDecorate ist) $
541-- | Write pretty-printed output to IDESlave with semantic annotations
542ideSlaveReturnAnnotated :: Integer -> Handle -> Doc OutputAnnotation -> Idris ()
543ideSlaveReturnAnnotated n h out = do ist <- getIState
544 (str, spans) <- fmap displaySpans .
546 fmap (fancifyAnnots ist) $
548 let good = [SymbolAtom "ok", toSExp str, toSExp spans]
549 runIO . hPutStrLn h $ convSExp "return" good n
551ihPrintTermWithType :: Handle -> Doc OutputAnnotation -> Doc OutputAnnotation -> Idris ()
552ihPrintTermWithType h tm ty = do ist <- getIState
553 let output = tm <+> colon <+> ty
554 case idris_outputmode ist of
555 RawOutput -> consoleDisplayAnnotated h output
556 IdeSlave n -> ideSlaveReturnAnnotated n h output
558-- | Pretty-print a collection of overloadings to REPL or IDESlave - corresponds to :t name
559ihPrintFunTypes :: Handle -> [(Name, Bool)] -> Name -> [(Name, PTerm)] -> Idris ()
560ihPrintFunTypes h bnd n [] = ihPrintError h $ "No such variable " ++ show n
561ihPrintFunTypes h bnd n overloads = do imp <- impShow
563 let output = vsep (map (uncurry (ppOverload imp)) overloads)
564 case idris_outputmode ist of
565 RawOutput -> consoleDisplayAnnotated h output
566 IdeSlave n -> ideSlaveReturnAnnotated n h output
567 where fullName n = prettyName True bnd n
568 ppOverload imp n tm = fullName n <+> colon <+> align (pprintPTerm imp bnd tm)
570ihRenderResult :: Handle -> Doc OutputAnnotation -> Idris ()
571ihRenderResult h d = do ist <- getIState
572 case idris_outputmode ist of
573 RawOutput -> consoleDisplayAnnotated h d
574 IdeSlave n -> ideSlaveReturnAnnotated n h d
576fancifyAnnots :: IState -> OutputAnnotation -> OutputAnnotation
577fancifyAnnots ist annot@(AnnName n _ _) =
578 do let ctxt = tt_ctxt ist
580 _ | isDConName n ctxt -> AnnName n (Just DataOutput) Nothing
581 _ | isFnName n ctxt -> AnnName n (Just FunOutput) Nothing
582 _ | isTConName n ctxt -> AnnName n (Just TypeOutput) Nothing
583 _ | otherwise -> annot
584fancifyAnnots _ annot = annot
586type1Doc :: Doc OutputAnnotation
587type1Doc = (annotate AnnConstType $ text "Type 1")
589-- | Show an error with semantic highlighting
590ihRenderError :: Handle -> Doc OutputAnnotation -> Idris ()
591ihRenderError h e = do ist <- getIState
592 case idris_outputmode ist of
593 RawOutput -> consoleDisplayAnnotated h e
595 (str, spans) <- fmap displaySpans .
597 fmap (fancifyAnnots ist) $
599 let good = [SymbolAtom "error", toSExp str, toSExp spans]
600 runIO . hPutStrLn h $ convSExp "return" good n
602ihPrintError :: Handle -> String -> Idris ()
603ihPrintError h s = do i <- getIState
604 case idris_outputmode i of
605 RawOutput -> case s of
607 s -> runIO $ hPutStrLn h s
609 let good = SexpList [SymbolAtom "error", toSExp s] in
610 runIO . hPutStrLn h $ convSExp "return" good n
612ihputStrLn :: Handle -> String -> Idris ()
613ihputStrLn h s = do i <- getIState
614 case idris_outputmode i of
615 RawOutput -> runIO $ hPutStrLn h s
616 IdeSlave n -> runIO . hPutStrLn h $ convSExp "write-string" s n
618iputStrLn = ihputStrLn stdout
619iPrintError = ihPrintError stdout
620iPrintResult = ihPrintResult stdout
623ideslavePutSExp :: SExpable a => String -> a -> Idris ()
624ideslavePutSExp cmd info = do i <- getIState
625 case idris_outputmode i of
626 IdeSlave n -> runIO . putStrLn $ convSExp cmd info n
629-- this needs some typing magic and more structured output towards emacs
630iputGoal :: SimpleDoc OutputAnnotation -> Idris ()
631iputGoal g = do i <- getIState
632 case idris_outputmode i of
633 RawOutput -> runIO $ putStrLn (displayDecorated (consoleDecorate i) g)
634 IdeSlave n -> runIO . putStrLn $
635 convSExp "write-goal" (displayS (fmap (fancifyAnnots i) g) "") n
637isetPrompt :: String -> Idris ()
638isetPrompt p = do i <- getIState
639 case idris_outputmode i of
640 IdeSlave n -> runIO . putStrLn $ convSExp "set-prompt" p n
642ihWarn :: Handle -> FC -> Doc OutputAnnotation -> Idris ()
643ihWarn h fc err = do i <- getIState
644 err' <- iRender . fmap (fancifyAnnots i) $ err
645 case idris_outputmode i of
648 hPutStrLn h (show fc ++ ":" ++ displayDecorated (consoleDecorate i) err')
650 do let (str, spans) = displaySpans err'
651 runIO . hPutStrLn h $
652 convSExp "warning" (fc_fname fc, fc_line fc, fc_column fc, str, spans) n
654setLogLevel :: Int -> Idris ()
655setLogLevel l = do i <- getIState
656 let opts = idris_options i
657 let opt' = opts { opt_logLevel = l }
658 putIState $ i { idris_options = opt' }
660setCmdLine :: [Opt] -> Idris ()
661setCmdLine opts = do i <- getIState
662 let iopts = idris_options i
663 putIState $ i { idris_options = iopts { opt_cmdline = opts } }
665getCmdLine :: Idris [Opt]
666getCmdLine = do i <- getIState
667 return (opt_cmdline (idris_options i))
669getDumpDefun :: Idris (Maybe FilePath)
670getDumpDefun = do i <- getIState
671 return $ findC (opt_cmdline (idris_options i))
672 where findC [] = Nothing
673 findC (DumpDefun x : _) = Just x
674 findC (_ : xs) = findC xs
676getDumpCases :: Idris (Maybe FilePath)
677getDumpCases = do i <- getIState
678 return $ findC (opt_cmdline (idris_options i))
679 where findC [] = Nothing
680 findC (DumpCases x : _) = Just x
681 findC (_ : xs) = findC xs
684logLevel = do i <- getIState
685 return (opt_logLevel (idris_options i))
687setErrContext :: Bool -> Idris ()
688setErrContext t = do i <- getIState
689 let opts = idris_options i
690 let opt' = opts { opt_errContext = t }
691 putIState $ i { idris_options = opt' }
693errContext :: Idris Bool
694errContext = do i <- getIState
695 return (opt_errContext (idris_options i))
698useREPL = do i <- getIState
699 return (opt_repl (idris_options i))
701setREPL :: Bool -> Idris ()
702setREPL t = do i <- getIState
703 let opts = idris_options i
704 let opt' = opts { opt_repl = t }
705 putIState $ i { idris_options = opt' }
707showOrigErr :: Idris Bool
708showOrigErr = do i <- getIState
709 return (opt_origerr (idris_options i))
711setShowOrigErr :: Bool -> Idris ()
712setShowOrigErr b = do i <- getIState
713 let opts = idris_options i
714 let opt' = opts { opt_origerr = b }
715 putIState $ i { idris_options = opt' }
717setAutoSolve :: Bool -> Idris ()
718setAutoSolve b = do i <- getIState
719 let opts = idris_options i
720 let opt' = opts { opt_autoSolve = b }
721 putIState $ i { idris_options = opt' }
723setNoBanner :: Bool -> Idris ()
724setNoBanner n = do i <- getIState
725 let opts = idris_options i
726 let opt' = opts { opt_nobanner = n }
727 putIState $ i { idris_options = opt' }
729getNoBanner :: Idris Bool
730getNoBanner = do i <- getIState
731 let opts = idris_options i
732 return (opt_nobanner opts)
734setQuiet :: Bool -> Idris ()
735setQuiet q = do i <- getIState
736 let opts = idris_options i
737 let opt' = opts { opt_quiet = q }
738 putIState $ i { idris_options = opt' }
740getQuiet :: Idris Bool
741getQuiet = do i <- getIState
742 let opts = idris_options i
743 return (opt_quiet opts)
745setCodegen :: Codegen -> Idris ()
746setCodegen t = do i <- getIState
747 let opts = idris_options i
748 let opt' = opts { opt_codegen = t }
749 putIState $ i { idris_options = opt' }
751codegen :: Idris Codegen
752codegen = do i <- getIState
753 return (opt_codegen (idris_options i))
755setOutputTy :: OutputType -> Idris ()
756setOutputTy t = do i <- getIState
757 let opts = idris_options i
758 let opt' = opts { opt_outputTy = t }
759 putIState $ i { idris_options = opt' }
761outputTy :: Idris OutputType
762outputTy = do i <- getIState
763 return $ opt_outputTy $ idris_options i
765setIdeSlave :: Bool -> Idris ()
766setIdeSlave True = do i <- getIState
767 putIState $ i { idris_outputmode = (IdeSlave 0), idris_colourRepl = False }
768setIdeSlave False = return ()
770setTargetTriple :: String -> Idris ()
771setTargetTriple t = do i <- getIState
772 let opts = idris_options i
773 opt' = opts { opt_triple = t }
774 putIState $ i { idris_options = opt' }
776targetTriple :: Idris String
777targetTriple = do i <- getIState
778 return (opt_triple (idris_options i))
780setTargetCPU :: String -> Idris ()
781setTargetCPU t = do i <- getIState
782 let opts = idris_options i
783 opt' = opts { opt_cpu = t }
784 putIState $ i { idris_options = opt' }
786targetCPU :: Idris String
787targetCPU = do i <- getIState
788 return (opt_cpu (idris_options i))
790setOptLevel :: Word -> Idris ()
791setOptLevel t = do i <- getIState
792 let opts = idris_options i
793 opt' = opts { opt_optLevel = t }
794 putIState $ i { idris_options = opt' }
796optLevel :: Idris Word
797optLevel = do i <- getIState
798 return (opt_optLevel (idris_options i))
801verbose = do i <- getIState
802 return (opt_verbose (idris_options i))
804setVerbose :: Bool -> Idris ()
805setVerbose t = do i <- getIState
806 let opts = idris_options i
807 let opt' = opts { opt_verbose = t }
808 putIState $ i { idris_options = opt' }
810typeInType :: Idris Bool
811typeInType = do i <- getIState
812 return (opt_typeintype (idris_options i))
814setTypeInType :: Bool -> Idris ()
815setTypeInType t = do i <- getIState
816 let opts = idris_options i
817 let opt' = opts { opt_typeintype = t }
818 putIState $ i { idris_options = opt' }
820coverage :: Idris Bool
821coverage = do i <- getIState
822 return (opt_coverage (idris_options i))
824setCoverage :: Bool -> Idris ()
825setCoverage t = do i <- getIState
826 let opts = idris_options i
827 let opt' = opts { opt_coverage = t }
828 putIState $ i { idris_options = opt' }
830setIBCSubDir :: FilePath -> Idris ()
831setIBCSubDir fp = do i <- getIState
832 let opts = idris_options i
833 let opt' = opts { opt_ibcsubdir = fp }
834 putIState $ i { idris_options = opt' }
836valIBCSubDir :: IState -> Idris FilePath
837valIBCSubDir i = return (opt_ibcsubdir (idris_options i))
839addImportDir :: FilePath -> Idris ()
840addImportDir fp = do i <- getIState
841 let opts = idris_options i
842 let opt' = opts { opt_importdirs = fp : opt_importdirs opts }
843 putIState $ i { idris_options = opt' }
845setImportDirs :: [FilePath] -> Idris ()
846setImportDirs fps = do i <- getIState
847 let opts = idris_options i
848 let opt' = opts { opt_importdirs = fps }
849 putIState $ i { idris_options = opt' }
851allImportDirs :: Idris [FilePath]
852allImportDirs = do i <- getIState
853 let optdirs = opt_importdirs (idris_options i)
854 return ("." : reverse optdirs)
856colourise :: Idris Bool
857colourise = do i <- getIState
858 return $ idris_colourRepl i
860setColourise :: Bool -> Idris ()
861setColourise b = do i <- getIState
862 putIState $ i { idris_colourRepl = b }
864setOutH :: Handle -> Idris ()
865setOutH h = do i <- getIState
866 putIState $ i { idris_outh = h }
869impShow = do i <- getIState
870 return (opt_showimp (idris_options i))
872setImpShow :: Bool -> Idris ()
873setImpShow t = do i <- getIState
874 let opts = idris_options i
875 let opt' = opts { opt_showimp = t }
876 putIState $ i { idris_options = opt' }
878setColour :: ColourType -> IdrisColour -> Idris ()
879setColour ct c = do i <- getIState
880 let newTheme = setColour' ct c (idris_colourTheme i)
881 putIState $ i { idris_colourTheme = newTheme }
882 where setColour' KeywordColour c t = t { keywordColour = c }
883 setColour' BoundVarColour c t = t { boundVarColour = c }
884 setColour' ImplicitColour c t = t { implicitColour = c }
885 setColour' FunctionColour c t = t { functionColour = c }
886 setColour' TypeColour c t = t { typeColour = c }
887 setColour' DataColour c t = t { dataColour = c }
888 setColour' PromptColour c t = t { promptColour = c }
890logLvl :: Int -> String -> Idris ()
891logLvl l str = do i <- getIState
892 let lvl = opt_logLevel (idris_options i)
894 case idris_outputmode i of
895 RawOutput -> do runIO $ putStrLn str
897 do let good = SexpList [IntegerAtom (toInteger l), toSExp str]
898 runIO $ putStrLn $ convSExp "log" good n
900cmdOptType :: Opt -> Idris Bool
901cmdOptType x = do i <- getIState
902 return $ x `elem` opt_cmdline (idris_options i)
904iLOG :: String -> Idris ()
907noErrors :: Idris Bool
908noErrors = do i <- getIState
910 Nothing -> return True
913setTypeCase :: Bool -> Idris ()
914setTypeCase t = do i <- getIState
915 let opts = idris_options i
916 let opt' = opts { opt_typecase = t }
917 putIState $ i { idris_options = opt' }
920-- Dealing with parameters
922expandParams :: (Name -> Name) -> [(Name, PTerm)] ->
923 [Name] -> -- all names
924 [Name] -> -- names with no declaration
926expandParams dec ps ns infs tm = en tm
928 -- if we shadow a name (say in a lambda binding) that is used in a call to
929 -- a lifted function, we need access to both names - once in the scope of the
930 -- binding and once to call the lifted functions. So we'll explicitly shadow
931 -- it. (Yes, it's a hack. The alternative would be to resolve names earlier
934 mkShadow (UN n) = MN 0 n
935 mkShadow (MN i n) = MN (i+1) n
936 mkShadow (NS x s) = NS (mkShadow x) s
939 | n `elem` (map fst ps ++ ns)
940 = let n' = mkShadow n in
941 PLam n' (en t) (en (shadow n n' s))
942 | otherwise = PLam n (en t) (en s)
944 | n `elem` (map fst ps ++ ns)
945 = let n' = mkShadow n in
946 PPi p n' (en t) (en (shadow n n' s))
947 | otherwise = PPi p n (en t) (en s)
949 | n `elem` (map fst ps ++ ns)
950 = let n' = mkShadow n in
951 PLet n' (en ty) (en v) (en (shadow n n' s))
952 | otherwise = PLet n (en ty) (en v) (en s)
953 -- FIXME: Should only do this in a type signature!
954 en (PDPair f p (PRef f' n) t r)
955 | n `elem` (map fst ps ++ ns) && t /= Placeholder
956 = let n' = mkShadow n in
957 PDPair f p (PRef f' n') (en t) (en (shadow n n' r))
958 en (PEq f l r) = PEq f (en l) (en r)
959 en (PRewrite f l r g) = PRewrite f (en l) (en r) (fmap en g)
960 en (PTyped l r) = PTyped (en l) (en r)
961 en (PPair f p l r) = PPair f p (en l) (en r)
962 en (PDPair f p l t r) = PDPair f p (en l) (en t) (en r)
963 en (PAlternative a as) = PAlternative a (map en as)
964 en (PHidden t) = PHidden (en t)
965 en (PUnifyLog t) = PUnifyLog (en t)
966 en (PDisamb ds t) = PDisamb ds (en t)
967 en (PNoImplicits t) = PNoImplicits (en t)
968 en (PDoBlock ds) = PDoBlock (map (fmap en) ds)
969 en (PProof ts) = PProof (map (fmap en) ts)
970 en (PTactics ts) = PTactics (map (fmap en) ts)
973 | n `nselem` ns = PQuote (Var (dec n))
974 en (PApp fc (PInferRef fc' n) as)
975 | n `nselem` ns = PApp fc (PInferRef fc' (dec n))
976 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
977 en (PApp fc (PRef fc' n) as)
978 | n `elem` infs = PApp fc (PInferRef fc' (dec n))
979 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
980 | n `nselem` ns = PApp fc (PRef fc' (dec n))
981 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
982 en (PAppBind fc (PRef fc' n) as)
983 | n `elem` infs = PAppBind fc (PInferRef fc' (dec n))
984 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
985 | n `nselem` ns = PAppBind fc (PRef fc' (dec n))
986 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
988 | n `elem` infs = PApp fc (PInferRef fc (dec n))
989 (map (pexp . (PRef fc)) (map fst ps))
990 | n `nselem` ns = PApp fc (PRef fc (dec n))
991 (map (pexp . (PRef fc)) (map fst ps))
993 | n `nselem` ns = PApp fc (PInferRef fc (dec n))
994 (map (pexp . (PRef fc)) (map fst ps))
995 en (PApp fc f as) = PApp fc (en f) (map (fmap en) as)
996 en (PAppBind fc f as) = PAppBind fc (en f) (map (fmap en) as)
997 en (PCase fc c os) = PCase fc (en c) (map (pmap en) os)
1001 nselem x (y : xs) | nseq x y = True
1002 | otherwise = nselem x xs
1004 nseq x y = nsroot x == nsroot y
1006expandParamsD :: Bool -> -- True = RHS only
1008 (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PDecl -> PDecl
1009expandParamsD rhsonly ist dec ps ns (PTy doc argdocs syn fc o n ty)
1010 = if n `elem` ns && (not rhsonly)
1011 then -- trace (show (n, expandParams dec ps ns ty)) $
1012 PTy doc argdocs syn fc o (dec n) (piBindp expl_param ps (expandParams dec ps ns [] ty))
1013 else --trace (show (n, expandParams dec ps ns ty)) $
1014 PTy doc argdocs syn fc o n (expandParams dec ps ns [] ty)
1015expandParamsD rhsonly ist dec ps ns (PPostulate doc syn fc o n ty)
1016 = if n `elem` ns && (not rhsonly)
1017 then -- trace (show (n, expandParams dec ps ns ty)) $
1018 PPostulate doc syn fc o (dec n) (piBind ps
1019 (expandParams dec ps ns [] ty))
1020 else --trace (show (n, expandParams dec ps ns ty)) $
1021 PPostulate doc syn fc o n (expandParams dec ps ns [] ty)
1022expandParamsD rhsonly ist dec ps ns (PClauses fc opts n cs)
1023 = let n' = if n `elem` ns then dec n else n in
1024 PClauses fc opts n' (map expandParamsC cs)
1026 expandParamsC (PClause fc n lhs ws rhs ds)
1027 = let -- ps' = updateps True (namesIn ist rhs) (zip ps [0..])
1028 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
1029 lhs' = if rhsonly then lhs else (expandParams dec ps'' ns [] lhs)
1030 n' = if n `elem` ns then dec n else n
1031 -- names bound on the lhs should not be expanded on the rhs
1032 ns' = removeBound lhs ns in
1034 (map (expandParams dec ps'' ns' []) ws)
1035 (expandParams dec ps'' ns' [] rhs)
1036 (map (expandParamsD True ist dec ps'' ns') ds)
1037 expandParamsC (PWith fc n lhs ws wval ds)
1038 = let -- ps' = updateps True (namesIn ist wval) (zip ps [0..])
1039 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
1040 lhs' = if rhsonly then lhs else (expandParams dec ps'' ns [] lhs)
1041 n' = if n `elem` ns then dec n else n
1042 ns' = removeBound lhs ns in
1044 (map (expandParams dec ps'' ns' []) ws)
1045 (expandParams dec ps'' ns' [] wval)
1046 (map (expandParamsD rhsonly ist dec ps'' ns') ds)
1047 updateps yn nm [] = []
1048 updateps yn nm (((a, t), i):as)
1049 | (a `elem` nm) == yn = (a, t) : updateps yn nm as
1050 | otherwise = (sMN i (show n ++ "_u"), t) : updateps yn nm as
1052 removeBound lhs ns = ns \\ nub (bnames lhs)
1054 bnames (PRef _ n) = [n]
1055 bnames (PApp _ _ args) = concatMap bnames (map getTm args)
1056 bnames (PPair _ _ l r) = bnames l ++ bnames r
1057 bnames (PDPair _ _ l Placeholder r) = bnames l ++ bnames r
1060expandParamsD rhs ist dec ps ns (PData doc argDocs syn fc co pd)
1061 = PData doc argDocs syn fc co (expandPData pd)
1063 -- just do the type decl, leave constructors alone (parameters will be
1064 -- added implicitly)
1065 expandPData (PDatadecl n ty cons)
1067 then PDatadecl (dec n) (piBind ps (expandParams dec ps ns [] ty))
1069 else PDatadecl n (expandParams dec ps ns [] ty) (map econ cons)
1070 econ (doc, argDocs, n, t, fc, fs)
1071 = (doc, argDocs, dec n, piBindp impl ps (expandParams dec ps ns [] t), fc, fs)
1072expandParamsD rhs ist dec ps ns (PRecord doc syn fc tn tty cdoc cn cty)
1074 then PRecord doc syn fc (dec tn) (piBind ps (expandParams dec ps ns [] tty))
1076 else PRecord doc syn fc (dec tn) (expandParams dec ps ns [] tty)
1078 where conty = piBindp impl ps (expandParams dec ps ns [] cty)
1079expandParamsD rhs ist dec ps ns (PParams f params pds)
1080 = PParams f (ps ++ map (mapsnd (expandParams dec ps ns [])) params)
1081 (map (expandParamsD True ist dec ps ns) pds)
1082-- (map (expandParamsD ist dec ps ns) pds)
1083expandParamsD rhs ist dec ps ns (PMutual f pds)
1084 = PMutual f (map (expandParamsD rhs ist dec ps ns) pds)
1085expandParamsD rhs ist dec ps ns (PClass doc info f cs n params decls)
1087 (map (expandParams dec ps ns []) cs)
1089 (map (mapsnd (expandParams dec ps ns [])) params)
1090 (map (expandParamsD rhs ist dec ps ns) decls)
1091expandParamsD rhs ist dec ps ns (PInstance info f cs n params ty cn decls)
1093 (map (expandParams dec ps ns []) cs)
1095 (map (expandParams dec ps ns []) params)
1096 (expandParams dec ps ns [] ty)
1098 (map (expandParamsD rhs ist dec ps ns) decls)
1099expandParamsD rhs ist dec ps ns d = d
1101mapsnd f (x, t) = (x, f t)
1103-- Calculate a priority for a type, for deciding elaboration order
1104-- * if it's just a type variable or concrete type, do it early (0)
1105-- * if there's only type variables and injective constructors, do it next (1)
1106-- * if there's a function type, next (2)
1107-- * finally, everything else (3)
1109getPriority :: IState -> PTerm -> Int
1110getPriority i tm = 1 -- pri tm
1113 case lookupP n (tt_ctxt i) of
1114 ((P (DCon _ _) _ _):_) -> 1
1115 ((P (TCon _ _) _ _):_) -> 1
1116 ((P Ref _ _):_) -> 1
1117 [] -> 0 -- must be locally bound, if it's not an error...
1118 pri (PPi _ _ x y) = max 5 (max (pri x) (pri y))
1122 pri (PEq _ l r) = max 1 (max (pri l) (pri r))
1123 pri (PRewrite _ l r _) = max 1 (max (pri l) (pri r))
1124 pri (PApp _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.getTm) as)))
1125 pri (PAppBind _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.getTm) as)))
1126 pri (PCase _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.snd) as)))
1127 pri (PTyped l r) = pri l
1128 pri (PPair _ _ l r) = max 1 (max (pri l) (pri r))
1129 pri (PDPair _ _ l t r) = max 1 (max (pri l) (max (pri t) (pri r)))
1130 pri (PAlternative a as) = maximum (map pri as)
1131 pri (PConstant _) = 0
1136addStatics :: Name -> Term -> PTerm -> Idris ()
1137addStatics n tm ptm =
1138 do let (statics, dynamics) = initStatics tm ptm
1139 let stnames = nub $ concatMap freeArgNames (map snd statics)
1140 let dnames = nub $ concatMap freeArgNames (map snd dynamics)
1141 -- also get the arguments which are 'uniquely inferrable' from
1142 -- statics (see sec 4.2 of "Scrapping Your Inefficient Engine")
1143 let statics' = nub $ map fst statics ++
1144 filter (\x -> not (elem x dnames)) stnames
1145 let stpos = staticList statics' tm
1147 when (not (null statics)) $
1148 logLvl 5 $ show n ++ " " ++ show statics' ++ "\n" ++ show dynamics
1149 ++ "\n" ++ show stnames ++ "\n" ++ show dnames
1150 putIState $ i { idris_statics = addDef n stpos (idris_statics i) }
1151 addIBC (IBCStatic n)
1153 initStatics (Bind n (Pi ty) sc) (PPi p _ _ s)
1154 = let (static, dynamic) = initStatics (instantiate (P Bound n ty) sc) s in
1155 if pstatic p == Static then ((n, ty) : static, dynamic)
1156 else if (not (searchArg p))
1157 then (static, (n, ty) : dynamic)
1158 else (static, dynamic)
1159 initStatics t pt = ([], [])
1161 freeArgNames (Bind n (Pi ty) sc)
1162 = nub $ freeArgNames ty
1163 freeArgNames tm = let (_, args) = unApply tm in
1164 concatMap freeNames args
1166 -- if a name appears in a type class or tactic implicit index, it doesn't
1167 -- affect its 'uniquely inferrable' from a static status since these are
1168 -- resolved by searching.
1169 searchArg (Constraint _ _) = True
1170 searchArg (TacImp _ _ _) = True
1173 staticList sts (Bind n (Pi _) sc) = (n `elem` sts) : staticList sts sc
1176-- Dealing with implicit arguments
1178-- Add constraint bindings from using block
1180addUsingConstraints :: SyntaxInfo -> FC -> PTerm -> Idris PTerm
1181addUsingConstraints syn fc t
1183 let ns = namesIn [] ist t
1184 let cs = getConstraints t -- check declared constraints
1185 let addconsts = uconsts \\ cs
1186 -- if all names in the arguments of addconsts appear in ns,
1187 -- add the constraint implicitly
1188 return (doAdd addconsts ns t)
1189 where uconsts = filter uconst (using syn)
1190 uconst (UConstraint _ _) = True
1194 -- if all of args in ns, then add it
1195 doAdd (UConstraint c args : cs) ns t
1196 | all (\n -> elem n ns) args
1197 = PPi (Constraint [] Dynamic) (sMN 0 "cu")
1198 (mkConst c args) (doAdd cs ns t)
1199 | otherwise = doAdd cs ns t
1201 mkConst c args = PApp fc (PRef fc c)
1202 (map (\n -> PExp 0 [] (PRef fc n)) args)
1204 getConstraints (PPi (Constraint _ _) _ c sc)
1205 = getcapp c ++ getConstraints sc
1206 getConstraints (PPi _ _ c sc) = getConstraints sc
1207 getConstraints _ = []
1209 getcapp (PApp _ (PRef _ c) args)
1210 = do ns <- mapM getName args
1211 return (UConstraint c ns)
1214 getName (PExp _ _ (PRef _ n)) = return n
1217-- Add implicit Pi bindings for any names in the term which appear in an
1218-- argument position.
1220-- This has become a right mess already. Better redo it some time...
1222implicit :: SyntaxInfo -> Name -> PTerm -> Idris PTerm
1223implicit syn n ptm = implicit' syn [] n ptm
1225implicit' :: SyntaxInfo -> [Name] -> Name -> PTerm -> Idris PTerm
1226implicit' syn ignore n ptm
1228 let (tm', impdata) = implicitise syn ignore i ptm
1229-- let (tm'', spos) = findStatics i tm'
1230 putIState $ i { idris_implicits = addDef n impdata (idris_implicits i) }
1232 logLvl 5 ("Implicit " ++ show n ++ " " ++ show impdata)
1234-- putIState $ i { idris_statics = addDef n spos (idris_statics i) }
1237implicitise :: SyntaxInfo -> [Name] -> IState -> PTerm -> (PTerm, [PArg])
1238implicitise syn ignore ist tm = -- trace ("INCOMING " ++ showImp True tm) $
1239 let (declimps, ns') = execState (imps True [] tm) ([], [])
1240 ns = filter (\n -> implicitable n || elem n (map fst uvars)) $
1241 ns' \\ (map fst pvars ++ no_imp syn ++ ignore)
1242 nsOrder = filter (not . inUsing) ns ++ filter inUsing ns in
1244 then (tm, reverse declimps)
1245 else implicitise syn ignore ist (pibind uvars nsOrder tm)
1247 uvars = map ipair (filter uimplicit (using syn))
1248 pvars = syn_params syn
1250 inUsing n = n `elem` map fst uvars
1252 ipair (UImplicit x y) = (x, y)
1253 uimplicit (UImplicit _ _) = True
1256 dropAll (x:xs) ys | x `elem` ys = dropAll xs ys
1257 | otherwise = x : dropAll xs ys
1260 -- Find names in argument position in a type, suitable for implicit
1262 -- Not the function position, but do everything else...
1263 implNamesIn uv (PApp fc f args) = concatMap (implNamesIn uv) (map getTm args)
1264 implNamesIn uv t = namesIn uv ist t
1266 imps top env (PApp _ f as)
1267 = do (decls, ns) <- get
1268 let isn = concatMap (namesIn uvars ist) (map getTm as)
1269 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1270 imps top env (PPi (Imp l _ _) n ty sc)
1271 = do let isn = nub (implNamesIn uvars ty) `dropAll` [n]
1273 put (PImp (getPriority ist ty) True l n Placeholder : decls,
1274 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1275 imps True (n:env) sc
1276 imps top env (PPi (Exp l _ _) n ty sc)
1277 = do let isn = nub (implNamesIn uvars ty ++ case sc of
1278 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1280 (decls, ns) <- get -- ignore decls in HO types
1281 put (PExp (getPriority ist ty) l Placeholder : decls,
1282 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1283 imps True (n:env) sc
1284 imps top env (PPi (Constraint l _) n ty sc)
1285 = do let isn = nub (implNamesIn uvars ty ++ case sc of
1286 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1288 (decls, ns) <- get -- ignore decls in HO types
1289 put (PConstraint 10 l Placeholder : decls,
1290 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1291 imps True (n:env) sc
1292 imps top env (PPi (TacImp l _ scr) n ty sc)
1293 = do let isn = nub (implNamesIn uvars ty ++ case sc of
1294 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
1296 (decls, ns) <- get -- ignore decls in HO types
1297 put (PTacImplicit 10 l n scr Placeholder : decls,
1298 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1299 imps True (n:env) sc
1300 imps top env (PEq _ l r)
1301 = do (decls, ns) <- get
1302 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1303 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1304 imps top env (PRewrite _ l r _)
1305 = do (decls, ns) <- get
1306 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1307 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1308 imps top env (PTyped l r)
1310 imps top env (PPair _ _ l r)
1311 = do (decls, ns) <- get
1312 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1313 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1314 imps top env (PDPair _ _ (PRef _ n) t r)
1315 = do (decls, ns) <- get
1316 let isn = nub (namesIn uvars ist t ++ namesIn uvars ist r) \\ [n]
1317 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1318 imps top env (PDPair _ _ l t r)
1319 = do (decls, ns) <- get
1320 let isn = namesIn uvars ist l ++ namesIn uvars ist t ++
1322 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1323 imps top env (PAlternative a as)
1324 = do (decls, ns) <- get
1325 let isn = concatMap (namesIn uvars ist) as
1326 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1327 imps top env (PLam n ty sc)
1328 = do imps False env ty
1329 imps False (n:env) sc
1330 imps top env (PHidden tm) = imps False env tm
1331 imps top env (PUnifyLog tm) = imps False env tm
1332 imps top env (PNoImplicits tm) = imps False env tm
1333 imps top env _ = return ()
1335 pibind using [] sc = sc
1336 pibind using (n:ns) sc
1337 = case lookup n using of
1338 Just ty -> PPi (Imp [] Dynamic False) n ty (pibind using ns sc)
1339 Nothing -> PPi (Imp [] Dynamic False) n Placeholder
1340 (pibind using ns sc)
1342-- Add implicit arguments in function calls
1343addImplPat :: IState -> PTerm -> PTerm
1344addImplPat = addImpl' True [] []
1346addImplBound :: IState -> [Name] -> PTerm -> PTerm
1347addImplBound ist ns = addImpl' False ns [] ist
1349addImplBoundInf :: IState -> [Name] -> [Name] -> PTerm -> PTerm
1350addImplBoundInf ist ns inf = addImpl' False ns inf ist
1352addImpl :: IState -> PTerm -> PTerm
1353addImpl = addImpl' False [] []
1355-- TODO: in patterns, don't add implicits to function names guarded by constructors
1356-- and *not* inside a PHidden
1358addImpl' :: Bool -> [Name] -> [Name] -> IState -> PTerm -> PTerm
1359addImpl' inpat env infns ist ptm
1360 = mkUniqueNames env (ai (zip env (repeat Nothing)) [] ptm)
1362 ai env ds (PRef fc f)
1363 | f `elem` infns = PInferRef fc f
1364 | not (f `elem` map fst env) = handleErr $ aiFn inpat inpat ist fc f ds []
1365 ai env ds (PHidden (PRef fc f))
1366 | not (f `elem` map fst env) = handleErr $ aiFn inpat False ist fc f ds []
1367 ai env ds (PEq fc l r)
1368 = let l' = ai env ds l
1371 ai env ds (PRewrite fc l r g)
1372 = let l' = ai env ds l
1374 g' = fmap (ai env ds) g in
1375 PRewrite fc l' r' g'
1376 ai env ds (PTyped l r)
1377 = let l' = ai env ds l
1380 ai env ds (PPair fc p l r)
1381 = let l' = ai env ds l
1384 ai env ds (PDPair fc p l t r)
1385 = let l' = ai env ds l
1388 PDPair fc p l' t' r'
1389 ai env ds (PAlternative a as)
1390 = let as' = map (ai env ds) as in
1392 ai env _ (PDisamb ds' as) = ai env ds' as
1393 ai env ds (PApp fc (PInferRef _ f) as)
1394 = let as' = map (fmap (ai env ds)) as in
1395 PApp fc (PInferRef fc f) as'
1396 ai env ds (PApp fc ftm@(PRef _ f) as)
1397 | f `elem` infns = ai env ds (PApp fc (PInferRef fc f) as)
1398 | not (f `elem` map fst env)
1399 = let as' = map (fmap (ai env ds)) as in
1400 handleErr $ aiFn inpat False ist fc f ds as'
1401 | Just (Just ty) <- lookup f env =
1402 let as' = map (fmap (ai env ds)) as
1403 arity = getPArity ty in
1404 mkPApp fc arity ftm as'
1405 ai env ds (PApp fc f as)
1406 = let f' = ai env ds f
1407 as' = map (fmap (ai env ds)) as in
1409 ai env ds (PCase fc c os)
1410 = let c' = ai env ds c
1411 os' = map (pmap (ai env ds)) os in
1413 ai env ds (PLam n ty sc)
1414 = let ty' = ai env ds ty
1415 sc' = ai ((n, Just ty):env) ds sc in
1417 ai env ds (PLet n ty val sc)
1418 = let ty' = ai env ds ty
1419 val' = ai env ds val
1420 sc' = ai ((n, Just ty):env) ds sc in
1422 ai env ds (PPi p n ty sc)
1423 = let ty' = ai env ds ty
1424 sc' = ai ((n, Just ty):env) ds sc in
1426 ai env ds (PGoal fc r n sc)
1427 = let r' = ai env ds r
1428 sc' = ai ((n, Nothing):env) ds sc in
1430 ai env ds (PHidden tm) = PHidden (ai env ds tm)
1431 ai env ds (PProof ts) = PProof (map (fmap (ai env ds)) ts)
1432 ai env ds (PTactics ts) = PTactics (map (fmap (ai env ds)) ts)
1433 ai env ds (PRefl fc tm) = PRefl fc (ai env ds tm)
1434 ai env ds (PUnifyLog tm) = PUnifyLog (ai env ds tm)
1435 ai env ds (PNoImplicits tm) = PNoImplicits (ai env ds tm)
1438 handleErr (Left err) = PElabError err
1439 handleErr (Right x) = x
1441-- if in a pattern, and there are no arguments, and there's no possible
1442-- names with zero explicit arguments, don't add implicits.
1444aiFn :: Bool -> Bool -> IState -> FC -> Name -> [[T.Text]] -> [PArg] -> Either Err PTerm
1445aiFn inpat True ist fc f ds []
1446 = case lookupDef f (tt_ctxt ist) of
1447 [] -> Right $ PPatvar fc f
1448 alts -> let ialts = lookupCtxtName f (idris_implicits ist) in
1449 -- trace (show f ++ " " ++ show (fc, any (all imp) ialts, ialts, any constructor alts)) $
1450 if (not (vname f) || tcname f
1451 || any (conCaf (tt_ctxt ist)) ialts)
1452-- any constructor alts || any allImp ialts))
1453 then aiFn inpat False ist fc f ds [] -- use it as a constructor
1454 else Right $ PPatvar fc f
1455 where imp (PExp _ _ _) = False
1458 allImp xs = all imp xs
1459 constructor (TyDecl (DCon _ _) _) = True
1460 constructor _ = False
1462 conCaf ctxt (n, cia) = isDConName n ctxt && allImp cia
1464 vname (UN n) = True -- non qualified
1467aiFn inpat expat ist fc f ds as
1468 | f `elem` primNames = Right $ PApp fc (PRef fc f) as
1469aiFn inpat expat ist fc f ds as
1470 -- This is where namespaces get resolved by adding PAlternative
1471 = do let ns = lookupCtxtName f (idris_implicits ist)
1472 let nh = filter (\(n, _) -> notHidden n) ns
1473 let ns' = case trimAlts ds nh of
1477 [(f',ns)] -> Right $ mkPApp fc (length ns) (PRef fc f') (insertImpl ns as)
1478 [] -> if f `elem` (map fst (idris_metavars ist))
1479 then Right $ PApp fc (PRef fc f) as
1480 else Right $ mkPApp fc (length as) (PRef fc f) as
1483 map (\(f', ns) -> mkPApp fc (length ns) (PRef fc f')
1484 (insertImpl ns as)) alts
1486 trimAlts [] alts = alts
1488 = filter (\(x, _) -> any (\d -> d `isPrefixOf` nspace x) ns) alts
1493 notHidden n = case getAccessibility n of
1498 = case lookupDefAcc n False (tt_ctxt ist) of
1503 insertImpl :: [PArg] -> [PArg] -> [PArg]
1504 insertImpl (PExp p l ty : ps) (PExp _ _ tm : given) =
1505 PExp p l tm : insertImpl ps given
1506 insertImpl (PConstraint p l ty : ps) (PConstraint _ _ tm : given) =
1507 PConstraint p l tm : insertImpl ps given
1508 insertImpl (PConstraint p l ty : ps) given =
1509 PConstraint p l (PResolveTC fc) : insertImpl ps given
1510 insertImpl (PImp p _ l n ty : ps) given =
1511 case find n given [] of
1512 Just (tm, given') -> PImp p False l n tm : insertImpl ps given'
1513 Nothing -> PImp p True l n Placeholder : insertImpl ps given
1514 insertImpl (PTacImplicit p l n sc' ty : ps) given =
1515 let sc = addImpl ist sc' in
1516 case find n given [] of
1517 Just (tm, given') -> PTacImplicit p l n sc tm : insertImpl ps given'
1519 then PTacImplicit p l n sc Placeholder : insertImpl ps given
1520 else PTacImplicit p l n sc sc : insertImpl ps given
1521 insertImpl expected [] = []
1522 insertImpl _ given = given
1524 find n [] acc = Nothing
1525 find n (PImp _ _ _ n' t : gs) acc
1526 | n == n' = Just (t, reverse acc ++ gs)
1527 find n (PTacImplicit _ _ n' _ t : gs) acc
1528 | n == n' = Just (t, reverse acc ++ gs)
1529 find n (g : gs) acc = find n gs (g : acc)
1531-- replace non-linear occurrences with _
1532-- ASSUMPTION: This is called before adding 'alternatives' because otherwise
1533-- it is hard to get right!
1535stripLinear :: IState -> PTerm -> PTerm
1536stripLinear i tm = evalState (sl tm) [] where
1537 sl :: PTerm -> State [Name] PTerm
1539 | (_:_) <- lookupTy f (tt_ctxt i)
1540 = return $ PRef fc f
1541 | otherwise = do ns <- get
1543 then return Placeholder
1544 else do put (f : ns)
1549 then return Placeholder
1550 else do put (f : ns)
1551 return (PPatvar fc f)
1552 sl t@(PAlternative _ (a : as)) = do sl a
1554 sl (PApp fc fn args) = do fn' <- sl fn
1555 args' <- mapM slA args
1556 return $ PApp fc fn' args'
1557 where slA (PImp p m l n t) = do t' <- sl t
1558 return $ PImp p m l n t'
1559 slA (PExp p l t) = do t' <- sl t
1560 return $ PExp p l t'
1561 slA (PConstraint p l t)
1563 return $ PConstraint p l t'
1564 slA (PTacImplicit p l n sc t)
1566 return $ PTacImplicit p l n sc t'
1569-- Remove functions which aren't applied to anything, which must then
1570-- be resolved by unification. Assume names resolved and alternatives
1571-- filled in (so no ambiguity).
1573stripUnmatchable :: IState -> PTerm -> PTerm
1574stripUnmatchable i (PApp fc fn args) = PApp fc fn (fmap (fmap su) args) where
1575 su :: PTerm -> PTerm
1577 | (Bind n (Pi t) sc :_) <- lookupTy f (tt_ctxt i)
1579 su (PApp fc fn args)
1580 = PApp fc fn (fmap (fmap su) args)
1581 su (PAlternative b alts)
1582 = let alts' = filter (/= Placeholder) (map su alts) in
1583 if null alts' then Placeholder
1584 else PAlternative b alts'
1585 su (PPair fc p l r) = PPair fc p (su l) (su r)
1586 su (PDPair fc p l t r) = PDPair fc p (su l) (su t) (su r)
1588stripUnmatchable i tm = tm
1591mkPApp fc a f as = let rest = drop a as in
1592 appRest fc (PApp fc f (take a as)) rest
1595 appRest fc f (a : as) = appRest fc (PApp fc f [a]) as
1597-- Find 'static' argument positions
1598-- (the declared ones, plus any names in argument position in the declared
1600-- FIXME: It's possible that this really has to happen after elaboration
1602findStatics :: IState -> PTerm -> (PTerm, [Bool])
1603findStatics ist tm = trace (show tm) $
1604 let (ns, ss) = fs tm in
1605 runState (pos ns ss tm) []
1606 where fs (PPi p n t sc)
1607 | Static <- pstatic p
1608 = let (ns, ss) = fs sc in
1609 (namesIn [] ist t : ns, n : ss)
1610 | otherwise = let (ns, ss) = fs sc in
1614 inOne n ns = length (filter id (map (elem n) ns)) == 1
1616 pos ns ss (PPi p n t sc)
1617 | elem n ss = do sc' <- pos ns ss sc
1620 return (PPi (p { pstatic = Static }) n t sc')
1621 | otherwise = do sc' <- pos ns ss sc
1624 return (PPi p n t sc')
1625 pos ns ss t = return t
1627-- for 6.12/7 compatibility
1628data EitherErr a b = LeftErr a | RightOK b
1630instance Monad (EitherErr a) where
1633 (LeftErr e) >>= k = LeftErr e
1634 RightOK v >>= k = k v
1636toEither (LeftErr e) = Left e
1637toEither (RightOK ho) = Right ho
1639-- syntactic match of a against b, returning pair of variables in a
1640-- and what they match. Returns the pair that failed if not a match.
1642matchClause :: IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
1643matchClause = matchClause' False
1645matchClause' :: Bool -> IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
1646matchClause' names i x y = checkRpts $ match (fullApp x) (fullApp y) where
1647 matchArg x y = match (fullApp (getTm x)) (fullApp (getTm y))
1649 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
1652 match' x y = match (fullApp x) (fullApp y)
1653 match (PApp _ (PRef _ (NS (UN fi) [b])) [_,_,x]) x'
1654 | fi == txt "fromInteger" && b == txt "builtins",
1655 PConstant (I _) <- getTm x = match (getTm x) x'
1656 match x' (PApp _ (PRef _ (NS (UN fi) [b])) [_,_,x])
1657 | fi == txt "fromInteger" && b == txt "builtins",
1658 PConstant (I _) <- getTm x = match (getTm x) x'
1659 match (PApp _ (PRef _ (UN l)) [_,x]) x' | l == txt "lazy" = match (getTm x) x'
1660 match x (PApp _ (PRef _ (UN l)) [_,x']) | l == txt "lazy" = match x (getTm x')
1661 match (PApp _ f args) (PApp _ f' args')
1662 | length args == length args'
1663 = do mf <- match' f f'
1664 ms <- zipWithM matchArg args args'
1665 return (mf ++ concat ms)
1666-- match (PRef _ n) (PRef _ n') | n == n' = return []
1667-- | otherwise = Nothing
1668 match (PRef f n) (PApp _ x []) = match (PRef f n) x
1669 match (PPatvar f n) xr = match (PRef f n) xr
1670 match xr (PPatvar f n) = match xr (PRef f n)
1671 match (PApp _ x []) (PRef f n) = match x (PRef f n)
1672 match (PRef _ n) tm@(PRef _ n')
1673 | n == n' && not names &&
1674 (not (isConName n (tt_ctxt i) || isFnName n (tt_ctxt i))
1675 || tm == Placeholder)
1677 | n == n' = return []
1679 | not names && (not (isConName n (tt_ctxt i) ||
1680 isFnName n (tt_ctxt i)) || tm == Placeholder)
1682 match (PEq _ l r) (PEq _ l' r') = do ml <- match' l l'
1685 match (PRewrite _ l r _) (PRewrite _ l' r' _)
1686 = do ml <- match' l l'
1689 match (PTyped l r) (PTyped l' r') = do ml <- match l l'
1692 match (PTyped l r) x = match l x
1693 match x (PTyped l r) = match x l
1694 match (PPair _ _ l r) (PPair _ _ l' r') = do ml <- match' l l'
1697 match (PDPair _ _ l t r) (PDPair _ _ l' t' r') = do ml <- match' l l'
1700 return (ml ++ mt ++ mr)
1701 match (PAlternative a as) (PAlternative a' as')
1702 = do ms <- zipWithM match' as as'
1704 match a@(PAlternative _ as) b
1705 = do let ms = zipWith match' as (repeat b)
1706 case (rights (map toEither ms)) of
1709 match (PCase _ _ _) _ = return [] -- lifted out
1710 match (PMetavar _) _ = return [] -- modified
1711 match (PInferRef _ _) _ = return [] -- modified
1712 match (PQuote _) _ = return []
1713 match (PProof _) _ = return []
1714 match (PTactics _) _ = return []
1715 match (PRefl _ _) (PRefl _ _) = return []
1716 match (PResolveTC _) (PResolveTC _) = return []
1717 match (PTrue _ _) (PTrue _ _) = return []
1718 match (PFalse _) (PFalse _) = return []
1719 match (PReturn _) (PReturn _) = return []
1720 match (PPi _ _ t s) (PPi _ _ t' s') = do mt <- match' t t'
1723 match (PLam _ t s) (PLam _ t' s') = do mt <- match' t t'
1726 match (PLet _ t ty s) (PLet _ t' ty' s') = do mt <- match' t t'
1727 mty <- match' ty ty'
1729 return (mt ++ mty ++ ms)
1730 match (PHidden x) (PHidden y) = match' x y
1731 match (PUnifyLog x) y = match' x y
1732 match x (PUnifyLog y) = match' x y
1733 match (PNoImplicits x) y = match' x y
1734 match x (PNoImplicits y) = match' x y
1735 match Placeholder _ = return []
1736 match _ Placeholder = return []
1737 match (PResolveTC _) _ = return []
1738 match a b | a == b = return []
1739 | otherwise = LeftErr (a, b)
1741 checkRpts (RightOK ms) = check ms where
1743 | Just t' <- lookup n xs = if t/=t' && t/=Placeholder && t'/=Placeholder
1746 check (_:xs) = check xs
1748 checkRpts (LeftErr x) = Left x
1750substMatches :: [(Name, PTerm)] -> PTerm -> PTerm
1751substMatches ms = substMatchesShadow ms []
1753substMatchesShadow :: [(Name, PTerm)] -> [Name] -> PTerm -> PTerm
1754substMatchesShadow [] shs t = t
1755substMatchesShadow ((n,tm):ns) shs t
1756 = substMatchShadow n shs tm (substMatchesShadow ns shs t)
1758substMatch :: Name -> PTerm -> PTerm -> PTerm
1759substMatch n = substMatchShadow n []
1761substMatchShadow :: Name -> [Name] -> PTerm -> PTerm -> PTerm
1762substMatchShadow n shs tm t = sm shs t where
1763 sm xs (PRef _ n') | n == n' = tm
1764 sm xs (PLam x t sc) = PLam x (sm xs t) (sm xs sc)
1765 sm xs (PPi p x t sc)
1767 = let x' = nextName x in
1768 PPi p x' (sm (x':xs) (substMatch x (PRef emptyFC x') t))
1769 (sm (x':xs) (substMatch x (PRef emptyFC x') sc))
1770 | otherwise = PPi p x (sm xs t) (sm (x : xs) sc)
1771 sm xs (PApp f x as) = fullApp $ PApp f (sm xs x) (map (fmap (sm xs)) as)
1772 sm xs (PCase f x as) = PCase f (sm xs x) (map (pmap (sm xs)) as)
1773 sm xs (PEq f x y) = PEq f (sm xs x) (sm xs y)
1774 sm xs (PRewrite f x y tm) = PRewrite f (sm xs x) (sm xs y)
1776 sm xs (PTyped x y) = PTyped (sm xs x) (sm xs y)
1777 sm xs (PPair f p x y) = PPair f p (sm xs x) (sm xs y)
1778 sm xs (PDPair f p x t y) = PDPair f p (sm xs x) (sm xs t) (sm xs y)
1779 sm xs (PAlternative a as) = PAlternative a (map (sm xs) as)
1780 sm xs (PHidden x) = PHidden (sm xs x)
1781 sm xs (PUnifyLog x) = PUnifyLog (sm xs x)
1782 sm xs (PNoImplicits x) = PNoImplicits (sm xs x)
1785 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
1788shadow :: Name -> Name -> PTerm -> PTerm
1789shadow n n' t = sm t where
1790 sm (PRef fc x) | n == x = PRef fc n'
1791 sm (PLam x t sc) | n /= x = PLam x (sm t) (sm sc)
1792 sm (PPi p x t sc) | n /=x = PPi p x (sm t) (sm sc)
1793 sm (PLet x t v sc) | n /= x = PLet x (sm t) (sm v) (sm sc)
1794 sm (PApp f x as) = PApp f (sm x) (map (fmap sm) as)
1795 sm (PAppBind f x as) = PAppBind f (sm x) (map (fmap sm) as)
1796 sm (PCase f x as) = PCase f (sm x) (map (pmap sm) as)
1797 sm (PEq f x y) = PEq f (sm x) (sm y)
1798 sm (PRewrite f x y tm) = PRewrite f (sm x) (sm y) (fmap sm tm)
1799 sm (PTyped x y) = PTyped (sm x) (sm y)
1800 sm (PPair f p x y) = PPair f p (sm x) (sm y)
1801 sm (PDPair f p x t y) = PDPair f p (sm x) (sm t) (sm y)
1802 sm (PAlternative a as) = PAlternative a (map sm as)
1803 sm (PTactics ts) = PTactics (map (fmap sm) ts)
1804 sm (PProof ts) = PProof (map (fmap sm) ts)
1805 sm (PHidden x) = PHidden (sm x)
1806 sm (PUnifyLog x) = PUnifyLog (sm x)
1807 sm (PNoImplicits x) = PNoImplicits (sm x)
1810-- Rename any binders which are repeated (so that we don't have to mess
1811-- about with shadowing anywhere else).
1813mkUniqueNames :: [Name] -> PTerm -> PTerm
1814mkUniqueNames env tm = evalState (mkUniq tm) env where
1815 inScope = boundNamesIn tm
1817 mkUniqA arg = do t' <- mkUniq (getTm arg)
1818 return (arg { getTm = t' })
1820 -- FIXME: Probably ought to do this for completeness! It's fine as
1821 -- long as there are no bindings inside tactics though.
1822 mkUniqT tac = return tac
1824 mkUniq :: PTerm -> State [Name] PTerm
1825 mkUniq (PLam n ty sc)
1829 then do let n' = uniqueName n (env ++ inScope)
1830 return (n', shadow n n' sc)
1835 return $! PLam n' ty' sc''
1836 mkUniq (PPi p n ty sc)
1840 then do let n' = uniqueName n (env ++ inScope)
1841 return (n', shadow n n' sc)
1846 return $! PPi p n' ty' sc''
1847 mkUniq (PLet n ty val sc)
1851 then do let n' = uniqueName n (env ++ inScope)
1852 return (n', shadow n n' sc)
1855 ty' <- mkUniq ty; val' <- mkUniq val
1857 return $! PLet n' ty' val' sc''
1858 mkUniq (PApp fc t args)
1860 args' <- mapM mkUniqA args
1861 return $! PApp fc t' args'
1862 mkUniq (PAppBind fc t args)
1864 args' <- mapM mkUniqA args
1865 return $! PAppBind fc t' args'
1866 mkUniq (PCase fc t alts)
1868 alts' <- mapM (\(x,y)-> do x' <- mkUniq x; y' <- mkUniq y
1869 return (x', y')) alts
1870 return $! PCase fc t' alts'
1871 mkUniq (PPair fc p l r)
1872 = do l' <- mkUniq l; r' <- mkUniq r
1873 return $! PPair fc p l' r'
1874 mkUniq (PDPair fc p (PRef fc' n) t sc)
1877 (n', sc') <- if n `elem` env
1878 then do let n' = uniqueName n (env ++ inScope)
1879 return (n', shadow n n' sc)
1884 return $! PDPair fc p (PRef fc' n') t' sc''
1885 mkUniq (PDPair fc p l t r)
1886 = do l' <- mkUniq l; t' <- mkUniq t; r' <- mkUniq r
1887 return $! PDPair fc p l' t' r'
1888 mkUniq (PAlternative b as)
1889 = liftM (PAlternative b) (mapM mkUniq as)
1890 mkUniq (PHidden t) = liftM PHidden (mkUniq t)
1891 mkUniq (PUnifyLog t) = liftM PUnifyLog (mkUniq t)
1892 mkUniq (PDisamb n t) = liftM (PDisamb n) (mkUniq t)
1893 mkUniq (PNoImplicits t) = liftM PNoImplicits (mkUniq t)
1894 mkUniq (PProof ts) = liftM PProof (mapM mkUniqT ts)
1895 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