Variable Evaluation

Our evaluation function now depends on some environment. We should pass this in as an argument and use it to get a value if we encounter a symbol type. Because our environment returns a copy of the value we need to remember to delete the input symbol lval.

  1. lval* lval_eval(lenv* e, lval* v) {
  2. if (v->type == LVAL_SYM) {
  3. lval* x = lenv_get(e, v);
  4. lval_del(v);
  5. return x;
  6. }
  7. if (v->type == LVAL_SEXPR) { return lval_eval_sexpr(e, v); }
  8. return v;
  9. }

Because we’ve added a function type, our evaluation of S-Expressions also needs to change. Instead of checking for a symbol type we want to ensure it is a function type. If this condition holds we can call the fun field of the lval using the same notation as standard function calls.

  1. lval* lval_eval_sexpr(lenv* e, lval* v) {
  2. for (int i = 0; i < v->count; i++) {
  3. v->cell[i] = lval_eval(e, v->cell[i]);
  4. }
  5. for (int i = 0; i < v->count; i++) {
  6. if (v->cell[i]->type == LVAL_ERR) { return lval_take(v, i); }
  7. }
  8. if (v->count == 0) { return v; }
  9. if (v->count == 1) { return lval_take(v, 0); }
  10. /* Ensure first element is a function after evaluation */
  11. lval* f = lval_pop(v, 0);
  12. if (f->type != LVAL_FUN) {
  13. lval_del(v); lval_del(f);
  14. return lval_err("first element is not a function");
  15. }
  16. /* If so call function to get result */
  17. lval* result = f->fun(e, v);
  18. lval_del(f);
  19. return result;
  20. }