    {-|
    Copyright  :  (C) 2018, Google Inc.
                      2022, LUMI GUIDE FIETSDETECTIE B.V.
    License    :  BSD2 (see the file LICENSE)
    Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>

    Houses internal BitRepresentation code which cannot be housed in clash-prelude
    due to its dependencies.
    -}

    {-# LANGUAGE TemplateHaskell #-}

    module Clash.Annotations.BitRepresentation.ClashLib
      ( coreToType'
      , bitsToBits
      ) where

    import           Clash.Annotations.BitRepresentation.Internal
      (Type'(..))
    import qualified Clash.Annotations.BitRepresentation.Util as BitRepresentation
    import qualified Clash.Core.Type                          as C
    import           Clash.Core.Name                          (nameOcc)
    import qualified Clash.Netlist.Types                      as Netlist
    import           Clash.Util                               (curLoc)
    import qualified Data.Text as T                           (pack)

    -- Convert Core type to BitRepresentation type
    coreToType'
      :: C.Type
      -- ^ Type to convert to bit representation type
      -> Either
           String
           -- Error message
           Type'
           -- Bit representation type
    coreToType' :: Type -> Either String Type'
    coreToType' (C.AppTy Type
    t1 Type
    t2) =
      Type' -> Type' -> Type'
    AppTy' (Type' -> Type' -> Type')
    -> Either String Type' -> Either String (Type' -> Type')
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    <$> Type -> Either String Type'
    coreToType' Type
    t1 Either String (Type' -> Type')
    -> Either String Type' -> Either String Type'
    forall a b.
    Either String (a -> b) -> Either String a -> Either String b
    forall (f :: Type -> Type) a b.
    Applicative f =>
    f (a -> b) -> f a -> f b
    <*> Type -> Either String Type'
    coreToType' Type
    t2
    coreToType' (C.ConstTy (C.TyCon TyConName
    name)) =
      Type' -> Either String Type'
    forall a. a -> Either String a
    forall (m :: Type -> Type) a. Monad m => a -> m a
    return (Type' -> Either String Type') -> Type' -> Either String Type'
    forall a b. (a -> b) -> a -> b
    $ Text -> Type'
    ConstTy' (TyConName -> Text
    forall a. Name a -> Text
    nameOcc TyConName
    name)
    coreToType' (C.LitTy (C.NumTy Integer
    n)) =
      Type' -> Either String Type'
    forall a. a -> Either String a
    forall (m :: Type -> Type) a. Monad m => a -> m a
    return (Type' -> Either String Type') -> Type' -> Either String Type'
    forall a b. (a -> b) -> a -> b
    $ Integer -> Type'
    LitTy' Integer
    n
    coreToType' (C.LitTy (C.SymTy String
    lit)) =
      Type' -> Either String Type'
    forall a. a -> Either String a
    forall (m :: Type -> Type) a. Monad m => a -> m a
    return (Type' -> Either String Type') -> Type' -> Either String Type'
    forall a b. (a -> b) -> a -> b
    $ Text -> Type'
    SymLitTy' (String -> Text
    T.pack String
    lit)
    coreToType' Type
    e =
      String -> Either String Type'
    forall a b. a -> Either a b
    Left (String -> Either String Type') -> String -> Either String Type'
    forall a b. (a -> b) -> a -> b
    $ $(curLoc) String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    "Unexpected type: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Type -> String
    forall a. Show a => a -> String
    show Type
    e

    bitToBit
      :: BitRepresentation.Bit
      -> Netlist.Bit
    bitToBit :: Bit -> Bit
    bitToBit Bit
    BitRepresentation.H = Bit
    Netlist.H
    bitToBit Bit
    BitRepresentation.L = Bit
    Netlist.L
    bitToBit Bit
    BitRepresentation.U = Bit
    Netlist.U

    -- | Converts a list of /BitRepresentation.Bit/s to their Netlist counterpart.
    bitsToBits
      :: [BitRepresentation.Bit]
      -> [Netlist.Bit]
    bitsToBits :: [Bit] -> [Bit]
    bitsToBits = (Bit -> Bit) -> [Bit] -> [Bit]
    forall a b. (a -> b) -> [a] -> [b]
    map Bit -> Bit
    bitToBit