首次尝试
我们的内建函数应该和上章的buildin_op
接口一致。也就是说所有的参数都先转换为S-表达式,同时要注意使用后释放内存。函数的返回值将是一个新的lval*
。
实现Q-表达式的head
和tail
的功能并不难。我们可以使用已有的S-表达式函数,比如lval_take
和lval_pop
。同时我们也要对错误的输入进行异常处理。
我们先从head
和tail
入手。它们在某些条件下是不能执行的。首先要保证输入的参数只有一个,并且类型为Q-表达式。其次这个输入的Q-表达式不能为空。
head
函数可以重复执行pop
并delete
在第二个列表元素(index 1)上,直到列表为空。
tail
函数更简单。只需要pop
并delete
第一个列表元素(index 0),剩余元素组成的列表则为我们所需要的。按此思路我们可以将代码实现如下:
lval* builtin_head(lval* a) {
/* Check Error Conditions */
if (a->count != 1) {
lval_del(a);
return lval_err("Function 'head' passed too many arguments!");
}
if (a->cell[0]->type != LVAL_QEXPR) {
lval_del(a);
return lval_err("Function 'head' passed incorrect types!");
}
if (a->cell[0]->count == 0) {
lval_del(a);
return lval_err("Function 'head' passed {}!");
}
/* Otherwise take first argument */
lval* v = lval_take(a, 0);
/* Delete all elements that are not head and return */
while (v->count > 1) { lval_del(lval_pop(v, 1)); }
return v;
}
lval* builtin_tail(lval* a) {
/* Check Error Conditions */
if (a->count != 1) {
lval_del(a);
return lval_err("Function 'tail' passed too many arguments!");
}
if (a->cell[0]->type != LVAL_QEXPR) {
lval_del(a);
return lval_err("Function 'tail' passed incorrect types!");
}
if (a->cell[0]->count == 0) {
lval_del(a);
return lval_err("Function 'tail' passed {}!");
}
/* Take first argument */
lval* v = lval_take(a, 0);
/* Delete first element and return */
lval_del(lval_pop(v, 0));
return v;
}
当前内容版权归 NoahDragon 译 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 NoahDragon 译 .