2025-08-12 01:35:36 +00:00
|
|
|
|
/*! 📡 P2P通信メソッド実装 (NEW ARCHITECTURE)
|
2025-08-11 05:11:52 +09:00
|
|
|
|
* IntentBoxとP2PBoxのNyashインタープリター統合
|
2025-08-12 01:35:36 +00:00
|
|
|
|
* Arc<Mutex>パターン対応版
|
2025-08-11 05:11:52 +09:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
use crate::ast::ASTNode;
|
2025-08-16 17:39:04 +09:00
|
|
|
|
use crate::box_trait::{NyashBox, StringBox};
|
2025-08-26 19:13:57 +09:00
|
|
|
|
use crate::boxes::{IntentBox, P2PBox};
|
2025-09-17 07:43:07 +09:00
|
|
|
|
use crate::interpreter::NyashInterpreter;
|
|
|
|
|
|
use crate::interpreter::RuntimeError;
|
2025-08-11 05:11:52 +09:00
|
|
|
|
|
|
|
|
|
|
impl NyashInterpreter {
|
2025-08-15 03:08:09 +00:00
|
|
|
|
/// IntentBoxのメソッド実行 (RwLock版)
|
2025-08-11 05:11:52 +09:00
|
|
|
|
pub(in crate::interpreter) fn execute_intent_box_method(
|
|
|
|
|
|
&mut self,
|
|
|
|
|
|
intent_box: &IntentBox,
|
|
|
|
|
|
method: &str,
|
|
|
|
|
|
_arguments: &[ASTNode],
|
2025-09-17 07:43:07 +09:00
|
|
|
|
) -> Result<Box<dyn NyashBox>, RuntimeError> {
|
2025-08-11 05:11:52 +09:00
|
|
|
|
match method {
|
2025-08-12 01:35:36 +00:00
|
|
|
|
// メッセージ名取得
|
2025-09-17 07:43:07 +09:00
|
|
|
|
"getName" | "name" => Ok(intent_box.get_name()),
|
|
|
|
|
|
|
2025-08-12 01:35:36 +00:00
|
|
|
|
// ペイロード取得(JSON文字列として)
|
2025-09-17 07:43:07 +09:00
|
|
|
|
"getPayload" | "payload" => Ok(intent_box.get_payload()),
|
|
|
|
|
|
|
2025-08-12 01:35:36 +00:00
|
|
|
|
// 型情報取得
|
2025-09-17 07:43:07 +09:00
|
|
|
|
"getType" | "type" => Ok(Box::new(StringBox::new("IntentBox"))),
|
|
|
|
|
|
|
2025-08-11 05:11:52 +09:00
|
|
|
|
_ => Err(RuntimeError::UndefinedVariable {
|
|
|
|
|
|
name: format!("IntentBox method '{}' not found", method),
|
2025-09-17 07:43:07 +09:00
|
|
|
|
}),
|
2025-08-11 05:11:52 +09:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-09-17 07:43:07 +09:00
|
|
|
|
|
2025-08-26 19:13:57 +09:00
|
|
|
|
// P2PBoxのメソッド実装(RwLockベース)
|
2025-08-11 05:11:52 +09:00
|
|
|
|
pub(in crate::interpreter) fn execute_p2p_box_method(
|
|
|
|
|
|
&mut self,
|
|
|
|
|
|
p2p_box: &P2PBox,
|
|
|
|
|
|
method: &str,
|
|
|
|
|
|
arguments: &[ASTNode],
|
|
|
|
|
|
) -> Result<Box<dyn NyashBox>, RuntimeError> {
|
2025-09-17 07:43:07 +09:00
|
|
|
|
if crate::interpreter::utils::debug_on()
|
|
|
|
|
|
|| std::env::var("NYASH_DEBUG_P2P").unwrap_or_default() == "1"
|
|
|
|
|
|
{
|
|
|
|
|
|
eprintln!(
|
|
|
|
|
|
"[Interp:P2P] {}(..) called with {} args",
|
|
|
|
|
|
method,
|
|
|
|
|
|
arguments.len()
|
|
|
|
|
|
);
|
2025-08-26 20:30:07 +09:00
|
|
|
|
}
|
2025-08-11 05:11:52 +09:00
|
|
|
|
match method {
|
|
|
|
|
|
// ノードID取得
|
2025-08-26 19:13:57 +09:00
|
|
|
|
"getNodeId" | "getId" => Ok(p2p_box.get_node_id()),
|
|
|
|
|
|
|
2025-08-12 01:35:36 +00:00
|
|
|
|
// トランスポート種類取得
|
2025-08-26 19:13:57 +09:00
|
|
|
|
"getTransportType" | "transport" => Ok(p2p_box.get_transport_type()),
|
|
|
|
|
|
|
2025-08-12 01:35:36 +00:00
|
|
|
|
// ノード到達可能性確認
|
|
|
|
|
|
"isReachable" => {
|
|
|
|
|
|
if arguments.is_empty() {
|
2025-09-17 07:43:07 +09:00
|
|
|
|
return Err(RuntimeError::InvalidOperation {
|
|
|
|
|
|
message: "isReachable requires node_id argument".to_string(),
|
|
|
|
|
|
});
|
2025-08-11 05:11:52 +09:00
|
|
|
|
}
|
2025-08-12 01:35:36 +00:00
|
|
|
|
let node_id_result = self.execute_expression(&arguments[0])?;
|
2025-08-26 19:13:57 +09:00
|
|
|
|
Ok(p2p_box.is_reachable(node_id_result))
|
2025-08-11 05:11:52 +09:00
|
|
|
|
}
|
2025-08-26 19:13:57 +09:00
|
|
|
|
|
|
|
|
|
|
// send メソッド実装(ResultBox返却)
|
2025-08-12 01:35:36 +00:00
|
|
|
|
"send" => {
|
|
|
|
|
|
if arguments.len() < 2 {
|
2025-09-17 07:43:07 +09:00
|
|
|
|
return Err(RuntimeError::InvalidOperation {
|
|
|
|
|
|
message: "send requires (to, intent) arguments".to_string(),
|
|
|
|
|
|
});
|
2025-08-11 05:11:52 +09:00
|
|
|
|
}
|
2025-08-12 01:35:36 +00:00
|
|
|
|
let to_result = self.execute_expression(&arguments[0])?;
|
|
|
|
|
|
let intent_result = self.execute_expression(&arguments[1])?;
|
2025-08-26 19:13:57 +09:00
|
|
|
|
Ok(p2p_box.send(to_result, intent_result))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-28 09:26:58 +09:00
|
|
|
|
// ping: health check using sys.ping/sys.pong
|
|
|
|
|
|
"ping" => {
|
|
|
|
|
|
if arguments.is_empty() {
|
2025-09-17 07:43:07 +09:00
|
|
|
|
return Err(RuntimeError::InvalidOperation {
|
|
|
|
|
|
message: "ping requires (to [, timeout_ms]) arguments".to_string(),
|
|
|
|
|
|
});
|
2025-08-28 09:26:58 +09:00
|
|
|
|
}
|
|
|
|
|
|
let to_result = self.execute_expression(&arguments[0])?;
|
|
|
|
|
|
if arguments.len() >= 2 {
|
|
|
|
|
|
let tmo_val = self.execute_expression(&arguments[1])?;
|
|
|
|
|
|
let tmo_ms = tmo_val.to_string_box().value.parse::<u64>().unwrap_or(200);
|
|
|
|
|
|
Ok(p2p_box.ping_with_timeout(to_result, tmo_ms))
|
|
|
|
|
|
} else {
|
|
|
|
|
|
Ok(p2p_box.ping(to_result))
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-26 19:13:57 +09:00
|
|
|
|
// on メソッド実装(ResultBox返却)
|
2025-08-26 20:30:07 +09:00
|
|
|
|
"on" => {
|
2025-08-26 19:13:57 +09:00
|
|
|
|
if arguments.len() < 2 {
|
2025-09-17 07:43:07 +09:00
|
|
|
|
return Err(RuntimeError::InvalidOperation {
|
|
|
|
|
|
message: "on requires (intentName, handler) arguments".to_string(),
|
|
|
|
|
|
});
|
2025-08-12 01:35:36 +00:00
|
|
|
|
}
|
2025-08-26 19:13:57 +09:00
|
|
|
|
let name_val = self.execute_expression(&arguments[0])?;
|
|
|
|
|
|
let handler_val = self.execute_expression(&arguments[1])?;
|
|
|
|
|
|
Ok(p2p_box.on(name_val, handler_val))
|
2025-08-11 05:11:52 +09:00
|
|
|
|
}
|
2025-08-26 19:13:57 +09:00
|
|
|
|
|
|
|
|
|
|
// 最後の受信情報(ループバック検証用)
|
|
|
|
|
|
"getLastFrom" => Ok(p2p_box.get_last_from()),
|
|
|
|
|
|
"getLastIntentName" => Ok(p2p_box.get_last_intent_name()),
|
|
|
|
|
|
"debug_nodes" | "debugNodes" => Ok(p2p_box.debug_nodes()),
|
|
|
|
|
|
"debug_bus_id" | "debugBusId" => Ok(p2p_box.debug_bus_id()),
|
|
|
|
|
|
|
|
|
|
|
|
// onOnce / off
|
|
|
|
|
|
"onOnce" | "on_once" => {
|
|
|
|
|
|
if arguments.len() < 2 {
|
2025-09-17 07:43:07 +09:00
|
|
|
|
return Err(RuntimeError::InvalidOperation {
|
|
|
|
|
|
message: "onOnce requires (intentName, handler) arguments".to_string(),
|
|
|
|
|
|
});
|
2025-08-26 19:13:57 +09:00
|
|
|
|
}
|
|
|
|
|
|
let name_val = self.execute_expression(&arguments[0])?;
|
|
|
|
|
|
let handler_val = self.execute_expression(&arguments[1])?;
|
|
|
|
|
|
Ok(p2p_box.on_once(name_val, handler_val))
|
|
|
|
|
|
}
|
|
|
|
|
|
"off" => {
|
|
|
|
|
|
if arguments.len() < 1 {
|
2025-09-17 07:43:07 +09:00
|
|
|
|
return Err(RuntimeError::InvalidOperation {
|
|
|
|
|
|
message: "off requires (intentName) argument".to_string(),
|
|
|
|
|
|
});
|
2025-08-26 19:13:57 +09:00
|
|
|
|
}
|
|
|
|
|
|
let name_val = self.execute_expression(&arguments[0])?;
|
|
|
|
|
|
Ok(p2p_box.off(name_val))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-17 07:43:07 +09:00
|
|
|
|
_ => Err(RuntimeError::UndefinedVariable {
|
|
|
|
|
|
name: format!("P2PBox method '{}' not found", method),
|
|
|
|
|
|
}),
|
2025-08-11 05:11:52 +09:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-08-26 19:13:57 +09:00
|
|
|
|
}
|