From 04b73d4628a08e99d2ede728c071158e7176351c Mon Sep 17 00:00:00 2001 From: Adam Kelly Date: Sun, 2 Sep 2018 14:10:36 +0100 Subject: [PATCH] Bool is a subclass of int, so doesn't need a special kind. --- tests/snippets/bools.py | 7 +++++++ vm/src/objbool.rs | 23 +++-------------------- vm/src/pyobject.rs | 19 +++++++++---------- vm/src/stdlib/json.rs | 8 +++++--- 4 files changed, 24 insertions(+), 33 deletions(-) diff --git a/tests/snippets/bools.py b/tests/snippets/bools.py index 440bcde90..aeec25639 100644 --- a/tests/snippets/bools.py +++ b/tests/snippets/bools.py @@ -39,3 +39,10 @@ assert ("thing" or 0) == "thing" assert (True and True) assert not (False and fake) assert (True and 5) == 5 + +# Bools are also ints. +assert isinstance(True, int) +assert True + True == 2 +assert False * 7 == 0 +assert True > 0 +assert int(True) == 1 diff --git a/vm/src/objbool.rs b/vm/src/objbool.rs index 7bb4fe804..4dd66e730 100644 --- a/vm/src/objbool.rs +++ b/vm/src/objbool.rs @@ -6,7 +6,6 @@ use super::vm::VirtualMachine; pub fn boolval(vm: &mut VirtualMachine, obj: PyObjectRef) -> Result { let result = match obj.borrow().kind { - PyObjectKind::Boolean { value } => value, PyObjectKind::Integer { value } => value != 0, PyObjectKind::Float { value } => value != 0.0, PyObjectKind::List { ref elements } => !elements.is_empty(), @@ -18,7 +17,7 @@ pub fn boolval(vm: &mut VirtualMachine, obj: PyObjectRef) -> Result match result.borrow().kind { - PyObjectKind::Boolean { value } => value, + PyObjectKind::Integer { value } => value != 0, _ => return Err(vm.new_type_error(String::from("TypeError"))), }, Err(err) => return Err(err), @@ -35,22 +34,6 @@ pub fn init(context: &PyContext) { let ref bool_type = context.bool_type; bool_type.set_attr("__new__", context.new_rustfunc(bool_new)); bool_type.set_attr("__str__", context.new_rustfunc(bool_str)); - bool_type.set_attr("__eq__", context.new_rustfunc(bool_eq)); -} - -fn bool_eq(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { - arg_check!( - vm, - args, - required = [(zelf, Some(vm.ctx.bool_type())), (other, None)] - ); - - let result = if objtype::isinstance(other.clone(), vm.ctx.bool_type()) { - get_value(zelf) == get_value(other) - } else { - false - }; - Ok(vm.ctx.new_bool(result)) } pub fn not(vm: &mut VirtualMachine, obj: &PyObjectRef) -> PyResult { @@ -64,8 +47,8 @@ pub fn not(vm: &mut VirtualMachine, obj: &PyObjectRef) -> PyResult { // Retrieve inner int value: pub fn get_value(obj: &PyObjectRef) -> bool { - if let PyObjectKind::Boolean { value } = &obj.borrow().kind { - *value + if let PyObjectKind::Integer { value } = &obj.borrow().kind { + *value != 0 } else { panic!("Inner error getting inner boolean"); } diff --git a/vm/src/pyobject.rs b/vm/src/pyobject.rs index 0373ca69b..cdfb71470 100644 --- a/vm/src/pyobject.rs +++ b/vm/src/pyobject.rs @@ -86,7 +86,7 @@ fn _nothing() -> PyObjectRef { pub fn create_type( name: &str, type_type: &PyObjectRef, - object: &PyObjectRef, + base: &PyObjectRef, dict_type: &PyObjectRef, ) -> PyObjectRef { let dict = PyObject::new( @@ -95,7 +95,7 @@ pub fn create_type( }, dict_type.clone(), ); - objtype::new(type_type.clone(), name, vec![object.clone()], dict).unwrap() + objtype::new(type_type.clone(), name, vec![base.clone()], dict).unwrap() } // Basic objects: @@ -119,7 +119,7 @@ impl PyContext { let float_type = create_type("float", &type_type, &object_type, &dict_type); let bytes_type = create_type("bytes", &type_type, &object_type, &dict_type); let tuple_type = create_type("tuple", &type_type, &object_type, &dict_type); - let bool_type = create_type("bool", &type_type, &object_type, &dict_type); + let bool_type = create_type("bool", &type_type, &int_type, &dict_type); let exceptions = exceptions::ExceptionZoo::new(&type_type, &object_type, &dict_type); let none = PyObject::new( @@ -220,7 +220,12 @@ impl PyContext { } pub fn new_bool(&self, b: bool) -> PyObjectRef { - PyObject::new(PyObjectKind::Boolean { value: b }, self.bool_type()) + PyObject::new( + PyObjectKind::Integer { + value: if b { 1 } else { 0 }, + }, + self.bool_type(), + ) } pub fn new_tuple(&self, elements: Vec) -> PyObjectRef { @@ -563,9 +568,6 @@ pub enum PyObjectKind { Float { value: f64, }, - Boolean { - value: bool, - }, Bytes { value: Vec, }, @@ -627,7 +629,6 @@ impl fmt::Debug for PyObjectKind { &PyObjectKind::Integer { ref value } => write!(f, "int {}", value), &PyObjectKind::Float { ref value } => write!(f, "float {}", value), &PyObjectKind::Bytes { ref value } => write!(f, "bytes {:?}", value), - &PyObjectKind::Boolean { ref value } => write!(f, "boolean {}", value), &PyObjectKind::List { elements: _ } => write!(f, "list"), &PyObjectKind::Tuple { elements: _ } => write!(f, "tuple"), &PyObjectKind::Dict { elements: _ } => write!(f, "dict"), @@ -675,7 +676,6 @@ impl PyObject { PyObjectKind::Integer { ref value } => format!("{:?}", value), PyObjectKind::Float { ref value } => format!("{:?}", value), PyObjectKind::Bytes { ref value } => format!("b'{:?}'", value), - PyObjectKind::Boolean { ref value } => format!("{:?}", value), PyObjectKind::List { ref elements } => format!( "[{}]", elements @@ -797,7 +797,6 @@ impl PartialEq for PyObject { false } } - (PyObjectKind::Boolean { value: a }, PyObjectKind::Boolean { value: b }) => a == b, (PyObjectKind::None, PyObjectKind::None) => true, _ => panic!( "TypeError in COMPARE_OP: can't compare {:?} with {:?}", diff --git a/vm/src/stdlib/json.rs b/vm/src/stdlib/json.rs index 6ed1ed224..24648db0f 100644 --- a/vm/src/stdlib/json.rs +++ b/vm/src/stdlib/json.rs @@ -45,12 +45,12 @@ 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)) } else if objtype::isinstance(self.pyobject.clone(), self.vm.ctx.float_type()) { 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.int_type()) { + serializer.serialize_i32(objint::get_value(self.pyobject)) } else if objtype::isinstance(self.pyobject.clone(), self.vm.ctx.list_type()) { let elements = objlist::get_elements(self.pyobject); serialize_seq_elements(serializer, elements) @@ -143,7 +143,9 @@ impl<'de> Visitor<'de> for PyObjectKindVisitor { where E: serde::de::Error, { - Ok(PyObjectKind::Boolean { value }) + Ok(PyObjectKind::Integer { + value: if value { 1 } else { 0 }, + }) } fn visit_seq(self, mut access: A) -> Result