ourc Node: Top Next: 1 Using ourc Up: (dir)

ourc is a Rust compiler grown from 269 bytes of machine code.

ourc is a bootstrapped-from-hex-code compiler that emits LLVM IR and passes 54% of rustc’s test suite and counting. We have a Rust crate, too.

$ cargo install ourc-bootstrap && ourc-bootstrap OUT # the whole tower from the hand-written hex, about 20 minutes

Read the manual → Verify it yourself github.com/jaredef/ourc

L0/hex0/hex0.hand.hexthis is just a tribute
31 c0           # xor  eax, eax   ; read = 0
31 ff           # xor  edi, edi   ; fd 0
be 0d 01 40 00  # mov  esi, IN    ; buf
ba 00 00 01 00  # mov  edx, 64 KiB
0f 05           # syscall         ; nbytes
48 8d 14 06     # lea  rdx, [rsi+rax]
bf 0d 01 41 00  # mov  edi, OUT
45 31 c0        # xor  r8d, r8d   ; pending
                # loop:
48 39 d6        # cmp  rsi, rdx
73 50           # jae  done       ; +80
0f b6 06        # movzx eax, [rsi]
48 ff c6        # inc  rsi
3c 23           # cmp  al, '#'
74 35           # je   comment    ; +53
Every byte and every jump offset worked out by hand from the x86-64 manual. The file is both the seed’s source and its documentation.

The tower

Eight rungs, each compiled by the one below it. The only binaries taken from the repository are the two hex seeds, and each must rebuild itself from its commented hex.

The tower’s code generator is built twice, by two different compilers, which must agree byte for byte.

  1. ourcRust → LLVM IR, and compiles itself51,210 lines
  2. SEM0A semantic Rust compiler, in 28 hops30,185 lines
  3. L5 · L6The self-hosting Rust bootstrap11,225 lines
  4. L4The first Rust compiler written in Rust2,306 lines
  5. L3A Rust-subset compiler, in C1,060 lines
  6. L2ccc, a self-hosting C compiler2,168 lines
  7. L1A C front-end, in M0 assembly5,635 lines
  8. L0hex0 → hex1 → hex2 → M0, by hand269 bytes

We don’t ever miscompile Rust. If ourc can’t do it, it just refuses to do so.

A program ourc accepts runs exactly as rustc’s build of it runs. A program it can’t compile faithfully gets an error, never a wrong answer.
points.rs ×
1
2
3
4
5
6
7
8
9
10
11
12
13
14
struct Point { x: i32, y: i32 }

fn dist2(p: &Point) -> i32 {
    p.x * p.x + p.y * p.y
}

fn main() {
    let pts = vec![Point { x: 3, y: 4 },
                   Point { x: 1, y: 1 }];
    let total: i32 =
        pts.iter().map(dist2).sum();
    println!("sum of squared distances: {}",
             total);
}
$ ourc points.rs -o points && ./points
sum of squared distances: 27
accepted · runs as rustc’s build runsRust
half.rs ×
1
2
3
fn main() {
    let x: f32 = 1.5;
}
$ ourc half.rs -o half
ourc[O0] half.rs -> error[23..24]:
  expected `a type other than `f32`
  (f32 is not implemented; f64 is)`,
  found `f32`
$ echo $?
1
refused · exit 1, no file writtenRust

No file is written. The error names the construct ourc stopped at.