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) {
|
if let Err(e) = crate::runtime::provider_lock::guard_before_new_box(box_type) {
|
||||||
return Err(self.err_invalid(e));
|
return Err(self.err_invalid(e));
|
||||||
}
|
}
|
||||||
let mut converted: Vec<Box<dyn NyashBox>> = Vec::with_capacity(args.len());
|
let converted = self.load_args_as_boxes(args)?;
|
||||||
for vid in args {
|
|
||||||
converted.push(self.reg_load(*vid)?.to_nyash_box());
|
|
||||||
}
|
|
||||||
let reg = crate::runtime::unified_registry::get_global_unified_registry();
|
let reg = crate::runtime::unified_registry::get_global_unified_registry();
|
||||||
let created = reg
|
let created = reg
|
||||||
.lock()
|
.lock()
|
||||||
@ -56,10 +53,7 @@ impl MirInterpreter {
|
|||||||
{
|
{
|
||||||
let host = crate::runtime::plugin_loader_unified::get_global_plugin_host();
|
let host = crate::runtime::plugin_loader_unified::get_global_plugin_host();
|
||||||
let host = host.read().unwrap();
|
let host = host.read().unwrap();
|
||||||
let mut argv: Vec<Box<dyn NyashBox>> = Vec::with_capacity(args.len());
|
let argv = self.load_args_as_boxes(args)?;
|
||||||
for a in args {
|
|
||||||
argv.push(self.reg_load(*a)?.to_nyash_box());
|
|
||||||
}
|
|
||||||
match host.invoke_instance_method(&p.box_type, method, p.inner.instance_id, &argv) {
|
match host.invoke_instance_method(&p.box_type, method, p.inner.instance_id, &argv) {
|
||||||
Ok(Some(ret)) => {
|
Ok(Some(ret)) => {
|
||||||
self.write_from_box(dst, 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 = crate::runtime::plugin_loader_unified::get_global_plugin_host();
|
||||||
let host = host.read().unwrap();
|
let host = host.read().unwrap();
|
||||||
let mut argv: Vec<Box<dyn NyashBox>> = Vec::with_capacity(args.len());
|
let argv = this.load_args_as_boxes(args)?;
|
||||||
for a in args {
|
|
||||||
argv.push(this.reg_load(*a)?.to_nyash_box());
|
|
||||||
}
|
|
||||||
match host.invoke_instance_method(&p.box_type, method, p.inner.instance_id, &argv) {
|
match host.invoke_instance_method(&p.box_type, method, p.inner.instance_id, &argv) {
|
||||||
Ok(Some(ret)) => {
|
Ok(Some(ret)) => {
|
||||||
this.write_from_box(dst, ret);
|
this.write_from_box(dst, ret);
|
||||||
|
|||||||
@ -74,7 +74,7 @@ impl MirInterpreter {
|
|||||||
"birth" => { return Ok(VMValue::Void); }
|
"birth" => { return Ok(VMValue::Void); }
|
||||||
"push" => {
|
"push" => {
|
||||||
if let Some(a0) = args.get(0) {
|
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);
|
let _ = arr.push(v);
|
||||||
return Ok(VMValue::Void);
|
return Ok(VMValue::Void);
|
||||||
}
|
}
|
||||||
@ -85,15 +85,15 @@ impl MirInterpreter {
|
|||||||
}
|
}
|
||||||
"get" => {
|
"get" => {
|
||||||
if let Some(a0) = args.get(0) {
|
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);
|
let ret = arr.get(idx);
|
||||||
return Ok(VMValue::from_nyash_box(ret));
|
return Ok(VMValue::from_nyash_box(ret));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"set" => {
|
"set" => {
|
||||||
if args.len() >= 2 {
|
if args.len() >= 2 {
|
||||||
let idx = self.reg_load(args[0])?.to_nyash_box();
|
let idx = self.load_as_box(args[0])?;
|
||||||
let val = self.reg_load(args[1])?.to_nyash_box();
|
let val = self.load_as_box(args[1])?;
|
||||||
let _ = arr.set(idx, val);
|
let _ = arr.set(idx, val);
|
||||||
return Ok(VMValue::Void);
|
return Ok(VMValue::Void);
|
||||||
}
|
}
|
||||||
@ -774,11 +774,7 @@ impl MirInterpreter {
|
|||||||
{
|
{
|
||||||
let host = crate::runtime::plugin_loader_unified::get_global_plugin_host();
|
let host = crate::runtime::plugin_loader_unified::get_global_plugin_host();
|
||||||
let host = host.read().unwrap();
|
let host = host.read().unwrap();
|
||||||
let mut argv: Vec<Box<dyn crate::box_trait::NyashBox>> =
|
let argv = self.load_args_as_boxes(args)?;
|
||||||
Vec::with_capacity(args.len());
|
|
||||||
for a in args {
|
|
||||||
argv.push(self.reg_load(*a)?.to_nyash_box());
|
|
||||||
}
|
|
||||||
match host.invoke_instance_method(
|
match host.invoke_instance_method(
|
||||||
&p.box_type,
|
&p.box_type,
|
||||||
method,
|
method,
|
||||||
|
|||||||
@ -77,8 +77,8 @@ impl MirInterpreter {
|
|||||||
("env.future", "new") => {
|
("env.future", "new") => {
|
||||||
let fut = crate::boxes::future::NyashFutureBox::new();
|
let fut = crate::boxes::future::NyashFutureBox::new();
|
||||||
if let Some(a0) = args.get(0) {
|
if let Some(a0) = args.get(0) {
|
||||||
let v = self.reg_load(*a0)?;
|
let v = self.load_as_box(*a0)?;
|
||||||
fut.set_result(v.to_nyash_box());
|
fut.set_result(v);
|
||||||
}
|
}
|
||||||
self.write_result(dst, VMValue::Future(fut));
|
self.write_result(dst, VMValue::Future(fut));
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -86,9 +86,9 @@ impl MirInterpreter {
|
|||||||
("env.future", "set") => {
|
("env.future", "set") => {
|
||||||
if args.len() >= 2 {
|
if args.len() >= 2 {
|
||||||
let f = self.reg_load(args[0])?;
|
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 {
|
if let VMValue::Future(fut) = f {
|
||||||
fut.set_result(v.to_nyash_box());
|
fut.set_result(v);
|
||||||
} else {
|
} else {
|
||||||
return Err(VMError::TypeError("env.future.set expects Future".into()));
|
return Err(VMError::TypeError("env.future.set expects Future".into()));
|
||||||
}
|
}
|
||||||
@ -118,8 +118,8 @@ impl MirInterpreter {
|
|||||||
}
|
}
|
||||||
("env.modules", "set") => {
|
("env.modules", "set") => {
|
||||||
if args.len() >= 2 {
|
if args.len() >= 2 {
|
||||||
let k = self.reg_load(args[0])?.to_string();
|
let k = self.load_as_string(args[0])?;
|
||||||
let v = self.reg_load(args[1])?.to_nyash_box();
|
let v = self.load_as_box(args[1])?;
|
||||||
crate::runtime::modules_registry::set(k, v);
|
crate::runtime::modules_registry::set(k, v);
|
||||||
}
|
}
|
||||||
self.write_void(dst);
|
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 arg_validation;
|
||||||
pub mod receiver_helpers;
|
pub mod receiver_helpers;
|
||||||
pub mod error_helpers;
|
pub mod error_helpers;
|
||||||
|
pub mod conversion_helpers;
|
||||||
|
|
||||||
// Re-export for convenience
|
// Re-export for convenience
|
||||||
pub use destination_helpers::*;
|
pub use destination_helpers::*;
|
||||||
pub use arg_validation::*;
|
pub use arg_validation::*;
|
||||||
pub use receiver_helpers::*;
|
pub use receiver_helpers::*;
|
||||||
pub use error_helpers::*;
|
pub use error_helpers::*;
|
||||||
|
pub use conversion_helpers::*;
|
||||||
|
|||||||
Reference in New Issue
Block a user