はじめに
本ドキュメントは、Keleusma のコマンドラインフロントエンドのインストール、最初のスクリプトの記述と実行、そして同じスクリプトを Rust ホストプログラムへ組み込む手順を、新規ユーザー向けに順を追って説明します。この解説では、edition 2024 かつサポートされる最小の Rust バージョン 1.88 の動作する Rust ツールチェインを前提とします。
CLI のインストール
Keleusma は keleusma という名前のスタンドアロンな CLI バイナリを同梱しています。この CLI は、スクリプトランナー、バイトコードコンパイラ、および対話型 REPL を提供します。ワークスペースのルートからインストールしてください。
git clone https://github.com/sgeos/keleusma
cd keleusma
cargo install --path keleusma-cli --bin keleusma
インストールを確認します。
keleusma --help
コマンドが見つからない場合は、CargoのbinディレクトリがシェルのPATHに含まれていることを確認してください。デフォルトの場所は~/.cargo/binです。
最初のスクリプト
hello.kelという名前のファイルを次の内容で作成します。
fn double(x: Word) -> Word {
x + x
}
fn main() -> Word {
double(21)
}
スクリプトを実行します。
keleusma run hello.kel
期待される出力です。
42
ランナーはスクリプトをパースし、コンパイルし、検証し、実行します。fnで宣言された原子的・全域関数は、ホストにyieldしたり、無制限の再帰を含んだりすることはできません。main関数がエントリーポイントです。戻り型は関数のシグネチャに現れ、必須です。
バイトコードへコンパイルする
CLIはスクリプトをバイトコードにシリアライズできます。シリアライズされた形式は組み込みAPIを通じて読み込めます。
keleusma compile hello.kel -o hello.kel.bin
出力ファイルはフレーム付きワイヤフォーマットを使い、マジック、長さ、バージョン、ターゲットのワード幅とアドレス幅、本体、CRCトレーラを持ちます。ホストはVm::load_bytesでこのファイルを読み込みます。
対話型REPL
REPLを起動して言語をインタラクティブに探索します。
keleusma repl
REPLは宣言をセッションのプレフィックスに蓄積し、現在のプレフィックスに対して式を評価します。REPLはコロン接頭辞のコマンド:help、:quit、:reset、:showをサポートします。
> 1 + 2
3
> fn double(x: Word) -> Word { x + x }
defined: double
> double(21)
42
> :quit
REPLは各式をfn main() -> T { <expression> }で包んで、戻り型Word、Float、bool、Text、()の順に試します。最初にコンパイルが通る型が使われます。このリストに含まれない型を持つ式は、明示的な関数宣言が必要です。
Rustホストに組み込む
同じスクリプトはRustホストプログラムからも実行できます。新しいCargoプロジェクトを作ります。
cargo new --bin keleusma-hello
cd keleusma-hello
Cargo.tomlにKeleusmaを追加します。
[dependencies]
keleusma = "0.2"
keleusma-arena = "0.3"
src/main.rsを次の内容で置き換えます。
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),
}
}
ビルドして実行します。
cargo run
期待される出力です。
42
ホストコードはCLIランナーと同じcompile-verify-runパイプラインを行います。4つのステップがソースに見えます — lex、parse、compile、execute、です。Arenaは、VMがオペランドスタックと動的文字列の確保のために借りる、境界付きメモリ領域です。DEFAULT_ARENA_CAPACITYは64キロバイトで、ほとんどのスクリプトに十分な値であり、バンドルされた例で使われている値です。
次のステップ
上のウォークスルーで、動くKeleusmaホストができました。よくある次のステップです。
- EMBEDDING.mdで、ネイティブ関数の登録、アリーナのサイズ、ストリーム分類スクリプトのためのcall/resumeループ、エラー回復を含む完全な組み込み面を読んでください。
- 検証器がプログラムを却下するときはWHY_REJECTED.mdを読んでください。エラーメッセージを根本原因にマッピングし、書き換えを提案しています。
- 一般的な言語機能を実演する短いスクリプトは
examples/scripts/を探索してください。各スクリプトはkeleusma runで実行できます。 - WCMU計算、ネイティブ計上、yieldを通じたエラー伝搬、文字列の相互運用を実演するRust組み込み例は
examples/を探索してください。 - フィーチャーゲート付きのエンドツーエンドSDL3オーディオデモは
examples/piano_roll.rsで実行してください。パラメータ制御の波形、エンベロープ、ビブラート、ローパスフィルタ、ステレオスピーカー別音量を持つ8つのヴォイスを、Keleusmaのティックループでシーケンスし、ホットコードスワップで事前コンパイル済みの楽曲一覧を巡ります。cargo run --release --example piano_roll --features sdl3-exampleで実行します。長文マニュアル(楽曲作曲、ホスト持ち上げ、他の制御ループ領域に対するアーキテクチャパターンを扱う)はPIANO_ROLL.mdを参照してください。