1{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, DeriveFunctor,
2 TypeSynonymInstances, PatternGuards #-}
4module Idris.AbsSyntax(module Idris.AbsSyntax, module Idris.AbsSyntaxTree) where
8import Core.Elaborate hiding (Tactic(..))
10import Idris.AbsSyntaxTree
14import System.Console.Haskeline
16import Control.Monad.State
27getContext :: Idris Context
28getContext = do i <- get; return (tt_ctxt i)
30getObjectFiles :: Idris [FilePath]
31getObjectFiles = do i <- get; return (idris_objs i)
33addObjectFile :: FilePath -> Idris ()
34addObjectFile f = do i <- get; put (i { idris_objs = f : idris_objs i })
36getLibs :: Idris [String]
37getLibs = do i <- get; return (idris_libs i)
39addLib :: String -> Idris ()
40addLib f = do i <- get; put (i { idris_libs = f : idris_libs i })
42addHdr :: String -> Idris ()
43addHdr f = do i <- get; put (i { idris_hdrs = f : idris_hdrs i })
45totcheck :: (FC, Name) -> Idris ()
46totcheck n = do i <- get; put (i { idris_totcheck = idris_totcheck i ++ [n] })
48setFlags :: Name -> [FnOpt] -> Idris ()
49setFlags n fs = do i <- get; put (i { idris_flags = addDef n fs (idris_flags i) })
51setAccessibility :: Name -> Accessibility -> Idris ()
54 let ctxt = setAccess n a (tt_ctxt i)
55 put (i { tt_ctxt = ctxt })
57setTotality :: Name -> Totality -> Idris ()
60 let ctxt = setTotal n a (tt_ctxt i)
61 put (i { tt_ctxt = ctxt })
63getTotality :: Name -> Idris Totality
66 case lookupTotal n (tt_ctxt i) of
68 _ -> return (Total [])
70addToCG :: Name -> CGInfo -> Idris ()
71addToCG n cg = do i <- get
72 put (i { idris_callgraph = addDef n cg (idris_callgraph i) })
74addToCalledG :: Name -> [Name] -> Idris ()
75addToCalledG n ns = return () -- TODO
77-- Add a class instance function. Dodgy hack: Put integer instances first in the
78-- list so they are resolved by default.
79-- Dodgy hack 2: put constraint chasers (@@) last
81addInstance :: Bool -> Name -> Name -> Idris ()
84 case lookupCtxt Nothing n (idris_classes ist) of
86 do let cs = addDef n (CI a b c d (addI i ins)) (idris_classes ist)
87 put (ist { idris_classes = cs })
88 _ -> do let cs = addDef n (CI (MN 0 "none") [] [] [] [i]) (idris_classes ist)
89 put (ist { idris_classes = cs })
90 where addI i ins | int = i : ins
91 | chaser n = ins ++ [i]
92 | otherwise = insI i ins
94 insI i (n : ns) | chaser n = i : n : ns
95 | otherwise = n : insI i ns
97 chaser (UN ('@':'@':_)) = True
98 chaser (NS n _) = chaser n
101addClass :: Name -> ClassInfo -> Idris ()
104 let i' = case lookupCtxt Nothing n (idris_classes ist) of
105 [c] -> c { class_instances = class_instances i }
107 put (ist { idris_classes = addDef n i' (idris_classes ist) })
109addIBC :: IBCWrite -> Idris ()
112 when (notDef (ibc_write i)) $
113 put (i { ibc_write = ibc : ibc_write i })
114 where notDef [] = True
115 notDef (IBCDef n': is) | n == n' = False
116 notDef (_ : is) = notDef is
117addIBC ibc = do i <- get; put (i { ibc_write = ibc : ibc_write i })
120clearIBC = do i <- get; put (i { ibc_write = [] })
122getHdrs :: Idris [String]
123getHdrs = do i <- get; return (idris_hdrs i)
125setErrLine :: Int -> Idris ()
126setErrLine x = do i <- get;
128 Nothing -> put (i { errLine = Just x })
132clearErr = do i <- get
133 put (i { errLine = Nothing })
135getSO :: Idris (Maybe String)
137 return (compiled_so i)
139setSO :: Maybe String -> Idris ()
141 put (i { compiled_so = s })
143getIState :: Idris IState
146putIState :: IState -> Idris ()
150getName = do i <- get;
151 let idx = idris_name i;
152 put (i { idris_name = idx + 1 })
155checkUndefined :: FC -> Name -> Idris ()
158 case lookupTy Nothing n i of
159 (_:_) -> fail $ show fc ++ ":" ++
160 show n ++ " already defined"
163isUndefined :: FC -> Name -> Idris Bool
166 case lookupTy Nothing n i of
167 (_:_) -> return False
170setContext :: Context -> Idris ()
171setContext ctxt = do i <- get; put (i { tt_ctxt = ctxt } )
173updateContext :: (Context -> Context) -> Idris ()
174updateContext f = do i <- get; put (i { tt_ctxt = f (tt_ctxt i) } )
176addConstraints :: FC -> (Int, [UConstraint]) -> Idris ()
177addConstraints fc (v, cs)
180 let ctxt' = ctxt { uconstraints = cs ++ uconstraints ctxt,
182 let ics = zip cs (repeat fc) ++ idris_constraints i
183 put (i { tt_ctxt = ctxt', idris_constraints = ics })
185addDeferred :: [(Name, Type)] -> Idris ()
186addDeferred ns = do mapM_ (\(n, t) -> updateContext (addTyDecl n (tidyNames [] t))) ns
188 put (i { idris_metavars = map fst ns ++ idris_metavars i })
189 where tidyNames used (Bind (MN i x) b sc)
190 = let n' = uniqueName (UN x) used in
191 Bind n' b $ tidyNames (n':used) sc
192 tidyNames used (Bind n b sc)
193 = let n' = uniqueName n used in
194 Bind n' b $ tidyNames (n':used) sc
197solveDeferred :: Name -> Idris ()
198solveDeferred n = do i <- get
199 put (i { idris_metavars = idris_metavars i \\ [n] })
201iputStrLn :: String -> Idris ()
202iputStrLn = liftIO . putStrLn
204iWarn :: FC -> String -> Idris ()
205iWarn fc err = liftIO $ putStrLn (show fc ++ ":" ++ err)
207setLogLevel :: Int -> Idris ()
208setLogLevel l = do i <- get
209 let opts = idris_options i
210 let opt' = opts { opt_logLevel = l }
211 put (i { idris_options = opt' } )
213setCmdLine :: [Opt] -> Idris ()
214setCmdLine opts = do i <- get
215 let iopts = idris_options i
216 put (i { idris_options = iopts { opt_cmdline = opts } })
218getDumpC :: Idris (Maybe FilePath)
219getDumpC = do i <- get
220 return $ findC (opt_cmdline (idris_options i))
221 where findC [] = Nothing
222 findC (DumpC x : _) = Just x
223 findC (_ : xs) = findC xs
225getDumpDefun :: Idris (Maybe FilePath)
226getDumpDefun = do i <- get
227 return $ findC (opt_cmdline (idris_options i))
228 where findC [] = Nothing
229 findC (DumpDefun x : _) = Just x
230 findC (_ : xs) = findC xs
232getDumpCases :: Idris (Maybe FilePath)
233getDumpCases = do i <- get
234 return $ findC (opt_cmdline (idris_options i))
235 where findC [] = Nothing
236 findC (DumpCases x : _) = Just x
237 findC (_ : xs) = findC xs
240logLevel = do i <- get
241 return (opt_logLevel (idris_options i))
243setErrContext :: Bool -> Idris ()
244setErrContext t = do i <- get
245 let opts = idris_options i
246 let opt' = opts { opt_errContext = t }
247 put (i { idris_options = opt' })
249errContext :: Idris Bool
250errContext = do i <- get
251 return (opt_errContext (idris_options i))
255 return (opt_repl (idris_options i))
257setREPL :: Bool -> Idris ()
258setREPL t = do i <- get
259 let opts = idris_options i
260 let opt' = opts { opt_repl = t }
261 put (i { idris_options = opt' })
265 return (opt_verbose (idris_options i))
267setVerbose :: Bool -> Idris ()
268setVerbose t = do i <- get
269 let opts = idris_options i
270 let opt' = opts { opt_verbose = t }
271 put (i { idris_options = opt' })
273typeInType :: Idris Bool
274typeInType = do i <- get
275 return (opt_typeintype (idris_options i))
277setTypeInType :: Bool -> Idris ()
278setTypeInType t = do i <- get
279 let opts = idris_options i
280 let opt' = opts { opt_typeintype = t }
281 put (i { idris_options = opt' })
283coverage :: Idris Bool
284coverage = do i <- get
285 return (opt_coverage (idris_options i))
287setCoverage :: Bool -> Idris ()
288setCoverage t = do i <- get
289 let opts = idris_options i
290 let opt' = opts { opt_coverage = t }
291 put (i { idris_options = opt' })
293setIBCSubDir :: FilePath -> Idris ()
294setIBCSubDir fp = do i <- get
295 let opts = idris_options i
296 let opt' = opts { opt_ibcsubdir = fp }
297 put (i { idris_options = opt' })
299valIBCSubDir :: IState -> Idris FilePath
300valIBCSubDir i = return (opt_ibcsubdir (idris_options i))
302addImportDir :: FilePath -> Idris ()
303addImportDir fp = do i <- get
304 let opts = idris_options i
305 let opt' = opts { opt_importdirs = fp : opt_importdirs opts }
306 put (i { idris_options = opt' })
308setImportDirs :: [FilePath] -> Idris ()
309setImportDirs fps = do i <- get
310 let opts = idris_options i
311 let opt' = opts { opt_importdirs = fps }
312 put (i { idris_options = opt' })
314allImportDirs :: IState -> Idris [FilePath]
315allImportDirs i = do let optdirs = opt_importdirs (idris_options i)
316 return ("." : optdirs)
320 return (opt_showimp (idris_options i))
322setImpShow :: Bool -> Idris ()
323setImpShow t = do i <- get
324 let opts = idris_options i
325 let opt' = opts { opt_showimp = t }
326 put (i { idris_options = opt' })
328logLvl :: Int -> String -> Idris ()
329logLvl l str = do i <- get
330 let lvl = opt_logLevel (idris_options i)
332 $ do liftIO (putStrLn str)
333 put (i { idris_log = idris_log i ++ str ++ "\n" } )
335cmdOptSet :: Opt -> Idris Bool
336cmdOptSet x = do i <- get
337 return $ x `elem` opt_cmdline (idris_options i)
339iLOG :: String -> Idris ()
342noErrors :: Idris Bool
343noErrors = do i <- get
345 Nothing -> return True
348setTypeCase :: Bool -> Idris ()
349setTypeCase t = do i <- get
350 let opts = idris_options i
351 let opt' = opts { opt_typecase = t }
352 put (i { idris_options = opt' })
355-- For inferring types of things
359inferTy = MN 0 "__Infer"
360inferCon = MN 0 "__infer"
361inferDecl = PDatadecl inferTy
363 [(inferCon, PPi impl (MN 0 "A") PSet (
364 PPi expl (MN 0 "a") (PRef bi (MN 0 "A"))
365 (PRef bi inferTy)), bi)]
367infTerm t = PApp bi (PRef bi inferCon) [pimp (MN 0 "A") Placeholder, pexp t]
368infP = P (TCon 6 0) inferTy (Set (UVal 0))
370getInferTerm, getInferType :: Term -> Term
371getInferTerm (Bind n b sc) = Bind n b $ getInferTerm sc
372getInferTerm (App (App _ _) tm) = tm
373getInferTerm tm = error ("getInferTerm " ++ show tm)
375getInferType (Bind n b sc) = Bind n b $ getInferType sc
376getInferType (App (App _ ty) _) = ty
378-- Handy primitives: Unit, False, Pair, MkPair, =, mkForeign
380primNames = [unitTy, unitCon,
381 falseTy, pairTy, pairCon,
382 eqTy, eqCon, inferTy, inferCon]
384unitTy = MN 0 "__Unit"
386unitDecl = PDatadecl unitTy PSet
387 [(unitCon, PRef bi unitTy, bi)]
389falseTy = MN 0 "__False"
390falseDecl = PDatadecl falseTy PSet []
392pairTy = MN 0 "__Pair"
393pairCon = MN 0 "__MkPair"
394pairDecl = PDatadecl pairTy (piBind [(n "A", PSet), (n "B", PSet)] PSet)
395 [(pairCon, PPi impl (n "A") PSet (
396 PPi impl (n "B") PSet (
397 PPi expl (n "a") (PRef bi (n "A")) (
398 PPi expl (n "b") (PRef bi (n "B"))
399 (PApp bi (PRef bi pairTy) [pexp (PRef bi (n "A")),
400 pexp (PRef bi (n "B"))])))), bi)]
405eqDecl = PDatadecl eqTy (piBind [(n "a", PSet), (n "b", PSet),
406 (n "x", PRef bi (n "a")), (n "y", PRef bi (n "b"))]
408 [(eqCon, PPi impl (n "a") PSet (
409 PPi impl (n "x") (PRef bi (n "a"))
410 (PApp bi (PRef bi eqTy) [pimp (n "a") Placeholder,
411 pimp (n "b") Placeholder,
412 pexp (PRef bi (n "x")),
413 pexp (PRef bi (n "x"))])), bi)]
416-- Defined in builtins.idr
418existsCon = UN "Ex_intro"
420piBind :: [(Name, PTerm)] -> PTerm -> PTerm
423piBindp :: Plicity -> [(Name, PTerm)] -> PTerm -> PTerm
425piBindp p ((n, ty):ns) t = PPi p n ty (piBind ns t)
427-- Dealing with parameters
429expandParams :: (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PTerm -> PTerm
430expandParams dec ps ns tm = en tm
432 -- if we shadow a name (say in a lambda binding) that is used in a call to
433 -- a lifted function, we need access to both names - once in the scope of the
434 -- binding and once to call the lifted functions. So we'll explicitly shadow
435 -- it. (Yes, it's a hack. The alternative would be to resolve names earlier
438 mkShadow (UN n) = MN 0 n
439 mkShadow (MN i n) = MN (i+1) n
440 mkShadow (NS x s) = NS (mkShadow x) s
443 | n `elem` map fst ps
444 = let n' = mkShadow n in
445 PLam n' (en t) (en (shadow n n' s))
446 | otherwise = PLam n (en t) (en s)
448 | n `elem` map fst ps
449 = let n' = mkShadow n in
450 PPi p n' (en t) (en (shadow n n' s))
451 | otherwise = PPi p n (en t) (en s)
453 | n `elem` map fst ps
454 = let n' = mkShadow n in
455 PLet n' (en ty) (en v) (en (shadow n n' s))
456 | otherwise = PLet n (en ty) (en v) (en s)
457 en (PEq f l r) = PEq f (en l) (en r)
458 en (PTyped l r) = PTyped (en l) (en r)
459 en (PPair f l r) = PPair f (en l) (en r)
460 en (PDPair f l t r) = PDPair f (en l) (en t) (en r)
461 en (PAlternative a as) = PAlternative a (map en as)
462 en (PHidden t) = PHidden (en t)
463 en (PDoBlock ds) = PDoBlock (map (fmap en) ds)
464 en (PProof ts) = PProof (map (fmap en) ts)
465 en (PTactics ts) = PTactics (map (fmap en) ts)
468 | n `nselem` ns = PQuote (Var (dec n))
469 en (PApp fc (PRef fc' n) as)
470 | n `nselem` ns = PApp fc (PRef fc' (dec n))
471 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
473 | n `nselem` ns = PApp fc (PRef fc (dec n))
474 (map (pexp . (PRef fc)) (map fst ps))
475 en (PApp fc f as) = PApp fc (en f) (map (fmap en) as)
476 en (PCase fc c os) = PCase fc (en c) (map (pmap en) os)
480 nselem x (y : xs) | nseq x y = True
481 | otherwise = nselem x xs
483 nseq x y = nsroot x == nsroot y
485expandParamsD :: IState ->
486 (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PDecl -> PDecl
487expandParamsD ist dec ps ns (PTy syn fc o n ty)
489 then PTy syn fc o (dec n) (piBind ps (expandParams dec ps ns ty))
490 else PTy syn fc o n (expandParams dec ps ns ty)
491expandParamsD ist dec ps ns (PClauses fc opts n cs)
492 = let n' = if n `elem` ns then dec n else n in
493 PClauses fc opts n' (map expandParamsC cs)
495 expandParamsC (PClause fc n lhs ws rhs ds)
496 = let -- ps' = updateps True (namesIn ist rhs) (zip ps [0..])
497 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
498 n' = if n `elem` ns then dec n else n in
499 PClause fc n' (expandParams dec ps'' ns lhs)
500 (map (expandParams dec ps'' ns) ws)
501 (expandParams dec ps'' ns rhs)
502 (map (expandParamsD ist dec ps'' ns) ds)
503 expandParamsC (PWith fc n lhs ws wval ds)
504 = let -- ps' = updateps True (namesIn ist wval) (zip ps [0..])
505 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
506 n' = if n `elem` ns then dec n else n in
507 PWith fc n' (expandParams dec ps'' ns lhs)
508 (map (expandParams dec ps'' ns) ws)
509 (expandParams dec ps'' ns wval)
510 (map (expandParamsD ist dec ps'' ns) ds)
511 updateps yn nm [] = []
512 updateps yn nm (((a, t), i):as)
513 | (a `elem` nm) == yn = (a, t) : updateps yn nm as
514 | otherwise = (MN i (show n ++ "_u"), t) : updateps yn nm as
515expandParamsD ist dec ps ns (PData syn fc co pd) = PData syn fc co (expandPData pd)
517 -- just do the type decl, leave constructors alone (parameters will be
519 expandPData (PDatadecl n ty cons)
521 then PDatadecl (dec n) (piBind ps (expandParams dec ps ns ty)) (map econ cons)
522 else PDatadecl n (expandParams dec ps ns ty) (map econ cons)
523 econ (n, t, fc) = (dec n, piBindp expl ps (expandParams dec ps ns t), fc)
524expandParamsD ist dec ps ns (PParams f params pds)
525 = PParams f (map (mapsnd (expandParams dec ps ns)) params)
526 (map (expandParamsD ist dec ps ns) pds)
527expandParamsD ist dec ps ns (PClass info f cs n params decls)
529 (map (expandParams dec ps ns) cs)
531 (map (mapsnd (expandParams dec ps ns)) params)
532 (map (expandParamsD ist dec ps ns) decls)
533expandParamsD ist dec ps ns (PInstance info f cs n params ty cn decls)
535 (map (expandParams dec ps ns) cs)
537 (map (expandParams dec ps ns) params)
538 (expandParams dec ps ns ty)
540 (map (expandParamsD ist dec ps ns) decls)
541expandParamsD ist dec ps ns d = d
543mapsnd f (x, t) = (x, f t)
545-- Calculate a priority for a type, for deciding elaboration order
546-- * if it's just a type variable or concrete type, do it early (0)
547-- * if there's only type variables and injective constructors, do it next (1)
548-- * if there's a function type, next (2)
549-- * finally, everything else (3)
551getPriority :: IState -> PTerm -> Int
552getPriority i tm = pri tm
555 case lookupP Nothing n (tt_ctxt i) of
556 ((P (DCon _ _) _ _):_) -> 1
557 ((P (TCon _ _) _ _):_) -> 1
559 [] -> 0 -- must be locally bound, if it's not an error...
560 pri (PPi _ _ x y) = max 5 (max (pri x) (pri y))
564 pri (PEq _ l r) = max 1 (max (pri l) (pri r))
565 pri (PApp _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.getTm) as)))
566 pri (PCase _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.snd) as)))
567 pri (PTyped l r) = pri l
568 pri (PPair _ l r) = max 1 (max (pri l) (pri r))
569 pri (PDPair _ l t r) = max 1 (max (pri l) (max (pri t) (pri r)))
570 pri (PAlternative a as) = maximum (map pri as)
571 pri (PConstant _) = 0
575addStatics :: Name -> Term -> PTerm -> Idris ()
577 do let (statics, dynamics) = initStatics tm ptm
578 let stnames = nub $ concatMap freeNames (map snd statics)
579 let dnames = nub $ concatMap freeNames (map snd dynamics)
580 when (not (null statics)) $
581 logLvl 7 $ show n ++ " " ++ show statics ++ "\n" ++ show dynamics
582 ++ "\n" ++ show stnames ++ "\n" ++ show dnames
583 let statics' = nub $ map fst statics ++
584 filter (\x -> not (elem x dnames)) stnames
585 let stpos = staticList statics' tm
587 put (i { idris_statics = addDef n stpos (idris_statics i) })
590 initStatics (Bind n (Pi ty) sc) (PPi p _ _ s)
591 = let (static, dynamic) = initStatics (instantiate (P Bound n ty) sc) s in
592 if pstatic p == Static then ((n, ty) : static, dynamic)
593 else (static, (n, ty) : dynamic)
594 initStatics t pt = ([], [])
596 staticList sts (Bind n (Pi _) sc) = (n `elem` sts) : staticList sts sc
599-- Dealing with implicit arguments
601-- Add implicit Pi bindings for any names in the term which appear in an
604-- This has become a right mess already. Better redo it some time...
606implicit :: SyntaxInfo -> Name -> PTerm -> Idris PTerm
607implicit syn n ptm = implicit' syn [] n ptm
609implicit' :: SyntaxInfo -> [Name] -> Name -> PTerm -> Idris PTerm
610implicit' syn ignore n ptm
612 let (tm', impdata) = implicitise syn ignore i ptm
613-- let (tm'', spos) = findStatics i tm'
614 put (i { idris_implicits = addDef n impdata (idris_implicits i) })
616 logLvl 5 ("Implicit " ++ show n ++ " " ++ show impdata)
618-- put (i { idris_statics = addDef n spos (idris_statics i) })
621implicitise :: SyntaxInfo -> [Name] -> IState -> PTerm -> (PTerm, [PArg])
622implicitise syn ignore ist tm
623 = let (declimps, ns') = execState (imps True [] tm) ([], [])
624 ns = filter (\n -> implicitable n || elem n (map fst uvars)) $
625 ns' \\ (map fst pvars ++ no_imp syn ++ ignore) in
627 then (tm, reverse declimps)
628 else implicitise syn ignore ist (pibind uvars ns tm)
631 pvars = syn_params syn
633 dropAll (x:xs) ys | x `elem` ys = dropAll xs ys
634 | otherwise = x : dropAll xs ys
637 imps top env (PApp _ f as)
638 = do (decls, ns) <- get
639 let isn = concatMap (namesIn uvars ist) (map getTm as)
640 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
641 imps top env (PPi (Imp l _) n ty sc)
642 = do let isn = nub (namesIn uvars ist ty) `dropAll` [n]
644 put (PImp (getPriority ist ty) l n ty : decls,
645 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
647 imps top env (PPi (Exp l _) n ty sc)
648 = do let isn = nub (namesIn uvars ist ty ++ case sc of
649 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
651 (decls, ns) <- get -- ignore decls in HO types
652 put (PExp (getPriority ist ty) l ty : decls,
653 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
655 imps top env (PPi (Constraint l _) n ty sc)
656 = do let isn = nub (namesIn uvars ist ty ++ case sc of
657 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
659 (decls, ns) <- get -- ignore decls in HO types
660 put (PConstraint 10 l ty : decls,
661 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
663 imps top env (PPi (TacImp l _ scr) n ty sc)
664 = do let isn = nub (namesIn uvars ist ty ++ case sc of
665 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
667 (decls, ns) <- get -- ignore decls in HO types
668 put (PTacImplicit 10 l n scr ty : decls,
669 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
671 imps top env (PEq _ l r)
672 = do (decls, ns) <- get
673 let isn = namesIn uvars ist l ++ namesIn uvars ist r
674 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
675 imps top env (PTyped l r)
677 imps top env (PPair _ l r)
678 = do (decls, ns) <- get
679 let isn = namesIn uvars ist l ++ namesIn uvars ist r
680 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
681 imps top env (PDPair _ (PRef _ n) t r)
682 = do (decls, ns) <- get
683 let isn = nub (namesIn uvars ist t ++ namesIn uvars ist r) \\ [n]
684 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
685 imps top env (PDPair _ l t r)
686 = do (decls, ns) <- get
687 let isn = namesIn uvars ist l ++ namesIn uvars ist t ++
689 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
690 imps top env (PAlternative a as)
691 = do (decls, ns) <- get
692 let isn = concatMap (namesIn uvars ist) as
693 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
694 imps top env (PLam n ty sc)
695 = do imps False env ty
696 imps False (n:env) sc
697 imps top env (PHidden tm) = imps False env tm
698 imps top env _ = return ()
700 pibind using [] sc = sc
701 pibind using (n:ns) sc
702 = case lookup n using of
703 Just ty -> PPi (Imp False Dynamic) n ty (pibind using ns sc)
704 Nothing -> if (implicitable n)
705 then PPi (Imp False Dynamic) n Placeholder
707 else pibind using ns sc
709-- Add implicit arguments in function calls
710addImplPat :: IState -> PTerm -> PTerm
711addImplPat = addImpl' True []
713addImplBound :: IState -> [Name] -> PTerm -> PTerm
714addImplBound ist ns = addImpl' False ns ist
716addImpl :: IState -> PTerm -> PTerm
717addImpl = addImpl' False []
719-- TODO: in patterns, don't add implicits to function names guarded by constructors
720-- and *not* inside a PHidden
722addImpl' :: Bool -> [Name] -> IState -> PTerm -> PTerm
723addImpl' inpat env ist ptm = ai env ptm
726 | not (f `elem` env) = handleErr $ aiFn inpat inpat ist fc f []
727 ai env (PHidden (PRef fc f))
728 | not (f `elem` env) = handleErr $ aiFn inpat False ist fc f []
729 ai env (PEq fc l r) = let l' = ai env l
732 ai env (PTyped l r) = let l' = ai env l
735 ai env (PPair fc l r) = let l' = ai env l
738 ai env (PDPair fc l t r) = let l' = ai env l
742 ai env (PAlternative a as) = let as' = map (ai env) as in
744 ai env (PApp fc (PRef _ f) as)
746 = let as' = map (fmap (ai env)) as in
747 handleErr $ aiFn inpat False ist fc f as'
748 ai env (PApp fc f as) = let f' = ai env f
749 as' = map (fmap (ai env)) as in
751 ai env (PCase fc c os) = let c' = ai env c
752 os' = map (pmap (ai env)) os in
754 ai env (PLam n ty sc) = let ty' = ai env ty
755 sc' = ai (n:env) sc in
757 ai env (PLet n ty val sc)
758 = let ty' = ai env ty
760 sc' = ai (n:env) sc in
762 ai env (PPi p n ty sc) = let ty' = ai env ty
763 sc' = ai (n:env) sc in
765 ai env (PHidden tm) = PHidden (ai env tm)
766 ai env (PProof ts) = PProof (map (fmap (ai env)) ts)
767 ai env (PTactics ts) = PTactics (map (fmap (ai env)) ts)
770 handleErr (Left err) = PElabError err
771 handleErr (Right x) = x
773-- if in a pattern, and there are no arguments, and there's no possible
774-- names with zero explicit arguments, don't add implicits.
776aiFn :: Bool -> Bool -> IState -> FC -> Name -> [PArg] -> Either Err PTerm
777aiFn inpat True ist fc f []
778 = case lookupDef Nothing f (tt_ctxt ist) of
779 [] -> Right $ PPatvar fc f
780 alts -> let ialts = lookupCtxt Nothing f (idris_implicits ist) in
781 -- trace (show f ++ " " ++ show (fc, any (all imp) ialts, ialts, any constructor alts)) $
782 if (not (vname f) || tcname f
783 || any constructor alts || any allImp ialts)
784 then aiFn inpat False ist fc f [] -- use it as a constructor
785 else Right $ PPatvar fc f
786 where imp (PExp _ _ _) = False
789 allImp xs = all imp xs
790 constructor (TyDecl (DCon _ _) _) = True
791 constructor _ = False
793 vname (UN n) = True -- non qualified
796aiFn inpat expat ist fc f as
797 | f `elem` primNames = Right $ PApp fc (PRef fc f) as
798aiFn inpat expat ist fc f as
799 -- This is where namespaces get resolved by adding PAlternative
800 = case lookupCtxtName Nothing f (idris_implicits ist) of
801 [(f',ns)] -> Right $ mkPApp fc (length ns) (PRef fc f') (insertImpl ns as)
802 [] -> if f `elem` idris_metavars ist
803 then Right $ PApp fc (PRef fc f) as
804 else Right $ mkPApp fc (length as) (PRef fc f) as
807 map (\(f', ns) -> mkPApp fc (length ns) (PRef fc f')
808 (insertImpl ns as)) alts
810 insertImpl :: [PArg] -> [PArg] -> [PArg]
811 insertImpl (PExp p l ty : ps) (PExp _ _ tm : given) =
812 PExp p l tm : insertImpl ps given
813 insertImpl (PConstraint p l ty : ps) (PConstraint _ _ tm : given) =
814 PConstraint p l tm : insertImpl ps given
815 insertImpl (PConstraint p l ty : ps) given =
816 PConstraint p l (PResolveTC fc) : insertImpl ps given
817 insertImpl (PImp p l n ty : ps) given =
818 case find n given [] of
819 Just (tm, given') -> PImp p l n tm : insertImpl ps given'
820 Nothing -> PImp p l n Placeholder : insertImpl ps given
821 insertImpl (PTacImplicit p l n sc ty : ps) given =
822 case find n given [] of
823 Just (tm, given') -> PTacImplicit p l n sc tm : insertImpl ps given'
825 then PTacImplicit p l n sc Placeholder : insertImpl ps given
826 else PTacImplicit p l n sc sc : insertImpl ps given
827 insertImpl expected [] = []
828 insertImpl _ given = given
830 find n [] acc = Nothing
831 find n (PImp _ _ n' t : gs) acc
832 | n == n' = Just (t, reverse acc ++ gs)
833 find n (PTacImplicit _ _ n' _ t : gs) acc
834 | n == n' = Just (t, reverse acc ++ gs)
835 find n (g : gs) acc = find n gs (g : acc)
838mkPApp fc a f as = let rest = drop a as in
839 appRest fc (PApp fc f (take a as)) rest
842 appRest fc f (a : as) = appRest fc (PApp fc f [a]) as
844-- Find 'static' argument positions
845-- (the declared ones, plus any names in argument position in the declared
847-- FIXME: It's possible that this really has to happen after elaboration
849findStatics :: IState -> PTerm -> (PTerm, [Bool])
850findStatics ist tm = trace (showImp True tm) $
851 let (ns, ss) = fs tm in
852 runState (pos ns ss tm) []
853 where fs (PPi p n t sc)
854 | Static <- pstatic p
855 = let (ns, ss) = fs sc in
856 (namesIn [] ist t : ns, n : ss)
857 | otherwise = let (ns, ss) = fs sc in
861 inOne n ns = length (filter id (map (elem n) ns)) == 1
863 pos ns ss (PPi p n t sc)
864 | elem n ss = do sc' <- pos ns ss sc
867 return (PPi (p { pstatic = Static }) n t sc')
868 | otherwise = do sc' <- pos ns ss sc
871 return (PPi p n t sc')
872 pos ns ss t = return t
874-- Debugging/logging stuff
876dumpDecls :: [PDecl] -> String
878dumpDecls (d:ds) = dumpDecl d ++ "\n" ++ dumpDecls ds
880dumpDecl (PFix _ f ops) = show f ++ " " ++ showSep ", " ops
881dumpDecl (PTy _ _ _ n t) = "tydecl " ++ show n ++ " : " ++ showImp True t
882dumpDecl (PClauses _ _ n cs) = "pat " ++ show n ++ "\t" ++ showSep "\n\t" (map (showCImp True) cs)
883dumpDecl (PData _ _ _ d) = showDImp True d
884dumpDecl (PParams _ ns ps) = "params {" ++ show ns ++ "\n" ++ dumpDecls ps ++ "}\n"
885dumpDecl (PNamespace n ps) = "namespace {" ++ n ++ "\n" ++ dumpDecls ps ++ "}\n"
886dumpDecl (PSyntax _ syn) = "syntax " ++ show syn
887dumpDecl (PClass _ _ cs n ps ds)
888 = "class " ++ show cs ++ " " ++ show n ++ " " ++ show ps ++ "\n" ++ dumpDecls ds
889dumpDecl (PInstance _ _ cs n _ t _ ds)
890 = "instance " ++ show cs ++ " " ++ show n ++ " " ++ show t ++ "\n" ++ dumpDecls ds
892-- dumpDecl (PImport i) = "import " ++ i
894-- for 6.12/7 compatibility
895data EitherErr a b = LeftErr a | RightOK b
897instance Monad (EitherErr a) where
900 (LeftErr e) >>= k = LeftErr e
901 RightOK v >>= k = k v
903toEither (LeftErr e) = Left e
904toEither (RightOK ho) = Right ho
906-- syntactic match of a against b, returning pair of variables in a
907-- and what they match. Returns the pair that failed if not a match.
909matchClause :: IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
910matchClause = matchClause' False
912matchClause' :: Bool -> IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
913matchClause' names i x y = checkRpts $ match (fullApp x) (fullApp y) where
914 matchArg x y = match (fullApp (getTm x)) (fullApp (getTm y))
916 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
919 match' x y = match (fullApp x) (fullApp y)
920 match (PApp _ (PRef _ (NS (UN "fromInteger") ["builtins"])) [_,_,x]) x'
921 | PConstant (I _) <- getTm x = match (getTm x) x'
922 match x' (PApp _ (PRef _ (NS (UN "fromInteger") ["builtins"])) [_,_,x])
923 | PConstant (I _) <- getTm x = match (getTm x) x'
924 match (PApp _ (PRef _ (UN "lazy")) [_,x]) x' = match (getTm x) x'
925 match x (PApp _ (PRef _ (UN "lazy")) [_,x']) = match x (getTm x')
926 match (PApp _ f args) (PApp _ f' args')
927 | length args == length args'
928 = do mf <- match' f f'
929 ms <- zipWithM matchArg args args'
930 return (mf ++ concat ms)
931-- match (PRef _ n) (PRef _ n') | n == n' = return []
932-- | otherwise = Nothing
933 match (PRef f n) (PApp _ x []) = match (PRef f n) x
934 match (PApp _ x []) (PRef f n) = match x (PRef f n)
935 match (PRef _ n) (PRef _ n') | n == n' = return []
937 | not names && (not (isConName Nothing n (tt_ctxt i)) || tm == Placeholder)
939 match (PEq _ l r) (PEq _ l' r') = do ml <- match' l l'
942 match (PTyped l r) (PTyped l' r') = do ml <- match l l'
945 match (PTyped l r) x = match l x
946 match x (PTyped l r) = match x l
947 match (PPair _ l r) (PPair _ l' r') = do ml <- match' l l'
950 match (PDPair _ l t r) (PDPair _ l' t' r') = do ml <- match' l l'
953 return (ml ++ mt ++ mr)
954 match (PAlternative a as) (PAlternative a' as')
955 = do ms <- zipWithM match' as as'
957 match a@(PAlternative _ as) b
958 = do let ms = zipWith match' as (repeat b)
959 case (rights (map toEither ms)) of
962 match (PCase _ _ _) _ = return [] -- lifted out
963 match (PMetavar _) _ = return [] -- modified
964 match (PQuote _) _ = return []
965 match (PProof _) _ = return []
966 match (PTactics _) _ = return []
967 match (PRefl _ _) (PRefl _ _) = return []
968 match (PResolveTC _) (PResolveTC _) = return []
969 match (PTrue _) (PTrue _) = return []
970 match (PFalse _) (PFalse _) = return []
971 match (PReturn _) (PReturn _) = return []
972 match (PPi _ _ t s) (PPi _ _ t' s') = do mt <- match' t t'
975 match (PLam _ t s) (PLam _ t' s') = do mt <- match' t t'
978 match (PLet _ t ty s) (PLet _ t' ty' s') = do mt <- match' t t'
981 return (mt ++ mty ++ ms)
982 match (PHidden x) (PHidden y) = match' x y
983 match Placeholder _ = return []
984 match _ Placeholder = return []
985 match (PResolveTC _) _ = return []
986 match a b | a == b = return []
987 | otherwise = LeftErr (a, b)
989 checkRpts (RightOK ms) = check ms where
991 | Just t' <- lookup n xs = if t/=t' && t/=Placeholder && t'/=Placeholder
994 check (_:xs) = check xs
996 checkRpts (LeftErr x) = Left x
998substMatches :: [(Name, PTerm)] -> PTerm -> PTerm
1000substMatches ((n,tm):ns) t = substMatch n tm (substMatches ns t)
1002substMatch :: Name -> PTerm -> PTerm -> PTerm
1003substMatch n tm t = sm t where
1004 sm (PRef _ n') | n == n' = tm
1005 sm (PLam x t sc) = PLam x (sm t) (sm sc)
1006 sm (PPi p x t sc) = PPi p x (sm t) (sm sc)
1007 sm (PApp f x as) = PApp f (sm x) (map (fmap sm) as)
1008 sm (PCase f x as) = PCase f (sm x) (map (pmap sm) as)
1009 sm (PEq f x y) = PEq f (sm x) (sm y)
1010 sm (PTyped x y) = PTyped (sm x) (sm y)
1011 sm (PPair f x y) = PPair f (sm x) (sm y)
1012 sm (PDPair f x t y) = PDPair f (sm x) (sm t) (sm y)
1013 sm (PAlternative a as) = PAlternative a (map sm as)
1014 sm (PHidden x) = PHidden (sm x)
1017shadow :: Name -> Name -> PTerm -> PTerm
1018shadow n n' t = sm t where
1019 sm (PRef fc x) | n == x = PRef fc n'
1020 sm (PLam x t sc) = PLam x (sm t) (sm sc)
1021 sm (PPi p x t sc) = PPi p x (sm t) (sm sc)
1022 sm (PApp f x as) = PApp f (sm x) (map (fmap sm) as)
1023 sm (PCase f x as) = PCase f (sm x) (map (pmap sm) as)
1024 sm (PEq f x y) = PEq f (sm x) (sm y)
1025 sm (PTyped x y) = PTyped (sm x) (sm y)
1026 sm (PPair f x y) = PPair f (sm x) (sm y)
1027 sm (PDPair f x t y) = PDPair f (sm x) (sm t) (sm y)
1028 sm (PAlternative a as) = PAlternative a (map sm as)
1029 sm (PHidden x) = PHidden (sm x)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list