{-|
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 (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 (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 (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 (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
$ $(String
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