Skip to content

Commit 5707548

Browse files
committed
Add set.add method
1 parent fca3e7a commit 5707548

5 files changed

Lines changed: 43 additions & 6 deletions

File tree

parser/src/python.lalrpop

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,7 @@ Atom: ast::Expression = {
592592
}
593593
},
594594
"{" <e:TestDict?> "}" => ast::Expression::Dict { elements: e.unwrap_or(Vec::new()) },
595+
"{" <e:TestDictComp> "}" => e,
595596
"{" <e:TestSet> "}" => ast::Expression::Set { elements: e },
596597
"{" <e:TestSetComp> "}" => e,
597598
"True" => ast::Expression::True,
@@ -623,6 +624,15 @@ TestDict: Vec<(ast::Expression, ast::Expression)> = {
623624
}
624625
};
625626

627+
TestDictComp: ast::Expression = {
628+
<e1:DictEntry> <c:CompFor> => {
629+
ast::Expression::Comprehension {
630+
kind: Box::new(ast::ComprehensionKind::Dict { key: e1.0, value: e1.1 }),
631+
generators: c,
632+
}
633+
}
634+
};
635+
626636
DictEntry: (ast::Expression, ast::Expression) = {
627637
<e1: Test> ":" <e2: Test> => (e1, e2),
628638
};

tests/snippets/comprehensions.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,11 @@
1010
(1, 2), (1, 5), (1, 10),
1111
(2, 2), (2, 5), (2, 10),
1212
(3, 2), (3, 5), (3, 10)]
13+
14+
v = {b * 2 for b in x}
15+
# TODO: how to check set equality?
16+
# assert v == {2, 6, 4}
17+
18+
# TODO:
19+
#u = {str(b): b-2 for b in x}
20+

vm/src/obj/objlist.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ fn list_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
116116
Ok(vm.new_str(s))
117117
}
118118

119-
pub fn append(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
119+
pub fn list_append(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
120120
trace!("list.append called with: {:?}", args);
121121
arg_check!(
122122
vm,
@@ -151,7 +151,7 @@ fn list_len(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
151151
Ok(vm.context().new_int(elements.len() as i32))
152152
}
153153

154-
fn reverse(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
154+
fn list_reverse(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
155155
trace!("list.reverse called with: {:?}", args);
156156
arg_check!(vm, args, required = [(list, Some(vm.ctx.list_type()))]);
157157
let mut list_obj = list.borrow_mut();
@@ -192,7 +192,7 @@ pub fn init(context: &PyContext) {
192192
list_type.set_attr("__len__", context.new_rustfunc(list_len));
193193
list_type.set_attr("__new__", context.new_rustfunc(list_new));
194194
list_type.set_attr("__repr__", context.new_rustfunc(list_repr));
195-
list_type.set_attr("append", context.new_rustfunc(append));
195+
list_type.set_attr("append", context.new_rustfunc(list_append));
196196
list_type.set_attr("clear", context.new_rustfunc(clear));
197-
list_type.set_attr("reverse", context.new_rustfunc(reverse));
197+
list_type.set_attr("reverse", context.new_rustfunc(list_reverse));
198198
}

vm/src/obj/objset.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,24 @@ pub fn sequence_to_hashmap(iterable: &Vec<PyObjectRef>) -> HashMap<usize, PyObje
3030
elements
3131
}
3232

33+
fn set_add(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
34+
trace!("set.add called with: {:?}", args);
35+
arg_check!(
36+
vm,
37+
args,
38+
required = [(s, Some(vm.ctx.set_type())), (item, None)]
39+
);
40+
let mut mut_obj = s.borrow_mut();
41+
42+
if let PyObjectKind::Set { ref mut elements } = mut_obj.kind {
43+
let key = item.get_id();
44+
elements.insert(key, item.clone());
45+
Ok(vm.get_none())
46+
} else {
47+
Err(vm.new_type_error("set.add is called with no list".to_string()))
48+
}
49+
}
50+
3351
/* Create a new object of sub-type of set */
3452
fn set_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
3553
arg_check!(
@@ -115,4 +133,5 @@ pub fn init(context: &PyContext) {
115133
set_type.set_attr("__len__", context.new_rustfunc(set_len));
116134
set_type.set_attr("__new__", context.new_rustfunc(set_new));
117135
set_type.set_attr("__repr__", context.new_rustfunc(set_repr));
136+
set_type.set_attr("add", context.new_rustfunc(set_add));
118137
}

vm/src/vm.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ impl VirtualMachine {
371371
self.ctx.new_int(lineno.get_row() as i32),
372372
self.ctx.new_str(run_obj_name.clone()),
373373
]);
374-
objlist::append(
374+
objlist::list_append(
375375
self,
376376
PyFuncArgs {
377377
args: vec![traceback, pos],
@@ -946,7 +946,7 @@ impl VirtualMachine {
946946
}
947947
}
948948
bytecode::Instruction::MapAdd { i } => {
949-
let dict_obj = self.nth_value(*i);
949+
let dict_obj = self.nth_value(*i + 1);
950950
let key = self.pop_value();
951951
let value = self.pop_value();
952952
match self.call_method(&dict_obj, "__setitem__", vec![key, value]) {

0 commit comments

Comments
 (0)