fix(joinir): Phase 96 next_non_ws break condition SSOT
This commit is contained in:
@ -63,19 +63,13 @@ impl BreakConditionAnalyzer {
|
||||
} = stmt
|
||||
{
|
||||
// Pattern 1: Check if the then_body contains a break statement
|
||||
if then_body
|
||||
.iter()
|
||||
.any(|node| matches!(node, ASTNode::Break { .. }))
|
||||
{
|
||||
if Self::has_break_in_stmts(then_body) {
|
||||
return Ok(condition.as_ref());
|
||||
}
|
||||
|
||||
// Pattern 2: Check if the else_body contains a break statement
|
||||
if let Some(else_stmts) = else_body {
|
||||
if else_stmts
|
||||
.iter()
|
||||
.any(|node| matches!(node, ASTNode::Break { .. }))
|
||||
{
|
||||
if Self::has_break_in_stmts(else_stmts) {
|
||||
// For else-break pattern, return the condition
|
||||
// Note: Caller must negate this condition
|
||||
return Ok(condition.as_ref());
|
||||
@ -86,6 +80,36 @@ impl BreakConditionAnalyzer {
|
||||
Err("No if-else-break pattern found".to_string())
|
||||
}
|
||||
|
||||
/// Extract a break condition as an owned AST node suitable for lowering.
|
||||
///
|
||||
/// This returns the condition in the "break when <cond> is true" form:
|
||||
/// - `if cond { break }` -> `cond`
|
||||
/// - `if cond { ... } else { break }` -> `!cond`
|
||||
///
|
||||
/// Use this when the caller needs a normalized break condition without separately
|
||||
/// re-checking whether the break was in then/else.
|
||||
pub fn extract_break_condition_node(body: &[ASTNode]) -> Result<ASTNode, String> {
|
||||
for stmt in body {
|
||||
if let ASTNode::If {
|
||||
condition,
|
||||
then_body,
|
||||
else_body,
|
||||
..
|
||||
} = stmt
|
||||
{
|
||||
if Self::has_break_in_stmts(then_body) {
|
||||
return Ok(condition.as_ref().clone());
|
||||
}
|
||||
if let Some(else_stmts) = else_body {
|
||||
if Self::has_break_in_stmts(else_stmts) {
|
||||
return Ok(Self::negate_condition(condition.as_ref()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err("No if-else-break pattern found".to_string())
|
||||
}
|
||||
|
||||
/// Check if break exists in else clause
|
||||
///
|
||||
/// Helper function to determine if a break statement is in the else clause
|
||||
@ -198,11 +222,27 @@ impl BreakConditionAnalyzer {
|
||||
}
|
||||
}
|
||||
|
||||
// Helper: Check if statements contain break
|
||||
// Helper: Check if statements contain break (recursive)
|
||||
fn has_break_in_stmts(stmts: &[ASTNode]) -> bool {
|
||||
stmts
|
||||
.iter()
|
||||
.any(|stmt| matches!(stmt, ASTNode::Break { .. }))
|
||||
stmts.iter().any(Self::has_break_node)
|
||||
}
|
||||
|
||||
fn has_break_node(node: &ASTNode) -> bool {
|
||||
match node {
|
||||
ASTNode::Break { .. } => true,
|
||||
ASTNode::If {
|
||||
then_body,
|
||||
else_body,
|
||||
..
|
||||
} => {
|
||||
then_body.iter().any(Self::has_break_node)
|
||||
|| else_body
|
||||
.as_ref()
|
||||
.map_or(false, |e| e.iter().any(Self::has_break_node))
|
||||
}
|
||||
ASTNode::Loop { body, .. } => body.iter().any(Self::has_break_node),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
// Helper: Recursively collect variables
|
||||
|
||||
Reference in New Issue
Block a user