on e65d0fa help sign in
Idris-dev/src/Idris/AbsSyntax.hs
2591 lines 110 kB history raw
1{-|
2Module : Idris.AbsSyntax
3Description : Provides Idris' core data definitions and utility code.
5License : BSD3
6Maintainer : The Idris Community.
7-}
9{-# LANGUAGE DeriveFunctor, FlexibleContexts, PatternGuards #-}
10{-# OPTIONS_GHC -fwarn-unused-imports #-}
12module Idris.AbsSyntax(
13 module Idris.AbsSyntax
14 , module Idris.AbsSyntaxTree
15 ) where
17import Idris.AbsSyntaxTree
18import Idris.Colours
19import Idris.Core.Evaluate
20import Idris.Core.TT
21import Idris.Docstrings
22import Idris.IdeMode hiding (Opt(..))
23import Idris.Options
24import IRTS.CodegenCommon
26import System.Directory (canonicalizePath, doesFileExist)
27import System.IO
29import Control.Applicative
30import Control.Monad.State
31import Prelude hiding (Applicative, Foldable, Traversable, (<$>))
33import Data.Either
34import Data.List hiding (insert, union)
35import qualified Data.Map as M
36import Data.Maybe
37import qualified Data.Set as S
38import qualified Data.Text as T
39import System.IO.Error (tryIOError)
41import Data.Generics.Uniplate.Data (descend, descendM)
43import Util.DynamicLinker
44import Util.Pretty
45import Util.System
47getContext :: Idris Context
48getContext = do i <- getIState; return (tt_ctxt i)
50forCodegen :: Codegen -> [(Codegen, a)] -> [a]
51forCodegen tgt xs = [x | (tgt', x) <- xs, eqLang tgt tgt']
52 where
53 eqLang (Via _ x) (Via _ y) = x == y
54 eqLang Bytecode Bytecode = True
55 eqLang _ _ = False
57getObjectFiles :: Codegen -> Idris [FilePath]
58getObjectFiles tgt = do i <- getIState; return (forCodegen tgt $ idris_objs i)
60addObjectFile :: Codegen -> FilePath -> Idris ()
61addObjectFile tgt f = do i <- getIState; putIState $ i { idris_objs = nub $ idris_objs i ++ [(tgt, f)] }
63getLibs :: Codegen -> Idris [String]
64getLibs tgt = do i <- getIState; return (forCodegen tgt $ idris_libs i)
66addLib :: Codegen -> String -> Idris ()
67addLib tgt f = do i <- getIState; putIState $ i { idris_libs = nub $ idris_libs i ++ [(tgt, f)] }
69getFlags :: Codegen -> Idris [String]
70getFlags tgt = do i <- getIState; return (forCodegen tgt $ idris_cgflags i)
72addFlag :: Codegen -> String -> Idris ()
73addFlag tgt f = do i <- getIState; putIState $ i { idris_cgflags = nub $ idris_cgflags i ++ [(tgt, f)] }
75addDyLib :: [String] -> Idris (Either DynamicLib String)
76addDyLib libs = do i <- getIState
77 let ls = idris_dynamic_libs i
78 let importdirs = opt_importdirs (idris_options i)
79 case mapMaybe (findDyLib ls) libs of
80 x:_ -> return (Left x)
81 [] -> do
82 handle <- lift . lift .
83 mapM (\l -> catchIO (tryLoadLib importdirs l)
84 (\_ -> return Nothing)) $ libs
85 case msum handle of
86 Nothing -> return (Right $ "Could not load dynamic alternatives \"" ++
87 intercalate "," libs ++ "\"")
88 Just x -> do putIState $ i { idris_dynamic_libs = x:ls }
89 return (Left x)
90 where findDyLib :: [DynamicLib] -> String -> Maybe DynamicLib
91 findDyLib [] _ = Nothing
92 findDyLib (lib:libs') l | l == lib_name lib = Just lib
93 | otherwise = findDyLib libs' l
95getAutoImports :: Idris [FilePath]
96getAutoImports = do i <- getIState
97 return (opt_autoImport (idris_options i))
99addAutoImport :: FilePath -> Idris ()
100addAutoImport fp = do i <- getIState
101 let opts = idris_options i
102 put (i { idris_options = opts { opt_autoImport =
103 fp : opt_autoImport opts } } )
105addDefinedName :: Name -> Idris ()
106addDefinedName n = do ist <- getIState
107 putIState $ ist { idris_inmodule = S.insert n (idris_inmodule ist) }
109getDefinedNames :: Idris [Name]
110getDefinedNames = do ist <- getIState
111 return (S.toList (idris_inmodule ist))
113addTT :: Term -> Idris (Maybe Term)
114addTT t = do ist <- getIState
115 case M.lookup t (idris_ttstats ist) of
116 Nothing -> do let tt' = M.insert t (1, t) (idris_ttstats ist)
117 putIState $ ist { idris_ttstats = tt' }
118 return Nothing
119 Just (i, t') -> do let tt' = M.insert t' (i + 1, t') (idris_ttstats ist)
120 putIState $ ist { idris_ttstats = tt' }
121 return (Just t')
123dumpTT :: Idris ()
124dumpTT = do ist <- get
125 let sts = sortBy count (M.toList (idris_ttstats ist))
126 mapM_ dump sts
127 return ()
128 where
129 count (_,x) (_,y) = compare y x
130 dump (tm, val) = runIO $ putStrLn (show val ++ ": " ++ show tm)
132addHdr :: Codegen -> String -> Idris ()
133addHdr tgt f = do i <- getIState; putIState $ i { idris_hdrs = nub $ (tgt, f) : idris_hdrs i }
135addImported :: Bool -> FilePath -> Idris ()
136addImported pub f
137 = do i <- getIState
138 putIState $ i { idris_imported = nub $ (f, pub) : idris_imported i }
140addLangExt :: LanguageExt -> Idris ()
141addLangExt e = do i <- getIState
142 putIState $ i {
143 idris_language_extensions = e : idris_language_extensions i
144 }
146dropLangExt :: LanguageExt -> Idris ()
147dropLangExt e = do i <- getIState
148 putIState $ i {
149 idris_language_extensions = idris_language_extensions i \\ [e]
150 }
152-- | Transforms are organised by the function being applied on the lhs
153-- of the transform, to make looking up appropriate transforms quicker
154addTrans :: Name -> (Term, Term) -> Idris ()
155addTrans basefn t
156 = do i <- getIState
157 let t' = case lookupCtxtExact basefn (idris_transforms i) of
158 Just def -> (t : def)
159 Nothing -> [t]
160 putIState $ i { idris_transforms = addDef basefn t'
161 (idris_transforms i) }
163-- | Add transformation rules from a definition, which will reverse the
164-- definition for an error to make it more readable
165addErrRev :: (Term, Term) -> Idris ()
166addErrRev t = do i <- getIState
167 putIState $ i { idris_errRev = t : idris_errRev i }
169-- | Say that the name should always be reduced in error messages, to
170-- help readability/error reflection
171addErrReduce :: Name -> Idris ()
172addErrReduce t = do i <- getIState
173 putIState $ i { idris_errReduce = t : idris_errReduce i }
175addErasureUsage :: Name -> Int -> Idris ()
176addErasureUsage n i = do ist <- getIState
177 putIState $ ist { idris_erasureUsed = (n, i) : idris_erasureUsed ist }
179addExport :: Name -> Idris ()
180addExport n = do ist <- getIState
181 putIState $ ist { idris_exports = n : idris_exports ist }
183addUsedName :: FC -> Name -> Name -> Idris ()
184addUsedName fc n arg
185 = do ist <- getIState
186 case lookupTyName n (tt_ctxt ist) of
187 [(n', ty)] -> addUsage n' 0 ty
188 [] -> throwError (At fc (NoSuchVariable n))
189 xs -> throwError (At fc (CantResolveAlts (map fst xs)))
190 where addUsage n i (Bind x _ sc) | x == arg = do addIBC (IBCUsage (n, i))
191 addErasureUsage n i
192 | otherwise = addUsage n (i + 1) sc
193 addUsage _ _ _ = throwError (At fc (Msg ("No such argument name " ++ show arg)))
195getErasureUsage :: Idris [(Name, Int)]
196getErasureUsage = do ist <- getIState;
197 return (idris_erasureUsed ist)
199getExports :: Idris [Name]
200getExports = do ist <- getIState
201 return (idris_exports ist)
203totcheck :: (FC, Name) -> Idris ()
204totcheck n = do i <- getIState; putIState $ i { idris_totcheck = idris_totcheck i ++ [n] }
206defer_totcheck :: (FC, Name) -> Idris ()
207defer_totcheck n
208 = do i <- getIState;
209 putIState $ i { idris_defertotcheck = nub (idris_defertotcheck i ++ [n]) }
211clear_totcheck :: Idris ()
212clear_totcheck = do i <- getIState; putIState $ i { idris_totcheck = [] }
214setFlags :: Name -> [FnOpt] -> Idris ()
215setFlags n fs = do i <- getIState; putIState $ i { idris_flags = addDef n fs (idris_flags i) }
217addFnOpt :: Name -> FnOpt -> Idris ()
218addFnOpt n f = do i <- getIState
219 let fls = case lookupCtxtExact n (idris_flags i) of
220 Nothing -> []
221 Just x -> x
222 setFlags n (f : fls)
224setFnInfo :: Name -> FnInfo -> Idris ()
225setFnInfo n fs = do i <- getIState; putIState $ i { idris_fninfo = addDef n fs (idris_fninfo i) }
227setAccessibility :: Name -> Accessibility -> Idris ()
228setAccessibility n a
229 = do i <- getIState
230 let ctxt = setAccess n a (tt_ctxt i)
231 putIState $ i { tt_ctxt = ctxt }
233-- | get the accessibility of a name outside this module
234getFromHideList :: Name -> Idris (Maybe Accessibility)
235getFromHideList n = do i <- getIState
236 return $ lookupCtxtExact n (hide_list i)
238setTotality :: Name -> Totality -> Idris ()
239setTotality n a
240 = do i <- getIState
241 let ctxt = setTotal n a (tt_ctxt i)
242 putIState $ i { tt_ctxt = ctxt }
244setInjectivity :: Name -> Injectivity -> Idris ()
245setInjectivity n a
246 = do i <- getIState
247 let ctxt = setInjective n a (tt_ctxt i)
248 putIState $ i { tt_ctxt = ctxt }
250getTotality :: Name -> Idris Totality
251getTotality n
252 = do i <- getIState
253 case lookupTotal n (tt_ctxt i) of
254 [t] -> return t
255 _ -> return (Total [])
257-- Get coercions which might return the required type
258getCoercionsTo :: IState -> Type -> [Name]
259getCoercionsTo i ty =
260 let cs = idris_coercions i
261 (fn,_) = unApply (getRetTy ty) in
262 findCoercions fn cs
263 where findCoercions _ [] = []
264 findCoercions t (n : ns) =
265 let ps = case lookupTy n (tt_ctxt i) of
266 [ty'] -> case unApply (getRetTy (normalise (tt_ctxt i) [] ty')) of
267 (t', _) -> [n | t == t']
268 _ -> [] in
269 ps ++ findCoercions t ns
271addToCG :: Name -> CGInfo -> Idris ()
272addToCG n cg
273 = do i <- getIState
274 putIState $ i { idris_callgraph = addDef n cg (idris_callgraph i) }
276addCalls :: Name -> [Name] -> Idris ()
277addCalls n calls
278 = do i <- getIState
279 case lookupCtxtExact n (idris_callgraph i) of
280 Nothing -> addToCG n (CGInfo calls Nothing [] [])
281 Just (CGInfo cs ans scg used) ->
282 addToCG n (CGInfo (nub (calls ++ cs)) ans scg used)
284addTyInferred :: Name -> Idris ()
285addTyInferred n
286 = do i <- getIState
287 putIState $ i { idris_tyinfodata =
288 addDef n TIPartial (idris_tyinfodata i) }
290addTyInfConstraints :: FC -> [(Term, Term)] -> Idris ()
291addTyInfConstraints fc ts = do logLvl 2 $ "TI missing: " ++ show ts
292 mapM_ addConstraint ts
293 return ()
294 where addConstraint (x, y) = findMVApps x y
296 findMVApps x y
297 = do let (fx, argsx) = unApply x
298 let (fy, argsy) = unApply y
299 if (fx /= fy)
300 then do
301 tryAddMV fx y
302 tryAddMV fy x
303 else mapM_ addConstraint (zip argsx argsy)
305 tryAddMV (P _ mv _) y =
306 do ist <- get
307 case lookup mv (idris_metavars ist) of
308 Just _ -> addConstraintRule mv y
309 _ -> return ()
310 tryAddMV _ _ = return ()
312 addConstraintRule :: Name -> Term -> Idris ()
313 addConstraintRule n t
314 = do ist <- get
315 logLvl 1 $ "TI constraint: " ++ show (n, t)
316 case lookupCtxt n (idris_tyinfodata ist) of
317 [TISolution ts] ->
318 do mapM_ (checkConsistent t) ts
319 let ti' = addDef n (TISolution (t : ts))
320 (idris_tyinfodata ist)
321 put $ ist { idris_tyinfodata = ti' }
322 _ ->
323 do let ti' = addDef n (TISolution [t])
324 (idris_tyinfodata ist)
325 put $ ist { idris_tyinfodata = ti' }
327 -- Check a solution is consistent with previous solutions
328 -- Meaning: If heads are both data types, they had better be the
329 -- same.
330 checkConsistent :: Term -> Term -> Idris ()
331 checkConsistent x y =
332 do let (fx, _) = unApply x
333 let (fy, _) = unApply y
334 case (fx, fy) of
335 (P (TCon _ _) n _, P (TCon _ _) n' _) -> errWhen (n/=n')
336 (P (TCon _ _) n _, Constant _) -> errWhen True
337 (Constant _, P (TCon _ _) n' _) -> errWhen True
338 (P (DCon _ _ _) n _, P (DCon _ _ _) n' _) -> errWhen (n/=n')
339 _ -> return ()
341 where errWhen True
342 = throwError (At fc
343 (CantUnify False (x, Nothing) (y, Nothing) (Msg "") [] 0))
344 errWhen False = return ()
346isTyInferred :: Name -> Idris Bool
347isTyInferred n
348 = do i <- getIState
349 case lookupCtxt n (idris_tyinfodata i) of
350 [TIPartial] -> return True
351 _ -> return False
353-- | Adds error handlers for a particular function and argument. If
354-- names are ambiguous, all matching handlers are updated.
355addFunctionErrorHandlers :: Name -> Name -> [Name] -> Idris ()
356addFunctionErrorHandlers f arg hs =
357 do i <- getIState
358 let oldHandlers = idris_function_errorhandlers i
359 let newHandlers = flip (addDef f) oldHandlers $
360 case lookupCtxtExact f oldHandlers of
361 Nothing -> M.singleton arg (S.fromList hs)
362 Just (oldHandlers) -> M.insertWith S.union arg (S.fromList hs) oldHandlers
363 -- will always be one of those two, thus no extra case
364 putIState $ i { idris_function_errorhandlers = newHandlers }
366-- | Trace all the names in a call graph starting at the given name
367getAllNames :: Name -> Idris [Name]
368getAllNames n = do i <- getIState
369 case getCGAllNames i n of
370 Just ns -> return ns
371 Nothing -> do ns <- allNames [] n
372 addCGAllNames i n ns
373 return ns
375getCGAllNames :: IState -> Name -> Maybe [Name]
376getCGAllNames i n = case lookupCtxtExact n (idris_callgraph i) of
377 Just ci -> allCalls ci
378 _ -> Nothing
380addCGAllNames :: IState -> Name -> [Name] -> Idris ()
381addCGAllNames i n ns
382 = case lookupCtxtExact n (idris_callgraph i) of
383 Just ci -> addToCG n (ci { allCalls = Just ns })
384 _ -> addToCG n (CGInfo [] (Just ns) [] [])
386allNames :: [Name] -> Name -> Idris [Name]
387allNames ns n | n `elem` ns = return []
388allNames ns n = do i <- getIState
389 case getCGAllNames i n of
390 Just ns -> return ns
391 Nothing -> case lookupCtxtExact n (idris_callgraph i) of
392 Just ci ->
393 do more <- mapM (allNames (n:ns)) (calls ci)
394 let ns' = nub (n : concat more)
395 addCGAllNames i n ns'
396 return ns'
397 _ -> return [n]
399addCoercion :: Name -> Idris ()
400addCoercion n = do i <- getIState
401 putIState $ i { idris_coercions = nub $ n : idris_coercions i }
403addDocStr :: Name -> Docstring DocTerm -> [(Name, Docstring DocTerm)] -> Idris ()
404addDocStr n doc args
405 = do i <- getIState
406 putIState $ i { idris_docstrings = addDef n (doc, args) (idris_docstrings i) }
408addNameHint :: Name -> Name -> Idris ()
409addNameHint ty n
410 = do i <- getIState
411 ty' <- case lookupCtxtName ty (idris_implicits i) of
412 [(tyn, _)] -> return tyn
413 [] -> throwError (NoSuchVariable ty)
414 tyns -> throwError (CantResolveAlts (map fst tyns))
415 let ns' = case lookupCtxt ty' (idris_namehints i) of
416 [ns] -> ns ++ [n]
417 _ -> [n]
418 putIState $ i { idris_namehints = addDef ty' ns' (idris_namehints i) }
420getNameHints :: IState -> Name -> [Name]
421getNameHints _ (UN arr) | arr == txt "->" = [sUN "f",sUN "g"]
422getNameHints i n =
423 case lookupCtxt n (idris_namehints i) of
424 [ns] -> ns
425 _ -> []
427addDeprecated :: Name -> String -> Idris ()
428addDeprecated n reason = do
429 i <- getIState
430 putIState $ i { idris_deprecated = addDef n reason (idris_deprecated i) }
432getDeprecated :: Name -> Idris (Maybe String)
433getDeprecated n = do
434 i <- getIState
435 return $ lookupCtxtExact n (idris_deprecated i)
437addFragile :: Name -> String -> Idris ()
438addFragile n reason = do
439 i <- getIState
440 putIState $ i { idris_fragile = addDef n reason (idris_fragile i) }
442getFragile :: Name -> Idris (Maybe String)
443getFragile n = do
444 i <- getIState
445 return $ lookupCtxtExact n (idris_fragile i)
447push_estack :: Name -> Bool -> Idris ()
448push_estack n implementation
449 = do i <- getIState
450 putIState (i { elab_stack = (n, implementation) : elab_stack i })
452pop_estack :: Idris ()
453pop_estack = do i <- getIState
454 putIState (i { elab_stack = ptail (elab_stack i) })
455 where ptail [] = []
456 ptail (_ : xs) = xs
458-- | Add an interface implementation function.
459--
460-- Precondition: the implementation should have the correct type.
461--
462-- Dodgy hack 1: Put integer implementations first in the list so they are
463-- resolved by default.
464--
465-- Dodgy hack 2: put constraint chasers (ParentN) last
466addImplementation :: Bool -- ^ whether the name is an Integer implementation
467 -> Bool -- ^ whether to include the implementation in implementation search
468 -> Name -- ^ the name of the interface
469 -> Name -- ^ the name of the implementation
470 -> Idris ()
471addImplementation int res n i
472 = do ist <- getIState
473 case lookupCtxt n (idris_interfaces ist) of
474 [CI a b c d e f g ins fds] ->
475 do let cs = addDef n (CI a b c d e f g (addI i ins) fds) (idris_interfaces ist)
476 putIState $ ist { idris_interfaces = cs }
477 _ -> do let cs = addDef n (CI (sMN 0 "none") [] [] [] [] [] [] [(i, res)] []) (idris_interfaces ist)
478 putIState $ ist { idris_interfaces = cs }
479 where addI, insI :: Name -> [(Name, Bool)] -> [(Name, Bool)]
480 addI i ins | int = (i, res) : ins
481 | chaser n = ins ++ [(i, res)]
482 | otherwise = insI i ins
483 insI i [] = [(i, res)]
484 insI i (n : ns) | chaser (fst n) = (i, res) : n : ns
485 | otherwise = n : insI i ns
487 chaser (SN (ParentN _ _)) = True
488 chaser (NS n _) = chaser n
489 chaser _ = False
491-- | Add a privileged implementation - one which implementation search will
492-- happily resolve immediately if it is type correct This is used for
493-- naming parent implementations when defining an implementation with
494-- constraints. Returns the old list, so we can revert easily at the
495-- end of a block
496addOpenImpl :: [Name] -> Idris [Name]
497addOpenImpl ns = do ist <- getIState
498 ns' <- mapM (checkValid ist) ns
499 let open = idris_openimpls ist
500 putIState $ ist { idris_openimpls = nub (ns' ++ open) }
501 return open
502 where
503 checkValid ist n
504 = case lookupCtxtName n (idris_implicits ist) of
505 [(n', _)] -> return n'
506 [] -> throwError (NoSuchVariable n)
507 more -> throwError (CantResolveAlts (map fst more))
509setOpenImpl :: [Name] -> Idris ()
510setOpenImpl ns = do ist <- getIState
511 putIState $ ist { idris_openimpls = ns }
513getOpenImpl :: Idris [Name]
514getOpenImpl = do ist <- getIState
515 return (idris_openimpls ist)
517addInterface :: Name -> InterfaceInfo -> Idris ()
518addInterface n i
519 = do ist <- getIState
520 let i' = case lookupCtxt n (idris_interfaces ist) of
521 [c] -> i { interface_implementations = interface_implementations c ++
522 interface_implementations i }
523 _ -> i
524 putIState $ ist { idris_interfaces = addDef n i' (idris_interfaces ist) }
526updateIMethods :: Name -> [(Name, PTerm)] -> Idris ()
527updateIMethods n meths
528 = do ist <- getIState
529 let i = case lookupCtxtExact n (idris_interfaces ist) of
530 Just c -> c { interface_methods = update (interface_methods c) }
531 Nothing -> error "Can't happen updateIMethods"
532 putIState $ ist { idris_interfaces = addDef n i (idris_interfaces ist) }
533 where
534 update [] = []
535 update (m@(n, (b, opts, t)) : rest)
536 | Just ty <- lookup n meths
537 = (n, (b, opts, ty)) : update rest
538 | otherwise = m : update rest
540addRecord :: Name -> RecordInfo -> Idris ()
541addRecord n ri = do ist <- getIState
542 putIState $ ist { idris_records = addDef n ri (idris_records ist) }
544addAutoHint :: Name -> Name -> Idris ()
545addAutoHint n hint =
546 do ist <- getIState
547 case lookupCtxtExact n (idris_autohints ist) of
548 Nothing ->
549 do let hs = addDef n [hint] (idris_autohints ist)
550 putIState $ ist { idris_autohints = hs }
551 Just nhints ->
552 do let hs = addDef n (hint : nhints) (idris_autohints ist)
553 putIState $ ist { idris_autohints = hs }
555getAutoHints :: Name -> Idris [Name]
556getAutoHints n = do ist <- getIState
557 case lookupCtxtExact n (idris_autohints ist) of
558 Nothing -> return []
559 Just ns -> return ns
561addIBC :: IBCWrite -> Idris ()
562addIBC ibc@(IBCDef n)
563 = do i <- getIState
564 when (notDef (ibc_write i)) $
565 putIState $ i { ibc_write = ibc : ibc_write i }
566 where notDef [] = True
567 notDef (IBCDef n': _) | n == n' = False
568 notDef (_ : is) = notDef is
569addIBC ibc = do i <- getIState; putIState $ i { ibc_write = ibc : ibc_write i }
571clearIBC :: Idris ()
572clearIBC = do i <- getIState; putIState $ i { ibc_write = [],
573 idris_inmodule = S.empty }
575resetNameIdx :: Idris ()
576resetNameIdx = do i <- getIState
577 put (i { idris_nameIdx = (0, emptyContext) })
579-- | Used to preserve sharing of names
580addNameIdx :: Name -> Idris (Int, Name)
581addNameIdx n = do i <- getIState
582 let (i', x) = addNameIdx' i n
583 putIState i'
584 return x
586addNameIdx' :: IState -> Name -> (IState, (Int, Name))
587addNameIdx' i n
588 = let idxs = snd (idris_nameIdx i) in
589 case lookupCtxt n idxs of
590 [x] -> (i, x)
591 _ -> let i' = fst (idris_nameIdx i) + 1 in
592 (i { idris_nameIdx = (i', addDef n (i', n) idxs) }, (i', n))
594getSymbol :: Name -> Idris Name
595getSymbol n = do i <- getIState
596 case M.lookup n (idris_symbols i) of
597 Just n' -> return n'
598 Nothing -> do let sym' = M.insert n n (idris_symbols i)
599 put (i { idris_symbols = sym' })
600 return n
602getHdrs :: Codegen -> Idris [String]
603getHdrs tgt = do i <- getIState; return (forCodegen tgt $ idris_hdrs i)
605getImported :: Idris [(FilePath, Bool)]
606getImported = idris_imported `fmap` getIState
608setErrSpan :: FC -> Idris ()
609setErrSpan x = do i <- getIState;
610 case (errSpan i) of
611 Nothing -> putIState $ i { errSpan = Just x }
612 Just _ -> return ()
614clearErr :: Idris ()
615clearErr = do i <- getIState
616 putIState $ i { errSpan = Nothing }
618getSO :: Idris (Maybe String)
619getSO = do i <- getIState
620 return (compiled_so i)
622setSO :: Maybe String -> Idris ()
623setSO s = do i <- getIState
624 putIState (i { compiled_so = s })
626getIState :: Idris IState
627getIState = get
629putIState :: IState -> Idris ()
630putIState = put
632updateIState :: (IState -> IState) -> Idris ()
633updateIState f = do i <- getIState
634 putIState $ f i
636withContext :: (IState -> Ctxt a) -> Name -> b -> (a -> Idris b) -> Idris b
637withContext ctx name dflt action = do
638 ist <- getIState
639 case lookupCtxt name (ctx ist) of
640 [x] -> action x
641 _ -> return dflt
643withContext_ :: (IState -> Ctxt a) -> Name -> (a -> Idris ()) -> Idris ()
644withContext_ ctx name action = withContext ctx name () action
646-- | A version of liftIO that puts errors into the exception type of
647-- the Idris monad
648runIO :: IO a -> Idris a
649runIO x = liftIO (tryIOError x) >>= either (throwError . Msg . show) return
650-- TODO: create specific Idris exceptions for specific IO errors such as "openFile: does not exist"
651--
652-- Issue #1738 on the issue tracker.
653-- https://github.com/idris-lang/Idris-dev/issues/1738
655getName :: Idris Int
656getName = do i <- getIState;
657 let idx = idris_name i;
658 putIState (i { idris_name = idx + 1 })
659 return idx
661-- | InternalApp keeps track of the real function application for
662-- making case splits from, not the application the programmer wrote,
663-- which doesn't have the whole context in any case other than top
664-- level definitions
665addInternalApp :: FilePath -> Int -> PTerm -> Idris ()
666addInternalApp fp l t
667 = do i <- getIState
668 -- We canonicalise the path to make "./Test/Module.idr" equal
669 -- to "Test/Module.idr"
670 exists <- runIO $ doesFileExist fp
671 when exists $
672 do fp' <- runIO $ canonicalizePath fp
673 putIState (i { idris_lineapps = ((fp', l), t) : idris_lineapps i })
675getInternalApp :: FilePath -> Int -> Idris PTerm
676getInternalApp fp l = do i <- getIState
677 -- We canonicalise the path to make
678 -- "./Test/Module.idr" equal to
679 -- "Test/Module.idr"
680 exists <- runIO $ doesFileExist fp
681 if exists
682 then do fp' <- runIO $ canonicalizePath fp
683 case lookup (fp', l) (idris_lineapps i) of
684 Just n' -> return n'
685 Nothing -> return Placeholder
686 -- TODO: What if it's not there?
687 else return Placeholder
689-- | Pattern definitions are only used for coverage checking, so erase
690-- them when we're done
691clearOrigPats :: Idris ()
692clearOrigPats = do i <- get
693 let ps = idris_patdefs i
694 let ps' = mapCtxt (\ (_,miss) -> ([], miss)) ps
695 put (i { idris_patdefs = ps' })
697-- | Erase types from Ps in the context (basically ending up with
698-- what's in the .ibc, which is all we need after all the analysis is
699-- done)
700clearPTypes :: Idris ()
701clearPTypes = do i <- get
702 let ctxt = tt_ctxt i
703 put (i { tt_ctxt = mapDefCtxt pErase ctxt })
704 where pErase (CaseOp c t tys orig _ cds)
705 = CaseOp c t tys orig [] (pErase' cds)
706 pErase x = x
707 pErase' (CaseDefs (cs, c) rs)
708 = let c' = (cs, fmap pEraseType c) in
709 CaseDefs c' rs
711checkUndefined :: FC -> Name -> Idris ()
712checkUndefined fc n
713 = do i <- getContext
714 case lookupTy n i of
715 (_:_) -> throwError . Msg $ show fc ++ ":" ++
716 show n ++ " already defined"
717 _ -> return ()
719isUndefined :: FC -> Name -> Idris Bool
720isUndefined _ n
721 = do i <- getContext
722 case lookupTyExact n i of
723 Just _ -> return False
724 _ -> return True
726setContext :: Context -> Idris ()
727setContext ctxt = do i <- getIState; putIState (i { tt_ctxt = ctxt } )
729updateContext :: (Context -> Context) -> Idris ()
730updateContext f = do i <- getIState; putIState (i { tt_ctxt = f (tt_ctxt i) } )
732addConstraints :: FC -> (Int, [UConstraint]) -> Idris ()
733addConstraints fc (v, cs)
734 = do tit <- typeInType
735 when (not tit) $ do
736 i <- getIState
737 let ctxt = tt_ctxt i
738 let ctxt' = ctxt { next_tvar = v }
739 let ics = insertAll (zip cs (repeat fc)) (idris_constraints i)
740 putIState $ i { tt_ctxt = ctxt', idris_constraints = ics }
741 where
742 insertAll [] c = c
743 insertAll ((ULE (UVal 0) _, fc) : cs) ics = insertAll cs ics
744 insertAll ((ULE x y, fc) : cs) ics | x == y = insertAll cs ics
745 insertAll ((c, fc) : cs) ics
746 = insertAll cs $ S.insert (ConstraintFC c fc) ics
748addDeferred = addDeferred' Ref
749addDeferredTyCon = addDeferred' (TCon 0 0)
751-- | Save information about a name that is not yet defined
752addDeferred' :: NameType
753 -> [(Name, (Int, Maybe Name, Type, [Name], Bool, Bool))]
754 -- ^ The Name is the name being made into a metavar,
755 -- the Int is the number of vars that are part of a
756 -- putative proof context, the Maybe Name is the
757 -- top-level function containing the new metavariable,
758 -- the Type is its type, and the Bool is whether :p is
759 -- allowed
760 -> Idris ()
761addDeferred' nt ns
762 = do mapM_ (\(n, (i, _, t, _, _, _)) -> updateContext (addTyDecl n nt (tidyNames S.empty t))) ns
763 mapM_ (\(n, _) -> when (not (n `elem` primDefs)) $ addIBC (IBCMetavar n)) ns
764 i <- getIState
765 putIState $ i { idris_metavars = map (\(n, (i, top, _, ns, isTopLevel, isDefinable)) ->
766 (n, (top, i, ns, isTopLevel, isDefinable))) ns ++
767 idris_metavars i }
768 where
769 -- 'tidyNames' is to generate user accessible names in case they are
770 -- needed in tactic scripts
771 tidyNames used (Bind (MN i x) b sc)
772 = let n' = uniqueNameSet (UN x) used in
773 Bind n' b $ tidyNames (S.insert n' used) sc
774 tidyNames used (Bind n b sc)
775 = let n' = uniqueNameSet n used in
776 Bind n' b $ tidyNames (S.insert n' used) sc
777 tidyNames _ b = b
779solveDeferred :: FC -> Name -> Idris ()
780solveDeferred fc n
781 = do i <- getIState
782 case lookup n (idris_metavars i) of
783 Just (_, _, _, _, False) ->
784 throwError $ At fc $ Msg ("Can't define hole " ++ show n ++ " as it depends on other holes")
785 _ -> putIState $ i { idris_metavars =
786 filter (\(n', _) -> n/=n')
787 (idris_metavars i),
788 ibc_write =
789 filter (notMV n) (ibc_write i)
790 }
791 where notMV n (IBCMetavar n') = not (n == n')
792 notMV n _ = True
794getUndefined :: Idris [Name]
795getUndefined = do i <- getIState
796 return (map fst (idris_metavars i) \\ primDefs)
798isMetavarName :: Name -> IState -> Bool
799isMetavarName n ist
800 = case lookupNames n (tt_ctxt ist) of
801 (t:_) -> isJust $ lookup t (idris_metavars ist)
802 _ -> False
804getWidth :: Idris ConsoleWidth
805getWidth = fmap idris_consolewidth getIState
807setWidth :: ConsoleWidth -> Idris ()
808setWidth w = do ist <- getIState
809 put ist { idris_consolewidth = w }
811setDepth :: Maybe Int -> Idris ()
812setDepth d = do ist <- getIState
813 put ist { idris_options = (idris_options ist) { opt_printdepth = d } }
815typeDescription :: String
816typeDescription = "The type of types"
819type1Doc :: Doc OutputAnnotation
820type1Doc = (annotate (AnnType "Type" "The type of types, one level up") $ text "Type 1")
823isetPrompt :: String -> Idris ()
824isetPrompt p = do i <- getIState
825 case idris_outputmode i of
826 IdeMode n h -> runIO . hPutStrLn h $ convSExp "set-prompt" p n
828-- | Tell clients how much was parsed and loaded
829isetLoadedRegion :: Idris ()
830isetLoadedRegion = do i <- getIState
831 let span = idris_parsedSpan i
832 case span of
833 Just fc ->
834 case idris_outputmode i of
835 IdeMode n h ->
836 runIO . hPutStrLn h $
837 convSExp "set-loaded-region" fc n
838 Nothing -> return ()
840setLogLevel :: Int -> Idris ()
841setLogLevel l = do i <- getIState
842 let opts = idris_options i
843 let opt' = opts { opt_logLevel = l }
844 putIState $ i { idris_options = opt' }
846setLogCats :: [LogCat] -> Idris ()
847setLogCats cs = do
848 i <- getIState
849 let opts = idris_options i
850 let opt' = opts { opt_logcats = cs }
851 putIState $ i { idris_options = opt' }
853setCmdLine :: [Opt] -> Idris ()
854setCmdLine opts = do i <- getIState
855 let iopts = idris_options i
856 putIState $ i { idris_options = iopts { opt_cmdline = opts } }
858getCmdLine :: Idris [Opt]
859getCmdLine = do i <- getIState
860 return (opt_cmdline (idris_options i))
862getDumpHighlighting :: Idris Bool
863getDumpHighlighting = do ist <- getIState
864 return (findC (opt_cmdline (idris_options ist)))
865 where findC = elem DumpHighlights
867getDumpDefun :: Idris (Maybe FilePath)
868getDumpDefun = do i <- getIState
869 return $ findC (opt_cmdline (idris_options i))
870 where findC [] = Nothing
871 findC (DumpDefun x : _) = Just x
872 findC (_ : xs) = findC xs
874getDumpCases :: Idris (Maybe FilePath)
875getDumpCases = do i <- getIState
876 return $ findC (opt_cmdline (idris_options i))
877 where findC [] = Nothing
878 findC (DumpCases x : _) = Just x
879 findC (_ : xs) = findC xs
881logLevel :: Idris Int
882logLevel = do i <- getIState
883 return (opt_logLevel (idris_options i))
885setAutoImpls :: Bool -> Idris ()
886setAutoImpls b = do i <- getIState
887 let opts = idris_options i
888 let opt' = opts { opt_autoimpls = b }
889 putIState $ i { idris_options = opt' }
891getAutoImpls :: Idris Bool
892getAutoImpls = do i <- getIState
893 return (opt_autoimpls (idris_options i))
895setErrContext :: Bool -> Idris ()
896setErrContext t = do i <- getIState
897 let opts = idris_options i
898 let opts' = opts { opt_errContext = t }
899 putIState $ i { idris_options = opts' }
901errContext :: Idris Bool
902errContext = do i <- getIState
903 return (opt_errContext (idris_options i))
905getOptimise :: Idris [Optimisation]
906getOptimise = do i <- getIState
907 return (opt_optimise (idris_options i))
909setOptimise :: [Optimisation] -> Idris ()
910setOptimise newopts = do i <- getIState
911 let opts = idris_options i
912 let opts' = opts { opt_optimise = newopts }
913 putIState $ i { idris_options = opts' }
915addOptimise :: Optimisation -> Idris ()
916addOptimise opt = do opts <- getOptimise
917 setOptimise (nub (opt : opts))
919removeOptimise :: Optimisation -> Idris ()
920removeOptimise opt = do opts <- getOptimise
921 setOptimise ((nub opts) \\ [opt])
923-- | Set appropriate optimisation set for the given level. We only
924-- have one optimisation that is configurable at the moment, however!
925setOptLevel :: Int -> Idris ()
926setOptLevel n | n <= 0 = setOptimise []
927setOptLevel 1 = setOptimise []
928setOptLevel 2 = setOptimise [PETransform]
929setOptLevel n | n >= 3 = setOptimise [PETransform]
931useREPL :: Idris Bool
932useREPL = do i <- getIState
933 return (opt_repl (idris_options i))
935setREPL :: Bool -> Idris ()
936setREPL t = do i <- getIState
937 let opts = idris_options i
938 let opt' = opts { opt_repl = t }
939 putIState $ i { idris_options = opt' }
941showOrigErr :: Idris Bool
942showOrigErr = do i <- getIState
943 return (opt_origerr (idris_options i))
945setShowOrigErr :: Bool -> Idris ()
946setShowOrigErr b = do i <- getIState
947 let opts = idris_options i
948 let opt' = opts { opt_origerr = b }
949 putIState $ i { idris_options = opt' }
951setAutoSolve :: Bool -> Idris ()
952setAutoSolve b = do i <- getIState
953 let opts = idris_options i
954 let opt' = opts { opt_autoSolve = b }
955 putIState $ i { idris_options = opt' }
957setNoBanner :: Bool -> Idris ()
958setNoBanner n = do i <- getIState
959 let opts = idris_options i
960 let opt' = opts { opt_nobanner = n }
961 putIState $ i { idris_options = opt' }
963getNoBanner :: Idris Bool
964getNoBanner = do i <- getIState
965 let opts = idris_options i
966 return (opt_nobanner opts)
968setEvalTypes :: Bool -> Idris ()
969setEvalTypes n = do i <- getIState
970 let opts = idris_options i
971 let opt' = opts { opt_evaltypes = n }
972 putIState $ i { idris_options = opt' }
974getDesugarNats :: Idris Bool
975getDesugarNats = do i <- getIState
976 let opts = idris_options i
977 return (opt_desugarnats opts)
980setDesugarNats :: Bool -> Idris ()
981setDesugarNats n = do i <- getIState
982 let opts = idris_options i
983 let opt' = opts { opt_desugarnats = n }
984 putIState $ i { idris_options = opt' }
986setQuiet :: Bool -> Idris ()
987setQuiet q = do i <- getIState
988 let opts = idris_options i
989 let opt' = opts { opt_quiet = q }
990 putIState $ i { idris_options = opt' }
992getQuiet :: Idris Bool
993getQuiet = do i <- getIState
994 let opts = idris_options i
995 return (opt_quiet opts)
997setCodegen :: Codegen -> Idris ()
998setCodegen t = do i <- getIState
999 let opts = idris_options i
1000 let opt' = opts { opt_codegen = t }
1001 putIState $ i { idris_options = opt' }
1003codegen :: Idris Codegen
1004codegen = do i <- getIState
1005 return (opt_codegen (idris_options i))
1008setOutputTy :: OutputType -> Idris ()
1009setOutputTy t = do i <- getIState
1010 let opts = idris_options i
1011 let opt' = opts { opt_outputTy = t }
1012 putIState $ i { idris_options = opt' }
1014outputTy :: Idris OutputType
1015outputTy = do i <- getIState
1016 return $ opt_outputTy $ idris_options i
1018setIdeMode :: Bool -> Handle -> Idris ()
1019setIdeMode True h = do i <- getIState
1020 putIState $ i { idris_outputmode = IdeMode 0 h
1021 , idris_colourRepl = False
1023setIdeMode False _ = return ()
1025setTargetTriple :: String -> Idris ()
1026setTargetTriple t = do i <- getIState
1027 let opts = idris_options i
1028 opt' = opts { opt_triple = t }
1029 putIState $ i { idris_options = opt' }
1031targetTriple :: Idris String
1032targetTriple = do i <- getIState
1033 return (opt_triple (idris_options i))
1035setTargetCPU :: String -> Idris ()
1036setTargetCPU t = do i <- getIState
1037 let opts = idris_options i
1038 opt' = opts { opt_cpu = t }
1039 putIState $ i { idris_options = opt' }
1041targetCPU :: Idris String
1042targetCPU = do i <- getIState
1043 return (opt_cpu (idris_options i))
1045verbose :: Idris Int
1046verbose = do
1047 i <- getIState
1048 -- Quietness overrides verbosity
1049 let quiet = opt_quiet $ idris_options i
1050 if quiet
1051 then return $ 0
1052 else return $ (opt_verbose $ idris_options i)
1054setVerbose :: Int -> Idris ()
1055setVerbose t = do
1056 i <- getIState
1057 let opts = idris_options i
1058 let opt' = opts { opt_verbose = t }
1059 putIState $ i { idris_options = opt' }
1061iReport :: Int -> String -> Idris ()
1062iReport level msg = do
1063 verbosity <- verbose
1064 i <- getIState
1065 when (level <= verbosity) $
1066 case idris_outputmode i of
1067 RawOutput h -> runIO $ hPutStrLn h msg
1068 IdeMode n h -> runIO . hPutStrLn h $ convSExp "write-string" msg n
1069 return ()
1071typeInType :: Idris Bool
1072typeInType = do i <- getIState
1073 return (opt_typeintype (idris_options i))
1075setTypeInType :: Bool -> Idris ()
1076setTypeInType t = do i <- getIState
1077 let opts = idris_options i
1078 let opt' = opts { opt_typeintype = t }
1079 putIState $ i { idris_options = opt' }
1081coverage :: Idris Bool
1082coverage = do i <- getIState
1083 return (opt_coverage (idris_options i))
1085setCoverage :: Bool -> Idris ()
1086setCoverage t = do i <- getIState
1087 let opts = idris_options i
1088 let opt' = opts { opt_coverage = t }
1089 putIState $ i { idris_options = opt' }
1091setIBCSubDir :: FilePath -> Idris ()
1092setIBCSubDir fp = do i <- getIState
1093 let opts = idris_options i
1094 let opt' = opts { opt_ibcsubdir = fp }
1095 putIState $ i { idris_options = opt' }
1097valIBCSubDir :: IState -> Idris FilePath
1098valIBCSubDir i = return (opt_ibcsubdir (idris_options i))
1100addImportDir :: FilePath -> Idris ()
1101addImportDir fp = do i <- getIState
1102 let opts = idris_options i
1103 let opt' = opts { opt_importdirs = nub $ fp : opt_importdirs opts }
1104 putIState $ i { idris_options = opt' }
1106setImportDirs :: [FilePath] -> Idris ()
1107setImportDirs fps = do i <- getIState
1108 let opts = idris_options i
1109 let opt' = opts { opt_importdirs = fps }
1110 putIState $ i { idris_options = opt' }
1112allImportDirs :: Idris [FilePath]
1113allImportDirs = do i <- getIState
1114 let optdirs = opt_importdirs (idris_options i)
1115 return ("." : reverse optdirs)
1117-- Like allImportDirs but the dirs that are a prefix of
1118-- the files path first. This makes it look in the current
1119-- package first.
1120rankedImportDirs :: FilePath -> Idris [FilePath]
1121rankedImportDirs fp = do ids <- allImportDirs
1122 let (prefixes, rest) = partition (`isPrefixOf`fp) ids
1123 return $ prefixes ++ rest
1125addSourceDir :: FilePath -> Idris ()
1126addSourceDir fp = do i <- getIState
1127 let opts = idris_options i
1128 let opts' = opts { opt_sourcedirs = nub $ fp : opt_sourcedirs opts }
1129 putIState $ i { idris_options = opts' }
1131setSourceDirs :: [FilePath] -> Idris ()
1132setSourceDirs fps = do i <- getIState
1133 let opts = idris_options i
1134 let opts' = opts { opt_sourcedirs = nub $ fps }
1135 putIState $ i { idris_options = opts' }
1137allSourceDirs :: Idris [FilePath]
1138allSourceDirs = do i <- getIState
1139 let optdirs = opt_sourcedirs (idris_options i)
1140 return ("." : reverse optdirs)
1142colourise :: Idris Bool
1143colourise = do i <- getIState
1144 return $ idris_colourRepl i
1146setColourise :: Bool -> Idris ()
1147setColourise b = do i <- getIState
1148 putIState $ i { idris_colourRepl = b }
1150impShow :: Idris Bool
1151impShow = do i <- getIState
1152 return (opt_showimp (idris_options i))
1154setImpShow :: Bool -> Idris ()
1155setImpShow t = do i <- getIState
1156 let opts = idris_options i
1157 let opt' = opts { opt_showimp = t }
1158 putIState $ i { idris_options = opt' }
1160setColour :: ColourType -> IdrisColour -> Idris ()
1161setColour ct c = do i <- getIState
1162 let newTheme = setColour' ct c (idris_colourTheme i)
1163 putIState $ i { idris_colourTheme = newTheme }
1164 where setColour' KeywordColour c t = t { keywordColour = c }
1165 setColour' BoundVarColour c t = t { boundVarColour = c }
1166 setColour' ImplicitColour c t = t { implicitColour = c }
1167 setColour' FunctionColour c t = t { functionColour = c }
1168 setColour' TypeColour c t = t { typeColour = c }
1169 setColour' DataColour c t = t { dataColour = c }
1170 setColour' PromptColour c t = t { promptColour = c }
1171 setColour' PostulateColour c t = t { postulateColour = c }
1173logLvl :: Int -> String -> Idris ()
1174logLvl = logLvlCats []
1176logCoverage :: Int -> String -> Idris ()
1177logCoverage = logLvlCats [ICoverage]
1179logErasure :: Int -> String -> Idris ()
1180logErasure = logLvlCats [IErasure]
1182-- | Log an action of the parser
1183logParser :: Int -> String -> Idris ()
1184logParser = logLvlCats parserCats
1186-- | Log an action of the elaborator.
1187logElab :: Int -> String -> Idris ()
1188logElab = logLvlCats elabCats
1190-- | Log an action of the compiler.
1191logCodeGen :: Int -> String -> Idris ()
1192logCodeGen = logLvlCats codegenCats
1194logIBC :: Int -> String -> Idris ()
1195logIBC = logLvlCats [IIBC]
1197-- | Log aspect of Idris execution
1199-- An empty set of logging levels is used to denote all categories.
1201-- @TODO update IDE protocol
1202logLvlCats :: [LogCat] -- ^ The categories that the message should appear under.
1203 -> Int -- ^ The Logging level the message should appear.
1204 -> String -- ^ The message to show the developer.
1205 -> Idris ()
1206logLvlCats cs l msg = do
1207 i <- getIState
1208 let lvl = opt_logLevel (idris_options i)
1209 let cats = opt_logcats (idris_options i)
1210 when (lvl >= l) $
1211 when (inCat cs cats || null cats) $
1212 case idris_outputmode i of
1213 RawOutput h -> do
1214 runIO $ hPutStrLn h msg
1215 IdeMode n h -> do
1216 let good = SexpList [IntegerAtom (toInteger l), toSExp msg]
1217 runIO . hPutStrLn h $ convSExp "log" good n
1218 where
1219 inCat :: [LogCat] -> [LogCat] -> Bool
1220 inCat cs cats = any (`elem` cats) cs
1222cmdOptType :: Opt -> Idris Bool
1223cmdOptType x = do i <- getIState
1224 return $ x `elem` opt_cmdline (idris_options i)
1226noErrors :: Idris Bool
1227noErrors = do i <- getIState
1228 case errSpan i of
1229 Nothing -> return True
1230 _ -> return False
1232setTypeCase :: Bool -> Idris ()
1233setTypeCase t = do i <- getIState
1234 let opts = idris_options i
1235 let opt' = opts { opt_typecase = t }
1236 putIState $ i { idris_options = opt' }
1238getIndentWith :: Idris Int
1239getIndentWith = do
1240 i <- getIState
1241 return $ interactiveOpts_indentWith (idris_interactiveOpts i)
1243setIndentWith :: Int -> Idris ()
1244setIndentWith indentWith = do
1245 i <- getIState
1246 let opts = idris_interactiveOpts i
1247 let opts' = opts { interactiveOpts_indentWith = indentWith }
1248 putIState $ i { idris_interactiveOpts = opts' }
1250getIndentClause :: Idris Int
1251getIndentClause = do
1252 i <- getIState
1253 return $ interactiveOpts_indentClause (idris_interactiveOpts i)
1255setIndentClause :: Int -> Idris ()
1256setIndentClause indentClause = do
1257 i <- getIState
1258 let opts = idris_interactiveOpts i
1259 let opts' = opts { interactiveOpts_indentClause = indentClause }
1260 putIState $ i { idris_interactiveOpts = opts' }
1262-- Dealing with parameters
1264expandParams :: (Name -> Name) -> [(Name, PTerm)] ->
1265 [Name] -> -- all names
1266 [Name] -> -- names with no declaration
1267 PTerm -> PTerm
1268expandParams dec ps ns infs tm = en 0 tm
1269 where
1270 -- if we shadow a name (say in a lambda binding) that is used in a call to
1271 -- a lifted function, we need access to both names - once in the scope of the
1272 -- binding and once to call the lifted functions. So we'll explicitly shadow
1273 -- it. (Yes, it's a hack. The alternative would be to resolve names earlier
1274 -- but we didn't...)
1276 mkShadow (UN n) = MN 0 n
1277 mkShadow (MN i n) = MN (i+1) n
1278 mkShadow (NS x s) = NS (mkShadow x) s
1280 en :: Int -- ^ The quotation level - only transform terms that are used, not terms
1281 -- that are merely mentioned.
1282 -> PTerm -> PTerm
1283 en 0 (PLam fc n nfc t s)
1284 | n `elem` (map fst ps ++ ns)
1285 = let n' = mkShadow n in
1286 PLam fc n' nfc (en 0 t) (en 0 (shadow n n' s))
1287 | otherwise = PLam fc n nfc (en 0 t) (en 0 s)
1288 en 0 (PPi p n nfc t s)
1289 | n `elem` (map fst ps ++ ns)
1290 = let n' = mkShadow n in -- TODO THINK SHADOWING TacImp?
1291 PPi (enTacImp 0 p) n' nfc (en 0 t) (en 0 (shadow n n' s))
1292 | otherwise = PPi (enTacImp 0 p) n nfc (en 0 t) (en 0 s)
1293 en 0 (PLet fc rc n nfc ty v s)
1294 | n `elem` (map fst ps ++ ns)
1295 = let n' = mkShadow n in
1296 PLet fc rc n' nfc (en 0 ty) (en 0 v) (en 0 (shadow n n' s))
1297 | otherwise = PLet fc rc n nfc (en 0 ty) (en 0 v) (en 0 s)
1298 -- FIXME: Should only do this in a type signature!
1299 en 0 (PDPair f hls p (PRef f' fcs n) t r)
1300 | n `elem` (map fst ps ++ ns) && t /= Placeholder
1301 = let n' = mkShadow n in
1302 PDPair f hls p (PRef f' fcs n') (en 0 t) (en 0 (shadow n n' r))
1303 en 0 (PRewrite f by l r g) = PRewrite f by (en 0 l) (en 0 r) (fmap (en 0) g)
1304 en 0 (PTyped l r) = PTyped (en 0 l) (en 0 r)
1305 en 0 (PPair f hls p l r) = PPair f hls p (en 0 l) (en 0 r)
1306 en 0 (PDPair f hls p l t r) = PDPair f hls p (en 0 l) (en 0 t) (en 0 r)
1307 en 0 (PAlternative ns a as) = PAlternative ns a (map (en 0) as)
1308 en 0 (PHidden t) = PHidden (en 0 t)
1309 en 0 (PUnifyLog t) = PUnifyLog (en 0 t)
1310 en 0 (PDisamb ds t) = PDisamb ds (en 0 t)
1311 en 0 (PNoImplicits t) = PNoImplicits (en 0 t)
1312 en 0 (PDoBlock ds) = PDoBlock (map (fmap (en 0)) ds)
1313 en 0 (PProof ts) = PProof (map (fmap (en 0)) ts)
1314 en 0 (PTactics ts) = PTactics (map (fmap (en 0)) ts)
1316 en 0 (PQuote (Var n))
1317 | n `nselem` ns = PQuote (Var (dec n))
1318 en 0 (PApp fc (PInferRef fc' hl n) as)
1319 | n `nselem` ns = PApp fc (PInferRef fc' hl (dec n))
1320 (map ((pexp . (PRef fc hl)) . fst) ps ++ (map (fmap (en 0)) as))
1321 en 0 (PApp fc (PRef fc' hl n) as)
1322 | n `elem` infs = PApp fc (PInferRef fc' hl (dec n))
1323 (map ((pexp . (PRef fc hl)) . fst) ps ++ (map (fmap (en 0)) as))
1324 | n `nselem` ns = PApp fc (PRef fc' hl (dec n))
1325 (map ((pexp . (PRef fc hl)) . fst) ps ++ (map (fmap (en 0)) as))
1326 en 0 (PAppBind fc (PRef fc' hl n) as)
1327 | n `elem` infs = PAppBind fc (PInferRef fc' hl (dec n))
1328 (map ((pexp . (PRef fc hl)) . fst) ps ++ (map (fmap (en 0)) as))
1329 | n `nselem` ns = PAppBind fc (PRef fc' hl (dec n))
1330 (map ((pexp . (PRef fc hl)) . fst) ps ++ (map (fmap (en 0)) as))
1331 en 0 (PRef fc hl n)
1332 | n `elem` infs = PApp fc (PInferRef fc hl (dec n))
1333 (map ((pexp . (PRef fc hl)) . fst) ps)
1334 | n `nselem` ns = PApp fc (PRef fc hl (dec n))
1335 (map ((pexp . (PRef fc hl)) . fst) ps)
1336 en 0 (PInferRef fc hl n)
1337 | n `nselem` ns = PApp fc (PInferRef fc hl (dec n))
1338 (map ((pexp . (PRef fc hl)) . fst) ps)
1339 en 0 (PApp fc f as) = PApp fc (en 0 f) (map (fmap (en 0)) as)
1340 en 0 (PAppBind fc f as) = PAppBind fc (en 0 f) (map (fmap (en 0)) as)
1341 en 0 (PCase fc c os) = PCase fc (en 0 c) (map (pmap (en 0)) os)
1342 en 0 (PIfThenElse fc c t f) = PIfThenElse fc (en 0 c) (en 0 t) (en 0 f)
1343 en 0 (PRunElab fc tm ns) = PRunElab fc (en 0 tm) ns
1344 en 0 (PConstSugar fc tm) = PConstSugar fc (en 0 tm)
1346 en ql (PQuasiquote tm ty) = PQuasiquote (en (ql + 1) tm) (fmap (en ql) ty)
1347 en ql (PUnquote tm) = PUnquote (en (ql - 1) tm)
1349 en ql t = descend (en ql) t
1351 nselem x [] = False
1352 nselem x (y : xs) | nseq x y = True
1353 | otherwise = nselem x xs
1355 nseq x y = nsroot x == nsroot y
1357 enTacImp ql (TacImp aos st scr rig) = TacImp aos st (en ql scr) rig
1358 enTacImp ql other = other
1360expandParamsD :: Bool -> -- True = RHS only
1361 IState ->
1362 (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PDecl -> PDecl
1363expandParamsD rhsonly ist dec ps ns (PTy doc argdocs syn fc o n nfc ty)
1364 = if n `elem` ns && (not rhsonly)
1365 then -- trace (show (n, expandParams dec ps ns ty)) $
1366 PTy doc argdocs syn fc o (dec n) nfc (piBindp expl_param ps (expandParams dec ps ns [] ty))
1367 else --trace (show (n, expandParams dec ps ns ty)) $
1368 PTy doc argdocs syn fc o n nfc (expandParams dec ps ns [] ty)
1369expandParamsD rhsonly ist dec ps ns (PPostulate e doc syn fc nfc o n ty)
1370 = if n `elem` ns && (not rhsonly)
1371 then -- trace (show (n, expandParams dec ps ns ty)) $
1372 PPostulate e doc syn fc nfc o (dec n)
1373 (piBind ps (expandParams dec ps ns [] ty))
1374 else --trace (show (n, expandParams dec ps ns ty)) $
1375 PPostulate e doc syn fc nfc o n (expandParams dec ps ns [] ty)
1376expandParamsD rhsonly ist dec ps ns (PClauses fc opts n cs)
1377 = let n' = if n `elem` ns then dec n else n in
1378 PClauses fc opts n' (map expandParamsC cs)
1379 where
1380 expandParamsC (PClause fc n lhs ws rhs ds)
1381 = let -- ps' = updateps True (namesIn ist rhs) (zip ps [0..])
1382 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
1383 lhs' = if rhsonly then lhs else (expandParams dec ps'' ns [] lhs)
1384 n' = if n `elem` ns then dec n else n
1385 -- names bound on the lhs should not be expanded on the rhs
1386 ns' = removeBound lhs ns in
1387 PClause fc n' lhs'
1388 (map (expandParams dec ps'' ns' []) ws)
1389 (expandParams dec ps'' ns' [] rhs)
1390 (map (expandParamsD True ist dec ps'' ns') ds)
1391 expandParamsC (PWith fc n lhs ws wval pn ds)
1392 = let -- ps' = updateps True (namesIn ist wval) (zip ps [0..])
1393 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
1394 lhs' = if rhsonly then lhs else (expandParams dec ps'' ns [] lhs)
1395 n' = if n `elem` ns then dec n else n
1396 ns' = removeBound lhs ns in
1397 PWith fc n' lhs'
1398 (map (expandParams dec ps'' ns' []) ws)
1399 (expandParams dec ps'' ns' [] wval)
1400 pn
1401 (map (expandParamsD rhsonly ist dec ps'' ns') ds)
1402 updateps yn nm [] = []
1403 updateps yn nm (((a, t), i):as)
1404 | (a `elem` nm) == yn = (a, t) : updateps yn nm as
1405 | otherwise = (sMN i (show a ++ "_shadow"), t) : updateps yn nm as
1407 removeBound lhs ns = ns \\ nub (bnames lhs)
1409 bnames (PRef _ _ n) = [n]
1410 bnames (PApp _ _ args) = concatMap (bnames . getTm) args
1411 bnames (PPair _ _ _ l r) = bnames l ++ bnames r
1412 bnames (PDPair _ _ _ l Placeholder r) = bnames l ++ bnames r
1413 bnames _ = []
1415-- | Expands parameters defined in parameter and where blocks inside of declarations
1416expandParamsD rhs ist dec ps ns (PData doc argDocs syn fc co pd)
1417 = PData doc argDocs syn fc co (expandPData pd)
1418 where
1419 -- just do the type decl, leave constructors alone (parameters will be
1420 -- added implicitly)
1421 expandPData (PDatadecl n nfc ty cons)
1422 = if n `elem` ns
1423 then PDatadecl (dec n) nfc (piBind ps (expandParams dec ps ns [] ty))
1424 (map econ cons)
1425 else PDatadecl n nfc (expandParams dec ps ns [] ty) (map econ cons)
1426 econ (doc, argDocs, n, nfc, t, fc, fs)
1427 = (doc, argDocs, dec n, nfc, piBindp expl ps (expandParams dec ps ns [] t), fc, fs)
1428expandParamsD rhs ist dec ps ns d@(PRecord doc rsyn fc opts name nfc prs pdocs fls cn cdoc csyn)
1429 = d
1430expandParamsD rhs ist dec ps ns (PParams f params pds)
1431 = PParams f (ps ++ map (mapsnd (expandParams dec ps ns [])) params)
1432 (map (expandParamsD True ist dec ps ns) pds)
1433-- (map (expandParamsD ist dec ps ns) pds)
1434expandParamsD rhs ist dec ps ns (PMutual f pds)
1435 = PMutual f (map (expandParamsD rhs ist dec ps ns) pds)
1436expandParamsD rhs ist dec ps ns (PInterface doc info f cs n nfc params pDocs fds decls cn cd)
1437 = PInterface doc info f
1438 (map (\ (n, t) -> (n, expandParams dec ps ns [] t)) cs)
1439 n nfc
1440 (map (\(n, fc, t) -> (n, fc, expandParams dec ps ns [] t)) params)
1441 pDocs
1442 fds
1443 (map (expandParamsD rhs ist dec ps ns) decls)
1444 cn
1445 cd
1446expandParamsD rhs ist dec ps ns (PImplementation doc argDocs info f cs pnames acc opts n nfc params pextra ty cn decls)
1447 = let cn' = case cn of
1448 Just n -> if n `elem` ns then Just (dec n) else Just n
1449 Nothing -> Nothing in
1450 PImplementation doc argDocs info f
1451 (map (\ (n, t) -> (n, expandParams dec ps ns [] t)) cs)
1452 pnames acc opts n
1453 nfc
1454 (map (expandParams dec ps ns []) params)
1455 (map (\ (n, t) -> (n, expandParams dec ps ns [] t)) pextra)
1456 (expandParams dec ps ns [] ty)
1457 cn'
1458 (map (expandParamsD True ist dec ps ns) decls)
1459expandParamsD rhs ist dec ps ns d = d
1461mapsnd f (x, t) = (x, f t)
1463expandImplementationScope ist dec ps ns (PImplementation doc argDocs info f cs pnames acc opts n nfc params pextra ty cn decls)
1464 = PImplementation doc argDocs info f cs pnames acc opts n nfc params (ps ++ pextra)
1465 ty cn decls
1466expandImplementationScope ist dec ps ns d = d
1468-- | Calculate a priority for a type, for deciding elaboration order
1469-- * if it's just a type variable or concrete type, do it early (0)
1470-- * if there's only type variables and injective constructors, do it next (1)
1471-- * if there's a function type, next (2)
1472-- * finally, everything else (3)
1473getPriority :: IState -> PTerm -> Int
1474getPriority i tm = 1
1476addStatics :: Name -> Term -> PTerm -> Idris ()
1477addStatics n tm ptm =
1478 do let (statics, dynamics) = initStatics tm ptm
1479 ist <- getIState
1480 let paramnames
1481 = nub $ case lookupCtxtExact n (idris_fninfo ist) of
1482 Just p -> getNamesFrom 0 (fn_params p) tm ++
1483 concatMap (getParamNames ist . snd) statics
1484 _ -> concatMap (getParamNames ist . snd) statics
1486 let stnames = nub $ concatMap (freeArgNames . snd) statics
1487 let dnames = (nub $ concatMap (freeArgNames . snd) dynamics)
1488 \\ paramnames
1489 -- also get the arguments which are 'uniquely inferrable' from
1490 -- statics (see sec 4.2 of "Scrapping Your Inefficient Engine")
1491 -- or parameters to the type of a static
1492 let statics' = nub $ map fst statics ++
1493 filter (\x -> not (elem x dnames)) stnames
1494 let stpos = staticList statics' tm
1495 i <- getIState
1496 unless (null statics) $
1497 logLvl 3 $ "Statics for " ++ show n ++ " " ++ show tm ++ "\n"
1498 ++ showTmImpls ptm ++ "\n"
1499 ++ show statics ++ "\n" ++ show dynamics
1500 ++ "\n" ++ show paramnames
1501 ++ "\n" ++ show stpos
1502 putIState $ i { idris_statics = addDef n stpos (idris_statics i) }
1503 addIBC (IBCStatic n)
1504 where
1505 initStatics (Bind n (Pi _ _ ty _) sc) (PPi p n' fc t s)
1506 | n /= n' = let (static, dynamic) = initStatics sc (PPi p n' fc t s) in
1507 (static, (n, ty) : dynamic)
1508 initStatics (Bind n (Pi _ _ ty _) sc) (PPi p n' fc _ s)
1509 = let (static, dynamic) = initStatics (instantiate (P Bound n ty) sc) s in
1510 if pstatic p == Static then ((n, ty) : static, dynamic)
1511 else if (not (searchArg p))
1512 then (static, (n, ty) : dynamic)
1513 else (static, dynamic)
1514 initStatics t pt = ([], [])
1516 getParamNames ist tm | (P _ n _ , args) <- unApply tm
1517 = case lookupCtxtExact n (idris_datatypes ist) of
1518 Just ti -> getNamePos 0 (param_pos ti) args
1519 Nothing -> []
1520 where getNamePos i ps [] = []
1521 getNamePos i ps (P _ n _ : as)
1522 | i `elem` ps = n : getNamePos (i + 1) ps as
1523 getNamePos i ps (_ : as) = getNamePos (i + 1) ps as
1524 getParamNames ist (Bind t (Pi _ _ (P _ n _) _) sc)
1525 = n : getParamNames ist sc
1526 getParamNames ist _ = []
1528 getNamesFrom i ps (Bind n (Pi _ _ _ _) sc)
1529 | i `elem` ps = n : getNamesFrom (i + 1) ps sc
1530 | otherwise = getNamesFrom (i + 1) ps sc
1531 getNamesFrom i ps sc = []
1533 freeArgNames (Bind n (Pi _ _ ty _) sc)
1534 = nub $ freeNames ty ++ freeNames sc -- treat '->' as fn here
1535 freeArgNames tm = let (_, args) = unApply tm in
1536 concatMap freeNames args
1538 -- if a name appears in an interface or tactic implicit index, it doesn't
1539 -- affect its 'uniquely inferrable' from a static status since these are
1540 -- resolved by searching.
1541 searchArg (Constraint _ _ _) = True
1542 searchArg (TacImp _ _ _ _) = True
1543 searchArg _ = False
1545 staticList sts (Bind n (Pi _ _ _ _) sc) = (n `elem` sts) : staticList sts sc
1546 staticList _ _ = []
1548-- Dealing with implicit arguments
1550-- Add some bound implicits to the using block if they aren't there already
1552addToUsing :: [Using] -> [(Name, PTerm)] -> [Using]
1553addToUsing us [] = us
1554addToUsing us ((n, t) : ns)
1555 | n `notElem` mapMaybe impName us = addToUsing (us ++ [UImplicit n t]) ns
1556 | otherwise = addToUsing us ns
1557 where impName (UImplicit n _) = Just n
1558 impName _ = Nothing
1560-- Add constraint bindings from using block
1562addUsingConstraints :: SyntaxInfo -> FC -> PTerm -> Idris PTerm
1563addUsingConstraints syn fc t
1564 = do ist <- get
1565 let ns = namesIn [] ist t
1566 let cs = getConstraints t -- check declared constraints
1567 let addconsts = uconsts \\ cs
1568 return (doAdd addconsts ns t)
1569 where uconsts = filter uconst (using syn)
1570 uconst (UConstraint _ _) = True
1571 uconst _ = False
1573 doAdd [] _ t = t
1574 -- if all of args in ns, then add it
1575 doAdd (UConstraint c args : cs) ns t
1576 | all (\n -> elem n ns) args
1577 = PPi (Constraint [] Dynamic RigW) (sMN 0 "cu") NoFC
1578 (mkConst c args) (doAdd cs ns t)
1579 | otherwise = doAdd cs ns t
1581 mkConst c args = PApp fc (PRef fc [] c)
1582 (map (PExp 0 [] (sMN 0 "carg") . PRef fc []) args)
1584 getConstraints (PPi (Constraint _ _ _) _ _ c sc)
1585 = getcapp c ++ getConstraints sc
1586 getConstraints (PPi _ _ _ c sc) = getConstraints sc
1587 getConstraints _ = []
1589 getcapp (PApp _ (PRef _ _ c) args)
1590 = do ns <- mapM getName args
1591 return (UConstraint c ns)
1592 getcapp _ = []
1594 getName (PExp _ _ _ (PRef _ _ n)) = return n
1595 getName _ = []
1597-- | Add implicit bindings from using block, and bind any missing names
1598addUsingImpls :: SyntaxInfo -> Name -> FC -> PTerm -> Idris PTerm
1599addUsingImpls syn n fc t
1600 = do ist <- getIState
1601 autoimpl <- getAutoImpls
1602 let ns_in = implicitNamesIn (map iname uimpls) ist t
1603 let ns = if autoimpl then ns_in
1604 else filter (\n -> n `elem` (map iname uimpls)) ns_in
1606 let badnames = filter (\n -> not (implicitable n) &&
1607 n `notElem` (map iname uimpls)) ns
1608 unless (null badnames) $
1609 throwError (At fc (Elaborating "type of " n Nothing
1610 (NoSuchVariable (head badnames))))
1611 let cs = getArgnames t -- get already bound names
1612 let addimpls = filter (\n -> iname n `notElem` cs) uimpls
1613 -- if all names in the arguments of addconsts appear in ns,
1614 -- add the constraint implicitly
1615 return (bindFree ns (doAdd addimpls ns t))
1616 where uimpls = filter uimpl (using syn)
1617 uimpl (UImplicit _ _) = True
1618 uimpl _ = False
1620 iname (UImplicit n _) = n
1621 iname (UConstraint _ _) = error "Can't happen addUsingImpls"
1623 doAdd [] _ t = t
1624 -- if all of args in ns, then add it
1625 doAdd (UImplicit n ty : cs) ns t
1626 | elem n ns
1627 = PPi impl_gen n NoFC ty (doAdd cs ns t)
1628 | otherwise = doAdd cs ns t
1630 -- bind the free names which weren't in the using block
1631 bindFree [] tm = tm
1632 bindFree (n:ns) tm
1633 | elem n (map iname uimpls) = bindFree ns tm
1634 | otherwise
1635 = PPi (impl_gen { pargopts = [InaccessibleArg] }) n NoFC Placeholder (bindFree ns tm)
1637 getArgnames (PPi _ n _ c sc)
1638 = n : getArgnames sc
1639 getArgnames _ = []
1641-- Given the original type and the elaborated type, return the implicitness
1642-- status of each pi-bound argument, and whether it's inaccessible (True) or not.
1644getUnboundImplicits :: IState -> Type -> PTerm -> [(Bool, PArg)]
1645getUnboundImplicits i t tm = getImps t (collectImps tm)
1646 where collectImps (PPi p n _ t sc)
1647 = (n, (p, t)) : collectImps sc
1648 collectImps _ = []
1650 scopedimpl (Just i) = not (toplevel_imp i)
1651 scopedimpl _ = False
1653 getImps (Bind n (Pi _ i _ _) sc) imps
1654 | scopedimpl i = getImps sc imps
1655 getImps (Bind n (Pi _ _ t _) sc) imps
1656 | Just (p, t') <- lookup n imps = argInfo n p t' : getImps sc imps
1657 where
1658 argInfo n (Imp opt _ _ _ _ _) Placeholder
1659 = (True, PImp 0 True opt n Placeholder)
1660 argInfo n (Imp opt _ _ _ _ _) t'
1661 = (False, PImp (getPriority i t') True opt n t')
1662 argInfo n (Exp opt _ _ _) t'
1663 = (InaccessibleArg `elem` opt,
1664 PExp (getPriority i t') opt n t')
1665 argInfo n (Constraint opt _ _) t'
1666 = (InaccessibleArg `elem` opt,
1667 PConstraint 10 opt n t')
1668 argInfo n (TacImp opt _ scr _) t'
1669 = (InaccessibleArg `elem` opt,
1670 PTacImplicit 10 opt n scr t')
1671 getImps (Bind n (Pi _ _ t _) sc) imps = impBind n t : getImps sc imps
1672 where impBind n t = (True, PImp 1 True [] n Placeholder)
1673 getImps sc tm = []
1675-- Add implicit Pi bindings for any names in the term which appear in an
1676-- argument position.
1678-- This has become a right mess already. Better redo it some time...
1679-- TODO: This is obsoleted by the new way of elaborating types, (which
1680-- calls addUsingImpls) but there's still a couple of places which use
1681-- it. Clean them up!
1683-- Issue 1739 in the issue tracker
1684-- https://github.com/idris-lang/Idris-dev/issues/1739
1685implicit :: ElabInfo -> SyntaxInfo -> Name -> PTerm -> Idris PTerm
1686implicit info syn n ptm = implicit' info syn [] n ptm
1688implicit' :: ElabInfo -> SyntaxInfo -> [Name] -> Name -> PTerm -> Idris PTerm
1689implicit' info syn ignore n ptm
1690 = do i <- getIState
1691 auto <- getAutoImpls
1692 let (tm', impdata) = implicitise auto syn ignore i ptm
1693 defaultArgCheck (eInfoNames info ++ M.keys (idris_implicits i)) impdata
1694-- let (tm'', spos) = findStatics i tm'
1695 putIState $ i { idris_implicits = addDef n impdata (idris_implicits i) }
1696 addIBC (IBCImp n)
1697 logLvl 5 ("Implicit " ++ show n ++ " " ++ show impdata)
1698-- i <- get
1699-- putIState $ i { idris_statics = addDef n spos (idris_statics i) }
1700 return tm'
1701 where
1702 -- Detect unknown names in default arguments and throw error if found.
1703 defaultArgCheck :: [Name] -> [PArg] -> Idris ()
1704 defaultArgCheck knowns params = foldM_ notFoundInDefault knowns params
1706 notFoundInDefault :: [Name] -> PArg -> Idris [Name]
1707 notFoundInDefault kns (PTacImplicit _ _ n script _)
1708 = do i <- getIState
1709 case notFound kns (namesIn [] i script) of
1710 Nothing -> return (n:kns)
1711 Just name -> throwError (NoSuchVariable name)
1712 notFoundInDefault kns p = return ((pname p):kns)
1714 notFound :: [Name] -> [Name] -> Maybe Name
1715 notFound kns [] = Nothing
1716 notFound kns (SN (WhereN _ _ _) : ns) = notFound kns ns -- Known already
1717 notFound kns (n:ns) = if elem n kns then notFound kns ns else Just n
1719-- | Even if auto_implicits is off, we need to call this so we record
1720-- which arguments are implicit
1721implicitise :: Bool -> SyntaxInfo -> [Name] -> IState -> PTerm -> (PTerm, [PArg])
1722implicitise auto syn ignore ist tm = -- trace ("INCOMING " ++ showImp True tm) $
1723 let (declimps, ns') = execState (imps True [] tm) ([], [])
1724 ns = filter (\n -> auto && implicitable n || elem n (map fst uvars)) $
1725 ns' \\ (map fst pvars ++ no_imp syn ++ ignore)
1726 nsOrder = filter (not . inUsing) ns ++ filter inUsing ns in
1727 if null ns
1728 then (tm, reverse declimps)
1729 else implicitise auto syn ignore ist (pibind uvars nsOrder tm)
1730 where
1731 uvars = map ipair (filter uimplicit (using syn))
1732 pvars = syn_params syn
1734 inUsing n = n `elem` map fst uvars
1736 ipair (UImplicit x y) = (x, y)
1737 uimplicit (UImplicit _ _) = True
1738 uimplicit _ = False
1740 dropAll (x:xs) ys | x `elem` ys = dropAll xs ys
1741 | otherwise = x : dropAll xs ys
1742 dropAll [] ys = []
1744 -- Find names in argument position in a type, suitable for implicit
1745 -- binding
1746 -- Not the function position, but do everything else...
1747 implNamesIn uv (PApp fc f args) = concatMap (implNamesIn uv . getTm) args
1748 implNamesIn uv t = implicitNamesIn (map fst uv) ist t
1750 imps top env ty@(PApp _ f as)
1751 = do (decls, ns) <- get
1752 let isn = nub (implNamesIn uvars ty)
1753 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1754 imps top env (PPi (Imp l _ _ _ _ _) n _ ty sc)
1755 = do let isn = nub (implNamesIn uvars ty) `dropAll` [n]
1756 (decls , ns) <- get
1757 put (PImp (getPriority ist ty) True l n Placeholder : decls,
1758 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1759 imps True (n:env) sc
1760 imps top env (PPi (Exp l _ _ _) n _ ty sc)
1761 = do let isn = nub (implNamesIn uvars ty ++ case sc of
1762 (PRef _ _ x) -> namesIn uvars ist sc `dropAll` [n]
1763 _ -> [])
1764 (decls, ns) <- get -- ignore decls in HO types
1765 put (PExp (getPriority ist ty) l n Placeholder : decls,
1766 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1767 imps True (n:env) sc
1768 imps top env (PPi (Constraint l _ _) n _ ty sc)
1769 = do let isn = nub (implNamesIn uvars ty ++ case sc of
1770 (PRef _ _ x) -> namesIn uvars ist sc `dropAll` [n]
1771 _ -> [])
1772 (decls, ns) <- get -- ignore decls in HO types
1773 put (PConstraint 10 l n Placeholder : decls,
1774 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1775 imps True (n:env) sc
1776 imps top env (PPi (TacImp l _ scr _) n _ ty sc)
1777 = do let isn = nub (implNamesIn uvars ty ++ case sc of
1778 (PRef _ _ x) -> namesIn uvars ist sc `dropAll` [n]
1779 _ -> [])
1780 (decls, ns) <- get -- ignore decls in HO types
1781 put (PTacImplicit 10 l n scr Placeholder : decls,
1782 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1783 imps True (n:env) sc
1784 imps top env (PRewrite _ _ l r _)
1785 = do (decls, ns) <- get
1786 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1787 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1788 imps top env (PTyped l r)
1789 = imps top env l
1790 imps top env (PPair _ _ _ l r)
1791 = do (decls, ns) <- get
1792 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1793 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1794 imps top env (PDPair _ _ _ (PRef _ _ n) t r)
1795 = do (decls, ns) <- get
1796 let isn = nub (namesIn uvars ist t ++ namesIn uvars ist r) \\ [n]
1797 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1798 imps top env (PDPair _ _ _ l t r)
1799 = do (decls, ns) <- get
1800 let isn = namesIn uvars ist l ++ namesIn uvars ist t ++
1801 namesIn uvars ist r
1802 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1803 imps top env (PAlternative ms a as)
1804 = do (decls, ns) <- get
1805 let isn = concatMap (namesIn uvars ist) as
1806 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1807 imps top env (PLam fc n _ ty sc)
1808 = do imps False env ty
1809 imps False (n:env) sc
1810 imps top env (PHidden tm) = imps False env tm
1811 imps top env (PUnifyLog tm) = imps False env tm
1812 imps top env (PNoImplicits tm) = imps False env tm
1813 imps top env (PRunElab fc tm ns) = imps False env tm
1814 imps top env (PConstSugar fc tm) = imps top env tm -- ignore PConstSugar - it's for highlighting only!
1815 imps top env _ = return ()
1817 pibind using [] sc = sc
1818 pibind using (n:ns) sc
1819 = case lookup n using of
1820 Just ty -> PPi impl_gen
1821 n NoFC ty (pibind using ns sc)
1822 Nothing -> PPi (impl_gen { pargopts = [InaccessibleArg] })
1823 n NoFC Placeholder (pibind using ns sc)
1825-- | Add implicit arguments in function calls
1826addImplPat :: IState -> PTerm -> PTerm
1827addImplPat = addImpl' True [] [] []
1829addImplBound :: IState -> [Name] -> PTerm -> PTerm
1830addImplBound ist ns = addImpl' False ns [] [] ist
1832addImplBoundInf :: IState -> [Name] -> [Name] -> PTerm -> PTerm
1833addImplBoundInf ist ns inf = addImpl' False ns inf [] ist
1835-- | Add the implicit arguments to applications in the term [Name]
1836-- gives the names to always expend, even when under a binder of that
1837-- name (this is to expand methods with implicit arguments in
1838-- dependent interfaces).
1839addImpl :: [Name] -> IState -> PTerm -> PTerm
1840addImpl = addImpl' False [] []
1842-- TODO: in patterns, don't add implicits to function names guarded by constructors
1843-- and *not* inside a PHidden
1845addImpl' :: Bool -> [Name] -> [Name] -> [Name] -> IState -> PTerm -> PTerm
1846addImpl' inpat env infns imp_meths ist ptm
1847 = ai inpat False (zip env (repeat Nothing)) [] (mkUniqueNames env [] ptm)
1848 where
1849 topname = case ptm of
1850 PRef _ _ n -> n
1851 PApp _ (PRef _ _ n) _ -> n
1852 _ -> sUN "" -- doesn't matter then
1854 ai :: Bool -> Bool -> [(Name, Maybe PTerm)] -> [[T.Text]] -> PTerm -> PTerm
1855 ai inpat qq env ds (PRef fc fcs f)
1856 | f `elem` infns = PInferRef fc fcs f
1857 | not (f `elem` map fst env) = handleErr $ aiFn topname inpat inpat qq imp_meths ist fc f fc ds []
1858 ai inpat qq env ds (PHidden (PRef fc hl f))
1859 | not (f `elem` map fst env) = PHidden (handleErr $ aiFn topname inpat False qq imp_meths ist fc f fc ds [])
1860 ai inpat qq env ds (PRewrite fc by l r g)
1861 = let l' = ai inpat qq env ds l
1862 r' = ai inpat qq env ds r
1863 g' = fmap (ai inpat qq env ds) g in
1864 PRewrite fc by l' r' g'
1865 ai inpat qq env ds (PTyped l r)
1866 = let l' = ai inpat qq env ds l
1867 r' = ai inpat qq env ds r in
1868 PTyped l' r'
1869 ai inpat qq env ds (PPair fc hls p l r)
1870 = let l' = ai inpat qq env ds l
1871 r' = ai inpat qq env ds r in
1872 PPair fc hls p l' r'
1873 ai inpat qq env ds (PDPair fc hls p l t r)
1874 = let l' = ai inpat qq env ds l
1875 t' = ai inpat qq env ds t
1876 r' = ai inpat qq env ds r in
1877 PDPair fc hls p l' t' r'
1878 ai inpat qq env ds (PAlternative ms a as)
1879 = let as' = map (ai inpat qq env ds) as in
1880 PAlternative ms a as'
1881 ai inpat qq env _ (PDisamb ds' as) = ai inpat qq env ds' as
1882 ai inpat qq env ds (PApp fc (PInferRef ffc hl f) as)
1883 = let as' = map (fmap (ai inpat qq env ds)) as in
1884 PApp fc (PInferRef ffc hl f) as'
1885 ai inpat qq env ds (PApp fc ftm@(PRef ffc hl f) as)
1886 | f `elem` infns = ai inpat qq env ds (PApp fc (PInferRef ffc hl f) as)
1887 | not (f `elem` map fst env)
1888 = let as' = map (fmap (ai inpat qq env ds)) as in
1889 handleErr $ aiFn topname inpat False qq imp_meths ist fc f ffc ds as'
1890 | Just (Just ty) <- lookup f env =
1891 let as' = map (fmap (ai inpat qq env ds)) as
1892 arity = getPArity ty in
1893 mkPApp fc arity ftm as'
1894 ai inpat qq env ds (PApp fc f as)
1895 = let f' = ai inpat qq env ds f
1896 as' = map (fmap (ai inpat qq env ds)) as in
1897 mkPApp fc 1 f' as'
1898 ai inpat qq env ds (PWithApp fc f a)
1899 = PWithApp fc (ai inpat qq env ds f) (ai inpat qq env ds a)
1900 ai inpat qq env ds (PCase fc c os)
1901 = let c' = ai inpat qq env ds c in
1902 -- leave lhs alone, because they get lifted into a new pattern match
1903 -- definition which is passed through addImpl again
1904 PCase fc c' (map aiCase os)
1905 where
1906 aiCase (lhs, rhs)
1907 = (lhs, ai inpat qq (env ++ patnames lhs) ds rhs)
1909 -- Anything beginning with a lower case letter, not applied,
1910 -- and no namespace is a pattern variable
1911 patnames (PApp _ (PRef _ _ f) [])
1912 | implicitable f = [(f, Nothing)]
1913 patnames (PRef _ _ f)
1914 | implicitable f = [(f, Nothing)]
1915 patnames (PApp _ (PRef _ _ _) args)
1916 = concatMap patnames (map getTm args)
1917 patnames (PPair _ _ _ l r) = patnames l ++ patnames r
1918 patnames (PDPair _ _ _ l t r) = patnames l ++ patnames t ++ patnames r
1919 patnames (PAs _ _ t) = patnames t
1920 patnames (PAlternative _ _ ts) = concatMap patnames ts
1921 patnames _ = []
1924 ai inpat qq env ds (PIfThenElse fc c t f) = PIfThenElse fc (ai inpat qq env ds c)
1925 (ai inpat qq env ds t)
1926 (ai inpat qq env ds f)
1928 -- If the name in a lambda is an unapplied data constructor name, do this
1929 -- as a 'case' instead because we'll expect to match on it
1930 ai inpat qq env ds (PLam fc n nfc ty sc)
1931 = if canBeDConName n (tt_ctxt ist)
1932 then ai inpat qq env ds (PLam fc (sMN 0 "lamp") NoFC ty
1933 (PCase fc (PRef fc [] (sMN 0 "lamp") )
1934 [(PRef fc [] n, sc)]))
1935 else let ty' = ai inpat qq env ds ty
1936 sc' = ai inpat qq ((n, Just ty):env) ds sc in
1937 PLam fc n nfc ty' sc'
1938 ai inpat qq env ds (PLet fc rc n nfc ty val sc)
1939 = if canBeDConName n (tt_ctxt ist)
1940 then ai inpat qq env ds (PCase fc val [(PRef fc [] n, sc)])
1941 else let ty' = ai inpat qq env ds ty
1942 val' = ai inpat qq env ds val
1943 sc' = ai inpat qq ((n, Just ty):env) ds sc in
1944 PLet fc rc n nfc ty' val' sc'
1945 ai inpat qq env ds (PPi p n nfc ty sc)
1946 = let ty' = ai inpat qq env ds ty
1947 env' = if n `elem` imp_meths then env
1948 else
1949 ((n, Just ty) : env)
1950 sc' = ai inpat qq env' ds sc in
1951 PPi p n nfc ty' sc'
1952 ai inpat qq env ds (PGoal fc r n sc)
1953 = let r' = ai inpat qq env ds r
1954 sc' = ai inpat qq ((n, Nothing):env) ds sc in
1955 PGoal fc r' n sc'
1956 ai inpat qq env ds (PHidden tm) = PHidden (ai inpat qq env ds tm)
1957 -- Don't do PProof or PTactics since implicits get added when scope is
1958 -- properly known in ElabTerm.runTac
1959 ai inpat qq env ds (PUnifyLog tm) = PUnifyLog (ai inpat qq env ds tm)
1960 ai inpat qq env ds (PNoImplicits tm) = PNoImplicits (ai inpat qq env ds tm)
1961 ai inpat qq env ds (PQuasiquote tm g) = PQuasiquote (ai inpat True env ds tm)
1962 (fmap (ai inpat True env ds) g)
1963 ai inpat qq env ds (PUnquote tm) = PUnquote (ai inpat False env ds tm)
1964 ai inpat qq env ds (PRunElab fc tm ns) = PRunElab fc (ai inpat False env ds tm) ns
1965 ai inpat qq env ds (PConstSugar fc tm) = PConstSugar fc (ai inpat qq env ds tm)
1966 ai inpat qq env ds tm = tm
1968 handleErr (Left err) = PElabError err
1969 handleErr (Right x) = x
1971-- if in a pattern, and there are no arguments, and there's no possible
1972-- names with zero explicit arguments, don't add implicits.
1974aiFn :: Name -> Bool -> Bool -> Bool
1975 -> [Name]
1976 -> IState -> FC
1977 -> Name -- ^ function being applied
1978 -> FC -> [[T.Text]]
1979 -> [PArg] -- ^ initial arguments (if in a pattern)
1980 -> Either Err PTerm
1981aiFn topname inpat True qq imp_meths ist fc f ffc ds []
1982 | inpat && implicitable f && unqualified f = Right $ PPatvar ffc f
1983 | otherwise
1984 = case lookupDef f (tt_ctxt ist) of
1985 [] -> Right $ PPatvar ffc f
1986 alts -> let ialts = lookupCtxtName f (idris_implicits ist) in
1987 -- trace (show f ++ " " ++ show (fc, any (all imp) ialts, ialts, any constructor alts)) $
1988 if (not (vname f) || tcname f
1989 || any (conCaf (tt_ctxt ist)) ialts)
1990-- any constructor alts || any allImp ialts))
1991 then aiFn topname inpat False qq imp_meths ist fc f ffc ds [] -- use it as a constructor
1992 else Right $ PPatvar ffc f
1993 where imp (PExp _ _ _ _) = False
1994 imp _ = True
1995-- allImp [] = False
1996 allImp xs = all imp xs
1998 unqualified (NS _ _) = False
1999 unqualified _ = True
2001 conCaf ctxt (n, cia) = (isDConName n ctxt || (qq && isTConName n ctxt)) && allImp cia
2003 vname (UN n) = True -- non qualified
2004 vname _ = False
2006aiFn topname inpat expat qq imp_meths ist fc f ffc ds as
2007 | f `elem` primNames = Right $ PApp fc (PRef ffc [ffc] f) as
2008aiFn topname inpat expat qq imp_meths ist fc f ffc ds as
2009 -- This is where namespaces get resolved by adding PAlternative
2010 = do let ns = lookupCtxtName f (idris_implicits ist)
2011 let nh = filter (\(n, _) -> notHidden n) ns
2012 let ns' = case trimAlts ds nh of
2013 [] -> nh
2014 x -> x
2015 case ns' of
2016 [(f',ns)] -> Right $ mkPApp fc (length ns) (PRef ffc [ffc] (isImpName f f'))
2017 (insertImpl ns as)
2018 [] -> case metaVar f (map fst (idris_metavars ist)) of
2019 Just f' -> Right $ PApp fc (PRef ffc [ffc] f') as
2020 Nothing -> Right $ mkPApp fc (length as) (PRef ffc [ffc] f) as
2021 alts -> Right $
2022 PAlternative [] (ExactlyOne True) $
2023 map (\(f', ns) -> mkPApp fc (length ns) (PRef ffc [ffc] (isImpName f f'))
2024 (insertImpl ns as)) alts
2025 where
2026 -- if the name is in imp_meths, we should actually refer to the bound
2027 -- name rather than the global one after expanding implicits
2028 isImpName f f' | f `elem` imp_meths = f
2029 | otherwise = f'
2031 -- If it's a metavariable name, try to qualify it from the list of
2032 -- unsolved metavariables
2033 metaVar f (mvn : ns) | f == nsroot mvn = Just mvn
2034 metaVar f (_ : ns) = metaVar f ns
2035 metaVar f [] = Nothing
2037 trimAlts [] alts = alts
2038 trimAlts ns alts
2039 = filter (\(x, _) -> any (\d -> d `isPrefixOf` nspace x) ns) alts
2041 nspace (NS _ s) = s
2042 nspace _ = []
2044 notHidden n = case getAccessibility n of
2045 Hidden -> False
2046 Private -> False
2047 _ -> True
2049 getAccessibility n
2050 = case lookupDefAccExact n False (tt_ctxt ist) of
2051 Just (n,t) -> t
2052 _ -> Public
2054 insertImpl :: [PArg] -- ^ expected argument types (from idris_implicits)
2055 -> [PArg] -- ^ given arguments
2056 -> [PArg]
2057 insertImpl ps as
2058 = let (as', badimpls) = partition (impIn ps) as in
2059 map addUnknownImp badimpls ++
2060 insImpAcc M.empty ps (filter expArg as') (filter (not . expArg) as')
2062 insImpAcc :: M.Map Name PTerm -- accumulated param names & arg terms
2063 -> [PArg] -- parameters
2064 -> [PArg] -- explicit arguments
2065 -> [PArg] -- implicits given
2066 -> [PArg]
2067 insImpAcc pnas (PExp p l n ty : ps) (PExp _ _ _ tm : given) imps =
2068 PExp p l n tm : insImpAcc (M.insert n tm pnas) ps given imps
2069 insImpAcc pnas (PConstraint p l n ty : ps) (PConstraint _ _ _ tm : given) imps =
2070 PConstraint p l n tm : insImpAcc (M.insert n tm pnas) ps given imps
2071 insImpAcc pnas (PConstraint p l n ty : ps) given imps =
2072 let rtc = PResolveTC fc in
2073 PConstraint p l n rtc : insImpAcc (M.insert n rtc pnas) ps given imps
2074 insImpAcc pnas (PImp p _ l n ty : ps) given imps =
2075 case find n imps [] of
2076 Just (tm, imps') ->
2077 PImp p False l n tm : insImpAcc (M.insert n tm pnas) ps given imps'
2078 Nothing ->
2079 PImp p True l n Placeholder :
2080 insImpAcc (M.insert n Placeholder pnas) ps given imps
2081 insImpAcc pnas (PTacImplicit p l n sc' ty : ps) given imps =
2082 let sc = addImpl imp_meths ist (substMatches (M.toList pnas) sc') in
2083 case find n imps [] of
2084 Just (tm, imps') ->
2085 PTacImplicit p l n sc tm :
2086 insImpAcc (M.insert n tm pnas) ps given imps'
2087 Nothing ->
2088 if inpat
2089 then PTacImplicit p l n sc Placeholder :
2090 insImpAcc (M.insert n Placeholder pnas) ps given imps
2091 else PTacImplicit p l n sc sc :
2092 insImpAcc (M.insert n sc pnas) ps given imps
2093 insImpAcc _ expected [] imps = map addUnknownImp imps -- so that unused implicits give error
2094 insImpAcc _ _ given imps = given ++ imps
2096 addUnknownImp arg = arg { argopts = UnknownImp : argopts arg }
2098 find n [] acc = Nothing
2099 find n (PImp _ _ _ n' t : gs) acc
2100 | n == n' = Just (t, reverse acc ++ gs)
2101 find n (PTacImplicit _ _ n' _ t : gs) acc
2102 | n == n' = Just (t, reverse acc ++ gs)
2103 find n (g : gs) acc = find n gs (g : acc)
2105-- | return True if the second argument is an implicit argument which
2106-- is expected in the implicits, or if it's not an implicit
2107impIn :: [PArg] -> PArg -> Bool
2108impIn ps (PExp _ _ _ _) = True
2109impIn ps (PConstraint _ _ _ _) = True
2110impIn ps arg = any (\p -> not (expArg arg) && pname arg == pname p) ps
2112expArg (PExp _ _ _ _) = True
2113expArg (PConstraint _ _ _ _) = True
2114expArg _ = False
2116-- replace non-linear occurrences with _
2118stripLinear :: IState -> PTerm -> PTerm
2119stripLinear i tm = evalState (sl tm) [] where
2120 sl :: PTerm -> State [Name] PTerm
2121 sl (PRef fc hl f)
2122 | (_:_) <- lookupTy f (tt_ctxt i)
2123 = return $ PRef fc hl f
2124 | otherwise = do ns <- get
2125 if (f `elem` ns)
2126 then return $ PHidden (PRef fc hl f) -- Placeholder
2127 else do put (f : ns)
2128 return (PRef fc hl f)
2129 sl (PPatvar fc f)
2130 = do ns <- get
2131 if (f `elem` ns)
2132 then return $ PHidden (PPatvar fc f) -- Placeholder
2133 else do put (f : ns)
2134 return (PPatvar fc f)
2135 -- Assumption is that variables are all the same in each alternative
2136 sl t@(PAlternative ms b as) = do ns <- get
2137 as' <- slAlts ns as
2138 return (PAlternative ms b as')
2139 where slAlts ns (a : as) = do put ns
2140 a' <- sl a
2141 as' <- slAlts ns as
2142 return (a' : as')
2143 slAlts ns [] = return []
2144 sl (PPair fc hls p l r) = do l' <- sl l; r' <- sl r; return (PPair fc hls p l' r')
2145 sl (PDPair fc hls p l t r) = do l' <- sl l
2146 t' <- sl t
2147 r' <- sl r
2148 return (PDPair fc hls p l' t' r')
2149 sl (PApp fc fn args) = do fn' <- case fn of
2150 -- Just the args, fn isn't matchable as a var
2151 PRef _ _ _ -> return fn
2152 t -> sl t
2153 args' <- mapM slA args
2154 return $ PApp fc fn' args'
2155 where slA (PImp p m l n t) = do t' <- sl t
2156 return $ PImp p m l n t'
2157 slA (PExp p l n t) = do t' <- sl t
2158 return $ PExp p l n t'
2159 slA (PConstraint p l n t)
2160 = do t' <- sl t
2161 return $ PConstraint p l n t'
2162 slA (PTacImplicit p l n sc t)
2163 = do t' <- sl t
2164 return $ PTacImplicit p l n sc t'
2165 sl x = return x
2167-- | Remove functions which aren't applied to anything, which must then
2168-- be resolved by unification. Assume names resolved and alternatives
2169-- filled in (so no ambiguity).
2170stripUnmatchable :: IState -> PTerm -> PTerm
2171stripUnmatchable i (PApp fc fn args) = PApp fc fn (fmap (fmap su) args) where
2172 su :: PTerm -> PTerm
2173 su tm@(PRef fc hl f)
2174 | (Bind n (Pi _ _ t _) sc :_) <- lookupTy f (tt_ctxt i)
2175 = Placeholder
2176 | (TType _ : _) <- lookupTy f (tt_ctxt i),
2177 not (implicitable f)
2178 = PHidden tm
2179 | (UType _ : _) <- lookupTy f (tt_ctxt i),
2180 not (implicitable f)
2181 = PHidden tm
2182 su (PApp fc f@(PRef _ _ fn) args)
2183 -- here we use canBeDConName because the impossible pattern
2184 -- check will not necessarily fully resolve constructor names,
2185 -- and these bare names will otherwise get in the way of
2186 -- impossbility checking.
2187 | canBeDConName fn ctxt
2188 = PApp fc f (fmap (fmap su) args)
2189 su (PApp fc f args)
2190 = PHidden (PApp fc f args)
2191 su (PAlternative ms b alts)
2192 = let alts' = filter (/= Placeholder) (map su alts) in
2193 if null alts' then Placeholder
2194 else liftHidden $ PAlternative ms b alts'
2195 su (PPair fc hls p l r) = PPair fc hls p (su l) (su r)
2196 su (PDPair fc hls p l t r) = PDPair fc hls p (su l) (su t) (su r)
2197 su t@(PLam fc _ _ _ _) = PHidden t
2198 su t@(PPi _ _ _ _ _) = PHidden t
2199 su t@(PConstant _ c) | isTypeConst c = PHidden t
2200 su t = t
2202 ctxt = tt_ctxt i
2204 -- If the ambiguous terms are all hidden, the PHidden needs to be outside
2205 -- because elaboration of PHidden gets delayed, and we need the elaboration
2206 -- to resolve the ambiguity.
2207 liftHidden tm@(PAlternative ms b as)
2208 | allHidden as = PHidden (PAlternative ms b (map unHide as))
2209 | otherwise = tm
2211 allHidden [] = True
2212 allHidden (PHidden _ : xs) = allHidden xs
2213 allHidden (x : xs) = False
2215 unHide (PHidden t) = t
2216 unHide t = t
2218stripUnmatchable i tm = tm
2220mkPApp fc a f [] = f
2221mkPApp fc a f as = let rest = drop a as in
2222 if a == 0 then appRest fc f rest
2223 else appRest fc (PApp fc f (take a as)) rest
2224 where
2225 appRest fc f [] = f
2226 appRest fc f (a : as) = appRest fc (PApp fc f [a]) as
2230-- | Find 'static' argument positions
2231-- (the declared ones, plus any names in argument position in the declared
2232-- statics)
2233-- FIXME: It's possible that this really has to happen after elaboration
2234findStatics :: IState -> PTerm -> (PTerm, [Bool])
2235findStatics ist tm = let (ns, ss) = fs tm
2236 in runState (pos ns ss tm) []
2237 where fs (PPi p n fc t sc)
2238 | Static <- pstatic p
2239 = let (ns, ss) = fs sc in
2240 (namesIn [] ist t : ns, n : ss)
2241 | otherwise = let (ns, ss) = fs sc in
2242 (ns, ss)
2243 fs _ = ([], [])
2245 pos ns ss (PPi p n fc t sc)
2246 | elem n ss = do sc' <- pos ns ss sc
2247 spos <- get
2248 put (True : spos)
2249 return (PPi (p { pstatic = Static }) n fc t sc')
2250 | otherwise = do sc' <- pos ns ss sc
2251 spos <- get
2252 put (False : spos)
2253 return (PPi p n fc t sc')
2254 pos ns ss t = return t
2256-- for 6.12/7 compatibility
2257data EitherErr a b = LeftErr a | RightOK b deriving ( Functor )
2259instance Applicative (EitherErr a) where
2260 pure = return
2261 (<*>) = ap
2263instance Monad (EitherErr a) where
2264 return = RightOK
2266 (LeftErr e) >>= _ = LeftErr e
2267 RightOK v >>= k = k v
2269toEither :: EitherErr a b -> Either a b
2270toEither (LeftErr e) = Left e
2271toEither (RightOK ho) = Right ho
2273-- | Syntactic match of a against b, returning pair of variables in a
2274-- and what they match. Returns the pair that failed if not a match.
2275matchClause :: IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
2276matchClause = matchClause' False
2278matchClause' :: Bool -> IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
2279matchClause' names i x y = checkRpts $ match (fullApp x) (fullApp y) where
2280 matchArg x y = match (fullApp (getTm x)) (fullApp (getTm y))
2282 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
2283 fullApp x = x
2285 match' x y = match (fullApp x) (fullApp y)
2286 match (PApp _ (PRef _ _ (NS (UN fi) [b])) [_,_,x]) x'
2287 | fi == txt "fromInteger" && b == txt "builtins",
2288 PConstant _ (I _) <- getTm x = match (getTm x) x'
2289 match x' (PApp _ (PRef _ _ (NS (UN fi) [b])) [_,_,x])
2290 | fi == txt "fromInteger" && b == txt "builtins",
2291 PConstant _ (I _) <- getTm x = match (getTm x) x'
2292 match (PApp _ (PRef _ _ (UN l)) [_,x]) x' | l == txt "lazy" = match (getTm x) x'
2293 match x (PApp _ (PRef _ _ (UN l)) [_,x']) | l == txt "lazy" = match x (getTm x')
2294 match (PApp _ f args) (PApp _ f' args')
2295 | length args == length args'
2296 = do mf <- match' f f'
2297 ms <- zipWithM matchArg args args'
2298 return (mf ++ concat ms)
2299 match (PRef f hl n) (PApp _ x []) = match (PRef f hl n) x
2300 match (PPatvar f n) xr = match (PRef f [f] n) xr
2301 match xr (PPatvar f n) = match xr (PRef f [f] n)
2302 match (PApp _ x []) (PRef f hl n) = match x (PRef f hl n)
2303 match (PRef _ _ n) tm@(PRef _ _ n')
2304 | n == n' && not names &&
2305 (not (isConName n (tt_ctxt i) || isFnName n (tt_ctxt i))
2306 || tm == Placeholder)
2307 = return [(n, tm)]
2308 -- if one namespace is missing, drop the other
2309 | n == n' || n == dropNS n' || dropNS n == n' = return []
2310 where dropNS (NS n _) = n
2311 dropNS n = n
2312 match (PRef _ _ n) tm
2313 | not names && (not (isConName n (tt_ctxt i) ||
2314 isFnName n (tt_ctxt i)) || tm == Placeholder)
2315 = return [(n, tm)]
2316 match (PRewrite _ by l r _) (PRewrite _ by' l' r' _) | by == by'
2317 = do ml <- match' l l'
2318 mr <- match' r r'
2319 return (ml ++ mr)
2320 match (PTyped l r) (PTyped l' r') = do ml <- match l l'
2321 mr <- match r r'
2322 return (ml ++ mr)
2323 match (PTyped l r) x = match l x
2324 match x (PTyped l r) = match x l
2325 match (PPair _ _ _ l r) (PPair _ _ _ l' r') = do ml <- match' l l'
2326 mr <- match' r r'
2327 return (ml ++ mr)
2328 match (PDPair _ _ _ l t r) (PDPair _ _ _ l' t' r') = do ml <- match' l l'
2329 mt <- match' t t'
2330 mr <- match' r r'
2331 return (ml ++ mt ++ mr)
2332 match (PAlternative _ a as) (PAlternative _ a' as')
2333 = do ms <- zipWithM match' as as'
2334 return (concat ms)
2335 match a@(PAlternative _ _ as) b
2336 = do let ms = zipWith match' as (repeat b)
2337 case (rights (map toEither ms)) of
2338 (x: _) -> return x
2339 _ -> LeftErr (a, b)
2340 match (PCase _ _ _) _ = return [] -- lifted out
2341 match (PMetavar _ _) _ = return [] -- modified
2342 match (PInferRef _ _ _) _ = return [] -- modified
2343 match (PQuote _) _ = return []
2344 match (PProof _) _ = return []
2345 match (PTactics _) _ = return []
2346 match (PResolveTC _) (PResolveTC _) = return []
2347 match (PTrue _ _) (PTrue _ _) = return []
2348 match (PPi _ _ _ t s) (PPi _ _ _ t' s') = do mt <- match' t t'
2349 ms <- match' s s'
2350 return (mt ++ ms)
2351 match (PLam _ _ _ t s) (PLam _ _ _ t' s') = do mt <- match' t t'
2352 ms <- match' s s'
2353 return (mt ++ ms)
2354 match (PLet _ _ _ _ t ty s) (PLet _ _ _ _ t' ty' s')
2355 = do mt <- match' t t'
2356 mty <- match' ty ty'
2357 ms <- match' s s'
2358 return (mt ++ mty ++ ms)
2359 match (PHidden x) (PHidden y)
2360 | RightOK xs <- match x y = return xs -- to collect variables
2361 | otherwise = return [] -- Otherwise hidden things are unmatchable
2362 match (PHidden x) y
2363 | RightOK xs <- match x y = return xs
2364 | otherwise = return []
2365 match x (PHidden y)
2366 | RightOK xs <- match x y = return xs
2367 | otherwise = return []
2368 match (PUnifyLog x) y = match' x y
2369 match x (PUnifyLog y) = match' x y
2370 match (PNoImplicits x) y = match' x y
2371 match x (PNoImplicits y) = match' x y
2372 match Placeholder _ = return []
2373 match _ Placeholder = return []
2374 match (PResolveTC _) _ = return []
2375 match a b | a == b = return []
2376 | otherwise = LeftErr (a, b)
2378 checkRpts (RightOK ms) = check ms where
2379 check ((n,t):xs)
2380 | Just t' <- lookup n xs = if t/=t' && t/=Placeholder && t'/=Placeholder
2381 then Left (t, t')
2382 else check xs
2383 check (_:xs) = check xs
2384 check [] = Right ms
2385 checkRpts (LeftErr x) = Left x
2387substMatches :: [(Name, PTerm)] -> PTerm -> PTerm
2388substMatches ms = substMatchesShadow ms []
2390-- substMatchesShadow :: [(Name, PTerm)] -> [Name] -> PTerm -> PTerm
2391-- substMatchesShadow [] shs t = t
2392-- substMatchesShadow ((n,tm):ns) shs t
2393-- = substMatchShadow n shs tm (substMatchesShadow ns shs t)
2395substMatch :: Name -> PTerm -> PTerm -> PTerm
2396substMatch n = substMatchShadow n []
2398substMatchShadow :: Name -> [Name] -> PTerm -> PTerm -> PTerm
2399substMatchShadow n shs tm t = substMatchesShadow [(n, tm)] shs t
2401substMatchesShadow :: [(Name, PTerm)] -> [Name] -> PTerm -> PTerm
2402substMatchesShadow nmap shs t = sm shs t where
2403 sm xs (PRef _ _ n) | Just tm <- lookup n nmap = tm
2404 sm xs (PLam fc x xfc t sc) = PLam fc x xfc (sm xs t) (sm xs sc)
2405 sm xs (PPi p x fc t sc)
2406 | x `elem` xs
2407 = let x' = nextName x in
2408 PPi p x' fc (sm (x':xs) (substMatch x (PRef emptyFC [] x') t))
2409 (sm (x':xs) (substMatch x (PRef emptyFC [] x') sc))
2410 | otherwise = PPi p x fc (sm xs t) (sm (x : xs) sc)
2411 sm xs (PLet fc rc x xfc val t sc)
2412 = PLet fc rc x xfc (sm xs val) (sm xs t) (sm xs sc)
2413 sm xs (PApp f x as) = fullApp $ PApp f (sm xs x) (map (fmap (sm xs)) as)
2414 sm xs (PCase f x as) = PCase f (sm xs x) (map (pmap (sm xs)) as)
2415 sm xs (PIfThenElse fc c t f) = PIfThenElse fc (sm xs c) (sm xs t) (sm xs f)
2416 sm xs (PRewrite f by x y tm) = PRewrite f by (sm xs x) (sm xs y)
2417 (fmap (sm xs) tm)
2418 sm xs (PTyped x y) = PTyped (sm xs x) (sm xs y)
2419 sm xs (PPair f hls p x y) = PPair f hls p (sm xs x) (sm xs y)
2420 sm xs (PDPair f hls p x t y) = PDPair f hls p (sm xs x) (sm xs t) (sm xs y)
2421 sm xs (PAlternative ms a as) = PAlternative ms a (map (sm xs) as)
2422 sm xs (PHidden x) = PHidden (sm xs x)
2423 sm xs (PUnifyLog x) = PUnifyLog (sm xs x)
2424 sm xs (PNoImplicits x) = PNoImplicits (sm xs x)
2425 sm xs (PRunElab fc script ns) = PRunElab fc (sm xs script) ns
2426 sm xs (PConstSugar fc tm) = PConstSugar fc (sm xs tm)
2427 sm xs x = x
2429 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
2430 fullApp x = x
2432shadow :: Name -> Name -> PTerm -> PTerm
2433shadow n n' t = sm 0 t where
2434 sm 0 (PRef fc hl x) | n == x = PRef fc hl n'
2435 sm 0 (PLam fc x xfc t sc) | n /= x = PLam fc x xfc (sm 0 t) (sm 0 sc)
2436 | otherwise = PLam fc x xfc (sm 0 t) sc
2437 sm 0 (PPi p x fc t sc) | n /= x = PPi p x fc (sm 0 t) (sm 0 sc)
2438 | otherwise = PPi p x fc (sm 0 t) sc
2439 sm 0 (PLet fc rc x xfc t v sc) | n /= x = PLet fc rc x xfc (sm 0 t) (sm 0 v) (sm 0 sc)
2440 | otherwise = PLet fc rc x xfc (sm 0 t) (sm 0 v) sc
2441 sm 0 (PApp f x as) = PApp f (sm 0 x) (map (fmap (sm 0)) as)
2442 sm 0 (PAppBind f x as) = PAppBind f (sm 0 x) (map (fmap (sm 0)) as)
2443 sm 0 (PCase f x as) = PCase f (sm 0 x) (map (pmap (sm 0)) as)
2444 sm 0 (PIfThenElse fc c t f) = PIfThenElse fc (sm 0 c) (sm 0 t) (sm 0 f)
2445 sm 0 (PRewrite f by x y tm) = PRewrite f by (sm 0 x) (sm 0 y) (fmap (sm 0) tm)
2446 sm 0 (PTyped x y) = PTyped (sm 0 x) (sm 0 y)
2447 sm 0 (PPair f hls p x y) = PPair f hls p (sm 0 x) (sm 0 y)
2448 sm 0 (PDPair f hls p x t y) = PDPair f hls p (sm 0 x) (sm 0 t) (sm 0 y)
2449 sm 0 (PAlternative ms a as)
2450 = PAlternative (map shadowAlt ms) a (map (sm 0) as)
2451 sm 0 (PTactics ts) = PTactics (map (fmap (sm 0)) ts)
2452 sm 0 (PProof ts) = PProof (map (fmap (sm 0)) ts)
2453 sm 0 (PHidden x) = PHidden (sm 0 x)
2454 sm 0 (PUnifyLog x) = PUnifyLog (sm 0 x)
2455 sm 0 (PNoImplicits x) = PNoImplicits (sm 0 x)
2456 sm 0 (PCoerced t) = PCoerced (sm 0 t)
2457 sm ql (PQuasiquote tm ty) = PQuasiquote (sm (ql + 1) tm) (fmap (sm ql) ty)
2458 sm ql (PUnquote tm) = PUnquote (sm (ql - 1) tm)
2459 sm ql x = descend (sm ql) x
2461 shadowAlt p@(x, oldn) = (update x, update oldn)
2462 update oldn | n == oldn = n'
2463 | otherwise = oldn
2465-- | Rename any binders which are repeated (so that we don't have to
2466-- mess about with shadowing anywhere else).
2467mkUniqueNames :: [Name] -> [(Name, Name)] -> PTerm -> PTerm
2468mkUniqueNames env shadows tm
2469 = evalState (mkUniq 0 initMap tm) (S.fromList env) where
2471 initMap = M.fromList shadows
2473 inScope :: S.Set Name
2474 inScope = S.fromList $ boundNamesIn tm
2476 mkUniqA ql nmap arg = do t' <- mkUniq ql nmap (getTm arg)
2477 return (arg { getTm = t' })
2479 -- Initialise the unique name with the environment length (so we're not
2480 -- looking for too long...)
2481 initN (UN n) l = UN $ txt (str n ++ show l)
2482 initN (MN i s) l = MN (i+l) s
2483 initN n _ = n
2485 -- FIXME: Probably ought to do this for completeness! It's fine as
2486 -- long as there are no bindings inside tactics though.
2487 mkUniqT _ nmap tac = return tac
2489 mkUniq :: Int -- ^ The number of quotations that we're under
2490 -> M.Map Name Name -> PTerm -> State (S.Set Name) PTerm
2491 mkUniq 0 nmap (PLam fc n nfc ty sc)
2492 = do env <- get
2493 (n', sc') <-
2494 if n `S.member` env
2495 then do let n' = uniqueNameSet (initN n (S.size env))
2496 (S.union env inScope)
2497 return (n', sc) -- shadow n n' sc)
2498 else return (n, sc)
2499 put (S.insert n' env)
2500 let nmap' = M.insert n n' nmap
2501 ty' <- mkUniq 0 nmap ty
2502 sc'' <- mkUniq 0 nmap' sc'
2503 return $! PLam fc n' nfc ty' sc''
2504 mkUniq 0 nmap (PPi p n fc ty sc)
2505 = do env <- get
2506 (n', sc') <-
2507 if n `S.member` env
2508 then do let n' = uniqueNameSet (initN n (S.size env))
2509 (S.union env inScope)
2510 return (n', sc) -- shadow n n' sc)
2511 else return (n, sc)
2512 put (S.insert n' env)
2513 let nmap' = M.insert n n' nmap
2514 ty' <- mkUniq 0 nmap ty
2515 sc'' <- mkUniq 0 nmap' sc'
2516 return $! PPi p n' fc ty' sc''
2517 mkUniq 0 nmap (PLet fc rc n nfc ty val sc)
2518 = do env <- get
2519 (n', sc') <-
2520 if n `S.member` env
2521 then do let n' = uniqueNameSet (initN n (S.size env))
2522 (S.union env inScope)
2523 return (n', sc) -- shadow n n' sc)
2524 else return (n, sc)
2525 put (S.insert n' env)
2526 let nmap' = M.insert n n' nmap
2527 ty' <- mkUniq 0 nmap ty; val' <- mkUniq 0 nmap val
2528 sc'' <- mkUniq 0 nmap' sc'
2529 return $! PLet fc rc n' nfc ty' val' sc''
2530 mkUniq 0 nmap (PApp fc t args)
2531 = do t' <- mkUniq 0 nmap t
2532 args' <- mapM (mkUniqA 0 nmap) args
2533 return $! PApp fc t' args'
2534 mkUniq 0 nmap (PAppBind fc t args)
2535 = do t' <- mkUniq 0 nmap t
2536 args' <- mapM (mkUniqA 0 nmap) args
2537 return $! PAppBind fc t' args'
2538 mkUniq 0 nmap (PCase fc t alts)
2539 = do t' <- mkUniq 0 nmap t
2540 alts' <- mapM (\(x,y)-> do x' <- mkUniq 0 nmap x; y' <- mkUniq 0 nmap y
2541 return (x', y')) alts
2542 return $! PCase fc t' alts'
2543 mkUniq 0 nmap (PIfThenElse fc c t f)
2544 = liftM3 (PIfThenElse fc) (mkUniq 0 nmap c) (mkUniq 0 nmap t) (mkUniq 0 nmap f)
2545 mkUniq 0 nmap (PPair fc hls p l r)
2546 = do l' <- mkUniq 0 nmap l; r' <- mkUniq 0 nmap r
2547 return $! PPair fc hls p l' r'
2548 mkUniq 0 nmap (PDPair fc hls p (PRef fc' hls' n) t sc)
2549 | t /= Placeholder
2550 = do env <- get
2551 (n', sc') <- if n `S.member` env
2552 then do let n' = uniqueNameSet n (S.union env inScope)
2553 return (n', sc) -- shadow n n' sc)
2554 else return (n, sc)
2555 put (S.insert n' env)
2556 let nmap' = M.insert n n' nmap
2557 t' <- mkUniq 0 nmap t
2558 sc'' <- mkUniq 0 nmap' sc'
2559 return $! PDPair fc hls p (PRef fc' hls' n') t' sc''
2560 mkUniq 0 nmap (PDPair fc hls p l t r)
2561 = do l' <- mkUniq 0 nmap l; t' <- mkUniq 0 nmap t; r' <- mkUniq 0 nmap r
2562 return $! PDPair fc hls p l' t' r'
2563 mkUniq 0 nmap (PAlternative ns b as)
2564 -- store the nmap and defer the rest until we've pruned the set
2565 -- during elaboration
2566 = return $ PAlternative (ns ++ M.toList nmap) b as
2567 mkUniq 0 nmap (PHidden t) = liftM PHidden (mkUniq 0 nmap t)
2568 mkUniq 0 nmap (PUnifyLog t) = liftM PUnifyLog (mkUniq 0 nmap t)
2569 mkUniq 0 nmap (PDisamb n t) = liftM (PDisamb n) (mkUniq 0 nmap t)
2570 mkUniq 0 nmap (PNoImplicits t) = liftM PNoImplicits (mkUniq 0 nmap t)
2571 mkUniq 0 nmap (PProof ts) = liftM PProof (mapM (mkUniqT 0 nmap) ts)
2572 mkUniq 0 nmap (PTactics ts) = liftM PTactics (mapM (mkUniqT 0 nmap) ts)
2573 mkUniq 0 nmap (PRunElab fc ts ns) = liftM (\tm -> PRunElab fc tm ns) (mkUniq 0 nmap ts)
2574 mkUniq 0 nmap (PConstSugar fc tm) = liftM (PConstSugar fc) (mkUniq 0 nmap tm)
2575 mkUniq 0 nmap (PCoerced tm) = liftM PCoerced (mkUniq 0 nmap tm)
2576 mkUniq 0 nmap t = return $ shadowAll (M.toList nmap) t
2577 where
2578 shadowAll [] t = t
2579 shadowAll ((n, n') : ns) t = shadow n n' (shadowAll ns t)
2581 mkUniq ql nmap (PQuasiquote tm ty) =
2582 do tm' <- mkUniq (ql + 1) nmap tm
2583 ty' <- case ty of
2584 Nothing -> return Nothing
2585 Just t -> fmap Just $ mkUniq ql nmap t
2586 return $! PQuasiquote tm' ty'
2587 mkUniq ql nmap (PUnquote tm) = fmap PUnquote (mkUniq (ql - 1) nmap tm)
2589 mkUniq ql nmap tm = descendM (mkUniq ql nmap) tm