索引函数

我们所有的内建函数都已定义。现在需要一个函数,根据提供的symbol来调用相应的方法。这里我们可以用strcmpstrstr来实现。

  1. lval* builtin(lval* a, char* func) {
  2. if (strcmp("list", func) == 0) { return builtin_list(a); }
  3. if (strcmp("head", func) == 0) { return builtin_head(a); }
  4. if (strcmp("tail", func) == 0) { return builtin_tail(a); }
  5. if (strcmp("join", func) == 0) { return builtin_join(a); }
  6. if (strcmp("eval", func) == 0) { return builtin_eval(a); }
  7. if (strstr("+-/*", func)) { return builtin_op(a, func); }
  8. lval_del(a);
  9. return lval_err("Unknown Function!");
  10. }

同时修改早先lval_eval_sexpr函数来调用新的buildin

  1. /* Call builtin with operator */
  2. lval* result = builtin(v, f->sym);
  3. lval_del(f);
  4. return result;

现在我们已经全面支持Q-表达式了。编译并运行最新的代码,试试新定义的操作符吧。现在我们可以将S-表达式加在Q-表达式中。这表明我们可以将代码看做是数据。这是Lisp语言不同于其它语言所特有的。

  1. lispy> list 1 2 3 4
  2. {1 2 3 4}
  3. lispy> {head (list 1 2 3 4)}
  4. {head (list 1 2 3 4)}
  5. lispy> eval {head (list 1 2 3 4)}
  6. {1}
  7. lispy> tail {tail tail tail}
  8. {tail tail}
  9. lispy> eval (tail {tail tail {5 6 7}})
  10. {6 7}
  11. lispy> eval (head {(+ 1 2) (+ 10 20)})
  12. 3