Skip to content

Commit df0400d

Browse files
committed
Add filter and zip builtins
1 parent 3c4aaa0 commit df0400d

File tree

5 files changed

+87
-17
lines changed

5 files changed

+87
-17
lines changed

tests/snippets/builtins.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,7 @@
1313

1414
assert type(frozenset) is type
1515

16+
assert list(zip(['a', 'b', 'c'], range(3), [9, 8, 7, 99])) == [('a', 0, 9), ('b', 1, 8), ('c', 2, 7)]
17+
18+
assert list(filter(lambda x: ((x % 2) == 0), [0, 1, 2])) == [0, 2]
19+

tests/snippets/class.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ def foo(self):
3333

3434

3535
class Bar:
36+
""" W00t """
3637
def __init__(self, x):
3738
self.x = x
3839

@@ -49,6 +50,9 @@ def kungfu(x):
4950
assert x == 3
5051

5152

53+
# TODO:
54+
# assert Bar.__doc__ == " W00t "
55+
5256
bar = Bar(42)
5357

5458
bar.fubar(2)

vm/src/builtins.rs

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,29 @@ fn builtin_exec(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
267267
vm.run_code_obj(code_obj, scope)
268268
}
269269

270-
// builtin_filter
270+
fn builtin_filter(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
271+
arg_check!(vm, args, required = [(function, None), (iterable, None)]);
272+
273+
// TODO: process one element at a time from iterators.
274+
let iterable = vm.extract_elements(iterable)?;
275+
276+
let mut new_items = vec![];
277+
for element in iterable {
278+
// apply function:
279+
let args = PyFuncArgs {
280+
args: vec![element.clone()],
281+
kwargs: vec![],
282+
};
283+
let result = vm.invoke(function.clone(), args)?;
284+
let result = objbool::boolval(vm, result)?;
285+
if result {
286+
new_items.push(element);
287+
}
288+
}
289+
290+
Ok(vm.ctx.new_list(new_items))
291+
}
292+
271293
// builtin_format
272294

273295
fn builtin_getattr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
@@ -581,7 +603,32 @@ fn builtin_sum(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
581603
}
582604

583605
// builtin_vars
584-
// builtin_zip
606+
607+
fn builtin_zip(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
608+
no_kwargs!(vm, args);
609+
610+
// TODO: process one element at a time from iterators.
611+
let mut iterables = vec![];
612+
for iterable in args.args.iter() {
613+
let iterable = vm.extract_elements(iterable)?;
614+
iterables.push(iterable);
615+
}
616+
617+
let minsize: usize = iterables.iter().map(|i| i.len()).min().unwrap_or(0);
618+
619+
let mut new_items = vec![];
620+
for i in 0..minsize {
621+
let items = iterables
622+
.iter()
623+
.map(|iterable| iterable[i].clone())
624+
.collect();
625+
let element = vm.ctx.new_tuple(items);
626+
new_items.push(element);
627+
}
628+
629+
Ok(vm.ctx.new_list(new_items))
630+
}
631+
585632
// builtin___import__
586633

587634
pub fn make_module(ctx: &PyContext) -> PyObjectRef {
@@ -616,6 +663,7 @@ pub fn make_module(ctx: &PyContext) -> PyObjectRef {
616663
dict.insert(String::from("exec"), ctx.new_rustfunc(builtin_exec));
617664
dict.insert(String::from("float"), ctx.float_type());
618665
dict.insert(String::from("frozenset"), ctx.frozenset_type());
666+
dict.insert(String::from("filter"), ctx.new_rustfunc(builtin_filter));
619667
dict.insert(String::from("getattr"), ctx.new_rustfunc(builtin_getattr));
620668
dict.insert(String::from("hasattr"), ctx.new_rustfunc(builtin_hasattr));
621669
dict.insert(String::from("hash"), ctx.new_rustfunc(builtin_hash));
@@ -654,6 +702,7 @@ pub fn make_module(ctx: &PyContext) -> PyObjectRef {
654702
dict.insert(String::from("super"), ctx.super_type());
655703
dict.insert(String::from("tuple"), ctx.tuple_type());
656704
dict.insert(String::from("type"), ctx.type_type());
705+
dict.insert(String::from("zip"), ctx.new_rustfunc(builtin_zip));
657706

658707
// Exceptions:
659708
dict.insert(

vm/src/macros.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,15 @@ macro_rules! arg_check {
8282
}
8383
};
8484
}
85+
86+
macro_rules! no_kwargs {
87+
( $vm: ident, $args:ident ) => {
88+
// Zero-arg case
89+
if $args.kwargs.len() != 0 {
90+
return Err($vm.new_type_error(format!(
91+
"Expected no keyword arguments (got: {})",
92+
$args.kwargs.len()
93+
)));
94+
}
95+
};
96+
}

vm/src/vm.rs

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,22 @@ pub struct VirtualMachine {
3737
}
3838

3939
impl VirtualMachine {
40+
/// Create a new `VirtualMachine` structure.
41+
pub fn new() -> VirtualMachine {
42+
let ctx = PyContext::new();
43+
let builtins = builtins::make_module(&ctx);
44+
let sysmod = sysmodule::mk_module(&ctx);
45+
// Add builtins as builtins module:
46+
// sysmod.get_attr("modules").unwrap().set_item("builtins", builtins.clone());
47+
let stdlib_inits = stdlib::get_module_inits();
48+
VirtualMachine {
49+
builtins: builtins,
50+
sys_module: sysmod,
51+
stdlib_inits,
52+
ctx: ctx,
53+
}
54+
}
55+
4056
pub fn run_code_obj(&mut self, code: PyObjectRef, scope: PyObjectRef) -> PyResult {
4157
let mut frame = Frame::new(code, scope);
4258
frame.run_frame_full(self)
@@ -122,21 +138,6 @@ impl VirtualMachine {
122138
&self.ctx
123139
}
124140

125-
pub fn new() -> VirtualMachine {
126-
let ctx = PyContext::new();
127-
let builtins = builtins::make_module(&ctx);
128-
let sysmod = sysmodule::mk_module(&ctx);
129-
// Add builtins as builtins module:
130-
// sysmod.get_attr("modules").unwrap().set_item("builtins", builtins.clone());
131-
let stdlib_inits = stdlib::get_module_inits();
132-
VirtualMachine {
133-
builtins: builtins,
134-
sys_module: sysmod,
135-
stdlib_inits,
136-
ctx: ctx,
137-
}
138-
}
139-
140141
pub fn get_builtin_scope(&mut self) -> PyObjectRef {
141142
let a2 = &*self.builtins.borrow();
142143
match a2.kind {

0 commit comments

Comments
 (0)