{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE Rank2Types #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE UndecidableInstances #-} module Synthesizer.LLVM.Parameterized.Value where import qualified Synthesizer.LLVM.Simple.Value as Value import LLVM.Core hiding (zero, ) import LLVM.Util.Arithmetic (TValue, ) import qualified LLVM.Util.Arithmetic as Arith {- import qualified Synthesizer.Basic.Phase as Phase import qualified Synthesizer.LLVM.Frame.Stereo as Stereo import Control.Monad (liftM2, liftM3, ) -} import qualified Algebra.Transcendental as Trans import qualified Algebra.Algebraic as Algebraic -- import qualified Algebra.RealRing as RealRing import qualified Algebra.Field as Field import qualified Algebra.Ring as Ring import qualified Algebra.Additive as Additive import NumericPrelude.Numeric import NumericPrelude.Base hiding (map, zipWith, writeFile, ) newtype T p a = Cons {decons :: forall r. p -> TValue r a} instance (Additive.C a, IsArithmetic a, IsConst a) => Additive.C (T p a) where zero = lift0 zero (+) = lift2 (+) (-) = lift2 (-) negate = lift1 negate instance (Ring.C a, IsArithmetic a, IsConst a) => Ring.C (T p a) where one = lift0 one (*) = lift2 (*) fromInteger = constant . fromInteger instance (Ring.C a, IsArithmetic a, IsConst a) => Enum (T p a) where succ x = x + one pred x = x - one fromEnum _ = error "CodeGenFunction Value: fromEnum" toEnum = fromIntegral {- instance (IsArithmetic a, Cmp a b, Num a, IsConst a) => Real (T p a) where toRational _ = error "CodeGenFunction Value: toRational" instance (Cmp a b, Num a, IsConst a, IsInteger a) => Integral (T p a) where quot = binop (if (isSigned (undefined :: a)) then sdiv else udiv) rem = binop (if (isSigned (undefined :: a)) then srem else urem) quotRem x y = (quot x y, rem x y) toInteger _ = error "CodeGenFunction Value: toInteger" -} instance (Field.C a, IsConst a, IsFloating a) => Field.C (T p a) where (/) = lift2 (/) fromRational' = constant . fromRational' {- instance (Cmp a b, Fractional a, IsConst a, IsFloating a) => RealFrac (T p a) where properFraction _ = error "CodeGenFunction Value: properFraction" -} instance (Algebraic.C a, IsConst a, IsFloating a) => Algebraic.C (T p a) where sqrt = lift1 sqrt instance (Trans.C a, IsConst a, IsFloating a) => Trans.C (T p a) where pi = constant pi sin = lift1 sin cos = lift1 cos tan = lift1 tan asin = lift1 asin acos = lift1 acos atan = lift1 atan sinh = lift1 sinh cosh = lift1 cosh asinh = lift1 asinh acosh = lift1 acosh atanh = lift1 atanh (**) = lift2 (**) exp = lift1 exp log = lift1 log twoPi :: (Trans.C a, IsConst a, IsFloating a) => T p a twoPi = 2*pi {- twoPi :: (Cmp a b, P.Floating a, IsConst a, IsFloating a) => TValue r a twoPi = P.fromInteger 2 P.* P.pi -} lift0 :: Value.T a -> T p a lift0 x = Cons $ const $ Value.decons x lift1 :: (Value.T a -> Value.T b) -> (T p a -> T p b) lift1 f x = Cons (\p -> Value.decons $ f (Value.Cons $ decons x p)) lift2 :: (Value.T a -> Value.T b -> Value.T c) -> (T p a -> T p b -> T p c) lift2 f x y = Cons $ \p -> Value.decons $ f (Value.Cons $ decons x p) (Value.Cons $ decons y p) constantValue :: Value a -> T p a constantValue x = Cons (const $ return x) constant :: (IsConst a) => a -> T p a constant = constantValue . valueOf choose :: (IsConst a) => (p -> a) -> T p a choose x = Cons (return . valueOf . x)