/*! * System Methods Module * * Extracted from box_methods.rs * Contains system-level Box method implementations: * - TimeBox methods (now, fromTimestamp, parse, sleep, format) * - DateTimeBox methods (year, month, day, hour, minute, second, timestamp, toISOString, format, addDays, addHours) * - TimerBox methods (elapsed, reset) * - DebugBox methods (startTracking, stopTracking, trackBox, dumpAll, saveToFile, watch, etc.) */ use super::*; use crate::box_trait::StringBox; use crate::boxes::{TimeBox, DateTimeBox}; impl NyashInterpreter { /// TimeBoxのメソッド呼び出しを実行 pub(super) fn execute_time_method(&mut self, time_box: &TimeBox, method: &str, arguments: &[ASTNode]) -> Result, RuntimeError> { // 引数を評価 let mut arg_values = Vec::new(); for arg in arguments { arg_values.push(self.execute_expression(arg)?); } // メソッドを実行 match method { "now" => { if !arg_values.is_empty() { return Err(RuntimeError::InvalidOperation { message: format!("now() expects 0 arguments, got {}", arg_values.len()), }); } Ok(time_box.now()) } "fromTimestamp" => { if arg_values.len() != 1 { return Err(RuntimeError::InvalidOperation { message: format!("fromTimestamp() expects 1 argument, got {}", arg_values.len()), }); } Ok(time_box.fromTimestamp(arg_values[0].clone_box())) } "parse" => { if arg_values.len() != 1 { return Err(RuntimeError::InvalidOperation { message: format!("parse() expects 1 argument, got {}", arg_values.len()), }); } Ok(time_box.parse(arg_values[0].clone_box())) } "sleep" => { if arg_values.len() != 1 { return Err(RuntimeError::InvalidOperation { message: format!("sleep() expects 1 argument, got {}", arg_values.len()), }); } Ok(time_box.sleep(arg_values[0].clone_box())) } "format" => { if arg_values.len() != 1 { return Err(RuntimeError::InvalidOperation { message: format!("format() expects 1 argument, got {}", arg_values.len()), }); } Ok(time_box.format(arg_values[0].clone_box())) } _ => { Err(RuntimeError::InvalidOperation { message: format!("Unknown TimeBox method: {}", method), }) } } } /// DateTimeBoxのメソッド呼び出しを実行 pub(super) fn execute_datetime_method(&mut self, datetime_box: &DateTimeBox, method: &str, arguments: &[ASTNode]) -> Result, RuntimeError> { // 引数を評価 let mut arg_values = Vec::new(); for arg in arguments { arg_values.push(self.execute_expression(arg)?); } // メソッドを実行 match method { "year" => { if !arg_values.is_empty() { return Err(RuntimeError::InvalidOperation { message: format!("year() expects 0 arguments, got {}", arg_values.len()), }); } Ok(datetime_box.year()) } "month" => { if !arg_values.is_empty() { return Err(RuntimeError::InvalidOperation { message: format!("month() expects 0 arguments, got {}", arg_values.len()), }); } Ok(datetime_box.month()) } "day" => { if !arg_values.is_empty() { return Err(RuntimeError::InvalidOperation { message: format!("day() expects 0 arguments, got {}", arg_values.len()), }); } Ok(datetime_box.day()) } "hour" => { if !arg_values.is_empty() { return Err(RuntimeError::InvalidOperation { message: format!("hour() expects 0 arguments, got {}", arg_values.len()), }); } Ok(datetime_box.hour()) } "minute" => { if !arg_values.is_empty() { return Err(RuntimeError::InvalidOperation { message: format!("minute() expects 0 arguments, got {}", arg_values.len()), }); } Ok(datetime_box.minute()) } "second" => { if !arg_values.is_empty() { return Err(RuntimeError::InvalidOperation { message: format!("second() expects 0 arguments, got {}", arg_values.len()), }); } Ok(datetime_box.second()) } "timestamp" => { if !arg_values.is_empty() { return Err(RuntimeError::InvalidOperation { message: format!("timestamp() expects 0 arguments, got {}", arg_values.len()), }); } Ok(datetime_box.timestamp()) } "toISOString" => { if !arg_values.is_empty() { return Err(RuntimeError::InvalidOperation { message: format!("toISOString() expects 0 arguments, got {}", arg_values.len()), }); } Ok(datetime_box.toISOString()) } "format" => { if arg_values.len() != 1 { return Err(RuntimeError::InvalidOperation { message: format!("format() expects 1 argument, got {}", arg_values.len()), }); } Ok(datetime_box.format(arg_values[0].clone_box())) } "addDays" => { if arg_values.len() != 1 { return Err(RuntimeError::InvalidOperation { message: format!("addDays() expects 1 argument, got {}", arg_values.len()), }); } Ok(datetime_box.addDays(arg_values[0].clone_box())) } "addHours" => { if arg_values.len() != 1 { return Err(RuntimeError::InvalidOperation { message: format!("addHours() expects 1 argument, got {}", arg_values.len()), }); } Ok(datetime_box.addHours(arg_values[0].clone_box())) } "toString" => { if !arg_values.is_empty() { return Err(RuntimeError::InvalidOperation { message: format!("toString() expects 0 arguments, got {}", arg_values.len()), }); } Ok(Box::new(datetime_box.to_string_box())) } _ => { Err(RuntimeError::InvalidOperation { message: format!("Unknown DateTimeBox method: {}", method), }) } } } /// TimerBoxのメソッド呼び出しを実行 pub(super) fn execute_timer_method(&mut self, timer_box: &TimerBox, method: &str, arguments: &[ASTNode]) -> Result, RuntimeError> { // 引数を評価 let mut arg_values = Vec::new(); for arg in arguments { arg_values.push(self.execute_expression(arg)?); } // メソッドを実行 match method { "elapsed" => { if !arg_values.is_empty() { return Err(RuntimeError::InvalidOperation { message: format!("elapsed() expects 0 arguments, got {}", arg_values.len()), }); } Ok(timer_box.elapsed()) } "reset" => { if !arg_values.is_empty() { return Err(RuntimeError::InvalidOperation { message: format!("reset() expects 0 arguments, got {}", arg_values.len()), }); } // NOTE: resetはmutableメソッドなので、ここでは新しいTimerBoxを作成 let timer_box = Box::new(TimerBox::new()) as Box; // 🌍 革命的実装:Environment tracking廃止 Ok(timer_box) } _ => { Err(RuntimeError::InvalidOperation { message: format!("Unknown TimerBox method: {}", method), }) } } } /// DebugBoxのメソッド呼び出しを実行 pub(super) fn execute_debug_method(&mut self, debug_box: &DebugBox, method: &str, arguments: &[ASTNode]) -> Result, RuntimeError> { // 引数を評価 let mut arg_values = Vec::new(); for arg in arguments { arg_values.push(self.execute_expression(arg)?); } // メソッドを実行 match method { "startTracking" => { if !arg_values.is_empty() { return Err(RuntimeError::InvalidOperation { message: format!("startTracking() expects 0 arguments, got {}", arg_values.len()), }); } debug_box.start_tracking() } "stopTracking" => { if !arg_values.is_empty() { return Err(RuntimeError::InvalidOperation { message: format!("stopTracking() expects 0 arguments, got {}", arg_values.len()), }); } debug_box.stop_tracking() } "trackBox" => { if arg_values.len() != 2 { return Err(RuntimeError::InvalidOperation { message: format!("trackBox() expects 2 arguments, got {}", arg_values.len()), }); } // 第2引数をStringBoxとして取得 let name = if let Some(str_box) = arg_values[1].as_any().downcast_ref::() { str_box.value.clone() } else { return Err(RuntimeError::InvalidOperation { message: "trackBox() second argument must be a string".to_string(), }); }; debug_box.track_box(arg_values[0].as_ref(), &name) } "dumpAll" => { if !arg_values.is_empty() { return Err(RuntimeError::InvalidOperation { message: format!("dumpAll() expects 0 arguments, got {}", arg_values.len()), }); } debug_box.dump_all() } "saveToFile" => { if arg_values.len() != 1 { return Err(RuntimeError::InvalidOperation { message: format!("saveToFile() expects 1 argument, got {}", arg_values.len()), }); } let filename = if let Some(str_box) = arg_values[0].as_any().downcast_ref::() { str_box.value.clone() } else { return Err(RuntimeError::InvalidOperation { message: "saveToFile() argument must be a string".to_string(), }); }; debug_box.save_to_file(&filename) } "watch" => { if arg_values.len() != 2 { return Err(RuntimeError::InvalidOperation { message: format!("watch() expects 2 arguments, got {}", arg_values.len()), }); } let name = if let Some(str_box) = arg_values[1].as_any().downcast_ref::() { str_box.value.clone() } else { return Err(RuntimeError::InvalidOperation { message: "watch() second argument must be a string".to_string(), }); }; debug_box.watch(arg_values[0].as_ref(), &name) } "memoryReport" => { if !arg_values.is_empty() { return Err(RuntimeError::InvalidOperation { message: format!("memoryReport() expects 0 arguments, got {}", arg_values.len()), }); } debug_box.memory_report() } "setBreakpoint" => { if arg_values.len() != 1 { return Err(RuntimeError::InvalidOperation { message: format!("setBreakpoint() expects 1 argument, got {}", arg_values.len()), }); } let func_name = if let Some(str_box) = arg_values[0].as_any().downcast_ref::() { str_box.value.clone() } else { return Err(RuntimeError::InvalidOperation { message: "setBreakpoint() argument must be a string".to_string(), }); }; debug_box.set_breakpoint(&func_name) } "traceCall" => { if arg_values.len() < 1 { return Err(RuntimeError::InvalidOperation { message: format!("traceCall() expects at least 1 argument, got {}", arg_values.len()), }); } let func_name = if let Some(str_box) = arg_values[0].as_any().downcast_ref::() { str_box.value.clone() } else { return Err(RuntimeError::InvalidOperation { message: "traceCall() first argument must be a string".to_string(), }); }; // 残りの引数を文字列として収集 let args: Vec = arg_values[1..].iter() .map(|v| v.to_string_box().value) .collect(); debug_box.trace_call(&func_name, args) } "showCallStack" => { if !arg_values.is_empty() { return Err(RuntimeError::InvalidOperation { message: format!("showCallStack() expects 0 arguments, got {}", arg_values.len()), }); } debug_box.show_call_stack() } "tracePluginCalls" => { if arg_values.len() != 1 { return Err(RuntimeError::InvalidOperation { message: format!("tracePluginCalls(on:bool) expects 1 argument, got {}", arg_values.len()), }); } let on = if let Some(b) = arg_values[0].as_any().downcast_ref::() { b.value } else { false }; debug_box.trace_plugin_calls(on) } "getJitEvents" => { if !arg_values.is_empty() { return Err(RuntimeError::InvalidOperation { message: format!("getJitEvents() expects 0 arguments, got {}", arg_values.len()), }); } debug_box.get_jit_events() } "clear" => { if !arg_values.is_empty() { return Err(RuntimeError::InvalidOperation { message: format!("clear() expects 0 arguments, got {}", arg_values.len()), }); } debug_box.clear() } "isTracking" => { if !arg_values.is_empty() { return Err(RuntimeError::InvalidOperation { message: format!("isTracking() expects 0 arguments, got {}", arg_values.len()), }); } debug_box.is_tracking() } "getTrackedCount" => { if !arg_values.is_empty() { return Err(RuntimeError::InvalidOperation { message: format!("getTrackedCount() expects 0 arguments, got {}", arg_values.len()), }); } debug_box.get_tracked_count() } _ => { Err(RuntimeError::InvalidOperation { message: format!("Unknown DebugBox method: {}", method), }) } } } }