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>
This commit is contained in:
nyash-codex
2025-12-04 04:42:32 +09:00
parent ebda07b65d
commit bb3dd6c2a4
6 changed files with 2168 additions and 1 deletions

View File

@ -65,7 +65,119 @@ Phase 122+: 実装修正(段階的改善)
### 🚀 次のステップ
**Phase 121**: hako_check JoinIR 統合設計(Phase 120 ベースラインをもとに設計)
**Phase 121**: hako_check JoinIR 統合設計(完了)✅
---
## 🎯 Phase 121: hako_check JoinIR 統合設計(完了)✅ 2025-12-04
### 📋 実装内容
**目的**: hako_check 経路を JoinIR 統合に向けて設計し、Phase 122+ 実装の指針を確立
**スコープ**:
1.**設計ドキュメント作成**: hako_check の役割・構造・JoinIR 統合方針を整理
2.**現状調査**: hako_check 実装の読解、JoinIR 関連の環境変数・フラグ洗い出し
3.**旧 MIR/PHI 経路の特定**: If/Loop の PHI 生成経路を明確化
4.**統合計画**: JoinIR 経路への移行ステップを設計Phase 122-124
### 📄 作成ドキュメント
| ドキュメント | ファイルパス | 内容 |
|-------------|------------|------|
| **設計ドキュメント** | `docs/development/current/main/hako_check_design.md` | hako_check の役割・実装構造・JoinIR 統合設計 |
| **現状調査** | `docs/development/current/main/phase121_hako_check_investigation.md` | エントリーポイント・MIR 生成経路・PHI 生成経路・環境変数の詳細調査 |
| **旧経路分析** | `docs/development/current/main/phase121_legacy_path_analysis.md` | 旧 MIR/PHI 経路の特定・JoinIR 経路との比較 |
| **統合ロードマップ** | `docs/development/current/main/phase121_integration_roadmap.md` | Phase 122-124 の実装計画・タイムライン・リスク管理 |
### 🔍 重要な発見
#### 1. hako_check は .hako スクリプト
**従来の認識**: hako_check は Rust バイナリの一部
**Phase 121 調査結果**: hako_check は `.hako スクリプト`として実装されている
**実装構造**:
```
tools/hako_check.sh (シェルスクリプトラッパー)
tools/hako_check/cli.hako (.hako エントリーポイント)
HakoAnalyzerBox.run() (静的解析メインロジック)
hakorune --backend vm (Rust VM で実行)
MirCompiler::compile() (AST → MIR 変換)
MirBuilder::build_module() (MIR 生成・PHI 生成)
```
**影響**:
- JoinIR 統合は **VM の MirBuilder** に実装する必要がある
- hako_check 専用の実装は不要VM 経路の改善で対応)
#### 2. If 文は旧経路、Loop は部分統合
**If 文** (`src/mir/builder/if_form.rs`):
-**旧 PHI 生成器を使用中**
- Phase 33-10 で JoinIR If Lowering が実装済み(`if_select.rs`だが、MirBuilder への統合は未完
- **Phase 122 最優先課題**
**Loop** (`src/mir/builder/control_flow.rs`):
- ⚠️ **部分統合**Phase 49 Mainline Integration
- Mainline Targetsprint_tokens, filterのみ JoinIR 経由
- その他の Loop は旧 LoopBuilder へフォールバック
- **Phase 122 拡張課題**
#### 3. 環境変数未整備
**Phase 121 調査結果**: hako_check で JoinIR 経路を選択する統一的な環境変数がない
**Phase 122 で追加予定**:
- `NYASH_HAKO_CHECK_JOINIR=1`: hako_check で JoinIR 経路を有効化
- `NYASH_LEGACY_PHI=1`: 旧経路への明示的切り替えPhase 123
### 📊 統合計画サマリ
**3段階移行戦略**:
| Phase | 実装内容 | デフォルト | 環境変数 |
|-------|---------|-----------|---------|
| **Phase 122** | 環境変数で選択可能 | 旧経路 | `NYASH_HAKO_CHECK_JOINIR=1` で JoinIR |
| **Phase 123** | JoinIR デフォルト化 | JoinIR 経路 | `NYASH_LEGACY_PHI=1` で旧経路 |
| **Phase 124** | 旧経路完全削除 | JoinIR のみ | 環境変数削除 |
**タイムライン**(目安):
- Phase 122: 1日If 文 JoinIR 統合・Loop 拡張)
- Phase 123: 1日デフォルト変更・警告追加
- Phase 124: 1日旧経路削除・クリーンアップ
- **合計**: 3日で hako_check JoinIR 統合完了見込み
### 🏆 Phase 121 の価値
**設計 First 原則の実践**:
```
Phase 120: 現状記録selfhost 経路ベースライン)
Phase 121: 設計hako_check 統合計画)← 今ここ
Phase 122+: 実装(段階的統合)
```
**実装前に設計を確定**:
- 旧経路と JoinIR 経路の違いを明確化
- 実装ステップを詳細に計画
- リスク管理を事前に整理
**Phase 122+ への明確な指針**:
- If 文の JoinIR 統合が最優先課題
- Loop の JoinIR 統合拡張Mainline Targets 制限解除)
- 段階的移行による互換性維持
### 🚀 次のステップ
**Phase 122**: hako_check 環境変数で JoinIR 選択可能に(実装開始)
---

View File

@ -0,0 +1,248 @@
# hako_check 設計Phase 121 時点)
## 概要
**hako_check** は .hako ファイルの静的解析・検証を行うツール。
Phase 121 では、この経路を JoinIR 統合に向けて設計する。
## hako_check の役割
### 現在の機能
- **構文チェック**: パーサーエラーの検出
- **型チェック**: 基本的な型の整合性確認
- **MIR 生成**: .hako → MIR への変換(検証用)
- **制御フローチェック**: unreachable code などの検出
- **ルールベース診断**: 19種類の診断ルールHC001-HC031
### hako_check の実装構造Phase 121 調査時点)
**重要**: hako_check は **Rust バイナリではなく .hako スクリプト**として実装されている。
```
tools/hako_check.sh # シェルスクリプトラッパー
tools/hako_check/cli.hako # .hako エントリーポイント
HakoAnalyzerBox.run() # 静的解析メインロジック
HakoAnalysisBuilderBox # IR 生成analysis_consumer.hako
hakorune --backend vm # Rust VM で実行
MirCompiler::compile() # AST → MIR 変換
MirBuilder::build_module() # MIR 生成(ここで PHI 生成)
```
### エントリーポイントの詳細
**ファイル**: `tools/hako_check.sh`
**実行フロー**:
1. `tools/hako_check.sh` がシェルスクリプトとして起動
2. `$BIN` (通常は `./target/release/hakorune`) を使用して `cli.hako` を実行
3. 環境変数で VM バックエンドを指定: `--backend vm`
**重要な環境変数**:
```bash
NYASH_DISABLE_PLUGINS=1 # プラグイン無効化(安定性優先)
NYASH_BOX_FACTORY_POLICY=builtin_first # ビルトイン Box 優先
NYASH_FEATURES=stage3 # Stage-3 パーサー使用
NYASH_ENABLE_USING=1 # using 文有効化
```
### MIR 生成経路
**hako_check での MIR 生成フロー**:
```
1. cli.hako が .hako ファイルを読み込む
2. HakoAnalysisBuilderBox.build_from_source_flags() を呼び出す
3. 内部で HakoParserCoreBox.parse() を使用(.hako パーサー)
4. AST を取得Rust VM 内部で nyash_rust::parser::NyashParser を使用)
5. Rust VM が AST を MirCompiler に渡す
6. MirCompiler::compile_with_source() が AST → MIR 変換
7. MirBuilder::build_module() で MIR 生成
8. If/Loop 文は control_flow.rs で処理
```
### PHI 生成経路Phase 121 時点)
**If 文の PHI 生成**:
- **ファイル**: `src/mir/builder/if_form.rs`
- **関数**: `MirBuilder::cf_if()` → PHI 生成ロジック
- **JoinIR 統合**: ❌ **未実装**(旧 PHI 生成器を使用中)
**Loop の PHI 生成**:
- **ファイル**: `src/mir/builder/control_flow.rs`
- **関数**: `MirBuilder::cf_loop()``try_cf_loop_joinir()`
- **JoinIR 統合**: ⚠️ **部分実装**Phase 49 で mainline 統合開始)
- `HAKO_JOINIR_PRINT_TOKENS_MAIN=1`: 特定関数のみ JoinIR 経由
- `HAKO_JOINIR_ARRAY_FILTER_MAIN=1`: 特定関数のみ JoinIR 経由
- デフォルトは旧 LoopBuilder へフォールバック
### Phase 121 での課題
- **旧 MIR/PHI 経路**: 現在は旧 PHI 生成器を主に使用している
- **JoinIR 統合**: If/Loop の JoinIR Lowering 経由への移行が必要
- **Strict モード**: NYASH_JOINIR_STRICT=1 での動作確認が未実施
## 現在の JoinIR 統合状況
### Loop PHI 生成(部分統合済み)
**Phase 49 Mainline Integration**:
```rust
// src/mir/builder/control_flow.rs
fn try_cf_loop_joinir(&mut self, condition: &ASTNode, body: &ASTNode) -> Result<Option<ValueId>, String> {
let core_on = crate::config::env::joinir_core_enabled();
let mainline_targets = vec!["print_tokens", "filter"];
if core_on && is_mainline_target(&func_name) {
// JoinIR Frontend を試す
return self.cf_loop_joinir_impl(condition, body, &func_name, debug);
}
// フォールバック: 旧 LoopBuilder
Ok(None)
}
```
**特徴**:
- **選択的統合**: 特定関数のみ JoinIR 経由mainline targets
- **フォールバック**: 失敗時は旧 LoopBuilder に戻る
- **環境変数制御**:
- `NYASH_JOINIR_CORE=1`: JoinIR Core 有効化
- `HAKO_JOINIR_PRINT_TOKENS_MAIN=1`: print_tokens/0 を JoinIR 経由
- `HAKO_JOINIR_ARRAY_FILTER_MAIN=1`: ArrayExtBox.filter/2 を JoinIR 経由
### If PHI 生成(未統合)
**Phase 121 調査結果**: If 文の PHI 生成は旧経路を使用中
**ファイル**: `src/mir/builder/if_form.rs`
```rust
// 旧 PHI 生成器Phase 121 時点で現役)
fn cf_if(&mut self, condition: &ASTNode, then_block: &ASTNode, else_block: Option<&ASTNode>) -> Result<ValueId, String> {
// 旧 PHI 生成ロジック
// Phase 33-10 で JoinIR If Lowering が実装されたが、
// MirBuilder 経路ではまだ統合されていない
}
```
## JoinIR 統合設計
### 統合方針
**3段階移行戦略**:
1. **Phase 122**: 環境変数で JoinIR 経路を選択可能に(デフォルトは旧経路)
- `NYASH_HAKO_CHECK_JOINIR=1` で JoinIR 経路を有効化
- 旧経路との互換性維持(フォールバック可能)
2. **Phase 123**: JoinIR 経路をデフォルトに(旧経路は `NYASH_LEGACY_PHI=1` でのみ有効)
- デフォルトで JoinIR 経路を使用
- 旧経路は明示的に有効化した場合のみ使用
3. **Phase 124**: 旧経路完全削除JoinIR のみ)
- 旧 PHI 生成器の完全削除
- `NYASH_LEGACY_PHI=1` 環境変数も削除
### 設計原則
**Baseline First**:
- Phase 120 で確立した selfhost 経路のベースラインを参考に
- hako_check 経路でも同様のベースライン確立が必要
**Fail-Fast**:
- フォールバック処理は原則禁止Phase 123 以降)
- エラーは早期に明示的に失敗させる
**環境変数制御**:
- `NYASH_HAKO_CHECK_JOINIR=1`: hako_check で JoinIR 経路を有効化
- `NYASH_JOINIR_STRICT=1`: フォールバック禁止(厳格モード)
### hako_check 特有の考慮事項
**1. .hako スクリプトとしての実行**:
- hako_check は Rust バイナリではなく .hako スクリプト
- Rust VM 経由で実行されるため、VM の MirBuilder を使用
- JoinIR 統合は **VM の MirBuilder** に実装する必要がある
**2. 診断ルールとの関係**:
- hako_check は 19 種類の診断ルールHC001-HC031を実装
- MIR 生成は診断の前段階IR 生成用)
- JoinIR 統合による診断ルールへの影響は最小限
**3. selfhost 経路との違い**:
- **selfhost**: .hako コンパイラを実行(実行時 PHI 必要)
- **hako_check**: 静的解析のみMIR 生成は検証用)
- PHI 生成の要件は同じだが、実行環境が異なる
## selfhost 経路との違い
| 項目 | selfhost 経路 | hako_check 経路 |
|------|---------------|-----------------|
| **目的** | .hako コンパイラ実行 | .hako 静的解析 |
| **実行** | VM/LLVM で実行 | MIR 生成のみVM で .hako スクリプト実行) |
| **PHI 生成** | 実行時に必要 | 検証用のみ |
| **エラー処理** | 実行時エラー | 静的エラー |
| **環境変数** | `NYASH_USE_NY_COMPILER=1` | `NYASH_DISABLE_PLUGINS=1` |
| **実装形式** | Rust バイナリ | .hako スクリプトVM で実行) |
## Phase 122+ 実装計画
### Phase 122: 環境変数で JoinIR 選択可能に
**実装内容**:
- [ ] `NYASH_HAKO_CHECK_JOINIR=1` 環境変数追加
- [ ] MirBuilder の `cf_if()` / `cf_loop()` で環境変数確認
- [ ] 条件分岐で JoinIR 経路 or 旧経路を選択
**実装箇所**:
- `src/mir/builder/if_form.rs`: If 文の JoinIR 統合
- `src/mir/builder/control_flow.rs`: Loop の JoinIR 統合拡張
**テスト**:
- [ ] 既存テスト全 PASS旧経路
- [ ] JoinIR 経路でのスモークテスト作成
### Phase 123: JoinIR 経路をデフォルトに
**実装内容**:
- [ ] デフォルトを JoinIR 経路に変更
- [ ] `NYASH_LEGACY_PHI=1` で旧経路に戻せるように
**テスト**:
- [ ] JoinIR 経路で全テスト PASS
- [ ] 旧経路でも互換性維持確認
### Phase 124: 旧経路完全削除
**実装内容**:
- [ ] 旧 PHI 生成器削除(`if_form.rs` の旧ロジック削除)
- [ ] `NYASH_LEGACY_PHI=1` 環境変数削除
- [ ] 関連ドキュメント更新
**テスト**:
- [ ] JoinIR 経路のみで全テスト PASS
## まとめ
Phase 121 は設計と調査のみ。実装は Phase 122+ で段階的に実施する。
**重要な発見**:
- hako_check は .hako スクリプトとして実装されている
- JoinIR 統合は VM の MirBuilder に実装する必要がある
- Loop は部分統合済みPhase 49、If は未統合
- 段階的移行戦略により互換性を維持しながら統合可能

View File

@ -0,0 +1,285 @@
# Phase 121: hako_check 現状調査結果
## 実行日時
2025-12-04Phase 120 完了直後)
## 調査項目 1: エントリーポイント
### 1.1 シェルスクリプトエントリー
**ファイル**: `tools/hako_check.sh`
**実装内容**:
```bash
#!/usr/bin/env bash
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
BIN="${NYASH_BIN:-$ROOT/target/release/hakorune}"
# ... 環境変数設定 ...
"$BIN" --backend vm "$ROOT/tools/hako_check/cli.hako" -- --source-file "$f" "$text"
```
**重要な発見**: hako_check は **Rust バイナリではなく .hako スクリプト**として実装されている。
**環境変数**:
- `NYASH_DISABLE_PLUGINS=1`: プラグイン無効化(安定性優先)
- `NYASH_BOX_FACTORY_POLICY=builtin_first`: ビルトイン Box 優先
- `NYASH_DISABLE_NY_COMPILER=1`: Ny コンパイラ無効化
- `HAKO_DISABLE_NY_COMPILER=1`: Hako コンパイラ無効化
- `NYASH_FEATURES=stage3`: Stage-3 パーサー使用
- `NYASH_PARSER_SEAM_TOLERANT=1`: パーサー seam 許容
- `HAKO_PARSER_SEAM_TOLERANT=1`: Hako パーサー seam 許容
- `NYASH_PARSER_ALLOW_SEMICOLON=1`: セミコロン許容
- `NYASH_ENABLE_USING=1`: using 文有効化
- `HAKO_ENABLE_USING=1`: Hako using 文有効化
- `NYASH_USING_AST=1`: AST ベース using 解決
- `NYASH_NY_COMPILER_TIMEOUT_MS`: コンパイラタイムアウト(デフォルト 8000ms
**コマンドライン引数**:
- `--backend vm`: VM バックエンド強制
- `--source-file <path> <text>`: ファイルパスと内容をインライン渡し
- `--format <text|dot|json-lsp>`: 出力フォーマット指定
### 1.2 .hako エントリーポイント
**ファイル**: `tools/hako_check/cli.hako`
**実装内容**:
```hako
static box HakoAnalyzerBox {
run(args) {
// ... 引数解析 ...
// IR 生成
ir = HakoAnalysisBuilderBox.build_from_source_flags(text, p, no_ast_eff)
// 診断ルール実行HC001-HC031
// ...
}
}
static box Main { method main(args) { return HakoAnalyzerBox.run(args) } }
```
**重要なポイント**:
- エントリーポイントは `Main.main()` メソッド
- `HakoAnalyzerBox.run()` で診断ロジックを実行
- IR 生成は `HakoAnalysisBuilderBox.build_from_source_flags()` を使用
## 調査項目 2: MIR 生成経路
### 2.1 IR 生成フロー
**ファイル**: `tools/hako_check/analysis_consumer.hako`
**使用している MirBuilder**: 間接的に使用VM 内部)
**フロー**:
```
HakoAnalysisBuilderBox.build_from_source_flags()
HakoParserCoreBox.parse(text) // .hako パーサーで AST 生成
[Rust VM 内部]
nyash_rust::parser::NyashParser::parse_from_string_with_fuel()
MirCompiler::compile_with_source()
MirBuilder::build_module(ast)
[If/Loop 文の処理]
MirBuilder::cf_if() / MirBuilder::cf_loop()
```
**呼び出し箇所**:
- `tools/hako_check/analysis_consumer.hako:32`: `HakoParserCoreBox.parse(text)`
- `src/runner/modes/common.rs:112`: `NyashParser::parse_from_string_with_fuel()`
- `src/mir/mod.rs:120`: `MirBuilder::build_module(ast)`
### 2.2 JoinIR 統合状況
**✅ 部分的に統合**: Loop の一部関数のみ JoinIR 経由
**調査結果**:
| 構文 | JoinIR 統合状況 | 実装箇所 | 制御方法 |
|------|----------------|---------|---------|
| **Loop** | ⚠️ 部分統合 | `src/mir/builder/control_flow.rs` | `HAKO_JOINIR_*_MAIN=1` |
| **If** | ❌ 未統合 | `src/mir/builder/if_form.rs` | なし |
**Loop の JoinIR 統合詳細**:
```rust
// src/mir/builder/control_flow.rs:L156-L200
fn try_cf_loop_joinir(&mut self, condition: &ASTNode, body: &ASTNode) -> Result<Option<ValueId>, String> {
let core_on = crate::config::env::joinir_core_enabled();
// Mainline targets: print_tokens, filter
if core_on && is_mainline_target(&func_name) {
// JoinIR Frontend を試す
return self.cf_loop_joinir_impl(condition, body, &func_name, debug);
}
// フォールバック: 旧 LoopBuilder
Ok(None)
}
```
**If の現状**:
```rust
// src/mir/builder/if_form.rs
// JoinIR 統合なし、旧 PHI 生成器を使用中
```
## 調査項目 3: PHI 生成経路
### 3.1 If 文の PHI 生成
**ファイル**: `src/mir/builder/if_form.rs`
**使用経路**: ❌ **旧 If Builder**JoinIR 未統合)
**実装**:
```rust
// src/mir/builder/if_form.rs
pub fn cf_if(
&mut self,
condition: &ASTNode,
then_block: &ASTNode,
else_block: Option<&ASTNode>,
) -> Result<ValueId, String> {
// 旧 PHI 生成ロジック
// Phase 33-10 で JoinIR If Lowering が実装されたが、
// MirBuilder 経路ではまだ統合されていない
}
```
**問題点**:
- Phase 33-10 で JoinIR If Lowering が実装済み(`src/mir/join_ir/lowering/if_select.rs`
- しかし MirBuilder の `cf_if()` はまだ旧経路を使用
- hako_check で If 文を含むコードを解析する際、旧 PHI 生成器が使われる
### 3.2 Loop の PHI 生成
**ファイル**: `src/mir/builder/control_flow.rs`
**使用経路**: ⚠️ **部分的に JoinIR Loop Lowering**Phase 49 統合)
**実装**:
```rust
// src/mir/builder/control_flow.rs
pub fn cf_loop(&mut self, condition: &ASTNode, body: &ASTNode) -> Result<ValueId, String> {
// Phase 49/80: Try JoinIR Frontend route for mainline targets
if let Some(result) = self.try_cf_loop_joinir(&condition, &body)? {
return Ok(result);
}
// Fallback: 旧 LoopBuilder
self.cf_loop_legacy(condition, body)
}
```
**Mainline Targets** (JoinIR 経由):
- `JsonTokenizer.print_tokens/0`: `HAKO_JOINIR_PRINT_TOKENS_MAIN=1`
- `ArrayExtBox.filter/2`: `HAKO_JOINIR_ARRAY_FILTER_MAIN=1`
**その他の Loop**: 旧 LoopBuilder へフォールバック
**JoinIR Frontend の実装箇所**:
- `src/mir/join_ir/frontend/mod.rs`: `AstToJoinIrLowerer`
- `src/mir/join_ir/lowering/loop_*.rs`: Loop Lowering 実装
## 調査項目 4: 環境変数・フラグ
### 4.1 検索コマンド
```bash
rg "NYASH_HAKO_CHECK" --type rust
rg "NYASH_JOINIR" --type rust | grep -i "hako_check"
```
### 4.2 発見された環境変数
#### hako_check 専用環境変数
| 環境変数 | 用途 | 設定箇所 |
|---------|-----|---------|
| `NYASH_DISABLE_PLUGINS=1` | プラグイン無効化 | `tools/hako_check.sh` |
| `NYASH_BOX_FACTORY_POLICY=builtin_first` | ビルトイン Box 優先 | `tools/hako_check.sh` |
| `NYASH_DISABLE_NY_COMPILER=1` | Ny コンパイラ無効化 | `tools/hako_check.sh` |
| `HAKO_DISABLE_NY_COMPILER=1` | Hako コンパイラ無効化 | `tools/hako_check.sh` |
| `NYASH_FEATURES=stage3` | Stage-3 パーサー使用 | `tools/hako_check.sh` |
| `NYASH_JSON_ONLY=1` | JSON 出力のみ | `tools/hako_check.sh` |
#### JoinIR 関連環境変数
| 環境変数 | 用途 | 実装箇所 |
|---------|-----|---------|
| `NYASH_JOINIR_STRICT=1` | フォールバック禁止 | `src/config/env.rs` |
| `NYASH_JOINIR_CORE=1` | JoinIR Core 有効化 | `src/config/env.rs` |
| `HAKO_JOINIR_PRINT_TOKENS_MAIN=1` | print_tokens を JoinIR 経由 | `src/mir/builder/control_flow.rs` |
| `HAKO_JOINIR_ARRAY_FILTER_MAIN=1` | ArrayExt.filter を JoinIR 経由 | `src/mir/builder/control_flow.rs` |
| `NYASH_JOINIR_MAINLINE_DEBUG=1` | JoinIR Mainline デバッグログ | `src/mir/builder/control_flow.rs` |
| `NYASH_JOINIR_EXPERIMENT=1` | JoinIR 実験モード | `src/tests/helpers/joinir_env.rs` |
#### hako_check で使用されていない JoinIR 変数
**Phase 121 調査結果**: hako_check は現在 JoinIR 関連環境変数を使用していない。
**理由**:
- hako_check.sh で `NYASH_DISABLE_NY_COMPILER=1` を設定
- JoinIR 統合は VM の MirBuilder に実装されているが、環境変数での制御がない
- Phase 122 で `NYASH_HAKO_CHECK_JOINIR=1` を導入予定
## Phase 122+ への提言
### 優先度高Phase 122 実装必須)
- [ ] **`NYASH_HAKO_CHECK_JOINIR=1` 環境変数追加**: hako_check で JoinIR 経路を有効化
- [ ] **If 文の JoinIR 統合**: `src/mir/builder/if_form.rs``cf_if()` を JoinIR 対応
- [ ] **Loop の JoinIR 統合拡張**: Mainline Targets 以外も JoinIR 経由に
### 優先度中Phase 123 実装推奨)
- [ ] **デフォルト変更**: JoinIR 経路をデフォルトに
- [ ] **`NYASH_LEGACY_PHI=1` 環境変数追加**: 旧経路への明示的切り替え
- [ ] **警告メッセージ追加**: 旧経路使用時に非推奨警告
### 優先度低Phase 124 クリーンアップ)
- [ ] **旧経路削除**: `if_form.rs` / `control_flow.rs` の旧 PHI 生成ロジック削除
- [ ] **環境変数削除**: `NYASH_LEGACY_PHI=1` サポート削除
- [ ] **ドキュメント更新**: 旧経路に関する記述を全削除
## 結論
hako_check 経路の現状は:
### ✅ **良好な点**
1. **安定した実装**: .hako スクリプトとして実装され、VM で安定動作
2. **環境変数制御**: 明確な環境変数で動作を制御
3. **部分統合開始**: Loop の Mainline Targets で JoinIR 統合実績あり
### ❌ **課題**
1. **If 文未統合**: If 文は旧 PHI 生成器を使用中
2. **Loop 部分統合**: Mainline Targets 以外は旧 LoopBuilder にフォールバック
3. **環境変数未整備**: JoinIR 経路を選択する統一的な環境変数がない
### ⚠️ **注意点**
1. **.hako スクリプト**: hako_check は Rust バイナリではないため、VM の MirBuilder に依存
2. **VM 経路のみ**: hako_check は常に `--backend vm` を使用
3. **プラグイン無効**: `NYASH_DISABLE_PLUGINS=1` で安定性優先
### 次のステップ
Phase 122+ で上記課題を段階的に解決する。特に **If 文の JoinIR 統合**が最優先課題。

View File

@ -0,0 +1,605 @@
# Phase 121: hako_check ラインの JoinIR 統合設計
## 0. ゴール
- **hako_check 経路**を JoinIR 経由に統合する設計を確立
- 現状の hako_check 実装を調査し、どこが旧 MIR/PHI 経路を使っているか明確化
- **Phase 122+ での実装**に向けた設計ドキュメントを作成Phase 121 は設計のみ)
---
## 1. スコープと非スコープ
### スコープ(今回やること)
1. **設計ドキュメント作成**: `hako_check_design.md` を作成hako_check の役割・構造・JoinIR 統合方針)
2. **現状調査**: hako_check の実装コードを読み、JoinIR 関連の env/flag 有無を洗い出し
3. **旧 MIR/PHI 経路の特定**: hako_check が使用している PHI 生成器・MIR ビルダーの経路を明確化
4. **統合計画**: JoinIR 経路への移行ステップを設計Phase 122+ 実装の指針)
5. **Phase 120 との関係整理**: selfhost 経路と hako_check 経路の違いを明確化
### 非スコープ(今回はやらない)
- **実装修正**: hako_check の実装変更Phase 122+ に回す)
- **テスト追加**: 新規テストの作成(設計確定後に Phase 122+ で実施)
- **パフォーマンス最適化**: JoinIR 統合による性能改善Phase 123+ で検討)
---
## 2. Task 1: hako_check 設計ドキュメント作成
### 2.1 実装内容
**ファイル**: `docs/development/current/main/hako_check_design.md`(新規)
**記載内容**:
```markdown
# hako_check 設計Phase 121 時点)
## 概要
**hako_check** は .hako ファイルの静的解析・検証を行うツール。
Phase 121 では、この経路を JoinIR 統合に向けて設計する。
## hako_check の役割
### 現在の機能
- **構文チェック**: パーサーエラーの検出
- **型チェック**: 基本的な型の整合性確認
- **MIR 生成**: .hako → MIR への変換(検証用)
- **制御フローチェック**: unreachable code などの検出
### Phase 121 での課題
- **旧 MIR/PHI 経路**: 現在は旧 PHI 生成器を使用している可能性
- **JoinIR 統合**: JoinIR Lowering 経由に移行する必要性
- **Strict モード**: NYASH_JOINIR_STRICT=1 での動作確認
## 現在の実装構造
### エントリーポイント
[調査結果を記載]
### MIR 生成経路
[調査結果を記載]
### PHI 生成経路
[調査結果を記載]
### 環境変数・フラグ
[調査結果を記載]
## JoinIR 統合設計
### 統合方針
**3段階移行戦略**:
1. **Phase 122**: 環境変数で JoinIR 経路を選択可能に(デフォルトは旧経路)
2. **Phase 123**: JoinIR 経路をデフォルトに(旧経路は `NYASH_LEGACY_PHI=1` でのみ有効)
3. **Phase 124**: 旧経路完全削除JoinIR のみ)
### 設計原則
**Baseline First**:
- Phase 120 で確立した selfhost 経路のベースラインを参考に
- hako_check 経路でも同様のベースライン確立が必要
**Fail-Fast**:
- フォールバック処理は原則禁止
- エラーは早期に明示的に失敗させる
**環境変数制御**:
- `NYASH_HAKO_CHECK_JOINIR=1`: hako_check で JoinIR 経路を有効化
- `NYASH_JOINIR_STRICT=1`: フォールバック禁止(厳格モード)
## selfhost 経路との違い
| 項目 | selfhost 経路 | hako_check 経路 |
|------|---------------|-----------------|
| **目的** | .hako コンパイラ実行 | .hako 静的解析 |
| **実行** | VM/LLVM で実行 | MIR 生成のみ |
| **PHI 生成** | 実行時に必要 | 検証用のみ |
| **エラー処理** | 実行時エラー | 静的エラー |
## Phase 122+ 実装計画
### Phase 122: 環境変数で JoinIR 選択可能に
**実装内容**:
- [ ] `NYASH_HAKO_CHECK_JOINIR=1` 環境変数追加
- [ ] hako_check エントリーポイントで環境変数確認
- [ ] 条件分岐で JoinIR 経路 or 旧経路を選択
**テスト**:
- [ ] 既存テスト全 PASS旧経路
- [ ] JoinIR 経路でのスモークテスト作成
### Phase 123: JoinIR 経路をデフォルトに
**実装内容**:
- [ ] デフォルトを JoinIR 経路に変更
- [ ] `NYASH_LEGACY_PHI=1` で旧経路に戻せるように
**テスト**:
- [ ] JoinIR 経路で全テスト PASS
- [ ] 旧経路でも互換性維持確認
### Phase 124: 旧経路完全削除
**実装内容**:
- [ ] 旧 PHI 生成器削除
- [ ] `NYASH_LEGACY_PHI=1` 環境変数削除
- [ ] 関連ドキュメント更新
**テスト**:
- [ ] JoinIR 経路のみで全テスト PASS
## まとめ
Phase 121 は設計と調査のみ。実装は Phase 122+ で段階的に実施する。
```
---
## 3. Task 2: 現状調査hako_check 実装の読解)
### 3.1 調査内容
**調査対象**:
1. **hako_check エントリーポイント**
- ファイル: `src/bin/hako_check.rs` または類似
- 調査項目: コマンドライン引数、環境変数の読み込み、実行フロー
2. **MIR 生成経路**
- ファイル: `src/mir/builder/` 配下
- 調査項目: hako_check が使用している MirBuilder の経路
3. **PHI 生成経路**
- ファイル: `src/mir/loop_builder.rs`, `src/mir/if_builder.rs` など
- 調査項目: 旧 PHI 生成器 vs JoinIR Lowering の使い分け
4. **環境変数・フラグ**
- ファイル: 全コード検索
- 調査項目: `NYASH_*` 環境変数の hako_check 関連のもの
### 3.2 調査記録
**ファイル**: `docs/development/current/main/phase121_hako_check_investigation.md`(新規)
**記載内容**:
```markdown
# Phase 121: hako_check 現状調査結果
## 実行日時
2025-12-04Phase 120 完了直後)
## 調査項目 1: エントリーポイント
**ファイル**: [該当ファイルパス]
**実装内容**:
[コード抜粋]
**環境変数**:
- [環境変数1]: [用途]
- [環境変数2]: [用途]
**コマンドライン引数**:
- [引数1]: [用途]
- [引数2]: [用途]
## 調査項目 2: MIR 生成経路
**ファイル**: [該当ファイルパス]
**使用している MirBuilder**:
- [MirBuilder の種類]
- [呼び出し箇所]
**JoinIR 統合状況**:
- ✅ 既に JoinIR 経由: [詳細]
- ❌ 旧経路を使用: [詳細]
- ⚠️ 部分的に統合: [詳細]
## 調査項目 3: PHI 生成経路
**ファイル**: [該当ファイルパス]
**If 文の PHI 生成**:
- ✅ JoinIR If Lowering: [詳細]
- ❌ 旧 If Builder: [詳細]
**Loop の PHI 生成**:
- ✅ JoinIR Loop Lowering: [詳細]
- ❌ 旧 Loop Builder: [詳細]
## 調査項目 4: 環境変数・フラグ
**検索コマンド**:
```bash
rg "NYASH_HAKO_CHECK" --type rust
rg "NYASH_JOINIR" --type rust | grep -i "hako_check"
```
**発見された環境変数**:
- [環境変数1]: [用途]
- [環境変数2]: [用途]
## Phase 122+ への提言
**優先度高**:
- [ ] [課題1]
- [ ] [課題2]
**優先度中**:
- [ ] [課題3]
- [ ] [課題4]
**優先度低**:
- [ ] [改善案1]
- [ ] [改善案2]
## 結論
hako_check 経路の現状は:
-**JoinIR 統合済み**: [該当箇所]
-**旧経路使用中**: [該当箇所]
- ⚠️ **部分的統合**: [該当箇所]
Phase 122+ で上記課題を段階的に解決する。
```
### 3.3 調査手法
**コマンド例**:
```bash
# hako_check エントリーポイント検索
find src/bin -name "*hako_check*" -o -name "*check*"
rg "fn main" src/bin/ | grep -i "check"
# MirBuilder 呼び出し検索
rg "MirBuilder::new" --type rust
rg "build_mir" --type rust | grep -i "check"
# PHI 生成器検索
rg "do_phi" --type rust
rg "JoinIR" --type rust | grep -E "(if|loop)"
# 環境変数検索
rg "NYASH_HAKO_CHECK" --type rust
rg "env::var.*HAKO.*CHECK" --type rust
```
---
## 4. Task 3: 旧 MIR/PHI 経路の特定
### 4.1 実装内容
**ファイル**: `docs/development/current/main/phase121_legacy_path_analysis.md`(新規)
**記載内容**:
```markdown
# Phase 121: 旧 MIR/PHI 経路の特定
## 旧経路の定義
**旧 MIR/PHI 経路**とは:
- **JoinIR Lowering 前**の PHI 生成器を直接使用している経路
- **Phase 33 以前**の実装If/Loop PHI 生成が直接 MirBuilder に組み込まれていた時期)
## 特定方法
### 1. ファイル名での特定
**旧経路候補**:
- `src/mir/if_builder.rs`: 旧 If PHI 生成器Phase 33-10 で削除済み?)
- `src/mir/loop_builder.rs`: 旧 Loop PHI 生成器Phase 33-10 で削除済み?)
**JoinIR 経路**:
- `src/mir/join_ir/lowering/if_select.rs`: JoinIR If Lowering
- `src/mir/join_ir/lowering/loop_*.rs`: JoinIR Loop Lowering
### 2. 関数名での特定
**旧経路の特徴的関数**:
```rust
// 旧 If PHI 生成器
fn build_if_with_phi(...)
fn merge_phi_for_if(...)
// 旧 Loop PHI 生成器
fn build_loop_with_phi(...)
fn merge_phi_for_loop(...)
```
**JoinIR 経路の関数**:
```rust
// JoinIR If Lowering
fn lower_if_to_mir(...)
fn if_select_lowering(...)
// JoinIR Loop Lowering
fn lower_loop_to_mir(...)
fn loop_lowering(...)
```
### 3. 環境変数での特定
**旧経路のフラグ**:
- `NYASH_LEGACY_PHI=1`: 旧 PHI 生成器を強制使用
**JoinIR 経路のフラグ**:
- `NYASH_JOINIR_STRICT=1`: JoinIR Lowering のみ使用(フォールバック禁止)
## hako_check での使用状況
[Task 2 の調査結果に基づいて記載]
### If 文の PHI 生成
**使用経路**: [旧経路 / JoinIR 経路 / 混在]
**根拠**: [コード抜粋・ファイル名・関数名]
### Loop の PHI 生成
**使用経路**: [旧経路 / JoinIR 経路 / 混在]
**根拠**: [コード抜粋・ファイル名・関数名]
## Phase 122+ での移行計画
**移行必要箇所**:
- [ ] [箇所1]: [詳細]
- [ ] [箇所2]: [詳細]
**既に JoinIR 統合済み**:
- ✅ [箇所1]: [詳細]
- ✅ [箇所2]: [詳細]
## まとめ
hako_check 経路の旧 MIR/PHI 使用状況:
- **旧経路使用中**: [件数]箇所
- **JoinIR 統合済み**: [件数]箇所
- **混在**: [件数]箇所
Phase 122+ で段階的に JoinIR 統合を完了する。
```
---
## 5. Task 4: 統合計画とドキュメント更新
### 5.1 統合計画の具体化
**ファイル**: `docs/development/current/main/phase121_integration_roadmap.md`(新規)
**記載内容**:
```markdown
# Phase 121: hako_check JoinIR 統合ロードマップ
## Phase 122: 環境変数で JoinIR 選択可能に
### 目標
hako_check で `NYASH_HAKO_CHECK_JOINIR=1` を指定すると、JoinIR 経路を使用するようにする。
デフォルトは旧経路を維持(互換性重視)。
### 実装ステップ
**Step 1**: 環境変数読み込み機能追加
- [ ] `src/bin/hako_check.rs` に環境変数読み込みコード追加
- [ ] `HakoCheckConfig` struct に `use_joinir: bool` フィールド追加
**Step 2**: 条件分岐の実装
- [ ] MIR 生成時に `use_joinir` を確認
- [ ] `if use_joinir { ... } else { ... }` で経路切り替え
**Step 3**: テスト追加
- [ ] 旧経路テスト: `cargo test --release hako_check_legacy`
- [ ] JoinIR 経路テスト: `NYASH_HAKO_CHECK_JOINIR=1 cargo test --release hako_check_joinir`
### 完了条件
- ✅ 環境変数なし: 旧経路で全テスト PASS
- ✅ `NYASH_HAKO_CHECK_JOINIR=1`: JoinIR 経路で代表テスト PASS
- ✅ ドキュメント更新完了
---
## Phase 123: JoinIR 経路をデフォルトに
### 目標
hako_check のデフォルトを JoinIR 経路に変更。
旧経路は `NYASH_LEGACY_PHI=1` でのみ使用可能に。
### 実装ステップ
**Step 1**: デフォルト値変更
- [ ] `HakoCheckConfig` の `use_joinir` を `true` に変更
- [ ] 環境変数 `NYASH_LEGACY_PHI=1` で旧経路に戻せるように
**Step 2**: 警告メッセージ追加
- [ ] 旧経路使用時に「非推奨」警告を表示
- [ ] JoinIR 経路への移行を促すメッセージ
**Step 3**: 全テスト PASS 確認
- [ ] JoinIR 経路で全テスト PASS
- [ ] `NYASH_LEGACY_PHI=1` で旧経路テスト PASS互換性維持
### 完了条件
- ✅ 環境変数なし: JoinIR 経路で全テスト PASS
- ✅ `NYASH_LEGACY_PHI=1`: 旧経路で全テスト PASS警告あり
- ✅ ドキュメント更新完了
---
## Phase 124: 旧経路完全削除
### 目標
旧 PHI 生成器を完全削除し、JoinIR 経路のみを使用する。
### 実装ステップ
**Step 1**: 旧経路コード削除
- [ ] `src/mir/if_builder.rs` 削除(または旧 PHI 生成部分削除)
- [ ] `src/mir/loop_builder.rs` 削除(または旧 PHI 生成部分削除)
- [ ] 関連する旧経路のヘルパー関数削除
**Step 2**: 環境変数削除
- [ ] `NYASH_LEGACY_PHI=1` サポート削除
- [ ] `NYASH_HAKO_CHECK_JOINIR=1` サポート削除(常に有効)
**Step 3**: ドキュメント更新
- [ ] 旧経路に関する記述を全削除
- [ ] JoinIR 統合完了を明記
### 完了条件
- ✅ JoinIR 経路のみで全テスト PASS
- ✅ 旧経路コード完全削除
- ✅ ドキュメント更新完了
---
## タイムライン(目安)
| Phase | 実装期間 | 完了条件 |
|-------|---------|---------|
| Phase 122 | 1-2日 | 環境変数で切り替え可能 |
| Phase 123 | 1-2日 | JoinIR デフォルト化 |
| Phase 124 | 1日 | 旧経路完全削除 |
**合計**: 3-5日で hako_check JoinIR 統合完了見込み
---
## リスク管理
### リスク 1: 互換性問題
**内容**: 旧経路に依存しているテストがある
**対策**:
- Phase 122 で環境変数による切り替えを実装
- Phase 123 で段階的にデフォルト変更
### リスク 2: パフォーマンス劣化
**内容**: JoinIR 経路が旧経路より遅い
**対策**:
- Phase 123 でパフォーマンス計測
- 問題があれば Phase 123.5 で最適化
### リスク 3: 未発見バグ
**内容**: JoinIR 経路に未発見のバグが残っている
**対策**:
- Phase 122 で代表テストを追加
- Phase 123 で全テスト PASS を確認
---
## まとめ
Phase 121 で設計を確定し、Phase 122-124 で段階的に実装する。
各 Phase で互換性を維持しながら、最終的に JoinIR 統合を完了する。
```
### 5.2 CURRENT_TASK.md 更新
**ファイル**: `CURRENT_TASK.md`(修正)
**Phase 121 セクション追加**:
```markdown
### 🎯 Phase 121: hako_check JoinIR 統合設計(完了)
- ✅ 設計ドキュメント作成: hako_check_design.md
- ✅ 現状調査完了: phase121_hako_check_investigation.md
- ✅ 旧 MIR/PHI 経路特定: phase121_legacy_path_analysis.md
- ✅ 統合計画策定: phase121_integration_roadmap.md
- ✅ Phase 120 との関係整理完了
**次のステップ**: Phase 122hako_check 環境変数で JoinIR 選択可能に)
```
---
## 6. 完成チェックリストPhase 121
- [ ] hako_check_design.md 作成(設計ドキュメント)
- [ ] phase121_hako_check_investigation.md 作成(現状調査)
- [ ] phase121_legacy_path_analysis.md 作成(旧経路特定)
- [ ] phase121_integration_roadmap.md 作成(統合計画)
- [ ] hako_check エントリーポイント調査完了
- [ ] MIR 生成経路調査完了
- [ ] PHI 生成経路調査完了
- [ ] 環境変数・フラグ調査完了
- [ ] Phase 122-124 の実装計画確定
- [ ] CURRENT_TASK.md 更新Phase 121 完了記録)
---
## 7. 設計原則Phase 121 で確立)
### 設計 First
```
【Phase 121 の哲学】
実装の前に、「どう作るか」を明確にする
Flow:
Phase 120: 現状記録selfhost 経路ベースライン)
Phase 121: 設計hako_check 統合計画) ← Complete
Phase 122+: 実装(段階的統合)
```
### 段階的統合の重要性
**3段階移行戦略の利点**:
- **Phase 122**: 環境変数で選択可能(リスク最小)
- **Phase 123**: デフォルト変更(互換性維持)
- **Phase 124**: 旧経路削除(完全統合)
**失敗しない移行のコツ**:
- **各 Phase で全テスト PASS**: 段階的に確認
- **環境変数での切り替え**: いつでも戻れる
- **警告メッセージ**: ユーザーに移行を促す
### Phase 120 との連携
**Phase 120 の成果を活用**:
- **ベースライン確立の手法**: hako_check でも同様の手法を使用
- **JoinIR Strict モード**: hako_check でも適用
- **スモークテスト**: hako_check 版を作成
---
**Phase 121 指示書完成日**: 2025-12-04Phase 120 完了直後)

View File

@ -0,0 +1,548 @@
# 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 統合**が最優先課題。

View File

@ -0,0 +1,369 @@
# Phase 121: 旧 MIR/PHI 経路の特定
## 旧経路の定義
**旧 MIR/PHI 経路**とは:
- **JoinIR Lowering 前**の PHI 生成器を直接使用している経路
- **Phase 33 以前**の実装If/Loop PHI 生成が直接 MirBuilder に組み込まれていた時期)
- Phase 33-10 で JoinIR If/Loop Lowering が実装されたが、MirBuilder への統合は未完
## 特定方法
### 1. ファイル名での特定
#### 旧経路候補
| ファイル | 状態 | 用途 |
|---------|------|------|
| `src/mir/builder/if_form.rs` | ✅ **現役** | 旧 If PHI 生成器JoinIR 未統合) |
| `src/mir/builder/control_flow.rs` | ⚠️ **部分統合** | Loop PHI 生成器Mainline のみ JoinIR |
| `src/mir/loop_builder.rs` | ❓ **調査中** | 旧 Loop PHI 生成器Phase 33-10 で削除済み?) |
#### JoinIR 経路
| ファイル | 状態 | 用途 |
|---------|------|------|
| `src/mir/join_ir/lowering/if_select.rs` | ✅ **実装済み** | JoinIR If Lowering |
| `src/mir/join_ir/lowering/loop_*.rs` | ✅ **実装済み** | JoinIR Loop Lowering |
| `src/mir/join_ir/frontend/mod.rs` | ✅ **実装済み** | AST → JoinIR 変換 |
### 2. 関数名での特定
#### 旧経路の特徴的関数
**If 文**`src/mir/builder/if_form.rs`:
```rust
// 旧 If PHI 生成器Phase 121 時点で現役)
pub fn cf_if(
&mut self,
condition: &ASTNode,
then_block: &ASTNode,
else_block: Option<&ASTNode>,
) -> Result<ValueId, String> {
// 旧 PHI 生成ロジック
// - BasicBlock 直接操作
// - PHI 命令を手動で挿入
// - JoinIR Lowering を経由しない
}
```
**特徴**:
- `BasicBlock::phi()` を直接呼び出し
- `merge_phi_for_if()` 等のヘルパー関数使用
- JoinIR Lowering を経由しない
**Loop**`src/mir/builder/control_flow.rs`:
```rust
// Phase 49: 部分的に JoinIR 統合済み
pub fn cf_loop(
&mut self,
condition: &ASTNode,
body: &ASTNode,
) -> Result<ValueId, String> {
// Phase 49/80: Try JoinIR Frontend route for mainline targets
if let Some(result) = self.try_cf_loop_joinir(&condition, &body)? {
return Ok(result);
}
// Fallback: 旧 LoopBuilder
self.cf_loop_legacy(condition, body)
}
```
**特徴**:
- `try_cf_loop_joinir()` で JoinIR 経由を試みる
- 失敗時は `cf_loop_legacy()` へフォールバック
- Mainline Targets のみ JoinIR 経由
#### JoinIR 経路の関数
**If Lowering**`src/mir/join_ir/lowering/if_select.rs`:
```rust
// JoinIR If LoweringPhase 33-10 実装済み)
pub fn lower_if_to_mir(...) -> Result<ValueId, String> {
// JoinIR ベースの If Lowering
// - IfMerge/IfSelect 命令を生成
// - PHI 命令を自動生成
}
```
**Loop Lowering**`src/mir/join_ir/lowering/loop_*.rs`:
```rust
// JoinIR Loop LoweringPhase 33 実装済み)
pub fn lower_loop_to_mir(...) -> Result<ValueId, String> {
// JoinIR ベースの Loop Lowering
// - LoopForm を使用
// - PHI 命令を自動生成
}
```
### 3. 環境変数での特定
#### 旧経路のフラグ
**Phase 121 調査結果**: 明示的な旧経路フラグは**存在しない**
**理由**:
- 旧経路がデフォルトのため、フラグで有効化する必要がない
- Phase 122 で `NYASH_LEGACY_PHI=1` を導入予定
#### JoinIR 経路のフラグ
| 環境変数 | 用途 | 実装箇所 |
|---------|-----|---------|
| `NYASH_JOINIR_STRICT=1` | フォールバック禁止(厳格モード) | `src/config/env.rs` |
| `NYASH_JOINIR_CORE=1` | JoinIR Core 有効化 | `src/config/env.rs` |
| `HAKO_JOINIR_PRINT_TOKENS_MAIN=1` | print_tokens を JoinIR 経由 | `src/mir/builder/control_flow.rs` |
| `HAKO_JOINIR_ARRAY_FILTER_MAIN=1` | ArrayExt.filter を JoinIR 経由 | `src/mir/builder/control_flow.rs` |
## hako_check での使用状況
### If 文の PHI 生成
**使用経路**: ❌ **旧経路**`src/mir/builder/if_form.rs`
**根拠**:
1. **ファイル**: `src/mir/builder/if_form.rs` が現役
2. **関数**: `cf_if()` が JoinIR Lowering を呼び出していない
3. **コード抜粋**:
```rust
// src/mir/builder/if_form.rs:L1-L50
pub fn cf_if(
&mut self,
condition: &ASTNode,
then_block: &ASTNode,
else_block: Option<&ASTNode>,
) -> Result<ValueId, String> {
// 旧 PHI 生成ロジックJoinIR Lowering 未使用)
// ...
}
```
**問題点**:
- Phase 33-10 で JoinIR If Lowering が実装済み(`if_select.rs`
- しかし MirBuilder の `cf_if()` はまだ JoinIR を呼び出していない
- hako_check で If 文を含むコードを解析する際、旧 PHI 生成器が使われる
### Loop の PHI 生成
**使用経路**: ⚠️ **混在**Mainline Targets のみ JoinIR 経由)
**根拠**:
1. **ファイル**: `src/mir/builder/control_flow.rs`
2. **関数**: `cf_loop()``try_cf_loop_joinir()`
3. **コード抜粋**:
```rust
// src/mir/builder/control_flow.rs:L150-L200
pub fn cf_loop(
&mut self,
condition: &ASTNode,
body: &ASTNode,
) -> Result<ValueId, String> {
// Phase 49/80: Try JoinIR Frontend route for mainline targets
if let Some(result) = self.try_cf_loop_joinir(&condition, &body)? {
return Ok(result);
}
// Fallback: 旧 LoopBuilder
self.cf_loop_legacy(condition, body)
}
```
**Mainline Targets** (JoinIR 経由):
- `JsonTokenizer.print_tokens/0`
- `ArrayExtBox.filter/2`
**その他の Loop** (旧経路):
- 上記以外のすべての Loop 文
## Phase 122+ での移行計画
### 移行必要箇所
#### 1. If 文の JoinIR 統合(最優先)
**ファイル**: `src/mir/builder/if_form.rs`
**現状**: ❌ 旧 PHI 生成器を使用中
**移行方法**:
```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::env_bool("NYASH_HAKO_CHECK_JOINIR") {
// JoinIR If Lowering を使用
return self.cf_if_joinir(condition, then_block, else_block);
}
// 旧 PHI 生成器(互換性維持)
self.cf_if_legacy(condition, then_block, else_block)
}
fn cf_if_joinir(
&mut self,
condition: &ASTNode,
then_block: &ASTNode,
else_block: Option<&ASTNode>,
) -> Result<ValueId, String> {
// JoinIR If Lowering を呼び出す
use crate::mir::join_ir::lowering::if_select::lower_if_to_mir;
lower_if_to_mir(self, condition, then_block, else_block)
}
```
**実装ステップ**:
1. [ ] `cf_if_joinir()` 関数を追加JoinIR Lowering 呼び出し)
2. [ ] `cf_if()` に環境変数チェックを追加
3. [ ] 既存ロジックを `cf_if_legacy()` に移動
#### 2. Loop の JoinIR 統合拡張(優先度中)
**ファイル**: `src/mir/builder/control_flow.rs`
**現状**: ⚠️ Mainline Targets のみ JoinIR 経由
**移行方法**:
```rust
// Phase 122: すべての Loop を JoinIR 経由に
pub fn cf_loop(
&mut self,
condition: &ASTNode,
body: &ASTNode,
) -> Result<ValueId, String> {
// Phase 122: 環境変数チェック
if crate::config::env::env_bool("NYASH_HAKO_CHECK_JOINIR") {
// すべての Loop を JoinIR 経由に
if let Some(result) = self.try_cf_loop_joinir(&condition, &body)? {
return Ok(result);
}
}
// 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)
}
```
**実装ステップ**:
1. [ ] `try_cf_loop_joinir()` の Mainline Targets 制限を削除
2. [ ] 環境変数で制御するように変更
3. [ ] フォールバックロジックを整理
### 既に JoinIR 統合済み
#### 1. Loop Mainline TargetsPhase 49
**ファイル**: `src/mir/builder/control_flow.rs`
**詳細**:
-`JsonTokenizer.print_tokens/0`: JoinIR 経由で動作確認済み
-`ArrayExtBox.filter/2`: JoinIR 経由で動作確認済み
**実装**:
```rust
// Phase 49: Mainline Integration
fn try_cf_loop_joinir(&mut self, condition: &ASTNode, body: &ASTNode) -> Result<Option<ValueId>, String> {
let core_on = crate::config::env::joinir_core_enabled();
// Mainline targets
let mainline_targets = vec!["print_tokens", "filter"];
if core_on && is_mainline_target(&func_name) {
// JoinIR Frontend を使用
return self.cf_loop_joinir_impl(condition, body, &func_name, debug);
}
Ok(None)
}
```
#### 2. JoinIR FrontendPhase 49
**ファイル**: `src/mir/join_ir/frontend/mod.rs`
**詳細**:
-`AstToJoinIrLowerer`: AST → JoinIR 変換
- ✅ JSON v0 → JoinIR 変換
- ✅ JoinModule 生成
## 旧経路と JoinIR 経路の比較
### If 文
| 項目 | 旧経路 | JoinIR 経路 |
|------|--------|------------|
| **ファイル** | `src/mir/builder/if_form.rs` | `src/mir/join_ir/lowering/if_select.rs` |
| **関数** | `cf_if()` | `lower_if_to_mir()` |
| **PHI 生成** | 手動BasicBlock::phi() | 自動IfMerge/IfSelect |
| **統合状況** | ❌ 現役使用中 | ✅ 実装済み(未統合) |
| **環境変数** | なし | `NYASH_HAKO_CHECK_JOINIR=1`Phase 122 |
### Loop
| 項目 | 旧経路 | JoinIR 経路 |
|------|--------|------------|
| **ファイル** | `src/mir/builder/control_flow.rs` | `src/mir/join_ir/frontend/mod.rs` |
| **関数** | `cf_loop_legacy()` | `cf_loop_joinir_impl()` |
| **PHI 生成** | 手動LoopBuilder | 自動LoopForm |
| **統合状況** | ⚠️ フォールバック経路 | ⚠️ Mainline Targets のみ |
| **環境変数** | なし | `HAKO_JOINIR_*_MAIN=1` |
## コード削減見込み
### Phase 122 完了後
**削減箇所**:
- `src/mir/builder/if_form.rs`: 旧 PHI 生成ロジック削除可能Phase 124
- `src/mir/builder/control_flow.rs`: `cf_loop_legacy()` 削除可能Phase 124
**削減見込み**:
- `if_form.rs`: 約 200-300 行削減
- `control_flow.rs`: 約 100-150 行削減
- **合計**: 約 300-450 行削減
### Phase 124 完了後(旧経路完全削除)
**削減箇所**:
- 旧 PHI 生成ヘルパー関数削除
- フォールバックロジック削除
- 環境変数制御コード削除
**削減見込み**:
- **合計**: 約 500-600 行削減MirBuilder 全体の約 5-10%
## まとめ
hako_check 経路の旧 MIR/PHI 使用状況:
### ❌ **旧経路使用中**: 1箇所
1. **If 文の PHI 生成**`src/mir/builder/if_form.rs`
- ファイル: `if_form.rs`
- 関数: `cf_if()`
- 根拠: JoinIR Lowering を呼び出していない
### ⚠️ **部分的統合**: 1箇所
1. **Loop の PHI 生成**`src/mir/builder/control_flow.rs`
- ファイル: `control_flow.rs`
- 関数: `cf_loop()``try_cf_loop_joinir()`
- 根拠: Mainline Targets のみ JoinIR 経由、その他はフォールバック
### ✅ **JoinIR 統合済み**: 0箇所完全統合は未完
**Phase 122+ で段階的に JoinIR 統合を完了する。**
**最優先課題**: **If 文の JoinIR 統合**`src/mir/builder/if_form.rs`