{-|
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 :: Text
-> Type -> WorkInfo -> IsMultiPrim -> PrimUnfolding -> PrimInfo
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 :: Text
-> Type -> WorkInfo -> IsMultiPrim -> PrimUnfolding -> PrimInfo
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 :: Text
-> Type -> WorkInfo -> IsMultiPrim -> PrimUnfolding -> PrimInfo
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
  }