{-# LANGUAGE CPP #-}
{-# 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 (zipWithM)
import Control.Monad.Extra (concatMapM, mapMaybeM)
import Control.Monad.Reader (runReaderT)
import Control.Monad.State.Strict (State, runStateT, runState)
import Data.Bifunctor (first, second)
import Data.Char (ord)
import Data.Either (partitionEithers, rights)
import Data.Foldable (foldlM)
import Data.List (elemIndex, partition)
import Data.List.Extra (zipEqual)
import Data.List.NonEmpty (NonEmpty (..))
import qualified Data.List.NonEmpty.Extra as NE
import Data.Maybe
(listToMaybe, fromMaybe)
import qualified Data.Map.Ordered as OMap
import qualified Data.Set as Set
import qualified Data.Text as StrictText
import GHC.Stack (HasCallStack)
#if MIN_VERSION_ghc(9,0,0)
import GHC.Utils.Outputable (ppr, showSDocUnsafe)
import GHC.Types.SrcLoc (isGoodSrcSpan)
#else
import Outputable (ppr, showSDocUnsafe)
import SrcLoc (isGoodSrcSpan)
#endif
import Clash.Annotations.Primitive (HDL)
import Clash.Annotations.BitRepresentation.ClashLib
(coreToType')
import Clash.Annotations.BitRepresentation.Internal
(CustomReprs, DataRepr'(..), ConstrRepr'(..), getDataRepr, getConstrRepr)
import Clash.Core.DataCon (DataCon (..))
import Clash.Core.HasType
import Clash.Core.Literal (Literal (..))
import Clash.Core.Name (Name(..))
import Clash.Core.Pretty (showPpr)
import Clash.Core.Term
(IsMultiPrim (..), PrimInfo (..), mpi_resultTypes, Alt, Pat (..), Term (..),
TickInfo (..), collectArgs, collectArgsTicks,
collectTicks, mkApps, mkTicks, stripTicks)
import qualified Clash.Core.Term as Core
import Clash.Core.TermInfo (multiPrimInfo', splitMultiPrimArgs)
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')
import Clash.Driver.Types (BindingMap, Binding(..), ClashEnv(..), ClashOpts (..))
import Clash.Netlist.BlackBox
import qualified Clash.Netlist.Id as 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
:: ClashEnv
-> Bool
-> BindingMap
-> VarEnv TopEntityT
-> VarEnv Identifier
-> (CustomReprs -> TyConMap -> Type ->
State HWMap (Maybe (Either String FilteredHWType)))
-> Bool
-> SomeBackend
-> IdentifierSet
-> FilePath
-> Maybe StrictText.Text
-> Id
-> IO (Component, ComponentMap, IdentifierSet)
genNetlist :: ClashEnv
-> Bool
-> BindingMap
-> VarEnv TopEntityT
-> VarEnv Identifier
-> (CustomReprs
-> TyConMap
-> Type
-> State HWMap (Maybe (Either [Char] FilteredHWType)))
-> Bool
-> SomeBackend
-> IdentifierSet
-> [Char]
-> Maybe Text
-> Id
-> IO (Component, ComponentMap, IdentifierSet)
genNetlist ClashEnv
env Bool
isTb BindingMap
globals VarEnv TopEntityT
tops VarEnv Identifier
topNames CustomReprs
-> TyConMap
-> Type
-> State HWMap (Maybe (Either [Char] FilteredHWType))
typeTrans Bool
ite SomeBackend
be IdentifierSet
seen0 [Char]
dir Maybe Text
prefixM Id
topEntity = do
((_meta, topComponent), s) <-
ClashEnv
-> Bool
-> BindingMap
-> VarEnv TopEntityT
-> (CustomReprs
-> TyConMap
-> Type
-> State HWMap (Maybe (Either [Char] FilteredHWType)))
-> Bool
-> SomeBackend
-> IdentifierSet
-> [Char]
-> VarEnv Identifier
-> NetlistMonad (ComponentMeta, Component)
-> IO ((ComponentMeta, Component), NetlistState)
forall a.
ClashEnv
-> Bool
-> BindingMap
-> VarEnv TopEntityT
-> (CustomReprs
-> TyConMap
-> Type
-> State HWMap (Maybe (Either [Char] FilteredHWType)))
-> Bool
-> SomeBackend
-> IdentifierSet
-> [Char]
-> VarEnv Identifier
-> NetlistMonad a
-> IO (a, NetlistState)
runNetlistMonad ClashEnv
env Bool
isTb BindingMap
globals VarEnv TopEntityT
tops CustomReprs
-> TyConMap
-> Type
-> State HWMap (Maybe (Either [Char] FilteredHWType))
typeTrans Bool
ite SomeBackend
be IdentifierSet
seen1 [Char]
dir VarEnv Identifier
componentNames_
(NetlistMonad (ComponentMeta, Component)
-> IO ((ComponentMeta, Component), NetlistState))
-> NetlistMonad (ComponentMeta, Component)
-> IO ((ComponentMeta, Component), NetlistState)
forall a b. (a -> b) -> a -> b
$ HasCallStack => Id -> NetlistMonad (ComponentMeta, Component)
Id -> NetlistMonad (ComponentMeta, Component)
genComponent Id
topEntity
return (topComponent, _components s, seen1)
where
(VarEnv Identifier
componentNames_, IdentifierSet
seen1) =
Bool
-> Maybe Text
-> IdentifierSet
-> VarEnv Identifier
-> BindingMap
-> (VarEnv Identifier, IdentifierSet)
genNames (ClashOpts -> Bool
opt_newInlineStrat (ClashEnv -> ClashOpts
envOpts ClashEnv
env)) Maybe Text
prefixM IdentifierSet
seen0 VarEnv Identifier
topNames BindingMap
globals
runNetlistMonad
:: ClashEnv
-> Bool
-> BindingMap
-> VarEnv TopEntityT
-> (CustomReprs -> TyConMap -> Type ->
State HWMap (Maybe (Either String FilteredHWType)))
-> Bool
-> SomeBackend
-> IdentifierSet
-> FilePath
-> VarEnv Identifier
-> NetlistMonad a
-> IO (a, NetlistState)
runNetlistMonad :: forall a.
ClashEnv
-> Bool
-> BindingMap
-> VarEnv TopEntityT
-> (CustomReprs
-> TyConMap
-> Type
-> State HWMap (Maybe (Either [Char] FilteredHWType)))
-> Bool
-> SomeBackend
-> IdentifierSet
-> [Char]
-> VarEnv Identifier
-> NetlistMonad a
-> IO (a, NetlistState)
runNetlistMonad ClashEnv
env Bool
isTb BindingMap
s VarEnv TopEntityT
tops CustomReprs
-> TyConMap
-> Type
-> State HWMap (Maybe (Either [Char] FilteredHWType))
typeTrans Bool
ite SomeBackend
be IdentifierSet
seenIds_ [Char]
dir VarEnv Identifier
componentNames_
= (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 (ClashEnv -> Text -> Text -> Maybe Text -> NetlistEnv
NetlistEnv ClashEnv
env Text
"" Text
"" Maybe Text
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' =
NetlistState
{ _bindings :: BindingMap
_bindings=BindingMap
s
, _components :: ComponentMap
_components=ComponentMap
forall k v. OMap k v
OMap.empty
, _typeTranslator :: CustomReprs
-> TyConMap
-> Type
-> State HWMap (Maybe (Either [Char] FilteredHWType))
_typeTranslator=CustomReprs
-> TyConMap
-> Type
-> State HWMap (Maybe (Either [Char] FilteredHWType))
typeTrans
, _curCompNm :: (Identifier, SrcSpan)
_curCompNm=([Char] -> Identifier
forall a. HasCallStack => [Char] -> a
error [Char]
"genComponent should have set _curCompNm", SrcSpan
noSrcSpan)
, _seenIds :: IdentifierSet
_seenIds=IdentifierSet
seenIds_
, _seenComps :: IdentifierSet
_seenComps=IdentifierSet
seenIds_
, _seenPrimitives :: Set Text
_seenPrimitives=Set Text
forall a. Set a
Set.empty
, _componentNames :: VarEnv Identifier
_componentNames=VarEnv Identifier
componentNames_
, _topEntityAnns :: VarEnv TopEntityT
_topEntityAnns=VarEnv TopEntityT
tops
, _hdlDir :: [Char]
_hdlDir=[Char]
dir
, _curBBlvl :: Int
_curBBlvl=Int
0
, _isTestBench :: Bool
_isTestBench=Bool
isTb
, _backEndITE :: Bool
_backEndITE=Bool
ite
, _backend :: SomeBackend
_backend=SomeBackend
be
, _htyCache :: HWMap
_htyCache=HWMap
forall a. Monoid a => a
mempty
, _usages :: UsageMap
_usages=UsageMap
forall a. Monoid a => a
mempty
}
genNames
:: Bool
-> Maybe StrictText.Text
-> IdentifierSet
-> VarEnv Identifier
-> BindingMap
-> (VarEnv Identifier, IdentifierSet)
genNames :: Bool
-> Maybe Text
-> IdentifierSet
-> VarEnv Identifier
-> BindingMap
-> (VarEnv Identifier, IdentifierSet)
genNames Bool
newInlineStrat Maybe Text
prefixM IdentifierSet
is VarEnv Identifier
env BindingMap
bndrs =
State IdentifierSet (VarEnv Identifier)
-> IdentifierSet -> (VarEnv Identifier, IdentifierSet)
forall s a. State s a -> s -> (a, s)
runState ((VarEnv Identifier
-> Binding Term -> State IdentifierSet (VarEnv Identifier))
-> VarEnv Identifier
-> BindingMap
-> State IdentifierSet (VarEnv Identifier)
forall (t :: Type -> Type) (m :: Type -> Type) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldlM VarEnv Identifier
-> Binding Term -> State IdentifierSet (VarEnv Identifier)
forall {f :: Type -> Type} {a}.
IdentifierSetMonad f =>
VarEnv Identifier -> Binding a -> f (VarEnv Identifier)
go VarEnv Identifier
env BindingMap
bndrs) IdentifierSet
is
where
go :: VarEnv Identifier -> Binding a -> f (VarEnv Identifier)
go VarEnv Identifier
env_ (Binding a -> Id
forall a. Binding a -> Id
bindingId -> Id
id_) =
case Id -> VarEnv Identifier -> Maybe Identifier
forall b a. Var b -> VarEnv a -> Maybe a
lookupVarEnv Id
id_ VarEnv Identifier
env_ of
Just Identifier
_ -> VarEnv Identifier -> f (VarEnv Identifier)
forall a. a -> f a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure VarEnv Identifier
env_
Maybe Identifier
Nothing -> do
nm <- Text -> f Identifier
forall (m :: Type -> Type).
(HasCallStack, IdentifierSetMonad m) =>
Text -> m Identifier
Id.makeBasic (Bool -> Maybe Text -> Id -> Text
genComponentName Bool
newInlineStrat Maybe Text
prefixM Id
id_)
pure (extendVarEnv id_ nm env_)
genTopNames
:: ClashOpts
-> HDL
-> [TopEntityT]
-> (VarEnv Identifier, IdentifierSet)
genTopNames :: ClashOpts
-> HDL -> [TopEntityT] -> (VarEnv Identifier, IdentifierSet)
genTopNames ClashOpts
opts HDL
hdl [TopEntityT]
tops =
(State IdentifierSet (VarEnv Identifier)
-> IdentifierSet -> (VarEnv Identifier, IdentifierSet))
-> IdentifierSet
-> State IdentifierSet (VarEnv Identifier)
-> (VarEnv Identifier, IdentifierSet)
forall a b c. (a -> b -> c) -> b -> a -> c
flip State IdentifierSet (VarEnv Identifier)
-> IdentifierSet -> (VarEnv Identifier, IdentifierSet)
forall s a. State s a -> s -> (a, s)
runState (Bool -> PreserveCase -> HDL -> IdentifierSet
Id.emptyIdentifierSet Bool
esc PreserveCase
lw HDL
hdl) (State IdentifierSet (VarEnv Identifier)
-> (VarEnv Identifier, IdentifierSet))
-> State IdentifierSet (VarEnv Identifier)
-> (VarEnv Identifier, IdentifierSet)
forall a b. (a -> b) -> a -> b
$ do
env0 <- (VarEnv Identifier
-> (Id, TopEntity) -> State IdentifierSet (VarEnv Identifier))
-> VarEnv Identifier
-> [(Id, TopEntity)]
-> State IdentifierSet (VarEnv Identifier)
forall (t :: Type -> Type) (m :: Type -> Type) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldlM VarEnv Identifier
-> (Id, TopEntity) -> State IdentifierSet (VarEnv Identifier)
forall {m :: Type -> Type} {b}.
IdentifierSetMonad m =>
VarEnv Identifier -> (Var b, TopEntity) -> m (VarEnv Identifier)
goFixed VarEnv Identifier
forall a. VarEnv a
emptyVarEnv [(Id, TopEntity)]
fixedTops
env1 <- foldlM goNonFixed env0 nonFixedTops
pure env1
where
prefixM :: Maybe Text
prefixM = ClashOpts -> Maybe Text
opt_componentPrefix ClashOpts
opts
esc :: Bool
esc = ClashOpts -> Bool
opt_escapedIds ClashOpts
opts
lw :: PreserveCase
lw = ClashOpts -> PreserveCase
opt_lowerCaseBasicIds ClashOpts
opts
fixedTops :: [(Id, TopEntity)]
fixedTops = [(Id
topId, TopEntity
ann) | TopEntityT{Id
topId :: Id
topId :: TopEntityT -> Id
topId, topAnnotation :: TopEntityT -> Maybe TopEntity
topAnnotation=Just TopEntity
ann} <- [TopEntityT]
tops]
nonFixedTops :: [Id]
nonFixedTops = [Id
topId | TopEntityT{Id
topId :: TopEntityT -> Id
topId :: Id
topId, topAnnotation :: TopEntityT -> Maybe TopEntity
topAnnotation=Maybe TopEntity
Nothing} <- [TopEntityT]
tops]
goFixed :: VarEnv Identifier -> (Var b, TopEntity) -> m (VarEnv Identifier)
goFixed VarEnv Identifier
env (Var b
topId, TopEntity
ann) = do
topNm <- Maybe Text -> TopEntity -> m Identifier
forall (m :: Type -> Type).
IdentifierSetMonad m =>
Maybe Text -> TopEntity -> m Identifier
genTopName Maybe Text
prefixM TopEntity
ann
pure (extendVarEnv topId topNm env)
goNonFixed :: VarEnv Identifier -> Id -> m (VarEnv Identifier)
goNonFixed VarEnv Identifier
env Id
id_ = do
topNm <- Text -> m Identifier
forall (m :: Type -> Type).
(HasCallStack, IdentifierSetMonad m) =>
Text -> m Identifier
Id.makeBasic (Bool -> Maybe Text -> Id -> Text
genComponentName Bool
True Maybe Text
prefixM Id
id_)
pure (extendVarEnv id_ topNm env)
genComponent
:: HasCallStack
=> Id
-> NetlistMonad (ComponentMeta, Component)
genComponent :: HasCallStack => Id -> NetlistMonad (ComponentMeta, Component)
genComponent Id
compName = do
compExprM <- Id -> BindingMap -> Maybe (Binding Term)
forall b a. Var b -> VarEnv a -> Maybe a
lookupVarEnv Id
compName (BindingMap -> Maybe (Binding Term))
-> NetlistMonad BindingMap -> NetlistMonad (Maybe (Binding Term))
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 compExprM of
Maybe (Binding Term)
Nothing -> do
(_,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
throw (ClashException sp ($(curLoc) ++ "No normalized expression found for: " ++ show compName) Nothing)
Just Binding Term
b -> do
Id
-> Lens' NetlistState ComponentMap
-> NetlistMonad (ComponentMeta, Component)
-> NetlistMonad (ComponentMeta, Component)
forall s (m :: Type -> Type) k v.
(MonadState s m, Uniquable k) =>
k -> Lens' s (OMap Unique v) -> m v -> m v
makeCachedO Id
compName (ComponentMap -> f ComponentMap) -> NetlistState -> f NetlistState
Lens' NetlistState ComponentMap
components (NetlistMonad (ComponentMeta, Component)
-> NetlistMonad (ComponentMeta, Component))
-> NetlistMonad (ComponentMeta, Component)
-> NetlistMonad (ComponentMeta, Component)
forall a b. (a -> b) -> a -> b
$ HasCallStack =>
Id -> Term -> NetlistMonad (ComponentMeta, Component)
Id -> Term -> NetlistMonad (ComponentMeta, Component)
genComponentT Id
compName (Binding Term -> Term
forall a. Binding a -> a
bindingTerm Binding Term
b)
genComponentT
:: HasCallStack
=> Id
-> Term
-> NetlistMonad (ComponentMeta, Component)
genComponentT :: HasCallStack =>
Id -> Term -> NetlistMonad (ComponentMeta, Component)
genComponentT Id
compName0 Term
componentExpr = do
tcm <- Getting TyConMap NetlistEnv TyConMap -> NetlistMonad TyConMap
forall s (m :: Type -> Type) a.
MonadReader s m =>
Getting a s a -> m a
Lens.view Getting TyConMap NetlistEnv TyConMap
Getter NetlistEnv TyConMap
tcCache
compName1 <- (`lookupVarEnv'` compName0) <$> Lens.use componentNames
sp <- (bindingLoc . (`lookupVarEnv'` compName0)) <$> Lens.use bindings
curCompNm .= (compName1, sp)
usages .= mempty
topEntityTM <- lookupVarEnv compName0 <$> Lens.use topEntityAnns
let topAnnMM = TopEntityT -> Maybe TopEntity
topAnnotation (TopEntityT -> Maybe TopEntity)
-> Maybe TopEntityT -> Maybe (Maybe TopEntity)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe TopEntityT
topEntityTM
topVarTypeM = ([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. HasType a => a -> Type
coreTypeOf (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
topEntityTM
seenIds <~ Lens.use seenComps
(wereVoids,compInps,argWrappers,compOutps,resUnwrappers,binders,resultM) <-
case splitNormalized tcm componentExpr of
Right ([Id]
args, [LetBinding]
binds, Id
res) -> do
let varType1 :: Type
varType1 = Type -> Maybe Type -> Type
forall a. a -> Maybe a -> a
fromMaybe (Id -> Type
forall a. HasType a => a -> Type
coreTypeOf Id
res) Maybe Type
topVarTypeM
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)
topAnnMM
(([Id]
args, [LetBinding]
binds, Id
res{varType=varType1}))
Left [Char]
err ->
ClashException
-> NetlistMonad
([Bool], [(Identifier, HWType)], [Declaration],
[(Identifier, HWType)], [Declaration], [LetBinding], Maybe Id)
forall a e. (HasCallStack, Exception e) => e -> a
throw (SrcSpan -> [Char] -> Maybe [Char] -> ClashException
ClashException SrcSpan
sp ($[Char]
curLoc [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
err) Maybe [Char]
forall a. Maybe a
Nothing)
netDecls <- concatMapM mkNetDecl (filter (maybe (const True) (/=) resultM . fst) binders)
decls <- concat <$> mapM (uncurry mkDeclarations) binders
case resultM of
Just Id
result -> do
[NetDecl' _ _ _ rIM] <- case (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 of
LetBinding
b:[LetBinding]
_ -> LetBinding -> NetlistMonad [Declaration]
mkNetDecl LetBinding
b
[LetBinding]
_ -> [Char] -> NetlistMonad [Declaration]
forall a. HasCallStack => [Char] -> a
error [Char]
"internal error: couldn't find result binder"
u <- Lens.use usages
let useOf (Identifier, b)
i = Usage -> Maybe Usage -> Usage
forall a. a -> Maybe a -> a
fromMaybe Usage
Cont (Maybe Usage -> Usage) -> Maybe Usage -> Usage
forall a b. (a -> b) -> a -> b
$ Identifier -> UsageMap -> Maybe Usage
lookupUsage ((Identifier, b) -> Identifier
forall a b. (a, b) -> a
fst (Identifier, b)
i) UsageMap
u
let (compOutps',resUnwrappers') = case compOutps of
[(Identifier, HWType)
oport] -> ([((Identifier, HWType) -> Usage
forall {b}. (Identifier, b) -> Usage
useOf (Identifier, HWType)
oport,(Identifier, HWType)
oport,Maybe Expr
rIM)],[Declaration]
resUnwrappers)
[(Identifier, HWType)]
_ -> case [Declaration]
resUnwrappers of
NetDecl Maybe Text
n Identifier
res HWType
resTy:[Declaration]
_ ->
(((Identifier, HWType) -> (Usage, (Identifier, HWType), Maybe Expr))
-> [(Identifier, HWType)]
-> [(Usage, (Identifier, HWType), Maybe Expr)]
forall a b. (a -> b) -> [a] -> [b]
map (\(Identifier, HWType)
op -> ((Identifier, HWType) -> Usage
forall {b}. (Identifier, b) -> Usage
useOf (Identifier, HWType)
op,(Identifier, HWType)
op,Maybe Expr
forall a. Maybe a
Nothing)) [(Identifier, HWType)]
compOutps
,Maybe Text -> Identifier -> HWType -> Maybe Expr -> Declaration
NetDecl' Maybe Text
n Identifier
res HWType
resTy Maybe Expr
forall a. Maybe a
NothingDeclaration -> [Declaration] -> [Declaration]
forall a. a -> [a] -> [a]
:Int -> [Declaration] -> [Declaration]
forall a. Int -> [a] -> [a]
drop Int
1 [Declaration]
resUnwrappers
)
[Declaration]
_ -> [Char]
-> ([(Usage, (Identifier, HWType), Maybe Expr)], [Declaration])
forall a. HasCallStack => [Char] -> a
error [Char]
"internal error: insufficient resUnwrappers"
component = Identifier
-> [(Identifier, HWType)]
-> [(Usage, (Identifier, HWType), Maybe Expr)]
-> [Declaration]
-> Component
Component Identifier
compName1 [(Identifier, HWType)]
compInps [(Usage, (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')
ids <- Lens.use seenIds
return (ComponentMeta wereVoids sp ids u, component)
Maybe Id
Nothing -> do
let component :: Component
component = Identifier
-> [(Identifier, HWType)]
-> [(Usage, (Identifier, HWType), Maybe Expr)]
-> [Declaration]
-> Component
Component Identifier
compName1 [(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)
ids <- Getting IdentifierSet NetlistState IdentifierSet
-> NetlistMonad IdentifierSet
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
Lens.use Getting IdentifierSet NetlistState IdentifierSet
Lens' NetlistState IdentifierSet
seenIds
u <- Lens.use usages
return (ComponentMeta wereVoids sp ids u, component)
mkNetDecl :: (Id, Term) -> NetlistMonad [Declaration]
mkNetDecl :: LetBinding -> NetlistMonad [Declaration]
mkNetDecl (Id
id_,Term
tm) = NetlistMonad [Declaration] -> NetlistMonad [Declaration]
forall a. NetlistMonad a -> NetlistMonad a
preserveVarEnv (NetlistMonad [Declaration] -> NetlistMonad [Declaration])
-> NetlistMonad [Declaration] -> NetlistMonad [Declaration]
forall a b. (a -> b) -> a -> b
$ do
hwTy <- [Char] -> Type -> NetlistMonad HWType
unsafeCoreTypeToHWTypeM' $(curLoc) (Id -> Type
forall a. HasType a => a -> Type
coreTypeOf Id
id_)
if | not (shouldRenderDecl hwTy tm) -> return []
| (Prim pInfo@PrimInfo{primMultiResult=MultiResult}, args) <- collectArgs tm ->
multiDecls pInfo args
| otherwise -> pure <$> singleDecl hwTy
where
multiDecls :: PrimInfo -> [Either Term Type] -> NetlistMonad [Declaration]
multiDecls PrimInfo
pInfo [Either Term Type]
args0 = do
tcm <- Getting TyConMap NetlistEnv TyConMap -> NetlistMonad TyConMap
forall s (m :: Type -> Type) a.
MonadReader s m =>
Getting a s a -> m a
Lens.view Getting TyConMap NetlistEnv TyConMap
Getter NetlistEnv TyConMap
tcCache
resInits0 <- getResInits (id_, tm)
let
resInits1 = (Expr -> Maybe Expr) -> [Expr] -> [Maybe Expr]
forall a b. (a -> b) -> [a] -> [b]
map Expr -> Maybe Expr
forall a. a -> Maybe a
Just [Expr]
resInits0 [Maybe Expr] -> [Maybe Expr] -> [Maybe Expr]
forall a. Semigroup a => a -> a -> a
<> Maybe Expr -> [Maybe Expr]
forall a. a -> [a]
repeat Maybe Expr
forall a. Maybe a
Nothing
mpInfo = HasCallStack => TyConMap -> PrimInfo -> MultiPrimInfo
TyConMap -> PrimInfo -> MultiPrimInfo
multiPrimInfo' TyConMap
tcm PrimInfo
pInfo
(_, res) = splitMultiPrimArgs mpInfo args0
netdecl Id
i HWType
typ Maybe Expr
resInit =
Maybe Text -> Identifier -> HWType -> Maybe Expr -> Declaration
NetDecl' Maybe Text
srcNote (HasCallStack => Id -> Identifier
Id -> Identifier
Id.unsafeFromCoreId Id
i) HWType
typ Maybe Expr
resInit
hwTys <- mapM (unsafeCoreTypeToHWTypeM' $(curLoc)) (mpi_resultTypes mpInfo)
pure (zipWith3 netdecl res hwTys resInits1)
singleDecl :: HWType -> NetlistMonad Declaration
singleDecl HWType
hwTy = do
rIM <- [Expr] -> Maybe Expr
forall a. [a] -> Maybe a
listToMaybe ([Expr] -> Maybe Expr)
-> NetlistMonad [Expr] -> NetlistMonad (Maybe Expr)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> LetBinding -> NetlistMonad [Expr]
getResInits (Id
id_, Term
tm)
return (NetDecl' srcNote (Id.unsafeFromCoreId id_) hwTy rIM)
addSrcNote :: SrcSpan -> Maybe Text
addSrcNote SrcSpan
loc
| SrcSpan -> Bool
isGoodSrcSpan SrcSpan
loc = Text -> Maybe Text
forall a. a -> Maybe a
Just ([Char] -> Text
StrictText.pack (SDoc -> [Char]
showSDocUnsafe (SrcSpan -> SDoc
forall a. Outputable a => a -> SDoc
ppr SrcSpan
loc)))
| Bool
otherwise = Maybe Text
forall a. Maybe a
Nothing
srcNote :: Maybe Text
srcNote = SrcSpan -> Maybe Text
addSrcNote (SrcSpan -> Maybe Text) -> SrcSpan -> Maybe Text
forall a b. (a -> b) -> a -> b
$ case Term
tm of
Tick (SrcSpan SrcSpan
s) Term
_ -> SrcSpan
s
Term
_ -> Name Term -> SrcSpan
forall a. Name a -> SrcSpan
nameLoc (Id -> Name Term
forall a. Var a -> Name a
varName Id
id_)
isMultiPrimSelect :: Term -> Bool
isMultiPrimSelect :: Term -> Bool
isMultiPrimSelect Term
t = case Term -> (Term, [Either Term Type])
collectArgs Term
t of
(Prim (PrimInfo -> Text
primName -> Text
"c$multiPrimSelect"), [Either Term Type]
_) -> Bool
True
(Term, [Either Term Type])
_ -> Bool
False
shouldRenderDecl :: HWType -> Term -> Bool
shouldRenderDecl :: HWType -> Term -> Bool
shouldRenderDecl HWType
ty Term
t
| HWType -> Bool
isVoid HWType
ty = Bool
False
| Term -> Bool
isMultiPrimSelect Term
t = Bool
False
| Bool
otherwise = Bool
True
getResInits :: (Id, Term) -> NetlistMonad [Expr]
getResInits :: LetBinding -> NetlistMonad [Expr]
getResInits (Id
i,Term -> (Term, [Either Term Type], [TickInfo])
collectArgsTicks -> (Term
k,[Either Term Type]
args0,[TickInfo]
ticks)) = case Term
k of
Prim PrimInfo
p -> HasCallStack => Text -> NetlistMonad CompiledPrimitive
Text -> NetlistMonad CompiledPrimitive
extractPrimWarnOrFail (PrimInfo -> Text
primName PrimInfo
p) NetlistMonad CompiledPrimitive
-> (CompiledPrimitive -> NetlistMonad [Expr])
-> NetlistMonad [Expr]
forall a b.
NetlistMonad a -> (a -> NetlistMonad b) -> NetlistMonad b
forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= PrimInfo -> CompiledPrimitive -> NetlistMonad [Expr]
forall {a} {c} {d}.
PrimInfo -> Primitive a BlackBox c d -> NetlistMonad [Expr]
go PrimInfo
p
Term
_ -> [Expr] -> NetlistMonad [Expr]
forall a. a -> NetlistMonad a
forall (m :: Type -> Type) a. Monad m => a -> m a
return []
where
go :: PrimInfo -> Primitive a BlackBox c d -> NetlistMonad [Expr]
go PrimInfo
pInfo (BlackBox {resultInits :: forall a b c d. Primitive a b c d -> [b]
resultInits=[BlackBox]
nmDs, multiResult :: forall a b c d. Primitive a b c d -> Bool
multiResult=Bool
True}) = [TickInfo]
-> ([Declaration] -> NetlistMonad [Expr]) -> NetlistMonad [Expr]
forall a.
[TickInfo] -> ([Declaration] -> NetlistMonad a) -> NetlistMonad a
withTicks [TickInfo]
ticks (([Declaration] -> NetlistMonad [Expr]) -> NetlistMonad [Expr])
-> ([Declaration] -> NetlistMonad [Expr]) -> NetlistMonad [Expr]
forall a b. (a -> b) -> a -> b
$ \[Declaration]
_ -> do
tcm <- Getting TyConMap NetlistEnv TyConMap -> NetlistMonad TyConMap
forall s (m :: Type -> Type) a.
MonadReader s m =>
Getting a s a -> m a
Lens.view Getting TyConMap NetlistEnv TyConMap
Getter NetlistEnv TyConMap
tcCache
let (args1, res) = splitMultiPrimArgs (multiPrimInfo' tcm pInfo) args0
(bbCtx, _) <- mkBlackBoxContext (primName pInfo) Concurrent res args1
mapM (go' (primName pInfo) bbCtx) nmDs
go PrimInfo
pInfo (BlackBox {resultInits :: forall a b c d. Primitive a b c d -> [b]
resultInits=[BlackBox]
nmDs}) = [TickInfo]
-> ([Declaration] -> NetlistMonad [Expr]) -> NetlistMonad [Expr]
forall a.
[TickInfo] -> ([Declaration] -> NetlistMonad a) -> NetlistMonad a
withTicks [TickInfo]
ticks (([Declaration] -> NetlistMonad [Expr]) -> NetlistMonad [Expr])
-> ([Declaration] -> NetlistMonad [Expr]) -> NetlistMonad [Expr]
forall a b. (a -> b) -> a -> b
$ \[Declaration]
_ -> do
(bbCtx, _) <- HasCallStack =>
Text
-> DeclarationType
-> [Id]
-> [Either Term Type]
-> NetlistMonad (BlackBoxContext, [Declaration])
Text
-> DeclarationType
-> [Id]
-> [Either Term Type]
-> NetlistMonad (BlackBoxContext, [Declaration])
mkBlackBoxContext (PrimInfo -> Text
primName PrimInfo
pInfo) DeclarationType
Concurrent [Id
i] [Either Term Type]
args0
mapM (go' (primName pInfo) bbCtx) nmDs
go PrimInfo
_ Primitive a BlackBox c d
_ = [Expr] -> NetlistMonad [Expr]
forall a. a -> NetlistMonad a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure []
go' :: Text -> BlackBoxContext -> BlackBox -> NetlistMonad Expr
go' Text
pNm BlackBoxContext
bbCtx BlackBox
nmD = do
(bbTempl, templDecl) <- Text
-> BlackBox
-> BlackBoxContext
-> NetlistMonad (BlackBox, [Declaration])
prepareBlackBox Text
pNm BlackBox
nmD BlackBoxContext
bbCtx
case templDecl of
[] ->
Expr -> NetlistMonad Expr
forall a. a -> NetlistMonad a
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Text
-> [BlackBoxTemplate]
-> [BlackBoxTemplate]
-> [((Text, Text), BlackBox)]
-> BlackBox
-> BlackBoxContext
-> Bool
-> Expr
BlackBoxE Text
pNm [] [] [] BlackBox
bbTempl BlackBoxContext
bbCtx Bool
False)
[Declaration]
_ -> do
(_,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
throw (ClashException sloc [I.i|
Initial values cannot produce declarations, but saw:
#{templDecl}
after rendering initial values for blackbox:
#{pNm}
Given template:
#{nmD}
|] Nothing)
mkDeclarations
:: HasCallStack
=> Id
-> Term
-> NetlistMonad [Declaration]
mkDeclarations :: HasCallStack => 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' :: HasCallStack =>
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 (HasCallStack =>
DeclarationType
-> Identifier
-> Id
-> [Term]
-> [Declaration]
-> NetlistMonad [Declaration]
DeclarationType
-> Identifier
-> Id
-> [Term]
-> [Declaration]
-> NetlistMonad [Declaration]
mkFunApp DeclarationType
declType (HasCallStack => Id -> Identifier
Id -> Identifier
Id.unsafeFromCoreId Id
bndr) Id
v [])
mkDeclarations' DeclarationType
_declType Id
_bndr e :: Term
e@(Term -> (Term, [TickInfo])
collectTicks -> (Case Term
_ Type
_ [],[TickInfo]
_)) = do
(_,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
throw $ ClashException
sp
( unwords [ $(curLoc)
, "Not in normal form: Case-decompositions with an"
, "empty list of alternatives not supported:\n\n"
, showPpr e
])
Nothing
mkDeclarations' DeclarationType
declType Id
bndr (Term -> (Term, [TickInfo])
collectTicks -> (Case Term
scrut Type
altTy ((Pat, Term)
alt:alts :: [(Pat, Term)]
alts@((Pat, Term)
_:[(Pat, Term)]
_)),[TickInfo]
ticks)) =
[TickInfo]
-> ([Declaration] -> NetlistMonad [Declaration])
-> NetlistMonad [Declaration]
forall a.
[TickInfo] -> ([Declaration] -> NetlistMonad a) -> NetlistMonad a
withTicks [TickInfo]
ticks (DeclarationType
-> NetlistId
-> Term
-> Type
-> NonEmpty (Pat, Term)
-> [Declaration]
-> NetlistMonad [Declaration]
mkSelection DeclarationType
declType (Id -> NetlistId
CoreId Id
bndr) Term
scrut Type
altTy ((Pat, Term)
alt (Pat, Term) -> [(Pat, Term)] -> NonEmpty (Pat, Term)
forall a. a -> [a] -> NonEmpty a
:| [(Pat, Term)]
alts))
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 a. [a] -> 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 =>
DeclarationType
-> Identifier
-> Id
-> [Term]
-> [Declaration]
-> NetlistMonad [Declaration]
DeclarationType
-> Identifier
-> Id
-> [Term]
-> [Declaration]
-> NetlistMonad [Declaration]
mkFunApp DeclarationType
declType (HasCallStack => Id -> Identifier
Id -> Identifier
Id.unsafeFromCoreId Id
bndr) Id
f [Term]
args)
| Bool
otherwise -> do
(_,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
throw (ClashException sp ($(curLoc) ++ "Not in normal form: Var-application with Type arguments:\n\n" ++ showPpr app) Nothing)
Term
_ -> do
(exprApp,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 = HasCallStack => Id -> Identifier
Id -> Identifier
Id.unsafeFromCoreId Id
bndr
assn <- case exprApp of
Identifier Identifier
_ Maybe Modifier
Nothing ->
[Declaration] -> NetlistMonad [Declaration]
forall a. a -> NetlistMonad a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure []
Expr
Noop ->
[Declaration] -> NetlistMonad [Declaration]
forall a. a -> NetlistMonad a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure []
Expr
_ -> do
assn <- case DeclarationType
declType of
DeclarationType
Concurrent -> HasCallStack => Identifier -> Expr -> NetlistMonad Declaration
Identifier -> Expr -> NetlistMonad Declaration
contAssign Identifier
dstId Expr
exprApp
DeclarationType
Sequential -> HasCallStack =>
Blocking -> Identifier -> Expr -> NetlistMonad Declaration
Blocking -> Identifier -> Expr -> NetlistMonad Declaration
procAssign Blocking
Blocking Identifier
dstId Expr
exprApp
pure [assn]
declsApp1 <- if null declsApp0
then withTicks ticks return
else pure declsApp0
return (declsApp1 ++ assn)
mkSelection
:: DeclarationType
-> NetlistId
-> Term
-> Type
-> NonEmpty Alt
-> [Declaration]
-> NetlistMonad [Declaration]
mkSelection :: DeclarationType
-> NetlistId
-> Term
-> Type
-> NonEmpty (Pat, Term)
-> [Declaration]
-> NetlistMonad [Declaration]
mkSelection DeclarationType
declType NetlistId
bndr Term
scrut Type
altTy NonEmpty (Pat, Term)
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 HasCallStack => Id -> Identifier
Id -> Identifier
Id.unsafeFromCoreId NetlistId
bndr
tcm <- Getting TyConMap NetlistEnv TyConMap -> NetlistMonad TyConMap
forall s (m :: Type -> Type) a.
MonadReader s m =>
Getting a s a -> m a
Lens.view Getting TyConMap NetlistEnv TyConMap
Getter NetlistEnv TyConMap
tcCache
let scrutTy = TyConMap -> Term -> Type
forall a. InferType a => TyConMap -> a -> Type
inferCoreTypeOf TyConMap
tcm Term
scrut
scrutHTy <- unsafeCoreTypeToHWTypeM' $(curLoc) scrutTy
scrutId <- Id.suffix dstId "selection"
(_,sp) <- Lens.use curCompNm
ite <- Lens.use backEndITE
altHTy <- unsafeCoreTypeToHWTypeM' $(curLoc) altTy
case iteAlts scrutHTy (NE.toList alts0) of
Just (Term
altT,Term
altF)
| Bool
ite
, DeclarationType
Concurrent <- DeclarationType
declType
-> do
(scrutExpr,scrutDecls) <- case HWType
scrutHTy of
SP {} -> (Expr -> Expr) -> (Expr, [Declaration]) -> (Expr, [Declaration])
forall a b c. (a -> b) -> (a, c) -> (b, c)
forall (p :: Type -> Type -> Type) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (SrcSpan -> HWType -> Pat -> Expr -> Expr
mkScrutExpr SrcSpan
sp HWType
scrutHTy ((Pat, Term) -> Pat
forall a b. (a, b) -> a
fst (NonEmpty (Pat, Term) -> (Pat, Term)
forall a. NonEmpty a -> a
NE.last NonEmpty (Pat, Term)
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
altTId <- Id.suffix dstId "sel_alt_t"
altFId <- Id.suffix dstId "sel_alt_f"
(altTExpr,altTDecls) <- mkExpr False declType (NetlistId altTId altTy) altT
(altFExpr,altFDecls) <- mkExpr False declType (NetlistId altFId altTy) altF
if | isVoid altHTy && isVoid scrutHTy
-> return $! scrutDecls ++ altTDecls ++ altFDecls
| isVoid altHTy
-> return $! altTDecls ++ altFDecls
| otherwise
-> do dstAssign <- contAssign dstId (IfThenElse scrutExpr altTExpr altFExpr)
return $! scrutDecls ++ altTDecls ++ altFDecls ++ tickDecls ++ [dstAssign]
Maybe (Term, Term)
_ -> do
reprs <- Getting CustomReprs NetlistEnv CustomReprs
-> NetlistMonad CustomReprs
forall s (m :: Type -> Type) a.
MonadReader s m =>
Getting a s a -> m a
Lens.view Getting CustomReprs NetlistEnv CustomReprs
Getter NetlistEnv CustomReprs
customReprs
let alts1 = (NonEmpty (Pat, Term) -> NonEmpty (Pat, Term)
reorderDefault (NonEmpty (Pat, Term) -> NonEmpty (Pat, Term))
-> (NonEmpty (Pat, Term) -> NonEmpty (Pat, Term))
-> NonEmpty (Pat, Term)
-> NonEmpty (Pat, Term)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TyConMap
-> CustomReprs
-> Type
-> NonEmpty (Pat, Term)
-> NonEmpty (Pat, Term)
reorderCustom TyConMap
tcm CustomReprs
reprs Type
scrutTy) NonEmpty (Pat, Term)
alts0
(scrutExpr,scrutDecls) <- first (mkScrutExpr sp scrutHTy (fst (NE.head alts1))) <$>
mkExpr True declType (NetlistId scrutId scrutTy) scrut
(exprs,altsDecls) <- unzip <$> mapM (mkCondExpr scrutHTy) (NE.toList alts1)
case declType of
DeclarationType
Sequential -> do
(altNets,exprAlts) <- ([([Declaration], (Maybe Literal, [Seq]))]
-> ([[Declaration]], [(Maybe Literal, [Seq])]))
-> NetlistMonad [([Declaration], (Maybe Literal, [Seq]))]
-> NetlistMonad ([[Declaration]], [(Maybe Literal, [Seq])])
forall a b. (a -> b) -> NetlistMonad a -> NetlistMonad b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap [([Declaration], (Maybe Literal, [Seq]))]
-> ([[Declaration]], [(Maybe Literal, [Seq])])
forall a b. [(a, b)] -> ([a], [b])
unzip (((Maybe Literal, Expr)
-> [Declaration]
-> NetlistMonad ([Declaration], (Maybe Literal, [Seq])))
-> [(Maybe Literal, Expr)]
-> [[Declaration]]
-> NetlistMonad [([Declaration], (Maybe Literal, [Seq]))]
forall (m :: Type -> Type) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m [c]
zipWithM (Identifier
-> (Maybe Literal, Expr)
-> [Declaration]
-> NetlistMonad ([Declaration], (Maybe Literal, [Seq]))
altAssign Identifier
dstId) [(Maybe Literal, Expr)]
exprs [[Declaration]]
altsDecls)
return $! scrutDecls ++ tickDecls ++ concat altNets ++
[Seq [Branch scrutExpr scrutHTy exprAlts]]
DeclarationType
Concurrent ->
if | HWType -> Bool
isVoid HWType
altHTy Bool -> Bool -> Bool
&& HWType -> Bool
isVoid HWType
scrutHTy
-> [Declaration] -> NetlistMonad [Declaration]
forall a. a -> NetlistMonad a
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 a. a -> NetlistMonad a
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
-> do assign <- Identifier
-> HWType
-> Expr
-> HWType
-> [(Maybe Literal, Expr)]
-> NetlistMonad Declaration
condAssign Identifier
dstId HWType
altHTy Expr
scrutExpr HWType
scrutHTy [(Maybe Literal, Expr)]
exprs
return $! scrutDecls ++ concat altsDecls ++ tickDecls ++ [assign]
where
mkCondExpr :: HWType -> (Pat,Term) -> NetlistMonad ((Maybe HW.Literal,Expr),[Declaration])
mkCondExpr :: HWType
-> (Pat, Term)
-> NetlistMonad ((Maybe Literal, Expr), [Declaration])
mkCondExpr HWType
scrutHTy (Pat
pat,Term
alt) = do
altId <- Identifier -> Text -> NetlistMonad Identifier
forall (m :: Type -> Type).
(HasCallStack, IdentifierSetMonad m) =>
Identifier -> Text -> m Identifier
Id.suffix ((Identifier -> Identifier)
-> (Id -> Identifier) -> NetlistId -> Identifier
forall r.
HasCallStack =>
(Identifier -> r) -> (Id -> r) -> NetlistId -> r
netlistId1 Identifier -> Identifier
forall a. a -> a
id HasCallStack => Id -> Identifier
Id -> Identifier
Id.unsafeFromCoreId NetlistId
bndr) Text
"sel_alt"
(altExpr,altDecls) <- mkExpr False declType (NetlistId altId altTy) alt
(,altDecls) <$> case pat of
Pat
DefaultPat -> (Maybe Literal, Expr) -> NetlistMonad (Maybe Literal, Expr)
forall a. a -> NetlistMonad a
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 a. a -> NetlistMonad a
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 a. a -> NetlistMonad a
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 a. a -> NetlistMonad a
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 a. a -> NetlistMonad a
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 a. a -> NetlistMonad a
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 a. a -> NetlistMonad a
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 a. a -> NetlistMonad a
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)
#if MIN_VERSION_base(4,16,0)
LitPat (Int8Literal Integer
i) -> (Maybe Literal, Expr) -> NetlistMonad (Maybe Literal, Expr)
forall a. a -> NetlistMonad a
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 (Int16Literal Integer
i) -> (Maybe Literal, Expr) -> NetlistMonad (Maybe Literal, Expr)
forall a. a -> NetlistMonad a
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 (Int32Literal Integer
i) -> (Maybe Literal, Expr) -> NetlistMonad (Maybe Literal, Expr)
forall a. a -> NetlistMonad a
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 (Word8Literal Integer
w) -> (Maybe Literal, Expr) -> NetlistMonad (Maybe Literal, Expr)
forall a. a -> NetlistMonad a
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 (Word16Literal Integer
w) -> (Maybe Literal, Expr) -> NetlistMonad (Maybe Literal, Expr)
forall a. a -> NetlistMonad a
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 (Word32Literal Integer
w) -> (Maybe Literal, Expr) -> NetlistMonad (Maybe Literal, Expr)
forall a. a -> NetlistMonad a
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)
#endif
LitPat (NaturalLiteral Integer
n) -> (Maybe Literal, Expr) -> NetlistMonad (Maybe Literal, Expr)
forall a. a -> NetlistMonad a
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
(_,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
throw (ClashException sp ($(curLoc) ++ "Not an integer literal in LitPat:\n\n" ++ showPpr pat) 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. (HasCallStack, Exception e) => e -> a
throw (SrcSpan -> [Char] -> Maybe [Char] -> ClashException
ClashException SrcSpan
sp ($(curLoc) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"Not in normal form: Not a variable reference or primitive as subject of a case-statement:\n\n" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Expr -> [Char]
forall a. Show a => a -> [Char]
show Expr
scrutE) Maybe [Char]
forall a. Maybe a
Nothing)
Pat
_ -> Expr
scrutE
altAssign
:: Identifier
-> (Maybe HW.Literal,Expr)
-> [Declaration]
-> NetlistMonad ([Declaration],(Maybe HW.Literal,[Seq]))
altAssign :: Identifier
-> (Maybe Literal, Expr)
-> [Declaration]
-> NetlistMonad ([Declaration], (Maybe Literal, [Seq]))
altAssign Identifier
i (Maybe Literal
m,Expr
expr) [Declaration]
ds = do
let ([Declaration]
nets,[Declaration]
rest) = (Declaration -> Bool)
-> [Declaration] -> ([Declaration], [Declaration])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition Declaration -> Bool
isNet [Declaration]
ds
assn <- case Expr
expr of
Expr
Noop -> [Declaration] -> NetlistMonad [Declaration]
forall a. a -> NetlistMonad a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure []
Expr
_ -> do assn <- HasCallStack =>
Blocking -> Identifier -> Expr -> NetlistMonad Declaration
Blocking -> Identifier -> Expr -> NetlistMonad Declaration
procAssign Blocking
Blocking Identifier
i Expr
expr
pure [assn]
pure (nets,(m,map SeqDecl (rest ++ assn)))
where
isNet :: Declaration -> Bool
isNet NetDecl' {} = Bool
True
isNet Declaration
_ = Bool
False
reorderDefault
:: NonEmpty (Pat, Term)
-> NonEmpty (Pat, Term)
reorderDefault :: NonEmpty (Pat, Term) -> NonEmpty (Pat, Term)
reorderDefault ((Pat
DefaultPat,Term
e) :| [(Pat, Term)]
alts') =
case [(Pat, Term)]
alts' of
[] -> (Pat
DefaultPat,Term
e) (Pat, Term) -> [(Pat, Term)] -> NonEmpty (Pat, Term)
forall a. a -> [a] -> NonEmpty a
:| []
(Pat, Term)
x:[(Pat, Term)]
xs -> (Pat, Term)
x (Pat, Term) -> [(Pat, Term)] -> NonEmpty (Pat, Term)
forall a. a -> [a] -> NonEmpty a
:| ([(Pat, Term)]
xs [(Pat, Term)] -> [(Pat, Term)] -> [(Pat, Term)]
forall a. Semigroup a => a -> a -> a
<> [(Pat
DefaultPat,Term
e)])
reorderDefault NonEmpty (Pat, Term)
alts' = NonEmpty (Pat, Term)
alts'
reorderCustom
:: TyConMap
-> CustomReprs
-> Type
-> NonEmpty (Pat, Term)
-> NonEmpty (Pat, Term)
reorderCustom :: TyConMap
-> CustomReprs
-> Type
-> NonEmpty (Pat, Term)
-> NonEmpty (Pat, Term)
reorderCustom TyConMap
tcm CustomReprs
reprs (TyConMap -> Type -> Maybe Type
coreView1 TyConMap
tcm -> Just Type
ty) NonEmpty (Pat, Term)
alts =
TyConMap
-> CustomReprs
-> Type
-> NonEmpty (Pat, Term)
-> NonEmpty (Pat, Term)
reorderCustom TyConMap
tcm CustomReprs
reprs Type
ty NonEmpty (Pat, Term)
alts
reorderCustom TyConMap
_tcm CustomReprs
reprs (Type -> Either [Char] Type'
coreToType' -> Right Type'
typeName) NonEmpty (Pat, Term)
alts =
case Type' -> CustomReprs -> Maybe DataRepr'
getDataRepr Type'
typeName CustomReprs
reprs of
Just (DataRepr' Type'
_name Int
_size [ConstrRepr']
_constrReprs) ->
((Pat, Term) -> Int)
-> NonEmpty (Pat, Term) -> NonEmpty (Pat, Term)
forall b a. Ord b => (a -> b) -> NonEmpty a -> NonEmpty a
NE.sortOn (CustomReprs -> Pat -> Int
patPos CustomReprs
reprs (Pat -> Int) -> ((Pat, Term) -> Pat) -> (Pat, Term) -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Pat, Term) -> Pat
forall a b. (a, b) -> a
fst) NonEmpty (Pat, Term)
alts
Maybe DataRepr'
Nothing ->
NonEmpty (Pat, Term)
alts
reorderCustom TyConMap
_tcm CustomReprs
_reprs Type
_type NonEmpty (Pat, Term)
alts =
NonEmpty (Pat, Term)
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 :: Text
name = Name DataCon -> Text
forall a. Name a -> Text
nameOcc (Name DataCon -> Text) -> Name DataCon -> Text
forall a b. (a -> b) -> a -> b
$ DataCon -> Name DataCon
dcName DataCon
dataCon in
case Text -> CustomReprs -> Maybe ConstrRepr'
getConstrRepr Text
name CustomReprs
reprs of
Maybe ConstrRepr'
Nothing ->
[Char] -> Int
forall a. HasCallStack => [Char] -> a
error ([Char] -> Int) -> [Char] -> Int
forall a b. (a -> b) -> a -> b
$ $(curLoc) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ (Pat -> [Char]
forall a. Show a => a -> [Char]
show Pat
pat)
Just (ConstrRepr' Text
_name Int
n Integer
_mask Integer
_value [Integer]
_anns) ->
Int
n
mkFunApp
:: HasCallStack
=> DeclarationType
-> Identifier
-> Id
-> [Term]
-> [Declaration]
-> NetlistMonad [Declaration]
mkFunApp :: HasCallStack =>
DeclarationType
-> Identifier
-> Id
-> [Term]
-> [Declaration]
-> NetlistMonad [Declaration]
mkFunApp DeclarationType
declType Identifier
dstId Id
fun [Term]
args [Declaration]
tickDecls = do
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
tcm <- Lens.view tcCache
case (isGlobalId fun, lookupVarEnv fun topAnns) of
(Bool
True, Just TopEntityT
topEntity)
| let ty :: Type
ty = Id -> Type
forall a. HasType a => a -> Type
coreTypeOf (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 a. [a] -> 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 a. [a] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length [Term]
args
-> do
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)
forall (m :: Type -> Type) a b.
Monad m =>
(a -> m b) -> [a] -> m [b]
mapM ([Char] -> Type -> NetlistMonad HWType
unsafeCoreTypeToHWTypeM' $(curLoc)) [Type]
fArgTys1
(argExprs, concat -> argDecls) <- unzip <$>
mapM (\(Term
e,Type
t) -> 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
dstId Type
t) Term
e)
(zip args fArgTys1)
let
filteredTypeExprs = ((Expr, HWType) -> Bool) -> [(Expr, HWType)] -> [(Expr, HWType)]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool)
-> ((Expr, HWType) -> Bool) -> (Expr, HWType) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HWType -> Bool
isVoid (HWType -> Bool)
-> ((Expr, HWType) -> HWType) -> (Expr, HWType) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Expr, HWType) -> HWType
forall a b. (a, b) -> b
snd) ([Expr] -> [HWType] -> [(Expr, HWType)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Expr]
argExprs [HWType]
argHWTys)
dstHWty <- unsafeCoreTypeToHWTypeM' $(curLoc) fResTy
argTys <- mapM (unsafeCoreTypeToHWTypeM $(curLoc) . inferCoreTypeOf tcm) args
resTy <- unsafeCoreTypeToHWTypeM $(curLoc) fResTy
let
ettArgs = (Maybe a
forall a. Maybe a
Nothing,) (FilteredHWType -> (Maybe a, FilteredHWType))
-> [FilteredHWType] -> [(Maybe a, FilteredHWType)]
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> [FilteredHWType]
argTys
ettRes = (Maybe a
forall a. Maybe a
Nothing, FilteredHWType
resTy)
expandedTopEntity <-
expandTopEntityOrErrM ettArgs ettRes (topAnnotation topEntity)
instDecls <-
mkTopUnWrapper
fun expandedTopEntity (dstId, dstHWty)
filteredTypeExprs tickDecls
return (argDecls ++ instDecls)
| Bool
otherwise -> [Char] -> NetlistMonad [Declaration]
forall a. HasCallStack => [Char] -> a
error ([Char] -> NetlistMonad [Declaration])
-> [Char] -> NetlistMonad [Declaration]
forall a b. (a -> b) -> a -> b
$ $(curLoc) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"under-applied TopEntity: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Id -> [Char]
forall p. PrettyPrec p => p -> [Char]
showPpr Id
fun
(Bool
True, Maybe TopEntityT
Nothing) -> do
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 lookupVarEnv fun normalized of
Maybe (Binding Term)
Nothing -> [Char] -> NetlistMonad [Declaration]
forall a. HasCallStack => [Char] -> a
error [I.i|
Internal error: unknown normalized binder:
#{showPpr fun}
|]
Just (Binding{Term
bindingTerm :: forall a. Binding a -> a
bindingTerm :: Term
bindingTerm}) -> do
(_, Component compName compInps co _) <- NetlistMonad (ComponentMeta, Component)
-> NetlistMonad (ComponentMeta, Component)
forall a. NetlistMonad a -> NetlistMonad a
preserveVarEnv (NetlistMonad (ComponentMeta, Component)
-> NetlistMonad (ComponentMeta, Component))
-> NetlistMonad (ComponentMeta, Component)
-> NetlistMonad (ComponentMeta, Component)
forall a b. (a -> b) -> a -> b
$ HasCallStack => Id -> NetlistMonad (ComponentMeta, Component)
Id -> NetlistMonad (ComponentMeta, Component)
genComponent Id
fun
let argTys = (Term -> Type) -> [Term] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map (TyConMap -> Term -> Type
forall a. InferType a => TyConMap -> a -> Type
inferCoreTypeOf TyConMap
tcm) [Term]
args
argHWTys <- mapM coreTypeToHWTypeM' argTys
(argExprs, concat -> argDecls) <- unzip <$>
mapM (\(Term
e,Type
t) -> 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
dstId Type
t) Term
e)
(zip args argTys)
let
argTypeExprs = [Maybe HWType] -> [(Expr, Type)] -> [(Maybe HWType, (Expr, Type))]
forall a b. [a] -> [b] -> [(a, b)]
zip [Maybe HWType]
argHWTys ([Expr] -> [Type] -> [(Expr, Type)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Expr]
argExprs [Type]
argTys)
filteredTypeExprs = ((Maybe HWType, (Expr, Type)) -> (Expr, Type))
-> [(Maybe HWType, (Expr, Type))] -> [(Expr, Type)]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap (Maybe HWType, (Expr, Type)) -> (Expr, Type)
forall a b. (a, b) -> b
snd ([(Maybe HWType, (Expr, Type))] -> [(Expr, Type)])
-> [(Maybe HWType, (Expr, Type))] -> [(Expr, Type)]
forall a b. (a -> b) -> a -> b
$ ((Maybe HWType, (Expr, Type)) -> Bool)
-> [(Maybe HWType, (Expr, Type))] -> [(Maybe HWType, (Expr, Type))]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool)
-> ((Maybe HWType, (Expr, Type)) -> Bool)
-> (Maybe HWType, (Expr, Type))
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Maybe HWType -> Bool
isVoidMaybe Bool
True (Maybe HWType -> Bool)
-> ((Maybe HWType, (Expr, Type)) -> Maybe HWType)
-> (Maybe HWType, (Expr, Type))
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe HWType, (Expr, Type)) -> Maybe HWType
forall a b. (a, b) -> a
fst) [(Maybe HWType, (Expr, Type))]
argTypeExprs
let compOutp = (\(Usage
_,(Identifier, HWType)
x,Maybe Expr
_) -> (Identifier, HWType)
x) ((Usage, (Identifier, HWType), Maybe Expr) -> (Identifier, HWType))
-> Maybe (Usage, (Identifier, HWType), Maybe Expr)
-> Maybe (Identifier, HWType)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> [(Usage, (Identifier, HWType), Maybe Expr)]
-> Maybe (Usage, (Identifier, HWType), Maybe Expr)
forall a. [a] -> Maybe a
listToMaybe [(Usage, (Identifier, HWType), Maybe Expr)]
co
if length filteredTypeExprs == length compInps
then do
(argExprs',argDecls') <- (second concat . unzip) <$> mapM (toSimpleVar declType dstId) filteredTypeExprs
let 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 = 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)]
let instLabel0 = [Text] -> Text
StrictText.concat [Identifier -> Text
Id.toText Identifier
compName, Text
"_", Identifier -> Text
Id.toText Identifier
dstId]
instLabel1 <- fromMaybe instLabel0 <$> Lens.view setName
instLabel2 <- affixName instLabel1
instLabel3 <- Id.makeBasic instLabel2
let portMap = [(Expr, PortDirection, HWType, Expr)] -> PortMap
NamedPortMap ([(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)
instDecl = EntityOrComponent
-> Maybe Text
-> [Attr Text]
-> Identifier
-> Identifier
-> [(Expr, HWType, Expr)]
-> PortMap
-> Declaration
InstDecl EntityOrComponent
Entity Maybe Text
forall a. Maybe a
Nothing [] Identifier
compName Identifier
instLabel3 [] PortMap
portMap
declareInstUses outpAssign
return (argDecls ++ argDecls' ++ tickDecls ++ [instDecl])
else
let
argsFiltered :: [Expr]
argsFiltered = ((Expr, Type) -> Expr) -> [(Expr, Type)] -> [Expr]
forall a b. (a -> b) -> [a] -> [b]
map (Expr, Type) -> Expr
forall a b. (a, b) -> a
fst [(Expr, Type)]
filteredTypeExprs
in 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
[] -> do
assn <- HasCallStack => Identifier -> Expr -> NetlistMonad Declaration
Identifier -> Expr -> NetlistMonad Declaration
contAssign Identifier
dstId (Identifier -> Maybe Modifier -> Expr
Identifier (HasCallStack => Id -> Identifier
Id -> Identifier
Id.unsafeFromCoreId Id
fun) Maybe Modifier
forall a. Maybe a
Nothing)
pure [assn]
[Term]
_ -> [Char] -> NetlistMonad [Declaration]
forall a. HasCallStack => [Char] -> 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 :: DeclarationType
-> Identifier
-> (Expr,Type)
-> NetlistMonad (Expr,[Declaration])
toSimpleVar :: DeclarationType
-> Identifier -> (Expr, Type) -> NetlistMonad (Expr, [Declaration])
toSimpleVar DeclarationType
_ Identifier
_ (e :: Expr
e@(Identifier Identifier
_ Maybe Modifier
Nothing),Type
_) = (Expr, [Declaration]) -> NetlistMonad (Expr, [Declaration])
forall a. a -> NetlistMonad a
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Expr
e,[])
toSimpleVar DeclarationType
declType Identifier
dstId (Expr
e,Type
ty) = do
argNm <- Identifier -> Text -> NetlistMonad Identifier
forall (m :: Type -> Type).
(HasCallStack, IdentifierSetMonad m) =>
Identifier -> Text -> m Identifier
Id.suffix Identifier
dstId Text
"fun_arg"
hTy <- unsafeCoreTypeToHWTypeM' $(curLoc) ty
let assignTy = DeclarationType -> Usage
declTypeUsage DeclarationType
declType
argDecl <- mkInit declType assignTy argNm hTy e
return (Identifier argNm Nothing, argDecl)
mkExpr :: HasCallStack
=> Bool
-> DeclarationType
-> NetlistId
-> Term
-> NetlistMonad (Expr,[Declaration])
mkExpr :: HasCallStack =>
Bool
-> DeclarationType
-> NetlistId
-> Term
-> NetlistMonad (Expr, [Declaration])
mkExpr Bool
_ DeclarationType
_ NetlistId
_ (Term -> Term
stripTicks -> Core.Literal Literal
l) = do
iw <- Getting Int NetlistEnv Int -> NetlistMonad Int
forall s (m :: Type -> Type) a.
MonadReader s m =>
Getting a s a -> m a
Lens.view Getting Int NetlistEnv Int
Getter NetlistEnv Int
intWidth
return (mkLiteral iw l, [])
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
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)
forall (m :: Type -> Type) a b.
Monad m =>
(a -> m b) -> [a] -> m [b]
mapM ([Char] -> Type -> NetlistMonad HWType
unsafeCoreTypeToHWTypeM' $(curLoc)) (NetlistId -> [Type]
netlistTypes NetlistId
bndr)
(_,sp) <- Lens.use curCompNm
let hwTyA = case [HWType]
hwTys of
HWType
hwTy:[HWType]
_ -> HWType
hwTy
[HWType]
_ -> [Char] -> HWType
forall a. HasCallStack => [Char] -> a
error ([Char]
"internal error: unable to extract sufficient hwTys from: " [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> NetlistId -> [Char]
forall a. Show a => a -> [Char]
show NetlistId
bndr)
case appF of
Data DataCon
dc -> HasCallStack =>
DeclarationType
-> [HWType]
-> NetlistId
-> DataCon
-> [Term]
-> NetlistMonad (Expr, [Declaration])
DeclarationType
-> [HWType]
-> NetlistId
-> DataCon
-> [Term]
-> NetlistMonad (Expr, [Declaration])
mkDcApplication DeclarationType
declType [HWType]
hwTys NetlistId
bndr DataCon
dc [Term]
tmArgs
Prim PrimInfo
pInfo -> Bool
-> Bool
-> DeclarationType
-> NetlistId
-> PrimInfo
-> [Either Term Type]
-> [Declaration]
-> NetlistMonad (Expr, [Declaration])
mkPrimitive Bool
False Bool
bbEasD DeclarationType
declType NetlistId
bndr PrimInfo
pInfo [Either Term Type]
args [Declaration]
tickDecls
Var Id
f
| [Term] -> Bool
forall a. [a] -> 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 a. a -> NetlistMonad a
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Expr
Noop, [])
else do
(Expr, [Declaration]) -> NetlistMonad (Expr, [Declaration])
forall a. a -> NetlistMonad a
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Identifier -> Maybe Modifier -> Expr
Identifier (HasCallStack => Id -> Identifier
Id -> Identifier
Id.unsafeFromCoreId Id
f) Maybe Modifier
forall a. Maybe a
Nothing, [])
| Bool -> Bool
not ([Type] -> Bool
forall a. [a] -> Bool
forall (t :: Type -> Type) a. Foldable t => t a -> Bool
null [Type]
tyArgs) ->
ClashException -> NetlistMonad (Expr, [Declaration])
forall a e. (HasCallStack, Exception e) => e -> a
throw (SrcSpan -> [Char] -> Maybe [Char] -> ClashException
ClashException SrcSpan
sp ($(curLoc) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"Not in normal form: "
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"Var-application with Type arguments:\n\n" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Term -> [Char]
forall p. PrettyPrec p => p -> [Char]
showPpr Term
app) Maybe [Char]
forall a. Maybe a
Nothing)
| Bool
otherwise -> do
argNm <- Identifier -> Text -> NetlistMonad Identifier
forall (m :: Type -> Type).
(HasCallStack, IdentifierSetMonad m) =>
Identifier -> Text -> m Identifier
Id.suffix ((Identifier -> Identifier)
-> (Id -> Identifier) -> NetlistId -> Identifier
forall r.
HasCallStack =>
(Identifier -> r) -> (Id -> r) -> NetlistId -> r
netlistId1 Identifier -> Identifier
forall a. a -> a
id HasCallStack => Id -> Identifier
Id -> Identifier
Id.unsafeFromCoreId NetlistId
bndr) Text
"fun_arg"
decls <- mkFunApp declType argNm f tmArgs tickDecls
if isVoid hwTyA then
return (Noop, decls)
else
return ( Identifier argNm Nothing
, NetDecl Nothing argNm hwTyA : decls)
Case Term
scrut Type
ty' [(Pat, Term)
alt] -> DeclarationType
-> Bool
-> NetlistId
-> Term
-> Type
-> (Pat, Term)
-> NetlistMonad (Expr, [Declaration])
mkProjection DeclarationType
declType Bool
bbEasD NetlistId
bndr Term
scrut Type
ty' (Pat, Term)
alt
Case Term
scrut Type
tyA ((Pat, Term)
alt:[(Pat, Term)]
alts) -> do
argNm <- Identifier -> Text -> NetlistMonad Identifier
forall (m :: Type -> Type).
(HasCallStack, IdentifierSetMonad m) =>
Identifier -> Text -> m Identifier
Id.suffix ((Identifier -> Identifier)
-> (Id -> Identifier) -> NetlistId -> Identifier
forall r.
HasCallStack =>
(Identifier -> r) -> (Id -> r) -> NetlistId -> r
netlistId1 Identifier -> Identifier
forall a. a -> a
id HasCallStack => Id -> Identifier
Id -> Identifier
Id.unsafeFromCoreId NetlistId
bndr) Text
"sel_arg"
decls <- mkSelection declType (NetlistId argNm (netlistTypes1 bndr))
scrut tyA (alt :| alts) tickDecls
if isVoid hwTyA then
return (Noop, decls)
else
return ( Identifier argNm Nothing
, NetDecl' Nothing argNm hwTyA Nothing:decls)
Letrec [LetBinding]
binders Term
body -> do
netDecls <- (LetBinding -> NetlistMonad [Declaration])
-> [LetBinding] -> NetlistMonad [Declaration]
forall (m :: Type -> Type) a b.
Monad m =>
(a -> m [b]) -> [a] -> m [b]
concatMapM LetBinding -> NetlistMonad [Declaration]
mkNetDecl [LetBinding]
binders
decls <- concatMapM (uncurry (mkDeclarations' declType)) binders
(bodyE,bodyDecls) <- mkExpr bbEasD declType bndr (mkApps (mkTicks body ticks) args)
return (bodyE,netDecls ++ decls ++ bodyDecls)
Term
_ -> ClashException -> NetlistMonad (Expr, [Declaration])
forall a e. (HasCallStack, Exception e) => e -> a
throw (SrcSpan -> [Char] -> Maybe [Char] -> ClashException
ClashException SrcSpan
sp ($(curLoc) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"Not in normal form: application of a Lambda-expression\n\n" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Term -> [Char]
forall p. PrettyPrec p => p -> [Char]
showPpr Term
app) Maybe [Char]
forall a. Maybe a
Nothing)
mkProjection
:: DeclarationType
-> Bool
-> NetlistId
-> Term
-> Type
-> Alt
-> NetlistMonad (Expr, [Declaration])
mkProjection :: DeclarationType
-> Bool
-> NetlistId
-> Term
-> Type
-> (Pat, Term)
-> NetlistMonad (Expr, [Declaration])
mkProjection DeclarationType
declType Bool
mkDec NetlistId
bndr Term
scrut Type
altTy alt :: (Pat, Term)
alt@(Pat
pat,Term
v) = do
tcm <- Getting TyConMap NetlistEnv TyConMap -> NetlistMonad TyConMap
forall s (m :: Type -> Type) a.
MonadReader s m =>
Getting a s a -> m a
Lens.view Getting TyConMap NetlistEnv TyConMap
Getter NetlistEnv TyConMap
tcCache
let assignTy = DeclarationType -> Usage
declTypeUsage DeclarationType
declType
let scrutTy = TyConMap -> Term -> Type
forall a. InferType a => TyConMap -> a -> Type
inferCoreTypeOf TyConMap
tcm Term
scrut
e = Term -> Type -> [(Pat, Term)] -> Term
Case Term
scrut Type
scrutTy [(Pat, Term)
alt]
(_,sp) <- Lens.use curCompNm
varTm <- case v of
(Var Id
n) -> Id -> NetlistMonad Id
forall a. a -> NetlistMonad a
forall (m :: Type -> Type) a. Monad m => a -> m a
return Id
n
Term
_ -> ClashException -> NetlistMonad Id
forall a e. (HasCallStack, Exception e) => e -> a
throw (SrcSpan -> [Char] -> Maybe [Char] -> ClashException
ClashException SrcSpan
sp ($(curLoc) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++
[Char]
"Not in normal form: RHS of case-projection is not a variable:\n\n"
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Term -> [Char]
forall p. PrettyPrec p => p -> [Char]
showPpr Term
e) Maybe [Char]
forall a. Maybe a
Nothing)
sHwTy <- unsafeCoreTypeToHWTypeM' $(curLoc) scrutTy
vHwTy <- unsafeCoreTypeToHWTypeM' $(curLoc) altTy
scrutRendered <- do
scrutNm <-
netlistId1
Id.next
(\Id
b -> Identifier -> Text -> NetlistMonad Identifier
forall (m :: Type -> Type).
(HasCallStack, IdentifierSetMonad m) =>
Identifier -> Text -> m Identifier
Id.suffix (HasCallStack => Id -> Identifier
Id -> Identifier
Id.unsafeFromCoreId Id
b) Text
"projection")
bndr
(scrutExpr,newDecls) <- mkExpr False declType (NetlistId scrutNm scrutTy) scrut
case scrutExpr of
Identifier Identifier
newId Maybe Modifier
modM ->
Either [Declaration] (Identifier, Maybe Modifier, [Declaration])
-> NetlistMonad
(Either [Declaration] (Identifier, Maybe Modifier, [Declaration]))
forall a. a -> NetlistMonad a
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 a. a -> NetlistMonad a
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
scrutDecl <- HasCallStack =>
DeclarationType
-> Usage
-> Identifier
-> HWType
-> Expr
-> NetlistMonad [Declaration]
DeclarationType
-> Usage
-> Identifier
-> HWType
-> Expr
-> NetlistMonad [Declaration]
mkInit DeclarationType
declType Usage
assignTy Identifier
scrutNm HWType
sHwTy Expr
scrutExpr
pure (Right (scrutNm, Nothing, newDecls ++ scrutDecl))
case scrutRendered of
Left [Declaration]
newDecls -> (Expr, [Declaration]) -> NetlistMonad (Expr, [Declaration])
forall a. a -> NetlistMonad a
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 = HasCallStack => Id -> Identifier
Id -> Identifier
Id.unsafeFromCoreId Id
varTm
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. (HasCallStack, Exception e) => e -> a
throw (SrcSpan -> [Char] -> Maybe [Char] -> ClashException
ClashException SrcSpan
sp ($(curLoc)
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"Not in normal form: Pattern binds existential variables:\n\n"
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Term -> [Char]
forall p. PrettyPrec p => p -> [Char]
showPpr Term
e) Maybe [Char]
forall a. Maybe a
Nothing)
else
[Id]
tms
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)
forall (m :: Type -> Type) a b.
Monad m =>
(a -> m b) -> [a] -> m [b]
mapM Type -> NetlistMonad (Maybe HWType)
coreTypeToHWTypeM' ((Id -> Type) -> [Id] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map Id -> Type
forall a. HasType a => a -> Type
coreTypeOf [Id]
tms)
let tmsBundled = [Maybe HWType] -> [Id] -> [(Maybe HWType, Id)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Maybe HWType]
argHWTys [Id]
tms'
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' = ((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 elemIndex varTm {varType = altTy} tmsFiltered' of
Maybe Int
Nothing -> Maybe Modifier -> NetlistMonad (Maybe Modifier)
forall a. a -> NetlistMonad a
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 a. a -> NetlistMonad a
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 a. a -> NetlistMonad a
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. (HasCallStack, Exception e) => e -> a
throw (SrcSpan -> [Char] -> Maybe [Char] -> ClashException
ClashException SrcSpan
sp ($(curLoc)
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"Not in normal form: Unexpected pattern in case-projection:\n\n"
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Term -> [Char]
forall p. PrettyPrec p => p -> [Char]
showPpr Term
e) Maybe [Char]
forall a. Maybe a
Nothing)
let 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 bndr of
NetlistId Identifier
scrutNm Type
_ | Bool
mkDec -> do
scrutNm' <- Identifier -> NetlistMonad Identifier
forall (m :: Type -> Type).
(HasCallStack, IdentifierSetMonad m) =>
Identifier -> m Identifier
Id.next Identifier
scrutNm
scrutDecl <- mkInit declType assignTy scrutNm' vHwTy extractExpr
return (Identifier scrutNm' Nothing, scrutDecl ++ decls)
MultiId {} -> [Char] -> NetlistMonad (Expr, [Declaration])
forall a. HasCallStack => [Char] -> a
error [Char]
"mkProjection: MultiId"
NetlistId
_ -> (Expr, [Declaration]) -> NetlistMonad (Expr, [Declaration])
forall a. a -> NetlistMonad a
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
=> DeclarationType
-> [HWType]
-> NetlistId
-> DataCon
-> [Term]
-> NetlistMonad (Expr,[Declaration])
mkDcApplication :: HasCallStack =>
DeclarationType
-> [HWType]
-> NetlistId
-> DataCon
-> [Term]
-> NetlistMonad (Expr, [Declaration])
mkDcApplication DeclarationType
declType [HWType
dstHType] NetlistId
bndr DataCon
dc [Term]
args = do
let dcNm :: Text
dcNm = Name DataCon -> Text
forall a. Name a -> Text
nameOcc (DataCon -> Name DataCon
dcName DataCon
dc)
tcm <- Getting TyConMap NetlistEnv TyConMap -> NetlistMonad TyConMap
forall s (m :: Type -> Type) a.
MonadReader s m =>
Getting a s a -> m a
Lens.view Getting TyConMap NetlistEnv TyConMap
Getter NetlistEnv TyConMap
tcCache
let argTys = (Term -> Type) -> [Term] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map (TyConMap -> Term -> Type
forall a. InferType a => TyConMap -> a -> Type
inferCoreTypeOf TyConMap
tcm) [Term]
args
argNm <- netlistId1 return (\Id
b -> Identifier -> Text -> NetlistMonad Identifier
forall (m :: Type -> Type).
(HasCallStack, IdentifierSetMonad m) =>
Identifier -> Text -> m Identifier
Id.suffix (HasCallStack => Id -> Identifier
Id -> Identifier
Id.unsafeFromCoreId Id
b) Text
"dc_arg") bndr
argHWTys <- mapM coreTypeToHWTypeM' argTys
(argExprs, concat -> argDecls) <- unzip <$>
mapM (\(Term
e,Type
t) -> 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
argNm Type
t) Term
e) (zip args argTys)
let
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)
(hWTysFiltered, argExprsFiltered) = unzip filteredTypeExprDecls
fmap (,argDecls) $! case (hWTysFiltered,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 a. a -> NetlistMonad a
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 Text
_ [(Text, [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 = (Text, [HWType]) -> [HWType]
forall a b. (a, b) -> b
snd ((Text, [HWType]) -> [HWType]) -> (Text, [HWType]) -> [HWType]
forall a b. (a -> b) -> a -> b
$ [Char] -> [(Text, [HWType])] -> Int -> (Text, [HWType])
forall a. HasCallStack => [Char] -> [a] -> Int -> a
indexNote ($(curLoc) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"No DC with tag: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
dcI) [(Text, [HWType])]
dcArgPairs Int
dcI
case Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare ([HWType] -> Int
forall a. [a] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length [HWType]
dcArgs) ([Expr] -> Int
forall a. [a] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length [Expr]
argExprsFiltered) of
Ordering
EQ -> Expr -> NetlistMonad Expr
forall a. a -> NetlistMonad a
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 -> [Char] -> NetlistMonad Expr
forall a. HasCallStack => [Char] -> a
error ([Char] -> NetlistMonad Expr) -> [Char] -> NetlistMonad Expr
forall a b. (a -> b) -> a -> b
$ $(curLoc) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"Over-applied constructor: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Text -> [Char]
StrictText.unpack Text
dcNm
Ordering
GT -> [Char] -> NetlistMonad Expr
forall a. HasCallStack => [Char] -> a
error ([Char] -> NetlistMonad Expr) -> [Char] -> NetlistMonad Expr
forall a b. (a -> b) -> a -> b
$ $(curLoc) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"Under-applied constructor: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Text -> [Char]
StrictText.unpack Text
dcNm
Product Text
_ Maybe [Text]
_ [HWType]
dcArgs ->
case Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare ([HWType] -> Int
forall a. [a] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length [HWType]
dcArgs) ([Expr] -> Int
forall a. [a] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length [Expr]
argExprsFiltered) of
Ordering
EQ -> Expr -> NetlistMonad Expr
forall a. a -> NetlistMonad a
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 -> [Char] -> NetlistMonad Expr
forall a. HasCallStack => [Char] -> a
error ([Char] -> NetlistMonad Expr) -> [Char] -> NetlistMonad Expr
forall a b. (a -> b) -> a -> b
$ $(curLoc) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"Over-applied constructor: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Text -> [Char]
StrictText.unpack Text
dcNm
Ordering
GT -> [Char] -> NetlistMonad Expr
forall a. HasCallStack => [Char] -> a
error ([Char] -> NetlistMonad Expr) -> [Char] -> NetlistMonad Expr
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
unlines [ $(curLoc) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"Under-applied constructor:" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Text -> [Char]
StrictText.unpack Text
dcNm
, [Char]
"dcArgs=" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [[Char]] -> [Char]
unlines [[Char]
" - " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ HWType -> [Char]
forall a. Show a => a -> [Char]
show HWType
x | HWType
x <- [HWType]
dcArgs]
, [Char]
"argExprs=" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [[Char]] -> [Char]
unlines [[Char]
" - " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Expr -> [Char]
forall a. Show a => a -> [Char]
show Expr
x | Expr
x <- [Expr]
argExprs]
, [Char]
"hWTysFilt=" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [[Char]] -> [Char]
unlines [[Char]
" - " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Maybe HWType -> [Char]
forall a. Show a => a -> [Char]
show Maybe HWType
x | Maybe HWType
x <- [Maybe HWType]
hWTysFiltered]
, [Char]
"argExprsFilt=" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [[Char]] -> [Char]
unlines [[Char]
" - " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Expr -> [Char]
forall a. Show a => a -> [Char]
show Expr
x | Expr
x <- [Expr]
argExprsFiltered]
]
CustomProduct Text
_ DataRepr'
_ Int
_ Maybe [Text]
_ [(Integer, HWType)]
dcArgs ->
case Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare ([(Integer, HWType)] -> Int
forall a. [a] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length [(Integer, HWType)]
dcArgs) ([Expr] -> Int
forall a. [a] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length [Expr]
argExprsFiltered) of
Ordering
EQ -> Expr -> NetlistMonad Expr
forall a. a -> NetlistMonad a
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 -> [Char] -> NetlistMonad Expr
forall a. HasCallStack => [Char] -> a
error ([Char] -> NetlistMonad Expr) -> [Char] -> NetlistMonad Expr
forall a b. (a -> b) -> a -> b
$ $(curLoc) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"Over-applied constructor: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Text -> [Char]
StrictText.unpack Text
dcNm
Ordering
GT -> [Char] -> NetlistMonad Expr
forall a. HasCallStack => [Char] -> a
error ([Char] -> NetlistMonad Expr) -> [Char] -> NetlistMonad Expr
forall a b. (a -> b) -> a -> b
$ $(curLoc) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"Under-applied constructor: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Text -> [Char]
StrictText.unpack Text
dcNm
Sum Text
_ [Text]
_ ->
Expr -> NetlistMonad Expr
forall a. a -> NetlistMonad a
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 Text
_ DataRepr'
_ Int
_ [(ConstrRepr', Text, [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 :: [Char]
note = $(curLoc) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"No DC with tag: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
dcI
let argTup :: (ConstrRepr', Text, [HWType])
argTup = [Char]
-> [(ConstrRepr', Text, [HWType])]
-> Int
-> (ConstrRepr', Text, [HWType])
forall a. HasCallStack => [Char] -> [a] -> Int -> a
indexNote [Char]
note [(ConstrRepr', Text, [HWType])]
dcArgsTups Int
dcI
let (ConstrRepr'
_, Text
_, [HWType]
dcArgs) = (ConstrRepr', Text, [HWType])
argTup
case Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare ([HWType] -> Int
forall a. [a] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length [HWType]
dcArgs) ([Expr] -> Int
forall a. [a] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length [Expr]
argExprsFiltered) of
Ordering
EQ -> Expr -> NetlistMonad Expr
forall a. a -> NetlistMonad a
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 -> [Char] -> NetlistMonad Expr
forall a. HasCallStack => [Char] -> a
error ([Char] -> NetlistMonad Expr) -> [Char] -> NetlistMonad Expr
forall a b. (a -> b) -> a -> b
$ $(curLoc) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"Over-applied constructor: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Text -> [Char]
StrictText.unpack Text
dcNm
Ordering
GT -> [Char] -> NetlistMonad Expr
forall a. HasCallStack => [Char] -> a
error ([Char] -> NetlistMonad Expr) -> [Char] -> NetlistMonad Expr
forall a b. (a -> b) -> a -> b
$ $(curLoc) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"Under-applied constructor: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Text -> [Char]
StrictText.unpack Text
dcNm
CustomSum Text
_ DataRepr'
_ Int
_ [(ConstrRepr', Text)]
_ ->
Expr -> NetlistMonad Expr
forall a. a -> NetlistMonad a
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)) [])
Enable Text
_ ->
case [Expr]
argExprsFiltered of
[Expr
x] -> Expr -> NetlistMonad Expr
forall a. a -> NetlistMonad a
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)) [Expr
x])
[Expr]
_ -> [Char] -> NetlistMonad Expr
forall a. HasCallStack => [Char] -> a
error ([Char] -> NetlistMonad Expr) -> [Char] -> NetlistMonad Expr
forall a b. (a -> b) -> a -> b
$ $(curLoc) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"unexpected arguments to Enable: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Expr] -> [Char]
forall a. Show a => a -> [Char]
show [Expr]
argExprsFiltered
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 -> [Char] -> Expr
forall a. HasCallStack => [Char] -> a
error ([Char] -> Expr) -> [Char] -> Expr
forall a b. (a -> b) -> a -> b
$ $(curLoc) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"unknown bool literal: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ DataCon -> [Char]
forall p. PrettyPrec p => p -> [Char]
showPpr DataCon
dc [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"(tag: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
tg [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
")"
in Expr -> NetlistMonad Expr
forall a. a -> NetlistMonad a
forall (m :: Type -> Type) a. Monad m => a -> m a
return Expr
dc'
Vector Int
0 HWType
_ -> Expr -> NetlistMonad Expr
forall a. a -> NetlistMonad a
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 a. a -> NetlistMonad a
forall (m :: Type -> Type) a. Monad m => a -> m a
return (HWType -> Modifier -> [Expr] -> Expr
HW.DataCon HWType
dstHType Modifier
VecAppend [Expr
e])
[Expr]
_ -> [Char] -> NetlistMonad Expr
forall a. HasCallStack => [Char] -> a
error ([Char] -> NetlistMonad Expr) -> [Char] -> NetlistMonad Expr
forall a b. (a -> b) -> a -> b
$ $(curLoc) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"Unexpected number of arguments for `Cons`: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Term] -> [Char]
forall p. PrettyPrec p => p -> [Char]
showPpr [Term]
args
Vector Int
_ HWType
_ -> case [Expr]
argExprsFiltered of
[Expr
e1,Expr
e2] -> Expr -> NetlistMonad Expr
forall a. a -> NetlistMonad a
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]
_ -> [Char] -> NetlistMonad Expr
forall a. HasCallStack => [Char] -> a
error ([Char] -> NetlistMonad Expr) -> [Char] -> NetlistMonad Expr
forall a b. (a -> b) -> a -> b
$ $(curLoc) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"Unexpected number of arguments for `Cons`: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Term] -> [Char]
forall p. PrettyPrec p => p -> [Char]
showPpr [Term]
args
MemBlob Int
_ Int
_ ->
case Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Int
6 ([Expr] -> Int
forall a. [a] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length [Expr]
argExprsFiltered) of
Ordering
EQ -> Expr -> NetlistMonad Expr
forall a. a -> NetlistMonad a
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 -> [Char] -> NetlistMonad Expr
forall a. HasCallStack => [Char] -> a
error ([Char] -> NetlistMonad Expr) -> [Char] -> NetlistMonad Expr
forall a b. (a -> b) -> a -> b
$ $(curLoc) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"Over-applied constructor"
Ordering
GT -> [Char] -> NetlistMonad Expr
forall a. HasCallStack => [Char] -> a
error ([Char] -> NetlistMonad Expr) -> [Char] -> NetlistMonad Expr
forall a b. (a -> b) -> a -> b
$ $(curLoc) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"Under-applied constructor"
RTree Int
0 HWType
_ -> case [Expr]
argExprsFiltered of
[Expr
e] -> Expr -> NetlistMonad Expr
forall a. a -> NetlistMonad a
forall (m :: Type -> Type) a. Monad m => a -> m a
return (HWType -> Modifier -> [Expr] -> Expr
HW.DataCon HWType
dstHType Modifier
RTreeAppend [Expr
e])
[Expr]
_ -> [Char] -> NetlistMonad Expr
forall a. HasCallStack => [Char] -> a
error ([Char] -> NetlistMonad Expr) -> [Char] -> NetlistMonad Expr
forall a b. (a -> b) -> a -> b
$ $(curLoc) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"Unexpected number of arguments for `LR`: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Term] -> [Char]
forall p. PrettyPrec p => p -> [Char]
showPpr [Term]
args
RTree Int
_ HWType
_ -> case [Expr]
argExprsFiltered of
[Expr
e1,Expr
e2] -> Expr -> NetlistMonad Expr
forall a. a -> NetlistMonad a
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]
_ -> [Char] -> NetlistMonad Expr
forall a. HasCallStack => [Char] -> a
error ([Char] -> NetlistMonad Expr) -> [Char] -> NetlistMonad Expr
forall a b. (a -> b) -> a -> b
$ $(curLoc) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"Unexpected number of arguments for `BR`: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Term] -> [Char]
forall p. PrettyPrec p => p -> [Char]
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 ([Char] -> Literal
StringLit [Char]
"")
Int
_ -> [Char] -> Expr
forall a. HasCallStack => [Char] -> a
error ([Char] -> Expr) -> [Char] -> Expr
forall a b. (a -> b) -> a -> b
$ $(curLoc) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"mkDcApplication undefined for: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ (HWType, DataCon, Int, [Term], [Maybe HWType]) -> [Char]
forall a. Show a => a -> [Char]
show (HWType
dstHType,DataCon
dc,DataCon -> Int
dcTag DataCon
dc,[Term]
args,[Maybe HWType]
argHWTys)
in Expr -> NetlistMonad Expr
forall a. a -> NetlistMonad a
forall (m :: Type -> Type) a. Monad m => a -> m a
return Expr
dc'
Void {} -> Expr -> NetlistMonad Expr
forall a. a -> NetlistMonad a
forall (m :: Type -> Type) a. Monad m => a -> m a
return Expr
Noop
Signed Int
_
#if MIN_VERSION_base(4,15,0)
| Text
dcNm Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"GHC.Num.Integer.IS"
#else
| dcNm == "GHC.Integer.Type.S#"
#endif
, (Expr
a:[Expr]
_) <- [Expr]
argExprsFiltered
-> Expr -> NetlistMonad Expr
forall a. a -> NetlistMonad a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure Expr
a
#if MIN_VERSION_base(4,15,0)
| Text
dcNm Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"GHC.Num.Integer.IP"
#else
| dcNm == "GHC.Integer.Type.Jp#"
#endif
, (a :: Expr
a@(HW.Literal Maybe (HWType, Int)
Nothing (NumLit Integer
_)):[Expr]
_) <- [Expr]
argExprs
-> Expr -> NetlistMonad Expr
forall a. a -> NetlistMonad a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure Expr
a
#if MIN_VERSION_base(4,15,0)
| Text
dcNm Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"GHC.Num.Integer.IN"
#else
| dcNm == "GHC.Integer.Type.Jn#"
#endif
, (HW.Literal Maybe (HWType, Int)
Nothing (NumLit Integer
i):[Expr]
_) <- [Expr]
argExprs
-> Expr -> NetlistMonad Expr
forall a. a -> NetlistMonad a
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
_
#if MIN_VERSION_base(4,15,0)
| Text
dcNm Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"GHC.Num.Natural.NS"
#else
| dcNm == "GHC.Natural.NatS#"
#endif
, (Expr
a:[Expr]
_) <- [Expr]
argExprsFiltered
-> Expr -> NetlistMonad Expr
forall a. a -> NetlistMonad a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure Expr
a
#if MIN_VERSION_base(4,15,0)
| Text
dcNm Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"GHC.Num.Natural.NB"
#else
| dcNm == "GHC.Natural.NatJ#"
#endif
, (a :: Expr
a@(HW.Literal Maybe (HWType, Int)
Nothing (NumLit Integer
_)):[Expr]
_) <- [Expr]
argExprs
-> Expr -> NetlistMonad Expr
forall a. a -> NetlistMonad a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure Expr
a
HWType
_ ->
[Char] -> NetlistMonad Expr
forall a. HasCallStack => [Char] -> a
error ([Char] -> NetlistMonad Expr) -> [Char] -> NetlistMonad Expr
forall a b. (a -> b) -> a -> b
$ $(curLoc) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"mkDcApplication undefined for: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ (HWType, DataCon, [Term], [Maybe HWType]) -> [Char]
forall a. Show a => a -> [Char]
show (HWType
dstHType,DataCon
dc,[Term]
args,[Maybe HWType]
argHWTys)
mkDcApplication DeclarationType
declType [HWType]
dstHTypes (MultiId [Id]
argNms) DataCon
_ [Term]
args = do
tcm <- Getting TyConMap NetlistEnv TyConMap -> NetlistMonad TyConMap
forall s (m :: Type -> Type) a.
MonadReader s m =>
Getting a s a -> m a
Lens.view Getting TyConMap NetlistEnv TyConMap
Getter NetlistEnv TyConMap
tcCache
let argTys = (Term -> Type) -> [Term] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map (TyConMap -> Term -> Type
forall a. InferType a => TyConMap -> a -> Type
inferCoreTypeOf TyConMap
tcm) [Term]
args
argHWTys <- mapM coreTypeToHWTypeM' argTys
let 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. [a] -> [b] -> [(a, b)]
zipEqual ((Id -> NetlistId) -> [Id] -> [NetlistId]
forall a b. (a -> b) -> [a] -> [b]
map Id -> NetlistId
CoreId [Id]
argNms) [Term]
args)
(_hWTysFiltered,argsFiltered) = unzip
(filter (maybe True (not . isVoid) . fst) argsBundled)
(argExprs,argDecls) <- fmap (second concat . unzip) $!
mapM (uncurry (mkExpr False declType)) argsFiltered
if length dstHTypes == length argExprs then do
assns <- mapMaybeM
(\case (NetlistId
_,Expr
Noop) -> Maybe Declaration -> NetlistMonad (Maybe Declaration)
forall a. a -> NetlistMonad a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure 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 HasCallStack => Id -> Identifier
Id -> Identifier
Id.unsafeFromCoreId 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 -> NetlistMonad (Maybe Declaration)
forall a. a -> NetlistMonad a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure Maybe Declaration
forall a. Maybe a
Nothing
Expr
_ -> Declaration -> Maybe Declaration
forall a. a -> Maybe a
Just (Declaration -> Maybe Declaration)
-> NetlistMonad Declaration -> NetlistMonad (Maybe Declaration)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> case DeclarationType
declType of
DeclarationType
Concurrent -> HasCallStack => Identifier -> Expr -> NetlistMonad Declaration
Identifier -> Expr -> NetlistMonad Declaration
contAssign Identifier
nm Expr
e
DeclarationType
Sequential -> HasCallStack =>
Blocking -> Identifier -> Expr -> NetlistMonad Declaration
Blocking -> Identifier -> Expr -> NetlistMonad Declaration
procAssign Blocking
Blocking Identifier
nm Expr
e)
(zipEqual (map CoreId argNms) argExprs)
return (Noop,argDecls ++ assns)
else
error "internal error"
mkDcApplication DeclarationType
_ [HWType]
_ NetlistId
_ DataCon
_ [Term]
_ = [Char] -> NetlistMonad (Expr, [Declaration])
forall a. HasCallStack => [Char] -> a
error [Char]
"internal error"