Skip to content

Commit f563856

Browse files
committed
Add some tuple class methods
1 parent 40cf7f4 commit f563856

File tree

6 files changed

+60
-19
lines changed

6 files changed

+60
-19
lines changed

vm/src/obj/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ pub mod objlist;
77
pub mod objobject;
88
pub mod objsequence;
99
pub mod objstr;
10+
pub mod objtuple;
1011
pub mod objtype;

vm/src/obj/objbytes.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use super::super::pyobject::{
2-
AttributeProtocol, FromPyObjectRef, PyContext, PyFuncArgs, PyObjectKind, PyObjectRef, PyResult,
3-
TypeProtocol,
2+
AttributeProtocol, PyContext, PyFuncArgs, PyObjectKind, PyObjectRef, PyResult, TypeProtocol,
43
};
54
use super::super::vm::VirtualMachine;
65
use super::objint;
@@ -24,7 +23,7 @@ fn bytes_init(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
2423
);
2524
let val = if objtype::isinstance(arg.clone(), vm.ctx.list_type()) {
2625
let mut data_bytes = vec![];
27-
for elem in objlist::get_elements(arg.clone()) {
26+
for elem in objlist::get_elements(arg) {
2827
let v = match objint::to_int(vm, &elem) {
2928
Ok(int_ref) => int_ref,
3029
Err(err) => return Err(err),

vm/src/obj/objlist.rs

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub fn set_item(
2626
}
2727
}
2828

29-
pub fn get_elements(obj: PyObjectRef) -> Vec<PyObjectRef> {
29+
pub fn get_elements(obj: &PyObjectRef) -> Vec<PyObjectRef> {
3030
if let PyObjectKind::List { elements } = &obj.borrow().kind {
3131
elements.to_vec()
3232
} else {
@@ -42,8 +42,8 @@ fn list_add(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
4242
);
4343

4444
if objtype::isinstance(o2.clone(), vm.ctx.list_type()) {
45-
let e1 = get_elements(o.clone());
46-
let e2 = get_elements(o2.clone());
45+
let e1 = get_elements(o);
46+
let e2 = get_elements(o2);
4747
let elements = e1.iter().chain(e2.iter()).map(|e| e.clone()).collect();
4848
Ok(vm.ctx.new_list(elements))
4949
} else {
@@ -54,7 +54,7 @@ fn list_add(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
5454
fn list_str(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
5555
arg_check!(vm, args, required = [(o, Some(vm.ctx.list_type()))]);
5656

57-
let elements = get_elements(o.clone());
57+
let elements = get_elements(o);
5858
let mut str_parts = vec![];
5959
for elem in elements {
6060
match vm.to_str(elem) {
@@ -95,15 +95,10 @@ fn clear(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
9595
}
9696
}
9797

98-
fn len(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
99-
trace!("list.len called with: {:?}", args);
98+
fn list_len(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
10099
arg_check!(vm, args, required = [(list, Some(vm.ctx.list_type()))]);
101-
let list_obj = list.borrow();
102-
if let PyObjectKind::List { ref elements } = list_obj.kind {
103-
Ok(vm.context().new_int(elements.len() as i32))
104-
} else {
105-
Err(vm.new_type_error("list.len is called with no list".to_string()))
106-
}
100+
let elements = get_elements(list);
101+
Ok(vm.context().new_int(elements.len() as i32))
107102
}
108103

109104
fn reverse(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
@@ -121,7 +116,7 @@ fn reverse(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
121116
pub fn init(context: &PyContext) {
122117
let ref list_type = context.list_type;
123118
list_type.set_attr("__add__", context.new_rustfunc(list_add));
124-
list_type.set_attr("__len__", context.new_rustfunc(len));
119+
list_type.set_attr("__len__", context.new_rustfunc(list_len));
125120
list_type.set_attr("__str__", context.new_rustfunc(list_str));
126121
list_type.set_attr("append", context.new_rustfunc(append));
127122
list_type.set_attr("clear", context.new_rustfunc(clear));

vm/src/obj/objtuple.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
use super::super::pyobject::{
2+
AttributeProtocol, PyContext, PyFuncArgs, PyObjectKind, PyObjectRef, PyResult, TypeProtocol,
3+
};
4+
use super::super::vm::VirtualMachine;
5+
use super::objstr;
6+
use super::objtype;
7+
8+
fn tuple_str(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
9+
arg_check!(vm, args, required = [(o, Some(vm.ctx.tuple_type()))]);
10+
11+
let elements = get_elements(o);
12+
let mut str_parts = vec![];
13+
for elem in elements {
14+
match vm.to_str(elem) {
15+
Ok(s) => str_parts.push(objstr::get_value(&s)),
16+
Err(err) => return Err(err),
17+
}
18+
}
19+
20+
let s = if str_parts.len() == 1 {
21+
format!("({},)", str_parts.join(", "))
22+
} else {
23+
format!("({})", str_parts.join(", "))
24+
};
25+
Ok(vm.new_str(s))
26+
}
27+
28+
pub fn get_elements(obj: &PyObjectRef) -> Vec<PyObjectRef> {
29+
if let PyObjectKind::List { elements } = &obj.borrow().kind {
30+
elements.to_vec()
31+
} else {
32+
panic!("Cannot extract elements from non-tuple");
33+
}
34+
}
35+
36+
fn tuple_len(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
37+
arg_check!(vm, args, required = [(tuple, Some(vm.ctx.tuple_type()))]);
38+
let elements = get_elements(tuple);
39+
Ok(vm.context().new_int(elements.len() as i32))
40+
}
41+
42+
pub fn init(context: &PyContext) {
43+
let ref tuple_type = context.tuple_type;
44+
tuple_type.set_attr("__len__", context.new_rustfunc(tuple_len));
45+
tuple_type.set_attr("__str__", context.new_rustfunc(tuple_str));
46+
}

vm/src/pyobject.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use super::obj::objint;
88
use super::obj::objlist;
99
use super::obj::objobject;
1010
use super::obj::objstr;
11+
use super::obj::objtuple;
1112
use super::obj::objtype;
1213
use super::objbool;
1314
use super::vm::VirtualMachine;
@@ -152,10 +153,9 @@ impl PyContext {
152153
objfloat::init(&context);
153154
objbytes::init(&context);
154155
objstr::init(&context);
156+
objtuple::init(&context);
155157
objbool::init(&context);
156158
exceptions::init(&context);
157-
// TODO: create exception hierarchy here?
158-
// exceptions::create_zoo(&context);
159159
context
160160
}
161161

vm/src/stdlib/json.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ impl<'s> serde::Serialize for PyObjectSerializer<'s> {
5252
} else if objtype::isinstance(self.pyobject.clone(), self.vm.ctx.bool_type()) {
5353
serializer.serialize_bool(objbool::get_value(self.pyobject))
5454
} else if objtype::isinstance(self.pyobject.clone(), self.vm.ctx.list_type()) {
55-
let elements = objlist::get_elements(self.pyobject.clone());
55+
let elements = objlist::get_elements(self.pyobject);
5656
serialize_seq_elements(serializer, elements)
5757
} else if objtype::isinstance(self.pyobject.clone(), self.vm.ctx.tuple_type()) {
5858
let elements = objsequence::get_elements(self.pyobject.clone());

0 commit comments

Comments
 (0)