Upload
jane-cunningham
View
43
Download
1
Embed Size (px)
DESCRIPTION
How To Make Sausages. How To Make Compilers?. language. compiler. This Talk. A new approach to the problem of calculating compilers from high-level semantics; Only requires simple techniques, and all the calculations have been formalised in Coq; - PowerPoint PPT Presentation
Citation preview
4
This Talk
A new approach to the problem of calculating compilers from high-level semantics;
Only requires simple techniques, and all the calculations have been formalised in Coq;
Scales to exceptions, state, variable binding, loops, non-determinism, interrupts, etc.
5
Arithmetic Expressions
data Expr = Val Int | Add Expr Expr
eval :: Expr Int
eval (Val n) = n
eval (Add x y) = eval x + eval y
Syntax:
Semantics:
7
Step 1 – Stacks
Aim: define a new semantics
evalS :: Expr Stack Stack
evalS e s = eval e : s
such that
Make the manipulation of arguments explicit by transforming the semantics to use a stack.
Stack = [Int]
8
evalS (Add x y) s
Case for addition:
eval (Add x y) : s
=
(eval x + eval y) : s=
add (evalS y (evalS x s))=
add (eval y : evalS x s)=
add (eval y : eval x : s)=
add (n:m:s) = m+n : s
9
New semantics:
evalS :: Expr Stack Stack
evalS (Val n) s = push n s
evalS (Add x y) s = add (evalS y (evalS x s))
Stack operations:
push n s = n : s
add (n:m:s) = m+n : s
10
Step 2 – Continuations
Make the flow of control explicit by transforming the semantics into continuation-passing style.
Definition:
A continuation is a function that is applied to the result of another
computation.
11
Aim: define a new semantics
evalC e c s = c (evalS e s)
such that
evalC :: Expr Cont Cont
Cont = Stack Stack
12
New semantics:
evalC :: Expr Cont Cont
evalC (Val n) c s = c (push n s)
evalC (Add x y) c s = evalC x (evalC y (c . add)) s
Previous semantics:
evalS :: Expr Stack Stack
evalS e = evalC e (λs s)
13
Step 3 - Defunctionalise
Basic idea:
Represent the continuations that we actually need using a
datatype.
Make the semantics first-order again by applying the technique of defunctionalisation.
14
comp :: Expr Code
comp e = comp’ e HALT
New semantics:
comp’ :: Expr Code Code
comp’ (Val n) c = PUSH n c
comp’ (Add x y) c = comp’ x (comp’ y (ADD c))
A compiler for arithmetic expressions!
16
data Code = PUSH Int Code | ADD Code | HALT
New datatype and its interpretation:
exec :: Code Stack Stack
exec (PUSH n c) s = exec c (n:s)
exec (ADD c) (n:m:s) = exec c (m+n : s)
exec HALT s = s
A virtual machine for arithmetic expressions!
Compiler Correctness
24
Is captured by the following two equations:
These follow from defunctionalisation, or can be
verified by simple inductive proofs.
exec c (eval e : s)
exec (comp e) s eval e : s=
exec (comp’ e c) s =
25
Reflection
We now have a three step process for calculating a correct compiler from a high-level semantics:
Can the steps be combined?
1 - Add a stack2 - Add a continuation3 - Remove the continuations
The Trick
26
Start directly with the correctness equations:
Aim to calculate definitions for comp, comp’, exec and Code that satisfy
these equations.
exec c (eval e : s)
exec (comp e) s eval e : s=
exec (comp’ e c) s =
27
In Practice
Calculating four interlinked definitions at the same time seems like an impossible task;
But… with experience gained from our stepwise approach, it turns out to be straightforward;
New calculation is simpler, more direct, and has the same structure as our stepwise version.
28
Summary
Purely calculational approach to developing compilers that are correct by construction;
Only requires simple techniques, and scales to a wide variety of language features;
More sophisticated languages also introduce the idea of using partial specifications.
29
Further Work
Register-based machines;
Real source/target languages;
Mechanical assistance;
EPSRC application.