feat(joinir): Phase 142 P2 Step 3-A - Pattern4 early return fail-fast
This commit is contained in:
@ -678,12 +678,13 @@ pub fn detect_parse_number_pattern(body: &[ASTNode]) -> Option<ParseNumberInfo>
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Phase 143-P1: Parse String Pattern Detection
|
||||
// Phase 143-P1/P2: Parse String/Array Pattern Detection
|
||||
// ============================================================================
|
||||
|
||||
/// Parse string pattern information
|
||||
/// Parse string/array pattern information
|
||||
///
|
||||
/// This struct holds the extracted information from a recognized parse_string pattern.
|
||||
/// This struct holds the extracted information from a recognized parse_string or parse_array pattern.
|
||||
/// Both patterns share the same structure: continue + return exits with carrier updates.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct ParseStringInfo {
|
||||
/// Carrier variable name (e.g., "p")
|
||||
@ -694,11 +695,11 @@ pub struct ParseStringInfo {
|
||||
pub body_stmts: Vec<ASTNode>,
|
||||
}
|
||||
|
||||
/// Detect parse_string pattern in loop body
|
||||
/// Detect parse_string or parse_array pattern in loop body
|
||||
///
|
||||
/// Phase 143-P1: Pattern with both continue (escape handling) AND return (quote found)
|
||||
/// Phase 143-P1/P2: Pattern with both continue (escape/separator handling) AND return (stop condition)
|
||||
///
|
||||
/// Pattern structure:
|
||||
/// Pattern structure (parse_string example):
|
||||
/// ```
|
||||
/// loop(p < len) {
|
||||
/// local ch = s.substring(p, p + 1)
|
||||
@ -725,10 +726,34 @@ pub struct ParseStringInfo {
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Pattern structure (parse_array example):
|
||||
/// ```
|
||||
/// loop(p < len) {
|
||||
/// local ch = s.substring(p, p + 1)
|
||||
///
|
||||
/// // Check for array end (return)
|
||||
/// if ch == "]" {
|
||||
/// return result
|
||||
/// }
|
||||
///
|
||||
/// // Check for separator (continue after processing)
|
||||
/// if ch == "," {
|
||||
/// arr.push(elem)
|
||||
/// elem = ""
|
||||
/// p = p + 1
|
||||
/// continue
|
||||
/// }
|
||||
///
|
||||
/// // Accumulate element
|
||||
/// elem = elem + ch
|
||||
/// p = p + 1
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Recognized characteristics:
|
||||
/// - Has return statement (early exit on quote)
|
||||
/// - Has continue statement (skip after escape processing)
|
||||
/// - Variable step update (p++ normally, but p+=2 on escape)
|
||||
/// - Has return statement (early exit on stop condition: quote for string, ']' for array)
|
||||
/// - Has continue statement (skip after separator: escape for string, ',' for array)
|
||||
/// - Variable step update (p++ normally, but p+=2 on escape for string)
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
@ -740,10 +765,11 @@ pub struct ParseStringInfo {
|
||||
///
|
||||
/// # Notes
|
||||
///
|
||||
/// This is more complex than parse_number or continue patterns due to:
|
||||
/// This detector handles both parse_string and parse_array patterns as they share
|
||||
/// the same structural characteristics:
|
||||
/// - Multiple exit types (return AND continue)
|
||||
/// - Variable step increment (conditional on escape sequence)
|
||||
/// - Nested control flow (escape has nested if inside)
|
||||
/// - Variable step increment (conditional on separator/escape)
|
||||
/// - Nested control flow (separator/escape has nested if inside)
|
||||
pub fn detect_parse_string_pattern(body: &[ASTNode]) -> Option<ParseStringInfo> {
|
||||
if body.is_empty() {
|
||||
return None;
|
||||
|
||||
@ -39,6 +39,49 @@ use crate::mir::loop_pattern_detection::error_messages;
|
||||
use crate::mir::ValueId;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
/// Phase 142 P2: Detect return statements in loop body
|
||||
///
|
||||
/// This is a helper function for Fail-Fast behavior when return statements
|
||||
/// are detected in Pattern4 (continue) loops, which are not yet fully supported.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `body` - Loop body statements to scan
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// `true` if at least one return statement is found in the body
|
||||
fn has_return_in_body(body: &[ASTNode]) -> bool {
|
||||
for stmt in body {
|
||||
if has_return_node(stmt) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// Helper: Recursively check if node or its children contain return
|
||||
fn has_return_node(node: &ASTNode) -> bool {
|
||||
match node {
|
||||
ASTNode::Return { .. } => true,
|
||||
ASTNode::If {
|
||||
then_body,
|
||||
else_body,
|
||||
..
|
||||
} => {
|
||||
then_body.iter().any(|n| has_return_node(n))
|
||||
|| else_body
|
||||
.as_ref()
|
||||
.map_or(false, |body| body.iter().any(|n| has_return_node(n)))
|
||||
}
|
||||
ASTNode::Loop { body, .. } => {
|
||||
// Nested loops: scan recursively (though not common in our patterns)
|
||||
body.iter().any(|n| has_return_node(n))
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Phase 194+: Detection function for Pattern 4
|
||||
///
|
||||
/// Phase 192: Updated to use pattern_kind for consistency
|
||||
@ -101,6 +144,16 @@ pub(crate) fn lower(
|
||||
builder: &mut MirBuilder,
|
||||
ctx: &super::router::LoopPatternContext,
|
||||
) -> Result<Option<ValueId>, String> {
|
||||
// Phase 142 P2: Check for return statements (not yet supported)
|
||||
if has_return_in_body(ctx.body) {
|
||||
return Err(
|
||||
"[Pattern4] Early return is not yet supported in continue loops. \
|
||||
This will be implemented in Phase 142 P2. \
|
||||
Pattern: loop with both continue and return statements."
|
||||
.to_string(),
|
||||
);
|
||||
}
|
||||
|
||||
// Phase 33-19: Connect stub to actual implementation
|
||||
builder.cf_loop_pattern4_with_continue(ctx.condition, ctx.body, ctx.func_name, ctx.debug)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user