{-# OPTIONS_GHC -fno-warn-orphans #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
module Clash.Annotations.TH
(
makeTopEntity
, makeTopEntityWithName
, makeTopEntityWithName'
, buildTopEntity
, maybeBuildTopEntity
, getNameBinding
)
where
import Data.Foldable ( fold)
import qualified Data.Set as Set
import qualified Data.Map as Map
#if !(MIN_VERSION_base(4,11,0))
import Data.Semigroup as Semigroup
#endif
import Data.Maybe ( catMaybes )
import Language.Haskell.TH
import Data.Functor.Foldable ( para )
import Data.Functor.Foldable.TH
import Control.Lens ( (%~), (&), (.~)
, _1, _2, _3, view
)
import Control.Monad (mfilter, liftM2, forM, zipWithM)
import Control.Monad.Trans.Reader (ReaderT(..), asks, local)
import Control.Monad.Trans.Class (lift)
import Language.Haskell.TH.Instances ( )
import Language.Haskell.TH.Datatype
import Language.Haskell.TH.Syntax (qRecover)
import Data.Generics.Uniplate.Data (rewrite)
import Clash.Annotations.TopEntity ( PortName(..)
, TopEntity(..)
)
import Clash.NamedTypes ((:::))
import Clash.Signal ( HiddenClockResetEnable
, HiddenClock, HiddenReset, HiddenEnable
, Signal)
import Clash.Signal.Delayed (DSignal)
$(makeBaseFunctor ''Type)
data Naming a = Complete a | HasFail String | BackTrack (Set.Set Name)
deriving a -> Naming b -> Naming a
(a -> b) -> Naming a -> Naming b
(forall a b. (a -> b) -> Naming a -> Naming b)
-> (forall a b. a -> Naming b -> Naming a) -> Functor Naming
forall a b. a -> Naming b -> Naming a
forall a b. (a -> b) -> Naming a -> Naming b
forall (f :: Type -> Type).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> Naming b -> Naming a
$c<$ :: forall a b. a -> Naming b -> Naming a
fmap :: (a -> b) -> Naming a -> Naming b
$cfmap :: forall a b. (a -> b) -> Naming a -> Naming b
Functor
instance Semigroup a => Semigroup (Naming a) where
Complete a
a <> :: Naming a -> Naming a -> Naming a
<> Complete a
b = a -> Naming a
forall a. a -> Naming a
Complete (a -> Naming a) -> a -> Naming a
forall a b. (a -> b) -> a -> b
$ a
a a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
b
BackTrack Set Name
n1 <> BackTrack Set Name
n2 = Set Name -> Naming a
forall a. Set Name -> Naming a
BackTrack (Set Name -> Naming a) -> Set Name -> Naming a
forall a b. (a -> b) -> a -> b
$ Set Name
n1 Set Name -> Set Name -> Set Name
forall a. Semigroup a => a -> a -> a
<> Set Name
n2
BackTrack Set Name
n <> Naming a
_ = Set Name -> Naming a
forall a. Set Name -> Naming a
BackTrack Set Name
n
Naming a
_ <> BackTrack Set Name
n = Set Name -> Naming a
forall a. Set Name -> Naming a
BackTrack Set Name
n
HasFail String
e1 <> HasFail String
e2 = String -> Naming a
forall a. String -> Naming a
HasFail (String -> Naming a) -> String -> Naming a
forall a b. (a -> b) -> a -> b
$ String
e1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
e2
Naming a
_ <> HasFail String
e = String -> Naming a
forall a. String -> Naming a
HasFail String
e
HasFail String
e <> Naming a
_ = String -> Naming a
forall a. String -> Naming a
HasFail String
e
instance (Semigroup a, Monoid a) => Monoid (Naming a) where
mempty :: Naming a
mempty = a -> Naming a
forall a. a -> Naming a
Complete a
forall a. Monoid a => a
mempty
#if !(MIN_VERSION_base(4,11,0))
mappend = (Semigroup.<>)
#endif
type ErrorContext = String
type TrackData = (Set.Set Name, ErrorContext)
type Tracked m a = ReaderT TrackData m a
pattern ArrowTy :: Type -> Type -> Type
pattern $bArrowTy :: Type -> Type -> Type
$mArrowTy :: forall r. Type -> (Type -> Type -> r) -> (Void# -> r) -> r
ArrowTy a b = AppT (AppT ArrowT a) b
unapp :: Type -> [Type]
unapp :: Type -> [Type]
unapp (AppT Type
l Type
r) = Type -> [Type]
unapp Type
l [Type] -> [Type] -> [Type]
forall a. [a] -> [a] -> [a]
++ [Type
r]
unapp Type
t = [Type
t]
unarrow :: Type -> [Type]
unarrow :: Type -> [Type]
unarrow (ArrowTy Type
x Type
y) = Type
x Type -> [Type] -> [Type]
forall a. a -> [a] -> [a]
: Type -> [Type]
unarrow Type
y
unarrow Type
_ = []
collapseNames :: [PortName] -> [PortName]
collapseNames :: [PortName] -> [PortName]
collapseNames [] = []
collapseNames [PortName
x] = [PortName
x]
collapseNames [PortName]
xs = [String -> [PortName] -> PortName
PortProduct String
"" [PortName]
xs]
failMsg :: String -> String
failMsg :: String -> String
failMsg String
s = String
"TopEntity generation error: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
s
errorContext :: Tracked Q String
errorContext :: Tracked Q String
errorContext = ((Set Name, String) -> String) -> Tracked Q String
forall (m :: Type -> Type) r a.
Monad m =>
(r -> a) -> ReaderT r m a
asks (Set Name, String) -> String
forall a b. (a, b) -> b
snd
failMsgWithContext :: String -> Tracked Q String
failMsgWithContext :: String -> Tracked Q String
failMsgWithContext String
s = String -> String -> String
forall a. [a] -> [a] -> [a]
(++) (String -> String
failMsg String
s) (String -> String) -> Tracked Q String -> Tracked Q String
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Tracked Q String
errorContext
visit :: (Show b) => Name -> b -> Tracked m a -> Tracked m a
visit :: Name -> b -> Tracked m a -> Tracked m a
visit Name
name b
a = ((Set Name, String) -> (Set Name, String))
-> Tracked m a -> Tracked m a
forall r (m :: Type -> Type) a.
(r -> r) -> ReaderT r m a -> ReaderT r m a
local (\(Set Name, String)
t -> (Set Name, String)
t (Set Name, String)
-> ((Set Name, String) -> (Set Name, String)) -> (Set Name, String)
forall a b. a -> (a -> b) -> b
& (Set Name -> Identity (Set Name))
-> (Set Name, String) -> Identity (Set Name, String)
forall s t a b. Field1 s t a b => Lens s t a b
_1 ((Set Name -> Identity (Set Name))
-> (Set Name, String) -> Identity (Set Name, String))
-> (Set Name -> Set Name)
-> (Set Name, String)
-> (Set Name, String)
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ Name -> Set Name -> Set Name
forall a. Ord a => a -> Set a -> Set a
Set.insert Name
name
(Set Name, String)
-> ((Set Name, String) -> (Set Name, String)) -> (Set Name, String)
forall a b. a -> (a -> b) -> b
& (String -> Identity String)
-> (Set Name, String) -> Identity (Set Name, String)
forall s t a b. Field2 s t a b => Lens s t a b
_2 ((String -> Identity String)
-> (Set Name, String) -> Identity (Set Name, String))
-> String -> (Set Name, String) -> (Set Name, String)
forall s t a b. ASetter s t a b -> b -> s -> t
.~ b -> String
forall a. Show a => a -> String
show b
a)
datatypeVars' :: DatatypeInfo -> [Name]
#if MIN_VERSION_th_abstraction(0,3,0)
datatypeVars' :: DatatypeInfo -> [Name]
datatypeVars' DatatypeInfo
d = TyVarBndr_ Any -> Name
forall flag. TyVarBndr_ Any -> Name
tvName (TyVarBndr_ Any -> Name) -> [TyVarBndr_ Any] -> [Name]
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> DatatypeInfo -> [TyVarBndr_ Any]
datatypeVars DatatypeInfo
d
#else
datatypeVars' d = name <$> datatypeVars d
where
name (VarT n) = n
name (SigT n _) = name n
name e = error $ "Unexpected datatype variable name of type " ++ show e
#endif
tryReifyDatatype :: a -> (DatatypeInfo -> a) -> Name -> Tracked Q a
tryReifyDatatype :: a -> (DatatypeInfo -> a) -> Name -> Tracked Q a
tryReifyDatatype a
a DatatypeInfo -> a
f Name
name = Q a -> Tracked Q a
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Q a -> Q a -> Q a
forall a. Q a -> Q a -> Q a
recover (a -> Q a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure a
a) (Q a -> Q a) -> Q a -> Q a
forall a b. (a -> b) -> a -> b
$ DatatypeInfo -> a
f (DatatypeInfo -> a) -> Q DatatypeInfo -> Q a
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Name -> Q DatatypeInfo
reifyDatatype Name
name)
portsFromTypes
:: [Type]
-> Tracked Q (Naming [PortName])
portsFromTypes :: [Type] -> Tracked Q (Naming [PortName])
portsFromTypes [Type]
xs = do
([Naming [PortName]] -> Naming [PortName]
forall a. Monoid a => [a] -> a
mconcat ([Naming [PortName]] -> Naming [PortName])
-> ReaderT (Set Name, String) Q [Naming [PortName]]
-> Tracked Q (Naming [PortName])
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> (Type -> Tracked Q (Naming [PortName]))
-> [Type] -> ReaderT (Set Name, String) Q [Naming [PortName]]
forall (t :: Type -> Type) (m :: Type -> Type) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Type -> Tracked Q (Naming [PortName])
f [Type]
xs)
Tracked Q (Naming [PortName])
-> (Naming [PortName] -> Tracked Q (Naming [PortName]))
-> Tracked Q (Naming [PortName])
forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Complete [PortName]
names | [PortName] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length [PortName]
names Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 Bool -> Bool -> Bool
&& [PortName] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length [PortName]
names Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= [Type] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length [Type]
xs ->
String -> Naming [PortName]
forall a. String -> Naming a
HasFail (String -> Naming [PortName])
-> Tracked Q String -> Tracked Q (Naming [PortName])
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> Tracked Q String
failMsgWithContext String
"Partially named constructor arguments!\n"
Naming [PortName]
x -> Naming [PortName] -> Tracked Q (Naming [PortName])
forall (m :: Type -> Type) a. Monad m => a -> m a
return Naming [PortName]
x
where
f :: Type -> Tracked Q (Naming [PortName])
f = (Naming [PortName] -> Naming [PortName])
-> Tracked Q (Naming [PortName]) -> Tracked Q (Naming [PortName])
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap (([PortName] -> [PortName])
-> Naming [PortName] -> Naming [PortName]
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap [PortName] -> [PortName]
collapseNames) (Tracked Q (Naming [PortName]) -> Tracked Q (Naming [PortName]))
-> (Type -> Tracked Q (Naming [PortName]))
-> Type
-> Tracked Q (Naming [PortName])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Type -> Tracked Q (Naming [PortName])
gatherNames
handleNamesInSum
:: [ConstructorInfo]
-> Tracked Q (Naming [PortName])
handleNamesInSum :: [ConstructorInfo] -> Tracked Q (Naming [PortName])
handleNamesInSum [ConstructorInfo]
xs =
([Naming [PortName]] -> Naming [PortName]
forall (t :: Type -> Type) m. (Foldable t, Monoid m) => t m -> m
fold ([Naming [PortName]] -> Naming [PortName])
-> ReaderT (Set Name, String) Q [Naming [PortName]]
-> Tracked Q (Naming [PortName])
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> ([Type] -> Tracked Q (Naming [PortName]))
-> [[Type]] -> ReaderT (Set Name, String) Q [Naming [PortName]]
forall (t :: Type -> Type) (m :: Type -> Type) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM [Type] -> Tracked Q (Naming [PortName])
portsFromTypes (ConstructorInfo -> [Type]
constructorFields (ConstructorInfo -> [Type]) -> [ConstructorInfo] -> [[Type]]
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> [ConstructorInfo]
xs)) Tracked Q (Naming [PortName])
-> (Naming [PortName] -> Tracked Q (Naming [PortName]))
-> Tracked Q (Naming [PortName])
forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Complete [] -> Naming [PortName] -> Tracked Q (Naming [PortName])
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Naming [PortName] -> Tracked Q (Naming [PortName]))
-> Naming [PortName] -> Tracked Q (Naming [PortName])
forall a b. (a -> b) -> a -> b
$ [PortName] -> Naming [PortName]
forall a. a -> Naming a
Complete []
Naming [PortName]
x ->
Naming [PortName] -> Naming [PortName] -> Naming [PortName]
forall a. Monoid a => a -> a -> a
mappend Naming [PortName]
x (Naming [PortName] -> Naming [PortName])
-> (String -> Naming [PortName]) -> String -> Naming [PortName]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Naming [PortName]
forall a. String -> Naming a
HasFail (String -> Naming [PortName])
-> Tracked Q String -> Tracked Q (Naming [PortName])
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> Tracked Q String
failMsgWithContext String
"Annotated sum types not supported!\n"
constructorToPorts :: Con -> Map.Map Name Type -> Tracked Q (Naming [PortName])
constructorToPorts :: Con -> Map Name Type -> Tracked Q (Naming [PortName])
constructorToPorts Con
c Map Name Type
m = do
let xs :: [Type]
xs = Map Name Type -> [Type] -> [Type]
forall a. TypeSubstitution a => Map Name Type -> a -> a
applySubstitution Map Name Type
m (Con -> [Type]
ctys Con
c)
[Type] -> Tracked Q (Naming [PortName])
portsFromTypes [Type]
xs
where
ctys :: Con -> [Type]
ctys (NormalC Name
_ ((BangType -> Type) -> [BangType] -> [Type]
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap BangType -> Type
forall a b. (a, b) -> b
snd -> [Type]
tys)) = [Type]
tys
ctys (RecC Name
_ ((VarBangType -> Type) -> [VarBangType] -> [Type]
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap (Getting Type VarBangType Type -> VarBangType -> Type
forall s (m :: Type -> Type) a.
MonadReader s m =>
Getting a s a -> m a
view Getting Type VarBangType Type
forall s t a b. Field3 s t a b => Lens s t a b
_3) -> [Type]
tys)) = [Type]
tys
ctys (InfixC BangType
_ Name
_ (BangType -> Type
forall a b. (a, b) -> b
snd -> Type
ty)) = [Type
ty]
ctys (ForallC [TyVarBndr_ Any]
_ [Type]
_ Con
c') = Con -> [Type]
ctys Con
c'
ctys (GadtC [Name]
_ ((BangType -> Type) -> [BangType] -> [Type]
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap BangType -> Type
forall a b. (a, b) -> b
snd -> [Type]
tys) Type
_) = [Type]
tys
ctys (RecGadtC [Name]
_ ((VarBangType -> Type) -> [VarBangType] -> [Type]
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap (Getting Type VarBangType Type -> VarBangType -> Type
forall s (m :: Type -> Type) a.
MonadReader s m =>
Getting a s a -> m a
view Getting Type VarBangType Type
forall s t a b. Field3 s t a b => Lens s t a b
_3) -> [Type]
tys) Type
_) = [Type]
tys
datatypeNameToPorts
:: Name
-> Tracked Q (Naming [PortName])
datatypeNameToPorts :: Name -> Tracked Q (Naming [PortName])
datatypeNameToPorts Name
name = do
[ConstructorInfo]
constructors <- [ConstructorInfo]
-> (DatatypeInfo -> [ConstructorInfo])
-> Name
-> Tracked Q [ConstructorInfo]
forall a. a -> (DatatypeInfo -> a) -> Name -> Tracked Q a
tryReifyDatatype [] DatatypeInfo -> [ConstructorInfo]
datatypeCons Name
name
Naming [PortName]
names <- case [ConstructorInfo]
constructors of
[] -> Naming [PortName] -> Tracked Q (Naming [PortName])
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Naming [PortName] -> Tracked Q (Naming [PortName]))
-> Naming [PortName] -> Tracked Q (Naming [PortName])
forall a b. (a -> b) -> a -> b
$ [PortName] -> Naming [PortName]
forall a. a -> Naming a
Complete []
[ConstructorInfo
x] -> [Type] -> Tracked Q (Naming [PortName])
portsFromTypes (ConstructorInfo -> [Type]
constructorFields ConstructorInfo
x)
[ConstructorInfo]
xs -> [ConstructorInfo] -> Tracked Q (Naming [PortName])
handleNamesInSum [ConstructorInfo]
xs
case Naming [PortName]
names of
BackTrack Set Name
ns | Name -> Set Name -> Bool
forall a. Ord a => a -> Set a -> Bool
Set.member Name
name Set Name
ns -> do
Q () -> ReaderT (Set Name, String) Q ()
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Q () -> ReaderT (Set Name, String) Q ())
-> Q () -> ReaderT (Set Name, String) Q ()
forall a b. (a -> b) -> a -> b
$ String -> Q ()
reportWarning (String -> Q ()) -> String -> Q ()
forall a b. (a -> b) -> a -> b
$ String
"Make sure HDL port names are correct:\n"
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"Backtracked when constructing " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Name -> String
forall a. Ppr a => a -> String
pprint Name
name
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n(Type appears recursive)"
Naming [PortName] -> Tracked Q (Naming [PortName])
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Naming [PortName] -> Tracked Q (Naming [PortName]))
-> Naming [PortName] -> Tracked Q (Naming [PortName])
forall a b. (a -> b) -> a -> b
$ case (Name -> Set Name -> Set Name
forall a. Ord a => a -> Set a -> Set a
Set.delete Name
name Set Name
ns) of
Set Name
e | Set Name
e Set Name -> Set Name -> Bool
forall a. Eq a => a -> a -> Bool
== Set Name
forall a. Set a
Set.empty -> [PortName] -> Naming [PortName]
forall a. a -> Naming a
Complete []
Set Name
xs -> Set Name -> Naming [PortName]
forall a. Set Name -> Naming a
BackTrack Set Name
xs
Naming [PortName]
_ -> Naming [PortName] -> Tracked Q (Naming [PortName])
forall (m :: Type -> Type) a. Monad m => a -> m a
return Naming [PortName]
names
type family PortLabel where
guardPorts :: Type -> Type
guardPorts :: Type -> Type
guardPorts = (Type -> Maybe Type) -> Type -> Type
forall on. Uniplate on => (on -> Maybe on) -> on -> on
rewrite ((Type -> Maybe Type) -> Type -> Type)
-> (Type -> Maybe Type) -> Type -> Type
forall a b. (a -> b) -> a -> b
$ \case
AppT (ConT Name
split) name :: Type
name@(LitT (StrTyLit String
_)) | Name
split Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
== ''(:::) -> Type -> Maybe Type
forall a. a -> Maybe a
Just (Type -> Maybe Type) -> Type -> Maybe Type
forall a b. (a -> b) -> a -> b
$ Type -> Type -> Type
AppT (Name -> Type
ConT ''PortLabel) Type
name
Type
_ -> Maybe Type
forall a. Maybe a
Nothing
typeTreeToPorts
:: TypeF (Type, Tracked Q (Naming [PortName]))
-> Tracked Q (Naming [PortName])
typeTreeToPorts :: TypeF (Type, Tracked Q (Naming [PortName]))
-> Tracked Q (Naming [PortName])
typeTreeToPorts (AppTF (AppT (ConT Name
split) (LitT (StrTyLit String
name)), Tracked Q (Naming [PortName])
_) (Type
_,Tracked Q (Naming [PortName])
c))
| Name
split Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
== ''PortLabel
= Tracked Q (Naming [PortName])
c Tracked Q (Naming [PortName])
-> (Naming [PortName] -> Tracked Q (Naming [PortName]))
-> Tracked Q (Naming [PortName])
forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Complete [] -> Naming [PortName] -> Tracked Q (Naming [PortName])
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Naming [PortName] -> Tracked Q (Naming [PortName]))
-> Naming [PortName] -> Tracked Q (Naming [PortName])
forall a b. (a -> b) -> a -> b
$ [PortName] -> Naming [PortName]
forall a. a -> Naming a
Complete [String -> PortName
PortName String
name]
Complete [PortName String
n2] -> Naming [PortName] -> Tracked Q (Naming [PortName])
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Naming [PortName] -> Tracked Q (Naming [PortName]))
-> Naming [PortName] -> Tracked Q (Naming [PortName])
forall a b. (a -> b) -> a -> b
$ [PortName] -> Naming [PortName]
forall a. a -> Naming a
Complete [String -> PortName
PortName (String
name String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"_" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
n2)]
Complete [PortName]
xs -> Naming [PortName] -> Tracked Q (Naming [PortName])
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Naming [PortName] -> Tracked Q (Naming [PortName]))
-> Naming [PortName] -> Tracked Q (Naming [PortName])
forall a b. (a -> b) -> a -> b
$ [PortName] -> Naming [PortName]
forall a. a -> Naming a
Complete [String -> [PortName] -> PortName
PortProduct String
name [PortName]
xs]
Naming [PortName]
x -> Naming [PortName] -> Tracked Q (Naming [PortName])
forall (m :: Type -> Type) a. Monad m => a -> m a
return Naming [PortName]
x
typeTreeToPorts (ConTF Name
name) = do
Set Name
seen <- ((Set Name, String) -> Set Name)
-> ReaderT (Set Name, String) Q (Set Name)
forall (m :: Type -> Type) r a.
Monad m =>
(r -> a) -> ReaderT r m a
asks (Set Name, String) -> Set Name
forall a b. (a, b) -> a
fst
if Name -> Set Name -> Bool
forall a. Ord a => a -> Set a -> Bool
Set.member Name
name Set Name
seen
then Naming [PortName] -> Tracked Q (Naming [PortName])
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Naming [PortName] -> Tracked Q (Naming [PortName]))
-> Naming [PortName] -> Tracked Q (Naming [PortName])
forall a b. (a -> b) -> a -> b
$ Set Name -> Naming [PortName]
forall a. Set Name -> Naming a
BackTrack (Set Name -> Naming [PortName]) -> Set Name -> Naming [PortName]
forall a b. (a -> b) -> a -> b
$ Name -> Set Name
forall a. a -> Set a
Set.singleton Name
name
else Name
-> Name
-> Tracked Q (Naming [PortName])
-> Tracked Q (Naming [PortName])
forall b (m :: Type -> Type) a.
Show b =>
Name -> b -> Tracked m a -> Tracked m a
visit Name
name Name
name (Tracked Q (Naming [PortName]) -> Tracked Q (Naming [PortName]))
-> Tracked Q (Naming [PortName]) -> Tracked Q (Naming [PortName])
forall a b. (a -> b) -> a -> b
$ do
Info
info <- Q Info -> ReaderT (Set Name, String) Q Info
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Q Info -> ReaderT (Set Name, String) Q Info)
-> Q Info -> ReaderT (Set Name, String) Q Info
forall a b. (a -> b) -> a -> b
$ Name -> Q Info
reify Name
name
case Info
info of
PrimTyConI Name
_ Int
_ Bool
_ -> Naming [PortName] -> Tracked Q (Naming [PortName])
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Naming [PortName] -> Tracked Q (Naming [PortName]))
-> Naming [PortName] -> Tracked Q (Naming [PortName])
forall a b. (a -> b) -> a -> b
$ [PortName] -> Naming [PortName]
forall a. a -> Naming a
Complete []
TyConI (TySynD Name
_ [TyVarBndr_ Any]
_ Type
t) -> Type -> Tracked Q (Naming [PortName])
gatherNames Type
t
Info
_ -> Name -> Tracked Q (Naming [PortName])
datatypeNameToPorts Name
name
typeTreeToPorts f :: TypeF (Type, Tracked Q (Naming [PortName]))
f@(AppTF (Type
a,Tracked Q (Naming [PortName])
a') (Type
b,Tracked Q (Naming [PortName])
b')) = do
case Type -> [Type]
unapp (Type -> Type -> Type
AppT Type
a Type
b) of
(ConT Name
x : Type
_ : Type
_ : []) | Name
x Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
== ''Clash.Signal.Signal -> Tracked Q (Naming [PortName])
b'
(ConT Name
x : Type
_ : Type
_ : Type
_ : []) | Name
x Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
== ''Clash.Signal.Delayed.DSignal -> Tracked Q (Naming [PortName])
b'
(ConT Name
x : [Type]
xs) -> do
Info
info <- Q Info -> ReaderT (Set Name, String) Q Info
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Q Info -> ReaderT (Set Name, String) Q Info)
-> Q Info -> ReaderT (Set Name, String) Q Info
forall a b. (a -> b) -> a -> b
$ Name -> Q Info
reify Name
x
case Info
info of
(TyConI (TySynD Name
_ [TyVarBndr_ Any]
synvars Type
def)) -> do
Type -> Tracked Q (Naming [PortName])
gatherNames (Type -> Tracked Q (Naming [PortName]))
-> Type -> Tracked Q (Naming [PortName])
forall a b. (a -> b) -> a -> b
$ [Type] -> [Name] -> Type -> Type
forall a. TypeSubstitution a => [Type] -> [Name] -> a -> a
applyContext [Type]
xs (TyVarBndr_ Any -> Name
forall flag. TyVarBndr_ Any -> Name
tvName (TyVarBndr_ Any -> Name) -> [TyVarBndr_ Any] -> [Name]
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> [TyVarBndr_ Any]
synvars) Type
def
FamilyI (ClosedTypeFamilyD (TypeFamilyHead Name
_ [TyVarBndr_ Any]
bds FamilyResultSig
_ Maybe InjectivityAnn
_) [TySynEqn]
eqs) [Dec]
_
| [TyVarBndr_ Any] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length [TyVarBndr_ Any]
bds Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== [Type] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length [Type]
xs -> do
[Maybe Type]
matches <- Q [Maybe Type] -> ReaderT (Set Name, String) Q [Maybe Type]
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Q [Maybe Type] -> ReaderT (Set Name, String) Q [Maybe Type])
-> Q [Maybe Type] -> ReaderT (Set Name, String) Q [Maybe Type]
forall a b. (a -> b) -> a -> b
$ [TySynEqn] -> (TySynEqn -> Q (Maybe Type)) -> Q [Maybe Type]
forall (t :: Type -> Type) (m :: Type -> Type) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [TySynEqn]
eqs ((TySynEqn -> Q (Maybe Type)) -> Q [Maybe Type])
-> (TySynEqn -> Q (Maybe Type)) -> Q [Maybe Type]
forall a b. (a -> b) -> a -> b
$ \TySynEqn
eq -> Q (Maybe Type) -> Q (Maybe Type) -> Q (Maybe Type)
forall (m :: Type -> Type) a. Quasi m => m a -> m a -> m a
qRecover (Maybe Type -> Q (Maybe Type)
forall (m :: Type -> Type) a. Monad m => a -> m a
return Maybe Type
forall a. Maybe a
Nothing) (Q (Maybe Type) -> Q (Maybe Type))
-> (Q Type -> Q (Maybe Type)) -> Q Type -> Q (Maybe Type)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Type -> Maybe Type) -> Q Type -> Q (Maybe Type)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap Type -> Maybe Type
forall a. a -> Maybe a
Just (Q Type -> Q (Maybe Type)) -> Q Type -> Q (Maybe Type)
forall a b. (a -> b) -> a -> b
$ do
Map Name Type
sub <- [Map Name Type] -> Map Name Type
forall a. Monoid a => [a] -> a
mconcat ([Map Name Type] -> Map Name Type)
-> Q [Map Name Type] -> Q (Map Name Type)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> (Type -> Type -> Q (Map Name Type))
-> [Type] -> [Type] -> Q [Map Name Type]
forall (m :: Type -> Type) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m [c]
zipWithM (\Type
l Type
r -> [Type] -> Q (Map Name Type)
unifyTypes [Type
l, Type
r]) [Type]
xs (TySynEqn -> [Type]
tySynArgs TySynEqn
eq)
Type -> Q Type
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Type -> Q Type) -> Type -> Q Type
forall a b. (a -> b) -> a -> b
$ Map Name Type -> Type -> Type
forall a. TypeSubstitution a => Map Name Type -> a -> a
applySubstitution Map Name Type
sub (Type -> Type) -> Type -> Type
forall a b. (a -> b) -> a -> b
$ TySynEqn -> Type
tySynRHS TySynEqn
eq
case [Maybe Type] -> [Type]
forall a. [Maybe a] -> [a]
catMaybes [Maybe Type]
matches of
(Type
r:[Type]
_) -> Type -> Tracked Q (Naming [PortName])
gatherNames Type
r
[] -> Naming [PortName] -> Tracked Q (Naming [PortName])
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Naming [PortName] -> Tracked Q (Naming [PortName]))
-> Naming [PortName] -> Tracked Q (Naming [PortName])
forall a b. (a -> b) -> a -> b
$ [PortName] -> Naming [PortName]
forall a. a -> Naming a
Complete []
Info
_ | Info -> Maybe Int
familyArity Info
info Maybe Int -> Maybe Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int -> Maybe Int
forall a. a -> Maybe a
Just ([Type] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length [Type]
xs) -> do
(Q [Dec] -> ReaderT (Set Name, String) Q [Dec]
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Q [Dec] -> ReaderT (Set Name, String) Q [Dec])
-> Q [Dec] -> ReaderT (Set Name, String) Q [Dec]
forall a b. (a -> b) -> a -> b
$ Name -> [Type] -> Q [Dec]
reifyInstances Name
x [Type]
xs) ReaderT (Set Name, String) Q [Dec]
-> ([Dec] -> Tracked Q (Naming [PortName]))
-> Tracked Q (Naming [PortName])
forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
#if MIN_VERSION_template_haskell(2,15,0)
[TySynInstD (TySynEqn Maybe [TyVarBndr_ Any]
_ Type
_ Type
r)] ->
#else
[TySynInstD _ (TySynEqn _ r)] ->
#endif
Type -> Tracked Q (Naming [PortName])
gatherNames ([Type] -> Info -> Type -> Type
forall p. TypeSubstitution p => [Type] -> Info -> p -> p
applyFamilyBindings [Type]
xs Info
info Type
r)
[NewtypeInstD [Type]
_ Maybe [TyVarBndr_ Any]
_ Type
_ Maybe Type
_ Con
c [DerivClause]
_] -> Con -> Map Name Type -> Tracked Q (Naming [PortName])
constructorToPorts Con
c ([Type] -> Info -> Map Name Type
forall a. [a] -> Info -> Map Name a
familyTyMap [Type]
xs Info
info)
[DataInstD [Type]
_ Maybe [TyVarBndr_ Any]
_ Type
_ Maybe Type
_ [Con]
cs [DerivClause]
_] -> do
case [Con]
cs of
[Con
c] -> Con -> Map Name Type -> Tracked Q (Naming [PortName])
constructorToPorts Con
c ([Type] -> Info -> Map Name Type
forall a. [a] -> Info -> Map Name a
familyTyMap [Type]
xs Info
info)
[Con]
_ -> Naming [PortName] -> Tracked Q (Naming [PortName])
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Naming [PortName] -> Tracked Q (Naming [PortName]))
-> Naming [PortName] -> Tracked Q (Naming [PortName])
forall a b. (a -> b) -> a -> b
$ [PortName] -> Naming [PortName]
forall a. a -> Naming a
Complete []
[Dec]
y -> String -> Tracked Q (Naming [PortName])
forall (m :: Type -> Type) a. MonadFail m => String -> m a
fail (String -> Tracked Q (Naming [PortName]))
-> String -> Tracked Q (Naming [PortName])
forall a b. (a -> b) -> a -> b
$ String -> String
failMsg String
"Encountered unexpected type during family application!"
String -> String -> String
forall a. [a] -> [a] -> [a]
++ [Dec] -> String
forall a. Ppr a => a -> String
pprint [Dec]
y
Info
_ -> do
Maybe DatatypeInfo
dataTy <- Maybe DatatypeInfo
-> (DatatypeInfo -> Maybe DatatypeInfo)
-> Name
-> Tracked Q (Maybe DatatypeInfo)
forall a. a -> (DatatypeInfo -> a) -> Name -> Tracked Q a
tryReifyDatatype Maybe DatatypeInfo
forall a. Maybe a
Nothing DatatypeInfo -> Maybe DatatypeInfo
forall a. a -> Maybe a
Just Name
x
let
hasAllArgs :: DatatypeInfo -> Bool
hasAllArgs = \DatatypeInfo
vs -> [Type] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length [Type]
xs Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== [TyVarBndr_ Any] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length (DatatypeInfo -> [TyVarBndr_ Any]
datatypeVars DatatypeInfo
vs)
constructors :: Maybe [ConstructorInfo]
constructors = [Type] -> DatatypeInfo -> [ConstructorInfo]
applyDatatypeContext [Type]
xs (DatatypeInfo -> [ConstructorInfo])
-> Maybe DatatypeInfo -> Maybe [ConstructorInfo]
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> (DatatypeInfo -> Bool) -> Maybe DatatypeInfo -> Maybe DatatypeInfo
forall (m :: Type -> Type) a.
MonadPlus m =>
(a -> Bool) -> m a -> m a
mfilter DatatypeInfo -> Bool
hasAllArgs Maybe DatatypeInfo
dataTy
getSingleConstructor :: m [b] -> m b
getSingleConstructor m [b]
cs = do [b
c] <- m [b]
cs; b -> m b
forall (m :: Type -> Type) a. Monad m => a -> m a
return b
c
constructor :: Maybe ConstructorInfo
constructor = Maybe [ConstructorInfo] -> Maybe ConstructorInfo
forall (m :: Type -> Type) b. MonadFail m => m [b] -> m b
getSingleConstructor Maybe [ConstructorInfo]
constructors
Tracked Q (Naming [PortName])
-> (ConstructorInfo -> Tracked Q (Naming [PortName]))
-> Maybe ConstructorInfo
-> Tracked Q (Naming [PortName])
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Tracked Q (Naming [PortName])
a' (Name
-> Doc
-> Tracked Q (Naming [PortName])
-> Tracked Q (Naming [PortName])
forall b (m :: Type -> Type) a.
Show b =>
Name -> b -> Tracked m a -> Tracked m a
visit Name
x (Name -> Doc
forall a. Ppr a => a -> Doc
ppr Name
x) (Tracked Q (Naming [PortName]) -> Tracked Q (Naming [PortName]))
-> (ConstructorInfo -> Tracked Q (Naming [PortName]))
-> ConstructorInfo
-> Tracked Q (Naming [PortName])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Type] -> Tracked Q (Naming [PortName])
portsFromTypes ([Type] -> Tracked Q (Naming [PortName]))
-> (ConstructorInfo -> [Type])
-> ConstructorInfo
-> Tracked Q (Naming [PortName])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ConstructorInfo -> [Type]
constructorFields) Maybe ConstructorInfo
constructor
(Type
ListT:[Type]
_) -> TypeF (Naming [PortName]) -> Naming [PortName]
forall (t :: Type -> Type) m. (Foldable t, Monoid m) => t m -> m
fold (TypeF (Naming [PortName]) -> Naming [PortName])
-> ReaderT (Set Name, String) Q (TypeF (Naming [PortName]))
-> Tracked Q (Naming [PortName])
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> ((Type, Tracked Q (Naming [PortName]))
-> Tracked Q (Naming [PortName]))
-> TypeF (Type, Tracked Q (Naming [PortName]))
-> ReaderT (Set Name, String) Q (TypeF (Naming [PortName]))
forall (t :: Type -> Type) (m :: Type -> Type) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Type, Tracked Q (Naming [PortName]))
-> Tracked Q (Naming [PortName])
forall a b. (a, b) -> b
snd TypeF (Type, Tracked Q (Naming [PortName]))
f
(TupleT Int
_:[Type]
_) -> TypeF (Naming [PortName]) -> Naming [PortName]
forall (t :: Type -> Type) m. (Foldable t, Monoid m) => t m -> m
fold (TypeF (Naming [PortName]) -> Naming [PortName])
-> ReaderT (Set Name, String) Q (TypeF (Naming [PortName]))
-> Tracked Q (Naming [PortName])
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> ((Type, Tracked Q (Naming [PortName]))
-> Tracked Q (Naming [PortName]))
-> TypeF (Type, Tracked Q (Naming [PortName]))
-> ReaderT (Set Name, String) Q (TypeF (Naming [PortName]))
forall (t :: Type -> Type) (m :: Type -> Type) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Type, Tracked Q (Naming [PortName]))
-> Tracked Q (Naming [PortName])
forall a b. (a, b) -> b
snd TypeF (Type, Tracked Q (Naming [PortName]))
f
[Type]
_ -> do
Q () -> ReaderT (Set Name, String) Q ()
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Q () -> ReaderT (Set Name, String) Q ())
-> Q () -> ReaderT (Set Name, String) Q ()
forall a b. (a -> b) -> a -> b
$ String -> Q ()
reportWarning (String -> Q ()) -> String -> Q ()
forall a b. (a -> b) -> a -> b
$ String
"Make sure HDL port names are correct:\n"
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"Type application with non ConT head:\n:("
String -> String -> String
forall a. [a] -> [a] -> [a]
++ Type -> String
forall a. Ppr a => a -> String
pprint (Type -> Type -> Type
AppT Type
a Type
b)
TypeF (Naming [PortName])
f' <- ((Type, Tracked Q (Naming [PortName]))
-> Tracked Q (Naming [PortName]))
-> TypeF (Type, Tracked Q (Naming [PortName]))
-> ReaderT (Set Name, String) Q (TypeF (Naming [PortName]))
forall (t :: Type -> Type) (m :: Type -> Type) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Type, Tracked Q (Naming [PortName]))
-> Tracked Q (Naming [PortName])
forall a b. (a, b) -> b
snd TypeF (Type, Tracked Q (Naming [PortName]))
f
Naming [PortName] -> Tracked Q (Naming [PortName])
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Naming [PortName] -> Tracked Q (Naming [PortName]))
-> Naming [PortName] -> Tracked Q (Naming [PortName])
forall a b. (a -> b) -> a -> b
$ TypeF (Naming [PortName]) -> Naming [PortName]
forall (t :: Type -> Type) m. (Foldable t, Monoid m) => t m -> m
fold TypeF (Naming [PortName])
f'
where
tyMap :: [a] -> [k] -> Map k a
tyMap [a]
ctx [k]
holes = [(k, a)] -> Map k a
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList ([(k, a)] -> Map k a) -> [(k, a)] -> Map k a
forall a b. (a -> b) -> a -> b
$ [k] -> [a] -> [(k, a)]
forall a b. [a] -> [b] -> [(a, b)]
zip [k]
holes [a]
ctx
familyTyMap :: [a] -> Info -> Map Name a
familyTyMap [a]
ctx (Info -> Maybe [TyVarBndr_ Any]
familyBindings -> Just [TyVarBndr_ Any]
holes) = [a] -> [Name] -> Map Name a
forall k a. Ord k => [a] -> [k] -> Map k a
tyMap [a]
ctx (TyVarBndr_ Any -> Name
forall flag. TyVarBndr_ Any -> Name
tvName (TyVarBndr_ Any -> Name) -> [TyVarBndr_ Any] -> [Name]
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> [TyVarBndr_ Any]
holes)
familyTyMap [a]
_ Info
_ = String -> Map Name a
forall a. HasCallStack => String -> a
error String
"familyTyMap called with non family argument!"
applyContext :: [Type] -> [Name] -> a -> a
applyContext [Type]
ctx [Name]
holes = Map Name Type -> a -> a
forall a. TypeSubstitution a => Map Name Type -> a -> a
applySubstitution ([Type] -> [Name] -> Map Name Type
forall k a. Ord k => [a] -> [k] -> Map k a
tyMap [Type]
ctx [Name]
holes)
applyDatatypeContext :: [Type] -> DatatypeInfo -> [ConstructorInfo]
applyDatatypeContext [Type]
ctx DatatypeInfo
d = [Type] -> [Name] -> ConstructorInfo -> ConstructorInfo
forall a. TypeSubstitution a => [Type] -> [Name] -> a -> a
applyContext [Type]
ctx (DatatypeInfo -> [Name]
datatypeVars' DatatypeInfo
d) (ConstructorInfo -> ConstructorInfo)
-> [ConstructorInfo] -> [ConstructorInfo]
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> DatatypeInfo -> [ConstructorInfo]
datatypeCons DatatypeInfo
d
applyFamilyBindings :: [Type] -> Info -> p -> p
applyFamilyBindings [Type]
ctx (Info -> Maybe [TyVarBndr_ Any]
familyBindings -> Just [TyVarBndr_ Any]
holes) p
t
= [Type] -> [Name] -> p -> p
forall a. TypeSubstitution a => [Type] -> [Name] -> a -> a
applyContext [Type]
ctx (TyVarBndr_ Any -> Name
forall flag. TyVarBndr_ Any -> Name
tvName (TyVarBndr_ Any -> Name) -> [TyVarBndr_ Any] -> [Name]
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> [TyVarBndr_ Any]
holes) p
t
applyFamilyBindings [Type]
_ Info
_ p
_ = String -> p
forall a. HasCallStack => String -> a
error String
"familyTyMap called with non family argument!"
#if MIN_VERSION_template_haskell(2,15,0)
tySynArgs :: TySynEqn -> [Type]
tySynArgs (TySynEqn Maybe [TyVarBndr_ Any]
_ Type
args Type
_) = [Type] -> [Type]
forall a. [a] -> [a]
tail (Type -> [Type]
unapp Type
args)
#else
tySynArgs (TySynEqn args _) = args
#endif
#if MIN_VERSION_template_haskell(2,15,0)
tySynRHS :: TySynEqn -> Type
tySynRHS (TySynEqn Maybe [TyVarBndr_ Any]
_ Type
_ Type
r) = Type
r
#else
tySynRHS (TySynEqn _ r) = r
#endif
familyBindings :: Info -> Maybe [TyVarBndr_ Any]
familyBindings (FamilyI (ClosedTypeFamilyD (TypeFamilyHead Name
_ [TyVarBndr_ Any]
xs FamilyResultSig
_ Maybe InjectivityAnn
_) [TySynEqn]
_) [Dec]
_) = [TyVarBndr_ Any] -> Maybe [TyVarBndr_ Any]
forall a. a -> Maybe a
Just [TyVarBndr_ Any]
xs
familyBindings (FamilyI (OpenTypeFamilyD (TypeFamilyHead Name
_ [TyVarBndr_ Any]
xs FamilyResultSig
_ Maybe InjectivityAnn
_)) [Dec]
_) = [TyVarBndr_ Any] -> Maybe [TyVarBndr_ Any]
forall a. a -> Maybe a
Just [TyVarBndr_ Any]
xs
familyBindings (FamilyI (DataFamilyD Name
_ [TyVarBndr_ Any]
xs Maybe Type
_) [Dec]
_) = [TyVarBndr_ Any] -> Maybe [TyVarBndr_ Any]
forall a. a -> Maybe a
Just [TyVarBndr_ Any]
xs
familyBindings Info
_ = Maybe [TyVarBndr_ Any]
forall a. Maybe a
Nothing
familyArity :: Info -> Maybe Int
familyArity = ([TyVarBndr_ Any] -> Int) -> Maybe [TyVarBndr_ Any] -> Maybe Int
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap [TyVarBndr_ Any] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length (Maybe [TyVarBndr_ Any] -> Maybe Int)
-> (Info -> Maybe [TyVarBndr_ Any]) -> Info -> Maybe Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Info -> Maybe [TyVarBndr_ Any]
familyBindings
typeTreeToPorts TypeF (Type, Tracked Q (Naming [PortName]))
f = do
TypeF (Naming [PortName])
f' <- ((Type, Tracked Q (Naming [PortName]))
-> Tracked Q (Naming [PortName]))
-> TypeF (Type, Tracked Q (Naming [PortName]))
-> ReaderT (Set Name, String) Q (TypeF (Naming [PortName]))
forall (t :: Type -> Type) (m :: Type -> Type) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Type, Tracked Q (Naming [PortName]))
-> Tracked Q (Naming [PortName])
forall a b. (a, b) -> b
snd TypeF (Type, Tracked Q (Naming [PortName]))
f
Naming [PortName] -> Tracked Q (Naming [PortName])
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Naming [PortName] -> Tracked Q (Naming [PortName]))
-> Naming [PortName] -> Tracked Q (Naming [PortName])
forall a b. (a -> b) -> a -> b
$ TypeF (Naming [PortName]) -> Naming [PortName]
forall (t :: Type -> Type) m. (Foldable t, Monoid m) => t m -> m
fold TypeF (Naming [PortName])
f'
gatherNames
:: Type
-> Tracked Q (Naming [PortName])
gatherNames :: Type -> Tracked Q (Naming [PortName])
gatherNames =
(Base Type (Type, Tracked Q (Naming [PortName]))
-> Tracked Q (Naming [PortName]))
-> Type -> Tracked Q (Naming [PortName])
forall t a. Recursive t => (Base t (t, a) -> a) -> t -> a
para Base Type (Type, Tracked Q (Naming [PortName]))
-> Tracked Q (Naming [PortName])
TypeF (Type, Tracked Q (Naming [PortName]))
-> Tracked Q (Naming [PortName])
typeTreeToPorts (Type -> Tracked Q (Naming [PortName]))
-> (Type -> Type) -> Type -> Tracked Q (Naming [PortName])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Type -> Type
guardPorts
buildPorts
:: Type
-> Q [PortName]
buildPorts :: Type -> Q [PortName]
buildPorts Type
x = do
(ReaderT (Set Name, String) Q [PortName]
-> (Set Name, String) -> Q [PortName])
-> (Set Name, String)
-> ReaderT (Set Name, String) Q [PortName]
-> Q [PortName]
forall a b c. (a -> b -> c) -> b -> a -> c
flip ReaderT (Set Name, String) Q [PortName]
-> (Set Name, String) -> Q [PortName]
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT (Set Name
forall a. Set a
Set.empty, String
"") (ReaderT (Set Name, String) Q [PortName] -> Q [PortName])
-> ReaderT (Set Name, String) Q [PortName] -> Q [PortName]
forall a b. (a -> b) -> a -> b
$ Type -> Tracked Q (Naming [PortName])
gatherNames Type
x
Tracked Q (Naming [PortName])
-> (Naming [PortName] -> ReaderT (Set Name, String) Q [PortName])
-> ReaderT (Set Name, String) Q [PortName]
forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Complete [PortName]
xs -> [PortName] -> ReaderT (Set Name, String) Q [PortName]
forall (m :: Type -> Type) a. Monad m => a -> m a
return [PortName]
xs
HasFail String
err -> String -> ReaderT (Set Name, String) Q [PortName]
forall (m :: Type -> Type) a. MonadFail m => String -> m a
fail String
err
BackTrack Set Name
n -> String -> ReaderT (Set Name, String) Q [PortName]
forall (m :: Type -> Type) a. MonadFail m => String -> m a
fail (String -> ReaderT (Set Name, String) Q [PortName])
-> String -> ReaderT (Set Name, String) Q [PortName]
forall a b. (a -> b) -> a -> b
$ String -> String
failMsg String
"Encountered recursive type at entry! " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Set Name -> String
forall a. Show a => a -> String
show Set Name
n
toReturnName :: Type -> Q PortName
toReturnName :: Type -> Q PortName
toReturnName (ArrowTy Type
_ Type
b) = Type -> Q PortName
toReturnName Type
b
toReturnName Type
b =
Type -> Q [PortName]
buildPorts Type
b
Q [PortName] -> ([PortName] -> Q PortName) -> Q PortName
forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
[] -> String -> Q PortName
forall (m :: Type -> Type) a. MonadFail m => String -> m a
fail (String -> Q PortName) -> String -> Q PortName
forall a b. (a -> b) -> a -> b
$ String -> String
failMsg String
"No return name specified!"
[PortName
x] -> PortName -> Q PortName
forall (m :: Type -> Type) a. Monad m => a -> m a
return PortName
x
[PortName]
xs -> PortName -> Q PortName
forall (m :: Type -> Type) a. Monad m => a -> m a
return (PortName -> Q PortName) -> PortName -> Q PortName
forall a b. (a -> b) -> a -> b
$ String -> [PortName] -> PortName
PortProduct String
"" [PortName]
xs
toArgNames :: Type -> Q [PortName]
toArgNames :: Type -> Q [PortName]
toArgNames Type
ty = (Type -> Q PortName) -> [Type] -> Q [PortName]
forall (t :: Type -> Type) (f :: Type -> Type) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse Type -> Q PortName
build (Type -> [Type]
unarrow Type
ty)
where
build :: Type -> Q PortName
build Type
x = Type -> Q [PortName]
buildPorts Type
x Q [PortName] -> ([PortName] -> Q PortName) -> Q PortName
forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= Type -> [PortName] -> Q PortName
forall (m :: Type -> Type) a.
(MonadFail m, Ppr a) =>
a -> [PortName] -> m PortName
check Type
x
check :: a -> [PortName] -> m PortName
check a
x [] = String -> m PortName
forall (m :: Type -> Type) a. MonadFail m => String -> m a
fail (String -> m PortName) -> String -> m PortName
forall a b. (a -> b) -> a -> b
$ String -> String
failMsg String
"Unnamed argument " String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Ppr a => a -> String
pprint a
x
check a
_ [PortName
a] = PortName -> m PortName
forall (m :: Type -> Type) a. Monad m => a -> m a
return PortName
a
check a
_ [PortName]
xs = PortName -> m PortName
forall (m :: Type -> Type) a. Monad m => a -> m a
return (PortName -> m PortName) -> PortName -> m PortName
forall a b. (a -> b) -> a -> b
$ String -> [PortName] -> PortName
PortProduct String
"" [PortName]
xs
data ClockType = None | SingleClockResetEnable | Other
deriving ClockType -> ClockType -> Bool
(ClockType -> ClockType -> Bool)
-> (ClockType -> ClockType -> Bool) -> Eq ClockType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ClockType -> ClockType -> Bool
$c/= :: ClockType -> ClockType -> Bool
== :: ClockType -> ClockType -> Bool
$c== :: ClockType -> ClockType -> Bool
Eq
handleConstraints :: Type -> ClockType -> Q (Type, ClockType)
handleConstraints :: Type -> ClockType -> Q (Type, ClockType)
handleConstraints (ForallT [] [] Type
x) ClockType
clk = Type -> ClockType -> Q (Type, ClockType)
handleConstraints Type
x ClockType
clk
handleConstraints (ForallT xs :: [TyVarBndr_ Any]
xs@(TyVarBndr_ Any
_:[TyVarBndr_ Any]
_) [Type]
_ Type
_) ClockType
_ =
String -> Q (Type, ClockType)
forall (m :: Type -> Type) a. MonadFail m => String -> m a
fail (String -> Q (Type, ClockType)) -> String -> Q (Type, ClockType)
forall a b. (a -> b) -> a -> b
$ String -> String
failMsg String
"Free type variables!\n"
String -> String -> String
forall a. [a] -> [a] -> [a]
++ [TyVarBndr_ Any] -> String
forall a. Ppr a => a -> String
pprint [TyVarBndr_ Any]
xs
handleConstraints (ForallT [TyVarBndr_ Any]
_ [Type]
c Type
x) ClockType
clk = Type -> ClockType -> Q (Type, ClockType)
handleConstraints Type
x ClockType
hiddenClocks
where
hiddenClocks :: ClockType
hiddenClocks = (ClockType -> Type -> ClockType)
-> ClockType -> [Type] -> ClockType
forall (t :: Type -> Type) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl ClockType -> Type -> ClockType
findHiddenClocks ClockType
clk [Type]
c
findHiddenClocks :: ClockType -> Type -> ClockType
findHiddenClocks ClockType
a (AppT (ConT Name
b) Type
_)
| Name
b Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
== ''Clash.Signal.HiddenClockResetEnable Bool -> Bool -> Bool
&& ClockType
a ClockType -> ClockType -> Bool
forall a. Eq a => a -> a -> Bool
== ClockType
None
= ClockType
SingleClockResetEnable
| Name
b Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
== ''Clash.Signal.HiddenClockResetEnable Bool -> Bool -> Bool
&& ClockType
a ClockType -> ClockType -> Bool
forall a. Eq a => a -> a -> Bool
/= ClockType
None
= ClockType
Other
| Name
b Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
== ''Clash.Signal.HiddenClock
Bool -> Bool -> Bool
|| Name
b Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
== ''Clash.Signal.HiddenReset
Bool -> Bool -> Bool
|| Name
b Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
== ''Clash.Signal.HiddenEnable
= ClockType
Other
findHiddenClocks ClockType
a Type
_ = ClockType
a
handleConstraints Type
x ClockType
clk = (Type, ClockType) -> Q (Type, ClockType)
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Type
x, ClockType
clk)
clockToPorts :: ClockType -> Q [PortName]
clockToPorts :: ClockType -> Q [PortName]
clockToPorts ClockType
None = [PortName] -> Q [PortName]
forall (m :: Type -> Type) a. Monad m => a -> m a
return []
clockToPorts (ClockType
SingleClockResetEnable) =
[PortName] -> Q [PortName]
forall (m :: Type -> Type) a. Monad m => a -> m a
return [String -> [PortName] -> PortName
PortProduct String
"" [ String -> PortName
PortName String
"clk" , String -> PortName
PortName String
"rst" , String -> PortName
PortName String
"en" ]]
clockToPorts ClockType
Other =
String -> Q [PortName]
forall (m :: Type -> Type) a. MonadFail m => String -> m a
fail (String -> Q [PortName]) -> String -> Q [PortName]
forall a b. (a -> b) -> a -> b
$ String -> String
failMsg String
"TH generation for multiple hidden clocks and"
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" HiddenClock/HiddenReset/HiddenEnable currently unsupported!"
buildTopEntity :: Maybe String -> (Name, Type) -> TExpQ TopEntity
buildTopEntity :: Maybe String -> (Name, Type) -> TExpQ TopEntity
buildTopEntity Maybe String
topName (Name
name, Type
ty) = do
(Type
ty', ClockType
clock) <- Type -> ClockType -> Q (Type, ClockType)
handleConstraints Type
ty ClockType
None
[PortName]
ins <- ([PortName] -> [PortName] -> [PortName])
-> Q [PortName] -> Q [PortName] -> Q [PortName]
forall (m :: Type -> Type) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 [PortName] -> [PortName] -> [PortName]
forall a. Semigroup a => a -> a -> a
(<>) (ClockType -> Q [PortName]
clockToPorts ClockType
clock) (Type -> Q [PortName]
toArgNames Type
ty')
PortName
out <- Type -> Q PortName
toReturnName Type
ty'
let outName :: String
outName = case Maybe String
topName of
Just String
name' -> String
name'
Maybe String
Nothing -> Name -> String
nameBase Name
name
[|| Synthesize
{ t_name = outName
, t_inputs = ins
, t_output = out
} ||]
maybeBuildTopEntity :: Maybe String -> Name -> Q (TExp (Maybe TopEntity))
maybeBuildTopEntity :: Maybe String -> Name -> Q (TExp (Maybe TopEntity))
maybeBuildTopEntity Maybe String
topName Name
name = do
Q (TExp (Maybe TopEntity))
-> Q (TExp (Maybe TopEntity)) -> Q (TExp (Maybe TopEntity))
forall a. Q a -> Q a -> Q a
recover ([|| Nothing ||]) (Q (TExp (Maybe TopEntity)) -> Q (TExp (Maybe TopEntity)))
-> Q (TExp (Maybe TopEntity)) -> Q (TExp (Maybe TopEntity))
forall a b. (a -> b) -> a -> b
$ do
let expr :: TExpQ TopEntity
expr = Name -> Q (Name, Type)
getNameBinding Name
name Q (Name, Type)
-> ((Name, Type) -> TExpQ TopEntity) -> TExpQ TopEntity
forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= Maybe String -> (Name, Type) -> TExpQ TopEntity
buildTopEntity Maybe String
topName
[|| Just ($$expr) ||]
getNameBinding :: Name -> Q (Name, Type)
getNameBinding :: Name -> Q (Name, Type)
getNameBinding Name
n = Name -> Q Info
reify Name
n Q Info -> (Info -> Q (Name, Type)) -> Q (Name, Type)
forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
VarI Name
name Type
ty Maybe Dec
_ -> (Name, Type) -> Q (Name, Type)
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Name
name, Type
ty)
Info
_ -> String -> Q (Name, Type)
forall (m :: Type -> Type) a. MonadFail m => String -> m a
fail String
"getNameBinding: Invalid Name, must be a top-level binding!"
makeTopEntityWithName' :: Name -> Maybe String -> DecQ
makeTopEntityWithName' :: Name -> Maybe String -> DecQ
makeTopEntityWithName' Name
n Maybe String
topName = do
(Name
name,Type
ty) <- Name -> Q (Name, Type)
getNameBinding Name
n
TExp TopEntity
topEntity <- Maybe String -> (Name, Type) -> TExpQ TopEntity
buildTopEntity Maybe String
topName (Name
name,Type
ty)
let prag :: Exp -> Dec
prag Exp
t = Pragma -> Dec
PragmaD (AnnTarget -> Exp -> Pragma
AnnP (Name -> AnnTarget
valueAnnotation Name
name) Exp
t)
Dec -> DecQ
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Dec -> DecQ) -> Dec -> DecQ
forall a b. (a -> b) -> a -> b
$ Exp -> Dec
prag (Exp -> Dec) -> Exp -> Dec
forall a b. (a -> b) -> a -> b
$ TExp TopEntity -> Exp
forall a. TExp a -> Exp
unType TExp TopEntity
topEntity
makeTopEntityWithName :: Name -> String -> DecsQ
makeTopEntityWithName :: Name -> String -> Q [Dec]
makeTopEntityWithName Name
nam String
top = Dec -> [Dec]
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Dec -> [Dec]) -> DecQ -> Q [Dec]
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Name -> Maybe String -> DecQ
makeTopEntityWithName' Name
nam (String -> Maybe String
forall a. a -> Maybe a
Just String
top)
makeTopEntity :: Name -> DecsQ
makeTopEntity :: Name -> Q [Dec]
makeTopEntity Name
nam = Dec -> [Dec]
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Dec -> [Dec]) -> DecQ -> Q [Dec]
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Name -> Maybe String -> DecQ
makeTopEntityWithName' Name
nam Maybe String
forall a. Maybe a
Nothing