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%
| .woodpecker | ||
| docs | ||
| examples | ||
| ext@5235959468 | ||
| runtime/c | ||
| src | ||
| std | ||
| tests | ||
| tools | ||
| .gitignore | ||
| .gitmodules | ||
| AGENTS.md | ||
| LICENSE | ||
| Makefile | ||
| README.md | ||
Saurus
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
#inlinefor FFI - C interop -
#externimports and#exportfor callbacks - Package collections - organized imports with
"collection:path"syntax - Testing - built-in test runner with
--testflag - 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
- Language Overview - Introduction and tutorial
- Language Specification - Complete language reference
- Compiler Architecture - How the compiler works
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