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