content: {-# LANGUAGE OverloadedStrings #-}
  {-# LANGUAGE QuasiQuotes #-}
  {-# LANGUAGE TemplateHaskell #-}
  {-# LANGUAGE TypeFamilies #-}
  
  module Clash.Tests.DerivingDataRepr where
  
  import Test.Tasty
  import Test.Tasty.HUnit
  import Prelude ((=<<), ($))
  import Clash.Annotations.BitRepresentation
  import Clash.Annotations.BitRepresentation.Deriving
  import Clash.Tests.DerivingDataReprTypes (Train(..), RGB(..), Headphones(..), EarCup(..))
  import Data.Maybe (Maybe(..))
  
  ---------------------------------------------------------
  ------------ DERIVING SIMPLE REPRESENTATIONS ------------
  ---------------------------------------------------------
  oneHotOverlapLRepr :: DataReprAnn
  oneHotOverlapLRepr = $( (simpleDerivator OneHot OverlapL) =<< [t| Train |] )
  
  oneHotOverlapLRepr' :: DataReprAnn
  oneHotOverlapLRepr' =
    DataReprAnn
      $(liftQ [t| Train |])
      8
      [ ConstrRepr 'Passenger   16  16  [0b1100]
      , ConstrRepr 'Freight     32  32  [0b1100, 0b0011]
      , ConstrRepr 'Maintenance 64  64  []
      , ConstrRepr 'Toy         128 128 []
      ]
  
  oneHotOverlapRRepr :: DataReprAnn
  oneHotOverlapRRepr = $( (simpleDerivator OneHot OverlapR) =<< [t| Train |] )
  
  oneHotOverlapRRepr' :: DataReprAnn
  oneHotOverlapRRepr' =
    DataReprAnn
      $(liftQ [t| Train |])
      8
      [ ConstrRepr 'Passenger   16  16  [0b0011]
      , ConstrRepr 'Freight     32  32  [0b1100, 0b0011]
      , ConstrRepr 'Maintenance 64  64  []
      , ConstrRepr 'Toy         128 128 []
      ]
  
  oneHotOverlapReprRec :: DataReprAnn
  oneHotOverlapReprRec = $( (simpleDerivator OneHot OverlapL) =<< [t| Headphones |] )
  
  oneHotOverlapReprRec' :: DataReprAnn
  oneHotOverlapReprRec' =
    DataReprAnn
      $(liftQ [t| Headphones |])
      4
      [ ConstrRepr 'InEar   4  4  [0b10]
      , ConstrRepr 'OverEar 8  8  [0b11]
      ]
  
  oneHotOverlapReprInfix :: DataReprAnn
  oneHotOverlapReprInfix = $( (simpleDerivator OneHot OverlapL) =<< [t| EarCup |] )
  
  oneHotOverlapReprInfix' :: DataReprAnn
  oneHotOverlapReprInfix' =
    DataReprAnn
      $(liftQ [t| EarCup |])
      5
      [ ConstrRepr '(:<>:) 16  16  [0b1100,0b0011] ]
  
  
  oneHotWideRepr :: DataReprAnn
  oneHotWideRepr = $( (simpleDerivator OneHot Wide) =<< [t| Train |] )
  
  oneHotWideRepr' :: DataReprAnn
  oneHotWideRepr' =
    DataReprAnn
      $(liftQ [t| Train |])
      10
      [ ConstrRepr 'Passenger   64  64  [0b110000]
      , ConstrRepr 'Freight     128 128 [0b001100, 0b000011]
      , ConstrRepr 'Maintenance 256 256 []
      , ConstrRepr 'Toy         512 512 []
      ]
  
  countOverlapRepr :: DataReprAnn
  countOverlapRepr = $( (simpleDerivator Binary OverlapL) =<< [t| Train |] )
  
  countOverlapRepr' :: DataReprAnn
  countOverlapRepr' =
    DataReprAnn
      $(liftQ [t| Train |])
      6
      [ ConstrRepr 'Passenger   0b110000 0b000000 [0b001100]
      , ConstrRepr 'Freight     0b110000 0b010000 [0b001100,0b000011]
      , ConstrRepr 'Maintenance 0b110000 0b100000 []
      , ConstrRepr 'Toy         0b110000 0b110000 []
      ]
  
  countWideRepr :: DataReprAnn
  countWideRepr = $( (simpleDerivator Binary Wide) =<< [t| Train |] )
  
  countWideRepr' :: DataReprAnn
  countWideRepr' =
    DataReprAnn
      $(liftQ [t| Train |])
      8
      [ ConstrRepr 'Passenger   0b11000000 0b00000000 [0b110000]
      , ConstrRepr 'Freight     0b11000000 0b01000000 [0b001100,0b000011]
      , ConstrRepr 'Maintenance 0b11000000 0b10000000 []
      , ConstrRepr 'Toy         0b11000000 0b11000000 []
      ]
  
  ------------------------------------------------
  ------------ PACKED REPRESENTATIONS ------------
  ------------------------------------------------
  
  packedRepr :: DataReprAnn
  packedRepr = $( packedDerivator =<< [t| Train |] )
  
  packedRepr' :: DataReprAnn
  packedRepr' =
    DataReprAnn
      $(liftQ [t| Train |])
      5
      [ ConstrRepr 'Freight     0b10000 0 [12,3]
      , ConstrRepr 'Passenger   3       1 [12]
      , ConstrRepr 'Toy         3       2 []
      , ConstrRepr 'Maintenance 3       3 []
      ]
  
  ------------------------------------------------------
  ------------ PACKED MAYBE REPRESENTATIONS ------------
  ------------------------------------------------------
  
  packedMaybeRGB :: DataReprAnn
  packedMaybeRGB = $( packedMaybeDerivator $(defaultDerivator =<< [t| Maybe RGB |]) =<< [t| Maybe RGB |] )
  
  packedMaybeRGB' :: DataReprAnn
  packedMaybeRGB' =
    DataReprAnn
      $(liftQ [t| Maybe RGB |])
      2
      [ ConstrRepr 'Nothing 0b11 0b11 []
      , ConstrRepr 'Just    0b00 0b00 [0b11]
      ]
  
  -- MAIN
  tests :: TestTree
  tests = testGroup "DerivingDataRepr"
    [ testCase "OneHotOverlapL"     $ oneHotOverlapLRepr     @?= oneHotOverlapLRepr'
    , testCase "OneHotOverlapR"     $ oneHotOverlapRRepr     @?= oneHotOverlapRRepr'
    , testCase "OneHotOverlapRec"   $ oneHotOverlapReprRec   @?= oneHotOverlapReprRec'
    , testCase "OneHotOverlapInfix" $ oneHotOverlapReprInfix @?= oneHotOverlapReprInfix'
    , testCase "OneHotWide"         $ oneHotWideRepr         @?= oneHotWideRepr'
    , testCase "BinaryOverlap"      $ countOverlapRepr       @?= countOverlapRepr'
    , testCase "BinaryWide"         $ countWideRepr          @?= countWideRepr'
    , testCase "Packed"             $ packedRepr             @?= packedRepr'
    , testCase "PackedMaybe"        $ packedMaybeRGB         @?= packedMaybeRGB'
    ]
  