\begin{lstlisting}[caption={Device type},label={lst:mtaskdevice}]
:: Channels :== ([MTaskMSGRecv], [MTaskMSGSend], Bool)
-:: BCState = ... // Compiler state, explained in later sections
:: MTaskDeviceSpec = ... // Also explained in later sections
:: MTaskMSGRecv = ... // Message format, explained in later sections
:: MTaskMSGSend = ... // Also explained in later sections
\begin{lstlisting}[label={lst:actualdev},%
caption={Device \gls{SDS}}]
+($<) :: a (f a) -> (f b)
($<) a fb = fmap (const a) fb
deviceStore :: RWShared (Maybe (MTaskDevice, Int)) [MTaskDevice] [MTaskDevice]
\begin{lstlisting}[caption={Local \gls{SDS}}]
deviceShare :: MTaskDevice -> Shared MTaskDevice
deviceShare d = mapReadWriteError
- ( \ds->case find ((==)d) of
+ ( \ds->case find ((==)d) ds of
Nothing = exception "Device lost"
Just d = Ok d)
, \w ds->case splitWith ((==)d) ds of
Text written using the \CI{Teletype} font indicates code and is often
referring to a listing. \emph{Emphasized} text is used for proper nouns and
-words that have a unexpected meaning.
+words that have an unexpected meaning.
The complete source code of this thesis can be found in the following git
repository:\\
\begin{lstlisting}[%
label={lst:control},caption={Control flow operators}]
-class If v q r ~s where
- If :: (v Bool p) (v t q) (v t r) -> v t s | ...
-
class IF v where
IF :: (v Bool p) (v t q) (v s r) -> v () Stmt | ...
(?) infix 1 :: (v Bool p) (v t q) -> v () Stmt | ...
-instance If Code Stmt Stmt Stmt
-instance If Code e Stmt Stmt
-instance If Code Stmt e Stmt
-instance If Code x y Expr
-
class seq v where
(:.) infixr 0 :: (v t p) (v u q) -> v u Stmt | ...
\end{lstlisting}
In {main=blink (lit 1000) True}
thermostat :: Main (View () Stmt)
-thermostat = {main =
- IF (analogRead A0 >. lit 50)
- ( digitalWrite D0 (lit True) )
- ( digitalWrite D0 (lit False) )
- }
+thermostat = {main = digitalWrite D0 (analogRead A0 >. lit 50) }
thermostat` :: Main (View () Stmt)
-thermostat` = let
+thermostat` = let
a0 = aIO A0
- d0 = dIO D0 in {main = IF (a0 >. lit 50) (d0 =. lit True) (d0 =. lit False) }
+ d0 = dIO D0 in {main = d0 =. a0 > lit 50 }
\end{lstlisting}
Bytecode view implementation for arithmetic and peripheral classes}]
instance arith ByteCode where
lit x = tell` [BCPush (BCValue x)]
- (+.) x y = op2 x y BCDiv
+ (+.) x y = op2 x y BCAdd
...
instance userLed ByteCode where
since the labels are resolved to real addresses later on anyway.
\begin{lstlisting}[label={lst:controlflow},%
- caption={Bytecode view for \texttt{arith} class}]
-freshlabel = get >>= \st=:{freshl}->put {st & freshl=freshl+1} >>| pure freshl
+ caption={Bytecode view for the \texttt{IF} class}]
+freshlabel = get >>= \st=:{freshl}->put {st & freshl=freshl+1} >>| tell freshl
-instance If ByteCode Stmt Stmt Stmt where If b t e = BCIfStmt b t e
-instance If ByteCode e Stmt Stmt where If b t e = BCIfStmt b t e
-instance If ByteCode Stmt e Stmt where If b t e = BCIfStmt b t e
-instance If ByteCode x y Stmt where If b t e = BCIfStmt b t e
instance IF ByteCode where
IF b t e = BCIfStmt b t e
(?) b t = BCIfStmt b t (tell` [])
+
BCIfStmt (BC b) (BC t) (BC e) = BC (
freshlabel >>= \else->freshlabel >>= \endif->
b >>| tell [BCJmpF else] >>|
)
instance noOp ByteCode where
- noOp = tell` [BCNop]
+ noOp = BC (pure ())
\end{lstlisting}
The semantics for the \gls{mTask}-\glspl{Task} bytecode view are different from
Listing~\ref{lst:compilation}. The compilation process consists of two steps.
First, the \gls{RWST} is executed. Then, the \emph{Jump} statements that
jump to labels are transformed to jump to program memory addresses. The
-translation of labels is possible in one sweep because fresh labels are reused.
-Reusing labels would not give a speed improvement since the labels are removed
-in the end.
+translation of labels to program addresses is straightforward. The function
+consumes the instructions one by one while incrementing the address counter
+with the length of the instruction. The generic function \CI{consNum} is used
+which gives the arity of the constructor. However, when it encounters a
+\CI{BCLab} instruction, the counter is not increased because the label will not
+result in an actual instruction. The label is removed and the position of the
+label is stored in the resulting map. When all labels are removed, the jump
+instructions are transformed using the \CI{implGotos} function that looks up
+the correct program address in the map resulting from the aforementioned
+function. This step is followed by comparing the old compiler state to the new
+one to find new instantiated \glspl{SDS}. The compilation concludes with
+converting the bytecode and \glspl{SDS} to actual messages ready to send to the
+client.
\begin{lstlisting}[label={lst:compilation},%
caption={Actual compilation.}]
computeGotos :: [BC] Int -> ([BC], Map Int Int)
computeGotos [] _ = ([], newMap)
-computeGotos [BCLab l:xs] i = appSnd ('DM'.put l i) (computeGotos xs i)
-computeGotos [x:xs] i = appFst (\bc->[x:bc]) (computeGotos xs (i + bclength x))
+computeGotos [BCLab l:xs] i
+# (bc, i) = computeGotos xs i
+= (bc, put l i)
+computeGotos [x:xs] i
+# (bc, i) = computeGotos xs (i + bclength x)
+= ([x:bc], i)
toRealByteCode :: (ByteCode a b) BCState -> (String, BCState)
toRealByteCode x s
# (bc, gtmap) = computeGotos bc 1
= (concat (map (toString o toByteVal) (map (implGotos gtmap) bc)), s)
+implGotos map (BCJmp t) = BCJmp $ fromJust (get t map)
+implGotos map (BCJmpT t) = BCJmpT $ fromJust (get t map)
+implGotos map (BCJmpF t) = BCJmpF $ fromJust (get t map)
+implGotos _ i = i
+
toMessages :: MTaskInterval (Main (ByteCode a b)) BCState -> ([MTaskMSGSend], BCState)
toMessages interval x oldstate
# (bc, newstate) = toRealByteCode (unMain x) oldstate
As an example for the bytecode compilation the following listing shows the
thermostat example given in Listing~\ref{lst:exmtask} compiled to bytecode.
-The left column indicates the position in the program memory.
+The left column indicates the position in the program memory. The \CI{endif}
+label is resolved to an address outside of the program space. This is not a
+problem since this is included in the stopping condition of the interpreter.
+When the program counter exceeds the length of the program, the task
+terminates.
\begin{lstlisting}[caption={Thermostat bytecode},language=c]
- 1-2 : BCAnalogRead (Analog A0)
- 3-6 : BCPush (Int 50)
- 7 : BCGre
- 8-9 : BCJmpF 17 //Jump to else
-10-12: BCPush (Bool 1)
-13-14: BCDigitalWrite (Digital D0)
-15-16: BCJmp 21 //Jump to endif
-17-19: BCPush (Bool 0) //Else label
-20 : BCDigitalWrite (Digital D0)
-21 : //Endif label
+ 0-1 : BCAnalogRead (Analog A0)
+ 2-5 : BCPush (Int 50)
+ 6 : BCGre
+ 7-8 : BCJmpF 17 //Jump to else
+ 9-11: BCPush (Bool 1)
+12-13: BCDigitalWrite (Digital D0)
+14-15: BCJmp 21 //Jump to endif
+16-18: BCPush (Bool 0) //Else label
+19 : BCDigitalWrite (Digital D0)
+20 : //Endif label
\end{lstlisting}
The factorial function can be expressed as an \gls{mTask}-\gls{Task} and uses
--- /dev/null
+intro: Problem statement en introductie uitwijden
+mtask: edsl, uitleggen waarom die hierarchie nodig is, isExpr
+mtask: voorbeelde sds
+mtask: semantics anders noemen
+emtsk: semantics, anders noemen en voorbeelden geven in strategies
+emtsk: Voorbeeldje voor namedsds
+emtsk: examples, factorial vervangen
+devcs: iets met taken en argumenten zeggen
+devcs: waarom kunnen taken geen andere taken starten
+devcs: duidelijker zijn dat je echt geen heap nodig hebt
+iTaks: duidelijker maken wat "managing devices" betekend
+dvspc: Uitleggen hoe device spec gemaakt word
+hbexm: Voorbeeld met de heartbeat sensor
+hbexm: Instructies van de heartbeat sensor verkleinen
+concl: Uitleggen hoe/of de probleemstelling opgelost is