Skip to content

Add pointwise command to the metaprogram parser #1921

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions plugins/hls-tactics-plugin/COMMANDS.md
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,29 @@ running `obvious` will produce:
```haskell
[]
```
## pointwise

arguments: tactic.
deterministic.

> 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.


### Example

> 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'.

Given:

```haskell
_
```

running `pointwise (use mappend)` will produce:

```haskell
mappend _ _
```
## recursion

arguments: none.
Expand Down
2 changes: 0 additions & 2 deletions plugins/hls-tactics-plugin/src/Wingman/KnownStrategies.hs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
module Wingman.KnownStrategies where

import Control.Applicative (empty)
import Control.Monad.Error.Class
import Control.Monad.Reader.Class (asks)
import Data.Foldable (for_)
import OccName (mkVarOcc)
import Refinery.Tactic
Expand Down
11 changes: 11 additions & 0 deletions plugins/hls-tactics-plugin/src/Wingman/Metaprogramming/Parser.hs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,17 @@ commands =
"f (_ :: a)"
]

, command "pointwise" Deterministic Tactic
"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."
(pure . flip restrictPositionForApplication (pure ()))
[ Example
(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'.")
["(use mappend)"]
[]
Nothing
"mappend _ _"
]

, command "apply" Deterministic (Ref One)
"Apply the given function from *local* scope."
(pure . useNameFromHypothesis apply)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module Wingman.Metaprogramming.Parser where

import Wingman.Metaprogramming.Lexer
import Wingman.Types

tactic :: Parser (TacticsM ())

Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ import Data.Functor ((<&>))
import Data.List (sortOn)
import Data.String (IsString)
import Data.Text (Text)
import Data.Text.Prettyprint.Doc
import Data.Text.Prettyprint.Doc hiding (parens)
import Data.Text.Prettyprint.Doc.Render.String (renderString)
import GhcPlugins (OccName)
import qualified Text.Megaparsec as P
import Wingman.Metaprogramming.Lexer (Parser, identifier, variable)
import Wingman.Metaprogramming.Lexer (Parser, identifier, variable, parens)
import Wingman.Types (TacticsM)

import {-# SOURCE #-} Wingman.Metaprogramming.Parser (tactic)


------------------------------------------------------------------------------
-- | Is a tactic deterministic or not?
Expand Down Expand Up @@ -46,11 +48,13 @@ data Syntax a where
Nullary :: Syntax (Parser (TacticsM ()))
Ref :: Count a -> Syntax (a -> Parser (TacticsM ()))
Bind :: Count a -> Syntax (a -> Parser (TacticsM ()))
Tactic :: Syntax (TacticsM () -> Parser (TacticsM ()))

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


------------------------------------------------------------------------------
Expand Down Expand Up @@ -108,21 +112,24 @@ data SomeMetaprogramCommand where
------------------------------------------------------------------------------
-- | Run the 'Parser' of a 'MetaprogramCommand'
makeMPParser :: MetaprogramCommand a -> Parser (TacticsM ())
makeMPParser (MC name Nullary _ _ tactic _) = do
makeMPParser (MC name Nullary _ _ t _) = do
identifier name
t
makeMPParser (MC name (Ref One) _ _ t _) = do
identifier name
tactic
makeMPParser (MC name (Ref One) _ _ tactic _) = do
variable >>= t
makeMPParser (MC name (Ref Many) _ _ t _) = do
identifier name
variable >>= tactic
makeMPParser (MC name (Ref Many) _ _ tactic _) = do
P.many variable >>= t
makeMPParser (MC name (Bind One) _ _ t _) = do
identifier name
P.many variable >>= tactic
makeMPParser (MC name (Bind One) _ _ tactic _) = do
variable >>= t
makeMPParser (MC name (Bind Many) _ _ t _) = do
identifier name
variable >>= tactic
makeMPParser (MC name (Bind Many) _ _ tactic _) = do
P.many variable >>= t
makeMPParser (MC name Tactic _ _ t _) = do
identifier name
P.many variable >>= tactic
parens tactic >>= t


------------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,5 @@ spec = do
metaTest 11 11 "MetaUseMethod"
metaTest 9 38 "MetaCataCollapse"
metaTest 7 16 "MetaCataCollapseUnary"
metaTest 6 46 "MetaPointwise"
metaTest 4 28 "MetaUseSymbol"

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import Data.Monoid

data Foo = Foo (Sum Int) (Sum Int)

mappend2 :: Foo -> Foo -> Foo
mappend2 (Foo sum sum') (Foo sum2 sum3)
= Foo (mappend sum sum2) (mappend sum' sum3)

7 changes: 7 additions & 0 deletions plugins/hls-tactics-plugin/test/golden/MetaPointwise.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import Data.Monoid

data Foo = Foo (Sum Int) (Sum Int)

mappend2 :: Foo -> Foo -> Foo
mappend2 = [wingman| intros f1 f2, destruct_all, ctor Foo; pointwise (use mappend); assumption|]