在 Common Lisp 中实现 Lisp eval 函数
Implement Lisp eval function in Common Lisp
我正在尝试使用 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))
代码中的大多数情况都可以用一次检查替换:((constantp body) body)
至于其他情况:
- 您可以使用
boundp
检查符号是否具有全局值。
- 要查找全局符号值,您可以使用
symbol-value
。
fboundp
可用于检查符号是否全局绑定到函数
- 要查找全局函数,您可以使用
symbol-function
访问其函数对象,有时可以使用 function-lambda-expression
从函数对象中检索可解析的源代码列表。有时这将不起作用,因为内置的 CLISP 函数可以在 C 中定义。
- 要检查符号是否具有关联的全局宏,请使用
macro-function
(returns 如果有则为非零)。
- 要展开宏表单,请使用
macroexpand
。
您可能还需要使用 special-operator-p
检测特殊运算符,并相应地处理它们。
我认为,如果您将解释的代码尽可能限制为宏和用户定义的函数,那么您正在尝试做的事情将会得到简化。
我记得读过有关遗传编程中用于跳过评估代码的宏扩展阶段的快速评估函数的文章,其方法看起来与您所想的类似。
我正在尝试使用 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))
代码中的大多数情况都可以用一次检查替换:((constantp body) body)
至于其他情况:
- 您可以使用
boundp
检查符号是否具有全局值。 - 要查找全局符号值,您可以使用
symbol-value
。 fboundp
可用于检查符号是否全局绑定到函数- 要查找全局函数,您可以使用
symbol-function
访问其函数对象,有时可以使用function-lambda-expression
从函数对象中检索可解析的源代码列表。有时这将不起作用,因为内置的 CLISP 函数可以在 C 中定义。 - 要检查符号是否具有关联的全局宏,请使用
macro-function
(returns 如果有则为非零)。 - 要展开宏表单,请使用
macroexpand
。
您可能还需要使用 special-operator-p
检测特殊运算符,并相应地处理它们。
我认为,如果您将解释的代码尽可能限制为宏和用户定义的函数,那么您正在尝试做的事情将会得到简化。 我记得读过有关遗传编程中用于跳过评估代码的宏扩展阶段的快速评估函数的文章,其方法看起来与您所想的类似。