Phase 25.1a: selfhost builder hotfix (fn rename, docs)
This commit is contained in:
241
docs/development/runtime/cli-hakorune-stage1.md
Normal file
241
docs/development/runtime/cli-hakorune-stage1.md
Normal file
@ -0,0 +1,241 @@
|
||||
# Stage1 Hakorune CLI Design(Proposal)
|
||||
|
||||
Status: design-only(Phase 25.1 時点では仕様策定と導線の整理まで)
|
||||
|
||||
## ゴール
|
||||
|
||||
- 「ユーザー/開発者が日常叩く CLI」としての `hakorune`(Stage1 selfhost バイナリ)のインターフェースを定義する。
|
||||
- 既存の Rust CLI(Stage0: `nyash`)が提供している機能を、「パイプライン志向」の小さなサブコマンドに整理し直す。
|
||||
- Stage1 は **パイプラインのオーケストレーションのみ** 担当し、MIR 実行・LLVM コード生成などの実行コアは Stage0/Rust に委譲する。
|
||||
|
||||
## バイナリとプロセスモデル
|
||||
|
||||
- Stage0(Rust CLI / ランタイムサービス)
|
||||
- 実体: `target/release/nyash`(将来: `hakorune-bootstrap`)
|
||||
- 役割: プロセス起動・VM/LLVM コア・ny-llvmc 呼び出しなどの「Ring0」。
|
||||
- Ny 側からは `env.mirbuilder.emit` / `env.codegen.emit_object` / `env.codegen.link_object` などの extern 名で見える。
|
||||
- Stage1 実行時は「CLI として」ではなく、これらのランタイムサービス層(C-ABI/extern)として利用することを前提とする。
|
||||
- Stage1(Hakorune selfhost CLI)
|
||||
- 実体: `target/selfhost/hakorune`(Phase 25.1 では Ny Executor プロトタイプ)。
|
||||
- 役割: `.hako → Program(JSON) → MIR(JSON) → 実行/EXE` というパイプラインの制御。
|
||||
- 将来的には、ユーザーが直接叩く標準 CLI として昇格(`PATH` に入れる対象)。
|
||||
|
||||
プロセスモデルの原則:
|
||||
- Stage1 は **自分で VM/LLVM を実装しない**。常に Ring0 のサービス(env.codegen/env.mirbuilder, NyRT/ny-llvmc 等)を経由して実行・AOT する。
|
||||
- Stage1 CLI は「どのステージまで進めるか」と「どのバックエンドで実行/ビルドするか」を宣言的に指定するだけに留める。
|
||||
- Stage1 バイナリ自体は Stage0 の CLI からは独立しており、Stage0 はあくまで「ブートストラップおよびランタイムサービス提供者」として扱う。
|
||||
|
||||
## トップレベル構文
|
||||
|
||||
```text
|
||||
hakorune <command> [<subcommand>] [options] [-- script_args...]
|
||||
```
|
||||
|
||||
- `command`/`subcommand` は **パイプラインの到達点** を表す。
|
||||
- `options` は主に:
|
||||
- 入出力ファイル
|
||||
- backend 選択(vm/llvm/pyvm)
|
||||
- profile(dev/ci/lite 等のプリセット)
|
||||
を指定する。
|
||||
- `--` 以降はユーザープログラムに渡す引数(既存の `NYASH_SCRIPT_ARGS_JSON` 経路と整合させる)。
|
||||
|
||||
## コマンド一覧(MVP 案)
|
||||
|
||||
| コマンド | 役割 |
|
||||
|-----------------------------------|-------------------------------------------|
|
||||
| `run` | .hako をコンパイルして実行(既定 VM) |
|
||||
| `build exe` | .hako からネイティブ EXE を AOT ビルド |
|
||||
| `emit program-json` | Stage‑B で Program(JSON v0) を出力 |
|
||||
| `emit mir-json` | Program(JSON) → MIR(JSON) を出力 |
|
||||
| `check` | 将来の構文/型/using チェック(予約) |
|
||||
|
||||
Phase 25.1 では、既存スクリプト置き換えに近い **`emit mir-json` / `build exe` を中心** に進め、`run`/`check` は設計レベルに留める。
|
||||
|
||||
## `run` コマンド
|
||||
|
||||
```text
|
||||
hakorune run [options] <entry.hako> [-- script_args...]
|
||||
```
|
||||
|
||||
### 意味論
|
||||
|
||||
- `.hako` ソースを Stage‑B → MirBuilder → AotPrep まで通し、選択された backend で実行する。
|
||||
- 実行経路:
|
||||
- backend=`vm` : Stage0 Rust VM(現行 `--backend vm` 相当)
|
||||
- backend=`llvm` : ny-llvmc+NyRT を通した EXE 実行(実装は後続フェーズ)
|
||||
- backend=`pyvm` : PyVM 経路(Phase‑15 の方針に従い、開発/検証専用)
|
||||
- プログラムの戻り値をプロセスの exit code にマッピング(現行 Rust CLI と同じ)。
|
||||
|
||||
### 主なオプション案
|
||||
|
||||
- `--backend {vm|llvm|pyvm}`(既定: `vm`)
|
||||
- `--profile {dev|ci|lite|strict}`
|
||||
- `dev` : 詳細ログ・トレースを有効(Phase 15/25 の既存 ENV を束ねる)
|
||||
- `ci` : 安定志向・プラグイン無効化など(現行 quick profile 相当)
|
||||
- `lite` : macro/using など重い機能をオフ
|
||||
- `strict`: 各種 STRICT トグルを有効(AotPrep/Verifier 等)
|
||||
- `--using-path <paths>`: `tools/dev_selfhost_loop.sh` の `--using-path` と一致させる。
|
||||
- `--json-only`(将来): Stage‑B までで止め、Program(JSON v0) を stdout に出力。
|
||||
|
||||
### Stage0 との関係
|
||||
|
||||
- Stage1 `run` は **直接 MIR を実行しない**。
|
||||
- 代わりに:
|
||||
1. Stage1 内で Program(JSON)/MIR(JSON) を構築。
|
||||
2. `NYASH_VERIFY_JSON` / `NYASH_JSON_ONLY` / `NYASH_SCRIPT_ARGS_JSON` など既存の ENV プロトコルを用いて Stage0 プロセスを呼び出す。
|
||||
- これにより「Rust 側の VM/LLVM コアはそのまま」「CLI 表面だけ selfhost 化」という段階移行が可能になる。
|
||||
|
||||
## `build exe` コマンド
|
||||
|
||||
```text
|
||||
hakorune build exe [options] <entry.hako>
|
||||
```
|
||||
|
||||
### 意味論
|
||||
|
||||
- `.hako` からネイティブ EXE を生成する高レベル API。
|
||||
- Phase 25.1 実装では、`.hako → Program(JSON v0) → MIR(JSON) → env.codegen.emit_object/link_object → EXE` までを 1 コマンドで行う。
|
||||
- 具体的な呼び出し:
|
||||
|
||||
```text
|
||||
hakorune build exe [-o <out>] [--quiet] <source.hako>
|
||||
```
|
||||
|
||||
### 意味論(Phase 25.1 実装範囲)
|
||||
|
||||
- `.hako` から EXE までのパイプライン:
|
||||
1. `.hako` → Program(JSON v0):
|
||||
- `BuildBox.emit_program_json_v0(src, null)` を呼び出し。
|
||||
- `"version":0` / `"kind":"Program"` を検査。
|
||||
2. Program(JSON v0) → MIR(JSON):
|
||||
- `MirBuilderBox.emit_from_program_json_v0(program_json, null)` を呼び出し。
|
||||
3. MIR(JSON) → object:
|
||||
- `hostbridge.extern_invoke("env.codegen", "emit_object", [mir_json])` を呼び出し、`.o` パスを取得。
|
||||
4. object → EXE:
|
||||
- `hostbridge.extern_invoke("env.codegen", "link_object", [obj_path, out?])` を呼び出し、EXE パスを取得。
|
||||
- 実行には C-API ルートの有効化が前提:
|
||||
- 例: `NYASH_LLVM_USE_CAPI=1`, `HAKO_V1_EXTERN_PROVIDER_C_ABI=1`, `NYASH_EMIT_EXE_NYRT` など。
|
||||
|
||||
### オプション(Phase 25.1 実装済み)
|
||||
|
||||
- `-o, --out <path>`:
|
||||
- 生成する EXE のパスを指定(省略時は env.codegen 側の既定パスを使用)。
|
||||
- `--quiet`:
|
||||
- 成功時のステータス出力(`[hakorune] build exe: <exe_path>`)を抑制。
|
||||
|
||||
※ `--target` / `--nyrt` / `--skip-build` などは、現時点では未実装の設計(将来の AOT プロファイル用)。***
|
||||
|
||||
## `emit program-json` コマンド
|
||||
|
||||
```text
|
||||
hakorune emit program-json [options] <entry.hako>
|
||||
```
|
||||
|
||||
### 意味論(Phase 25.1 実装範囲)
|
||||
|
||||
- `.hako` ソースファイル(`<entry.hako>`)を読み込み、`BuildBox.emit_program_json_v0(src, null)` を呼び出して Program(JSON v0) を生成する。
|
||||
- Phase 25.1 の実装では:
|
||||
- 入力: `<entry.hako>` パスのみ(標準入力や複数ファイルは未対応)。
|
||||
- 出力:
|
||||
- 既定: Program(JSON v0) を stdout にそのまま出力。
|
||||
- `-o/--out` 指定時: JSON はファイルに書き込み、stdout には短いステータス行のみを出力。
|
||||
- バリデーション: `"version":0` と `"kind":"Program"` を含まない場合はエラー終了(exit code 92)。
|
||||
|
||||
### オプション(Phase 25.1 実装済み)
|
||||
|
||||
- `-o, --out <file>`:
|
||||
- Program(JSON v0) を `<file>` に書き出す。
|
||||
- スクリプト互換性のため、stdout には短いメッセージ(タグ)だけを出す(JSON 本文は出さない)。
|
||||
- `--quiet`:
|
||||
- `-o/--out` と組み合わせた場合に、ステータス行も抑制し「完全に無音」のファイル出力にする。
|
||||
- `--quiet` 単独では意味を持たず、現状は無視される(将来のログ制御用に予約)。
|
||||
|
||||
## `emit mir-json` コマンド
|
||||
|
||||
```text
|
||||
hakorune emit mir-json [options] <entry.hako>
|
||||
```
|
||||
|
||||
### 意味論(Phase 25.1 実装範囲)
|
||||
|
||||
- Program(JSON v0) から MIR(JSON) を出す経路に加えて、`.hako` から Program(JSON v0)→MIR(JSON) まで進める経路も実装済み。
|
||||
- 実際の CLI 呼び出しは主に次の2通り:
|
||||
|
||||
```text
|
||||
# 1) Program(JSON v0) から MIR(JSON)
|
||||
hakorune emit mir-json --from-program-json <program.json>
|
||||
|
||||
# 2) .hako から直接 MIR(JSON) まで
|
||||
hakorune emit mir-json [-o <out>] [--quiet] <source.hako>
|
||||
```
|
||||
|
||||
- 処理内容:
|
||||
- `--from-program-json` 指定時:
|
||||
- FileBox で `<program.json>` を読み込み、文字列として取得。
|
||||
- `MirBuilderBox.emit_from_program_json_v0(program_json, null)` を呼び出して MIR(JSON) を生成。
|
||||
- `.hako` 直接指定時:
|
||||
- FileBox で `<source.hako>` を読み込み、`BuildBox.emit_program_json_v0(src, null)` で Program(JSON v0) を生成。
|
||||
- `"version":0` / `"kind":"Program"` を検査した上で、その Program(JSON v0) を `MirBuilderBox.emit_from_program_json_v0` に渡す。
|
||||
- 成功時は MIR(JSON) を stdout に出力(`-o/--out` 指定時はファイル出力)し、exit code 0。
|
||||
- 失敗時(ファイルエラー / builder null など)はエラーメッセージ+exit code 92。
|
||||
|
||||
### オプション(Phase 25.1 実装済み)
|
||||
|
||||
- `--from-program-json <file>`:
|
||||
- Program(JSON v0) を含むファイルパスを指定。
|
||||
- `.hako` との併用は禁止(両方指定した場合はエラー)。
|
||||
- `-o, --out <file>`:
|
||||
- MIR(JSON) を `<file>` に書き出す。
|
||||
- stdout に MIR(JSON) を直接出さなくなる(短いステータス行のみ)。
|
||||
- `--quiet`:
|
||||
- `-o/--out` と併用時にステータス行も抑制し、MIR(JSON) をファイルにだけ書き込む。
|
||||
|
||||
※ `--force-jsonfrag` / `--normalize-provider` などは、引き続き設計のみで未実装。
|
||||
|
||||
## `check` コマンド(予約)
|
||||
|
||||
```text
|
||||
hakorune check [options] <entry.hako>
|
||||
```
|
||||
|
||||
### 意味論(将来)
|
||||
|
||||
- Stage‑B / MirBuilder / AotPrep を **実行せずに**:
|
||||
- 構文
|
||||
- using 解決
|
||||
- System Hakorune subset 制約
|
||||
などを検証するためのエントリポイント。
|
||||
|
||||
- 実装は `.hako` 側で `tools/hako-check` 相当のロジックを呼び出す想定。
|
||||
- Phase 25.1 では「名前予約」と「インターフェース定義」のみを行い、実装は Phase 26 以降。
|
||||
|
||||
## Stage0 / Stage1 の責務分離(CLI 視点)
|
||||
|
||||
- Stage1(hakorune)
|
||||
- ユーザー向け CLI surface。
|
||||
- パイプライン選択とオプション解釈。
|
||||
- JSON v0/v1 の配線・一時ファイル管理。
|
||||
- Stage0(nyash / hakorune-bootstrap)
|
||||
- VM 実行(vm/backend=vm)。
|
||||
- LLVM ハーネス/ny-llvmc 経由の AOT(backend=llvm)。
|
||||
- env.codegen / env.mirbuilder などのホストブリッジ提供。
|
||||
|
||||
原則:
|
||||
- Stage1 は **新しい意味論・最適化ロジックを持たない**。
|
||||
- Stage1 CLI は「どの Stage0/ny-llvmc サービスをどう呼ぶか」を決める **構造レイヤ**。
|
||||
|
||||
## フェーズ別導入計画(CLI 観点)
|
||||
|
||||
- Phase 25.1
|
||||
- `build_stage1.sh` による Ny Executor EXE(`target/selfhost/hakorune`)を用意。
|
||||
- 本ドキュメントで CLI サブコマンドと引数の仕様を固定。
|
||||
- `hakorune emit mir-json` / `hakorune build exe` に対応する内部 API を `.hako` 側で設計(実装は最小限 or 後続)。
|
||||
- Phase 26 以降
|
||||
- `run` サブコマンドを実装し、日常的な `hakorune run apps/APP/main.hako` 導線を整備。
|
||||
- 既存の selfhost スクリプト(`selfhost_build.sh` / `hakorune_emit_mir.sh` / `selfhost_exe_stageb.sh`)を段階的に CLI 経由に移行。
|
||||
- `check` を `.hako` 側の hako-check ライブラリに接続。
|
||||
- Stage1 → Stage1' の自己ホストサイクルを検証する:
|
||||
- Stage1 が自分自身(launcher/runner/CLI を含む)を AOT して Stage1' を生成できること。
|
||||
- Stage1 / Stage1' の CLI インターフェース・代表挙動が一致することをゴールデン/スモークで確認する。
|
||||
|
||||
このファイルは「Stage1 CLI の仕様 SSOT」として扱い、実装時は本仕様を先に更新→テスト→コードの順で進める。***
|
||||
Reference in New Issue
Block a user