Add List.extend and List.to_list, plus some more tests

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
2024-09-30 19:53:31 -07:00
parent a370d3a56f
commit a7d7d8e564
4 changed files with 110 additions and 4 deletions

View File

@@ -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()
}
}