Cheez is a small programming language I created in 2018. It's more on the low level side, inspired by Rust and uses LLVM as it's backend.
It is statically and strongly typed with C-like memory management, so no garbage collector. It doesn't use semicolons, has parametric polymorphism (I think that's what it's called), defer
, virtual functions using trait objects, slices, type inference and more.
Some features I plan to implement someday are lambdas, pattern matching, something like Rust's borrow checker but less restrictive and compile time code execution.
A detailed description of each feature can be found here (early in progress).
The compiler is written in C#. I also wrote a Language Server, but I haven't maintained it so it's not even compiling right now. There is also a VSCode extension which provides basic syntax highlighting and access to the language server.
You can download it from the releases page.
Here are some simple examples, more advanced examples can be found here
Here's what a Hello World program looks like:
io :: import std.io
Main :: () {
io.println("Hello World.")
}
A fibonacci calculator, starting at index 0:
io :: import std.io
fib :: (x: int) -> int {
if x <= 1 {
return 1
}
return fib(x - 1) + fib(x - 2)
}
Main :: () {
x := fib(5)
io.formatln("fib(5) = {}", [x])
}
Greatest common divisor:
io :: import std.io
// iterative implementation
gcd_it :: (mut a: int, mut b: int) -> int {
if a == 0 {
return b
}
while b != 0 {
if a > b {
a = a - b
} else {
b = b - a
}
}
return a
}
// recursive implementation
gcd_rec :: (a: int, b: int) -> int {
if b == 0 {
return a
}
return gcd_rec(b, a % b)
}
Main :: () {
io.formatln("gcd_it(9, 6) = {}", [gcd_it(9, 6)])
io.formatln("gcd_rec(9, 6) = {}", [gcd_rec(9, 6)])
}
Vectors and trait implementation:
use import std.string
use import std.printable
io :: import std.io
fmt :: import std.fmt
Vec3 :: struct #copy {
x : double
y : double
z : double
}
impl Vec3 {
add :: (Self, other: Vec3) -> Vec3 #operator("+") {
return Vec3(
x = self.x + other.x
y = self.y + other.y
z = self.z + other.z
)
}
}
impl Printable for Vec3 {
print :: (&Self, str: &mut String, format: string) {
fmt.format_into(str, "({}, {}, {})", [self.x, self.y, self.z])
}
}
Main :: () {
a := Vec3(1, 2, 3)
b := Vec3(x = 4, y = 5, z = 6)
c := a + b
io.formatln("
{}
+ {}
------------------------------
= {}", [a, b, c])
}
Generic dynamic array:
mem :: import std.mem.allocator
fmt :: import std.fmt
io :: import std.io
Main :: () {
mut ints := Array[int].new()
ints.add(3)
ints.add(2)
ints.add(1)
for v, i in &ints {
io.formatln("ints[{}] = {}", [i, v])
}
}
Array :: struct(T: type) {
data : ^mut T
length : int
capacity : int
}
impl(T: type) Array[T] {
new :: () -> Self {
return Array[T](
length = 0
capacity = 10
data = mem.alloc_raw(T, 10)
)
}
add :: (&mut Self, val: int) {
if capacity <= length {
capacity = capacity * 2
data = mem.realloc_raw(data, u64(capacity))
}
data[length] = val
length += 1
}
get :: (&Self, index: int) -> int #operator("[]") {
return self.data[index]
}
}
impl(T: type) Drop for Array[T] {
drop :: (&Self) {
mem.free(self.data)
}
}
for_extension_array :: (self: &Array[$T], body: Code) #for {
for i in 0..self.length {
it_index := i
it := self[i]
@insert(body, _break=break, _continue=continue)
}
}
Run the compiler using this command in Windows Command Line:
cheezc.exe test.che
test.exe
Powershell
.\cheezc.exe .\test.che
.\test.exe
Compiler options:
Option | Description |
---|---|
-r, --run | (Default: false) Specifies whether the code should be run immediatly |
-o, --out | (Default: .) Output directory: --out |
--int | Intermediate directory: --int |
-n, --name | Name of the executable generated: |
--print-ast-raw | Print the raw abstract syntax tree to a file: --print-ast-raw |
--print-ast-analysed | Print the analysed abstract syntax tree to a file: --print-ast-analysed |
--no-code | (Default: false) Don't generate an executable |
--no-errors | (Default: false) Don't show error messages |
--ld | Additional include directories: --ld [ []...] |
--libs | Additional Libraries to link to: --libs [ []...] |
--subsystem | (Default: console) Sub system: --subsystem [windows |
--modules | Additional modules: --modules [: [:]...] |
--stdlib | Path to the standard library: --stdlib |
--opt | (Default: false) Perform optimizations: --opt |
--emit-llvm-ir | (Default: false) Output .ll file containing LLVM IR: --emit-llvm-ir |
--time | (Default: false) Print how long the compilation takes: --time |
--test | (Default: false) Run the program as a test. |
--trace-stack | (Default: false) Enable stacktrace (potentially big impact on performance): --trace-stack |
--error-source | (Default: false) When reporting an error, print the line which contains the error |
--preload | Path to a .che file used to import by default |
--print-linker-args | (Default: false) Print arguments passed to linker |
--language-server-tcp | (Default: false) Launch language server over tcp |
--port | (Default: 5007) Port to use for language server |
--language-server-console | (Default: false) Launch language server over standard input/output |
--parent-pid | (Default: -1) Process id of process launching this program. Used in language server mode to exit language server when parent exits |
--help | Display this help screen. |
--version | Display version information. |