Files
hakorune/docs/development/current/main/phase121_integration_roadmap.md

549 lines
15 KiB
Markdown
Raw Normal View History

docs(joinir): Phase 121 hako_check JoinIR integration design ## Phase 121: hako_check JoinIR 統合設計 (完了) ### 概要 hako_check経路のJoinIR統合に向けた設計と現状調査を完了。 実装修正なし、設計と調査のみ(Phase 122+で実装予定)。 ### 完了タスク - ✅ 設計ドキュメント作成: hako_check_design.md - ✅ 現状調査完了: phase121_hako_check_investigation.md - ✅ 旧MIR/PHI経路特定: phase121_legacy_path_analysis.md - ✅ 統合計画策定: phase121_integration_roadmap.md - ✅ Phase 120との関係整理完了 ### 重要な発見 1. **hako_checkは.hakoスクリプト** - Rustバイナリではなく、.hakoスクリプトとして実装 - tools/hako_check/cli.hako がエントリーポイント - VM の MirBuilder に JoinIR 統合すれば自動的に対応 2. **If文は旧経路、Loopは部分統合** - If文 (src/mir/builder/if_form.rs): ❌ 旧PHI生成器使用中 - Loop (src/mir/builder/control_flow.rs): ⚠️ Mainline Targetsのみ統合 3. **環境変数未整備** - JoinIR経路選択の統一的な環境変数なし - Phase 122で `NYASH_HAKO_CHECK_JOINIR=1` 追加予定 ### Phase 122-124 統合計画 **3段階移行戦略**: - **Phase 122**: 環境変数で選択可能(デフォルト旧経路) - **Phase 123**: JoinIR デフォルト化(旧経路は NYASH_LEGACY_PHI=1) - **Phase 124**: 旧経路完全削除(JoinIR のみ) **タイムライン**: 3日で hako_check JoinIR 統合完了見込み ### Phase 122 への指針 **最優先課題**: 1. If文の JoinIR 統合 (src/mir/builder/if_form.rs) 2. Loop の JoinIR 統合拡張 (Mainline Targets 制限解除) 3. 環境変数 NYASH_HAKO_CHECK_JOINIR=1 の追加 **実装ステップ** (Phase 122): - Step 1: 環境変数読み込み (30分) - Step 2: If文の JoinIR 統合 (2-3時間) - Step 3: Loop の JoinIR 統合拡張 (1-2時間) - Step 4: テスト追加 (1-2時間) - Step 5: ドキュメント更新 (30分) ### ファイル構成 **新規作成**: - docs/development/current/main/phase121_hako_check_joinir_design.md (指示書) - docs/development/current/main/hako_check_design.md (設計) - docs/development/current/main/phase121_hako_check_investigation.md (調査) - docs/development/current/main/phase121_legacy_path_analysis.md (旧経路特定) - docs/development/current/main/phase121_integration_roadmap.md (統合計画) **修正**: - CURRENT_TASK.md (Phase 121完了記録追加) ### 技術的成果 - Phase 120: selfhost経路のベースライン確立 - Phase 121: hako_check統合計画の設計 ← Complete - Phase 122+: 段階的実装(予定) 設計First原則の実践により、実装前に明確な指針を確立しました。 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 04:42:32 +09:00
# Phase 121: hako_check JoinIR 統合ロードマップ
## Phase 122: 環境変数で JoinIR 選択可能に
### 目標
hako_check で `NYASH_HAKO_CHECK_JOINIR=1` を指定すると、JoinIR 経路を使用するようにする。
デフォルトは旧経路を維持(互換性重視)。
### 実装ステップ
#### Step 1: 環境変数読み込み機能追加
**ファイル**: `src/config/env.rs`
**実装内容**:
```rust
/// hako_check で JoinIR 経路を有効化するフラグ
pub fn hako_check_joinir_enabled() -> bool {
env_flag("NYASH_HAKO_CHECK_JOINIR").unwrap_or(false)
}
```
**チェックリスト**:
- [ ] `src/config/env.rs``hako_check_joinir_enabled()` 関数追加
- [ ] 既存の `joinir_core_enabled()` との関係を整理
- [ ] ドキュメント更新(環境変数リスト)
#### Step 2: If 文の JoinIR 統合
**ファイル**: `src/mir/builder/if_form.rs`
**実装内容**:
```rust
// Phase 122: 環境変数で JoinIR 経路を選択可能に
pub fn cf_if(
&mut self,
condition: &ASTNode,
then_block: &ASTNode,
else_block: Option<&ASTNode>,
) -> Result<ValueId, String> {
// Phase 122: 環境変数チェック
if crate::config::env::hako_check_joinir_enabled() {
// JoinIR If Lowering を使用
return self.cf_if_joinir(condition, then_block, else_block);
}
// 旧 PHI 生成器(互換性維持)
self.cf_if_legacy(condition, then_block, else_block)
}
/// Phase 122: JoinIR If Lowering 経由
fn cf_if_joinir(
&mut self,
condition: &ASTNode,
then_block: &ASTNode,
else_block: Option<&ASTNode>,
) -> Result<ValueId, String> {
use crate::mir::join_ir::lowering::if_select::lower_if_to_mir;
lower_if_to_mir(self, condition, then_block, else_block)
}
/// 既存ロジックを cf_if_legacy に移動
fn cf_if_legacy(
&mut self,
condition: &ASTNode,
then_block: &ASTNode,
else_block: Option<&ASTNode>,
) -> Result<ValueId, String> {
// 既存の cf_if() ロジックをここに移動
// ...
}
```
**チェックリスト**:
- [ ] `cf_if_joinir()` 関数を追加JoinIR Lowering 呼び出し)
- [ ] `cf_if()` に環境変数チェックを追加
- [ ] 既存ロジックを `cf_if_legacy()` に移動
- [ ] JoinIR If Lowering`if_select.rs`)との連携確認
#### Step 3: Loop の JoinIR 統合拡張
**ファイル**: `src/mir/builder/control_flow.rs`
**実装内容**:
```rust
// Phase 122: 環境変数で全 Loop を JoinIR 経由に
pub fn cf_loop(
&mut self,
condition: &ASTNode,
body: &ASTNode,
) -> Result<ValueId, String> {
// Phase 122: hako_check 環境変数チェック
if crate::config::env::hako_check_joinir_enabled() {
// すべての Loop を JoinIR 経由に
if let Some(result) = self.try_cf_loop_joinir_all(&condition, &body)? {
return Ok(result);
}
// JoinIR 失敗時はエラー(フォールバック禁止)
return Err("JoinIR Loop Lowering failed (NYASH_HAKO_CHECK_JOINIR=1)".to_string());
}
// Phase 49: Mainline Targets のみ JoinIR 経由(既存ロジック)
if let Some(result) = self.try_cf_loop_joinir(&condition, &body)? {
return Ok(result);
}
// Fallback: 旧 LoopBuilder
self.cf_loop_legacy(condition, body)
}
/// Phase 122: すべての Loop を JoinIR 経由に
fn try_cf_loop_joinir_all(
&mut self,
condition: &ASTNode,
body: &ASTNode,
) -> Result<Option<ValueId>, String> {
// Mainline Targets 制限を削除
let debug = std::env::var("NYASH_JOINIR_MAINLINE_DEBUG").is_ok();
let func_name = self.current_function_name();
if debug {
eprintln!(
"[cf_loop/joinir/all] Routing {} through JoinIR Frontend (all loops)",
func_name
);
}
self.cf_loop_joinir_impl(condition, body, &func_name, debug)
}
```
**チェックリスト**:
- [ ] `try_cf_loop_joinir_all()` 関数を追加Mainline 制限なし)
- [ ] `cf_loop()` に環境変数チェックを追加
- [ ] フォールバック禁止ロジックを実装
- [ ] JoinIR Loop Lowering との連携確認
#### Step 4: テスト追加
**スモークテスト**: `tools/smokes/v2/profiles/quick/analyze/hako_check_joinir_smoke.sh`
**実装内容**:
```bash
#!/usr/bin/env bash
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/../../../../.." && pwd)"
# Phase 122: hako_check JoinIR 経路スモークテスト
echo "=== hako_check JoinIR Smoke Test ==="
# Test 1: If 文JoinIR 経由)
echo "Test 1: If statement with JoinIR"
cat > /tmp/hako_check_if_test.hako <<'EOF'
static box Main {
method main(args) {
local x = 1
if x == 1 {
print("then")
} else {
print("else")
}
return 0
}
}
EOF
NYASH_HAKO_CHECK_JOINIR=1 "$ROOT/tools/hako_check.sh" /tmp/hako_check_if_test.hako
echo "✅ If statement test passed"
# Test 2: LoopJoinIR 経由)
echo "Test 2: Loop with JoinIR"
cat > /tmp/hako_check_loop_test.hako <<'EOF'
static box Main {
method main(args) {
local i = 0
loop (i < 3) {
print(i)
i = i + 1
}
return 0
}
}
EOF
NYASH_HAKO_CHECK_JOINIR=1 "$ROOT/tools/hako_check.sh" /tmp/hako_check_loop_test.hako
echo "✅ Loop test passed"
# Test 3: 互換性(旧経路)
echo "Test 3: Legacy path compatibility"
"$ROOT/tools/hako_check.sh" /tmp/hako_check_if_test.hako
echo "✅ Legacy path test passed"
echo "=== All tests passed ==="
```
**チェックリスト**:
- [ ] スモークテストスクリプト作成
- [ ] If 文テスト実装
- [ ] Loop テスト実装
- [ ] 互換性テスト実装(旧経路)
- [ ] CI に統合
#### Step 5: ドキュメント更新
**更新ファイル**:
- `docs/development/current/main/hako_check_design.md`: Phase 122 実装完了を記録
- `docs/reference/env-vars.md`: `NYASH_HAKO_CHECK_JOINIR=1` を追加
- `CLAUDE.md`: Phase 122 完了を記録
**チェックリスト**:
- [ ] 設計ドキュメント更新
- [ ] 環境変数リファレンス更新
- [ ] CLAUDE.md 更新
### 完了条件
- ✅ 環境変数なし: 旧経路で全テスト PASS
-`NYASH_HAKO_CHECK_JOINIR=1`: JoinIR 経路で代表テスト PASS
- ✅ ドキュメント更新完了
### タイムライン(目安)
| タスク | 所要時間 | 担当 |
|-------|---------|-----|
| Step 1: 環境変数読み込み | 30分 | 実装者 |
| Step 2: If 文 JoinIR 統合 | 2-3時間 | 実装者 |
| Step 3: Loop JoinIR 統合拡張 | 1-2時間 | 実装者 |
| Step 4: テスト追加 | 1-2時間 | 実装者 |
| Step 5: ドキュメント更新 | 30分 | 実装者 |
| **合計** | **1日** | - |
---
## Phase 123: JoinIR 経路をデフォルトに
### 目標
hako_check のデフォルトを JoinIR 経路に変更。
旧経路は `NYASH_LEGACY_PHI=1` でのみ使用可能に。
### 実装ステップ
#### Step 1: デフォルト値変更
**ファイル**: `src/config/env.rs`
**実装内容**:
```rust
/// hako_check で JoinIR 経路を有効化するフラグ
/// Phase 123: デフォルトを true に変更
pub fn hako_check_joinir_enabled() -> bool {
// Phase 123: デフォルトを true に変更
// NYASH_LEGACY_PHI=1 で旧経路に戻せる
if env_flag("NYASH_LEGACY_PHI").unwrap_or(false) {
return false;
}
// NYASH_HAKO_CHECK_JOINIR=0 で明示的に無効化
env_flag("NYASH_HAKO_CHECK_JOINIR").unwrap_or(true)
}
```
**チェックリスト**:
- [ ] `hako_check_joinir_enabled()` のデフォルトを `true` に変更
- [ ] `NYASH_LEGACY_PHI=1` サポート追加
- [ ] 環境変数優先順位を整理
#### Step 2: 警告メッセージ追加
**ファイル**: `src/mir/builder/if_form.rs`, `src/mir/builder/control_flow.rs`
**実装内容**:
```rust
// Phase 123: 旧経路使用時に警告
pub fn cf_if(
&mut self,
condition: &ASTNode,
then_block: &ASTNode,
else_block: Option<&ASTNode>,
) -> Result<ValueId, String> {
if crate::config::env::hako_check_joinir_enabled() {
return self.cf_if_joinir(condition, then_block, else_block);
}
// Phase 123: 旧経路使用時に警告
eprintln!(
"[WARN] Using legacy PHI path for If statement. Set NYASH_LEGACY_PHI=0 to use JoinIR path."
);
self.cf_if_legacy(condition, then_block, else_block)
}
```
**チェックリスト**:
- [ ] If 文の旧経路使用時に警告を追加
- [ ] Loop の旧経路使用時に警告を追加
- [ ] 警告メッセージに移行ガイドを含める
#### Step 3: 全テスト PASS 確認
**テスト内容**:
```bash
# JoinIR 経路で全テスト PASSデフォルト
./tools/hako_check.sh apps/
./tools/smokes/v2/run.sh --profile quick --filter "hc*"
# 旧経路で互換性維持確認
NYASH_LEGACY_PHI=1 ./tools/hako_check.sh apps/
NYASH_LEGACY_PHI=1 ./tools/smokes/v2/run.sh --profile quick --filter "hc*"
```
**チェックリスト**:
- [ ] JoinIR 経路で全テスト PASS
- [ ] `NYASH_LEGACY_PHI=1` で旧経路テスト PASS互換性維持
- [ ] 警告メッセージが正しく表示されることを確認
### 完了条件
- ✅ 環境変数なし: JoinIR 経路で全テスト PASS
-`NYASH_LEGACY_PHI=1`: 旧経路で全テスト PASS警告あり
- ✅ ドキュメント更新完了
### タイムライン(目安)
| タスク | 所要時間 | 担当 |
|-------|---------|-----|
| Step 1: デフォルト値変更 | 30分 | 実装者 |
| Step 2: 警告メッセージ追加 | 1時間 | 実装者 |
| Step 3: 全テスト PASS 確認 | 2-3時間 | 実装者 |
| ドキュメント更新 | 30分 | 実装者 |
| **合計** | **1日** | - |
---
## Phase 124: 旧経路完全削除
### 目標
旧 PHI 生成器を完全削除し、JoinIR 経路のみを使用する。
### 実装ステップ
#### Step 1: 旧経路コード削除
**ファイル**: `src/mir/builder/if_form.rs`
**実装内容**:
```rust
// Phase 124: 旧経路削除、JoinIR のみ使用
pub fn cf_if(
&mut self,
condition: &ASTNode,
then_block: &ASTNode,
else_block: Option<&ASTNode>,
) -> Result<ValueId, String> {
// JoinIR If Lowering のみ
self.cf_if_joinir(condition, then_block, else_block)
}
// cf_if_legacy() 削除
```
**ファイル**: `src/mir/builder/control_flow.rs`
**実装内容**:
```rust
// Phase 124: 旧経路削除、JoinIR のみ使用
pub fn cf_loop(
&mut self,
condition: &ASTNode,
body: &ASTNode,
) -> Result<ValueId, String> {
// JoinIR Loop Lowering のみ
if let Some(result) = self.try_cf_loop_joinir_all(&condition, &body)? {
return Ok(result);
}
Err("JoinIR Loop Lowering failed".to_string())
}
// cf_loop_legacy() 削除
// try_cf_loop_joinir() 削除Mainline Targets 制限版)
```
**チェックリスト**:
- [ ] `cf_if_legacy()` 削除(`if_form.rs`
- [ ] `cf_loop_legacy()` 削除(`control_flow.rs`
- [ ] 関連する旧 PHI 生成ヘルパー関数削除
- [ ] フォールバックロジック削除
#### Step 2: 環境変数削除
**ファイル**: `src/config/env.rs`
**実装内容**:
```rust
/// hako_check で JoinIR 経路を有効化するフラグ
/// Phase 124: 常に true環境変数不要
pub fn hako_check_joinir_enabled() -> bool {
true // 常に JoinIR 経路
}
```
**チェックリスト**:
- [ ] `NYASH_LEGACY_PHI=1` サポート削除
- [ ] `NYASH_HAKO_CHECK_JOINIR=1` サポート削除(常に有効)
- [ ] 関連する環境変数チェックコード削除
#### Step 3: ドキュメント更新
**更新ファイル**:
- `docs/development/current/main/hako_check_design.md`: 旧経路に関する記述削除
- `docs/reference/env-vars.md`: 削除された環境変数を記録
- `CLAUDE.md`: Phase 124 完了を記録
- `CURRENT_TASK.md`: Phase 121-124 完了を記録
**チェックリスト**:
- [ ] 設計ドキュメントから旧経路の記述削除
- [ ] 環境変数リファレンス更新
- [ ] CLAUDE.md 更新
- [ ] CURRENT_TASK.md 更新
### 完了条件
- ✅ JoinIR 経路のみで全テスト PASS
- ✅ 旧経路コード完全削除
- ✅ ドキュメント更新完了
### タイムライン(目安)
| タスク | 所要時間 | 担当 |
|-------|---------|-----|
| Step 1: 旧経路コード削除 | 2-3時間 | 実装者 |
| Step 2: 環境変数削除 | 1時間 | 実装者 |
| Step 3: ドキュメント更新 | 1時間 | 実装者 |
| 全テスト PASS 確認 | 1時間 | 実装者 |
| **合計** | **1日** | - |
---
## タイムライン(目安)
| Phase | 実装期間 | 完了条件 |
|-------|---------|---------|
| Phase 122 | 1日 | 環境変数で切り替え可能 |
| Phase 123 | 1日 | JoinIR デフォルト化 |
| Phase 124 | 1日 | 旧経路完全削除 |
**合計**: 3日で hako_check JoinIR 統合完了見込み
---
## リスク管理
### リスク 1: 互換性問題
**内容**: 旧経路に依存しているテストがある
**対策**:
- Phase 122 で環境変数による切り替えを実装
- Phase 123 で段階的にデフォルト変更
- 各 Phase で全テスト PASS を確認
**検出方法**:
```bash
# 旧経路でのテスト
NYASH_LEGACY_PHI=1 cargo test --release
# JoinIR 経路でのテスト
NYASH_HAKO_CHECK_JOINIR=1 cargo test --release
```
### リスク 2: パフォーマンス劣化
**内容**: JoinIR 経路が旧経路より遅い
**対策**:
- Phase 123 でパフォーマンス計測
- 問題があれば Phase 123.5 で最適化
- ベンチマークスクリプト作成
**計測方法**:
```bash
# 旧経路でのベンチマーク
time NYASH_LEGACY_PHI=1 ./tools/hako_check.sh apps/
# JoinIR 経路でのベンチマーク
time NYASH_HAKO_CHECK_JOINIR=1 ./tools/hako_check.sh apps/
```
### リスク 3: 未発見バグ
**内容**: JoinIR 経路に未発見のバグが残っている
**対策**:
- Phase 122 で代表テストを追加
- Phase 123 で全テスト PASS を確認
- Phase 124 で最終確認テスト実施
**検出方法**:
```bash
# 全スモークテスト実行
./tools/smokes/v2/run.sh --profile quick
# 全 hako_check テスト実行
./tools/hako_check.sh apps/
./tools/hako_check.sh tools/
./tools/hako_check.sh local_tests/
```
### リスク 4: JoinIR If Lowering の未成熟
**内容**: JoinIR If Lowering`if_select.rs`)が一部のパターンに対応していない
**対策**:
- Phase 122 でエラーハンドリングを強化
- 未対応パターンを明確に検出してエラー報告
- 必要に応じて JoinIR If Lowering を拡張
**検出方法**:
```bash
# JoinIR Strict モードでテスト
NYASH_JOINIR_STRICT=1 NYASH_HAKO_CHECK_JOINIR=1 ./tools/hako_check.sh apps/
```
---
## まとめ
Phase 121 で設計を確定し、Phase 122-124 で段階的に実装する。
各 Phase で互換性を維持しながら、最終的に JoinIR 統合を完了する。
### 実装優先順位
1. **Phase 122**: 環境変数で JoinIR 選択可能に(最優先)
2. **Phase 123**: JoinIR 経路をデフォルトに(優先度高)
3. **Phase 124**: 旧経路完全削除(クリーンアップ)
### 期待される効果
- **コード削減**: 約 500-600 行削減MirBuilder の約 5-10%
- **保守性向上**: PHI 生成ロジックが JoinIR に統一
- **安定性向上**: 旧 PHI 生成器のバグが根絶
### 次のステップ
Phase 122 の実装を開始する。特に **If 文の JoinIR 統合**が最優先課題。