Merge pull request #62 from RustPython/list_append

Register append function to list type
This commit is contained in:
cthulahoops
2018-08-14 22:16:11 +01:00
committed by GitHub
7 changed files with 91 additions and 40 deletions

View File

@@ -10,4 +10,4 @@ pytest = "*"
[dev-packages]
[requires]
python_version = "3.6"
python_version = "3"

29
tests/Pipfile.lock generated
View File

@@ -1,11 +1,11 @@
{
"_meta": {
"hash": {
"sha256": "ce98de5914393363a8cb86a4753b3964caa53a4659a403a3ef357e2086363ef7"
"sha256": "b2d2d68e7d4330ff8d889816c56b9cee4bf54962c86b2c11382108176a201ec8"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.6"
"python_version": "3"
},
"sources": [
{
@@ -48,36 +48,35 @@
},
"more-itertools": {
"hashes": [
"sha256:2b6b9893337bfd9166bee6a62c2b0c9fe7735dcf85948b387ec8cba30e85d8e8",
"sha256:6703844a52d3588f951883005efcf555e49566a48afd4db4e965d69b883980d3",
"sha256:a18d870ef2ffca2b8463c0070ad17b5978056f403fb64e3f15fe62a52db21cc0"
"sha256:c187a73da93e7a8acc0001572aebc7e3c69daf7bf6881a2cea10650bd4420092",
"sha256:c476b5d3a34e12d40130bc2f935028b5f636df8f372dc2c1c01dc19681b2039e",
"sha256:fcbfeaea0be121980e15bc97b3817b5202ca73d0eae185b4550cbfce2a3ebb3d"
],
"version": "==4.2.0"
"version": "==4.3.0"
},
"pluggy": {
"hashes": [
"sha256:7f8ae7f5bdf75671a718d2daf0a64b7885f74510bcd98b1a0bb420eb9a9d0cff",
"sha256:d345c8fe681115900d6da8d048ba67c25df42973bda370783cd58826442dcd7c",
"sha256:e160a7fcf25762bb60efc7e171d4497ff1d8d2d75a3d0df7a21b76821ecbf5c5"
"sha256:6e3836e39f4d36ae72840833db137f7b7d35105079aee6ec4a62d9f80d594dd1",
"sha256:95eb8364a4708392bae89035f45341871286a333f749c3141c20573d2b3876e1"
],
"markers": "python_version != '3.2.*' and python_version != '3.0.*' and python_version != '3.1.*' and python_version != '3.3.*' and python_version >= '2.7'",
"version": "==0.6.0"
"markers": "python_version != '3.3.*' and python_version != '3.0.*' and python_version >= '2.7' and python_version != '3.1.*' and python_version != '3.2.*'",
"version": "==0.7.1"
},
"py": {
"hashes": [
"sha256:3fd59af7435864e1a243790d322d763925431213b6b8529c6ca71081ace3bbf7",
"sha256:e31fb2767eb657cbde86c454f02e99cb846d3cd9d61b318525140214fdc0e98e"
],
"markers": "python_version != '3.2.*' and python_version != '3.0.*' and python_version != '3.1.*' and python_version != '3.3.*' and python_version >= '2.7'",
"markers": "python_version != '3.3.*' and python_version != '3.0.*' and python_version >= '2.7' and python_version != '3.1.*' and python_version != '3.2.*'",
"version": "==1.5.4"
},
"pytest": {
"hashes": [
"sha256:0453c8676c2bee6feb0434748b068d5510273a916295fd61d306c4f22fbfd752",
"sha256:4b208614ae6d98195430ad6bde03641c78553acee7c83cec2e85d613c0cd383d"
"sha256:86a8dbf407e437351cef4dba46736e9c5a6e3c3ac71b2e942209748e76ff2086",
"sha256:e74466e97ac14582a8188ff4c53e6cc3810315f342f6096899332ae864c1d432"
],
"index": "pypi",
"version": "==3.6.3"
"version": "==3.7.1"
},
"six": {
"hashes": [

View File

@@ -30,8 +30,12 @@ fn dir_locals(vm: &mut VirtualMachine) -> PyObjectRef {
}
fn dir_object(vm: &mut VirtualMachine, _obj: PyObjectRef) -> PyObjectRef {
// TODO: Implement dir for objects
let d = vm.new_dict();
// TODO: loop over dict of instance, next of class?
// TODO: Implement dir for objects
// for i in obj.iter_items() {
// d.set_item(k, v);
// }
d
}

View File

@@ -1,6 +1,7 @@
use super::objsequence::PySliceableSequence;
use super::pyobject::{PyObjectKind, PyObjectRef, PyResult};
use super::pyobject::{PyFuncArgs, PyObject, PyObjectKind, PyObjectRef, PyResult};
use super::vm::VirtualMachine;
use std::collections::HashMap;
// set_item:
pub fn set_item(
@@ -22,15 +23,61 @@ pub fn set_item(
}
}
pub fn _append(vm: &mut VirtualMachine, _l: PyObjectRef, _other: PyObjectRef) -> PyResult {
// TODO: Implement objlist::append
Ok(vm.get_none())
fn append(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
trace!("list.append called with: {:?}", args);
if args.args.len() == 2 {
let l = args.args[0].clone();
let o = args.args[1].clone();
let mut list_obj = l.borrow_mut();
if let PyObjectKind::List { ref mut elements } = list_obj.kind {
elements.push(o);
Ok(vm.get_none())
} else {
Err(vm.new_exception("list.append is called with no list".to_string()))
}
} else {
Err(vm.new_exception("list.append requires two arguments".to_string()))
}
}
/* TODO:
pub fn make_type() -> PyObjectRef {
// dict.insert("__set_item__".to_string(), set_item);
dict.insert("append".to_string(), _append)
fn reverse(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
trace!("list.reverse called with: {:?}", args);
if args.args.len() == 1 {
let l = args.args[0].clone();
let mut list_obj = l.borrow_mut();
if let PyObjectKind::List { ref mut elements } = list_obj.kind {
elements.reverse();
Ok(vm.get_none())
} else {
Err(vm.new_exception("list.reverse is called with no list".to_string()))
}
} else {
Err(vm.new_exception("list.reverse requires one arguments".to_string()))
}
}
pub fn create_type(type_type: PyObjectRef, method_type: PyObjectRef) -> PyObjectRef {
let mut dict = HashMap::new();
dict.insert(
"append".to_string(),
PyObject::new(
PyObjectKind::RustFunction { function: append },
method_type.clone(),
),
);
dict.insert(
"reverse".to_string(),
PyObject::new(
PyObjectKind::RustFunction { function: reverse },
method_type.clone(),
),
);
let typ = PyObject::new(
PyObjectKind::Class {
name: "list".to_string(),
dict: PyObject::new(PyObjectKind::Dict { elements: dict }, type_type.clone()),
},
type_type.clone(),
);
typ
}
*/

View File

@@ -1,6 +1,7 @@
use super::bytecode;
use super::objfunction;
use super::objint;
use super::objlist;
use super::objtype;
use super::vm::VirtualMachine;
use std::cell::RefCell;
@@ -65,15 +66,17 @@ pub struct Scope {
impl PyContext {
pub fn new() -> PyContext {
let type_type = objtype::create_type();
let function_type = objfunction::create_type(type_type.clone());
let bound_method_type = objfunction::create_bound_method_type(type_type.clone());
PyContext {
int_type: objint::create_type(type_type.clone()),
list_type: type_type.clone(),
list_type: objlist::create_type(type_type.clone(), function_type.clone()),
tuple_type: type_type.clone(),
dict_type: type_type.clone(),
none: PyObject::new(PyObjectKind::None, type_type.clone()),
function_type: objfunction::create_type(type_type.clone()),
bound_method_type: objfunction::create_bound_method_type(type_type.clone()),
function_type: function_type,
bound_method_type: bound_method_type,
type_type: type_type,
}
}
@@ -90,10 +93,10 @@ impl PyContext {
PyObject::new(PyObjectKind::Boolean { value: b }, self.type_type.clone())
}
pub fn new_tuple(&self) -> PyObjectRef {
pub fn new_tuple(&self, elements: Option<Vec<PyObjectRef>>) -> PyObjectRef {
PyObject::new(
PyObjectKind::Tuple {
elements: Vec::new(),
elements: elements.unwrap_or(Vec::new()),
},
self.type_type.clone(),
)
@@ -104,7 +107,7 @@ impl PyContext {
PyObjectKind::List {
elements: elements.unwrap_or(Vec::new()),
},
self.type_type.clone(),
self.list_type.clone(),
)
}
@@ -262,7 +265,7 @@ impl AttributeProtocol for PyObjectRef {
PyObjectKind::Module { name: _, ref dict } => dict.contains_key(attr_name),
PyObjectKind::Class { name: _, ref dict } => dict.contains_key(attr_name),
PyObjectKind::Instance { ref dict } => dict.contains_key(attr_name),
ref kind => unimplemented!("load_attr unimplemented for: {:?}", kind),
_ => false,
}
}
@@ -286,7 +289,7 @@ impl DictProtocol for PyObjectRef {
PyObjectKind::Dict { ref elements } => elements.contains_key(k),
PyObjectKind::Module { name: _, ref dict } => dict.contains_key(k),
PyObjectKind::Scope { ref scope } => scope.locals.contains_key(k),
_ => panic!("TODO"),
ref kind => unimplemented!("TODO {:?}", kind),
}
}
@@ -427,7 +430,7 @@ impl fmt::Debug for PyObjectKind {
&PyObjectKind::Module { name: _, dict: _ } => write!(f, "module"),
&PyObjectKind::Scope { scope: _ } => write!(f, "scope"),
&PyObjectKind::None => write!(f, "None"),
&PyObjectKind::Class { name: _, dict: _ } => write!(f, "class"),
&PyObjectKind::Class { ref name, dict: _ } => write!(f, "class {:?}", name),
&PyObjectKind::Instance { dict: _ } => write!(f, "instance"),
&PyObjectKind::RustFunction { function: _ } => write!(f, "rust function"),
}

View File

@@ -594,15 +594,13 @@ impl VirtualMachine {
}
bytecode::Instruction::BuildList { size } => {
let elements = self.pop_multiple(*size);
let list_obj =
PyObject::new(PyObjectKind::List { elements: elements }, self.get_type());
let list_obj = self.context().new_list(Some(elements));
self.push_value(list_obj);
None
}
bytecode::Instruction::BuildTuple { size } => {
let elements = self.pop_multiple(*size);
let list_obj =
PyObject::new(PyObjectKind::Tuple { elements: elements }, self.get_type());
let list_obj = self.context().new_tuple(Some(elements));
self.push_value(list_obj);
None
}