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