{-|
  Copyright   :  (C) 2013-2016, University of Twente,
                     2016-2017, Myrtle Software Ltd,
                     2017-2022, Google Inc.,
                     2017-2026, QBayLogic B.V.
  License     :  BSD2 (see the file LICENSE)
  Maintainer  :  QBayLogic B.V. <devops@qbaylogic.com>
-}

module Clash.GHC.Evaluator.Primitives
  ( ghcPrimStepImpls
  ) where

import qualified Data.HashMap.Strict as HashMap
import           Data.Text           (Text)

import           Clash.Core.Evaluator.Types

import qualified Clash.GHC.Evaluator.Primitives.Clash.Annotations.BitRepresentation.Deriving as Clash.Annotations.BitRepresentation.Deriving
import qualified Clash.GHC.Evaluator.Primitives.Clash.Class.BitPack.Internal as Clash.Class.BitPack.Internal
import qualified Clash.GHC.Evaluator.Primitives.Clash.Class.Exp as Clash.Class.Exp
import qualified Clash.GHC.Evaluator.Primitives.Clash.Promoted.Nat as Clash.Promoted.Nat
import qualified Clash.GHC.Evaluator.Primitives.Clash.Sized.Internal.BitVector as Clash.Sized.Internal.BitVector
import qualified Clash.GHC.Evaluator.Primitives.Clash.Sized.Internal.Index as Clash.Sized.Internal.Index
import qualified Clash.GHC.Evaluator.Primitives.Clash.Sized.Internal.Signed as Clash.Sized.Internal.Signed
import qualified Clash.GHC.Evaluator.Primitives.Clash.Sized.Internal.Unsigned as Clash.Sized.Internal.Unsigned
import qualified Clash.GHC.Evaluator.Primitives.Clash.Sized.RTree as Clash.Sized.RTree
import qualified Clash.GHC.Evaluator.Primitives.Clash.Sized.Vector as Clash.Sized.Vector
import qualified Clash.GHC.Evaluator.Primitives.Data.Singletons.TypeLits.Internal as Data.Singletons.TypeLits.Internal
import qualified Clash.GHC.Evaluator.Primitives.Data.Text.Show as Data.Text.Show
import qualified Clash.GHC.Evaluator.Primitives.GHC.Base as GHC.Base
import qualified Clash.GHC.Evaluator.Primitives.GHC.Classes as GHC.Classes
import qualified Clash.GHC.Evaluator.Primitives.GHC.Float as GHC.Float
import qualified Clash.GHC.Evaluator.Primitives.GHC.Int as GHC.Int
import qualified Clash.GHC.Evaluator.Primitives.GHC.Internal.Float as GHC.Internal.Float
import qualified Clash.GHC.Evaluator.Primitives.GHC.Internal.Real as GHC.Internal.Real
import qualified Clash.GHC.Evaluator.Primitives.GHC.Magic as GHC.Magic
import qualified Clash.GHC.Evaluator.Primitives.GHC.Num as GHC.Num
import qualified Clash.GHC.Evaluator.Primitives.GHC.Num.BigNat as GHC.Num.BigNat
import qualified Clash.GHC.Evaluator.Primitives.GHC.Num.Integer as GHC.Num.Integer
import qualified Clash.GHC.Evaluator.Primitives.GHC.Num.Natural as GHC.Num.Natural
import qualified Clash.GHC.Evaluator.Primitives.GHC.Prim as GHC.Prim
import qualified Clash.GHC.Evaluator.Primitives.GHC.PrimopWrappers as GHC.PrimopWrappers
import qualified Clash.GHC.Evaluator.Primitives.GHC.Real as GHC.Real
import qualified Clash.GHC.Evaluator.Primitives.GHC.TypeLits as GHC.TypeLits
import qualified Clash.GHC.Evaluator.Primitives.GHC.TypeNats as GHC.TypeNats
import qualified Clash.GHC.Evaluator.Primitives.GHC.Types as GHC.Types
import qualified Clash.GHC.Evaluator.Primitives.GHC.Word as GHC.Word

-- | All primitive evaluation rules of the GHC frontend, indexed by primitive
-- name. Errors if multiple implementations are registered under the same name.
ghcPrimStepImpls :: HashMap.HashMap Text PrimStep
ghcPrimStepImpls :: HashMap Text PrimStep
ghcPrimStepImpls
  | HashMap Text Int -> Bool
forall k v. HashMap k v -> Bool
HashMap.null HashMap Text Int
duplicateNames = [(Text, PrimStep)] -> HashMap Text PrimStep
forall k v. Hashable k => [(k, v)] -> HashMap k v
HashMap.fromList [(Text, PrimStep)]
allPrimitives
  | Bool
otherwise = [Char] -> HashMap Text PrimStep
forall a. HasCallStack => [Char] -> a
error ([Char] -> HashMap Text PrimStep)
-> [Char] -> HashMap Text PrimStep
forall a b. (a -> b) -> a -> b
$
      [Char]
"ghcPrimStepImpls: multiple implementations registered for: "
        [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Text] -> [Char]
forall a. Show a => a -> [Char]
show (HashMap Text Int -> [Text]
forall k v. HashMap k v -> [k]
HashMap.keys HashMap Text Int
duplicateNames)
 where
  duplicateNames :: HashMap Text Int
duplicateNames =
    (Int -> Bool) -> HashMap Text Int -> HashMap Text Int
forall v k. (v -> Bool) -> HashMap k v -> HashMap k v
HashMap.filter (Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1) (HashMap Text Int -> HashMap Text Int)
-> HashMap Text Int -> HashMap Text Int
forall a b. (a -> b) -> a -> b
$
      (Int -> Int -> Int) -> [(Text, Int)] -> HashMap Text Int
forall k v. Hashable k => (v -> v -> v) -> [(k, v)] -> HashMap k v
HashMap.fromListWith Int -> Int -> Int
forall a. Num a => a -> a -> a
(+) [(Text
name, Int
1 :: Int) | (Text
name, PrimStep
_) <- [(Text, PrimStep)]
allPrimitives]

  allPrimitives :: [(Text, PrimStep)]
  allPrimitives :: [(Text, PrimStep)]
allPrimitives = [[(Text, PrimStep)]] -> [(Text, PrimStep)]
forall (t :: Type -> Type) a. Foldable t => t [a] -> [a]
concat
    [ [(Text, PrimStep)]
Clash.Annotations.BitRepresentation.Deriving.primitives
    , [(Text, PrimStep)]
Clash.Class.BitPack.Internal.primitives
    , [(Text, PrimStep)]
Clash.Class.Exp.primitives
    , [(Text, PrimStep)]
Clash.Promoted.Nat.primitives
    , [(Text, PrimStep)]
Clash.Sized.Internal.BitVector.primitives
    , [(Text, PrimStep)]
Clash.Sized.Internal.Index.primitives
    , [(Text, PrimStep)]
Clash.Sized.Internal.Signed.primitives
    , [(Text, PrimStep)]
Clash.Sized.Internal.Unsigned.primitives
    , [(Text, PrimStep)]
Clash.Sized.RTree.primitives
    , [(Text, PrimStep)]
Clash.Sized.Vector.primitives
    , [(Text, PrimStep)]
Data.Singletons.TypeLits.Internal.primitives
    , [(Text, PrimStep)]
Data.Text.Show.primitives
    , [(Text, PrimStep)]
GHC.Base.primitives
    , [(Text, PrimStep)]
GHC.Classes.primitives
    , [(Text, PrimStep)]
GHC.Float.primitives
    , [(Text, PrimStep)]
GHC.Int.primitives
    , [(Text, PrimStep)]
GHC.Internal.Float.primitives
    , [(Text, PrimStep)]
GHC.Internal.Real.primitives
    , [(Text, PrimStep)]
GHC.Magic.primitives
    , [(Text, PrimStep)]
GHC.Num.primitives
    , [(Text, PrimStep)]
GHC.Num.BigNat.primitives
    , [(Text, PrimStep)]
GHC.Num.Integer.primitives
    , [(Text, PrimStep)]
GHC.Num.Natural.primitives
    , [(Text, PrimStep)]
GHC.Prim.primitives
    , [(Text, PrimStep)]
GHC.PrimopWrappers.primitives
    , [(Text, PrimStep)]
GHC.Real.primitives
    , [(Text, PrimStep)]
GHC.TypeLits.primitives
    , [(Text, PrimStep)]
GHC.TypeNats.primitives
    , [(Text, PrimStep)]
GHC.Types.primitives
    , [(Text, PrimStep)]
GHC.Word.primitives
    ]