--------------------------------------------------------------------------------
-- Copyright © 2011 National Institute of Aerospace / Galois, Inc.
--------------------------------------------------------------------------------

-- | Bitwise operators.

{-# LANGUAGE Safe #-}

{-# OPTIONS_GHC -fno-warn-orphans #-}

module Copilot.Language.Operators.BitWise
  ( Bits ((.&.), complement, (.|.))
  , (.^.)
  , (.<<.)
  , (.>>.)
  ) where

import Copilot.Core (Typed, typeOf)
import qualified Copilot.Core as Core
import Copilot.Language.Stream
import qualified Prelude as P
import Data.Bits

instance (Typed a, Bits a) => Bits (Stream a) where
  .&. :: Stream a -> Stream a -> Stream a
(.&.)        = Op2 a a a -> Stream a -> Stream a -> Stream a
forall a b c.
(Typed a, Typed b, Typed c) =>
Op2 a b c -> Stream a -> Stream b -> Stream c
Op2 (Type a -> Op2 a a a
forall a. Bits a => Type a -> Op2 a a a
Core.BwAnd Type a
forall a. Typed a => Type a
typeOf)
  complement :: Stream a -> Stream a
complement   = Op1 a a -> Stream a -> Stream a
forall a b. (Typed a, Typed b) => Op1 a b -> Stream a -> Stream b
Op1 (Type a -> Op1 a a
forall a. Bits a => Type a -> Op1 a a
Core.BwNot Type a
forall a. Typed a => Type a
typeOf)
  .|. :: Stream a -> Stream a -> Stream a
(.|.)        = Op2 a a a -> Stream a -> Stream a -> Stream a
forall a b c.
(Typed a, Typed b, Typed c) =>
Op2 a b c -> Stream a -> Stream b -> Stream c
Op2 (Type a -> Op2 a a a
forall a. Bits a => Type a -> Op2 a a a
Core.BwOr  Type a
forall a. Typed a => Type a
typeOf)
  xor :: Stream a -> Stream a -> Stream a
xor          = Op2 a a a -> Stream a -> Stream a -> Stream a
forall a b c.
(Typed a, Typed b, Typed c) =>
Op2 a b c -> Stream a -> Stream b -> Stream c
Op2 (Type a -> Op2 a a a
forall a. Bits a => Type a -> Op2 a a a
Core.BwXor Type a
forall a. Typed a => Type a
typeOf)
  shiftL :: Stream a -> Int -> Stream a
shiftL       = [Char] -> Stream a -> Int -> Stream a
forall a. HasCallStack => [Char] -> a
P.error [Char]
"shiftL undefined, for left-shifting use .<<."
  shiftR :: Stream a -> Int -> Stream a
shiftR       = [Char] -> Stream a -> Int -> Stream a
forall a. HasCallStack => [Char] -> a
P.error [Char]
"shiftR undefined, for right-shifting use .>>."
  rotate :: Stream a -> Int -> Stream a
rotate       = [Char] -> Stream a -> Int -> Stream a
forall a. HasCallStack => [Char] -> a
P.error [Char]
"tbd: rotate"
  bitSize :: Stream a -> Int
bitSize      = [Char] -> Stream a -> Int
forall a. HasCallStack => [Char] -> a
P.error [Char]
"tbd: bitSize"
  bitSizeMaybe :: Stream a -> Maybe Int
bitSizeMaybe = [Char] -> Stream a -> Maybe Int
forall a. HasCallStack => [Char] -> a
P.error [Char]
"tbd: bitSizeMaybe"
  isSigned :: Stream a -> Bool
isSigned     = [Char] -> Stream a -> Bool
forall a. HasCallStack => [Char] -> a
P.error [Char]
"tbd: issigned"
  testBit :: Stream a -> Int -> Bool
testBit      = [Char] -> Stream a -> Int -> Bool
forall a. HasCallStack => [Char] -> a
P.error [Char]
"tbd: testBit"
  bit :: Int -> Stream a
bit          = [Char] -> Int -> Stream a
forall a. HasCallStack => [Char] -> a
P.error [Char]
"tbd: bit"
  popCount :: Stream a -> Int
popCount     = [Char] -> Stream a -> Int
forall a. HasCallStack => [Char] -> a
P.error [Char]
"tbd: popCount"

-- Avoid redefinition of the Operators.Boolean xor
(.^.) :: Bits a => a -> a -> a
.^. :: a -> a -> a
(.^.) = a -> a -> a
forall a. Bits a => a -> a -> a
xor

(.<<.), (.>>.) :: (Bits a, Typed a, Typed b, P.Integral b)
               => Stream a -> Stream b -> Stream a
.<<. :: Stream a -> Stream b -> Stream a
(.<<.) = Op2 a b a -> Stream a -> Stream b -> Stream a
forall a b c.
(Typed a, Typed b, Typed c) =>
Op2 a b c -> Stream a -> Stream b -> Stream c
Op2 (Type a -> Type b -> Op2 a b a
forall a b. (Bits a, Integral b) => Type a -> Type b -> Op2 a b a
Core.BwShiftL Type a
forall a. Typed a => Type a
typeOf Type b
forall a. Typed a => Type a
typeOf)
.>>. :: Stream a -> Stream b -> Stream a
(.>>.) = Op2 a b a -> Stream a -> Stream b -> Stream a
forall a b c.
(Typed a, Typed b, Typed c) =>
Op2 a b c -> Stream a -> Stream b -> Stream c
Op2 (Type a -> Type b -> Op2 a b a
forall a b. (Bits a, Integral b) => Type a -> Type b -> Op2 a b a
Core.BwShiftR Type a
forall a. Typed a => Type a
typeOf Type b
forall a. Typed a => Type a
typeOf)