add stuff about assignments, class implementation etc
[msc-thesis1617.git] / results.mtask.tex
index 8c22015..9580dec 100644 (file)
@@ -5,6 +5,9 @@ embedding this obstacle is very easy to solve. A type housing the \gls{EDSL}
 does not have to implement all the available classes. Moreover, classes can be
 added at will without interfering with the existing views.
 
 does not have to implement all the available classes. Moreover, classes can be
 added at will without interfering with the existing views.
 
+\section{Semantics}
+\todo{semantics}
+
 \section{Bytecode compilation}
 The \glspl{mTask} are sent to the device in bytecode and are saved in the
 memory of the device. To compile the \gls{EDSL} code to bytecode, a view is
 \section{Bytecode compilation}
 The \glspl{mTask} are sent to the device in bytecode and are saved in the
 memory of the device. To compile the \gls{EDSL} code to bytecode, a view is
@@ -32,7 +35,7 @@ the moment a simple encoding scheme is used that uses a single byte prefixes to
 detect which type the value is. The devices know of these prefixes and act
 accordingly.
 
 detect which type the value is. The devices know of these prefixes and act
 accordingly.
 
-\begin{lstlisting}[language=Clean,label={lst:bcview},caption={Bytecode view}]
+\begin{lstlisting}[label={lst:bcview},caption={Bytecode view}]
 :: ByteCode a p = BC (RWS () [BC] BCState ())
 :: BCValue = E.e: BCValue e & mTaskType, TC e
 :: BCShare = {
 :: ByteCode a p = BC (RWS () [BC] BCState ())
 :: BCValue = E.e: BCValue e & mTaskType, TC e
 :: BCShare = {
@@ -58,15 +61,137 @@ instance serial ByteCode
 \end{lstlisting}
 
 \section{Implementation}
 \end{lstlisting}
 
 \section{Implementation}
+\subsection{Instruction Set}
+The instruction set is given in Listing~\ref{bc:instr}. The instruction set is
+kept large, but under $255$, to get the highest expressivity for the lowest
+program size. 
+
+The interpreter is a
+stack machine. Therefore the it needs instructions like \emph{Push} and
+\emph{Pop}. The virtual instruction \CI{BCLab} is added to allow for an easy
+implementation. However, this is not a real instruction and the labels are
+resolved to actual addresses in the final step of compilation to save
+instructions.
+
+\begin{lstlisting}[label={bc:instr},%
+       caption={Bytecode instruction set}]
+:: BC = BCNop
+       | BCLab Int          | BCPush BCValue     | BCPop
+       //SDS functions
+       | BCSdsStore BCShare | BCSdsFetch BCShare | BCSdsPublish BCShare
+       //Unary ops
+       | BCNot
+       //Binary Int ops
+       | BCAdd              | BCSub              | BCMul
+       | BCDiv
+       //Binary Bool ops
+       | BCAnd              | BCOr
+       //Binary ops
+       | BCEq               | BCNeq              | BCLes             | BCGre
+       | BCLeq              | BCGeq
+       //Conditionals and jumping
+       | BCJmp Int          | BCJmpT Int         | BCJmpF Int
+       //UserLED
+       | BCLedOn            | BCLedOff
+       //Pins
+       | BCAnalogRead Pin   | BCAnalogWrite Pin  | BCDigitalRead Pin | BCDigitalWrite Pin
+       //Return
+       | BCReturn
+\end{lstlisting}
+
+All instructions are can be converted semi-automatically using the generic
+function \CI{consIndex\{*\}} that gives the index of the constructor. This
+constructor index is the actual byte value for the instruction. The
+\CI{BCValue} type contains existentially quantified types and therefore must
+have a given implementation for all generic functions.
+
 \subsection{Helper functions}
 \subsection{Helper functions}
+The \CI{ByteCode} type is just a boxed \gls{RWST} and that gives us access to
+the whole range of \gls{RWST} functions. However, to apply a function the type
+must be unboxed. After application the type must be boxed again. To achieve
+this some helper functions have been created. They are listed in
+Listing~\ref{lst:helpers}. The \CI{op} and \CI{op2} function is crafted to make
+operators that pop one or two values off the stack respectively. The \CI{tell`}
+is a wrapper around the \gls{RWST} function \CI{tell} that appends the argument
+to the \emph{Writer} value.
+
+\begin{lstlisting}[label={lst:helpers},caption={Some helper functions}]
+op2 :: (ByteCode a p1) (ByteCode a p2) BC -> ByteCode b Expr
+op2 (BC x) (BC y) bc = BC (x >>| y >>| tell [bc])
+
+op :: (ByteCode a p) BC -> ByteCode a Expr
+op (BC x) bc = BC (x >>| tell [bc])
+
+tell` :: [BC] -> (ByteCode a p)
+tell` x = BC (tell x)
+
+unBC :: (ByteCode a p) -> RWS () [BC] BCState ()
+unBC (BC x) = x
+\end{lstlisting}
+
+\subsection{Arithmetics \& Peripherals}
+Almost all of the code from the simple classes use exclusively helper
+functions. Listing~\ref{lst:arithview} shows some implementations. The classes
+\CI{boolExpr} and the classes for the peripherals are implemented in the same
+fashion.
+
+\begin{lstlisting}[label={lst:arithview},caption={%
+       Bytecode view implementation for arithmetic and peripheral classes}]
+instance arith ByteCode where
+       lit x = tell` [BCPush (BCValue x)]
+       (+.) x y = op2 x y BCDiv
+       ...
 
 
-\subsection{Arithmetics}
+instance userLed ByteCode where
+       ledOn  l = op l BCLedOn
+       ledOff l = op l BCLedOff
+\end{lstlisting}
 
 \subsection{Control Flow}
 
 \subsection{Control Flow}
+\begin{lstlisting}[label={lst:controlflow},%
+       caption={Bytecode view for \texttt{arith}}]
+instance noOp ByteCode where
+       noOp = tell` [BCNop]
+\end{lstlisting}
 
 
-\subsection{Shared Data Sources}
+\subsection{Shared Data Sources \& Assignment}
+Shared data sources must be acquired from the state and constructing one
+happens via multiple steps. First a fresh identifier is grabbed from the state.
+Then a \CI{BCShare} record is created with that identifier. A \CI{BCSdsFetch}
+instruction is written and the body is generated to finally add the share to
+the actual state. The exact implementation is shown in
+Listing~\ref{lst:shareview}.
 
 
-\section{Semantics}
+\begin{lstlisting}[label={lst:shareview},%
+       caption={Bytecode view for \texttt{arith}}]
+instance sds ByteCode where
+       sds f = {main = BC (freshs
+                               >>= \sdsi->pure {BCShare | sdsi=sdsi,sdsval=BCValue 0}
+                               >>= \sds->pure (f (tell` [BCSdsFetch sds]))
+                               >>= \(v In bdy)->modify (addSDS sds v)
+                               >>| unBC (unMain bdy))}
+       pub (BC x) = BC (censor (\[BCSdsFetch s]->[BCSdsPublish s]) x)
 
 
-\todo{Uitleggen wat het systeem precies doet}
+addSDS sds v s = {s & sdss=[{sds & sdsval=BCValue v}:s.sdss]}
+\end{lstlisting}
+
+All assignable types compile to an \gls{RWST} that writes one instruction. For
+example, using an \gls{SDS} always results in an expression of the form
+\CI{sds \x=4 In ...}. The actual \CI{x} is the \gls{RWST} that always writes
+one \CI{BCSdsFetch} instruction with the correct \gls{SDS} embedded. When the
+call of the \CI{x} is not a read but an assignment,  the instruction will be
+rewritten as a \CI{BCSdsStore}. The implementation for this is given in
+Listing~\ref{lst:assignmentview}.
+
+\begin{lstlisting}[label={lst:assignmentview},%
+       caption={Bytecode view implementation for assignment.}]
+instance assign ByteCode where
+       (=.) (BC v) (BC e) = BC (e >>| censor makeStore v)
+
+makeStore [BCSdsFetch i]    = [BCSdsStore i]
+makeStore [BCDigitalRead i] = [BCDigitalWrite i]
+makeStore [...]             = [...]
+\end{lstlisting}
 
 
+\section{Actual Compilation}
+\todo{hulp functies voor compileren}