{-# OPTIONS_GHC -Wunused-imports #-}
module Agda.Syntax.Notation where
import Prelude hiding (null)
import Control.Arrow ( (&&&) )
import Control.DeepSeq
import Control.Monad
import Control.Monad.Except
import qualified Data.List as List
import Data.Set (Set)
import qualified Data.Set as Set
import GHC.Generics (Generic)
import qualified Agda.Syntax.Abstract.Name as A
import Agda.Syntax.Common
import Agda.Syntax.Common.Pretty
import Agda.Syntax.Concrete.Name
import Agda.Syntax.Concrete.Pretty()
import Agda.Syntax.Position
import Agda.Utils.Lens
import Agda.Utils.List
import Agda.Utils.List1           ( List1, pattern (:|) )
import qualified Agda.Utils.List1 as List1
import Agda.Utils.Null
import Agda.Utils.Singleton
import Agda.Utils.Impossible
data HoleName
  = LambdaHole { HoleName -> List1 (Ranged [Char])
_bindHoleNames :: List1 RString
               , HoleName -> Ranged [Char]
holeName       :: RString
               }
    
  | ExprHole   { holeName      :: RString }
    
isLambdaHole :: HoleName -> Bool
isLambdaHole :: HoleName -> Bool
isLambdaHole (LambdaHole List1 (Ranged [Char])
_ Ranged [Char]
_) = Bool
True
isLambdaHole HoleName
_ = Bool
False
stringParts :: Notation -> [String]
stringParts :: Notation -> [[Char]]
stringParts Notation
gs = [ Ranged [Char] -> [Char]
forall a. Ranged a -> a
rangedThing Ranged [Char]
x | IdPart Ranged [Char]
x <- Notation
gs ]
holeTarget :: NotationPart -> Maybe Int
holeTarget :: NotationPart -> Maybe Int
holeTarget (VarPart Range
_ Ranged BoundVariablePosition
n)  = Int -> Maybe Int
forall a. a -> Maybe a
Just (Int -> Maybe Int) -> Int -> Maybe Int
forall a b. (a -> b) -> a -> b
$ BoundVariablePosition -> Int
holeNumber (BoundVariablePosition -> Int) -> BoundVariablePosition -> Int
forall a b. (a -> b) -> a -> b
$ Ranged BoundVariablePosition -> BoundVariablePosition
forall a. Ranged a -> a
rangedThing Ranged BoundVariablePosition
n
holeTarget (WildPart Ranged BoundVariablePosition
n)   = Int -> Maybe Int
forall a. a -> Maybe a
Just (Int -> Maybe Int) -> Int -> Maybe Int
forall a b. (a -> b) -> a -> b
$ BoundVariablePosition -> Int
holeNumber (BoundVariablePosition -> Int) -> BoundVariablePosition -> Int
forall a b. (a -> b) -> a -> b
$ Ranged BoundVariablePosition -> BoundVariablePosition
forall a. Ranged a -> a
rangedThing Ranged BoundVariablePosition
n
holeTarget (HolePart Range
_ NamedArg (Ranged Int)
n) = Int -> Maybe Int
forall a. a -> Maybe a
Just (Int -> Maybe Int) -> Int -> Maybe Int
forall a b. (a -> b) -> a -> b
$ Ranged Int -> Int
forall a. Ranged a -> a
rangedThing (Ranged Int -> Int) -> Ranged Int -> Int
forall a b. (a -> b) -> a -> b
$ NamedArg (Ranged Int) -> Ranged Int
forall a. NamedArg a -> a
namedArg NamedArg (Ranged Int)
n
holeTarget IdPart{}       = Maybe Int
forall a. Maybe a
Nothing
isAHole :: NotationPart -> Bool
isAHole :: NotationPart -> Bool
isAHole HolePart{} = Bool
True
isAHole VarPart{}  = Bool
False
isAHole WildPart{} = Bool
False
isAHole IdPart{}   = Bool
False
isBinder :: NotationPart -> Bool
isBinder :: NotationPart -> Bool
isBinder HolePart{} = Bool
False
isBinder VarPart{}  = Bool
True
isBinder WildPart{} = Bool
True
isBinder IdPart{}   = Bool
False
data NotationKind
  = InfixNotation   
  | PrefixNotation  
  | PostfixNotation 
  | NonfixNotation  
  | NoNotation
   deriving (NotationKind -> NotationKind -> Bool
(NotationKind -> NotationKind -> Bool)
-> (NotationKind -> NotationKind -> Bool) -> Eq NotationKind
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: NotationKind -> NotationKind -> Bool
== :: NotationKind -> NotationKind -> Bool
$c/= :: NotationKind -> NotationKind -> Bool
/= :: NotationKind -> NotationKind -> Bool
Eq, Int -> NotationKind -> ShowS
[NotationKind] -> ShowS
NotationKind -> [Char]
(Int -> NotationKind -> ShowS)
-> (NotationKind -> [Char])
-> ([NotationKind] -> ShowS)
-> Show NotationKind
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> NotationKind -> ShowS
showsPrec :: Int -> NotationKind -> ShowS
$cshow :: NotationKind -> [Char]
show :: NotationKind -> [Char]
$cshowList :: [NotationKind] -> ShowS
showList :: [NotationKind] -> ShowS
Show, (forall x. NotationKind -> Rep NotationKind x)
-> (forall x. Rep NotationKind x -> NotationKind)
-> Generic NotationKind
forall x. Rep NotationKind x -> NotationKind
forall x. NotationKind -> Rep NotationKind x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. NotationKind -> Rep NotationKind x
from :: forall x. NotationKind -> Rep NotationKind x
$cto :: forall x. Rep NotationKind x -> NotationKind
to :: forall x. Rep NotationKind x -> NotationKind
Generic)
notationKind :: Notation -> NotationKind
notationKind :: Notation -> NotationKind
notationKind []  = NotationKind
NoNotation
notationKind (NotationPart
h:Notation
syn) =
  case (NotationPart -> Bool
isAHole NotationPart
h, NotationPart -> Bool
isAHole (NotationPart -> Bool) -> NotationPart -> Bool
forall a b. (a -> b) -> a -> b
$ NotationPart -> Notation -> NotationPart
forall a. a -> [a] -> a
last1 NotationPart
h Notation
syn) of
    (Bool
True , Bool
True ) -> NotationKind
InfixNotation
    (Bool
True , Bool
False) -> NotationKind
PostfixNotation
    (Bool
False, Bool
True ) -> NotationKind
PrefixNotation
    (Bool
False, Bool
False) -> NotationKind
NonfixNotation
mkNotation :: [NamedArg HoleName] -> [RString] -> Either String Notation
mkNotation :: [NamedArg HoleName] -> [Ranged [Char]] -> Either [Char] Notation
mkNotation [NamedArg HoleName]
_ [] = [Char] -> Either [Char] Notation
forall a. [Char] -> Either [Char] a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError [Char]
"empty notation is disallowed"
mkNotation [NamedArg HoleName]
holes [Ranged [Char]]
ids = do
  Bool -> Either [Char] () -> Either [Char] ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
uniqueHoleNames     (Either [Char] () -> Either [Char] ())
-> Either [Char] () -> Either [Char] ()
forall a b. (a -> b) -> a -> b
$ [Char] -> Either [Char] ()
forall a. [Char] -> Either [Char] a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError [Char]
"syntax must use unique argument names"
  let Notation
xs :: Notation = (Ranged [Char] -> NotationPart) -> [Ranged [Char]] -> Notation
forall a b. (a -> b) -> [a] -> [b]
map Ranged [Char] -> NotationPart
mkPart [Ranged [Char]]
ids
  Bool -> Either [Char] () -> Either [Char] ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Notation -> Bool
noAdjacentHoles Notation
xs)  (Either [Char] () -> Either [Char] ())
-> Either [Char] () -> Either [Char] ()
forall a b. (a -> b) -> a -> b
$ [Char] -> Either [Char] ()
forall a. [Char] -> Either [Char] a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError ([Char] -> Either [Char] ()) -> [Char] -> Either [Char] ()
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
     [ [Char]
"syntax must not contain adjacent holes ("
     , [Char]
prettyHoles
     , [Char]
")"
     ]
  Bool -> Either [Char] () -> Either [Char] ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Notation -> Bool
isExprLinear Notation
xs)   (Either [Char] () -> Either [Char] ())
-> Either [Char] () -> Either [Char] ()
forall a b. (a -> b) -> a -> b
$ [Char] -> Either [Char] ()
forall a. [Char] -> Either [Char] a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError [Char]
"syntax must use holes exactly once"
  Bool -> Either [Char] () -> Either [Char] ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Notation -> Bool
isLambdaLinear Notation
xs) (Either [Char] () -> Either [Char] ())
-> Either [Char] () -> Either [Char] ()
forall a b. (a -> b) -> a -> b
$ [Char] -> Either [Char] ()
forall a. [Char] -> Either [Char] a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError [Char]
"syntax must use binding holes exactly once"
  
  
  Bool -> Either [Char] () -> Either [Char] ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when   (Notation -> Bool
isSingleHole Notation
xs)   (Either [Char] () -> Either [Char] ())
-> Either [Char] () -> Either [Char] ()
forall a b. (a -> b) -> a -> b
$ [Char] -> Either [Char] ()
forall a. [Char] -> Either [Char] a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError [Char]
"syntax cannot be a single hole"
  Notation -> Either [Char] Notation
forall a. a -> Either [Char] a
forall (m :: * -> *) a. Monad m => a -> m a
return (Notation -> Either [Char] Notation)
-> Notation -> Either [Char] Notation
forall a b. (a -> b) -> a -> b
$ Notation -> Notation
insertWildParts Notation
xs
    where
      holeNames :: [RString]
      holeNames :: [Ranged [Char]]
holeNames = (NamedArg HoleName -> HoleName)
-> [NamedArg HoleName] -> [HoleName]
forall a b. (a -> b) -> [a] -> [b]
map NamedArg HoleName -> HoleName
forall a. NamedArg a -> a
namedArg [NamedArg HoleName]
holes [HoleName] -> (HoleName -> [Ranged [Char]]) -> [Ranged [Char]]
forall a b. [a] -> (a -> [b]) -> [b]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        LambdaHole List1 (Ranged [Char])
_ Ranged [Char]
y -> [Ranged [Char]
y]
        ExprHole Ranged [Char]
y     -> [Ranged [Char]
y]
      prettyHoles :: String
      prettyHoles :: [Char]
prettyHoles = [[Char]] -> [Char]
List.unwords ([[Char]] -> [Char]) -> [[Char]] -> [Char]
forall a b. (a -> b) -> a -> b
$ (Ranged [Char] -> [Char]) -> [Ranged [Char]] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map (ShowS
rawNameToString ShowS -> (Ranged [Char] -> [Char]) -> Ranged [Char] -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ranged [Char] -> [Char]
forall a. Ranged a -> a
rangedThing) [Ranged [Char]]
holeNames
      mkPart :: Ranged [Char] -> NotationPart
mkPart Ranged [Char]
ident = NotationPart
-> (NotationPart -> NotationPart)
-> Maybe NotationPart
-> NotationPart
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Ranged [Char] -> NotationPart
IdPart Ranged [Char]
ident) (NotationPart -> Ranged [Char] -> NotationPart
forall t u. (SetRange t, HasRange u) => t -> u -> t
`withRangeOf` Ranged [Char]
ident) (Maybe NotationPart -> NotationPart)
-> Maybe NotationPart -> NotationPart
forall a b. (a -> b) -> a -> b
$ Ranged [Char]
-> [(Ranged [Char], NotationPart)] -> Maybe NotationPart
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Ranged [Char]
ident [(Ranged [Char], NotationPart)]
holeMap
      holeNumbers :: [Int]
holeNumbers   = [Int
0 .. [NamedArg HoleName] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [NamedArg HoleName]
holes Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1]
      numberedHoles :: [(Int, NamedArg HoleName)]
      numberedHoles :: [(Int, NamedArg HoleName)]
numberedHoles = [Int] -> [NamedArg HoleName] -> [(Int, NamedArg HoleName)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int]
holeNumbers [NamedArg HoleName]
holes
      
      
      
      insertWildParts :: [NotationPart] -> [NotationPart]
      insertWildParts :: Notation -> Notation
insertWildParts Notation
xs = (Ranged BoundVariablePosition -> Notation -> Notation)
-> Notation -> [Ranged BoundVariablePosition] -> Notation
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Ranged BoundVariablePosition -> Notation -> Notation
ins Notation
xs [Ranged BoundVariablePosition]
wilds
        where
          wilds :: [Ranged BoundVariablePosition]
wilds = [ Ranged BoundVariablePosition
i | (Ranged [Char]
_, WildPart Ranged BoundVariablePosition
i) <- [(Ranged [Char], NotationPart)]
holeMap ]
          ins :: Ranged BoundVariablePosition -> Notation -> Notation
ins Ranged BoundVariablePosition
w (HolePart Range
r NamedArg (Ranged Int)
h : Notation
hs)
            | NamedArg (Ranged Int) -> Ranged Int
forall a. NamedArg a -> a
namedArg NamedArg (Ranged Int)
h Ranged Int -> Ranged Int -> Bool
forall a. Eq a => a -> a -> Bool
== (BoundVariablePosition -> Int)
-> Ranged BoundVariablePosition -> Ranged Int
forall a b. (a -> b) -> Ranged a -> Ranged b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap BoundVariablePosition -> Int
holeNumber Ranged BoundVariablePosition
w =
              Range -> NamedArg (Ranged Int) -> NotationPart
HolePart Range
r NamedArg (Ranged Int)
h NotationPart -> Notation -> Notation
forall a. a -> [a] -> [a]
: Ranged BoundVariablePosition -> NotationPart
WildPart Ranged BoundVariablePosition
w NotationPart -> Notation -> Notation
forall a. a -> [a] -> [a]
: Notation
hs
          ins Ranged BoundVariablePosition
w (NotationPart
h : Notation
hs) = NotationPart
h NotationPart -> Notation -> Notation
forall a. a -> [a] -> [a]
: Ranged BoundVariablePosition -> Notation -> Notation
insBefore Ranged BoundVariablePosition
w Notation
hs
          ins Ranged BoundVariablePosition
_ [] = Notation
forall a. HasCallStack => a
__IMPOSSIBLE__
          insBefore :: Ranged BoundVariablePosition -> Notation -> Notation
insBefore Ranged BoundVariablePosition
w (HolePart Range
r NamedArg (Ranged Int)
h : Notation
hs)
            | NamedArg (Ranged Int) -> Ranged Int
forall a. NamedArg a -> a
namedArg NamedArg (Ranged Int)
h Ranged Int -> Ranged Int -> Bool
forall a. Eq a => a -> a -> Bool
== (BoundVariablePosition -> Int)
-> Ranged BoundVariablePosition -> Ranged Int
forall a b. (a -> b) -> Ranged a -> Ranged b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap BoundVariablePosition -> Int
holeNumber Ranged BoundVariablePosition
w =
              Ranged BoundVariablePosition -> NotationPart
WildPart Ranged BoundVariablePosition
w NotationPart -> Notation -> Notation
forall a. a -> [a] -> [a]
: Range -> NamedArg (Ranged Int) -> NotationPart
HolePart Range
r NamedArg (Ranged Int)
h NotationPart -> Notation -> Notation
forall a. a -> [a] -> [a]
: Notation
hs
          insBefore Ranged BoundVariablePosition
w (NotationPart
h : Notation
hs) = NotationPart
h NotationPart -> Notation -> Notation
forall a. a -> [a] -> [a]
: Ranged BoundVariablePosition -> Notation -> Notation
insBefore Ranged BoundVariablePosition
w Notation
hs
          insBefore Ranged BoundVariablePosition
_ [] = Notation
forall a. HasCallStack => a
__IMPOSSIBLE__
      
      
      
      
      holeMap :: [(RString, NotationPart)]
      holeMap :: [(Ranged [Char], NotationPart)]
holeMap = do
        (Int
i, NamedArg HoleName
h) <- [(Int, NamedArg HoleName)]
numberedHoles
        let ri :: Ranged [Char] -> Ranged Int
ri Ranged [Char]
x   = Range -> Int -> Ranged Int
forall a. Range -> a -> Ranged a
Ranged (Ranged [Char] -> Range
forall a. HasRange a => a -> Range
getRange Ranged [Char]
x) Int
i
            rp :: Ranged [Char] -> Int -> Ranged BoundVariablePosition
rp Ranged [Char]
x Int
n = Range -> BoundVariablePosition -> Ranged BoundVariablePosition
forall a. Range -> a -> Ranged a
Ranged (Ranged [Char] -> Range
forall a. HasRange a => a -> Range
getRange Ranged [Char]
x) (BoundVariablePosition -> Ranged BoundVariablePosition)
-> BoundVariablePosition -> Ranged BoundVariablePosition
forall a b. (a -> b) -> a -> b
$
                     BoundVariablePosition
                       { holeNumber :: Int
holeNumber = Int
i
                       , varNumber :: Int
varNumber  = Int
n
                       }
            hole :: Ranged [Char] -> NotationPart
hole Ranged [Char]
y = Range -> NamedArg (Ranged Int) -> NotationPart
HolePart Range
forall a. Range' a
noRange (NamedArg (Ranged Int) -> NotationPart)
-> NamedArg (Ranged Int) -> NotationPart
forall a b. (a -> b) -> a -> b
$ (Named NamedName HoleName -> Named_ (Ranged Int))
-> NamedArg HoleName -> NamedArg (Ranged Int)
forall a b. (a -> b) -> Arg a -> Arg b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Ranged [Char] -> Ranged Int
ri Ranged [Char]
y Ranged Int -> Named NamedName HoleName -> Named_ (Ranged Int)
forall a b. a -> Named NamedName b -> Named NamedName a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$) NamedArg HoleName
h
                              
        case NamedArg HoleName -> HoleName
forall a. NamedArg a -> a
namedArg NamedArg HoleName
h of
          ExprHole Ranged [Char]
y      -> [(Ranged [Char]
y, Ranged [Char] -> NotationPart
hole Ranged [Char]
y)]
          LambdaHole List1 (Ranged [Char])
xs Ranged [Char]
y -> [(Ranged [Char]
y, Ranged [Char] -> NotationPart
hole Ranged [Char]
y)] [(Ranged [Char], NotationPart)]
-> [(Ranged [Char], NotationPart)]
-> [(Ranged [Char], NotationPart)]
forall a. [a] -> [a] -> [a]
++
            (Int -> Ranged [Char] -> (Ranged [Char], NotationPart))
-> [Int] -> [Ranged [Char]] -> [(Ranged [Char], NotationPart)]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith
              (\ Int
n Ranged [Char]
x -> case Ranged [Char] -> [Char]
forall a. Ranged a -> a
rangedThing Ranged [Char]
x of
                [Char]
"_" -> (Ranged [Char]
x, Ranged BoundVariablePosition -> NotationPart
WildPart (Ranged [Char] -> Int -> Ranged BoundVariablePosition
rp Ranged [Char]
x Int
n))
                [Char]
_   -> (Ranged [Char]
x, Range -> Ranged BoundVariablePosition -> NotationPart
VarPart Range
forall a. Range' a
noRange (Ranged [Char] -> Int -> Ranged BoundVariablePosition
rp Ranged [Char]
x Int
n)))
                                   
              [Int
0..]
              (List1 (Ranged [Char]) -> [Item (List1 (Ranged [Char]))]
forall l. IsList l => l -> [Item l]
List1.toList List1 (Ranged [Char])
xs)
      
      
      uniqueHoleNames :: Bool
uniqueHoleNames = [Ranged [Char]] -> Bool
forall a. Eq a => [a] -> Bool
distinct [ Ranged [Char]
x | (Ranged [Char]
x, NotationPart
_) <- [(Ranged [Char], NotationPart)]
holeMap, Ranged [Char] -> [Char]
forall a. Ranged a -> a
rangedThing Ranged [Char]
x [Char] -> [Char] -> Bool
forall a. Eq a => a -> a -> Bool
/= [Char]
"_" ]
      isExprLinear :: Notation -> Bool
isExprLinear Notation
xs =
        [Int] -> [Int]
forall a. Ord a => [a] -> [a]
List.sort [ Int
i | NotationPart
x <- Notation
xs, NotationPart -> Bool
isAHole NotationPart
x, let Just Int
i = NotationPart -> Maybe Int
holeTarget NotationPart
x ]
          [Int] -> [Int] -> Bool
forall a. Eq a => a -> a -> Bool
==
        [Int]
holeNumbers
      isLambdaLinear :: Notation -> Bool
isLambdaLinear Notation
xs =
        [BoundVariablePosition] -> [BoundVariablePosition]
forall a. Ord a => [a] -> [a]
List.sort [ Ranged BoundVariablePosition -> BoundVariablePosition
forall a. Ranged a -> a
rangedThing Ranged BoundVariablePosition
x | VarPart Range
_ Ranged BoundVariablePosition
x <- Notation
xs ]
          [BoundVariablePosition] -> [BoundVariablePosition] -> Bool
forall a. Eq a => a -> a -> Bool
==
        [ BoundVariablePosition { holeNumber :: Int
holeNumber = Int
i, varNumber :: Int
varNumber = Int
v }
        | (Int
i, NamedArg HoleName
h) <- [(Int, NamedArg HoleName)]
numberedHoles
        , LambdaHole List1 (Ranged [Char])
vs Ranged [Char]
_ <- [NamedArg HoleName -> HoleName
forall a. NamedArg a -> a
namedArg NamedArg HoleName
h]
        , (Int
v, [Char]
x) <- [Int] -> [[Char]] -> [(Int, [Char])]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0..] ([[Char]] -> [(Int, [Char])]) -> [[Char]] -> [(Int, [Char])]
forall a b. (a -> b) -> a -> b
$ (Ranged [Char] -> [Char]) -> [Ranged [Char]] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map Ranged [Char] -> [Char]
forall a. Ranged a -> a
rangedThing ([Ranged [Char]] -> [[Char]]) -> [Ranged [Char]] -> [[Char]]
forall a b. (a -> b) -> a -> b
$ List1 (Ranged [Char]) -> [Item (List1 (Ranged [Char]))]
forall l. IsList l => l -> [Item l]
List1.toList List1 (Ranged [Char])
vs
        , [Char]
x [Char] -> [Char] -> Bool
forall a. Eq a => a -> a -> Bool
/= [Char]
"_"
        ]
      noAdjacentHoles :: [NotationPart] -> Bool
      noAdjacentHoles :: Notation -> Bool
noAdjacentHoles =
        Notation -> Bool
noAdj (Notation -> Bool) -> (Notation -> Notation) -> Notation -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
        (NotationPart -> Bool) -> Notation -> Notation
forall a. (a -> Bool) -> [a] -> [a]
filter (\NotationPart
h -> case NotationPart
h of
                   HolePart{} -> Bool
True
                   IdPart{}   -> Bool
True
                   NotationPart
_          -> Bool
False)
        where
        noAdj :: Notation -> Bool
noAdj []       = Bool
forall a. HasCallStack => a
__IMPOSSIBLE__
        noAdj [NotationPart
x]      = Bool
True
        noAdj (NotationPart
x:NotationPart
y:Notation
xs) =
          Bool -> Bool
not (NotationPart -> Bool
isAHole NotationPart
x Bool -> Bool -> Bool
&& NotationPart -> Bool
isAHole NotationPart
y) Bool -> Bool -> Bool
&&
          Notation -> Bool
noAdj (NotationPart
yNotationPart -> Notation -> Notation
forall a. a -> [a] -> [a]
:Notation
xs)
      isSingleHole :: [NotationPart] -> Bool
      isSingleHole :: Notation -> Bool
isSingleHole = \case
        [ IdPart{} ] -> Bool
False
        [ NotationPart
_hole ]    -> Bool
True
        Notation
_            -> Bool
False
data NewNotation = NewNotation
  { NewNotation -> QName
notaName  :: QName
  , NewNotation -> Set Name
notaNames :: Set A.Name
    
    
    
    
  , NewNotation -> Fixity
notaFixity :: Fixity
    
  , NewNotation -> Notation
notation :: Notation
    
  , NewNotation -> Bool
notaIsOperator :: Bool
    
    
  } deriving (Int -> NewNotation -> ShowS
[NewNotation] -> ShowS
NewNotation -> [Char]
(Int -> NewNotation -> ShowS)
-> (NewNotation -> [Char])
-> ([NewNotation] -> ShowS)
-> Show NewNotation
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> NewNotation -> ShowS
showsPrec :: Int -> NewNotation -> ShowS
$cshow :: NewNotation -> [Char]
show :: NewNotation -> [Char]
$cshowList :: [NewNotation] -> ShowS
showList :: [NewNotation] -> ShowS
Show, (forall x. NewNotation -> Rep NewNotation x)
-> (forall x. Rep NewNotation x -> NewNotation)
-> Generic NewNotation
forall x. Rep NewNotation x -> NewNotation
forall x. NewNotation -> Rep NewNotation x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. NewNotation -> Rep NewNotation x
from :: forall x. NewNotation -> Rep NewNotation x
$cto :: forall x. Rep NewNotation x -> NewNotation
to :: forall x. Rep NewNotation x -> NewNotation
Generic)
instance LensFixity NewNotation where
  lensFixity :: Lens' NewNotation Fixity
lensFixity Fixity -> f Fixity
f NewNotation
nota = Fixity -> f Fixity
f (NewNotation -> Fixity
notaFixity NewNotation
nota) f Fixity -> (Fixity -> NewNotation) -> f NewNotation
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \ Fixity
fx -> NewNotation
nota { notaFixity = fx }
namesToNotation :: QName -> A.Name -> NewNotation
namesToNotation :: QName -> Name -> NewNotation
namesToNotation QName
q Name
n = NewNotation
  { notaName :: QName
notaName       = QName
q
  , notaNames :: Set Name
notaNames      = Name -> Set Name
forall a. a -> Set a
Set.singleton Name
n
  , notaFixity :: Fixity
notaFixity     = Fixity
f
  , notation :: Notation
notation       = if Notation -> Bool
forall a. Null a => a -> Bool
null Notation
syn then Name -> Notation
syntaxOf (QName -> Name
unqualify QName
q) else Notation
syn
  , notaIsOperator :: Bool
notaIsOperator = Notation -> Bool
forall a. Null a => a -> Bool
null Notation
syn
  }
  where Fixity' Fixity
f Notation
syn Range
_ = Name -> Fixity'
A.nameFixity Name
n
useDefaultFixity :: NewNotation -> NewNotation
useDefaultFixity :: NewNotation -> NewNotation
useDefaultFixity NewNotation
n
  | NewNotation -> Fixity
notaFixity NewNotation
n Fixity -> Fixity -> Bool
forall a. Eq a => a -> a -> Bool
== Fixity
noFixity = NewNotation
n { notaFixity = defaultFixity }
  | Bool
otherwise                = NewNotation
n
notationNames :: NewNotation -> [QName]
notationNames :: NewNotation -> [QName]
notationNames (NewNotation QName
q Set Name
_ Fixity
_ Notation
parts Bool
_) =
  ((Name -> QName) -> Name -> QName)
-> [Name -> QName] -> [Name] -> [QName]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (Name -> QName) -> Name -> QName
forall a b. (a -> b) -> a -> b
($) (Name -> QName
reQualify (Name -> QName) -> [Name -> QName] -> [Name -> QName]
forall a. a -> [a] -> [a]
: (Name -> QName) -> [Name -> QName]
forall a. a -> [a]
repeat Name -> QName
QName) [[Char] -> Name
simpleName ([Char] -> Name) -> [Char] -> Name
forall a b. (a -> b) -> a -> b
$ Ranged [Char] -> [Char]
forall a. Ranged a -> a
rangedThing Ranged [Char]
x | IdPart Ranged [Char]
x <- Notation
parts ]
  where
    
    modules :: [Name]
modules     = NonEmpty Name -> [Name]
forall a. NonEmpty a -> [a]
List1.init (QName -> NonEmpty Name
qnameParts QName
q)
    
    reQualify :: Name -> QName
reQualify Name
x = (Name -> QName -> QName) -> QName -> [Name] -> QName
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
List.foldr Name -> QName -> QName
Qual (Name -> QName
QName Name
x) [Name]
modules
syntaxOf :: Name -> Notation
syntaxOf :: Name -> Notation
syntaxOf Name
y
  | Name -> Bool
isOperator Name
y = Int -> [NamePart] -> Notation
mkSyn Int
0 ([NamePart] -> Notation) -> [NamePart] -> Notation
forall a b. (a -> b) -> a -> b
$ NameParts -> [Item NameParts]
forall l. IsList l => l -> [Item l]
List1.toList (NameParts -> [Item NameParts]) -> NameParts -> [Item NameParts]
forall a b. (a -> b) -> a -> b
$ Name -> NameParts
nameNameParts Name
y
  | Bool
otherwise    = Notation
noNotation
  where
    
    
    
    mkSyn :: Int -> [NamePart] -> Notation
    mkSyn :: Int -> [NamePart] -> Notation
mkSyn Int
n []          = []
    mkSyn Int
n (NamePart
Hole : [NamePart]
xs) = Range -> NamedArg (Ranged Int) -> NotationPart
HolePart Range
forall a. Range' a
noRange (Ranged Int -> NamedArg (Ranged Int)
forall a. a -> NamedArg a
defaultNamedArg (Ranged Int -> NamedArg (Ranged Int))
-> Ranged Int -> NamedArg (Ranged Int)
forall a b. (a -> b) -> a -> b
$ Int -> Ranged Int
forall a. a -> Ranged a
unranged Int
n) NotationPart -> Notation -> Notation
forall a. a -> [a] -> [a]
: Int -> [NamePart] -> Notation
mkSyn (Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
n) [NamePart]
xs
    mkSyn Int
n (Id [Char]
x : [NamePart]
xs) = Ranged [Char] -> NotationPart
IdPart ([Char] -> Ranged [Char]
forall a. a -> Ranged a
unranged [Char]
x) NotationPart -> Notation -> Notation
forall a. a -> [a] -> [a]
: Int -> [NamePart] -> Notation
mkSyn Int
n [NamePart]
xs
mergeNotations :: List1 NewNotation -> List1 NewNotation
mergeNotations :: NonEmpty NewNotation -> NonEmpty NewNotation
mergeNotations =
  (NonEmpty NewNotation -> NewNotation)
-> List1 (NonEmpty NewNotation) -> NonEmpty NewNotation
forall a b. (a -> b) -> NonEmpty a -> NonEmpty b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap NonEmpty NewNotation -> NewNotation
merge
  (List1 (NonEmpty NewNotation) -> NonEmpty NewNotation)
-> (NonEmpty NewNotation -> List1 (NonEmpty NewNotation))
-> NonEmpty NewNotation
-> NonEmpty NewNotation
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (NonEmpty NewNotation -> List1 (NonEmpty NewNotation))
-> List1 (NonEmpty NewNotation) -> List1 (NonEmpty NewNotation)
forall a b. (a -> List1 b) -> List1 a -> List1 b
List1.concatMap1 NonEmpty NewNotation -> List1 (NonEmpty NewNotation)
groupIfLevelsMatch
  (List1 (NonEmpty NewNotation) -> List1 (NonEmpty NewNotation))
-> (NonEmpty NewNotation -> List1 (NonEmpty NewNotation))
-> NonEmpty NewNotation
-> List1 (NonEmpty NewNotation)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (NewNotation -> (Notation, Bool))
-> NonEmpty NewNotation -> List1 (NonEmpty NewNotation)
forall b a. Ord b => (a -> b) -> List1 a -> List1 (List1 a)
List1.groupOn1 (NewNotation -> Notation
notation (NewNotation -> Notation)
-> (NewNotation -> Bool) -> NewNotation -> (Notation, Bool)
forall b c c'. (b -> c) -> (b -> c') -> b -> (c, c')
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& NewNotation -> Bool
notaIsOperator)
  where
  groupIfLevelsMatch :: List1 NewNotation -> List1 (List1 NewNotation)
  groupIfLevelsMatch :: NonEmpty NewNotation -> List1 (NonEmpty NewNotation)
groupIfLevelsMatch NonEmpty NewNotation
ns =
    if [FixityLevel] -> Bool
forall a. Eq a => [a] -> Bool
allEqual ((Fixity -> FixityLevel) -> [Fixity] -> [FixityLevel]
forall a b. (a -> b) -> [a] -> [b]
map Fixity -> FixityLevel
fixityLevel [Fixity]
related)
    then NonEmpty NewNotation -> List1 (NonEmpty NewNotation)
forall el coll. Singleton el coll => el -> coll
singleton (NonEmpty NewNotation -> List1 (NonEmpty NewNotation))
-> NonEmpty NewNotation -> List1 (NonEmpty NewNotation)
forall a b. (a -> b) -> a -> b
$ NonEmpty NewNotation -> NonEmpty NewNotation
sameAssoc (NonEmpty NewNotation -> NonEmpty NewNotation)
-> NonEmpty NewNotation -> NonEmpty NewNotation
forall a b. (a -> b) -> a -> b
$ NonEmpty NewNotation -> NonEmpty NewNotation
sameLevel NonEmpty NewNotation
ns
    else (NewNotation -> NonEmpty NewNotation)
-> NonEmpty NewNotation -> List1 (NonEmpty NewNotation)
forall a b. (a -> b) -> NonEmpty a -> NonEmpty b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap NewNotation -> NonEmpty NewNotation
forall el coll. Singleton el coll => el -> coll
singleton NonEmpty NewNotation
ns
    where
    
    related :: [Fixity]
related = (NewNotation -> Maybe Fixity) -> NonEmpty NewNotation -> [Fixity]
forall a b. (a -> Maybe b) -> List1 a -> [b]
List1.mapMaybe (Fixity -> Maybe Fixity
maybeRelated (Fixity -> Maybe Fixity)
-> (NewNotation -> Fixity) -> NewNotation -> Maybe Fixity
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NewNotation -> Fixity
notaFixity) NonEmpty NewNotation
ns
      where
        maybeRelated :: Fixity -> Maybe Fixity
maybeRelated Fixity
f =
          case Fixity -> FixityLevel
fixityLevel Fixity
f of
            FixityLevel
Unrelated  -> Maybe Fixity
forall a. Maybe a
Nothing
            Related {} -> Fixity -> Maybe Fixity
forall a. a -> Maybe a
Just Fixity
f
    
    
    
    
    sameLevel :: NonEmpty NewNotation -> NonEmpty NewNotation
sameLevel = (NewNotation -> NewNotation)
-> NonEmpty NewNotation -> NonEmpty NewNotation
forall a b. (a -> b) -> NonEmpty a -> NonEmpty b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Lens' NewNotation FixityLevel -> LensSet NewNotation FixityLevel
forall o i. Lens' o i -> LensSet o i
set ((Fixity -> f Fixity) -> NewNotation -> f NewNotation
Lens' NewNotation Fixity
_notaFixity ((Fixity -> f Fixity) -> NewNotation -> f NewNotation)
-> ((FixityLevel -> f FixityLevel) -> Fixity -> f Fixity)
-> (FixityLevel -> f FixityLevel)
-> NewNotation
-> f NewNotation
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (FixityLevel -> f FixityLevel) -> Fixity -> f Fixity
Lens' Fixity FixityLevel
_fixityLevel) FixityLevel
level)
      where
      level :: FixityLevel
level = case [Fixity]
related of
        Fixity
f : [Fixity]
_ -> Fixity -> FixityLevel
fixityLevel Fixity
f
        []    -> FixityLevel
Unrelated
    
    
    
    sameAssoc :: NonEmpty NewNotation -> NonEmpty NewNotation
sameAssoc = (NewNotation -> NewNotation)
-> NonEmpty NewNotation -> NonEmpty NewNotation
forall a b. (a -> b) -> NonEmpty a -> NonEmpty b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Lens' NewNotation Associativity
-> LensSet NewNotation Associativity
forall o i. Lens' o i -> LensSet o i
set ((Fixity -> f Fixity) -> NewNotation -> f NewNotation
Lens' NewNotation Fixity
_notaFixity ((Fixity -> f Fixity) -> NewNotation -> f NewNotation)
-> ((Associativity -> f Associativity) -> Fixity -> f Fixity)
-> (Associativity -> f Associativity)
-> NewNotation
-> f NewNotation
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Associativity -> f Associativity) -> Fixity -> f Fixity
Lens' Fixity Associativity
_fixityAssoc) Associativity
assoc)
      where
      assoc :: Associativity
assoc = case [Fixity]
related of
        Fixity
f : [Fixity]
_ | [Associativity] -> Bool
forall a. Eq a => [a] -> Bool
allEqual ((Fixity -> Associativity) -> [Fixity] -> [Associativity]
forall a b. (a -> b) -> [a] -> [b]
map Fixity -> Associativity
fixityAssoc [Fixity]
related) -> Fixity -> Associativity
fixityAssoc Fixity
f
        [Fixity]
_                                          -> Associativity
NonAssoc
  merge :: List1 NewNotation -> NewNotation
  merge :: NonEmpty NewNotation -> NewNotation
merge (NewNotation
n :| [NewNotation]
ns) = NewNotation
n { notaNames = Set.unions $ map notaNames $ n:ns }
isLambdaNotation :: NewNotation -> Bool
isLambdaNotation :: NewNotation -> Bool
isLambdaNotation NewNotation
n = (NotationPart -> Bool) -> Notation -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any NotationPart -> Bool
isBinder (NewNotation -> Notation
notation NewNotation
n)
  where
    isBinder :: NotationPart -> Bool
isBinder VarPart{}  = Bool
True
    isBinder WildPart{} = Bool
True
    isBinder IdPart{}   = Bool
False
    isBinder HolePart{} = Bool
False
_notaFixity :: Lens' NewNotation Fixity
_notaFixity :: Lens' NewNotation Fixity
_notaFixity Fixity -> f Fixity
f NewNotation
r = Fixity -> f Fixity
f (NewNotation -> Fixity
notaFixity NewNotation
r) f Fixity -> (Fixity -> NewNotation) -> f NewNotation
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \Fixity
x -> NewNotation
r { notaFixity = x }
data NotationSection = NotationSection
  { NotationSection -> NewNotation
sectNotation  :: NewNotation
  , NotationSection -> NotationKind
sectKind      :: NotationKind
    
    
  , NotationSection -> Maybe FixityLevel
sectLevel     :: Maybe FixityLevel
    
  , NotationSection -> Bool
sectIsSection :: Bool
    
  }
  deriving (Int -> NotationSection -> ShowS
[NotationSection] -> ShowS
NotationSection -> [Char]
(Int -> NotationSection -> ShowS)
-> (NotationSection -> [Char])
-> ([NotationSection] -> ShowS)
-> Show NotationSection
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> NotationSection -> ShowS
showsPrec :: Int -> NotationSection -> ShowS
$cshow :: NotationSection -> [Char]
show :: NotationSection -> [Char]
$cshowList :: [NotationSection] -> ShowS
showList :: [NotationSection] -> ShowS
Show, (forall x. NotationSection -> Rep NotationSection x)
-> (forall x. Rep NotationSection x -> NotationSection)
-> Generic NotationSection
forall x. Rep NotationSection x -> NotationSection
forall x. NotationSection -> Rep NotationSection x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. NotationSection -> Rep NotationSection x
from :: forall x. NotationSection -> Rep NotationSection x
$cto :: forall x. Rep NotationSection x -> NotationSection
to :: forall x. Rep NotationSection x -> NotationSection
Generic)
noSection :: NewNotation -> NotationSection
noSection :: NewNotation -> NotationSection
noSection NewNotation
n = NotationSection
  { sectNotation :: NewNotation
sectNotation  = NewNotation
n
  , sectKind :: NotationKind
sectKind      = Notation -> NotationKind
notationKind (NewNotation -> Notation
notation NewNotation
n)
  , sectLevel :: Maybe FixityLevel
sectLevel     = FixityLevel -> Maybe FixityLevel
forall a. a -> Maybe a
Just (Fixity -> FixityLevel
fixityLevel (NewNotation -> Fixity
notaFixity NewNotation
n))
  , sectIsSection :: Bool
sectIsSection = Bool
False
  }
instance Pretty NewNotation where
  pretty :: NewNotation -> Doc
pretty (NewNotation QName
x Set Name
_xs Fixity
fx Notation
nota Bool
isOp) = Doc -> Doc -> Doc -> Doc
hsepWith Doc
"=" Doc
px Doc
pn
    where
    px :: Doc
px = [Doc] -> Doc
forall (t :: * -> *). Foldable t => t Doc -> Doc
fsep [ if Bool
isOp then Doc
forall a. Null a => a
empty else Doc
"syntax" , Fixity -> Doc
forall a. Pretty a => a -> Doc
pretty Fixity
fx , QName -> Doc
forall a. Pretty a => a -> Doc
pretty QName
x ]
    pn :: Doc
pn = if Bool
isOp then Doc
forall a. Null a => a
empty else Notation -> Doc
forall a. Pretty a => a -> Doc
pretty Notation
nota
instance Pretty NotationKind where pretty :: NotationKind -> Doc
pretty = NotationKind -> Doc
forall a. Show a => a -> Doc
pshow
instance Pretty NotationSection where
  pretty :: NotationSection -> Doc
pretty (NotationSection NewNotation
nota NotationKind
kind Maybe FixityLevel
mlevel Bool
isSection)
    | Bool
isSection = [Doc] -> Doc
forall (t :: * -> *). Foldable t => t Doc -> Doc
fsep
        [ Doc
"section"
        , NotationKind -> Doc
forall a. Pretty a => a -> Doc
pretty NotationKind
kind
        , Doc -> (FixityLevel -> Doc) -> Maybe FixityLevel -> Doc
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Doc
forall a. Null a => a
empty FixityLevel -> Doc
forall a. Pretty a => a -> Doc
pretty Maybe FixityLevel
mlevel
        , NewNotation -> Doc
forall a. Pretty a => a -> Doc
pretty NewNotation
nota
        ]
    | Bool
otherwise = NewNotation -> Doc
forall a. Pretty a => a -> Doc
pretty NewNotation
nota
instance NFData NotationKind
instance NFData NewNotation
instance NFData NotationSection