stukje over incomplete functions
[cc1516.git] / deliverables / report / ext.tex
1 \section{Extensions}
2 \subsection{Higher order functions}
3 The nature of the type checking algorithm already included type checking and
4 inferring the type of higher order functions. Since we allow constants there is
5 a difference between \SI{read} and \SI{read()}. To make this difference we
6 introduced a separate type of expression called a \SI{FuncType}, this type
7 encodes a function with arity $0$.
8
9 As all other data types a function type object occupies one item on the stack
10 which contains a heap pointer. The heap pointer points to a position on the
11 heap that stores, in increasing addresses, the function identification number,
12 the number of arguments already given and finally the argument values.
13 For example the following snippet shows the representation of the incomplete
14 function \SI{plus} that already has two arguments.
15 \begin{SPLCode}
16 //SPLCode
17 plus(x, y, z){ return x + y + z; }
18
19 main(){
20 var a = plus(4, 3);
21 }
22
23 /*# | Stack
24 001 | 001 //Pointer to the
25 ... |
26
27 # | Heap
28 001 | 008 //Function identification number
29 002 | 002 //Available arguments
30 003 | 004 //Argument 1
31 004 | 003 //Argument 2
32 */
33 \end{SPLCode}
34
35 When an incomplete function is declared we save the remaining arity in our
36 state to be able to know when a function is complete and can be executed. When
37 a function is still not complete the function is copied in totality and the
38 available arguments position on the heap is increased accordingly and the
39 arguments are added on the heap.
40
41 Function numbers are integers that identify the function. Normally we address
42 functions using labels but it is not possible to store labels on the heap or on
43 the stack. Therefore we include a function in the preamble that is basically a
44 dictionary from integers to labels. All functions have their unique number that
45 identifies them via the function dictionary called \SI{1func}. When we want to
46 call a function that is identified by an address instead of a label we first
47 collect all the arguments from the heap and add the arguments given in the
48 function call. Calculating the number of arguments that have to be popped from
49 the heap is done at runtime using the \emph{Available Arguments} value stored
50 on the heap. Instead of jumping to a label we jump to the \SI{1func} function
51 and make sure the identification is situated in register R5. \SI{1func} then
52 makes sure the correct function is branched to and the caller can resume the
53 normal execution path.
54
55
56 \subsection{Syntactic sugars}
57 Several small syntactic sugars have been added on several levels of processing
58 to make writing programs more easy.
59
60 \subsubsection{Literal strings}
61 While there are no literal strings one can print lists of characters. Entering
62 lists of characters can be cumbersome and therefore a shorthand notation is
63 added to define literal strings using double quotes. During the lexing phase
64 the string is lexed as a single token and during parsing the token is
65 transformed to a equal character list representation. The following example
66 shows the syntax before transformation and the syntax after. Note that just as
67 in characters, literal strings can contain escape characters.
68
69 \begin{SPLCode}
70 //Before transformation
71 var a = "Hello world!";
72 //After transformation
73 var a = 'H':'e':'l':'l':'o':' ':'w':'o':'r':'l':'d':'!':[]
74 \end{SPLCode}
75
76 \subsubsection{Anonymous functions}
77 When the programmers wants to use small functions that consist of one line to
78 for example use the operators in a functional way the programmer has to make a
79 named function for every operator. In some cases it is easy to do this inline
80 using anonymous functions. A small syntactic sugar has been added that will
81 inline anonymous functions to non-anonymous functions during the parsing phase.
82 The following snippet is an example of a filter on even values before and after
83 transformation.
84
85 \begin{SPLCode}
86 //Before transformation
87 main(){
88 var a = filter(\x->x % 2 == 0, 1 : 2 : 3 : 4 : 5 : []);
89 }
90
91 //After transformation
92 1lambda_23(x){
93 return x % 2 == 0;
94 }
95
96 main(){
97 var a = filter(1lambda_23, 1 : 2 : 3 : 4 : 5 : []);
98 }
99 \end{SPLCode}
100
101 Every anonymous functions gets a unique name outside the namespace of legal
102 names for functions making sure the name is unique. By implementing the
103 transformation in the parsing phase the function is automatically checked
104 or inferred on type.
105
106 \subsubsection{Variable arguments printing}
107 To ease the programmer we have included a parse-level transformation that
108 transforms \SI{print} with multiple arguments to multiple \SI{print} function
109 calls with a single argument. The following example shows the syntax before the
110 transformation and the syntax after the transformation.
111
112 \begin{SPLCode}
113 //Before transformation
114 print("abc", 42, 'c', "da\n");
115
116 //After transformation
117 print('a':'b':'c':[]);
118 print(42);
119 print('c');
120 print('d':'a':'\n':[]);
121 \end{SPLCode}