我正在尝试实现一个 eval
函数,使用CLISP。
我的动机:假设我有一个这样的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))
你代码中的大部分情况都可以用一个检查来代替。((constantp body) body)
至于其他情况:
boundp
来检查一个符号是否有一个全局值。symbol-value
.fboundp
可以用于检查一个符号是否全局绑定到一个函数上symbol-function
来访问其函数对象,有时也可以使用 function-lambda-expression
来从函数对象中检索一个可解析的源代码列表。有时这将无法工作,因为内置的CLISP函数可以用C语言定义。macro-function
(如果是,则返回非nil)。macroexpand
.您可能还需要使用 special-operator-p
,并对它们进行相应的处理。
我认为,如果你把你所解释的代码尽可能限制在宏和用户定义的函数中,你所要做的事情就会简化.我记得我读过一个在遗传编程中使用的快速eval函数,以跳过评估代码的宏扩展阶段,它的方法看起来与你似乎有类似的想法。