Files
hakorune/src/mir/join_ir_vm_bridge/convert.rs

131 lines
4.9 KiB
Rust

use crate::mir::join_ir::{BinOpKind, CompareOp, ConstValue, JoinModule, MirLikeInst};
use crate::mir::{
BinaryOp, CompareOp as MirCompareOp, ConstValue as MirConstValue, EffectMask, MirInstruction,
MirModule,
};
use super::JoinIrVmBridgeError;
// Phase 190: Use modular converters from parent module
use super::joinir_function_converter::JoinIrFunctionConverter;
/// Phase 190: JoinIR → MIR 変換器(統合エントリーポイント)
///
/// Phase 32 L-2.2 Step-3: テストから呼び出し可能に `pub(crate)` 化
#[cfg_attr(not(test), allow(dead_code))]
pub(crate) fn convert_joinir_to_mir(
join_module: &JoinModule,
) -> Result<MirModule, JoinIrVmBridgeError> {
// Phase 190: Delegate to FunctionConverter
JoinIrFunctionConverter::convert_joinir_to_mir(join_module)
}
/// MirLikeInst → MirInstruction 変換
/// Phase 190: 共有ユーティリティとして pub(crate) に変更
pub(crate) fn convert_mir_like_inst(
mir_like: &MirLikeInst,
) -> Result<MirInstruction, JoinIrVmBridgeError> {
match mir_like {
MirLikeInst::Const { dst, value } => {
let mir_const = match value {
ConstValue::Integer(i) => MirConstValue::Integer(*i),
ConstValue::Bool(b) => MirConstValue::Bool(*b),
ConstValue::String(s) => MirConstValue::String(s.clone()),
ConstValue::Null => MirConstValue::Null,
};
Ok(MirInstruction::Const {
dst: *dst,
value: mir_const,
})
}
MirLikeInst::BinOp { dst, op, lhs, rhs } => {
let mir_op = match op {
BinOpKind::Add => BinaryOp::Add,
BinOpKind::Sub => BinaryOp::Sub,
BinOpKind::Mul => BinaryOp::Mul,
BinOpKind::Div => BinaryOp::Div,
BinOpKind::Mod => BinaryOp::Mod, // Phase 188-Impl-3
BinOpKind::Or => BinaryOp::Or,
BinOpKind::And => BinaryOp::And,
};
Ok(MirInstruction::BinOp {
dst: *dst,
op: mir_op,
lhs: *lhs,
rhs: *rhs,
})
}
MirLikeInst::Compare { dst, op, lhs, rhs } => {
let mir_cmp = match op {
CompareOp::Lt => MirCompareOp::Lt,
CompareOp::Le => MirCompareOp::Le,
CompareOp::Gt => MirCompareOp::Gt,
CompareOp::Ge => MirCompareOp::Ge,
CompareOp::Eq => MirCompareOp::Eq,
CompareOp::Ne => MirCompareOp::Ne,
};
Ok(MirInstruction::Compare {
dst: *dst,
op: mir_cmp,
lhs: *lhs,
rhs: *rhs,
})
}
MirLikeInst::BoxCall {
dst,
box_name,
method,
args,
} => {
// Phase 27-shortterm S-4.3: BoxCall → MIR BoxCall
// box_name は JoinIR で保持しているが、MIR BoxCall には receiver ValueId のみ
// 暫定: args[0] を receiver として扱う
if args.is_empty() {
return Err(JoinIrVmBridgeError::new(format!(
"BoxCall requires at least one argument (receiver), got: box_name={}, method={}",
box_name, method
)));
}
let receiver = args[0];
let method_args = args[1..].to_vec();
Ok(MirInstruction::BoxCall {
dst: *dst,
box_val: receiver,
method: method.clone(),
method_id: None, // Phase 27-shortterm: no method ID resolution
args: method_args,
effects: EffectMask::PURE, // Phase 27-shortterm: assume pure
})
}
// Phase 56: UnaryOp
MirLikeInst::UnaryOp { dst, op, operand } => {
let mir_op = match op {
crate::mir::join_ir::UnaryOp::Not => crate::mir::types::UnaryOp::Not,
crate::mir::join_ir::UnaryOp::Neg => crate::mir::types::UnaryOp::Neg,
};
Ok(MirInstruction::UnaryOp {
dst: *dst,
op: mir_op,
operand: *operand,
})
}
// Phase 188: Print
MirLikeInst::Print { value } => Ok(MirInstruction::Print {
value: *value,
effects: EffectMask::IO,
}),
// Phase 188-Impl-3: Select
// Select is a ternary operator: cond ? then_val : else_val
// This should not be directly converted to a single MIR instruction
// Instead, it should be handled by merge_joinir_mir_blocks which creates
// proper control flow with branches and PHI nodes
MirLikeInst::Select { .. } => {
Err(JoinIrVmBridgeError::new(
"Select instruction should be handled by merge_joinir_mir_blocks, not convert_mir_like_inst".to_string()
))
}
}
}