add string split method

This commit is contained in:
Ava Hahn 2023-03-08 19:42:08 -08:00
parent 7438b2c9e5
commit 6961fcc9fa
Signed by untrusted user who does not match committer: affine
GPG key ID: 3A4645B8CF806069
4 changed files with 90 additions and 2 deletions

View file

@ -74,6 +74,17 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
},
);
syms.insert(
"split".to_string(),
Symbol {
name: String::from("split"),
args: Args::Strict(vec![Type::String, Type::String]),
conditional_branches: false,
docs: strings::SPLIT_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(strings::split_callback)),
},
);
syms.insert(
"strlen".to_string(),
Symbol {

View file

@ -115,3 +115,36 @@ pub fn contains_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, String>
Ok(Ctr::Bool(parent_str.contains(&child_str)))
}
pub const SPLIT_DOCSTRING: &str = "Takes two strings. String 1 is a source string and string 2 is a delimiter.
Returns a list of substrings from string 1 that were found delimited by string 2.";
pub fn split_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, String> {
let parent_str: String;
if let Ctr::String(ref s) = *ast.car {
parent_str = s.to_string();
} else {
return Err("first argument must be a string".to_string());
}
let second_arg_obj: &Ctr;
let delim_str: String;
if let Ctr::Seg(ref s) = *ast.cdr {
second_arg_obj = &*s.car;
} else {
return Err("impossible error: needs two arguments".to_string());
}
if let Ctr::String(ref s) = &*second_arg_obj {
delim_str = s.clone();
} else {
return Err("second argument must be a string".to_string());
}
let mut ret = Seg::new();
for substr in parent_str.split(&delim_str) {
ret.append(Box::new(Ctr::String(substr.to_string())));
}
Ok(Ctr::Seg(ret))
}