|0.1.3||Dec 13, 2019|
|0.1.2||Sep 14, 2019|
|0.1.1||Jun 24, 2019|
|0.1.0||Jun 24, 2019|
|0.0.1||Jun 24, 2019|
#2 in #scheme
37 downloads per month
🐳 A tiny educational Scheme compiler written in Rust that generates readable x86 assembly. Implements the paper An Incremental Approach to Compiler Construction by Abdulaziz Ghuloum. We aim to be complete, correct and fast, in that order of importance.
$ cargo build $ cargo test
Running simple programs is straight forward.
$ echo "(define (twice x) (* x 2)) (twice 21)" | cargo run -q 42
The previous step generates x86 assembly that gets compiled to a very tiny (~13KB) native executable binary along with some runtime written in Rust and some glue code in C.
$ ./inc 42 $ file inc inc: Mach-O 64-bit executable x86_64 $ stat -f "%z" inc 13556
The generated assembly is usually easy to read, and if you squint hard enough kinda looks like the source code 😉
$ echo "(define (twice x) (* x 2)) (twice 21)" | cargo run -q -- -S
.section __TEXT,__text .intel_syntax noprefix .globl "_init" "_init": push rbp mov rbp, rsp mov r12, rdi # Store heap index to R12 mov rax, 168 mov qword ptr [rbp - 24], rax call "twice" pop rbp ret .globl "twice" "twice": push rbp mov rbp, rsp mov rax, [rbp - 8] mov qword ptr [rbp - 16], rax mov rax, 16 sar rax, 3 mul qword ptr [rbp - 16] pop rbp ret
Under the hood, inc compiles scheme to x86 assembly and uses Clang (or GCC on Linux) to generate machine executable binaries.
Generate the asm
$ echo "(define (twice x) (* x 2)) (twice 21)" | cargo run -q -- -S > inc.s
Compile the runtime as well the generated assembly into shared object files
$ clang -c inc.s # Generates inc.o $ clang -c runtime.c # Generates runtime.o $ cargo build # Generates ./target/debug/libinc.dylib
Link it all together with a linker
$ ld -L./target/debug runtime.o inc.o -linc -ldl -lpthread -o inc
The same binary is generated again
$ ./inc 42
Conveniently clang can do it all in one step if you prefer it that way.
$ clang -L./target/debug inc.s runtime.c -linc -ldl -lpthread -o inc
Inc is reasonably well documented and is preferably read with Cargo docs. Build docs locally or read online (⚠ Could be outdated)
$ cargo doc --document-private-items --open
- Read the paper for an overview
- Watch a talk about this project if that works better.
- Ask HN: What's the best resource for learning modern x64 assembly?