lispi/
elementary_functions.rs

1use crate::types::*;
2
3pub fn atom(x: SExpression) -> bool {
4    matches!(x, SExpression::Atom(_))
5}
6
7pub fn eq(x: Atom, y: Atom) -> bool {
8    x == y
9}
10
11pub fn car(x: List) -> SExpression {
12    *x.0
13}
14
15pub fn cdr(x: List) -> SExpression {
16    *x.1
17}
18
19pub fn cons<H, T>(head: H, tail: T) -> List
20where
21    H: Into<SExpression>,
22    T: Into<SExpression>,
23{
24    List(Box::new(head.into()), Box::new(tail.into()))
25}
26
27#[test]
28fn test_atom() {
29    assert!(atom(T.into()));
30    assert!(atom(F.into()));
31    assert!(atom(NIL.into()));
32    assert!(!atom(SExpression::List(List::new(T.into(), T.into()))));
33}
34
35#[test]
36fn test_eq() {
37    assert!(eq(1.into(), 1.into()));
38    assert!(eq(T.into(), T.into()));
39    assert!(eq("X".into(), "X".into()));
40    assert!(!eq(1.into(), 2.into()));
41    assert!(!eq(T.into(), NIL));
42    assert!(!eq(1.into(), NIL));
43    assert!(!eq("X".into(), NIL));
44}
45
46#[test]
47fn test_car() {
48    assert_eq!(car(List::new("A".into(), NIL.into())), "A".into());
49    assert_eq!(car(List::new("A".into(), "B".into())), "A".into());
50    assert_eq!(
51        car(List::new(
52            List::new("A".into(), "B".into()).into(),
53            "C".into()
54        )),
55        List::new("A".into(), "B".into()).into()
56    );
57}
58
59#[test]
60fn test_cdr() {
61    assert_eq!(cdr(List::new("A".into(), NIL.into())), NIL.into());
62    assert_eq!(cdr(List::new("A".into(), "B".into())), "B".into());
63    assert_eq!(
64        cdr(List::new(
65            "A".into(),
66            List::new("B".into(), "C".into()).into()
67        )),
68        List::new("B".into(), "C".into()).into()
69    );
70}
71
72#[test]
73fn test_cons_car_cdr() {
74    // same tests as above but using cons for constructing lists
75    assert_eq!(car(cons(T, NIL)), T.into());
76
77    assert_eq!(cdr(cons(T, NIL)), NIL.into());
78
79    let x: List = cons(T, NIL);
80    let expr: List = cons(car(x.clone()), cdr(x.clone()));
81
82    assert_eq!(x, expr);
83}