Files
hakorune/src/interpreter/methods/http_methods.rs
Moe Charm 2949648e71 fix: MIR builder me resolution for static box methods
- Fixed me ValueId inconsistency in static box methods
- Previously, each me reference generated a new const __me__ ValueId
- Now caches the first me ValueId in variable_map for reuse
- This ensures RefSet and RefGet operate on the same object
- ArrayBox get/set/push now working correctly in VM mode
- Test results: 1, 42, 3 (as expected)

🔧 Technical Details:
- build_me_expression() now stores fallback ValueId in variable_map
- Subsequent me references reuse the same ValueId
- VM BoxCall debug logs confirm ArrayBox methods dispatch correctly

Co-Authored-By: ChatGPT5
Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-23 21:13:02 +09:00

306 lines
12 KiB
Rust

/*! 🌐 HTTP Method Implementations
*
* HTTP関連Boxのメソッド実行を実装
* SocketBox, HTTPServerBox, HTTPRequestBox, HTTPResponseBox
*/
use super::super::*;
use crate::boxes::{SocketBox, HTTPServerBox, HTTPRequestBox, HTTPResponseBox};
impl NyashInterpreter {
/// SocketBox methods
pub(in crate::interpreter) fn execute_socket_method(
&mut self,
socket_box: &SocketBox,
method: &str,
arguments: &[ASTNode]
) -> Result<Box<dyn NyashBox>, RuntimeError> {
match method {
"bind" => {
if arguments.len() != 2 {
return Err(RuntimeError::InvalidOperation {
message: format!("bind() expects 2 arguments, got {}", arguments.len()),
});
}
let address = self.execute_expression(&arguments[0])?;
let port = self.execute_expression(&arguments[1])?;
let result = socket_box.bind(address, port);
Ok(result)
}
"listen" => {
if arguments.len() != 1 {
return Err(RuntimeError::InvalidOperation {
message: format!("listen() expects 1 argument, got {}", arguments.len()),
});
}
let backlog = self.execute_expression(&arguments[0])?;
Ok(socket_box.listen(backlog))
}
"accept" => {
if !arguments.is_empty() {
return Err(RuntimeError::InvalidOperation {
message: format!("accept() expects 0 arguments, got {}", arguments.len()),
});
}
Ok(socket_box.accept())
}
"acceptTimeout" | "accept_timeout" => {
if arguments.len() != 1 {
return Err(RuntimeError::InvalidOperation {
message: format!("acceptTimeout(ms) expects 1 argument, got {}", arguments.len()),
});
}
let ms = self.execute_expression(&arguments[0])?;
Ok(socket_box.accept_timeout(ms))
}
"connect" => {
if arguments.len() != 2 {
return Err(RuntimeError::InvalidOperation {
message: format!("connect() expects 2 arguments, got {}", arguments.len()),
});
}
let address = self.execute_expression(&arguments[0])?;
let port = self.execute_expression(&arguments[1])?;
Ok(socket_box.connect(address, port))
}
"read" => {
if !arguments.is_empty() {
return Err(RuntimeError::InvalidOperation {
message: format!("read() expects 0 arguments, got {}", arguments.len()),
});
}
Ok(socket_box.read())
}
"recvTimeout" | "recv_timeout" => {
if arguments.len() != 1 {
return Err(RuntimeError::InvalidOperation {
message: format!("recvTimeout(ms) expects 1 argument, got {}", arguments.len()),
});
}
let ms = self.execute_expression(&arguments[0])?;
Ok(socket_box.recv_timeout(ms))
}
"readHttpRequest" => {
if !arguments.is_empty() {
return Err(RuntimeError::InvalidOperation {
message: format!("readHttpRequest() expects 0 arguments, got {}", arguments.len()),
});
}
Ok(socket_box.read_http_request())
}
"write" => {
if arguments.len() != 1 {
return Err(RuntimeError::InvalidOperation {
message: format!("write() expects 1 argument, got {}", arguments.len()),
});
}
let data = self.execute_expression(&arguments[0])?;
Ok(socket_box.write(data))
}
"close" => {
if !arguments.is_empty() {
return Err(RuntimeError::InvalidOperation {
message: format!("close() expects 0 arguments, got {}", arguments.len()),
});
}
Ok(socket_box.close())
}
"isConnected" => {
if !arguments.is_empty() {
return Err(RuntimeError::InvalidOperation {
message: format!("isConnected() expects 0 arguments, got {}", arguments.len()),
});
}
Ok(socket_box.is_connected())
}
"isServer" => {
if !arguments.is_empty() {
return Err(RuntimeError::InvalidOperation {
message: format!("isServer() expects 0 arguments, got {}", arguments.len()),
});
}
Ok(socket_box.is_server())
}
"toString" => {
if !arguments.is_empty() {
return Err(RuntimeError::InvalidOperation {
message: format!("toString() expects 0 arguments, got {}", arguments.len()),
});
}
Ok(Box::new(socket_box.to_string_box()))
}
_ => Err(RuntimeError::UndefinedVariable {
name: format!("SocketBox method '{}' not found", method),
}),
}
}
/// HTTPServerBox methods
pub(in crate::interpreter) fn execute_http_server_method(
&mut self,
server_box: &HTTPServerBox,
method: &str,
arguments: &[ASTNode]
) -> Result<Box<dyn NyashBox>, RuntimeError> {
match method {
"bind" => {
if arguments.len() != 2 {
return Err(RuntimeError::InvalidOperation {
message: format!("bind() expects 2 arguments, got {}", arguments.len()),
});
}
let address = self.execute_expression(&arguments[0])?;
let port = self.execute_expression(&arguments[1])?;
Ok(server_box.bind(address, port))
}
"listen" => {
if arguments.len() != 1 {
return Err(RuntimeError::InvalidOperation {
message: format!("listen() expects 1 argument, got {}", arguments.len()),
});
}
let backlog = self.execute_expression(&arguments[0])?;
Ok(server_box.listen(backlog))
}
"start" => {
if !arguments.is_empty() {
return Err(RuntimeError::InvalidOperation {
message: format!("start() expects 0 arguments, got {}", arguments.len()),
});
}
Ok(server_box.start())
}
"stop" => {
if !arguments.is_empty() {
return Err(RuntimeError::InvalidOperation {
message: format!("stop() expects 0 arguments, got {}", arguments.len()),
});
}
Ok(server_box.stop())
}
"get" => {
if arguments.len() != 2 {
return Err(RuntimeError::InvalidOperation {
message: format!("get() expects 2 arguments, got {}", arguments.len()),
});
}
let path = self.execute_expression(&arguments[0])?;
let handler = self.execute_expression(&arguments[1])?;
Ok(server_box.get(path, handler))
}
"toString" => {
if !arguments.is_empty() {
return Err(RuntimeError::InvalidOperation {
message: format!("toString() expects 0 arguments, got {}", arguments.len()),
});
}
Ok(Box::new(server_box.to_string_box()))
}
_ => Err(RuntimeError::UndefinedVariable {
name: format!("HTTPServerBox method '{}' not found", method),
}),
}
}
/// HTTPRequestBox methods
pub(in crate::interpreter) fn execute_http_request_method(
&mut self,
request_box: &HTTPRequestBox,
method: &str,
arguments: &[ASTNode]
) -> Result<Box<dyn NyashBox>, RuntimeError> {
match method {
"getMethod" => {
if !arguments.is_empty() {
return Err(RuntimeError::InvalidOperation {
message: format!("getMethod() expects 0 arguments, got {}", arguments.len()),
});
}
Ok(request_box.get_method())
}
"getPath" => {
if !arguments.is_empty() {
return Err(RuntimeError::InvalidOperation {
message: format!("getPath() expects 0 arguments, got {}", arguments.len()),
});
}
Ok(request_box.get_path())
}
"toString" => {
if !arguments.is_empty() {
return Err(RuntimeError::InvalidOperation {
message: format!("toString() expects 0 arguments, got {}", arguments.len()),
});
}
Ok(Box::new(request_box.to_string_box()))
}
_ => Err(RuntimeError::UndefinedVariable {
name: format!("HTTPRequestBox method '{}' not found", method),
}),
}
}
/// HTTPResponseBox methods
pub(in crate::interpreter) fn execute_http_response_method(
&mut self,
response_box: &HTTPResponseBox,
method: &str,
arguments: &[ASTNode]
) -> Result<Box<dyn NyashBox>, RuntimeError> {
match method {
"setStatus" => {
if arguments.len() != 2 {
return Err(RuntimeError::InvalidOperation {
message: format!("setStatus() expects 2 arguments, got {}", arguments.len()),
});
}
let code = self.execute_expression(&arguments[0])?;
let message = self.execute_expression(&arguments[1])?;
Ok(response_box.set_status(code, message))
}
"toHttpString" => {
if !arguments.is_empty() {
return Err(RuntimeError::InvalidOperation {
message: format!("toHttpString() expects 0 arguments, got {}", arguments.len()),
});
}
Ok(response_box.to_http_string())
}
"toString" => {
if !arguments.is_empty() {
return Err(RuntimeError::InvalidOperation {
message: format!("toString() expects 0 arguments, got {}", arguments.len()),
});
}
Ok(Box::new(response_box.to_string_box()))
}
_ => Err(RuntimeError::UndefinedVariable {
name: format!("HTTPResponseBox method '{}' not found", method),
}),
}
}
}