Crane: Week One
Today marks one week since I started working on my programming language, Crane.
An Introduction
Crane is a language for writing robust and elegant software that will endure over time.
It's statically typed, compiles to native code with an (eventual) garbage collector1, and comes with the features you'd expect of a modern language, like sum types and no nulls.
Crane currently supports the following types:
()
- The unit typeUint64
- A 64-bit unsigned integerString
- An immutable string of UTF-8 characters
There's also the minimal beginnings of a standard library that contains the following functions:
fn print(value: String) {}
fn println(value: String) {}
fn int_add(a: Uint64, b: Uint64) -> Uint64 {}
fn int_to_string(value: Uint64) -> String {}
Here's an example of a small Crane program:
fn main() {
let world = "世界"
hello(world)
}
fn hello(name: String) {
print("你好,")
print(name)
println("。")
}
Running this through the Crane compiler will produce a single-file binary which we can then execute:
$ ./build/main
你好,世界。
Compile-time errors
Being a statically-typed language, Crane will provide you with helpful errors at compile time when there are issues with your program:
Building excellent compiler errors is going to be a lot of work, but I think it's an important aspect of the language. By putting in a good diagnostic framework early my hope is that it will help make it easier to build with good errors in mind.
Syntax
If you're familiar with Rust at all, you might have noticed that Crane's syntax is decidedly Rust-like. This is no accident.
I think Rust gets a tremendous amount right as a language, both in terms of syntax and language features. The design of Crane owes a lot to Rust as an inspiration.
Of course, there are—and will continue to be—differences as Crane evolves and comes into its own.
A Peek Under the Hood
The Crane compiler is written in Rust. This was an obvious choice for me.
Rust is very well-suited to compiler development, and there is a wealth of crates available to help with the language-building process.
Some of the crates that power the Crane compiler:
clap
for powering the compiler CLIlogos
for lexingariadne
for reporting errors and diagnosticsinkwell
for interacting with LLVM in the backendinsta
for snapshot testing
At time of writing the Crane codebase is just shy of 2,500 lines of code:
It's still very much early days for Crane and there's a long road ahead before it becomes a "real" language, but I'm very happy with the progress of this first week.
I expect to write more of these posts about Crane in the future.
In the meantime, you can check out the Crane repo on GitHub if you'd like to follow along with Crane's development.
Currently Crane programs just gratuitously leak memory.