refactor(interpreter): Step 5 - Extract builtins module
- Move execute_builtin_box_method() to expressions/builtins.rs (88 lines) - Move execute_builtin_birth_method() to expressions/builtins.rs (74 lines) - Complete expressions module refactoring (5/5 steps) - Remove orphaned doc comment that prevented compilation - Total extracted: ~380 lines from mod.rs to 4 specialized modules - Improved maintainability with single responsibility principle
This commit is contained in:
@ -3,3 +3,144 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::ast::ASTNode;
|
||||||
|
use crate::box_trait::{NyashBox, SharedNyashBox};
|
||||||
|
use crate::boxes::FutureBox;
|
||||||
|
use crate::{InstanceBox};
|
||||||
|
use crate::interpreter::core::{NyashInterpreter, RuntimeError};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
impl NyashInterpreter {
|
||||||
|
/// フィールドアクセスを実行 - Field access processing with weak reference support
|
||||||
|
pub(super) fn execute_field_access(&mut self, object: &ASTNode, field: &str)
|
||||||
|
-> Result<SharedNyashBox, RuntimeError> {
|
||||||
|
|
||||||
|
// 🔥 Static Boxアクセスチェック
|
||||||
|
if let ASTNode::Variable { name, .. } = object {
|
||||||
|
// Static boxの可能性をチェック
|
||||||
|
if self.is_static_box(name) {
|
||||||
|
let static_result = self.execute_static_field_access(name, field)?;
|
||||||
|
return Ok(Arc::from(static_result));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// オブジェクトを評価(通常のフィールドアクセス)
|
||||||
|
let obj_value = self.execute_expression(object);
|
||||||
|
|
||||||
|
let obj_value = obj_value?;
|
||||||
|
|
||||||
|
// InstanceBoxにキャスト
|
||||||
|
if let Some(instance) = obj_value.as_any().downcast_ref::<InstanceBox>() {
|
||||||
|
// 🔥 Usage prohibition guard - check if instance is finalized
|
||||||
|
if instance.is_finalized() {
|
||||||
|
return Err(RuntimeError::InvalidOperation {
|
||||||
|
message: "Instance was finalized; further use is prohibited".to_string(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// フィールドの値を取得
|
||||||
|
let field_value = instance.get_field(field)
|
||||||
|
.ok_or(RuntimeError::InvalidOperation {
|
||||||
|
message: format!("Field '{}' not found in {}", field, instance.class_name),
|
||||||
|
})?;
|
||||||
|
|
||||||
|
eprintln!("✅ FIELD ACCESS: Returning shared reference id={}", field_value.box_id());
|
||||||
|
|
||||||
|
// 🔗 Weak Reference Check: Use unified accessor for weak fields
|
||||||
|
let box_decls = self.shared.box_declarations.read().unwrap();
|
||||||
|
if let Some(box_decl) = box_decls.get(&instance.class_name) {
|
||||||
|
if box_decl.weak_fields.contains(&field.to_string()) {
|
||||||
|
eprintln!("🔗 DEBUG: Accessing weak field '{}' in class '{}'", field, instance.class_name);
|
||||||
|
|
||||||
|
// 🎯 PHASE 2: Use unified accessor for auto-nil weak reference handling
|
||||||
|
if let Some(weak_value) = instance.get_weak_field(field, self) { // Pass self
|
||||||
|
match &weak_value {
|
||||||
|
crate::value::NyashValue::Null => {
|
||||||
|
eprintln!("🔗 DEBUG: Weak field '{}' is null (reference dropped)", field);
|
||||||
|
// Return null box for compatibility
|
||||||
|
return Ok(Arc::new(crate::boxes::null_box::NullBox::new()));
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
eprintln!("🔗 DEBUG: Weak field '{}' still has valid reference", field);
|
||||||
|
// Convert back to Box<dyn NyashBox> for now
|
||||||
|
if let Ok(box_value) = weak_value.to_box() {
|
||||||
|
if let Ok(inner_box) = box_value.try_lock() {
|
||||||
|
return Ok(Arc::from(inner_box.clone_box()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If weak field access failed, fall through to normal access
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the shared Arc reference directly
|
||||||
|
Ok(field_value)
|
||||||
|
} else {
|
||||||
|
Err(RuntimeError::TypeError {
|
||||||
|
message: format!("Cannot access field '{}' on non-instance type. Type: {}", field, obj_value.type_name()),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 🔥 Static Box名前空間のフィールドアクセス
|
||||||
|
fn execute_static_field_access(&mut self, static_box_name: &str, field: &str)
|
||||||
|
-> Result<Box<dyn NyashBox>, RuntimeError> {
|
||||||
|
// 1. Static Boxの初期化を確実に実行
|
||||||
|
self.ensure_static_box_initialized(static_box_name)?;
|
||||||
|
|
||||||
|
// 2. GlobalBox.statics.{static_box_name} からインスタンスを取得
|
||||||
|
let global_box = self.shared.global_box.lock()
|
||||||
|
.map_err(|_| RuntimeError::RuntimeFailure {
|
||||||
|
message: "Failed to acquire global box lock".to_string()
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let statics_box = global_box.get_field("statics")
|
||||||
|
.ok_or(RuntimeError::RuntimeFailure {
|
||||||
|
message: "statics namespace not found in GlobalBox".to_string()
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let statics_instance = statics_box.as_any()
|
||||||
|
.downcast_ref::<InstanceBox>()
|
||||||
|
.ok_or(RuntimeError::TypeError {
|
||||||
|
message: "statics field is not an InstanceBox".to_string()
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let static_box_instance = statics_instance.get_field(static_box_name)
|
||||||
|
.ok_or(RuntimeError::RuntimeFailure {
|
||||||
|
message: format!("Static box '{}' instance not found in statics namespace", static_box_name)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let instance = static_box_instance.as_any()
|
||||||
|
.downcast_ref::<InstanceBox>()
|
||||||
|
.ok_or(RuntimeError::TypeError {
|
||||||
|
message: format!("Static box '{}' is not an InstanceBox", static_box_name)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
// 3. フィールドアクセス
|
||||||
|
let shared_field = instance.get_field(field)
|
||||||
|
.ok_or(RuntimeError::InvalidOperation {
|
||||||
|
message: format!("Field '{}' not found in static box '{}'", field, static_box_name),
|
||||||
|
})?;
|
||||||
|
|
||||||
|
// Convert Arc to Box for compatibility
|
||||||
|
Ok((*shared_field).clone_box())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// await式を実行 - Execute await expression
|
||||||
|
pub(super) fn execute_await(&mut self, expression: &ASTNode) -> Result<Box<dyn NyashBox>, RuntimeError> {
|
||||||
|
let value = self.execute_expression(expression)?;
|
||||||
|
|
||||||
|
// FutureBoxなら待機して結果を取得
|
||||||
|
if let Some(future) = value.as_any().downcast_ref::<FutureBox>() {
|
||||||
|
future.wait_and_get()
|
||||||
|
.map_err(|msg| RuntimeError::InvalidOperation { message: msg })
|
||||||
|
} else {
|
||||||
|
// FutureBoxでなければそのまま返す
|
||||||
|
Ok(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -3,3 +3,178 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::ast::ASTNode;
|
||||||
|
use crate::box_trait::{NyashBox, StringBox, IntegerBox, VoidBox};
|
||||||
|
use crate::boxes::{ArrayBox, MapBox, MathBox, ConsoleBox, TimeBox, RandomBox, DebugBox, SoundBox, SocketBox};
|
||||||
|
use crate::boxes::{HTTPServerBox, HTTPRequestBox, HTTPResponseBox};
|
||||||
|
use crate::boxes::file::FileBox;
|
||||||
|
use crate::interpreter::core::{NyashInterpreter, RuntimeError};
|
||||||
|
|
||||||
|
impl NyashInterpreter {
|
||||||
|
/// 🔥 ビルトインBoxのメソッド呼び出し
|
||||||
|
pub(super) fn execute_builtin_box_method(&mut self, parent: &str, method: &str, mut current_instance: Box<dyn NyashBox>, arguments: &[ASTNode])
|
||||||
|
-> Result<Box<dyn NyashBox>, RuntimeError> {
|
||||||
|
|
||||||
|
// 🌟 Phase 8.9: birth method support for builtin boxes
|
||||||
|
if method == "birth" {
|
||||||
|
return self.execute_builtin_birth_method(parent, current_instance, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ビルトインBoxのインスタンスを作成または取得
|
||||||
|
// 現在のインスタンスからビルトインBoxのデータを取得し、ビルトインBoxとしてメソッド実行
|
||||||
|
|
||||||
|
match parent {
|
||||||
|
"StringBox" => {
|
||||||
|
// StringBoxのインスタンスを作成(デフォルト値)
|
||||||
|
let string_box = StringBox::new("");
|
||||||
|
self.execute_string_method(&string_box, method, arguments)
|
||||||
|
}
|
||||||
|
"IntegerBox" => {
|
||||||
|
// IntegerBoxのインスタンスを作成(デフォルト値)
|
||||||
|
let integer_box = IntegerBox::new(0);
|
||||||
|
self.execute_integer_method(&integer_box, method, arguments)
|
||||||
|
}
|
||||||
|
"ArrayBox" => {
|
||||||
|
let array_box = ArrayBox::new();
|
||||||
|
self.execute_array_method(&array_box, method, arguments)
|
||||||
|
}
|
||||||
|
"MapBox" => {
|
||||||
|
let map_box = MapBox::new();
|
||||||
|
self.execute_map_method(&map_box, method, arguments)
|
||||||
|
}
|
||||||
|
"MathBox" => {
|
||||||
|
let math_box = MathBox::new();
|
||||||
|
self.execute_math_method(&math_box, method, arguments)
|
||||||
|
}
|
||||||
|
"P2PBox" => {
|
||||||
|
// P2PBoxの場合、現在のインスタンスからP2PBoxインスタンスを取得する必要がある
|
||||||
|
// TODO: 現在のインスタンスのフィールドからP2PBoxを取得
|
||||||
|
return Err(RuntimeError::InvalidOperation {
|
||||||
|
message: format!("P2PBox delegation not yet fully implemented: {}.{}", parent, method),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
"FileBox" => {
|
||||||
|
let file_box = crate::boxes::file::FileBox::new();
|
||||||
|
self.execute_file_method(&file_box, method, arguments)
|
||||||
|
}
|
||||||
|
"ConsoleBox" => {
|
||||||
|
let console_box = ConsoleBox::new();
|
||||||
|
self.execute_console_method(&console_box, method, arguments)
|
||||||
|
}
|
||||||
|
"TimeBox" => {
|
||||||
|
let time_box = TimeBox::new();
|
||||||
|
self.execute_time_method(&time_box, method, arguments)
|
||||||
|
}
|
||||||
|
"RandomBox" => {
|
||||||
|
let random_box = RandomBox::new();
|
||||||
|
self.execute_random_method(&random_box, method, arguments)
|
||||||
|
}
|
||||||
|
"DebugBox" => {
|
||||||
|
let debug_box = DebugBox::new();
|
||||||
|
self.execute_debug_method(&debug_box, method, arguments)
|
||||||
|
}
|
||||||
|
"SoundBox" => {
|
||||||
|
let sound_box = SoundBox::new();
|
||||||
|
self.execute_sound_method(&sound_box, method, arguments)
|
||||||
|
}
|
||||||
|
"SocketBox" => {
|
||||||
|
let socket_box = SocketBox::new();
|
||||||
|
self.execute_socket_method(&socket_box, method, arguments)
|
||||||
|
}
|
||||||
|
"HTTPServerBox" => {
|
||||||
|
let http_server_box = HTTPServerBox::new();
|
||||||
|
self.execute_http_server_method(&http_server_box, method, arguments)
|
||||||
|
}
|
||||||
|
"HTTPRequestBox" => {
|
||||||
|
let http_request_box = HTTPRequestBox::new();
|
||||||
|
self.execute_http_request_method(&http_request_box, method, arguments)
|
||||||
|
}
|
||||||
|
"HTTPResponseBox" => {
|
||||||
|
let http_response_box = HTTPResponseBox::new();
|
||||||
|
self.execute_http_response_method(&http_response_box, method, arguments)
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
Err(RuntimeError::InvalidOperation {
|
||||||
|
message: format!("Unknown built-in Box type for delegation: {}", parent),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 🌟 Phase 8.9: Execute birth method for builtin boxes
|
||||||
|
/// Provides constructor functionality for builtin boxes through explicit birth() calls
|
||||||
|
pub(super) fn execute_builtin_birth_method(&mut self, builtin_name: &str, current_instance: Box<dyn NyashBox>, arguments: &[ASTNode])
|
||||||
|
-> Result<Box<dyn NyashBox>, RuntimeError> {
|
||||||
|
|
||||||
|
// 引数を評価
|
||||||
|
let mut arg_values = Vec::new();
|
||||||
|
for arg in arguments {
|
||||||
|
arg_values.push(self.execute_expression(arg)?);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ビルトインBoxの種類に応じて適切なインスタンスを作成して返す
|
||||||
|
match builtin_name {
|
||||||
|
"StringBox" => {
|
||||||
|
if arg_values.len() != 1 {
|
||||||
|
return Err(RuntimeError::InvalidOperation {
|
||||||
|
message: format!("StringBox.birth() expects 1 argument, got {}", arg_values.len()),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let content = arg_values[0].to_string_box().value;
|
||||||
|
eprintln!("🌟 DEBUG: StringBox.birth() created with content: '{}'", content);
|
||||||
|
let string_box = StringBox::new(content);
|
||||||
|
Ok(Box::new(VoidBox::new())) // Return void to indicate successful initialization
|
||||||
|
}
|
||||||
|
"IntegerBox" => {
|
||||||
|
if arg_values.len() != 1 {
|
||||||
|
return Err(RuntimeError::InvalidOperation {
|
||||||
|
message: format!("IntegerBox.birth() expects 1 argument, got {}", arg_values.len()),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let value = if let Ok(int_val) = arg_values[0].to_string_box().value.parse::<i64>() {
|
||||||
|
int_val
|
||||||
|
} else {
|
||||||
|
return Err(RuntimeError::TypeError {
|
||||||
|
message: format!("Cannot convert '{}' to integer", arg_values[0].to_string_box().value),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
let integer_box = IntegerBox::new(value);
|
||||||
|
eprintln!("🌟 DEBUG: IntegerBox.birth() created with value: {}", value);
|
||||||
|
Ok(Box::new(VoidBox::new()))
|
||||||
|
}
|
||||||
|
"MathBox" => {
|
||||||
|
// MathBoxは引数なしのコンストラクタ
|
||||||
|
if arg_values.len() != 0 {
|
||||||
|
return Err(RuntimeError::InvalidOperation {
|
||||||
|
message: format!("MathBox.birth() expects 0 arguments, got {}", arg_values.len()),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let math_box = MathBox::new();
|
||||||
|
eprintln!("🌟 DEBUG: MathBox.birth() created");
|
||||||
|
Ok(Box::new(VoidBox::new()))
|
||||||
|
}
|
||||||
|
"ArrayBox" => {
|
||||||
|
// ArrayBoxも引数なしのコンストラクタ
|
||||||
|
if arg_values.len() != 0 {
|
||||||
|
return Err(RuntimeError::InvalidOperation {
|
||||||
|
message: format!("ArrayBox.birth() expects 0 arguments, got {}", arg_values.len()),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let array_box = ArrayBox::new();
|
||||||
|
eprintln!("🌟 DEBUG: ArrayBox.birth() created");
|
||||||
|
Ok(Box::new(VoidBox::new()))
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
// 他のビルトインBoxは今後追加
|
||||||
|
Err(RuntimeError::InvalidOperation {
|
||||||
|
message: format!("birth() method not yet implemented for builtin box '{}'", builtin_name),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -153,138 +153,6 @@ impl NyashInterpreter {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// フィールドアクセスを実行 - Field access processing with weak reference support
|
|
||||||
pub(super) fn execute_field_access(&mut self, object: &ASTNode, field: &str)
|
|
||||||
-> Result<SharedNyashBox, RuntimeError> {
|
|
||||||
|
|
||||||
// 🔥 Static Boxアクセスチェック
|
|
||||||
if let ASTNode::Variable { name, .. } = object {
|
|
||||||
// Static boxの可能性をチェック
|
|
||||||
if self.is_static_box(name) {
|
|
||||||
let static_result = self.execute_static_field_access(name, field)?;
|
|
||||||
return Ok(Arc::from(static_result));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// オブジェクトを評価(通常のフィールドアクセス)
|
|
||||||
let obj_value = self.execute_expression(object);
|
|
||||||
|
|
||||||
let obj_value = obj_value?;
|
|
||||||
|
|
||||||
// InstanceBoxにキャスト
|
|
||||||
if let Some(instance) = obj_value.as_any().downcast_ref::<InstanceBox>() {
|
|
||||||
// 🔥 Usage prohibition guard - check if instance is finalized
|
|
||||||
if instance.is_finalized() {
|
|
||||||
return Err(RuntimeError::InvalidOperation {
|
|
||||||
message: "Instance was finalized; further use is prohibited".to_string(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// フィールドの値を取得
|
|
||||||
let field_value = instance.get_field(field)
|
|
||||||
.ok_or(RuntimeError::InvalidOperation {
|
|
||||||
message: format!("Field '{}' not found in {}", field, instance.class_name),
|
|
||||||
})?;
|
|
||||||
|
|
||||||
eprintln!("✅ FIELD ACCESS: Returning shared reference id={}", field_value.box_id());
|
|
||||||
|
|
||||||
// 🔗 Weak Reference Check: Use unified accessor for weak fields
|
|
||||||
let box_decls = self.shared.box_declarations.read().unwrap();
|
|
||||||
if let Some(box_decl) = box_decls.get(&instance.class_name) {
|
|
||||||
if box_decl.weak_fields.contains(&field.to_string()) {
|
|
||||||
eprintln!("🔗 DEBUG: Accessing weak field '{}' in class '{}'", field, instance.class_name);
|
|
||||||
|
|
||||||
// 🎯 PHASE 2: Use unified accessor for auto-nil weak reference handling
|
|
||||||
if let Some(weak_value) = instance.get_weak_field(field, self) { // Pass self
|
|
||||||
match &weak_value {
|
|
||||||
crate::value::NyashValue::Null => {
|
|
||||||
eprintln!("🔗 DEBUG: Weak field '{}' is null (reference dropped)", field);
|
|
||||||
// Return null box for compatibility
|
|
||||||
return Ok(Arc::new(crate::boxes::null_box::NullBox::new()));
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
eprintln!("🔗 DEBUG: Weak field '{}' still has valid reference", field);
|
|
||||||
// Convert back to Box<dyn NyashBox> for now
|
|
||||||
if let Ok(box_value) = weak_value.to_box() {
|
|
||||||
if let Ok(inner_box) = box_value.try_lock() {
|
|
||||||
return Ok(Arc::from(inner_box.clone_box()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If weak field access failed, fall through to normal access
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the shared Arc reference directly
|
|
||||||
Ok(field_value)
|
|
||||||
} else {
|
|
||||||
Err(RuntimeError::TypeError {
|
|
||||||
message: format!("Cannot access field '{}' on non-instance type. Type: {}", field, obj_value.type_name()),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 🔥 Static Box名前空間のフィールドアクセス
|
|
||||||
fn execute_static_field_access(&mut self, static_box_name: &str, field: &str)
|
|
||||||
-> Result<Box<dyn NyashBox>, RuntimeError> {
|
|
||||||
// 1. Static Boxの初期化を確実に実行
|
|
||||||
self.ensure_static_box_initialized(static_box_name)?;
|
|
||||||
|
|
||||||
// 2. GlobalBox.statics.{static_box_name} からインスタンスを取得
|
|
||||||
let global_box = self.shared.global_box.lock()
|
|
||||||
.map_err(|_| RuntimeError::RuntimeFailure {
|
|
||||||
message: "Failed to acquire global box lock".to_string()
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let statics_box = global_box.get_field("statics")
|
|
||||||
.ok_or(RuntimeError::RuntimeFailure {
|
|
||||||
message: "statics namespace not found in GlobalBox".to_string()
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let statics_instance = statics_box.as_any()
|
|
||||||
.downcast_ref::<InstanceBox>()
|
|
||||||
.ok_or(RuntimeError::TypeError {
|
|
||||||
message: "statics field is not an InstanceBox".to_string()
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let static_box_instance = statics_instance.get_field(static_box_name)
|
|
||||||
.ok_or(RuntimeError::RuntimeFailure {
|
|
||||||
message: format!("Static box '{}' instance not found in statics namespace", static_box_name)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let instance = static_box_instance.as_any()
|
|
||||||
.downcast_ref::<InstanceBox>()
|
|
||||||
.ok_or(RuntimeError::TypeError {
|
|
||||||
message: format!("Static box '{}' is not an InstanceBox", static_box_name)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
// 3. フィールドアクセス
|
|
||||||
let shared_field = instance.get_field(field)
|
|
||||||
.ok_or(RuntimeError::InvalidOperation {
|
|
||||||
message: format!("Field '{}' not found in static box '{}'", field, static_box_name),
|
|
||||||
})?;
|
|
||||||
|
|
||||||
// Convert Arc to Box for compatibility
|
|
||||||
Ok((*shared_field).clone_box())
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// await式を実行 - Execute await expression
|
|
||||||
pub(super) fn execute_await(&mut self, expression: &ASTNode) -> Result<Box<dyn NyashBox>, RuntimeError> {
|
|
||||||
let value = self.execute_expression(expression)?;
|
|
||||||
|
|
||||||
// FutureBoxなら待機して結果を取得
|
|
||||||
if let Some(future) = value.as_any().downcast_ref::<FutureBox>() {
|
|
||||||
future.wait_and_get()
|
|
||||||
.map_err(|msg| RuntimeError::InvalidOperation { message: msg })
|
|
||||||
} else {
|
|
||||||
// FutureBoxでなければそのまま返す
|
|
||||||
Ok(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 🔄 循環参照検出: オブジェクトの一意IDを取得
|
/// 🔄 循環参照検出: オブジェクトの一意IDを取得
|
||||||
fn get_object_id(&self, node: &ASTNode) -> Option<usize> {
|
fn get_object_id(&self, node: &ASTNode) -> Option<usize> {
|
||||||
@ -314,7 +182,6 @@ impl NyashInterpreter {
|
|||||||
hash
|
hash
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 🔗 Convert NyashBox to NyashValue for weak reference operations
|
|
||||||
// fn box_to_nyash_value(&self, box_val: &Box<dyn NyashBox>) -> Option<nyash_rust::value::NyashValue> {
|
// fn box_to_nyash_value(&self, box_val: &Box<dyn NyashBox>) -> Option<nyash_rust::value::NyashValue> {
|
||||||
// // Try to convert the box back to NyashValue for weak reference operations
|
// // Try to convert the box back to NyashValue for weak reference operations
|
||||||
// // This is a simplified conversion - in reality we might need more sophisticated logic
|
// // This is a simplified conversion - in reality we might need more sophisticated logic
|
||||||
@ -339,170 +206,4 @@ impl NyashInterpreter {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
/// 🔥 ビルトインBoxのメソッド呼び出し
|
|
||||||
fn execute_builtin_box_method(&mut self, parent: &str, method: &str, mut current_instance: Box<dyn NyashBox>, arguments: &[ASTNode])
|
|
||||||
-> Result<Box<dyn NyashBox>, RuntimeError> {
|
|
||||||
|
|
||||||
// 🌟 Phase 8.9: birth method support for builtin boxes
|
|
||||||
if method == "birth" {
|
|
||||||
return self.execute_builtin_birth_method(parent, current_instance, arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ビルトインBoxのインスタンスを作成または取得
|
|
||||||
// 現在のインスタンスからビルトインBoxのデータを取得し、ビルトインBoxとしてメソッド実行
|
|
||||||
|
|
||||||
match parent {
|
|
||||||
"StringBox" => {
|
|
||||||
// StringBoxのインスタンスを作成(デフォルト値)
|
|
||||||
let string_box = StringBox::new("");
|
|
||||||
self.execute_string_method(&string_box, method, arguments)
|
|
||||||
}
|
|
||||||
"IntegerBox" => {
|
|
||||||
// IntegerBoxのインスタンスを作成(デフォルト値)
|
|
||||||
let integer_box = IntegerBox::new(0);
|
|
||||||
self.execute_integer_method(&integer_box, method, arguments)
|
|
||||||
}
|
|
||||||
"ArrayBox" => {
|
|
||||||
let array_box = ArrayBox::new();
|
|
||||||
self.execute_array_method(&array_box, method, arguments)
|
|
||||||
}
|
|
||||||
"MapBox" => {
|
|
||||||
let map_box = MapBox::new();
|
|
||||||
self.execute_map_method(&map_box, method, arguments)
|
|
||||||
}
|
|
||||||
"MathBox" => {
|
|
||||||
let math_box = MathBox::new();
|
|
||||||
self.execute_math_method(&math_box, method, arguments)
|
|
||||||
}
|
|
||||||
"P2PBox" => {
|
|
||||||
// P2PBoxの場合、現在のインスタンスからP2PBoxインスタンスを取得する必要がある
|
|
||||||
// TODO: 現在のインスタンスのフィールドからP2PBoxを取得
|
|
||||||
return Err(RuntimeError::InvalidOperation {
|
|
||||||
message: format!("P2PBox delegation not yet fully implemented: {}.{}", parent, method),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
"FileBox" => {
|
|
||||||
let file_box = crate::boxes::file::FileBox::new();
|
|
||||||
self.execute_file_method(&file_box, method, arguments)
|
|
||||||
}
|
|
||||||
"ConsoleBox" => {
|
|
||||||
let console_box = ConsoleBox::new();
|
|
||||||
self.execute_console_method(&console_box, method, arguments)
|
|
||||||
}
|
|
||||||
"TimeBox" => {
|
|
||||||
let time_box = TimeBox::new();
|
|
||||||
self.execute_time_method(&time_box, method, arguments)
|
|
||||||
}
|
|
||||||
"RandomBox" => {
|
|
||||||
let random_box = RandomBox::new();
|
|
||||||
self.execute_random_method(&random_box, method, arguments)
|
|
||||||
}
|
|
||||||
"DebugBox" => {
|
|
||||||
let debug_box = DebugBox::new();
|
|
||||||
self.execute_debug_method(&debug_box, method, arguments)
|
|
||||||
}
|
|
||||||
"SoundBox" => {
|
|
||||||
let sound_box = SoundBox::new();
|
|
||||||
self.execute_sound_method(&sound_box, method, arguments)
|
|
||||||
}
|
|
||||||
"SocketBox" => {
|
|
||||||
let socket_box = SocketBox::new();
|
|
||||||
self.execute_socket_method(&socket_box, method, arguments)
|
|
||||||
}
|
|
||||||
"HTTPServerBox" => {
|
|
||||||
let http_server_box = HTTPServerBox::new();
|
|
||||||
self.execute_http_server_method(&http_server_box, method, arguments)
|
|
||||||
}
|
|
||||||
"HTTPRequestBox" => {
|
|
||||||
let http_request_box = HTTPRequestBox::new();
|
|
||||||
self.execute_http_request_method(&http_request_box, method, arguments)
|
|
||||||
}
|
|
||||||
"HTTPResponseBox" => {
|
|
||||||
let http_response_box = HTTPResponseBox::new();
|
|
||||||
self.execute_http_response_method(&http_response_box, method, arguments)
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
Err(RuntimeError::InvalidOperation {
|
|
||||||
message: format!("Unknown built-in Box type for delegation: {}", parent),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 🌟 Phase 8.9: Execute birth method for builtin boxes
|
|
||||||
/// Provides constructor functionality for builtin boxes through explicit birth() calls
|
|
||||||
fn execute_builtin_birth_method(&mut self, builtin_name: &str, current_instance: Box<dyn NyashBox>, arguments: &[ASTNode])
|
|
||||||
-> Result<Box<dyn NyashBox>, RuntimeError> {
|
|
||||||
|
|
||||||
// 引数を評価
|
|
||||||
let mut arg_values = Vec::new();
|
|
||||||
for arg in arguments {
|
|
||||||
arg_values.push(self.execute_expression(arg)?);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ビルトインBoxの種類に応じて適切なインスタンスを作成して返す
|
|
||||||
match builtin_name {
|
|
||||||
"StringBox" => {
|
|
||||||
if arg_values.len() != 1 {
|
|
||||||
return Err(RuntimeError::InvalidOperation {
|
|
||||||
message: format!("StringBox.birth() expects 1 argument, got {}", arg_values.len()),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let content = arg_values[0].to_string_box().value;
|
|
||||||
eprintln!("🌟 DEBUG: StringBox.birth() created with content: '{}'", content);
|
|
||||||
let string_box = StringBox::new(content);
|
|
||||||
Ok(Box::new(VoidBox::new())) // Return void to indicate successful initialization
|
|
||||||
}
|
|
||||||
"IntegerBox" => {
|
|
||||||
if arg_values.len() != 1 {
|
|
||||||
return Err(RuntimeError::InvalidOperation {
|
|
||||||
message: format!("IntegerBox.birth() expects 1 argument, got {}", arg_values.len()),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let value = if let Ok(int_val) = arg_values[0].to_string_box().value.parse::<i64>() {
|
|
||||||
int_val
|
|
||||||
} else {
|
|
||||||
return Err(RuntimeError::TypeError {
|
|
||||||
message: format!("Cannot convert '{}' to integer", arg_values[0].to_string_box().value),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
let integer_box = IntegerBox::new(value);
|
|
||||||
eprintln!("🌟 DEBUG: IntegerBox.birth() created with value: {}", value);
|
|
||||||
Ok(Box::new(VoidBox::new()))
|
|
||||||
}
|
|
||||||
"MathBox" => {
|
|
||||||
// MathBoxは引数なしのコンストラクタ
|
|
||||||
if arg_values.len() != 0 {
|
|
||||||
return Err(RuntimeError::InvalidOperation {
|
|
||||||
message: format!("MathBox.birth() expects 0 arguments, got {}", arg_values.len()),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let math_box = MathBox::new();
|
|
||||||
eprintln!("🌟 DEBUG: MathBox.birth() created");
|
|
||||||
Ok(Box::new(VoidBox::new()))
|
|
||||||
}
|
|
||||||
"ArrayBox" => {
|
|
||||||
// ArrayBoxも引数なしのコンストラクタ
|
|
||||||
if arg_values.len() != 0 {
|
|
||||||
return Err(RuntimeError::InvalidOperation {
|
|
||||||
message: format!("ArrayBox.birth() expects 0 arguments, got {}", arg_values.len()),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let array_box = ArrayBox::new();
|
|
||||||
eprintln!("🌟 DEBUG: ArrayBox.birth() created");
|
|
||||||
Ok(Box::new(VoidBox::new()))
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
// 他のビルトインBoxは今後追加
|
|
||||||
Err(RuntimeError::InvalidOperation {
|
|
||||||
message: format!("birth() method not yet implemented for builtin box '{}'", builtin_name),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user