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