14 KiB
14 KiB
Current Task — Phase 15 Snapshot (2025-09-18)
Snapshot / Policy
- Execution policy: PHI-off (edge-copy) by default. MIR builders/bridge do not emit PHIs; LLVM (llvmlite harness) synthesizes PHIs. PHI-on is dev-only and gated by feature
phi-legacy. - Semantic reference: PyVM. AOT/EXE-first via llvmlite harness +
ny-llvmc. - Harness-first run path:
--backend llvmuses llvmlite harness (whenNYASH_LLVM_USE_HARNESS=1) to emit an EXE and run it, returning the program exit code.
Env toggles (current)
NYASH_MIR_NO_PHI(default=1): PHI-off.NYASH_VERIFY_EDGE_COPY_STRICT=1: Enable strict edge-copy verifier in PHI-off.NYASH_LLVM_USE_HARNESS=1: Use llvmlite harness path.NYASH_LLVM_PREPASS_IFMERGE=1: Enable if-merge prepass for ret-merge convenience (harness).NYASH_LLVM_TRACE_PHI=1+NYASH_LLVM_TRACE_OUT=<file>: Emit PHI wiring JSONL trace.phi-legacyfeature +NYASH_MIR_NO_PHI=0: Dev-only PHI-on (legacy/testing).
Planned (parser Stage‑3 gate):
NYASH_PARSER_STAGE3=1to accept try/catch/throw/cleanup syntax in the core parser (postfix catch/cleanup included).
Completed (highlights)
- Loop/If builder hygiene
- Continue/Break commonized (
jump_with_pred,do_{break,continue}) in MIR LoopBuilder and JSON bridge.
- Continue/Break commonized (
- PHI-off correctness tooling
- Strict verifier (PHI-off): checks per-pred
Copycoverage and forbids merge self-copy (NYASH_VERIFY_EDGE_COPY_STRICT=1). - LLVM PHI trace (JSONL): unified structured events from harness (
finalize_*,add_incoming,wire_choose,snapshot). - Trace checker:
tools/phi_trace_check.py(diffs on mismatch,--summary/--strict-zero).
- Strict verifier (PHI-off): checks per-pred
- Harness-first runner
--backend llvm+NYASH_LLVM_USE_HARNESS=1: emit EXE viany-llvmcand run (returns exit code).
- One-shot + smokes
tools/phi_trace_run.sh: build → run → trace → check in one shot (multi-app;--strict-zero).tools/test/smoke/llvm/phi_trace/test.sh: curated cases (loop_if_phi / ternary_nested / phi_mix / heavy_mix).- Difficult mixes added:
apps/tests/llvm_phi_mix.nyash,apps/tests/llvm_phi_heavy_mix.nyash(Box生成 + continue/break/early return)。
- Docs
- PHI policy:
docs/reference/mir/phi_policy.md(PHI‑off恒久・PHI‑on保守限定)。 - Lowering contexts guide:
docs/design/LOWERING_CONTEXTS.md(If/Loop スナップショット規約)。 - PHI-off トラブルシュート:
docs/guides/phi-off-troubleshooting.md。 - Testing guide updated with trace usage.
- Stage‑3 Exceptions (MVP):
docs/guides/exceptions-stage3.md(単一catch+Resultモード+ThrowCtx の方針)。
- PHI policy:
- Stage‑3 parser gate(Phase A 完了)
- Rust parser が
NYASH_PARSER_STAGE3=1で try/catch/cleanup/throw を受理((Type x)|(x)|()の各形式)。 - parser tests/EBNF/doc を更新。
- Rust parser が
- Bridge Result‑mode(Phase B/C の実装基盤)
NYASH_TRY_RESULT_MODE=1で try/catch/cleanup を MIR Throw/Catch なしに構造化lower(単一catchポリシー)。- ThrowCtx(thread‑local)で try 降下中の任意スコープの throw を現在の catch に集約(ネスト throw 対応)。
- 合流は PHI‑off 規約(edge‑copy)。Bridge 出力に PHI が混ざった場合は
strip_phi_functionsで正規化(後段ハーネスは PHI 合成)。 - Bridge スモーク追加:
tools/test/smoke/bridge/try_result_mode.sh(JSON v0 → Bridge → PyVM/VM。代表ケース緑)。
Tools & Scripts (quick)
- One-shot:
bash tools/phi_trace_run.sh apps/tests/llvm_phi_heavy_mix.nyash --strict-zero - PHI trace smoke (optional):
bash tools/test/smoke/llvm/phi_trace/test.sh - Fast smokes (opt-in trace):
NYASH_LLVM_TRACE_SMOKE=1 bash tools/smokes/fast_local.sh - Bridge (Result‑mode) smokes:
bash tools/test/smoke/bridge/try_result_mode.sh - Bridge→harness PHI trace (WIP):
bash tools/phi_trace_bridge_try.sh tests/json_v0_stage3/try_nested_if.json
Next — Stage‑3 Try/Catch/Throw (cleanup unified; parser→lowering, incremental)
Phase A — Parser acceptance (no behavior change)
- Goal: Accept Stage‑3 syntax in the Rust parser behind a gate.
- Scope:
- Parse
try { … } catch [(Type x)|(x)|()] { … } [cleanup { … }]andthrow <expr>.- Build existing AST forms:
ASTNode::TryCatch,CatchClause,ASTNode::Throw. - Gate via env (planned):
NYASH_PARSER_STAGE3=1(既定OFF)。 Status: DONE (cleanup unified; finally removed)
- Build existing AST forms:
- Deliverables:
- Parser unit tests: 正常(各バリアント)/構文エラー(不完全・重複cleanup等)。
- EBNF/doc 更新(最小仕様、複数catchは将来)。
Phase B — Safe lowering path (no exceptions thrown)
- Goal: Allow “no-throw path” lowering to MIR/JSON so existing runners remain green.
- Scope:
- Lower try/catch when try-body doesn’t throw; catch block is structurally present but not executed.
- JSON v0 bridgeとASTの形状整合を確認(既存
lowering/try_catch.rsを安全適用)。
- Deliverables:
- Minimal smoke: try/catch where try 内で例外なし(正常合流/ret の健全性)。
Status note (Result‑mode MVP)
NYASH_TRY_RESULT_MODE=1: try/catch/cleanup を構造化lower(MIR Throw/Catch 不使用)。- 単一catchポリシー+ThrowCtx でネスト throw を含む try 範囲の throw を集約(catch パラメータは preds→値の束ねで受理)。
- 合流は PHI‑off(edge‑copy)。Bridge 出力時に PHI が残った場合は正規化して除去。
Phase C — Minimal throw/catch path
- Goal: Enable one end-to-end throw→catch→cleanup path for simple cases.
- Scope:
throw "message"→ 単一 catch で受理(型は文字列ラベル相当の最小仕様)。
- cleanup は “常に実行” の構造のみ(副作用最小)。
- PHI-off 合流は edge-copy 規約を維持(phi-trace で preds→dst 網羅を確認)。
- Deliverables:
- 代表スモーク(print/return 系)
- phi-trace を用いた整合チェック Implementation track (current)
- Use
NYASH_TRY_RESULT_MODE=1and single‑catch policy(catch 内分岐)。 - ThrowCtx によりネスト throw を集約。catch パラメータは preds→値の束ねで受理(PHI‑offはedge‑copy)。
- LLVM harness: PHI 責務を finalize_phis に一任。ret.py を簡素化(Return のみ)。if‑merge 事前宣言の安全化、uses 向け predeclare を追加。
- 結果: try/cleanup 基本・print・throw(デッド)・cleanup return override(許可) は harness 緑。
- 残: method 後置 cleanup + return(許可) は PHI 先頭化の徹底が必要(resolver の未宣言 multi‑pred PHI 合成を完全停止→predeclare 必須化)。
Phase 15.5 — Block‑Postfix Catch(try を無くす設計)
Design (MVP)
- Syntax(後置):
{ body } catch (e) { handler } [cleanup { … }]{ body } cleanup { … }(catch 省略可)- Policy:
- 単一 catch(分岐は catch 内で行う)。パラメータ形式は
(Type x)|(x)|()を許容。 - 作用域は “同じ階層” のブロックに限定。ブロック内の
throwは直後の catch にのみ到達(外に伝播しない)。 - MVP 静的検査: 直後に catch のない独立ブロック内で「直接の
throw文」を禁止(ビルドエラー)。関数呼び出し由来の throw は当面ノーチェック。 - 適用対象: 独立ブロック文に限定(if/else/loop の構文ブロック直後は不可)。必要なら独立ブロックで包む。
- 単一 catch(分岐は catch 内で行う)。パラメータ形式は
Gates / Flags
- Parser gate(提案):
NYASH_BLOCK_CATCH=1(受理ON)。初期は Stage‑3 と同一ゲートでも可(NYASH_PARSER_STAGE3=1)。 - Bridge: 既存
NYASH_TRY_RESULT_MODE=1(構造化lower/MIR Throw/Catch不使用)。
Lowering(実装方針)
- Parser で後置 catch/cleanup を既存
ASTNode::TryCatchに畳み込む(try_body=直前ブロック)。 - Bridge は既存 Result‑mode/ThrowCtx/単一catch・PHI‑off(edge‑copy)をそのまま利用(コード変更最小)。
Tasks(順番) — Progress
- Parser acceptance(ゲート付き) — DONE(cleanup 統一)
- 後置 catch/cleanup を受理 →
ASTNode::TryCatchに組み立て。- 限定: 独立ブロック文のみ。トップレベルの
catch/finally先頭は専用エラーで誘導(if/else/loop 直後では使わず、独立ブロックで包む)。 - Unit tests:
(Type x)/(x)/()+cleanup、ネガティブ(直後に catch 無しで直接 throw など)。
- 限定: 独立ブロック文のみ。トップレベルの
- Static checks(MVP) — DONE
- 独立ブロック内 “直接の throw 文” に後置 catch が無ければビルドエラー。
- 将来拡張: 関数に最小 throws 効果ビットを導入し、静的安全性を高める(未着手)。
- Bridge / Lowering(確認のみ) — DONE
- 既存 Result‑mode の try/catch/finally 経路で正常動作(ThrowCtx によるネスト throw 集約、PHI‑off 合流)。
- Bridge スモーク(JSON v0→PyVM)を拡充。統合ハードケース追加(後述)。
- Docs & EBNF 更新 — DONE
- 例外ガイドを後置 catch 中心に再編。EBNF に
block_catch := '{' stmt* '}' ('catch' '(' … ')' block)? ('cleanup' block)?を追加し、ゲートも明記。
- Harness PHI trace(継続) — WIP
- finalize_phis の PHI 配置を「常にブロック先頭」へ修正し、Bridge→harness の後置構文ケースを緑に。
Migration / Compatibility
- 旧
try { … } catch { … }は当面受理(非推奨)。段階導入後に後置 catch を推奨デフォルトへ。 - 将来: フォーマッタ/自動変換の提供を検討。
Risks / Notes(Phase 15.5)
- 直後 catch 不在での throw を静的に完全検出するには “効果型” が必要。MVP は「直接の throw 文のみチェック」で開始。
- 構文の曖昧さ(if/else/loop ブロック直後)は独立ブロックに限定する規則で回避。
Out of scope(初期)
- 複数 catch/型階層、例外伝播/ネストの深い制御、最適化。
Phase 15.6 — Method‑Level Postfix Catch/Finally(メソッド境界の安全化)
Design (MVP)
- Syntax(後置 at method end):
method name(params) { body } [catch (e) { handler }] [cleanup { … }]- Policy:
- 単一 catch、順序は
catch→finallyのみ許可。 - 近接優先: ブロック後置の catch があればそれが優先。次にメソッドレベル、最後に呼出し側。
- 単一 catch、順序は
- Gates / Flags
NYASH_METHOD_CATCH=1(またはNYASH_PARSER_STAGE3=1と同梱)
Plan(段階)
- Parser acceptance(ゲート付き)
- 既存メソッド定義の末尾に
catch/finallyを受理 →TryCatchに正規化(body を try_body に束ねる)。 - Unit tests: 正常/順序違反/複数catchエラー/末尾finallyのみ。
- 既存メソッド定義の末尾に
- Lowering(確認のみ)
- 既存 Result‑mode/ThrowCtx/PHI‑off 降下を再利用(変更なし)。
- Docs & EBNF 更新(本チケットで一部済)
- 仕様・ガイドを method‑level 追記、使用例と制約を明記。
Future (Phase 16.x)
- ブロック先行・メソッド後置
{ body } method name(..) [catch..] [finally..]に拡張(先読み/二段パース)。
Handoff (2025‑09‑18)
- Status
- Parser: DONE(ゲート
NYASH_METHOD_CATCH=1またはNYASH_PARSER_STAGE3=1)。 - AST: FunctionDeclaration.body は TryCatch に正規化(単一catch、順序=catch→cleanup)。
- Docs/EBNF: 更新済。
- Unit tests: パーサ単体(cleanup‑only)追加済。
- E2E: PENDING(VM/MIR 経路)。現状
static box Main { main() { … } finally { … } }で MIR ビルダが duplicate terminator panic。
- Parser: DONE(ゲート
- Repro (E2E panic)
NYASH_METHOD_CATCH=1 NYASH_PARSER_STAGE3=1 ./target/release/nyash --backend vm apps/tests/method_postfix_finally_only.nyash- Panic:
Basic block bb* already has a terminator(src/mir/basic_block.rs:94)。
- Next
- MIR builder: Try/Cleanup の終端整理(return は cleanup 実行後に有効化;二重 terminator 抑止)。
- E2E samples: method_postfix_finally_only(期待 42)/ method_postfix_catch_basic(構造確認)。
- 追加テスト: 複数 catch エラー/順序違反/近接優先の確認。
- Optional: TRM(JSON v0 Bridge)経由へのルート(暫定の回避パスとして)検討。
How to Run / Verify (current)
- Harness-first run(EXE ファースト)
NYASH_LLVM_USE_HARNESS=1 ./target/release/nyash --backend llvm apps/tests/loop_if_phi.nyash
- PHI trace(one-shot)
bash tools/phi_trace_run.sh apps/tests/llvm_phi_heavy_mix.nyash --strict-zero
- Strict verifier(PHI-off)
NYASH_VERIFY_EDGE_COPY_STRICT=1 cargo test --lib
- Bridge(Result‑mode) — JSON v0 → Bridge → PyVM/VM
bash tools/test/smoke/bridge/try_result_mode.sh- 直接:
NYASH_TRY_RESULT_MODE=1 NYASH_PIPE_USE_PYVM=1 ./target/release/nyash --ny-parser-pipe --backend vm < tests/json_v0_stage3/try_basic.json - 統合ケース(複合):
tests/json_v0_stage3/try_unified_hard.json(期待 exit=40)
- Bridge→Harness PHI trace(WIP)
bash tools/phi_trace_bridge_try.sh tests/json_v0_stage3/try_nested_if.json
Risks / Notes
- PHI-off と LLVM 合成の一貫性は phi-trace/strict で監視。開発時にズレが出たら JSONL と diff 出力で即座に特定可能。
- Harness 実行に Python/llvmlite が必要。
ny-llvmcはcargo build -p nyash-llvm-compiler --releaseで用意。 - 現在の課題: llvmlite ハーネス側の PHI 配置順序("PHI nodes not grouped at top")により Bridge→harness の一部ケースで失敗。Bridge 側は PHI‑off 正規化済み。ハーネスの
finalize_phisを「常にブロック先頭に PHI を配置」へ修正予定。