feat(canonicalizer): Phase 143-P0 - parse_number pattern support
Add parse_number pattern recognition to canonicalizer, expanding adaptation
range for digit collection loops with break in THEN clause.
## Changes
### New Recognizer (ast_feature_extractor.rs)
- `detect_parse_number_pattern()`: Detects `if invalid { break }` pattern
- `ParseNumberInfo`: Struct for extracted pattern info
- ~150 lines added
### Canonicalizer Integration (canonicalizer.rs)
- Parse_number pattern detection before skip_whitespace
- LoopSkeleton construction with 4 steps (Header + Body x2 + Update)
- Routes to Pattern2Break (has_break=true)
- ~60 lines modified
### Export Chain (6 files)
- patterns/mod.rs → joinir/mod.rs → control_flow/mod.rs
- builder.rs → mir/mod.rs
- 8 lines total
### Tests
- `test_parse_number_pattern_recognized()`: Unit test for recognition
- Strict parity verification: GREEN (canonical and router agree)
- ~130 lines added
## Pattern Comparison
| Aspect | Skip Whitespace | Parse Number |
|--------|----------------|--------------|
| Break location | ELSE clause | THEN clause |
| Pattern | `if cond { update } else { break }` | `if invalid { break } rest... update` |
| Body after if | None | Required (result append) |
## Results
- ✅ Skeleton creation successful
- ✅ RoutingDecision matches router (Pattern2Break)
- ✅ Strict parity OK (canonicalizer ↔ router agreement)
- ✅ Unit test PASS
- ✅ Manual test: test_pattern2_parse_number.hako executes correctly
## Statistics
- New patterns: 1 (parse_number)
- Total patterns: 3 (skip_whitespace, parse_number, continue)
- Lines added: ~280
- Files modified: 8
- Parity status: Green ✅
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -4,7 +4,9 @@
|
||||
//! Provides backward-compatible wrappers for existing callsites.
|
||||
|
||||
use crate::ast::ASTNode;
|
||||
use crate::mir::{detect_skip_whitespace_pattern as ast_detect, SkipWhitespaceInfo};
|
||||
use crate::mir::detect_continue_pattern;
|
||||
use crate::mir::detect_parse_number_pattern as ast_detect_parse_number;
|
||||
use crate::mir::detect_skip_whitespace_pattern as ast_detect;
|
||||
|
||||
// ============================================================================
|
||||
// Skip Whitespace Pattern (Phase 140-P4-B SSOT Wrapper)
|
||||
@ -36,6 +38,81 @@ pub fn try_extract_skip_whitespace_pattern(
|
||||
ast_detect(body).map(|info| (info.carrier_name, info.delta, info.body_stmts))
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Parse Number Pattern (Phase 143-P0)
|
||||
// ============================================================================
|
||||
|
||||
/// Try to extract parse_number pattern from loop
|
||||
///
|
||||
/// Pattern structure:
|
||||
/// ```
|
||||
/// loop(cond) {
|
||||
/// // ... optional body statements (ch, digit_pos computation)
|
||||
/// if invalid_cond {
|
||||
/// break
|
||||
/// }
|
||||
/// // ... rest statements (result append, carrier update)
|
||||
/// carrier = carrier + const
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Returns (carrier_name, delta, body_stmts, rest_stmts) if pattern matches.
|
||||
///
|
||||
/// # Phase 143-P0: Parse Number Pattern Detection
|
||||
///
|
||||
/// This function delegates to `ast_feature_extractor::detect_parse_number_pattern`
|
||||
/// for SSOT implementation.
|
||||
pub fn try_extract_parse_number_pattern(
|
||||
body: &[ASTNode],
|
||||
) -> Option<(String, i64, Vec<ASTNode>, Vec<ASTNode>)> {
|
||||
ast_detect_parse_number(body).map(|info| {
|
||||
(
|
||||
info.carrier_name,
|
||||
info.delta,
|
||||
info.body_stmts,
|
||||
info.rest_stmts,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Continue Pattern (Phase 142-P1)
|
||||
// ============================================================================
|
||||
|
||||
/// Try to extract continue pattern from loop
|
||||
///
|
||||
/// Pattern structure:
|
||||
/// ```
|
||||
/// loop(cond) {
|
||||
/// // ... optional body statements (Body)
|
||||
/// if skip_cond {
|
||||
/// carrier = carrier + const // Optional update before continue
|
||||
/// continue
|
||||
/// }
|
||||
/// // ... rest of body statements (Rest)
|
||||
/// carrier = carrier + const // Carrier update
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Returns (carrier_name, delta, body_stmts, rest_stmts) if pattern matches.
|
||||
///
|
||||
/// # Phase 142-P1: Continue Pattern Detection
|
||||
///
|
||||
/// This function delegates to `ast_feature_extractor::detect_continue_pattern`
|
||||
/// for SSOT implementation.
|
||||
pub fn try_extract_continue_pattern(
|
||||
body: &[ASTNode],
|
||||
) -> Option<(String, i64, Vec<ASTNode>, Vec<ASTNode>)> {
|
||||
detect_continue_pattern(body).map(|info| {
|
||||
(
|
||||
info.carrier_name,
|
||||
info.delta,
|
||||
info.body_stmts,
|
||||
info.rest_stmts,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
Reference in New Issue
Block a user