on b56ef01 help sign in
Idris-dev/src/Idris/AbsSyntax.hs
2601 lines 110 kB history raw
1{-|
2Module : Idris.AbsSyntax
3Description : Provides Idris' core data definitions and utility code.
5License : BSD3
6Maintainer : The Idris Community.
7-}
9{-# LANGUAGE DeriveFunctor, FlexibleContexts, PatternGuards #-}
10{-# OPTIONS_GHC -fwarn-unused-imports #-}
12module Idris.AbsSyntax(
13 module Idris.AbsSyntax
14 , module Idris.AbsSyntaxTree
15 ) where
17import Idris.AbsSyntaxTree
18import Idris.Colours
19import Idris.Core.Evaluate
20import Idris.Core.TT
21import Idris.Docstrings
22import Idris.IdeMode hiding (Opt(..))
23import Idris.Options
24import IRTS.CodegenCommon
26import System.Directory (canonicalizePath, doesFileExist)
27import System.IO
29import Control.Applicative
30import Control.Monad.State
31import Prelude hiding (Applicative, Foldable, Traversable, (<$>))
33import Data.Char
34import Data.Either
35import Data.List hiding (insert, union)
36import qualified Data.Map as M
37import Data.Maybe
38import qualified Data.Set as S
39import qualified Data.Text as T
40import System.IO.Error (tryIOError)
42import Data.Generics.Uniplate.Data (descend, descendM)
44import Util.DynamicLinker
45import Util.Pretty
46import Util.System
48getContext :: Idris Context
49getContext = do i <- getIState; return (tt_ctxt i)
51forCodegen :: Codegen -> [(Codegen, a)] -> [a]
52forCodegen tgt xs = [x | (tgt', x) <- xs, eqLang tgt tgt']
53 where
54 eqLang (Via _ x) (Via _ y) = x == y
55 eqLang Bytecode Bytecode = True
56 eqLang _ _ = False
58getObjectFiles :: Codegen -> Idris [FilePath]
59getObjectFiles tgt = do i <- getIState; return (forCodegen tgt $ idris_objs i)
61addObjectFile :: Codegen -> FilePath -> Idris ()
62addObjectFile tgt f = do i <- getIState; putIState $ i { idris_objs = nub $ idris_objs i ++ [(tgt, f)] }
64getLibs :: Codegen -> Idris [String]
65getLibs tgt = do i <- getIState; return (forCodegen tgt $ idris_libs i)
67addLib :: Codegen -> String -> Idris ()
68addLib tgt f = do i <- getIState; putIState $ i { idris_libs = nub $ idris_libs i ++ [(tgt, f)] }
70getFlags :: Codegen -> Idris [String]
71getFlags tgt = do i <- getIState; return (forCodegen tgt $ idris_cgflags i)
73addFlag :: Codegen -> String -> Idris ()
74addFlag tgt f = do i <- getIState; putIState $ i { idris_cgflags = nub $ idris_cgflags i ++ [(tgt, f)] }
76addDyLib :: [String] -> Idris (Either DynamicLib String)
77addDyLib libs = do i <- getIState
78 let ls = idris_dynamic_libs i
79 let importdirs = opt_importdirs (idris_options i)
80 case mapMaybe (findDyLib ls) libs of
81 x:_ -> return (Left x)
82 [] -> do
83 handle <- lift . lift .
84 mapM (\l -> catchIO (tryLoadLib importdirs l)
85 (\_ -> return Nothing)) $ libs
86 case msum handle of
87 Nothing -> return (Right $ "Could not load dynamic alternatives \"" ++
88 intercalate "," libs ++ "\"")
89 Just x -> do putIState $ i { idris_dynamic_libs = x:ls }
90 return (Left x)
91 where findDyLib :: [DynamicLib] -> String -> Maybe DynamicLib
92 findDyLib [] _ = Nothing
93 findDyLib (lib:libs') l | l == lib_name lib = Just lib
94 | otherwise = findDyLib libs' l
96getAutoImports :: Idris [FilePath]
97getAutoImports = do i <- getIState
98 return (opt_autoImport (idris_options i))
100addAutoImport :: FilePath -> Idris ()
101addAutoImport fp = do i <- getIState
102 let opts = idris_options i
103 put (i { idris_options = opts { opt_autoImport =
104 fp : opt_autoImport opts } } )
106addDefinedName :: Name -> Idris ()
107addDefinedName n = do ist <- getIState
108 putIState $ ist { idris_inmodule = S.insert n (idris_inmodule ist) }
110getDefinedNames :: Idris [Name]
111getDefinedNames = do ist <- getIState
112 return (S.toList (idris_inmodule ist))
114addTT :: Term -> Idris (Maybe Term)
115addTT t = do ist <- getIState
116 case M.lookup t (idris_ttstats ist) of
117 Nothing -> do let tt' = M.insert t (1, t) (idris_ttstats ist)
118 putIState $ ist { idris_ttstats = tt' }
119 return Nothing
120 Just (i, t') -> do let tt' = M.insert t' (i + 1, t') (idris_ttstats ist)
121 putIState $ ist { idris_ttstats = tt' }
122 return (Just t')
124dumpTT :: Idris ()
125dumpTT = do ist <- get
126 let sts = sortBy count (M.toList (idris_ttstats ist))
127 mapM_ dump sts
128 return ()
129 where
130 count (_,x) (_,y) = compare y x
131 dump (tm, val) = runIO $ putStrLn (show val ++ ": " ++ show tm)
133addHdr :: Codegen -> String -> Idris ()
134addHdr tgt f = do i <- getIState; putIState $ i { idris_hdrs = nub $ (tgt, f) : idris_hdrs i }
136addImported :: Bool -> FilePath -> Idris ()
137addImported pub f
138 = do i <- getIState
139 putIState $ i { idris_imported = nub $ (f, pub) : idris_imported i }
141addLangExt :: LanguageExt -> Idris ()
142addLangExt e = do i <- getIState
143 putIState $ i {
144 idris_language_extensions = e : idris_language_extensions i
145 }
147dropLangExt :: LanguageExt -> Idris ()
148dropLangExt e = do i <- getIState
149 putIState $ i {
150 idris_language_extensions = idris_language_extensions i \\ [e]
151 }
153-- | Transforms are organised by the function being applied on the lhs
154-- of the transform, to make looking up appropriate transforms quicker
155addTrans :: Name -> (Term, Term) -> Idris ()
156addTrans basefn t
157 = do i <- getIState
158 let t' = case lookupCtxtExact basefn (idris_transforms i) of
159 Just def -> (t : def)
160 Nothing -> [t]
161 putIState $ i { idris_transforms = addDef basefn t'
162 (idris_transforms i) }
164-- | Add transformation rules from a definition, which will reverse the
165-- definition for an error to make it more readable
166addErrRev :: (Term, Term) -> Idris ()
167addErrRev t = do i <- getIState
168 putIState $ i { idris_errRev = t : idris_errRev i }
170-- | Say that the name should always be reduced in error messages, to
171-- help readability/error reflection
172addErrReduce :: Name -> Idris ()
173addErrReduce t = do i <- getIState
174 putIState $ i { idris_errReduce = t : idris_errReduce i }
176addErasureUsage :: Name -> Int -> Idris ()
177addErasureUsage n i = do ist <- getIState
178 putIState $ ist { idris_erasureUsed = (n, i) : idris_erasureUsed ist }
180addExport :: Name -> Idris ()
181addExport n = do ist <- getIState
182 putIState $ ist { idris_exports = n : idris_exports ist }
184addUsedName :: FC -> Name -> Name -> Idris ()
185addUsedName fc n arg
186 = do ist <- getIState
187 case lookupTyName n (tt_ctxt ist) of
188 [(n', ty)] -> addUsage n' 0 ty
189 [] -> throwError (At fc (NoSuchVariable n))
190 xs -> throwError (At fc (CantResolveAlts (map fst xs)))
191 where addUsage n i (Bind x _ sc) | x == arg = do addIBC (IBCUsage (n, i))
192 addErasureUsage n i
193 | otherwise = addUsage n (i + 1) sc
194 addUsage _ _ _ = throwError (At fc (Msg ("No such argument name " ++ show arg)))
196getErasureUsage :: Idris [(Name, Int)]
197getErasureUsage = do ist <- getIState;
198 return (idris_erasureUsed ist)
200getExports :: Idris [Name]
201getExports = do ist <- getIState
202 return (idris_exports ist)
204totcheck :: (FC, Name) -> Idris ()
205totcheck n = do i <- getIState; putIState $ i { idris_totcheck = idris_totcheck i ++ [n] }
207defer_totcheck :: (FC, Name) -> Idris ()
208defer_totcheck n
209 = do i <- getIState;
210 putIState $ i { idris_defertotcheck = nub (idris_defertotcheck i ++ [n]) }
212clear_totcheck :: Idris ()
213clear_totcheck = do i <- getIState; putIState $ i { idris_totcheck = [] }
215setFlags :: Name -> [FnOpt] -> Idris ()
216setFlags n fs = do i <- getIState; putIState $ i { idris_flags = addDef n fs (idris_flags i) }
218addFnOpt :: Name -> FnOpt -> Idris ()
219addFnOpt n f = do i <- getIState
220 let fls = case lookupCtxtExact n (idris_flags i) of
221 Nothing -> []
222 Just x -> x
223 setFlags n (f : fls)
225setFnInfo :: Name -> FnInfo -> Idris ()
226setFnInfo n fs = do i <- getIState; putIState $ i { idris_fninfo = addDef n fs (idris_fninfo i) }
228setAccessibility :: Name -> Accessibility -> Idris ()
229setAccessibility n a
230 = do i <- getIState
231 let ctxt = setAccess n a (tt_ctxt i)
232 putIState $ i { tt_ctxt = ctxt }
234-- | get the accessibility of a name outside this module
235getFromHideList :: Name -> Idris (Maybe Accessibility)
236getFromHideList n = do i <- getIState
237 return $ lookupCtxtExact n (hide_list i)
239setTotality :: Name -> Totality -> Idris ()
240setTotality n a
241 = do i <- getIState
242 let ctxt = setTotal n a (tt_ctxt i)
243 putIState $ i { tt_ctxt = ctxt }
245setInjectivity :: Name -> Injectivity -> Idris ()
246setInjectivity n a
247 = do i <- getIState
248 let ctxt = setInjective n a (tt_ctxt i)
249 putIState $ i { tt_ctxt = ctxt }
251getTotality :: Name -> Idris Totality
252getTotality n
253 = do i <- getIState
254 case lookupTotal n (tt_ctxt i) of
255 [t] -> return t
256 _ -> return (Total [])
258-- Get coercions which might return the required type
259getCoercionsTo :: IState -> Type -> [Name]
260getCoercionsTo i ty =
261 let cs = idris_coercions i
262 (fn,_) = unApply (getRetTy ty) in
263 findCoercions fn cs
264 where findCoercions _ [] = []
265 findCoercions t (n : ns) =
266 let ps = case lookupTy n (tt_ctxt i) of
267 [ty'] -> case unApply (getRetTy (normalise (tt_ctxt i) [] ty')) of
268 (t', _) -> [n | t == t']
269 _ -> [] in
270 ps ++ findCoercions t ns
272addToCG :: Name -> CGInfo -> Idris ()
273addToCG n cg
274 = do i <- getIState
275 putIState $ i { idris_callgraph = addDef n cg (idris_callgraph i) }
277addCalls :: Name -> [Name] -> Idris ()
278addCalls n calls
279 = do i <- getIState
280 case lookupCtxtExact n (idris_callgraph i) of
281 Nothing -> addToCG n (CGInfo calls Nothing [] [])
282 Just (CGInfo cs ans scg used) ->
283 addToCG n (CGInfo (nub (calls ++ cs)) ans scg used)
285addTyInferred :: Name -> Idris ()
286addTyInferred n
287 = do i <- getIState
288 putIState $ i { idris_tyinfodata =
289 addDef n TIPartial (idris_tyinfodata i) }
291addTyInfConstraints :: FC -> [(Term, Term)] -> Idris ()
292addTyInfConstraints fc ts = do logLvl 2 $ "TI missing: " ++ show ts
293 mapM_ addConstraint ts
294 return ()
295 where addConstraint (x, y) = findMVApps x y
297 findMVApps x y
298 = do let (fx, argsx) = unApply x
299 let (fy, argsy) = unApply y
300 if (fx /= fy)
301 then do
302 tryAddMV fx y
303 tryAddMV fy x
304 else mapM_ addConstraint (zip argsx argsy)
306 tryAddMV (P _ mv _) y =
307 do ist <- get
308 case lookup mv (idris_metavars ist) of
309 Just _ -> addConstraintRule mv y
310 _ -> return ()
311 tryAddMV _ _ = return ()
313 addConstraintRule :: Name -> Term -> Idris ()
314 addConstraintRule n t
315 = do ist <- get
316 logLvl 1 $ "TI constraint: " ++ show (n, t)
317 case lookupCtxt n (idris_tyinfodata ist) of
318 [TISolution ts] ->
319 do mapM_ (checkConsistent t) ts
320 let ti' = addDef n (TISolution (t : ts))
321 (idris_tyinfodata ist)
322 put $ ist { idris_tyinfodata = ti' }
323 _ ->
324 do let ti' = addDef n (TISolution [t])
325 (idris_tyinfodata ist)
326 put $ ist { idris_tyinfodata = ti' }
328 -- Check a solution is consistent with previous solutions
329 -- Meaning: If heads are both data types, they had better be the
330 -- same.
331 checkConsistent :: Term -> Term -> Idris ()
332 checkConsistent x y =
333 do let (fx, _) = unApply x
334 let (fy, _) = unApply y
335 case (fx, fy) of
336 (P (TCon _ _) n _, P (TCon _ _) n' _) -> errWhen (n/=n')
337 (P (TCon _ _) n _, Constant _) -> errWhen True
338 (Constant _, P (TCon _ _) n' _) -> errWhen True
339 (P (DCon _ _ _) n _, P (DCon _ _ _) n' _) -> errWhen (n/=n')
340 _ -> return ()
342 where errWhen True
343 = throwError (At fc
344 (CantUnify False (x, Nothing) (y, Nothing) (Msg "") [] 0))
345 errWhen False = return ()
347isTyInferred :: Name -> Idris Bool
348isTyInferred n
349 = do i <- getIState
350 case lookupCtxt n (idris_tyinfodata i) of
351 [TIPartial] -> return True
352 _ -> return False
354-- | Adds error handlers for a particular function and argument. If
355-- names are ambiguous, all matching handlers are updated.
356addFunctionErrorHandlers :: Name -> Name -> [Name] -> Idris ()
357addFunctionErrorHandlers f arg hs =
358 do i <- getIState
359 let oldHandlers = idris_function_errorhandlers i
360 let newHandlers = flip (addDef f) oldHandlers $
361 case lookupCtxtExact f oldHandlers of
362 Nothing -> M.singleton arg (S.fromList hs)
363 Just (oldHandlers) -> M.insertWith S.union arg (S.fromList hs) oldHandlers
364 -- will always be one of those two, thus no extra case
365 putIState $ i { idris_function_errorhandlers = newHandlers }
367-- | Trace all the names in a call graph starting at the given name
368getAllNames :: Name -> Idris [Name]
369getAllNames n = do i <- getIState
370 case getCGAllNames i n of
371 Just ns -> return ns
372 Nothing -> do ns <- allNames [] n
373 addCGAllNames i n ns
374 return ns
376getCGAllNames :: IState -> Name -> Maybe [Name]
377getCGAllNames i n = case lookupCtxtExact n (idris_callgraph i) of
378 Just ci -> allCalls ci
379 _ -> Nothing
381addCGAllNames :: IState -> Name -> [Name] -> Idris ()
382addCGAllNames i n ns
383 = case lookupCtxtExact n (idris_callgraph i) of
384 Just ci -> addToCG n (ci { allCalls = Just ns })
385 _ -> addToCG n (CGInfo [] (Just ns) [] [])
387allNames :: [Name] -> Name -> Idris [Name]
388allNames ns n | n `elem` ns = return []
389allNames ns n = do i <- getIState
390 case getCGAllNames i n of
391 Just ns -> return ns
392 Nothing -> case lookupCtxtExact n (idris_callgraph i) of
393 Just ci ->
394 do more <- mapM (allNames (n:ns)) (calls ci)
395 let ns' = nub (n : concat more)
396 addCGAllNames i n ns'
397 return ns'
398 _ -> return [n]
400addCoercion :: Name -> Idris ()
401addCoercion n = do i <- getIState
402 putIState $ i { idris_coercions = nub $ n : idris_coercions i }
404addDocStr :: Name -> Docstring DocTerm -> [(Name, Docstring DocTerm)] -> Idris ()
405addDocStr n doc args
406 = do i <- getIState
407 putIState $ i { idris_docstrings = addDef n (doc, args) (idris_docstrings i) }
409addNameHint :: Name -> Name -> Idris ()
410addNameHint ty n
411 = do i <- getIState
412 ty' <- case lookupCtxtName ty (idris_implicits i) of
413 [(tyn, _)] -> return tyn
414 [] -> throwError (NoSuchVariable ty)
415 tyns -> throwError (CantResolveAlts (map fst tyns))
416 let ns' = case lookupCtxt ty' (idris_namehints i) of
417 [ns] -> ns ++ [n]
418 _ -> [n]
419 putIState $ i { idris_namehints = addDef ty' ns' (idris_namehints i) }
421getNameHints :: IState -> Name -> [Name]
422getNameHints _ (UN arr) | arr == txt "->" = [sUN "f",sUN "g"]
423getNameHints i n =
424 case lookupCtxt n (idris_namehints i) of
425 [ns] -> ns
426 _ -> []
428addDeprecated :: Name -> String -> Idris ()
429addDeprecated n reason = do
430 i <- getIState
431 putIState $ i { idris_deprecated = addDef n reason (idris_deprecated i) }
433getDeprecated :: Name -> Idris (Maybe String)
434getDeprecated n = do
435 i <- getIState
436 return $ lookupCtxtExact n (idris_deprecated i)
438addFragile :: Name -> String -> Idris ()
439addFragile n reason = do
440 i <- getIState
441 putIState $ i { idris_fragile = addDef n reason (idris_fragile i) }
443getFragile :: Name -> Idris (Maybe String)
444getFragile n = do
445 i <- getIState
446 return $ lookupCtxtExact n (idris_fragile i)
448push_estack :: Name -> Bool -> Idris ()
449push_estack n implementation
450 = do i <- getIState
451 putIState (i { elab_stack = (n, implementation) : elab_stack i })
453pop_estack :: Idris ()
454pop_estack = do i <- getIState
455 putIState (i { elab_stack = ptail (elab_stack i) })
456 where ptail [] = []
457 ptail (_ : xs) = xs
459-- | Add an interface implementation function.
460--
461-- Precondition: the implementation should have the correct type.
462--
463-- Dodgy hack 1: Put integer implementations first in the list so they are
464-- resolved by default.
465--
466-- Dodgy hack 2: put constraint chasers (ParentN) last
467addImplementation :: Bool -- ^ whether the name is an Integer implementation
468 -> Bool -- ^ whether to include the implementation in implementation search
469 -> Name -- ^ the name of the interface
470 -> Name -- ^ the name of the implementation
471 -> Idris ()
472addImplementation int res n i
473 = do ist <- getIState
474 case lookupCtxt n (idris_interfaces ist) of
475 [CI a b c d e f g ins fds] ->
476 do let cs = addDef n (CI a b c d e f g (addI i ins) fds) (idris_interfaces ist)
477 putIState $ ist { idris_interfaces = cs }
478 _ -> do let cs = addDef n (CI (sMN 0 "none") [] [] [] [] [] [] [(i, res)] []) (idris_interfaces ist)
479 putIState $ ist { idris_interfaces = cs }
480 where addI, insI :: Name -> [(Name, Bool)] -> [(Name, Bool)]
481 addI i ins | int = (i, res) : ins
482 | chaser n = ins ++ [(i, res)]
483 | otherwise = insI i ins
484 insI i [] = [(i, res)]
485 insI i (n : ns) | chaser (fst n) = (i, res) : n : ns
486 | otherwise = n : insI i ns
488 chaser (SN (ParentN _ _)) = True
489 chaser (NS n _) = chaser n
490 chaser _ = False
492-- | Add a privileged implementation - one which implementation search will
493-- happily resolve immediately if it is type correct This is used for
494-- naming parent implementations when defining an implementation with
495-- constraints. Returns the old list, so we can revert easily at the
496-- end of a block
497addOpenImpl :: [Name] -> Idris [Name]
498addOpenImpl ns = do ist <- getIState
499 ns' <- mapM (checkValid ist) ns
500 let open = idris_openimpls ist
501 putIState $ ist { idris_openimpls = nub (ns' ++ open) }
502 return open
503 where
504 checkValid ist n
505 = case lookupCtxtName n (idris_implicits ist) of
506 [(n', _)] -> return n'
507 [] -> throwError (NoSuchVariable n)
508 more -> throwError (CantResolveAlts (map fst more))
510setOpenImpl :: [Name] -> Idris ()
511setOpenImpl ns = do ist <- getIState
512 putIState $ ist { idris_openimpls = ns }
514getOpenImpl :: Idris [Name]
515getOpenImpl = do ist <- getIState
516 return (idris_openimpls ist)
518addInterface :: Name -> InterfaceInfo -> Idris ()
519addInterface n i
520 = do ist <- getIState
521 let i' = case lookupCtxt n (idris_interfaces ist) of
522 [c] -> i { interface_implementations = interface_implementations c ++
523 interface_implementations i }
524 _ -> i
525 putIState $ ist { idris_interfaces = addDef n i' (idris_interfaces ist) }
527updateIMethods :: Name -> [(Name, PTerm)] -> Idris ()
528updateIMethods n meths
529 = do ist <- getIState
530 let i = case lookupCtxtExact n (idris_interfaces ist) of
531 Just c -> c { interface_methods = update (interface_methods c) }
532 Nothing -> error "Can't happen updateIMethods"
533 putIState $ ist { idris_interfaces = addDef n i (idris_interfaces ist) }
534 where
535 update [] = []
536 update (m@(n, (b, opts, t)) : rest)
537 | Just ty <- lookup n meths
538 = (n, (b, opts, ty)) : update rest
539 | otherwise = m : update rest
541addRecord :: Name -> RecordInfo -> Idris ()
542addRecord n ri = do ist <- getIState
543 putIState $ ist { idris_records = addDef n ri (idris_records ist) }
545addAutoHint :: Name -> Name -> Idris ()
546addAutoHint n hint =
547 do ist <- getIState
548 case lookupCtxtExact n (idris_autohints ist) of
549 Nothing ->
550 do let hs = addDef n [hint] (idris_autohints ist)
551 putIState $ ist { idris_autohints = hs }
552 Just nhints ->
553 do let hs = addDef n (hint : nhints) (idris_autohints ist)
554 putIState $ ist { idris_autohints = hs }
556getAutoHints :: Name -> Idris [Name]
557getAutoHints n = do ist <- getIState
558 case lookupCtxtExact n (idris_autohints ist) of
559 Nothing -> return []
560 Just ns -> return ns
562addIBC :: IBCWrite -> Idris ()
563addIBC ibc@(IBCDef n)
564 = do i <- getIState
565 when (notDef (ibc_write i)) $
566 putIState $ i { ibc_write = ibc : ibc_write i }
567 where notDef [] = True
568 notDef (IBCDef n': _) | n == n' = False
569 notDef (_ : is) = notDef is
570addIBC ibc = do i <- getIState; putIState $ i { ibc_write = ibc : ibc_write i }
572clearIBC :: Idris ()
573clearIBC = do i <- getIState; putIState $ i { ibc_write = [],
574 idris_inmodule = S.empty }
576resetNameIdx :: Idris ()
577resetNameIdx = do i <- getIState
578 put (i { idris_nameIdx = (0, emptyContext) })
580-- | Used to preserve sharing of names
581addNameIdx :: Name -> Idris (Int, Name)
582addNameIdx n = do i <- getIState
583 let (i', x) = addNameIdx' i n
584 putIState i'
585 return x
587addNameIdx' :: IState -> Name -> (IState, (Int, Name))
588addNameIdx' i n
589 = let idxs = snd (idris_nameIdx i) in
590 case lookupCtxt n idxs of
591 [x] -> (i, x)
592 _ -> let i' = fst (idris_nameIdx i) + 1 in
593 (i { idris_nameIdx = (i', addDef n (i', n) idxs) }, (i', n))
595getSymbol :: Name -> Idris Name
596getSymbol n = do i <- getIState
597 case M.lookup n (idris_symbols i) of
598 Just n' -> return n'
599 Nothing -> do let sym' = M.insert n n (idris_symbols i)
600 put (i { idris_symbols = sym' })
601 return n
603getHdrs :: Codegen -> Idris [String]
604getHdrs tgt = do i <- getIState; return (forCodegen tgt $ idris_hdrs i)
606getImported :: Idris [(FilePath, Bool)]
607getImported = idris_imported `fmap` getIState
609setErrSpan :: FC -> Idris ()
610setErrSpan x = do i <- getIState;
611 case (errSpan i) of
612 Nothing -> putIState $ i { errSpan = Just x }
613 Just _ -> return ()
615clearErr :: Idris ()
616clearErr = do i <- getIState
617 putIState $ i { errSpan = Nothing }
619getSO :: Idris (Maybe String)
620getSO = do i <- getIState
621 return (compiled_so i)
623setSO :: Maybe String -> Idris ()
624setSO s = do i <- getIState
625 putIState (i { compiled_so = s })
627getIState :: Idris IState
628getIState = get
630putIState :: IState -> Idris ()
631putIState = put
633updateIState :: (IState -> IState) -> Idris ()
634updateIState f = do i <- getIState
635 putIState $ f i
637withContext :: (IState -> Ctxt a) -> Name -> b -> (a -> Idris b) -> Idris b
638withContext ctx name dflt action = do
639 ist <- getIState
640 case lookupCtxt name (ctx ist) of
641 [x] -> action x
642 _ -> return dflt
644withContext_ :: (IState -> Ctxt a) -> Name -> (a -> Idris ()) -> Idris ()
645withContext_ ctx name action = withContext ctx name () action
647-- | A version of liftIO that puts errors into the exception type of
648-- the Idris monad
649runIO :: IO a -> Idris a
650runIO x = liftIO (tryIOError x) >>= either (throwError . Msg . show) return
651-- TODO: create specific Idris exceptions for specific IO errors such as "openFile: does not exist"
652--
653-- Issue #1738 on the issue tracker.
654-- https://github.com/idris-lang/Idris-dev/issues/1738
656getName :: Idris Int
657getName = do i <- getIState;
658 let idx = idris_name i;
659 putIState (i { idris_name = idx + 1 })
660 return idx
662-- | InternalApp keeps track of the real function application for
663-- making case splits from, not the application the programmer wrote,
664-- which doesn't have the whole context in any case other than top
665-- level definitions
666addInternalApp :: FilePath -> Int -> PTerm -> Idris ()
667addInternalApp fp l t
668 = do i <- getIState
669 -- We canonicalise the path to make "./Test/Module.idr" equal
670 -- to "Test/Module.idr"
671 exists <- runIO $ doesFileExist fp
672 when exists $
673 do fp' <- runIO $ canonicalizePath fp
674 putIState (i { idris_lineapps = ((fp', l), t) : idris_lineapps i })
676getInternalApp :: FilePath -> Int -> Idris PTerm
677getInternalApp fp l = do i <- getIState
678 -- We canonicalise the path to make
679 -- "./Test/Module.idr" equal to
680 -- "Test/Module.idr"
681 exists <- runIO $ doesFileExist fp
682 if exists
683 then do fp' <- runIO $ canonicalizePath fp
684 case lookup (fp', l) (idris_lineapps i) of
685 Just n' -> return n'
686 Nothing -> return Placeholder
687 -- TODO: What if it's not there?
688 else return Placeholder
690-- | Pattern definitions are only used for coverage checking, so erase
691-- them when we're done
692clearOrigPats :: Idris ()
693clearOrigPats = do i <- get
694 let ps = idris_patdefs i
695 let ps' = mapCtxt (\ (_,miss) -> ([], miss)) ps
696 put (i { idris_patdefs = ps' })
698-- | Erase types from Ps in the context (basically ending up with
699-- what's in the .ibc, which is all we need after all the analysis is
700-- done)
701clearPTypes :: Idris ()
702clearPTypes = do i <- get
703 let ctxt = tt_ctxt i
704 put (i { tt_ctxt = mapDefCtxt pErase ctxt })
705 where pErase (CaseOp c t tys orig _ cds)
706 = CaseOp c t tys orig [] (pErase' cds)
707 pErase x = x
708 pErase' (CaseDefs (cs, c) rs)
709 = let c' = (cs, fmap pEraseType c) in
710 CaseDefs c' rs
712checkUndefined :: FC -> Name -> Idris ()
713checkUndefined fc n
714 = do i <- getContext
715 case lookupTy n i of
716 (_:_) -> throwError . Msg $ show fc ++ ":" ++
717 show n ++ " already defined"
718 _ -> return ()
720isUndefined :: FC -> Name -> Idris Bool
721isUndefined _ n
722 = do i <- getContext
723 case lookupTyExact n i of
724 Just _ -> return False
725 _ -> return True
727setContext :: Context -> Idris ()
728setContext ctxt = do i <- getIState; putIState (i { tt_ctxt = ctxt } )
730updateContext :: (Context -> Context) -> Idris ()
731updateContext f = do i <- getIState; putIState (i { tt_ctxt = f (tt_ctxt i) } )
733addConstraints :: FC -> (Int, [UConstraint]) -> Idris ()
734addConstraints fc (v, cs)
735 = do tit <- typeInType
736 when (not tit) $ do
737 i <- getIState
738 let ctxt = tt_ctxt i
739 let ctxt' = ctxt { next_tvar = v }
740 let ics = insertAll (zip cs (repeat fc)) (idris_constraints i)
741 putIState $ i { tt_ctxt = ctxt', idris_constraints = ics }
742 where
743 insertAll [] c = c
744 insertAll ((ULE (UVal 0) _, fc) : cs) ics = insertAll cs ics
745 insertAll ((ULE x y, fc) : cs) ics | x == y = insertAll cs ics
746 insertAll ((c, fc) : cs) ics
747 = insertAll cs $ S.insert (ConstraintFC c fc) ics
749addDeferred = addDeferred' Ref
750addDeferredTyCon = addDeferred' (TCon 0 0)
752-- | Save information about a name that is not yet defined
753addDeferred' :: NameType
754 -> [(Name, (Int, Maybe Name, Type, [Name], Bool, Bool))]
755 -- ^ The Name is the name being made into a metavar,
756 -- the Int is the number of vars that are part of a
757 -- putative proof context, the Maybe Name is the
758 -- top-level function containing the new metavariable,
759 -- the Type is its type, and the Bool is whether :p is
760 -- allowed
761 -> Idris ()
762addDeferred' nt ns
763 = do mapM_ (\(n, (i, _, t, _, _, _)) -> updateContext (addTyDecl n nt (tidyNames S.empty t))) ns
764 mapM_ (\(n, _) -> when (not (n `elem` primDefs)) $ addIBC (IBCMetavar n)) ns
765 i <- getIState
766 putIState $ i { idris_metavars = map (\(n, (i, top, _, ns, isTopLevel, isDefinable)) ->
767 (n, (top, i, ns, isTopLevel, isDefinable))) ns ++
768 idris_metavars i }
769 where
770 -- 'tidyNames' is to generate user accessible names in case they are
771 -- needed in tactic scripts
772 tidyNames used (Bind (MN i x) b sc)
773 = let n' = uniqueNameSet (UN x) used in
774 Bind n' b $ tidyNames (S.insert n' used) sc
775 tidyNames used (Bind n b sc)
776 = let n' = uniqueNameSet n used in
777 Bind n' b $ tidyNames (S.insert n' used) sc
778 tidyNames _ b = b
780solveDeferred :: FC -> Name -> Idris ()
781solveDeferred fc n
782 = do i <- getIState
783 case lookup n (idris_metavars i) of
784 Just (_, _, _, _, False) ->
785 throwError $ At fc $ Msg ("Can't define hole " ++ show n ++ " as it depends on other holes")
786 _ -> putIState $ i { idris_metavars =
787 filter (\(n', _) -> n/=n')
788 (idris_metavars i),
789 ibc_write =
790 filter (notMV n) (ibc_write i)
791 }
792 where notMV n (IBCMetavar n') = not (n == n')
793 notMV n _ = True
795getUndefined :: Idris [Name]
796getUndefined = do i <- getIState
797 return (map fst (idris_metavars i) \\ primDefs)
799isMetavarName :: Name -> IState -> Bool
800isMetavarName n ist
801 = case lookupNames n (tt_ctxt ist) of
802 (t:_) -> isJust $ lookup t (idris_metavars ist)
803 _ -> False
805getWidth :: Idris ConsoleWidth
806getWidth = fmap idris_consolewidth getIState
808setWidth :: ConsoleWidth -> Idris ()
809setWidth w = do ist <- getIState
810 put ist { idris_consolewidth = w }
812setDepth :: Maybe Int -> Idris ()
813setDepth d = do ist <- getIState
814 put ist { idris_options = (idris_options ist) { opt_printdepth = d } }
816typeDescription :: String
817typeDescription = "The type of types"
820type1Doc :: Doc OutputAnnotation
821type1Doc = (annotate (AnnType "Type" "The type of types, one level up") $ text "Type 1")
824isetPrompt :: String -> Idris ()
825isetPrompt p = do i <- getIState
826 case idris_outputmode i of
827 IdeMode n h -> runIO . hPutStrLn h $ convSExp "set-prompt" p n
829-- | Tell clients how much was parsed and loaded
830isetLoadedRegion :: Idris ()
831isetLoadedRegion = do i <- getIState
832 let span = idris_parsedSpan i
833 case span of
834 Just fc ->
835 case idris_outputmode i of
836 IdeMode n h ->
837 runIO . hPutStrLn h $
838 convSExp "set-loaded-region" fc n
839 Nothing -> return ()
841setLogLevel :: Int -> Idris ()
842setLogLevel l = do i <- getIState
843 let opts = idris_options i
844 let opt' = opts { opt_logLevel = l }
845 putIState $ i { idris_options = opt' }
847setLogCats :: [LogCat] -> Idris ()
848setLogCats cs = do
849 i <- getIState
850 let opts = idris_options i
851 let opt' = opts { opt_logcats = cs }
852 putIState $ i { idris_options = opt' }
854setCmdLine :: [Opt] -> Idris ()
855setCmdLine opts = do i <- getIState
856 let iopts = idris_options i
857 putIState $ i { idris_options = iopts { opt_cmdline = opts } }
859getCmdLine :: Idris [Opt]
860getCmdLine = do i <- getIState
861 return (opt_cmdline (idris_options i))
863getDumpHighlighting :: Idris Bool
864getDumpHighlighting = do ist <- getIState
865 return (findC (opt_cmdline (idris_options ist)))
866 where findC = elem DumpHighlights
868getDumpDefun :: Idris (Maybe FilePath)
869getDumpDefun = do i <- getIState
870 return $ findC (opt_cmdline (idris_options i))
871 where findC [] = Nothing
872 findC (DumpDefun x : _) = Just x
873 findC (_ : xs) = findC xs
875getDumpCases :: Idris (Maybe FilePath)
876getDumpCases = do i <- getIState
877 return $ findC (opt_cmdline (idris_options i))
878 where findC [] = Nothing
879 findC (DumpCases x : _) = Just x
880 findC (_ : xs) = findC xs
882logLevel :: Idris Int
883logLevel = do i <- getIState
884 return (opt_logLevel (idris_options i))
886setAutoImpls :: Bool -> Idris ()
887setAutoImpls b = do i <- getIState
888 let opts = idris_options i
889 let opt' = opts { opt_autoimpls = b }
890 putIState $ i { idris_options = opt' }
892getAutoImpls :: Idris Bool
893getAutoImpls = do i <- getIState
894 return (opt_autoimpls (idris_options i))
896setErrContext :: Bool -> Idris ()
897setErrContext t = do i <- getIState
898 let opts = idris_options i
899 let opts' = opts { opt_errContext = t }
900 putIState $ i { idris_options = opts' }
902errContext :: Idris Bool
903errContext = do i <- getIState
904 return (opt_errContext (idris_options i))
906getOptimise :: Idris [Optimisation]
907getOptimise = do i <- getIState
908 return (opt_optimise (idris_options i))
910setOptimise :: [Optimisation] -> Idris ()
911setOptimise newopts = do i <- getIState
912 let opts = idris_options i
913 let opts' = opts { opt_optimise = newopts }
914 putIState $ i { idris_options = opts' }
916addOptimise :: Optimisation -> Idris ()
917addOptimise opt = do opts <- getOptimise
918 setOptimise (nub (opt : opts))
920removeOptimise :: Optimisation -> Idris ()
921removeOptimise opt = do opts <- getOptimise
922 setOptimise ((nub opts) \\ [opt])
924-- | Set appropriate optimisation set for the given level. We only
925-- have one optimisation that is configurable at the moment, however!
926setOptLevel :: Int -> Idris ()
927setOptLevel n | n <= 0 = setOptimise []
928setOptLevel 1 = setOptimise []
929setOptLevel 2 = setOptimise [PETransform]
930setOptLevel n | n >= 3 = setOptimise [PETransform]
932useREPL :: Idris Bool
933useREPL = do i <- getIState
934 return (opt_repl (idris_options i))
936setREPL :: Bool -> Idris ()
937setREPL t = do i <- getIState
938 let opts = idris_options i
939 let opt' = opts { opt_repl = t }
940 putIState $ i { idris_options = opt' }
942showOrigErr :: Idris Bool
943showOrigErr = do i <- getIState
944 return (opt_origerr (idris_options i))
946setShowOrigErr :: Bool -> Idris ()
947setShowOrigErr b = do i <- getIState
948 let opts = idris_options i
949 let opt' = opts { opt_origerr = b }
950 putIState $ i { idris_options = opt' }
952setAutoSolve :: Bool -> Idris ()
953setAutoSolve b = do i <- getIState
954 let opts = idris_options i
955 let opt' = opts { opt_autoSolve = b }
956 putIState $ i { idris_options = opt' }
958setNoBanner :: Bool -> Idris ()
959setNoBanner n = do i <- getIState
960 let opts = idris_options i
961 let opt' = opts { opt_nobanner = n }
962 putIState $ i { idris_options = opt' }
964getNoBanner :: Idris Bool
965getNoBanner = do i <- getIState
966 let opts = idris_options i
967 return (opt_nobanner opts)
969setEvalTypes :: Bool -> Idris ()
970setEvalTypes n = do i <- getIState
971 let opts = idris_options i
972 let opt' = opts { opt_evaltypes = n }
973 putIState $ i { idris_options = opt' }
975getDesugarNats :: Idris Bool
976getDesugarNats = do i <- getIState
977 let opts = idris_options i
978 return (opt_desugarnats opts)
981setDesugarNats :: Bool -> Idris ()
982setDesugarNats n = do i <- getIState
983 let opts = idris_options i
984 let opt' = opts { opt_desugarnats = n }
985 putIState $ i { idris_options = opt' }
987setQuiet :: Bool -> Idris ()
988setQuiet q = do i <- getIState
989 let opts = idris_options i
990 let opt' = opts { opt_quiet = q }
991 putIState $ i { idris_options = opt' }
993getQuiet :: Idris Bool
994getQuiet = do i <- getIState
995 let opts = idris_options i
996 return (opt_quiet opts)
998setCodegen :: Codegen -> Idris ()
999setCodegen t = do i <- getIState
1000 let opts = idris_options i
1001 let opt' = opts { opt_codegen = t }
1002 putIState $ i { idris_options = opt' }
1004codegen :: Idris Codegen
1005codegen = do i <- getIState
1006 return (opt_codegen (idris_options i))
1009setOutputTy :: OutputType -> Idris ()
1010setOutputTy t = do i <- getIState
1011 let opts = idris_options i
1012 let opt' = opts { opt_outputTy = t }
1013 putIState $ i { idris_options = opt' }
1015outputTy :: Idris OutputType
1016outputTy = do i <- getIState
1017 return $ opt_outputTy $ idris_options i
1019setIdeMode :: Bool -> Handle -> Idris ()
1020setIdeMode True h = do i <- getIState
1021 putIState $ i { idris_outputmode = IdeMode 0 h
1022 , idris_colourRepl = False
1024setIdeMode False _ = return ()
1026setTargetTriple :: String -> Idris ()
1027setTargetTriple t = do i <- getIState
1028 let opts = idris_options i
1029 opt' = opts { opt_triple = t }
1030 putIState $ i { idris_options = opt' }
1032targetTriple :: Idris String
1033targetTriple = do i <- getIState
1034 return (opt_triple (idris_options i))
1036setTargetCPU :: String -> Idris ()
1037setTargetCPU t = do i <- getIState
1038 let opts = idris_options i
1039 opt' = opts { opt_cpu = t }
1040 putIState $ i { idris_options = opt' }
1042targetCPU :: Idris String
1043targetCPU = do i <- getIState
1044 return (opt_cpu (idris_options i))
1046verbose :: Idris Int
1047verbose = do
1048 i <- getIState
1049 -- Quietness overrides verbosity
1050 let quiet = opt_quiet $ idris_options i
1051 if quiet
1052 then return $ 0
1053 else return $ (opt_verbose $ idris_options i)
1055setVerbose :: Int -> Idris ()
1056setVerbose t = do
1057 i <- getIState
1058 let opts = idris_options i
1059 let opt' = opts { opt_verbose = t }
1060 putIState $ i { idris_options = opt' }
1062iReport :: Int -> String -> Idris ()
1063iReport level msg = do
1064 verbosity <- verbose
1065 i <- getIState
1066 when (level <= verbosity) $
1067 case idris_outputmode i of
1068 RawOutput h -> runIO $ hPutStrLn h msg
1069 IdeMode n h -> runIO . hPutStrLn h $ convSExp "write-string" msg n
1070 return ()
1072typeInType :: Idris Bool
1073typeInType = do i <- getIState
1074 return (opt_typeintype (idris_options i))
1076setTypeInType :: Bool -> Idris ()
1077setTypeInType t = do i <- getIState
1078 let opts = idris_options i
1079 let opt' = opts { opt_typeintype = t }
1080 putIState $ i { idris_options = opt' }
1082coverage :: Idris Bool
1083coverage = do i <- getIState
1084 return (opt_coverage (idris_options i))
1086setCoverage :: Bool -> Idris ()
1087setCoverage t = do i <- getIState
1088 let opts = idris_options i
1089 let opt' = opts { opt_coverage = t }
1090 putIState $ i { idris_options = opt' }
1092setIBCSubDir :: FilePath -> Idris ()
1093setIBCSubDir fp = do i <- getIState
1094 let opts = idris_options i
1095 let opt' = opts { opt_ibcsubdir = fp }
1096 putIState $ i { idris_options = opt' }
1098valIBCSubDir :: IState -> Idris FilePath
1099valIBCSubDir i = return (opt_ibcsubdir (idris_options i))
1101addImportDir :: FilePath -> Idris ()
1102addImportDir fp = do i <- getIState
1103 let opts = idris_options i
1104 let opt' = opts { opt_importdirs = nub $ fp : opt_importdirs opts }
1105 putIState $ i { idris_options = opt' }
1107setImportDirs :: [FilePath] -> Idris ()
1108setImportDirs fps = do i <- getIState
1109 let opts = idris_options i
1110 let opt' = opts { opt_importdirs = fps }
1111 putIState $ i { idris_options = opt' }
1113allImportDirs :: Idris [FilePath]
1114allImportDirs = do i <- getIState
1115 let optdirs = opt_importdirs (idris_options i)
1116 return ("." : reverse optdirs)
1118-- Like allImportDirs but the dirs that are a prefix of
1119-- the files path first. This makes it look in the current
1120-- package first.
1121rankedImportDirs :: FilePath -> Idris [FilePath]
1122rankedImportDirs fp = do ids <- allImportDirs
1123 let (prefixes, rest) = partition (`isPrefixOf`fp) ids
1124 return $ prefixes ++ rest
1126addSourceDir :: FilePath -> Idris ()
1127addSourceDir fp = do i <- getIState
1128 let opts = idris_options i
1129 let opts' = opts { opt_sourcedirs = nub $ fp : opt_sourcedirs opts }
1130 putIState $ i { idris_options = opts' }
1132setSourceDirs :: [FilePath] -> Idris ()
1133setSourceDirs fps = do i <- getIState
1134 let opts = idris_options i
1135 let opts' = opts { opt_sourcedirs = nub $ fps }
1136 putIState $ i { idris_options = opts' }
1138allSourceDirs :: Idris [FilePath]
1139allSourceDirs = do i <- getIState
1140 let optdirs = opt_sourcedirs (idris_options i)
1141 return ("." : reverse optdirs)
1143colourise :: Idris Bool
1144colourise = do i <- getIState
1145 return $ idris_colourRepl i
1147setColourise :: Bool -> Idris ()
1148setColourise b = do i <- getIState
1149 putIState $ i { idris_colourRepl = b }
1151impShow :: Idris Bool
1152impShow = do i <- getIState
1153 return (opt_showimp (idris_options i))
1155setImpShow :: Bool -> Idris ()
1156setImpShow t = do i <- getIState
1157 let opts = idris_options i
1158 let opt' = opts { opt_showimp = t }
1159 putIState $ i { idris_options = opt' }
1161setColour :: ColourType -> IdrisColour -> Idris ()
1162setColour ct c = do i <- getIState
1163 let newTheme = setColour' ct c (idris_colourTheme i)
1164 putIState $ i { idris_colourTheme = newTheme }
1165 where setColour' KeywordColour c t = t { keywordColour = c }
1166 setColour' BoundVarColour c t = t { boundVarColour = c }
1167 setColour' ImplicitColour c t = t { implicitColour = c }
1168 setColour' FunctionColour c t = t { functionColour = c }
1169 setColour' TypeColour c t = t { typeColour = c }
1170 setColour' DataColour c t = t { dataColour = c }
1171 setColour' PromptColour c t = t { promptColour = c }
1172 setColour' PostulateColour c t = t { postulateColour = c }
1174logLvl :: Int -> String -> Idris ()
1175logLvl = logLvlCats []
1177logCoverage :: Int -> String -> Idris ()
1178logCoverage = logLvlCats [ICoverage]
1180logErasure :: Int -> String -> Idris ()
1181logErasure = logLvlCats [IErasure]
1183-- | Log an action of the parser
1184logParser :: Int -> String -> Idris ()
1185logParser = logLvlCats parserCats
1187-- | Log an action of the elaborator.
1188logElab :: Int -> String -> Idris ()
1189logElab = logLvlCats elabCats
1191-- | Log an action of the compiler.
1192logCodeGen :: Int -> String -> Idris ()
1193logCodeGen = logLvlCats codegenCats
1195logIBC :: Int -> String -> Idris ()
1196logIBC = logLvlCats [IIBC]
1198-- | Log aspect of Idris execution
1200-- An empty set of logging levels is used to denote all categories.
1202-- @TODO update IDE protocol
1203logLvlCats :: [LogCat] -- ^ The categories that the message should appear under.
1204 -> Int -- ^ The Logging level the message should appear.
1205 -> String -- ^ The message to show the developer.
1206 -> Idris ()
1207logLvlCats cs l msg = do
1208 i <- getIState
1209 let lvl = opt_logLevel (idris_options i)
1210 let cats = opt_logcats (idris_options i)
1211 when (lvl >= l) $
1212 when (inCat cs cats || null cats) $
1213 case idris_outputmode i of
1214 RawOutput h -> do
1215 runIO $ hPutStrLn h msg
1216 IdeMode n h -> do
1217 let good = SexpList [IntegerAtom (toInteger l), toSExp msg]
1218 runIO . hPutStrLn h $ convSExp "log" good n
1219 where
1220 inCat :: [LogCat] -> [LogCat] -> Bool
1221 inCat cs cats = any (`elem` cats) cs
1223cmdOptType :: Opt -> Idris Bool
1224cmdOptType x = do i <- getIState
1225 return $ x `elem` opt_cmdline (idris_options i)
1227noErrors :: Idris Bool
1228noErrors = do i <- getIState
1229 case errSpan i of
1230 Nothing -> return True
1231 _ -> return False
1233setTypeCase :: Bool -> Idris ()
1234setTypeCase t = do i <- getIState
1235 let opts = idris_options i
1236 let opt' = opts { opt_typecase = t }
1237 putIState $ i { idris_options = opt' }
1239getIndentWith :: Idris Int
1240getIndentWith = do
1241 i <- getIState
1242 return $ interactiveOpts_indentWith (idris_interactiveOpts i)
1244setIndentWith :: Int -> Idris ()
1245setIndentWith indentWith = do
1246 i <- getIState
1247 let opts = idris_interactiveOpts i
1248 let opts' = opts { interactiveOpts_indentWith = indentWith }
1249 putIState $ i { idris_interactiveOpts = opts' }
1251getIndentClause :: Idris Int
1252getIndentClause = do
1253 i <- getIState
1254 return $ interactiveOpts_indentClause (idris_interactiveOpts i)
1256setIndentClause :: Int -> Idris ()
1257setIndentClause indentClause = do
1258 i <- getIState
1259 let opts = idris_interactiveOpts i
1260 let opts' = opts { interactiveOpts_indentClause = indentClause }
1261 putIState $ i { idris_interactiveOpts = opts' }
1263-- Dealing with parameters
1265expandParams :: (Name -> Name) -> [(Name, PTerm)] ->
1266 [Name] -> -- all names
1267 [Name] -> -- names with no declaration
1268 PTerm -> PTerm
1269expandParams dec ps ns infs tm = en 0 tm
1270 where
1271 -- if we shadow a name (say in a lambda binding) that is used in a call to
1272 -- a lifted function, we need access to both names - once in the scope of the
1273 -- binding and once to call the lifted functions. So we'll explicitly shadow
1274 -- it. (Yes, it's a hack. The alternative would be to resolve names earlier
1275 -- but we didn't...)
1277 mkShadow (UN n) = MN 0 n
1278 mkShadow (MN i n) = MN (i+1) n
1279 mkShadow (NS x s) = NS (mkShadow x) s
1281 en :: Int -- ^ The quotation level - only transform terms that are used, not terms
1282 -- that are merely mentioned.
1283 -> PTerm -> PTerm
1284 en 0 (PLam fc n nfc t s)
1285 | n `elem` (map fst ps ++ ns)
1286 = let n' = mkShadow n in
1287 PLam fc n' nfc (en 0 t) (en 0 (shadow n n' s))
1288 | otherwise = PLam fc n nfc (en 0 t) (en 0 s)
1289 en 0 (PPi p n nfc t s)
1290 | n `elem` (map fst ps ++ ns)
1291 = let n' = mkShadow n in -- TODO THINK SHADOWING TacImp?
1292 PPi (enTacImp 0 p) n' nfc (en 0 t) (en 0 (shadow n n' s))
1293 | otherwise = PPi (enTacImp 0 p) n nfc (en 0 t) (en 0 s)
1294 en 0 (PLet fc rc n nfc ty v s)
1295 | n `elem` (map fst ps ++ ns)
1296 = let n' = mkShadow n in
1297 PLet fc rc n' nfc (en 0 ty) (en 0 v) (en 0 (shadow n n' s))
1298 | otherwise = PLet fc rc n nfc (en 0 ty) (en 0 v) (en 0 s)
1299 -- FIXME: Should only do this in a type signature!
1300 en 0 (PDPair f hls p (PRef f' fcs n) t r)
1301 | n `elem` (map fst ps ++ ns) && t /= Placeholder
1302 = let n' = mkShadow n in
1303 PDPair f hls p (PRef f' fcs n') (en 0 t) (en 0 (shadow n n' r))
1304 en 0 (PRewrite f by l r g) = PRewrite f by (en 0 l) (en 0 r) (fmap (en 0) g)
1305 en 0 (PTyped l r) = PTyped (en 0 l) (en 0 r)
1306 en 0 (PPair f hls p l r) = PPair f hls p (en 0 l) (en 0 r)
1307 en 0 (PDPair f hls p l t r) = PDPair f hls p (en 0 l) (en 0 t) (en 0 r)
1308 en 0 (PAlternative ns a as) = PAlternative ns a (map (en 0) as)
1309 en 0 (PHidden t) = PHidden (en 0 t)
1310 en 0 (PUnifyLog t) = PUnifyLog (en 0 t)
1311 en 0 (PDisamb ds t) = PDisamb ds (en 0 t)
1312 en 0 (PNoImplicits t) = PNoImplicits (en 0 t)
1313 en 0 (PDoBlock ds) = PDoBlock (map (fmap (en 0)) ds)
1314 en 0 (PProof ts) = PProof (map (fmap (en 0)) ts)
1315 en 0 (PTactics ts) = PTactics (map (fmap (en 0)) ts)
1317 en 0 (PQuote (Var n))
1318 | n `nselem` ns = PQuote (Var (dec n))
1319 en 0 (PApp fc (PInferRef fc' hl n) as)
1320 | n `nselem` ns = PApp fc (PInferRef fc' hl (dec n))
1321 (map ((pexp . (PRef fc hl)) . fst) ps ++ (map (fmap (en 0)) as))
1322 en 0 (PApp fc (PRef fc' hl n) as)
1323 | n `elem` infs = PApp fc (PInferRef fc' hl (dec n))
1324 (map ((pexp . (PRef fc hl)) . fst) ps ++ (map (fmap (en 0)) as))
1325 | n `nselem` ns = PApp fc (PRef fc' hl (dec n))
1326 (map ((pexp . (PRef fc hl)) . fst) ps ++ (map (fmap (en 0)) as))
1327 en 0 (PAppBind fc (PRef fc' hl n) as)
1328 | n `elem` infs = PAppBind fc (PInferRef fc' hl (dec n))
1329 (map ((pexp . (PRef fc hl)) . fst) ps ++ (map (fmap (en 0)) as))
1330 | n `nselem` ns = PAppBind fc (PRef fc' hl (dec n))
1331 (map ((pexp . (PRef fc hl)) . fst) ps ++ (map (fmap (en 0)) as))
1332 en 0 (PRef fc hl n)
1333 | n `elem` infs = PApp fc (PInferRef fc hl (dec n))
1334 (map ((pexp . (PRef fc hl)) . fst) ps)
1335 | n `nselem` ns = PApp fc (PRef fc hl (dec n))
1336 (map ((pexp . (PRef fc hl)) . fst) ps)
1337 en 0 (PInferRef fc hl n)
1338 | n `nselem` ns = PApp fc (PInferRef fc hl (dec n))
1339 (map ((pexp . (PRef fc hl)) . fst) ps)
1340 en 0 (PApp fc f as) = PApp fc (en 0 f) (map (fmap (en 0)) as)
1341 en 0 (PAppBind fc f as) = PAppBind fc (en 0 f) (map (fmap (en 0)) as)
1342 en 0 (PCase fc c os) = PCase fc (en 0 c) (map (pmap (en 0)) os)
1343 en 0 (PIfThenElse fc c t f) = PIfThenElse fc (en 0 c) (en 0 t) (en 0 f)
1344 en 0 (PRunElab fc tm ns) = PRunElab fc (en 0 tm) ns
1345 en 0 (PConstSugar fc tm) = PConstSugar fc (en 0 tm)
1347 en ql (PQuasiquote tm ty) = PQuasiquote (en (ql + 1) tm) (fmap (en ql) ty)
1348 en ql (PUnquote tm) = PUnquote (en (ql - 1) tm)
1350 en ql t = descend (en ql) t
1352 nselem x [] = False
1353 nselem x (y : xs) | nseq x y = True
1354 | otherwise = nselem x xs
1356 nseq x y = nsroot x == nsroot y
1358 enTacImp ql (TacImp aos st scr rig) = TacImp aos st (en ql scr) rig
1359 enTacImp ql other = other
1361expandParamsD :: Bool -> -- True = RHS only
1362 IState ->
1363 (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PDecl -> PDecl
1364expandParamsD rhsonly ist dec ps ns (PTy doc argdocs syn fc o n nfc ty)
1365 = if n `elem` ns && (not rhsonly)
1366 then -- trace (show (n, expandParams dec ps ns ty)) $
1367 PTy doc argdocs syn fc o (dec n) nfc (piBindp expl_param ps (expandParams dec ps ns [] ty))
1368 else --trace (show (n, expandParams dec ps ns ty)) $
1369 PTy doc argdocs syn fc o n nfc (expandParams dec ps ns [] ty)
1370expandParamsD rhsonly ist dec ps ns (PPostulate e doc syn fc nfc o n ty)
1371 = if n `elem` ns && (not rhsonly)
1372 then -- trace (show (n, expandParams dec ps ns ty)) $
1373 PPostulate e doc syn fc nfc o (dec n)
1374 (piBind ps (expandParams dec ps ns [] ty))
1375 else --trace (show (n, expandParams dec ps ns ty)) $
1376 PPostulate e doc syn fc nfc o n (expandParams dec ps ns [] ty)
1377expandParamsD rhsonly ist dec ps ns (PClauses fc opts n cs)
1378 = let n' = if n `elem` ns then dec n else n in
1379 PClauses fc opts n' (map expandParamsC cs)
1380 where
1381 expandParamsC (PClause fc n lhs ws rhs ds)
1382 = let -- ps' = updateps True (namesIn ist rhs) (zip ps [0..])
1383 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
1384 lhs' = if rhsonly then lhs else (expandParams dec ps'' ns [] lhs)
1385 n' = if n `elem` ns then dec n else n
1386 -- names bound on the lhs should not be expanded on the rhs
1387 ns' = removeBound lhs ns in
1388 PClause fc n' lhs'
1389 (map (expandParams dec ps'' ns' []) ws)
1390 (expandParams dec ps'' ns' [] rhs)
1391 (map (expandParamsD True ist dec ps'' ns') ds)
1392 expandParamsC (PWith fc n lhs ws wval pn ds)
1393 = let -- ps' = updateps True (namesIn ist wval) (zip ps [0..])
1394 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
1395 lhs' = if rhsonly then lhs else (expandParams dec ps'' ns [] lhs)
1396 n' = if n `elem` ns then dec n else n
1397 ns' = removeBound lhs ns in
1398 PWith fc n' lhs'
1399 (map (expandParams dec ps'' ns' []) ws)
1400 (expandParams dec ps'' ns' [] wval)
1401 pn
1402 (map (expandParamsD rhsonly ist dec ps'' ns') ds)
1403 updateps yn nm [] = []
1404 updateps yn nm (((a, t), i):as)
1405 | (a `elem` nm) == yn = (a, t) : updateps yn nm as
1406 | otherwise = (sMN i (show a ++ "_shadow"), t) : updateps yn nm as
1408 removeBound lhs ns = ns \\ nub (bnames lhs)
1410 bnames (PRef _ _ n) = [n]
1411 bnames (PApp _ _ args) = concatMap (bnames . getTm) args
1412 bnames (PPair _ _ _ l r) = bnames l ++ bnames r
1413 bnames (PDPair _ _ _ l Placeholder r) = bnames l ++ bnames r
1414 bnames _ = []
1416-- | Expands parameters defined in parameter and where blocks inside of declarations
1417expandParamsD rhs ist dec ps ns (PData doc argDocs syn fc co pd)
1418 = PData doc argDocs syn fc co (expandPData pd)
1419 where
1420 -- just do the type decl, leave constructors alone (parameters will be
1421 -- added implicitly)
1422 expandPData (PDatadecl n nfc ty cons)
1423 = if n `elem` ns
1424 then PDatadecl (dec n) nfc (piBind ps (expandParams dec ps ns [] ty))
1425 (map econ cons)
1426 else PDatadecl n nfc (expandParams dec ps ns [] ty) (map econ cons)
1427 econ (doc, argDocs, n, nfc, t, fc, fs)
1428 = (doc, argDocs, dec n, nfc, piBindp expl ps (expandParams dec ps ns [] t), fc, fs)
1429expandParamsD rhs ist dec ps ns d@(PRecord doc rsyn fc opts name nfc prs pdocs fls cn cdoc csyn)
1430 = d
1431expandParamsD rhs ist dec ps ns (PParams f params pds)
1432 = PParams f (ps ++ map (mapsnd (expandParams dec ps ns [])) params)
1433 (map (expandParamsD True ist dec ps ns) pds)
1434-- (map (expandParamsD ist dec ps ns) pds)
1435expandParamsD rhs ist dec ps ns (PMutual f pds)
1436 = PMutual f (map (expandParamsD rhs ist dec ps ns) pds)
1437expandParamsD rhs ist dec ps ns (PInterface doc info f cs n nfc params pDocs fds decls cn cd)
1438 = PInterface doc info f
1439 (map (\ (n, t) -> (n, expandParams dec ps ns [] t)) cs)
1440 n nfc
1441 (map (\(n, fc, t) -> (n, fc, expandParams dec ps ns [] t)) params)
1442 pDocs
1443 fds
1444 (map (expandParamsD rhs ist dec ps ns) decls)
1445 cn
1446 cd
1447expandParamsD rhs ist dec ps ns (PImplementation doc argDocs info f cs pnames acc opts n nfc params pextra ty cn decls)
1448 = let cn' = case cn of
1449 Just n -> if n `elem` ns then Just (dec n) else Just n
1450 Nothing -> Nothing in
1451 PImplementation doc argDocs info f
1452 (map (\ (n, t) -> (n, expandParams dec ps ns [] t)) cs)
1453 pnames acc opts n
1454 nfc
1455 (map (expandParams dec ps ns []) params)
1456 (map (\ (n, t) -> (n, expandParams dec ps ns [] t)) pextra)
1457 (expandParams dec ps ns [] ty)
1458 cn'
1459 (map (expandParamsD True ist dec ps ns) decls)
1460expandParamsD rhs ist dec ps ns d = d
1462mapsnd f (x, t) = (x, f t)
1464expandImplementationScope ist dec ps ns (PImplementation doc argDocs info f cs pnames acc opts n nfc params pextra ty cn decls)
1465 = PImplementation doc argDocs info f cs pnames acc opts n nfc params (ps ++ pextra)
1466 ty cn decls
1467expandImplementationScope ist dec ps ns d = d
1469-- | Calculate a priority for a type, for deciding elaboration order
1470-- * if it's just a type variable or concrete type, do it early (0)
1471-- * if there's only type variables and injective constructors, do it next (1)
1472-- * if there's a function type, next (2)
1473-- * finally, everything else (3)
1474getPriority :: IState -> PTerm -> Int
1475getPriority i tm = 1
1477addStatics :: Name -> Term -> PTerm -> Idris ()
1478addStatics n tm ptm =
1479 do let (statics, dynamics) = initStatics tm ptm
1480 ist <- getIState
1481 let paramnames
1482 = nub $ case lookupCtxtExact n (idris_fninfo ist) of
1483 Just p -> getNamesFrom 0 (fn_params p) tm ++
1484 concatMap (getParamNames ist . snd) statics
1485 _ -> concatMap (getParamNames ist . snd) statics
1487 let stnames = nub $ concatMap (freeArgNames . snd) statics
1488 let dnames = (nub $ concatMap (freeArgNames . snd) dynamics)
1489 \\ paramnames
1490 -- also get the arguments which are 'uniquely inferrable' from
1491 -- statics (see sec 4.2 of "Scrapping Your Inefficient Engine")
1492 -- or parameters to the type of a static
1493 let statics' = nub $ map fst statics ++
1494 filter (\x -> not (elem x dnames)) stnames
1495 let stpos = staticList statics' tm
1496 i <- getIState
1497 unless (null statics) $
1498 logLvl 3 $ "Statics for " ++ show n ++ " " ++ show tm ++ "\n"
1499 ++ showTmImpls ptm ++ "\n"
1500 ++ show statics ++ "\n" ++ show dynamics
1501 ++ "\n" ++ show paramnames
1502 ++ "\n" ++ show stpos
1503 putIState $ i { idris_statics = addDef n stpos (idris_statics i) }
1504 addIBC (IBCStatic n)
1505 where
1506 initStatics (Bind n (Pi _ _ ty _) sc) (PPi p n' fc t s)
1507 | n /= n' = let (static, dynamic) = initStatics sc (PPi p n' fc t s) in
1508 (static, (n, ty) : dynamic)
1509 initStatics (Bind n (Pi _ _ ty _) sc) (PPi p n' fc _ s)
1510 = let (static, dynamic) = initStatics (instantiate (P Bound n ty) sc) s in
1511 if pstatic p == Static then ((n, ty) : static, dynamic)
1512 else if (not (searchArg p))
1513 then (static, (n, ty) : dynamic)
1514 else (static, dynamic)
1515 initStatics t pt = ([], [])
1517 getParamNames ist tm | (P _ n _ , args) <- unApply tm
1518 = case lookupCtxtExact n (idris_datatypes ist) of
1519 Just ti -> getNamePos 0 (param_pos ti) args
1520 Nothing -> []
1521 where getNamePos i ps [] = []
1522 getNamePos i ps (P _ n _ : as)
1523 | i `elem` ps = n : getNamePos (i + 1) ps as
1524 getNamePos i ps (_ : as) = getNamePos (i + 1) ps as
1525 getParamNames ist (Bind t (Pi _ _ (P _ n _) _) sc)
1526 = n : getParamNames ist sc
1527 getParamNames ist _ = []
1529 getNamesFrom i ps (Bind n (Pi _ _ _ _) sc)
1530 | i `elem` ps = n : getNamesFrom (i + 1) ps sc
1531 | otherwise = getNamesFrom (i + 1) ps sc
1532 getNamesFrom i ps sc = []
1534 freeArgNames (Bind n (Pi _ _ ty _) sc)
1535 = nub $ freeNames ty ++ freeNames sc -- treat '->' as fn here
1536 freeArgNames tm = let (_, args) = unApply tm in
1537 concatMap freeNames args
1539 -- if a name appears in an interface or tactic implicit index, it doesn't
1540 -- affect its 'uniquely inferrable' from a static status since these are
1541 -- resolved by searching.
1542 searchArg (Constraint _ _ _) = True
1543 searchArg (TacImp _ _ _ _) = True
1544 searchArg _ = False
1546 staticList sts (Bind n (Pi _ _ _ _) sc) = (n `elem` sts) : staticList sts sc
1547 staticList _ _ = []
1549-- Dealing with implicit arguments
1551-- Add some bound implicits to the using block if they aren't there already
1553addToUsing :: [Using] -> [(Name, PTerm)] -> [Using]
1554addToUsing us [] = us
1555addToUsing us ((n, t) : ns)
1556 | n `notElem` mapMaybe impName us = addToUsing (us ++ [UImplicit n t]) ns
1557 | otherwise = addToUsing us ns
1558 where impName (UImplicit n _) = Just n
1559 impName _ = Nothing
1561-- Add constraint bindings from using block
1563addUsingConstraints :: SyntaxInfo -> FC -> PTerm -> Idris PTerm
1564addUsingConstraints syn fc t
1565 = do ist <- get
1566 let ns = namesIn [] ist t
1567 let cs = getConstraints t -- check declared constraints
1568 let addconsts = uconsts \\ cs
1569 return (doAdd addconsts ns t)
1570 where uconsts = filter uconst (using syn)
1571 uconst (UConstraint _ _) = True
1572 uconst _ = False
1574 doAdd [] _ t = t
1575 -- if all of args in ns, then add it
1576 doAdd (UConstraint c args : cs) ns t
1577 | all (\n -> elem n ns) args
1578 = PPi (Constraint [] Dynamic RigW) (sMN 0 "cu") NoFC
1579 (mkConst c args) (doAdd cs ns t)
1580 | otherwise = doAdd cs ns t
1582 mkConst c args = PApp fc (PRef fc [] c)
1583 (map (PExp 0 [] (sMN 0 "carg") . PRef fc []) args)
1585 getConstraints (PPi (Constraint _ _ _) _ _ c sc)
1586 = getcapp c ++ getConstraints sc
1587 getConstraints (PPi _ _ _ c sc) = getConstraints sc
1588 getConstraints _ = []
1590 getcapp (PApp _ (PRef _ _ c) args)
1591 = do ns <- mapM getName args
1592 return (UConstraint c ns)
1593 getcapp _ = []
1595 getName (PExp _ _ _ (PRef _ _ n)) = return n
1596 getName _ = []
1598-- | Add implicit bindings from using block, and bind any missing names
1599addUsingImpls :: SyntaxInfo -> Name -> FC -> PTerm -> Idris PTerm
1600addUsingImpls syn n fc t
1601 = do ist <- getIState
1602 autoimpl <- getAutoImpls
1603 let ns_in = implicitNamesIn (map iname uimpls) ist t
1604 let ns = if autoimpl then ns_in
1605 else filter (\n -> n `elem` (map iname uimpls)) ns_in
1607 let badnames = filter (\n -> not (implicitable n) &&
1608 n `notElem` (map iname uimpls)) ns
1609 unless (null badnames) $
1610 throwError (At fc (Elaborating "type of " n Nothing
1611 (NoSuchVariable (head badnames))))
1612 let cs = getArgnames t -- get already bound names
1613 let addimpls = filter (\n -> iname n `notElem` cs) uimpls
1614 -- if all names in the arguments of addconsts appear in ns,
1615 -- add the constraint implicitly
1616 return (bindFree ns (doAdd addimpls ns t))
1617 where uimpls = filter uimpl (using syn)
1618 uimpl (UImplicit _ _) = True
1619 uimpl _ = False
1621 iname (UImplicit n _) = n
1622 iname (UConstraint _ _) = error "Can't happen addUsingImpls"
1624 doAdd [] _ t = t
1625 -- if all of args in ns, then add it
1626 doAdd (UImplicit n ty : cs) ns t
1627 | elem n ns
1628 = PPi impl_gen n NoFC ty (doAdd cs ns t)
1629 | otherwise = doAdd cs ns t
1631 -- bind the free names which weren't in the using block
1632 bindFree [] tm = tm
1633 bindFree (n:ns) tm
1634 | elem n (map iname uimpls) = bindFree ns tm
1635 | otherwise
1636 = PPi (impl_gen { pargopts = [InaccessibleArg] }) n NoFC Placeholder (bindFree ns tm)
1638 getArgnames (PPi _ n _ c sc)
1639 = n : getArgnames sc
1640 getArgnames _ = []
1642-- Given the original type and the elaborated type, return the implicitness
1643-- status of each pi-bound argument, and whether it's inaccessible (True) or not.
1645getUnboundImplicits :: IState -> Type -> PTerm -> [(Bool, PArg)]
1646getUnboundImplicits i t tm = getImps t (collectImps tm)
1647 where collectImps (PPi p n _ t sc)
1648 = (n, (p, t)) : collectImps sc
1649 collectImps _ = []
1651 scopedimpl (Just i) = not (toplevel_imp i)
1652 scopedimpl _ = False
1654 getImps (Bind n (Pi _ i _ _) sc) imps
1655 | scopedimpl i = getImps sc imps
1656 getImps (Bind n (Pi _ _ t _) sc) imps
1657 | Just (p, t') <- lookup n imps = argInfo n p t' : getImps sc imps
1658 where
1659 argInfo n (Imp opt _ _ _ _ _) Placeholder
1660 = (True, PImp 0 True opt n Placeholder)
1661 argInfo n (Imp opt _ _ _ _ _) t'
1662 = (False, PImp (getPriority i t') True opt n t')
1663 argInfo n (Exp opt _ _ _) t'
1664 = (InaccessibleArg `elem` opt,
1665 PExp (getPriority i t') opt n t')
1666 argInfo n (Constraint opt _ _) t'
1667 = (InaccessibleArg `elem` opt,
1668 PConstraint 10 opt n t')
1669 argInfo n (TacImp opt _ scr _) t'
1670 = (InaccessibleArg `elem` opt,
1671 PTacImplicit 10 opt n scr t')
1672 getImps (Bind n (Pi _ _ t _) sc) imps = impBind n t : getImps sc imps
1673 where impBind n t = (True, PImp 1 True [] n Placeholder)
1674 getImps sc tm = []
1676-- Add implicit Pi bindings for any names in the term which appear in an
1677-- argument position.
1679-- This has become a right mess already. Better redo it some time...
1680-- TODO: This is obsoleted by the new way of elaborating types, (which
1681-- calls addUsingImpls) but there's still a couple of places which use
1682-- it. Clean them up!
1684-- Issue 1739 in the issue tracker
1685-- https://github.com/idris-lang/Idris-dev/issues/1739
1686implicit :: ElabInfo -> SyntaxInfo -> Name -> PTerm -> Idris PTerm
1687implicit info syn n ptm = implicit' info syn [] n ptm
1689implicit' :: ElabInfo -> SyntaxInfo -> [Name] -> Name -> PTerm -> Idris PTerm
1690implicit' info syn ignore n ptm
1691 = do i <- getIState
1692 auto <- getAutoImpls
1693 let (tm', impdata) = implicitise auto syn ignore i ptm
1694 defaultArgCheck (eInfoNames info ++ M.keys (idris_implicits i)) impdata
1695-- let (tm'', spos) = findStatics i tm'
1696 putIState $ i { idris_implicits = addDef n impdata (idris_implicits i) }
1697 addIBC (IBCImp n)
1698 logLvl 5 ("Implicit " ++ show n ++ " " ++ show impdata)
1699-- i <- get
1700-- putIState $ i { idris_statics = addDef n spos (idris_statics i) }
1701 return tm'
1702 where
1703 -- Detect unknown names in default arguments and throw error if found.
1704 defaultArgCheck :: [Name] -> [PArg] -> Idris ()
1705 defaultArgCheck knowns params = foldM_ notFoundInDefault knowns params
1707 notFoundInDefault :: [Name] -> PArg -> Idris [Name]
1708 notFoundInDefault kns (PTacImplicit _ _ n script _)
1709 = do i <- getIState
1710 case notFound kns (namesIn [] i script) of
1711 Nothing -> return (n:kns)
1712 Just name -> throwError (NoSuchVariable name)
1713 notFoundInDefault kns p = return ((pname p):kns)
1715 notFound :: [Name] -> [Name] -> Maybe Name
1716 notFound kns [] = Nothing
1717 notFound kns (SN (WhereN _ _ _) : ns) = notFound kns ns -- Known already
1718 notFound kns (n:ns) = if elem n kns then notFound kns ns else Just n
1720-- | Even if auto_implicits is off, we need to call this so we record
1721-- which arguments are implicit
1722implicitise :: Bool -> SyntaxInfo -> [Name] -> IState -> PTerm -> (PTerm, [PArg])
1723implicitise auto syn ignore ist tm = -- trace ("INCOMING " ++ showImp True tm) $
1724 let (declimps, ns') = execState (imps True [] tm) ([], [])
1725 ns = filter (\n -> auto && implicitable n || elem n (map fst uvars)) $
1726 ns' \\ (map fst pvars ++ no_imp syn ++ ignore)
1727 nsOrder = filter (not . inUsing) ns ++ filter inUsing ns in
1728 if null ns
1729 then (tm, reverse declimps)
1730 else implicitise auto syn ignore ist (pibind uvars nsOrder tm)
1731 where
1732 uvars = map ipair (filter uimplicit (using syn))
1733 pvars = syn_params syn
1735 inUsing n = n `elem` map fst uvars
1737 ipair (UImplicit x y) = (x, y)
1738 uimplicit (UImplicit _ _) = True
1739 uimplicit _ = False
1741 dropAll (x:xs) ys | x `elem` ys = dropAll xs ys
1742 | otherwise = x : dropAll xs ys
1743 dropAll [] ys = []
1745 -- Find names in argument position in a type, suitable for implicit
1746 -- binding
1747 -- Not the function position, but do everything else...
1748 implNamesIn uv (PApp fc f args) = concatMap (implNamesIn uv . getTm) args
1749 implNamesIn uv t = implicitNamesIn (map fst uv) ist t
1751 imps top env ty@(PApp _ f as)
1752 = do (decls, ns) <- get
1753 let isn = nub (implNamesIn uvars ty)
1754 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1755 imps top env (PPi (Imp l _ _ _ _ _) n _ ty sc)
1756 = do let isn = nub (implNamesIn uvars ty) `dropAll` [n]
1757 (decls , ns) <- get
1758 put (PImp (getPriority ist ty) True l n Placeholder : decls,
1759 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1760 imps True (n:env) sc
1761 imps top env (PPi (Exp l _ _ _) n _ ty sc)
1762 = do let isn = nub (implNamesIn uvars ty ++ case sc of
1763 (PRef _ _ x) -> namesIn uvars ist sc `dropAll` [n]
1764 _ -> [])
1765 (decls, ns) <- get -- ignore decls in HO types
1766 put (PExp (getPriority ist ty) l n Placeholder : decls,
1767 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1768 imps True (n:env) sc
1769 imps top env (PPi (Constraint l _ _) n _ ty sc)
1770 = do let isn = nub (implNamesIn uvars ty ++ case sc of
1771 (PRef _ _ x) -> namesIn uvars ist sc `dropAll` [n]
1772 _ -> [])
1773 (decls, ns) <- get -- ignore decls in HO types
1774 put (PConstraint 10 l n Placeholder : decls,
1775 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1776 imps True (n:env) sc
1777 imps top env (PPi (TacImp l _ scr _) n _ ty sc)
1778 = do let isn = nub (implNamesIn uvars ty ++ case sc of
1779 (PRef _ _ x) -> namesIn uvars ist sc `dropAll` [n]
1780 _ -> [])
1781 (decls, ns) <- get -- ignore decls in HO types
1782 put (PTacImplicit 10 l n scr Placeholder : decls,
1783 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1784 imps True (n:env) sc
1785 imps top env (PRewrite _ _ l r _)
1786 = do (decls, ns) <- get
1787 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1788 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1789 imps top env (PTyped l r)
1790 = imps top env l
1791 imps top env (PPair _ _ _ 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 (PDPair _ _ _ (PRef _ _ n) t r)
1796 = do (decls, ns) <- get
1797 let isn = nub (namesIn uvars ist t ++ namesIn uvars ist r) \\ [n]
1798 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1799 imps top env (PDPair _ _ _ l t r)
1800 = do (decls, ns) <- get
1801 let isn = namesIn uvars ist l ++ namesIn uvars ist t ++
1802 namesIn uvars ist r
1803 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1804 imps top env (PAlternative ms a as)
1805 = do (decls, ns) <- get
1806 let isn = concatMap (namesIn uvars ist) as
1807 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1808 imps top env (PLam fc n _ ty sc)
1809 = do imps False env ty
1810 imps False (n:env) sc
1811 imps top env (PHidden tm) = imps False env tm
1812 imps top env (PUnifyLog tm) = imps False env tm
1813 imps top env (PNoImplicits tm) = imps False env tm
1814 imps top env (PRunElab fc tm ns) = imps False env tm
1815 imps top env (PConstSugar fc tm) = imps top env tm -- ignore PConstSugar - it's for highlighting only!
1816 imps top env _ = return ()
1818 pibind using [] sc = sc
1819 pibind using (n:ns) sc
1820 = case lookup n using of
1821 Just ty -> PPi impl_gen
1822 n NoFC ty (pibind using ns sc)
1823 Nothing -> PPi (impl_gen { pargopts = [InaccessibleArg] })
1824 n NoFC Placeholder (pibind using ns sc)
1826-- | Add implicit arguments in function calls
1827addImplPat :: IState -> PTerm -> PTerm
1828addImplPat = addImpl' True [] [] []
1830addImplBound :: IState -> [Name] -> PTerm -> PTerm
1831addImplBound ist ns = addImpl' False ns [] [] ist
1833addImplBoundInf :: IState -> [Name] -> [Name] -> PTerm -> PTerm
1834addImplBoundInf ist ns inf = addImpl' False ns inf [] ist
1836-- | Add the implicit arguments to applications in the term [Name]
1837-- gives the names to always expend, even when under a binder of that
1838-- name (this is to expand methods with implicit arguments in
1839-- dependent interfaces).
1840addImpl :: [Name] -> IState -> PTerm -> PTerm
1841addImpl = addImpl' False [] []
1843-- TODO: in patterns, don't add implicits to function names guarded by constructors
1844-- and *not* inside a PHidden
1846addImpl' :: Bool -> [Name] -> [Name] -> [Name] -> IState -> PTerm -> PTerm
1847addImpl' inpat env infns imp_meths ist ptm
1848 = ai inpat False (zip env (repeat Nothing)) [] (mkUniqueNames env [] ptm)
1849 where
1850 allowcap = AllowCapitalizedPatternVariables `elem` opt_cmdline (idris_options ist)
1852 topname = case ptm of
1853 PRef _ _ n -> n
1854 PApp _ (PRef _ _ n) _ -> n
1855 _ -> sUN "" -- doesn't matter then
1857 ai :: Bool -> Bool -> [(Name, Maybe PTerm)] -> [[T.Text]] -> PTerm -> PTerm
1858 ai inpat qq env ds (PRef fc fcs f)
1859 | f `elem` infns = PInferRef fc fcs f
1860 | not (f `elem` map fst env) = handleErr $ aiFn topname allowcap inpat inpat qq imp_meths ist fc f fc ds []
1861 ai inpat qq env ds (PHidden (PRef fc hl f))
1862 | not (f `elem` map fst env) = PHidden (handleErr $ aiFn topname allowcap inpat False qq imp_meths ist fc f fc ds [])
1863 ai inpat qq env ds (PRewrite fc by l r g)
1864 = let l' = ai inpat qq env ds l
1865 r' = ai inpat qq env ds r
1866 g' = fmap (ai inpat qq env ds) g in
1867 PRewrite fc by l' r' g'
1868 ai inpat qq env ds (PTyped l r)
1869 = let l' = ai inpat qq env ds l
1870 r' = ai inpat qq env ds r in
1871 PTyped l' r'
1872 ai inpat qq env ds (PPair fc hls p l r)
1873 = let l' = ai inpat qq env ds l
1874 r' = ai inpat qq env ds r in
1875 PPair fc hls p l' r'
1876 ai inpat qq env ds (PDPair fc hls p l t r)
1877 = let l' = ai inpat qq env ds l
1878 t' = ai inpat qq env ds t
1879 r' = ai inpat qq env ds r in
1880 PDPair fc hls p l' t' r'
1881 ai inpat qq env ds (PAlternative ms a as)
1882 = let as' = map (ai inpat qq env ds) as in
1883 PAlternative ms a as'
1884 ai inpat qq env _ (PDisamb ds' as) = ai inpat qq env ds' as
1885 ai inpat qq env ds (PApp fc (PInferRef ffc hl f) as)
1886 = let as' = map (fmap (ai inpat qq env ds)) as in
1887 PApp fc (PInferRef ffc hl f) as'
1888 ai inpat qq env ds (PApp fc ftm@(PRef ffc hl f) as)
1889 | f `elem` infns = ai inpat qq env ds (PApp fc (PInferRef ffc hl f) as)
1890 | not (f `elem` map fst env)
1891 = let as' = map (fmap (ai inpat qq env ds)) as in
1892 handleErr $ aiFn topname allowcap inpat False qq imp_meths ist fc f ffc ds as'
1893 | Just (Just ty) <- lookup f env =
1894 let as' = map (fmap (ai inpat qq env ds)) as
1895 arity = getPArity ty in
1896 mkPApp fc arity ftm as'
1897 ai inpat qq env ds (PApp fc f as)
1898 = let f' = ai inpat qq env ds f
1899 as' = map (fmap (ai inpat qq env ds)) as in
1900 mkPApp fc 1 f' as'
1901 ai inpat qq env ds (PWithApp fc f a)
1902 = PWithApp fc (ai inpat qq env ds f) (ai inpat qq env ds a)
1903 ai inpat qq env ds (PCase fc c os)
1904 = let c' = ai inpat qq env ds c in
1905 -- leave lhs alone, because they get lifted into a new pattern match
1906 -- definition which is passed through addImpl again
1907 PCase fc c' (map aiCase os)
1908 where
1909 aiCase (lhs, rhs)
1910 = (lhs, ai inpat qq (env ++ patnames lhs) ds rhs)
1912 -- Anything beginning with a lower case letter, not applied,
1913 -- and no namespace is a pattern variable
1914 patnames (PApp _ (PRef _ _ f) [])
1915 | implicitable f = [(f, Nothing)]
1916 patnames (PRef _ _ f)
1917 | implicitable f = [(f, Nothing)]
1918 patnames (PApp _ (PRef _ _ _) args)
1919 = concatMap patnames (map getTm args)
1920 patnames (PPair _ _ _ l r) = patnames l ++ patnames r
1921 patnames (PDPair _ _ _ l t r) = patnames l ++ patnames t ++ patnames r
1922 patnames (PAs _ _ t) = patnames t
1923 patnames (PAlternative _ _ ts) = concatMap patnames ts
1924 patnames _ = []
1927 ai inpat qq env ds (PIfThenElse fc c t f) = PIfThenElse fc (ai inpat qq env ds c)
1928 (ai inpat qq env ds t)
1929 (ai inpat qq env ds f)
1931 -- If the name in a lambda is an unapplied data constructor name, do this
1932 -- as a 'case' instead because we'll expect to match on it
1933 ai inpat qq env ds (PLam fc n nfc ty sc)
1934 = if canBeDConName n (tt_ctxt ist)
1935 then ai inpat qq env ds (PLam fc (sMN 0 "lamp") NoFC ty
1936 (PCase fc (PRef fc [] (sMN 0 "lamp") )
1937 [(PRef fc [] n, sc)]))
1938 else let ty' = ai inpat qq env ds ty
1939 sc' = ai inpat qq ((n, Just ty):env) ds sc in
1940 PLam fc n nfc ty' sc'
1941 ai inpat qq env ds (PLet fc rc n nfc ty val sc)
1942 = if canBeDConName n (tt_ctxt ist)
1943 then ai inpat qq env ds (PCase fc val [(PRef fc [] n, sc)])
1944 else let ty' = ai inpat qq env ds ty
1945 val' = ai inpat qq env ds val
1946 sc' = ai inpat qq ((n, Just ty):env) ds sc in
1947 PLet fc rc n nfc ty' val' sc'
1948 ai inpat qq env ds (PPi p n nfc ty sc)
1949 = let ty' = ai inpat qq env ds ty
1950 env' = if n `elem` imp_meths then env
1951 else
1952 ((n, Just ty) : env)
1953 sc' = ai inpat qq env' ds sc in
1954 PPi p n nfc ty' sc'
1955 ai inpat qq env ds (PGoal fc r n sc)
1956 = let r' = ai inpat qq env ds r
1957 sc' = ai inpat qq ((n, Nothing):env) ds sc in
1958 PGoal fc r' n sc'
1959 ai inpat qq env ds (PHidden tm) = PHidden (ai inpat qq env ds tm)
1960 -- Don't do PProof or PTactics since implicits get added when scope is
1961 -- properly known in ElabTerm.runTac
1962 ai inpat qq env ds (PUnifyLog tm) = PUnifyLog (ai inpat qq env ds tm)
1963 ai inpat qq env ds (PNoImplicits tm) = PNoImplicits (ai inpat qq env ds tm)
1964 ai inpat qq env ds (PQuasiquote tm g) = PQuasiquote (ai inpat True env ds tm)
1965 (fmap (ai inpat True env ds) g)
1966 ai inpat qq env ds (PUnquote tm) = PUnquote (ai inpat False env ds tm)
1967 ai inpat qq env ds (PRunElab fc tm ns) = PRunElab fc (ai inpat False env ds tm) ns
1968 ai inpat qq env ds (PConstSugar fc tm) = PConstSugar fc (ai inpat qq env ds tm)
1969 ai inpat qq env ds tm = tm
1971 handleErr (Left err) = PElabError err
1972 handleErr (Right x) = x
1974-- if in a pattern, and there are no arguments, and there's no possible
1975-- names with zero explicit arguments, don't add implicits.
1977aiFn :: Name -> Bool -- ^ Allow capitalization of pattern variables
1978 -> Bool -> Bool -> Bool
1979 -> [Name]
1980 -> IState -> FC
1981 -> Name -- ^ function being applied
1982 -> FC -> [[T.Text]]
1983 -> [PArg] -- ^ initial arguments (if in a pattern)
1984 -> Either Err PTerm
1985aiFn topname allowcap inpat True qq imp_meths ist fc f ffc ds []
1986 | inpat && implicitable f && unqualified f = Right $ PPatvar ffc f
1987 | otherwise
1988 = case lookupDef f (tt_ctxt ist) of
1989 [] -> if allowcap
1990 then Right $ PPatvar ffc f
1991 else case f of
1992 MN _ _ -> Right $ PPatvar ffc f
1993 UN xs | isDigit (T.head xs) -- for partial evaluation vars
1994 -> Right $ PPatvar ffc f
1995 _ -> Left $ Msg $ show f ++ " is not a valid name for a pattern variable"
1996 alts -> let ialts = lookupCtxtName f (idris_implicits ist) in
1997 -- trace (show f ++ " " ++ show (fc, any (all imp) ialts, ialts, any constructor alts)) $
1998 if (not (vname f) || tcname f
1999 || any (conCaf (tt_ctxt ist)) ialts)
2000-- any constructor alts || any allImp ialts))
2001 then aiFn topname allowcap inpat False qq imp_meths ist fc f ffc ds [] -- use it as a constructor
2002 else Right $ PPatvar ffc f
2003 where imp (PExp _ _ _ _) = False
2004 imp _ = True
2005-- allImp [] = False
2006 allImp xs = all imp xs
2008 unqualified (NS _ _) = False
2009 unqualified _ = True
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 allowcap 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 allowcap 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 | canBeDConName fn ctxt
2198 = PApp fc f (fmap (fmap su) args)
2199 su (PApp fc f args)
2200 = PHidden (PApp fc f args)
2201 su (PAlternative ms b alts)
2202 = let alts' = filter (/= Placeholder) (map su alts) in
2203 if null alts' then Placeholder
2204 else liftHidden $ PAlternative ms b alts'
2205 su (PPair fc hls p l r) = PPair fc hls p (su l) (su r)
2206 su (PDPair fc hls p l t r) = PDPair fc hls p (su l) (su t) (su r)
2207 su t@(PLam fc _ _ _ _) = PHidden t
2208 su t@(PPi _ _ _ _ _) = PHidden t
2209 su t@(PConstant _ c) | isTypeConst c = PHidden t
2210 su t = t
2212 ctxt = tt_ctxt i
2214 -- If the ambiguous terms are all hidden, the PHidden needs to be outside
2215 -- because elaboration of PHidden gets delayed, and we need the elaboration
2216 -- to resolve the ambiguity.
2217 liftHidden tm@(PAlternative ms b as)
2218 | allHidden as = PHidden (PAlternative ms b (map unHide as))
2219 | otherwise = tm
2221 allHidden [] = True
2222 allHidden (PHidden _ : xs) = allHidden xs
2223 allHidden (x : xs) = False
2225 unHide (PHidden t) = t
2226 unHide t = t
2228stripUnmatchable i tm = tm
2230mkPApp fc a f [] = f
2231mkPApp fc a f as = let rest = drop a as in
2232 if a == 0 then appRest fc f rest
2233 else appRest fc (PApp fc f (take a as)) rest
2234 where
2235 appRest fc f [] = f
2236 appRest fc f (a : as) = appRest fc (PApp fc f [a]) as
2240-- | Find 'static' argument positions
2241-- (the declared ones, plus any names in argument position in the declared
2242-- statics)
2243-- FIXME: It's possible that this really has to happen after elaboration
2244findStatics :: IState -> PTerm -> (PTerm, [Bool])
2245findStatics ist tm = let (ns, ss) = fs tm
2246 in runState (pos ns ss tm) []
2247 where fs (PPi p n fc t sc)
2248 | Static <- pstatic p
2249 = let (ns, ss) = fs sc in
2250 (namesIn [] ist t : ns, n : ss)
2251 | otherwise = let (ns, ss) = fs sc in
2252 (ns, ss)
2253 fs _ = ([], [])
2255 pos ns ss (PPi p n fc t sc)
2256 | elem n ss = do sc' <- pos ns ss sc
2257 spos <- get
2258 put (True : spos)
2259 return (PPi (p { pstatic = Static }) n fc t sc')
2260 | otherwise = do sc' <- pos ns ss sc
2261 spos <- get
2262 put (False : spos)
2263 return (PPi p n fc t sc')
2264 pos ns ss t = return t
2266-- for 6.12/7 compatibility
2267data EitherErr a b = LeftErr a | RightOK b deriving ( Functor )
2269instance Applicative (EitherErr a) where
2270 pure = return
2271 (<*>) = ap
2273instance Monad (EitherErr a) where
2274 return = RightOK
2276 (LeftErr e) >>= _ = LeftErr e
2277 RightOK v >>= k = k v
2279toEither :: EitherErr a b -> Either a b
2280toEither (LeftErr e) = Left e
2281toEither (RightOK ho) = Right ho
2283-- | Syntactic match of a against b, returning pair of variables in a
2284-- and what they match. Returns the pair that failed if not a match.
2285matchClause :: IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
2286matchClause = matchClause' False
2288matchClause' :: Bool -> IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
2289matchClause' names i x y = checkRpts $ match (fullApp x) (fullApp y) where
2290 matchArg x y = match (fullApp (getTm x)) (fullApp (getTm y))
2292 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
2293 fullApp x = x
2295 match' x y = match (fullApp x) (fullApp y)
2296 match (PApp _ (PRef _ _ (NS (UN fi) [b])) [_,_,x]) x'
2297 | fi == txt "fromInteger" && b == txt "builtins",
2298 PConstant _ (I _) <- getTm x = match (getTm x) x'
2299 match x' (PApp _ (PRef _ _ (NS (UN fi) [b])) [_,_,x])
2300 | fi == txt "fromInteger" && b == txt "builtins",
2301 PConstant _ (I _) <- getTm x = match (getTm x) x'
2302 match (PApp _ (PRef _ _ (UN l)) [_,x]) x' | l == txt "lazy" = match (getTm x) x'
2303 match x (PApp _ (PRef _ _ (UN l)) [_,x']) | l == txt "lazy" = match x (getTm x')
2304 match (PApp _ f args) (PApp _ f' args')
2305 | length args == length args'
2306 = do mf <- match' f f'
2307 ms <- zipWithM matchArg args args'
2308 return (mf ++ concat ms)
2309 match (PRef f hl n) (PApp _ x []) = match (PRef f hl n) x
2310 match (PPatvar f n) xr = match (PRef f [f] n) xr
2311 match xr (PPatvar f n) = match xr (PRef f [f] n)
2312 match (PApp _ x []) (PRef f hl n) = match x (PRef f hl n)
2313 match (PRef _ _ n) tm@(PRef _ _ n')
2314 | n == n' && not names &&
2315 (not (isConName n (tt_ctxt i) || isFnName n (tt_ctxt i))
2316 || tm == Placeholder)
2317 = return [(n, tm)]
2318 -- if one namespace is missing, drop the other
2319 | n == n' || n == dropNS n' || dropNS n == n' = return []
2320 where dropNS (NS n _) = n
2321 dropNS n = n
2322 match (PRef _ _ n) tm
2323 | not names && (not (isConName n (tt_ctxt i) ||
2324 isFnName n (tt_ctxt i)) || tm == Placeholder)
2325 = return [(n, tm)]
2326 match (PRewrite _ by l r _) (PRewrite _ by' l' r' _) | by == by'
2327 = do ml <- match' l l'
2328 mr <- match' r r'
2329 return (ml ++ mr)
2330 match (PTyped l r) (PTyped l' r') = do ml <- match l l'
2331 mr <- match r r'
2332 return (ml ++ mr)
2333 match (PTyped l r) x = match l x
2334 match x (PTyped l r) = match x l
2335 match (PPair _ _ _ l r) (PPair _ _ _ l' r') = do ml <- match' l l'
2336 mr <- match' r r'
2337 return (ml ++ mr)
2338 match (PDPair _ _ _ l t r) (PDPair _ _ _ l' t' r') = do ml <- match' l l'
2339 mt <- match' t t'
2340 mr <- match' r r'
2341 return (ml ++ mt ++ mr)
2342 match (PAlternative _ a as) (PAlternative _ a' as')
2343 = do ms <- zipWithM match' as as'
2344 return (concat ms)
2345 match a@(PAlternative _ _ as) b
2346 = do let ms = zipWith match' as (repeat b)
2347 case (rights (map toEither ms)) of
2348 (x: _) -> return x
2349 _ -> LeftErr (a, b)
2350 match (PCase _ _ _) _ = return [] -- lifted out
2351 match (PMetavar _ _) _ = return [] -- modified
2352 match (PInferRef _ _ _) _ = return [] -- modified
2353 match (PQuote _) _ = return []
2354 match (PProof _) _ = return []
2355 match (PTactics _) _ = return []
2356 match (PResolveTC _) (PResolveTC _) = return []
2357 match (PTrue _ _) (PTrue _ _) = return []
2358 match (PPi _ _ _ t s) (PPi _ _ _ t' s') = do mt <- match' t t'
2359 ms <- match' s s'
2360 return (mt ++ ms)
2361 match (PLam _ _ _ t s) (PLam _ _ _ t' s') = do mt <- match' t t'
2362 ms <- match' s s'
2363 return (mt ++ ms)
2364 match (PLet _ _ _ _ t ty s) (PLet _ _ _ _ t' ty' s')
2365 = do mt <- match' t t'
2366 mty <- match' ty ty'
2367 ms <- match' s s'
2368 return (mt ++ mty ++ ms)
2369 match (PHidden x) (PHidden y)
2370 | RightOK xs <- match x y = return xs -- to collect variables
2371 | otherwise = return [] -- Otherwise hidden things are unmatchable
2372 match (PHidden x) y
2373 | RightOK xs <- match x y = return xs
2374 | otherwise = return []
2375 match x (PHidden y)
2376 | RightOK xs <- match x y = return xs
2377 | otherwise = return []
2378 match (PUnifyLog x) y = match' x y
2379 match x (PUnifyLog y) = match' x y
2380 match (PNoImplicits x) y = match' x y
2381 match x (PNoImplicits y) = match' x y
2382 match Placeholder _ = return []
2383 match _ Placeholder = return []
2384 match (PResolveTC _) _ = return []
2385 match a b | a == b = return []
2386 | otherwise = LeftErr (a, b)
2388 checkRpts (RightOK ms) = check ms where
2389 check ((n,t):xs)
2390 | Just t' <- lookup n xs = if t/=t' && t/=Placeholder && t'/=Placeholder
2391 then Left (t, t')
2392 else check xs
2393 check (_:xs) = check xs
2394 check [] = Right ms
2395 checkRpts (LeftErr x) = Left x
2397substMatches :: [(Name, PTerm)] -> PTerm -> PTerm
2398substMatches ms = substMatchesShadow ms []
2400-- substMatchesShadow :: [(Name, PTerm)] -> [Name] -> PTerm -> PTerm
2401-- substMatchesShadow [] shs t = t
2402-- substMatchesShadow ((n,tm):ns) shs t
2403-- = substMatchShadow n shs tm (substMatchesShadow ns shs t)
2405substMatch :: Name -> PTerm -> PTerm -> PTerm
2406substMatch n = substMatchShadow n []
2408substMatchShadow :: Name -> [Name] -> PTerm -> PTerm -> PTerm
2409substMatchShadow n shs tm t = substMatchesShadow [(n, tm)] shs t
2411substMatchesShadow :: [(Name, PTerm)] -> [Name] -> PTerm -> PTerm
2412substMatchesShadow nmap shs t = sm shs t where
2413 sm xs (PRef _ _ n) | Just tm <- lookup n nmap = tm
2414 sm xs (PLam fc x xfc t sc) = PLam fc x xfc (sm xs t) (sm xs sc)
2415 sm xs (PPi p x fc t sc)
2416 | x `elem` xs
2417 = let x' = nextName x in
2418 PPi p x' fc (sm (x':xs) (substMatch x (PRef emptyFC [] x') t))
2419 (sm (x':xs) (substMatch x (PRef emptyFC [] x') sc))
2420 | otherwise = PPi p x fc (sm xs t) (sm (x : xs) sc)
2421 sm xs (PLet fc rc x xfc val t sc)
2422 = PLet fc rc x xfc (sm xs val) (sm xs t) (sm xs sc)
2423 sm xs (PApp f x as) = fullApp $ PApp f (sm xs x) (map (fmap (sm xs)) as)
2424 sm xs (PCase f x as) = PCase f (sm xs x) (map (pmap (sm xs)) as)
2425 sm xs (PIfThenElse fc c t f) = PIfThenElse fc (sm xs c) (sm xs t) (sm xs f)
2426 sm xs (PRewrite f by x y tm) = PRewrite f by (sm xs x) (sm xs y)
2427 (fmap (sm xs) tm)
2428 sm xs (PTyped x y) = PTyped (sm xs x) (sm xs y)
2429 sm xs (PPair f hls p x y) = PPair f hls p (sm xs x) (sm xs y)
2430 sm xs (PDPair f hls p x t y) = PDPair f hls p (sm xs x) (sm xs t) (sm xs y)
2431 sm xs (PAlternative ms a as) = PAlternative ms a (map (sm xs) as)
2432 sm xs (PHidden x) = PHidden (sm xs x)
2433 sm xs (PUnifyLog x) = PUnifyLog (sm xs x)
2434 sm xs (PNoImplicits x) = PNoImplicits (sm xs x)
2435 sm xs (PRunElab fc script ns) = PRunElab fc (sm xs script) ns
2436 sm xs (PConstSugar fc tm) = PConstSugar fc (sm xs tm)
2437 sm xs x = x
2439 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
2440 fullApp x = x
2442shadow :: Name -> Name -> PTerm -> PTerm
2443shadow n n' t = sm 0 t where
2444 sm 0 (PRef fc hl x) | n == x = PRef fc hl n'
2445 sm 0 (PLam fc x xfc t sc) | n /= x = PLam fc x xfc (sm 0 t) (sm 0 sc)
2446 | otherwise = PLam fc x xfc (sm 0 t) sc
2447 sm 0 (PPi p x fc t sc) | n /= x = PPi p x fc (sm 0 t) (sm 0 sc)
2448 | otherwise = PPi p x fc (sm 0 t) sc
2449 sm 0 (PLet fc rc x xfc t v sc) | n /= x = PLet fc rc x xfc (sm 0 t) (sm 0 v) (sm 0 sc)
2450 | otherwise = PLet fc rc x xfc (sm 0 t) (sm 0 v) sc
2451 sm 0 (PApp f x as) = PApp f (sm 0 x) (map (fmap (sm 0)) as)
2452 sm 0 (PAppBind f x as) = PAppBind f (sm 0 x) (map (fmap (sm 0)) as)
2453 sm 0 (PCase f x as) = PCase f (sm 0 x) (map (pmap (sm 0)) as)
2454 sm 0 (PIfThenElse fc c t f) = PIfThenElse fc (sm 0 c) (sm 0 t) (sm 0 f)
2455 sm 0 (PRewrite f by x y tm) = PRewrite f by (sm 0 x) (sm 0 y) (fmap (sm 0) tm)
2456 sm 0 (PTyped x y) = PTyped (sm 0 x) (sm 0 y)
2457 sm 0 (PPair f hls p x y) = PPair f hls p (sm 0 x) (sm 0 y)
2458 sm 0 (PDPair f hls p x t y) = PDPair f hls p (sm 0 x) (sm 0 t) (sm 0 y)
2459 sm 0 (PAlternative ms a as)
2460 = PAlternative (map shadowAlt ms) a (map (sm 0) as)
2461 sm 0 (PTactics ts) = PTactics (map (fmap (sm 0)) ts)
2462 sm 0 (PProof ts) = PProof (map (fmap (sm 0)) ts)
2463 sm 0 (PHidden x) = PHidden (sm 0 x)
2464 sm 0 (PUnifyLog x) = PUnifyLog (sm 0 x)
2465 sm 0 (PNoImplicits x) = PNoImplicits (sm 0 x)
2466 sm 0 (PCoerced t) = PCoerced (sm 0 t)
2467 sm ql (PQuasiquote tm ty) = PQuasiquote (sm (ql + 1) tm) (fmap (sm ql) ty)
2468 sm ql (PUnquote tm) = PUnquote (sm (ql - 1) tm)
2469 sm ql x = descend (sm ql) x
2471 shadowAlt p@(x, oldn) = (update x, update oldn)
2472 update oldn | n == oldn = n'
2473 | otherwise = oldn
2475-- | Rename any binders which are repeated (so that we don't have to
2476-- mess about with shadowing anywhere else).
2477mkUniqueNames :: [Name] -> [(Name, Name)] -> PTerm -> PTerm
2478mkUniqueNames env shadows tm
2479 = evalState (mkUniq 0 initMap tm) (S.fromList env) where
2481 initMap = M.fromList shadows
2483 inScope :: S.Set Name
2484 inScope = S.fromList $ boundNamesIn tm
2486 mkUniqA ql nmap arg = do t' <- mkUniq ql nmap (getTm arg)
2487 return (arg { getTm = t' })
2489 -- Initialise the unique name with the environment length (so we're not
2490 -- looking for too long...)
2491 initN (UN n) l = UN $ txt (str n ++ show l)
2492 initN (MN i s) l = MN (i+l) s
2493 initN n _ = n
2495 -- FIXME: Probably ought to do this for completeness! It's fine as
2496 -- long as there are no bindings inside tactics though.
2497 mkUniqT _ nmap tac = return tac
2499 mkUniq :: Int -- ^ The number of quotations that we're under
2500 -> M.Map Name Name -> PTerm -> State (S.Set Name) PTerm
2501 mkUniq 0 nmap (PLam fc n nfc ty sc)
2502 = do env <- get
2503 (n', sc') <-
2504 if n `S.member` env
2505 then do let n' = uniqueNameSet (initN n (S.size env))
2506 (S.union env inScope)
2507 return (n', sc) -- shadow n n' sc)
2508 else return (n, sc)
2509 put (S.insert n' env)
2510 let nmap' = M.insert n n' nmap
2511 ty' <- mkUniq 0 nmap ty
2512 sc'' <- mkUniq 0 nmap' sc'
2513 return $! PLam fc n' nfc ty' sc''
2514 mkUniq 0 nmap (PPi p n fc ty sc)
2515 = do env <- get
2516 (n', sc') <-
2517 if n `S.member` env
2518 then do let n' = uniqueNameSet (initN n (S.size env))
2519 (S.union env inScope)
2520 return (n', sc) -- shadow n n' sc)
2521 else return (n, sc)
2522 put (S.insert n' env)
2523 let nmap' = M.insert n n' nmap
2524 ty' <- mkUniq 0 nmap ty
2525 sc'' <- mkUniq 0 nmap' sc'
2526 return $! PPi p n' fc ty' sc''
2527 mkUniq 0 nmap (PLet fc rc n nfc ty val sc)
2528 = do env <- get
2529 (n', sc') <-
2530 if n `S.member` env
2531 then do let n' = uniqueNameSet (initN n (S.size env))
2532 (S.union env inScope)
2533 return (n', sc) -- shadow n n' sc)
2534 else return (n, sc)
2535 put (S.insert n' env)
2536 let nmap' = M.insert n n' nmap
2537 ty' <- mkUniq 0 nmap ty; val' <- mkUniq 0 nmap val
2538 sc'' <- mkUniq 0 nmap' sc'
2539 return $! PLet fc rc n' nfc ty' val' sc''
2540 mkUniq 0 nmap (PApp fc t args)
2541 = do t' <- mkUniq 0 nmap t
2542 args' <- mapM (mkUniqA 0 nmap) args
2543 return $! PApp fc t' args'
2544 mkUniq 0 nmap (PAppBind fc t args)
2545 = do t' <- mkUniq 0 nmap t
2546 args' <- mapM (mkUniqA 0 nmap) args
2547 return $! PAppBind fc t' args'
2548 mkUniq 0 nmap (PCase fc t alts)
2549 = do t' <- mkUniq 0 nmap t
2550 alts' <- mapM (\(x,y)-> do x' <- mkUniq 0 nmap x; y' <- mkUniq 0 nmap y
2551 return (x', y')) alts
2552 return $! PCase fc t' alts'
2553 mkUniq 0 nmap (PIfThenElse fc c t f)
2554 = liftM3 (PIfThenElse fc) (mkUniq 0 nmap c) (mkUniq 0 nmap t) (mkUniq 0 nmap f)
2555 mkUniq 0 nmap (PPair fc hls p l r)
2556 = do l' <- mkUniq 0 nmap l; r' <- mkUniq 0 nmap r
2557 return $! PPair fc hls p l' r'
2558 mkUniq 0 nmap (PDPair fc hls p (PRef fc' hls' n) t sc)
2559 | t /= Placeholder
2560 = do env <- get
2561 (n', sc') <- if n `S.member` env
2562 then do let n' = uniqueNameSet n (S.union env inScope)
2563 return (n', sc) -- shadow n n' sc)
2564 else return (n, sc)
2565 put (S.insert n' env)
2566 let nmap' = M.insert n n' nmap
2567 t' <- mkUniq 0 nmap t
2568 sc'' <- mkUniq 0 nmap' sc'
2569 return $! PDPair fc hls p (PRef fc' hls' n') t' sc''
2570 mkUniq 0 nmap (PDPair fc hls p l t r)
2571 = do l' <- mkUniq 0 nmap l; t' <- mkUniq 0 nmap t; r' <- mkUniq 0 nmap r
2572 return $! PDPair fc hls p l' t' r'
2573 mkUniq 0 nmap (PAlternative ns b as)
2574 -- store the nmap and defer the rest until we've pruned the set
2575 -- during elaboration
2576 = return $ PAlternative (ns ++ M.toList nmap) b as
2577 mkUniq 0 nmap (PHidden t) = liftM PHidden (mkUniq 0 nmap t)
2578 mkUniq 0 nmap (PUnifyLog t) = liftM PUnifyLog (mkUniq 0 nmap t)
2579 mkUniq 0 nmap (PDisamb n t) = liftM (PDisamb n) (mkUniq 0 nmap t)
2580 mkUniq 0 nmap (PNoImplicits t) = liftM PNoImplicits (mkUniq 0 nmap t)
2581 mkUniq 0 nmap (PProof ts) = liftM PProof (mapM (mkUniqT 0 nmap) ts)
2582 mkUniq 0 nmap (PTactics ts) = liftM PTactics (mapM (mkUniqT 0 nmap) ts)
2583 mkUniq 0 nmap (PRunElab fc ts ns) = liftM (\tm -> PRunElab fc tm ns) (mkUniq 0 nmap ts)
2584 mkUniq 0 nmap (PConstSugar fc tm) = liftM (PConstSugar fc) (mkUniq 0 nmap tm)
2585 mkUniq 0 nmap (PCoerced tm) = liftM PCoerced (mkUniq 0 nmap tm)
2586 mkUniq 0 nmap t = return $ shadowAll (M.toList nmap) t
2587 where
2588 shadowAll [] t = t
2589 shadowAll ((n, n') : ns) t = shadow n n' (shadowAll ns t)
2591 mkUniq ql nmap (PQuasiquote tm ty) =
2592 do tm' <- mkUniq (ql + 1) nmap tm
2593 ty' <- case ty of
2594 Nothing -> return Nothing
2595 Just t -> fmap Just $ mkUniq ql nmap t
2596 return $! PQuasiquote tm' ty'
2597 mkUniq ql nmap (PUnquote tm) = fmap PUnquote (mkUniq (ql - 1) nmap tm)
2599 mkUniq ql nmap tm = descendM (mkUniq ql nmap) tm