feat(joinir): Phase 27-shortterm S-5.1 完了 - JoinValue を VMValue ベースに統合

## 実装内容

### JoinValue 型の拡張
- **BoxRef variant 追加**: `BoxRef(Arc<dyn NyashBox>)` で VM と値を共有
- **Manual PartialEq 実装**: BoxRef は Arc::ptr_eq で比較

### VMValue との相互変換強化
- `to_vm_value()`: BoxRef サポート追加
- `into_vm_value()`: Zero-cost 変換(owned values)
- `from_vm_value()`: BoxRef サポート追加

### 後方互換性
- 既存の Int/Bool/Str/Unit variant は変更なし
- すべての既存コードがそのまま動作
- 16個の unit test 全て PASS 

### S-5.2 への準備
- BoxRef を method_router 経由で使用する準備完了
- 「VM 2号機」を避けるための基盤確立

## テスト結果
- join_ir_ops unit tests: 16 passed / 0 failed
This commit is contained in:
nyash-codex
2025-11-24 07:31:34 +09:00
parent 790c8381fb
commit 03cb0a49c7

View File

@ -11,12 +11,32 @@
use crate::mir::join_ir::{BinOpKind, CompareOp};
/// JoinIR で扱う値型
#[derive(Debug, Clone, PartialEq)]
///
/// Phase 27-shortterm S-5.1: VMValue との統合
/// - BoxRef variant 追加S-5.2 で method_router 統合時に使用)
/// - from_vm_value()/into_vm_value() で VMValue と相互変換可能
#[derive(Debug, Clone)]
pub enum JoinValue {
Int(i64),
Bool(bool),
Str(String),
Unit,
/// S-5.2: method_router 経由で Box/Plugin を実行するために使用
BoxRef(std::sync::Arc<dyn crate::box_trait::NyashBox>),
}
// Manual PartialEq implementation (BoxRef は Arc::ptr_eq で比較)
impl PartialEq for JoinValue {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(JoinValue::Int(a), JoinValue::Int(b)) => a == b,
(JoinValue::Bool(a), JoinValue::Bool(b)) => a == b,
(JoinValue::Str(a), JoinValue::Str(b)) => a == b,
(JoinValue::Unit, JoinValue::Unit) => true,
(JoinValue::BoxRef(a), JoinValue::BoxRef(b)) => std::sync::Arc::ptr_eq(a, b),
_ => false,
}
}
}
/// JoinIR ops box エラー型
@ -288,6 +308,8 @@ mod tests {
impl JoinValue {
/// Convert JoinValue to VMValue for VM execution
///
/// Phase 27-shortterm S-5.1: BoxRef サポート追加
///
/// # Example
/// ```ignore
/// let join_val = JoinValue::Int(42);
@ -300,13 +322,28 @@ impl JoinValue {
JoinValue::Bool(b) => crate::backend::VMValue::Bool(*b),
JoinValue::Str(s) => crate::backend::VMValue::String(s.clone()),
JoinValue::Unit => crate::backend::VMValue::Void,
JoinValue::BoxRef(b) => crate::backend::VMValue::BoxRef(b.clone()),
}
}
/// Convert JoinValue into VMValue (consuming self)
///
/// Phase 27-shortterm S-5.1: Zero-cost conversion for owned values
pub fn into_vm_value(self) -> crate::backend::VMValue {
match self {
JoinValue::Int(i) => crate::backend::VMValue::Integer(i),
JoinValue::Bool(b) => crate::backend::VMValue::Bool(b),
JoinValue::Str(s) => crate::backend::VMValue::String(s),
JoinValue::Unit => crate::backend::VMValue::Void,
JoinValue::BoxRef(b) => crate::backend::VMValue::BoxRef(b),
}
}
/// Convert VMValue to JoinValue
///
/// Returns error for VMValue types not representable in JoinValue
/// (Float, Future, BoxRef).
/// Phase 27-shortterm S-5.1: BoxRef サポート追加
///
/// Returns error for VMValue types not representable in JoinValue (Float, Future).
///
/// # Example
/// ```ignore
@ -320,15 +357,13 @@ impl JoinValue {
crate::backend::VMValue::Bool(b) => Ok(JoinValue::Bool(*b)),
crate::backend::VMValue::String(s) => Ok(JoinValue::Str(s.clone())),
crate::backend::VMValue::Void => Ok(JoinValue::Unit),
crate::backend::VMValue::BoxRef(b) => Ok(JoinValue::BoxRef(b.clone())),
crate::backend::VMValue::Float(_) => {
Err(JoinIrOpError::new("Float not supported in JoinValue"))
}
crate::backend::VMValue::Future(_) => {
Err(JoinIrOpError::new("Future not supported in JoinValue"))
}
crate::backend::VMValue::BoxRef(_) => {
Err(JoinIrOpError::new("BoxRef not directly convertible to JoinValue - requires NyashBox downcast"))
}
}
}
}