diff --git a/src/interpreter/expressions/calls.rs b/src/interpreter/expressions/calls.rs index 3d780b16..9e6f8b82 100644 --- a/src/interpreter/expressions/calls.rs +++ b/src/interpreter/expressions/calls.rs @@ -255,6 +255,11 @@ impl NyashInterpreter { return self.execute_file_method(file_box, method, arguments); } + // PluginFileBox method calls (BID-FFI system) + if let Some(plugin_file_box) = obj_value.as_any().downcast_ref::() { + return self.execute_plugin_file_method(plugin_file_box, method, arguments); + } + // ResultBox method calls if let Some(result_box) = obj_value.as_any().downcast_ref::() { return self.execute_result_method(result_box, method, arguments); diff --git a/src/interpreter/methods/io_methods.rs b/src/interpreter/methods/io_methods.rs index 1f8aeaf5..2686b1d5 100644 --- a/src/interpreter/methods/io_methods.rs +++ b/src/interpreter/methods/io_methods.rs @@ -10,6 +10,7 @@ use super::super::*; use crate::box_trait::{ResultBox, StringBox, NyashBox}; use crate::boxes::FileBox; +use crate::bid::plugin_box::PluginFileBox; impl NyashInterpreter { /// FileBoxのメソッド呼び出しを実行 @@ -105,4 +106,73 @@ impl NyashInterpreter { }) } } + + /// PluginFileBoxのメソッド呼び出しを実行 (BID-FFI system) + /// Handles plugin-backed file I/O operations via FFI interface + pub(in crate::interpreter) fn execute_plugin_file_method(&mut self, plugin_file_box: &PluginFileBox, method: &str, arguments: &[ASTNode]) + -> Result, RuntimeError> { + match method { + "read" => { + if !arguments.is_empty() { + return Err(RuntimeError::InvalidOperation { + message: format!("read() expects 0 arguments, got {}", arguments.len()), + }); + } + // Read the entire file content + match plugin_file_box.read_bytes(8192) { // Read up to 8KB + Ok(bytes) => { + let content = String::from_utf8_lossy(&bytes).to_string(); + Ok(Box::new(StringBox::new(content))) + } + Err(e) => Err(RuntimeError::InvalidOperation { + message: format!("Plugin read failed: {:?}", e), + }) + } + } + "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])?; + let text = content.to_string_box().value; + match plugin_file_box.write_bytes(text.as_bytes()) { + Ok(bytes_written) => Ok(Box::new(StringBox::new("OK".to_string()))), + Err(e) => Err(RuntimeError::InvalidOperation { + message: format!("Plugin write failed: {:?}", e), + }) + } + } + "exists" => { + if !arguments.is_empty() { + return Err(RuntimeError::InvalidOperation { + message: format!("exists() expects 0 arguments, got {}", arguments.len()), + }); + } + // Plugin FileBox doesn't have exists() method in current implementation + // Return true if we can read (approximate) + match plugin_file_box.read_bytes(1) { + Ok(_) => Ok(Box::new(crate::box_trait::BoolBox::new(true))), + Err(_) => Ok(Box::new(crate::box_trait::BoolBox::new(false))), + } + } + "close" => { + if !arguments.is_empty() { + return Err(RuntimeError::InvalidOperation { + message: format!("close() expects 0 arguments, got {}", arguments.len()), + }); + } + match plugin_file_box.close() { + Ok(()) => Ok(Box::new(StringBox::new("OK".to_string()))), + Err(e) => Err(RuntimeError::InvalidOperation { + message: format!("Plugin close failed: {:?}", e), + }) + } + } + _ => Err(RuntimeError::InvalidOperation { + message: format!("Unknown method '{}' for PluginFileBox", method), + }) + } + } } \ No newline at end of file