Skip to content

Commit 773452c

Browse files
authored
Add pointwise command to the metaprogram parser (#1921)
* Add pointwise command to the metaprogram parser * Fix documentation
1 parent 8f5558a commit 773452c

File tree

8 files changed

+76
-15
lines changed

8 files changed

+76
-15
lines changed

plugins/hls-tactics-plugin/COMMANDS.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,29 @@ running `obvious` will produce:
389389
```haskell
390390
[]
391391
```
392+
## pointwise
393+
394+
arguments: tactic.
395+
deterministic.
396+
397+
> Restrict the hypothesis in the holes of the given tactic to align up with the top-level bindings. This will ensure, eg, that the first hole can see only terms that came from the first position in any terms destructed from the top-level bindings.
398+
399+
400+
### Example
401+
402+
> In the context of `f (a1, b1) (a2, b2) = _`. The resulting first hole can see only 'a1' and 'a2', and the second, only 'b1' and 'b2'.
403+
404+
Given:
405+
406+
```haskell
407+
_
408+
```
409+
410+
running `pointwise (use mappend)` will produce:
411+
412+
```haskell
413+
mappend _ _
414+
```
392415
## recursion
393416

394417
arguments: none.

plugins/hls-tactics-plugin/src/Wingman/KnownStrategies.hs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
module Wingman.KnownStrategies where
22

3-
import Control.Applicative (empty)
43
import Control.Monad.Error.Class
5-
import Control.Monad.Reader.Class (asks)
64
import Data.Foldable (for_)
75
import OccName (mkVarOcc)
86
import Refinery.Tactic

plugins/hls-tactics-plugin/src/Wingman/Metaprogramming/Parser.hs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,17 @@ commands =
176176
"f (_ :: a)"
177177
]
178178

179+
, command "pointwise" Deterministic Tactic
180+
"Restrict the hypothesis in the holes of the given tactic to align up with the top-level bindings. This will ensure, eg, that the first hole can see only terms that came from the first position in any terms destructed from the top-level bindings."
181+
(pure . flip restrictPositionForApplication (pure ()))
182+
[ Example
183+
(Just "In the context of `f (a1, b1) (a2, b2) = _`. The resulting first hole can see only 'a1' and 'a2', and the second, only 'b1' and 'b2'.")
184+
["(use mappend)"]
185+
[]
186+
Nothing
187+
"mappend _ _"
188+
]
189+
179190
, command "apply" Deterministic (Ref One)
180191
"Apply the given function from *local* scope."
181192
(pure . useNameFromHypothesis apply)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module Wingman.Metaprogramming.Parser where
2+
3+
import Wingman.Metaprogramming.Lexer
4+
import Wingman.Types
5+
6+
tactic :: Parser (TacticsM ())
7+

plugins/hls-tactics-plugin/src/Wingman/Metaprogramming/Parser/Documentation.hs

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@ import Data.Functor ((<&>))
66
import Data.List (sortOn)
77
import Data.String (IsString)
88
import Data.Text (Text)
9-
import Data.Text.Prettyprint.Doc
9+
import Data.Text.Prettyprint.Doc hiding (parens)
1010
import Data.Text.Prettyprint.Doc.Render.String (renderString)
1111
import GhcPlugins (OccName)
1212
import qualified Text.Megaparsec as P
13-
import Wingman.Metaprogramming.Lexer (Parser, identifier, variable)
13+
import Wingman.Metaprogramming.Lexer (Parser, identifier, variable, parens)
1414
import Wingman.Types (TacticsM)
1515

16+
import {-# SOURCE #-} Wingman.Metaprogramming.Parser (tactic)
17+
1618

1719
------------------------------------------------------------------------------
1820
-- | Is a tactic deterministic or not?
@@ -46,11 +48,13 @@ data Syntax a where
4648
Nullary :: Syntax (Parser (TacticsM ()))
4749
Ref :: Count a -> Syntax (a -> Parser (TacticsM ()))
4850
Bind :: Count a -> Syntax (a -> Parser (TacticsM ()))
51+
Tactic :: Syntax (TacticsM () -> Parser (TacticsM ()))
4952

5053
prettySyntax :: Syntax a -> Doc b
5154
prettySyntax Nullary = "none"
5255
prettySyntax (Ref co) = prettyCount co <+> "reference"
5356
prettySyntax (Bind co) = prettyCount co <+> "binding"
57+
prettySyntax Tactic = "tactic"
5458

5559

5660
------------------------------------------------------------------------------
@@ -108,21 +112,24 @@ data SomeMetaprogramCommand where
108112
------------------------------------------------------------------------------
109113
-- | Run the 'Parser' of a 'MetaprogramCommand'
110114
makeMPParser :: MetaprogramCommand a -> Parser (TacticsM ())
111-
makeMPParser (MC name Nullary _ _ tactic _) = do
115+
makeMPParser (MC name Nullary _ _ t _) = do
116+
identifier name
117+
t
118+
makeMPParser (MC name (Ref One) _ _ t _) = do
112119
identifier name
113-
tactic
114-
makeMPParser (MC name (Ref One) _ _ tactic _) = do
120+
variable >>= t
121+
makeMPParser (MC name (Ref Many) _ _ t _) = do
115122
identifier name
116-
variable >>= tactic
117-
makeMPParser (MC name (Ref Many) _ _ tactic _) = do
123+
P.many variable >>= t
124+
makeMPParser (MC name (Bind One) _ _ t _) = do
118125
identifier name
119-
P.many variable >>= tactic
120-
makeMPParser (MC name (Bind One) _ _ tactic _) = do
126+
variable >>= t
127+
makeMPParser (MC name (Bind Many) _ _ t _) = do
121128
identifier name
122-
variable >>= tactic
123-
makeMPParser (MC name (Bind Many) _ _ tactic _) = do
129+
P.many variable >>= t
130+
makeMPParser (MC name Tactic _ _ t _) = do
124131
identifier name
125-
P.many variable >>= tactic
132+
parens tactic >>= t
126133

127134

128135
------------------------------------------------------------------------------

plugins/hls-tactics-plugin/test/CodeAction/RunMetaprogramSpec.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,5 @@ spec = do
3333
metaTest 11 11 "MetaUseMethod"
3434
metaTest 9 38 "MetaCataCollapse"
3535
metaTest 7 16 "MetaCataCollapseUnary"
36+
metaTest 6 46 "MetaPointwise"
3637
metaTest 4 28 "MetaUseSymbol"
37-
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import Data.Monoid
2+
3+
data Foo = Foo (Sum Int) (Sum Int)
4+
5+
mappend2 :: Foo -> Foo -> Foo
6+
mappend2 (Foo sum sum') (Foo sum2 sum3)
7+
= Foo (mappend sum sum2) (mappend sum' sum3)
8+
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import Data.Monoid
2+
3+
data Foo = Foo (Sum Int) (Sum Int)
4+
5+
mappend2 :: Foo -> Foo -> Foo
6+
mappend2 = [wingman| intros f1 f2, destruct_all, ctor Foo; pointwise (use mappend); assumption|]
7+

0 commit comments

Comments
 (0)