232 lines
8.1 KiB
Markdown
232 lines
8.1 KiB
Markdown
|
|
# Phase 231: ExprLowerer パイロット実装(Pattern2 条件式限定)
|
|||
|
|
|
|||
|
|
## 概要
|
|||
|
|
|
|||
|
|
Phase 231 は、Phase 230 で設計した ExprLowerer / ScopeManager アーキテクチャの実現可能性を検証するパイロット実装。
|
|||
|
|
Pattern2 の break 条件式に限定し、新しい変数解決システムが既存コードに素直に統合できることを確認した。
|
|||
|
|
|
|||
|
|
## 実装内容
|
|||
|
|
|
|||
|
|
### 1. ScopeManager trait(変数解決の統一インターフェース)
|
|||
|
|
|
|||
|
|
**ファイル**: `src/mir/join_ir/lowering/scope_manager.rs`
|
|||
|
|
|
|||
|
|
**責務**:
|
|||
|
|
- 変数参照を統一的に扱う trait
|
|||
|
|
- ConditionEnv / LoopBodyLocalEnv / CapturedEnv / CarrierInfo を統合
|
|||
|
|
- 変数のスコープ種別(LoopVar / Carrier / LoopBodyLocal / Captured)を判定
|
|||
|
|
|
|||
|
|
**設計原則**:
|
|||
|
|
- **Box-First**: trait-based "box" で変数解決を抽象化
|
|||
|
|
- **Single Responsibility**: 変数解決のみ担当(AST lowering や ValueId 割り当ては別箱)
|
|||
|
|
- **Testable**: 独立してテスト可能
|
|||
|
|
|
|||
|
|
### 2. Pattern2ScopeManager(Pattern2 専用実装)
|
|||
|
|
|
|||
|
|
**ファイル**: `src/mir/join_ir/lowering/scope_manager.rs`
|
|||
|
|
|
|||
|
|
**責務**:
|
|||
|
|
- Pattern2 のすべての環境を統合(ConditionEnv, LoopBodyLocalEnv, CapturedEnv, CarrierInfo)
|
|||
|
|
- promoted_loopbodylocals の名前解決(`digit_pos` → `is_digit_pos` 変換)
|
|||
|
|
|
|||
|
|
**Lookup 順序**:
|
|||
|
|
1. ConditionEnv(ループ変数、キャリア、条件専用変数)
|
|||
|
|
2. LoopBodyLocalEnv(ボディローカル変数)
|
|||
|
|
3. CapturedEnv(キャプチャされた外部変数)
|
|||
|
|
4. Promoted LoopBodyLocal(昇格された変数の名前変換)
|
|||
|
|
|
|||
|
|
### 3. ExprLowerer(式 lowering の統一 API)
|
|||
|
|
|
|||
|
|
**ファイル**: `src/mir/join_ir/lowering/expr_lowerer.rs`
|
|||
|
|
|
|||
|
|
**責務**:
|
|||
|
|
- AST 式を JoinIR ValueId へ lowering
|
|||
|
|
- ScopeManager を使った変数解決
|
|||
|
|
- サポートされていない AST ノードの検出と fallback
|
|||
|
|
|
|||
|
|
**Phase 231 スコープ**:
|
|||
|
|
- **Context**: Condition のみ(loop/break 条件)
|
|||
|
|
- **Supported**: リテラル、変数、比較演算(<, >, ==, !=, <=, >=)、論理演算(and, or, not)
|
|||
|
|
- **Not Supported**: MethodCall, NewBox, 複雑な式
|
|||
|
|
|
|||
|
|
**設計原則**:
|
|||
|
|
- **Fail-Safe**: 未対応ノードは明示的エラー(実行時エラーにしない)
|
|||
|
|
- **Thin Wrapper**: 既存の condition_lowerer を活用(Phase 231 は API 統一が目的)
|
|||
|
|
- **Incremental Adoption**: 検証専用、実際の lowering 置き換えは Phase 232+
|
|||
|
|
|
|||
|
|
### 4. Pattern2 統合(pre-validation)
|
|||
|
|
|
|||
|
|
**ファイル**: `src/mir/builder/control_flow/joinir/patterns/pattern2_with_break.rs`
|
|||
|
|
|
|||
|
|
**統合方法**:
|
|||
|
|
- break 条件 lowering の **前** に ExprLowerer で検証
|
|||
|
|
- 成功: ログ出力(`[pattern2/phase231] ✓ ExprLowerer successfully validated`)
|
|||
|
|
- UnsupportedNode: fallback ログ(期待される動作)
|
|||
|
|
- 予期しないエラー: 警告ログ(legacy path が処理)
|
|||
|
|
|
|||
|
|
**重要**: Phase 231 は **検証専用**。実際の lowering は従来通り `lower_loop_with_break_minimal` が実行。
|
|||
|
|
|
|||
|
|
## テスト結果
|
|||
|
|
|
|||
|
|
### 単体テスト
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
test mir::join_ir::lowering::scope_manager::tests::test_pattern2_scope_manager_loop_var ... ok
|
|||
|
|
test mir::join_ir::lowering::scope_manager::tests::test_pattern2_scope_manager_carrier ... ok
|
|||
|
|
test mir::join_ir::lowering::scope_manager::tests::test_pattern2_scope_manager_promoted_variable ... ok
|
|||
|
|
test mir::join_ir::lowering::scope_manager::tests::test_pattern2_scope_manager_body_local ... ok
|
|||
|
|
|
|||
|
|
test mir::join_ir::lowering::expr_lowerer::tests::test_expr_lowerer_simple_comparison ... ok
|
|||
|
|
test mir::join_ir::lowering::expr_lowerer::tests::test_expr_lowerer_variable_not_found ... ok
|
|||
|
|
test mir::join_ir::lowering::expr_lowerer::tests::test_expr_lowerer_unsupported_node ... ok
|
|||
|
|
test mir::join_ir::lowering::expr_lowerer::tests::test_is_supported_condition ... ok
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 統合テスト
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
test result: PASSED. 890 passed; 7 failed; 64 ignored
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
- 890 PASS(変更前と同じ)
|
|||
|
|
- 7 FAIL(pre-existing issues、Phase 231 とは無関係)
|
|||
|
|
- Pattern2 関連テスト全て PASS
|
|||
|
|
|
|||
|
|
### E2E テスト
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
$ ./target/release/hakorune /tmp/test_phase231.hako 2>&1 | grep phase231
|
|||
|
|
[pattern2/phase231] ✓ ExprLowerer successfully validated break condition
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
テストプログラム:
|
|||
|
|
```nyash
|
|||
|
|
static box Phase231Test {
|
|||
|
|
main() {
|
|||
|
|
local i = 0
|
|||
|
|
local sum = 0
|
|||
|
|
loop(i < 10) {
|
|||
|
|
if i >= 5 { break }
|
|||
|
|
sum = sum + i
|
|||
|
|
i = i + 1
|
|||
|
|
}
|
|||
|
|
return sum // RC: 0(正常動作)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## ファイル変更
|
|||
|
|
|
|||
|
|
### 新規ファイル(2ファイル)
|
|||
|
|
|
|||
|
|
1. `src/mir/join_ir/lowering/scope_manager.rs`(280 lines)
|
|||
|
|
- ScopeManager trait
|
|||
|
|
- Pattern2ScopeManager 実装
|
|||
|
|
- VarScopeKind enum
|
|||
|
|
- 4 unit tests
|
|||
|
|
|
|||
|
|
2. `src/mir/join_ir/lowering/expr_lowerer.rs`(455 lines)
|
|||
|
|
- ExprLowerer struct
|
|||
|
|
- ExprContext / ExprLoweringError enum
|
|||
|
|
- 3 unit tests
|
|||
|
|
|
|||
|
|
### 変更ファイル(3ファイル)
|
|||
|
|
|
|||
|
|
1. `src/mir/join_ir/lowering/mod.rs`(+2 lines)
|
|||
|
|
- scope_manager, expr_lowerer モジュール追加
|
|||
|
|
|
|||
|
|
2. `src/mir/builder/control_flow/joinir/patterns/pattern2_with_break.rs`(+36 lines)
|
|||
|
|
- ExprLowerer pre-validation 追加
|
|||
|
|
|
|||
|
|
3. `docs/development/current/main/joinir-architecture-overview.md`(+20 lines)
|
|||
|
|
- Phase 231 実装内容を追加
|
|||
|
|
|
|||
|
|
## 設計上の重要な判断
|
|||
|
|
|
|||
|
|
### 1. Pre-validation アプローチ
|
|||
|
|
|
|||
|
|
**Why**: 既存の proven lowering path を保持しつつ、新 API の検証データを収集。
|
|||
|
|
|
|||
|
|
**Benefits**:
|
|||
|
|
- 既存コードへの影響ゼロ(fallback 完備)
|
|||
|
|
- 段階的移行が可能(Phase 232+ で実際の lowering 置き換え)
|
|||
|
|
- どのパターンが動くか/動かないかのデータ収集
|
|||
|
|
|
|||
|
|
### 2. ScopeManager を trait に
|
|||
|
|
|
|||
|
|
**Why**: Pattern2 以外にも拡張しやすくするため。
|
|||
|
|
|
|||
|
|
**Benefits**:
|
|||
|
|
- Pattern1/Pattern3/Pattern4 で異なる実装を提供可能
|
|||
|
|
- テスト時にモック実装が作れる
|
|||
|
|
- 将来の拡張(General context 対応)がしやすい
|
|||
|
|
|
|||
|
|
### 3. ExprLowerer は condition_lowerer を再利用
|
|||
|
|
|
|||
|
|
**Why**: Phase 231 は API 統一が目的、ロジック reimplementation は不要。
|
|||
|
|
|
|||
|
|
**Benefits**:
|
|||
|
|
- 実装コストが低い(thin wrapper)
|
|||
|
|
- 既存の proven logic を活用(品質保証済み)
|
|||
|
|
- ScopeManager → ConditionEnv 変換だけに集中
|
|||
|
|
|
|||
|
|
## 箱化・モジュール化の原則
|
|||
|
|
|
|||
|
|
### Box-First
|
|||
|
|
|
|||
|
|
- **ScopeManager**: 変数解決を統一的に扱う trait-based "box"
|
|||
|
|
- **ExprLowerer**: 式 lowering を1箇所に集約(パイロット段階)
|
|||
|
|
|
|||
|
|
### Single Responsibility
|
|||
|
|
|
|||
|
|
- **ScopeManager**: 変数解決のみ(AST lowering や ValueId 割り当ては別箱)
|
|||
|
|
- **ExprLowerer**: 式 lowering のみ(変数環境管理は ScopeManager に委譲)
|
|||
|
|
|
|||
|
|
### Fail-Safe
|
|||
|
|
|
|||
|
|
- 未対応 AST ノードは明示的エラー(UnsupportedNode)
|
|||
|
|
- フォールバック経路を必ず用意(legacy path が処理)
|
|||
|
|
- 実行時エラーにしない(コンパイル時に検出)
|
|||
|
|
|
|||
|
|
### Testability
|
|||
|
|
|
|||
|
|
- ScopeManager は trait なので独立してテスト可能
|
|||
|
|
- ExprLowerer は MirBuilder に依存するが、最小限の stub で動作
|
|||
|
|
- 単体テストで各種エラーケースを網羅
|
|||
|
|
|
|||
|
|
## 次のステップ
|
|||
|
|
|
|||
|
|
### Phase 232: Pattern1/Pattern3 への拡大
|
|||
|
|
|
|||
|
|
- Pattern1ScopeManager, Pattern3ScopeManager 実装
|
|||
|
|
- loop 条件も ExprLowerer で pre-validation
|
|||
|
|
- データ収集: どのパターンが動くか確認
|
|||
|
|
|
|||
|
|
### Phase 233: 実際の lowering 置き換え
|
|||
|
|
|
|||
|
|
- ExprLowerer を実際の lowering path として使用
|
|||
|
|
- fallback path を削除(ExprLowerer が完全に置き換え)
|
|||
|
|
- テスト: すべての Pattern2/Pattern1/Pattern3 で動作確認
|
|||
|
|
|
|||
|
|
### Phase 234+: General context 対応
|
|||
|
|
|
|||
|
|
- ExprContext::General 実装
|
|||
|
|
- MethodCall, NewBox, 複雑な式のサポート
|
|||
|
|
- 完全な式 lowering 統一
|
|||
|
|
|
|||
|
|
## まとめ
|
|||
|
|
|
|||
|
|
Phase 231 は ExprLowerer / ScopeManager アーキテクチャの実現可能性を実証した。
|
|||
|
|
|
|||
|
|
**成功要因**:
|
|||
|
|
- Pre-validation アプローチで既存コードへの影響ゼロ
|
|||
|
|
- ScopeManager trait で変数解決を統一的に抽象化
|
|||
|
|
- Box-First / Fail-Safe 原則の徹底
|
|||
|
|
|
|||
|
|
**次の課題**:
|
|||
|
|
- Pattern1/Pattern3 への拡大(Phase 232)
|
|||
|
|
- 実際の lowering 置き換え(Phase 233)
|
|||
|
|
- General context 対応(Phase 234+)
|
|||
|
|
|
|||
|
|
Phase 231 の成果により、Phase 230 の設計が正しいことが検証され、次のフェーズへの明確な道筋がついた。
|