{-|
  Copyright   :  (C) 2026 QBayLogic B.V.
  License     :  BSD2 (see the file LICENSE)
  Maintainer  :  QBayLogic B.V. <devops@qbaylogic.com>

  Blackbox implementations for functions in "Clash.Sized.BitVector".
-}
{-# LANGUAGE OverloadedStrings #-}

module Clash.Primitives.Sized.BitVector (indexBitVectorCV) where

import Clash.Netlist.BlackBox (isLiteral)
import Clash.Netlist.BlackBox.Parser (runParse)
import Clash.Netlist.BlackBox.Types
  ( BlackBoxFunction
  , BlackBoxMeta (..)
  , TemplateKind (TExpr)
  , emptyBlackBoxMeta
  )
import Clash.Netlist.Types (BlackBox (BBTemplate))
import Text.Trifecta.Result (Result (Success))

-- index# :: KnownNat n => BitVector n -> Int -> Bit
indexBitVectorCV :: BlackBoxFunction
indexBitVectorCV :: BlackBoxFunction
indexBitVectorCV Bool
_isD Text
_primName [Either Term Type]
args [Type]
_ty =
  Either String (BlackBoxMeta, BlackBox)
-> NetlistMonad (Either String (BlackBoxMeta, BlackBox))
forall a. a -> NetlistMonad a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Either String (BlackBoxMeta, BlackBox)
 -> NetlistMonad (Either String (BlackBoxMeta, BlackBox)))
-> Either String (BlackBoxMeta, BlackBox)
-> NetlistMonad (Either String (BlackBoxMeta, BlackBox))
forall a b. (a -> b) -> a -> b
$ case Text -> Result BlackBoxTemplate
runParse Text
template of
    Success BlackBoxTemplate
t -> (BlackBoxMeta, BlackBox) -> Either String (BlackBoxMeta, BlackBox)
forall a b. b -> Either a b
Right (BlackBoxMeta
emptyBlackBoxMeta{bbKind = TExpr}, BlackBoxTemplate -> BlackBox
BBTemplate BlackBoxTemplate
t)
    Result BlackBoxTemplate
_ -> String -> Either String (BlackBoxMeta, BlackBox)
forall a b. a -> Either a b
Left String
"indexBitVectorCV: could not parse index template"
 where
  -- Select the template before validation: a ~LIT inside a ~IF would also
  -- require a literal argument when that branch is not selected.
  template :: Text
template
    | [Either Term Type
_nTy, Either Term Type
_kn, Either Term Type
_bv, Left Term
ix] <- [Either Term Type]
args
    , Term -> Bool
isLiteral Term
ix
    = Text
"~VAR[bv][1][~LIT[2]]"
    | Bool
otherwise
    = Text
"~VAR[bv][1][~ARG[2]]"