signals-0.0.0.1: Core.hs
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Core where
import Interpretation
import Control.Monad.Operational
import Data.Constraint
import Data.Dynamic
import Data.Typeable
import Data.IORef
import Data.Array.IO.Safe
import qualified System.IO as IO
--------------------------------------------------------------------------------
-- * Commands
--------------------------------------------------------------------------------
-- | Imperative commands
data CMD exp a
where
-- ^ File management (IOHandler in Haskell)
Open :: FilePath -> CMD exp Handle
Close :: Handle -> CMD exp ()
Put :: Handle -> exp Float -> CMD exp ()
Get :: Handle -> CMD exp (exp Float)
Eof :: Handle -> CMD exp (exp Bool)
-- ^ Mutable references (IORef in Haskell)
InitRef :: Typeable a => CMD exp (Ref (exp a))
NewRef :: Typeable a => exp a -> CMD exp (Ref (exp a))
GetRef :: Typeable a => Ref (exp a) -> CMD exp (exp a)
SetRef :: Ref (exp a) -> exp a -> CMD exp ()
-- ^ Mutable arrays (IOArray in Haskell)
NewArr :: Integral n => exp n -> exp a -> CMD exp (Arr (exp a))
GetArr :: Integral n => exp n -> Arr (exp a) -> CMD exp (exp a)
SetArr :: Integral n => exp n -> exp a -> Arr (exp a) -> CMD exp ()
-- no new var. is assigned.
UnsafeGetRef :: Ref (exp a) -> CMD exp (exp a)
UnsafeGetArr :: Integral n => exp n -> Arr (exp a) -> CMD exp (exp a)
-- ^ Control structures | Todo: Move to seperate data class
If :: exp Bool
-> Program (CMD exp) ()
-> Program (CMD exp) ()
-> CMD exp ()
While :: Program (CMD exp) (exp Bool)
-> Program (CMD exp) ()
-> CMD exp ()
Break :: CMD exp ()
-- ^ Misc.
Printf :: Show a => String -> exp a -> CMD exp ()
GetTime :: CMD exp (exp Double)
-- |
data Handle
= HandleComp String
| HandleEval IO.Handle
deriving Typeable
-- |
data Ref a
= RefComp String
| RefEval (IORef a)
deriving Typeable
-- |
data Arr a
= ArrComp String
| ArrEval (IOArray Int a)
deriving Typeable
--------------------------------------------------------------------------------
-- ** User Interface
--------------------------------------------------------------------------------
-- *** File Handling
open :: FilePath -> ProgramT (CMD exp) m Handle
open = singleton . Open
close :: Handle -> ProgramT (CMD exp) m ()
close = singleton . Close
fput :: Handle -> exp Float -> ProgramT (CMD exp) m ()
fput p = singleton . Put p
fget :: Handle -> ProgramT (CMD exp) m (exp Float)
fget = singleton . Get
feof :: Handle -> ProgramT (CMD exp) m (exp Bool)
feof = singleton . Eof
--------------------------------------------------------------------------------
-- *** Variables
initRef :: Typeable a => ProgramT (CMD exp) m (Ref (exp a))
initRef = singleton InitRef
newRef :: Typeable a => exp a -> ProgramT (CMD exp) m (Ref (exp a))
newRef e = singleton (NewRef e)
getRef :: Typeable a => Ref (exp a) -> ProgramT (CMD exp) m (exp a)
getRef r = singleton (GetRef r)
setRef :: Ref (exp a) -> exp a -> ProgramT (CMD exp) m ()
setRef r = singleton . SetRef r
--------------------------------------------------------------------------------
-- *** Arrays
newArr :: Integral n => exp n -> exp a -> ProgramT (CMD exp) m (Arr (exp a))
newArr n = singleton . NewArr n
getArr :: Integral n => exp n -> Arr (exp a) -> ProgramT (CMD exp) m (exp a)
getArr n = singleton . GetArr n
setArr :: Integral n => exp n -> exp a -> Arr (exp a) -> ProgramT (CMD exp) m ()
setArr n a = singleton . SetArr n a
----------------------------------------
-- Unsafe
-- | Like 'getRef' but assumes that the reference will not be modified later
-- in the program
unsafeGetRef :: Ref (exp a) -> ProgramT (CMD exp) m (exp a)
unsafeGetRef = singleton . UnsafeGetRef
-- TODO: It would be possible to make a conservative analysis to find out if
-- uses of `unsafeGetRef` are safe. Even better, the compiler could
-- automatically treat `getRef` as `unsafeGetRef` whenever possible.
unsafeGetArr :: Integral n => exp n -> Arr (exp a) -> ProgramT (CMD exp) m (exp a)
unsafeGetArr i = singleton . UnsafeGetArr i
--------------------------------------------------------------------------------
-- **
iff :: exp Bool
-> Program (CMD exp) ()
-> Program (CMD exp) ()
-> Program (CMD exp) ()
iff b t f = singleton $ If b t f
while :: Program (CMD exp) (exp Bool)
-> Program (CMD exp) ()
-> Program (CMD exp) ()
while b t = singleton $ While b t
break :: Program (CMD exp) ()
break = singleton Break
printf :: Show a => String -> exp a -> Program (CMD exp) ()
printf format = singleton . Printf format
getTime :: Program (CMD exp) (exp Double)
getTime = singleton GetTime
--------------------------------------------------------------------------------
-- * Constructs
--------------------------------------------------------------------------------
-- |
data Construct cmd a
where
Function :: String -> Program cmd () -> Construct cmd ()
--------------------------------------------------------------------------------
-- ** User Interface
mkFunction :: String -> Program cmd () -> Program (Construct cmd) ()
mkFunction fun body = singleton $ Function fun body
--------------------------------------------------------------------------------
-- *
--------------------------------------------------------------------------------
class EEq exp a
where
(==:) :: exp a -> exp a -> exp Bool
(/=:) :: exp a -> exp a -> exp Bool