syntactic-0.7: CEFP/MuFeldspar/Frontend.hs
{-# OPTIONS_GHC -fcontext-stack=30 #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE ViewPatterns #-}
module MuFeldspar.Frontend where
import Data.Bits (Bits)
import Language.Syntactic
import Language.Syntactic.Constructs.Symbol
import Language.Syntactic.Constructs.Literal
import Language.Syntactic.Constructs.Condition
import Language.Syntactic.Constructs.TupleSyntacticPoly
import Language.Syntactic.Constructs.Binding
import Language.Syntactic.Constructs.Binding.HigherOrder
import MuFeldspar.Core
value :: Syntax a => Internal a -> a
value = sugarSymCtx poly . Literal
false :: Data Bool
false = value False
true :: Data Bool
true = value True
-- | For types containing some kind of \"thunk\", this function can be used to
-- force computation
force :: Syntax a => a -> a
force = resugar
desugarD :: Syntax a => a -> Data (Internal a)
desugarD = resugar
sugarD :: Syntax a => Data (Internal a) -> a
sugarD = resugar
share :: (Syntax a, Syntax b) => a -> (a -> b) -> b
share = sugarSym (letBind poly)
instance (Type a, Num a) => Num (Data a)
where
fromInteger = value . fromInteger
abs = sugarSym Abs
signum = sugarSym Sign
(+) = sugarSym Add
(-) = sugarSym Sub
(*) = sugarSym Mul
div :: (Type a, Integral a) => Data a -> Data a -> Data a
div = sugarSym Div
mod :: (Type a, Integral a) => Data a -> Data a -> Data a
mod = sugarSym Mod
(^) :: (Type a, Integral a) => Data a -> Data a -> Data a
(^) = sugarSym Exp
instance (Type a, Fractional a) => Fractional (Data a)
where
fromRational = value . fromRational
(/) = sugarSym FDiv
i2n :: (Type a, Integral a, Type b, Num b) => Data a -> Data b
i2n = sugarSym I2N
f2i :: (Type a, Integral a) => Data Float -> Data a
f2i = sugarSym F2I
b2i :: (Type a, Integral a) => Data Bool -> Data a
b2i = sugarSym B2I
complex :: Data Float -> Data Float -> Data Complex
complex = sugarSym Complex
realPart :: Data Complex -> Data Float
realPart = sugarSym RealPart
imagPart :: Data Complex -> Data Float
imagPart = sugarSym ImagPart
mkPolar :: Data Float -> Data Float -> Data Complex
mkPolar = sugarSym MkPolar
magnitude :: Data Complex -> Data Float
magnitude = sugarSym Magnitude
phase :: Data Complex -> Data Float
phase = sugarSym Phase
polar :: Data Complex -> (Data Float, Data Float)
polar a = (magnitude a, phase a)
cis :: Data Float -> Data Complex
cis = mkPolar 1
complement :: (Type a, Bits a) => Data a -> Data a
complement = sugarSym Complement
(.&.) :: (Type a, Bits a) => Data a -> Data a -> Data a
(.&.) = sugarSym BitAnd
(.|.) :: (Type a, Bits a) => Data a -> Data a -> Data a
(.|.) = sugarSym BitOr
xor :: (Type a, Bits a) => Data a -> Data a -> Data a
xor = sugarSym Xor
shiftL :: (Type a, Bits a) => Data a -> Data Index -> Data a
shiftL = sugarSym ShiftL
shiftR :: (Type a, Bits a) => Data a -> Data Index -> Data a
shiftR = sugarSym ShiftR
(<<), (>>) :: (Type a, Bits a) => Data a -> Data Index -> Data a
(<<) = shiftL
(>>) = shiftR
infixl 5 <<, >>
rotateL :: (Type a, Bits a) => Data a -> Data Index -> Data a
rotateL = sugarSym RotateL
rotateR :: (Type a, Bits a) => Data a -> Data Index -> Data a
rotateR = sugarSym RotateR
bitSize :: (Type a, Bits a) => Data a -> Data Index
bitSize = sugarSym BitSize
reverseBits :: (Type a, Bits a) => Data a -> Data a
reverseBits = sugarSym ReverseBits
(==) :: Type a => Data a -> Data a -> Data Bool
(==) = sugarSym Eq
not :: Data Bool -> Data Bool
not = sugarSym Not
(&&) :: Data Bool -> Data Bool -> Data Bool
(&&) = sugarSym And
(||) :: Data Bool -> Data Bool -> Data Bool
(||) = sugarSym Or
(<) :: (Type a, Ord a) => Data a -> Data a -> Data Bool
(<) = sugarSym Less
(<=) :: (Type a, Ord a) => Data a -> Data a -> Data Bool
(<=) = sugarSym LEQ
(>) :: (Type a, Ord a) => Data a -> Data a -> Data Bool
(>) = sugarSym Greater
(>=) :: (Type a, Ord a) => Data a -> Data a -> Data Bool
(>=) = sugarSym GEQ
max :: (Type a, Ord a) => Data a -> Data a -> Data a
max = sugarSym Max
min :: (Type a, Ord a) => Data a -> Data a -> Data a
min = sugarSym Min
(?) :: Syntax a => Data Bool -> (a,a) -> a
cond ? (t,e) = sugarSymCtx poly Condition cond t e
parallel :: Type a => Data Length -> (Data Index -> Data a) -> Data [a]
parallel len ixf
| getIx :$: arr :$: var0 <- body
, Just GetIx <- project getIx
, Just (Variable 0) <- prjCtx poly var0
= setLength len $ Data arr
where
body = unData $ ixf $ Data $ inject (Variable 0 `withContext` poly)
-- This case is an optimization that's included because it has a great effect
-- on the size of the generated code.
parallel len ixf = sugarSym Parallel len ixf
sequential :: (Type a, Syntax st) =>
Data Length -> st -> (Data Index -> st -> (Data a, st)) -> Data [a]
sequential = sugarSym Sequential
forLoop :: Syntax st => Data Length -> st -> (Data Index -> st -> st) -> st
forLoop = sugarSym ForLoop
getLength :: Type a => Data [a] -> Data Length
getLength = sugarSym GetLength
setLength :: Type a => Data Length -> Data [a] -> Data [a]
setLength (desugar -> ((project -> Just GetLength) :$: arr')) arr
| alphaEq poly (reify poly arr') (reify poly $ unData arr)
= arr
-- This case is an optimization that's needed for the optimization of
-- 'parallel' to work properly.
setLength arr len = sugarSym SetLength arr len
getIx :: Type a => Data [a] -> Data Index -> Data a
getIx = sugarSym GetIx