【问题标题】:Adapting readmacros UCI Lisp code to common lisp使 readmacros UCI Lisp 代码适应常见的 lisp
【发布时间】:2020-09-16 22:13:34
【问题描述】:

我正在尝试使通用 lisp 等效于这个 UCI Lisp/Interlisp 辅助函数,用于模式数学。

(DRM /? (LAMBDA () (LIST '*VAR* (READ]

文档如下:

-Variables, which are used by the pattern matcher, start with a question mark ("?"), as in ?FOO.
-This is converted internally to (*VAR* role-name), so ?FOO becomes (*VAR* FOO).
-The DRM defines ? to convert itself to *VAR* when it is read

这是我目前的实现:

(set-macro-character #\? (lambda () (list '*var* (read))))

但是当我运行下面的匹配函数时:

(match (ptrans (actor ?x) (object ?x) (to (store)))
   (ptrans (actor (person)) (object (person)) (to (store))) nil)

我收到以下来自 DRM 功能的错误:

*** - EVAL/APPLY: too many arguments given to :LAMBDA

我的实现是否正确?

【问题讨论】:

  • 该函数应该接受两个参数,但与宏字符关联的 lambda 不接受:有关详细信息和示例,请参阅 clhs.lisp.se/Body/f_set_ma.htm

标签: common-lisp clisp


【解决方案1】:

Reader 宏函数需要接受两个参数:一个是它们可以从中读取源代码的流,另一个是触发它们被调用的字符。如果您将实现更改为

(set-macro-character #\? (lambda (stream char)
                           (declare (ignore char))
                           (list '*var* (read stream))))

那么任何出现的?x 都将被读取为(*VAR* X)。 请注意,如果将其用作函数参数,则会对其进行评估,如果 VAR 不是绑定的函数/宏,则会导致错误。

您可能希望将?x 读入为'(*VAR* X)(注意引号)以获取列表作为数据。 在这种情况下,您应该这样做:

(set-macro-character #\? (lambda (stream char)
                           (declare (ignore char))
                           (list 'quote
                                 (list '*var* (read stream)))))

防止对读取器宏函数返回的形式进行评估。

【讨论】:

    猜你喜欢
    • 2020-09-13
    • 2020-09-10
    • 2012-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多