1 / 34

Calculating Compilers from High-Level Semantics: A Purely Calculational Approach

Learn how to make compilers using a stepwise approach, starting from high-level semantics and gradually adding stack and continuation operations. The process leverages simple techniques and guarantees correctness. The approach scales to handle various language features.

jonesv
Download Presentation

Calculating Compilers from High-Level Semantics: A Purely Calculational Approach

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. How To Make Sausages

  2. How To Make Compilers? language compiler

  3. 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 mechanically verified; • Scales to exceptions, state, variable binding, loops, non-determinism, interrupts, etc.

  4. Arithmetic Expressions Syntax: data Expr = Val Int | Add Expr Expr Semantics: eval :: Expr  Int eval (Val n) = n eval (Add x y) = eval x + eval y

  5. Example 1 + (2 + 3) Add (Val 1) (Add (Val 2) (Val 3)) 6

  6. Step 1 – Stacks Make the manipulation of arguments explicit by transforming the semantics to use a stack. Aim: define a new semantics eval' :: Expr  Stack  Stack such that Stack = [Int] = eval' e s eval e : s

  7. Case for addition: eval' (Add x y) s = add (n:m:s) = m+n : s eval (Add x y) : s = (eval x + eval y) : s = add (eval y : eval x : s) = add (eval y : eval' x s) = add (eval' y (eval' x s))

  8. New semantics: eval' :: Expr  Stack  Stack eval' (Val n) s = push n s eval' (Add x y) s = add (eval' y (eval' x s)) Stack operations: push n s = n : s add (n:m:s) = m+n : s

  9. 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.

  10. eval x + eval y computation continuation Example: Basic idea: Generalise the semantics to make the use of continuations explicit.

  11. Aim: define a new semantics eval'' :: Expr  Cont  Cont Cont = Stack  Stack such that = eval'' e c s c (eval' e s)

  12. New semantics: eval'' :: Expr  Cont  Cont eval'' (Val n) c s = c (push n s) eval'' (Add x y) c s = eval'' x (eval'' y (c . add)) s Previous semantics: eval' :: Expr  Cont eval' e s = eval'' e id s

  13. Step 3 – Defunctionalise Make the semantics first-order again by applying the technique of defunctionalisation. Basic idea: Represent the continuations that we actually need using a datatype.

  14. This can be achieved in a simple manner. eval'' :: Expr  Cont  Cont eval'' (Val n) c s = c (push n s) eval'' (Add x y) c s = eval'' x (eval'' y (c . add)) s eval' :: Expr  Cont eval' e s = eval'' e id s Make the stack argument implicit.

  15. This can be achieved in a simple manner. eval'' :: Expr  Cont  Cont eval'' (Val n) c = c . push n eval'' (Add x y) c = eval'' x (eval'' y (c . add)) eval' :: Expr  Cont eval' e = eval'' e id Identify the forms of continuations used.

  16. This can be achieved in a simple manner. eval'' :: Expr  Cont  Cont eval'' (Val n) c = c . push n eval'' (Add x y) c = eval'' x (eval'' y (c . add)) eval' :: Expr  Cont eval' e = eval'' e id Represent them using a datatype.

  17. This can be achieved in a simple manner. comp' :: Expr  Code  Code comp' (Val n) c = PUSH n c comp' (Add x y) c = comp' x (comp' y (ADD c)) comp :: Expr  Code comp e = comp' e HALT A compiler for expressions! 

  18. Example 1 + (2 + 3) PUSH 1 PUSH 2 PUSH 3 ADD ADD HALT

  19. New datatype and its interpretation: data Code = PUSH Int Code | ADD Code | HALT 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 expressions!

  20. Example 1 + (2 + 3) Code Stack PUSH 1 PUSH 2 PUSH 3 ADD ADD HALT

  21. Example 1 + (2 + 3) Code Stack PUSH 2 PUSH 3 ADD ADD HALT 1

  22. Example 1 + (2 + 3) Code Stack PUSH 3 ADD ADD HALT 2 1

  23. Example 1 + (2 + 3) Code Stack ADD ADD HALT 3 2 1

  24. Example 1 + (2 + 3) Code Stack ADD HALT 5 1

  25. Example 1 + (2 + 3) Code Stack HALT 6

  26. Example 1 + (2 + 3) Code Stack 6

  27. Compiler Correctness Is captured by the following two equations: = exec (comp e) s eval e : s = exec (comp’ e c) s exec c (eval e : s) These follow from defunctionalisation, or can be verified by simple inductive proofs.

  28. Reflection We now have a three step process for calculating a correct compiler from a high-level semantics: 1 - Add a stack 2 - Add a continuation 3 - Remove the continuations Can the steps be combined?

  29. The Trick Start directly with the correctness equations: = exec (comp e) s eval e : s = exec (comp’ e c) s exec c (eval e : s) Aim to calculate definitions for comp, comp’, exec and Code that satisfy these equations.

  30. 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.

  31. 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.

  32. Ongoing Work • Register-based machines; • Real source/target languages; • Mechanical assistance; • Funding application.

More Related