{-# LANGUAGE DisambiguateRecordFields #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE NoFieldSelectors #-}
{-# LANGUAGE OverloadedRecordDot #-}
module Clash.Rewrite.StrategyDSL
(
Constructor (..)
, TransformationWorker (..)
, Transformation (..)
, toTransformation
, anyConstructor
, named
, onVar
, onData
, onLiteral
, onPrim
, onLam
, onTyLam
, onApp
, onTyApp
, onLet
, onCase
, onCast
, onTick
, onVarNode
, onPrimNode
, onAppNode
, onTyAppNode
, onLetNode
, onTickNode
, Step (..)
, chain
, one
, nested
, Strat (..)
, topdown
, bottomup
, topdownFix
, topdownSuc
, innerMost
, pass
, callStrategy
, repeatR
, Strategic (..)
, (>-!->)
, ToStep (..)
) where
import Language.Haskell.TH.Syntax (Name)
data Constructor
= CVar | CData | CLiteral | CPrim | CLam | CTyLam
| CApp | CTyApp | CLet | CCase | CCast | CTick
deriving (Constructor -> Constructor -> Bool
(Constructor -> Constructor -> Bool)
-> (Constructor -> Constructor -> Bool) -> Eq Constructor
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Constructor -> Constructor -> Bool
== :: Constructor -> Constructor -> Bool
$c/= :: Constructor -> Constructor -> Bool
/= :: Constructor -> Constructor -> Bool
Eq, Eq Constructor
Eq Constructor =>
(Constructor -> Constructor -> Ordering)
-> (Constructor -> Constructor -> Bool)
-> (Constructor -> Constructor -> Bool)
-> (Constructor -> Constructor -> Bool)
-> (Constructor -> Constructor -> Bool)
-> (Constructor -> Constructor -> Constructor)
-> (Constructor -> Constructor -> Constructor)
-> Ord Constructor
Constructor -> Constructor -> Bool
Constructor -> Constructor -> Ordering
Constructor -> Constructor -> Constructor
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Constructor -> Constructor -> Ordering
compare :: Constructor -> Constructor -> Ordering
$c< :: Constructor -> Constructor -> Bool
< :: Constructor -> Constructor -> Bool
$c<= :: Constructor -> Constructor -> Bool
<= :: Constructor -> Constructor -> Bool
$c> :: Constructor -> Constructor -> Bool
> :: Constructor -> Constructor -> Bool
$c>= :: Constructor -> Constructor -> Bool
>= :: Constructor -> Constructor -> Bool
$cmax :: Constructor -> Constructor -> Constructor
max :: Constructor -> Constructor -> Constructor
$cmin :: Constructor -> Constructor -> Constructor
min :: Constructor -> Constructor -> Constructor
Ord, Int -> Constructor -> ShowS
[Constructor] -> ShowS
Constructor -> String
(Int -> Constructor -> ShowS)
-> (Constructor -> String)
-> ([Constructor] -> ShowS)
-> Show Constructor
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Constructor -> ShowS
showsPrec :: Int -> Constructor -> ShowS
$cshow :: Constructor -> String
show :: Constructor -> String
$cshowList :: [Constructor] -> ShowS
showList :: [Constructor] -> ShowS
Show, Int -> Constructor
Constructor -> Int
Constructor -> [Constructor]
Constructor -> Constructor
Constructor -> Constructor -> [Constructor]
Constructor -> Constructor -> Constructor -> [Constructor]
(Constructor -> Constructor)
-> (Constructor -> Constructor)
-> (Int -> Constructor)
-> (Constructor -> Int)
-> (Constructor -> [Constructor])
-> (Constructor -> Constructor -> [Constructor])
-> (Constructor -> Constructor -> [Constructor])
-> (Constructor -> Constructor -> Constructor -> [Constructor])
-> Enum Constructor
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: Constructor -> Constructor
succ :: Constructor -> Constructor
$cpred :: Constructor -> Constructor
pred :: Constructor -> Constructor
$ctoEnum :: Int -> Constructor
toEnum :: Int -> Constructor
$cfromEnum :: Constructor -> Int
fromEnum :: Constructor -> Int
$cenumFrom :: Constructor -> [Constructor]
enumFrom :: Constructor -> [Constructor]
$cenumFromThen :: Constructor -> Constructor -> [Constructor]
enumFromThen :: Constructor -> Constructor -> [Constructor]
$cenumFromTo :: Constructor -> Constructor -> [Constructor]
enumFromTo :: Constructor -> Constructor -> [Constructor]
$cenumFromThenTo :: Constructor -> Constructor -> Constructor -> [Constructor]
enumFromThenTo :: Constructor -> Constructor -> Constructor -> [Constructor]
Enum, Constructor
Constructor -> Constructor -> Bounded Constructor
forall a. a -> a -> Bounded a
$cminBound :: Constructor
minBound :: Constructor
$cmaxBound :: Constructor
maxBound :: Constructor
Bounded)
data TransformationWorker
= FieldWorker !Constructor !Name
| Worker !Constructor !Name
| AnyWorker !Name
deriving (TransformationWorker -> TransformationWorker -> Bool
(TransformationWorker -> TransformationWorker -> Bool)
-> (TransformationWorker -> TransformationWorker -> Bool)
-> Eq TransformationWorker
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: TransformationWorker -> TransformationWorker -> Bool
== :: TransformationWorker -> TransformationWorker -> Bool
$c/= :: TransformationWorker -> TransformationWorker -> Bool
/= :: TransformationWorker -> TransformationWorker -> Bool
Eq, Int -> TransformationWorker -> ShowS
[TransformationWorker] -> ShowS
TransformationWorker -> String
(Int -> TransformationWorker -> ShowS)
-> (TransformationWorker -> String)
-> ([TransformationWorker] -> ShowS)
-> Show TransformationWorker
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TransformationWorker -> ShowS
showsPrec :: Int -> TransformationWorker -> ShowS
$cshow :: TransformationWorker -> String
show :: TransformationWorker -> String
$cshowList :: [TransformationWorker] -> ShowS
showList :: [TransformationWorker] -> ShowS
Show)
data Transformation = Transformation
{ Transformation -> String
name :: !String
, Transformation -> [TransformationWorker]
workers :: ![TransformationWorker]
} deriving (Transformation -> Transformation -> Bool
(Transformation -> Transformation -> Bool)
-> (Transformation -> Transformation -> Bool) -> Eq Transformation
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Transformation -> Transformation -> Bool
== :: Transformation -> Transformation -> Bool
$c/= :: Transformation -> Transformation -> Bool
/= :: Transformation -> Transformation -> Bool
Eq, Int -> Transformation -> ShowS
[Transformation] -> ShowS
Transformation -> String
(Int -> Transformation -> ShowS)
-> (Transformation -> String)
-> ([Transformation] -> ShowS)
-> Show Transformation
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Transformation -> ShowS
showsPrec :: Int -> Transformation -> ShowS
$cshow :: Transformation -> String
show :: Transformation -> String
$cshowList :: [Transformation] -> ShowS
showList :: [Transformation] -> ShowS
Show)
toTransformation :: String -> [TransformationWorker] -> Transformation
toTransformation :: String -> [TransformationWorker] -> Transformation
toTransformation = String -> [TransformationWorker] -> Transformation
Transformation
anyConstructor :: String -> Name -> Transformation
anyConstructor :: String -> Name -> Transformation
anyConstructor String
name Name
worker = String -> [TransformationWorker] -> Transformation
Transformation String
name [Name -> TransformationWorker
AnyWorker Name
worker]
named :: String -> Transformation -> Transformation
named :: String -> Transformation -> Transformation
named String
alias Transformation
transformation = Transformation
transformation { name = alias }
onVar, onData, onLiteral, onPrim, onLam, onTyLam, onApp, onTyApp, onLet,
onCase, onCast, onTick :: Name -> [TransformationWorker]
onVar :: Name -> [TransformationWorker]
onVar = TransformationWorker -> [TransformationWorker]
forall a. a -> [a]
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (TransformationWorker -> [TransformationWorker])
-> (Name -> TransformationWorker) -> Name -> [TransformationWorker]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Constructor -> Name -> TransformationWorker
FieldWorker Constructor
CVar
onData :: Name -> [TransformationWorker]
onData = TransformationWorker -> [TransformationWorker]
forall a. a -> [a]
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (TransformationWorker -> [TransformationWorker])
-> (Name -> TransformationWorker) -> Name -> [TransformationWorker]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Constructor -> Name -> TransformationWorker
FieldWorker Constructor
CData
onLiteral :: Name -> [TransformationWorker]
onLiteral = TransformationWorker -> [TransformationWorker]
forall a. a -> [a]
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (TransformationWorker -> [TransformationWorker])
-> (Name -> TransformationWorker) -> Name -> [TransformationWorker]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Constructor -> Name -> TransformationWorker
FieldWorker Constructor
CLiteral
onPrim :: Name -> [TransformationWorker]
onPrim = TransformationWorker -> [TransformationWorker]
forall a. a -> [a]
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (TransformationWorker -> [TransformationWorker])
-> (Name -> TransformationWorker) -> Name -> [TransformationWorker]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Constructor -> Name -> TransformationWorker
FieldWorker Constructor
CPrim
onLam :: Name -> [TransformationWorker]
onLam = TransformationWorker -> [TransformationWorker]
forall a. a -> [a]
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (TransformationWorker -> [TransformationWorker])
-> (Name -> TransformationWorker) -> Name -> [TransformationWorker]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Constructor -> Name -> TransformationWorker
FieldWorker Constructor
CLam
onTyLam :: Name -> [TransformationWorker]
onTyLam = TransformationWorker -> [TransformationWorker]
forall a. a -> [a]
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (TransformationWorker -> [TransformationWorker])
-> (Name -> TransformationWorker) -> Name -> [TransformationWorker]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Constructor -> Name -> TransformationWorker
FieldWorker Constructor
CTyLam
onApp :: Name -> [TransformationWorker]
onApp = TransformationWorker -> [TransformationWorker]
forall a. a -> [a]
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (TransformationWorker -> [TransformationWorker])
-> (Name -> TransformationWorker) -> Name -> [TransformationWorker]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Constructor -> Name -> TransformationWorker
FieldWorker Constructor
CApp
onTyApp :: Name -> [TransformationWorker]
onTyApp = TransformationWorker -> [TransformationWorker]
forall a. a -> [a]
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (TransformationWorker -> [TransformationWorker])
-> (Name -> TransformationWorker) -> Name -> [TransformationWorker]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Constructor -> Name -> TransformationWorker
FieldWorker Constructor
CTyApp
onLet :: Name -> [TransformationWorker]
onLet = TransformationWorker -> [TransformationWorker]
forall a. a -> [a]
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (TransformationWorker -> [TransformationWorker])
-> (Name -> TransformationWorker) -> Name -> [TransformationWorker]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Constructor -> Name -> TransformationWorker
FieldWorker Constructor
CLet
onCase :: Name -> [TransformationWorker]
onCase = TransformationWorker -> [TransformationWorker]
forall a. a -> [a]
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (TransformationWorker -> [TransformationWorker])
-> (Name -> TransformationWorker) -> Name -> [TransformationWorker]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Constructor -> Name -> TransformationWorker
FieldWorker Constructor
CCase
onCast :: Name -> [TransformationWorker]
onCast = TransformationWorker -> [TransformationWorker]
forall a. a -> [a]
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (TransformationWorker -> [TransformationWorker])
-> (Name -> TransformationWorker) -> Name -> [TransformationWorker]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Constructor -> Name -> TransformationWorker
FieldWorker Constructor
CCast
onTick :: Name -> [TransformationWorker]
onTick = TransformationWorker -> [TransformationWorker]
forall a. a -> [a]
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (TransformationWorker -> [TransformationWorker])
-> (Name -> TransformationWorker) -> Name -> [TransformationWorker]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Constructor -> Name -> TransformationWorker
FieldWorker Constructor
CTick
onVarNode, onPrimNode, onAppNode, onTyAppNode, onLetNode,
onTickNode :: Name -> [TransformationWorker]
onVarNode :: Name -> [TransformationWorker]
onVarNode = TransformationWorker -> [TransformationWorker]
forall a. a -> [a]
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (TransformationWorker -> [TransformationWorker])
-> (Name -> TransformationWorker) -> Name -> [TransformationWorker]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Constructor -> Name -> TransformationWorker
Worker Constructor
CVar
onPrimNode :: Name -> [TransformationWorker]
onPrimNode = TransformationWorker -> [TransformationWorker]
forall a. a -> [a]
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (TransformationWorker -> [TransformationWorker])
-> (Name -> TransformationWorker) -> Name -> [TransformationWorker]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Constructor -> Name -> TransformationWorker
Worker Constructor
CPrim
onAppNode :: Name -> [TransformationWorker]
onAppNode = TransformationWorker -> [TransformationWorker]
forall a. a -> [a]
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (TransformationWorker -> [TransformationWorker])
-> (Name -> TransformationWorker) -> Name -> [TransformationWorker]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Constructor -> Name -> TransformationWorker
Worker Constructor
CApp
onTyAppNode :: Name -> [TransformationWorker]
onTyAppNode = TransformationWorker -> [TransformationWorker]
forall a. a -> [a]
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (TransformationWorker -> [TransformationWorker])
-> (Name -> TransformationWorker) -> Name -> [TransformationWorker]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Constructor -> Name -> TransformationWorker
Worker Constructor
CTyApp
onLetNode :: Name -> [TransformationWorker]
onLetNode = TransformationWorker -> [TransformationWorker]
forall a. a -> [a]
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (TransformationWorker -> [TransformationWorker])
-> (Name -> TransformationWorker) -> Name -> [TransformationWorker]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Constructor -> Name -> TransformationWorker
Worker Constructor
CLet
onTickNode :: Name -> [TransformationWorker]
onTickNode = TransformationWorker -> [TransformationWorker]
forall a. a -> [a]
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (TransformationWorker -> [TransformationWorker])
-> (Name -> TransformationWorker) -> Name -> [TransformationWorker]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Constructor -> Name -> TransformationWorker
Worker Constructor
CTick
data Step
= Chain [Transformation]
| SeqS Step Step
| OnChangeS Step Step
| OnNoChangeS Step Step
| EmbedS Strat
deriving (Step -> Step -> Bool
(Step -> Step -> Bool) -> (Step -> Step -> Bool) -> Eq Step
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Step -> Step -> Bool
== :: Step -> Step -> Bool
$c/= :: Step -> Step -> Bool
/= :: Step -> Step -> Bool
Eq, Int -> Step -> ShowS
[Step] -> ShowS
Step -> String
(Int -> Step -> ShowS)
-> (Step -> String) -> ([Step] -> ShowS) -> Show Step
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Step -> ShowS
showsPrec :: Int -> Step -> ShowS
$cshow :: Step -> String
show :: Step -> String
$cshowList :: [Step] -> ShowS
showList :: [Step] -> ShowS
Show)
data Strat
= TopDown Step
| BottomUp Step
| TopDownFix Step
| TopDownSuc Step
| InnerMost Step
| Pass String Name
| CallStrategy Name
| Seq Strat Strat
| DeepSeqS Strat Strat
| OnChange Strat Strat
| OnNoChange Strat Strat
| Repeat Strat
deriving (Strat -> Strat -> Bool
(Strat -> Strat -> Bool) -> (Strat -> Strat -> Bool) -> Eq Strat
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Strat -> Strat -> Bool
== :: Strat -> Strat -> Bool
$c/= :: Strat -> Strat -> Bool
/= :: Strat -> Strat -> Bool
Eq, Int -> Strat -> ShowS
[Strat] -> ShowS
Strat -> String
(Int -> Strat -> ShowS)
-> (Strat -> String) -> ([Strat] -> ShowS) -> Show Strat
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Strat -> ShowS
showsPrec :: Int -> Strat -> ShowS
$cshow :: Strat -> String
show :: Strat -> String
$cshowList :: [Strat] -> ShowS
showList :: [Strat] -> ShowS
Show)
class ToStep s where
toStep :: s -> Step
instance ToStep Step where
toStep :: Step -> Step
toStep = Step -> Step
forall a. a -> a
id
instance ToStep Transformation where
toStep :: Transformation -> Step
toStep = Transformation -> Step
one
chain :: [Transformation] -> Step
chain :: [Transformation] -> Step
chain = [Transformation] -> Step
Chain
one :: Transformation -> Step
one :: Transformation -> Step
one = [Transformation] -> Step
Chain ([Transformation] -> Step)
-> (Transformation -> [Transformation]) -> Transformation -> Step
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Transformation -> [Transformation]
forall a. a -> [a]
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure
nested :: Strat -> Step
nested :: Strat -> Step
nested = Strat -> Step
EmbedS
topdown, bottomup, topdownFix, topdownSuc, innerMost :: ToStep s => s -> Strat
topdown :: forall s. ToStep s => s -> Strat
topdown = Step -> Strat
TopDown (Step -> Strat) -> (s -> Step) -> s -> Strat
forall b c a. (b -> c) -> (a -> b) -> a -> c
. s -> Step
forall s. ToStep s => s -> Step
toStep
bottomup :: forall s. ToStep s => s -> Strat
bottomup = Step -> Strat
BottomUp (Step -> Strat) -> (s -> Step) -> s -> Strat
forall b c a. (b -> c) -> (a -> b) -> a -> c
. s -> Step
forall s. ToStep s => s -> Step
toStep
topdownFix :: forall s. ToStep s => s -> Strat
topdownFix = Step -> Strat
TopDownFix (Step -> Strat) -> (s -> Step) -> s -> Strat
forall b c a. (b -> c) -> (a -> b) -> a -> c
. s -> Step
forall s. ToStep s => s -> Step
toStep
topdownSuc :: forall s. ToStep s => s -> Strat
topdownSuc = Step -> Strat
TopDownSuc (Step -> Strat) -> (s -> Step) -> s -> Strat
forall b c a. (b -> c) -> (a -> b) -> a -> c
. s -> Step
forall s. ToStep s => s -> Step
toStep
innerMost :: forall s. ToStep s => s -> Strat
innerMost = Step -> Strat
InnerMost (Step -> Strat) -> (s -> Step) -> s -> Strat
forall b c a. (b -> c) -> (a -> b) -> a -> c
. s -> Step
forall s. ToStep s => s -> Step
toStep
pass :: String -> Name -> Strat
pass :: String -> Name -> Strat
pass = String -> Name -> Strat
Pass
callStrategy :: Name -> Strat
callStrategy :: Name -> Strat
callStrategy = Name -> Strat
CallStrategy
repeatR :: Strat -> Strat
repeatR :: Strat -> Strat
repeatR = Strat -> Strat
Repeat
infixr 6 >->
infixr 5 !->
infixr 5 >-!
class Strategic a where
(>->) :: a -> a -> a
(!->) :: a -> a -> a
(>-!) :: a -> a -> a
instance Strategic Strat where
>-> :: Strat -> Strat -> Strat
(>->) = Strat -> Strat -> Strat
Seq
!-> :: Strat -> Strat -> Strat
(!->) = Strat -> Strat -> Strat
OnChange
>-! :: Strat -> Strat -> Strat
(>-!) = Strat -> Strat -> Strat
OnNoChange
instance Strategic Step where
>-> :: Step -> Step -> Step
(>->) = Step -> Step -> Step
SeqS
!-> :: Step -> Step -> Step
(!->) = Step -> Step -> Step
OnChangeS
>-! :: Step -> Step -> Step
(>-!) = Step -> Step -> Step
OnNoChangeS
infixr 6 >-!->
(>-!->) :: Strat -> Strat -> Strat
>-!-> :: Strat -> Strat -> Strat
(>-!->) = Strat -> Strat -> Strat
DeepSeqS