on df5bf81 help sign in
Idris-dev/src/Idris/AbsSyntaxTree.hs
1116 lines 40 kB history raw
1{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, DeriveFunctor,
2 TypeSynonymInstances, PatternGuards #-}
4module Idris.AbsSyntaxTree where
6import Core.TT
7import Core.Evaluate
8import Core.Elaborate hiding (Tactic(..))
9import Core.Typecheck
10import IRTS.Lang
11import IRTS.CodegenCommon
12import Util.Pretty
14import Paths_idris
16import System.Console.Haskeline
18import Control.Monad.Trans.State.Strict
20import Data.List
21import Data.Char
22import Data.Either
24import Debug.Trace
26data IOption = IOption { opt_logLevel :: Int,
27 opt_typecase :: Bool,
28 opt_typeintype :: Bool,
29 opt_coverage :: Bool,
30 opt_showimp :: Bool,
31 opt_errContext :: Bool,
32 opt_repl :: Bool,
33 opt_verbose :: Bool,
34 opt_target :: Target,
35 opt_outputTy :: OutputType,
36 opt_ibcsubdir :: FilePath,
37 opt_importdirs :: [FilePath],
38 opt_cmdline :: [Opt] -- remember whole command line
39 }
40 deriving (Show, Eq)
42defaultOpts = IOption 0 False False True False False True True ViaC Executable "" [] []
44-- TODO: Add 'module data' to IState, which can be saved out and reloaded quickly (i.e
45-- without typechecking).
46-- This will include all the functions and data declarations, plus fixity declarations
47-- and syntax macros.
49-- | The global state used in the Idris monad
50data IState = IState {
51 tt_ctxt :: Context, -- ^ All the currently defined names and their terms
52 idris_constraints :: [(UConstraint, FC)],
53 -- ^ A list of universe constraints and their corresponding source locations
54 idris_infixes :: [FixDecl], -- ^ Currently defined infix operators
55 idris_implicits :: Ctxt [PArg],
56 idris_statics :: Ctxt [Bool],
57 idris_classes :: Ctxt ClassInfo,
58 idris_dsls :: Ctxt DSL,
59 idris_optimisation :: Ctxt OptInfo,
60 idris_datatypes :: Ctxt TypeInfo,
61 idris_patdefs :: Ctxt [([Name], Term, Term)], -- not exported
62 idris_flags :: Ctxt [FnOpt],
63 idris_callgraph :: Ctxt CGInfo, -- name, args used in each pos
64 idris_calledgraph :: Ctxt [Name],
65 idris_docstrings :: Ctxt String,
66 idris_totcheck :: [(FC, Name)],
67 idris_log :: String,
68 idris_options :: IOption,
69 idris_name :: Int,
70 idris_metavars :: [Name], -- ^ The currently defined but not proven metavariables
71 idris_coercions :: [Name],
72 syntax_rules :: [Syntax],
73 syntax_keywords :: [String],
74 imported :: [FilePath], -- ^ The imported modules
75 idris_scprims :: [(Name, (Int, PrimFn))],
76 idris_objs :: [FilePath],
77 idris_libs :: [String],
78 idris_hdrs :: [String],
79 proof_list :: [(Name, [String])],
80 errLine :: Maybe Int,
81 lastParse :: Maybe Name,
82 indent_stack :: [Int],
83 brace_stack :: [Maybe Int],
84 hide_list :: [(Name, Maybe Accessibility)],
85 default_access :: Accessibility,
86 default_total :: Bool,
87 ibc_write :: [IBCWrite],
88 compiled_so :: Maybe String
89 }
91data SizeChange = Smaller | Same | Bigger | Unknown
92 deriving (Show, Eq)
93{-!
94deriving instance Binary SizeChange
95!-}
97type SCGEntry = (Name, [Maybe (Int, SizeChange)])
99data CGInfo = CGInfo { argsdef :: [Name],
100 calls :: [(Name, [[Name]])],
101 scg :: [SCGEntry],
102 argsused :: [Name],
103 unusedpos :: [Int] }
104 deriving Show
105{-!
106deriving instance Binary CGInfo
107!-}
109primDefs = [UN "unsafePerformIO", UN "mkLazyForeign", UN "mkForeign", UN "FalseElim"]
111-- information that needs writing for the current module's .ibc file
112data IBCWrite = IBCFix FixDecl
113 | IBCImp Name
114 | IBCStatic Name
115 | IBCClass Name
116 | IBCInstance Bool Name Name
117 | IBCDSL Name
118 | IBCData Name
119 | IBCOpt Name
120 | IBCSyntax Syntax
121 | IBCKeyword String
122 | IBCImport FilePath
123 | IBCObj FilePath
124 | IBCLib String
125 | IBCHeader String
126 | IBCAccess Name Accessibility
127 | IBCTotal Name Totality
128 | IBCFlags Name [FnOpt]
129 | IBCCG Name
130 | IBCDoc Name
131 | IBCCoercion Name
132 | IBCDef Name -- i.e. main context
133 deriving Show
135idrisInit = IState initContext [] [] emptyContext emptyContext emptyContext
136 emptyContext emptyContext emptyContext emptyContext
137 emptyContext emptyContext emptyContext emptyContext
138 [] "" defaultOpts 6 [] [] [] [] [] [] [] [] []
139 [] Nothing Nothing [] [] [] Hidden False [] Nothing
141-- | The monad for the main REPL - reading and processing files and updating
142-- global state (hence the IO inner monad).
143type Idris = StateT IState IO
145-- Commands in the REPL
147data Target = ViaC
148 | ViaJava
149 | ViaNode
150 | ViaJavaScript
151 | Bytecode
152 deriving (Show, Eq)
154-- | REPL commands
155data Command = Quit
156 | Help
157 | Eval PTerm
158 | Check PTerm
159 | DocStr Name
160 | TotCheck Name
161 | Reload
162 | Load FilePath
163 | ModImport String
164 | Edit
165 | Compile Target String
166 | Execute
167 | ExecVal PTerm
168 | NewCompile String
169 | Metavars
170 | Prove Name
171 | AddProof (Maybe Name)
172 | RmProof Name
173 | ShowProof Name
174 | Proofs
175 | Universes
176 | TTShell
177 | LogLvl Int
178 | Spec PTerm
179 | HNF PTerm
180 | Defn Name
181 | Info Name
182 | Missing Name
183 | Pattelab PTerm
184 | DebugInfo Name
185 | Search PTerm
186 | SetOpt Opt
187 | UnsetOpt Opt
188 | NOP
190data Opt = Filename String
191 | Ver
192 | Usage
193 | ShowLibs
194 | ShowLibdir
195 | ShowIncs
196 | NoPrelude
197 | NoREPL
198 | OLogging Int
199 | Output String
200 | NewOutput String
201 | TypeCase
202 | TypeInType
203 | DefaultTotal
204 | DefaultPartial
205 | WarnPartial
206 | NoCoverage
207 | ErrContext
208 | ShowImpl
209 | Verbose
210 | IBCSubDir String
211 | ImportDir String
212 | PkgBuild String
213 | PkgInstall String
214 | PkgClean String
215 | WarnOnly
216 | Pkg String
217 | BCAsm String
218 | DumpDefun String
219 | DumpCases String
220 | FOVM String
221 | UseTarget Target
222 | OutputTy OutputType
223 deriving (Show, Eq)
225-- Parsed declarations
227data Fixity = Infixl { prec :: Int }
228 | Infixr { prec :: Int }
229 | InfixN { prec :: Int }
230 | PrefixN { prec :: Int }
231 deriving Eq
232{-!
233deriving instance Binary Fixity
234!-}
236instance Show Fixity where
237 show (Infixl i) = "infixl " ++ show i
238 show (Infixr i) = "infixr " ++ show i
239 show (InfixN i) = "infix " ++ show i
240 show (PrefixN i) = "prefix " ++ show i
242data FixDecl = Fix Fixity String
243 deriving Eq
245instance Show FixDecl where
246 show (Fix f s) = show f ++ " " ++ s
248{-!
249deriving instance Binary FixDecl
250!-}
252instance Ord FixDecl where
253 compare (Fix x _) (Fix y _) = compare (prec x) (prec y)
256data Static = Static | Dynamic
257 deriving (Show, Eq)
258{-!
259deriving instance Binary Static
260!-}
262-- Mark bindings with their explicitness, and laziness
263data Plicity = Imp { plazy :: Bool,
264 pstatic :: Static,
265 pdocstr :: String }
266 | Exp { plazy :: Bool,
267 pstatic :: Static,
268 pdocstr :: String }
269 | Constraint { plazy :: Bool,
270 pstatic :: Static,
271 pdocstr :: String }
272 | TacImp { plazy :: Bool,
273 pstatic :: Static,
274 pscript :: PTerm,
275 pdocstr :: String }
276 deriving (Show, Eq)
278{-!
279deriving instance Binary Plicity
280!-}
282impl = Imp False Dynamic ""
283expl = Exp False Dynamic ""
284constraint = Constraint False Dynamic ""
285tacimpl t = TacImp False Dynamic t ""
287data FnOpt = Inlinable | TotalFn | PartialFn
288 | Coinductive | AssertTotal | TCGen
289 | Implicit -- implicit coercion
290 | CExport String -- export, with a C name
291 | Specialise [Name] -- specialise it, freeze these names
292 deriving (Show, Eq)
293{-!
294deriving instance Binary FnOpt
295!-}
297type FnOpts = [FnOpt]
299inlinable :: FnOpts -> Bool
300inlinable = elem Inlinable
302-- | Top-level declarations such as compiler directives, definitions,
303-- datatypes and typeclasses.
304data PDecl' t
305 = PFix FC Fixity [String] -- ^ Fixity declaration
306 | PTy String SyntaxInfo FC FnOpts Name t -- ^ Type declaration
307 | PPostulate String SyntaxInfo FC FnOpts Name t -- ^ Postulate
308 | PClauses FC FnOpts Name [PClause' t] -- ^ Pattern clause
309 | PCAF FC Name t -- ^ Top level constant
310 | PData String SyntaxInfo FC Bool (PData' t) -- ^ Data declaration. The Bool argument is True for codata.
311 | PParams FC [(Name, t)] [PDecl' t] -- ^ Params block
312 | PNamespace String [PDecl' t] -- ^ New namespace
313 | PRecord String SyntaxInfo FC Name t String Name t -- ^ Record declaration
314 | PClass String SyntaxInfo FC
315 [t] -- constraints
316 Name
317 [(Name, t)] -- parameters
318 [PDecl' t] -- declarations
319 -- ^ Type class: arguments are documentation, syntax info, source location, constraints,
320 -- class name, parameters, method declarations
321 | PInstance SyntaxInfo FC [t] -- constraints
322 Name -- class
323 [t] -- parameters
324 t -- full instance type
325 (Maybe Name) -- explicit name
326 [PDecl' t]
327 -- ^ Instance declaration: arguments are syntax info, source location, constraints,
328 -- class name, parameters, full instance type, optional explicit name, and definitions
329 | PDSL Name (DSL' t) -- ^ DSL declaration
330 | PSyntax FC Syntax -- ^ Syntax definition
331 | PMutual FC [PDecl' t] -- ^ Mutual block
332 | PDirective (Idris ()) -- ^ Compiler directive. The parser inserts the corresponding action in the Idris monad.
333 deriving Functor
334{-!
335deriving instance Binary PDecl'
336!-}
338data PClause' t = PClause FC Name t [t] t [PDecl' t]
339 | PWith FC Name t [t] t [PDecl' t]
340 | PClauseR FC [t] t [PDecl' t]
341 | PWithR FC [t] t [PDecl' t]
342 deriving Functor
343{-!
344deriving instance Binary PClause'
345!-}
347-- | Data declaration
348data PData' t = PDatadecl { d_name :: Name, -- ^ The name of the datatype
349 d_tcon :: t, -- ^ Type constructor
350 d_cons :: [(String, Name, t, FC)] -- ^ Constructors
351 }
352 -- ^ Data declaration
353 | PLaterdecl { d_name :: Name, d_tcon :: t }
354 -- ^ "Placeholder" for data whose constructors are defined later
355 deriving Functor
356{-!
357deriving instance Binary PData'
358!-}
360-- Handy to get a free function for applying PTerm -> PTerm functions
361-- across a program, by deriving Functor
363type PDecl = PDecl' PTerm
364type PData = PData' PTerm
365type PClause = PClause' PTerm
367-- get all the names declared in a decl
369declared :: PDecl -> [Name]
370declared (PFix _ _ _) = []
371declared (PTy _ _ _ _ n t) = [n]
372declared (PPostulate _ _ _ _ n t) = [n]
373declared (PClauses _ _ n _) = [] -- not a declaration
374declared (PRecord _ _ _ n _ _ c _) = [n, c]
375declared (PData _ _ _ _ (PDatadecl n _ ts)) = n : map fstt ts
376 where fstt (_, a, _, _) = a
377declared (PParams _ _ ds) = concatMap declared ds
378declared (PMutual _ ds) = concatMap declared ds
379declared (PNamespace _ ds) = concatMap declared ds
381-- get the names declared, not counting nested parameter blocks
382tldeclared :: PDecl -> [Name]
383tldeclared (PFix _ _ _) = []
384tldeclared (PTy _ _ _ _ n t) = [n]
385tldeclared (PPostulate _ _ _ _ n t) = [n]
386tldeclared (PClauses _ _ n _) = [] -- not a declaration
387tldeclared (PRecord _ _ _ n _ _ c _) = [n, c]
388tldeclared (PData _ _ _ _ (PDatadecl n _ ts)) = n : map fstt ts
389 where fstt (_, a, _, _) = a
390tldeclared (PParams _ _ ds) = []
391tldeclared (PMutual _ ds) = concatMap tldeclared ds
392tldeclared (PNamespace _ ds) = concatMap tldeclared ds
393-- declared (PImport _) = []
395defined :: PDecl -> [Name]
396defined (PFix _ _ _) = []
397defined (PTy _ _ _ _ n t) = []
398defined (PPostulate _ _ _ _ n t) = []
399defined (PClauses _ _ n _) = [n] -- not a declaration
400defined (PRecord _ _ _ n _ _ c _) = [n, c]
401defined (PData _ _ _ _ (PDatadecl n _ ts)) = n : map fstt ts
402 where fstt (_, a, _, _) = a
403defined (PParams _ _ ds) = concatMap defined ds
404defined (PMutual _ ds) = concatMap defined ds
405defined (PNamespace _ ds) = concatMap defined ds
406-- declared (PImport _) = []
408updateN :: [(Name, Name)] -> Name -> Name
409updateN ns n | Just n' <- lookup n ns = n'
410updateN _ n = n
412updateNs :: [(Name, Name)] -> PTerm -> PTerm
413updateNs [] t = t
414updateNs ns t = mapPT updateRef t
415 where updateRef (PRef fc f) = PRef fc (updateN ns f)
416 updateRef t = t
418-- updateDNs :: [(Name, Name)] -> PDecl -> PDecl
419-- updateDNs [] t = t
420-- updateDNs ns (PTy s f n t) | Just n' <- lookup n ns = PTy s f n' t
421-- updateDNs ns (PClauses f n c) | Just n' <- lookup n ns = PClauses f n' (map updateCNs c)
422-- where updateCNs ns (PClause n l ts r ds)
423-- = PClause (updateN ns n) (fmap (updateNs ns) l)
424-- (map (fmap (updateNs ns)) ts)
425-- (fmap (updateNs ns) r)
426-- (map (updateDNs ns) ds)
427-- updateDNs ns c = c
429-- | High level language terms
430data PTerm = PQuote Raw
431 | PRef FC Name
432 | PInferRef FC Name -- ^ A name to be defined later
433 | PPatvar FC Name
434 | PLam Name PTerm PTerm
435 | PPi Plicity Name PTerm PTerm
436 | PLet Name PTerm PTerm PTerm
437 | PTyped PTerm PTerm -- ^ Term with explicit type
438 | PApp FC PTerm [PArg]
439 | PCase FC PTerm [(PTerm, PTerm)]
440 | PTrue FC
441 | PFalse FC
442 | PRefl FC PTerm
443 | PResolveTC FC
444 | PEq FC PTerm PTerm
445 | PPair FC PTerm PTerm
446 | PDPair FC PTerm PTerm PTerm
447 | PAlternative Bool [PTerm] -- True if only one may work
448 | PHidden PTerm -- ^ Irrelevant or hidden pattern
449 | PType
450 | PConstant Const
451 | Placeholder
452 | PDoBlock [PDo]
453 | PIdiom FC PTerm
454 | PReturn FC
455 | PMetavar Name
456 | PProof [PTactic] -- ^ Proof script
457 | PTactics [PTactic] -- ^ As PProof, but no auto solving
458 | PElabError Err -- ^ Error to report on elaboration
459 | PImpossible -- ^ Special case for declaring when an LHS can't typecheck
460 | PCoerced PTerm -- ^ To mark a coerced argument, so as not to coerce twice
461 deriving Eq
462{-!
463deriving instance Binary PTerm
464!-}
466mapPT :: (PTerm -> PTerm) -> PTerm -> PTerm
467mapPT f t = f (mpt t) where
468 mpt (PLam n t s) = PLam n (mapPT f t) (mapPT f s)
469 mpt (PPi p n t s) = PPi p n (mapPT f t) (mapPT f s)
470 mpt (PLet n ty v s) = PLet n (mapPT f ty) (mapPT f v) (mapPT f s)
471 mpt (PApp fc t as) = PApp fc (mapPT f t) (map (fmap (mapPT f)) as)
472 mpt (PCase fc c os) = PCase fc (mapPT f c) (map (pmap (mapPT f)) os)
473 mpt (PEq fc l r) = PEq fc (mapPT f l) (mapPT f r)
474 mpt (PTyped l r) = PTyped (mapPT f l) (mapPT f r)
475 mpt (PPair fc l r) = PPair fc (mapPT f l) (mapPT f r)
476 mpt (PDPair fc l t r) = PDPair fc (mapPT f l) (mapPT f t) (mapPT f r)
477 mpt (PAlternative a as) = PAlternative a (map (mapPT f) as)
478 mpt (PHidden t) = PHidden (mapPT f t)
479 mpt (PDoBlock ds) = PDoBlock (map (fmap (mapPT f)) ds)
480 mpt (PProof ts) = PProof (map (fmap (mapPT f)) ts)
481 mpt (PTactics ts) = PTactics (map (fmap (mapPT f)) ts)
482 mpt x = x
485data PTactic' t = Intro [Name] | Intros | Focus Name
486 | Refine Name [Bool] | Rewrite t
487 | LetTac Name t | LetTacTy Name t t
488 | Exact t | Compute | Trivial
489 | Solve
490 | Attack
491 | ProofState | ProofTerm | Undo
492 | Try (PTactic' t) (PTactic' t)
493 | TSeq (PTactic' t) (PTactic' t)
494 | ReflectTac t -- see Language.Reflection module
495 | GoalType String (PTactic' t)
496 | Qed | Abandon
497 deriving (Show, Eq, Functor)
498{-!
499deriving instance Binary PTactic'
500!-}
502instance Sized a => Sized (PTactic' a) where
503 size (Intro nms) = 1 + size nms
504 size Intros = 1
505 size (Focus nm) = 1 + size nm
506 size (Refine nm bs) = 1 + size nm + length bs
507 size (Rewrite t) = 1 + size t
508 size (LetTac nm t) = 1 + size nm + size t
509 size (Exact t) = 1 + size t
510 size Compute = 1
511 size Trivial = 1
512 size Solve = 1
513 size Attack = 1
514 size ProofState = 1
515 size ProofTerm = 1
516 size Undo = 1
517 size (Try l r) = 1 + size l + size r
518 size (TSeq l r) = 1 + size l + size r
519 size Qed = 1
520 size Abandon = 1
522type PTactic = PTactic' PTerm
524data PDo' t = DoExp FC t
525 | DoBind FC Name t
526 | DoBindP FC t t
527 | DoLet FC Name t t
528 | DoLetP FC t t
529 deriving (Eq, Functor)
530{-!
531deriving instance Binary PDo'
532!-}
534instance Sized a => Sized (PDo' a) where
535 size (DoExp fc t) = 1 + size fc + size t
536 size (DoBind fc nm t) = 1 + size fc + size nm + size t
537 size (DoBindP fc l r) = 1 + size fc + size l + size r
538 size (DoLet fc nm l r) = 1 + size fc + size nm + size l + size r
539 size (DoLetP fc l r) = 1 + size fc + size l + size r
541type PDo = PDo' PTerm
543-- The priority gives a hint as to elaboration order. Best to elaborate
544-- things early which will help give a more concrete type to other
545-- variables, e.g. a before (interpTy a).
546-- TODO: priority no longer serves any purpose, drop it!
548data PArg' t = PImp { priority :: Int,
549 lazyarg :: Bool, pname :: Name, getTm :: t,
550 pargdoc :: String }
551 | PExp { priority :: Int,
552 lazyarg :: Bool, getTm :: t,
553 pargdoc :: String }
554 | PConstraint { priority :: Int,
555 lazyarg :: Bool, getTm :: t,
556 pargdoc :: String }
557 | PTacImplicit { priority :: Int,
558 lazyarg :: Bool, pname :: Name,
559 getScript :: t,
560 getTm :: t,
561 pargdoc :: String }
562 deriving (Show, Eq, Functor)
564instance Sized a => Sized (PArg' a) where
565 size (PImp p l nm trm _) = 1 + size nm + size trm
566 size (PExp p l trm _) = 1 + size trm
567 size (PConstraint p l trm _) = 1 + size trm
568 size (PTacImplicit p l nm scr trm _) = 1 + size nm + size scr + size trm
570{-!
571deriving instance Binary PArg'
572!-}
574pimp n t = PImp 0 True n t ""
575pexp t = PExp 0 False t ""
576pconst t = PConstraint 0 False t ""
577ptacimp n s t = PTacImplicit 0 True n s t ""
579type PArg = PArg' PTerm
581-- Type class data
583data ClassInfo = CI { instanceName :: Name,
584 class_methods :: [(Name, (FnOpts, PTerm))],
585 class_defaults :: [(Name, (Name, PDecl))], -- method name -> default impl
586 class_params :: [Name],
587 class_instances :: [Name] }
588 deriving Show
589{-!
590deriving instance Binary ClassInfo
591!-}
593data OptInfo = Optimise { collapsible :: Bool,
594 forceable :: [Int], -- argument positions
595 recursive :: [Int] }
596 deriving Show
597{-!
598deriving instance Binary OptInfo
599!-}
602data TypeInfo = TI { con_names :: [Name],
603 codata :: Bool,
604 param_pos :: [Int] }
605 deriving Show
606{-!
607deriving instance Binary TypeInfo
608!-}
610-- Syntactic sugar info
612data DSL' t = DSL { dsl_bind :: t,
613 dsl_return :: t,
614 dsl_apply :: t,
615 dsl_pure :: t,
616 dsl_var :: Maybe t,
617 index_first :: Maybe t,
618 index_next :: Maybe t,
619 dsl_lambda :: Maybe t,
620 dsl_let :: Maybe t
621 }
622 deriving (Show, Functor)
623{-!
624deriving instance Binary DSL'
625!-}
627type DSL = DSL' PTerm
629data SynContext = PatternSyntax | TermSyntax | AnySyntax
630 deriving Show
631{-!
632deriving instance Binary SynContext
633!-}
635data Syntax = Rule [SSymbol] PTerm SynContext
636 deriving Show
637{-!
638deriving instance Binary Syntax
639!-}
641data SSymbol = Keyword Name
642 | Symbol String
643 | Binding Name
644 | Expr Name
645 | SimpleExpr Name
646 deriving Show
647{-!
648deriving instance Binary SSymbol
649!-}
651initDSL = DSL (PRef f (UN ">>="))
652 (PRef f (UN "return"))
653 (PRef f (UN "<$>"))
654 (PRef f (UN "pure"))
655 Nothing
656 Nothing
657 Nothing
658 Nothing
659 Nothing
660 where f = FC "(builtin)" 0
662data SyntaxInfo = Syn { using :: [(Name, PTerm)],
663 syn_params :: [(Name, PTerm)],
664 syn_namespace :: [String],
665 no_imp :: [Name],
666 decoration :: Name -> Name,
667 inPattern :: Bool,
668 implicitAllowed :: Bool,
669 dsl_info :: DSL }
670 deriving Show
671{-!
672deriving instance Binary SyntaxInfo
673!-}
675defaultSyntax = Syn [] [] [] [] id False False initDSL
677expandNS :: SyntaxInfo -> Name -> Name
678expandNS syn n@(NS _ _) = n
679expandNS syn n = case syn_namespace syn of
680 [] -> n
681 xs -> NS n xs
684--- Pretty printing declarations and terms
686instance Show PTerm where
687 show tm = showImp False tm
689instance Pretty PTerm where
690 pretty = prettyImp False
692instance Show PDecl where
693 show d = showDeclImp False d
695instance Show PClause where
696 show c = showCImp True c
698instance Show PData where
699 show d = showDImp False d
701showDeclImp _ (PFix _ f ops) = show f ++ " " ++ showSep ", " ops
702showDeclImp t (PTy _ _ _ _ n ty) = show n ++ " : " ++ showImp t ty
703showDeclImp t (PPostulate _ _ _ _ n ty) = show n ++ " : " ++ showImp t ty
704showDeclImp _ (PClauses _ _ n c) = showSep "\n" (map show c)
705showDeclImp _ (PData _ _ _ _ d) = show d
706showDeclImp _ (PParams f ns ps) = "parameters " ++ show ns ++ "\n" ++
707 showSep "\n" (map show ps)
710showCImp :: Bool -> PClause -> String
711showCImp impl (PClause _ n l ws r w)
712 = showImp impl l ++ showWs ws ++ " = " ++ showImp impl r
713 ++ " where " ++ show w
714 where
715 showWs [] = ""
716 showWs (x : xs) = " | " ++ showImp impl x ++ showWs xs
717showCImp impl (PWith _ n l ws r w)
718 = showImp impl l ++ showWs ws ++ " with " ++ showImp impl r
719 ++ " { " ++ show w ++ " } "
720 where
721 showWs [] = ""
722 showWs (x : xs) = " | " ++ showImp impl x ++ showWs xs
725showDImp :: Bool -> PData -> String
726showDImp impl (PDatadecl n ty cons)
727 = "data " ++ show n ++ " : " ++ showImp impl ty ++ " where\n\t"
728 ++ showSep "\n\t| "
729 (map (\ (_, n, t, _) -> show n ++ " : " ++ showImp impl t) cons)
731getImps :: [PArg] -> [(Name, PTerm)]
732getImps [] = []
733getImps (PImp _ _ n tm _ : xs) = (n, tm) : getImps xs
734getImps (_ : xs) = getImps xs
736getExps :: [PArg] -> [PTerm]
737getExps [] = []
738getExps (PExp _ _ tm _ : xs) = tm : getExps xs
739getExps (_ : xs) = getExps xs
741getConsts :: [PArg] -> [PTerm]
742getConsts [] = []
743getConsts (PConstraint _ _ tm _ : xs) = tm : getConsts xs
744getConsts (_ : xs) = getConsts xs
746getAll :: [PArg] -> [PTerm]
747getAll = map getTm
749prettyImp :: Bool -> PTerm -> Doc
750prettyImp impl = prettySe 10
751 where
752 prettySe p (PQuote r) =
753 if size r > breakingSize then
754 text "![" $$ pretty r <> text "]"
755 else
756 text "![" <> pretty r <> text "]"
757 prettySe p (PPatvar fc n) = pretty n
758 prettySe p (PRef fc n) =
759 if impl then
760 pretty n
761 else
762 prettyBasic n
763 where
764 prettyBasic n@(UN _) = pretty n
765 prettyBasic (MN _ s) = text s
766 prettyBasic (NS n s) = (foldr (<>) empty (intersperse (text ".") (map text $ reverse s))) <> prettyBasic n
767 prettySe p (PLam n ty sc) =
768 bracket p 2 $
769 if size sc > breakingSize then
770 text "λ" <> pretty n <+> text "=>" $+$ pretty sc
771 else
772 text "λ" <> pretty n <+> text "=>" <+> pretty sc
773 prettySe p (PLet n ty v sc) =
774 bracket p 2 $
775 if size sc > breakingSize then
776 text "let" <+> pretty n <+> text "=" <+> prettySe 10 v <+> text "in" $+$
777 nest nestingSize (prettySe 10 sc)
778 else
779 text "let" <+> pretty n <+> text "=" <+> prettySe 10 v <+> text "in" <+>
780 prettySe 10 sc
781 prettySe p (PPi (Exp l s _) n ty sc)
782 | n `elem` allNamesIn sc || impl =
783 let open = if l then text "|" <> lparen else lparen in
784 bracket p 2 $
785 if size sc > breakingSize then
786 open <> pretty n <+> colon <+> prettySe 10 ty <> rparen <+>
787 st <+> text "->" $+$ prettySe 10 sc
788 else
789 open <> pretty n <+> colon <+> prettySe 10 ty <> rparen <+>
790 st <+> text "->" <+> prettySe 10 sc
791 | otherwise =
792 bracket p 2 $
793 if size sc > breakingSize then
794 prettySe 0 ty <+> st <+> text "->" $+$ prettySe 10 sc
795 else
796 prettySe 0 ty <+> st <+> text "->" <+> prettySe 10 sc
797 where
798 st =
799 case s of
800 Static -> text "[static]"
801 _ -> empty
802 prettySe p (PPi (Imp l s _) n ty sc)
803 | impl =
804 let open = if l then text "|" <> lbrace else lbrace in
805 bracket p 2 $
806 if size sc > breakingSize then
807 open <> pretty n <+> colon <+> prettySe 10 ty <> rbrace <+>
808 st <+> text "->" <+> prettySe 10 sc
809 else
810 open <> pretty n <+> colon <+> prettySe 10 ty <> rbrace <+>
811 st <+> text "->" <+> prettySe 10 sc
812 | otherwise = prettySe 10 sc
813 where
814 st =
815 case s of
816 Static -> text $ "[static]"
817 _ -> empty
818 prettySe p (PPi (Constraint _ _ _) n ty sc) =
819 bracket p 2 $
820 if size sc > breakingSize then
821 prettySe 10 ty <+> text "=>" <+> prettySe 10 sc
822 else
823 prettySe 10 ty <+> text "=>" $+$ prettySe 10 sc
824 prettySe p (PPi (TacImp _ _ s _) n ty sc) =
825 bracket p 2 $
826 if size sc > breakingSize then
827 lbrace <> text "tacimp" <+> pretty n <+> colon <+> prettySe 10 ty <>
828 rbrace <+> text "->" $+$ prettySe 10 sc
829 else
830 lbrace <> text "tacimp" <+> pretty n <+> colon <+> prettySe 10 ty <>
831 rbrace <+> text "->" <+> prettySe 10 sc
832 prettySe p (PApp _ (PRef _ f) [])
833 | not impl = pretty f
834 prettySe p (PApp _ (PRef _ op@(UN (f:_))) args)
835 | length (getExps args) == 2 && (not impl) && (not $ isAlpha f) =
836 let [l, r] = getExps args in
837 bracket p 1 $
838 if size r > breakingSize then
839 prettySe 1 l <+> pretty op $+$ prettySe 0 r
840 else
841 prettySe 1 l <+> pretty op <+> prettySe 0 r
842 prettySe p (PApp _ f as) =
843 let args = getExps as in
844 bracket p 1 $
845 prettySe 1 f <+>
846 if impl then
847 foldl fS empty as
848 -- foldr (<+>) empty $ map prettyArgS as
849 else
850 foldl fSe empty args
851 -- foldr (<+>) empty $ map prettyArgSe args
852 where
853 fS l r =
854 if size r > breakingSize then
855 l $+$ nest nestingSize (prettyArgS r)
856 else
857 l <+> prettyArgS r
859 fSe l r =
860 if size r > breakingSize then
861 l $+$ nest nestingSize (prettyArgSe r)
862 else
863 l <+> prettyArgSe r
864 prettySe p (PCase _ scr opts) =
865 text "case" <+> prettySe 10 scr <+> text "of" $+$ nest nestingSize prettyBody
866 where
867 prettyBody = foldr ($$) empty $ intersperse (text "|") $ map sc opts
869 sc (l, r) = prettySe 10 l <+> text "=>" <+> prettySe 10 r
870 prettySe p (PHidden tm) = text "." <> prettySe 0 tm
871 prettySe p (PRefl _ _) = text "refl"
872 prettySe p (PResolveTC _) = text "resolvetc"
873 prettySe p (PTrue _) = text "()"
874 prettySe p (PFalse _) = text "_|_"
875 prettySe p (PEq _ l r) =
876 bracket p 2 $
877 if size r > breakingSize then
878 prettySe 10 l <+> text "=" $$ nest nestingSize (prettySe 10 r)
879 else
880 prettySe 10 l <+> text "=" <+> prettySe 10 r
881 prettySe p (PTyped l r) =
882 lparen <> prettySe 10 l <+> colon <+> prettySe 10 r <> rparen
883 prettySe p (PPair _ l r) =
884 if size r > breakingSize then
885 lparen <> prettySe 10 l <> text "," $+$
886 prettySe 10 r <> rparen
887 else
888 lparen <> prettySe 10 l <> text "," <+> prettySe 10 r <> rparen
889 prettySe p (PDPair _ l t r) =
890 if size r > breakingSize then
891 lparen <> prettySe 10 l <+> text "**" $+$
892 prettySe 10 r <> rparen
893 else
894 lparen <> prettySe 10 l <+> text "**" <+> prettySe 10 r <> rparen
895 prettySe p (PAlternative a as) =
896 lparen <> text "|" <> prettyAs <> text "|" <> rparen
897 where
898 prettyAs =
899 foldr (\l -> \r -> l <+> text "," <+> r) empty $ map (prettySe 10) as
900 prettySe p PType = text "Type"
901 prettySe p (PConstant c) = pretty c
902 -- XXX: add pretty for tactics
903 prettySe p (PProof ts) =
904 text "proof" <+> lbrace $+$ nest nestingSize (text . show $ ts) $+$ rbrace
905 prettySe p (PTactics ts) =
906 text "tactics" <+> lbrace $+$ nest nestingSize (text . show $ ts) $+$ rbrace
907 prettySe p (PMetavar n) = text "?" <> pretty n
908 prettySe p (PReturn f) = text "return"
909 prettySe p PImpossible = text "impossible"
910 prettySe p Placeholder = text "_"
911 prettySe p (PDoBlock _) = text "do block pretty not implemented"
912 prettySe p (PElabError s) = pretty s
914 prettySe p _ = text "test"
916 prettyArgS (PImp _ _ n tm _) = prettyArgSi (n, tm)
917 prettyArgS (PExp _ _ tm _) = prettyArgSe tm
918 prettyArgS (PConstraint _ _ tm _) = prettyArgSc tm
919 prettyArgS (PTacImplicit _ _ n _ tm _) = prettyArgSti (n, tm)
921 prettyArgSe arg = prettySe 0 arg
922 prettyArgSi (n, val) = lbrace <> pretty n <+> text "=" <+> prettySe 10 val <> rbrace
923 prettyArgSc val = lbrace <> lbrace <> prettySe 10 val <> rbrace <> rbrace
924 prettyArgSti (n, val) = lbrace <> text "auto" <+> pretty n <+> text "=" <+> prettySe 10 val <> rbrace
926 bracket outer inner doc
927 | inner > outer = lparen <> doc <> rparen
928 | otherwise = doc
930showImp :: Bool -> PTerm -> String
931showImp impl tm = se 10 tm where
932 se p (PQuote r) = "![" ++ show r ++ "]"
933 se p (PPatvar fc n) = show n
934 se p (PInferRef fc n) = "!" ++ show n -- ++ "[" ++ show fc ++ "]"
935 se p (PRef fc n) = if impl then show n -- ++ "[" ++ show fc ++ "]"
936 else showbasic n
937 where showbasic n@(UN _) = show n
938 showbasic (MN _ s) = s
939 showbasic (NS n s) = showSep "." (reverse s) ++ "." ++ showbasic n
940 se p (PLam n ty sc) = bracket p 2 $ "\\ " ++ show n ++
941 (if impl then " : " ++ se 10 ty else "") ++ " => "
942 ++ se 10 sc
943 se p (PLet n ty v sc) = bracket p 2 $ "let " ++ show n ++ " = " ++ se 10 v ++
944 " in " ++ se 10 sc
945 se p (PPi (Exp l s _) n ty sc)
946 | n `elem` allNamesIn sc || impl
947 = bracket p 2 $
948 (if l then "|(" else "(") ++
949 show n ++ " : " ++ se 10 ty ++
950 ") " ++ st ++
951 "-> " ++ se 10 sc
952 | otherwise = bracket p 2 $ se 0 ty ++ " " ++ st ++ "-> " ++ se 10 sc
953 where st = case s of
954 Static -> "[static] "
955 _ -> ""
956 se p (PPi (Imp l s _) n ty sc)
957 | impl = bracket p 2 $ (if l then "|{" else "{") ++
958 show n ++ " : " ++ se 10 ty ++
959 "} " ++ st ++ "-> " ++ se 10 sc
960 | otherwise = se 10 sc
961 where st = case s of
962 Static -> "[static] "
963 _ -> ""
964 se p (PPi (Constraint _ _ _) n ty sc)
965 = bracket p 2 $ se 10 ty ++ " => " ++ se 10 sc
966 se p (PPi (TacImp _ _ s _) n ty sc)
967 = bracket p 2 $ "{tacimp " ++ show n ++ " : " ++ se 10 ty ++ "} -> " ++ se 10 sc
968 se p (PApp _ (PRef _ f) [])
969 | not impl = show f
970 se p (PApp _ (PRef _ op@(UN (f:_))) args)
971 | length (getExps args) == 2 && not impl && not (isAlpha f)
972 = let [l, r] = getExps args in
973 bracket p 1 $ se 1 l ++ " " ++ show op ++ " " ++ se 0 r
974 se p (PApp _ f as)
975 = let args = getExps as in
976 bracket p 1 $ se 1 f ++ if impl then concatMap sArg as
977 else concatMap seArg args
978 se p (PCase _ scr opts) = "case " ++ se 10 scr ++ " of " ++ showSep " | " (map sc opts)
979 where sc (l, r) = se 10 l ++ " => " ++ se 10 r
980 se p (PHidden tm) = "." ++ se 0 tm
981 se p (PRefl _ t)
982 | not impl = "refl"
983 | otherwise = "refl {" ++ se 10 t ++ "}"
984 se p (PResolveTC _) = "resolvetc"
985 se p (PTrue _) = "()"
986 se p (PFalse _) = "_|_"
987 se p (PEq _ l r) = bracket p 2 $ se 10 l ++ " = " ++ se 10 r
988 se p (PTyped l r) = "(" ++ se 10 l ++ " : " ++ se 10 r ++ ")"
989 se p (PPair _ l r) = "(" ++ se 10 l ++ ", " ++ se 10 r ++ ")"
990 se p (PDPair _ l t r) = "(" ++ se 10 l ++ " ** " ++ se 10 r ++ ")"
991 se p (PAlternative a as) = "(|" ++ showSep " , " (map (se 10) as) ++ "|)"
992 se p PType = "Type"
993 se p (PConstant c) = show c
994 se p (PProof ts) = "proof { " ++ show ts ++ "}"
995 se p (PTactics ts) = "tactics { " ++ show ts ++ "}"
996 se p (PMetavar n) = "?" ++ show n
997 se p (PReturn f) = "return"
998 se p PImpossible = "impossible"
999 se p Placeholder = "_"
1000 se p (PDoBlock _) = "do block show not implemented"
1001 se p (PElabError s) = show s
1002 se p (PCoerced t) = se p t
1003-- se p x = "Not implemented"
1005 sArg (PImp _ _ n tm _) = siArg (n, tm)
1006 sArg (PExp _ _ tm _) = seArg tm
1007 sArg (PConstraint _ _ tm _) = scArg tm
1008 sArg (PTacImplicit _ _ n _ tm _) = stiArg (n, tm)
1010 seArg arg = " " ++ se 0 arg
1011 siArg (n, val) = " {" ++ show n ++ " = " ++ se 10 val ++ "}"
1012 scArg val = " {{" ++ se 10 val ++ "}}"
1013 stiArg (n, val) = " {auto " ++ show n ++ " = " ++ se 10 val ++ "}"
1015 bracket outer inner str | inner > outer = "(" ++ str ++ ")"
1016 | otherwise = str
1019instance Sized PTerm where
1020 size (PQuote rawTerm) = size rawTerm
1021 size (PRef fc name) = size name
1022 size (PLam name ty bdy) = 1 + size ty + size bdy
1023 size (PPi plicity name ty bdy) = 1 + size ty + size bdy
1024 size (PLet name ty def bdy) = 1 + size ty + size def + size bdy
1025 size (PTyped trm ty) = 1 + size trm + size ty
1026 size (PApp fc name args) = 1 + size args
1027 size (PCase fc trm bdy) = 1 + size trm + size bdy
1028 size (PTrue fc) = 1
1029 size (PFalse fc) = 1
1030 size (PRefl fc _) = 1
1031 size (PResolveTC fc) = 1
1032 size (PEq fc left right) = 1 + size left + size right
1033 size (PPair fc left right) = 1 + size left + size right
1034 size (PDPair fs left ty right) = 1 + size left + size ty + size right
1035 size (PAlternative a alts) = 1 + size alts
1036 size (PHidden hidden) = size hidden
1037 size PType = 1
1038 size (PConstant const) = 1 + size const
1039 size Placeholder = 1
1040 size (PDoBlock dos) = 1 + size dos
1041 size (PIdiom fc term) = 1 + size term
1042 size (PReturn fc) = 1
1043 size (PMetavar name) = 1
1044 size (PProof tactics) = size tactics
1045 size (PElabError err) = size err
1046 size PImpossible = 1
1048getPArity :: PTerm -> Int
1049getPArity (PPi _ _ _ sc) = 1 + getPArity sc
1050getPArity _ = 0
1052-- Return all names, free or globally bound, in the given term.
1054allNamesIn :: PTerm -> [Name]
1055allNamesIn tm = nub $ ni [] tm
1056 where
1057 ni env (PRef _ n)
1058 | not (n `elem` env) = [n]
1059 ni env (PApp _ f as) = ni env f ++ concatMap (ni env) (map getTm as)
1060 ni env (PCase _ c os) = ni env c ++ concatMap (ni env) (map snd os)
1061 ni env (PLam n ty sc) = ni env ty ++ ni (n:env) sc
1062 ni env (PPi _ n ty sc) = ni env ty ++ ni (n:env) sc
1063 ni env (PHidden tm) = ni env tm
1064 ni env (PEq _ l r) = ni env l ++ ni env r
1065 ni env (PTyped l r) = ni env l ++ ni env r
1066 ni env (PPair _ l r) = ni env l ++ ni env r
1067 ni env (PDPair _ (PRef _ n) t r) = ni env t ++ ni (n:env) r
1068 ni env (PDPair _ l t r) = ni env l ++ ni env t ++ ni env r
1069 ni env (PAlternative a ls) = concatMap (ni env) ls
1070 ni env _ = []
1072-- Return names which are free in the given term.
1074namesIn :: [(Name, PTerm)] -> IState -> PTerm -> [Name]
1075namesIn uvars ist tm = nub $ ni [] tm
1076 where
1077 ni env (PRef _ n)
1078 | not (n `elem` env)
1079 = case lookupTy Nothing n (tt_ctxt ist) of
1080 [] -> [n]
1081 _ -> if n `elem` (map fst uvars) then [n] else []
1082 ni env (PApp _ f as) = ni env f ++ concatMap (ni env) (map getTm as)
1083 ni env (PCase _ c os) = ni env c ++ concatMap (ni env) (map snd os)
1084 ni env (PLam n ty sc) = ni env ty ++ ni (n:env) sc
1085 ni env (PPi _ n ty sc) = ni env ty ++ ni (n:env) sc
1086 ni env (PEq _ l r) = ni env l ++ ni env r
1087 ni env (PTyped l r) = ni env l ++ ni env r
1088 ni env (PPair _ l r) = ni env l ++ ni env r
1089 ni env (PDPair _ (PRef _ n) t r) = ni env t ++ ni (n:env) r
1090 ni env (PDPair _ l t r) = ni env l ++ ni env t ++ ni env r
1091 ni env (PAlternative a as) = concatMap (ni env) as
1092 ni env (PHidden tm) = ni env tm
1093 ni env _ = []
1095-- Return which of the given names are used in the given term.
1097usedNamesIn :: [Name] -> IState -> PTerm -> [Name]
1098usedNamesIn vars ist tm = nub $ ni [] tm
1099 where
1100 ni env (PRef _ n)
1101 | n `elem` vars && not (n `elem` env)
1102 = case lookupTy Nothing n (tt_ctxt ist) of
1103 [] -> [n]
1104 _ -> []
1105 ni env (PApp _ f as) = ni env f ++ concatMap (ni env) (map getTm as)
1106 ni env (PCase _ c os) = ni env c ++ concatMap (ni env) (map snd os)
1107 ni env (PLam n ty sc) = ni env ty ++ ni (n:env) sc
1108 ni env (PPi _ n ty sc) = ni env ty ++ ni (n:env) sc
1109 ni env (PEq _ l r) = ni env l ++ ni env r
1110 ni env (PTyped l r) = ni env l ++ ni env r
1111 ni env (PPair _ l r) = ni env l ++ ni env r
1112 ni env (PDPair _ (PRef _ n) t r) = ni env t ++ ni (n:env) r
1113 ni env (PDPair _ l t r) = ni env l ++ ni env t ++ ni env r
1114 ni env (PAlternative a as) = concatMap (ni env) as
1115 ni env (PHidden tm) = ni env tm
1116 ni env _ = []