forked from haskell/haskell-language-server
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathParser.hs
83 lines (67 loc) · 2.58 KB
/
Parser.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications #-}
module Wingman.Metaprogramming.Parser where
import qualified Control.Monad.Combinators.Expr as P
import Data.Functor
import Development.IDE.GHC.Compat (alphaTyVars, LHsExpr, GhcPs)
import GhcPlugins (mkTyVarTy)
import qualified Refinery.Tactic as R
import qualified Text.Megaparsec as P
import Wingman.Auto
import Wingman.LanguageServer.TacticProviders (useNameFromHypothesis)
import Wingman.Metaprogramming.Lexer
import Wingman.Tactics
import Wingman.Types
import qualified Data.Text as T
nullary :: T.Text -> TacticsM () -> Parser (TacticsM ())
nullary name tac = identifier name $> tac
unary_occ :: T.Text -> (OccName -> TacticsM ()) -> Parser (TacticsM ())
unary_occ name tac = tac <$> (identifier name *> variable)
variadic_occ :: T.Text -> ([OccName] -> TacticsM ()) -> Parser (TacticsM ())
variadic_occ name tac = tac <$> (identifier name *> P.many variable)
tactic :: Parser (TacticsM ())
tactic = flip P.makeExprParser operators $ P.choice
[ braces tactic
, nullary "assumption" assumption
, unary_occ "assume" assume
, variadic_occ "intros" $ \case
[] -> intros
names -> intros' $ Just names
, nullary "destruct_all" destructAll
, unary_occ "destruct" $ useNameFromHypothesis destruct
, unary_occ "homo" $ useNameFromHypothesis homo
, unary_occ "apply" $ useNameFromHypothesis apply
, unary_occ "split" userSplit
, nullary "obvious" obvious
, nullary "auto" auto
, R.try <$> (keyword "try" *> tactic)
]
bindOne :: TacticsM a -> TacticsM a -> TacticsM a
bindOne t t1 = t R.<@> [t1]
operators :: [[P.Operator Parser (TacticsM ())]]
operators =
[ [ P.Prefix (symbol "*" $> R.many_) ]
, [ P.InfixR (symbol "|" $> (R.<%>) )]
, [ P.InfixL (symbol ";" $> (>>))
, P.InfixL (symbol "," $> bindOne)
]
]
skolems :: [Type]
skolems = fmap mkTyVarTy alphaTyVars
a_skolem, b_skolem, c_skolem :: Type
(a_skolem : b_skolem : c_skolem : _) = skolems
attempt_it :: Context -> Judgement -> String -> Either String (LHsExpr GhcPs)
attempt_it ctx jdg program =
case P.runParser (sc *> tactic <* P.eof) "<splice>" (T.pack program) of
Left peb -> Left $ P.errorBundlePretty peb
Right tt -> do
case runTactic
ctx
jdg
tt
of
Left tes -> Left $ show tes
Right rtr -> Right $ rtr_extract rtr