    {-|
    Copyright   : (C) 2021, QBayLogic B.V.,
                      2022, Google Inc.
    License     : BSD2 (see the file LICENSE)
    Maintainer  : QBayLogic B.V. <devops@qbaylogic.com>

    Special primitives created during the normalization process.
    -}

    {-# LANGUAGE TemplateHaskellQuotes #-}

    module Clash.Normalize.Primitives
      ( removedArg
      , undefined
      , undefinedX
      ) where

    import Prelude hiding (undefined)

    import qualified Data.Text.Extra as Text

    import Clash.Core.Term (IsMultiPrim(..), PrimInfo(..), PrimUnfolding(..), WorkInfo(..))
    import Clash.Core.Util (undefinedTy)

    -- | The removedArg primitive represents an argument which is computationally
    -- irrelevant, and has been removed from the circuit (as removing it does not
    -- change the behaviour of the circuit). Examples of such arguments are unused
    -- arguments to blackboxes, as removing them does not affect the rendered HDL.
    --
    removedArg :: PrimInfo
    removedArg :: PrimInfo
    removedArg = PrimInfo
      { primName :: Text
    primName = Name -> Text
    forall a. Show a => a -> Text
    Text.showt 'removedArg
      , primType :: Type
    primType = Type
    undefinedTy
      , primWorkInfo :: WorkInfo
    primWorkInfo = WorkInfo
    WorkNever
      , primMultiResult :: IsMultiPrim
    primMultiResult = IsMultiPrim
    SingleResult
      , primUnfolding :: PrimUnfolding
    primUnfolding = PrimUnfolding
    NoUnfolding
      }

    -- | The undefined primitive represents an undefined value that was identified
    -- during normalization. This includes undefined results to compile-time
    -- evaluation, such as division by zero.
    --
    undefined :: PrimInfo
    undefined :: PrimInfo
    undefined = PrimInfo
      { primName :: Text
    primName = Name -> Text
    forall a. Show a => a -> Text
    Text.showt 'undefined
      , primType :: Type
    primType = Type
    undefinedTy
      , primWorkInfo :: WorkInfo
    primWorkInfo = WorkInfo
    WorkNever
      , primMultiResult :: IsMultiPrim
    primMultiResult = IsMultiPrim
    SingleResult
      , primUnfolding :: PrimUnfolding
    primUnfolding = PrimUnfolding
    NoUnfolding
      }

    -- | The undefinedX primitive represents an X-exception throwing value that was
    -- identified during normalization.
    --
    undefinedX :: PrimInfo
    undefinedX :: PrimInfo
    undefinedX = PrimInfo
      { primName :: Text
    primName = Name -> Text
    forall a. Show a => a -> Text
    Text.showt 'undefinedX
      , primType :: Type
    primType = Type
    undefinedTy
      , primWorkInfo :: WorkInfo
    primWorkInfo = WorkInfo
    WorkNever
      , primMultiResult :: IsMultiPrim
    primMultiResult = IsMultiPrim
    SingleResult
      , primUnfolding :: PrimUnfolding
    primUnfolding = PrimUnfolding
    NoUnfolding
      }