Files
hakorune/src/interpreter/objects_basic_constructors.rs

158 lines
7.1 KiB
Rust
Raw Normal View History

//! Basic type constructors for execute_new
//! Handles StringBox, IntegerBox, BoolBox, ArrayBox, etc.
use crate::ast::ASTNode;
use crate::box_trait::*;
use crate::interpreter::core::{NyashInterpreter as Interpreter, RuntimeError};
use crate::boxes::FloatBox;
use crate::boxes::null_box::NullBox;
use crate::boxes::map_box::MapBox;
impl Interpreter {
/// Create basic type boxes (StringBox, IntegerBox, BoolBox, etc.)
pub(super) fn create_basic_box(
&mut self,
class: &str,
arguments: &[ASTNode]
) -> Result<Box<dyn NyashBox>, RuntimeError> {
match class {
"StringBox" => {
// StringBoxは引数1個文字列値で作成
if arguments.len() != 1 {
return Err(RuntimeError::InvalidOperation {
message: format!("StringBox constructor expects 1 argument, got {}", arguments.len()),
});
}
let value = self.execute_expression(&arguments[0])?;
if let Some(s) = value.as_any().downcast_ref::<StringBox>() {
return Ok(Box::new(StringBox::new(s.value.clone())));
} else if let Some(i) = value.as_any().downcast_ref::<IntegerBox>() {
return Ok(Box::new(StringBox::new(i.value.to_string())));
} else if let Some(b) = value.as_any().downcast_ref::<BoolBox>() {
return Ok(Box::new(StringBox::new(b.value.to_string())));
} else {
return Ok(Box::new(StringBox::new(value.to_string_box().value)));
}
}
"IntegerBox" => {
// IntegerBoxは引数1個整数値で作成
if arguments.len() != 1 {
return Err(RuntimeError::InvalidOperation {
message: format!("IntegerBox constructor expects 1 argument, got {}", arguments.len()),
});
}
let value = self.execute_expression(&arguments[0])?;
if let Some(i) = value.as_any().downcast_ref::<IntegerBox>() {
return Ok(Box::new(IntegerBox::new(i.value)));
} else if let Some(s) = value.as_any().downcast_ref::<StringBox>() {
match s.value.parse::<i64>() {
Ok(n) => return Ok(Box::new(IntegerBox::new(n))),
Err(_) => return Err(RuntimeError::TypeError {
message: format!("Cannot convert '{}' to integer", s.value),
}),
}
} else {
return Err(RuntimeError::TypeError {
message: "IntegerBox constructor requires integer or string argument".to_string(),
});
}
}
"BoolBox" => {
// BoolBoxは引数1個ブール値で作成
if arguments.len() != 1 {
return Err(RuntimeError::InvalidOperation {
message: format!("BoolBox constructor expects 1 argument, got {}", arguments.len()),
});
}
let value = self.execute_expression(&arguments[0])?;
if let Some(b) = value.as_any().downcast_ref::<BoolBox>() {
return Ok(Box::new(BoolBox::new(b.value)));
} else if let Some(s) = value.as_any().downcast_ref::<StringBox>() {
let val = match s.value.as_str() {
"true" => true,
"false" => false,
_ => return Err(RuntimeError::TypeError {
message: format!("Cannot convert '{}' to boolean", s.value),
}),
};
return Ok(Box::new(BoolBox::new(val)));
} else {
return Err(RuntimeError::TypeError {
message: "BoolBox constructor requires boolean or string argument".to_string(),
});
}
}
"ArrayBox" => {
// ArrayBoxは引数なしで作成
if !arguments.is_empty() {
return Err(RuntimeError::InvalidOperation {
message: format!("ArrayBox constructor expects 0 arguments, got {}", arguments.len()),
});
}
return Ok(Box::new(ArrayBox::new()));
}
"NullBox" => {
// NullBoxは引数なしで作成
if !arguments.is_empty() {
return Err(RuntimeError::InvalidOperation {
message: format!("NullBox constructor expects 0 arguments, got {}", arguments.len()),
});
}
return Ok(Box::new(NullBox::new()));
}
"MapBox" => {
// MapBoxは引数なしで作成
if !arguments.is_empty() {
return Err(RuntimeError::InvalidOperation {
message: format!("MapBox constructor expects 0 arguments, got {}", arguments.len()),
});
}
let map_box = Box::new(MapBox::new()) as Box<dyn NyashBox>;
return Ok(map_box);
}
"FloatBox" => {
// FloatBoxは引数1個浮動小数点数値で作成
if arguments.len() != 1 {
return Err(RuntimeError::InvalidOperation {
message: format!("FloatBox constructor expects 1 argument, got {}", arguments.len()),
});
}
let value = self.execute_expression(&arguments[0])?;
if let Some(f) = value.as_any().downcast_ref::<FloatBox>() {
return Ok(Box::new(FloatBox::new(f.value)));
} else if let Some(i) = value.as_any().downcast_ref::<IntegerBox>() {
return Ok(Box::new(FloatBox::new(i.value as f64)));
} else if let Some(s) = value.as_any().downcast_ref::<StringBox>() {
match s.value.parse::<f64>() {
Ok(n) => return Ok(Box::new(FloatBox::new(n))),
Err(_) => return Err(RuntimeError::TypeError {
message: format!("Cannot convert '{}' to float", s.value),
}),
}
} else {
return Err(RuntimeError::TypeError {
message: "FloatBox constructor requires float, integer, or string argument".to_string(),
});
}
}
_ => {
// Not a basic type
Err(RuntimeError::TypeError {
message: format!("Not a basic type: {}", class),
})
}
}
}
}