/*! * VM BoxCall Dispatch - method calls on boxes */ use crate::box_trait::{NyashBox, StringBox, IntegerBox, BoolBox, VoidBox}; use super::vm::{VM, VMError}; impl VM { /// Call a method on a Box - simplified version of interpreter method dispatch pub(super) fn call_box_method_impl(&self, box_value: Box, method: &str, _args: Vec>) -> Result, VMError> { // ResultBox (NyashResultBox - new) if let Some(result_box) = box_value.as_any().downcast_ref::() { match method { "is_ok" | "isOk" => { return Ok(result_box.is_ok()); } "get_value" | "getValue" => { return Ok(result_box.get_value()); } "get_error" | "getError" => { return Ok(result_box.get_error()); } _ => return Ok(Box::new(VoidBox::new())), } } // ResultBox (box_trait::ResultBox - legacy) { #[allow(deprecated)] if let Some(result_box_legacy) = box_value.as_any().downcast_ref::() { match method { "is_ok" | "isOk" => { return Ok(result_box_legacy.is_ok()); } "get_value" | "getValue" => { return Ok(result_box_legacy.get_value()); } "get_error" | "getError" => { return Ok(result_box_legacy.get_error()); } _ => return Ok(Box::new(VoidBox::new())), } } } // Generic fallback: toString for any Box type if method == "toString" { return Ok(Box::new(StringBox::new(box_value.to_string_box().value))); } // StringBox methods if let Some(string_box) = box_value.as_any().downcast_ref::() { match method { "length" | "len" => { return Ok(Box::new(IntegerBox::new(string_box.value.len() as i64))); } "toString" => { return Ok(Box::new(StringBox::new(string_box.value.clone()))); } _ => return Ok(Box::new(VoidBox::new())), } } // ArrayBox methods (minimal set) if let Some(array_box) = box_value.as_any().downcast_ref::() { match method { "push" => { if let Some(v) = _args.get(0) { return Ok(array_box.push(v.clone_or_share())); } return Ok(Box::new(StringBox::new("Error: push(value) requires 1 arg"))); } "pop" => { return Ok(array_box.pop()); }, "length" | "len" => { return Ok(array_box.length()); }, "get" => { if let Some(i) = _args.get(0) { return Ok(array_box.get(i.clone_or_share())); } return Ok(Box::new(StringBox::new("Error: get(index) requires 1 arg"))); } "set" => { if _args.len() >= 2 { return Ok(array_box.set(_args[0].clone_or_share(), _args[1].clone_or_share())); } return Ok(Box::new(StringBox::new("Error: set(index, value) requires 2 args"))); } "remove" => { if let Some(i) = _args.get(0) { return Ok(array_box.remove(i.clone_or_share())); } return Ok(Box::new(StringBox::new("Error: remove(index) requires 1 arg"))); } "contains" => { if let Some(v) = _args.get(0) { return Ok(array_box.contains(v.clone_or_share())); } return Ok(Box::new(StringBox::new("Error: contains(value) requires 1 arg"))); } "indexOf" => { if let Some(v) = _args.get(0) { return Ok(array_box.indexOf(v.clone_or_share())); } return Ok(Box::new(StringBox::new("Error: indexOf(value) requires 1 arg"))); } "clear" => { return Ok(array_box.clear()); }, "join" => { if let Some(sep) = _args.get(0) { return Ok(array_box.join(sep.clone_or_share())); } return Ok(Box::new(StringBox::new("Error: join(sep) requires 1 arg"))); } "sort" => { return Ok(array_box.sort()); }, "reverse" => { return Ok(array_box.reverse()); }, "slice" => { if _args.len() >= 2 { return Ok(array_box.slice(_args[0].clone_or_share(), _args[1].clone_or_share())); } return Ok(Box::new(StringBox::new("Error: slice(start, end) requires 2 args"))); } _ => return Ok(Box::new(VoidBox::new())), } } // MapBox methods (minimal set) if let Some(map_box) = box_value.as_any().downcast_ref::() { match method { "set" => { if _args.len() >= 2 { return Ok(map_box.set(_args[0].clone_or_share(), _args[1].clone_or_share())); } return Ok(Box::new(StringBox::new("Error: set(key, value) requires 2 args"))); } "get" => { if let Some(k) = _args.get(0) { return Ok(map_box.get(k.clone_or_share())); } return Ok(Box::new(StringBox::new("Error: get(key) requires 1 arg"))); } "has" => { if let Some(k) = _args.get(0) { return Ok(map_box.has(k.clone_or_share())); } return Ok(Box::new(StringBox::new("Error: has(key) requires 1 arg"))); } "delete" | "remove" => { if let Some(k) = _args.get(0) { return Ok(map_box.delete(k.clone_or_share())); } return Ok(Box::new(StringBox::new("Error: delete(key) requires 1 arg"))); } "keys" => { return Ok(map_box.keys()); }, "values" => { return Ok(map_box.values()); }, "size" => { return Ok(map_box.size()); }, "clear" => { return Ok(map_box.clear()); }, _ => return Ok(Box::new(VoidBox::new())), } } // SocketBox methods (minimal + timeouts) if let Some(sock) = box_value.as_any().downcast_ref::() { match method { "bind" => { if _args.len() >= 2 { return Ok(sock.bind(_args[0].clone_or_share(), _args[1].clone_or_share())); } return Ok(Box::new(StringBox::new("Error: bind(address, port) requires 2 args"))); } "listen" => { if let Some(b) = _args.get(0) { return Ok(sock.listen(b.clone_or_share())); } return Ok(Box::new(StringBox::new("Error: listen(backlog) requires 1 arg"))); } "accept" => { return Ok(sock.accept()); }, "acceptTimeout" | "accept_timeout" => { if let Some(ms) = _args.get(0) { return Ok(sock.accept_timeout(ms.clone_or_share())); } return Ok(Box::new(crate::box_trait::VoidBox::new())); } "connect" => { if _args.len() >= 2 { return Ok(sock.connect(_args[0].clone_or_share(), _args[1].clone_or_share())); } return Ok(Box::new(StringBox::new("Error: connect(address, port) requires 2 args"))); } "read" => { return Ok(sock.read()); }, "recvTimeout" | "recv_timeout" => { if let Some(ms) = _args.get(0) { return Ok(sock.recv_timeout(ms.clone_or_share())); } return Ok(Box::new(StringBox::new(""))); } "write" => { if let Some(d) = _args.get(0) { return Ok(sock.write(d.clone_or_share())); } return Ok(Box::new(crate::box_trait::BoolBox::new(false))); } "close" => { return Ok(sock.close()); }, "isServer" | "is_server" => { return Ok(sock.is_server()); }, "isConnected" | "is_connected" => { return Ok(sock.is_connected()); }, _ => return Ok(Box::new(VoidBox::new())), } } // IntegerBox methods if let Some(integer_box) = box_value.as_any().downcast_ref::() { match method { "toString" => { return Ok(Box::new(StringBox::new(integer_box.value.to_string()))); }, "abs" => { return Ok(Box::new(IntegerBox::new(integer_box.value.abs()))); }, _ => return Ok(Box::new(VoidBox::new())), } } // BoolBox methods if let Some(bool_box) = box_value.as_any().downcast_ref::() { match method { "toString" => { return Ok(Box::new(StringBox::new(bool_box.value.to_string()))); }, _ => return Ok(Box::new(VoidBox::new())), } } // Default: return void for any unrecognized box type or method Ok(Box::new(VoidBox::new())) } }