Phase 6 WIP: Type conversion helpers (11 sites, 23 lines)
Added conversion_helpers.rs with unified type conversion: - load_as_box() for reg_load().to_nyash_box() - load_as_string() for reg_load().to_string() - load_as_int/bool() for type-checked loads - load_args_as_boxes/values() for bulk conversion Files updated (partial): - boxes.rs: 2 sites (-6 lines) - calls.rs: 5 sites (-10 lines) - boxes_plugin.rs: 1 site (-3 lines) - externals.rs: 3 sites (-4 lines) Next: boxes_array, boxes_map, boxes_object_fields, boxes_instance Tests: Phase 21.0 PASS (2/2, 100%) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -13,10 +13,7 @@ impl MirInterpreter {
|
||||
if let Err(e) = crate::runtime::provider_lock::guard_before_new_box(box_type) {
|
||||
return Err(self.err_invalid(e));
|
||||
}
|
||||
let mut converted: Vec<Box<dyn NyashBox>> = Vec::with_capacity(args.len());
|
||||
for vid in args {
|
||||
converted.push(self.reg_load(*vid)?.to_nyash_box());
|
||||
}
|
||||
let converted = self.load_args_as_boxes(args)?;
|
||||
let reg = crate::runtime::unified_registry::get_global_unified_registry();
|
||||
let created = reg
|
||||
.lock()
|
||||
@ -56,10 +53,7 @@ impl MirInterpreter {
|
||||
{
|
||||
let host = crate::runtime::plugin_loader_unified::get_global_plugin_host();
|
||||
let host = host.read().unwrap();
|
||||
let mut argv: Vec<Box<dyn NyashBox>> = Vec::with_capacity(args.len());
|
||||
for a in args {
|
||||
argv.push(self.reg_load(*a)?.to_nyash_box());
|
||||
}
|
||||
let argv = self.load_args_as_boxes(args)?;
|
||||
match host.invoke_instance_method(&p.box_type, method, p.inner.instance_id, &argv) {
|
||||
Ok(Some(ret)) => {
|
||||
self.write_from_box(dst, ret);
|
||||
|
||||
@ -41,10 +41,7 @@ pub(super) fn invoke_plugin_box(
|
||||
}
|
||||
let host = crate::runtime::plugin_loader_unified::get_global_plugin_host();
|
||||
let host = host.read().unwrap();
|
||||
let mut argv: Vec<Box<dyn NyashBox>> = Vec::with_capacity(args.len());
|
||||
for a in args {
|
||||
argv.push(this.reg_load(*a)?.to_nyash_box());
|
||||
}
|
||||
let argv = this.load_args_as_boxes(args)?;
|
||||
match host.invoke_instance_method(&p.box_type, method, p.inner.instance_id, &argv) {
|
||||
Ok(Some(ret)) => {
|
||||
this.write_from_box(dst, ret);
|
||||
|
||||
@ -74,7 +74,7 @@ impl MirInterpreter {
|
||||
"birth" => { return Ok(VMValue::Void); }
|
||||
"push" => {
|
||||
if let Some(a0) = args.get(0) {
|
||||
let v = self.reg_load(*a0)?.to_nyash_box();
|
||||
let v = self.load_as_box(*a0)?;
|
||||
let _ = arr.push(v);
|
||||
return Ok(VMValue::Void);
|
||||
}
|
||||
@ -85,15 +85,15 @@ impl MirInterpreter {
|
||||
}
|
||||
"get" => {
|
||||
if let Some(a0) = args.get(0) {
|
||||
let idx = self.reg_load(*a0)?.to_nyash_box();
|
||||
let idx = self.load_as_box(*a0)?;
|
||||
let ret = arr.get(idx);
|
||||
return Ok(VMValue::from_nyash_box(ret));
|
||||
}
|
||||
}
|
||||
"set" => {
|
||||
if args.len() >= 2 {
|
||||
let idx = self.reg_load(args[0])?.to_nyash_box();
|
||||
let val = self.reg_load(args[1])?.to_nyash_box();
|
||||
let idx = self.load_as_box(args[0])?;
|
||||
let val = self.load_as_box(args[1])?;
|
||||
let _ = arr.set(idx, val);
|
||||
return Ok(VMValue::Void);
|
||||
}
|
||||
@ -774,11 +774,7 @@ impl MirInterpreter {
|
||||
{
|
||||
let host = crate::runtime::plugin_loader_unified::get_global_plugin_host();
|
||||
let host = host.read().unwrap();
|
||||
let mut argv: Vec<Box<dyn crate::box_trait::NyashBox>> =
|
||||
Vec::with_capacity(args.len());
|
||||
for a in args {
|
||||
argv.push(self.reg_load(*a)?.to_nyash_box());
|
||||
}
|
||||
let argv = self.load_args_as_boxes(args)?;
|
||||
match host.invoke_instance_method(
|
||||
&p.box_type,
|
||||
method,
|
||||
|
||||
@ -77,8 +77,8 @@ impl MirInterpreter {
|
||||
("env.future", "new") => {
|
||||
let fut = crate::boxes::future::NyashFutureBox::new();
|
||||
if let Some(a0) = args.get(0) {
|
||||
let v = self.reg_load(*a0)?;
|
||||
fut.set_result(v.to_nyash_box());
|
||||
let v = self.load_as_box(*a0)?;
|
||||
fut.set_result(v);
|
||||
}
|
||||
self.write_result(dst, VMValue::Future(fut));
|
||||
Ok(())
|
||||
@ -86,9 +86,9 @@ impl MirInterpreter {
|
||||
("env.future", "set") => {
|
||||
if args.len() >= 2 {
|
||||
let f = self.reg_load(args[0])?;
|
||||
let v = self.reg_load(args[1])?;
|
||||
let v = self.load_as_box(args[1])?;
|
||||
if let VMValue::Future(fut) = f {
|
||||
fut.set_result(v.to_nyash_box());
|
||||
fut.set_result(v);
|
||||
} else {
|
||||
return Err(VMError::TypeError("env.future.set expects Future".into()));
|
||||
}
|
||||
@ -118,8 +118,8 @@ impl MirInterpreter {
|
||||
}
|
||||
("env.modules", "set") => {
|
||||
if args.len() >= 2 {
|
||||
let k = self.reg_load(args[0])?.to_string();
|
||||
let v = self.reg_load(args[1])?.to_nyash_box();
|
||||
let k = self.load_as_string(args[0])?;
|
||||
let v = self.load_as_box(args[1])?;
|
||||
crate::runtime::modules_registry::set(k, v);
|
||||
}
|
||||
self.write_void(dst);
|
||||
|
||||
121
src/backend/mir_interpreter/utils/conversion_helpers.rs
Normal file
121
src/backend/mir_interpreter/utils/conversion_helpers.rs
Normal file
@ -0,0 +1,121 @@
|
||||
//! 型変換ユーティリティ
|
||||
//!
|
||||
//! レジスタ値の読み込み+型変換チェーンを統一します。
|
||||
|
||||
use super::super::*;
|
||||
use crate::mir::ValueId;
|
||||
use crate::box_trait::NyashBox;
|
||||
|
||||
impl MirInterpreter {
|
||||
/// レジスタ値をBox<dyn NyashBox>として読み込む
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `vid` - 読み込むValueId
|
||||
///
|
||||
/// # Returns
|
||||
/// * `Result<Box<dyn NyashBox>, VMError>` - 変換済みのBox
|
||||
#[inline]
|
||||
pub(crate) fn load_as_box(&mut self, vid: ValueId) -> Result<Box<dyn NyashBox>, VMError> {
|
||||
Ok(self.reg_load(vid)?.to_nyash_box())
|
||||
}
|
||||
|
||||
/// レジスタ値をStringとして読み込む
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `vid` - 読み込むValueId
|
||||
///
|
||||
/// # Returns
|
||||
/// * `Result<String, VMError>` - 変換済みのString
|
||||
#[inline]
|
||||
pub(crate) fn load_as_string(&mut self, vid: ValueId) -> Result<String, VMError> {
|
||||
Ok(self.reg_load(vid)?.to_string())
|
||||
}
|
||||
|
||||
/// レジスタ値をi64として読み込む
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `vid` - 読み込むValueId
|
||||
///
|
||||
/// # Returns
|
||||
/// * `Result<i64, VMError>` - 変換済みのi64
|
||||
///
|
||||
/// # Errors
|
||||
/// * 値が整数でない場合はエラー
|
||||
#[inline]
|
||||
pub(crate) fn load_as_int(&mut self, vid: ValueId) -> Result<i64, VMError> {
|
||||
match self.reg_load(vid)? {
|
||||
VMValue::Integer(i) => Ok(i),
|
||||
other => {
|
||||
let type_name = match other {
|
||||
VMValue::Integer(_) => "Integer",
|
||||
VMValue::Float(_) => "Float",
|
||||
VMValue::Bool(_) => "Bool",
|
||||
VMValue::String(_) => "String",
|
||||
VMValue::Void => "Void",
|
||||
VMValue::BoxRef(b) => return Err(self.err_type_mismatch("load_as_int", "Integer", &b.type_name())),
|
||||
VMValue::Future(_) => "Future",
|
||||
};
|
||||
Err(self.err_type_mismatch("load_as_int", "Integer", type_name))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// レジスタ値をboolとして読み込む
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `vid` - 読み込むValueId
|
||||
///
|
||||
/// # Returns
|
||||
/// * `Result<bool, VMError>` - 変換済みのbool
|
||||
///
|
||||
/// # Errors
|
||||
/// * 値がboolでない場合はエラー
|
||||
#[inline]
|
||||
pub(crate) fn load_as_bool(&mut self, vid: ValueId) -> Result<bool, VMError> {
|
||||
match self.reg_load(vid)? {
|
||||
VMValue::Bool(b) => Ok(b),
|
||||
other => {
|
||||
let type_name = match other {
|
||||
VMValue::Integer(_) => "Integer",
|
||||
VMValue::Float(_) => "Float",
|
||||
VMValue::Bool(_) => "Bool",
|
||||
VMValue::String(_) => "String",
|
||||
VMValue::Void => "Void",
|
||||
VMValue::BoxRef(b) => return Err(self.err_type_mismatch("load_as_bool", "Bool", &b.type_name())),
|
||||
VMValue::Future(_) => "Future",
|
||||
};
|
||||
Err(self.err_type_mismatch("load_as_bool", "Bool", type_name))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 複数のレジスタ値をVec<Box<dyn NyashBox>>として読み込む
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `vids` - 読み込むValueIdのスライス
|
||||
///
|
||||
/// # Returns
|
||||
/// * `Result<Vec<Box<dyn NyashBox>>, VMError>` - 変換済みのVec
|
||||
#[inline]
|
||||
pub(crate) fn load_args_as_boxes(
|
||||
&mut self,
|
||||
vids: &[ValueId],
|
||||
) -> Result<Vec<Box<dyn NyashBox>>, VMError> {
|
||||
vids.iter().map(|vid| self.load_as_box(*vid)).collect()
|
||||
}
|
||||
|
||||
/// 複数のレジスタ値をVec<VMValue>として読み込む
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `vids` - 読み込むValueIdのスライス
|
||||
///
|
||||
/// # Returns
|
||||
/// * `Result<Vec<VMValue>, VMError>` - 読み込んだVMValueのVec
|
||||
#[inline]
|
||||
pub(crate) fn load_args_as_values(
|
||||
&mut self,
|
||||
vids: &[ValueId],
|
||||
) -> Result<Vec<VMValue>, VMError> {
|
||||
vids.iter().map(|vid| self.reg_load(*vid)).collect()
|
||||
}
|
||||
}
|
||||
@ -4,9 +4,11 @@ pub mod destination_helpers;
|
||||
pub mod arg_validation;
|
||||
pub mod receiver_helpers;
|
||||
pub mod error_helpers;
|
||||
pub mod conversion_helpers;
|
||||
|
||||
// Re-export for convenience
|
||||
pub use destination_helpers::*;
|
||||
pub use arg_validation::*;
|
||||
pub use receiver_helpers::*;
|
||||
pub use error_helpers::*;
|
||||
pub use conversion_helpers::*;
|
||||
|
||||
Reference in New Issue
Block a user