Refactor (light): move VM value ops to backend/vm_values.rs; add backend/vm_boxcall.rs with call_box_method_impl and rewire call_unified_method. Update CURRENT_TASK for refactor start.

This commit is contained in:
Moe Charm
2025-08-26 00:48:09 +09:00
parent 63656c1d1b
commit 2a02eb7a52
7 changed files with 348 additions and 286 deletions

View File

@ -626,290 +626,6 @@ impl VM {
self.values[index] = Some(value);
}
/// Execute binary operation
pub(super) fn execute_binary_op(&self, op: &BinaryOp, left: &VMValue, right: &VMValue) -> Result<VMValue, VMError> {
// Fast path: logical AND/OR accept any truthy via as_bool (supports BoxRef BoolBox/Void coercions)
if matches!(*op, BinaryOp::And | BinaryOp::Or) {
let l = left.as_bool()?;
let r = right.as_bool()?;
return Ok(VMValue::Bool(match *op { BinaryOp::And => l && r, BinaryOp::Or => l || r, _ => unreachable!() }));
}
match (left, right) {
// Logical booleans (native)
(VMValue::Bool(l), VMValue::Bool(r)) => {
let result = match op {
BinaryOp::And => *l && *r,
BinaryOp::Or => *l || *r,
_ => return Err(VMError::TypeError(format!(
"Unsupported boolean operation: {:?}", op
))),
};
Ok(VMValue::Bool(result))
}
// Logical booleans (BoxRef BoolBox)
(VMValue::BoxRef(lb), VMValue::BoxRef(rb))
if lb.as_any().downcast_ref::<BoolBox>().is_some()
&& rb.as_any().downcast_ref::<BoolBox>().is_some() =>
{
let l = lb.as_any().downcast_ref::<BoolBox>().unwrap().value;
let r = rb.as_any().downcast_ref::<BoolBox>().unwrap().value;
let result = match op {
BinaryOp::And => l && r,
BinaryOp::Or => l || r,
_ => return Err(VMError::TypeError(format!(
"Unsupported boolean BoxRef operation: {:?}", op
))),
};
Ok(VMValue::Bool(result))
}
// Mixed boolean forms (BoxRef BoolBox with native Bool)
(VMValue::BoxRef(lb), VMValue::Bool(r)) if lb.as_any().downcast_ref::<BoolBox>().is_some() => {
let l = lb.as_any().downcast_ref::<BoolBox>().unwrap().value;
let result = match op {
BinaryOp::And => l && *r,
BinaryOp::Or => l || *r,
_ => return Err(VMError::TypeError(format!(
"Unsupported boolean operation: {:?}", op
))),
};
Ok(VMValue::Bool(result))
}
(VMValue::Bool(l), VMValue::BoxRef(rb)) if rb.as_any().downcast_ref::<BoolBox>().is_some() => {
let r = rb.as_any().downcast_ref::<BoolBox>().unwrap().value;
let result = match op {
BinaryOp::And => *l && r,
BinaryOp::Or => *l || r,
_ => return Err(VMError::TypeError(format!(
"Unsupported boolean operation: {:?}", op
))),
};
Ok(VMValue::Bool(result))
}
// Arithmetic with BoxRef(IntegerBox)
(VMValue::BoxRef(li), VMValue::BoxRef(ri))
if li.as_any().downcast_ref::<IntegerBox>().is_some()
&& ri.as_any().downcast_ref::<IntegerBox>().is_some() =>
{
let l = li.as_any().downcast_ref::<IntegerBox>().unwrap().value;
let r = ri.as_any().downcast_ref::<IntegerBox>().unwrap().value;
let res = match op {
BinaryOp::Add => l + r,
BinaryOp::Sub => l - r,
BinaryOp::Mul => l * r,
BinaryOp::Div => {
if r == 0 { return Err(VMError::DivisionByZero); }
l / r
}
_ => return Err(VMError::InvalidInstruction(format!(
"Unsupported integer BoxRef operation: {:?}", op
))),
};
Ok(VMValue::Integer(res))
}
// Mixed Integer forms: BoxRef<IntegerBox> with native Integer
(VMValue::BoxRef(li), VMValue::Integer(r)) if li.as_any().downcast_ref::<IntegerBox>().is_some() => {
let l = li.as_any().downcast_ref::<IntegerBox>().unwrap().value;
let res = match op {
BinaryOp::Add => l + *r,
BinaryOp::Sub => l - *r,
BinaryOp::Mul => l * *r,
BinaryOp::Div => {
if *r == 0 { return Err(VMError::DivisionByZero); }
l / *r
}
_ => return Err(VMError::InvalidInstruction(format!(
"Unsupported integer operation: {:?}", op
))),
};
Ok(VMValue::Integer(res))
}
(VMValue::Integer(l), VMValue::BoxRef(ri)) if ri.as_any().downcast_ref::<IntegerBox>().is_some() => {
let r = ri.as_any().downcast_ref::<IntegerBox>().unwrap().value;
let res = match op {
BinaryOp::Add => *l + r,
BinaryOp::Sub => *l - r,
BinaryOp::Mul => *l * r,
BinaryOp::Div => {
if r == 0 { return Err(VMError::DivisionByZero); }
*l / r
}
_ => return Err(VMError::InvalidInstruction(format!(
"Unsupported integer operation: {:?}", op
))),
};
Ok(VMValue::Integer(res))
}
(VMValue::Integer(l), VMValue::Integer(r)) => {
let result = match op {
BinaryOp::Add => *l + *r,
BinaryOp::Sub => *l - *r,
BinaryOp::Mul => *l * *r,
BinaryOp::Div => {
if *r == 0 {
return Err(VMError::DivisionByZero);
}
*l / *r
},
_ => return Err(VMError::InvalidInstruction(format!("Unsupported integer operation: {:?}", op))),
};
Ok(VMValue::Integer(result))
},
(VMValue::String(l), VMValue::Integer(r)) => {
// String + Integer concatenation
match op {
BinaryOp::Add => Ok(VMValue::String(format!("{}{}", l, r))),
_ => Err(VMError::TypeError("String-integer operations only support addition".to_string())),
}
},
(VMValue::String(l), VMValue::Bool(r)) => {
// String + Bool concatenation
match op {
BinaryOp::Add => Ok(VMValue::String(format!("{}{}", l, r))),
_ => Err(VMError::TypeError("String-bool operations only support addition".to_string())),
}
},
(VMValue::String(l), VMValue::String(r)) => {
// String concatenation
match op {
BinaryOp::Add => Ok(VMValue::String(format!("{}{}", l, r))),
_ => Err(VMError::TypeError("String operations only support addition".to_string())),
}
},
// String + BoxRef concatenation
(VMValue::String(l), VMValue::BoxRef(r)) => {
match op {
BinaryOp::Add => Ok(VMValue::String(format!("{}{}", l, r.to_string_box().value))),
_ => Err(VMError::TypeError("String-BoxRef operations only support addition".to_string())),
}
},
// BoxRef + String concatenation
(VMValue::BoxRef(l), VMValue::String(r)) => {
match op {
BinaryOp::Add => Ok(VMValue::String(format!("{}{}", l.to_string_box().value, r))),
_ => Err(VMError::TypeError("BoxRef-String operations only support addition".to_string())),
}
},
_ => Err(VMError::TypeError(format!("Unsupported binary operation [vm.rs updated]: {:?} on {:?} and {:?}", op, left, right))),
}
}
/// Execute unary operation
pub(super) fn execute_unary_op(&self, op: &UnaryOp, operand: &VMValue) -> Result<VMValue, VMError> {
match (op, operand) {
(UnaryOp::Neg, VMValue::Integer(i)) => Ok(VMValue::Integer(-i)),
(UnaryOp::Not, VMValue::Bool(b)) => Ok(VMValue::Bool(!b)),
_ => Err(VMError::TypeError(format!("Unsupported unary operation: {:?} on {:?}", op, operand))),
}
}
/// Execute comparison operation
pub(super) fn execute_compare_op(&self, op: &CompareOp, left: &VMValue, right: &VMValue) -> Result<bool, VMError> {
match (left, right) {
// Numeric mixed comparisons (Integer/Float)
(VMValue::Integer(l), VMValue::Float(r)) => {
let l = *l as f64;
let r = *r;
let result = match op {
CompareOp::Eq => l == r,
CompareOp::Ne => l != r,
CompareOp::Lt => l < r,
CompareOp::Le => l <= r,
CompareOp::Gt => l > r,
CompareOp::Ge => l >= r,
};
Ok(result)
},
(VMValue::Float(l), VMValue::Integer(r)) => {
let l = *l;
let r = *r as f64;
let result = match op {
CompareOp::Eq => l == r,
CompareOp::Ne => l != r,
CompareOp::Lt => l < r,
CompareOp::Le => l <= r,
CompareOp::Gt => l > r,
CompareOp::Ge => l >= r,
};
Ok(result)
},
// Bool comparisons: support Eq/Ne only for now
(VMValue::Bool(l), VMValue::Bool(r)) => {
let result = match op {
CompareOp::Eq => l == r,
CompareOp::Ne => l != r,
_ => return Err(VMError::TypeError(format!("Unsupported boolean comparison: {:?}", op))),
};
Ok(result)
},
// Void comparisons: only Eq/Ne are defined
(VMValue::Void, VMValue::Void) => {
let result = match op {
CompareOp::Eq => true,
CompareOp::Ne => false,
_ => return Err(VMError::TypeError("Cannot order Void".to_string())),
};
Ok(result)
},
(VMValue::Void, _) | (_, VMValue::Void) => {
let result = match op {
CompareOp::Eq => false, // void == X (X != void) is false
CompareOp::Ne => true, // void != X is true
_ => return Err(VMError::TypeError("Cannot order Void".to_string())),
};
Ok(result)
},
(VMValue::Integer(l), VMValue::Integer(r)) => {
let result = match op {
CompareOp::Eq => l == r,
CompareOp::Ne => l != r,
CompareOp::Lt => l < r,
CompareOp::Le => l <= r,
CompareOp::Gt => l > r,
CompareOp::Ge => l >= r,
};
Ok(result)
},
(VMValue::Float(l), VMValue::Float(r)) => {
let result = match op {
CompareOp::Eq => l == r,
CompareOp::Ne => l != r,
CompareOp::Lt => l < r,
CompareOp::Le => l <= r,
CompareOp::Gt => l > r,
CompareOp::Ge => l >= r,
};
Ok(result)
},
(VMValue::String(l), VMValue::String(r)) => {
let result = match op {
CompareOp::Eq => l == r,
CompareOp::Ne => l != r,
CompareOp::Lt => l < r,
CompareOp::Le => l <= r,
CompareOp::Gt => l > r,
CompareOp::Ge => l >= r,
};
Ok(result)
},
_ => Err(VMError::TypeError(format!("Unsupported comparison: {:?} on {:?} and {:?}", op, left, right))),
}
}
/// Record an instruction execution for statistics
pub(super) fn record_instruction(&mut self, instruction: &MirInstruction) {
@ -1031,7 +747,7 @@ impl VM {
fn call_unified_method(&self, box_value: Box<dyn NyashBox>, method: &str, args: Vec<Box<dyn NyashBox>>) -> Result<Box<dyn NyashBox>, VMError> {
// For now, we use the simplified method dispatch
// In a full implementation, this would check for InstanceBox and dispatch appropriately
self.call_box_method(box_value, method, args)
self.call_box_method_impl(box_value, method, args)
}
/// Call a method on a Box - simplified version of interpreter method dispatch