Files
hakorune/src/interpreter/system_methods.rs

409 lines
17 KiB
Rust
Raw Normal View History

/*!
* 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<Box<dyn NyashBox>, 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<Box<dyn NyashBox>, 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<Box<dyn NyashBox>, 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<dyn NyashBox>;
// 🌍 革命的実装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<Box<dyn NyashBox>, 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::<StringBox>() {
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::<StringBox>() {
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::<StringBox>() {
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::<StringBox>() {
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::<StringBox>() {
str_box.value.clone()
} else {
return Err(RuntimeError::InvalidOperation {
message: "traceCall() first argument must be a string".to_string(),
});
};
// 残りの引数を文字列として収集
let args: Vec<String> = 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::<crate::box_trait::BoolBox>() { 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),
})
}
}
}
}