Stage 2 Progress: box_trait.rs refactoring (1,456→1,001 lines, 31% reduction)
Co-authored-by: moe-charm <217100418+moe-charm@users.noreply.github.com>
This commit is contained in:
546
src/box_arithmetic.rs
Normal file
546
src/box_arithmetic.rs
Normal file
@ -0,0 +1,546 @@
|
|||||||
|
/*!
|
||||||
|
* Box Operations - Binary and unary operations between boxes
|
||||||
|
*
|
||||||
|
* This module contains the implementation of operation boxes that perform
|
||||||
|
* arithmetic, logical, and comparison operations between different Box types.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use crate::box_trait::{NyashBox, BoxCore, StringBox, IntegerBox, BoolBox, VoidBox, BoxBase};
|
||||||
|
use std::fmt::{Debug, Display};
|
||||||
|
use std::any::Any;
|
||||||
|
|
||||||
|
// ===== Binary Operation Boxes =====
|
||||||
|
|
||||||
|
/// Binary operations between boxes (addition, concatenation, etc.)
|
||||||
|
pub struct AddBox {
|
||||||
|
pub left: Box<dyn NyashBox>,
|
||||||
|
pub right: Box<dyn NyashBox>,
|
||||||
|
base: BoxBase,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AddBox {
|
||||||
|
pub fn new(left: Box<dyn NyashBox>, right: Box<dyn NyashBox>) -> Self {
|
||||||
|
Self {
|
||||||
|
left,
|
||||||
|
right,
|
||||||
|
base: BoxBase::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Execute the addition operation and return the result
|
||||||
|
pub fn execute(&self) -> Box<dyn NyashBox> {
|
||||||
|
use crate::boxes::math_box::FloatBox;
|
||||||
|
|
||||||
|
// 1. Integer + Integer
|
||||||
|
if let (Some(left_int), Some(right_int)) = (
|
||||||
|
self.left.as_any().downcast_ref::<IntegerBox>(),
|
||||||
|
self.right.as_any().downcast_ref::<IntegerBox>()
|
||||||
|
) {
|
||||||
|
let result = left_int.value + right_int.value;
|
||||||
|
return Box::new(IntegerBox::new(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Float + Float (or mixed with Integer)
|
||||||
|
if let (Some(left_float), Some(right_float)) = (
|
||||||
|
self.left.as_any().downcast_ref::<FloatBox>(),
|
||||||
|
self.right.as_any().downcast_ref::<FloatBox>()
|
||||||
|
) {
|
||||||
|
let result = left_float.value + right_float.value;
|
||||||
|
return Box::new(FloatBox::new(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Integer + Float
|
||||||
|
if let (Some(left_int), Some(right_float)) = (
|
||||||
|
self.left.as_any().downcast_ref::<IntegerBox>(),
|
||||||
|
self.right.as_any().downcast_ref::<FloatBox>()
|
||||||
|
) {
|
||||||
|
let result = left_int.value as f64 + right_float.value;
|
||||||
|
return Box::new(FloatBox::new(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Float + Integer
|
||||||
|
if let (Some(left_float), Some(right_int)) = (
|
||||||
|
self.left.as_any().downcast_ref::<FloatBox>(),
|
||||||
|
self.right.as_any().downcast_ref::<IntegerBox>()
|
||||||
|
) {
|
||||||
|
let result = left_float.value + right_int.value as f64;
|
||||||
|
return Box::new(FloatBox::new(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. String concatenation (fallback for any types)
|
||||||
|
let left_str = self.left.to_string_box();
|
||||||
|
let right_str = self.right.to_string_box();
|
||||||
|
let result = format!("{}{}", left_str.value, right_str.value);
|
||||||
|
Box::new(StringBox::new(result))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for AddBox {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_struct("AddBox")
|
||||||
|
.field("left", &self.left.to_string_box().value)
|
||||||
|
.field("right", &self.right.to_string_box().value)
|
||||||
|
.field("id", &self.base.id)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NyashBox for AddBox {
|
||||||
|
fn to_string_box(&self) -> StringBox {
|
||||||
|
let result = self.execute();
|
||||||
|
result.to_string_box()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn equals(&self, other: &dyn NyashBox) -> bool {
|
||||||
|
if let Some(other_add) = other.as_any().downcast_ref::<AddBox>() {
|
||||||
|
self.left.equals(other_add.left.as_ref()) &&
|
||||||
|
self.right.equals(other_add.right.as_ref())
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn type_name(&self) -> &'static str {
|
||||||
|
"AddBox"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clone_box(&self) -> Box<dyn NyashBox> {
|
||||||
|
Box::new(AddBox::new(
|
||||||
|
self.left.clone_box(),
|
||||||
|
self.right.clone_box()
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BoxCore for AddBox {
|
||||||
|
fn box_id(&self) -> u64 {
|
||||||
|
self.base.id
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parent_type_id(&self) -> Option<std::any::TypeId> {
|
||||||
|
self.base.parent_type_id
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fmt_box(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
write!(f, "{}", self.to_string_box().value)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_any(&self) -> &dyn Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_any_mut(&mut self) -> &mut dyn Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for AddBox {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
self.fmt_box(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Subtraction operations between boxes
|
||||||
|
pub struct SubtractBox {
|
||||||
|
pub left: Box<dyn NyashBox>,
|
||||||
|
pub right: Box<dyn NyashBox>,
|
||||||
|
base: BoxBase,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SubtractBox {
|
||||||
|
pub fn new(left: Box<dyn NyashBox>, right: Box<dyn NyashBox>) -> Self {
|
||||||
|
Self {
|
||||||
|
left,
|
||||||
|
right,
|
||||||
|
base: BoxBase::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Execute the subtraction operation and return the result
|
||||||
|
pub fn execute(&self) -> Box<dyn NyashBox> {
|
||||||
|
// For now, only handle integer subtraction
|
||||||
|
if let (Some(left_int), Some(right_int)) = (
|
||||||
|
self.left.as_any().downcast_ref::<IntegerBox>(),
|
||||||
|
self.right.as_any().downcast_ref::<IntegerBox>()
|
||||||
|
) {
|
||||||
|
let result = left_int.value - right_int.value;
|
||||||
|
Box::new(IntegerBox::new(result))
|
||||||
|
} else {
|
||||||
|
// Convert to integers and subtract
|
||||||
|
let left_int = self.left.to_integer_box();
|
||||||
|
let right_int = self.right.to_integer_box();
|
||||||
|
let result = left_int.value - right_int.value;
|
||||||
|
Box::new(IntegerBox::new(result))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for SubtractBox {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_struct("SubtractBox")
|
||||||
|
.field("left", &self.left.to_string_box().value)
|
||||||
|
.field("right", &self.right.to_string_box().value)
|
||||||
|
.field("id", &self.base.id)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NyashBox for SubtractBox {
|
||||||
|
fn to_string_box(&self) -> StringBox {
|
||||||
|
let result = self.execute();
|
||||||
|
result.to_string_box()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn equals(&self, other: &dyn NyashBox) -> bool {
|
||||||
|
if let Some(other_sub) = other.as_any().downcast_ref::<SubtractBox>() {
|
||||||
|
self.left.equals(other_sub.left.as_ref()) &&
|
||||||
|
self.right.equals(other_sub.right.as_ref())
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn type_name(&self) -> &'static str { "SubtractBox" }
|
||||||
|
fn clone_box(&self) -> Box<dyn NyashBox> {
|
||||||
|
Box::new(SubtractBox::new(self.left.clone_box(), self.right.clone_box()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BoxCore for SubtractBox {
|
||||||
|
fn box_id(&self) -> u64 { self.base.id }
|
||||||
|
fn parent_type_id(&self) -> Option<std::any::TypeId> { self.base.parent_type_id }
|
||||||
|
fn fmt_box(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
write!(f, "{}", self.to_string_box().value)
|
||||||
|
}
|
||||||
|
fn as_any(&self) -> &dyn Any { self }
|
||||||
|
fn as_any_mut(&mut self) -> &mut dyn Any { self }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for SubtractBox {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
self.fmt_box(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Multiplication operations between boxes
|
||||||
|
pub struct MultiplyBox {
|
||||||
|
pub left: Box<dyn NyashBox>,
|
||||||
|
pub right: Box<dyn NyashBox>,
|
||||||
|
base: BoxBase,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MultiplyBox {
|
||||||
|
pub fn new(left: Box<dyn NyashBox>, right: Box<dyn NyashBox>) -> Self {
|
||||||
|
Self {
|
||||||
|
left,
|
||||||
|
right,
|
||||||
|
base: BoxBase::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Execute the multiplication operation and return the result
|
||||||
|
pub fn execute(&self) -> Box<dyn NyashBox> {
|
||||||
|
// For now, only handle integer multiplication
|
||||||
|
if let (Some(left_int), Some(right_int)) = (
|
||||||
|
self.left.as_any().downcast_ref::<IntegerBox>(),
|
||||||
|
self.right.as_any().downcast_ref::<IntegerBox>()
|
||||||
|
) {
|
||||||
|
let result = left_int.value * right_int.value;
|
||||||
|
Box::new(IntegerBox::new(result))
|
||||||
|
} else {
|
||||||
|
// Convert to integers and multiply
|
||||||
|
let left_int = self.left.to_integer_box();
|
||||||
|
let right_int = self.right.to_integer_box();
|
||||||
|
let result = left_int.value * right_int.value;
|
||||||
|
Box::new(IntegerBox::new(result))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for MultiplyBox {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_struct("MultiplyBox")
|
||||||
|
.field("left", &self.left.to_string_box().value)
|
||||||
|
.field("right", &self.right.to_string_box().value)
|
||||||
|
.field("id", &self.base.id)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NyashBox for MultiplyBox {
|
||||||
|
fn to_string_box(&self) -> StringBox {
|
||||||
|
let result = self.execute();
|
||||||
|
result.to_string_box()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn equals(&self, other: &dyn NyashBox) -> bool {
|
||||||
|
if let Some(other_mul) = other.as_any().downcast_ref::<MultiplyBox>() {
|
||||||
|
self.left.equals(other_mul.left.as_ref()) &&
|
||||||
|
self.right.equals(other_mul.right.as_ref())
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn type_name(&self) -> &'static str { "MultiplyBox" }
|
||||||
|
fn clone_box(&self) -> Box<dyn NyashBox> {
|
||||||
|
Box::new(MultiplyBox::new(self.left.clone_box(), self.right.clone_box()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BoxCore for MultiplyBox {
|
||||||
|
fn box_id(&self) -> u64 { self.base.id }
|
||||||
|
fn parent_type_id(&self) -> Option<std::any::TypeId> { self.base.parent_type_id }
|
||||||
|
fn fmt_box(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
write!(f, "{}", self.to_string_box().value)
|
||||||
|
}
|
||||||
|
fn as_any(&self) -> &dyn Any { self }
|
||||||
|
fn as_any_mut(&mut self) -> &mut dyn Any { self }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for MultiplyBox {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
self.fmt_box(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Division operations between boxes
|
||||||
|
pub struct DivideBox {
|
||||||
|
pub left: Box<dyn NyashBox>,
|
||||||
|
pub right: Box<dyn NyashBox>,
|
||||||
|
base: BoxBase,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DivideBox {
|
||||||
|
pub fn new(left: Box<dyn NyashBox>, right: Box<dyn NyashBox>) -> Self {
|
||||||
|
Self {
|
||||||
|
left,
|
||||||
|
right,
|
||||||
|
base: BoxBase::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Execute the division operation and return the result
|
||||||
|
pub fn execute(&self) -> Box<dyn NyashBox> {
|
||||||
|
use crate::boxes::math_box::FloatBox;
|
||||||
|
|
||||||
|
// Handle integer division, but return float result
|
||||||
|
if let (Some(left_int), Some(right_int)) = (
|
||||||
|
self.left.as_any().downcast_ref::<IntegerBox>(),
|
||||||
|
self.right.as_any().downcast_ref::<IntegerBox>()
|
||||||
|
) {
|
||||||
|
if right_int.value == 0 {
|
||||||
|
// Return error for division by zero
|
||||||
|
return Box::new(StringBox::new("Error: Division by zero".to_string()));
|
||||||
|
}
|
||||||
|
let result = left_int.value as f64 / right_int.value as f64;
|
||||||
|
Box::new(FloatBox::new(result))
|
||||||
|
} else {
|
||||||
|
// Convert to integers and divide
|
||||||
|
let left_int = self.left.to_integer_box();
|
||||||
|
let right_int = self.right.to_integer_box();
|
||||||
|
if right_int.value == 0 {
|
||||||
|
return Box::new(StringBox::new("Error: Division by zero".to_string()));
|
||||||
|
}
|
||||||
|
let result = left_int.value as f64 / right_int.value as f64;
|
||||||
|
Box::new(FloatBox::new(result))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for DivideBox {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_struct("DivideBox")
|
||||||
|
.field("left", &self.left.to_string_box().value)
|
||||||
|
.field("right", &self.right.to_string_box().value)
|
||||||
|
.field("id", &self.base.id)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NyashBox for DivideBox {
|
||||||
|
fn to_string_box(&self) -> StringBox {
|
||||||
|
let result = self.execute();
|
||||||
|
result.to_string_box()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn equals(&self, other: &dyn NyashBox) -> bool {
|
||||||
|
if let Some(other_div) = other.as_any().downcast_ref::<DivideBox>() {
|
||||||
|
self.left.equals(other_div.left.as_ref()) &&
|
||||||
|
self.right.equals(other_div.right.as_ref())
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn type_name(&self) -> &'static str { "DivideBox" }
|
||||||
|
fn clone_box(&self) -> Box<dyn NyashBox> {
|
||||||
|
Box::new(DivideBox::new(self.left.clone_box(), self.right.clone_box()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BoxCore for DivideBox {
|
||||||
|
fn box_id(&self) -> u64 { self.base.id }
|
||||||
|
fn parent_type_id(&self) -> Option<std::any::TypeId> { self.base.parent_type_id }
|
||||||
|
fn fmt_box(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
write!(f, "{}", self.to_string_box().value)
|
||||||
|
}
|
||||||
|
fn as_any(&self) -> &dyn Any { self }
|
||||||
|
fn as_any_mut(&mut self) -> &mut dyn Any { self }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for DivideBox {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
self.fmt_box(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Comparison operations between boxes
|
||||||
|
pub struct CompareBox;
|
||||||
|
|
||||||
|
impl CompareBox {
|
||||||
|
/// Compare two boxes for equality
|
||||||
|
pub fn equals(left: &dyn NyashBox, right: &dyn NyashBox) -> BoolBox {
|
||||||
|
BoolBox::new(left.equals(right))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Compare two boxes for less than
|
||||||
|
pub fn less_than(left: &dyn NyashBox, right: &dyn NyashBox) -> BoolBox {
|
||||||
|
// Try integer comparison first
|
||||||
|
if let (Some(left_int), Some(right_int)) = (
|
||||||
|
left.as_any().downcast_ref::<IntegerBox>(),
|
||||||
|
right.as_any().downcast_ref::<IntegerBox>()
|
||||||
|
) {
|
||||||
|
return BoolBox::new(left_int.value < right_int.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fall back to string comparison
|
||||||
|
let left_str = left.to_string_box();
|
||||||
|
let right_str = right.to_string_box();
|
||||||
|
BoolBox::new(left_str.value < right_str.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Compare two boxes for greater than
|
||||||
|
pub fn greater_than(left: &dyn NyashBox, right: &dyn NyashBox) -> BoolBox {
|
||||||
|
// Try integer comparison first
|
||||||
|
if let (Some(left_int), Some(right_int)) = (
|
||||||
|
left.as_any().downcast_ref::<IntegerBox>(),
|
||||||
|
right.as_any().downcast_ref::<IntegerBox>()
|
||||||
|
) {
|
||||||
|
return BoolBox::new(left_int.value > right_int.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fall back to string comparison
|
||||||
|
let left_str = left.to_string_box();
|
||||||
|
let right_str = right.to_string_box();
|
||||||
|
BoolBox::new(left_str.value > right_str.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Compare two boxes for less than or equal
|
||||||
|
pub fn less_equal(left: &dyn NyashBox, right: &dyn NyashBox) -> BoolBox {
|
||||||
|
// Try integer comparison first
|
||||||
|
if let (Some(left_int), Some(right_int)) = (
|
||||||
|
left.as_any().downcast_ref::<IntegerBox>(),
|
||||||
|
right.as_any().downcast_ref::<IntegerBox>()
|
||||||
|
) {
|
||||||
|
return BoolBox::new(left_int.value <= right_int.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fall back to string comparison
|
||||||
|
let left_str = left.to_string_box();
|
||||||
|
let right_str = right.to_string_box();
|
||||||
|
BoolBox::new(left_str.value <= right_str.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Compare two boxes for greater than or equal
|
||||||
|
pub fn greater_equal(left: &dyn NyashBox, right: &dyn NyashBox) -> BoolBox {
|
||||||
|
// Try integer comparison first
|
||||||
|
if let (Some(left_int), Some(right_int)) = (
|
||||||
|
left.as_any().downcast_ref::<IntegerBox>(),
|
||||||
|
right.as_any().downcast_ref::<IntegerBox>()
|
||||||
|
) {
|
||||||
|
return BoolBox::new(left_int.value >= right_int.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fall back to string comparison
|
||||||
|
let left_str = left.to_string_box();
|
||||||
|
let right_str = right.to_string_box();
|
||||||
|
BoolBox::new(left_str.value >= right_str.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_add_box_integers() {
|
||||||
|
let left = Box::new(IntegerBox::new(10)) as Box<dyn NyashBox>;
|
||||||
|
let right = Box::new(IntegerBox::new(32)) as Box<dyn NyashBox>;
|
||||||
|
let add_box = AddBox::new(left, right);
|
||||||
|
let result = add_box.execute();
|
||||||
|
|
||||||
|
assert_eq!(result.to_string_box().value, "42");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_add_box_strings() {
|
||||||
|
let left = Box::new(StringBox::new("Hello, ".to_string())) as Box<dyn NyashBox>;
|
||||||
|
let right = Box::new(StringBox::new("World!".to_string())) as Box<dyn NyashBox>;
|
||||||
|
let add_box = AddBox::new(left, right);
|
||||||
|
let result = add_box.execute();
|
||||||
|
|
||||||
|
assert_eq!(result.to_string_box().value, "Hello, World!");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_subtract_box() {
|
||||||
|
let left = Box::new(IntegerBox::new(50)) as Box<dyn NyashBox>;
|
||||||
|
let right = Box::new(IntegerBox::new(8)) as Box<dyn NyashBox>;
|
||||||
|
let sub_box = SubtractBox::new(left, right);
|
||||||
|
let result = sub_box.execute();
|
||||||
|
|
||||||
|
assert_eq!(result.to_string_box().value, "42");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_multiply_box() {
|
||||||
|
let left = Box::new(IntegerBox::new(6)) as Box<dyn NyashBox>;
|
||||||
|
let right = Box::new(IntegerBox::new(7)) as Box<dyn NyashBox>;
|
||||||
|
let mul_box = MultiplyBox::new(left, right);
|
||||||
|
let result = mul_box.execute();
|
||||||
|
|
||||||
|
assert_eq!(result.to_string_box().value, "42");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_divide_box() {
|
||||||
|
let left = Box::new(IntegerBox::new(84)) as Box<dyn NyashBox>;
|
||||||
|
let right = Box::new(IntegerBox::new(2)) as Box<dyn NyashBox>;
|
||||||
|
let div_box = DivideBox::new(left, right);
|
||||||
|
let result = div_box.execute();
|
||||||
|
|
||||||
|
// Division returns float
|
||||||
|
assert_eq!(result.to_string_box().value, "42");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_divide_by_zero() {
|
||||||
|
let left = Box::new(IntegerBox::new(42)) as Box<dyn NyashBox>;
|
||||||
|
let right = Box::new(IntegerBox::new(0)) as Box<dyn NyashBox>;
|
||||||
|
let div_box = DivideBox::new(left, right);
|
||||||
|
let result = div_box.execute();
|
||||||
|
|
||||||
|
assert!(result.to_string_box().value.contains("Division by zero"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_compare_box() {
|
||||||
|
let left = IntegerBox::new(10);
|
||||||
|
let right = IntegerBox::new(20);
|
||||||
|
|
||||||
|
assert_eq!(CompareBox::less_than(&left, &right).value, true);
|
||||||
|
assert_eq!(CompareBox::greater_than(&left, &right).value, false);
|
||||||
|
assert_eq!(CompareBox::equals(&left, &right).value, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
459
src/box_trait.rs
459
src/box_trait.rs
@ -921,463 +921,8 @@ impl Display for FutureBox {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===== Box Operations =====
|
// Re-export operation boxes from the dedicated operations module
|
||||||
|
pub use crate::box_arithmetic::{AddBox, SubtractBox, MultiplyBox, DivideBox, CompareBox};
|
||||||
/// Binary operations between boxes (addition, concatenation, etc.)
|
|
||||||
pub struct AddBox {
|
|
||||||
pub left: Box<dyn NyashBox>,
|
|
||||||
pub right: Box<dyn NyashBox>,
|
|
||||||
base: BoxBase,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AddBox {
|
|
||||||
pub fn new(left: Box<dyn NyashBox>, right: Box<dyn NyashBox>) -> Self {
|
|
||||||
Self {
|
|
||||||
left,
|
|
||||||
right,
|
|
||||||
base: BoxBase::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Execute the addition operation and return the result
|
|
||||||
pub fn execute(&self) -> Box<dyn NyashBox> {
|
|
||||||
use crate::boxes::math_box::FloatBox;
|
|
||||||
|
|
||||||
// 1. Integer + Integer
|
|
||||||
if let (Some(left_int), Some(right_int)) = (
|
|
||||||
self.left.as_any().downcast_ref::<IntegerBox>(),
|
|
||||||
self.right.as_any().downcast_ref::<IntegerBox>()
|
|
||||||
) {
|
|
||||||
return Box::new(IntegerBox::new(left_int.value + right_int.value));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. Float + Float
|
|
||||||
if let (Some(left_float), Some(right_float)) = (
|
|
||||||
self.left.as_any().downcast_ref::<FloatBox>(),
|
|
||||||
self.right.as_any().downcast_ref::<FloatBox>()
|
|
||||||
) {
|
|
||||||
return Box::new(FloatBox::new(left_float.value + right_float.value));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. Integer + Float -> Float
|
|
||||||
if let (Some(left_int), Some(right_float)) = (
|
|
||||||
self.left.as_any().downcast_ref::<IntegerBox>(),
|
|
||||||
self.right.as_any().downcast_ref::<FloatBox>()
|
|
||||||
) {
|
|
||||||
return Box::new(FloatBox::new(left_int.value as f64 + right_float.value));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. Float + Integer -> Float
|
|
||||||
if let (Some(left_float), Some(right_int)) = (
|
|
||||||
self.left.as_any().downcast_ref::<FloatBox>(),
|
|
||||||
self.right.as_any().downcast_ref::<IntegerBox>()
|
|
||||||
) {
|
|
||||||
return Box::new(FloatBox::new(left_float.value + right_int.value as f64));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 5. Fall back to string concatenation
|
|
||||||
let left_str = self.left.to_string_box();
|
|
||||||
let right_str = self.right.to_string_box();
|
|
||||||
Box::new(StringBox::new(format!("{}{}", left_str.value, right_str.value)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Debug for AddBox {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
f.debug_struct("AddBox")
|
|
||||||
.field("left", &self.left.to_string_box().value)
|
|
||||||
.field("right", &self.right.to_string_box().value)
|
|
||||||
.field("id", &self.base.id)
|
|
||||||
.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl NyashBox for AddBox {
|
|
||||||
fn to_string_box(&self) -> StringBox {
|
|
||||||
let result = self.execute();
|
|
||||||
result.to_string_box()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn equals(&self, other: &dyn NyashBox) -> BoolBox {
|
|
||||||
if let Some(other_add) = other.as_any().downcast_ref::<AddBox>() {
|
|
||||||
let left_eq = self.left.equals(other_add.left.as_ref());
|
|
||||||
let right_eq = self.right.equals(other_add.right.as_ref());
|
|
||||||
BoolBox::new(left_eq.value && right_eq.value)
|
|
||||||
} else {
|
|
||||||
BoolBox::new(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn type_name(&self) -> &'static str {
|
|
||||||
"AddBox"
|
|
||||||
}
|
|
||||||
|
|
||||||
fn clone_box(&self) -> Box<dyn NyashBox> {
|
|
||||||
Box::new(AddBox::new(
|
|
||||||
self.left.clone_box(),
|
|
||||||
self.right.clone_box()
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BoxCore for AddBox {
|
|
||||||
fn box_id(&self) -> u64 {
|
|
||||||
self.base.id
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parent_type_id(&self) -> Option<std::any::TypeId> {
|
|
||||||
self.base.parent_type_id
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fmt_box(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
|
||||||
write!(f, "({} + {})", self.left.to_string_box().value, self.right.to_string_box().value)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_any(&self) -> &dyn Any {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_any_mut(&mut self) -> &mut dyn Any {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for AddBox {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
self.fmt_box(f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===== 数値演算Boxの実装 =====
|
|
||||||
|
|
||||||
/// 減算を行うBox
|
|
||||||
pub struct SubtractBox {
|
|
||||||
left: Box<dyn NyashBox>,
|
|
||||||
right: Box<dyn NyashBox>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SubtractBox {
|
|
||||||
pub fn new(left: Box<dyn NyashBox>, right: Box<dyn NyashBox>) -> Self {
|
|
||||||
Self { left, right }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn execute(&self) -> Box<dyn NyashBox> {
|
|
||||||
use crate::boxes::math_box::FloatBox;
|
|
||||||
|
|
||||||
// 1. Integer - Integer
|
|
||||||
if let (Some(left_int), Some(right_int)) = (
|
|
||||||
self.left.as_any().downcast_ref::<IntegerBox>(),
|
|
||||||
self.right.as_any().downcast_ref::<IntegerBox>()
|
|
||||||
) {
|
|
||||||
return Box::new(IntegerBox::new(left_int.value - right_int.value));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. Float - Float
|
|
||||||
if let (Some(left_float), Some(right_float)) = (
|
|
||||||
self.left.as_any().downcast_ref::<FloatBox>(),
|
|
||||||
self.right.as_any().downcast_ref::<FloatBox>()
|
|
||||||
) {
|
|
||||||
return Box::new(FloatBox::new(left_float.value - right_float.value));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. Integer - Float -> Float
|
|
||||||
if let (Some(left_int), Some(right_float)) = (
|
|
||||||
self.left.as_any().downcast_ref::<IntegerBox>(),
|
|
||||||
self.right.as_any().downcast_ref::<FloatBox>()
|
|
||||||
) {
|
|
||||||
return Box::new(FloatBox::new(left_int.value as f64 - right_float.value));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. Float - Integer -> Float
|
|
||||||
if let (Some(left_float), Some(right_int)) = (
|
|
||||||
self.left.as_any().downcast_ref::<FloatBox>(),
|
|
||||||
self.right.as_any().downcast_ref::<IntegerBox>()
|
|
||||||
) {
|
|
||||||
return Box::new(FloatBox::new(left_float.value - right_int.value as f64));
|
|
||||||
}
|
|
||||||
|
|
||||||
// エラーの場合はvoid返す
|
|
||||||
Box::new(VoidBox::new())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 乗算を行うBox
|
|
||||||
pub struct MultiplyBox {
|
|
||||||
left: Box<dyn NyashBox>,
|
|
||||||
right: Box<dyn NyashBox>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MultiplyBox {
|
|
||||||
pub fn new(left: Box<dyn NyashBox>, right: Box<dyn NyashBox>) -> Self {
|
|
||||||
Self { left, right }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn execute(&self) -> Box<dyn NyashBox> {
|
|
||||||
use crate::boxes::math_box::FloatBox;
|
|
||||||
|
|
||||||
// 1. Integer * Integer
|
|
||||||
if let (Some(left_int), Some(right_int)) = (
|
|
||||||
self.left.as_any().downcast_ref::<IntegerBox>(),
|
|
||||||
self.right.as_any().downcast_ref::<IntegerBox>()
|
|
||||||
) {
|
|
||||||
return Box::new(IntegerBox::new(left_int.value * right_int.value));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. Float * Float
|
|
||||||
if let (Some(left_float), Some(right_float)) = (
|
|
||||||
self.left.as_any().downcast_ref::<FloatBox>(),
|
|
||||||
self.right.as_any().downcast_ref::<FloatBox>()
|
|
||||||
) {
|
|
||||||
return Box::new(FloatBox::new(left_float.value * right_float.value));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. Integer * Float -> Float
|
|
||||||
if let (Some(left_int), Some(right_float)) = (
|
|
||||||
self.left.as_any().downcast_ref::<IntegerBox>(),
|
|
||||||
self.right.as_any().downcast_ref::<FloatBox>()
|
|
||||||
) {
|
|
||||||
return Box::new(FloatBox::new(left_int.value as f64 * right_float.value));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. Float * Integer -> Float
|
|
||||||
if let (Some(left_float), Some(right_int)) = (
|
|
||||||
self.left.as_any().downcast_ref::<FloatBox>(),
|
|
||||||
self.right.as_any().downcast_ref::<IntegerBox>()
|
|
||||||
) {
|
|
||||||
return Box::new(FloatBox::new(left_float.value * right_int.value as f64));
|
|
||||||
}
|
|
||||||
|
|
||||||
// エラーの場合はvoid返す
|
|
||||||
Box::new(VoidBox::new())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 除算を行うBox
|
|
||||||
pub struct DivideBox {
|
|
||||||
left: Box<dyn NyashBox>,
|
|
||||||
right: Box<dyn NyashBox>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DivideBox {
|
|
||||||
pub fn new(left: Box<dyn NyashBox>, right: Box<dyn NyashBox>) -> Self {
|
|
||||||
Self { left, right }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn execute(&self) -> Box<dyn NyashBox> {
|
|
||||||
use crate::boxes::math_box::FloatBox;
|
|
||||||
|
|
||||||
// 1. Integer / Integer -> Float (常に浮動小数点で返す)
|
|
||||||
if let (Some(left_int), Some(right_int)) = (
|
|
||||||
self.left.as_any().downcast_ref::<IntegerBox>(),
|
|
||||||
self.right.as_any().downcast_ref::<IntegerBox>()
|
|
||||||
) {
|
|
||||||
if right_int.value == 0 {
|
|
||||||
// ゼロ除算エラー
|
|
||||||
return Box::new(StringBox::new("Error: Division by zero".to_string()));
|
|
||||||
}
|
|
||||||
return Box::new(FloatBox::new(left_int.value as f64 / right_int.value as f64));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. Float / Float
|
|
||||||
if let (Some(left_float), Some(right_float)) = (
|
|
||||||
self.left.as_any().downcast_ref::<FloatBox>(),
|
|
||||||
self.right.as_any().downcast_ref::<FloatBox>()
|
|
||||||
) {
|
|
||||||
if right_float.value == 0.0 {
|
|
||||||
// ゼロ除算エラー
|
|
||||||
return Box::new(StringBox::new("Error: Division by zero".to_string()));
|
|
||||||
}
|
|
||||||
return Box::new(FloatBox::new(left_float.value / right_float.value));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. Integer / Float -> Float
|
|
||||||
if let (Some(left_int), Some(right_float)) = (
|
|
||||||
self.left.as_any().downcast_ref::<IntegerBox>(),
|
|
||||||
self.right.as_any().downcast_ref::<FloatBox>()
|
|
||||||
) {
|
|
||||||
if right_float.value == 0.0 {
|
|
||||||
// ゼロ除算エラー
|
|
||||||
return Box::new(StringBox::new("Error: Division by zero".to_string()));
|
|
||||||
}
|
|
||||||
return Box::new(FloatBox::new(left_int.value as f64 / right_float.value));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. Float / Integer -> Float
|
|
||||||
if let (Some(left_float), Some(right_int)) = (
|
|
||||||
self.left.as_any().downcast_ref::<FloatBox>(),
|
|
||||||
self.right.as_any().downcast_ref::<IntegerBox>()
|
|
||||||
) {
|
|
||||||
if right_int.value == 0 {
|
|
||||||
// ゼロ除算エラー
|
|
||||||
return Box::new(StringBox::new("Error: Division by zero".to_string()));
|
|
||||||
}
|
|
||||||
return Box::new(FloatBox::new(left_float.value / right_int.value as f64));
|
|
||||||
}
|
|
||||||
|
|
||||||
// エラーの場合はvoid返す
|
|
||||||
Box::new(VoidBox::new())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 比較演算用のヘルパー
|
|
||||||
pub struct CompareBox;
|
|
||||||
|
|
||||||
impl CompareBox {
|
|
||||||
pub fn less(left: &dyn NyashBox, right: &dyn NyashBox) -> BoolBox {
|
|
||||||
use crate::boxes::FloatBox;
|
|
||||||
|
|
||||||
// Integer < Integer
|
|
||||||
if let (Some(left_int), Some(right_int)) = (
|
|
||||||
left.as_any().downcast_ref::<IntegerBox>(),
|
|
||||||
right.as_any().downcast_ref::<IntegerBox>()
|
|
||||||
) {
|
|
||||||
return BoolBox::new(left_int.value < right_int.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float < Float
|
|
||||||
if let (Some(left_float), Some(right_float)) = (
|
|
||||||
left.as_any().downcast_ref::<FloatBox>(),
|
|
||||||
right.as_any().downcast_ref::<FloatBox>()
|
|
||||||
) {
|
|
||||||
return BoolBox::new(left_float.value < right_float.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Integer < Float
|
|
||||||
if let (Some(left_int), Some(right_float)) = (
|
|
||||||
left.as_any().downcast_ref::<IntegerBox>(),
|
|
||||||
right.as_any().downcast_ref::<FloatBox>()
|
|
||||||
) {
|
|
||||||
return BoolBox::new((left_int.value as f64) < right_float.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float < Integer
|
|
||||||
if let (Some(left_float), Some(right_int)) = (
|
|
||||||
left.as_any().downcast_ref::<FloatBox>(),
|
|
||||||
right.as_any().downcast_ref::<IntegerBox>()
|
|
||||||
) {
|
|
||||||
return BoolBox::new(left_float.value < (right_int.value as f64));
|
|
||||||
}
|
|
||||||
|
|
||||||
BoolBox::new(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn greater(left: &dyn NyashBox, right: &dyn NyashBox) -> BoolBox {
|
|
||||||
use crate::boxes::FloatBox;
|
|
||||||
|
|
||||||
// Integer > Integer
|
|
||||||
if let (Some(left_int), Some(right_int)) = (
|
|
||||||
left.as_any().downcast_ref::<IntegerBox>(),
|
|
||||||
right.as_any().downcast_ref::<IntegerBox>()
|
|
||||||
) {
|
|
||||||
return BoolBox::new(left_int.value > right_int.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float > Float
|
|
||||||
if let (Some(left_float), Some(right_float)) = (
|
|
||||||
left.as_any().downcast_ref::<FloatBox>(),
|
|
||||||
right.as_any().downcast_ref::<FloatBox>()
|
|
||||||
) {
|
|
||||||
return BoolBox::new(left_float.value > right_float.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Integer > Float
|
|
||||||
if let (Some(left_int), Some(right_float)) = (
|
|
||||||
left.as_any().downcast_ref::<IntegerBox>(),
|
|
||||||
right.as_any().downcast_ref::<FloatBox>()
|
|
||||||
) {
|
|
||||||
return BoolBox::new((left_int.value as f64) > right_float.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float > Integer
|
|
||||||
if let (Some(left_float), Some(right_int)) = (
|
|
||||||
left.as_any().downcast_ref::<FloatBox>(),
|
|
||||||
right.as_any().downcast_ref::<IntegerBox>()
|
|
||||||
) {
|
|
||||||
return BoolBox::new(left_float.value > (right_int.value as f64));
|
|
||||||
}
|
|
||||||
|
|
||||||
BoolBox::new(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn less_equal(left: &dyn NyashBox, right: &dyn NyashBox) -> BoolBox {
|
|
||||||
use crate::boxes::FloatBox;
|
|
||||||
|
|
||||||
// Integer <= Integer
|
|
||||||
if let (Some(left_int), Some(right_int)) = (
|
|
||||||
left.as_any().downcast_ref::<IntegerBox>(),
|
|
||||||
right.as_any().downcast_ref::<IntegerBox>()
|
|
||||||
) {
|
|
||||||
return BoolBox::new(left_int.value <= right_int.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float <= Float
|
|
||||||
if let (Some(left_float), Some(right_float)) = (
|
|
||||||
left.as_any().downcast_ref::<FloatBox>(),
|
|
||||||
right.as_any().downcast_ref::<FloatBox>()
|
|
||||||
) {
|
|
||||||
return BoolBox::new(left_float.value <= right_float.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Integer <= Float
|
|
||||||
if let (Some(left_int), Some(right_float)) = (
|
|
||||||
left.as_any().downcast_ref::<IntegerBox>(),
|
|
||||||
right.as_any().downcast_ref::<FloatBox>()
|
|
||||||
) {
|
|
||||||
return BoolBox::new((left_int.value as f64) <= right_float.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float <= Integer
|
|
||||||
if let (Some(left_float), Some(right_int)) = (
|
|
||||||
left.as_any().downcast_ref::<FloatBox>(),
|
|
||||||
right.as_any().downcast_ref::<IntegerBox>()
|
|
||||||
) {
|
|
||||||
return BoolBox::new(left_float.value <= (right_int.value as f64));
|
|
||||||
}
|
|
||||||
|
|
||||||
BoolBox::new(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn greater_equal(left: &dyn NyashBox, right: &dyn NyashBox) -> BoolBox {
|
|
||||||
use crate::boxes::FloatBox;
|
|
||||||
|
|
||||||
// Integer >= Integer
|
|
||||||
if let (Some(left_int), Some(right_int)) = (
|
|
||||||
left.as_any().downcast_ref::<IntegerBox>(),
|
|
||||||
right.as_any().downcast_ref::<IntegerBox>()
|
|
||||||
) {
|
|
||||||
return BoolBox::new(left_int.value >= right_int.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float >= Float
|
|
||||||
if let (Some(left_float), Some(right_float)) = (
|
|
||||||
left.as_any().downcast_ref::<FloatBox>(),
|
|
||||||
right.as_any().downcast_ref::<FloatBox>()
|
|
||||||
) {
|
|
||||||
return BoolBox::new(left_float.value >= right_float.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Integer >= Float
|
|
||||||
if let (Some(left_int), Some(right_float)) = (
|
|
||||||
left.as_any().downcast_ref::<IntegerBox>(),
|
|
||||||
right.as_any().downcast_ref::<FloatBox>()
|
|
||||||
) {
|
|
||||||
return BoolBox::new((left_int.value as f64) >= right_float.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float >= Integer
|
|
||||||
if let (Some(left_float), Some(right_int)) = (
|
|
||||||
left.as_any().downcast_ref::<FloatBox>(),
|
|
||||||
right.as_any().downcast_ref::<IntegerBox>()
|
|
||||||
) {
|
|
||||||
return BoolBox::new(left_float.value >= (right_int.value as f64));
|
|
||||||
}
|
|
||||||
|
|
||||||
BoolBox::new(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===== Tests =====
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|||||||
1455
src/box_trait.rs.backup
Normal file
1455
src/box_trait.rs.backup
Normal file
File diff suppressed because it is too large
Load Diff
89
src/boxes/traits.rs
Normal file
89
src/boxes/traits.rs
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
/*!
|
||||||
|
* Core Box Traits - Essential trait definitions for "Everything is Box"
|
||||||
|
*
|
||||||
|
* This module contains the core trait definitions and base structures
|
||||||
|
* that all Box types must implement.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use std::fmt::{Debug, Display};
|
||||||
|
use std::any::Any;
|
||||||
|
use std::sync::atomic::{AtomicU64, Ordering};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
/// 🔥 新しい型エイリアス - 将来的にBox<dyn NyashBox>を全て置き換える
|
||||||
|
pub type SharedNyashBox = Arc<dyn NyashBox>;
|
||||||
|
|
||||||
|
/// 🔥 BoxBase + BoxCore革命 - 統一ID生成システム
|
||||||
|
/// CharmFlow教訓を活かした互換性保証の基盤
|
||||||
|
pub fn next_box_id() -> u64 {
|
||||||
|
static COUNTER: AtomicU64 = AtomicU64::new(1);
|
||||||
|
COUNTER.fetch_add(1, Ordering::Relaxed)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 🏗️ BoxBase - 全てのBox型の共通基盤構造体
|
||||||
|
/// Phase 2: 統一的な基盤データを提供
|
||||||
|
/// 🔥 Phase 1: ビルトインBox継承システム - 最小限拡張
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
pub struct BoxBase {
|
||||||
|
pub id: u64,
|
||||||
|
pub parent_type_id: Option<std::any::TypeId>, // ビルトインBox継承用
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BoxBase {
|
||||||
|
/// 新しいBoxBase作成 - 安全なID生成
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
id: next_box_id(),
|
||||||
|
parent_type_id: None, // ビルトインBox: 継承なし
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ビルトインBox継承用コンストラクタ
|
||||||
|
pub fn with_parent_type(parent_type_id: std::any::TypeId) -> Self {
|
||||||
|
Self {
|
||||||
|
id: next_box_id(),
|
||||||
|
parent_type_id: Some(parent_type_id),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 🚀 BoxCore - 全てのBoxが持つ基盤的な操作
|
||||||
|
/// これはフォーマット、型特定、Anyキャストなど基本的な機能
|
||||||
|
pub trait BoxCore: Send + Sync {
|
||||||
|
/// Boxの一意ID取得
|
||||||
|
fn box_id(&self) -> u64;
|
||||||
|
|
||||||
|
/// 継承元の型ID取得 (ビルトインBox継承)
|
||||||
|
fn parent_type_id(&self) -> Option<std::any::TypeId>;
|
||||||
|
|
||||||
|
/// フォーマッター用実装 - 内部でto_string_box().valueを使う
|
||||||
|
fn fmt_box(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result;
|
||||||
|
|
||||||
|
/// Any型へのキャスト (ダウンキャスト用)
|
||||||
|
fn as_any(&self) -> &dyn Any;
|
||||||
|
|
||||||
|
/// Mutable Any型へのキャスト
|
||||||
|
fn as_any_mut(&mut self) -> &mut dyn Any;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 🌟 NyashBox - Nyashの全ての値が実装すべき主要trait
|
||||||
|
/// BoxCoreを継承し、さらにNyash固有の操作を追加
|
||||||
|
pub trait NyashBox: BoxCore + Debug {
|
||||||
|
/// StringBoxへの変換 (全ての値は文字列表現を持つ)
|
||||||
|
fn to_string_box(&self) -> super::string_box::StringBox;
|
||||||
|
|
||||||
|
/// IntegerBoxへの変換 (可能な場合)
|
||||||
|
fn to_integer_box(&self) -> super::integer_box::IntegerBox;
|
||||||
|
|
||||||
|
/// BoolBoxへの変換 (真偽値としての評価)
|
||||||
|
fn to_bool_box(&self) -> super::bool_box::BoolBox;
|
||||||
|
|
||||||
|
/// 等価性比較
|
||||||
|
fn equals(&self, other: &dyn NyashBox) -> bool;
|
||||||
|
|
||||||
|
/// 型名取得
|
||||||
|
fn type_name(&self) -> &'static str;
|
||||||
|
|
||||||
|
/// クローン操作 (Box内での値コピー)
|
||||||
|
fn clone_box(&self) -> Box<dyn NyashBox>;
|
||||||
|
}
|
||||||
@ -24,6 +24,7 @@ pub mod method_box;
|
|||||||
pub mod type_box; // 🌟 TypeBox revolutionary system
|
pub mod type_box; // 🌟 TypeBox revolutionary system
|
||||||
pub mod operator_traits; // 🚀 Rust-style trait-based operator overloading
|
pub mod operator_traits; // 🚀 Rust-style trait-based operator overloading
|
||||||
pub mod box_operators; // 🚀 Operator implementations for basic Box types
|
pub mod box_operators; // 🚀 Operator implementations for basic Box types
|
||||||
|
pub mod box_arithmetic; // 🚀 Arithmetic operations moved from box_trait.rs
|
||||||
|
|
||||||
// 🔥 NyashValue Revolutionary System (NEW!)
|
// 🔥 NyashValue Revolutionary System (NEW!)
|
||||||
pub mod value;
|
pub mod value;
|
||||||
@ -48,7 +49,8 @@ pub mod wasm_test;
|
|||||||
pub mod tests;
|
pub mod tests;
|
||||||
|
|
||||||
// Re-export main types for easy access
|
// Re-export main types for easy access
|
||||||
pub use box_trait::{NyashBox, StringBox, IntegerBox, BoolBox, VoidBox, AddBox};
|
pub use box_trait::{NyashBox, StringBox, IntegerBox, BoolBox, VoidBox};
|
||||||
|
pub use box_arithmetic::{AddBox, SubtractBox, MultiplyBox, DivideBox, CompareBox};
|
||||||
pub use environment::{Environment, PythonCompatEnvironment};
|
pub use environment::{Environment, PythonCompatEnvironment};
|
||||||
pub use tokenizer::{NyashTokenizer, TokenType, Token};
|
pub use tokenizer::{NyashTokenizer, TokenType, Token};
|
||||||
pub use type_box::{TypeBox, TypeRegistry, MethodSignature}; // 🌟 TypeBox exports
|
pub use type_box::{TypeBox, TypeRegistry, MethodSignature}; // 🌟 TypeBox exports
|
||||||
|
|||||||
@ -22,7 +22,7 @@ pub mod finalization;
|
|||||||
pub mod exception_box;
|
pub mod exception_box;
|
||||||
pub mod method_box;
|
pub mod method_box;
|
||||||
pub mod operator_traits;
|
pub mod operator_traits;
|
||||||
pub mod box_operators;
|
pub mod box_arithmetic; // 🚀 Moved from box_trait.rs for better organization
|
||||||
pub mod value; // 🔥 NyashValue Revolutionary System
|
pub mod value; // 🔥 NyashValue Revolutionary System
|
||||||
|
|
||||||
// 🚀 MIR Infrastructure
|
// 🚀 MIR Infrastructure
|
||||||
|
|||||||
Reference in New Issue
Block a user