feat(joinir): Phase 213-2 Step 2-2 & 2-3 Data structure extensions

Extended PatternPipelineContext and CarrierUpdateInfo for Pattern 3 AST-based generalization.

Changes:
1. PatternPipelineContext:
   - Added loop_condition: Option<ASTNode>
   - Added loop_body: Option<Vec<ASTNode>>
   - Added loop_update_summary: Option<LoopUpdateSummary>
   - Updated build_pattern_context() for Pattern 3

2. CarrierUpdateInfo:
   - Added then_expr: Option<ASTNode>
   - Added else_expr: Option<ASTNode>
   - Updated analyze_loop_updates() with None defaults

Status: Phase 213-2 Steps 2-2 & 2-3 complete
Next: Create Pattern3IfAnalyzer to extract if statement and populate update summary
This commit is contained in:
nyash-codex
2025-12-10 00:01:53 +09:00
parent 577b5b01d5
commit d7805e5974
138 changed files with 3529 additions and 378 deletions

View File

@ -212,15 +212,72 @@ impl super::MirBuilder {
/// Note:
/// - While/ForRange は将来 Loop lowering へ委譲する拡張ポイントとして扱い、
/// 現状は他の専用ビルダ/既存パスと同様に build_expression に委譲する。
///
/// Phase 212.5: If statement のサポート追加
/// - Statement としての If副作用のみが欲しいを明示的に処理
/// - Expression としての If値を使うは build_expression 経由のまま
pub(super) fn build_statement(&mut self, node: ASTNode) -> Result<ValueId, String> {
// Align current_span to this statement node before lowering expressions under it.
self.current_span = node.span();
match node {
// Phase 212.5: Statement としての If 処理
ASTNode::If {
condition,
then_body,
else_body,
..
} => {
// Statement としての If - 既存 If lowering を呼ぶ
self.build_if_statement(*condition, then_body, else_body)?;
// Statement なので値は使わないVoid を返す)
Ok(crate::mir::builder::emission::constant::emit_void(self))
}
// 将来ここに While / ForRange / Match / Using など statement 専用分岐を追加する。
other => self.build_expression(other),
}
}
/// Phase 212.5: Statement としての If 処理(副作用のみ)
///
/// ループ内 if や top-level statement if はここを通る。
/// Expression としての if値を使う場合は build_expression 経由。
///
/// # Arguments
/// * `condition` - If の条件式
/// * `then_body` - then ブロックの statements
/// * `else_body` - else ブロックの statements (optional)
///
/// # Example
/// ```hako
/// if i > 0 {
/// sum = sum + 1 // ← Statement としての If
/// }
/// ```
pub(super) fn build_if_statement(
&mut self,
condition: ASTNode,
then_body: Vec<ASTNode>,
else_body: Option<Vec<ASTNode>>,
) -> Result<(), String> {
use crate::ast::Span;
// then_body と else_body を ASTNode::Program に変換
let then_node = ASTNode::Program {
statements: then_body,
span: Span::unknown(),
};
let else_node = else_body.map(|b| ASTNode::Program {
statements: b,
span: Span::unknown(),
});
// 既存の If lowering を呼ぶcf_if は lower_if_form を呼ぶ)
// 戻り値は無視Statement なので値は使わない)
let _result = self.cf_if(condition, then_node, else_node)?;
Ok(())
}
// Local declarations with optional initializers
pub(super) fn build_local_statement(
&mut self,