Files
hakorune/src/mir/builder/control_flow/joinir/patterns/router.rs

262 lines
9.2 KiB
Rust
Raw Normal View History

//! Pattern Router - Plan/Composer routing for loop patterns
feat(joinir): Phase 194 - Table-driven loop pattern router Replace if/else chain with table-driven pattern dispatch for easier pattern addition and maintenance. # Changes ## New Files - router.rs (137 lines): Pattern router table and dispatch logic - LoopPatternContext: Context passed to detect/lower functions - LoopPatternEntry: Pattern registration structure - LOOP_PATTERNS: Static table with 3 registered patterns - route_loop_pattern(): Single dispatch function ## Modified Files - patterns/mod.rs (+8 lines): Export router module - pattern1_minimal.rs (+19 lines): Added can_lower() + lower() wrapper - pattern2_with_break.rs (+17 lines): Added can_lower() + lower() wrapper - pattern3_with_if_phi.rs (+22 lines): Added can_lower() + lower() wrapper - routing.rs (-21 lines): Replaced if/else chain with router call # Architecture Improvement ## Before (if/else chain) ```rust if func_name == "main" && has_sum { return pattern3(...); } else if func_name == "main" { return pattern1(...); } else if func_name == "JoinIrMin.main/0" { return pattern2(...); } ``` ## After (table-driven) ```rust let ctx = LoopPatternContext::new(...); route_loop_pattern(self, &ctx)? ``` # Adding New Patterns (Now Trivial!) 1. Create pattern4_your_name.rs 2. Implement can_lower() + lower() 3. Add entry to LOOP_PATTERNS table That's it! No routing logic changes needed. # Testing ✅ Pattern 1 (loop_min_while.hako): PASSED ✅ Pattern 2 (joinir_min_loop.hako): PASSED ✅ Pattern 3 (loop_if_phi.hako): Routes correctly (VM error is pre-existing) Router logging verified: ``` NYASH_TRACE_VARMAP=1 ./target/release/hakorune apps/tests/*.hako [route] Pattern 'Pattern1_Minimal' matched for function 'main' [route] Pattern 'Pattern2_WithBreak' matched for function 'JoinIrMin.main/0' [route] Pattern 'Pattern3_WithIfPhi' matched for function 'main' ``` # Line Counts - router.rs: 137 lines (new) - Total pattern files: 491 lines (3 patterns) - routing.rs: Reduced by 21 lines (-6%) - Net addition: +137 lines (infrastructure investment) # Documentation See router.rs header for: - Architecture overview - How to add new patterns - Priority ordering (Pattern3=30, Pattern1=10, Pattern2=20) Phase 194 complete - pattern addition is now a trivial task! 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 22:11:39 +09:00
//!
//! Phase 29ap P12: Legacy loop table removed (plan/composer SSOT only)
feat(joinir): Phase 194 - Table-driven loop pattern router Replace if/else chain with table-driven pattern dispatch for easier pattern addition and maintenance. # Changes ## New Files - router.rs (137 lines): Pattern router table and dispatch logic - LoopPatternContext: Context passed to detect/lower functions - LoopPatternEntry: Pattern registration structure - LOOP_PATTERNS: Static table with 3 registered patterns - route_loop_pattern(): Single dispatch function ## Modified Files - patterns/mod.rs (+8 lines): Export router module - pattern1_minimal.rs (+19 lines): Added can_lower() + lower() wrapper - pattern2_with_break.rs (+17 lines): Added can_lower() + lower() wrapper - pattern3_with_if_phi.rs (+22 lines): Added can_lower() + lower() wrapper - routing.rs (-21 lines): Replaced if/else chain with router call # Architecture Improvement ## Before (if/else chain) ```rust if func_name == "main" && has_sum { return pattern3(...); } else if func_name == "main" { return pattern1(...); } else if func_name == "JoinIrMin.main/0" { return pattern2(...); } ``` ## After (table-driven) ```rust let ctx = LoopPatternContext::new(...); route_loop_pattern(self, &ctx)? ``` # Adding New Patterns (Now Trivial!) 1. Create pattern4_your_name.rs 2. Implement can_lower() + lower() 3. Add entry to LOOP_PATTERNS table That's it! No routing logic changes needed. # Testing ✅ Pattern 1 (loop_min_while.hako): PASSED ✅ Pattern 2 (joinir_min_loop.hako): PASSED ✅ Pattern 3 (loop_if_phi.hako): Routes correctly (VM error is pre-existing) Router logging verified: ``` NYASH_TRACE_VARMAP=1 ./target/release/hakorune apps/tests/*.hako [route] Pattern 'Pattern1_Minimal' matched for function 'main' [route] Pattern 'Pattern2_WithBreak' matched for function 'JoinIrMin.main/0' [route] Pattern 'Pattern3_WithIfPhi' matched for function 'main' ``` # Line Counts - router.rs: 137 lines (new) - Total pattern files: 491 lines (3 patterns) - routing.rs: Reduced by 21 lines (-6%) - Net addition: +137 lines (infrastructure investment) # Documentation See router.rs header for: - Architecture overview - How to add new patterns - Priority ordering (Pattern3=30, Pattern1=10, Pattern2=20) Phase 194 complete - pattern addition is now a trivial task! 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 22:11:39 +09:00
//!
//! # Architecture
//!
//! - single_planner derives a DomainPlan + facts outcome (SSOT)
//! - composer adopts CorePlan (strict/dev shadow or release adopt)
//! - PlanLowerer emits MIR from CorePlan (emit_frag SSOT)
feat(joinir): Phase 194 - Table-driven loop pattern router Replace if/else chain with table-driven pattern dispatch for easier pattern addition and maintenance. # Changes ## New Files - router.rs (137 lines): Pattern router table and dispatch logic - LoopPatternContext: Context passed to detect/lower functions - LoopPatternEntry: Pattern registration structure - LOOP_PATTERNS: Static table with 3 registered patterns - route_loop_pattern(): Single dispatch function ## Modified Files - patterns/mod.rs (+8 lines): Export router module - pattern1_minimal.rs (+19 lines): Added can_lower() + lower() wrapper - pattern2_with_break.rs (+17 lines): Added can_lower() + lower() wrapper - pattern3_with_if_phi.rs (+22 lines): Added can_lower() + lower() wrapper - routing.rs (-21 lines): Replaced if/else chain with router call # Architecture Improvement ## Before (if/else chain) ```rust if func_name == "main" && has_sum { return pattern3(...); } else if func_name == "main" { return pattern1(...); } else if func_name == "JoinIrMin.main/0" { return pattern2(...); } ``` ## After (table-driven) ```rust let ctx = LoopPatternContext::new(...); route_loop_pattern(self, &ctx)? ``` # Adding New Patterns (Now Trivial!) 1. Create pattern4_your_name.rs 2. Implement can_lower() + lower() 3. Add entry to LOOP_PATTERNS table That's it! No routing logic changes needed. # Testing ✅ Pattern 1 (loop_min_while.hako): PASSED ✅ Pattern 2 (joinir_min_loop.hako): PASSED ✅ Pattern 3 (loop_if_phi.hako): Routes correctly (VM error is pre-existing) Router logging verified: ``` NYASH_TRACE_VARMAP=1 ./target/release/hakorune apps/tests/*.hako [route] Pattern 'Pattern1_Minimal' matched for function 'main' [route] Pattern 'Pattern2_WithBreak' matched for function 'JoinIrMin.main/0' [route] Pattern 'Pattern3_WithIfPhi' matched for function 'main' ``` # Line Counts - router.rs: 137 lines (new) - Total pattern files: 491 lines (3 patterns) - routing.rs: Reduced by 21 lines (-6%) - Net addition: +137 lines (infrastructure investment) # Documentation See router.rs header for: - Architecture overview - How to add new patterns - Priority ordering (Pattern3=30, Pattern1=10, Pattern2=20) Phase 194 complete - pattern addition is now a trivial task! 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 22:11:39 +09:00
//!
//! # Adding New Patterns
//!
//! 1. Add Facts/Planner extraction in plan layer
//! 2. Normalize/verify in plan normalizer/verifier
//! 3. Compose CorePlan in composer (shadow/release adopt as needed)
//! 4. Keep router unchanged (it only delegates to plan/composer)
feat(joinir): Phase 194 - Table-driven loop pattern router Replace if/else chain with table-driven pattern dispatch for easier pattern addition and maintenance. # Changes ## New Files - router.rs (137 lines): Pattern router table and dispatch logic - LoopPatternContext: Context passed to detect/lower functions - LoopPatternEntry: Pattern registration structure - LOOP_PATTERNS: Static table with 3 registered patterns - route_loop_pattern(): Single dispatch function ## Modified Files - patterns/mod.rs (+8 lines): Export router module - pattern1_minimal.rs (+19 lines): Added can_lower() + lower() wrapper - pattern2_with_break.rs (+17 lines): Added can_lower() + lower() wrapper - pattern3_with_if_phi.rs (+22 lines): Added can_lower() + lower() wrapper - routing.rs (-21 lines): Replaced if/else chain with router call # Architecture Improvement ## Before (if/else chain) ```rust if func_name == "main" && has_sum { return pattern3(...); } else if func_name == "main" { return pattern1(...); } else if func_name == "JoinIrMin.main/0" { return pattern2(...); } ``` ## After (table-driven) ```rust let ctx = LoopPatternContext::new(...); route_loop_pattern(self, &ctx)? ``` # Adding New Patterns (Now Trivial!) 1. Create pattern4_your_name.rs 2. Implement can_lower() + lower() 3. Add entry to LOOP_PATTERNS table That's it! No routing logic changes needed. # Testing ✅ Pattern 1 (loop_min_while.hako): PASSED ✅ Pattern 2 (joinir_min_loop.hako): PASSED ✅ Pattern 3 (loop_if_phi.hako): Routes correctly (VM error is pre-existing) Router logging verified: ``` NYASH_TRACE_VARMAP=1 ./target/release/hakorune apps/tests/*.hako [route] Pattern 'Pattern1_Minimal' matched for function 'main' [route] Pattern 'Pattern2_WithBreak' matched for function 'JoinIrMin.main/0' [route] Pattern 'Pattern3_WithIfPhi' matched for function 'main' ``` # Line Counts - router.rs: 137 lines (new) - Total pattern files: 491 lines (3 patterns) - routing.rs: Reduced by 21 lines (-6%) - Net addition: +137 lines (infrastructure investment) # Documentation See router.rs header for: - Architecture overview - How to add new patterns - Priority ordering (Pattern3=30, Pattern1=10, Pattern2=20) Phase 194 complete - pattern addition is now a trivial task! 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 22:11:39 +09:00
use crate::ast::ASTNode;
use crate::mir::builder::MirBuilder;
use crate::mir::ValueId;
refactor(joinir): Phase 193-1 - AST Feature Extractor Box modularization **Phase 193-1**: Create independent AST Feature Extractor Box module ## Summary Extracted feature detection logic from router.rs into a new, reusable ast_feature_extractor.rs module. This improves: - **Modularity**: Feature extraction is now a pure, side-effect-free module - **Reusability**: Can be used for Pattern 5-6 detection and analysis tools - **Testability**: Pure functions can be unit tested independently - **Maintainability**: Clear separation of concerns (router does dispatch, extractor does analysis) ## Changes ### New Files - **src/mir/builder/control_flow/joinir/patterns/ast_feature_extractor.rs** (+180 lines) - `detect_continue_in_body()`: Detect continue statements - `detect_break_in_body()`: Detect break statements - `extract_features()`: Full feature extraction pipeline - `detect_if_else_phi_in_body()`: Pattern detection for if-else PHI - `count_carriers_in_body()`: Heuristic carrier counting - Unit tests for basic functionality ### Modified Files - **src/mir/builder/control_flow/joinir/patterns/router.rs** - Removed 75 lines of feature detection code - Now delegates to `ast_features::` module - Phase 193 documentation in comments - Cleaner separation of concerns - **src/mir/builder/control_flow/joinir/patterns/mod.rs** - Added module declaration for ast_feature_extractor - Updated documentation with Phase 193 info ## Architecture ``` router.rs (10 lines) └─→ ast_feature_extractor.rs (180 lines) - Pure functions for AST analysis - No side effects - High reusability - Testable in isolation ``` ## Testing ✅ Build succeeds: `cargo build --release` compiles cleanly ✅ Binary compatibility: Existing .hako files execute correctly ✅ No logic changes: Feature detection identical to previous implementation ## Metrics - Lines moved from router to new module: 75 - New module total: 180 lines (including tests and documentation) - Router.rs reduced by ~40% in feature detection code - New module rated ⭐⭐⭐⭐⭐ for reusability and independence ## Next Steps - Phase 193-2: CarrierInfo Builder Enhancement - Phase 193-3: Pattern Classification Improvement - Phase 194: Further pattern detection optimizations 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-06 03:30:03 +09:00
use crate::mir::loop_pattern_detection::{LoopFeatures, LoopPatternKind};
// Phase 273 P1: Import Plan components (DomainPlan → Normalizer → Verifier → Lowerer)
use crate::mir::builder::control_flow::plan::lowerer::PlanLowerer;
use crate::mir::builder::control_flow::plan::normalizer::PlanNormalizer;
use crate::mir::builder::control_flow::plan::verifier::PlanVerifier;
use crate::mir::builder::control_flow::plan::composer;
use crate::mir::builder::control_flow::plan::single_planner;
/// AST Feature Extractor (declared in mod.rs as pub module, import from parent)
refactor(joinir): Phase 193-1 - AST Feature Extractor Box modularization **Phase 193-1**: Create independent AST Feature Extractor Box module ## Summary Extracted feature detection logic from router.rs into a new, reusable ast_feature_extractor.rs module. This improves: - **Modularity**: Feature extraction is now a pure, side-effect-free module - **Reusability**: Can be used for Pattern 5-6 detection and analysis tools - **Testability**: Pure functions can be unit tested independently - **Maintainability**: Clear separation of concerns (router does dispatch, extractor does analysis) ## Changes ### New Files - **src/mir/builder/control_flow/joinir/patterns/ast_feature_extractor.rs** (+180 lines) - `detect_continue_in_body()`: Detect continue statements - `detect_break_in_body()`: Detect break statements - `extract_features()`: Full feature extraction pipeline - `detect_if_else_phi_in_body()`: Pattern detection for if-else PHI - `count_carriers_in_body()`: Heuristic carrier counting - Unit tests for basic functionality ### Modified Files - **src/mir/builder/control_flow/joinir/patterns/router.rs** - Removed 75 lines of feature detection code - Now delegates to `ast_features::` module - Phase 193 documentation in comments - Cleaner separation of concerns - **src/mir/builder/control_flow/joinir/patterns/mod.rs** - Added module declaration for ast_feature_extractor - Updated documentation with Phase 193 info ## Architecture ``` router.rs (10 lines) └─→ ast_feature_extractor.rs (180 lines) - Pure functions for AST analysis - No side effects - High reusability - Testable in isolation ``` ## Testing ✅ Build succeeds: `cargo build --release` compiles cleanly ✅ Binary compatibility: Existing .hako files execute correctly ✅ No logic changes: Feature detection identical to previous implementation ## Metrics - Lines moved from router to new module: 75 - New module total: 180 lines (including tests and documentation) - Router.rs reduced by ~40% in feature detection code - New module rated ⭐⭐⭐⭐⭐ for reusability and independence ## Next Steps - Phase 193-2: CarrierInfo Builder Enhancement - Phase 193-3: Pattern Classification Improvement - Phase 194: Further pattern detection optimizations 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-06 03:30:03 +09:00
use super::ast_feature_extractor as ast_features;
/// Phase 92 P0-2: Import LoopSkeleton for Option A
use crate::mir::loop_canonicalizer::LoopSkeleton;
feat(joinir): Phase 194 - Table-driven loop pattern router Replace if/else chain with table-driven pattern dispatch for easier pattern addition and maintenance. # Changes ## New Files - router.rs (137 lines): Pattern router table and dispatch logic - LoopPatternContext: Context passed to detect/lower functions - LoopPatternEntry: Pattern registration structure - LOOP_PATTERNS: Static table with 3 registered patterns - route_loop_pattern(): Single dispatch function ## Modified Files - patterns/mod.rs (+8 lines): Export router module - pattern1_minimal.rs (+19 lines): Added can_lower() + lower() wrapper - pattern2_with_break.rs (+17 lines): Added can_lower() + lower() wrapper - pattern3_with_if_phi.rs (+22 lines): Added can_lower() + lower() wrapper - routing.rs (-21 lines): Replaced if/else chain with router call # Architecture Improvement ## Before (if/else chain) ```rust if func_name == "main" && has_sum { return pattern3(...); } else if func_name == "main" { return pattern1(...); } else if func_name == "JoinIrMin.main/0" { return pattern2(...); } ``` ## After (table-driven) ```rust let ctx = LoopPatternContext::new(...); route_loop_pattern(self, &ctx)? ``` # Adding New Patterns (Now Trivial!) 1. Create pattern4_your_name.rs 2. Implement can_lower() + lower() 3. Add entry to LOOP_PATTERNS table That's it! No routing logic changes needed. # Testing ✅ Pattern 1 (loop_min_while.hako): PASSED ✅ Pattern 2 (joinir_min_loop.hako): PASSED ✅ Pattern 3 (loop_if_phi.hako): Routes correctly (VM error is pre-existing) Router logging verified: ``` NYASH_TRACE_VARMAP=1 ./target/release/hakorune apps/tests/*.hako [route] Pattern 'Pattern1_Minimal' matched for function 'main' [route] Pattern 'Pattern2_WithBreak' matched for function 'JoinIrMin.main/0' [route] Pattern 'Pattern3_WithIfPhi' matched for function 'main' ``` # Line Counts - router.rs: 137 lines (new) - Total pattern files: 491 lines (3 patterns) - routing.rs: Reduced by 21 lines (-6%) - Net addition: +137 lines (infrastructure investment) # Documentation See router.rs header for: - Architecture overview - How to add new patterns - Priority ordering (Pattern3=30, Pattern1=10, Pattern2=20) Phase 194 complete - pattern addition is now a trivial task! 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 22:11:39 +09:00
/// Context passed to pattern detect/lower functions
pub(crate) struct LoopPatternContext<'a> {
feat(joinir): Phase 194 - Table-driven loop pattern router Replace if/else chain with table-driven pattern dispatch for easier pattern addition and maintenance. # Changes ## New Files - router.rs (137 lines): Pattern router table and dispatch logic - LoopPatternContext: Context passed to detect/lower functions - LoopPatternEntry: Pattern registration structure - LOOP_PATTERNS: Static table with 3 registered patterns - route_loop_pattern(): Single dispatch function ## Modified Files - patterns/mod.rs (+8 lines): Export router module - pattern1_minimal.rs (+19 lines): Added can_lower() + lower() wrapper - pattern2_with_break.rs (+17 lines): Added can_lower() + lower() wrapper - pattern3_with_if_phi.rs (+22 lines): Added can_lower() + lower() wrapper - routing.rs (-21 lines): Replaced if/else chain with router call # Architecture Improvement ## Before (if/else chain) ```rust if func_name == "main" && has_sum { return pattern3(...); } else if func_name == "main" { return pattern1(...); } else if func_name == "JoinIrMin.main/0" { return pattern2(...); } ``` ## After (table-driven) ```rust let ctx = LoopPatternContext::new(...); route_loop_pattern(self, &ctx)? ``` # Adding New Patterns (Now Trivial!) 1. Create pattern4_your_name.rs 2. Implement can_lower() + lower() 3. Add entry to LOOP_PATTERNS table That's it! No routing logic changes needed. # Testing ✅ Pattern 1 (loop_min_while.hako): PASSED ✅ Pattern 2 (joinir_min_loop.hako): PASSED ✅ Pattern 3 (loop_if_phi.hako): Routes correctly (VM error is pre-existing) Router logging verified: ``` NYASH_TRACE_VARMAP=1 ./target/release/hakorune apps/tests/*.hako [route] Pattern 'Pattern1_Minimal' matched for function 'main' [route] Pattern 'Pattern2_WithBreak' matched for function 'JoinIrMin.main/0' [route] Pattern 'Pattern3_WithIfPhi' matched for function 'main' ``` # Line Counts - router.rs: 137 lines (new) - Total pattern files: 491 lines (3 patterns) - routing.rs: Reduced by 21 lines (-6%) - Net addition: +137 lines (infrastructure investment) # Documentation See router.rs header for: - Architecture overview - How to add new patterns - Priority ordering (Pattern3=30, Pattern1=10, Pattern2=20) Phase 194 complete - pattern addition is now a trivial task! 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 22:11:39 +09:00
/// Loop condition AST node
pub condition: &'a ASTNode,
/// Loop body statements
pub body: &'a [ASTNode],
/// Current function name (for routing)
pub func_name: &'a str,
/// Debug logging enabled
pub debug: bool,
/// In static box context? (affects Pattern8 routing)
pub in_static_box: bool,
/// Has continue statement(s) in body? (Phase 194+)
#[allow(dead_code)]
pub has_continue: bool,
/// Has break statement(s) in body? (Phase 194+)
#[allow(dead_code)]
pub has_break: bool,
refactor(joinir): Phase 193-1 - AST Feature Extractor Box modularization **Phase 193-1**: Create independent AST Feature Extractor Box module ## Summary Extracted feature detection logic from router.rs into a new, reusable ast_feature_extractor.rs module. This improves: - **Modularity**: Feature extraction is now a pure, side-effect-free module - **Reusability**: Can be used for Pattern 5-6 detection and analysis tools - **Testability**: Pure functions can be unit tested independently - **Maintainability**: Clear separation of concerns (router does dispatch, extractor does analysis) ## Changes ### New Files - **src/mir/builder/control_flow/joinir/patterns/ast_feature_extractor.rs** (+180 lines) - `detect_continue_in_body()`: Detect continue statements - `detect_break_in_body()`: Detect break statements - `extract_features()`: Full feature extraction pipeline - `detect_if_else_phi_in_body()`: Pattern detection for if-else PHI - `count_carriers_in_body()`: Heuristic carrier counting - Unit tests for basic functionality ### Modified Files - **src/mir/builder/control_flow/joinir/patterns/router.rs** - Removed 75 lines of feature detection code - Now delegates to `ast_features::` module - Phase 193 documentation in comments - Cleaner separation of concerns - **src/mir/builder/control_flow/joinir/patterns/mod.rs** - Added module declaration for ast_feature_extractor - Updated documentation with Phase 193 info ## Architecture ``` router.rs (10 lines) └─→ ast_feature_extractor.rs (180 lines) - Pure functions for AST analysis - No side effects - High reusability - Testable in isolation ``` ## Testing ✅ Build succeeds: `cargo build --release` compiles cleanly ✅ Binary compatibility: Existing .hako files execute correctly ✅ No logic changes: Feature detection identical to previous implementation ## Metrics - Lines moved from router to new module: 75 - New module total: 180 lines (including tests and documentation) - Router.rs reduced by ~40% in feature detection code - New module rated ⭐⭐⭐⭐⭐ for reusability and independence ## Next Steps - Phase 193-2: CarrierInfo Builder Enhancement - Phase 193-3: Pattern Classification Improvement - Phase 194: Further pattern detection optimizations 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-06 03:30:03 +09:00
/// Phase 192: Loop features extracted from AST
#[allow(dead_code)]
refactor(joinir): Phase 193-1 - AST Feature Extractor Box modularization **Phase 193-1**: Create independent AST Feature Extractor Box module ## Summary Extracted feature detection logic from router.rs into a new, reusable ast_feature_extractor.rs module. This improves: - **Modularity**: Feature extraction is now a pure, side-effect-free module - **Reusability**: Can be used for Pattern 5-6 detection and analysis tools - **Testability**: Pure functions can be unit tested independently - **Maintainability**: Clear separation of concerns (router does dispatch, extractor does analysis) ## Changes ### New Files - **src/mir/builder/control_flow/joinir/patterns/ast_feature_extractor.rs** (+180 lines) - `detect_continue_in_body()`: Detect continue statements - `detect_break_in_body()`: Detect break statements - `extract_features()`: Full feature extraction pipeline - `detect_if_else_phi_in_body()`: Pattern detection for if-else PHI - `count_carriers_in_body()`: Heuristic carrier counting - Unit tests for basic functionality ### Modified Files - **src/mir/builder/control_flow/joinir/patterns/router.rs** - Removed 75 lines of feature detection code - Now delegates to `ast_features::` module - Phase 193 documentation in comments - Cleaner separation of concerns - **src/mir/builder/control_flow/joinir/patterns/mod.rs** - Added module declaration for ast_feature_extractor - Updated documentation with Phase 193 info ## Architecture ``` router.rs (10 lines) └─→ ast_feature_extractor.rs (180 lines) - Pure functions for AST analysis - No side effects - High reusability - Testable in isolation ``` ## Testing ✅ Build succeeds: `cargo build --release` compiles cleanly ✅ Binary compatibility: Existing .hako files execute correctly ✅ No logic changes: Feature detection identical to previous implementation ## Metrics - Lines moved from router to new module: 75 - New module total: 180 lines (including tests and documentation) - Router.rs reduced by ~40% in feature detection code - New module rated ⭐⭐⭐⭐⭐ for reusability and independence ## Next Steps - Phase 193-2: CarrierInfo Builder Enhancement - Phase 193-3: Pattern Classification Improvement - Phase 194: Further pattern detection optimizations 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-06 03:30:03 +09:00
pub features: LoopFeatures,
/// Phase 192: Pattern classification based on features
pub pattern_kind: LoopPatternKind,
/// Phase 200-C: Optional function body AST for capture analysis
/// None if not available, Some(&[ASTNode]) if function body is accessible
pub fn_body: Option<&'a [ASTNode]>,
/// Phase 92 P0-2: Optional LoopSkeleton from canonicalizer
/// This provides ConditionalStep information for Pattern2 lowering.
/// None if canonicalizer hasn't run yet (backward compatibility).
/// SSOT Principle: Avoid re-detecting ConditionalStep in lowering phase.
#[allow(dead_code)]
pub skeleton: Option<&'a LoopSkeleton>,
feat(joinir): Phase 188.3 - Pattern6 (NestedLoopMinimal) 選択ロジック実装 ## Phase 188.3 進捗: Phase 2 完了 (6/13 tasks) ### 実装完了 ✅ **Phase 1: Fixture作成** - apps/tests/phase1883_nested_minimal.hako 追加 - Add/Compare のみ(乗算なし) - 期待 exit code: 9 (3×3 nested loops) - 既存 lowering で fallback 動作確認 **Phase 2: 選択ロジック (SSOT)** - LoopPatternContext に step_tree_max_loop_depth フィールド追加 - choose_pattern_kind() に Pattern6 選択ロジック実装: 1. Cheap check (has_inner_loop) 2. StepTree 構築 (max_loop_depth 取得) 3. AST validation (is_pattern6_lowerable) - pattern6_nested_minimal.rs モジュール作成 (stub) - LOOP_PATTERNS に Pattern6 entry 追加 - **検証**: Pattern6 が正しく選択される ✅ ### 設計原則 (確認済み) 1. **Fail-Fast**: Pattern6 選択後は Ok(None) で逃げない 2. **outer 変数 write-back 検出 → validation false** (Phase 188.4+) 3. **最小実装**: inner local だけ、Pattern1 モデル二重化 4. **cfg! 依存なし**: production で動作 ### 検証結果 ``` [choose_pattern_kind] has_inner_loop=true [choose_pattern_kind] max_loop_depth=2 [choose_pattern_kind] is_pattern6_lowerable=true ✅ Pattern6 SELECTED! ``` Stub からの期待エラー: ``` [ERROR] ❌ [Pattern6] Nested loop lowering not yet implemented ``` ### 次: Phase 3 (Lowering 実装 - 推定4時間) 残りタスク: - Phase 3-1: AST 抽出ヘルパー - Phase 3-2: Validation ヘルパー - Phase 3-3: Continuation 生成 (outer_step, inner_step, k_inner_exit) - Phase 3-4: fixture が exit=9 を返すことを検証 ### 変更ファイル **新規**: - apps/tests/phase1883_nested_minimal.hako - src/mir/builder/control_flow/joinir/patterns/pattern6_nested_minimal.rs - docs/development/current/main/phases/phase-188.{1,2,3}/README.md **変更**: - src/mir/builder/control_flow/joinir/routing.rs (Pattern6 選択) - src/mir/builder/control_flow/joinir/patterns/router.rs (Context 拡張) - src/mir/builder/control_flow/joinir/patterns/mod.rs (module 宣言) 🎯 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-27 05:45:12 +09:00
/// Phase 188.3: Cached StepTree max_loop_depth for Pattern6
/// None if not computed, Some(depth) if Pattern6 candidate
/// Avoids re-building StepTree in lowering phase
pub step_tree_max_loop_depth: Option<u32>,
feat(joinir): Phase 194 - Table-driven loop pattern router Replace if/else chain with table-driven pattern dispatch for easier pattern addition and maintenance. # Changes ## New Files - router.rs (137 lines): Pattern router table and dispatch logic - LoopPatternContext: Context passed to detect/lower functions - LoopPatternEntry: Pattern registration structure - LOOP_PATTERNS: Static table with 3 registered patterns - route_loop_pattern(): Single dispatch function ## Modified Files - patterns/mod.rs (+8 lines): Export router module - pattern1_minimal.rs (+19 lines): Added can_lower() + lower() wrapper - pattern2_with_break.rs (+17 lines): Added can_lower() + lower() wrapper - pattern3_with_if_phi.rs (+22 lines): Added can_lower() + lower() wrapper - routing.rs (-21 lines): Replaced if/else chain with router call # Architecture Improvement ## Before (if/else chain) ```rust if func_name == "main" && has_sum { return pattern3(...); } else if func_name == "main" { return pattern1(...); } else if func_name == "JoinIrMin.main/0" { return pattern2(...); } ``` ## After (table-driven) ```rust let ctx = LoopPatternContext::new(...); route_loop_pattern(self, &ctx)? ``` # Adding New Patterns (Now Trivial!) 1. Create pattern4_your_name.rs 2. Implement can_lower() + lower() 3. Add entry to LOOP_PATTERNS table That's it! No routing logic changes needed. # Testing ✅ Pattern 1 (loop_min_while.hako): PASSED ✅ Pattern 2 (joinir_min_loop.hako): PASSED ✅ Pattern 3 (loop_if_phi.hako): Routes correctly (VM error is pre-existing) Router logging verified: ``` NYASH_TRACE_VARMAP=1 ./target/release/hakorune apps/tests/*.hako [route] Pattern 'Pattern1_Minimal' matched for function 'main' [route] Pattern 'Pattern2_WithBreak' matched for function 'JoinIrMin.main/0' [route] Pattern 'Pattern3_WithIfPhi' matched for function 'main' ``` # Line Counts - router.rs: 137 lines (new) - Total pattern files: 491 lines (3 patterns) - routing.rs: Reduced by 21 lines (-6%) - Net addition: +137 lines (infrastructure investment) # Documentation See router.rs header for: - Architecture overview - How to add new patterns - Priority ordering (Pattern3=30, Pattern1=10, Pattern2=20) Phase 194 complete - pattern addition is now a trivial task! 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 22:11:39 +09:00
}
impl<'a> LoopPatternContext<'a> {
/// Create new context from routing parameters
///
/// Automatically detects continue/break statements in body
/// Extracts features and classifies pattern from AST
/// Detects infinite loop condition
/// Uses choose_pattern_kind() SSOT entry point
pub(crate) fn new(
feat(joinir): Phase 194 - Table-driven loop pattern router Replace if/else chain with table-driven pattern dispatch for easier pattern addition and maintenance. # Changes ## New Files - router.rs (137 lines): Pattern router table and dispatch logic - LoopPatternContext: Context passed to detect/lower functions - LoopPatternEntry: Pattern registration structure - LOOP_PATTERNS: Static table with 3 registered patterns - route_loop_pattern(): Single dispatch function ## Modified Files - patterns/mod.rs (+8 lines): Export router module - pattern1_minimal.rs (+19 lines): Added can_lower() + lower() wrapper - pattern2_with_break.rs (+17 lines): Added can_lower() + lower() wrapper - pattern3_with_if_phi.rs (+22 lines): Added can_lower() + lower() wrapper - routing.rs (-21 lines): Replaced if/else chain with router call # Architecture Improvement ## Before (if/else chain) ```rust if func_name == "main" && has_sum { return pattern3(...); } else if func_name == "main" { return pattern1(...); } else if func_name == "JoinIrMin.main/0" { return pattern2(...); } ``` ## After (table-driven) ```rust let ctx = LoopPatternContext::new(...); route_loop_pattern(self, &ctx)? ``` # Adding New Patterns (Now Trivial!) 1. Create pattern4_your_name.rs 2. Implement can_lower() + lower() 3. Add entry to LOOP_PATTERNS table That's it! No routing logic changes needed. # Testing ✅ Pattern 1 (loop_min_while.hako): PASSED ✅ Pattern 2 (joinir_min_loop.hako): PASSED ✅ Pattern 3 (loop_if_phi.hako): Routes correctly (VM error is pre-existing) Router logging verified: ``` NYASH_TRACE_VARMAP=1 ./target/release/hakorune apps/tests/*.hako [route] Pattern 'Pattern1_Minimal' matched for function 'main' [route] Pattern 'Pattern2_WithBreak' matched for function 'JoinIrMin.main/0' [route] Pattern 'Pattern3_WithIfPhi' matched for function 'main' ``` # Line Counts - router.rs: 137 lines (new) - Total pattern files: 491 lines (3 patterns) - routing.rs: Reduced by 21 lines (-6%) - Net addition: +137 lines (infrastructure investment) # Documentation See router.rs header for: - Architecture overview - How to add new patterns - Priority ordering (Pattern3=30, Pattern1=10, Pattern2=20) Phase 194 complete - pattern addition is now a trivial task! 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 22:11:39 +09:00
condition: &'a ASTNode,
body: &'a [ASTNode],
func_name: &'a str,
debug: bool,
in_static_box: bool,
feat(joinir): Phase 194 - Table-driven loop pattern router Replace if/else chain with table-driven pattern dispatch for easier pattern addition and maintenance. # Changes ## New Files - router.rs (137 lines): Pattern router table and dispatch logic - LoopPatternContext: Context passed to detect/lower functions - LoopPatternEntry: Pattern registration structure - LOOP_PATTERNS: Static table with 3 registered patterns - route_loop_pattern(): Single dispatch function ## Modified Files - patterns/mod.rs (+8 lines): Export router module - pattern1_minimal.rs (+19 lines): Added can_lower() + lower() wrapper - pattern2_with_break.rs (+17 lines): Added can_lower() + lower() wrapper - pattern3_with_if_phi.rs (+22 lines): Added can_lower() + lower() wrapper - routing.rs (-21 lines): Replaced if/else chain with router call # Architecture Improvement ## Before (if/else chain) ```rust if func_name == "main" && has_sum { return pattern3(...); } else if func_name == "main" { return pattern1(...); } else if func_name == "JoinIrMin.main/0" { return pattern2(...); } ``` ## After (table-driven) ```rust let ctx = LoopPatternContext::new(...); route_loop_pattern(self, &ctx)? ``` # Adding New Patterns (Now Trivial!) 1. Create pattern4_your_name.rs 2. Implement can_lower() + lower() 3. Add entry to LOOP_PATTERNS table That's it! No routing logic changes needed. # Testing ✅ Pattern 1 (loop_min_while.hako): PASSED ✅ Pattern 2 (joinir_min_loop.hako): PASSED ✅ Pattern 3 (loop_if_phi.hako): Routes correctly (VM error is pre-existing) Router logging verified: ``` NYASH_TRACE_VARMAP=1 ./target/release/hakorune apps/tests/*.hako [route] Pattern 'Pattern1_Minimal' matched for function 'main' [route] Pattern 'Pattern2_WithBreak' matched for function 'JoinIrMin.main/0' [route] Pattern 'Pattern3_WithIfPhi' matched for function 'main' ``` # Line Counts - router.rs: 137 lines (new) - Total pattern files: 491 lines (3 patterns) - routing.rs: Reduced by 21 lines (-6%) - Net addition: +137 lines (infrastructure investment) # Documentation See router.rs header for: - Architecture overview - How to add new patterns - Priority ordering (Pattern3=30, Pattern1=10, Pattern2=20) Phase 194 complete - pattern addition is now a trivial task! 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 22:11:39 +09:00
) -> Self {
// Use AST Feature Extractor for break/continue detection
refactor(joinir): Phase 193-1 - AST Feature Extractor Box modularization **Phase 193-1**: Create independent AST Feature Extractor Box module ## Summary Extracted feature detection logic from router.rs into a new, reusable ast_feature_extractor.rs module. This improves: - **Modularity**: Feature extraction is now a pure, side-effect-free module - **Reusability**: Can be used for Pattern 5-6 detection and analysis tools - **Testability**: Pure functions can be unit tested independently - **Maintainability**: Clear separation of concerns (router does dispatch, extractor does analysis) ## Changes ### New Files - **src/mir/builder/control_flow/joinir/patterns/ast_feature_extractor.rs** (+180 lines) - `detect_continue_in_body()`: Detect continue statements - `detect_break_in_body()`: Detect break statements - `extract_features()`: Full feature extraction pipeline - `detect_if_else_phi_in_body()`: Pattern detection for if-else PHI - `count_carriers_in_body()`: Heuristic carrier counting - Unit tests for basic functionality ### Modified Files - **src/mir/builder/control_flow/joinir/patterns/router.rs** - Removed 75 lines of feature detection code - Now delegates to `ast_features::` module - Phase 193 documentation in comments - Cleaner separation of concerns - **src/mir/builder/control_flow/joinir/patterns/mod.rs** - Added module declaration for ast_feature_extractor - Updated documentation with Phase 193 info ## Architecture ``` router.rs (10 lines) └─→ ast_feature_extractor.rs (180 lines) - Pure functions for AST analysis - No side effects - High reusability - Testable in isolation ``` ## Testing ✅ Build succeeds: `cargo build --release` compiles cleanly ✅ Binary compatibility: Existing .hako files execute correctly ✅ No logic changes: Feature detection identical to previous implementation ## Metrics - Lines moved from router to new module: 75 - New module total: 180 lines (including tests and documentation) - Router.rs reduced by ~40% in feature detection code - New module rated ⭐⭐⭐⭐⭐ for reusability and independence ## Next Steps - Phase 193-2: CarrierInfo Builder Enhancement - Phase 193-3: Pattern Classification Improvement - Phase 194: Further pattern detection optimizations 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-06 03:30:03 +09:00
let has_continue = ast_features::detect_continue_in_body(body);
let has_break = ast_features::detect_break_in_body(body);
// Extract features (includes infinite loop detection)
let features = ast_features::extract_features(condition, body, has_continue, has_break);
refactor(joinir): Phase 193-1 - AST Feature Extractor Box modularization **Phase 193-1**: Create independent AST Feature Extractor Box module ## Summary Extracted feature detection logic from router.rs into a new, reusable ast_feature_extractor.rs module. This improves: - **Modularity**: Feature extraction is now a pure, side-effect-free module - **Reusability**: Can be used for Pattern 5-6 detection and analysis tools - **Testability**: Pure functions can be unit tested independently - **Maintainability**: Clear separation of concerns (router does dispatch, extractor does analysis) ## Changes ### New Files - **src/mir/builder/control_flow/joinir/patterns/ast_feature_extractor.rs** (+180 lines) - `detect_continue_in_body()`: Detect continue statements - `detect_break_in_body()`: Detect break statements - `extract_features()`: Full feature extraction pipeline - `detect_if_else_phi_in_body()`: Pattern detection for if-else PHI - `count_carriers_in_body()`: Heuristic carrier counting - Unit tests for basic functionality ### Modified Files - **src/mir/builder/control_flow/joinir/patterns/router.rs** - Removed 75 lines of feature detection code - Now delegates to `ast_features::` module - Phase 193 documentation in comments - Cleaner separation of concerns - **src/mir/builder/control_flow/joinir/patterns/mod.rs** - Added module declaration for ast_feature_extractor - Updated documentation with Phase 193 info ## Architecture ``` router.rs (10 lines) └─→ ast_feature_extractor.rs (180 lines) - Pure functions for AST analysis - No side effects - High reusability - Testable in isolation ``` ## Testing ✅ Build succeeds: `cargo build --release` compiles cleanly ✅ Binary compatibility: Existing .hako files execute correctly ✅ No logic changes: Feature detection identical to previous implementation ## Metrics - Lines moved from router to new module: 75 - New module total: 180 lines (including tests and documentation) - Router.rs reduced by ~40% in feature detection code - New module rated ⭐⭐⭐⭐⭐ for reusability and independence ## Next Steps - Phase 193-2: CarrierInfo Builder Enhancement - Phase 193-3: Pattern Classification Improvement - Phase 194: Further pattern detection optimizations 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-06 03:30:03 +09:00
// Phase 137-6-S1: Use SSOT pattern selection entry point
use crate::mir::builder::control_flow::joinir::routing::choose_pattern_kind;
let pattern_kind = choose_pattern_kind(condition, body);
feat(joinir): Phase 194 - Table-driven loop pattern router Replace if/else chain with table-driven pattern dispatch for easier pattern addition and maintenance. # Changes ## New Files - router.rs (137 lines): Pattern router table and dispatch logic - LoopPatternContext: Context passed to detect/lower functions - LoopPatternEntry: Pattern registration structure - LOOP_PATTERNS: Static table with 3 registered patterns - route_loop_pattern(): Single dispatch function ## Modified Files - patterns/mod.rs (+8 lines): Export router module - pattern1_minimal.rs (+19 lines): Added can_lower() + lower() wrapper - pattern2_with_break.rs (+17 lines): Added can_lower() + lower() wrapper - pattern3_with_if_phi.rs (+22 lines): Added can_lower() + lower() wrapper - routing.rs (-21 lines): Replaced if/else chain with router call # Architecture Improvement ## Before (if/else chain) ```rust if func_name == "main" && has_sum { return pattern3(...); } else if func_name == "main" { return pattern1(...); } else if func_name == "JoinIrMin.main/0" { return pattern2(...); } ``` ## After (table-driven) ```rust let ctx = LoopPatternContext::new(...); route_loop_pattern(self, &ctx)? ``` # Adding New Patterns (Now Trivial!) 1. Create pattern4_your_name.rs 2. Implement can_lower() + lower() 3. Add entry to LOOP_PATTERNS table That's it! No routing logic changes needed. # Testing ✅ Pattern 1 (loop_min_while.hako): PASSED ✅ Pattern 2 (joinir_min_loop.hako): PASSED ✅ Pattern 3 (loop_if_phi.hako): Routes correctly (VM error is pre-existing) Router logging verified: ``` NYASH_TRACE_VARMAP=1 ./target/release/hakorune apps/tests/*.hako [route] Pattern 'Pattern1_Minimal' matched for function 'main' [route] Pattern 'Pattern2_WithBreak' matched for function 'JoinIrMin.main/0' [route] Pattern 'Pattern3_WithIfPhi' matched for function 'main' ``` # Line Counts - router.rs: 137 lines (new) - Total pattern files: 491 lines (3 patterns) - routing.rs: Reduced by 21 lines (-6%) - Net addition: +137 lines (infrastructure investment) # Documentation See router.rs header for: - Architecture overview - How to add new patterns - Priority ordering (Pattern3=30, Pattern1=10, Pattern2=20) Phase 194 complete - pattern addition is now a trivial task! 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 22:11:39 +09:00
Self {
condition,
body,
func_name,
debug,
in_static_box,
has_continue,
has_break,
refactor(joinir): Phase 193-1 - AST Feature Extractor Box modularization **Phase 193-1**: Create independent AST Feature Extractor Box module ## Summary Extracted feature detection logic from router.rs into a new, reusable ast_feature_extractor.rs module. This improves: - **Modularity**: Feature extraction is now a pure, side-effect-free module - **Reusability**: Can be used for Pattern 5-6 detection and analysis tools - **Testability**: Pure functions can be unit tested independently - **Maintainability**: Clear separation of concerns (router does dispatch, extractor does analysis) ## Changes ### New Files - **src/mir/builder/control_flow/joinir/patterns/ast_feature_extractor.rs** (+180 lines) - `detect_continue_in_body()`: Detect continue statements - `detect_break_in_body()`: Detect break statements - `extract_features()`: Full feature extraction pipeline - `detect_if_else_phi_in_body()`: Pattern detection for if-else PHI - `count_carriers_in_body()`: Heuristic carrier counting - Unit tests for basic functionality ### Modified Files - **src/mir/builder/control_flow/joinir/patterns/router.rs** - Removed 75 lines of feature detection code - Now delegates to `ast_features::` module - Phase 193 documentation in comments - Cleaner separation of concerns - **src/mir/builder/control_flow/joinir/patterns/mod.rs** - Added module declaration for ast_feature_extractor - Updated documentation with Phase 193 info ## Architecture ``` router.rs (10 lines) └─→ ast_feature_extractor.rs (180 lines) - Pure functions for AST analysis - No side effects - High reusability - Testable in isolation ``` ## Testing ✅ Build succeeds: `cargo build --release` compiles cleanly ✅ Binary compatibility: Existing .hako files execute correctly ✅ No logic changes: Feature detection identical to previous implementation ## Metrics - Lines moved from router to new module: 75 - New module total: 180 lines (including tests and documentation) - Router.rs reduced by ~40% in feature detection code - New module rated ⭐⭐⭐⭐⭐ for reusability and independence ## Next Steps - Phase 193-2: CarrierInfo Builder Enhancement - Phase 193-3: Pattern Classification Improvement - Phase 194: Further pattern detection optimizations 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-06 03:30:03 +09:00
features,
pattern_kind,
fn_body: None, // Phase 200-C: Default to None
skeleton: None, // Phase 92 P0-2: Default to None
feat(joinir): Phase 188.3 - Pattern6 (NestedLoopMinimal) 選択ロジック実装 ## Phase 188.3 進捗: Phase 2 完了 (6/13 tasks) ### 実装完了 ✅ **Phase 1: Fixture作成** - apps/tests/phase1883_nested_minimal.hako 追加 - Add/Compare のみ(乗算なし) - 期待 exit code: 9 (3×3 nested loops) - 既存 lowering で fallback 動作確認 **Phase 2: 選択ロジック (SSOT)** - LoopPatternContext に step_tree_max_loop_depth フィールド追加 - choose_pattern_kind() に Pattern6 選択ロジック実装: 1. Cheap check (has_inner_loop) 2. StepTree 構築 (max_loop_depth 取得) 3. AST validation (is_pattern6_lowerable) - pattern6_nested_minimal.rs モジュール作成 (stub) - LOOP_PATTERNS に Pattern6 entry 追加 - **検証**: Pattern6 が正しく選択される ✅ ### 設計原則 (確認済み) 1. **Fail-Fast**: Pattern6 選択後は Ok(None) で逃げない 2. **outer 変数 write-back 検出 → validation false** (Phase 188.4+) 3. **最小実装**: inner local だけ、Pattern1 モデル二重化 4. **cfg! 依存なし**: production で動作 ### 検証結果 ``` [choose_pattern_kind] has_inner_loop=true [choose_pattern_kind] max_loop_depth=2 [choose_pattern_kind] is_pattern6_lowerable=true ✅ Pattern6 SELECTED! ``` Stub からの期待エラー: ``` [ERROR] ❌ [Pattern6] Nested loop lowering not yet implemented ``` ### 次: Phase 3 (Lowering 実装 - 推定4時間) 残りタスク: - Phase 3-1: AST 抽出ヘルパー - Phase 3-2: Validation ヘルパー - Phase 3-3: Continuation 生成 (outer_step, inner_step, k_inner_exit) - Phase 3-4: fixture が exit=9 を返すことを検証 ### 変更ファイル **新規**: - apps/tests/phase1883_nested_minimal.hako - src/mir/builder/control_flow/joinir/patterns/pattern6_nested_minimal.rs - docs/development/current/main/phases/phase-188.{1,2,3}/README.md **変更**: - src/mir/builder/control_flow/joinir/routing.rs (Pattern6 選択) - src/mir/builder/control_flow/joinir/patterns/router.rs (Context 拡張) - src/mir/builder/control_flow/joinir/patterns/mod.rs (module 宣言) 🎯 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-27 05:45:12 +09:00
step_tree_max_loop_depth: None, // Phase 188.3: Default to None
}
}
/// Phase 200-C: Create context with fn_body for capture analysis
pub(crate) fn with_fn_body(
condition: &'a ASTNode,
body: &'a [ASTNode],
func_name: &'a str,
debug: bool,
in_static_box: bool,
fn_body: &'a [ASTNode],
) -> Self {
let mut ctx = Self::new(condition, body, func_name, debug, in_static_box);
ctx.fn_body = Some(fn_body);
ctx
}
/// Phase 92 P0-2: Set skeleton (for canonicalizer integration)
#[allow(dead_code)]
pub(crate) fn with_skeleton(mut self, skeleton: &'a LoopSkeleton) -> Self {
self.skeleton = Some(skeleton);
self
}
}
feat(joinir): Phase 286 P2/P2.1/P2.2 - JoinIR Line Absorption (Pattern1/4 Plan化 PoC + hygiene) Phase 286 P2: Pattern4 (Loop with Continue) を Plan/Frag SSOT に移行 - DomainPlan::Pattern4Continue 追加 - PlanNormalizer::normalize_pattern4_continue() 実装(phi_bindings による PHI dst 優先参照) - Router integration(Plan line routing → legacy fallback) - Integration test PASS (output: 6), quick smoke 154/154 PASS Phase 286 P2.1: Pattern1 (SimpleWhile) を Plan/Frag SSOT に移行 - DomainPlan::Pattern1SimpleWhile 追加 - PlanNormalizer::normalize_pattern1_simple_while() 実装(4ブロック、1 PHI、phi_bindings 流用) - Router integration(Plan line routing → legacy fallback) - Integration test PASS (return: 3), quick smoke 154/154 PASS Phase 286 P2.2: hygiene(extractor重複排除 + router小整理) - extractor helper化: extract_loop_increment_plan を common_helpers.rs に統一 - Pattern1/Pattern4 が呼ぶだけに変更(重複排除 ~25行) - router helper化: lower_via_plan() を追加し Pattern6/7/4/1 で共用 - 3行パターン(normalize→verify→lower)を1関数に集約(ボイラープレート削減 ~40行) 成果物: - DomainPlan 2パターン新規追加(Pattern1SimpleWhile, Pattern4Continue) - Normalizer 2つの normalize 関数追加 - Router に Plan line ブロック追加 + lower_via_plan() helper - Extractor に extract_pattern1_plan() 追加 - Integration fixtures 2個 + smoke tests 2個 検証: - quick smoke: 154/154 PASS - integration: phase286_pattern1_frag_poc PASS, phase286_pattern4_frag_poc PASS - Plan line routing: route=plan strategy=extract で Pattern1/4 検出確認 🤖 Generated with Claude Code Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-26 02:03:22 +09:00
/// Phase 286 P2.2: Common helper for Plan line lowering
///
/// Extracts the common 3-line pattern used by Plan-based routing:
feat(joinir): Phase 286 P2/P2.1/P2.2 - JoinIR Line Absorption (Pattern1/4 Plan化 PoC + hygiene) Phase 286 P2: Pattern4 (Loop with Continue) を Plan/Frag SSOT に移行 - DomainPlan::Pattern4Continue 追加 - PlanNormalizer::normalize_pattern4_continue() 実装(phi_bindings による PHI dst 優先参照) - Router integration(Plan line routing → legacy fallback) - Integration test PASS (output: 6), quick smoke 154/154 PASS Phase 286 P2.1: Pattern1 (SimpleWhile) を Plan/Frag SSOT に移行 - DomainPlan::Pattern1SimpleWhile 追加 - PlanNormalizer::normalize_pattern1_simple_while() 実装(4ブロック、1 PHI、phi_bindings 流用) - Router integration(Plan line routing → legacy fallback) - Integration test PASS (return: 3), quick smoke 154/154 PASS Phase 286 P2.2: hygiene(extractor重複排除 + router小整理) - extractor helper化: extract_loop_increment_plan を common_helpers.rs に統一 - Pattern1/Pattern4 が呼ぶだけに変更(重複排除 ~25行) - router helper化: lower_via_plan() を追加し Pattern6/7/4/1 で共用 - 3行パターン(normalize→verify→lower)を1関数に集約(ボイラープレート削減 ~40行) 成果物: - DomainPlan 2パターン新規追加(Pattern1SimpleWhile, Pattern4Continue) - Normalizer 2つの normalize 関数追加 - Router に Plan line ブロック追加 + lower_via_plan() helper - Extractor に extract_pattern1_plan() 追加 - Integration fixtures 2個 + smoke tests 2個 検証: - quick smoke: 154/154 PASS - integration: phase286_pattern1_frag_poc PASS, phase286_pattern4_frag_poc PASS - Plan line routing: route=plan strategy=extract で Pattern1/4 検出確認 🤖 Generated with Claude Code Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-26 02:03:22 +09:00
/// 1. Normalize DomainPlan → CorePlan
/// 2. Verify CorePlan invariants (fail-fast)
/// 3. Lower CorePlan → MIR
///
/// This eliminates repetition across 4 pattern routing blocks.
fn lower_via_plan(
builder: &mut MirBuilder,
domain_plan: crate::mir::builder::control_flow::plan::DomainPlan,
ctx: &LoopPatternContext,
) -> Result<Option<ValueId>, String> {
let core_plan = PlanNormalizer::normalize(builder, domain_plan, ctx)?;
PlanVerifier::verify(&core_plan)?;
PlanLowerer::lower(builder, core_plan, ctx)
}
// Phase 29ai P5: Plan extractor routing moved to `plan::single_planner`.
/// Route loop patterns via plan/composer SSOT.
refactor(joinir): Box-First cleanup - trace unification + SSOT + Fail-Fast ## Changes ### 1. eprintln! to trace.rs unification **File**: src/mir/builder/control_flow/joinir/routing.rs - Replaced direct eprintln! with trace::trace().routing() - Box-First principle: Log responsibility centralized in trace.rs - Enables filtering via HAKO_JOINIR_DEBUG=1 ### 2. Priority field removal (SSOT) **File**: src/mir/builder/control_flow/joinir/patterns/router.rs - Removed #[allow(dead_code)] priority field - Array order is SSOT (Single Source of Truth) for pattern priority - Pattern try order: Pattern5 → Pattern4 → Pattern3 → Pattern1 → Pattern2 - Eliminated dead code warning ### 3. catch_unwind removal (Fail-Fast) **File**: src/mir/builder/control_flow/joinir/routing_legacy_binding.rs - Removed catch_unwind + Ok(None) silent error swallowing - Fail-Fast principle: Panics propagate explicitly - Enables early detection of panic sources ## Verification ✅ Build: cargo build --release (0 errors) ✅ Tests: 71 JoinIR tests all PASS ✅ VM: /tmp/p1_return_i.hako → Result: 3 ✅ LLVM: /tmp/p1_return_i.hako → Mock exit code: 0 ## Design Principles Applied - **Box-First**: Log responsibility → trace.rs - **SSOT**: Array order defines priority (no redundant field) - **Fail-Fast**: Explicit failures, no silent error swallowing ## Statistics - 3 files changed - 53 deletions, 28 insertions - Net: -25 lines (code reduction) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-15 03:27:47 +09:00
///
/// Returns Ok(Some(value_id)) if a plan matched and lowered successfully.
/// Returns Ok(None) if no plan matched.
/// Returns Err if a plan matched but lowering failed.
feat(joinir): Phase 194 - Table-driven loop pattern router Replace if/else chain with table-driven pattern dispatch for easier pattern addition and maintenance. # Changes ## New Files - router.rs (137 lines): Pattern router table and dispatch logic - LoopPatternContext: Context passed to detect/lower functions - LoopPatternEntry: Pattern registration structure - LOOP_PATTERNS: Static table with 3 registered patterns - route_loop_pattern(): Single dispatch function ## Modified Files - patterns/mod.rs (+8 lines): Export router module - pattern1_minimal.rs (+19 lines): Added can_lower() + lower() wrapper - pattern2_with_break.rs (+17 lines): Added can_lower() + lower() wrapper - pattern3_with_if_phi.rs (+22 lines): Added can_lower() + lower() wrapper - routing.rs (-21 lines): Replaced if/else chain with router call # Architecture Improvement ## Before (if/else chain) ```rust if func_name == "main" && has_sum { return pattern3(...); } else if func_name == "main" { return pattern1(...); } else if func_name == "JoinIrMin.main/0" { return pattern2(...); } ``` ## After (table-driven) ```rust let ctx = LoopPatternContext::new(...); route_loop_pattern(self, &ctx)? ``` # Adding New Patterns (Now Trivial!) 1. Create pattern4_your_name.rs 2. Implement can_lower() + lower() 3. Add entry to LOOP_PATTERNS table That's it! No routing logic changes needed. # Testing ✅ Pattern 1 (loop_min_while.hako): PASSED ✅ Pattern 2 (joinir_min_loop.hako): PASSED ✅ Pattern 3 (loop_if_phi.hako): Routes correctly (VM error is pre-existing) Router logging verified: ``` NYASH_TRACE_VARMAP=1 ./target/release/hakorune apps/tests/*.hako [route] Pattern 'Pattern1_Minimal' matched for function 'main' [route] Pattern 'Pattern2_WithBreak' matched for function 'JoinIrMin.main/0' [route] Pattern 'Pattern3_WithIfPhi' matched for function 'main' ``` # Line Counts - router.rs: 137 lines (new) - Total pattern files: 491 lines (3 patterns) - routing.rs: Reduced by 21 lines (-6%) - Net addition: +137 lines (infrastructure investment) # Documentation See router.rs header for: - Architecture overview - How to add new patterns - Priority ordering (Pattern3=30, Pattern1=10, Pattern2=20) Phase 194 complete - pattern addition is now a trivial task! 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 22:11:39 +09:00
///
/// # Router Architecture (Plan/Composer SSOT)
refactor(joinir): Phase 193-1 - AST Feature Extractor Box modularization **Phase 193-1**: Create independent AST Feature Extractor Box module ## Summary Extracted feature detection logic from router.rs into a new, reusable ast_feature_extractor.rs module. This improves: - **Modularity**: Feature extraction is now a pure, side-effect-free module - **Reusability**: Can be used for Pattern 5-6 detection and analysis tools - **Testability**: Pure functions can be unit tested independently - **Maintainability**: Clear separation of concerns (router does dispatch, extractor does analysis) ## Changes ### New Files - **src/mir/builder/control_flow/joinir/patterns/ast_feature_extractor.rs** (+180 lines) - `detect_continue_in_body()`: Detect continue statements - `detect_break_in_body()`: Detect break statements - `extract_features()`: Full feature extraction pipeline - `detect_if_else_phi_in_body()`: Pattern detection for if-else PHI - `count_carriers_in_body()`: Heuristic carrier counting - Unit tests for basic functionality ### Modified Files - **src/mir/builder/control_flow/joinir/patterns/router.rs** - Removed 75 lines of feature detection code - Now delegates to `ast_features::` module - Phase 193 documentation in comments - Cleaner separation of concerns - **src/mir/builder/control_flow/joinir/patterns/mod.rs** - Added module declaration for ast_feature_extractor - Updated documentation with Phase 193 info ## Architecture ``` router.rs (10 lines) └─→ ast_feature_extractor.rs (180 lines) - Pure functions for AST analysis - No side effects - High reusability - Testable in isolation ``` ## Testing ✅ Build succeeds: `cargo build --release` compiles cleanly ✅ Binary compatibility: Existing .hako files execute correctly ✅ No logic changes: Feature detection identical to previous implementation ## Metrics - Lines moved from router to new module: 75 - New module total: 180 lines (including tests and documentation) - Router.rs reduced by ~40% in feature detection code - New module rated ⭐⭐⭐⭐⭐ for reusability and independence ## Next Steps - Phase 193-2: CarrierInfo Builder Enhancement - Phase 193-3: Pattern Classification Improvement - Phase 194: Further pattern detection optimizations 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-06 03:30:03 +09:00
///
/// The plan line (Extractor → Normalizer → Verifier → Lowerer) is the
/// operational SSOT for loop routing (Phase 273+).
docs(plan): Phase 273 P4 - Plan Line SSOT Documentation Finalization Phase 273 P4 では、Plan ライン(Extractor → Normalizer → Verifier → Lowerer)を "current operational SSOT" として文書化し、アーキテクチャの収束を明文化した。 ## Changes ### router.rs docstring 更新 - "Phase 273 P3: Plan Line is Current SSOT for Pattern6/7" セクション追加 - ルーティング戦略を明示(Plan entry points → legacy table) - SSOT Entry Points を列挙(Pattern6/7 Normalizer, Pattern1-5 各 Lowerer) ### phase-273/README.md 更新 - P3 completion section 追加(generalized CoreLoopPlan 移行完了) - P3+ Legacy Removal section 追加(~174 lines 削除記録) - P4 Proposal section 追加(Documentation Finalization チェックリスト) - SSOT Documentation Entry Points リスト追加(5 つの SSOT 入口) ### joinir-architecture-overview.md 更新 - Section 2.1.2 "Plan-Based Patterns (Pattern6-7, Phase 273 P3)" 追加 - Plan Extractor, Normalizer, Verifier, Lowerer の Box 構造を文書化 - Plan line vs JoinIR line 比較表追加(収束性・SSOT 特性の対比) - SSOT characteristics リスト追加(Normalizer SSOT, emit_frag SSOT 等) ## SSOT Entry Points(Phase 273 P3 完了時点) 1. **ルーティング**: `router.rs::route_loop_pattern()` - Pattern6/7 Plan entry points 2. **型定義**: `plan/mod.rs` - DomainPlan/CorePlan 固定語彙 3. **正規化**: `plan/normalizer.rs` - Pattern 固有知識一元管理 4. **検証**: `plan/verifier.rs` - fail-fast 不変条件(V2-V9) 5. **降格**: `plan/lowerer.rs` - Pattern-agnostic MIR emission ## Test - ✅ VM regression: phase254_p0_index_of_vm.sh (PASS) - ✅ LLVM regression: phase258_p0_index_of_string_llvm_exe.sh (PASS) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-23 00:34:38 +09:00
///
/// Plan-based architecture (Phase 273 P1-P3):
/// - extract_*_plan() → DomainPlan (pure extraction, no builder)
/// - PlanNormalizer::normalize() → CorePlan (pattern knowledge expansion, SSOT)
/// - PlanVerifier::verify() → fail-fast validation
docs(plan): Phase 273 P4 - Plan Line SSOT Documentation Finalization Phase 273 P4 では、Plan ライン(Extractor → Normalizer → Verifier → Lowerer)を "current operational SSOT" として文書化し、アーキテクチャの収束を明文化した。 ## Changes ### router.rs docstring 更新 - "Phase 273 P3: Plan Line is Current SSOT for Pattern6/7" セクション追加 - ルーティング戦略を明示(Plan entry points → legacy table) - SSOT Entry Points を列挙(Pattern6/7 Normalizer, Pattern1-5 各 Lowerer) ### phase-273/README.md 更新 - P3 completion section 追加(generalized CoreLoopPlan 移行完了) - P3+ Legacy Removal section 追加(~174 lines 削除記録) - P4 Proposal section 追加(Documentation Finalization チェックリスト) - SSOT Documentation Entry Points リスト追加(5 つの SSOT 入口) ### joinir-architecture-overview.md 更新 - Section 2.1.2 "Plan-Based Patterns (Pattern6-7, Phase 273 P3)" 追加 - Plan Extractor, Normalizer, Verifier, Lowerer の Box 構造を文書化 - Plan line vs JoinIR line 比較表追加(収束性・SSOT 特性の対比) - SSOT characteristics リスト追加(Normalizer SSOT, emit_frag SSOT 等) ## SSOT Entry Points(Phase 273 P3 完了時点) 1. **ルーティング**: `router.rs::route_loop_pattern()` - Pattern6/7 Plan entry points 2. **型定義**: `plan/mod.rs` - DomainPlan/CorePlan 固定語彙 3. **正規化**: `plan/normalizer.rs` - Pattern 固有知識一元管理 4. **検証**: `plan/verifier.rs` - fail-fast 不変条件(V2-V9) 5. **降格**: `plan/lowerer.rs` - Pattern-agnostic MIR emission ## Test - ✅ VM regression: phase254_p0_index_of_vm.sh (PASS) - ✅ LLVM regression: phase258_p0_index_of_string_llvm_exe.sh (PASS) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-23 00:34:38 +09:00
/// - PlanLowerer::lower() → MIR emission (pattern-agnostic, emit_frag SSOT)
///
/// SSOT Entry Points:
/// - Pattern6: src/mir/builder/control_flow/plan/normalizer.rs (ScanWithInit normalization)
/// - Pattern7: src/mir/builder/control_flow/plan/normalizer.rs (SplitScan normalization)
pub(crate) fn route_loop_pattern(
feat(joinir): Phase 194 - Table-driven loop pattern router Replace if/else chain with table-driven pattern dispatch for easier pattern addition and maintenance. # Changes ## New Files - router.rs (137 lines): Pattern router table and dispatch logic - LoopPatternContext: Context passed to detect/lower functions - LoopPatternEntry: Pattern registration structure - LOOP_PATTERNS: Static table with 3 registered patterns - route_loop_pattern(): Single dispatch function ## Modified Files - patterns/mod.rs (+8 lines): Export router module - pattern1_minimal.rs (+19 lines): Added can_lower() + lower() wrapper - pattern2_with_break.rs (+17 lines): Added can_lower() + lower() wrapper - pattern3_with_if_phi.rs (+22 lines): Added can_lower() + lower() wrapper - routing.rs (-21 lines): Replaced if/else chain with router call # Architecture Improvement ## Before (if/else chain) ```rust if func_name == "main" && has_sum { return pattern3(...); } else if func_name == "main" { return pattern1(...); } else if func_name == "JoinIrMin.main/0" { return pattern2(...); } ``` ## After (table-driven) ```rust let ctx = LoopPatternContext::new(...); route_loop_pattern(self, &ctx)? ``` # Adding New Patterns (Now Trivial!) 1. Create pattern4_your_name.rs 2. Implement can_lower() + lower() 3. Add entry to LOOP_PATTERNS table That's it! No routing logic changes needed. # Testing ✅ Pattern 1 (loop_min_while.hako): PASSED ✅ Pattern 2 (joinir_min_loop.hako): PASSED ✅ Pattern 3 (loop_if_phi.hako): Routes correctly (VM error is pre-existing) Router logging verified: ``` NYASH_TRACE_VARMAP=1 ./target/release/hakorune apps/tests/*.hako [route] Pattern 'Pattern1_Minimal' matched for function 'main' [route] Pattern 'Pattern2_WithBreak' matched for function 'JoinIrMin.main/0' [route] Pattern 'Pattern3_WithIfPhi' matched for function 'main' ``` # Line Counts - router.rs: 137 lines (new) - Total pattern files: 491 lines (3 patterns) - routing.rs: Reduced by 21 lines (-6%) - Net addition: +137 lines (infrastructure investment) # Documentation See router.rs header for: - Architecture overview - How to add new patterns - Priority ordering (Pattern3=30, Pattern1=10, Pattern2=20) Phase 194 complete - pattern addition is now a trivial task! 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 22:11:39 +09:00
builder: &mut MirBuilder,
ctx: &LoopPatternContext,
) -> Result<Option<ValueId>, String> {
feat(joinir): Phase 195 - Unified JoinLoopTrace for all JoinIR debug output Created centralized tracing module for JoinIR loop lowering operations, consolidating scattered eprintln! calls into a single SSOT interface. # Implementation 1. **Created trace.rs module** (~233 lines) - JoinLoopTrace struct with env var controls - Unified API: pattern(), varmap(), joinir_stats(), phi(), merge(), etc. - Global singleton via trace() function - Supports 5 env vars: NYASH_TRACE_VARMAP, NYASH_JOINIR_DEBUG, NYASH_OPTION_C_DEBUG, NYASH_JOINIR_MAINLINE_DEBUG, NYASH_LOOPFORM_DEBUG 2. **Updated debug.rs** - Delegates trace_varmap() to JoinLoopTrace 3. **Updated routing.rs** - All eprintln! replaced with trace calls (10 instances) 4. **Updated pattern routers** - All 3 patterns now use unified trace - pattern1_minimal.rs: 6 replacements - pattern2_with_break.rs: 6 replacements - pattern3_with_if_phi.rs: 6 replacements - router.rs: 2 replacements 5. **Updated merge/block_allocator.rs** - 6 eprintln! → trace calls # Benefits - **Single Source of Truth**: All trace control through environment variables - **Consistent Format**: Unified [trace:*] prefix for easy filtering - **Zero Overhead**: No output when env vars unset - **Easy Extension**: Add new trace points via existing API - **Better Debug Experience**: Structured output with clear categories # Testing ✅ cargo build --release - Success ✅ NYASH_TRACE_VARMAP=1 - Shows varmap traces only ✅ NYASH_JOINIR_DEBUG=1 - Shows joinir + blocks + routing traces ✅ No env vars - No debug output ✅ apps/tests/loop_min_while.hako - All tests pass # Related - Phase 191-194 groundwork (modular merge structure) - NYASH_TRACE_VARMAP added today for variable_map debugging - Consolidates ~80 scattered eprintln! calls across JoinIR 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 22:23:51 +09:00
use super::super::trace;
// Phase 29ai P5: Single entrypoint for plan extraction (router has no rule table).
let (domain_plan, outcome) = single_planner::try_build_domain_plan_with_outcome(ctx)?;
let strict_or_dev = crate::config::env::joinir_dev::strict_enabled()
|| crate::config::env::joinir_dev_enabled();
if strict_or_dev {
if let Some(adopt) = composer::try_shadow_adopt_nested_minimal(builder, ctx, &outcome)? {
let composer::ShadowAdoptOutcome { core_plan, tag } = adopt;
PlanVerifier::verify(&core_plan)?;
eprintln!("{}", tag);
return PlanLowerer::lower(builder, core_plan, ctx);
}
if let Some(err) = composer::strict_nested_loop_guard(&outcome, ctx) {
eprintln!("{}", err);
return Err(err);
}
}
if !strict_or_dev {
if let Some(core_plan) =
composer::try_release_adopt_nested_minimal(builder, ctx, &outcome)?
{
PlanVerifier::verify(&core_plan)?;
return PlanLowerer::lower(builder, core_plan, ctx);
}
}
if let Some(domain_plan) = domain_plan {
if let Some(adopt) = composer::try_shadow_adopt_core_plan(
builder,
ctx,
strict_or_dev,
&domain_plan,
&outcome,
)? {
let composer::ShadowAdoptOutcome { core_plan, tag } = adopt;
PlanVerifier::verify(&core_plan)?;
eprintln!("{}", tag);
return PlanLowerer::lower(builder, core_plan, ctx);
}
if !strict_or_dev {
if let Some(core_plan) =
composer::try_release_adopt_core_plan(builder, ctx, &domain_plan, &outcome)?
{
PlanVerifier::verify(&core_plan)?;
return PlanLowerer::lower(builder, core_plan, ctx);
}
}
return lower_via_plan(builder, domain_plan, ctx);
feat(joinir): Phase 286 P2/P2.1/P2.2 - JoinIR Line Absorption (Pattern1/4 Plan化 PoC + hygiene) Phase 286 P2: Pattern4 (Loop with Continue) を Plan/Frag SSOT に移行 - DomainPlan::Pattern4Continue 追加 - PlanNormalizer::normalize_pattern4_continue() 実装(phi_bindings による PHI dst 優先参照) - Router integration(Plan line routing → legacy fallback) - Integration test PASS (output: 6), quick smoke 154/154 PASS Phase 286 P2.1: Pattern1 (SimpleWhile) を Plan/Frag SSOT に移行 - DomainPlan::Pattern1SimpleWhile 追加 - PlanNormalizer::normalize_pattern1_simple_while() 実装(4ブロック、1 PHI、phi_bindings 流用) - Router integration(Plan line routing → legacy fallback) - Integration test PASS (return: 3), quick smoke 154/154 PASS Phase 286 P2.2: hygiene(extractor重複排除 + router小整理) - extractor helper化: extract_loop_increment_plan を common_helpers.rs に統一 - Pattern1/Pattern4 が呼ぶだけに変更(重複排除 ~25行) - router helper化: lower_via_plan() を追加し Pattern6/7/4/1 で共用 - 3行パターン(normalize→verify→lower)を1関数に集約(ボイラープレート削減 ~40行) 成果物: - DomainPlan 2パターン新規追加(Pattern1SimpleWhile, Pattern4Continue) - Normalizer 2つの normalize 関数追加 - Router に Plan line ブロック追加 + lower_via_plan() helper - Extractor に extract_pattern1_plan() 追加 - Integration fixtures 2個 + smoke tests 2個 検証: - quick smoke: 154/154 PASS - integration: phase286_pattern1_frag_poc PASS, phase286_pattern4_frag_poc PASS - Plan line routing: route=plan strategy=extract で Pattern1/4 検出確認 🤖 Generated with Claude Code Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-26 02:03:22 +09:00
}
// No pattern matched - return None (caller will handle error)
feat(joinir): Phase 194 - Table-driven loop pattern router Replace if/else chain with table-driven pattern dispatch for easier pattern addition and maintenance. # Changes ## New Files - router.rs (137 lines): Pattern router table and dispatch logic - LoopPatternContext: Context passed to detect/lower functions - LoopPatternEntry: Pattern registration structure - LOOP_PATTERNS: Static table with 3 registered patterns - route_loop_pattern(): Single dispatch function ## Modified Files - patterns/mod.rs (+8 lines): Export router module - pattern1_minimal.rs (+19 lines): Added can_lower() + lower() wrapper - pattern2_with_break.rs (+17 lines): Added can_lower() + lower() wrapper - pattern3_with_if_phi.rs (+22 lines): Added can_lower() + lower() wrapper - routing.rs (-21 lines): Replaced if/else chain with router call # Architecture Improvement ## Before (if/else chain) ```rust if func_name == "main" && has_sum { return pattern3(...); } else if func_name == "main" { return pattern1(...); } else if func_name == "JoinIrMin.main/0" { return pattern2(...); } ``` ## After (table-driven) ```rust let ctx = LoopPatternContext::new(...); route_loop_pattern(self, &ctx)? ``` # Adding New Patterns (Now Trivial!) 1. Create pattern4_your_name.rs 2. Implement can_lower() + lower() 3. Add entry to LOOP_PATTERNS table That's it! No routing logic changes needed. # Testing ✅ Pattern 1 (loop_min_while.hako): PASSED ✅ Pattern 2 (joinir_min_loop.hako): PASSED ✅ Pattern 3 (loop_if_phi.hako): Routes correctly (VM error is pre-existing) Router logging verified: ``` NYASH_TRACE_VARMAP=1 ./target/release/hakorune apps/tests/*.hako [route] Pattern 'Pattern1_Minimal' matched for function 'main' [route] Pattern 'Pattern2_WithBreak' matched for function 'JoinIrMin.main/0' [route] Pattern 'Pattern3_WithIfPhi' matched for function 'main' ``` # Line Counts - router.rs: 137 lines (new) - Total pattern files: 491 lines (3 patterns) - routing.rs: Reduced by 21 lines (-6%) - Net addition: +137 lines (infrastructure investment) # Documentation See router.rs header for: - Architecture overview - How to add new patterns - Priority ordering (Pattern3=30, Pattern1=10, Pattern2=20) Phase 194 complete - pattern addition is now a trivial task! 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 22:11:39 +09:00
if ctx.debug {
trace::trace().debug(
"route",
&format!(
"route=none (no pattern matched) func='{}' pattern_kind={:?} (exhausted: plan+joinir)",
ctx.func_name, ctx.pattern_kind
),
);
feat(joinir): Phase 194 - Table-driven loop pattern router Replace if/else chain with table-driven pattern dispatch for easier pattern addition and maintenance. # Changes ## New Files - router.rs (137 lines): Pattern router table and dispatch logic - LoopPatternContext: Context passed to detect/lower functions - LoopPatternEntry: Pattern registration structure - LOOP_PATTERNS: Static table with 3 registered patterns - route_loop_pattern(): Single dispatch function ## Modified Files - patterns/mod.rs (+8 lines): Export router module - pattern1_minimal.rs (+19 lines): Added can_lower() + lower() wrapper - pattern2_with_break.rs (+17 lines): Added can_lower() + lower() wrapper - pattern3_with_if_phi.rs (+22 lines): Added can_lower() + lower() wrapper - routing.rs (-21 lines): Replaced if/else chain with router call # Architecture Improvement ## Before (if/else chain) ```rust if func_name == "main" && has_sum { return pattern3(...); } else if func_name == "main" { return pattern1(...); } else if func_name == "JoinIrMin.main/0" { return pattern2(...); } ``` ## After (table-driven) ```rust let ctx = LoopPatternContext::new(...); route_loop_pattern(self, &ctx)? ``` # Adding New Patterns (Now Trivial!) 1. Create pattern4_your_name.rs 2. Implement can_lower() + lower() 3. Add entry to LOOP_PATTERNS table That's it! No routing logic changes needed. # Testing ✅ Pattern 1 (loop_min_while.hako): PASSED ✅ Pattern 2 (joinir_min_loop.hako): PASSED ✅ Pattern 3 (loop_if_phi.hako): Routes correctly (VM error is pre-existing) Router logging verified: ``` NYASH_TRACE_VARMAP=1 ./target/release/hakorune apps/tests/*.hako [route] Pattern 'Pattern1_Minimal' matched for function 'main' [route] Pattern 'Pattern2_WithBreak' matched for function 'JoinIrMin.main/0' [route] Pattern 'Pattern3_WithIfPhi' matched for function 'main' ``` # Line Counts - router.rs: 137 lines (new) - Total pattern files: 491 lines (3 patterns) - routing.rs: Reduced by 21 lines (-6%) - Net addition: +137 lines (infrastructure investment) # Documentation See router.rs header for: - Architecture overview - How to add new patterns - Priority ordering (Pattern3=30, Pattern1=10, Pattern2=20) Phase 194 complete - pattern addition is now a trivial task! 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 22:11:39 +09:00
}
Ok(None)
}