本文へ移動
Hikari 仕様

hikari コマンド仕様

本書は hikari CLI の起動形態と各サブコマンドの仕様を定める。言語の意味論は language-spec.md、組込関数群は prelude.md を参照。分量の大きいモードは別冊に分離した — REPL は repl.md、LSP サーバーは lsp.md、ビルド (hikari build) は build.md、静的検査 (hikari check) は check.md、テスト (hikari test) は test.md、整形 (hikari format) は format.md、スタイル検査 (hikari lint) は lint.md、図の生成 (hikari diagram) は diagram.md。本書中の §N は本書内の節を指し、別冊内の節は「repl.md「動作モード」」のように書名+節名で参照する。

1. 起動ディスパッチ

hikari [SUBCOMMAND | <path>] [ARGS...]

第 1 引数によって起動モードが決まる。

第 1 引数 モード
なし REPL repl.md
lsp LSP サーバー lsp.md
build バイナリビルド build.md
check 静的検査のみ check.md
test テスト実行 test.md
format ソース整形 format.md
lint スタイル検査 lint.md
diagram 図の生成 §10
doc リファレンス生成 §11
add 依存追加 §12
get 依存取得 §12
update 依存更新 §12
remove 依存削除 §12
eval 標準入力評価 §5.6
version / --version 版と構成の表示
help / --help 使い方の表示
inspect 処理系自身の調査 (作る側の道具)
それ以外 ファイル実行 §5

上の表の第 1 列がそのまま予約語である。 同名のファイルを実行したい場合は ./lsp のようにディレクトリ付きで指定する (lsp.hika のように拡張子が付いていれば衝突しない)。inspect は処理系を作る側の調査用で、使う側の道具ではないため本書では形を定めない — 予約されていることだけをここに置く (形は docs/internals にある)。

1.1 終了コード

ファイル実行モード・eval モード・build モード・check モードの終了コード:

code 意味
0 成功
1 構文エラー / 評価エラー / ビルドエラー
2 I/O エラー / 引数不正 / 必須ツール不在

REPL と LSP サーバーは正常終了時 0

1.2 ソース系サブコマンドの住み分け

check / format / lint / diagram はいずれも評価せずソースを扱うが、責務が異なる。

ツール 対象 動作 不変条件
check (check.md) 正しさ(構文 + 静的エラー、到達可能グラフ全体) 検出のみ
format (format.md) 具体構文の正規形 -w で書き換え 抽象構文木を保存
lint (lint.md) スタイル/品質(パース可能前提、保守的) 検出、--fix で書き換え --fix抽象構文を変えうる
diagram (diagram.md) 読み手への提示(入れ子・スロット節と本体・名前の指し先) 図を書き出す ソースを書き換えない
  • checklint はどちらも評価せず診断するが、check は「正しさ」(エラーの有無、モジュールグラフ単位)、lint は「書き方」(エラーではないスタイル問題、ファイル単位で import 解決なし)。
  • formatlint --fix はどちらもソースを書き換えるが、不変条件が違う。format抽象構文木を保存する正規化のみ(具体構文の見た目を正す。例: 1 引数 f(x)f x)。lint --fix抽象構文を変える正規化まで踏み込む(例: 制御構造 if(c, t, e)if c {t} {e}。評価結果は同じだが適用の段数=抽象構文が変わる)。よって format は制御構造のタプル形を保ち、並置化は lint --fix が担う。
  • diagram はこの 3 つと違い、診断も書き換えもしない。ソースを読み手のために描き直すだけである。図に出る字面は format の正規形と一致させるので、整形済みのソースと図が食い違わない。

2. REPL

REPL (hikari を引数なしで起動) の仕様は repl.md に分離した。

3. LSP サーバー (hikari lsp)

LSP サーバー (hikari lsp) の仕様は lsp.md に分離した。

4. ビルド (hikari build)

ビルド (hikari build) の仕様は build.md に分離した。

5. ファイル実行 (hikari <path> [args...])

<path>.hika ソースとして読み込み、評価する。<path> より後ろのトークンは プログラム起動引数としてそのまま実行プログラムへ渡り、std:envargs() (std/env.md §3) で取得できる。

hikari app.hika list --json hello     # args() は ["list", "--json", "hello"]

hikari 自身のフラグは位置を問わず entry に渡る前に取り除かれるため args() には現れない。

5.1 ファイル先頭の扱い

ファイルは先頭に宣言行を持たない (language-spec.md §13.1)。先頭の空行・行コメント・shebang #!... は許容され、# で始まる行はすべて行コメントである (language-spec.md §1.1)。

5.2 標準入出力

  • 標準入力: input(prompt) (prelude.md §1) の読み取り元。
  • 標準出力: print(s) の出力先。
  • 標準エラー: パース/評価エラーメッセージの出力先(トップレベルに達した ? の失敗 bail 診断を含む、language-spec.md §16.5)。

5.3 import の解決

import <対象> := "<rel>"caller ファイルのディレクトリ を起点に絶対化される。同じファイルを複数回 import してもパースは 1 度だけである。循環 import は呼び出し位置のエラーで停止する (詳細は language-spec.md の import 章を参照)。

ファイル実行モードでは OS の絶対パス解決が使われ、ファイルシステム外への参照 (絶対パスなど) も許される。embed バイナリ (build.md) では FS ルートからの slash 相対パスに限定される (driverConfig::embed_mode)。

std:fs の各関数 (read / write / readdir ほか、std/fs.md) は import fs := "std:fs" で取得するが、データファイルの読み書きはソースの import m := "x.hika" とは 解決系統が別 で、embed バイナリ内でも常にホスト FS の cwd 相対で動く (embed FS にはアクセスしない)。std:fs モジュール自体は embed バイナリにも常に含まれる。

5.4 終了コード

状況 code
正常終了 0
パース・評価エラー 1
ファイル読み取り失敗 2

トップレベルに達した未処理失敗(? の失敗 bail、language-spec.md §16.5)は評価エラーとして 1。診断は stderr(§5.2)に出す。

5.5 静的型検査

hikari <path> は、評価の 前に 必ず静的型検査 (static-analysis.md §2) を走らせ、型エラーが 1 件でもあれば診断を stderr に出して 評価せず exit code 1 で停止する。型検査がクリーンなら通常どおり評価する。

  • 検査の内容は static-analysis.md §2 が定める (検出対象の一覧は check.md「検査内容」)。
  • 水準を下げる手段は無い。一部の規則だけを外すフラグも、ファイル単位で有効・無効を切り替える手段も持たない (ファイルは中身だけを宣言し、処理系の振る舞いを変える属性は持たない。language-spec.md §13.1)。評価せず診断だけを見たい場合は hikari check (check.md) を使う。
  • 終了コードは §5.4 と同じ (型エラーは構文/評価エラーと同じ 1)。

5.6 標準入力からの評価 (hikari eval)

hikari eval は標準入力から読み込んだソース全量を .hika プログラムとして評価する。エディターの選択範囲など、ファイルに無いソース断片を実行する用途を想定する。

  • 入力: 標準入力全量がソース。引数は受けない — パスもフラグも引数不正 (2) として断る。hikari eval foo.hika は「そのファイルを評価する」と読めるので、黙って読み飛ばすと書き手は何も起きないまま標準入力を待たされる。
  • ファイル先頭: ファイル実行 (§5.1) と同じく、先頭に宣言行は要らない。
  • 型検査: ファイル実行 (§5.5) と同じく静的型検査 (static-analysis.md §2) を必ず適用する。型エラーが 1 件でもあれば評価せず exit code 1
  • 標準出力: print(s) の出力先。標準エラー: パース/評価エラーの出力先。
  • input(): 標準入力はソースとして消費されるため、input(prompt) は即座に EOF(空)を受け取る。
  • import の解決: import <対象> := "<rel>"実行時カレントディレクトリ を起点に絶対化される(§5.3 と同じ OS filepath ベース)。エラー位置のファイルラベルは <stdin> と表示する。
  • 終了コード: ファイル実行 (§5.4) と同一。
状況 code
正常終了 0
パース・評価エラー 1
標準入力の読み取り失敗 / 引数不正 2

eval評価する 点で、評価せずソースを扱う check / format / lint (§1.2) とは別系統である。

6. 静的検査 (hikari check)

静的検査 (hikari check) の仕様は check.md に分離した。

7. テスト (hikari test)

テスト (hikari test) の仕様は test.md に分離した。

8. 整形 (hikari format)

整形 (hikari format) の仕様は format.md に分離した。

9. スタイル検査 (hikari lint)

スタイル検査 (hikari lint) の仕様は lint.md に分離した。

10. 図の生成 (hikari diagram)

図の生成 (hikari diagram) の仕様は diagram.md に分離した。.hika を、外部資源を参照しない 1 枚の図(既定は HTML、--svg で SVG 単体、--no-comments でコメント抜き)に変換する。図が足すのはリテラルの入れ子・書かれた区切り (|match のアームの =>) による左右と上下の分割・名前の指し先の 3 つだけで、:=! などの字面は書かれたまま残る。

11. リファレンス生成 (hikari doc)

hikari doc は prelude・std・言語構文の doc コメント(#|)と、処理系が焼き込んで持つリファレンス表からユーザー向けリファレンス Markdown を docs/reference/ に生成する。.hika の doc コメントと焼き込んだ表が真実源であり、docs/reference/ はそこから機械的に生成される派生物である。ライブラリ項目には、処理系の静的型表 (LSP hover と同じ出所) から型シグネチャ (Hikari 型表記) を合成し、形と同じコードブロックの 2 行目に束縛注釈と同じ「名前: 型」の形 (例 range: {Int, Int | Range}) で併記する。型表から確定しない項目 (型名の値束縛・each のように戻り型を静的に固定できないメソッドなど) は形と意味だけを出す。

11.1 構文

hikari doc [--check]

引数を取らない (対象は常にリポジトリ全体の doc コメント)。

11.2 動作

  • hikari doc — prelude・std 各モジュール・言語構文の doc コメントを収集し、ライブラリ項目に静的型表から型シグネチャを join した上で、docs/reference/{prelude.md, std/*.md, syntax.md} を生成して上書きする。
  • hikari doc --check — 同じ生成処理を行い、結果が現在の docs/reference/ の内容と一致するか検査する。差分があれば非ゼロ終了 (CI で「生成物が最新か」を検査する用途)。
  • --check 以外の引数は受けない — 知らないフラグも、パスのような余分な引数も引数不正 (§11.4) として断る。読み飛ばすと --chek のような綴り違いが黙って書き出しへ倒れ、検査のつもりで回した入口が常に緑になる。書き出し先は固定なのでパスを取る余地も無い。

11.3 doctest

doc コメント中の >>> で始まる例はリファレンスへそのまま載る。例は実際に評価して期待値と突き合わせるmake doctest。焼き込んだ表が持つ例を REPL と同じ評価で走らせる)。したがって例が実装と乖離したらそこで落ちる。

.hika の doc ブロックと焼き込んだ表の例が食い違わないことは、鮮度の検査(compiler/docdata/tests/fresh.rs)が別に見る。例の見張りはこの 2 段で、前者だけだと表と実装が揃って古くなる形を見逃し、後者だけだと .hika を直して表を直し忘れたことに気付けない。

11.4 出力と終了コード

状況 code
生成 (--check 無し) 成功 0
--check で差分なし 0
--check で差分あり 1
I/O エラー / 引数不正 2

12. パッケージ管理 (add / get / update / remove)

third-party パッケージ (packages.md) の依存を、マニフェスト (package.toml) と lockfile (package.lock) を介して管理する。取得元は git source とローカル path dep。別名解決・キャッシュ・推移依存・複数共存の意味論は packages.mdpkg: 解決の言語側は language-spec.md §13.4 を参照。

各コマンドは cwd を起点に上方探索で最も近いマニフェストを対象とする。マニフェストが無い場合は §12.5 のエラー。

add / remove はマニフェストの deps / entry を読み、正規形 (entry を先頭に置き、続けて [deps] テーブルに alias = "<source>" を 1 行ずつ) で書き戻す。既存の deps宣言順は保持し、追加分は末尾に足す。マニフェストに書いたコメントは保持されない。

12.1 hikari add

hikari add <host/path@tag> [--as <alias>]
  • <host/path@tag> の git source をキャッシュ (§13 HIKARI_CACHE) へ取得し、tag → commit を解決して lockfile に固定する。マニフェスト depsalias = "<host/path@tag>" を追記する。
  • --as <alias> 省略時、alias は path の末尾要素をそのまま使う (例 github.com/u/hikari-httphikari-http)。末尾要素が alias の字形 (packages.md §1) に合わない場合 (. を含むなど) は取得せずエラーで --as <alias> を要求する。短い別名にしたい場合も --as http を使う。
  • 既存の同名 alias があればその pin を更新する (version の差し替え)。
  • path dep の追加は hikari add では扱わず、マニフェストを直接編集する (取得を伴わないため)。

12.2 hikari get

hikari get
  • 引数なし。マニフェストと lockfile を読み、未取得の依存をキャッシュへ復元する。lockfile があれば commit を信頼し tag の再解決はしない。CI・新規 clone 後の初期化に使う。
  • lockfile が無い場合はマニフェストから tag → commit を解決して取得し、lockfile を生成する。

12.3 hikari update

hikari update [alias]
  • マニフェストに記載された tag を再解決 (tag → 現在の commit) し、lockfile を書き換える。alias 指定でその 1 件、省略で全 git 依存。
  • バージョンを上げるのは tag の変更 (hikari add <...@新tag> またはマニフェスト編集) であり、update は記載済み tag の commit 固定を最新化するもの (semver range の自動引き上げは持たない)。

12.4 hikari remove

hikari remove <alias>
  • マニフェスト deps から <alias> を削除し、どの依存からも参照されなくなった実体を lockfile から除く。キャッシュ実体は他プロジェクトと共有のため削除しない。

12.5 出力と終了コード

状況 code
成功 0
取得・解決失敗 (不正な tag / リポジトリ到達不可 / マニフェスト不正) / 対象 alias 不在 1
引数不正 / マニフェスト読み取り失敗 / git 不在 2

git ツールチェーンは PATH の各要素に実行できる git があるかで確認する。無ければマニフェストを読むより先に exit code 2 で止まる (PATH が未設定のときも見つからない扱い)。

13. 環境変数

変数 影響先 意味
HIKARI_REPO hikari build / hikari lsp Hikari 本体ソースの絶対パス。設定すれば自動検出 (build.md「Hikari リポジトリの位置解決」/ lsp の定義ジャンプ lsp.md「定義ジャンプ」) より優先
HIKARI_CACHE add / get / update / ファイル実行・buildpkg: 解決 third-party パッケージのグローバルキャッシュ。未設定時の既定は XDG の $XDG_CACHE_HOME/hikari (既定 ~/.cache/hikari) (packages.md)
HIKARI_VERIFY_ERASURE ファイル実行・hikari test・REPL・hikari build 設定すると、型消去 (language-spec.md §17) で照合が消えた地点でも照合を実行し、失敗したら専用の診断を出して停止する。Any を経由した書き換えが別の注釈位置の前提を壊していないかを実測で確かめる口である (同 §17「健全性保証」)。消えた地点へ照合を残すかはビルド時に決まるので、hikari build の生成物で検分したいときはビルド時にも設定する。未設定時は消えた地点で何もしない
HIKARI_VERIFY_GC ファイル実行・--aot 生成物 設定すると、箱のアリーナの回収器が空いた添字を再利用せず墓標を残し、解放済みの箱を読んだら報告する (rust-backend.md「箱のアリーナは回収器を持つ」)。未設定時は freelist で添字を再利用する

14. 意図的に残す制約

  • cargo install で据えたバイナリから hikari build を使う場合、処理系ソースツリーのルートが見つからなければ HIKARI_REPO が要る (本体ソースの自動配置は未対応)。探索順は build.md「Hikari リポジトリの位置解決」を参照。
  • Universal Binary (darwin/arm64 + darwin/amd64lipo 結合) は非対応 — 別ターゲットとして個別バイナリを並べるのみ。
  • バイナリサイズの最適化は行わない。hikari build は生成した cargo プロジェクトを cargo build --release で組むだけで (同梱モードの雛形が opt-level = 3 を置くほかは release の既定のまま)、strip も UPX 等の圧縮も掛けない。
  • LSP は semantic tokens・go-to-definition・references・hover (型情報)・補完 (ドットメンバー)・整形 (全文フォーマット)・コードアクション (lint 自動修正)・シンボル一覧 (アウトライン)・リネーム・インレイヒント (推論型)・出現ハイライト・診断 (静的検査 Error + lint Warning、publishDiagnostics) を提供 (各機能は lsp.md)。hover は prelude 組込名・ユーザー定義識別子に加え、型メソッド (list.each 等) とユーザー定義オブジェクトのメンバーも対象とする (lsp.md「hover」)。補完はドット (.) を trigger に、レシーバーの slot・型メソッド・std メンバー・universal method を返す (lsp.md「補完」)。
  • hikari format は AST 再構成方式のため、行内の任意改行位置やスロットの positional/named 混在順といった意味に影響しない見た目は正規形へ寄せる (原文どおりには保たない)。
  • hikari lint のルールの一覧は lint.md「ルール」の表が持つ。ここには写さない — まとめた一覧を別ファイルへ置くと、ルールを足したときに片方だけが古くなる (あちらの code 表は make diag-codes が実装の診断コードと突き合わせるので、正の側は機械が守る)。多くは全体走査による保守的判定に留める (制御構造名・条件分岐系ルールは構文上の callee 名のみで判定し、シャドウイングは見ない)。例外は single-assignshadow の 2 つで、どちらも「その名前がどのスコープの束縛か」が意味に効くためオブジェクトリテラル単位のスコープ木を組む — single-assign は束縛ごとに書き込み回数を数え (lint.md「single-assign がスコープ厳密解析を行う理由と健全性」)、shadowmatch のアーム body も独立フレームに分けたうえで外側スコープ・prelude の同名と突き合わせる (lint.md「shadow の判定範囲」)。
  • third-party パッケージの取得元は git と ローカル path dep のみ (packages.md)。中央レジストリ・HTTPS tarball 直取得・semver range の自動解決は非対応 (exact pin + 複数共存)。hikari add 等のパッケージ管理コマンドは git ツールチェーンを必要とする。