int lval_equal(struct lval* x, struct lval* y) { if (x->type != y->type) return 0; switch (x->type) { case LVAL_ERR: return 0; case LVAL_NUM: return x->num == y->num; case LVAL_BOOL: return x->flag == y->flag; case LVAL_SYM: return strcmp(x->sym, y->sym) == 0; case LVAL_FUN: if (x->fun_type != y->fun_type) return 0; switch (x->fun_type) { case LVAL_FUN_BUILTIN: return x->builtin == y->builtin; case LVAL_FUN_LAMBDA: return lval_equal(x->args, y->args) && lval_equal(x->body, y->body); } case LVAL_SEXP: case LVAL_QEXP: if (x->count != y->count) return 0; for (int i = 0; i < x->count; i++) { if (!lval_equal(x->cell[i], y->cell[i])) { return 0; } } return 1; } }
int lval_eval_compare(char* sym, struct lval* x, struct lval* y) { if (strcmp(sym, "<") == 0) return x->num < y->num; else if (strcmp(sym, ">") == 0) return x->num > y->num; else if (strcmp(sym, ">=") == 0) return x->num >= y->num; else if (strcmp(sym, "<=") == 0) return x->num <= y->num; else if (strcmp(sym, "=") == 0) return lval_equal(x, y); else if (strcmp(sym, "!=") == 0) return !lval_equal(x, y); return 0; }
BOOL lval_equal(lval* a, lval* b) { if (a->type != b->type) { return FALSE; } switch(a->type) { case LVAL_ERR: return a->data.err.num == b->data.err.num; case LVAL_NUM: return fabs(a->data.num - b->data.num) <= DBL_EPSILON; case LVAL_SYM: return strcmp(a->data.sym, b->data.sym) == 0; case LVAL_STR: return strcmp(a->data.str, b->data.str) == 0; case LVAL_OK: case LVAL_EXIT: return TRUE; case LVAL_FUNC: if (a->data.func->builtin != NULL) { if (b->data.func->builtin != NULL) { return a->data.func->builtin == a->data.func->builtin; } else { return FALSE; } } else { if (b->data.func->builtin == NULL) { return FALSE; } else { return lval_equal(b->data.func->formals, b->data.func->formals) && lval_equal(b->data.func->body, b->data.func->body); } } case LVAL_Q_EXPR: case LVAL_S_EXPR: if (a->cell_count != b->cell_count) { return 0; } for (int i = 0; i < a->cell_count; i++) { if (!lval_equal(a->cell_list[i], b->cell_list[i])) { return FALSE; } } return TRUE; default: return FALSE; } }
/* xequal - are these equal? (recursive) */ LVAL xequal(void) { LVAL arg1,arg2; /* get the two arguments */ arg1 = xlgetarg(); arg2 = xlgetarg(); xllastarg(); /* compare the arguments */ return (lval_equal(arg1,arg2) ? s_true : NIL); }