module Swarm.Language.Parser.Comment (
populateComments,
populateStandaloneComments,
populateSuffixComments,
preorder,
revpostorder,
) where
import Control.Lens (backwards, mapMOf, (%~))
import Control.Lens.Plated (Plated, plate)
import Control.Monad ((>=>))
import Control.Monad.State (MonadState (..), State, evalState)
import Data.Foldable qualified as F
import Data.List (partition)
import Data.Sequence (Seq, (<|), (|>))
import Swarm.Language.Syntax
populateComments :: Seq Comment -> Syntax -> Syntax
Seq Comment
cmts = [Comment] -> Syntax -> Syntax
populateStandaloneComments [Comment]
standalone (Syntax -> Syntax) -> (Syntax -> Syntax) -> Syntax -> Syntax
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Comment] -> Syntax -> Syntax
populateSuffixComments [Comment]
suffix
where
([Comment]
standalone, [Comment]
suffix) = (Comment -> Bool) -> [Comment] -> ([Comment], [Comment])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition Comment -> Bool
isStandalone (Seq Comment -> [Comment]
forall a. Seq a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
F.toList Seq Comment
cmts)
insertComments ::
(SrcLoc -> SrcLoc -> Bool) ->
(Comment -> Comments -> Comments) ->
Syntax ->
State [Comment] Syntax
SrcLoc -> SrcLoc -> Bool
cmpLoc Comment -> Comments -> Comments
ins = Syntax -> State [Comment] Syntax
forall {m :: * -> *}. MonadState [Comment] m => Syntax -> m Syntax
go
where
go :: Syntax -> m Syntax
go s :: Syntax
s@(CSyntax SrcLoc
l Term
t Comments
cs) = do
[Comment]
curCmts <- m [Comment]
forall s (m :: * -> *). MonadState s m => m s
get
case [Comment]
curCmts of
[] -> Syntax -> m Syntax
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Syntax
s
(Comment
nextCmt : [Comment]
restCmts) -> case Comment -> SrcLoc
commentSrcLoc Comment
nextCmt SrcLoc -> SrcLoc -> Bool
`cmpLoc` SrcLoc
l of
Bool
True -> [Comment] -> m ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put [Comment]
restCmts m () -> m Syntax -> m Syntax
forall a b. m a -> m b -> m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Syntax -> m Syntax
go (SrcLoc -> Term -> Comments -> Syntax
CSyntax SrcLoc
l Term
t (Comment -> Comments -> Comments
ins Comment
nextCmt Comments
cs))
Bool
False -> Syntax -> m Syntax
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Syntax
s
populateStandaloneComments :: [Comment] -> Syntax -> Syntax
populateStandaloneComments :: [Comment] -> Syntax -> Syntax
populateStandaloneComments [Comment]
cmts =
(State [Comment] Syntax -> [Comment] -> Syntax)
-> [Comment] -> State [Comment] Syntax -> Syntax
forall a b c. (a -> b -> c) -> b -> a -> c
flip State [Comment] Syntax -> [Comment] -> Syntax
forall s a. State s a -> s -> a
evalState [Comment]
cmts
(State [Comment] Syntax -> Syntax)
-> (Syntax -> State [Comment] Syntax) -> Syntax -> Syntax
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Syntax -> State [Comment] Syntax)
-> Syntax -> State [Comment] Syntax
forall a (m :: * -> *).
(Plated a, Monad m) =>
(a -> m a) -> a -> m a
preorder ((SrcLoc -> SrcLoc -> Bool)
-> (Comment -> Comments -> Comments)
-> Syntax
-> State [Comment] Syntax
insertComments SrcLoc -> SrcLoc -> Bool
srcLocStartsBefore (\Comment
c -> (Seq Comment -> Identity (Seq Comment))
-> Comments -> Identity Comments
Lens' Comments (Seq Comment)
beforeComments ((Seq Comment -> Identity (Seq Comment))
-> Comments -> Identity Comments)
-> (Seq Comment -> Seq Comment) -> Comments -> Comments
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ (Seq Comment -> Comment -> Seq Comment
forall a. Seq a -> a -> Seq a
|> Comment
c)))
populateSuffixComments :: [Comment] -> Syntax -> Syntax
[Comment]
cmts =
(State [Comment] Syntax -> [Comment] -> Syntax)
-> [Comment] -> State [Comment] Syntax -> Syntax
forall a b c. (a -> b -> c) -> b -> a -> c
flip State [Comment] Syntax -> [Comment] -> Syntax
forall s a. State s a -> s -> a
evalState ([Comment] -> [Comment]
forall a. [a] -> [a]
reverse [Comment]
cmts)
(State [Comment] Syntax -> Syntax)
-> (Syntax -> State [Comment] Syntax) -> Syntax -> Syntax
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Syntax -> State [Comment] Syntax)
-> Syntax -> State [Comment] Syntax
forall a (m :: * -> *).
(Plated a, Monad m) =>
(a -> m a) -> a -> m a
revpostorder ((SrcLoc -> SrcLoc -> Bool)
-> (Comment -> Comments -> Comments)
-> Syntax
-> State [Comment] Syntax
insertComments ((SrcLoc -> SrcLoc -> Bool) -> SrcLoc -> SrcLoc -> Bool
forall a b c. (a -> b -> c) -> b -> a -> c
flip SrcLoc -> SrcLoc -> Bool
srcLocEndsBefore) (\Comment
c -> (Seq Comment -> Identity (Seq Comment))
-> Comments -> Identity Comments
Lens' Comments (Seq Comment)
afterComments ((Seq Comment -> Identity (Seq Comment))
-> Comments -> Identity Comments)
-> (Seq Comment -> Seq Comment) -> Comments -> Comments
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ (Comment
c Comment -> Seq Comment -> Seq Comment
forall a. a -> Seq a -> Seq a
<|)))
preorder :: (Plated a, Monad m) => (a -> m a) -> (a -> m a)
preorder :: forall a (m :: * -> *).
(Plated a, Monad m) =>
(a -> m a) -> a -> m a
preorder a -> m a
g = a -> m a
go
where
go :: a -> m a
go = a -> m a
g (a -> m a) -> (a -> m a) -> a -> m a
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> LensLike (WrappedMonad m) a a a a -> (a -> m a) -> a -> m a
forall (m :: * -> *) s t a b.
LensLike (WrappedMonad m) s t a b -> (a -> m b) -> s -> m t
mapMOf LensLike (WrappedMonad m) a a a a
forall a. Plated a => Traversal' a a
Traversal' a a
plate a -> m a
go
revpostorder :: (Plated a, Monad m) => (a -> m a) -> (a -> m a)
revpostorder :: forall a (m :: * -> *).
(Plated a, Monad m) =>
(a -> m a) -> a -> m a
revpostorder a -> m a
g = a -> m a
go
where
go :: a -> m a
go = a -> m a
g (a -> m a) -> (a -> m a) -> a -> m a
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> LensLike (WrappedMonad m) a a a a -> (a -> m a) -> a -> m a
forall (m :: * -> *) s t a b.
LensLike (WrappedMonad m) s t a b -> (a -> m b) -> s -> m t
mapMOf (Optical (->) (->) (Backwards (WrappedMonad m)) a a a a
-> LensLike (WrappedMonad m) a a a a
forall (p :: * -> * -> *) (q :: * -> * -> *) (f :: * -> *) s t a b.
(Profunctor p, Profunctor q) =>
Optical p q (Backwards f) s t a b -> Optical p q f s t a b
backwards Optical (->) (->) (Backwards (WrappedMonad m)) a a a a
forall a. Plated a => Traversal' a a
Traversal' a a
plate) a -> m a
go