revert: 古いプラグインシステム実装前の状態に巻き戻し

- ソースコードをcommit 3f7d71fの状態に復元(古いプラグインシステム実装前)
- docsフォルダは最新の状態を維持(BID-FFI設計ドキュメント含む)
- nyashバイナリの基本動作確認済み
- BID-FFIシステムをクリーンに再実装する準備完了

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Moe Charm
2025-08-18 08:34:19 +09:00
parent 75868a5a96
commit bec0e9bc92
35 changed files with 731 additions and 2757 deletions

View File

@ -16,8 +16,6 @@ cli = []
gui = ["dep:egui", "dep:eframe", "dep:egui_extras", "dep:image"]
gui-examples = ["gui"]
all-examples = ["gui-examples"]
# 動的ライブラリサポート
dynamic-file = ["dep:libloading"]
[lib]
name = "nyash_rust"
@ -29,11 +27,6 @@ crate-type = ["cdylib", "rlib"]
name = "nyash"
path = "src/main.rs"
# WASM runner executable
[[bin]]
name = "nyash-wasm-run"
path = "src/bin/nyash-wasm-run.rs"
# Examples for development - only available as examples, not bins
[[example]]
name = "gui_simple_notepad"
@ -120,9 +113,6 @@ js-sys = "0.3"
wabt = "0.10"
wasmtime = "35.0.0"
# 動的ライブラリロードPhase 9.75f
libloading = { version = "0.8", optional = true }
# GUI フレームワーク - only when gui feature is enabled
egui = { version = "0.29", optional = true }
eframe = { version = "0.29", default-features = false, features = ["default_fonts", "glow"], optional = true }
@ -179,12 +169,3 @@ panic = "abort"
# 開発用設定
opt-level = 0
debug = true
# Workspace configuration
[workspace]
members = [
".", # メインのnyash-rustプロジェクト
"plugins/nyash-file", # FileBoxプラグイン
"plugins/nyash-math", # Math/Time系プラグイン
]
resolver = "2"

File diff suppressed because it is too large Load Diff

View File

@ -61,7 +61,7 @@
- ✅ libloadingプラグイン動的ロード基盤
-**プラグインシステム統合テスト14/14合格** 🎉
### 🎯 **Day 5 90%完了!** (2025-08-17)
### 🎯 **Day 5 一時中断** (2025-08-18)
**目標**: 実際のプラグインライブラリ作成と統合
**実装戦略**:
@ -75,8 +75,15 @@
- ✅ Nyashインタープリターのプラグインロード統合
- ✅ 透過的切り替え実動作確認PluginBox生成確認
**残作業最後の10%**:
- ⏳ PluginBoxのtoString等メソッド実装修正
**中断理由**:
- 🚨 **古いプラグインシステムのコードが混在していた**
- 🔧 ソースコードをcommit 3f7d71f古いプラグイン実装前に巻き戻し
- 📚 docsフォルダは最新状態を維持
- ✅ nyashバイナリの基本動作確認完了
**再開時の作業**:
- ⏳ BID-FFIシステムをクリーンに再実装
- ⏳ PluginBoxのtoString等メソッド実装
- ⏳ 実際のファイル操作メソッドopen/read/write動作確認
### 🎯 今週の実装計画(段階的戦略に更新)
@ -153,27 +160,35 @@ cargo build --release -j32
```
---
**最終更新**: 2025-08-17 26:30
**次回レビュー**: 2025-08-18Day 5-6完了時)
**最終更新**: 2025-08-18 08:30 JST
**次回レビュー**: 2025-08-18BID-FFI再実装開始時)
## 🎯 **Day 5 最終段階の詳細**
## 🎯 **現在の状況** (2025-08-18)
### 現在の動作状況
1. **nyash.tomlなし**: ビルトインFileBox動作
2. **nyash.tomlあり**: プラグインFileBoxロード成功 ✅
3. **PluginBox生成**: 成功type_name: PluginBox
4. **toString呼び出し**: エラーPluginBoxプロキシが未完成
### クリーンアップ完了
1. **古いプラグインシステム削除**: ソースコードをcommit 3f7d71fに巻き戻し
2. **ドキュメント保持**: docs/は最新の状態を維持 ✅
3. **基本動作確認**: nyashバイナリが正常動作
4. **ビルド成功**: `cargo build --release --bin nyash` 完了 ✅
### 残作業詳細
1. **PluginBox完全実装**
- toStringメソッドのプラグイン呼び出し
- ファイル操作メソッドopen/read/write/close転送
### BID-FFI実装状況
- **仕様**: 完成済みdocs/説明書/reference/box-design/ffi-abi-specification.md
- **設計**: 完成済みdocs/説明書/reference/box-design/plugin-system.md
- **基盤コード**: src/bid/モジュールは削除済み(再実装必要)
- **プラグイン**: plugins/nyash-filebox-pluginも削除済み再作成必要
2. **BID-FFI統合**
- TLVエンコード/デコードの実際の動作
- メソッドディスパッチの実装
### 次のステップ
1. **BID-FFIシステムをクリーンに再実装**
- src/bid/モジュール作成
- TLVエンコード/デコード実装
- プラグインローダー実装
### 実証成功の証拠
- プラグイン動的ロード: `✅ Plugin library loaded: nyash_filebox_plugin`
- BoxFactoryRegistry統合: FileBox → PluginBox自動切り替え
- プラグインシステム基盤: 90%完成!
2. **FileBoxプラグイン作成**
- plugins/nyash-filebox-plugin/再作成
- C FFI実装
- ビルドシステム構築
3. **統合テスト**
- nyash.tomlによる切り替え
- プラグイン動的ロード確認
- メソッド呼び出し動作確認

View File

@ -1,13 +0,0 @@
🚀 Nyash MIR Compiler - Processing file: local_tests/test_simple_string.nyash 🚀
🚀 MIR Output for local_tests/test_simple_string.nyash:
; MIR Module: main
define void @main() {
bb0:
0: safepoint
1: %0 = const "Hello"
2: %1 = ref_new %0
3: ret %1
}

View File

@ -0,0 +1,2 @@
[plugins]
FileBox = "nyash_filebox_plugin"

View File

@ -53,8 +53,6 @@ impl AotCompiler {
WasmError::UnsupportedInstruction(msg) => AotError::CompilationError(format!("Unsupported MIR instruction: {}", msg)),
WasmError::WasmValidationError(msg) => AotError::CompilationError(format!("WASM validation failed: {}", msg)),
WasmError::IOError(msg) => AotError::IOError(msg),
WasmError::RuntimeError(msg) => AotError::RuntimeError(msg),
WasmError::CompilationError(msg) => AotError::CompilationError(msg),
})?;
self.stats.wasm_size = wasm_bytes.len();

View File

@ -231,7 +231,12 @@ impl VM {
Ok(ControlFlow::Continue)
},
// Phase 3: UnaryOp removed - now handled by Call intrinsics (@unary_neg, @unary_not, etc.)
MirInstruction::UnaryOp { dst, op, operand } => {
let operand_val = self.get_value(*operand)?;
let result = self.execute_unary_op(op, &operand_val)?;
self.values.insert(*dst, result);
Ok(ControlFlow::Continue)
},
MirInstruction::Compare { dst, op, lhs, rhs } => {
let left = self.get_value(*lhs)?;
@ -241,7 +246,11 @@ impl VM {
Ok(ControlFlow::Continue)
},
// Phase 3: Print removed - now handled by Call intrinsic (@print)
MirInstruction::Print { value, .. } => {
let val = self.get_value(*value)?;
println!("{}", val.to_string());
Ok(ControlFlow::Continue)
},
MirInstruction::Return { value } => {
let return_value = if let Some(val_id) = value {
@ -280,31 +289,27 @@ impl VM {
Ok(ControlFlow::Continue)
},
// Phase 3: Load/Store removed - now handled by BoxFieldLoad/BoxFieldStore
// Missing instructions that need basic implementations
MirInstruction::Load { dst, ptr } => {
// For now, loading is the same as getting the value
let value = self.get_value(*ptr)?;
self.values.insert(*dst, value);
Ok(ControlFlow::Continue)
},
MirInstruction::Call { dst, func, args, effects: _ } => {
// Phase 2: Handle intrinsic function calls
let func_value = self.get_value(*func)?;
MirInstruction::Store { value, ptr } => {
// For now, storing just updates the ptr with the value
let val = self.get_value(*value)?;
self.values.insert(*ptr, val);
Ok(ControlFlow::Continue)
},
if let VMValue::String(func_name) = func_value {
if func_name.starts_with('@') {
// This is an intrinsic call
let result = self.execute_intrinsic(&func_name, args)?;
if let Some(dst_id) = dst {
self.values.insert(*dst_id, result);
}
} else {
// Regular function call - not implemented yet
MirInstruction::Call { dst, func: _, args: _, effects: _ } => {
// For now, function calls return void
// TODO: Implement proper function call handling
if let Some(dst_id) = dst {
self.values.insert(*dst_id, VMValue::Void);
}
}
} else {
// Non-string function - not implemented yet
if let Some(dst_id) = dst {
self.values.insert(*dst_id, VMValue::Void);
}
}
Ok(ControlFlow::Continue)
},
@ -364,27 +369,67 @@ impl VM {
Ok(ControlFlow::Continue)
},
// Phase 5: Removed instructions - TypeCheck, Cast, ArrayGet, ArraySet, Copy, Debug, Nop
#[allow(deprecated)]
MirInstruction::TypeCheck { .. } |
MirInstruction::Cast { .. } |
MirInstruction::ArrayGet { .. } |
MirInstruction::ArraySet { .. } |
MirInstruction::Copy { .. } |
MirInstruction::Debug { .. } |
MirInstruction::Nop => {
Err(VMError::InvalidInstruction(
"Phase 5: Deprecated instruction - use 26-instruction set replacements".to_string()
))
MirInstruction::TypeCheck { dst, value: _, expected_type: _ } => {
// For now, type checks always return true
// TODO: Implement proper type checking
self.values.insert(*dst, VMValue::Bool(true));
Ok(ControlFlow::Continue)
},
// Phase 5: Removed instructions - Throw, Catch
#[allow(deprecated)]
MirInstruction::Throw { .. } |
MirInstruction::Catch { .. } => {
Err(VMError::InvalidInstruction(
"Phase 5: Exception handling via intrinsics - use Call with @throw/@catch".to_string()
))
MirInstruction::Cast { dst, value, target_type: _ } => {
// For now, casting just copies the value
// TODO: Implement proper type casting
let val = self.get_value(*value)?;
self.values.insert(*dst, val);
Ok(ControlFlow::Continue)
},
MirInstruction::ArrayGet { dst, array: _, index: _ } => {
// For now, array access returns a placeholder
// TODO: Implement proper array access
self.values.insert(*dst, VMValue::Integer(0));
Ok(ControlFlow::Continue)
},
MirInstruction::ArraySet { array: _, index: _, value: _ } => {
// For now, array setting is a no-op
// TODO: Implement proper array setting
Ok(ControlFlow::Continue)
},
MirInstruction::Copy { dst, src } => {
// Copy instruction - duplicate the source value
let val = self.get_value(*src)?;
self.values.insert(*dst, val);
Ok(ControlFlow::Continue)
},
MirInstruction::Debug { value, message: _ } => {
// Debug instruction - print value for debugging
let val = self.get_value(*value)?;
println!("DEBUG: {}", val.to_string());
Ok(ControlFlow::Continue)
},
MirInstruction::Nop => {
// No-op instruction
Ok(ControlFlow::Continue)
},
// Phase 5: Control flow & exception handling
MirInstruction::Throw { exception, effects: _ } => {
let exception_val = self.get_value(*exception)?;
// For now, convert throw to error return (simplified exception handling)
// In a full implementation, this would unwind the stack looking for catch handlers
println!("Exception thrown: {}", exception_val.to_string());
Err(VMError::InvalidInstruction(format!("Unhandled exception: {}", exception_val.to_string())))
},
MirInstruction::Catch { exception_type: _, exception_value, handler_bb: _ } => {
// For now, catch is a no-op since we don't have full exception handling
// In a real implementation, this would set up exception handling metadata
self.values.insert(*exception_value, VMValue::Void);
Ok(ControlFlow::Continue)
},
MirInstruction::Safepoint => {
@ -393,15 +438,49 @@ impl VM {
Ok(ControlFlow::Continue)
},
// Phase 5: Removed instruction - RefNew
#[allow(deprecated)]
MirInstruction::RefNew { .. } => {
Err(VMError::InvalidInstruction(
"Phase 5: RefNew deprecated - RefGet is sufficient".to_string()
))
// Phase 6: Box reference operations
MirInstruction::RefNew { dst, box_val } => {
// For now, a reference is just the same as the box value
// In a real implementation, this would create a proper reference
let box_value = self.get_value(*box_val)?;
self.values.insert(*dst, box_value);
Ok(ControlFlow::Continue)
},
// Phase 3: RefGet/RefSet removed - now handled by BoxFieldLoad/BoxFieldStore
MirInstruction::RefGet { dst, reference, field } => {
// Get field value from object
let field_value = if let Some(fields) = self.object_fields.get(reference) {
if let Some(value) = fields.get(field) {
value.clone()
} else {
// Field not set yet, return default
VMValue::Integer(0)
}
} else {
// Object has no fields yet, return default
VMValue::Integer(0)
};
self.values.insert(*dst, field_value);
Ok(ControlFlow::Continue)
},
MirInstruction::RefSet { reference, field, value } => {
// Get the value to set
let new_value = self.get_value(*value)?;
// Ensure object has field storage
if !self.object_fields.contains_key(reference) {
self.object_fields.insert(*reference, HashMap::new());
}
// Set the field
if let Some(fields) = self.object_fields.get_mut(reference) {
fields.insert(field.clone(), new_value);
}
Ok(ControlFlow::Continue)
},
MirInstruction::WeakNew { dst, box_val } => {
// For now, a weak reference is just a copy of the value
@ -419,23 +498,61 @@ impl VM {
Ok(ControlFlow::Continue)
},
// Phase 5: Removed instructions - BarrierRead, BarrierWrite
#[allow(deprecated)]
MirInstruction::BarrierRead { .. } |
MirInstruction::BarrierWrite { .. } => {
Err(VMError::InvalidInstruction(
"Phase 5: Memory barriers deprecated - use AtomicFence".to_string()
))
MirInstruction::BarrierRead { ptr: _ } => {
// Memory barrier read is a no-op for now
// In a real implementation, this would ensure memory ordering
Ok(ControlFlow::Continue)
},
// Phase 5: Removed instructions - FutureNew, FutureSet, Await
#[allow(deprecated)]
MirInstruction::FutureNew { .. } |
MirInstruction::FutureSet { .. } |
MirInstruction::Await { .. } => {
Err(VMError::InvalidInstruction(
"Phase 5: Future operations deprecated - use NewBox + BoxCall".to_string()
))
MirInstruction::BarrierWrite { ptr: _ } => {
// Memory barrier write is a no-op for now
// In a real implementation, this would ensure memory ordering
Ok(ControlFlow::Continue)
},
// Phase 7: Async/Future Operations
MirInstruction::FutureNew { dst, value } => {
let initial_value = self.get_value(*value)?;
println!("FutureNew: initial_value = {:?}", initial_value);
let future = crate::boxes::future::FutureBox::new();
// Convert VMValue to NyashBox and set it in the future
let nyash_box = initial_value.to_nyash_box();
println!("FutureNew: converted to NyashBox type = {}", nyash_box.type_name());
future.set_result(nyash_box);
self.values.insert(*dst, VMValue::Future(future));
println!("FutureNew: stored Future in dst = {:?}", dst);
Ok(ControlFlow::Continue)
},
MirInstruction::FutureSet { future, value } => {
let future_val = self.get_value(*future)?;
let new_value = self.get_value(*value)?;
if let VMValue::Future(ref future_box) = future_val {
future_box.set_result(new_value.to_nyash_box());
Ok(ControlFlow::Continue)
} else {
Err(VMError::TypeError(format!("Expected Future, got {:?}", future_val)))
}
},
MirInstruction::Await { dst, future } => {
let future_val = self.get_value(*future)?;
println!("Await: future_val = {:?}", future_val);
if let VMValue::Future(ref future_box) = future_val {
// This blocks until the future is ready
let result = future_box.get();
println!("Await: future.get() returned type = {}", result.type_name());
println!("Await: future.get() string = {}", result.to_string_box().value);
// Convert NyashBox back to VMValue
let vm_value = VMValue::from_nyash_box(result);
println!("Await: converted back to VMValue = {:?}", vm_value);
self.values.insert(*dst, vm_value);
Ok(ControlFlow::Continue)
} else {
Err(VMError::TypeError(format!("Expected Future, got {:?}", future_val)))
}
},
// Phase 9.7: External Function Calls
@ -468,134 +585,6 @@ impl VM {
Ok(ControlFlow::Continue)
},
// Phase 8.5: MIR 26-instruction reduction (NEW)
MirInstruction::BoxFieldLoad { dst, box_val, field } => {
// Load field from box (Everything is Box principle)
let box_value = self.get_value(*box_val)?;
// For now, simulate field access - in full implementation,
// this would access actual Box structure fields
let field_value = match field.as_str() {
"value" => box_value.clone(), // Default field
"type" => VMValue::String(format!("{}Field", box_val)),
_ => VMValue::String(format!("field_{}", field)),
};
self.values.insert(*dst, field_value);
Ok(ControlFlow::Continue)
},
MirInstruction::BoxFieldStore { box_val, field: _, value } => {
// Store field in box (Everything is Box principle)
let _box_value = self.get_value(*box_val)?;
let _store_value = self.get_value(*value)?;
// For now, this is a no-op - in full implementation,
// this would modify actual Box structure fields
// println!("Storing {} in {}.{}", store_value, box_val, field);
Ok(ControlFlow::Continue)
},
MirInstruction::WeakCheck { dst, weak_ref } => {
// Check if weak reference is still alive
let _weak_value = self.get_value(*weak_ref)?;
// For now, always return true - in full implementation,
// this would check actual weak reference validity
self.values.insert(*dst, VMValue::Bool(true));
Ok(ControlFlow::Continue)
},
MirInstruction::Send { data, target } => {
// Send data via Bus system
let _data_value = self.get_value(*data)?;
let _target_value = self.get_value(*target)?;
// For now, this is a no-op - in full implementation,
// this would use the Bus communication system
// println!("Sending {} to {}", data_value, target_value);
Ok(ControlFlow::Continue)
},
MirInstruction::Recv { dst, source } => {
// Receive data from Bus system
let _source_value = self.get_value(*source)?;
// For now, return a placeholder - in full implementation,
// this would receive from actual Bus communication
self.values.insert(*dst, VMValue::String("received_data".to_string()));
Ok(ControlFlow::Continue)
},
MirInstruction::TailCall { func, args, effects: _ } => {
// Tail call optimization - call function and return immediately
let _func_value = self.get_value(*func)?;
let _arg_values: Result<Vec<_>, _> = args.iter().map(|arg| self.get_value(*arg)).collect();
// For now, this is simplified - in full implementation,
// this would optimize the call stack
// println!("Tail calling function with {} args", args.len());
Ok(ControlFlow::Continue)
},
MirInstruction::Adopt { parent, child } => {
// Adopt ownership (parent takes child)
let _parent_value = self.get_value(*parent)?;
let _child_value = self.get_value(*child)?;
// For now, this is a no-op - in full implementation,
// this would modify ownership relationships
// println!("Parent {} adopts child {}", parent, child);
Ok(ControlFlow::Continue)
},
MirInstruction::Release { reference } => {
// Release strong ownership
let _ref_value = self.get_value(*reference)?;
// For now, this is a no-op - in full implementation,
// this would release strong ownership and potentially weak-ify
// println!("Releasing ownership of {}", reference);
Ok(ControlFlow::Continue)
},
MirInstruction::MemCopy { dst, src, size } => {
// Memory copy optimization
let src_value = self.get_value(*src)?;
let _size_value = self.get_value(*size)?;
// For now, just copy the source value
self.values.insert(*dst, src_value);
Ok(ControlFlow::Continue)
},
MirInstruction::AtomicFence { ordering: _ } => {
// Atomic memory fence
// For now, this is a no-op - in full implementation,
// this would ensure proper memory ordering for parallel execution
// println!("Memory fence with ordering: {:?}", ordering);
Ok(ControlFlow::Continue)
},
// Phase 3: Removed instructions that are no longer generated by frontend
MirInstruction::UnaryOp { .. } |
MirInstruction::Print { .. } |
MirInstruction::Load { .. } |
MirInstruction::Store { .. } |
MirInstruction::RefGet { .. } |
MirInstruction::RefSet { .. } => {
Err(VMError::InvalidInstruction(
"Old instruction format no longer supported - use new intrinsic/BoxField format".to_string()
))
},
}
}
@ -802,86 +791,6 @@ impl VM {
// Default: return void for any unrecognized box type or method
Ok(Box::new(VoidBox::new()))
}
/// Execute intrinsic function call (Phase 2 addition)
fn execute_intrinsic(&mut self, intrinsic_name: &str, args: &[ValueId]) -> Result<VMValue, VMError> {
match intrinsic_name {
"@print" => {
// Print intrinsic - output the first argument
if let Some(arg_id) = args.first() {
let value = self.get_value(*arg_id)?;
match value {
VMValue::String(s) => println!("{}", s),
VMValue::Integer(i) => println!("{}", i),
VMValue::Float(f) => println!("{}", f),
VMValue::Bool(b) => println!("{}", b),
VMValue::Void => println!("void"),
VMValue::Future(_) => println!("Future"),
}
}
Ok(VMValue::Void) // Print returns void
},
"@unary_neg" => {
// Unary negation intrinsic
if let Some(arg_id) = args.first() {
let value = self.get_value(*arg_id)?;
match value {
VMValue::Integer(i) => Ok(VMValue::Integer(-i)),
VMValue::Float(f) => Ok(VMValue::Float(-f)),
_ => Err(VMError::TypeError(format!("Cannot negate {:?}", value))),
}
} else {
Err(VMError::TypeError("@unary_neg requires 1 argument".to_string()))
}
},
"@unary_not" => {
// Unary logical NOT intrinsic
if let Some(arg_id) = args.first() {
let value = self.get_value(*arg_id)?;
match value {
VMValue::Bool(b) => Ok(VMValue::Bool(!b)),
VMValue::Integer(i) => Ok(VMValue::Bool(i == 0)), // 0 is false, non-zero is true
_ => Err(VMError::TypeError(format!("Cannot apply NOT to {:?}", value))),
}
} else {
Err(VMError::TypeError("@unary_not requires 1 argument".to_string()))
}
},
"@unary_bitnot" => {
// Unary bitwise NOT intrinsic
if let Some(arg_id) = args.first() {
let value = self.get_value(*arg_id)?;
match value {
VMValue::Integer(i) => Ok(VMValue::Integer(!i)),
_ => Err(VMError::TypeError(format!("Cannot apply bitwise NOT to {:?}", value))),
}
} else {
Err(VMError::TypeError("@unary_bitnot requires 1 argument".to_string()))
}
},
"@throw" => {
// Throw intrinsic - for now just print the exception
if let Some(arg_id) = args.first() {
let value = self.get_value(*arg_id)?;
println!("Exception thrown: {:?}", value);
}
Err(VMError::InvalidInstruction("Exception thrown".to_string()))
},
"@set_exception_handler" => {
// Exception handler setup - for now just return success
Ok(VMValue::Void)
},
_ => {
Err(VMError::InvalidInstruction(format!("Unknown intrinsic: {}", intrinsic_name)))
}
}
}
}
/// Control flow result from instruction execution

View File

@ -244,18 +244,47 @@ impl WasmCodegen {
self.generate_return(value.as_ref())
},
// Phase 3: Print removed - now handled by Call intrinsic (@print)
// Phase 8.3 PoC2: Reference operations
// Phase 5: RefNew deprecated - just use the value directly
#[allow(deprecated)]
MirInstruction::RefNew { .. } => {
Err(WasmError::UnsupportedInstruction(
"Phase 5: RefNew deprecated - references are handled implicitly".to_string()
))
MirInstruction::Print { value, .. } => {
self.generate_print(*value)
},
// Phase 3: RefGet/RefSet removed - now handled by BoxFieldLoad/BoxFieldStore
// Phase 8.3 PoC2: Reference operations
MirInstruction::RefNew { dst, box_val } => {
// Create a new reference to a Box by copying the Box value
// This assumes box_val contains a Box pointer already
Ok(vec![
format!("local.get ${}", self.get_local_index(*box_val)?),
format!("local.set ${}", self.get_local_index(*dst)?),
])
},
MirInstruction::RefGet { dst, reference, field: _ } => {
// Load field value from Box through reference
// reference contains Box pointer, field is the field name
// For now, assume all fields are at offset 12 (first field after header)
// TODO: Add proper field offset calculation
Ok(vec![
format!("local.get ${}", self.get_local_index(*reference)?),
"i32.const 12".to_string(), // Offset: header (12 bytes) + first field
"i32.add".to_string(),
"i32.load".to_string(),
format!("local.set ${}", self.get_local_index(*dst)?),
])
},
MirInstruction::RefSet { reference, field: _, value } => {
// Store field value to Box through reference
// reference contains Box pointer, field is the field name, value is new value
// For now, assume all fields are at offset 12 (first field after header)
// TODO: Add proper field offset calculation
Ok(vec![
format!("local.get ${}", self.get_local_index(*reference)?),
"i32.const 12".to_string(), // Offset: header (12 bytes) + first field
"i32.add".to_string(),
format!("local.get ${}", self.get_local_index(*value)?),
"i32.store".to_string(),
])
},
MirInstruction::NewBox { dst, box_type, args } => {
// Create a new Box using the generic allocator
@ -294,54 +323,29 @@ impl WasmCodegen {
},
// Phase 8.4 PoC3: Extension stubs
MirInstruction::WeakNew { dst, box_val } => {
// WeakNew is still part of 26-instruction set
MirInstruction::WeakNew { dst, box_val } |
MirInstruction::FutureNew { dst, value: box_val } => {
// Treat as regular reference for now
Ok(vec![
format!("local.get ${}", self.get_local_index(*box_val)?),
format!("local.set ${}", self.get_local_index(*dst)?),
])
},
// Phase 5: FutureNew deprecated - use NewBox "Future"
#[allow(deprecated)]
MirInstruction::FutureNew { .. } => {
Err(WasmError::UnsupportedInstruction(
"Phase 5: FutureNew deprecated - use 'NewBox \"Future\"' instead".to_string()
))
},
MirInstruction::WeakLoad { dst, weak_ref } => {
// WeakLoad is still part of 26-instruction set
MirInstruction::WeakLoad { dst, weak_ref } |
MirInstruction::Await { dst, future: weak_ref } => {
// Always succeed for now
Ok(vec![
format!("local.get ${}", self.get_local_index(*weak_ref)?),
format!("local.set ${}", self.get_local_index(*dst)?),
])
},
// Phase 5: Await deprecated - use BoxCall Future.await()
#[allow(deprecated)]
MirInstruction::Await { .. } => {
Err(WasmError::UnsupportedInstruction(
"Phase 5: Await deprecated - use 'BoxCall Future.await()' instead".to_string()
))
},
// Phase 5: BarrierRead/BarrierWrite deprecated - use AtomicFence
#[allow(deprecated)]
MirInstruction::BarrierRead { .. } => {
Err(WasmError::UnsupportedInstruction(
"Phase 5: BarrierRead deprecated - use AtomicFence with acquire ordering".to_string()
))
},
#[allow(deprecated)]
MirInstruction::BarrierWrite { .. } => {
Err(WasmError::UnsupportedInstruction(
"Phase 5: BarrierWrite deprecated - use AtomicFence with release ordering".to_string()
))
},
MirInstruction::BarrierRead { .. } |
MirInstruction::BarrierWrite { .. } |
MirInstruction::FutureSet { .. } |
MirInstruction::Safepoint => {
// Safepoint is still valid - no-op for now
// No-op for now
Ok(vec!["nop".to_string()])
},
@ -404,189 +408,6 @@ impl WasmCodegen {
self.generate_box_call(*dst, *box_val, method, args)
},
// Phase 8.5: MIR 26-instruction reduction (NEW)
MirInstruction::BoxFieldLoad { dst, box_val, field: _ } => {
// Load field from box (similar to RefGet but with explicit Box semantics)
// For now, assume all fields are at offset 12 (first field after header)
Ok(vec![
format!("local.get ${}", self.get_local_index(*box_val)?),
"i32.const 12".to_string(), // Box header + first field offset
"i32.add".to_string(),
"i32.load".to_string(),
format!("local.set ${}", self.get_local_index(*dst)?),
])
},
MirInstruction::BoxFieldStore { box_val, field: _, value } => {
// Store field to box (similar to RefSet but with explicit Box semantics)
Ok(vec![
format!("local.get ${}", self.get_local_index(*box_val)?),
"i32.const 12".to_string(), // Box header + first field offset
"i32.add".to_string(),
format!("local.get ${}", self.get_local_index(*value)?),
"i32.store".to_string(),
])
},
MirInstruction::WeakCheck { dst, weak_ref } => {
// Check if weak reference is still alive
// For now, always return 1 (true) - in full implementation,
// this would check actual weak reference validity
Ok(vec![
format!("local.get ${}", self.get_local_index(*weak_ref)?), // Touch the ref
"drop".to_string(), // Ignore the actual value
"i32.const 1".to_string(), // Always alive for now
format!("local.set ${}", self.get_local_index(*dst)?),
])
},
MirInstruction::Send { data, target } => {
// Send data via Bus system - no-op for now
Ok(vec![
format!("local.get ${}", self.get_local_index(*data)?),
format!("local.get ${}", self.get_local_index(*target)?),
"drop".to_string(), // Drop target
"drop".to_string(), // Drop data
"nop".to_string(), // No actual send operation
])
},
MirInstruction::Recv { dst, source } => {
// Receive data from Bus system - return constant for now
Ok(vec![
format!("local.get ${}", self.get_local_index(*source)?), // Touch source
"drop".to_string(), // Ignore source
"i32.const 42".to_string(), // Placeholder received data
format!("local.set ${}", self.get_local_index(*dst)?),
])
},
MirInstruction::TailCall { func, args, effects: _ } => {
// Tail call optimization - simplified as regular call for now
let mut instructions = Vec::new();
// Load all arguments
for arg in args {
instructions.push(format!("local.get ${}", self.get_local_index(*arg)?));
}
// Call function (assuming it's a function index)
instructions.push(format!("local.get ${}", self.get_local_index(*func)?));
instructions.push("call_indirect".to_string());
Ok(instructions)
},
MirInstruction::Adopt { parent, child } => {
// Adopt ownership - no-op for now in WASM
Ok(vec![
format!("local.get ${}", self.get_local_index(*parent)?),
format!("local.get ${}", self.get_local_index(*child)?),
"drop".to_string(), // Drop child
"drop".to_string(), // Drop parent
"nop".to_string(), // No actual adoption
])
},
MirInstruction::Release { reference } => {
// Release strong ownership - no-op for now
Ok(vec![
format!("local.get ${}", self.get_local_index(*reference)?),
"drop".to_string(), // Drop reference
"nop".to_string(), // No actual release
])
},
MirInstruction::MemCopy { dst, src, size } => {
// Memory copy optimization - simple copy for now
Ok(vec![
format!("local.get ${}", self.get_local_index(*src)?),
format!("local.set ${}", self.get_local_index(*dst)?),
// Size is ignored for now - in full implementation,
// this would use memory.copy instruction
format!("local.get ${}", self.get_local_index(*size)?),
"drop".to_string(),
])
},
MirInstruction::AtomicFence { ordering: _ } => {
// Atomic memory fence - no-op for now
// WASM doesn't have direct memory fence instructions
// In full implementation, this might use atomic wait/notify
Ok(vec!["nop".to_string()])
},
// Phase 4: Call instruction for intrinsic functions
MirInstruction::Call { dst, func, args, effects: _ } => {
self.generate_call_instruction(dst.as_ref(), *func, args)
},
// Phase 5: Removed instructions - TypeCheck, Cast, ArrayGet, ArraySet, Copy, Debug, Nop
#[allow(deprecated)]
MirInstruction::TypeCheck { .. } |
MirInstruction::Cast { .. } |
MirInstruction::ArrayGet { .. } |
MirInstruction::ArraySet { .. } |
MirInstruction::Copy { .. } |
MirInstruction::Debug { .. } |
MirInstruction::Nop => {
Err(WasmError::UnsupportedInstruction(
"Phase 5: Deprecated instruction - use 26-instruction set replacements".to_string()
))
},
// Phase 5: Removed instructions - UnaryOp (use BinOp instead)
#[allow(deprecated)]
MirInstruction::UnaryOp { .. } => {
Err(WasmError::UnsupportedInstruction(
"Phase 5: UnaryOp deprecated - use BinOp (e.g., 'not x' -> 'x xor true', 'neg x' -> '0 sub x')".to_string()
))
},
// Phase 5: Removed instructions - Load/Store (use BoxFieldLoad/BoxFieldStore)
#[allow(deprecated)]
MirInstruction::Load { .. } => {
Err(WasmError::UnsupportedInstruction(
"Phase 5: Load deprecated - use BoxFieldLoad for field access".to_string()
))
},
#[allow(deprecated)]
MirInstruction::Store { .. } => {
Err(WasmError::UnsupportedInstruction(
"Phase 5: Store deprecated - use BoxFieldStore for field updates".to_string()
))
},
// Phase 5: Removed instructions - Print (use Call @print)
#[allow(deprecated)]
MirInstruction::Print { .. } => {
Err(WasmError::UnsupportedInstruction(
"Phase 5: Print deprecated - use 'Call @print' intrinsic function".to_string()
))
},
// Phase 5: Removed instructions - Throw/Catch (use Call @throw/@catch)
#[allow(deprecated)]
MirInstruction::Throw { .. } => {
Err(WasmError::UnsupportedInstruction(
"Phase 5: Throw deprecated - use 'Call @throw' intrinsic function".to_string()
))
},
#[allow(deprecated)]
MirInstruction::Catch { .. } => {
Err(WasmError::UnsupportedInstruction(
"Phase 5: Catch deprecated - use 'Call @catch' intrinsic function".to_string()
))
},
// Phase 5: Removed FutureSet - use BoxCall instead
#[allow(deprecated)]
MirInstruction::FutureSet { .. } => {
Err(WasmError::UnsupportedInstruction(
"Phase 5: FutureSet deprecated - use BoxCall method for Future.set()".to_string()
))
},
// Unsupported instructions
_ => Err(WasmError::UnsupportedInstruction(
format!("Instruction not yet supported: {:?}", instruction)
@ -865,36 +686,6 @@ impl WasmCodegen {
Ok(instructions)
}
/// Generate Call instruction for intrinsic functions (Phase 4)
fn generate_call_instruction(&mut self, dst: Option<&ValueId>, func: ValueId, args: &[ValueId]) -> Result<Vec<String>, WasmError> {
// Get the function name from the func ValueId
// In MIR, intrinsic function names are stored as string constants
let mut instructions = Vec::new();
// For intrinsic functions, we handle them based on their name
// The func ValueId should contain a string constant like "@print"
// For now, assume all calls are @print intrinsic
// TODO: Implement proper function name resolution from ValueId
// Load all arguments onto stack in order
for arg in args {
instructions.push(format!("local.get ${}", self.get_local_index(*arg)?));
}
// Call the print function (assuming it's imported as $print)
instructions.push("call $print".to_string());
// Store result if destination is provided
if let Some(dst) = dst {
// Intrinsic functions typically return void, but we provide a dummy value
instructions.push("i32.const 0".to_string()); // Void result
instructions.push(format!("local.set ${}", self.get_local_index(*dst)?));
}
Ok(instructions)
}
}
#[cfg(test)]

View File

@ -8,13 +8,10 @@
mod codegen;
mod memory;
mod runtime;
mod host;
mod executor;
pub use codegen::{WasmCodegen, WasmModule};
pub use memory::{MemoryManager, BoxLayout};
pub use runtime::RuntimeImports;
pub use executor::WasmExecutor;
use crate::mir::MirModule;
@ -26,8 +23,6 @@ pub enum WasmError {
UnsupportedInstruction(String),
WasmValidationError(String),
IOError(String),
RuntimeError(String),
CompilationError(String),
}
impl std::fmt::Display for WasmError {
@ -38,8 +33,6 @@ impl std::fmt::Display for WasmError {
WasmError::UnsupportedInstruction(msg) => write!(f, "Unsupported instruction: {}", msg),
WasmError::WasmValidationError(msg) => write!(f, "WASM validation error: {}", msg),
WasmError::IOError(msg) => write!(f, "IO error: {}", msg),
WasmError::RuntimeError(msg) => write!(f, "Runtime error: {}", msg),
WasmError::CompilationError(msg) => write!(f, "Compilation error: {}", msg),
}
}
}

View File

@ -3,7 +3,6 @@
// 参考: 既存Boxの設計思想
use crate::box_trait::{NyashBox, StringBox, BoolBox, BoxCore, BoxBase};
use crate::bid::{BidBridge, BidHandle, BidType, BidError, BoxRegistry};
use std::any::Any;
use std::sync::RwLock;
@ -147,25 +146,6 @@ impl std::fmt::Display for NyashFutureBox {
}
}
impl BidBridge for NyashFutureBox {
fn to_bid_handle(&self, registry: &mut BoxRegistry) -> Result<BidHandle, BidError> {
use std::sync::Arc;
let arc_box: Arc<dyn NyashBox> = Arc::new(self.clone());
let handle = registry.register_box(
crate::bid::types::BoxTypeId::FutureBox as u32,
arc_box
);
Ok(handle)
}
fn bid_type(&self) -> BidType {
BidType::Handle {
type_id: crate::bid::types::BoxTypeId::FutureBox as u32,
instance_id: 0 // Will be filled by registry
}
}
}
// Export NyashFutureBox as FutureBox for consistency
pub type FutureBox = NyashFutureBox;

View File

@ -38,7 +38,6 @@
*/
use crate::box_trait::{NyashBox, BoxCore, BoxBase};
use crate::bid::{BidBridge, BidHandle, BidType, BidError, BoxRegistry};
use std::any::Any;
use std::fmt::Display;
@ -118,22 +117,3 @@ impl Display for IntegerBox {
self.fmt_box(f)
}
}
impl BidBridge for IntegerBox {
fn to_bid_handle(&self, registry: &mut BoxRegistry) -> Result<BidHandle, BidError> {
use std::sync::Arc;
let arc_box: Arc<dyn NyashBox> = Arc::new(self.clone());
let handle = registry.register_box(
crate::bid::types::BoxTypeId::IntegerBox as u32,
arc_box
);
Ok(handle)
}
fn bid_type(&self) -> BidType {
BidType::Handle {
type_id: crate::bid::types::BoxTypeId::IntegerBox as u32,
instance_id: 0 // Will be filled by registry
}
}
}

View File

@ -28,7 +28,6 @@
* ```
*/
use crate::box_trait::{NyashBox, BoxCore, BoxBase};
use crate::bid::{BidBridge, BidHandle, BidType, BidError, BoxRegistry};
use std::any::Any;
use std::fmt::Display;
@ -186,22 +185,3 @@ impl Display for StringBox {
self.fmt_box(f)
}
}
impl BidBridge for StringBox {
fn to_bid_handle(&self, registry: &mut BoxRegistry) -> Result<BidHandle, BidError> {
use std::sync::Arc;
let arc_box: Arc<dyn NyashBox> = Arc::new(self.clone());
let handle = registry.register_box(
crate::bid::types::BoxTypeId::StringBox as u32,
arc_box
);
Ok(handle)
}
fn bid_type(&self) -> BidType {
BidType::Handle {
type_id: crate::bid::types::BoxTypeId::StringBox as u32,
instance_id: 0 // Will be filled by registry
}
}
}

View File

@ -516,7 +516,7 @@ mod tests {
// フィールドに値を設定
let int_value = Box::new(IntegerBox::new(42)) as Box<dyn NyashBox>;
instance.set_field("value", int_value.into()).unwrap();
instance.set_field("value", int_value).unwrap();
// フィールドの値を取得
let retrieved = instance.get_field("value").unwrap();

View File

@ -350,13 +350,13 @@ impl NyashInterpreter {
// 2. local変数をチェック
if let Some(local_value) = self.local_vars.get(name) {
eprintln!("🔍 DEBUG: Found '{}' in local_vars, type: {}", name, local_value.type_name());
eprintln!("🔍 DEBUG: Found '{}' in local_vars", name);
// 🔧 修正clone_box() → Arc::clone() で参照共有
let shared_value = Arc::clone(local_value);
eprintln!("✅ RESOLVE_VARIABLE shared reference: {} id={}, type: {}",
name, shared_value.box_id(), shared_value.type_name());
eprintln!("✅ RESOLVE_VARIABLE shared reference: {} id={}",
name, shared_value.box_id());
return Ok(shared_value);
}
@ -478,12 +478,7 @@ impl NyashInterpreter {
/// local変数を宣言関数内でのみ有効
pub(super) fn declare_local_variable(&mut self, name: &str, value: Box<dyn NyashBox>) {
eprintln!("🔍 DEBUG: declare_local_variable '{}' with type: {}, id: {}",
name, value.type_name(), value.box_id());
let arc_value: Arc<dyn NyashBox> = Arc::from(value);
eprintln!("🔍 DEBUG: After Arc::from, type: {}, id: {}",
arc_value.type_name(), arc_value.box_id());
self.local_vars.insert(name.to_string(), arc_value);
self.local_vars.insert(name.to_string(), Arc::from(value));
}
/// outbox変数を宣言static関数内で所有権移転

View File

@ -13,8 +13,6 @@ use crate::instance::InstanceBox;
use crate::channel_box::ChannelBox;
use crate::interpreter::core::{NyashInterpreter, RuntimeError};
use crate::interpreter::finalization;
#[cfg(feature = "dynamic-file")]
use crate::interpreter::plugin_loader::FileBoxProxy;
use std::sync::Arc;
impl NyashInterpreter {
@ -257,18 +255,6 @@ impl NyashInterpreter {
return self.execute_file_method(file_box, method, arguments);
}
// FileBoxProxy method calls (動的ライブラリ版)
#[cfg(feature = "dynamic-file")]
{
eprintln!("🔍 DEBUG: Checking if object is FileBoxProxy, type_name: {}", obj_value.type_name());
if let Some(file_proxy) = obj_value.as_any().downcast_ref::<crate::interpreter::plugin_loader::FileBoxProxy>() {
eprintln!("✅ DEBUG: Object is FileBoxProxy, calling execute_file_proxy_method");
return self.execute_file_proxy_method(file_proxy, method, arguments);
} else {
eprintln!("❌ DEBUG: Object is NOT FileBoxProxy");
}
}
// ResultBox method calls
if let Some(result_box) = obj_value.as_any().downcast_ref::<crate::box_trait::ResultBox>() {
return self.execute_result_method(result_box, method, arguments);

View File

@ -8,10 +8,7 @@
use super::*;
use crate::boxes::{buffer::BufferBox, JSONBox, HttpClientBox, StreamBox, RegexBox, IntentBox, SocketBox, HTTPServerBox, HTTPRequestBox, HTTPResponseBox};
#[cfg(not(feature = "dynamic-file"))]
use crate::boxes::{FloatBox, MathBox, ConsoleBox, TimeBox, DateTimeBox, RandomBox, SoundBox, DebugBox, file::FileBox, MapBox};
#[cfg(feature = "dynamic-file")]
use crate::boxes::{FloatBox, ConsoleBox, SoundBox, DebugBox, MapBox};
use std::sync::Arc;
impl NyashInterpreter {
@ -241,43 +238,25 @@ impl NyashInterpreter {
}
// MathBox method calls
#[cfg(not(feature = "dynamic-file"))]
if let Some(math_box) = obj_value.as_any().downcast_ref::<MathBox>() {
return self.execute_math_method(math_box, method, arguments);
}
#[cfg(feature = "dynamic-file")]
if let Some(math_proxy) = obj_value.as_any().downcast_ref::<crate::interpreter::plugin_loader::MathBoxProxy>() {
return self.execute_math_proxy_method(math_proxy, method, arguments);
}
// NullBox method calls
if let Some(null_box) = obj_value.as_any().downcast_ref::<crate::boxes::null_box::NullBox>() {
return self.execute_null_method(null_box, method, arguments);
}
// TimeBox method calls
#[cfg(not(feature = "dynamic-file"))]
if let Some(time_box) = obj_value.as_any().downcast_ref::<TimeBox>() {
return self.execute_time_method(time_box, method, arguments);
}
#[cfg(feature = "dynamic-file")]
if let Some(time_proxy) = obj_value.as_any().downcast_ref::<crate::interpreter::plugin_loader::TimeBoxProxy>() {
return self.execute_time_proxy_method(time_proxy, method, arguments);
}
// DateTimeBox method calls
#[cfg(not(feature = "dynamic-file"))]
if let Some(datetime_box) = obj_value.as_any().downcast_ref::<DateTimeBox>() {
return self.execute_datetime_method(datetime_box, method, arguments);
}
#[cfg(feature = "dynamic-file")]
if let Some(datetime_proxy) = obj_value.as_any().downcast_ref::<crate::interpreter::plugin_loader::DateTimeBoxProxy>() {
return self.execute_datetime_proxy_method(datetime_proxy, method, arguments);
}
// TimerBox method calls
if let Some(timer_box) = obj_value.as_any().downcast_ref::<TimerBox>() {
return self.execute_timer_method(timer_box, method, arguments);
@ -289,16 +268,10 @@ impl NyashInterpreter {
}
// RandomBox method calls
#[cfg(not(feature = "dynamic-file"))]
if let Some(random_box) = obj_value.as_any().downcast_ref::<RandomBox>() {
return self.execute_random_method(random_box, method, arguments);
}
#[cfg(feature = "dynamic-file")]
if let Some(random_proxy) = obj_value.as_any().downcast_ref::<crate::interpreter::plugin_loader::RandomBoxProxy>() {
return self.execute_random_proxy_method(random_proxy, method, arguments);
}
// SoundBox method calls
if let Some(sound_box) = obj_value.as_any().downcast_ref::<SoundBox>() {
return self.execute_sound_method(sound_box, method, arguments);

View File

@ -10,64 +10,11 @@
use super::super::*;
use crate::box_trait::{ResultBox, StringBox, NyashBox};
use crate::boxes::FileBox;
#[cfg(feature = "dynamic-file")]
use crate::interpreter::plugin_loader::FileBoxProxy;
impl NyashInterpreter {
/// FileBoxのメソッド呼び出しを実行
/// Handles file I/O operations including read, write, exists, delete, and copy
pub(in crate::interpreter) fn execute_file_method(&mut self, file_box: &FileBox, method: &str, arguments: &[ASTNode])
-> Result<Box<dyn NyashBox>, RuntimeError> {
self.execute_file_method_static(file_box, method, arguments)
}
/// FileBoxProxyのメソッド呼び出しを実行動的ライブラリ版
#[cfg(feature = "dynamic-file")]
pub(in crate::interpreter) fn execute_file_proxy_method(&mut self, file_box: &FileBoxProxy, method: &str, arguments: &[ASTNode])
-> Result<Box<dyn NyashBox>, RuntimeError> {
eprintln!("🔍 DEBUG: execute_file_proxy_method called with method: '{}'", method);
match method {
"read" => {
if !arguments.is_empty() {
return Err(RuntimeError::InvalidOperation {
message: format!("read() expects 0 arguments, got {}", arguments.len()),
});
}
file_box.read()
}
"write" => {
if arguments.len() != 1 {
return Err(RuntimeError::InvalidOperation {
message: format!("write() expects 1 argument, got {}", arguments.len()),
});
}
let content = self.execute_expression(&arguments[0])?;
file_box.write(content)
}
"exists" => {
if !arguments.is_empty() {
return Err(RuntimeError::InvalidOperation {
message: format!("exists() expects 0 arguments, got {}", arguments.len()),
});
}
file_box.exists()
}
"toString" => {
if !arguments.is_empty() {
return Err(RuntimeError::InvalidOperation {
message: format!("toString() expects 0 arguments, got {}", arguments.len()),
});
}
Ok(Box::new(file_box.to_string_box()))
}
_ => Err(RuntimeError::InvalidOperation {
message: format!("Undefined method '{}' for FileBox", method),
}),
}
}
/// 静的FileBoxのメソッド実装
fn execute_file_method_static(&mut self, file_box: &FileBox, method: &str, arguments: &[ASTNode])
-> Result<Box<dyn NyashBox>, RuntimeError> {
match method {
"read" => {
@ -118,14 +65,6 @@ impl NyashInterpreter {
})
}
}
"toString" => {
if !arguments.is_empty() {
return Err(RuntimeError::InvalidOperation {
message: format!("toString() expects 0 arguments, got {}", arguments.len()),
});
}
Ok(Box::new(file_box.to_string_box()))
}
_ => Err(RuntimeError::InvalidOperation {
message: format!("Unknown method '{}' for FileBox", method),
})

View File

@ -23,6 +23,5 @@ pub mod data_methods; // BufferBox, JSONBox, RegexBox
pub mod network_methods; // HttpClientBox, StreamBox
pub mod p2p_methods; // IntentBox, P2PBox
pub mod http_methods; // SocketBox, HTTPServerBox, HTTPRequestBox, HTTPResponseBox
pub mod math_methods; // MathBox, RandomBox, TimeBox, DateTimeBox
// Re-export methods for easy access

View File

@ -7,9 +7,7 @@
// Import all necessary dependencies
use crate::ast::{ASTNode, CatchClause};
use crate::box_trait::{NyashBox, StringBox, IntegerBox, BoolBox, VoidBox, ArrayBox, ResultBox, ErrorBox, BoxCore};
#[cfg(not(feature = "dynamic-file"))]
use crate::box_trait::FileBox;
use crate::box_trait::{NyashBox, StringBox, IntegerBox, BoolBox, VoidBox, ArrayBox, FileBox, ResultBox, ErrorBox, BoxCore};
use crate::boxes::FutureBox;
use crate::instance::InstanceBox;
use crate::channel_box::ChannelBox;
@ -42,16 +40,10 @@ mod math_methods;
mod system_methods;
mod web_methods;
mod special_methods;
#[cfg(feature = "dynamic-file")]
mod plugin_loader;
// Main interpreter implementation - will be moved from interpreter.rs
pub use core::NyashInterpreter;
// Dynamic plugin support
#[cfg(feature = "dynamic-file")]
pub use plugin_loader::{PluginLoader, FileBoxProxy};
/// 実行制御フロー
#[derive(Debug)]

View File

@ -7,11 +7,7 @@
*/
use super::*;
use crate::boxes::{NullBox, ConsoleBox, FloatBox, SocketBox, HTTPServerBox, HTTPRequestBox, HTTPResponseBox};
#[cfg(not(feature = "dynamic-file"))]
use crate::boxes::{FileBox, MathBox, RandomBox, TimeBox, DateTimeBox};
#[cfg(feature = "dynamic-file")]
use crate::boxes::DateTimeBox;
use crate::boxes::{NullBox, ConsoleBox, FloatBox, DateTimeBox, SocketBox, HTTPServerBox, HTTPRequestBox, HTTPResponseBox};
// use crate::boxes::intent_box_wrapper::IntentBoxWrapper;
use crate::box_trait::SharedNyashBox;
use std::sync::Arc;
@ -98,18 +94,16 @@ impl NyashInterpreter {
message: format!("FileBox constructor expects 1 argument, got {}", arguments.len()),
});
}
// BoxFactoryRegistryを使用して作成プラグイン対応
use crate::runtime::get_global_registry;
let registry = get_global_registry();
// 引数を評価
let mut evaluated_args = Vec::new();
for arg in arguments {
evaluated_args.push(self.execute_expression(arg)?);
let path_value = self.execute_expression(&arguments[0])?;
if let Some(path_str) = path_value.as_any().downcast_ref::<StringBox>() {
let file_box = Box::new(FileBox::new(&path_str.value)) as Box<dyn NyashBox>;
// 🌍 革命的実装Environment tracking廃止
return Ok(file_box);
} else {
return Err(RuntimeError::TypeError {
message: "FileBox constructor requires string path argument".to_string(),
});
}
return registry.create_box("FileBox", &evaluated_args)
.map_err(|e| RuntimeError::InvalidOperation { message: e });
}
"ResultBox" => {
// ResultBoxは引数1個成功値で作成
@ -153,34 +147,10 @@ impl NyashInterpreter {
message: format!("MathBox constructor expects 0 arguments, got {}", arguments.len()),
});
}
println!("🔧 DEBUG: DYNAMIC-FILE feature check...");
#[cfg(feature = "dynamic-file")]
{
println!("🔌 DEBUG: DYNAMIC-FILE ENABLED - Creating MathBox through dynamic library");
log::debug!("🔌 DEBUG: Creating MathBox through dynamic library");
match super::plugin_loader::PluginLoader::create_math_box() {
Ok(math_box) => {
println!("🔌 DEBUG: MathBox created successfully, type_name: {}", math_box.type_name());
log::debug!("🔌 DEBUG: MathBox created successfully, type_name: {}", math_box.type_name());
return Ok(math_box);
}
Err(e) => {
println!("❌ DEBUG: Failed to create MathBox through dynamic library: {}", e);
log::error!("Failed to create MathBox through dynamic library: {}", e);
// Fall back to static MathBox
let math_box = Box::new(MathBox::new()) as Box<dyn NyashBox>;
// 🌍 革命的実装Environment tracking廃止
return Ok(math_box);
}
}
}
#[cfg(not(feature = "dynamic-file"))]
{
println!("🔌 DEBUG: DYNAMIC-FILE DISABLED - Creating static MathBox");
let math_box = Box::new(MathBox::new()) as Box<dyn NyashBox>;
return Ok(math_box);
}
}
"NullBox" => {
// NullBoxは引数なしで作成
if !arguments.is_empty() {
@ -392,65 +362,25 @@ impl NyashInterpreter {
message: format!("TimeBox constructor expects 0 arguments, got {}", arguments.len()),
});
}
#[cfg(feature = "dynamic-file")]
{
log::debug!("🔌 DEBUG: Creating TimeBox through dynamic library");
let time_box = super::plugin_loader::PluginLoader::create_time_box()?;
log::debug!("🔌 DEBUG: TimeBox created successfully, type_name: {}", time_box.type_name());
return Ok(time_box);
}
#[cfg(not(feature = "dynamic-file"))]
{
let time_box = Box::new(TimeBox::new()) as Box<dyn NyashBox>;
// 🌍 革命的実装Environment tracking廃止
return Ok(time_box);
}
}
"DateTimeBox" => {
// DateTimeBoxは引数なしで現在時刻、または引数1個でタイムスタンプ
match arguments.len() {
0 => {
#[cfg(feature = "dynamic-file")]
{
log::debug!("🔌 DEBUG: Creating DateTimeBox (now) through dynamic library");
let datetime_box = super::plugin_loader::PluginLoader::create_datetime_now()?;
log::debug!("🔌 DEBUG: DateTimeBox created successfully, type_name: {}", datetime_box.type_name());
return Ok(datetime_box);
}
#[cfg(not(feature = "dynamic-file"))]
{
let datetime_box = Box::new(DateTimeBox::now()) as Box<dyn NyashBox>;
// 🌍 革命的実装Environment tracking廃止
return Ok(datetime_box);
}
}
1 => {
let timestamp_value = self.execute_expression(&arguments[0])?;
// Try integer timestamp first
if let Some(int_box) = timestamp_value.as_any().downcast_ref::<IntegerBox>() {
#[cfg(feature = "dynamic-file")]
{
// TODO: Add timestamp creation to plugin
let datetime_box = Box::new(DateTimeBox::from_timestamp(int_box.value)) as Box<dyn NyashBox>;
// 🌍 革命的実装Environment tracking廃止
return Ok(datetime_box);
}
#[cfg(not(feature = "dynamic-file"))]
{
let datetime_box = Box::new(DateTimeBox::from_timestamp(int_box.value)) as Box<dyn NyashBox>;
return Ok(datetime_box);
}
}
// Try string parsing
let time_str = timestamp_value.to_string_box().value;
#[cfg(feature = "dynamic-file")]
{
log::debug!("🔌 DEBUG: Creating DateTimeBox from string through dynamic library");
let datetime_box = super::plugin_loader::PluginLoader::create_datetime_from_string(&time_str)?;
log::debug!("🔌 DEBUG: DateTimeBox created successfully, type_name: {}", datetime_box.type_name());
return Ok(datetime_box);
}
#[cfg(not(feature = "dynamic-file"))]
{
} else {
return Err(RuntimeError::TypeError {
message: "DateTimeBox constructor requires integer timestamp".to_string(),
});
@ -492,19 +422,10 @@ impl NyashInterpreter {
message: format!("RandomBox constructor expects 0 arguments, got {}", arguments.len()),
});
}
#[cfg(feature = "dynamic-file")]
{
log::debug!("🔌 DEBUG: Creating RandomBox through dynamic library");
let random_box = super::plugin_loader::PluginLoader::create_random_box()?;
log::debug!("🔌 DEBUG: RandomBox created successfully, type_name: {}", random_box.type_name());
return Ok(random_box);
}
#[cfg(not(feature = "dynamic-file"))]
{
let random_box = Box::new(RandomBox::new()) as Box<dyn NyashBox>;
// 🌍 革命的実装Environment tracking廃止
return Ok(random_box);
}
}
"SoundBox" => {
// SoundBoxは引数なしで作成
if !arguments.is_empty() {

View File

@ -145,7 +145,6 @@ impl NyashInterpreter {
if let Some(Some(init_expr)) = initial_values.get(i) {
// 🚀 初期化付きlocal宣言: local x = value
let init_value = self.execute_expression(init_expr)?;
eprintln!("🔍 DEBUG: Local variable '{}' initialized with type: {}", var_name, init_value.type_name());
self.declare_local_variable(var_name, init_value);
} else {
// 従来のlocal宣言: local x

View File

@ -29,12 +29,6 @@ pub mod box_arithmetic; // 🚀 Arithmetic operations moved from box_trait.rs
// 🔥 NyashValue Revolutionary System (NEW!)
pub mod value;
// 🚀 BID-FFI: Box Interface Definition with FFI (NEW!)
pub mod bid;
// 🔌 Runtime: Plugin System and Box Management (NEW!)
pub mod runtime;
// 🌐 P2P Communication Infrastructure (NEW!)
pub mod messaging;
pub mod transport;

View File

@ -38,12 +38,6 @@ pub mod backend;
// 📊 Performance Benchmarks
pub mod benchmarks;
// 🚀 BID-FFI: Box Interface Definition with FFI
pub mod bid;
// 🔌 Runtime: Plugin System (Day 5)
pub mod runtime;
// 🚀 Refactored modules for better organization
pub mod cli;
pub mod runner;

View File

@ -291,28 +291,12 @@ impl MirBuilder {
let operand_val = self.build_expression(operand)?;
let dst = self.value_gen.next();
// Phase 2: Convert UnaryOp to intrinsic call
// Create intrinsic function name based on operator
let intrinsic_name = match operator.as_str() {
"-" => "@unary_neg",
"!" | "not" => "@unary_not",
"~" => "@unary_bitnot",
_ => return Err(format!("Unsupported unary operator: {}", operator)),
};
let mir_op = self.convert_unary_operator(operator)?;
// Create string constant for intrinsic function name
let func_name_id = self.value_gen.next();
self.emit_instruction(MirInstruction::Const {
dst: func_name_id,
value: ConstValue::String(intrinsic_name.to_string()),
})?;
// Emit intrinsic call
self.emit_instruction(MirInstruction::Call {
dst: Some(dst),
func: func_name_id,
args: vec![operand_val],
effects: EffectMask::PURE, // Unary operations are pure
self.emit_instruction(MirInstruction::UnaryOp {
dst,
op: mir_op,
operand: operand_val,
})?;
Ok(dst)
@ -369,20 +353,10 @@ impl MirBuilder {
fn build_print_statement(&mut self, expression: ASTNode) -> Result<ValueId, String> {
let value = self.build_expression(expression)?;
// Phase 2: Convert Print to intrinsic call (@print)
// Create string constant for intrinsic function name
let func_name_id = self.value_gen.next();
self.emit_instruction(MirInstruction::Const {
dst: func_name_id,
value: ConstValue::String("@print".to_string()),
})?;
// Emit intrinsic call (print returns void)
self.emit_instruction(MirInstruction::Call {
dst: None, // Print has no return value
func: func_name_id,
args: vec![value],
effects: EffectMask::PURE.add(Effect::Io), // IO effect for print
// For now, use a special Print instruction (minimal scope)
self.emit_instruction(MirInstruction::Print {
value,
effects: EffectMask::PURE.add(Effect::Io),
})?;
// Return the value that was printed
@ -556,35 +530,15 @@ impl MirBuilder {
let finally_block = if finally_body.is_some() { Some(self.block_gen.next()) } else { None };
let exit_block = self.block_gen.next();
// Phase 2: Convert Catch to intrinsic call (@set_exception_handler)
// Set up exception handler for the try block (before we enter it)
if let Some(catch_clause) = catch_clauses.first() {
let exception_value = self.value_gen.next();
// Create string constants for intrinsic function name and exception type
let func_name_id = self.value_gen.next();
self.emit_instruction(MirInstruction::Const {
dst: func_name_id,
value: ConstValue::String("@set_exception_handler".to_string()),
})?;
let exception_type_id = self.value_gen.next();
self.emit_instruction(MirInstruction::Const {
dst: exception_type_id,
value: ConstValue::String(catch_clause.exception_type.clone().unwrap_or("*".to_string())),
})?;
let handler_bb_id = self.value_gen.next();
self.emit_instruction(MirInstruction::Const {
dst: handler_bb_id,
value: ConstValue::Integer(catch_block.as_u32() as i64),
})?;
// Register catch handler via intrinsic call
self.emit_instruction(MirInstruction::Call {
dst: Some(exception_value),
func: func_name_id,
args: vec![exception_type_id, handler_bb_id],
effects: EffectMask::CONTROL, // Exception handling has control effects
// Register catch handler for exceptions that may occur in try block
self.emit_instruction(MirInstruction::Catch {
exception_type: catch_clause.exception_type.clone(),
exception_value,
handler_bb: catch_block,
})?;
}
@ -655,20 +609,10 @@ impl MirBuilder {
fn build_throw_statement(&mut self, expression: ASTNode) -> Result<ValueId, String> {
let exception_value = self.build_expression(expression)?;
// Phase 2: Convert Throw to intrinsic call (@throw)
// Create string constant for intrinsic function name
let func_name_id = self.value_gen.next();
self.emit_instruction(MirInstruction::Const {
dst: func_name_id,
value: ConstValue::String("@throw".to_string()),
})?;
// Emit intrinsic call (throw has PANIC effect and doesn't return)
self.emit_instruction(MirInstruction::Call {
dst: None, // Throw never returns
func: func_name_id,
args: vec![exception_value],
effects: EffectMask::PANIC, // PANIC effect for throw
// Emit throw instruction with PANIC effect (this is a terminator)
self.emit_instruction(MirInstruction::Throw {
exception: exception_value,
effects: EffectMask::PANIC,
})?;
// Throw doesn't return normally, but we need to return a value for the type system
@ -760,11 +704,11 @@ impl MirBuilder {
// First, build the object expression to get its ValueId
let object_value = self.build_expression(object)?;
// Get the field from the object using BoxFieldLoad (Phase 8.5 new instruction)
// Get the field from the object using RefGet
let result_id = self.value_gen.next();
self.emit_instruction(MirInstruction::BoxFieldLoad {
self.emit_instruction(MirInstruction::RefGet {
dst: result_id,
box_val: object_value,
reference: object_value,
field,
})?;
@ -772,45 +716,22 @@ impl MirBuilder {
}
/// Build new expression: new ClassName(arguments)
fn build_new_expression(&mut self, class: String, arguments: Vec<ASTNode>) -> Result<ValueId, String> {
// Special handling for StringBox - if it has a string literal argument,
// treat it as a string constant, not a box creation
if class == "StringBox" && arguments.len() == 1 {
if let ASTNode::Literal { value: LiteralValue::String(s), .. } = &arguments[0] {
// Just create a string constant
fn build_new_expression(&mut self, class: String, _arguments: Vec<ASTNode>) -> Result<ValueId, String> {
// For Phase 6.1, we'll create a simple RefNew without processing arguments
// In a full implementation, arguments would be used for constructor calls
let dst = self.value_gen.next();
// For now, create a "box type" value representing the class
let type_value = self.value_gen.next();
self.emit_instruction(MirInstruction::Const {
dst,
value: ConstValue::String(s.clone()),
dst: type_value,
value: ConstValue::String(class),
})?;
// Phase 5-3: RefNew is deprecated - use NewBox instead
let string_box_dst = self.value_gen.next();
self.emit_instruction(MirInstruction::NewBox {
dst: string_box_dst,
box_type: "StringBox".to_string(),
args: vec![dst],
})?;
return Ok(string_box_dst);
}
}
// Phase 5-3: Create NewBox with processed arguments
let dst = self.value_gen.next();
// Process all arguments
let mut arg_values = Vec::new();
for arg in arguments {
let arg_value = self.build_expression(arg)?;
arg_values.push(arg_value);
}
// Create NewBox instruction
self.emit_instruction(MirInstruction::NewBox {
// Create the reference using RefNew
self.emit_instruction(MirInstruction::RefNew {
dst,
box_type: class,
args: arg_values,
box_val: type_value,
})?;
Ok(dst)
@ -822,9 +743,9 @@ impl MirBuilder {
let object_value = self.build_expression(object)?;
let value_result = self.build_expression(value)?;
// Set the field using BoxFieldStore (Phase 8.5 new instruction)
self.emit_instruction(MirInstruction::BoxFieldStore {
box_val: object_value,
// Set the field using RefSet
self.emit_instruction(MirInstruction::RefSet {
reference: object_value,
field,
value: value_result,
})?;
@ -888,12 +809,11 @@ impl MirBuilder {
// Evaluate the expression
let expression_value = self.build_expression(expression)?;
// Phase 2: Convert FutureNew to NewBox + BoxCall implementation
// Create a new Future with the evaluated expression as the initial value
let future_id = self.value_gen.next();
self.emit_instruction(MirInstruction::NewBox {
self.emit_instruction(MirInstruction::FutureNew {
dst: future_id,
box_type: "FutureBox".to_string(),
args: vec![expression_value],
value: expression_value,
})?;
// Store the future in the variable
@ -907,16 +827,13 @@ impl MirBuilder {
// Evaluate the expression (should be a Future)
let future_value = self.build_expression(expression)?;
// Phase 2: Convert Await to BoxCall implementation
// Create destination for await result
let result_id = self.value_gen.next();
// Emit await as a method call on the future box
self.emit_instruction(MirInstruction::BoxCall {
dst: Some(result_id),
box_val: future_value,
method: "await".to_string(),
args: vec![],
effects: EffectMask::IO.add(Effect::Control), // Await has IO and control effects
// Emit await instruction
self.emit_instruction(MirInstruction::Await {
dst: result_id,
future: future_value,
})?;
Ok(result_id)

View File

@ -31,8 +31,6 @@ pub enum MirInstruction {
/// Unary operation
/// `%dst = op %operand`
/// DEPRECATED: Phase 5 - Use BinOp instead (e.g., `not %a` → `%a xor true`, `neg %a` → `0 sub %a`)
#[deprecated(since = "Phase 5", note = "Use BinOp instead")]
UnaryOp {
dst: ValueId,
op: UnaryOp,
@ -52,8 +50,6 @@ pub enum MirInstruction {
// === Memory Operations ===
/// Load from memory/variable
/// `%dst = load %ptr`
/// DEPRECATED: Phase 5 - Use BoxFieldLoad instead
#[deprecated(since = "Phase 5", note = "Use BoxFieldLoad instead")]
Load {
dst: ValueId,
ptr: ValueId,
@ -61,8 +57,6 @@ pub enum MirInstruction {
/// Store to memory/variable
/// `store %value -> %ptr`
/// DEPRECATED: Phase 5 - Use BoxFieldStore instead
#[deprecated(since = "Phase 5", note = "Use BoxFieldStore instead")]
Store {
value: ValueId,
ptr: ValueId,
@ -128,8 +122,6 @@ pub enum MirInstruction {
/// Check Box type
/// `%dst = type_check %box "BoxType"`
/// DEPRECATED: Phase 5 - Use Call with @type_check intrinsic
#[deprecated(since = "Phase 5", note = "Use Call with @type_check intrinsic")]
TypeCheck {
dst: ValueId,
value: ValueId,
@ -139,8 +131,6 @@ pub enum MirInstruction {
// === Type Conversion ===
/// Convert between types
/// `%dst = cast %value as Type`
/// DEPRECATED: Phase 5 - Use Call with @cast intrinsic
#[deprecated(since = "Phase 5", note = "Use Call with @cast intrinsic")]
Cast {
dst: ValueId,
value: ValueId,
@ -150,8 +140,6 @@ pub enum MirInstruction {
// === Array Operations ===
/// Get array element
/// `%dst = %array[%index]`
/// DEPRECATED: Phase 5 - Use BoxFieldLoad or Call with @array_get intrinsic
#[deprecated(since = "Phase 5", note = "Use BoxFieldLoad or Call with @array_get intrinsic")]
ArrayGet {
dst: ValueId,
array: ValueId,
@ -160,8 +148,6 @@ pub enum MirInstruction {
/// Set array element
/// `%array[%index] = %value`
/// DEPRECATED: Phase 5 - Use BoxFieldStore or Call with @array_set intrinsic
#[deprecated(since = "Phase 5", note = "Use BoxFieldStore or Call with @array_set intrinsic")]
ArraySet {
array: ValueId,
index: ValueId,
@ -171,8 +157,6 @@ pub enum MirInstruction {
// === Special Operations ===
/// Copy a value (for optimization passes)
/// `%dst = copy %src`
/// DEPRECATED: Phase 5 - Optimization pass only, not needed in IR
#[deprecated(since = "Phase 5", note = "Optimization pass only, not needed in IR")]
Copy {
dst: ValueId,
src: ValueId,
@ -180,8 +164,6 @@ pub enum MirInstruction {
/// Debug/introspection instruction
/// `debug %value "message"`
/// DEPRECATED: Phase 5 - Use Call with @debug intrinsic
#[deprecated(since = "Phase 5", note = "Use Call with @debug intrinsic")]
Debug {
value: ValueId,
message: String,
@ -189,24 +171,18 @@ pub enum MirInstruction {
/// Print instruction for console output
/// `print %value`
/// DEPRECATED: Phase 5 - Use Call with @print intrinsic
#[deprecated(since = "Phase 5", note = "Use Call with @print intrinsic")]
Print {
value: ValueId,
effects: EffectMask,
},
/// No-op instruction (for optimization placeholders)
/// DEPRECATED: Phase 5 - Not needed in final IR
#[deprecated(since = "Phase 5", note = "Not needed in final IR")]
Nop,
// === Control Flow & Exception Handling (Phase 5) ===
/// Throw an exception
/// `throw %exception_value`
/// DEPRECATED: Phase 5 - Use Call with @throw intrinsic
#[deprecated(since = "Phase 5", note = "Use Call with @throw intrinsic")]
Throw {
exception: ValueId,
effects: EffectMask,
@ -214,8 +190,6 @@ pub enum MirInstruction {
/// Catch handler setup (landing pad for exceptions)
/// `catch %exception_type -> %handler_bb`
/// DEPRECATED: Phase 5 - Use Call with @catch intrinsic
#[deprecated(since = "Phase 5", note = "Use Call with @catch intrinsic")]
Catch {
exception_type: Option<String>, // None = catch-all
exception_value: ValueId, // Where to store caught exception
@ -230,8 +204,6 @@ pub enum MirInstruction {
/// Create a new reference to a Box
/// `%dst = ref_new %box`
/// DEPRECATED: Phase 5 - RefGet is sufficient
#[deprecated(since = "Phase 5", note = "RefGet is sufficient")]
RefNew {
dst: ValueId,
box_val: ValueId,
@ -269,16 +241,12 @@ pub enum MirInstruction {
/// Memory barrier read (no-op for now, proper effect annotation)
/// `barrier_read %ptr`
/// DEPRECATED: Phase 5 - Use AtomicFence instead
#[deprecated(since = "Phase 5", note = "Use AtomicFence instead")]
BarrierRead {
ptr: ValueId,
},
/// Memory barrier write (no-op for now, proper effect annotation)
/// `barrier_write %ptr`
/// DEPRECATED: Phase 5 - Use AtomicFence instead
#[deprecated(since = "Phase 5", note = "Use AtomicFence instead")]
BarrierWrite {
ptr: ValueId,
},
@ -287,8 +255,6 @@ pub enum MirInstruction {
/// Create a new Future with initial value
/// `%dst = future_new %value`
/// DEPRECATED: Phase 5 - Use NewBox + BoxCall
#[deprecated(since = "Phase 5", note = "Use NewBox + BoxCall")]
FutureNew {
dst: ValueId,
value: ValueId,
@ -296,8 +262,6 @@ pub enum MirInstruction {
/// Set Future value and mark as ready
/// `future_set %future = %value`
/// DEPRECATED: Phase 5 - Use BoxCall
#[deprecated(since = "Phase 5", note = "Use BoxCall")]
FutureSet {
future: ValueId,
value: ValueId,
@ -305,8 +269,6 @@ pub enum MirInstruction {
/// Wait for Future completion and get value
/// `%dst = await %future`
/// DEPRECATED: Phase 5 - Use BoxCall
#[deprecated(since = "Phase 5", note = "Use BoxCall")]
Await {
dst: ValueId,
future: ValueId,
@ -323,80 +285,6 @@ pub enum MirInstruction {
args: Vec<ValueId>,
effects: EffectMask,
},
// === Phase 8.5: MIR 26-instruction reduction (NEW) ===
/// Box field load operation (replaces Load)
/// `%dst = %box.field`
BoxFieldLoad {
dst: ValueId,
box_val: ValueId,
field: String,
},
/// Box field store operation (replaces Store)
/// `%box.field = %value`
BoxFieldStore {
box_val: ValueId,
field: String,
value: ValueId,
},
/// Check weak reference validity
/// `%dst = weak_check %weak_ref`
WeakCheck {
dst: ValueId,
weak_ref: ValueId,
},
/// Send data via Bus
/// `send %data -> %target`
Send {
data: ValueId,
target: ValueId,
},
/// Receive data from Bus
/// `%dst = recv %source`
Recv {
dst: ValueId,
source: ValueId,
},
/// Tail call optimization
/// `tail_call %func(%args...)`
TailCall {
func: ValueId,
args: Vec<ValueId>,
effects: EffectMask,
},
/// Adopt ownership (parent takes child)
/// `adopt %parent <- %child`
Adopt {
parent: ValueId,
child: ValueId,
},
/// Release strong ownership
/// `release %ref`
Release {
reference: ValueId,
},
/// Memory copy optimization
/// `memcopy %dst <- %src, %size`
MemCopy {
dst: ValueId,
src: ValueId,
size: ValueId,
},
/// Atomic memory fence
/// `atomic_fence %ordering`
AtomicFence {
ordering: AtomicOrdering,
},
}
/// Constant values in MIR
@ -456,16 +344,6 @@ pub enum MirType {
Unknown,
}
/// Atomic memory ordering for fence operations
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AtomicOrdering {
Relaxed,
Acquire,
Release,
AcqRel,
SeqCst,
}
impl MirInstruction {
/// Get the effect mask for this instruction
pub fn effects(&self) -> EffectMask {
@ -526,18 +404,6 @@ impl MirInstruction {
// Phase 9.7: External Function Calls
MirInstruction::ExternCall { effects, .. } => *effects, // Use provided effect mask
// Phase 8.5: MIR 26-instruction reduction (NEW)
MirInstruction::BoxFieldLoad { .. } => EffectMask::READ, // Box field read
MirInstruction::BoxFieldStore { .. } => EffectMask::WRITE, // Box field write
MirInstruction::WeakCheck { .. } => EffectMask::PURE, // Check is pure
MirInstruction::Send { .. } => EffectMask::IO, // Bus send has IO effects
MirInstruction::Recv { .. } => EffectMask::IO, // Bus recv has IO effects
MirInstruction::TailCall { effects, .. } => *effects, // Use provided effect mask
MirInstruction::Adopt { .. } => EffectMask::WRITE, // Ownership change has write effects
MirInstruction::Release { .. } => EffectMask::WRITE, // Ownership release has write effects
MirInstruction::MemCopy { .. } => EffectMask::WRITE, // Memory copy has write effects
MirInstruction::AtomicFence { .. } => EffectMask::IO.add(Effect::Barrier), // Fence has barrier + IO
}
}
@ -566,12 +432,6 @@ impl MirInstruction {
MirInstruction::BoxCall { dst, .. } |
MirInstruction::ExternCall { dst, .. } => *dst,
// Phase 8.5: MIR 26-instruction reduction (NEW)
MirInstruction::BoxFieldLoad { dst, .. } |
MirInstruction::WeakCheck { dst, .. } |
MirInstruction::Recv { dst, .. } |
MirInstruction::MemCopy { dst, .. } => Some(*dst),
MirInstruction::Store { .. } |
MirInstruction::Branch { .. } |
MirInstruction::Jump { .. } |
@ -587,14 +447,6 @@ impl MirInstruction {
MirInstruction::Safepoint |
MirInstruction::Nop => None,
// Phase 8.5: Non-value producing instructions
MirInstruction::BoxFieldStore { .. } |
MirInstruction::Send { .. } |
MirInstruction::TailCall { .. } |
MirInstruction::Adopt { .. } |
MirInstruction::Release { .. } |
MirInstruction::AtomicFence { .. } => None,
MirInstruction::Catch { exception_value, .. } => Some(*exception_value),
}
}
@ -667,22 +519,6 @@ impl MirInstruction {
// Phase 9.7: External Function Calls
MirInstruction::ExternCall { args, .. } => args.clone(),
// Phase 8.5: MIR 26-instruction reduction (NEW)
MirInstruction::BoxFieldLoad { box_val, .. } => vec![*box_val],
MirInstruction::BoxFieldStore { box_val, value, .. } => vec![*box_val, *value],
MirInstruction::WeakCheck { weak_ref, .. } => vec![*weak_ref],
MirInstruction::Send { data, target } => vec![*data, *target],
MirInstruction::Recv { source, .. } => vec![*source],
MirInstruction::TailCall { func, args, .. } => {
let mut used = vec![*func];
used.extend(args);
used
},
MirInstruction::Adopt { parent, child } => vec![*parent, *child],
MirInstruction::Release { reference } => vec![*reference],
MirInstruction::MemCopy { dst, src, size } => vec![*dst, *src, *size],
MirInstruction::AtomicFence { .. } => Vec::new(), // Fence doesn't use values
}
}
}
@ -766,39 +602,6 @@ impl fmt::Display for MirInstruction {
effects)
}
},
// Phase 8.5: MIR 26-instruction reduction (NEW)
MirInstruction::BoxFieldLoad { dst, box_val, field } => {
write!(f, "{} = {}.{}", dst, box_val, field)
},
MirInstruction::BoxFieldStore { box_val, field, value } => {
write!(f, "{}.{} = {}", box_val, field, value)
},
MirInstruction::WeakCheck { dst, weak_ref } => {
write!(f, "{} = weak_check {}", dst, weak_ref)
},
MirInstruction::Send { data, target } => {
write!(f, "send {} -> {}", data, target)
},
MirInstruction::Recv { dst, source } => {
write!(f, "{} = recv {}", dst, source)
},
MirInstruction::TailCall { func, args, effects } => {
write!(f, "tail_call {}({}); effects: {}", func,
args.iter().map(|v| format!("{}", v)).collect::<Vec<_>>().join(", "),
effects)
},
MirInstruction::Adopt { parent, child } => {
write!(f, "adopt {} <- {}", parent, child)
},
MirInstruction::Release { reference } => {
write!(f, "release {}", reference)
},
MirInstruction::MemCopy { dst, src, size } => {
write!(f, "memcopy {} <- {}, {}", dst, src, size)
},
MirInstruction::AtomicFence { ordering } => {
write!(f, "atomic_fence {:?}", ordering)
},
_ => write!(f, "{:?}", self), // Fallback for other instructions
}
}
@ -817,18 +620,6 @@ impl fmt::Display for ConstValue {
}
}
impl fmt::Display for AtomicOrdering {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
AtomicOrdering::Relaxed => write!(f, "relaxed"),
AtomicOrdering::Acquire => write!(f, "acquire"),
AtomicOrdering::Release => write!(f, "release"),
AtomicOrdering::AcqRel => write!(f, "acq_rel"),
AtomicOrdering::SeqCst => write!(f, "seq_cst"),
}
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@ -13,7 +13,6 @@ pub mod builder;
pub mod verification;
pub mod ownership_verifier_simple; // Simple ownership forest verification for current MIR
pub mod printer;
pub mod optimizer; // Phase 3: Effect System based optimization passes
pub mod value_id;
pub mod effect;
@ -26,7 +25,6 @@ pub use builder::MirBuilder;
pub use verification::{MirVerifier, VerificationError};
pub use ownership_verifier_simple::{OwnershipVerifier, OwnershipError, OwnershipStats}; // Simple ownership forest verification
pub use printer::MirPrinter;
pub use optimizer::{MirOptimizer, OptimizationStats}; // Phase 3: Effect System optimizations
pub use value_id::{ValueId, LocalId, ValueIdGenerator};
pub use effect::{EffectMask, Effect};

View File

@ -371,39 +371,6 @@ impl MirPrinter {
format!("extern_call {}.{}({}) [effects: {}]", iface_name, method_name, args_str, effects)
}
},
// Phase 8.5: MIR 26-instruction reduction (NEW)
MirInstruction::BoxFieldLoad { dst, box_val, field } => {
format!("{} = {}.{}", dst, box_val, field)
},
MirInstruction::BoxFieldStore { box_val, field, value } => {
format!("{}.{} = {}", box_val, field, value)
},
MirInstruction::WeakCheck { dst, weak_ref } => {
format!("{} = weak_check {}", dst, weak_ref)
},
MirInstruction::Send { data, target } => {
format!("send {} -> {}", data, target)
},
MirInstruction::Recv { dst, source } => {
format!("{} = recv {}", dst, source)
},
MirInstruction::TailCall { func, args, effects } => {
let args_str = args.iter().map(|v| format!("{}", v)).collect::<Vec<_>>().join(", ");
format!("tail_call {}({}) [effects: {}]", func, args_str, effects)
},
MirInstruction::Adopt { parent, child } => {
format!("adopt {} <- {}", parent, child)
},
MirInstruction::Release { reference } => {
format!("release {}", reference)
},
MirInstruction::MemCopy { dst, src, size } => {
format!("memcopy {} <- {}, {}", dst, src, size)
},
MirInstruction::AtomicFence { ordering } => {
format!("atomic_fence {:?}", ordering)
},
}
}

View File

@ -14,7 +14,6 @@ use crate::{
interpreter::NyashInterpreter,
mir::{MirCompiler, MirPrinter},
backend::{VM, wasm::WasmBackend, aot::AotBackend},
runtime::{PluginConfig, get_global_registry},
};
use std::{fs, process};
@ -26,89 +25,9 @@ pub struct NyashRunner {
impl NyashRunner {
/// Create a new runner with the given configuration
pub fn new(config: CliConfig) -> Self {
// 🔌 プラグインシステム初期化
Self::initialize_plugin_system();
Self { config }
}
/// プラグインシステム初期化nyash.toml読み込み
fn initialize_plugin_system() {
// nyash.tomlが存在するかチェック
if std::path::Path::new("nyash.toml").exists() {
match std::fs::read_to_string("nyash.toml") {
Ok(toml_content) => {
match PluginConfig::parse(&toml_content) {
Ok(plugin_config) => {
println!("🔌 Loading plugin configuration from nyash.toml");
let registry = get_global_registry();
// ビルトインBoxを登録フォールバック用
Self::register_builtin_boxes(&registry);
// プラグイン設定を適用
registry.apply_plugin_config(&plugin_config);
// プラグインライブラリをロード
#[cfg(feature = "dynamic-file")]
{
use crate::runtime::get_global_loader;
let loader = get_global_loader();
for (box_name, plugin_name) in &plugin_config.plugins {
// プラグインライブラリパスを構築
let lib_path = format!("plugins/{}/target/release/lib{}.so",
plugin_name.replace('_', "-"), plugin_name);
println!("🔍 Loading plugin library: {}", lib_path);
if let Err(e) = loader.load_plugin(plugin_name, &lib_path) {
eprintln!("⚠️ Failed to load plugin {}: {}", plugin_name, e);
} else {
println!("✅ Plugin library loaded: {}", plugin_name);
}
}
}
println!("✅ Plugin system initialized: {} plugins configured",
plugin_config.plugins.len());
}
Err(e) => {
eprintln!("⚠️ Failed to parse nyash.toml: {}", e);
eprintln!(" Using builtin boxes only");
}
}
}
Err(e) => {
eprintln!("⚠️ Failed to read nyash.toml: {}", e);
eprintln!(" Using builtin boxes only");
}
}
} else {
// nyash.tomlがない場合はビルトインのみ
let registry = get_global_registry();
Self::register_builtin_boxes(&registry);
println!("📦 Using builtin boxes only (no nyash.toml found)");
}
}
/// ビルトインBox登録フォールバック用
fn register_builtin_boxes(registry: &crate::runtime::BoxFactoryRegistry) {
// FileBoxビルトイン版のコンストラクタ
fn builtin_filebox_constructor(args: &[Box<dyn NyashBox>]) -> Result<Box<dyn NyashBox>, String> {
// 簡易実装StringBoxとして扱う実際のビルトインFileBoxが必要
if args.is_empty() {
Ok(Box::new(StringBox::new("BuiltinFileBox")))
} else {
let path = args[0].to_string_box().value;
Ok(Box::new(StringBox::new(&format!("BuiltinFileBox({})", path))))
}
}
registry.register_builtin("FileBox", builtin_filebox_constructor);
println!(" 📁 FileBox (builtin) registered");
}
/// Run Nyash based on the configuration
pub fn run(&self) {
// Benchmark mode - can run without a file

19
test_simple.nyash Normal file
View File

@ -0,0 +1,19 @@
// 簡単なNyashテストプログラム
print("🎉 Nyash is working!")
print("Everything is Box!")
// 基本的な演算
local a = 10
local b = 20
local result = a + b
print("10 + 20 = " + result.toString())
// StringBox
local greeting = "Hello, Nyash!"
print(greeting)
// ArrayBox
local arr = new ArrayBox()
arr.push("First")
arr.push("Second")
print("Array length: " + arr.length().toString())

View File

@ -6,10 +6,10 @@
use nyash_rust::mir::{
MirModule, MirFunction, FunctionSignature, MirType, EffectMask,
BasicBlock, BasicBlockId, ValueId, MirInstruction, ConstValue, AtomicOrdering
BasicBlock, BasicBlockId, ValueId, MirInstruction, ConstValue
};
use nyash_rust::backend::VM;
use nyash_rust::box_trait::IntegerBox;
use nyash_rust::backend::{VM, VMValue};
use nyash_rust::box_trait::{IntegerBox, NyashBox};
#[test]
fn test_mir_phase6_vm_ref_ops() {
@ -45,7 +45,6 @@ fn test_mir_phase6_vm_ref_ops() {
let obj_ref = ValueId::new(1);
let one_val = ValueId::new(2);
let x_val = ValueId::new(3);
let print_func = ValueId::new(4);
// Add instructions
@ -55,18 +54,10 @@ fn test_mir_phase6_vm_ref_ops() {
value: ConstValue::String("Obj".to_string()),
});
// %4 = const "@print" (for intrinsic call)
block.add_instruction(MirInstruction::Const {
dst: print_func,
value: ConstValue::String("@print".to_string()),
});
// %1 = new Obj()
// Phase 5: RefNew is deprecated - use NewBox instead
block.add_instruction(MirInstruction::NewBox {
// %1 = ref_new %0
block.add_instruction(MirInstruction::RefNew {
dst: obj_ref,
box_type: "Obj".to_string(),
args: vec![],
box_val: obj_type_val,
});
// %2 = const 1
@ -75,34 +66,28 @@ fn test_mir_phase6_vm_ref_ops() {
value: ConstValue::Integer(1),
});
// atomic_fence release
// Phase 5: BarrierWrite is deprecated - use AtomicFence instead
block.add_instruction(MirInstruction::AtomicFence {
ordering: AtomicOrdering::Release,
// barrier_write %1
block.add_instruction(MirInstruction::BarrierWrite {
ptr: obj_ref,
});
// %1.x = %2
// Phase 5: RefSet is deprecated - use BoxFieldStore instead
block.add_instruction(MirInstruction::BoxFieldStore {
box_val: obj_ref,
// ref_set %1, "x", %2
block.add_instruction(MirInstruction::RefSet {
reference: obj_ref,
field: "x".to_string(),
value: one_val,
});
// %3 = %1.x
// Phase 5: RefGet is deprecated - use BoxFieldLoad instead
block.add_instruction(MirInstruction::BoxFieldLoad {
// %3 = ref_get %1, "x"
block.add_instruction(MirInstruction::RefGet {
dst: x_val,
box_val: obj_ref,
reference: obj_ref,
field: "x".to_string(),
});
// call @print(%3)
// Phase 5: Print is deprecated - use Call @print instead
block.add_instruction(MirInstruction::Call {
dst: None,
func: print_func,
args: vec![x_val],
// print %3
block.add_instruction(MirInstruction::Print {
value: x_val,
effects: EffectMask::IO,
});
@ -183,14 +168,13 @@ fn test_barrier_no_op() {
value: ConstValue::Integer(42),
});
// Test atomic fence instructions (replace barriers)
// Phase 5: BarrierRead/BarrierWrite are deprecated - use AtomicFence
block.add_instruction(MirInstruction::AtomicFence {
ordering: AtomicOrdering::Acquire,
// Test barrier instructions (should be no-ops)
block.add_instruction(MirInstruction::BarrierRead {
ptr: test_val,
});
block.add_instruction(MirInstruction::AtomicFence {
ordering: AtomicOrdering::Release,
block.add_instruction(MirInstruction::BarrierWrite {
ptr: test_val,
});
block.add_instruction(MirInstruction::Return {

View File

@ -107,17 +107,17 @@ fn test_mir_phase7_basic_nowait_await() {
.flat_map(|block| &block.instructions)
.collect();
// Phase 5: FutureNew is deprecated - should contain NewBox "FutureBox" instead
let has_future_box = instructions.iter().any(|inst| {
matches!(inst, nyash_rust::mir::MirInstruction::NewBox { box_type, .. } if box_type == "FutureBox")
// Should contain FutureNew instruction
let has_future_new = instructions.iter().any(|inst| {
matches!(inst, nyash_rust::mir::MirInstruction::FutureNew { .. })
});
assert!(has_future_box, "MIR should contain NewBox FutureBox instruction");
assert!(has_future_new, "MIR should contain FutureNew instruction");
// Phase 5: Await is deprecated - should contain BoxCall "await" instead
let has_await_call = instructions.iter().any(|inst| {
matches!(inst, nyash_rust::mir::MirInstruction::BoxCall { method, .. } if method == "await")
// Should contain Await instruction
let has_await = instructions.iter().any(|inst| {
matches!(inst, nyash_rust::mir::MirInstruction::Await { .. })
});
assert!(has_await_call, "MIR should contain BoxCall await instruction");
assert!(has_await, "MIR should contain Await instruction");
// Test VM execution
let mut vm = VM::new();

View File

@ -0,0 +1,334 @@
/*!
* Phase 8.3 PoC2 Integration Test - Box Operations in WASM
*
* Tests end-to-end MIR→WASM compilation and execution for:
* - RefNew: Box creation and reference assignment
* - RefGet: Field reading from Box objects
* - RefSet: Field writing to Box objects
* - NewBox: Direct Box allocation with type information
*
* Validates the "Everything is Box" philosophy in WASM
*/
use nyash_rust::mir::{
MirModule, MirFunction, FunctionSignature, MirType, EffectMask,
BasicBlock, BasicBlockId, ValueId, MirInstruction, ConstValue
};
use nyash_rust::backend::wasm::WasmBackend;
#[test]
fn test_wasm_poc2_refnew_basic() {
// Build MIR equivalent to:
// function main() {
// %box = new_box "DataBox"(42)
// %ref = ref_new %box
// return %ref // Should return box pointer
// }
let mut backend = WasmBackend::new();
let mir_module = build_refnew_mir_module();
// Generate WAT text for debugging
let wat_result = backend.compile_to_wat(mir_module.clone());
assert!(wat_result.is_ok(), "WAT generation should succeed");
let wat_text = wat_result.unwrap();
// Verify WAT contains expected elements
assert!(wat_text.contains("(module"), "Should contain module declaration");
assert!(wat_text.contains("$malloc"), "Should contain malloc function");
assert!(wat_text.contains("$alloc_databox"), "Should contain DataBox allocator");
assert!(wat_text.contains("call $alloc_databox"), "Should call DataBox allocator");
assert!(wat_text.contains("i32.store"), "Should store field values");
// Compile to WASM binary and execute
let wasm_result = backend.compile_module(mir_module);
if let Err(e) = &wasm_result {
println!("WASM compilation error: {}", e);
}
assert!(wasm_result.is_ok(), "WASM compilation should succeed");
let wasm_bytes = wasm_result.unwrap();
assert!(!wasm_bytes.is_empty(), "WASM bytes should not be empty");
// Execute with wasmtime
let execution_result = backend.execute_wasm(&wasm_bytes);
assert!(execution_result.is_ok(), "WASM execution should succeed");
let return_value = execution_result.unwrap();
// Should return a valid pointer (greater than heap start 0x800)
assert!(return_value >= 0x800, "Should return valid Box pointer: {}", return_value);
}
#[test]
fn test_wasm_poc2_refget_refset() {
// Build MIR equivalent to:
// function main() {
// %box = new_box "DataBox"(10)
// %ref = ref_new %box
// ref_set %ref.value = 42
// %result = ref_get %ref.value
// return %result // Should return 42
// }
let mut backend = WasmBackend::new();
let mir_module = build_refget_refset_mir_module();
let wasm_result = backend.compile_module(mir_module);
assert!(wasm_result.is_ok(), "WASM compilation should succeed");
let return_value = backend.execute_wasm(&wasm_result.unwrap()).unwrap();
assert_eq!(return_value, 42, "Should return updated field value");
}
#[test]
fn test_wasm_poc2_complete_box_workflow() {
// Build MIR equivalent to:
// function main() {
// %box1 = new_box "DataBox"(100)
// %box2 = new_box "DataBox"(200)
// %ref1 = ref_new %box1
// %ref2 = ref_new %box2
// %val1 = ref_get %ref1.value
// %val2 = ref_get %ref2.value
// %sum = %val1 + %val2
// ref_set %ref1.value = %sum
// %result = ref_get %ref1.value
// return %result // Should return 300
// }
let mut backend = WasmBackend::new();
let mir_module = build_complete_workflow_mir_module();
let wasm_result = backend.compile_module(mir_module);
assert!(wasm_result.is_ok(), "WASM compilation should succeed");
let return_value = backend.execute_wasm(&wasm_result.unwrap()).unwrap();
assert_eq!(return_value, 300, "Should return sum of Box values");
}
/// Build MIR module for basic RefNew test
fn build_refnew_mir_module() -> MirModule {
let mut module = MirModule::new("test_refnew".to_string());
let main_signature = FunctionSignature {
name: "main".to_string(),
params: vec![],
return_type: MirType::Integer,
effects: EffectMask::PURE,
};
let entry_block = BasicBlockId::new(0);
let mut main_function = MirFunction::new(main_signature, entry_block);
let mut block = BasicBlock::new(entry_block);
let init_val = ValueId::new(0); // 42
let box_ptr = ValueId::new(1); // DataBox pointer
let ref_ptr = ValueId::new(2); // Reference to DataBox
// Create constant for initialization
block.add_instruction(MirInstruction::Const {
dst: init_val,
value: ConstValue::Integer(42),
});
// Create DataBox with initial value
block.add_instruction(MirInstruction::NewBox {
dst: box_ptr,
box_type: "DataBox".to_string(),
args: vec![init_val],
});
// Create reference to the Box
block.add_instruction(MirInstruction::RefNew {
dst: ref_ptr,
box_val: box_ptr,
});
// Return the reference
block.set_terminator(MirInstruction::Return {
value: Some(ref_ptr),
});
main_function.add_block(block);
module.add_function(main_function);
module
}
/// Build MIR module for RefGet/RefSet test
fn build_refget_refset_mir_module() -> MirModule {
let mut module = MirModule::new("test_refget_refset".to_string());
let main_signature = FunctionSignature {
name: "main".to_string(),
params: vec![],
return_type: MirType::Integer,
effects: EffectMask::PURE,
};
let entry_block = BasicBlockId::new(0);
let mut main_function = MirFunction::new(main_signature, entry_block);
let mut block = BasicBlock::new(entry_block);
let init_val = ValueId::new(0); // 10
let new_val = ValueId::new(1); // 42
let box_ptr = ValueId::new(2); // DataBox pointer
let ref_ptr = ValueId::new(3); // Reference to DataBox
let result = ValueId::new(4); // Read back value
// Create constants
block.add_instruction(MirInstruction::Const {
dst: init_val,
value: ConstValue::Integer(10),
});
block.add_instruction(MirInstruction::Const {
dst: new_val,
value: ConstValue::Integer(42),
});
// Create DataBox with initial value
block.add_instruction(MirInstruction::NewBox {
dst: box_ptr,
box_type: "DataBox".to_string(),
args: vec![init_val],
});
// Create reference to the Box
block.add_instruction(MirInstruction::RefNew {
dst: ref_ptr,
box_val: box_ptr,
});
// Set field value
block.add_instruction(MirInstruction::RefSet {
reference: ref_ptr,
field: "value".to_string(),
value: new_val,
});
// Get field value
block.add_instruction(MirInstruction::RefGet {
dst: result,
reference: ref_ptr,
field: "value".to_string(),
});
// Return the result
block.set_terminator(MirInstruction::Return {
value: Some(result),
});
main_function.add_block(block);
module.add_function(main_function);
module
}
/// Build MIR module for complete Box workflow test
fn build_complete_workflow_mir_module() -> MirModule {
let mut module = MirModule::new("test_complete_workflow".to_string());
let main_signature = FunctionSignature {
name: "main".to_string(),
params: vec![],
return_type: MirType::Integer,
effects: EffectMask::PURE,
};
let entry_block = BasicBlockId::new(0);
let mut main_function = MirFunction::new(main_signature, entry_block);
let mut block = BasicBlock::new(entry_block);
let val1_init = ValueId::new(0); // 100
let val2_init = ValueId::new(1); // 200
let box1_ptr = ValueId::new(2); // DataBox 1 pointer
let box2_ptr = ValueId::new(3); // DataBox 2 pointer
let ref1_ptr = ValueId::new(4); // Reference to DataBox 1
let ref2_ptr = ValueId::new(5); // Reference to DataBox 2
let val1 = ValueId::new(6); // Value from box1
let val2 = ValueId::new(7); // Value from box2
let sum = ValueId::new(8); // Sum of values
let result = ValueId::new(9); // Final result
// Create constants
block.add_instruction(MirInstruction::Const {
dst: val1_init,
value: ConstValue::Integer(100),
});
block.add_instruction(MirInstruction::Const {
dst: val2_init,
value: ConstValue::Integer(200),
});
// Create DataBoxes
block.add_instruction(MirInstruction::NewBox {
dst: box1_ptr,
box_type: "DataBox".to_string(),
args: vec![val1_init],
});
block.add_instruction(MirInstruction::NewBox {
dst: box2_ptr,
box_type: "DataBox".to_string(),
args: vec![val2_init],
});
// Create references
block.add_instruction(MirInstruction::RefNew {
dst: ref1_ptr,
box_val: box1_ptr,
});
block.add_instruction(MirInstruction::RefNew {
dst: ref2_ptr,
box_val: box2_ptr,
});
// Get values from both boxes
block.add_instruction(MirInstruction::RefGet {
dst: val1,
reference: ref1_ptr,
field: "value".to_string(),
});
block.add_instruction(MirInstruction::RefGet {
dst: val2,
reference: ref2_ptr,
field: "value".to_string(),
});
// Add values
block.add_instruction(MirInstruction::BinOp {
dst: sum,
op: nyash_rust::mir::BinaryOp::Add,
lhs: val1,
rhs: val2,
});
// Store sum back to first box
block.add_instruction(MirInstruction::RefSet {
reference: ref1_ptr,
field: "value".to_string(),
value: sum,
});
// Read back the result
block.add_instruction(MirInstruction::RefGet {
dst: result,
reference: ref1_ptr,
field: "value".to_string(),
});
// Return the result
block.set_terminator(MirInstruction::Return {
value: Some(result),
});
main_function.add_block(block);
module.add_function(main_function);
module
}