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 = n : idris_totcheck i })
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.
80addInstance :: Bool -> Name -> Name -> Idris ()
83 case lookupCtxt Nothing n (idris_classes ist) of
85 do let cs = addDef n (CI a b c d (addI i ins)) (idris_classes ist)
86 put (ist { idris_classes = cs })
87 _ -> do let cs = addDef n (CI (MN 0 "none") [] [] [] [i]) (idris_classes ist)
88 put (ist { idris_classes = cs })
89 where addI i ins | int = i : ins
90 | otherwise = ins ++ [i]
92addClass :: Name -> ClassInfo -> Idris ()
95 let i' = case lookupCtxt Nothing n (idris_classes ist) of
96 [c] -> c { class_instances = class_instances i }
98 put (ist { idris_classes = addDef n i' (idris_classes ist) })
100addIBC :: IBCWrite -> Idris ()
103 when (notDef (ibc_write i)) $
104 put (i { ibc_write = ibc : ibc_write i })
105 where notDef [] = True
106 notDef (IBCDef n': is) | n == n' = False
107 notDef (_ : is) = notDef is
108addIBC ibc = do i <- get; put (i { ibc_write = ibc : ibc_write i })
111clearIBC = do i <- get; put (i { ibc_write = [] })
113getHdrs :: Idris [String]
114getHdrs = do i <- get; return (idris_hdrs i)
116setErrLine :: Int -> Idris ()
117setErrLine x = do i <- get;
119 Nothing -> put (i { errLine = Just x })
123clearErr = do i <- get
124 put (i { errLine = Nothing })
126getSO :: Idris (Maybe String)
128 return (compiled_so i)
130setSO :: Maybe String -> Idris ()
132 put (i { compiled_so = s })
134getIState :: Idris IState
137putIState :: IState -> Idris ()
141getName = do i <- get;
142 let idx = idris_name i;
143 put (i { idris_name = idx + 1 })
146checkUndefined :: FC -> Name -> Idris ()
149 case lookupTy Nothing n i of
150 (_:_) -> fail $ show fc ++ ":" ++
151 show n ++ " already defined"
154setContext :: Context -> Idris ()
155setContext ctxt = do i <- get; put (i { tt_ctxt = ctxt } )
157updateContext :: (Context -> Context) -> Idris ()
158updateContext f = do i <- get; put (i { tt_ctxt = f (tt_ctxt i) } )
160addConstraints :: FC -> (Int, [UConstraint]) -> Idris ()
161addConstraints fc (v, cs)
164 let ctxt' = ctxt { uconstraints = cs ++ uconstraints ctxt,
166 let ics = zip cs (repeat fc) ++ idris_constraints i
167 put (i { tt_ctxt = ctxt', idris_constraints = ics })
169addDeferred :: [(Name, Type)] -> Idris ()
170addDeferred ns = do mapM_ (\(n, t) -> updateContext (addTyDecl n (tidyNames [] t))) ns
172 put (i { idris_metavars = map fst ns ++ idris_metavars i })
173 where tidyNames used (Bind (MN i x) b sc)
174 = let n' = uniqueName (UN x) used in
175 Bind n' b $ tidyNames (n':used) sc
176 tidyNames used (Bind n b sc)
177 = let n' = uniqueName n used in
178 Bind n' b $ tidyNames (n':used) sc
181solveDeferred :: Name -> Idris ()
182solveDeferred n = do i <- get
183 put (i { idris_metavars = idris_metavars i \\ [n] })
185iputStrLn :: String -> Idris ()
186iputStrLn = liftIO . putStrLn
188iWarn :: FC -> String -> Idris ()
189iWarn fc err = liftIO $ putStrLn (show fc ++ ":" ++ err)
191setLogLevel :: Int -> Idris ()
192setLogLevel l = do i <- get
193 let opts = idris_options i
194 let opt' = opts { opt_logLevel = l }
195 put (i { idris_options = opt' } )
197setCmdLine :: [Opt] -> Idris ()
198setCmdLine opts = do i <- get
199 let iopts = idris_options i
200 put (i { idris_options = iopts { opt_cmdline = opts } })
202getDumpC :: Idris (Maybe FilePath)
203getDumpC = do i <- get
204 return $ findC (opt_cmdline (idris_options i))
205 where findC [] = Nothing
206 findC (DumpC x : _) = Just x
207 findC (_ : xs) = findC xs
209getDumpDefun :: Idris (Maybe FilePath)
210getDumpDefun = do i <- get
211 return $ findC (opt_cmdline (idris_options i))
212 where findC [] = Nothing
213 findC (DumpDefun x : _) = Just x
214 findC (_ : xs) = findC xs
216getDumpCases :: Idris (Maybe FilePath)
217getDumpCases = do i <- get
218 return $ findC (opt_cmdline (idris_options i))
219 where findC [] = Nothing
220 findC (DumpCases x : _) = Just x
221 findC (_ : xs) = findC xs
224logLevel = do i <- get
225 return (opt_logLevel (idris_options i))
227setErrContext :: Bool -> Idris ()
228setErrContext t = do i <- get
229 let opts = idris_options i
230 let opt' = opts { opt_errContext = t }
231 put (i { idris_options = opt' })
233errContext :: Idris Bool
234errContext = do i <- get
235 return (opt_errContext (idris_options i))
239 return (opt_repl (idris_options i))
241setREPL :: Bool -> Idris ()
242setREPL t = do i <- get
243 let opts = idris_options i
244 let opt' = opts { opt_repl = t }
245 put (i { idris_options = opt' })
249 return (opt_verbose (idris_options i))
251setVerbose :: Bool -> Idris ()
252setVerbose t = do i <- get
253 let opts = idris_options i
254 let opt' = opts { opt_verbose = t }
255 put (i { idris_options = opt' })
257typeInType :: Idris Bool
258typeInType = do i <- get
259 return (opt_typeintype (idris_options i))
261setTypeInType :: Bool -> Idris ()
262setTypeInType t = do i <- get
263 let opts = idris_options i
264 let opt' = opts { opt_typeintype = t }
265 put (i { idris_options = opt' })
267coverage :: Idris Bool
268coverage = do i <- get
269 return (opt_coverage (idris_options i))
271setCoverage :: Bool -> Idris ()
272setCoverage t = do i <- get
273 let opts = idris_options i
274 let opt' = opts { opt_coverage = t }
275 put (i { idris_options = opt' })
277setIBCSubDir :: FilePath -> Idris ()
278setIBCSubDir fp = do i <- get
279 let opts = idris_options i
280 let opt' = opts { opt_ibcsubdir = fp }
281 put (i { idris_options = opt' })
283valIBCSubDir :: IState -> Idris FilePath
284valIBCSubDir i = return (opt_ibcsubdir (idris_options i))
286addImportDir :: FilePath -> Idris ()
287addImportDir fp = do i <- get
288 let opts = idris_options i
289 let opt' = opts { opt_importdirs = fp : opt_importdirs opts }
290 put (i { idris_options = opt' })
292setImportDirs :: [FilePath] -> Idris ()
293setImportDirs fps = do i <- get
294 let opts = idris_options i
295 let opt' = opts { opt_importdirs = fps }
296 put (i { idris_options = opt' })
298allImportDirs :: IState -> Idris [FilePath]
299allImportDirs i = do let optdirs = opt_importdirs (idris_options i)
300 return ("." : optdirs)
304 return (opt_showimp (idris_options i))
306setImpShow :: Bool -> Idris ()
307setImpShow t = do i <- get
308 let opts = idris_options i
309 let opt' = opts { opt_showimp = t }
310 put (i { idris_options = opt' })
312logLvl :: Int -> String -> Idris ()
313logLvl l str = do i <- get
314 let lvl = opt_logLevel (idris_options i)
316 $ do liftIO (putStrLn str)
317 put (i { idris_log = idris_log i ++ str ++ "\n" } )
319iLOG :: String -> Idris ()
322noErrors :: Idris Bool
323noErrors = do i <- get
325 Nothing -> return True
328setTypeCase :: Bool -> Idris ()
329setTypeCase t = do i <- get
330 let opts = idris_options i
331 let opt' = opts { opt_typecase = t }
332 put (i { idris_options = opt' })
335-- For inferring types of things
339inferTy = MN 0 "__Infer"
340inferCon = MN 0 "__infer"
341inferDecl = PDatadecl inferTy
343 [(inferCon, PPi impl (MN 0 "A") PSet (
344 PPi expl (MN 0 "a") (PRef bi (MN 0 "A"))
345 (PRef bi inferTy)), bi)]
347infTerm t = PApp bi (PRef bi inferCon) [pimp (MN 0 "A") Placeholder, pexp t]
348infP = P (TCon 6 0) inferTy (Set (UVal 0))
350getInferTerm, getInferType :: Term -> Term
351getInferTerm (Bind n b sc) = Bind n b $ getInferTerm sc
352getInferTerm (App (App _ _) tm) = tm
353getInferTerm tm = error ("getInferTerm " ++ show tm)
355getInferType (Bind n b sc) = Bind n b $ getInferType sc
356getInferType (App (App _ ty) _) = ty
358-- Handy primitives: Unit, False, Pair, MkPair, =, mkForeign
360primNames = [unitTy, unitCon,
361 falseTy, pairTy, pairCon,
362 eqTy, eqCon, inferTy, inferCon]
364unitTy = MN 0 "__Unit"
366unitDecl = PDatadecl unitTy PSet
367 [(unitCon, PRef bi unitTy, bi)]
369falseTy = MN 0 "__False"
370falseDecl = PDatadecl falseTy PSet []
372pairTy = MN 0 "__Pair"
373pairCon = MN 0 "__MkPair"
374pairDecl = PDatadecl pairTy (piBind [(n "A", PSet), (n "B", PSet)] PSet)
375 [(pairCon, PPi impl (n "A") PSet (
376 PPi impl (n "B") PSet (
377 PPi expl (n "a") (PRef bi (n "A")) (
378 PPi expl (n "b") (PRef bi (n "B"))
379 (PApp bi (PRef bi pairTy) [pexp (PRef bi (n "A")),
380 pexp (PRef bi (n "B"))])))), bi)]
385eqDecl = PDatadecl eqTy (piBind [(n "a", PSet), (n "b", PSet),
386 (n "x", PRef bi (n "a")), (n "y", PRef bi (n "b"))]
388 [(eqCon, PPi impl (n "a") PSet (
389 PPi impl (n "x") (PRef bi (n "a"))
390 (PApp bi (PRef bi eqTy) [pimp (n "a") Placeholder,
391 pimp (n "b") Placeholder,
392 pexp (PRef bi (n "x")),
393 pexp (PRef bi (n "x"))])), bi)]
396-- Defined in builtins.idr
398existsCon = UN "Ex_intro"
400piBind :: [(Name, PTerm)] -> PTerm -> PTerm
402piBind ((n, ty):ns) t = PPi expl n ty (piBind ns t)
404tcname (UN ('@':_)) = True
405tcname (NS n _) = tcname n
408-- Dealing with parameters
410expandParams :: (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PTerm -> PTerm
411expandParams dec ps ns tm = en tm
413 -- if we shadow a name (say in a lambda binding) that is used in a call to
414 -- a lifted function, we need access to both names - once in the scope of the
415 -- binding and once to call the lifted functions. So we'll explicitly shadow
416 -- it. (Yes, it's a hack. The alternative would be to resolve names earlier
419 mkShadow (UN n) = MN 0 n
420 mkShadow (MN i n) = MN (i+1) n
421 mkShadow (NS x s) = NS (mkShadow x) s
424 | n `elem` map fst ps
425 = let n' = mkShadow n in
426 PLam n' (en t) (en (shadow n n' s))
427 | otherwise = PLam n (en t) (en s)
429 | n `elem` map fst ps
430 = let n' = mkShadow n in
431 PPi p n' (en t) (en (shadow n n' s))
432 | otherwise = PPi p n (en t) (en s)
434 | n `elem` map fst ps
435 = let n' = mkShadow n in
436 PLet n' (en ty) (en v) (en (shadow n n' s))
437 | otherwise = PLet n (en ty) (en v) (en s)
438 en (PEq f l r) = PEq f (en l) (en r)
439 en (PTyped l r) = PTyped (en l) (en r)
440 en (PPair f l r) = PPair f (en l) (en r)
441 en (PDPair f l t r) = PDPair f (en l) (en t) (en r)
442 en (PAlternative a as) = PAlternative a (map en as)
443 en (PHidden t) = PHidden (en t)
444 en (PDoBlock ds) = PDoBlock (map (fmap en) ds)
445 en (PProof ts) = PProof (map (fmap en) ts)
446 en (PTactics ts) = PTactics (map (fmap en) ts)
449 | n `elem` ns = PQuote (Var (dec n))
450 en (PApp fc (PRef fc' n) as)
451 | n `elem` ns = PApp fc (PRef fc' (dec n))
452 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
454 | n `elem` ns = PApp fc (PRef fc (dec n))
455 (map (pexp . (PRef fc)) (map fst ps))
456 en (PApp fc f as) = PApp fc (en f) (map (fmap en) as)
457 en (PCase fc c os) = PCase fc (en c) (map (pmap en) os)
460expandParamsD :: IState ->
461 (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PDecl -> PDecl
462expandParamsD ist dec ps ns (PTy syn fc o n ty)
464 then PTy syn fc o (dec n) (piBind ps (expandParams dec ps ns ty))
465 else PTy syn fc o n (expandParams dec ps ns ty)
466expandParamsD ist dec ps ns (PClauses fc opts n cs)
467 = let n' = if n `elem` ns then dec n else n in
468 PClauses fc opts n' (map expandParamsC cs)
470 expandParamsC (PClause fc n lhs ws rhs ds)
471 = let -- ps' = updateps True (namesIn ist rhs) (zip ps [0..])
472 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
473 n' = if n `elem` ns then dec n else n in
474 PClause fc n' (expandParams dec ps'' ns lhs)
475 (map (expandParams dec ps'' ns) ws)
476 (expandParams dec ps'' ns rhs)
477 (map (expandParamsD ist dec ps'' ns) ds)
478 expandParamsC (PWith fc n lhs ws wval ds)
479 = let -- ps' = updateps True (namesIn ist wval) (zip ps [0..])
480 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
481 n' = if n `elem` ns then dec n else n in
482 PWith fc n' (expandParams dec ps'' ns lhs)
483 (map (expandParams dec ps'' ns) ws)
484 (expandParams dec ps'' ns wval)
485 (map (expandParamsD ist dec ps'' ns) ds)
486 updateps yn nm [] = []
487 updateps yn nm (((a, t), i):as)
488 | (a `elem` nm) == yn = (a, t) : updateps yn nm as
489 | otherwise = (MN i (show n ++ "_u"), t) : updateps yn nm as
491expandParamsD ist dec ps ns d = d
493-- Calculate a priority for a type, for deciding elaboration order
494-- * if it's just a type variable or concrete type, do it early (0)
495-- * if there's only type variables and injective constructors, do it next (1)
496-- * if there's a function type, next (2)
497-- * finally, everything else (3)
499getPriority :: IState -> PTerm -> Int
500getPriority i tm = pri tm
503 case lookupP Nothing n (tt_ctxt i) of
504 ((P (DCon _ _) _ _):_) -> 1
505 ((P (TCon _ _) _ _):_) -> 1
507 [] -> 0 -- must be locally bound, if it's not an error...
508 pri (PPi _ _ x y) = max 5 (max (pri x) (pri y))
512 pri (PEq _ l r) = max 1 (max (pri l) (pri r))
513 pri (PApp _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.getTm) as)))
514 pri (PCase _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.snd) as)))
515 pri (PTyped l r) = pri l
516 pri (PPair _ l r) = max 1 (max (pri l) (pri r))
517 pri (PDPair _ l t r) = max 1 (max (pri l) (max (pri t) (pri r)))
518 pri (PAlternative a as) = maximum (map pri as)
519 pri (PConstant _) = 0
523addStatics :: Name -> Term -> PTerm -> Idris ()
525 do let (statics, dynamics) = initStatics tm ptm
526 let stnames = nub $ concatMap freeNames (map snd statics)
527 let dnames = nub $ concatMap freeNames (map snd dynamics)
528 when (not (null statics)) $
529 logLvl 7 $ show n ++ " " ++ show statics ++ "\n" ++ show dynamics
530 ++ "\n" ++ show stnames ++ "\n" ++ show dnames
531 let statics' = nub $ map fst statics ++
532 filter (\x -> not (elem x dnames)) stnames
533 let stpos = staticList statics' tm
535 put (i { idris_statics = addDef n stpos (idris_statics i) })
538 initStatics (Bind n (Pi ty) sc) (PPi p _ _ s)
539 = let (static, dynamic) = initStatics (instantiate (P Bound n ty) sc) s in
540 if pstatic p == Static then ((n, ty) : static, dynamic)
541 else (static, (n, ty) : dynamic)
542 initStatics t pt = ([], [])
544 staticList sts (Bind n (Pi _) sc) = (n `elem` sts) : staticList sts sc
547-- Dealing with implicit arguments
549-- Add implicit Pi bindings for any names in the term which appear in an
552-- This has become a right mess already. Better redo it some time...
554implicit :: SyntaxInfo -> Name -> PTerm -> Idris PTerm
555implicit syn n ptm = implicit' syn [] n ptm
557implicit' :: SyntaxInfo -> [Name] -> Name -> PTerm -> Idris PTerm
558implicit' syn ignore n ptm
560 let (tm', impdata) = implicitise syn ignore i ptm
561-- let (tm'', spos) = findStatics i tm'
562 put (i { idris_implicits = addDef n impdata (idris_implicits i) })
564 logLvl 5 ("Implicit " ++ show n ++ " " ++ show impdata)
566-- put (i { idris_statics = addDef n spos (idris_statics i) })
569implicitise :: SyntaxInfo -> [Name] -> IState -> PTerm -> (PTerm, [PArg])
570implicitise syn ignore ist tm
571 = let (declimps, ns') = execState (imps True [] tm) ([], [])
572 ns = ns' \\ (map fst pvars ++ no_imp syn ++ ignore) in
574 then (tm, reverse declimps)
575 else implicitise syn ignore ist (pibind uvars ns tm)
578 pvars = syn_params syn
580 dropAll (x:xs) ys | x `elem` ys = dropAll xs ys
581 | otherwise = x : dropAll xs ys
584 imps top env (PApp _ f as)
585 = do (decls, ns) <- get
586 let isn = concatMap (namesIn uvars ist) (map getTm as)
587 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
588 imps top env (PPi (Imp l _) n ty sc)
589 = do let isn = nub (namesIn uvars ist ty) `dropAll` [n]
591 put (PImp (getPriority ist ty) l n ty : decls,
592 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
594 imps top env (PPi (Exp l _) n ty sc)
595 = do let isn = nub (namesIn uvars ist ty ++ case sc of
596 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
598 (decls, ns) <- get -- ignore decls in HO types
599 put (PExp (getPriority ist ty) l ty : decls,
600 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
602 imps top env (PPi (Constraint l _) n ty sc)
603 = do let isn = nub (namesIn uvars ist ty ++ case sc of
604 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
606 (decls, ns) <- get -- ignore decls in HO types
607 put (PConstraint 10 l ty : decls,
608 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
610 imps top env (PPi (TacImp l _ scr) n ty sc)
611 = do let isn = nub (namesIn uvars ist ty ++ case sc of
612 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
614 (decls, ns) <- get -- ignore decls in HO types
615 put (PTacImplicit 10 l n scr ty : decls,
616 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
618 imps top env (PEq _ l r)
619 = do (decls, ns) <- get
620 let isn = namesIn uvars ist l ++ namesIn uvars ist r
621 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
622 imps top env (PTyped l r)
624 imps top env (PPair _ l r)
625 = do (decls, ns) <- get
626 let isn = namesIn uvars ist l ++ namesIn uvars ist r
627 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
628 imps top env (PDPair _ (PRef _ n) t r)
629 = do (decls, ns) <- get
630 let isn = nub (namesIn uvars ist t ++ namesIn uvars ist r) \\ [n]
631 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
632 imps top env (PDPair _ l t r)
633 = do (decls, ns) <- get
634 let isn = namesIn uvars ist l ++ namesIn uvars ist t ++
636 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
637 imps top env (PAlternative a as)
638 = do (decls, ns) <- get
639 let isn = concatMap (namesIn uvars ist) as
640 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
641 imps top env (PLam n ty sc)
642 = do imps False env ty
643 imps False (n:env) sc
644 imps top env (PHidden tm) = imps False env tm
645 imps top env _ = return ()
647 pibind using [] sc = sc
648 pibind using (n:ns) sc
649 = case lookup n using of
650 Just ty -> PPi (Imp False Dynamic) n ty (pibind using ns sc)
651 Nothing -> PPi (Imp False Dynamic) n Placeholder (pibind using ns sc)
653-- Add implicit arguments in function calls
654addImplPat :: IState -> PTerm -> PTerm
655addImplPat = addImpl' True []
657addImplBound :: IState -> [Name] -> PTerm -> PTerm
658addImplBound ist ns = addImpl' False ns ist
660addImpl :: IState -> PTerm -> PTerm
661addImpl = addImpl' False []
663-- TODO: in patterns, don't add implicits to function names guarded by constructors
664-- and *not* inside a PHidden
666addImpl' :: Bool -> [Name] -> IState -> PTerm -> PTerm
667addImpl' inpat env ist ptm = ai env ptm
670 | not (f `elem` env) = handleErr $ aiFn inpat inpat ist fc f []
671 ai env (PHidden (PRef fc f))
672 | not (f `elem` env) = handleErr $ aiFn inpat False ist fc f []
673 ai env (PEq fc l r) = let l' = ai env l
676 ai env (PTyped l r) = let l' = ai env l
679 ai env (PPair fc l r) = let l' = ai env l
682 ai env (PDPair fc l t r) = let l' = ai env l
686 ai env (PAlternative a as) = let as' = map (ai env) as in
688 ai env (PApp fc (PRef _ f) as)
690 = let as' = map (fmap (ai env)) as in
691 handleErr $ aiFn inpat False ist fc f as'
692 ai env (PApp fc f as) = let f' = ai env f
693 as' = map (fmap (ai env)) as in
695 ai env (PCase fc c os) = let c' = ai env c
696 os' = map (pmap (ai env)) os in
698 ai env (PLam n ty sc) = let ty' = ai env ty
699 sc' = ai (n:env) sc in
701 ai env (PLet n ty val sc)
702 = let ty' = ai env ty
704 sc' = ai (n:env) sc in
706 ai env (PPi p n ty sc) = let ty' = ai env ty
707 sc' = ai (n:env) sc in
709 ai env (PHidden tm) = PHidden (ai env tm)
710 ai env (PProof ts) = PProof (map (fmap (ai env)) ts)
711 ai env (PTactics ts) = PTactics (map (fmap (ai env)) ts)
714 handleErr (Left err) = PElabError err
715 handleErr (Right x) = x
717-- if in a pattern, and there are no arguments, and there's no possible
718-- names with zero explicit arguments, don't add implicits.
720aiFn :: Bool -> Bool -> IState -> FC -> Name -> [PArg] -> Either Err PTerm
721aiFn inpat True ist fc f []
722 = case lookupDef Nothing f (tt_ctxt ist) of
723 [] -> Right $ PPatvar fc f
724 alts -> let ialts = lookupCtxt Nothing f (idris_implicits ist) in
725 -- trace (show f ++ " " ++ show (fc, any (all imp) ialts, ialts, any constructor alts)) $
726 if (not (vname f) || tcname f
727 || any constructor alts || any allImp ialts)
728 then aiFn inpat False ist fc f [] -- use it as a constructor
729 else Right $ PPatvar fc f
730 where imp (PExp _ _ _) = False
733 allImp xs = all imp xs
734 constructor (TyDecl (DCon _ _) _) = True
735 constructor _ = False
737 vname (UN n) = True -- non qualified
740aiFn inpat expat ist fc f as
741 | f `elem` primNames = Right $ PApp fc (PRef fc f) as
742aiFn inpat expat ist fc f as
743 -- This is where namespaces get resolved by adding PAlternative
744 = case lookupCtxtName Nothing f (idris_implicits ist) of
745 [(f',ns)] -> Right $ mkPApp fc (length ns) (PRef fc f') (insertImpl ns as)
746 [] -> if f `elem` idris_metavars ist
747 then Right $ PApp fc (PRef fc f) as
748 else Right $ mkPApp fc (length as) (PRef fc f) as
751 map (\(f', ns) -> mkPApp fc (length ns) (PRef fc f')
752 (insertImpl ns as)) alts
754 insertImpl :: [PArg] -> [PArg] -> [PArg]
755 insertImpl (PExp p l ty : ps) (PExp _ _ tm : given) =
756 PExp p l tm : insertImpl ps given
757 insertImpl (PConstraint p l ty : ps) (PConstraint _ _ tm : given) =
758 PConstraint p l tm : insertImpl ps given
759 insertImpl (PConstraint p l ty : ps) given =
760 PConstraint p l (PResolveTC fc) : insertImpl ps given
761 insertImpl (PImp p l n ty : ps) given =
762 case find n given [] of
763 Just (tm, given') -> PImp p l n tm : insertImpl ps given'
764 Nothing -> PImp p l n Placeholder : insertImpl ps given
765 insertImpl (PTacImplicit p l n sc ty : ps) given =
766 case find n given [] of
767 Just (tm, given') -> PTacImplicit p l n sc tm : insertImpl ps given'
769 then PTacImplicit p l n sc Placeholder : insertImpl ps given
770 else PTacImplicit p l n sc sc : insertImpl ps given
771 insertImpl expected [] = []
772 insertImpl _ given = given
774 find n [] acc = Nothing
775 find n (PImp _ _ n' t : gs) acc
776 | n == n' = Just (t, reverse acc ++ gs)
777 find n (PTacImplicit _ _ n' _ t : gs) acc
778 | n == n' = Just (t, reverse acc ++ gs)
779 find n (g : gs) acc = find n gs (g : acc)
782mkPApp fc a f as = let rest = drop a as in
783 appRest fc (PApp fc f (take a as)) rest
786 appRest fc f (a : as) = appRest fc (PApp fc f [a]) as
788-- Find 'static' argument positions
789-- (the declared ones, plus any names in argument position in the declared
791-- FIXME: It's possible that this really has to happen after elaboration
793findStatics :: IState -> PTerm -> (PTerm, [Bool])
794findStatics ist tm = trace (showImp True tm) $
795 let (ns, ss) = fs tm in
796 runState (pos ns ss tm) []
797 where fs (PPi p n t sc)
798 | Static <- pstatic p
799 = let (ns, ss) = fs sc in
800 (namesIn [] ist t : ns, n : ss)
801 | otherwise = let (ns, ss) = fs sc in
805 inOne n ns = length (filter id (map (elem n) ns)) == 1
807 pos ns ss (PPi p n t sc)
808 | elem n ss = do sc' <- pos ns ss sc
811 return (PPi (p { pstatic = Static }) n t sc')
812 | otherwise = do sc' <- pos ns ss sc
815 return (PPi p n t sc')
816 pos ns ss t = return t
818-- Debugging/logging stuff
820dumpDecls :: [PDecl] -> String
822dumpDecls (d:ds) = dumpDecl d ++ "\n" ++ dumpDecls ds
824dumpDecl (PFix _ f ops) = show f ++ " " ++ showSep ", " ops
825dumpDecl (PTy _ _ _ n t) = "tydecl " ++ show n ++ " : " ++ showImp True t
826dumpDecl (PClauses _ _ n cs) = "pat " ++ show n ++ "\t" ++ showSep "\n\t" (map (showCImp True) cs)
827dumpDecl (PData _ _ d) = showDImp True d
828dumpDecl (PParams _ ns ps) = "params {" ++ show ns ++ "\n" ++ dumpDecls ps ++ "}\n"
829dumpDecl (PNamespace n ps) = "namespace {" ++ n ++ "\n" ++ dumpDecls ps ++ "}\n"
830dumpDecl (PSyntax _ syn) = "syntax " ++ show syn
831dumpDecl (PClass _ _ cs n ps ds)
832 = "class " ++ show cs ++ " " ++ show n ++ " " ++ show ps ++ "\n" ++ dumpDecls ds
833dumpDecl (PInstance _ _ cs n _ t _ ds)
834 = "instance " ++ show cs ++ " " ++ show n ++ " " ++ show t ++ "\n" ++ dumpDecls ds
836-- dumpDecl (PImport i) = "import " ++ i
838-- for 6.12/7 compatibility
839data EitherErr a b = LeftErr a | RightOK b
841instance Monad (EitherErr a) where
844 (LeftErr e) >>= k = LeftErr e
845 RightOK v >>= k = k v
847toEither (LeftErr e) = Left e
848toEither (RightOK ho) = Right ho
850-- syntactic match of a against b, returning pair of variables in a
851-- and what they match. Returns the pair that failed if not a match.
853matchClause :: IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
854matchClause = matchClause' False
856matchClause' :: Bool -> IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
857matchClause' names i x y = checkRpts $ match (fullApp x) (fullApp y) where
858 matchArg x y = match (fullApp (getTm x)) (fullApp (getTm y))
860 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
863 match' x y = match (fullApp x) (fullApp y)
864 match (PApp _ (PRef _ (NS (UN "fromInteger") ["builtins"])) [_,_,x]) x'
865 | PConstant (I _) <- getTm x = match (getTm x) x'
866 match x' (PApp _ (PRef _ (NS (UN "fromInteger") ["builtins"])) [_,_,x])
867 | PConstant (I _) <- getTm x = match (getTm x) x'
868 match (PApp _ (PRef _ (UN "lazy")) [_,x]) x' = match (getTm x) x'
869 match x (PApp _ (PRef _ (UN "lazy")) [_,x']) = match x (getTm x')
870 match (PApp _ f args) (PApp _ f' args')
871 | length args == length args'
872 = do mf <- match' f f'
873 ms <- zipWithM matchArg args args'
874 return (mf ++ concat ms)
875-- match (PRef _ n) (PRef _ n') | n == n' = return []
876-- | otherwise = Nothing
877 match (PRef f n) (PApp _ x []) = match (PRef f n) x
878 match (PApp _ x []) (PRef f n) = match x (PRef f n)
879 match (PRef _ n) (PRef _ n') | n == n' = return []
881 | not names && (not (isConName Nothing n (tt_ctxt i)) || tm == Placeholder)
883 match (PEq _ l r) (PEq _ l' r') = do ml <- match' l l'
886 match (PTyped l r) (PTyped l' r') = do ml <- match l l'
889 match (PTyped l r) x = match l x
890 match x (PTyped l r) = match x l
891 match (PPair _ l r) (PPair _ l' r') = do ml <- match' l l'
894 match (PDPair _ l t r) (PDPair _ l' t' r') = do ml <- match' l l'
897 return (ml ++ mt ++ mr)
898 match (PAlternative a as) (PAlternative a' as')
899 = do ms <- zipWithM match' as as'
901 match a@(PAlternative _ as) b
902 = do let ms = zipWith match' as (repeat b)
903 case (rights (map toEither ms)) of
906 match (PCase _ _ _) _ = return [] -- lifted out
907 match (PMetavar _) _ = return [] -- modified
908 match (PQuote _) _ = return []
909 match (PProof _) _ = return []
910 match (PTactics _) _ = return []
911 match (PRefl _ _) (PRefl _ _) = return []
912 match (PResolveTC _) (PResolveTC _) = return []
913 match (PTrue _) (PTrue _) = return []
914 match (PFalse _) (PFalse _) = return []
915 match (PReturn _) (PReturn _) = return []
916 match (PPi _ _ t s) (PPi _ _ t' s') = do mt <- match' t t'
919 match (PLam _ t s) (PLam _ t' s') = do mt <- match' t t'
922 match (PLet _ t ty s) (PLet _ t' ty' s') = do mt <- match' t t'
925 return (mt ++ mty ++ ms)
926 match (PHidden x) (PHidden y) = match' x y
927 match Placeholder _ = return []
928 match _ Placeholder = return []
929 match (PResolveTC _) _ = return []
930 match a b | a == b = return []
931 | otherwise = LeftErr (a, b)
933 checkRpts (RightOK ms) = check ms where
935 | Just t' <- lookup n xs = if t/=t' && t/=Placeholder && t'/=Placeholder
938 check (_:xs) = check xs
940 checkRpts (LeftErr x) = Left x
942substMatches :: [(Name, PTerm)] -> PTerm -> PTerm
944substMatches ((n,tm):ns) t = substMatch n tm (substMatches ns t)
946substMatch :: Name -> PTerm -> PTerm -> PTerm
947substMatch n tm t = sm t where
948 sm (PRef _ n') | n == n' = tm
949 sm (PLam x t sc) = PLam x (sm t) (sm sc)
950 sm (PPi p x t sc) = PPi p x (sm t) (sm sc)
951 sm (PApp f x as) = PApp f (sm x) (map (fmap sm) as)
952 sm (PCase f x as) = PCase f (sm x) (map (pmap sm) as)
953 sm (PEq f x y) = PEq f (sm x) (sm y)
954 sm (PTyped x y) = PTyped (sm x) (sm y)
955 sm (PPair f x y) = PPair f (sm x) (sm y)
956 sm (PDPair f x t y) = PDPair f (sm x) (sm t) (sm y)
957 sm (PAlternative a as) = PAlternative a (map sm as)
958 sm (PHidden x) = PHidden (sm x)
961shadow :: Name -> Name -> PTerm -> PTerm
962shadow n n' t = sm t where
963 sm (PRef fc x) | n == x = PRef fc n'
964 sm (PLam x t sc) = PLam x (sm t) (sm sc)
965 sm (PPi p x t sc) = PPi p x (sm t) (sm sc)
966 sm (PApp f x as) = PApp f (sm x) (map (fmap sm) as)
967 sm (PCase f x as) = PCase f (sm x) (map (pmap sm) as)
968 sm (PEq f x y) = PEq f (sm x) (sm y)
969 sm (PTyped x y) = PTyped (sm x) (sm y)
970 sm (PPair f x y) = PPair f (sm x) (sm y)
971 sm (PDPair f x t y) = PDPair f (sm x) (sm t) (sm y)
972 sm (PAlternative a as) = PAlternative a (map sm as)
973 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