module Language.Copilot.Language (
mod, div, mod0, div0,
(<), (<=), (==), (/=), (>=), (>),
not, (||), (&&), (^), (==>),
Bool(..),
Num(..),
Fractional((/)),
mux,
var, varB, varI8, varI16, varI32, varI64,
varW8, varW16, varW32, varW64, varF, varD,
const, constI8, constI16, constI32, constI64,
constW8, constW16, constW32, constW64, constF, constD,
true, false,
module Language.Copilot.Language.Sampling,
drop, (++), (.=),
module Language.Copilot.Language.FunctionCalls,
module Language.Copilot.Language.Casting,
notConstVarErr
) where
import qualified Language.Atom as A
import Data.Int
import Data.Word
import Prelude ( Bool(..), Num(..), Float, Double, ($), error
, Fractional(..), fromInteger, Show(..))
import qualified Prelude as P
import Control.Monad.Writer (tell)
import qualified Data.Map as M
import Language.Copilot.Core
import Language.Copilot.Language.Sampling
import Language.Copilot.Language.Casting
import Language.Copilot.Language.FunctionCalls
not :: Spec Bool -> Spec Bool
not = F P.not A.not_
mod, div :: (Streamable a, A.IntegralE a) => Spec a -> Spec a -> Spec a
mod = F2 P.mod A.mod_
div = F2 P.div A.div_
mod0, div0 :: (Streamable a, A.IntegralE a) => a -> Spec a -> Spec a -> Spec a
mod0 d = F2 (\ x0 x1 -> if x1 P.== 0 then x0 `P.div` d
else x0 `P.div` x1)
(\ e0 e1 -> A.mod0_ e0 e1 d)
div0 d = F2 (\ x0 x1 -> if x1 P.== 0 then x0 `P.mod` d
else x0 `P.mod` x1)
(\ e0 e1 -> A.div0_ e0 e1 d)
(<), (<=), (>=), (>) :: (Streamable a, A.OrdE a) => Spec a -> Spec a -> Spec Bool
(<) = F2 (P.<) (A.<.)
(<=) = F2 (P.<=) (A.<=.)
(>=) = F2 (P.>=) (A.>=.)
(>) = F2 (P.>) (A.>.)
(==), (/=) :: (Streamable a, A.EqE a) => Spec a -> Spec a -> Spec Bool
(==) = F2 (P.==) (A.==.)
(/=) = F2 (P./=) (A./=.)
(||), (&&), (^), (==>) :: Spec Bool -> Spec Bool -> Spec Bool
(||) = F2 (P.||) (A.||.)
(&&) = F2 (P.&&) (A.&&.)
(^) = F2
(\ x y -> (x P.&& P.not y) P.|| (y P.&& P.not x))
(\ x y -> (x A.&&. A.not_ y) A.||. (y A.&&. A.not_ x))
(==>) = F2 (\ x y -> y P.|| P.not x) A.imply
mux :: (Streamable a) => Spec Bool -> Spec a -> Spec a -> Spec a
mux = F3 (\ b x y -> if b then x else y) A.mux
infix 5 ==, /=, <, <=, >=, >
infixr 4 ||, &&, ^, ==>
var :: Streamable a => Var -> Spec a
var = Var
varB :: Var -> Spec Bool
varB = Var
varI8 :: Var -> Spec Int8
varI8 = Var
varI16 :: Var -> Spec Int16
varI16 = Var
varI32 :: Var -> Spec Int32
varI32 = Var
varI64 :: Var -> Spec Int64
varI64 = Var
varW8 :: Var -> Spec Word8
varW8 = Var
varW16 :: Var -> Spec Word16
varW16 = Var
varW32 :: Var -> Spec Word32
varW32 = Var
varW64 :: Var -> Spec Word64
varW64 = Var
varF :: Var -> Spec Float
varF = Var
varD :: Var -> Spec Double
varD = Var
(.=) :: Streamable a => Spec a -> Spec a -> Streams
v .= s =
case v of
(Var v') -> tell $ LangElems (updateSubMap (M.insert v' s) emptySM)
M.empty
_ -> error $ "Given spec " P.++ show v
P.++ " but expected a variable in a Copilot definition (.=)."
const :: Streamable a => a -> Spec a
const = Const
constI8 :: Int8 -> Spec Int8
constI8 = Const
constI16 :: Int16 -> Spec Int16
constI16 = Const
constI32 :: Int32 -> Spec Int32
constI32 = Const
constI64 :: Int64 -> Spec Int64
constI64 = Const
constW8 :: Word8 -> Spec Word8
constW8 = Const
constW16 :: Word16 -> Spec Word16
constW16 = Const
constW32 :: Word32 -> Spec Word32
constW32 = Const
constW64 :: Word64 -> Spec Word64
constW64 = Const
constF :: Float -> Spec Float
constF = Const
constD :: Double -> Spec Double
constD = Const
true, false :: Spec Bool
true = Const True
false = Const False
drop :: Streamable a => Int -> Spec a -> Spec a
drop i s = Drop i s
(++) :: Streamable a => [a] -> Spec a -> Spec a
ls ++ s = Append ls s
infixr 3 ++
infixr 2 .=