4 |
4 |
5 section{*Case study: compiling expressions*} |
5 section{*Case study: compiling expressions*} |
6 |
6 |
7 text{*\label{sec:ExprCompiler} |
7 text{*\label{sec:ExprCompiler} |
8 The task is to develop a compiler from a generic type of expressions (built |
8 The task is to develop a compiler from a generic type of expressions (built |
9 up from variables, constants and binary operations) to a stack machine. This |
9 from variables, constants and binary operations) to a stack machine. This |
10 generic type of expressions is a generalization of the boolean expressions in |
10 generic type of expressions is a generalization of the boolean expressions in |
11 \S\ref{sec:boolex}. This time we do not commit ourselves to a particular |
11 \S\ref{sec:boolex}. This time we do not commit ourselves to a particular |
12 type of variables or values but make them type parameters. Neither is there |
12 type of variables or values but make them type parameters. Neither is there |
13 a fixed set of binary operations: instead the expression contains the |
13 a fixed set of binary operations: instead the expression contains the |
14 appropriate function itself. |
14 appropriate function itself. |
21 |
21 |
22 text{*\noindent |
22 text{*\noindent |
23 The three constructors represent constants, variables and the application of |
23 The three constructors represent constants, variables and the application of |
24 a binary operation to two subexpressions. |
24 a binary operation to two subexpressions. |
25 |
25 |
26 The value of an expression w.r.t.\ an environment that maps variables to |
26 The value of an expression with respect to an environment that maps variables to |
27 values is easily defined: |
27 values is easily defined: |
28 *} |
28 *} |
29 |
29 |
30 consts value :: "('a,'v)expr \<Rightarrow> ('a \<Rightarrow> 'v) \<Rightarrow> 'v"; |
30 consts value :: "('a,'v)expr \<Rightarrow> ('a \<Rightarrow> 'v) \<Rightarrow> 'v"; |
31 primrec |
31 primrec |
33 "value (Vex a) env = env a" |
33 "value (Vex a) env = env a" |
34 "value (Bex f e1 e2) env = f (value e1 env) (value e2 env)"; |
34 "value (Bex f e1 e2) env = f (value e1 env) (value e2 env)"; |
35 |
35 |
36 text{* |
36 text{* |
37 The stack machine has three instructions: load a constant value onto the |
37 The stack machine has three instructions: load a constant value onto the |
38 stack, load the contents of a certain address onto the stack, and apply a |
38 stack, load the contents of an address onto the stack, and apply a |
39 binary operation to the two topmost elements of the stack, replacing them by |
39 binary operation to the two topmost elements of the stack, replacing them by |
40 the result. As for @{text"expr"}, addresses and values are type parameters: |
40 the result. As for @{text"expr"}, addresses and values are type parameters: |
41 *} |
41 *} |
42 |
42 |
43 datatype ('a,'v) instr = Const 'v |
43 datatype ('a,'v) instr = Const 'v |
64 text{*\noindent |
64 text{*\noindent |
65 Recall that @{term"hd"} and @{term"tl"} |
65 Recall that @{term"hd"} and @{term"tl"} |
66 return the first element and the remainder of a list. |
66 return the first element and the remainder of a list. |
67 Because all functions are total, @{term"hd"} is defined even for the empty |
67 Because all functions are total, @{term"hd"} is defined even for the empty |
68 list, although we do not know what the result is. Thus our model of the |
68 list, although we do not know what the result is. Thus our model of the |
69 machine always terminates properly, although the above definition does not |
69 machine always terminates properly, although the definition above does not |
70 tell us much about the result in situations where @{term"Apply"} was executed |
70 tell us much about the result in situations where @{term"Apply"} was executed |
71 with fewer than two elements on the stack. |
71 with fewer than two elements on the stack. |
72 |
72 |
73 The compiler is a function from expressions to a list of instructions. Its |
73 The compiler is a function from expressions to a list of instructions. Its |
74 definition is pretty much obvious: |
74 definition is obvious: |
75 *} |
75 *} |
76 |
76 |
77 consts comp :: "('a,'v)expr \<Rightarrow> ('a,'v)instr list"; |
77 consts comp :: "('a,'v)expr \<Rightarrow> ('a,'v)instr list"; |
78 primrec |
78 primrec |
79 "comp (Cex v) = [Const v]" |
79 "comp (Cex v) = [Const v]" |