{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TemplateHaskell #-}
module Clash.Netlist where
import Control.Exception (throw)
import Control.Lens ((.=))
import qualified Control.Lens as Lens
import Control.Monad (join)
import Control.Monad.IO.Class (liftIO)
import Control.Monad.Reader (runReaderT)
import Control.Monad.State.Strict (State, runStateT)
import Data.Binary.IEEE754 (floatToWord, doubleToWord)
import Data.Char (ord)
import Data.Either (partitionEithers, rights)
import Data.HashMap.Strict (HashMap)
import qualified Data.HashMap.Strict as HashMapS
import qualified Data.HashMap.Lazy as HashMap
import Data.List (elemIndex, partition, sortOn)
import Data.List.Extra (zipEqual)
import Data.Maybe
(catMaybes, listToMaybe, mapMaybe, fromMaybe)
import qualified Data.Set as Set
import Data.Primitive.ByteArray (ByteArray (..))
import qualified Data.Text as StrictText
import qualified Data.Vector.Primitive as PV
import GHC.Integer.GMP.Internals (Integer (..), BigNat (..))
import System.FilePath ((</>), (<.>))
import Text.Read (readMaybe)
import Outputable (ppr, showSDocUnsafe)
import SrcLoc (isGoodSrcSpan)
import Clash.Annotations.Primitive (extractPrim)
import Clash.Annotations.BitRepresentation.ClashLib
(coreToType')
import Clash.Annotations.BitRepresentation.Internal
(CustomReprs, DataRepr'(..), ConstrRepr'(..), getDataRepr, getConstrRepr)
import Clash.Annotations.TopEntity (TopEntity (..))
import Clash.Core.DataCon (DataCon (..))
import Clash.Core.Literal (Literal (..))
import Clash.Core.Name (Name(..))
import Clash.Core.Pretty (showPpr)
import Clash.Core.Term
( Alt, Pat (..), Term (..), TickInfo (..), PrimInfo(primName), collectArgs
, collectArgsTicks, collectTicks, mkApps, mkTicks, stripTicks)
import qualified Clash.Core.Term as Core
import Clash.Core.TermInfo (termType)
import Clash.Core.Type
(Type (..), coreView1, splitFunForallTy, splitCoreFunForallTy)
import Clash.Core.TyCon (TyConMap)
import Clash.Core.Util (splitShouldSplit)
import Clash.Core.Var (Id, Var (..), isGlobalId)
import Clash.Core.VarEnv
(VarEnv, emptyInScopeSet, emptyVarEnv, extendVarEnv, lookupVarEnv,
lookupVarEnv', mkVarEnv)
import Clash.Driver.Types (BindingMap, Binding(..), ClashOpts (..))
import Clash.Netlist.BlackBox
import Clash.Netlist.Id
import Clash.Netlist.Types as HW
import Clash.Netlist.Util
import Clash.Primitives.Types as P
import Clash.Util
import qualified Clash.Util.Interpolate as I
genNetlist
:: Bool
-> ClashOpts
-> CustomReprs
-> BindingMap
-> [TopEntityT]
-> CompiledPrimMap
-> TyConMap
-> (CustomReprs -> TyConMap -> Type ->
State HWMap (Maybe (Either String FilteredHWType)))
-> Int
-> (IdType -> Identifier -> Identifier)
-> (IdType -> Identifier -> Identifier -> Identifier)
-> Bool
-> SomeBackend
-> HashMap Identifier Word
-> FilePath
-> ComponentPrefix
-> Id
-> IO (VarEnv ([Bool],SrcSpan,HashMap Identifier Word,Component),HashMap Identifier Word)
genNetlist :: Bool
-> ClashOpts
-> CustomReprs
-> BindingMap
-> [TopEntityT]
-> CompiledPrimMap
-> TyConMap
-> (CustomReprs
-> TyConMap
-> Type
-> State HWMap (Maybe (Either String FilteredHWType)))
-> Int
-> (IdType -> Identifier -> Identifier)
-> (IdType -> Identifier -> Identifier -> Identifier)
-> Bool
-> SomeBackend
-> HashMap Identifier Word
-> String
-> ComponentPrefix
-> Id
-> IO
(VarEnv ([Bool], SrcSpan, HashMap Identifier Word, Component),
HashMap Identifier Word)
genNetlist Bool
isTb ClashOpts
opts CustomReprs
reprs BindingMap
globals [TopEntityT]
tops CompiledPrimMap
primMap TyConMap
tcm CustomReprs
-> TyConMap
-> Type
-> State HWMap (Maybe (Either String FilteredHWType))
typeTrans Int
iw IdType -> Identifier -> Identifier
mkId IdType -> Identifier -> Identifier -> Identifier
extId Bool
ite SomeBackend
be HashMap Identifier Word
seen String
env ComponentPrefix
prefixM Id
topEntity = do
(([Bool], SrcSpan, HashMap Identifier Word, Component)
_,NetlistState
s) <- Bool
-> ClashOpts
-> CustomReprs
-> BindingMap
-> VarEnv TopEntityT
-> CompiledPrimMap
-> TyConMap
-> (CustomReprs
-> TyConMap
-> Type
-> State HWMap (Maybe (Either String FilteredHWType)))
-> Int
-> (IdType -> Identifier -> Identifier)
-> (IdType -> Identifier -> Identifier -> Identifier)
-> Bool
-> SomeBackend
-> HashMap Identifier Word
-> String
-> ComponentPrefix
-> NetlistMonad
([Bool], SrcSpan, HashMap Identifier Word, Component)
-> IO
(([Bool], SrcSpan, HashMap Identifier Word, Component),
NetlistState)
forall a.
Bool
-> ClashOpts
-> CustomReprs
-> BindingMap
-> VarEnv TopEntityT
-> CompiledPrimMap
-> TyConMap
-> (CustomReprs
-> TyConMap
-> Type
-> State HWMap (Maybe (Either String FilteredHWType)))
-> Int
-> (IdType -> Identifier -> Identifier)
-> (IdType -> Identifier -> Identifier -> Identifier)
-> Bool
-> SomeBackend
-> HashMap Identifier Word
-> String
-> ComponentPrefix
-> NetlistMonad a
-> IO (a, NetlistState)
runNetlistMonad Bool
isTb ClashOpts
opts CustomReprs
reprs BindingMap
globals VarEnv TopEntityT
topEntityMap
CompiledPrimMap
primMap TyConMap
tcm CustomReprs
-> TyConMap
-> Type
-> State HWMap (Maybe (Either String FilteredHWType))
typeTrans Int
iw IdType -> Identifier -> Identifier
mkId IdType -> Identifier -> Identifier -> Identifier
extId Bool
ite SomeBackend
be HashMap Identifier Word
seen String
env ComponentPrefix
prefixM (NetlistMonad ([Bool], SrcSpan, HashMap Identifier Word, Component)
-> IO
(([Bool], SrcSpan, HashMap Identifier Word, Component),
NetlistState))
-> NetlistMonad
([Bool], SrcSpan, HashMap Identifier Word, Component)
-> IO
(([Bool], SrcSpan, HashMap Identifier Word, Component),
NetlistState)
forall a b. (a -> b) -> a -> b
$
HasCallStack =>
Id
-> NetlistMonad
([Bool], SrcSpan, HashMap Identifier Word, Component)
Id
-> NetlistMonad
([Bool], SrcSpan, HashMap Identifier Word, Component)
genComponent Id
topEntity
(VarEnv ([Bool], SrcSpan, HashMap Identifier Word, Component),
HashMap Identifier Word)
-> IO
(VarEnv ([Bool], SrcSpan, HashMap Identifier Word, Component),
HashMap Identifier Word)
forall (m :: Type -> Type) a. Monad m => a -> m a
return ( NetlistState
-> VarEnv ([Bool], SrcSpan, HashMap Identifier Word, Component)
_components NetlistState
s
, NetlistState -> HashMap Identifier Word
_seenComps NetlistState
s
)
where
topEntityMap :: VarEnv TopEntityT
topEntityMap :: VarEnv TopEntityT
topEntityMap = [(Id, TopEntityT)] -> VarEnv TopEntityT
forall a b. [(Var a, b)] -> VarEnv b
mkVarEnv ([Id] -> [TopEntityT] -> [(Id, TopEntityT)]
forall a b. [a] -> [b] -> [(a, b)]
zip ((TopEntityT -> Id) -> [TopEntityT] -> [Id]
forall a b. (a -> b) -> [a] -> [b]
map TopEntityT -> Id
topId [TopEntityT]
tops) [TopEntityT]
tops)
runNetlistMonad
:: Bool
-> ClashOpts
-> CustomReprs
-> BindingMap
-> VarEnv TopEntityT
-> CompiledPrimMap
-> TyConMap
-> (CustomReprs -> TyConMap -> Type ->
State HWMap (Maybe (Either String FilteredHWType)))
-> Int
-> (IdType -> Identifier -> Identifier)
-> (IdType -> Identifier -> Identifier -> Identifier)
-> Bool
-> SomeBackend
-> HashMap Identifier Word
-> FilePath
-> ComponentPrefix
-> NetlistMonad a
-> IO (a, NetlistState)
runNetlistMonad :: Bool
-> ClashOpts
-> CustomReprs
-> BindingMap
-> VarEnv TopEntityT
-> CompiledPrimMap
-> TyConMap
-> (CustomReprs
-> TyConMap
-> Type
-> State HWMap (Maybe (Either String FilteredHWType)))
-> Int
-> (IdType -> Identifier -> Identifier)
-> (IdType -> Identifier -> Identifier -> Identifier)
-> Bool
-> SomeBackend
-> HashMap Identifier Word
-> String
-> ComponentPrefix
-> NetlistMonad a
-> IO (a, NetlistState)
runNetlistMonad Bool
isTb ClashOpts
opts CustomReprs
reprs BindingMap
s VarEnv TopEntityT
tops CompiledPrimMap
p TyConMap
tcm CustomReprs
-> TyConMap
-> Type
-> State HWMap (Maybe (Either String FilteredHWType))
typeTrans Int
iw IdType -> Identifier -> Identifier
mkId IdType -> Identifier -> Identifier -> Identifier
extId Bool
ite SomeBackend
be HashMap Identifier Word
seenIds_ String
env ComponentPrefix
prefixM
= (ReaderT NetlistEnv IO (a, NetlistState)
-> NetlistEnv -> IO (a, NetlistState))
-> NetlistEnv
-> ReaderT NetlistEnv IO (a, NetlistState)
-> IO (a, NetlistState)
forall a b c. (a -> b -> c) -> b -> a -> c
flip ReaderT NetlistEnv IO (a, NetlistState)
-> NetlistEnv -> IO (a, NetlistState)
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT (Identifier -> Identifier -> Maybe Identifier -> NetlistEnv
NetlistEnv Identifier
"" Identifier
"" Maybe Identifier
forall a. Maybe a
Nothing)
(ReaderT NetlistEnv IO (a, NetlistState) -> IO (a, NetlistState))
-> (NetlistMonad a -> ReaderT NetlistEnv IO (a, NetlistState))
-> NetlistMonad a
-> IO (a, NetlistState)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (StateT NetlistState (ReaderT NetlistEnv IO) a
-> NetlistState -> ReaderT NetlistEnv IO (a, NetlistState))
-> NetlistState
-> StateT NetlistState (ReaderT NetlistEnv IO) a
-> ReaderT NetlistEnv IO (a, NetlistState)
forall a b c. (a -> b -> c) -> b -> a -> c
flip StateT NetlistState (ReaderT NetlistEnv IO) a
-> NetlistState -> ReaderT NetlistEnv IO (a, NetlistState)
forall s (m :: Type -> Type) a. StateT s m a -> s -> m (a, s)
runStateT NetlistState
s'
(StateT NetlistState (ReaderT NetlistEnv IO) a
-> ReaderT NetlistEnv IO (a, NetlistState))
-> (NetlistMonad a
-> StateT NetlistState (ReaderT NetlistEnv IO) a)
-> NetlistMonad a
-> ReaderT NetlistEnv IO (a, NetlistState)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NetlistMonad a -> StateT NetlistState (ReaderT NetlistEnv IO) a
forall a.
NetlistMonad a -> StateT NetlistState (ReaderT NetlistEnv IO) a
runNetlist
where
s' :: NetlistState
s' =
BindingMap
-> Int
-> VarEnv ([Bool], SrcSpan, HashMap Identifier Word, Component)
-> CompiledPrimMap
-> (CustomReprs
-> TyConMap
-> Type
-> State HWMap (Maybe (Either String FilteredHWType)))
-> TyConMap
-> (Identifier, SrcSpan)
-> Int
-> (IdType -> Identifier -> Identifier)
-> (IdType -> Identifier -> Identifier -> Identifier)
-> HashMap Identifier Word
-> HashMap Identifier Word
-> Set Identifier
-> VarEnv Identifier
-> VarEnv TopEntityT
-> String
-> Int
-> ComponentPrefix
-> CustomReprs
-> ClashOpts
-> Bool
-> Bool
-> SomeBackend
-> HWMap
-> NetlistState
NetlistState
BindingMap
s Int
0 VarEnv ([Bool], SrcSpan, HashMap Identifier Word, Component)
forall a. VarEnv a
emptyVarEnv CompiledPrimMap
p CustomReprs
-> TyConMap
-> Type
-> State HWMap (Maybe (Either String FilteredHWType))
typeTrans TyConMap
tcm (Identifier
StrictText.empty,SrcSpan
noSrcSpan) Int
iw IdType -> Identifier -> Identifier
mkId
IdType -> Identifier -> Identifier -> Identifier
extId HashMap Identifier Word
forall k v. HashMap k v
HashMapS.empty HashMap Identifier Word
seenIds' Set Identifier
forall a. Set a
Set.empty VarEnv Identifier
names VarEnv TopEntityT
tops String
env Int
0 ComponentPrefix
prefixM CustomReprs
reprs ClashOpts
opts Bool
isTb Bool
ite SomeBackend
be
HWMap
forall k v. HashMap k v
HashMapS.empty
(HashMap Identifier Word
seenIds',VarEnv Identifier
names) = Bool
-> (IdType -> Identifier -> Identifier)
-> ComponentPrefix
-> HashMap Identifier Word
-> VarEnv Identifier
-> BindingMap
-> (HashMap Identifier Word, VarEnv Identifier)
genNames (ClashOpts -> Bool
opt_newInlineStrat ClashOpts
opts) IdType -> Identifier -> Identifier
mkId ComponentPrefix
prefixM HashMap Identifier Word
seenIds_
VarEnv Identifier
forall a. VarEnv a
emptyVarEnv BindingMap
s
genNames :: Bool
-> (IdType -> Identifier -> Identifier)
-> ComponentPrefix
-> HashMap Identifier Word
-> VarEnv Identifier
-> BindingMap
-> (HashMap Identifier Word, VarEnv Identifier)
genNames :: Bool
-> (IdType -> Identifier -> Identifier)
-> ComponentPrefix
-> HashMap Identifier Word
-> VarEnv Identifier
-> BindingMap
-> (HashMap Identifier Word, VarEnv Identifier)
genNames Bool
newInlineStrat IdType -> Identifier -> Identifier
mkId ComponentPrefix
prefixM HashMap Identifier Word
s0 VarEnv Identifier
m0 = (Binding
-> (HashMap Identifier Word, VarEnv Identifier)
-> (HashMap Identifier Word, VarEnv Identifier))
-> (HashMap Identifier Word, VarEnv Identifier)
-> BindingMap
-> (HashMap Identifier Word, VarEnv Identifier)
forall (t :: Type -> Type) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Binding
-> (HashMap Identifier Word, VarEnv Identifier)
-> (HashMap Identifier Word, VarEnv Identifier)
go (HashMap Identifier Word
s0,VarEnv Identifier
m0)
where
go :: Binding
-> (HashMap Identifier Word, VarEnv Identifier)
-> (HashMap Identifier Word, VarEnv Identifier)
go Binding
b (HashMap Identifier Word
s,VarEnv Identifier
m) =
let nm' :: Identifier
nm' = Bool
-> HashMap Identifier Word
-> (IdType -> Identifier -> Identifier)
-> ComponentPrefix
-> Id
-> Identifier
genComponentName Bool
newInlineStrat HashMap Identifier Word
s IdType -> Identifier -> Identifier
mkId ComponentPrefix
prefixM (Binding -> Id
bindingId Binding
b)
s' :: HashMap Identifier Word
s' = Identifier
-> Word -> HashMap Identifier Word -> HashMap Identifier Word
forall k v.
(Eq k, Hashable k) =>
k -> v -> HashMap k v -> HashMap k v
HashMapS.insert Identifier
nm' Word
0 HashMap Identifier Word
s
m' :: VarEnv Identifier
m' = Id -> Identifier -> VarEnv Identifier -> VarEnv Identifier
forall b a. Var b -> a -> VarEnv a -> VarEnv a
extendVarEnv (Binding -> Id
bindingId Binding
b) Identifier
nm' VarEnv Identifier
m
in (HashMap Identifier Word
s', VarEnv Identifier
m')
genComponent
:: HasCallStack
=> Id
-> NetlistMonad ([Bool],SrcSpan,HashMap Identifier Word,Component)
genComponent :: Id
-> NetlistMonad
([Bool], SrcSpan, HashMap Identifier Word, Component)
genComponent Id
compName = do
Maybe Binding
compExprM <- Id -> BindingMap -> Maybe Binding
forall b a. Var b -> VarEnv a -> Maybe a
lookupVarEnv Id
compName (BindingMap -> Maybe Binding)
-> NetlistMonad BindingMap -> NetlistMonad (Maybe Binding)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Getting BindingMap NetlistState BindingMap
-> NetlistMonad BindingMap
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
Lens.use Getting BindingMap NetlistState BindingMap
Lens' NetlistState BindingMap
bindings
case Maybe Binding
compExprM of
Maybe Binding
Nothing -> do
(Identifier
_,SrcSpan
sp) <- Getting (Identifier, SrcSpan) NetlistState (Identifier, SrcSpan)
-> NetlistMonad (Identifier, SrcSpan)
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
Lens.use Getting (Identifier, SrcSpan) NetlistState (Identifier, SrcSpan)
Lens' NetlistState (Identifier, SrcSpan)
curCompNm
ClashException
-> NetlistMonad
([Bool], SrcSpan, HashMap Identifier Word, Component)
forall a e. Exception e => e -> a
throw (SrcSpan -> String -> Maybe String -> ClashException
ClashException SrcSpan
sp ($(String
curLoc) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"No normalized expression found for: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Id -> String
forall a. Show a => a -> String
show Id
compName) Maybe String
forall a. Maybe a
Nothing)
Just Binding
b -> do
Id
-> Lens'
NetlistState
(VarEnv ([Bool], SrcSpan, HashMap Identifier Word, Component))
-> NetlistMonad
([Bool], SrcSpan, HashMap Identifier Word, Component)
-> NetlistMonad
([Bool], SrcSpan, HashMap Identifier Word, Component)
forall s (m :: Type -> Type) k v.
(MonadState s m, Uniquable k) =>
k -> Lens' s (UniqMap v) -> m v -> m v
makeCachedU Id
compName Lens'
NetlistState
(VarEnv ([Bool], SrcSpan, HashMap Identifier Word, Component))
components (NetlistMonad ([Bool], SrcSpan, HashMap Identifier Word, Component)
-> NetlistMonad
([Bool], SrcSpan, HashMap Identifier Word, Component))
-> NetlistMonad
([Bool], SrcSpan, HashMap Identifier Word, Component)
-> NetlistMonad
([Bool], SrcSpan, HashMap Identifier Word, Component)
forall a b. (a -> b) -> a -> b
$ HasCallStack =>
Id
-> Term
-> NetlistMonad
([Bool], SrcSpan, HashMap Identifier Word, Component)
Id
-> Term
-> NetlistMonad
([Bool], SrcSpan, HashMap Identifier Word, Component)
genComponentT Id
compName (Binding -> Term
bindingTerm Binding
b)
genComponentT
:: HasCallStack
=> Id
-> Term
-> NetlistMonad ([Bool],SrcSpan,HashMap Identifier Word,Component)
genComponentT :: Id
-> Term
-> NetlistMonad
([Bool], SrcSpan, HashMap Identifier Word, Component)
genComponentT Id
compName Term
componentExpr = do
(Int -> Identity Int) -> NetlistState -> Identity NetlistState
Lens' NetlistState Int
varCount ((Int -> Identity Int) -> NetlistState -> Identity NetlistState)
-> Int -> NetlistMonad ()
forall s (m :: Type -> Type) a b.
MonadState s m =>
ASetter s s a b -> b -> m ()
.= Int
0
Identifier
componentName1 <- (VarEnv Identifier -> Id -> Identifier
forall a b. VarEnv a -> Var b -> a
`lookupVarEnv'` Id
compName) (VarEnv Identifier -> Identifier)
-> NetlistMonad (VarEnv Identifier) -> NetlistMonad Identifier
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Getting (VarEnv Identifier) NetlistState (VarEnv Identifier)
-> NetlistMonad (VarEnv Identifier)
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
Lens.use Getting (VarEnv Identifier) NetlistState (VarEnv Identifier)
Lens' NetlistState (VarEnv Identifier)
componentNames
Maybe (Maybe TopEntity)
topEntMM <- (TopEntityT -> Maybe TopEntity)
-> Maybe TopEntityT -> Maybe (Maybe TopEntity)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap TopEntityT -> Maybe TopEntity
topAnnotation (Maybe TopEntityT -> Maybe (Maybe TopEntity))
-> (VarEnv TopEntityT -> Maybe TopEntityT)
-> VarEnv TopEntityT
-> Maybe (Maybe TopEntity)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Id -> VarEnv TopEntityT -> Maybe TopEntityT
forall b a. Var b -> VarEnv a -> Maybe a
lookupVarEnv Id
compName (VarEnv TopEntityT -> Maybe (Maybe TopEntity))
-> NetlistMonad (VarEnv TopEntityT)
-> NetlistMonad (Maybe (Maybe TopEntity))
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Getting (VarEnv TopEntityT) NetlistState (VarEnv TopEntityT)
-> NetlistMonad (VarEnv TopEntityT)
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
Lens.use Getting (VarEnv TopEntityT) NetlistState (VarEnv TopEntityT)
Lens' NetlistState (VarEnv TopEntityT)
topEntityAnns
ComponentPrefix
prefixM <- Getting ComponentPrefix NetlistState ComponentPrefix
-> NetlistMonad ComponentPrefix
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
Lens.use Getting ComponentPrefix NetlistState ComponentPrefix
Lens' NetlistState ComponentPrefix
componentPrefix
let componentName2 :: Identifier
componentName2 = case (ComponentPrefix -> Maybe Identifier
componentPrefixTop ComponentPrefix
prefixM, Maybe (Maybe TopEntity) -> Maybe TopEntity
forall (m :: Type -> Type) a. Monad m => m (m a) -> m a
join Maybe (Maybe TopEntity)
topEntMM) of
(Just Identifier
p, Just TopEntity
ann) -> Identifier
p Identifier -> Identifier -> Identifier
`StrictText.append` String -> Identifier
StrictText.pack (Char
'_'Char -> String -> String
forall a. a -> [a] -> [a]
:TopEntity -> String
t_name TopEntity
ann)
(Maybe Identifier
_,Just TopEntity
ann) -> String -> Identifier
StrictText.pack (TopEntity -> String
t_name TopEntity
ann)
(Maybe Identifier, Maybe TopEntity)
_ -> Identifier
componentName1
SrcSpan
sp <- (Binding -> SrcSpan
bindingLoc (Binding -> SrcSpan)
-> (BindingMap -> Binding) -> BindingMap -> SrcSpan
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (BindingMap -> Id -> Binding
forall a b. VarEnv a -> Var b -> a
`lookupVarEnv'` Id
compName)) (BindingMap -> SrcSpan)
-> NetlistMonad BindingMap -> NetlistMonad SrcSpan
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Getting BindingMap NetlistState BindingMap
-> NetlistMonad BindingMap
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
Lens.use Getting BindingMap NetlistState BindingMap
Lens' NetlistState BindingMap
bindings
((Identifier, SrcSpan) -> Identity (Identifier, SrcSpan))
-> NetlistState -> Identity NetlistState
Lens' NetlistState (Identifier, SrcSpan)
curCompNm (((Identifier, SrcSpan) -> Identity (Identifier, SrcSpan))
-> NetlistState -> Identity NetlistState)
-> (Identifier, SrcSpan) -> NetlistMonad ()
forall s (m :: Type -> Type) a b.
MonadState s m =>
ASetter s s a b -> b -> m ()
.= (Identifier
componentName2,SrcSpan
sp)
TyConMap
tcm <- Getting TyConMap NetlistState TyConMap -> NetlistMonad TyConMap
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
Lens.use Getting TyConMap NetlistState TyConMap
Lens' NetlistState TyConMap
tcCache
Maybe TopEntityT
topEntityTypeM <- Id -> VarEnv TopEntityT -> Maybe TopEntityT
forall b a. Var b -> VarEnv a -> Maybe a
lookupVarEnv Id
compName (VarEnv TopEntityT -> Maybe TopEntityT)
-> NetlistMonad (VarEnv TopEntityT)
-> NetlistMonad (Maybe TopEntityT)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Getting (VarEnv TopEntityT) NetlistState (VarEnv TopEntityT)
-> NetlistMonad (VarEnv TopEntityT)
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
Lens.use Getting (VarEnv TopEntityT) NetlistState (VarEnv TopEntityT)
Lens' NetlistState (VarEnv TopEntityT)
topEntityAnns
let topEntityTypeM' :: Maybe Type
topEntityTypeM' = ([Either TyVar Type], Type) -> Type
forall a b. (a, b) -> b
snd (([Either TyVar Type], Type) -> Type)
-> (TopEntityT -> ([Either TyVar Type], Type))
-> TopEntityT
-> Type
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TyConMap -> Type -> ([Either TyVar Type], Type)
splitCoreFunForallTy TyConMap
tcm (Type -> ([Either TyVar Type], Type))
-> (TopEntityT -> Type)
-> TopEntityT
-> ([Either TyVar Type], Type)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Id -> Type
forall a. Var a -> Type
varType (Id -> Type) -> (TopEntityT -> Id) -> TopEntityT -> Type
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TopEntityT -> Id
topId (TopEntityT -> Type) -> Maybe TopEntityT -> Maybe Type
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe TopEntityT
topEntityTypeM
(HashMap Identifier Word -> Identity (HashMap Identifier Word))
-> NetlistState -> Identity NetlistState
Lens' NetlistState (HashMap Identifier Word)
seenIds ((HashMap Identifier Word -> Identity (HashMap Identifier Word))
-> NetlistState -> Identity NetlistState)
-> HashMap Identifier Word -> NetlistMonad ()
forall s (m :: Type -> Type) a b.
MonadState s m =>
ASetter s s a b -> b -> m ()
.= HashMap Identifier Word
forall k v. HashMap k v
HashMapS.empty
([Bool]
wereVoids,[(Identifier, HWType)]
compInps,[Declaration]
argWrappers,[(Identifier, HWType)]
compOutps,[Declaration]
resUnwrappers,[LetBinding]
binders,Maybe Id
resultM) <-
case TyConMap -> Term -> Either String ([Id], [LetBinding], Id)
splitNormalized TyConMap
tcm Term
componentExpr of
Right ([Id]
args, [LetBinding]
binds, Id
res) -> do
let varType' :: Type
varType' = Type -> Maybe Type -> Type
forall a. a -> Maybe a -> a
fromMaybe (Id -> Type
forall a. Var a -> Type
varType Id
res) Maybe Type
topEntityTypeM'
HasCallStack =>
InScopeSet
-> Maybe (Maybe TopEntity)
-> ([Id], [LetBinding], Id)
-> NetlistMonad
([Bool], [(Identifier, HWType)], [Declaration],
[(Identifier, HWType)], [Declaration], [LetBinding], Maybe Id)
InScopeSet
-> Maybe (Maybe TopEntity)
-> ([Id], [LetBinding], Id)
-> NetlistMonad
([Bool], [(Identifier, HWType)], [Declaration],
[(Identifier, HWType)], [Declaration], [LetBinding], Maybe Id)
mkUniqueNormalized InScopeSet
emptyInScopeSet Maybe (Maybe TopEntity)
topEntMM (([Id]
args, [LetBinding]
binds, Id
res{varType :: Type
varType=Type
varType'}))
Left String
err ->
ClashException
-> NetlistMonad
([Bool], [(Identifier, HWType)], [Declaration],
[(Identifier, HWType)], [Declaration], [LetBinding], Maybe Id)
forall a e. Exception e => e -> a
throw (SrcSpan -> String -> Maybe String -> ClashException
ClashException SrcSpan
sp (String
$curLoc String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
err) Maybe String
forall a. Maybe a
Nothing)
[Declaration]
netDecls <- ([Maybe Declaration] -> [Declaration])
-> NetlistMonad [Maybe Declaration] -> NetlistMonad [Declaration]
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap [Maybe Declaration] -> [Declaration]
forall a. [Maybe a] -> [a]
catMaybes (NetlistMonad [Maybe Declaration] -> NetlistMonad [Declaration])
-> ([LetBinding] -> NetlistMonad [Maybe Declaration])
-> [LetBinding]
-> NetlistMonad [Declaration]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (LetBinding -> NetlistMonad (Maybe Declaration))
-> [LetBinding] -> NetlistMonad [Maybe Declaration]
forall (t :: Type -> Type) (m :: Type -> Type) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM LetBinding -> NetlistMonad (Maybe Declaration)
mkNetDecl ([LetBinding] -> NetlistMonad [Declaration])
-> [LetBinding] -> NetlistMonad [Declaration]
forall a b. (a -> b) -> a -> b
$ (LetBinding -> Bool) -> [LetBinding] -> [LetBinding]
forall a. (a -> Bool) -> [a] -> [a]
filter ((Id -> Bool) -> (Id -> Id -> Bool) -> Maybe Id -> Id -> Bool
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Bool -> Id -> Bool
forall a b. a -> b -> a
const Bool
True) Id -> Id -> Bool
forall a. Eq a => a -> a -> Bool
(/=) Maybe Id
resultM (Id -> Bool) -> (LetBinding -> Id) -> LetBinding -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LetBinding -> Id
forall a b. (a, b) -> a
fst) [LetBinding]
binders
[Declaration]
decls <- [[Declaration]] -> [Declaration]
forall (t :: Type -> Type) a. Foldable t => t [a] -> [a]
concat ([[Declaration]] -> [Declaration])
-> NetlistMonad [[Declaration]] -> NetlistMonad [Declaration]
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> (LetBinding -> NetlistMonad [Declaration])
-> [LetBinding] -> NetlistMonad [[Declaration]]
forall (t :: Type -> Type) (m :: Type -> Type) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM ((Id -> Term -> NetlistMonad [Declaration])
-> LetBinding -> NetlistMonad [Declaration]
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry HasCallStack => Id -> Term -> NetlistMonad [Declaration]
Id -> Term -> NetlistMonad [Declaration]
mkDeclarations) [LetBinding]
binders
case Maybe Id
resultM of
Just Id
result -> do
Just (NetDecl' Maybe Identifier
_ WireOrReg
rw Identifier
_ Either Identifier HWType
_ Maybe Expr
rIM) <- LetBinding -> NetlistMonad (Maybe Declaration)
mkNetDecl (LetBinding -> NetlistMonad (Maybe Declaration))
-> ([LetBinding] -> LetBinding)
-> [LetBinding]
-> NetlistMonad (Maybe Declaration)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [LetBinding] -> LetBinding
forall a. [a] -> a
head ([LetBinding] -> NetlistMonad (Maybe Declaration))
-> [LetBinding] -> NetlistMonad (Maybe Declaration)
forall a b. (a -> b) -> a -> b
$ (LetBinding -> Bool) -> [LetBinding] -> [LetBinding]
forall a. (a -> Bool) -> [a] -> [a]
filter ((Id -> Id -> Bool
forall a. Eq a => a -> a -> Bool
==Id
result) (Id -> Bool) -> (LetBinding -> Id) -> LetBinding -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LetBinding -> Id
forall a b. (a, b) -> a
fst) [LetBinding]
binders
let ([(WireOrReg, (Identifier, HWType), Maybe Expr)]
compOutps',[Declaration]
resUnwrappers') = case [(Identifier, HWType)]
compOutps of
[(Identifier, HWType)
oport] -> ([(WireOrReg
rw,(Identifier, HWType)
oport,Maybe Expr
rIM)],[Declaration]
resUnwrappers)
[(Identifier, HWType)]
_ -> let NetDecl Maybe Identifier
n Identifier
res HWType
resTy = [Declaration] -> Declaration
forall a. [a] -> a
head [Declaration]
resUnwrappers
in (((Identifier, HWType)
-> (WireOrReg, (Identifier, HWType), Maybe Expr))
-> [(Identifier, HWType)]
-> [(WireOrReg, (Identifier, HWType), Maybe Expr)]
forall a b. (a -> b) -> [a] -> [b]
map (WireOrReg
Wire,,Maybe Expr
forall a. Maybe a
Nothing) [(Identifier, HWType)]
compOutps
,Maybe Identifier
-> WireOrReg
-> Identifier
-> Either Identifier HWType
-> Maybe Expr
-> Declaration
NetDecl' Maybe Identifier
n WireOrReg
rw Identifier
res (HWType -> Either Identifier HWType
forall a b. b -> Either a b
Right HWType
resTy) Maybe Expr
forall a. Maybe a
NothingDeclaration -> [Declaration] -> [Declaration]
forall a. a -> [a] -> [a]
:[Declaration] -> [Declaration]
forall a. [a] -> [a]
tail [Declaration]
resUnwrappers
)
component :: Component
component = Identifier
-> [(Identifier, HWType)]
-> [(WireOrReg, (Identifier, HWType), Maybe Expr)]
-> [Declaration]
-> Component
Component Identifier
componentName2 [(Identifier, HWType)]
compInps [(WireOrReg, (Identifier, HWType), Maybe Expr)]
compOutps'
([Declaration]
netDecls [Declaration] -> [Declaration] -> [Declaration]
forall a. [a] -> [a] -> [a]
++ [Declaration]
argWrappers [Declaration] -> [Declaration] -> [Declaration]
forall a. [a] -> [a] -> [a]
++ [Declaration]
decls [Declaration] -> [Declaration] -> [Declaration]
forall a. [a] -> [a] -> [a]
++ [Declaration]
resUnwrappers')
HashMap Identifier Word
ids <- Getting
(HashMap Identifier Word) NetlistState (HashMap Identifier Word)
-> NetlistMonad (HashMap Identifier Word)
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
Lens.use Getting
(HashMap Identifier Word) NetlistState (HashMap Identifier Word)
Lens' NetlistState (HashMap Identifier Word)
seenIds
([Bool], SrcSpan, HashMap Identifier Word, Component)
-> NetlistMonad
([Bool], SrcSpan, HashMap Identifier Word, Component)
forall (m :: Type -> Type) a. Monad m => a -> m a
return ([Bool]
wereVoids, SrcSpan
sp, HashMap Identifier Word
ids, Component
component)
Maybe Id
Nothing -> do
let component :: Component
component = Identifier
-> [(Identifier, HWType)]
-> [(WireOrReg, (Identifier, HWType), Maybe Expr)]
-> [Declaration]
-> Component
Component Identifier
componentName2 [(Identifier, HWType)]
compInps [] ([Declaration]
netDecls [Declaration] -> [Declaration] -> [Declaration]
forall a. [a] -> [a] -> [a]
++ [Declaration]
argWrappers [Declaration] -> [Declaration] -> [Declaration]
forall a. [a] -> [a] -> [a]
++ [Declaration]
decls)
HashMap Identifier Word
ids <- Getting
(HashMap Identifier Word) NetlistState (HashMap Identifier Word)
-> NetlistMonad (HashMap Identifier Word)
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
Lens.use Getting
(HashMap Identifier Word) NetlistState (HashMap Identifier Word)
Lens' NetlistState (HashMap Identifier Word)
seenIds
([Bool], SrcSpan, HashMap Identifier Word, Component)
-> NetlistMonad
([Bool], SrcSpan, HashMap Identifier Word, Component)
forall (m :: Type -> Type) a. Monad m => a -> m a
return ([Bool]
wereVoids, SrcSpan
sp, HashMap Identifier Word
ids, Component
component)
mkNetDecl :: (Id, Term) -> NetlistMonad (Maybe Declaration)
mkNetDecl :: LetBinding -> NetlistMonad (Maybe Declaration)
mkNetDecl (Id
id_,Term
tm) = NetlistMonad (Maybe Declaration)
-> NetlistMonad (Maybe Declaration)
forall a. NetlistMonad a -> NetlistMonad a
preserveVarEnv (NetlistMonad (Maybe Declaration)
-> NetlistMonad (Maybe Declaration))
-> NetlistMonad (Maybe Declaration)
-> NetlistMonad (Maybe Declaration)
forall a b. (a -> b) -> a -> b
$ do
let typ :: Type
typ = Id -> Type
forall a. Var a -> Type
varType Id
id_
HWType
hwTy <- String -> Type -> NetlistMonad HWType
unsafeCoreTypeToHWTypeM' $(String
curLoc) Type
typ
WireOrReg
wr <- Term -> NetlistMonad WireOrReg
termToWireOrReg Term
tm
Maybe Expr
rIM <- LetBinding -> NetlistMonad (Maybe Expr)
getResInit (Id
id_,Term
tm)
if HWType -> Bool
isVoid HWType
hwTy
then Maybe Declaration -> NetlistMonad (Maybe Declaration)
forall (m :: Type -> Type) a. Monad m => a -> m a
return Maybe Declaration
forall a. Maybe a
Nothing
else Maybe Declaration -> NetlistMonad (Maybe Declaration)
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Maybe Declaration -> NetlistMonad (Maybe Declaration))
-> (Declaration -> Maybe Declaration)
-> Declaration
-> NetlistMonad (Maybe Declaration)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Declaration -> Maybe Declaration
forall a. a -> Maybe a
Just (Declaration -> NetlistMonad (Maybe Declaration))
-> Declaration -> NetlistMonad (Maybe Declaration)
forall a b. (a -> b) -> a -> b
$ Maybe Identifier
-> WireOrReg
-> Identifier
-> Either Identifier HWType
-> Maybe Expr
-> Declaration
NetDecl' (SrcSpan -> Maybe Identifier
addSrcNote SrcSpan
sp)
WireOrReg
wr
(Id -> Identifier
id2identifier Id
id_)
(HWType -> Either Identifier HWType
forall a b. b -> Either a b
Right HWType
hwTy)
Maybe Expr
rIM
where
nm :: Name Term
nm = Id -> Name Term
forall a. Var a -> Name a
varName Id
id_
sp :: SrcSpan
sp = case Term
tm of {Tick (SrcSpan SrcSpan
s) Term
_ -> SrcSpan
s; Term
_ -> Name Term -> SrcSpan
forall a. Name a -> SrcSpan
nameLoc Name Term
nm}
termToWireOrReg :: Term -> NetlistMonad WireOrReg
termToWireOrReg :: Term -> NetlistMonad WireOrReg
termToWireOrReg (Term -> Term
stripTicks -> Case Term
scrut Type
_ alts0 :: [Alt]
alts0@(Alt
_:Alt
_:[Alt]
_)) = do
TyConMap
tcm <- Getting TyConMap NetlistState TyConMap -> NetlistMonad TyConMap
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
Lens.use Getting TyConMap NetlistState TyConMap
Lens' NetlistState TyConMap
tcCache
let scrutTy :: Type
scrutTy = TyConMap -> Term -> Type
termType TyConMap
tcm Term
scrut
HWType
scrutHTy <- String -> Type -> NetlistMonad HWType
unsafeCoreTypeToHWTypeM' $(String
curLoc) Type
scrutTy
Bool
ite <- Getting Bool NetlistState Bool -> NetlistMonad Bool
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
Lens.use Getting Bool NetlistState Bool
Lens' NetlistState Bool
backEndITE
case HWType -> [Alt] -> Maybe (Term, Term)
iteAlts HWType
scrutHTy [Alt]
alts0 of
Just (Term, Term)
_ | Bool
ite -> WireOrReg -> NetlistMonad WireOrReg
forall (m :: Type -> Type) a. Monad m => a -> m a
return WireOrReg
Wire
Maybe (Term, Term)
_ -> WireOrReg -> NetlistMonad WireOrReg
forall (m :: Type -> Type) a. Monad m => a -> m a
return WireOrReg
Reg
termToWireOrReg (Term -> (Term, [Either Term Type])
collectArgs -> (Prim PrimInfo
p,[Either Term Type]
_)) = do
Maybe GuardedCompiledPrimitive
bbM <- Identifier -> CompiledPrimMap -> Maybe GuardedCompiledPrimitive
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HashMap.lookup (PrimInfo -> Identifier
primName PrimInfo
p) (CompiledPrimMap -> Maybe GuardedCompiledPrimitive)
-> NetlistMonad CompiledPrimMap
-> NetlistMonad (Maybe GuardedCompiledPrimitive)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Getting CompiledPrimMap NetlistState CompiledPrimMap
-> NetlistMonad CompiledPrimMap
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
Lens.use Getting CompiledPrimMap NetlistState CompiledPrimMap
Lens' NetlistState CompiledPrimMap
primitives
case Maybe GuardedCompiledPrimitive
bbM of
Just (GuardedCompiledPrimitive -> Maybe CompiledPrimitive
forall a. PrimitiveGuard a -> Maybe a
extractPrim -> Just BlackBox {Bool
[BlackBoxTemplate]
[(Int, Int)]
[((Identifier, Identifier), BlackBox)]
Maybe BlackBox
()
Identifier
BlackBox
WorkInfo
TemplateKind
RenderVoid
template :: forall a b c d. Primitive a b c d -> b
resultInit :: forall a b c d. Primitive a b c d -> Maybe b
resultName :: forall a b c d. Primitive a b c d -> Maybe b
includes :: forall a b c d.
Primitive a b c d -> [((Identifier, Identifier), b)]
functionPlurality :: forall a b c d. Primitive a b c d -> [(Int, Int)]
imports :: forall a b c d. Primitive a b c d -> [a]
libraries :: forall a b c d. Primitive a b c d -> [a]
outputReg :: forall a b c d. Primitive a b c d -> Bool
warning :: forall a b c d. Primitive a b c d -> c
kind :: forall a b c d. Primitive a b c d -> TemplateKind
renderVoid :: forall a b c d. Primitive a b c d -> RenderVoid
workInfo :: forall a b c d. Primitive a b c d -> WorkInfo
name :: forall a b c d. Primitive a b c d -> Identifier
template :: BlackBox
resultInit :: Maybe BlackBox
resultName :: Maybe BlackBox
includes :: [((Identifier, Identifier), BlackBox)]
functionPlurality :: [(Int, Int)]
imports :: [BlackBoxTemplate]
libraries :: [BlackBoxTemplate]
outputReg :: Bool
warning :: ()
kind :: TemplateKind
renderVoid :: RenderVoid
workInfo :: WorkInfo
name :: Identifier
..}) | Bool
outputReg -> WireOrReg -> NetlistMonad WireOrReg
forall (m :: Type -> Type) a. Monad m => a -> m a
return WireOrReg
Reg
Maybe GuardedCompiledPrimitive
_ | PrimInfo -> Identifier
primName PrimInfo
p Identifier -> Identifier -> Bool
forall a. Eq a => a -> a -> Bool
== Identifier
"Clash.Explicit.SimIO.mealyIO" -> WireOrReg -> NetlistMonad WireOrReg
forall (m :: Type -> Type) a. Monad m => a -> m a
return WireOrReg
Reg
Maybe GuardedCompiledPrimitive
_ -> WireOrReg -> NetlistMonad WireOrReg
forall (m :: Type -> Type) a. Monad m => a -> m a
return WireOrReg
Wire
termToWireOrReg Term
_ = WireOrReg -> NetlistMonad WireOrReg
forall (m :: Type -> Type) a. Monad m => a -> m a
return WireOrReg
Wire
addSrcNote :: SrcSpan -> Maybe Identifier
addSrcNote SrcSpan
loc = if SrcSpan -> Bool
isGoodSrcSpan SrcSpan
loc
then Identifier -> Maybe Identifier
forall a. a -> Maybe a
Just (String -> Identifier
StrictText.pack (SDoc -> String
showSDocUnsafe (SrcSpan -> SDoc
forall a. Outputable a => a -> SDoc
ppr SrcSpan
loc)))
else Maybe Identifier
forall a. Maybe a
Nothing
getResInit
:: (Id,Term) -> NetlistMonad (Maybe Expr)
getResInit :: LetBinding -> NetlistMonad (Maybe Expr)
getResInit (Id
i,Term -> (Term, [Either Term Type], [TickInfo])
collectArgsTicks -> (Term
k,[Either Term Type]
args,[TickInfo]
ticks)) = case Term
k of
Prim PrimInfo
p -> HasCallStack => Identifier -> NetlistMonad CompiledPrimitive
Identifier -> NetlistMonad CompiledPrimitive
extractPrimWarnOrFail (PrimInfo -> Identifier
primName PrimInfo
p) NetlistMonad CompiledPrimitive
-> (CompiledPrimitive -> NetlistMonad (Maybe Expr))
-> NetlistMonad (Maybe Expr)
forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= Identifier -> CompiledPrimitive -> NetlistMonad (Maybe Expr)
forall a c d.
Identifier -> Primitive a BlackBox c d -> NetlistMonad (Maybe Expr)
go (PrimInfo -> Identifier
primName PrimInfo
p)
Term
_ -> Maybe Expr -> NetlistMonad (Maybe Expr)
forall (m :: Type -> Type) a. Monad m => a -> m a
return Maybe Expr
forall a. Maybe a
Nothing
where
go :: Identifier -> Primitive a BlackBox c d -> NetlistMonad (Maybe Expr)
go Identifier
pNm (BlackBox {resultInit :: forall a b c d. Primitive a b c d -> Maybe b
resultInit = Just BlackBox
nmD}) = [TickInfo]
-> ([Declaration] -> NetlistMonad (Maybe Expr))
-> NetlistMonad (Maybe Expr)
forall a.
[TickInfo] -> ([Declaration] -> NetlistMonad a) -> NetlistMonad a
withTicks [TickInfo]
ticks (([Declaration] -> NetlistMonad (Maybe Expr))
-> NetlistMonad (Maybe Expr))
-> ([Declaration] -> NetlistMonad (Maybe Expr))
-> NetlistMonad (Maybe Expr)
forall a b. (a -> b) -> a -> b
$ \[Declaration]
_ -> do
(BlackBoxContext
bbCtx,[Declaration]
_) <- Identifier
-> Id
-> [Either Term Type]
-> NetlistMonad (BlackBoxContext, [Declaration])
mkBlackBoxContext Identifier
pNm Id
i [Either Term Type]
args
(BlackBox
bbTempl,[Declaration]
templDecl) <- Identifier
-> BlackBox
-> BlackBoxContext
-> NetlistMonad (BlackBox, [Declaration])
prepareBlackBox Identifier
pNm BlackBox
nmD BlackBoxContext
bbCtx
case [Declaration]
templDecl of
[] -> Maybe Expr -> NetlistMonad (Maybe Expr)
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Expr -> Maybe Expr
forall a. a -> Maybe a
Just (Identifier
-> [BlackBoxTemplate]
-> [BlackBoxTemplate]
-> [((Identifier, Identifier), BlackBox)]
-> BlackBox
-> BlackBoxContext
-> Bool
-> Expr
BlackBoxE Identifier
pNm [] [] [] BlackBox
bbTempl BlackBoxContext
bbCtx Bool
False))
[Declaration]
_ -> do
(Identifier
_,SrcSpan
sloc) <- Getting (Identifier, SrcSpan) NetlistState (Identifier, SrcSpan)
-> NetlistMonad (Identifier, SrcSpan)
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
Lens.use Getting (Identifier, SrcSpan) NetlistState (Identifier, SrcSpan)
Lens' NetlistState (Identifier, SrcSpan)
curCompNm
ClashException -> NetlistMonad (Maybe Expr)
forall a e. Exception e => e -> a
throw (SrcSpan -> String -> Maybe String -> ClashException
ClashException SrcSpan
sloc
([String] -> String
unwords [ $(String
curLoc)
, String
"signal initialization requires declarations:\n"
, [Declaration] -> String
forall a. Show a => a -> String
show [Declaration]
templDecl
])
Maybe String
forall a. Maybe a
Nothing)
go Identifier
_ Primitive a BlackBox c d
_ = Maybe Expr -> NetlistMonad (Maybe Expr)
forall (m :: Type -> Type) a. Monad m => a -> m a
return Maybe Expr
forall a. Maybe a
Nothing
mkDeclarations
:: HasCallStack
=> Id
-> Term
-> NetlistMonad [Declaration]
mkDeclarations :: Id -> Term -> NetlistMonad [Declaration]
mkDeclarations = HasCallStack =>
DeclarationType -> Id -> Term -> NetlistMonad [Declaration]
DeclarationType -> Id -> Term -> NetlistMonad [Declaration]
mkDeclarations' DeclarationType
Concurrent
mkDeclarations'
:: HasCallStack
=> DeclarationType
-> Id
-> Term
-> NetlistMonad [Declaration]
mkDeclarations' :: DeclarationType -> Id -> Term -> NetlistMonad [Declaration]
mkDeclarations' DeclarationType
_declType Id
bndr (Term -> (Term, [TickInfo])
collectTicks -> (Var Id
v,[TickInfo]
ticks)) =
[TickInfo]
-> ([Declaration] -> NetlistMonad [Declaration])
-> NetlistMonad [Declaration]
forall a.
[TickInfo] -> ([Declaration] -> NetlistMonad a) -> NetlistMonad a
withTicks [TickInfo]
ticks (([Declaration] -> NetlistMonad [Declaration])
-> NetlistMonad [Declaration])
-> ([Declaration] -> NetlistMonad [Declaration])
-> NetlistMonad [Declaration]
forall a b. (a -> b) -> a -> b
$ \[Declaration]
tickDecls -> do
HasCallStack =>
Identifier
-> Id -> [Term] -> [Declaration] -> NetlistMonad [Declaration]
Identifier
-> Id -> [Term] -> [Declaration] -> NetlistMonad [Declaration]
mkFunApp (Id -> Identifier
id2identifier Id
bndr) Id
v [] [Declaration]
tickDecls
mkDeclarations' DeclarationType
_declType Id
_bndr e :: Term
e@(Term -> (Term, [TickInfo])
collectTicks -> (Case Term
_ Type
_ [],[TickInfo]
_)) = do
(Identifier
_,SrcSpan
sp) <- Getting (Identifier, SrcSpan) NetlistState (Identifier, SrcSpan)
-> NetlistMonad (Identifier, SrcSpan)
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
Lens.use Getting (Identifier, SrcSpan) NetlistState (Identifier, SrcSpan)
Lens' NetlistState (Identifier, SrcSpan)
curCompNm
ClashException -> NetlistMonad [Declaration]
forall a e. Exception e => e -> a
throw (ClashException -> NetlistMonad [Declaration])
-> ClashException -> NetlistMonad [Declaration]
forall a b. (a -> b) -> a -> b
$ SrcSpan -> String -> Maybe String -> ClashException
ClashException
SrcSpan
sp
( [String] -> String
unwords [ $(String
curLoc)
, String
"Not in normal form: Case-decompositions with an"
, String
"empty list of alternatives not supported:\n\n"
, Term -> String
forall p. PrettyPrec p => p -> String
showPpr Term
e
])
Maybe String
forall a. Maybe a
Nothing
mkDeclarations' DeclarationType
declType Id
bndr (Term -> (Term, [TickInfo])
collectTicks -> (Case Term
scrut Type
altTy alts :: [Alt]
alts@(Alt
_:Alt
_:[Alt]
_),[TickInfo]
ticks)) =
[TickInfo]
-> ([Declaration] -> NetlistMonad [Declaration])
-> NetlistMonad [Declaration]
forall a.
[TickInfo] -> ([Declaration] -> NetlistMonad a) -> NetlistMonad a
withTicks [TickInfo]
ticks (([Declaration] -> NetlistMonad [Declaration])
-> NetlistMonad [Declaration])
-> ([Declaration] -> NetlistMonad [Declaration])
-> NetlistMonad [Declaration]
forall a b. (a -> b) -> a -> b
$ \[Declaration]
tickDecls -> do
DeclarationType
-> NetlistId
-> Term
-> Type
-> [Alt]
-> [Declaration]
-> NetlistMonad [Declaration]
mkSelection DeclarationType
declType (Id -> NetlistId
CoreId Id
bndr) Term
scrut Type
altTy [Alt]
alts [Declaration]
tickDecls
mkDeclarations' DeclarationType
declType Id
bndr Term
app = do
let (Term
appF,[Either Term Type]
args0,[TickInfo]
ticks) = Term -> (Term, [Either Term Type], [TickInfo])
collectArgsTicks Term
app
([Term]
args,[Type]
tyArgs) = [Either Term Type] -> ([Term], [Type])
forall a b. [Either a b] -> ([a], [b])
partitionEithers [Either Term Type]
args0
case Term
appF of
Var Id
f
| [Type] -> Bool
forall (t :: Type -> Type) a. Foldable t => t a -> Bool
null [Type]
tyArgs -> [TickInfo]
-> ([Declaration] -> NetlistMonad [Declaration])
-> NetlistMonad [Declaration]
forall a.
[TickInfo] -> ([Declaration] -> NetlistMonad a) -> NetlistMonad a
withTicks [TickInfo]
ticks (HasCallStack =>
Identifier
-> Id -> [Term] -> [Declaration] -> NetlistMonad [Declaration]
Identifier
-> Id -> [Term] -> [Declaration] -> NetlistMonad [Declaration]
mkFunApp (Id -> Identifier
id2identifier Id
bndr) Id
f [Term]
args)
| Bool
otherwise -> do
(Identifier
_,SrcSpan
sp) <- Getting (Identifier, SrcSpan) NetlistState (Identifier, SrcSpan)
-> NetlistMonad (Identifier, SrcSpan)
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
Lens.use Getting (Identifier, SrcSpan) NetlistState (Identifier, SrcSpan)
Lens' NetlistState (Identifier, SrcSpan)
curCompNm
ClashException -> NetlistMonad [Declaration]
forall a e. Exception e => e -> a
throw (SrcSpan -> String -> Maybe String -> ClashException
ClashException SrcSpan
sp ($(String
curLoc) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"Not in normal form: Var-application with Type arguments:\n\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term -> String
forall p. PrettyPrec p => p -> String
showPpr Term
app) Maybe String
forall a. Maybe a
Nothing)
Term
_ -> do
(Expr
exprApp,[Declaration]
declsApp0) <- HasCallStack =>
Bool
-> DeclarationType
-> NetlistId
-> Term
-> NetlistMonad (Expr, [Declaration])
Bool
-> DeclarationType
-> NetlistId
-> Term
-> NetlistMonad (Expr, [Declaration])
mkExpr Bool
False DeclarationType
declType (Id -> NetlistId
CoreId Id
bndr) Term
app
let dstId :: Identifier
dstId = Id -> Identifier
id2identifier Id
bndr
assn :: [Declaration]
assn =
case Expr
exprApp of
Identifier Identifier
_ Maybe Modifier
Nothing ->
[]
Expr
Noop ->
[]
Expr
_ ->
[Identifier -> Expr -> Declaration
Assignment Identifier
dstId Expr
exprApp]
[Declaration]
declsApp1 <- if [Declaration] -> Bool
forall (t :: Type -> Type) a. Foldable t => t a -> Bool
null [Declaration]
declsApp0
then [TickInfo]
-> ([Declaration] -> NetlistMonad [Declaration])
-> NetlistMonad [Declaration]
forall a.
[TickInfo] -> ([Declaration] -> NetlistMonad a) -> NetlistMonad a
withTicks [TickInfo]
ticks [Declaration] -> NetlistMonad [Declaration]
forall (m :: Type -> Type) a. Monad m => a -> m a
return
else [Declaration] -> NetlistMonad [Declaration]
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure [Declaration]
declsApp0
[Declaration] -> NetlistMonad [Declaration]
forall (m :: Type -> Type) a. Monad m => a -> m a
return ([Declaration]
declsApp1 [Declaration] -> [Declaration] -> [Declaration]
forall a. [a] -> [a] -> [a]
++ [Declaration]
assn)
mkSelection
:: DeclarationType
-> NetlistId
-> Term
-> Type
-> [Alt]
-> [Declaration]
-> NetlistMonad [Declaration]
mkSelection :: DeclarationType
-> NetlistId
-> Term
-> Type
-> [Alt]
-> [Declaration]
-> NetlistMonad [Declaration]
mkSelection DeclarationType
declType NetlistId
bndr Term
scrut Type
altTy [Alt]
alts0 [Declaration]
tickDecls = do
let dstId :: Identifier
dstId = (Identifier -> Identifier)
-> (Id -> Identifier) -> NetlistId -> Identifier
forall r.
HasCallStack =>
(Identifier -> r) -> (Id -> r) -> NetlistId -> r
netlistId1 Identifier -> Identifier
forall a. a -> a
id Id -> Identifier
id2identifier NetlistId
bndr
TyConMap
tcm <- Getting TyConMap NetlistState TyConMap -> NetlistMonad TyConMap
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
Lens.use Getting TyConMap NetlistState TyConMap
Lens' NetlistState TyConMap
tcCache
let scrutTy :: Type
scrutTy = TyConMap -> Term -> Type
termType TyConMap
tcm Term
scrut
HWType
scrutHTy <- String -> Type -> NetlistMonad HWType
unsafeCoreTypeToHWTypeM' $(String
curLoc) Type
scrutTy
Identifier
scrutId <- IdType -> Identifier -> Identifier -> NetlistMonad Identifier
extendIdentifier IdType
Extended Identifier
dstId Identifier
"_selection"
(Identifier
_,SrcSpan
sp) <- Getting (Identifier, SrcSpan) NetlistState (Identifier, SrcSpan)
-> NetlistMonad (Identifier, SrcSpan)
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
Lens.use Getting (Identifier, SrcSpan) NetlistState (Identifier, SrcSpan)
Lens' NetlistState (Identifier, SrcSpan)
curCompNm
Bool
ite <- Getting Bool NetlistState Bool -> NetlistMonad Bool
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
Lens.use Getting Bool NetlistState Bool
Lens' NetlistState Bool
backEndITE
HWType
altHTy <- String -> Type -> NetlistMonad HWType
unsafeCoreTypeToHWTypeM' $(String
curLoc) Type
altTy
case HWType -> [Alt] -> Maybe (Term, Term)
iteAlts HWType
scrutHTy [Alt]
alts0 of
Just (Term
altT,Term
altF)
| Bool
ite
, DeclarationType
Concurrent <- DeclarationType
declType
-> do
(Expr
scrutExpr,[Declaration]
scrutDecls) <- case HWType
scrutHTy of
SP {} -> (Expr -> Expr) -> (Expr, [Declaration]) -> (Expr, [Declaration])
forall (a :: Type -> Type -> Type) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first (SrcSpan -> HWType -> Pat -> Expr -> Expr
mkScrutExpr SrcSpan
sp HWType
scrutHTy (Alt -> Pat
forall a b. (a, b) -> a
fst ([Alt] -> Alt
forall a. [a] -> a
last [Alt]
alts0))) ((Expr, [Declaration]) -> (Expr, [Declaration]))
-> NetlistMonad (Expr, [Declaration])
-> NetlistMonad (Expr, [Declaration])
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$>
HasCallStack =>
Bool
-> DeclarationType
-> NetlistId
-> Term
-> NetlistMonad (Expr, [Declaration])
Bool
-> DeclarationType
-> NetlistId
-> Term
-> NetlistMonad (Expr, [Declaration])
mkExpr Bool
True DeclarationType
declType (Identifier -> Type -> NetlistId
NetlistId Identifier
scrutId Type
scrutTy) Term
scrut
HWType
_ -> HasCallStack =>
Bool
-> DeclarationType
-> NetlistId
-> Term
-> NetlistMonad (Expr, [Declaration])
Bool
-> DeclarationType
-> NetlistId
-> Term
-> NetlistMonad (Expr, [Declaration])
mkExpr Bool
False DeclarationType
declType (Identifier -> Type -> NetlistId
NetlistId Identifier
scrutId Type
scrutTy) Term
scrut
Identifier
altTId <- IdType -> Identifier -> Identifier -> NetlistMonad Identifier
extendIdentifier IdType
Extended Identifier
dstId Identifier
"_sel_alt_t"
Identifier
altFId <- IdType -> Identifier -> Identifier -> NetlistMonad Identifier
extendIdentifier IdType
Extended Identifier
dstId Identifier
"_sel_alt_f"
(Expr
altTExpr,[Declaration]
altTDecls) <- HasCallStack =>
Bool
-> DeclarationType
-> NetlistId
-> Term
-> NetlistMonad (Expr, [Declaration])
Bool
-> DeclarationType
-> NetlistId
-> Term
-> NetlistMonad (Expr, [Declaration])
mkExpr Bool
False DeclarationType
declType (Identifier -> Type -> NetlistId
NetlistId Identifier
altTId Type
altTy) Term
altT
(Expr
altFExpr,[Declaration]
altFDecls) <- HasCallStack =>
Bool
-> DeclarationType
-> NetlistId
-> Term
-> NetlistMonad (Expr, [Declaration])
Bool
-> DeclarationType
-> NetlistId
-> Term
-> NetlistMonad (Expr, [Declaration])
mkExpr Bool
False DeclarationType
declType (Identifier -> Type -> NetlistId
NetlistId Identifier
altFId Type
altTy) Term
altF
if | HWType -> Bool
isVoid HWType
altHTy Bool -> Bool -> Bool
&& HWType -> Bool
isVoid HWType
scrutHTy
-> [Declaration] -> NetlistMonad [Declaration]
forall (m :: Type -> Type) a. Monad m => a -> m a
return ([Declaration] -> NetlistMonad [Declaration])
-> [Declaration] -> NetlistMonad [Declaration]
forall a b. (a -> b) -> a -> b
$! [Declaration]
scrutDecls [Declaration] -> [Declaration] -> [Declaration]
forall a. [a] -> [a] -> [a]
++ [Declaration]
altTDecls [Declaration] -> [Declaration] -> [Declaration]
forall a. [a] -> [a] -> [a]
++ [Declaration]
altFDecls
| HWType -> Bool
isVoid HWType
altHTy
-> [Declaration] -> NetlistMonad [Declaration]
forall (m :: Type -> Type) a. Monad m => a -> m a
return ([Declaration] -> NetlistMonad [Declaration])
-> [Declaration] -> NetlistMonad [Declaration]
forall a b. (a -> b) -> a -> b
$! [Declaration]
altTDecls [Declaration] -> [Declaration] -> [Declaration]
forall a. [a] -> [a] -> [a]
++ [Declaration]
altFDecls
| Bool
otherwise
-> [Declaration] -> NetlistMonad [Declaration]
forall (m :: Type -> Type) a. Monad m => a -> m a
return ([Declaration] -> NetlistMonad [Declaration])
-> [Declaration] -> NetlistMonad [Declaration]
forall a b. (a -> b) -> a -> b
$! [Declaration]
scrutDecls [Declaration] -> [Declaration] -> [Declaration]
forall a. [a] -> [a] -> [a]
++ [Declaration]
altTDecls [Declaration] -> [Declaration] -> [Declaration]
forall a. [a] -> [a] -> [a]
++ [Declaration]
altFDecls [Declaration] -> [Declaration] -> [Declaration]
forall a. [a] -> [a] -> [a]
++ [Declaration]
tickDecls [Declaration] -> [Declaration] -> [Declaration]
forall a. [a] -> [a] -> [a]
++
[Identifier -> Expr -> Declaration
Assignment Identifier
dstId (Expr -> Expr -> Expr -> Expr
IfThenElse Expr
scrutExpr Expr
altTExpr Expr
altFExpr)]
Maybe (Term, Term)
_ -> do
CustomReprs
reprs <- Getting CustomReprs NetlistState CustomReprs
-> NetlistMonad CustomReprs
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
Lens.use Getting CustomReprs NetlistState CustomReprs
Lens' NetlistState CustomReprs
customReprs
let alts1 :: [Alt]
alts1 = ([Alt] -> [Alt]
reorderDefault ([Alt] -> [Alt]) -> ([Alt] -> [Alt]) -> [Alt] -> [Alt]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TyConMap -> CustomReprs -> Type -> [Alt] -> [Alt]
reorderCustom TyConMap
tcm CustomReprs
reprs Type
scrutTy) [Alt]
alts0
(Expr
scrutExpr,[Declaration]
scrutDecls) <- (Expr -> Expr) -> (Expr, [Declaration]) -> (Expr, [Declaration])
forall (a :: Type -> Type -> Type) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first (SrcSpan -> HWType -> Pat -> Expr -> Expr
mkScrutExpr SrcSpan
sp HWType
scrutHTy (Alt -> Pat
forall a b. (a, b) -> a
fst ([Alt] -> Alt
forall a. [a] -> a
head [Alt]
alts1))) ((Expr, [Declaration]) -> (Expr, [Declaration]))
-> NetlistMonad (Expr, [Declaration])
-> NetlistMonad (Expr, [Declaration])
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$>
HasCallStack =>
Bool
-> DeclarationType
-> NetlistId
-> Term
-> NetlistMonad (Expr, [Declaration])
Bool
-> DeclarationType
-> NetlistId
-> Term
-> NetlistMonad (Expr, [Declaration])
mkExpr Bool
True DeclarationType
declType (Identifier -> Type -> NetlistId
NetlistId Identifier
scrutId Type
scrutTy) Term
scrut
([(Maybe Literal, Expr)]
exprs,[[Declaration]]
altsDecls) <- [((Maybe Literal, Expr), [Declaration])]
-> ([(Maybe Literal, Expr)], [[Declaration]])
forall a b. [(a, b)] -> ([a], [b])
unzip ([((Maybe Literal, Expr), [Declaration])]
-> ([(Maybe Literal, Expr)], [[Declaration]]))
-> NetlistMonad [((Maybe Literal, Expr), [Declaration])]
-> NetlistMonad ([(Maybe Literal, Expr)], [[Declaration]])
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> (Alt -> NetlistMonad ((Maybe Literal, Expr), [Declaration]))
-> [Alt] -> NetlistMonad [((Maybe Literal, Expr), [Declaration])]
forall (t :: Type -> Type) (m :: Type -> Type) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (HWType
-> Alt -> NetlistMonad ((Maybe Literal, Expr), [Declaration])
mkCondExpr HWType
scrutHTy) [Alt]
alts1
case DeclarationType
declType of
DeclarationType
Sequential -> do
let ([[Declaration]]
altNets,[(Maybe Literal, [Seq])]
exprAlts) = [([Declaration], (Maybe Literal, [Seq]))]
-> ([[Declaration]], [(Maybe Literal, [Seq])])
forall a b. [(a, b)] -> ([a], [b])
unzip (((Maybe Literal, Expr)
-> [Declaration] -> ([Declaration], (Maybe Literal, [Seq])))
-> [(Maybe Literal, Expr)]
-> [[Declaration]]
-> [([Declaration], (Maybe Literal, [Seq]))]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (Identifier
-> (Maybe Literal, Expr)
-> [Declaration]
-> ([Declaration], (Maybe Literal, [Seq]))
altAssign Identifier
dstId)
[(Maybe Literal, Expr)]
exprs [[Declaration]]
altsDecls)
[Declaration] -> NetlistMonad [Declaration]
forall (m :: Type -> Type) a. Monad m => a -> m a
return ([Declaration] -> NetlistMonad [Declaration])
-> [Declaration] -> NetlistMonad [Declaration]
forall a b. (a -> b) -> a -> b
$! [Declaration]
scrutDecls [Declaration] -> [Declaration] -> [Declaration]
forall a. [a] -> [a] -> [a]
++ [Declaration]
tickDecls [Declaration] -> [Declaration] -> [Declaration]
forall a. [a] -> [a] -> [a]
++ [[Declaration]] -> [Declaration]
forall (t :: Type -> Type) a. Foldable t => t [a] -> [a]
concat [[Declaration]]
altNets [Declaration] -> [Declaration] -> [Declaration]
forall a. [a] -> [a] -> [a]
++
[[Seq] -> Declaration
Seq [Expr -> HWType -> [(Maybe Literal, [Seq])] -> Seq
Branch Expr
scrutExpr HWType
scrutHTy [(Maybe Literal, [Seq])]
exprAlts]]
DeclarationType
Concurrent ->
if | HWType -> Bool
isVoid HWType
altHTy Bool -> Bool -> Bool
&& HWType -> Bool
isVoid HWType
scrutHTy
-> [Declaration] -> NetlistMonad [Declaration]
forall (m :: Type -> Type) a. Monad m => a -> m a
return ([Declaration] -> NetlistMonad [Declaration])
-> [Declaration] -> NetlistMonad [Declaration]
forall a b. (a -> b) -> a -> b
$! [[Declaration]] -> [Declaration]
forall (t :: Type -> Type) a. Foldable t => t [a] -> [a]
concat [[Declaration]]
altsDecls [Declaration] -> [Declaration] -> [Declaration]
forall a. [a] -> [a] -> [a]
++ [Declaration]
scrutDecls
| HWType -> Bool
isVoid HWType
altHTy
-> [Declaration] -> NetlistMonad [Declaration]
forall (m :: Type -> Type) a. Monad m => a -> m a
return ([Declaration] -> NetlistMonad [Declaration])
-> [Declaration] -> NetlistMonad [Declaration]
forall a b. (a -> b) -> a -> b
$! [[Declaration]] -> [Declaration]
forall (t :: Type -> Type) a. Foldable t => t [a] -> [a]
concat [[Declaration]]
altsDecls
| Bool
otherwise
-> [Declaration] -> NetlistMonad [Declaration]
forall (m :: Type -> Type) a. Monad m => a -> m a
return ([Declaration] -> NetlistMonad [Declaration])
-> [Declaration] -> NetlistMonad [Declaration]
forall a b. (a -> b) -> a -> b
$! [Declaration]
scrutDecls [Declaration] -> [Declaration] -> [Declaration]
forall a. [a] -> [a] -> [a]
++ [[Declaration]] -> [Declaration]
forall (t :: Type -> Type) a. Foldable t => t [a] -> [a]
concat [[Declaration]]
altsDecls [Declaration] -> [Declaration] -> [Declaration]
forall a. [a] -> [a] -> [a]
++ [Declaration]
tickDecls
[Declaration] -> [Declaration] -> [Declaration]
forall a. [a] -> [a] -> [a]
++ [Identifier
-> HWType
-> Expr
-> HWType
-> [(Maybe Literal, Expr)]
-> Declaration
CondAssignment Identifier
dstId HWType
altHTy Expr
scrutExpr HWType
scrutHTy [(Maybe Literal, Expr)]
exprs]
where
mkCondExpr :: HWType -> (Pat,Term) -> NetlistMonad ((Maybe HW.Literal,Expr),[Declaration])
mkCondExpr :: HWType
-> Alt -> NetlistMonad ((Maybe Literal, Expr), [Declaration])
mkCondExpr HWType
scrutHTy (Pat
pat,Term
alt) = do
Identifier
altId <- IdType -> Identifier -> Identifier -> NetlistMonad Identifier
extendIdentifier IdType
Extended
((Identifier -> Identifier)
-> (Id -> Identifier) -> NetlistId -> Identifier
forall r.
HasCallStack =>
(Identifier -> r) -> (Id -> r) -> NetlistId -> r
netlistId1 Identifier -> Identifier
forall a. a -> a
id Id -> Identifier
id2identifier NetlistId
bndr)
Identifier
"_sel_alt"
(Expr
altExpr,[Declaration]
altDecls) <- HasCallStack =>
Bool
-> DeclarationType
-> NetlistId
-> Term
-> NetlistMonad (Expr, [Declaration])
Bool
-> DeclarationType
-> NetlistId
-> Term
-> NetlistMonad (Expr, [Declaration])
mkExpr Bool
False DeclarationType
declType (Identifier -> Type -> NetlistId
NetlistId Identifier
altId Type
altTy) Term
alt
(,[Declaration]
altDecls) ((Maybe Literal, Expr) -> ((Maybe Literal, Expr), [Declaration]))
-> NetlistMonad (Maybe Literal, Expr)
-> NetlistMonad ((Maybe Literal, Expr), [Declaration])
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> case Pat
pat of
Pat
DefaultPat -> (Maybe Literal, Expr) -> NetlistMonad (Maybe Literal, Expr)
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Maybe Literal
forall a. Maybe a
Nothing,Expr
altExpr)
DataPat DataCon
dc [TyVar]
_ [Id]
_ -> (Maybe Literal, Expr) -> NetlistMonad (Maybe Literal, Expr)
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Literal -> Maybe Literal
forall a. a -> Maybe a
Just (HWType -> Int -> Literal
dcToLiteral HWType
scrutHTy (DataCon -> Int
dcTag DataCon
dc)),Expr
altExpr)
LitPat (IntegerLiteral Integer
i) -> (Maybe Literal, Expr) -> NetlistMonad (Maybe Literal, Expr)
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Literal -> Maybe Literal
forall a. a -> Maybe a
Just (Integer -> Literal
NumLit Integer
i),Expr
altExpr)
LitPat (IntLiteral Integer
i) -> (Maybe Literal, Expr) -> NetlistMonad (Maybe Literal, Expr)
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Literal -> Maybe Literal
forall a. a -> Maybe a
Just (Integer -> Literal
NumLit Integer
i), Expr
altExpr)
LitPat (WordLiteral Integer
w) -> (Maybe Literal, Expr) -> NetlistMonad (Maybe Literal, Expr)
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Literal -> Maybe Literal
forall a. a -> Maybe a
Just (Integer -> Literal
NumLit Integer
w), Expr
altExpr)
LitPat (CharLiteral Char
c) -> (Maybe Literal, Expr) -> NetlistMonad (Maybe Literal, Expr)
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Literal -> Maybe Literal
forall a. a -> Maybe a
Just (Integer -> Literal
NumLit (Integer -> Literal) -> (Int -> Integer) -> Int -> Literal
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Integer
forall a. Integral a => a -> Integer
toInteger (Int -> Literal) -> Int -> Literal
forall a b. (a -> b) -> a -> b
$ Char -> Int
ord Char
c), Expr
altExpr)
LitPat (Int64Literal Integer
i) -> (Maybe Literal, Expr) -> NetlistMonad (Maybe Literal, Expr)
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Literal -> Maybe Literal
forall a. a -> Maybe a
Just (Integer -> Literal
NumLit Integer
i), Expr
altExpr)
LitPat (Word64Literal Integer
w) -> (Maybe Literal, Expr) -> NetlistMonad (Maybe Literal, Expr)
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Literal -> Maybe Literal
forall a. a -> Maybe a
Just (Integer -> Literal
NumLit Integer
w), Expr
altExpr)
LitPat (NaturalLiteral Integer
n) -> (Maybe Literal, Expr) -> NetlistMonad (Maybe Literal, Expr)
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Literal -> Maybe Literal
forall a. a -> Maybe a
Just (Integer -> Literal
NumLit Integer
n), Expr
altExpr)
Pat
_ -> do
(Identifier
_,SrcSpan
sp) <- Getting (Identifier, SrcSpan) NetlistState (Identifier, SrcSpan)
-> NetlistMonad (Identifier, SrcSpan)
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
Lens.use Getting (Identifier, SrcSpan) NetlistState (Identifier, SrcSpan)
Lens' NetlistState (Identifier, SrcSpan)
curCompNm
ClashException -> NetlistMonad (Maybe Literal, Expr)
forall a e. Exception e => e -> a
throw (SrcSpan -> String -> Maybe String -> ClashException
ClashException SrcSpan
sp ($(String
curLoc) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"Not an integer literal in LitPat:\n\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Pat -> String
forall p. PrettyPrec p => p -> String
showPpr Pat
pat) Maybe String
forall a. Maybe a
Nothing)
mkScrutExpr :: SrcSpan -> HWType -> Pat -> Expr -> Expr
mkScrutExpr :: SrcSpan -> HWType -> Pat -> Expr -> Expr
mkScrutExpr SrcSpan
sp HWType
scrutHTy Pat
pat Expr
scrutE = case Pat
pat of
DataPat DataCon
dc [TyVar]
_ [Id]
_ -> let modifier :: Maybe Modifier
modifier = Modifier -> Maybe Modifier
forall a. a -> Maybe a
Just ((HWType, Int) -> Modifier
DC (HWType
scrutHTy,DataCon -> Int
dcTag DataCon
dc Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1))
in case Expr
scrutE of
Identifier Identifier
scrutId Maybe Modifier
Nothing -> Identifier -> Maybe Modifier -> Expr
Identifier Identifier
scrutId Maybe Modifier
modifier
Expr
_ -> ClashException -> Expr
forall a e. Exception e => e -> a
throw (SrcSpan -> String -> Maybe String -> ClashException
ClashException SrcSpan
sp ($(String
curLoc) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"Not in normal form: Not a variable reference or primitive as subject of a case-statement:\n\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Expr -> String
forall a. Show a => a -> String
show Expr
scrutE) Maybe String
forall a. Maybe a
Nothing)
Pat
_ -> Expr
scrutE
altAssign :: Identifier -> (Maybe HW.Literal,Expr) -> [Declaration]
-> ([Declaration],(Maybe HW.Literal,[Seq]))
altAssign :: Identifier
-> (Maybe Literal, Expr)
-> [Declaration]
-> ([Declaration], (Maybe Literal, [Seq]))
altAssign Identifier
i (Maybe Literal
m,Expr
expr) [Declaration]
ds =
let ([Declaration]
nets,[Declaration]
rest) = (Declaration -> Bool)
-> [Declaration] -> ([Declaration], [Declaration])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition Declaration -> Bool
isNet [Declaration]
ds
assn :: [Seq]
assn = case Expr
expr of { Expr
Noop -> []; Expr
_ -> [Declaration -> Seq
SeqDecl (Identifier -> Expr -> Declaration
Assignment Identifier
i Expr
expr)] }
in ([Declaration]
nets,(Maybe Literal
m,(Declaration -> Seq) -> [Declaration] -> [Seq]
forall a b. (a -> b) -> [a] -> [b]
map Declaration -> Seq
SeqDecl [Declaration]
rest [Seq] -> [Seq] -> [Seq]
forall a. [a] -> [a] -> [a]
++ [Seq]
assn))
where
isNet :: Declaration -> Bool
isNet NetDecl' {} = Bool
True
isNet Declaration
_ = Bool
False
reorderDefault
:: [(Pat, Term)]
-> [(Pat, Term)]
reorderDefault :: [Alt] -> [Alt]
reorderDefault ((Pat
DefaultPat,Term
e):[Alt]
alts') = [Alt]
alts' [Alt] -> [Alt] -> [Alt]
forall a. [a] -> [a] -> [a]
++ [(Pat
DefaultPat,Term
e)]
reorderDefault [Alt]
alts' = [Alt]
alts'
reorderCustom
:: TyConMap
-> CustomReprs
-> Type
-> [(Pat, Term)]
-> [(Pat, Term)]
reorderCustom :: TyConMap -> CustomReprs -> Type -> [Alt] -> [Alt]
reorderCustom TyConMap
tcm CustomReprs
reprs (TyConMap -> Type -> Maybe Type
coreView1 TyConMap
tcm -> Just Type
ty) [Alt]
alts =
TyConMap -> CustomReprs -> Type -> [Alt] -> [Alt]
reorderCustom TyConMap
tcm CustomReprs
reprs Type
ty [Alt]
alts
reorderCustom TyConMap
_tcm CustomReprs
reprs (Type -> Either String Type'
coreToType' -> Right Type'
typeName) [Alt]
alts =
case Type' -> CustomReprs -> Maybe DataRepr'
getDataRepr Type'
typeName CustomReprs
reprs of
Just (DataRepr' Type'
_name Int
_size [ConstrRepr']
_constrReprs) ->
(Alt -> Int) -> [Alt] -> [Alt]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn (CustomReprs -> Pat -> Int
patPos CustomReprs
reprs (Pat -> Int) -> (Alt -> Pat) -> Alt -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Alt -> Pat
forall a b. (a, b) -> a
fst) [Alt]
alts
Maybe DataRepr'
Nothing ->
[Alt]
alts
reorderCustom TyConMap
_tcm CustomReprs
_reprs Type
_type [Alt]
alts =
[Alt]
alts
patPos
:: CustomReprs
-> Pat
-> Int
patPos :: CustomReprs -> Pat -> Int
patPos CustomReprs
_reprs Pat
DefaultPat = -Int
1
patPos CustomReprs
_reprs (LitPat Literal
_) = Int
0
patPos CustomReprs
reprs pat :: Pat
pat@(DataPat DataCon
dataCon [TyVar]
_ [Id]
_) =
let name :: Identifier
name = Name DataCon -> Identifier
forall a. Name a -> Identifier
nameOcc (Name DataCon -> Identifier) -> Name DataCon -> Identifier
forall a b. (a -> b) -> a -> b
$ DataCon -> Name DataCon
dcName DataCon
dataCon in
case Identifier -> CustomReprs -> Maybe ConstrRepr'
getConstrRepr Identifier
name CustomReprs
reprs of
Maybe ConstrRepr'
Nothing ->
String -> Int
forall a. HasCallStack => String -> a
error (String -> Int) -> String -> Int
forall a b. (a -> b) -> a -> b
$ $(String
curLoc) String -> String -> String
forall a. [a] -> [a] -> [a]
++ (Pat -> String
forall a. Show a => a -> String
show Pat
pat)
Just (ConstrRepr' Identifier
_name Int
n Integer
_mask Integer
_value [Integer]
_anns) ->
Int
n
mkFunApp
:: HasCallStack
=> Identifier
-> Id
-> [Term]
-> [Declaration]
-> NetlistMonad [Declaration]
mkFunApp :: Identifier
-> Id -> [Term] -> [Declaration] -> NetlistMonad [Declaration]
mkFunApp Identifier
dstId Id
fun [Term]
args [Declaration]
tickDecls = do
VarEnv TopEntityT
topAnns <- Getting (VarEnv TopEntityT) NetlistState (VarEnv TopEntityT)
-> NetlistMonad (VarEnv TopEntityT)
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
Lens.use Getting (VarEnv TopEntityT) NetlistState (VarEnv TopEntityT)
Lens' NetlistState (VarEnv TopEntityT)
topEntityAnns
TyConMap
tcm <- Getting TyConMap NetlistState TyConMap -> NetlistMonad TyConMap
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
Lens.use Getting TyConMap NetlistState TyConMap
Lens' NetlistState TyConMap
tcCache
case (Id -> Bool
forall a. Var a -> Bool
isGlobalId Id
fun, Id -> VarEnv TopEntityT -> Maybe TopEntityT
forall b a. Var b -> VarEnv a -> Maybe a
lookupVarEnv Id
fun VarEnv TopEntityT
topAnns) of
(Bool
True, Just TopEntityT
topEntity)
| let ty :: Type
ty = Id -> Type
forall a. Var a -> Type
varType (TopEntityT -> Id
topId TopEntityT
topEntity)
, let ([Either TyVar Type]
fArgTys0,Type
fResTy) = Type -> ([Either TyVar Type], Type)
splitFunForallTy Type
ty
, let fArgTys1 :: [Type]
fArgTys1 = TyConMap -> [Type] -> [Type]
splitShouldSplit TyConMap
tcm ([Type] -> [Type]) -> [Type] -> [Type]
forall a b. (a -> b) -> a -> b
$ [Either TyVar Type] -> [Type]
forall a b. [Either a b] -> [b]
rights [Either TyVar Type]
fArgTys0
, [Type] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length [Type]
fArgTys1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== [Term] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length [Term]
args
-> do
let annM :: Maybe TopEntity
annM = TopEntityT -> Maybe TopEntity
topAnnotation TopEntityT
topEntity
[HWType]
argHWTys <- (Type -> NetlistMonad HWType) -> [Type] -> NetlistMonad [HWType]
forall (t :: Type -> Type) (m :: Type -> Type) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (String -> Type -> NetlistMonad HWType
unsafeCoreTypeToHWTypeM' $(String
curLoc)) [Type]
fArgTys1
([Expr]
argExprs, [[Declaration]] -> [Declaration]
forall (t :: Type -> Type) a. Foldable t => t [a] -> [a]
concat -> [Declaration]
argDecls) <- [(Expr, [Declaration])] -> ([Expr], [[Declaration]])
forall a b. [(a, b)] -> ([a], [b])
unzip ([(Expr, [Declaration])] -> ([Expr], [[Declaration]]))
-> NetlistMonad [(Expr, [Declaration])]
-> NetlistMonad ([Expr], [[Declaration]])
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$>
((Term, Type) -> NetlistMonad (Expr, [Declaration]))
-> [(Term, Type)] -> NetlistMonad [(Expr, [Declaration])]
forall (t :: Type -> Type) (m :: Type -> Type) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (\(Term
e,Type
t) -> HasCallStack =>
Bool
-> DeclarationType
-> NetlistId
-> Term
-> NetlistMonad (Expr, [Declaration])
Bool
-> DeclarationType
-> NetlistId
-> Term
-> NetlistMonad (Expr, [Declaration])
mkExpr Bool
False DeclarationType
Concurrent (Identifier -> Type -> NetlistId
NetlistId Identifier
dstId Type
t) Term
e)
([Term] -> [Type] -> [(Term, Type)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Term]
args [Type]
fArgTys1)
let
filteredTypeExprs :: [(HWType, Expr)]
filteredTypeExprs = ((HWType, Expr) -> Bool) -> [(HWType, Expr)] -> [(HWType, Expr)]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool)
-> ((HWType, Expr) -> Bool) -> (HWType, Expr) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HWType -> Bool
isVoid (HWType -> Bool)
-> ((HWType, Expr) -> HWType) -> (HWType, Expr) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (HWType, Expr) -> HWType
forall a b. (a, b) -> a
fst) ([HWType] -> [Expr] -> [(HWType, Expr)]
forall a b. [a] -> [b] -> [(a, b)]
zip [HWType]
argHWTys [Expr]
argExprs)
([HWType]
hWTysFiltered, [Expr]
argExprsFiltered) = [(HWType, Expr)] -> ([HWType], [Expr])
forall a b. [(a, b)] -> ([a], [b])
unzip [(HWType, Expr)]
filteredTypeExprs
HWType
dstHWty <- String -> Type -> NetlistMonad HWType
unsafeCoreTypeToHWTypeM' $(String
curLoc) Type
fResTy
String
env <- Getting String NetlistState String -> NetlistMonad String
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
Lens.use Getting String NetlistState String
Lens' NetlistState String
hdlDir
IdType -> Identifier -> Identifier
mkId <- Getting
(IdType -> Identifier -> Identifier)
NetlistState
(IdType -> Identifier -> Identifier)
-> NetlistMonad (IdType -> Identifier -> Identifier)
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
Lens.use Getting
(IdType -> Identifier -> Identifier)
NetlistState
(IdType -> Identifier -> Identifier)
Lens' NetlistState (IdType -> Identifier -> Identifier)
mkIdentifierFn
ComponentPrefix
prefixM <- Getting ComponentPrefix NetlistState ComponentPrefix
-> NetlistMonad ComponentPrefix
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
Lens.use Getting ComponentPrefix NetlistState ComponentPrefix
Lens' NetlistState ComponentPrefix
componentPrefix
Bool
newInlineStrat <- ClashOpts -> Bool
opt_newInlineStrat (ClashOpts -> Bool) -> NetlistMonad ClashOpts -> NetlistMonad Bool
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Getting ClashOpts NetlistState ClashOpts -> NetlistMonad ClashOpts
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
Lens.use Getting ClashOpts NetlistState ClashOpts
Lens' NetlistState ClashOpts
clashOpts
let topName :: String
topName = Identifier -> String
StrictText.unpack
(Bool
-> (IdType -> Identifier -> Identifier)
-> ComponentPrefix
-> Maybe TopEntity
-> Id
-> Identifier
genTopComponentName Bool
newInlineStrat IdType -> Identifier -> Identifier
mkId ComponentPrefix
prefixM Maybe TopEntity
annM Id
fun)
modName :: String
modName = (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
takeWhile (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'.')
(Identifier -> String
StrictText.unpack (Name Term -> Identifier
forall a. Name a -> Identifier
nameOcc (Id -> Name Term
forall a. Var a -> Name a
varName Id
fun)))
String
manFile <- case Maybe TopEntity
annM of
Just TopEntity
_ -> String -> NetlistMonad String
forall (m :: Type -> Type) a. Monad m => a -> m a
return (String
env String -> String -> String
</> String
".." String -> String -> String
</> String
modName String -> String -> String
</> String
topName String -> String -> String
</> String
topName String -> String -> String
<.> String
"manifest")
Maybe TopEntity
Nothing -> String -> NetlistMonad String
forall (m :: Type -> Type) a. Monad m => a -> m a
return (String
env String -> String -> String
</> String
topName String -> String -> String
<.> String
"manifest")
Just Manifest
man <- String -> Maybe Manifest
forall a. Read a => String -> Maybe a
readMaybe (String -> Maybe Manifest)
-> NetlistMonad String -> NetlistMonad (Maybe Manifest)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> IO String -> NetlistMonad String
forall (m :: Type -> Type) a. MonadIO m => IO a -> m a
liftIO (String -> IO String
readFile String
manFile)
[Declaration]
instDecls <- Id
-> Maybe TopEntity
-> Manifest
-> (Identifier, HWType)
-> [(Expr, HWType)]
-> [Declaration]
-> NetlistMonad [Declaration]
mkTopUnWrapper Id
fun Maybe TopEntity
annM Manifest
man (Identifier
dstId,HWType
dstHWty)
([Expr] -> [HWType] -> [(Expr, HWType)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Expr]
argExprsFiltered [HWType]
hWTysFiltered)
[Declaration]
tickDecls
[Declaration] -> NetlistMonad [Declaration]
forall (m :: Type -> Type) a. Monad m => a -> m a
return ([Declaration]
argDecls [Declaration] -> [Declaration] -> [Declaration]
forall a. [a] -> [a] -> [a]
++ [Declaration]
instDecls)
| Bool
otherwise -> String -> NetlistMonad [Declaration]
forall a. HasCallStack => String -> a
error (String -> NetlistMonad [Declaration])
-> String -> NetlistMonad [Declaration]
forall a b. (a -> b) -> a -> b
$ $(String
curLoc) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"under-applied TopEntity: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Id -> String
forall p. PrettyPrec p => p -> String
showPpr Id
fun
(Bool
True, Maybe TopEntityT
Nothing) -> do
BindingMap
normalized <- Getting BindingMap NetlistState BindingMap
-> NetlistMonad BindingMap
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
Lens.use Getting BindingMap NetlistState BindingMap
Lens' NetlistState BindingMap
bindings
case Id -> BindingMap -> Maybe Binding
forall b a. Var b -> VarEnv a -> Maybe a
lookupVarEnv Id
fun BindingMap
normalized of
Maybe Binding
Nothing -> String -> NetlistMonad [Declaration]
forall a. HasCallStack => String -> a
error [I.i|
Internal error: unknown normalized binder:
#{showPpr fun}
|]
Just (Binding{Term
bindingTerm :: Term
bindingTerm :: Binding -> Term
bindingTerm}) -> do
([Bool]
_,SrcSpan
_,HashMap Identifier Word
_,Component Identifier
compName [(Identifier, HWType)]
compInps [(WireOrReg, (Identifier, HWType), Maybe Expr)]
co [Declaration]
_) <- NetlistMonad ([Bool], SrcSpan, HashMap Identifier Word, Component)
-> NetlistMonad
([Bool], SrcSpan, HashMap Identifier Word, Component)
forall a. NetlistMonad a -> NetlistMonad a
preserveVarEnv (NetlistMonad ([Bool], SrcSpan, HashMap Identifier Word, Component)
-> NetlistMonad
([Bool], SrcSpan, HashMap Identifier Word, Component))
-> NetlistMonad
([Bool], SrcSpan, HashMap Identifier Word, Component)
-> NetlistMonad
([Bool], SrcSpan, HashMap Identifier Word, Component)
forall a b. (a -> b) -> a -> b
$ HasCallStack =>
Id
-> NetlistMonad
([Bool], SrcSpan, HashMap Identifier Word, Component)
Id
-> NetlistMonad
([Bool], SrcSpan, HashMap Identifier Word, Component)
genComponent Id
fun
let argTys :: [Type]
argTys = (Term -> Type) -> [Term] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map (TyConMap -> Term -> Type
termType TyConMap
tcm) [Term]
args
[Maybe HWType]
argHWTys <- (Type -> NetlistMonad (Maybe HWType))
-> [Type] -> NetlistMonad [Maybe HWType]
forall (t :: Type -> Type) (m :: Type -> Type) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Type -> NetlistMonad (Maybe HWType)
coreTypeToHWTypeM' [Type]
argTys
([Expr]
argExprs, [[Declaration]] -> [Declaration]
forall (t :: Type -> Type) a. Foldable t => t [a] -> [a]
concat -> [Declaration]
argDecls) <- [(Expr, [Declaration])] -> ([Expr], [[Declaration]])
forall a b. [(a, b)] -> ([a], [b])
unzip ([(Expr, [Declaration])] -> ([Expr], [[Declaration]]))
-> NetlistMonad [(Expr, [Declaration])]
-> NetlistMonad ([Expr], [[Declaration]])
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$>
((Term, Type) -> NetlistMonad (Expr, [Declaration]))
-> [(Term, Type)] -> NetlistMonad [(Expr, [Declaration])]
forall (t :: Type -> Type) (m :: Type -> Type) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (\(Term
e,Type
t) -> HasCallStack =>
Bool
-> DeclarationType
-> NetlistId
-> Term
-> NetlistMonad (Expr, [Declaration])
Bool
-> DeclarationType
-> NetlistId
-> Term
-> NetlistMonad (Expr, [Declaration])
mkExpr Bool
False DeclarationType
Concurrent (Identifier -> Type -> NetlistId
NetlistId Identifier
dstId Type
t) Term
e)
([Term] -> [Type] -> [(Term, Type)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Term]
args [Type]
argTys)
let
argTypeExprs :: [(Maybe HWType, (Type, Expr))]
argTypeExprs = [Maybe HWType] -> [(Type, Expr)] -> [(Maybe HWType, (Type, Expr))]
forall a b. [a] -> [b] -> [(a, b)]
zip [Maybe HWType]
argHWTys ([Type] -> [Expr] -> [(Type, Expr)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Type]
argTys [Expr]
argExprs)
filteredTypeExprs :: [(Type, Expr)]
filteredTypeExprs = ((Maybe HWType, (Type, Expr)) -> (Type, Expr))
-> [(Maybe HWType, (Type, Expr))] -> [(Type, Expr)]
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap (Maybe HWType, (Type, Expr)) -> (Type, Expr)
forall a b. (a, b) -> b
snd ([(Maybe HWType, (Type, Expr))] -> [(Type, Expr)])
-> [(Maybe HWType, (Type, Expr))] -> [(Type, Expr)]
forall a b. (a -> b) -> a -> b
$ ((Maybe HWType, (Type, Expr)) -> Bool)
-> [(Maybe HWType, (Type, Expr))] -> [(Maybe HWType, (Type, Expr))]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool)
-> ((Maybe HWType, (Type, Expr)) -> Bool)
-> (Maybe HWType, (Type, Expr))
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Maybe HWType -> Bool
isVoidMaybe Bool
True (Maybe HWType -> Bool)
-> ((Maybe HWType, (Type, Expr)) -> Maybe HWType)
-> (Maybe HWType, (Type, Expr))
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe HWType, (Type, Expr)) -> Maybe HWType
forall a b. (a, b) -> a
fst) [(Maybe HWType, (Type, Expr))]
argTypeExprs
([Type]
argTysFiltered, [Expr]
argsFiltered) = [(Type, Expr)] -> ([Type], [Expr])
forall a b. [(a, b)] -> ([a], [b])
unzip [(Type, Expr)]
filteredTypeExprs
let compOutp :: Maybe (Identifier, HWType)
compOutp = (\(WireOrReg
_,(Identifier, HWType)
x,Maybe Expr
_) -> (Identifier, HWType)
x) ((WireOrReg, (Identifier, HWType), Maybe Expr)
-> (Identifier, HWType))
-> Maybe (WireOrReg, (Identifier, HWType), Maybe Expr)
-> Maybe (Identifier, HWType)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> [(WireOrReg, (Identifier, HWType), Maybe Expr)]
-> Maybe (WireOrReg, (Identifier, HWType), Maybe Expr)
forall a. [a] -> Maybe a
listToMaybe [(WireOrReg, (Identifier, HWType), Maybe Expr)]
co
if [Type] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length [Type]
argTysFiltered Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== [(Identifier, HWType)] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length [(Identifier, HWType)]
compInps
then do
([Expr]
argExprs',[Declaration]
argDecls') <- (([[Declaration]] -> [Declaration])
-> ([Expr], [[Declaration]]) -> ([Expr], [Declaration])
forall (a :: Type -> Type -> Type) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second [[Declaration]] -> [Declaration]
forall (t :: Type -> Type) a. Foldable t => t [a] -> [a]
concat (([Expr], [[Declaration]]) -> ([Expr], [Declaration]))
-> ([(Expr, [Declaration])] -> ([Expr], [[Declaration]]))
-> [(Expr, [Declaration])]
-> ([Expr], [Declaration])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(Expr, [Declaration])] -> ([Expr], [[Declaration]])
forall a b. [(a, b)] -> ([a], [b])
unzip) ([(Expr, [Declaration])] -> ([Expr], [Declaration]))
-> NetlistMonad [(Expr, [Declaration])]
-> NetlistMonad ([Expr], [Declaration])
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> ((Expr, Type) -> NetlistMonad (Expr, [Declaration]))
-> [(Expr, Type)] -> NetlistMonad [(Expr, [Declaration])]
forall (t :: Type -> Type) (m :: Type -> Type) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Identifier -> (Expr, Type) -> NetlistMonad (Expr, [Declaration])
toSimpleVar Identifier
dstId) ([Expr] -> [Type] -> [(Expr, Type)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Expr]
argsFiltered [Type]
argTysFiltered)
let inpAssigns :: [(Expr, PortDirection, HWType, Expr)]
inpAssigns = ((Identifier, HWType)
-> Expr -> (Expr, PortDirection, HWType, Expr))
-> [(Identifier, HWType)]
-> [Expr]
-> [(Expr, PortDirection, HWType, Expr)]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\(Identifier
i,HWType
t) Expr
e -> (Identifier -> Maybe Modifier -> Expr
Identifier Identifier
i Maybe Modifier
forall a. Maybe a
Nothing,PortDirection
In,HWType
t,Expr
e)) [(Identifier, HWType)]
compInps [Expr]
argExprs'
outpAssign :: [(Expr, PortDirection, HWType, Expr)]
outpAssign = case Maybe (Identifier, HWType)
compOutp of
Maybe (Identifier, HWType)
Nothing -> []
Just (Identifier
id_,HWType
hwtype) -> [(Identifier -> Maybe Modifier -> Expr
Identifier Identifier
id_ Maybe Modifier
forall a. Maybe a
Nothing,PortDirection
Out,HWType
hwtype,Identifier -> Maybe Modifier -> Expr
Identifier Identifier
dstId Maybe Modifier
forall a. Maybe a
Nothing)]
Identifier
instLabel0 <- IdType -> Identifier -> Identifier -> NetlistMonad Identifier
extendIdentifier IdType
Basic Identifier
compName (String -> Identifier
StrictText.pack String
"_" Identifier -> Identifier -> Identifier
`StrictText.append` Identifier
dstId)
Identifier
instLabel1 <- Identifier -> Maybe Identifier -> Identifier
forall a. a -> Maybe a -> a
fromMaybe Identifier
instLabel0 (Maybe Identifier -> Identifier)
-> NetlistMonad (Maybe Identifier) -> NetlistMonad Identifier
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Getting (Maybe Identifier) NetlistEnv (Maybe Identifier)
-> NetlistMonad (Maybe Identifier)
forall s (m :: Type -> Type) a.
MonadReader s m =>
Getting a s a -> m a
Lens.view Getting (Maybe Identifier) NetlistEnv (Maybe Identifier)
Lens' NetlistEnv (Maybe Identifier)
setName
Identifier
instLabel2 <- Identifier -> NetlistMonad Identifier
affixName Identifier
instLabel1
Identifier
instLabel3 <- IdType -> Identifier -> NetlistMonad Identifier
mkUniqueIdentifier IdType
Basic Identifier
instLabel2
let instDecl :: Declaration
instDecl = EntityOrComponent
-> Maybe Identifier
-> Identifier
-> Identifier
-> [(Expr, HWType, Expr)]
-> [(Expr, PortDirection, HWType, Expr)]
-> Declaration
InstDecl EntityOrComponent
Entity Maybe Identifier
forall a. Maybe a
Nothing Identifier
compName Identifier
instLabel3 [] ([(Expr, PortDirection, HWType, Expr)]
outpAssign [(Expr, PortDirection, HWType, Expr)]
-> [(Expr, PortDirection, HWType, Expr)]
-> [(Expr, PortDirection, HWType, Expr)]
forall a. [a] -> [a] -> [a]
++ [(Expr, PortDirection, HWType, Expr)]
inpAssigns)
[Declaration] -> NetlistMonad [Declaration]
forall (m :: Type -> Type) a. Monad m => a -> m a
return ([Declaration]
argDecls [Declaration] -> [Declaration] -> [Declaration]
forall a. [a] -> [a] -> [a]
++ [Declaration]
argDecls' [Declaration] -> [Declaration] -> [Declaration]
forall a. [a] -> [a] -> [a]
++ [Declaration]
tickDecls [Declaration] -> [Declaration] -> [Declaration]
forall a. [a] -> [a] -> [a]
++ [Declaration
instDecl])
else String -> NetlistMonad [Declaration]
forall a. HasCallStack => String -> a
error [I.i|
Under-applied normalized function at component #{compName}:
#{showPpr fun}
Core:
#{showPpr bindingTerm}
Applied to arguments:
#{showPpr args}
Applied to filtered arguments:
#{argsFiltered}
Component inputs:
#{compInps}
|]
(Bool, Maybe TopEntityT)
_ ->
case [Term]
args of
[] ->
[Declaration] -> NetlistMonad [Declaration]
forall (m :: Type -> Type) a. Monad m => a -> m a
return [Identifier -> Expr -> Declaration
Assignment Identifier
dstId (Identifier -> Maybe Modifier -> Expr
Identifier (Name Term -> Identifier
forall a. Name a -> Identifier
nameOcc (Name Term -> Identifier) -> Name Term -> Identifier
forall a b. (a -> b) -> a -> b
$ Id -> Name Term
forall a. Var a -> Name a
varName Id
fun) Maybe Modifier
forall a. Maybe a
Nothing)]
[Term]
_ -> String -> NetlistMonad [Declaration]
forall a. HasCallStack => String -> a
error [I.i|
Netlist generation encountered a local function. This should not
happen. Function:
#{showPpr fun}
Arguments:
#{showPpr args}
Posssible user issues:
* A top entity has an higher-order argument, e.g (Int -> Int) or
Maybe (Int -> Int)
Possible internal compiler issues:
* 'bindOrLiftNonRep' failed to fire
* 'caseCon' failed to eliminate something of a type such as
"Maybe (Int -> Int)"
|]
toSimpleVar :: Identifier
-> (Expr,Type)
-> NetlistMonad (Expr,[Declaration])
toSimpleVar :: Identifier -> (Expr, Type) -> NetlistMonad (Expr, [Declaration])
toSimpleVar Identifier
_ (e :: Expr
e@(Identifier Identifier
_ Maybe Modifier
Nothing),Type
_) = (Expr, [Declaration]) -> NetlistMonad (Expr, [Declaration])
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Expr
e,[])
toSimpleVar Identifier
dstId (Expr
e,Type
ty) = do
Identifier
argNm <- IdType -> Identifier -> Identifier -> NetlistMonad Identifier
extendIdentifier IdType
Extended
Identifier
dstId
Identifier
"_fun_arg"
Identifier
argNm' <- IdType -> Identifier -> NetlistMonad Identifier
mkUniqueIdentifier IdType
Extended Identifier
argNm
HWType
hTy <- String -> Type -> NetlistMonad HWType
unsafeCoreTypeToHWTypeM' $(String
curLoc) Type
ty
let argDecl :: Declaration
argDecl = Maybe Identifier -> Identifier -> HWType -> Declaration
NetDecl Maybe Identifier
forall a. Maybe a
Nothing Identifier
argNm' HWType
hTy
argAssn :: Declaration
argAssn = Identifier -> Expr -> Declaration
Assignment Identifier
argNm' Expr
e
(Expr, [Declaration]) -> NetlistMonad (Expr, [Declaration])
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Identifier -> Maybe Modifier -> Expr
Identifier Identifier
argNm' Maybe Modifier
forall a. Maybe a
Nothing,[Declaration
argDecl,Declaration
argAssn])
mkExpr :: HasCallStack
=> Bool
-> DeclarationType
-> NetlistId
-> Term
-> NetlistMonad (Expr,[Declaration])
mkExpr :: Bool
-> DeclarationType
-> NetlistId
-> Term
-> NetlistMonad (Expr, [Declaration])
mkExpr Bool
_ DeclarationType
_ NetlistId
_ (Term -> Term
stripTicks -> Core.Literal Literal
l) = do
Int
iw <- Getting Int NetlistState Int -> NetlistMonad Int
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
Lens.use Getting Int NetlistState Int
Lens' NetlistState Int
intWidth
case Literal
l of
IntegerLiteral Integer
i -> (Expr, [Declaration]) -> NetlistMonad (Expr, [Declaration])
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Maybe (HWType, Int) -> Literal -> Expr
HW.Literal ((HWType, Int) -> Maybe (HWType, Int)
forall a. a -> Maybe a
Just (Int -> HWType
Signed Int
iw,Int
iw)) (Literal -> Expr) -> Literal -> Expr
forall a b. (a -> b) -> a -> b
$ Integer -> Literal
NumLit Integer
i, [])
IntLiteral Integer
i -> (Expr, [Declaration]) -> NetlistMonad (Expr, [Declaration])
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Maybe (HWType, Int) -> Literal -> Expr
HW.Literal ((HWType, Int) -> Maybe (HWType, Int)
forall a. a -> Maybe a
Just (Int -> HWType
Signed Int
iw,Int
iw)) (Literal -> Expr) -> Literal -> Expr
forall a b. (a -> b) -> a -> b
$ Integer -> Literal
NumLit Integer
i, [])
WordLiteral Integer
w -> (Expr, [Declaration]) -> NetlistMonad (Expr, [Declaration])
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Maybe (HWType, Int) -> Literal -> Expr
HW.Literal ((HWType, Int) -> Maybe (HWType, Int)
forall a. a -> Maybe a
Just (Int -> HWType
Unsigned Int
iw,Int
iw)) (Literal -> Expr) -> Literal -> Expr
forall a b. (a -> b) -> a -> b
$ Integer -> Literal
NumLit Integer
w, [])
Int64Literal Integer
i -> (Expr, [Declaration]) -> NetlistMonad (Expr, [Declaration])
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Maybe (HWType, Int) -> Literal -> Expr
HW.Literal ((HWType, Int) -> Maybe (HWType, Int)
forall a. a -> Maybe a
Just (Int -> HWType
Signed Int
64,Int
64)) (Literal -> Expr) -> Literal -> Expr
forall a b. (a -> b) -> a -> b
$ Integer -> Literal
NumLit Integer
i, [])
Word64Literal Integer
w -> (Expr, [Declaration]) -> NetlistMonad (Expr, [Declaration])
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Maybe (HWType, Int) -> Literal -> Expr
HW.Literal ((HWType, Int) -> Maybe (HWType, Int)
forall a. a -> Maybe a
Just (Int -> HWType
Unsigned Int
64,Int
64)) (Literal -> Expr) -> Literal -> Expr
forall a b. (a -> b) -> a -> b
$ Integer -> Literal
NumLit Integer
w, [])
CharLiteral Char
c -> (Expr, [Declaration]) -> NetlistMonad (Expr, [Declaration])
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Maybe (HWType, Int) -> Literal -> Expr
HW.Literal ((HWType, Int) -> Maybe (HWType, Int)
forall a. a -> Maybe a
Just (Int -> HWType
Unsigned Int
21,Int
21)) (Literal -> Expr) -> (Int -> Literal) -> Int -> Expr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Literal
NumLit (Integer -> Literal) -> (Int -> Integer) -> Int -> Literal
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Integer
forall a. Integral a => a -> Integer
toInteger (Int -> Expr) -> Int -> Expr
forall a b. (a -> b) -> a -> b
$ Char -> Int
ord Char
c, [])
FloatLiteral Rational
r -> let f :: Float
f = Rational -> Float
forall a. Fractional a => Rational -> a
fromRational Rational
r :: Float
i :: Integer
i = Word32 -> Integer
forall a. Integral a => a -> Integer
toInteger (Float -> Word32
floatToWord Float
f)
in (Expr, [Declaration]) -> NetlistMonad (Expr, [Declaration])
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Maybe (HWType, Int) -> Literal -> Expr
HW.Literal ((HWType, Int) -> Maybe (HWType, Int)
forall a. a -> Maybe a
Just (Int -> HWType
BitVector Int
32,Int
32)) (Integer -> Literal
NumLit Integer
i), [])
DoubleLiteral Rational
r -> let d :: Double
d = Rational -> Double
forall a. Fractional a => Rational -> a
fromRational Rational
r :: Double
i :: Integer
i = Word64 -> Integer
forall a. Integral a => a -> Integer
toInteger (Double -> Word64
doubleToWord Double
d)
in (Expr, [Declaration]) -> NetlistMonad (Expr, [Declaration])
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Maybe (HWType, Int) -> Literal -> Expr
HW.Literal ((HWType, Int) -> Maybe (HWType, Int)
forall a. a -> Maybe a
Just (Int -> HWType
BitVector Int
64,Int
64)) (Integer -> Literal
NumLit Integer
i), [])
NaturalLiteral Integer
n -> (Expr, [Declaration]) -> NetlistMonad (Expr, [Declaration])
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Maybe (HWType, Int) -> Literal -> Expr
HW.Literal ((HWType, Int) -> Maybe (HWType, Int)
forall a. a -> Maybe a
Just (Int -> HWType
Unsigned Int
iw,Int
iw)) (Literal -> Expr) -> Literal -> Expr
forall a b. (a -> b) -> a -> b
$ Integer -> Literal
NumLit Integer
n, [])
ByteArrayLiteral (PV.Vector Int
_ Int
_ (ByteArray ByteArray#
ba)) -> (Expr, [Declaration]) -> NetlistMonad (Expr, [Declaration])
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Maybe (HWType, Int) -> Literal -> Expr
HW.Literal Maybe (HWType, Int)
forall a. Maybe a
Nothing (Integer -> Literal
NumLit (BigNat -> Integer
Jp# (ByteArray# -> BigNat
BN# ByteArray#
ba))),[])
Literal
_ -> String -> NetlistMonad (Expr, [Declaration])
forall a. HasCallStack => String -> a
error (String -> NetlistMonad (Expr, [Declaration]))
-> String -> NetlistMonad (Expr, [Declaration])
forall a b. (a -> b) -> a -> b
$ $(String
curLoc) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"not an integer or char literal"
mkExpr Bool
bbEasD DeclarationType
declType NetlistId
bndr Term
app =
let (Term
appF,[Either Term Type]
args,[TickInfo]
ticks) = Term -> (Term, [Either Term Type], [TickInfo])
collectArgsTicks Term
app
([Term]
tmArgs,[Type]
tyArgs) = [Either Term Type] -> ([Term], [Type])
forall a b. [Either a b] -> ([a], [b])
partitionEithers [Either Term Type]
args
in [TickInfo]
-> ([Declaration] -> NetlistMonad (Expr, [Declaration]))
-> NetlistMonad (Expr, [Declaration])
forall a.
[TickInfo] -> ([Declaration] -> NetlistMonad a) -> NetlistMonad a
withTicks [TickInfo]
ticks (([Declaration] -> NetlistMonad (Expr, [Declaration]))
-> NetlistMonad (Expr, [Declaration]))
-> ([Declaration] -> NetlistMonad (Expr, [Declaration]))
-> NetlistMonad (Expr, [Declaration])
forall a b. (a -> b) -> a -> b
$ \[Declaration]
tickDecls -> do
[HWType]
hwTys <- (Type -> NetlistMonad HWType) -> [Type] -> NetlistMonad [HWType]
forall (t :: Type -> Type) (m :: Type -> Type) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (String -> Type -> NetlistMonad HWType
unsafeCoreTypeToHWTypeM' $(String
curLoc)) (NetlistId -> [Type]
netlistTypes NetlistId
bndr)
(Identifier
_,SrcSpan
sp) <- Getting (Identifier, SrcSpan) NetlistState (Identifier, SrcSpan)
-> NetlistMonad (Identifier, SrcSpan)
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
Lens.use Getting (Identifier, SrcSpan) NetlistState (Identifier, SrcSpan)
Lens' NetlistState (Identifier, SrcSpan)
curCompNm
let hwTyA :: HWType
hwTyA = [HWType] -> HWType
forall a. [a] -> a
head [HWType]
hwTys
case Term
appF of
Data DataCon
dc -> HasCallStack =>
[HWType]
-> NetlistId
-> DataCon
-> [Term]
-> NetlistMonad (Expr, [Declaration])
[HWType]
-> NetlistId
-> DataCon
-> [Term]
-> NetlistMonad (Expr, [Declaration])
mkDcApplication [HWType]
hwTys NetlistId
bndr DataCon
dc [Term]
tmArgs
Prim PrimInfo
pInfo -> Bool
-> Bool
-> NetlistId
-> PrimInfo
-> [Either Term Type]
-> [Declaration]
-> NetlistMonad (Expr, [Declaration])
mkPrimitive Bool
False Bool
bbEasD NetlistId
bndr PrimInfo
pInfo [Either Term Type]
args [Declaration]
tickDecls
Var Id
f
| [Term] -> Bool
forall (t :: Type -> Type) a. Foldable t => t a -> Bool
null [Term]
tmArgs ->
if HWType -> Bool
isVoid HWType
hwTyA then
(Expr, [Declaration]) -> NetlistMonad (Expr, [Declaration])
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Expr
Noop, [])
else
(Expr, [Declaration]) -> NetlistMonad (Expr, [Declaration])
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Identifier -> Maybe Modifier -> Expr
Identifier (Name Term -> Identifier
forall a. Name a -> Identifier
nameOcc (Name Term -> Identifier) -> Name Term -> Identifier
forall a b. (a -> b) -> a -> b
$ Id -> Name Term
forall a. Var a -> Name a
varName Id
f) Maybe Modifier
forall a. Maybe a
Nothing, [])
| Bool -> Bool
not ([Type] -> Bool
forall (t :: Type -> Type) a. Foldable t => t a -> Bool
null [Type]
tyArgs) ->
ClashException -> NetlistMonad (Expr, [Declaration])
forall a e. Exception e => e -> a
throw (SrcSpan -> String -> Maybe String -> ClashException
ClashException SrcSpan
sp ($(String
curLoc) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"Not in normal form: "
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"Var-application with Type arguments:\n\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term -> String
forall p. PrettyPrec p => p -> String
showPpr Term
app) Maybe String
forall a. Maybe a
Nothing)
| Bool
otherwise -> do
Identifier
argNm0 <- IdType -> Identifier -> Identifier -> NetlistMonad Identifier
extendIdentifier IdType
Extended ((Identifier -> Identifier)
-> (Id -> Identifier) -> NetlistId -> Identifier
forall r.
HasCallStack =>
(Identifier -> r) -> (Id -> r) -> NetlistId -> r
netlistId1 Identifier -> Identifier
forall a. a -> a
id Id -> Identifier
id2identifier NetlistId
bndr)
Identifier
"_fun_arg"
Identifier
argNm1 <- IdType -> Identifier -> NetlistMonad Identifier
mkUniqueIdentifier IdType
Extended Identifier
argNm0
[Declaration]
decls <- HasCallStack =>
Identifier
-> Id -> [Term] -> [Declaration] -> NetlistMonad [Declaration]
Identifier
-> Id -> [Term] -> [Declaration] -> NetlistMonad [Declaration]
mkFunApp Identifier
argNm1 Id
f [Term]
tmArgs [Declaration]
tickDecls
if HWType -> Bool
isVoid HWType
hwTyA then
(Expr, [Declaration]) -> NetlistMonad (Expr, [Declaration])
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Expr
Noop, [Declaration]
decls)
else
(Expr, [Declaration]) -> NetlistMonad (Expr, [Declaration])
forall (m :: Type -> Type) a. Monad m => a -> m a
return ( Identifier -> Maybe Modifier -> Expr
Identifier Identifier
argNm1 Maybe Modifier
forall a. Maybe a
Nothing
, Maybe Identifier
-> WireOrReg
-> Identifier
-> Either Identifier HWType
-> Maybe Expr
-> Declaration
NetDecl' Maybe Identifier
forall a. Maybe a
Nothing WireOrReg
Wire Identifier
argNm1 (HWType -> Either Identifier HWType
forall a b. b -> Either a b
Right HWType
hwTyA) Maybe Expr
forall a. Maybe a
NothingDeclaration -> [Declaration] -> [Declaration]
forall a. a -> [a] -> [a]
:[Declaration]
decls)
Case Term
scrut Type
ty' [Alt
alt] -> Bool
-> NetlistId
-> Term
-> Type
-> Alt
-> NetlistMonad (Expr, [Declaration])
mkProjection Bool
bbEasD NetlistId
bndr Term
scrut Type
ty' Alt
alt
Case Term
scrut Type
tyA [Alt]
alts -> do
TyConMap
tcm <- Getting TyConMap NetlistState TyConMap -> NetlistMonad TyConMap
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
Lens.use Getting TyConMap NetlistState TyConMap
Lens' NetlistState TyConMap
tcCache
let scrutTy :: Type
scrutTy = TyConMap -> Term -> Type
termType TyConMap
tcm Term
scrut
HWType
scrutHTy <- String -> Type -> NetlistMonad HWType
unsafeCoreTypeToHWTypeM' $(String
curLoc) Type
scrutTy
Bool
ite <- Getting Bool NetlistState Bool -> NetlistMonad Bool
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
Lens.use Getting Bool NetlistState Bool
Lens' NetlistState Bool
backEndITE
let wr :: WireOrReg
wr = case HWType -> [Alt] -> Maybe (Term, Term)
iteAlts HWType
scrutHTy [Alt]
alts of
Just (Term, Term)
_ | Bool
ite -> WireOrReg
Wire
Maybe (Term, Term)
_ -> WireOrReg
Reg
Identifier
argNm0 <- IdType -> Identifier -> Identifier -> NetlistMonad Identifier
extendIdentifier IdType
Extended ((Identifier -> Identifier)
-> (Id -> Identifier) -> NetlistId -> Identifier
forall r.
HasCallStack =>
(Identifier -> r) -> (Id -> r) -> NetlistId -> r
netlistId1 Identifier -> Identifier
forall a. a -> a
id Id -> Identifier
id2identifier NetlistId
bndr) Identifier
"_sel_arg"
Identifier
argNm1 <- IdType -> Identifier -> NetlistMonad Identifier
mkUniqueIdentifier IdType
Extended Identifier
argNm0
[Declaration]
decls <- DeclarationType
-> NetlistId
-> Term
-> Type
-> [Alt]
-> [Declaration]
-> NetlistMonad [Declaration]
mkSelection DeclarationType
declType (Identifier -> Type -> NetlistId
NetlistId Identifier
argNm1 (HasCallStack => NetlistId -> Type
NetlistId -> Type
netlistTypes1 NetlistId
bndr))
Term
scrut Type
tyA [Alt]
alts [Declaration]
tickDecls
if HWType -> Bool
isVoid HWType
hwTyA then
(Expr, [Declaration]) -> NetlistMonad (Expr, [Declaration])
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Expr
Noop, [Declaration]
decls)
else
(Expr, [Declaration]) -> NetlistMonad (Expr, [Declaration])
forall (m :: Type -> Type) a. Monad m => a -> m a
return ( Identifier -> Maybe Modifier -> Expr
Identifier Identifier
argNm1 Maybe Modifier
forall a. Maybe a
Nothing
, Maybe Identifier
-> WireOrReg
-> Identifier
-> Either Identifier HWType
-> Maybe Expr
-> Declaration
NetDecl' Maybe Identifier
forall a. Maybe a
Nothing WireOrReg
wr Identifier
argNm1 (HWType -> Either Identifier HWType
forall a b. b -> Either a b
Right HWType
hwTyA) Maybe Expr
forall a. Maybe a
NothingDeclaration -> [Declaration] -> [Declaration]
forall a. a -> [a] -> [a]
:[Declaration]
decls)
Letrec [LetBinding]
binders Term
body -> do
[Declaration]
netDecls <- ([Maybe Declaration] -> [Declaration])
-> NetlistMonad [Maybe Declaration] -> NetlistMonad [Declaration]
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap [Maybe Declaration] -> [Declaration]
forall a. [Maybe a] -> [a]
catMaybes (NetlistMonad [Maybe Declaration] -> NetlistMonad [Declaration])
-> NetlistMonad [Maybe Declaration] -> NetlistMonad [Declaration]
forall a b. (a -> b) -> a -> b
$ (LetBinding -> NetlistMonad (Maybe Declaration))
-> [LetBinding] -> NetlistMonad [Maybe Declaration]
forall (t :: Type -> Type) (m :: Type -> Type) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM LetBinding -> NetlistMonad (Maybe Declaration)
mkNetDecl [LetBinding]
binders
[Declaration]
decls <- [[Declaration]] -> [Declaration]
forall (t :: Type -> Type) a. Foldable t => t [a] -> [a]
concat ([[Declaration]] -> [Declaration])
-> NetlistMonad [[Declaration]] -> NetlistMonad [Declaration]
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> (LetBinding -> NetlistMonad [Declaration])
-> [LetBinding] -> NetlistMonad [[Declaration]]
forall (t :: Type -> Type) (m :: Type -> Type) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM ((Id -> Term -> NetlistMonad [Declaration])
-> LetBinding -> NetlistMonad [Declaration]
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry HasCallStack => Id -> Term -> NetlistMonad [Declaration]
Id -> Term -> NetlistMonad [Declaration]
mkDeclarations) [LetBinding]
binders
(Expr
bodyE,[Declaration]
bodyDecls) <- HasCallStack =>
Bool
-> DeclarationType
-> NetlistId
-> Term
-> NetlistMonad (Expr, [Declaration])
Bool
-> DeclarationType
-> NetlistId
-> Term
-> NetlistMonad (Expr, [Declaration])
mkExpr Bool
bbEasD DeclarationType
declType NetlistId
bndr (Term -> [Either Term Type] -> Term
mkApps (Term -> [TickInfo] -> Term
mkTicks Term
body [TickInfo]
ticks) [Either Term Type]
args)
(Expr, [Declaration]) -> NetlistMonad (Expr, [Declaration])
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Expr
bodyE,[Declaration]
netDecls [Declaration] -> [Declaration] -> [Declaration]
forall a. [a] -> [a] -> [a]
++ [Declaration]
decls [Declaration] -> [Declaration] -> [Declaration]
forall a. [a] -> [a] -> [a]
++ [Declaration]
bodyDecls)
Term
_ -> ClashException -> NetlistMonad (Expr, [Declaration])
forall a e. Exception e => e -> a
throw (SrcSpan -> String -> Maybe String -> ClashException
ClashException SrcSpan
sp ($(String
curLoc) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"Not in normal form: application of a Lambda-expression\n\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term -> String
forall p. PrettyPrec p => p -> String
showPpr Term
app) Maybe String
forall a. Maybe a
Nothing)
mkProjection
:: Bool
-> NetlistId
-> Term
-> Type
-> Alt
-> NetlistMonad (Expr, [Declaration])
mkProjection :: Bool
-> NetlistId
-> Term
-> Type
-> Alt
-> NetlistMonad (Expr, [Declaration])
mkProjection Bool
mkDec NetlistId
bndr Term
scrut Type
altTy alt :: Alt
alt@(Pat
pat,Term
v) = do
TyConMap
tcm <- Getting TyConMap NetlistState TyConMap -> NetlistMonad TyConMap
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
Lens.use Getting TyConMap NetlistState TyConMap
Lens' NetlistState TyConMap
tcCache
let scrutTy :: Type
scrutTy = TyConMap -> Term -> Type
termType TyConMap
tcm Term
scrut
e :: Term
e = Term -> Type -> [Alt] -> Term
Case Term
scrut Type
scrutTy [Alt
alt]
(Identifier
_,SrcSpan
sp) <- Getting (Identifier, SrcSpan) NetlistState (Identifier, SrcSpan)
-> NetlistMonad (Identifier, SrcSpan)
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
Lens.use Getting (Identifier, SrcSpan) NetlistState (Identifier, SrcSpan)
Lens' NetlistState (Identifier, SrcSpan)
curCompNm
Id
varTm <- case Term
v of
(Var Id
n) -> Id -> NetlistMonad Id
forall (m :: Type -> Type) a. Monad m => a -> m a
return Id
n
Term
_ -> ClashException -> NetlistMonad Id
forall a e. Exception e => e -> a
throw (SrcSpan -> String -> Maybe String -> ClashException
ClashException SrcSpan
sp ($(String
curLoc) String -> String -> String
forall a. [a] -> [a] -> [a]
++
String
"Not in normal form: RHS of case-projection is not a variable:\n\n"
String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term -> String
forall p. PrettyPrec p => p -> String
showPpr Term
e) Maybe String
forall a. Maybe a
Nothing)
HWType
sHwTy <- String -> Type -> NetlistMonad HWType
unsafeCoreTypeToHWTypeM' $(String
curLoc) Type
scrutTy
HWType
vHwTy <- String -> Type -> NetlistMonad HWType
unsafeCoreTypeToHWTypeM' $(String
curLoc) Type
altTy
Either [Declaration] (Identifier, Maybe Modifier, [Declaration])
scrutRendered <- do
Identifier
scrutNm <-
(Identifier -> NetlistMonad Identifier)
-> (Id -> NetlistMonad Identifier)
-> NetlistId
-> NetlistMonad Identifier
forall r.
HasCallStack =>
(Identifier -> r) -> (Id -> r) -> NetlistId -> r
netlistId1
Identifier -> NetlistMonad Identifier
forall (m :: Type -> Type) a. Monad m => a -> m a
return
(\Id
b -> IdType -> Identifier -> Identifier -> NetlistMonad Identifier
extendIdentifier IdType
Extended (Id -> Identifier
id2identifier Id
b) Identifier
"_projection")
NetlistId
bndr
(Expr
scrutExpr,[Declaration]
newDecls) <- HasCallStack =>
Bool
-> DeclarationType
-> NetlistId
-> Term
-> NetlistMonad (Expr, [Declaration])
Bool
-> DeclarationType
-> NetlistId
-> Term
-> NetlistMonad (Expr, [Declaration])
mkExpr Bool
False DeclarationType
Concurrent (Identifier -> Type -> NetlistId
NetlistId Identifier
scrutNm Type
scrutTy) Term
scrut
case Expr
scrutExpr of
Identifier Identifier
newId Maybe Modifier
modM ->
Either [Declaration] (Identifier, Maybe Modifier, [Declaration])
-> NetlistMonad
(Either [Declaration] (Identifier, Maybe Modifier, [Declaration]))
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure ((Identifier, Maybe Modifier, [Declaration])
-> Either [Declaration] (Identifier, Maybe Modifier, [Declaration])
forall a b. b -> Either a b
Right (Identifier
newId, Maybe Modifier
modM, [Declaration]
newDecls))
Expr
Noop ->
Either [Declaration] (Identifier, Maybe Modifier, [Declaration])
-> NetlistMonad
(Either [Declaration] (Identifier, Maybe Modifier, [Declaration]))
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure ([Declaration]
-> Either [Declaration] (Identifier, Maybe Modifier, [Declaration])
forall a b. a -> Either a b
Left [Declaration]
newDecls)
Expr
_ -> do
Identifier
scrutNm' <- IdType -> Identifier -> NetlistMonad Identifier
mkUniqueIdentifier IdType
Extended Identifier
scrutNm
let scrutDecl :: Declaration
scrutDecl = Maybe Identifier -> Identifier -> HWType -> Declaration
NetDecl Maybe Identifier
forall a. Maybe a
Nothing Identifier
scrutNm' HWType
sHwTy
scrutAssn :: Declaration
scrutAssn = Identifier -> Expr -> Declaration
Assignment Identifier
scrutNm' Expr
scrutExpr
Either [Declaration] (Identifier, Maybe Modifier, [Declaration])
-> NetlistMonad
(Either [Declaration] (Identifier, Maybe Modifier, [Declaration]))
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure ((Identifier, Maybe Modifier, [Declaration])
-> Either [Declaration] (Identifier, Maybe Modifier, [Declaration])
forall a b. b -> Either a b
Right (Identifier
scrutNm', Maybe Modifier
forall a. Maybe a
Nothing, [Declaration]
newDecls [Declaration] -> [Declaration] -> [Declaration]
forall a. [a] -> [a] -> [a]
++ [Declaration
scrutDecl, Declaration
scrutAssn]))
case Either [Declaration] (Identifier, Maybe Modifier, [Declaration])
scrutRendered of
Left [Declaration]
newDecls -> (Expr, [Declaration]) -> NetlistMonad (Expr, [Declaration])
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Expr
Noop, [Declaration]
newDecls)
Right (Identifier
selId, Maybe Modifier
modM, [Declaration]
decls) -> do
let altVarId :: Identifier
altVarId = Name Term -> Identifier
forall a. Name a -> Identifier
nameOcc (Id -> Name Term
forall a. Var a -> Name a
varName Id
varTm)
Maybe Modifier
modifier <- case Pat
pat of
DataPat DataCon
dc [TyVar]
exts [Id]
tms -> do
let
tms' :: [Id]
tms' =
if [TyVar] -> [Id] -> Bool
forall a. [TyVar] -> [Var a] -> Bool
bindsExistentials [TyVar]
exts [Id]
tms then
ClashException -> [Id]
forall a e. Exception e => e -> a
throw (SrcSpan -> String -> Maybe String -> ClashException
ClashException SrcSpan
sp ($(String
curLoc)
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"Not in normal form: Pattern binds existential variables:\n\n"
String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term -> String
forall p. PrettyPrec p => p -> String
showPpr Term
e) Maybe String
forall a. Maybe a
Nothing)
else
[Id]
tms
[Maybe HWType]
argHWTys <- (Type -> NetlistMonad (Maybe HWType))
-> [Type] -> NetlistMonad [Maybe HWType]
forall (t :: Type -> Type) (m :: Type -> Type) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Type -> NetlistMonad (Maybe HWType)
coreTypeToHWTypeM' ((Id -> Type) -> [Id] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map Id -> Type
forall a. Var a -> Type
varType [Id]
tms)
let tmsBundled :: [(Maybe HWType, Id)]
tmsBundled = [Maybe HWType] -> [Id] -> [(Maybe HWType, Id)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Maybe HWType]
argHWTys [Id]
tms'
tmsFiltered :: [(Maybe HWType, Id)]
tmsFiltered = ((Maybe HWType, Id) -> Bool)
-> [(Maybe HWType, Id)] -> [(Maybe HWType, Id)]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> (HWType -> Bool) -> Maybe HWType -> Bool
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Bool
False (Bool -> Bool
not (Bool -> Bool) -> (HWType -> Bool) -> HWType -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HWType -> Bool
isVoid) (Maybe HWType -> Bool)
-> ((Maybe HWType, Id) -> Maybe HWType)
-> (Maybe HWType, Id)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe HWType, Id) -> Maybe HWType
forall a b. (a, b) -> a
fst) [(Maybe HWType, Id)]
tmsBundled
tmsFiltered' :: [Id]
tmsFiltered' = ((Maybe HWType, Id) -> Id) -> [(Maybe HWType, Id)] -> [Id]
forall a b. (a -> b) -> [a] -> [b]
map (Maybe HWType, Id) -> Id
forall a b. (a, b) -> b
snd [(Maybe HWType, Id)]
tmsFiltered
case Id -> [Id] -> Maybe Int
forall a. Eq a => a -> [a] -> Maybe Int
elemIndex Id
varTm {varType :: Type
varType = Type
altTy} [Id]
tmsFiltered' of
Maybe Int
Nothing -> Maybe Modifier -> NetlistMonad (Maybe Modifier)
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure Maybe Modifier
forall a. Maybe a
Nothing
Just Int
fI
| HWType
sHwTy HWType -> HWType -> Bool
forall a. Eq a => a -> a -> Bool
/= HWType
vHwTy ->
Maybe Modifier -> NetlistMonad (Maybe Modifier)
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Maybe Modifier -> NetlistMonad (Maybe Modifier))
-> Maybe Modifier -> NetlistMonad (Maybe Modifier)
forall a b. (a -> b) -> a -> b
$ Maybe Modifier -> Maybe Modifier -> Maybe Modifier
nestModifier Maybe Modifier
modM (Modifier -> Maybe Modifier
forall a. a -> Maybe a
Just ((HWType, Int, Int) -> Modifier
Indexed (HWType
sHwTy,DataCon -> Int
dcTag DataCon
dc Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1,Int
fI)))
| Bool
otherwise ->
Maybe Modifier -> NetlistMonad (Maybe Modifier)
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Maybe Modifier -> NetlistMonad (Maybe Modifier))
-> Maybe Modifier -> NetlistMonad (Maybe Modifier)
forall a b. (a -> b) -> a -> b
$ Maybe Modifier -> Maybe Modifier -> Maybe Modifier
nestModifier Maybe Modifier
modM (Modifier -> Maybe Modifier
forall a. a -> Maybe a
Just ((HWType, Int) -> Modifier
DC (Maybe HWType -> HWType
Void Maybe HWType
forall a. Maybe a
Nothing,Int
0)))
Pat
_ -> ClashException -> NetlistMonad (Maybe Modifier)
forall a e. Exception e => e -> a
throw (SrcSpan -> String -> Maybe String -> ClashException
ClashException SrcSpan
sp ($(String
curLoc)
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"Not in normal form: Unexpected pattern in case-projection:\n\n"
String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term -> String
forall p. PrettyPrec p => p -> String
showPpr Term
e) Maybe String
forall a. Maybe a
Nothing)
let extractExpr :: Expr
extractExpr = Identifier -> Maybe Modifier -> Expr
Identifier (Identifier
-> (Modifier -> Identifier) -> Maybe Modifier -> Identifier
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Identifier
altVarId (Identifier -> Modifier -> Identifier
forall a b. a -> b -> a
const Identifier
selId) Maybe Modifier
modifier) Maybe Modifier
modifier
case NetlistId
bndr of
NetlistId Identifier
scrutNm Type
_ | Bool
mkDec -> do
Identifier
scrutNm' <- IdType -> Identifier -> NetlistMonad Identifier
mkUniqueIdentifier IdType
Extended Identifier
scrutNm
let scrutDecl :: Declaration
scrutDecl = Maybe Identifier -> Identifier -> HWType -> Declaration
NetDecl Maybe Identifier
forall a. Maybe a
Nothing Identifier
scrutNm' HWType
vHwTy
scrutAssn :: Declaration
scrutAssn = Identifier -> Expr -> Declaration
Assignment Identifier
scrutNm' Expr
extractExpr
(Expr, [Declaration]) -> NetlistMonad (Expr, [Declaration])
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Identifier -> Maybe Modifier -> Expr
Identifier Identifier
scrutNm' Maybe Modifier
forall a. Maybe a
Nothing,Declaration
scrutDeclDeclaration -> [Declaration] -> [Declaration]
forall a. a -> [a] -> [a]
:Declaration
scrutAssnDeclaration -> [Declaration] -> [Declaration]
forall a. a -> [a] -> [a]
:[Declaration]
decls)
MultiId {} -> String -> NetlistMonad (Expr, [Declaration])
forall a. HasCallStack => String -> a
error String
"mkProjection: MultiId"
NetlistId
_ -> (Expr, [Declaration]) -> NetlistMonad (Expr, [Declaration])
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Expr
extractExpr,[Declaration]
decls)
where
nestModifier :: Maybe Modifier -> Maybe Modifier -> Maybe Modifier
nestModifier Maybe Modifier
Nothing Maybe Modifier
m = Maybe Modifier
m
nestModifier Maybe Modifier
m Maybe Modifier
Nothing = Maybe Modifier
m
nestModifier (Just Modifier
m1) (Just Modifier
m2) = Modifier -> Maybe Modifier
forall a. a -> Maybe a
Just (Modifier -> Modifier -> Modifier
Nested Modifier
m1 Modifier
m2)
mkDcApplication
:: HasCallStack
=> [HWType]
-> NetlistId
-> DataCon
-> [Term]
-> NetlistMonad (Expr,[Declaration])
mkDcApplication :: [HWType]
-> NetlistId
-> DataCon
-> [Term]
-> NetlistMonad (Expr, [Declaration])
mkDcApplication [HWType
dstHType] NetlistId
bndr DataCon
dc [Term]
args = do
let dcNm :: Identifier
dcNm = Name DataCon -> Identifier
forall a. Name a -> Identifier
nameOcc (DataCon -> Name DataCon
dcName DataCon
dc)
TyConMap
tcm <- Getting TyConMap NetlistState TyConMap -> NetlistMonad TyConMap
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
Lens.use Getting TyConMap NetlistState TyConMap
Lens' NetlistState TyConMap
tcCache
let argTys :: [Type]
argTys = (Term -> Type) -> [Term] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map (TyConMap -> Term -> Type
termType TyConMap
tcm) [Term]
args
Identifier
argNm <- (Identifier -> NetlistMonad Identifier)
-> (Id -> NetlistMonad Identifier)
-> NetlistId
-> NetlistMonad Identifier
forall r.
HasCallStack =>
(Identifier -> r) -> (Id -> r) -> NetlistId -> r
netlistId1 Identifier -> NetlistMonad Identifier
forall (m :: Type -> Type) a. Monad m => a -> m a
return (\Id
b -> IdType -> Identifier -> Identifier -> NetlistMonad Identifier
extendIdentifier IdType
Extended (Name Term -> Identifier
forall a. Name a -> Identifier
nameOcc (Id -> Name Term
forall a. Var a -> Name a
varName Id
b)) Identifier
"_dc_arg") NetlistId
bndr
[Maybe HWType]
argHWTys <- (Type -> NetlistMonad (Maybe HWType))
-> [Type] -> NetlistMonad [Maybe HWType]
forall (t :: Type -> Type) (m :: Type -> Type) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Type -> NetlistMonad (Maybe HWType)
coreTypeToHWTypeM' [Type]
argTys
([Expr]
argExprs, [[Declaration]] -> [Declaration]
forall (t :: Type -> Type) a. Foldable t => t [a] -> [a]
concat -> [Declaration]
argDecls) <- [(Expr, [Declaration])] -> ([Expr], [[Declaration]])
forall a b. [(a, b)] -> ([a], [b])
unzip ([(Expr, [Declaration])] -> ([Expr], [[Declaration]]))
-> NetlistMonad [(Expr, [Declaration])]
-> NetlistMonad ([Expr], [[Declaration]])
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$>
((Term, Type) -> NetlistMonad (Expr, [Declaration]))
-> [(Term, Type)] -> NetlistMonad [(Expr, [Declaration])]
forall (t :: Type -> Type) (m :: Type -> Type) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (\(Term
e,Type
t) -> HasCallStack =>
Bool
-> DeclarationType
-> NetlistId
-> Term
-> NetlistMonad (Expr, [Declaration])
Bool
-> DeclarationType
-> NetlistId
-> Term
-> NetlistMonad (Expr, [Declaration])
mkExpr Bool
False DeclarationType
Concurrent (Identifier -> Type -> NetlistId
NetlistId Identifier
argNm Type
t) Term
e) ([Term] -> [Type] -> [(Term, Type)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Term]
args [Type]
argTys)
let
filteredTypeExprDecls :: [(Maybe HWType, Expr)]
filteredTypeExprDecls =
((Maybe HWType, Expr) -> Bool)
-> [(Maybe HWType, Expr)] -> [(Maybe HWType, Expr)]
forall a. (a -> Bool) -> [a] -> [a]
filter
(Bool -> Bool
not (Bool -> Bool)
-> ((Maybe HWType, Expr) -> Bool) -> (Maybe HWType, Expr) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Maybe HWType -> Bool
isVoidMaybe Bool
True (Maybe HWType -> Bool)
-> ((Maybe HWType, Expr) -> Maybe HWType)
-> (Maybe HWType, Expr)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe HWType, Expr) -> Maybe HWType
forall a b. (a, b) -> a
fst)
([Maybe HWType] -> [Expr] -> [(Maybe HWType, Expr)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Maybe HWType]
argHWTys [Expr]
argExprs)
([Maybe HWType]
hWTysFiltered, [Expr]
argExprsFiltered) = [(Maybe HWType, Expr)] -> ([Maybe HWType], [Expr])
forall a b. [(a, b)] -> ([a], [b])
unzip [(Maybe HWType, Expr)]
filteredTypeExprDecls
(Expr -> (Expr, [Declaration]))
-> NetlistMonad Expr -> NetlistMonad (Expr, [Declaration])
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap (,[Declaration]
argDecls) (NetlistMonad Expr -> NetlistMonad (Expr, [Declaration]))
-> NetlistMonad Expr -> NetlistMonad (Expr, [Declaration])
forall a b. (a -> b) -> a -> b
$! case ([Maybe HWType]
hWTysFiltered,[Expr]
argExprsFiltered) of
([Just HWType
argHwTy],[Expr
argExpr]) | HWType
argHwTy HWType -> HWType -> Bool
forall a. Eq a => a -> a -> Bool
== HWType
dstHType ->
Expr -> NetlistMonad Expr
forall (m :: Type -> Type) a. Monad m => a -> m a
return (HWType -> Modifier -> [Expr] -> Expr
HW.DataCon HWType
dstHType ((HWType, Int) -> Modifier
DC (Maybe HWType -> HWType
Void Maybe HWType
forall a. Maybe a
Nothing,-Int
1)) [Expr
argExpr])
([Maybe HWType], [Expr])
_ -> case HWType
dstHType of
SP Identifier
_ [(Identifier, [HWType])]
dcArgPairs -> do
let dcI :: Int
dcI = DataCon -> Int
dcTag DataCon
dc Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
dcArgs :: [HWType]
dcArgs = (Identifier, [HWType]) -> [HWType]
forall a b. (a, b) -> b
snd ((Identifier, [HWType]) -> [HWType])
-> (Identifier, [HWType]) -> [HWType]
forall a b. (a -> b) -> a -> b
$ String -> [(Identifier, [HWType])] -> Int -> (Identifier, [HWType])
forall a. HasCallStack => String -> [a] -> Int -> a
indexNote ($(String
curLoc) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"No DC with tag: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
dcI) [(Identifier, [HWType])]
dcArgPairs Int
dcI
case Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare ([HWType] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length [HWType]
dcArgs) ([Expr] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length [Expr]
argExprsFiltered) of
Ordering
EQ -> Expr -> NetlistMonad Expr
forall (m :: Type -> Type) a. Monad m => a -> m a
return (HWType -> Modifier -> [Expr] -> Expr
HW.DataCon HWType
dstHType ((HWType, Int) -> Modifier
DC (HWType
dstHType,Int
dcI)) [Expr]
argExprsFiltered)
Ordering
LT -> String -> NetlistMonad Expr
forall a. HasCallStack => String -> a
error (String -> NetlistMonad Expr) -> String -> NetlistMonad Expr
forall a b. (a -> b) -> a -> b
$ $(String
curLoc) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"Over-applied constructor"
Ordering
GT -> String -> NetlistMonad Expr
forall a. HasCallStack => String -> a
error (String -> NetlistMonad Expr) -> String -> NetlistMonad Expr
forall a b. (a -> b) -> a -> b
$ $(String
curLoc) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"Under-applied constructor"
Product Identifier
_ Maybe [Identifier]
_ [HWType]
dcArgs ->
case Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare ([HWType] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length [HWType]
dcArgs) ([Expr] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length [Expr]
argExprsFiltered) of
Ordering
EQ -> Expr -> NetlistMonad Expr
forall (m :: Type -> Type) a. Monad m => a -> m a
return (HWType -> Modifier -> [Expr] -> Expr
HW.DataCon HWType
dstHType ((HWType, Int) -> Modifier
DC (HWType
dstHType,Int
0)) [Expr]
argExprsFiltered)
Ordering
LT -> String -> NetlistMonad Expr
forall a. HasCallStack => String -> a
error (String -> NetlistMonad Expr) -> String -> NetlistMonad Expr
forall a b. (a -> b) -> a -> b
$ $(String
curLoc) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"Over-applied constructor"
Ordering
GT -> String -> NetlistMonad Expr
forall a. HasCallStack => String -> a
error (String -> NetlistMonad Expr) -> String -> NetlistMonad Expr
forall a b. (a -> b) -> a -> b
$ $(String
curLoc) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"Under-applied constructor"
CustomProduct Identifier
_ DataRepr'
_ Int
_ Maybe [Identifier]
_ [(Integer, HWType)]
dcArgs ->
case Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare ([(Integer, HWType)] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length [(Integer, HWType)]
dcArgs) ([Expr] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length [Expr]
argExprsFiltered) of
Ordering
EQ -> Expr -> NetlistMonad Expr
forall (m :: Type -> Type) a. Monad m => a -> m a
return (HWType -> Modifier -> [Expr] -> Expr
HW.DataCon HWType
dstHType ((HWType, Int) -> Modifier
DC (HWType
dstHType,Int
0)) [Expr]
argExprsFiltered)
Ordering
LT -> String -> NetlistMonad Expr
forall a. HasCallStack => String -> a
error (String -> NetlistMonad Expr) -> String -> NetlistMonad Expr
forall a b. (a -> b) -> a -> b
$ $(String
curLoc) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"Over-applied constructor"
Ordering
GT -> String -> NetlistMonad Expr
forall a. HasCallStack => String -> a
error (String -> NetlistMonad Expr) -> String -> NetlistMonad Expr
forall a b. (a -> b) -> a -> b
$ $(String
curLoc) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"Under-applied constructor"
Sum Identifier
_ [Identifier]
_ ->
Expr -> NetlistMonad Expr
forall (m :: Type -> Type) a. Monad m => a -> m a
return (HWType -> Modifier -> [Expr] -> Expr
HW.DataCon HWType
dstHType ((HWType, Int) -> Modifier
DC (HWType
dstHType,DataCon -> Int
dcTag DataCon
dc Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)) [])
CustomSP Identifier
_ DataRepr'
_ Int
_ [(ConstrRepr', Identifier, [HWType])]
dcArgsTups -> do
let dcI :: Int
dcI = DataCon -> Int
dcTag DataCon
dc Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
let note :: String
note = $(String
curLoc) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"No DC with tag: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
dcI
let argTup :: (ConstrRepr', Identifier, [HWType])
argTup = String
-> [(ConstrRepr', Identifier, [HWType])]
-> Int
-> (ConstrRepr', Identifier, [HWType])
forall a. HasCallStack => String -> [a] -> Int -> a
indexNote String
note [(ConstrRepr', Identifier, [HWType])]
dcArgsTups Int
dcI
let (ConstrRepr'
_, Identifier
_, [HWType]
dcArgs) = (ConstrRepr', Identifier, [HWType])
argTup
case Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare ([HWType] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length [HWType]
dcArgs) ([Expr] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length [Expr]
argExprsFiltered) of
Ordering
EQ -> Expr -> NetlistMonad Expr
forall (m :: Type -> Type) a. Monad m => a -> m a
return (HWType -> Modifier -> [Expr] -> Expr
HW.DataCon HWType
dstHType ((HWType, Int) -> Modifier
DC (HWType
dstHType, Int
dcI)) [Expr]
argExprsFiltered)
Ordering
LT -> String -> NetlistMonad Expr
forall a. HasCallStack => String -> a
error (String -> NetlistMonad Expr) -> String -> NetlistMonad Expr
forall a b. (a -> b) -> a -> b
$ $(String
curLoc) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"Over-applied constructor"
Ordering
GT -> String -> NetlistMonad Expr
forall a. HasCallStack => String -> a
error (String -> NetlistMonad Expr) -> String -> NetlistMonad Expr
forall a b. (a -> b) -> a -> b
$ $(String
curLoc) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"Under-applied constructor"
CustomSum Identifier
_ DataRepr'
_ Int
_ [(ConstrRepr', Identifier)]
_ ->
Expr -> NetlistMonad Expr
forall (m :: Type -> Type) a. Monad m => a -> m a
return (HWType -> Modifier -> [Expr] -> Expr
HW.DataCon HWType
dstHType ((HWType, Int) -> Modifier
DC (HWType
dstHType, DataCon -> Int
dcTag DataCon
dc Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)) [])
HWType
Bool ->
let dc' :: Expr
dc' = case DataCon -> Int
dcTag DataCon
dc of
Int
1 -> Maybe (HWType, Int) -> Literal -> Expr
HW.Literal Maybe (HWType, Int)
forall a. Maybe a
Nothing (Bool -> Literal
BoolLit Bool
False)
Int
2 -> Maybe (HWType, Int) -> Literal -> Expr
HW.Literal Maybe (HWType, Int)
forall a. Maybe a
Nothing (Bool -> Literal
BoolLit Bool
True)
Int
tg -> String -> Expr
forall a. HasCallStack => String -> a
error (String -> Expr) -> String -> Expr
forall a b. (a -> b) -> a -> b
$ $(String
curLoc) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"unknown bool literal: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ DataCon -> String
forall p. PrettyPrec p => p -> String
showPpr DataCon
dc String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"(tag: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
tg String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
in Expr -> NetlistMonad Expr
forall (m :: Type -> Type) a. Monad m => a -> m a
return Expr
dc'
Vector Int
0 HWType
_ -> Expr -> NetlistMonad Expr
forall (m :: Type -> Type) a. Monad m => a -> m a
return (HWType -> Modifier -> [Expr] -> Expr
HW.DataCon HWType
dstHType Modifier
VecAppend [])
Vector Int
1 HWType
_ -> case [Expr]
argExprsFiltered of
[Expr
e] -> Expr -> NetlistMonad Expr
forall (m :: Type -> Type) a. Monad m => a -> m a
return (HWType -> Modifier -> [Expr] -> Expr
HW.DataCon HWType
dstHType Modifier
VecAppend [Expr
e])
[Expr]
_ -> String -> NetlistMonad Expr
forall a. HasCallStack => String -> a
error (String -> NetlistMonad Expr) -> String -> NetlistMonad Expr
forall a b. (a -> b) -> a -> b
$ $(String
curLoc) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"Unexpected number of arguments for `Cons`: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [Term] -> String
forall p. PrettyPrec p => p -> String
showPpr [Term]
args
Vector Int
_ HWType
_ -> case [Expr]
argExprsFiltered of
[Expr
e1,Expr
e2] -> Expr -> NetlistMonad Expr
forall (m :: Type -> Type) a. Monad m => a -> m a
return (HWType -> Modifier -> [Expr] -> Expr
HW.DataCon HWType
dstHType Modifier
VecAppend [Expr
e1,Expr
e2])
[Expr]
_ -> String -> NetlistMonad Expr
forall a. HasCallStack => String -> a
error (String -> NetlistMonad Expr) -> String -> NetlistMonad Expr
forall a b. (a -> b) -> a -> b
$ $(String
curLoc) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"Unexpected number of arguments for `Cons`: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [Term] -> String
forall p. PrettyPrec p => p -> String
showPpr [Term]
args
RTree Int
0 HWType
_ -> case [Expr]
argExprsFiltered of
[Expr
e] -> Expr -> NetlistMonad Expr
forall (m :: Type -> Type) a. Monad m => a -> m a
return (HWType -> Modifier -> [Expr] -> Expr
HW.DataCon HWType
dstHType Modifier
RTreeAppend [Expr
e])
[Expr]
_ -> String -> NetlistMonad Expr
forall a. HasCallStack => String -> a
error (String -> NetlistMonad Expr) -> String -> NetlistMonad Expr
forall a b. (a -> b) -> a -> b
$ $(String
curLoc) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"Unexpected number of arguments for `LR`: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [Term] -> String
forall p. PrettyPrec p => p -> String
showPpr [Term]
args
RTree Int
_ HWType
_ -> case [Expr]
argExprsFiltered of
[Expr
e1,Expr
e2] -> Expr -> NetlistMonad Expr
forall (m :: Type -> Type) a. Monad m => a -> m a
return (HWType -> Modifier -> [Expr] -> Expr
HW.DataCon HWType
dstHType Modifier
RTreeAppend [Expr
e1,Expr
e2])
[Expr]
_ -> String -> NetlistMonad Expr
forall a. HasCallStack => String -> a
error (String -> NetlistMonad Expr) -> String -> NetlistMonad Expr
forall a b. (a -> b) -> a -> b
$ $(String
curLoc) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"Unexpected number of arguments for `BR`: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [Term] -> String
forall p. PrettyPrec p => p -> String
showPpr [Term]
args
HWType
String ->
let dc' :: Expr
dc' = case DataCon -> Int
dcTag DataCon
dc of
Int
1 -> Maybe (HWType, Int) -> Literal -> Expr
HW.Literal Maybe (HWType, Int)
forall a. Maybe a
Nothing (String -> Literal
StringLit String
"")
Int
_ -> String -> Expr
forall a. HasCallStack => String -> a
error (String -> Expr) -> String -> Expr
forall a b. (a -> b) -> a -> b
$ $(String
curLoc) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"mkDcApplication undefined for: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ (HWType, DataCon, Int, [Term], [Maybe HWType]) -> String
forall a. Show a => a -> String
show (HWType
dstHType,DataCon
dc,DataCon -> Int
dcTag DataCon
dc,[Term]
args,[Maybe HWType]
argHWTys)
in Expr -> NetlistMonad Expr
forall (m :: Type -> Type) a. Monad m => a -> m a
return Expr
dc'
Void {} -> Expr -> NetlistMonad Expr
forall (m :: Type -> Type) a. Monad m => a -> m a
return Expr
Noop
Signed Int
_
| Identifier
dcNm Identifier -> Identifier -> Bool
forall a. Eq a => a -> a -> Bool
== Identifier
"GHC.Integer.Type.S#"
-> Expr -> NetlistMonad Expr
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure ([Expr] -> Expr
forall a. [a] -> a
head [Expr]
argExprsFiltered)
| Identifier
dcNm Identifier -> Identifier -> Bool
forall a. Eq a => a -> a -> Bool
== Identifier
"GHC.Integer.Type.Jp#"
, HW.Literal Maybe (HWType, Int)
Nothing (NumLit Integer
_) <- [Expr] -> Expr
forall a. [a] -> a
head [Expr]
argExprs
-> Expr -> NetlistMonad Expr
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure ([Expr] -> Expr
forall a. [a] -> a
head [Expr]
argExprs)
| Identifier
dcNm Identifier -> Identifier -> Bool
forall a. Eq a => a -> a -> Bool
== Identifier
"GHC.Integer.Type.Jn#"
, HW.Literal Maybe (HWType, Int)
Nothing (NumLit Integer
i) <- [Expr] -> Expr
forall a. [a] -> a
head [Expr]
argExprs
-> Expr -> NetlistMonad Expr
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Maybe (HWType, Int) -> Literal -> Expr
HW.Literal Maybe (HWType, Int)
forall a. Maybe a
Nothing (Integer -> Literal
NumLit (Integer -> Integer
forall a. Num a => a -> a
negate Integer
i)))
Unsigned Int
_
| Identifier
dcNm Identifier -> Identifier -> Bool
forall a. Eq a => a -> a -> Bool
== Identifier
"GHC.Natural.NatS#"
-> Expr -> NetlistMonad Expr
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure ([Expr] -> Expr
forall a. [a] -> a
head [Expr]
argExprsFiltered)
| Identifier
dcNm Identifier -> Identifier -> Bool
forall a. Eq a => a -> a -> Bool
== Identifier
"GHC.Natural.NatJ#"
, HW.Literal Maybe (HWType, Int)
Nothing (NumLit Integer
_) <- [Expr] -> Expr
forall a. [a] -> a
head [Expr]
argExprs
-> Expr -> NetlistMonad Expr
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure ([Expr] -> Expr
forall a. [a] -> a
head [Expr]
argExprs)
HWType
_ ->
String -> NetlistMonad Expr
forall a. HasCallStack => String -> a
error (String -> NetlistMonad Expr) -> String -> NetlistMonad Expr
forall a b. (a -> b) -> a -> b
$ $(String
curLoc) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"mkDcApplication undefined for: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ (HWType, DataCon, [Term], [Maybe HWType]) -> String
forall a. Show a => a -> String
show (HWType
dstHType,DataCon
dc,[Term]
args,[Maybe HWType]
argHWTys)
mkDcApplication [HWType]
dstHTypes (MultiId [Id]
argNms) DataCon
_ [Term]
args = do
TyConMap
tcm <- Getting TyConMap NetlistState TyConMap -> NetlistMonad TyConMap
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
Lens.use Getting TyConMap NetlistState TyConMap
Lens' NetlistState TyConMap
tcCache
let argTys :: [Type]
argTys = (Term -> Type) -> [Term] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map (TyConMap -> Term -> Type
termType TyConMap
tcm) [Term]
args
[Maybe HWType]
argHWTys <- (Type -> NetlistMonad (Maybe HWType))
-> [Type] -> NetlistMonad [Maybe HWType]
forall (t :: Type -> Type) (m :: Type -> Type) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Type -> NetlistMonad (Maybe HWType)
coreTypeToHWTypeM' [Type]
argTys
let argsBundled :: [(Maybe HWType, (NetlistId, Term))]
argsBundled = [Maybe HWType]
-> [(NetlistId, Term)] -> [(Maybe HWType, (NetlistId, Term))]
forall a b. [a] -> [b] -> [(a, b)]
zip [Maybe HWType]
argHWTys ([NetlistId] -> [Term] -> [(NetlistId, Term)]
forall a b. HasCallStack => [a] -> [b] -> [(a, b)]
zipEqual ((Id -> NetlistId) -> [Id] -> [NetlistId]
forall a b. (a -> b) -> [a] -> [b]
map Id -> NetlistId
CoreId [Id]
argNms) [Term]
args)
([Maybe HWType]
_hWTysFiltered,[(NetlistId, Term)]
argsFiltered) = [(Maybe HWType, (NetlistId, Term))]
-> ([Maybe HWType], [(NetlistId, Term)])
forall a b. [(a, b)] -> ([a], [b])
unzip
(((Maybe HWType, (NetlistId, Term)) -> Bool)
-> [(Maybe HWType, (NetlistId, Term))]
-> [(Maybe HWType, (NetlistId, Term))]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> (HWType -> Bool) -> Maybe HWType -> Bool
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Bool
True (Bool -> Bool
not (Bool -> Bool) -> (HWType -> Bool) -> HWType -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HWType -> Bool
isVoid) (Maybe HWType -> Bool)
-> ((Maybe HWType, (NetlistId, Term)) -> Maybe HWType)
-> (Maybe HWType, (NetlistId, Term))
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe HWType, (NetlistId, Term)) -> Maybe HWType
forall a b. (a, b) -> a
fst) [(Maybe HWType, (NetlistId, Term))]
argsBundled)
([Expr]
argExprs,[Declaration]
argDecls) <- ([(Expr, [Declaration])] -> ([Expr], [Declaration]))
-> NetlistMonad [(Expr, [Declaration])]
-> NetlistMonad ([Expr], [Declaration])
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap (([[Declaration]] -> [Declaration])
-> ([Expr], [[Declaration]]) -> ([Expr], [Declaration])
forall (a :: Type -> Type -> Type) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second [[Declaration]] -> [Declaration]
forall (t :: Type -> Type) a. Foldable t => t [a] -> [a]
concat (([Expr], [[Declaration]]) -> ([Expr], [Declaration]))
-> ([(Expr, [Declaration])] -> ([Expr], [[Declaration]]))
-> [(Expr, [Declaration])]
-> ([Expr], [Declaration])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(Expr, [Declaration])] -> ([Expr], [[Declaration]])
forall a b. [(a, b)] -> ([a], [b])
unzip) (NetlistMonad [(Expr, [Declaration])]
-> NetlistMonad ([Expr], [Declaration]))
-> NetlistMonad [(Expr, [Declaration])]
-> NetlistMonad ([Expr], [Declaration])
forall a b. (a -> b) -> a -> b
$!
((NetlistId, Term) -> NetlistMonad (Expr, [Declaration]))
-> [(NetlistId, Term)] -> NetlistMonad [(Expr, [Declaration])]
forall (t :: Type -> Type) (m :: Type -> Type) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM ((NetlistId -> Term -> NetlistMonad (Expr, [Declaration]))
-> (NetlistId, Term) -> NetlistMonad (Expr, [Declaration])
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (HasCallStack =>
Bool
-> DeclarationType
-> NetlistId
-> Term
-> NetlistMonad (Expr, [Declaration])
Bool
-> DeclarationType
-> NetlistId
-> Term
-> NetlistMonad (Expr, [Declaration])
mkExpr Bool
False DeclarationType
Concurrent)) [(NetlistId, Term)]
argsFiltered
if [HWType] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length [HWType]
dstHTypes Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== [Expr] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length [Expr]
argExprs then do
let assns :: [Declaration]
assns = ((NetlistId, Expr) -> Maybe Declaration)
-> [(NetlistId, Expr)] -> [Declaration]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe
(\case (NetlistId
_,Expr
Noop) -> Maybe Declaration
forall a. Maybe a
Nothing
(NetlistId
dstId,Expr
e) -> let nm :: Identifier
nm = (Identifier -> Identifier)
-> (Id -> Identifier) -> NetlistId -> Identifier
forall r.
HasCallStack =>
(Identifier -> r) -> (Id -> r) -> NetlistId -> r
netlistId1 Identifier -> Identifier
forall a. a -> a
id Id -> Identifier
id2identifier NetlistId
dstId
in case Expr
e of
Identifier Identifier
nm0 Maybe Modifier
Nothing
| Identifier
nm Identifier -> Identifier -> Bool
forall a. Eq a => a -> a -> Bool
== Identifier
nm0 -> Maybe Declaration
forall a. Maybe a
Nothing
Expr
_ -> Declaration -> Maybe Declaration
forall a. a -> Maybe a
Just (Identifier -> Expr -> Declaration
Assignment Identifier
nm Expr
e))
([NetlistId] -> [Expr] -> [(NetlistId, Expr)]
forall a b. HasCallStack => [a] -> [b] -> [(a, b)]
zipEqual ((Id -> NetlistId) -> [Id] -> [NetlistId]
forall a b. (a -> b) -> [a] -> [b]
map Id -> NetlistId
CoreId [Id]
argNms) [Expr]
argExprs)
(Expr, [Declaration]) -> NetlistMonad (Expr, [Declaration])
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Expr
Noop,[Declaration]
argDecls [Declaration] -> [Declaration] -> [Declaration]
forall a. [a] -> [a] -> [a]
++ [Declaration]
assns)
else
String -> NetlistMonad (Expr, [Declaration])
forall a. HasCallStack => String -> a
error String
"internal error"
mkDcApplication [HWType]
_ NetlistId
_ DataCon
_ [Term]
_ = String -> NetlistMonad (Expr, [Declaration])
forall a. HasCallStack => String -> a
error String
"internal error"