copilot-1.0: A stream DSL for writing embedded C monitors.



Provides basic types and functions for other parts of Copilot.

If you wish to add a new type, you need to make it an instance of Streamable, to add it to foldStreamableMaps, mapStreamableMaps, and optionnaly to add an ext[Type], a [type] and a var[Type] functions in Language.hs to make it easier to use.



type Period = IntSource

Atom period -- used as an option to control the duration of a Copilot tick.

type Var = StringSource

Names of the streams or external variables

type Name = StringSource

C file name

data Port Source

Port over which to broadcast information


Port Int 

data Ext Source

Holds external variables or external functions to call.


ExtV Var 
Fun String Args 


Eq Ext 
Show Ext 
ExtCl Ext

For functions.

data ExtRet Source


ExtRetA String 


data ArgConstVar Source

Arguments to be passed to a C function. Either a Copilot variable or a constant. A little hacky that I store constants as strings so we don't have to pass around types. However, these data are just used to make external C calls, for which we have no type info anyway, so it's a bit of a moot point.


V Var 
C String 

data Spec a whereSource

Specification of a stream, parameterized by the type of the values of the stream. The only requirement on a is that it should be Streamable.


Var :: Streamable a => Var -> Spec a 
Const :: Streamable a => a -> Spec a 
PVar :: Streamable a => Type -> Ext -> Spec a 
PArr :: (Streamable a, Streamable b, IntegralE b) => Type -> (Ext, Spec b) -> Spec a 
F :: (Streamable a, Streamable b) => (b -> a) -> (E b -> E a) -> Spec b -> Spec a 
F2 :: (Streamable a, Streamable b, Streamable c) => (b -> c -> a) -> (E b -> E c -> E a) -> Spec b -> Spec c -> Spec a 
F3 :: (Streamable a, Streamable b, Streamable c, Streamable d) => (b -> c -> d -> a) -> (E b -> E c -> E d -> E a) -> Spec b -> Spec c -> Spec d -> Spec a 
Append :: Streamable a => [a] -> Spec a -> Spec a 
Drop :: Streamable a => Int -> Spec a -> Spec a 


Eq a => Eq (Spec a) 
(Streamable a, NumE a, Fractional a) => Fractional (Spec a) 
(Streamable a, NumE a) => Num (Spec a) 
Show a => Show (Spec a) 
Monoid (StreamableMaps Spec) 
Streamable b => ArgCl (Spec b) 

type Streams = Writer LangElems ()Source

Container for mutually recursive streams, whose specifications may be parameterized by different types

type Stream a = Streamable a => (Var, Spec a)Source

A named stream

data Send a Source

An instruction to send data on a port at a given phase. data Send a = Sendable a => Send (Var, Phase, Port)




sendVar :: Spec a
sendPort :: Port
sendName :: String


Streamable a => Show (Send a) 

data Trigger Source




data LangElems Source

Holds all the different kinds of language elements that are pushed into the Writer monad. This currently includes the actual specs, send directives, and trigger directives. (Use the functions in Language.hs to make sends and triggers.)


class (Expr a, Assign a, Show a) => Streamable a whereSource

Holds the complete specification of a distributed monitor type DistributedStreams = (Streams, Sends)

A type is streamable iff a stream may emit values of that type

There are very strong links between Streamable and StreamableMaps : the types aggregated in StreamableMaps are exactly the Streamable types and that invariant should be kept (see methods)


getSubMap :: StreamableMaps b -> Map Var (b a)Source

Provides access to the Map in a StreamableMaps which store values of the good type

updateSubMap :: (Map Var (b a) -> Map Var (b a)) -> StreamableMaps b -> StreamableMaps bSource

Provides a way to modify (mostly used for insertions) the Map in a StreamableMaps which store values of the good type

unit :: aSource

A default value for the type a. Its value is not important.

atomConstructor :: Var -> a -> Atom (V a)Source

A constructor to produce an Atom value

externalAtomConstructor :: Var -> V aSource

A constructor to get an Atom value from an external variable

typeId :: a -> StringSource

The argument only coerces the type, it is discarded. Returns the format for outputting a value of this type with printf in C

For example %f for a float

typeIdPrec :: a -> StringSource

The same, only adds the wanted precision for floating points.

atomType :: a -> TypeSource

The argument only coerces the type, it is discarded. Returns the corresponding Atom type.

showAsC :: a -> StringSource

Like Show, except that the formatting is exactly the same as the one of C for example the booleans are first converted to 0 or 1, and floats and doubles have the good precision.

data StreamableMaps a Source

This is a generalization of Streams which is used for storing Maps over values parameterized by different types.

It is extensively used in the internals of Copilot, in conjunction with foldStreamableMaps and mapStreamableMaps




bMap :: Map Var (a Bool)
i8Map :: Map Var (a Int8)
i16Map :: Map Var (a Int16)
i32Map :: Map Var (a Int32)
i64Map :: Map Var (a Int64)
w8Map :: Map Var (a Word8)
w16Map :: Map Var (a Word16)
w32Map :: Map Var (a Word32)
w64Map :: Map Var (a Word64)
fMap :: Map Var (a Float)
dMap :: Map Var (a Double)


emptySM :: StreamableMaps aSource

An empty streamableMaps.

isEmptySM :: StreamableMaps a -> BoolSource

Verifies if its argument is equal to emptySM

getMaybeElem :: Streamable a => Var -> StreamableMaps b -> Maybe (b a)Source

Lookup into the map of the right type in StreamableMaps

getElem :: Streamable a => Var -> StreamableMaps b -> b aSource

Lookup into the map of the right type in StreamableMaps Launch an exception if the index is not in it

foldStreamableMaps :: forall b c. (Streamable a => Var -> c a -> b -> b) -> StreamableMaps c -> b -> bSource

This function is used to iterate on all the values in all the maps stored by a StreamableMaps, accumulating a value over time

mapStreamableMaps :: forall s s'. (forall a. Streamable a => Var -> s a -> s' a) -> StreamableMaps s -> StreamableMaps s'Source

mapStreamableMapsM :: forall s s' m. Monad m => (Streamable a => Var -> s a -> m (s' a)) -> StreamableMaps s -> m (StreamableMaps s')Source

filterStreamableMaps :: forall c b. StreamableMaps c -> [(Type, Var, b)] -> (StreamableMaps c, Bool)Source

Only keeps in sm the values whose key+type are in l. Also returns a bool saying whether all the elements in sm were in l. Works even if some elements in l are not in sm. Not optimised at all.

normalizeVar :: Var -> VarSource

Replace all accepted special characters by sequences of underscores.

getVars :: StreamableMaps s -> [Var]Source

Get the Copilot variables.

type Vars = StreamableMaps []Source

For each typed variable, this type holds all its successive values in an infinite list Beware : each element of one of those lists corresponds to a full Atom period, not to a single clock tick.

vPre :: Name -> StringSource

Copilot variable reference, taking the name of the generated C file.

funcShow :: Name -> String -> Args -> StringSource

For calling a function with Atom variables.

getMaybeVar :: Streamable a => Spec a -> VarSource

Get a variable name from a spec; throw an error otherwise.

notConstVarErr :: Streamable a => Spec a -> (ArgConstVar -> b) -> bSource

If the Spec isn't a Var or Const, then throw an error; otherwise, apply the function.