8 #define FLOAT_EQUALS_MARGIN 1e-6
10 static bool equal_atoms(struct Atom *atom1, struct Atom *atom2)
15 if (atom1->type != atom2->type) {
19 switch (atom1->type) {
21 return strcmp(atom1->sym, atom2->sym) == 0;
24 return fabsf(atom1->num - atom2->num) <= FLOAT_EQUALS_MARGIN;
27 return strcmp(atom1->str, atom2->str) == 0;
33 static bool equal_cons(struct Cons *cons1, struct Cons *cons2)
37 return equal(cons1->car, cons2->car) && equal(cons1->cdr, cons2->cdr);
40 bool equal(struct Expr obj1, struct Expr obj2)
42 if (obj1.type != obj2.type) {
48 return equal_atoms(obj1.atom, obj2.atom);
51 return equal_cons(obj1.cons, obj2.cons);
60 bool nil_p(struct Expr obj)
62 return obj.type == EXPR_ATOM
63 && obj.atom->type == ATOM_SYMBOL
64 && strcmp(obj.atom->sym, "nil") == 0;
67 struct Expr assoc(struct Expr key, struct Expr alist)
69 /* TODO(#310): assoc has a recursive implementation */
73 switch (alist.cons->car.type) {
75 if (equal(alist.cons->car.cons->car, key)) {
76 return alist.cons->car;
78 return assoc(key, alist.cons->cdr);
83 return assoc(key, alist.cons->cdr);