在Common Lisp中实现Lisp评估功能

时间:2020-05-02 02:53:29

标签: lisp common-lisp interpreter

我正在尝试使用CLISP实现eval函数。

我的动力:假设我有一个这样的Lisp程序:

(defun call (arg)
  (cond
    (some-condition (call (other (strange (functions (on arg)))))
    (t nil)
  )
)

(defun mysterious-function (arg)
  (call (strange (functions (on arg))))
)

(mysterious-function 100)       ; only this line can be changed

我想知道(mysterious-function 100)中实际被称为什么。

目前我的想法如下所示,但障碍是:

  1. 如何查找符号(当前使用eval
  2. 如何获取函数的定义(例如,获取类似(defun f (x))的内容)然后进行解析
  3. 如何检测宏并将其展开

我的方向正确吗?

(defun my-eval (body)
  (cond
    ((typep body 'integer) body)
    ((typep body 'float) body)
    ((typep body 'rational) body)
    ((typep body 'complex) body)
    ((typep body 'boolean) body)
    ((typep body 'symbol) (eval body))
    ((typep body 'list) (eval body))
    (t (error))
  )
)

(my-eval '(mysterious-function 100))

1 个答案:

答案 0 :(得分:1)

您的代码中的大多数情况都可以用一次检查代替:((constantp body) body)

对于其他情况:

  • 您可以使用boundp检查符号是否具有全局值。
  • 要查找全局符号值,可以使用symbol-value
  • fboundp可用于检查符号是否全局绑定到函数
  • 要查找全局函数,可以使用symbol-function访问其函数对象,有时可以使用function-lambda-expression从函数对象中检索可解析的源代码列表。有时这不能正常工作,因为可以使用C定义CLISP内置函数。
  • 要检查符号是否具有关联的全局宏,请使用macro-function(如果有则返回非nil)。
  • 要扩展宏格式,请使用macroexpand

您可能还需要使用special-operator-p检测特殊运算符,并进行相应的处理。

我认为,如果将解释的代码尽可能地限制为宏和用户定义的函数,将会简化您的工作。 我记得曾经读过一篇关于遗传编程中使用的快速评估函数,该函数可以跳过评估代码的宏扩展阶段,而它的方法看起来与您所想的相似。