co-feldspar-0.1.0.1: src/Feldspar/Frontend.hs
{-# language TypeFamilies #-}
{-# language MultiParamTypeClasses #-}
{-# language FlexibleContexts #-}
{-# language ConstraintKinds #-}
{-# language ScopedTypeVariables #-}
{-# language FunctionalDependencies #-}
module Feldspar.Frontend where
import Feldspar.Sugar
import Feldspar.Representation
import Data.Bits (Bits, FiniteBits)
import Data.Constraint
import Data.Int
import Data.Struct
import Data.Proxy
import Data.Word hiding (Word)
import qualified Data.Bits as Bits
-- syntactic.
import Language.Syntactic as S hiding (Equality)
-- operational-higher.
import qualified Control.Monad.Operational.Higher as Oper (Program, Param2)
-- imperative-edsl
import qualified Language.Embedded.Imperative as Imp
import qualified Language.Embedded.Imperative.CMD as Imp (Ref)
import Prelude hiding (length, Word, (<), (>))
--------------------------------------------------------------------------------
-- * ...
--------------------------------------------------------------------------------
-- | ...
type Syn (dom :: * -> *) (pred :: * -> Constraint) (exp :: * -> *) (a :: *) =
( Syntactic a
, Domain a ~ dom
, Type pred (Internal a)
, Tuples dom
)
-- | ...
type Syn' dom pred exp a = (Syn dom pred exp a, PrimType pred (Internal a))
-- | ...
type Syntax exp a = (Syn (DomainOf exp) (PredOf exp) exp a, ExprOf a ~ exp)
-- | ...
type Syntax' exp a = (Syn' (DomainOf exp) (PredOf exp) exp a, ExprOf a ~ exp)
-- | ...
type Primitive exp a = PredOf exp a
--------------------------------------------------------------------------------
-- | ...
type SyntaxM m a = Syntax (Expr m) a
-- | ...
type SyntaxM' m a = Syntax' (Expr m) a
--------------------------------------------------------------------------------
-- * Expressions.
--------------------------------------------------------------------------------
class Value exp
where
value :: Syntax exp a => Internal a -> a
class Share exp
where
share :: (Syntax exp a, Syntax exp b) => a -> (a -> b) -> b
class Iterate exp
where
loop :: Syntax exp st => exp Length -> exp Length -> st
-> (exp Index -> st -> st) -> st
iter :: (Iterate exp, Syntax exp st, Num (exp Length))
=> exp Length -> st -> (exp Index -> st -> st) -> st
iter = loop 0
class Cond exp
where
cond :: Syntax exp a => exp Bool -> a -> a -> a
-- | Condition operator; use as follows:
--
-- @
-- cond1 `?` a $
-- cond2 `?` b $
-- default
-- @
(?) :: (Cond exp, Syntax exp a) => exp Bool -> a -> a -> a
(?) = cond
infixl 1 ?
class Equality exp
where
(==) :: (Eq a, Primitive exp a) => exp a -> exp a -> exp Bool
infix 4 ==
class Equality exp => Ordered exp
where
(<) :: (Ord a, Primitive exp a) => exp a -> exp a -> exp Bool
(<=) :: (Ord a, Primitive exp a) => exp a -> exp a -> exp Bool
(>) :: (Ord a, Primitive exp a) => exp a -> exp a -> exp Bool
(>=) :: (Ord a, Primitive exp a) => exp a -> exp a -> exp Bool
infix 4 <, >, <=, >=
max :: (Cond exp, Ordered exp, Syntax exp (exp a), Ord a, Primitive exp a)
=> exp a -> exp a -> exp a
max a b = cond (a > b) a b
min :: (Cond exp, Ordered exp, Syntax exp (exp a), Ord a, Primitive exp a)
=> exp a -> exp a -> exp a
min a b = cond (a < b) a b
class Logical exp
where
not :: exp Bool -> exp Bool
(&&) :: exp Bool -> exp Bool -> exp Bool
(||) :: exp Bool -> exp Bool -> exp Bool
infix 3 &&
infix 2 ||
class Multiplicative exp
where
mult :: (Integral a, Primitive exp a) => exp a -> exp a -> exp a
div :: (Integral a, Primitive exp a) => exp a -> exp a -> exp a
mod :: (Integral a, Primitive exp a) => exp a -> exp a -> exp a
class Bitwise exp
where
complement :: (Bits a, Primitive exp a) => exp a -> exp a
(.&.) :: (Bits a, Primitive exp a) => exp a -> exp a -> exp a
(.|.) :: (Bits a, Primitive exp a) => exp a -> exp a -> exp a
xor :: (Bits a, Primitive exp a) => exp a -> exp a -> exp a
sll :: ( Bits a, Primitive exp a
, Integral b, Primitive exp b)
=> exp a -> exp b -> exp a
srl :: ( Bits a, Primitive exp a
, Integral b, Primitive exp b)
=> exp a -> exp b -> exp a
rol :: ( Bits a, Primitive exp a
, Integral b, Primitive exp b)
=> exp a -> exp b -> exp a
ror :: ( Bits a, Primitive exp a
, Integral b, Primitive exp b)
=> exp a -> exp b -> exp a
infixl 8 `sll`, `srl`, `rol`, `ror`
infixl 7 .&.
infixl 6 `xor`
infixl 5 .|.
shiftL :: (Bitwise exp, Bits a, Primitive exp a, Integral b, Primitive exp b) => exp a -> exp b -> exp a
shiftL = sll
shiftR :: (Bitwise exp, Bits a, Primitive exp a, Integral b, Primitive exp b) => exp a -> exp b -> exp a
shiftR = srl
rotateL :: (Bitwise exp, Bits a, Primitive exp a, Integral b, Primitive exp b) => exp a -> exp b -> exp a
rotateL = rol
rotateR :: (Bitwise exp, Bits a, Primitive exp a, Integral b, Primitive exp b) => exp a -> exp b -> exp a
rotateR = ror
(.<<.) :: (Bitwise exp, Bits a, Primitive exp a, Primitive exp Int32) => exp a -> exp Int32 -> exp a
(.<<.) = shiftL
(.>>.) :: (Bitwise exp, Bits a, Primitive exp a, Primitive exp Int32) => exp a -> exp Int32 -> exp a
(.>>.) = shiftR
infixl 8 `shiftL`, `shiftR`, `rotateL`, `rotateR`, .<<., .>>.
bitSize :: forall exp a. FiniteBits a => exp a -> Word64
bitSize _ = fromIntegral $ Bits.finiteBitSize (a :: a)
where a = error "Bits.finiteBitSize evaluated its argument"
ones :: (Bitwise exp, Bits a, Num (exp a), Primitive exp a) => exp a
ones = complement 0
class Casting exp
where
i2n :: (Integral a, Primitive exp a, Num b, Primitive exp b) => exp a -> exp b
i2b :: (Integral a, Primitive exp a, Primitive exp Bool) => exp a -> exp Bool
b2i :: (Integral a, Primitive exp a, Primitive exp Bool) => exp Bool -> exp a
--------------------------------------------------------------------------------
-- * Instructions.
--------------------------------------------------------------------------------
-- | Computational instructions.
type MonadComp m
= ( Monad m
, References m
, Arrays m
, IArrays m
, Control m
)
--------------------------------------------------------------------------------
class Monad m => References m
where
type Reference m :: * -> *
initRef :: SyntaxM m a => a -> m (Reference m a)
newRef :: SyntaxM m a => m (Reference m a)
getRef :: SyntaxM m a => Reference m a -> m a
setRef :: SyntaxM m a => Reference m a -> a -> m ()
unsafeFreezeRef :: SyntaxM m a => Reference m a -> m a
updateRef :: (References m, SyntaxM m a) => Reference m a -> (a -> a) -> m ()
updateRef ref f = do v <- unsafeFreezeRef ref; setRef ref (f v)
shareM :: (SyntaxM m a, References m) => a -> m a
shareM a = initRef a >>= unsafeFreezeRef
--------------------------------------------------------------------------------
class Finite exp arr
where
length :: arr -> exp Length
class Indexed exp arr
where
type ArrElem arr :: *
(!) :: arr -> exp Index -> ArrElem arr
class Slicable exp arr
where
slice :: exp Index -> exp Length -> arr -> arr
--------------------------------------------------------------------------------
class Monad m => Arrays m
where
type Array m :: * -> *
initArr :: SyntaxM' m a => [Internal a] -> m (Array m a)
newArr :: SyntaxM m a => Expr m Length -> m (Array m a)
getArr :: SyntaxM m a => Array m a -> Expr m Index -> m a
setArr :: SyntaxM m a => Array m a -> Expr m Index -> a -> m ()
copyArr :: SyntaxM m a => Array m a -> Array m a -> m ()
--------------------------------------------------------------------------------
class Arrays m => IArrays m
where
type IArray m :: * -> *
unsafeFreezeArr :: (SyntaxM m a, Finite (Expr m) (Array m a))
=> Array m a -> m (IArray m a)
unsafeThawArr :: (SyntaxM m a, Finite (Expr m) (IArray m a))
=> IArray m a -> m (Array m a)
freezeArr ::
( IArrays m
, SyntaxM m a
, Finite (Expr m) (Array m a)
)
=> Array m a -> m (IArray m a)
freezeArr arr =
do iarr <- newArr (length arr)
copyArr iarr arr
unsafeFreezeArr iarr
thawArr ::
( IArrays m
, SyntaxM m a
, Finite (Expr m) (IArray m a)
)
=> IArray m a -> m (Array m a)
thawArr iarr =
do brr <- unsafeThawArr iarr -- haha.
arr <- newArr (length iarr)
copyArr arr brr
return arr
unsafeFreezeSlice
:: ( IArrays m
, SyntaxM m a
, Finite (Expr m) (Array m a)
, Slicable (Expr m) (IArray m a)
, Num (Expr m Index)
)
=> Expr m Length -> Array m a -> m (IArray m a)
unsafeFreezeSlice len = fmap (slice 0 len) . unsafeFreezeArr
--------------------------------------------------------------------------------
class Monad m => Control m
where
-- | Conditional statement.
iff ::
Expr m Bool -- ^ Condition.
-> m () -- ^ True branch.
-> m () -- ^ False branch.
-> m ()
class Monad m => Loop m
where
-- | While-loop.
while ::
m (Expr m Bool) -- ^ Condition.
-> m () -- ^ Loop body.
-> m ()
-- | For-loop.
for :: (Integral a, SyntaxM' m (Expr m a))
=> Expr m a -- ^ Lower bound (inclusive).
-> Int -- ^ Inc./dec. step.
-> Expr m a -- ^ Upper bound (inclusive).
-> (Expr m a -> m ()) -- ^ Step function.
-> m ()
class Monad m => Assert m
where
break :: m ()
assert :: Expr m Bool -> String -> m ()
--------------------------------------------------------------------------------