lispi/
elementary_functions.rs1use 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 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}