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 -> [Name] -> Idris ()
71addToCG n ns = do i <- get
72 put (i { idris_callgraph = addDef n ns (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' } )
198logLevel = do i <- get
199 return (opt_logLevel (idris_options i))
201setErrContext :: Bool -> Idris ()
202setErrContext t = do i <- get
203 let opts = idris_options i
204 let opt' = opts { opt_errContext = t }
205 put (i { idris_options = opt' })
207errContext :: Idris Bool
208errContext = do i <- get
209 return (opt_errContext (idris_options i))
213 return (opt_repl (idris_options i))
215setREPL :: Bool -> Idris ()
216setREPL t = do i <- get
217 let opts = idris_options i
218 let opt' = opts { opt_repl = t }
219 put (i { idris_options = opt' })
223 return (opt_verbose (idris_options i))
225setVerbose :: Bool -> Idris ()
226setVerbose t = do i <- get
227 let opts = idris_options i
228 let opt' = opts { opt_verbose = t }
229 put (i { idris_options = opt' })
231typeInType :: Idris Bool
232typeInType = do i <- get
233 return (opt_typeintype (idris_options i))
235setTypeInType :: Bool -> Idris ()
236setTypeInType t = do i <- get
237 let opts = idris_options i
238 let opt' = opts { opt_typeintype = t }
239 put (i { idris_options = opt' })
241coverage :: Idris Bool
242coverage = do i <- get
243 return (opt_coverage (idris_options i))
245setCoverage :: Bool -> Idris ()
246setCoverage t = do i <- get
247 let opts = idris_options i
248 let opt' = opts { opt_coverage = t }
249 put (i { idris_options = opt' })
251setIBCSubDir :: FilePath -> Idris ()
252setIBCSubDir fp = do i <- get
253 let opts = idris_options i
254 let opt' = opts { opt_ibcsubdir = fp }
255 put (i { idris_options = opt' })
257valIBCSubDir :: IState -> Idris FilePath
258valIBCSubDir i = return (opt_ibcsubdir (idris_options i))
260addImportDir :: FilePath -> Idris ()
261addImportDir fp = do i <- get
262 let opts = idris_options i
263 let opt' = opts { opt_importdirs = fp : opt_importdirs opts }
264 put (i { idris_options = opt' })
266setImportDirs :: [FilePath] -> Idris ()
267setImportDirs fps = do i <- get
268 let opts = idris_options i
269 let opt' = opts { opt_importdirs = fps }
270 put (i { idris_options = opt' })
272allImportDirs :: IState -> Idris [FilePath]
273allImportDirs i = do let optdirs = opt_importdirs (idris_options i)
274 return ("." : optdirs)
278 return (opt_showimp (idris_options i))
280setImpShow :: Bool -> Idris ()
281setImpShow t = do i <- get
282 let opts = idris_options i
283 let opt' = opts { opt_showimp = t }
284 put (i { idris_options = opt' })
286logLvl :: Int -> String -> Idris ()
287logLvl l str = do i <- get
288 let lvl = opt_logLevel (idris_options i)
290 $ do liftIO (putStrLn str)
291 put (i { idris_log = idris_log i ++ str ++ "\n" } )
293iLOG :: String -> Idris ()
296noErrors :: Idris Bool
297noErrors = do i <- get
299 Nothing -> return True
302setTypeCase :: Bool -> Idris ()
303setTypeCase t = do i <- get
304 let opts = idris_options i
305 let opt' = opts { opt_typecase = t }
306 put (i { idris_options = opt' })
309-- For inferring types of things
313inferTy = MN 0 "__Infer"
314inferCon = MN 0 "__infer"
315inferDecl = PDatadecl inferTy
317 [(inferCon, PPi impl (MN 0 "A") PSet (
318 PPi expl (MN 0 "a") (PRef bi (MN 0 "A"))
319 (PRef bi inferTy)), bi)]
321infTerm t = PApp bi (PRef bi inferCon) [pimp (MN 0 "A") Placeholder, pexp t]
322infP = P (TCon 6 0) inferTy (Set (UVal 0))
324getInferTerm, getInferType :: Term -> Term
325getInferTerm (Bind n b sc) = Bind n b $ getInferTerm sc
326getInferTerm (App (App _ _) tm) = tm
327getInferTerm tm = error ("getInferTerm " ++ show tm)
329getInferType (Bind n b sc) = Bind n b $ getInferType sc
330getInferType (App (App _ ty) _) = ty
332-- Handy primitives: Unit, False, Pair, MkPair, =, mkForeign
334primNames = [unitTy, unitCon,
335 falseTy, pairTy, pairCon,
336 eqTy, eqCon, inferTy, inferCon]
338unitTy = MN 0 "__Unit"
340unitDecl = PDatadecl unitTy PSet
341 [(unitCon, PRef bi unitTy, bi)]
343falseTy = MN 0 "__False"
344falseDecl = PDatadecl falseTy PSet []
346pairTy = MN 0 "__Pair"
347pairCon = MN 0 "__MkPair"
348pairDecl = PDatadecl pairTy (piBind [(n "A", PSet), (n "B", PSet)] PSet)
349 [(pairCon, PPi impl (n "A") PSet (
350 PPi impl (n "B") PSet (
351 PPi expl (n "a") (PRef bi (n "A")) (
352 PPi expl (n "b") (PRef bi (n "B"))
353 (PApp bi (PRef bi pairTy) [pexp (PRef bi (n "A")),
354 pexp (PRef bi (n "B"))])))), bi)]
359eqDecl = PDatadecl eqTy (piBind [(n "a", PSet), (n "b", PSet),
360 (n "x", PRef bi (n "a")), (n "y", PRef bi (n "b"))]
362 [(eqCon, PPi impl (n "a") PSet (
363 PPi impl (n "x") (PRef bi (n "a"))
364 (PApp bi (PRef bi eqTy) [pimp (n "a") Placeholder,
365 pimp (n "b") Placeholder,
366 pexp (PRef bi (n "x")),
367 pexp (PRef bi (n "x"))])), bi)]
370-- Defined in builtins.idr
372existsCon = UN "Ex_intro"
374piBind :: [(Name, PTerm)] -> PTerm -> PTerm
376piBind ((n, ty):ns) t = PPi expl n ty (piBind ns t)
378tcname (UN ('@':_)) = True
379tcname (NS n _) = tcname n
382-- Dealing with parameters
384expandParams :: (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PTerm -> PTerm
385expandParams dec ps ns tm = en tm
387 -- if we shadow a name (say in a lambda binding) that is used in a call to
388 -- a lifted function, we need access to both names - once in the scope of the
389 -- binding and once to call the lifted functions. So we'll explicitly shadow
390 -- it. (Yes, it's a hack. The alternative would be to resolve names earlier
393 mkShadow (UN n) = MN 0 n
394 mkShadow (MN i n) = MN (i+1) n
395 mkShadow (NS x s) = NS (mkShadow x) s
398 | n `elem` map fst ps
399 = let n' = mkShadow n in
400 PLam n' (en t) (en (shadow n n' s))
401 | otherwise = PLam n (en t) (en s)
403 | n `elem` map fst ps
404 = let n' = mkShadow n in
405 PPi p n' (en t) (en (shadow n n' s))
406 | otherwise = PPi p n (en t) (en s)
408 | n `elem` map fst ps
409 = let n' = mkShadow n in
410 PLet n' (en ty) (en v) (en (shadow n n' s))
411 | otherwise = PLet n (en ty) (en v) (en s)
412 en (PEq f l r) = PEq f (en l) (en r)
413 en (PTyped l r) = PTyped (en l) (en r)
414 en (PPair f l r) = PPair f (en l) (en r)
415 en (PDPair f l t r) = PDPair f (en l) (en t) (en r)
416 en (PAlternative a as) = PAlternative a (map en as)
417 en (PHidden t) = PHidden (en t)
418 en (PDoBlock ds) = PDoBlock (map (fmap en) ds)
419 en (PProof ts) = PProof (map (fmap en) ts)
420 en (PTactics ts) = PTactics (map (fmap en) ts)
423 | n `elem` ns = PQuote (Var (dec n))
424 en (PApp fc (PRef fc' n) as)
425 | n `elem` ns = PApp fc (PRef fc' (dec n))
426 (map (pexp . (PRef fc)) (map fst ps) ++ (map (fmap en) as))
428 | n `elem` ns = PApp fc (PRef fc (dec n))
429 (map (pexp . (PRef fc)) (map fst ps))
430 en (PApp fc f as) = PApp fc (en f) (map (fmap en) as)
431 en (PCase fc c os) = PCase fc (en c) (map (pmap en) os)
434expandParamsD :: IState ->
435 (Name -> Name) -> [(Name, PTerm)] -> [Name] -> PDecl -> PDecl
436expandParamsD ist dec ps ns (PTy syn fc o n ty)
438 then PTy syn fc o (dec n) (piBind ps (expandParams dec ps ns ty))
439 else PTy syn fc o n (expandParams dec ps ns ty)
440expandParamsD ist dec ps ns (PClauses fc opts n cs)
441 = let n' = if n `elem` ns then dec n else n in
442 PClauses fc opts n' (map expandParamsC cs)
444 expandParamsC (PClause fc n lhs ws rhs ds)
445 = let -- ps' = updateps True (namesIn ist rhs) (zip ps [0..])
446 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
447 n' = if n `elem` ns then dec n else n in
448 PClause fc n' (expandParams dec ps'' ns lhs)
449 (map (expandParams dec ps'' ns) ws)
450 (expandParams dec ps'' ns rhs)
451 (map (expandParamsD ist dec ps'' ns) ds)
452 expandParamsC (PWith fc n lhs ws wval ds)
453 = let -- ps' = updateps True (namesIn ist wval) (zip ps [0..])
454 ps'' = updateps False (namesIn [] ist lhs) (zip ps [0..])
455 n' = if n `elem` ns then dec n else n in
456 PWith fc n' (expandParams dec ps'' ns lhs)
457 (map (expandParams dec ps'' ns) ws)
458 (expandParams dec ps'' ns wval)
459 (map (expandParamsD ist dec ps'' ns) ds)
460 updateps yn nm [] = []
461 updateps yn nm (((a, t), i):as)
462 | (a `elem` nm) == yn = (a, t) : updateps yn nm as
463 | otherwise = (MN i (show n ++ "_u"), t) : updateps yn nm as
465expandParamsD ist dec ps ns d = d
467-- Calculate a priority for a type, for deciding elaboration order
468-- * if it's just a type variable or concrete type, do it early (0)
469-- * if there's only type variables and injective constructors, do it next (1)
470-- * if there's a function type, next (2)
471-- * finally, everything else (3)
473getPriority :: IState -> PTerm -> Int
474getPriority i tm = pri tm
477 case lookupP Nothing n (tt_ctxt i) of
478 ((P (DCon _ _) _ _):_) -> 1
479 ((P (TCon _ _) _ _):_) -> 1
481 [] -> 0 -- must be locally bound, if it's not an error...
482 pri (PPi _ _ x y) = max 5 (max (pri x) (pri y))
486 pri (PEq _ l r) = max 1 (max (pri l) (pri r))
487 pri (PApp _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.getTm) as)))
488 pri (PCase _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.snd) as)))
489 pri (PTyped l r) = pri l
490 pri (PPair _ l r) = max 1 (max (pri l) (pri r))
491 pri (PDPair _ l t r) = max 1 (max (pri l) (max (pri t) (pri r)))
492 pri (PAlternative a as) = maximum (map pri as)
493 pri (PConstant _) = 0
497addStatics :: Name -> Term -> PTerm -> Idris ()
499 do let (statics, dynamics) = initStatics tm ptm
500 let stnames = nub $ concatMap freeNames (map snd statics)
501 let dnames = nub $ concatMap freeNames (map snd dynamics)
502 when (not (null statics)) $
503 logLvl 7 $ show n ++ " " ++ show statics ++ "\n" ++ show dynamics
504 ++ "\n" ++ show stnames ++ "\n" ++ show dnames
505 let statics' = nub $ map fst statics ++
506 filter (\x -> not (elem x dnames)) stnames
507 let stpos = staticList statics' tm
509 put (i { idris_statics = addDef n stpos (idris_statics i) })
512 initStatics (Bind n (Pi ty) sc) (PPi p _ _ s)
513 = let (static, dynamic) = initStatics (instantiate (P Bound n ty) sc) s in
514 if pstatic p == Static then ((n, ty) : static, dynamic)
515 else (static, (n, ty) : dynamic)
516 initStatics t pt = ([], [])
518 staticList sts (Bind n (Pi _) sc) = (n `elem` sts) : staticList sts sc
521-- Dealing with implicit arguments
523-- Add implicit Pi bindings for any names in the term which appear in an
526-- This has become a right mess already. Better redo it some time...
528implicit :: SyntaxInfo -> Name -> PTerm -> Idris PTerm
531 let (tm', impdata) = implicitise syn i ptm
532-- let (tm'', spos) = findStatics i tm'
533 put (i { idris_implicits = addDef n impdata (idris_implicits i) })
535 logLvl 5 ("Implicit " ++ show n ++ " " ++ show impdata)
537-- put (i { idris_statics = addDef n spos (idris_statics i) })
540implicitise :: SyntaxInfo -> IState -> PTerm -> (PTerm, [PArg])
541implicitise syn ist tm
542 = let (declimps, ns') = execState (imps True [] tm) ([], [])
543 ns = ns' \\ (map fst pvars ++ no_imp syn) in
545 then (tm, reverse declimps)
546 else implicitise syn ist (pibind uvars ns tm)
549 pvars = syn_params syn
551 dropAll (x:xs) ys | x `elem` ys = dropAll xs ys
552 | otherwise = x : dropAll xs ys
555 imps top env (PApp _ f as)
556 = do (decls, ns) <- get
557 let isn = concatMap (namesIn uvars ist) (map getTm as)
558 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
559 imps top env (PPi (Imp l _) n ty sc)
560 = do let isn = nub (namesIn uvars ist ty) `dropAll` [n]
562 put (PImp (getPriority ist ty) l n ty : decls,
563 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
565 imps top env (PPi (Exp l _) n ty sc)
566 = do let isn = nub (namesIn uvars ist ty ++ case sc of
567 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
569 (decls, ns) <- get -- ignore decls in HO types
570 put (PExp (getPriority ist ty) l ty : decls,
571 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
573 imps top env (PPi (Constraint l _) n ty sc)
574 = do let isn = nub (namesIn uvars ist ty ++ case sc of
575 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
577 (decls, ns) <- get -- ignore decls in HO types
578 put (PConstraint 10 l ty : decls,
579 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
581 imps top env (PPi (TacImp l _ scr) n ty sc)
582 = do let isn = nub (namesIn uvars ist ty ++ case sc of
583 (PRef _ x) -> namesIn uvars ist sc `dropAll` [n]
585 (decls, ns) <- get -- ignore decls in HO types
586 put (PTacImplicit 10 l n scr ty : decls,
587 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
589 imps top env (PEq _ l r)
590 = do (decls, ns) <- get
591 let isn = namesIn uvars ist l ++ namesIn uvars ist r
592 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
593 imps top env (PTyped l r)
595 imps top env (PPair _ l r)
596 = do (decls, ns) <- get
597 let isn = namesIn uvars ist l ++ namesIn uvars ist r
598 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
599 imps top env (PDPair _ (PRef _ n) t r)
600 = do (decls, ns) <- get
601 let isn = nub (namesIn uvars ist t ++ namesIn uvars ist r) \\ [n]
602 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
603 imps top env (PDPair _ l t r)
604 = do (decls, ns) <- get
605 let isn = namesIn uvars ist l ++ namesIn uvars ist t ++
607 put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
608 imps top env (PAlternative a as)
609 = do (decls, ns) <- get
610 let isn = concatMap (namesIn uvars ist) as
611 put (decls, nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
612 imps top env (PLam n ty sc)
613 = do imps False env ty
614 imps False (n:env) sc
615 imps top env (PHidden tm) = imps False env tm
616 imps top env _ = return ()
618 pibind using [] sc = sc
619 pibind using (n:ns) sc
620 = case lookup n using of
621 Just ty -> PPi (Imp False Dynamic) n ty (pibind using ns sc)
622 Nothing -> PPi (Imp False Dynamic) n Placeholder (pibind using ns sc)
624-- Add implicit arguments in function calls
625addImplPat :: IState -> PTerm -> PTerm
626addImplPat = addImpl' True []
628addImplBound :: IState -> [Name] -> PTerm -> PTerm
629addImplBound ist ns = addImpl' False ns ist
631addImpl :: IState -> PTerm -> PTerm
632addImpl = addImpl' False []
634-- TODO: in patterns, don't add implicits to function names guarded by constructors
635-- and *not* inside a PHidden
637addImpl' :: Bool -> [Name] -> IState -> PTerm -> PTerm
638addImpl' inpat env ist ptm = ai env ptm
641 | not (f `elem` env) = handleErr $ aiFn inpat inpat ist fc f []
642 ai env (PHidden (PRef fc f))
643 | not (f `elem` env) = handleErr $ aiFn inpat False ist fc f []
644 ai env (PEq fc l r) = let l' = ai env l
647 ai env (PTyped l r) = let l' = ai env l
650 ai env (PPair fc l r) = let l' = ai env l
653 ai env (PDPair fc l t r) = let l' = ai env l
657 ai env (PAlternative a as) = let as' = map (ai env) as in
659 ai env (PApp fc (PRef _ f) as)
661 = let as' = map (fmap (ai env)) as in
662 handleErr $ aiFn inpat False ist fc f as'
663 ai env (PApp fc f as) = let f' = ai env f
664 as' = map (fmap (ai env)) as in
666 ai env (PCase fc c os) = let c' = ai env c
667 os' = map (pmap (ai env)) os in
669 ai env (PLam n ty sc) = let ty' = ai env ty
670 sc' = ai (n:env) sc in
672 ai env (PLet n ty val sc)
673 = let ty' = ai env ty
675 sc' = ai (n:env) sc in
677 ai env (PPi p n ty sc) = let ty' = ai env ty
678 sc' = ai (n:env) sc in
680 ai env (PHidden tm) = PHidden (ai env tm)
681 ai env (PProof ts) = PProof (map (fmap (ai env)) ts)
682 ai env (PTactics ts) = PTactics (map (fmap (ai env)) ts)
685 handleErr (Left err) = PElabError err
686 handleErr (Right x) = x
688-- if in a pattern, and there are no arguments, and there's no possible
689-- names with zero explicit arguments, don't add implicits.
691aiFn :: Bool -> Bool -> IState -> FC -> Name -> [PArg] -> Either Err PTerm
692aiFn inpat True ist fc f []
693 = case lookupCtxt Nothing f (idris_implicits ist) of
694 [] -> Right $ PRef fc f
695 alts -> if (any (all imp) alts)
696 then aiFn inpat False ist fc f [] -- use it as a constructor
697 else Right $ PRef fc f
698 where imp (PExp _ _ _) = False
700aiFn inpat expat ist fc f as
701 | f `elem` primNames = Right $ PApp fc (PRef fc f) as
702aiFn inpat expat ist fc f as
703 -- This is where namespaces get resolved by adding PAlternative
704 = case lookupCtxtName Nothing f (idris_implicits ist) of
705 [(f',ns)] -> Right $ mkPApp fc (length ns) (PRef fc f') (insertImpl ns as)
706 [] -> if f `elem` idris_metavars ist
707 then Right $ PApp fc (PRef fc f) as
708 else Right $ mkPApp fc (length as) (PRef fc f) as
711 map (\(f', ns) -> mkPApp fc (length ns) (PRef fc f')
712 (insertImpl ns as)) alts
714 insertImpl :: [PArg] -> [PArg] -> [PArg]
715 insertImpl (PExp p l ty : ps) (PExp _ _ tm : given) =
716 PExp p l tm : insertImpl ps given
717 insertImpl (PConstraint p l ty : ps) (PConstraint _ _ tm : given) =
718 PConstraint p l tm : insertImpl ps given
719 insertImpl (PConstraint p l ty : ps) given =
720 PConstraint p l (PResolveTC fc) : insertImpl ps given
721 insertImpl (PImp p l n ty : ps) given =
722 case find n given [] of
723 Just (tm, given') -> PImp p l n tm : insertImpl ps given'
724 Nothing -> PImp p l n Placeholder : insertImpl ps given
725 insertImpl (PTacImplicit p l n sc ty : ps) given =
726 case find n given [] of
727 Just (tm, given') -> PTacImplicit p l n sc tm : insertImpl ps given'
729 then PTacImplicit p l n sc Placeholder : insertImpl ps given
730 else PTacImplicit p l n sc sc : insertImpl ps given
731 insertImpl expected [] = []
732 insertImpl _ given = given
734 find n [] acc = Nothing
735 find n (PImp _ _ n' t : gs) acc
736 | n == n' = Just (t, reverse acc ++ gs)
737 find n (PTacImplicit _ _ n' _ t : gs) acc
738 | n == n' = Just (t, reverse acc ++ gs)
739 find n (g : gs) acc = find n gs (g : acc)
742mkPApp fc a f as = let rest = drop a as in
743 appRest fc (PApp fc f (take a as)) rest
746 appRest fc f (a : as) = appRest fc (PApp fc f [a]) as
748-- Find 'static' argument positions
749-- (the declared ones, plus any names in argument position in the declared
751-- FIXME: It's possible that this really has to happen after elaboration
753findStatics :: IState -> PTerm -> (PTerm, [Bool])
754findStatics ist tm = trace (showImp True tm) $
755 let (ns, ss) = fs tm in
756 runState (pos ns ss tm) []
757 where fs (PPi p n t sc)
758 | Static <- pstatic p
759 = let (ns, ss) = fs sc in
760 (namesIn [] ist t : ns, n : ss)
761 | otherwise = let (ns, ss) = fs sc in
765 inOne n ns = length (filter id (map (elem n) ns)) == 1
767 pos ns ss (PPi p n t sc)
768 | elem n ss = do sc' <- pos ns ss sc
771 return (PPi (p { pstatic = Static }) n t sc')
772 | otherwise = do sc' <- pos ns ss sc
775 return (PPi p n t sc')
776 pos ns ss t = return t
778-- Debugging/logging stuff
780dumpDecls :: [PDecl] -> String
782dumpDecls (d:ds) = dumpDecl d ++ "\n" ++ dumpDecls ds
784dumpDecl (PFix _ f ops) = show f ++ " " ++ showSep ", " ops
785dumpDecl (PTy _ _ _ n t) = "tydecl " ++ show n ++ " : " ++ showImp True t
786dumpDecl (PClauses _ _ n cs) = "pat " ++ show n ++ "\t" ++ showSep "\n\t" (map (showCImp True) cs)
787dumpDecl (PData _ _ d) = showDImp True d
788dumpDecl (PParams _ ns ps) = "params {" ++ show ns ++ "\n" ++ dumpDecls ps ++ "}\n"
789dumpDecl (PNamespace n ps) = "namespace {" ++ n ++ "\n" ++ dumpDecls ps ++ "}\n"
790dumpDecl (PSyntax _ syn) = "syntax " ++ show syn
791dumpDecl (PClass _ _ cs n ps ds)
792 = "class " ++ show cs ++ " " ++ show n ++ " " ++ show ps ++ "\n" ++ dumpDecls ds
793dumpDecl (PInstance _ _ cs n _ t _ ds)
794 = "instance " ++ show cs ++ " " ++ show n ++ " " ++ show t ++ "\n" ++ dumpDecls ds
796-- dumpDecl (PImport i) = "import " ++ i
798-- for 6.12/7 compatibility
799data EitherErr a b = LeftErr a | RightOK b
801instance Monad (EitherErr a) where
804 (LeftErr e) >>= k = LeftErr e
805 RightOK v >>= k = k v
807toEither (LeftErr e) = Left e
808toEither (RightOK ho) = Right ho
810-- syntactic match of a against b, returning pair of variables in a
811-- and what they match. Returns the pair that failed if not a match.
813matchClause :: IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
814matchClause = matchClause' False
816matchClause' :: Bool -> IState -> PTerm -> PTerm -> Either (PTerm, PTerm) [(Name, PTerm)]
817matchClause' names i x y = checkRpts $ match (fullApp x) (fullApp y) where
818 matchArg x y = match (fullApp (getTm x)) (fullApp (getTm y))
820 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
823 match' x y = match (fullApp x) (fullApp y)
824 match (PApp _ (PRef _ (NS (UN "fromInteger") ["builtins"])) [_,_,x]) x'
825 | PConstant (I _) <- getTm x = match (getTm x) x'
826 match x' (PApp _ (PRef _ (NS (UN "fromInteger") ["builtins"])) [_,_,x])
827 | PConstant (I _) <- getTm x = match (getTm x) x'
828 match (PApp _ (PRef _ (UN "lazy")) [_,x]) x' = match (getTm x) x'
829 match x (PApp _ (PRef _ (UN "lazy")) [_,x']) = match x (getTm x')
830 match (PApp _ f args) (PApp _ f' args')
831 | length args == length args'
832 = do mf <- match' f f'
833 ms <- zipWithM matchArg args args'
834 return (mf ++ concat ms)
835-- match (PRef _ n) (PRef _ n') | n == n' = return []
836-- | otherwise = Nothing
837 match (PRef f n) (PApp _ x []) = match (PRef f n) x
838 match (PApp _ x []) (PRef f n) = match x (PRef f n)
839 match (PRef _ n) (PRef _ n') | n == n' = return []
841 | not names && (not (isConName Nothing n (tt_ctxt i)) || tm == Placeholder)
843 match (PEq _ l r) (PEq _ l' r') = do ml <- match' l l'
846 match (PTyped l r) (PTyped l' r') = do ml <- match l l'
849 match (PTyped l r) x = match l x
850 match x (PTyped l r) = match x l
851 match (PPair _ l r) (PPair _ l' r') = do ml <- match' l l'
854 match (PDPair _ l t r) (PDPair _ l' t' r') = do ml <- match' l l'
857 return (ml ++ mt ++ mr)
858 match (PAlternative a as) (PAlternative a' as')
859 = do ms <- zipWithM match' as as'
861 match a@(PAlternative _ as) b
862 = do let ms = zipWith match' as (repeat b)
863 case (rights (map toEither ms)) of
866 match (PCase _ _ _) _ = return [] -- lifted out
867 match (PMetavar _) _ = return [] -- modified
868 match (PQuote _) _ = return []
869 match (PProof _) _ = return []
870 match (PTactics _) _ = return []
871 match (PRefl _) (PRefl _) = return []
872 match (PResolveTC _) (PResolveTC _) = return []
873 match (PTrue _) (PTrue _) = return []
874 match (PFalse _) (PFalse _) = return []
875 match (PReturn _) (PReturn _) = return []
876 match (PPi _ _ t s) (PPi _ _ t' s') = do mt <- match' t t'
879 match (PLam _ t s) (PLam _ t' s') = do mt <- match' t t'
882 match (PLet _ t ty s) (PLet _ t' ty' s') = do mt <- match' t t'
885 return (mt ++ mty ++ ms)
886 match (PHidden x) (PHidden y) = match' x y
887 match Placeholder _ = return []
888-- match _ Placeholder = return []
889 match (PResolveTC _) _ = return []
890 match a b | a == b = return []
891 | otherwise = LeftErr (a, b)
893 checkRpts (RightOK ms) = check ms where
895 | Just t' <- lookup n xs = if t/=t' && t/=Placeholder && t'/=Placeholder
898 check (_:xs) = check xs
900 checkRpts (LeftErr x) = Left x
902substMatches :: [(Name, PTerm)] -> PTerm -> PTerm
904substMatches ((n,tm):ns) t = substMatch n tm (substMatches ns t)
906substMatch :: Name -> PTerm -> PTerm -> PTerm
907substMatch n tm t = sm t where
908 sm (PRef _ n') | n == n' = tm
909 sm (PLam x t sc) = PLam x (sm t) (sm sc)
910 sm (PPi p x t sc) = PPi p x (sm t) (sm sc)
911 sm (PApp f x as) = PApp f (sm x) (map (fmap sm) as)
912 sm (PCase f x as) = PCase f (sm x) (map (pmap sm) as)
913 sm (PEq f x y) = PEq f (sm x) (sm y)
914 sm (PTyped x y) = PTyped (sm x) (sm y)
915 sm (PPair f x y) = PPair f (sm x) (sm y)
916 sm (PDPair f x t y) = PDPair f (sm x) (sm t) (sm y)
917 sm (PAlternative a as) = PAlternative a (map sm as)
918 sm (PHidden x) = PHidden (sm x)
921shadow :: Name -> Name -> PTerm -> PTerm
922shadow n n' t = sm t where
923 sm (PRef fc x) | n == x = PRef fc n'
924 sm (PLam x t sc) = PLam x (sm t) (sm sc)
925 sm (PPi p x t sc) = PPi p x (sm t) (sm sc)
926 sm (PApp f x as) = PApp f (sm x) (map (fmap sm) as)
927 sm (PCase f x as) = PCase f (sm x) (map (pmap sm) as)
928 sm (PEq f x y) = PEq f (sm x) (sm y)
929 sm (PTyped x y) = PTyped (sm x) (sm y)
930 sm (PPair f x y) = PPair f (sm x) (sm y)
931 sm (PDPair f x t y) = PDPair f (sm x) (sm t) (sm y)
932 sm (PAlternative a as) = PAlternative a (map sm as)
933 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