If Function


To make our comparison operators useful we’ll need an if function. This function is a little like the ternary operation in C. Upon some condition being true it evaluates to one thing, and if the condition is false, it evaluates to another.

We can again make use of Q-Expressions to encode a computation. First we get the user to pass in the result of a comparison, then we get the user to pass in two Q-Expressions representing the code to be evaluated upon a condition being either true or 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. }

All that remains is for us to register all of these new builtins and we are again ready to go.

  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);

Have a quick mess around to check that everything is working correctly.

  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