3ef929df53
docs(normalization): Update README for Phase 142 P0
...
- Document statement-level normalization unit change
- Add Phase 142 P0 section to Pattern Detection
- Mark Phase 132-135 patterns as LEGACY
- Update suffix_router description
- Clarify LoopWithPost deprecation status
Phase 142 P0: Normalization unit changed from "block suffix" to "statement"
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com >
2025-12-19 04:40:35 +09:00
aaba27d311
refactor(normalization): Deprecate LoopWithPost variant
...
- Mark LoopWithPost enum variant as deprecated (Phase 142 P0)
- Add deprecation to loop_with_post() constructor function
- Document migration path to LoopOnly
- Keep for backward compatibility until full migration
Phase 142 P0: Statement-level normalization makes LoopWithPost obsolete
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com >
2025-12-19 04:39:25 +09:00
1742f0412e
feat(normalized): Phase 141 P1.5 - external env inputs + KnownIntrinsic SSOT
...
## Task B: External env input bug fix (Priority 1)
Fix: Suffix normalization couldn't access prefix-built local variables
**Problem**: `s.length()` failed because 's' (from prefix `s = "abc"`) was
not in available_inputs during suffix normalization.
**Root cause**: `AvailableInputsCollectorBox::collect()` only collected
function params and CapturedEnv, missing `builder.variable_map`.
**Solution**: Add `prefix_variables` parameter with 3-source merge:
1. Function params (highest priority)
2. Prefix variables (medium priority - NEW)
3. CapturedEnv (lowest priority)
**Changed files**:
- src/mir/control_tree/normalized_shadow/available_inputs_collector.rs
- src/mir/builder/control_flow/normalization/execute_box.rs
- src/mir/builder/control_flow/joinir/patterns/policies/normalized_shadow_suffix_router_box.rs
- src/mir/builder/control_flow/joinir/routing.rs
- src/mir/builder/stmts.rs
- src/mir/control_tree/normalized_shadow/dev_pipeline.rs
- docs/development/current/main/design/normalized-expr-lowering.md (Available Inputs SSOT section)
**Tests**: 3 new unit tests (prefix merge, priority order)
## Task A: KnownIntrinsic SSOT化 (Priority 2)
Eliminate string literal scattered matching by centralizing to registry.
**Problem**: Adding new intrinsics required editing if/match chains with
hard-coded string literals (`if method == KnownIntrinsic::Length0.method_name()`).
**Solution**: Create `KnownIntrinsicRegistryBox` as SSOT:
- `lookup(method, arity) -> Option<KnownIntrinsic>`
- `get_spec(intrinsic) -> KnownIntrinsicSpec`
- Adding new intrinsics now requires: (1) enum variant, (2) registry entry only
**Changed files**:
- src/mir/control_tree/normalized_shadow/common/known_intrinsics.rs (NEW)
- src/mir/control_tree/normalized_shadow/common/expr_lowerer_box.rs
- src/mir/control_tree/normalized_shadow/common/expr_lowering_contract.rs (deprecated methods removed)
- src/mir/control_tree/normalized_shadow/common/mod.rs
- docs/development/current/main/design/normalized-expr-lowering.md (Known Intrinsic SSOT section)
**Impact**: ~30% code reduction in intrinsic matching logic
## Task C: Better diagnostics (Priority 3)
Add `OutOfScopeReason::IntrinsicNotWhitelisted` for precise diagnostics.
**Changed files**:
- src/mir/control_tree/normalized_shadow/common/expr_lowering_contract.rs (enum variant)
- src/mir/control_tree/normalized_shadow/common/expr_lowerer_box.rs (diagnostic logic)
## Verification
✅ Build: `cargo build --release` - PASS
✅ Phase 97 regression: next_non_ws LLVM EXE - PASS
✅ Phase 131: loop(true) break-once VM - PASS
✅ Phase 136: return literal VM - PASS
✅ Phase 137: return x+2 VM - PASS
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com >
2025-12-19 03:59:41 +09:00
1264b3593d
fix(normalization): Tighten loop(true) gate to prevent loop(i<n) mismatch
...
Problem:
- Phase 97 LLVM EXE tests (next_non_ws, json_loader_escape) were failing
- NormalizationPlan accepted loop(i < n) but couldn't lower it
- Execute stage returned hard error instead of fallback
Root Cause:
- Plan stage only checked `ASTNode::Loop`, not condition
- loop(i < n) got Plan → Execute tried to normalize → error
- Should: loop(i < n) returns Ok(None) → fallback to Pattern2
Fix:
- Tighten gate in plan_box.rs (lines 50-71)
- Only accept loop(true) - literal Bool true
- loop(i < n) now returns Ok(None) → clean fallback
Added:
- Test: test_plan_block_suffix_no_match_loop_not_true()
- Verifies loop(i < n) returns None (not Plan)
Verification:
- Phase 97 next_non_ws LLVM EXE: PASS
- Phase 97 json_loader_escape LLVM EXE: PASS
- Phase 131/135/136/137 regression: all PASS
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com >
2025-12-19 00:15:51 +09:00
91c7dfbf0b
refactor(normalization): Phase 135 P0 - Extend plan to zero post-loop assigns
...
Generalize NormalizationPlan suffix detection to accept zero post-loop assignments:
Goal: Improve entry point consistency by allowing `loop + assign* + return` (N >= 0)
Implementation:
- Modified plan_box.rs detection logic (only file changed)
- Removed `post_assign_count >= 1` requirement
- Unified Phase 131 (loop + return) and Phase 132-133 (loop + assign+ + return) paths
Changes:
- src/mir/builder/control_flow/normalization/plan_box.rs:
- Removed assignment count constraint
- Unified pattern detection: `loop + assign* + return` (N >= 0)
- apps/tests/phase135_loop_true_break_once_post_empty_return_min.hako (new fixture)
- tools/smokes/v2/profiles/integration/apps/phase135_*.sh (new smoke tests)
Pattern support:
- Phase 131/135: loop + return only (consumed: 2, post_assign_count: 0) ✅
- Phase 132: loop + 1 assign + return (consumed: 3, post_assign_count: 1) ✅
- Phase 133: loop + N assigns + return (consumed: 2+N, post_assign_count: N) ✅
Design principles maintained:
- **Minimal change**: Only plan_box.rs modified (execute_box unchanged)
- **SSOT**: Detection logic centralized in plan_box.rs
- **Box-First**: Responsibility separation preserved (Plan/Execute)
Test results:
- Unit tests (plan_box): 9/9 PASS (2 new tests added)
- Phase 135 VM/LLVM EXE: PASS (exit code 1)
- Phase 131 regression: 2/2 PASS (path now unified)
- Phase 133 regression: 2/2 PASS
- cargo test --lib: PASS
Benefits:
- Unified entry point for all loop + post patterns
- Easier maintenance (single detection logic)
- Future extensibility (easy to add new patterns)
- Clear separation of Phase 131 and Phase 132-135 paths
Default behavior unchanged: Dev-only guard maintained
Related: Phase 135 normalization pattern consistency improvement
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com >
2025-12-18 22:46:32 +09:00
f4ab5ca5f4
refactor(control_flow): Phase 134 P0 - Normalization entry point SSOT
...
Consolidate dual entry points into unified NormalizationPlan system:
Problem:
- Dual entry points: try_normalized_shadow() + suffix_router_box
- ~220 lines of duplicated pattern detection logic
- Maintenance burden: changes required in two places
Solution:
- New normalization module with Box-First architecture
- NormalizationPlanBox: Single source of truth for pattern detection
- NormalizationExecuteBox: Single source of truth for execution
Implementation:
- src/mir/builder/control_flow/normalization/ (new module)
- README.md: Design contract (SSOT)
- plan.rs: NormalizationPlan data structure
- plan_box.rs: Pattern detection (7 unit tests)
- execute_box.rs: Execution logic
- mod.rs: Module integration
Refactored files:
- routing.rs::try_normalized_shadow(): 165 → 87 lines (-78 lines)
- suffix_router_box::try_lower_loop_suffix(): 258 → 116 lines (-142 lines)
Pattern support maintained:
- Phase 131: loop(true) only (consumed: 1)
- Phase 132: loop + single post (consumed: 3)
- Phase 133: loop + multiple post (consumed: 2+N)
Box-First principles:
- Plan Box: Detection responsibility only
- Execute Box: Execution responsibility only
- README.md: Contract documentation (SSOT)
- Clear separation enables independent testing
Test results:
- cargo test --lib: 1186 PASS (10 new tests added)
- Phase 133 VM/LLVM EXE: PASS (exit code 6)
- Phase 132 LLVM EXE: PASS (exit code 3)
- Phase 131 LLVM EXE: PASS (exit code 1)
Benefits:
- Code duplication eliminated (~220 lines)
- Single source of truth for normalization decisions
- Improved maintainability and testability
- Future-proof extensibility (easy to add new patterns)
Default behavior unchanged: Dev-only guard maintained
Related: Phase 134 normalization infrastructure improvement
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com >
2025-12-18 22:29:29 +09:00