diff --git a/vm/src/objbool.rs b/vm/src/objbool.rs index 1eda368cd..5ace3f217 100644 --- a/vm/src/objbool.rs +++ b/vm/src/objbool.rs @@ -34,6 +34,27 @@ pub fn boolval(vm: &mut VirtualMachine, obj: PyObjectRef) -> Result 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 { + 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 { diff --git a/vm/src/objfloat.rs b/vm/src/objfloat.rs index 7b0e6bd7a..72890d687 100644 --- a/vm/src/objfloat.rs +++ b/vm/src/objfloat.rs @@ -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)); diff --git a/vm/src/objint.rs b/vm/src/objint.rs index de3aeb2b1..ebee5920e 100644 --- a/vm/src/objint.rs +++ b/vm/src/objint.rs @@ -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)); diff --git a/vm/src/objlist.rs b/vm/src/objlist.rs index 9c6735407..21441837c 100644 --- a/vm/src/objlist.rs +++ b/vm/src/objlist.rs @@ -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::>() + .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)); diff --git a/vm/src/objstr.rs b/vm/src/objstr.rs index 9fc257fea..357337c95 100644 --- a/vm/src/objstr.rs +++ b/vm/src/objstr.rs @@ -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 { diff --git a/vm/src/pyobject.rs b/vm/src/pyobject.rs index c00dc5b81..18d2dbeff 100644 --- a/vm/src/pyobject.rs +++ b/vm/src/pyobject.rs @@ -555,10 +555,6 @@ pub enum PyObjectKind { stop: Option, step: Option, }, - 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!(""), PyObjectKind::Module { ref name, dict: _ } => format!("", name), PyObjectKind::Scope { ref scope } => format!("", scope), - PyObjectKind::NameError { ref name } => format!("NameError: {:?}", name), PyObjectKind::Slice { ref start, ref stop, diff --git a/vm/src/vm.rs b/vm/src/vm.rs index 7c27976ac..5ce2bf53e 100644 --- a/vm/src/vm.rs +++ b/vm/src/vm.rs @@ -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 {