diff --git a/vm/src/obj/objfloat.rs b/vm/src/obj/objfloat.rs index c03839f23..96ecffb6d 100644 --- a/vm/src/obj/objfloat.rs +++ b/vm/src/obj/objfloat.rs @@ -7,12 +7,12 @@ use super::objtype; fn str(vm: &mut VirtualMachine, args: PyFuncArgs) -> Result { arg_check!(vm, args, required = [(float, Some(vm.ctx.float_type()))]); - let v = get_value(float.clone()); + let v = get_value(float); Ok(vm.new_str(v.to_string())) } // Retrieve inner float value: -pub fn get_value(obj: PyObjectRef) -> f64 { +pub fn get_value(obj: &PyObjectRef) -> f64 { if let PyObjectKind::Float { value } = &obj.borrow().kind { *value } else { @@ -27,11 +27,11 @@ fn float_add(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { required = [(i, Some(vm.ctx.float_type())), (i2, None)] ); - let v1 = get_value(i.clone()); + let v1 = get_value(i); if objtype::isinstance(i2.clone(), vm.ctx.float_type()) { - Ok(vm.ctx.new_float(v1 + get_value(i2.clone()))) + Ok(vm.ctx.new_float(v1 + get_value(i2))) } else if objtype::isinstance(i2.clone(), vm.ctx.int_type()) { - Ok(vm.ctx.new_float(v1 + objint::get_value(i2.clone()) as f64)) + Ok(vm.ctx.new_float(v1 + objint::get_value(i2) as f64)) } else { Err(vm.new_type_error(format!("Cannot add {:?} and {:?}", i, i2))) } @@ -44,11 +44,11 @@ fn float_sub(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { required = [(i, Some(vm.ctx.float_type())), (i2, None)] ); - let v1 = get_value(i.clone()); + let v1 = get_value(i); if objtype::isinstance(i2.clone(), vm.ctx.float_type()) { - Ok(vm.ctx.new_float(v1 - get_value(i2.clone()))) + Ok(vm.ctx.new_float(v1 - get_value(i2))) } else if objtype::isinstance(i2.clone(), vm.ctx.int_type()) { - Ok(vm.ctx.new_float(v1 - objint::get_value(i2.clone()) as f64)) + Ok(vm.ctx.new_float(v1 - objint::get_value(i2) as f64)) } else { Err(vm.new_type_error(format!("Cannot add {:?} and {:?}", i, i2))) } @@ -61,12 +61,12 @@ fn float_pow(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { required = [(i, Some(vm.ctx.float_type())), (i2, None)] ); - let v1 = get_value(i.clone()); + let v1 = get_value(i); if objtype::isinstance(i2.clone(), vm.ctx.float_type()) { - let result = v1.powf(get_value(i2.clone())); + let result = v1.powf(get_value(i2)); Ok(vm.ctx.new_float(result)) } else if objtype::isinstance(i2.clone(), vm.ctx.int_type()) { - let result = v1.powf(objint::get_value(i2.clone()) as f64); + let result = v1.powf(objint::get_value(i2) as f64); Ok(vm.ctx.new_float(result)) } else { Err(vm.new_type_error(format!("Cannot add {:?} and {:?}", i, i2))) diff --git a/vm/src/obj/objint.rs b/vm/src/obj/objint.rs index ed5b23bc0..00ffacb45 100644 --- a/vm/src/obj/objint.rs +++ b/vm/src/obj/objint.rs @@ -1,5 +1,6 @@ use super::super::pyobject::{ - AttributeProtocol, PyContext, PyFuncArgs, PyObjectKind, PyObjectRef, PyResult, TypeProtocol, + AttributeProtocol, FromPyObjectRef, PyContext, PyFuncArgs, PyObjectKind, PyObjectRef, PyResult, + TypeProtocol, }; use super::super::vm::VirtualMachine; use super::objfloat; @@ -7,12 +8,12 @@ use super::objtype; fn str(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { arg_check!(vm, args, required = [(int, Some(vm.ctx.int_type()))]); - let v = get_value(int.clone()); + let v = get_value(int); Ok(vm.new_str(v.to_string())) } // Retrieve inner int value: -pub fn get_value(obj: PyObjectRef) -> i32 { +pub fn get_value(obj: &PyObjectRef) -> i32 { if let PyObjectKind::Integer { value } = &obj.borrow().kind { *value } else { @@ -20,18 +21,23 @@ pub fn get_value(obj: PyObjectRef) -> i32 { } } +impl FromPyObjectRef for i32 { + fn from_pyobj(obj: &PyObjectRef) -> i32 { + get_value(obj) + } +} + fn int_add(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { arg_check!( vm, args, required = [(i, Some(vm.ctx.int_type())), (i2, None)] ); + let i = i32::from_pyobj(i); if objtype::isinstance(i2.clone(), vm.ctx.int_type()) { - Ok(vm.ctx.new_int(get_value(i.clone()) + get_value(i2.clone()))) + Ok(vm.ctx.new_int(i + get_value(i2))) } else if objtype::isinstance(i2.clone(), vm.ctx.float_type()) { - Ok(vm - .ctx - .new_float(get_value(i.clone()) as f64 + objfloat::get_value(i2.clone()))) + Ok(vm.ctx.new_float(i as f64 + objfloat::get_value(i2))) } else { Err(vm.new_type_error(format!("Cannot add {:?} and {:?}", i, i2))) } @@ -43,8 +49,11 @@ fn int_sub(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { args, required = [(i, Some(vm.ctx.int_type())), (i2, None)] ); + let i = i32::from_pyobj(i); if objtype::isinstance(i2.clone(), vm.ctx.int_type()) { - Ok(vm.ctx.new_int(get_value(i.clone()) - get_value(i2.clone()))) + Ok(vm.ctx.new_int(i - get_value(i2))) + } else if objtype::isinstance(i2.clone(), vm.ctx.float_type()) { + Ok(vm.ctx.new_float(i as f64 - objfloat::get_value(i2))) } else { Err(vm.new_type_error(format!("Cannot substract {:?} and {:?}", i, i2))) } @@ -57,7 +66,7 @@ fn int_mul(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { required = [(i, Some(vm.ctx.int_type())), (i2, None)] ); if objtype::isinstance(i2.clone(), vm.ctx.int_type()) { - Ok(vm.ctx.new_int(get_value(i.clone()) * get_value(i2.clone()))) + Ok(vm.ctx.new_int(get_value(i) * get_value(i2))) } else { Err(vm.new_type_error(format!("Cannot multiply {:?} and {:?}", i, i2))) } @@ -69,14 +78,11 @@ fn int_truediv(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { args, required = [(i, Some(vm.ctx.int_type())), (i2, None)] ); + let v1 = get_value(i); if objtype::isinstance(i2.clone(), vm.ctx.int_type()) { - Ok(vm - .ctx - .new_float(get_value(i.clone()) as f64 / get_value(i2.clone()) as f64)) + Ok(vm.ctx.new_float(v1 as f64 / get_value(i2) as f64)) } else if objtype::isinstance(i2.clone(), vm.ctx.float_type()) { - Ok(vm - .ctx - .new_float(get_value(i.clone()) as f64 / objfloat::get_value(i2.clone()))) + Ok(vm.ctx.new_float(v1 as f64 / objfloat::get_value(i2))) } else { Err(vm.new_type_error(format!("Cannot multiply {:?} and {:?}", i, i2))) } @@ -88,8 +94,9 @@ fn int_mod(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { args, required = [(i, Some(vm.ctx.int_type())), (i2, None)] ); + let v1 = get_value(i); if objtype::isinstance(i2.clone(), vm.ctx.int_type()) { - Ok(vm.ctx.new_int(get_value(i.clone()) % get_value(i2.clone()))) + Ok(vm.ctx.new_int(v1 % get_value(i2))) } else { Err(vm.new_type_error(format!("Cannot modulo {:?} and {:?}", i, i2))) } @@ -101,12 +108,12 @@ fn int_pow(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { args, required = [(i, Some(vm.ctx.int_type())), (i2, None)] ); - let v1 = get_value(i.clone()); + let v1 = get_value(i); if objtype::isinstance(i2.clone(), vm.ctx.int_type()) { - let v2 = get_value(i2.clone()); + let v2 = get_value(i2); Ok(vm.ctx.new_int(v1.pow(v2 as u32))) } else if objtype::isinstance(i2.clone(), vm.ctx.float_type()) { - let v2 = objfloat::get_value(i2.clone()); + let v2 = objfloat::get_value(i2); Ok(vm.ctx.new_float((v1 as f64).powf(v2))) } else { Err(vm.new_type_error(format!("Cannot modulo {:?} and {:?}", i, i2))) diff --git a/vm/src/obj/objstr.rs b/vm/src/obj/objstr.rs index 330074ada..5c4976280 100644 --- a/vm/src/obj/objstr.rs +++ b/vm/src/obj/objstr.rs @@ -57,7 +57,7 @@ fn str_mul(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { ); if objtype::isinstance(s2.clone(), vm.ctx.int_type()) { let value1 = get_value(&s); - let value2 = objint::get_value(s2.clone()); + let value2 = objint::get_value(s2); let mut result = String::new(); for _x in 0..value2 { result.push_str(value1.as_str()); diff --git a/vm/src/pyobject.rs b/vm/src/pyobject.rs index c54208508..078e03829 100644 --- a/vm/src/pyobject.rs +++ b/vm/src/pyobject.rs @@ -324,6 +324,10 @@ impl IdProtocol for PyObjectRef { } } +pub trait FromPyObjectRef { + fn from_pyobj(obj: &PyObjectRef) -> Self; +} + pub trait TypeProtocol { fn typ(&self) -> PyObjectRef; } diff --git a/vm/src/stdlib/json.rs b/vm/src/stdlib/json.rs index d9a847cb3..c96f82522 100644 --- a/vm/src/stdlib/json.rs +++ b/vm/src/stdlib/json.rs @@ -46,9 +46,9 @@ impl<'s> serde::Serialize for PyObjectSerializer<'s> { if objtype::isinstance(self.pyobject.clone(), self.vm.ctx.str_type()) { serializer.serialize_str(&objstr::get_value(&self.pyobject)) } else if objtype::isinstance(self.pyobject.clone(), self.vm.ctx.int_type()) { - serializer.serialize_i32(objint::get_value(self.pyobject.clone())) + serializer.serialize_i32(objint::get_value(self.pyobject)) } else if objtype::isinstance(self.pyobject.clone(), self.vm.ctx.float_type()) { - serializer.serialize_f64(objfloat::get_value(self.pyobject.clone())) + serializer.serialize_f64(objfloat::get_value(self.pyobject)) } else if objtype::isinstance(self.pyobject.clone(), self.vm.ctx.bool_type()) { serializer.serialize_bool(objbool::get_value(self.pyobject)) } else if objtype::isinstance(self.pyobject.clone(), self.vm.ctx.list_type()) { diff --git a/vm/src/vm.rs b/vm/src/vm.rs index 213160120..86be94b33 100644 --- a/vm/src/vm.rs +++ b/vm/src/vm.rs @@ -979,7 +979,7 @@ mod tests { let a = vm.ctx.new_int(33); let b = vm.ctx.new_int(12); let res = vm._add(a, b).unwrap(); - let value = objint::get_value(res); + let value = objint::get_value(&res); assert_eq!(value, 45); }