update gen
authorMart Lubbers <mart@martlubbers.net>
Fri, 17 Jun 2016 16:50:15 +0000 (18:50 +0200)
committerMart Lubbers <mart@martlubbers.net>
Fri, 17 Jun 2016 16:50:15 +0000 (18:50 +0200)
deliverables/report/gen.tex
deliverables/report/sem.tex

index 068976e..f81d3d5 100644 (file)
@@ -3,35 +3,46 @@
 \SPLC{} uses a simple stack layout in which all functions have their own stack
 frame and all the arguments and local variables are present within this frame.
 Arguments and local variables are either saved on the stack directly, or as a
-pointer to the heap. Simple values, i.e. Ints, Bools and Chars are stored 
-directly on the stack, while other values are stored on the heap. 
+pointer to the heap. This means that every allocated variable uses precisely
+one stack address.
 
-The heap simply grows with each added value, currently no garbage collection is
-done. Lists are represented simply as linked lists, by first storing the pointer
-to the next list element and then the current list element. Tuples are simply 
-stored by storing the two values in succession. 
+Simple values, i.e. \SI{Int}s, \SI{Bool}s and \SI{Char}s are stored directly on
+the stack in their representative numeric value. Values on the stack in \SSM{}
+are always numbers. For \SI{Int}s we use standard signed integers. For
+characters \textsc{ASCII} values are used. A boolean true is
+stored as a negative one and the boolean false is stored as a zero.
 
-When calling a functions its arguments are placed on the stack, after which 
-a \tt{bsr} instruction calls the function. The function can then load its 
-arguments, if and when these are needed in an expression, by copying them 
-from below its stack frame. 
+The heap simply grows with each added value, currently no garbage collection is
+done. Functions, lists and tuples are currently stored in the heap. Lists are
+represented simply as linked lists, by first storing the pointer to the next
+list element and having the current list element in front of that pointer. The
+empty list is represented as the null pointer. Tuples are stored by
+storing the two values in succession on the heap and pointing to the first of
+the two. Detailed description of function storage is explained in
+Subsection~\ref{ssec:high}.
+
+When calling a functions its arguments are placed on the stack, after which a
+\tt{bsr} instruction calls the function. The function can then load its
+arguments, if and when these are needed in an expression, by copying them from
+below its stack frame. The \tt{bsr} instruction is an instruction that works
+together with the \tt{ret} instruction. \tt{bsr} places the previous program
+counter on the stack so that it can be restored with a \tt{ret}.
 
 Note that the combination of this copying behaviour and passing complex values
-as heap pointers means that in some cases \SPLC{} programs behave as 
+as heap pointers means that in some cases \SPLC{} programs behave as
 pass-by-value while in others it behave as pass-by-reference. Simple values
-are trivially pass-by-value, whilst lists and tuples can behave as both, 
-depending on the usage. E.g. assigning a new list/tuple to an argument will 
+are trivially pass-by-value, whilst lists and tuples can behave as both,
+depending on the usage. E.g. assigning a new list/tuple to an argument will
 behave as pass-by-value, whilst changing the argument through a field selector
 will behave as pass by reference, thus the pointer is passed by value.
 
-Listing~\ref{lst:stackFunCall} shows the layout of the stack when executing the 
-two functions. the layout shown is the layout of the stack just before 
-the \tt{add} instruction to add x and y in plus. Note that, in compliance with 
-\SSM{}s 
-calling model, the return address of a function is saved below the stack frame
-of that function. When plus has returned, the two arguments are popped of the
-stack and the value in \tt{RR} (for functions which do not return \tt{Void}) 
-is placed on the stack.
+Listing~\ref{lst:stackFunCall} shows the layout of the stack when executing the
+two functions. the layout shown is the layout of the stack just before the
+\tt{add} instruction to add x and y in plus. Note that, in compliance with
+\SSM{}s calling model, the return address of a function is saved below the
+stack frame of that function. When plus has returned, the two arguments are
+popped of the stack and the value in \tt{RR} (for functions which do not return
+\tt{Void}) is placed on the stack.
 
 \begin{SPLCode} \label{lst:stackFunCall}
 plus(x, y}{ return x + y; }
@@ -54,22 +65,40 @@ main(){ var a = plus(3, 4); }
 
 \subsection{Generation}
 The code generation phase transforms a well typed \AST{} to either an error,
-or an \tt{SSMProgram}. The latter is a list of labels and instructions. The 
-generation happens within a 
+or a \tt{SSMProgram}. The latter is a list of labels and instructions. The
+generation happens within a
 \CI{WriterT SSMProgram (StateT (Addressbook, [Label]) (Either GenError)) a}
 environment. Which we have implemented as a \tt{RWST} with \tt{()} for the
-reading environment. In this \tt{Addressbook} is a simple map from 
+reading environment. In this \tt{Addressbook} is a simple map from
 identifiers to \tt{Address}, which in turn is either a label to jump to or an
 address where a variable can be found (relative to the current frame). The list
-of labels is simply an infinite generator for fresh labels, used when generating
-code for e.g. an if-statement.
-
-Code generation is done by walking through the \AST{} depth first and generating
-instructions for each encountered element. E.g. generation for an \tt{Op2Expr} 
-is simply recursively generating for each element of the expression:
-\CI{g e1 >>| g e2 >>| g op}. 
-
-\subsection{Higher order functions}
+of labels is simply an infinite generator for fresh labels, used when
+generating code for e.g. an if-statement.
+
+Code generation is done by walking through the \AST{} depth first and
+generating instructions for each encountered element. E.g. generation for an
+\tt{Op2Expr} is simply recursively generating for each element of the
+expression: \CI{g e1 >>| g e2 >>| g op}. For example the snippet in
+Listing~\ref{lst:codegen} shows the code generation instance for the
+implementation of the \SI{:} operator. First we generate the code for the left
+part of the cons operator, the head, and afterwards the right side of the
+operator, the tail. They are glued together by pushing the head and the tail
+subsequently on the heap and what we are left with is the pointer to the tail.
+
+\begin{lstlisting}[
+       language=Clean,
+       label={lst:codegen},
+       caption={Code generation of the cons operator}]
+instance g Expr where
+       ...
+       g (Op2Expr _ e1 BiCons e2) = g e2 >>| g e1
+               >>| tell [Instr "sth" [] ""]
+               >>| tell [Instr "ajs" [Lit -1] ""]
+               >>| tell [Instr "sth" [] ""]
+       ...
+\end{lstlisting}
+
+\subsection{Higher order functions}\label{ssec:high}
 The nature of the type checking algorithm already included type checking and
 inferring the type of higher order functions. Since we allow constants there is
 a difference between \SI{read} and \SI{read()}. To make this difference we
@@ -92,7 +121,7 @@ main(){
 
 /*# | Stack
 001 | 001    //Pointer to the
-... | 
+... |
 
   # | Heap
 001 | 008    //Function identification number
index 66ff397..e40e86b 100644 (file)
@@ -19,7 +19,7 @@ two dozen lines of \Clean{} code. The last step is a \emph{Hindley-Milner} type
 inference algorithm, which is a magnitude more complex. This last step also
 decorates the \AST{} with inferred type information.
 
-\subsection{AST transformation for lambdas}
+\subsection{\AST{} transformation for lambdas}
 Before checking the semantic correctness of the program one small \AST{}
 transformations needs to be done. Currently this transformation is build into
 the semantic analysis phase, however, it would be more in place as a separate
@@ -52,6 +52,15 @@ main() {
 }
 \end{lstlisting}
 
+\subsection{\AST{} transformation for printing}
+During type inference and checking it is clear what the type is of all the
+functions and thus we can specify the print functions since it is overloaded.
+At time of compilation the overloaded print function is changed to the
+corresponding specific function. For example \SI{print(True)} is changed to
+\SI{1printbool(True)}. Printing is the only overloaded functionality built-in.
+While comparison and equality are overloaded too they generate the same
+assembly code for different types and thus need not to be specified.
+
 \subsection{Type inference}
 \SPLC{} features a \emph{Hindley-Milner} type inference algorithm based on the
 algorithm presented in the slides. It supports full polymorphism and can infer