在普通Lisp中实现Lisp eval函数

问题描述 投票:0回答:1

我正在尝试实现一个 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).

目前我的想法是这样的,但障碍是。

  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))
lisp common-lisp interpreter
1个回答
1
投票

你代码中的大部分情况都可以用一个检查来代替。((constantp body) body)

至于其他情况:

  • 你可以使用 boundp 来检查一个符号是否有一个全局值。
  • 要查询一个全局符号值,你可以使用 symbol-value.
  • fboundp 可以用于检查一个符号是否全局绑定到一个函数上
  • 要查找一个全局函数,你可以使用 symbol-function 来访问其函数对象,有时也可以使用 function-lambda-expression 来从函数对象中检索一个可解析的源代码列表。有时这将无法工作,因为内置的CLISP函数可以用C语言定义。
  • 要检查一个符号是否有关联的全局宏,使用 macro-function (如果是,则返回非nil)。
  • 要展开一个宏形式,请使用 macroexpand.

您可能还需要使用 special-operator-p,并对它们进行相应的处理。

我认为,如果你把你所解释的代码尽可能限制在宏和用户定义的函数中,你所要做的事情就会简化.我记得我读过一个在遗传编程中使用的快速eval函数,以跳过评估代码的宏扩展阶段,它的方法看起来与你似乎有类似的想法。

© www.soinside.com 2019 - 2024. All rights reserved.