{-# LANGUAGE CPP #-}
{-# LANGUAGE QuasiQuotes #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Language.C.Smart where
import Language.C.Quote.C
import Language.C.Syntax as C
#if !MIN_VERSION_template_haskell(2,7,0)
import qualified Data.Loc
import qualified Data.Symbol
import qualified Language.C.Syntax
#endif /* !MIN_VERSION_template_haskell(2,7,0) */
instance Enum Exp where
toEnum n = [cexp|$int:n|]
fromEnum [cexp|$int:n|] = fromIntegral n
fromEnum [cexp|$uint:n|] = fromIntegral n
fromEnum [cexp|$lint:n|] = fromIntegral n
fromEnum [cexp|$ulint:n|] = fromIntegral n
fromEnum _ =
error "fromEnum: non-integer constant C expressions"
instance Num C.Exp where
e1 + e2 = [cexp|$exp:e1 + $exp:e2|]
e1 * e2 = [cexp|$exp:e1 * $exp:e2|]
e1 - e2 = [cexp|$exp:e1 - $exp:e2|]
negate e = [cexp|-$exp:e|]
abs e = [cexp|abs($exp:e)|]
signum e = [cexp|$exp:e > 0 ? 1 : ($exp:e < 0 ? -1 : 0)|]
fromInteger n = [cexp|$int:n|]
instance Real C.Exp where
toRational [cexp|$float:n|] = toRational n
toRational [cexp|$double:n|] = toRational n
toRational [cexp|$ldouble:n|] = toRational n
toRational _ =
error "fromEnum: non-rational constant C expressions"
instance Integral C.Exp where
e1 `quotRem` e2 = ([cexp|$exp:e1 / $exp:e2|], [cexp|$exp:e1 % $exp:e2|])
toInteger [cexp|$int:n|] = n
toInteger [cexp|$uint:n|] = n
toInteger [cexp|$lint:n|] = n
toInteger [cexp|$ulint:n|] = n
toInteger _ =
error "fromInteger: non-integer constant C expressions"
instance Fractional C.Exp where
e1 / e2 = [cexp|$exp:e1 / $exp:e2|]
recip e = [cexp|1 / $exp:e|]
fromRational n = [cexp|$double:(fromRational n)|]
instance Floating C.Exp where
pi = [cexp|3.141592653589793238|]
exp e = [cexp|exp($exp:e)|]
sqrt e = [cexp|sqrt($exp:e)|]
log e = [cexp|log($exp:e)|]
e1 ** e2 = [cexp|pow($exp:e1, $exp:e2)|]
logBase e1 e2 = [cexp|log($exp:e2)/log($exp:e1)|]
sin e = [cexp|sin($exp:e)|]
tan e = [cexp|tan($exp:e)|]
cos e = [cexp|cos($exp:e)|]
asin e = [cexp|asin($exp:e)|]
atan e = [cexp|atan($exp:e)|]
acos e = [cexp|acos($exp:e)|]
sinh e = [cexp|sinh($exp:e)|]
tanh e = [cexp|tanh($exp:e)|]
cosh e = [cexp|cosh($exp:e)|]
asinh e = [cexp|asinh($exp:e)|]
atanh e = [cexp|atanh($exp:e)|]
acosh e = [cexp|acosh($exp:e)|]
infix 4 ===
(===) :: C.Exp -> C.Exp -> C.Stm
e1 === e2 = [cstm|$exp:e1 = $exp:e2;|]
infix 4 +=
(+=) :: C.Exp -> C.Exp -> C.Stm
e1 += e2 = [cstm|$exp:e1 += $exp:e2;|]