9 #define FLOAT_EQUALS_MARGIN 1e-6
11 static bool equal_atoms(struct Atom *atom1, struct Atom *atom2)
16 if (atom1->type != atom2->type) {
20 switch (atom1->type) {
22 return strcmp(atom1->sym, atom2->sym) == 0;
25 return fabsf(atom1->num - atom2->num) <= FLOAT_EQUALS_MARGIN;
28 return strcmp(atom1->str, atom2->str) == 0;
34 static bool equal_cons(struct Cons *cons1, struct Cons *cons2)
38 return equal(cons1->car, cons2->car) && equal(cons1->cdr, cons2->cdr);
41 bool equal(struct Expr obj1, struct Expr obj2)
43 if (obj1.type != obj2.type) {
49 return equal_atoms(obj1.atom, obj2.atom);
52 return equal_cons(obj1.cons, obj2.cons);
61 bool nil_p(struct Expr obj)
64 && strcmp(obj.atom->sym, "nil") == 0;
67 bool symbol_p(struct Expr obj)
69 return obj.type == EXPR_ATOM
70 && obj.atom->type == ATOM_SYMBOL;
73 bool cons_p(struct Expr obj)
75 return obj.type == EXPR_CONS;
78 struct Expr assoc(struct Expr key, struct Expr alist)
80 while (cons_p(alist)) {
81 if (cons_p(alist.cons->car) && equal(alist.cons->car.cons->car, key)) {
82 return alist.cons->car;
85 alist = alist.cons->cdr;
91 static struct Expr list_rec(Gc *gc, size_t n, va_list args)
97 struct Expr obj = va_arg(args, struct Expr);
98 return CONS(gc, obj, list_rec(gc, n - 1, args));
101 struct Expr list(Gc *gc, size_t n, ...)
105 struct Expr obj = list_rec(gc, n, args);