I didn’t really have a plan, but I went ahead and started making this compiler from scratch in C anyways. Now we have a functioning compiler with a brand new language that has still not even been named.
Running the compiler executable with no arguments will display a usage message that contains compiler flags and options as well as command layout.
Dependencies:
- CMake >= 3.14
- Any C Compiler (We like GCC)
First, generate a build tree using CMake.
cmake -B bld
Finally, build an executable from the build tree.
cmake --build bld
GNU Binutils:
as code.S -o code.o
ld code.o -o code
GNU Compiler Collection
gcc code.S -o code.exe
LLVM/Clang
clang code.S -o code.exe --target=x86_64
To use external calls, link with appropriate libraries!
The language is statically typed. Variables must be declared and type annotated before use.
Whitespace is ignored and there are no required expression delimiters. That’s right: no semi-colons and no forced indent!
Functions are first-class citizens.
A program in this language comes in the form of a file. The file may
contain a series of expressions that will be executed in order, from
top to bottom. There is no main
function or other entry point;
control flow starts at the very top of the file and makes it’s way to
the bottom of the file.
Let’s take a look at a basic program:
fact : integer (n : integer) = integer (n : integer) { if n < 2 { 1 } else { n * fact(n - 1) } } fact(5)
This program will return 120 as a status code. The result of the last expression in the file is the return value. The same holds true for function bodies, and if/else bodies.
Variables in a local scope shadow variables in a parent scope, and may share the same symbolic name.