将readmacros UCI Lisp代码修改为通用lisp

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

我正在尝试使通用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函数时:

(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

我的实现正确吗?

common-lisp clisp
1个回答
0
投票

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)))))

为了避免评估读取器宏函数返回的形式。

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