refactor(mir): phase260 p0.1 strangler hardening + smoke fixtures
This commit is contained in:
@ -10,6 +10,8 @@
|
||||
//! silently fall back to an unrelated route.
|
||||
|
||||
use crate::ast::ASTNode;
|
||||
use crate::ast::UnaryOperator;
|
||||
use crate::ast::LiteralValue;
|
||||
use crate::mir::loop_pattern_detection::break_condition_analyzer::BreakConditionAnalyzer;
|
||||
|
||||
use super::policies::{loop_true_read_digits_policy, PolicyDecision};
|
||||
@ -24,6 +26,21 @@ pub(crate) struct Pattern2BreakConditionRouting {
|
||||
pub(crate) struct Pattern2BreakConditionPolicyRouterBox;
|
||||
|
||||
impl Pattern2BreakConditionPolicyRouterBox {
|
||||
fn negate_condition(condition: &ASTNode) -> ASTNode {
|
||||
match condition {
|
||||
ASTNode::UnaryOp {
|
||||
operator: UnaryOperator::Not,
|
||||
operand,
|
||||
..
|
||||
} => operand.as_ref().clone(),
|
||||
other => ASTNode::UnaryOp {
|
||||
operator: UnaryOperator::Not,
|
||||
operand: Box::new(other.clone()),
|
||||
span: other.span(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn route(condition: &ASTNode, body: &[ASTNode]) -> Result<Pattern2BreakConditionRouting, String> {
|
||||
// loop(true) read-digits family:
|
||||
// - multiple breaks exist; normalize as:
|
||||
@ -36,7 +53,24 @@ impl Pattern2BreakConditionPolicyRouterBox {
|
||||
}),
|
||||
PolicyDecision::Reject(reason) => Err(format!("[cf_loop/pattern2] {}", reason)),
|
||||
PolicyDecision::None => Ok(Pattern2BreakConditionRouting {
|
||||
// Phase 260 P0.1: If the loop has an explicit header condition and the body
|
||||
// does not contain a top-level break-guard pattern, the exit condition is
|
||||
// structurally derived as `!(loop_condition)`.
|
||||
break_condition_node: BreakConditionAnalyzer::extract_break_condition_node(body)
|
||||
.or_else(|_| {
|
||||
if matches!(
|
||||
condition,
|
||||
ASTNode::Literal {
|
||||
value: LiteralValue::Bool(true),
|
||||
..
|
||||
}
|
||||
) {
|
||||
Err("[cf_loop/pattern2] loop(true) requires a break guard pattern"
|
||||
.to_string())
|
||||
} else {
|
||||
Ok(Self::negate_condition(condition))
|
||||
}
|
||||
})
|
||||
.map_err(|_| {
|
||||
"[cf_loop/pattern2] Failed to extract break condition from loop body".to_string()
|
||||
})?,
|
||||
@ -46,4 +80,3 @@ impl Pattern2BreakConditionPolicyRouterBox {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -853,15 +853,15 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_is_const_step_pattern_negative() {
|
||||
// i - 1
|
||||
// i - j (non-const step)
|
||||
let value = ASTNode::BinaryOp {
|
||||
operator: BinaryOperator::Subtract,
|
||||
left: Box::new(ASTNode::Variable {
|
||||
name: "i".to_string(),
|
||||
span: Span::unknown(),
|
||||
}),
|
||||
right: Box::new(ASTNode::Literal {
|
||||
value: LiteralValue::Integer(1),
|
||||
right: Box::new(ASTNode::Variable {
|
||||
name: "j".to_string(),
|
||||
span: Span::unknown(),
|
||||
}),
|
||||
span: Span::unknown(),
|
||||
|
||||
@ -69,14 +69,28 @@ impl JoinLoopTrace {
|
||||
/// Create a new tracer, reading environment variables.
|
||||
pub fn new() -> Self {
|
||||
use crate::config::env::is_joinir_debug;
|
||||
let varmap_enabled = std::env::var("NYASH_TRACE_VARMAP").is_ok();
|
||||
let joinir_enabled = is_joinir_debug();
|
||||
let phi_enabled = std::env::var("NYASH_OPTION_C_DEBUG").is_ok();
|
||||
let mainline_enabled = std::env::var("NYASH_JOINIR_MAINLINE_DEBUG").is_ok();
|
||||
let loopform_enabled = std::env::var("NYASH_LOOPFORM_DEBUG").is_ok();
|
||||
let capture_enabled = std::env::var("NYASH_CAPTURE_DEBUG").is_ok();
|
||||
|
||||
// IMPORTANT:
|
||||
// `NYASH_JOINIR_DEV=1` is a semantic/feature toggle used by the smoke SSOT.
|
||||
// It must not implicitly enable noisy stderr traces.
|
||||
//
|
||||
// Dev traces are enabled only when JoinIR debug is explicitly requested.
|
||||
let dev_enabled = crate::config::env::joinir_dev_enabled() && joinir_enabled;
|
||||
|
||||
Self {
|
||||
varmap_enabled: std::env::var("NYASH_TRACE_VARMAP").is_ok(),
|
||||
joinir_enabled: is_joinir_debug(),
|
||||
phi_enabled: std::env::var("NYASH_OPTION_C_DEBUG").is_ok(),
|
||||
mainline_enabled: std::env::var("NYASH_JOINIR_MAINLINE_DEBUG").is_ok(),
|
||||
loopform_enabled: std::env::var("NYASH_LOOPFORM_DEBUG").is_ok(),
|
||||
dev_enabled: crate::config::env::joinir_dev_enabled(),
|
||||
capture_enabled: std::env::var("NYASH_CAPTURE_DEBUG").is_ok(),
|
||||
varmap_enabled,
|
||||
joinir_enabled,
|
||||
phi_enabled,
|
||||
mainline_enabled,
|
||||
loopform_enabled,
|
||||
dev_enabled,
|
||||
capture_enabled,
|
||||
}
|
||||
}
|
||||
|
||||
@ -87,7 +101,6 @@ impl JoinLoopTrace {
|
||||
|| self.phi_enabled
|
||||
|| self.mainline_enabled
|
||||
|| self.loopform_enabled
|
||||
|| self.dev_enabled
|
||||
|| self.capture_enabled
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user