mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
Merge with master branch
This commit is contained in:
6
tests/snippets/builtin_pow.py
Normal file
6
tests/snippets/builtin_pow.py
Normal file
@@ -0,0 +1,6 @@
|
||||
assert pow(3,2) == 9
|
||||
assert pow(5,3, 100) == 25
|
||||
|
||||
#causes overflow
|
||||
# assert pow(41, 7, 2) == 1
|
||||
assert pow(7, 2, 49) == 0
|
||||
@@ -290,7 +290,38 @@ fn builtin_next(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
// builtin_oct
|
||||
// builtin_open
|
||||
// builtin_ord
|
||||
// builtin_pow
|
||||
|
||||
fn builtin_pow(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(
|
||||
vm,
|
||||
args,
|
||||
required = [(x, None), (y, None)],
|
||||
optional = [(mod_value, Some(vm.ctx.int_type()))]
|
||||
);
|
||||
let pow_method_name = "__pow__".to_string();
|
||||
let result = match vm.get_attribute(x.clone(), &pow_method_name) {
|
||||
Ok(attrib) => vm.invoke(attrib, PyFuncArgs::new(vec![y.clone()], vec![])),
|
||||
Err(..) => Err(vm.new_type_error("unsupported operand type(s) for pow".to_string())),
|
||||
};
|
||||
//Check if the 3rd argument is defined and perform modulus on the result
|
||||
//this should be optimized in the future to perform a "power-mod" algorithm in
|
||||
//order to improve performance
|
||||
match mod_value {
|
||||
Some(mod_value) => {
|
||||
let mod_method_name = "__mod__".to_string();
|
||||
match vm.get_attribute(
|
||||
result.expect("result not defined").clone(),
|
||||
&mod_method_name,
|
||||
) {
|
||||
Ok(value) => vm.invoke(value, PyFuncArgs::new(vec![mod_value.clone()], vec![])),
|
||||
Err(..) => {
|
||||
Err(vm.new_type_error("unsupported operand type(s) for mod".to_string()))
|
||||
}
|
||||
}
|
||||
}
|
||||
None => result,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn builtin_print(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
trace!("print called with {:?}", args);
|
||||
@@ -386,6 +417,7 @@ pub fn make_module(ctx: &PyContext) -> PyObjectRef {
|
||||
dict.insert(String::from("list"), ctx.list_type());
|
||||
dict.insert(String::from("locals"), ctx.new_rustfunc(builtin_locals));
|
||||
dict.insert(String::from("next"), ctx.new_rustfunc(builtin_next));
|
||||
dict.insert(String::from("pow"), ctx.new_rustfunc(builtin_pow));
|
||||
dict.insert(String::from("print"), ctx.new_rustfunc(builtin_print));
|
||||
dict.insert(String::from("range"), ctx.new_rustfunc(builtin_range));
|
||||
dict.insert(String::from("repr"), ctx.new_rustfunc(builtin_repr));
|
||||
|
||||
@@ -156,7 +156,7 @@ fn int_truediv(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
} else if objtype::isinstance(i2, vm.ctx.float_type()) {
|
||||
Ok(vm.ctx.new_float(v1 as f64 / objfloat::get_value(i2)))
|
||||
} else {
|
||||
Err(vm.new_type_error(format!("Cannot multiply {:?} and {:?}", i, i2)))
|
||||
Err(vm.new_type_error(format!("Cannot divide {:?} and {:?}", i, i2)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,7 +188,7 @@ fn int_pow(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
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)))
|
||||
Err(vm.new_type_error(format!("Cannot raise power {:?} and {:?}", i, i2)))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user