等于函数
等于函数将会与排序函数有所不同,因为我们想要它不仅仅适用于数字类型。除此之外,它将用于判断输入是否为空列表,或者判断两个函数是否相同。因此我们需要定义一个用来检验两个不同类型lval
变量是否相等的函数。
该函数实质上检查两个构成lval
类型数据的所有字段是否相等。 若所有字段都相等,则两者被认为是相等的。 否则,若存在任何差异,则两者被认为是不相等的。
int lval_eq(lval* x, lval* y) {
/* Different Types are always unequal */
if (x->type != y->type) { return 0; }
/* Compare Based upon type */
switch (x->type) {
/* Compare Number Value */
case LVAL_NUM: return (x->num == y->num);
/* Compare String Values */
case LVAL_ERR: return (strcmp(x->err, y->err) == 0);
case LVAL_SYM: return (strcmp(x->sym, y->sym) == 0);
/* If builtin compare, otherwise compare formals and body */
case LVAL_FUN:
if (x->builtin || y->builtin) {
return x->builtin == y->builtin;
} else {
return lval_eq(x->formals, y->formals)
&& lval_eq(x->body, y->body);
}
/* If list compare every individual element */
case LVAL_QEXPR:
case LVAL_SEXPR:
if (x->count != y->count) { return 0; }
for (int i = 0; i < x->count; i++) {
/* If any element not equal then whole list not equal */
if (!lval_eq(x->cell[i], y->cell[i])) { return 0; }
}
/* Otherwise lists must be equal */
return 1;
break;
}
return 0;
}
使用该函数,可以非常简单地新增用于比较是否相等的内置函数。 我们仅需要保证输入为两个参数,检验它们是否相等,然后我们将比较结果存储到一个新的lval
中并返回它。
lval* builtin_cmp(lenv* e, lval* a, char* op) {
LASSERT_NUM(op, a, 2);
int r;
if (strcmp(op, "==") == 0) {
r = lval_eq(a->cell[0], a->cell[1]);
}
if (strcmp(op, "!=") == 0) {
r = !lval_eq(a->cell[0], a->cell[1]);
}
lval_del(a);
return lval_num(r);
}
lval* builtin_eq(lenv* e, lval* a) {
return builtin_cmp(e, a, "==");
}
lval* builtin_ne(lenv* e, lval* a) {
return builtin_cmp(e, a, "!=");
}
当前内容版权归 NoahDragon 译 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 NoahDragon 译 .