on master help sign in
Idris-dev/src/Idris/AbsSyntax.hs
2602 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 = (InaccessibleArg `elem` opt,
1663 PImp (getPriority i t') True opt n t')
1664 argInfo n (Exp opt _ _ _) t'
1665 = (InaccessibleArg `elem` opt,
1666 PExp (getPriority i t') opt n t')
1667 argInfo n (Constraint opt _ _) t'
1668 = (InaccessibleArg `elem` opt,
1669 PConstraint 10 opt n t')
1670 argInfo n (TacImp opt _ scr _) t'
1671 = (InaccessibleArg `elem` opt,
1672 PTacImplicit 10 opt n scr t')
1673 getImps (Bind n (Pi _ _ t _) sc) imps = impBind n t : getImps sc imps
1674 where impBind n t = (True, PImp 1 True [] n Placeholder)
1675 getImps sc tm = []
1677-- Add implicit Pi bindings for any names in the term which appear in an
1678-- argument position.
1680-- This has become a right mess already. Better redo it some time...
1681-- TODO: This is obsoleted by the new way of elaborating types, (which
1682-- calls addUsingImpls) but there's still a couple of places which use
1683-- it. Clean them up!
1685-- Issue 1739 in the issue tracker
1686-- https://github.com/idris-lang/Idris-dev/issues/1739
1687implicit :: ElabInfo -> SyntaxInfo -> Name -> PTerm -> Idris PTerm
1688implicit info syn n ptm = implicit' info syn [] n ptm
1690implicit' :: ElabInfo -> SyntaxInfo -> [Name] -> Name -> PTerm -> Idris PTerm
1691implicit' info syn ignore n ptm
1692 = do i <- getIState
1693 auto <- getAutoImpls
1694 let (tm', impdata) = implicitise auto syn ignore i ptm
1695 defaultArgCheck (eInfoNames info ++ M.keys (idris_implicits i)) impdata
1696-- let (tm'', spos) = findStatics i tm'
1697 putIState $ i { idris_implicits = addDef n impdata (idris_implicits i) }
1698 addIBC (IBCImp n)
1699 logLvl 5 ("Implicit " ++ show n ++ " " ++ show impdata)
1700-- i <- get
1701-- putIState $ i { idris_statics = addDef n spos (idris_statics i) }
1702 return tm'
1703 where
1704 -- Detect unknown names in default arguments and throw error if found.
1705 defaultArgCheck :: [Name] -> [PArg] -> Idris ()
1706 defaultArgCheck knowns params = foldM_ notFoundInDefault knowns params
1708 notFoundInDefault :: [Name] -> PArg -> Idris [Name]
1709 notFoundInDefault kns (PTacImplicit _ _ n script _)
1710 = do i <- getIState
1711 case notFound kns (namesIn [] i script) of
1712 Nothing -> return (n:kns)
1713 Just name -> throwError (NoSuchVariable name)
1714 notFoundInDefault kns p = return ((pname p):kns)
1716 notFound :: [Name] -> [Name] -> Maybe Name
1717 notFound kns [] = Nothing
1718 notFound kns (SN (WhereN _ _ _) : ns) = notFound kns ns -- Known already
1719 notFound kns (n:ns) = if elem n kns then notFound kns ns else Just n
1721-- | Even if auto_implicits is off, we need to call this so we record
1722-- which arguments are implicit
1723implicitise :: Bool -> SyntaxInfo -> [Name] -> IState -> PTerm -> (PTerm, [PArg])
1724implicitise auto syn ignore ist tm = -- trace ("INCOMING " ++ showImp True tm) $
1725 let (declimps, ns') = execState (imps True [] tm) ([], [])
1726 ns = filter (\n -> auto && implicitable n || elem n (map fst uvars)) $
1727 ns' \\ (map fst pvars ++ no_imp syn ++ ignore)
1728 nsOrder = filter (not . inUsing) ns ++ filter inUsing ns in
1729 if null ns
1730 then (tm, reverse declimps)
1731 else implicitise auto syn ignore ist (pibind uvars nsOrder tm)
1732 where
1733 uvars = map ipair (filter uimplicit (using syn))
1734 pvars = syn_params syn
1736 inUsing n = n `elem` map fst uvars
1738 ipair (UImplicit x y) = (x, y)
1739 uimplicit (UImplicit _ _) = True
1740 uimplicit _ = False
1742 dropAll (x:xs) ys | x `elem` ys = dropAll xs ys
1743 | otherwise = x : dropAll xs ys
1744 dropAll [] ys = []
1746 -- Find names in argument position in a type, suitable for implicit
1747 -- binding
1748 -- Not the function position, but do everything else...
1749 implNamesIn uv (PApp fc f args) = concatMap (implNamesIn uv . getTm) args
1750 implNamesIn uv t = implicitNamesIn (map fst uv) ist t
1752 imps top env ty@(PApp _ f as)
1753 = do (decls, ns) <- get
1754 let isn = nub (implNamesIn uvars ty)
1755 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1756 imps top env (PPi (Imp l _ _ _ _ _) n _ ty sc)
1757 = do let isn = nub (implNamesIn uvars ty) `dropAll` [n]
1758 (decls , ns) <- get
1759 put (PImp (getPriority ist ty) True l n Placeholder : decls,
1760 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1761 imps True (n:env) sc
1762 imps top env (PPi (Exp l _ _ _) n _ ty sc)
1763 = do let isn = nub (implNamesIn uvars ty ++ case sc of
1764 (PRef _ _ x) -> namesIn uvars ist sc `dropAll` [n]
1765 _ -> [])
1766 (decls, ns) <- get -- ignore decls in HO types
1767 put (PExp (getPriority ist ty) l n Placeholder : decls,
1768 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1769 imps True (n:env) sc
1770 imps top env (PPi (Constraint l _ _) n _ ty sc)
1771 = do let isn = nub (implNamesIn uvars ty ++ case sc of
1772 (PRef _ _ x) -> namesIn uvars ist sc `dropAll` [n]
1773 _ -> [])
1774 (decls, ns) <- get -- ignore decls in HO types
1775 put (PConstraint 10 l n Placeholder : decls,
1776 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1777 imps True (n:env) sc
1778 imps top env (PPi (TacImp l _ scr _) n _ ty sc)
1779 = do let isn = nub (implNamesIn uvars ty ++ case sc of
1780 (PRef _ _ x) -> namesIn uvars ist sc `dropAll` [n]
1781 _ -> [])
1782 (decls, ns) <- get -- ignore decls in HO types
1783 put (PTacImplicit 10 l n scr Placeholder : decls,
1784 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1785 imps True (n:env) sc
1786 imps top env (PRewrite _ _ l r _)
1787 = do (decls, ns) <- get
1788 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1789 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1790 imps top env (PTyped l r)
1791 = imps top env l
1792 imps top env (PPair _ _ _ l r)
1793 = do (decls, ns) <- get
1794 let isn = namesIn uvars ist l ++ namesIn uvars ist r
1795 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1796 imps top env (PDPair _ _ _ (PRef _ _ n) t r)
1797 = do (decls, ns) <- get
1798 let isn = nub (namesIn uvars ist t ++ namesIn uvars ist r) \\ [n]
1799 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1800 imps top env (PDPair _ _ _ l t r)
1801 = do (decls, ns) <- get
1802 let isn = namesIn uvars ist l ++ namesIn uvars ist t ++
1803 namesIn uvars ist r
1804 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
1805 imps top env (PAlternative ms a as)
1806 = do (decls, ns) <- get
1807 let isn = concatMap (namesIn uvars ist) as
1808 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
1809 imps top env (PLam fc n _ ty sc)
1810 = do imps False env ty
1811 imps False (n:env) sc
1812 imps top env (PHidden tm) = imps False env tm
1813 imps top env (PUnifyLog tm) = imps False env tm
1814 imps top env (PNoImplicits tm) = imps False env tm
1815 imps top env (PRunElab fc tm ns) = imps False env tm
1816 imps top env (PConstSugar fc tm) = imps top env tm -- ignore PConstSugar - it's for highlighting only!
1817 imps top env _ = return ()
1819 pibind using [] sc = sc
1820 pibind using (n:ns) sc
1821 = case lookup n using of
1822 Just ty -> PPi impl_gen
1823 n NoFC ty (pibind using ns sc)
1824 Nothing -> PPi (impl_gen { pargopts = [InaccessibleArg] })
1825 n NoFC Placeholder (pibind using ns sc)
1827-- | Add implicit arguments in function calls
1828addImplPat :: IState -> PTerm -> PTerm
1829addImplPat = addImpl' True [] [] []
1831addImplBound :: IState -> [Name] -> PTerm -> PTerm
1832addImplBound ist ns = addImpl' False ns [] [] ist
1834addImplBoundInf :: IState -> [Name] -> [Name] -> PTerm -> PTerm
1835addImplBoundInf ist ns inf = addImpl' False ns inf [] ist
1837-- | Add the implicit arguments to applications in the term [Name]
1838-- gives the names to always expend, even when under a binder of that
1839-- name (this is to expand methods with implicit arguments in
1840-- dependent interfaces).
1841addImpl :: [Name] -> IState -> PTerm -> PTerm
1842addImpl = addImpl' False [] []
1844-- TODO: in patterns, don't add implicits to function names guarded by constructors
1845-- and *not* inside a PHidden
1847addImpl' :: Bool -> [Name] -> [Name] -> [Name] -> IState -> PTerm -> PTerm
1848addImpl' inpat env infns imp_meths ist ptm
1849 = ai inpat False (zip env (repeat Nothing)) [] (mkUniqueNames env [] ptm)
1850 where
1851 allowcap = AllowCapitalizedPatternVariables `elem` opt_cmdline (idris_options ist)
1853 topname = case ptm of
1854 PRef _ _ n -> n
1855 PApp _ (PRef _ _ n) _ -> n
1856 _ -> sUN "" -- doesn't matter then
1858 ai :: Bool -> Bool -> [(Name, Maybe PTerm)] -> [[T.Text]] -> PTerm -> PTerm
1859 ai inpat qq env ds (PRef fc fcs f)
1860 | f `elem` infns = PInferRef fc fcs f
1861 | not (f `elem` map fst env) = handleErr $ aiFn topname allowcap inpat inpat qq imp_meths ist fc f fc ds []
1862 ai inpat qq env ds (PHidden (PRef fc hl f))
1863 | not (f `elem` map fst env) = PHidden (handleErr $ aiFn topname allowcap inpat False qq imp_meths ist fc f fc ds [])
1864 ai inpat qq env ds (PRewrite fc by l r g)
1865 = let l' = ai inpat qq env ds l
1866 r' = ai inpat qq env ds r
1867 g' = fmap (ai inpat qq env ds) g in
1868 PRewrite fc by l' r' g'
1869 ai inpat qq env ds (PTyped l r)
1870 = let l' = ai inpat qq env ds l
1871 r' = ai inpat qq env ds r in
1872 PTyped l' r'
1873 ai inpat qq env ds (PPair fc hls p l r)
1874 = let l' = ai inpat qq env ds l
1875 r' = ai inpat qq env ds r in
1876 PPair fc hls p l' r'
1877 ai inpat qq env ds (PDPair fc hls p l t r)
1878 = let l' = ai inpat qq env ds l
1879 t' = ai inpat qq env ds t
1880 r' = ai inpat qq env ds r in
1881 PDPair fc hls p l' t' r'
1882 ai inpat qq env ds (PAlternative ms a as)
1883 = let as' = map (ai inpat qq env ds) as in
1884 PAlternative ms a as'
1885 ai inpat qq env _ (PDisamb ds' as) = ai inpat qq env ds' as
1886 ai inpat qq env ds (PApp fc (PInferRef ffc hl f) as)
1887 = let as' = map (fmap (ai inpat qq env ds)) as in
1888 PApp fc (PInferRef ffc hl f) as'
1889 ai inpat qq env ds (PApp fc ftm@(PRef ffc hl f) as)
1890 | f `elem` infns = ai inpat qq env ds (PApp fc (PInferRef ffc hl f) as)
1891 | not (f `elem` map fst env)
1892 = let as' = map (fmap (ai inpat qq env ds)) as in
1893 handleErr $ aiFn topname allowcap inpat False qq imp_meths ist fc f ffc ds as'
1894 | Just (Just ty) <- lookup f env =
1895 let as' = map (fmap (ai inpat qq env ds)) as
1896 arity = getPArity ty in
1897 mkPApp fc arity ftm as'
1898 ai inpat qq env ds (PApp fc f as)
1899 = let f' = ai inpat qq env ds f
1900 as' = map (fmap (ai inpat qq env ds)) as in
1901 mkPApp fc 1 f' as'
1902 ai inpat qq env ds (PWithApp fc f a)
1903 = PWithApp fc (ai inpat qq env ds f) (ai inpat qq env ds a)
1904 ai inpat qq env ds (PCase fc c os)
1905 = let c' = ai inpat qq env ds c in
1906 -- leave lhs alone, because they get lifted into a new pattern match
1907 -- definition which is passed through addImpl again
1908 PCase fc c' (map aiCase os)
1909 where
1910 aiCase (lhs, rhs)
1911 = (lhs, ai inpat qq (env ++ patnames lhs) ds rhs)
1913 -- Anything beginning with a lower case letter, not applied,
1914 -- and no namespace is a pattern variable
1915 patnames (PApp _ (PRef _ _ f) [])
1916 | implicitable f = [(f, Nothing)]
1917 patnames (PRef _ _ f)
1918 | implicitable f = [(f, Nothing)]
1919 patnames (PApp _ (PRef _ _ _) args)
1920 = concatMap patnames (map getTm args)
1921 patnames (PPair _ _ _ l r) = patnames l ++ patnames r
1922 patnames (PDPair _ _ _ l t r) = patnames l ++ patnames t ++ patnames r
1923 patnames (PAs _ _ t) = patnames t
1924 patnames (PAlternative _ _ ts) = concatMap patnames ts
1925 patnames _ = []
1928 ai inpat qq env ds (PIfThenElse fc c t f) = PIfThenElse fc (ai inpat qq env ds c)
1929 (ai inpat qq env ds t)
1930 (ai inpat qq env ds f)
1932 -- If the name in a lambda is an unapplied data constructor name, do this
1933 -- as a 'case' instead because we'll expect to match on it
1934 ai inpat qq env ds (PLam fc n nfc ty sc)
1935 = if canBeDConName n (tt_ctxt ist)
1936 then ai inpat qq env ds (PLam fc (sMN 0 "lamp") NoFC ty
1937 (PCase fc (PRef fc [] (sMN 0 "lamp") )
1938 [(PRef fc [] n, sc)]))
1939 else let ty' = ai inpat qq env ds ty
1940 sc' = ai inpat qq ((n, Just ty):env) ds sc in
1941 PLam fc n nfc ty' sc'
1942 ai inpat qq env ds (PLet fc rc n nfc ty val sc)
1943 = if canBeDConName n (tt_ctxt ist)
1944 then ai inpat qq env ds (PCase fc val [(PRef fc [] n, sc)])
1945 else let ty' = ai inpat qq env ds ty
1946 val' = ai inpat qq env ds val
1947 sc' = ai inpat qq ((n, Just ty):env) ds sc in
1948 PLet fc rc n nfc ty' val' sc'
1949 ai inpat qq env ds (PPi p n nfc ty sc)
1950 = let ty' = ai inpat qq env ds ty
1951 env' = if n `elem` imp_meths then env
1952 else
1953 ((n, Just ty) : env)
1954 sc' = ai inpat qq env' ds sc in
1955 PPi p n nfc ty' sc'
1956 ai inpat qq env ds (PGoal fc r n sc)
1957 = let r' = ai inpat qq env ds r
1958 sc' = ai inpat qq ((n, Nothing):env) ds sc in
1959 PGoal fc r' n sc'
1960 ai inpat qq env ds (PHidden tm) = PHidden (ai inpat qq env ds tm)
1961 -- Don't do PProof or PTactics since implicits get added when scope is
1962 -- properly known in ElabTerm.runTac
1963 ai inpat qq env ds (PUnifyLog tm) = PUnifyLog (ai inpat qq env ds tm)
1964 ai inpat qq env ds (PNoImplicits tm) = PNoImplicits (ai inpat qq env ds tm)
1965 ai inpat qq env ds (PQuasiquote tm g) = PQuasiquote (ai inpat True env ds tm)
1966 (fmap (ai inpat True env ds) g)
1967 ai inpat qq env ds (PUnquote tm) = PUnquote (ai inpat False env ds tm)
1968 ai inpat qq env ds (PRunElab fc tm ns) = PRunElab fc (ai inpat False env ds tm) ns
1969 ai inpat qq env ds (PConstSugar fc tm) = PConstSugar fc (ai inpat qq env ds tm)
1970 ai inpat qq env ds tm = tm
1972 handleErr (Left err) = PElabError err
1973 handleErr (Right x) = x
1975-- if in a pattern, and there are no arguments, and there's no possible
1976-- names with zero explicit arguments, don't add implicits.
1978aiFn :: Name -> Bool -- ^ Allow capitalization of pattern variables
1979 -> Bool -> Bool -> Bool
1980 -> [Name]
1981 -> IState -> FC
1982 -> Name -- ^ function being applied
1983 -> FC -> [[T.Text]]
1984 -> [PArg] -- ^ initial arguments (if in a pattern)
1985 -> Either Err PTerm
1986aiFn topname allowcap inpat True qq imp_meths ist fc f ffc ds []
1987 | inpat && implicitable f && unqualified f = Right $ PPatvar ffc f
1988 | otherwise
1989 = case lookupDef f (tt_ctxt ist) of
1990 [] -> if allowcap
1991 then Right $ PPatvar ffc f
1992 else case f of
1993 MN _ _ -> Right $ PPatvar ffc f
1994 UN xs | isDigit (T.head xs) -- for partial evaluation vars
1995 -> Right $ PPatvar ffc f
1996 _ -> Left $ Msg $ show f ++ " is not a valid name for a pattern variable"
1997 alts -> let ialts = lookupCtxtName f (idris_implicits ist) in
1998 -- trace (show f ++ " " ++ show (fc, any (all imp) ialts, ialts, any constructor alts)) $
1999 if (not (vname f) || tcname f
2000 || any (conCaf (tt_ctxt ist)) ialts)
2001-- any constructor alts || any allImp ialts))
2002 then aiFn topname allowcap inpat False qq imp_meths ist fc f ffc ds [] -- use it as a constructor
2003 else Right $ PPatvar ffc f
2004 where imp (PExp _ _ _ _) = False
2005 imp _ = True
2006-- allImp [] = False
2007 allImp xs = all imp xs
2009 unqualified (NS _ _) = False
2010 unqualified _ = True
2012 conCaf ctxt (n, cia) = (isDConName n ctxt || (qq && isTConName n ctxt)) && allImp cia
2014 vname (UN n) = True -- non qualified
2015 vname _ = False
2017aiFn topname allowcap inpat expat qq imp_meths ist fc f ffc ds as
2018 | f `elem` primNames = Right $ PApp fc (PRef ffc [ffc] f) as
2019aiFn topname allowcap inpat expat qq imp_meths ist fc f ffc ds as
2020 -- This is where namespaces get resolved by adding PAlternative
2021 = do let ns = lookupCtxtName f (idris_implicits ist)
2022 let nh = filter (\(n, _) -> notHidden n) ns
2023 let ns' = case trimAlts ds nh of
2024 [] -> nh
2025 x -> x
2026 case ns' of
2027 [(f',ns)] -> Right $ mkPApp fc (length ns) (PRef ffc [ffc] (isImpName f f'))
2028 (insertImpl ns as)
2029 [] -> case metaVar f (map fst (idris_metavars ist)) of
2030 Just f' -> Right $ PApp fc (PRef ffc [ffc] f') as
2031 Nothing -> Right $ mkPApp fc (length as) (PRef ffc [ffc] f) as
2032 alts -> Right $
2033 PAlternative [] (ExactlyOne True) $
2034 map (\(f', ns) -> mkPApp fc (length ns) (PRef ffc [ffc] (isImpName f f'))
2035 (insertImpl ns as)) alts
2036 where
2037 -- if the name is in imp_meths, we should actually refer to the bound
2038 -- name rather than the global one after expanding implicits
2039 isImpName f f' | f `elem` imp_meths = f
2040 | otherwise = f'
2042 -- If it's a metavariable name, try to qualify it from the list of
2043 -- unsolved metavariables
2044 metaVar f (mvn : ns) | f == nsroot mvn = Just mvn
2045 metaVar f (_ : ns) = metaVar f ns
2046 metaVar f [] = Nothing
2048 trimAlts [] alts = alts
2049 trimAlts ns alts
2050 = filter (\(x, _) -> any (\d -> d `isPrefixOf` nspace x) ns) alts
2052 nspace (NS _ s) = s
2053 nspace _ = []
2055 notHidden n = case getAccessibility n of
2056 Hidden -> False
2057 Private -> False
2058 _ -> True
2060 getAccessibility n
2061 = case lookupDefAccExact n False (tt_ctxt ist) of
2062 Just (n,t) -> t
2063 _ -> Public
2065 insertImpl :: [PArg] -- ^ expected argument types (from idris_implicits)
2066 -> [PArg] -- ^ given arguments
2067 -> [PArg]
2068 insertImpl ps as
2069 = let (as', badimpls) = partition (impIn ps) as in
2070 map addUnknownImp badimpls ++
2071 insImpAcc M.empty ps (filter expArg as') (filter (not . expArg) as')
2073 insImpAcc :: M.Map Name PTerm -- accumulated param names & arg terms
2074 -> [PArg] -- parameters
2075 -> [PArg] -- explicit arguments
2076 -> [PArg] -- implicits given
2077 -> [PArg]
2078 insImpAcc pnas (PExp p l n ty : ps) (PExp _ _ _ tm : given) imps =
2079 PExp p l n tm : insImpAcc (M.insert n tm pnas) ps given imps
2080 insImpAcc pnas (PConstraint p l n ty : ps) (PConstraint _ _ _ tm : given) imps =
2081 PConstraint p l n tm : insImpAcc (M.insert n tm pnas) ps given imps
2082 insImpAcc pnas (PConstraint p l n ty : ps) given imps =
2083 let rtc = PResolveTC fc in
2084 PConstraint p l n rtc : insImpAcc (M.insert n rtc pnas) ps given imps
2085 insImpAcc pnas (PImp p _ l n ty : ps) given imps =
2086 case find n imps [] of
2087 Just (tm, imps') ->
2088 PImp p False l n tm : insImpAcc (M.insert n tm pnas) ps given imps'
2089 Nothing ->
2090 PImp p True l n Placeholder :
2091 insImpAcc (M.insert n Placeholder pnas) ps given imps
2092 insImpAcc pnas (PTacImplicit p l n sc' ty : ps) given imps =
2093 let sc = addImpl imp_meths ist (substMatches (M.toList pnas) sc') in
2094 case find n imps [] of
2095 Just (tm, imps') ->
2096 PTacImplicit p l n sc tm :
2097 insImpAcc (M.insert n tm pnas) ps given imps'
2098 Nothing ->
2099 if inpat
2100 then PTacImplicit p l n sc Placeholder :
2101 insImpAcc (M.insert n Placeholder pnas) ps given imps
2102 else PTacImplicit p l n sc sc :
2103 insImpAcc (M.insert n sc pnas) ps given imps
2104 insImpAcc _ expected [] imps = map addUnknownImp imps -- so that unused implicits give error
2105 insImpAcc _ _ given imps = given ++ imps
2107 addUnknownImp arg = arg { argopts = UnknownImp : argopts arg }
2109 find n [] acc = Nothing
2110 find n (PImp _ _ _ n' t : gs) acc
2111 | n == n' = Just (t, reverse acc ++ gs)
2112 find n (PTacImplicit _ _ n' _ t : gs) acc
2113 | n == n' = Just (t, reverse acc ++ gs)
2114 find n (g : gs) acc = find n gs (g : acc)
2116-- | return True if the second argument is an implicit argument which
2117-- is expected in the implicits, or if it's not an implicit
2118impIn :: [PArg] -> PArg -> Bool
2119impIn ps (PExp _ _ _ _) = True
2120impIn ps (PConstraint _ _ _ _) = True
2121impIn ps arg = any (\p -> not (expArg arg) && pname arg == pname p) ps
2123expArg (PExp _ _ _ _) = True
2124expArg (PConstraint _ _ _ _) = True
2125expArg _ = False
2127-- replace non-linear occurrences with _
2129stripLinear :: IState -> PTerm -> PTerm
2130stripLinear i tm = evalState (sl tm) [] where
2131 sl :: PTerm -> State [Name] PTerm
2132 sl (PRef fc hl f)
2133 | (_:_) <- lookupTy f (tt_ctxt i)
2134 = return $ PRef fc hl f
2135 | otherwise = do ns <- get
2136 if (f `elem` ns)
2137 then return $ PHidden (PRef fc hl f) -- Placeholder
2138 else do put (f : ns)
2139 return (PRef fc hl f)
2140 sl (PPatvar fc f)
2141 = do ns <- get
2142 if (f `elem` ns)
2143 then return $ PHidden (PPatvar fc f) -- Placeholder
2144 else do put (f : ns)
2145 return (PPatvar fc f)
2146 -- Assumption is that variables are all the same in each alternative
2147 sl t@(PAlternative ms b as) = do ns <- get
2148 as' <- slAlts ns as
2149 return (PAlternative ms b as')
2150 where slAlts ns (a : as) = do put ns
2151 a' <- sl a
2152 as' <- slAlts ns as
2153 return (a' : as')
2154 slAlts ns [] = return []
2155 sl (PPair fc hls p l r) = do l' <- sl l; r' <- sl r; return (PPair fc hls p l' r')
2156 sl (PDPair fc hls p l t r) = do l' <- sl l
2157 t' <- sl t
2158 r' <- sl r
2159 return (PDPair fc hls p l' t' r')
2160 sl (PApp fc fn args) = do fn' <- case fn of
2161 -- Just the args, fn isn't matchable as a var
2162 PRef _ _ _ -> return fn
2163 t -> sl t
2164 args' <- mapM slA args
2165 return $ PApp fc fn' args'
2166 where slA (PImp p m l n t) = do t' <- sl t
2167 return $ PImp p m l n t'
2168 slA (PExp p l n t) = do t' <- sl t
2169 return $ PExp p l n t'
2170 slA (PConstraint p l n t)
2171 = do t' <- sl t
2172 return $ PConstraint p l n t'
2173 slA (PTacImplicit p l n sc t)
2174 = do t' <- sl t
2175 return $ PTacImplicit p l n sc t'
2176 sl x = return x
2178-- | Remove functions which aren't applied to anything, which must then
2179-- be resolved by unification. Assume names resolved and alternatives
2180-- filled in (so no ambiguity).
2181stripUnmatchable :: IState -> PTerm -> PTerm
2182stripUnmatchable i (PApp fc fn args) = PApp fc fn (fmap (fmap su) args) where
2183 su :: PTerm -> PTerm
2184 su tm@(PRef fc hl f)
2185 | (Bind n (Pi _ _ t _) sc :_) <- lookupTy f (tt_ctxt i)
2186 = Placeholder
2187 | (TType _ : _) <- lookupTy f (tt_ctxt i),
2188 not (implicitable f)
2189 = PHidden tm
2190 | (UType _ : _) <- lookupTy f (tt_ctxt i),
2191 not (implicitable f)
2192 = PHidden tm
2193 su (PApp fc f@(PRef _ _ fn) args)
2194 -- here we use canBeDConName because the impossible pattern
2195 -- check will not necessarily fully resolve constructor names,
2196 -- and these bare names will otherwise get in the way of
2197 -- impossbility checking.
2198 | canBeDConName fn ctxt
2199 = PApp fc f (fmap (fmap su) args)
2200 su (PApp fc f args)
2201 = PHidden (PApp fc f args)
2202 su (PAlternative ms b alts)
2203 = let alts' = filter (/= Placeholder) (map su alts) in
2204 if null alts' then Placeholder
2205 else liftHidden $ PAlternative ms b alts'
2206 su (PPair fc hls p l r) = PPair fc hls p (su l) (su r)
2207 su (PDPair fc hls p l t r) = PDPair fc hls p (su l) (su t) (su r)
2208 su t@(PLam fc _ _ _ _) = PHidden t
2209 su t@(PPi _ _ _ _ _) = PHidden t
2210 su t@(PConstant _ c) | isTypeConst c = PHidden t
2211 su t = t
2213 ctxt = tt_ctxt i
2215 -- If the ambiguous terms are all hidden, the PHidden needs to be outside
2216 -- because elaboration of PHidden gets delayed, and we need the elaboration
2217 -- to resolve the ambiguity.
2218 liftHidden tm@(PAlternative ms b as)
2219 | allHidden as = PHidden (PAlternative ms b (map unHide as))
2220 | otherwise = tm
2222 allHidden [] = True
2223 allHidden (PHidden _ : xs) = allHidden xs
2224 allHidden (x : xs) = False
2226 unHide (PHidden t) = t
2227 unHide t = t
2229stripUnmatchable i tm = tm
2231mkPApp fc a f [] = f
2232mkPApp fc a f as = let rest = drop a as in
2233 if a == 0 then appRest fc f rest
2234 else appRest fc (PApp fc f (take a as)) rest
2235 where
2236 appRest fc f [] = f
2237 appRest fc f (a : as) = appRest fc (PApp fc f [a]) as
2241-- | Find 'static' argument positions
2242-- (the declared ones, plus any names in argument position in the declared
2243-- statics)
2244-- FIXME: It's possible that this really has to happen after elaboration
2245findStatics :: IState -> PTerm -> (PTerm, [Bool])
2246findStatics ist tm = let (ns, ss) = fs tm
2247 in runState (pos ns ss tm) []
2248 where fs (PPi p n fc t sc)
2249 | Static <- pstatic p
2250 = let (ns, ss) = fs sc in
2251 (namesIn [] ist t : ns, n : ss)
2252 | otherwise = let (ns, ss) = fs sc in
2253 (ns, ss)
2254 fs _ = ([], [])
2256 pos ns ss (PPi p n fc t sc)
2257 | elem n ss = do sc' <- pos ns ss sc
2258 spos <- get
2259 put (True : spos)
2260 return (PPi (p { pstatic = Static }) n fc t sc')
2261 | otherwise = do sc' <- pos ns ss sc
2262 spos <- get
2263 put (False : spos)
2264 return (PPi p n fc t sc')
2265 pos ns ss t = return t
2267-- for 6.12/7 compatibility
2268data EitherErr a b = LeftErr a | RightOK b deriving ( Functor )
2270instance Applicative (EitherErr a) where
2271 pure = return
2272 (<*>) = ap
2274instance Monad (EitherErr a) where
2275 return = RightOK
2277 (LeftErr e) >>= _ = LeftErr e
2278 RightOK v >>= k = k v
2280toEither :: EitherErr a b -> Either a b
2281toEither (LeftErr e) = Left e
2282toEither (RightOK ho) = Right ho
2284-- | Syntactic match of a against b, returning pair of variables in a
2285-- and what they match. Returns the pair that failed if not a match.
2286matchClause :: IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
2287matchClause = matchClause' False
2289matchClause' :: Bool -> IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
2290matchClause' names i x y = checkRpts $ match (fullApp x) (fullApp y) where
2291 matchArg x y = match (fullApp (getTm x)) (fullApp (getTm y))
2293 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
2294 fullApp x = x
2296 match' x y = match (fullApp x) (fullApp y)
2297 match (PApp _ (PRef _ _ (NS (UN fi) [b])) [_,_,x]) x'
2298 | fi == txt "fromInteger" && b == txt "builtins",
2299 PConstant _ (I _) <- getTm x = match (getTm x) x'
2300 match x' (PApp _ (PRef _ _ (NS (UN fi) [b])) [_,_,x])
2301 | fi == txt "fromInteger" && b == txt "builtins",
2302 PConstant _ (I _) <- getTm x = match (getTm x) x'
2303 match (PApp _ (PRef _ _ (UN l)) [_,x]) x' | l == txt "lazy" = match (getTm x) x'
2304 match x (PApp _ (PRef _ _ (UN l)) [_,x']) | l == txt "lazy" = match x (getTm x')
2305 match (PApp _ f args) (PApp _ f' args')
2306 | length args == length args'
2307 = do mf <- match' f f'
2308 ms <- zipWithM matchArg args args'
2309 return (mf ++ concat ms)
2310 match (PRef f hl n) (PApp _ x []) = match (PRef f hl n) x
2311 match (PPatvar f n) xr = match (PRef f [f] n) xr
2312 match xr (PPatvar f n) = match xr (PRef f [f] n)
2313 match (PApp _ x []) (PRef f hl n) = match x (PRef f hl n)
2314 match (PRef _ _ n) tm@(PRef _ _ n')
2315 | n == n' && not names &&
2316 (not (isConName n (tt_ctxt i) || isFnName n (tt_ctxt i))
2317 || tm == Placeholder)
2318 = return [(n, tm)]
2319 -- if one namespace is missing, drop the other
2320 | n == n' || n == dropNS n' || dropNS n == n' = return []
2321 where dropNS (NS n _) = n
2322 dropNS n = n
2323 match (PRef _ _ n) tm
2324 | not names && (not (isConName n (tt_ctxt i) ||
2325 isFnName n (tt_ctxt i)) || tm == Placeholder)
2326 = return [(n, tm)]
2327 match (PRewrite _ by l r _) (PRewrite _ by' l' r' _) | by == by'
2328 = do ml <- match' l l'
2329 mr <- match' r r'
2330 return (ml ++ mr)
2331 match (PTyped l r) (PTyped l' r') = do ml <- match l l'
2332 mr <- match r r'
2333 return (ml ++ mr)
2334 match (PTyped l r) x = match l x
2335 match x (PTyped l r) = match x l
2336 match (PPair _ _ _ l r) (PPair _ _ _ l' r') = do ml <- match' l l'
2337 mr <- match' r r'
2338 return (ml ++ mr)
2339 match (PDPair _ _ _ l t r) (PDPair _ _ _ l' t' r') = do ml <- match' l l'
2340 mt <- match' t t'
2341 mr <- match' r r'
2342 return (ml ++ mt ++ mr)
2343 match (PAlternative _ a as) (PAlternative _ a' as')
2344 = do ms <- zipWithM match' as as'
2345 return (concat ms)
2346 match a@(PAlternative _ _ as) b
2347 = do let ms = zipWith match' as (repeat b)
2348 case (rights (map toEither ms)) of
2349 (x: _) -> return x
2350 _ -> LeftErr (a, b)
2351 match (PCase _ _ _) _ = return [] -- lifted out
2352 match (PMetavar _ _) _ = return [] -- modified
2353 match (PInferRef _ _ _) _ = return [] -- modified
2354 match (PQuote _) _ = return []
2355 match (PProof _) _ = return []
2356 match (PTactics _) _ = return []
2357 match (PResolveTC _) (PResolveTC _) = return []
2358 match (PTrue _ _) (PTrue _ _) = return []
2359 match (PPi _ _ _ t s) (PPi _ _ _ t' s') = do mt <- match' t t'
2360 ms <- match' s s'
2361 return (mt ++ ms)
2362 match (PLam _ _ _ t s) (PLam _ _ _ t' s') = do mt <- match' t t'
2363 ms <- match' s s'
2364 return (mt ++ ms)
2365 match (PLet _ _ _ _ t ty s) (PLet _ _ _ _ t' ty' s')
2366 = do mt <- match' t t'
2367 mty <- match' ty ty'
2368 ms <- match' s s'
2369 return (mt ++ mty ++ ms)
2370 match (PHidden x) (PHidden y)
2371 | RightOK xs <- match x y = return xs -- to collect variables
2372 | otherwise = return [] -- Otherwise hidden things are unmatchable
2373 match (PHidden x) y
2374 | RightOK xs <- match x y = return xs
2375 | otherwise = return []
2376 match x (PHidden y)
2377 | RightOK xs <- match x y = return xs
2378 | otherwise = return []
2379 match (PUnifyLog x) y = match' x y
2380 match x (PUnifyLog y) = match' x y
2381 match (PNoImplicits x) y = match' x y
2382 match x (PNoImplicits y) = match' x y
2383 match Placeholder _ = return []
2384 match _ Placeholder = return []
2385 match (PResolveTC _) _ = return []
2386 match a b | a == b = return []
2387 | otherwise = LeftErr (a, b)
2389 checkRpts (RightOK ms) = check ms where
2390 check ((n,t):xs)
2391 | Just t' <- lookup n xs = if t/=t' && t/=Placeholder && t'/=Placeholder
2392 then Left (t, t')
2393 else check xs
2394 check (_:xs) = check xs
2395 check [] = Right ms
2396 checkRpts (LeftErr x) = Left x
2398substMatches :: [(Name, PTerm)] -> PTerm -> PTerm
2399substMatches ms = substMatchesShadow ms []
2401-- substMatchesShadow :: [(Name, PTerm)] -> [Name] -> PTerm -> PTerm
2402-- substMatchesShadow [] shs t = t
2403-- substMatchesShadow ((n,tm):ns) shs t
2404-- = substMatchShadow n shs tm (substMatchesShadow ns shs t)
2406substMatch :: Name -> PTerm -> PTerm -> PTerm
2407substMatch n = substMatchShadow n []
2409substMatchShadow :: Name -> [Name] -> PTerm -> PTerm -> PTerm
2410substMatchShadow n shs tm t = substMatchesShadow [(n, tm)] shs t
2412substMatchesShadow :: [(Name, PTerm)] -> [Name] -> PTerm -> PTerm
2413substMatchesShadow nmap shs t = sm shs t where
2414 sm xs (PRef _ _ n) | Just tm <- lookup n nmap = tm
2415 sm xs (PLam fc x xfc t sc) = PLam fc x xfc (sm xs t) (sm xs sc)
2416 sm xs (PPi p x fc t sc)
2417 | x `elem` xs
2418 = let x' = nextName x in
2419 PPi p x' fc (sm (x':xs) (substMatch x (PRef emptyFC [] x') t))
2420 (sm (x':xs) (substMatch x (PRef emptyFC [] x') sc))
2421 | otherwise = PPi p x fc (sm xs t) (sm (x : xs) sc)
2422 sm xs (PLet fc rc x xfc val t sc)
2423 = PLet fc rc x xfc (sm xs val) (sm xs t) (sm xs sc)
2424 sm xs (PApp f x as) = fullApp $ PApp f (sm xs x) (map (fmap (sm xs)) as)
2425 sm xs (PCase f x as) = PCase f (sm xs x) (map (pmap (sm xs)) as)
2426 sm xs (PIfThenElse fc c t f) = PIfThenElse fc (sm xs c) (sm xs t) (sm xs f)
2427 sm xs (PRewrite f by x y tm) = PRewrite f by (sm xs x) (sm xs y)
2428 (fmap (sm xs) tm)
2429 sm xs (PTyped x y) = PTyped (sm xs x) (sm xs y)
2430 sm xs (PPair f hls p x y) = PPair f hls p (sm xs x) (sm xs y)
2431 sm xs (PDPair f hls p x t y) = PDPair f hls p (sm xs x) (sm xs t) (sm xs y)
2432 sm xs (PAlternative ms a as) = PAlternative ms a (map (sm xs) as)
2433 sm xs (PHidden x) = PHidden (sm xs x)
2434 sm xs (PUnifyLog x) = PUnifyLog (sm xs x)
2435 sm xs (PNoImplicits x) = PNoImplicits (sm xs x)
2436 sm xs (PRunElab fc script ns) = PRunElab fc (sm xs script) ns
2437 sm xs (PConstSugar fc tm) = PConstSugar fc (sm xs tm)
2438 sm xs x = x
2440 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
2441 fullApp x = x
2443shadow :: Name -> Name -> PTerm -> PTerm
2444shadow n n' t = sm 0 t where
2445 sm 0 (PRef fc hl x) | n == x = PRef fc hl n'
2446 sm 0 (PLam fc x xfc t sc) | n /= x = PLam fc x xfc (sm 0 t) (sm 0 sc)
2447 | otherwise = PLam fc x xfc (sm 0 t) sc
2448 sm 0 (PPi p x fc t sc) | n /= x = PPi p x fc (sm 0 t) (sm 0 sc)
2449 | otherwise = PPi p x fc (sm 0 t) sc
2450 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)
2451 | otherwise = PLet fc rc x xfc (sm 0 t) (sm 0 v) sc
2452 sm 0 (PApp f x as) = PApp f (sm 0 x) (map (fmap (sm 0)) as)
2453 sm 0 (PAppBind f x as) = PAppBind f (sm 0 x) (map (fmap (sm 0)) as)
2454 sm 0 (PCase f x as) = PCase f (sm 0 x) (map (pmap (sm 0)) as)
2455 sm 0 (PIfThenElse fc c t f) = PIfThenElse fc (sm 0 c) (sm 0 t) (sm 0 f)
2456 sm 0 (PRewrite f by x y tm) = PRewrite f by (sm 0 x) (sm 0 y) (fmap (sm 0) tm)
2457 sm 0 (PTyped x y) = PTyped (sm 0 x) (sm 0 y)
2458 sm 0 (PPair f hls p x y) = PPair f hls p (sm 0 x) (sm 0 y)
2459 sm 0 (PDPair f hls p x t y) = PDPair f hls p (sm 0 x) (sm 0 t) (sm 0 y)
2460 sm 0 (PAlternative ms a as)
2461 = PAlternative (map shadowAlt ms) a (map (sm 0) as)
2462 sm 0 (PTactics ts) = PTactics (map (fmap (sm 0)) ts)
2463 sm 0 (PProof ts) = PProof (map (fmap (sm 0)) ts)
2464 sm 0 (PHidden x) = PHidden (sm 0 x)
2465 sm 0 (PUnifyLog x) = PUnifyLog (sm 0 x)
2466 sm 0 (PNoImplicits x) = PNoImplicits (sm 0 x)
2467 sm 0 (PCoerced t) = PCoerced (sm 0 t)
2468 sm ql (PQuasiquote tm ty) = PQuasiquote (sm (ql + 1) tm) (fmap (sm ql) ty)
2469 sm ql (PUnquote tm) = PUnquote (sm (ql - 1) tm)
2470 sm ql x = descend (sm ql) x
2472 shadowAlt p@(x, oldn) = (update x, update oldn)
2473 update oldn | n == oldn = n'
2474 | otherwise = oldn
2476-- | Rename any binders which are repeated (so that we don't have to
2477-- mess about with shadowing anywhere else).
2478mkUniqueNames :: [Name] -> [(Name, Name)] -> PTerm -> PTerm
2479mkUniqueNames env shadows tm
2480 = evalState (mkUniq 0 initMap tm) (S.fromList env) where
2482 initMap = M.fromList shadows
2484 inScope :: S.Set Name
2485 inScope = S.fromList $ boundNamesIn tm
2487 mkUniqA ql nmap arg = do t' <- mkUniq ql nmap (getTm arg)
2488 return (arg { getTm = t' })
2490 -- Initialise the unique name with the environment length (so we're not
2491 -- looking for too long...)
2492 initN (UN n) l = UN $ txt (str n ++ show l)
2493 initN (MN i s) l = MN (i+l) s
2494 initN n _ = n
2496 -- FIXME: Probably ought to do this for completeness! It's fine as
2497 -- long as there are no bindings inside tactics though.
2498 mkUniqT _ nmap tac = return tac
2500 mkUniq :: Int -- ^ The number of quotations that we're under
2501 -> M.Map Name Name -> PTerm -> State (S.Set Name) PTerm
2502 mkUniq 0 nmap (PLam fc n nfc ty sc)
2503 = do env <- get
2504 (n', sc') <-
2505 if n `S.member` env
2506 then do let n' = uniqueNameSet (initN n (S.size env))
2507 (S.union env inScope)
2508 return (n', sc) -- shadow n n' sc)
2509 else return (n, sc)
2510 put (S.insert n' env)
2511 let nmap' = M.insert n n' nmap
2512 ty' <- mkUniq 0 nmap ty
2513 sc'' <- mkUniq 0 nmap' sc'
2514 return $! PLam fc n' nfc ty' sc''
2515 mkUniq 0 nmap (PPi p n fc ty sc)
2516 = do env <- get
2517 (n', sc') <-
2518 if n `S.member` env
2519 then do let n' = uniqueNameSet (initN n (S.size env))
2520 (S.union env inScope)
2521 return (n', sc) -- shadow n n' sc)
2522 else return (n, sc)
2523 put (S.insert n' env)
2524 let nmap' = M.insert n n' nmap
2525 ty' <- mkUniq 0 nmap ty
2526 sc'' <- mkUniq 0 nmap' sc'
2527 return $! PPi p n' fc ty' sc''
2528 mkUniq 0 nmap (PLet fc rc n nfc ty val sc)
2529 = do env <- get
2530 (n', sc') <-
2531 if n `S.member` env
2532 then do let n' = uniqueNameSet (initN n (S.size env))
2533 (S.union env inScope)
2534 return (n', sc) -- shadow n n' sc)
2535 else return (n, sc)
2536 put (S.insert n' env)
2537 let nmap' = M.insert n n' nmap
2538 ty' <- mkUniq 0 nmap ty; val' <- mkUniq 0 nmap val
2539 sc'' <- mkUniq 0 nmap' sc'
2540 return $! PLet fc rc n' nfc ty' val' sc''
2541 mkUniq 0 nmap (PApp fc t args)
2542 = do t' <- mkUniq 0 nmap t
2543 args' <- mapM (mkUniqA 0 nmap) args
2544 return $! PApp fc t' args'
2545 mkUniq 0 nmap (PAppBind fc t args)
2546 = do t' <- mkUniq 0 nmap t
2547 args' <- mapM (mkUniqA 0 nmap) args
2548 return $! PAppBind fc t' args'
2549 mkUniq 0 nmap (PCase fc t alts)
2550 = do t' <- mkUniq 0 nmap t
2551 alts' <- mapM (\(x,y)-> do x' <- mkUniq 0 nmap x; y' <- mkUniq 0 nmap y
2552 return (x', y')) alts
2553 return $! PCase fc t' alts'
2554 mkUniq 0 nmap (PIfThenElse fc c t f)
2555 = liftM3 (PIfThenElse fc) (mkUniq 0 nmap c) (mkUniq 0 nmap t) (mkUniq 0 nmap f)
2556 mkUniq 0 nmap (PPair fc hls p l r)
2557 = do l' <- mkUniq 0 nmap l; r' <- mkUniq 0 nmap r
2558 return $! PPair fc hls p l' r'
2559 mkUniq 0 nmap (PDPair fc hls p (PRef fc' hls' n) t sc)
2560 | t /= Placeholder
2561 = do env <- get
2562 (n', sc') <- if n `S.member` env
2563 then do let n' = uniqueNameSet n (S.union env inScope)
2564 return (n', sc) -- shadow n n' sc)
2565 else return (n, sc)
2566 put (S.insert n' env)
2567 let nmap' = M.insert n n' nmap
2568 t' <- mkUniq 0 nmap t
2569 sc'' <- mkUniq 0 nmap' sc'
2570 return $! PDPair fc hls p (PRef fc' hls' n') t' sc''
2571 mkUniq 0 nmap (PDPair fc hls p l t r)
2572 = do l' <- mkUniq 0 nmap l; t' <- mkUniq 0 nmap t; r' <- mkUniq 0 nmap r
2573 return $! PDPair fc hls p l' t' r'
2574 mkUniq 0 nmap (PAlternative ns b as)
2575 -- store the nmap and defer the rest until we've pruned the set
2576 -- during elaboration
2577 = return $ PAlternative (ns ++ M.toList nmap) b as
2578 mkUniq 0 nmap (PHidden t) = liftM PHidden (mkUniq 0 nmap t)
2579 mkUniq 0 nmap (PUnifyLog t) = liftM PUnifyLog (mkUniq 0 nmap t)
2580 mkUniq 0 nmap (PDisamb n t) = liftM (PDisamb n) (mkUniq 0 nmap t)
2581 mkUniq 0 nmap (PNoImplicits t) = liftM PNoImplicits (mkUniq 0 nmap t)
2582 mkUniq 0 nmap (PProof ts) = liftM PProof (mapM (mkUniqT 0 nmap) ts)
2583 mkUniq 0 nmap (PTactics ts) = liftM PTactics (mapM (mkUniqT 0 nmap) ts)
2584 mkUniq 0 nmap (PRunElab fc ts ns) = liftM (\tm -> PRunElab fc tm ns) (mkUniq 0 nmap ts)
2585 mkUniq 0 nmap (PConstSugar fc tm) = liftM (PConstSugar fc) (mkUniq 0 nmap tm)
2586 mkUniq 0 nmap (PCoerced tm) = liftM PCoerced (mkUniq 0 nmap tm)
2587 mkUniq 0 nmap t = return $ shadowAll (M.toList nmap) t
2588 where
2589 shadowAll [] t = t
2590 shadowAll ((n, n') : ns) t = shadow n n' (shadowAll ns t)
2592 mkUniq ql nmap (PQuasiquote tm ty) =
2593 do tm' <- mkUniq (ql + 1) nmap tm
2594 ty' <- case ty of
2595 Nothing -> return Nothing
2596 Just t -> fmap Just $ mkUniq ql nmap t
2597 return $! PQuasiquote tm' ty'
2598 mkUniq ql nmap (PUnquote tm) = fmap PUnquote (mkUniq (ql - 1) nmap tm)
2600 mkUniq ql nmap tm = descendM (mkUniq ql nmap) tm