If函数

为了更好的使用比较运算符,我们需要新增if函数。 该函数有点像C中的三元运算。在条件为真时,它对一段代码求值,如果条件为假,则对另一段代码求值。

我们再次使用Q表达式来对计算式进行编码。 首先,我们让用户传入比较结果,然后我们让用户传入两个Q表达式,分别表示在条件结果为true或false时进行求值的代码。

  1. lval* builtin_if(lenv* e, lval* a) {
  2. LASSERT_NUM("if", a, 3);
  3. LASSERT_TYPE("if", a, 0, LVAL_NUM);
  4. LASSERT_TYPE("if", a, 1, LVAL_QEXPR);
  5. LASSERT_TYPE("if", a, 2, LVAL_QEXPR);
  6. /* Mark Both Expressions as evaluable */
  7. lval* x;
  8. a->cell[1]->type = LVAL_SEXPR;
  9. a->cell[2]->type = LVAL_SEXPR;
  10. if (a->cell[0]->num) {
  11. /* If condition is true evaluate first expression */
  12. x = lval_eval(e, lval_pop(a, 1));
  13. } else {
  14. /* Otherwise evaluate second expression */
  15. x = lval_eval(e, lval_pop(a, 2));
  16. }
  17. /* Delete argument list and return */
  18. lval_del(a);
  19. return x;
  20. }

剩下的就是让我们注册这些新增内置函数。

  1. /* Comparison Functions */
  2. lenv_add_builtin(e, "if", builtin_if);
  3. lenv_add_builtin(e, "==", builtin_eq);
  4. lenv_add_builtin(e, "!=", builtin_ne);
  5. lenv_add_builtin(e, ">", builtin_gt);
  6. lenv_add_builtin(e, "<", builtin_lt);
  7. lenv_add_builtin(e, ">=", builtin_ge);
  8. lenv_add_builtin(e, "<=", builtin_le);

测试一下新增内置函数,检查Lispy一切是否工作正常。

  1. lispy> > 10 5
  2. 1
  3. lispy> <= 88 5
  4. 0
  5. lispy> == 5 6
  6. 0
  7. lispy> == 5 {}
  8. 0
  9. lispy> == 1 1
  10. 1
  11. lispy> != {} 56
  12. 1
  13. lispy> == {1 2 3 {5 6}} {1 2 3 {5 6}}
  14. 1
  15. lispy> def {x y} 100 200
  16. ()
  17. lispy> if (== x y) {+ x y} {- x y}
  18. -100