| 134 | |
| 135 | #[inline] |
| 136 | pub fn equals(&self, other: &Value<'gc>) -> bool { |
| 137 | match (self, other) { |
| 138 | (Value::Number(a), Value::Number(b)) => a == b, |
| 139 | (Value::Boolean(a), Value::Boolean(b)) => a == b, |
| 140 | (Value::String(a), Value::String(b)) => a.equals(b), |
| 141 | (Value::IoString(a), Value::IoString(b)) => *a == *b, |
| 142 | (Value::String(a), Value::IoString(b)) => a.as_bytes() == b.as_bytes(), |
| 143 | (Value::IoString(a), Value::String(b)) => a.as_bytes() == b.as_bytes(), |
| 144 | (Value::List(a), Value::List(b)) => a.borrow().equals(&b.borrow()), |
| 145 | (Value::Object(a), Value::Object(b)) => Gc::ptr_eq(*a, *b), |
| 146 | (Value::Enum(a), Value::Enum(b)) => Gc::ptr_eq(*a, *b), |
| 147 | (Value::EnumVariant(a), Value::EnumVariant(b)) => { |
| 148 | // We only need to compare the enum type name and variant name, not the underlying value. |
| 149 | // The value is just for initialization and access, but doesn't affect the variant's identity. |
| 150 | Gc::ptr_eq(a.enum_, b.enum_) && a.name == b.name |
| 151 | } |
| 152 | (Value::Class(a), Value::Class(b)) => Gc::ptr_eq(*a, *b), |
| 153 | (Value::Closure(a), Value::Closure(b)) => Gc::ptr_eq(*a, *b), |
| 154 | (Value::Instance(a), Value::Instance(b)) => Gc::ptr_eq(*a, *b), |
| 155 | (Value::BoundMethod(a), Value::BoundMethod(b)) => Gc::ptr_eq(*a, *b), |
| 156 | (Value::Agent(a), Value::Agent(b)) => Gc::ptr_eq(*a, *b), |
| 157 | (Value::Nil, Value::Nil) => true, |
| 158 | // _ => core::mem::discriminant(self) == core::mem::discriminant(other), |
| 159 | _ => false, |
| 160 | } |
| 161 | } |
| 162 | |
| 163 | pub fn as_number(self) -> Result<f64, VmError> { |
| 164 | match self { |