feat(joinir): Phase 224-E - DigitPos condition normalization

Add DigitPosConditionNormalizer to transform integer comparison to boolean:
- `digit_pos < 0` → `!is_digit_pos`

This eliminates the type error caused by comparing Bool carrier with Integer:
- Before: Bool(is_digit_pos) < Integer(0) → Type error
- After: !is_digit_pos → Boolean expression, no type mismatch

Implementation:
- New Box: digitpos_condition_normalizer.rs (173 lines)
- Pattern2 integration: normalize after promotion success
- 5 unit tests (all pass)
- E2E test passes (type error eliminated)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-12-10 22:10:28 +09:00
parent 38e810d071
commit b07329b37f
6 changed files with 506 additions and 7 deletions

View File

@ -240,7 +240,7 @@ impl MirBuilder {
// Wrap condition in UnaryOp Not if break is in else clause
use crate::ast::UnaryOperator;
let break_condition_node = if break_in_else {
let mut break_condition_node = if break_in_else {
// Extract span from the raw condition node (use unknown as default)
let span = crate::ast::Span::unknown();
@ -328,6 +328,21 @@ impl MirBuilder {
));
}
}
// Phase 224-E: Normalize digit_pos condition before lowering
// Transform: digit_pos < 0 → !is_digit_pos
use crate::mir::join_ir::lowering::digitpos_condition_normalizer::DigitPosConditionNormalizer;
break_condition_node = DigitPosConditionNormalizer::normalize(
&break_condition_node,
&promoted_var,
&carrier_name,
);
eprintln!(
"[pattern2/phase224e] Normalized break condition for promoted variable '{}' → carrier '{}'",
promoted_var, carrier_name
);
// Carrier promoted and merged, proceed with normal lowering
}
ConditionPromotionResult::CannotPromote { reason, vars } => {