STASIS
Docs / language

A small, explicit surface.

C-shaped expressions, fixed-layout values, and visible mutation. The examples below use current Stasis syntax.

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;
}