Add List.extend and List.to_list, plus some more tests
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
@@ -125,7 +125,7 @@ impl List {
|
||||
if index == this.list().len() {
|
||||
// if this is the last item in the list, then we're done
|
||||
let new_str = format!("{}{}]", build_str.borrow(), repr_str.borrow());
|
||||
FunctionResult::ReturnPush(Str::create(new_str))
|
||||
Str::create(new_str).into()
|
||||
} else {
|
||||
// otherwise, continue building the string and calling to_repr
|
||||
let new_str = format!("{}{}, ", build_str.borrow(), repr_str.borrow());
|
||||
@@ -145,6 +145,13 @@ impl List {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn to_list(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
|
||||
// create a clone of this list
|
||||
let this = vm.frame_stack()[0].clone();
|
||||
let list_items = with_obj_downcast(this, |list: &List| list.list().clone());
|
||||
List::create(list_items).into()
|
||||
}
|
||||
|
||||
impl_do_call!(to_list);
|
||||
|
||||
pub(crate) fn init(_vm: &mut Vm, _state: FunctionState) -> FunctionResult {
|
||||
@@ -182,7 +189,7 @@ impl List {
|
||||
}
|
||||
});
|
||||
|
||||
FunctionResult::ReturnPush(item)
|
||||
item.into()
|
||||
}
|
||||
|
||||
pub(crate) fn len(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
|
||||
@@ -195,7 +202,7 @@ impl List {
|
||||
let this = vm.frame_stack()[0].clone();
|
||||
let arg = vm.frame_stack()[1].clone();
|
||||
with_obj_downcast_mut(this, |list: &mut List| list.list_mut().push(arg));
|
||||
FunctionResult::ReturnPush(Nil::create())
|
||||
Nil::create().into()
|
||||
}
|
||||
|
||||
pub(crate) fn pop(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
|
||||
@@ -210,6 +217,27 @@ impl List {
|
||||
todo!("throw an exception when the list is empty and there is nothing to pop")
|
||||
};
|
||||
|
||||
FunctionResult::ReturnPush(last)
|
||||
last.into()
|
||||
}
|
||||
|
||||
pub(crate) fn extend(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
|
||||
let this = vm.frame_stack()[0].clone();
|
||||
let arg = vm.frame_stack()[1].clone();
|
||||
|
||||
// we have to clone here, in case this and arg are the same list. otherwise, we couldn't
|
||||
// borrow `this` mutably while using `list` immutably.
|
||||
let list_extension = if let Some(list) = arg.borrow().as_any().downcast_ref::<List>() {
|
||||
list.list().clone()
|
||||
} else {
|
||||
// TODO List::extend - throw an exception when the argument is not a list
|
||||
// BLOCKED-ON: exceptions
|
||||
todo!("throw an exception when the List.extend argument is not a list")
|
||||
};
|
||||
|
||||
with_obj_downcast_mut(this, |list: &mut List| {
|
||||
list.list_mut().extend(list_extension);
|
||||
});
|
||||
|
||||
Nil::create().into()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,6 +190,7 @@ pub fn init_types() {
|
||||
List {
|
||||
// Conversion methods
|
||||
to_repr => BuiltinFunction::create("to_repr", List::to_repr, 1),
|
||||
to_list => BuiltinFunction::create("to_list", List::to_list, 1),
|
||||
|
||||
// Constructor
|
||||
__call__ => BuiltinFunction::create("__call__", List::do_call, 2),
|
||||
@@ -203,6 +204,7 @@ pub fn init_types() {
|
||||
|
||||
push => BuiltinFunction::create("push", List::push, 2),
|
||||
pop => BuiltinFunction::create("pop", List::pop, 1),
|
||||
extend => BuiltinFunction::create("extend", List::extend, 2),
|
||||
},
|
||||
Str {
|
||||
// Conversion methods
|
||||
|
||||
Reference in New Issue
Block a user