moonshot

technical

coff

self-hosted

coff is written in c0 and compiles its own source. that is the milestone that lets the whole stack lean on as little outside itself as it can. the compiler that first bootstrapped it, coff0 (explained below), now serves only as a testing oracle. every self-hosted build is checked byte-for-byte against it,a byte-for-byte match means the self-hosted compiler produces exactly the same output as the reference, which is strong evidence it did not drift as it took over from the bootstrap. so the two must agree. moonshot itself is built through the self-hosted compiler alone.

coff0

a self-hosted compiler has a chicken-and-egg problem. coff is written in c0, so something else had to compile it the very first time.the naming follows the generations, coff0 is the zeroth compiler, the one that existed before c0 could compile anything, the self-hosted compiler it built is coff1. that something is coff0, a compiler for the same c0 language, written in plain C and built with an ordinary C compiler. it existed for exactly one purpose, to compile the first c0-written coff, and once that build could compile itself, coff0 was retired from the build entirely.

splitting source across files

to keep large programs manageable, c0 has one simple tool for splitting source across files, an include directive, resolved by coff as plain textual substitution before compilation begins.

include "jenna.c0";
include "chrone.c0";
include "punkt.c0";

this is substitution, not separate compilation.the included files are spliced in as raw text, and one flat buffer reaches the compiler, exactly as a single file always has. the parser does not even know the feature exists. it is enough to break a growing kernel into files named after its parts, without inventing a whole module system before one is needed.

inside the compiler

coff is a straight pipeline. include expansion produces one flat buffer of source, a lexer turns it into tokens, a parser builds the program from those tokens, and code generation emits x86_64 assembly, which the system assembler and linker turn into a freestanding binary. there is no optimiser, the point, for now, is output that is simple and easy to check.

the dashed stage is the one step coff does not do itself. the assembly it emits is handed to the system's assembler and linker. everything above that line is coff's own.

source

coff and the whole test suite live at github.com/cofflang/coff. the readme walks through bootstrapping it with nothing but a C compiler, the system assembler and linker. after that first build it compiles itself. contributions are welcome.