内建函数

虽然现在已经可以读取Q-表达式了,但它仍无任何用处。接下来我们将构建一些函数来操纵Q-表达式。

这些操作符将作用于我们的列表类型,所以设计要尽可能简洁。我们可以先定义一些简单的操作符,再以它们为基础来构建更复杂的,这样就可以不用添加额外的C代码。以下操作符将可以满足本书内容的需要:

  • list 接收一个或者多个参数,返回一个包含所有参数的Q-表达式
  • head 接受一个Q-表达式,返回一个包含其第一个元素的Q-表达式
  • tail 接受一个Q-表达式,返回一个除首元素外的Q-表达式
  • join 接受一个或者多个Q-表达式,返回一个将其连在一起的Q-表达式
  • eval 接受一个Q-表达式,将其看做一个S-表达式,并运行

如同我们前面加的数学运算符一样,这些新的操作符也需要加入到symbol中。然后我们可以试着定义这些操作符的行为,就如上章中的buildin_op

  1. mpca_lang(MPCA_LANG_DEFAULT,
  2. " \
  3. number : /-?[0-9]+/ ; \
  4. symbol : \"list\" | \"head\" | \"tail\" \
  5. | \"join\" | \"eval\" | '+' | '-' | '*' | '/' ; \
  6. sexpr : '(' <expr>* ')' ; \
  7. qexpr : '{' <expr>* '}' ; \
  8. expr : <number> | <symbol> | <sexpr> | <qexpr> ; \
  9. lispy : /^/ <expr>* /$/ ; \
  10. ",
  11. Number, Symbol, Sexpr, Qexpr, Expr, Lispy)