Merge with master branch

This commit is contained in:
Windel Bouwman
2018-09-09 20:36:42 +02:00
3 changed files with 41 additions and 3 deletions

View 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

View File

@@ -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));

View File

@@ -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)))
}
}