Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Getting Started

Navigation: Guide | Documentation Root

This document walks a new user through installing the Keleusma command-line frontend, writing and running a first script, and embedding the same script in a Rust host program. The walkthrough assumes a working Rust toolchain at edition 2024 and minimum supported Rust version 1.88.

Install the CLI

Keleusma ships a standalone CLI binary called keleusma. The CLI provides a script runner, a bytecode compiler, and an interactive REPL. Install it from the workspace root.

git clone https://github.com/sgeos/keleusma
cd keleusma
cargo install --path keleusma-cli --bin keleusma

Verify the installation.

keleusma --help

If the command is not found, ensure Cargo’s bin directory is on the shell PATH. The default location is ~/.cargo/bin.

A First Script

Create a file called hello.kel with the following contents.

fn double(x: Word) -> Word {
    x + x
}

fn main() -> Word {
    double(21)
}

Run the script.

keleusma run hello.kel

Expected output.

42

The runner parses, compiles, verifies, and executes the script. Atomic total functions declared with fn may not yield to the host or contain unbounded recursion. The main function is the entry point. The return type appears in the function signature and is required.

Compile to Bytecode

The CLI can serialize a script to bytecode. The serialized form is loadable through the embedding API.

keleusma compile hello.kel -o hello.kel.bin

The output file uses the framed wire format with magic, length, version, target word and address widths, body, and CRC trailer. A host loads the file through Vm::load_bytes.

Interactive REPL

Start the REPL to explore the language interactively.

keleusma repl

The REPL accumulates declarations into a session prefix and evaluates expressions against the current prefix. The REPL supports the colon-prefixed commands :help, :quit, :reset, and :show.

> 1 + 2
3
> fn double(x: Word) -> Word { x + x }
defined: double
> double(21)
42
> :quit

The REPL wraps each expression as fn main() -> T { <expression> } and tries return types Word, Float, bool, Text, and () in order. The first type that compiles is used. Expressions whose type lies outside this list require an explicit function declaration.

Embed in a Rust Host

The same script runs from a Rust host program. Create a new Cargo project.

cargo new --bin keleusma-hello
cd keleusma-hello

Add Keleusma to Cargo.toml.

[dependencies]
keleusma = "0.2"
keleusma-arena = "0.3"

Replace src/main.rs with the following.

use keleusma::compiler::compile;
use keleusma::lexer::tokenize;
use keleusma::parser::parse;
use keleusma::vm::{DEFAULT_ARENA_CAPACITY, Vm, VmState};
use keleusma::{Arena, Value};

const SCRIPT: &str = "
    fn double(x: Word) -> Word { x + x }
    fn main() -> Word { double(21) }
";

fn main() {
    let tokens = tokenize(SCRIPT).expect("lex");
    let program = parse(&tokens).expect("parse");
    let module = compile(&program).expect("compile");

    let arena = Arena::with_capacity(DEFAULT_ARENA_CAPACITY);
    let mut vm = Vm::new(module, &arena).expect("verify");

    match vm.call(&[]).expect("call") {
        VmState::Finished(Value::Int(n)) => println!("{}", n),
        other => panic!("unexpected: {:?}", other),
    }
}

Build and run.

cargo run

Expected output.

42

The host code performs the same compile-verify-run pipeline as the CLI runner. The four steps are visible in the source: lex, parse, compile, and execute. The Arena is the bounded-memory region the VM borrows for its operand stack and dynamic-string allocations. DEFAULT_ARENA_CAPACITY is sixty-four kilobytes, sufficient for most scripts and the value used by the bundled examples.

Next Steps

The walkthrough above produces a running Keleusma host. Common next steps include the following.

  • Read EMBEDDING.md for the full embedding surface, including native function registration, arena sizing, the call and resume loop for stream-classified scripts, and error recovery.
  • Read WHY_REJECTED.md when the verifier rejects a program. The document maps error messages to root causes and proposes rewrites.
  • Explore examples/scripts/ for short scripts demonstrating common language features. Each script runs through keleusma run.
  • Explore examples/ for Rust embedding examples that demonstrate WCMU computation, native attestation, error propagation through yield, and string interoperability.
  • Run examples/piano_roll.rs for a feature-gated end-to-end SDL3 audio demonstration. Eight voices with parameter-controlled waveform, envelope, vibrato, low-pass filter, and stereo per-speaker volume, sequenced by a Keleusma tick loop and rotating across a roster of precompiled songs through hot code swap. Run with cargo run --release --example piano_roll --features sdl3-example. See PIANO_ROLL.md for the long-form manual covering song composition, host lifting, and architectural patterns for other control-loop domains.