mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
Merge branch 'master' into equality
This commit is contained in:
@@ -25,3 +25,11 @@ assert type(2 / 3) is float
|
||||
x = 1
|
||||
assert type(x) is int
|
||||
assert type(x - 1) is int
|
||||
|
||||
a = bytes([1, 2, 3])
|
||||
print(a)
|
||||
try:
|
||||
bytes([object()])
|
||||
except TypeError:
|
||||
pass
|
||||
|
||||
|
||||
@@ -322,6 +322,7 @@ pub fn make_module(ctx: &PyContext) -> PyObjectRef {
|
||||
dict.insert(String::from("all"), ctx.new_rustfunc(builtin_all));
|
||||
dict.insert(String::from("any"), ctx.new_rustfunc(builtin_any));
|
||||
dict.insert(String::from("bool"), ctx.bool_type());
|
||||
dict.insert(String::from("bytes"), ctx.bytes_type());
|
||||
dict.insert(String::from("chr"), ctx.new_rustfunc(builtin_chr));
|
||||
dict.insert(String::from("compile"), ctx.new_rustfunc(builtin_compile));
|
||||
dict.insert(String::from("dict"), ctx.dict_type());
|
||||
|
||||
@@ -22,9 +22,6 @@ mod frame;
|
||||
mod import;
|
||||
mod obj;
|
||||
mod objbool;
|
||||
mod objfunction;
|
||||
mod objobject;
|
||||
mod objsequence;
|
||||
pub mod pyobject;
|
||||
pub mod stdlib;
|
||||
mod sysmodule;
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
pub mod objbytes;
|
||||
pub mod objdict;
|
||||
pub mod objfloat;
|
||||
pub mod objfunction;
|
||||
pub mod objint;
|
||||
pub mod objlist;
|
||||
pub mod objobject;
|
||||
pub mod objsequence;
|
||||
pub mod objstr;
|
||||
pub mod objtuple;
|
||||
pub mod objtype;
|
||||
|
||||
59
vm/src/obj/objbytes.rs
Normal file
59
vm/src/obj/objbytes.rs
Normal file
@@ -0,0 +1,59 @@
|
||||
use super::super::pyobject::{
|
||||
AttributeProtocol, PyContext, PyFuncArgs, PyObjectKind, PyObjectRef, PyResult, TypeProtocol,
|
||||
};
|
||||
use super::super::vm::VirtualMachine;
|
||||
use super::objint;
|
||||
use super::objlist;
|
||||
use super::objtype;
|
||||
// Binary data support
|
||||
|
||||
// Fill bytes class methods:
|
||||
pub fn init(context: &PyContext) {
|
||||
let ref bytes_type = context.bytes_type;
|
||||
bytes_type.set_attr("__init__", context.new_rustfunc(bytes_init));
|
||||
bytes_type.set_attr("__str__", context.new_rustfunc(bytes_str));
|
||||
}
|
||||
|
||||
// __init__ (store value into objectkind)
|
||||
fn bytes_init(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(
|
||||
vm,
|
||||
args,
|
||||
required = [(zelf, Some(vm.ctx.bytes_type())), (arg, None)]
|
||||
);
|
||||
let val = if objtype::isinstance(arg.clone(), vm.ctx.list_type()) {
|
||||
let mut data_bytes = vec![];
|
||||
for elem in objlist::get_elements(arg) {
|
||||
let v = match objint::to_int(vm, &elem) {
|
||||
Ok(int_ref) => int_ref,
|
||||
Err(err) => return Err(err),
|
||||
};
|
||||
data_bytes.push(v as u8);
|
||||
}
|
||||
data_bytes
|
||||
} else {
|
||||
return Err(vm.new_type_error("Cannot construct bytes".to_string()));
|
||||
};
|
||||
set_value(zelf, val);
|
||||
Ok(vm.get_none())
|
||||
}
|
||||
|
||||
pub fn get_value(obj: &PyObjectRef) -> Vec<u8> {
|
||||
if let PyObjectKind::Bytes { value } = &obj.borrow().kind {
|
||||
value.clone()
|
||||
} else {
|
||||
panic!("Inner error getting int {:?}", obj);
|
||||
}
|
||||
}
|
||||
|
||||
fn set_value(obj: &PyObjectRef, value: Vec<u8>) {
|
||||
obj.borrow_mut().kind = PyObjectKind::Bytes { value };
|
||||
}
|
||||
|
||||
fn bytes_str(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(vm, args, required = [(obj, Some(vm.ctx.bytes_type()))]);
|
||||
let data = get_value(obj);
|
||||
let data: Vec<String> = data.into_iter().map(|b| format!("\\x{:02x}", b)).collect();
|
||||
let data = data.join("");
|
||||
Ok(vm.new_str(format!("b'{}'", data)))
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
use super::pyobject::{AttributeProtocol, PyContext, PyFuncArgs, PyResult};
|
||||
use super::vm::VirtualMachine;
|
||||
use super::super::pyobject::{AttributeProtocol, PyContext, PyFuncArgs, PyResult};
|
||||
use super::super::vm::VirtualMachine;
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
let ref function_type = context.function_type;
|
||||
@@ -19,15 +19,27 @@ fn int_init(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
args,
|
||||
required = [(zelf, Some(vm.ctx.int_type())), (arg, None)]
|
||||
);
|
||||
let val = if objtype::isinstance(arg.clone(), vm.ctx.int_type()) {
|
||||
get_value(arg)
|
||||
} else if objtype::isinstance(arg.clone(), vm.ctx.float_type()) {
|
||||
objfloat::get_value(arg) as i32
|
||||
|
||||
// Try to cast to int:
|
||||
let val = match to_int(vm, arg) {
|
||||
Ok(val) => val,
|
||||
Err(err) => return Err(err),
|
||||
};
|
||||
|
||||
set_value(zelf, val);
|
||||
Ok(vm.get_none())
|
||||
}
|
||||
|
||||
// Casting function:
|
||||
pub fn to_int(vm: &mut VirtualMachine, obj: &PyObjectRef) -> Result<i32, PyObjectRef> {
|
||||
let val = if objtype::isinstance(obj.clone(), vm.ctx.int_type()) {
|
||||
get_value(obj)
|
||||
} else if objtype::isinstance(obj.clone(), vm.ctx.float_type()) {
|
||||
objfloat::get_value(obj) as i32
|
||||
} else {
|
||||
return Err(vm.new_type_error("Cannot construct int".to_string()));
|
||||
};
|
||||
set_value(zelf, val);
|
||||
Ok(vm.get_none())
|
||||
Ok(val)
|
||||
}
|
||||
|
||||
// Retrieve inner int value:
|
||||
@@ -162,16 +174,64 @@ fn int_pow(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
}
|
||||
}
|
||||
|
||||
fn int_xor(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(
|
||||
vm,
|
||||
args,
|
||||
required = [(i, Some(vm.ctx.int_type())), (i2, None)]
|
||||
);
|
||||
let v1 = get_value(i);
|
||||
if objtype::isinstance(i2.clone(), vm.ctx.int_type()) {
|
||||
let v2 = get_value(i2);
|
||||
Ok(vm.ctx.new_int(v1 ^ v2))
|
||||
} else {
|
||||
Err(vm.new_type_error(format!("Cannot xor {:?} and {:?}", i, i2)))
|
||||
}
|
||||
}
|
||||
|
||||
fn int_or(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(
|
||||
vm,
|
||||
args,
|
||||
required = [(i, Some(vm.ctx.int_type())), (i2, None)]
|
||||
);
|
||||
let v1 = get_value(i);
|
||||
if objtype::isinstance(i2.clone(), vm.ctx.int_type()) {
|
||||
let v2 = get_value(i2);
|
||||
Ok(vm.ctx.new_int(v1 | v2))
|
||||
} else {
|
||||
Err(vm.new_type_error(format!("Cannot or {:?} and {:?}", i, i2)))
|
||||
}
|
||||
}
|
||||
|
||||
fn int_and(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(
|
||||
vm,
|
||||
args,
|
||||
required = [(i, Some(vm.ctx.int_type())), (i2, None)]
|
||||
);
|
||||
let v1 = get_value(i);
|
||||
if objtype::isinstance(i2.clone(), vm.ctx.int_type()) {
|
||||
let v2 = get_value(i2);
|
||||
Ok(vm.ctx.new_int(v1 & v2))
|
||||
} else {
|
||||
Err(vm.new_type_error(format!("Cannot and {:?} and {:?}", i, i2)))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
let ref int_type = context.int_type;
|
||||
int_type.set_attr("__eq__", context.new_rustfunc(int_eq));
|
||||
int_type.set_attr("__add__", context.new_rustfunc(int_add));
|
||||
int_type.set_attr("__and__", context.new_rustfunc(int_and));
|
||||
int_type.set_attr("__init__", context.new_rustfunc(int_init));
|
||||
int_type.set_attr("__mod__", context.new_rustfunc(int_mod));
|
||||
int_type.set_attr("__mul__", context.new_rustfunc(int_mul));
|
||||
int_type.set_attr("__or__", context.new_rustfunc(int_or));
|
||||
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));
|
||||
int_type.set_attr("__truediv__", context.new_rustfunc(int_truediv));
|
||||
int_type.set_attr("__xor__", context.new_rustfunc(int_xor));
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use super::super::objsequence::{seq_equal, PySliceableSequence};
|
||||
use super::super::pyobject::{
|
||||
AttributeProtocol, PyContext, PyFuncArgs, PyObjectKind, PyObjectRef, PyResult, TypeProtocol,
|
||||
};
|
||||
use super::super::vm::VirtualMachine;
|
||||
use super::objsequence::{seq_equal, PySliceableSequence};
|
||||
use super::objstr;
|
||||
use super::objtype;
|
||||
|
||||
@@ -26,7 +26,7 @@ pub fn set_item(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_elements(obj: PyObjectRef) -> Vec<PyObjectRef> {
|
||||
pub fn get_elements(obj: &PyObjectRef) -> Vec<PyObjectRef> {
|
||||
if let PyObjectKind::List { elements } = &obj.borrow().kind {
|
||||
elements.to_vec()
|
||||
} else {
|
||||
@@ -42,8 +42,8 @@ fn list_eq(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
);
|
||||
|
||||
let result = if objtype::isinstance(other.clone(), vm.ctx.list_type()) {
|
||||
let zelf = get_elements(zelf.clone());
|
||||
let other = get_elements(other.clone());
|
||||
let zelf = get_elements(zelf);
|
||||
let other = get_elements(other);
|
||||
seq_equal(vm, zelf, other)?
|
||||
} else {
|
||||
false
|
||||
@@ -59,8 +59,8 @@ fn list_add(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
);
|
||||
|
||||
if objtype::isinstance(o2.clone(), vm.ctx.list_type()) {
|
||||
let e1 = get_elements(o.clone());
|
||||
let e2 = get_elements(o2.clone());
|
||||
let e1 = get_elements(o);
|
||||
let e2 = get_elements(o2);
|
||||
let elements = e1.iter().chain(e2.iter()).map(|e| e.clone()).collect();
|
||||
Ok(vm.ctx.new_list(elements))
|
||||
} else {
|
||||
@@ -71,7 +71,7 @@ fn list_add(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
fn list_str(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(vm, args, required = [(o, Some(vm.ctx.list_type()))]);
|
||||
|
||||
let elements = get_elements(o.clone());
|
||||
let elements = get_elements(o);
|
||||
let mut str_parts = vec![];
|
||||
for elem in elements {
|
||||
match vm.to_str(elem) {
|
||||
@@ -115,12 +115,8 @@ fn clear(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
fn list_len(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
trace!("list.len called with: {:?}", args);
|
||||
arg_check!(vm, args, required = [(list, Some(vm.ctx.list_type()))]);
|
||||
let list_obj = list.borrow();
|
||||
if let PyObjectKind::List { ref elements } = list_obj.kind {
|
||||
Ok(vm.context().new_int(elements.len() as i32))
|
||||
} else {
|
||||
Err(vm.new_type_error("list.len is called with no list".to_string()))
|
||||
}
|
||||
let elements = get_elements(list);
|
||||
Ok(vm.context().new_int(elements.len() as i32))
|
||||
}
|
||||
|
||||
fn reverse(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use super::obj::objdict;
|
||||
use super::obj::objtype;
|
||||
use super::pyobject::{
|
||||
use super::super::pyobject::{
|
||||
AttributeProtocol, IdProtocol, PyContext, PyFuncArgs, PyObject, PyObjectKind, PyObjectRef,
|
||||
PyResult, TypeProtocol,
|
||||
};
|
||||
use super::vm::VirtualMachine;
|
||||
use super::super::vm::VirtualMachine;
|
||||
use super::objdict;
|
||||
use super::objtype;
|
||||
|
||||
pub fn new_instance(vm: &mut VirtualMachine, mut args: PyFuncArgs) -> PyResult {
|
||||
// more or less __new__ operator
|
||||
@@ -1,6 +1,6 @@
|
||||
use super::objbool;
|
||||
use super::pyobject::{PyObject, PyObjectKind, PyObjectRef, PyResult, TypeProtocol};
|
||||
use super::vm::VirtualMachine;
|
||||
use super::super::objbool;
|
||||
use super::super::pyobject::{PyObject, PyObjectKind, PyObjectRef, PyResult, TypeProtocol};
|
||||
use super::super::vm::VirtualMachine;
|
||||
use std::marker::Sized;
|
||||
|
||||
pub trait PySliceableSequence {
|
||||
@@ -100,14 +100,6 @@ pub fn get_item(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_elements(obj: PyObjectRef) -> Vec<PyObjectRef> {
|
||||
if let PyObjectKind::Tuple { elements } = &obj.borrow().kind {
|
||||
elements.to_vec()
|
||||
} else {
|
||||
panic!("Cannot extract list elements from non-list");
|
||||
}
|
||||
}
|
||||
|
||||
pub fn seq_equal(
|
||||
vm: &mut VirtualMachine,
|
||||
zelf: Vec<PyObjectRef>,
|
||||
@@ -1,9 +1,9 @@
|
||||
use super::super::objsequence::PySliceableSequence;
|
||||
use super::super::pyobject::{
|
||||
AttributeProtocol, PyContext, PyFuncArgs, PyObjectKind, PyObjectRef, PyResult, TypeProtocol,
|
||||
};
|
||||
use super::super::vm::VirtualMachine;
|
||||
use super::objint;
|
||||
use super::objsequence::PySliceableSequence;
|
||||
use super::objtype;
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use super::super::objsequence::{get_elements, seq_equal};
|
||||
use super::super::pyobject::{
|
||||
AttributeProtocol, PyContext, PyFuncArgs, PyObjectRef, PyResult, TypeProtocol,
|
||||
AttributeProtocol, PyContext, PyFuncArgs, PyObjectKind, PyObjectRef, PyResult, TypeProtocol,
|
||||
};
|
||||
use super::super::vm::VirtualMachine;
|
||||
use super::objsequence::seq_equal;
|
||||
use super::objstr;
|
||||
use super::objtype;
|
||||
|
||||
@@ -14,8 +14,8 @@ fn tuple_eq(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
);
|
||||
|
||||
let result = if objtype::isinstance(other.clone(), vm.ctx.tuple_type()) {
|
||||
let zelf = get_elements(zelf.clone());
|
||||
let other = get_elements(other.clone());
|
||||
let zelf = get_elements(zelf);
|
||||
let other = get_elements(other);
|
||||
seq_equal(vm, zelf, other)?
|
||||
} else {
|
||||
false
|
||||
@@ -24,21 +24,16 @@ fn tuple_eq(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
}
|
||||
|
||||
fn tuple_len(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
trace!("tuple.len called with: {:?}", args);
|
||||
arg_check!(vm, args, required = [(zelf, Some(vm.ctx.tuple_type()))]);
|
||||
let elements = get_elements(zelf.clone());
|
||||
let elements = get_elements(zelf);
|
||||
Ok(vm.context().new_int(elements.len() as i32))
|
||||
}
|
||||
|
||||
fn tuple_str(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(vm, args, required = [(zelf, Some(vm.ctx.tuple_type()))]);
|
||||
|
||||
let elements = get_elements(zelf.clone());
|
||||
if elements.len() == 1 {
|
||||
let ref part = vm.to_str(elements[0].clone())?;
|
||||
let s = format!("({},)", objstr::get_value(part));
|
||||
return Ok(vm.new_str(s));
|
||||
}
|
||||
let elements = get_elements(zelf);
|
||||
|
||||
let mut str_parts = vec![];
|
||||
for elem in elements {
|
||||
match vm.to_str(elem) {
|
||||
@@ -47,10 +42,22 @@ fn tuple_str(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
}
|
||||
}
|
||||
|
||||
let s = format!("({})", str_parts.join(", "));
|
||||
let s = if str_parts.len() == 1 {
|
||||
format!("({},)", str_parts[0])
|
||||
} else {
|
||||
format!("({})", str_parts.join(", "))
|
||||
};
|
||||
Ok(vm.new_str(s))
|
||||
}
|
||||
|
||||
pub fn get_elements(obj: &PyObjectRef) -> Vec<PyObjectRef> {
|
||||
if let PyObjectKind::Tuple { elements } = &obj.borrow().kind {
|
||||
elements.to_vec()
|
||||
} else {
|
||||
panic!("Cannot extract elements from non-tuple");
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
let ref tuple_type = context.tuple_type;
|
||||
tuple_type.set_attr("__eq__", context.new_rustfunc(tuple_eq));
|
||||
|
||||
@@ -112,10 +112,22 @@ pub fn type_call(vm: &mut VirtualMachine, mut args: PyFuncArgs) -> PyResult {
|
||||
debug!("type_call: {:?}", args);
|
||||
let typ = args.shift();
|
||||
let new = typ.get_attr("__new__").unwrap();
|
||||
let obj = vm.invoke(new, args.insert(typ.clone()))?;
|
||||
let obj = match vm.invoke(new, args.insert(typ.clone())) {
|
||||
Ok(res) => res,
|
||||
Err(err) => return Err(err),
|
||||
};
|
||||
|
||||
if let Some(init) = obj.typ().get_attr("__init__") {
|
||||
let _ = vm.invoke(init, args.insert(obj.clone())).unwrap();
|
||||
match vm.invoke(init, args.insert(obj.clone())) {
|
||||
Ok(res) => {
|
||||
// TODO: assert that return is none?
|
||||
if !isinstance(res, vm.get_none()) {
|
||||
// panic!("__init__ must return none");
|
||||
// return Err(vm.new_type_error("__init__ must return None".to_string()));
|
||||
}
|
||||
}
|
||||
Err(err) => return Err(err),
|
||||
}
|
||||
}
|
||||
Ok(obj)
|
||||
}
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
use super::bytecode;
|
||||
use super::exceptions;
|
||||
use super::obj::objbytes;
|
||||
use super::obj::objdict;
|
||||
use super::obj::objfloat;
|
||||
use super::obj::objfunction;
|
||||
use super::obj::objint;
|
||||
use super::obj::objlist;
|
||||
use super::obj::objobject;
|
||||
use super::obj::objstr;
|
||||
use super::obj::objtuple;
|
||||
use super::obj::objtype;
|
||||
use super::objbool;
|
||||
use super::objfunction;
|
||||
use super::objobject;
|
||||
use super::vm::VirtualMachine;
|
||||
use std::cell::RefCell;
|
||||
use std::cmp::Ordering;
|
||||
@@ -53,6 +54,7 @@ pub struct PyContext {
|
||||
pub dict_type: PyObjectRef,
|
||||
pub int_type: PyObjectRef,
|
||||
pub float_type: PyObjectRef,
|
||||
pub bytes_type: PyObjectRef,
|
||||
pub bool_type: PyObjectRef,
|
||||
pub list_type: PyObjectRef,
|
||||
pub tuple_type: PyObjectRef,
|
||||
@@ -115,6 +117,7 @@ impl PyContext {
|
||||
let list_type = create_type("list", &type_type, &object_type, &dict_type);
|
||||
let int_type = create_type("int", &type_type, &object_type, &dict_type);
|
||||
let float_type = create_type("float", &type_type, &object_type, &dict_type);
|
||||
let bytes_type = create_type("bytes", &type_type, &object_type, &dict_type);
|
||||
let tuple_type = create_type("tuple", &type_type, &object_type, &dict_type);
|
||||
let bool_type = create_type("bool", &type_type, &object_type, &dict_type);
|
||||
let exceptions = exceptions::ExceptionZoo::new(&type_type, &object_type, &dict_type);
|
||||
@@ -127,6 +130,7 @@ impl PyContext {
|
||||
let context = PyContext {
|
||||
int_type: int_type,
|
||||
float_type: float_type,
|
||||
bytes_type: bytes_type,
|
||||
list_type: list_type,
|
||||
bool_type: bool_type,
|
||||
tuple_type: tuple_type,
|
||||
@@ -148,11 +152,11 @@ impl PyContext {
|
||||
objfunction::init(&context);
|
||||
objint::init(&context);
|
||||
objfloat::init(&context);
|
||||
objbytes::init(&context);
|
||||
objstr::init(&context);
|
||||
objtuple::init(&context);
|
||||
objbool::init(&context);
|
||||
exceptions::init(&context);
|
||||
// TODO: create exception hierarchy here?
|
||||
// exceptions::create_zoo(&context);
|
||||
context
|
||||
}
|
||||
|
||||
@@ -164,6 +168,10 @@ impl PyContext {
|
||||
self.float_type.clone()
|
||||
}
|
||||
|
||||
pub fn bytes_type(&self) -> PyObjectRef {
|
||||
self.bytes_type.clone()
|
||||
}
|
||||
|
||||
pub fn list_type(&self) -> PyObjectRef {
|
||||
self.list_type.clone()
|
||||
}
|
||||
@@ -558,6 +566,9 @@ pub enum PyObjectKind {
|
||||
Boolean {
|
||||
value: bool,
|
||||
},
|
||||
Bytes {
|
||||
value: Vec<u8>,
|
||||
},
|
||||
List {
|
||||
elements: Vec<PyObjectRef>,
|
||||
},
|
||||
@@ -615,6 +626,7 @@ impl fmt::Debug for PyObjectKind {
|
||||
&PyObjectKind::String { ref value } => write!(f, "str \"{}\"", value),
|
||||
&PyObjectKind::Integer { ref value } => write!(f, "int {}", value),
|
||||
&PyObjectKind::Float { ref value } => write!(f, "float {}", value),
|
||||
&PyObjectKind::Bytes { ref value } => write!(f, "bytes {:?}", value),
|
||||
&PyObjectKind::Boolean { ref value } => write!(f, "boolean {}", value),
|
||||
&PyObjectKind::List { elements: _ } => write!(f, "list"),
|
||||
&PyObjectKind::Tuple { elements: _ } => write!(f, "tuple"),
|
||||
@@ -662,6 +674,7 @@ impl PyObject {
|
||||
PyObjectKind::String { ref value } => value.clone(),
|
||||
PyObjectKind::Integer { ref value } => format!("{:?}", value),
|
||||
PyObjectKind::Float { ref value } => format!("{:?}", value),
|
||||
PyObjectKind::Bytes { ref value } => format!("b'{:?}'", value),
|
||||
PyObjectKind::Boolean { ref value } => format!("{:?}", value),
|
||||
PyObjectKind::List { ref elements } => format!(
|
||||
"[{}]",
|
||||
@@ -773,11 +786,6 @@ impl PartialEq for PyObject {
|
||||
(PyObjectKind::String { value: ref v1i }, PyObjectKind::String { value: ref v2i }) => {
|
||||
*v2i == *v1i
|
||||
}
|
||||
/*
|
||||
(&NativeType::Float(ref v1f), &NativeType::Float(ref v2f)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Boolean(v2f == v1f)));
|
||||
},
|
||||
*/
|
||||
(PyObjectKind::List { elements: ref l1 }, PyObjectKind::List { elements: ref l2 })
|
||||
| (
|
||||
PyObjectKind::Tuple { elements: ref l1 },
|
||||
|
||||
@@ -6,13 +6,13 @@ use serde::de::Visitor;
|
||||
use serde::ser::{SerializeMap, SerializeSeq};
|
||||
use serde_json;
|
||||
|
||||
use super::super::obj::{objdict, objfloat, objint, objlist, objstr, objtype};
|
||||
use super::super::obj::{objdict, objfloat, objint, objlist, objstr, objtuple, objtype};
|
||||
use super::super::objbool;
|
||||
use super::super::pyobject::{
|
||||
DictProtocol, PyContext, PyFuncArgs, PyObject, PyObjectKind, PyObjectRef, PyResult,
|
||||
TypeProtocol,
|
||||
};
|
||||
use super::super::VirtualMachine;
|
||||
use super::super::{objbool, objsequence};
|
||||
|
||||
// We need to have a VM available to serialise a PyObject based on its subclass, so we implement
|
||||
// PyObject serialisation via a proxy object which holds a reference to a VM
|
||||
@@ -52,10 +52,10 @@ impl<'s> serde::Serialize for PyObjectSerializer<'s> {
|
||||
} else if objtype::isinstance(self.pyobject.clone(), self.vm.ctx.bool_type()) {
|
||||
serializer.serialize_bool(objbool::get_value(self.pyobject))
|
||||
} else if objtype::isinstance(self.pyobject.clone(), self.vm.ctx.list_type()) {
|
||||
let elements = objlist::get_elements(self.pyobject.clone());
|
||||
let elements = objlist::get_elements(self.pyobject);
|
||||
serialize_seq_elements(serializer, elements)
|
||||
} else if objtype::isinstance(self.pyobject.clone(), self.vm.ctx.tuple_type()) {
|
||||
let elements = objsequence::get_elements(self.pyobject.clone());
|
||||
let elements = objtuple::get_elements(self.pyobject);
|
||||
serialize_seq_elements(serializer, elements)
|
||||
} else if objtype::isinstance(self.pyobject.clone(), self.vm.ctx.dict_type()) {
|
||||
let elements = objdict::get_elements(self.pyobject);
|
||||
|
||||
19
vm/src/vm.rs
19
vm/src/vm.rs
@@ -16,10 +16,10 @@ use super::bytecode;
|
||||
use super::frame::{copy_code, Block, Frame};
|
||||
use super::import::import;
|
||||
use super::obj::objlist;
|
||||
use super::obj::objobject;
|
||||
use super::obj::objstr;
|
||||
use super::obj::objtype;
|
||||
use super::objbool;
|
||||
use super::objobject;
|
||||
use super::pyobject::{
|
||||
AttributeProtocol, DictProtocol, IdProtocol, ParentProtocol, PyContext, PyFuncArgs, PyObject,
|
||||
PyObjectKind, PyObjectRef, PyResult, ToRust,
|
||||
@@ -296,7 +296,7 @@ impl VirtualMachine {
|
||||
match &a2.kind {
|
||||
PyObjectKind::String { ref value } => objstr::subscript(self, value, b),
|
||||
PyObjectKind::List { ref elements } | PyObjectKind::Tuple { ref elements } => {
|
||||
super::objsequence::get_item(self, &a, elements, b)
|
||||
super::obj::objsequence::get_item(self, &a, elements, b)
|
||||
}
|
||||
_ => Err(self.new_type_error(format!(
|
||||
"TypeError: indexing type {:?} with index {:?} is not supported (yet?)",
|
||||
@@ -367,6 +367,18 @@ impl VirtualMachine {
|
||||
self.call_method(a, "__mod__", vec![b])
|
||||
}
|
||||
|
||||
fn _xor(&mut self, a: PyObjectRef, b: PyObjectRef) -> PyResult {
|
||||
self.call_method(a, "__xor__", vec![b])
|
||||
}
|
||||
|
||||
fn _or(&mut self, a: PyObjectRef, b: PyObjectRef) -> PyResult {
|
||||
self.call_method(a, "__or__", vec![b])
|
||||
}
|
||||
|
||||
fn _and(&mut self, a: PyObjectRef, b: PyObjectRef) -> PyResult {
|
||||
self.call_method(a, "__and__", vec![b])
|
||||
}
|
||||
|
||||
fn execute_binop(&mut self, op: &bytecode::BinaryOperator) -> Option<PyResult> {
|
||||
let b_ref = self.pop_value();
|
||||
let a_ref = self.pop_value();
|
||||
@@ -380,6 +392,9 @@ impl VirtualMachine {
|
||||
&bytecode::BinaryOperator::Divide => self._div(a_ref, b_ref),
|
||||
&bytecode::BinaryOperator::Subscript => self.subscript(a_ref, b_ref),
|
||||
&bytecode::BinaryOperator::Modulo => self._modulo(a_ref, b_ref),
|
||||
&bytecode::BinaryOperator::Xor => self._xor(a_ref, b_ref),
|
||||
&bytecode::BinaryOperator::Or => self._or(a_ref, b_ref),
|
||||
&bytecode::BinaryOperator::And => self._and(a_ref, b_ref),
|
||||
_ => panic!("NOT IMPL {:?}", op),
|
||||
};
|
||||
match result {
|
||||
|
||||
Reference in New Issue
Block a user