feat(phase-9.75g-0): Implement BID-FFI Day 5 - FileBox plugin library and transparent switching (90% complete)

Day 5 achievements:
- Created independent FileBox plugin crate with C FFI exports
- Integrated plugin loading into Nyash interpreter startup
- Implemented transparent builtin/plugin Box switching via nyash.toml
- Successfully loaded plugin library (385KB .so) at runtime
- Confirmed PluginBox proxy creation for FileBox instances

Architecture changes:
- Added plugins/ directory with .gitignore for build artifacts
- Modified runner.rs to load plugins from nyash.toml on startup
- Updated objects.rs to use BoxFactoryRegistry for FileBox creation
- Fixed bid module visibility between lib.rs and main.rs

Remaining work (10%):
- Complete PluginBox proxy method implementations (toString, etc.)
- Test actual file operations through plugin interface
- Finalize error handling and edge cases

Build status: All tests passing, plugin loading confirmed
This commit is contained in:
Moe Charm
2025-08-18 00:33:01 +09:00
parent a0e3c0dc75
commit 75868a5a96
11 changed files with 688 additions and 46 deletions

View File

@ -98,34 +98,18 @@ impl NyashInterpreter {
message: format!("FileBox constructor expects 1 argument, got {}", arguments.len()),
});
}
let path_value = self.execute_expression(&arguments[0])?;
if let Some(path_str) = path_value.as_any().downcast_ref::<StringBox>() {
#[cfg(feature = "dynamic-file")]
{
// 動的ライブラリ経由でFileBoxを作成
use crate::interpreter::plugin_loader::PluginLoader;
eprintln!("🔌 DEBUG: Creating FileBox through dynamic library for path: {}", path_str.value);
let file_box = PluginLoader::create_file_box(&path_str.value)?;
eprintln!("🔌 DEBUG: FileBox created successfully, type_name: {}", file_box.type_name());
return Ok(file_box);
}
#[cfg(not(feature = "dynamic-file"))]
{
// 静的リンク版
let file_box = match FileBox::open(&path_str.value) {
Ok(fb) => Box::new(fb) as Box<dyn NyashBox>,
Err(e) => return Err(RuntimeError::InvalidOperation {
message: format!("Failed to create FileBox: {}", e)
})
};
return Ok(file_box);
}
} else {
return Err(RuntimeError::TypeError {
message: "FileBox constructor requires string path argument".to_string(),
});
// 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)?);
}
return registry.create_box("FileBox", &evaluated_args)
.map_err(|e| RuntimeError::InvalidOperation { message: e });
}
"ResultBox" => {
// ResultBoxは引数1個成功値で作成