Skip to content

asvarga/Decaf-LLVM

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

79 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Decaf

A compiler for Brown's CS126 by Alex Varga and Denizalp Goktas.

Contents of this README

Building the Compiler

$ cd [PathToDecaf]/src
$ make

The compiler should detect and target whichever architecture you are using. I have only tested it on my Mac.

Running a Program

Once the compiler is make'd, the decaf python script will compile and run your program.

It takes the optional flags -c, -l, -r for restricting to compilation/linking/running respectively.

$ cd [PathToDecaf]
$ ./decaf [PathToProgram]

Alternatively, you can add [PathToDecaf] to your $PATH or add a symlink to the decaf python script like:

$ cd [PathToDecaf]
$ ln -s decaf /usr/local/bin/decaf

Then .decaf files with hashbangs can be run like:

$ cd [PathToDecaf]/src/test2
$ ./test0.decaf

Examples

Given Examples:

$ ./test/fib.decaf
How many fibs? : 10
fib(1) = 1
fib(2) = 1
fib(3) = 2
fib(4) = 3
fib(5) = 5
fib(6) = 8
fib(7) = 13
fib(8) = 21
fib(9) = 34
fib(10) = 55

$ ./test/adder.decaf
Enter two integers: 
3
4
3 + 4 = 7

$ ./test/hello.decaf
Hello World!

$ ./test/short.decaf
144

More Examples:

$ ./test2/test0.decaf
x = 17
17 is odd

$ ./test2/test1.decaf
Enter ints, 0 to exit.
4
:)
7
:)
0
:(

$ ./test2/test2.decaf
Start the countdown at: 10
10
9
8
7
6
5
4
3
2
1
Happy New Year!

$ ./test2/test3.decaf
My name is Alex
Hello A-A-A-Alex

$ ./test2/test4.decaf
(1, 10)
(2, 10)
(3, 10)

About

This compiler uses flex and bison for parsing, and LLVM for code generation. See the Makefile for details.

The AST and operations on it make heavy use of the visitor pattern. I've done my best to avoid uses of C++'s dynamic_cast and all accept/visit methods have void return types. I wouldn't recommend this approach, because it requires delegating all desired pattern matching to the parser, and storing information about variants in AST nodes in somewhat hacky ways. This might be extra performant but is a painful process.

Code generation targets LLVM's IR. A first pass Visitor (Pass1V) pins a hodgepodge of various information onto AST nodes, like class and method symbol tables, depth/index values, pointers to parents, etc. These are used by the main visitor (CodeGenV) which uses LLVM's IRBuilder.

The generated IR code uses lots of memory loads/stores instead of register operations. This is fine because LLVM provides createPromoteMemoryToRegisterPass which is self explanatory, and allows us to keep out code-generating code simpler. There are lines in parser.ypp which can be uncommented to print the generated IR code.

Finally, the generated object file is linked against decaffuntime.c which calls the code's _$DecafMain method, which itself calls whichever main method is found in the decaf file. The generated code is made aware of the runtime's methods through explicit LLVM declare statements, rather than using decaf_runtime.h. See the decaf python script for details.

About

A compiler for Brown's CS126 by Alex Varga and Denizalp Goktas.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published