feat(joinir): Phase 188 StringAppend support in Pattern2/4

- Extended Pattern2/4 whitelist to accept StringLiteral updates
- CarrierUpdateEmitter now emits JoinIR for string append
- Selective Fail-Fast: accept safe patterns, reject complex

Changes:
- pattern2_with_break.rs: StringLiteral whitelist
- pattern4_with_continue.rs: StringLiteral whitelist
- carrier_update_emitter.rs: StringLiteral JoinIR emission

Tests:
- phase188_string_append_char.hako
- phase188_string_append_literal.hako
- 10/10 carrier_update_emitter tests PASS

🤖 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 01:09:54 +09:00
parent d4231f5d3a
commit a2933880ae
8 changed files with 160 additions and 32 deletions

View File

@ -124,15 +124,22 @@ pub fn emit_carrier_update_with_env(
)
})?
}
// Phase 178: String updates detected but not lowered to JoinIR yet
// The Rust MIR path handles string concatenation
// For JoinIR: just pass through the carrier param (no JoinIR update)
UpdateRhs::StringLiteral(_) | UpdateRhs::Other => {
eprintln!(
"[joinir/pattern2] Phase 178: Carrier '{}' has string/complex update - skipping JoinIR emit, using param passthrough",
// Phase 188: String updates now emit JoinIR BinOp
// StringAppendLiteral: s = s + "literal"
UpdateRhs::StringLiteral(s) => {
let const_id = alloc_value();
instructions.push(JoinInst::Compute(MirLikeInst::Const {
dst: const_id,
value: ConstValue::String(s.clone()),
}));
const_id
}
// Phase 178/188: Complex updates (method calls) still rejected
UpdateRhs::Other => {
return Err(format!(
"Carrier '{}' has complex update (UpdateRhs::Other) - should be rejected by can_lower()",
carrier.name
);
return Ok(carrier_param); // Pass-through: no JoinIR update
));
}
};
@ -259,15 +266,22 @@ pub fn emit_carrier_update(
)
})?
}
// Phase 178: String updates detected but not lowered to JoinIR yet
// The Rust MIR path handles string concatenation
// For JoinIR: just pass through the carrier param (no JoinIR update)
UpdateRhs::StringLiteral(_) | UpdateRhs::Other => {
eprintln!(
"[joinir/pattern2] Phase 178: Carrier '{}' has string/complex update - skipping JoinIR emit, using param passthrough",
// Phase 188: String updates now emit JoinIR BinOp
// StringAppendLiteral: s = s + "literal"
UpdateRhs::StringLiteral(s) => {
let const_id = alloc_value();
instructions.push(JoinInst::Compute(MirLikeInst::Const {
dst: const_id,
value: ConstValue::String(s.clone()),
}));
const_id
}
// Phase 178/188: Complex updates (method calls) still rejected
UpdateRhs::Other => {
return Err(format!(
"Carrier '{}' has complex update (UpdateRhs::Other) - should be rejected by can_lower()",
carrier.name
);
return Ok(carrier_param); // Pass-through: no JoinIR update
));
}
};