Spaceship is a high-performance system automation language designed to replace legacy shell scripting. It includes a strict, Go-inspired syntax, a powerful fixed-width type system, and a novel JIT (just-in-time) compilation model for POSIX commands, all built on top of LLVM.
- Display: Statically typed and JIT-compiled for maximum execution speed.
- Security: Eliminates weaknesses of shell injection through hardening
ProcessAPI driven by direct OS-level syscalls. - Reliability: A clear, unambiguous error handling model based on POSIX exit codes.
- Modern syntax: A clean, Go-inspired syntax that’s easy to read and write.
The spacecraft uses a rigid, fixed-width type system. There is no guesswork; All types must be declared explicitly.
| Type | Description | syntax example |
|---|---|---|
i1 |
boolean type | var is_active i1 = true |
i8 , i128 |
fixed-width signed integer | var user_id i64 |
f32, f64 |
decimal numbers | const PI f64 = 3.14159 |
u8[] |
raw byte array (string) | var message u8[] = "hello" |
[ |
fixed size array | var buffer [1024]i8 |
map[ |
hash map | var scores map[u8[]]i32 |
Error Handling: !i32 Contract
Spaceship uses an explicit error handling mechanism that maps directly to POSIX exit codes. errnoAny function that may fail must declare its return type ! Prefix, indicating that it returns an error contract.
Example: fn readFile(path u8[]) !i32
- If successful, the function returns a non-zero value.
- On failure, it returns a standard POSIX error code (for example,
ENOENTfor “No such file or directory”).
This contract is enforced by check {} except {} block.
check {
// Code that might fail
var fd = readFile("my_file.txt")
} except {
// This block executes if readFile() returns an error code
// The error code is implicitly available in the `err` variable
Posix.write(stdout, "Error reading file: " + err)
}
Execution and Pipeline Model
secure process execution with Syscalls Library
All external commands are executed using Process API. This API backend is powered by Syscalls Runtime libraries that interface directly with the process creation API of the host operating system (for example, fork,execve On Linux/macOS, CreateProcess on Windows).
This is an important security feature that prevents shell injection vulnerabilities by design, because the arguments are passed as a structured array, not as a raw string to be parsed by the shell.
Example: Process("ls", ["-l", "/home/user"])
Spaceship uses a deferred execution model for command pipelines, inspired by the Fluent API. Operations are chained together using .then()but till then there is no execution .run() It is said.
Example:
var pipeline = Process("grep", ["-r", "keyword", "."])
.then(Process("wc", ["-l"]))
// Nothing has executed yet.
var result = pipeline.run() // The pipeline is now executed.
@jit Instructions: Shell-to-Original Translation
@jit Directives are a powerful compiler feature that translates shell scripts into native POSIX logic and JIT-compiles them directly into the LLVM execution path. This provides significant performance and security benefits over traditional shell script execution.
Example: @jit("deploy.sh")
This allows developers to leverage existing shell scripts while benefiting from the performance and security of the Spaceship runtime.
The primary standard library for SpaceShipOne is the JIT-compiled POSIX layer Syscalls Runtime Library. This ensures that all file I/O, process management, and other system-level operations are as fast and efficient as possible.
// Declare a fixed-size array of 4 64-bit integers
var vector [4]i64
// Declare a map with string keys and 32-bit integer values
var user_ages map[u8[]]i32
// Accessing an element (syntax)
vector[2] = 100
user_ages["jules"] = 32
Function definition and error handling
// Definition for a function that can fail
fn open_or_fail(path u8[]) !i32 {
// ... low-level POSIX call to open the file ...
// Returns a file descriptor (i32) on success or an error code on failure.
}
fn main() {
check {
var file_descriptor = open_or_fail("/etc/hosts")
} except {
// The 'err' variable is implicitly available and holds the i32 error code.
Posix.write(stdout, "Failed to open file with error code: " + err)
}
}
// Find all .log files, count their lines, sort numerically, and get the top 5.
var pipeline = Process("find", [".", "-name", "*.log"])
.then(Process("xargs", ["wc", "-l"]))
.then(Process("sort", ["-n"]))
.then(Process("tail", ["-n", "5"]))
// Execute the entire pipeline.
var top_five_logs = pipeline.run()
Posix.write(stdout, top_five_logs)
The primary goal of Spaceship is to provide significant performance improvements compared to traditional, interpreted shell scripting languages such as Bash. By using the JIT-compiler with LLVM, our goal is to perform common system administration and automation tasks faster.
The following is the benchmark Imaginary and serves to reflect the project’s performance goals. The task is to count the total number of rows .log Files within a larger directory structure.
| language/method | time (seconds) | performance factor | notes |
|---|---|---|---|
bash (find + xargs + wc) |
~12.5 seconds | 1x (baseline) | High process manufacturing overhead. |
python (os.walk) |
~7.8 seconds | ~1.6x | Quick, but still explained. |
Spaceship (Target) |
~0.9s | ~14x | JIT-compiled native code with minimal overhead. |
This theoretical benchmark highlights the benefits of avoiding interpreter overhead and leveraging direct, compiled POSIX calls for process management and I/O. Note: The standard library Is still under development ,
<a href