The Sunder Programming Language
Add support for higher half kernel mappings
Fix for-range loop bug where jge was used instead of jnb for the loop exit condition


browse  log 
release notes 



You can also use your local clone with git send-email.

#The Sunder Programming Language

Sunder is a C-like systems programming language and compiler for x86-64 Linux.


  • POSIX-compatible make
  • Supported toolchain containing:
    • C99 compiler (POSIX c99, clang, gcc, etc.)
    • ld
  • nasm or yasm
  • clang-format (development only)

Dependencies can be installed on Debian-based distros (amd64) with:

$ apt-get install build-essential clang clang-format nasm yasm


#Quick Version

Run make build to build the compiler.

Run make check examples to run the test suite and compile the example programs under the examples directory.

#Long Version

The top-level Makefile contains the following important targets:

  • build => Build the compiler.
  • check => Run the test suite for the language and standard library.
  • examples => Compile the example programs under the examples directory.
  • format => Run clang-format over the compiler sources.
  • clean => Remove build artifacts.

Targets will execute with CC=c99 and CFLAGS='-O0 -g' by default. Additional compiler/compiler-flag combinations are listed below, but the default CC and CFLAGS selection should be fine for most cases.

Specific compiler/compiler-flag combinations include:

$ make <targets> CFLAGS='$(C99_DBG)'  # POSIX c99 (debug)
$ make <targets> CFLAGS='$(C99_REL)'  # POSIX c99 (release)

$ # Use CC=clang for Clang or CC=gcc for GCC
$ make <targets> CC=clang CFLAGS='$(GNU_DBG)'              # clang/gcc (debug)
$ make <targets> CC=clang CFLAGS='$(GNU_DBG) $(SANITIZE)'  # clang/gcc (debug with Address Sanitizer)
$ make <targets> CC=clang CFLAGS='$(GNU_REL)'              # clang/gcc (release)

The compiler is built with SUNDER_DEFAULT_BACKEND=yasm by default, indicating that yasm should be used if SUNDER_BACKEND (explained below) is not set when the compiler is invoked. To use nasm as the default compiler backend, override SUNDER_DEFAULT_BACKEND with nasm when executing targets:

$ make <targets> SUNDER_DEFAULT_BACKEND=nasm


The install target will install the Sunder toolchain into the directory specified by SUNDER_HOME (default $HOME/.sunder). Run make install with SUNDER_HOME specified as the directory of your choice:

$ make install                          # Install to the default $HOME/.sunder
$ make install SUNDER_HOME=/opt/sunder  # Install to /opt/sunder

Then, add the following snippet to your .profile, replacing $HOME/.sunder with your chosen SUNDER_HOME directory if installing to a non-default SUNDER_HOME location:

export SUNDER_HOME="$HOME/.sunder"
if [ -e "$SUNDER_HOME/env" ]; then
    . "$SUNDER_HOME/env"

Verify that the compiler has been successfully installed by running sunder-compile -h. You may have to source your .profile in new shells until the start of your next login session.

#Using the Sunder Compiler

Sunder programs are compiled into executables with sunder-compile.

import "std";

func main() void {
    std::print_line(std::out(), "Hello, world!");
$ sunder-compile -o hello examples/hello.sunder
$ ./hello
Hello, world!

The -o OUT option may be used to specify the name of the output executable. If this option is not provided then the output executable will default to the name a.out.

The intermediate files OUT.asm and OUT.o (output executable name plus .asm and .o extensions) are generated during compilation and subsequently removed after the output executable has been created. The -k flag will instruct the compiler not to remove these files (useful for debugging).

$ sunder-compile -k -o hello examples/hello.sunder
$ ls hello*
hello  hello.asm  hello.o

The following environment variables affect compiler behavior:

  • SUNDER_BACKEND => Selects the backend to be used for object file generation. Currently, SUNDER_BACKEND=nasm and SUNDER_BACKEND=yasm are supported. If this environment variable is not set, then the default backend is used.
  • SUNDER_IMPORT_PATH => Colon-separated list of directories specifying the module search path for import statements.
  • SUNDER_SYSASM_PATH => Location of the platform specific sys.asm file that defines the program entry point as well as low-level operating system and hardware abstractions. If this environment variable is not set, then the default path, ${SUNDER_HOME}/lib/sys/sys.asm, is used.

#Using Sunder as a Scripting Language

Sunder can be used for scripting by adding #!/usr/bin/env sunder-run (or equivalent) as the first line of a Sunder source file.

#!/usr/bin/env sunder-run
import "std";

func main() void {
    std::print(std::out(), "What is your name?\n> ");

    var allocator = std::general_allocator::init();
    defer {

    var result = std::read_line(std::input(), std::allocator::init[[typeof(allocator)]](&allocator));
    if result.is_error() {
        std::print_line(std::err(), result.error().*.data);

    var optional = result.value();
    if optional.is_empty() or countof(optional.value()) == 0 {
        std::print_line(std::err(), "error: unexpected empty input");

    var name = std::ascii::view_trimmed(optional.value());
    std::print_format_line(std::out(), "Nice to meet you {}!", (:[]std::formatter)[std::formatter::init[[typeof(name)]](&name)]);
$ ./examples/greet.sunder
What is your name?
> Alice
Nice to meet you Alice!

#Using Sunder Without Installing

Executing the following commands will create an environment sufficient for Sunder devlopment and experimentation without requiring the Sunder toolchain to be installed.

$ cd /your/path/to/sunder
$ make
$ . ./env
$ sunder-run examples/hello.sunder
Hello, world!


Sunder is distributed under the terms of the Apache License (Version 2.0).

See LICENSE for more information.