feat(joinir): Phase 185-187 body-local infrastructure + string design

Phase 185: Body-local Pattern2/4 integration skeleton
- Added collect_body_local_variables() helper
- Integrated UpdateEnv usage in loop_with_break_minimal
- Test files created (blocked by init lowering)

Phase 186: Body-local init lowering infrastructure
- Created LoopBodyLocalInitLowerer box (378 lines)
- Supports BinOp (+/-/*//) + Const + Variable
- Fail-Fast for method calls/string operations
- 3 unit tests passing

Phase 187: String UpdateLowering design (doc-only)
- Defined UpdateKind whitelist (6 categories)
- StringAppendChar/Literal patterns identified
- 3-layer architecture documented
- No code changes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-12-09 00:59:38 +09:00
parent b6e31cf8ca
commit d4231f5d3a
13 changed files with 2472 additions and 11 deletions

View File

@ -5,6 +5,38 @@ use crate::mir::builder::MirBuilder;
use crate::mir::ValueId;
use super::super::trace;
/// Phase 185-2: Collect body-local variable declarations from loop body
///
/// Returns Vec<(name, ValueId)> for variables declared with `local` in loop body.
/// This function scans the loop body AST for Local nodes and allocates
/// JoinIR-local ValueIds for each one.
///
/// # Arguments
///
/// * `body` - Loop body AST nodes to scan
/// * `alloc_join_value` - JoinIR ValueId allocator function
///
/// # Returns
///
/// Vector of (variable_name, join_value_id) pairs for all body-local variables
fn collect_body_local_variables(
body: &[ASTNode],
alloc_join_value: &mut dyn FnMut() -> ValueId,
) -> Vec<(String, ValueId)> {
let mut locals = Vec::new();
for node in body {
if let ASTNode::Local { variables, .. } = node {
// Local declaration can have multiple variables (e.g., local a, b, c)
for name in variables {
let value_id = alloc_join_value();
locals.push((name.clone(), value_id));
eprintln!("[pattern2/body-local] Collected local '{}' → {:?}", name, value_id);
}
}
}
locals
}
/// Phase 194: Detection function for Pattern 2
///
/// Phase 192: Updated to structure-based detection
@ -140,6 +172,16 @@ impl MirBuilder {
id
};
// Phase 185-2: Collect body-local variables
use crate::mir::join_ir::lowering::loop_body_local_env::LoopBodyLocalEnv;
let body_locals = collect_body_local_variables(_body, &mut alloc_join_value);
let body_local_env = LoopBodyLocalEnv::from_locals(body_locals);
eprintln!("[pattern2/body-local] Phase 185-2: Collected {} body-local variables", body_local_env.len());
for (name, vid) in body_local_env.iter() {
eprintln!(" {}{:?}", name, vid);
}
// Debug: Log condition bindings
eprintln!("[cf_loop/pattern2] Phase 171-172: ConditionEnv contains {} variables:", env.len());
eprintln!(" Loop param '{}' → JoinIR ValueId(0)", loop_var_name);
@ -273,6 +315,7 @@ impl MirBuilder {
&env,
&carrier_info,
&carrier_updates,
Some(&body_local_env), // Phase 185-2: Pass body-local environment
) {
Ok((module, meta)) => (module, meta),
Err(e) => {