Phase 273 P0-P1: Two-layer plan architecture - DomainPlan: Pattern-specific knowledge (ScanWithInit) - CorePlan: Fixed vocabulary (Seq, Loop, If, Effect, Exit) - ValueId references only (String expressions forbidden) - Pipeline: Extractor→Normalizer→Verifier→Lowerer New plan/ module: - mod.rs: Type definitions, SSOT spec - normalizer.rs: DomainPlan→CorePlan + ID allocation - verifier.rs: V1-V6 invariant checks (fail-fast) - lowerer.rs: CorePlan→MIR (pattern-agnostic) LLVM fix (ChatGPT): - function_lower.py: Fix argument reference bug - Phase 258 index_of_string now PASS on LLVM backend 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
4.3 KiB
4.3 KiB
Phase 273 P1: Plan語彙固定 + PlanVerifier(fail-fast)(Claude Code 指示書)
Status: instructions / design-first
目的:
- P0 の pattern-specific Plan(
Plan::ScanWithInit)を、増殖しない固定語彙へ畳む。 - Extractor は pure を維持しつつ、Plan の整合性は Verifier で fail-fast に固定する。
スコープ:
- Plan 型の再設計(固定語彙への移行)
- PlanNormalizer(DomainPlan → CorePlan)の追加(SSOT)
- PlanVerifier の追加(境界で fail-fast)
- Pattern6 を “固定語彙 CorePlan” で表現し直す(PoC 維持)
Non-goals:
- 全 pattern の移行(P2+)
- 新しい言語機能
- env var 追加
参照:
- Phase 273 README:
docs/development/current/main/phases/phase-273/README.md - Phase 273 P0 completion:
docs/development/current/main/phases/phase-273/P0-COMPLETION.md - Frag SSOT:
docs/development/current/main/design/edgecfg-fragments.md
Step 1: Plan の固定語彙を導入する
方針:
Planの variant を “構造語彙” に固定する(増殖しない)。- pattern-specific variant は廃止方向(P1では Pattern6 から移行)。
最低限(P1):
Plan::Seq(Vec<Plan>)Plan::Loop(LoopPlan)Plan::If(IfPlan)Plan::Effect(EffectPlan)(副作用の順序だけ)Plan::Exit(ExitPlan)(Return/Break/Continue…)
注意:
- P1では “式の意味” を Plan に入れすぎない(expr は参照/ID/ASTNode を持つだけにする)。
- 式を
Stringにしない(Lowerer 側に「文字列式の解釈器」を生やさない)。
Step 1.5: DomainPlan → CorePlan の 2層 + PlanNormalizer(SSOT)
狙い:
- “固定語彙にしたいが、scan固有データも欲しい” の葛藤を構造で解消する。
- Lowerer を CorePlan-only にして、pattern固有知識の混入を防ぐ。
方針:
DomainPlan: pattern 固有の最小表現(短命・増殖は許容するが「削る側」)CorePlan: 固定語彙のみ(増殖禁止)PlanNormalizerが 唯一DomainPlan → CorePlanを行う(SSOT)
重要:
EffectPlan::ScanInitのような scan専用 variant は禁止- 「あとで MethodCall に統一する」前提の例外は作らない(裾広がりの入口になる)
Step 2: PlanVerifier を追加する(fail-fast)
新規モジュール案:
src/mir/builder/control_flow/plan/verifier.rs
役割:
- Extractor が返した Plan が “Lowerer が扱える契約” を満たすかを検証する
- close-but-unsupported を
Errにして誤コンパイル余地を潰す
P1で入れる最小の不変条件(例):
- Loop の header params / carriers が揃っている
- Exit が Loop 外へ飛ぶ場合の kind が妥当
- Effect が順序上の制約を破っていない(最低限:Effect がブロック境界で落ちない)
Step 3: Pattern6 を固定語彙 Plan で表現し直す
方針:
- Extractor は
DomainPlanを返す(pure)。 PlanNormalizerがDomainPlan → CorePlanを行い、固定語彙CorePlan::{Seq,Loop,If,Exit,Effect}の組み合わせに落とす。- Lowerer は
CorePlanのみを処理する(pattern固有知識を持たない)。
禁止(P1):
- scan固有情報を
EffectPlanの payload/variant として持つこと(固定語彙の侵食) - 式を
Stringとして Plan に埋め込むこと(第二の処理系が生える)
Step 4: Router の責務を整理する
方針:
- router は
extract_*を呼び、PlanVerifierを通し、PlanLowererに渡すだけ。 - router が builder を触らない(制御の入口は薄く保つ)。
推奨の順序(P1):
extract_*(pure, DomainPlan)→Ok(None)/Ok(Some(domain))/ErrPlanNormalizer::normalize(domain) -> CorePlan(SSOT)PlanVerifier::verify(&core)(fail-fast)PlanLowerer::lower(core)(CorePlan-only)
Step 5: 回帰確認(P0 と同等)
最低限:
tools/smokes/v2/profiles/integration/apps/phase254_p0_index_of_vm.shPASS
完了条件(P1)
- Plan enum の variant が固定語彙に収束している(増殖しない)
- PlanVerifier が境界で fail-fast を提供している
- Pattern6 が固定語彙 Plan で表現され、P0のPoCが維持されている