30
CALCULATING CORRECT COMPILERS Graham Hutton and Patrick Bahr
• Upload

jane-cunningham
• Category

## Documents

• view

43
• download

1

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

### Transcript of How To Make Sausages

CALCULATINGCORRECT COMPILERS

Graham Hutton and Patrick Bahr

2

How To Make Sausages

3

How To Make Compilers?

language compiler

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:

Example

6

1 + (2 + 3)

Add (Val 1) (Add (Val 2) (Val 3))

6

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!

15

1 + (2 + 3)

Example

PUSH 1PUSH 2PUSH 3ADD ADDHALT

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!

17

1 + (2 + 3)

Example

PUSH 1PUSH 2PUSH 3ADD ADDHALT

Stack

Code

18

1 + (2 + 3)

Example

PUSH 2PUSH 3ADD ADDHALT

Stack

Code

1

19

1 + (2 + 3)

Example

PUSH 3ADD ADDHALT

Stack

Code

21

20

1 + (2 + 3)

Example

ADD ADDHALT

Stack

Code

321

21

1 + (2 + 3)

Example

ADDHALT

Stack

Code

51

22

1 + (2 + 3)

Example

HALT

Stack

Code

6

23

1 + (2 + 3)

Example

Stack

Code

6

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.

CALCULATINGCORRECT COMPILERS

Graham Hutton and Patrick Bahr