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"
163setContext :: Context -> Idris ()
164setContext ctxt = do i <- get; put (i { tt_ctxt = ctxt } )
166updateContext :: (Context -> Context) -> Idris ()
167updateContext f = do i <- get; put (i { tt_ctxt = f (tt_ctxt i) } )
169addConstraints :: FC -> (Int, [UConstraint]) -> Idris ()
170addConstraints fc (v, cs)
173 let ctxt' = ctxt { uconstraints = cs ++ uconstraints ctxt,
175 let ics = zip cs (repeat fc) ++ idris_constraints i
176 put (i { tt_ctxt = ctxt', idris_constraints = ics })
178addDeferred :: [(Name, Type)] -> Idris ()
179addDeferred ns = do mapM_ (\(n, t) -> updateContext (addTyDecl n (tidyNames [] t))) ns
181 put (i { idris_metavars = map fst ns ++ idris_metavars i })
182 where tidyNames used (Bind (MN i x) b sc)
183 = let n' = uniqueName (UN x) used in
184 Bind n' b $ tidyNames (n':used) sc
185 tidyNames used (Bind n b sc)
186 = let n' = uniqueName n used in
187 Bind n' b $ tidyNames (n':used) sc
190solveDeferred :: Name -> Idris ()
191solveDeferred n = do i <- get
192 put (i { idris_metavars = idris_metavars i \\ [n] })
194iputStrLn :: String -> Idris ()
195iputStrLn = liftIO . putStrLn
197iWarn :: FC -> String -> Idris ()
198iWarn fc err = liftIO $ putStrLn (show fc ++ ":" ++ err)
200setLogLevel :: Int -> Idris ()
201setLogLevel l = do i <- get
202 let opts = idris_options i
203 let opt' = opts { opt_logLevel = l }
204 put (i { idris_options = opt' } )
206setCmdLine :: [Opt] -> Idris ()
207setCmdLine opts = do i <- get
208 let iopts = idris_options i
209 put (i { idris_options = iopts { opt_cmdline = opts } })
211getDumpC :: Idris (Maybe FilePath)
212getDumpC = do i <- get
213 return $ findC (opt_cmdline (idris_options i))
214 where findC [] = Nothing
215 findC (DumpC x : _) = Just x
216 findC (_ : xs) = findC xs
218getDumpDefun :: Idris (Maybe FilePath)
219getDumpDefun = do i <- get
220 return $ findC (opt_cmdline (idris_options i))
221 where findC [] = Nothing
222 findC (DumpDefun x : _) = Just x
223 findC (_ : xs) = findC xs
225getDumpCases :: Idris (Maybe FilePath)
226getDumpCases = do i <- get
227 return $ findC (opt_cmdline (idris_options i))
228 where findC [] = Nothing
229 findC (DumpCases x : _) = Just x
230 findC (_ : xs) = findC xs
233logLevel = do i <- get
234 return (opt_logLevel (idris_options i))
236setErrContext :: Bool -> Idris ()
237setErrContext t = do i <- get
238 let opts = idris_options i
239 let opt' = opts { opt_errContext = t }
240 put (i { idris_options = opt' })
242errContext :: Idris Bool
243errContext = do i <- get
244 return (opt_errContext (idris_options i))
248 return (opt_repl (idris_options i))
250setREPL :: Bool -> Idris ()
251setREPL t = do i <- get
252 let opts = idris_options i
253 let opt' = opts { opt_repl = t }
254 put (i { idris_options = opt' })
258 return (opt_verbose (idris_options i))
260setVerbose :: Bool -> Idris ()
261setVerbose t = do i <- get
262 let opts = idris_options i
263 let opt' = opts { opt_verbose = t }
264 put (i { idris_options = opt' })
266typeInType :: Idris Bool
267typeInType = do i <- get
268 return (opt_typeintype (idris_options i))
270setTypeInType :: Bool -> Idris ()
271setTypeInType t = do i <- get
272 let opts = idris_options i
273 let opt' = opts { opt_typeintype = t }
274 put (i { idris_options = opt' })
276coverage :: Idris Bool
277coverage = do i <- get
278 return (opt_coverage (idris_options i))
280setCoverage :: Bool -> Idris ()
281setCoverage t = do i <- get
282 let opts = idris_options i
283 let opt' = opts { opt_coverage = t }
284 put (i { idris_options = opt' })
286setIBCSubDir :: FilePath -> Idris ()
287setIBCSubDir fp = do i <- get
288 let opts = idris_options i
289 let opt' = opts { opt_ibcsubdir = fp }
290 put (i { idris_options = opt' })
292valIBCSubDir :: IState -> Idris FilePath
293valIBCSubDir i = return (opt_ibcsubdir (idris_options i))
295addImportDir :: FilePath -> Idris ()
296addImportDir fp = do i <- get
297 let opts = idris_options i
298 let opt' = opts { opt_importdirs = fp : opt_importdirs opts }
299 put (i { idris_options = opt' })
301setImportDirs :: [FilePath] -> Idris ()
302setImportDirs fps = do i <- get
303 let opts = idris_options i
304 let opt' = opts { opt_importdirs = fps }
305 put (i { idris_options = opt' })
307allImportDirs :: IState -> Idris [FilePath]
308allImportDirs i = do let optdirs = opt_importdirs (idris_options i)
309 return ("." : optdirs)
313 return (opt_showimp (idris_options i))
315setImpShow :: Bool -> Idris ()
316setImpShow t = do i <- get
317 let opts = idris_options i
318 let opt' = opts { opt_showimp = t }
319 put (i { idris_options = opt' })
321logLvl :: Int -> String -> Idris ()
322logLvl l str = do i <- get
323 let lvl = opt_logLevel (idris_options i)
325 $ do liftIO (putStrLn str)
326 put (i { idris_log = idris_log i ++ str ++ "\n" } )
328cmdOptSet :: Opt -> Idris Bool
329cmdOptSet x = do i <- get
330 return $ x `elem` opt_cmdline (idris_options i)
332iLOG :: String -> Idris ()
335noErrors :: Idris Bool
336noErrors = do i <- get
338 Nothing -> return True
341setTypeCase :: Bool -> Idris ()
342setTypeCase t = do i <- get
343 let opts = idris_options i
344 let opt' = opts { opt_typecase = t }
345 put (i { idris_options = opt' })
348-- For inferring types of things
352inferTy = MN 0 "__Infer"
353inferCon = MN 0 "__infer"
354inferDecl = PDatadecl inferTy
356 [(inferCon, PPi impl (MN 0 "A") PSet (
357 PPi expl (MN 0 "a") (PRef bi (MN 0 "A"))
358 (PRef bi inferTy)), bi)]
360infTerm t = PApp bi (PRef bi inferCon) [pimp (MN 0 "A") Placeholder, pexp t]
361infP = P (TCon 6 0) inferTy (Set (UVal 0))
363getInferTerm, getInferType :: Term -> Term
364getInferTerm (Bind n b sc) = Bind n b $ getInferTerm sc
365getInferTerm (App (App _ _) tm) = tm
366getInferTerm tm = error ("getInferTerm " ++ show tm)
368getInferType (Bind n b sc) = Bind n b $ getInferType sc
369getInferType (App (App _ ty) _) = ty
371-- Handy primitives: Unit, False, Pair, MkPair, =, mkForeign
373primNames = [unitTy, unitCon,
374 falseTy, pairTy, pairCon,
375 eqTy, eqCon, inferTy, inferCon]
377unitTy = MN 0 "__Unit"
379unitDecl = PDatadecl unitTy PSet
380 [(unitCon, PRef bi unitTy, bi)]
382falseTy = MN 0 "__False"
383falseDecl = PDatadecl falseTy PSet []
385pairTy = MN 0 "__Pair"
386pairCon = MN 0 "__MkPair"
387pairDecl = PDatadecl pairTy (piBind [(n "A", PSet), (n "B", PSet)] PSet)
388 [(pairCon, PPi impl (n "A") PSet (
389 PPi impl (n "B") PSet (
390 PPi expl (n "a") (PRef bi (n "A")) (
391 PPi expl (n "b") (PRef bi (n "B"))
392 (PApp bi (PRef bi pairTy) [pexp (PRef bi (n "A")),
393 pexp (PRef bi (n "B"))])))), bi)]
398eqDecl = PDatadecl eqTy (piBind [(n "a", PSet), (n "b", PSet),
399 (n "x", PRef bi (n "a")), (n "y", PRef bi (n "b"))]
401 [(eqCon, PPi impl (n "a") PSet (
402 PPi impl (n "x") (PRef bi (n "a"))
403 (PApp bi (PRef bi eqTy) [pimp (n "a") Placeholder,
404 pimp (n "b") Placeholder,
405 pexp (PRef bi (n "x")),
406 pexp (PRef bi (n "x"))])), bi)]
409-- Defined in builtins.idr
411existsCon = UN "Ex_intro"
413piBind :: [(Name, PTerm)] -> PTerm -> PTerm
416piBindp :: Plicity -> [(Name, PTerm)] -> PTerm -> PTerm
418piBindp p ((n, ty):ns) t = PPi p n ty (piBind ns t)
420-- Dealing with parameters
422expandParams :: (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PTerm -> PTerm
423expandParams dec ps ns tm = en tm
425 -- if we shadow a name (say in a lambda binding) that is used in a call to
426 -- a lifted function, we need access to both names - once in the scope of the
427 -- binding and once to call the lifted functions. So we'll explicitly shadow
428 -- it. (Yes, it's a hack. The alternative would be to resolve names earlier
431 mkShadow (UN n) = MN 0 n
432 mkShadow (MN i n) = MN (i+1) n
433 mkShadow (NS x s) = NS (mkShadow x) s
436 | n `elem` map fst ps
437 = let n' = mkShadow n in
438 PLam n' (en t) (en (shadow n n' s))
439 | otherwise = PLam n (en t) (en s)
441 | n `elem` map fst ps
442 = let n' = mkShadow n in
443 PPi p n' (en t) (en (shadow n n' s))
444 | otherwise = PPi p n (en t) (en s)
446 | n `elem` map fst ps
447 = let n' = mkShadow n in
448 PLet n' (en ty) (en v) (en (shadow n n' s))
449 | otherwise = PLet n (en ty) (en v) (en s)
450 en (PEq f l r) = PEq f (en l) (en r)
451 en (PTyped l r) = PTyped (en l) (en r)
452 en (PPair f l r) = PPair f (en l) (en r)
453 en (PDPair f l t r) = PDPair f (en l) (en t) (en r)
454 en (PAlternative a as) = PAlternative a (map en as)
455 en (PHidden t) = PHidden (en t)
456 en (PDoBlock ds) = PDoBlock (map (fmap en) ds)
457 en (PProof ts) = PProof (map (fmap en) ts)
458 en (PTactics ts) = PTactics (map (fmap en) ts)
461 | n `nselem` ns = PQuote (Var (dec n))
462 en (PApp fc (PRef fc' n) as)
463 | n `nselem` ns = PApp fc (PRef fc' (dec n))
464 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
466 | n `nselem` ns = PApp fc (PRef fc (dec n))
467 (map (pexp . (PRef fc)) (map fst ps))
468 en (PApp fc f as) = PApp fc (en f) (map (fmap en) as)
469 en (PCase fc c os) = PCase fc (en c) (map (pmap en) os)
473 nselem x (y : xs) | nseq x y = True
474 | otherwise = nselem x xs
476 nseq x y = nsroot x == nsroot y
478expandParamsD :: IState ->
479 (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PDecl -> PDecl
480expandParamsD ist dec ps ns (PTy syn fc o n ty)
482 then PTy syn fc o (dec n) (piBind ps (expandParams dec ps ns ty))
483 else PTy syn fc o n (expandParams dec ps ns ty)
484expandParamsD ist dec ps ns (PClauses fc opts n cs)
485 = let n' = if n `elem` ns then dec n else n in
486 PClauses fc opts n' (map expandParamsC cs)
488 expandParamsC (PClause fc n lhs ws rhs ds)
489 = let -- ps' = updateps True (namesIn ist rhs) (zip ps [0..])
490 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
491 n' = if n `elem` ns then dec n else n in
492 PClause fc n' (expandParams dec ps'' ns lhs)
493 (map (expandParams dec ps'' ns) ws)
494 (expandParams dec ps'' ns rhs)
495 (map (expandParamsD ist dec ps'' ns) ds)
496 expandParamsC (PWith fc n lhs ws wval ds)
497 = let -- ps' = updateps True (namesIn ist wval) (zip ps [0..])
498 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
499 n' = if n `elem` ns then dec n else n in
500 PWith fc n' (expandParams dec ps'' ns lhs)
501 (map (expandParams dec ps'' ns) ws)
502 (expandParams dec ps'' ns wval)
503 (map (expandParamsD ist dec ps'' ns) ds)
504 updateps yn nm [] = []
505 updateps yn nm (((a, t), i):as)
506 | (a `elem` nm) == yn = (a, t) : updateps yn nm as
507 | otherwise = (MN i (show n ++ "_u"), t) : updateps yn nm as
508expandParamsD ist dec ps ns (PData syn fc co pd) = PData syn fc co (expandPData pd)
510 -- just do the type decl, leave constructors alone (parameters will be
512 expandPData (PDatadecl n ty cons)
514 then PDatadecl (dec n) (piBind ps (expandParams dec ps ns ty)) (map econ cons)
515 else PDatadecl n (expandParams dec ps ns ty) (map econ cons)
516 econ (n, t, fc) = (dec n, piBindp expl ps (expandParams dec ps ns t), fc)
517expandParamsD ist dec ps ns (PParams f params pds)
518 = PParams f (map (mapsnd (expandParams dec ps ns)) params)
519 (map (expandParamsD ist dec ps ns) pds)
520expandParamsD ist dec ps ns (PClass info f cs n params decls)
522 (map (expandParams dec ps ns) cs)
524 (map (mapsnd (expandParams dec ps ns)) params)
525 (map (expandParamsD ist dec ps ns) decls)
526expandParamsD ist dec ps ns (PInstance info f cs n params ty cn decls)
528 (map (expandParams dec ps ns) cs)
530 (map (expandParams dec ps ns) params)
531 (expandParams dec ps ns ty)
533 (map (expandParamsD ist dec ps ns) decls)
534expandParamsD ist dec ps ns d = d
536mapsnd f (x, t) = (x, f t)
538-- Calculate a priority for a type, for deciding elaboration order
539-- * if it's just a type variable or concrete type, do it early (0)
540-- * if there's only type variables and injective constructors, do it next (1)
541-- * if there's a function type, next (2)
542-- * finally, everything else (3)
544getPriority :: IState -> PTerm -> Int
545getPriority i tm = pri tm
548 case lookupP Nothing n (tt_ctxt i) of
549 ((P (DCon _ _) _ _):_) -> 1
550 ((P (TCon _ _) _ _):_) -> 1
552 [] -> 0 -- must be locally bound, if it's not an error...
553 pri (PPi _ _ x y) = max 5 (max (pri x) (pri y))
557 pri (PEq _ l r) = max 1 (max (pri l) (pri r))
558 pri (PApp _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.getTm) as)))
559 pri (PCase _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.snd) as)))
560 pri (PTyped l r) = pri l
561 pri (PPair _ l r) = max 1 (max (pri l) (pri r))
562 pri (PDPair _ l t r) = max 1 (max (pri l) (max (pri t) (pri r)))
563 pri (PAlternative a as) = maximum (map pri as)
564 pri (PConstant _) = 0
568addStatics :: Name -> Term -> PTerm -> Idris ()
570 do let (statics, dynamics) = initStatics tm ptm
571 let stnames = nub $ concatMap freeNames (map snd statics)
572 let dnames = nub $ concatMap freeNames (map snd dynamics)
573 when (not (null statics)) $
574 logLvl 7 $ show n ++ " " ++ show statics ++ "\n" ++ show dynamics
575 ++ "\n" ++ show stnames ++ "\n" ++ show dnames
576 let statics' = nub $ map fst statics ++
577 filter (\x -> not (elem x dnames)) stnames
578 let stpos = staticList statics' tm
580 put (i { idris_statics = addDef n stpos (idris_statics i) })
583 initStatics (Bind n (Pi ty) sc) (PPi p _ _ s)
584 = let (static, dynamic) = initStatics (instantiate (P Bound n ty) sc) s in
585 if pstatic p == Static then ((n, ty) : static, dynamic)
586 else (static, (n, ty) : dynamic)
587 initStatics t pt = ([], [])
589 staticList sts (Bind n (Pi _) sc) = (n `elem` sts) : staticList sts sc
592-- Dealing with implicit arguments
594-- Add implicit Pi bindings for any names in the term which appear in an
597-- This has become a right mess already. Better redo it some time...
599implicit :: SyntaxInfo -> Name -> PTerm -> Idris PTerm
600implicit syn n ptm = implicit' syn [] n ptm
602implicit' :: SyntaxInfo -> [Name] -> Name -> PTerm -> Idris PTerm
603implicit' syn ignore n ptm
605 let (tm', impdata) = implicitise syn ignore i ptm
606-- let (tm'', spos) = findStatics i tm'
607 put (i { idris_implicits = addDef n impdata (idris_implicits i) })
609 logLvl 5 ("Implicit " ++ show n ++ " " ++ show impdata)
611-- put (i { idris_statics = addDef n spos (idris_statics i) })
614implicitise :: SyntaxInfo -> [Name] -> IState -> PTerm -> (PTerm, [PArg])
615implicitise syn ignore ist tm
616 = let (declimps, ns') = execState (imps True [] tm) ([], [])
617 ns = ns' \\ (map fst pvars ++ no_imp syn ++ ignore) in
619 then (tm, reverse declimps)
620 else implicitise syn ignore ist (pibind uvars ns tm)
623 pvars = syn_params syn
625 dropAll (x:xs) ys | x `elem` ys = dropAll xs ys
626 | otherwise = x : dropAll xs ys
629 imps top env (PApp _ f as)
630 = do (decls, ns) <- get
631 let isn = concatMap (namesIn uvars ist) (map getTm as)
632 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
633 imps top env (PPi (Imp l _) n ty sc)
634 = do let isn = nub (namesIn uvars ist ty) `dropAll` [n]
636 put (PImp (getPriority ist ty) l n ty : decls,
637 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
639 imps top env (PPi (Exp l _) n ty sc)
640 = do let isn = nub (namesIn uvars ist ty ++ case sc of
641 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
643 (decls, ns) <- get -- ignore decls in HO types
644 put (PExp (getPriority ist ty) l ty : decls,
645 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
647 imps top env (PPi (Constraint 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 (PConstraint 10 l ty : decls,
653 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
655 imps top env (PPi (TacImp l _ scr) 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 (PTacImplicit 10 l n scr ty : decls,
661 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
663 imps top env (PEq _ l r)
664 = do (decls, ns) <- get
665 let isn = namesIn uvars ist l ++ namesIn uvars ist r
666 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
667 imps top env (PTyped l r)
669 imps top env (PPair _ l r)
670 = do (decls, ns) <- get
671 let isn = namesIn uvars ist l ++ namesIn uvars ist r
672 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
673 imps top env (PDPair _ (PRef _ n) t r)
674 = do (decls, ns) <- get
675 let isn = nub (namesIn uvars ist t ++ namesIn uvars ist r) \\ [n]
676 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
677 imps top env (PDPair _ l t r)
678 = do (decls, ns) <- get
679 let isn = namesIn uvars ist l ++ namesIn uvars ist t ++
681 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
682 imps top env (PAlternative a as)
683 = do (decls, ns) <- get
684 let isn = concatMap (namesIn uvars ist) as
685 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
686 imps top env (PLam n ty sc)
687 = do imps False env ty
688 imps False (n:env) sc
689 imps top env (PHidden tm) = imps False env tm
690 imps top env _ = return ()
692 pibind using [] sc = sc
693 pibind using (n:ns) sc
694 = case lookup n using of
695 Just ty -> PPi (Imp False Dynamic) n ty (pibind using ns sc)
696 Nothing -> PPi (Imp False Dynamic) n Placeholder (pibind using ns sc)
698-- Add implicit arguments in function calls
699addImplPat :: IState -> PTerm -> PTerm
700addImplPat = addImpl' True []
702addImplBound :: IState -> [Name] -> PTerm -> PTerm
703addImplBound ist ns = addImpl' False ns ist
705addImpl :: IState -> PTerm -> PTerm
706addImpl = addImpl' False []
708-- TODO: in patterns, don't add implicits to function names guarded by constructors
709-- and *not* inside a PHidden
711addImpl' :: Bool -> [Name] -> IState -> PTerm -> PTerm
712addImpl' inpat env ist ptm = ai env ptm
715 | not (f `elem` env) = handleErr $ aiFn inpat inpat ist fc f []
716 ai env (PHidden (PRef fc f))
717 | not (f `elem` env) = handleErr $ aiFn inpat False ist fc f []
718 ai env (PEq fc l r) = let l' = ai env l
721 ai env (PTyped l r) = let l' = ai env l
724 ai env (PPair fc l r) = let l' = ai env l
727 ai env (PDPair fc l t r) = let l' = ai env l
731 ai env (PAlternative a as) = let as' = map (ai env) as in
733 ai env (PApp fc (PRef _ f) as)
735 = let as' = map (fmap (ai env)) as in
736 handleErr $ aiFn inpat False ist fc f as'
737 ai env (PApp fc f as) = let f' = ai env f
738 as' = map (fmap (ai env)) as in
740 ai env (PCase fc c os) = let c' = ai env c
741 os' = map (pmap (ai env)) os in
743 ai env (PLam n ty sc) = let ty' = ai env ty
744 sc' = ai (n:env) sc in
746 ai env (PLet n ty val sc)
747 = let ty' = ai env ty
749 sc' = ai (n:env) sc in
751 ai env (PPi p n ty sc) = let ty' = ai env ty
752 sc' = ai (n:env) sc in
754 ai env (PHidden tm) = PHidden (ai env tm)
755 ai env (PProof ts) = PProof (map (fmap (ai env)) ts)
756 ai env (PTactics ts) = PTactics (map (fmap (ai env)) ts)
759 handleErr (Left err) = PElabError err
760 handleErr (Right x) = x
762-- if in a pattern, and there are no arguments, and there's no possible
763-- names with zero explicit arguments, don't add implicits.
765aiFn :: Bool -> Bool -> IState -> FC -> Name -> [PArg] -> Either Err PTerm
766aiFn inpat True ist fc f []
767 = case lookupDef Nothing f (tt_ctxt ist) of
768 [] -> Right $ PPatvar fc f
769 alts -> let ialts = lookupCtxt Nothing f (idris_implicits ist) in
770 -- trace (show f ++ " " ++ show (fc, any (all imp) ialts, ialts, any constructor alts)) $
771 if (not (vname f) || tcname f
772 || any constructor alts || any allImp ialts)
773 then aiFn inpat False ist fc f [] -- use it as a constructor
774 else Right $ PPatvar fc f
775 where imp (PExp _ _ _) = False
778 allImp xs = all imp xs
779 constructor (TyDecl (DCon _ _) _) = True
780 constructor _ = False
782 vname (UN n) = True -- non qualified
785aiFn inpat expat ist fc f as
786 | f `elem` primNames = Right $ PApp fc (PRef fc f) as
787aiFn inpat expat ist fc f as
788 -- This is where namespaces get resolved by adding PAlternative
789 = case lookupCtxtName Nothing f (idris_implicits ist) of
790 [(f',ns)] -> Right $ mkPApp fc (length ns) (PRef fc f') (insertImpl ns as)
791 [] -> if f `elem` idris_metavars ist
792 then Right $ PApp fc (PRef fc f) as
793 else Right $ mkPApp fc (length as) (PRef fc f) as
796 map (\(f', ns) -> mkPApp fc (length ns) (PRef fc f')
797 (insertImpl ns as)) alts
799 insertImpl :: [PArg] -> [PArg] -> [PArg]
800 insertImpl (PExp p l ty : ps) (PExp _ _ tm : given) =
801 PExp p l tm : insertImpl ps given
802 insertImpl (PConstraint p l ty : ps) (PConstraint _ _ tm : given) =
803 PConstraint p l tm : insertImpl ps given
804 insertImpl (PConstraint p l ty : ps) given =
805 PConstraint p l (PResolveTC fc) : insertImpl ps given
806 insertImpl (PImp p l n ty : ps) given =
807 case find n given [] of
808 Just (tm, given') -> PImp p l n tm : insertImpl ps given'
809 Nothing -> PImp p l n Placeholder : insertImpl ps given
810 insertImpl (PTacImplicit p l n sc ty : ps) given =
811 case find n given [] of
812 Just (tm, given') -> PTacImplicit p l n sc tm : insertImpl ps given'
814 then PTacImplicit p l n sc Placeholder : insertImpl ps given
815 else PTacImplicit p l n sc sc : insertImpl ps given
816 insertImpl expected [] = []
817 insertImpl _ given = given
819 find n [] acc = Nothing
820 find n (PImp _ _ n' t : gs) acc
821 | n == n' = Just (t, reverse acc ++ gs)
822 find n (PTacImplicit _ _ n' _ t : gs) acc
823 | n == n' = Just (t, reverse acc ++ gs)
824 find n (g : gs) acc = find n gs (g : acc)
827mkPApp fc a f as = let rest = drop a as in
828 appRest fc (PApp fc f (take a as)) rest
831 appRest fc f (a : as) = appRest fc (PApp fc f [a]) as
833-- Find 'static' argument positions
834-- (the declared ones, plus any names in argument position in the declared
836-- FIXME: It's possible that this really has to happen after elaboration
838findStatics :: IState -> PTerm -> (PTerm, [Bool])
839findStatics ist tm = trace (showImp True tm) $
840 let (ns, ss) = fs tm in
841 runState (pos ns ss tm) []
842 where fs (PPi p n t sc)
843 | Static <- pstatic p
844 = let (ns, ss) = fs sc in
845 (namesIn [] ist t : ns, n : ss)
846 | otherwise = let (ns, ss) = fs sc in
850 inOne n ns = length (filter id (map (elem n) ns)) == 1
852 pos ns ss (PPi p n t sc)
853 | elem n ss = do sc' <- pos ns ss sc
856 return (PPi (p { pstatic = Static }) n t sc')
857 | otherwise = do sc' <- pos ns ss sc
860 return (PPi p n t sc')
861 pos ns ss t = return t
863-- Debugging/logging stuff
865dumpDecls :: [PDecl] -> String
867dumpDecls (d:ds) = dumpDecl d ++ "\n" ++ dumpDecls ds
869dumpDecl (PFix _ f ops) = show f ++ " " ++ showSep ", " ops
870dumpDecl (PTy _ _ _ n t) = "tydecl " ++ show n ++ " : " ++ showImp True t
871dumpDecl (PClauses _ _ n cs) = "pat " ++ show n ++ "\t" ++ showSep "\n\t" (map (showCImp True) cs)
872dumpDecl (PData _ _ _ d) = showDImp True d
873dumpDecl (PParams _ ns ps) = "params {" ++ show ns ++ "\n" ++ dumpDecls ps ++ "}\n"
874dumpDecl (PNamespace n ps) = "namespace {" ++ n ++ "\n" ++ dumpDecls ps ++ "}\n"
875dumpDecl (PSyntax _ syn) = "syntax " ++ show syn
876dumpDecl (PClass _ _ cs n ps ds)
877 = "class " ++ show cs ++ " " ++ show n ++ " " ++ show ps ++ "\n" ++ dumpDecls ds
878dumpDecl (PInstance _ _ cs n _ t _ ds)
879 = "instance " ++ show cs ++ " " ++ show n ++ " " ++ show t ++ "\n" ++ dumpDecls ds
881-- dumpDecl (PImport i) = "import " ++ i
883-- for 6.12/7 compatibility
884data EitherErr a b = LeftErr a | RightOK b
886instance Monad (EitherErr a) where
889 (LeftErr e) >>= k = LeftErr e
890 RightOK v >>= k = k v
892toEither (LeftErr e) = Left e
893toEither (RightOK ho) = Right ho
895-- syntactic match of a against b, returning pair of variables in a
896-- and what they match. Returns the pair that failed if not a match.
898matchClause :: IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
899matchClause = matchClause' False
901matchClause' :: Bool -> IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
902matchClause' names i x y = checkRpts $ match (fullApp x) (fullApp y) where
903 matchArg x y = match (fullApp (getTm x)) (fullApp (getTm y))
905 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
908 match' x y = match (fullApp x) (fullApp y)
909 match (PApp _ (PRef _ (NS (UN "fromInteger") ["builtins"])) [_,_,x]) x'
910 | PConstant (I _) <- getTm x = match (getTm x) x'
911 match x' (PApp _ (PRef _ (NS (UN "fromInteger") ["builtins"])) [_,_,x])
912 | PConstant (I _) <- getTm x = match (getTm x) x'
913 match (PApp _ (PRef _ (UN "lazy")) [_,x]) x' = match (getTm x) x'
914 match x (PApp _ (PRef _ (UN "lazy")) [_,x']) = match x (getTm x')
915 match (PApp _ f args) (PApp _ f' args')
916 | length args == length args'
917 = do mf <- match' f f'
918 ms <- zipWithM matchArg args args'
919 return (mf ++ concat ms)
920-- match (PRef _ n) (PRef _ n') | n == n' = return []
921-- | otherwise = Nothing
922 match (PRef f n) (PApp _ x []) = match (PRef f n) x
923 match (PApp _ x []) (PRef f n) = match x (PRef f n)
924 match (PRef _ n) (PRef _ n') | n == n' = return []
926 | not names && (not (isConName Nothing n (tt_ctxt i)) || tm == Placeholder)
928 match (PEq _ l r) (PEq _ l' r') = do ml <- match' l l'
931 match (PTyped l r) (PTyped l' r') = do ml <- match l l'
934 match (PTyped l r) x = match l x
935 match x (PTyped l r) = match x l
936 match (PPair _ l r) (PPair _ l' r') = do ml <- match' l l'
939 match (PDPair _ l t r) (PDPair _ l' t' r') = do ml <- match' l l'
942 return (ml ++ mt ++ mr)
943 match (PAlternative a as) (PAlternative a' as')
944 = do ms <- zipWithM match' as as'
946 match a@(PAlternative _ as) b
947 = do let ms = zipWith match' as (repeat b)
948 case (rights (map toEither ms)) of
951 match (PCase _ _ _) _ = return [] -- lifted out
952 match (PMetavar _) _ = return [] -- modified
953 match (PQuote _) _ = return []
954 match (PProof _) _ = return []
955 match (PTactics _) _ = return []
956 match (PRefl _ _) (PRefl _ _) = return []
957 match (PResolveTC _) (PResolveTC _) = return []
958 match (PTrue _) (PTrue _) = return []
959 match (PFalse _) (PFalse _) = return []
960 match (PReturn _) (PReturn _) = return []
961 match (PPi _ _ t s) (PPi _ _ t' s') = do mt <- match' t t'
964 match (PLam _ t s) (PLam _ t' s') = do mt <- match' t t'
967 match (PLet _ t ty s) (PLet _ t' ty' s') = do mt <- match' t t'
970 return (mt ++ mty ++ ms)
971 match (PHidden x) (PHidden y) = match' x y
972 match Placeholder _ = return []
973 match _ Placeholder = return []
974 match (PResolveTC _) _ = return []
975 match a b | a == b = return []
976 | otherwise = LeftErr (a, b)
978 checkRpts (RightOK ms) = check ms where
980 | Just t' <- lookup n xs = if t/=t' && t/=Placeholder && t'/=Placeholder
983 check (_:xs) = check xs
985 checkRpts (LeftErr x) = Left x
987substMatches :: [(Name, PTerm)] -> PTerm -> PTerm
989substMatches ((n,tm):ns) t = substMatch n tm (substMatches ns t)
991substMatch :: Name -> PTerm -> PTerm -> PTerm
992substMatch n tm t = sm t where
993 sm (PRef _ n') | n == n' = tm
994 sm (PLam x t sc) = PLam x (sm t) (sm sc)
995 sm (PPi p x t sc) = PPi p x (sm t) (sm sc)
996 sm (PApp f x as) = PApp f (sm x) (map (fmap sm) as)
997 sm (PCase f x as) = PCase f (sm x) (map (pmap sm) as)
998 sm (PEq f x y) = PEq f (sm x) (sm y)
999 sm (PTyped x y) = PTyped (sm x) (sm y)
1000 sm (PPair f x y) = PPair f (sm x) (sm y)
1001 sm (PDPair f x t y) = PDPair f (sm x) (sm t) (sm y)
1002 sm (PAlternative a as) = PAlternative a (map sm as)
1003 sm (PHidden x) = PHidden (sm x)
1006shadow :: Name -> Name -> PTerm -> PTerm
1007shadow n n' t = sm t where
1008 sm (PRef fc x) | n == x = PRef fc n'
1009 sm (PLam x t sc) = PLam x (sm t) (sm sc)
1010 sm (PPi p x t sc) = PPi p x (sm t) (sm sc)
1011 sm (PApp f x as) = PApp f (sm x) (map (fmap sm) as)
1012 sm (PCase f x as) = PCase f (sm x) (map (pmap sm) as)
1013 sm (PEq f x y) = PEq f (sm x) (sm y)
1014 sm (PTyped x y) = PTyped (sm x) (sm y)
1015 sm (PPair f x y) = PPair f (sm x) (sm y)
1016 sm (PDPair f x t y) = PDPair f (sm x) (sm t) (sm y)
1017 sm (PAlternative a as) = PAlternative a (map sm as)
1018 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