01 / Values
Primitives, let, and infix operators.
Primitive types include i32, u8, f32, f64, bool, void, and string types. Omitted local types require an initializer.
let lives: i32 = 3;
let next_lives = lives - 1;
let ratio: f32 = 0.5;
let alive = next_lives > 0;
score += 100;
if (alive && score >= 100) { print("ready"); }02 / State and types
Structs, enums, globals, fixed arrays.
Persistent data is declared globally. Arrays have a fixed capacity and can be passed as view parameters.
enum Team { Red, Blue }
struct Enemy {
health: i32;
team: Team;
active: bool;
}
global enemies: Enemy[64];
function activate(index: i32, health: i32): void {
enemies[index].health = health;
enemies[index].active = true;
return;
}Fixed strings use layouts such as ascii[32] and utf8[128]; capacity and length remain explicit.
let label: ascii[32]; ascii_clear(label); ascii_push(label, char_from_digit(7));
03 / Calls and control flow
Functions read at the call site.
A first struct parameter named self enables receiver form. The ordinary call remains equivalent.
function damage(self: Enemy, amount: i32): void {
self.health -= amount;
return;
}
enemies[0].damage(5);
damage(enemies[0], 5);for (let i = 0; i < 64; i += 1) {
if (enemies[i].active) { enemies[i].damage(1); }
}
foreach (let enemy in enemies) {
if (enemy.active) { print(enemy.health); }
}04 / Modules and tests
Imports are ordinary source dependencies.
import "../src/stdlib/stdlib.stasis";
import "../src/stdlib/graphics.stasis";
function main(): i32 {
init_window(800, 600, "Example");
return 0;
}Tests live in .test.stasis files and use the same compiler/JIT path as the program.
test `damage lowers health`(): bool {
let enemy: Enemy;
enemy.health = 10;
enemy.damage(3);
return enemy.health == 7;
}