Implement Phase 8.9: Remove transparency system and add weak reference nullification
Co-authored-by: moe-charm <217100418+moe-charm@users.noreply.github.com>
This commit is contained in:
@ -781,6 +781,11 @@ impl NyashInterpreter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 🔗 Phase 8.9: Weak reference invalidation after user fini
|
||||||
|
let target_info = obj_value.to_string_box().value;
|
||||||
|
eprintln!("🔗 DEBUG: Triggering weak reference invalidation for fini: {}", target_info);
|
||||||
|
self.trigger_weak_reference_invalidation(&target_info);
|
||||||
|
|
||||||
// インスタンスの内部的な解放処理
|
// インスタンスの内部的な解放処理
|
||||||
instance.fini().map_err(|e| RuntimeError::InvalidOperation {
|
instance.fini().map_err(|e| RuntimeError::InvalidOperation {
|
||||||
message: e,
|
message: e,
|
||||||
@ -1087,12 +1092,8 @@ impl NyashInterpreter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 🔥 Phase 8.8: pack透明化システム - ビルトイン自動呼び出し (先行チェック)
|
// 🔥 Phase 8.9: Transparency system removed - all delegation must be explicit
|
||||||
if is_builtin && method == parent {
|
// Removed: if is_builtin && method == parent { ... execute_builtin_constructor_call ... }
|
||||||
// 透明化: `from StringBox()` → 内部的にビルトインBox作成・統合
|
|
||||||
drop(box_declarations); // ロック解放
|
|
||||||
return self.execute_builtin_constructor_call(parent, current_instance_val.clone_box(), arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
if is_builtin {
|
if is_builtin {
|
||||||
// ビルトインBoxの場合、ロックを解放してからメソッド呼び出し
|
// ビルトインBoxの場合、ロックを解放してからメソッド呼び出し
|
||||||
@ -1250,87 +1251,6 @@ impl NyashInterpreter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 🔥 Phase 8.8: pack透明化システム - ビルトインBoxコンストラクタ統合
|
|
||||||
/// `from StringBox(content)` の透明処理: StringBoxを作成して現在のインスタンスに統合
|
|
||||||
fn execute_builtin_constructor_call(&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 constructor expects 1 argument, got {}", arg_values.len()),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let content = arg_values[0].to_string_box().value;
|
|
||||||
// StringBoxインスタンスを作成
|
|
||||||
let string_box = StringBox::new(content);
|
|
||||||
|
|
||||||
// 現在のインスタンスが継承Boxの場合、StringBox部分を設定
|
|
||||||
// この処理は、ユーザー定義Box内部にStringBoxデータを埋め込む処理
|
|
||||||
// 実際の実装では、現在のインスタンスの特定フィールドに設定するなど
|
|
||||||
// より複雑な統合処理が必要になる可能性がある
|
|
||||||
|
|
||||||
// 現在のバージョンでは、成功したことを示すVoidBoxを返す
|
|
||||||
Ok(Box::new(VoidBox::new()))
|
|
||||||
}
|
|
||||||
"IntegerBox" => {
|
|
||||||
if arg_values.len() != 1 {
|
|
||||||
return Err(RuntimeError::InvalidOperation {
|
|
||||||
message: format!("IntegerBox constructor 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);
|
|
||||||
Ok(Box::new(VoidBox::new()))
|
|
||||||
}
|
|
||||||
"MathBox" => {
|
|
||||||
// MathBoxは引数なしのコンストラクタ
|
|
||||||
if arg_values.len() != 0 {
|
|
||||||
return Err(RuntimeError::InvalidOperation {
|
|
||||||
message: format!("MathBox constructor expects 0 arguments, got {}", arg_values.len()),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let math_box = MathBox::new();
|
|
||||||
Ok(Box::new(VoidBox::new()))
|
|
||||||
}
|
|
||||||
"ArrayBox" => {
|
|
||||||
// ArrayBoxも引数なしのコンストラクタ
|
|
||||||
if arg_values.len() != 0 {
|
|
||||||
return Err(RuntimeError::InvalidOperation {
|
|
||||||
message: format!("ArrayBox constructor expects 0 arguments, got {}", arg_values.len()),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let array_box = ArrayBox::new();
|
|
||||||
Ok(Box::new(VoidBox::new()))
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
// 他のビルトインBoxは今後追加
|
|
||||||
Err(RuntimeError::InvalidOperation {
|
|
||||||
message: format!("Builtin constructor for '{}' not yet implemented in transparency system", builtin_name),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 🔥 ビルトインBoxのメソッド呼び出し
|
/// 🔥 ビルトインBoxのメソッド呼び出し
|
||||||
fn execute_builtin_box_method(&mut self, parent: &str, method: &str, mut current_instance: Box<dyn NyashBox>, arguments: &[ASTNode])
|
fn execute_builtin_box_method(&mut self, parent: &str, method: &str, mut current_instance: Box<dyn NyashBox>, arguments: &[ASTNode])
|
||||||
-> Result<Box<dyn NyashBox>, RuntimeError> {
|
-> Result<Box<dyn NyashBox>, RuntimeError> {
|
||||||
|
|||||||
@ -516,9 +516,13 @@ impl NyashParser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// DOTがない場合: from Parent() 形式 - 透明化システム
|
// DOTがない場合: from Parent() 形式 - 透明化システム廃止
|
||||||
// 🔥 Pack透明化: Parent名をmethod名として使用
|
// Phase 8.9: 明示的birth()構文を強制
|
||||||
parent.clone()
|
let line = self.current_token().line;
|
||||||
|
return Err(ParseError::TransparencySystemRemoved {
|
||||||
|
suggestion: format!("Use 'from {}.birth()' instead of 'from {}()'", parent, parent),
|
||||||
|
line,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 引数リストをパース
|
// 引数リストをパース
|
||||||
|
|||||||
@ -77,6 +77,9 @@ pub enum ParseError {
|
|||||||
#[error("🚨 Infinite loop detected in parser at {location} - token: {token:?} at line {line}")]
|
#[error("🚨 Infinite loop detected in parser at {location} - token: {token:?} at line {line}")]
|
||||||
InfiniteLoop { location: String, token: TokenType, line: usize },
|
InfiniteLoop { location: String, token: TokenType, line: usize },
|
||||||
|
|
||||||
|
#[error("🔥 Transparency system removed: {suggestion} at line {line}")]
|
||||||
|
TransparencySystemRemoved { suggestion: String, line: usize },
|
||||||
|
|
||||||
#[error("Tokenize error: {0}")]
|
#[error("Tokenize error: {0}")]
|
||||||
TokenizeError(#[from] TokenizeError),
|
TokenizeError(#[from] TokenizeError),
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,7 +36,7 @@ box Calculator from MathBox {
|
|||||||
init { precision }
|
init { precision }
|
||||||
|
|
||||||
birth(precisionLevel) {
|
birth(precisionLevel) {
|
||||||
from MathBox() # 透明化(引数なし)
|
from MathBox.birth() # Explicit syntax after Phase 8.9
|
||||||
me.precision = precisionLevel
|
me.precision = precisionLevel
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,4 +58,4 @@ print("3. MathBox透明化:")
|
|||||||
local calc = new Calculator("高精度")
|
local calc = new Calculator("高精度")
|
||||||
print(calc.getPrecision())
|
print(calc.getPrecision())
|
||||||
|
|
||||||
print("=== 全テスト成功!pack透明化システム完了 ===")
|
print("=== 全テスト成功!pack透明化システム完了 ===")テム完了 ===")
|
||||||
36
test_phase_8_9_error_cases.nyash
Normal file
36
test_phase_8_9_error_cases.nyash
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
# Phase 8.9: Error case tests
|
||||||
|
# These should all produce compile errors after transparency system removal
|
||||||
|
|
||||||
|
print("=== Error Test Cases (should all fail after Phase 8.9) ===")
|
||||||
|
|
||||||
|
# Error Case 1: Simple transparency syntax
|
||||||
|
box BadString from StringBox {
|
||||||
|
init { prefix }
|
||||||
|
|
||||||
|
birth(content) {
|
||||||
|
from StringBox(content) # ❌ Should error
|
||||||
|
me.prefix = "bad"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Error Case 2: Multiple argument transparency
|
||||||
|
box BadInteger from IntegerBox {
|
||||||
|
init { multiplier }
|
||||||
|
|
||||||
|
birth(value) {
|
||||||
|
from IntegerBox(value) # ❌ Should error
|
||||||
|
me.multiplier = 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Error Case 3: Zero argument transparency
|
||||||
|
box BadMath from MathBox {
|
||||||
|
init { precision }
|
||||||
|
|
||||||
|
birth() {
|
||||||
|
from MathBox() # ❌ Should error
|
||||||
|
me.precision = "high"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print("=== If you see this message, transparency system was NOT properly removed! ===")
|
||||||
59
test_phase_8_9_explicit_birth.nyash
Normal file
59
test_phase_8_9_explicit_birth.nyash
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
# Phase 8.9: Test explicit birth() syntax
|
||||||
|
# This file tests that explicit birth() calls work correctly
|
||||||
|
|
||||||
|
print("=== Testing explicit birth() syntax ===")
|
||||||
|
|
||||||
|
# Test 1: Basic explicit birth() call
|
||||||
|
box SimpleBox {
|
||||||
|
init { content }
|
||||||
|
|
||||||
|
birth(data) {
|
||||||
|
me.content = data
|
||||||
|
print("SimpleBox birth: " + data)
|
||||||
|
}
|
||||||
|
|
||||||
|
getContent() {
|
||||||
|
return me.content
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
local simple = new SimpleBox("test_data")
|
||||||
|
print("Content: " + simple.getContent())
|
||||||
|
|
||||||
|
# Test 2: Explicit birth() with inheritance
|
||||||
|
box EnhancedString from StringBox {
|
||||||
|
init { prefix }
|
||||||
|
|
||||||
|
birth(content, prefixStr) {
|
||||||
|
from StringBox.birth(content) # ✅ Explicit syntax
|
||||||
|
me.prefix = prefixStr
|
||||||
|
print("EnhancedString birth: " + prefixStr + " -> " + content)
|
||||||
|
}
|
||||||
|
|
||||||
|
override toString() {
|
||||||
|
return me.prefix + ": " + from StringBox.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
local enhanced = new EnhancedString("Hello World", "MESSAGE")
|
||||||
|
print("Enhanced string: " + enhanced.toString())
|
||||||
|
|
||||||
|
# Test 3: Multiple inheritance levels
|
||||||
|
box SuperEnhancedString from EnhancedString {
|
||||||
|
init { suffix }
|
||||||
|
|
||||||
|
birth(content, prefixStr, suffixStr) {
|
||||||
|
from EnhancedString.birth(content, prefixStr) # ✅ Explicit parent birth
|
||||||
|
me.suffix = suffixStr
|
||||||
|
print("SuperEnhancedString birth: " + suffixStr)
|
||||||
|
}
|
||||||
|
|
||||||
|
override toString() {
|
||||||
|
return from EnhancedString.toString() + " [" + me.suffix + "]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
local superEnh = new SuperEnhancedString("Amazing", "SUPER", "END")
|
||||||
|
print("Super enhanced: " + superEnh.toString())
|
||||||
|
|
||||||
|
print("=== All explicit birth() tests passed ===")
|
||||||
84
test_phase_8_9_transparency_removal.nyash
Normal file
84
test_phase_8_9_transparency_removal.nyash
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
# Phase 8.9: birth() Unified System Test
|
||||||
|
# Test 1: Transparency system must produce compile errors
|
||||||
|
# Test 2: Explicit birth() syntax must work correctly
|
||||||
|
# Test 3: Weak reference nullification after fini()
|
||||||
|
|
||||||
|
print("=== Phase 8.9: Testing transparency removal and explicit birth() syntax ===")
|
||||||
|
|
||||||
|
# Test 1: This should produce a compile error after changes
|
||||||
|
# from StringBox(content) # ❌ Should error after transparency removal
|
||||||
|
|
||||||
|
# Test 2: Explicit birth() syntax - should work correctly
|
||||||
|
box EnhancedString from StringBox {
|
||||||
|
init { prefix }
|
||||||
|
|
||||||
|
birth(content, prefixStr) {
|
||||||
|
from StringBox.birth(content) # ✅ Explicit syntax - must work
|
||||||
|
me.prefix = prefixStr
|
||||||
|
}
|
||||||
|
|
||||||
|
override toString() {
|
||||||
|
return me.prefix + ": " + from StringBox.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print("Test 2: Explicit birth() syntax")
|
||||||
|
local enhanced = new EnhancedString("Hello World", "Enhanced")
|
||||||
|
print(enhanced.toString())
|
||||||
|
|
||||||
|
# Test 3: Weak reference nullification after fini
|
||||||
|
box CPU {
|
||||||
|
init { name, memory }
|
||||||
|
|
||||||
|
birth(cpuName) {
|
||||||
|
me.name = cpuName
|
||||||
|
print("CPU " + me.name + " initialized")
|
||||||
|
}
|
||||||
|
|
||||||
|
fini() {
|
||||||
|
print("CPU " + me.name + " finalizing...")
|
||||||
|
if (me.memory != null) {
|
||||||
|
me.memory.cleanup()
|
||||||
|
}
|
||||||
|
print("CPU " + me.name + " finalized")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
box Memory {
|
||||||
|
init { data, weak cpu_ref }
|
||||||
|
|
||||||
|
birth(cpu) {
|
||||||
|
me.data = "memory_data"
|
||||||
|
me.cpu_ref = cpu # This becomes a weak reference
|
||||||
|
print("Memory initialized with weak CPU reference")
|
||||||
|
}
|
||||||
|
|
||||||
|
checkCPU() {
|
||||||
|
if (me.cpu_ref != null) {
|
||||||
|
return "CPU is alive: " + me.cpu_ref.name
|
||||||
|
} else {
|
||||||
|
return "CPU reference is null"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
print("Memory cleanup called")
|
||||||
|
me.data = "cleaned"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print("Test 3: Weak reference nullification after fini")
|
||||||
|
local cpu = new CPU("TestCPU")
|
||||||
|
local memory = new Memory(cpu)
|
||||||
|
cpu.memory = memory
|
||||||
|
|
||||||
|
# Before fini
|
||||||
|
print("Before CPU fini: " + memory.checkCPU())
|
||||||
|
|
||||||
|
# After fini - weak reference should be nullified
|
||||||
|
cpu.fini()
|
||||||
|
cpu = null
|
||||||
|
|
||||||
|
print("After CPU fini: " + memory.checkCPU())
|
||||||
|
|
||||||
|
print("=== Phase 8.9 tests completed ===")
|
||||||
Reference in New Issue
Block a user