我正在尝试使通用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
我的实现正确吗?
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)))))
为了避免评估读取器宏函数返回的形式。