From 8d7be94b03d9b28f41683364671de6a2f6673c4d Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Sat, 1 Feb 2020 17:40:24 +0900 Subject: [PATCH] PyBool --- tests/snippets/bools.py | 1 + vm/src/obj/objbool.rs | 181 ++++++++++++++++++++-------------------- 2 files changed, 91 insertions(+), 91 deletions(-) diff --git a/tests/snippets/bools.py b/tests/snippets/bools.py index 5bb12ee8d1..a46dbaab93 100644 --- a/tests/snippets/bools.py +++ b/tests/snippets/bools.py @@ -94,6 +94,7 @@ def __bool__(self): assert bool([1]) is True assert bool(set([1,2])) is True +assert repr(True) == "True" # Check __len__ work class TestMagicMethodLenZero: diff --git a/vm/src/obj/objbool.rs b/vm/src/obj/objbool.rs index 1cd91e9b9d..56d21bb5c5 100644 --- a/vm/src/obj/objbool.rs +++ b/vm/src/obj/objbool.rs @@ -3,7 +3,8 @@ use num_traits::Zero; use crate::function::PyFuncArgs; use crate::pyobject::{ - IdProtocol, IntoPyObject, PyContext, PyObjectRef, PyResult, TryFromObject, TypeProtocol, + IdProtocol, IntoPyObject, PyClassImpl, PyContext, PyObjectRef, PyResult, TryFromObject, + TypeProtocol, }; use crate::vm::VirtualMachine; @@ -78,114 +79,112 @@ pub fn boolval(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult { Ok(rs_bool) } -pub fn init(context: &PyContext) { - let bool_doc = "bool(x) -> bool - -Returns True when the argument x is true, False otherwise. -The builtins True and False are the only two instances of the class bool. -The class bool is a subclass of the class int, and cannot be subclassed."; - - let bool_type = &context.types.bool_type; - extend_class!(context, bool_type, { - (slot new) => bool_new, - "__repr__" => context.new_method(bool_repr), - "__format__" => context.new_method(bool_format), - "__or__" => context.new_method(bool_or), - "__ror__" => context.new_method(bool_or), - "__and__" => context.new_method(bool_and), - "__rand__" => context.new_method(bool_and), - "__xor__" => context.new_method(bool_xor), - "__rxor__" => context.new_method(bool_xor), - "__doc__" => context.new_str(bool_doc.to_owned()), - }); -} +/// bool(x) -> bool +/// +/// Returns True when the argument x is true, False otherwise. +/// The builtins True and False are the only two instances of the class bool. +/// The class bool is a subclass of the class int, and cannot be subclassed. +#[pyclass] +struct PyBool; -pub fn not(vm: &VirtualMachine, obj: &PyObjectRef) -> PyResult { - if objtype::isinstance(obj, &vm.ctx.bool_type()) { - let value = get_value(obj); - Ok(!value) - } else { - Err(vm.new_type_error(format!("Can only invert a bool, on {:?}", obj))) +#[pyimpl] +impl PyBool { + #[pymethod(magic)] + fn repr(zelf: bool) -> String { + if zelf { "True" } else { "False" }.to_owned() } -} -// Retrieve inner int value: -pub fn get_value(obj: &PyObjectRef) -> bool { - !obj.payload::().unwrap().as_bigint().is_zero() -} + #[pymethod(magic)] + fn format( + obj: PyObjectRef, + format_spec: PyStringRef, + vm: &VirtualMachine, + ) -> PyResult { + if format_spec.as_str().is_empty() { + vm.to_str(&obj) + } else { + Err(vm.new_type_error("unsupported format string passed to bool.__format__".to_owned())) + } + } -pub fn get_py_int(obj: &PyObjectRef) -> &PyInt { - &obj.payload::().unwrap() -} + #[pymethod(name = "__ror__")] + #[pymethod(magic)] + fn or(lhs: PyObjectRef, rhs: PyObjectRef, vm: &VirtualMachine) -> PyResult { + if objtype::isinstance(&lhs, &vm.ctx.bool_type()) + && objtype::isinstance(&rhs, &vm.ctx.bool_type()) + { + let lhs = get_value(&lhs); + let rhs = get_value(&rhs); + (lhs || rhs).into_pyobject(vm) + } else { + get_py_int(&lhs).or(rhs.clone(), vm).into_pyobject(vm) + } + } -fn bool_repr(obj: bool) -> String { - if obj { - "True".to_owned() - } else { - "False".to_owned() + #[pymethod(name = "__rand__")] + #[pymethod(magic)] + fn and(lhs: PyObjectRef, rhs: PyObjectRef, vm: &VirtualMachine) -> PyResult { + if objtype::isinstance(&lhs, &vm.ctx.bool_type()) + && objtype::isinstance(&rhs, &vm.ctx.bool_type()) + { + let lhs = get_value(&lhs); + let rhs = get_value(&rhs); + (lhs && rhs).into_pyobject(vm) + } else { + get_py_int(&lhs).and(rhs.clone(), vm).into_pyobject(vm) + } } -} -fn bool_format( - obj: PyObjectRef, - format_spec: PyStringRef, - vm: &VirtualMachine, -) -> PyResult { - if format_spec.as_str().is_empty() { - vm.to_str(&obj) - } else { - Err(vm.new_type_error("unsupported format string passed to bool.__format__".to_owned())) + #[pymethod(name = "__rxor__")] + #[pymethod(magic)] + fn xor(lhs: PyObjectRef, rhs: PyObjectRef, vm: &VirtualMachine) -> PyResult { + if objtype::isinstance(&lhs, &vm.ctx.bool_type()) + && objtype::isinstance(&rhs, &vm.ctx.bool_type()) + { + let lhs = get_value(&lhs); + let rhs = get_value(&rhs); + (lhs ^ rhs).into_pyobject(vm) + } else { + get_py_int(&lhs).xor(rhs.clone(), vm).into_pyobject(vm) + } } -} -fn bool_or(lhs: PyObjectRef, rhs: PyObjectRef, vm: &VirtualMachine) -> PyResult { - if objtype::isinstance(&lhs, &vm.ctx.bool_type()) - && objtype::isinstance(&rhs, &vm.ctx.bool_type()) - { - let lhs = get_value(&lhs); - let rhs = get_value(&rhs); - (lhs || rhs).into_pyobject(vm) - } else { - get_py_int(&lhs).or(rhs.clone(), vm).into_pyobject(vm) + #[pyslot] + fn tp_new(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult { + arg_check!( + vm, + args, + required = [(_zelf, Some(vm.ctx.type_type()))], + optional = [(val, None)] + ); + let value = match val { + Some(val) => boolval(vm, val.clone())?, + None => false, + }; + Ok(vm.new_bool(value)) } } -fn bool_and(lhs: PyObjectRef, rhs: PyObjectRef, vm: &VirtualMachine) -> PyResult { - if objtype::isinstance(&lhs, &vm.ctx.bool_type()) - && objtype::isinstance(&rhs, &vm.ctx.bool_type()) - { - let lhs = get_value(&lhs); - let rhs = get_value(&rhs); - (lhs && rhs).into_pyobject(vm) - } else { - get_py_int(&lhs).and(rhs.clone(), vm).into_pyobject(vm) - } +pub(crate) fn init(context: &PyContext) { + PyBool::extend_class(context, &context.types.bool_type); } -fn bool_xor(lhs: PyObjectRef, rhs: PyObjectRef, vm: &VirtualMachine) -> PyResult { - if objtype::isinstance(&lhs, &vm.ctx.bool_type()) - && objtype::isinstance(&rhs, &vm.ctx.bool_type()) - { - let lhs = get_value(&lhs); - let rhs = get_value(&rhs); - (lhs ^ rhs).into_pyobject(vm) +pub fn not(vm: &VirtualMachine, obj: &PyObjectRef) -> PyResult { + if objtype::isinstance(obj, &vm.ctx.bool_type()) { + let value = get_value(obj); + Ok(!value) } else { - get_py_int(&lhs).xor(rhs.clone(), vm).into_pyobject(vm) + Err(vm.new_type_error(format!("Can only invert a bool, on {:?}", obj))) } } -fn bool_new(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult { - arg_check!( - vm, - args, - required = [(_zelf, Some(vm.ctx.type_type()))], - optional = [(val, None)] - ); - let value = match val { - Some(val) => boolval(vm, val.clone())?, - None => false, - }; - Ok(vm.new_bool(value)) +// Retrieve inner int value: +pub fn get_value(obj: &PyObjectRef) -> bool { + !obj.payload::().unwrap().as_bigint().is_zero() +} + +pub fn get_py_int(obj: &PyObjectRef) -> &PyInt { + &obj.payload::().unwrap() } #[derive(Debug, Copy, Clone, PartialEq)]