c0
c0 compiles to freestanding binaries, code that assumes no runtime and no standard library beneath it,which is the only way a language can be used to write a kernel because the thing it is meant to write is a kernel. the feature set grows only when moonshot actually needs it. that is why c0 was pushed past the point of merely compiling itself, and on toward being a real, capable language.
one type
c0 has a single value type: int, a 64-bit signed
integer.there is no unsigned type and no array type. a consequence worth knowing is that division is signed and truncating, so packed bit patterns are kept below 32 bits where the sign bit cannot interfere.
everything is an int: numbers, characters, truth values and addresses.
memory is handled through an address value, and the builtins below read and write through it.
the shape of a program
the syntax is a small, familiar subset of C. functions (up to six parameters, with
recursion), global and local variables, if/else,
while, the usual arithmetic and comparison operators, character
literals with escapes, string literals, and // comments. a program
starts at main. source can be split across files with the
include directive, which coff resolves
by plain textual substitution.
include "file.c0";
// this is a comment.
int main() {
int i = 0;
int sum = 0;
while (i < 5) {
sum = sum + i;
i = i + 1;
}
return sum;
}
builtins instead of a standard library
there is no standard library. a small set of builtins covers what the language
itself cannot express. alloc hands out zeroed memory, and
load8/store8/load64/store64
read and write it a byte or eight bytes at a time. print and
write produce output, open and read take
files in, and exit ends the program. hosted programs (like coff
itself) get argc/argv. the kernel uses none of the hosted
builtins and talks to hardware through the load/store pair instead.
the set is not frozen, a builtin is added when moonshot needs one the language cannot otherwise reach, the same rule the language itself grows by. a general standard library, though, is not a goal, for now, the kernel is meant to build what it needs out of the primitives above.
the whole language
this is the entire vocabulary, c0 is small enough that it fits in a list.
- types
intonly, a 64-bit signed integer, which also stands in for characters, truth values and addresses.- keywords
int,if,else,while,return,break,continue.- directives
include "file.c0";splices another source file in as text, resolved by coff before compilation.- structure
- functions of up to six parameters (recursion allowed), global and local variables, and
mainas the entry point. - operators
- the arithmetic
+ - * /, the comparisons== != < <= > >=, and=for assignment. - literals
- integers, character literals with escapes, and string literals.
- comments
//to the end of the line.- builtins
alloc,load8,store8,load64,store64,print,write,open,read,exit, and (hosted only)argc,argv, described just above.
things are missing on purpose
a feature is added when moonshot produces a concrete need for it, and not before, because every feature the language gains is also code the compiler must carry, correctly, forever. c0 has to stay small enough that its compiler can be held in your head and re-verified against the bootstrap oracle.