{-# LANGUAGE QuasiQuotes #-}

-- |
-- Module      : Verismith.Shuffle
-- Description : Shuffle Verilog around.
-- Copyright   : (c) 2021, Yann Herklotz
-- License     : GPL-3
-- Maintainer  : yann [at] yannherklotz [dot] com
-- Stability   : experimental
-- Portability : POSIX
--
-- Shuffles the Verilog file around a bit.
module Verismith.Shuffle where

import Control.Lens hiding (Context)
import Control.Monad (replicateM)
import Control.Monad.Reader
import Control.Monad.State.Strict
import Data.Containers.ListUtils (nubOrd)
import Data.List (intercalate, partition)
import qualified Data.Map.Strict as Map
import Data.Maybe (fromMaybe)
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Text.IO as T
import Hedgehog (Gen, GenT, MonadGen)
import qualified Hedgehog as Hog
import qualified Hedgehog.Gen as Hog
import qualified Hedgehog.Range as HogR
import Verismith.Config
import Verismith.Generate
import Verismith.Utils
import Verismith.Verilog.AST
import Verismith.Verilog.BitVec
import Verismith.Verilog.CodeGen
import Verismith.Verilog.Eval
import Verismith.Verilog.Internal
import Verismith.Verilog.Mutate
import Verismith.Verilog.Quote

-- | Shuffles assign statements and always blocks in a Verilog file.
shuffleLinesModule :: (MonadGen m) => ModDecl a -> m (ModDecl a)
shuffleLinesModule :: forall (m :: * -> *) a. MonadGen m => ModDecl a -> m (ModDecl a)
shuffleLinesModule ModDecl a
m = do
  [ModItem a]
shuf' <- [ModItem a] -> m [ModItem a]
forall (m :: * -> *) a. MonadGen m => [a] -> m [a]
Hog.shuffle [ModItem a]
shuf
  ModDecl a -> m (ModDecl a)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (ModDecl a
m ModDecl a -> (ModDecl a -> ModDecl a) -> ModDecl a
forall a b. a -> (a -> b) -> b
& ([ModItem a] -> Identity [ModItem a])
-> ModDecl a -> Identity (ModDecl a)
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems (([ModItem a] -> Identity [ModItem a])
 -> ModDecl a -> Identity (ModDecl a))
-> [ModItem a] -> ModDecl a -> ModDecl a
forall s t a b. ASetter s t a b -> b -> s -> t
.~ ([ModItem a]
stat [ModItem a] -> [ModItem a] -> [ModItem a]
forall a. Semigroup a => a -> a -> a
<> [ModItem a]
shuf'))
  where
    ([ModItem a]
shuf, [ModItem a]
stat) =
      (ModItem a -> Bool) -> [ModItem a] -> ([ModItem a], [ModItem a])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition
        ( \ModItem a
x -> case ModItem a
x of
            Always Statement a
_ -> Bool
True
            ModCA ContAssign
_ -> Bool
True
            ModItem a
_ -> Bool
False
        )
        (ModDecl a
m ModDecl a
-> Getting [ModItem a] (ModDecl a) [ModItem a] -> [ModItem a]
forall s a. s -> Getting a s a -> a
^. Getting [ModItem a] (ModDecl a) [ModItem a]
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems)

renameIdent :: Map.Map Text Text -> Identifier -> Identifier
renameIdent :: Map Text Text -> Identifier -> Identifier
renameIdent Map Text Text
map (Identifier Text
e) = Text -> Identifier
Identifier (Text -> Identifier) -> Text -> Identifier
forall a b. (a -> b) -> a -> b
$ Text -> Text -> Map Text Text -> Text
forall k a. Ord k => a -> k -> Map k a -> a
Map.findWithDefault Text
e Text
e Map Text Text
map

renameExpr :: Map.Map Text Text -> Expr -> Expr
renameExpr :: Map Text Text -> Expr -> Expr
renameExpr Map Text Text
map (Id Identifier
e) = Identifier -> Expr
Id (Map Text Text -> Identifier -> Identifier
renameIdent Map Text Text
map Identifier
e)
renameExpr Map Text Text
map (VecSelect Identifier
e Expr
a) = Identifier -> Expr -> Expr
VecSelect (Map Text Text -> Identifier -> Identifier
renameIdent Map Text Text
map Identifier
e) Expr
a
renameExpr Map Text Text
map (RangeSelect Identifier
e Range
r) = Identifier -> Range -> Expr
RangeSelect (Map Text Text -> Identifier -> Identifier
renameIdent Map Text Text
map Identifier
e) Range
r
renameExpr Map Text Text
map (Appl Identifier
e Expr
r) = Identifier -> Expr -> Expr
Appl (Map Text Text -> Identifier -> Identifier
renameIdent Map Text Text
map Identifier
e) Expr
r
renameExpr Map Text Text
_ Expr
e = Expr
e

renameVariablesModule :: (MonadGen m) => ModDecl a -> m (ModDecl a)
renameVariablesModule :: forall (m :: * -> *) a. MonadGen m => ModDecl a -> m (ModDecl a)
renameVariablesModule ModDecl a
m = do
  [Text]
shuf' <- [Text] -> m [Text]
forall (m :: * -> *) a. MonadGen m => [a] -> m [a]
Hog.shuffle [Text]
ids
  let map :: Map Text Text
map = [(Text, Text)] -> Map Text Text
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList ([(Text, Text)] -> Map Text Text)
-> [(Text, Text)] -> Map Text Text
forall a b. (a -> b) -> a -> b
$ [Text] -> [Text] -> [(Text, Text)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Text]
ids [Text]
shuf'
  ModDecl a -> m (ModDecl a)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return
    ( ModDecl a
m
        ModDecl a -> (ModDecl a -> ModDecl a) -> ModDecl a
forall a b. a -> (a -> b) -> b
& (([ModItem a] -> Identity [ModItem a])
-> ModDecl a -> Identity (ModDecl a)
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems (([ModItem a] -> Identity [ModItem a])
 -> ModDecl a -> Identity (ModDecl a))
-> ((ModItem a -> Identity (ModItem a))
    -> [ModItem a] -> Identity [ModItem a])
-> (ModItem a -> Identity (ModItem a))
-> ModDecl a
-> Identity (ModDecl a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ModItem a -> Identity (ModItem a))
-> [ModItem a] -> Identity [ModItem a]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((ModItem a -> Identity (ModItem a))
 -> ModDecl a -> Identity (ModDecl a))
-> (ModItem a -> ModItem a) -> ModDecl a -> ModDecl a
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ ((Expr -> Expr) -> ModItem a -> ModItem a
forall a. Mutate a => (Expr -> Expr) -> a -> a
mutExpr ((Expr -> Expr) -> Expr -> Expr
forall a. Plated a => (a -> a) -> a -> a
transform ((Expr -> Expr) -> Expr -> Expr) -> (Expr -> Expr) -> Expr -> Expr
forall a b. (a -> b) -> a -> b
$ Map Text Text -> Expr -> Expr
renameExpr Map Text Text
map)))
          (ModDecl a -> ModDecl a)
-> (ModDecl a -> ModDecl a) -> ModDecl a -> ModDecl a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (([Port] -> Identity [Port]) -> ModDecl a -> Identity (ModDecl a)
forall a (f :: * -> *).
Applicative f =>
([Port] -> f [Port]) -> ModDecl a -> f (ModDecl a)
modOutPorts (([Port] -> Identity [Port]) -> ModDecl a -> Identity (ModDecl a))
-> ((Identifier -> Identity Identifier)
    -> [Port] -> Identity [Port])
-> (Identifier -> Identity Identifier)
-> ModDecl a
-> Identity (ModDecl a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Port -> Identity Port) -> [Port] -> Identity [Port]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((Port -> Identity Port) -> [Port] -> Identity [Port])
-> ((Identifier -> Identity Identifier) -> Port -> Identity Port)
-> (Identifier -> Identity Identifier)
-> [Port]
-> Identity [Port]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Identifier -> Identity Identifier) -> Port -> Identity Port
Lens' Port Identifier
portName ((Identifier -> Identity Identifier)
 -> ModDecl a -> Identity (ModDecl a))
-> (Identifier -> Identifier) -> ModDecl a -> ModDecl a
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ Map Text Text -> Identifier -> Identifier
renameIdent Map Text Text
map)
          (ModDecl a -> ModDecl a)
-> (ModDecl a -> ModDecl a) -> ModDecl a -> ModDecl a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (([Port] -> Identity [Port]) -> ModDecl a -> Identity (ModDecl a)
forall a (f :: * -> *).
Applicative f =>
([Port] -> f [Port]) -> ModDecl a -> f (ModDecl a)
modInPorts (([Port] -> Identity [Port]) -> ModDecl a -> Identity (ModDecl a))
-> ((Identifier -> Identity Identifier)
    -> [Port] -> Identity [Port])
-> (Identifier -> Identity Identifier)
-> ModDecl a
-> Identity (ModDecl a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Port -> Identity Port) -> [Port] -> Identity [Port]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((Port -> Identity Port) -> [Port] -> Identity [Port])
-> ((Identifier -> Identity Identifier) -> Port -> Identity Port)
-> (Identifier -> Identity Identifier)
-> [Port]
-> Identity [Port]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Identifier -> Identity Identifier) -> Port -> Identity Port
Lens' Port Identifier
portName ((Identifier -> Identity Identifier)
 -> ModDecl a -> Identity (ModDecl a))
-> (Identifier -> Identifier) -> ModDecl a -> ModDecl a
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ Map Text Text -> Identifier -> Identifier
renameIdent Map Text Text
map)
          (ModDecl a -> ModDecl a)
-> (ModDecl a -> ModDecl a) -> ModDecl a -> ModDecl a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (([ModItem a] -> Identity [ModItem a])
-> ModDecl a -> Identity (ModDecl a)
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems (([ModItem a] -> Identity [ModItem a])
 -> ModDecl a -> Identity (ModDecl a))
-> ((Identifier -> Identity Identifier)
    -> [ModItem a] -> Identity [ModItem a])
-> (Identifier -> Identity Identifier)
-> ModDecl a
-> Identity (ModDecl a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ModItem a -> Identity (ModItem a))
-> [ModItem a] -> Identity [ModItem a]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((ModItem a -> Identity (ModItem a))
 -> [ModItem a] -> Identity [ModItem a])
-> ((Identifier -> Identity Identifier)
    -> ModItem a -> Identity (ModItem a))
-> (Identifier -> Identity Identifier)
-> [ModItem a]
-> Identity [ModItem a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Port -> Identity Port) -> ModItem a -> Identity (ModItem a)
forall a (f :: * -> *).
Applicative f =>
(Port -> f Port) -> ModItem a -> f (ModItem a)
declPort ((Port -> Identity Port) -> ModItem a -> Identity (ModItem a))
-> ((Identifier -> Identity Identifier) -> Port -> Identity Port)
-> (Identifier -> Identity Identifier)
-> ModItem a
-> Identity (ModItem a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Identifier -> Identity Identifier) -> Port -> Identity Port
Lens' Port Identifier
portName ((Identifier -> Identity Identifier)
 -> ModDecl a -> Identity (ModDecl a))
-> (Identifier -> Identifier) -> ModDecl a -> ModDecl a
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ Map Text Text -> Identifier -> Identifier
renameIdent Map Text Text
map)
          (ModDecl a -> ModDecl a)
-> (ModDecl a -> ModDecl a) -> ModDecl a -> ModDecl a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ASetter (ModDecl a) (ModDecl a) (Statement a) (Statement a)
-> (Statement a -> Statement a) -> ModDecl a -> ModDecl a
forall a s t. Plated a => ASetter s t a a -> (a -> a) -> s -> t
transformOn (([ModItem a] -> Identity [ModItem a])
-> ModDecl a -> Identity (ModDecl a)
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems (([ModItem a] -> Identity [ModItem a])
 -> ModDecl a -> Identity (ModDecl a))
-> ((Statement a -> Identity (Statement a))
    -> [ModItem a] -> Identity [ModItem a])
-> ASetter (ModDecl a) (ModDecl a) (Statement a) (Statement a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ModItem a -> Identity (ModItem a))
-> [ModItem a] -> Identity [ModItem a]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((ModItem a -> Identity (ModItem a))
 -> [ModItem a] -> Identity [ModItem a])
-> ((Statement a -> Identity (Statement a))
    -> ModItem a -> Identity (ModItem a))
-> (Statement a -> Identity (Statement a))
-> [ModItem a]
-> Identity [ModItem a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Statement a -> Identity (Statement a))
-> ModItem a -> Identity (ModItem a)
forall a (p :: * -> * -> *) (f :: * -> *).
(Choice p, Applicative f) =>
p (Statement a) (f (Statement a)) -> p (ModItem a) (f (ModItem a))
_Always) ((Assign -> Identity Assign)
-> Statement a -> Identity (Statement a)
forall a (f :: * -> *).
Applicative f =>
(Assign -> f Assign) -> Statement a -> f (Statement a)
stmntBA ((Assign -> Identity Assign)
 -> Statement a -> Identity (Statement a))
-> ((Identifier -> Identity Identifier)
    -> Assign -> Identity Assign)
-> (Identifier -> Identity Identifier)
-> Statement a
-> Identity (Statement a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (LVal -> Identity LVal) -> Assign -> Identity Assign
Lens' Assign LVal
assignReg ((LVal -> Identity LVal) -> Assign -> Identity Assign)
-> ((Identifier -> Identity Identifier) -> LVal -> Identity LVal)
-> (Identifier -> Identity Identifier)
-> Assign
-> Identity Assign
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Identifier -> Identity Identifier) -> LVal -> Identity LVal
Traversal' LVal Identifier
regId ((Identifier -> Identity Identifier)
 -> Statement a -> Identity (Statement a))
-> (Identifier -> Identifier) -> Statement a -> Statement a
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ Map Text Text -> Identifier -> Identifier
renameIdent Map Text Text
map))
          (ModDecl a -> ModDecl a)
-> (ModDecl a -> ModDecl a) -> ModDecl a -> ModDecl a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ASetter (ModDecl a) (ModDecl a) (Statement a) (Statement a)
-> (Statement a -> Statement a) -> ModDecl a -> ModDecl a
forall a s t. Plated a => ASetter s t a a -> (a -> a) -> s -> t
transformOn (([ModItem a] -> Identity [ModItem a])
-> ModDecl a -> Identity (ModDecl a)
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems (([ModItem a] -> Identity [ModItem a])
 -> ModDecl a -> Identity (ModDecl a))
-> ((Statement a -> Identity (Statement a))
    -> [ModItem a] -> Identity [ModItem a])
-> ASetter (ModDecl a) (ModDecl a) (Statement a) (Statement a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ModItem a -> Identity (ModItem a))
-> [ModItem a] -> Identity [ModItem a]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((ModItem a -> Identity (ModItem a))
 -> [ModItem a] -> Identity [ModItem a])
-> ((Statement a -> Identity (Statement a))
    -> ModItem a -> Identity (ModItem a))
-> (Statement a -> Identity (Statement a))
-> [ModItem a]
-> Identity [ModItem a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Statement a -> Identity (Statement a))
-> ModItem a -> Identity (ModItem a)
forall a (p :: * -> * -> *) (f :: * -> *).
(Choice p, Applicative f) =>
p (Statement a) (f (Statement a)) -> p (ModItem a) (f (ModItem a))
_Always) ((Assign -> Identity Assign)
-> Statement a -> Identity (Statement a)
forall a (f :: * -> *).
Applicative f =>
(Assign -> f Assign) -> Statement a -> f (Statement a)
stmntNBA ((Assign -> Identity Assign)
 -> Statement a -> Identity (Statement a))
-> ((Identifier -> Identity Identifier)
    -> Assign -> Identity Assign)
-> (Identifier -> Identity Identifier)
-> Statement a
-> Identity (Statement a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (LVal -> Identity LVal) -> Assign -> Identity Assign
Lens' Assign LVal
assignReg ((LVal -> Identity LVal) -> Assign -> Identity Assign)
-> ((Identifier -> Identity Identifier) -> LVal -> Identity LVal)
-> (Identifier -> Identity Identifier)
-> Assign
-> Identity Assign
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Identifier -> Identity Identifier) -> LVal -> Identity LVal
Traversal' LVal Identifier
regId ((Identifier -> Identity Identifier)
 -> Statement a -> Identity (Statement a))
-> (Identifier -> Identifier) -> Statement a -> Statement a
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ Map Text Text -> Identifier -> Identifier
renameIdent Map Text Text
map))
          (ModDecl a -> ModDecl a)
-> (ModDecl a -> ModDecl a) -> ModDecl a -> ModDecl a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ASetter (ModDecl a) (ModDecl a) (Statement a) (Statement a)
-> (Statement a -> Statement a) -> ModDecl a -> ModDecl a
forall a s t. Plated a => ASetter s t a a -> (a -> a) -> s -> t
transformOn (([ModItem a] -> Identity [ModItem a])
-> ModDecl a -> Identity (ModDecl a)
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems (([ModItem a] -> Identity [ModItem a])
 -> ModDecl a -> Identity (ModDecl a))
-> ((Statement a -> Identity (Statement a))
    -> [ModItem a] -> Identity [ModItem a])
-> ASetter (ModDecl a) (ModDecl a) (Statement a) (Statement a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ModItem a -> Identity (ModItem a))
-> [ModItem a] -> Identity [ModItem a]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((ModItem a -> Identity (ModItem a))
 -> [ModItem a] -> Identity [ModItem a])
-> ((Statement a -> Identity (Statement a))
    -> ModItem a -> Identity (ModItem a))
-> (Statement a -> Identity (Statement a))
-> [ModItem a]
-> Identity [ModItem a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Statement a -> Identity (Statement a))
-> ModItem a -> Identity (ModItem a)
forall a (p :: * -> * -> *) (f :: * -> *).
(Choice p, Applicative f) =>
p (Statement a) (f (Statement a)) -> p (ModItem a) (f (ModItem a))
_Initial) ((Assign -> Identity Assign)
-> Statement a -> Identity (Statement a)
forall a (f :: * -> *).
Applicative f =>
(Assign -> f Assign) -> Statement a -> f (Statement a)
stmntBA ((Assign -> Identity Assign)
 -> Statement a -> Identity (Statement a))
-> ((Identifier -> Identity Identifier)
    -> Assign -> Identity Assign)
-> (Identifier -> Identity Identifier)
-> Statement a
-> Identity (Statement a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (LVal -> Identity LVal) -> Assign -> Identity Assign
Lens' Assign LVal
assignReg ((LVal -> Identity LVal) -> Assign -> Identity Assign)
-> ((Identifier -> Identity Identifier) -> LVal -> Identity LVal)
-> (Identifier -> Identity Identifier)
-> Assign
-> Identity Assign
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Identifier -> Identity Identifier) -> LVal -> Identity LVal
Traversal' LVal Identifier
regId ((Identifier -> Identity Identifier)
 -> Statement a -> Identity (Statement a))
-> (Identifier -> Identifier) -> Statement a -> Statement a
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ Map Text Text -> Identifier -> Identifier
renameIdent Map Text Text
map))
          (ModDecl a -> ModDecl a)
-> (ModDecl a -> ModDecl a) -> ModDecl a -> ModDecl a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ASetter (ModDecl a) (ModDecl a) (Statement a) (Statement a)
-> (Statement a -> Statement a) -> ModDecl a -> ModDecl a
forall a s t. Plated a => ASetter s t a a -> (a -> a) -> s -> t
transformOn (([ModItem a] -> Identity [ModItem a])
-> ModDecl a -> Identity (ModDecl a)
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems (([ModItem a] -> Identity [ModItem a])
 -> ModDecl a -> Identity (ModDecl a))
-> ((Statement a -> Identity (Statement a))
    -> [ModItem a] -> Identity [ModItem a])
-> ASetter (ModDecl a) (ModDecl a) (Statement a) (Statement a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ModItem a -> Identity (ModItem a))
-> [ModItem a] -> Identity [ModItem a]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((ModItem a -> Identity (ModItem a))
 -> [ModItem a] -> Identity [ModItem a])
-> ((Statement a -> Identity (Statement a))
    -> ModItem a -> Identity (ModItem a))
-> (Statement a -> Identity (Statement a))
-> [ModItem a]
-> Identity [ModItem a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Statement a -> Identity (Statement a))
-> ModItem a -> Identity (ModItem a)
forall a (p :: * -> * -> *) (f :: * -> *).
(Choice p, Applicative f) =>
p (Statement a) (f (Statement a)) -> p (ModItem a) (f (ModItem a))
_Initial) ((Assign -> Identity Assign)
-> Statement a -> Identity (Statement a)
forall a (f :: * -> *).
Applicative f =>
(Assign -> f Assign) -> Statement a -> f (Statement a)
stmntNBA ((Assign -> Identity Assign)
 -> Statement a -> Identity (Statement a))
-> ((Identifier -> Identity Identifier)
    -> Assign -> Identity Assign)
-> (Identifier -> Identity Identifier)
-> Statement a
-> Identity (Statement a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (LVal -> Identity LVal) -> Assign -> Identity Assign
Lens' Assign LVal
assignReg ((LVal -> Identity LVal) -> Assign -> Identity Assign)
-> ((Identifier -> Identity Identifier) -> LVal -> Identity LVal)
-> (Identifier -> Identity Identifier)
-> Assign
-> Identity Assign
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Identifier -> Identity Identifier) -> LVal -> Identity LVal
Traversal' LVal Identifier
regId ((Identifier -> Identity Identifier)
 -> Statement a -> Identity (Statement a))
-> (Identifier -> Identifier) -> Statement a -> Statement a
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ Map Text Text -> Identifier -> Identifier
renameIdent Map Text Text
map))
          (ModDecl a -> ModDecl a)
-> (ModDecl a -> ModDecl a) -> ModDecl a -> ModDecl a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (([ModItem a] -> Identity [ModItem a])
-> ModDecl a -> Identity (ModDecl a)
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems (([ModItem a] -> Identity [ModItem a])
 -> ModDecl a -> Identity (ModDecl a))
-> ((Identifier -> Identity Identifier)
    -> [ModItem a] -> Identity [ModItem a])
-> (Identifier -> Identity Identifier)
-> ModDecl a
-> Identity (ModDecl a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ModItem a -> Identity (ModItem a))
-> [ModItem a] -> Identity [ModItem a]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((ModItem a -> Identity (ModItem a))
 -> [ModItem a] -> Identity [ModItem a])
-> ((Identifier -> Identity Identifier)
    -> ModItem a -> Identity (ModItem a))
-> (Identifier -> Identity Identifier)
-> [ModItem a]
-> Identity [ModItem a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ContAssign -> Identity ContAssign)
-> ModItem a -> Identity (ModItem a)
forall a (f :: * -> *).
Applicative f =>
(ContAssign -> f ContAssign) -> ModItem a -> f (ModItem a)
modContAssign ((ContAssign -> Identity ContAssign)
 -> ModItem a -> Identity (ModItem a))
-> ((Identifier -> Identity Identifier)
    -> ContAssign -> Identity ContAssign)
-> (Identifier -> Identity Identifier)
-> ModItem a
-> Identity (ModItem a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Identifier -> Identity Identifier)
-> ContAssign -> Identity ContAssign
Lens' ContAssign Identifier
contAssignNetLVal ((Identifier -> Identity Identifier)
 -> ModDecl a -> Identity (ModDecl a))
-> (Identifier -> Identifier) -> ModDecl a -> ModDecl a
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ Map Text Text -> Identifier -> Identifier
renameIdent Map Text Text
map)
    )
  where
    ids :: [Text]
ids = [Text] -> [Text]
forall a. Ord a => [a] -> [a]
nubOrd ([Text] -> [Text]) -> [Text] -> [Text]
forall a b. (a -> b) -> a -> b
$ ((Expr -> [Expr]) -> [Expr] -> [Expr]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Expr -> [Expr]
forall a. Plated a => a -> [a]
universe ([Expr] -> [Expr]) -> [Expr] -> [Expr]
forall a b. (a -> b) -> a -> b
$ [Expr]
allExprCA [Expr] -> [Expr] -> [Expr]
forall a. Semigroup a => a -> a -> a
<> [Expr]
allExprStmnt) [Expr] -> Getting (Endo [Text]) [Expr] Text -> [Text]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. (Expr -> Const (Endo [Text]) Expr)
-> [Expr] -> Const (Endo [Text]) [Expr]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((Expr -> Const (Endo [Text]) Expr)
 -> [Expr] -> Const (Endo [Text]) [Expr])
-> ((Text -> Const (Endo [Text]) Text)
    -> Expr -> Const (Endo [Text]) Expr)
-> Getting (Endo [Text]) [Expr] Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Identifier -> Const (Endo [Text]) Identifier)
-> Expr -> Const (Endo [Text]) Expr
Prism' Expr Identifier
_Id ((Identifier -> Const (Endo [Text]) Identifier)
 -> Expr -> Const (Endo [Text]) Expr)
-> ((Text -> Const (Endo [Text]) Text)
    -> Identifier -> Const (Endo [Text]) Identifier)
-> (Text -> Const (Endo [Text]) Text)
-> Expr
-> Const (Endo [Text]) Expr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Unwrapped Identifier
 -> Const (Endo [Text]) (Unwrapped Identifier))
-> Identifier -> Const (Endo [Text]) Identifier
(Text -> Const (Endo [Text]) Text)
-> Identifier -> Const (Endo [Text]) Identifier
forall s t. Rewrapping s t => Iso s t (Unwrapped s) (Unwrapped t)
Iso
  Identifier Identifier (Unwrapped Identifier) (Unwrapped Identifier)
_Wrapped
    allExprCA :: [Expr]
allExprCA = ModDecl a
m ModDecl a -> Getting (Endo [Expr]) (ModDecl a) Expr -> [Expr]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. ([ModItem a] -> Const (Endo [Expr]) [ModItem a])
-> ModDecl a -> Const (Endo [Expr]) (ModDecl a)
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems (([ModItem a] -> Const (Endo [Expr]) [ModItem a])
 -> ModDecl a -> Const (Endo [Expr]) (ModDecl a))
-> ((Expr -> Const (Endo [Expr]) Expr)
    -> [ModItem a] -> Const (Endo [Expr]) [ModItem a])
-> Getting (Endo [Expr]) (ModDecl a) Expr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ModItem a -> Const (Endo [Expr]) (ModItem a))
-> [ModItem a] -> Const (Endo [Expr]) [ModItem a]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((ModItem a -> Const (Endo [Expr]) (ModItem a))
 -> [ModItem a] -> Const (Endo [Expr]) [ModItem a])
-> ((Expr -> Const (Endo [Expr]) Expr)
    -> ModItem a -> Const (Endo [Expr]) (ModItem a))
-> (Expr -> Const (Endo [Expr]) Expr)
-> [ModItem a]
-> Const (Endo [Expr]) [ModItem a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ContAssign -> Const (Endo [Expr]) ContAssign)
-> ModItem a -> Const (Endo [Expr]) (ModItem a)
forall a (f :: * -> *).
Applicative f =>
(ContAssign -> f ContAssign) -> ModItem a -> f (ModItem a)
modContAssign ((ContAssign -> Const (Endo [Expr]) ContAssign)
 -> ModItem a -> Const (Endo [Expr]) (ModItem a))
-> ((Expr -> Const (Endo [Expr]) Expr)
    -> ContAssign -> Const (Endo [Expr]) ContAssign)
-> (Expr -> Const (Endo [Expr]) Expr)
-> ModItem a
-> Const (Endo [Expr]) (ModItem a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Expr -> Const (Endo [Expr]) Expr)
-> ContAssign -> Const (Endo [Expr]) ContAssign
Lens' ContAssign Expr
contAssignExpr
    allExprStmnt :: [Expr]
allExprStmnt =
      ([Statement a]
allStat [Statement a] -> Getting (Endo [Expr]) [Statement a] Expr -> [Expr]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. (Statement a -> Const (Endo [Expr]) (Statement a))
-> [Statement a] -> Const (Endo [Expr]) [Statement a]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((Statement a -> Const (Endo [Expr]) (Statement a))
 -> [Statement a] -> Const (Endo [Expr]) [Statement a])
-> ((Expr -> Const (Endo [Expr]) Expr)
    -> Statement a -> Const (Endo [Expr]) (Statement a))
-> Getting (Endo [Expr]) [Statement a] Expr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Expr -> Const (Endo [Expr]) Expr)
-> Statement a -> Const (Endo [Expr]) (Statement a)
forall a (f :: * -> *).
Applicative f =>
(Expr -> f Expr) -> Statement a -> f (Statement a)
stmntCondExpr)
        [Expr] -> [Expr] -> [Expr]
forall a. Semigroup a => a -> a -> a
<> ([Statement a]
allStat [Statement a] -> Getting (Endo [Expr]) [Statement a] Expr -> [Expr]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. (Statement a -> Const (Endo [Expr]) (Statement a))
-> [Statement a] -> Const (Endo [Expr]) [Statement a]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((Statement a -> Const (Endo [Expr]) (Statement a))
 -> [Statement a] -> Const (Endo [Expr]) [Statement a])
-> ((Expr -> Const (Endo [Expr]) Expr)
    -> Statement a -> Const (Endo [Expr]) (Statement a))
-> Getting (Endo [Expr]) [Statement a] Expr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Expr -> Const (Endo [Expr]) Expr)
-> Statement a -> Const (Endo [Expr]) (Statement a)
forall a (f :: * -> *).
Applicative f =>
(Expr -> f Expr) -> Statement a -> f (Statement a)
stmntCaseExpr)
        [Expr] -> [Expr] -> [Expr]
forall a. Semigroup a => a -> a -> a
<> ([Statement a]
allStat [Statement a] -> Getting (Endo [Expr]) [Statement a] Expr -> [Expr]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. (Statement a -> Const (Endo [Expr]) (Statement a))
-> [Statement a] -> Const (Endo [Expr]) [Statement a]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((Statement a -> Const (Endo [Expr]) (Statement a))
 -> [Statement a] -> Const (Endo [Expr]) [Statement a])
-> ((Expr -> Const (Endo [Expr]) Expr)
    -> Statement a -> Const (Endo [Expr]) (Statement a))
-> Getting (Endo [Expr]) [Statement a] Expr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Expr -> Const (Endo [Expr]) Expr)
-> Statement a -> Const (Endo [Expr]) (Statement a)
forall a (f :: * -> *).
Applicative f =>
(Expr -> f Expr) -> Statement a -> f (Statement a)
forExpr)
        [Expr] -> [Expr] -> [Expr]
forall a. Semigroup a => a -> a -> a
<> ([Statement a]
allStat [Statement a] -> Getting (Endo [Expr]) [Statement a] Expr -> [Expr]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. (Statement a -> Const (Endo [Expr]) (Statement a))
-> [Statement a] -> Const (Endo [Expr]) [Statement a]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((Statement a -> Const (Endo [Expr]) (Statement a))
 -> [Statement a] -> Const (Endo [Expr]) [Statement a])
-> ((Expr -> Const (Endo [Expr]) Expr)
    -> Statement a -> Const (Endo [Expr]) (Statement a))
-> Getting (Endo [Expr]) [Statement a] Expr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Assign -> Const (Endo [Expr]) Assign)
-> Statement a -> Const (Endo [Expr]) (Statement a)
forall a (f :: * -> *).
Applicative f =>
(Assign -> f Assign) -> Statement a -> f (Statement a)
stmntBA ((Assign -> Const (Endo [Expr]) Assign)
 -> Statement a -> Const (Endo [Expr]) (Statement a))
-> ((Expr -> Const (Endo [Expr]) Expr)
    -> Assign -> Const (Endo [Expr]) Assign)
-> (Expr -> Const (Endo [Expr]) Expr)
-> Statement a
-> Const (Endo [Expr]) (Statement a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Expr -> Const (Endo [Expr]) Expr)
-> Assign -> Const (Endo [Expr]) Assign
Lens' Assign Expr
assignExpr)
        [Expr] -> [Expr] -> [Expr]
forall a. Semigroup a => a -> a -> a
<> ([Statement a]
allStat [Statement a] -> Getting (Endo [Expr]) [Statement a] Expr -> [Expr]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. (Statement a -> Const (Endo [Expr]) (Statement a))
-> [Statement a] -> Const (Endo [Expr]) [Statement a]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((Statement a -> Const (Endo [Expr]) (Statement a))
 -> [Statement a] -> Const (Endo [Expr]) [Statement a])
-> ((Expr -> Const (Endo [Expr]) Expr)
    -> Statement a -> Const (Endo [Expr]) (Statement a))
-> Getting (Endo [Expr]) [Statement a] Expr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Assign -> Const (Endo [Expr]) Assign)
-> Statement a -> Const (Endo [Expr]) (Statement a)
forall a (f :: * -> *).
Applicative f =>
(Assign -> f Assign) -> Statement a -> f (Statement a)
stmntNBA ((Assign -> Const (Endo [Expr]) Assign)
 -> Statement a -> Const (Endo [Expr]) (Statement a))
-> ((Expr -> Const (Endo [Expr]) Expr)
    -> Assign -> Const (Endo [Expr]) Assign)
-> (Expr -> Const (Endo [Expr]) Expr)
-> Statement a
-> Const (Endo [Expr]) (Statement a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Expr -> Const (Endo [Expr]) Expr)
-> Assign -> Const (Endo [Expr]) Assign
Lens' Assign Expr
assignExpr)
    allStat :: [Statement a]
allStat = (Statement a -> [Statement a]) -> [Statement a] -> [Statement a]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Statement a -> [Statement a]
forall a. Plated a => a -> [a]
universe [Statement a]
stat
    stat :: [Statement a]
stat =
      (ModDecl a
m ModDecl a
-> Getting (Endo [Statement a]) (ModDecl a) (Statement a)
-> [Statement a]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. ([ModItem a] -> Const (Endo [Statement a]) [ModItem a])
-> ModDecl a -> Const (Endo [Statement a]) (ModDecl a)
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems (([ModItem a] -> Const (Endo [Statement a]) [ModItem a])
 -> ModDecl a -> Const (Endo [Statement a]) (ModDecl a))
-> ((Statement a -> Const (Endo [Statement a]) (Statement a))
    -> [ModItem a] -> Const (Endo [Statement a]) [ModItem a])
-> Getting (Endo [Statement a]) (ModDecl a) (Statement a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ModItem a -> Const (Endo [Statement a]) (ModItem a))
-> [ModItem a] -> Const (Endo [Statement a]) [ModItem a]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((ModItem a -> Const (Endo [Statement a]) (ModItem a))
 -> [ModItem a] -> Const (Endo [Statement a]) [ModItem a])
-> ((Statement a -> Const (Endo [Statement a]) (Statement a))
    -> ModItem a -> Const (Endo [Statement a]) (ModItem a))
-> (Statement a -> Const (Endo [Statement a]) (Statement a))
-> [ModItem a]
-> Const (Endo [Statement a]) [ModItem a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Statement a -> Const (Endo [Statement a]) (Statement a))
-> ModItem a -> Const (Endo [Statement a]) (ModItem a)
forall a (p :: * -> * -> *) (f :: * -> *).
(Choice p, Applicative f) =>
p (Statement a) (f (Statement a)) -> p (ModItem a) (f (ModItem a))
_Initial)
        [Statement a] -> [Statement a] -> [Statement a]
forall a. Semigroup a => a -> a -> a
<> (ModDecl a
m ModDecl a
-> Getting (Endo [Statement a]) (ModDecl a) (Statement a)
-> [Statement a]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. ([ModItem a] -> Const (Endo [Statement a]) [ModItem a])
-> ModDecl a -> Const (Endo [Statement a]) (ModDecl a)
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems (([ModItem a] -> Const (Endo [Statement a]) [ModItem a])
 -> ModDecl a -> Const (Endo [Statement a]) (ModDecl a))
-> ((Statement a -> Const (Endo [Statement a]) (Statement a))
    -> [ModItem a] -> Const (Endo [Statement a]) [ModItem a])
-> Getting (Endo [Statement a]) (ModDecl a) (Statement a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ModItem a -> Const (Endo [Statement a]) (ModItem a))
-> [ModItem a] -> Const (Endo [Statement a]) [ModItem a]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((ModItem a -> Const (Endo [Statement a]) (ModItem a))
 -> [ModItem a] -> Const (Endo [Statement a]) [ModItem a])
-> ((Statement a -> Const (Endo [Statement a]) (Statement a))
    -> ModItem a -> Const (Endo [Statement a]) (ModItem a))
-> (Statement a -> Const (Endo [Statement a]) (Statement a))
-> [ModItem a]
-> Const (Endo [Statement a]) [ModItem a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Statement a -> Const (Endo [Statement a]) (Statement a))
-> ModItem a -> Const (Endo [Statement a]) (ModItem a)
forall a (p :: * -> * -> *) (f :: * -> *).
(Choice p, Applicative f) =>
p (Statement a) (f (Statement a)) -> p (ModItem a) (f (ModItem a))
_Always)

identModule :: (MonadGen m) => ModDecl a -> m (ModDecl a)
identModule :: forall (m :: * -> *) a. MonadGen m => ModDecl a -> m (ModDecl a)
identModule = ModDecl a -> m (ModDecl a)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return

applyModules :: (MonadGen m) => (ModDecl a -> m (ModDecl a)) -> SourceInfo a -> m (SourceInfo a)
applyModules :: forall (m :: * -> *) a.
MonadGen m =>
(ModDecl a -> m (ModDecl a)) -> SourceInfo a -> m (SourceInfo a)
applyModules ModDecl a -> m (ModDecl a)
f SourceInfo a
s = do
  [ModDecl a]
ms' <- [m (ModDecl a)] -> m [ModDecl a]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
forall (m :: * -> *) a. Monad m => [m a] -> m [a]
sequence (ModDecl a -> m (ModDecl a)
f (ModDecl a -> m (ModDecl a)) -> [ModDecl a] -> [m (ModDecl a)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [ModDecl a]
ms)
  SourceInfo a -> m (SourceInfo a)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (SourceInfo a
s SourceInfo a -> (SourceInfo a -> SourceInfo a) -> SourceInfo a
forall a b. a -> (a -> b) -> b
& (Verilog a -> Identity (Verilog a))
-> SourceInfo a -> Identity (SourceInfo a)
forall a1 a2 (f :: * -> *).
Functor f =>
(Verilog a1 -> f (Verilog a2))
-> SourceInfo a1 -> f (SourceInfo a2)
infoSrc ((Verilog a -> Identity (Verilog a))
 -> SourceInfo a -> Identity (SourceInfo a))
-> ((Unwrapped (Verilog a) -> Identity [ModDecl a])
    -> Verilog a -> Identity (Verilog a))
-> (Unwrapped (Verilog a) -> Identity [ModDecl a])
-> SourceInfo a
-> Identity (SourceInfo a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Unwrapped (Verilog a) -> Identity [ModDecl a])
-> Verilog a -> Identity (Verilog a)
(Unwrapped (Verilog a) -> Identity (Unwrapped (Verilog a)))
-> Verilog a -> Identity (Verilog a)
forall s t. Rewrapping s t => Iso s t (Unwrapped s) (Unwrapped t)
Iso
  (Verilog a)
  (Verilog a)
  (Unwrapped (Verilog a))
  (Unwrapped (Verilog a))
_Wrapped ((Unwrapped (Verilog a) -> Identity [ModDecl a])
 -> SourceInfo a -> Identity (SourceInfo a))
-> [ModDecl a] -> SourceInfo a -> SourceInfo a
forall s t a b. ASetter s t a b -> b -> s -> t
.~ [ModDecl a]
ms')
  where
    ms :: Unwrapped (Verilog a)
ms = SourceInfo a
s SourceInfo a
-> Getting
     (Unwrapped (Verilog a)) (SourceInfo a) (Unwrapped (Verilog a))
-> Unwrapped (Verilog a)
forall s a. s -> Getting a s a -> a
^. (Verilog a -> Const (Unwrapped (Verilog a)) (Verilog a))
-> SourceInfo a -> Const (Unwrapped (Verilog a)) (SourceInfo a)
forall a1 a2 (f :: * -> *).
Functor f =>
(Verilog a1 -> f (Verilog a2))
-> SourceInfo a1 -> f (SourceInfo a2)
infoSrc ((Verilog a -> Const (Unwrapped (Verilog a)) (Verilog a))
 -> SourceInfo a -> Const (Unwrapped (Verilog a)) (SourceInfo a))
-> ((Unwrapped (Verilog a)
     -> Const (Unwrapped (Verilog a)) (Unwrapped (Verilog a)))
    -> Verilog a -> Const (Unwrapped (Verilog a)) (Verilog a))
-> Getting
     (Unwrapped (Verilog a)) (SourceInfo a) (Unwrapped (Verilog a))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Unwrapped (Verilog a)
 -> Const (Unwrapped (Verilog a)) (Unwrapped (Verilog a)))
-> Verilog a -> Const (Unwrapped (Verilog a)) (Verilog a)
forall s t. Rewrapping s t => Iso s t (Unwrapped s) (Unwrapped t)
Iso
  (Verilog a)
  (Verilog a)
  (Unwrapped (Verilog a))
  (Unwrapped (Verilog a))
_Wrapped

shuffleLines, renameVariables, identityMod :: (SourceInfo a) -> Gen (SourceInfo a)
shuffleLines :: forall a. SourceInfo a -> Gen (SourceInfo a)
shuffleLines = (ModDecl a -> GenT Identity (ModDecl a))
-> SourceInfo a -> GenT Identity (SourceInfo a)
forall (m :: * -> *) a.
MonadGen m =>
(ModDecl a -> m (ModDecl a)) -> SourceInfo a -> m (SourceInfo a)
applyModules ModDecl a -> GenT Identity (ModDecl a)
forall (m :: * -> *) a. MonadGen m => ModDecl a -> m (ModDecl a)
shuffleLinesModule
renameVariables :: forall a. SourceInfo a -> Gen (SourceInfo a)
renameVariables = (ModDecl a -> GenT Identity (ModDecl a))
-> SourceInfo a -> GenT Identity (SourceInfo a)
forall (m :: * -> *) a.
MonadGen m =>
(ModDecl a -> m (ModDecl a)) -> SourceInfo a -> m (SourceInfo a)
applyModules ModDecl a -> GenT Identity (ModDecl a)
forall (m :: * -> *) a. MonadGen m => ModDecl a -> m (ModDecl a)
renameVariablesModule
identityMod :: forall a. SourceInfo a -> Gen (SourceInfo a)
identityMod = (ModDecl a -> GenT Identity (ModDecl a))
-> SourceInfo a -> GenT Identity (SourceInfo a)
forall (m :: * -> *) a.
MonadGen m =>
(ModDecl a -> m (ModDecl a)) -> SourceInfo a -> m (SourceInfo a)
applyModules ModDecl a -> GenT Identity (ModDecl a)
forall (m :: * -> *) a. MonadGen m => ModDecl a -> m (ModDecl a)
identModule

shuffleLinesIO :: (SourceInfo a) -> IO (SourceInfo a)
shuffleLinesIO :: forall a. SourceInfo a -> IO (SourceInfo a)
shuffleLinesIO = Gen (SourceInfo a) -> IO (SourceInfo a)
forall (m :: * -> *) a. MonadIO m => Gen a -> m a
Hog.sample (Gen (SourceInfo a) -> IO (SourceInfo a))
-> (SourceInfo a -> Gen (SourceInfo a))
-> SourceInfo a
-> IO (SourceInfo a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SourceInfo a -> Gen (SourceInfo a)
forall a. SourceInfo a -> Gen (SourceInfo a)
shuffleLines

renameVariablesIO :: (SourceInfo a) -> IO (SourceInfo a)
renameVariablesIO :: forall a. SourceInfo a -> IO (SourceInfo a)
renameVariablesIO = Gen (SourceInfo a) -> IO (SourceInfo a)
forall (m :: * -> *) a. MonadIO m => Gen a -> m a
Hog.sample (Gen (SourceInfo a) -> IO (SourceInfo a))
-> (SourceInfo a -> Gen (SourceInfo a))
-> SourceInfo a
-> IO (SourceInfo a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SourceInfo a -> Gen (SourceInfo a)
forall a. SourceInfo a -> Gen (SourceInfo a)
renameVariables

runShuffle :: Bool -> Bool -> SourceInfo a -> IO (SourceInfo a)
runShuffle :: forall a. Bool -> Bool -> SourceInfo a -> IO (SourceInfo a)
runShuffle Bool
nshuf Bool
nren SourceInfo a
sv = do
  SourceInfo a
sv' <- Bool
-> (SourceInfo a -> IO (SourceInfo a))
-> SourceInfo a
-> IO (SourceInfo a)
forall {m :: * -> *} {a}. Monad m => Bool -> (a -> m a) -> a -> m a
fopt Bool
nren SourceInfo a -> IO (SourceInfo a)
forall a. SourceInfo a -> IO (SourceInfo a)
renameVariablesIO SourceInfo a
sv
  Bool
-> (SourceInfo a -> IO (SourceInfo a))
-> SourceInfo a
-> IO (SourceInfo a)
forall {m :: * -> *} {a}. Monad m => Bool -> (a -> m a) -> a -> m a
fopt Bool
nshuf SourceInfo a -> IO (SourceInfo a)
forall a. SourceInfo a -> IO (SourceInfo a)
shuffleLinesIO SourceInfo a
sv'
  where
    fopt :: Bool -> (a -> m a) -> a -> m a
fopt Bool
o a -> m a
f = if Bool
o then a -> m a
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return else a -> m a
f

m' :: SourceInfo ()
m' :: SourceInfo ()
m' =
  Text -> Verilog () -> SourceInfo ()
forall a. Text -> Verilog a -> SourceInfo a
SourceInfo
    Text
"m"
    [verilog|
module fir_kernel_4tap_arch_1 #(
    parameter   BW = 32,
    parameter   SW = 5
) (X1, X2, X3, X5, X4, S, result);
    input  [BW-1:0] X1;
    input  [BW-1:0] X2;
    input  [BW-1:0] X3;
    input  [BW-1:0] X5;
    input  [BW-1:0] X4;
    input  [SW-1:0] S;
    output [BW-1:0] result;
    reg [SW:0] two_shift;
    wire [BW-1:0] first_sum;
    wire [BW-1:0] second_sum;

    always @* two_shift = S<<1;
    assign first_sum = X1 ? X1[2:0] : X1;
    assign second_sum = X4 + (X5 << S);
    assign result = ((first_sum >> two_shift) + second_sum) >> S;
endmodule
|]

renameExample, shuffleExample :: IO (GenVerilog (SourceInfo ()))
renameExample :: IO (GenVerilog (SourceInfo ()))
renameExample = SourceInfo () -> GenVerilog (SourceInfo ())
forall a. a -> GenVerilog a
GenVerilog (SourceInfo () -> GenVerilog (SourceInfo ()))
-> IO (SourceInfo ()) -> IO (GenVerilog (SourceInfo ()))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen (SourceInfo ()) -> IO (SourceInfo ())
forall (m :: * -> *) a. MonadIO m => Gen a -> m a
Hog.sample (SourceInfo () -> Gen (SourceInfo ())
forall a. SourceInfo a -> Gen (SourceInfo a)
renameVariables SourceInfo ()
m')
shuffleExample :: IO (GenVerilog (SourceInfo ()))
shuffleExample = SourceInfo () -> GenVerilog (SourceInfo ())
forall a. a -> GenVerilog a
GenVerilog (SourceInfo () -> GenVerilog (SourceInfo ()))
-> IO (SourceInfo ()) -> IO (GenVerilog (SourceInfo ()))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen (SourceInfo ()) -> IO (SourceInfo ())
forall (m :: * -> *) a. MonadIO m => Gen a -> m a
Hog.sample (SourceInfo () -> Gen (SourceInfo ())
forall a. SourceInfo a -> Gen (SourceInfo a)
shuffleLines SourceInfo ()
m')