From 73ae085ed845100e82ee64641f38da46790edeaa Mon Sep 17 00:00:00 2001 From: lausek Date: Tue, 5 Feb 2019 12:47:30 +0100 Subject: [PATCH 1/3] implemented rounding funcs for int (#304) --- vm/src/obj/objint.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/vm/src/obj/objint.rs b/vm/src/obj/objint.rs index a00f1d5b0f..0eda177cf5 100644 --- a/vm/src/obj/objint.rs +++ b/vm/src/obj/objint.rs @@ -294,6 +294,21 @@ fn int_floordiv(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { } } +fn int_round(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { + arg_check!( + vm, + args, + required = [(i, Some(vm.ctx.int_type()))], + optional = [(_precision, None)] + ); + Ok(vm.ctx.new_int(get_value(i))) +} + +fn int_ceil_floor(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { + arg_check!(vm, args, required = [(i, Some(vm.ctx.int_type()))]); + Ok(vm.ctx.new_int(get_value(i))) +} + fn int_format(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { arg_check!( vm, @@ -512,6 +527,9 @@ pub fn init(context: &PyContext) { context.set_attr(&int_type, "__and__", context.new_rustfunc(int_and)); context.set_attr(&int_type, "__divmod__", context.new_rustfunc(int_divmod)); context.set_attr(&int_type, "__float__", context.new_rustfunc(int_float)); + context.set_attr(&int_type, "__round__", context.new_rustfunc(int_round)); + context.set_attr(&int_type, "__ceil__", context.new_rustfunc(int_ceil_floor)); + context.set_attr(&int_type, "__floor__", context.new_rustfunc(int_ceil_floor)); context.set_attr( &int_type, "__floordiv__", From 3d07ecdd1c6762d1eec870611b23f597b7933f1d Mon Sep 17 00:00:00 2001 From: lausek Date: Tue, 5 Feb 2019 14:08:08 +0100 Subject: [PATCH 2/3] int type: trunc and index --- tests/snippets/numbers.py | 7 +++++++ vm/src/obj/objint.rs | 8 +++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/tests/snippets/numbers.py b/tests/snippets/numbers.py index 7b01f6473c..c13470edad 100644 --- a/tests/snippets/numbers.py +++ b/tests/snippets/numbers.py @@ -9,6 +9,13 @@ class A(int): assert x == 7 assert type(x) is A +assert int(2).__index__() == 2 +assert int(2).__trunc__() == 2 +assert int(2).__ceil__() == 2 +assert int(2).__floor__() == 2 +assert int(2).__round__() == 2 +assert int(2).__round__(3) == 2 + assert int(2).__bool__() == True assert int(0.5).__bool__() == False assert int(-1).__bool__() == True diff --git a/vm/src/obj/objint.rs b/vm/src/obj/objint.rs index 0eda177cf5..8598e68e87 100644 --- a/vm/src/obj/objint.rs +++ b/vm/src/obj/objint.rs @@ -304,7 +304,7 @@ fn int_round(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { Ok(vm.ctx.new_int(get_value(i))) } -fn int_ceil_floor(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { +fn int_pass_value(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { arg_check!(vm, args, required = [(i, Some(vm.ctx.int_type()))]); Ok(vm.ctx.new_int(get_value(i))) } @@ -528,8 +528,10 @@ pub fn init(context: &PyContext) { context.set_attr(&int_type, "__divmod__", context.new_rustfunc(int_divmod)); context.set_attr(&int_type, "__float__", context.new_rustfunc(int_float)); context.set_attr(&int_type, "__round__", context.new_rustfunc(int_round)); - context.set_attr(&int_type, "__ceil__", context.new_rustfunc(int_ceil_floor)); - context.set_attr(&int_type, "__floor__", context.new_rustfunc(int_ceil_floor)); + context.set_attr(&int_type, "__ceil__", context.new_rustfunc(int_pass_value)); + context.set_attr(&int_type, "__floor__", context.new_rustfunc(int_pass_value)); + context.set_attr(&int_type, "__index__", context.new_rustfunc(int_pass_value)); + context.set_attr(&int_type, "__trunc__", context.new_rustfunc(int_pass_value)); context.set_attr( &int_type, "__floordiv__", From 02d99758fed6031cb7e83845214b4caaf3871657 Mon Sep 17 00:00:00 2001 From: lausek Date: Wed, 6 Feb 2019 18:38:37 +0100 Subject: [PATCH 3/3] round() for int --- tests/snippets/numbers.py | 10 ++++++++++ vm/src/builtins.rs | 20 +++++++++++++++++++- vm/src/obj/objint.rs | 1 + 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/tests/snippets/numbers.py b/tests/snippets/numbers.py index c13470edad..da4ff50400 100644 --- a/tests/snippets/numbers.py +++ b/tests/snippets/numbers.py @@ -15,6 +15,16 @@ class A(int): assert int(2).__floor__() == 2 assert int(2).__round__() == 2 assert int(2).__round__(3) == 2 +assert int(-2).__index__() == -2 +assert int(-2).__trunc__() == -2 +assert int(-2).__ceil__() == -2 +assert int(-2).__floor__() == -2 +assert int(-2).__round__() == -2 +assert int(-2).__round__(3) == -2 + +assert round(10) == 10 +assert round(10, 2) == 10 +assert round(10, -1) == 10 assert int(2).__bool__() == True assert int(0.5).__bool__() == False diff --git a/vm/src/builtins.rs b/vm/src/builtins.rs index a08e70fb70..31f377b28b 100644 --- a/vm/src/builtins.rs +++ b/vm/src/builtins.rs @@ -664,7 +664,24 @@ fn builtin_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { vm.to_repr(obj) } // builtin_reversed -// builtin_round + +fn builtin_round(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { + arg_check!( + vm, + args, + required = [(number, Some(vm.ctx.object()))], + optional = [(ndigits, None)] + ); + if let Some(ndigits) = ndigits { + let ndigits = vm.call_method(ndigits, "__int__", vec![])?; + let rounded = vm.call_method(number, "__round__", vec![ndigits])?; + Ok(rounded) + } else { + // without a parameter, the result type is coerced to int + let rounded = &vm.call_method(number, "__round__", vec![])?; + Ok(vm.ctx.new_int(objint::get_value(rounded))) + } +} fn builtin_setattr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { arg_check!( @@ -777,6 +794,7 @@ pub fn make_module(ctx: &PyContext) -> PyObjectRef { ctx.set_attr(&py_mod, "property", ctx.property_type()); ctx.set_attr(&py_mod, "range", ctx.range_type()); ctx.set_attr(&py_mod, "repr", ctx.new_rustfunc(builtin_repr)); + ctx.set_attr(&py_mod, "round", ctx.new_rustfunc(builtin_round)); ctx.set_attr(&py_mod, "set", ctx.set_type()); ctx.set_attr(&py_mod, "setattr", ctx.new_rustfunc(builtin_setattr)); ctx.set_attr(&py_mod, "staticmethod", ctx.staticmethod_type()); diff --git a/vm/src/obj/objint.rs b/vm/src/obj/objint.rs index 8598e68e87..75e3b3dec1 100644 --- a/vm/src/obj/objint.rs +++ b/vm/src/obj/objint.rs @@ -532,6 +532,7 @@ pub fn init(context: &PyContext) { context.set_attr(&int_type, "__floor__", context.new_rustfunc(int_pass_value)); context.set_attr(&int_type, "__index__", context.new_rustfunc(int_pass_value)); context.set_attr(&int_type, "__trunc__", context.new_rustfunc(int_pass_value)); + context.set_attr(&int_type, "__int__", context.new_rustfunc(int_pass_value)); context.set_attr( &int_type, "__floordiv__",