我正在尝试使用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)
中实际被称为什么。
目前我的想法如下所示,但障碍是:
eval
)(defun f (x))
的内容)然后进行解析我的方向正确吗?
(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))
答案 0 :(得分:1)
您的代码中的大多数情况都可以用一次检查代替:((constantp body) body)
对于其他情况:
boundp
检查符号是否具有全局值。symbol-value
。fboundp
可用于检查符号是否全局绑定到函数symbol-function
访问其函数对象,有时可以使用function-lambda-expression
从函数对象中检索可解析的源代码列表。有时这不能正常工作,因为可以使用C定义CLISP内置函数。macro-function
(如果有则返回非nil)。macroexpand
。您可能还需要使用special-operator-p
检测特殊运算符,并进行相应的处理。
我认为,如果将解释的代码尽可能地限制为宏和用户定义的函数,将会简化您的工作。 我记得曾经读过一篇关于遗传编程中使用的快速评估函数,该函数可以跳过评估代码的宏扩展阶段,而它的方法看起来与您所想的相似。