Phase 4 Complete: Interpreter integration with weak field detection
Co-authored-by: moe-charm <217100418+moe-charm@users.noreply.github.com>
This commit is contained in:
@ -564,6 +564,7 @@ impl NyashInterpreter {
|
|||||||
fields: Vec<String>,
|
fields: Vec<String>,
|
||||||
methods: HashMap<String, ASTNode>,
|
methods: HashMap<String, ASTNode>,
|
||||||
init_fields: Vec<String>,
|
init_fields: Vec<String>,
|
||||||
|
weak_fields: Vec<String>, // 🔗 weak修飾子が付いたフィールドのリスト
|
||||||
static_init: Option<Vec<ASTNode>>,
|
static_init: Option<Vec<ASTNode>>,
|
||||||
extends: Vec<String>, // 🚀 Multi-delegation: Changed from Option<String> to Vec<String>
|
extends: Vec<String>, // 🚀 Multi-delegation: Changed from Option<String> to Vec<String>
|
||||||
implements: Vec<String>,
|
implements: Vec<String>,
|
||||||
@ -577,6 +578,7 @@ impl NyashInterpreter {
|
|||||||
fields,
|
fields,
|
||||||
methods,
|
methods,
|
||||||
init_fields,
|
init_fields,
|
||||||
|
weak_fields, // 🔗 Add weak_fields to static box definition
|
||||||
static_init,
|
static_init,
|
||||||
extends,
|
extends,
|
||||||
implements,
|
implements,
|
||||||
|
|||||||
@ -605,7 +605,7 @@ impl NyashInterpreter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// フィールドアクセスを実行 - Field access processing
|
/// フィールドアクセスを実行 - Field access processing with weak reference support
|
||||||
pub(super) fn execute_field_access(&mut self, object: &ASTNode, field: &str)
|
pub(super) fn execute_field_access(&mut self, object: &ASTNode, field: &str)
|
||||||
-> Result<Box<dyn NyashBox>, RuntimeError> {
|
-> Result<Box<dyn NyashBox>, RuntimeError> {
|
||||||
|
|
||||||
@ -626,10 +626,28 @@ impl NyashInterpreter {
|
|||||||
// InstanceBoxにキャスト
|
// InstanceBoxにキャスト
|
||||||
if let Some(instance) = obj_value.as_any().downcast_ref::<InstanceBox>() {
|
if let Some(instance) = obj_value.as_any().downcast_ref::<InstanceBox>() {
|
||||||
// フィールドの値を取得
|
// フィールドの値を取得
|
||||||
instance.get_field(field)
|
let field_value = instance.get_field(field)
|
||||||
.ok_or(RuntimeError::InvalidOperation {
|
.ok_or(RuntimeError::InvalidOperation {
|
||||||
message: format!("Field '{}' not found in {}", field, instance.class_name),
|
message: format!("Field '{}' not found in {}", field, instance.class_name),
|
||||||
})
|
})?;
|
||||||
|
|
||||||
|
// 🔗 Weak Reference Check: Log that we're accessing a weak field
|
||||||
|
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);
|
||||||
|
|
||||||
|
// For now, just check if the field is null (simulating dropped weak reference)
|
||||||
|
if field_value.as_any().downcast_ref::<crate::boxes::null_box::NullBox>().is_some() {
|
||||||
|
eprintln!("🔗 DEBUG: Weak field '{}' is null (reference dropped)", field);
|
||||||
|
} else {
|
||||||
|
eprintln!("🔗 DEBUG: Weak field '{}' still has valid reference", field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normal field access for now
|
||||||
|
Ok(field_value)
|
||||||
} else {
|
} else {
|
||||||
Err(RuntimeError::TypeError {
|
Err(RuntimeError::TypeError {
|
||||||
message: format!("Cannot access field '{}' on non-instance type. Type: {}", field, obj_value.type_name()),
|
message: format!("Cannot access field '{}' on non-instance type. Type: {}", field, obj_value.type_name()),
|
||||||
@ -721,6 +739,30 @@ 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> {
|
||||||
|
// // 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
|
||||||
|
// use nyash_rust::value::NyashValue;
|
||||||
|
// use crate::box_trait::{StringBox, IntegerBox, BoolBox, VoidBox};
|
||||||
|
//
|
||||||
|
// if let Some(string_box) = box_val.as_any().downcast_ref::<StringBox>() {
|
||||||
|
// Some(NyashValue::String(string_box.value.clone()))
|
||||||
|
// } else if let Some(int_box) = box_val.as_any().downcast_ref::<IntegerBox>() {
|
||||||
|
// Some(NyashValue::Integer(int_box.value))
|
||||||
|
// } else if let Some(bool_box) = box_val.as_any().downcast_ref::<BoolBox>() {
|
||||||
|
// Some(NyashValue::Bool(bool_box.value))
|
||||||
|
// } else if box_val.as_any().downcast_ref::<VoidBox>().is_some() {
|
||||||
|
// Some(NyashValue::Void)
|
||||||
|
// } else if box_val.as_any().downcast_ref::<crate::boxes::null_box::NullBox>().is_some() {
|
||||||
|
// Some(NyashValue::Null)
|
||||||
|
// } else {
|
||||||
|
// // For complex types, create a Box variant
|
||||||
|
// // Note: This is where we'd store the weak reference
|
||||||
|
// None // Simplified for now
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
/// 🔥 FromCall実行処理 - from Parent.method(arguments) or from Parent.constructor(arguments)
|
/// 🔥 FromCall実行処理 - from Parent.method(arguments) or from Parent.constructor(arguments)
|
||||||
pub(super) fn execute_from_call(&mut self, parent: &str, method: &str, arguments: &[ASTNode])
|
pub(super) fn execute_from_call(&mut self, parent: &str, method: &str, arguments: &[ASTNode])
|
||||||
-> Result<Box<dyn NyashBox>, RuntimeError> {
|
-> Result<Box<dyn NyashBox>, RuntimeError> {
|
||||||
|
|||||||
@ -67,6 +67,7 @@ pub struct BoxDeclaration {
|
|||||||
pub methods: HashMap<String, ASTNode>,
|
pub methods: HashMap<String, ASTNode>,
|
||||||
pub constructors: HashMap<String, ASTNode>,
|
pub constructors: HashMap<String, ASTNode>,
|
||||||
pub init_fields: Vec<String>,
|
pub init_fields: Vec<String>,
|
||||||
|
pub weak_fields: Vec<String>, // 🔗 weak修飾子が付いたフィールドのリスト
|
||||||
pub is_interface: bool,
|
pub is_interface: bool,
|
||||||
pub extends: Vec<String>, // 🚀 Multi-delegation: Changed from Option<String> to Vec<String>
|
pub extends: Vec<String>, // 🚀 Multi-delegation: Changed from Option<String> to Vec<String>
|
||||||
pub implements: Vec<String>,
|
pub implements: Vec<String>,
|
||||||
@ -80,6 +81,7 @@ pub struct StaticBoxDefinition {
|
|||||||
pub fields: Vec<String>,
|
pub fields: Vec<String>,
|
||||||
pub methods: HashMap<String, ASTNode>,
|
pub methods: HashMap<String, ASTNode>,
|
||||||
pub init_fields: Vec<String>,
|
pub init_fields: Vec<String>,
|
||||||
|
pub weak_fields: Vec<String>, // 🔗 weak修飾子が付いたフィールドのリスト
|
||||||
pub static_init: Option<Vec<ASTNode>>, // static { } ブロック
|
pub static_init: Option<Vec<ASTNode>>, // static { } ブロック
|
||||||
pub extends: Vec<String>, // 🚀 Multi-delegation: Changed from Option<String> to Vec<String>
|
pub extends: Vec<String>, // 🚀 Multi-delegation: Changed from Option<String> to Vec<String>
|
||||||
pub implements: Vec<String>,
|
pub implements: Vec<String>,
|
||||||
|
|||||||
@ -752,6 +752,7 @@ impl NyashInterpreter {
|
|||||||
methods: HashMap<String, ASTNode>,
|
methods: HashMap<String, ASTNode>,
|
||||||
constructors: HashMap<String, ASTNode>,
|
constructors: HashMap<String, ASTNode>,
|
||||||
init_fields: Vec<String>,
|
init_fields: Vec<String>,
|
||||||
|
weak_fields: Vec<String>, // 🔗 weak修飾子が付いたフィールドのリスト
|
||||||
is_interface: bool,
|
is_interface: bool,
|
||||||
extends: Vec<String>, // 🚀 Multi-delegation: Changed from Option<String> to Vec<String>
|
extends: Vec<String>, // 🚀 Multi-delegation: Changed from Option<String> to Vec<String>
|
||||||
implements: Vec<String>,
|
implements: Vec<String>,
|
||||||
@ -779,6 +780,7 @@ impl NyashInterpreter {
|
|||||||
methods,
|
methods,
|
||||||
constructors,
|
constructors,
|
||||||
init_fields,
|
init_fields,
|
||||||
|
weak_fields, // 🔗 Add weak_fields to the construction
|
||||||
is_interface,
|
is_interface,
|
||||||
extends,
|
extends,
|
||||||
implements,
|
implements,
|
||||||
|
|||||||
@ -49,7 +49,7 @@ impl NyashInterpreter {
|
|||||||
self.execute_nowait(variable, expression)
|
self.execute_nowait(variable, expression)
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTNode::BoxDeclaration { name, fields, methods, constructors, init_fields, is_interface, extends, implements, type_parameters, is_static, static_init, .. } => {
|
ASTNode::BoxDeclaration { name, fields, methods, constructors, init_fields, weak_fields, is_interface, extends, implements, type_parameters, is_static, static_init, .. } => {
|
||||||
if *is_static {
|
if *is_static {
|
||||||
// 🔥 Static Box宣言の処理
|
// 🔥 Static Box宣言の処理
|
||||||
self.register_static_box_declaration(
|
self.register_static_box_declaration(
|
||||||
@ -57,6 +57,7 @@ impl NyashInterpreter {
|
|||||||
fields.clone(),
|
fields.clone(),
|
||||||
methods.clone(),
|
methods.clone(),
|
||||||
init_fields.clone(),
|
init_fields.clone(),
|
||||||
|
weak_fields.clone(), // 🔗 Add weak_fields parameter
|
||||||
static_init.clone(),
|
static_init.clone(),
|
||||||
extends.clone(),
|
extends.clone(),
|
||||||
implements.clone(),
|
implements.clone(),
|
||||||
@ -70,6 +71,7 @@ impl NyashInterpreter {
|
|||||||
methods.clone(),
|
methods.clone(),
|
||||||
constructors.clone(),
|
constructors.clone(),
|
||||||
init_fields.clone(),
|
init_fields.clone(),
|
||||||
|
weak_fields.clone(), // 🔗 Add weak_fields parameter
|
||||||
*is_interface,
|
*is_interface,
|
||||||
extends.clone(),
|
extends.clone(),
|
||||||
implements.clone(),
|
implements.clone(),
|
||||||
@ -250,6 +252,17 @@ impl NyashInterpreter {
|
|||||||
let obj_value = self.execute_expression(object)?;
|
let obj_value = self.execute_expression(object)?;
|
||||||
|
|
||||||
if let Some(instance) = obj_value.as_any().downcast_ref::<InstanceBox>() {
|
if let Some(instance) = obj_value.as_any().downcast_ref::<InstanceBox>() {
|
||||||
|
// 🔗 Weak Reference Assignment Check
|
||||||
|
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: Assigning to weak field '{}' in class '{}'", field, instance.class_name);
|
||||||
|
eprintln!("🔗 DEBUG: In a full implementation, this would convert strong reference to weak");
|
||||||
|
// For now, just log that this is a weak field assignment
|
||||||
|
// In the full implementation, we would convert val to a weak reference here
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 既存のフィールド値があればfini()を呼ぶ
|
// 既存のフィールド値があればfini()を呼ぶ
|
||||||
if let Some(old_field_value) = instance.get_field(field) {
|
if let Some(old_field_value) = instance.get_field(field) {
|
||||||
if let Some(old_instance) = old_field_value.as_any().downcast_ref::<InstanceBox>() {
|
if let Some(old_instance) = old_field_value.as_any().downcast_ref::<InstanceBox>() {
|
||||||
|
|||||||
38
test_weak_detection.nyash
Normal file
38
test_weak_detection.nyash
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// Simplified weak reference detection test
|
||||||
|
|
||||||
|
box Parent {
|
||||||
|
init { child }
|
||||||
|
|
||||||
|
pack() {
|
||||||
|
me.child = new Child()
|
||||||
|
me.child.setParent(me) // This should detect weak assignment
|
||||||
|
}
|
||||||
|
|
||||||
|
getChild() {
|
||||||
|
return me.child
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
box Child {
|
||||||
|
init { weak parent } // weak modifier on parent field
|
||||||
|
|
||||||
|
setParent(p) {
|
||||||
|
me.parent = p // Should detect weak field assignment
|
||||||
|
}
|
||||||
|
|
||||||
|
checkParent() {
|
||||||
|
return me.parent // Should detect weak field access
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static box Main {
|
||||||
|
main() {
|
||||||
|
local p = new Parent()
|
||||||
|
local child = p.getChild()
|
||||||
|
|
||||||
|
print("Testing weak field access...")
|
||||||
|
local parent_ref = child.checkParent()
|
||||||
|
|
||||||
|
return "weak reference detection test completed"
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user