refactor(joinir): boxify Pattern2 routing and schedule facts
This commit is contained in:
@ -55,6 +55,23 @@
|
||||
|
||||
---
|
||||
|
||||
### loop_true_read_digits_policy.rs (Phase 104/105)
|
||||
**現在の場所**: `patterns/policies/loop_true_read_digits_policy.rs`
|
||||
|
||||
**責務**: `loop(true)` + break-only digits(`read_digits_from` family)の認識とルーティング
|
||||
|
||||
**判断基準**:
|
||||
- `loop(true)` である
|
||||
- read-digits(loop(true)) detector に一致する
|
||||
- `ReadDigitsBreakConditionBox` が eos 条件 + digit 条件を抽出できる
|
||||
|
||||
**出力**:
|
||||
- `PolicyDecision::Use(LoopTrueReadDigitsPolicyResult)` - `break_when_true := (ch == \"\") || !(digit_cond)` と `ch` allow-list
|
||||
- `PolicyDecision::Reject(String)` - 検出失敗理由(Fail-Fast)
|
||||
- `PolicyDecision::None` - 該当なし
|
||||
|
||||
---
|
||||
|
||||
### body_local_policy.rs
|
||||
**現在の場所**: `patterns/body_local_policy.rs`
|
||||
|
||||
|
||||
@ -0,0 +1,61 @@
|
||||
//! loop(true) + break-only digits (read_digits_from family) policy
|
||||
//!
|
||||
//! Goal: keep Pattern2 core lowering structural by moving shape recognition + routing
|
||||
//! for loop(true) read-digits family into a dedicated policy box.
|
||||
//!
|
||||
//! This policy is intentionally narrow:
|
||||
//! - It only triggers when the body matches the read-digits(loop(true)) detector.
|
||||
//! - It returns a normalized "break when true" condition AST:
|
||||
//! `break_when_true := (ch == "") || !(digit_cond)`
|
||||
//! - It provides the single allowed body-local variable name (`ch`) for condition lowering.
|
||||
|
||||
use super::PolicyDecision;
|
||||
use crate::ast::{ASTNode, BinaryOperator, Span, UnaryOperator};
|
||||
|
||||
pub(crate) struct LoopTrueReadDigitsPolicyResult {
|
||||
pub break_condition_node: ASTNode,
|
||||
pub allowed_ch_var: String,
|
||||
}
|
||||
|
||||
pub(crate) fn classify_loop_true_read_digits(
|
||||
condition: &ASTNode,
|
||||
body: &[ASTNode],
|
||||
) -> PolicyDecision<LoopTrueReadDigitsPolicyResult> {
|
||||
use crate::mir::builder::control_flow::joinir::patterns::{
|
||||
ast_feature_extractor::detect_read_digits_loop_true_pattern,
|
||||
loop_true_counter_extractor::LoopTrueCounterExtractorBox,
|
||||
read_digits_break_condition_box::ReadDigitsBreakConditionBox,
|
||||
};
|
||||
|
||||
if !LoopTrueCounterExtractorBox::is_loop_true(condition) {
|
||||
return PolicyDecision::None;
|
||||
}
|
||||
if detect_read_digits_loop_true_pattern(body).is_none() {
|
||||
return PolicyDecision::None;
|
||||
}
|
||||
|
||||
let (ch_var, eos_cond, digit_cond) =
|
||||
match ReadDigitsBreakConditionBox::extract_eos_and_digit_condition(body) {
|
||||
Ok(v) => v,
|
||||
Err(e) => return PolicyDecision::Reject(e),
|
||||
};
|
||||
|
||||
let break_on_not_digit = ASTNode::UnaryOp {
|
||||
operator: UnaryOperator::Not,
|
||||
operand: Box::new(digit_cond),
|
||||
span: Span::unknown(),
|
||||
};
|
||||
|
||||
let break_when_true = ASTNode::BinaryOp {
|
||||
operator: BinaryOperator::Or,
|
||||
left: Box::new(eos_cond),
|
||||
right: Box::new(break_on_not_digit),
|
||||
span: Span::unknown(),
|
||||
};
|
||||
|
||||
PolicyDecision::Use(LoopTrueReadDigitsPolicyResult {
|
||||
break_condition_node: break_when_true,
|
||||
allowed_ch_var: ch_var,
|
||||
})
|
||||
}
|
||||
|
||||
@ -32,3 +32,4 @@ pub enum PolicyDecision<T> {
|
||||
|
||||
pub(in crate::mir::builder) mod p5b_escape_derived_policy;
|
||||
pub(in crate::mir::builder) mod trim_policy;
|
||||
pub(in crate::mir::builder) mod loop_true_read_digits_policy;
|
||||
|
||||
Reference in New Issue
Block a user