Moved pow method

This commit is contained in:
Windel Bouwman
2018-08-29 13:23:42 +02:00
parent 201281554f
commit 81cbe66085
7 changed files with 94 additions and 40 deletions

View File

@@ -34,6 +34,27 @@ pub fn boolval(vm: &mut VirtualMachine, obj: PyObjectRef) -> Result<bool, PyObje
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));
}
// Retrieve inner int value:
pub fn get_value(obj: &PyObjectRef) -> bool {
if let PyObjectKind::Boolean { value } = &obj.borrow().kind {
*value
} else {
panic!("Inner error getting inner boolean");
}
}
fn bool_str(vm: &mut VirtualMachine, args: PyFuncArgs) -> Result<PyObjectRef, PyObjectRef> {
arg_check!(vm, args, required = [(obj, Some(vm.ctx.bool_type()))]);
let v = get_value(obj);
let s = if v {
"True".to_string()
} else {
"True".to_string()
};
Ok(vm.new_str(s))
}
fn bool_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {

View File

@@ -27,14 +27,11 @@ fn float_add(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
required = [(i, Some(vm.ctx.float_type())), (i2, None)]
);
let v1 = get_value(i.clone());
if objtype::isinstance(i2.clone(), vm.ctx.float_type()) {
Ok(vm
.ctx
.new_float(get_value(i.clone()) + get_value(i2.clone())))
Ok(vm.ctx.new_float(v1 + get_value(i2.clone())))
} else if objtype::isinstance(i2.clone(), vm.ctx.int_type()) {
Ok(vm
.ctx
.new_float(get_value(i.clone()) + objint::get_value(i2.clone()) as f64))
Ok(vm.ctx.new_float(v1 + objint::get_value(i2.clone()) as f64))
} else {
Err(vm.new_type_error(format!("Cannot add {:?} and {:?}", i, i2)))
}
@@ -47,14 +44,30 @@ fn float_sub(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
required = [(i, Some(vm.ctx.float_type())), (i2, None)]
);
let v1 = get_value(i.clone());
if objtype::isinstance(i2.clone(), vm.ctx.float_type()) {
Ok(vm
.ctx
.new_float(get_value(i.clone()) - get_value(i2.clone())))
Ok(vm.ctx.new_float(v1 - get_value(i2.clone())))
} else if objtype::isinstance(i2.clone(), vm.ctx.int_type()) {
Ok(vm
.ctx
.new_float(get_value(i.clone()) - objint::get_value(i2.clone()) as f64))
Ok(vm.ctx.new_float(v1 - objint::get_value(i2.clone()) as f64))
} else {
Err(vm.new_type_error(format!("Cannot add {:?} and {:?}", i, i2)))
}
}
fn float_pow(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(
vm,
args,
required = [(i, Some(vm.ctx.float_type())), (i2, None)]
);
let v1 = get_value(i.clone());
if objtype::isinstance(i2.clone(), vm.ctx.float_type()) {
let result = v1.powf(get_value(i2.clone()));
Ok(vm.ctx.new_float(result))
} else if objtype::isinstance(i2.clone(), vm.ctx.int_type()) {
let result = v1.powf(objint::get_value(i2.clone()) as f64);
Ok(vm.ctx.new_float(result))
} else {
Err(vm.new_type_error(format!("Cannot add {:?} and {:?}", i, i2)))
}
@@ -63,6 +76,7 @@ fn float_sub(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
pub fn init(context: &PyContext) {
let ref float_type = context.float_type;
float_type.set_attr("__add__", context.new_rustfunc(float_add));
float_type.set_attr("__pow__", context.new_rustfunc(float_pow));
float_type.set_attr("__str__", context.new_rustfunc(str));
float_type.set_attr("__sub__", context.new_rustfunc(float_sub));
float_type.set_attr("__repr__", context.new_rustfunc(str));

View File

@@ -95,11 +95,30 @@ fn int_mod(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
}
}
fn int_pow(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(
vm,
args,
required = [(i, Some(vm.ctx.int_type())), (i2, None)]
);
let v1 = get_value(i.clone());
if objtype::isinstance(i2.clone(), vm.ctx.int_type()) {
let v2 = get_value(i2.clone());
Ok(vm.ctx.new_int(v1.pow(v2 as u32)))
} else if objtype::isinstance(i2.clone(), vm.ctx.float_type()) {
let v2 = objfloat::get_value(i2.clone());
Ok(vm.ctx.new_float((v1 as f64).powf(v2)))
} else {
Err(vm.new_type_error(format!("Cannot modulo {:?} and {:?}", i, i2)))
}
}
pub fn init(context: &PyContext) {
let ref int_type = context.int_type;
int_type.set_attr("__add__", context.new_rustfunc(int_add));
int_type.set_attr("__mod__", context.new_rustfunc(int_mod));
int_type.set_attr("__mul__", context.new_rustfunc(int_mul));
int_type.set_attr("__pow__", context.new_rustfunc(int_pow));
int_type.set_attr("__repr__", context.new_rustfunc(str));
int_type.set_attr("__str__", context.new_rustfunc(str));
int_type.set_attr("__sub__", context.new_rustfunc(int_sub));

View File

@@ -50,6 +50,28 @@ fn list_add(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
}
}
/*
* TODO:
fn list_str(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(
vm,
args,
required = [(o, Some(vm.ctx.list_type()))]
);
let
PyObjectKind::List { ref elements } => format!(
"[{}]",
elements
.iter()
.map(|elem| elem.borrow().str())
.collect::<Vec<_>>()
.join(", ")
),
}
}
*/
pub fn append(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
trace!("list.append called with: {:?}", args);
arg_check!(
@@ -105,6 +127,7 @@ pub fn init(context: &PyContext) {
let ref list_type = context.list_type;
list_type.set_attr("__add__", context.new_rustfunc(list_add));
list_type.set_attr("__len__", context.new_rustfunc(len));
// list_type.set_attr("__str__", context.new_rustfunc(list_str));
list_type.set_attr("append", context.new_rustfunc(append));
list_type.set_attr("clear", context.new_rustfunc(clear));
list_type.set_attr("reverse", context.new_rustfunc(reverse));

View File

@@ -72,8 +72,8 @@ fn str_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
if args.args.len() > 2 {
panic!("str expects exactly one parameter");
};
let s = args.args[1].borrow().str();
Ok(vm.new_str(s))
vm.to_str(args.args[1].clone())
}
impl PySliceableSequence for String {

View File

@@ -555,10 +555,6 @@ pub enum PyObjectKind {
stop: Option<i32>,
step: Option<i32>,
},
NameError {
// TODO: improve python object and type system
name: String,
},
Code {
code: bytecode::CodeObject,
},
@@ -610,7 +606,6 @@ impl fmt::Debug for PyObjectKind {
stop: _,
step: _,
} => write!(f, "slice"),
&PyObjectKind::NameError { name: _ } => write!(f, "NameError"),
&PyObjectKind::Code { ref code } => write!(f, "code: {:?}", code),
&PyObjectKind::Function { code: _, scope: _ } => write!(f, "function"),
&PyObjectKind::BoundMethod {
@@ -687,7 +682,6 @@ impl PyObject {
PyObjectKind::RustFunction { function: _ } => format!("<rustfunc>"),
PyObjectKind::Module { ref name, dict: _ } => format!("<module '{}'>", name),
PyObjectKind::Scope { ref scope } => format!("<scope '{:?}'>", scope),
PyObjectKind::NameError { ref name } => format!("NameError: {:?}", name),
PyObjectKind::Slice {
ref start,
ref stop,

View File

@@ -130,8 +130,8 @@ impl VirtualMachine {
}
// Container of the virtual machine state:
pub fn to_str(&mut self, obj: PyObjectRef) -> String {
obj.borrow().str()
pub fn to_str(&mut self, obj: PyObjectRef) -> PyResult {
self.call_method(obj, "__str__".to_string(), vec![])
}
pub fn current_frame(&self) -> &Frame {
@@ -349,24 +349,7 @@ impl VirtualMachine {
}
fn _pow(&mut self, a: PyObjectRef, b: PyObjectRef) -> PyResult {
let b2 = &*b.borrow();
let a2 = &*a.borrow();
match (&a2.kind, &b2.kind) {
(
&PyObjectKind::Integer { value: ref v1 },
&PyObjectKind::Integer { value: ref v2 },
) => Ok(self.ctx.new_int(v1.pow(*v2 as u32))),
(&PyObjectKind::Float { value: ref v1 }, &PyObjectKind::Integer { value: ref v2 }) => {
Ok(self.ctx.new_float(v1.powf(*v2 as f64)))
}
(&PyObjectKind::Integer { value: ref v1 }, &PyObjectKind::Float { value: ref v2 }) => {
Ok(self.ctx.new_float((*v1 as f64).powf(*v2)))
}
(&PyObjectKind::Float { value: ref v1 }, &PyObjectKind::Float { value: ref v2 }) => {
Ok(self.ctx.new_float(v1.powf(*v2)))
}
_ => panic!("Not impl"),
}
self.call_method(a, "__pow__".to_string(), vec![b])
}
fn _modulo(&mut self, a: PyObjectRef, b: PyObjectRef) -> PyResult {