【问题标题】:Implement Lisp eval function in Common Lisp在 Common Lisp 中实现 Lisp eval 函数
【发布时间】:2020-08-16 14:46:21
【问题描述】:

我正在尝试使用 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))

【问题讨论】:

  • 这个问题不清楚。你想为 Common Lisp 写一个评估器吗?或者对于一些小得多的方言,其中评估器是用 in common Lisp 编写的?网上有很多关于如何编写评估器的资源:你看过吗?
  • 我正在尝试使用 Common Lisp 为 Common Lisp 编写一个评估器。我发现的大多数在线资源都在使用其他一些非函数式编程语言,例如 Python。我为其他 Lisp 方言找到了一些,但不是 Common Lisp。
  • 好吧,我认为为 CL 编写评估器远远超出了堆栈交换答案的范围:它是一种大型工业语言,它的评估器必然会很复杂。不是因为你大概可以直接使用的“库”,而是因为符号宏 &c &c 之类的东西。
  • SICL 可能与您的兴趣相关:github.com/robert-strandh/SICL

标签: lisp common-lisp interpreter


【解决方案1】:

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

至于其他情况:

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

您可能还需要检测带有special-operator-p 的特殊运算符,并相应地处理它们。

我认为,如果您将解释的代码尽可能地限制为宏和用户定义的函数,那么您尝试做的事情将会得到简化。 我记得读过关于基因编程中用于跳过评估代码的宏扩展阶段的快速评估函数,它的方法看起来与您的想法相似。

【讨论】:

  • 您提到的功能似乎是一个很好的起点。但是,我放弃了实现它,因为要实现我需要的所有功能,要写的东西太多了。关于constantp 的一个注释:它为(+ 1 2 3) 返回true,所以我仍然需要处理我需要处理的所有可能的情况。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-23
  • 2017-10-19
  • 2019-01-18
  • 1970-01-01
  • 2017-06-08
  • 2021-04-04
  • 1970-01-01
相关资源
最近更新 更多