struct lval* lval_eval_comp(struct lenv* e, char* sym, struct lval* v) { if (strcmp(sym, "=") != 0 || strcmp(sym, "!=") != 0) { for (int i = 0; i < v->count; i++) { LTYPE(v, LVAL_NUM, i, sym); } } if (v->count <= 1) { lval_del(v); return lval_bool(1); } struct lval* x = lval_pop(v, 0); int result = 1; while (v->count > 0) { struct lval* y = lval_pop(v, 0); if (lval_eval_compare(sym, x, y)) { lval_del(x); x = y; } else { lval_del(y); result = 0; break; } } lval_del(x); lval_del(v); return lval_bool(result); }
struct lval* lval_read_bool(char* value) { if (strcmp(value, "#t") == 0) { return lval_bool(1); } if (strcmp(value, "#f") == 0) { return lval_bool(0); } return lval_err("Unknown boolean %s", value); }
lval* lval_eq(lval* left, lval* right) { if (left->type != right->type) { return lval_bool(0); } switch(left->type) { case LVAL_NUM: case LVAL_BOOL: if (left->num == right->num) { return lval_bool(1); } else { return lval_bool(0); } case LVAL_SYM: if (strcmp(left->sym, right->sym) == 0) { return lval_bool(1); } else { return lval_bool(0); } case LVAL_STR: if (strcmp(left->str, right->str) == 0) { return lval_bool(1); } else { return lval_bool(0); } case LVAL_FUN: if (left->builtin == right->builtin) { return lval_bool(1); } else { if ((lval_eq(left->formals, right->formals)->num == 0) && (lval_eq(left->body, right->body)->num == 0)) return lval_bool(0); } case LVAL_SEXPR: case LVAL_QEXPR: if (left->count != right->count) { return lval_bool(0); } for (int i = 0; i < left->count; i++) { if ((lval_eq(left->cell[i], right->cell[i]))->num == 0) { return lval_bool(0); } } return lval_bool(1); } return lval_bool(0); }