6 | import public Libraries.Text.Parser
7 | import Libraries.Data.WithDefault
9 | withFC : (fname : OriginDesc) => Rule a -> Rule (WithFC a)
14 | pure (Mk [MkFC fname start end] parsed)
16 | topDecl : OriginDesc -> IndentInfo -> Rule ImpDecl
20 | collectDefs : List ImpDecl -> List ImpDecl
26 | %hide Core.Core.(>>=)
28 | %hide Core.Core.pure
30 | %hide Lexer.Core.(<|>)
33 | atom : OriginDesc -> Rule RawImp
35 | = do start <- location
38 | pure (IPrimVal (MkFC fname start end) x)
39 | <|> do start <- location
42 | pure (IPrimVal (MkFC fname start end) (Str str))
43 | <|> do start <- location
46 | pure (IType (MkFC fname start end))
47 | <|> do start <- location
50 | pure (Implicit (MkFC fname start end) True)
51 | <|> do start <- location
54 | pure (Implicit (MkFC fname start end) False)
55 | <|> do start <- location
58 | pure (ISearch (MkFC fname start end) 1000)
59 | <|> do start <- location
62 | pure (IVar (MkFC fname start end) x)
63 | <|> do start <- location
67 | pure (IBindVar (MkFC fname start end) x)
68 | <|> do start <- location
71 | pure (IHole (MkFC fname start end) x)
73 | visOption : Rule Visibility
75 | = do keyword "public"
78 | <|> do keyword "export"
80 | <|> do keyword "private"
83 | visibility : EmptyRule (WithDefault Visibility Private)
85 | = (specified <$> visOption)
88 | totalityOpt : Rule TotalReq
90 | = do keyword "partial"
92 | <|> do keyword "total"
94 | <|> do keyword "covering"
97 | dataVisOpt : EmptyRule (WithDefault Visibility Private, Maybe TotalReq)
99 | = do {
vis <- visOption ;
mbtot <- optional totalityOpt ;
pure (specified vis, mbtot) }
100 | <|> do {
tot <- totalityOpt ;
vis <- visibility ;
pure (vis, Just tot) }
101 | <|> pure (defaulted, Nothing)
104 | fnOpt = do x <- totalityOpt
107 | fnDirectOpt : Rule FnOpt
111 | <|> do pragma "chaser"
113 | <|> do pragma "globalhint"
114 | pure (GlobalHint True)
115 | <|> do pragma "defaulthint"
116 | pure (GlobalHint False)
117 | <|> do pragma "inline"
119 | <|> do pragma "noinline"
121 | <|> do pragma "deprecate"
123 | <|> do pragma "extern"
126 | visOpt : Rule (Either Visibility FnOpt)
128 | = do vis <- visOption
130 | <|> do tot <- fnOpt
132 | <|> do opt <- fnDirectOpt
135 | getVisibility : Maybe Visibility -> List (Either Visibility FnOpt) ->
136 | EmptyRule Visibility
137 | getVisibility Nothing [] = pure Private
138 | getVisibility (Just vis) [] = pure vis
139 | getVisibility Nothing (Left x :: xs) = getVisibility (Just x) xs
140 | getVisibility (Just vis) (Left x :: xs)
141 | = fatalError "Multiple visibility modifiers"
142 | getVisibility v (_ :: xs) = getVisibility v xs
144 | getRight : Either a b -> Maybe b
145 | getRight (Left _) = Nothing
146 | getRight (Right v) = Just v
148 | bindSymbol : Rule (PiInfo RawImp)
156 | appExpr : OriginDesc -> IndentInfo -> Rule RawImp
157 | appExpr fname indents
158 | = case_ fname indents
159 | <|> lazy fname indents
160 | <|> do start <- location
161 | f <- simpleExpr fname indents
162 | args <- many (argExpr fname indents)
164 | pure (applyExpImp start end f args)
166 | applyExpImp : FilePos -> FilePos ->
167 | RawImp -> List (Either RawImp (Maybe Name, RawImp)) ->
169 | applyExpImp start end f [] = f
170 | applyExpImp start end f (Left exp :: args)
171 | = applyExpImp start end (IApp (MkFC fname start end) f exp) args
172 | applyExpImp start end f (Right (Just n, imp) :: args)
173 | = applyExpImp start end (INamedApp (MkFC fname start end) f n imp) args
174 | applyExpImp start end f (Right (Nothing, imp) :: args)
175 | = applyExpImp start end (IAutoApp (MkFC fname start end) f imp) args
177 | argExpr : OriginDesc -> IndentInfo ->
178 | Rule (Either RawImp (Maybe Name, RawImp))
179 | argExpr fname indents
180 | = do continue indents
181 | arg <- simpleExpr fname indents
183 | <|> do continue indents
184 | arg <- implicitArg fname indents
187 | implicitArg : OriginDesc -> IndentInfo -> Rule (Maybe Name, RawImp)
188 | implicitArg fname indents
189 | = do start <- location
194 | tm <- expr fname indents
199 | pure (Just x, IVar (MkFC fname start end) x))
202 | tm <- expr fname indents
206 | as : OriginDesc -> IndentInfo -> Rule RawImp
208 | = do start <- location
210 | nameEnd <- location
212 | pat <- simpleExpr fname indents
214 | pure (IAs (MkFC fname start end) (MkFC fname start nameEnd) UseRight x pat)
216 | simpleExpr : OriginDesc -> IndentInfo -> Rule RawImp
217 | simpleExpr fname indents
220 | <|> binder fname indents
221 | <|> rewrite_ fname indents
222 | <|> record_ fname indents
224 | e <- expr fname indents
228 | multiplicity : EmptyRule (Maybe Integer)
234 | getMult : Maybe Integer -> EmptyRule RigCount
235 | getMult (Just 0) = pure erased
236 | getMult (Just 1) = pure linear
237 | getMult Nothing = pure top
238 | getMult _ = fatalError "Invalid multiplicity (must be 0 or 1)"
240 | pibindAll : FC -> PiInfo RawImp -> List (WithRig $
WithMName RawImp) ->
242 | pibindAll fc p [] scope = scope
243 | pibindAll fc p (ty :: rest) scope
244 | = IPi fc ty.rig p (map val ty.mName) ty.val (pibindAll fc p rest scope)
246 | bindList : OriginDesc -> FilePos -> IndentInfo ->
247 | Rule (List (RigCount, Name, RawImp))
248 | bindList fname start indents
249 | = forget <$> sepBy1 (symbol ",")
250 | (do rigc <- multiplicity
254 | (Implicit (MkFC fname start end) False)
256 | appExpr fname indents)
257 | rig <- getMult rigc
261 | pibindListName : OriginDesc -> FilePos -> IndentInfo ->
262 | Rule (List (WithRig $
WithName RawImp))
263 | pibindListName fname start indents
264 | = do rigc <- multiplicity
265 | ns <- sepBy1 (symbol ",") (withFC userName)
267 | ty <- expr fname indents
269 | rig <- getMult rigc
270 | pure (map (\n => Mk [rig, n] ty) (forget ns))
271 | <|> forget <$> sepBy1 (symbol ",")
272 | (do rigc <- multiplicity
275 | ty <- expr fname indents
276 | rig <- getMult rigc
277 | pure (Mk [rig, n] ty))
279 | pibindList : OriginDesc -> FilePos -> IndentInfo ->
280 | Rule (List (WithRig $
WithMName RawImp))
281 | pibindList fname start indents
282 | = do params <- pibindListName fname start indents
283 | pure $
map (\ty => Mk [ty.rig, Just ty.name] ty.val) params
286 | autoImplicitPi : OriginDesc -> IndentInfo -> Rule RawImp
287 | autoImplicitPi fname indents
288 | = do start <- location
292 | binders <- pibindList fname start indents
295 | scope <- typeExpr fname indents
297 | pure (pibindAll (MkFC fname start end) AutoImplicit binders scope)
299 | forall_ : OriginDesc -> IndentInfo -> Rule RawImp
300 | forall_ fname indents
301 | = do start <- location
305 | ns <- sepBy1 (symbol ",") (withFC userName)
307 | let nfc = MkFC fname nstart nend
308 | let binders = map (\n => Mk [erased {a=RigCount}, Just n]
309 | (Implicit nfc False))
312 | scope <- typeExpr fname indents
314 | pure (pibindAll (MkFC fname start end) Implicit binders scope)
316 | implicitPi : OriginDesc -> IndentInfo -> Rule RawImp
317 | implicitPi fname indents
318 | = do start <- location
320 | binders <- pibindList fname start indents
323 | scope <- typeExpr fname indents
325 | pure (pibindAll (MkFC fname start end) Implicit binders scope)
327 | explicitPi : OriginDesc -> IndentInfo -> Rule RawImp
328 | explicitPi fname indents
329 | = do start <- location
331 | binders <- pibindList fname start indents
334 | scope <- typeExpr fname indents
336 | pure (pibindAll (MkFC fname start end) exp binders scope)
338 | lam : OriginDesc -> IndentInfo -> Rule RawImp
340 | = do start <- location
342 | binders <- bindList fname start indents
344 | mustContinue indents Nothing
345 | scope <- expr fname indents
347 | pure (bindAll (MkFC fname start end) binders scope)
349 | bindAll : FC -> List (RigCount, Name, RawImp) -> RawImp -> RawImp
350 | bindAll fc [] scope = scope
351 | bindAll fc ((rig, n, ty) :: rest) scope
352 | = ILam fc rig Explicit (Just n) ty (bindAll fc rest scope)
354 | let_ : OriginDesc -> IndentInfo -> Rule RawImp
356 | = do start <- location
358 | rigc <- multiplicity
359 | rig <- getMult rigc
363 | val <- expr fname indents
366 | scope <- typeExpr fname indents
368 | pure (let fc = MkFC fname start end in
369 | ILet fc (boundToFC fname n) rig n.val (Implicit fc False) val scope)
370 | <|> do start <- location
372 | ds <- block (topDecl fname)
375 | scope <- typeExpr fname indents
377 | pure (ILocal (MkFC fname start end) (collectDefs ds) scope)
379 | case_ : OriginDesc -> IndentInfo -> Rule RawImp
380 | case_ fname indents
381 | = do start <- location
384 | scr <- expr fname indents
386 | alts <- block (caseAlt fname)
388 | pure (let fc = MkFC fname start end in
389 | ICase fc opts scr (Implicit fc False) alts)
391 | caseAlt : OriginDesc -> IndentInfo -> Rule ImpClause
392 | caseAlt fname indents
393 | = do start <- location
394 | lhs <- appExpr fname indents
395 | caseRHS fname indents start lhs
397 | caseRHS : OriginDesc -> IndentInfo -> (Int, Int) -> RawImp ->
399 | caseRHS fname indents start lhs
402 | rhs <- expr fname indents
405 | pure (PatClause (MkFC fname start end) lhs rhs)
406 | <|> do keyword "impossible"
409 | pure (ImpossibleClause (MkFC fname start end) lhs)
411 | record_ : OriginDesc -> IndentInfo -> Rule RawImp
412 | record_ fname indents
413 | = do start <- location
417 | fs <- sepBy1 (symbol ",") (field fname indents)
419 | sc <- expr fname indents
421 | pure (IUpdate (MkFC fname start end) (forget fs) sc)
423 | field : OriginDesc -> IndentInfo -> Rule IFieldUpdate
424 | field fname indents
425 | = do path <- sepBy1 (symbol "->") unqualifiedName
426 | upd <- (do symbol "=";
pure ISetField)
428 | (do symbol "$=";
pure ISetFieldApp)
429 | val <- appExpr fname indents
430 | pure (upd (forget path) val)
432 | rewrite_ : OriginDesc -> IndentInfo -> Rule RawImp
433 | rewrite_ fname indents
434 | = do start <- location
436 | rule <- expr fname indents
438 | tm <- expr fname indents
440 | pure (IRewrite (MkFC fname start end) rule tm)
442 | lazy : OriginDesc -> IndentInfo -> Rule RawImp
444 | = do start <- location
446 | tm <- simpleExpr fname indents
448 | pure (IDelayed (MkFC fname start end) LLazy tm)
449 | <|> do start <- location
451 | tm <- simpleExpr fname indents
453 | pure (IDelayed (MkFC fname start end) LInf tm)
454 | <|> do start <- location
456 | tm <- simpleExpr fname indents
458 | pure (IDelay (MkFC fname start end) tm)
459 | <|> do start <- location
461 | tm <- simpleExpr fname indents
463 | pure (IForce (MkFC fname start end) tm)
466 | binder : OriginDesc -> IndentInfo -> Rule RawImp
467 | binder fname indents
468 | = autoImplicitPi fname indents
469 | <|> forall_ fname indents
470 | <|> implicitPi fname indents
471 | <|> explicitPi fname indents
472 | <|> lam fname indents
473 | <|> let_ fname indents
475 | typeExpr : OriginDesc -> IndentInfo -> Rule RawImp
476 | typeExpr fname indents
477 | = do start <- location
478 | arg <- appExpr fname indents
479 | (do continue indents
480 | rest <- some (do exp <- bindSymbol
481 | op <- appExpr fname indents
484 | pure (mkPi start end arg (forget rest)))
487 | mkPi : FilePos -> FilePos -> RawImp -> List (PiInfo RawImp, RawImp) -> RawImp
488 | mkPi start end arg [] = arg
489 | mkPi start end arg ((exp, a) :: as)
490 | = IPi (MkFC fname start end) top exp Nothing arg
491 | (mkPi start end a as)
494 | expr : OriginDesc -> IndentInfo -> Rule RawImp
497 | tyDecl : OriginDesc -> IndentInfo -> Rule ImpTy
498 | tyDecl fname indents
499 | = do start <- location
501 | nameEnd <- location
503 | ty <- expr fname indents
506 | let fc = MkFC fname start end
507 | pure (Mk [fc, n] ty)
510 | parseRHS : (withArgs : Nat) ->
511 | OriginDesc -> IndentInfo -> (Int, Int) -> RawImp ->
512 | Rule (Name, ImpClause)
513 | parseRHS withArgs fname indents start lhs
516 | rhs <- expr fname indents
519 | let fc = MkFC fname start end
520 | pure (!(getFn lhs), PatClause fc lhs rhs)
521 | <|> do keyword "with"
526 | wval <- expr fname indents
528 | prf <- optional $
do
530 | pure (!(getMult !multiplicity), !name)
531 | ws <- nonEmptyBlock (clause (S withArgs) fname)
533 | let fc = MkFC fname start end
534 | pure (MkPair !(getFn lhs) $
WithClause fc lhs rig wval prf [] (forget $
map snd ws))
536 | <|> do keyword "impossible"
539 | let fc = MkFC fname start end
540 | pure (!(getFn lhs), ImpossibleClause fc lhs)
542 | getFn : RawImp -> EmptyRule Name
543 | getFn (IVar _ n) = pure n
544 | getFn (IApp _ f a) = getFn f
545 | getFn (IAutoApp _ f a) = getFn f
546 | getFn (INamedApp _ f _ a) = getFn f
547 | getFn _ = fail "Not a function application"
549 | clause : Nat -> OriginDesc -> IndentInfo -> Rule (Name, ImpClause)
550 | clause withArgs fname indents
551 | = do start <- location
552 | lhs <- expr fname indents
553 | extra <- many parseWithArg
554 | ifThenElse (withArgs /= length extra)
555 | (fatalError "Wrong number of 'with' arguments")
556 | (parseRHS withArgs fname indents start (applyArgs lhs extra))
558 | applyArgs : RawImp -> List (FC, RawImp) -> RawImp
560 | applyArgs f ((fc, a) :: args) = applyArgs (IApp fc f a) args
562 | parseWithArg : Rule (FC, RawImp)
566 | tm <- expr fname indents
568 | pure (MkFC fname start end, tm)
570 | definition : OriginDesc -> IndentInfo -> Rule ImpDecl
571 | definition fname indents
572 | = do start <- location
573 | nd <- clause 0 fname indents
575 | pure (IDef (MkFC fname start end) (fst nd) [snd nd])
577 | dataOpt : Rule DataOpt
579 | = do exactIdent "noHints"
581 | <|> do exactIdent "uniqueSearch"
583 | <|> do exactIdent "search"
587 | dataOpts : EmptyRule (List DataOpt)
588 | dataOpts = option [] $
do
590 | dopts <- sepBy1 (symbol ",") dataOpt
592 | pure $
forget dopts
594 | dataDecl : OriginDesc -> IndentInfo -> Rule ImpData
595 | dataDecl fname indents
596 | = do start <- location
600 | ty <- expr fname indents
603 | cs <- block (tyDecl fname)
605 | pure (MkImpData (MkFC fname start end) n (Just ty) opts cs)
607 | recordParam : OriginDesc -> IndentInfo -> Rule (List (ImpParameter' RawImp))
608 | recordParam fname indents
611 | params <- pibindListName fname start indents
613 | pure (map (map (MkPiBindData Explicit)) params)
617 | info <- (pure AutoImplicit <* keyword "auto"
620 | t <- simpleExpr fname indents
621 | pure $
DefImplicit t)
623 | params <- pibindListName fname start indents
625 | pure (map (map (MkPiBindData info)) params)
626 | <|> do n <- withFC name
627 | pure [ Mk [top, n] (MkPiBindData Explicit (Implicit n.fc False)) ]
629 | fieldDecl : OriginDesc -> IndentInfo -> Rule (List IField)
630 | fieldDecl fname indents
633 | fs <- fieldBody Implicit
637 | <|> do fs <- fieldBody Explicit
641 | fieldBody : PiInfo RawImp -> Rule (List IField)
643 | = do start <- location
644 | ns <- sepBy1 (symbol ",") (withFC userName)
646 | ty <- expr fname indents
648 | pure (map (\n => Mk [MkFC fname start end, linear, n]
649 | (MkPiBindData p ty)) (forget ns))
651 | recordDecl : OriginDesc -> IndentInfo -> Rule ImpDecl
652 | recordDecl fname indents
653 | = do start <- location
654 | (vis,mbtot) <- dataVisOpt
659 | paramss <- many (recordParam fname indents)
660 | let params = concat paramss
663 | exactIdent "constructor"
665 | flds <- assert_total (blockAfter col (fieldDecl fname))
667 | pure (let fc = MkFC fname start end
668 | in IRecord fc Nothing vis mbtot
669 | (Mk [fc] $
MkImpRecord (Mk [n] params) (Mk [dc, opts] (concat flds))))
671 | namespaceDecl : Rule Namespace
673 | = do keyword "namespace"
677 | logLevel : Rule (Maybe (List String, Nat))
679 | = (Nothing <$ exactIdent "off")
680 | <|> do topic <- option [] ((::) <$> unqualifiedName <*> many aDotIdent)
682 | pure (Just (topic, fromInteger lvl))
684 | directive : OriginDesc -> IndentInfo -> Rule ImpDecl
685 | directive fname indents
686 | = do pragma "logging"
691 | <|> do b <- bounds (do pragma "builtin"
696 | (t, n) <- pure b.val
697 | pure $
IBuiltin (boundToFC fname b) t n
720 | topDecl fname indents
721 | = do start <- location
722 | (vis,mbtot) <- dataVisOpt
723 | dat <- dataDecl fname indents
725 | pure (IData (MkFC fname start end) vis mbtot dat)
726 | <|> do start <- location
727 | ns <- namespaceDecl
728 | ds <- assert_total (nonEmptyBlock (topDecl fname))
730 | pure (INamespace (MkFC fname start end) ns (forget ds))
731 | <|> do start <- location
732 | visOpts <- many visOpt
733 | vis <- getVisibility Nothing visOpts
734 | let opts = mapMaybe getRight visOpts
737 | claim <- tyDecl fname indents
739 | pure (IClaim (MkFCVal (MkFC fname start end) $
MkIClaimData rig vis opts claim))
740 | <|> recordDecl fname indents
741 | <|> directive fname indents
742 | <|> definition fname indents
746 | collectDefs [] = []
747 | collectDefs (IDef loc fn cs :: ds)
748 | = let (cs', rest) = spanMap (isClause fn) ds in
749 | IDef loc fn (cs ++ cs') :: assert_total (collectDefs rest)
751 | spanMap : (a -> Maybe (List b)) -> List a -> (List b, List a)
752 | spanMap f [] = ([], [])
753 | spanMap f (x :: xs) = case f x of
754 | Nothing => ([], x :: xs)
755 | Just y => case spanMap f xs of
756 | (ys, zs) => (y ++ ys, zs)
758 | isClause : Name -> ImpDecl -> Maybe (List ImpClause)
759 | isClause n (IDef _ n' cs)
760 | = if n == n' then Just cs else Nothing
761 | isClause n _ = Nothing
762 | collectDefs (INamespace loc ns nds :: ds)
763 | = INamespace loc ns (collectDefs nds) :: collectDefs ds
764 | collectDefs (IFail loc msg nds :: ds)
765 | = IFail loc msg (collectDefs nds) :: collectDefs ds
766 | collectDefs (d :: ds)
767 | = d :: collectDefs ds
771 | prog : OriginDesc -> Rule (List ImpDecl)
773 | = do ds <- nonEmptyBlock (topDecl fname)
774 | pure (collectDefs $
forget ds)
778 | command : Rule ImpREPL
780 | = do symbol ":";
exactIdent "t"
781 | tm <- expr (Virtual Interactive) init
783 | <|> do symbol ":";
exactIdent "s"
785 | pure (ProofSearch n)
786 | <|> do symbol ":";
exactIdent "es"
788 | pure (ExprSearch n)
789 | <|> do symbol ":";
exactIdent "gd"
792 | pure (GenerateDef (fromInteger l) n)
793 | <|> do symbol ":";
exactIdent "missing"
796 | <|> do symbol ":";
keyword "total"
798 | pure (CheckTotal n)
799 | <|> do symbol ":";
exactIdent "di"
802 | <|> do symbol ":";
exactIdent "q"
804 | <|> do tm <- expr (Virtual Interactive) init