This is the Saurus reference compiler. The language combines Go-like syntax with C-like manual memory management, compiling to portable C89 code. https://saurus-lang.org
  • C 98.5%
  • Shell 1.1%
  • Makefile 0.4%
Find a file
Andreas T Jonsson 16a3e68488
Some checks failed
ci/woodpecker/push/windows Pipeline was successful
ci/woodpecker/push/test_wasm Pipeline failed
ci/woodpecker/push/test_c Pipeline was successful
Add CloneAndTerminate to strings package for null-terminated copies
2026-03-16 16:32:34 +01:00
.woodpecker Updated ext 2026-02-26 16:37:29 +01:00
docs Rework any-boxing to alias/copy semantics, add UTF-8 iteration, and harden validation 2026-03-09 17:50:39 +01:00
examples Add multi-variable declarations, array binop rvalues, and extern type conversions 2026-02-12 17:54:44 +01:00
ext@5235959468 Updated submodule 2026-03-15 09:26:54 +01:00
runtime/c Spec corrections, defined type support, heap-based any boxing, and new tests 2026-03-04 22:20:56 +01:00
src Fix C backend codegen for memset/memcmp on global variables 2026-03-15 08:53:18 +01:00
std Add CloneAndTerminate to strings package for null-terminated copies 2026-03-16 16:32:34 +01:00
tests Fix C backend codegen for memset/memcmp on global variables 2026-03-15 08:53:18 +01:00
tools Update editor plugins: add #message/#embed directives, fix snippets 2026-03-11 21:55:52 +01:00
.gitignore Update lang test docs and fix variadic function test syntax 2026-01-10 11:30:02 +01:00
.gitmodules Add ext packages submodule, auto-discover test modules, and fix integer literal codegen overflow 2026-02-10 21:32:08 +01:00
AGENTS.md Fix cross-file visibility of package-level vars with composite literal initializers 2026-03-04 11:18:21 +01:00
LICENSE Fix type system bugs, add make() builtin, and update branding 2026-01-11 21:29:00 +01:00
Makefile Add ext packages submodule, auto-discover test modules, and fix integer literal codegen overflow 2026-02-10 21:32:08 +01:00
README.md Fix cross-file visibility of package-level vars with composite literal initializers 2026-03-04 11:18:21 +01:00

Saurus

status-badge discord-badge

A statically-typed, compiled programming language designed for systems programming. Saurus combines Go-like syntax with C-like manual memory management, compiling to portable C89 code or standalone WebAssembly (WASI) modules.

Features

  • Static typing with type inference
  • Manual memory management - no garbage collector
  • First-class functions, anonymous functions, and multiple return values
  • Defer - schedule cleanup calls to run at function return (LIFO order)
  • Lists with make, append, free
  • Maps - hash tables with make, indexed access, remove, free
  • Slices - zero-copy array views and slice literals
  • Array programming - element-wise operations, swizzle access, [_] size inference
  • Structs - named and anonymous struct types with structural equality
  • Iota - automatic constant enumeration
  • Inline C - embed raw C code with #inline for FFI
  • C interop - #extern imports and #export for callbacks
  • Package collections - organized imports with "collection:path" syntax
  • Testing - built-in test runner with --test flag
  • C89 backend - portable C code generation
  • WebAssembly backend - standalone WASI module generation

Quick Start

make                              # Build compiler
./saurus hello.srs                # Run directly
./saurus -c -o hello hello.srs    # Compile to executable

Windows: Use WSL. Cross-compile with CC=x86_64-w64-mingw32-gcc.

Hello World

package main

import "std:fmt"

func main() {
    fmt.Printf("Hello, World!\n")
}

Examples

Variables, Functions, and Memory

package main

import "std:fmt"

type Point struct { x, y int }

func add(a, b int) int { return a + b }

func main() {
    fmt.Printf("Sum: %d\n", add(10, 20))

    p := new(Point)
    p.x, p.y = 10, 20
    fmt.Printf("Point(%d, %d)\n", p.x, p.y)
    free(p)
}

Lists and Multiple Returns

package main

import "std:fmt"

func divide(a, b int) (int, int) { return a / b, a % b }

func main() {
    q, r := divide(17, 5)
    fmt.Printf("17 / 5 = %d remainder %d\n", q, r)

    nums := make(list[int], 0, 4)
    append(nums, 1, 2, 3)
    for i, v in nums { fmt.Printf("nums[%d] = %d\n", i, v) }
    free(nums)
}

Array Programming

package main

import "std:fmt"

func main() {
    a := [4]int{1, 2, 3, 4}
    b := a + [4]int{10, 20, 30, 40}  // Element-wise: [11, 22, 33, 44]
    c := a * 2                       // Scalar broadcast: [2, 4, 6, 8]

    v := [4]float32{1.0, 2.0, 3.0, 4.0}
    fmt.Printf("x=%f w=%f\n", v.x, v.w)  // Swizzle access

    primes := [_]int{2, 3, 5, 7, 11}     // Inferred size
}

Constants with Iota

package main

const (
    Sunday = iota; Monday; Tuesday; Wednesday; Thursday; Friday; Saturday
)

const (
    _ = iota
    KB = 1 << (10 * iota)  // 1024
    MB                      // 1048576
    GB                      // 1073741824
)

Defer

package main

import "std:fmt"

func process() {
    fmt.Printf("open resource\n")
    defer fmt.Printf("close resource\n")

    defer fmt.Printf("second cleanup\n")  // LIFO: runs before "close resource"

    fmt.Printf("working...\n")
}

func main() {
    process()
    // Output: open resource, working..., second cleanup, close resource
}

Inline C and Exports

package main

#export func myCallback(x int) int { return x * 2 }

func main() {
    x, y := 42, 100
    #inline `printf("x + y = %lld\n", (long long)(${x} + ${y}));`
}

Compiler Usage

Usage: saurus [options] <file.srs>
       saurus [options] <package-directory>
       saurus [options] -                          # read from stdin

Options:
  -r              Compile and run (default if no options given)
  -c              Compile to executable or object file using CC
  -o <file>       Output file name
  -O, --optimize  Enable backend-specific optimizations (C: -O2)
  --emit-as       Output generated C code
  --emit-tokens   Dump tokens (for debugging)
  --emit-ast      Dump AST (for debugging)
  --emit-ir       Dump IR (for debugging)
  --debug         Emit debug info for source-level debugging
  --test          Run tests (sets 'test' build tag, runs Test* functions)
  --tags=x,y,z    Enable build tags for conditional compilation
  --allow-unused  Disable unused declaration checking
  --no-entry      Skip generating main() entry point (for libraries)
  --object        Compile to object file (.o) instead of executable
  --valgrind      Run executable through valgrind (memory checking)
  --backend=c     Use C backend (default)
  --backend=wasm  Use WebAssembly backend (generates .wasm files)
  --stdlib <path> Standard library path (default: std, env: SAURUS_STDLIB)
  --collection name=path  Add a package collection
  --root          Print the compiler executable directory and exit
  -v, --verbose   Verbose output
  --version       Show version
  -h, --help      Show help

Environment variables:
  CC              C compiler (default: cc)
  SAURUS_STDLIB   Standard library path (default: std)
  SAURUS_RUNTIME  Runtime library path (default: runtime)

Types

Type Description
bool Boolean (true/false)
int, int8, int16, int32, int64 Signed integers
uint, uint8, uint16, uint32, uint64 Unsigned integers
uintptr Pointer-sized unsigned integer
float32, float64 Floating point
byte, rune Aliases for uint8 and int32
string Immutable, UTF-8 encoded
*T Pointer to T
[N]T Fixed-size array (element-wise ops, swizzle)
[]T Slice (array view)
list[T] Growable array
map[K]V Hash table (K must be comparable)
struct Named or anonymous field collection
func Function type
any Dynamic type with runtime type ID
typeid Runtime type identifier

Built-in Functions

Function Description
new(T) Allocate memory, returns *T
free(p) Deallocate memory
make(list[T], len, cap) Create list
make(map[K]V) Create map
append(d, v...) Append to list
remove(m, k...) Remove keys from map
len(v) Length of string, array, slice, list, or map
cap(d) Capacity of list
clear(x) Clear/zero a collection, array, slice, struct, or pointer
panic(msg) Terminate with error
assert(cond, msg?) Runtime assertion
sizeof(T) Size of type in bytes

Type Conversions

Syntax Use Case Example
T(x) Numeric conversions float64(42)
x as T Type assertions from any a as int, a as *int
x assume T Pointer casts p assume *uint

Documentation

Development

git clone --recurse-submodules https://codeberg.org/saurus/saurus.git
cd saurus
make            # Build
make test       # Unit tests
make lang-test  # Language tests
make std-test   # Standard library tests
make ext-test   # Extension library tests
make clean      # Clean build

License

BSD 1-Clause License. See LICENSE for details.

Copyright (c) 2009-2026 Andreas T Jonsson