added list len, front, and back

This commit is contained in:
Ava Hahn 2023-03-07 14:29:31 -08:00
parent 06d30ac263
commit 7fd47c1812
Signed by untrusted user who does not match committer: affine
GPG key ID: 3A4645B8CF806069
5 changed files with 215 additions and 12 deletions

View file

@ -49,3 +49,57 @@ pub fn append_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, String> {
Ok(Ctr::Seg(temp))
}
}
pub const LEN_DOCSTRING: &str = "Takes a single argument, expected to be a list.
Returns the length of said list.
Interpreter will panic if the length of the list is greater than the max value of a signed 128 bit integer";
pub fn len_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, String> {
if let Ctr::Seg(ref s) = *ast.car {
if let Ctr::None = *s.car {
Ok(Ctr::Integer(0))
} else {
Ok(Ctr::Integer(s.len() as i128))
}
} else {
Err("impossible condition: argument to len not a list".to_string())
}
}
pub const CAR_DOCSTRING: &str = "Takes a single argument, expected to be a list.
Returns a copy of the first value in that list.
If the list is empty, returns an err to avoid passing back a null value.";
pub fn car_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, String> {
if let Ctr::Seg(ref s) = *ast.car {
if let Ctr::None = *s.car {
Err("argument is empty".to_string())
} else {
Ok(*s.car.clone())
}
} else {
Err("impossible condition: argument to car not a list".to_string())
}
}
pub const CDR_DOCSTRING: &str = "Takes a single argument, expected to be a list.
Returns a copy of the last value in that list.
If the list is empty, returns an err to avoid passing back a null value.";
pub fn cdr_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, String> {
if let Ctr::Seg(ref s) = *ast.car {
let mut ret = &s.car;
let mut iter = &s.cdr;
while let Ctr::Seg(ref next) = **iter {
ret = &next.car;
iter = &next.cdr;
}
if let Ctr::None = **ret {
Err("argument is empty".to_string())
} else {
Ok(*ret.clone())
}
} else {
Err("impossible condition: argument to cdr not a list".to_string())
}
}