title | author | date | css |
---|---|---|---|
Compiling a simple functional language<br> with LLVM and Haskell
|
Andreas Herrmann<br> <a href="https://github.com/aherrmann/simply_llvm">
<i class="fa fa-github" aria-hidden="true"></i>
github.com/aherrmann/simply_llvm
</a>
|
November 24, 2016 |
-
Compiler toolchain
-
native code for multiple targets (x86, x86_64, ARM, and many more)
-
target independent optimizer
-
just in time (JIT) compiler
-
-
Abstract assembly language
-
infinite virtual registers
-
static single assignment (SSA) form
-
-
Simply-typed lambda calculus
-
Base types:
Int
,Bool
; and function types:a -> b
-
Literals, Variables
-
Branches
-
Primitive operations:
+
,-
,*
,==
-
Lambda abstraction, and function application
-
non-recursive let-bindings
-
mutually recursive global bindings
-
one main function
Calculate the factorial of the given number
globals
factorial' (acc : Int) (n : Int) : Int =
if n == 0 then
acc
else
factorial' (acc * n) (n - 1)
factorial (n : Int) : Int =
factorial' 1 n
main (n : Int) =
factorial n
-
higher order functions
-
closures
-
functions as values
globals
apply (f : Int -> Int) (x : Int) : Int =
f x
mkAdder (a : Int) : Int -> Int =
(+) a
main (n : Int) =
let
add3 = mkAdder 3
in
apply add3 n
-
Parse to AST (not implemented)
-
Type-check
-
Convert to intermediate representation
-
Convert to LLVM IR
-
(Optimize)
-
Generate native code
-
Execute
Difference between "Simply" and LLVM:
-
In LLVM everything is explicitly typed (annotated AST)
-
LLVM distinguishes local and global variables explicitly
-
LLVM only allows global function definitions
-
LLVM has no closures
-
In LLVM all function have to be fully applied
-
(Up to closures)
-
(Up to closures)
-
Closure captures environment and expects arguments
-
Global function that takes environment and arguments
-
Parsing, Pretty-Printing, Testing
-
Garbage Collection
-
Polymorphism (Damas–Hindley–Milner)
-
Dependent Types
-
Backend for Morte