Add Str::index and Str::to_list
Strings can be converted to a list of strings, split up by character. Strings can also be indexed by character. Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
@@ -101,6 +101,14 @@ impl Str {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn to_list(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
|
||||||
|
let this = vm.frame_stack()[0].clone();
|
||||||
|
let list_items = with_obj_downcast(this, |str: &Str| {
|
||||||
|
str.str_value().chars().map(|c| Str::create(c)).collect()
|
||||||
|
});
|
||||||
|
List::create(list_items).into()
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn len(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
|
pub(crate) fn len(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
|
||||||
let len = with_obj_downcast(vm.frame_stack()[0].clone(), |str_inst: &Str| {
|
let len = with_obj_downcast(vm.frame_stack()[0].clone(), |str_inst: &Str| {
|
||||||
str_inst.str_value().len() as i64
|
str_inst.str_value().len() as i64
|
||||||
@@ -141,4 +149,38 @@ impl Str {
|
|||||||
let new = format!("{}", lhs.borrow()).repeat(repeat_count);
|
let new = format!("{}", lhs.borrow()).repeat(repeat_count);
|
||||||
Str::create(new).into()
|
Str::create(new).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn index(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
|
||||||
|
let this = vm.frame_stack()[0].clone();
|
||||||
|
let index_obj = vm.frame_stack()[1].clone();
|
||||||
|
|
||||||
|
let index = if let Some(index_obj) = index_obj.borrow().as_any().downcast_ref::<Int>() {
|
||||||
|
index_obj.int_value()
|
||||||
|
} else {
|
||||||
|
// TODO Str::index - throw an exception when the index object is not an integer
|
||||||
|
// BLOCKED-ON: exceptions
|
||||||
|
todo!("throw an exception when the index object is not an integer")
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO Str::index - maybe there is a way we can optimize this, because both getting the
|
||||||
|
// length in characters plus getting the nth character can be slow if we're doing UTF-8
|
||||||
|
// lookups. Maybe cache the length of the string in the Str struct?
|
||||||
|
let c = with_obj_downcast(this, |str: &Str| {
|
||||||
|
let len = str.str_value().chars().count();
|
||||||
|
let mut index = index;
|
||||||
|
if index < 0 {
|
||||||
|
index = len as i64 + index;
|
||||||
|
}
|
||||||
|
|
||||||
|
if index < 0 || index as usize >= len {
|
||||||
|
// TODO Str::index - throw an exception when the index is out of range
|
||||||
|
// BLOCKED-ON: exceptions
|
||||||
|
todo!("throw an exception when the str index is out of range")
|
||||||
|
} else {
|
||||||
|
str.str_value().chars().nth(index as usize).unwrap()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Str::create(c).into()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -157,6 +157,7 @@ pub fn init_types() {
|
|||||||
to_bool => BuiltinFunction::create("to_bool", BaseObj::to_bool, 1),
|
to_bool => BuiltinFunction::create("to_bool", BaseObj::to_bool, 1),
|
||||||
to_int => BuiltinFunction::create("to_int", BaseObj::not_implemented_un, 1),
|
to_int => BuiltinFunction::create("to_int", BaseObj::not_implemented_un, 1),
|
||||||
to_float => BuiltinFunction::create("to_float", BaseObj::not_implemented_un, 1),
|
to_float => BuiltinFunction::create("to_float", BaseObj::not_implemented_un, 1),
|
||||||
|
to_list => BuiltinFunction::create("to_list", BaseObj::not_implemented_un, 1),
|
||||||
len => BuiltinFunction::create("len", BaseObj::not_implemented_un, 1),
|
len => BuiltinFunction::create("len", BaseObj::not_implemented_un, 1),
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
@@ -204,6 +205,7 @@ pub fn init_types() {
|
|||||||
to_str => BuiltinFunction::create("to_str", Str::to_str, 1),
|
to_str => BuiltinFunction::create("to_str", Str::to_str, 1),
|
||||||
to_int => BuiltinFunction::create("to_int", Str::to_int, 1),
|
to_int => BuiltinFunction::create("to_int", Str::to_int, 1),
|
||||||
to_float => BuiltinFunction::create("to_float", Str::to_float, 1),
|
to_float => BuiltinFunction::create("to_float", Str::to_float, 1),
|
||||||
|
to_list => BuiltinFunction::create("to_list", Str::to_list, 1),
|
||||||
len => BuiltinFunction::create("len", Str::len, 1),
|
len => BuiltinFunction::create("len", Str::len, 1),
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
@@ -214,6 +216,8 @@ pub fn init_types() {
|
|||||||
__add__ => BuiltinFunction::create("__add__", Str::add, 2),
|
__add__ => BuiltinFunction::create("__add__", Str::add, 2),
|
||||||
__mul__ => BuiltinFunction::create("__mul__", Str::mul, 2),
|
__mul__ => BuiltinFunction::create("__mul__", Str::mul, 2),
|
||||||
|
|
||||||
|
__index__ => BuiltinFunction::create("__index__", Str::index, 2),
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
// TODO Str methods - .lower, .upper, .slice, etc
|
// TODO Str methods - .lower, .upper, .slice, etc
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user