I’ve just released a proper working version of Cowgol 2.0, a brand new version of my small language for small systems. Better type checking! Better syntax! Better code generation! Better compilation speed! And, ironically, this was mostly achieved by drastically simplifying it and reducing functionality…
So, this is a complete rewrite, from the ground up, of the old Cowgol, which was far too complicated, slow, and difficult to use. As I’ve been working on this since 2017 a quick summary of Cowgol: it’s a strongly typed self-hosted programming language and compiler, where the compiler is written in itself, designed to produce code for and also to run on very small systems. I’ve been targeting a Z80 or 8080 running CP/M, and a 6502 running the BBC Micro TubeOS, but it will also generate code for a few other architectures, including ix86. The language has about the expressivity of ANSI C, with a few bonus features like proper 8-bit arithmetic. See the link above for a sample.
tl;dr: if you were patient you could compile programs on a Commodore 64. But I haven’t done a port to the Commodore 64 yet, so here’s the 6502 compiler in action running on an emulated BBC Master Turbo, courtesy of Matt Godbolt’s jsbeeb emulator. Press SHIFT+F12 (that’s SHIFT+BREAK on a real BBC Micro) to boot the disk and start the compiler.
The new version features:
- a proper parser (using Lemon)
- a table based backend which is simpler to port and produces better code
- a proper register allocator (based on destination driven allocation, which is absurdly simple and produces good results)
- fewer compiler stages (two executables rather than one; the compiler originally had everything in a single executable but that made space too tight on 8-bit systems)
- better code quality (it’s actually pretty good in places)
- modular compilation
- a linker
- smaller binaries (the Z80 compiler is two executables, one 32kB and the other 26kB).
It will target:
- Z80 (for CP/M)
- 8080 (also for CP/M)
- NMOS 6502
- 65C02 (this is the version in the demo above)
- 6502 interpreted bytecode (the compiler generates Forth-like bytecode with a built-in interpreter in the executable. It’s much smaller, but also way slower.)
- Intel 80386 (I use this for testing the compiler locally)
- C (it’s huge, terrible C, but it makes bootstrapping the compiler much easier)
Adding new backends is pretty straightforward — the 80386 backend is 1200 lines of code, most of which are helper routines for emitting instructions. Of course, it’s not very optimised. The 6502 backend is about twice that because the 6502 is so unorthogonal.
My next stop is probably a H6303 backend because I need to run some code on one and porting the compiler is frankly easier than writing machine code by hand.