list contains implemented

This commit is contained in:
Ava Apples Affine 2023-03-20 22:03:10 -07:00
parent da0709c4db
commit b638918a89
Signed by: affine
GPG key ID: 3A4645B8CF806069
7 changed files with 36 additions and 9 deletions

View file

@ -478,7 +478,6 @@ Note: this section only tracks the state of incomplete TODO items. Having everyt
** TODO Pre-alpha tasks
- Shell prompt is fully configurable (History, L, R, and Delim)
- userlib list contains
- Input function
- Lex function
- Read function (Input + Lex)

View file

@ -55,6 +55,18 @@
(adder (lambda (x y) (add x y))))
(eq? (reduce adder list) (add 1 2 3)))))
('contains? finds elem in list'
(quote
(contains? (1 2 3) 1)))
('contains? finds last elem in list'
(quote
(contains? (1 2 3) 3)))
('contains? doesnt find elem not in list'
(quote
(not (contains? (1 2 3) 4))))
;; add more test cases here
))

View file

@ -85,3 +85,18 @@ this will continue iuntil the list is exhausted.'
(set (q result) (func result current))
(set (q list-iter) (pop remaining)))))
result))
(def contains?
'Takes two arguments: a list and an element.
Returns true if the list contains the element.'
(list elem)
(let ((found false)
(list-iter (pop list)))
(while (and (gt? (len list-iter) 1)
(not found))
(let ((current (car list-iter))
(remaining (cdr list-iter)))
(if (eq? current elem)
(set (q found) true)
(set (q list-iter) (pop remaining)))))
found))

View file

@ -120,6 +120,7 @@ pub fn run_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, String> {
if let Ok(s) = current_dir() {
prefixes.push(String::from(s.to_str().unwrap()));
}
prefixes.push(String::from("/"));
if let Ctr::String(ref filename) = *ast.car {
for prefix in prefixes {
let candidate = Path::new(&prefix.clone()).join(filename);

View file

@ -68,13 +68,13 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
);
syms.insert(
"contains".to_string(),
"substr?".to_string(),
Symbol {
name: String::from("contains"),
name: String::from("substr?"),
args: Args::Strict(vec![Type::String, Type::String]),
conditional_branches: false,
docs: strings::CONTAINS_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(strings::contains_callback)),
docs: strings::SUBSTR_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(strings::substr_callback)),
..Default::default()
},
);

View file

@ -90,10 +90,10 @@ pub fn strcast_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, String>
}
}
pub const CONTAINS_DOCSTRING: &str =
pub const SUBSTR_DOCSTRING: &str =
"Takes two strings. Returns true if string1 contains at least one instance of string2";
pub fn contains_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, String> {
pub fn substr_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();

View file

@ -154,7 +154,7 @@ mod str_lib_tests {
#[test]
fn test_contains() {
let document = "(contains 'bigger' 'ger')";
let document = "(substr? 'bigger' 'ger')";
let result = "true";
let mut syms = SymTable::new();
static_stdlib(&mut syms).unwrap();
@ -169,7 +169,7 @@ mod str_lib_tests {
#[test]
fn test_doesnt_contain() {
let document = "(contains 'smaller' 'ger')";
let document = "(substr? 'smaller' 'ger')";
let result = "false";
let mut syms = SymTable::new();
static_stdlib(&mut syms).unwrap();