80 lines
4.6 KiB
Markdown
80 lines
4.6 KiB
Markdown
# Phase 20.18 — Result(ケースバイケース)+ 軽量糖衣 + Null/Void 固定
|
||
|
||
目的(要約)
|
||
- 「全部 Result は重い」を回避しつつ、一貫した失敗取り扱いを提供する。
|
||
- Null/Void の言語レベル固定(予約語)と VM 値表現(Null タグ)を導入し、欠落/手続きの意味を明確化。
|
||
- ケース別の最小主義:検索=sentinel、境界=Fail‑Fast+try_系、変換/I/O=Result 既定。
|
||
- 糖衣は左辺だけ(`let a?=/a!=`)に限定し、ゼロアロケーションで Lowering。
|
||
|
||
適用範囲(MVP)
|
||
- Null/Void の固定(言語+VM)
|
||
- 言語: `null`, `void` を予約語にする(リテラル)。
|
||
- MIR JSON v0: `Const` に `{"type":"Null"|"Void"}` を追加。
|
||
- VM/Interpreter: `VMValue::Null` を追加(0 アロケーション、比較高速)。
|
||
- 既定挙動(SSOT)
|
||
- `String.indexOf/1` → not found は `-1`(sentinelのまま)。
|
||
- `Array.get/1` → 範囲外は `null`(Fail しない)。
|
||
- `Array.pop/0` → 空配列は `null`(Fail しない)。
|
||
- `Array.set/2` → i<0 または i>len は `E_OOB`、i==len は append、0<=i<len は置換。戻りは `void`。
|
||
- `Map.get/1` → 欠落は `null`(Fail しない)。
|
||
- `Map.set/2` → 不正キー= `E_INVALID_KEY`、不正値= `E_INVALID_VALUE`、戻りは `void`。
|
||
- `Map.delete/1` → 削除値 or `null`。`Map.clear/0` → `void`。
|
||
- 追加API(5つ)
|
||
- `Array.try_get/1`, `Array.try_pop/0`
|
||
- `Map.try_get/1`
|
||
- `String.to_i64/0`, `String.to_f64/0`
|
||
|
||
糖衣(任意・軽実装)
|
||
- `let r = arr.try_get(0)` … Resultのまま
|
||
- `let x? = arr.try_get(0)` … `ok→値 / err→VoidBox`
|
||
- `let x! = arr.try_get(0)` … `ok→値 / err→即Fail`
|
||
- `if let ok(v) = arr.try_get(0) { … } else { … }`
|
||
|
||
実装方針(段階導入)
|
||
- Phase A(本フェーズ)
|
||
- Null/Void: 予約語・MIR・VM の三層で固定(VMValue::Null、singleton 変換)。
|
||
- Core/Gate‑C: Array/Map の SSOT へ挙動を収束(上記 既定挙動)。
|
||
- Parser: 左辺の `?`/`!` と `if let ok(..)` を受理。
|
||
- Lowering: `?`/`!`/if-let を branch/select に展開(ゼロアロケーション)。
|
||
- Verifier: 例外タグ `E_OOB/E_EMPTY/E_NOT_FOUND/E_PARSE` を安定化。
|
||
- Gate: `HAKO_TRY_API=1`(既定OFF)でスモーク有効化。
|
||
- Phase B(20.19+ 任意)
|
||
- MIR/LLVM を“値版Result” `{i1 ok, T payload}` に寄せる(SROA/mem2reg 合流)
|
||
- Box化は保存/境界(FFI/ABI)のみで行いゼロコスト化を徹底
|
||
|
||
受入れ基準(MVP)
|
||
- quick(opt‑in)で try_* + 糖衣(`?`/`!`/if-let ok)スモークが緑。
|
||
- Fail‑Fastタグが安定(E_OOB/E_EMPTY/E_NOT_FOUND/E_PARSE)。
|
||
- Array/Map の SSOT(Null/void 既定)が Gate‑C/Core/VM で一致。
|
||
|
||
---
|
||
|
||
完了サマリ(2025‑10‑29 現在)
|
||
- Bridge‑B(Ny/Core直行): include ベースで安定。Gate‑C(Core) の file/pipe は緑。
|
||
- Core canary(直行): array_get/push/set_get は緑。string indexOf bang は TTL 互換で緑(タグ優先、未到達時は -1/rc=0 を暫定許容)。
|
||
- Runner: Core ラッパー出力はタグ行を優先採用。Gate‑C(Core) はタグ→stderr+rc=1、数値→rc=(num&0xFF)。
|
||
- Docs: VM README/Smokes README/CURRENT_TASK を更新(Bridge‑B方針、カナリア導線、TTL注記)。
|
||
|
||
残タスク(短期)
|
||
- Core からの Fail‑Fast を state 経由の戻り値へ統一して、タグを必ず last line にする(print 依存解消)。
|
||
- 上記完了後、string indexOf bang の TTL 互換(-1容認)を撤去し、タグ必須に戻す。
|
||
|
||
ノート
|
||
- 20.17 は self‑hosting 完了を優先。実装は本フェーズでまとめて入れる。
|
||
- 糖衣は左辺のみ(公開名の二重化を避ける)。Result は段階で“値版”へ移行予定。
|
||
|
||
---
|
||
|
||
## Plugins への影響(互換ポリシー)
|
||
|
||
ABI 変更は不要(Box 戻りのまま)。ただし意味論は SSOT に合わせる:
|
||
|
||
- ArrayBox(プラグイン実装がある場合)
|
||
- get: 範囲外→NullBox、pop: 空→NullBox、push/set/clear: 戻りは VoidBox。
|
||
- set: i<0 or i>len は `E_OOB`。i==len は append、0<=i<len は置換。
|
||
- MapBox(プラグイン実装がある場合)
|
||
- get: 欠落→NullBox、delete: 削除値 or NullBox、clear: VoidBox、set: VoidBox。
|
||
- set: Null key/不正型→ `E_INVALID_KEY`、不正値→ `E_INVALID_VALUE`。暗黙変換は禁止。
|
||
|
||
Core/Gate‑C が先行で SSOT を満たすため、プラグインが未更新でも Gate‑C(Core) 直行経路は安定。VM 経路でプラグイン実装が呼ばれる場合は、上記の意味論に合わせて段階更新する。
|